@tanstack/ai-client 0.22.1 → 0.23.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/dist/esm/audio-recorder.js +190 -213
- package/dist/esm/audio-recorder.js.map +1 -1
- package/dist/esm/chat-client.d.ts +172 -3
- package/dist/esm/chat-client.js +1656 -1386
- package/dist/esm/chat-client.js.map +1 -1
- package/dist/esm/cleared-stream-tracker.d.ts +23 -0
- package/dist/esm/cleared-stream-tracker.js +97 -0
- package/dist/esm/cleared-stream-tracker.js.map +1 -0
- package/dist/esm/client-persistor.d.ts +25 -12
- package/dist/esm/client-persistor.js +260 -235
- package/dist/esm/client-persistor.js.map +1 -1
- package/dist/esm/connection-adapters.d.ts +231 -10
- package/dist/esm/connection-adapters.js +989 -574
- package/dist/esm/connection-adapters.js.map +1 -1
- package/dist/esm/devtools-noop.d.ts +1 -0
- package/dist/esm/devtools-noop.js +79 -139
- package/dist/esm/devtools-noop.js.map +1 -1
- package/dist/esm/devtools.d.ts +31 -1
- package/dist/esm/devtools.js +977 -1127
- package/dist/esm/devtools.js.map +1 -1
- package/dist/esm/events.js +224 -226
- package/dist/esm/events.js.map +1 -1
- package/dist/esm/generation-client.d.ts +145 -2
- package/dist/esm/generation-client.js +659 -321
- package/dist/esm/generation-client.js.map +1 -1
- package/dist/esm/generation-reconstruct.d.ts +21 -0
- package/dist/esm/generation-reconstruct.js +85 -0
- package/dist/esm/generation-reconstruct.js.map +1 -0
- package/dist/esm/generation-types.d.ts +289 -3
- package/dist/esm/generation-types.js +356 -13
- package/dist/esm/generation-types.js.map +1 -1
- package/dist/esm/index.d.ts +9 -4
- package/dist/esm/index.js +7 -39
- package/dist/esm/interrupt-manager.d.ts +77 -0
- package/dist/esm/interrupt-manager.js +787 -0
- package/dist/esm/interrupt-manager.js.map +1 -0
- package/dist/esm/mcp-app-bridge.js +56 -64
- package/dist/esm/mcp-app-bridge.js.map +1 -1
- package/dist/esm/realtime-client.js +366 -440
- package/dist/esm/realtime-client.js.map +1 -1
- package/dist/esm/response-stream.js +19 -26
- package/dist/esm/response-stream.js.map +1 -1
- package/dist/esm/sse-parser.js +44 -47
- package/dist/esm/sse-parser.js.map +1 -1
- package/dist/esm/sse-utils.js +8 -9
- package/dist/esm/sse-utils.js.map +1 -1
- package/dist/esm/storage-adapters.d.ts +62 -0
- package/dist/esm/storage-adapters.js +174 -0
- package/dist/esm/storage-adapters.js.map +1 -0
- package/dist/esm/types.d.ts +212 -10
- package/dist/esm/types.js +38 -7
- package/dist/esm/types.js.map +1 -1
- package/dist/esm/video-generation-client.d.ts +113 -2
- package/dist/esm/video-generation-client.js +665 -379
- package/dist/esm/video-generation-client.js.map +1 -1
- package/package.json +7 -7
- package/src/chat-client.ts +1079 -61
- package/src/cleared-stream-tracker.ts +151 -0
- package/src/client-persistor.ts +102 -33
- package/src/connection-adapters.ts +1185 -142
- package/src/devtools-noop.ts +4 -3
- package/src/devtools.ts +121 -3
- package/src/generation-client.ts +563 -13
- package/src/generation-reconstruct.ts +121 -0
- package/src/generation-types.ts +727 -3
- package/src/index.ts +56 -1
- package/src/interrupt-manager.ts +1440 -0
- package/src/storage-adapters.ts +242 -0
- package/src/types.ts +301 -9
- package/src/video-generation-client.ts +479 -13
- package/dist/esm/index.js.map +0 -1
package/src/devtools-noop.ts
CHANGED
|
@@ -86,6 +86,7 @@ export class NoOpChatDevtoolsBridge {
|
|
|
86
86
|
return ''
|
|
87
87
|
}
|
|
88
88
|
observeChunk(_chunk: StreamChunk): void {}
|
|
89
|
+
recordMemoryState(_value: unknown): void {}
|
|
89
90
|
beginRun(_runId: string, _threadId: string): void {}
|
|
90
91
|
getCurrentRunEventContext(): ChatClientRunEventContext | undefined {
|
|
91
92
|
return undefined
|
|
@@ -190,12 +191,12 @@ void _bridgeParity
|
|
|
190
191
|
export const createNoOpChatDevtoolsBridge: ChatDevtoolsBridgeFactory = (
|
|
191
192
|
options,
|
|
192
193
|
) =>
|
|
193
|
-
//
|
|
194
|
+
// oxlint-disable-next-line eslint-js/no-restricted-syntax -- see comment above
|
|
194
195
|
new NoOpChatDevtoolsBridge(options) as unknown as ChatDevtoolsBridge
|
|
195
196
|
|
|
196
197
|
export const createNoOpGenerationDevtoolsBridge: GenerationDevtoolsBridgeFactory =
|
|
197
198
|
<TOutput>(options: GenerationDevtoolsBridgeOptions<TOutput>) =>
|
|
198
|
-
//
|
|
199
|
+
// oxlint-disable-next-line eslint-js/no-restricted-syntax -- see comment above
|
|
199
200
|
new NoOpGenerationDevtoolsBridge<TOutput>(
|
|
200
201
|
options,
|
|
201
202
|
) as unknown as GenerationDevtoolsBridge<TOutput>
|
|
@@ -205,7 +206,7 @@ export const createNoOpVideoDevtoolsBridge: VideoDevtoolsBridgeFactory = <
|
|
|
205
206
|
>(
|
|
206
207
|
options: VideoDevtoolsBridgeOptions<TOutput>,
|
|
207
208
|
) =>
|
|
208
|
-
//
|
|
209
|
+
// oxlint-disable-next-line eslint-js/no-restricted-syntax -- see comment above
|
|
209
210
|
new NoOpVideoDevtoolsBridge<TOutput>(
|
|
210
211
|
options,
|
|
211
212
|
) as unknown as VideoDevtoolsBridge<TOutput>
|
package/src/devtools.ts
CHANGED
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
import { convertSchemaToJsonSchema } from '@tanstack/ai/client'
|
|
7
7
|
import { DefaultChatClientEventEmitter } from './events'
|
|
8
8
|
import type { AnyClientTool, StreamChunk } from '@tanstack/ai/client'
|
|
9
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
AIDevtoolsEventVisibility,
|
|
11
|
+
MemoryScopeLite,
|
|
12
|
+
} from '@tanstack/ai-event-client'
|
|
10
13
|
import type {
|
|
11
14
|
ChatClientEventContext,
|
|
12
15
|
ChatClientEventEmitter,
|
|
@@ -25,6 +28,33 @@ export interface AIDevtoolsDisplayOptions {
|
|
|
25
28
|
name?: string
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Structural mirror of `MemoryStateEventValue` from `@tanstack/ai-memory` — the
|
|
33
|
+
* payload of the `memory:state` CUSTOM chunk. Kept local so `ai-client` doesn't
|
|
34
|
+
* depend on `ai-memory`; the memory middleware is the producer.
|
|
35
|
+
*/
|
|
36
|
+
interface MemoryStateEventValue {
|
|
37
|
+
scope: MemoryScopeLite
|
|
38
|
+
adapter: string
|
|
39
|
+
query?: string
|
|
40
|
+
recall?: {
|
|
41
|
+
fragmentCount?: number
|
|
42
|
+
hasTools?: boolean
|
|
43
|
+
systemPromptChars?: number
|
|
44
|
+
durationMs?: number
|
|
45
|
+
}
|
|
46
|
+
snapshot?: {
|
|
47
|
+
takenAt: string
|
|
48
|
+
data: unknown
|
|
49
|
+
facts?: Array<{
|
|
50
|
+
id: string
|
|
51
|
+
text: string
|
|
52
|
+
source?: string
|
|
53
|
+
createdAt?: string
|
|
54
|
+
}>
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
28
58
|
export interface AIDevtoolsClientMetadata extends AIDevtoolsDisplayOptions {
|
|
29
59
|
framework?: string
|
|
30
60
|
hookName: string
|
|
@@ -463,7 +493,7 @@ export class ClientDevtoolsBridge<TSnapshot extends object> {
|
|
|
463
493
|
...this.createMetadataPayload(),
|
|
464
494
|
// Wire envelope uses Record<string, unknown>; widen the typed snapshot
|
|
465
495
|
// here so the typed-snapshot constraint above can stay narrow.
|
|
466
|
-
//
|
|
496
|
+
// oxlint-disable-next-line eslint-js/no-restricted-syntax -- TSnapshot extends object is structurally compatible but TS can't see the missing index signature
|
|
467
497
|
state: this.options.getSnapshot() as unknown as Record<string, unknown>,
|
|
468
498
|
})
|
|
469
499
|
}
|
|
@@ -626,8 +656,16 @@ export class ClientDevtoolsBridge<TSnapshot extends object> {
|
|
|
626
656
|
this.emitRegistered()
|
|
627
657
|
this.emitToolsRegistered()
|
|
628
658
|
this.emitSnapshot()
|
|
659
|
+
this.onReplayState()
|
|
629
660
|
}
|
|
630
661
|
|
|
662
|
+
/**
|
|
663
|
+
* Extension hook for subclasses to replay any additional cached state on a
|
|
664
|
+
* `devtools:request-state` (i.e. when a panel opens). Called only after the
|
|
665
|
+
* base guards (disposed/superseded/targetHookId) pass. No-op by default.
|
|
666
|
+
*/
|
|
667
|
+
protected onReplayState(): void {}
|
|
668
|
+
|
|
631
669
|
private async handleToolFixtureApply(
|
|
632
670
|
event: AIDevtoolsEvent<AIDevtoolsToolFixture>,
|
|
633
671
|
): Promise<void> {
|
|
@@ -644,6 +682,9 @@ export class ClientDevtoolsBridge<TSnapshot extends object> {
|
|
|
644
682
|
return false
|
|
645
683
|
}
|
|
646
684
|
|
|
685
|
+
// Fixture routing: `hookId` wins when present (latest bridge for that
|
|
686
|
+
// registry key). `threadId` is the fallback for fixtures scoped only to a
|
|
687
|
+
// conversation / generation slot without a hook id.
|
|
647
688
|
if (fixture.hookId) {
|
|
648
689
|
return fixture.hookId === this.options.hookId
|
|
649
690
|
}
|
|
@@ -657,13 +698,16 @@ export class ClientDevtoolsBridge<TSnapshot extends object> {
|
|
|
657
698
|
return true
|
|
658
699
|
}
|
|
659
700
|
|
|
660
|
-
|
|
701
|
+
protected createEnvelope(
|
|
661
702
|
eventType:
|
|
662
703
|
| 'hook:registered'
|
|
663
704
|
| 'hook:updated'
|
|
664
705
|
| 'hook:unregistered'
|
|
665
706
|
| 'hook:state-snapshot'
|
|
666
707
|
| 'tools:registered'
|
|
708
|
+
| 'memory:retrieve:started'
|
|
709
|
+
| 'memory:retrieve:completed'
|
|
710
|
+
| 'memory:snapshot'
|
|
667
711
|
| AIDevtoolsRunEventType,
|
|
668
712
|
visibility: AIDevtoolsEventVisibility = 'client-state',
|
|
669
713
|
context: { runId?: string } = {},
|
|
@@ -740,6 +784,8 @@ export class ChatDevtoolsBridge extends ClientDevtoolsBridge<AIDevtoolsChatSnaps
|
|
|
740
784
|
private currentStreamId: string | null = null
|
|
741
785
|
private lastStreamId: string | null = null
|
|
742
786
|
private lastRunEventContext: ChatClientRunEventContext | undefined
|
|
787
|
+
/** Last transported `memory:state` value, replayed when a panel opens. */
|
|
788
|
+
private lastMemoryStateValue: unknown = null
|
|
743
789
|
|
|
744
790
|
constructor(options: ChatDevtoolsBridgeOptions) {
|
|
745
791
|
super({
|
|
@@ -830,6 +876,78 @@ export class ChatDevtoolsBridge extends ClientDevtoolsBridge<AIDevtoolsChatSnaps
|
|
|
830
876
|
}
|
|
831
877
|
}
|
|
832
878
|
|
|
879
|
+
/**
|
|
880
|
+
* Record a transported `memory:state` value (the server memory middleware's
|
|
881
|
+
* per-turn recall metrics + store snapshot). Called from the chat client's
|
|
882
|
+
* `onCustomEvent` handler — the designated path for CUSTOM stream events —
|
|
883
|
+
* NOT from `observeChunk`. Re-emits the browser `memory:*` events the devtools
|
|
884
|
+
* store consumes, and caches the value so a panel opened later can replay it
|
|
885
|
+
* (see {@link onReplayState}). Symmetric with the generation bridge's
|
|
886
|
+
* `recordResultChange` / `recordProgressChange`.
|
|
887
|
+
*/
|
|
888
|
+
recordMemoryState(rawValue: unknown): void {
|
|
889
|
+
this.lastMemoryStateValue = rawValue
|
|
890
|
+
this.emitMemoryState(rawValue)
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Re-emit the browser-side `memory:*` events from a transported
|
|
895
|
+
* `memory:state` value. The devtools store consumes these to render the
|
|
896
|
+
* Memory tab (operations timeline + live contents). The recall pair mirrors
|
|
897
|
+
* the server middleware's own emits; the snapshot is included only when the
|
|
898
|
+
* adapter supports introspection.
|
|
899
|
+
*/
|
|
900
|
+
private emitMemoryState(rawValue: unknown): void {
|
|
901
|
+
if (!rawValue || typeof rawValue !== 'object') return
|
|
902
|
+
const value = rawValue as MemoryStateEventValue
|
|
903
|
+
const scope = value.scope
|
|
904
|
+
const adapter = value.adapter
|
|
905
|
+
if (!scope || typeof adapter !== 'string') return
|
|
906
|
+
const runContext = this.currentRunId ? { runId: this.currentRunId } : {}
|
|
907
|
+
|
|
908
|
+
emitAIDevtoolsEvent('memory:retrieve:started', {
|
|
909
|
+
...this.createEnvelope(
|
|
910
|
+
'memory:retrieve:started',
|
|
911
|
+
'client-state',
|
|
912
|
+
runContext,
|
|
913
|
+
),
|
|
914
|
+
scope,
|
|
915
|
+
adapter,
|
|
916
|
+
query: value.query ?? '',
|
|
917
|
+
})
|
|
918
|
+
if (value.recall) {
|
|
919
|
+
emitAIDevtoolsEvent('memory:retrieve:completed', {
|
|
920
|
+
...this.createEnvelope(
|
|
921
|
+
'memory:retrieve:completed',
|
|
922
|
+
'client-state',
|
|
923
|
+
runContext,
|
|
924
|
+
),
|
|
925
|
+
scope,
|
|
926
|
+
adapter,
|
|
927
|
+
fragmentCount: value.recall.fragmentCount ?? 0,
|
|
928
|
+
hasTools: Boolean(value.recall.hasTools),
|
|
929
|
+
systemPromptChars: value.recall.systemPromptChars ?? 0,
|
|
930
|
+
durationMs: value.recall.durationMs ?? 0,
|
|
931
|
+
})
|
|
932
|
+
}
|
|
933
|
+
if (value.snapshot) {
|
|
934
|
+
emitAIDevtoolsEvent('memory:snapshot', {
|
|
935
|
+
...this.createEnvelope('memory:snapshot', 'client-state', runContext),
|
|
936
|
+
scope,
|
|
937
|
+
adapter,
|
|
938
|
+
takenAt: value.snapshot.takenAt,
|
|
939
|
+
data: value.snapshot.data,
|
|
940
|
+
facts: value.snapshot.facts ?? [],
|
|
941
|
+
})
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
protected override onReplayState(): void {
|
|
946
|
+
if (this.lastMemoryStateValue != null) {
|
|
947
|
+
this.emitMemoryState(this.lastMemoryStateValue)
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
|
|
833
951
|
getCurrentRunEventContext(): ChatClientRunEventContext | undefined {
|
|
834
952
|
if (!this.currentRunId) return undefined
|
|
835
953
|
return {
|