@truefoundry/trueforge-core 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/dist/agent-session/ITurnResourceResolver.d.ts +8 -7
- package/dist/agent-session/ITurnResourceResolver.d.ts.map +1 -1
- package/dist/agent-session/ITurnResourceResolver.js.map +1 -1
- package/dist/agent-session/SessionHandle.d.ts +12 -0
- package/dist/agent-session/SessionHandle.d.ts.map +1 -1
- package/dist/agent-session/SessionHandle.js +74 -33
- package/dist/agent-session/SessionHandle.js.map +1 -1
- package/dist/agent-session/SessionHandle.mjs +74 -33
- package/dist/agent-session/SessionHandle.mjs.map +1 -1
- package/dist/agent-session/TurnResourceResolver.d.ts +3 -8
- package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
- package/dist/agent-session/TurnResourceResolver.js +6 -2
- package/dist/agent-session/TurnResourceResolver.js.map +1 -1
- package/dist/agent-session/TurnResourceResolver.mjs +6 -2
- package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
- package/dist/agent-session/schemas/turn.d.ts.map +1 -1
- package/dist/agent-session/schemas/turn.js +3 -1
- package/dist/agent-session/schemas/turn.js.map +1 -1
- package/dist/agent-session/schemas/turn.mjs +3 -1
- package/dist/agent-session/schemas/turn.mjs.map +1 -1
- package/dist/agent-session/store/ISessionStore.d.ts +7 -6
- package/dist/agent-session/store/ISessionStore.d.ts.map +1 -1
- package/dist/agent-session/store/ISessionStore.js.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.d.ts.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.js +25 -10
- package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.mjs +25 -10
- package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
- package/dist/agent-session/store/OffsetPageToken.d.ts.map +1 -1
- package/dist/agent-session/store/OffsetPageToken.js +3 -1
- package/dist/agent-session/store/OffsetPageToken.js.map +1 -1
- package/dist/agent-session/store/OffsetPageToken.mjs +3 -1
- package/dist/agent-session/store/OffsetPageToken.mjs.map +1 -1
- package/dist/agent-session/store/SessionListPageToken.d.ts.map +1 -1
- package/dist/agent-session/store/SessionListPageToken.js +3 -1
- package/dist/agent-session/store/SessionListPageToken.js.map +1 -1
- package/dist/agent-session/store/SessionListPageToken.mjs +3 -1
- package/dist/agent-session/store/SessionListPageToken.mjs.map +1 -1
- package/dist/core/InstructionBuilder.d.ts.map +1 -1
- package/dist/core/InstructionBuilder.js +12 -4
- package/dist/core/InstructionBuilder.js.map +1 -1
- package/dist/core/InstructionBuilder.mjs +12 -4
- package/dist/core/InstructionBuilder.mjs.map +1 -1
- package/dist/core/capabilities/builtins/AskUserQuestion.d.ts.map +1 -1
- package/dist/core/capabilities/builtins/AskUserQuestion.js +5 -0
- package/dist/core/capabilities/builtins/AskUserQuestion.js.map +1 -1
- package/dist/core/capabilities/builtins/AskUserQuestion.mjs +5 -0
- package/dist/core/capabilities/builtins/AskUserQuestion.mjs.map +1 -1
- package/dist/core/capabilities/builtins/LargeToolResponse.d.ts.map +1 -1
- package/dist/core/capabilities/builtins/LargeToolResponse.js +6 -2
- package/dist/core/capabilities/builtins/LargeToolResponse.js.map +1 -1
- package/dist/core/capabilities/builtins/LargeToolResponse.mjs +6 -2
- package/dist/core/capabilities/builtins/LargeToolResponse.mjs.map +1 -1
- package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
- package/dist/core/llm/VercelAILLM.js +6 -2
- package/dist/core/llm/VercelAILLM.js.map +1 -1
- package/dist/core/llm/VercelAILLM.mjs +6 -2
- package/dist/core/llm/VercelAILLM.mjs.map +1 -1
- package/dist/core/mcp/RemoteMCP.d.ts.map +1 -1
- package/dist/core/mcp/RemoteMCP.js +15 -5
- package/dist/core/mcp/RemoteMCP.js.map +1 -1
- package/dist/core/mcp/RemoteMCP.mjs +15 -5
- package/dist/core/mcp/RemoteMCP.mjs.map +1 -1
- package/dist/core/mcp/ToolSelectorPolicy.d.ts.map +1 -1
- package/dist/core/mcp/ToolSelectorPolicy.js +3 -1
- package/dist/core/mcp/ToolSelectorPolicy.js.map +1 -1
- package/dist/core/mcp/ToolSelectorPolicy.mjs +3 -1
- package/dist/core/mcp/ToolSelectorPolicy.mjs.map +1 -1
- package/dist/core/mcp/ToolSet.d.ts.map +1 -1
- package/dist/core/mcp/ToolSet.js +9 -3
- package/dist/core/mcp/ToolSet.js.map +1 -1
- package/dist/core/mcp/ToolSet.mjs +9 -3
- package/dist/core/mcp/ToolSet.mjs.map +1 -1
- package/dist/core/mcp/convertMCPServers.d.ts.map +1 -1
- package/dist/core/mcp/convertMCPServers.js +6 -2
- package/dist/core/mcp/convertMCPServers.js.map +1 -1
- package/dist/core/mcp/convertMCPServers.mjs +6 -2
- package/dist/core/mcp/convertMCPServers.mjs.map +1 -1
- package/dist/core/mcp/remoteMcpClient.d.ts.map +1 -1
- package/dist/core/mcp/remoteMcpClient.js +21 -7
- package/dist/core/mcp/remoteMcpClient.js.map +1 -1
- package/dist/core/mcp/remoteMcpClient.mjs +21 -7
- package/dist/core/mcp/remoteMcpClient.mjs.map +1 -1
- package/dist/core/mcp/toolSelectors.d.ts.map +1 -1
- package/dist/core/mcp/toolSelectors.js +18 -6
- package/dist/core/mcp/toolSelectors.js.map +1 -1
- package/dist/core/mcp/toolSelectors.mjs +18 -6
- package/dist/core/mcp/toolSelectors.mjs.map +1 -1
- package/dist/core/runtime/AgentThread.d.ts.map +1 -1
- package/dist/core/runtime/AgentThread.js +42 -17
- package/dist/core/runtime/AgentThread.js.map +1 -1
- package/dist/core/runtime/AgentThread.mjs +42 -17
- package/dist/core/runtime/AgentThread.mjs.map +1 -1
- package/dist/core/runtime/AgentThreadOrchestrator.d.ts.map +1 -1
- package/dist/core/runtime/AgentThreadOrchestrator.js +27 -9
- package/dist/core/runtime/AgentThreadOrchestrator.js.map +1 -1
- package/dist/core/runtime/AgentThreadOrchestrator.mjs +27 -9
- package/dist/core/runtime/AgentThreadOrchestrator.mjs.map +1 -1
- package/dist/core/runtime/DeferredTool.d.ts.map +1 -1
- package/dist/core/runtime/DeferredTool.js +15 -5
- package/dist/core/runtime/DeferredTool.js.map +1 -1
- package/dist/core/runtime/DeferredTool.mjs +15 -5
- package/dist/core/runtime/DeferredTool.mjs.map +1 -1
- package/dist/core/runtime/contextUtils.d.ts.map +1 -1
- package/dist/core/runtime/contextUtils.js +3 -1
- package/dist/core/runtime/contextUtils.js.map +1 -1
- package/dist/core/runtime/contextUtils.mjs +3 -1
- package/dist/core/runtime/contextUtils.mjs.map +1 -1
- package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
- package/dist/core/sandbox/Sandbox.js +12 -4
- package/dist/core/sandbox/Sandbox.js.map +1 -1
- package/dist/core/sandbox/Sandbox.mjs +12 -4
- package/dist/core/sandbox/Sandbox.mjs.map +1 -1
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.d.ts.map +1 -1
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.js +9 -3
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.js.map +1 -1
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs +9 -3
- package/dist/core/sandbox/codeMode/CodeModeDispatcher.mjs.map +1 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.d.ts.map +1 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js +9 -3
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.js.map +1 -1
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs +9 -3
- package/dist/core/sandbox/codeMode/nats/CodeModeNatsTransport.mjs.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.d.ts +17 -0
- package/dist/core/sandbox/provider/DaytonaProvider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.js +83 -17
- package/dist/core/sandbox/provider/DaytonaProvider.js.map +1 -1
- package/dist/core/sandbox/provider/DaytonaProvider.mjs +83 -17
- package/dist/core/sandbox/provider/DaytonaProvider.mjs.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.d.ts.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.js +12 -4
- package/dist/core/sandbox/provider/TFYSandboxProvider.js.map +1 -1
- package/dist/core/sandbox/provider/TFYSandboxProvider.mjs +12 -4
- package/dist/core/sandbox/provider/TFYSandboxProvider.mjs.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.d.ts.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.js +3 -1
- package/dist/core/sandbox/skills/SkillMounter.js.map +1 -1
- package/dist/core/sandbox/skills/SkillMounter.mjs +3 -1
- package/dist/core/sandbox/skills/SkillMounter.mjs.map +1 -1
- package/dist/core/util/abort.d.ts.map +1 -1
- package/dist/core/util/abort.js +3 -1
- package/dist/core/util/abort.js.map +1 -1
- package/dist/core/util/abort.mjs +3 -1
- package/dist/core/util/abort.mjs.map +1 -1
- package/package.json +10 -6
|
@@ -74,7 +74,9 @@ var CreateTurnRequestSchema = z.object({
|
|
|
74
74
|
previous_turn_id: z.union([z.literal("auto"), z.literal("none"), z.string().min(1)]).optional().default("auto").describe(`Defaults to 'auto' (chain to session last turn). Use 'none' for a new root turn.`).openapi("PreviousTurnIdInput"),
|
|
75
75
|
stream: z.boolean().optional().default(true).describe("When true (default), stream turn events as SSE. When false, return the running turn immediately.")
|
|
76
76
|
}).superRefine((data, ctx) => {
|
|
77
|
-
if (!data.input)
|
|
77
|
+
if (!data.input) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
78
80
|
const hasUser = data.input.some((msg) => "type" in msg && msg.type === "user.message");
|
|
79
81
|
const hasApprovalOrToolResponse = data.input.some(
|
|
80
82
|
(msg) => "type" in msg && (msg.type === "user.tool_approval" || msg.type === "user.tool_response")
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/agent-session/schemas/turn.ts"],"sourcesContent":["/** Turn product schemas: turn state, input items, and create-turn request. */\nimport { z } from '@hono/zod-openapi';\nimport {\n ActionRequiredEventSchema,\n AgentInputUserMessageSchema,\n ModelMessageEventSchema,\n UserToolApprovalMessageSchema,\n UserToolResponseMessageSchema,\n} from '../../core/events/schema';\n\nexport enum CancellationReason {\n // AbortController.abort() reason for the max-execution timer.\n ServerExecutionTimeout = 'server-execution-timeout',\n // Emitted when the client cancels the run.\n ClientCancelled = 'client-cancelled',\n // Prior turn aborted because the client started a new turn.\n CancelledForNextTurn = 'cancelled-for-next-turn',\n // Process shutting down (SIGTERM/SIGINT).\n Abandoned = 'abandoned',\n}\n\nexport const TurnStateRunningSchema = z\n .object({\n status: z.literal('running').describe('Turn is still executing.'),\n })\n .openapi('TurnStateRunning');\n\nexport const TurnStateCancelledReasonSchema = z\n .enum(CancellationReason)\n .describe('Reason for the cancellation.')\n .openapi('TurnStateCancelledReason');\n\n/** Billable aggregate for one turn. */\nexport const TurnMetricsSchema = z\n .object({\n total_input_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total input tokens across model calls in this turn.'),\n total_output_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total output tokens across model calls in this turn.'),\n total_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total tokens (input + output) across model calls in this turn.'),\n total_cache_read_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total cache-read tokens across model calls in this turn.'),\n total_cache_write_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total cache-write tokens across model calls in this turn.'),\n total_reasoning_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total reasoning tokens across model calls in this turn.'),\n total_cost_in_usd: z.number().nonnegative().optional().describe('Estimated total cost in USD for this turn.'),\n })\n .openapi('TurnMetrics');\n\nexport const TurnStateCancelledSchema = z\n .object({\n status: z.literal('cancelled').describe('Turn was cancelled before completion.'),\n reason: TurnStateCancelledReasonSchema,\n completed_at: z.string().describe('ISO 8601 time when cancellation completed.'),\n metrics: TurnMetricsSchema.optional().describe('Optional billable aggregate for work done before cancel.'),\n })\n .openapi('TurnStateCancelled');\n\nexport const TurnStateErrorSchema = z\n .object({\n status: z.literal('error').describe('Turn ended with an error.'),\n message: z.string().describe('Human-readable error message.'),\n completed_at: z.string().describe('ISO 8601 time when the error state was recorded.'),\n metrics: TurnMetricsSchema.optional().describe('Optional billable aggregate for work done before the error.'),\n })\n .openapi('TurnStateError');\n\nexport const TurnStateDoneSchema = z\n .object({\n status: z.literal('done').describe('Turn finished (possibly paused for required actions).'),\n output: z\n .union([ModelMessageEventSchema, z.null()])\n .describe('Final `model.message` for the turn, or null when the turn ended paused without a final message.'),\n required_actions: z\n .array(ActionRequiredEventSchema)\n .describe(\n 'Pending actions (`tool.approval_required`, `tool.response_required`, `mcp.auth_required`); empty when none.',\n ),\n completed_at: z.string().describe('ISO 8601 time when the turn reached a terminal state.'),\n metrics: TurnMetricsSchema.optional().describe('Optional billable aggregate for the whole turn.'),\n })\n .openapi('TurnStateDone');\n\nexport const TurnStateSchema = z\n .discriminatedUnion('status', [\n TurnStateRunningSchema,\n TurnStateDoneSchema,\n TurnStateCancelledSchema,\n TurnStateErrorSchema,\n ])\n .openapi('TurnState');\n\nexport const TurnInputItemSchema = z\n .discriminatedUnion('type', [\n AgentInputUserMessageSchema,\n UserToolApprovalMessageSchema,\n UserToolResponseMessageSchema,\n ])\n .openapi('TurnInputItem');\n\nexport const TurnSchema = z\n .object({\n id: z.string().describe('Unique turn id.'),\n session_id: z.string().describe('Session that owns this turn.'),\n previous_turn_id: z.string().nullable().describe('Prior turn this turn chains from; null for a root turn.'),\n input: z.array(TurnInputItemSchema).optional().describe('Input items supplied when the turn was created.'),\n state: TurnStateSchema,\n created_at: z.string().describe('ISO 8601 creation timestamp.'),\n })\n .openapi('Turn');\n\n/**\n * Wire type for the previous_turn_id field. Includes the default so the schema\n * can be referenced directly without re-wrapping (re-wrapping strips the $ref).\n */\nexport const CreateTurnRequestSchema = z\n .object({\n input: z\n .array(TurnInputItemSchema)\n .optional()\n .describe(\n 'Turn input items: user messages and/or approval/tool-response resumes. Do not mix user messages with approval or tool-response items.',\n ),\n previous_turn_id: z\n .union([z.literal('auto'), z.literal('none'), z.string().min(1)])\n .optional()\n .default('auto')\n .describe(`Defaults to 'auto' (chain to session last turn). Use 'none' for a new root turn.`)\n .openapi('PreviousTurnIdInput'),\n stream: z\n .boolean()\n .optional()\n .default(true)\n .describe('When true (default), stream turn events as SSE. When false, return the running turn immediately.'),\n })\n .superRefine((data, ctx) => {\n if (!data.input) return;\n const hasUser = data.input.some(msg => 'type' in msg && msg.type === 'user.message');\n const hasApprovalOrToolResponse = data.input.some(\n msg => 'type' in msg && (msg.type === 'user.tool_approval' || msg.type === 'user.tool_response'),\n );\n if (hasUser && hasApprovalOrToolResponse) {\n ctx.addIssue({\n code: 'custom',\n message: 'input must not mix user messages with approval decisions or client-side tool responses',\n });\n }\n })\n .openapi('CreateTurnRequest');\n\nexport type Turn = z.infer<typeof TurnSchema>;\nexport type TurnInputItem = z.infer<typeof TurnInputItemSchema>;\nexport type TurnState = z.infer<typeof TurnStateSchema>;\nexport type TerminalTurnState = Exclude<TurnState, { status: 'running' }>;\nexport type TurnMetrics = z.infer<typeof TurnMetricsSchema>;\n"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../../src/agent-session/schemas/turn.ts"],"sourcesContent":["/** Turn product schemas: turn state, input items, and create-turn request. */\nimport { z } from '@hono/zod-openapi';\nimport {\n ActionRequiredEventSchema,\n AgentInputUserMessageSchema,\n ModelMessageEventSchema,\n UserToolApprovalMessageSchema,\n UserToolResponseMessageSchema,\n} from '../../core/events/schema';\n\nexport enum CancellationReason {\n // AbortController.abort() reason for the max-execution timer.\n ServerExecutionTimeout = 'server-execution-timeout',\n // Emitted when the client cancels the run.\n ClientCancelled = 'client-cancelled',\n // Prior turn aborted because the client started a new turn.\n CancelledForNextTurn = 'cancelled-for-next-turn',\n // Process shutting down (SIGTERM/SIGINT).\n Abandoned = 'abandoned',\n}\n\nexport const TurnStateRunningSchema = z\n .object({\n status: z.literal('running').describe('Turn is still executing.'),\n })\n .openapi('TurnStateRunning');\n\nexport const TurnStateCancelledReasonSchema = z\n .enum(CancellationReason)\n .describe('Reason for the cancellation.')\n .openapi('TurnStateCancelledReason');\n\n/** Billable aggregate for one turn. */\nexport const TurnMetricsSchema = z\n .object({\n total_input_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total input tokens across model calls in this turn.'),\n total_output_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total output tokens across model calls in this turn.'),\n total_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total tokens (input + output) across model calls in this turn.'),\n total_cache_read_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total cache-read tokens across model calls in this turn.'),\n total_cache_write_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total cache-write tokens across model calls in this turn.'),\n total_reasoning_tokens: z\n .number()\n .int()\n .nonnegative()\n .optional()\n .describe('Total reasoning tokens across model calls in this turn.'),\n total_cost_in_usd: z.number().nonnegative().optional().describe('Estimated total cost in USD for this turn.'),\n })\n .openapi('TurnMetrics');\n\nexport const TurnStateCancelledSchema = z\n .object({\n status: z.literal('cancelled').describe('Turn was cancelled before completion.'),\n reason: TurnStateCancelledReasonSchema,\n completed_at: z.string().describe('ISO 8601 time when cancellation completed.'),\n metrics: TurnMetricsSchema.optional().describe('Optional billable aggregate for work done before cancel.'),\n })\n .openapi('TurnStateCancelled');\n\nexport const TurnStateErrorSchema = z\n .object({\n status: z.literal('error').describe('Turn ended with an error.'),\n message: z.string().describe('Human-readable error message.'),\n completed_at: z.string().describe('ISO 8601 time when the error state was recorded.'),\n metrics: TurnMetricsSchema.optional().describe('Optional billable aggregate for work done before the error.'),\n })\n .openapi('TurnStateError');\n\nexport const TurnStateDoneSchema = z\n .object({\n status: z.literal('done').describe('Turn finished (possibly paused for required actions).'),\n output: z\n .union([ModelMessageEventSchema, z.null()])\n .describe('Final `model.message` for the turn, or null when the turn ended paused without a final message.'),\n required_actions: z\n .array(ActionRequiredEventSchema)\n .describe(\n 'Pending actions (`tool.approval_required`, `tool.response_required`, `mcp.auth_required`); empty when none.',\n ),\n completed_at: z.string().describe('ISO 8601 time when the turn reached a terminal state.'),\n metrics: TurnMetricsSchema.optional().describe('Optional billable aggregate for the whole turn.'),\n })\n .openapi('TurnStateDone');\n\nexport const TurnStateSchema = z\n .discriminatedUnion('status', [\n TurnStateRunningSchema,\n TurnStateDoneSchema,\n TurnStateCancelledSchema,\n TurnStateErrorSchema,\n ])\n .openapi('TurnState');\n\nexport const TurnInputItemSchema = z\n .discriminatedUnion('type', [\n AgentInputUserMessageSchema,\n UserToolApprovalMessageSchema,\n UserToolResponseMessageSchema,\n ])\n .openapi('TurnInputItem');\n\nexport const TurnSchema = z\n .object({\n id: z.string().describe('Unique turn id.'),\n session_id: z.string().describe('Session that owns this turn.'),\n previous_turn_id: z.string().nullable().describe('Prior turn this turn chains from; null for a root turn.'),\n input: z.array(TurnInputItemSchema).optional().describe('Input items supplied when the turn was created.'),\n state: TurnStateSchema,\n created_at: z.string().describe('ISO 8601 creation timestamp.'),\n })\n .openapi('Turn');\n\n/**\n * Wire type for the previous_turn_id field. Includes the default so the schema\n * can be referenced directly without re-wrapping (re-wrapping strips the $ref).\n */\nexport const CreateTurnRequestSchema = z\n .object({\n input: z\n .array(TurnInputItemSchema)\n .optional()\n .describe(\n 'Turn input items: user messages and/or approval/tool-response resumes. Do not mix user messages with approval or tool-response items.',\n ),\n previous_turn_id: z\n .union([z.literal('auto'), z.literal('none'), z.string().min(1)])\n .optional()\n .default('auto')\n .describe(`Defaults to 'auto' (chain to session last turn). Use 'none' for a new root turn.`)\n .openapi('PreviousTurnIdInput'),\n stream: z\n .boolean()\n .optional()\n .default(true)\n .describe('When true (default), stream turn events as SSE. When false, return the running turn immediately.'),\n })\n .superRefine((data, ctx) => {\n if (!data.input) {\n return;\n }\n const hasUser = data.input.some(msg => 'type' in msg && msg.type === 'user.message');\n const hasApprovalOrToolResponse = data.input.some(\n msg => 'type' in msg && (msg.type === 'user.tool_approval' || msg.type === 'user.tool_response'),\n );\n if (hasUser && hasApprovalOrToolResponse) {\n ctx.addIssue({\n code: 'custom',\n message: 'input must not mix user messages with approval decisions or client-side tool responses',\n });\n }\n })\n .openapi('CreateTurnRequest');\n\nexport type Turn = z.infer<typeof TurnSchema>;\nexport type TurnInputItem = z.infer<typeof TurnInputItemSchema>;\nexport type TurnState = z.infer<typeof TurnStateSchema>;\nexport type TerminalTurnState = Exclude<TurnState, { status: 'running' }>;\nexport type TurnMetrics = z.infer<typeof TurnMetricsSchema>;\n"],"mappings":"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","names":["CancellationReason"]}
|
|
@@ -7,7 +7,7 @@ import type { SessionRecord } from '../models/SessionRecord';
|
|
|
7
7
|
import type { TurnRecord } from '../models/TurnRecord';
|
|
8
8
|
import type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';
|
|
9
9
|
import type { TokenPagination } from '../schemas/pagination';
|
|
10
|
-
import type { TerminalTurnState } from '../schemas/turn';
|
|
10
|
+
import type { CancellationReason, TerminalTurnState } from '../schemas/turn';
|
|
11
11
|
/**
|
|
12
12
|
* Caller-supplied fields for creating a session; the store owns timestamps and tip state.
|
|
13
13
|
* `agent` is a discriminated reference | inline binding.
|
|
@@ -82,6 +82,8 @@ export interface CreateTurnInput<TTurnCustom extends object = Record<string, nev
|
|
|
82
82
|
export interface FreezeAndGetTurnInput {
|
|
83
83
|
session_id: string;
|
|
84
84
|
turn_id: string;
|
|
85
|
+
/** Written onto the turn row when the freeze actually cancels a running turn. */
|
|
86
|
+
reason: CancellationReason;
|
|
85
87
|
/** Caller-built cancelled turn.done event; store persists atomically with state flip when it cancels. */
|
|
86
88
|
turn_done_event: PersistedTurnEvent;
|
|
87
89
|
}
|
|
@@ -232,11 +234,10 @@ export interface ISessionStore<TSessionCustom extends object = Record<string, ne
|
|
|
232
234
|
*/
|
|
233
235
|
createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void>;
|
|
234
236
|
/**
|
|
235
|
-
* One tx: (a) conditionally cancel a running turn with
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
* {@link TurnNotFoundError}.
|
|
237
|
+
* One tx: (a) conditionally cancel a running turn with `reason`; (b) if it
|
|
238
|
+
* did cancel, insert the caller-built `turn_done_event` — already-terminal
|
|
239
|
+
* turns skip the event insert; (c) return the now-immutable turn record.
|
|
240
|
+
* Missing turn → {@link TurnNotFoundError}.
|
|
240
241
|
*/
|
|
241
242
|
freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>>;
|
|
242
243
|
/** Returns the turn record, or undefined if not found in this session. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ISessionStore.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/ISessionStore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,wBAAwB,EACzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ISessionStore.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/ISessionStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/agent-session/store/ISessionStore.ts"],"sourcesContent":["import type { JsonValue } from '../../core/capabilities/AgentCapability';\nimport type { MCPServerInitInfo, ThreadOverwriteContextEvent } from '../../core/events/schema';\nimport type {\n AgentThreadSnapshot,\n ContextMessage,\n SubAgentCompletionMarker,\n} from '../../core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '../../core/runtime/contextUsage';\nimport type { SandboxInfo } from '../../core/sandbox/Sandbox';\nimport type { SessionRecord } from '../models/SessionRecord';\nimport type { TurnRecord } from '../models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';\nimport type { TokenPagination } from '../schemas/pagination';\nimport type { TerminalTurnState } from '../schemas/turn';\n\n/**\n * Caller-supplied fields for creating a session; the store owns timestamps and tip state.\n * `agent` is a discriminated reference | inline binding.\n */\nexport type CreateSessionInput<TSessionCustom extends object = Record<string, never>> = Pick<\n SessionRecord<TSessionCustom>,\n 'tenant_id' | 'session_id' | 'agent' | 'created_by'\n> & {\n custom: TSessionCustom | null;\n};\n\n/**\n * PATCH fields for an existing session; `undefined` fields are left unchanged.\n * `agent` may be set only on inline sessions, and only as an inline arm (`{ type: 'inline', spec }`).\n */\nexport type UpdateSessionInput<TSessionCustom extends object = Record<string, never>> = Pick<\n SessionRecord<TSessionCustom>,\n 'tenant_id' | 'session_id'\n> & {\n agent: Extract<SessionRecord<TSessionCustom>['agent'], { type: 'inline' }> | undefined;\n title: SessionRecord<TSessionCustom>['title'] | undefined;\n};\n\nexport interface GetSessionInput {\n tenant_id: string;\n session_id: string;\n}\n\nexport interface DeleteSessionInput {\n tenant_id: string;\n session_id: string;\n}\n\nexport interface ListSessionsInput {\n tenant_id: string;\n limit: number;\n page_token: string | undefined;\n order: 'asc' | 'desc' | undefined;\n /** Inclusive lower bound on `created_at` (instant). */\n start_timestamp: Date | undefined;\n /** Inclusive upper bound on `created_at` (instant). */\n end_timestamp: Date | undefined;\n /** When set, only sessions bound to this named agent id. */\n agent_id: string | undefined;\n /** When set, only sessions created by this identity. */\n created_by: string | undefined;\n}\n\n/** Turn row fields without assembled snapshot (create input / listTurns). */\nexport type TurnRecordWithoutSnapshot<TTurnCustom extends object = Record<string, never>> = Omit<\n TurnRecord<TTurnCustom>,\n 'snapshot'\n>;\n\n/** Thread registration; mutable per-turn data arrives through dedicated createTurn fields. */\nexport type NewThreadInit = Omit<\n AgentThreadSnapshot,\n 'context' | 'current_context_usage' | 'completion' | 'capability_state'\n>;\n\n/** Full post-send capability map for one thread. */\nexport type ThreadCapabilityStateInit = Pick<AgentThreadSnapshot, 'thread_id' | 'capability_state'>;\n\n/** One drained send() append batch for one thread; writer = the new turn. */\nexport interface TurnContextAppend {\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n}\n\nexport interface CreateTurnInput<TTurnCustom extends object = Record<string, never>> {\n turn: TurnRecordWithoutSnapshot<TTurnCustom>;\n /** Threads absent on the previous turn (turn 1: the root thread; else empty). */\n new_threads: NewThreadInit[];\n /**\n * All new messages, for new and carried-forward threads alike — collected by\n * draining orchestrator.send() BEFORE this call. Draining without persisting is\n * safe: send() mutates only in-memory threads, and if createTurn fails the whole\n * in-memory state (orchestrator, threads, resolver) is discarded — so either this\n * turn commits atomically with its appends, or nothing was persisted at all.\n */\n new_context_appends: TurnContextAppend[];\n /**\n * Complete post-send capability maps: exactly one entry per turn thread.\n * Authoritative for this turn; the store does not carry capability rows forward.\n */\n capability_states: ThreadCapabilityStateInit[];\n /** Set only if session.title is NULL (first write wins). */\n update_session_title_if_not_exist: string | null;\n}\n\nexport interface FreezeAndGetTurnInput {\n session_id: string;\n turn_id: string;\n /** Caller-built cancelled turn.done event; store persists atomically with state flip when it cancels. */\n turn_done_event: PersistedTurnEvent;\n}\n\nexport interface GetTurnInput {\n session_id: string;\n turn_id: string;\n}\n\nexport interface ListTurnsInput {\n session_id: string;\n limit: number;\n page_token: string | undefined;\n}\n\nexport interface UpdateTurnStateInput {\n session_id: string;\n turn_id: string;\n state: TerminalTurnState;\n /** Caller-built turn.done; written atomically with the state flip in the same tx. */\n turn_done_event: PersistedTurnEvent;\n}\n\nexport interface AppendToEventsInput {\n session_id: string;\n turn_id: string;\n events: PersistedTurnEvent[];\n}\n\nexport interface AddThreadsInput {\n session_id: string;\n turn_id: string;\n threads: AgentThreadSnapshot[];\n}\n\nexport interface RemoveThreadsInput {\n session_id: string;\n turn_id: string;\n thread_ids: string[];\n}\n\nexport interface AppendToThreadContextInput {\n session_id: string;\n turn_id: string;\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n completion: SubAgentCompletionMarker | null;\n}\n\nexport interface OverwriteThreadContextInput {\n session_id: string;\n turn_id: string;\n event: ThreadOverwriteContextEvent;\n}\n\nexport interface PatchMCPServersInput {\n session_id: string;\n turn_id: string;\n mcp_servers: MCPServerInitInfo[];\n}\n\nexport interface PatchSandboxInfoInput {\n session_id: string;\n turn_id: string;\n sandbox_info: SandboxInfo;\n}\n\nexport interface PatchThreadCapabilityStateInput {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: JsonValue;\n}\n\nexport interface ListTurnEventsInput {\n session_id: string;\n turn_id: string;\n limit: number;\n page_token: string | undefined;\n order: 'asc' | 'desc' | undefined;\n}\n\nexport interface ListSessionEventsInput {\n session_id: string;\n limit: number;\n page_token: string | undefined;\n last_turn_id: string | undefined;\n}\n\n/**\n * Session/turn persistence contract. Pure durability: no streaming, SSE, or\n * subscription members. Callers authorize the parent session before using\n * turn-scoped operations, which rely on globally unique session_id values.\n * Capability maps are initialized atomically by createTurn and subsequently\n * updated through patchThreadCapabilityState. Agent binding is session-scoped\n * as a discriminated `agent` (ref | value); named agents are not hydrated on read.\n */\nexport interface ISessionStore<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n /**\n * Persists a discriminated `agent` (ref | value). SQL backends may flatten to columns.\n * `session_id` is globally unique across tenants.\n * Persists caller-supplied `created_by` (immutable after create).\n * Sets `last_activity_timestamp_ms` (= now) on create.\n */\n createSession(input: CreateSessionInput<TSessionCustom>): Promise<void>;\n\n /** Permanently removes a session and all related data; missing sessions are a no-op. */\n deleteSession(input: DeleteSessionInput): Promise<void>;\n\n /**\n * Returns the session as stored (ref agents are not hydrated to a value).\n * Does **not** bump `last_activity_timestamp_ms` (read path).\n */\n getSession(input: GetSessionInput): Promise<SessionRecord<TSessionCustom> | undefined>;\n\n /**\n * PATCH semantics — update only the provided fields:\n * - agent: replace inline binding (inline sessions only; reference → invariant error).\n * - title: set/replace the session title.\n * Bumps `last_activity_timestamp_ms` (= now) in the same update.\n */\n updateSession(input: UpdateSessionInput<TSessionCustom>): Promise<void>;\n\n /**\n * Paginated list of the tenant's sessions ordered by `updated_at`\n * (`order` defaults to `desc`, `session_id` tie-break). `page_token` is a\n * keyset cursor on `(updated_at, session_id)`. `start_timestamp` /\n * `end_timestamp` are inclusive instant bounds on `created_at`. Optional\n * `agent_id` filters ref-bound sessions; optional `created_by` filters by\n * creator identity. Does **not** bump `last_activity_timestamp_ms` (read path).\n */\n listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<TSessionCustom>[]; pagination: TokenPagination }>;\n\n /**\n * Creates the turn AND advances `session.last_turn_id`. Context merging is the\n * store's responsibility: `new_context_appends` and `new_threads` are applied\n * on top of the previous turn's snapshot when `turn.previous_turn_id` is set.\n * `capability_states` is the complete authoritative map for every resulting\n * thread and is persisted directly without store-side carry-forward.\n *\n * Atomicity (store contract): insert turn + set `last_turn_id` (+ session\n * turn-list append if the backend has one) MUST be one atomic unit per\n * session. Concurrent createTurn on the same session must not drop a turn\n * row or leave `last_turn_id` pointing at a turn that was never created.\n * The implementation supplies the mechanism (session lock, row lock/tx, …).\n *\n * Also bumps `session.last_activity_timestamp_ms` in that same atomic unit.\n *\n * Fork semantics for `turn.previous_turn_id`:\n * - `null` — new root turn (no parent); always allowed.\n * - string — fork/chain from that turn when it exists. Tip-equality is NOT\n * required; concurrent forks from the same tip both succeed. Unknown id is\n * allowed (relaxed) and treated as no inheritance. If that turn exists and\n * is still `running`, reject with {@link PreviousTurnRunningError} —\n * callers must {@link freezeAndGetTurn} first.\n * `last_turn_id` always advances to the new turn in the same atomic unit.\n *\n * `update_session_title_if_not_exist`: when set AND `session.title` is\n * unset/null, set it in the same atomic unit; an existing title is NEVER\n * overwritten (first write wins). The caller derives the value; the store\n * only conditionally sets it.\n */\n createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void>;\n\n /**\n * One tx: (a) conditionally cancel a running turn with\n * {@link CancellationReason.CancelledForNextTurn}; (b) if it did cancel,\n * insert the caller-built `turn_done_event` — already-terminal turns skip the\n * event insert; (c) return the now-immutable turn record. Missing turn →\n * {@link TurnNotFoundError}.\n */\n freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>>;\n\n /** Returns the turn record, or undefined if not found in this session. */\n getTurn(input: GetTurnInput): Promise<TurnRecord<TTurnCustom> | undefined>;\n\n /** Paginated list of turn rows (no snapshot); use getTurn for assembled snapshot. */\n listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }>;\n\n /**\n * Writes the terminal state and `turn_done_event` atomically. Store contract —\n * **first terminal write wins**:\n * - Allowed: `running` → `done` | `cancelled` | `error`.\n * - Rejected with **409** (or equivalent conflict): any write when status is already\n * terminal — including done→cancelled, cancelled→done, error→*, terminal→running.\n * - Missing turn → 404 / not-found.\n *\n * Check under the same concurrency control as other turn mutations (lock/CAS) —\n * not a racy read-then-write outside the critical section.\n */\n updateTurnState(input: UpdateTurnStateInput): Promise<void>;\n\n /**\n * Durable event log for the turn. MUST include lifecycle rows: a\n * `TurnCreatedEvent` at the start of the stream and a terminal `TurnDoneEvent`\n * (or its cancelled/error shape) at the end. Every turn written through this\n * API persists lifecycle in the stream — implementations never synthesize\n * missing created/done rows on read. Every event MUST carry `id` and\n * `created_at`; `id` is a monotonic ULID and is the primary within-turn sort\n * key. `created_at` records event creation time but is not the order key.\n */\n appendToEvents(input: AppendToEventsInput): Promise<void>;\n\n /** Adds thread snapshots to the turn (sub-agent spawns). */\n addThreads(input: AddThreadsInput): Promise<void>;\n\n /** Removes threads from the turn by id. */\n removeThreads(input: RemoveThreadsInput): Promise<void>;\n\n /** Appends messages to a thread's context; optionally updates usage / completion marker. */\n appendToThreadContext(input: AppendToThreadContextInput): Promise<void>;\n\n /** Replaces a thread's context wholesale (context-overwrite event). */\n overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void>;\n\n /** Patches the turn snapshot's MCP server init info (by source id). */\n patchMCPServers(input: PatchMCPServersInput): Promise<void>;\n\n /** Patches the turn snapshot's sandbox info (id for cross-turn reattach). */\n patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void>;\n\n /** Generic capability KV — store has zero Plan/feature knowledge. */\n patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void>;\n\n /** Paginated read ordered lexically by monotonic `event.id` (asc default). */\n listTurnEvents(input: ListTurnEventsInput): Promise<{\n data: PersistedTurnEvent[];\n pagination: TokenPagination;\n }>;\n\n /**\n * Paginated session-wide feed of persisted events across turns, including\n * turn.created / turn.done lifecycle rows. Reads only — never synthesizes.\n *\n * Includes events from **running** turns (the HTTP layer may 409 separately;\n * that is not store semantics). Ordering: newest turn first, then monotonic\n * `event.id` descending within each turn. `last_turn_id` anchors the window\n * to that turn plus its ancestors; when omitted, the session's current\n * `last_turn_id` selects the active branch. Continuation page tokens encode\n * that anchor and take precedence over `last_turn_id`, so later session\n * activity cannot move an in-progress pagination walk to another branch.\n * `ancestor_ids` may include only the previous N ancestors and need not reach\n * the root — implementations must spill through older turns' own\n * `ancestor_ids` when needed. Sibling branches from forks are excluded.\n */\n listSessionEvents(input: ListSessionEventsInput): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/agent-session/store/ISessionStore.ts"],"sourcesContent":["import type { JsonValue } from '../../core/capabilities/AgentCapability';\nimport type { MCPServerInitInfo, ThreadOverwriteContextEvent } from '../../core/events/schema';\nimport type {\n AgentThreadSnapshot,\n ContextMessage,\n SubAgentCompletionMarker,\n} from '../../core/runtime/AgentThread.types';\nimport type { CurrentContextUsage } from '../../core/runtime/contextUsage';\nimport type { SandboxInfo } from '../../core/sandbox/Sandbox';\nimport type { SessionRecord } from '../models/SessionRecord';\nimport type { TurnRecord } from '../models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';\nimport type { TokenPagination } from '../schemas/pagination';\nimport type { CancellationReason, TerminalTurnState } from '../schemas/turn';\n\n/**\n * Caller-supplied fields for creating a session; the store owns timestamps and tip state.\n * `agent` is a discriminated reference | inline binding.\n */\nexport type CreateSessionInput<TSessionCustom extends object = Record<string, never>> = Pick<\n SessionRecord<TSessionCustom>,\n 'tenant_id' | 'session_id' | 'agent' | 'created_by'\n> & {\n custom: TSessionCustom | null;\n};\n\n/**\n * PATCH fields for an existing session; `undefined` fields are left unchanged.\n * `agent` may be set only on inline sessions, and only as an inline arm (`{ type: 'inline', spec }`).\n */\nexport type UpdateSessionInput<TSessionCustom extends object = Record<string, never>> = Pick<\n SessionRecord<TSessionCustom>,\n 'tenant_id' | 'session_id'\n> & {\n agent: Extract<SessionRecord<TSessionCustom>['agent'], { type: 'inline' }> | undefined;\n title: SessionRecord<TSessionCustom>['title'] | undefined;\n};\n\nexport interface GetSessionInput {\n tenant_id: string;\n session_id: string;\n}\n\nexport interface DeleteSessionInput {\n tenant_id: string;\n session_id: string;\n}\n\nexport interface ListSessionsInput {\n tenant_id: string;\n limit: number;\n page_token: string | undefined;\n order: 'asc' | 'desc' | undefined;\n /** Inclusive lower bound on `created_at` (instant). */\n start_timestamp: Date | undefined;\n /** Inclusive upper bound on `created_at` (instant). */\n end_timestamp: Date | undefined;\n /** When set, only sessions bound to this named agent id. */\n agent_id: string | undefined;\n /** When set, only sessions created by this identity. */\n created_by: string | undefined;\n}\n\n/** Turn row fields without assembled snapshot (create input / listTurns). */\nexport type TurnRecordWithoutSnapshot<TTurnCustom extends object = Record<string, never>> = Omit<\n TurnRecord<TTurnCustom>,\n 'snapshot'\n>;\n\n/** Thread registration; mutable per-turn data arrives through dedicated createTurn fields. */\nexport type NewThreadInit = Omit<\n AgentThreadSnapshot,\n 'context' | 'current_context_usage' | 'completion' | 'capability_state'\n>;\n\n/** Full post-send capability map for one thread. */\nexport type ThreadCapabilityStateInit = Pick<AgentThreadSnapshot, 'thread_id' | 'capability_state'>;\n\n/** One drained send() append batch for one thread; writer = the new turn. */\nexport interface TurnContextAppend {\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n}\n\nexport interface CreateTurnInput<TTurnCustom extends object = Record<string, never>> {\n turn: TurnRecordWithoutSnapshot<TTurnCustom>;\n /** Threads absent on the previous turn (turn 1: the root thread; else empty). */\n new_threads: NewThreadInit[];\n /**\n * All new messages, for new and carried-forward threads alike — collected by\n * draining orchestrator.send() BEFORE this call. Draining without persisting is\n * safe: send() mutates only in-memory threads, and if createTurn fails the whole\n * in-memory state (orchestrator, threads, resolver) is discarded — so either this\n * turn commits atomically with its appends, or nothing was persisted at all.\n */\n new_context_appends: TurnContextAppend[];\n /**\n * Complete post-send capability maps: exactly one entry per turn thread.\n * Authoritative for this turn; the store does not carry capability rows forward.\n */\n capability_states: ThreadCapabilityStateInit[];\n /** Set only if session.title is NULL (first write wins). */\n update_session_title_if_not_exist: string | null;\n}\n\nexport interface FreezeAndGetTurnInput {\n session_id: string;\n turn_id: string;\n /** Written onto the turn row when the freeze actually cancels a running turn. */\n reason: CancellationReason;\n /** Caller-built cancelled turn.done event; store persists atomically with state flip when it cancels. */\n turn_done_event: PersistedTurnEvent;\n}\n\nexport interface GetTurnInput {\n session_id: string;\n turn_id: string;\n}\n\nexport interface ListTurnsInput {\n session_id: string;\n limit: number;\n page_token: string | undefined;\n}\n\nexport interface UpdateTurnStateInput {\n session_id: string;\n turn_id: string;\n state: TerminalTurnState;\n /** Caller-built turn.done; written atomically with the state flip in the same tx. */\n turn_done_event: PersistedTurnEvent;\n}\n\nexport interface AppendToEventsInput {\n session_id: string;\n turn_id: string;\n events: PersistedTurnEvent[];\n}\n\nexport interface AddThreadsInput {\n session_id: string;\n turn_id: string;\n threads: AgentThreadSnapshot[];\n}\n\nexport interface RemoveThreadsInput {\n session_id: string;\n turn_id: string;\n thread_ids: string[];\n}\n\nexport interface AppendToThreadContextInput {\n session_id: string;\n turn_id: string;\n thread_id: string;\n context: ContextMessage[];\n current_context_usage: CurrentContextUsage | null;\n completion: SubAgentCompletionMarker | null;\n}\n\nexport interface OverwriteThreadContextInput {\n session_id: string;\n turn_id: string;\n event: ThreadOverwriteContextEvent;\n}\n\nexport interface PatchMCPServersInput {\n session_id: string;\n turn_id: string;\n mcp_servers: MCPServerInitInfo[];\n}\n\nexport interface PatchSandboxInfoInput {\n session_id: string;\n turn_id: string;\n sandbox_info: SandboxInfo;\n}\n\nexport interface PatchThreadCapabilityStateInput {\n session_id: string;\n turn_id: string;\n thread_id: string;\n key: string;\n state: JsonValue;\n}\n\nexport interface ListTurnEventsInput {\n session_id: string;\n turn_id: string;\n limit: number;\n page_token: string | undefined;\n order: 'asc' | 'desc' | undefined;\n}\n\nexport interface ListSessionEventsInput {\n session_id: string;\n limit: number;\n page_token: string | undefined;\n last_turn_id: string | undefined;\n}\n\n/**\n * Session/turn persistence contract. Pure durability: no streaming, SSE, or\n * subscription members. Callers authorize the parent session before using\n * turn-scoped operations, which rely on globally unique session_id values.\n * Capability maps are initialized atomically by createTurn and subsequently\n * updated through patchThreadCapabilityState. Agent binding is session-scoped\n * as a discriminated `agent` (ref | value); named agents are not hydrated on read.\n */\nexport interface ISessionStore<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n /**\n * Persists a discriminated `agent` (ref | value). SQL backends may flatten to columns.\n * `session_id` is globally unique across tenants.\n * Persists caller-supplied `created_by` (immutable after create).\n * Sets `last_activity_timestamp_ms` (= now) on create.\n */\n createSession(input: CreateSessionInput<TSessionCustom>): Promise<void>;\n\n /** Permanently removes a session and all related data; missing sessions are a no-op. */\n deleteSession(input: DeleteSessionInput): Promise<void>;\n\n /**\n * Returns the session as stored (ref agents are not hydrated to a value).\n * Does **not** bump `last_activity_timestamp_ms` (read path).\n */\n getSession(input: GetSessionInput): Promise<SessionRecord<TSessionCustom> | undefined>;\n\n /**\n * PATCH semantics — update only the provided fields:\n * - agent: replace inline binding (inline sessions only; reference → invariant error).\n * - title: set/replace the session title.\n * Bumps `last_activity_timestamp_ms` (= now) in the same update.\n */\n updateSession(input: UpdateSessionInput<TSessionCustom>): Promise<void>;\n\n /**\n * Paginated list of the tenant's sessions ordered by `updated_at`\n * (`order` defaults to `desc`, `session_id` tie-break). `page_token` is a\n * keyset cursor on `(updated_at, session_id)`. `start_timestamp` /\n * `end_timestamp` are inclusive instant bounds on `created_at`. Optional\n * `agent_id` filters ref-bound sessions; optional `created_by` filters by\n * creator identity. Does **not** bump `last_activity_timestamp_ms` (read path).\n */\n listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<TSessionCustom>[]; pagination: TokenPagination }>;\n\n /**\n * Creates the turn AND advances `session.last_turn_id`. Context merging is the\n * store's responsibility: `new_context_appends` and `new_threads` are applied\n * on top of the previous turn's snapshot when `turn.previous_turn_id` is set.\n * `capability_states` is the complete authoritative map for every resulting\n * thread and is persisted directly without store-side carry-forward.\n *\n * Atomicity (store contract): insert turn + set `last_turn_id` (+ session\n * turn-list append if the backend has one) MUST be one atomic unit per\n * session. Concurrent createTurn on the same session must not drop a turn\n * row or leave `last_turn_id` pointing at a turn that was never created.\n * The implementation supplies the mechanism (session lock, row lock/tx, …).\n *\n * Also bumps `session.last_activity_timestamp_ms` in that same atomic unit.\n *\n * Fork semantics for `turn.previous_turn_id`:\n * - `null` — new root turn (no parent); always allowed.\n * - string — fork/chain from that turn when it exists. Tip-equality is NOT\n * required; concurrent forks from the same tip both succeed. Unknown id is\n * allowed (relaxed) and treated as no inheritance. If that turn exists and\n * is still `running`, reject with {@link PreviousTurnRunningError} —\n * callers must {@link freezeAndGetTurn} first.\n * `last_turn_id` always advances to the new turn in the same atomic unit.\n *\n * `update_session_title_if_not_exist`: when set AND `session.title` is\n * unset/null, set it in the same atomic unit; an existing title is NEVER\n * overwritten (first write wins). The caller derives the value; the store\n * only conditionally sets it.\n */\n createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void>;\n\n /**\n * One tx: (a) conditionally cancel a running turn with `reason`; (b) if it\n * did cancel, insert the caller-built `turn_done_event` — already-terminal\n * turns skip the event insert; (c) return the now-immutable turn record.\n * Missing turn → {@link TurnNotFoundError}.\n */\n freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>>;\n\n /** Returns the turn record, or undefined if not found in this session. */\n getTurn(input: GetTurnInput): Promise<TurnRecord<TTurnCustom> | undefined>;\n\n /** Paginated list of turn rows (no snapshot); use getTurn for assembled snapshot. */\n listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }>;\n\n /**\n * Writes the terminal state and `turn_done_event` atomically. Store contract —\n * **first terminal write wins**:\n * - Allowed: `running` → `done` | `cancelled` | `error`.\n * - Rejected with **409** (or equivalent conflict): any write when status is already\n * terminal — including done→cancelled, cancelled→done, error→*, terminal→running.\n * - Missing turn → 404 / not-found.\n *\n * Check under the same concurrency control as other turn mutations (lock/CAS) —\n * not a racy read-then-write outside the critical section.\n */\n updateTurnState(input: UpdateTurnStateInput): Promise<void>;\n\n /**\n * Durable event log for the turn. MUST include lifecycle rows: a\n * `TurnCreatedEvent` at the start of the stream and a terminal `TurnDoneEvent`\n * (or its cancelled/error shape) at the end. Every turn written through this\n * API persists lifecycle in the stream — implementations never synthesize\n * missing created/done rows on read. Every event MUST carry `id` and\n * `created_at`; `id` is a monotonic ULID and is the primary within-turn sort\n * key. `created_at` records event creation time but is not the order key.\n */\n appendToEvents(input: AppendToEventsInput): Promise<void>;\n\n /** Adds thread snapshots to the turn (sub-agent spawns). */\n addThreads(input: AddThreadsInput): Promise<void>;\n\n /** Removes threads from the turn by id. */\n removeThreads(input: RemoveThreadsInput): Promise<void>;\n\n /** Appends messages to a thread's context; optionally updates usage / completion marker. */\n appendToThreadContext(input: AppendToThreadContextInput): Promise<void>;\n\n /** Replaces a thread's context wholesale (context-overwrite event). */\n overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void>;\n\n /** Patches the turn snapshot's MCP server init info (by source id). */\n patchMCPServers(input: PatchMCPServersInput): Promise<void>;\n\n /** Patches the turn snapshot's sandbox info (id for cross-turn reattach). */\n patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void>;\n\n /** Generic capability KV — store has zero Plan/feature knowledge. */\n patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void>;\n\n /** Paginated read ordered lexically by monotonic `event.id` (asc default). */\n listTurnEvents(input: ListTurnEventsInput): Promise<{\n data: PersistedTurnEvent[];\n pagination: TokenPagination;\n }>;\n\n /**\n * Paginated session-wide feed of persisted events across turns, including\n * turn.created / turn.done lifecycle rows. Reads only — never synthesizes.\n *\n * Includes events from **running** turns (the HTTP layer may 409 separately;\n * that is not store semantics). Ordering: newest turn first, then monotonic\n * `event.id` descending within each turn. `last_turn_id` anchors the window\n * to that turn plus its ancestors; when omitted, the session's current\n * `last_turn_id` selects the active branch. Continuation page tokens encode\n * that anchor and take precedence over `last_turn_id`, so later session\n * activity cannot move an in-progress pagination walk to another branch.\n * `ancestor_ids` may include only the previous N ancestors and need not reach\n * the root — implementations must spill through older turns' own\n * `ancestor_ids` when needed. Sibling branches from forks are excluded.\n */\n listSessionEvents(input: ListSessionEventsInput): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemorySessionStore.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/InMemorySessionStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EAEd,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,kBAAkB,EAElB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"InMemorySessionStore.d.ts","sourceRoot":"","sources":["../../../src/agent-session/store/InMemorySessionStore.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAG7D,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,eAAe,EACf,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EAEd,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,kBAAkB,EAElB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AA6HzB;;;GAGG;AACH,qBAAa,oBAAoB,CAC/B,cAAc,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACrD,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAClD,YAAW,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC;IACrD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAoD;IAC7E,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;IACpE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAErD,aAAa,CAAC,KAAK,EAAE,kBAAkB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB5E;IAEK,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY5D;IAEK,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC,CAG3F;IAEK,aAAa,CAAC,KAAK,EAAE,kBAAkB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB5E;IAEK,YAAY,CAChB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,aAAa,CAAC,cAAc,CAAC,EAAE,CAAC;QAAC,UAAU,EAAE,eAAe,CAAA;KAAE,CAAC,CAoDjF;IAEK,UAAU,CAAC,KAAK,EAAE,eAAe,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDnE;IAEK,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAmBrF;IAEK,OAAO,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,CAG/E;IAEK,SAAS,CACb,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;QAAE,IAAI,EAAE,yBAAyB,CAAC,WAAW,CAAC,EAAE,CAAC;QAAC,UAAU,EAAE,eAAe,CAAA;KAAE,CAAC,CAe1F;IAEK,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAahE;IAEK,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAS9D;IAED,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,kBAAkB;IAQpB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAOtD;IAEK,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAU5D;IAEK,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC,CAe5E;IAEK,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAW9E;IAEK,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhE;IAEK,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlE;IAEK,0BAA0B,CAAC,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBtF;IAEK,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC;QACxD,IAAI,EAAE,kBAAkB,EAAE,CAAC;QAC3B,UAAU,EAAE,eAAe,CAAC;KAC7B,CAAC,CAWD;IAEK,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAC9D,IAAI,EAAE,gBAAgB,EAAE,CAAC;QACzB,UAAU,EAAE,eAAe,CAAC;KAC7B,CAAC,CAkCD;IAED;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;CAqB7B"}
|
|
@@ -24,7 +24,6 @@ __export(InMemorySessionStore_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(InMemorySessionStore_exports);
|
|
26
26
|
var import_contextUsage = require("../../core/runtime/contextUsage.js");
|
|
27
|
-
var import_turn = require("../schemas/turn.js");
|
|
28
27
|
var import_assertCreateTurnThreadDelta = require("./assertCreateTurnThreadDelta.js");
|
|
29
28
|
var import_OffsetPageToken = require("./OffsetPageToken.js");
|
|
30
29
|
var import_SessionEventPageToken = require("./SessionEventPageToken.js");
|
|
@@ -40,8 +39,12 @@ function turnKey({ session_id, turn_id }) {
|
|
|
40
39
|
return `${session_id}:${turn_id}`;
|
|
41
40
|
}
|
|
42
41
|
function compareSessionId(a, b) {
|
|
43
|
-
if (a < b)
|
|
44
|
-
|
|
42
|
+
if (a < b) {
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
if (a > b) {
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
45
48
|
return 0;
|
|
46
49
|
}
|
|
47
50
|
function newThreadSnapshot(thread) {
|
|
@@ -169,7 +172,9 @@ var InMemorySessionStore = class {
|
|
|
169
172
|
async listSessions(input) {
|
|
170
173
|
const records = [];
|
|
171
174
|
for (const stored of this.sessions.values()) {
|
|
172
|
-
if (stored.record.tenant_id !== input.tenant_id)
|
|
175
|
+
if (stored.record.tenant_id !== input.tenant_id) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
173
178
|
if (input.agent_id !== void 0 && (stored.record.agent.type !== "reference" || stored.record.agent.id !== input.agent_id)) {
|
|
174
179
|
continue;
|
|
175
180
|
}
|
|
@@ -177,8 +182,12 @@ var InMemorySessionStore = class {
|
|
|
177
182
|
continue;
|
|
178
183
|
}
|
|
179
184
|
const createdAt = stored.record.created_at.getTime();
|
|
180
|
-
if (input.start_timestamp !== void 0 && createdAt < input.start_timestamp.getTime())
|
|
181
|
-
|
|
185
|
+
if (input.start_timestamp !== void 0 && createdAt < input.start_timestamp.getTime()) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (input.end_timestamp !== void 0 && createdAt > input.end_timestamp.getTime()) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
182
191
|
records.push(stored.record);
|
|
183
192
|
}
|
|
184
193
|
records.sort((a, b) => {
|
|
@@ -253,7 +262,7 @@ var InMemorySessionStore = class {
|
|
|
253
262
|
if (turn.state.status === "running") {
|
|
254
263
|
const cancelledState = {
|
|
255
264
|
status: "cancelled",
|
|
256
|
-
reason:
|
|
265
|
+
reason: input.reason,
|
|
257
266
|
completed_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
258
267
|
};
|
|
259
268
|
turn.state = cancelledState;
|
|
@@ -458,11 +467,17 @@ var InMemorySessionStore = class {
|
|
|
458
467
|
let oldestId = chain[0];
|
|
459
468
|
while (oldestId && oldestId !== anchor.turn_id) {
|
|
460
469
|
const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));
|
|
461
|
-
if (!oldest)
|
|
470
|
+
if (!oldest) {
|
|
471
|
+
break;
|
|
472
|
+
}
|
|
462
473
|
const older = oldest.ancestor_ids.filter((id) => !seen.has(id));
|
|
463
|
-
if (older.length === 0)
|
|
474
|
+
if (older.length === 0) {
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
464
477
|
chain.unshift(...older);
|
|
465
|
-
for (const id of older)
|
|
478
|
+
for (const id of older) {
|
|
479
|
+
seen.add(id);
|
|
480
|
+
}
|
|
466
481
|
oldestId = older[0];
|
|
467
482
|
}
|
|
468
483
|
return chain;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/agent-session/store/InMemorySessionStore.ts"],"sourcesContent":["import type { AgentThreadSnapshot } from '../../core/runtime/AgentThread.types';\nimport { getEmptyCurrentContextUsage } from '../../core/runtime/contextUsage';\nimport type { SessionRecord } from '../models/SessionRecord';\nimport type { TurnRecord, TurnSnapshot } from '../models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';\nimport type { TokenPagination } from '../schemas/pagination';\nimport { CancellationReason, type TerminalTurnState } from '../schemas/turn';\nimport { assertCreateTurnThreadDelta } from './assertCreateTurnThreadDelta';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n NewThreadInit,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnContextAppend,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from './ISessionStore';\nimport { decodeOffsetPageToken, encodeOffsetPageToken } from './OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from './SessionEventPageToken';\nimport { decodeSessionListPageToken, paginateSessionListRows } from './SessionListPageToken';\nimport {\n PreviousTurnRunningError,\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from './SessionStoreErrors';\n\n/* eslint-disable @typescript-eslint/require-await -- in-memory store is synchronous; methods stay async so thrown SessionStore*Error reject as Promises for ISessionStore callers */\n\ntype StoredEvent = PersistedTurnEvent;\n\ninterface StoredSession<TSessionCustom extends object> {\n record: SessionRecord<TSessionCustom>;\n turnIds: string[];\n}\n\nfunction deepCopy<T>(value: T): T {\n return structuredClone(value);\n}\n\nfunction sessionKey(sessionId: string): string {\n return sessionId;\n}\n\nfunction turnKey({ session_id, turn_id }: { session_id: string; turn_id: string }): string {\n return `${session_id}:${turn_id}`;\n}\n\n/** Lexicographic session_id order — shared by listSessions sort and keyset filter. */\nfunction compareSessionId(a: string, b: string): number {\n if (a < b) return -1;\n if (a > b) return 1;\n return 0;\n}\n\nfunction newThreadSnapshot(thread: NewThreadInit): AgentThreadSnapshot {\n return {\n thread_id: thread.thread_id,\n parent: thread.parent ?? null,\n agent_info: thread.agent_info ?? null,\n capability_state: null,\n context: [],\n current_context_usage: getEmptyCurrentContextUsage(),\n completion: null,\n };\n}\n\nfunction applyContextAppends(threads: Record<string, AgentThreadSnapshot>, appends: TurnContextAppend[]): void {\n for (const append of appends) {\n const thread = threads[append.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`new_context_appends references unknown thread ${append.thread_id}`);\n }\n thread.context.push(...deepCopy(append.context));\n if (append.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(append.current_context_usage);\n }\n }\n}\n\nfunction buildSnapshotFromDelta(input: {\n previousSnapshot: TurnSnapshot | undefined;\n new_threads: NewThreadInit[];\n new_context_appends: TurnContextAppend[];\n capability_states: CreateTurnInput['capability_states'];\n}): TurnSnapshot {\n const threads: Record<string, AgentThreadSnapshot> = input.previousSnapshot\n ? deepCopy(input.previousSnapshot.threads)\n : {};\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(Object.keys(threads)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n for (const nt of input.new_threads) {\n threads[nt.thread_id] = newThreadSnapshot(nt);\n }\n\n applyContextAppends(threads, input.new_context_appends);\n for (const capability of input.capability_states) {\n const thread = threads[capability.thread_id];\n if (thread === undefined) {\n throw new SessionStoreInvariantError(`capability_states references unknown thread ${capability.thread_id}`);\n }\n thread.capability_state = deepCopy(capability.capability_state);\n }\n\n return {\n threads,\n mcp_servers: input.previousSnapshot ? deepCopy(input.previousSnapshot.mcp_servers) : null,\n sandbox_info: input.previousSnapshot ? deepCopy(input.previousSnapshot.sandbox_info) : null,\n };\n}\n\nfunction paginate<T>(items: T[], limit: number, pageToken?: string): { data: T[]; pagination: TokenPagination } {\n const offset = decodeOffsetPageToken(pageToken);\n const slice = items.slice(offset, offset + limit);\n return {\n data: slice,\n pagination: {\n limit,\n ...(offset + limit < items.length ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n\n/**\n * Reference ISessionStore implementation. Proves the contract without SSE/subscription\n * hooks. Deep-copies on read/write boundaries so callers cannot mutate stored state.\n */\nexport class InMemorySessionStore<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> implements ISessionStore<TSessionCustom, TTurnCustom> {\n private readonly sessions = new Map<string, StoredSession<TSessionCustom>>();\n private readonly turns = new Map<string, TurnRecord<TTurnCustom>>();\n private readonly events = new Map<string, StoredEvent[]>();\n\n async createSession(input: CreateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n if (this.sessions.has(key)) {\n throw new SessionAlreadyExistsError(input.session_id);\n }\n const now = new Date();\n const record: SessionRecord<TSessionCustom> = {\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent: deepCopy(input.agent),\n title: null,\n last_turn_id: null,\n created_at: now,\n updated_at: now,\n last_activity_timestamp_ms: Date.now(),\n custom: input.custom !== null ? deepCopy(input.custom) : null,\n };\n this.sessions.set(key, { record, turnIds: [] });\n return;\n }\n\n async deleteSession(input: DeleteSessionInput): Promise<void> {\n const sKey = sessionKey(input.session_id);\n const stored = this.sessions.get(sKey);\n if (stored?.record.tenant_id !== input.tenant_id) {\n return;\n }\n for (const turnId of stored.turnIds) {\n const tKey = turnKey({ session_id: input.session_id, turn_id: turnId });\n this.turns.delete(tKey);\n this.events.delete(tKey);\n }\n this.sessions.delete(sKey);\n }\n\n async getSession(input: GetSessionInput): Promise<SessionRecord<TSessionCustom> | undefined> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n return stored?.record.tenant_id === input.tenant_id ? deepCopy(stored.record) : undefined;\n }\n\n async updateSession(input: UpdateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n const stored = this.sessions.get(key);\n if (stored?.record.tenant_id !== input.tenant_id) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (input.agent !== undefined) {\n if (stored.record.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n stored.record.agent = deepCopy(input.agent);\n }\n if (input.title !== undefined) {\n stored.record.title = input.title;\n }\n const now = Date.now();\n stored.record.updated_at = new Date(now);\n stored.record.last_activity_timestamp_ms = now;\n return;\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<TSessionCustom>[]; pagination: TokenPagination }> {\n const records: SessionRecord<TSessionCustom>[] = [];\n for (const stored of this.sessions.values()) {\n if (stored.record.tenant_id !== input.tenant_id) continue;\n if (\n input.agent_id !== undefined &&\n (stored.record.agent.type !== 'reference' || stored.record.agent.id !== input.agent_id)\n ) {\n continue;\n }\n if (input.created_by !== undefined && stored.record.created_by !== input.created_by) {\n continue;\n }\n const createdAt = stored.record.created_at.getTime();\n if (input.start_timestamp !== undefined && createdAt < input.start_timestamp.getTime()) continue;\n if (input.end_timestamp !== undefined && createdAt > input.end_timestamp.getTime()) continue;\n records.push(stored.record);\n }\n records.sort((a, b) => {\n const aTime = a.updated_at.getTime();\n const bTime = b.updated_at.getTime();\n if (aTime !== bTime) {\n return input.order === 'asc' ? aTime - bTime : bTime - aTime;\n }\n // Same lexicographic order as the keyset predicate below (and Postgres/SQLite).\n return input.order === 'asc'\n ? compareSessionId(a.session_id, b.session_id)\n : compareSessionId(b.session_id, a.session_id);\n });\n\n let filtered = records;\n const cursor = decodeSessionListPageToken(input.page_token);\n if (cursor) {\n const cursorTime = new Date(cursor.updated_at).getTime();\n filtered = records.filter(record => {\n const t = record.updated_at.getTime();\n const idCmp = compareSessionId(record.session_id, cursor.session_id);\n if (input.order === 'asc') {\n return t > cursorTime || (t === cursorTime && idCmp > 0);\n }\n return t < cursorTime || (t === cursorTime && idCmp < 0);\n });\n }\n\n const page = paginateSessionListRows(filtered, input.limit, row => row.updated_at.toISOString());\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void> {\n // Atomicity is free here: this body is fully synchronous, so Node's\n // run-to-completion guarantees it. Real backends must still use their own\n // locking/transactions to satisfy the ISessionStore createTurn contract.\n const sKey = sessionKey(input.turn.session_id);\n const stored = this.sessions.get(sKey);\n if (!stored) {\n throw new SessionNotFoundError(input.turn.session_id);\n }\n\n const previousTurnId = input.turn.previous_turn_id;\n let previousSnapshot: TurnSnapshot | undefined;\n if (previousTurnId !== null) {\n const prevKey = turnKey({ session_id: input.turn.session_id, turn_id: previousTurnId });\n const prev = this.turns.get(prevKey);\n // Unknown previous_turn_id is allowed (relaxed): treat as no inheritance.\n // A still-running previous must be frozen first.\n if (prev !== undefined) {\n if (prev.state.status === 'running') {\n throw new PreviousTurnRunningError(previousTurnId);\n }\n previousSnapshot = prev.snapshot;\n }\n }\n\n const tKey = turnKey(input.turn);\n if (this.turns.has(tKey)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id);\n }\n\n const snapshot = buildSnapshotFromDelta({\n previousSnapshot,\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...deepCopy(input.turn),\n snapshot,\n };\n\n this.turns.set(tKey, turnRecord);\n this.events.set(tKey, []);\n stored.turnIds.push(input.turn.turn_id);\n stored.record.last_turn_id = input.turn.turn_id;\n stored.record.last_activity_timestamp_ms = Date.now();\n stored.record.updated_at = new Date();\n if (input.update_session_title_if_not_exist !== null && stored.record.title === null) {\n stored.record.title = input.update_session_title_if_not_exist;\n }\n }\n\n async freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>> {\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n\n if (turn.state.status === 'running') {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: CancellationReason.CancelledForNextTurn,\n completed_at: new Date().toISOString(),\n };\n turn.state = cancelledState;\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n return deepCopy(turn);\n }\n\n async getTurn(input: GetTurnInput): Promise<TurnRecord<TTurnCustom> | undefined> {\n const turn = this.turns.get(turnKey(input));\n return turn ? deepCopy(turn) : undefined;\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n const records = stored.turnIds.map(id => {\n const turn = this.turns.get(turnKey({ session_id: input.session_id, turn_id: id }));\n if (!turn) {\n throw new TurnNotFoundError(id);\n }\n const { snapshot, ...row } = deepCopy(turn);\n void snapshot;\n return row;\n });\n return paginate(records, input.limit, input.page_token);\n }\n\n async updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n // Same as createTurn: synchronous body ⇒ atomic under run-to-completion.\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(input.turn_id, turn.state);\n }\n turn.state = deepCopy(input.state);\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n async appendToEvents(input: AppendToEventsInput): Promise<void> {\n this.requireRunningTurn(input.session_id, input.turn_id);\n const tKey = turnKey(input);\n const list = this.events.get(tKey);\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n list.push(...deepCopy(input.events));\n return;\n }\n\n private requireTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.turns.get(turnKey({ session_id: sessionId, turn_id: turnId }));\n if (!turn) {\n throw new TurnNotFoundError(turnId);\n }\n return turn;\n }\n\n private requireRunningTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.requireTurn(sessionId, turnId);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(turnId, turn.state);\n }\n return turn;\n }\n\n async addThreads(input: AddThreadsInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const thread of input.threads) {\n turn.snapshot.threads[thread.thread_id] = deepCopy(thread);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async removeThreads(input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const id of input.thread_ids) {\n Reflect.deleteProperty(turn.snapshot.threads, id);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.context.push(...deepCopy(input.context));\n if (input.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(input.current_context_usage);\n }\n if (input.completion !== null) {\n thread.completion = deepCopy(input.completion);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const threadId = input.event.thread_id;\n const thread = turn.snapshot.threads[threadId];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${threadId}`);\n }\n thread.context = deepCopy(input.event.context);\n thread.current_context_usage = deepCopy(input.event.current_context_usage);\n turn.updated_at = new Date();\n return;\n }\n\n async patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.mcp_servers ??= {};\n for (const server of input.mcp_servers) {\n turn.snapshot.mcp_servers[server.id] = deepCopy(server);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.sandbox_info = deepCopy(input.sandbox_info);\n turn.updated_at = new Date();\n return;\n }\n\n async patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.capability_state ??= {};\n if (input.state === null) {\n Reflect.deleteProperty(thread.capability_state, input.key);\n if (Object.keys(thread.capability_state).length === 0) {\n thread.capability_state = null;\n }\n } else {\n thread.capability_state[input.key] = deepCopy(input.state);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async listTurnEvents(input: ListTurnEventsInput): Promise<{\n data: PersistedTurnEvent[];\n pagination: TokenPagination;\n }> {\n this.requireTurn(input.session_id, input.turn_id);\n const list = this.events.get(turnKey(input));\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n const ordered = [...list].sort((a, b) =>\n input.order === 'desc' ? b.id.localeCompare(a.id) : a.id.localeCompare(b.id),\n );\n const page = paginate(ordered, input.limit, input.page_token);\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async listSessionEvents(input: ListSessionEventsInput): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? stored.record.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit: input.limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = this.turns.get(turnKey({ session_id: input.session_id, turn_id: cursor.last_turn_id }));\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n const turnIds = this.resolveAncestorChain(input.session_id, anchor);\n const flattened: SessionEventItem[] = [];\n for (const turnId of [...turnIds].reverse()) {\n const evts = this.events.get(turnKey({ session_id: input.session_id, turn_id: turnId })) ?? [];\n for (const event of [...evts].sort((a, b) => b.id.localeCompare(a.id))) {\n flattened.push({ turn_id: turnId, event });\n }\n }\n const page = paginateSessionEventRows(\n flattened.slice(cursor.offset, cursor.offset + input.limit + 1),\n input.limit,\n cursor,\n );\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n /**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\n private resolveAncestorChain(sessionId: string, anchor: TurnRecord<TTurnCustom>): string[] {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));\n if (!oldest) break;\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) break;\n chain.unshift(...older);\n for (const id of older) seen.add(id);\n oldestId = older[0];\n }\n return chain;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/agent-session/store/InMemorySessionStore.ts"],"sourcesContent":["import type { AgentThreadSnapshot } from '../../core/runtime/AgentThread.types';\nimport { getEmptyCurrentContextUsage } from '../../core/runtime/contextUsage';\nimport type { SessionRecord } from '../models/SessionRecord';\nimport type { TurnRecord, TurnSnapshot } from '../models/TurnRecord';\nimport type { PersistedTurnEvent, SessionEventItem } from '../schemas/events';\nimport type { TokenPagination } from '../schemas/pagination';\nimport type { TerminalTurnState } from '../schemas/turn';\nimport { assertCreateTurnThreadDelta } from './assertCreateTurnThreadDelta';\nimport type {\n AddThreadsInput,\n AppendToEventsInput,\n AppendToThreadContextInput,\n CreateSessionInput,\n CreateTurnInput,\n DeleteSessionInput,\n FreezeAndGetTurnInput,\n GetSessionInput,\n GetTurnInput,\n ISessionStore,\n ListSessionEventsInput,\n ListSessionsInput,\n ListTurnEventsInput,\n ListTurnsInput,\n NewThreadInit,\n OverwriteThreadContextInput,\n PatchMCPServersInput,\n PatchSandboxInfoInput,\n PatchThreadCapabilityStateInput,\n RemoveThreadsInput,\n TurnContextAppend,\n TurnRecordWithoutSnapshot,\n UpdateSessionInput,\n UpdateTurnStateInput,\n} from './ISessionStore';\nimport { decodeOffsetPageToken, encodeOffsetPageToken } from './OffsetPageToken';\nimport {\n decodeSessionEventPageToken,\n paginateSessionEventRows,\n type SessionEventPageCursor,\n} from './SessionEventPageToken';\nimport { decodeSessionListPageToken, paginateSessionListRows } from './SessionListPageToken';\nimport {\n PreviousTurnRunningError,\n SessionAlreadyExistsError,\n SessionNotFoundError,\n SessionStoreInvariantError,\n TurnAlreadyExistsError,\n TurnNotFoundError,\n TurnNotRunningError,\n} from './SessionStoreErrors';\n\n/* eslint-disable @typescript-eslint/require-await -- in-memory store is synchronous; methods stay async so thrown SessionStore*Error reject as Promises for ISessionStore callers */\n\ntype StoredEvent = PersistedTurnEvent;\n\ninterface StoredSession<TSessionCustom extends object> {\n record: SessionRecord<TSessionCustom>;\n turnIds: string[];\n}\n\nfunction deepCopy<T>(value: T): T {\n return structuredClone(value);\n}\n\nfunction sessionKey(sessionId: string): string {\n return sessionId;\n}\n\nfunction turnKey({ session_id, turn_id }: { session_id: string; turn_id: string }): string {\n return `${session_id}:${turn_id}`;\n}\n\n/** Lexicographic session_id order — shared by listSessions sort and keyset filter. */\nfunction compareSessionId(a: string, b: string): number {\n if (a < b) {\n return -1;\n }\n if (a > b) {\n return 1;\n }\n return 0;\n}\n\nfunction newThreadSnapshot(thread: NewThreadInit): AgentThreadSnapshot {\n return {\n thread_id: thread.thread_id,\n parent: thread.parent ?? null,\n agent_info: thread.agent_info ?? null,\n capability_state: null,\n context: [],\n current_context_usage: getEmptyCurrentContextUsage(),\n completion: null,\n };\n}\n\nfunction applyContextAppends(threads: Record<string, AgentThreadSnapshot>, appends: TurnContextAppend[]): void {\n for (const append of appends) {\n const thread = threads[append.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`new_context_appends references unknown thread ${append.thread_id}`);\n }\n thread.context.push(...deepCopy(append.context));\n if (append.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(append.current_context_usage);\n }\n }\n}\n\nfunction buildSnapshotFromDelta(input: {\n previousSnapshot: TurnSnapshot | undefined;\n new_threads: NewThreadInit[];\n new_context_appends: TurnContextAppend[];\n capability_states: CreateTurnInput['capability_states'];\n}): TurnSnapshot {\n const threads: Record<string, AgentThreadSnapshot> = input.previousSnapshot\n ? deepCopy(input.previousSnapshot.threads)\n : {};\n\n assertCreateTurnThreadDelta({\n previousThreadIds: new Set(Object.keys(threads)),\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n for (const nt of input.new_threads) {\n threads[nt.thread_id] = newThreadSnapshot(nt);\n }\n\n applyContextAppends(threads, input.new_context_appends);\n for (const capability of input.capability_states) {\n const thread = threads[capability.thread_id];\n if (thread === undefined) {\n throw new SessionStoreInvariantError(`capability_states references unknown thread ${capability.thread_id}`);\n }\n thread.capability_state = deepCopy(capability.capability_state);\n }\n\n return {\n threads,\n mcp_servers: input.previousSnapshot ? deepCopy(input.previousSnapshot.mcp_servers) : null,\n sandbox_info: input.previousSnapshot ? deepCopy(input.previousSnapshot.sandbox_info) : null,\n };\n}\n\nfunction paginate<T>(items: T[], limit: number, pageToken?: string): { data: T[]; pagination: TokenPagination } {\n const offset = decodeOffsetPageToken(pageToken);\n const slice = items.slice(offset, offset + limit);\n return {\n data: slice,\n pagination: {\n limit,\n ...(offset + limit < items.length ? { next_page_token: encodeOffsetPageToken(offset + limit) } : {}),\n ...(offset > 0 ? { previous_page_token: encodeOffsetPageToken(Math.max(0, offset - limit)) } : {}),\n },\n };\n}\n\n/**\n * Reference ISessionStore implementation. Proves the contract without SSE/subscription\n * hooks. Deep-copies on read/write boundaries so callers cannot mutate stored state.\n */\nexport class InMemorySessionStore<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> implements ISessionStore<TSessionCustom, TTurnCustom> {\n private readonly sessions = new Map<string, StoredSession<TSessionCustom>>();\n private readonly turns = new Map<string, TurnRecord<TTurnCustom>>();\n private readonly events = new Map<string, StoredEvent[]>();\n\n async createSession(input: CreateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n if (this.sessions.has(key)) {\n throw new SessionAlreadyExistsError(input.session_id);\n }\n const now = new Date();\n const record: SessionRecord<TSessionCustom> = {\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n created_by: input.created_by,\n agent: deepCopy(input.agent),\n title: null,\n last_turn_id: null,\n created_at: now,\n updated_at: now,\n last_activity_timestamp_ms: Date.now(),\n custom: input.custom !== null ? deepCopy(input.custom) : null,\n };\n this.sessions.set(key, { record, turnIds: [] });\n return;\n }\n\n async deleteSession(input: DeleteSessionInput): Promise<void> {\n const sKey = sessionKey(input.session_id);\n const stored = this.sessions.get(sKey);\n if (stored?.record.tenant_id !== input.tenant_id) {\n return;\n }\n for (const turnId of stored.turnIds) {\n const tKey = turnKey({ session_id: input.session_id, turn_id: turnId });\n this.turns.delete(tKey);\n this.events.delete(tKey);\n }\n this.sessions.delete(sKey);\n }\n\n async getSession(input: GetSessionInput): Promise<SessionRecord<TSessionCustom> | undefined> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n return stored?.record.tenant_id === input.tenant_id ? deepCopy(stored.record) : undefined;\n }\n\n async updateSession(input: UpdateSessionInput<TSessionCustom>): Promise<void> {\n const key = sessionKey(input.session_id);\n const stored = this.sessions.get(key);\n if (stored?.record.tenant_id !== input.tenant_id) {\n throw new SessionNotFoundError(input.session_id);\n }\n if (input.agent !== undefined) {\n if (stored.record.agent.type === 'reference') {\n throw new SessionStoreInvariantError(`Session ${input.session_id} is named; agent cannot be updated`);\n }\n stored.record.agent = deepCopy(input.agent);\n }\n if (input.title !== undefined) {\n stored.record.title = input.title;\n }\n const now = Date.now();\n stored.record.updated_at = new Date(now);\n stored.record.last_activity_timestamp_ms = now;\n return;\n }\n\n async listSessions(\n input: ListSessionsInput,\n ): Promise<{ data: SessionRecord<TSessionCustom>[]; pagination: TokenPagination }> {\n const records: SessionRecord<TSessionCustom>[] = [];\n for (const stored of this.sessions.values()) {\n if (stored.record.tenant_id !== input.tenant_id) {\n continue;\n }\n if (\n input.agent_id !== undefined &&\n (stored.record.agent.type !== 'reference' || stored.record.agent.id !== input.agent_id)\n ) {\n continue;\n }\n if (input.created_by !== undefined && stored.record.created_by !== input.created_by) {\n continue;\n }\n const createdAt = stored.record.created_at.getTime();\n if (input.start_timestamp !== undefined && createdAt < input.start_timestamp.getTime()) {\n continue;\n }\n if (input.end_timestamp !== undefined && createdAt > input.end_timestamp.getTime()) {\n continue;\n }\n records.push(stored.record);\n }\n records.sort((a, b) => {\n const aTime = a.updated_at.getTime();\n const bTime = b.updated_at.getTime();\n if (aTime !== bTime) {\n return input.order === 'asc' ? aTime - bTime : bTime - aTime;\n }\n // Same lexicographic order as the keyset predicate below (and Postgres/SQLite).\n return input.order === 'asc'\n ? compareSessionId(a.session_id, b.session_id)\n : compareSessionId(b.session_id, a.session_id);\n });\n\n let filtered = records;\n const cursor = decodeSessionListPageToken(input.page_token);\n if (cursor) {\n const cursorTime = new Date(cursor.updated_at).getTime();\n filtered = records.filter(record => {\n const t = record.updated_at.getTime();\n const idCmp = compareSessionId(record.session_id, cursor.session_id);\n if (input.order === 'asc') {\n return t > cursorTime || (t === cursorTime && idCmp > 0);\n }\n return t < cursorTime || (t === cursorTime && idCmp < 0);\n });\n }\n\n const page = paginateSessionListRows(filtered, input.limit, row => row.updated_at.toISOString());\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async createTurn(input: CreateTurnInput<TTurnCustom>): Promise<void> {\n // Atomicity is free here: this body is fully synchronous, so Node's\n // run-to-completion guarantees it. Real backends must still use their own\n // locking/transactions to satisfy the ISessionStore createTurn contract.\n const sKey = sessionKey(input.turn.session_id);\n const stored = this.sessions.get(sKey);\n if (!stored) {\n throw new SessionNotFoundError(input.turn.session_id);\n }\n\n const previousTurnId = input.turn.previous_turn_id;\n let previousSnapshot: TurnSnapshot | undefined;\n if (previousTurnId !== null) {\n const prevKey = turnKey({ session_id: input.turn.session_id, turn_id: previousTurnId });\n const prev = this.turns.get(prevKey);\n // Unknown previous_turn_id is allowed (relaxed): treat as no inheritance.\n // A still-running previous must be frozen first.\n if (prev !== undefined) {\n if (prev.state.status === 'running') {\n throw new PreviousTurnRunningError(previousTurnId);\n }\n previousSnapshot = prev.snapshot;\n }\n }\n\n const tKey = turnKey(input.turn);\n if (this.turns.has(tKey)) {\n throw new TurnAlreadyExistsError(input.turn.turn_id);\n }\n\n const snapshot = buildSnapshotFromDelta({\n previousSnapshot,\n new_threads: input.new_threads,\n new_context_appends: input.new_context_appends,\n capability_states: input.capability_states,\n });\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...deepCopy(input.turn),\n snapshot,\n };\n\n this.turns.set(tKey, turnRecord);\n this.events.set(tKey, []);\n stored.turnIds.push(input.turn.turn_id);\n stored.record.last_turn_id = input.turn.turn_id;\n stored.record.last_activity_timestamp_ms = Date.now();\n stored.record.updated_at = new Date();\n if (input.update_session_title_if_not_exist !== null && stored.record.title === null) {\n stored.record.title = input.update_session_title_if_not_exist;\n }\n }\n\n async freezeAndGetTurn(input: FreezeAndGetTurnInput): Promise<TurnRecord<TTurnCustom>> {\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n\n if (turn.state.status === 'running') {\n const cancelledState: TerminalTurnState = {\n status: 'cancelled',\n reason: input.reason,\n completed_at: new Date().toISOString(),\n };\n turn.state = cancelledState;\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n return deepCopy(turn);\n }\n\n async getTurn(input: GetTurnInput): Promise<TurnRecord<TTurnCustom> | undefined> {\n const turn = this.turns.get(turnKey(input));\n return turn ? deepCopy(turn) : undefined;\n }\n\n async listTurns(\n input: ListTurnsInput,\n ): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n const records = stored.turnIds.map(id => {\n const turn = this.turns.get(turnKey({ session_id: input.session_id, turn_id: id }));\n if (!turn) {\n throw new TurnNotFoundError(id);\n }\n const { snapshot, ...row } = deepCopy(turn);\n void snapshot;\n return row;\n });\n return paginate(records, input.limit, input.page_token);\n }\n\n async updateTurnState(input: UpdateTurnStateInput): Promise<void> {\n // Same as createTurn: synchronous body ⇒ atomic under run-to-completion.\n const tKey = turnKey(input);\n const turn = this.requireTurn(input.session_id, input.turn_id);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(input.turn_id, turn.state);\n }\n turn.state = deepCopy(input.state);\n turn.updated_at = new Date();\n const list = this.events.get(tKey);\n if (list) {\n list.push(deepCopy(input.turn_done_event));\n }\n }\n\n async appendToEvents(input: AppendToEventsInput): Promise<void> {\n this.requireRunningTurn(input.session_id, input.turn_id);\n const tKey = turnKey(input);\n const list = this.events.get(tKey);\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n list.push(...deepCopy(input.events));\n return;\n }\n\n private requireTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.turns.get(turnKey({ session_id: sessionId, turn_id: turnId }));\n if (!turn) {\n throw new TurnNotFoundError(turnId);\n }\n return turn;\n }\n\n private requireRunningTurn(sessionId: string, turnId: string): TurnRecord<TTurnCustom> {\n const turn = this.requireTurn(sessionId, turnId);\n if (turn.state.status !== 'running') {\n throw new TurnNotRunningError(turnId, turn.state);\n }\n return turn;\n }\n\n async addThreads(input: AddThreadsInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const thread of input.threads) {\n turn.snapshot.threads[thread.thread_id] = deepCopy(thread);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async removeThreads(input: RemoveThreadsInput): Promise<void> {\n if (input.thread_ids.length === 0) {\n return;\n }\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n for (const id of input.thread_ids) {\n Reflect.deleteProperty(turn.snapshot.threads, id);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async appendToThreadContext(input: AppendToThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.context.push(...deepCopy(input.context));\n if (input.current_context_usage !== null) {\n thread.current_context_usage = deepCopy(input.current_context_usage);\n }\n if (input.completion !== null) {\n thread.completion = deepCopy(input.completion);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async overwriteThreadContext(input: OverwriteThreadContextInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const threadId = input.event.thread_id;\n const thread = turn.snapshot.threads[threadId];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${threadId}`);\n }\n thread.context = deepCopy(input.event.context);\n thread.current_context_usage = deepCopy(input.event.current_context_usage);\n turn.updated_at = new Date();\n return;\n }\n\n async patchMCPServers(input: PatchMCPServersInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.mcp_servers ??= {};\n for (const server of input.mcp_servers) {\n turn.snapshot.mcp_servers[server.id] = deepCopy(server);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async patchSandboxInfo(input: PatchSandboxInfoInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n turn.snapshot.sandbox_info = deepCopy(input.sandbox_info);\n turn.updated_at = new Date();\n return;\n }\n\n async patchThreadCapabilityState(input: PatchThreadCapabilityStateInput): Promise<void> {\n const turn = this.requireRunningTurn(input.session_id, input.turn_id);\n const thread = turn.snapshot.threads[input.thread_id];\n if (!thread) {\n throw new SessionStoreInvariantError(`Thread not found: ${input.thread_id}`);\n }\n thread.capability_state ??= {};\n if (input.state === null) {\n Reflect.deleteProperty(thread.capability_state, input.key);\n if (Object.keys(thread.capability_state).length === 0) {\n thread.capability_state = null;\n }\n } else {\n thread.capability_state[input.key] = deepCopy(input.state);\n }\n turn.updated_at = new Date();\n return;\n }\n\n async listTurnEvents(input: ListTurnEventsInput): Promise<{\n data: PersistedTurnEvent[];\n pagination: TokenPagination;\n }> {\n this.requireTurn(input.session_id, input.turn_id);\n const list = this.events.get(turnKey(input));\n if (!list) {\n throw new TurnNotFoundError(input.turn_id);\n }\n const ordered = [...list].sort((a, b) =>\n input.order === 'desc' ? b.id.localeCompare(a.id) : a.id.localeCompare(b.id),\n );\n const page = paginate(ordered, input.limit, input.page_token);\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n async listSessionEvents(input: ListSessionEventsInput): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n const stored = this.sessions.get(sessionKey(input.session_id));\n if (!stored) {\n throw new SessionNotFoundError(input.session_id);\n }\n\n const decodedCursor = input.page_token === undefined ? undefined : decodeSessionEventPageToken(input.page_token);\n const lastTurnId = decodedCursor?.last_turn_id ?? input.last_turn_id ?? stored.record.last_turn_id;\n if (lastTurnId === null) {\n return { data: [], pagination: { limit: input.limit } };\n }\n const cursor: SessionEventPageCursor = {\n last_turn_id: lastTurnId,\n offset: decodedCursor?.offset ?? 0,\n };\n\n const anchor = this.turns.get(turnKey({ session_id: input.session_id, turn_id: cursor.last_turn_id }));\n if (!anchor) {\n throw new TurnNotFoundError(cursor.last_turn_id);\n }\n const turnIds = this.resolveAncestorChain(input.session_id, anchor);\n const flattened: SessionEventItem[] = [];\n for (const turnId of [...turnIds].reverse()) {\n const evts = this.events.get(turnKey({ session_id: input.session_id, turn_id: turnId })) ?? [];\n for (const event of [...evts].sort((a, b) => b.id.localeCompare(a.id))) {\n flattened.push({ turn_id: turnId, event });\n }\n }\n const page = paginateSessionEventRows(\n flattened.slice(cursor.offset, cursor.offset + input.limit + 1),\n input.limit,\n cursor,\n );\n return { data: deepCopy(page.data), pagination: page.pagination };\n }\n\n /**\n * Full chain (oldest first, anchor last). `ancestor_ids` may be only the\n * previous N ancestors, so spill through the oldest ancestor's own window\n * until a root or gap. A missing turn or repeated id ends the walk.\n */\n private resolveAncestorChain(sessionId: string, anchor: TurnRecord<TTurnCustom>): string[] {\n const chain = [...anchor.ancestor_ids, anchor.turn_id];\n const seen = new Set(chain);\n let oldestId = chain[0];\n while (oldestId && oldestId !== anchor.turn_id) {\n const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));\n if (!oldest) {\n break;\n }\n const older = oldest.ancestor_ids.filter(id => !seen.has(id));\n if (older.length === 0) {\n break;\n }\n chain.unshift(...older);\n for (const id of older) {\n seen.add(id);\n }\n oldestId = older[0];\n }\n return chain;\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// src/agent-session/store/InMemorySessionStore.ts
|
|
2
2
|
import { getEmptyCurrentContextUsage } from "../../core/runtime/contextUsage.mjs";
|
|
3
|
-
import { CancellationReason } from "../schemas/turn.mjs";
|
|
4
3
|
import { assertCreateTurnThreadDelta } from "./assertCreateTurnThreadDelta.mjs";
|
|
5
4
|
import { decodeOffsetPageToken, encodeOffsetPageToken } from "./OffsetPageToken.mjs";
|
|
6
5
|
import {
|
|
@@ -27,8 +26,12 @@ function turnKey({ session_id, turn_id }) {
|
|
|
27
26
|
return `${session_id}:${turn_id}`;
|
|
28
27
|
}
|
|
29
28
|
function compareSessionId(a, b) {
|
|
30
|
-
if (a < b)
|
|
31
|
-
|
|
29
|
+
if (a < b) {
|
|
30
|
+
return -1;
|
|
31
|
+
}
|
|
32
|
+
if (a > b) {
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
32
35
|
return 0;
|
|
33
36
|
}
|
|
34
37
|
function newThreadSnapshot(thread) {
|
|
@@ -156,7 +159,9 @@ var InMemorySessionStore = class {
|
|
|
156
159
|
async listSessions(input) {
|
|
157
160
|
const records = [];
|
|
158
161
|
for (const stored of this.sessions.values()) {
|
|
159
|
-
if (stored.record.tenant_id !== input.tenant_id)
|
|
162
|
+
if (stored.record.tenant_id !== input.tenant_id) {
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
160
165
|
if (input.agent_id !== void 0 && (stored.record.agent.type !== "reference" || stored.record.agent.id !== input.agent_id)) {
|
|
161
166
|
continue;
|
|
162
167
|
}
|
|
@@ -164,8 +169,12 @@ var InMemorySessionStore = class {
|
|
|
164
169
|
continue;
|
|
165
170
|
}
|
|
166
171
|
const createdAt = stored.record.created_at.getTime();
|
|
167
|
-
if (input.start_timestamp !== void 0 && createdAt < input.start_timestamp.getTime())
|
|
168
|
-
|
|
172
|
+
if (input.start_timestamp !== void 0 && createdAt < input.start_timestamp.getTime()) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (input.end_timestamp !== void 0 && createdAt > input.end_timestamp.getTime()) {
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
169
178
|
records.push(stored.record);
|
|
170
179
|
}
|
|
171
180
|
records.sort((a, b) => {
|
|
@@ -240,7 +249,7 @@ var InMemorySessionStore = class {
|
|
|
240
249
|
if (turn.state.status === "running") {
|
|
241
250
|
const cancelledState = {
|
|
242
251
|
status: "cancelled",
|
|
243
|
-
reason:
|
|
252
|
+
reason: input.reason,
|
|
244
253
|
completed_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
245
254
|
};
|
|
246
255
|
turn.state = cancelledState;
|
|
@@ -445,11 +454,17 @@ var InMemorySessionStore = class {
|
|
|
445
454
|
let oldestId = chain[0];
|
|
446
455
|
while (oldestId && oldestId !== anchor.turn_id) {
|
|
447
456
|
const oldest = this.turns.get(turnKey({ session_id: sessionId, turn_id: oldestId }));
|
|
448
|
-
if (!oldest)
|
|
457
|
+
if (!oldest) {
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
449
460
|
const older = oldest.ancestor_ids.filter((id) => !seen.has(id));
|
|
450
|
-
if (older.length === 0)
|
|
461
|
+
if (older.length === 0) {
|
|
462
|
+
break;
|
|
463
|
+
}
|
|
451
464
|
chain.unshift(...older);
|
|
452
|
-
for (const id of older)
|
|
465
|
+
for (const id of older) {
|
|
466
|
+
seen.add(id);
|
|
467
|
+
}
|
|
453
468
|
oldestId = older[0];
|
|
454
469
|
}
|
|
455
470
|
return chain;
|