@vinhnt-sdk/core 0.6.1 → 0.7.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 +149 -87
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/kernel/handoff.d.ts +136 -0
- package/dist/kernel/handoff.d.ts.map +1 -0
- package/dist/kernel/handoff.js +144 -0
- package/dist/kernel/handoff.js.map +1 -0
- package/dist/kernel/kernel-types.d.ts +112 -13
- package/dist/kernel/kernel-types.d.ts.map +1 -1
- package/dist/kernel/kernel-types.js.map +1 -1
- package/dist/kernel/kernel.d.ts +13 -0
- package/dist/kernel/kernel.d.ts.map +1 -1
- package/dist/kernel/kernel.js +82 -11
- package/dist/kernel/kernel.js.map +1 -1
- package/dist/kernel/run-context.d.ts +130 -22
- package/dist/kernel/run-context.d.ts.map +1 -1
- package/dist/kernel/run-context.js +169 -11
- package/dist/kernel/run-context.js.map +1 -1
- package/dist/kernel/run-loop.d.ts +39 -1
- package/dist/kernel/run-loop.d.ts.map +1 -1
- package/dist/kernel/run-loop.js +151 -6
- package/dist/kernel/run-loop.js.map +1 -1
- package/dist/tool/bridge.js +1 -1
- package/dist/tool/bridge.js.map +1 -1
- package/dist/tool/runtime.d.ts +18 -1
- package/dist/tool/runtime.d.ts.map +1 -1
- package/dist/tool/runtime.js +62 -4
- package/dist/tool/runtime.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @vinhnt-sdk/core
|
|
2
2
|
|
|
3
|
-
> Version: 0.1
|
|
3
|
+
> Version: 0.6.1 | Status: STABLE
|
|
4
4
|
|
|
5
|
-
Core agent engine for vinhnt-sdk — kernel, orchestration, streaming, event bus, and
|
|
5
|
+
Core agent engine for vinhnt-sdk — kernel, orchestration, streaming, event bus, and workflows.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -14,63 +14,79 @@ npm install @vinhnt-sdk/core
|
|
|
14
14
|
pnpm add @vinhnt-sdk/core
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- **AgentKernel** — Main orchestration engine with configurable steps, retries, and circuit breaker
|
|
20
|
+
- **RunUsage** — Nested usage metrics (tokens, cost, duration, tool calls)
|
|
21
|
+
- **AgentRunHandle** — Lifecycle management with cancel, events streaming, and completion tracking
|
|
22
|
+
- **Agent-as-Tool** — Delegate work to sub-agents via tool interface
|
|
23
|
+
- **Workflow** — Parallel, sequential, and conditional step execution
|
|
24
|
+
- **Guardrails** — Input/output safety tripwires
|
|
25
|
+
- **Guard System** — Monotonic guard decisions for tool execution
|
|
26
|
+
|
|
17
27
|
## Quick Start
|
|
18
28
|
|
|
19
29
|
```typescript
|
|
20
|
-
import { AgentKernel } from
|
|
21
|
-
import
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
async
|
|
32
|
-
|
|
33
|
-
|
|
30
|
+
import { AgentKernel, InMemoryEventBus } from "@vinhnt-sdk/core";
|
|
31
|
+
import { defineTool } from "@vinhnt-sdk/tools";
|
|
32
|
+
import { z } from "zod";
|
|
33
|
+
|
|
34
|
+
const calculatorTool = defineTool({
|
|
35
|
+
name: "calculator",
|
|
36
|
+
description: "Perform arithmetic calculations",
|
|
37
|
+
risk: "read",
|
|
38
|
+
input: z.object({
|
|
39
|
+
expression: z.string(),
|
|
40
|
+
}),
|
|
41
|
+
async execute(input) {
|
|
42
|
+
const parts = input.expression.match(/^(\d+)\s*([+\-*/])\s*(\d+)$/);
|
|
43
|
+
if (!parts) throw new Error("Invalid expression");
|
|
44
|
+
const [, a, op, b] = parts;
|
|
45
|
+
const numA = parseInt(a, 10);
|
|
46
|
+
const numB = parseInt(b, 10);
|
|
47
|
+
switch (op) {
|
|
48
|
+
case "+": return { result: numA + numB };
|
|
49
|
+
case "-": return { result: numA - numB };
|
|
50
|
+
case "*": return { result: numA * numB };
|
|
51
|
+
case "/": return { result: numA / numB };
|
|
52
|
+
default: throw new Error("Unknown operator");
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
}).toDefinition();
|
|
34
56
|
|
|
35
|
-
// Create kernel
|
|
36
57
|
const kernel = new AgentKernel({
|
|
37
58
|
model: yourModelProvider,
|
|
38
|
-
store: new
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// Create run handle
|
|
43
|
-
const handle = kernel.createRunHandle("Hello!", {
|
|
44
|
-
sessionId: "session-123",
|
|
45
|
-
agentId: "my-agent",
|
|
46
|
-
userId: "user-1",
|
|
59
|
+
store: new InMemoryEventBus(),
|
|
60
|
+
tools: [calculatorTool],
|
|
61
|
+
maxSteps: 10,
|
|
47
62
|
});
|
|
48
63
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
64
|
+
const handle = kernel.createRunHandle("Calculate 2 + 2", {
|
|
65
|
+
sessionId: "session-1",
|
|
66
|
+
agentId: "calculator-agent",
|
|
52
67
|
});
|
|
53
68
|
|
|
54
|
-
// Wait for completion
|
|
55
69
|
const result = await handle.completed;
|
|
56
70
|
console.log(result.status); // "succeeded"
|
|
71
|
+
console.log(result.usage); // RunUsage with nested metrics
|
|
57
72
|
```
|
|
58
73
|
|
|
59
74
|
## API Reference
|
|
60
75
|
|
|
61
76
|
### Core Classes
|
|
62
77
|
|
|
63
|
-
| Export |
|
|
64
|
-
|
|
65
|
-
| `AgentKernel` |
|
|
66
|
-
| `
|
|
67
|
-
| `
|
|
68
|
-
| `
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
78
|
+
| Export | Description |
|
|
79
|
+
|--------|-------------|
|
|
80
|
+
| `AgentKernel` | Main kernel for agent orchestration |
|
|
81
|
+
| `KernelError` | Error class for kernel failures |
|
|
82
|
+
| `InMemoryEventBus` | Typed pub/sub event bus |
|
|
83
|
+
| `InMemorySessionState` | Session state management |
|
|
84
|
+
| `SessionRunCoordinator` | Run coordination across sessions |
|
|
85
|
+
| `InMemoryAgentRegistry` | Agent registry for sub-agents |
|
|
86
|
+
| `InMemoryModelRegistry` | Model registry for multi-model routing |
|
|
87
|
+
| `InMemoryApprovalStore` | Approval storage for permissions |
|
|
88
|
+
| `WorkspaceManager` | Workspace file management |
|
|
89
|
+
| `Tracer` | Execution tracing |
|
|
74
90
|
|
|
75
91
|
### Kernel Methods
|
|
76
92
|
|
|
@@ -81,13 +97,12 @@ console.log(result.status); // "succeeded"
|
|
|
81
97
|
| `streamRun(prompt, ctx)` | Stream run events |
|
|
82
98
|
| `reconfigure(config)` | Reconfigure kernel |
|
|
83
99
|
|
|
84
|
-
###
|
|
100
|
+
### AgentRunHandle
|
|
85
101
|
|
|
86
102
|
```typescript
|
|
87
103
|
const handle = kernel.createRunHandle(prompt, {
|
|
88
104
|
sessionId: "session-123",
|
|
89
105
|
agentId: "my-agent",
|
|
90
|
-
userId: "user-1",
|
|
91
106
|
});
|
|
92
107
|
|
|
93
108
|
// Properties
|
|
@@ -97,7 +112,7 @@ handle.isCompleted; // Is completed
|
|
|
97
112
|
handle.isCancelled; // Is cancelled
|
|
98
113
|
|
|
99
114
|
// Methods
|
|
100
|
-
handle.onEvent(handler); //
|
|
115
|
+
handle.onEvent(handler); // Subscribe to events
|
|
101
116
|
handle.events(); // Async iterable of events
|
|
102
117
|
handle.cancel(); // Cancel run
|
|
103
118
|
|
|
@@ -105,84 +120,134 @@ handle.cancel(); // Cancel run
|
|
|
105
120
|
const result = await handle.completed;
|
|
106
121
|
```
|
|
107
122
|
|
|
108
|
-
###
|
|
123
|
+
### AgentRunResult (Nested Usage Pattern)
|
|
109
124
|
|
|
110
125
|
```typescript
|
|
111
|
-
|
|
126
|
+
interface AgentRunResult {
|
|
127
|
+
readonly runId: RunId;
|
|
128
|
+
readonly status: "succeeded" | "failed" | "cancelled";
|
|
129
|
+
readonly output?: string;
|
|
130
|
+
readonly error?: string;
|
|
131
|
+
readonly usage?: RunUsage;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
interface RunUsage {
|
|
135
|
+
readonly totalSteps: number;
|
|
136
|
+
readonly durationMs?: number;
|
|
137
|
+
readonly inputTokens?: number;
|
|
138
|
+
readonly outputTokens?: number;
|
|
139
|
+
readonly reasoningTokens?: number;
|
|
140
|
+
readonly cacheReadTokens?: number;
|
|
141
|
+
readonly cacheWriteTokens?: number;
|
|
142
|
+
readonly totalTokens?: number;
|
|
143
|
+
readonly cost?: number;
|
|
144
|
+
readonly toolCallsCount?: number;
|
|
145
|
+
readonly model?: string;
|
|
146
|
+
readonly provider?: string;
|
|
147
|
+
readonly stopReason?: string;
|
|
148
|
+
readonly raw?: Record<string, unknown>;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
112
151
|
|
|
113
|
-
|
|
152
|
+
### Agent-as-Tool
|
|
114
153
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
154
|
+
```typescript
|
|
155
|
+
import { agentAsTool, createHandoffTool } from "@vinhnt-sdk/core";
|
|
156
|
+
|
|
157
|
+
const codeReviewTool = agentAsTool({
|
|
158
|
+
agentId: "code-reviewer",
|
|
159
|
+
description: "Review code for issues",
|
|
160
|
+
kernel,
|
|
118
161
|
});
|
|
119
162
|
|
|
120
|
-
//
|
|
121
|
-
|
|
163
|
+
// Use in another agent
|
|
164
|
+
const kernel2 = new AgentKernel({
|
|
165
|
+
model: provider,
|
|
166
|
+
store: eventStore,
|
|
167
|
+
tools: [codeReviewTool],
|
|
168
|
+
});
|
|
169
|
+
```
|
|
122
170
|
|
|
123
|
-
|
|
124
|
-
for await (const event of bus.stream(eventDef, abortSignal)) {
|
|
125
|
-
console.log(event);
|
|
126
|
-
}
|
|
171
|
+
### Workflow
|
|
127
172
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
173
|
+
```typescript
|
|
174
|
+
import { parallel, sequential, conditional } from "@vinhnt-sdk/core";
|
|
175
|
+
|
|
176
|
+
// Sequential execution
|
|
177
|
+
const result = await sequential([
|
|
178
|
+
{ step: step1 },
|
|
179
|
+
{ step: step2 },
|
|
180
|
+
{ step: step3 },
|
|
181
|
+
], context);
|
|
182
|
+
|
|
183
|
+
// Parallel execution
|
|
184
|
+
const results = await parallel([
|
|
185
|
+
{ step: fetchUsers },
|
|
186
|
+
{ step: fetchOrders },
|
|
187
|
+
{ step: fetchProducts },
|
|
188
|
+
], context);
|
|
189
|
+
|
|
190
|
+
// Conditional execution
|
|
191
|
+
const result = await conditional([
|
|
192
|
+
{ branch: "if-high-priority", condition: (ctx) => ctx.priority === "high", step: handleHighPriority },
|
|
193
|
+
{ branch: "default", step: handleNormal },
|
|
194
|
+
], context);
|
|
132
195
|
```
|
|
133
196
|
|
|
134
|
-
###
|
|
197
|
+
### Guardrails
|
|
135
198
|
|
|
136
199
|
```typescript
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
resetTimeoutMs: 30_000,
|
|
146
|
-
maxRetries: 3,
|
|
147
|
-
retryBackoffMs: 1000,
|
|
148
|
-
maxRetryBackoffMs: 30_000,
|
|
149
|
-
},
|
|
200
|
+
import { runGuardrails, maxLengthGuardrail, blocklistGuardrail } from "@vinhnt-sdk/core";
|
|
201
|
+
|
|
202
|
+
const result = await runGuardrails({
|
|
203
|
+
input: userInput,
|
|
204
|
+
guardrails: [
|
|
205
|
+
maxLengthGuardrail({ maxLength: 10000 }),
|
|
206
|
+
blocklistGuardrail({ patterns: ["password", "secret"] }),
|
|
207
|
+
],
|
|
150
208
|
});
|
|
209
|
+
|
|
210
|
+
if (result.blocked) {
|
|
211
|
+
console.log("Input blocked:", result.reason);
|
|
212
|
+
}
|
|
151
213
|
```
|
|
152
214
|
|
|
153
215
|
## Dependencies
|
|
154
216
|
|
|
155
|
-
- `@vinhnt-sdk/schema`
|
|
156
|
-
- `@vinhnt-sdk/
|
|
217
|
+
- `@vinhnt-sdk/schema` >=0.5.0
|
|
218
|
+
- `@vinhnt-sdk/event` workspace:*
|
|
219
|
+
- `@vinhnt-sdk/llm` workspace:*
|
|
220
|
+
- `@vinhnt-sdk/permission` workspace:*
|
|
221
|
+
- `@vinhnt-sdk/sandbox` workspace:*
|
|
222
|
+
- `@vinhnt-sdk/guard` workspace:*
|
|
223
|
+
- `@vinhnt-sdk/guardrails` workspace:*
|
|
224
|
+
- `@vinhnt-sdk/workflow` workspace:*
|
|
225
|
+
- `@vinhnt-sdk/session` workspace:*
|
|
157
226
|
- `@vinhnt-sdk/knowledge` workspace:*
|
|
158
227
|
- `@vinhnt-sdk/tools` workspace:*
|
|
228
|
+
- `@vinhnt-sdk/step-executor` workspace:*
|
|
159
229
|
- `zod` ^4.4.3
|
|
160
230
|
|
|
161
|
-
## Peer Dependencies
|
|
162
|
-
|
|
163
|
-
None
|
|
164
|
-
|
|
165
231
|
## Usage Examples
|
|
166
232
|
|
|
167
233
|
### Basic Agent Run
|
|
168
234
|
|
|
169
235
|
```typescript
|
|
170
|
-
import { AgentKernel } from
|
|
236
|
+
import { AgentKernel, InMemoryEventBus } from "@vinhnt-sdk/core";
|
|
171
237
|
|
|
172
238
|
const kernel = new AgentKernel({
|
|
173
239
|
model: yourModelProvider,
|
|
174
|
-
store:
|
|
240
|
+
store: new InMemoryEventBus(),
|
|
175
241
|
});
|
|
176
242
|
|
|
177
|
-
// Simple run
|
|
178
243
|
const handle = kernel.createRunHandle("Write a hello world program", {
|
|
179
244
|
sessionId: "session-1",
|
|
180
245
|
agentId: "coder",
|
|
181
|
-
userId: "developer",
|
|
182
246
|
});
|
|
183
247
|
|
|
184
248
|
const result = await handle.completed;
|
|
185
249
|
console.log(result.output);
|
|
250
|
+
console.log(result.usage?.totalTokens);
|
|
186
251
|
```
|
|
187
252
|
|
|
188
253
|
### Streaming Events
|
|
@@ -191,10 +256,8 @@ console.log(result.output);
|
|
|
191
256
|
const handle = kernel.createRunHandle("Tell me a story", {
|
|
192
257
|
sessionId: "session-2",
|
|
193
258
|
agentId: "storyteller",
|
|
194
|
-
userId: "user-1",
|
|
195
259
|
});
|
|
196
260
|
|
|
197
|
-
// Stream events
|
|
198
261
|
for await (const event of handle.events()) {
|
|
199
262
|
switch (event.type) {
|
|
200
263
|
case "agent.started":
|
|
@@ -218,7 +281,6 @@ for await (const event of handle.events()) {
|
|
|
218
281
|
```typescript
|
|
219
282
|
const handle = kernel.createRunHandle("Long running task", ctx);
|
|
220
283
|
|
|
221
|
-
// Cancel after 5 seconds
|
|
222
284
|
setTimeout(() => handle.cancel(), 5000);
|
|
223
285
|
|
|
224
286
|
const result = await handle.completed;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
export { AgentKernel, KernelError } from "./kernel/kernel.js";
|
|
2
2
|
export { canTransitionRun, terminalRunStatuses } from "./kernel/state-machine.js";
|
|
3
3
|
export { RunStateMachine } from "@vinhnt-sdk/step-executor";
|
|
4
|
-
export type { AgentKernelConfig, RunHandle, AgentRunHandle, AgentRunResult } from "./kernel/kernel-types.js";
|
|
4
|
+
export type { AgentKernelConfig, ModelSettings, RunHandle, AgentRunHandle, AgentRunResult, RunUsage } from "./kernel/kernel-types.js";
|
|
5
|
+
export { AgentRunContext } from "./kernel/run-context.js";
|
|
6
|
+
export type { ApprovalRecord } from "./kernel/run-context.js";
|
|
5
7
|
export { createAgent } from "./agent/agent-factory.js";
|
|
6
8
|
export type { CreateAgentParams } from "./agent/agent-factory.js";
|
|
7
9
|
export { agentAsTool, createHandoffTool } from "./kernel/agent-as-tool.js";
|
|
8
10
|
export type { AgentAsToolOptions } from "./kernel/agent-as-tool.js";
|
|
11
|
+
export { createHandoff, isHandoff, HANDOFF_SYMBOL, HandoffTracker } from "./kernel/handoff.js";
|
|
12
|
+
export type { Handoff, HandoffToolOptions, HandoffRecord } from "./kernel/handoff.js";
|
|
9
13
|
export { createUpdatePlanTool, createGetPlanTool } from "./tools/update-plan.js";
|
|
10
14
|
export type { Plan, PlanStep } from "./tools/update-plan.js";
|
|
11
15
|
export { InMemoryEventBus } from "@vinhnt-sdk/event";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,YAAY,EAAE,iBAAiB,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7,10 +7,13 @@
|
|
|
7
7
|
export { AgentKernel, KernelError } from "./kernel/kernel.js";
|
|
8
8
|
export { canTransitionRun, terminalRunStatuses } from "./kernel/state-machine.js";
|
|
9
9
|
export { RunStateMachine } from "@vinhnt-sdk/step-executor";
|
|
10
|
+
export { AgentRunContext } from "./kernel/run-context.js";
|
|
10
11
|
// === Agent system ===
|
|
11
12
|
export { createAgent } from "./agent/agent-factory.js";
|
|
12
13
|
// === Agent-as-Tool ===
|
|
13
14
|
export { agentAsTool, createHandoffTool } from "./kernel/agent-as-tool.js";
|
|
15
|
+
// === Handoff ===
|
|
16
|
+
export { createHandoff, isHandoff, HANDOFF_SYMBOL, HandoffTracker } from "./kernel/handoff.js";
|
|
14
17
|
// === Plan tracking ===
|
|
15
18
|
export { createUpdatePlanTool, createGetPlanTool } from "./tools/update-plan.js";
|
|
16
19
|
// === Event bus ===
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB;AACnB,kDAAkD;AAClD,EAAE;AACF,6CAA6C;AAC7C,iDAAiD;AAEjD,gCAAgC;AAEhC,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Handoff — signal that transfers control to another agent.
|
|
3
|
+
*
|
|
4
|
+
* When a tool returns a `Handoff`, the run loop detects it and swaps the
|
|
5
|
+
* active agent. The new agent takes over the conversation from the next step.
|
|
6
|
+
*
|
|
7
|
+
* Follows the OpenAI Agents SDK pattern: handoff is a special tool return
|
|
8
|
+
* value that the runner intercepts, not a regular tool output.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { handoff, type Handoff } from '@vinhnt-sdk/core';
|
|
13
|
+
*
|
|
14
|
+
* // Define a handoff tool
|
|
15
|
+
* const transferToBilling = handoff({
|
|
16
|
+
* agentId: 'billing-agent',
|
|
17
|
+
* toolName: 'transfer_to_billing',
|
|
18
|
+
* toolDescription: 'Transfer to billing specialist for payment issues',
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* // Register on agent
|
|
22
|
+
* const triageAgent = createAgent({
|
|
23
|
+
* id: 'triage',
|
|
24
|
+
* tools: [transferToBilling, ...otherTools],
|
|
25
|
+
* });
|
|
26
|
+
*
|
|
27
|
+
* // When LLM calls transfer_to_billing, run loop detects Handoff
|
|
28
|
+
* // and swaps active agent to billing-agent.
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
import type { AgentId } from "@vinhnt-sdk/schema";
|
|
32
|
+
import { type ToolDefinition } from "@vinhnt-sdk/tools";
|
|
33
|
+
/**
|
|
34
|
+
* Symbol used to identify handoff results in tool output.
|
|
35
|
+
* The run loop checks for this symbol to detect agent transfers.
|
|
36
|
+
*/
|
|
37
|
+
export declare const HANDOFF_SYMBOL: unique symbol;
|
|
38
|
+
/**
|
|
39
|
+
* A handoff result — signals the run loop to transfer control.
|
|
40
|
+
*
|
|
41
|
+
* Not a regular tool output. The run loop intercepts this and swaps agents.
|
|
42
|
+
*/
|
|
43
|
+
export interface Handoff {
|
|
44
|
+
readonly [key: symbol]: true | undefined;
|
|
45
|
+
readonly __handoff: true;
|
|
46
|
+
/** Target agent to transfer control to. */
|
|
47
|
+
readonly targetAgentId: AgentId;
|
|
48
|
+
/** Reason for the handoff (for logging/tracing). */
|
|
49
|
+
readonly reason: string;
|
|
50
|
+
/** Optional summary of conversation so far (passed to target agent). */
|
|
51
|
+
readonly summary?: string | undefined;
|
|
52
|
+
/** Optional context data to pass to the target agent. */
|
|
53
|
+
readonly context?: Record<string, unknown> | undefined;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a value is a Handoff.
|
|
57
|
+
*/
|
|
58
|
+
export declare function isHandoff(value: unknown): value is Handoff;
|
|
59
|
+
/**
|
|
60
|
+
* Create a Handoff result.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createHandoff(options: {
|
|
63
|
+
targetAgentId: AgentId;
|
|
64
|
+
reason: string;
|
|
65
|
+
summary?: string | undefined;
|
|
66
|
+
context?: Record<string, unknown> | undefined;
|
|
67
|
+
}): Handoff;
|
|
68
|
+
export interface HandoffToolOptions {
|
|
69
|
+
/** Target agent ID to transfer to. */
|
|
70
|
+
readonly agentId: AgentId;
|
|
71
|
+
/** Tool name (default: "transfer_to_{agentId}") */
|
|
72
|
+
readonly toolName?: string;
|
|
73
|
+
/** Tool description for the LLM. */
|
|
74
|
+
readonly toolDescription: string;
|
|
75
|
+
/** Callback before handoff (for logging). */
|
|
76
|
+
readonly onHandoff?: (reason: string) => void | Promise<void>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Create a handoff tool — when LLM calls it, control transfers to target agent.
|
|
80
|
+
*
|
|
81
|
+
* Unlike `agentAsTool` (parent keeps control), handoff gives full control
|
|
82
|
+
* to the target agent. The original agent pauses until the target completes
|
|
83
|
+
* or transfers back.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```ts
|
|
87
|
+
* const handoffTool = createHandoffTool({
|
|
88
|
+
* agentId: 'billing' as AgentId,
|
|
89
|
+
* toolDescription: 'Transfer to billing specialist for payment issues',
|
|
90
|
+
* onHandoff: (reason) => console.log('Transferring:', reason),
|
|
91
|
+
* });
|
|
92
|
+
*
|
|
93
|
+
* // Register on triage agent
|
|
94
|
+
* triageAgent.tools.push(handoffTool);
|
|
95
|
+
*
|
|
96
|
+
* // When LLM calls transfer_to_billing:
|
|
97
|
+
* // 1. Run loop executes the tool
|
|
98
|
+
* // 2. Tool returns Handoff object
|
|
99
|
+
* // 3. Run loop detects Handoff
|
|
100
|
+
* // 4. Active agent swaps to billing-agent
|
|
101
|
+
* // 5. Billing agent continues the conversation
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export declare function createHandoffTool(options: HandoffToolOptions): ToolDefinition;
|
|
105
|
+
/**
|
|
106
|
+
* Record of a handoff that occurred during a run.
|
|
107
|
+
*/
|
|
108
|
+
export interface HandoffRecord {
|
|
109
|
+
/** Timestamp of the handoff. */
|
|
110
|
+
readonly timestamp: number;
|
|
111
|
+
/** Agent that initiated the handoff. */
|
|
112
|
+
readonly fromAgentId: AgentId;
|
|
113
|
+
/** Agent that received control. */
|
|
114
|
+
readonly toAgentId: AgentId;
|
|
115
|
+
/** Reason for the handoff. */
|
|
116
|
+
readonly reason: string;
|
|
117
|
+
/** Step number when handoff occurred. */
|
|
118
|
+
readonly step: number;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Track handoff history for a run (cycle detection, debugging).
|
|
122
|
+
*/
|
|
123
|
+
export declare class HandoffTracker {
|
|
124
|
+
private readonly history;
|
|
125
|
+
private readonly maxDepth;
|
|
126
|
+
constructor(maxDepth?: number);
|
|
127
|
+
/** Record a handoff. Returns false if cycle detected or max depth exceeded. */
|
|
128
|
+
record(record: HandoffRecord): boolean;
|
|
129
|
+
/** Get the full handoff history. */
|
|
130
|
+
getHistory(): readonly HandoffRecord[];
|
|
131
|
+
/** Get the chain of agent IDs in this handoff chain. */
|
|
132
|
+
getAgentChain(): AgentId[];
|
|
133
|
+
/** Check if an agent has already been visited (cycle detection). */
|
|
134
|
+
hasVisited(agentId: AgentId): boolean;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=handoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handoff.d.ts","sourceRoot":"","sources":["../../src/kernel/handoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEpE;;;GAGG;AACH,eAAO,MAAM,cAAc,eAAyC,CAAC;AAErE;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,2CAA2C;IAC3C,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;IAChC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CACxD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,CAM1D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IACrC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;CAC/C,GAAG,OAAO,CASV;AAMD,MAAM,WAAW,kBAAkB;IACjC,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CA6B7E;AAMD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,wCAAwC;IACxC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,mCAAmC;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8BAA8B;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,GAAE,MAAW;IAIjC,+EAA+E;IAC/E,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO;IAgBtC,oCAAoC;IACpC,UAAU,IAAI,SAAS,aAAa,EAAE;IAItC,wDAAwD;IACxD,aAAa,IAAI,OAAO,EAAE;IAI1B,oEAAoE;IACpE,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO;CAGtC"}
|