agents 0.13.3 → 0.14.1
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 +6 -4
- package/dist/{agent-tool-types-l98LCbBl.d.ts → agent-tool-types-BAJWu8s4.d.ts} +474 -117
- package/dist/agent-tool-types.d.ts +13 -11
- package/dist/{agent-tools-Bg5ilERh.d.ts → agent-tools-0R6KEert.d.ts} +2 -2
- package/dist/{agent-tools-BAdX1vdI.js → agent-tools-DYrkT-Kx.js} +46 -6
- package/dist/agent-tools-DYrkT-Kx.js.map +1 -0
- package/dist/agent-tools.d.ts +14 -20
- package/dist/agent-tools.js +10 -6
- package/dist/agent-tools.js.map +1 -1
- package/dist/browser/ai.d.ts +1 -1
- package/dist/browser/ai.js +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/tanstack-ai.d.ts +1 -1
- package/dist/browser/tanstack-ai.js +1 -1
- package/dist/chat/index.d.ts +162 -19
- package/dist/chat/index.js +97 -13
- package/dist/chat/index.js.map +1 -1
- package/dist/chat-sdk/index.d.ts +5 -5
- package/dist/chat-sdk/index.js +2 -2
- package/dist/chat-sdk/index.js.map +1 -1
- package/dist/{classPrivateFieldGet2-Evpt0SEr.js → classPrivateFieldGet2-D_obpP6O.js} +5 -5
- package/dist/classPrivateMethodInitSpec-10iTYB7F.js +7 -0
- package/dist/{client-D1kFXo80.js → client-FUizKzj2.js} +299 -95
- package/dist/client-FUizKzj2.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/{compaction-helpers-B-pG5J22.d.ts → compaction-helpers-BEUILPss.d.ts} +59 -33
- package/dist/{compaction-helpers-fJyf8j4m.js → compaction-helpers-iiKMr2TQ.js} +22 -3
- package/dist/compaction-helpers-iiKMr2TQ.js.map +1 -0
- package/dist/{do-oauth-client-provider-4OKQU9rT.d.ts → do-oauth-client-provider-D4ZwyBDu.d.ts} +21 -1
- package/dist/{email-J0GGS3sa.d.ts → email-CL27preh.d.ts} +1 -1
- package/dist/email.d.ts +2 -2
- package/dist/experimental/memory/session/index.d.ts +30 -25
- package/dist/experimental/memory/session/index.js +7 -2
- package/dist/experimental/memory/session/index.js.map +1 -1
- package/dist/experimental/memory/utils/index.d.ts +12 -10
- package/dist/experimental/memory/utils/index.js +2 -2
- package/dist/{index-DKey3P4s.d.ts → index-RJ4OxMOe.d.ts} +270 -1
- package/dist/index.d.ts +74 -67
- package/dist/index.js +485 -64
- package/dist/index.js.map +1 -1
- package/dist/{internal_context-BZrMS0B5.d.ts → internal_context-Dg4Cgjcu.d.ts} +1 -1
- package/dist/internal_context.d.ts +1 -1
- package/dist/mcp/client.d.ts +17 -13
- package/dist/mcp/client.js +2 -2
- package/dist/mcp/do-oauth-client-provider.d.ts +1 -1
- package/dist/mcp/do-oauth-client-provider.js +143 -17
- package/dist/mcp/do-oauth-client-provider.js.map +1 -1
- package/dist/mcp/index.d.ts +35 -27
- package/dist/mcp/index.js +402 -69
- package/dist/mcp/index.js.map +1 -1
- package/dist/observability/index.d.ts +1 -1
- package/dist/observability/index.js +15 -1
- package/dist/observability/index.js.map +1 -1
- package/dist/react.d.ts +3 -3
- package/dist/react.js +1 -1
- package/dist/{retries-BVdRl5ZE.d.ts → retries-CF_HKSlJ.d.ts} +1 -1
- package/dist/retries.d.ts +1 -1
- package/dist/serializable.d.ts +1 -1
- package/dist/{shared-Cvj92byG.d.ts → shared-4CAYLCTO.d.ts} +1 -1
- package/dist/{shared-CiKaIK4h.js → shared-BIpUk4G5.js} +3 -7
- package/dist/{shared-CiKaIK4h.js.map → shared-BIpUk4G5.js.map} +1 -1
- package/dist/skills/index.d.ts +236 -0
- package/dist/skills/index.js +1326 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/sub-routing.d.ts +6 -6
- package/dist/{tool-output-truncation-CH-khbZ3.js → tool-output-truncation-CNnnGZQ3.js} +1 -1
- package/dist/{tool-output-truncation-CH-khbZ3.js.map → tool-output-truncation-CNnnGZQ3.js.map} +1 -1
- package/dist/{types-_JjKmv-l.d.ts → types-6Zo2zfoO.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/vite.d.ts +1 -1
- package/dist/vite.js +248 -2
- package/dist/vite.js.map +1 -1
- package/dist/{workflow-types-Dkzg4hAx.d.ts → workflow-types-SrZK_o9p.d.ts} +1 -1
- package/dist/workflow-types.d.ts +1 -1
- package/dist/workflows.d.ts +13 -3
- package/dist/workflows.js +10 -1
- package/dist/workflows.js.map +1 -1
- package/package.json +31 -13
- package/skills-module.d.ts +22 -0
- package/dist/agent-tools-BAdX1vdI.js.map +0 -1
- package/dist/client-D1kFXo80.js.map +0 -1
- package/dist/compaction-helpers-fJyf8j4m.js.map +0 -1
package/dist/chat/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
a as AgentToolEventState,
|
|
3
3
|
i as AgentToolEventMessage,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from "../agent-tool-types-
|
|
4
|
+
r as AgentToolEvent,
|
|
5
|
+
u as AgentToolRunState
|
|
6
|
+
} from "../agent-tool-types-BAJWu8s4.js";
|
|
7
7
|
import {
|
|
8
8
|
n as createAgentToolEventState,
|
|
9
9
|
t as applyAgentToolEvent
|
|
10
|
-
} from "../agent-tools-
|
|
10
|
+
} from "../agent-tools-0R6KEert.js";
|
|
11
11
|
import { JSONSchema7, Tool, ToolSet, UIMessage } from "ai";
|
|
12
12
|
import { Connection } from "agents";
|
|
13
13
|
|
|
@@ -51,6 +51,29 @@ type StreamChunkData = {
|
|
|
51
51
|
messageMetadata?: unknown;
|
|
52
52
|
[key: string]: unknown;
|
|
53
53
|
};
|
|
54
|
+
/**
|
|
55
|
+
* Coerce a tool part's `input` into a provider-acceptable object.
|
|
56
|
+
*
|
|
57
|
+
* The Anthropic Messages API requires `tool_use.input` to be a JSON **object** —
|
|
58
|
+
* `null`, `undefined`, `""`, a raw string, **or an array** are all rejected with
|
|
59
|
+
* `tool_use.input: Input should be an object` (verified empirically against the
|
|
60
|
+
* live API: `{}` → 200, but `""`, `[]`, and `[{...}]` all → 400). A streamed
|
|
61
|
+
* tool call that finishes with no `input_json_delta` events (the model called
|
|
62
|
+
* the tool with no args), or whose input surfaces as a stringified JSON blob,
|
|
63
|
+
* can persist one of these shapes — and because it lives in durable storage, the
|
|
64
|
+
* session is then wedged across reconnects, redeploys, and DO evictions.
|
|
65
|
+
* Enforcing the invariant at the write boundary (and as a read-side repair
|
|
66
|
+
* backstop) keeps the transcript valid.
|
|
67
|
+
*
|
|
68
|
+
* - A plain (non-array) object is returned untouched (`changed: false`).
|
|
69
|
+
* - A string that parses to a plain object is parsed.
|
|
70
|
+
* - Everything else (`null`, `undefined`, `""`, arrays, primitives, non-object
|
|
71
|
+
* or unparseable JSON) collapses to `{}`.
|
|
72
|
+
*/
|
|
73
|
+
declare function normalizeToolInput(raw: unknown): {
|
|
74
|
+
input: unknown;
|
|
75
|
+
changed: boolean;
|
|
76
|
+
};
|
|
54
77
|
/**
|
|
55
78
|
* Applies a stream chunk to a mutable parts array, building up the message
|
|
56
79
|
* incrementally. Returns true if the chunk was handled, false if it was
|
|
@@ -334,7 +357,21 @@ type SaveMessagesResult = {
|
|
|
334
357
|
* stream is detected after DO restart.
|
|
335
358
|
*/
|
|
336
359
|
type ChatRecoveryContext = {
|
|
337
|
-
/**
|
|
360
|
+
/** Stable identifier for this recovery incident. */ incidentId: string;
|
|
361
|
+
/**
|
|
362
|
+
* Stable request ID for the whole continuation chain (the recovery "root").
|
|
363
|
+
* Unlike `requestId` — which changes on every chained continuation — this is
|
|
364
|
+
* constant for the lifetime of the incident, so it's the right key for
|
|
365
|
+
* per-incident budget tracking or fresh-incident detection without
|
|
366
|
+
* re-deriving identity from message IDs.
|
|
367
|
+
*/
|
|
368
|
+
recoveryRootRequestId: string /** Attempt number for this recovery incident, starting at 1. */;
|
|
369
|
+
attempt: number /** Maximum attempts before the framework terminalizes recovery. */;
|
|
370
|
+
maxAttempts: number /** Whether this recovery is retrying an unanswered user turn or continuing a partial assistant turn. */;
|
|
371
|
+
recoveryKind:
|
|
372
|
+
| "retry"
|
|
373
|
+
| "continue" /** Stream ID from the interrupted stream. */;
|
|
374
|
+
streamId: string /** Request ID from the interrupted stream. */;
|
|
338
375
|
requestId: string /** Partial text extracted from stored chunks. */;
|
|
339
376
|
partialText: string /** Partial message parts reconstructed from chunks. */;
|
|
340
377
|
partialParts: MessagePart[] /** Checkpoint data from `this.stash()` during the interrupted stream. */;
|
|
@@ -359,6 +396,59 @@ type ChatRecoveryOptions = {
|
|
|
359
396
|
/** Save the partial response from stored chunks. Default: true. */ persist?: boolean /** Schedule a continuation via `continueLastTurn()`. Default: true. */;
|
|
360
397
|
continue?: boolean;
|
|
361
398
|
};
|
|
399
|
+
/**
|
|
400
|
+
* Context passed when framework-owned chat recovery exhausts its retry budget.
|
|
401
|
+
*
|
|
402
|
+
* Carries enough to render/persist a user-facing terminal banner without
|
|
403
|
+
* re-deriving anything: the `terminalMessage` that was shown, the
|
|
404
|
+
* `recoveryRootRequestId` (stable incident identity), and the partial the turn
|
|
405
|
+
* produced before it was given up on.
|
|
406
|
+
*/
|
|
407
|
+
type ChatRecoveryExhaustedContext = Pick<
|
|
408
|
+
ChatRecoveryContext,
|
|
409
|
+
| "incidentId"
|
|
410
|
+
| "requestId"
|
|
411
|
+
| "recoveryRootRequestId"
|
|
412
|
+
| "attempt"
|
|
413
|
+
| "maxAttempts"
|
|
414
|
+
| "recoveryKind"
|
|
415
|
+
| "streamId"
|
|
416
|
+
| "createdAt"
|
|
417
|
+
| "partialText"
|
|
418
|
+
| "partialParts"
|
|
419
|
+
> & {
|
|
420
|
+
/**
|
|
421
|
+
* Why recovery stopped. One of:
|
|
422
|
+
* - `max_attempts_exceeded` — the per-incident attempt budget was spent.
|
|
423
|
+
* - `no_progress_timeout` — no forward progress within the no-progress window.
|
|
424
|
+
* - `max_recovery_window_exceeded` — the absolute incident-age ceiling was hit.
|
|
425
|
+
* - `stable_timeout` — a recovery attempt kept timing out waiting for the
|
|
426
|
+
* isolate to reach stable state until the budget drained (extreme churn).
|
|
427
|
+
*
|
|
428
|
+
* Treat this as an open string: new reasons may be added.
|
|
429
|
+
*/
|
|
430
|
+
reason: string /** The terminal message shown to the user (from the `chatRecovery` config). */;
|
|
431
|
+
terminalMessage: string;
|
|
432
|
+
};
|
|
433
|
+
/**
|
|
434
|
+
* Configuration for durable chat recovery. `true` uses these defaults:
|
|
435
|
+
* `maxAttempts: 6`, `stableTimeoutMs: 10_000`, and a generic terminal message.
|
|
436
|
+
*/
|
|
437
|
+
type ChatRecoveryConfig =
|
|
438
|
+
| boolean
|
|
439
|
+
| {
|
|
440
|
+
maxAttempts?: number;
|
|
441
|
+
stableTimeoutMs?: number;
|
|
442
|
+
terminalMessage?: string;
|
|
443
|
+
onExhausted?(ctx: ChatRecoveryExhaustedContext): void | Promise<void>;
|
|
444
|
+
};
|
|
445
|
+
type ResolvedChatRecoveryConfig = {
|
|
446
|
+
enabled: boolean;
|
|
447
|
+
maxAttempts: number;
|
|
448
|
+
stableTimeoutMs: number;
|
|
449
|
+
terminalMessage: string;
|
|
450
|
+
onExhausted?: (ctx: ChatRecoveryExhaustedContext) => void | Promise<void>;
|
|
451
|
+
};
|
|
362
452
|
/**
|
|
363
453
|
* Controls how overlapping user submit requests behave while another
|
|
364
454
|
* chat turn is already active or queued.
|
|
@@ -631,6 +721,7 @@ declare const CHAT_MESSAGE_TYPES: {
|
|
|
631
721
|
readonly TOOL_RESULT: "cf_agent_tool_result";
|
|
632
722
|
readonly TOOL_APPROVAL: "cf_agent_tool_approval";
|
|
633
723
|
readonly MESSAGE_UPDATED: "cf_agent_message_updated";
|
|
724
|
+
readonly CHAT_RECOVERING: "cf_agent_chat_recovering";
|
|
634
725
|
};
|
|
635
726
|
//#endregion
|
|
636
727
|
//#region src/chat/continuation-state.d.ts
|
|
@@ -644,9 +735,11 @@ interface ContinuationConnection {
|
|
|
644
735
|
readonly id: string;
|
|
645
736
|
send(message: string): void;
|
|
646
737
|
}
|
|
647
|
-
interface ContinuationPending
|
|
648
|
-
|
|
649
|
-
|
|
738
|
+
interface ContinuationPending<
|
|
739
|
+
TConnection extends ContinuationConnection = ContinuationConnection
|
|
740
|
+
> {
|
|
741
|
+
connection: TConnection;
|
|
742
|
+
connectionId: string | null;
|
|
650
743
|
requestId: string;
|
|
651
744
|
clientTools?: ClientToolSchema[];
|
|
652
745
|
body?: Record<string, unknown>;
|
|
@@ -654,24 +747,33 @@ interface ContinuationPending {
|
|
|
654
747
|
prerequisite: Promise<boolean> | null;
|
|
655
748
|
pastCoalesce: boolean;
|
|
656
749
|
}
|
|
657
|
-
interface ContinuationDeferred
|
|
658
|
-
|
|
659
|
-
|
|
750
|
+
interface ContinuationDeferred<
|
|
751
|
+
TConnection extends ContinuationConnection = ContinuationConnection
|
|
752
|
+
> {
|
|
753
|
+
connection: TConnection;
|
|
754
|
+
connectionId: string | null;
|
|
660
755
|
clientTools?: ClientToolSchema[];
|
|
661
756
|
body?: Record<string, unknown>;
|
|
662
757
|
errorPrefix: string;
|
|
663
758
|
prerequisite: Promise<boolean> | null;
|
|
664
759
|
}
|
|
665
|
-
declare class ContinuationState
|
|
666
|
-
|
|
667
|
-
|
|
760
|
+
declare class ContinuationState<
|
|
761
|
+
TConnection extends ContinuationConnection = ContinuationConnection
|
|
762
|
+
> {
|
|
763
|
+
pending: ContinuationPending<TConnection> | null;
|
|
764
|
+
deferred: ContinuationDeferred<TConnection> | null;
|
|
668
765
|
activeRequestId: string | null;
|
|
669
766
|
activeConnectionId: string | null;
|
|
670
|
-
awaitingConnections: Map<string,
|
|
767
|
+
awaitingConnections: Map<string, TConnection>;
|
|
671
768
|
/** Clear pending state and awaiting connections (without sending RESUME_NONE). */
|
|
672
769
|
clearPending(): void;
|
|
673
770
|
clearDeferred(): void;
|
|
674
771
|
clearAll(): void;
|
|
772
|
+
/**
|
|
773
|
+
* Mark a connection as no longer available without canceling the
|
|
774
|
+
* continuation it initiated.
|
|
775
|
+
*/
|
|
776
|
+
releaseConnection(connectionId: string): void;
|
|
675
777
|
/**
|
|
676
778
|
* Send STREAM_RESUME_NONE to all connections waiting for a
|
|
677
779
|
* continuation stream to start, then clear the map.
|
|
@@ -681,9 +783,7 @@ declare class ContinuationState {
|
|
|
681
783
|
* Flush awaiting connections by notifying each one via the provided
|
|
682
784
|
* callback (typically sends STREAM_RESUMING), then clear.
|
|
683
785
|
*/
|
|
684
|
-
flushAwaitingConnections(
|
|
685
|
-
notify: (conn: ContinuationConnection) => void
|
|
686
|
-
): void;
|
|
786
|
+
flushAwaitingConnections(notify: (conn: TConnection) => void): void;
|
|
687
787
|
/**
|
|
688
788
|
* Transition pending → active. Called when the continuation stream
|
|
689
789
|
* actually starts. Moves request/connection IDs to active slots,
|
|
@@ -697,7 +797,9 @@ declare class ContinuationState {
|
|
|
697
797
|
* Returns the new pending state (so the host can enqueue the turn),
|
|
698
798
|
* or null if there was nothing deferred.
|
|
699
799
|
*/
|
|
700
|
-
activateDeferred(
|
|
800
|
+
activateDeferred(
|
|
801
|
+
generateRequestId: () => string
|
|
802
|
+
): ContinuationPending<TConnection> | null;
|
|
701
803
|
}
|
|
702
804
|
//#endregion
|
|
703
805
|
//#region src/chat/abort-registry.d.ts
|
|
@@ -810,6 +912,39 @@ declare function toolResultUpdate(
|
|
|
810
912
|
overrideState?: "output-error",
|
|
811
913
|
errorText?: string
|
|
812
914
|
): ToolPartUpdate;
|
|
915
|
+
/**
|
|
916
|
+
* Build an update descriptor for a terminal tool result that belongs to a
|
|
917
|
+
* tool part in a *different* (earlier) assistant message than the one
|
|
918
|
+
* currently being streamed.
|
|
919
|
+
*
|
|
920
|
+
* This is the "cross-message" case: an approved server tool executes during a
|
|
921
|
+
* continuation stream, but its tool part lives in the assistant message that
|
|
922
|
+
* originally requested it. `StreamAccumulator` surfaces this as a
|
|
923
|
+
* `cross-message-tool-update` action because the accumulator only owns the
|
|
924
|
+
* current turn's new content and cannot mutate a part from a prior message.
|
|
925
|
+
*
|
|
926
|
+
* Compared to {@link toolResultUpdate} this builder is deliberately more
|
|
927
|
+
* defensive, mirroring the equivalent fallback in `@cloudflare/ai-chat`:
|
|
928
|
+
*
|
|
929
|
+
* - It matches the broad set of pre-terminal **and** terminal states, so a
|
|
930
|
+
* provider that replays the entire prior tool round-trip during a
|
|
931
|
+
* continuation (notably the OpenAI Responses API — issue #1404) still
|
|
932
|
+
* resolves to the same part instead of silently missing it.
|
|
933
|
+
* - It is **first-write-wins**: a chunk arriving for a tool that already holds
|
|
934
|
+
* a terminal result is treated as a replay and the existing output is never
|
|
935
|
+
* overwritten. In that case `apply` returns the *same part reference*, which
|
|
936
|
+
* callers use as an idempotent-no-op signal to skip the durable write and a
|
|
937
|
+
* redundant `MESSAGE_UPDATED` broadcast.
|
|
938
|
+
* - It preserves a streamed `preliminary` flag when one is present, otherwise
|
|
939
|
+
* marks the result final (`preliminary: false`).
|
|
940
|
+
*/
|
|
941
|
+
declare function crossMessageToolResultUpdate(
|
|
942
|
+
toolCallId: string,
|
|
943
|
+
updateType: "output-available" | "output-error",
|
|
944
|
+
output?: unknown,
|
|
945
|
+
errorText?: string,
|
|
946
|
+
preliminary?: boolean
|
|
947
|
+
): ToolPartUpdate;
|
|
813
948
|
/**
|
|
814
949
|
* Build an update descriptor for applying a tool approval.
|
|
815
950
|
*
|
|
@@ -945,6 +1080,7 @@ type ChatFiberSnapshot<Kind extends string = string> = {
|
|
|
945
1080
|
kind: Kind;
|
|
946
1081
|
version: 1;
|
|
947
1082
|
requestId: string;
|
|
1083
|
+
recoveryRootRequestId?: string;
|
|
948
1084
|
continuation: boolean;
|
|
949
1085
|
latestMessageId?: string;
|
|
950
1086
|
latestMessageRole?: string;
|
|
@@ -956,6 +1092,7 @@ type ChatFiberSnapshot<Kind extends string = string> = {
|
|
|
956
1092
|
declare function createChatFiberSnapshot<Kind extends string>({
|
|
957
1093
|
kind,
|
|
958
1094
|
requestId,
|
|
1095
|
+
recoveryRootRequestId,
|
|
959
1096
|
continuation,
|
|
960
1097
|
messages,
|
|
961
1098
|
lastBody,
|
|
@@ -963,6 +1100,7 @@ declare function createChatFiberSnapshot<Kind extends string>({
|
|
|
963
1100
|
}: {
|
|
964
1101
|
kind: Kind;
|
|
965
1102
|
requestId: string;
|
|
1103
|
+
recoveryRootRequestId?: string;
|
|
966
1104
|
continuation: boolean;
|
|
967
1105
|
messages: UIMessage[];
|
|
968
1106
|
lastBody?: Record<string, unknown>;
|
|
@@ -994,7 +1132,9 @@ export {
|
|
|
994
1132
|
CHAT_MESSAGE_TYPES,
|
|
995
1133
|
type ChatFiberSnapshot,
|
|
996
1134
|
type ChatProtocolEvent,
|
|
1135
|
+
type ChatRecoveryConfig,
|
|
997
1136
|
type ChatRecoveryContext,
|
|
1137
|
+
type ChatRecoveryExhaustedContext,
|
|
998
1138
|
type ChatRecoveryOptions,
|
|
999
1139
|
type ChatResponseResult,
|
|
1000
1140
|
type ChunkAction,
|
|
@@ -1010,6 +1150,7 @@ export {
|
|
|
1010
1150
|
type MessageParts,
|
|
1011
1151
|
type NormalizedMessageConcurrency,
|
|
1012
1152
|
ROW_MAX_BYTES,
|
|
1153
|
+
type ResolvedChatRecoveryConfig,
|
|
1013
1154
|
ResumableStream,
|
|
1014
1155
|
type SaveMessagesOptions,
|
|
1015
1156
|
type SaveMessagesResult,
|
|
@@ -1031,8 +1172,10 @@ export {
|
|
|
1031
1172
|
createAgentToolEventState,
|
|
1032
1173
|
createChatFiberSnapshot,
|
|
1033
1174
|
createToolsFromClientSchemas,
|
|
1175
|
+
crossMessageToolResultUpdate,
|
|
1034
1176
|
enforceRowSizeLimit,
|
|
1035
1177
|
isReplayChunk,
|
|
1178
|
+
normalizeToolInput,
|
|
1036
1179
|
parseProtocolMessage,
|
|
1037
1180
|
reconcileMessages,
|
|
1038
1181
|
resolveToolMergeId,
|
package/dist/chat/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as isReplayChunk, n as createAgentToolEventState, r as applyChunkToParts, t as applyAgentToolEvent } from "../agent-tools-
|
|
2
|
-
import { t as truncateToolOutput } from "../tool-output-truncation-
|
|
1
|
+
import { a as normalizeToolInput, i as isReplayChunk, n as createAgentToolEventState, r as applyChunkToParts, t as applyAgentToolEvent } from "../agent-tools-DYrkT-Kx.js";
|
|
2
|
+
import { t as truncateToolOutput } from "../tool-output-truncation-CNnnGZQ3.js";
|
|
3
3
|
import { jsonSchema, tool } from "ai";
|
|
4
4
|
import { nanoid } from "nanoid";
|
|
5
5
|
//#region src/chat/sanitize.ts
|
|
@@ -520,7 +520,8 @@ const CHAT_MESSAGE_TYPES = {
|
|
|
520
520
|
STREAM_RESUME_NONE: "cf_agent_stream_resume_none",
|
|
521
521
|
TOOL_RESULT: "cf_agent_tool_result",
|
|
522
522
|
TOOL_APPROVAL: "cf_agent_tool_approval",
|
|
523
|
-
MESSAGE_UPDATED: "cf_agent_message_updated"
|
|
523
|
+
MESSAGE_UPDATED: "cf_agent_message_updated",
|
|
524
|
+
CHAT_RECOVERING: "cf_agent_chat_recovering"
|
|
524
525
|
};
|
|
525
526
|
//#endregion
|
|
526
527
|
//#region src/chat/resumable-stream.ts
|
|
@@ -969,6 +970,22 @@ var ContinuationState = class {
|
|
|
969
970
|
this.activeConnectionId = null;
|
|
970
971
|
}
|
|
971
972
|
/**
|
|
973
|
+
* Mark a connection as no longer available without canceling the
|
|
974
|
+
* continuation it initiated.
|
|
975
|
+
*/
|
|
976
|
+
releaseConnection(connectionId) {
|
|
977
|
+
this.awaitingConnections.delete(connectionId);
|
|
978
|
+
if (this.pending?.connectionId === connectionId) this.pending = {
|
|
979
|
+
...this.pending,
|
|
980
|
+
connectionId: null
|
|
981
|
+
};
|
|
982
|
+
if (this.deferred?.connectionId === connectionId) this.deferred = {
|
|
983
|
+
...this.deferred,
|
|
984
|
+
connectionId: null
|
|
985
|
+
};
|
|
986
|
+
if (this.activeConnectionId === connectionId) this.activeConnectionId = null;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
972
989
|
* Send STREAM_RESUME_NONE to all connections waiting for a
|
|
973
990
|
* continuation stream to start, then clear the map.
|
|
974
991
|
*/
|
|
@@ -1019,7 +1036,7 @@ var ContinuationState = class {
|
|
|
1019
1036
|
prerequisite: d.prerequisite,
|
|
1020
1037
|
pastCoalesce: false
|
|
1021
1038
|
};
|
|
1022
|
-
this.awaitingConnections.set(d.connectionId, d.connection);
|
|
1039
|
+
if (d.connectionId !== null) this.awaitingConnections.set(d.connectionId, d.connection);
|
|
1023
1040
|
return this.pending;
|
|
1024
1041
|
}
|
|
1025
1042
|
};
|
|
@@ -1172,6 +1189,60 @@ function toolResultUpdate(toolCallId, output, overrideState, errorText) {
|
|
|
1172
1189
|
};
|
|
1173
1190
|
}
|
|
1174
1191
|
/**
|
|
1192
|
+
* Build an update descriptor for a terminal tool result that belongs to a
|
|
1193
|
+
* tool part in a *different* (earlier) assistant message than the one
|
|
1194
|
+
* currently being streamed.
|
|
1195
|
+
*
|
|
1196
|
+
* This is the "cross-message" case: an approved server tool executes during a
|
|
1197
|
+
* continuation stream, but its tool part lives in the assistant message that
|
|
1198
|
+
* originally requested it. `StreamAccumulator` surfaces this as a
|
|
1199
|
+
* `cross-message-tool-update` action because the accumulator only owns the
|
|
1200
|
+
* current turn's new content and cannot mutate a part from a prior message.
|
|
1201
|
+
*
|
|
1202
|
+
* Compared to {@link toolResultUpdate} this builder is deliberately more
|
|
1203
|
+
* defensive, mirroring the equivalent fallback in `@cloudflare/ai-chat`:
|
|
1204
|
+
*
|
|
1205
|
+
* - It matches the broad set of pre-terminal **and** terminal states, so a
|
|
1206
|
+
* provider that replays the entire prior tool round-trip during a
|
|
1207
|
+
* continuation (notably the OpenAI Responses API — issue #1404) still
|
|
1208
|
+
* resolves to the same part instead of silently missing it.
|
|
1209
|
+
* - It is **first-write-wins**: a chunk arriving for a tool that already holds
|
|
1210
|
+
* a terminal result is treated as a replay and the existing output is never
|
|
1211
|
+
* overwritten. In that case `apply` returns the *same part reference*, which
|
|
1212
|
+
* callers use as an idempotent-no-op signal to skip the durable write and a
|
|
1213
|
+
* redundant `MESSAGE_UPDATED` broadcast.
|
|
1214
|
+
* - It preserves a streamed `preliminary` flag when one is present, otherwise
|
|
1215
|
+
* marks the result final (`preliminary: false`).
|
|
1216
|
+
*/
|
|
1217
|
+
function crossMessageToolResultUpdate(toolCallId, updateType, output, errorText, preliminary) {
|
|
1218
|
+
return {
|
|
1219
|
+
toolCallId,
|
|
1220
|
+
matchStates: [
|
|
1221
|
+
"input-streaming",
|
|
1222
|
+
"input-available",
|
|
1223
|
+
"approval-requested",
|
|
1224
|
+
"approval-responded",
|
|
1225
|
+
"output-available",
|
|
1226
|
+
"output-error",
|
|
1227
|
+
"output-denied"
|
|
1228
|
+
],
|
|
1229
|
+
apply: (part) => {
|
|
1230
|
+
if (part.state === "output-available" || part.state === "output-error" || part.state === "output-denied") return part;
|
|
1231
|
+
if (updateType === "output-error") return {
|
|
1232
|
+
...part,
|
|
1233
|
+
state: "output-error",
|
|
1234
|
+
errorText: errorText ?? "Tool execution failed"
|
|
1235
|
+
};
|
|
1236
|
+
return {
|
|
1237
|
+
...part,
|
|
1238
|
+
state: "output-available",
|
|
1239
|
+
output,
|
|
1240
|
+
preliminary: preliminary ?? false
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
1245
|
+
/**
|
|
1175
1246
|
* Build an update descriptor for applying a tool approval.
|
|
1176
1247
|
*
|
|
1177
1248
|
* Matches parts in `input-available` or `approval-requested` state.
|
|
@@ -1311,23 +1382,35 @@ function assistantContentKey(message, sanitize) {
|
|
|
1311
1382
|
return JSON.stringify(sanitized.parts);
|
|
1312
1383
|
}
|
|
1313
1384
|
function mergeServerToolOutputs(incoming, serverMessages) {
|
|
1314
|
-
const
|
|
1385
|
+
const serverResolvedParts = /* @__PURE__ */ new Map();
|
|
1315
1386
|
for (const msg of serverMessages) {
|
|
1316
1387
|
if (msg.role !== "assistant") continue;
|
|
1317
|
-
for (const part of msg.parts)
|
|
1388
|
+
for (const part of msg.parts) {
|
|
1389
|
+
const record = part;
|
|
1390
|
+
if ("toolCallId" in record && "state" in record && (record.state === "output-available" || record.state === "output-error" || record.state === "output-denied")) serverResolvedParts.set(record.toolCallId, record);
|
|
1391
|
+
}
|
|
1318
1392
|
}
|
|
1319
|
-
if (
|
|
1393
|
+
if (serverResolvedParts.size === 0) return incoming;
|
|
1320
1394
|
return incoming.map((msg) => {
|
|
1321
1395
|
if (msg.role !== "assistant") return msg;
|
|
1322
1396
|
let hasChanges = false;
|
|
1323
1397
|
const updatedParts = msg.parts.map((part) => {
|
|
1324
|
-
|
|
1398
|
+
const record = part;
|
|
1399
|
+
if ("toolCallId" in record && "state" in record && (record.state === "input-available" || record.state === "approval-requested" || record.state === "approval-responded") && serverResolvedParts.has(record.toolCallId)) {
|
|
1325
1400
|
hasChanges = true;
|
|
1326
|
-
|
|
1401
|
+
const server = serverResolvedParts.get(record.toolCallId);
|
|
1402
|
+
const merged = {
|
|
1327
1403
|
...part,
|
|
1328
|
-
state:
|
|
1329
|
-
output: serverToolOutputs.get(part.toolCallId)
|
|
1404
|
+
state: server.state
|
|
1330
1405
|
};
|
|
1406
|
+
if (server.state === "output-available") {
|
|
1407
|
+
if ("output" in server) merged.output = server.output;
|
|
1408
|
+
} else if (server.state === "output-error") {
|
|
1409
|
+
if ("errorText" in server) merged.errorText = server.errorText;
|
|
1410
|
+
} else if (server.state === "output-denied") {
|
|
1411
|
+
if ("approval" in server) merged.approval = server.approval;
|
|
1412
|
+
}
|
|
1413
|
+
return merged;
|
|
1331
1414
|
}
|
|
1332
1415
|
return part;
|
|
1333
1416
|
});
|
|
@@ -1379,7 +1462,7 @@ function findMessageByToolCallId(messages, toolCallId) {
|
|
|
1379
1462
|
}
|
|
1380
1463
|
//#endregion
|
|
1381
1464
|
//#region src/chat/recovery.ts
|
|
1382
|
-
function createChatFiberSnapshot({ kind, requestId, continuation, messages, lastBody, lastClientTools }) {
|
|
1465
|
+
function createChatFiberSnapshot({ kind, requestId, recoveryRootRequestId, continuation, messages, lastBody, lastClientTools }) {
|
|
1383
1466
|
const latestMessage = messages.length > 0 ? messages[messages.length - 1] : void 0;
|
|
1384
1467
|
let latestUser;
|
|
1385
1468
|
for (let index = messages.length - 1; index >= 0; index--) if (messages[index].role === "user") {
|
|
@@ -1390,6 +1473,7 @@ function createChatFiberSnapshot({ kind, requestId, continuation, messages, last
|
|
|
1390
1473
|
kind,
|
|
1391
1474
|
version: 1,
|
|
1392
1475
|
requestId,
|
|
1476
|
+
recoveryRootRequestId,
|
|
1393
1477
|
continuation,
|
|
1394
1478
|
latestMessageId: latestMessage?.id,
|
|
1395
1479
|
latestMessageRole: latestMessage?.role,
|
|
@@ -1427,6 +1511,6 @@ function unwrapChatFiberSnapshot(key, value, expectedKind) {
|
|
|
1427
1511
|
};
|
|
1428
1512
|
}
|
|
1429
1513
|
//#endregion
|
|
1430
|
-
export { AbortRegistry, CHAT_MESSAGE_TYPES, ContinuationState, ROW_MAX_BYTES, ResumableStream, StreamAccumulator, SubmitConcurrencyController, TurnQueue, applyAgentToolEvent, applyChunkToParts, applyToolUpdate, assistantContentKey, transition as broadcastTransition, byteLength, createAgentToolEventState, createChatFiberSnapshot, createToolsFromClientSchemas, enforceRowSizeLimit, isReplayChunk, parseProtocolMessage, reconcileMessages, resolveToolMergeId, sanitizeMessage, toolApprovalUpdate, toolResultUpdate, unwrapChatFiberSnapshot, wrapChatFiberSnapshot };
|
|
1514
|
+
export { AbortRegistry, CHAT_MESSAGE_TYPES, ContinuationState, ROW_MAX_BYTES, ResumableStream, StreamAccumulator, SubmitConcurrencyController, TurnQueue, applyAgentToolEvent, applyChunkToParts, applyToolUpdate, assistantContentKey, transition as broadcastTransition, byteLength, createAgentToolEventState, createChatFiberSnapshot, createToolsFromClientSchemas, crossMessageToolResultUpdate, enforceRowSizeLimit, isReplayChunk, normalizeToolInput, parseProtocolMessage, reconcileMessages, resolveToolMergeId, sanitizeMessage, toolApprovalUpdate, toolResultUpdate, unwrapChatFiberSnapshot, wrapChatFiberSnapshot };
|
|
1431
1515
|
|
|
1432
1516
|
//# sourceMappingURL=index.js.map
|