From 3cd38f471eb67660e8a5269f83784e3ca5a32852 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Wed, 22 Oct 2025 22:31:47 -0700 Subject: [PATCH] DMessage: session draft --- src/common/stores/chat/chat.message.ts | 27 +++++++++++++++++++ .../chatGenerate/parsers/anthropic.parser.ts | 7 ++--- .../parsers/openai.responses.parser.ts | 5 ++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/common/stores/chat/chat.message.ts b/src/common/stores/chat/chat.message.ts index bce478ece..e4fe1dd0b 100644 --- a/src/common/stores/chat/chat.message.ts +++ b/src/common/stores/chat/chat.message.ts @@ -26,6 +26,23 @@ export interface DMessage { generator?: DMessageGenerator; // Assistant generator info, and metrics + /** + * Session metadata for multi-turn agentic sessions. + * + * Enables stateful time-monotonic multi-turn interactions in a stateless architecture: + * - Parsers accumulate session values (container IDs, response handles, etc.) + * - Request builders traverse history for latest non-expired values + * - Child messages inherit parent session, new values override + * + * Pattern: + * 1. Parser extracts vendor session data → stores in sessionMetadata + * 2. Request builder finds latest value per key → includes in next request + * 3. Vendor reuses session (e.g., Anthropic container for file access, OpenAI response for reconnection) + * + * Keys namespaced by vendor: 'anthropic.container.id', 'openai.response.id' + */ + // sessionMetadata?: DMessageSessionMetadata; + userFlags?: DMessageUserFlag[]; // (UI) user-set per-message flags // TODO: @deprecated remove this, it's really view-dependent @@ -42,6 +59,15 @@ export type DMessageId = string; export type DMessageRole = 'user' | 'assistant' | 'system'; +/** + * Session metadata carrying vendor-specific state across multi-turn agentic sessions. + * Namespaced keys (e.g., 'anthropic.container.id'), child inherits parent, new values override. + * + * NOTE: may use some typescript module augmentation to plug new keys and value types here. + * NOTE2: may add references to the parent sessions/unique Ids, although they may be the message itself + */ +// export type DMessageSessionMetadata = Record; + // Message > Metadata @@ -185,6 +211,7 @@ export function duplicateDMessage(message: Readonly, skipVoid: boolean metadata: message.metadata ? duplicateDMessageMetadata(message.metadata) : undefined, generator: message.generator ? duplicateDMessageGenerator(message.generator) : undefined, + // sessionMetadata: message.sessionMetadata ? duplicateDMessageSession(message.sessionMetadata) : undefined, userFlags: message.userFlags ? [...message.userFlags] : undefined, tokenCount: message.tokenCount, diff --git a/src/modules/aix/server/dispatch/chatGenerate/parsers/anthropic.parser.ts b/src/modules/aix/server/dispatch/chatGenerate/parsers/anthropic.parser.ts index 8066d9a36..64c153292 100644 --- a/src/modules/aix/server/dispatch/chatGenerate/parsers/anthropic.parser.ts +++ b/src/modules/aix/server/dispatch/chatGenerate/parsers/anthropic.parser.ts @@ -96,9 +96,10 @@ export function createAnthropicMessageParser(): ChatGenerateParseFunction { // -> Container metadata (for Skills) if (responseMessage.container) { - // Store container metadata for potential use in file downloads - // TODO: When IParticleTransmitter supports container metadata, call: - // pt.setContainerMetadata(responseMessage.container); + // TODO: [PRIORITY] Accumulate in DMessage.sessionMetadata: + // pt.setSessionMetadata('anthropic.container.id', container.id) + // pt.setSessionMetadata('anthropic.container.expiresAt', Date.parse(container.expires_at)) + // Request builder will find latest values and reuse container across turns for file access. console.log('[Anthropic] Container active:', { id: responseMessage.container.id, diff --git a/src/modules/aix/server/dispatch/chatGenerate/parsers/openai.responses.parser.ts b/src/modules/aix/server/dispatch/chatGenerate/parsers/openai.responses.parser.ts index 2870f442d..c00a69c02 100644 --- a/src/modules/aix/server/dispatch/chatGenerate/parsers/openai.responses.parser.ts +++ b/src/modules/aix/server/dispatch/chatGenerate/parsers/openai.responses.parser.ts @@ -273,6 +273,11 @@ export function createOpenAIResponsesEventParser(): ChatGenerateParseFunction { if (event.response.store && event.response.id) pt.setUpstreamHandle(event.response.id, 'oai-responses' /*, event.sequence_number - commented, unused for now */); + // TODO: [FUTURE] Accumulate in DMessage.sessionMetadata: + // pt.setSessionMetadata('openai.response.id', response.id) + // pt.setSessionMetadata('openai.response.expiresAt', response.expires_at) + // Request builder will find latest values and enable reconnection/continuation. + // -> TODO: Generation Details: // .created_at, .truncation, .temperature, .top_p, .tool_choice, tool count, text output type break;