agent-lattice 0.16.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 +66 -18
- package/dist/index.d.ts +67 -17
- 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
|
|
|
@@ -221,9 +226,9 @@ for await (const event of team.query("Ask engineering to investigate.", {
|
|
|
221
226
|
|
|
222
227
|
## LangSmith Context Tracing
|
|
223
228
|
|
|
224
|
-
|
|
225
|
-
`
|
|
226
|
-
|
|
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.
|
|
227
232
|
|
|
228
233
|
Configure LangSmith with its standard environment variables:
|
|
229
234
|
|
|
@@ -237,7 +242,6 @@ LANGSMITH_WORKSPACE_ID=<your-langsmith-workspace-id>
|
|
|
237
242
|
```
|
|
238
243
|
|
|
239
244
|
```ts
|
|
240
|
-
import { RunTree } from "langsmith/run_trees";
|
|
241
245
|
import {
|
|
242
246
|
createAgent,
|
|
243
247
|
createCompositeContextTracer,
|
|
@@ -248,7 +252,6 @@ import {
|
|
|
248
252
|
const tracer = createCompositeContextTracer([
|
|
249
253
|
createJsonlContextTracer({ path: ".agent-runs/session.jsonl" }),
|
|
250
254
|
createLangSmithContextTracer({
|
|
251
|
-
RunTree,
|
|
252
255
|
projectName: process.env.LANGSMITH_PROJECT,
|
|
253
256
|
workspaceId: process.env.LANGSMITH_WORKSPACE_ID,
|
|
254
257
|
tags: ["local-debug"],
|
|
@@ -277,11 +280,9 @@ tracer. `workspaceId` is optional and only selects a LangSmith workspace; it is
|
|
|
277
280
|
not the tracing project name.
|
|
278
281
|
|
|
279
282
|
```ts
|
|
280
|
-
import { RunTree } from "langsmith/run_trees";
|
|
281
283
|
import { createLangSmithContextTracer } from "agent-lattice";
|
|
282
284
|
|
|
283
285
|
const tracer = createLangSmithContextTracer({
|
|
284
|
-
RunTree,
|
|
285
286
|
apiKey: process.env.LANGSMITH_API_KEY,
|
|
286
287
|
apiUrl: process.env.LANGSMITH_ENDPOINT,
|
|
287
288
|
projectName: process.env.LANGSMITH_PROJECT,
|
|
@@ -290,6 +291,9 @@ const tracer = createLangSmithContextTracer({
|
|
|
290
291
|
});
|
|
291
292
|
```
|
|
292
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
|
+
|
|
293
297
|
LangSmith receives one root `chain` run per SDK query. For an `Agent` query,
|
|
294
298
|
model turns and SDK tool calls appear as child `llm` and `tool` runs. For a
|
|
295
299
|
`Team` query, the root represents the complete Team invocation; the initial
|
|
@@ -299,15 +303,21 @@ recorded as `agent_session_id` metadata, so tracing does not change Agent state
|
|
|
299
303
|
or returned SDK messages.
|
|
300
304
|
|
|
301
305
|
Custom sinks can implement the same interface for SQLite, OpenTelemetry, object
|
|
302
|
-
storage, or host-specific observability.
|
|
303
|
-
|
|
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()`.)
|
|
304
312
|
|
|
305
313
|
```ts
|
|
306
|
-
|
|
314
|
+
import { defineContextTracer } from "agent-lattice";
|
|
315
|
+
|
|
316
|
+
const tracer = defineContextTracer({
|
|
307
317
|
async onEvent(event) {
|
|
308
318
|
// TODO: Replace with your own storage/logging code.
|
|
309
319
|
},
|
|
310
|
-
};
|
|
320
|
+
});
|
|
311
321
|
```
|
|
312
322
|
|
|
313
323
|
## DeepSeek Anthropic-compatible API
|
|
@@ -730,13 +740,15 @@ const mcp = await connectMCPStreamableHTTPServer("https://mcp.example.com/mcp",
|
|
|
730
740
|
type AgentLike<TContext = unknown> = {
|
|
731
741
|
query(prompt, options?): AsyncGenerator<SDKMessage | TeamRunnerMessage>;
|
|
732
742
|
prompt(prompt, options?): Promise<SDKResultMessage>;
|
|
733
|
-
interrupt():
|
|
743
|
+
interrupt(): boolean;
|
|
734
744
|
};
|
|
735
745
|
```
|
|
736
746
|
|
|
737
747
|
`interrupt()` ends the in-flight model request with an `"interrupted"` result
|
|
738
748
|
(see [Interrupting A Query](#interrupting-a-query)); on a `Team` or
|
|
739
|
-
`TeamRunner` it delegates to the lead/root agent.
|
|
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.*
|
|
740
752
|
|
|
741
753
|
That means a team can be used anywhere a callable agent is expected. From the
|
|
742
754
|
outside, a team is an agent; inside, it can contain a whole organization.
|
|
@@ -1170,8 +1182,42 @@ The store contract is three methods — `load()`, `append(message)`, and
|
|
|
1170
1182
|
The JSONL store's `load()` skips malformed lines rather than failing, so a
|
|
1171
1183
|
torn final write does not lose the rest of the transcript. By default a
|
|
1172
1184
|
failing store is swallowed and the conversation continues in memory only,
|
|
1173
|
-
mirroring the tracer's failure semantics;
|
|
1174
|
-
|
|
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
|
+
```
|
|
1175
1221
|
|
|
1176
1222
|
## Deadlines
|
|
1177
1223
|
|
|
@@ -1204,7 +1250,7 @@ loop indefinitely. Losing that race abandons the call rather than cancelling it.
|
|
|
1204
1250
|
|
|
1205
1251
|
## Interrupting A Query
|
|
1206
1252
|
|
|
1207
|
-
*Requires 0.16.0 or later.*
|
|
1253
|
+
*Requires 0.16.0 or later; `interrupt()` returns `boolean` from 0.17.0.*
|
|
1208
1254
|
|
|
1209
1255
|
`agent.interrupt()` ends the current query without tearing the conversation
|
|
1210
1256
|
down. Where `QueryOptions.signal` terminates the query with `"error_abort"`,
|
|
@@ -1225,8 +1271,10 @@ await agent.prompt("Actually, skip 0.15.x and cover 0.16.0 only.");
|
|
|
1225
1271
|
|
|
1226
1272
|
An interrupt that lands while a tool batch is executing takes effect once the
|
|
1227
1273
|
batch completes: its tool results are written to history first, and the query
|
|
1228
|
-
ends `"interrupted"` before the next model call. `interrupt()`
|
|
1229
|
-
|
|
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.
|
|
1230
1278
|
|
|
1231
1279
|
## Token Usage And Truncation
|
|
1232
1280
|
|
package/dist/index.d.ts
CHANGED
|
@@ -34,8 +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
|
-
|
|
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;
|
|
39
43
|
};
|
|
40
44
|
export type DelegateWaitMode = "result" | "accepted";
|
|
41
45
|
export type AgentRuntimeSource = {
|
|
@@ -117,7 +121,6 @@ export type ContextTraceEvent = {
|
|
|
117
121
|
data: Record<string, unknown>;
|
|
118
122
|
};
|
|
119
123
|
export type ContextTracer = {
|
|
120
|
-
failOnError?: boolean;
|
|
121
124
|
onEvent(event: ContextTraceEvent): Promise<void> | void;
|
|
122
125
|
flush?(): Promise<void>;
|
|
123
126
|
close?(): Promise<void>;
|
|
@@ -135,7 +138,9 @@ export type LangSmithRunTreeLike = RunTree;
|
|
|
135
138
|
export type LangSmithRunTreeConstructor = new (config: LangSmithRunTreeConfig) => LangSmithRunTreeLike;
|
|
136
139
|
export type LangSmithWriteReplicaConfig = NonNullable<LangSmithRunTreeConfig["replicas"]>[number];
|
|
137
140
|
export type LangSmithContextTracerOptions = {
|
|
141
|
+
/** Defaults to the bundled langsmith RunTree; inject a constructor for custom runtimes. */
|
|
138
142
|
RunTree?: LangSmithRunTreeConstructor;
|
|
143
|
+
/** Factory form of RunTree, mainly for tests. Takes precedence over RunTree. */
|
|
139
144
|
runTree?: (config: LangSmithRunTreeConfig) => LangSmithRunTreeLike;
|
|
140
145
|
projectName?: string;
|
|
141
146
|
name?: string;
|
|
@@ -159,11 +164,18 @@ export type ModelMessage = {
|
|
|
159
164
|
* whole history — a store must support full replacement. Methods may be
|
|
160
165
|
* synchronous or return a promise; the Agent awaits them to preserve order.
|
|
161
166
|
* Like `ContextTracer`, a failing store is swallowed by default and the
|
|
162
|
-
* conversation continues in memory only;
|
|
163
|
-
*
|
|
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.
|
|
164
177
|
*/
|
|
165
178
|
export type HistoryStore = {
|
|
166
|
-
failOnError?: boolean;
|
|
167
179
|
load(): ModelMessage[] | Promise<ModelMessage[]>;
|
|
168
180
|
append(message: ModelMessage): void | Promise<void>;
|
|
169
181
|
replace(messages: ModelMessage[]): void | Promise<void>;
|
|
@@ -489,8 +501,8 @@ export type Team = {
|
|
|
489
501
|
drain(options?: TeamDrainOptions): Promise<TeamDrainResult>;
|
|
490
502
|
query(prompt: string | ContentBlock[], options?: QueryOptions): AsyncGenerator<TeamRunnerMessage>;
|
|
491
503
|
prompt(prompt: string | ContentBlock[], options?: QueryOptions): Promise<SDKResultMessage>;
|
|
492
|
-
/** Interrupts the lead agent's in-flight model request. */
|
|
493
|
-
interrupt():
|
|
504
|
+
/** Interrupts the lead agent's in-flight model request; returns `true` when a query was interrupted, `false` when idle. */
|
|
505
|
+
interrupt(): boolean;
|
|
494
506
|
};
|
|
495
507
|
export type TeamDrainOptions = {
|
|
496
508
|
maxRounds?: number;
|
|
@@ -513,8 +525,8 @@ export type TeamRunner = {
|
|
|
513
525
|
mailbox: TeamMailbox;
|
|
514
526
|
query(prompt: string | ContentBlock[], options?: QueryOptions): AsyncGenerator<TeamRunnerMessage>;
|
|
515
527
|
prompt(prompt: string | ContentBlock[], options?: QueryOptions): Promise<SDKResultMessage>;
|
|
516
|
-
/** Interrupts the root agent's in-flight model request. */
|
|
517
|
-
interrupt():
|
|
528
|
+
/** Interrupts the root agent's in-flight model request; returns `true` when a query was interrupted, `false` when idle. */
|
|
529
|
+
interrupt(): boolean;
|
|
518
530
|
};
|
|
519
531
|
export type PermissionRequest = {
|
|
520
532
|
toolName: string;
|
|
@@ -774,6 +786,15 @@ export type AgentSpec<TContext = unknown> = {
|
|
|
774
786
|
export declare function defineAgent<TContext = unknown>(options: AgentOptions<TContext>): AgentSpec<TContext>;
|
|
775
787
|
export declare function isAgentSpec(target: AgentLike<any> | AgentSpec<any>): target is AgentSpec<any>;
|
|
776
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;
|
|
777
798
|
export declare function createJsonlContextTracer(options: JsonlContextTracerOptions): ContextTracer;
|
|
778
799
|
/**
|
|
779
800
|
* Chains hooks in array order: each one sees the previous one's output, so
|
|
@@ -782,7 +803,7 @@ export declare function createJsonlContextTracer(options: JsonlContextTracerOpti
|
|
|
782
803
|
*/
|
|
783
804
|
export declare function createCompositeAgentHooks<TContext = unknown>(hooks: Array<AgentHooks<TContext> | undefined | null>): AgentHooks<TContext>;
|
|
784
805
|
export declare function createCompositeContextTracer(tracers: Array<ContextTracer | undefined | null>): ContextTracer;
|
|
785
|
-
export declare function createLangSmithContextTracer(options
|
|
806
|
+
export declare function createLangSmithContextTracer(options?: LangSmithContextTracerOptions): ContextTracer;
|
|
786
807
|
export declare function skill(input: SkillInput): SkillDefinition;
|
|
787
808
|
export declare function loadSkill(path: string): Promise<SkillDefinition>;
|
|
788
809
|
export declare function createMCPTools(client: MCPClient, options?: MCPToolsOptions): Promise<Array<ToolDefinition<Record<string, unknown>>>>;
|
|
@@ -796,6 +817,16 @@ export declare function connectMCPStreamableHTTPServer(url: string | URL, option
|
|
|
796
817
|
* Writes are serialized through an internal queue, so callers may fire them
|
|
797
818
|
* without waiting for ordering.
|
|
798
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;
|
|
799
830
|
export declare function createJsonlHistoryStore(options: JsonlHistoryStoreOptions): HistoryStore;
|
|
800
831
|
export declare function teamMember(input: TeamMemberInput): TeamMemberDefinition;
|
|
801
832
|
export declare function createMemoryMailbox(): TeamMailbox;
|
|
@@ -812,7 +843,13 @@ export declare function query<TContext = unknown>(params: AgentOptions<TContext>
|
|
|
812
843
|
signal?: AbortSignal;
|
|
813
844
|
context?: TContext;
|
|
814
845
|
}): AsyncGenerator<SDKMessage>;
|
|
815
|
-
|
|
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> {
|
|
816
853
|
private readonly options;
|
|
817
854
|
private readonly modelClient;
|
|
818
855
|
private readonly messages;
|
|
@@ -833,14 +870,17 @@ export declare class Agent<TContext = unknown> {
|
|
|
833
870
|
* "interrupted". Completed turns stay in history; follow up with a new
|
|
834
871
|
* query() to continue the conversation. Unlike `QueryOptions.signal`, which
|
|
835
872
|
* terminates the query as an error, an interrupt is normal control flow.
|
|
836
|
-
*
|
|
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.
|
|
837
876
|
*/
|
|
838
|
-
interrupt():
|
|
877
|
+
interrupt(): boolean;
|
|
839
878
|
/**
|
|
840
879
|
* The store is read once per Agent lifetime, lazily on the first query or
|
|
841
880
|
* getHistory() call — the constructor cannot be async. A failed load follows
|
|
842
|
-
* the same rule as a failed write: swallowed unless `failOnError`
|
|
843
|
-
* which case the error propagates and the Agent
|
|
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.
|
|
844
884
|
*/
|
|
845
885
|
private ensureHistoryLoaded;
|
|
846
886
|
private loadHistory;
|
|
@@ -854,6 +894,16 @@ export declare class Agent<TContext = unknown> {
|
|
|
854
894
|
* mutating the result cannot corrupt the live conversation.
|
|
855
895
|
*/
|
|
856
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>;
|
|
857
907
|
addTools(tools: Array<ToolDefinition<any, TContext>>): void;
|
|
858
908
|
private initMessage;
|
|
859
909
|
private resultMessage;
|
|
@@ -878,7 +928,7 @@ export declare class Agent<TContext = unknown> {
|
|
|
878
928
|
private executeToolBatch;
|
|
879
929
|
private isToolCallConcurrencySafe;
|
|
880
930
|
}
|
|
931
|
+
export type { Agent };
|
|
881
932
|
type InferInput<TSchema> = TSchema extends {
|
|
882
933
|
parse(input: unknown): infer TInput;
|
|
883
934
|
} ? TInput : Record<string, unknown>;
|
|
884
|
-
export {};
|