agent-lattice 0.9.25 → 0.14.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 CHANGED
@@ -7,6 +7,11 @@ Install it from npm as `agent-lattice`. It works with Anthropic and
7
7
  Anthropic-compatible providers such as DeepSeek, without installing the Claude
8
8
  Code CLI runtime.
9
9
 
10
+ > **Integrating this SDK from an AI agent?** Start at
11
+ > <https://docs.claude-code-sdk.com/llms.txt> for an index of the documentation,
12
+ > where every page is served as clean Markdown. Read
13
+ > <https://docs.claude-code-sdk.com/llms-full.txt> to take it all in one request.
14
+
10
15
  ## Install
11
16
 
12
17
  ```bash
@@ -50,6 +55,24 @@ const agent = createBareAgent({
50
55
  });
51
56
  ```
52
57
 
58
+ `agent.query()` yields `stream_event` messages while the model is still
59
+ responding, so a host can render output incrementally:
60
+
61
+ ```ts
62
+ for await (const message of agent.query("Say hello")) {
63
+ if (message.type === "stream_event") {
64
+ const event = message.event as { type: string; delta?: { text?: string } };
65
+ if (event.type === "content_block_delta" && event.delta?.text) {
66
+ process.stdout.write(event.delta.text);
67
+ }
68
+ }
69
+ }
70
+ ```
71
+
72
+ The SDK produces the next event only after the loop takes the current one.
73
+ Slow work in the loop body delays later events without dropping or reordering
74
+ them, so keep expensive handling off the loop itself.
75
+
53
76
  Pass `{ stream: false }` to disable model streaming for a query:
54
77
 
55
78
  ```ts
@@ -103,6 +126,30 @@ Use `{ type: "adaptive" }` for models that support adaptive thinking. Use
103
126
  budget is capped at `maxTokens - 1` to satisfy the Anthropic API constraint.
104
127
  When omitted, the SDK does not send a thinking configuration.
105
128
 
129
+ For Kimi K3 through an Anthropic-compatible endpoint or gateway, use
130
+ `reasoningEffort` to send the provider's top-level `reasoning_effort` parameter:
131
+
132
+ ```ts
133
+ const agent = createAgent({
134
+ apiKey: process.env.MOONSHOT_API_KEY,
135
+ baseURL: process.env.KIMI_ANTHROPIC_BASE_URL,
136
+ model: "kimi-k3",
137
+ reasoningEffort: "high",
138
+ });
139
+
140
+ const result = await agent.prompt("Solve this carefully.", {
141
+ reasoningEffort: "low",
142
+ });
143
+ ```
144
+
145
+ The supported values are `"low"`, `"high"`, and `"max"`. A query-level value
146
+ overrides the agent default. When omitted, the SDK does not send
147
+ `reasoning_effort`, so the provider applies its own default (`"max"` for Kimi
148
+ K3). Kimi K3 does not accept `thinkingConfig`; use `reasoningEffort` instead.
149
+ The Kimi Open Platform endpoint at `https://api.moonshot.cn/v1` uses the OpenAI
150
+ Chat Completions protocol and is not a valid `baseURL` for the SDK's built-in
151
+ Anthropic client.
152
+
106
153
  ## Multimodal Input
107
154
 
108
155
  Pass Anthropic-compatible content blocks for image or document prompts:
@@ -369,6 +416,100 @@ policy, tool execution is unchanged. A policy prevents known bad combinations
369
416
  inside one model response, but it does not replace database transactions or
370
417
  revision checks against concurrent external updates.
371
418
 
419
+ ## Automatic Context Compaction
420
+
421
+ History only grows, so a long-running agent eventually exceeds the model's
422
+ context window. Enable `autoCompact` to replace the older part of the
423
+ conversation with a model-written summary:
424
+
425
+ ```ts
426
+ const agent = createAgent({
427
+ apiKey: process.env.ANTHROPIC_API_KEY,
428
+ model: "claude-sonnet-4-6",
429
+ autoCompact: true, // or { thresholdTokens: 150_000, keepRecentMessages: 8 }
430
+ });
431
+ ```
432
+
433
+ Compaction runs between turns, once a response reports more input tokens than
434
+ `thresholdTokens` (default `100000`). Everything except the last
435
+ `keepRecentMessages` messages (default `6`) is summarized, and the history is
436
+ rebuilt as that summary followed by the retained messages. The summary is
437
+ wrapped in an instruction telling the model that compaction just happened and to
438
+ continue from it, so the next turn resumes the task instead of restarting it.
439
+
440
+ Unlike the `onModelRequest` hook, which shapes a single request, this **rewrites
441
+ the stored conversation** — that is what makes the saving persist, but the
442
+ replaced turns are gone.
443
+
444
+ The cut point never separates a `tool_result` from the `tool_use` that produced
445
+ it, because the model API rejects that. If no safe cut leaves anything to
446
+ summarize, compaction is skipped.
447
+
448
+ Compaction costs a model call. Its tokens are folded into `result.usage`, and a
449
+ `system` message with `subtype: "compaction"` reports what happened:
450
+
451
+ ```ts
452
+ for await (const message of agent.query("Refactor this module.")) {
453
+ if (message.type === "system" && message.subtype === "compaction") {
454
+ console.log(`compacted ${message.compacted_messages} messages`, message.usage);
455
+ }
456
+ }
457
+ ```
458
+
459
+ The trigger depends on reported usage, so a custom `ModelClient` that omits
460
+ `usage` never compacts. Override the instruction with `prompt`, or read the
461
+ built-in one from `DEFAULT_COMPACTION_PROMPT`.
462
+
463
+ The threshold is a forecast, so a single large tool result can still carry a
464
+ request past the window. Compaction then runs as a recovery — summarize, then
465
+ retry the same turn — on either `stop_reason: "model_context_window_exceeded"`
466
+ or an API error naming a too-long prompt. It is attempted once per query; if
467
+ summarizing fails or there is nothing left to summarize, the original failure
468
+ surfaces unchanged.
469
+
470
+ `stop_reason: "max_tokens"` deliberately does **not** trigger compaction. It
471
+ means the *output* hit `maxTokens`, not that the input was too large — the model
472
+ had room to read and ran out of room to write, so compacting the history would
473
+ not make the answer complete. Raise `maxTokens` instead.
474
+
475
+ ## Hooks
476
+
477
+ `permission` and `toolBatchPolicy` decide whether something runs. Hooks decide
478
+ what it looks like — redacting tool output, trimming context before a request,
479
+ or injecting retrieved documents:
480
+
481
+ ```ts
482
+ const agent = createAgent({
483
+ apiKey: process.env.ANTHROPIC_API_KEY,
484
+ model: "claude-sonnet-4-6",
485
+ tools: [queryDatabase],
486
+ hooks: {
487
+ async onToolResult({ toolName, result, error }) {
488
+ if (toolName !== "queryDatabase") return; // undefined: leave unchanged
489
+ return { ...result, content: await redact(result.content) };
490
+ },
491
+ onModelRequest({ messages, turn }) {
492
+ if (messages.length < 40) return;
493
+ return { messages: compact(messages) };
494
+ },
495
+ },
496
+ });
497
+ ```
498
+
499
+ `onToolResult` sees every result on its way to the model, including handler
500
+ failures, aborted calls, and calls blocked by `toolBatchPolicy`. `onModelRequest`
501
+ shapes a single request; the stored conversation is untouched, so trimming
502
+ context does not destroy history.
503
+
504
+ A hook returns a replacement or nothing, and must not mutate what it receives. A
505
+ hook that throws propagates out of `query()` rather than becoming an error
506
+ `result` — a redaction hook that failed quietly would leak the data it exists to
507
+ protect. Hooks run before the matching trace event, so traces record what was
508
+ actually sent.
509
+
510
+ Compose independent concerns with `createCompositeAgentHooks([a, b, c])`, which
511
+ chains them in order, each receiving the previous one's output.
512
+
372
513
  ## Business Context For Tools
373
514
 
374
515
  Pass host application data through `context`. The SDK gives that context to
@@ -897,3 +1038,62 @@ console.log(result.result);
897
1038
  The SDK stores conversation state in memory for the lifetime of the `Agent`
898
1039
  instance. Persistent transcripts and resume support are intentionally out of
899
1040
  scope for the first release.
1041
+
1042
+ An `Agent` is a conversation, not a reusable client. Because the history is
1043
+ instance state, starting a query while another is still running would interleave
1044
+ both conversations; the SDK rejects the second one with `ConcurrentQueryError`.
1045
+ Create one Agent per concurrent conversation — in a server, per request or per
1046
+ user session rather than a shared module-level instance. Sequential reuse, as
1047
+ above, is the intended pattern.
1048
+
1049
+ ## Deadlines
1050
+
1051
+ `QueryOptions.signal` bounds a whole query — every model request, tool call, and
1052
+ turn together. `requestTimeoutMs` bounds each single model request, so an agent
1053
+ that legitimately runs many tool-using turns does not have to fit them all into
1054
+ one budget:
1055
+
1056
+ ```ts
1057
+ const agent = createAgent({
1058
+ apiKey: process.env.ANTHROPIC_API_KEY,
1059
+ model: "claude-sonnet-4-6",
1060
+ requestTimeoutMs: 120_000,
1061
+ });
1062
+
1063
+ const result = await agent.prompt("Audit this repository.", {
1064
+ signal: AbortSignal.timeout(600_000),
1065
+ requestTimeoutMs: 60_000, // overrides the agent default for this query
1066
+ });
1067
+ ```
1068
+
1069
+ A request deadline produces `subtype: "error_timeout"` with a `TimeoutError`,
1070
+ distinct from the `"error_abort"` of a caller-initiated cancellation, so hosts
1071
+ can retry timeouts without retrying deliberate cancellations.
1072
+
1073
+ Both limits are enforced by the SDK rather than delegated. `ModelRequest` carries
1074
+ `signal` and `timeoutMs` so a client can cancel its own work, but the agent loop
1075
+ also races the call, so a `ModelClient` that honours neither cannot stall the
1076
+ loop indefinitely. Losing that race abandons the call rather than cancelling it.
1077
+
1078
+ ## Token Usage And Truncation
1079
+
1080
+ Every `result` message reports `usage`, summed over the model requests in that
1081
+ query, plus the `stop_reason` of the last response:
1082
+
1083
+ ```ts
1084
+ const result = await agent.prompt("Summarize this file.");
1085
+ console.log(result.usage);
1086
+ // { input_tokens: 1200, output_tokens: 512, cache_read_input_tokens: 800 }
1087
+
1088
+ if (result.stop_reason === "max_tokens") {
1089
+ // subtype is still "success", but result is a fragment, not an answer.
1090
+ }
1091
+ ```
1092
+
1093
+ `stop_reason: "max_tokens"` means the model hit its output budget mid-response.
1094
+ The SDK does not treat that as an error, so checking this field is the only way
1095
+ to distinguish a complete answer from a truncated one.
1096
+
1097
+ Usage comes from the model client. The built-in Anthropic client fills it in from
1098
+ the response, including the streaming path; a custom `ModelClient` that omits
1099
+ `usage` produces zeroed counts rather than an error.
package/dist/index.d.ts CHANGED
@@ -102,7 +102,7 @@ export type AgentRuntimeContext = {
102
102
  emit(message: TeamRunnerMessage): void;
103
103
  shouldPauseAfterToolBatch?(): boolean;
104
104
  };
105
- export type ContextTraceEventType = "run_start" | "user_message" | "model_request" | "assistant_message" | "tool_use" | "tool_result" | "team_message" | "result" | "error";
105
+ export type ContextTraceEventType = "run_start" | "user_message" | "model_request" | "assistant_message" | "tool_use" | "tool_result" | "team_message" | "result" | "compaction" | "error";
106
106
  export type ContextTraceEvent = {
107
107
  version: 1;
108
108
  timestamp: string;
@@ -150,9 +150,27 @@ export type ModelMessage = {
150
150
  role: "user" | "assistant";
151
151
  content: string | ContentBlock[];
152
152
  };
153
+ export type TokenUsage = {
154
+ input_tokens: number;
155
+ output_tokens: number;
156
+ cache_creation_input_tokens?: number;
157
+ cache_read_input_tokens?: number;
158
+ };
159
+ /**
160
+ * Why the model stopped. `"max_tokens"` means the response was cut off mid-way:
161
+ * the text is a fragment, not an answer. Left open because providers add values.
162
+ */
163
+ export type StopReason = "end_turn"
164
+ /** Output hit `maxTokens`. The text is a fragment; compaction does not help. */
165
+ | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal"
166
+ /** The context window ran out mid-request. This is what compaction is for. */
167
+ | "model_context_window_exceeded" | (string & {});
153
168
  export type AssistantModelMessage = {
154
169
  role: "assistant";
155
170
  content: ContentBlock[];
171
+ /** Absent when a custom ModelClient does not report it. */
172
+ usage?: TokenUsage;
173
+ stopReason?: StopReason;
156
174
  };
157
175
  export type ModelToolDefinition = {
158
176
  name: string;
@@ -168,6 +186,9 @@ export type ModelRequest = {
168
186
  stream: boolean;
169
187
  outputFormat?: OutputFormat;
170
188
  thinkingConfig?: ThinkingConfig;
189
+ reasoningEffort?: ReasoningEffort;
190
+ /** Deadline for this single request. Clients should honour it; the SDK also enforces it. */
191
+ timeoutMs?: number;
171
192
  onStreamEvent?: (event: Record<string, unknown>) => void;
172
193
  signal?: AbortSignal;
173
194
  };
@@ -210,6 +231,70 @@ export type ToolExecutionContext<TContext = unknown> = {
210
231
  agentRuntime?: AgentRuntimeContext;
211
232
  permissions?: RuntimePermissions;
212
233
  };
234
+ export type ToolResultHookContext<TContext = unknown> = {
235
+ toolName: string;
236
+ toolUseId: string;
237
+ /** Raw input as the model sent it, before the tool schema parsed it. */
238
+ input: unknown;
239
+ /** What the SDK would send back to the model. */
240
+ result: ToolResultBlock;
241
+ /** Present when the handler failed, was denied, or was cancelled. */
242
+ error?: Error;
243
+ context?: TContext;
244
+ source?: AgentRuntimeSource;
245
+ signal?: AbortSignal;
246
+ };
247
+ export type ModelRequestHookContext<TContext = unknown> = {
248
+ /** What the SDK would send. Not the stored history; see AgentHooks. */
249
+ messages: ModelMessage[];
250
+ systemPrompt?: string;
251
+ /** 1 for the first model request of the query. */
252
+ turn: number;
253
+ context?: TContext;
254
+ source?: AgentRuntimeSource;
255
+ signal?: AbortSignal;
256
+ };
257
+ export type ModelRequestHookResult = {
258
+ messages?: ModelMessage[];
259
+ systemPrompt?: string;
260
+ };
261
+ export declare const DEFAULT_COMPACTION_PROMPT = "Your task is to create a detailed summary of the conversation so far,\npaying close attention to the user's explicit requests and your previous actions.\n\nThis summary should be thorough in capturing:\n- technical details\n- code patterns\n- architectural decisions\n- files that were modified\n- commands that were run\n- errors encountered\n- solutions attempted\n- important context needed to continue the work\n\nPreserve:\n- user's intent\n- important constraints\n- decisions already made\n- reasoning behind decisions\n- unresolved issues\n- next steps\n\nThe summary will replace the conversation history, so include everything\nnecessary for another Claude instance to continue the task successfully.\n\nOutput only the summary.";
262
+ export type AutoCompactOptions = {
263
+ /**
264
+ * Compact once a model response reports more input tokens than this.
265
+ * Defaults to 100000, chosen to leave headroom on a 200k-token model.
266
+ */
267
+ thresholdTokens?: number;
268
+ /** Trailing messages left verbatim after the summary. Defaults to 6. */
269
+ keepRecentMessages?: number;
270
+ /** Replaces DEFAULT_COMPACTION_PROMPT. */
271
+ prompt?: string;
272
+ /** Model used for the summary. Defaults to the agent's model. */
273
+ model?: string;
274
+ /** Output cap for the summary. Defaults to 8192. */
275
+ maxTokens?: number;
276
+ };
277
+ /**
278
+ * Lifecycle callbacks that can rewrite what crosses the agent loop's boundaries,
279
+ * as opposed to `permission` and `toolBatchPolicy`, which can only allow or deny.
280
+ *
281
+ * A hook returns a replacement, or nothing to leave the value unchanged; it must
282
+ * not mutate what it receives.
283
+ *
284
+ * A hook that throws propagates out of `query()` rather than being swallowed the
285
+ * way a tracer error is, or being reported as an error `result`. A hook failure
286
+ * is host code failing, like `ConcurrentQueryError`, not an upstream failure the
287
+ * loop can describe to the model — and a redaction hook that failed quietly
288
+ * would leak the data it exists to protect.
289
+ *
290
+ * Hooks run before the matching trace event, so traces record what was actually
291
+ * sent. `onModelRequest` shapes one request only and never edits the stored
292
+ * conversation, so trimming context for a long turn does not destroy history.
293
+ */
294
+ export type AgentHooks<TContext = unknown> = {
295
+ onToolResult?(context: ToolResultHookContext<TContext>): ToolResultBlock | void | Promise<ToolResultBlock | void>;
296
+ onModelRequest?(context: ModelRequestHookContext<TContext>): ModelRequestHookResult | void | Promise<ModelRequestHookResult | void>;
297
+ };
213
298
  export type ToolHandler<TInput = unknown, TContext = unknown> = (input: TInput, context: ToolExecutionContext<TContext>) => Promise<ToolResult> | ToolResult;
214
299
  export type ToolOptions<TInput = unknown> = {
215
300
  isConcurrencySafe?: (input: TInput) => boolean;
@@ -421,8 +506,18 @@ export type AgentOptions<TContext = unknown> = {
421
506
  maxTokens?: number;
422
507
  maxTurns?: number;
423
508
  thinkingConfig?: ThinkingConfig;
509
+ reasoningEffort?: ReasoningEffort;
510
+ /** Deadline for each single model request, in milliseconds. Unset means no SDK-side limit. */
511
+ requestTimeoutMs?: number;
424
512
  tools?: Array<ToolDefinition<any, TContext>>;
425
513
  toolBatchPolicy?: ToolBatchPolicy<TContext>;
514
+ /** Lifecycle callbacks that rewrite tool results and outgoing model requests. */
515
+ hooks?: AgentHooks<TContext>;
516
+ /**
517
+ * Replaces older conversation history with a model-written summary once it
518
+ * grows past a threshold. Off unless set; `true` uses the defaults.
519
+ */
520
+ autoCompact?: boolean | AutoCompactOptions;
426
521
  toolConcurrency?: ToolConcurrencyOptions;
427
522
  skills?: SkillDefinition[];
428
523
  workspace?: AgentWorkspaceOptions;
@@ -440,6 +535,9 @@ export type QueryOptions<TContext = unknown> = {
440
535
  stream?: boolean;
441
536
  outputFormat?: OutputFormat;
442
537
  thinkingConfig?: ThinkingConfig;
538
+ reasoningEffort?: ReasoningEffort;
539
+ /** Overrides the agent's per-request deadline for this query. */
540
+ requestTimeoutMs?: number;
443
541
  signal?: AbortSignal;
444
542
  context?: TContext;
445
543
  agentRuntime?: AgentRuntimeContext;
@@ -455,6 +553,7 @@ export type ThinkingConfig = {
455
553
  } | {
456
554
  type: "disabled";
457
555
  };
556
+ export type ReasoningEffort = "low" | "high" | "max";
458
557
  export type SDKSystemInitMessage = {
459
558
  type: "system";
460
559
  subtype: "init";
@@ -462,6 +561,19 @@ export type SDKSystemInitMessage = {
462
561
  tools: string[];
463
562
  session_id: string;
464
563
  };
564
+ export type SDKSystemCompactionMessage = {
565
+ type: "system";
566
+ subtype: "compaction";
567
+ session_id: string;
568
+ /** Messages replaced by the summary. */
569
+ compacted_messages: number;
570
+ /** Messages kept verbatim after it. */
571
+ retained_messages: number;
572
+ /** Input tokens of the turn that triggered compaction. */
573
+ trigger_input_tokens: number;
574
+ /** Cost of producing the summary, already folded into the result usage. */
575
+ usage: TokenUsage;
576
+ };
465
577
  export type SDKAssistantMessage = {
466
578
  type: "assistant";
467
579
  message: AssistantModelMessage;
@@ -481,14 +593,21 @@ export type SDKStreamEventMessage = {
481
593
  };
482
594
  export type SDKResultMessage = {
483
595
  type: "result";
484
- subtype: "success" | "error" | "error_max_turns" | "error_abort";
596
+ subtype: "success" | "error" | "error_max_turns" | "error_abort" | "error_timeout";
485
597
  is_error: boolean;
486
598
  result: string;
487
599
  session_id: string;
488
600
  num_turns: number;
489
601
  error?: Error;
490
- };
491
- export type SDKMessage = SDKSystemInitMessage | SDKStreamEventMessage | SDKAssistantMessage | SDKUserMessage | SDKResultMessage;
602
+ /** Summed over every model request in the query. Zeroed when unreported. */
603
+ usage: TokenUsage;
604
+ /**
605
+ * From the last model response. Check for `"max_tokens"`: `subtype` is still
606
+ * `"success"` there, but `result` is a truncated fragment.
607
+ */
608
+ stop_reason?: StopReason;
609
+ };
610
+ export type SDKMessage = SDKSystemInitMessage | SDKSystemCompactionMessage | SDKStreamEventMessage | SDKAssistantMessage | SDKUserMessage | SDKResultMessage;
492
611
  export type TeamRunnerSource = AgentRuntimeSource;
493
612
  export type TeamRunnerTeamMessage = {
494
613
  type: "team_message";
@@ -528,6 +647,12 @@ export declare class MaxTurnsError extends AgentSDKError {
528
647
  }
529
648
  export declare class AbortError extends AgentSDKError {
530
649
  }
650
+ /** A second query was started on an Agent that was still running one. */
651
+ export declare class ConcurrentQueryError extends AgentSDKError {
652
+ }
653
+ /** A model request exceeded `requestTimeoutMs`. */
654
+ export declare class TimeoutError extends AgentSDKError {
655
+ }
531
656
  export declare class ToolBatchRejectedError extends AgentSDKError {
532
657
  readonly rejection: ToolBatchPolicyRejection;
533
658
  constructor(rejection: ToolBatchPolicyRejection);
@@ -575,6 +700,12 @@ export declare function createAgent<TContext = unknown>(options: AgentOptions<TC
575
700
  export declare function createBareAgent<TContext = unknown>(options: BareAgentOptions<TContext>): Agent<TContext>;
576
701
  export declare function createBuiltinTools(options?: AgentWorkspaceToolsOptions): Array<ToolDefinition<any, any>>;
577
702
  export declare function createJsonlContextTracer(options: JsonlContextTracerOptions): ContextTracer;
703
+ /**
704
+ * Chains hooks in array order: each one sees the previous one's output, so
705
+ * redaction, truncation, and auditing can be written separately and combined.
706
+ * Unlike the composite tracer, a failure is not swallowed — see `AgentHooks`.
707
+ */
708
+ export declare function createCompositeAgentHooks<TContext = unknown>(hooks: Array<AgentHooks<TContext> | undefined | null>): AgentHooks<TContext>;
578
709
  export declare function createCompositeContextTracer(tracers: Array<ContextTracer | undefined | null>): ContextTracer;
579
710
  export declare function createLangSmithContextTracer(options: LangSmithContextTracerOptions): ContextTracer;
580
711
  export declare function skill(input: SkillInput): SkillDefinition;
@@ -593,6 +724,7 @@ export declare function query<TContext = unknown>(params: AgentOptions<TContext>
593
724
  stream?: boolean;
594
725
  outputFormat?: OutputFormat;
595
726
  thinkingConfig?: ThinkingConfig;
727
+ reasoningEffort?: ReasoningEffort;
596
728
  signal?: AbortSignal;
597
729
  context?: TContext;
598
730
  }): AsyncGenerator<SDKMessage>;
@@ -602,13 +734,34 @@ export declare class Agent<TContext = unknown> {
602
734
  private readonly messages;
603
735
  private readonly sessionId;
604
736
  private readonly toolConcurrency;
737
+ private running;
605
738
  constructor(options: AgentOptions<TContext>);
739
+ /**
740
+ * One Agent owns one conversation. Overlapping queries would interleave writes
741
+ * into the shared history, so the second caller is rejected rather than served
742
+ * a conversation containing someone else's turns.
743
+ */
606
744
  query(prompt: string | ContentBlock[], options?: QueryOptions<TContext>): AsyncGenerator<SDKMessage>;
745
+ private runQuery;
607
746
  prompt(prompt: string | ContentBlock[], options?: QueryOptions<TContext>): Promise<SDKResultMessage>;
608
747
  addTools(tools: Array<ToolDefinition<any, TContext>>): void;
609
748
  private initMessage;
610
749
  private resultMessage;
611
750
  private modelTools;
751
+ /**
752
+ * Replaces the summarizable head of the conversation with a model-written
753
+ * summary. Returns undefined when there is nothing safe to compact, and lets a
754
+ * failed summarization surface so the caller can decide: compaction is best
755
+ * effort, and continuing with a full history is better than losing it.
756
+ */
757
+ private compactHistory;
758
+ /**
759
+ * Last-resort compaction after a turn already ran out of context, as opposed
760
+ * to the threshold check that runs between turns. Returns the message to emit
761
+ * so the caller can retry, or undefined when compaction cannot help and the
762
+ * original failure should surface instead.
763
+ */
764
+ private recoverFromOverflow;
612
765
  private messagesForModel;
613
766
  private selectSkills;
614
767
  private runTool;