redesign fully scaffolded and web login works
This commit is contained in:
226
gateway/src/harness/memory/session-context.ts
Normal file
226
gateway/src/harness/memory/session-context.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
import type { UserLicense, ChannelType } from '../../types/user.js';
|
||||
import type { BaseMessage } from '@langchain/core/messages';
|
||||
|
||||
/**
|
||||
* Channel capabilities (what the channel supports)
|
||||
*/
|
||||
export interface ChannelCapabilities {
|
||||
supportsMarkdown: boolean;
|
||||
supportsImages: boolean;
|
||||
supportsButtons: boolean;
|
||||
supportsVoice: boolean;
|
||||
supportsFiles: boolean;
|
||||
maxMessageLength: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Active channel information for multi-channel routing
|
||||
*/
|
||||
export interface ActiveChannel {
|
||||
type: ChannelType;
|
||||
channelUserId: string; // Platform-specific ID (telegram_id, discord_id, etc)
|
||||
capabilities: ChannelCapabilities;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workspace state (current user context)
|
||||
*/
|
||||
export interface WorkspaceContext {
|
||||
activeIndicators: string[];
|
||||
activeStrategies: string[];
|
||||
watchlist: string[];
|
||||
recentQueries: string[];
|
||||
preferences: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Memory chunk from RAG retrieval
|
||||
*/
|
||||
export interface MemoryChunk {
|
||||
id: string;
|
||||
content: string;
|
||||
role: 'user' | 'assistant' | 'system';
|
||||
timestamp: number;
|
||||
relevanceScore: number;
|
||||
metadata?: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced user context for agent harness
|
||||
*
|
||||
* Contains all necessary context for an agent session:
|
||||
* - User identity and license
|
||||
* - Active channel info (for multi-channel support)
|
||||
* - Conversation state and history
|
||||
* - RAG-retrieved relevant memories
|
||||
* - Workspace state
|
||||
*
|
||||
* This object is passed to all agent nodes and tools.
|
||||
*/
|
||||
export interface UserContext {
|
||||
// Identity
|
||||
userId: string;
|
||||
sessionId: string;
|
||||
license: UserLicense;
|
||||
|
||||
// Channel context (for multi-channel routing)
|
||||
activeChannel: ActiveChannel;
|
||||
|
||||
// Conversation state
|
||||
conversationHistory: BaseMessage[];
|
||||
currentMessage?: string;
|
||||
|
||||
// RAG context
|
||||
relevantMemories: MemoryChunk[];
|
||||
|
||||
// Workspace state
|
||||
workspaceState: WorkspaceContext;
|
||||
|
||||
// Metadata
|
||||
createdAt: Date;
|
||||
lastActivity: Date;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default channel capabilities based on type
|
||||
*/
|
||||
export function getDefaultCapabilities(channelType: ChannelType): ChannelCapabilities {
|
||||
switch (channelType) {
|
||||
case 'websocket':
|
||||
return {
|
||||
supportsMarkdown: true,
|
||||
supportsImages: true,
|
||||
supportsButtons: true,
|
||||
supportsVoice: false,
|
||||
supportsFiles: true,
|
||||
maxMessageLength: 100000,
|
||||
};
|
||||
|
||||
case 'telegram':
|
||||
return {
|
||||
supportsMarkdown: true,
|
||||
supportsImages: true,
|
||||
supportsButtons: true,
|
||||
supportsVoice: true,
|
||||
supportsFiles: true,
|
||||
maxMessageLength: 4096,
|
||||
};
|
||||
|
||||
case 'slack':
|
||||
return {
|
||||
supportsMarkdown: true,
|
||||
supportsImages: true,
|
||||
supportsButtons: true,
|
||||
supportsVoice: false,
|
||||
supportsFiles: true,
|
||||
maxMessageLength: 40000,
|
||||
};
|
||||
|
||||
case 'discord':
|
||||
return {
|
||||
supportsMarkdown: true,
|
||||
supportsImages: true,
|
||||
supportsButtons: true,
|
||||
supportsVoice: true,
|
||||
supportsFiles: true,
|
||||
maxMessageLength: 2000,
|
||||
};
|
||||
|
||||
default:
|
||||
// Default fallback
|
||||
return {
|
||||
supportsMarkdown: false,
|
||||
supportsImages: false,
|
||||
supportsButtons: false,
|
||||
supportsVoice: false,
|
||||
supportsFiles: false,
|
||||
maxMessageLength: 1000,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new user context
|
||||
*/
|
||||
export function createUserContext(params: {
|
||||
userId: string;
|
||||
sessionId: string;
|
||||
license: UserLicense;
|
||||
channelType: ChannelType;
|
||||
channelUserId: string;
|
||||
channelCapabilities?: Partial<ChannelCapabilities>;
|
||||
}): UserContext {
|
||||
const defaultCapabilities = getDefaultCapabilities(params.channelType);
|
||||
const capabilities: ChannelCapabilities = {
|
||||
...defaultCapabilities,
|
||||
...params.channelCapabilities,
|
||||
};
|
||||
|
||||
return {
|
||||
userId: params.userId,
|
||||
sessionId: params.sessionId,
|
||||
license: params.license,
|
||||
activeChannel: {
|
||||
type: params.channelType,
|
||||
channelUserId: params.channelUserId,
|
||||
capabilities,
|
||||
},
|
||||
conversationHistory: [],
|
||||
relevantMemories: [],
|
||||
workspaceState: {
|
||||
activeIndicators: [],
|
||||
activeStrategies: [],
|
||||
watchlist: [],
|
||||
recentQueries: [],
|
||||
preferences: {},
|
||||
},
|
||||
createdAt: new Date(),
|
||||
lastActivity: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update last activity timestamp
|
||||
*/
|
||||
export function touchContext(context: UserContext): UserContext {
|
||||
return {
|
||||
...context,
|
||||
lastActivity: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if context has expired (for TTL management)
|
||||
*/
|
||||
export function isContextExpired(context: UserContext, ttlSeconds: number): boolean {
|
||||
const now = Date.now();
|
||||
const lastActivity = context.lastActivity.getTime();
|
||||
return (now - lastActivity) / 1000 > ttlSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize context for Redis storage
|
||||
*/
|
||||
export function serializeContext(context: UserContext): string {
|
||||
return JSON.stringify({
|
||||
...context,
|
||||
createdAt: context.createdAt.toISOString(),
|
||||
lastActivity: context.lastActivity.toISOString(),
|
||||
// Don't serialize conversation history (too large, use checkpoint instead)
|
||||
conversationHistory: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize context from Redis storage
|
||||
*/
|
||||
export function deserializeContext(data: string): Partial<UserContext> {
|
||||
const parsed = JSON.parse(data);
|
||||
return {
|
||||
...parsed,
|
||||
createdAt: new Date(parsed.createdAt),
|
||||
lastActivity: new Date(parsed.lastActivity),
|
||||
conversationHistory: [], // Will be loaded from checkpoint
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user