agent-lattice 0.9.23 → 0.9.24

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 CHANGED
@@ -283,6 +283,47 @@ const result = await agent.prompt("What is 2+2?");
283
283
  console.log(result.result);
284
284
  ```
285
285
 
286
+ ## Tool Batch Policy
287
+
288
+ Use `toolBatchPolicy` when some tools must not run in the same model response.
289
+ The policy sees the complete batch before any tool executes. If it rejects the
290
+ batch, no tool runs and every tool call receives a structured `is_error: true`
291
+ result.
292
+
293
+ ```ts
294
+ const lead = createAgent({
295
+ model: "claude-sonnet-4-6",
296
+ tools: [incrementRevision],
297
+ toolBatchPolicy: {
298
+ validate({ toolCalls }) {
299
+ const incrementsRevision = toolCalls.find(
300
+ call => call.name === "incrementRevision",
301
+ );
302
+ const handoff = toolCalls.find(
303
+ call => call.kind === "agent_tool" &&
304
+ (call.input as { mode?: string }).mode === "handoff",
305
+ );
306
+ if (incrementsRevision && handoff) {
307
+ return {
308
+ allowed: false,
309
+ code: "invalid_tool_batch",
310
+ message: "Update the revision before delegating dependent work.",
311
+ conflictingToolCallIds: [incrementsRevision.id, handoff.id],
312
+ suggestedNextStep: "Run incrementRevision first, then hand off the new revision.",
313
+ };
314
+ }
315
+ return { allowed: true };
316
+ },
317
+ },
318
+ });
319
+ ```
320
+
321
+ The policy may be synchronous or asynchronous. If it throws, the SDK rejects
322
+ the whole batch with `tool_batch_policy_error`; no tool has executed. Without a
323
+ policy, tool execution is unchanged. A policy prevents known bad combinations
324
+ inside one model response, but it does not replace database transactions or
325
+ revision checks against concurrent external updates.
326
+
286
327
  ## Business Context For Tools
287
328
 
288
329
  Pass host application data through `context`. The SDK gives that context to
package/dist/index.d.ts CHANGED
@@ -177,6 +177,32 @@ export interface ModelClient {
177
177
  export type ToolResult = {
178
178
  content: string | ContentBlock[];
179
179
  };
180
+ export type ToolKind = "tool" | "agent_tool";
181
+ export type ToolBatchCall = {
182
+ id: string;
183
+ name: string;
184
+ input: unknown;
185
+ kind: ToolKind;
186
+ };
187
+ export type ToolBatchPolicyContext<TContext = unknown> = {
188
+ source?: AgentRuntimeSource;
189
+ toolCalls: ToolBatchCall[];
190
+ context?: TContext;
191
+ signal?: AbortSignal;
192
+ };
193
+ export type ToolBatchPolicyRejection = {
194
+ allowed: false;
195
+ code: string;
196
+ message: string;
197
+ conflictingToolCallIds?: string[];
198
+ suggestedNextStep?: string;
199
+ };
200
+ export type ToolBatchPolicyResult = {
201
+ allowed: true;
202
+ } | ToolBatchPolicyRejection;
203
+ export type ToolBatchPolicy<TContext = unknown> = {
204
+ validate(context: ToolBatchPolicyContext<TContext>): ToolBatchPolicyResult | Promise<ToolBatchPolicyResult>;
205
+ };
180
206
  export type ToolExecutionContext<TContext = unknown> = {
181
207
  signal?: AbortSignal;
182
208
  toolUseId: string;
@@ -188,6 +214,7 @@ export type ToolHandler<TInput = unknown, TContext = unknown> = (input: TInput,
188
214
  export type ToolDefinition<TInput = unknown, TContext = unknown> = {
189
215
  name: string;
190
216
  description: string;
217
+ kind?: ToolKind;
191
218
  inputSchema: unknown;
192
219
  jsonSchema: Record<string, unknown>;
193
220
  parse(input: unknown): TInput;
@@ -386,6 +413,7 @@ export type AgentOptions<TContext = unknown> = {
386
413
  maxTurns?: number;
387
414
  thinkingConfig?: ThinkingConfig;
388
415
  tools?: Array<ToolDefinition<any, TContext>>;
416
+ toolBatchPolicy?: ToolBatchPolicy<TContext>;
389
417
  skills?: SkillDefinition[];
390
418
  workspace?: AgentWorkspaceOptions;
391
419
  permission?: (request: PermissionRequest) => Promise<PermissionDecision> | PermissionDecision;
@@ -490,6 +518,10 @@ export declare class MaxTurnsError extends AgentSDKError {
490
518
  }
491
519
  export declare class AbortError extends AgentSDKError {
492
520
  }
521
+ export declare class ToolBatchRejectedError extends AgentSDKError {
522
+ readonly rejection: ToolBatchPolicyRejection;
523
+ constructor(rejection: ToolBatchPolicyRejection);
524
+ }
493
525
  export declare class ToolPermissionDeniedError extends AgentSDKError {
494
526
  readonly denial: PermissionDenial;
495
527
  constructor(denial: PermissionDenial);