DMessage: session draft

This commit is contained in:
Enrico Ros
2025-10-22 22:31:47 -07:00
parent 1581d46be7
commit 3cd38f471e
3 changed files with 36 additions and 3 deletions
+27
View File
@@ -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<string, string | number | boolean | null>;
// Message > Metadata
@@ -185,6 +211,7 @@ export function duplicateDMessage(message: Readonly<DMessage>, 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,
@@ -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,
@@ -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;