agent-lattice 0.15.0 → 0.17.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 +186 -13
- package/dist/index.d.ts +144 -5
- package/dist/index.js +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,6 +55,11 @@ const agent = createBareAgent({
|
|
|
55
55
|
});
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
+
`Agent` is a type-only export — instances come from these factories (or
|
|
59
|
+
`AgentSpec.spawn()`), never from `new Agent()`, because the factories also
|
|
60
|
+
generate the session id and install the workspace. (Breaking in 0.17.0: the
|
|
61
|
+
`Agent` class constructor is no longer exported.)
|
|
62
|
+
|
|
58
63
|
`agent.query()` yields `stream_event` messages while the model is still
|
|
59
64
|
responding, so a host can render output incrementally:
|
|
60
65
|
|
|
@@ -73,6 +78,19 @@ The SDK produces the next event only after the loop takes the current one.
|
|
|
73
78
|
Slow work in the loop body delays later events without dropping or reordering
|
|
74
79
|
them, so keep expensive handling off the loop itself.
|
|
75
80
|
|
|
81
|
+
`query()` yields these SDK messages:
|
|
82
|
+
|
|
83
|
+
| Type | When | What it carries |
|
|
84
|
+
| --- | --- | --- |
|
|
85
|
+
| `system` | Query start | Session init metadata (model, tools, `session_id`). |
|
|
86
|
+
| `stream_event` | While the model is responding | Raw provider stream event for incremental rendering. |
|
|
87
|
+
| `assistant` | After each model turn is assembled | The `AssistantModelMessage` with text / `tool_use` blocks and provider metadata. |
|
|
88
|
+
| `user` | After a whole tool batch finishes | Tool results as `ToolResultBlock[]`; the prompt is never echoed. |
|
|
89
|
+
| `result` | Once, at the end of the query | Final text, `subtype` (`"success"`, `"interrupted"`, or an error variant), and token usage. |
|
|
90
|
+
|
|
91
|
+
For the exact per-event guarantees see
|
|
92
|
+
[Streaming Events](https://docs.claude-code-sdk.com/concepts/streaming-events/).
|
|
93
|
+
|
|
76
94
|
Pass `{ stream: false }` to disable model streaming for a query:
|
|
77
95
|
|
|
78
96
|
```ts
|
|
@@ -208,9 +226,9 @@ for await (const event of team.query("Ask engineering to investigate.", {
|
|
|
208
226
|
|
|
209
227
|
## LangSmith Context Tracing
|
|
210
228
|
|
|
211
|
-
|
|
212
|
-
`
|
|
213
|
-
|
|
229
|
+
The SDK depends on `langsmith` directly and uses its official `RunTree` /
|
|
230
|
+
`RunTreeConfig` types for this adapter, so the tracer works out of the box —
|
|
231
|
+
no constructor wiring needed.
|
|
214
232
|
|
|
215
233
|
Configure LangSmith with its standard environment variables:
|
|
216
234
|
|
|
@@ -224,7 +242,6 @@ LANGSMITH_WORKSPACE_ID=<your-langsmith-workspace-id>
|
|
|
224
242
|
```
|
|
225
243
|
|
|
226
244
|
```ts
|
|
227
|
-
import { RunTree } from "langsmith/run_trees";
|
|
228
245
|
import {
|
|
229
246
|
createAgent,
|
|
230
247
|
createCompositeContextTracer,
|
|
@@ -235,7 +252,6 @@ import {
|
|
|
235
252
|
const tracer = createCompositeContextTracer([
|
|
236
253
|
createJsonlContextTracer({ path: ".agent-runs/session.jsonl" }),
|
|
237
254
|
createLangSmithContextTracer({
|
|
238
|
-
RunTree,
|
|
239
255
|
projectName: process.env.LANGSMITH_PROJECT,
|
|
240
256
|
workspaceId: process.env.LANGSMITH_WORKSPACE_ID,
|
|
241
257
|
tags: ["local-debug"],
|
|
@@ -264,11 +280,9 @@ tracer. `workspaceId` is optional and only selects a LangSmith workspace; it is
|
|
|
264
280
|
not the tracing project name.
|
|
265
281
|
|
|
266
282
|
```ts
|
|
267
|
-
import { RunTree } from "langsmith/run_trees";
|
|
268
283
|
import { createLangSmithContextTracer } from "agent-lattice";
|
|
269
284
|
|
|
270
285
|
const tracer = createLangSmithContextTracer({
|
|
271
|
-
RunTree,
|
|
272
286
|
apiKey: process.env.LANGSMITH_API_KEY,
|
|
273
287
|
apiUrl: process.env.LANGSMITH_ENDPOINT,
|
|
274
288
|
projectName: process.env.LANGSMITH_PROJECT,
|
|
@@ -277,6 +291,9 @@ const tracer = createLangSmithContextTracer({
|
|
|
277
291
|
});
|
|
278
292
|
```
|
|
279
293
|
|
|
294
|
+
`RunTree` defaults to the bundled langsmith constructor since 0.17.0; pass
|
|
295
|
+
`RunTree` or `runTree` only to inject a custom runtime or a test fake.
|
|
296
|
+
|
|
280
297
|
LangSmith receives one root `chain` run per SDK query. For an `Agent` query,
|
|
281
298
|
model turns and SDK tool calls appear as child `llm` and `tool` runs. For a
|
|
282
299
|
`Team` query, the root represents the complete Team invocation; the initial
|
|
@@ -286,15 +303,21 @@ recorded as `agent_session_id` metadata, so tracing does not change Agent state
|
|
|
286
303
|
or returned SDK messages.
|
|
287
304
|
|
|
288
305
|
Custom sinks can implement the same interface for SQLite, OpenTelemetry, object
|
|
289
|
-
storage, or host-specific observability.
|
|
290
|
-
|
|
306
|
+
storage, or host-specific observability. A `ContextTracer` port object exposes
|
|
307
|
+
methods only — `failOnError` is bound when the factory creates the tracer, not
|
|
308
|
+
set as a field afterwards. Implement a custom sink with `defineContextTracer()`.
|
|
309
|
+
*Requires 0.17.0 or later.* (Breaking in 0.17.0: the public `failOnError` field
|
|
310
|
+
was removed from `ContextTracer`; custom tracers created before 0.17.0 must go
|
|
311
|
+
through `defineContextTracer()`.)
|
|
291
312
|
|
|
292
313
|
```ts
|
|
293
|
-
|
|
314
|
+
import { defineContextTracer } from "agent-lattice";
|
|
315
|
+
|
|
316
|
+
const tracer = defineContextTracer({
|
|
294
317
|
async onEvent(event) {
|
|
295
318
|
// TODO: Replace with your own storage/logging code.
|
|
296
319
|
},
|
|
297
|
-
};
|
|
320
|
+
});
|
|
298
321
|
```
|
|
299
322
|
|
|
300
323
|
## DeepSeek Anthropic-compatible API
|
|
@@ -334,6 +357,29 @@ const result = await agent.prompt("What is 2+2?");
|
|
|
334
357
|
console.log(result.result);
|
|
335
358
|
```
|
|
336
359
|
|
|
360
|
+
## End The Run From A Tool
|
|
361
|
+
|
|
362
|
+
*Requires 0.16.0 or later.*
|
|
363
|
+
|
|
364
|
+
A tool that has the final answer can end the run itself by returning
|
|
365
|
+
`endTurn: true`. The SDK finishes with `subtype: "success"` and uses that
|
|
366
|
+
tool's text content as the result, without calling the model again:
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
const finish = tool(
|
|
370
|
+
"finish",
|
|
371
|
+
"Submit the final answer and end the run",
|
|
372
|
+
z.object({ answer: z.string() }),
|
|
373
|
+
async ({ answer }) => ({ content: answer, endTurn: true }),
|
|
374
|
+
);
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
`endTurn` does not cancel the other tools of the same batch — they already
|
|
378
|
+
started concurrently, their `tool_result` blocks still enter the history, and
|
|
379
|
+
`onToolResult` hooks and trace events run for them as usual. Only the next
|
|
380
|
+
model call is skipped. When several tools in a batch set `endTurn`, the first
|
|
381
|
+
one's content becomes the result text.
|
|
382
|
+
|
|
337
383
|
## Concurrent Tool Calls
|
|
338
384
|
|
|
339
385
|
The model requests concurrency by returning multiple `tool_use` blocks in one
|
|
@@ -694,9 +740,16 @@ const mcp = await connectMCPStreamableHTTPServer("https://mcp.example.com/mcp",
|
|
|
694
740
|
type AgentLike<TContext = unknown> = {
|
|
695
741
|
query(prompt, options?): AsyncGenerator<SDKMessage | TeamRunnerMessage>;
|
|
696
742
|
prompt(prompt, options?): Promise<SDKResultMessage>;
|
|
743
|
+
interrupt(): boolean;
|
|
697
744
|
};
|
|
698
745
|
```
|
|
699
746
|
|
|
747
|
+
`interrupt()` ends the in-flight model request with an `"interrupted"` result
|
|
748
|
+
(see [Interrupting A Query](#interrupting-a-query)); on a `Team` or
|
|
749
|
+
`TeamRunner` it delegates to the lead/root agent. It returns `true` when a
|
|
750
|
+
query was interrupted and `false` when idle. *Requires 0.16.0 or later; the
|
|
751
|
+
`boolean` return requires 0.17.0 or later.*
|
|
752
|
+
|
|
700
753
|
That means a team can be used anywhere a callable agent is expected. From the
|
|
701
754
|
outside, a team is an agent; inside, it can contain a whole organization.
|
|
702
755
|
|
|
@@ -1074,8 +1127,8 @@ console.log(result.result);
|
|
|
1074
1127
|
```
|
|
1075
1128
|
|
|
1076
1129
|
The SDK stores conversation state in memory for the lifetime of the `Agent`
|
|
1077
|
-
instance.
|
|
1078
|
-
|
|
1130
|
+
instance. To persist it or resume a conversation in another process, attach a
|
|
1131
|
+
`HistoryStore` — see [Persistent History And Resume](#persistent-history-and-resume).
|
|
1079
1132
|
|
|
1080
1133
|
An `Agent` is a conversation, not a reusable client. Because the history is
|
|
1081
1134
|
instance state, starting a query while another is still running would interleave
|
|
@@ -1084,6 +1137,88 @@ Create one Agent per concurrent conversation — in a server, per request or per
|
|
|
1084
1137
|
user session rather than a shared module-level instance. Sequential reuse, as
|
|
1085
1138
|
above, is the intended pattern.
|
|
1086
1139
|
|
|
1140
|
+
## Persistent History And Resume
|
|
1141
|
+
|
|
1142
|
+
*Requires 0.16.0 or later.*
|
|
1143
|
+
|
|
1144
|
+
Pass a `HistoryStore` to seed an Agent's history from durable storage and have
|
|
1145
|
+
every later write mirrored back. `createJsonlHistoryStore()` persists one JSON
|
|
1146
|
+
message per line:
|
|
1147
|
+
|
|
1148
|
+
```ts
|
|
1149
|
+
import { createAgent, createJsonlHistoryStore } from "agent-lattice";
|
|
1150
|
+
|
|
1151
|
+
const historyStore = createJsonlHistoryStore({
|
|
1152
|
+
path: ".agent-sessions/ada.jsonl",
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
const agent = createAgent({
|
|
1156
|
+
apiKey: process.env.DEEPSEEK_API_KEY,
|
|
1157
|
+
baseURL: "https://api.deepseek.com/anthropic",
|
|
1158
|
+
model: "deepseek-v4-flash",
|
|
1159
|
+
historyStore,
|
|
1160
|
+
});
|
|
1161
|
+
|
|
1162
|
+
// The first query lazily loads any history the store already holds, then the
|
|
1163
|
+
// new prompt continues from it. Every user, assistant, and tool_result message
|
|
1164
|
+
// is appended to the file as it lands.
|
|
1165
|
+
const result = await agent.prompt("What is my name?");
|
|
1166
|
+
|
|
1167
|
+
// A copy of the live history, safe to inspect or mutate.
|
|
1168
|
+
const transcript = await agent.getHistory();
|
|
1169
|
+
```
|
|
1170
|
+
|
|
1171
|
+
The store contract is three methods — `load()`, `append(message)`, and
|
|
1172
|
+
`replace(messages)` — each synchronous or returning a promise:
|
|
1173
|
+
|
|
1174
|
+
- `load()` runs once per Agent lifetime, lazily before the first query (the
|
|
1175
|
+
constructor cannot be async). Resuming across processes is simply a new
|
|
1176
|
+
Agent over the same store; the "one Agent, one conversation" rule is
|
|
1177
|
+
unchanged.
|
|
1178
|
+
- `append(message)` follows every message added to the history.
|
|
1179
|
+
- `replace(messages)` follows compaction, which rewrites the whole history —
|
|
1180
|
+
a store must support full replacement, not just appends.
|
|
1181
|
+
|
|
1182
|
+
The JSONL store's `load()` skips malformed lines rather than failing, so a
|
|
1183
|
+
torn final write does not lose the rest of the transcript. By default a
|
|
1184
|
+
failing store is swallowed and the conversation continues in memory only,
|
|
1185
|
+
mirroring the tracer's failure semantics; bind `failOnError: true` when the
|
|
1186
|
+
store is created (via `createJsonlHistoryStore()` options or
|
|
1187
|
+
`defineHistoryStore()`) to propagate store errors out of `query()` instead.
|
|
1188
|
+
|
|
1189
|
+
Implement a custom store with `defineHistoryStore()`, which validates the
|
|
1190
|
+
three methods and binds `failOnError`; the returned port object exposes
|
|
1191
|
+
methods only. *Requires 0.17.0 or later.* (Breaking in 0.17.0: the public
|
|
1192
|
+
`failOnError` field was removed from `HistoryStore`; custom stores created
|
|
1193
|
+
before 0.17.0 must go through `defineHistoryStore()`.)
|
|
1194
|
+
|
|
1195
|
+
```ts
|
|
1196
|
+
import { defineHistoryStore } from "agent-lattice";
|
|
1197
|
+
|
|
1198
|
+
const historyStore = defineHistoryStore({
|
|
1199
|
+
load: () => loadMessagesFromYourDatabase(),
|
|
1200
|
+
append: message => appendMessageToYourDatabase(message),
|
|
1201
|
+
replace: messages => replaceMessagesInYourDatabase(messages),
|
|
1202
|
+
});
|
|
1203
|
+
```
|
|
1204
|
+
|
|
1205
|
+
To rewrite the history from the host instead of from compaction, use
|
|
1206
|
+
`agent.replaceHistory(messages)`. *Requires 0.17.0 or later.* It is idle-only:
|
|
1207
|
+
calling it while a query is running throws `ConcurrentQueryError`, the same
|
|
1208
|
+
guard as a concurrent `query()`. When a `historyStore` is configured the store
|
|
1209
|
+
is replaced too, so persistence stays in sync, and the replacement also
|
|
1210
|
+
suppresses the lazy `load()` — seeding never overwrites what the host just
|
|
1211
|
+
installed. The SDK does not validate the content: the host owns it, and the
|
|
1212
|
+
history must be well-formed (e.g. no dangling `tool_use` without its matching
|
|
1213
|
+
`tool_result`).
|
|
1214
|
+
|
|
1215
|
+
```ts
|
|
1216
|
+
await agent.replaceHistory([
|
|
1217
|
+
{ role: "user", content: "My name is Ada." },
|
|
1218
|
+
{ role: "assistant", content: [{ type: "text", text: "Nice to meet you, Ada." }] },
|
|
1219
|
+
]);
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1087
1222
|
## Deadlines
|
|
1088
1223
|
|
|
1089
1224
|
`QueryOptions.signal` bounds a whole query — every model request, tool call, and
|
|
@@ -1113,6 +1248,34 @@ Both limits are enforced by the SDK rather than delegated. `ModelRequest` carrie
|
|
|
1113
1248
|
also races the call, so a `ModelClient` that honours neither cannot stall the
|
|
1114
1249
|
loop indefinitely. Losing that race abandons the call rather than cancelling it.
|
|
1115
1250
|
|
|
1251
|
+
## Interrupting A Query
|
|
1252
|
+
|
|
1253
|
+
*Requires 0.16.0 or later; `interrupt()` returns `boolean` from 0.17.0.*
|
|
1254
|
+
|
|
1255
|
+
`agent.interrupt()` ends the current query without tearing the conversation
|
|
1256
|
+
down. Where `QueryOptions.signal` terminates the query with `"error_abort"`,
|
|
1257
|
+
`interrupt()` aborts only the in-flight model request and finishes with
|
|
1258
|
+
`subtype: "interrupted"` — normal control flow, so `is_error` stays `false`.
|
|
1259
|
+
As on abort, the partial assistant message is dropped, but every completed
|
|
1260
|
+
turn stays in the history, so the host can continue the same Agent with a new
|
|
1261
|
+
`query()` that injects its own message:
|
|
1262
|
+
|
|
1263
|
+
```ts
|
|
1264
|
+
const pending = agent.prompt("Draft the release notes.");
|
|
1265
|
+
agent.interrupt(); // e.g. the user typed a correction
|
|
1266
|
+
const result = await pending;
|
|
1267
|
+
// result.subtype === "interrupted"
|
|
1268
|
+
|
|
1269
|
+
await agent.prompt("Actually, skip 0.15.x and cover 0.16.0 only.");
|
|
1270
|
+
```
|
|
1271
|
+
|
|
1272
|
+
An interrupt that lands while a tool batch is executing takes effect once the
|
|
1273
|
+
batch completes: its tool results are written to history first, and the query
|
|
1274
|
+
ends `"interrupted"` before the next model call. `interrupt()` returns `true`
|
|
1275
|
+
when a query was running and is now interrupted, and `false` when idle — a
|
|
1276
|
+
`false` tells the host there is nothing to wait for, so it can send its next
|
|
1277
|
+
query directly.
|
|
1278
|
+
|
|
1116
1279
|
## Token Usage And Truncation
|
|
1117
1280
|
|
|
1118
1281
|
Every `result` message reports `usage`, summed over the model requests in that
|
|
@@ -1135,3 +1298,13 @@ to distinguish a complete answer from a truncated one.
|
|
|
1135
1298
|
Usage comes from the model client. The built-in Anthropic client fills it in from
|
|
1136
1299
|
the response, including the streaming path; a custom `ModelClient` that omits
|
|
1137
1300
|
`usage` produces zeroed counts rather than an error.
|
|
1301
|
+
|
|
1302
|
+
Assistant messages also carry provider response metadata: `providerResponseId`
|
|
1303
|
+
is the provider-assigned response id and `model` is the model that actually
|
|
1304
|
+
served the response, which may differ from the requested `AgentOptions.model`.
|
|
1305
|
+
The built-in Anthropic client fills both in on streaming and non-streaming
|
|
1306
|
+
requests; a custom `ModelClient` may set them on the `AssistantModelMessage` it
|
|
1307
|
+
returns. Both fields are optional and absent when the client does not report
|
|
1308
|
+
them.
|
|
1309
|
+
|
|
1310
|
+
*Requires 0.16.0 or later.*
|
package/dist/index.d.ts
CHANGED
|
@@ -34,6 +34,12 @@ export type AgentLikeEvent = SDKMessage | TeamRunnerMessage;
|
|
|
34
34
|
export type AgentLike<TContext = unknown> = {
|
|
35
35
|
query(prompt: string | ContentBlock[], options?: QueryOptions<TContext>): AsyncGenerator<AgentLikeEvent>;
|
|
36
36
|
prompt(prompt: string | ContentBlock[], options?: QueryOptions<TContext>): Promise<SDKResultMessage>;
|
|
37
|
+
/**
|
|
38
|
+
* End the in-flight model request with an "interrupted" result; follow up
|
|
39
|
+
* with a new query(). Returns `true` when a query was interrupted, `false`
|
|
40
|
+
* when idle — a `false` means the host can send its next query directly.
|
|
41
|
+
*/
|
|
42
|
+
interrupt(): boolean;
|
|
37
43
|
};
|
|
38
44
|
export type DelegateWaitMode = "result" | "accepted";
|
|
39
45
|
export type AgentRuntimeSource = {
|
|
@@ -115,7 +121,6 @@ export type ContextTraceEvent = {
|
|
|
115
121
|
data: Record<string, unknown>;
|
|
116
122
|
};
|
|
117
123
|
export type ContextTracer = {
|
|
118
|
-
failOnError?: boolean;
|
|
119
124
|
onEvent(event: ContextTraceEvent): Promise<void> | void;
|
|
120
125
|
flush?(): Promise<void>;
|
|
121
126
|
close?(): Promise<void>;
|
|
@@ -133,7 +138,9 @@ export type LangSmithRunTreeLike = RunTree;
|
|
|
133
138
|
export type LangSmithRunTreeConstructor = new (config: LangSmithRunTreeConfig) => LangSmithRunTreeLike;
|
|
134
139
|
export type LangSmithWriteReplicaConfig = NonNullable<LangSmithRunTreeConfig["replicas"]>[number];
|
|
135
140
|
export type LangSmithContextTracerOptions = {
|
|
141
|
+
/** Defaults to the bundled langsmith RunTree; inject a constructor for custom runtimes. */
|
|
136
142
|
RunTree?: LangSmithRunTreeConstructor;
|
|
143
|
+
/** Factory form of RunTree, mainly for tests. Takes precedence over RunTree. */
|
|
137
144
|
runTree?: (config: LangSmithRunTreeConfig) => LangSmithRunTreeLike;
|
|
138
145
|
projectName?: string;
|
|
139
146
|
name?: string;
|
|
@@ -150,6 +157,33 @@ export type ModelMessage = {
|
|
|
150
157
|
role: "user" | "assistant";
|
|
151
158
|
content: string | ContentBlock[];
|
|
152
159
|
};
|
|
160
|
+
/**
|
|
161
|
+
* Persistence adapter for an Agent's conversation history. `load()` runs once
|
|
162
|
+
* per Agent lifetime, before the first query; `append()` follows every message
|
|
163
|
+
* added to the history; `replace()` follows compaction, which rewrites the
|
|
164
|
+
* whole history — a store must support full replacement. Methods may be
|
|
165
|
+
* synchronous or return a promise; the Agent awaits them to preserve order.
|
|
166
|
+
* Like `ContextTracer`, a failing store is swallowed by default and the
|
|
167
|
+
* conversation continues in memory only; pass `failOnError` to the factory
|
|
168
|
+
* that creates the store (`createJsonlHistoryStore`, `defineHistoryStore`)
|
|
169
|
+
* to propagate store errors out of `query()` instead.
|
|
170
|
+
*
|
|
171
|
+
* The objects passed to `append()` and `replace()` are guaranteed to carry at
|
|
172
|
+
* least `role` and `content`. Runtime objects may carry extra fields (`usage`,
|
|
173
|
+
* `stopReason`, `providerResponseId`, `model`) that are not part of the
|
|
174
|
+
* contract and must not be relied on; hosts that need response metadata for
|
|
175
|
+
* reconciliation or analytics should use the ContextTracer's
|
|
176
|
+
* `assistant_message` events instead.
|
|
177
|
+
*/
|
|
178
|
+
export type HistoryStore = {
|
|
179
|
+
load(): ModelMessage[] | Promise<ModelMessage[]>;
|
|
180
|
+
append(message: ModelMessage): void | Promise<void>;
|
|
181
|
+
replace(messages: ModelMessage[]): void | Promise<void>;
|
|
182
|
+
};
|
|
183
|
+
export type JsonlHistoryStoreOptions = {
|
|
184
|
+
path: string;
|
|
185
|
+
failOnError?: boolean;
|
|
186
|
+
};
|
|
153
187
|
export type TokenUsage = {
|
|
154
188
|
input_tokens: number;
|
|
155
189
|
output_tokens: number;
|
|
@@ -171,6 +205,13 @@ export type AssistantModelMessage = {
|
|
|
171
205
|
/** Absent when a custom ModelClient does not report it. */
|
|
172
206
|
usage?: TokenUsage;
|
|
173
207
|
stopReason?: StopReason;
|
|
208
|
+
/** The provider-assigned response id. Absent when a custom ModelClient does not report it. */
|
|
209
|
+
providerResponseId?: string;
|
|
210
|
+
/**
|
|
211
|
+
* The model that actually served this response, which may differ from
|
|
212
|
+
* `ModelRequest.model`. Absent when a custom ModelClient does not report it.
|
|
213
|
+
*/
|
|
214
|
+
model?: string;
|
|
174
215
|
};
|
|
175
216
|
export type ModelToolDefinition = {
|
|
176
217
|
name: string;
|
|
@@ -197,6 +238,8 @@ export interface ModelClient {
|
|
|
197
238
|
}
|
|
198
239
|
export type ToolResult = {
|
|
199
240
|
content: string | ContentBlock[];
|
|
241
|
+
/** End the run after this tool batch: finish with subtype "success" instead of calling the model again. */
|
|
242
|
+
endTurn?: boolean;
|
|
200
243
|
};
|
|
201
244
|
export type ToolKind = "tool" | "agent_tool";
|
|
202
245
|
export type ToolBatchCall = {
|
|
@@ -458,6 +501,8 @@ export type Team = {
|
|
|
458
501
|
drain(options?: TeamDrainOptions): Promise<TeamDrainResult>;
|
|
459
502
|
query(prompt: string | ContentBlock[], options?: QueryOptions): AsyncGenerator<TeamRunnerMessage>;
|
|
460
503
|
prompt(prompt: string | ContentBlock[], options?: QueryOptions): Promise<SDKResultMessage>;
|
|
504
|
+
/** Interrupts the lead agent's in-flight model request; returns `true` when a query was interrupted, `false` when idle. */
|
|
505
|
+
interrupt(): boolean;
|
|
461
506
|
};
|
|
462
507
|
export type TeamDrainOptions = {
|
|
463
508
|
maxRounds?: number;
|
|
@@ -480,6 +525,8 @@ export type TeamRunner = {
|
|
|
480
525
|
mailbox: TeamMailbox;
|
|
481
526
|
query(prompt: string | ContentBlock[], options?: QueryOptions): AsyncGenerator<TeamRunnerMessage>;
|
|
482
527
|
prompt(prompt: string | ContentBlock[], options?: QueryOptions): Promise<SDKResultMessage>;
|
|
528
|
+
/** Interrupts the root agent's in-flight model request; returns `true` when a query was interrupted, `false` when idle. */
|
|
529
|
+
interrupt(): boolean;
|
|
483
530
|
};
|
|
484
531
|
export type PermissionRequest = {
|
|
485
532
|
toolName: string;
|
|
@@ -524,6 +571,12 @@ export type AgentOptions<TContext = unknown> = {
|
|
|
524
571
|
permission?: (request: PermissionRequest) => Promise<PermissionDecision> | PermissionDecision;
|
|
525
572
|
modelClient?: ModelClient;
|
|
526
573
|
tracer?: ContextTracer;
|
|
574
|
+
/**
|
|
575
|
+
* Persistence adapter for the conversation history. Seeded via `load()` once
|
|
576
|
+
* before the first query, then notified on every history write. Compaction
|
|
577
|
+
* calls `replace()`, so the store must support full replacement.
|
|
578
|
+
*/
|
|
579
|
+
historyStore?: HistoryStore;
|
|
527
580
|
};
|
|
528
581
|
export type BareAgentOptions<TContext = unknown> = Omit<AgentOptions<TContext>, "workspace">;
|
|
529
582
|
export type AgentWorkspaceToolsOptions = {
|
|
@@ -579,6 +632,14 @@ export type SDKAssistantMessage = {
|
|
|
579
632
|
message: AssistantModelMessage;
|
|
580
633
|
session_id: string;
|
|
581
634
|
};
|
|
635
|
+
/**
|
|
636
|
+
* Emitted only after a whole tool batch finishes — one event per batch, never
|
|
637
|
+
* one per tool, and never for the prompt (the prompt is not echoed; subscribe
|
|
638
|
+
* a `ContextTracer` for a full transcript). `message.content` is always
|
|
639
|
+
* `ToolResultBlock[]`; the declared `ModelMessage` type is wider than this
|
|
640
|
+
* guarantee. `tool_use_result` is a convenience view: a single tool's result
|
|
641
|
+
* `content`, or the array of result blocks when the batch had several tools.
|
|
642
|
+
*/
|
|
582
643
|
export type SDKUserMessage = {
|
|
583
644
|
type: "user";
|
|
584
645
|
message: ModelMessage;
|
|
@@ -593,7 +654,12 @@ export type SDKStreamEventMessage = {
|
|
|
593
654
|
};
|
|
594
655
|
export type SDKResultMessage = {
|
|
595
656
|
type: "result";
|
|
596
|
-
|
|
657
|
+
/**
|
|
658
|
+
* `"interrupted"` is not an error: `Agent.interrupt()` ends the query this
|
|
659
|
+
* way, keeping completed turns in history so a follow-up query can continue
|
|
660
|
+
* the conversation. `is_error` stays `false` for it.
|
|
661
|
+
*/
|
|
662
|
+
subtype: "success" | "interrupted" | "error" | "error_max_turns" | "error_abort" | "error_timeout";
|
|
597
663
|
is_error: boolean;
|
|
598
664
|
result: string;
|
|
599
665
|
session_id: string;
|
|
@@ -720,6 +786,15 @@ export type AgentSpec<TContext = unknown> = {
|
|
|
720
786
|
export declare function defineAgent<TContext = unknown>(options: AgentOptions<TContext>): AgentSpec<TContext>;
|
|
721
787
|
export declare function isAgentSpec(target: AgentLike<any> | AgentSpec<any>): target is AgentSpec<any>;
|
|
722
788
|
export declare function createBuiltinTools(options?: AgentWorkspaceToolsOptions): Array<ToolDefinition<any, any>>;
|
|
789
|
+
/**
|
|
790
|
+
* Entry point for implementing a custom trace sink. Validates that the
|
|
791
|
+
* required `onEvent` method exists and binds `failOnError` at creation time —
|
|
792
|
+
* a `ContextTracer` exposes methods only; the flag travels with the returned
|
|
793
|
+
* object as internal metadata the runtime reads when a call throws.
|
|
794
|
+
*/
|
|
795
|
+
export declare function defineContextTracer(impl: ContextTracer & {
|
|
796
|
+
failOnError?: boolean;
|
|
797
|
+
}): ContextTracer;
|
|
723
798
|
export declare function createJsonlContextTracer(options: JsonlContextTracerOptions): ContextTracer;
|
|
724
799
|
/**
|
|
725
800
|
* Chains hooks in array order: each one sees the previous one's output, so
|
|
@@ -728,12 +803,31 @@ export declare function createJsonlContextTracer(options: JsonlContextTracerOpti
|
|
|
728
803
|
*/
|
|
729
804
|
export declare function createCompositeAgentHooks<TContext = unknown>(hooks: Array<AgentHooks<TContext> | undefined | null>): AgentHooks<TContext>;
|
|
730
805
|
export declare function createCompositeContextTracer(tracers: Array<ContextTracer | undefined | null>): ContextTracer;
|
|
731
|
-
export declare function createLangSmithContextTracer(options
|
|
806
|
+
export declare function createLangSmithContextTracer(options?: LangSmithContextTracerOptions): ContextTracer;
|
|
732
807
|
export declare function skill(input: SkillInput): SkillDefinition;
|
|
733
808
|
export declare function loadSkill(path: string): Promise<SkillDefinition>;
|
|
734
809
|
export declare function createMCPTools(client: MCPClient, options?: MCPToolsOptions): Promise<Array<ToolDefinition<Record<string, unknown>>>>;
|
|
735
810
|
export declare function connectMCPStdioServer(server: StdioServerParameters, options?: MCPStdioServerOptions): Promise<MCPStdioConnection>;
|
|
736
811
|
export declare function connectMCPStreamableHTTPServer(url: string | URL, options?: MCPStreamableHTTPServerOptions): Promise<MCPStreamableHTTPConnection>;
|
|
812
|
+
/**
|
|
813
|
+
* Persists an Agent's history as one JSON message per line. `append()` adds a
|
|
814
|
+
* line; `replace()` rewrites the whole file, which is how compaction is
|
|
815
|
+
* persisted. `load()` reads every line and skips malformed ones — a truncated
|
|
816
|
+
* final line from a torn write must not lose the rest of the transcript.
|
|
817
|
+
* Writes are serialized through an internal queue, so callers may fire them
|
|
818
|
+
* without waiting for ordering.
|
|
819
|
+
*/
|
|
820
|
+
/**
|
|
821
|
+
* Entry point for implementing a custom history store. Validates that the
|
|
822
|
+
* required `load`/`append`/`replace` methods exist and binds `failOnError` at
|
|
823
|
+
* creation time — a `HistoryStore` exposes methods only; the flag travels
|
|
824
|
+
* with the returned object as internal metadata the runtime reads when a call
|
|
825
|
+
* throws.
|
|
826
|
+
*/
|
|
827
|
+
export declare function defineHistoryStore(impl: HistoryStore & {
|
|
828
|
+
failOnError?: boolean;
|
|
829
|
+
}): HistoryStore;
|
|
830
|
+
export declare function createJsonlHistoryStore(options: JsonlHistoryStoreOptions): HistoryStore;
|
|
737
831
|
export declare function teamMember(input: TeamMemberInput): TeamMemberDefinition;
|
|
738
832
|
export declare function createMemoryMailbox(): TeamMailbox;
|
|
739
833
|
export declare function createSQLiteMailbox(options: SQLiteMailboxOptions): TeamMailbox;
|
|
@@ -749,13 +843,21 @@ export declare function query<TContext = unknown>(params: AgentOptions<TContext>
|
|
|
749
843
|
signal?: AbortSignal;
|
|
750
844
|
context?: TContext;
|
|
751
845
|
}): AsyncGenerator<SDKMessage>;
|
|
752
|
-
|
|
846
|
+
/**
|
|
847
|
+
* An Agent owns one conversation: history, workspace, and session identity.
|
|
848
|
+
* Create instances with `createAgent()` or `createBareAgent()` (or spawn from
|
|
849
|
+
* an `AgentSpec`) — the constructor is intentionally not exported, because the
|
|
850
|
+
* factories also generate the session id and install workspace tools.
|
|
851
|
+
*/
|
|
852
|
+
declare class Agent<TContext = unknown> {
|
|
753
853
|
private readonly options;
|
|
754
854
|
private readonly modelClient;
|
|
755
855
|
private readonly messages;
|
|
756
856
|
private readonly sessionId;
|
|
757
857
|
private readonly toolConcurrency;
|
|
758
858
|
private running;
|
|
859
|
+
private interruptController;
|
|
860
|
+
private historyLoaded;
|
|
759
861
|
constructor(options: AgentOptions<TContext>);
|
|
760
862
|
/**
|
|
761
863
|
* One Agent owns one conversation. Overlapping queries would interleave writes
|
|
@@ -763,8 +865,45 @@ export declare class Agent<TContext = unknown> {
|
|
|
763
865
|
* a conversation containing someone else's turns.
|
|
764
866
|
*/
|
|
765
867
|
query(prompt: string | ContentBlock[], options?: QueryOptions<TContext>): AsyncGenerator<SDKMessage>;
|
|
868
|
+
/**
|
|
869
|
+
* Abort the in-flight model request and end the current query with subtype
|
|
870
|
+
* "interrupted". Completed turns stay in history; follow up with a new
|
|
871
|
+
* query() to continue the conversation. Unlike `QueryOptions.signal`, which
|
|
872
|
+
* terminates the query as an error, an interrupt is normal control flow.
|
|
873
|
+
* Returns `true` when a query was running and is now interrupted, `false`
|
|
874
|
+
* when idle — a `false` tells the host it can send its next query directly
|
|
875
|
+
* instead of waiting for an "interrupted" result.
|
|
876
|
+
*/
|
|
877
|
+
interrupt(): boolean;
|
|
878
|
+
/**
|
|
879
|
+
* The store is read once per Agent lifetime, lazily on the first query or
|
|
880
|
+
* getHistory() call — the constructor cannot be async. A failed load follows
|
|
881
|
+
* the same rule as a failed write: swallowed unless `failOnError` was bound
|
|
882
|
+
* by the store's factory, in which case the error propagates and the Agent
|
|
883
|
+
* starts empty.
|
|
884
|
+
*/
|
|
885
|
+
private ensureHistoryLoaded;
|
|
886
|
+
private loadHistory;
|
|
887
|
+
private appendStoredHistory;
|
|
888
|
+
private replaceStoredHistory;
|
|
766
889
|
private runQuery;
|
|
767
890
|
prompt(prompt: string | ContentBlock[], options?: QueryOptions<TContext>): Promise<SDKResultMessage>;
|
|
891
|
+
/**
|
|
892
|
+
* The conversation history as currently held by this Agent, including any
|
|
893
|
+
* messages seeded from `AgentOptions.historyStore`. Returns a deep copy, so
|
|
894
|
+
* mutating the result cannot corrupt the live conversation.
|
|
895
|
+
*/
|
|
896
|
+
getHistory(): Promise<ModelMessage[]>;
|
|
897
|
+
/**
|
|
898
|
+
* Replace the conversation history. Idle only: throws ConcurrentQueryError
|
|
899
|
+
* while a query is running. When a historyStore is configured the store is
|
|
900
|
+
* replaced too, so persistence stays in sync.
|
|
901
|
+
*
|
|
902
|
+
* The host owns the content: the SDK does not validate the messages, so the
|
|
903
|
+
* replacement must be a well-formed history — e.g. no dangling `tool_use`
|
|
904
|
+
* without its matching `tool_result`.
|
|
905
|
+
*/
|
|
906
|
+
replaceHistory(messages: ModelMessage[]): Promise<void>;
|
|
768
907
|
addTools(tools: Array<ToolDefinition<any, TContext>>): void;
|
|
769
908
|
private initMessage;
|
|
770
909
|
private resultMessage;
|
|
@@ -789,7 +928,7 @@ export declare class Agent<TContext = unknown> {
|
|
|
789
928
|
private executeToolBatch;
|
|
790
929
|
private isToolCallConcurrencySafe;
|
|
791
930
|
}
|
|
931
|
+
export type { Agent };
|
|
792
932
|
type InferInput<TSchema> = TSchema extends {
|
|
793
933
|
parse(input: unknown): infer TInput;
|
|
794
934
|
} ? TInput : Record<string, unknown>;
|
|
795
|
-
export {};
|