@truefoundry/trueforge-core 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-session/ITurnResourceResolver.d.ts +8 -7
- package/dist/agent-session/ITurnResourceResolver.d.ts.map +1 -1
- package/dist/agent-session/ITurnResourceResolver.js.map +1 -1
- package/dist/agent-session/SessionHandle.d.ts +12 -0
- package/dist/agent-session/SessionHandle.d.ts.map +1 -1
- package/dist/agent-session/SessionHandle.js +74 -33
- package/dist/agent-session/SessionHandle.js.map +1 -1
- package/dist/agent-session/SessionHandle.mjs +74 -33
- package/dist/agent-session/SessionHandle.mjs.map +1 -1
- package/dist/agent-session/TurnResourceResolver.d.ts +3 -8
- package/dist/agent-session/TurnResourceResolver.d.ts.map +1 -1
- package/dist/agent-session/TurnResourceResolver.js.map +1 -1
- package/dist/agent-session/TurnResourceResolver.mjs.map +1 -1
- package/dist/agent-session/store/ISessionStore.d.ts +7 -6
- package/dist/agent-session/store/ISessionStore.d.ts.map +1 -1
- package/dist/agent-session/store/ISessionStore.js.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.js +1 -2
- package/dist/agent-session/store/InMemorySessionStore.js.map +1 -1
- package/dist/agent-session/store/InMemorySessionStore.mjs +1 -2
- package/dist/agent-session/store/InMemorySessionStore.mjs.map +1 -1
- package/dist/core/runtime/AgentThread.d.ts.map +1 -1
- package/dist/core/runtime/AgentThread.js +0 -3
- package/dist/core/runtime/AgentThread.js.map +1 -1
- package/dist/core/runtime/AgentThread.mjs +0 -3
- package/dist/core/runtime/AgentThread.mjs.map +1 -1
- 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
|
|
40
|
-
*
|
|
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,
|
|
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
|
|
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,
|
|
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
|
|
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.
|
|
148
|
-
session_id: this.session.session_id,
|
|
150
|
+
const previous = previousTurnId ? await this.freezeTurn({
|
|
149
151
|
turn_id: previousTurnId,
|
|
150
|
-
|
|
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
|
|
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
|
|
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
|
|
289
|
-
const
|
|
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
|
-
|
|
342
|
+
this.buildThread({
|
|
293
343
|
threadId,
|
|
294
|
-
|
|
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
|
-
|
|
349
|
+
resolvedDefinition
|
|
301
350
|
})
|
|
302
351
|
);
|
|
303
352
|
}
|
|
304
353
|
return map;
|
|
305
354
|
}
|
|
306
|
-
|
|
307
|
-
const { definition, extraCapabilities } =
|
|
308
|
-
|
|
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.
|
|
372
|
+
title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : "main"),
|
|
331
373
|
sandbox: input.sandbox,
|
|
332
|
-
context: input.
|
|
333
|
-
currentContextUsage: input.
|
|
334
|
-
parent: input.
|
|
335
|
-
agentInfo: input.
|
|
336
|
-
preComputedCompletion: input.
|
|
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.
|
|
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
|
|
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.
|
|
128
|
-
session_id: this.session.session_id,
|
|
130
|
+
const previous = previousTurnId ? await this.freezeTurn({
|
|
129
131
|
turn_id: previousTurnId,
|
|
130
|
-
|
|
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
|
|
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
|
|
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
|
|
269
|
-
const
|
|
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
|
-
|
|
322
|
+
this.buildThread({
|
|
273
323
|
threadId,
|
|
274
|
-
|
|
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
|
-
|
|
329
|
+
resolvedDefinition
|
|
281
330
|
})
|
|
282
331
|
);
|
|
283
332
|
}
|
|
284
333
|
return map;
|
|
285
334
|
}
|
|
286
|
-
|
|
287
|
-
const { definition, extraCapabilities } =
|
|
288
|
-
|
|
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.
|
|
352
|
+
title: input.previousThreadSnapshot?.agent_info?.name ?? (isChild ? input.threadId : "main"),
|
|
311
353
|
sandbox: input.sandbox,
|
|
312
|
-
context: input.
|
|
313
|
-
currentContextUsage: input.
|
|
314
|
-
parent: input.
|
|
315
|
-
agentInfo: input.
|
|
316
|
-
preComputedCompletion: input.
|
|
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.
|
|
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,
|