@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
|
@@ -1,54 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return this.punctuation.test(chunk);
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
class BatchStrategy {
|
|
13
|
-
constructor(batchSize = 5) {
|
|
14
|
-
this.batchSize = batchSize;
|
|
15
|
-
}
|
|
16
|
-
batchSize;
|
|
17
|
-
chunkCount = 0;
|
|
18
|
-
shouldEmit(_chunk, _accumulated) {
|
|
19
|
-
this.chunkCount++;
|
|
20
|
-
if (this.chunkCount >= this.batchSize) {
|
|
21
|
-
this.chunkCount = 0;
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
reset() {
|
|
27
|
-
this.chunkCount = 0;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
class WordBoundaryStrategy {
|
|
31
|
-
shouldEmit(chunk, _accumulated) {
|
|
32
|
-
return /\s$/.test(chunk);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
class CompositeStrategy {
|
|
36
|
-
constructor(strategies) {
|
|
37
|
-
this.strategies = strategies;
|
|
38
|
-
}
|
|
39
|
-
strategies;
|
|
40
|
-
shouldEmit(chunk, accumulated) {
|
|
41
|
-
return this.strategies.some((s) => s.shouldEmit(chunk, accumulated));
|
|
42
|
-
}
|
|
43
|
-
reset() {
|
|
44
|
-
this.strategies.forEach((s) => s.reset?.());
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
export {
|
|
48
|
-
BatchStrategy,
|
|
49
|
-
CompositeStrategy,
|
|
50
|
-
ImmediateStrategy,
|
|
51
|
-
PunctuationStrategy,
|
|
52
|
-
WordBoundaryStrategy
|
|
1
|
+
//#region src/activities/chat/stream/strategies.ts
|
|
2
|
+
/**
|
|
3
|
+
* Immediate Strategy - emit on every chunk (default behavior)
|
|
4
|
+
*/
|
|
5
|
+
var ImmediateStrategy = class {
|
|
6
|
+
shouldEmit(_chunk, _accumulated) {
|
|
7
|
+
return true;
|
|
8
|
+
}
|
|
53
9
|
};
|
|
54
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Punctuation Strategy - emit when chunk contains punctuation
|
|
12
|
+
* Useful for natural text flow in UI
|
|
13
|
+
*/
|
|
14
|
+
var PunctuationStrategy = class {
|
|
15
|
+
punctuation = /[.,!?;:\n]/;
|
|
16
|
+
shouldEmit(chunk, _accumulated) {
|
|
17
|
+
return this.punctuation.test(chunk);
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Batch Strategy - emit every N chunks
|
|
22
|
+
* Useful for reducing UI update frequency
|
|
23
|
+
*/
|
|
24
|
+
var BatchStrategy = class {
|
|
25
|
+
batchSize;
|
|
26
|
+
chunkCount = 0;
|
|
27
|
+
constructor(batchSize = 5) {
|
|
28
|
+
this.batchSize = batchSize;
|
|
29
|
+
}
|
|
30
|
+
shouldEmit(_chunk, _accumulated) {
|
|
31
|
+
this.chunkCount++;
|
|
32
|
+
if (this.chunkCount >= this.batchSize) {
|
|
33
|
+
this.chunkCount = 0;
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
reset() {
|
|
39
|
+
this.chunkCount = 0;
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Word Boundary Strategy - emit at word boundaries
|
|
44
|
+
* Prevents cutting words in half
|
|
45
|
+
*/
|
|
46
|
+
var WordBoundaryStrategy = class {
|
|
47
|
+
shouldEmit(chunk, _accumulated) {
|
|
48
|
+
return /\s$/.test(chunk);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Composite Strategy - combine multiple strategies (OR logic)
|
|
53
|
+
* Emits if ANY strategy says to emit
|
|
54
|
+
*/
|
|
55
|
+
var CompositeStrategy = class {
|
|
56
|
+
strategies;
|
|
57
|
+
constructor(strategies) {
|
|
58
|
+
this.strategies = strategies;
|
|
59
|
+
}
|
|
60
|
+
shouldEmit(chunk, accumulated) {
|
|
61
|
+
return this.strategies.some((s) => s.shouldEmit(chunk, accumulated));
|
|
62
|
+
}
|
|
63
|
+
reset() {
|
|
64
|
+
this.strategies.forEach((s) => s.reset?.());
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { BatchStrategy, CompositeStrategy, ImmediateStrategy, PunctuationStrategy, WordBoundaryStrategy };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=strategies.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strategies.js","sources":["../../../../../src/activities/chat/stream/strategies.ts"],"sourcesContent":["/**\n * Built-in Chunk Strategies\n *\n * Strategies for controlling when text updates are emitted to the UI\n */\n\nimport type { ChunkStrategy } from './types'\n\n/**\n * Immediate Strategy - emit on every chunk (default behavior)\n */\nexport class ImmediateStrategy implements ChunkStrategy {\n shouldEmit(_chunk: string, _accumulated: string): boolean {\n return true\n }\n}\n\n/**\n * Punctuation Strategy - emit when chunk contains punctuation\n * Useful for natural text flow in UI\n */\nexport class PunctuationStrategy implements ChunkStrategy {\n private readonly punctuation = /[.,!?;:\\n]/\n\n shouldEmit(chunk: string, _accumulated: string): boolean {\n return this.punctuation.test(chunk)\n }\n}\n\n/**\n * Batch Strategy - emit every N chunks\n * Useful for reducing UI update frequency\n */\nexport class BatchStrategy implements ChunkStrategy {\n private chunkCount = 0\n\n constructor(private readonly batchSize: number = 5) {}\n\n shouldEmit(_chunk: string, _accumulated: string): boolean {\n this.chunkCount++\n if (this.chunkCount >= this.batchSize) {\n this.chunkCount = 0\n return true\n }\n return false\n }\n\n reset(): void {\n this.chunkCount = 0\n }\n}\n\n/**\n * Word Boundary Strategy - emit at word boundaries\n * Prevents cutting words in half\n */\nexport class WordBoundaryStrategy implements ChunkStrategy {\n shouldEmit(chunk: string, _accumulated: string): boolean {\n // Emit if chunk ends with whitespace\n return /\\s$/.test(chunk)\n }\n}\n\n/**\n * Composite Strategy - combine multiple strategies (OR logic)\n * Emits if ANY strategy says to emit\n */\nexport class CompositeStrategy implements ChunkStrategy {\n constructor(private readonly strategies: Array<ChunkStrategy>) {}\n\n shouldEmit(chunk: string, accumulated: string): boolean {\n return this.strategies.some((s) => s.shouldEmit(chunk, accumulated))\n }\n\n reset(): void {\n this.strategies.forEach((s) => s.reset?.())\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"strategies.js","names":[],"sources":["../../../../../src/activities/chat/stream/strategies.ts"],"sourcesContent":["/**\n * Built-in Chunk Strategies\n *\n * Strategies for controlling when text updates are emitted to the UI\n */\n\nimport type { ChunkStrategy } from './types'\n\n/**\n * Immediate Strategy - emit on every chunk (default behavior)\n */\nexport class ImmediateStrategy implements ChunkStrategy {\n shouldEmit(_chunk: string, _accumulated: string): boolean {\n return true\n }\n}\n\n/**\n * Punctuation Strategy - emit when chunk contains punctuation\n * Useful for natural text flow in UI\n */\nexport class PunctuationStrategy implements ChunkStrategy {\n private readonly punctuation = /[.,!?;:\\n]/\n\n shouldEmit(chunk: string, _accumulated: string): boolean {\n return this.punctuation.test(chunk)\n }\n}\n\n/**\n * Batch Strategy - emit every N chunks\n * Useful for reducing UI update frequency\n */\nexport class BatchStrategy implements ChunkStrategy {\n private chunkCount = 0\n\n constructor(private readonly batchSize: number = 5) {}\n\n shouldEmit(_chunk: string, _accumulated: string): boolean {\n this.chunkCount++\n if (this.chunkCount >= this.batchSize) {\n this.chunkCount = 0\n return true\n }\n return false\n }\n\n reset(): void {\n this.chunkCount = 0\n }\n}\n\n/**\n * Word Boundary Strategy - emit at word boundaries\n * Prevents cutting words in half\n */\nexport class WordBoundaryStrategy implements ChunkStrategy {\n shouldEmit(chunk: string, _accumulated: string): boolean {\n // Emit if chunk ends with whitespace\n return /\\s$/.test(chunk)\n }\n}\n\n/**\n * Composite Strategy - combine multiple strategies (OR logic)\n * Emits if ANY strategy says to emit\n */\nexport class CompositeStrategy implements ChunkStrategy {\n constructor(private readonly strategies: Array<ChunkStrategy>) {}\n\n shouldEmit(chunk: string, accumulated: string): boolean {\n return this.strategies.some((s) => s.shouldEmit(chunk, accumulated))\n }\n\n reset(): void {\n this.strategies.forEach((s) => s.reset?.())\n }\n}\n"],"mappings":";;;;AAWA,IAAa,oBAAb,MAAwD;CACtD,WAAW,QAAgB,cAA+B;EACxD,OAAO;CACT;AACF;;;;;AAMA,IAAa,sBAAb,MAA0D;CACxD,cAA+B;CAE/B,WAAW,OAAe,cAA+B;EACvD,OAAO,KAAK,YAAY,KAAK,KAAK;CACpC;AACF;;;;;AAMA,IAAa,gBAAb,MAAoD;CAGrB;CAF7B,aAAqB;CAErB,YAAY,YAAqC,GAAG;EAAvB,KAAA,YAAA;CAAwB;CAErD,WAAW,QAAgB,cAA+B;EACxD,KAAK;EACL,IAAI,KAAK,cAAc,KAAK,WAAW;GACrC,KAAK,aAAa;GAClB,OAAO;EACT;EACA,OAAO;CACT;CAEA,QAAc;EACZ,KAAK,aAAa;CACpB;AACF;;;;;AAMA,IAAa,uBAAb,MAA2D;CACzD,WAAW,OAAe,cAA+B;EAEvD,OAAO,MAAM,KAAK,KAAK;CACzB;AACF;;;;;AAMA,IAAa,oBAAb,MAAwD;CACzB;CAA7B,YAAY,YAAmD;EAAlC,KAAA,aAAA;CAAmC;CAEhE,WAAW,OAAe,aAA8B;EACtD,OAAO,KAAK,WAAW,MAAM,MAAM,EAAE,WAAW,OAAO,WAAW,CAAC;CACrE;CAEA,QAAc;EACZ,KAAK,WAAW,SAAS,MAAM,EAAE,QAAQ,CAAC;CAC5C;AACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import { JSONSchema, SchemaInput } from '../../../types.js';
|
|
3
|
+
import { ApprovalSchemaConfig } from './tool-definition.js';
|
|
4
|
+
export interface NormalizedSchemaInput {
|
|
5
|
+
source: SchemaInput;
|
|
6
|
+
validator?: StandardSchemaV1;
|
|
7
|
+
jsonSchema?: JSONSchema;
|
|
8
|
+
}
|
|
9
|
+
export interface NormalizedApprovalSchema {
|
|
10
|
+
branches: {
|
|
11
|
+
approve: NormalizedSchemaInput | null;
|
|
12
|
+
reject: NormalizedSchemaInput | null;
|
|
13
|
+
};
|
|
14
|
+
responseSchema: JSONSchema;
|
|
15
|
+
responseSchemaHash: string;
|
|
16
|
+
approvalSchemaHash: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function normalizeApprovalSchema(approvalSchema: ApprovalSchemaConfig | undefined, inputSchema?: SchemaInput): NormalizedApprovalSchema;
|
|
19
|
+
export declare function hashSchemaInput(schema: SchemaInput | undefined): string;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { canonicalInterruptJson, digestInterruptJson } from "../../../interrupt-serialization.js";
|
|
2
|
+
import { isStandardJSONSchema, isStandardSchema } from "./schema-converter.js";
|
|
3
|
+
//#region src/activities/chat/tools/approval-schema.ts
|
|
4
|
+
var jsonSchemaKeywords = /* @__PURE__ */ new Set([
|
|
5
|
+
"$schema",
|
|
6
|
+
"$id",
|
|
7
|
+
"$ref",
|
|
8
|
+
"$defs",
|
|
9
|
+
"type",
|
|
10
|
+
"properties",
|
|
11
|
+
"required",
|
|
12
|
+
"additionalProperties",
|
|
13
|
+
"items",
|
|
14
|
+
"oneOf",
|
|
15
|
+
"anyOf",
|
|
16
|
+
"allOf",
|
|
17
|
+
"enum",
|
|
18
|
+
"const",
|
|
19
|
+
"format",
|
|
20
|
+
"minimum",
|
|
21
|
+
"maximum",
|
|
22
|
+
"minLength",
|
|
23
|
+
"maxLength",
|
|
24
|
+
"pattern"
|
|
25
|
+
]);
|
|
26
|
+
function isPlainRecord(value) {
|
|
27
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
28
|
+
}
|
|
29
|
+
function isRawJsonSchema(value) {
|
|
30
|
+
return isPlainRecord(value) && Object.keys(value).some((key) => jsonSchemaKeywords.has(key));
|
|
31
|
+
}
|
|
32
|
+
function isSchemaInput(value) {
|
|
33
|
+
return isStandardSchema(value) || isStandardJSONSchema(value) || isRawJsonSchema(value);
|
|
34
|
+
}
|
|
35
|
+
function isApprovalBranchMap(value) {
|
|
36
|
+
if (!isPlainRecord(value)) return false;
|
|
37
|
+
const keys = Object.keys(value);
|
|
38
|
+
return keys.length > 0 && keys.every((key) => key === "approve" || key === "reject") && keys.every((key) => isSchemaInput(value[key]));
|
|
39
|
+
}
|
|
40
|
+
function toJsonSchema(value) {
|
|
41
|
+
const result = {};
|
|
42
|
+
for (const [key, item] of Object.entries(value)) result[key] = item;
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
function schemaToWire(schema) {
|
|
46
|
+
if (isStandardSchema(schema)) {
|
|
47
|
+
const jsonSchema = isStandardJSONSchema(schema) ? toJsonSchema(schema["~standard"].jsonSchema.input({ target: "draft-2020-12" })) : void 0;
|
|
48
|
+
return {
|
|
49
|
+
source: schema,
|
|
50
|
+
validator: schema,
|
|
51
|
+
...jsonSchema !== void 0 && { jsonSchema }
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (isRawJsonSchema(schema)) return {
|
|
55
|
+
source: schema,
|
|
56
|
+
jsonSchema: schema
|
|
57
|
+
};
|
|
58
|
+
throw new TypeError("Expected a supported SchemaInput.");
|
|
59
|
+
}
|
|
60
|
+
function decisionEnvelope(input) {
|
|
61
|
+
const properties = { approved: { const: input.approved } };
|
|
62
|
+
const required = ["approved"];
|
|
63
|
+
if (input.approved && input.inputSchema) properties["editedArgs"] = input.inputSchema.jsonSchema ?? {};
|
|
64
|
+
if (input.payload) {
|
|
65
|
+
properties["payload"] = input.payload.jsonSchema ?? {};
|
|
66
|
+
required.push("payload");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
type: "object",
|
|
70
|
+
properties,
|
|
71
|
+
required,
|
|
72
|
+
additionalProperties: false
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function normalizeApprovalSchema(approvalSchema, inputSchema) {
|
|
76
|
+
const normalizedInput = inputSchema === void 0 ? null : schemaToWire(inputSchema);
|
|
77
|
+
let approve = null;
|
|
78
|
+
let reject = null;
|
|
79
|
+
if (approvalSchema !== void 0) if (isStandardSchema(approvalSchema) || isRawJsonSchema(approvalSchema)) {
|
|
80
|
+
approve = schemaToWire(approvalSchema);
|
|
81
|
+
reject = approve;
|
|
82
|
+
} else if (isApprovalBranchMap(approvalSchema)) {
|
|
83
|
+
approve = approvalSchema.approve === void 0 ? null : schemaToWire(approvalSchema.approve);
|
|
84
|
+
reject = approvalSchema.reject === void 0 ? null : schemaToWire(approvalSchema.reject);
|
|
85
|
+
} else throw new TypeError("approvalSchema must be a SchemaInput or a nonempty map containing approve or reject.");
|
|
86
|
+
const responseSchema = { oneOf: [decisionEnvelope({
|
|
87
|
+
approved: true,
|
|
88
|
+
payload: approve,
|
|
89
|
+
inputSchema: normalizedInput
|
|
90
|
+
}), decisionEnvelope({
|
|
91
|
+
approved: false,
|
|
92
|
+
payload: reject,
|
|
93
|
+
inputSchema: null
|
|
94
|
+
})] };
|
|
95
|
+
const responseCanonical = canonicalInterruptJson(responseSchema);
|
|
96
|
+
const approvalCanonical = canonicalInterruptJson({
|
|
97
|
+
approve: approve?.jsonSchema ?? null,
|
|
98
|
+
reject: reject?.jsonSchema ?? null
|
|
99
|
+
});
|
|
100
|
+
return {
|
|
101
|
+
branches: {
|
|
102
|
+
approve,
|
|
103
|
+
reject
|
|
104
|
+
},
|
|
105
|
+
responseSchema,
|
|
106
|
+
responseSchemaHash: digestInterruptJson(responseCanonical),
|
|
107
|
+
approvalSchemaHash: digestInterruptJson(approvalCanonical)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function hashSchemaInput(schema) {
|
|
111
|
+
if (schema === void 0) return digestInterruptJson("undefined");
|
|
112
|
+
return digestInterruptJson(canonicalInterruptJson(schemaToWire(schema).jsonSchema ?? { standardValidator: "unserialized" }));
|
|
113
|
+
}
|
|
114
|
+
//#endregion
|
|
115
|
+
export { hashSchemaInput, normalizeApprovalSchema };
|
|
116
|
+
|
|
117
|
+
//# sourceMappingURL=approval-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-schema.js","names":[],"sources":["../../../../../src/activities/chat/tools/approval-schema.ts"],"sourcesContent":["import {\n canonicalInterruptJson,\n digestInterruptJson,\n} from '../../../interrupt-serialization'\nimport { isStandardJSONSchema, isStandardSchema } from './schema-converter'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport type { JSONSchema, SchemaInput } from '../../../types'\nimport type { ApprovalSchemaConfig } from './tool-definition'\n\nexport interface NormalizedSchemaInput {\n source: SchemaInput\n validator?: StandardSchemaV1\n jsonSchema?: JSONSchema\n}\n\nexport interface NormalizedApprovalSchema {\n branches: {\n approve: NormalizedSchemaInput | null\n reject: NormalizedSchemaInput | null\n }\n responseSchema: JSONSchema\n responseSchemaHash: string\n approvalSchemaHash: string\n}\n\nconst jsonSchemaKeywords = new Set([\n '$schema',\n '$id',\n '$ref',\n '$defs',\n 'type',\n 'properties',\n 'required',\n 'additionalProperties',\n 'items',\n 'oneOf',\n 'anyOf',\n 'allOf',\n 'enum',\n 'const',\n 'format',\n 'minimum',\n 'maximum',\n 'minLength',\n 'maxLength',\n 'pattern',\n])\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype ||\n Object.getPrototypeOf(value) === null)\n )\n}\n\nfunction isRawJsonSchema(value: unknown): value is JSONSchema {\n return (\n isPlainRecord(value) &&\n Object.keys(value).some((key) => jsonSchemaKeywords.has(key))\n )\n}\n\nfunction isSchemaInput(value: unknown): value is SchemaInput {\n return (\n isStandardSchema(value) ||\n isStandardJSONSchema(value) ||\n isRawJsonSchema(value)\n )\n}\n\nfunction isApprovalBranchMap(\n value: unknown,\n): value is { approve?: SchemaInput; reject?: SchemaInput } {\n if (!isPlainRecord(value)) return false\n const keys = Object.keys(value)\n return (\n keys.length > 0 &&\n keys.every((key) => key === 'approve' || key === 'reject') &&\n keys.every((key) => isSchemaInput(value[key]))\n )\n}\n\nfunction toJsonSchema(value: Record<string, unknown>): JSONSchema {\n const result: JSONSchema = {}\n for (const [key, item] of Object.entries(value)) {\n result[key] = item\n }\n return result\n}\n\nfunction schemaToWire(schema: SchemaInput): NormalizedSchemaInput {\n if (isStandardSchema(schema)) {\n const jsonSchema = isStandardJSONSchema(schema)\n ? toJsonSchema(\n schema['~standard'].jsonSchema.input({\n target: 'draft-2020-12',\n }),\n )\n : undefined\n return {\n source: schema,\n validator: schema,\n ...(jsonSchema !== undefined && { jsonSchema }),\n }\n }\n if (isRawJsonSchema(schema)) {\n // The library does not compile or validate raw JSON Schema; it is carried\n // on the wire and hashed as-is. Validation is the application's job.\n return { source: schema, jsonSchema: schema }\n }\n throw new TypeError('Expected a supported SchemaInput.')\n}\n\nfunction decisionEnvelope(input: {\n approved: boolean\n payload: NormalizedSchemaInput | null\n inputSchema: NormalizedSchemaInput | null\n}): JSONSchema {\n const properties: Record<string, JSONSchema> = {\n approved: { const: input.approved },\n }\n const required = ['approved']\n if (input.approved && input.inputSchema) {\n properties['editedArgs'] = input.inputSchema.jsonSchema ?? {}\n }\n if (input.payload) {\n properties['payload'] = input.payload.jsonSchema ?? {}\n required.push('payload')\n }\n return {\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n }\n}\n\nexport function normalizeApprovalSchema(\n approvalSchema: ApprovalSchemaConfig | undefined,\n inputSchema?: SchemaInput,\n): NormalizedApprovalSchema {\n const normalizedInput =\n inputSchema === undefined ? null : schemaToWire(inputSchema)\n let approve: NormalizedSchemaInput | null = null\n let reject: NormalizedSchemaInput | null = null\n\n if (approvalSchema !== undefined) {\n if (isStandardSchema(approvalSchema) || isRawJsonSchema(approvalSchema)) {\n approve = schemaToWire(approvalSchema)\n reject = approve\n } else if (isApprovalBranchMap(approvalSchema)) {\n approve =\n approvalSchema.approve === undefined\n ? null\n : schemaToWire(approvalSchema.approve)\n reject =\n approvalSchema.reject === undefined\n ? null\n : schemaToWire(approvalSchema.reject)\n } else {\n throw new TypeError(\n 'approvalSchema must be a SchemaInput or a nonempty map containing approve or reject.',\n )\n }\n }\n\n const responseSchema: JSONSchema = {\n oneOf: [\n decisionEnvelope({\n approved: true,\n payload: approve,\n inputSchema: normalizedInput,\n }),\n decisionEnvelope({\n approved: false,\n payload: reject,\n inputSchema: null,\n }),\n ],\n }\n const responseCanonical = canonicalInterruptJson(responseSchema)\n const approvalCanonical = canonicalInterruptJson({\n approve: approve?.jsonSchema ?? null,\n reject: reject?.jsonSchema ?? null,\n })\n\n return {\n branches: { approve, reject },\n responseSchema,\n responseSchemaHash: digestInterruptJson(responseCanonical),\n approvalSchemaHash: digestInterruptJson(approvalCanonical),\n }\n}\n\nexport function hashSchemaInput(schema: SchemaInput | undefined): string {\n if (schema === undefined) return digestInterruptJson('undefined')\n const normalized = schemaToWire(schema)\n const identity = normalized.jsonSchema ?? {\n standardValidator: 'unserialized',\n }\n return digestInterruptJson(canonicalInterruptJson(identity))\n}\n"],"mappings":"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"}
|