@agent-native/core 0.210.1-nightly-20261020124228 → 0.210.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/a2a/server.js +2 -1
- package/dist/agent/contain-principal.js +2 -3
- package/dist/agent/engine/ai-sdk-engine.js +29 -20
- package/dist/agent/engine/anthropic-engine.js +10 -1
- package/dist/agent/engine/builder-engine.js +28 -14
- package/dist/agent/engine/types.d.ts +11 -0
- package/dist/agent/engine/types.js +8 -0
- package/dist/agent/execution-fence.d.ts +5 -0
- package/dist/agent/execution-fence.js +15 -0
- package/dist/agent/harness/background.js +28 -7
- package/dist/agent/production-agent.d.ts +4 -3
- package/dist/agent/production-agent.js +20 -3
- package/dist/agent/run-manager.d.ts +8 -1
- package/dist/agent/run-manager.js +273 -34
- package/dist/agent/run-store.d.ts +3 -2
- package/dist/agent/run-store.fencing.worker.js +19 -1
- package/dist/agent/run-store.js +216 -67
- package/dist/client/use-agent-engine-configured.d.ts +2 -2
- package/dist/client/use-agent-engine-configured.js +3 -9
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts +7 -7
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +5 -5
- package/dist/progress/routes.d.ts +1 -1
- package/dist/secrets/routes.d.ts +4 -4
- package/dist/server/agent-chat-plugin.js +27 -11
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/agent-engine-default-model-route.d.ts +1 -1
- package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
- package/dist/server/agent-teams.d.ts +3 -0
- package/dist/server/agent-teams.js +192 -30
- package/package.json +4 -4
package/dist/a2a/server.js
CHANGED
|
@@ -8,6 +8,7 @@ import { redactArgsToJson } from "../audit/redact.js";
|
|
|
8
8
|
import { extractBearerToken, verifyInternalToken, } from "../integrations/internal-token.js";
|
|
9
9
|
import { parseServiceIdentityEmail } from "../org/service-identity.js";
|
|
10
10
|
import { assertServicePrincipalMayRun, recordServicePrincipalDenial, ServicePrincipalRefusedError, } from "../org/service-principal-guard.js";
|
|
11
|
+
import { getConfiguredAppBasePath } from "../server/app-base-path.js";
|
|
11
12
|
import { readDeployCredentialEnv } from "../server/credential-provider.js";
|
|
12
13
|
import { getH3App } from "../server/framework-request-handler.js";
|
|
13
14
|
import { publicFrameworkPath } from "../server/framework-route-prefix.js";
|
|
@@ -107,7 +108,7 @@ function expectedJwtAudience(event, options) {
|
|
|
107
108
|
process.env.URL ||
|
|
108
109
|
process.env.DEPLOY_URL ||
|
|
109
110
|
process.env.BETTER_AUTH_URL;
|
|
110
|
-
const receiverBasePath =
|
|
111
|
+
const receiverBasePath = getConfiguredAppBasePath() || undefined;
|
|
111
112
|
if (fromEnv) {
|
|
112
113
|
return audienceForRoute(canonicalA2AAudience(String(fromEnv), receiverBasePath), options);
|
|
113
114
|
}
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* before the suspend keeps spending its tool budget until it ends. Containment
|
|
6
6
|
* aborts those runs so "suspended" means stopped, not "stops eventually".
|
|
7
7
|
*
|
|
8
|
-
* A run's owner is its chat thread's `owner_email`.
|
|
9
|
-
*
|
|
10
|
-
* only a confirmed `aborted` status counts as aborted.
|
|
8
|
+
* A run's owner is its chat thread's `owner_email`. A run counts as contained
|
|
9
|
+
* only after its durable status is confirmed as `aborted`.
|
|
11
10
|
*/
|
|
12
11
|
import { ensureChatThreadTables } from "../chat-threads/store.js";
|
|
13
12
|
import { getDbExec } from "../db/client.js";
|
|
@@ -13,6 +13,7 @@ import { clampThinkingBudgetTokens, resolveMaxOutputTokensForEngine, } from "./o
|
|
|
13
13
|
import { createProviderToolNameMap } from "./tool-name.js";
|
|
14
14
|
import { engineToolsToAISDK, engineMessagesToAISDK, aiSdkPartToEngineEvents, aiSdkStepToAssistantContent, } from "./translate-ai-sdk.js";
|
|
15
15
|
import { createStreamedToolInputState, finalizeStreamedToolInputs, observeStreamedToolInput, } from "./translate-anthropic.js";
|
|
16
|
+
import { startModelDispatch } from "./types.js";
|
|
16
17
|
const PROVIDER_CAPABILITIES = {
|
|
17
18
|
anthropic: {
|
|
18
19
|
thinking: true,
|
|
@@ -385,27 +386,35 @@ class AISDKEngine {
|
|
|
385
386
|
let assistantContent = [];
|
|
386
387
|
const firstEventAbort = createFirstEventAbortController(opts.abortSignal);
|
|
387
388
|
const toolInputs = createStreamedToolInputState();
|
|
389
|
+
const dispatch = await startModelDispatch(opts, () => streamText({
|
|
390
|
+
model: providerModel,
|
|
391
|
+
system: opts.systemPrompt,
|
|
392
|
+
messages,
|
|
393
|
+
tools: aiSdkTools,
|
|
394
|
+
...(this.omitMaxOutputTokens
|
|
395
|
+
? {}
|
|
396
|
+
: { maxOutputTokens: resolvedMaxOutputTokens }),
|
|
397
|
+
maxRetries: 1,
|
|
398
|
+
...(samplingAllowed && opts.temperature !== undefined
|
|
399
|
+
? { temperature: opts.temperature }
|
|
400
|
+
: {}),
|
|
401
|
+
abortSignal: firstEventAbort.signal,
|
|
402
|
+
onStepFinish: (step) => {
|
|
403
|
+
assistantContent = aiSdkStepToAssistantContent(step, toolNameMap);
|
|
404
|
+
},
|
|
405
|
+
...(Object.keys(providerOpts).length > 0
|
|
406
|
+
? { providerOptions: providerOpts }
|
|
407
|
+
: {}),
|
|
408
|
+
})).catch((error) => {
|
|
409
|
+
firstEventAbort.cleanup();
|
|
410
|
+
throw error;
|
|
411
|
+
});
|
|
412
|
+
if (!dispatch.started) {
|
|
413
|
+
firstEventAbort.cleanup();
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
const result = dispatch.value;
|
|
388
417
|
try {
|
|
389
|
-
const result = streamText({
|
|
390
|
-
model: providerModel,
|
|
391
|
-
system: opts.systemPrompt,
|
|
392
|
-
messages,
|
|
393
|
-
tools: aiSdkTools,
|
|
394
|
-
...(this.omitMaxOutputTokens
|
|
395
|
-
? {}
|
|
396
|
-
: { maxOutputTokens: resolvedMaxOutputTokens }),
|
|
397
|
-
maxRetries: 1,
|
|
398
|
-
...(samplingAllowed && opts.temperature !== undefined
|
|
399
|
-
? { temperature: opts.temperature }
|
|
400
|
-
: {}),
|
|
401
|
-
abortSignal: firstEventAbort.signal,
|
|
402
|
-
onStepFinish: (step) => {
|
|
403
|
-
assistantContent = aiSdkStepToAssistantContent(step, toolNameMap);
|
|
404
|
-
},
|
|
405
|
-
...(Object.keys(providerOpts).length > 0
|
|
406
|
-
? { providerOptions: providerOpts }
|
|
407
|
-
: {}),
|
|
408
|
-
});
|
|
409
418
|
let bufferedStop;
|
|
410
419
|
let sawFirstEvent = false;
|
|
411
420
|
let credentialFailureRecorded = false;
|
|
@@ -10,6 +10,7 @@ import { clampThinkingBudgetTokens, resolveMaxOutputTokensForEngine, } from "./o
|
|
|
10
10
|
import { splitSystemPromptForCache, stablePrefixCacheControl, } from "./prompt-cache.js";
|
|
11
11
|
import { createProviderToolNameMap } from "./tool-name.js";
|
|
12
12
|
import { engineToolsToAnthropic, engineMessagesToAnthropic, anthropicContentToEngine, anthropicChunkToEngineEvents, createAnthropicChunkStreamState, createStreamedToolInputState, finalizeStreamedToolInputs, observeStreamedToolInput, } from "./translate-anthropic.js";
|
|
13
|
+
import { startModelDispatch } from "./types.js";
|
|
13
14
|
export const ANTHROPIC_CAPABILITIES = {
|
|
14
15
|
thinking: true,
|
|
15
16
|
promptCaching: true,
|
|
@@ -126,9 +127,17 @@ class AnthropicEngine {
|
|
|
126
127
|
if (!requestParams.tools)
|
|
127
128
|
delete requestParams.tools;
|
|
128
129
|
const firstEventAbort = createFirstEventAbortController(opts.abortSignal);
|
|
129
|
-
const
|
|
130
|
+
const dispatch = await startModelDispatch(opts, () => client.messages.stream(requestParams, {
|
|
130
131
|
signal: firstEventAbort.signal,
|
|
132
|
+
})).catch((error) => {
|
|
133
|
+
firstEventAbort.cleanup();
|
|
134
|
+
throw error;
|
|
131
135
|
});
|
|
136
|
+
if (!dispatch.started) {
|
|
137
|
+
firstEventAbort.cleanup();
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const apiStream = dispatch.value;
|
|
132
141
|
const chunkState = createAnthropicChunkStreamState();
|
|
133
142
|
const toolInputs = createStreamedToolInputState();
|
|
134
143
|
try {
|
|
@@ -17,6 +17,7 @@ import { resolveMaxOutputTokensForEngine } from "./output-tokens.js";
|
|
|
17
17
|
import { splitSystemPromptForCache, stablePrefixCacheControl, } from "./prompt-cache.js";
|
|
18
18
|
import { createProviderToolNameMap, toEngineToolName, } from "./tool-name.js";
|
|
19
19
|
import { createStreamedToolInputState, engineMessagesToBuilderGatewayAnthropic, engineToolsToAnthropic, finalizeStreamedToolInputs, observeStreamedToolInput, } from "./translate-anthropic.js";
|
|
20
|
+
import { startModelDispatch } from "./types.js";
|
|
20
21
|
export const BUILDER_CAPABILITIES = {
|
|
21
22
|
thinking: true,
|
|
22
23
|
promptCaching: true,
|
|
@@ -243,22 +244,35 @@ class BuilderEngine {
|
|
|
243
244
|
const gatewayTimeoutMs = getBuilderGatewayTimeoutMs();
|
|
244
245
|
const gatewayAbort = createGatewayAbortSignal(opts.abortSignal, gatewayTimeoutMs);
|
|
245
246
|
try {
|
|
247
|
+
const dispatch = await startModelDispatch(opts, () => {
|
|
248
|
+
try {
|
|
249
|
+
return fetch(gatewayUrl.toString(), {
|
|
250
|
+
method: "POST",
|
|
251
|
+
headers: {
|
|
252
|
+
"Content-Type": "application/json",
|
|
253
|
+
Authorization: authHeader,
|
|
254
|
+
...(spaceId && !oauthAccess
|
|
255
|
+
? { "x-builder-api-key": spaceId }
|
|
256
|
+
: {}),
|
|
257
|
+
...getBuilderGatewayRequestHeaders(),
|
|
258
|
+
...(builderUserId ? { "x-builder-user-id": builderUserId } : {}),
|
|
259
|
+
},
|
|
260
|
+
body: payload,
|
|
261
|
+
signal: gatewayAbort.signal,
|
|
262
|
+
}).then((response) => ({ status: "fulfilled", response }), (error) => ({ status: "rejected", error }));
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
return Promise.resolve({ status: "rejected", error });
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
if (!dispatch.started)
|
|
269
|
+
return;
|
|
246
270
|
let response;
|
|
247
271
|
try {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
Authorization: authHeader,
|
|
253
|
-
...(spaceId && !oauthAccess
|
|
254
|
-
? { "x-builder-api-key": spaceId }
|
|
255
|
-
: {}),
|
|
256
|
-
...getBuilderGatewayRequestHeaders(),
|
|
257
|
-
...(builderUserId ? { "x-builder-user-id": builderUserId } : {}),
|
|
258
|
-
},
|
|
259
|
-
body: payload,
|
|
260
|
-
signal: gatewayAbort.signal,
|
|
261
|
-
});
|
|
272
|
+
const result = await dispatch.value;
|
|
273
|
+
if (result.status === "rejected")
|
|
274
|
+
throw result.error;
|
|
275
|
+
response = result.response;
|
|
262
276
|
}
|
|
263
277
|
catch (err) {
|
|
264
278
|
const timedOut = gatewayAbort.didTimeout();
|
|
@@ -165,6 +165,14 @@ export interface EngineCapabilities {
|
|
|
165
165
|
computerUse: boolean;
|
|
166
166
|
parallelToolCalls: boolean;
|
|
167
167
|
}
|
|
168
|
+
export type ModelDispatchDecision<T> = {
|
|
169
|
+
started: true;
|
|
170
|
+
value: T;
|
|
171
|
+
} | {
|
|
172
|
+
started: false;
|
|
173
|
+
};
|
|
174
|
+
/** Runs the synchronous request start while the caller's coordination lock is held. */
|
|
175
|
+
export type BeforeModelDispatch = <T>(dispatch: () => T) => Promise<ModelDispatchDecision<T>>;
|
|
168
176
|
export interface EngineStreamOptions {
|
|
169
177
|
model: string;
|
|
170
178
|
systemPrompt: string;
|
|
@@ -174,6 +182,8 @@ export interface EngineStreamOptions {
|
|
|
174
182
|
maxOutputTokens?: number;
|
|
175
183
|
temperature?: number;
|
|
176
184
|
reasoningEffort?: ReasoningEffort;
|
|
185
|
+
beforeModelDispatch?: BeforeModelDispatch;
|
|
186
|
+
onModelDispatchStarted?: () => void;
|
|
177
187
|
providerOptions?: {
|
|
178
188
|
anthropic?: {
|
|
179
189
|
thinking?: {
|
|
@@ -190,6 +200,7 @@ export interface EngineStreamOptions {
|
|
|
190
200
|
[provider: string]: Record<string, unknown> | undefined;
|
|
191
201
|
};
|
|
192
202
|
}
|
|
203
|
+
export declare function startModelDispatch<T>(options: Pick<EngineStreamOptions, "beforeModelDispatch" | "onModelDispatchStarted">, dispatch: () => T): Promise<ModelDispatchDecision<T>>;
|
|
193
204
|
export interface AgentEngine {
|
|
194
205
|
readonly name: string;
|
|
195
206
|
readonly label: string;
|
|
@@ -20,3 +20,11 @@ export class EngineError extends Error {
|
|
|
20
20
|
this.retryAfterMs = opts?.retryAfterMs;
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
+
export async function startModelDispatch(options, dispatch) {
|
|
24
|
+
const result = options.beforeModelDispatch
|
|
25
|
+
? await options.beforeModelDispatch(dispatch)
|
|
26
|
+
: { started: true, value: dispatch() };
|
|
27
|
+
if (result.started)
|
|
28
|
+
options.onModelDispatchStarted?.();
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
@@ -16,6 +16,11 @@ export declare class MissingExecutionFenceError extends ExecutionFenceError {
|
|
|
16
16
|
constructor();
|
|
17
17
|
}
|
|
18
18
|
export declare function currentExecutionFence(): ExecutionFence | undefined;
|
|
19
|
+
export declare function currentExecutionFenceForScope(scope: {
|
|
20
|
+
runId?: string;
|
|
21
|
+
threadId?: string;
|
|
22
|
+
turnId?: string;
|
|
23
|
+
}): ExecutionFence | undefined;
|
|
19
24
|
export declare function withExecutionLeaseRequested<T>(work: () => T): T;
|
|
20
25
|
export declare function withExecutionFence<T>(fence: ExecutionFence, work: () => T): T;
|
|
21
26
|
export declare function lockAndAssertCurrentExecutionFences(tx: DbExec): Promise<void>;
|
|
@@ -27,6 +27,21 @@ export function currentExecutionFence() {
|
|
|
27
27
|
}
|
|
28
28
|
return fence;
|
|
29
29
|
}
|
|
30
|
+
export function currentExecutionFenceForScope(scope) {
|
|
31
|
+
const context = executionFenceStorage.getStore();
|
|
32
|
+
const fence = context?.fences.find((candidate) => (!scope.runId || scope.runId === candidate.runId) &&
|
|
33
|
+
(!scope.threadId || scope.threadId === candidate.threadId) &&
|
|
34
|
+
(!scope.turnId || scope.turnId === candidate.turnId));
|
|
35
|
+
if (fence)
|
|
36
|
+
return fence;
|
|
37
|
+
if (context?.executionLeaseRequested) {
|
|
38
|
+
const activeFence = context.fences.at(-1);
|
|
39
|
+
if (!activeFence)
|
|
40
|
+
throw new MissingExecutionFenceError();
|
|
41
|
+
throw new StaleExecutionFenceError(activeFence);
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
30
45
|
export function withExecutionLeaseRequested(work) {
|
|
31
46
|
const current = executionFenceStorage.getStore();
|
|
32
47
|
return executionFenceStorage.run({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { redactArgsToValue, redactTextToSummary } from "../../audit/redact.js";
|
|
2
|
-
import {
|
|
2
|
+
import { abortRunDurably } from "../run-manager.js";
|
|
3
3
|
import { getRunEventsSince } from "../run-store.js";
|
|
4
4
|
import { resolveAgentHarnessApproval, sendAgentHarnessFollowUp, stopLiveAgentHarnessSession, } from "./lifecycle.js";
|
|
5
5
|
import { getAgentHarnessSessionByRunId, listAgentHarnessSessions, markAgentHarnessSessionStopped, } from "./store.js";
|
|
@@ -63,14 +63,35 @@ export async function stopAgentHarnessBackgroundRun(runId, options = {
|
|
|
63
63
|
(options.orgId !== undefined && session.orgId !== options.orgId)) {
|
|
64
64
|
return missingHarnessRunResult(runId);
|
|
65
65
|
}
|
|
66
|
+
const failures = [];
|
|
66
67
|
if (session.runId) {
|
|
67
|
-
|
|
68
|
+
try {
|
|
69
|
+
await abortRunDurably(session.runId, "user", { allowNotStarted: true });
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
failures.push(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
await stopLiveAgentHarnessSession({
|
|
77
|
+
sessionId: session.id,
|
|
78
|
+
scope: options,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
failures.push(error);
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
await markAgentHarnessSessionStopped(session.id, failures.length > 0 ? "errored" : "stopped");
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
failures.push(error);
|
|
89
|
+
}
|
|
90
|
+
if (failures.length === 1)
|
|
91
|
+
throw failures[0];
|
|
92
|
+
if (failures.length > 1) {
|
|
93
|
+
throw new AggregateError(failures, "Agent Harness background stop failed.");
|
|
68
94
|
}
|
|
69
|
-
await stopLiveAgentHarnessSession({
|
|
70
|
-
sessionId: session.id,
|
|
71
|
-
scope: options,
|
|
72
|
-
});
|
|
73
|
-
await markAgentHarnessSessionStopped(session.id, "stopped");
|
|
74
95
|
return {
|
|
75
96
|
ok: true,
|
|
76
97
|
runId,
|
|
@@ -18,9 +18,9 @@ import { type ReasoningEffort } from "../shared/reasoning-effort.js";
|
|
|
18
18
|
import type { TrackingMeta } from "../tracking/registry.js";
|
|
19
19
|
import { type ResolveEngineConfig } from "./engine/index.js";
|
|
20
20
|
import { PROVIDER_TO_ENV } from "./engine/provider-env-vars.js";
|
|
21
|
-
import type { AgentEngine, EngineTool, EngineMessage, EngineContentPart, EngineImagePart } from "./engine/types.js";
|
|
21
|
+
import type { AgentEngine, EngineTool, EngineMessage, EngineContentPart, EngineImagePart, BeforeModelDispatch } from "./engine/types.js";
|
|
22
22
|
import { type Processor } from "./processors.js";
|
|
23
|
-
import { subscribeToRun, getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably } from "./run-manager.js";
|
|
23
|
+
import { subscribeToRun, getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAndTurnDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably } from "./run-manager.js";
|
|
24
24
|
import type { ActiveRun } from "./run-manager.js";
|
|
25
25
|
import { type AgentTurnInitiator, insertRun, isTurnAborted, markRunAborted, updateRunHeartbeat, updateRunStatusIfRunning, updateRunTerminalStateIfRunning, setRunError, setRunTerminalReason, claimBackgroundRun, readBackgroundRunClaim, recordRunDiagnostic, countRunsForTurn } from "./run-store.js";
|
|
26
26
|
import { type AgentActionScope, ActionTool, AgentChatAttachment, AgentChatEvent, AgentFileMutationProof, AgentChatReference, AgentChatStructuredMessage } from "./types.js";
|
|
@@ -731,6 +731,7 @@ export declare function runAgentLoop(opts: {
|
|
|
731
731
|
send: (event: AgentChatEvent) => void | Promise<void>;
|
|
732
732
|
signal: AbortSignal;
|
|
733
733
|
beforeWrite?: () => Promise<void>;
|
|
734
|
+
beforeModelDispatch?: BeforeModelDispatch;
|
|
734
735
|
unknownWriteToolNames?: Set<string>;
|
|
735
736
|
/** The request's unknown outcomes, which each of its loops feeds and holds by. */
|
|
736
737
|
unknownOutcomes?: UnknownOutcomes;
|
|
@@ -992,4 +993,4 @@ export declare function resolveAgentModelSelection(options: {
|
|
|
992
993
|
source: AgentModelSelectionSource;
|
|
993
994
|
};
|
|
994
995
|
export declare function createProductionAgentHandler(options: ProductionAgentOptions): H3EventHandler;
|
|
995
|
-
export { getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably, subscribeToRun, };
|
|
996
|
+
export { getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAndTurnDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably, subscribeToRun, };
|
|
@@ -85,7 +85,7 @@ import { getContextWindowForModel, resolveFallbackModel, } from "./model-config.
|
|
|
85
85
|
import { maybeCompactThread, buildObservationalContext, hasObservationalMemory, serializeObservationalMemoryBlock, } from "./observational-memory/index.js";
|
|
86
86
|
import { ProcessorChain, TripWire, toolCallsFromContent, } from "./processors.js";
|
|
87
87
|
import { applyUncheckedDefaultModelReplacement } from "./provider-model-selection.js";
|
|
88
|
-
import { startRun, subscribeToRun, replayCompletedTurn, getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably, getSlotHoldingRunId, tryClaimRunSlot, isHostedRuntime, resolveRunSoftTimeoutMs, resolveRunToolTimeoutCeilingMs, endsAfterToolResultWithoutAssistantFinal, endsDuringActionPreparation, } from "./run-manager.js";
|
|
88
|
+
import { startRun, subscribeToRun, replayCompletedTurn, getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAndTurnDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably, getSlotHoldingRunId, tryClaimRunSlot, isHostedRuntime, resolveRunSoftTimeoutMs, resolveRunToolTimeoutCeilingMs, endsAfterToolResultWithoutAssistantFinal, endsDuringActionPreparation, } from "./run-manager.js";
|
|
89
89
|
import { writeLedgerEntry, readLedgerEntry, beginAgentExecutionStep, completeAgentExecutionStep, markAgentExecutionStepDispatched, markAgentExecutionStepUnknown, recordLateAgentExecutionStepOutcome, clearLedgerForThread, AgentTurnInitiatorMismatchError, AgentTurnInitiatorUnavailableError, insertRun, insertRunEvent, isTurnAborted, markRunAborted, updateRunHeartbeat, updateRunStatusIfRunning, updateRunTerminalStateIfRunning, setRunError, setRunTerminalReason, claimBackgroundRun, readBackgroundRunClaim, recordRunDiagnostic, countRunsForTurn, RUN_DIAG_STAGE, UNCLAIMED_BACKGROUND_RUN_GRACE_MS, turnRunLedgerExhausted, } from "./run-store.js";
|
|
90
90
|
import { buildCurrentTimeUserContext } from "./runtime-context.js";
|
|
91
91
|
import { claimSetupResume, setupResumeRefusedRunId, } from "./setup-resume-claim.js";
|
|
@@ -5002,11 +5002,21 @@ export async function runAgentLoop(opts) {
|
|
|
5002
5002
|
reasoningEffort: completingFollowUpSuggestions
|
|
5003
5003
|
? "none"
|
|
5004
5004
|
: effectiveReasoningEffort,
|
|
5005
|
+
beforeModelDispatch: opts.beforeModelDispatch,
|
|
5006
|
+
onModelDispatchStarted: () => {
|
|
5007
|
+
usage.llmCalls = (usage.llmCalls ?? 0) + 1;
|
|
5008
|
+
},
|
|
5005
5009
|
providerOptions,
|
|
5006
5010
|
};
|
|
5007
5011
|
opts.onModelSettings?.(model, effectiveReasoningEffort);
|
|
5008
|
-
usage.llmCalls = (usage.llmCalls ?? 0) + 1;
|
|
5009
5012
|
notifyModelInputObserver(opts.onModelInput, engineMessages);
|
|
5013
|
+
if (signal.aborted) {
|
|
5014
|
+
reportOutcome({
|
|
5015
|
+
state: "canceled",
|
|
5016
|
+
message: "Agent run was aborted.",
|
|
5017
|
+
});
|
|
5018
|
+
return usage;
|
|
5019
|
+
}
|
|
5010
5020
|
const eventStream = engine.stream(streamOpts);
|
|
5011
5021
|
let thinkingBuffer = "";
|
|
5012
5022
|
const toolInputNames = new Map();
|
|
@@ -5303,6 +5313,13 @@ export async function runAgentLoop(opts) {
|
|
|
5303
5313
|
await requestEventIteratorReturn(eventIterator, !eventIteratorReturnRequested);
|
|
5304
5314
|
}
|
|
5305
5315
|
}
|
|
5316
|
+
if (signal.aborted) {
|
|
5317
|
+
reportOutcome({
|
|
5318
|
+
state: "canceled",
|
|
5319
|
+
message: "Agent run was aborted.",
|
|
5320
|
+
});
|
|
5321
|
+
return usage;
|
|
5322
|
+
}
|
|
5306
5323
|
if (endedForNoProgress) {
|
|
5307
5324
|
if (completingFollowUpSuggestions)
|
|
5308
5325
|
break;
|
|
@@ -11220,4 +11237,4 @@ export function createProductionAgentHandler(options) {
|
|
|
11220
11237
|
return stream;
|
|
11221
11238
|
});
|
|
11222
11239
|
}
|
|
11223
|
-
export { getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably, subscribeToRun, };
|
|
11240
|
+
export { getActiveRunForThread, getActiveRunForThreadAsync, getRun, abortRun, abortRunDurably, abortRunAndTurnDurably, abortRunAtSafeBoundaryDurably, abortTurnByRefDurably, abortTurnDurably, subscribeToRun, };
|
|
@@ -14,6 +14,7 @@ export interface ActiveRun {
|
|
|
14
14
|
nextEventSeq?: number;
|
|
15
15
|
pendingAbortEvent?: RunEvent;
|
|
16
16
|
flushEvents?: () => Promise<void>;
|
|
17
|
+
waitForPersistence?: () => Promise<void>;
|
|
17
18
|
abortReason?: string;
|
|
18
19
|
continuationTerminalEvent?: Extract<AgentChatEvent, {
|
|
19
20
|
type: "auto_continue";
|
|
@@ -159,9 +160,15 @@ export declare function abortRun(runId: string, reason?: string): boolean;
|
|
|
159
160
|
* must use this path; otherwise the recovery POST can race the old row while
|
|
160
161
|
* it is still marked running.
|
|
161
162
|
*/
|
|
162
|
-
export declare function abortRunDurably(runId: string, reason?: string
|
|
163
|
+
export declare function abortRunDurably(runId: string, reason?: string, options?: {
|
|
164
|
+
allowNotStarted?: boolean;
|
|
165
|
+
}): Promise<boolean>;
|
|
163
166
|
/** Abort after the durable run store confirms no model or tool work is in flight. */
|
|
164
167
|
export declare function abortRunAtSafeBoundaryDurably(runId: string, reason?: string): Promise<boolean>;
|
|
165
168
|
export declare function abortTurnByRefDurably(threadId: string, turnId: string, reason?: string): Promise<"aborted" | "already_terminal">;
|
|
166
169
|
export declare function abortTurnDurably(runId: string, reason?: string): Promise<"aborted" | "already_terminal">;
|
|
170
|
+
/** Persist a Stop's turn marker even when a terminal event flush must be reported. */
|
|
171
|
+
export declare function abortRunAndTurnDurably(runId: string, reason?: string, options?: {
|
|
172
|
+
safeBoundary?: boolean;
|
|
173
|
+
}): Promise<boolean>;
|
|
167
174
|
export { getSlotHoldingRunId, tryClaimRunSlot } from "./run-store.js";
|