UNPKG

@tanstack/ai

Version:

Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.

54 lines (53 loc) 2.32 kB
//#region src/activities/chat/cancel.ts /** * Abort reason that marks an abort as an explicit cancellation. * * Namespaced so an application's own reason string cannot collide with it by * accident, and matched with `===` (never a substring test) so an arbitrary * provider error message can never be read as a deliberate cancel. */ var RUN_CANCEL_REASON = "tanstack-ai:cancel-requested"; /** Whether an abort reason means "the user explicitly cancelled this run". */ function isCancelRequestedReason(reason) { return reason === RUN_CANCEL_REASON; } /** * Record an explicit cancel on the run record. * * Deliberately does NOT set a status. The driver is the only actor that knows * when the agent has actually stopped and the sandbox has been torn down, so it * owns the transition to `'aborted'`. Writing a terminal status here would tell * every reader the run is over while the agent is still burning tokens. * * A no-op for an unknown `runId`, inheriting `RunStore.update`'s documented * invariant. */ async function requestRunCancel(runs, runId) { await runs.update(runId, { cancelRequested: true }); } /** * Whether an explicit cancel has been recorded for `runId`. * * Answers `false` rather than throwing when the store cannot be read. Callers * are middleware abort hooks, which are already on a teardown path, and a * store failure there must not replace the caller's own reason for tearing * down with a store error. The cost of a false negative is that a cancel * degrades into a detach — the run record gains `detachedSince`/`sandboxKey` * instead of transitioning to `'aborted'`. `@tanstack/ai-sandbox`'s * `reapDetachedRuns` recovers that run once the `detachedRunTtlMs` the * application passes to that sweep has elapsed — nothing derives it from * `withSandbox`, which has no TTL option — so the cost is a delayed teardown * rather than a lost one, provided the application actually schedules the * sweep, which is its job and not the framework's. Still strictly better than * failing the teardown. */ async function wasCancelRequested(runs, runId) { try { return (await runs.get(runId))?.cancelRequested === true; } catch { return false; } } //#endregion export { RUN_CANCEL_REASON, isCancelRequestedReason, requestRunCancel, wasCancelRequested }; //# sourceMappingURL=cancel.js.map