@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.
Files changed (34) hide show
  1. package/dist/a2a/server.js +2 -1
  2. package/dist/agent/contain-principal.js +2 -3
  3. package/dist/agent/engine/ai-sdk-engine.js +29 -20
  4. package/dist/agent/engine/anthropic-engine.js +10 -1
  5. package/dist/agent/engine/builder-engine.js +28 -14
  6. package/dist/agent/engine/types.d.ts +11 -0
  7. package/dist/agent/engine/types.js +8 -0
  8. package/dist/agent/execution-fence.d.ts +5 -0
  9. package/dist/agent/execution-fence.js +15 -0
  10. package/dist/agent/harness/background.js +28 -7
  11. package/dist/agent/production-agent.d.ts +4 -3
  12. package/dist/agent/production-agent.js +20 -3
  13. package/dist/agent/run-manager.d.ts +8 -1
  14. package/dist/agent/run-manager.js +273 -34
  15. package/dist/agent/run-store.d.ts +3 -2
  16. package/dist/agent/run-store.fencing.worker.js +19 -1
  17. package/dist/agent/run-store.js +216 -67
  18. package/dist/client/use-agent-engine-configured.d.ts +2 -2
  19. package/dist/client/use-agent-engine-configured.js +3 -9
  20. package/dist/collab/awareness.d.ts +2 -2
  21. package/dist/collab/routes.d.ts +1 -1
  22. package/dist/collab/struct-routes.d.ts +1 -1
  23. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  24. package/dist/notifications/routes.d.ts +1 -1
  25. package/dist/observability/routes.d.ts +5 -5
  26. package/dist/progress/routes.d.ts +1 -1
  27. package/dist/secrets/routes.d.ts +4 -4
  28. package/dist/server/agent-chat-plugin.js +27 -11
  29. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  30. package/dist/server/agent-engine-default-model-route.d.ts +1 -1
  31. package/dist/server/agent-engine-ollama-models-route.d.ts +2 -2
  32. package/dist/server/agent-teams.d.ts +3 -0
  33. package/dist/server/agent-teams.js +192 -30
  34. package/package.json +4 -4
@@ -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 = process.env.APP_BASE_PATH;
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`. `abortRunDurably` logs and
9
- * swallows a failed SQL write, so the outcome is re-read from `agent_runs`:
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 apiStream = client.messages.stream(requestParams, {
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
- response = await fetch(gatewayUrl.toString(), {
249
- method: "POST",
250
- headers: {
251
- "Content-Type": "application/json",
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 { abortRun } from "../run-manager.js";
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
- abortRun(session.runId, "user");
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): Promise<boolean>;
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";