@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,5 +1,6 @@
|
|
|
1
1
|
import { normalizeToolResult } from '../../../utilities/tool-result'
|
|
2
2
|
import { isStandardSchema, parseWithStandardSchema } from './schema-converter'
|
|
3
|
+
import type { ToolApprovalResolution } from '../../../interrupts'
|
|
3
4
|
import type {
|
|
4
5
|
AnyTool,
|
|
5
6
|
ContentPart,
|
|
@@ -311,6 +312,13 @@ export class ToolCallManager<
|
|
|
311
312
|
|
|
312
313
|
let toolResultContent: string | Array<ContentPart>
|
|
313
314
|
let toolResultState: ToolOutputState | undefined
|
|
315
|
+
// Holds the parsed/validated execution output before serialization.
|
|
316
|
+
// Surfaced on the emitted `TOOL_CALL_END` event as `output` so
|
|
317
|
+
// consumers can read it typed (via `TypedStreamChunk` distribution
|
|
318
|
+
// over the tools array) without re-parsing `result`.
|
|
319
|
+
// Stays `undefined` when the tool has no `execute` (client-only
|
|
320
|
+
// tools) or when execution throws.
|
|
321
|
+
let toolOutput: unknown
|
|
314
322
|
if (tool?.execute) {
|
|
315
323
|
try {
|
|
316
324
|
// Parse arguments (normalize null/non-object to {} for empty tool_use blocks)
|
|
@@ -369,6 +377,7 @@ export class ToolCallManager<
|
|
|
369
377
|
}
|
|
370
378
|
}
|
|
371
379
|
|
|
380
|
+
toolOutput = result
|
|
372
381
|
toolResultContent = normalizeToolResult(result)
|
|
373
382
|
} catch (error: unknown) {
|
|
374
383
|
// If tool execution fails, add error message
|
|
@@ -390,9 +399,11 @@ export class ToolCallManager<
|
|
|
390
399
|
toolName: toolCall.function.name,
|
|
391
400
|
model: finishEvent.model,
|
|
392
401
|
timestamp: Date.now(),
|
|
402
|
+
// Typed parsed output (undefined for failed exec / client-only tools).
|
|
403
|
+
...(toolOutput !== undefined ? { output: toolOutput } : {}),
|
|
393
404
|
result: toolResultContent,
|
|
394
405
|
...(toolResultState !== undefined && { state: toolResultState }),
|
|
395
|
-
}
|
|
406
|
+
}
|
|
396
407
|
|
|
397
408
|
// Add tool result message
|
|
398
409
|
toolResults.push({
|
|
@@ -420,6 +431,17 @@ export interface ToolResult {
|
|
|
420
431
|
state?: 'output-available' | 'output-error'
|
|
421
432
|
/** Duration of tool execution in milliseconds (only for server-executed tools) */
|
|
422
433
|
duration?: number
|
|
434
|
+
/**
|
|
435
|
+
* Parsed tool input (after JSON parse + optional Standard Schema validation).
|
|
436
|
+
* Surfaced on engine-emitted `TOOL_CALL_END` events for TypedStreamChunk consumers.
|
|
437
|
+
*/
|
|
438
|
+
input?: unknown
|
|
439
|
+
/**
|
|
440
|
+
* Parsed tool output before wire serialization. Surfaced on engine-emitted
|
|
441
|
+
* `TOOL_CALL_END` events so consumers can read typed `output` without
|
|
442
|
+
* re-parsing `result`. Undefined on error paths and when execution is skipped.
|
|
443
|
+
*/
|
|
444
|
+
output?: unknown
|
|
423
445
|
}
|
|
424
446
|
|
|
425
447
|
export interface ApprovalRequest {
|
|
@@ -435,6 +457,36 @@ export interface ClientToolRequest {
|
|
|
435
457
|
input: any
|
|
436
458
|
}
|
|
437
459
|
|
|
460
|
+
export interface ToolResumeExecutionState {
|
|
461
|
+
deniedToolResults?: ReadonlyMap<string, unknown>
|
|
462
|
+
cancelledToolCallIds?: ReadonlySet<string>
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function approvalResolution(
|
|
466
|
+
approvals: ReadonlyMap<string, ToolApprovalResolution>,
|
|
467
|
+
toolCallId: string,
|
|
468
|
+
): ToolApprovalResolution | undefined {
|
|
469
|
+
return approvals.get(toolCallId) ?? approvals.get(`approval_${toolCallId}`)
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function isApproved(resolution: ToolApprovalResolution): boolean {
|
|
473
|
+
return typeof resolution === 'boolean' ? resolution : resolution.approved
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function editedApprovalArgs(
|
|
477
|
+
resolution: ToolApprovalResolution,
|
|
478
|
+
): unknown | undefined {
|
|
479
|
+
return typeof resolution === 'object' && resolution.approved
|
|
480
|
+
? resolution.editedArgs
|
|
481
|
+
: undefined
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function deniedApprovalResult(resolution: ToolApprovalResolution): unknown {
|
|
485
|
+
return typeof resolution === 'object' && !resolution.approved
|
|
486
|
+
? (resolution.payload ?? { error: 'User declined tool execution' })
|
|
487
|
+
: { error: 'User declined tool execution' }
|
|
488
|
+
}
|
|
489
|
+
|
|
438
490
|
interface ExecuteToolCallsResult {
|
|
439
491
|
/** Tool results ready to send to LLM */
|
|
440
492
|
results: Array<ToolResult>
|
|
@@ -588,6 +640,8 @@ export async function* executeServerTool<TContext = unknown>(
|
|
|
588
640
|
toolCallId: toolCall.id,
|
|
589
641
|
toolName,
|
|
590
642
|
result: finalResult,
|
|
643
|
+
input,
|
|
644
|
+
output: finalResult,
|
|
591
645
|
duration,
|
|
592
646
|
})
|
|
593
647
|
|
|
@@ -620,6 +674,7 @@ export async function* executeServerTool<TContext = unknown>(
|
|
|
620
674
|
toolCallId: toolCall.id,
|
|
621
675
|
toolName,
|
|
622
676
|
result: { error: message },
|
|
677
|
+
input,
|
|
623
678
|
state: 'output-error',
|
|
624
679
|
duration,
|
|
625
680
|
})
|
|
@@ -643,6 +698,7 @@ function buildClientToolResult(
|
|
|
643
698
|
toolName: string,
|
|
644
699
|
tool: AnyTool,
|
|
645
700
|
rawResult: unknown,
|
|
701
|
+
input?: unknown,
|
|
646
702
|
): ToolResult {
|
|
647
703
|
try {
|
|
648
704
|
let result = rawResult
|
|
@@ -650,11 +706,14 @@ function buildClientToolResult(
|
|
|
650
706
|
result = parseWithStandardSchema(tool.outputSchema, result)
|
|
651
707
|
}
|
|
652
708
|
|
|
709
|
+
const parsed =
|
|
710
|
+
typeof result === 'string' ? safeJsonParse(result) : (result ?? null)
|
|
653
711
|
return {
|
|
654
712
|
toolCallId,
|
|
655
713
|
toolName,
|
|
656
|
-
result:
|
|
657
|
-
|
|
714
|
+
result: parsed,
|
|
715
|
+
input,
|
|
716
|
+
output: parsed,
|
|
658
717
|
}
|
|
659
718
|
} catch (error: unknown) {
|
|
660
719
|
const message = error instanceof Error ? error.message : 'Validation failed'
|
|
@@ -662,6 +721,7 @@ function buildClientToolResult(
|
|
|
662
721
|
toolCallId,
|
|
663
722
|
toolName,
|
|
664
723
|
result: { error: message },
|
|
724
|
+
input,
|
|
665
725
|
state: 'output-error',
|
|
666
726
|
}
|
|
667
727
|
}
|
|
@@ -678,14 +738,14 @@ function buildClientToolResult(
|
|
|
678
738
|
*
|
|
679
739
|
* @param toolCalls - Tool calls from the LLM
|
|
680
740
|
* @param tools - Available tools with their configurations
|
|
681
|
-
* @param approvals - Map
|
|
741
|
+
* @param approvals - Map keyed by toolCallId (or `approval_${toolCallId}`) → ToolApprovalResolution
|
|
682
742
|
* @param clientResults - Map of client-side execution results (toolCallId -> result)
|
|
683
743
|
* @param createCustomEventChunk - Factory to create CustomEvent chunks (optional)
|
|
684
744
|
*/
|
|
685
745
|
export async function* executeToolCalls<TContext = unknown>(
|
|
686
746
|
toolCalls: Array<ToolCall>,
|
|
687
747
|
tools: ReadonlyArray<AnyTool>,
|
|
688
|
-
approvals: Map<string,
|
|
748
|
+
approvals: Map<string, ToolApprovalResolution> = new Map(),
|
|
689
749
|
clientResults: Map<string, any> = new Map(),
|
|
690
750
|
createCustomEventChunk?: (
|
|
691
751
|
eventName: string,
|
|
@@ -694,6 +754,7 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
694
754
|
middlewareHooks?: ToolExecutionMiddlewareHooks,
|
|
695
755
|
userContext?: TContext,
|
|
696
756
|
abortSignal?: AbortSignal,
|
|
757
|
+
resumeState?: ToolResumeExecutionState,
|
|
697
758
|
): AsyncGenerator<CustomEvent, ExecuteToolCallsResult, void> {
|
|
698
759
|
const results: Array<ToolResult> = []
|
|
699
760
|
const needsApproval: Array<ApprovalRequest> = []
|
|
@@ -709,7 +770,11 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
709
770
|
// defer all execution so side effects don't happen before the user decides.
|
|
710
771
|
const hasPendingApprovals = toolCalls.some((tc) => {
|
|
711
772
|
const t = toolMap.get(tc.function.name)
|
|
712
|
-
return
|
|
773
|
+
return (
|
|
774
|
+
t?.needsApproval &&
|
|
775
|
+
approvalResolution(approvals, tc.id) === undefined &&
|
|
776
|
+
!resumeState?.cancelledToolCallIds?.has(tc.id)
|
|
777
|
+
)
|
|
713
778
|
})
|
|
714
779
|
|
|
715
780
|
for (const toolCall of toolCalls) {
|
|
@@ -729,11 +794,25 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
729
794
|
|
|
730
795
|
// Skip non-pending tools while approvals are outstanding
|
|
731
796
|
if (hasPendingApprovals) {
|
|
732
|
-
|
|
797
|
+
const isPendingApproval =
|
|
798
|
+
tool.needsApproval &&
|
|
799
|
+
approvalResolution(approvals, toolCall.id) === undefined
|
|
800
|
+
const isPlainClientRequest = !tool.needsApproval && !tool.execute
|
|
801
|
+
if (!isPendingApproval && !isPlainClientRequest) {
|
|
733
802
|
continue
|
|
734
803
|
}
|
|
735
804
|
}
|
|
736
805
|
|
|
806
|
+
if (resumeState?.cancelledToolCallIds?.has(toolCall.id)) {
|
|
807
|
+
results.push({
|
|
808
|
+
toolCallId: toolCall.id,
|
|
809
|
+
toolName,
|
|
810
|
+
result: { error: 'Tool execution cancelled' },
|
|
811
|
+
state: 'output-error',
|
|
812
|
+
})
|
|
813
|
+
continue
|
|
814
|
+
}
|
|
815
|
+
|
|
737
816
|
// Parse arguments, throwing error if invalid JSON
|
|
738
817
|
let input: unknown = {}
|
|
739
818
|
const argsStr = toolCall.function.arguments.trim() || '{}'
|
|
@@ -763,6 +842,8 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
763
842
|
result: {
|
|
764
843
|
error: `Input validation failed for tool ${tool.name}: ${message}`,
|
|
765
844
|
},
|
|
845
|
+
// raw parse may have failed validation — still attach best-effort input
|
|
846
|
+
input,
|
|
766
847
|
state: 'output-error',
|
|
767
848
|
})
|
|
768
849
|
continue
|
|
@@ -792,12 +873,14 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
792
873
|
// Check if tool needs approval
|
|
793
874
|
if (tool.needsApproval) {
|
|
794
875
|
const approvalId = `approval_${toolCall.id}`
|
|
876
|
+
const resolution = approvalResolution(approvals, toolCall.id)
|
|
795
877
|
|
|
796
878
|
// Check if approval decision exists
|
|
797
|
-
if (
|
|
798
|
-
const approved =
|
|
879
|
+
if (resolution !== undefined) {
|
|
880
|
+
const approved = isApproved(resolution)
|
|
799
881
|
|
|
800
882
|
if (approved) {
|
|
883
|
+
input = editedApprovalArgs(resolution) ?? input
|
|
801
884
|
// Approved - check if client has executed
|
|
802
885
|
if (clientResults.has(toolCall.id)) {
|
|
803
886
|
results.push(
|
|
@@ -806,6 +889,7 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
806
889
|
toolName,
|
|
807
890
|
tool,
|
|
808
891
|
clientResults.get(toolCall.id),
|
|
892
|
+
input,
|
|
809
893
|
),
|
|
810
894
|
)
|
|
811
895
|
} else {
|
|
@@ -821,7 +905,10 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
821
905
|
results.push({
|
|
822
906
|
toolCallId: toolCall.id,
|
|
823
907
|
toolName,
|
|
824
|
-
result:
|
|
908
|
+
result:
|
|
909
|
+
resumeState?.deniedToolResults?.get(toolCall.id) ??
|
|
910
|
+
deniedApprovalResult(resolution),
|
|
911
|
+
input,
|
|
825
912
|
state: 'output-error',
|
|
826
913
|
})
|
|
827
914
|
}
|
|
@@ -843,6 +930,7 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
843
930
|
toolName,
|
|
844
931
|
tool,
|
|
845
932
|
clientResults.get(toolCall.id),
|
|
933
|
+
input,
|
|
846
934
|
),
|
|
847
935
|
)
|
|
848
936
|
} else {
|
|
@@ -860,12 +948,14 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
860
948
|
// CASE 2: Server tool with approval required
|
|
861
949
|
if (tool.needsApproval) {
|
|
862
950
|
const approvalId = `approval_${toolCall.id}`
|
|
951
|
+
const resolution = approvalResolution(approvals, toolCall.id)
|
|
863
952
|
|
|
864
953
|
// Check if approval decision exists
|
|
865
|
-
if (
|
|
866
|
-
const approved =
|
|
954
|
+
if (resolution !== undefined) {
|
|
955
|
+
const approved = isApproved(resolution)
|
|
867
956
|
|
|
868
957
|
if (approved) {
|
|
958
|
+
input = editedApprovalArgs(resolution) ?? input
|
|
869
959
|
// Apply middleware before-hook for approved tools
|
|
870
960
|
if (middlewareHooks) {
|
|
871
961
|
const decision = await applyBeforeToolCallDecision(
|
|
@@ -895,7 +985,10 @@ export async function* executeToolCalls<TContext = unknown>(
|
|
|
895
985
|
results.push({
|
|
896
986
|
toolCallId: toolCall.id,
|
|
897
987
|
toolName,
|
|
898
|
-
result:
|
|
988
|
+
result:
|
|
989
|
+
resumeState?.deniedToolResults?.get(toolCall.id) ??
|
|
990
|
+
deniedApprovalResult(resolution),
|
|
991
|
+
input,
|
|
899
992
|
state: 'output-error',
|
|
900
993
|
})
|
|
901
994
|
}
|
|
@@ -1,36 +1,120 @@
|
|
|
1
|
-
import type { StandardJSONSchemaV1 } from '@standard-schema/spec'
|
|
2
1
|
import type {
|
|
2
|
+
InferSchemaType,
|
|
3
3
|
JSONSchema,
|
|
4
4
|
SchemaInput,
|
|
5
5
|
Tool,
|
|
6
6
|
ToolExecuteFunction,
|
|
7
7
|
} from '../../../types'
|
|
8
|
+
import type {
|
|
9
|
+
StandardJSONSchemaV1,
|
|
10
|
+
StandardSchemaV1,
|
|
11
|
+
} from '@standard-schema/spec'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Type-level brand key for {@link ToolApprovalCapabilityMarker}. Only ever used
|
|
15
|
+
* in type positions, but it must stay exported: a `unique symbol` referenced by
|
|
16
|
+
* an exported interface has to be nameable in the emitted declarations.
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export declare const toolApprovalCapability: unique symbol
|
|
21
|
+
|
|
22
|
+
export interface ToolApprovalCapabilityMarker<
|
|
23
|
+
TNeedsApproval extends boolean,
|
|
24
|
+
TApprovalSchema,
|
|
25
|
+
> {
|
|
26
|
+
readonly [toolApprovalCapability]?: {
|
|
27
|
+
needsApproval: TNeedsApproval
|
|
28
|
+
approvalSchema: TApprovalSchema
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ApprovalSchemaConfig =
|
|
33
|
+
| SchemaInput
|
|
34
|
+
| { approve: SchemaInput; reject?: SchemaInput }
|
|
35
|
+
| { approve?: SchemaInput; reject: SchemaInput }
|
|
36
|
+
|
|
37
|
+
type ApprovalConfig<
|
|
38
|
+
TNeedsApproval extends boolean,
|
|
39
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined,
|
|
40
|
+
> = TNeedsApproval extends true
|
|
41
|
+
? { needsApproval: TNeedsApproval; approvalSchema?: TApprovalSchema }
|
|
42
|
+
: { needsApproval?: TNeedsApproval; approvalSchema?: never }
|
|
43
|
+
|
|
44
|
+
export type ApprovalCapabilityOf<TTool> =
|
|
45
|
+
TTool extends ToolApprovalCapabilityMarker<infer TNeeds, unknown>
|
|
46
|
+
? TNeeds
|
|
47
|
+
: false
|
|
48
|
+
|
|
49
|
+
export type ApprovalSchemaOf<TTool> =
|
|
50
|
+
TTool extends ToolApprovalCapabilityMarker<boolean, infer TSchema>
|
|
51
|
+
? TSchema
|
|
52
|
+
: undefined
|
|
53
|
+
|
|
54
|
+
export declare const noSchema: unique symbol
|
|
55
|
+
export type NoSchema = typeof noSchema
|
|
56
|
+
|
|
57
|
+
export type InputSchemaOf<TTool> = TTool extends {
|
|
58
|
+
inputSchema: infer TInput
|
|
59
|
+
}
|
|
60
|
+
? TInput extends undefined
|
|
61
|
+
? NoSchema
|
|
62
|
+
: TInput
|
|
63
|
+
: NoSchema
|
|
64
|
+
|
|
65
|
+
export type OutputSchemaOf<TTool> = TTool extends {
|
|
66
|
+
outputSchema: infer TOutput
|
|
67
|
+
}
|
|
68
|
+
? TOutput extends undefined
|
|
69
|
+
? NoSchema
|
|
70
|
+
: TOutput
|
|
71
|
+
: NoSchema
|
|
72
|
+
|
|
73
|
+
type BuiltToolSchemaFields<
|
|
74
|
+
TInput extends SchemaInput | undefined,
|
|
75
|
+
TOutput extends SchemaInput | undefined,
|
|
76
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined,
|
|
77
|
+
> = {
|
|
78
|
+
inputSchema: TInput
|
|
79
|
+
outputSchema: TOutput
|
|
80
|
+
approvalSchema: TApprovalSchema
|
|
81
|
+
}
|
|
8
82
|
|
|
9
83
|
/**
|
|
10
84
|
* Marker type for server-side tools
|
|
11
85
|
*/
|
|
12
86
|
export interface ServerTool<
|
|
13
|
-
TInput extends SchemaInput =
|
|
14
|
-
TOutput extends SchemaInput =
|
|
87
|
+
TInput extends SchemaInput | undefined = undefined,
|
|
88
|
+
TOutput extends SchemaInput | undefined = undefined,
|
|
15
89
|
TName extends string = string,
|
|
16
90
|
TContext = unknown,
|
|
17
|
-
|
|
91
|
+
TNeedsApproval extends boolean = false,
|
|
92
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined,
|
|
93
|
+
>
|
|
94
|
+
extends
|
|
95
|
+
Tool<TInput, TOutput, TName, TContext>,
|
|
96
|
+
ToolApprovalCapabilityMarker<TNeedsApproval, TApprovalSchema> {
|
|
18
97
|
__toolSide: 'server'
|
|
98
|
+
inputSchema?: TInput
|
|
99
|
+
outputSchema?: TOutput
|
|
100
|
+
needsApproval?: TNeedsApproval
|
|
101
|
+
approvalSchema?: TApprovalSchema
|
|
19
102
|
}
|
|
20
103
|
|
|
21
104
|
/**
|
|
22
105
|
* Marker type for client-side tools
|
|
23
106
|
*/
|
|
24
107
|
export interface ClientTool<
|
|
25
|
-
TInput extends SchemaInput =
|
|
26
|
-
TOutput extends SchemaInput =
|
|
108
|
+
TInput extends SchemaInput | undefined = undefined,
|
|
109
|
+
TOutput extends SchemaInput | undefined = undefined,
|
|
27
110
|
TName extends string = string,
|
|
28
111
|
TContext = unknown,
|
|
29
112
|
// Captured as a literal (`true` / `false`) so downstream types — notably
|
|
30
113
|
// the tool-call part's `approval` field — can be gated on it. Defaults to
|
|
31
114
|
// `false` when the tool config omits `needsApproval`.
|
|
32
115
|
TNeedsApproval extends boolean = false,
|
|
33
|
-
|
|
116
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined,
|
|
117
|
+
> extends ToolApprovalCapabilityMarker<TNeedsApproval, TApprovalSchema> {
|
|
34
118
|
__toolSide: 'client'
|
|
35
119
|
name: TName
|
|
36
120
|
description: string
|
|
@@ -42,35 +126,55 @@ export interface ClientTool<
|
|
|
42
126
|
inputSchema?: TInput
|
|
43
127
|
outputSchema?: TOutput
|
|
44
128
|
needsApproval?: TNeedsApproval
|
|
129
|
+
approvalSchema?: TApprovalSchema
|
|
45
130
|
lazy?: boolean
|
|
46
131
|
metadata?: Record<string, unknown>
|
|
47
132
|
execute?: ToolExecuteFunction<TInput, TOutput, TContext>
|
|
48
133
|
}
|
|
49
134
|
|
|
135
|
+
/** Broad server-tool shape for heterogeneous internal collections. */
|
|
136
|
+
export type AnyServerTool = Omit<
|
|
137
|
+
ServerTool<any, any, string, any, boolean, any>,
|
|
138
|
+
'execute'
|
|
139
|
+
> & {
|
|
140
|
+
execute?: ((args: any, context?: any) => any) | undefined
|
|
141
|
+
}
|
|
142
|
+
|
|
50
143
|
/**
|
|
51
144
|
* Tool definition that can be used directly or instantiated for server/client
|
|
52
145
|
*/
|
|
53
146
|
export interface ToolDefinitionInstance<
|
|
54
|
-
TInput extends SchemaInput =
|
|
55
|
-
TOutput extends SchemaInput =
|
|
147
|
+
TInput extends SchemaInput | undefined = undefined,
|
|
148
|
+
TOutput extends SchemaInput | undefined = undefined,
|
|
56
149
|
TName extends string = string,
|
|
57
150
|
TContext = unknown,
|
|
58
151
|
TNeedsApproval extends boolean = false,
|
|
152
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined,
|
|
59
153
|
> extends Tool<TInput, TOutput, TName, TContext> {
|
|
60
154
|
__toolSide: 'definition'
|
|
61
155
|
// Narrow the base `needsApproval?: boolean` to the captured literal so it
|
|
62
156
|
// survives into `ToolCallPartForTool`'s approval gate.
|
|
157
|
+
inputSchema: TInput
|
|
158
|
+
outputSchema: TOutput
|
|
63
159
|
needsApproval?: TNeedsApproval
|
|
160
|
+
approvalSchema: TApprovalSchema
|
|
161
|
+
readonly [toolApprovalCapability]?: {
|
|
162
|
+
needsApproval: TNeedsApproval
|
|
163
|
+
approvalSchema: TApprovalSchema
|
|
164
|
+
}
|
|
64
165
|
}
|
|
65
166
|
|
|
66
167
|
/**
|
|
67
168
|
* Union type for any kind of client-side tool (client tool or definition)
|
|
68
169
|
*/
|
|
69
170
|
export type AnyClientTool =
|
|
70
|
-
| (Omit<ClientTool<any, any, string, any, boolean>, 'execute'> & {
|
|
171
|
+
| (Omit<ClientTool<any, any, string, any, boolean, any>, 'execute'> & {
|
|
71
172
|
execute?: ((args: any, context?: any) => any) | undefined
|
|
72
173
|
})
|
|
73
|
-
| (Omit<
|
|
174
|
+
| (Omit<
|
|
175
|
+
ToolDefinitionInstance<any, any, string, any, boolean, any>,
|
|
176
|
+
'execute'
|
|
177
|
+
> & {
|
|
74
178
|
execute?: ((args: any, context?: any) => any) | undefined
|
|
75
179
|
})
|
|
76
180
|
|
|
@@ -83,63 +187,73 @@ export type InferToolName<T> = T extends { name: infer N } ? N : never
|
|
|
83
187
|
* Extract the input type from a tool (inferred from Standard JSON Schema, or `unknown` for plain JSONSchema)
|
|
84
188
|
*/
|
|
85
189
|
export type InferToolInput<T> = T extends { inputSchema?: infer TInput }
|
|
86
|
-
? TInput extends
|
|
87
|
-
?
|
|
88
|
-
: TInput
|
|
89
|
-
? unknown
|
|
90
|
-
: unknown
|
|
190
|
+
? TInput extends JSONSchema
|
|
191
|
+
? unknown
|
|
192
|
+
: InferSchemaType<TInput>
|
|
91
193
|
: unknown
|
|
92
194
|
|
|
93
195
|
/**
|
|
94
196
|
* Extract the output type from a tool (inferred from Standard JSON Schema, or `unknown` for plain JSONSchema)
|
|
95
197
|
*/
|
|
96
198
|
export type InferToolOutput<T> = T extends { outputSchema?: infer TOutput }
|
|
97
|
-
? TOutput extends StandardJSONSchemaV1<
|
|
98
|
-
?
|
|
99
|
-
: TOutput extends
|
|
100
|
-
?
|
|
101
|
-
:
|
|
199
|
+
? TOutput extends StandardJSONSchemaV1<any, any>
|
|
200
|
+
? InferSchemaType<TOutput>
|
|
201
|
+
: TOutput extends StandardSchemaV1<any, any>
|
|
202
|
+
? InferSchemaType<TOutput>
|
|
203
|
+
: TOutput extends JSONSchema
|
|
204
|
+
? unknown
|
|
205
|
+
: InferSchemaType<TOutput>
|
|
102
206
|
: unknown
|
|
103
207
|
|
|
104
208
|
/**
|
|
105
209
|
* Tool definition configuration
|
|
106
210
|
*/
|
|
107
|
-
export
|
|
108
|
-
TInput extends SchemaInput =
|
|
109
|
-
TOutput extends SchemaInput =
|
|
211
|
+
export type ToolDefinitionConfig<
|
|
212
|
+
TInput extends SchemaInput | undefined = undefined,
|
|
213
|
+
TOutput extends SchemaInput | undefined = undefined,
|
|
110
214
|
TName extends string = string,
|
|
111
215
|
TNeedsApproval extends boolean = false,
|
|
112
|
-
|
|
216
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined,
|
|
217
|
+
> = {
|
|
113
218
|
name: TName
|
|
114
219
|
description: string
|
|
115
220
|
inputSchema?: TInput
|
|
116
221
|
outputSchema?: TOutput
|
|
117
|
-
needsApproval?: TNeedsApproval
|
|
118
222
|
lazy?: boolean
|
|
119
223
|
metadata?: Record<string, unknown>
|
|
120
|
-
}
|
|
224
|
+
} & ApprovalConfig<TNeedsApproval, TApprovalSchema>
|
|
121
225
|
|
|
122
226
|
/**
|
|
123
227
|
* Tool definition builder that allows creating server or client tools from a shared definition
|
|
124
228
|
*/
|
|
125
229
|
export interface ToolDefinition<
|
|
126
|
-
TInput extends SchemaInput =
|
|
127
|
-
TOutput extends SchemaInput =
|
|
230
|
+
TInput extends SchemaInput | undefined = undefined,
|
|
231
|
+
TOutput extends SchemaInput | undefined = undefined,
|
|
128
232
|
TName extends string = string,
|
|
129
233
|
TNeedsApproval extends boolean = false,
|
|
234
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined,
|
|
130
235
|
> extends ToolDefinitionInstance<
|
|
131
236
|
TInput,
|
|
132
237
|
TOutput,
|
|
133
238
|
TName,
|
|
134
239
|
unknown,
|
|
135
|
-
TNeedsApproval
|
|
240
|
+
TNeedsApproval,
|
|
241
|
+
TApprovalSchema
|
|
136
242
|
> {
|
|
137
243
|
/**
|
|
138
244
|
* Create a server-side tool with execute function
|
|
139
245
|
*/
|
|
140
246
|
server: <TContext = unknown>(
|
|
141
247
|
execute: ToolExecuteFunction<TInput, TOutput, TContext>,
|
|
142
|
-
) => ServerTool<
|
|
248
|
+
) => ServerTool<
|
|
249
|
+
TInput,
|
|
250
|
+
TOutput,
|
|
251
|
+
TName,
|
|
252
|
+
TContext,
|
|
253
|
+
TNeedsApproval,
|
|
254
|
+
TApprovalSchema
|
|
255
|
+
> &
|
|
256
|
+
BuiltToolSchemaFields<TInput, TOutput, TApprovalSchema>
|
|
143
257
|
|
|
144
258
|
/**
|
|
145
259
|
* Create a client-side tool with optional execute function.
|
|
@@ -148,7 +262,15 @@ export interface ToolDefinition<
|
|
|
148
262
|
*/
|
|
149
263
|
client: <TContext = unknown>(
|
|
150
264
|
execute?: ToolExecuteFunction<TInput, TOutput, TContext>,
|
|
151
|
-
) => ClientTool<
|
|
265
|
+
) => ClientTool<
|
|
266
|
+
TInput,
|
|
267
|
+
TOutput,
|
|
268
|
+
TName,
|
|
269
|
+
TContext,
|
|
270
|
+
TNeedsApproval,
|
|
271
|
+
TApprovalSchema
|
|
272
|
+
> &
|
|
273
|
+
BuiltToolSchemaFields<TInput, TOutput, TApprovalSchema>
|
|
152
274
|
}
|
|
153
275
|
|
|
154
276
|
/**
|
|
@@ -207,35 +329,84 @@ export interface ToolDefinition<
|
|
|
207
329
|
* ```
|
|
208
330
|
*/
|
|
209
331
|
export function toolDefinition<
|
|
210
|
-
TInput extends SchemaInput =
|
|
211
|
-
TOutput extends SchemaInput =
|
|
332
|
+
TInput extends SchemaInput | undefined = undefined,
|
|
333
|
+
TOutput extends SchemaInput | undefined = undefined,
|
|
212
334
|
TName extends string = string,
|
|
213
335
|
// `const` forces the literal (`true` / `false`) to be captured from the
|
|
214
336
|
// config's optional `needsApproval` — without it TS widens to `boolean`,
|
|
215
337
|
// which collapses the approval gate in `ToolCallPartForTool`.
|
|
216
338
|
const TNeedsApproval extends boolean = false,
|
|
339
|
+
TApprovalSchema extends ApprovalSchemaConfig | undefined = undefined,
|
|
217
340
|
>(
|
|
218
|
-
config: ToolDefinitionConfig<
|
|
219
|
-
|
|
220
|
-
|
|
341
|
+
config: ToolDefinitionConfig<
|
|
342
|
+
TInput,
|
|
343
|
+
TOutput,
|
|
344
|
+
TName,
|
|
345
|
+
TNeedsApproval,
|
|
346
|
+
TApprovalSchema
|
|
347
|
+
>,
|
|
348
|
+
): ToolDefinition<TInput, TOutput, TName, TNeedsApproval, TApprovalSchema> {
|
|
349
|
+
if (config.approvalSchema !== undefined && config.needsApproval !== true) {
|
|
350
|
+
throw new TypeError('approvalSchema requires needsApproval: true.')
|
|
351
|
+
}
|
|
352
|
+
const inputSchema = config.inputSchema as TInput
|
|
353
|
+
const outputSchema = config.outputSchema as TOutput
|
|
354
|
+
const approvalSchema = config.approvalSchema as TApprovalSchema
|
|
355
|
+
const needsApproval = config.needsApproval as TNeedsApproval | undefined
|
|
356
|
+
|
|
357
|
+
const definition: ToolDefinition<
|
|
358
|
+
TInput,
|
|
359
|
+
TOutput,
|
|
360
|
+
TName,
|
|
361
|
+
TNeedsApproval,
|
|
362
|
+
TApprovalSchema
|
|
363
|
+
> = {
|
|
221
364
|
__toolSide: 'definition',
|
|
222
365
|
...config,
|
|
366
|
+
inputSchema,
|
|
367
|
+
outputSchema,
|
|
368
|
+
approvalSchema,
|
|
369
|
+
needsApproval,
|
|
223
370
|
server<TContext = unknown>(
|
|
224
371
|
execute: ToolExecuteFunction<TInput, TOutput, TContext>,
|
|
225
|
-
): ServerTool<
|
|
372
|
+
): ServerTool<
|
|
373
|
+
TInput,
|
|
374
|
+
TOutput,
|
|
375
|
+
TName,
|
|
376
|
+
TContext,
|
|
377
|
+
TNeedsApproval,
|
|
378
|
+
TApprovalSchema
|
|
379
|
+
> &
|
|
380
|
+
BuiltToolSchemaFields<TInput, TOutput, TApprovalSchema> {
|
|
226
381
|
return {
|
|
227
382
|
__toolSide: 'server',
|
|
228
383
|
...config,
|
|
384
|
+
inputSchema,
|
|
385
|
+
outputSchema,
|
|
386
|
+
approvalSchema,
|
|
387
|
+
needsApproval,
|
|
229
388
|
execute,
|
|
230
389
|
}
|
|
231
390
|
},
|
|
232
391
|
|
|
233
392
|
client<TContext = unknown>(
|
|
234
393
|
execute?: ToolExecuteFunction<TInput, TOutput, TContext>,
|
|
235
|
-
): ClientTool<
|
|
394
|
+
): ClientTool<
|
|
395
|
+
TInput,
|
|
396
|
+
TOutput,
|
|
397
|
+
TName,
|
|
398
|
+
TContext,
|
|
399
|
+
TNeedsApproval,
|
|
400
|
+
TApprovalSchema
|
|
401
|
+
> &
|
|
402
|
+
BuiltToolSchemaFields<TInput, TOutput, TApprovalSchema> {
|
|
236
403
|
return {
|
|
237
404
|
__toolSide: 'client',
|
|
238
405
|
...config,
|
|
406
|
+
inputSchema,
|
|
407
|
+
outputSchema,
|
|
408
|
+
approvalSchema,
|
|
409
|
+
needsApproval,
|
|
239
410
|
...(execute !== undefined && { execute }),
|
|
240
411
|
}
|
|
241
412
|
},
|