@tanstack/ai 0.20.0 → 0.20.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/dist/esm/activities/chat/adapter.js +3 -1
- package/dist/esm/activities/chat/adapter.js.map +1 -1
- package/dist/esm/activities/chat/index.d.ts +3 -3
- package/dist/esm/activities/chat/index.js +46 -18
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/messages.js +1 -1
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/middleware/compose.js +2 -0
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +5 -5
- package/dist/esm/activities/chat/stream/processor.d.ts +8 -8
- package/dist/esm/activities/chat/stream/processor.js +29 -21
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/stream/strategies.d.ts +3 -3
- package/dist/esm/activities/chat/stream/strategies.js +4 -4
- package/dist/esm/activities/chat/stream/strategies.js.map +1 -1
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js +5 -0
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +1 -1
- package/dist/esm/activities/chat/tools/schema-converter.d.ts +1 -1
- package/dist/esm/activities/chat/tools/schema-converter.js +36 -35
- package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +2 -2
- package/dist/esm/activities/chat/tools/tool-calls.js +17 -9
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-definition.js +1 -1
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
- package/dist/esm/activities/generateAudio/adapter.js +3 -1
- package/dist/esm/activities/generateAudio/adapter.js.map +1 -1
- package/dist/esm/activities/generateAudio/index.d.ts +5 -1
- package/dist/esm/activities/generateAudio/index.js.map +1 -1
- package/dist/esm/activities/generateImage/adapter.js +3 -1
- package/dist/esm/activities/generateImage/adapter.js.map +1 -1
- package/dist/esm/activities/generateImage/index.js +5 -0
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/adapter.js +3 -1
- package/dist/esm/activities/generateSpeech/adapter.js.map +1 -1
- package/dist/esm/activities/generateTranscription/adapter.js +3 -1
- package/dist/esm/activities/generateTranscription/adapter.js.map +1 -1
- package/dist/esm/activities/generateVideo/adapter.js +3 -1
- package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
- package/dist/esm/activities/stream-generation-result.js +6 -2
- package/dist/esm/activities/stream-generation-result.js.map +1 -1
- package/dist/esm/activities/summarize/adapter.js +3 -1
- package/dist/esm/activities/summarize/adapter.js.map +1 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.d.ts +1 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.js +5 -0
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
- package/dist/esm/activities/summarize/index.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/logger/internal-logger.js +2 -0
- package/dist/esm/logger/internal-logger.js.map +1 -1
- package/dist/esm/middlewares/content-guard.js +5 -4
- package/dist/esm/middlewares/content-guard.js.map +1 -1
- package/dist/esm/middlewares/otel.js +24 -14
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/realtime/index.d.ts +1 -1
- package/dist/esm/realtime/index.js.map +1 -1
- package/dist/esm/tools/provider-tool.d.ts +9 -0
- package/dist/esm/tools/provider-tool.js +7 -0
- package/dist/esm/tools/provider-tool.js.map +1 -0
- package/dist/esm/types.d.ts +6 -6
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
- package/dist/esm/utilities/chat-params.js.map +1 -1
- package/package.json +2 -2
- package/src/activities/chat/index.ts +34 -26
- package/src/activities/chat/messages.ts +2 -1
- package/src/activities/chat/middleware/types.ts +11 -9
- package/src/activities/chat/stream/processor.ts +19 -19
- package/src/activities/chat/stream/strategies.ts +3 -3
- package/src/activities/chat/tools/schema-converter.ts +77 -52
- package/src/activities/chat/tools/tool-calls.ts +18 -11
- package/src/activities/chat/tools/tool-definition.ts +6 -1
- package/src/activities/generateAudio/index.ts +5 -4
- package/src/activities/generateImage/index.ts +5 -0
- package/src/activities/stream-generation-result.ts +11 -2
- package/src/activities/summarize/chat-stream-summarize.ts +5 -2
- package/src/activities/summarize/index.ts +2 -2
- package/src/index.ts +1 -0
- package/src/middlewares/content-guard.ts +11 -3
- package/src/middlewares/otel.ts +25 -14
- package/src/realtime/index.ts +1 -1
- package/src/tools/provider-tool.ts +14 -0
- package/src/types.ts +12 -8
- package/src/utilities/ag-ui-wire.ts +2 -2
- package/src/utilities/chat-params.ts +2 -2
|
@@ -55,12 +55,21 @@ export async function* streamGenerationResult<TResult>(
|
|
|
55
55
|
}
|
|
56
56
|
} catch (error: unknown) {
|
|
57
57
|
const payload = toRunErrorPayload(error, 'Generation failed')
|
|
58
|
+
// `code` is omitted entirely when undefined so the event matches the
|
|
59
|
+
// AG-UI `code?: string` shape under `exactOptionalPropertyTypes`. The
|
|
60
|
+
// deprecated nested `error` form preserves the same conditional
|
|
61
|
+
// structure for backward compatibility.
|
|
62
|
+
const codeFields =
|
|
63
|
+
payload.code !== undefined ? { code: payload.code } : undefined
|
|
58
64
|
yield {
|
|
59
65
|
type: EventType.RUN_ERROR,
|
|
60
66
|
message: payload.message,
|
|
61
|
-
|
|
67
|
+
...codeFields,
|
|
62
68
|
// Deprecated nested form for backward compatibility
|
|
63
|
-
error:
|
|
69
|
+
error: {
|
|
70
|
+
message: payload.message,
|
|
71
|
+
...codeFields,
|
|
72
|
+
},
|
|
64
73
|
timestamp: Date.now(),
|
|
65
74
|
}
|
|
66
75
|
}
|
|
@@ -46,7 +46,7 @@ export class ChatStreamSummarizeAdapter<
|
|
|
46
46
|
> extends BaseSummarizeAdapter<TModel, TProviderOptions> {
|
|
47
47
|
readonly name: string
|
|
48
48
|
|
|
49
|
-
private textAdapter: ChatStreamCapable
|
|
49
|
+
private readonly textAdapter: ChatStreamCapable
|
|
50
50
|
|
|
51
51
|
constructor(
|
|
52
52
|
textAdapter: ChatStreamCapable,
|
|
@@ -124,7 +124,7 @@ export class ChatStreamSummarizeAdapter<
|
|
|
124
124
|
return { id, model, summary, usage }
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
async *summarizeStream(
|
|
127
|
+
override async *summarizeStream(
|
|
128
128
|
options: SummarizationOptions<TProviderOptions>,
|
|
129
129
|
): AsyncIterable<StreamChunk> {
|
|
130
130
|
const systemPrompt = this.buildSummarizationPrompt(options)
|
|
@@ -221,6 +221,9 @@ export class ChatStreamSummarizeAdapter<
|
|
|
221
221
|
case 'concise':
|
|
222
222
|
prompt += 'Provide a very concise summary in 1-2 sentences. '
|
|
223
223
|
break
|
|
224
|
+
case undefined:
|
|
225
|
+
prompt += 'Provide a clear and concise summary. '
|
|
226
|
+
break
|
|
224
227
|
default:
|
|
225
228
|
prompt += 'Provide a clear and concise summary. '
|
|
226
229
|
}
|
|
@@ -159,7 +159,7 @@ export function summarize<
|
|
|
159
159
|
|
|
160
160
|
if (stream) {
|
|
161
161
|
return runStreamingSummarize(
|
|
162
|
-
options as
|
|
162
|
+
options as SummarizeActivityOptions<
|
|
163
163
|
SummarizeAdapter<string, object>,
|
|
164
164
|
true
|
|
165
165
|
>,
|
|
@@ -167,7 +167,7 @@ export function summarize<
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
return runSummarize(
|
|
170
|
-
options as
|
|
170
|
+
options as SummarizeActivityOptions<
|
|
171
171
|
SummarizeAdapter<string, object>,
|
|
172
172
|
false
|
|
173
173
|
>,
|
package/src/index.ts
CHANGED
|
@@ -142,10 +142,15 @@ function createDeltaStrategy(
|
|
|
142
142
|
|
|
143
143
|
if (blockOnMatch) return null // drop chunk
|
|
144
144
|
|
|
145
|
+
// Strip out the previous `content` field by destructuring it away — with
|
|
146
|
+
// `exactOptionalPropertyTypes` we can't assign `content: undefined`
|
|
147
|
+
// against `content?: string`. The replacement event carries only the
|
|
148
|
+
// filtered delta.
|
|
149
|
+
const { content: _strippedContent, ...rest } = chunk
|
|
150
|
+
void _strippedContent
|
|
145
151
|
return {
|
|
146
|
-
...
|
|
152
|
+
...rest,
|
|
147
153
|
delta: filtered,
|
|
148
|
-
content: undefined,
|
|
149
154
|
} as StreamChunk
|
|
150
155
|
},
|
|
151
156
|
}
|
|
@@ -278,8 +283,11 @@ function createBufferedStrategy(
|
|
|
278
283
|
content: filtered.slice(0, safeFilteredEnd),
|
|
279
284
|
} as StreamChunk
|
|
280
285
|
|
|
286
|
+
// `pending` was empty before this push iff `emitChunk` is now the only
|
|
287
|
+
// entry — return it directly without re-indexing through `pending[0]`.
|
|
288
|
+
const wasEmpty = pending.length === 0
|
|
281
289
|
pending.push(emitChunk)
|
|
282
|
-
return
|
|
290
|
+
return wasEmpty ? emitChunk : pending
|
|
283
291
|
},
|
|
284
292
|
}
|
|
285
293
|
}
|
package/src/middlewares/otel.ts
CHANGED
|
@@ -137,8 +137,11 @@ function serializeContent(content: unknown): string {
|
|
|
137
137
|
case 'document':
|
|
138
138
|
parts.push('[document]')
|
|
139
139
|
break
|
|
140
|
+
case undefined:
|
|
141
|
+
parts.push('[unknown]')
|
|
142
|
+
break
|
|
140
143
|
default:
|
|
141
|
-
parts.push(`[${type
|
|
144
|
+
parts.push(`[${type}]`)
|
|
142
145
|
}
|
|
143
146
|
}
|
|
144
147
|
return parts.join(' ')
|
|
@@ -630,9 +633,10 @@ export function otelMiddleware(options: OtelMiddlewareOptions): ChatMiddleware {
|
|
|
630
633
|
|
|
631
634
|
if (!info.ok && info.error !== undefined) {
|
|
632
635
|
toolSpan.recordException(info.error as Exception)
|
|
636
|
+
const msg = errorMessage(info.error)
|
|
633
637
|
toolSpan.setStatus({
|
|
634
638
|
code: SpanStatusCode.ERROR,
|
|
635
|
-
message:
|
|
639
|
+
...(msg !== undefined && { message: msg }),
|
|
636
640
|
})
|
|
637
641
|
}
|
|
638
642
|
|
|
@@ -688,13 +692,16 @@ export function otelMiddleware(options: OtelMiddlewareOptions): ChatMiddleware {
|
|
|
688
692
|
|
|
689
693
|
const errType = errorTypeName(info.error)
|
|
690
694
|
const message = errorMessage(info.error)
|
|
695
|
+
const statusMessage =
|
|
696
|
+
message !== undefined ? { message } : ({} as const)
|
|
691
697
|
const exception = info.error as Exception
|
|
692
698
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
699
|
+
const iterationSpan = state.currentIterationSpan
|
|
700
|
+
if (iterationSpan) {
|
|
701
|
+
iterationSpan.recordException(exception)
|
|
702
|
+
iterationSpan.setStatus({
|
|
696
703
|
code: SpanStatusCode.ERROR,
|
|
697
|
-
|
|
704
|
+
...statusMessage,
|
|
698
705
|
})
|
|
699
706
|
safeCall('otel.onSpanEnd', () =>
|
|
700
707
|
onSpanEnd?.(
|
|
@@ -703,17 +710,17 @@ export function otelMiddleware(options: OtelMiddlewareOptions): ChatMiddleware {
|
|
|
703
710
|
ctx,
|
|
704
711
|
iteration: state.iterationCount - 1,
|
|
705
712
|
} as OtelSpanInfo<'iteration'>,
|
|
706
|
-
|
|
713
|
+
iterationSpan,
|
|
707
714
|
),
|
|
708
715
|
)
|
|
709
|
-
|
|
716
|
+
iterationSpan.end()
|
|
710
717
|
state.currentIterationSpan = null
|
|
711
718
|
}
|
|
712
719
|
|
|
713
720
|
for (const [id, entry] of state.toolSpans) {
|
|
714
721
|
const { span, toolName } = entry
|
|
715
722
|
span.recordException(exception)
|
|
716
|
-
span.setStatus({ code: SpanStatusCode.ERROR,
|
|
723
|
+
span.setStatus({ code: SpanStatusCode.ERROR, ...statusMessage })
|
|
717
724
|
safeCall('otel.onSpanEnd', () =>
|
|
718
725
|
onSpanEnd?.(
|
|
719
726
|
{
|
|
@@ -731,7 +738,10 @@ export function otelMiddleware(options: OtelMiddlewareOptions): ChatMiddleware {
|
|
|
731
738
|
}
|
|
732
739
|
|
|
733
740
|
state.rootSpan.recordException(exception)
|
|
734
|
-
state.rootSpan.setStatus({
|
|
741
|
+
state.rootSpan.setStatus({
|
|
742
|
+
code: SpanStatusCode.ERROR,
|
|
743
|
+
...statusMessage,
|
|
744
|
+
})
|
|
735
745
|
|
|
736
746
|
if (durationHistogram) {
|
|
737
747
|
durationHistogram.record(info.duration / 1000, {
|
|
@@ -763,8 +773,9 @@ export function otelMiddleware(options: OtelMiddlewareOptions): ChatMiddleware {
|
|
|
763
773
|
span.setStatus({ code: SpanStatusCode.ERROR, message: 'cancelled' })
|
|
764
774
|
}
|
|
765
775
|
|
|
766
|
-
|
|
767
|
-
|
|
776
|
+
const iterationSpan = state.currentIterationSpan
|
|
777
|
+
if (iterationSpan) {
|
|
778
|
+
closeCancelled(iterationSpan)
|
|
768
779
|
safeCall('otel.onSpanEnd', () =>
|
|
769
780
|
onSpanEnd?.(
|
|
770
781
|
{
|
|
@@ -772,10 +783,10 @@ export function otelMiddleware(options: OtelMiddlewareOptions): ChatMiddleware {
|
|
|
772
783
|
ctx,
|
|
773
784
|
iteration: state.iterationCount - 1,
|
|
774
785
|
} as OtelSpanInfo<'iteration'>,
|
|
775
|
-
|
|
786
|
+
iterationSpan,
|
|
776
787
|
),
|
|
777
788
|
)
|
|
778
|
-
|
|
789
|
+
iterationSpan.end()
|
|
779
790
|
state.currentIterationSpan = null
|
|
780
791
|
}
|
|
781
792
|
for (const [id, entry] of state.toolSpans) {
|
package/src/realtime/index.ts
CHANGED
|
@@ -23,3 +23,17 @@ export interface ProviderTool<
|
|
|
23
23
|
readonly '~provider': TProvider
|
|
24
24
|
readonly '~toolKind': TKind
|
|
25
25
|
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Attach the `ProviderTool` phantom brand to a plain `Tool`-shaped object.
|
|
29
|
+
*
|
|
30
|
+
* The brand fields (`'~provider'`, `'~toolKind'`) exist only in the type
|
|
31
|
+
* system and are never assigned at runtime, so this is a single audited
|
|
32
|
+
* type-only assertion. Use it inside adapter `xxxTool()` factories instead
|
|
33
|
+
* of `as unknown as` — the cast collapses to one named site.
|
|
34
|
+
*/
|
|
35
|
+
export function brandProviderTool<T extends ProviderTool<string, string>>(
|
|
36
|
+
tool: Omit<T, '~provider' | '~toolKind'>,
|
|
37
|
+
): T {
|
|
38
|
+
return tool as T
|
|
39
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -586,7 +586,9 @@ export interface Tool<
|
|
|
586
586
|
* return weather; // Can return object or string
|
|
587
587
|
* }
|
|
588
588
|
*/
|
|
589
|
-
execute?:
|
|
589
|
+
execute?:
|
|
590
|
+
| ((args: any, context?: ToolExecutionContext) => Promise<any> | any)
|
|
591
|
+
| undefined
|
|
590
592
|
|
|
591
593
|
/** If true, tool execution requires user approval before running. Works with both server and client tools. */
|
|
592
594
|
needsApproval?: boolean
|
|
@@ -595,7 +597,7 @@ export interface Tool<
|
|
|
595
597
|
lazy?: boolean
|
|
596
598
|
|
|
597
599
|
/** Additional metadata for adapters or custom extensions */
|
|
598
|
-
metadata?: Record<string, any>
|
|
600
|
+
metadata?: Record<string, any> | undefined
|
|
599
601
|
}
|
|
600
602
|
|
|
601
603
|
export interface ToolConfig {
|
|
@@ -729,7 +731,7 @@ export interface TextOptions<
|
|
|
729
731
|
> {
|
|
730
732
|
model: string
|
|
731
733
|
messages: Array<ModelMessage>
|
|
732
|
-
tools?: Array<Tool<any, any, any>>
|
|
734
|
+
tools?: Array<Tool<any, any, any>> | undefined
|
|
733
735
|
/**
|
|
734
736
|
* System prompts to include with the request.
|
|
735
737
|
*
|
|
@@ -791,7 +793,7 @@ export interface TextOptions<
|
|
|
791
793
|
* - Anthropic: `metadata` (Record<string, any>) - includes optional user_id (max 256 chars)
|
|
792
794
|
* - Gemini: Not directly available in TextProviderOptions
|
|
793
795
|
*/
|
|
794
|
-
metadata?: Record<string, any>
|
|
796
|
+
metadata?: Record<string, any> | undefined
|
|
795
797
|
modelOptions?: TProviderOptionsForModel
|
|
796
798
|
request?: Request | RequestInit
|
|
797
799
|
|
|
@@ -938,10 +940,12 @@ export interface RunErrorEvent extends AGUIRunErrorEvent {
|
|
|
938
940
|
* @deprecated Use top-level `message` and `code` fields instead.
|
|
939
941
|
* Kept for backward compatibility.
|
|
940
942
|
*/
|
|
941
|
-
error?:
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
943
|
+
error?:
|
|
944
|
+
| {
|
|
945
|
+
message: string
|
|
946
|
+
code?: string | undefined
|
|
947
|
+
}
|
|
948
|
+
| undefined
|
|
945
949
|
}
|
|
946
950
|
|
|
947
951
|
/**
|
|
@@ -61,7 +61,7 @@ export function uiMessagesToWire(
|
|
|
61
61
|
content:
|
|
62
62
|
parts.length > 0
|
|
63
63
|
? collectText(parts)
|
|
64
|
-
: ((msg as
|
|
64
|
+
: ((msg as { content?: string }).content ?? ''),
|
|
65
65
|
})
|
|
66
66
|
continue
|
|
67
67
|
}
|
|
@@ -72,7 +72,7 @@ export function uiMessagesToWire(
|
|
|
72
72
|
content:
|
|
73
73
|
parts.length > 0
|
|
74
74
|
? collectUserContent(parts)
|
|
75
|
-
: ((msg as
|
|
75
|
+
: ((msg as { content?: string }).content ?? ''),
|
|
76
76
|
})
|
|
77
77
|
continue
|
|
78
78
|
}
|
|
@@ -131,7 +131,7 @@ export async function chatParamsFromRequest(
|
|
|
131
131
|
'Invalid AG-UI request body. See docs/migration/ag-ui-compliance.md.',
|
|
132
132
|
{ status: 400 },
|
|
133
133
|
)
|
|
134
|
-
;(res as
|
|
134
|
+
;(res as { cause?: unknown }).cause = cause
|
|
135
135
|
throw res
|
|
136
136
|
}
|
|
137
137
|
try {
|
|
@@ -145,7 +145,7 @@ export async function chatParamsFromRequest(
|
|
|
145
145
|
'Invalid AG-UI request body. See docs/migration/ag-ui-compliance.md.',
|
|
146
146
|
{ status: 400 },
|
|
147
147
|
)
|
|
148
|
-
;(res as
|
|
148
|
+
;(res as { cause?: unknown }).cause = cause
|
|
149
149
|
throw res
|
|
150
150
|
}
|
|
151
151
|
}
|