@tanstack/ai 0.61.0 → 0.64.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 (104) hide show
  1. package/README.md +1 -0
  2. package/dist/esm/activities/chat/agents/define-agent.d.ts +17 -5
  3. package/dist/esm/activities/chat/agents/define-agent.js.map +1 -1
  4. package/dist/esm/activities/chat/agents/spawn.d.ts +2 -0
  5. package/dist/esm/activities/chat/agents/spawn.js +10 -33
  6. package/dist/esm/activities/chat/agents/spawn.js.map +1 -1
  7. package/dist/esm/activities/chat/index.d.ts +2 -0
  8. package/dist/esm/activities/chat/index.js +166 -60
  9. package/dist/esm/activities/chat/index.js.map +1 -1
  10. package/dist/esm/activities/chat/messages.js +43 -22
  11. package/dist/esm/activities/chat/messages.js.map +1 -1
  12. package/dist/esm/activities/chat/middleware/types.d.ts +1 -0
  13. package/dist/esm/activities/chat/middleware/types.js.map +1 -1
  14. package/dist/esm/activities/chat/stream/message-updaters.d.ts +2 -2
  15. package/dist/esm/activities/chat/stream/message-updaters.js +6 -2
  16. package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
  17. package/dist/esm/activities/chat/stream/processor.d.ts +11 -9
  18. package/dist/esm/activities/chat/stream/processor.js +38 -18
  19. package/dist/esm/activities/chat/stream/processor.js.map +1 -1
  20. package/dist/esm/activities/chat/tools/schema-converter.d.ts +8 -0
  21. package/dist/esm/activities/chat/tools/schema-converter.js +6 -5
  22. package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -1
  23. package/dist/esm/activities/chat/tools/tool-calls.d.ts +20 -3
  24. package/dist/esm/activities/chat/tools/tool-calls.js +126 -36
  25. package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
  26. package/dist/esm/activities/chat/tools/tool-definition.d.ts +4 -0
  27. package/dist/esm/activities/chat/tools/tool-definition.js +4 -0
  28. package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
  29. package/dist/esm/activities/evaluate/adapter.d.ts +4 -0
  30. package/dist/esm/activities/evaluate/adapter.js.map +1 -1
  31. package/dist/esm/activities/evaluate/index.d.ts +4 -0
  32. package/dist/esm/activities/evaluate/index.js +3 -1
  33. package/dist/esm/activities/evaluate/index.js.map +1 -1
  34. package/dist/esm/activities/generateSpeech/index.d.ts +1 -1
  35. package/dist/esm/activities/generateSpeech/index.js +1 -1
  36. package/dist/esm/activities/generateSpeech/index.js.map +1 -1
  37. package/dist/esm/activities/generateVideo/adapter.d.ts +14 -6
  38. package/dist/esm/activities/generateVideo/adapter.js +6 -3
  39. package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
  40. package/dist/esm/activities/generateVideo/index.d.ts +5 -4
  41. package/dist/esm/activities/generateVideo/index.js.map +1 -1
  42. package/dist/esm/activities/generateVideo/snap.d.ts +12 -3
  43. package/dist/esm/activities/generateVideo/snap.js +47 -8
  44. package/dist/esm/activities/generateVideo/snap.js.map +1 -1
  45. package/dist/esm/activities/generateVoice/index.d.ts +1 -1
  46. package/dist/esm/activities/generateVoice/index.js +1 -1
  47. package/dist/esm/activities/generateVoice/index.js.map +1 -1
  48. package/dist/esm/activities/index.d.ts +2 -2
  49. package/dist/esm/activities/index.js +2 -2
  50. package/dist/esm/adapter-internals.d.ts +1 -0
  51. package/dist/esm/adapter-internals.js +2 -1
  52. package/dist/esm/client.d.ts +1 -1
  53. package/dist/esm/client.js.map +1 -1
  54. package/dist/esm/index.d.ts +1 -1
  55. package/dist/esm/index.js +2 -2
  56. package/dist/esm/interrupt-resume.js +29 -4
  57. package/dist/esm/interrupt-resume.js.map +1 -1
  58. package/dist/esm/middlewares/otel.d.ts +5 -2
  59. package/dist/esm/middlewares/otel.js +114 -0
  60. package/dist/esm/middlewares/otel.js.map +1 -1
  61. package/dist/esm/types.d.ts +70 -4
  62. package/dist/esm/utilities/ag-ui-wire.js +8 -4
  63. package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
  64. package/dist/esm/utilities/merge-streams.d.ts +6 -0
  65. package/dist/esm/utilities/merge-streams.js +37 -0
  66. package/dist/esm/utilities/merge-streams.js.map +1 -0
  67. package/dist/esm/utilities/reasoning-encrypted-value.d.ts +8 -0
  68. package/dist/esm/utilities/reasoning-encrypted-value.js +11 -1
  69. package/dist/esm/utilities/reasoning-encrypted-value.js.map +1 -1
  70. package/dist/esm/utilities/tool-result.d.ts +2 -1
  71. package/dist/esm/utilities/tool-result.js +4 -1
  72. package/dist/esm/utilities/tool-result.js.map +1 -1
  73. package/package.json +3 -3
  74. package/skills/ai-core/chat-experience/SKILL.md +120 -0
  75. package/skills/ai-core/media-generation/SKILL.md +3 -3
  76. package/skills/ai-core/tool-calling/SKILL.md +103 -0
  77. package/src/activities/chat/agents/define-agent.ts +20 -3
  78. package/src/activities/chat/agents/spawn.ts +22 -43
  79. package/src/activities/chat/index.ts +248 -65
  80. package/src/activities/chat/messages.ts +54 -7
  81. package/src/activities/chat/middleware/types.ts +1 -0
  82. package/src/activities/chat/stream/message-updaters.ts +8 -0
  83. package/src/activities/chat/stream/processor.ts +57 -27
  84. package/src/activities/chat/tools/schema-converter.ts +17 -5
  85. package/src/activities/chat/tools/tool-calls.ts +215 -68
  86. package/src/activities/chat/tools/tool-definition.ts +8 -0
  87. package/src/activities/evaluate/adapter.ts +4 -0
  88. package/src/activities/evaluate/index.ts +6 -0
  89. package/src/activities/generateSpeech/index.ts +1 -1
  90. package/src/activities/generateVideo/adapter.ts +21 -7
  91. package/src/activities/generateVideo/index.ts +5 -4
  92. package/src/activities/generateVideo/snap.ts +64 -6
  93. package/src/activities/generateVoice/index.ts +1 -1
  94. package/src/activities/index.ts +2 -1
  95. package/src/adapter-internals.ts +1 -0
  96. package/src/client.ts +1 -0
  97. package/src/index.ts +1 -0
  98. package/src/interrupt-resume.ts +55 -4
  99. package/src/middlewares/otel.ts +161 -3
  100. package/src/types.ts +66 -5
  101. package/src/utilities/ag-ui-wire.ts +17 -2
  102. package/src/utilities/merge-streams.ts +34 -0
  103. package/src/utilities/reasoning-encrypted-value.ts +12 -0
  104. package/src/utilities/tool-result.ts +7 -1
@@ -14,12 +14,14 @@ import type {
14
14
  StructuredOutputPart,
15
15
  SubagentPart,
16
16
  TanStackMessageMetadata,
17
+ ToolResultOutcome,
17
18
  UIMessage,
18
19
  UIResourcePart,
19
20
  } from '../types'
20
21
  import type { MetadataRecord } from './merge-metadata'
21
22
  import { tanstackMetadata } from './merge-metadata'
22
23
  import { isProviderExecutedToolCall } from './provider-executed'
24
+ import { REDACTED_THINKING_ID_PREFIX } from './reasoning-encrypted-value'
23
25
  import { normalizeToolResult } from './tool-result'
24
26
  import { wireSubagentInfo, wireSubagentRunId } from './subagent-wire'
25
27
  import type { SubagentWireInfo } from './subagent-wire'
@@ -49,6 +51,7 @@ function rebuiltToolMetadata(
49
51
  id: string | undefined,
50
52
  content: string | null | Array<ContentPart>,
51
53
  anchorOwnsUiResources = false,
54
+ outcome?: ToolResultOutcome,
52
55
  ): MetadataRecord | undefined {
53
56
  const source: MetadataRecord = isRecord(metadata) ? metadata : {}
54
57
  const tanstack = isRecord(source.tanstack) ? { ...source.tanstack } : {}
@@ -61,7 +64,11 @@ function rebuiltToolMetadata(
61
64
  }
62
65
  const result = {
63
66
  ...source,
64
- tanstack: { ...tanstack, toolResult },
67
+ tanstack: {
68
+ ...tanstack,
69
+ ...(outcome !== undefined && { toolResultOutcome: outcome }),
70
+ toolResult,
71
+ },
65
72
  }
66
73
  return Object.keys(result).length ? result : undefined
67
74
  }
@@ -262,6 +269,7 @@ export function uiMessagesToWire(
262
269
  part.id,
263
270
  part.content,
264
271
  true,
272
+ part.outcome,
265
273
  )
266
274
  wire.push({
267
275
  role: 'tool',
@@ -306,6 +314,8 @@ export function uiMessagesToWire(
306
314
  undefined,
307
315
  undefined,
308
316
  result,
317
+ false,
318
+ part.approval?.approved === false ? 'denied' : undefined,
309
319
  ),
310
320
  })
311
321
  }
@@ -385,6 +395,8 @@ function messageMetadata(
385
395
  tanstack.model = previousTanstack.model
386
396
  if (previousTanstack?.runId !== undefined)
387
397
  tanstack.runId = previousTanstack.runId
398
+ if (previousTanstack?.run?.id !== undefined)
399
+ tanstack.run = { id: previousTanstack.run.id }
388
400
  if (previousTanstack?.signature !== undefined)
389
401
  tanstack.signature = previousTanstack.signature
390
402
  const createdAt = coerceCreatedAt(msg.createdAt)
@@ -603,7 +615,10 @@ function collectToolCalls(
603
615
  }
604
616
 
605
617
  function deriveReasoningId(messageId: string, part: MessagePart): string {
606
- return `${messageId}-reasoning-${(part as { id?: string }).id ?? hashContent((part as { content: string }).content)}`
618
+ const id = `${messageId}-reasoning-${(part as { id?: string }).id ?? hashContent((part as { content: string }).content)}`
619
+ return part.type === 'thinking' && part.redacted
620
+ ? `${REDACTED_THINKING_ID_PREFIX}${id}`
621
+ : id
607
622
  }
608
623
 
609
624
  function deriveToolMessageId(toolCallId: string): string {
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Yield the items of several async streams as they arrive. If the reader
3
+ * stops early, every stream that is still open is closed, so its `finally`
4
+ * runs.
5
+ */
6
+ export async function* mergeStreams<T>(streams: Array<AsyncIterable<T>>) {
7
+ const readers = streams.map((stream) => {
8
+ const iterator = stream[Symbol.asyncIterator]()
9
+ return {
10
+ iterator,
11
+ next: iterator.next(),
12
+ }
13
+ })
14
+
15
+ try {
16
+ while (readers.length > 0) {
17
+ const indexed = readers.map((reader, index) =>
18
+ reader.next.then((result) => ({ index, result, reader })),
19
+ )
20
+ const winner = await Promise.race(indexed)
21
+ if (winner.result.done) {
22
+ readers.splice(winner.index, 1)
23
+ continue
24
+ }
25
+ yield winner.result.value
26
+ winner.reader.next = winner.reader.iterator.next()
27
+ }
28
+ } finally {
29
+ // The reader stopped early. Close every stream so its finally runs.
30
+ for (const reader of readers) {
31
+ void reader.iterator.return?.().catch(() => {})
32
+ }
33
+ }
34
+ }
@@ -16,3 +16,15 @@ export function reasoningEncryptedValue(opts: {
16
16
  ...(opts.timestamp !== undefined ? { timestamp: opts.timestamp } : {}),
17
17
  }
18
18
  }
19
+
20
+ /**
21
+ * Id prefix for the reasoning message of a redacted thinking block (Anthropic
22
+ * `redacted_thinking`). AG-UI's `encryptedValue` does not say what kind of
23
+ * bytes it holds (ag-ui-protocol/ag-ui#2884), so the id that `entityId` points
24
+ * to says it. AG-UI clients keep message ids, but they drop event metadata.
25
+ */
26
+ export const REDACTED_THINKING_ID_PREFIX = 'redacted_thinking-'
27
+
28
+ export function isRedactedThinkingId(id: unknown): boolean {
29
+ return typeof id === 'string' && id.startsWith(REDACTED_THINKING_ID_PREFIX)
30
+ }
@@ -1,4 +1,4 @@
1
- import type { ContentPart } from '../types'
1
+ import type { ContentPart, ToolResultOutcome } from '../types'
2
2
 
3
3
  const CONTENT_PART_TYPES = new Set([
4
4
  'text',
@@ -8,6 +8,12 @@ const CONTENT_PART_TYPES = new Set([
8
8
  'document',
9
9
  ])
10
10
 
11
+ export function isToolResultOutcome(
12
+ value: unknown,
13
+ ): value is ToolResultOutcome {
14
+ return value === 'cancelled' || value === 'denied'
15
+ }
16
+
11
17
  /**
12
18
  * Structural check for a single `ContentPart`. A text part must carry a string
13
19
  * `content`. Every other part carries a source with a string `value`; a file