@tanstack/ai 0.41.0 → 0.43.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/README.md +15 -1
- package/dist/esm/activities/chat/adapter.js +23 -16
- package/dist/esm/activities/chat/adapter.js.map +1 -1
- package/dist/esm/activities/chat/agent-loop-strategies.d.ts +10 -4
- package/dist/esm/activities/chat/agent-loop-strategies.js +75 -17
- package/dist/esm/activities/chat/agent-loop-strategies.js.map +1 -1
- package/dist/esm/activities/chat/cancel.d.ts +40 -0
- package/dist/esm/activities/chat/cancel.js +54 -0
- package/dist/esm/activities/chat/cancel.js.map +1 -0
- package/dist/esm/activities/chat/index.d.ts +28 -16
- package/dist/esm/activities/chat/index.js +2100 -1744
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/mcp/manager.d.ts +2 -2
- package/dist/esm/activities/chat/mcp/manager.js +90 -77
- package/dist/esm/activities/chat/mcp/manager.js.map +1 -1
- package/dist/esm/activities/chat/mcp/types.d.ts +2 -2
- package/dist/esm/activities/chat/messages.js +397 -346
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/middleware/builder.js +17 -15
- package/dist/esm/activities/chat/middleware/builder.js.map +1 -1
- package/dist/esm/activities/chat/middleware/capabilities.js +78 -43
- package/dist/esm/activities/chat/middleware/capabilities.js.map +1 -1
- package/dist/esm/activities/chat/middleware/compose.d.ts +94 -1
- package/dist/esm/activities/chat/middleware/compose.js +623 -531
- package/dist/esm/activities/chat/middleware/compose.js.map +1 -1
- package/dist/esm/activities/chat/middleware/define.js +12 -5
- package/dist/esm/activities/chat/middleware/define.js.map +1 -1
- package/dist/esm/activities/chat/middleware/index.d.ts +5 -1
- package/dist/esm/activities/chat/middleware/locks.d.ts +50 -0
- package/dist/esm/activities/chat/middleware/locks.js +71 -0
- package/dist/esm/activities/chat/middleware/locks.js.map +1 -0
- package/dist/esm/activities/chat/middleware/pending-turn.d.ts +15 -0
- package/dist/esm/activities/chat/middleware/pending-turn.js +35 -0
- package/dist/esm/activities/chat/middleware/pending-turn.js.map +1 -0
- package/dist/esm/activities/chat/middleware/run-disconnect.d.ts +23 -0
- package/dist/esm/activities/chat/middleware/run-disconnect.js +42 -0
- package/dist/esm/activities/chat/middleware/run-disconnect.js.map +1 -0
- package/dist/esm/activities/chat/middleware/run-store.d.ts +283 -0
- package/dist/esm/activities/chat/middleware/run-store.js +176 -0
- package/dist/esm/activities/chat/middleware/run-store.js.map +1 -0
- package/dist/esm/activities/chat/middleware/sandbox-runtime.js +14 -8
- package/dist/esm/activities/chat/middleware/sandbox-runtime.js.map +1 -1
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js +79 -70
- package/dist/esm/activities/chat/middleware/tool-cache-middleware.js.map +1 -1
- package/dist/esm/activities/chat/middleware/types.d.ts +59 -2
- package/dist/esm/activities/chat/middleware/validate.js +23 -28
- package/dist/esm/activities/chat/middleware/validate.js.map +1 -1
- package/dist/esm/activities/chat/stream/json-parser.js +39 -25
- package/dist/esm/activities/chat/stream/json-parser.js.map +1 -1
- package/dist/esm/activities/chat/stream/message-updaters.js +275 -234
- package/dist/esm/activities/chat/stream/message-updaters.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +24 -4
- package/dist/esm/activities/chat/stream/processor.js +1341 -1542
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/chat/stream/strategies.js +69 -53
- package/dist/esm/activities/chat/stream/strategies.js.map +1 -1
- package/dist/esm/activities/chat/tools/approval-schema.d.ts +19 -0
- package/dist/esm/activities/chat/tools/approval-schema.js +117 -0
- package/dist/esm/activities/chat/tools/approval-schema.js.map +1 -0
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js +164 -191
- package/dist/esm/activities/chat/tools/lazy-tool-manager.js.map +1 -1
- package/dist/esm/activities/chat/tools/lazy-tools.js +24 -12
- package/dist/esm/activities/chat/tools/lazy-tools.js.map +1 -1
- package/dist/esm/activities/chat/tools/schema-converter.js +293 -146
- package/dist/esm/activities/chat/tools/schema-converter.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-calls.d.ts +18 -2
- package/dist/esm/activities/chat/tools/tool-calls.js +522 -531
- package/dist/esm/activities/chat/tools/tool-calls.js.map +1 -1
- package/dist/esm/activities/chat/tools/tool-definition.d.ts +75 -16
- package/dist/esm/activities/chat/tools/tool-definition.js +95 -23
- package/dist/esm/activities/chat/tools/tool-definition.js.map +1 -1
- package/dist/esm/activities/error-payload.js +85 -47
- package/dist/esm/activities/error-payload.js.map +1 -1
- package/dist/esm/activities/generateAudio/adapter.js +22 -15
- package/dist/esm/activities/generateAudio/adapter.js.map +1 -1
- package/dist/esm/activities/generateAudio/index.d.ts +4 -0
- package/dist/esm/activities/generateAudio/index.js +141 -105
- package/dist/esm/activities/generateAudio/index.js.map +1 -1
- package/dist/esm/activities/generateImage/adapter.js +22 -15
- package/dist/esm/activities/generateImage/adapter.js.map +1 -1
- package/dist/esm/activities/generateImage/index.d.ts +4 -0
- package/dist/esm/activities/generateImage/index.js +155 -111
- package/dist/esm/activities/generateImage/index.js.map +1 -1
- package/dist/esm/activities/generateSpeech/adapter.js +22 -15
- package/dist/esm/activities/generateSpeech/adapter.js.map +1 -1
- package/dist/esm/activities/generateSpeech/index.d.ts +4 -0
- package/dist/esm/activities/generateSpeech/index.js +159 -110
- package/dist/esm/activities/generateSpeech/index.js.map +1 -1
- package/dist/esm/activities/generateTranscription/adapter.js +22 -15
- package/dist/esm/activities/generateTranscription/adapter.js.map +1 -1
- package/dist/esm/activities/generateTranscription/index.d.ts +4 -0
- package/dist/esm/activities/generateTranscription/index.js +159 -100
- package/dist/esm/activities/generateTranscription/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/adapter.js +36 -29
- package/dist/esm/activities/generateVideo/adapter.js.map +1 -1
- package/dist/esm/activities/generateVideo/index.d.ts +143 -19
- package/dist/esm/activities/generateVideo/index.js +456 -279
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/generateVideo/snap.js +60 -48
- package/dist/esm/activities/generateVideo/snap.js.map +1 -1
- package/dist/esm/activities/index.js +8 -34
- package/dist/esm/activities/middleware/index.d.ts +1 -1
- package/dist/esm/activities/middleware/run.d.ts +10 -0
- package/dist/esm/activities/middleware/run.js +53 -29
- package/dist/esm/activities/middleware/run.js.map +1 -1
- package/dist/esm/activities/middleware/types.d.ts +44 -6
- package/dist/esm/activities/stream-generation-result.d.ts +4 -1
- package/dist/esm/activities/stream-generation-result.js +79 -44
- package/dist/esm/activities/stream-generation-result.js.map +1 -1
- package/dist/esm/activities/summarize/adapter.js +22 -15
- package/dist/esm/activities/summarize/adapter.js.map +1 -1
- package/dist/esm/activities/summarize/chat-stream-summarize.js +252 -202
- package/dist/esm/activities/summarize/chat-stream-summarize.js.map +1 -1
- package/dist/esm/activities/summarize/index.d.ts +27 -0
- package/dist/esm/activities/summarize/index.js +268 -102
- package/dist/esm/activities/summarize/index.js.map +1 -1
- package/dist/esm/adapter-internals.d.ts +2 -1
- package/dist/esm/adapter-internals.js +4 -11
- package/dist/esm/client.d.ts +25 -3
- package/dist/esm/client.js +131 -64
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/custom-events.d.ts +76 -0
- package/dist/esm/custom-events.js +37 -0
- package/dist/esm/custom-events.js.map +1 -0
- package/dist/esm/delivery-detach.d.ts +50 -0
- package/dist/esm/delivery-detach.js +71 -0
- package/dist/esm/delivery-detach.js.map +1 -0
- package/dist/esm/delivery-disconnect.d.ts +62 -0
- package/dist/esm/delivery-disconnect.js +81 -0
- package/dist/esm/delivery-disconnect.js.map +1 -0
- package/dist/esm/extend-adapter.js +19 -17
- package/dist/esm/extend-adapter.js.map +1 -1
- package/dist/esm/index.d.ts +23 -5
- package/dist/esm/index.js +30 -97
- package/dist/esm/interrupt-resume.d.ts +71 -0
- package/dist/esm/interrupt-resume.js +438 -0
- package/dist/esm/interrupt-resume.js.map +1 -0
- package/dist/esm/interrupt-serialization.d.ts +12 -0
- package/dist/esm/interrupt-serialization.js +178 -0
- package/dist/esm/interrupt-serialization.js.map +1 -0
- package/dist/esm/interrupts.d.ts +84 -0
- package/dist/esm/interrupts.js +31 -0
- package/dist/esm/interrupts.js.map +1 -0
- package/dist/esm/locks.d.ts +10 -0
- package/dist/esm/locks.js +2 -0
- package/dist/esm/logger/console-logger.js +101 -78
- package/dist/esm/logger/console-logger.js.map +1 -1
- package/dist/esm/logger/internal-logger.js +104 -89
- package/dist/esm/logger/internal-logger.js.map +1 -1
- package/dist/esm/logger/resolve.js +54 -49
- package/dist/esm/logger/resolve.js.map +1 -1
- package/dist/esm/logger/types.d.ts +1 -1
- package/dist/esm/middlewares/content-guard.js +142 -148
- package/dist/esm/middlewares/content-guard.js.map +1 -1
- package/dist/esm/middlewares/index.js +2 -6
- package/dist/esm/middlewares/otel.js +598 -732
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/middlewares/usage-attributes.js +47 -40
- package/dist/esm/middlewares/usage-attributes.js.map +1 -1
- package/dist/esm/realtime/event-emitter.js +24 -25
- package/dist/esm/realtime/event-emitter.js.map +1 -1
- package/dist/esm/realtime/index.d.ts +5 -9
- package/dist/esm/realtime/index.js +29 -6
- package/dist/esm/realtime/index.js.map +1 -1
- package/dist/esm/scope.d.ts +47 -0
- package/dist/esm/stream-durability.d.ts +171 -0
- package/dist/esm/stream-durability.js +295 -0
- package/dist/esm/stream-durability.js.map +1 -0
- package/dist/esm/stream-to-response.d.ts +178 -13
- package/dist/esm/stream-to-response.js +663 -115
- package/dist/esm/stream-to-response.js.map +1 -1
- package/dist/esm/strip-to-spec-middleware.js +30 -16
- package/dist/esm/strip-to-spec-middleware.js.map +1 -1
- package/dist/esm/system-prompts.js +27 -21
- package/dist/esm/system-prompts.js.map +1 -1
- package/dist/esm/tool-registry.js +72 -45
- package/dist/esm/tool-registry.js.map +1 -1
- package/dist/esm/tools/provider-tool.js +14 -5
- package/dist/esm/tools/provider-tool.js.map +1 -1
- package/dist/esm/types.d.ts +332 -21
- package/dist/esm/types.js +2 -0
- package/dist/esm/utilities/ag-ui-wire.js +79 -93
- package/dist/esm/utilities/ag-ui-wire.js.map +1 -1
- package/dist/esm/utilities/chat-params.d.ts +26 -4
- package/dist/esm/utilities/chat-params.js +218 -92
- package/dist/esm/utilities/chat-params.js.map +1 -1
- package/dist/esm/utilities/errors.js +28 -18
- package/dist/esm/utilities/errors.js.map +1 -1
- package/dist/esm/utilities/media-prompt.js +46 -41
- package/dist/esm/utilities/media-prompt.js.map +1 -1
- package/dist/esm/utilities/numbers.js +13 -10
- package/dist/esm/utilities/numbers.js.map +1 -1
- package/dist/esm/utilities/provider-executed.js +20 -11
- package/dist/esm/utilities/provider-executed.js.map +1 -1
- package/dist/esm/utilities/sampling-keys.js +31 -19
- package/dist/esm/utilities/sampling-keys.js.map +1 -1
- package/dist/esm/utilities/tool-result.js +42 -30
- package/dist/esm/utilities/tool-result.js.map +1 -1
- package/dist/esm/utilities/usage.js +27 -9
- package/dist/esm/utilities/usage.js.map +1 -1
- package/dist/esm/utils.js +26 -18
- package/dist/esm/utils.js.map +1 -1
- package/package.json +10 -6
- package/skills/ai-core/SKILL.md +69 -18
- package/skills/ai-core/adapter-configuration/SKILL.md +44 -21
- package/skills/ai-core/adapter-configuration/references/anthropic-adapter.md +1 -3
- package/skills/ai-core/adapter-configuration/references/byteplus-adapter.md +148 -0
- package/skills/ai-core/adapter-configuration/references/gemini-adapter.md +2 -6
- package/skills/ai-core/adapter-configuration/references/groq-adapter.md +2 -6
- package/skills/ai-core/adapter-configuration/references/openai-adapter.md +1 -3
- package/skills/ai-core/ag-ui-protocol/SKILL.md +1 -1
- package/skills/ai-core/chat-experience/SKILL.md +156 -11
- package/skills/ai-core/client-persistence/SKILL.md +277 -0
- package/skills/ai-core/custom-backend-integration/SKILL.md +1 -1
- package/skills/ai-core/debug-logging/SKILL.md +1 -1
- package/skills/ai-core/locks/SKILL.md +143 -0
- package/skills/ai-core/media-generation/SKILL.md +144 -12
- package/skills/ai-core/middleware/SKILL.md +258 -33
- package/skills/ai-core/structured-outputs/SKILL.md +1 -1
- package/skills/ai-core/tool-calling/SKILL.md +54 -59
- package/src/activities/chat/agent-loop-strategies.ts +10 -4
- package/src/activities/chat/cancel.ts +81 -0
- package/src/activities/chat/index.ts +1152 -153
- package/src/activities/chat/mcp/manager.ts +4 -4
- package/src/activities/chat/mcp/types.ts +2 -2
- package/src/activities/chat/messages.ts +5 -3
- package/src/activities/chat/middleware/builder.ts +1 -1
- package/src/activities/chat/middleware/compose.ts +186 -9
- package/src/activities/chat/middleware/index.ts +26 -0
- package/src/activities/chat/middleware/locks.ts +102 -0
- package/src/activities/chat/middleware/pending-turn.ts +47 -0
- package/src/activities/chat/middleware/run-disconnect.ts +62 -0
- package/src/activities/chat/middleware/run-store.ts +412 -0
- package/src/activities/chat/middleware/types.ts +62 -1
- package/src/activities/chat/stream/processor.ts +189 -5
- package/src/activities/chat/tools/approval-schema.ts +205 -0
- package/src/activities/chat/tools/tool-calls.ts +106 -13
- package/src/activities/chat/tools/tool-definition.ts +210 -39
- package/src/activities/generateAudio/index.ts +20 -3
- package/src/activities/generateImage/index.ts +20 -3
- package/src/activities/generateSpeech/index.ts +25 -3
- package/src/activities/generateTranscription/index.ts +26 -3
- package/src/activities/generateVideo/index.ts +345 -82
- package/src/activities/middleware/index.ts +2 -0
- package/src/activities/middleware/run.ts +31 -0
- package/src/activities/middleware/types.ts +49 -5
- package/src/activities/stream-generation-result.ts +30 -2
- package/src/activities/summarize/chat-stream-summarize.ts +5 -0
- package/src/activities/summarize/index.ts +200 -10
- package/src/adapter-internals.ts +10 -1
- package/src/client.ts +244 -0
- package/src/custom-events.ts +107 -0
- package/src/delivery-detach.ts +72 -0
- package/src/delivery-disconnect.ts +84 -0
- package/src/index.ts +138 -0
- package/src/interrupt-resume.ts +824 -0
- package/src/interrupt-serialization.ts +183 -0
- package/src/interrupts.ts +146 -0
- package/src/locks.ts +17 -0
- package/src/logger/types.ts +1 -1
- package/src/middlewares/otel.ts +1 -0
- package/src/realtime/index.ts +5 -9
- package/src/scope.ts +47 -0
- package/src/stream-durability.ts +598 -0
- package/src/stream-to-response.ts +1051 -95
- package/src/strip-to-spec-middleware.ts +3 -3
- package/src/types.ts +416 -24
- package/src/utilities/chat-params.ts +245 -55
- package/dist/esm/activities/index.js.map +0 -1
- package/dist/esm/adapter-internals.js.map +0 -1
- package/dist/esm/index.js.map +0 -1
- package/dist/esm/middlewares/index.js.map +0 -1
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// Dependency-free SHA-256 (FIPS 180-4). Sync and isomorphic (Node + browser)
|
|
2
|
+
// so interrupt hashing needs no crypto library. Users can replace the whole
|
|
3
|
+
// algorithm through the `interrupts.hash` option; this is only the default.
|
|
4
|
+
// ponytail: bundled ~60-line hash, swap via interrupts.hash if you need more.
|
|
5
|
+
const SHA256_K = new Uint32Array([
|
|
6
|
+
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
|
|
7
|
+
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
|
|
8
|
+
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
|
|
9
|
+
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
|
10
|
+
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
|
|
11
|
+
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
|
|
12
|
+
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
|
|
13
|
+
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
|
|
14
|
+
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
|
|
15
|
+
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
|
|
16
|
+
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
|
|
17
|
+
])
|
|
18
|
+
|
|
19
|
+
function rotr(x: number, n: number): number {
|
|
20
|
+
return (x >>> n) | (x << (32 - n))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function sha256Hex(input: string): string {
|
|
24
|
+
const msg = new TextEncoder().encode(input)
|
|
25
|
+
|
|
26
|
+
const bitLen = msg.length * 8
|
|
27
|
+
const withOne = msg.length + 1
|
|
28
|
+
const total = withOne + ((56 - (withOne % 64) + 64) % 64) + 8
|
|
29
|
+
const bytes = new Uint8Array(total)
|
|
30
|
+
bytes.set(msg)
|
|
31
|
+
bytes[msg.length] = 0x80
|
|
32
|
+
const view = new DataView(bytes.buffer)
|
|
33
|
+
view.setUint32(total - 8, Math.floor(bitLen / 0x100000000))
|
|
34
|
+
view.setUint32(total - 4, bitLen >>> 0)
|
|
35
|
+
|
|
36
|
+
let h0 = 0x6a09e667
|
|
37
|
+
let h1 = 0xbb67ae85
|
|
38
|
+
let h2 = 0x3c6ef372
|
|
39
|
+
let h3 = 0xa54ff53a
|
|
40
|
+
let h4 = 0x510e527f
|
|
41
|
+
let h5 = 0x9b05688c
|
|
42
|
+
let h6 = 0x1f83d9ab
|
|
43
|
+
let h7 = 0x5be0cd19
|
|
44
|
+
|
|
45
|
+
const w = new Uint32Array(64)
|
|
46
|
+
for (let offset = 0; offset < total; offset += 64) {
|
|
47
|
+
for (let i = 0; i < 16; i++) w[i] = view.getUint32(offset + i * 4)
|
|
48
|
+
for (let i = 16; i < 64; i++) {
|
|
49
|
+
const x15 = w[i - 15] ?? 0
|
|
50
|
+
const x2 = w[i - 2] ?? 0
|
|
51
|
+
const s0 = rotr(x15, 7) ^ rotr(x15, 18) ^ (x15 >>> 3)
|
|
52
|
+
const s1 = rotr(x2, 17) ^ rotr(x2, 19) ^ (x2 >>> 10)
|
|
53
|
+
w[i] = ((w[i - 16] ?? 0) + s0 + (w[i - 7] ?? 0) + s1) >>> 0
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let a = h0
|
|
57
|
+
let b = h1
|
|
58
|
+
let c = h2
|
|
59
|
+
let d = h3
|
|
60
|
+
let e = h4
|
|
61
|
+
let f = h5
|
|
62
|
+
let g = h6
|
|
63
|
+
let hh = h7
|
|
64
|
+
for (let i = 0; i < 64; i++) {
|
|
65
|
+
const bigS1 = rotr(e, 6) ^ rotr(e, 11) ^ rotr(e, 25)
|
|
66
|
+
const ch = (e & f) ^ (~e & g)
|
|
67
|
+
const t1 = (hh + bigS1 + ch + (SHA256_K[i] ?? 0) + (w[i] ?? 0)) >>> 0
|
|
68
|
+
const bigS0 = rotr(a, 2) ^ rotr(a, 13) ^ rotr(a, 22)
|
|
69
|
+
const maj = (a & b) ^ (a & c) ^ (b & c)
|
|
70
|
+
const t2 = (bigS0 + maj) >>> 0
|
|
71
|
+
hh = g
|
|
72
|
+
g = f
|
|
73
|
+
f = e
|
|
74
|
+
e = (d + t1) >>> 0
|
|
75
|
+
d = c
|
|
76
|
+
c = b
|
|
77
|
+
b = a
|
|
78
|
+
a = (t1 + t2) >>> 0
|
|
79
|
+
}
|
|
80
|
+
h0 = (h0 + a) >>> 0
|
|
81
|
+
h1 = (h1 + b) >>> 0
|
|
82
|
+
h2 = (h2 + c) >>> 0
|
|
83
|
+
h3 = (h3 + d) >>> 0
|
|
84
|
+
h4 = (h4 + e) >>> 0
|
|
85
|
+
h5 = (h5 + f) >>> 0
|
|
86
|
+
h6 = (h6 + g) >>> 0
|
|
87
|
+
h7 = (h7 + hh) >>> 0
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const hex = (n: number): string => (n >>> 0).toString(16).padStart(8, '0')
|
|
91
|
+
return (
|
|
92
|
+
hex(h0) +
|
|
93
|
+
hex(h1) +
|
|
94
|
+
hex(h2) +
|
|
95
|
+
hex(h3) +
|
|
96
|
+
hex(h4) +
|
|
97
|
+
hex(h5) +
|
|
98
|
+
hex(h6) +
|
|
99
|
+
hex(h7)
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* A hash function for interrupt bindings and resolution fingerprints. Receives
|
|
105
|
+
* canonical JSON text and returns an opaque string. Must be deterministic; the
|
|
106
|
+
* server compares hashes it computed against the ones in a binding, so the same
|
|
107
|
+
* function has to run wherever a given binding is produced and checked.
|
|
108
|
+
*/
|
|
109
|
+
export type InterruptHash = (canonicalJson: string) => string
|
|
110
|
+
|
|
111
|
+
/** The built-in default: SHA-256, prefixed so the algorithm is self-describing. */
|
|
112
|
+
export function defaultInterruptHash(canonicalJson: string): string {
|
|
113
|
+
return `sha256:${sha256Hex(canonicalJson)}`
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function canonical(value: unknown, active: WeakSet<object>): string {
|
|
117
|
+
if (value === null) return 'null'
|
|
118
|
+
if (typeof value === 'string' || typeof value === 'boolean') {
|
|
119
|
+
return JSON.stringify(value)
|
|
120
|
+
}
|
|
121
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
122
|
+
return JSON.stringify(value)
|
|
123
|
+
}
|
|
124
|
+
if (typeof value !== 'object') {
|
|
125
|
+
throw new TypeError('Interrupt values must be JSON-compatible.')
|
|
126
|
+
}
|
|
127
|
+
if (active.has(value)) {
|
|
128
|
+
throw new TypeError('Interrupt values must not cycle.')
|
|
129
|
+
}
|
|
130
|
+
if (
|
|
131
|
+
!Array.isArray(value) &&
|
|
132
|
+
Object.getPrototypeOf(value) !== Object.prototype &&
|
|
133
|
+
Object.getPrototypeOf(value) !== null
|
|
134
|
+
) {
|
|
135
|
+
throw new TypeError('Interrupt values must use plain JSON objects.')
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
active.add(value)
|
|
139
|
+
let encoded: string
|
|
140
|
+
if (Array.isArray(value)) {
|
|
141
|
+
const items: Array<string> = []
|
|
142
|
+
for (let index = 0; index < value.length; index++) {
|
|
143
|
+
items.push(canonical(value[index], active))
|
|
144
|
+
}
|
|
145
|
+
encoded = `[${items.join(',')}]`
|
|
146
|
+
} else {
|
|
147
|
+
const record = value as Record<string, unknown>
|
|
148
|
+
encoded = `{${Object.keys(record)
|
|
149
|
+
.sort()
|
|
150
|
+
.map((key) => `${JSON.stringify(key)}:${canonical(record[key], active)}`)
|
|
151
|
+
.join(',')}}`
|
|
152
|
+
}
|
|
153
|
+
active.delete(value)
|
|
154
|
+
return encoded
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export function canonicalInterruptJson(value: unknown): string {
|
|
158
|
+
return canonical(value, new WeakSet<object>())
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export function digestInterruptJson(
|
|
162
|
+
canonicalJson: string,
|
|
163
|
+
hash: InterruptHash = defaultInterruptHash,
|
|
164
|
+
): string {
|
|
165
|
+
if (typeof canonicalJson !== 'string') {
|
|
166
|
+
throw new TypeError('Interrupt digests require canonical JSON text.')
|
|
167
|
+
}
|
|
168
|
+
return hash(canonicalJson)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function freezeTree(value: unknown): void {
|
|
172
|
+
if (value === null || typeof value !== 'object' || Object.isFrozen(value)) {
|
|
173
|
+
return
|
|
174
|
+
}
|
|
175
|
+
Object.values(value).forEach(freezeTree)
|
|
176
|
+
Object.freeze(value)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export function cloneAndDeepFreezeJson<T>(value: T): T {
|
|
180
|
+
const clone: T = JSON.parse(canonicalInterruptJson(value))
|
|
181
|
+
freezeTree(clone)
|
|
182
|
+
return clone
|
|
183
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {
|
|
2
|
+
canonicalInterruptJson,
|
|
3
|
+
cloneAndDeepFreezeJson,
|
|
4
|
+
digestInterruptJson,
|
|
5
|
+
} from './interrupt-serialization'
|
|
6
|
+
import type { RunAgentResumeItem } from './types'
|
|
7
|
+
|
|
8
|
+
export interface InterruptCorrelation {
|
|
9
|
+
threadId: string
|
|
10
|
+
interruptedRunId: string
|
|
11
|
+
generation: number
|
|
12
|
+
submissionId?: string
|
|
13
|
+
continuationRunId?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type ItemInterruptErrorCode =
|
|
17
|
+
| 'invalid-payload'
|
|
18
|
+
| 'invalid-edited-args'
|
|
19
|
+
| 'invalid-tool-output'
|
|
20
|
+
| 'invalid-response-schema'
|
|
21
|
+
| 'unknown-interrupt'
|
|
22
|
+
| 'expired'
|
|
23
|
+
| 'stale'
|
|
24
|
+
| 'conflict'
|
|
25
|
+
| 'legacy-unsupported'
|
|
26
|
+
|
|
27
|
+
export type BatchInterruptErrorCode =
|
|
28
|
+
| 'incomplete-batch'
|
|
29
|
+
| 'item-validation-failed'
|
|
30
|
+
| 'unsupported-bulk-operation'
|
|
31
|
+
| 'async-resolver'
|
|
32
|
+
| 'inactive-transaction'
|
|
33
|
+
| 'mixed-provenance'
|
|
34
|
+
| 'transport'
|
|
35
|
+
| 'server'
|
|
36
|
+
| 'protocol'
|
|
37
|
+
| 'invalid-response-schema'
|
|
38
|
+
| 'expired'
|
|
39
|
+
| 'stale'
|
|
40
|
+
| 'conflict'
|
|
41
|
+
| 'legacy-submit-failed'
|
|
42
|
+
|
|
43
|
+
export interface ItemInterruptError extends InterruptCorrelation {
|
|
44
|
+
scope: 'item'
|
|
45
|
+
interruptId: string
|
|
46
|
+
code: ItemInterruptErrorCode
|
|
47
|
+
message: string
|
|
48
|
+
path?: ReadonlyArray<string | number>
|
|
49
|
+
source: 'client' | 'server'
|
|
50
|
+
retryable: boolean
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface BatchInterruptError extends InterruptCorrelation {
|
|
54
|
+
scope: 'batch'
|
|
55
|
+
code: BatchInterruptErrorCode
|
|
56
|
+
message: string
|
|
57
|
+
source: 'client' | 'server' | 'transport'
|
|
58
|
+
retryable: boolean
|
|
59
|
+
interruptIds: ReadonlyArray<string>
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type InterruptSubmissionError = ItemInterruptError | BatchInterruptError
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Wire version of {@link InterruptBinding}.
|
|
66
|
+
*
|
|
67
|
+
* The binding is the only part of an AG-UI `Interrupt` that this package
|
|
68
|
+
* claims — it rides in `metadata` under
|
|
69
|
+
* {@link INTERRUPT_BINDING_METADATA_KEY} and tells the resume path how to
|
|
70
|
+
* correlate an answer back to a paused run. Producers stamp `v`; readers
|
|
71
|
+
* reject any version they don't understand rather than duck-typing the fields.
|
|
72
|
+
*
|
|
73
|
+
* That matters because an AG-UI `Interrupt` is a shared envelope. Another
|
|
74
|
+
* producer — a workflow engine projecting a durable approval, a third-party
|
|
75
|
+
* agent — can legitimately put its own binding in the same envelope. Versioning
|
|
76
|
+
* makes "not mine" a clean rejection instead of a partial match that resumes
|
|
77
|
+
* against the wrong owner.
|
|
78
|
+
*/
|
|
79
|
+
export const INTERRUPT_BINDING_VERSION = 1 as const
|
|
80
|
+
|
|
81
|
+
interface InterruptBindingBase {
|
|
82
|
+
/** @see INTERRUPT_BINDING_VERSION */
|
|
83
|
+
v: typeof INTERRUPT_BINDING_VERSION
|
|
84
|
+
interruptId: string
|
|
85
|
+
interruptedRunId: string
|
|
86
|
+
generation: number
|
|
87
|
+
responseSchemaHash: string
|
|
88
|
+
expiresAt?: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export type InterruptBinding =
|
|
92
|
+
| (InterruptBindingBase & {
|
|
93
|
+
kind: 'tool-approval'
|
|
94
|
+
toolName: string
|
|
95
|
+
toolCallId: string
|
|
96
|
+
originalArgs: unknown
|
|
97
|
+
inputSchemaHash: string
|
|
98
|
+
approvalSchemaHash: string
|
|
99
|
+
})
|
|
100
|
+
| (InterruptBindingBase & {
|
|
101
|
+
kind: 'client-tool-execution'
|
|
102
|
+
toolName: string
|
|
103
|
+
toolCallId: string
|
|
104
|
+
outputSchemaHash: string
|
|
105
|
+
})
|
|
106
|
+
| (InterruptBindingBase & {
|
|
107
|
+
kind: 'generic'
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
export type UnopenedInterruptBinding = InterruptBinding extends infer TBinding
|
|
111
|
+
? TBinding extends InterruptBinding
|
|
112
|
+
? Omit<TBinding, 'interruptedRunId' | 'generation'>
|
|
113
|
+
: never
|
|
114
|
+
: never
|
|
115
|
+
|
|
116
|
+
export type ToolApprovalResolution =
|
|
117
|
+
| boolean
|
|
118
|
+
| {
|
|
119
|
+
approved: true
|
|
120
|
+
editedArgs?: unknown
|
|
121
|
+
payload?: unknown
|
|
122
|
+
}
|
|
123
|
+
| {
|
|
124
|
+
approved: false
|
|
125
|
+
payload?: unknown
|
|
126
|
+
editedArgs?: never
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function canonicalizeInterruptResolutions(
|
|
130
|
+
resolutions: ReadonlyArray<RunAgentResumeItem>,
|
|
131
|
+
): {
|
|
132
|
+
resolutions: ReadonlyArray<RunAgentResumeItem>
|
|
133
|
+
canonicalResolutions: string
|
|
134
|
+
fingerprint: string
|
|
135
|
+
} {
|
|
136
|
+
const sorted = [...resolutions].sort((left, right) =>
|
|
137
|
+
left.interruptId.localeCompare(right.interruptId),
|
|
138
|
+
)
|
|
139
|
+
const frozen = cloneAndDeepFreezeJson(sorted)
|
|
140
|
+
const canonicalResolutions = canonicalInterruptJson(frozen)
|
|
141
|
+
return Object.freeze({
|
|
142
|
+
resolutions: frozen,
|
|
143
|
+
canonicalResolutions,
|
|
144
|
+
fingerprint: digestInterruptJson(canonicalResolutions),
|
|
145
|
+
})
|
|
146
|
+
}
|
package/src/locks.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Distributed-mutex primitive — coordination, not state persistence.
|
|
3
|
+
*
|
|
4
|
+
* Its own subpath (`@tanstack/ai/locks`) so it stays out of the main barrel and
|
|
5
|
+
* consumers opt in explicitly. Provide a store with `withLocks`; downstream
|
|
6
|
+
* middleware (e.g. `@tanstack/ai-sandbox`'s `ensure`) reads it via `getLocks` /
|
|
7
|
+
* `LocksCapability`. Import from here, not from `@tanstack/ai-persistence`.
|
|
8
|
+
*/
|
|
9
|
+
export {
|
|
10
|
+
LocksCapability,
|
|
11
|
+
getLocks,
|
|
12
|
+
provideLocks,
|
|
13
|
+
InMemoryLockStore,
|
|
14
|
+
withLocks,
|
|
15
|
+
defineLock,
|
|
16
|
+
} from './activities/chat/middleware/index'
|
|
17
|
+
export type { LockStore } from './activities/chat/middleware/index'
|
package/src/logger/types.ts
CHANGED
|
@@ -29,7 +29,7 @@ export interface Logger {
|
|
|
29
29
|
*/
|
|
30
30
|
export interface DebugCategories {
|
|
31
31
|
/**
|
|
32
|
-
* Raw chunks/frames received from a provider SDK (OpenAI, Anthropic, Gemini, Ollama, Grok, Groq, OpenRouter, fal, ElevenLabs). Emitted inside every streaming adapter's chunk loop.
|
|
32
|
+
* Raw chunks/frames received from a provider SDK (OpenAI, Anthropic, Gemini, Ollama, Grok, Groq, OpenRouter, fal, ElevenLabs, BytePlus). Emitted inside every streaming adapter's chunk loop.
|
|
33
33
|
*/
|
|
34
34
|
provider?: boolean
|
|
35
35
|
/**
|
package/src/middlewares/otel.ts
CHANGED
package/src/realtime/index.ts
CHANGED
|
@@ -19,15 +19,11 @@ export type * from './types'
|
|
|
19
19
|
* import { realtimeToken } from '@tanstack/ai'
|
|
20
20
|
* import { openaiRealtimeToken } from '@tanstack/ai-openai'
|
|
21
21
|
*
|
|
22
|
-
* //
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* model: 'gpt-realtime',
|
|
28
|
-
* }),
|
|
29
|
-
* })
|
|
30
|
-
* })
|
|
22
|
+
* // On the server (e.g. inside a server route or framework server
|
|
23
|
+
* // function), mint an ephemeral token for the client:
|
|
24
|
+
* const token = await realtimeToken({
|
|
25
|
+
* adapter: openaiRealtimeToken({ model: 'gpt-realtime' }),
|
|
26
|
+
* })
|
|
31
27
|
* ```
|
|
32
28
|
*/
|
|
33
29
|
export async function realtimeToken(
|
package/src/scope.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared identity/isolation scope for the TanStack AI subsystems that persist
|
|
3
|
+
* or recall per-conversation data — `@tanstack/ai-persistence` (keyed CRUD over
|
|
4
|
+
* threads, runs, interrupts) and `@tanstack/ai-memory` (ranked recall/save).
|
|
5
|
+
*
|
|
6
|
+
* Both subsystems answer the same underlying question — "whose data is this?" —
|
|
7
|
+
* so they share ONE identity vocabulary defined here rather than each inventing
|
|
8
|
+
* its own. `threadId` is the single conversation key across the codebase (it is
|
|
9
|
+
* `ChatMiddlewareContext.threadId`, and `conversationId` is deprecated in favor
|
|
10
|
+
* of it); a subsystem must never introduce a second name (`sessionId`,
|
|
11
|
+
* `conversationId`, …) for the same concept.
|
|
12
|
+
*
|
|
13
|
+
* ## Security
|
|
14
|
+
*
|
|
15
|
+
* A `Scope` is an isolation boundary. Derive every field server-side from
|
|
16
|
+
* trusted, validated session state — **never** from client input. `threadId`
|
|
17
|
+
* in particular resolves from a client-supplied value on the request, so a
|
|
18
|
+
* subsystem that reads/writes user-owned data (memory, per-user metadata) must
|
|
19
|
+
* pair it with a server-trusted `userId`/`tenantId` and must not treat a bare
|
|
20
|
+
* client `threadId` as sufficient isolation: thread ids are guessable, so on
|
|
21
|
+
* their own they let one caller read another's data.
|
|
22
|
+
*/
|
|
23
|
+
export interface Scope {
|
|
24
|
+
/**
|
|
25
|
+
* The conversation this data belongs to. Required — the minimal isolation
|
|
26
|
+
* key both subsystems already center on. Same concept as
|
|
27
|
+
* `ChatMiddlewareContext.threadId`.
|
|
28
|
+
*/
|
|
29
|
+
threadId: string
|
|
30
|
+
/**
|
|
31
|
+
* Durable end-user identity, for cross-thread recall and per-user isolation.
|
|
32
|
+
* Optional, but required in practice for any multi-user deployment — a
|
|
33
|
+
* `threadId` alone is not an authorization boundary (see Security above).
|
|
34
|
+
*/
|
|
35
|
+
userId?: string
|
|
36
|
+
/**
|
|
37
|
+
* Tenant/organization boundary for multi-tenant deployments. When present,
|
|
38
|
+
* every read and write must be confined to it.
|
|
39
|
+
*/
|
|
40
|
+
tenantId?: string
|
|
41
|
+
/**
|
|
42
|
+
* Logical partition within a tenant/user (e.g. separating distinct memory
|
|
43
|
+
* banks or persistence namespaces). Reserved — no subsystem keys on it yet;
|
|
44
|
+
* adapters that don't understand it must ignore it rather than error.
|
|
45
|
+
*/
|
|
46
|
+
namespace?: string
|
|
47
|
+
}
|