@tanstack/ai 0.19.1 → 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.d.ts +9 -3
- 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 +13 -4
- 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 +8 -7
- 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 +3 -0
- package/dist/esm/index.js +4 -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 +38 -16
- 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/system-prompts.d.ts +66 -0
- package/dist/esm/system-prompts.js +23 -0
- package/dist/esm/system-prompts.js.map +1 -0
- 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 +22 -7
- 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/adapter.ts +11 -2
- package/src/activities/chat/index.ts +46 -27
- package/src/activities/chat/messages.ts +2 -1
- package/src/activities/chat/middleware/types.ts +14 -11
- 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 +5 -0
- package/src/middlewares/content-guard.ts +11 -3
- package/src/middlewares/otel.ts +47 -16
- package/src/realtime/index.ts +1 -1
- package/src/system-prompts.ts +98 -0
- package/src/tools/provider-tool.ts +14 -0
- package/src/types.ts +28 -9
- package/src/utilities/ag-ui-wire.ts +2 -2
- package/src/utilities/chat-params.ts +2 -2
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single entry in `chat({ systemPrompts: [...] })`.
|
|
3
|
+
*
|
|
4
|
+
* Accepts a plain string (the common case) or a structured object that lets
|
|
5
|
+
* providers attach typed metadata to the prompt — e.g. Anthropic
|
|
6
|
+
* `cache_control` for prompt caching, future per-prompt safety overrides for
|
|
7
|
+
* Gemini, etc.
|
|
8
|
+
*
|
|
9
|
+
* At the chat call site, `metadata` is narrowed by the adapter via
|
|
10
|
+
* `~types['systemPromptMetadata']`. Providers that don't declare one inherit
|
|
11
|
+
* the default `never`, which makes the field carry no meaningful value: TS
|
|
12
|
+
* only accepts `undefined` there, and provider-foreign metadata that reaches
|
|
13
|
+
* an adapter via JS / `as any` is silently dropped, never written to the
|
|
14
|
+
* wire. For type-safe per-provider metadata, refer to the provider's
|
|
15
|
+
* `<Provider>SystemPromptMetadata` interface (e.g. `AnthropicSystemPromptMetadata`).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // The 90% case — plain strings work everywhere.
|
|
19
|
+
* systemPrompts: ['Be concise.', 'Cite sources.']
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* // Provider-specific metadata via the object form. No `satisfies` cast
|
|
23
|
+
* // is needed — the adapter narrows the `metadata` field's type at the
|
|
24
|
+
* // call site so users get autocomplete and structural checking
|
|
25
|
+
* // automatically.
|
|
26
|
+
* import { anthropicText } from '@tanstack/ai-anthropic'
|
|
27
|
+
*
|
|
28
|
+
* chat({
|
|
29
|
+
* adapter: anthropicText(),
|
|
30
|
+
* systemPrompts: [
|
|
31
|
+
* {
|
|
32
|
+
* content: 'Stable instructions — cache me.',
|
|
33
|
+
* metadata: { cache_control: { type: 'ephemeral' } },
|
|
34
|
+
* },
|
|
35
|
+
* 'Volatile per-request instruction.',
|
|
36
|
+
* ],
|
|
37
|
+
* })
|
|
38
|
+
*/
|
|
39
|
+
export type SystemPrompt<TMetadata = unknown> =
|
|
40
|
+
| string
|
|
41
|
+
| {
|
|
42
|
+
content: string
|
|
43
|
+
metadata?: TMetadata
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Normalised shape adapters see after the chat layer turns string entries
|
|
48
|
+
* into `{ content }` objects. Adapters call `normalizeSystemPrompts` once at
|
|
49
|
+
* the top of their option-mapping pipeline so the rest of the code only has
|
|
50
|
+
* to handle one shape.
|
|
51
|
+
*/
|
|
52
|
+
export interface NormalizedSystemPrompt<TMetadata = unknown> {
|
|
53
|
+
content: string
|
|
54
|
+
metadata?: TMetadata
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Normalise the public `systemPrompts` shape (`Array<string | { content, metadata? }>`)
|
|
59
|
+
* to a homogenous `Array<{ content, metadata? }>`. Adapters use this so they
|
|
60
|
+
* don't have to type-narrow string vs object inline.
|
|
61
|
+
*
|
|
62
|
+
* Returns an empty array (never `undefined`) so callers can chain `.map` /
|
|
63
|
+
* `.join` without an extra null check.
|
|
64
|
+
*
|
|
65
|
+
* Throws a `TypeError` (naming the offending index) if an object-form entry's
|
|
66
|
+
* `content` isn't a string. Public API boundary — callers reaching this
|
|
67
|
+
* function through `as any` / external JS would otherwise stream a literal
|
|
68
|
+
* `"undefined"` into the model's system prompt with no signal.
|
|
69
|
+
*/
|
|
70
|
+
export function normalizeSystemPrompts<TMetadata = unknown>(
|
|
71
|
+
// Accept the wide public shape (`SystemPrompt<unknown>`) regardless of the
|
|
72
|
+
// caller's `TMetadata`. Adapters know their own metadata shape; the
|
|
73
|
+
// generic narrows the *output* so adapter code can read `p.metadata.X`
|
|
74
|
+
// without an additional cast.
|
|
75
|
+
prompts: ReadonlyArray<SystemPrompt> | undefined,
|
|
76
|
+
): Array<NormalizedSystemPrompt<TMetadata>> {
|
|
77
|
+
if (!prompts || prompts.length === 0) return []
|
|
78
|
+
return prompts.map((p, i) => {
|
|
79
|
+
if (typeof p === 'string') return { content: p }
|
|
80
|
+
// Defence in depth: TypeScript narrows `p` to the object arm here, but
|
|
81
|
+
// this function is a public API boundary that callers can reach via
|
|
82
|
+
// plain JS or `as any`. Re-validate at runtime so we never stream a
|
|
83
|
+
// literal `"undefined"` into the model.
|
|
84
|
+
const candidate = p as unknown
|
|
85
|
+
if (candidate === null || typeof candidate !== 'object') {
|
|
86
|
+
throw new TypeError(
|
|
87
|
+
`systemPrompts[${i}]: expected a string or { content, metadata? }, got ${candidate === null ? 'null' : typeof candidate}`,
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
const { content } = candidate as { content?: unknown }
|
|
91
|
+
if (typeof content !== 'string') {
|
|
92
|
+
throw new TypeError(
|
|
93
|
+
`systemPrompts[${i}]: content must be a string, got ${typeof content}`,
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
return p as NormalizedSystemPrompt<TMetadata>
|
|
97
|
+
})
|
|
98
|
+
}
|
|
@@ -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
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
StandardSchemaV1,
|
|
4
4
|
} from '@standard-schema/spec'
|
|
5
5
|
import type { InternalLogger } from './logger/internal-logger'
|
|
6
|
+
import type { SystemPrompt } from './system-prompts'
|
|
6
7
|
import type {
|
|
7
8
|
BaseEvent as AGUIBaseEvent,
|
|
8
9
|
CustomEvent as AGUICustomEvent,
|
|
@@ -585,7 +586,9 @@ export interface Tool<
|
|
|
585
586
|
* return weather; // Can return object or string
|
|
586
587
|
* }
|
|
587
588
|
*/
|
|
588
|
-
execute?:
|
|
589
|
+
execute?:
|
|
590
|
+
| ((args: any, context?: ToolExecutionContext) => Promise<any> | any)
|
|
591
|
+
| undefined
|
|
589
592
|
|
|
590
593
|
/** If true, tool execution requires user approval before running. Works with both server and client tools. */
|
|
591
594
|
needsApproval?: boolean
|
|
@@ -594,7 +597,7 @@ export interface Tool<
|
|
|
594
597
|
lazy?: boolean
|
|
595
598
|
|
|
596
599
|
/** Additional metadata for adapters or custom extensions */
|
|
597
|
-
metadata?: Record<string, any>
|
|
600
|
+
metadata?: Record<string, any> | undefined
|
|
598
601
|
}
|
|
599
602
|
|
|
600
603
|
export interface ToolConfig {
|
|
@@ -728,8 +731,22 @@ export interface TextOptions<
|
|
|
728
731
|
> {
|
|
729
732
|
model: string
|
|
730
733
|
messages: Array<ModelMessage>
|
|
731
|
-
tools?: Array<Tool<any, any, any>>
|
|
732
|
-
|
|
734
|
+
tools?: Array<Tool<any, any, any>> | undefined
|
|
735
|
+
/**
|
|
736
|
+
* System prompts to include with the request.
|
|
737
|
+
*
|
|
738
|
+
* Accepts plain strings (the common case) or `{ content, metadata }`
|
|
739
|
+
* objects that let providers attach typed metadata (e.g. Anthropic
|
|
740
|
+
* `cache_control` for prompt caching) per prompt. At the chat call site
|
|
741
|
+
* the adapter narrows `metadata`'s type via `~types['systemPromptMetadata']`
|
|
742
|
+
* — providers that don't declare one default to `never`, which makes the
|
|
743
|
+
* field carry no meaningful value (TypeScript will only accept
|
|
744
|
+
* `undefined` there). Provider-foreign metadata that reaches an adapter
|
|
745
|
+
* via JS / `as any` is silently dropped, never written to the wire.
|
|
746
|
+
*
|
|
747
|
+
* @see SystemPrompt
|
|
748
|
+
*/
|
|
749
|
+
systemPrompts?: Array<SystemPrompt>
|
|
733
750
|
agentLoopStrategy?: AgentLoopStrategy
|
|
734
751
|
/**
|
|
735
752
|
* Controls the randomness of the output.
|
|
@@ -776,7 +793,7 @@ export interface TextOptions<
|
|
|
776
793
|
* - Anthropic: `metadata` (Record<string, any>) - includes optional user_id (max 256 chars)
|
|
777
794
|
* - Gemini: Not directly available in TextProviderOptions
|
|
778
795
|
*/
|
|
779
|
-
metadata?: Record<string, any>
|
|
796
|
+
metadata?: Record<string, any> | undefined
|
|
780
797
|
modelOptions?: TProviderOptionsForModel
|
|
781
798
|
request?: Request | RequestInit
|
|
782
799
|
|
|
@@ -923,10 +940,12 @@ export interface RunErrorEvent extends AGUIRunErrorEvent {
|
|
|
923
940
|
* @deprecated Use top-level `message` and `code` fields instead.
|
|
924
941
|
* Kept for backward compatibility.
|
|
925
942
|
*/
|
|
926
|
-
error?:
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
943
|
+
error?:
|
|
944
|
+
| {
|
|
945
|
+
message: string
|
|
946
|
+
code?: string | undefined
|
|
947
|
+
}
|
|
948
|
+
| undefined
|
|
930
949
|
}
|
|
931
950
|
|
|
932
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
|
}
|