@tanstack/ai-client 0.22.0 → 0.23.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.
Files changed (72) hide show
  1. package/README.md +15 -1
  2. package/dist/esm/audio-recorder.js +190 -213
  3. package/dist/esm/audio-recorder.js.map +1 -1
  4. package/dist/esm/chat-client.d.ts +172 -3
  5. package/dist/esm/chat-client.js +1656 -1386
  6. package/dist/esm/chat-client.js.map +1 -1
  7. package/dist/esm/cleared-stream-tracker.d.ts +23 -0
  8. package/dist/esm/cleared-stream-tracker.js +97 -0
  9. package/dist/esm/cleared-stream-tracker.js.map +1 -0
  10. package/dist/esm/client-persistor.d.ts +25 -12
  11. package/dist/esm/client-persistor.js +260 -235
  12. package/dist/esm/client-persistor.js.map +1 -1
  13. package/dist/esm/connection-adapters.d.ts +231 -10
  14. package/dist/esm/connection-adapters.js +989 -574
  15. package/dist/esm/connection-adapters.js.map +1 -1
  16. package/dist/esm/devtools-noop.d.ts +1 -0
  17. package/dist/esm/devtools-noop.js +79 -139
  18. package/dist/esm/devtools-noop.js.map +1 -1
  19. package/dist/esm/devtools.d.ts +31 -1
  20. package/dist/esm/devtools.js +977 -1127
  21. package/dist/esm/devtools.js.map +1 -1
  22. package/dist/esm/events.js +224 -226
  23. package/dist/esm/events.js.map +1 -1
  24. package/dist/esm/generation-client.d.ts +145 -2
  25. package/dist/esm/generation-client.js +659 -321
  26. package/dist/esm/generation-client.js.map +1 -1
  27. package/dist/esm/generation-reconstruct.d.ts +21 -0
  28. package/dist/esm/generation-reconstruct.js +85 -0
  29. package/dist/esm/generation-reconstruct.js.map +1 -0
  30. package/dist/esm/generation-types.d.ts +289 -3
  31. package/dist/esm/generation-types.js +356 -13
  32. package/dist/esm/generation-types.js.map +1 -1
  33. package/dist/esm/index.d.ts +9 -4
  34. package/dist/esm/index.js +7 -39
  35. package/dist/esm/interrupt-manager.d.ts +77 -0
  36. package/dist/esm/interrupt-manager.js +787 -0
  37. package/dist/esm/interrupt-manager.js.map +1 -0
  38. package/dist/esm/mcp-app-bridge.js +56 -64
  39. package/dist/esm/mcp-app-bridge.js.map +1 -1
  40. package/dist/esm/realtime-client.js +366 -440
  41. package/dist/esm/realtime-client.js.map +1 -1
  42. package/dist/esm/response-stream.js +19 -26
  43. package/dist/esm/response-stream.js.map +1 -1
  44. package/dist/esm/sse-parser.js +44 -47
  45. package/dist/esm/sse-parser.js.map +1 -1
  46. package/dist/esm/sse-utils.js +8 -9
  47. package/dist/esm/sse-utils.js.map +1 -1
  48. package/dist/esm/storage-adapters.d.ts +62 -0
  49. package/dist/esm/storage-adapters.js +174 -0
  50. package/dist/esm/storage-adapters.js.map +1 -0
  51. package/dist/esm/types.d.ts +212 -10
  52. package/dist/esm/types.js +38 -7
  53. package/dist/esm/types.js.map +1 -1
  54. package/dist/esm/video-generation-client.d.ts +113 -2
  55. package/dist/esm/video-generation-client.js +665 -379
  56. package/dist/esm/video-generation-client.js.map +1 -1
  57. package/package.json +7 -7
  58. package/src/chat-client.ts +1079 -61
  59. package/src/cleared-stream-tracker.ts +151 -0
  60. package/src/client-persistor.ts +102 -33
  61. package/src/connection-adapters.ts +1185 -142
  62. package/src/devtools-noop.ts +4 -3
  63. package/src/devtools.ts +121 -3
  64. package/src/generation-client.ts +563 -13
  65. package/src/generation-reconstruct.ts +121 -0
  66. package/src/generation-types.ts +727 -3
  67. package/src/index.ts +56 -1
  68. package/src/interrupt-manager.ts +1440 -0
  69. package/src/storage-adapters.ts +242 -0
  70. package/src/types.ts +301 -9
  71. package/src/video-generation-client.ts +479 -13
  72. package/dist/esm/index.js.map +0 -1
@@ -0,0 +1,121 @@
1
+ import type {
2
+ AudioGenerationResult,
3
+ ImageGenerationResult,
4
+ PersistedArtifactRef,
5
+ SummarizationResult,
6
+ TranscriptionResult,
7
+ TTSResult,
8
+ } from '@tanstack/ai'
9
+ import type { GenerationRestoredResult } from './generation-types'
10
+
11
+ /**
12
+ * Per-activity `reconstructResult` mappers. On mount restore the generic
13
+ * `GenerationClient` hands each specialized hook a {@link GenerationRestoredResult}
14
+ * (the metadata that survived persistence plus the durable artifact refs, each
15
+ * carrying its serve `url`); the mapper rebuilds the concrete typed result so
16
+ * `result` repaints as if the run had just finished, with media resolved to the
17
+ * durable serve route rather than the provider's expired link.
18
+ *
19
+ * A mapper returns `null` when the snapshot cannot rebuild a valid result; then
20
+ * `result` stays null while `status` / `error` / `resumeState` still repaint.
21
+ */
22
+
23
+ /** Output artifact refs of a given media type that carry a durable serve URL. */
24
+ function mediaUrls(
25
+ restored: GenerationRestoredResult,
26
+ mediaType: PersistedArtifactRef['source']['mediaType'],
27
+ ): Array<string> {
28
+ return restored.artifacts
29
+ .filter(
30
+ (a) =>
31
+ a.role === 'output' &&
32
+ a.source.mediaType === mediaType &&
33
+ a.url != null,
34
+ )
35
+ .map((a) => a.url as string)
36
+ }
37
+
38
+ /** image → `{ id, model, images: [{ url }], artifacts }`. */
39
+ export function reconstructImageResult(
40
+ restored: GenerationRestoredResult,
41
+ ): ImageGenerationResult | null {
42
+ const urls = mediaUrls(restored, 'image')
43
+ if (urls.length === 0) return null
44
+ return {
45
+ id: restored.id ?? '',
46
+ model: restored.model ?? '',
47
+ images: urls.map((url) => ({ url })),
48
+ ...(restored.artifacts.length > 0 ? { artifacts: restored.artifacts } : {}),
49
+ }
50
+ }
51
+
52
+ /**
53
+ * tts → `{ id, model, audio: '', format, contentType, artifacts }`.
54
+ *
55
+ * Unlike {@link reconstructAudioResult}, `TTSResult.audio` is a bare base64
56
+ * string with no URL slot, and server-driven persistence never stores the raw
57
+ * bytes — only the durable serve URL on the artifact ref. So the restored
58
+ * result surfaces the audio through `artifacts` (each carrying `url`); consumers
59
+ * play the restored clip from `result.artifacts[0].url` and fall back to the
60
+ * live base64 `audio` only for a just-finished (non-restored) run.
61
+ */
62
+ export function reconstructSpeechResult(
63
+ restored: GenerationRestoredResult,
64
+ ): TTSResult | null {
65
+ const ref = restored.artifacts.find(
66
+ (a) =>
67
+ a.role === 'output' && a.source.mediaType === 'audio' && a.url != null,
68
+ )
69
+ if (!ref) return null
70
+ const contentType = ref.mimeType || undefined
71
+ return {
72
+ id: restored.id ?? '',
73
+ model: restored.model ?? '',
74
+ // Bytes live in the blob store, served at `ref.url`; the base64 field can't
75
+ // be rebuilt from the snapshot, so it stays empty on restore.
76
+ audio: '',
77
+ format: contentType?.split('/')[1] ?? '',
78
+ ...(contentType ? { contentType } : {}),
79
+ artifacts: restored.artifacts,
80
+ }
81
+ }
82
+
83
+ /** audio → `{ id, model, audio: { url }, artifacts }`. */
84
+ export function reconstructAudioResult(
85
+ restored: GenerationRestoredResult,
86
+ ): AudioGenerationResult | null {
87
+ const [url] = mediaUrls(restored, 'audio')
88
+ if (!url) return null
89
+ return {
90
+ id: restored.id ?? '',
91
+ model: restored.model ?? '',
92
+ audio: { url },
93
+ ...(restored.artifacts.length > 0 ? { artifacts: restored.artifacts } : {}),
94
+ }
95
+ }
96
+
97
+ /** transcription → `{ id, model, text, artifacts }`. */
98
+ export function reconstructTranscriptionResult(
99
+ restored: GenerationRestoredResult,
100
+ ): TranscriptionResult | null {
101
+ if (restored.text === undefined) return null
102
+ return {
103
+ id: restored.id ?? '',
104
+ model: restored.model ?? '',
105
+ text: restored.text,
106
+ ...(restored.artifacts.length > 0 ? { artifacts: restored.artifacts } : {}),
107
+ }
108
+ }
109
+
110
+ /** summarize → `{ id, model, summary, usage }` (needs persisted `usage`). */
111
+ export function reconstructSummarizeResult(
112
+ restored: GenerationRestoredResult,
113
+ ): SummarizationResult | null {
114
+ if (restored.text === undefined || restored.usage === undefined) return null
115
+ return {
116
+ id: restored.id ?? '',
117
+ model: restored.model ?? '',
118
+ summary: restored.text,
119
+ usage: restored.usage,
120
+ }
121
+ }