@tanstack/ai 0.43.0 → 0.44.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/messages.js +21 -8
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/embed/adapter.d.ts +69 -0
- package/dist/esm/activities/embed/adapter.js +23 -0
- package/dist/esm/activities/embed/adapter.js.map +1 -0
- package/dist/esm/activities/embed/index.d.ts +117 -0
- package/dist/esm/activities/embed/index.js +166 -0
- package/dist/esm/activities/embed/index.js.map +1 -0
- package/dist/esm/activities/error-payload.d.ts +8 -0
- package/dist/esm/activities/error-payload.js +29 -17
- package/dist/esm/activities/error-payload.js.map +1 -1
- package/dist/esm/activities/generateAudio/index.d.ts +12 -0
- package/dist/esm/activities/generateAudio/index.js +19 -6
- package/dist/esm/activities/generateAudio/index.js.map +1 -1
- package/dist/esm/activities/generateImage/index.d.ts +12 -0
- package/dist/esm/activities/generateImage/index.js +21 -7
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +17 -1
- package/dist/esm/activities/generateSpeech/index.js +19 -6
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +17 -1
- package/dist/esm/activities/generateTranscription/index.js +19 -6
- package/dist/esm/activities/generateTranscription/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/index.d.ts +18 -0
- package/dist/esm/activities/generateVideo/index.js +54 -15
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/index.d.ts +8 -2
- package/dist/esm/activities/index.js +11 -7
- package/dist/esm/activities/middleware/types.d.ts +1 -1
- package/dist/esm/activities/rerank/adapter.d.ts +63 -0
- package/dist/esm/activities/rerank/adapter.js +23 -0
- package/dist/esm/activities/rerank/adapter.js.map +1 -0
- package/dist/esm/activities/rerank/index.d.ts +92 -0
- package/dist/esm/activities/rerank/index.js +163 -0
- package/dist/esm/activities/rerank/index.js.map +1 -0
- package/dist/esm/activities/summarize/index.d.ts +17 -1
- package/dist/esm/activities/summarize/index.js +19 -5
- package/dist/esm/activities/summarize/index.js.map +1 -1
- package/dist/esm/index.d.ts +7 -2
- package/dist/esm/index.js +5 -1
- package/dist/esm/middlewares/otel.d.ts +3 -1
- package/dist/esm/middlewares/otel.js +25 -6
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/types.d.ts +195 -0
- package/dist/esm/utilities/activity-abort.d.ts +53 -0
- package/dist/esm/utilities/activity-abort.js +150 -0
- package/dist/esm/utilities/activity-abort.js.map +1 -0
- package/dist/esm/utilities/embedding-input.d.ts +32 -0
- package/dist/esm/utilities/embedding-input.js +61 -0
- package/dist/esm/utilities/embedding-input.js.map +1 -0
- package/package.json +3 -3
- package/src/activities/chat/messages.ts +30 -1
- package/src/activities/embed/adapter.ts +112 -0
- package/src/activities/embed/index.ts +318 -0
- package/src/activities/error-payload.ts +41 -9
- package/src/activities/generateAudio/index.ts +47 -5
- package/src/activities/generateImage/index.ts +48 -5
- package/src/activities/generateSpeech/index.ts +52 -9
- package/src/activities/generateTranscription/index.ts +52 -9
- package/src/activities/generateVideo/index.ts +131 -33
- package/src/activities/index.ts +44 -0
- package/src/activities/middleware/types.ts +2 -0
- package/src/activities/rerank/adapter.ts +90 -0
- package/src/activities/rerank/index.ts +302 -0
- package/src/activities/summarize/index.ts +59 -19
- package/src/index.ts +19 -0
- package/src/middlewares/otel.ts +60 -8
- package/src/types.ts +219 -0
- package/src/utilities/activity-abort.ts +197 -0
- package/src/utilities/embedding-input.ts +83 -0
package/dist/esm/types.d.ts
CHANGED
|
@@ -259,6 +259,11 @@ export interface ModelMessage<TContent extends string | null | Array<ContentPart
|
|
|
259
259
|
* resume the SAME message bubble in place (see `@tanstack/ai-persistence`).
|
|
260
260
|
*/
|
|
261
261
|
id?: string;
|
|
262
|
+
/**
|
|
263
|
+
* Optional message creation timestamp. When present, message converters
|
|
264
|
+
* preserve it across persist → hydrate round-trips.
|
|
265
|
+
*/
|
|
266
|
+
createdAt?: Date;
|
|
262
267
|
}
|
|
263
268
|
/**
|
|
264
269
|
* Message parts - building blocks of UIMessage
|
|
@@ -1656,6 +1661,12 @@ export interface SummarizationOptions<TProviderOptions extends object = Record<s
|
|
|
1656
1661
|
* call logger.request() before the SDK call and logger.errors() in catch blocks.
|
|
1657
1662
|
*/
|
|
1658
1663
|
logger: InternalLogger;
|
|
1664
|
+
/**
|
|
1665
|
+
* Effective abort signal composed by the activity from caller `abortSignal`
|
|
1666
|
+
* and/or `timeout`. Adapters should forward this to the provider SDK when
|
|
1667
|
+
* supported. Request-specific — never store on a global client config.
|
|
1668
|
+
*/
|
|
1669
|
+
abortSignal?: AbortSignal;
|
|
1659
1670
|
}
|
|
1660
1671
|
export interface SummarizationResult {
|
|
1661
1672
|
id: string;
|
|
@@ -1663,6 +1674,69 @@ export interface SummarizationResult {
|
|
|
1663
1674
|
summary: string;
|
|
1664
1675
|
usage: TokenUsage;
|
|
1665
1676
|
}
|
|
1677
|
+
/**
|
|
1678
|
+
* Options passed to a {@link RerankAdapter}. Documents reach the adapter
|
|
1679
|
+
* already serialized to strings — the `rerank()` activity stringifies object
|
|
1680
|
+
* documents and maps results back to the original elements, so adapters never
|
|
1681
|
+
* deal with the caller's document type.
|
|
1682
|
+
*/
|
|
1683
|
+
export interface RerankOptions<TProviderOptions extends object = Record<string, unknown>> {
|
|
1684
|
+
model: string;
|
|
1685
|
+
/** The search query documents are scored against. */
|
|
1686
|
+
query: string;
|
|
1687
|
+
/** Documents to rerank, pre-serialized to strings by the activity. */
|
|
1688
|
+
documents: Array<string>;
|
|
1689
|
+
/** Return only the top N results. Passed through to the provider. */
|
|
1690
|
+
topN?: number;
|
|
1691
|
+
/** Provider-specific options forwarded by the rerank() activity. */
|
|
1692
|
+
modelOptions?: TProviderOptions;
|
|
1693
|
+
/** Forwarded to the provider request for cancellation. */
|
|
1694
|
+
abortSignal?: AbortSignal;
|
|
1695
|
+
/**
|
|
1696
|
+
* Internal logger threaded from the rerank() entry point. Adapters must call
|
|
1697
|
+
* logger.request() before the provider call and logger.errors() in catch
|
|
1698
|
+
* blocks.
|
|
1699
|
+
*/
|
|
1700
|
+
logger: InternalLogger;
|
|
1701
|
+
}
|
|
1702
|
+
/**
|
|
1703
|
+
* Provider-level rerank result. Adapters return scored indices into the
|
|
1704
|
+
* (serialized) `documents` array plus usage — never the documents themselves.
|
|
1705
|
+
* The activity attaches the original documents.
|
|
1706
|
+
*/
|
|
1707
|
+
export interface RerankAdapterResult {
|
|
1708
|
+
id: string;
|
|
1709
|
+
/** Scored results, highest relevance first, as indices into `documents`. */
|
|
1710
|
+
ranking: Array<{
|
|
1711
|
+
index: number;
|
|
1712
|
+
score: number;
|
|
1713
|
+
}>;
|
|
1714
|
+
usage: TokenUsage;
|
|
1715
|
+
}
|
|
1716
|
+
/**
|
|
1717
|
+
* Public result of the `rerank()` activity, generic over the caller's document
|
|
1718
|
+
* element type so `document` / `rerankedDocuments` carry the original values
|
|
1719
|
+
* (strings or objects), not their serialized form.
|
|
1720
|
+
*/
|
|
1721
|
+
export interface RerankResult<TDocument = string> {
|
|
1722
|
+
id: string;
|
|
1723
|
+
model: string;
|
|
1724
|
+
/** Scored results, highest relevance first. */
|
|
1725
|
+
ranking: Array<{
|
|
1726
|
+
index: number;
|
|
1727
|
+
score: number;
|
|
1728
|
+
document: TDocument;
|
|
1729
|
+
}>;
|
|
1730
|
+
/** The documents reordered by relevance — `ranking.map(r => r.document)`. */
|
|
1731
|
+
rerankedDocuments: Array<TDocument>;
|
|
1732
|
+
/**
|
|
1733
|
+
* Usage for the request. Rerank typically bills in provider-defined "search
|
|
1734
|
+
* units" (`usage.unitsBilled`) rather than tokens. Some providers (e.g.
|
|
1735
|
+
* OpenRouter) may also report `totalTokens` and `cost`; Cohere reports only
|
|
1736
|
+
* search units and leaves the token counts at 0.
|
|
1737
|
+
*/
|
|
1738
|
+
usage: TokenUsage;
|
|
1739
|
+
}
|
|
1666
1740
|
/**
|
|
1667
1741
|
* Optional role hint on a media input part (image / video / audio). Adapters
|
|
1668
1742
|
* read `metadata.role` to route the part to the provider-specific request
|
|
@@ -1761,6 +1835,12 @@ export interface ImageGenerationOptions<TProviderOptions extends object = object
|
|
|
1761
1835
|
* call logger.request() before the SDK call and logger.errors() in catch blocks.
|
|
1762
1836
|
*/
|
|
1763
1837
|
logger: InternalLogger;
|
|
1838
|
+
/**
|
|
1839
|
+
* Effective abort signal composed by the activity from caller `abortSignal`
|
|
1840
|
+
* and/or `timeout`. Adapters should forward this to the provider SDK when
|
|
1841
|
+
* supported. Request-specific — never store on a global client config.
|
|
1842
|
+
*/
|
|
1843
|
+
abortSignal?: AbortSignal;
|
|
1764
1844
|
}
|
|
1765
1845
|
/**
|
|
1766
1846
|
* Source of a generated media asset. Exactly one of `url` or `b64Json` is
|
|
@@ -1854,6 +1934,12 @@ export interface AudioGenerationOptions<TProviderOptions extends object = object
|
|
|
1854
1934
|
* catch blocks.
|
|
1855
1935
|
*/
|
|
1856
1936
|
logger: InternalLogger;
|
|
1937
|
+
/**
|
|
1938
|
+
* Effective abort signal composed by the activity from caller `abortSignal`
|
|
1939
|
+
* and/or `timeout`. Adapters should forward this to the provider SDK when
|
|
1940
|
+
* supported. Request-specific — never store on a global client config.
|
|
1941
|
+
*/
|
|
1942
|
+
abortSignal?: AbortSignal;
|
|
1857
1943
|
}
|
|
1858
1944
|
/**
|
|
1859
1945
|
* A single generated audio output
|
|
@@ -1912,6 +1998,12 @@ export interface VideoGenerationOptions<TProviderOptions extends object = object
|
|
|
1912
1998
|
* call logger.request() before the SDK call and logger.errors() in catch blocks.
|
|
1913
1999
|
*/
|
|
1914
2000
|
logger: InternalLogger;
|
|
2001
|
+
/**
|
|
2002
|
+
* Effective abort signal composed by the activity from caller `abortSignal`
|
|
2003
|
+
* and/or `timeout`. Adapters should forward this to the provider SDK when
|
|
2004
|
+
* supported. Request-specific — never store on a global client config.
|
|
2005
|
+
*/
|
|
2006
|
+
abortSignal?: AbortSignal;
|
|
1915
2007
|
}
|
|
1916
2008
|
/**
|
|
1917
2009
|
* Result of creating a video generation job.
|
|
@@ -1989,6 +2081,12 @@ export interface TTSOptions<TProviderOptions extends object = object> {
|
|
|
1989
2081
|
* catch blocks.
|
|
1990
2082
|
*/
|
|
1991
2083
|
logger: InternalLogger;
|
|
2084
|
+
/**
|
|
2085
|
+
* Effective abort signal composed by the activity from caller `abortSignal`
|
|
2086
|
+
* and/or `timeout`. Adapters should forward this to the provider SDK when
|
|
2087
|
+
* supported. Request-specific — never store on a global client config.
|
|
2088
|
+
*/
|
|
2089
|
+
abortSignal?: AbortSignal;
|
|
1992
2090
|
}
|
|
1993
2091
|
/**
|
|
1994
2092
|
* Result of text-to-speech generation.
|
|
@@ -2035,6 +2133,12 @@ export interface TranscriptionOptions<TProviderOptions extends object = object>
|
|
|
2035
2133
|
* in catch blocks.
|
|
2036
2134
|
*/
|
|
2037
2135
|
logger: InternalLogger;
|
|
2136
|
+
/**
|
|
2137
|
+
* Effective abort signal composed by the activity from caller `abortSignal`
|
|
2138
|
+
* and/or `timeout`. Adapters should forward this to the provider SDK when
|
|
2139
|
+
* supported. Request-specific — never store on a global client config.
|
|
2140
|
+
*/
|
|
2141
|
+
abortSignal?: AbortSignal;
|
|
2038
2142
|
}
|
|
2039
2143
|
/**
|
|
2040
2144
|
* A single segment of transcribed audio with timing information.
|
|
@@ -2087,6 +2191,97 @@ export interface TranscriptionResult {
|
|
|
2087
2191
|
/** Persisted artifact references for generated assets, when available */
|
|
2088
2192
|
artifacts?: Array<PersistedArtifactRef>;
|
|
2089
2193
|
}
|
|
2194
|
+
/**
|
|
2195
|
+
* Input modalities an embedding model can accept. Unlike
|
|
2196
|
+
* {@link MediaPromptModality}, `'text'` is listed explicitly because
|
|
2197
|
+
* text-only embedding models are the common case and the modality list
|
|
2198
|
+
* drives compile-time narrowing of {@link EmbeddingInputItem}.
|
|
2199
|
+
*/
|
|
2200
|
+
export type EmbeddingModality = 'text' | 'image';
|
|
2201
|
+
/**
|
|
2202
|
+
* Per-model map from model name to the input modalities it accepts, used as
|
|
2203
|
+
* an adapter type parameter (`TModelInputModalitiesByName`). Models absent
|
|
2204
|
+
* from the map fall back to the unconstrained {@link EmbeddingInputItem}.
|
|
2205
|
+
*/
|
|
2206
|
+
export type EmbeddingModelInputModalitiesByName = Record<string, ReadonlyArray<EmbeddingModality>>;
|
|
2207
|
+
/**
|
|
2208
|
+
* A fused multi-part embedding item: all parts are embedded together into a
|
|
2209
|
+
* single vector (e.g. a product photo plus its caption). Written as a nested
|
|
2210
|
+
* array of content parts — the same `Array<ContentPart>` convention chat
|
|
2211
|
+
* messages use — so a fused item is visually distinct from the top-level
|
|
2212
|
+
* `input` list, where each element produces its own vector. Supported by
|
|
2213
|
+
* multimodal embedding models such as Cohere embed-v4 and Amazon Titan
|
|
2214
|
+
* Multimodal.
|
|
2215
|
+
*/
|
|
2216
|
+
export type EmbeddingContentParts = Array<TextPart | ImagePart>;
|
|
2217
|
+
/**
|
|
2218
|
+
* One embeddable item, producing exactly one vector. A bare string is
|
|
2219
|
+
* shorthand for a text part; a nested {@link EmbeddingContentParts} array
|
|
2220
|
+
* fuses its parts into a single vector. Note that a bare array at the top
|
|
2221
|
+
* level of `input` is the *list of items* (one vector each) — fuse by
|
|
2222
|
+
* nesting, e.g. `input: [[textPart, imagePart]]`.
|
|
2223
|
+
*/
|
|
2224
|
+
export type EmbeddingInputItem = string | TextPart | ImagePart | EmbeddingContentParts;
|
|
2225
|
+
/** Maps an embedding modality to the item types it admits. @internal */
|
|
2226
|
+
interface EmbeddingItemByModality {
|
|
2227
|
+
text: TextPart;
|
|
2228
|
+
image: ImagePart | EmbeddingContentParts;
|
|
2229
|
+
}
|
|
2230
|
+
/**
|
|
2231
|
+
* Embedding item type narrowed to the modalities a specific model supports.
|
|
2232
|
+
* `EmbeddingInputItemFor<'text'>` (a text-only model) is `string | TextPart`;
|
|
2233
|
+
* `'text' | 'image'` additionally admits image parts and fused
|
|
2234
|
+
* {@link EmbeddingContentParts} arrays. Used by the activity option types
|
|
2235
|
+
* together with the adapter's per-model modality map so unsupported inputs
|
|
2236
|
+
* fail at compile time.
|
|
2237
|
+
*/
|
|
2238
|
+
export type EmbeddingInputItemFor<TModalities extends EmbeddingModality = EmbeddingModality> = string | TextPart | EmbeddingItemByModality[TModalities];
|
|
2239
|
+
/**
|
|
2240
|
+
* Options for embedding generation, as received by adapters. The `embed()`
|
|
2241
|
+
* entry point normalizes a single input item to an array before calling the
|
|
2242
|
+
* adapter, so `input` is always an array here.
|
|
2243
|
+
*/
|
|
2244
|
+
export interface EmbeddingOptions<TProviderOptions extends object = object> {
|
|
2245
|
+
/** The model to use for embedding generation */
|
|
2246
|
+
model: string;
|
|
2247
|
+
/** The items to embed — one vector per item */
|
|
2248
|
+
input: Array<EmbeddingInputItem>;
|
|
2249
|
+
/**
|
|
2250
|
+
* Requested output dimensionality. Adapters for models with fixed
|
|
2251
|
+
* dimensions throw a clear runtime error when this is set.
|
|
2252
|
+
*/
|
|
2253
|
+
dimensions?: number;
|
|
2254
|
+
/** Model-specific options for embedding generation */
|
|
2255
|
+
modelOptions?: TProviderOptions;
|
|
2256
|
+
/**
|
|
2257
|
+
* Internal logger threaded from the embed() entry point. Adapters must
|
|
2258
|
+
* call logger.request() before the SDK call and logger.errors() in catch
|
|
2259
|
+
* blocks.
|
|
2260
|
+
*/
|
|
2261
|
+
logger: InternalLogger;
|
|
2262
|
+
}
|
|
2263
|
+
/**
|
|
2264
|
+
* A single embedding vector.
|
|
2265
|
+
*/
|
|
2266
|
+
export interface Embedding {
|
|
2267
|
+
/** The embedding vector */
|
|
2268
|
+
vector: Array<number>;
|
|
2269
|
+
/** Position of the source item in the (normalized) input array */
|
|
2270
|
+
index: number;
|
|
2271
|
+
}
|
|
2272
|
+
/**
|
|
2273
|
+
* Result of embedding generation.
|
|
2274
|
+
*/
|
|
2275
|
+
export interface EmbeddingResult {
|
|
2276
|
+
/** Unique identifier for the generation */
|
|
2277
|
+
id: string;
|
|
2278
|
+
/** Model used for generation */
|
|
2279
|
+
model: string;
|
|
2280
|
+
/** One embedding per input item, in input order */
|
|
2281
|
+
embeddings: Array<Embedding>;
|
|
2282
|
+
/** Token usage information (if provided by the adapter) */
|
|
2283
|
+
usage?: TokenUsage;
|
|
2284
|
+
}
|
|
2090
2285
|
/**
|
|
2091
2286
|
* Default metadata type for adapters that don't define custom metadata.
|
|
2092
2287
|
* Uses unknown for all modalities.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared abort/timeout composition for media (and summarize) activities.
|
|
3
|
+
*
|
|
4
|
+
* Callers pass optional `timeout` and/or `abortSignal` on activity options.
|
|
5
|
+
* Core composes them into one effective signal, races the adapter call so a
|
|
6
|
+
* hung provider still rejects, clears timeout resources on settle, and
|
|
7
|
+
* classifies aborts so lifecycle middleware gets `onAbort` rather than
|
|
8
|
+
* `onError`.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Combine two optional AbortSignals into one that aborts when either does.
|
|
12
|
+
* Returns the other signal directly when one is absent or already aborted.
|
|
13
|
+
* First abort wins and preserves its reason.
|
|
14
|
+
*
|
|
15
|
+
* Manual implementation — `AbortSignal.any` requires Node >= 20.3.
|
|
16
|
+
*/
|
|
17
|
+
export declare function combineAbortSignals(a: AbortSignal | undefined, b: AbortSignal | undefined): AbortSignal | undefined;
|
|
18
|
+
/** Normalize an abort reason into an Error the activity can reject with. */
|
|
19
|
+
export declare function toAbortError(reason: unknown): Error;
|
|
20
|
+
export interface ActivityAbortControls {
|
|
21
|
+
/** Effective signal, or `undefined` when neither timeout nor caller signal. */
|
|
22
|
+
signal: AbortSignal | undefined;
|
|
23
|
+
/** Clear the timeout timer if one was set. Idempotent. */
|
|
24
|
+
clear: () => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Compose an activity-level timeout with a caller AbortSignal.
|
|
28
|
+
*
|
|
29
|
+
* - No SDK-wide default timeout; omit both for unlimited wait.
|
|
30
|
+
* - First of caller cancellation or timeout wins and keeps its reason.
|
|
31
|
+
* - Call `clear()` when the activity settles (success or failure) so timers
|
|
32
|
+
* do not leak.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createActivityAbortControls(options: {
|
|
35
|
+
abortSignal?: AbortSignal;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
}): ActivityAbortControls;
|
|
38
|
+
/**
|
|
39
|
+
* Reject when `signal` aborts, even if the underlying promise ignores it.
|
|
40
|
+
* Ensures activity-level timeouts work for adapters that do not yet forward
|
|
41
|
+
* the signal to the provider SDK.
|
|
42
|
+
*
|
|
43
|
+
* When the signal wins, the adapter promise is observed with an empty handler
|
|
44
|
+
* so a later settle cannot surface as an unhandled rejection.
|
|
45
|
+
*/
|
|
46
|
+
export declare function raceWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Whether a thrown value (and optional effective signal) should route to
|
|
49
|
+
* middleware `onAbort` instead of `onError`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function isActivityAbortError(error: unknown, signal?: AbortSignal): boolean;
|
|
52
|
+
/** Best-effort string reason for {@link GenerationAbortInfo}. */
|
|
53
|
+
export declare function abortReasonMessage(error: unknown, signal?: AbortSignal): string | undefined;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
//#region src/utilities/activity-abort.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared abort/timeout composition for media (and summarize) activities.
|
|
4
|
+
*
|
|
5
|
+
* Callers pass optional `timeout` and/or `abortSignal` on activity options.
|
|
6
|
+
* Core composes them into one effective signal, races the adapter call so a
|
|
7
|
+
* hung provider still rejects, clears timeout resources on settle, and
|
|
8
|
+
* classifies aborts so lifecycle middleware gets `onAbort` rather than
|
|
9
|
+
* `onError`.
|
|
10
|
+
*/
|
|
11
|
+
var ABORT_ERROR_NAMES = /* @__PURE__ */ new Set([
|
|
12
|
+
"AbortError",
|
|
13
|
+
"TimeoutError",
|
|
14
|
+
"APIUserAbortError",
|
|
15
|
+
"RequestAbortedError"
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Combine two optional AbortSignals into one that aborts when either does.
|
|
19
|
+
* Returns the other signal directly when one is absent or already aborted.
|
|
20
|
+
* First abort wins and preserves its reason.
|
|
21
|
+
*
|
|
22
|
+
* Manual implementation — `AbortSignal.any` requires Node >= 20.3.
|
|
23
|
+
*/
|
|
24
|
+
function combineAbortSignals(a, b) {
|
|
25
|
+
if (!a) return b;
|
|
26
|
+
if (!b) return a;
|
|
27
|
+
if (a.aborted) return a;
|
|
28
|
+
if (b.aborted) return b;
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
const onAbort = (source) => () => {
|
|
31
|
+
controller.abort(source.reason);
|
|
32
|
+
};
|
|
33
|
+
a.addEventListener("abort", onAbort(a), { once: true });
|
|
34
|
+
b.addEventListener("abort", onAbort(b), { once: true });
|
|
35
|
+
return controller.signal;
|
|
36
|
+
}
|
|
37
|
+
function createTimeoutReason(ms) {
|
|
38
|
+
if (typeof DOMException !== "undefined") return new DOMException(`Activity timed out after ${ms}ms`, "TimeoutError");
|
|
39
|
+
const err = /* @__PURE__ */ new Error(`Activity timed out after ${ms}ms`);
|
|
40
|
+
err.name = "TimeoutError";
|
|
41
|
+
return err;
|
|
42
|
+
}
|
|
43
|
+
/** Normalize an abort reason into an Error the activity can reject with. */
|
|
44
|
+
function toAbortError(reason) {
|
|
45
|
+
if (reason instanceof Error) return reason;
|
|
46
|
+
if (typeof reason === "string" && reason.length > 0) {
|
|
47
|
+
const err = new Error(reason);
|
|
48
|
+
err.name = "AbortError";
|
|
49
|
+
return err;
|
|
50
|
+
}
|
|
51
|
+
const err = /* @__PURE__ */ new Error("The operation was aborted");
|
|
52
|
+
err.name = "AbortError";
|
|
53
|
+
return err;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Compose an activity-level timeout with a caller AbortSignal.
|
|
57
|
+
*
|
|
58
|
+
* - No SDK-wide default timeout; omit both for unlimited wait.
|
|
59
|
+
* - First of caller cancellation or timeout wins and keeps its reason.
|
|
60
|
+
* - Call `clear()` when the activity settles (success or failure) so timers
|
|
61
|
+
* do not leak.
|
|
62
|
+
*/
|
|
63
|
+
function createActivityAbortControls(options) {
|
|
64
|
+
let timeoutId;
|
|
65
|
+
let timeoutSignal;
|
|
66
|
+
if (options.timeout !== void 0) {
|
|
67
|
+
if (!Number.isFinite(options.timeout) || options.timeout < 0) throw new Error(`Invalid activity timeout: expected a non-negative finite number, got ${String(options.timeout)}`);
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
timeoutSignal = controller.signal;
|
|
70
|
+
const ms = options.timeout;
|
|
71
|
+
timeoutId = setTimeout(() => {
|
|
72
|
+
controller.abort(createTimeoutReason(ms));
|
|
73
|
+
}, ms);
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
signal: combineAbortSignals(options.abortSignal, timeoutSignal),
|
|
77
|
+
clear: () => {
|
|
78
|
+
if (timeoutId !== void 0) {
|
|
79
|
+
clearTimeout(timeoutId);
|
|
80
|
+
timeoutId = void 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Reject when `signal` aborts, even if the underlying promise ignores it.
|
|
87
|
+
* Ensures activity-level timeouts work for adapters that do not yet forward
|
|
88
|
+
* the signal to the provider SDK.
|
|
89
|
+
*
|
|
90
|
+
* When the signal wins, the adapter promise is observed with an empty handler
|
|
91
|
+
* so a later settle cannot surface as an unhandled rejection.
|
|
92
|
+
*/
|
|
93
|
+
function raceWithAbort(promise, signal) {
|
|
94
|
+
if (!signal) return promise;
|
|
95
|
+
const swallow = () => {
|
|
96
|
+
promise.then(() => void 0, () => void 0);
|
|
97
|
+
};
|
|
98
|
+
if (signal.aborted) {
|
|
99
|
+
swallow();
|
|
100
|
+
return Promise.reject(toAbortError(signal.reason));
|
|
101
|
+
}
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
let settled = false;
|
|
104
|
+
const onAbort = () => {
|
|
105
|
+
if (settled) return;
|
|
106
|
+
settled = true;
|
|
107
|
+
cleanup();
|
|
108
|
+
swallow();
|
|
109
|
+
reject(toAbortError(signal.reason));
|
|
110
|
+
};
|
|
111
|
+
const cleanup = () => {
|
|
112
|
+
signal.removeEventListener("abort", onAbort);
|
|
113
|
+
};
|
|
114
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
115
|
+
promise.then((value) => {
|
|
116
|
+
if (settled) return;
|
|
117
|
+
settled = true;
|
|
118
|
+
cleanup();
|
|
119
|
+
resolve(value);
|
|
120
|
+
}, (error) => {
|
|
121
|
+
if (settled) return;
|
|
122
|
+
settled = true;
|
|
123
|
+
cleanup();
|
|
124
|
+
reject(error);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Whether a thrown value (and optional effective signal) should route to
|
|
130
|
+
* middleware `onAbort` instead of `onError`.
|
|
131
|
+
*/
|
|
132
|
+
function isActivityAbortError(error, signal) {
|
|
133
|
+
if (signal?.aborted) return true;
|
|
134
|
+
if (!error || typeof error !== "object") return false;
|
|
135
|
+
const name = error.name;
|
|
136
|
+
return typeof name === "string" && ABORT_ERROR_NAMES.has(name);
|
|
137
|
+
}
|
|
138
|
+
/** Best-effort string reason for {@link GenerationAbortInfo}. */
|
|
139
|
+
function abortReasonMessage(error, signal) {
|
|
140
|
+
if (signal?.reason !== void 0) {
|
|
141
|
+
if (typeof signal.reason === "string") return signal.reason;
|
|
142
|
+
if (signal.reason instanceof Error) return signal.reason.message;
|
|
143
|
+
}
|
|
144
|
+
if (error instanceof Error) return error.message;
|
|
145
|
+
if (typeof error === "string") return error;
|
|
146
|
+
}
|
|
147
|
+
//#endregion
|
|
148
|
+
export { abortReasonMessage, combineAbortSignals, createActivityAbortControls, isActivityAbortError, raceWithAbort, toAbortError };
|
|
149
|
+
|
|
150
|
+
//# sourceMappingURL=activity-abort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-abort.js","names":[],"sources":["../../../src/utilities/activity-abort.ts"],"sourcesContent":["/**\n * Shared abort/timeout composition for media (and summarize) activities.\n *\n * Callers pass optional `timeout` and/or `abortSignal` on activity options.\n * Core composes them into one effective signal, races the adapter call so a\n * hung provider still rejects, clears timeout resources on settle, and\n * classifies aborts so lifecycle middleware gets `onAbort` rather than\n * `onError`.\n */\n\nconst ABORT_ERROR_NAMES = new Set([\n 'AbortError',\n 'TimeoutError',\n 'APIUserAbortError',\n 'RequestAbortedError',\n])\n\n/**\n * Combine two optional AbortSignals into one that aborts when either does.\n * Returns the other signal directly when one is absent or already aborted.\n * First abort wins and preserves its reason.\n *\n * Manual implementation — `AbortSignal.any` requires Node >= 20.3.\n */\nexport function combineAbortSignals(\n a: AbortSignal | undefined,\n b: AbortSignal | undefined,\n): AbortSignal | undefined {\n if (!a) return b\n if (!b) return a\n if (a.aborted) return a\n if (b.aborted) return b\n const controller = new AbortController()\n const onAbort = (source: AbortSignal) => () => {\n controller.abort(source.reason)\n }\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return controller.signal\n}\n\nfunction createTimeoutReason(ms: number): Error {\n if (typeof DOMException !== 'undefined') {\n return new DOMException(`Activity timed out after ${ms}ms`, 'TimeoutError')\n }\n const err = new Error(`Activity timed out after ${ms}ms`)\n err.name = 'TimeoutError'\n return err\n}\n\n/** Normalize an abort reason into an Error the activity can reject with. */\nexport function toAbortError(reason: unknown): Error {\n if (reason instanceof Error) return reason\n if (typeof reason === 'string' && reason.length > 0) {\n const err = new Error(reason)\n err.name = 'AbortError'\n return err\n }\n const err = new Error('The operation was aborted')\n err.name = 'AbortError'\n return err\n}\n\nexport interface ActivityAbortControls {\n /** Effective signal, or `undefined` when neither timeout nor caller signal. */\n signal: AbortSignal | undefined\n /** Clear the timeout timer if one was set. Idempotent. */\n clear: () => void\n}\n\n/**\n * Compose an activity-level timeout with a caller AbortSignal.\n *\n * - No SDK-wide default timeout; omit both for unlimited wait.\n * - First of caller cancellation or timeout wins and keeps its reason.\n * - Call `clear()` when the activity settles (success or failure) so timers\n * do not leak.\n */\nexport function createActivityAbortControls(options: {\n abortSignal?: AbortSignal\n timeout?: number\n}): ActivityAbortControls {\n let timeoutId: ReturnType<typeof setTimeout> | undefined\n let timeoutSignal: AbortSignal | undefined\n\n if (options.timeout !== undefined) {\n if (!Number.isFinite(options.timeout) || options.timeout < 0) {\n throw new Error(\n `Invalid activity timeout: expected a non-negative finite number, got ${String(options.timeout)}`,\n )\n }\n const controller = new AbortController()\n timeoutSignal = controller.signal\n const ms = options.timeout\n timeoutId = setTimeout(() => {\n controller.abort(createTimeoutReason(ms))\n }, ms)\n }\n\n const signal = combineAbortSignals(options.abortSignal, timeoutSignal)\n\n return {\n signal,\n clear: () => {\n if (timeoutId !== undefined) {\n clearTimeout(timeoutId)\n timeoutId = undefined\n }\n },\n }\n}\n\n/**\n * Reject when `signal` aborts, even if the underlying promise ignores it.\n * Ensures activity-level timeouts work for adapters that do not yet forward\n * the signal to the provider SDK.\n *\n * When the signal wins, the adapter promise is observed with an empty handler\n * so a later settle cannot surface as an unhandled rejection.\n */\nexport function raceWithAbort<T>(\n promise: Promise<T>,\n signal: AbortSignal | undefined,\n): Promise<T> {\n if (!signal) return promise\n\n const swallow = () => {\n // Observe the adapter promise without acting on its outcome so a late\n // reject after we already aborted cannot become an unhandled rejection.\n promise.then(\n () => undefined,\n () => undefined,\n )\n }\n\n if (signal.aborted) {\n swallow()\n return Promise.reject(toAbortError(signal.reason))\n }\n\n return new Promise<T>((resolve, reject) => {\n let settled = false\n const onAbort = () => {\n if (settled) return\n settled = true\n cleanup()\n swallow()\n reject(toAbortError(signal.reason))\n }\n const cleanup = () => {\n signal.removeEventListener('abort', onAbort)\n }\n signal.addEventListener('abort', onAbort, { once: true })\n promise.then(\n (value) => {\n if (settled) return\n settled = true\n cleanup()\n resolve(value)\n },\n (error: unknown) => {\n if (settled) return\n settled = true\n cleanup()\n reject(error)\n },\n )\n })\n}\n\n/**\n * Whether a thrown value (and optional effective signal) should route to\n * middleware `onAbort` instead of `onError`.\n */\nexport function isActivityAbortError(\n error: unknown,\n signal?: AbortSignal,\n): boolean {\n if (signal?.aborted) return true\n if (!error || typeof error !== 'object') return false\n const name = (error as { name?: unknown }).name\n return typeof name === 'string' && ABORT_ERROR_NAMES.has(name)\n}\n\n/** Best-effort string reason for {@link GenerationAbortInfo}. */\nexport function abortReasonMessage(\n error: unknown,\n signal?: AbortSignal,\n): string | undefined {\n if (signal?.reason !== undefined) {\n if (typeof signal.reason === 'string') return signal.reason\n if (signal.reason instanceof Error) return signal.reason.message\n }\n if (error instanceof Error) return error.message\n if (typeof error === 'string') return error\n return undefined\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { EmbeddingInputItem, ImagePart } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* One embedding input item resolved into its text and image constituents.
|
|
4
|
+
* Produced by {@link resolveEmbeddingInput}; adapters map each entry onto
|
|
5
|
+
* one provider-native input (one vector per entry).
|
|
6
|
+
*/
|
|
7
|
+
export interface ResolvedEmbeddingItem {
|
|
8
|
+
/** Text contents of the item, in order (empty for image-only items) */
|
|
9
|
+
texts: Array<string>;
|
|
10
|
+
/** Image parts of the item, in order (empty for text-only items) */
|
|
11
|
+
images: Array<ImagePart>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resolve each embedding input item into its text and image constituents,
|
|
15
|
+
* preserving input order (result[i] corresponds to input[i] and to the
|
|
16
|
+
* vector at index i).
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveEmbeddingInput(input: Array<EmbeddingInputItem>): Array<ResolvedEmbeddingItem>;
|
|
19
|
+
/**
|
|
20
|
+
* Extract plain text inputs for a text-only embedding model, throwing a
|
|
21
|
+
* uniform error if any item carries an image. The per-model modality typing
|
|
22
|
+
* rejects these at compile time; this guard covers untyped/dynamic callers.
|
|
23
|
+
*/
|
|
24
|
+
export declare function requireTextOnlyEmbeddingInput(input: Array<EmbeddingInputItem>, provider: string, model: string): Array<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Count text-only and image-carrying items for observability events. Never
|
|
27
|
+
* exposes input content.
|
|
28
|
+
*/
|
|
29
|
+
export declare function countEmbeddingInputModalities(input: Array<EmbeddingInputItem>): {
|
|
30
|
+
textInputCount: number;
|
|
31
|
+
imageInputCount: number;
|
|
32
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
//#region src/utilities/embedding-input.ts
|
|
2
|
+
function resolveItem(item) {
|
|
3
|
+
if (typeof item === "string") return {
|
|
4
|
+
texts: [item],
|
|
5
|
+
images: []
|
|
6
|
+
};
|
|
7
|
+
if (Array.isArray(item)) {
|
|
8
|
+
const resolved = {
|
|
9
|
+
texts: [],
|
|
10
|
+
images: []
|
|
11
|
+
};
|
|
12
|
+
for (const part of item) if (part.type === "text") resolved.texts.push(part.content);
|
|
13
|
+
else resolved.images.push(part);
|
|
14
|
+
return resolved;
|
|
15
|
+
}
|
|
16
|
+
if (item.type === "text") return {
|
|
17
|
+
texts: [item.content],
|
|
18
|
+
images: []
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
texts: [],
|
|
22
|
+
images: [item]
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve each embedding input item into its text and image constituents,
|
|
27
|
+
* preserving input order (result[i] corresponds to input[i] and to the
|
|
28
|
+
* vector at index i).
|
|
29
|
+
*/
|
|
30
|
+
function resolveEmbeddingInput(input) {
|
|
31
|
+
return input.map(resolveItem);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Extract plain text inputs for a text-only embedding model, throwing a
|
|
35
|
+
* uniform error if any item carries an image. The per-model modality typing
|
|
36
|
+
* rejects these at compile time; this guard covers untyped/dynamic callers.
|
|
37
|
+
*/
|
|
38
|
+
function requireTextOnlyEmbeddingInput(input, provider, model) {
|
|
39
|
+
return resolveEmbeddingInput(input).map((item, index) => {
|
|
40
|
+
if (item.images.length > 0) throw new Error(`${provider} model "${model}" only supports text embedding inputs; input item at index ${index} contains an image part`);
|
|
41
|
+
return item.texts.join("\n");
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Count text-only and image-carrying items for observability events. Never
|
|
46
|
+
* exposes input content.
|
|
47
|
+
*/
|
|
48
|
+
function countEmbeddingInputModalities(input) {
|
|
49
|
+
let textInputCount = 0;
|
|
50
|
+
let imageInputCount = 0;
|
|
51
|
+
for (const item of resolveEmbeddingInput(input)) if (item.images.length > 0) imageInputCount++;
|
|
52
|
+
else textInputCount++;
|
|
53
|
+
return {
|
|
54
|
+
textInputCount,
|
|
55
|
+
imageInputCount
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { countEmbeddingInputModalities, requireTextOnlyEmbeddingInput, resolveEmbeddingInput };
|
|
60
|
+
|
|
61
|
+
//# sourceMappingURL=embedding-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding-input.js","names":[],"sources":["../../../src/utilities/embedding-input.ts"],"sourcesContent":["import type { EmbeddingInputItem, ImagePart } from '../types'\n\n/**\n * One embedding input item resolved into its text and image constituents.\n * Produced by {@link resolveEmbeddingInput}; adapters map each entry onto\n * one provider-native input (one vector per entry).\n */\nexport interface ResolvedEmbeddingItem {\n /** Text contents of the item, in order (empty for image-only items) */\n texts: Array<string>\n /** Image parts of the item, in order (empty for text-only items) */\n images: Array<ImagePart>\n}\n\nfunction resolveItem(item: EmbeddingInputItem): ResolvedEmbeddingItem {\n if (typeof item === 'string') {\n return { texts: [item], images: [] }\n }\n // A nested array is a fused item: its parts embed together into one vector.\n if (Array.isArray(item)) {\n const resolved: ResolvedEmbeddingItem = { texts: [], images: [] }\n for (const part of item) {\n if (part.type === 'text') {\n resolved.texts.push(part.content)\n } else {\n resolved.images.push(part)\n }\n }\n return resolved\n }\n if (item.type === 'text') {\n return { texts: [item.content], images: [] }\n }\n return { texts: [], images: [item] }\n}\n\n/**\n * Resolve each embedding input item into its text and image constituents,\n * preserving input order (result[i] corresponds to input[i] and to the\n * vector at index i).\n */\nexport function resolveEmbeddingInput(\n input: Array<EmbeddingInputItem>,\n): Array<ResolvedEmbeddingItem> {\n return input.map(resolveItem)\n}\n\n/**\n * Extract plain text inputs for a text-only embedding model, throwing a\n * uniform error if any item carries an image. The per-model modality typing\n * rejects these at compile time; this guard covers untyped/dynamic callers.\n */\nexport function requireTextOnlyEmbeddingInput(\n input: Array<EmbeddingInputItem>,\n provider: string,\n model: string,\n): Array<string> {\n return resolveEmbeddingInput(input).map((item, index) => {\n if (item.images.length > 0) {\n throw new Error(\n `${provider} model \"${model}\" only supports text embedding inputs; ` +\n `input item at index ${index} contains an image part`,\n )\n }\n return item.texts.join('\\n')\n })\n}\n\n/**\n * Count text-only and image-carrying items for observability events. Never\n * exposes input content.\n */\nexport function countEmbeddingInputModalities(\n input: Array<EmbeddingInputItem>,\n): { textInputCount: number; imageInputCount: number } {\n let textInputCount = 0\n let imageInputCount = 0\n for (const item of resolveEmbeddingInput(input)) {\n if (item.images.length > 0) imageInputCount++\n else textInputCount++\n }\n return { textInputCount, imageInputCount }\n}\n"],"mappings":";AAcA,SAAS,YAAY,MAAiD;CACpE,IAAI,OAAO,SAAS,UAClB,OAAO;EAAE,OAAO,CAAC,IAAI;EAAG,QAAQ,CAAC;CAAE;CAGrC,IAAI,MAAM,QAAQ,IAAI,GAAG;EACvB,MAAM,WAAkC;GAAE,OAAO,CAAC;GAAG,QAAQ,CAAC;EAAE;EAChE,KAAK,MAAM,QAAQ,MACjB,IAAI,KAAK,SAAS,QAChB,SAAS,MAAM,KAAK,KAAK,OAAO;OAEhC,SAAS,OAAO,KAAK,IAAI;EAG7B,OAAO;CACT;CACA,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,OAAO,CAAC,KAAK,OAAO;EAAG,QAAQ,CAAC;CAAE;CAE7C,OAAO;EAAE,OAAO,CAAC;EAAG,QAAQ,CAAC,IAAI;CAAE;AACrC;;;;;;AAOA,SAAgB,sBACd,OAC8B;CAC9B,OAAO,MAAM,IAAI,WAAW;AAC9B;;;;;;AAOA,SAAgB,8BACd,OACA,UACA,OACe;CACf,OAAO,sBAAsB,KAAK,CAAC,CAAC,KAAK,MAAM,UAAU;EACvD,IAAI,KAAK,OAAO,SAAS,GACvB,MAAM,IAAI,MACR,GAAG,SAAS,UAAU,MAAM,6DACH,MAAM,wBACjC;EAEF,OAAO,KAAK,MAAM,KAAK,IAAI;CAC7B,CAAC;AACH;;;;;AAMA,SAAgB,8BACd,OACqD;CACrD,IAAI,iBAAiB;CACrB,IAAI,kBAAkB;CACtB,KAAK,MAAM,QAAQ,sBAAsB,KAAK,GAC5C,IAAI,KAAK,OAAO,SAAS,GAAG;MACvB;CAEP,OAAO;EAAE;EAAgB;CAAgB;AAC3C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/ai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"@ag-ui/core": "0.1.1-canary.beta.0",
|
|
81
81
|
"@standard-schema/spec": "^1.1.0",
|
|
82
82
|
"partial-json": "^0.1.7",
|
|
83
|
-
"@tanstack/ai-event-client": "0.
|
|
84
|
-
"@tanstack/ai-utils": "0.4.0"
|
|
83
|
+
"@tanstack/ai-event-client": "^0.8.0",
|
|
84
|
+
"@tanstack/ai-utils": "^0.4.0"
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"@opentelemetry/api": ">=1.9.0"
|