@truefoundry/trueforge-core 0.1.1 → 0.1.3

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 (38) hide show
  1. package/dist/agent-session/ITurnResourceResolver.d.ts +8 -7
  2. package/dist/agent-session/ITurnResourceResolver.d.ts.map +1 -1
  3. package/dist/agent-session/ITurnResourceResolver.js.map +1 -1
  4. package/dist/agent-session/SessionHandle.d.ts +12 -0
  5. package/dist/agent-session/SessionHandle.d.ts.map +1 -1
  6. package/dist/agent-session/SessionHandle.js +74 -33
  7. package/dist/agent-session/SessionHandle.js.map +1 -1
  8. package/dist/agent-session/SessionHandle.mjs +74 -33
  9. package/dist/agent-session/SessionHandle.mjs.map +1 -1
  10. package/dist/agent-session/TurnResourceResolver.d.ts +3 -8
  11. package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
  12. package/dist/agent-session/TurnResourceResolver.js.map +1 -1
  13. package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
  14. package/dist/agent-session/store/ISessionStore.d.ts +7 -6
  15. package/dist/agent-session/store/ISessionStore.d.ts.map +1 -1
  16. package/dist/agent-session/store/ISessionStore.js.map +1 -1
  17. package/dist/agent-session/store/InMemorySessionStore.js +1 -2
  18. package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
  19. package/dist/agent-session/store/InMemorySessionStore.mjs +1 -2
  20. package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
  21. package/dist/core/runtime/AgentThread.d.ts.map +1 -1
  22. package/dist/core/runtime/AgentThread.js +0 -3
  23. package/dist/core/runtime/AgentThread.js.map +1 -1
  24. package/dist/core/runtime/AgentThread.mjs +0 -3
  25. package/dist/core/runtime/AgentThread.mjs.map +1 -1
  26. package/dist/core/sandbox/Sandbox.d.ts +1 -2
  27. package/dist/core/sandbox/Sandbox.d.ts.map +1 -1
  28. package/dist/core/sandbox/Sandbox.js +1 -5
  29. package/dist/core/sandbox/Sandbox.js.map +1 -1
  30. package/dist/core/sandbox/Sandbox.mjs +1 -5
  31. package/dist/core/sandbox/Sandbox.mjs.map +1 -1
  32. package/dist/core/sandbox/sandboxScripts.gen.d.ts +1 -1
  33. package/dist/core/sandbox/sandboxScripts.gen.d.ts.map +1 -1
  34. package/dist/core/sandbox/sandboxScripts.gen.js +1 -1
  35. package/dist/core/sandbox/sandboxScripts.gen.js.map +1 -1
  36. package/dist/core/sandbox/sandboxScripts.gen.mjs +1 -1
  37. package/dist/core/sandbox/sandboxScripts.gen.mjs.map +1 -1
  38. package/package.json +1 -1
@@ -6,6 +6,11 @@ import type { Sandbox, SandboxInfo } from '../core/sandbox/Sandbox';
6
6
  import type { AgentTracing } from '../core/tracing/AgentTracing';
7
7
  import type { TurnRecord } from './models/TurnRecord';
8
8
  import type { AgentSpec } from './schemas/agentSpec';
9
+ /** Result of {@link ITurnResourceResolver.resolveAgentDefinition}. */
10
+ export interface ResolvedAgentDefinition {
11
+ definition: AgentDefinition;
12
+ extraCapabilities?: AgentCapability[] | undefined;
13
+ }
9
14
  /**
10
15
  * Per-run wiring contract consumed by SessionHandle.createTurn(). Implementations hold
11
16
  * per-request state (secrets, providers, caches) freely.
@@ -36,8 +41,8 @@ export interface ITurnResourceResolver<TTurnCustom extends object = Record<strin
36
41
  tracing: AgentTracing;
37
42
  }): Promise<Sandbox | undefined>;
38
43
  /**
39
- * Called once per thread_id; calls for different ids may overlap (parallel
40
- * sub-agent spawns), so implementations must be concurrency-safe across ids.
44
+ * Called once per thread (rebuild or live sub-agent spawn); calls for different
45
+ * threads may overlap, so implementations must be concurrency-safe.
41
46
  * `agent_info` is set for sub-agent threads. `previousTurn` is read-only:
42
47
  * branch on it, but never load state into capabilities — return blank
43
48
  * instances; the AgentThread constructor is the sole hydration path.
@@ -45,15 +50,11 @@ export interface ITurnResourceResolver<TTurnCustom extends object = Record<strin
45
50
  */
46
51
  resolveAgentDefinition(input: {
47
52
  spec: AgentSpec;
48
- thread_id: string;
49
53
  agent_info?: AgentInfo | undefined;
50
54
  previousTurn?: TurnRecord<TTurnCustom> | undefined;
51
55
  signal: AbortSignal;
52
56
  tracing: AgentTracing;
53
- }): Promise<{
54
- definition: AgentDefinition;
55
- extraCapabilities?: AgentCapability[] | undefined;
56
- }>;
57
+ }): Promise<ResolvedAgentDefinition>;
57
58
  /**
58
59
  * Release per-run resources. Called by the harness at the end of the run:
59
60
  * by TurnHandle.stream() in its finally (AFTER the terminal state write), or by
@@ -1 +1 @@
1
- {"version":3,"file":"ITurnResourceResolver.d.ts","sourceRoot":"","sources":["../../src/agent-session/ITurnResourceResolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IACvF,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,aAAa,IAAI,YAAY,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClE;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE;QACpB,IAAI,EAAE,SAAS,CAAC;QAChB,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;QACnC,YAAY,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;QACnD,MAAM,EAAE,WAAW,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACjC;;;;;;;OAOG;IACH,sBAAsB,CAAC,KAAK,EAAE;QAC5B,IAAI,EAAE,SAAS,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;QACnC,YAAY,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;QACnD,MAAM,EAAE,WAAW,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,GAAG,OAAO,CAAC;QACV,UAAU,EAAE,eAAe,CAAC;QAC5B,iBAAiB,CAAC,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC;KACnD,CAAC,CAAC;IACH;;;;;;;;;OASG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
1
+ {"version":3,"file":"ITurnResourceResolver.d.ts","sourceRoot":"","sources":["../../src/agent-session/ITurnResourceResolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,sEAAsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,eAAe,CAAC;IAC5B,iBAAiB,CAAC,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC;CACnD;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB,CAAC,WAAW,SAAS,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IACvF,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,aAAa,IAAI,YAAY,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAClE;;;;;OAKG;IACH,cAAc,CAAC,KAAK,EAAE;QACpB,IAAI,EAAE,SAAS,CAAC;QAChB,QAAQ,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;QACnC,YAAY,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;QACnD,MAAM,EAAE,WAAW,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,GAAG,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC;IACjC;;;;;;;OAOG;IACH,sBAAsB,CAAC,KAAK,EAAE;QAC5B,IAAI,EAAE,SAAS,CAAC;QAChB,UAAU,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;QACnC,YAAY,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC;QACnD,MAAM,EAAE,WAAW,CAAC;QACpB,OAAO,EAAE,YAAY,CAAC;KACvB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACrC;;;;;;;;;OASG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/agent-session/ITurnResourceResolver.ts"],"sourcesContent":["import type { Logger } from 'winston';\nimport type { AgentCapability } from '../core/capabilities/AgentCapability';\nimport type { AgentDefinition } from '../core/runtime/AgentDefinition';\nimport type { AgentInfo } from '../core/runtime/AgentThread.types';\nimport type { Sandbox, SandboxInfo } from '../core/sandbox/Sandbox';\nimport type { AgentTracing } from '../core/tracing/AgentTracing';\nimport type { TurnRecord } from './models/TurnRecord';\nimport type { AgentSpec } from './schemas/agentSpec';\n\n/**\n * Per-run wiring contract consumed by SessionHandle.createTurn(). Implementations hold\n * per-request state (secrets, providers, caches) freely.\n */\nexport interface ITurnResourceResolver<TTurnCustom extends object = Record<string, never>> {\n /** Forwarded to AgentThread / orchestrator / RemoteMCP. */\n readonly logger: Logger;\n /** Called exactly once per run, before any other method. */\n createTracing(): AgentTracing;\n /**\n * Look up the live AgentSpec for a named (ref) session agent.\n * Value sessions use the stored spec and never call this.\n */\n resolveAgentSpec(input: { agent_id: string }): Promise<AgentSpec>;\n /**\n * Called exactly once per run, before any thread is built; the harness holds\n * the result and shares the same reference across all threads. Return\n * undefined when the run needs no sandbox. `existing` carries the previous\n * turn's sandbox info for cross-turn reattach.\n */\n resolveSandbox(input: {\n spec: AgentSpec;\n existing?: SandboxInfo | undefined;\n previousTurn?: TurnRecord<TTurnCustom> | undefined;\n signal: AbortSignal;\n tracing: AgentTracing;\n }): Promise<Sandbox | undefined>;\n /**\n * Called once per thread_id; calls for different ids may overlap (parallel\n * sub-agent spawns), so implementations must be concurrency-safe across ids.\n * `agent_info` is set for sub-agent threads. `previousTurn` is read-only:\n * branch on it, but never load state into capabilities — return blank\n * instances; the AgentThread constructor is the sole hydration path.\n * `extraCapabilities` are appended after the built-in capabilities.\n */\n resolveAgentDefinition(input: {\n spec: AgentSpec;\n thread_id: string;\n agent_info?: AgentInfo | undefined;\n previousTurn?: TurnRecord<TTurnCustom> | undefined;\n signal: AbortSignal;\n tracing: AgentTracing;\n }): Promise<{\n definition: AgentDefinition;\n extraCapabilities?: AgentCapability[] | undefined;\n }>;\n /**\n * Release per-run resources. Called by the harness at the end of the run:\n * by TurnHandle.stream() in its finally (AFTER the terminal state write), or by\n * SessionHandle.createTurn() when it throws before a TurnHandle exists — so resources acquired\n * during a failed run (e.g. a sandbox VM) are still released. Best-effort:\n * the harness logs and swallows errors — close() can never flip a terminal\n * state or fail the turn. Must be idempotent. The resolver owns cleanup\n * because it owns acquisition: the run flow calls this one method without\n * knowing what was resolved.\n */\n close(): Promise<void>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/agent-session/ITurnResourceResolver.ts"],"sourcesContent":["import type { Logger } from 'winston';\nimport type { AgentCapability } from '../core/capabilities/AgentCapability';\nimport type { AgentDefinition } from '../core/runtime/AgentDefinition';\nimport type { AgentInfo } from '../core/runtime/AgentThread.types';\nimport type { Sandbox, SandboxInfo } from '../core/sandbox/Sandbox';\nimport type { AgentTracing } from '../core/tracing/AgentTracing';\nimport type { TurnRecord } from './models/TurnRecord';\nimport type { AgentSpec } from './schemas/agentSpec';\n\n/** Result of {@link ITurnResourceResolver.resolveAgentDefinition}. */\nexport interface ResolvedAgentDefinition {\n definition: AgentDefinition;\n extraCapabilities?: AgentCapability[] | undefined;\n}\n\n/**\n * Per-run wiring contract consumed by SessionHandle.createTurn(). Implementations hold\n * per-request state (secrets, providers, caches) freely.\n */\nexport interface ITurnResourceResolver<TTurnCustom extends object = Record<string, never>> {\n /** Forwarded to AgentThread / orchestrator / RemoteMCP. */\n readonly logger: Logger;\n /** Called exactly once per run, before any other method. */\n createTracing(): AgentTracing;\n /**\n * Look up the live AgentSpec for a named (ref) session agent.\n * Value sessions use the stored spec and never call this.\n */\n resolveAgentSpec(input: { agent_id: string }): Promise<AgentSpec>;\n /**\n * Called exactly once per run, before any thread is built; the harness holds\n * the result and shares the same reference across all threads. Return\n * undefined when the run needs no sandbox. `existing` carries the previous\n * turn's sandbox info for cross-turn reattach.\n */\n resolveSandbox(input: {\n spec: AgentSpec;\n existing?: SandboxInfo | undefined;\n previousTurn?: TurnRecord<TTurnCustom> | undefined;\n signal: AbortSignal;\n tracing: AgentTracing;\n }): Promise<Sandbox | undefined>;\n /**\n * Called once per thread (rebuild or live sub-agent spawn); calls for different\n * threads may overlap, so implementations must be concurrency-safe.\n * `agent_info` is set for sub-agent threads. `previousTurn` is read-only:\n * branch on it, but never load state into capabilities — return blank\n * instances; the AgentThread constructor is the sole hydration path.\n * `extraCapabilities` are appended after the built-in capabilities.\n */\n resolveAgentDefinition(input: {\n spec: AgentSpec;\n agent_info?: AgentInfo | undefined;\n previousTurn?: TurnRecord<TTurnCustom> | undefined;\n signal: AbortSignal;\n tracing: AgentTracing;\n }): Promise<ResolvedAgentDefinition>;\n /**\n * Release per-run resources. Called by the harness at the end of the run:\n * by TurnHandle.stream() in its finally (AFTER the terminal state write), or by\n * SessionHandle.createTurn() when it throws before a TurnHandle exists — so resources acquired\n * during a failed run (e.g. a sandbox VM) are still released. Best-effort:\n * the harness logs and swallows errors — close() can never flip a terminal\n * state or fail the turn. Must be idempotent. The resolver owns cleanup\n * because it owns acquisition: the run flow calls this one method without\n * knowing what was resolved.\n */\n close(): Promise<void>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -1,9 +1,11 @@
1
1
  import type { ITurnResourceResolver } from './ITurnResourceResolver';
2
2
  import type { SessionRecord } from './models/SessionRecord';
3
+ import { type TurnRecord } from './models/TurnRecord';
3
4
  import type { SessionEventItem } from './schemas/events';
4
5
  import type { TokenPagination } from './schemas/pagination';
5
6
  import type { SessionAgent } from './schemas/session';
6
7
  import type { TurnInputItem } from './schemas/turn';
8
+ import { CancellationReason } from './schemas/turn';
7
9
  import type { ISessionStore, TurnRecordWithoutSnapshot } from './store/ISessionStore';
8
10
  import { TurnHandle } from './TurnHandle';
9
11
  export declare class SessionHandle<TSessionCustom extends object = Record<string, never>, TTurnCustom extends object = Record<string, never>> {
@@ -51,6 +53,15 @@ export declare class SessionHandle<TSessionCustom extends object = Record<string
51
53
  */
52
54
  update_session_title_if_not_exist?: string | undefined;
53
55
  }): Promise<TurnHandle<TTurnCustom>>;
56
+ /**
57
+ * Conditionally cancel a running turn in this session and return the
58
+ * now-immutable record. Already-terminal turns are returned unchanged.
59
+ * Missing turn → {@link TurnNotFoundError}.
60
+ */
61
+ freezeTurn(input: {
62
+ turn_id: string;
63
+ reason: CancellationReason;
64
+ }): Promise<TurnRecord<TTurnCustom>>;
54
65
  /** Returns the turn handle (store-backed; not executable), or undefined if not found. */
55
66
  getTurn(turn_id: string): Promise<TurnHandle<TTurnCustom> | undefined>;
56
67
  /** Paginated list of this session's turn rows (no snapshot). */
@@ -74,6 +85,7 @@ export declare class SessionHandle<TSessionCustom extends object = Record<string
74
85
  data: SessionEventItem[];
75
86
  pagination: TokenPagination;
76
87
  }>;
88
+ private resolveAgentDefinitions;
77
89
  private buildThreads;
78
90
  private buildThread;
79
91
  private makeCreateDynamicSubAgentThread;
@@ -1 +1 @@
1
- {"version":3,"file":"SessionHandle.d.ts","sourceRoot":"","sources":["../../src/agent-session/SessionHandle.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAoC,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACxH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAkF1C,qBAAa,aAAa,CACxB,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;IACnE,OAAO,CAAC,OAAO,CAAgC;IAE/C,YAAY,OAAO,EAAE;QAAE,KAAK,EAAE,aAAa,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAAC,OAAO,EAAE,aAAa,CAAC,cAAc,CAAC,CAAA;KAAE,EAGjH;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,IAAI,KAAK,IAAI,YAAY,CAExB;IAED,IAAI,MAAM,IAAI,cAAc,GAAG,IAAI,CAElC;IAED,IAAI,MAAM,IAAI,aAAa,CAAC,cAAc,CAAC,CAE1C;IAED;;;;;;;;;;;;;;;;OAgBG;IACG,UAAU,CAAC,KAAK,EAAE;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;QACpC,0FAA0F;QAC1F,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACtC,MAAM,EAAE,WAAW,CAAC;QACpB,QAAQ,EAAE,qBAAqB,CAAC,WAAW,CAAC,CAAC;QAC7C,yFAAyF;QACzF,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,KAAK,WAAW,CAAC,GAAG,SAAS,CAAC;QAC7E;;;;WAIG;QACH,iCAAiC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACxD,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAmInC;IAED,yFAAyF;IACnF,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAC,CAM3E;IAED,gEAAgE;IAC1D,SAAS,CAAC,KAAK,EAAE;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACjC,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,yBAAyB,CAAC,WAAW,CAAC,EAAE,CAAC;QAAC,UAAU,EAAE,eAAe,CAAA;KAAE,CAAC,CAM3F;IAED;;;;OAIG;IACG,UAAU,CAAC,KAAK,EAAE;QACtB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAChC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACnC,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,gBAAgB,EAAE,CAAC;QACzB,UAAU,EAAE,eAAe,CAAC;KAC7B,CAAC,CAOD;YAEa,YAAY;YA8BZ,WAAW;IA+CzB,OAAO,CAAC,+BAA+B;CAoDxC"}
1
+ {"version":3,"file":"SessionHandle.d.ts","sourceRoot":"","sources":["../../src/agent-session/SessionHandle.ts"],"names":[],"mappings":"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"}
@@ -83,14 +83,14 @@ function collectContextAppends(events) {
83
83
  return [...appendMap.values()];
84
84
  })();
85
85
  }
86
- function cancelledTurnDoneEvent() {
86
+ function cancelledTurnDoneEvent(reason) {
87
87
  return {
88
88
  type: import_events.EventType.TURN_DONE,
89
89
  id: (0, import_schema.newEventId)(),
90
90
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
91
91
  state: {
92
92
  status: "cancelled",
93
- reason: import_turn.CancellationReason.CancelledForNextTurn,
93
+ reason,
94
94
  completed_at: (/* @__PURE__ */ new Date()).toISOString()
95
95
  },
96
96
  thread_id: null
@@ -103,6 +103,9 @@ function threadsRecordFromMap(threads) {
103
103
  }
104
104
  return out;
105
105
  }
106
+ function threadIdsForCurrentTurn(snapshot) {
107
+ return snapshot ? Object.keys(snapshot.threads) : [import_TurnRecord.MAIN_THREAD_ID];
108
+ }
106
109
  var SessionHandle = class {
107
110
  store;
108
111
  session;
@@ -144,10 +147,9 @@ var SessionHandle = class {
144
147
  */
145
148
  async createTurn(input) {
146
149
  const previousTurnId = resolvePreviousTurnId(input.previous_turn_id, this.session.last_turn_id);
147
- const previous = previousTurnId ? await this.store.freezeAndGetTurn({
148
- session_id: this.session.session_id,
150
+ const previous = previousTurnId ? await this.freezeTurn({
149
151
  turn_id: previousTurnId,
150
- turn_done_event: cancelledTurnDoneEvent()
152
+ reason: import_turn.CancellationReason.CancelledForNextTurn
151
153
  }) : void 0;
152
154
  const custom = typeof input.custom === "function" ? input.custom(previous?.custom ?? void 0) : input.custom;
153
155
  try {
@@ -161,14 +163,28 @@ var SessionHandle = class {
161
163
  signal: input.signal,
162
164
  tracing
163
165
  });
164
- const agentThreads = await this.buildThreads({
166
+ const definitionsByThreadId = await this.resolveAgentDefinitions({
165
167
  previous,
166
168
  resolver: input.resolver,
167
169
  spec,
168
- sandbox,
169
170
  tracing,
170
171
  signal: input.signal
171
172
  });
173
+ const mainDefinition = definitionsByThreadId.get(import_TurnRecord.MAIN_THREAD_ID);
174
+ if (!mainDefinition) {
175
+ throw new Error("Unreachable: missing resolved agent definition for main thread");
176
+ }
177
+ if (sandbox) {
178
+ sandbox.configureCodeMode(mainDefinition.definition.toolSets ?? []);
179
+ }
180
+ const agentThreads = this.buildThreads({
181
+ previous,
182
+ resolver: input.resolver,
183
+ spec,
184
+ sandbox,
185
+ tracing,
186
+ definitionsByThreadId
187
+ });
172
188
  const createDynamicSubAgentThread = this.makeCreateDynamicSubAgentThread({
173
189
  resolver: input.resolver,
174
190
  previous,
@@ -252,6 +268,19 @@ var SessionHandle = class {
252
268
  throw error;
253
269
  }
254
270
  }
271
+ /**
272
+ * Conditionally cancel a running turn in this session and return the
273
+ * now-immutable record. Already-terminal turns are returned unchanged.
274
+ * Missing turn → {@link TurnNotFoundError}.
275
+ */
276
+ async freezeTurn(input) {
277
+ return this.store.freezeAndGetTurn({
278
+ session_id: this.session.session_id,
279
+ turn_id: input.turn_id,
280
+ reason: input.reason,
281
+ turn_done_event: cancelledTurnDoneEvent(input.reason)
282
+ });
283
+ }
255
284
  /** Returns the turn handle (store-backed; not executable), or undefined if not found. */
256
285
  async getTurn(turn_id) {
257
286
  return import_TurnHandle.TurnHandle.get({
@@ -281,38 +310,51 @@ var SessionHandle = class {
281
310
  last_turn_id: input.last_turn_id
282
311
  });
283
312
  }
284
- async buildThreads(input) {
313
+ async resolveAgentDefinitions(input) {
314
+ const snapshots = input.previous?.snapshot.threads;
315
+ const threadIds = threadIdsForCurrentTurn(input.previous?.snapshot);
316
+ const definitionsByThreadId = /* @__PURE__ */ new Map();
317
+ await Promise.all(
318
+ threadIds.map(async (threadId) => {
319
+ const previousThreadSnapshot = snapshots?.[threadId];
320
+ const resolved = await input.resolver.resolveAgentDefinition({
321
+ spec: input.spec,
322
+ agent_info: previousThreadSnapshot?.agent_info ?? void 0,
323
+ previousTurn: input.previous,
324
+ signal: input.signal,
325
+ tracing: input.tracing
326
+ });
327
+ definitionsByThreadId.set(threadId, resolved);
328
+ })
329
+ );
330
+ return definitionsByThreadId;
331
+ }
332
+ buildThreads(input) {
285
333
  const snapshots = input.previous?.snapshot.threads;
286
- const threadIds = snapshots ? Object.keys(snapshots) : [import_TurnRecord.MAIN_THREAD_ID];
287
334
  const map = /* @__PURE__ */ new Map();
288
- for (const threadId of threadIds) {
289
- const data = snapshots?.[threadId];
335
+ for (const threadId of threadIdsForCurrentTurn(input.previous?.snapshot)) {
336
+ const resolvedDefinition = input.definitionsByThreadId.get(threadId);
337
+ if (!resolvedDefinition) {
338
+ throw new Error(`Unreachable: missing resolved agent definition for thread '${threadId}'`);
339
+ }
290
340
  map.set(
291
341
  threadId,
292
- await this.buildThread({
342
+ this.buildThread({
293
343
  threadId,
294
- data,
344
+ previousThreadSnapshot: snapshots?.[threadId],
295
345
  resolver: input.resolver,
296
- previous: input.previous,
297
346
  spec: input.spec,
298
347
  sandbox: input.sandbox,
299
348
  tracing: input.tracing,
300
- signal: input.signal
349
+ resolvedDefinition
301
350
  })
302
351
  );
303
352
  }
304
353
  return map;
305
354
  }
306
- async buildThread(input) {
307
- const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({
308
- spec: input.spec,
309
- thread_id: input.threadId,
310
- agent_info: input.data?.agent_info ?? void 0,
311
- previousTurn: input.previous,
312
- signal: input.signal,
313
- tracing: input.tracing
314
- });
315
- const isChild = Boolean(input.data?.parent);
355
+ buildThread(input) {
356
+ const { definition, extraCapabilities } = input.resolvedDefinition;
357
+ const isChild = Boolean(input.previousThreadSnapshot?.parent);
316
358
  const capabilities = [
317
359
  ...(0, import_builtinsFromSpec.builtinsFromSpec)({
318
360
  spec: input.spec,
@@ -327,15 +369,15 @@ var SessionHandle = class {
327
369
  return new import_AgentThread.AgentThread({
328
370
  definition,
329
371
  threadId: input.threadId,
330
- title: input.data?.agent_info?.name ?? (isChild ? input.threadId : "main"),
372
+ title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : "main"),
331
373
  sandbox: input.sandbox,
332
- context: input.data?.context,
333
- currentContextUsage: input.data?.current_context_usage,
334
- parent: input.data?.parent ?? void 0,
335
- agentInfo: input.data?.agent_info ?? void 0,
336
- preComputedCompletion: input.data?.completion ?? void 0,
374
+ context: input.previousThreadSnapshot?.context,
375
+ currentContextUsage: input.previousThreadSnapshot?.current_context_usage,
376
+ parent: input.previousThreadSnapshot?.parent ?? void 0,
377
+ agentInfo: input.previousThreadSnapshot?.agent_info ?? void 0,
378
+ preComputedCompletion: input.previousThreadSnapshot?.completion ?? void 0,
337
379
  capabilities,
338
- capabilityState: input.data?.capability_state ?? void 0,
380
+ capabilityState: input.previousThreadSnapshot?.capability_state ?? void 0,
339
381
  tracing: input.tracing,
340
382
  logger: input.resolver.logger
341
383
  });
@@ -344,7 +386,6 @@ var SessionHandle = class {
344
386
  return async (params) => {
345
387
  const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({
346
388
  spec: input.spec,
347
- thread_id: params.threadId,
348
389
  agent_info: params.request,
349
390
  previousTurn: input.previous,
350
391
  signal: params.signal,
@@ -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 } from './ITurnResourceResolver';\nimport type { SessionRecord } from './models/SessionRecord';\nimport { MAIN_THREAD_ID, type TurnRecord } 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;\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(): TurnDoneEvent {\n return {\n type: EventType.TURN_DONE,\n id: newEventId(),\n created_at: new Date().toISOString(),\n state: {\n status: 'cancelled',\n reason: CancellationReason.CancelledForNextTurn,\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\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.store.freezeAndGetTurn({\n session_id: this.session.session_id,\n turn_id: previousTurnId,\n turn_done_event: cancelledTurnDoneEvent(),\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 agentThreads = await this.buildThreads({\n previous,\n resolver: input.resolver,\n spec,\n sandbox,\n tracing,\n signal: input.signal,\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 /** 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 buildThreads(input: {\n previous: TurnRecord<TTurnCustom> | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n signal: AbortSignal;\n }): Promise<Map<string, AgentThread>> {\n const snapshots = input.previous?.snapshot.threads;\n const threadIds = snapshots ? Object.keys(snapshots) : [MAIN_THREAD_ID];\n const map = new Map<string, AgentThread>();\n for (const threadId of threadIds) {\n const data = snapshots?.[threadId];\n map.set(\n threadId,\n await this.buildThread({\n threadId,\n data,\n resolver: input.resolver,\n previous: input.previous,\n spec: input.spec,\n sandbox: input.sandbox,\n tracing: input.tracing,\n signal: input.signal,\n }),\n );\n }\n return map;\n }\n\n private async buildThread(input: {\n threadId: string;\n data?: AgentThreadSnapshot | undefined;\n resolver: ITurnResourceResolver<TTurnCustom>;\n previous: TurnRecord<TTurnCustom> | undefined;\n spec: AgentSpec;\n sandbox: Sandbox | undefined;\n tracing: AgentTracing;\n signal: AbortSignal;\n }): Promise<AgentThread> {\n const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({\n spec: input.spec,\n thread_id: input.threadId,\n agent_info: input.data?.agent_info ?? undefined,\n previousTurn: input.previous,\n signal: input.signal,\n tracing: input.tracing,\n });\n const isChild = Boolean(input.data?.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.data?.agent_info?.name ?? (isChild ? input.threadId : 'main'),\n sandbox: input.sandbox,\n context: input.data?.context,\n currentContextUsage: input.data?.current_context_usage,\n parent: input.data?.parent ?? undefined,\n agentInfo: input.data?.agent_info ?? undefined,\n preComputedCompletion: input.data?.completion ?? undefined,\n capabilities,\n capabilityState: input.data?.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 thread_id: params.threadId,\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 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":[]}
@@ -63,14 +63,14 @@ function collectContextAppends(events) {
63
63
  return [...appendMap.values()];
64
64
  })();
65
65
  }
66
- function cancelledTurnDoneEvent() {
66
+ function cancelledTurnDoneEvent(reason) {
67
67
  return {
68
68
  type: EventType.TURN_DONE,
69
69
  id: newEventId(),
70
70
  created_at: (/* @__PURE__ */ new Date()).toISOString(),
71
71
  state: {
72
72
  status: "cancelled",
73
- reason: CancellationReason.CancelledForNextTurn,
73
+ reason,
74
74
  completed_at: (/* @__PURE__ */ new Date()).toISOString()
75
75
  },
76
76
  thread_id: null
@@ -83,6 +83,9 @@ function threadsRecordFromMap(threads) {
83
83
  }
84
84
  return out;
85
85
  }
86
+ function threadIdsForCurrentTurn(snapshot) {
87
+ return snapshot ? Object.keys(snapshot.threads) : [MAIN_THREAD_ID];
88
+ }
86
89
  var SessionHandle = class {
87
90
  store;
88
91
  session;
@@ -124,10 +127,9 @@ var SessionHandle = class {
124
127
  */
125
128
  async createTurn(input) {
126
129
  const previousTurnId = resolvePreviousTurnId(input.previous_turn_id, this.session.last_turn_id);
127
- const previous = previousTurnId ? await this.store.freezeAndGetTurn({
128
- session_id: this.session.session_id,
130
+ const previous = previousTurnId ? await this.freezeTurn({
129
131
  turn_id: previousTurnId,
130
- turn_done_event: cancelledTurnDoneEvent()
132
+ reason: CancellationReason.CancelledForNextTurn
131
133
  }) : void 0;
132
134
  const custom = typeof input.custom === "function" ? input.custom(previous?.custom ?? void 0) : input.custom;
133
135
  try {
@@ -141,14 +143,28 @@ var SessionHandle = class {
141
143
  signal: input.signal,
142
144
  tracing
143
145
  });
144
- const agentThreads = await this.buildThreads({
146
+ const definitionsByThreadId = await this.resolveAgentDefinitions({
145
147
  previous,
146
148
  resolver: input.resolver,
147
149
  spec,
148
- sandbox,
149
150
  tracing,
150
151
  signal: input.signal
151
152
  });
153
+ const mainDefinition = definitionsByThreadId.get(MAIN_THREAD_ID);
154
+ if (!mainDefinition) {
155
+ throw new Error("Unreachable: missing resolved agent definition for main thread");
156
+ }
157
+ if (sandbox) {
158
+ sandbox.configureCodeMode(mainDefinition.definition.toolSets ?? []);
159
+ }
160
+ const agentThreads = this.buildThreads({
161
+ previous,
162
+ resolver: input.resolver,
163
+ spec,
164
+ sandbox,
165
+ tracing,
166
+ definitionsByThreadId
167
+ });
152
168
  const createDynamicSubAgentThread = this.makeCreateDynamicSubAgentThread({
153
169
  resolver: input.resolver,
154
170
  previous,
@@ -232,6 +248,19 @@ var SessionHandle = class {
232
248
  throw error;
233
249
  }
234
250
  }
251
+ /**
252
+ * Conditionally cancel a running turn in this session and return the
253
+ * now-immutable record. Already-terminal turns are returned unchanged.
254
+ * Missing turn → {@link TurnNotFoundError}.
255
+ */
256
+ async freezeTurn(input) {
257
+ return this.store.freezeAndGetTurn({
258
+ session_id: this.session.session_id,
259
+ turn_id: input.turn_id,
260
+ reason: input.reason,
261
+ turn_done_event: cancelledTurnDoneEvent(input.reason)
262
+ });
263
+ }
235
264
  /** Returns the turn handle (store-backed; not executable), or undefined if not found. */
236
265
  async getTurn(turn_id) {
237
266
  return TurnHandle.get({
@@ -261,38 +290,51 @@ var SessionHandle = class {
261
290
  last_turn_id: input.last_turn_id
262
291
  });
263
292
  }
264
- async buildThreads(input) {
293
+ async resolveAgentDefinitions(input) {
294
+ const snapshots = input.previous?.snapshot.threads;
295
+ const threadIds = threadIdsForCurrentTurn(input.previous?.snapshot);
296
+ const definitionsByThreadId = /* @__PURE__ */ new Map();
297
+ await Promise.all(
298
+ threadIds.map(async (threadId) => {
299
+ const previousThreadSnapshot = snapshots?.[threadId];
300
+ const resolved = await input.resolver.resolveAgentDefinition({
301
+ spec: input.spec,
302
+ agent_info: previousThreadSnapshot?.agent_info ?? void 0,
303
+ previousTurn: input.previous,
304
+ signal: input.signal,
305
+ tracing: input.tracing
306
+ });
307
+ definitionsByThreadId.set(threadId, resolved);
308
+ })
309
+ );
310
+ return definitionsByThreadId;
311
+ }
312
+ buildThreads(input) {
265
313
  const snapshots = input.previous?.snapshot.threads;
266
- const threadIds = snapshots ? Object.keys(snapshots) : [MAIN_THREAD_ID];
267
314
  const map = /* @__PURE__ */ new Map();
268
- for (const threadId of threadIds) {
269
- const data = snapshots?.[threadId];
315
+ for (const threadId of threadIdsForCurrentTurn(input.previous?.snapshot)) {
316
+ const resolvedDefinition = input.definitionsByThreadId.get(threadId);
317
+ if (!resolvedDefinition) {
318
+ throw new Error(`Unreachable: missing resolved agent definition for thread '${threadId}'`);
319
+ }
270
320
  map.set(
271
321
  threadId,
272
- await this.buildThread({
322
+ this.buildThread({
273
323
  threadId,
274
- data,
324
+ previousThreadSnapshot: snapshots?.[threadId],
275
325
  resolver: input.resolver,
276
- previous: input.previous,
277
326
  spec: input.spec,
278
327
  sandbox: input.sandbox,
279
328
  tracing: input.tracing,
280
- signal: input.signal
329
+ resolvedDefinition
281
330
  })
282
331
  );
283
332
  }
284
333
  return map;
285
334
  }
286
- async buildThread(input) {
287
- const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({
288
- spec: input.spec,
289
- thread_id: input.threadId,
290
- agent_info: input.data?.agent_info ?? void 0,
291
- previousTurn: input.previous,
292
- signal: input.signal,
293
- tracing: input.tracing
294
- });
295
- const isChild = Boolean(input.data?.parent);
335
+ buildThread(input) {
336
+ const { definition, extraCapabilities } = input.resolvedDefinition;
337
+ const isChild = Boolean(input.previousThreadSnapshot?.parent);
296
338
  const capabilities = [
297
339
  ...builtinsFromSpec({
298
340
  spec: input.spec,
@@ -307,15 +349,15 @@ var SessionHandle = class {
307
349
  return new AgentThread({
308
350
  definition,
309
351
  threadId: input.threadId,
310
- title: input.data?.agent_info?.name ?? (isChild ? input.threadId : "main"),
352
+ title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : "main"),
311
353
  sandbox: input.sandbox,
312
- context: input.data?.context,
313
- currentContextUsage: input.data?.current_context_usage,
314
- parent: input.data?.parent ?? void 0,
315
- agentInfo: input.data?.agent_info ?? void 0,
316
- preComputedCompletion: input.data?.completion ?? void 0,
354
+ context: input.previousThreadSnapshot?.context,
355
+ currentContextUsage: input.previousThreadSnapshot?.current_context_usage,
356
+ parent: input.previousThreadSnapshot?.parent ?? void 0,
357
+ agentInfo: input.previousThreadSnapshot?.agent_info ?? void 0,
358
+ preComputedCompletion: input.previousThreadSnapshot?.completion ?? void 0,
317
359
  capabilities,
318
- capabilityState: input.data?.capability_state ?? void 0,
360
+ capabilityState: input.previousThreadSnapshot?.capability_state ?? void 0,
319
361
  tracing: input.tracing,
320
362
  logger: input.resolver.logger
321
363
  });
@@ -324,7 +366,6 @@ var SessionHandle = class {
324
366
  return async (params) => {
325
367
  const { definition, extraCapabilities } = await input.resolver.resolveAgentDefinition({
326
368
  spec: input.spec,
327
- thread_id: params.threadId,
328
369
  agent_info: params.request,
329
370
  previousTurn: input.previous,
330
371
  signal: params.signal,