zeitlich 0.2.47 → 0.2.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{activities-CPwKoUlD.d.cts → activities-7OcT_vdR.d.cts} +3 -3
- package/dist/{activities-DlaBxNID.d.ts → activities-zG_FBoY2.d.ts} +3 -3
- package/dist/adapters/thread/anthropic/index.d.cts +5 -5
- package/dist/adapters/thread/anthropic/index.d.ts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.cts +5 -5
- package/dist/adapters/thread/anthropic/workflow.d.ts +5 -5
- package/dist/adapters/thread/google-genai/index.d.cts +5 -5
- package/dist/adapters/thread/google-genai/index.d.ts +5 -5
- package/dist/adapters/thread/google-genai/workflow.d.cts +6 -6
- package/dist/adapters/thread/google-genai/workflow.d.ts +6 -6
- package/dist/adapters/thread/langchain/index.d.cts +5 -5
- package/dist/adapters/thread/langchain/index.d.ts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.cts +5 -5
- package/dist/adapters/thread/langchain/workflow.d.ts +5 -5
- package/dist/{cold-store-Z2wvK2cV.d.cts → cold-store-CkWoNtMh.d.cts} +1 -1
- package/dist/{cold-store-BDgJpwLI.d.ts → cold-store-DKMAO1Dd.d.ts} +1 -1
- package/dist/index.cjs +76 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -8
- package/dist/index.d.ts +8 -8
- package/dist/index.js +76 -10
- package/dist/index.js.map +1 -1
- package/dist/{proxy-CDh3Rsa7.d.cts → proxy-B7CWEV-T.d.cts} +1 -1
- package/dist/{proxy-Du8ggERu.d.ts → proxy-ByFHMVRX.d.ts} +1 -1
- package/dist/{thread-manager-DtHYws2F.d.ts → thread-manager-7AW4rhfu.d.ts} +2 -2
- package/dist/{thread-manager-D8zKNFZ9.d.cts → thread-manager-B9rtMEVn.d.cts} +2 -2
- package/dist/{thread-manager-BjoYYXgd.d.cts → thread-manager-Cibe0X5m.d.cts} +2 -2
- package/dist/{thread-manager-Dw96FKH1.d.ts → thread-manager-nK-WcFzM.d.ts} +2 -2
- package/dist/{types-BMJrsHo0.d.cts → types-BR-k7h0e.d.cts} +1 -1
- package/dist/{types-CtdOquo3.d.ts → types-DO4Tkwxo.d.ts} +1 -1
- package/dist/{types-qQVZfhoT.d.ts → types-DeVNWqlb.d.ts} +54 -0
- package/dist/{types-DNEl5uxQ.d.cts → types-XUUFvrJ9.d.cts} +54 -0
- package/dist/{workflow-BH9ImDGq.d.cts → workflow-KbGsxpfh.d.cts} +1 -1
- package/dist/{workflow-Cdw3-RNB.d.ts → workflow-uhOIj9D-.d.ts} +1 -1
- package/dist/workflow.cjs +76 -10
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +2 -2
- package/dist/workflow.d.ts +2 -2
- package/dist/workflow.js +76 -10
- package/dist/workflow.js.map +1 -1
- package/package.json +6 -6
- package/src/lib/lifecycle.ts +13 -1
- package/src/lib/session/session-edge-cases.integration.test.ts +44 -0
- package/src/lib/session/session.ts +26 -0
- package/src/lib/subagent/handler.ts +55 -6
- package/src/lib/subagent/subagent.integration.test.ts +239 -2
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +36 -0
- package/src/lib/tool-router/router.ts +29 -3
- package/src/lib/tool-router/types.ts +43 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
2
|
import Anthropic from '@anthropic-ai/sdk';
|
|
3
|
-
import { J as JsonValue } from './types-
|
|
4
|
-
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-
|
|
3
|
+
import { J as JsonValue } from './types-DeVNWqlb.js';
|
|
4
|
+
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-DO4Tkwxo.js';
|
|
5
5
|
|
|
6
6
|
/** SDK-native content type for Anthropic human messages */
|
|
7
7
|
type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
2
|
import Anthropic from '@anthropic-ai/sdk';
|
|
3
|
-
import { J as JsonValue } from './types-
|
|
4
|
-
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-
|
|
3
|
+
import { J as JsonValue } from './types-XUUFvrJ9.cjs';
|
|
4
|
+
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BR-k7h0e.cjs';
|
|
5
5
|
|
|
6
6
|
/** SDK-native content type for Anthropic human messages */
|
|
7
7
|
type AnthropicContent = string | Anthropic.Messages.ContentBlockParam[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
|
-
import { J as JsonValue } from './types-
|
|
2
|
+
import { J as JsonValue } from './types-XUUFvrJ9.cjs';
|
|
3
3
|
import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
|
|
4
|
-
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-
|
|
4
|
+
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-BR-k7h0e.cjs';
|
|
5
5
|
|
|
6
6
|
/** SDK-native content type for LangChain human messages */
|
|
7
7
|
type LangChainContent = string | MessageContent;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Redis from 'ioredis';
|
|
2
|
-
import { J as JsonValue } from './types-
|
|
2
|
+
import { J as JsonValue } from './types-DeVNWqlb.js';
|
|
3
3
|
import { MessageContent, StoredMessage, BaseMessage } from '@langchain/core/messages';
|
|
4
|
-
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-
|
|
4
|
+
import { T as ThreadManagerHooks, P as ProviderThreadManager } from './types-DO4Tkwxo.js';
|
|
5
5
|
|
|
6
6
|
/** SDK-native content type for LangChain human messages */
|
|
7
7
|
type LangChainContent = string | MessageContent;
|
|
@@ -134,6 +134,32 @@ interface RouterContext {
|
|
|
134
134
|
toolCallId: string;
|
|
135
135
|
toolName: string;
|
|
136
136
|
sandboxId?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Id of the assistant message that issued this tool call (the message
|
|
139
|
+
* the session passed as `assistantMessageId` into `runAgent`). Present
|
|
140
|
+
* for any tool call processed through `processToolCalls` from a
|
|
141
|
+
* session; may be absent when the router is driven manually (e.g.
|
|
142
|
+
* tests, custom orchestrators).
|
|
143
|
+
*
|
|
144
|
+
* Subagent handlers that fork the parent's thread mid-call use this
|
|
145
|
+
* to truncate the orphan trailing assistant message from the forked
|
|
146
|
+
* thread so the child's first model call sees a well-formed history.
|
|
147
|
+
*/
|
|
148
|
+
assistantMessageId?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Persist the parent session's current `PersistedThreadState` slice
|
|
151
|
+
* (tasks + custom state) to the durable thread store. Wired up by
|
|
152
|
+
* the session — absent for manually-driven routers (tests, custom
|
|
153
|
+
* orchestrators).
|
|
154
|
+
*
|
|
155
|
+
* Subagent handlers invoke this before spawning a child that will
|
|
156
|
+
* read the parent's thread (`newThreadSource: "from-parent"` or an
|
|
157
|
+
* explicit parent threadId): the parent's slice otherwise only
|
|
158
|
+
* lands in storage at session-exit time, so the child would load a
|
|
159
|
+
* stale (or empty) snapshot. Best-effort — failures are logged by
|
|
160
|
+
* the session but never thrown.
|
|
161
|
+
*/
|
|
162
|
+
persistThreadState?: () => Promise<void>;
|
|
137
163
|
}
|
|
138
164
|
/**
|
|
139
165
|
* A handler function for a specific tool.
|
|
@@ -201,6 +227,23 @@ interface ProcessToolCallsContext {
|
|
|
201
227
|
turn?: number;
|
|
202
228
|
/** Active sandbox ID (when a sandbox is configured for this session) */
|
|
203
229
|
sandboxId?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Id of the assistant message that produced these tool calls. The
|
|
232
|
+
* router forwards it into every handler's {@link RouterContext} so
|
|
233
|
+
* handlers can reference the message they were issued from (e.g.
|
|
234
|
+
* subagent forks that need to truncate the orphan assistant message
|
|
235
|
+
* out of a parent-forked thread).
|
|
236
|
+
*/
|
|
237
|
+
assistantMessageId?: string;
|
|
238
|
+
/**
|
|
239
|
+
* Optional callback that flushes the session's in-memory
|
|
240
|
+
* `PersistedThreadState` slice to the durable thread store. The
|
|
241
|
+
* router forwards it into every handler's {@link RouterContext}
|
|
242
|
+
* verbatim. The session uses this to let mid-loop tool handlers
|
|
243
|
+
* (notably subagents that fork or continue the parent's thread)
|
|
244
|
+
* persist the parent's slice before the child reads it.
|
|
245
|
+
*/
|
|
246
|
+
persistThreadState?: () => Promise<void>;
|
|
204
247
|
}
|
|
205
248
|
/**
|
|
206
249
|
* Signal that a tool handler requested a rewind. Attached to the
|
|
@@ -887,6 +930,14 @@ interface Hooks<T extends ToolMap, TResult = unknown, TContent = unknown> extend
|
|
|
887
930
|
* continue there. When the adapter has `onForkPrepareThread` and/or
|
|
888
931
|
* `onForkTransform` hooks configured, they are applied once to the forked
|
|
889
932
|
* thread before the session starts.
|
|
933
|
+
*
|
|
934
|
+
* The optional `truncateAfterFork.fromMessageId` directs the session to
|
|
935
|
+
* call `truncateThread` on the freshly forked thread immediately after
|
|
936
|
+
* the fork, dropping that message and everything after. Used by
|
|
937
|
+
* subagents that fork their parent's thread mid-tool-call to strip the
|
|
938
|
+
* orphan assistant `tool_use` block (the one whose `tool_result` will
|
|
939
|
+
* never arrive in the child's thread) so the first model call doesn't
|
|
940
|
+
* reject on an unmatched tool-use/tool-result pair.
|
|
890
941
|
*/
|
|
891
942
|
type ThreadInit = {
|
|
892
943
|
mode: "new";
|
|
@@ -897,6 +948,9 @@ type ThreadInit = {
|
|
|
897
948
|
} | {
|
|
898
949
|
mode: "fork";
|
|
899
950
|
threadId: string;
|
|
951
|
+
truncateAfterFork?: {
|
|
952
|
+
fromMessageId: string;
|
|
953
|
+
};
|
|
900
954
|
};
|
|
901
955
|
|
|
902
956
|
/**
|
|
@@ -134,6 +134,32 @@ interface RouterContext {
|
|
|
134
134
|
toolCallId: string;
|
|
135
135
|
toolName: string;
|
|
136
136
|
sandboxId?: string;
|
|
137
|
+
/**
|
|
138
|
+
* Id of the assistant message that issued this tool call (the message
|
|
139
|
+
* the session passed as `assistantMessageId` into `runAgent`). Present
|
|
140
|
+
* for any tool call processed through `processToolCalls` from a
|
|
141
|
+
* session; may be absent when the router is driven manually (e.g.
|
|
142
|
+
* tests, custom orchestrators).
|
|
143
|
+
*
|
|
144
|
+
* Subagent handlers that fork the parent's thread mid-call use this
|
|
145
|
+
* to truncate the orphan trailing assistant message from the forked
|
|
146
|
+
* thread so the child's first model call sees a well-formed history.
|
|
147
|
+
*/
|
|
148
|
+
assistantMessageId?: string;
|
|
149
|
+
/**
|
|
150
|
+
* Persist the parent session's current `PersistedThreadState` slice
|
|
151
|
+
* (tasks + custom state) to the durable thread store. Wired up by
|
|
152
|
+
* the session — absent for manually-driven routers (tests, custom
|
|
153
|
+
* orchestrators).
|
|
154
|
+
*
|
|
155
|
+
* Subagent handlers invoke this before spawning a child that will
|
|
156
|
+
* read the parent's thread (`newThreadSource: "from-parent"` or an
|
|
157
|
+
* explicit parent threadId): the parent's slice otherwise only
|
|
158
|
+
* lands in storage at session-exit time, so the child would load a
|
|
159
|
+
* stale (or empty) snapshot. Best-effort — failures are logged by
|
|
160
|
+
* the session but never thrown.
|
|
161
|
+
*/
|
|
162
|
+
persistThreadState?: () => Promise<void>;
|
|
137
163
|
}
|
|
138
164
|
/**
|
|
139
165
|
* A handler function for a specific tool.
|
|
@@ -201,6 +227,23 @@ interface ProcessToolCallsContext {
|
|
|
201
227
|
turn?: number;
|
|
202
228
|
/** Active sandbox ID (when a sandbox is configured for this session) */
|
|
203
229
|
sandboxId?: string;
|
|
230
|
+
/**
|
|
231
|
+
* Id of the assistant message that produced these tool calls. The
|
|
232
|
+
* router forwards it into every handler's {@link RouterContext} so
|
|
233
|
+
* handlers can reference the message they were issued from (e.g.
|
|
234
|
+
* subagent forks that need to truncate the orphan assistant message
|
|
235
|
+
* out of a parent-forked thread).
|
|
236
|
+
*/
|
|
237
|
+
assistantMessageId?: string;
|
|
238
|
+
/**
|
|
239
|
+
* Optional callback that flushes the session's in-memory
|
|
240
|
+
* `PersistedThreadState` slice to the durable thread store. The
|
|
241
|
+
* router forwards it into every handler's {@link RouterContext}
|
|
242
|
+
* verbatim. The session uses this to let mid-loop tool handlers
|
|
243
|
+
* (notably subagents that fork or continue the parent's thread)
|
|
244
|
+
* persist the parent's slice before the child reads it.
|
|
245
|
+
*/
|
|
246
|
+
persistThreadState?: () => Promise<void>;
|
|
204
247
|
}
|
|
205
248
|
/**
|
|
206
249
|
* Signal that a tool handler requested a rewind. Attached to the
|
|
@@ -887,6 +930,14 @@ interface Hooks<T extends ToolMap, TResult = unknown, TContent = unknown> extend
|
|
|
887
930
|
* continue there. When the adapter has `onForkPrepareThread` and/or
|
|
888
931
|
* `onForkTransform` hooks configured, they are applied once to the forked
|
|
889
932
|
* thread before the session starts.
|
|
933
|
+
*
|
|
934
|
+
* The optional `truncateAfterFork.fromMessageId` directs the session to
|
|
935
|
+
* call `truncateThread` on the freshly forked thread immediately after
|
|
936
|
+
* the fork, dropping that message and everything after. Used by
|
|
937
|
+
* subagents that fork their parent's thread mid-tool-call to strip the
|
|
938
|
+
* orphan assistant `tool_use` block (the one whose `tool_result` will
|
|
939
|
+
* never arrive in the child's thread) so the first model call doesn't
|
|
940
|
+
* reject on an unmatched tool-use/tool-result pair.
|
|
890
941
|
*/
|
|
891
942
|
type ThreadInit = {
|
|
892
943
|
mode: "new";
|
|
@@ -897,6 +948,9 @@ type ThreadInit = {
|
|
|
897
948
|
} | {
|
|
898
949
|
mode: "fork";
|
|
899
950
|
threadId: string;
|
|
951
|
+
truncateAfterFork?: {
|
|
952
|
+
fromMessageId: string;
|
|
953
|
+
};
|
|
900
954
|
};
|
|
901
955
|
|
|
902
956
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-
|
|
1
|
+
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-XUUFvrJ9.cjs';
|
|
2
2
|
import z$1, { z } from 'zod';
|
|
3
3
|
import './types-CJ7tCdl6.cjs';
|
|
4
4
|
import { Duration } from '@temporalio/common';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-
|
|
1
|
+
import { au as ToolMap, _ as SandboxInit, ah as SubagentSandboxShutdown, a1 as SessionConfig, aF as ZeitlichSession, $ as SandboxShutdown, am as ThreadInit, u as JsonSerializable, B as BaseAgentState, p as AgentStateManager, aH as ToolRouterOptions, ax as ToolRouter, R as RouterContext, J as JsonValue, az as ToolWithHandler, w as ParsedToolCallUnion, av as ToolNames, ac as SubagentDefinition, af as SubagentHooks, ag as SubagentSandboxConfig, aa as SubagentConfig, ai as SubagentSessionInput, ad as SubagentFnResult, a7 as SessionStartHook, a2 as SessionEndHook, E as PostToolUseHook, z as PostToolUseFailureHook, a4 as SessionExitReason, an as TokenUsage, f as RunAgentConfig, A as AgentResponse, F as FileEntryMetadata, aB as VirtualFileTree, k as TreeMutation, s as FileEntry, aC as VirtualFsOps, h as SkillMetadata, i as Skill, c as ToolHandlerResponse, as as ToolHandler, aE as WorkflowTask, d as ActivityToolHandler } from './types-DeVNWqlb.js';
|
|
2
2
|
import z$1, { z } from 'zod';
|
|
3
3
|
import './types-CJ7tCdl6.js';
|
|
4
4
|
import { Duration } from '@temporalio/common';
|
package/dist/workflow.cjs
CHANGED
|
@@ -123,7 +123,7 @@ function createToolRouter(options) {
|
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
async function processToolCall(toolCall, turn, sandboxId, onRewindRequested) {
|
|
126
|
+
async function processToolCall(toolCall, turn, sandboxId, onRewindRequested, assistantMessageId, persistThreadState) {
|
|
127
127
|
const startTime = Date.now();
|
|
128
128
|
const tool = toolMap.get(toolCall.name);
|
|
129
129
|
const preResult = await runPreHooks(toolCall, tool, turn);
|
|
@@ -158,7 +158,9 @@ function createToolRouter(options) {
|
|
|
158
158
|
...options.threadKey && { threadKey: options.threadKey },
|
|
159
159
|
toolCallId: toolCall.id,
|
|
160
160
|
toolName: toolCall.name,
|
|
161
|
-
...sandboxId !== void 0 && { sandboxId }
|
|
161
|
+
...sandboxId !== void 0 && { sandboxId },
|
|
162
|
+
...assistantMessageId !== void 0 && { assistantMessageId },
|
|
163
|
+
...persistThreadState !== void 0 && { persistThreadState }
|
|
162
164
|
};
|
|
163
165
|
const response = await tool.handler(
|
|
164
166
|
effectiveArgs,
|
|
@@ -285,6 +287,8 @@ function createToolRouter(options) {
|
|
|
285
287
|
}
|
|
286
288
|
const turn = context?.turn ?? 0;
|
|
287
289
|
const sandboxId = context?.sandboxId;
|
|
290
|
+
const assistantMessageId = context?.assistantMessageId;
|
|
291
|
+
const persistThreadState = context?.persistThreadState;
|
|
288
292
|
let rewindSignal;
|
|
289
293
|
if (options.parallel) {
|
|
290
294
|
const scope = new workflow.CancellationScope({ cancellable: true });
|
|
@@ -297,7 +301,14 @@ function createToolRouter(options) {
|
|
|
297
301
|
const outcomes = await scope.run(
|
|
298
302
|
async () => Promise.allSettled(
|
|
299
303
|
toolCalls.map(
|
|
300
|
-
(tc) => processToolCall(
|
|
304
|
+
(tc) => processToolCall(
|
|
305
|
+
tc,
|
|
306
|
+
turn,
|
|
307
|
+
sandboxId,
|
|
308
|
+
onRewindRequested,
|
|
309
|
+
assistantMessageId,
|
|
310
|
+
persistThreadState
|
|
311
|
+
)
|
|
301
312
|
)
|
|
302
313
|
)
|
|
303
314
|
);
|
|
@@ -317,7 +328,14 @@ function createToolRouter(options) {
|
|
|
317
328
|
}
|
|
318
329
|
const results = [];
|
|
319
330
|
for (const toolCall of toolCalls) {
|
|
320
|
-
const outcome = await processToolCall(
|
|
331
|
+
const outcome = await processToolCall(
|
|
332
|
+
toolCall,
|
|
333
|
+
turn,
|
|
334
|
+
sandboxId,
|
|
335
|
+
void 0,
|
|
336
|
+
assistantMessageId,
|
|
337
|
+
persistThreadState
|
|
338
|
+
);
|
|
321
339
|
if (outcome.kind === "rewind") {
|
|
322
340
|
rewindSignal = outcome.signal;
|
|
323
341
|
break;
|
|
@@ -341,6 +359,12 @@ function createToolRouter(options) {
|
|
|
341
359
|
toolName: toolCall.name,
|
|
342
360
|
...context?.sandboxId !== void 0 && {
|
|
343
361
|
sandboxId: context.sandboxId
|
|
362
|
+
},
|
|
363
|
+
...context?.assistantMessageId !== void 0 && {
|
|
364
|
+
assistantMessageId: context.assistantMessageId
|
|
365
|
+
},
|
|
366
|
+
...context?.persistThreadState !== void 0 && {
|
|
367
|
+
persistThreadState: context.persistThreadState
|
|
344
368
|
}
|
|
345
369
|
};
|
|
346
370
|
const response = await handler(
|
|
@@ -567,13 +591,26 @@ function createSubagentHandler(subagents) {
|
|
|
567
591
|
const threadMode = config.thread ?? "new";
|
|
568
592
|
const allowsContinuation = threadMode !== "new";
|
|
569
593
|
const newThreadSource = config.newThreadSource ?? "new";
|
|
570
|
-
const
|
|
594
|
+
const usingParentFallback = allowsContinuation && !args.threadId && newThreadSource === "from-parent";
|
|
595
|
+
const continuationThreadId = !allowsContinuation ? void 0 : args.threadId ?? (usingParentFallback ? context.threadId : void 0);
|
|
571
596
|
let thread;
|
|
572
597
|
if (continuationThreadId) {
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
598
|
+
if (threadMode === "fork") {
|
|
599
|
+
thread = {
|
|
600
|
+
mode: "fork",
|
|
601
|
+
threadId: continuationThreadId,
|
|
602
|
+
...usingParentFallback && context.assistantMessageId ? {
|
|
603
|
+
truncateAfterFork: {
|
|
604
|
+
fromMessageId: context.assistantMessageId
|
|
605
|
+
}
|
|
606
|
+
} : {}
|
|
607
|
+
};
|
|
608
|
+
} else {
|
|
609
|
+
thread = {
|
|
610
|
+
mode: "continue",
|
|
611
|
+
threadId: continuationThreadId
|
|
612
|
+
};
|
|
613
|
+
}
|
|
577
614
|
}
|
|
578
615
|
let sandbox;
|
|
579
616
|
let sandboxShutdownOverride;
|
|
@@ -685,6 +722,17 @@ function createSubagentHandler(subagents) {
|
|
|
685
722
|
if (isSnapshotBaseCreator) {
|
|
686
723
|
snapshotBaseCreatorAgent.set(childWorkflowId, config.agentName);
|
|
687
724
|
}
|
|
725
|
+
if (continuationThreadId && continuationThreadId === context.threadId && context.persistThreadState) {
|
|
726
|
+
try {
|
|
727
|
+
await context.persistThreadState();
|
|
728
|
+
} catch (err) {
|
|
729
|
+
workflow.log.warn("failed to persist parent thread state for subagent", {
|
|
730
|
+
subagent: config.agentName,
|
|
731
|
+
childWorkflowId,
|
|
732
|
+
error: err instanceof Error ? err.message : String(err)
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
}
|
|
688
736
|
workflow.log.info("subagent spawned", {
|
|
689
737
|
subagent: config.agentName,
|
|
690
738
|
childWorkflowId,
|
|
@@ -1034,6 +1082,7 @@ async function createSession(config) {
|
|
|
1034
1082
|
appendSystemMessage,
|
|
1035
1083
|
appendAgentMessage,
|
|
1036
1084
|
forkThread,
|
|
1085
|
+
truncateThread,
|
|
1037
1086
|
loadThreadState,
|
|
1038
1087
|
saveThreadState,
|
|
1039
1088
|
hydrateThread,
|
|
@@ -1183,6 +1232,10 @@ async function createSession(config) {
|
|
|
1183
1232
|
if (threadMode === "fork" && sourceThreadId) {
|
|
1184
1233
|
await hydrateThread(sourceThreadId, threadKey);
|
|
1185
1234
|
await forkThread(sourceThreadId, threadId, threadKey);
|
|
1235
|
+
const truncate = threadInit.truncateAfterFork;
|
|
1236
|
+
if (truncate?.fromMessageId) {
|
|
1237
|
+
await truncateThread(threadId, truncate.fromMessageId, threadKey);
|
|
1238
|
+
}
|
|
1186
1239
|
const forkedSlice = await loadThreadState(threadId, threadKey);
|
|
1187
1240
|
if (forkedSlice) rehydrateFromSlice(forkedSlice);
|
|
1188
1241
|
} else if (threadMode === "continue") {
|
|
@@ -1312,7 +1365,20 @@ async function createSession(config) {
|
|
|
1312
1365
|
parsedToolCalls,
|
|
1313
1366
|
{
|
|
1314
1367
|
turn: currentTurn,
|
|
1315
|
-
...sandboxId !== void 0 && { sandboxId }
|
|
1368
|
+
...sandboxId !== void 0 && { sandboxId },
|
|
1369
|
+
...assistantId !== void 0 && {
|
|
1370
|
+
assistantMessageId: assistantId
|
|
1371
|
+
},
|
|
1372
|
+
// Hand handlers a way to persist the parent's slice
|
|
1373
|
+
// mid-loop (subagents that fork or continue the parent's
|
|
1374
|
+
// thread need this — otherwise the child loads a stale
|
|
1375
|
+
// snapshot from the prior session, since `saveThreadState`
|
|
1376
|
+
// would otherwise only run in the `finally` below).
|
|
1377
|
+
persistThreadState: () => saveThreadState(
|
|
1378
|
+
threadId,
|
|
1379
|
+
stateManager.getPersistedSlice(),
|
|
1380
|
+
threadKey
|
|
1381
|
+
)
|
|
1316
1382
|
}
|
|
1317
1383
|
);
|
|
1318
1384
|
for (const result of toolCallResults) {
|