@truefoundry/trueforge-core 0.2.0-rc.0 → 0.2.0-rc.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.
Files changed (63) hide show
  1. package/dist/agent-session/SessionHandle.d.ts +1 -0
  2. package/dist/agent-session/SessionHandle.d.ts.map +1 -1
  3. package/dist/agent-session/SessionHandle.js +3 -0
  4. package/dist/agent-session/SessionHandle.js.map +1 -1
  5. package/dist/agent-session/SessionHandle.mjs +3 -0
  6. package/dist/agent-session/SessionHandle.mjs.map +1 -1
  7. package/dist/agent-session/Sessions.d.ts +21 -6
  8. package/dist/agent-session/Sessions.d.ts.map +1 -1
  9. package/dist/agent-session/Sessions.js +46 -1
  10. package/dist/agent-session/Sessions.js.map +1 -1
  11. package/dist/agent-session/Sessions.mjs +46 -1
  12. package/dist/agent-session/Sessions.mjs.map +1 -1
  13. package/dist/agent-session/index.d.ts +6 -4
  14. package/dist/agent-session/index.d.ts.map +1 -1
  15. package/dist/agent-session/index.js +15 -0
  16. package/dist/agent-session/index.js.map +1 -1
  17. package/dist/agent-session/index.mjs +17 -1
  18. package/dist/agent-session/index.mjs.map +1 -1
  19. package/dist/agent-session/models/SessionRecord.d.ts +14 -2
  20. package/dist/agent-session/models/SessionRecord.d.ts.map +1 -1
  21. package/dist/agent-session/models/SessionRecord.js.map +1 -1
  22. package/dist/agent-session/schemas/session.d.ts +43 -1
  23. package/dist/agent-session/schemas/session.d.ts.map +1 -1
  24. package/dist/agent-session/schemas/session.js +43 -5
  25. package/dist/agent-session/schemas/session.js.map +1 -1
  26. package/dist/agent-session/schemas/session.mjs +37 -4
  27. package/dist/agent-session/schemas/session.mjs.map +1 -1
  28. package/dist/agent-session/schemas/subject.d.ts +9 -0
  29. package/dist/agent-session/schemas/subject.d.ts.map +1 -0
  30. package/dist/agent-session/schemas/subject.js +36 -0
  31. package/dist/agent-session/schemas/subject.js.map +1 -0
  32. package/dist/agent-session/schemas/subject.mjs +11 -0
  33. package/dist/agent-session/schemas/subject.mjs.map +1 -0
  34. package/dist/agent-session/store/ISessionStore.d.ts +44 -20
  35. package/dist/agent-session/store/ISessionStore.d.ts.map +1 -1
  36. package/dist/agent-session/store/ISessionStore.js.map +1 -1
  37. package/dist/agent-session/store/InMemorySessionStore.d.ts +4 -1
  38. package/dist/agent-session/store/InMemorySessionStore.d.ts.map +1 -1
  39. package/dist/agent-session/store/InMemorySessionStore.js +66 -2
  40. package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
  41. package/dist/agent-session/store/InMemorySessionStore.mjs +67 -2
  42. package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
  43. package/dist/agent-session/store/SessionStoreErrors.d.ts +4 -0
  44. package/dist/agent-session/store/SessionStoreErrors.d.ts.map +1 -1
  45. package/dist/agent-session/store/SessionStoreErrors.js +10 -0
  46. package/dist/agent-session/store/SessionStoreErrors.js.map +1 -1
  47. package/dist/agent-session/store/SessionStoreErrors.mjs +9 -0
  48. package/dist/agent-session/store/SessionStoreErrors.mjs.map +1 -1
  49. package/dist/core/llm/VercelAILLM.d.ts +1 -1
  50. package/dist/core/llm/VercelAILLM.d.ts.map +1 -1
  51. package/dist/core/llm/VercelAILLM.js +4 -2
  52. package/dist/core/llm/VercelAILLM.js.map +1 -1
  53. package/dist/core/llm/VercelAILLM.mjs +4 -2
  54. package/dist/core/llm/VercelAILLM.mjs.map +1 -1
  55. package/dist/core/mcp/remoteMcpClient.js +1 -1
  56. package/dist/core/mcp/remoteMcpClient.js.map +1 -1
  57. package/dist/core/mcp/remoteMcpClient.mjs +1 -1
  58. package/dist/core/mcp/remoteMcpClient.mjs.map +1 -1
  59. package/dist/core/sandbox/Sandbox.js +5 -5
  60. package/dist/core/sandbox/Sandbox.js.map +1 -1
  61. package/dist/core/sandbox/Sandbox.mjs +1 -1
  62. package/dist/core/sandbox/Sandbox.mjs.map +1 -1
  63. package/package.json +1 -1
@@ -19,6 +19,7 @@ export declare class SessionHandle<TSessionCustom extends object = Record<string
19
19
  get tenant_id(): string;
20
20
  get agent(): SessionAgent;
21
21
  get custom(): TSessionCustom | null;
22
+ get metadata(): SessionRecord<TSessionCustom>['metadata'];
22
23
  get record(): SessionRecord<TSessionCustom>;
23
24
  /**
24
25
  * Prepares and commits a new turn — NO execution happens here (execution =
@@ -1 +1 @@
1
- {"version":3,"file":"SessionHandle.d.ts","sourceRoot":"","sources":["../../src/agent-session/SessionHandle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SessionHandle.d.ts","sourceRoot":"","sources":["../../src/agent-session/SessionHandle.ts"],"names":[],"mappings":"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"}
@@ -125,6 +125,9 @@ var SessionHandle = class {
125
125
  get custom() {
126
126
  return this.session.custom;
127
127
  }
128
+ get metadata() {
129
+ return this.session.metadata;
130
+ }
128
131
  get record() {
129
132
  return this.session;
130
133
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent-session/SessionHandle.ts"],"sourcesContent":["/**\n * Bound session handle: starts turns via {@link SessionHandle.createTurn}.\n */\nimport { newEventId } from '../core/events/schema';\nimport type { AgentDefinition } from '../core/runtime/AgentDefinition';\nimport { AgentThread } from '../core/runtime/AgentThread';\nimport type {\n AgentThreadAppendContext,\n AgentThreadSendBatch,\n AgentThreadSnapshot,\n} from '../core/runtime/AgentThread.types';\nimport { AgentThreadOrchestrator } from '../core/runtime/AgentThreadOrchestrator';\nimport {\n isApprovalDecisionMessage,\n isClientSideToolResponseMessage,\n isInputUserMessage,\n} from '../core/runtime/contextUtils';\nimport type { CreateDynamicSubAgentThread } from '../core/runtime/CreateDynamicSubAgentThread';\nimport type { Sandbox } from '../core/sandbox/Sandbox';\nimport type { AgentTracing } from '../core/tracing/AgentTracing';\nimport { builtinsFromSpec } from './builtinsFromSpec';\nimport type { ITurnResourceResolver, ResolvedAgentDefinition } from './ITurnResourceResolver';\nimport type { SessionRecord } from './models/SessionRecord';\nimport { MAIN_THREAD_ID, type TurnRecord, type TurnSnapshot } from './models/TurnRecord';\nimport type { AgentSpec } from './schemas/agentSpec';\nimport type { SessionEventItem } from './schemas/events';\nimport { EventType, type TurnDoneEvent } from './schemas/events';\nimport type { TokenPagination } from './schemas/pagination';\nimport type { SessionAgent } from './schemas/session';\nimport type { TurnInputItem } from './schemas/turn';\nimport { CancellationReason } from './schemas/turn';\nimport type { ISessionStore, NewThreadInit, TurnContextAppend, TurnRecordWithoutSnapshot } from './store/ISessionStore';\nimport { TurnHandle } from './TurnHandle';\n\n/** How many recent ancestors SessionHandle persists on each turn. Store-local. */\nconst MAX_TURN_ANCESTORS = 20;\n\nfunction resolvePreviousTurnId(requested: string | undefined, lastTurnId: string | null | undefined): string | null {\n if (requested === 'none') {\n return null;\n }\n if (requested === undefined || requested === 'auto') {\n return lastTurnId ?? null;\n }\n return requested;\n}\n\nfunction toSendBatch(input: TurnInputItem[] | undefined): AgentThreadSendBatch {\n if (!input || input.length === 0) {\n return [];\n }\n if (input.every(msg => isApprovalDecisionMessage(msg) || isClientSideToolResponseMessage(msg))) {\n return input;\n }\n if (input.every(isInputUserMessage)) {\n return input;\n }\n throw new Error('input must be homogeneous: all user messages, or all approval/tool-response messages');\n}\n\nfunction toNewThreadInit(snapshot: AgentThreadSnapshot): NewThreadInit {\n const { context, current_context_usage, completion, capability_state, ...rest } = snapshot;\n void context;\n void current_context_usage;\n void completion;\n void capability_state;\n return rest;\n}\n\nfunction collectContextAppends(\n events: AsyncGenerator<AgentThreadAppendContext, void, unknown>,\n): Promise<TurnContextAppend[]> {\n return (async () => {\n const appendMap = new Map<string, TurnContextAppend>();\n for await (const event of events) {\n const existing = appendMap.get(event.thread_id);\n if (existing) {\n existing.context.push(...event.context);\n if (event.current_context_usage !== undefined) {\n existing.current_context_usage = event.current_context_usage;\n }\n } else {\n appendMap.set(event.thread_id, {\n thread_id: event.thread_id,\n context: [...event.context],\n current_context_usage: event.current_context_usage ?? null,\n });\n }\n }\n return [...appendMap.values()];\n })();\n}\n\nfunction cancelledTurnDoneEvent(reason: CancellationReason): TurnDoneEvent {\n return {\n type: EventType.TURN_DONE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n state: {\n status: 'cancelled',\n reason,\n completed_at: new Date().toISOString(),\n },\n thread_id: null,\n };\n}\n\nfunction threadsRecordFromMap(threads: Map<string, AgentThread>): Record<string, AgentThreadSnapshot> {\n const out: Record<string, AgentThreadSnapshot> = {};\n for (const [id, thread] of threads) {\n out[id] = thread.toSnapshot();\n }\n return out;\n}\n\n// Current-turn thread ids. Main (`MAIN_THREAD_ID`) is always present — first turn\n// synthesizes it; later turns always carry it in the previous snapshot.\nfunction threadIdsForCurrentTurn(snapshot: TurnSnapshot | undefined): string[] {\n return snapshot ? Object.keys(snapshot.threads) : [MAIN_THREAD_ID];\n}\n\nexport class SessionHandle<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n private session: SessionRecord<TSessionCustom>;\n\n constructor(options: { store: ISessionStore<TSessionCustom, TTurnCustom>; session: SessionRecord<TSessionCustom> }) {\n this.store = options.store;\n this.session = options.session;\n }\n\n get session_id(): string {\n return this.session.session_id;\n }\n\n get tenant_id(): string {\n return this.session.tenant_id;\n }\n\n get agent(): SessionAgent {\n return this.session.agent;\n }\n\n get custom(): TSessionCustom | null {\n return this.session.custom;\n }\n\n get record(): SessionRecord<TSessionCustom> {\n return this.session;\n }\n\n /**\n * Prepares and commits a new turn — NO execution happens here (execution =\n * TurnHandle.stream()). Builds threads from the previous turn's snapshot, then\n * sends the input through the orchestrator fully drained (validation +\n * context append; empty input still preflights threads awaiting user input),\n * then persists via one atomic store.createTurn LAST. A send/validation\n * failure therefore persists nothing. The returned turn is durable with\n * state { status: 'running' }.\n *\n * On any failure, createTurn() closes the resolver (best-effort) before rethrowing,\n * so resources acquired here (e.g. a sandbox VM) never outlive a failed run.\n * On success, ownership of resolver.close() passes to TurnHandle.stream().\n *\n * `previous_turn_id`: omitted/`'auto'` → session tip; `'none'` → new root\n * (no parent, even on a non-empty session); string → fork from that turn\n * (must exist). Concurrent `'auto'` forks both succeed.\n */\n async createTurn(input: {\n turn_id: string;\n input?: TurnInputItem[] | undefined;\n /** 'auto'/omitted → session.last_turn_id; 'none' → new root; id → fork from that turn. */\n previous_turn_id?: string | undefined;\n signal: AbortSignal;\n resolver: ITurnResourceResolver<TTurnCustom>;\n /** Value = stored as-is. Fn = merge over previous turn's custom. Omitted = undefined. */\n custom?: TTurnCustom | ((previous?: TTurnCustom) => TTurnCustom) | undefined;\n /**\n * Forwarded to store.createTurn: sets session.title in the same atomic\n * unit IF the session has none; never overwrites. The caller derives the\n * value (e.g. from the first user message) — the library does not.\n */\n update_session_title_if_not_exist?: string | undefined;\n }): Promise<TurnHandle<TTurnCustom>> {\n const previousTurnId = resolvePreviousTurnId(input.previous_turn_id, this.session.last_turn_id);\n const previous = previousTurnId\n ? await this.freezeTurn({\n turn_id: previousTurnId,\n reason: CancellationReason.CancelledForNextTurn,\n })\n : undefined;\n\n const custom = typeof input.custom === 'function' ? input.custom(previous?.custom ?? undefined) : input.custom;\n\n // Dispose-on-early-failure: any resource acquired below (sandbox handle,\n // MCP connections) is owned by createTurn() until the TurnHandle is returned; from then\n // on TurnHandle.stream()'s finally owns resolver.close(). On any throw in this\n // acquisition phase we close the resolver (best-effort, error swallowed)\n // and rethrow — same pattern as the gateway's sessionTurnHandler, which\n // wraps getAgent/handler.init and calls gatewayStore.dispose() on failure.\n try {\n const tracing = input.resolver.createTracing();\n const agent = this.session.agent;\n const spec = agent.type === 'inline' ? agent.spec : await input.resolver.resolveAgentSpec({ agent_id: agent.id });\n const sandbox = await input.resolver.resolveSandbox({\n spec,\n existing: previous?.snapshot.sandbox_info ?? undefined,\n previousTurn: previous,\n signal: input.signal,\n tracing,\n });\n\n const definitionsByThreadId = await this.resolveAgentDefinitions({\n previous,\n resolver: input.resolver,\n spec,\n tracing,\n signal: input.signal,\n });\n\n // Wire Code Mode once from main toolSets before threads share the sandbox.\n const mainDefinition = definitionsByThreadId.get(MAIN_THREAD_ID);\n if (!mainDefinition) {\n throw new Error('Unreachable: missing resolved agent definition for main thread');\n }\n if (sandbox) {\n sandbox.configureCodeMode(mainDefinition.definition.toolSets ?? []);\n }\n\n const agentThreads = this.buildThreads({\n previous,\n resolver: input.resolver,\n spec,\n sandbox,\n tracing,\n definitionsByThreadId,\n });\n\n const createDynamicSubAgentThread = this.makeCreateDynamicSubAgentThread({\n resolver: input.resolver,\n previous,\n spec,\n sandbox,\n tracing,\n });\n\n const orchestrator = new AgentThreadOrchestrator({\n agentThreads,\n createDynamicSubAgentThread,\n tracing,\n logger: input.resolver.logger,\n });\n\n // SEND BEFORE COMMIT — validate + append; throw ⇒ nothing persisted.\n const sendBatch = toSendBatch(input.input);\n const new_context_appends = await collectContextAppends(orchestrator.send(sendBatch));\n\n const turnId = input.turn_id;\n const now = new Date();\n\n const new_threads: NewThreadInit[] = [];\n if (!previous) {\n const root = agentThreads.get(MAIN_THREAD_ID);\n if (root) {\n new_threads.push(toNewThreadInit(root.toSnapshot()));\n }\n } else {\n for (const [threadId, thread] of agentThreads) {\n if (previous.snapshot.threads[threadId] === undefined) {\n new_threads.push(toNewThreadInit(thread.toSnapshot()));\n }\n }\n }\n\n const turnInit: TurnRecordWithoutSnapshot<TTurnCustom> = {\n turn_id: turnId,\n session_id: this.session.session_id,\n first_turn_id: previous?.first_turn_id ?? turnId,\n ancestor_ids: previous ? [...previous.ancestor_ids, previous.turn_id].slice(-MAX_TURN_ANCESTORS) : [],\n previous_turn_id: previousTurnId,\n state: { status: 'running' },\n input: input.input ?? [],\n created_at: now,\n updated_at: now,\n custom: custom ?? null,\n };\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...turnInit,\n snapshot: {\n threads: threadsRecordFromMap(agentThreads),\n mcp_servers: previous?.snapshot.mcp_servers ?? null,\n sandbox_info: previous?.snapshot.sandbox_info ?? null,\n },\n };\n\n await this.store.createTurn({\n turn: turnInit,\n new_threads,\n new_context_appends,\n capability_states: [...agentThreads].map(([thread_id, thread]) => ({\n thread_id,\n capability_state: thread.toSnapshot().capability_state,\n })),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist ?? null,\n });\n\n const refreshed = await this.store.getSession({\n tenant_id: this.tenant_id,\n session_id: this.session.session_id,\n });\n if (refreshed) {\n this.session = refreshed;\n }\n\n return new TurnHandle({\n store: this.store,\n turn: turnRecord,\n orchestrator,\n resolver: input.resolver,\n signal: input.signal,\n });\n } catch (error) {\n await input.resolver.close().catch((closeError: unknown) => {\n input.resolver.logger.warn('TurnResourceResolver.close() failed after createTurn() error', {\n err: closeError,\n });\n });\n throw error;\n }\n }\n\n /**\n * Conditionally cancel a running turn in this session and return the\n * now-immutable record. Already-terminal turns are returned unchanged.\n * Missing turn → {@link TurnNotFoundError}.\n */\n async freezeTurn(input: { turn_id: string; reason: CancellationReason }): Promise<TurnRecord<TTurnCustom>> {\n return this.store.freezeAndGetTurn({\n session_id: this.session.session_id,\n turn_id: input.turn_id,\n reason: input.reason,\n turn_done_event: cancelledTurnDoneEvent(input.reason),\n });\n }\n\n /** Returns the turn handle (store-backed; not executable), or undefined if not found. */\n async getTurn(turn_id: string): Promise<TurnHandle<TTurnCustom> | undefined> {\n return TurnHandle.get({\n store: this.store,\n session_id: this.session.session_id,\n turn_id,\n });\n }\n\n /** Paginated list of this session's turn rows (no snapshot). */\n async listTurns(input: {\n limit: number;\n page_token?: string | undefined;\n }): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n return this.store.listTurns({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n });\n }\n\n /**\n * Paginated session-wide feed of persisted events across turns, including\n * turn.created / turn.done lifecycle events. Reads from the store only —\n * nothing is synthesized on read.\n */\n async listEvents(input: {\n limit: number;\n page_token?: string | undefined;\n last_turn_id?: string | undefined;\n }): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n return this.store.listSessionEvents({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n last_turn_id: input.last_turn_id,\n });\n }\n\n private async resolveAgentDefinitions(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n tracing: AgentTracing;\n signal: AbortSignal;\n }): Promise<Map<string, ResolvedAgentDefinition>> {\n const snapshots = input.previous?.snapshot.threads;\n const threadIds = threadIdsForCurrentTurn(input.previous?.snapshot);\n const definitionsByThreadId = new Map<string, ResolvedAgentDefinition>();\n await Promise.all(\n threadIds.map(async threadId => {\n const previousThreadSnapshot = snapshots?.[threadId];\n const resolved = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: previousThreadSnapshot?.agent_info ?? undefined,\n previousTurn: input.previous,\n signal: input.signal,\n tracing: input.tracing,\n });\n definitionsByThreadId.set(threadId, resolved);\n }),\n );\n return definitionsByThreadId;\n }\n\n private buildThreads(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n definitionsByThreadId: ReadonlyMap<string, ResolvedAgentDefinition>;\n }): Map<string, AgentThread> {\n const snapshots = input.previous?.snapshot.threads;\n const map = new Map<string, AgentThread>();\n for (const threadId of threadIdsForCurrentTurn(input.previous?.snapshot)) {\n const resolvedDefinition = input.definitionsByThreadId.get(threadId);\n if (!resolvedDefinition) {\n throw new Error(`Unreachable: missing resolved agent definition for thread '${threadId}'`);\n }\n map.set(\n threadId,\n this.buildThread({\n threadId,\n previousThreadSnapshot: snapshots?.[threadId],\n resolver: input.resolver,\n spec: input.spec,\n sandbox: input.sandbox,\n tracing: input.tracing,\n resolvedDefinition,\n }),\n );\n }\n return map;\n }\n\n private buildThread(input: {\n threadId: string;\n previousThreadSnapshot?: AgentThreadSnapshot | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n resolvedDefinition: ResolvedAgentDefinition;\n }): AgentThread {\n const { definition, extraCapabilities } = input.resolvedDefinition;\n const isChild = Boolean(input.previousThreadSnapshot?.parent);\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition,\n isChild,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition,\n threadId: input.threadId,\n title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : 'main'),\n sandbox: input.sandbox,\n context: input.previousThreadSnapshot?.context,\n currentContextUsage: input.previousThreadSnapshot?.current_context_usage,\n parent: input.previousThreadSnapshot?.parent ?? undefined,\n agentInfo: input.previousThreadSnapshot?.agent_info ?? undefined,\n preComputedCompletion: input.previousThreadSnapshot?.completion ?? undefined,\n capabilities,\n capabilityState: input.previousThreadSnapshot?.capability_state ?? undefined,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n }\n\n private makeCreateDynamicSubAgentThread(input: {\n resolver: ITurnResourceResolver<TTurnCustom>;\n previous: TurnRecord<TTurnCustom> | undefined;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n }): CreateDynamicSubAgentThread {\n return async params => {\n const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: params.request,\n previousTurn: input.previous,\n signal: params.signal,\n tracing: input.tracing,\n });\n // Model override (request.model) is resolved inside resolveAgentDefinition\n // into modelClient — do not re-label a stale client here.\n const childDefinition: AgentDefinition = {\n ...definition,\n toolSets: params.parentDefinition.toolSets ?? definition.toolSets,\n // The delegated task goes in as the initial user message; the sub-agent\n // system prompt is SUB_AGENT_IDENTITY (added by AgentThread.buildInstruction).\n instruction: undefined,\n messages: [{ role: 'user', content: params.request.input }],\n // Sub-agents should return free-form summaries to the parent, not the user-facing structured response.\n responseFormat: undefined,\n };\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition: childDefinition,\n isChild: true,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition: childDefinition,\n threadId: params.threadId,\n title: params.request.name,\n sandbox: input.sandbox,\n parent: params.parent,\n agentInfo: params.request,\n capabilities,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n };\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/agent-session/SessionHandle.ts"],"sourcesContent":["/**\n * Bound session handle: starts turns via {@link SessionHandle.createTurn}.\n */\nimport { newEventId } from '../core/events/schema';\nimport type { AgentDefinition } from '../core/runtime/AgentDefinition';\nimport { AgentThread } from '../core/runtime/AgentThread';\nimport type {\n AgentThreadAppendContext,\n AgentThreadSendBatch,\n AgentThreadSnapshot,\n} from '../core/runtime/AgentThread.types';\nimport { AgentThreadOrchestrator } from '../core/runtime/AgentThreadOrchestrator';\nimport {\n isApprovalDecisionMessage,\n isClientSideToolResponseMessage,\n isInputUserMessage,\n} from '../core/runtime/contextUtils';\nimport type { CreateDynamicSubAgentThread } from '../core/runtime/CreateDynamicSubAgentThread';\nimport type { Sandbox } from '../core/sandbox/Sandbox';\nimport type { AgentTracing } from '../core/tracing/AgentTracing';\nimport { builtinsFromSpec } from './builtinsFromSpec';\nimport type { ITurnResourceResolver, ResolvedAgentDefinition } from './ITurnResourceResolver';\nimport type { SessionRecord } from './models/SessionRecord';\nimport { MAIN_THREAD_ID, type TurnRecord, type TurnSnapshot } from './models/TurnRecord';\nimport type { AgentSpec } from './schemas/agentSpec';\nimport type { SessionEventItem } from './schemas/events';\nimport { EventType, type TurnDoneEvent } from './schemas/events';\nimport type { TokenPagination } from './schemas/pagination';\nimport type { SessionAgent } from './schemas/session';\nimport type { TurnInputItem } from './schemas/turn';\nimport { CancellationReason } from './schemas/turn';\nimport type { ISessionStore, NewThreadInit, TurnContextAppend, TurnRecordWithoutSnapshot } from './store/ISessionStore';\nimport { TurnHandle } from './TurnHandle';\n\n/** How many recent ancestors SessionHandle persists on each turn. Store-local. */\nconst MAX_TURN_ANCESTORS = 20;\n\nfunction resolvePreviousTurnId(requested: string | undefined, lastTurnId: string | null | undefined): string | null {\n if (requested === 'none') {\n return null;\n }\n if (requested === undefined || requested === 'auto') {\n return lastTurnId ?? null;\n }\n return requested;\n}\n\nfunction toSendBatch(input: TurnInputItem[] | undefined): AgentThreadSendBatch {\n if (!input || input.length === 0) {\n return [];\n }\n if (input.every(msg => isApprovalDecisionMessage(msg) || isClientSideToolResponseMessage(msg))) {\n return input;\n }\n if (input.every(isInputUserMessage)) {\n return input;\n }\n throw new Error('input must be homogeneous: all user messages, or all approval/tool-response messages');\n}\n\nfunction toNewThreadInit(snapshot: AgentThreadSnapshot): NewThreadInit {\n const { context, current_context_usage, completion, capability_state, ...rest } = snapshot;\n void context;\n void current_context_usage;\n void completion;\n void capability_state;\n return rest;\n}\n\nfunction collectContextAppends(\n events: AsyncGenerator<AgentThreadAppendContext, void, unknown>,\n): Promise<TurnContextAppend[]> {\n return (async () => {\n const appendMap = new Map<string, TurnContextAppend>();\n for await (const event of events) {\n const existing = appendMap.get(event.thread_id);\n if (existing) {\n existing.context.push(...event.context);\n if (event.current_context_usage !== undefined) {\n existing.current_context_usage = event.current_context_usage;\n }\n } else {\n appendMap.set(event.thread_id, {\n thread_id: event.thread_id,\n context: [...event.context],\n current_context_usage: event.current_context_usage ?? null,\n });\n }\n }\n return [...appendMap.values()];\n })();\n}\n\nfunction cancelledTurnDoneEvent(reason: CancellationReason): TurnDoneEvent {\n return {\n type: EventType.TURN_DONE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n state: {\n status: 'cancelled',\n reason,\n completed_at: new Date().toISOString(),\n },\n thread_id: null,\n };\n}\n\nfunction threadsRecordFromMap(threads: Map<string, AgentThread>): Record<string, AgentThreadSnapshot> {\n const out: Record<string, AgentThreadSnapshot> = {};\n for (const [id, thread] of threads) {\n out[id] = thread.toSnapshot();\n }\n return out;\n}\n\n// Current-turn thread ids. Main (`MAIN_THREAD_ID`) is always present — first turn\n// synthesizes it; later turns always carry it in the previous snapshot.\nfunction threadIdsForCurrentTurn(snapshot: TurnSnapshot | undefined): string[] {\n return snapshot ? Object.keys(snapshot.threads) : [MAIN_THREAD_ID];\n}\n\nexport class SessionHandle<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n private session: SessionRecord<TSessionCustom>;\n\n constructor(options: { store: ISessionStore<TSessionCustom, TTurnCustom>; session: SessionRecord<TSessionCustom> }) {\n this.store = options.store;\n this.session = options.session;\n }\n\n get session_id(): string {\n return this.session.session_id;\n }\n\n get tenant_id(): string {\n return this.session.tenant_id;\n }\n\n get agent(): SessionAgent {\n return this.session.agent;\n }\n\n get custom(): TSessionCustom | null {\n return this.session.custom;\n }\n\n get metadata(): SessionRecord<TSessionCustom>['metadata'] {\n return this.session.metadata;\n }\n\n get record(): SessionRecord<TSessionCustom> {\n return this.session;\n }\n\n /**\n * Prepares and commits a new turn — NO execution happens here (execution =\n * TurnHandle.stream()). Builds threads from the previous turn's snapshot, then\n * sends the input through the orchestrator fully drained (validation +\n * context append; empty input still preflights threads awaiting user input),\n * then persists via one atomic store.createTurn LAST. A send/validation\n * failure therefore persists nothing. The returned turn is durable with\n * state { status: 'running' }.\n *\n * On any failure, createTurn() closes the resolver (best-effort) before rethrowing,\n * so resources acquired here (e.g. a sandbox VM) never outlive a failed run.\n * On success, ownership of resolver.close() passes to TurnHandle.stream().\n *\n * `previous_turn_id`: omitted/`'auto'` → session tip; `'none'` → new root\n * (no parent, even on a non-empty session); string → fork from that turn\n * (must exist). Concurrent `'auto'` forks both succeed.\n */\n async createTurn(input: {\n turn_id: string;\n input?: TurnInputItem[] | undefined;\n /** 'auto'/omitted → session.last_turn_id; 'none' → new root; id → fork from that turn. */\n previous_turn_id?: string | undefined;\n signal: AbortSignal;\n resolver: ITurnResourceResolver<TTurnCustom>;\n /** Value = stored as-is. Fn = merge over previous turn's custom. Omitted = undefined. */\n custom?: TTurnCustom | ((previous?: TTurnCustom) => TTurnCustom) | undefined;\n /**\n * Forwarded to store.createTurn: sets session.title in the same atomic\n * unit IF the session has none; never overwrites. The caller derives the\n * value (e.g. from the first user message) — the library does not.\n */\n update_session_title_if_not_exist?: string | undefined;\n }): Promise<TurnHandle<TTurnCustom>> {\n const previousTurnId = resolvePreviousTurnId(input.previous_turn_id, this.session.last_turn_id);\n const previous = previousTurnId\n ? await this.freezeTurn({\n turn_id: previousTurnId,\n reason: CancellationReason.CancelledForNextTurn,\n })\n : undefined;\n\n const custom = typeof input.custom === 'function' ? input.custom(previous?.custom ?? undefined) : input.custom;\n\n // Dispose-on-early-failure: any resource acquired below (sandbox handle,\n // MCP connections) is owned by createTurn() until the TurnHandle is returned; from then\n // on TurnHandle.stream()'s finally owns resolver.close(). On any throw in this\n // acquisition phase we close the resolver (best-effort, error swallowed)\n // and rethrow — same pattern as the gateway's sessionTurnHandler, which\n // wraps getAgent/handler.init and calls gatewayStore.dispose() on failure.\n try {\n const tracing = input.resolver.createTracing();\n const agent = this.session.agent;\n const spec = agent.type === 'inline' ? agent.spec : await input.resolver.resolveAgentSpec({ agent_id: agent.id });\n const sandbox = await input.resolver.resolveSandbox({\n spec,\n existing: previous?.snapshot.sandbox_info ?? undefined,\n previousTurn: previous,\n signal: input.signal,\n tracing,\n });\n\n const definitionsByThreadId = await this.resolveAgentDefinitions({\n previous,\n resolver: input.resolver,\n spec,\n tracing,\n signal: input.signal,\n });\n\n // Wire Code Mode once from main toolSets before threads share the sandbox.\n const mainDefinition = definitionsByThreadId.get(MAIN_THREAD_ID);\n if (!mainDefinition) {\n throw new Error('Unreachable: missing resolved agent definition for main thread');\n }\n if (sandbox) {\n sandbox.configureCodeMode(mainDefinition.definition.toolSets ?? []);\n }\n\n const agentThreads = this.buildThreads({\n previous,\n resolver: input.resolver,\n spec,\n sandbox,\n tracing,\n definitionsByThreadId,\n });\n\n const createDynamicSubAgentThread = this.makeCreateDynamicSubAgentThread({\n resolver: input.resolver,\n previous,\n spec,\n sandbox,\n tracing,\n });\n\n const orchestrator = new AgentThreadOrchestrator({\n agentThreads,\n createDynamicSubAgentThread,\n tracing,\n logger: input.resolver.logger,\n });\n\n // SEND BEFORE COMMIT — validate + append; throw ⇒ nothing persisted.\n const sendBatch = toSendBatch(input.input);\n const new_context_appends = await collectContextAppends(orchestrator.send(sendBatch));\n\n const turnId = input.turn_id;\n const now = new Date();\n\n const new_threads: NewThreadInit[] = [];\n if (!previous) {\n const root = agentThreads.get(MAIN_THREAD_ID);\n if (root) {\n new_threads.push(toNewThreadInit(root.toSnapshot()));\n }\n } else {\n for (const [threadId, thread] of agentThreads) {\n if (previous.snapshot.threads[threadId] === undefined) {\n new_threads.push(toNewThreadInit(thread.toSnapshot()));\n }\n }\n }\n\n const turnInit: TurnRecordWithoutSnapshot<TTurnCustom> = {\n turn_id: turnId,\n session_id: this.session.session_id,\n first_turn_id: previous?.first_turn_id ?? turnId,\n ancestor_ids: previous ? [...previous.ancestor_ids, previous.turn_id].slice(-MAX_TURN_ANCESTORS) : [],\n previous_turn_id: previousTurnId,\n state: { status: 'running' },\n input: input.input ?? [],\n created_at: now,\n updated_at: now,\n custom: custom ?? null,\n };\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...turnInit,\n snapshot: {\n threads: threadsRecordFromMap(agentThreads),\n mcp_servers: previous?.snapshot.mcp_servers ?? null,\n sandbox_info: previous?.snapshot.sandbox_info ?? null,\n },\n };\n\n await this.store.createTurn({\n turn: turnInit,\n new_threads,\n new_context_appends,\n capability_states: [...agentThreads].map(([thread_id, thread]) => ({\n thread_id,\n capability_state: thread.toSnapshot().capability_state,\n })),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist ?? null,\n });\n\n const refreshed = await this.store.getSession({\n tenant_id: this.tenant_id,\n session_id: this.session.session_id,\n });\n if (refreshed) {\n this.session = refreshed;\n }\n\n return new TurnHandle({\n store: this.store,\n turn: turnRecord,\n orchestrator,\n resolver: input.resolver,\n signal: input.signal,\n });\n } catch (error) {\n await input.resolver.close().catch((closeError: unknown) => {\n input.resolver.logger.warn('TurnResourceResolver.close() failed after createTurn() error', {\n err: closeError,\n });\n });\n throw error;\n }\n }\n\n /**\n * Conditionally cancel a running turn in this session and return the\n * now-immutable record. Already-terminal turns are returned unchanged.\n * Missing turn → {@link TurnNotFoundError}.\n */\n async freezeTurn(input: { turn_id: string; reason: CancellationReason }): Promise<TurnRecord<TTurnCustom>> {\n return this.store.freezeAndGetTurn({\n session_id: this.session.session_id,\n turn_id: input.turn_id,\n reason: input.reason,\n turn_done_event: cancelledTurnDoneEvent(input.reason),\n });\n }\n\n /** Returns the turn handle (store-backed; not executable), or undefined if not found. */\n async getTurn(turn_id: string): Promise<TurnHandle<TTurnCustom> | undefined> {\n return TurnHandle.get({\n store: this.store,\n session_id: this.session.session_id,\n turn_id,\n });\n }\n\n /** Paginated list of this session's turn rows (no snapshot). */\n async listTurns(input: {\n limit: number;\n page_token?: string | undefined;\n }): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n return this.store.listTurns({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n });\n }\n\n /**\n * Paginated session-wide feed of persisted events across turns, including\n * turn.created / turn.done lifecycle events. Reads from the store only —\n * nothing is synthesized on read.\n */\n async listEvents(input: {\n limit: number;\n page_token?: string | undefined;\n last_turn_id?: string | undefined;\n }): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n return this.store.listSessionEvents({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n last_turn_id: input.last_turn_id,\n });\n }\n\n private async resolveAgentDefinitions(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n tracing: AgentTracing;\n signal: AbortSignal;\n }): Promise<Map<string, ResolvedAgentDefinition>> {\n const snapshots = input.previous?.snapshot.threads;\n const threadIds = threadIdsForCurrentTurn(input.previous?.snapshot);\n const definitionsByThreadId = new Map<string, ResolvedAgentDefinition>();\n await Promise.all(\n threadIds.map(async threadId => {\n const previousThreadSnapshot = snapshots?.[threadId];\n const resolved = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: previousThreadSnapshot?.agent_info ?? undefined,\n previousTurn: input.previous,\n signal: input.signal,\n tracing: input.tracing,\n });\n definitionsByThreadId.set(threadId, resolved);\n }),\n );\n return definitionsByThreadId;\n }\n\n private buildThreads(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n definitionsByThreadId: ReadonlyMap<string, ResolvedAgentDefinition>;\n }): Map<string, AgentThread> {\n const snapshots = input.previous?.snapshot.threads;\n const map = new Map<string, AgentThread>();\n for (const threadId of threadIdsForCurrentTurn(input.previous?.snapshot)) {\n const resolvedDefinition = input.definitionsByThreadId.get(threadId);\n if (!resolvedDefinition) {\n throw new Error(`Unreachable: missing resolved agent definition for thread '${threadId}'`);\n }\n map.set(\n threadId,\n this.buildThread({\n threadId,\n previousThreadSnapshot: snapshots?.[threadId],\n resolver: input.resolver,\n spec: input.spec,\n sandbox: input.sandbox,\n tracing: input.tracing,\n resolvedDefinition,\n }),\n );\n }\n return map;\n }\n\n private buildThread(input: {\n threadId: string;\n previousThreadSnapshot?: AgentThreadSnapshot | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n resolvedDefinition: ResolvedAgentDefinition;\n }): AgentThread {\n const { definition, extraCapabilities } = input.resolvedDefinition;\n const isChild = Boolean(input.previousThreadSnapshot?.parent);\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition,\n isChild,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition,\n threadId: input.threadId,\n title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : 'main'),\n sandbox: input.sandbox,\n context: input.previousThreadSnapshot?.context,\n currentContextUsage: input.previousThreadSnapshot?.current_context_usage,\n parent: input.previousThreadSnapshot?.parent ?? undefined,\n agentInfo: input.previousThreadSnapshot?.agent_info ?? undefined,\n preComputedCompletion: input.previousThreadSnapshot?.completion ?? undefined,\n capabilities,\n capabilityState: input.previousThreadSnapshot?.capability_state ?? undefined,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n }\n\n private makeCreateDynamicSubAgentThread(input: {\n resolver: ITurnResourceResolver<TTurnCustom>;\n previous: TurnRecord<TTurnCustom> | undefined;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n }): CreateDynamicSubAgentThread {\n return async params => {\n const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: params.request,\n previousTurn: input.previous,\n signal: params.signal,\n tracing: input.tracing,\n });\n // Model override (request.model) is resolved inside resolveAgentDefinition\n // into modelClient — do not re-label a stale client here.\n const childDefinition: AgentDefinition = {\n ...definition,\n toolSets: params.parentDefinition.toolSets ?? definition.toolSets,\n // The delegated task goes in as the initial user message; the sub-agent\n // system prompt is SUB_AGENT_IDENTITY (added by AgentThread.buildInstruction).\n instruction: undefined,\n messages: [{ role: 'user', content: params.request.input }],\n // Sub-agents should return free-form summaries to the parent, not the user-facing structured response.\n responseFormat: undefined,\n };\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition: childDefinition,\n isChild: true,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition: childDefinition,\n threadId: params.threadId,\n title: params.request.name,\n sandbox: input.sandbox,\n parent: params.parent,\n agentInfo: params.request,\n capabilities,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n };\n }\n}\n"],"mappings":"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","names":[]}
@@ -105,6 +105,9 @@ var SessionHandle = class {
105
105
  get custom() {
106
106
  return this.session.custom;
107
107
  }
108
+ get metadata() {
109
+ return this.session.metadata;
110
+ }
108
111
  get record() {
109
112
  return this.session;
110
113
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent-session/SessionHandle.ts"],"sourcesContent":["/**\n * Bound session handle: starts turns via {@link SessionHandle.createTurn}.\n */\nimport { newEventId } from '../core/events/schema';\nimport type { AgentDefinition } from '../core/runtime/AgentDefinition';\nimport { AgentThread } from '../core/runtime/AgentThread';\nimport type {\n AgentThreadAppendContext,\n AgentThreadSendBatch,\n AgentThreadSnapshot,\n} from '../core/runtime/AgentThread.types';\nimport { AgentThreadOrchestrator } from '../core/runtime/AgentThreadOrchestrator';\nimport {\n isApprovalDecisionMessage,\n isClientSideToolResponseMessage,\n isInputUserMessage,\n} from '../core/runtime/contextUtils';\nimport type { CreateDynamicSubAgentThread } from '../core/runtime/CreateDynamicSubAgentThread';\nimport type { Sandbox } from '../core/sandbox/Sandbox';\nimport type { AgentTracing } from '../core/tracing/AgentTracing';\nimport { builtinsFromSpec } from './builtinsFromSpec';\nimport type { ITurnResourceResolver, ResolvedAgentDefinition } from './ITurnResourceResolver';\nimport type { SessionRecord } from './models/SessionRecord';\nimport { MAIN_THREAD_ID, type TurnRecord, type TurnSnapshot } from './models/TurnRecord';\nimport type { AgentSpec } from './schemas/agentSpec';\nimport type { SessionEventItem } from './schemas/events';\nimport { EventType, type TurnDoneEvent } from './schemas/events';\nimport type { TokenPagination } from './schemas/pagination';\nimport type { SessionAgent } from './schemas/session';\nimport type { TurnInputItem } from './schemas/turn';\nimport { CancellationReason } from './schemas/turn';\nimport type { ISessionStore, NewThreadInit, TurnContextAppend, TurnRecordWithoutSnapshot } from './store/ISessionStore';\nimport { TurnHandle } from './TurnHandle';\n\n/** How many recent ancestors SessionHandle persists on each turn. Store-local. */\nconst MAX_TURN_ANCESTORS = 20;\n\nfunction resolvePreviousTurnId(requested: string | undefined, lastTurnId: string | null | undefined): string | null {\n if (requested === 'none') {\n return null;\n }\n if (requested === undefined || requested === 'auto') {\n return lastTurnId ?? null;\n }\n return requested;\n}\n\nfunction toSendBatch(input: TurnInputItem[] | undefined): AgentThreadSendBatch {\n if (!input || input.length === 0) {\n return [];\n }\n if (input.every(msg => isApprovalDecisionMessage(msg) || isClientSideToolResponseMessage(msg))) {\n return input;\n }\n if (input.every(isInputUserMessage)) {\n return input;\n }\n throw new Error('input must be homogeneous: all user messages, or all approval/tool-response messages');\n}\n\nfunction toNewThreadInit(snapshot: AgentThreadSnapshot): NewThreadInit {\n const { context, current_context_usage, completion, capability_state, ...rest } = snapshot;\n void context;\n void current_context_usage;\n void completion;\n void capability_state;\n return rest;\n}\n\nfunction collectContextAppends(\n events: AsyncGenerator<AgentThreadAppendContext, void, unknown>,\n): Promise<TurnContextAppend[]> {\n return (async () => {\n const appendMap = new Map<string, TurnContextAppend>();\n for await (const event of events) {\n const existing = appendMap.get(event.thread_id);\n if (existing) {\n existing.context.push(...event.context);\n if (event.current_context_usage !== undefined) {\n existing.current_context_usage = event.current_context_usage;\n }\n } else {\n appendMap.set(event.thread_id, {\n thread_id: event.thread_id,\n context: [...event.context],\n current_context_usage: event.current_context_usage ?? null,\n });\n }\n }\n return [...appendMap.values()];\n })();\n}\n\nfunction cancelledTurnDoneEvent(reason: CancellationReason): TurnDoneEvent {\n return {\n type: EventType.TURN_DONE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n state: {\n status: 'cancelled',\n reason,\n completed_at: new Date().toISOString(),\n },\n thread_id: null,\n };\n}\n\nfunction threadsRecordFromMap(threads: Map<string, AgentThread>): Record<string, AgentThreadSnapshot> {\n const out: Record<string, AgentThreadSnapshot> = {};\n for (const [id, thread] of threads) {\n out[id] = thread.toSnapshot();\n }\n return out;\n}\n\n// Current-turn thread ids. Main (`MAIN_THREAD_ID`) is always present — first turn\n// synthesizes it; later turns always carry it in the previous snapshot.\nfunction threadIdsForCurrentTurn(snapshot: TurnSnapshot | undefined): string[] {\n return snapshot ? Object.keys(snapshot.threads) : [MAIN_THREAD_ID];\n}\n\nexport class SessionHandle<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n private session: SessionRecord<TSessionCustom>;\n\n constructor(options: { store: ISessionStore<TSessionCustom, TTurnCustom>; session: SessionRecord<TSessionCustom> }) {\n this.store = options.store;\n this.session = options.session;\n }\n\n get session_id(): string {\n return this.session.session_id;\n }\n\n get tenant_id(): string {\n return this.session.tenant_id;\n }\n\n get agent(): SessionAgent {\n return this.session.agent;\n }\n\n get custom(): TSessionCustom | null {\n return this.session.custom;\n }\n\n get record(): SessionRecord<TSessionCustom> {\n return this.session;\n }\n\n /**\n * Prepares and commits a new turn — NO execution happens here (execution =\n * TurnHandle.stream()). Builds threads from the previous turn's snapshot, then\n * sends the input through the orchestrator fully drained (validation +\n * context append; empty input still preflights threads awaiting user input),\n * then persists via one atomic store.createTurn LAST. A send/validation\n * failure therefore persists nothing. The returned turn is durable with\n * state { status: 'running' }.\n *\n * On any failure, createTurn() closes the resolver (best-effort) before rethrowing,\n * so resources acquired here (e.g. a sandbox VM) never outlive a failed run.\n * On success, ownership of resolver.close() passes to TurnHandle.stream().\n *\n * `previous_turn_id`: omitted/`'auto'` → session tip; `'none'` → new root\n * (no parent, even on a non-empty session); string → fork from that turn\n * (must exist). Concurrent `'auto'` forks both succeed.\n */\n async createTurn(input: {\n turn_id: string;\n input?: TurnInputItem[] | undefined;\n /** 'auto'/omitted → session.last_turn_id; 'none' → new root; id → fork from that turn. */\n previous_turn_id?: string | undefined;\n signal: AbortSignal;\n resolver: ITurnResourceResolver<TTurnCustom>;\n /** Value = stored as-is. Fn = merge over previous turn's custom. Omitted = undefined. */\n custom?: TTurnCustom | ((previous?: TTurnCustom) => TTurnCustom) | undefined;\n /**\n * Forwarded to store.createTurn: sets session.title in the same atomic\n * unit IF the session has none; never overwrites. The caller derives the\n * value (e.g. from the first user message) — the library does not.\n */\n update_session_title_if_not_exist?: string | undefined;\n }): Promise<TurnHandle<TTurnCustom>> {\n const previousTurnId = resolvePreviousTurnId(input.previous_turn_id, this.session.last_turn_id);\n const previous = previousTurnId\n ? await this.freezeTurn({\n turn_id: previousTurnId,\n reason: CancellationReason.CancelledForNextTurn,\n })\n : undefined;\n\n const custom = typeof input.custom === 'function' ? input.custom(previous?.custom ?? undefined) : input.custom;\n\n // Dispose-on-early-failure: any resource acquired below (sandbox handle,\n // MCP connections) is owned by createTurn() until the TurnHandle is returned; from then\n // on TurnHandle.stream()'s finally owns resolver.close(). On any throw in this\n // acquisition phase we close the resolver (best-effort, error swallowed)\n // and rethrow — same pattern as the gateway's sessionTurnHandler, which\n // wraps getAgent/handler.init and calls gatewayStore.dispose() on failure.\n try {\n const tracing = input.resolver.createTracing();\n const agent = this.session.agent;\n const spec = agent.type === 'inline' ? agent.spec : await input.resolver.resolveAgentSpec({ agent_id: agent.id });\n const sandbox = await input.resolver.resolveSandbox({\n spec,\n existing: previous?.snapshot.sandbox_info ?? undefined,\n previousTurn: previous,\n signal: input.signal,\n tracing,\n });\n\n const definitionsByThreadId = await this.resolveAgentDefinitions({\n previous,\n resolver: input.resolver,\n spec,\n tracing,\n signal: input.signal,\n });\n\n // Wire Code Mode once from main toolSets before threads share the sandbox.\n const mainDefinition = definitionsByThreadId.get(MAIN_THREAD_ID);\n if (!mainDefinition) {\n throw new Error('Unreachable: missing resolved agent definition for main thread');\n }\n if (sandbox) {\n sandbox.configureCodeMode(mainDefinition.definition.toolSets ?? []);\n }\n\n const agentThreads = this.buildThreads({\n previous,\n resolver: input.resolver,\n spec,\n sandbox,\n tracing,\n definitionsByThreadId,\n });\n\n const createDynamicSubAgentThread = this.makeCreateDynamicSubAgentThread({\n resolver: input.resolver,\n previous,\n spec,\n sandbox,\n tracing,\n });\n\n const orchestrator = new AgentThreadOrchestrator({\n agentThreads,\n createDynamicSubAgentThread,\n tracing,\n logger: input.resolver.logger,\n });\n\n // SEND BEFORE COMMIT — validate + append; throw ⇒ nothing persisted.\n const sendBatch = toSendBatch(input.input);\n const new_context_appends = await collectContextAppends(orchestrator.send(sendBatch));\n\n const turnId = input.turn_id;\n const now = new Date();\n\n const new_threads: NewThreadInit[] = [];\n if (!previous) {\n const root = agentThreads.get(MAIN_THREAD_ID);\n if (root) {\n new_threads.push(toNewThreadInit(root.toSnapshot()));\n }\n } else {\n for (const [threadId, thread] of agentThreads) {\n if (previous.snapshot.threads[threadId] === undefined) {\n new_threads.push(toNewThreadInit(thread.toSnapshot()));\n }\n }\n }\n\n const turnInit: TurnRecordWithoutSnapshot<TTurnCustom> = {\n turn_id: turnId,\n session_id: this.session.session_id,\n first_turn_id: previous?.first_turn_id ?? turnId,\n ancestor_ids: previous ? [...previous.ancestor_ids, previous.turn_id].slice(-MAX_TURN_ANCESTORS) : [],\n previous_turn_id: previousTurnId,\n state: { status: 'running' },\n input: input.input ?? [],\n created_at: now,\n updated_at: now,\n custom: custom ?? null,\n };\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...turnInit,\n snapshot: {\n threads: threadsRecordFromMap(agentThreads),\n mcp_servers: previous?.snapshot.mcp_servers ?? null,\n sandbox_info: previous?.snapshot.sandbox_info ?? null,\n },\n };\n\n await this.store.createTurn({\n turn: turnInit,\n new_threads,\n new_context_appends,\n capability_states: [...agentThreads].map(([thread_id, thread]) => ({\n thread_id,\n capability_state: thread.toSnapshot().capability_state,\n })),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist ?? null,\n });\n\n const refreshed = await this.store.getSession({\n tenant_id: this.tenant_id,\n session_id: this.session.session_id,\n });\n if (refreshed) {\n this.session = refreshed;\n }\n\n return new TurnHandle({\n store: this.store,\n turn: turnRecord,\n orchestrator,\n resolver: input.resolver,\n signal: input.signal,\n });\n } catch (error) {\n await input.resolver.close().catch((closeError: unknown) => {\n input.resolver.logger.warn('TurnResourceResolver.close() failed after createTurn() error', {\n err: closeError,\n });\n });\n throw error;\n }\n }\n\n /**\n * Conditionally cancel a running turn in this session and return the\n * now-immutable record. Already-terminal turns are returned unchanged.\n * Missing turn → {@link TurnNotFoundError}.\n */\n async freezeTurn(input: { turn_id: string; reason: CancellationReason }): Promise<TurnRecord<TTurnCustom>> {\n return this.store.freezeAndGetTurn({\n session_id: this.session.session_id,\n turn_id: input.turn_id,\n reason: input.reason,\n turn_done_event: cancelledTurnDoneEvent(input.reason),\n });\n }\n\n /** Returns the turn handle (store-backed; not executable), or undefined if not found. */\n async getTurn(turn_id: string): Promise<TurnHandle<TTurnCustom> | undefined> {\n return TurnHandle.get({\n store: this.store,\n session_id: this.session.session_id,\n turn_id,\n });\n }\n\n /** Paginated list of this session's turn rows (no snapshot). */\n async listTurns(input: {\n limit: number;\n page_token?: string | undefined;\n }): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n return this.store.listTurns({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n });\n }\n\n /**\n * Paginated session-wide feed of persisted events across turns, including\n * turn.created / turn.done lifecycle events. Reads from the store only —\n * nothing is synthesized on read.\n */\n async listEvents(input: {\n limit: number;\n page_token?: string | undefined;\n last_turn_id?: string | undefined;\n }): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n return this.store.listSessionEvents({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n last_turn_id: input.last_turn_id,\n });\n }\n\n private async resolveAgentDefinitions(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n tracing: AgentTracing;\n signal: AbortSignal;\n }): Promise<Map<string, ResolvedAgentDefinition>> {\n const snapshots = input.previous?.snapshot.threads;\n const threadIds = threadIdsForCurrentTurn(input.previous?.snapshot);\n const definitionsByThreadId = new Map<string, ResolvedAgentDefinition>();\n await Promise.all(\n threadIds.map(async threadId => {\n const previousThreadSnapshot = snapshots?.[threadId];\n const resolved = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: previousThreadSnapshot?.agent_info ?? undefined,\n previousTurn: input.previous,\n signal: input.signal,\n tracing: input.tracing,\n });\n definitionsByThreadId.set(threadId, resolved);\n }),\n );\n return definitionsByThreadId;\n }\n\n private buildThreads(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n definitionsByThreadId: ReadonlyMap<string, ResolvedAgentDefinition>;\n }): Map<string, AgentThread> {\n const snapshots = input.previous?.snapshot.threads;\n const map = new Map<string, AgentThread>();\n for (const threadId of threadIdsForCurrentTurn(input.previous?.snapshot)) {\n const resolvedDefinition = input.definitionsByThreadId.get(threadId);\n if (!resolvedDefinition) {\n throw new Error(`Unreachable: missing resolved agent definition for thread '${threadId}'`);\n }\n map.set(\n threadId,\n this.buildThread({\n threadId,\n previousThreadSnapshot: snapshots?.[threadId],\n resolver: input.resolver,\n spec: input.spec,\n sandbox: input.sandbox,\n tracing: input.tracing,\n resolvedDefinition,\n }),\n );\n }\n return map;\n }\n\n private buildThread(input: {\n threadId: string;\n previousThreadSnapshot?: AgentThreadSnapshot | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n resolvedDefinition: ResolvedAgentDefinition;\n }): AgentThread {\n const { definition, extraCapabilities } = input.resolvedDefinition;\n const isChild = Boolean(input.previousThreadSnapshot?.parent);\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition,\n isChild,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition,\n threadId: input.threadId,\n title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : 'main'),\n sandbox: input.sandbox,\n context: input.previousThreadSnapshot?.context,\n currentContextUsage: input.previousThreadSnapshot?.current_context_usage,\n parent: input.previousThreadSnapshot?.parent ?? undefined,\n agentInfo: input.previousThreadSnapshot?.agent_info ?? undefined,\n preComputedCompletion: input.previousThreadSnapshot?.completion ?? undefined,\n capabilities,\n capabilityState: input.previousThreadSnapshot?.capability_state ?? undefined,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n }\n\n private makeCreateDynamicSubAgentThread(input: {\n resolver: ITurnResourceResolver<TTurnCustom>;\n previous: TurnRecord<TTurnCustom> | undefined;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n }): CreateDynamicSubAgentThread {\n return async params => {\n const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: params.request,\n previousTurn: input.previous,\n signal: params.signal,\n tracing: input.tracing,\n });\n // Model override (request.model) is resolved inside resolveAgentDefinition\n // into modelClient — do not re-label a stale client here.\n const childDefinition: AgentDefinition = {\n ...definition,\n toolSets: params.parentDefinition.toolSets ?? definition.toolSets,\n // The delegated task goes in as the initial user message; the sub-agent\n // system prompt is SUB_AGENT_IDENTITY (added by AgentThread.buildInstruction).\n instruction: undefined,\n messages: [{ role: 'user', content: params.request.input }],\n // Sub-agents should return free-form summaries to the parent, not the user-facing structured response.\n responseFormat: undefined,\n };\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition: childDefinition,\n isChild: true,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition: childDefinition,\n threadId: params.threadId,\n title: params.request.name,\n sandbox: input.sandbox,\n parent: params.parent,\n agentInfo: params.request,\n capabilities,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n };\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/agent-session/SessionHandle.ts"],"sourcesContent":["/**\n * Bound session handle: starts turns via {@link SessionHandle.createTurn}.\n */\nimport { newEventId } from '../core/events/schema';\nimport type { AgentDefinition } from '../core/runtime/AgentDefinition';\nimport { AgentThread } from '../core/runtime/AgentThread';\nimport type {\n AgentThreadAppendContext,\n AgentThreadSendBatch,\n AgentThreadSnapshot,\n} from '../core/runtime/AgentThread.types';\nimport { AgentThreadOrchestrator } from '../core/runtime/AgentThreadOrchestrator';\nimport {\n isApprovalDecisionMessage,\n isClientSideToolResponseMessage,\n isInputUserMessage,\n} from '../core/runtime/contextUtils';\nimport type { CreateDynamicSubAgentThread } from '../core/runtime/CreateDynamicSubAgentThread';\nimport type { Sandbox } from '../core/sandbox/Sandbox';\nimport type { AgentTracing } from '../core/tracing/AgentTracing';\nimport { builtinsFromSpec } from './builtinsFromSpec';\nimport type { ITurnResourceResolver, ResolvedAgentDefinition } from './ITurnResourceResolver';\nimport type { SessionRecord } from './models/SessionRecord';\nimport { MAIN_THREAD_ID, type TurnRecord, type TurnSnapshot } from './models/TurnRecord';\nimport type { AgentSpec } from './schemas/agentSpec';\nimport type { SessionEventItem } from './schemas/events';\nimport { EventType, type TurnDoneEvent } from './schemas/events';\nimport type { TokenPagination } from './schemas/pagination';\nimport type { SessionAgent } from './schemas/session';\nimport type { TurnInputItem } from './schemas/turn';\nimport { CancellationReason } from './schemas/turn';\nimport type { ISessionStore, NewThreadInit, TurnContextAppend, TurnRecordWithoutSnapshot } from './store/ISessionStore';\nimport { TurnHandle } from './TurnHandle';\n\n/** How many recent ancestors SessionHandle persists on each turn. Store-local. */\nconst MAX_TURN_ANCESTORS = 20;\n\nfunction resolvePreviousTurnId(requested: string | undefined, lastTurnId: string | null | undefined): string | null {\n if (requested === 'none') {\n return null;\n }\n if (requested === undefined || requested === 'auto') {\n return lastTurnId ?? null;\n }\n return requested;\n}\n\nfunction toSendBatch(input: TurnInputItem[] | undefined): AgentThreadSendBatch {\n if (!input || input.length === 0) {\n return [];\n }\n if (input.every(msg => isApprovalDecisionMessage(msg) || isClientSideToolResponseMessage(msg))) {\n return input;\n }\n if (input.every(isInputUserMessage)) {\n return input;\n }\n throw new Error('input must be homogeneous: all user messages, or all approval/tool-response messages');\n}\n\nfunction toNewThreadInit(snapshot: AgentThreadSnapshot): NewThreadInit {\n const { context, current_context_usage, completion, capability_state, ...rest } = snapshot;\n void context;\n void current_context_usage;\n void completion;\n void capability_state;\n return rest;\n}\n\nfunction collectContextAppends(\n events: AsyncGenerator<AgentThreadAppendContext, void, unknown>,\n): Promise<TurnContextAppend[]> {\n return (async () => {\n const appendMap = new Map<string, TurnContextAppend>();\n for await (const event of events) {\n const existing = appendMap.get(event.thread_id);\n if (existing) {\n existing.context.push(...event.context);\n if (event.current_context_usage !== undefined) {\n existing.current_context_usage = event.current_context_usage;\n }\n } else {\n appendMap.set(event.thread_id, {\n thread_id: event.thread_id,\n context: [...event.context],\n current_context_usage: event.current_context_usage ?? null,\n });\n }\n }\n return [...appendMap.values()];\n })();\n}\n\nfunction cancelledTurnDoneEvent(reason: CancellationReason): TurnDoneEvent {\n return {\n type: EventType.TURN_DONE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n state: {\n status: 'cancelled',\n reason,\n completed_at: new Date().toISOString(),\n },\n thread_id: null,\n };\n}\n\nfunction threadsRecordFromMap(threads: Map<string, AgentThread>): Record<string, AgentThreadSnapshot> {\n const out: Record<string, AgentThreadSnapshot> = {};\n for (const [id, thread] of threads) {\n out[id] = thread.toSnapshot();\n }\n return out;\n}\n\n// Current-turn thread ids. Main (`MAIN_THREAD_ID`) is always present — first turn\n// synthesizes it; later turns always carry it in the previous snapshot.\nfunction threadIdsForCurrentTurn(snapshot: TurnSnapshot | undefined): string[] {\n return snapshot ? Object.keys(snapshot.threads) : [MAIN_THREAD_ID];\n}\n\nexport class SessionHandle<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n private session: SessionRecord<TSessionCustom>;\n\n constructor(options: { store: ISessionStore<TSessionCustom, TTurnCustom>; session: SessionRecord<TSessionCustom> }) {\n this.store = options.store;\n this.session = options.session;\n }\n\n get session_id(): string {\n return this.session.session_id;\n }\n\n get tenant_id(): string {\n return this.session.tenant_id;\n }\n\n get agent(): SessionAgent {\n return this.session.agent;\n }\n\n get custom(): TSessionCustom | null {\n return this.session.custom;\n }\n\n get metadata(): SessionRecord<TSessionCustom>['metadata'] {\n return this.session.metadata;\n }\n\n get record(): SessionRecord<TSessionCustom> {\n return this.session;\n }\n\n /**\n * Prepares and commits a new turn — NO execution happens here (execution =\n * TurnHandle.stream()). Builds threads from the previous turn's snapshot, then\n * sends the input through the orchestrator fully drained (validation +\n * context append; empty input still preflights threads awaiting user input),\n * then persists via one atomic store.createTurn LAST. A send/validation\n * failure therefore persists nothing. The returned turn is durable with\n * state { status: 'running' }.\n *\n * On any failure, createTurn() closes the resolver (best-effort) before rethrowing,\n * so resources acquired here (e.g. a sandbox VM) never outlive a failed run.\n * On success, ownership of resolver.close() passes to TurnHandle.stream().\n *\n * `previous_turn_id`: omitted/`'auto'` → session tip; `'none'` → new root\n * (no parent, even on a non-empty session); string → fork from that turn\n * (must exist). Concurrent `'auto'` forks both succeed.\n */\n async createTurn(input: {\n turn_id: string;\n input?: TurnInputItem[] | undefined;\n /** 'auto'/omitted → session.last_turn_id; 'none' → new root; id → fork from that turn. */\n previous_turn_id?: string | undefined;\n signal: AbortSignal;\n resolver: ITurnResourceResolver<TTurnCustom>;\n /** Value = stored as-is. Fn = merge over previous turn's custom. Omitted = undefined. */\n custom?: TTurnCustom | ((previous?: TTurnCustom) => TTurnCustom) | undefined;\n /**\n * Forwarded to store.createTurn: sets session.title in the same atomic\n * unit IF the session has none; never overwrites. The caller derives the\n * value (e.g. from the first user message) — the library does not.\n */\n update_session_title_if_not_exist?: string | undefined;\n }): Promise<TurnHandle<TTurnCustom>> {\n const previousTurnId = resolvePreviousTurnId(input.previous_turn_id, this.session.last_turn_id);\n const previous = previousTurnId\n ? await this.freezeTurn({\n turn_id: previousTurnId,\n reason: CancellationReason.CancelledForNextTurn,\n })\n : undefined;\n\n const custom = typeof input.custom === 'function' ? input.custom(previous?.custom ?? undefined) : input.custom;\n\n // Dispose-on-early-failure: any resource acquired below (sandbox handle,\n // MCP connections) is owned by createTurn() until the TurnHandle is returned; from then\n // on TurnHandle.stream()'s finally owns resolver.close(). On any throw in this\n // acquisition phase we close the resolver (best-effort, error swallowed)\n // and rethrow — same pattern as the gateway's sessionTurnHandler, which\n // wraps getAgent/handler.init and calls gatewayStore.dispose() on failure.\n try {\n const tracing = input.resolver.createTracing();\n const agent = this.session.agent;\n const spec = agent.type === 'inline' ? agent.spec : await input.resolver.resolveAgentSpec({ agent_id: agent.id });\n const sandbox = await input.resolver.resolveSandbox({\n spec,\n existing: previous?.snapshot.sandbox_info ?? undefined,\n previousTurn: previous,\n signal: input.signal,\n tracing,\n });\n\n const definitionsByThreadId = await this.resolveAgentDefinitions({\n previous,\n resolver: input.resolver,\n spec,\n tracing,\n signal: input.signal,\n });\n\n // Wire Code Mode once from main toolSets before threads share the sandbox.\n const mainDefinition = definitionsByThreadId.get(MAIN_THREAD_ID);\n if (!mainDefinition) {\n throw new Error('Unreachable: missing resolved agent definition for main thread');\n }\n if (sandbox) {\n sandbox.configureCodeMode(mainDefinition.definition.toolSets ?? []);\n }\n\n const agentThreads = this.buildThreads({\n previous,\n resolver: input.resolver,\n spec,\n sandbox,\n tracing,\n definitionsByThreadId,\n });\n\n const createDynamicSubAgentThread = this.makeCreateDynamicSubAgentThread({\n resolver: input.resolver,\n previous,\n spec,\n sandbox,\n tracing,\n });\n\n const orchestrator = new AgentThreadOrchestrator({\n agentThreads,\n createDynamicSubAgentThread,\n tracing,\n logger: input.resolver.logger,\n });\n\n // SEND BEFORE COMMIT — validate + append; throw ⇒ nothing persisted.\n const sendBatch = toSendBatch(input.input);\n const new_context_appends = await collectContextAppends(orchestrator.send(sendBatch));\n\n const turnId = input.turn_id;\n const now = new Date();\n\n const new_threads: NewThreadInit[] = [];\n if (!previous) {\n const root = agentThreads.get(MAIN_THREAD_ID);\n if (root) {\n new_threads.push(toNewThreadInit(root.toSnapshot()));\n }\n } else {\n for (const [threadId, thread] of agentThreads) {\n if (previous.snapshot.threads[threadId] === undefined) {\n new_threads.push(toNewThreadInit(thread.toSnapshot()));\n }\n }\n }\n\n const turnInit: TurnRecordWithoutSnapshot<TTurnCustom> = {\n turn_id: turnId,\n session_id: this.session.session_id,\n first_turn_id: previous?.first_turn_id ?? turnId,\n ancestor_ids: previous ? [...previous.ancestor_ids, previous.turn_id].slice(-MAX_TURN_ANCESTORS) : [],\n previous_turn_id: previousTurnId,\n state: { status: 'running' },\n input: input.input ?? [],\n created_at: now,\n updated_at: now,\n custom: custom ?? null,\n };\n\n const turnRecord: TurnRecord<TTurnCustom> = {\n ...turnInit,\n snapshot: {\n threads: threadsRecordFromMap(agentThreads),\n mcp_servers: previous?.snapshot.mcp_servers ?? null,\n sandbox_info: previous?.snapshot.sandbox_info ?? null,\n },\n };\n\n await this.store.createTurn({\n turn: turnInit,\n new_threads,\n new_context_appends,\n capability_states: [...agentThreads].map(([thread_id, thread]) => ({\n thread_id,\n capability_state: thread.toSnapshot().capability_state,\n })),\n update_session_title_if_not_exist: input.update_session_title_if_not_exist ?? null,\n });\n\n const refreshed = await this.store.getSession({\n tenant_id: this.tenant_id,\n session_id: this.session.session_id,\n });\n if (refreshed) {\n this.session = refreshed;\n }\n\n return new TurnHandle({\n store: this.store,\n turn: turnRecord,\n orchestrator,\n resolver: input.resolver,\n signal: input.signal,\n });\n } catch (error) {\n await input.resolver.close().catch((closeError: unknown) => {\n input.resolver.logger.warn('TurnResourceResolver.close() failed after createTurn() error', {\n err: closeError,\n });\n });\n throw error;\n }\n }\n\n /**\n * Conditionally cancel a running turn in this session and return the\n * now-immutable record. Already-terminal turns are returned unchanged.\n * Missing turn → {@link TurnNotFoundError}.\n */\n async freezeTurn(input: { turn_id: string; reason: CancellationReason }): Promise<TurnRecord<TTurnCustom>> {\n return this.store.freezeAndGetTurn({\n session_id: this.session.session_id,\n turn_id: input.turn_id,\n reason: input.reason,\n turn_done_event: cancelledTurnDoneEvent(input.reason),\n });\n }\n\n /** Returns the turn handle (store-backed; not executable), or undefined if not found. */\n async getTurn(turn_id: string): Promise<TurnHandle<TTurnCustom> | undefined> {\n return TurnHandle.get({\n store: this.store,\n session_id: this.session.session_id,\n turn_id,\n });\n }\n\n /** Paginated list of this session's turn rows (no snapshot). */\n async listTurns(input: {\n limit: number;\n page_token?: string | undefined;\n }): Promise<{ data: TurnRecordWithoutSnapshot<TTurnCustom>[]; pagination: TokenPagination }> {\n return this.store.listTurns({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n });\n }\n\n /**\n * Paginated session-wide feed of persisted events across turns, including\n * turn.created / turn.done lifecycle events. Reads from the store only —\n * nothing is synthesized on read.\n */\n async listEvents(input: {\n limit: number;\n page_token?: string | undefined;\n last_turn_id?: string | undefined;\n }): Promise<{\n data: SessionEventItem[];\n pagination: TokenPagination;\n }> {\n return this.store.listSessionEvents({\n session_id: this.session.session_id,\n limit: input.limit,\n page_token: input.page_token,\n last_turn_id: input.last_turn_id,\n });\n }\n\n private async resolveAgentDefinitions(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n tracing: AgentTracing;\n signal: AbortSignal;\n }): Promise<Map<string, ResolvedAgentDefinition>> {\n const snapshots = input.previous?.snapshot.threads;\n const threadIds = threadIdsForCurrentTurn(input.previous?.snapshot);\n const definitionsByThreadId = new Map<string, ResolvedAgentDefinition>();\n await Promise.all(\n threadIds.map(async threadId => {\n const previousThreadSnapshot = snapshots?.[threadId];\n const resolved = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: previousThreadSnapshot?.agent_info ?? undefined,\n previousTurn: input.previous,\n signal: input.signal,\n tracing: input.tracing,\n });\n definitionsByThreadId.set(threadId, resolved);\n }),\n );\n return definitionsByThreadId;\n }\n\n private buildThreads(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n definitionsByThreadId: ReadonlyMap<string, ResolvedAgentDefinition>;\n }): Map<string, AgentThread> {\n const snapshots = input.previous?.snapshot.threads;\n const map = new Map<string, AgentThread>();\n for (const threadId of threadIdsForCurrentTurn(input.previous?.snapshot)) {\n const resolvedDefinition = input.definitionsByThreadId.get(threadId);\n if (!resolvedDefinition) {\n throw new Error(`Unreachable: missing resolved agent definition for thread '${threadId}'`);\n }\n map.set(\n threadId,\n this.buildThread({\n threadId,\n previousThreadSnapshot: snapshots?.[threadId],\n resolver: input.resolver,\n spec: input.spec,\n sandbox: input.sandbox,\n tracing: input.tracing,\n resolvedDefinition,\n }),\n );\n }\n return map;\n }\n\n private buildThread(input: {\n threadId: string;\n previousThreadSnapshot?: AgentThreadSnapshot | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n resolvedDefinition: ResolvedAgentDefinition;\n }): AgentThread {\n const { definition, extraCapabilities } = input.resolvedDefinition;\n const isChild = Boolean(input.previousThreadSnapshot?.parent);\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition,\n isChild,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition,\n threadId: input.threadId,\n title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : 'main'),\n sandbox: input.sandbox,\n context: input.previousThreadSnapshot?.context,\n currentContextUsage: input.previousThreadSnapshot?.current_context_usage,\n parent: input.previousThreadSnapshot?.parent ?? undefined,\n agentInfo: input.previousThreadSnapshot?.agent_info ?? undefined,\n preComputedCompletion: input.previousThreadSnapshot?.completion ?? undefined,\n capabilities,\n capabilityState: input.previousThreadSnapshot?.capability_state ?? undefined,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n }\n\n private makeCreateDynamicSubAgentThread(input: {\n resolver: ITurnResourceResolver<TTurnCustom>;\n previous: TurnRecord<TTurnCustom> | undefined;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n }): CreateDynamicSubAgentThread {\n return async params => {\n const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n agent_info: params.request,\n previousTurn: input.previous,\n signal: params.signal,\n tracing: input.tracing,\n });\n // Model override (request.model) is resolved inside resolveAgentDefinition\n // into modelClient — do not re-label a stale client here.\n const childDefinition: AgentDefinition = {\n ...definition,\n toolSets: params.parentDefinition.toolSets ?? definition.toolSets,\n // The delegated task goes in as the initial user message; the sub-agent\n // system prompt is SUB_AGENT_IDENTITY (added by AgentThread.buildInstruction).\n instruction: undefined,\n messages: [{ role: 'user', content: params.request.input }],\n // Sub-agents should return free-form summaries to the parent, not the user-facing structured response.\n responseFormat: undefined,\n };\n const capabilities = [\n ...builtinsFromSpec({\n spec: input.spec,\n definition: childDefinition,\n isChild: true,\n sandboxAvailable: Boolean(input.sandbox),\n tracing: input.tracing,\n logger: input.resolver.logger,\n }),\n ...(extraCapabilities ?? []),\n ];\n return new AgentThread({\n definition: childDefinition,\n threadId: params.threadId,\n title: params.request.name,\n sandbox: input.sandbox,\n parent: params.parent,\n agentInfo: params.request,\n capabilities,\n tracing: input.tracing,\n logger: input.resolver.logger,\n });\n };\n }\n}\n"],"mappings":"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","names":[]}
@@ -1,11 +1,12 @@
1
+ import { SessionHandle } from './SessionHandle';
2
+ import type { CreateSessionInput, GetSessionByExternalIdInput, GetSessionInput, ISessionStore } from './store/ISessionStore';
1
3
  /**
2
- * Storage-only session collection: create / get. Behavior arrives per run via
3
- * the resolver on {@link SessionHandle.createTurn}.
4
+ * Domain create input: same as {@link CreateSessionInput}, but `custom`,
5
+ * `metadata`, and `source` are optional — {@link Sessions.create} defaults them
6
+ * (`null` / `{}` / `null`). The store contract requires those fields explicitly.
4
7
  */
5
- import { SessionHandle } from './SessionHandle';
6
- import type { CreateSessionInput, GetSessionInput, ISessionStore } from './store/ISessionStore';
7
- export type SessionsCreateInput<TSessionCustom extends object> = Omit<CreateSessionInput<TSessionCustom>, 'custom'> & {
8
- custom?: TSessionCustom | undefined;
8
+ export type SessionsCreateInput<TSessionCustom extends object> = Omit<CreateSessionInput<TSessionCustom>, 'custom' | 'metadata' | 'source'> & {
9
+ [K in 'custom' | 'metadata' | 'source']?: CreateSessionInput<TSessionCustom>[K] | undefined;
9
10
  };
10
11
  export declare class Sessions<TSessionCustom extends object = Record<string, never>, TTurnCustom extends object = Record<string, never>> {
11
12
  private readonly store;
@@ -21,5 +22,19 @@ export declare class Sessions<TSessionCustom extends object = Record<string, nev
21
22
  * undefined if not found. Read-only: does not bump last_activity_timestamp_ms.
22
23
  */
23
24
  get(input: GetSessionInput): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined>;
25
+ /**
26
+ * Returns the session bound to this tenant-scoped external id, or undefined.
27
+ * Read-only: does not bump last_activity_timestamp_ms.
28
+ */
29
+ getByExternalId(input: GetSessionByExternalIdInput): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined>;
30
+ /**
31
+ * Get-or-create the session bound to a tenant-scoped `external_id`.
32
+ */
33
+ getOrCreateByExternalId(input: Omit<SessionsCreateInput<TSessionCustom>, 'session_id' | 'external_id'> & {
34
+ external_id: string;
35
+ }): Promise<{
36
+ session: SessionHandle<TSessionCustom, TTurnCustom>;
37
+ created: boolean;
38
+ }>;
24
39
  }
25
40
  //# sourceMappingURL=Sessions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Sessions.d.ts","sourceRoot":"","sources":["../../src/agent-session/Sessions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEhG,MAAM,MAAM,mBAAmB,CAAC,cAAc,SAAS,MAAM,IAAI,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,GAAG;IACpH,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CACrC,CAAC;AAEF,qBAAa,QAAQ,CACnB,cAAc,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACrD,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAElD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IAEnE,YAAY,IAAI,EAAE;QAAE,YAAY,EAAE,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;KAAE,EAE7E;IAED;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,mBAAmB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAgB5G;IAED;;;OAGG;IACG,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,CASjG;CACF"}
1
+ {"version":3,"file":"Sessions.d.ts","sourceRoot":"","sources":["../../src/agent-session/Sessions.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EACV,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,EACf,aAAa,EACd,MAAM,uBAAuB,CAAC;AAG/B;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,CAAC,cAAc,SAAS,MAAM,IAAI,IAAI,CACnE,kBAAkB,CAAC,cAAc,CAAC,EAClC,QAAQ,GAAG,UAAU,GAAG,QAAQ,CACjC,GAAG;KACD,CAAC,IAAI,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAC5F,CAAC;AAEF,qBAAa,QAAQ,CACnB,cAAc,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACrD,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAElD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6C;IAEnE,YAAY,IAAI,EAAE;QAAE,YAAY,EAAE,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,CAAA;KAAE,EAE7E;IAED;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,mBAAmB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC,CAkB5G;IAED;;;OAGG;IACG,GAAG,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,CASjG;IAED;;;OAGG;IACG,eAAe,CACnB,KAAK,EAAE,2BAA2B,GACjC,OAAO,CAAC,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,CASjE;IAED;;OAEG;IACG,uBAAuB,CAC3B,KAAK,EAAE,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,EAAE,YAAY,GAAG,aAAa,CAAC,GAAG;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,GACvG,OAAO,CAAC;QAAE,OAAO,EAAE,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAyBpF;CACF"}
@@ -23,7 +23,9 @@ __export(Sessions_exports, {
23
23
  Sessions: () => Sessions
24
24
  });
25
25
  module.exports = __toCommonJS(Sessions_exports);
26
+ var import_ulid = require("ulid");
26
27
  var import_SessionHandle = require("./SessionHandle.js");
28
+ var import_SessionStoreErrors = require("./store/SessionStoreErrors.js");
27
29
  var Sessions = class {
28
30
  store;
29
31
  constructor(deps) {
@@ -35,7 +37,9 @@ var Sessions = class {
35
37
  async create(input) {
36
38
  await this.store.createSession({
37
39
  ...input,
38
- custom: input.custom ?? null
40
+ custom: input.custom ?? null,
41
+ metadata: input.metadata ?? {},
42
+ source: input.source ?? null
39
43
  });
40
44
  const record = await this.store.getSession({
41
45
  tenant_id: input.tenant_id,
@@ -63,6 +67,47 @@ var Sessions = class {
63
67
  session: record
64
68
  });
65
69
  }
70
+ /**
71
+ * Returns the session bound to this tenant-scoped external id, or undefined.
72
+ * Read-only: does not bump last_activity_timestamp_ms.
73
+ */
74
+ async getByExternalId(input) {
75
+ const record = await this.store.getSessionByExternalId(input);
76
+ if (!record) {
77
+ return void 0;
78
+ }
79
+ return new import_SessionHandle.SessionHandle({
80
+ store: this.store,
81
+ session: record
82
+ });
83
+ }
84
+ /**
85
+ * Get-or-create the session bound to a tenant-scoped `external_id`.
86
+ */
87
+ async getOrCreateByExternalId(input) {
88
+ const { tenant_id, external_id } = input;
89
+ const existing = await this.getByExternalId({ tenant_id, external_id });
90
+ if (existing !== void 0) {
91
+ return { session: existing, created: false };
92
+ }
93
+ try {
94
+ const session = await this.create({
95
+ ...input,
96
+ session_id: (0, import_ulid.ulid)().toLowerCase(),
97
+ external_id
98
+ });
99
+ return { session, created: true };
100
+ } catch (error) {
101
+ if (!(error instanceof import_SessionStoreErrors.SessionExternalIdConflictError)) {
102
+ throw error;
103
+ }
104
+ const winner = await this.getByExternalId({ tenant_id, external_id });
105
+ if (winner === void 0) {
106
+ throw error;
107
+ }
108
+ return { session: winner, created: false };
109
+ }
110
+ }
66
111
  };
67
112
  // Annotate the CommonJS export names for ESM import in node:
68
113
  0 && (module.exports = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent-session/Sessions.ts"],"sourcesContent":["/**\n * Storage-only session collection: create / get. Behavior arrives per run via\n * the resolver on {@link SessionHandle.createTurn}.\n */\nimport { SessionHandle } from './SessionHandle';\nimport type { CreateSessionInput, GetSessionInput, ISessionStore } from './store/ISessionStore';\n\nexport type SessionsCreateInput<TSessionCustom extends object> = Omit<CreateSessionInput<TSessionCustom>, 'custom'> & {\n custom?: TSessionCustom | undefined;\n};\n\nexport class Sessions<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n\n constructor(deps: { sessionStore: ISessionStore<TSessionCustom, TTurnCustom> }) {\n this.store = deps.sessionStore;\n }\n\n /**\n * Creates and persists a new session with a reference or inline agent binding.\n */\n async create(input: SessionsCreateInput<TSessionCustom>): Promise<SessionHandle<TSessionCustom, TTurnCustom>> {\n await this.store.createSession({\n ...input,\n custom: input.custom ?? null,\n });\n const record = await this.store.getSession({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n });\n if (!record) {\n throw new Error(`Session create succeeded but getSession returned undefined: ${input.session_id}`);\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Returns the session as stored (ref agents are not hydrated to a value), or\n * undefined if not found. Read-only: does not bump last_activity_timestamp_ms.\n */\n async get(input: GetSessionInput): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined> {\n const record = await this.store.getSession(input);\n if (!record) {\n return undefined;\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,2BAA8B;AAOvB,IAAM,WAAN,MAGL;AAAA,EACiB;AAAA,EAEjB,YAAY,MAAoE;AAC9E,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAiG;AAC5G,UAAM,KAAK,MAAM,cAAc;AAAA,MAC7B,GAAG;AAAA,MACH,QAAQ,MAAM,UAAU;AAAA,IAC1B,CAAC;AACD,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW;AAAA,MACzC,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM;AAAA,IACpB,CAAC;AACD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,+DAA+D,MAAM,UAAU,EAAE;AAAA,IACnG;AACA,WAAO,IAAI,mCAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,OAAyF;AACjG,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW,KAAK;AAChD,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,IAAI,mCAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/agent-session/Sessions.ts"],"sourcesContent":["/**\n * Storage-only session collection: create / get. Behavior arrives per run via\n * the resolver on {@link SessionHandle.createTurn}.\n */\nimport { ulid } from 'ulid';\nimport { SessionHandle } from './SessionHandle';\nimport type {\n CreateSessionInput,\n GetSessionByExternalIdInput,\n GetSessionInput,\n ISessionStore,\n} from './store/ISessionStore';\nimport { SessionExternalIdConflictError } from './store/SessionStoreErrors';\n\n/**\n * Domain create input: same as {@link CreateSessionInput}, but `custom`,\n * `metadata`, and `source` are optional — {@link Sessions.create} defaults them\n * (`null` / `{}` / `null`). The store contract requires those fields explicitly.\n */\nexport type SessionsCreateInput<TSessionCustom extends object> = Omit<\n CreateSessionInput<TSessionCustom>,\n 'custom' | 'metadata' | 'source'\n> & {\n [K in 'custom' | 'metadata' | 'source']?: CreateSessionInput<TSessionCustom>[K] | undefined;\n};\n\nexport class Sessions<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n\n constructor(deps: { sessionStore: ISessionStore<TSessionCustom, TTurnCustom> }) {\n this.store = deps.sessionStore;\n }\n\n /**\n * Creates and persists a new session with a reference or inline agent binding.\n */\n async create(input: SessionsCreateInput<TSessionCustom>): Promise<SessionHandle<TSessionCustom, TTurnCustom>> {\n await this.store.createSession({\n ...input,\n custom: input.custom ?? null,\n metadata: input.metadata ?? {},\n source: input.source ?? null,\n });\n const record = await this.store.getSession({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n });\n if (!record) {\n throw new Error(`Session create succeeded but getSession returned undefined: ${input.session_id}`);\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Returns the session as stored (ref agents are not hydrated to a value), or\n * undefined if not found. Read-only: does not bump last_activity_timestamp_ms.\n */\n async get(input: GetSessionInput): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined> {\n const record = await this.store.getSession(input);\n if (!record) {\n return undefined;\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Returns the session bound to this tenant-scoped external id, or undefined.\n * Read-only: does not bump last_activity_timestamp_ms.\n */\n async getByExternalId(\n input: GetSessionByExternalIdInput,\n ): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined> {\n const record = await this.store.getSessionByExternalId(input);\n if (!record) {\n return undefined;\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Get-or-create the session bound to a tenant-scoped `external_id`.\n */\n async getOrCreateByExternalId(\n input: Omit<SessionsCreateInput<TSessionCustom>, 'session_id' | 'external_id'> & { external_id: string },\n ): Promise<{ session: SessionHandle<TSessionCustom, TTurnCustom>; created: boolean }> {\n const { tenant_id, external_id } = input;\n\n const existing = await this.getByExternalId({ tenant_id, external_id });\n if (existing !== undefined) {\n return { session: existing, created: false };\n }\n\n try {\n const session = await this.create({\n ...input,\n session_id: ulid().toLowerCase(),\n external_id,\n });\n return { session, created: true };\n } catch (error) {\n if (!(error instanceof SessionExternalIdConflictError)) {\n throw error;\n }\n const winner = await this.getByExternalId({ tenant_id, external_id });\n if (winner === undefined) {\n throw error;\n }\n return { session: winner, created: false };\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,kBAAqB;AACrB,2BAA8B;AAO9B,gCAA+C;AAcxC,IAAM,WAAN,MAGL;AAAA,EACiB;AAAA,EAEjB,YAAY,MAAoE;AAC9E,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAiG;AAC5G,UAAM,KAAK,MAAM,cAAc;AAAA,MAC7B,GAAG;AAAA,MACH,QAAQ,MAAM,UAAU;AAAA,MACxB,UAAU,MAAM,YAAY,CAAC;AAAA,MAC7B,QAAQ,MAAM,UAAU;AAAA,IAC1B,CAAC;AACD,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW;AAAA,MACzC,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM;AAAA,IACpB,CAAC;AACD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,+DAA+D,MAAM,UAAU,EAAE;AAAA,IACnG;AACA,WAAO,IAAI,mCAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,OAAyF;AACjG,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW,KAAK;AAChD,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,IAAI,mCAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBACJ,OACiE;AACjE,UAAM,SAAS,MAAM,KAAK,MAAM,uBAAuB,KAAK;AAC5D,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,IAAI,mCAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBACJ,OACoF;AACpF,UAAM,EAAE,WAAW,YAAY,IAAI;AAEnC,UAAM,WAAW,MAAM,KAAK,gBAAgB,EAAE,WAAW,YAAY,CAAC;AACtE,QAAI,aAAa,QAAW;AAC1B,aAAO,EAAE,SAAS,UAAU,SAAS,MAAM;AAAA,IAC7C;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,OAAO;AAAA,QAChC,GAAG;AAAA,QACH,gBAAY,kBAAK,EAAE,YAAY;AAAA,QAC/B;AAAA,MACF,CAAC;AACD,aAAO,EAAE,SAAS,SAAS,KAAK;AAAA,IAClC,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,2DAAiC;AACtD,cAAM;AAAA,MACR;AACA,YAAM,SAAS,MAAM,KAAK,gBAAgB,EAAE,WAAW,YAAY,CAAC;AACpE,UAAI,WAAW,QAAW;AACxB,cAAM;AAAA,MACR;AACA,aAAO,EAAE,SAAS,QAAQ,SAAS,MAAM;AAAA,IAC3C;AAAA,EACF;AACF;","names":[]}
@@ -1,5 +1,7 @@
1
1
  // src/agent-session/Sessions.ts
2
+ import { ulid } from "ulid";
2
3
  import { SessionHandle } from "./SessionHandle.mjs";
4
+ import { SessionExternalIdConflictError } from "./store/SessionStoreErrors.mjs";
3
5
  var Sessions = class {
4
6
  store;
5
7
  constructor(deps) {
@@ -11,7 +13,9 @@ var Sessions = class {
11
13
  async create(input) {
12
14
  await this.store.createSession({
13
15
  ...input,
14
- custom: input.custom ?? null
16
+ custom: input.custom ?? null,
17
+ metadata: input.metadata ?? {},
18
+ source: input.source ?? null
15
19
  });
16
20
  const record = await this.store.getSession({
17
21
  tenant_id: input.tenant_id,
@@ -39,6 +43,47 @@ var Sessions = class {
39
43
  session: record
40
44
  });
41
45
  }
46
+ /**
47
+ * Returns the session bound to this tenant-scoped external id, or undefined.
48
+ * Read-only: does not bump last_activity_timestamp_ms.
49
+ */
50
+ async getByExternalId(input) {
51
+ const record = await this.store.getSessionByExternalId(input);
52
+ if (!record) {
53
+ return void 0;
54
+ }
55
+ return new SessionHandle({
56
+ store: this.store,
57
+ session: record
58
+ });
59
+ }
60
+ /**
61
+ * Get-or-create the session bound to a tenant-scoped `external_id`.
62
+ */
63
+ async getOrCreateByExternalId(input) {
64
+ const { tenant_id, external_id } = input;
65
+ const existing = await this.getByExternalId({ tenant_id, external_id });
66
+ if (existing !== void 0) {
67
+ return { session: existing, created: false };
68
+ }
69
+ try {
70
+ const session = await this.create({
71
+ ...input,
72
+ session_id: ulid().toLowerCase(),
73
+ external_id
74
+ });
75
+ return { session, created: true };
76
+ } catch (error) {
77
+ if (!(error instanceof SessionExternalIdConflictError)) {
78
+ throw error;
79
+ }
80
+ const winner = await this.getByExternalId({ tenant_id, external_id });
81
+ if (winner === void 0) {
82
+ throw error;
83
+ }
84
+ return { session: winner, created: false };
85
+ }
86
+ }
42
87
  };
43
88
  export {
44
89
  Sessions
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent-session/Sessions.ts"],"sourcesContent":["/**\n * Storage-only session collection: create / get. Behavior arrives per run via\n * the resolver on {@link SessionHandle.createTurn}.\n */\nimport { SessionHandle } from './SessionHandle';\nimport type { CreateSessionInput, GetSessionInput, ISessionStore } from './store/ISessionStore';\n\nexport type SessionsCreateInput<TSessionCustom extends object> = Omit<CreateSessionInput<TSessionCustom>, 'custom'> & {\n custom?: TSessionCustom | undefined;\n};\n\nexport class Sessions<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n\n constructor(deps: { sessionStore: ISessionStore<TSessionCustom, TTurnCustom> }) {\n this.store = deps.sessionStore;\n }\n\n /**\n * Creates and persists a new session with a reference or inline agent binding.\n */\n async create(input: SessionsCreateInput<TSessionCustom>): Promise<SessionHandle<TSessionCustom, TTurnCustom>> {\n await this.store.createSession({\n ...input,\n custom: input.custom ?? null,\n });\n const record = await this.store.getSession({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n });\n if (!record) {\n throw new Error(`Session create succeeded but getSession returned undefined: ${input.session_id}`);\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Returns the session as stored (ref agents are not hydrated to a value), or\n * undefined if not found. Read-only: does not bump last_activity_timestamp_ms.\n */\n async get(input: GetSessionInput): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined> {\n const record = await this.store.getSession(input);\n if (!record) {\n return undefined;\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n}\n"],"mappings":";AAIA,SAAS,qBAAqB;AAOvB,IAAM,WAAN,MAGL;AAAA,EACiB;AAAA,EAEjB,YAAY,MAAoE;AAC9E,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAiG;AAC5G,UAAM,KAAK,MAAM,cAAc;AAAA,MAC7B,GAAG;AAAA,MACH,QAAQ,MAAM,UAAU;AAAA,IAC1B,CAAC;AACD,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW;AAAA,MACzC,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM;AAAA,IACpB,CAAC;AACD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,+DAA+D,MAAM,UAAU,EAAE;AAAA,IACnG;AACA,WAAO,IAAI,cAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,OAAyF;AACjG,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW,KAAK;AAChD,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,IAAI,cAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/agent-session/Sessions.ts"],"sourcesContent":["/**\n * Storage-only session collection: create / get. Behavior arrives per run via\n * the resolver on {@link SessionHandle.createTurn}.\n */\nimport { ulid } from 'ulid';\nimport { SessionHandle } from './SessionHandle';\nimport type {\n CreateSessionInput,\n GetSessionByExternalIdInput,\n GetSessionInput,\n ISessionStore,\n} from './store/ISessionStore';\nimport { SessionExternalIdConflictError } from './store/SessionStoreErrors';\n\n/**\n * Domain create input: same as {@link CreateSessionInput}, but `custom`,\n * `metadata`, and `source` are optional — {@link Sessions.create} defaults them\n * (`null` / `{}` / `null`). The store contract requires those fields explicitly.\n */\nexport type SessionsCreateInput<TSessionCustom extends object> = Omit<\n CreateSessionInput<TSessionCustom>,\n 'custom' | 'metadata' | 'source'\n> & {\n [K in 'custom' | 'metadata' | 'source']?: CreateSessionInput<TSessionCustom>[K] | undefined;\n};\n\nexport class Sessions<\n TSessionCustom extends object = Record<string, never>,\n TTurnCustom extends object = Record<string, never>,\n> {\n private readonly store: ISessionStore<TSessionCustom, TTurnCustom>;\n\n constructor(deps: { sessionStore: ISessionStore<TSessionCustom, TTurnCustom> }) {\n this.store = deps.sessionStore;\n }\n\n /**\n * Creates and persists a new session with a reference or inline agent binding.\n */\n async create(input: SessionsCreateInput<TSessionCustom>): Promise<SessionHandle<TSessionCustom, TTurnCustom>> {\n await this.store.createSession({\n ...input,\n custom: input.custom ?? null,\n metadata: input.metadata ?? {},\n source: input.source ?? null,\n });\n const record = await this.store.getSession({\n tenant_id: input.tenant_id,\n session_id: input.session_id,\n });\n if (!record) {\n throw new Error(`Session create succeeded but getSession returned undefined: ${input.session_id}`);\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Returns the session as stored (ref agents are not hydrated to a value), or\n * undefined if not found. Read-only: does not bump last_activity_timestamp_ms.\n */\n async get(input: GetSessionInput): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined> {\n const record = await this.store.getSession(input);\n if (!record) {\n return undefined;\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Returns the session bound to this tenant-scoped external id, or undefined.\n * Read-only: does not bump last_activity_timestamp_ms.\n */\n async getByExternalId(\n input: GetSessionByExternalIdInput,\n ): Promise<SessionHandle<TSessionCustom, TTurnCustom> | undefined> {\n const record = await this.store.getSessionByExternalId(input);\n if (!record) {\n return undefined;\n }\n return new SessionHandle({\n store: this.store,\n session: record,\n });\n }\n\n /**\n * Get-or-create the session bound to a tenant-scoped `external_id`.\n */\n async getOrCreateByExternalId(\n input: Omit<SessionsCreateInput<TSessionCustom>, 'session_id' | 'external_id'> & { external_id: string },\n ): Promise<{ session: SessionHandle<TSessionCustom, TTurnCustom>; created: boolean }> {\n const { tenant_id, external_id } = input;\n\n const existing = await this.getByExternalId({ tenant_id, external_id });\n if (existing !== undefined) {\n return { session: existing, created: false };\n }\n\n try {\n const session = await this.create({\n ...input,\n session_id: ulid().toLowerCase(),\n external_id,\n });\n return { session, created: true };\n } catch (error) {\n if (!(error instanceof SessionExternalIdConflictError)) {\n throw error;\n }\n const winner = await this.getByExternalId({ tenant_id, external_id });\n if (winner === undefined) {\n throw error;\n }\n return { session: winner, created: false };\n }\n }\n}\n"],"mappings":";AAIA,SAAS,YAAY;AACrB,SAAS,qBAAqB;AAO9B,SAAS,sCAAsC;AAcxC,IAAM,WAAN,MAGL;AAAA,EACiB;AAAA,EAEjB,YAAY,MAAoE;AAC9E,SAAK,QAAQ,KAAK;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAiG;AAC5G,UAAM,KAAK,MAAM,cAAc;AAAA,MAC7B,GAAG;AAAA,MACH,QAAQ,MAAM,UAAU;AAAA,MACxB,UAAU,MAAM,YAAY,CAAC;AAAA,MAC7B,QAAQ,MAAM,UAAU;AAAA,IAC1B,CAAC;AACD,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW;AAAA,MACzC,WAAW,MAAM;AAAA,MACjB,YAAY,MAAM;AAAA,IACpB,CAAC;AACD,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,+DAA+D,MAAM,UAAU,EAAE;AAAA,IACnG;AACA,WAAO,IAAI,cAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,IAAI,OAAyF;AACjG,UAAM,SAAS,MAAM,KAAK,MAAM,WAAW,KAAK;AAChD,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,IAAI,cAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,gBACJ,OACiE;AACjE,UAAM,SAAS,MAAM,KAAK,MAAM,uBAAuB,KAAK;AAC5D,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,WAAO,IAAI,cAAc;AAAA,MACvB,OAAO,KAAK;AAAA,MACZ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,wBACJ,OACoF;AACpF,UAAM,EAAE,WAAW,YAAY,IAAI;AAEnC,UAAM,WAAW,MAAM,KAAK,gBAAgB,EAAE,WAAW,YAAY,CAAC;AACtE,QAAI,aAAa,QAAW;AAC1B,aAAO,EAAE,SAAS,UAAU,SAAS,MAAM;AAAA,IAC7C;AAEA,QAAI;AACF,YAAM,UAAU,MAAM,KAAK,OAAO;AAAA,QAChC,GAAG;AAAA,QACH,YAAY,KAAK,EAAE,YAAY;AAAA,QAC/B;AAAA,MACF,CAAC;AACD,aAAO,EAAE,SAAS,SAAS,KAAK;AAAA,IAClC,SAAS,OAAO;AACd,UAAI,EAAE,iBAAiB,iCAAiC;AACtD,cAAM;AAAA,MACR;AACA,YAAM,SAAS,MAAM,KAAK,gBAAgB,EAAE,WAAW,YAAY,CAAC;AACpE,UAAI,WAAW,QAAW;AACxB,cAAM;AAAA,MACR;AACA,aAAO,EAAE,SAAS,QAAQ,SAAS,MAAM;AAAA,IAC3C;AAAA,EACF;AACF;","names":[]}
@@ -6,8 +6,10 @@ export { AgentSpecSchema, DEFAULT_AGENT_CONFIG_ITERATION_LIMIT, RuntimeConfigSch
6
6
  export type { AgentSpec, Skill } from './schemas/agentSpec';
7
7
  export { CancellationReason, CreateTurnRequestSchema, TurnInputItemSchema, TurnMetricsSchema, TurnSchema, TurnStateCancelledReasonSchema, TurnStateCancelledSchema, TurnStateDoneSchema, TurnStateErrorSchema, TurnStateRunningSchema, TurnStateSchema, } from './schemas/turn';
8
8
  export type { TerminalTurnState, Turn, TurnInputItem, TurnMetrics, TurnState } from './schemas/turn';
9
- export { SessionSchema } from './schemas/session';
10
- export type { Session, SessionAgent } from './schemas/session';
9
+ export { SessionMetadataSchema, SessionMetricsSchema, SessionSchema, SessionSourceScheduleSchema, SessionSourceSchema, SessionSourceTypeSchema, } from './schemas/session';
10
+ export type { Session, SessionAgent, SessionMetadata, SessionMetrics, SessionSource, SessionSourceType, } from './schemas/session';
11
+ export { CreatedBySubjectSchema } from './schemas/subject';
12
+ export type { CreatedBySubject } from './schemas/subject';
11
13
  export { EventType, SessionEventItemSchema, SessionEventSchema, TurnCreatedEventSchema, TurnDoneEventSchema, } from './schemas/events';
12
14
  export type { PersistedTurnEvent, SessionEvent, SessionEventItem, TurnCreatedEvent, TurnDoneEvent, } from './schemas/events';
13
15
  export { TokenPaginationSchema } from './schemas/pagination';
@@ -17,8 +19,8 @@ export { MAIN_THREAD_ID } from './models/TurnRecord';
17
19
  export type { TurnRecord, TurnSnapshot } from './models/TurnRecord';
18
20
  export { assertCreateTurnThreadDelta } from './store/assertCreateTurnThreadDelta';
19
21
  export { InMemorySessionStore } from './store/InMemorySessionStore';
20
- export type { AddThreadsInput, AppendToEventsInput, AppendToThreadContextInput, CreateSessionInput, CreateTurnInput, DeleteSessionInput, FreezeAndGetTurnInput, GetSessionInput, GetTurnInput, ISessionStore, ListSessionEventsInput, ListSessionsInput, ListTurnEventsInput, ListTurnsInput, NewThreadInit, OverwriteThreadContextInput, PatchMCPServersInput, PatchSandboxInfoInput, PatchThreadCapabilityStateInput, RemoveThreadsInput, TurnContextAppend, TurnRecordWithoutSnapshot, UpdateSessionInput, UpdateTurnStateInput, } from './store/ISessionStore';
21
- export { InvalidPageTokenError, PreviousTurnRunningError, SessionAlreadyExistsError, SessionNotFoundError, SessionStoreConflictError, SessionStoreInvariantError, SessionStoreNotFoundError, TurnAlreadyExistsError, TurnNotFoundError, TurnNotRunningError, } from './store/SessionStoreErrors';
22
+ export type { AddThreadsInput, AppendToEventsInput, AppendToThreadContextInput, CreateSessionInput, CreateTurnInput, DeleteSessionInput, FreezeAndGetTurnInput, GetSessionByExternalIdInput, GetSessionInput, GetTurnInput, ISessionStore, ListSessionEventsInput, ListSessionsInput, ListTurnEventsInput, ListTurnsInput, NewThreadInit, OverwriteThreadContextInput, PatchMCPServersInput, PatchSandboxInfoInput, PatchThreadCapabilityStateInput, RemoveThreadsInput, TurnContextAppend, TurnRecordWithoutSnapshot, UpdateSessionInput, UpdateTurnStateInput, } from './store/ISessionStore';
23
+ export { InvalidPageTokenError, PreviousTurnRunningError, SessionAlreadyExistsError, SessionExternalIdConflictError, SessionNotFoundError, SessionStoreConflictError, SessionStoreInvariantError, SessionStoreNotFoundError, TurnAlreadyExistsError, TurnNotFoundError, TurnNotRunningError, } from './store/SessionStoreErrors';
22
24
  export type { ITurnResourceResolver } from './ITurnResourceResolver';
23
25
  export { TurnResourceResolver } from './TurnResourceResolver';
24
26
  export type { TurnSandboxFactory } from './TurnResourceResolver';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-session/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,oCAAoC,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACjH,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,8BAA8B,EAC9B,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAErG,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE/D,OAAO,EACL,SAAS,EACT,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,YAAY,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,EACd,aAAa,EACb,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agent-session/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,eAAe,EAAE,oCAAoC,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACjH,YAAY,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,UAAU,EACV,8BAA8B,EAC9B,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,iBAAiB,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAErG,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,2BAA2B,EAC3B,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,OAAO,EACP,YAAY,EACZ,eAAe,EACf,cAAc,EACd,aAAa,EACb,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,OAAO,EACL,SAAS,EACT,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,YAAY,EACV,eAAe,EACf,mBAAmB,EACnB,0BAA0B,EAC1B,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,2BAA2B,EAC3B,eAAe,EACf,YAAY,EACZ,aAAa,EACb,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,aAAa,EACb,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,kBAAkB,EAClB,iBAAiB,EACjB,yBAAyB,EACzB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,yBAAyB,EACzB,8BAA8B,EAC9B,oBAAoB,EACpB,yBAAyB,EACzB,0BAA0B,EAC1B,yBAAyB,EACzB,sBAAsB,EACtB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,4BAA4B,CAAC;AAEpC,YAAY,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,YAAY,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC"}