@tanstack/ai 0.58.0 → 0.59.0
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/esm/activities/chat/agents/define-agent.d.ts +81 -0
- package/dist/esm/activities/chat/agents/define-agent.js +34 -0
- package/dist/esm/activities/chat/agents/define-agent.js.map +1 -0
- package/dist/esm/activities/chat/agents/route.d.ts +53 -0
- package/dist/esm/activities/chat/agents/route.js +59 -0
- package/dist/esm/activities/chat/agents/route.js.map +1 -0
- package/dist/esm/activities/chat/agents/spawn.d.ts +124 -0
- package/dist/esm/activities/chat/agents/spawn.js +490 -0
- package/dist/esm/activities/chat/agents/spawn.js.map +1 -0
- package/dist/esm/activities/chat/agents/turn.d.ts +36 -0
- package/dist/esm/activities/chat/agents/turn.js +78 -0
- package/dist/esm/activities/chat/agents/turn.js.map +1 -0
- package/dist/esm/activities/chat/index.d.ts +13 -3
- package/dist/esm/activities/chat/index.js +337 -13
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/messages.d.ts +7 -1
- package/dist/esm/activities/chat/messages.js +94 -18
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/middleware/run-store.d.ts +43 -7
- package/dist/esm/activities/chat/middleware/run-store.js +8 -1
- package/dist/esm/activities/chat/middleware/run-store.js.map +1 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +47 -1
- package/dist/esm/activities/chat/middleware/types.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +46 -0
- package/dist/esm/activities/chat/stream/processor.js +280 -7
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +17 -3
- package/dist/esm/activities/chat/tools/tool-calls.js +54 -5
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/generateAudio/index.js +1 -1
- package/dist/esm/activities/generateImage/index.js +1 -1
- package/dist/esm/activities/generateLiveVideo/index.js +1 -1
- package/dist/esm/activities/generateSpeech/index.js +1 -1
- package/dist/esm/activities/generateTranscription/index.js +1 -1
- package/dist/esm/activities/generateVoice/index.js +1 -1
- package/dist/esm/activities/generateWorld/index.js +1 -1
- package/dist/esm/activities/index.d.ts +3 -0
- package/dist/esm/activities/index.js +5 -3
- package/dist/esm/activities/summarize/index.js +1 -1
- package/dist/esm/client.d.ts +5 -36
- package/dist/esm/client.js +4 -37
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +6 -3
- package/dist/esm/middlewares/content-guard.js.map +1 -1
- package/dist/esm/types.d.ts +110 -88
- package/dist/esm/utilities/adapter-yield-chunk.d.ts +5 -1
- package/dist/esm/utilities/ag-ui-usage.d.ts +9 -9
- package/dist/esm/utilities/ag-ui-usage.js +66 -3
- package/dist/esm/utilities/ag-ui-usage.js.map +1 -1
- package/dist/esm/utilities/ag-ui-wire.js +56 -0
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
- package/dist/esm/utilities/normalize-stream-chunk.js +7 -2
- package/dist/esm/utilities/normalize-stream-chunk.js.map +1 -1
- package/dist/esm/utilities/spec-event-keys.js +13 -8
- package/dist/esm/utilities/spec-event-keys.js.map +1 -1
- package/dist/esm/utilities/subagent-wire.d.ts +36 -0
- package/dist/esm/utilities/subagent-wire.js +131 -0
- package/dist/esm/utilities/subagent-wire.js.map +1 -0
- package/package.json +2 -2
- package/skills/ai-core/adapter-configuration/references/grok-adapter.md +1 -1
- package/skills/ai-core/media-generation/SKILL.md +2 -2
- package/skills/ai-core/middleware/SKILL.md +7 -4
- package/src/activities/chat/agents/define-agent.ts +121 -0
- package/src/activities/chat/agents/route.ts +115 -0
- package/src/activities/chat/agents/spawn.ts +806 -0
- package/src/activities/chat/agents/turn.ts +151 -0
- package/src/activities/chat/index.ts +529 -11
- package/src/activities/chat/messages.ts +125 -15
- package/src/activities/chat/middleware/run-store.ts +56 -7
- package/src/activities/chat/middleware/types.ts +47 -0
- package/src/activities/chat/stream/processor.ts +428 -8
- package/src/activities/chat/tools/tool-calls.ts +77 -11
- package/src/activities/index.ts +15 -0
- package/src/client.ts +22 -35
- package/src/index.ts +23 -0
- package/src/middlewares/content-guard.ts +7 -5
- package/src/types.ts +154 -94
- package/src/utilities/adapter-yield-chunk.ts +10 -2
- package/src/utilities/ag-ui-usage.test.ts +38 -0
- package/src/utilities/ag-ui-usage.ts +98 -11
- package/src/utilities/ag-ui-wire.ts +74 -0
- package/src/utilities/normalize-stream-chunk.ts +10 -2
- package/src/utilities/spec-event-keys.ts +34 -7
- package/src/utilities/subagent-wire.ts +184 -0
package/dist/esm/client.js
CHANGED
|
@@ -11,11 +11,14 @@ import { INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, ge
|
|
|
11
11
|
import { convertMessagesToModelMessages, generateMessageId, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeToUIMessage, uiMessageToModelMessages } from "./activities/chat/messages.js";
|
|
12
12
|
import { uiMessagesToWire } from "./utilities/ag-ui-wire.js";
|
|
13
13
|
import { restoreInboundChunk } from "./utilities/restore-inbound-chunk.js";
|
|
14
|
+
import { defineAgent } from "./activities/chat/agents/define-agent.js";
|
|
15
|
+
import { subagentRoute } from "./activities/chat/agents/route.js";
|
|
14
16
|
import { toolDefinition } from "./activities/chat/tools/tool-definition.js";
|
|
15
17
|
import { getChunkRunId, getChunkThreadId } from "./utilities/chunk-ids.js";
|
|
16
18
|
import { PartialJSONParser, defaultJSONParser, parsePartialJSON } from "./activities/chat/stream/json-parser.js";
|
|
17
19
|
import { BatchStrategy, CompositeStrategy, ImmediateStrategy, PunctuationStrategy, WordBoundaryStrategy } from "./activities/chat/stream/strategies.js";
|
|
18
20
|
import { StreamProcessor } from "./activities/chat/stream/processor.js";
|
|
21
|
+
import { EventType } from "@ag-ui/core";
|
|
19
22
|
//#region src/client.ts
|
|
20
23
|
var generationKinds = [
|
|
21
24
|
"image",
|
|
@@ -119,43 +122,7 @@ async function generationParamsFromRequest(kind, request) {
|
|
|
119
122
|
if (!isRecord(body)) throw new Error("Generation request body must be a JSON object.");
|
|
120
123
|
return generationParamsFromBody(kind, body);
|
|
121
124
|
}
|
|
122
|
-
var EventType = /* @__PURE__ */ function(EventType) {
|
|
123
|
-
EventType["TEXT_MESSAGE_START"] = "TEXT_MESSAGE_START";
|
|
124
|
-
EventType["TEXT_MESSAGE_CONTENT"] = "TEXT_MESSAGE_CONTENT";
|
|
125
|
-
EventType["TEXT_MESSAGE_END"] = "TEXT_MESSAGE_END";
|
|
126
|
-
EventType["TEXT_MESSAGE_CHUNK"] = "TEXT_MESSAGE_CHUNK";
|
|
127
|
-
EventType["TOOL_CALL_START"] = "TOOL_CALL_START";
|
|
128
|
-
EventType["TOOL_CALL_ARGS"] = "TOOL_CALL_ARGS";
|
|
129
|
-
EventType["TOOL_CALL_END"] = "TOOL_CALL_END";
|
|
130
|
-
EventType["TOOL_CALL_CHUNK"] = "TOOL_CALL_CHUNK";
|
|
131
|
-
EventType["TOOL_CALL_RESULT"] = "TOOL_CALL_RESULT";
|
|
132
|
-
EventType["THINKING_START"] = "THINKING_START";
|
|
133
|
-
EventType["THINKING_END"] = "THINKING_END";
|
|
134
|
-
EventType["THINKING_TEXT_MESSAGE_START"] = "THINKING_TEXT_MESSAGE_START";
|
|
135
|
-
EventType["THINKING_TEXT_MESSAGE_CONTENT"] = "THINKING_TEXT_MESSAGE_CONTENT";
|
|
136
|
-
EventType["THINKING_TEXT_MESSAGE_END"] = "THINKING_TEXT_MESSAGE_END";
|
|
137
|
-
EventType["STATE_SNAPSHOT"] = "STATE_SNAPSHOT";
|
|
138
|
-
EventType["STATE_DELTA"] = "STATE_DELTA";
|
|
139
|
-
EventType["MESSAGES_SNAPSHOT"] = "MESSAGES_SNAPSHOT";
|
|
140
|
-
EventType["ACTIVITY_SNAPSHOT"] = "ACTIVITY_SNAPSHOT";
|
|
141
|
-
EventType["ACTIVITY_DELTA"] = "ACTIVITY_DELTA";
|
|
142
|
-
EventType["RAW"] = "RAW";
|
|
143
|
-
EventType["CUSTOM"] = "CUSTOM";
|
|
144
|
-
EventType["RUN_STARTED"] = "RUN_STARTED";
|
|
145
|
-
EventType["RUN_FINISHED"] = "RUN_FINISHED";
|
|
146
|
-
EventType["RUN_ERROR"] = "RUN_ERROR";
|
|
147
|
-
EventType["STEP_STARTED"] = "STEP_STARTED";
|
|
148
|
-
EventType["STEP_FINISHED"] = "STEP_FINISHED";
|
|
149
|
-
EventType["REASONING_START"] = "REASONING_START";
|
|
150
|
-
EventType["REASONING_MESSAGE_START"] = "REASONING_MESSAGE_START";
|
|
151
|
-
EventType["REASONING_MESSAGE_CONTENT"] = "REASONING_MESSAGE_CONTENT";
|
|
152
|
-
EventType["REASONING_MESSAGE_END"] = "REASONING_MESSAGE_END";
|
|
153
|
-
EventType["REASONING_MESSAGE_CHUNK"] = "REASONING_MESSAGE_CHUNK";
|
|
154
|
-
EventType["REASONING_END"] = "REASONING_END";
|
|
155
|
-
EventType["REASONING_ENCRYPTED_VALUE"] = "REASONING_ENCRYPTED_VALUE";
|
|
156
|
-
return EventType;
|
|
157
|
-
}({});
|
|
158
125
|
//#endregion
|
|
159
|
-
export { BatchStrategy, CompositeStrategy, EventType, INTERRUPT_BINDING_METADATA_KEY, INTERRUPT_BINDING_VERSION, INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, INTERRUPT_PAYLOAD_METADATA_KEY, ImmediateStrategy, PartialJSONParser, PunctuationStrategy, StreamProcessor, WordBoundaryStrategy, canonicalInterruptJson, canonicalizeInterruptResolutions, cloneAndDeepFreezeJson, convertMessagesToModelMessages, convertSchemaToJsonSchema, defaultJSONParser, defineInterrupt, digestInterruptJson, fromSpecTokenUsage, generateMessageId, generationParamsFromBody, generationParamsFromRequest, genericInterruptContinuationFromDescriptor, getChunkRunId, getChunkThreadId, hashInterruptDefinitionSchema, hashSchemaInput, isStandardSchema, mergeMetadata, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeApprovalSchema, normalizeStreamChunk, normalizeToUIMessage, parsePartialJSON, parseWithStandardSchema, readGenericInterruptContinuation, readInterruptBinding, readUnopenedInterruptBinding, restoreInboundChunk, tanstackMetadata, toSpecTokenUsage, toolDefinition, uiMessageToModelMessages, uiMessagesToWire, validateWithStandardSchema, withInterruptBinding, withTanstackMetadata, withoutInterruptBinding, wrapGenericInterruptContinuation };
|
|
126
|
+
export { BatchStrategy, CompositeStrategy, EventType, INTERRUPT_BINDING_METADATA_KEY, INTERRUPT_BINDING_VERSION, INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, INTERRUPT_PAYLOAD_METADATA_KEY, ImmediateStrategy, PartialJSONParser, PunctuationStrategy, StreamProcessor, WordBoundaryStrategy, canonicalInterruptJson, canonicalizeInterruptResolutions, cloneAndDeepFreezeJson, convertMessagesToModelMessages, convertSchemaToJsonSchema, defaultJSONParser, defineAgent, defineInterrupt, digestInterruptJson, fromSpecTokenUsage, generateMessageId, generationParamsFromBody, generationParamsFromRequest, genericInterruptContinuationFromDescriptor, getChunkRunId, getChunkThreadId, hashInterruptDefinitionSchema, hashSchemaInput, isStandardSchema, mergeMetadata, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeApprovalSchema, normalizeStreamChunk, normalizeToUIMessage, parsePartialJSON, parseWithStandardSchema, readGenericInterruptContinuation, readInterruptBinding, readUnopenedInterruptBinding, restoreInboundChunk, subagentRoute, tanstackMetadata, toSpecTokenUsage, toolDefinition, uiMessageToModelMessages, uiMessagesToWire, validateWithStandardSchema, withInterruptBinding, withTanstackMetadata, withoutInterruptBinding, wrapGenericInterruptContinuation };
|
|
160
127
|
|
|
161
128
|
//# sourceMappingURL=client.js.map
|
package/dist/esm/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":[],"sources":["../../src/client.ts"],"sourcesContent":["import type {\n AudioGenerationOptions,\n ImageGenerationOptions,\n TTSOptions,\n TranscriptionOptions,\n VoiceGenerationOptions,\n VideoGenerationOptions,\n WorldGenerationOptions,\n LiveVideoGenerationOptions,\n} from './types'\n\nexport type GenerationKind =\n | 'image'\n | 'audio'\n | 'tts'\n | 'voice'\n | 'video'\n | 'transcription'\n | 'world'\n | 'liveVideo'\n\ntype GenerationInputByKind = {\n image: Omit<ImageGenerationOptions, 'logger' | 'model'>\n audio: Omit<AudioGenerationOptions, 'logger' | 'model'>\n tts: Omit<TTSOptions, 'logger' | 'model'>\n voice: Omit<VoiceGenerationOptions, 'logger' | 'model'>\n video: Omit<VideoGenerationOptions, 'logger' | 'model'>\n transcription: Omit<TranscriptionOptions, 'logger' | 'model'>\n world: Omit<WorldGenerationOptions, 'logger' | 'model'>\n liveVideo: Omit<LiveVideoGenerationOptions, 'logger' | 'model'>\n}\n\nexport interface GenerationParams<TKind extends GenerationKind> {\n input: GenerationInputByKind[TKind]\n forwardedProps: Record<string, unknown>\n threadId?: string\n runId?: string\n}\n\nconst generationKinds = [\n 'image',\n 'audio',\n 'tts',\n 'voice',\n 'video',\n 'transcription',\n 'world',\n 'liveVideo',\n] as const satisfies ReadonlyArray<GenerationKind>\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction hasOwnKey(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction isGenerationEnvelope(body: unknown): body is Record<string, unknown> {\n return (\n isRecord(body) &&\n (hasOwnKey(body, 'data') || hasOwnKey(body, 'forwardedProps'))\n )\n}\n\nfunction assertGenerationKind(kind: unknown): asserts kind is GenerationKind {\n if (!generationKinds.includes(kind as GenerationKind)) {\n throw new Error(\n `Unsupported generation kind: ${String(\n kind,\n )}. Expected one of ${generationKinds.join(', ')}.`,\n )\n }\n}\n\n/**\n * The input field(s) that identify a generation body for a kind. Most kinds\n * have exactly one; `voice` accepts either of its two creation modes, so any\n * one of its keys is enough.\n */\nfunction requiredKeysForKind(kind: GenerationKind): Array<string> {\n // Enumerated rather than defaulted so a new generation kind has to declare\n // the field that identifies its body instead of silently inheriting\n // `prompt`.\n switch (kind) {\n case 'tts':\n return ['text']\n case 'transcription':\n return ['audio']\n case 'voice':\n return ['prompt', 'referenceAudio']\n case 'image':\n case 'audio':\n case 'video':\n case 'world':\n case 'liveVideo':\n return ['prompt']\n }\n}\n\nfunction assertInputForKind(\n kind: GenerationKind,\n input: unknown,\n): asserts input is GenerationInputByKind[GenerationKind] {\n if (!isRecord(input)) {\n throw new Error(`Generation ${kind} input must be an object.`)\n }\n\n const requiredKeys = requiredKeysForKind(kind)\n\n if (!requiredKeys.some((key) => hasOwnKey(input, key))) {\n throw new Error(\n `Generation ${kind} input must include ${requiredKeys.join(' or ')}.`,\n )\n }\n}\n\nfunction isInputForKind(kind: GenerationKind, input: unknown): boolean {\n if (!isRecord(input)) return false\n\n return requiredKeysForKind(kind).some((key) => hasOwnKey(input, key))\n}\n\nfunction forwardedPropsFromEnvelope(\n envelope: Record<string, unknown>,\n): Record<string, unknown> {\n if (!hasOwnKey(envelope, 'forwardedProps')) {\n return {}\n }\n\n if (!isRecord(envelope.forwardedProps)) {\n throw new Error('Generation envelope forwardedProps must be an object.')\n }\n\n return envelope.forwardedProps\n}\n\nfunction optionalStringField(\n envelope: Record<string, unknown>,\n key: 'threadId' | 'runId',\n): string | undefined {\n if (!hasOwnKey(envelope, key)) {\n return undefined\n }\n\n const value = envelope[key]\n if (typeof value !== 'string') {\n throw new Error(`Generation envelope ${key} must be a string.`)\n }\n\n return value\n}\n\nfunction generationIdentityFields(envelope: Record<string, unknown>): {\n threadId?: string\n runId?: string\n} {\n const identity: {\n threadId?: string\n runId?: string\n } = {}\n const threadId = optionalStringField(envelope, 'threadId')\n const runId = optionalStringField(envelope, 'runId')\n\n if (threadId !== undefined) identity.threadId = threadId\n if (runId !== undefined) identity.runId = runId\n\n return identity\n}\n\nexport function generationParamsFromBody<TKind extends GenerationKind>(\n kind: TKind,\n body: unknown,\n): GenerationParams<TKind> {\n assertGenerationKind(kind)\n\n if (isInputForKind(kind, body)) {\n assertInputForKind(kind, body)\n return {\n input: body as GenerationInputByKind[TKind],\n forwardedProps: {},\n }\n }\n\n if (!isGenerationEnvelope(body)) {\n assertInputForKind(kind, body)\n return {\n input: body as GenerationInputByKind[TKind],\n forwardedProps: {},\n }\n }\n\n if (!hasOwnKey(body, 'data')) {\n throw new Error(`Generation ${kind} envelope must include data.`)\n }\n\n const input = body.data\n assertInputForKind(kind, input)\n\n const forwardedProps = forwardedPropsFromEnvelope(body)\n\n return {\n input: input as GenerationInputByKind[TKind],\n forwardedProps,\n ...generationIdentityFields(body),\n }\n}\n\nexport async function generationParamsFromRequest<TKind extends GenerationKind>(\n kind: TKind,\n request: Request,\n): Promise<GenerationParams<TKind>> {\n let body: unknown\n try {\n body = await request.json()\n } catch (error) {\n throw new Error('Invalid JSON request body.', { cause: error })\n }\n\n if (!isRecord(body)) {\n throw new Error('Generation request body must be a JSON object.')\n }\n\n return generationParamsFromBody(kind, body)\n}\n\nexport enum EventType {\n TEXT_MESSAGE_START = 'TEXT_MESSAGE_START',\n TEXT_MESSAGE_CONTENT = 'TEXT_MESSAGE_CONTENT',\n TEXT_MESSAGE_END = 'TEXT_MESSAGE_END',\n TEXT_MESSAGE_CHUNK = 'TEXT_MESSAGE_CHUNK',\n TOOL_CALL_START = 'TOOL_CALL_START',\n TOOL_CALL_ARGS = 'TOOL_CALL_ARGS',\n TOOL_CALL_END = 'TOOL_CALL_END',\n TOOL_CALL_CHUNK = 'TOOL_CALL_CHUNK',\n TOOL_CALL_RESULT = 'TOOL_CALL_RESULT',\n THINKING_START = 'THINKING_START',\n THINKING_END = 'THINKING_END',\n THINKING_TEXT_MESSAGE_START = 'THINKING_TEXT_MESSAGE_START',\n THINKING_TEXT_MESSAGE_CONTENT = 'THINKING_TEXT_MESSAGE_CONTENT',\n THINKING_TEXT_MESSAGE_END = 'THINKING_TEXT_MESSAGE_END',\n STATE_SNAPSHOT = 'STATE_SNAPSHOT',\n STATE_DELTA = 'STATE_DELTA',\n MESSAGES_SNAPSHOT = 'MESSAGES_SNAPSHOT',\n ACTIVITY_SNAPSHOT = 'ACTIVITY_SNAPSHOT',\n ACTIVITY_DELTA = 'ACTIVITY_DELTA',\n RAW = 'RAW',\n CUSTOM = 'CUSTOM',\n RUN_STARTED = 'RUN_STARTED',\n RUN_FINISHED = 'RUN_FINISHED',\n RUN_ERROR = 'RUN_ERROR',\n STEP_STARTED = 'STEP_STARTED',\n STEP_FINISHED = 'STEP_FINISHED',\n REASONING_START = 'REASONING_START',\n REASONING_MESSAGE_START = 'REASONING_MESSAGE_START',\n REASONING_MESSAGE_CONTENT = 'REASONING_MESSAGE_CONTENT',\n REASONING_MESSAGE_END = 'REASONING_MESSAGE_END',\n REASONING_MESSAGE_CHUNK = 'REASONING_MESSAGE_CHUNK',\n REASONING_END = 'REASONING_END',\n REASONING_ENCRYPTED_VALUE = 'REASONING_ENCRYPTED_VALUE',\n}\n\nexport {\n toolDefinition,\n type AnyClientTool,\n type ClientTool,\n type InferToolInput,\n type InferToolName,\n type InferToolOutput,\n type ApprovalCapabilityOf,\n type ApprovalSchemaConfig,\n type ApprovalSchemaOf,\n type InputSchemaOf,\n type OutputSchemaOf,\n type NoSchema,\n type ToolDefinition,\n type ToolDefinitionConfig,\n type ToolDefinitionInstance,\n} from './activities/chat/tools/tool-definition'\n\nexport {\n hashSchemaInput,\n normalizeApprovalSchema,\n type NormalizedApprovalSchema,\n type NormalizedSchemaInput,\n} from './activities/chat/tools/approval-schema'\n\nexport {\n canonicalInterruptJson,\n cloneAndDeepFreezeJson,\n digestInterruptJson,\n} from './interrupt-serialization'\n\nexport {\n convertSchemaToJsonSchema,\n isStandardSchema,\n parseWithStandardSchema,\n validateWithStandardSchema,\n} from './activities/chat/tools/schema-converter'\n\nexport {\n convertMessagesToModelMessages,\n generateMessageId,\n modelMessageToUIMessage,\n modelMessagesToUIMessages,\n normalizeToUIMessage,\n uiMessageToModelMessages,\n} from './activities/chat/messages'\n\nexport {\n BatchStrategy,\n CompositeStrategy,\n defaultJSONParser,\n ImmediateStrategy,\n parsePartialJSON,\n PartialJSONParser,\n PunctuationStrategy,\n StreamProcessor,\n WordBoundaryStrategy,\n} from './activities/chat/stream/index'\nexport type {\n ChunkRecording,\n ChunkStrategy,\n InternalToolCallState,\n JSONParser,\n ProcessorResult,\n ProcessorState,\n StreamProcessorEvents,\n StreamProcessorOptions,\n ToolCallState,\n ToolResultState,\n} from './activities/chat/stream/index'\n\nexport { uiMessagesToWire } from './utilities/ag-ui-wire'\nexport {\n mergeMetadata,\n tanstackMetadata,\n withTanstackMetadata,\n} from './utilities/merge-metadata'\nexport { fromSpecTokenUsage, toSpecTokenUsage } from './utilities/ag-ui-usage'\nexport type { SpecTokenUsage } from './utilities/ag-ui-usage'\nexport { normalizeStreamChunk } from './utilities/normalize-stream-chunk'\nexport { restoreInboundChunk } from './utilities/restore-inbound-chunk'\nexport type { AdapterYieldChunk } from './utilities/adapter-yield-chunk'\nexport { getChunkRunId, getChunkThreadId } from './utilities/chunk-ids'\nexport type { WireMessage } from './utilities/ag-ui-wire'\n\nexport type {\n AudioPart,\n ContentPart,\n ContentPartDataSource,\n ContentPartSource,\n ContentPartUrlSource,\n CustomEvent,\n DocumentPart,\n ImagePart,\n MediaInputMetadata,\n MediaInputRole,\n MediaPrompt,\n MediaPromptPart,\n MessagePart,\n ModelMessage,\n PersistedArtifactActivity,\n PersistedArtifactRef,\n PersistedArtifactRole,\n Interrupt,\n RunAgentResumeItem,\n RunErrorEvent,\n RunFinishedEvent,\n RunFinishedOutcome,\n SchemaInput,\n StreamChunk,\n StructuredOutputPart,\n TextPart,\n TanStackMessageMetadata,\n TanStackRunMetadata,\n ThinkingPart,\n ToolCall,\n ToolCallPart,\n ToolResultPart,\n UIMessage,\n UIResourcePart,\n VideoPart,\n InferSchemaType,\n} from './types'\n\n// Enumerated, not `export *` — see the matching note in `index.ts`. The\n// interrupt protocol surface is a commitment, so it is published field by\n// field.\nexport {\n INTERRUPT_BINDING_VERSION,\n canonicalizeInterruptResolutions,\n} from './interrupts'\nexport {\n defineInterrupt,\n hashInterruptDefinitionSchema,\n INTERRUPT_PAYLOAD_METADATA_KEY,\n} from './interrupt-definition'\nexport {\n INTERRUPT_CONTINUATION_METADATA_KEY,\n INTERRUPT_CONTINUATION_VERSION,\n genericInterruptContinuationFromDescriptor,\n readGenericInterruptContinuation,\n wrapGenericInterruptContinuation,\n} from './generic-interrupt-continuation'\nexport type {\n GenericInterruptContinuation,\n GenericInterruptContinuationReadResult,\n} from './generic-interrupt-continuation'\nexport type {\n GenericInterruptRequest,\n InterruptDefinition,\n} from './interrupt-definition'\nexport type {\n BatchInterruptError,\n BatchInterruptErrorCode,\n InterruptBinding,\n InterruptCorrelation,\n InterruptSubmissionError,\n ItemInterruptError,\n ItemInterruptErrorCode,\n ToolApprovalResolution,\n UnopenedInterruptBinding,\n} from './interrupts'\n\nexport {\n INTERRUPT_BINDING_METADATA_KEY,\n readInterruptBinding,\n readUnopenedInterruptBinding,\n withInterruptBinding,\n withoutInterruptBinding,\n} from './interrupt-resume'\n\nexport type {\n AudioVisualization,\n RealtimeAdapter,\n RealtimeConnection,\n RealtimeError,\n RealtimeErrorCode,\n RealtimeEvent,\n RealtimeEventHandler,\n RealtimeEventPayloads,\n RealtimeMessage,\n RealtimeMessagePart,\n RealtimeMode,\n RealtimeSessionConfig,\n RealtimeStatus,\n RealtimeToken,\n RealtimeAudioPart,\n RealtimeImagePart,\n RealtimeTextPart,\n RealtimeToolCallPart,\n RealtimeToolResultPart,\n VADConfig,\n} from './realtime/types'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":[],"sources":["../../src/client.ts"],"sourcesContent":["import type {\n AudioGenerationOptions,\n ImageGenerationOptions,\n TTSOptions,\n TranscriptionOptions,\n VoiceGenerationOptions,\n VideoGenerationOptions,\n WorldGenerationOptions,\n LiveVideoGenerationOptions,\n} from './types'\n\nexport type GenerationKind =\n | 'image'\n | 'audio'\n | 'tts'\n | 'voice'\n | 'video'\n | 'transcription'\n | 'world'\n | 'liveVideo'\n\ntype GenerationInputByKind = {\n image: Omit<ImageGenerationOptions, 'logger' | 'model'>\n audio: Omit<AudioGenerationOptions, 'logger' | 'model'>\n tts: Omit<TTSOptions, 'logger' | 'model'>\n voice: Omit<VoiceGenerationOptions, 'logger' | 'model'>\n video: Omit<VideoGenerationOptions, 'logger' | 'model'>\n transcription: Omit<TranscriptionOptions, 'logger' | 'model'>\n world: Omit<WorldGenerationOptions, 'logger' | 'model'>\n liveVideo: Omit<LiveVideoGenerationOptions, 'logger' | 'model'>\n}\n\nexport interface GenerationParams<TKind extends GenerationKind> {\n input: GenerationInputByKind[TKind]\n forwardedProps: Record<string, unknown>\n threadId?: string\n runId?: string\n}\n\nconst generationKinds = [\n 'image',\n 'audio',\n 'tts',\n 'voice',\n 'video',\n 'transcription',\n 'world',\n 'liveVideo',\n] as const satisfies ReadonlyArray<GenerationKind>\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction hasOwnKey(value: Record<string, unknown>, key: string): boolean {\n return Object.prototype.hasOwnProperty.call(value, key)\n}\n\nfunction isGenerationEnvelope(body: unknown): body is Record<string, unknown> {\n return (\n isRecord(body) &&\n (hasOwnKey(body, 'data') || hasOwnKey(body, 'forwardedProps'))\n )\n}\n\nfunction assertGenerationKind(kind: unknown): asserts kind is GenerationKind {\n if (!generationKinds.includes(kind as GenerationKind)) {\n throw new Error(\n `Unsupported generation kind: ${String(\n kind,\n )}. Expected one of ${generationKinds.join(', ')}.`,\n )\n }\n}\n\n/**\n * The input field(s) that identify a generation body for a kind. Most kinds\n * have exactly one; `voice` accepts either of its two creation modes, so any\n * one of its keys is enough.\n */\nfunction requiredKeysForKind(kind: GenerationKind): Array<string> {\n // Enumerated rather than defaulted so a new generation kind has to declare\n // the field that identifies its body instead of silently inheriting\n // `prompt`.\n switch (kind) {\n case 'tts':\n return ['text']\n case 'transcription':\n return ['audio']\n case 'voice':\n return ['prompt', 'referenceAudio']\n case 'image':\n case 'audio':\n case 'video':\n case 'world':\n case 'liveVideo':\n return ['prompt']\n }\n}\n\nfunction assertInputForKind(\n kind: GenerationKind,\n input: unknown,\n): asserts input is GenerationInputByKind[GenerationKind] {\n if (!isRecord(input)) {\n throw new Error(`Generation ${kind} input must be an object.`)\n }\n\n const requiredKeys = requiredKeysForKind(kind)\n\n if (!requiredKeys.some((key) => hasOwnKey(input, key))) {\n throw new Error(\n `Generation ${kind} input must include ${requiredKeys.join(' or ')}.`,\n )\n }\n}\n\nfunction isInputForKind(kind: GenerationKind, input: unknown): boolean {\n if (!isRecord(input)) return false\n\n return requiredKeysForKind(kind).some((key) => hasOwnKey(input, key))\n}\n\nfunction forwardedPropsFromEnvelope(\n envelope: Record<string, unknown>,\n): Record<string, unknown> {\n if (!hasOwnKey(envelope, 'forwardedProps')) {\n return {}\n }\n\n if (!isRecord(envelope.forwardedProps)) {\n throw new Error('Generation envelope forwardedProps must be an object.')\n }\n\n return envelope.forwardedProps\n}\n\nfunction optionalStringField(\n envelope: Record<string, unknown>,\n key: 'threadId' | 'runId',\n): string | undefined {\n if (!hasOwnKey(envelope, key)) {\n return undefined\n }\n\n const value = envelope[key]\n if (typeof value !== 'string') {\n throw new Error(`Generation envelope ${key} must be a string.`)\n }\n\n return value\n}\n\nfunction generationIdentityFields(envelope: Record<string, unknown>): {\n threadId?: string\n runId?: string\n} {\n const identity: {\n threadId?: string\n runId?: string\n } = {}\n const threadId = optionalStringField(envelope, 'threadId')\n const runId = optionalStringField(envelope, 'runId')\n\n if (threadId !== undefined) identity.threadId = threadId\n if (runId !== undefined) identity.runId = runId\n\n return identity\n}\n\nexport function generationParamsFromBody<TKind extends GenerationKind>(\n kind: TKind,\n body: unknown,\n): GenerationParams<TKind> {\n assertGenerationKind(kind)\n\n if (isInputForKind(kind, body)) {\n assertInputForKind(kind, body)\n return {\n input: body as GenerationInputByKind[TKind],\n forwardedProps: {},\n }\n }\n\n if (!isGenerationEnvelope(body)) {\n assertInputForKind(kind, body)\n return {\n input: body as GenerationInputByKind[TKind],\n forwardedProps: {},\n }\n }\n\n if (!hasOwnKey(body, 'data')) {\n throw new Error(`Generation ${kind} envelope must include data.`)\n }\n\n const input = body.data\n assertInputForKind(kind, input)\n\n const forwardedProps = forwardedPropsFromEnvelope(body)\n\n return {\n input: input as GenerationInputByKind[TKind],\n forwardedProps,\n ...generationIdentityFields(body),\n }\n}\n\nexport async function generationParamsFromRequest<TKind extends GenerationKind>(\n kind: TKind,\n request: Request,\n): Promise<GenerationParams<TKind>> {\n let body: unknown\n try {\n body = await request.json()\n } catch (error) {\n throw new Error('Invalid JSON request body.', { cause: error })\n }\n\n if (!isRecord(body)) {\n throw new Error('Generation request body must be a JSON object.')\n }\n\n return generationParamsFromBody(kind, body)\n}\n\nexport { EventType } from '@ag-ui/core'\n\nexport {\n defineAgent,\n type DefinedAgent,\n type SubagentChoiceOptions,\n type SubagentRunContext,\n} from './activities/chat/agents/define-agent'\nexport {\n subagentRoute,\n type SubagentRouteOptions,\n} from './activities/chat/agents/route'\nexport type {\n SubagentOrder,\n SubagentRouterPick,\n SubagentRouterPlan,\n SubagentStep,\n SubagentStepsPlan,\n} from './activities/chat/agents/spawn'\n\nexport {\n toolDefinition,\n type AnyClientTool,\n type ClientTool,\n type InferToolInput,\n type InferToolName,\n type InferToolOutput,\n type ApprovalCapabilityOf,\n type ApprovalSchemaConfig,\n type ApprovalSchemaOf,\n type InputSchemaOf,\n type OutputSchemaOf,\n type NoSchema,\n type ToolDefinition,\n type ToolDefinitionConfig,\n type ToolDefinitionInstance,\n} from './activities/chat/tools/tool-definition'\n\nexport {\n hashSchemaInput,\n normalizeApprovalSchema,\n type NormalizedApprovalSchema,\n type NormalizedSchemaInput,\n} from './activities/chat/tools/approval-schema'\n\nexport {\n canonicalInterruptJson,\n cloneAndDeepFreezeJson,\n digestInterruptJson,\n} from './interrupt-serialization'\n\nexport {\n convertSchemaToJsonSchema,\n isStandardSchema,\n parseWithStandardSchema,\n validateWithStandardSchema,\n} from './activities/chat/tools/schema-converter'\n\nexport {\n convertMessagesToModelMessages,\n generateMessageId,\n modelMessageToUIMessage,\n modelMessagesToUIMessages,\n normalizeToUIMessage,\n uiMessageToModelMessages,\n} from './activities/chat/messages'\n\nexport {\n BatchStrategy,\n CompositeStrategy,\n defaultJSONParser,\n ImmediateStrategy,\n parsePartialJSON,\n PartialJSONParser,\n PunctuationStrategy,\n StreamProcessor,\n WordBoundaryStrategy,\n} from './activities/chat/stream/index'\nexport type {\n ChunkRecording,\n ChunkStrategy,\n InternalToolCallState,\n JSONParser,\n ProcessorResult,\n ProcessorState,\n StreamProcessorEvents,\n StreamProcessorOptions,\n ToolCallState,\n ToolResultState,\n} from './activities/chat/stream/index'\n\nexport { uiMessagesToWire } from './utilities/ag-ui-wire'\nexport {\n mergeMetadata,\n tanstackMetadata,\n withTanstackMetadata,\n} from './utilities/merge-metadata'\nexport { fromSpecTokenUsage, toSpecTokenUsage } from './utilities/ag-ui-usage'\nexport type { SpecTokenUsage } from './utilities/ag-ui-usage'\nexport { normalizeStreamChunk } from './utilities/normalize-stream-chunk'\nexport { restoreInboundChunk } from './utilities/restore-inbound-chunk'\nexport type { AdapterYieldChunk } from './utilities/adapter-yield-chunk'\nexport { getChunkRunId, getChunkThreadId } from './utilities/chunk-ids'\nexport type { WireMessage } from './utilities/ag-ui-wire'\n\nexport type {\n AudioPart,\n ContentPart,\n ContentPartDataSource,\n ContentPartFileSource,\n SubagentHandleData,\n SubagentStatus,\n ContentPartSource,\n ContentPartUrlSource,\n CustomEvent,\n DocumentPart,\n ImagePart,\n MediaInputMetadata,\n MediaInputRole,\n MediaPrompt,\n MediaPromptPart,\n MessagePart,\n ModelMessage,\n PersistedArtifactActivity,\n PersistedArtifactRef,\n PersistedArtifactRole,\n Interrupt,\n RunAgentResumeItem,\n RunErrorEvent,\n RunFinishedEvent,\n RunFinishedOutcome,\n SchemaInput,\n StreamChunk,\n StructuredOutputPart,\n TextPart,\n TanStackMessageMetadata,\n TanStackRunMetadata,\n ThinkingPart,\n ToolCall,\n ToolCallPart,\n ToolResultPart,\n UIMessage,\n UIResourcePart,\n VideoPart,\n InferSchemaType,\n} from './types'\n\n// Enumerated, not `export *` — see the matching note in `index.ts`. The\n// interrupt protocol surface is a commitment, so it is published field by\n// field.\nexport {\n INTERRUPT_BINDING_VERSION,\n canonicalizeInterruptResolutions,\n} from './interrupts'\nexport {\n defineInterrupt,\n hashInterruptDefinitionSchema,\n INTERRUPT_PAYLOAD_METADATA_KEY,\n} from './interrupt-definition'\nexport {\n INTERRUPT_CONTINUATION_METADATA_KEY,\n INTERRUPT_CONTINUATION_VERSION,\n genericInterruptContinuationFromDescriptor,\n readGenericInterruptContinuation,\n wrapGenericInterruptContinuation,\n} from './generic-interrupt-continuation'\nexport type {\n GenericInterruptContinuation,\n GenericInterruptContinuationReadResult,\n} from './generic-interrupt-continuation'\nexport type {\n GenericInterruptRequest,\n InterruptDefinition,\n} from './interrupt-definition'\nexport type {\n BatchInterruptError,\n BatchInterruptErrorCode,\n InterruptBinding,\n InterruptCorrelation,\n InterruptSubmissionError,\n ItemInterruptError,\n ItemInterruptErrorCode,\n ToolApprovalResolution,\n UnopenedInterruptBinding,\n} from './interrupts'\n\nexport {\n INTERRUPT_BINDING_METADATA_KEY,\n readInterruptBinding,\n readUnopenedInterruptBinding,\n withInterruptBinding,\n withoutInterruptBinding,\n} from './interrupt-resume'\n\nexport type {\n AudioVisualization,\n RealtimeAdapter,\n RealtimeConnection,\n RealtimeError,\n RealtimeErrorCode,\n RealtimeEvent,\n RealtimeEventHandler,\n RealtimeEventPayloads,\n RealtimeMessage,\n RealtimeMessagePart,\n RealtimeMode,\n RealtimeSessionConfig,\n RealtimeStatus,\n RealtimeToken,\n RealtimeAudioPart,\n RealtimeImagePart,\n RealtimeTextPart,\n RealtimeToolCallPart,\n RealtimeToolResultPart,\n VADConfig,\n} from './realtime/types'\n"],"mappings":"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"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -14,6 +14,9 @@ export { createLiveVideoOptions } from './activities/generateLiveVideo/index.js'
|
|
|
14
14
|
export type { AIAdapter, ImageAdapter, AnyImageAdapter, TextAdapter, AnyTextAdapter, AnySummarizeAdapter, SummarizeAdapter, AnyAudioAdapter, AudioAdapter, AnyTTSAdapter, TTSAdapter, TTSCapabilities, AnyVoiceAdapter, VoiceAdapter, AnyTranscriptionAdapter, TranscriptionAdapter, AnyVideoAdapter, VideoAdapter, AnyEmbeddingAdapter, EmbeddingAdapter, AnyRerankAdapter, RerankAdapter, AnyEvaluateAdapter, EvaluateAdapter, ChoiceAnswer, ScoreAnswer, BooleanAnswer, EvaluateResult, WireQuestion, WireAnswer, AnyWorldAdapter, WorldAdapter, AnyLiveVideoAdapter, LiveVideoAdapter, } from './activities/index.js';
|
|
15
15
|
export { BaseRerankAdapter } from './activities/rerank/adapter.js';
|
|
16
16
|
export { BaseEvaluateAdapter } from './activities/evaluate/adapter.js';
|
|
17
|
+
export { defineAgent, type DefinedAgent, type SubagentChoiceOptions, type SubagentRunContext, } from './activities/chat/agents/define-agent.js';
|
|
18
|
+
export { subagentRoute, type SubagentRouteOptions, } from './activities/chat/agents/route.js';
|
|
19
|
+
export type { SubagentOrder, SubagentRouterPick, SubagentRouterPlan, SubagentStep, SubagentStepsPlan, } from './activities/chat/agents/spawn.js';
|
|
17
20
|
export { toolDefinition, type ToolDefinition, type ToolDefinitionInstance, type ToolDefinitionConfig, type ServerTool, type AnyServerTool, type ClientTool, type AnyClientTool, type InferToolName, type InferToolInput, type InferToolOutput, type ApprovalCapabilityOf, type ApprovalSchemaConfig, type ApprovalSchemaOf, type InputSchemaOf, type OutputSchemaOf, type NoSchema, } from './activities/chat/tools/tool-definition.js';
|
|
18
21
|
export { hashSchemaInput, normalizeApprovalSchema, type NormalizedApprovalSchema, type NormalizedSchemaInput, } from './activities/chat/tools/approval-schema.js';
|
|
19
22
|
export { canonicalInterruptJson, cloneAndDeepFreezeJson, digestInterruptJson, } from './interrupt-serialization.js';
|
|
@@ -74,6 +77,8 @@ export { chatParamsFromRequest, chatParamsFromRequestBody, mergeAgentTools, } fr
|
|
|
74
77
|
export type { ClientToolDeclaration, MergedAgentTools, } from './utilities/chat-params.js';
|
|
75
78
|
export { generationParamsFromBody, generationParamsFromRequest } from './client.js';
|
|
76
79
|
export { uiMessagesToWire } from './utilities/ag-ui-wire.js';
|
|
80
|
+
export type { SubagentWireInfo } from './utilities/subagent-wire.js';
|
|
81
|
+
export { subagentHostMessageId, wireSubagentInfo, } from './utilities/subagent-wire.js';
|
|
77
82
|
export { mergeMetadata, withTanstackMetadata } from './utilities/merge-metadata.js';
|
|
78
83
|
export { fromSpecTokenUsage, toSpecTokenUsage } from './utilities/ag-ui-usage.js';
|
|
79
84
|
export type { SpecTokenUsage } from './utilities/ag-ui-usage.js';
|
package/dist/esm/index.js
CHANGED
|
@@ -18,6 +18,7 @@ import { INTERRUPT_BINDING_METADATA_KEY, InterruptResumeValidationError, interru
|
|
|
18
18
|
import { INTERRUPT_PAYLOAD_METADATA_KEY, createInterruptBinding, defineInterrupt } from "./interrupt-definition.js";
|
|
19
19
|
import { INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, genericInterruptContinuationFromDescriptor, readGenericInterruptContinuation, wrapGenericInterruptContinuation } from "./generic-interrupt-continuation.js";
|
|
20
20
|
import { isContentPart, isContentPartArray, normalizeToolResult } from "./utilities/tool-result.js";
|
|
21
|
+
import { subagentHostMessageId, wireSubagentInfo } from "./utilities/subagent-wire.js";
|
|
21
22
|
import { getProviderExecutedMetadata, isProviderExecutedToolCall } from "./utilities/provider-executed.js";
|
|
22
23
|
import { convertMessagesToModelMessages, generateMessageId, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeToUIMessage, uiMessageToModelMessages } from "./activities/chat/messages.js";
|
|
23
24
|
import { uiMessagesToWire } from "./utilities/ag-ui-wire.js";
|
|
@@ -28,11 +29,13 @@ import { ToolCallManager } from "./activities/chat/tools/tool-calls.js";
|
|
|
28
29
|
import { combineStrategies, maxIterations, untilFinishReason } from "./activities/chat/agent-loop-strategies.js";
|
|
29
30
|
import { MCPDuplicateToolNameError } from "./activities/chat/mcp/manager.js";
|
|
30
31
|
import { chat, createChatOptions } from "./activities/chat/index.js";
|
|
32
|
+
import { defineAgent } from "./activities/chat/agents/define-agent.js";
|
|
33
|
+
import { BaseEvaluateAdapter } from "./activities/evaluate/adapter.js";
|
|
34
|
+
import { boolean, choice, decide, score } from "./activities/evaluate/index.js";
|
|
35
|
+
import { subagentRoute } from "./activities/chat/agents/route.js";
|
|
31
36
|
import { createSummarizeOptions, summarize } from "./activities/summarize/index.js";
|
|
32
37
|
import { BaseRerankAdapter } from "./activities/rerank/adapter.js";
|
|
33
38
|
import { createRerankOptions, rerank } from "./activities/rerank/index.js";
|
|
34
|
-
import { BaseEvaluateAdapter } from "./activities/evaluate/adapter.js";
|
|
35
|
-
import { boolean, choice, decide, score } from "./activities/evaluate/index.js";
|
|
36
39
|
import { resolveMediaPrompt } from "./utilities/media-prompt.js";
|
|
37
40
|
import { createImageOptions, generateImage } from "./activities/generateImage/index.js";
|
|
38
41
|
import { createAudioOptions, generateAudio } from "./activities/generateAudio/index.js";
|
|
@@ -64,4 +67,4 @@ import { BatchStrategy, CompositeStrategy, ImmediateStrategy, PunctuationStrateg
|
|
|
64
67
|
import { StreamProcessor, createReplayStream } from "./activities/chat/stream/processor.js";
|
|
65
68
|
import { generationParamsFromBody, generationParamsFromRequest } from "./client.js";
|
|
66
69
|
import { createModel, extendAdapter } from "./extend-adapter.js";
|
|
67
|
-
export { BaseEvaluateAdapter, BaseRerankAdapter, BatchStrategy, CUSTOM_EVENT, CompositeStrategy, ConsoleLogger, DISCOVERY_TOOL_NAME, DetachableRunCapability, DuplicateToolNameError, EventType, INTERRUPT_BINDING_METADATA_KEY, INTERRUPT_BINDING_VERSION, INTERRUPT_BOUNDARY_PHASES, INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, INTERRUPT_PAYLOAD_METADATA_KEY, INTERRUPT_TOOL_RESUMES, ImmediateStrategy, InMemoryRunStore, InterruptResumeValidationError, MCPDuplicateToolNameError, MetadataCapability, PartialJSONParser, PunctuationStrategy, RUN_ACCEPTED_EVENT, RUN_CANCEL_REASON, RunDetachedCapability, SkillLimitError, StandardSchemaValidationError, StreamProcessor, ToolCallManager, WordBoundaryStrategy, boolean, brandProviderTool, buildBaseUsage, canonicalInterruptJson, canonicalizeInterruptResolutions, chat, chatParamsFromRequest, chatParamsFromRequestBody, choice, cloneAndDeepFreezeJson, combineStrategies, convertMessagesToModelMessages, convertSchemaToJsonSchema, countEmbeddingInputModalities, createAudioOptions, createCapability, createChatMiddleware, createChatOptions, createEmbedOptions, createFrozenRegistry, createImageOptions, createInterruptBinding, createLiveVideoOptions, createModel, createRealtimeEventEmitter, createReplayStream, createRerankOptions, createSpeechOptions, createSummarizeOptions, createToolRegistry, createTranscriptionOptions, createVideoOptions, createVoiceOptions, createWorldOptions, decide, decodeWsFrame, defaultJSONParser, defineChatMiddleware, defineInterrupt, defineRunStore, detectImageMimeType, digestInterruptJson, embed, encodeWsFrame, extendAdapter, firstSentence, fromSpecTokenUsage, generateAudio, generateImage, generateLiveVideo, generateMessageId, generateSpeech, generateTranscription, generateVideo, generateVoice, generateWorld, generationParamsFromBody, generationParamsFromRequest, genericInterruptContinuationFromDescriptor, getChunkRunId, getChunkThreadId, getDetachableRun, getMetadata, getProviderExecutedMetadata, getRunDetached, getVideoJobStatus, hashSchemaInput, interruptItemError, isCancelRequestedReason, isContentPart, isContentPartArray, isCustomEvent, isProviderExecutedToolCall, isRunStatus, isStandardSchema, isTerminalRunStatus, listVoices, maxIterations, memoryStream, mergeAgentTools, mergeMetadata, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeApprovalSchema, normalizeStreamChunk, normalizeSystemPrompts, normalizeToUIMessage, normalizeToolResult, parsePartialJSON, parseWithStandardSchema, provideDetachableRun, provideMetadata, provideRunDetached, readGenericInterruptContinuation, readInterruptBinding, readUnopenedInterruptBinding, realtimeToken, renderLazyCatalogEntry, replayRunStream, requestRunCancel, requireTextOnlyEmbeddingInput, rerank, resolveEmbeddingInput, resolveMediaPrompt, resolveResumeRunId, resumeHttpResponse, resumeServerSentEventsResponse, resumeWebSocketResponse, resumeWebSocketStream, score, streamToText, summarize, toHttpResponse, toHttpStream, toServerSentEventsResponse, toServerSentEventsStream, toSpecTokenUsage, toWebSocketResponse, toWebSocketStream, toolDefinition, uiMessageToModelMessages, uiMessagesToWire, untilFinishReason, validateInterruptResumeBatch, validateWithStandardSchema, wasCancelRequested, withInterruptBinding, withTanstackMetadata, withoutInterruptBinding, wrapGenericInterruptContinuation };
|
|
70
|
+
export { BaseEvaluateAdapter, BaseRerankAdapter, BatchStrategy, CUSTOM_EVENT, CompositeStrategy, ConsoleLogger, DISCOVERY_TOOL_NAME, DetachableRunCapability, DuplicateToolNameError, EventType, INTERRUPT_BINDING_METADATA_KEY, INTERRUPT_BINDING_VERSION, INTERRUPT_BOUNDARY_PHASES, INTERRUPT_CONTINUATION_METADATA_KEY, INTERRUPT_CONTINUATION_VERSION, INTERRUPT_PAYLOAD_METADATA_KEY, INTERRUPT_TOOL_RESUMES, ImmediateStrategy, InMemoryRunStore, InterruptResumeValidationError, MCPDuplicateToolNameError, MetadataCapability, PartialJSONParser, PunctuationStrategy, RUN_ACCEPTED_EVENT, RUN_CANCEL_REASON, RunDetachedCapability, SkillLimitError, StandardSchemaValidationError, StreamProcessor, ToolCallManager, WordBoundaryStrategy, boolean, brandProviderTool, buildBaseUsage, canonicalInterruptJson, canonicalizeInterruptResolutions, chat, chatParamsFromRequest, chatParamsFromRequestBody, choice, cloneAndDeepFreezeJson, combineStrategies, convertMessagesToModelMessages, convertSchemaToJsonSchema, countEmbeddingInputModalities, createAudioOptions, createCapability, createChatMiddleware, createChatOptions, createEmbedOptions, createFrozenRegistry, createImageOptions, createInterruptBinding, createLiveVideoOptions, createModel, createRealtimeEventEmitter, createReplayStream, createRerankOptions, createSpeechOptions, createSummarizeOptions, createToolRegistry, createTranscriptionOptions, createVideoOptions, createVoiceOptions, createWorldOptions, decide, decodeWsFrame, defaultJSONParser, defineAgent, defineChatMiddleware, defineInterrupt, defineRunStore, detectImageMimeType, digestInterruptJson, embed, encodeWsFrame, extendAdapter, firstSentence, fromSpecTokenUsage, generateAudio, generateImage, generateLiveVideo, generateMessageId, generateSpeech, generateTranscription, generateVideo, generateVoice, generateWorld, generationParamsFromBody, generationParamsFromRequest, genericInterruptContinuationFromDescriptor, getChunkRunId, getChunkThreadId, getDetachableRun, getMetadata, getProviderExecutedMetadata, getRunDetached, getVideoJobStatus, hashSchemaInput, interruptItemError, isCancelRequestedReason, isContentPart, isContentPartArray, isCustomEvent, isProviderExecutedToolCall, isRunStatus, isStandardSchema, isTerminalRunStatus, listVoices, maxIterations, memoryStream, mergeAgentTools, mergeMetadata, modelMessageToUIMessage, modelMessagesToUIMessages, normalizeApprovalSchema, normalizeStreamChunk, normalizeSystemPrompts, normalizeToUIMessage, normalizeToolResult, parsePartialJSON, parseWithStandardSchema, provideDetachableRun, provideMetadata, provideRunDetached, readGenericInterruptContinuation, readInterruptBinding, readUnopenedInterruptBinding, realtimeToken, renderLazyCatalogEntry, replayRunStream, requestRunCancel, requireTextOnlyEmbeddingInput, rerank, resolveEmbeddingInput, resolveMediaPrompt, resolveResumeRunId, resumeHttpResponse, resumeServerSentEventsResponse, resumeWebSocketResponse, resumeWebSocketStream, score, streamToText, subagentHostMessageId, subagentRoute, summarize, toHttpResponse, toHttpStream, toServerSentEventsResponse, toServerSentEventsStream, toSpecTokenUsage, toWebSocketResponse, toWebSocketStream, toolDefinition, uiMessageToModelMessages, uiMessagesToWire, untilFinishReason, validateInterruptResumeBatch, validateWithStandardSchema, wasCancelRequested, wireSubagentInfo, withInterruptBinding, withTanstackMetadata, withoutInterruptBinding, wrapGenericInterruptContinuation };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content-guard.js","names":[],"sources":["../../../src/middlewares/content-guard.ts"],"sourcesContent":["import type {\n ChatMiddleware,\n ChatMiddlewareContext,\n} from '../activities/chat/middleware/types'\nimport type { StreamChunk } from '../types'\n\n/**\n * A content guard rule — either a regex pattern with replacement, or a transform function.\n */\nexport type ContentGuardRule =\n | { pattern: RegExp; replacement: string }\n | { fn: (text: string) => string }\n\n/**\n * Information passed to the onFiltered callback.\n */\nexport interface ContentFilteredInfo {\n /** The message ID being filtered */\n messageId: string\n /** The original text before filtering */\n original: string\n /** The filtered text after rules applied */\n filtered: string\n /** Which strategy was used */\n strategy: 'delta' | 'buffered'\n}\n\n/**\n * Options for the content guard middleware.\n */\nexport interface ContentGuardMiddlewareOptions {\n /**\n * Rules to apply to text content. Each rule is either a regex pattern\n * with a replacement string, or a custom transform function.\n * Rules are applied in order. Each rule receives the output of the previous.\n */\n rules: Array<ContentGuardRule>\n\n /**\n * Matching strategy:\n * - 'delta': Apply rules to each delta as it arrives. Fast, real-time,\n * but patterns spanning chunk boundaries may be missed.\n * - 'buffered': Accumulate content and apply rules to settled portions,\n * holding back a look-behind buffer to catch cross-boundary patterns.\n *\n * @default 'buffered'\n */\n strategy?: 'delta' | 'buffered'\n\n /**\n * Number of characters to hold back before emitting (buffered strategy only).\n * Should be at least as long as the longest pattern you expect to match.\n * Buffer is flushed when the stream ends.\n *\n * @default 50\n */\n bufferSize?: number\n\n /**\n * If true, drop the entire chunk when any rule changes the content.\n * @default false\n */\n blockOnMatch?: boolean\n\n /**\n * Callback when content is filtered by any rule.\n */\n onFiltered?: (info: ContentFilteredInfo) => void\n}\n\n/**\n * Apply all rules to a string, returning the transformed result.\n */\nfunction applyRules(text: string, rules: Array<ContentGuardRule>): string {\n let result = text\n for (const rule of rules) {\n if ('pattern' in rule) {\n result = result.replace(rule.pattern, rule.replacement)\n } else {\n result = rule.fn(result)\n }\n }\n return result\n}\n\n/**\n * Creates a middleware that filters or transforms streamed text content.\n *\n * @example\n * ```ts\n * import { contentGuardMiddleware } from '@tanstack/ai/middlewares'\n *\n * const guard = contentGuardMiddleware({\n * rules: [\n * { pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g, replacement: '[SSN REDACTED]' },\n * ],\n * strategy: 'buffered',\n * })\n * ```\n */\nexport function contentGuardMiddleware(\n options: ContentGuardMiddlewareOptions,\n): ChatMiddleware {\n const {\n rules,\n strategy = 'buffered',\n bufferSize = 50,\n blockOnMatch = false,\n onFiltered,\n } = options\n\n if (strategy === 'delta') {\n return createDeltaStrategy(rules, blockOnMatch, onFiltered)\n }\n return createBufferedStrategy(rules, bufferSize, blockOnMatch, onFiltered)\n}\n\nfunction createDeltaStrategy(\n rules: Array<ContentGuardRule>,\n blockOnMatch: boolean,\n onFiltered?: (info: ContentFilteredInfo) => void,\n): ChatMiddleware {\n return {\n name: 'content-guard',\n\n onChunk(_ctx: ChatMiddlewareContext, chunk: StreamChunk) {\n if (chunk.type !== 'TEXT_MESSAGE_CONTENT') return\n\n const original = chunk.delta\n const filtered = applyRules(original, rules)\n\n if (filtered === original) return // unchanged, pass through\n\n if (onFiltered) {\n onFiltered({\n messageId: chunk.messageId,\n original,\n filtered,\n strategy: 'delta',\n })\n }\n\n if (blockOnMatch) return null // drop chunk\n\n // Strip out the previous `content` field by destructuring it away — with\n // `exactOptionalPropertyTypes` we can't assign `content: undefined`\n // against `content?: string`. The replacement event carries only the\n // filtered delta.\n const { content: _strippedContent, ...rest } = chunk\n void _strippedContent\n return {\n ...rest,\n delta: filtered,\n }\n },\n }\n}\n\nfunction createBufferedStrategy(\n rules: Array<ContentGuardRule>,\n bufferSize: number,\n blockOnMatch: boolean,\n onFiltered?: (info: ContentFilteredInfo) => void,\n): ChatMiddleware {\n let rawAccumulated = ''\n let emittedFilteredLength = 0\n let lastMessageId = ''\n\n function resetState() {\n rawAccumulated = ''\n emittedFilteredLength = 0\n lastMessageId = ''\n }\n\n function flushBuffer(): StreamChunk | null {\n if (rawAccumulated.length === 0) return null\n\n const filtered = applyRules(rawAccumulated, rules)\n\n if (blockOnMatch && filtered !== rawAccumulated) {\n if (onFiltered) {\n onFiltered({\n messageId: lastMessageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n resetState()\n return null\n }\n\n const remaining = filtered.slice(emittedFilteredLength)\n if (remaining.length > 0) {\n if (filtered !== rawAccumulated && onFiltered) {\n onFiltered({\n messageId: lastMessageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n\n const flushed = {\n type: 'TEXT_MESSAGE_CONTENT',\n messageId: lastMessageId,\n delta: remaining,\n content: filtered,\n timestamp: Date.now(),\n } as StreamChunk\n\n resetState()\n return flushed\n }\n\n resetState()\n return null\n }\n\n return {\n name: 'content-guard',\n\n onStart() {\n resetState()\n },\n\n onChunk(_ctx: ChatMiddlewareContext, chunk: StreamChunk) {\n // Flush buffer on stream end events\n if (chunk.type === 'TEXT_MESSAGE_END' || chunk.type === 'RUN_FINISHED') {\n const flushed = flushBuffer()\n if (flushed) return [flushed, chunk]\n return // pass through end event\n }\n\n if (chunk.type !== 'TEXT_MESSAGE_CONTENT') return // pass through\n\n // Flush buffer on message boundary change\n const pending: Array<StreamChunk> = []\n if (lastMessageId && chunk.messageId !== lastMessageId) {\n const flushed = flushBuffer()\n if (flushed) pending.push(flushed)\n }\n\n rawAccumulated += chunk.delta\n lastMessageId = chunk.messageId\n\n // Apply rules to full accumulated text, buffer in filtered space\n const filtered = applyRules(rawAccumulated, rules)\n const safeFilteredEnd = Math.max(0, filtered.length - bufferSize)\n\n if (safeFilteredEnd <= emittedFilteredLength) {\n return pending.length > 0 ? pending : null\n }\n\n if (blockOnMatch && filtered !== rawAccumulated) {\n if (onFiltered) {\n onFiltered({\n messageId: chunk.messageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n return pending.length > 0 ? pending : null\n }\n\n const newDelta = filtered.slice(emittedFilteredLength, safeFilteredEnd)\n\n if (filtered !== rawAccumulated && onFiltered) {\n onFiltered({\n messageId: chunk.messageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n\n emittedFilteredLength = safeFilteredEnd\n\n const emitChunk = {\n ...chunk,\n delta: newDelta,\n content: filtered.slice(0, safeFilteredEnd),\n } as StreamChunk\n\n // `pending` was empty before this push iff `emitChunk` is now the only\n // entry — return it directly without re-indexing through `pending[0]`.\n const wasEmpty = pending.length === 0\n pending.push(emitChunk)\n return wasEmpty ? emitChunk : pending\n },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"content-guard.js","names":[],"sources":["../../../src/middlewares/content-guard.ts"],"sourcesContent":["import type {\n ChatMiddleware,\n ChatMiddlewareContext,\n} from '../activities/chat/middleware/types'\nimport type { StreamChunk } from '../types'\nimport type { AdapterYieldChunk } from '../utilities/adapter-yield-chunk'\n\n/**\n * A content guard rule — either a regex pattern with replacement, or a transform function.\n */\nexport type ContentGuardRule =\n | { pattern: RegExp; replacement: string }\n | { fn: (text: string) => string }\n\n/**\n * Information passed to the onFiltered callback.\n */\nexport interface ContentFilteredInfo {\n /** The message ID being filtered */\n messageId: string\n /** The original text before filtering */\n original: string\n /** The filtered text after rules applied */\n filtered: string\n /** Which strategy was used */\n strategy: 'delta' | 'buffered'\n}\n\n/**\n * Options for the content guard middleware.\n */\nexport interface ContentGuardMiddlewareOptions {\n /**\n * Rules to apply to text content. Each rule is either a regex pattern\n * with a replacement string, or a custom transform function.\n * Rules are applied in order. Each rule receives the output of the previous.\n */\n rules: Array<ContentGuardRule>\n\n /**\n * Matching strategy:\n * - 'delta': Apply rules to each delta as it arrives. Fast, real-time,\n * but patterns spanning chunk boundaries may be missed.\n * - 'buffered': Accumulate content and apply rules to settled portions,\n * holding back a look-behind buffer to catch cross-boundary patterns.\n *\n * @default 'buffered'\n */\n strategy?: 'delta' | 'buffered'\n\n /**\n * Number of characters to hold back before emitting (buffered strategy only).\n * Should be at least as long as the longest pattern you expect to match.\n * Buffer is flushed when the stream ends.\n *\n * @default 50\n */\n bufferSize?: number\n\n /**\n * If true, drop the entire chunk when any rule changes the content.\n * @default false\n */\n blockOnMatch?: boolean\n\n /**\n * Callback when content is filtered by any rule.\n */\n onFiltered?: (info: ContentFilteredInfo) => void\n}\n\n/**\n * Apply all rules to a string, returning the transformed result.\n */\nfunction applyRules(text: string, rules: Array<ContentGuardRule>): string {\n let result = text\n for (const rule of rules) {\n if ('pattern' in rule) {\n result = result.replace(rule.pattern, rule.replacement)\n } else {\n result = rule.fn(result)\n }\n }\n return result\n}\n\n/**\n * Creates a middleware that filters or transforms streamed text content.\n *\n * @example\n * ```ts\n * import { contentGuardMiddleware } from '@tanstack/ai/middlewares'\n *\n * const guard = contentGuardMiddleware({\n * rules: [\n * { pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g, replacement: '[SSN REDACTED]' },\n * ],\n * strategy: 'buffered',\n * })\n * ```\n */\nexport function contentGuardMiddleware(\n options: ContentGuardMiddlewareOptions,\n): ChatMiddleware {\n const {\n rules,\n strategy = 'buffered',\n bufferSize = 50,\n blockOnMatch = false,\n onFiltered,\n } = options\n\n if (strategy === 'delta') {\n return createDeltaStrategy(rules, blockOnMatch, onFiltered)\n }\n return createBufferedStrategy(rules, bufferSize, blockOnMatch, onFiltered)\n}\n\nfunction createDeltaStrategy(\n rules: Array<ContentGuardRule>,\n blockOnMatch: boolean,\n onFiltered?: (info: ContentFilteredInfo) => void,\n): ChatMiddleware {\n return {\n name: 'content-guard',\n\n onChunk(_ctx: ChatMiddlewareContext, chunk: StreamChunk) {\n if (chunk.type !== 'TEXT_MESSAGE_CONTENT') return\n\n const original = chunk.delta\n const filtered = applyRules(original, rules)\n\n if (filtered === original) return // unchanged, pass through\n\n if (onFiltered) {\n onFiltered({\n messageId: chunk.messageId,\n original,\n filtered,\n strategy: 'delta',\n })\n }\n\n if (blockOnMatch) return null // drop chunk\n\n // Drop the adapter-era content field; the replacement event carries only\n // the filtered delta.\n const { content: _strippedContent, ...rest } = chunk as Extract<\n AdapterYieldChunk,\n { type: 'TEXT_MESSAGE_CONTENT' }\n >\n void _strippedContent\n return {\n ...rest,\n delta: filtered,\n }\n },\n }\n}\n\nfunction createBufferedStrategy(\n rules: Array<ContentGuardRule>,\n bufferSize: number,\n blockOnMatch: boolean,\n onFiltered?: (info: ContentFilteredInfo) => void,\n): ChatMiddleware {\n let rawAccumulated = ''\n let emittedFilteredLength = 0\n let lastMessageId = ''\n\n function resetState() {\n rawAccumulated = ''\n emittedFilteredLength = 0\n lastMessageId = ''\n }\n\n function flushBuffer(): StreamChunk | null {\n if (rawAccumulated.length === 0) return null\n\n const filtered = applyRules(rawAccumulated, rules)\n\n if (blockOnMatch && filtered !== rawAccumulated) {\n if (onFiltered) {\n onFiltered({\n messageId: lastMessageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n resetState()\n return null\n }\n\n const remaining = filtered.slice(emittedFilteredLength)\n if (remaining.length > 0) {\n if (filtered !== rawAccumulated && onFiltered) {\n onFiltered({\n messageId: lastMessageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n\n const flushed = {\n type: 'TEXT_MESSAGE_CONTENT',\n messageId: lastMessageId,\n delta: remaining,\n content: filtered,\n timestamp: Date.now(),\n } as StreamChunk\n\n resetState()\n return flushed\n }\n\n resetState()\n return null\n }\n\n return {\n name: 'content-guard',\n\n onStart() {\n resetState()\n },\n\n onChunk(_ctx: ChatMiddlewareContext, chunk: StreamChunk) {\n // Flush buffer on stream end events\n if (chunk.type === 'TEXT_MESSAGE_END' || chunk.type === 'RUN_FINISHED') {\n const flushed = flushBuffer()\n if (flushed) return [flushed, chunk]\n return // pass through end event\n }\n\n if (chunk.type !== 'TEXT_MESSAGE_CONTENT') return // pass through\n\n // Flush buffer on message boundary change\n const pending: Array<StreamChunk> = []\n if (lastMessageId && chunk.messageId !== lastMessageId) {\n const flushed = flushBuffer()\n if (flushed) pending.push(flushed)\n }\n\n rawAccumulated += chunk.delta\n lastMessageId = chunk.messageId\n\n // Apply rules to full accumulated text, buffer in filtered space\n const filtered = applyRules(rawAccumulated, rules)\n const safeFilteredEnd = Math.max(0, filtered.length - bufferSize)\n\n if (safeFilteredEnd <= emittedFilteredLength) {\n return pending.length > 0 ? pending : null\n }\n\n if (blockOnMatch && filtered !== rawAccumulated) {\n if (onFiltered) {\n onFiltered({\n messageId: chunk.messageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n return pending.length > 0 ? pending : null\n }\n\n const newDelta = filtered.slice(emittedFilteredLength, safeFilteredEnd)\n\n if (filtered !== rawAccumulated && onFiltered) {\n onFiltered({\n messageId: chunk.messageId,\n original: rawAccumulated,\n filtered,\n strategy: 'buffered',\n })\n }\n\n emittedFilteredLength = safeFilteredEnd\n\n const emitChunk = {\n ...chunk,\n delta: newDelta,\n content: filtered.slice(0, safeFilteredEnd),\n } as StreamChunk\n\n // `pending` was empty before this push iff `emitChunk` is now the only\n // entry — return it directly without re-indexing through `pending[0]`.\n const wasEmpty = pending.length === 0\n pending.push(emitChunk)\n return wasEmpty ? emitChunk : pending\n },\n }\n}\n"],"mappings":"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"}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { SystemPrompt } from './system-prompts.js';
|
|
|
4
4
|
import { CapabilityContext } from './activities/chat/middleware/capabilities.js';
|
|
5
5
|
import { InterruptSubmissionError } from './interrupts.js';
|
|
6
6
|
import { BilledUsage, BillingUnit, CompletionTokensDetails, PromptTokensDetails, ProviderUsageDetails, TokenUsage, UsageCostBreakdown } from '@tanstack/ai-event-client';
|
|
7
|
-
import { BaseEvent as AGUIBaseEvent, CustomEvent as AGUICustomEvent, Interrupt as AGUIInterrupt, MessagesSnapshotEvent as AGUIMessagesSnapshotEvent, ReasoningEncryptedValueEvent as AGUIReasoningEncryptedValueEvent, ReasoningEndEvent as AGUIReasoningEndEvent, ReasoningMessageContentEvent as AGUIReasoningMessageContentEvent, ReasoningMessageEndEvent as AGUIReasoningMessageEndEvent, ReasoningMessageStartEvent as AGUIReasoningMessageStartEvent, ReasoningStartEvent as AGUIReasoningStartEvent, ResumeEntry as AGUIResumeEntry, RunErrorEvent as AGUIRunErrorEvent, RunFinishedEvent as AGUIRunFinishedEvent, RunFinishedOutcome as AGUIRunFinishedOutcome, RunStartedEvent as AGUIRunStartedEvent, StateDeltaEvent as AGUIStateDeltaEvent, StateSnapshotEvent as AGUIStateSnapshotEvent, StepFinishedEvent as AGUIStepFinishedEvent, StepStartedEvent as AGUIStepStartedEvent, TextMessageContentEvent as AGUITextMessageContentEvent, TextMessageEndEvent as AGUITextMessageEndEvent, TextMessageStartEvent as AGUITextMessageStartEvent, ToolCallArgsEvent as AGUIToolCallArgsEvent, ToolCallEndEvent as AGUIToolCallEndEvent, ToolCallResultEvent as AGUIToolCallResultEvent, ToolCallStartEvent as AGUIToolCallStartEvent, EventType } from '@ag-ui/core';
|
|
7
|
+
import { ActivityDeltaEvent as AGUIActivityDeltaEvent, ActivitySnapshotEvent as AGUIActivitySnapshotEvent, AudioPart as AGUIAudioPart, BaseEvent as AGUIBaseEvent, ContentPart as AGUIContentPart, CustomEvent as AGUICustomEvent, DataSource as AGUIDataSource, DocumentPart as AGUIDocumentPart, FileSource as AGUIFileSource, ImagePart as AGUIImagePart, Interrupt as AGUIInterrupt, MessagesSnapshotEvent as AGUIMessagesSnapshotEvent, ReasoningEncryptedValueEvent as AGUIReasoningEncryptedValueEvent, ReasoningEndEvent as AGUIReasoningEndEvent, RawEvent as AGUIRawEvent, ReasoningMessageChunkEvent as AGUIReasoningMessageChunkEvent, ReasoningMessageContentEvent as AGUIReasoningMessageContentEvent, ReasoningMessageEndEvent as AGUIReasoningMessageEndEvent, ReasoningMessageStartEvent as AGUIReasoningMessageStartEvent, ReasoningStartEvent as AGUIReasoningStartEvent, ResumeEntry as AGUIResumeEntry, RunErrorEvent as AGUIRunErrorEvent, RunFinishedEvent as AGUIRunFinishedEvent, RunFinishedOutcome as AGUIRunFinishedOutcome, RunStartedEvent as AGUIRunStartedEvent, StateDeltaEvent as AGUIStateDeltaEvent, StateSnapshotEvent as AGUIStateSnapshotEvent, StepFinishedEvent as AGUIStepFinishedEvent, StepStartedEvent as AGUIStepStartedEvent, SubagentErrorEvent as AGUISubagentErrorEvent, SubagentFinishedEvent as AGUISubagentFinishedEvent, SubagentFinishedSuspendedOutcome as AGUISubagentFinishedSuspendedOutcome, SubagentInfo as AGUISubagentInfo, SubagentRunId as AGUISubagentRunId, SubagentStartedEvent as AGUISubagentStartedEvent, TextMessageChunkEvent as AGUITextMessageChunkEvent, TextMessageContentEvent as AGUITextMessageContentEvent, TextMessageEndEvent as AGUITextMessageEndEvent, TextMessageStartEvent as AGUITextMessageStartEvent, ToolCall as AGUIToolCall, ToolCallArgsEvent as AGUIToolCallArgsEvent, ToolCallChunkEvent as AGUIToolCallChunkEvent, ToolCallEndEvent as AGUIToolCallEndEvent, ToolCallResultEvent as AGUIToolCallResultEvent, ToolCallStartEvent as AGUIToolCallStartEvent, UrlSource as AGUIUrlSource, VideoPart as AGUIVideoPart, EventType } from '@ag-ui/core';
|
|
8
8
|
import { SpecTokenUsage, TokenUsageLeftover } from './utilities/ag-ui-usage.js';
|
|
9
|
+
import { SubagentWireInfo } from './utilities/subagent-wire.js';
|
|
9
10
|
export type { ProviderTool } from './tools/provider-tool.js';
|
|
10
11
|
/**
|
|
11
12
|
* Tool call states - track the lifecycle of a tool call
|
|
@@ -87,13 +88,8 @@ export type SchemaInput = StandardJSONSchemaV1<any, any> | StandardSchemaV1<any,
|
|
|
87
88
|
* JSON Schema at compile time.
|
|
88
89
|
*/
|
|
89
90
|
export type InferSchemaType<T> = T extends StandardJSONSchemaV1<infer TInput, unknown> ? TInput : T extends StandardSchemaV1<infer TInput, unknown> ? TInput : unknown;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
type: 'function';
|
|
93
|
-
function: {
|
|
94
|
-
name: string;
|
|
95
|
-
arguments: string;
|
|
96
|
-
};
|
|
91
|
+
/** AG-UI `ToolCall` with typed metadata. `function.arguments` is a JSON string. */
|
|
92
|
+
export interface ToolCall<TMetadata = unknown> extends Omit<AGUIToolCall, 'metadata'> {
|
|
97
93
|
/** Provider-specific metadata to carry through the tool call lifecycle.
|
|
98
94
|
* Typed per-adapter via `TToolCallMetadata`. For example,
|
|
99
95
|
* `@tanstack/ai-gemini` sets this to `{ thoughtSignature?: string }`. */
|
|
@@ -119,99 +115,60 @@ export interface ProviderExecutedToolMetadata {
|
|
|
119
115
|
[key: string]: unknown;
|
|
120
116
|
}
|
|
121
117
|
/**
|
|
122
|
-
* Supported input modality types for multimodal content
|
|
123
|
-
* -
|
|
124
|
-
* - 'image': Image content (base64 or URL)
|
|
125
|
-
* - 'audio': Audio content (base64 or URL)
|
|
126
|
-
* - 'video': Video content (base64 or URL)
|
|
127
|
-
* - 'document': Document content like PDFs (base64 or URL)
|
|
118
|
+
* Supported input modality types for multimodal content: the `type` of each
|
|
119
|
+
* AG-UI `ContentPart` (text, image, audio, video, document).
|
|
128
120
|
*/
|
|
129
|
-
export type Modality = '
|
|
121
|
+
export type Modality = AGUIContentPart['type'];
|
|
130
122
|
/**
|
|
131
|
-
*
|
|
132
|
-
* Requires a mimeType to ensure providers receive proper content type information.
|
|
123
|
+
* Inline base64 content. AG-UI `DataSource`: `mimeType` is required.
|
|
133
124
|
*/
|
|
134
|
-
export interface ContentPartDataSource {
|
|
135
|
-
/**
|
|
136
|
-
* Indicates this is inline data content.
|
|
137
|
-
*/
|
|
138
|
-
type: 'data';
|
|
139
|
-
/**
|
|
140
|
-
* The base64-encoded content value.
|
|
141
|
-
*/
|
|
142
|
-
value: string;
|
|
143
|
-
/**
|
|
144
|
-
* The MIME type of the content (e.g., 'image/png', 'audio/wav').
|
|
145
|
-
* Required for data sources to ensure proper handling by providers.
|
|
146
|
-
*/
|
|
147
|
-
mimeType: string;
|
|
125
|
+
export interface ContentPartDataSource extends AGUIDataSource {
|
|
148
126
|
}
|
|
149
127
|
/**
|
|
150
|
-
*
|
|
151
|
-
* mimeType is optional as it can often be inferred from the URL or response headers.
|
|
128
|
+
* URL-referenced content. AG-UI `UrlSource`: `mimeType` is optional.
|
|
152
129
|
*/
|
|
153
|
-
export interface ContentPartUrlSource {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
*/
|
|
161
|
-
value: string;
|
|
162
|
-
/**
|
|
163
|
-
* Optional MIME type hint for cases where providers can't infer it from the URL.
|
|
164
|
-
*/
|
|
165
|
-
mimeType?: string;
|
|
130
|
+
export interface ContentPartUrlSource extends AGUIUrlSource {
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* A provider-issued file handle (Files API). AG-UI `FileSource`: the handle
|
|
134
|
+
* is opaque, do not fetch or parse it.
|
|
135
|
+
*/
|
|
136
|
+
export interface ContentPartFileSource extends AGUIFileSource {
|
|
166
137
|
}
|
|
167
138
|
/**
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
* - For 'data' sources: mimeType is required
|
|
171
|
-
* - For 'url' sources: mimeType is optional
|
|
139
|
+
* Where a media part's bytes come from: inline data, a URL, or a provider
|
|
140
|
+
* file handle. Same members as AG-UI `PartSource`.
|
|
172
141
|
*/
|
|
173
|
-
export type ContentPartSource = ContentPartDataSource | ContentPartUrlSource;
|
|
142
|
+
export type ContentPartSource = ContentPartDataSource | ContentPartUrlSource | ContentPartFileSource;
|
|
174
143
|
/**
|
|
175
|
-
* Image content part for multimodal messages.
|
|
144
|
+
* Image content part for multimodal messages. AG-UI `ImagePart` with typed metadata.
|
|
176
145
|
* @template TMetadata - Provider-specific metadata type (e.g., OpenAI's detail level)
|
|
177
146
|
*/
|
|
178
|
-
export interface ImagePart<TMetadata = unknown> {
|
|
179
|
-
type: 'image';
|
|
180
|
-
/** Source of the image content */
|
|
181
|
-
source: ContentPartSource;
|
|
147
|
+
export interface ImagePart<TMetadata = unknown> extends AGUIImagePart {
|
|
182
148
|
/** Provider-specific metadata (e.g., OpenAI's detail: 'auto' | 'low' | 'high') */
|
|
183
149
|
metadata?: TMetadata;
|
|
184
150
|
}
|
|
185
151
|
/**
|
|
186
|
-
* Audio content part for multimodal messages.
|
|
152
|
+
* Audio content part for multimodal messages. AG-UI `AudioPart` with typed metadata.
|
|
187
153
|
* @template TMetadata - Provider-specific metadata type
|
|
188
154
|
*/
|
|
189
|
-
export interface AudioPart<TMetadata = unknown> {
|
|
190
|
-
type: 'audio';
|
|
191
|
-
/** Source of the audio content */
|
|
192
|
-
source: ContentPartSource;
|
|
155
|
+
export interface AudioPart<TMetadata = unknown> extends AGUIAudioPart {
|
|
193
156
|
/** Provider-specific metadata (e.g., format, sample rate) */
|
|
194
157
|
metadata?: TMetadata;
|
|
195
158
|
}
|
|
196
159
|
/**
|
|
197
|
-
* Video content part for multimodal messages.
|
|
160
|
+
* Video content part for multimodal messages. AG-UI `VideoPart` with typed metadata.
|
|
198
161
|
* @template TMetadata - Provider-specific metadata type
|
|
199
162
|
*/
|
|
200
|
-
export interface VideoPart<TMetadata = unknown> {
|
|
201
|
-
type: 'video';
|
|
202
|
-
/** Source of the video content */
|
|
203
|
-
source: ContentPartSource;
|
|
163
|
+
export interface VideoPart<TMetadata = unknown> extends AGUIVideoPart {
|
|
204
164
|
/** Provider-specific metadata (e.g., duration, resolution) */
|
|
205
165
|
metadata?: TMetadata;
|
|
206
166
|
}
|
|
207
167
|
/**
|
|
208
|
-
* Document content part for multimodal messages (e.g., PDFs).
|
|
168
|
+
* Document content part for multimodal messages (e.g., PDFs). AG-UI `DocumentPart` with typed metadata.
|
|
209
169
|
* @template TMetadata - Provider-specific metadata type (e.g., Anthropic's media_type)
|
|
210
170
|
*/
|
|
211
|
-
export interface DocumentPart<TMetadata = unknown> {
|
|
212
|
-
type: 'document';
|
|
213
|
-
/** Source of the document content */
|
|
214
|
-
source: ContentPartSource;
|
|
171
|
+
export interface DocumentPart<TMetadata = unknown> extends AGUIDocumentPart {
|
|
215
172
|
/** Provider-specific metadata (e.g., media_type for PDFs) */
|
|
216
173
|
metadata?: TMetadata;
|
|
217
174
|
}
|
|
@@ -360,6 +317,28 @@ export interface StructuredOutputPart<TData = unknown> {
|
|
|
360
317
|
/** Populated when `status === 'error'`. */
|
|
361
318
|
errorMessage?: string;
|
|
362
319
|
}
|
|
320
|
+
export type SubagentStatus = 'running' | 'finished' | 'error' | 'suspended';
|
|
321
|
+
/**
|
|
322
|
+
* One child invocation as the client sees it. AG-UI `SubagentInfo` names the
|
|
323
|
+
* child; the other AG-UI fields come from its `SUBAGENT_STARTED`,
|
|
324
|
+
* `SUBAGENT_FINISHED` and `SUBAGENT_ERROR` events. `id` is the AG-UI
|
|
325
|
+
* `subagentRunId`. `status`, `parentRunId` and `messages` are client state the
|
|
326
|
+
* spec does not model.
|
|
327
|
+
*/
|
|
328
|
+
export interface SubagentHandleData extends AGUISubagentInfo, Pick<AGUISubagentStartedEvent, 'parentSubagentRunId' | 'parentToolCallId' | 'metadata'> {
|
|
329
|
+
id: AGUISubagentRunId;
|
|
330
|
+
status: SubagentStatus;
|
|
331
|
+
/** The parent chat run that started this child. */
|
|
332
|
+
parentRunId?: string;
|
|
333
|
+
/** Interrupts this child raised, while `status` is `'suspended'`. */
|
|
334
|
+
interruptIds?: AGUISubagentFinishedSuspendedOutcome['interruptIds'];
|
|
335
|
+
messages: Array<UIMessage>;
|
|
336
|
+
error?: Pick<AGUISubagentErrorEvent, 'message' | 'code'>;
|
|
337
|
+
}
|
|
338
|
+
export interface SubagentPart {
|
|
339
|
+
type: 'subagent';
|
|
340
|
+
subagent: SubagentHandleData;
|
|
341
|
+
}
|
|
363
342
|
export interface UIResourcePart {
|
|
364
343
|
type: 'ui-resource';
|
|
365
344
|
/** The ui:// resource object in MCP-native shape — fed straight to the renderer. */
|
|
@@ -381,7 +360,7 @@ export interface UIResourcePart {
|
|
|
381
360
|
* Currently always `undefined` — nothing populates this field yet. */
|
|
382
361
|
meta?: Record<string, unknown>;
|
|
383
362
|
}
|
|
384
|
-
export type MessagePart<TData = unknown> = TextPart | ImagePart | AudioPart | VideoPart | DocumentPart | ToolCallPart | ToolResultPart | ThinkingPart | StructuredOutputPart<TData> | UIResourcePart;
|
|
363
|
+
export type MessagePart<TData = unknown> = TextPart | ImagePart | AudioPart | VideoPart | DocumentPart | ToolCallPart | ToolResultPart | ThinkingPart | StructuredOutputPart<TData> | UIResourcePart | SubagentPart;
|
|
385
364
|
/**
|
|
386
365
|
* Shape of `metadata.tanstack` on a message.
|
|
387
366
|
* `createdAt` is an ISO-8601 string.
|
|
@@ -389,6 +368,10 @@ export type MessagePart<TData = unknown> = TextPart | ImagePart | AudioPart | Vi
|
|
|
389
368
|
export interface TanStackMessageMetadata {
|
|
390
369
|
createdAt?: string;
|
|
391
370
|
model?: string;
|
|
371
|
+
/** Parent chat run that produced this assistant message. */
|
|
372
|
+
runId?: string;
|
|
373
|
+
/** Card data on a child wire message. See `uiMessagesToWire`. */
|
|
374
|
+
subagent?: SubagentWireInfo;
|
|
392
375
|
/** Thinking signature for a `role: 'reasoning'` fan-out message. */
|
|
393
376
|
signature?: string;
|
|
394
377
|
/** Per-tool-call provider metadata keyed by tool call id (e.g. Gemini thoughtSignature). */
|
|
@@ -907,6 +890,12 @@ export interface TextOptions<TProviderOptionsSuperset extends Record<string, any
|
|
|
907
890
|
* Surfaced for observability/middleware; not consumed by the LLM call.
|
|
908
891
|
*/
|
|
909
892
|
parentRunId?: string;
|
|
893
|
+
/**
|
|
894
|
+
* AG-UI subagent run id when this chat runs as a child of another run.
|
|
895
|
+
* A child `chat()` passes `ctx.subagentRunId`. Middleware reads it as
|
|
896
|
+
* `ctx.subagentRunId`. Absent on a top-level run.
|
|
897
|
+
*/
|
|
898
|
+
subagentRunId?: string;
|
|
910
899
|
/** Application state mirrored in a STATE_SNAPSHOT before an interrupt terminal. */
|
|
911
900
|
state?: unknown;
|
|
912
901
|
/**
|
|
@@ -1046,13 +1035,10 @@ export interface TextMessageEndEvent extends AGUITextMessageEndEvent {
|
|
|
1046
1035
|
/**
|
|
1047
1036
|
* Emitted when a tool call starts.
|
|
1048
1037
|
*
|
|
1049
|
-
* @ag-ui/core provides: `toolCallId`, `toolCallName`, `parentMessageId
|
|
1050
|
-
*
|
|
1051
|
-
* Field shapes are taken from AG-UI via `Pick` (not `extends`) so Zod
|
|
1052
|
-
* `.passthrough()` index signatures do not pollute the StreamChunk
|
|
1053
|
-
* discriminated union — required for {@link KnownCustomEvent} narrowing.
|
|
1038
|
+
* @ag-ui/core provides: `toolCallId`, `toolCallName`, `parentMessageId?`,
|
|
1039
|
+
* `subagentRunId?`
|
|
1054
1040
|
*/
|
|
1055
|
-
export interface ToolCallStartEvent extends
|
|
1041
|
+
export interface ToolCallStartEvent extends Omit<AGUIToolCallStartEvent, 'type'> {
|
|
1056
1042
|
type: 'TOOL_CALL_START';
|
|
1057
1043
|
/** Alias of `toolCallName`. Kept so existing stream readers still compile. */
|
|
1058
1044
|
toolName?: string;
|
|
@@ -1069,11 +1055,9 @@ export interface ToolCallArgsEvent extends AGUIToolCallArgsEvent {
|
|
|
1069
1055
|
/**
|
|
1070
1056
|
* Emitted when a tool call completes.
|
|
1071
1057
|
*
|
|
1072
|
-
* @ag-ui/core provides: `toolCallId`
|
|
1073
|
-
*
|
|
1074
|
-
* Same `Pick` (not `extends`) rationale as {@link ToolCallStartEvent}.
|
|
1058
|
+
* @ag-ui/core provides: `toolCallId`, `subagentRunId?`
|
|
1075
1059
|
*/
|
|
1076
|
-
export interface ToolCallEndEvent extends
|
|
1060
|
+
export interface ToolCallEndEvent extends Omit<AGUIToolCallEndEvent, 'type'> {
|
|
1077
1061
|
type: 'TOOL_CALL_END';
|
|
1078
1062
|
/** Parsed tool arguments when the adapter already parsed them. */
|
|
1079
1063
|
input?: unknown;
|
|
@@ -1130,12 +1114,9 @@ export interface StateDeltaEvent extends AGUIStateDeltaEvent {
|
|
|
1130
1114
|
/**
|
|
1131
1115
|
* Custom event for extensibility.
|
|
1132
1116
|
*
|
|
1133
|
-
* @ag-ui/core provides: `name`, `value`
|
|
1134
|
-
*
|
|
1135
|
-
* Uses `Pick` (not `extends`) so the Zod passthrough index signature does not
|
|
1136
|
-
* erase discriminant property access on {@link KnownCustomEvent} unions.
|
|
1117
|
+
* @ag-ui/core provides: `name`, `value`, `subagentRunId?`
|
|
1137
1118
|
*/
|
|
1138
|
-
export interface CustomEvent extends
|
|
1119
|
+
export interface CustomEvent extends Omit<AGUICustomEvent, 'type'> {
|
|
1139
1120
|
type: 'CUSTOM';
|
|
1140
1121
|
metadata?: Record<string, any>;
|
|
1141
1122
|
}
|
|
@@ -1420,10 +1401,51 @@ export interface ReasoningEndEvent extends AGUIReasoningEndEvent {
|
|
|
1420
1401
|
*/
|
|
1421
1402
|
export interface ReasoningEncryptedValueEvent extends AGUIReasoningEncryptedValueEvent {
|
|
1422
1403
|
}
|
|
1404
|
+
/** AG-UI 1.0 ActivitySnapshotEvent shape. */
|
|
1405
|
+
export interface ActivitySnapshotEvent extends AGUIActivitySnapshotEvent {
|
|
1406
|
+
}
|
|
1407
|
+
/** AG-UI 1.0 ActivityDeltaEvent shape. */
|
|
1408
|
+
export interface ActivityDeltaEvent extends AGUIActivityDeltaEvent {
|
|
1409
|
+
}
|
|
1410
|
+
/** AG-UI 1.0 RawEvent shape. */
|
|
1411
|
+
export interface RawEvent extends AGUIRawEvent {
|
|
1412
|
+
}
|
|
1413
|
+
/** AG-UI 1.0 TextMessageChunkEvent shape. */
|
|
1414
|
+
export interface TextMessageChunkEvent extends AGUITextMessageChunkEvent {
|
|
1415
|
+
}
|
|
1416
|
+
/** AG-UI 1.0 ToolCallChunkEvent shape. */
|
|
1417
|
+
export interface ToolCallChunkEvent extends AGUIToolCallChunkEvent {
|
|
1418
|
+
}
|
|
1419
|
+
/** AG-UI 1.0 ReasoningMessageChunkEvent shape. */
|
|
1420
|
+
export interface ReasoningMessageChunkEvent extends AGUIReasoningMessageChunkEvent {
|
|
1421
|
+
}
|
|
1423
1422
|
/**
|
|
1424
1423
|
* Union of all AG-UI events.
|
|
1425
1424
|
*/
|
|
1426
|
-
export type AGUIEvent = RunStartedEvent | RunFinishedEvent | RunErrorEvent | TextMessageStartEvent | TextMessageContentEvent | TextMessageEndEvent | ToolCallStartEvent | ToolCallArgsEvent | ToolCallEndEvent | ToolCallResultEvent | StepStartedEvent | StepFinishedEvent | MessagesSnapshotEvent | StateSnapshotEvent | StateDeltaEvent | CustomEvent | ReasoningStartEvent | ReasoningMessageStartEvent | ReasoningMessageContentEvent | ReasoningMessageEndEvent | ReasoningEndEvent | ReasoningEncryptedValueEvent;
|
|
1425
|
+
export type AGUIEvent = ActivitySnapshotEvent | ActivityDeltaEvent | RawEvent | TextMessageChunkEvent | ToolCallChunkEvent | ReasoningMessageChunkEvent | RunStartedEvent | RunFinishedEvent | RunErrorEvent | TextMessageStartEvent | TextMessageContentEvent | TextMessageEndEvent | ToolCallStartEvent | ToolCallArgsEvent | ToolCallEndEvent | ToolCallResultEvent | StepStartedEvent | StepFinishedEvent | MessagesSnapshotEvent | StateSnapshotEvent | StateDeltaEvent | CustomEvent | ReasoningStartEvent | ReasoningMessageStartEvent | ReasoningMessageContentEvent | ReasoningMessageEndEvent | ReasoningEndEvent | ReasoningEncryptedValueEvent | SubagentStartedEvent | SubagentFinishedEvent | SubagentErrorEvent;
|
|
1426
|
+
/**
|
|
1427
|
+
* A child agent started. The later chunks for that child carry the same
|
|
1428
|
+
* `subagentRunId`.
|
|
1429
|
+
*
|
|
1430
|
+
* @ag-ui/core provides: `subagentRunId`, `name`, `description?`,
|
|
1431
|
+
* `parentSubagentRunId?`, `parentToolCallId?`, `parentMessageId?`, `metadata?`
|
|
1432
|
+
*/
|
|
1433
|
+
export interface SubagentStartedEvent extends AGUISubagentStartedEvent {
|
|
1434
|
+
}
|
|
1435
|
+
/**
|
|
1436
|
+
* A child agent's segment of this run ended.
|
|
1437
|
+
*
|
|
1438
|
+
* @ag-ui/core provides: `subagentRunId`, `result?`, `outcome?`
|
|
1439
|
+
*/
|
|
1440
|
+
export interface SubagentFinishedEvent extends AGUISubagentFinishedEvent {
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* A child agent failed. The parent run can continue.
|
|
1444
|
+
*
|
|
1445
|
+
* @ag-ui/core provides: `subagentRunId`, `message`, `code?`
|
|
1446
|
+
*/
|
|
1447
|
+
export interface SubagentErrorEvent extends AGUISubagentErrorEvent {
|
|
1448
|
+
}
|
|
1427
1449
|
/**
|
|
1428
1450
|
* Chunk returned by the SDK during streaming chat completions.
|
|
1429
1451
|
* Uses the AG-UI protocol event format.
|
|
@@ -3,8 +3,9 @@ import { ContentPart, StreamChunk, ToolOutputState } from '../types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Adapter / engine yield before normalize. Public StreamChunk is spec-only.
|
|
5
5
|
* This type still allows the old extra fields.
|
|
6
|
+
* Extras never override a spec field (see WithAdapterExtras).
|
|
6
7
|
*/
|
|
7
|
-
|
|
8
|
+
type AdapterExtras = {
|
|
8
9
|
model?: string;
|
|
9
10
|
finishReason?: 'stop' | 'length' | 'content_filter' | 'tool_calls' | null;
|
|
10
11
|
usage?: any;
|
|
@@ -29,3 +30,6 @@ export type AdapterYieldChunk = StreamChunk & {
|
|
|
29
30
|
threadId?: string;
|
|
30
31
|
runId?: string;
|
|
31
32
|
};
|
|
33
|
+
type WithAdapterExtras<T> = T extends StreamChunk ? T & Omit<AdapterExtras, keyof T> : never;
|
|
34
|
+
export type AdapterYieldChunk = WithAdapterExtras<StreamChunk>;
|
|
35
|
+
export {};
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
+
import { TokenUsage as SpecTokenUsage } from '@ag-ui/core';
|
|
1
2
|
import { TokenUsage } from '../types.js';
|
|
2
3
|
/** AG-UI spec `usage[]` item (provider/model labels + token counts only). */
|
|
3
|
-
export
|
|
4
|
-
provider?: string;
|
|
5
|
-
model?: string;
|
|
6
|
-
inputTokens?: number;
|
|
7
|
-
outputTokens?: number;
|
|
8
|
-
totalTokens?: number;
|
|
9
|
-
reasoningTokens?: number;
|
|
10
|
-
cachedInputTokens?: number;
|
|
11
|
-
}
|
|
4
|
+
export type { TokenUsage as SpecTokenUsage } from '@ag-ui/core';
|
|
12
5
|
export interface ToSpecTokenUsageOptions {
|
|
13
6
|
provider?: string;
|
|
14
7
|
model?: string;
|
|
@@ -20,5 +13,12 @@ export declare function toSpecTokenUsage(usage: TokenUsage, options?: ToSpecToke
|
|
|
20
13
|
usage: Array<SpecTokenUsage>;
|
|
21
14
|
leftover?: TokenUsageLeftover;
|
|
22
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Add two usage totals, as for a parent run and its children. Numbers add
|
|
18
|
+
* up. `billed` adds up only in the same unit. `providerUsageDetails` is
|
|
19
|
+
* opaque, so the latest one stays. `@tanstack/ai-persistence` sums per-run
|
|
20
|
+
* usage with the same rules.
|
|
21
|
+
*/
|
|
22
|
+
export declare function addTokenUsage(current: TokenUsage, next: TokenUsage): TokenUsage;
|
|
23
23
|
export declare function rebuildTokenUsage(usage: unknown, leftover?: TokenUsageLeftover): TokenUsage | undefined;
|
|
24
24
|
export declare function fromSpecTokenUsage(usage: ReadonlyArray<SpecTokenUsage> | undefined, leftover?: TokenUsageLeftover): TokenUsage | undefined;
|