@cognipeer/agent-sdk 0.9.7 → 0.10.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/dist/index.d.ts CHANGED
@@ -107,6 +107,746 @@ declare function withTools(model: SmartModel, tools: any[], options?: {
107
107
  }): BaseChatModel;
108
108
  declare function fromLangchainModel(lcModel: any): BaseChatModel;
109
109
 
110
+ /**
111
+ * Skill primitive — progressive capability disclosure for the smart agent.
112
+ *
113
+ * A Skill is a lazy, self-contained capability bundle. The model discovers a
114
+ * skill by its cheap one-line `header`, then calls `open_skill(key)` to load the
115
+ * skill's prompt and (for small skills) bind its tools, or
116
+ * `bind_skill_tools(key, names)` to bind a chosen subset of a fat skill. This
117
+ * keeps the number of bound tools per step small — the property small models
118
+ * need — and replaces an up-front tool-selector pass with on-demand disclosure.
119
+ *
120
+ * Discovery itself comes in two flavors, see `SkillPolicy.disclosure`: the
121
+ * headers can be listed in the system prompt, or looked up with `search_skills`.
122
+ */
123
+ type SkillToolHeader = {
124
+ name: string;
125
+ description?: string;
126
+ };
127
+ type SkillModelTier = "small" | "large";
128
+ /**
129
+ * How the model finds out which skills exist.
130
+ *
131
+ * - `"catalog"` (default): every available skill's header is rendered into the
132
+ * system prompt as `<available_skills>`. Cheapest possible discovery — the
133
+ * model needs no tool call — but the prompt grows with the catalog, and the
134
+ * whole catalog is paid for on every single turn of every conversation.
135
+ * - `"search"`: nothing goes into the prompt. The model finds skills through
136
+ * the `search_skills` tool, whose description is the only always-on cost.
137
+ * Prompt cost is constant, so this is the mode for a catalog that is large,
138
+ * workspace-supplied, or mostly irrelevant to any one conversation. The
139
+ * trade-off is real: a model that never calls `search_skills` never learns
140
+ * the skills exist, so keep the tool description explicit about when to call.
141
+ */
142
+ type SkillDisclosure = "catalog" | "search";
143
+ type Skill = {
144
+ /** Stable key, e.g. "mcp:atlassian" | "integration:google" | "builtin:drawio". */
145
+ key: string;
146
+ title: string;
147
+ /** One-line "what + when to use" the model always sees in the catalog. */
148
+ header: string;
149
+ /** Injected (as the open_skill result) only after the skill is opened. */
150
+ prompt: string | (() => Promise<string> | string);
151
+ /** When true, opening this skill should trigger sandbox bootstrap. */
152
+ needsSandbox?: boolean;
153
+ /** Gate: a "large"-only skill is hidden from a small-tier model. */
154
+ minModelTier?: SkillModelTier;
155
+ /** Whether the skill is usable in the current workspace (integration connected, etc.). */
156
+ isAvailable?: () => boolean | Promise<boolean>;
157
+ /** Cheap list of the skill's tool headers (names + one-liners). */
158
+ listToolIndex: () => Promise<SkillToolHeader[]> | SkillToolHeader[];
159
+ /** Bind concrete tools. With no names, bind the whole (small) skill. */
160
+ bindTools: (names?: string[]) => Promise<ToolInterface[]> | ToolInterface[];
161
+ /** Optional embedding/heuristic ranking of tool headers for a fat skill. */
162
+ rankToolHeaders?: (query: string, headers: SkillToolHeader[]) => Promise<SkillToolHeader[]> | SkillToolHeader[];
163
+ /** Deterministic floor: tools to bind when a weak model gives no usable query. */
164
+ defaultBindNames?: string[];
165
+ };
166
+ type SkillPolicy = {
167
+ /** Max distinct skills open at once (small tier should be 1). */
168
+ maxOpenSkills: number;
169
+ /** Max tools bound from a single skill in one bind call. */
170
+ maxBoundToolsPerSkill: number;
171
+ /** Overall cap on skill-bound tools across the whole run. */
172
+ maxBoundToolsTotal: number;
173
+ /** Current model tier; gates `minModelTier`. */
174
+ modelTier?: SkillModelTier;
175
+ /** How the model discovers skills. Defaults to `"catalog"`. */
176
+ disclosure?: SkillDisclosure;
177
+ };
178
+ declare const DEFAULT_SKILL_POLICY: SkillPolicy;
179
+ declare const SMALL_TIER_SKILL_POLICY: SkillPolicy;
180
+ /**
181
+ * Mutable per-invoke registry. The skill tools mutate this ref (append-only) and
182
+ * call `__onToolsChanged` so the runtime can rebuild its tool sets. Mirrors the
183
+ * stateRef pattern used by createAskUserQuestionTool.
184
+ */
185
+ type SkillRegistryRef = {
186
+ /** Append-only: skills the model has opened this run. */
187
+ openedSkillKeys: string[];
188
+ /** Append-only, deduped by tool name: tools bound from opened skills. */
189
+ boundSkillTools: ToolInterface[];
190
+ /** Rebuild hook wired by createSmartAgent; rebuilds both recovery variants. */
191
+ __onToolsChanged?: () => void;
192
+ };
193
+ declare function createSkillRegistryRef(): SkillRegistryRef;
194
+
195
+ /**
196
+ * A non-text part of a message, normalized across the two shapes this SDK
197
+ * accepts: the unified `{ type: "image" | "audio" | "file", source: … }` used by
198
+ * the native providers, and the legacy OpenAI-style `{ type: "image_url", … }`.
199
+ * A policy that had to know which of the two it was looking at would be wrong
200
+ * for half of its callers.
201
+ */
202
+ type MediaAttachment = {
203
+ /** Position in the content array, so a policy can rewrite the right part. */
204
+ index: number;
205
+ kind: "image" | "audio" | "video" | "file" | "unknown";
206
+ mediaType?: string;
207
+ sourceType?: "url" | "base64";
208
+ url?: string;
209
+ /** Decoded size for a base64 payload. Unknown for a URL — nobody fetched it. */
210
+ approxBytes?: number;
211
+ fileName?: string;
212
+ };
213
+ declare function contentToString(content: string | ContentPart$1[] | any): string;
214
+ declare function extractMessageText(message: any): string;
215
+ /**
216
+ * The text a hook should reason about: the text parts only, joined.
217
+ *
218
+ * Deliberately not `contentToString`, which renders media as human-readable
219
+ * descriptors (`[image:…]`) for logs and token counting. A guardrail scoring
220
+ * that string would be scoring the SDK's own placeholder text, and a redactor
221
+ * rewriting it would bake the placeholder into the message.
222
+ */
223
+ declare function textFromContent(content: string | ContentPart$1[] | unknown): string;
224
+ /**
225
+ * Rewrite the text of a message's content, leaving every other part exactly as
226
+ * it was — same objects, same order.
227
+ *
228
+ * This is the write-back half of every text-oriented hook. Assigning a plain
229
+ * string over a multi-part `content` is the silent version of this operation:
230
+ * the run still answers, it just answers without the image the user attached.
231
+ */
232
+ declare function mapTextParts(content: string | ContentPart$1[] | unknown, fn: (text: string) => string): string | ContentPart$1[] | unknown;
233
+ /**
234
+ * Put a whole replacement text back into a multi-part content.
235
+ *
236
+ * A hook that took `text` saw the CONCATENATION of every text part, so there is
237
+ * no general way to split its answer back across them. With one text part (the
238
+ * ordinary case) this is exact. With several, the replacement lands in the first
239
+ * and the rest are dropped — media parts keep their positions either way. A
240
+ * plugin that needs exact multi-part fidelity should return `content` instead,
241
+ * which is why that field exists.
242
+ */
243
+ declare function replaceTextContent(content: string | ContentPart$1[] | unknown, text: string): string | ContentPart$1[] | unknown;
244
+ /** Every non-text part of a message, normalized for policy code. */
245
+ declare function collectAttachments(content: string | ContentPart$1[] | unknown): MediaAttachment[];
246
+
247
+ /**
248
+ * Plugin layer — type surface.
249
+ *
250
+ * This module is TYPE-ONLY on purpose. `src/types.ts` imports `AgentPlugin`
251
+ * from here while this file imports most of its payload types from there; a
252
+ * runtime export in either direction would create a real module cycle. Keeping
253
+ * everything here erasable (`import type` / `export type`) means the cycle
254
+ * disappears at compile time.
255
+ *
256
+ * Three kinds of extension live in a plugin:
257
+ * - hooks intercept many run, chained, decisions merge
258
+ * - contributions add many run, results accumulate
259
+ * - slots replace exactly one owner, conflict is a hard error
260
+ */
261
+
262
+ type MaybePromise<T> = T | Promise<T>;
263
+ /** How a plugin's failure is interpreted. `closed` turns an error into a deny. */
264
+ type PluginFailureMode = "open" | "closed";
265
+ /** Merged verdict of a gate hook. Escalation order: allow &lt; ask &lt; deny. */
266
+ type HookDecision = "allow" | "deny" | "ask";
267
+ type PluginLogger = {
268
+ debug(...args: unknown[]): void;
269
+ warn(...args: unknown[]): void;
270
+ error(...args: unknown[]): void;
271
+ };
272
+ /**
273
+ * Passed to every hook and slot call. Scoped per plugin: `store` is private to
274
+ * the plugin that received it and lives for exactly one run.
275
+ */
276
+ type HookContext = {
277
+ /** Stable id for this invoke, always present. */
278
+ runId: string;
279
+ /**
280
+ * The run's trace id, for correlating a decision with its timeline.
281
+ *
282
+ * Undefined when tracing is off, and also for hooks that run BEFORE the first
283
+ * model call on a smart agent — the trace session is created inside the first
284
+ * base leg, while `sessionStart` and `userPromptSubmit` run ahead of it.
285
+ * `runId` is the identifier that is always available; treat this as an
286
+ * additional join key, not a replacement.
287
+ */
288
+ traceId?: string;
289
+ agentName?: string;
290
+ /** Name of the hook currently executing — handy for shared handlers. */
291
+ hookName: string;
292
+ /**
293
+ * Live agent state. Declared readonly because mutation must go through the
294
+ * hook's return value; an in-place write is invisible to the composition
295
+ * rules and makes execution order unobservable.
296
+ */
297
+ state: Readonly<SmartState>;
298
+ /** Per-plugin, per-run scratch space. Never serialized into a snapshot. */
299
+ store: Record<string, unknown>;
300
+ /** Emit an event to the host's `onEvent`. */
301
+ emit: (event: SmartAgentEvent) => void;
302
+ logger: PluginLogger;
303
+ /** The run's cancellation signal — forward it to outbound HTTP calls. */
304
+ signal?: AbortSignal;
305
+ /** Delegation depth. 0 is the root agent; children increment it. */
306
+ depth: number;
307
+ };
308
+ /** Passed to `setup`, `tools`, `systemPrompt` and `wrapModel`. */
309
+ type PluginSetupContext = {
310
+ agentName?: string;
311
+ agentVersion?: string;
312
+ /** The agent's model, before any `wrapModel` in this plugin's own chain. */
313
+ model: unknown;
314
+ logger: PluginLogger;
315
+ /** Register a teardown callback instead of returning one from `setup`. */
316
+ onDispose: (fn: () => MaybePromise<void>) => void;
317
+ };
318
+ /**
319
+ * The single source of truth for hook payloads. Every `output` field is
320
+ * optional so that adding capability later is not a breaking change, and
321
+ * returning `undefined` always means "nothing changed".
322
+ */
323
+ interface HookMap {
324
+ /** Run is starting. Fires once per `invoke()`, including on resume. */
325
+ sessionStart: {
326
+ input: {
327
+ messages: Message[];
328
+ /** True when this invoke continues a paused/snapshotted run. */
329
+ resumed: boolean;
330
+ config?: InvokeConfig;
331
+ };
332
+ output: {
333
+ /** Replace the starting transcript (e.g. hydrate from a conversation store). */
334
+ messages?: Message[];
335
+ /** Appended to the composed system prompt for this run. */
336
+ systemPromptAppend?: string;
337
+ metadata?: Record<string, unknown>;
338
+ };
339
+ };
340
+ /**
341
+ * A new user message is entering the transcript. Input-side guardrail point.
342
+ *
343
+ * A user turn is not always a string: it can carry images, audio, video or
344
+ * files alongside its text. `text` is the concatenation of the text parts,
345
+ * `content` is the whole thing, and `attachments` is the non-text half
346
+ * normalized for policy code.
347
+ */
348
+ userPromptSubmit: {
349
+ input: {
350
+ /** Concatenated text parts. Empty string for a media-only turn. */
351
+ text: string;
352
+ /** The full content, string or parts. Return `content` to rewrite it exactly. */
353
+ content: string | ContentPart$1[];
354
+ /** Every non-text part, normalized across the unified and legacy shapes. */
355
+ attachments: MediaAttachment[];
356
+ message: Message;
357
+ };
358
+ output: {
359
+ /**
360
+ * Rewritten text — masking, normalization, injection stripping. Written
361
+ * back into the text parts, never over the whole content: assigning a
362
+ * string over a multi-part message is how an attached image disappears.
363
+ * With several text parts the replacement lands in the first and the rest
364
+ * are dropped, because the hook only ever saw their concatenation —
365
+ * return `content` when that matters.
366
+ */
367
+ text?: string;
368
+ /** Full control over the parts: reorder, drop an attachment, rewrite per part. */
369
+ content?: string | ContentPart$1[];
370
+ /** Extra system-level context appended for this turn only. */
371
+ additionalContext?: string;
372
+ decision?: "allow" | "deny";
373
+ reason?: string;
374
+ metadata?: Record<string, unknown>;
375
+ };
376
+ };
377
+ /** Immediately before every model call, including retries and finalization. */
378
+ preModelCall: {
379
+ input: {
380
+ messages: Message[];
381
+ tools: ToolInterface[];
382
+ /** Provider invoke options: signal, response_format, reasoning, … */
383
+ params: Record<string, unknown>;
384
+ model: unknown;
385
+ /** 1-based loop iteration. */
386
+ iteration: number;
387
+ };
388
+ output: {
389
+ messages?: Message[];
390
+ /** Narrow the tool menu for this call only. */
391
+ tools?: ToolInterface[];
392
+ /** Shallow-merged into the provider options — never replaces them wholesale. */
393
+ params?: Record<string, unknown>;
394
+ /** Skip the provider entirely and use this as the assistant turn. */
395
+ shortCircuit?: AIMessage;
396
+ decision?: "allow" | "deny";
397
+ reason?: string;
398
+ metadata?: Record<string, unknown>;
399
+ };
400
+ };
401
+ /** The assistant turn came back, before the loop decides what to do with it. */
402
+ postModelCall: {
403
+ input: {
404
+ message: AIMessage;
405
+ usage?: Record<string, unknown>;
406
+ durationMs: number;
407
+ iteration: number;
408
+ /** True when the message was produced by a `preModelCall` short-circuit. */
409
+ shortCircuited: boolean;
410
+ };
411
+ output: {
412
+ message?: AIMessage;
413
+ decision?: "allow" | "deny";
414
+ reason?: string;
415
+ /** Re-run this model call. Bounded by `maxModelRetries`. */
416
+ retry?: boolean;
417
+ metadata?: Record<string, unknown>;
418
+ };
419
+ };
420
+ /** After argument validation, before the approval gate. */
421
+ preToolUse: {
422
+ input: {
423
+ toolName: string;
424
+ toolCallId: string;
425
+ args: unknown;
426
+ tool: ToolInterface;
427
+ /** Tool executions already recorded in this run. */
428
+ executionCount: number;
429
+ };
430
+ output: {
431
+ /** Corrected or constrained arguments. Re-validated against the schema. */
432
+ args?: unknown;
433
+ /** `ask` escalates to human approval; it can never be downgraded to `allow`. */
434
+ decision?: HookDecision;
435
+ /** Surfaced to the model as the tool result on `deny`. */
436
+ reason?: string;
437
+ /** Prompt text when this hook raised the approval. */
438
+ approvalPrompt?: string;
439
+ /** Skip execution and use this as the tool's output (cache, mock, stub). */
440
+ result?: unknown;
441
+ metadata?: Record<string, unknown>;
442
+ };
443
+ };
444
+ /** Raw tool output, before ContextPilot compression and the hard cap. */
445
+ postToolUse: {
446
+ input: {
447
+ toolName: string;
448
+ toolCallId: string;
449
+ args: unknown;
450
+ output: unknown;
451
+ error?: Error;
452
+ durationMs: number;
453
+ executionId: string;
454
+ };
455
+ output: {
456
+ /** Rewritten output — redaction, normalization, schema coercion. */
457
+ output?: unknown;
458
+ decision?: "allow" | "deny";
459
+ reason?: string;
460
+ metadata?: Record<string, unknown>;
461
+ };
462
+ };
463
+ /** Before the summarizer runs. */
464
+ preCompact: {
465
+ input: {
466
+ reason: "token_pressure" | "manual";
467
+ messages: Message[];
468
+ tokenCount: number;
469
+ threshold: number;
470
+ };
471
+ output: {
472
+ /** Replace the candidate set (e.g. pin messages that must survive). */
473
+ messages?: Message[];
474
+ /** Skip compaction for this pass. */
475
+ skip?: boolean;
476
+ metadata?: Record<string, unknown>;
477
+ };
478
+ };
479
+ /** After a summary was produced and applied. */
480
+ postCompact: {
481
+ input: {
482
+ summary: StructuredSummary;
483
+ tokensBefore: number;
484
+ tokensAfter: number;
485
+ /** Name of the strategy that produced it — `"builtin"` when no slot is filled. */
486
+ strategy: string;
487
+ };
488
+ output: void;
489
+ };
490
+ /** The run produced a final answer and is about to return it. */
491
+ preFinalAnswer: {
492
+ input: {
493
+ content: string;
494
+ output?: unknown;
495
+ message?: AIMessage;
496
+ };
497
+ output: {
498
+ content?: string;
499
+ decision?: "allow" | "deny";
500
+ reason?: string;
501
+ /** Keep looping with this instruction instead of returning. Bounded. */
502
+ continueWith?: string;
503
+ metadata?: Record<string, unknown>;
504
+ };
505
+ };
506
+ /** A sub-agent task is about to start. */
507
+ subagentStart: {
508
+ input: {
509
+ name: string;
510
+ task: string;
511
+ depth: number;
512
+ };
513
+ output: {
514
+ task?: string;
515
+ decision?: "allow" | "deny";
516
+ reason?: string;
517
+ };
518
+ };
519
+ /** A sub-agent finished and its result is returning to the parent. */
520
+ subagentStop: {
521
+ input: {
522
+ name: string;
523
+ result: unknown;
524
+ depth: number;
525
+ durationMs?: number;
526
+ };
527
+ output: void;
528
+ };
529
+ /** Something needs a human, or a limit was hit. Observation only. */
530
+ notification: {
531
+ input: {
532
+ kind: "approval" | "user_question" | "limit" | "error";
533
+ detail: unknown;
534
+ };
535
+ output: void;
536
+ };
537
+ /** The run ended, on every exit path. */
538
+ sessionEnd: {
539
+ input: {
540
+ status: "success" | "error" | "paused" | "cancelled";
541
+ result?: AgentInvokeResult;
542
+ error?: Error;
543
+ usage?: SmartState["usage"];
544
+ durationMs: number;
545
+ };
546
+ output: void;
547
+ };
548
+ }
549
+ type HookName = keyof HookMap;
550
+ type HookHandler<K extends HookName> = (input: HookMap[K]["input"], ctx: HookContext) => MaybePromise<HookMap[K]["output"] | void>;
551
+ /** Hooks declared inline on the agent, or inside a plugin. */
552
+ type HookRegistrations = {
553
+ [K in HookName]?: HookHandler<K> | Array<HookHandler<K>>;
554
+ };
555
+ /** What a gate hook chain produced, after composition. */
556
+ type GateResult<K extends HookName> = {
557
+ decision: HookDecision;
558
+ reason?: string;
559
+ /** Plugin that produced the blocking decision, when there is one. */
560
+ deniedBy?: string;
561
+ /** The payload after every handler's mutations were applied in order. */
562
+ input: HookMap[K]["input"];
563
+ /** First short-circuit value offered, if any. */
564
+ shortCircuit?: unknown;
565
+ /** Whether any handler mutated the payload. */
566
+ mutated: boolean;
567
+ /**
568
+ * Which plugins mutated it, in the order they ran.
569
+ *
570
+ * Plugin-level, not span-level: a handler returns a rewritten payload rather
571
+ * than an op list, so "which rule changed this span" is not recoverable —
572
+ * but "which plugin changed this" is, and that is the question an audit
573
+ * trail is usually asked. A plugin that needs finer provenance reports it
574
+ * through `metadata` (piiRedaction emits the entity types it matched).
575
+ */
576
+ mutatedBy: string[];
577
+ /** Accumulated non-payload output (systemPromptAppend, additionalContext, …). */
578
+ collected: Record<string, unknown[]>;
579
+ /** Boolean flags OR-ed across handlers (skip, retry, …). */
580
+ flags: Record<string, boolean>;
581
+ /** Merged `metadata` objects from every handler. */
582
+ metadata?: Record<string, unknown>;
583
+ };
584
+ type SummarizerInput = {
585
+ /**
586
+ * The messages the SDK selected as compressable. Selection is not negotiable:
587
+ * protected tool_call ids and the recency window are correctness-critical and
588
+ * stay on the SDK side.
589
+ */
590
+ messages: Message[];
591
+ /** Prior summary for incremental mode. */
592
+ previousSummary?: StructuredSummary;
593
+ /** Latest user request, so the summary can be query-focused. */
594
+ query: string;
595
+ budget: {
596
+ targetTokens: number;
597
+ maxTokens: number;
598
+ };
599
+ /** The agent's model. A strategy is free to use a cheaper one. */
600
+ model: unknown;
601
+ mode: SummarizationMode;
602
+ };
603
+ type SummarizerResult = {
604
+ summary: StructuredSummary;
605
+ /** Provider usage, so the SDK can bill the compaction call. */
606
+ usage?: unknown;
607
+ /** Recovery references for archived tool payloads. */
608
+ archived?: Array<{
609
+ executionId: string;
610
+ ref: string;
611
+ }>;
612
+ };
613
+ type SummarizerStrategy = {
614
+ name: string;
615
+ /** Returning `null` means "could not compress" — same contract as the built-in `{}`. */
616
+ compress(input: SummarizerInput, ctx: HookContext): MaybePromise<SummarizerResult | null>;
617
+ };
618
+ type ConversationStore = {
619
+ load(threadId: string): MaybePromise<Message[] | null | undefined>;
620
+ append(threadId: string, messages: Message[]): MaybePromise<void>;
621
+ clear?(threadId: string): MaybePromise<void>;
622
+ };
623
+ type CheckpointStore = {
624
+ save(id: string, snapshot: AgentSnapshot): MaybePromise<void>;
625
+ load(id: string): MaybePromise<AgentSnapshot | null | undefined>;
626
+ list?(prefix?: string): MaybePromise<string[]>;
627
+ remove?(id: string): MaybePromise<void>;
628
+ };
629
+ type ApprovalTransport = {
630
+ /**
631
+ * Deliver a pending approval to a human and wait for the answer. Returning
632
+ * `null` leaves the run paused for the host to resolve the usual way.
633
+ */
634
+ request(pending: PendingToolApproval, ctx: HookContext): MaybePromise<ToolApprovalResolution | null>;
635
+ /** Optional: same treatment for `ask_user_question`. */
636
+ requestUserInput?(pending: PendingUserQuestion, ctx: HookContext): MaybePromise<unknown | null>;
637
+ };
638
+ type SkillSource = {
639
+ name: string;
640
+ list(ctx: PluginSetupContext): MaybePromise<Skill[]>;
641
+ };
642
+ type PromptSource = {
643
+ name: string;
644
+ /** Resolve a named, versioned prompt. `null` falls through to the default. */
645
+ resolve(key: string, ctx: HookContext): MaybePromise<string | null | undefined>;
646
+ };
647
+ type ContextBuilder = {
648
+ name: string;
649
+ build(input: {
650
+ state: SmartState;
651
+ defaultMessages: Message[];
652
+ }, ctx: HookContext): MaybePromise<Message[]>;
653
+ };
654
+ type CostEstimator = (args: {
655
+ modelName?: string;
656
+ inputTokens: number;
657
+ outputTokens: number;
658
+ cachedInputTokens?: number;
659
+ reasoningTokens?: number;
660
+ }) => number;
661
+ /**
662
+ * Slots replace an SDK default. Exactly one plugin may fill each one; two
663
+ * claimants is a construction-time error, never a silent last-one-wins.
664
+ */
665
+ type PluginProvides = {
666
+ summarizer?: SummarizerStrategy;
667
+ tokenCounter?: (text: string) => number;
668
+ costEstimator?: CostEstimator;
669
+ memoryStore?: MemoryStore;
670
+ conversationStore?: ConversationStore;
671
+ checkpointStore?: CheckpointStore;
672
+ approvalTransport?: ApprovalTransport;
673
+ skillSource?: SkillSource;
674
+ promptSource?: PromptSource;
675
+ contextBuilder?: ContextBuilder;
676
+ };
677
+ type SlotName = keyof PluginProvides;
678
+ type AgentPlugin = {
679
+ /** Unique within one agent. A duplicate is a construction-time error. */
680
+ name: string;
681
+ version?: string;
682
+ description?: string;
683
+ /** Execution order; lower runs first. Default 100. */
684
+ priority?: number;
685
+ /** How this plugin's own errors and timeouts are interpreted. Default "open". */
686
+ failureMode?: PluginFailureMode;
687
+ /** Per-handler timeout in ms. Default 10_000. */
688
+ timeoutMs?: number;
689
+ /**
690
+ * Whether children (sub-agents, `asTool` delegates) inherit this plugin.
691
+ * Default true — a policy a delegation can shed is not a policy.
692
+ */
693
+ inheritToSubagents?: boolean;
694
+ /** One-time construction. May return a disposer. */
695
+ setup?: (ctx: PluginSetupContext) => MaybePromise<void | (() => MaybePromise<void>)>;
696
+ dispose?: () => MaybePromise<void>;
697
+ hooks?: HookRegistrations;
698
+ /**
699
+ * Whether this plugin's `preToolUse` handler can return `decision: "ask"`.
700
+ * Defaults to true for any plugin that registers `preToolUse`.
701
+ *
702
+ * It exists for scheduling, not for policy: a call that may pause for a human
703
+ * has to run in the sequential group, because the parallel fan-out has already
704
+ * started its siblings by the time a pause is raised. Declaring `false` on a
705
+ * pure redaction/audit hook keeps the tool batch parallel.
706
+ */
707
+ mayRequireApproval?: boolean;
708
+ tools?: ToolInterface[] | ((ctx: PluginSetupContext) => MaybePromise<ToolInterface[]>);
709
+ systemPrompt?: string | ((current: string, ctx: PluginSetupContext) => string);
710
+ toolDescriptions?: Record<string, string | ((defaultDescription: string) => string)>;
711
+ wrapModel?: (model: unknown, ctx: PluginSetupContext) => unknown;
712
+ provides?: PluginProvides;
713
+ /** Bridge for v1 guardrails carried inside a plugin. */
714
+ guardrails?: ConversationGuardrail[];
715
+ /** Set by the SDK on internally-generated bridge plugins. */
716
+ readonly __internal?: boolean;
717
+ };
718
+ /** Everything the plugin layer contributes, resolved once per agent. */
719
+ type PluginContributions = {
720
+ tools: ToolInterface[];
721
+ toolDescriptions: Record<string, string | ((defaultDescription: string) => string)>;
722
+ guardrails: ConversationGuardrail[];
723
+ /** Applied in priority order, before any legacy `promptHooks.transformSystemPrompt`. */
724
+ applySystemPrompt: (base: string) => string;
725
+ /** Applied outermost-last, so the highest-priority plugin wraps first. */
726
+ applyModelWrappers: (model: unknown) => unknown;
727
+ };
728
+ /** Emitted so the hook layer itself is observable. */
729
+ type PluginEvent = {
730
+ type: "plugin";
731
+ plugin: string;
732
+ hook: string;
733
+ phase: "success" | "error" | "timeout";
734
+ decision?: HookDecision;
735
+ mutated?: boolean;
736
+ shortCircuited?: boolean;
737
+ reason?: string;
738
+ durationMs?: number;
739
+ error?: {
740
+ message: string;
741
+ };
742
+ };
743
+ /**
744
+ * A hook outcome worth putting on the trace timeline. Only material outcomes
745
+ * are recorded — a decision that was not `allow`, a payload mutation, a
746
+ * short-circuit, or a failure. Per-handler noise stays on the `plugin` event
747
+ * stream, where it costs nothing.
748
+ */
749
+ type PluginTraceRecord = {
750
+ plugin: string;
751
+ hook: HookName;
752
+ /** Plugins that had already rewritten this payload when the record was made. */
753
+ mutatedBy?: string[];
754
+ /**
755
+ * `skipped` for a policy deny and for a fail-open error: neither is a system
756
+ * failure, and `error` would flip the whole trace session's status for a run
757
+ * that behaved exactly as configured. `error` is reserved for a fail-closed
758
+ * failure, which does abort the run.
759
+ */
760
+ status: "success" | "error" | "skipped";
761
+ decision?: HookDecision;
762
+ mutated?: boolean;
763
+ shortCircuited?: boolean;
764
+ reason?: string;
765
+ durationMs?: number;
766
+ error?: {
767
+ message: string;
768
+ };
769
+ };
770
+ type PluginHostOptions = {
771
+ /** Emit a `plugin` event for every handler, not just the interesting ones. */
772
+ debug?: boolean;
773
+ logger?: PluginLogger;
774
+ /** Cap on `postModelCall.retry`. Default 2. */
775
+ maxModelRetries?: number;
776
+ /** Cap on `preFinalAnswer.continueWith`. Default 2. */
777
+ maxContinuations?: number;
778
+ };
779
+
780
+ /**
781
+ * Plugin layer — runtime.
782
+ *
783
+ * `createPluginHost` is agent-scoped: it validates the plugin set, resolves
784
+ * slots and contributions once, and owns setup/dispose. `beginRun` opens a
785
+ * run-scoped handle whose per-plugin stores live and die with one `invoke()`,
786
+ * which is what keeps concurrent invokes on the same agent instance isolated.
787
+ *
788
+ * Composition rules (see docs/guide/plugins.md):
789
+ * R1 order priority ascending, then registration order; stable
790
+ * R2 mutation chained — each handler sees the previous one's output
791
+ * R3 decision deny > ask > allow; the first deny short-circuits the chain
792
+ * R4 short-circuit first value offered wins, the rest are reported and dropped
793
+ * R5 errors per-plugin failureMode: "open" continues, "closed" denies
794
+ * R6 timeout per-handler, treated as an error under R5
795
+ * R7 observers never block and never fail the run
796
+ * R8 observable every decision/mutation is emitted as a `plugin` event
797
+ */
798
+
799
+ declare const HOOK_NAMES: HookName[];
800
+ declare class HookTimeoutError extends Error {
801
+ constructor(label: string, ms: number);
802
+ }
803
+ type PluginRunHost = {
804
+ /** Cheap guard so call sites can skip building payloads when nothing listens. */
805
+ has(hook: HookName): boolean;
806
+ /** Cap on `postModelCall.retry` for this run. */
807
+ readonly maxModelRetries: number;
808
+ /** Cap on `preFinalAnswer.continueWith` for this run. */
809
+ readonly maxContinuations: number;
810
+ /**
811
+ * True when some registered `preToolUse` plugin may return `ask`. Call sites
812
+ * use it to keep such calls out of the parallel fan-out.
813
+ */
814
+ readonly mayPauseOnToolUse: boolean;
815
+ runGate<K extends HookName>(hook: K, input: HookMap[K]["input"]): Promise<GateResult<K>>;
816
+ runObservers<K extends HookName>(hook: K, input: HookMap[K]["input"]): Promise<void>;
817
+ /** Release per-run plugin stores. */
818
+ end(): void;
819
+ };
820
+ type PluginHost = {
821
+ readonly plugins: AgentPlugin[];
822
+ readonly slots: PluginProvides;
823
+ readonly contributions: PluginContributions;
824
+ readonly maxModelRetries: number;
825
+ readonly maxContinuations: number;
826
+ has(hook: HookName): boolean;
827
+ hasAny(): boolean;
828
+ /** True when some `preToolUse` plugin may escalate a call to human approval. */
829
+ mayPauseOnToolUse(): boolean;
830
+ /** Resolve contributions and run every `setup`. Idempotent; a failure sticks. */
831
+ setup(ctx: Omit<PluginSetupContext, "onDispose" | "logger"> & {
832
+ logger?: PluginLogger;
833
+ }): Promise<void>;
834
+ dispose(): Promise<void>;
835
+ beginRun(opts: {
836
+ runId: string;
837
+ agentName?: string;
838
+ getState: () => SmartState;
839
+ emit?: (event: SmartAgentEvent) => void;
840
+ /** Put a material hook outcome on the trace timeline. */
841
+ recordTrace?: (record: PluginTraceRecord) => void;
842
+ signal?: AbortSignal;
843
+ depth?: number;
844
+ }): PluginRunHost;
845
+ /** The subset a child agent inherits. */
846
+ childPlugins(): AgentPlugin[];
847
+ };
848
+ declare function createPluginHost(plugins?: AgentPlugin[], options?: PluginHostOptions): PluginHost;
849
+
110
850
  /**
111
851
  * Sub-agent primitive — dynamic problem-solving by delegating self-contained
112
852
  * subtasks to focused child agents.
@@ -237,91 +977,6 @@ type SubagentToolNames = {
237
977
  };
238
978
  declare const DEFAULT_SUBAGENT_TOOL_NAMES: SubagentToolNames;
239
979
 
240
- /**
241
- * Skill primitive — progressive capability disclosure for the smart agent.
242
- *
243
- * A Skill is a lazy, self-contained capability bundle. The model discovers a
244
- * skill by its cheap one-line `header`, then calls `open_skill(key)` to load the
245
- * skill's prompt and (for small skills) bind its tools, or
246
- * `bind_skill_tools(key, names)` to bind a chosen subset of a fat skill. This
247
- * keeps the number of bound tools per step small — the property small models
248
- * need — and replaces an up-front tool-selector pass with on-demand disclosure.
249
- *
250
- * Discovery itself comes in two flavors, see `SkillPolicy.disclosure`: the
251
- * headers can be listed in the system prompt, or looked up with `search_skills`.
252
- */
253
- type SkillToolHeader = {
254
- name: string;
255
- description?: string;
256
- };
257
- type SkillModelTier = "small" | "large";
258
- /**
259
- * How the model finds out which skills exist.
260
- *
261
- * - `"catalog"` (default): every available skill's header is rendered into the
262
- * system prompt as `<available_skills>`. Cheapest possible discovery — the
263
- * model needs no tool call — but the prompt grows with the catalog, and the
264
- * whole catalog is paid for on every single turn of every conversation.
265
- * - `"search"`: nothing goes into the prompt. The model finds skills through
266
- * the `search_skills` tool, whose description is the only always-on cost.
267
- * Prompt cost is constant, so this is the mode for a catalog that is large,
268
- * workspace-supplied, or mostly irrelevant to any one conversation. The
269
- * trade-off is real: a model that never calls `search_skills` never learns
270
- * the skills exist, so keep the tool description explicit about when to call.
271
- */
272
- type SkillDisclosure = "catalog" | "search";
273
- type Skill = {
274
- /** Stable key, e.g. "mcp:atlassian" | "integration:google" | "builtin:drawio". */
275
- key: string;
276
- title: string;
277
- /** One-line "what + when to use" the model always sees in the catalog. */
278
- header: string;
279
- /** Injected (as the open_skill result) only after the skill is opened. */
280
- prompt: string | (() => Promise<string> | string);
281
- /** When true, opening this skill should trigger sandbox bootstrap. */
282
- needsSandbox?: boolean;
283
- /** Gate: a "large"-only skill is hidden from a small-tier model. */
284
- minModelTier?: SkillModelTier;
285
- /** Whether the skill is usable in the current workspace (integration connected, etc.). */
286
- isAvailable?: () => boolean | Promise<boolean>;
287
- /** Cheap list of the skill's tool headers (names + one-liners). */
288
- listToolIndex: () => Promise<SkillToolHeader[]> | SkillToolHeader[];
289
- /** Bind concrete tools. With no names, bind the whole (small) skill. */
290
- bindTools: (names?: string[]) => Promise<ToolInterface[]> | ToolInterface[];
291
- /** Optional embedding/heuristic ranking of tool headers for a fat skill. */
292
- rankToolHeaders?: (query: string, headers: SkillToolHeader[]) => Promise<SkillToolHeader[]> | SkillToolHeader[];
293
- /** Deterministic floor: tools to bind when a weak model gives no usable query. */
294
- defaultBindNames?: string[];
295
- };
296
- type SkillPolicy = {
297
- /** Max distinct skills open at once (small tier should be 1). */
298
- maxOpenSkills: number;
299
- /** Max tools bound from a single skill in one bind call. */
300
- maxBoundToolsPerSkill: number;
301
- /** Overall cap on skill-bound tools across the whole run. */
302
- maxBoundToolsTotal: number;
303
- /** Current model tier; gates `minModelTier`. */
304
- modelTier?: SkillModelTier;
305
- /** How the model discovers skills. Defaults to `"catalog"`. */
306
- disclosure?: SkillDisclosure;
307
- };
308
- declare const DEFAULT_SKILL_POLICY: SkillPolicy;
309
- declare const SMALL_TIER_SKILL_POLICY: SkillPolicy;
310
- /**
311
- * Mutable per-invoke registry. The skill tools mutate this ref (append-only) and
312
- * call `__onToolsChanged` so the runtime can rebuild its tool sets. Mirrors the
313
- * stateRef pattern used by createAskUserQuestionTool.
314
- */
315
- type SkillRegistryRef = {
316
- /** Append-only: skills the model has opened this run. */
317
- openedSkillKeys: string[];
318
- /** Append-only, deduped by tool name: tools bound from opened skills. */
319
- boundSkillTools: ToolInterface[];
320
- /** Rebuild hook wired by createSmartAgent; rebuilds both recovery variants. */
321
- __onToolsChanged?: () => void;
322
- };
323
- declare function createSkillRegistryRef(): SkillRegistryRef;
324
-
325
980
  type ContextPilotJsonCompressionConfig = {
326
981
  enabled?: boolean;
327
982
  /** Fraction (0-1) of array items to retain. Lower = more aggressive. */
@@ -545,6 +1200,17 @@ type ConversationGuardrail = {
545
1200
  description?: string;
546
1201
  appliesTo: GuardrailPhase[];
547
1202
  rules: GuardrailRule[];
1203
+ /**
1204
+ * What a rule THROWING means. `"closed"` (the default, and the historical
1205
+ * behaviour) turns the error into a block. `"open"` records a warning and
1206
+ * lets the turn continue.
1207
+ *
1208
+ * The distinction matters because a rule that reaches a database or a policy
1209
+ * service fails transiently, and under `"closed"` one blip hard-blocks every
1210
+ * turn until it clears — a availability decision the guardrail author should
1211
+ * be making deliberately rather than inheriting.
1212
+ */
1213
+ failureMode?: "open" | "closed";
548
1214
  haltOnViolation?: boolean;
549
1215
  onViolation?: (incident: GuardrailIncident, context: GuardrailContext) => Promise<GuardrailDisposition | void> | GuardrailDisposition | void;
550
1216
  metadata?: Record<string, any>;
@@ -683,6 +1349,19 @@ type AgentOptions = {
683
1349
  * passed explicitly.
684
1350
  */
685
1351
  contextPilot?: ContextPilotConfig;
1352
+ /**
1353
+ * Plugins: named bundles of hooks, contributions and strategy slots. See
1354
+ * {@link AgentPlugin} and docs/guide/plugins.md.
1355
+ */
1356
+ plugins?: AgentPlugin[];
1357
+ /**
1358
+ * Inline hooks, for the cases where naming a plugin would be ceremony. They
1359
+ * are wrapped into an anonymous plugin that runs at the default priority,
1360
+ * after any explicitly lower-priority plugin.
1361
+ */
1362
+ hooks?: HookRegistrations;
1363
+ /** Tuning for the plugin host (retry/continuation caps, debug events). */
1364
+ pluginOptions?: PluginHostOptions;
686
1365
  };
687
1366
  type ReasoningLevel = "minimal" | "low" | "medium" | "high";
688
1367
  type ReflectionCadence = "off" | "every_turn" | "after_tool" | "on_branch" | "initial_then_after_tool";
@@ -1059,6 +1738,12 @@ type SmartAgentOptions = {
1059
1738
  * catalog block. See {@link PromptHooks}.
1060
1739
  */
1061
1740
  promptHooks?: PromptHooks;
1741
+ /** See AgentOptions.plugins. */
1742
+ plugins?: AgentPlugin[];
1743
+ /** See AgentOptions.hooks. */
1744
+ hooks?: HookRegistrations;
1745
+ /** See AgentOptions.pluginOptions. */
1746
+ pluginOptions?: PluginHostOptions;
1062
1747
  };
1063
1748
  /**
1064
1749
  * Override points for the SDK's built-in (otherwise static) prompt surfaces.
@@ -1834,7 +2519,7 @@ type DelegationEventStamp = {
1834
2519
  /** Name of the `asTool` child agent this forwarded event came from. */
1835
2520
  delegatedTo?: string;
1836
2521
  };
1837
- type SmartAgentEvent = (ToolCallEvent | ToolApprovalEvent | UserQuestionEvent | PlanEvent | SummarizationEvent | FinalAnswerEvent | MetadataEvent | HandoffEvent | GuardrailEvent | ProgressEvent | StreamEvent | CancelledEvent | SubagentEvent | ReflectionEvent) & DelegationEventStamp;
2522
+ type SmartAgentEvent = (ToolCallEvent | ToolApprovalEvent | UserQuestionEvent | PlanEvent | SummarizationEvent | FinalAnswerEvent | MetadataEvent | HandoffEvent | GuardrailEvent | ProgressEvent | StreamEvent | CancelledEvent | SubagentEvent | ReflectionEvent | PluginEvent) & DelegationEventStamp;
1838
2523
  type ReflectionEvent = {
1839
2524
  type: "reflection";
1840
2525
  id: string;
@@ -1889,6 +2574,23 @@ type InvokeConfig = RunnableConfig & {
1889
2574
  * unavailable keys are skipped. Ignored when the agent has no `skills`.
1890
2575
  */
1891
2576
  preopenedSkills?: string[];
2577
+ /**
2578
+ * @internal Session handle threaded from createSmartAgent's driver into each
2579
+ * `base.invoke()` leg. It is what makes one logical turn one plugin session:
2580
+ * whoever creates it owns sessionStart/sessionEnd/preFinalAnswer, and the
2581
+ * legs that inherit it fire none of the three.
2582
+ *
2583
+ * Deliberately NOT carried on `state.ctx`. A handle on ctx rides out on
2584
+ * `result.state` and comes back in on the next `invoke(previousState)`, which
2585
+ * makes two concurrent continuations share one store and one run id.
2586
+ */
2587
+ __pluginSession?: {
2588
+ host: PluginRunHost;
2589
+ runId: string;
2590
+ stateHolder: {
2591
+ value: SmartState;
2592
+ };
2593
+ };
1892
2594
  };
1893
2595
  type SnapshotRuntimeHint = {
1894
2596
  name?: string;
@@ -1932,6 +2634,15 @@ type AgentInvokeResult<TOutput = unknown> = {
1932
2634
  state?: SmartState;
1933
2635
  };
1934
2636
  type AgentInstance<TOutput = unknown> = {
2637
+ /**
2638
+ * Release plugin-held resources (HTTP clients, MCP connections, batch
2639
+ * buffers). Safe to skip for plugin-free agents; safe to call twice.
2640
+ */
2641
+ dispose?: () => Promise<void>;
2642
+ /** Internal: the agent's plugin host, used to seed child agents. */
2643
+ __plugins?: unknown;
2644
+ /** Composed plugin systemPrompt contribution; run-scoped, never serialized. */
2645
+ __applySystemPromptContribution?: unknown;
1935
2646
  invoke: (input: SmartState, config?: InvokeConfig) => Promise<AgentInvokeResult<TOutput>>;
1936
2647
  snapshot: (state: SmartState, options?: SnapshotOptions) => AgentSnapshot;
1937
2648
  resume: (snapshot: AgentSnapshot, config?: InvokeConfig, restoreOptions?: RestoreSnapshotOptions) => Promise<AgentInvokeResult<TOutput>>;
@@ -2003,6 +2714,13 @@ declare function createTool({ name, description, schema, func, needsApproval, ap
2003
2714
 
2004
2715
  declare function buildSystemPrompt(extra?: string, planning?: boolean | PlanningMode, name?: string, todoListPrompt?: string): string;
2005
2716
 
2717
+ /**
2718
+ * Turn handoff descriptors into the tools that expose them to the model.
2719
+ *
2720
+ * Shared with createSmartAgent, which builds its own per-invoke tool set and
2721
+ * would otherwise never see these — a typed, documented option doing nothing.
2722
+ */
2723
+ declare function buildHandoffTools(handoffs: HandoffDescriptor[]): any[];
2006
2724
  declare function createAgent<TOutput = unknown>(opts: AgentOptions & {
2007
2725
  outputSchema?: ZodSchema<TOutput>;
2008
2726
  }): AgentInstance<TOutput>;
@@ -2562,12 +3280,12 @@ declare const guardianSchema: z.ZodObject<{
2562
3280
  }, "strip", z.ZodTypeAny, {
2563
3281
  allow: boolean;
2564
3282
  reason?: string | undefined;
2565
- disposition?: "block" | "warn" | "allow" | undefined;
3283
+ disposition?: "allow" | "block" | "warn" | undefined;
2566
3284
  details?: Record<string, any> | undefined;
2567
3285
  }, {
2568
3286
  allow: boolean;
2569
3287
  reason?: string | undefined;
2570
- disposition?: "block" | "warn" | "allow" | undefined;
3288
+ disposition?: "allow" | "block" | "warn" | undefined;
2571
3289
  details?: Record<string, any> | undefined;
2572
3290
  }>;
2573
3291
  type AgentRuleOptions = {
@@ -2623,400 +3341,301 @@ type CodeGuardrailOptions = GuardrailPresetBase & {
2623
3341
  declare function createCodeGuardrail(options?: CodeGuardrailOptions): ConversationGuardrail;
2624
3342
 
2625
3343
  /**
2626
- * Centralized manager for structured output across both base Agent and SmartAgent.
3344
+ * Wrap a plugin factory so config flows through with full inference:
2627
3345
  *
2628
- * Responsibilities:
2629
- * - Prepare tools or response_format depending on the resolved strategy
2630
- * - Build system prompt hints tailored to the strategy
2631
- * - Build nudge/correction prompts for retries
2632
- * - Parse final output from tool result or assistant content
2633
- * - Report structured errors (never silently swallow)
3346
+ * const myGuard = definePlugin<{ level: number }>((cfg) => ({ name: "my-guard", ... }));
3347
+ * myGuard({ level: 2 })
3348
+ *
3349
+ * The indirection buys nothing at runtime — it exists so the config type is
3350
+ * inferred at the call site and the returned object is checked against
3351
+ * `AgentPlugin` at the definition site, where the error message is useful.
2634
3352
  */
2635
- declare class StructuredOutputManager<T> {
2636
- readonly strategy: StructuredOutputStrategy;
2637
- readonly schema: ZodSchema<T>;
2638
- readonly maxRetries: number;
2639
- constructor(schema: ZodSchema<T>, strategy: StructuredOutputStrategy, config?: StructuredOutputManagerConfig);
2640
- /**
2641
- * Get the `response` tool for tool-based strategy.
2642
- * Returns undefined for native strategy (no tool needed).
2643
- */
2644
- getResponseTool(): ToolInterface | undefined;
2645
- /**
2646
- * Get response_format config for native strategy.
2647
- * Returns undefined for tool-based strategy.
2648
- */
2649
- getResponseFormat(): Record<string, any> | undefined;
2650
- /**
2651
- * Build the system prompt hint that tells the model how to produce structured output.
2652
- */
2653
- buildSystemPromptHint(): string;
2654
- /**
2655
- * Build a nudge message for when the model didn't produce structured output.
2656
- * Used by the agent loop when it needs to retry.
2657
- * User role is intentional: OpenAI-compatible chat templates such as Qwen
2658
- * reject system messages anywhere except the beginning of the conversation.
2659
- */
2660
- buildNudgeMessage(isLastAttempt: boolean): {
2661
- role: string;
2662
- content: string;
2663
- };
2664
- /**
2665
- * Build a correction message when schema validation failed.
2666
- */
2667
- buildCorrectionMessage(error: StructuredOutputError, _previousAttempt?: unknown): {
2668
- role: string;
2669
- content: string;
2670
- };
2671
- /**
2672
- * Try to parse structured output from the tool-based finalization result.
2673
- * Called when __structuredOutputParsed is available in ctx.
2674
- */
2675
- parseFromToolResult(data: unknown): StructuredOutputResult<T>;
2676
- /**
2677
- * Try to parse structured output from assistant message content.
2678
- * For native strategy: content should be valid JSON.
2679
- * For tool-based strategy: last-resort fallback extraction from text.
2680
- */
2681
- parseFromContent(content: string): StructuredOutputResult<T>;
2682
- /**
2683
- * Create a "no output" error result.
2684
- */
2685
- noOutputResult(attempts: number, rawContent?: string): StructuredOutputResult<T>;
3353
+ declare function definePlugin<TConfig = void>(factory: (config: TConfig) => AgentPlugin): (config: TConfig) => AgentPlugin;
3354
+ /**
3355
+ * A single hook, packaged as a plugin. For the common case where naming and a
3356
+ * lifecycle would be ceremony:
3357
+ *
3358
+ * defineHook("preToolUse", ({ toolName }) => toolName === "shell" ? { decision: "ask" } : undefined)
3359
+ */
3360
+ declare function defineHook<K extends HookName>(hook: K, handler: HookHandler<K>, opts?: {
3361
+ name?: string;
3362
+ priority?: number;
3363
+ failureMode?: PluginFailureMode;
3364
+ timeoutMs?: number;
3365
+ inheritToSubagents?: boolean;
2686
3366
  /**
2687
- * Create a "max retries" error result.
3367
+ * Declare that this hook never returns `decision: "ask"`. Without it a
3368
+ * `preToolUse` hook is assumed to be able to pause, and the whole tool
3369
+ * batch is scheduled serially — silently costing an agent its parallel
3370
+ * tool execution.
2688
3371
  */
2689
- maxRetriesResult(lastError: StructuredOutputError, attempts: number, rawContent?: string): StructuredOutputResult<T>;
2690
- }
3372
+ mayRequireApproval?: boolean;
3373
+ }): AgentPlugin;
2691
3374
 
2692
3375
  /**
2693
- * Tool-based structured output strategy.
3376
+ * What this build actually implements.
2694
3377
  *
2695
- * Injects a hidden `response` tool that the model must call with the final JSON.
2696
- * This is the universal fallback that works with all providers.
3378
+ * A policy configured as `mode: "enforce"` whose hook is never called is worse
3379
+ * than no policy: the console shows a control that does not exist. A host
3380
+ * cannot infer that from the type surface, because a declared hook and a wired
3381
+ * one look identical to TypeScript — so the runtime states it.
3382
+ *
3383
+ * This table is maintained BY HAND alongside the wiring. That is deliberate:
3384
+ * deriving it from the registry would only prove that a handler was registered,
3385
+ * not that any call site raises it, which is precisely the failure it exists to
3386
+ * make visible.
2697
3387
  */
2698
- declare class ToolBasedStrategy implements StructuredOutputStrategy {
2699
- readonly kind: "tool_based";
2700
- /**
2701
- * Create the `response` tool for a given Zod schema.
2702
- * The tool validates input against the schema and returns a sentinel object
2703
- * that the tools node picks up to finalize the structured output.
2704
- */
2705
- createResponseTool<T>(schema: ZodSchema<T>): ToolInterface;
2706
- /**
2707
- * Try to extract structured output from raw assistant text content.
2708
- * Used as a last resort when the model writes JSON directly instead of calling the tool.
2709
- */
2710
- extractFromText<T>(content: string, schema: ZodSchema<T>): {
2711
- data: T;
2712
- } | {
2713
- error: StructuredOutputError;
2714
- };
2715
- buildCorrectionPrompt(error: ZodError<any>, previousAttempt: unknown): string;
2716
- }
2717
3388
 
2718
3389
  /**
2719
- * Native JSON Schema strategy for providers that support `response_format`.
3390
+ * Bumped when the hook contract changes shape in a way a host must notice —
3391
+ * a hook gains or loses a call site, a payload field changes meaning, a slot
3392
+ * starts or stops being consumed. Independent of the package version.
3393
+ */
3394
+ declare const HOOK_CONTRACT_VERSION = 1;
3395
+ type CapabilityStatus = {
3396
+ /** True when a call site in the runtime actually raises this. */
3397
+ implemented: boolean;
3398
+ /** Why not, or what the caveat is. */
3399
+ notes?: string;
3400
+ };
3401
+ type SdkCapabilities = {
3402
+ hookContractVersion: number;
3403
+ hooks: Record<HookName, CapabilityStatus>;
3404
+ slots: Record<SlotName, CapabilityStatus>;
3405
+ features: Record<string, CapabilityStatus>;
3406
+ };
3407
+ /**
3408
+ * Hook ids used by the Cognipeer Console's guardrail plane, mapped onto this
3409
+ * SDK's hooks.
2720
3410
  *
2721
- * Works with OpenAI (gpt-4o+), Google Gemini, and similar providers
2722
- * that accept `response_format: { type: "json_schema", json_schema: {...} }`.
3411
+ * The Console plane originally had one input stage, which collapsed two
3412
+ * moments that behave differently: `userPromptSubmit` fires ONCE for a new
3413
+ * user turn and can see attachments, while `preModelCall` fires before EVERY
3414
+ * provider call — which is where the legacy `GuardrailPhase.Request` actually
3415
+ * ran. A policy meant to vet what a person typed wants the first; one meant to
3416
+ * vet every prompt reaching the model, including turns built from tool output,
3417
+ * wants the second. Mapping both to one id silently changes how often the
3418
+ * policy runs, and on a moderation-model guardrail that is a cost as well as a
3419
+ * semantics bug.
2723
3420
  *
2724
- * The model guarantees valid JSON output matching the schema — no tool needed.
3421
+ * The Console added `prompt.pre` for the first and kept `input.pre` meaning
3422
+ * the second, so every id below is single-valued.
2725
3423
  */
2726
- declare class NativeJsonSchemaStrategy implements StructuredOutputStrategy {
2727
- readonly kind: "native";
2728
- private resolveJsonPointer;
2729
- private unwrapRootObjectSchema;
3424
+ declare const CONSOLE_HOOK_MAP: Readonly<Record<string, HookName | null>>;
3425
+ /** What this build implements. Safe to call at any time; allocates a fresh copy. */
3426
+ declare function pluginCapabilities(): SdkCapabilities;
3427
+ /** Convenience for a host that only wants to know whether it can enforce. */
3428
+ declare function isHookImplemented(hook: HookName): boolean;
3429
+
3430
+ /**
3431
+ * Guardrail transport + the plugin that drives it.
3432
+ *
3433
+ * Layered the way tracing sinks are layered — a transport seam, a generic HTTP
3434
+ * implementation, an in-process escape hatch, and thin first-party presets on
3435
+ * top (see `cognipeerGuardrail`, `portkeyGuardrail`). What is deliberately NOT
3436
+ * copied from tracing is its retry policy: a trace post can afford four
3437
+ * attempts at an 8s timeout because nothing waits on it, while a guardrail sits
3438
+ * on the critical path of every turn and the same policy would stall an agent
3439
+ * for half a minute.
3440
+ */
3441
+
3442
+ /**
3443
+ * `tool` is the ARGUMENTS a model wants to run; `tool_result` is what came
3444
+ * back. They are different surfaces with different risks — one is an action
3445
+ * about to happen, the other is untrusted content entering the context — and a
3446
+ * policy usually wants different rules for each.
3447
+ */
3448
+ type GuardrailPhaseName = "input" | "output" | "tool" | "tool_result";
3449
+ type GuardrailRequest = {
3450
+ phase: GuardrailPhaseName;
3451
+ content: string;
3452
+ /** Tool name for `tool` / `tool_result`, otherwise unset. */
3453
+ subject?: string;
3454
+ /** The SDK hook this check was raised from, so a preset can map it exactly. */
3455
+ hook?: string;
3456
+ /** Structured tool arguments, for a service that wants them un-stringified. */
3457
+ toolArgs?: unknown;
3458
+ /** The tool's return value, for `tool_result`. */
3459
+ toolResult?: unknown;
2730
3460
  /**
2731
- * Convert a Zod schema to the JSON Schema object used in response_format.
3461
+ * Non-text parts of the turn — images, audio, video, files. A text-only
3462
+ * policy sees the caption and nothing else, so a service that moderates
3463
+ * media needs these; one that does not simply ignores the field.
3464
+ *
3465
+ * Inline payloads are DESCRIBED (kind, media type, size) rather than
3466
+ * inlined: shipping a base64 image on every check would multiply the cost of
3467
+ * the guardrail by the size of the upload. A service that needs the bytes
3468
+ * should take a URL, or the caller should override `buildRequest`.
2732
3469
  */
2733
- toJsonSchema(schema: ZodSchema<any>, name?: string): Record<string, any>;
3470
+ attachments?: MediaAttachment[];
3471
+ metadata?: Record<string, unknown>;
3472
+ };
3473
+ type GuardrailViolation = {
3474
+ id?: string;
3475
+ type?: string;
3476
+ severity?: string;
3477
+ detail?: string;
3478
+ };
3479
+ type GuardrailVerdict = {
3480
+ action: "allow" | "block" | "mask";
3481
+ message?: string;
3482
+ /** Required when `action === "mask"`. */
3483
+ maskedContent?: string;
3484
+ violations?: GuardrailViolation[];
3485
+ /** The untouched service response, for tracing and debugging. */
3486
+ raw?: unknown;
3487
+ };
3488
+ type GuardrailCallContext = {
3489
+ runId: string;
3490
+ agentName?: string;
3491
+ /** Correlates a guardrail decision with the trace session in the console UI. */
3492
+ traceId?: string;
3493
+ signal?: AbortSignal;
3494
+ };
3495
+ type GuardrailTransport = {
3496
+ name: string;
3497
+ /** Verdicts must come back in the same order as `requests`. */
3498
+ evaluate(requests: GuardrailRequest[], ctx: GuardrailCallContext): MaybePromise<GuardrailVerdict[]>;
2734
3499
  /**
2735
- * Build response_format configuration for the model call.
2736
- * Returns the object that should be spread into model invocation options.
3500
+ * Optional setup-time handshake. When a service can say which phases carry
3501
+ * active rules, every other phase skips the network entirely — usually the
3502
+ * single biggest latency win available here.
2737
3503
  */
2738
- buildResponseFormat(schema: ZodSchema<any>, name?: string): Record<string, any>;
3504
+ describe?: () => MaybePromise<{
3505
+ activePhases?: GuardrailPhaseName[];
3506
+ } | null | undefined>;
3507
+ close?: () => MaybePromise<void>;
3508
+ };
3509
+ type HttpGuardrailOptions = {
3510
+ url: string;
3511
+ /** Static headers, or a thunk so a rotating token is read per call. */
3512
+ headers?: Record<string, string> | (() => Record<string, string>);
3513
+ /** Hard ceiling per attempt. Default 3000ms — this is on the critical path. */
3514
+ timeoutMs?: number;
3515
+ /** Retries after the first attempt. Default 1. */
3516
+ retries?: number;
3517
+ /** Send all pending checks in one request. Default true. */
3518
+ batch?: boolean;
3519
+ /** Override the wire request. Default: `{ items, runId, traceId }`. */
3520
+ buildRequest?: (requests: GuardrailRequest[], ctx: GuardrailCallContext) => unknown;
3521
+ /** Override response mapping. Default: `normalizeVerdicts`, which is forgiving. */
3522
+ mapVerdict?: (response: unknown, requests: GuardrailRequest[]) => GuardrailVerdict[];
2739
3523
  /**
2740
- * Parse and validate model response content.
2741
- * With native support, content is guaranteed JSON — but we still validate with Zod
2742
- * for type safety and field-level error reporting.
3524
+ * Status codes that carry a VERDICT rather than an error. Some services
3525
+ * signal the outcome in the status line (e.g. 446 for a block); treating
3526
+ * those as transport failures would route a real decision through the
3527
+ * failureMode path with the wrong reason attached.
2743
3528
  */
2744
- extractOutput<T>(content: string, schema: ZodSchema<T>): {
2745
- data: T;
2746
- } | {
2747
- error: StructuredOutputError;
3529
+ verdictStatuses?: number[];
3530
+ /** Optional GET endpoint for the setup-time handshake. */
3531
+ describeUrl?: string;
3532
+ name?: string;
3533
+ };
3534
+ /**
3535
+ * Accepts the shapes a guardrail service is likely to return and normalizes
3536
+ * them. Being forgiving here is the point: the exact contract can change on the
3537
+ * service side without a client release, and a stricter parser would turn a
3538
+ * cosmetic field rename into an outage.
3539
+ */
3540
+ declare function normalizeVerdicts(response: unknown, requests: GuardrailRequest[]): GuardrailVerdict[];
3541
+ declare function httpGuardrail(options: HttpGuardrailOptions): GuardrailTransport;
3542
+ /** In-process evaluation — regex policies, a local model, Presidio, tests. */
3543
+ declare function customGuardrail(evaluate: (request: GuardrailRequest, ctx: GuardrailCallContext) => MaybePromise<GuardrailVerdict | void>, name?: string): GuardrailTransport;
3544
+ type GuardrailPluginOptions = {
3545
+ name: string;
3546
+ transport: GuardrailTransport;
3547
+ /** Which surfaces to check. Default: input + output. */
3548
+ apply?: GuardrailPhaseName[];
3549
+ /**
3550
+ * `shadow` evaluates and reports but never blocks or masks. This is how a
3551
+ * policy gets rolled out safely: measure what it would have caught first.
3552
+ */
3553
+ mode?: "enforce" | "shadow";
3554
+ /** Block when the service is unreachable. Default true. */
3555
+ failClosed?: boolean;
3556
+ timeoutMs?: number;
3557
+ priority?: number;
3558
+ inheritToSubagents?: boolean;
3559
+ /** Memoize verdicts per run. Default true. */
3560
+ cache?: boolean | {
3561
+ maxEntries?: number;
2748
3562
  };
2749
- buildCorrectionPrompt(error: ZodError<any>, previousAttempt: unknown): string;
2750
- }
3563
+ /** Extra metadata attached to every request. */
3564
+ metadata?: Record<string, unknown>;
3565
+ };
3566
+ declare function createGuardrailPlugin(options: GuardrailPluginOptions): AgentPlugin;
2751
3567
 
2752
3568
  /**
2753
- * Resolve the most appropriate structured output strategy for a given model.
3569
+ * Cognipeer Console guardrail — the first-party preset.
2754
3570
  *
2755
- * If the model exposes capabilities (via adapter or direct provider),
2756
- * we use native JSON Schema support when available. Otherwise we fall back
2757
- * to the universal tool-based approach.
3571
+ * Talks to the Console's HOOK plane, not its single-shot evaluator:
2758
3572
  *
2759
- * When direct providers are added to the SDK, they should set
2760
- * `model.capabilities.structuredOutput = "native"` for providers that support
2761
- * response_format (OpenAI, Gemini, etc.).
2762
- */
2763
- declare function resolveStrategy(model: any): StructuredOutputStrategy;
2764
- /**
2765
- * Extract capabilities from a model object.
2766
- * Supports:
2767
- * - model.capabilities (set by adapters or direct providers)
2768
- * - Auto-detection from model class name / metadata
3573
+ * POST {baseUrl}/api/client/v1/guardrails/hooks/evaluate
3574
+ * Authorization: Bearer <api key>
3575
+ * { hook, guardrail_keys, text?, tool_name?, tool_args?, tool_result?, … }
3576
+ *
3577
+ * Three properties of that contract shape everything below, and getting any of
3578
+ * them wrong turns a working policy into a silent one:
3579
+ *
3580
+ * `decision` is the EFFECTIVE verdict, already neutralised in monitor mode.
3581
+ * Priority runs block > redact > warn > flag > allow.
3582
+ * `enforced` false means the decision was NOT applied — a dry run. Blocking
3583
+ * on `decision === "block"` without checking this turns every
3584
+ * monitoring policy into an enforcing one on the day it is
3585
+ * switched on for observation.
3586
+ * `passed` means "no blocking finding", NOT "the request was allowed".
3587
+ * The two diverge in monitor mode, which is exactly when someone
3588
+ * reads the wrong one.
3589
+ *
3590
+ * `subject` (or `redacted_text` for the text case) is filled only when the
3591
+ * service actually rewrote something; when it is present it REPLACES what was
3592
+ * sent rather than being merged with it.
3593
+ *
3594
+ * The endpoint answers 200 for a finding as readily as for a clean check, and
3595
+ * only emits 246/446 when a guardrail opts into verdict status codes — so both
3596
+ * are declared as verdict-carrying rather than treated as transport failures.
3597
+ * An unknown key answers 404 ON PURPOSE: a vacuous allow read as "content is
3598
+ * safe" is the failure the whole plane exists to avoid.
2769
3599
  */
2770
- declare function getModelCapabilities(model: any): ModelCapabilities;
2771
-
2772
- declare function captureSnapshot(state: SmartState, options?: SnapshotOptions): AgentSnapshot;
2773
- declare function restoreSnapshot(snapshot: AgentSnapshot, restoreOptions?: RestoreSnapshotOptions): SmartState;
2774
-
2775
- declare function resolveToolApprovalState(state: SmartState, resolution: ToolApprovalResolution): SmartState;
2776
-
2777
- declare function resolveUserQuestionState(state: SmartState, resolution: UserQuestionResolution): SmartState;
2778
3600
 
2779
- /**
2780
- * The built-in ask-user tool's name. Exported because more than one layer has to
2781
- * recognise it: `createSmartAgent` builds the tool into the list it hands to
2782
- * `createAgent`, which must then not attach a second one of its own.
2783
- */
2784
- declare const ASK_USER_TOOL_NAME = "ask_user_question";
2785
- type AskUserStateRef = {
2786
- pendingUserQuestions?: PendingUserQuestion[];
2787
- ctx?: Record<string, any>;
2788
- __onEvent?: (event: any) => void;
2789
- __currentToolCallId?: string;
2790
- };
2791
- declare function createAskUserQuestionTool(stateRef: AskUserStateRef, config: HumanInTheLoopAskUserConfig): ToolInterface<any, any, any>;
2792
-
2793
- declare function fromLangchainTools<T extends ToolInterface = ToolInterface>(tools: any[]): T[];
2794
-
2795
- type ResolvedReflectionConfig = {
2796
- enabled: boolean;
2797
- cadence: ReflectionCadence;
2798
- mode: "piggyback" | "separate";
2799
- maxTokens: number;
2800
- maxChars: number;
2801
- keepLast: number;
2802
- summarize: boolean;
2803
- promptTemplate?: string;
2804
- emitEvents: boolean;
2805
- maxPerRun?: number;
2806
- everyNTurns: number;
2807
- feedTo: "memory" | "plan" | "none";
2808
- shouldReflect?: (ctx: ReflectionHookContext) => boolean;
2809
- buildPrompt?: (ctx: ReflectionHookContext & {
2810
- defaultPrompt: string;
2811
- maxChars: number;
2812
- }) => string;
2813
- onReflection?: (record: ReflectionRecord, ctx: ReflectionHookContext) => void;
2814
- };
2815
- type ResolvedReasoning = {
2816
- enabled: boolean;
2817
- level: ReasoningLevel;
2818
- native?: NativeReasoningConfig;
2819
- reflection: ResolvedReflectionConfig;
2820
- };
2821
- /**
2822
- * Validates a user-supplied ReasoningConfig and throws a descriptive error for
2823
- * obviously-wrong values. Pure; safe to call before resolveReasoning.
2824
- */
2825
- declare function validateReasoningConfig(input: ReasoningConfig | undefined): void;
2826
- declare function resolveReasoning(input: ReasoningConfig | undefined): ResolvedReasoning | undefined;
2827
-
2828
- /**
2829
- * Tools the agent loop uses to steer ITSELF. Their arguments are never digested —
2830
- * digesting them is never a win (the arguments are small) and always a risk:
2831
- * - `response` carries the run's final structured output,
2832
- * - `manage_plan` (and its deprecated alias `manage_todo_list` — same handler,
2833
- * same shared state, see contextTools.ts) carries the living plan,
2834
- * - `ask_user_question` carries the question the user's answer replies to,
2835
- * - `open_skill` / `bind_skill_tools` / `search_skills` name the capability being
2836
- * loaded, which the rest of the run reasons about,
2837
- * - `get_tool_response` is the recovery path itself.
2838
- * They also default to `keep_full` on the output axis (overridable per tool).
2839
- */
2840
- declare const CONTROL_PLANE_TOOL_NAMES: readonly string[];
2841
- /**
2842
- * Delegation tools: the arguments ARE the brief handed to the child agent — the
2843
- * parent must be able to say what it delegated. Never digested. The child's report
2844
- * (the output) may still be archived and paged back in.
2845
- */
2846
- declare const DELEGATION_TOOL_NAMES: readonly string[];
2847
- declare const DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS = 2000;
2848
- declare const DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS = 200;
2849
- /** Key marking a digested argument field. Recognized as a recovery reference. */
2850
- declare const TOOL_INPUT_DIGEST_KEY = "__digest";
2851
- /**
2852
- * Compact textual preview of a value for archive/structured retention. Used by
2853
- * the summarizer when an old tool response is reduced to a placeholder. Not
2854
- * used at tool execution time.
2855
- */
2856
- declare function summarizeObject(value: any): string;
2857
- /**
2858
- * Tool-definition-declared retention specs, keyed by tool name. Built from the
2859
- * runtime's live tool list so a skill-bound tool contributes its own declaration.
2860
- */
2861
- type ToolRetentionDeclarations = Map<string, ToolRetentionSpec>;
2862
- declare function collectToolRetentionDeclarations(tools: Array<ToolInterface<any, any, any>> | undefined): ToolRetentionDeclarations;
2863
- /**
2864
- * Resolves the retention policy applied by the summarizer when context limits
2865
- * are reached. Critical tools are never reduced.
2866
- *
2867
- * Precedence (first match wins):
2868
- * 1. `criticalTools` — absolute, never reduced (documented contract).
2869
- * 2. `toolResponses.retentionByTool[name].output` — caller's two-axis override.
2870
- * 3. `toolResponses.toolResponseRetentionByTool[name]` — legacy single-axis map.
2871
- * 4. the tool definition's own `retention.output`.
2872
- * 5. built-in control-plane default (`keep_full`).
2873
- * 6. `toolResponses.defaultPolicy`.
2874
- */
2875
- declare function resolveSummarizationRetention(toolName: string, config: ResolvedSmartAgentConfig, declarations?: ToolRetentionDeclarations): ToolResponseRetentionPolicy;
2876
- /**
2877
- * Resolves the retention policy applied to a tool call's ARGUMENTS.
2878
- *
2879
- * Precedence (first match wins):
2880
- * 1. control-plane + delegation tools — always `keep` (hard invariant).
2881
- * 2. `criticalTools` — a tool whose response may never be reduced does not get
2882
- * its request reduced either.
2883
- * 3. `toolResponses.retentionByTool[name].input`.
2884
- * 4. the tool definition's own `retention.input`.
2885
- * 5. `toolResponses.defaultInputPolicy` (defaults to `keep`).
2886
- *
2887
- * The default is `keep`, so argument digesting never happens unless a tool or a
2888
- * caller explicitly asks for it.
2889
- */
2890
- declare function resolveInputRetention(toolName: string, config: ResolvedSmartAgentConfig, declarations?: ToolRetentionDeclarations): ToolInputRetentionPolicy;
2891
- type ToolInputDigestOptions = {
2892
- /** Per-field character threshold. Strings at or below this are preserved verbatim. */
2893
- maxFieldChars?: number;
2894
- /** Leading characters of a digested field kept as a preview. */
2895
- headChars?: number;
2896
- /** Execution id embedded in each marker so the model can page the original back in. */
2897
- executionId?: string;
2898
- };
2899
- type ToolInputDigestResult = {
2900
- /** The rewritten value. Identical reference when nothing was digested. */
2901
- value: unknown;
2902
- /** Dotted paths of the fields that were replaced by a digest marker. */
2903
- digestedPaths: string[];
2904
- /** Characters reclaimed from the serialized arguments. */
2905
- reclaimedChars: number;
2906
- };
2907
- /**
2908
- * Field-level argument digest.
2909
- *
2910
- * Walks the argument structure and replaces ONLY string leaves longer than
2911
- * `maxFieldChars` with a compact descriptor. Every other field — paths, ids,
2912
- * modes, indexes, booleans, short strings — is preserved verbatim, so a call like
2913
- *
2914
- * { filePath: "/reports/q3.md", mode: "append", section: 3, content: "<60k>" }
2915
- *
2916
- * compacts to
2917
- *
2918
- * { filePath: "/reports/q3.md", mode: "append", section: 3,
2919
- * content: { __digest: { chars: 61840, sha256: "…", head: "# Q3 …", recover: "…" } } }
2920
- *
2921
- * The model can still state exactly what it did; only the payload it no longer
2922
- * needs to re-read is gone. Idempotent: an existing digest marker is left alone.
2923
- */
2924
- declare function digestToolInputValue(value: unknown, options?: ToolInputDigestOptions): ToolInputDigestResult;
2925
- /**
2926
- * Digest a serialized `tool_call.function.arguments` JSON string in place.
2927
- * Returns the input string unchanged when nothing needed digesting, when the
2928
- * string is not parseable JSON (never guess at a non-JSON payload), or when the
2929
- * result would not actually be smaller.
2930
- */
2931
- declare function digestToolInputArguments(argumentsJson: string, options?: ToolInputDigestOptions): {
2932
- arguments: string;
2933
- digestedPaths: string[];
2934
- reclaimedChars: number;
2935
- };
2936
- /**
2937
- * Parse tool arguments against the tool's schema.
2938
- *
2939
- * Two passes, and the order is the contract: the raw arguments are validated
2940
- * FIRST, so a model that emits well-typed arguments is unaffected and the schema
2941
- * stays a real constraint. Only when that fails are the arguments run through
2942
- * `coerceToolArgs` and re-validated — repairing the type artifacts smaller and
2943
- * grammar-constrained backends produce (a nested object sent as a JSON string, a
2944
- * number sent as `"60"`, `""` standing in for an omitted optional) instead of
2945
- * spending a turn telling the model something it did not get wrong.
2946
- *
2947
- * Coercion never fabricates a value, so a genuinely missing required argument
2948
- * still fails — and it fails with the ORIGINAL issues plus the shape the tool
2949
- * actually wants, because "expected object, received string" on its own does not
2950
- * tell a weaker model which key to fix.
2951
- */
2952
- declare function validateToolArgs(tool: ToolInterface<any, any, any>, args: unknown): {
2953
- ok: true;
2954
- value: any;
2955
- coerced?: boolean;
2956
- } | {
2957
- ok: false;
2958
- message: string;
2959
- };
2960
-
2961
- /**
2962
- * Re-type `value` so it satisfies `schema`, walking both together.
2963
- *
2964
- * Returns the original value untouched whenever nothing needs repairing or
2965
- * nothing sensible can be done — this must never throw, because it runs on the
2966
- * error path and a throw here would replace a useful validation message with a
2967
- * crash.
2968
- */
2969
- declare function coerceToolArgs(schema: unknown, value: unknown): unknown;
2970
-
2971
- declare function fileSink(path?: string): TraceSinkConfig;
2972
- type CustomSinkArg = ((event: TraceEventRecord) => void | Promise<void>) | {
2973
- onEvent?: (event: TraceEventRecord) => void | Promise<void>;
2974
- onSession?: (session: TraceSessionFile) => void | Promise<void>;
3601
+ type CognipeerGuardrailConfig = {
3602
+ /** Guardrail keys from the Console. Defaults to `COGNIPEER_GUARDRAIL_KEYS` (comma-separated). */
3603
+ guardrailKeys?: string[];
3604
+ /** Convenience for the single-key case. */
3605
+ guardrailKey?: string;
3606
+ /** Defaults to `COGNIPEER_API_KEY`. */
3607
+ apiKey?: string;
3608
+ /** Defaults to `COGNIPEER_BASE_URL`, then the production console. Point at localhost for local runs. */
3609
+ baseUrl?: string;
3610
+ /** Override the hook-evaluate path. */
3611
+ path?: string;
3612
+ /** Surfaces to guard. Default: input + output. Add `"tool"` / `"tool_result"` for the tool surface. */
3613
+ apply?: GuardrailPhaseName[];
3614
+ /** Restrict to specific check families, e.g. `["pii"]`. */
3615
+ only?: string[];
3616
+ /** Override the SDK-hook → Console-hook-id mapping, merged over the default. */
3617
+ hookIds?: Record<string, string>;
3618
+ /** Ask the service to evaluate without enforcing. Independent of `mode`. */
3619
+ shadow?: boolean;
3620
+ /** `shadow` here reports locally without acting, whatever the service says. */
3621
+ mode?: "enforce" | "shadow";
3622
+ /** Default true — an unreachable or misconfigured policy blocks rather than silently stops guarding. */
3623
+ failClosed?: boolean;
3624
+ /** Per-check ceiling. Default 3000ms; also sent as `budget_ms`. */
3625
+ timeoutMs?: number;
3626
+ retries?: number;
3627
+ priority?: number;
3628
+ cache?: boolean | {
3629
+ maxEntries?: number;
3630
+ };
3631
+ metadata?: Record<string, unknown>;
3632
+ buildRequest?: (requests: GuardrailRequest[], ctx: GuardrailCallContext) => unknown;
3633
+ mapVerdict?: (response: unknown, requests: GuardrailRequest[]) => GuardrailVerdict[];
3634
+ name?: string;
2975
3635
  };
2976
- declare function customSink(handler: CustomSinkArg): TraceSinkConfig;
2977
- declare function cognipeerSink(apiKey: string): TraceSinkConfig;
2978
- declare function cognipeerSink(url: string | undefined, apiKey: string): TraceSinkConfig;
2979
- declare function httpSink(url: string, headers?: Record<string, string>): TraceSinkConfig;
2980
- /**
2981
- * Create an OTLP/HTTP JSON sink that exports traces in OpenTelemetry format.
2982
- * @param endpoint OTLP endpoint URL (e.g. "https://console.cognipeer.com/api/client/v1/traces")
2983
- * @param headers Optional headers (e.g. { Authorization: "Bearer ..." })
2984
- */
2985
- declare function otlpSink(endpoint: string, headers?: Record<string, string>): TraceSinkConfig;
2986
- /**
2987
- * Convert a complete TraceSessionFile into an OTLP ExportTraceServiceRequest (JSON).
2988
- * Produces a root span for the session and child spans for each event.
2989
- */
2990
- declare function traceSessionToOtlp(session: TraceSessionFile): Record<string, unknown>;
2991
- /** Generate a W3C-compatible trace ID (32 hex chars / 128-bit). */
2992
- declare function generateTraceId(): string;
2993
- /** Generate an OTel span ID (16 hex chars / 64-bit). */
2994
- declare function generateSpanId(): string;
2995
- /**
2996
- * Build the `tool_definitions` section for one model call, or undefined when
2997
- * nothing usable was supplied. Exported for provider/node code that assembles
2998
- * sections itself.
2999
- */
3000
- declare function buildToolDefinitionsSection(toolDefinitions: Array<{
3001
- name: string;
3002
- description?: string;
3003
- parameters?: Record<string, any>;
3004
- }>): TraceToolDefinitionsSection | undefined;
3005
- /**
3006
- * Build the `response_format` section for one model call, or undefined when
3007
- * nothing usable was supplied.
3008
- *
3009
- * Accepts either the invoke-options wrapper produced by
3010
- * `NativeJsonSchemaStrategy.buildResponseFormat()` (`{ response_format: {…} }`)
3011
- * or a bare `response_format` object, so callers can pass whatever they hold.
3012
- * Exported for provider/node code that assembles sections itself.
3013
- */
3014
- declare function buildResponseFormatSection(responseFormat: Record<string, any> | undefined, strategy?: "native" | "tool_based"): TraceResponseFormatSection | undefined;
3015
- /**
3016
- * Start a streaming trace session. Should be called before recording events in streaming mode.
3017
- * This sends the session start to the remote endpoint immediately.
3018
- */
3019
- declare function startStreamingSession(session: TraceSessionRuntime | undefined, agentRuntime?: AgentRuntimeConfig): Promise<void>;
3636
+ /** The Console's hook response, mapped onto the transport's three-valued verdict. */
3637
+ declare function mapConsoleHookVerdict(response: unknown, requests: GuardrailRequest[]): GuardrailVerdict[];
3638
+ declare function cognipeerGuardrail(config?: CognipeerGuardrailConfig): AgentPlugin;
3020
3639
 
3021
3640
  type MessageRole = "system" | "user" | "assistant" | "tool";
3022
3641
  type TextContent = {
@@ -3311,6 +3930,1479 @@ declare class ProviderError extends Error {
3311
3930
  constructor(message: string, provider: string, statusCode?: number | undefined, responseBody?: any | undefined);
3312
3931
  }
3313
3932
 
3933
+ /**
3934
+ * Portkey — two integration shapes, because Portkey supports two.
3935
+ *
3936
+ * Gateway all model traffic flows through Portkey and its guardrails run
3937
+ * on their hop. No extra latency, but it only covers model calls —
3938
+ * tool arguments and tool output never reach it.
3939
+ * Standalone the model talks to its provider directly and we call Portkey's
3940
+ * guardrail API ourselves. Full coverage including the tool
3941
+ * surface, at the cost of an extra round trip per checked turn.
3942
+ *
3943
+ * Gateway mode is deliberately NOT a `wrapModel` contribution. Retargeting an
3944
+ * arbitrary already-constructed model object is guesswork; building the
3945
+ * provider config that points at the gateway is exact. `portkeyGateway()`
3946
+ * returns that config.
3947
+ */
3948
+
3949
+ type PortkeyGatewayConfig = {
3950
+ /** Defaults to `PORTKEY_API_KEY`. */
3951
+ apiKey?: string;
3952
+ /** Portkey config id carrying the guardrail attachment. */
3953
+ configId?: string;
3954
+ /** Portkey virtual key for the upstream provider credentials. */
3955
+ virtualKey?: string;
3956
+ baseURL?: string;
3957
+ defaultModel?: string;
3958
+ /** Merged last, so it can override anything above. */
3959
+ headers?: Record<string, string>;
3960
+ };
3961
+ /**
3962
+ * Build the provider config that routes model traffic through the Portkey
3963
+ * gateway. Hand the result to `createProvider`:
3964
+ *
3965
+ * const model = fromNativeProvider(createProvider(portkeyGateway({ configId })));
3966
+ */
3967
+ declare function portkeyGateway(config?: PortkeyGatewayConfig): OpenAICompatibleProviderConfig;
3968
+ type PortkeyGuardrailConfig = {
3969
+ /** Defaults to `PORTKEY_API_KEY`. */
3970
+ apiKey?: string;
3971
+ baseUrl?: string;
3972
+ /** Path of the guardrail evaluation endpoint. */
3973
+ path?: string;
3974
+ /** Guardrail / check ids to run. */
3975
+ checks?: string[];
3976
+ apply?: GuardrailPhaseName[];
3977
+ mode?: "enforce" | "shadow";
3978
+ failClosed?: boolean;
3979
+ timeoutMs?: number;
3980
+ retries?: number;
3981
+ priority?: number;
3982
+ batch?: boolean;
3983
+ cache?: boolean | {
3984
+ maxEntries?: number;
3985
+ };
3986
+ metadata?: Record<string, unknown>;
3987
+ /** Escape hatch for the exact wire shape. */
3988
+ buildRequest?: (requests: GuardrailRequest[], ctx: GuardrailCallContext) => unknown;
3989
+ mapVerdict?: (response: unknown, requests: GuardrailRequest[]) => GuardrailVerdict[];
3990
+ name?: string;
3991
+ };
3992
+ /**
3993
+ * Standalone-mode Portkey guardrails. Covers the tool surface that gateway mode
3994
+ * cannot see, so the two are complementary rather than alternatives — running
3995
+ * gateway for model traffic and this for tools is a valid configuration.
3996
+ */
3997
+ declare function portkeyGuardrail(config?: PortkeyGuardrailConfig): AgentPlugin;
3998
+
3999
+ /**
4000
+ * PII redaction — the reference implementation of the mutation path.
4001
+ *
4002
+ * This plugin never blocks. It rewrites, which is the thing the v1 guardrail
4003
+ * engine structurally could not do: a guardrail could only decide that a
4004
+ * message containing a national id was unacceptable, not hand back the same
4005
+ * message with the id masked.
4006
+ *
4007
+ * Detectors that can be checksummed are checksummed. A bare 11-digit or
4008
+ * 16-digit regex matches order numbers, timestamps and product codes, and a
4009
+ * redactor with a high false-positive rate gets switched off — which protects
4010
+ * nothing at all.
4011
+ */
4012
+
4013
+ type PiiEntity = "TCKN" | "IBAN" | "EMAIL" | "PHONE_TR" | "CREDIT_CARD" | "IP" | "JWT" | "API_KEY";
4014
+ type PiiDetector = {
4015
+ entity: string;
4016
+ pattern: RegExp;
4017
+ /** Second-stage check; a match that fails it is not a finding. */
4018
+ validate?: (match: string) => boolean;
4019
+ };
4020
+ type PiiRedactionConfig = {
4021
+ /** Which built-in detectors to run. Default: all of them. */
4022
+ entities?: PiiEntity[];
4023
+ /** Extra detectors, run after the built-ins. */
4024
+ detectors?: PiiDetector[];
4025
+ /** Where to redact. Default: user input, tool output and the final answer. */
4026
+ apply?: Array<"input" | "toolOutput" | "modelOutput" | "finalAnswer">;
4027
+ /** Build the replacement token. Default: `[REDACTED:ENTITY]`. */
4028
+ mask?: (entity: string, match: string) => string;
4029
+ /**
4030
+ * Keep the last N characters visible (`[REDACTED:IBAN:…4821]`). Useful when
4031
+ * the model must still be able to tell two redacted values apart.
4032
+ */
4033
+ keepLast?: number;
4034
+ priority?: number;
4035
+ name?: string;
4036
+ };
4037
+ /** Turkish national identification number, with its two checksum digits. */
4038
+ declare function isValidTckn(value: string): boolean;
4039
+ /** Luhn — catches most typos and nearly all non-card digit runs. */
4040
+ declare function isValidLuhn(value: string): boolean;
4041
+ /** ISO 13616 mod-97 check. */
4042
+ declare function isValidIban(value: string): boolean;
4043
+ type RedactionResult = {
4044
+ text: string;
4045
+ findings: Array<{
4046
+ entity: string;
4047
+ count: number;
4048
+ }>;
4049
+ };
4050
+ declare function redactText(text: string, detectors: PiiDetector[], mask: (entity: string, match: string) => string): RedactionResult;
4051
+ declare function piiRedaction(config?: PiiRedactionConfig): AgentPlugin;
4052
+
4053
+ /**
4054
+ * Central tool policy.
4055
+ *
4056
+ * Today approval lives on the tool definition (`needsApproval`), which means a
4057
+ * policy has to be edited into every tool it governs — including tools that
4058
+ * arrived from an MCP server and are not yours to edit. This moves the decision
4059
+ * to one place the security owner can read in full.
4060
+ *
4061
+ * The escalation rule is enforced by the host, not here: a hook can raise a
4062
+ * call to `ask` or `deny`, and can never lower one. A policy that could grant
4063
+ * `allow` over a tool's own `needsApproval: true` would be a way to switch the
4064
+ * approval system off from a plugin.
4065
+ */
4066
+
4067
+ type ToolRule = {
4068
+ /** Exact tool name, or a RegExp tested against it. */
4069
+ tool: string | RegExp;
4070
+ /** What to do when this rule matches. */
4071
+ action: "allow" | "ask" | "deny";
4072
+ /** Narrow the rule to specific arguments. */
4073
+ when?: (args: Record<string, unknown>) => boolean;
4074
+ /** Message shown to the reviewer, or handed back to the model on `deny`. */
4075
+ reason?: string | ((args: Record<string, unknown>, toolName: string) => string);
4076
+ };
4077
+ type ToolPolicyConfig = {
4078
+ /** Evaluated in order; the first match wins. */
4079
+ rules?: ToolRule[];
4080
+ /** Shorthand: always require approval for these tools. */
4081
+ ask?: Array<string | RegExp>;
4082
+ /** Shorthand: always refuse these tools. */
4083
+ deny?: Array<string | RegExp>;
4084
+ /**
4085
+ * When set, any tool NOT named here is denied. The strictest useful setting
4086
+ * for an agent with dynamically discovered tools.
4087
+ *
4088
+ * The SDK's own control-plane tools are exempt by default — see
4089
+ * `governControlPlaneTools`.
4090
+ */
4091
+ allowOnly?: Array<string | RegExp>;
4092
+ /**
4093
+ * Whether `allowOnly` also governs the SDK's own machinery:
4094
+ * `ask_user_question`, `manage_plan`, `get_tool_response`, `response`,
4095
+ * `open_skill` and friends.
4096
+ *
4097
+ * Default false. An allow-list is written by naming the tools you care
4098
+ * about, and nobody writing one means "also stop the agent from asking me a
4099
+ * question or returning its structured output". Governing them silently
4100
+ * breaks human-in-the-loop, planning and structured output at once, and the
4101
+ * symptom — a run that quietly stops using half the runtime — points nowhere
4102
+ * near the policy. Set true to govern them anyway; an explicit `deny` entry
4103
+ * or a rule still applies to them either way.
4104
+ */
4105
+ governControlPlaneTools?: boolean;
4106
+ /** Cap executions per tool, per run — a loop-breaker for retry storms. */
4107
+ maxExecutionsPerTool?: number | Record<string, number>;
4108
+ priority?: number;
4109
+ name?: string;
4110
+ };
4111
+ declare function toolPolicy(config?: ToolPolicyConfig): AgentPlugin;
4112
+ /**
4113
+ * Path sandbox for filesystem-shaped tools. Rejects absolute escapes, parent
4114
+ * traversal, and anything resolving outside the allowed roots.
4115
+ */
4116
+ declare function pathSandbox(config: {
4117
+ /** Argument names that carry a path. Default: path, file, filePath, dir, directory. */
4118
+ argNames?: string[];
4119
+ /** Allowed prefixes. A path must start with one of them once normalized. */
4120
+ roots: string[];
4121
+ /** Only apply to these tools. Default: every tool that carries a path argument. */
4122
+ tools?: Array<string | RegExp>;
4123
+ name?: string;
4124
+ priority?: number;
4125
+ }): AgentPlugin;
4126
+
4127
+ /**
4128
+ * Spend ceiling for a run.
4129
+ *
4130
+ * Counters are derived from `state.usage` rather than kept in the plugin's own
4131
+ * store, which makes the budget correct across a pause/resume boundary for
4132
+ * free: plugin stores are per-run and would reset to zero on resume, while
4133
+ * `state.usage` is part of the snapshot.
4134
+ */
4135
+
4136
+ type BudgetGuardConfig = {
4137
+ /** Hard ceiling in USD. Requires `costEstimator`. */
4138
+ maxUsd?: number;
4139
+ /** Hard ceiling on cumulative output tokens across the run. */
4140
+ maxOutputTokens?: number;
4141
+ /** Hard ceiling on model calls. */
4142
+ maxModelCalls?: number;
4143
+ /**
4144
+ * Per-run pricing. Without it the USD ceiling is inert — the SDK carries no
4145
+ * built-in price table, and a stale one is worse than none.
4146
+ */
4147
+ costEstimator?: CostEstimator;
4148
+ /** `deny` stops the run; `warn` only emits. Default `deny`. */
4149
+ onExceeded?: "deny" | "warn";
4150
+ /** Emit a `metadata` event once this fraction of the budget is used. Default 0.8. */
4151
+ warnAt?: number;
4152
+ priority?: number;
4153
+ name?: string;
4154
+ };
4155
+ declare function budgetGuard(config?: BudgetGuardConfig): AgentPlugin;
4156
+
4157
+ /**
4158
+ * Append-only record of what the agent tried to do.
4159
+ *
4160
+ * Registered at priority 0 so it observes every tool attempt *before* any
4161
+ * policy plugin can deny it — an audit log that only sees the calls that were
4162
+ * allowed answers the wrong question. The outcome of each attempt is reconciled
4163
+ * at `sessionEnd` from `toolHistory`, which carries the final status
4164
+ * (`success` / `error` / `rejected` / `handoff`) for every call.
4165
+ */
4166
+
4167
+ type AuditEntry = {
4168
+ runId: string;
4169
+ agentName?: string;
4170
+ at: string;
4171
+ kind: "tool_attempt" | "tool_outcome" | "notification" | "session_end";
4172
+ toolName?: string;
4173
+ toolCallId?: string;
4174
+ args?: unknown;
4175
+ status?: string;
4176
+ detail?: unknown;
4177
+ };
4178
+ type AuditLogConfig = {
4179
+ /** Where entries go. Defaults to `console.log` of a compact JSON line. */
4180
+ sink?: (entry: AuditEntry) => MaybePromise<void>;
4181
+ /** Include tool arguments. Off by default — arguments routinely carry PII. */
4182
+ includeArgs?: boolean;
4183
+ /** Truncate serialized arguments to this many characters. Default 2000. */
4184
+ maxArgChars?: number;
4185
+ name?: string;
4186
+ };
4187
+ declare function auditLog(config?: AuditLogConfig): AgentPlugin;
4188
+
4189
+ /**
4190
+ * Slot implementations for the two stores every product ends up writing itself:
4191
+ * conversation history and checkpoint persistence.
4192
+ *
4193
+ * The in-memory versions are real implementations, not stubs — they are the
4194
+ * right choice for tests, for single-process workers, and for a first
4195
+ * deployment. The file-backed checkpoint store is the smallest thing that
4196
+ * survives a restart.
4197
+ */
4198
+
4199
+ type ConversationPluginConfig = {
4200
+ store: ConversationStore;
4201
+ /**
4202
+ * Which thread this run belongs to. A string is a fixed thread; a function
4203
+ * reads it from the incoming state (typically `state.metadata.threadId`).
4204
+ */
4205
+ threadId: string | ((state: unknown) => string | undefined);
4206
+ /** Cap the messages loaded back. Default: everything the store returns. */
4207
+ maxMessages?: number;
4208
+ name?: string;
4209
+ priority?: number;
4210
+ };
4211
+ /**
4212
+ * Hydrates the transcript on `sessionStart` and appends the new turns on
4213
+ * `sessionEnd`. Only messages produced by this run are appended, so replaying
4214
+ * the same thread does not duplicate history.
4215
+ */
4216
+ declare function conversationHistory(config: ConversationPluginConfig): AgentPlugin;
4217
+ declare function inMemoryConversationStore(): ConversationStore;
4218
+ type CheckpointPluginConfig = {
4219
+ store: CheckpointStore;
4220
+ /** Checkpoint id. Defaults to the run id. */
4221
+ id?: string | ((state: unknown) => string | undefined);
4222
+ /**
4223
+ * Which pauses to persist. Default: every non-success ending, which is when a
4224
+ * run can actually be continued.
4225
+ */
4226
+ saveOn?: Array<"paused" | "cancelled" | "error" | "success">;
4227
+ /** Build the snapshot. Defaults to `captureSnapshot` semantics via the host. */
4228
+ capture?: (state: unknown) => MaybePromise<AgentSnapshot>;
4229
+ name?: string;
4230
+ priority?: number;
4231
+ };
4232
+ /**
4233
+ * Persists a snapshot whenever a run ends in a resumable state. The SDK already
4234
+ * has `snapshot()` / `resume()`; what it has never had is somewhere to put the
4235
+ * result.
4236
+ */
4237
+ declare function checkpointing(config: CheckpointPluginConfig): AgentPlugin;
4238
+ declare function inMemoryCheckpointStore(): CheckpointStore;
4239
+ /**
4240
+ * File-backed checkpoints. One JSON file per id under `dir`. Node only — the
4241
+ * `fs` import is dynamic so bundling for an edge runtime does not pull it in
4242
+ * unless this function is actually called.
4243
+ */
4244
+ declare function fileCheckpointStore(dir?: string): CheckpointStore;
4245
+
4246
+ /**
4247
+ * Indirect prompt-injection screening.
4248
+ *
4249
+ * The dangerous text in an agent run is rarely what the user typed — it is what
4250
+ * a tool brought back: a web page, a PDF, a ticket comment, an email body. That
4251
+ * content lands in the same transcript as the operator's instructions, and the
4252
+ * model has no channel-level way to tell the two apart. This plugin sits on
4253
+ * `postToolUse`, which is exactly where fetched content enters, and labels it
4254
+ * as data.
4255
+ *
4256
+ * It is a heuristic and it is worth being blunt about the limits. False
4257
+ * positives are routine (a security wiki page *about* injection trips several
4258
+ * families at once); false negatives are cheap for an attacker (a paraphrase, a
4259
+ * translation, a homoglyph, an instruction split across two sentences). Treat
4260
+ * this as defence in depth behind the real controls — a tool allow-list, egress
4261
+ * restrictions, per-tool approval — and never as a trust boundary.
4262
+ *
4263
+ * The default action follows from that. Annotating keeps the fetched answer
4264
+ * available while telling the model what it is holding; blocking would throw
4265
+ * away a page that usually still contains the information the user asked for,
4266
+ * and a screen that destroys useful work gets switched off within a week.
4267
+ */
4268
+
4269
+ type PromptInjectionFamily = "override" | "roleplay" | "fakeSystem" | "promptLeak" | "exfiltration" | "imageExfil" | "encodedPayload" | "custom";
4270
+ type PromptInjectionGuardConfig = {
4271
+ /**
4272
+ * What to do with flagged content. Default `annotate` — see the module note.
4273
+ * `strip` drops the offending lines, `deny` refuses the tool result outright.
4274
+ */
4275
+ action?: "deny" | "annotate" | "strip";
4276
+ /**
4277
+ * Extra patterns, checked alongside the built-in families. They count as one
4278
+ * additional family rather than joining an existing one: a caller-written
4279
+ * pattern is a deliberate, site-specific signal, so it scores like a strong
4280
+ * one instead of diluting the built-in weights.
4281
+ */
4282
+ patterns?: RegExp[];
4283
+ /**
4284
+ * Minimum score before acting, 0–1. Default 0.5, which one strong family
4285
+ * clears on its own and one weak family does not.
4286
+ */
4287
+ minConfidence?: number;
4288
+ /** Surfaces to screen. Default `["toolOutput"]`. */
4289
+ applyTo?: Array<"toolOutput" | "input">;
4290
+ name?: string;
4291
+ priority?: number;
4292
+ };
4293
+ type InjectionScan = {
4294
+ /** 0–1. A coarse count of independent signals, not a probability. */
4295
+ confidence: number;
4296
+ families: PromptInjectionFamily[];
4297
+ };
4298
+ declare function promptInjectionGuard(config?: PromptInjectionGuardConfig): AgentPlugin;
4299
+
4300
+ /**
4301
+ * Contract check on the final answer.
4302
+ *
4303
+ * Prompt engineering states the shape an answer must have; nothing verifies it.
4304
+ * This is the verification step: length bounds, required and forbidden shapes,
4305
+ * and an escape hatch for the checks that only the caller can express. A
4306
+ * violation denies with the rule that failed named in the reason, so the
4307
+ * failure is actionable rather than a generic "output rejected".
4308
+ *
4309
+ * Only `maxChars` can be repaired automatically. Every other rule describes
4310
+ * something the answer is missing or must not contain, and there is no honest
4311
+ * local edit for that — silently patching a non-conforming answer would return
4312
+ * something the model never wrote and nobody reviewed.
4313
+ */
4314
+
4315
+ type OutputGuardConfig = {
4316
+ /** Upper bound on the answer's length. */
4317
+ maxChars?: number;
4318
+ /** Lower bound, checked after trimming — whitespace is not an answer. */
4319
+ minChars?: number;
4320
+ /** Every pattern must match. Use for required sections, citations, formats. */
4321
+ mustMatch?: RegExp[];
4322
+ /** No pattern may match. Use for banned phrases, internal markers, hedges. */
4323
+ mustNotMatch?: RegExp[];
4324
+ /** Reject an empty or whitespace-only answer. Default true. */
4325
+ forbidEmpty?: boolean;
4326
+ /** Caller-defined rule. Return a violation message, or `undefined` to pass. */
4327
+ custom?: (content: string, ctx: HookContext) => string | undefined;
4328
+ /**
4329
+ * `deny` (default) hands the reason back so the loop can try again.
4330
+ * `truncate` applies to `maxChars` only; anything else still denies.
4331
+ */
4332
+ action?: "deny" | "truncate";
4333
+ name?: string;
4334
+ priority?: number;
4335
+ };
4336
+ declare function outputGuard(config?: OutputGuardConfig): AgentPlugin;
4337
+
4338
+ /**
4339
+ * One structured record per run, shaped for a metrics pipeline.
4340
+ *
4341
+ * Only the things that have no ledger — how many model calls and tool calls
4342
+ * this leg actually made — are tallied in the plugin's own store. Every number
4343
+ * a billing or reliability dashboard will later be reconciled against is read
4344
+ * back off the state instead: `state.usage` is the single billing ledger and
4345
+ * `state.toolHistory` is the single record of what each call did. Both are part
4346
+ * of the snapshot, so they survive a pause/resume; a plugin-kept token counter
4347
+ * would restart at zero on resume and under-report the run's real bill.
4348
+ *
4349
+ * The counting hooks are gates, and a deny ends the chain. Sitting at priority
4350
+ * 1 — immediately after `auditLog` (0) and ahead of every policy plugin — is
4351
+ * what keeps a model turn that a guardrail later rejects inside the count: a
4352
+ * metric that only sees the traffic nothing objected to describes a different
4353
+ * agent than the one that ran.
4354
+ */
4355
+
4356
+ type SessionMetrics = {
4357
+ runId: string;
4358
+ agentName?: string;
4359
+ status: "success" | "error" | "paused" | "cancelled";
4360
+ durationMs: number;
4361
+ modelCalls: number;
4362
+ /** Every attempt, including the ones a policy refused. */
4363
+ toolCalls: number;
4364
+ failedToolCalls: number;
4365
+ /** Denied by a hook or by a human at the approval gate. */
4366
+ deniedToolCalls: number;
4367
+ inputTokens: number;
4368
+ outputTokens: number;
4369
+ cachedInputTokens: number;
4370
+ totalTokens: number;
4371
+ /** Present only when a `costEstimator` was configured. */
4372
+ estimatedCostUsd?: number;
4373
+ /** Executions per tool name. Opt-in — a wide tool menu makes this unbounded. */
4374
+ toolBreakdown?: Record<string, number>;
4375
+ };
4376
+ type SessionMetricsConfig = {
4377
+ /** Where the record goes. Defaults to one JSON line on `console.log`. */
4378
+ sink?: (metrics: SessionMetrics) => MaybePromise<void>;
4379
+ /** Add per-tool execution counts. Off by default. */
4380
+ includeToolBreakdown?: boolean;
4381
+ /**
4382
+ * Pricing for `estimatedCostUsd`. Deliberately NOT published as the
4383
+ * `costEstimator` slot: a slot has exactly one owner, and a metrics plugin
4384
+ * that claimed it would make itself un-installable next to `budgetGuard`.
4385
+ */
4386
+ costEstimator?: CostEstimator;
4387
+ name?: string;
4388
+ };
4389
+ declare function sessionMetrics(config?: SessionMetricsConfig): AgentPlugin;
4390
+
4391
+ /**
4392
+ * Lifecycle wrapper for a Model Context Protocol server.
4393
+ *
4394
+ * An MCP server is not a list of tools, it is a SESSION: something has to open
4395
+ * a transport, discover what the server offers, and close it again when the
4396
+ * agent goes away. `tools:` can express only the middle third of that, which is
4397
+ * why a caller wiring MCP by hand ends up leaking a child process or a socket
4398
+ * per agent. A plugin owns `setup` and a disposer, so the session ends when the
4399
+ * agent does.
4400
+ *
4401
+ * The connection itself stays the caller's dependency: `connect` is supplied by
4402
+ * them, so `@langchain/mcp-adapters` or an official MCP client never becomes a
4403
+ * dependency of this SDK, and any transport — stdio, SSE, streamable HTTP, an
4404
+ * in-process fake — works the same way.
4405
+ *
4406
+ * Connecting happens in `setup` rather than inside the `tools` contribution
4407
+ * because that is the only place the host applies `failureMode`. A fail-closed
4408
+ * plugin whose server is unreachable must stop the agent from being built: the
4409
+ * alternative is an agent that starts happily with none of the tools its
4410
+ * instructions tell it to use, and then improvises.
4411
+ */
4412
+
4413
+ type McpConnection = {
4414
+ /** The tools the server advertised. */
4415
+ tools: ToolInterface[];
4416
+ /** Shut the session down. Called once, when the last agent using it disposes. */
4417
+ close?: () => Promise<void> | void;
4418
+ };
4419
+ type McpConfig = {
4420
+ /** Opens the session. Owns the client library, the transport and the auth. */
4421
+ connect: () => Promise<McpConnection>;
4422
+ /**
4423
+ * Renames discovered tools to `${prefix}__${name}`. Two servers routinely
4424
+ * both export a `search`, and the SDK merges tools by name — without a prefix
4425
+ * one silently shadows the other.
4426
+ */
4427
+ prefix?: string;
4428
+ name?: string;
4429
+ /** Default `"open"`: an unreachable server degrades the agent, it is not a breach. */
4430
+ failureMode?: PluginFailureMode;
4431
+ /** Cap on `connect`. Default 30s. */
4432
+ timeoutMs?: number;
4433
+ };
4434
+ declare function mcp(config: McpConfig): AgentPlugin;
4435
+
4436
+ /**
4437
+ * Token-bucket throttle for model and tool calls.
4438
+ *
4439
+ * The thing this protects against is not a hostile user, it is one agent: a
4440
+ * retry loop or a fan-out of sub-agents can put a month of traffic through a
4441
+ * shared upstream in a minute, and the upstream's own 429 arrives too late to
4442
+ * be cheap. So the ceiling is enforced here, where a refusal is still just a
4443
+ * tool result the model can read.
4444
+ *
4445
+ * Buckets live in this closure — one set per `rateLimit()` call, i.e. per agent
4446
+ * — and are keyed by `config.key?.(ctx) ?? "default"`. They deliberately do NOT
4447
+ * live in `ctx.store`: that store is per RUN, so a bucket kept there would be
4448
+ * full again on every `invoke()` and would limit nothing across runs, which is
4449
+ * exactly the traffic pattern worth limiting. Keying also matters: without a
4450
+ * `key`, two tenants sharing one agent instance share one budget, and the noisy
4451
+ * one starves the quiet one.
4452
+ */
4453
+
4454
+ type RateLimitConfig = {
4455
+ /** Model calls allowed per minute, across the whole agent. */
4456
+ modelCallsPerMinute?: number;
4457
+ /** Tool executions allowed per minute, summed over every tool. */
4458
+ toolCallsPerMinute?: number;
4459
+ /** Extra per-tool ceilings, checked on top of `toolCallsPerMinute`. */
4460
+ perToolPerMinute?: Record<string, number>;
4461
+ /**
4462
+ * Bucket identity — a tenant, an end user, an api key. Everything the same
4463
+ * key returns shares one budget; a missing key puts every caller in one.
4464
+ */
4465
+ key?: (ctx: HookContext) => string;
4466
+ /**
4467
+ * `deny` refuses immediately and lets the model decide what to do; `wait`
4468
+ * blocks the call until a token frees, which smooths a burst instead of
4469
+ * surfacing it. Default `deny`.
4470
+ */
4471
+ onExceeded?: "deny" | "wait";
4472
+ /** Upper bound on a `wait`, after which the call is denied anyway. Default 5000. */
4473
+ maxWaitMs?: number;
4474
+ name?: string;
4475
+ priority?: number;
4476
+ };
4477
+ declare function rateLimit(config?: RateLimitConfig): AgentPlugin;
4478
+
4479
+ /**
4480
+ * Exact-match cache for model responses.
4481
+ *
4482
+ * Agent loops replay the same prefix constantly — a retried tool, a re-planned
4483
+ * step, a fan-out of sub-agents that all start from the same system prompt and
4484
+ * the same question. When the wire messages and the tool menu are byte-identical
4485
+ * the provider's answer is the only thing that is not free, so it is served
4486
+ * from memory and the call never leaves the process. Nothing is inferred:
4487
+ * "similar" is not a hit, only "identical" is.
4488
+ */
4489
+
4490
+ type ResponseCacheConfig = {
4491
+ /** How long an entry stays servable. Default 5 minutes. */
4492
+ ttlMs?: number;
4493
+ /** Entry ceiling; the least recently used entry is dropped past it. Default 100. */
4494
+ maxEntries?: number;
4495
+ /**
4496
+ * Replace the default key. Returning `undefined` means "do not cache this
4497
+ * call" — the honest way to exclude anything non-deterministic (a prompt
4498
+ * carrying `now()`, a per-user tool result) without turning the plugin off.
4499
+ */
4500
+ keyOf?: (input: HookMap["preModelCall"]["input"]) => string | undefined;
4501
+ /**
4502
+ * `run` gives every `invoke()` a fresh cache (safe by default: nothing
4503
+ * outlives the conversation it came from); `agent` shares one cache across
4504
+ * every run on this agent instance, which is where the real savings are and
4505
+ * also where a stale or cross-tenant answer becomes possible. Default `run`.
4506
+ */
4507
+ scope?: "run" | "agent";
4508
+ name?: string;
4509
+ priority?: number;
4510
+ };
4511
+ declare function responseCache(config?: ResponseCacheConfig): AgentPlugin;
4512
+
4513
+ type SigV4Credentials = {
4514
+ accessKeyId: string;
4515
+ secretAccessKey: string;
4516
+ sessionToken?: string;
4517
+ };
4518
+
4519
+ /**
4520
+ * Guardrail presets — four more services on the seam in `guardrail.ts`.
4521
+ *
4522
+ * Each one is the same three decisions `cognipeerGuardrail` makes and nothing
4523
+ * more: where to POST, how to authenticate, and how that service's response
4524
+ * becomes a `GuardrailVerdict`. None of them re-implements the plugin — the
4525
+ * caching, shadow mode, phase skipping and fail-closed behaviour all stay in
4526
+ * `createGuardrailPlugin`, so a fix there reaches every preset at once.
4527
+ *
4528
+ * How much a preset is allowed to assume differs per service, and that
4529
+ * difference is stated per function rather than hidden:
4530
+ *
4531
+ * openAIModeration the wire contract is public, stable and versioned, so
4532
+ * the mapper reads its fields directly and is strict
4533
+ * about a shape it does not recognise.
4534
+ * azureContentSafety path and body are what the docs look like, but they
4535
+ * are NOT verified here — they live behind
4536
+ * `buildRequest` / `mapVerdict` overrides, and the
4537
+ * default mapper falls back to the forgiving
4538
+ * `normalizeVerdicts` when it sees an unfamiliar body.
4539
+ * bedrockGuardrail same caveat, plus SigV4 signing reused from
4540
+ * `src/providers/utils/sigv4.ts`.
4541
+ * regexGuardrail no wire contract at all: in-process patterns, so a
4542
+ * team can adopt the guardrail plugin shape before it
4543
+ * has a service to point at.
4544
+ *
4545
+ * Priorities sit in the 20-25 guardrail band already used by `cognipeer` (20)
4546
+ * and `portkey` (25), ordered cheapest-first on purpose. R3 makes the first
4547
+ * deny terminal for the chain, so putting the local matcher ahead of the
4548
+ * network ones (and the free moderation call ahead of the billed ones) means
4549
+ * the most expensive check is the one most likely never to be made — and a
4550
+ * locally-detectable violation is never shipped to a third party at all.
4551
+ */
4552
+
4553
+ type OpenAIModerationConfig = {
4554
+ /** Defaults to `OPENAI_API_KEY`. */
4555
+ apiKey?: string;
4556
+ /** Moderation model. Default `omni-moderation-latest`. */
4557
+ model?: string;
4558
+ /** Origin only — the `/v1/moderations` path is appended. Defaults to `OPENAI_BASE_URL`, then the public API. */
4559
+ baseUrl?: string;
4560
+ /**
4561
+ * What a flagged result becomes. `block` (default) refuses the turn; `mask`
4562
+ * substitutes `maskWith`, which is how a team replaces a violating answer
4563
+ * with a fixed refusal instead of failing the run.
4564
+ */
4565
+ action?: "block" | "mask";
4566
+ /** Replacement used when `action` is `mask`. */
4567
+ maskWith?: string;
4568
+ /** Surfaces to guard. Default: input + output. */
4569
+ apply?: GuardrailPhaseName[];
4570
+ /** `shadow` reports what would have been blocked without blocking. */
4571
+ mode?: "enforce" | "shadow";
4572
+ /** Default true — a moderation outage blocks rather than silently stops moderating. */
4573
+ failClosed?: boolean;
4574
+ /** Per-check ceiling. Default 3000ms. */
4575
+ timeoutMs?: number;
4576
+ /** Retries after the first attempt. Default 1. */
4577
+ retries?: number;
4578
+ priority?: number;
4579
+ /** Memoize verdicts per run. Default true. */
4580
+ cache?: boolean | {
4581
+ maxEntries?: number;
4582
+ };
4583
+ metadata?: Record<string, unknown>;
4584
+ name?: string;
4585
+ };
4586
+ /**
4587
+ * OpenAI's moderation endpoint. Free, fast and text-only, which is why it sits
4588
+ * at the cheap end of the guardrail band.
4589
+ */
4590
+ declare function openAIModeration(config?: OpenAIModerationConfig): AgentPlugin;
4591
+ type AzureContentSafetyConfig = {
4592
+ /** Resource endpoint, e.g. `https://my-resource.cognitiveservices.azure.com`. Defaults to `AZURE_CONTENT_SAFETY_ENDPOINT`. */
4593
+ endpoint?: string;
4594
+ /** Defaults to `AZURE_CONTENT_SAFETY_KEY`. */
4595
+ apiKey?: string;
4596
+ /** Block when a requested category reaches this severity. Default 4. */
4597
+ severityThreshold?: number;
4598
+ /** Categories to analyse. Default: Hate, SelfHarm, Sexual, Violence. */
4599
+ categories?: string[];
4600
+ /** `api-version` query parameter. */
4601
+ apiVersion?: string;
4602
+ /** Override the analyze path (rarely needed). */
4603
+ path?: string;
4604
+ apply?: GuardrailPhaseName[];
4605
+ mode?: "enforce" | "shadow";
4606
+ failClosed?: boolean;
4607
+ timeoutMs?: number;
4608
+ retries?: number;
4609
+ priority?: number;
4610
+ cache?: boolean | {
4611
+ maxEntries?: number;
4612
+ };
4613
+ metadata?: Record<string, unknown>;
4614
+ /** Escape hatch: build the wire request yourself. */
4615
+ buildRequest?: (requests: GuardrailRequest[], ctx: GuardrailCallContext) => unknown;
4616
+ /** Escape hatch: map the response to verdicts, in request order. */
4617
+ mapVerdict?: (response: unknown, requests: GuardrailRequest[]) => GuardrailVerdict[];
4618
+ name?: string;
4619
+ };
4620
+ /**
4621
+ * Azure AI Content Safety. The path, body and response field names default to
4622
+ * what the public documentation describes, but they are UNVERIFIED here: both
4623
+ * ends of the contract are overridable (`buildRequest` / `mapVerdict`) exactly
4624
+ * so a shape change is a one-line configuration fix rather than a fork.
4625
+ */
4626
+ declare function azureContentSafety(config?: AzureContentSafetyConfig): AgentPlugin;
4627
+ type BedrockGuardrailConfig = {
4628
+ /** Guardrail id from Bedrock. */
4629
+ guardrailIdentifier: string;
4630
+ /** Guardrail version, e.g. `"1"` or `"DRAFT"`. */
4631
+ guardrailVersion: string;
4632
+ /** Defaults to `AWS_REGION`, then `AWS_DEFAULT_REGION`, then `us-east-1`. */
4633
+ region?: string;
4634
+ /** Defaults to the standard `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` / `AWS_SESSION_TOKEN` variables. */
4635
+ credentials?: SigV4Credentials;
4636
+ /** Override the runtime host (VPC endpoint, a local mock). */
4637
+ baseUrl?: string;
4638
+ apply?: GuardrailPhaseName[];
4639
+ mode?: "enforce" | "shadow";
4640
+ failClosed?: boolean;
4641
+ timeoutMs?: number;
4642
+ /** Retries after the first attempt. Default 1; each attempt is signed afresh. */
4643
+ retries?: number;
4644
+ priority?: number;
4645
+ cache?: boolean | {
4646
+ maxEntries?: number;
4647
+ };
4648
+ metadata?: Record<string, unknown>;
4649
+ /** Escape hatch: build the wire request yourself. */
4650
+ buildRequest?: (request: GuardrailRequest, ctx: GuardrailCallContext) => unknown;
4651
+ /** Escape hatch: map the response to a verdict. */
4652
+ mapVerdict?: (response: unknown, request: GuardrailRequest) => GuardrailVerdict;
4653
+ name?: string;
4654
+ };
4655
+ /**
4656
+ * AWS Bedrock ApplyGuardrail. Signing is reused from the provider layer
4657
+ * (`src/providers/utils/sigv4.ts`) rather than reimplemented — one signer, one
4658
+ * place for a signing bug to be fixed.
4659
+ */
4660
+ declare function bedrockGuardrail(config: BedrockGuardrailConfig): AgentPlugin;
4661
+ type RegexGuardrailConfig = {
4662
+ /** Any match denies the turn. */
4663
+ block?: RegExp[];
4664
+ /** Applied in order; a changed text becomes a `mask` verdict. */
4665
+ mask?: Array<{
4666
+ pattern: RegExp;
4667
+ replacement: string;
4668
+ }>;
4669
+ apply?: GuardrailPhaseName[];
4670
+ mode?: "enforce" | "shadow";
4671
+ failClosed?: boolean;
4672
+ priority?: number;
4673
+ cache?: boolean | {
4674
+ maxEntries?: number;
4675
+ };
4676
+ metadata?: Record<string, unknown>;
4677
+ name?: string;
4678
+ };
4679
+ /**
4680
+ * A guardrail with no service behind it. The point is adoption order: a team
4681
+ * can put the plugin, its phases, its shadow mode and its incident events in
4682
+ * place today with a list of patterns, then swap the transport for a real
4683
+ * service later without touching anything else in the agent.
4684
+ */
4685
+ declare function regexGuardrail(config?: RegexGuardrailConfig): AgentPlugin;
4686
+
4687
+ /**
4688
+ * What a user is allowed to attach.
4689
+ *
4690
+ * A multimodal turn is an untrusted upload path with a per-token price tag: a
4691
+ * single high-resolution image can cost more than the conversation around it,
4692
+ * a video the provider does not support fails deep inside the request, and a
4693
+ * `http://` URL is a server-side fetch of whatever the sender wants. None of
4694
+ * that is visible to a text guardrail, which sees only the caption.
4695
+ *
4696
+ * Structural checks only — kind, count, size, media type, source. Deciding
4697
+ * whether a picture is acceptable is a content question and belongs to a
4698
+ * moderation service; this decides whether it should be there at all.
4699
+ */
4700
+
4701
+ type MediaKind = "image" | "audio" | "video" | "file" | "unknown";
4702
+ type MediaPolicyConfig = {
4703
+ /** Kinds that may be attached. Default: every kind. */
4704
+ allow?: MediaKind[];
4705
+ /** Kinds that may never be attached. Checked after `allow`. */
4706
+ deny?: MediaKind[];
4707
+ /** Cap on attachments in one turn. */
4708
+ maxAttachments?: number;
4709
+ /** Cap on a single attachment, in bytes. Only measurable for inline data. */
4710
+ maxBytesPerAttachment?: number;
4711
+ /** Cap on the total inline bytes in one turn. */
4712
+ maxTotalBytes?: number;
4713
+ /** Exact media types, or a prefix ending in `/` (e.g. `"image/"`). */
4714
+ allowedMediaTypes?: string[];
4715
+ /** Reject `http://` sources. Default true — the provider fetches these server-side. */
4716
+ requireHttps?: boolean;
4717
+ /**
4718
+ * `deny` refuses the turn and tells the user why; `strip` drops the offending
4719
+ * parts and lets the run continue on what is left. Default `deny`, because
4720
+ * silently answering about a picture the model never received is worse than
4721
+ * saying no.
4722
+ */
4723
+ action?: "deny" | "strip";
4724
+ name?: string;
4725
+ priority?: number;
4726
+ };
4727
+ declare function mediaPolicy(config?: MediaPolicyConfig): AgentPlugin;
4728
+
4729
+ /**
4730
+ * Langfuse export, driven by hooks instead of by a tracing sink.
4731
+ *
4732
+ * The SDK already has a tracing runtime (`tracing: { enabled: true }` plus a
4733
+ * sink — file / http / otlp / cognipeer / custom) and that remains the richer
4734
+ * path: it carries prompts, tool payloads, response formats and the full span
4735
+ * tree. This plugin exists for two reasons the sink cannot serve.
4736
+ *
4737
+ * 1. Packaging. A product that already ships its guardrails as plugins can
4738
+ * hand its users one array — `plugins: [cognipeerGuardrail(), langfuseTracing()]`
4739
+ * — instead of a plugin array plus a separate `tracing` block.
4740
+ * 2. Reach. A sink only ever sees what the SDK core records. A plugin sits on
4741
+ * the hook chain, so it also sees things that never become trace events:
4742
+ * a tool call another plugin denied at `preToolUse` (recorded here as a
4743
+ * span that opens and never closes cleanly), a model turn a guardrail
4744
+ * rejected, a short-circuited call that never reached a provider.
4745
+ *
4746
+ * Content is deliberately NOT exported. Prompts, tool arguments and tool
4747
+ * results stay inside the process: shipping them to a third party by default
4748
+ * would be a surprise, and the SDK's own tracing runtime already has `logData`
4749
+ * for anyone who wants it. What goes out is shape and cost — model, latency,
4750
+ * token usage, tool names, outcomes. `buildPayload` is the seam for a caller
4751
+ * who wants more.
4752
+ *
4753
+ * WIRE CONTRACT — UNVERIFIED. The endpoint and auth scheme below
4754
+ * (`POST {baseUrl}/api/public/ingestion`, HTTP Basic `publicKey:secretKey`, a
4755
+ * `{ batch: [...] }` body of typed events) are what this module assumes, and
4756
+ * the per-event body shapes in `defaultBuildPayload` are an assumption on top
4757
+ * of that assumption — they were NOT verified against Langfuse documentation
4758
+ * while writing this. Everything about the body is therefore behind the
4759
+ * overridable `buildPayload(events, ctx)`: if Langfuse's schema differs, pass
4760
+ * your own and nothing else in this file has to move.
4761
+ */
4762
+
4763
+ /**
4764
+ * A neutral, in-house description of one thing worth reporting. Hooks produce
4765
+ * these; only `buildPayload` knows what Langfuse calls them. Keeping the two
4766
+ * apart is what makes the unverified schema a single-function problem.
4767
+ */
4768
+ type LangfuseEventKind = "trace-start" | "trace-end" | "generation" | "span-start" | "span-end";
4769
+ type LangfuseEvent = {
4770
+ /** Idempotency id for this ingestion envelope — unique per event, never reused. */
4771
+ id: string;
4772
+ kind: LangfuseEventKind;
4773
+ /** ISO time the event was produced (not the time the work happened). */
4774
+ timestamp: string;
4775
+ /** The run's Langfuse trace id. Every event of one run shares it. */
4776
+ traceId: string;
4777
+ /** Observation id — set for generations and spans, absent for the trace itself. */
4778
+ observationId?: string;
4779
+ name: string;
4780
+ startTime?: string;
4781
+ endTime?: string;
4782
+ model?: string;
4783
+ /** Token counts, already normalized across provider spellings. */
4784
+ usage?: {
4785
+ input?: number;
4786
+ output?: number;
4787
+ total?: number;
4788
+ };
4789
+ /** Structured outcome. Never message content — see the module header. */
4790
+ output?: unknown;
4791
+ level?: "DEFAULT" | "WARNING" | "ERROR";
4792
+ statusMessage?: string;
4793
+ metadata?: Record<string, unknown>;
4794
+ };
4795
+ /** The static, per-plugin half of a payload; the varying half is the events. */
4796
+ type LangfuseBuildContext = {
4797
+ baseUrl: string;
4798
+ publicKey: string;
4799
+ release?: string;
4800
+ userId?: string;
4801
+ sessionId?: string;
4802
+ tags?: string[];
4803
+ };
4804
+ type LangfuseTracingConfig = {
4805
+ /** Defaults to `LANGFUSE_PUBLIC_KEY`. */
4806
+ publicKey?: string;
4807
+ /** Defaults to `LANGFUSE_SECRET_KEY`. */
4808
+ secretKey?: string;
4809
+ /** Defaults to `LANGFUSE_BASE_URL`, then Langfuse Cloud. Point at a self-hosted instance here. */
4810
+ baseUrl?: string;
4811
+ /** Build/version tag attached to the trace. */
4812
+ release?: string;
4813
+ /** End-user attribution for the trace. */
4814
+ userId?: string;
4815
+ /** Groups several runs into one Langfuse session (a chat thread, typically). */
4816
+ sessionId?: string;
4817
+ tags?: string[];
4818
+ /** Flush once this many events are buffered. Default 20. */
4819
+ flushAt?: number;
4820
+ /** Flush a partially-filled buffer after this long. Default 5000ms. 0 disables the timer. */
4821
+ flushIntervalMs?: number;
4822
+ /** Escape hatch for the whole wire body — see the UNVERIFIED note in the module header. */
4823
+ buildPayload?: (events: LangfuseEvent[], ctx: LangfuseBuildContext) => unknown;
4824
+ /** Plugin name, when exporting to more than one Langfuse project at once. */
4825
+ name?: string;
4826
+ };
4827
+ /** The assumed `{ batch: [...] }` ingestion body. Replaceable via `buildPayload`. */
4828
+ declare function defaultBuildPayload(events: LangfuseEvent[], ctx: LangfuseBuildContext): unknown;
4829
+ declare function langfuseTracing(config?: LangfuseTracingConfig): AgentPlugin;
4830
+
4831
+ /**
4832
+ * OTLP/HTTP export of a finished run, driven by a hook instead of by a sink.
4833
+ *
4834
+ * The SDK already ships `otlpSink(endpoint, headers)`, and when observability
4835
+ * is configured on its own that remains the right tool — it is wired straight
4836
+ * into `finalizeTraceSession` and needs no plugin at all. This plugin exists
4837
+ * for the product that wants one array: `plugins: [cognipeerGuardrail(),
4838
+ * otelTracing({ endpoint })]`, with tracing and policy declared side by side
4839
+ * rather than in two unrelated config blocks.
4840
+ *
4841
+ * It does NOT re-implement the sink. The conversion is `traceSessionToOtlp`,
4842
+ * the same function `otlpSink` uses, applied to the same session object — so a
4843
+ * span tree exported through this plugin and one exported through the sink are
4844
+ * the same spans. What the plugin adds is placement: it runs on the hook chain,
4845
+ * next to the guardrails, and can therefore be turned on and off with them.
4846
+ *
4847
+ * Because it reads the SDK's trace session, it needs `tracing: { enabled: true }`
4848
+ * on the agent. Without it there is no session to export and the plugin says so
4849
+ * out loud (a `metadata` event plus a warning) rather than doing nothing: a
4850
+ * silent no-op in an observability tool is the failure that costs the most,
4851
+ * because it is discovered days later when someone goes looking for the traces.
4852
+ */
4853
+
4854
+ type OtelTracingConfig = {
4855
+ /** OTLP/HTTP JSON traces endpoint, e.g. `https://collector.example.com/v1/traces`. */
4856
+ endpoint: string;
4857
+ /** Auth and tenancy headers for the collector. */
4858
+ headers?: Record<string, string>;
4859
+ /** `service.name` on the exported resource. Defaults to the agent's name. */
4860
+ serviceName?: string;
4861
+ /** Plugin name, when exporting to more than one collector at once. */
4862
+ name?: string;
4863
+ };
4864
+ declare function otelTracing(config: OtelTracingConfig): AgentPlugin;
4865
+
4866
+ /**
4867
+ * Webhook-backed human-in-the-loop transport for the `approvalTransport` slot.
4868
+ *
4869
+ * ── Runtime status (read this before wiring it into a product) ───────────────
4870
+ * The `approvalTransport` slot is DECLARED (`PluginProvides`) and RESOLVED (the
4871
+ * host validates single ownership and exposes it on `host.slots`), but as of
4872
+ * this file's writing NOTHING IN THE RUNTIME CALLS IT: `grep -rn
4873
+ * approvalTransport src` finds only the type, the slot list and the docs table,
4874
+ * and the tools node still pauses the run and waits for `resolveToolApproval`.
4875
+ * Nothing reads `host.slots` at all yet, so this is the state of every slot
4876
+ * rather than a gap peculiar to this one.
4877
+ * Installing this plugin today changes no behaviour. It ships now because
4878
+ * the contract — `request()` returning a resolution, or `null` to leave the run
4879
+ * paused — is already fixed, and the tests below pin it so the day the tools
4880
+ * node consumes the slot the transport is already proven against it.
4881
+ *
4882
+ * ── Wire contract ───────────────────────────────────────────────────────────
4883
+ * The default request body and the default response parsing are THIS SDK's own
4884
+ * convention, not a schema published by any approval product. Nothing here was
4885
+ * verified against Slack, Teams, Jira, ServiceNow, PagerDuty or any other
4886
+ * system, and no such schema is invented and presented as fact. Point `url` at
4887
+ * an endpoint you control, or override `buildRequest` / `parseDecision` — the
4888
+ * same two-function escape hatch `cognipeerGuardrail` uses for exactly this
4889
+ * reason.
4890
+ *
4891
+ * ── Safety posture ──────────────────────────────────────────────────────────
4892
+ * "I could not get an answer" is `null`, which leaves the approval pending so
4893
+ * the host resolves it the ordinary way. That is the default on timeout and on
4894
+ * a delivery failure: an unreachable webhook must never silently become a "yes",
4895
+ * and it must not become an automatic "no" either, because a rejected tool call
4896
+ * is a wrong answer handed to the model. `onTimeout: "reject"` opts into the
4897
+ * strict reading for deployments that would rather fail the call than leave a
4898
+ * run parked.
4899
+ */
4900
+
4901
+ type WebhookApprovalConfig = {
4902
+ /** Where the pending approval is POSTed so a human can see it. */
4903
+ url: string;
4904
+ /** Static headers, or a thunk so a rotating token is read per call. */
4905
+ headers?: Record<string, string> | (() => Record<string, string>);
4906
+ /**
4907
+ * Status endpoint polled until a decision appears. A function receives the
4908
+ * pending approval, so a per-approval URL can be built. When omitted, the
4909
+ * POST response itself must carry the decision (or a `pollUrl`/`statusUrl`
4910
+ * field, which is the default convention this transport understands).
4911
+ */
4912
+ pollUrl?: string | ((pending: PendingToolApproval, ctx: HookContext) => string | undefined);
4913
+ /** Gap between status checks. Default 2000ms. */
4914
+ pollIntervalMs?: number;
4915
+ /** Total budget for one approval, POST included. Default 300_000ms (5 min). */
4916
+ timeoutMs?: number;
4917
+ /** Override the POST body. Default: `{ type, runId, agentName, depth, approval }`. */
4918
+ buildRequest?: (pending: PendingToolApproval, ctx: HookContext) => unknown;
4919
+ /**
4920
+ * Map a webhook or poll response to a resolution. Returning `null`/`undefined`
4921
+ * means "no decision yet" and keeps polling — it is not an error.
4922
+ */
4923
+ parseDecision?: (response: unknown, pending: PendingToolApproval) => ToolApprovalResolution | null | undefined;
4924
+ /**
4925
+ * What an expired budget means. Default `leave-pending` (return `null`, run
4926
+ * stays paused). `reject` resolves the approval as refused instead.
4927
+ */
4928
+ onTimeout?: "reject" | "leave-pending";
4929
+ name?: string;
4930
+ };
4931
+ /**
4932
+ * Forgiving on purpose, in the same spirit as `normalizeVerdicts`: the shape of
4933
+ * whatever ticketing system sits behind the webhook can change without an SDK
4934
+ * release, and a strict parser would turn a field rename into every approval
4935
+ * timing out.
4936
+ */
4937
+ declare function parseApprovalDecision(response: unknown, pending: PendingToolApproval): ToolApprovalResolution | null;
4938
+ declare function webhookApproval(config: WebhookApprovalConfig): AgentPlugin;
4939
+
4940
+ /**
4941
+ * Keeps the assistant answering in the language it is supposed to answer in.
4942
+ *
4943
+ * The failure this fixes is mundane and constant: a Turkish user asks a
4944
+ * question, a tool returns an English document, and the model drifts into the
4945
+ * language of its context instead of the language of its reader.
4946
+ *
4947
+ * Two hooks, because the problem has two halves:
4948
+ * - `preModelCall` adds a system-level instruction naming the required
4949
+ * language to every call. This is the half that actually fixes drift —
4950
+ * prevention, on the request, where the model can still act on it.
4951
+ * - `preFinalAnswer` measures the answer and, under `action: "deny"`, refuses
4952
+ * it with a reason naming both the detected and the required language, so
4953
+ * the loop gets a specific, actionable correction instead of a retry.
4954
+ *
4955
+ * `deny` is a BACKSTOP FOR DRIFT, not a gate you can demonstrate on demand.
4956
+ * The instruction the first hook adds is the last message on the wire, so it
4957
+ * outranks a user asking for another language: measured against a real model,
4958
+ * five of five attempts to force a mismatch came back in the required language
4959
+ * and the refusal never fired. That is the design working — prevention is the
4960
+ * fix, enforcement is the safety net for the long tail where it slips. Enable
4961
+ * `deny` for that tail, not for a guarantee, and pin `detect` if you need a
4962
+ * deterministic test.
4963
+ *
4964
+ * Note what is deliberately NOT done. `preFinalAnswer` does not rewrite the
4965
+ * answer: translating locally would return text the model never wrote and
4966
+ * nobody reviewed (the same reasoning `outputGuard` gives for only repairing
4967
+ * `maxChars`). And a mismatch is not surfaced at `userPromptSubmit` either —
4968
+ * the user's language is not the thing being constrained.
4969
+ *
4970
+ * ── The detector is a heuristic ─────────────────────────────────────────────
4971
+ * `detectLanguage` is stopwords plus script and diacritic evidence. It is fast,
4972
+ * dependency-free and offline, and it is wrong on short text: "Ok" and "Merci"
4973
+ * carry no signal, and a two-sentence answer full of code and proper nouns
4974
+ * carries very little. `minChars` (default 40, measured after code fences,
4975
+ * inline code, URLs and e-mail addresses are removed) is the guard against
4976
+ * judging text that cannot be judged, and an undetectable answer is always
4977
+ * allowed. Pass `detect` to swap in a real classifier when the cost is worth it.
4978
+ */
4979
+
4980
+ type LanguageGuardConfig = {
4981
+ /**
4982
+ * BCP-47-ish tag the answer must be in ("tr", "en-GB"). Only the base subtag
4983
+ * is compared. The function form reads it per run — typically off
4984
+ * `state.metadata` for a per-user locale.
4985
+ */
4986
+ language: string | ((ctx: HookContext) => string | undefined);
4987
+ /**
4988
+ * `instruct` (default) only steers the request. `deny` additionally refuses a
4989
+ * final answer in the wrong language, costing an extra model turn.
4990
+ */
4991
+ action?: "deny" | "instruct";
4992
+ /** Replace the built-in heuristic. Receives the answer with code/URLs stripped. */
4993
+ detect?: (text: string) => string | undefined;
4994
+ /** Below this many characters of prose the answer is never judged. Default 40. */
4995
+ minChars?: number;
4996
+ name?: string;
4997
+ priority?: number;
4998
+ };
4999
+ /**
5000
+ * Best-effort language of a piece of text: a script check first (a non-Latin
5001
+ * script settles it outright), then stopword and diacritic scoring across the
5002
+ * Latin profiles. Returns `undefined` when the evidence is thin or two
5003
+ * languages score within a point of each other — saying "I don't know" is the
5004
+ * only honest answer a heuristic this small can give, and every caller here
5005
+ * treats it as "allow".
5006
+ */
5007
+ declare function detectLanguage(text: string): string | undefined;
5008
+ declare function languageGuard(config: LanguageGuardConfig): AgentPlugin;
5009
+
5010
+ /**
5011
+ * Centralized manager for structured output across both base Agent and SmartAgent.
5012
+ *
5013
+ * Responsibilities:
5014
+ * - Prepare tools or response_format depending on the resolved strategy
5015
+ * - Build system prompt hints tailored to the strategy
5016
+ * - Build nudge/correction prompts for retries
5017
+ * - Parse final output from tool result or assistant content
5018
+ * - Report structured errors (never silently swallow)
5019
+ */
5020
+ declare class StructuredOutputManager<T> {
5021
+ readonly strategy: StructuredOutputStrategy;
5022
+ readonly schema: ZodSchema<T>;
5023
+ readonly maxRetries: number;
5024
+ constructor(schema: ZodSchema<T>, strategy: StructuredOutputStrategy, config?: StructuredOutputManagerConfig);
5025
+ /**
5026
+ * Get the `response` tool for tool-based strategy.
5027
+ * Returns undefined for native strategy (no tool needed).
5028
+ */
5029
+ getResponseTool(): ToolInterface | undefined;
5030
+ /**
5031
+ * Get response_format config for native strategy.
5032
+ * Returns undefined for tool-based strategy.
5033
+ */
5034
+ getResponseFormat(): Record<string, any> | undefined;
5035
+ /**
5036
+ * Build the system prompt hint that tells the model how to produce structured output.
5037
+ */
5038
+ buildSystemPromptHint(): string;
5039
+ /**
5040
+ * Build a nudge message for when the model didn't produce structured output.
5041
+ * Used by the agent loop when it needs to retry.
5042
+ * User role is intentional: OpenAI-compatible chat templates such as Qwen
5043
+ * reject system messages anywhere except the beginning of the conversation.
5044
+ */
5045
+ buildNudgeMessage(isLastAttempt: boolean): {
5046
+ role: string;
5047
+ content: string;
5048
+ };
5049
+ /**
5050
+ * Build a correction message when schema validation failed.
5051
+ */
5052
+ buildCorrectionMessage(error: StructuredOutputError, _previousAttempt?: unknown): {
5053
+ role: string;
5054
+ content: string;
5055
+ };
5056
+ /**
5057
+ * Try to parse structured output from the tool-based finalization result.
5058
+ * Called when __structuredOutputParsed is available in ctx.
5059
+ */
5060
+ parseFromToolResult(data: unknown): StructuredOutputResult<T>;
5061
+ /**
5062
+ * Try to parse structured output from assistant message content.
5063
+ * For native strategy: content should be valid JSON.
5064
+ * For tool-based strategy: last-resort fallback extraction from text.
5065
+ */
5066
+ parseFromContent(content: string): StructuredOutputResult<T>;
5067
+ /**
5068
+ * Create a "no output" error result.
5069
+ */
5070
+ noOutputResult(attempts: number, rawContent?: string): StructuredOutputResult<T>;
5071
+ /**
5072
+ * Create a "max retries" error result.
5073
+ */
5074
+ maxRetriesResult(lastError: StructuredOutputError, attempts: number, rawContent?: string): StructuredOutputResult<T>;
5075
+ }
5076
+
5077
+ /**
5078
+ * Tool-based structured output strategy.
5079
+ *
5080
+ * Injects a hidden `response` tool that the model must call with the final JSON.
5081
+ * This is the universal fallback that works with all providers.
5082
+ */
5083
+ declare class ToolBasedStrategy implements StructuredOutputStrategy {
5084
+ readonly kind: "tool_based";
5085
+ /**
5086
+ * Create the `response` tool for a given Zod schema.
5087
+ * The tool validates input against the schema and returns a sentinel object
5088
+ * that the tools node picks up to finalize the structured output.
5089
+ */
5090
+ createResponseTool<T>(schema: ZodSchema<T>): ToolInterface;
5091
+ /**
5092
+ * Try to extract structured output from raw assistant text content.
5093
+ * Used as a last resort when the model writes JSON directly instead of calling the tool.
5094
+ */
5095
+ extractFromText<T>(content: string, schema: ZodSchema<T>): {
5096
+ data: T;
5097
+ } | {
5098
+ error: StructuredOutputError;
5099
+ };
5100
+ buildCorrectionPrompt(error: ZodError<any>, previousAttempt: unknown): string;
5101
+ }
5102
+
5103
+ /**
5104
+ * Native JSON Schema strategy for providers that support `response_format`.
5105
+ *
5106
+ * Works with OpenAI (gpt-4o+), Google Gemini, and similar providers
5107
+ * that accept `response_format: { type: "json_schema", json_schema: {...} }`.
5108
+ *
5109
+ * The model guarantees valid JSON output matching the schema — no tool needed.
5110
+ */
5111
+ declare class NativeJsonSchemaStrategy implements StructuredOutputStrategy {
5112
+ readonly kind: "native";
5113
+ private resolveJsonPointer;
5114
+ private unwrapRootObjectSchema;
5115
+ /**
5116
+ * Convert a Zod schema to the JSON Schema object used in response_format.
5117
+ */
5118
+ toJsonSchema(schema: ZodSchema<any>, name?: string): Record<string, any>;
5119
+ /**
5120
+ * Build response_format configuration for the model call.
5121
+ * Returns the object that should be spread into model invocation options.
5122
+ */
5123
+ buildResponseFormat(schema: ZodSchema<any>, name?: string): Record<string, any>;
5124
+ /**
5125
+ * Parse and validate model response content.
5126
+ * With native support, content is guaranteed JSON — but we still validate with Zod
5127
+ * for type safety and field-level error reporting.
5128
+ */
5129
+ extractOutput<T>(content: string, schema: ZodSchema<T>): {
5130
+ data: T;
5131
+ } | {
5132
+ error: StructuredOutputError;
5133
+ };
5134
+ buildCorrectionPrompt(error: ZodError<any>, previousAttempt: unknown): string;
5135
+ }
5136
+
5137
+ /**
5138
+ * Resolve the most appropriate structured output strategy for a given model.
5139
+ *
5140
+ * If the model exposes capabilities (via adapter or direct provider),
5141
+ * we use native JSON Schema support when available. Otherwise we fall back
5142
+ * to the universal tool-based approach.
5143
+ *
5144
+ * When direct providers are added to the SDK, they should set
5145
+ * `model.capabilities.structuredOutput = "native"` for providers that support
5146
+ * response_format (OpenAI, Gemini, etc.).
5147
+ */
5148
+ declare function resolveStrategy(model: any): StructuredOutputStrategy;
5149
+ /**
5150
+ * Extract capabilities from a model object.
5151
+ * Supports:
5152
+ * - model.capabilities (set by adapters or direct providers)
5153
+ * - Auto-detection from model class name / metadata
5154
+ */
5155
+ declare function getModelCapabilities(model: any): ModelCapabilities;
5156
+
5157
+ declare function captureSnapshot(state: SmartState, options?: SnapshotOptions): AgentSnapshot;
5158
+ declare function restoreSnapshot(snapshot: AgentSnapshot, restoreOptions?: RestoreSnapshotOptions): SmartState;
5159
+
5160
+ declare function resolveToolApprovalState(state: SmartState, resolution: ToolApprovalResolution): SmartState;
5161
+
5162
+ declare function resolveUserQuestionState(state: SmartState, resolution: UserQuestionResolution): SmartState;
5163
+
5164
+ /**
5165
+ * The built-in ask-user tool's name. Exported because more than one layer has to
5166
+ * recognise it: `createSmartAgent` builds the tool into the list it hands to
5167
+ * `createAgent`, which must then not attach a second one of its own.
5168
+ */
5169
+ declare const ASK_USER_TOOL_NAME = "ask_user_question";
5170
+ type AskUserStateRef = {
5171
+ pendingUserQuestions?: PendingUserQuestion[];
5172
+ ctx?: Record<string, any>;
5173
+ __onEvent?: (event: any) => void;
5174
+ __currentToolCallId?: string;
5175
+ };
5176
+ declare function createAskUserQuestionTool(stateRef: AskUserStateRef, config: HumanInTheLoopAskUserConfig): ToolInterface<any, any, any>;
5177
+
5178
+ declare function fromLangchainTools<T extends ToolInterface = ToolInterface>(tools: any[]): T[];
5179
+
5180
+ type ResolvedReflectionConfig = {
5181
+ enabled: boolean;
5182
+ cadence: ReflectionCadence;
5183
+ mode: "piggyback" | "separate";
5184
+ maxTokens: number;
5185
+ maxChars: number;
5186
+ keepLast: number;
5187
+ summarize: boolean;
5188
+ promptTemplate?: string;
5189
+ emitEvents: boolean;
5190
+ maxPerRun?: number;
5191
+ everyNTurns: number;
5192
+ feedTo: "memory" | "plan" | "none";
5193
+ shouldReflect?: (ctx: ReflectionHookContext) => boolean;
5194
+ buildPrompt?: (ctx: ReflectionHookContext & {
5195
+ defaultPrompt: string;
5196
+ maxChars: number;
5197
+ }) => string;
5198
+ onReflection?: (record: ReflectionRecord, ctx: ReflectionHookContext) => void;
5199
+ };
5200
+ type ResolvedReasoning = {
5201
+ enabled: boolean;
5202
+ level: ReasoningLevel;
5203
+ native?: NativeReasoningConfig;
5204
+ reflection: ResolvedReflectionConfig;
5205
+ };
5206
+ /**
5207
+ * Validates a user-supplied ReasoningConfig and throws a descriptive error for
5208
+ * obviously-wrong values. Pure; safe to call before resolveReasoning.
5209
+ */
5210
+ declare function validateReasoningConfig(input: ReasoningConfig | undefined): void;
5211
+ declare function resolveReasoning(input: ReasoningConfig | undefined): ResolvedReasoning | undefined;
5212
+
5213
+ /**
5214
+ * Tools the agent loop uses to steer ITSELF. Their arguments are never digested —
5215
+ * digesting them is never a win (the arguments are small) and always a risk:
5216
+ * - `response` carries the run's final structured output,
5217
+ * - `manage_plan` (and its deprecated alias `manage_todo_list` — same handler,
5218
+ * same shared state, see contextTools.ts) carries the living plan,
5219
+ * - `ask_user_question` carries the question the user's answer replies to,
5220
+ * - `open_skill` / `bind_skill_tools` / `search_skills` name the capability being
5221
+ * loaded, which the rest of the run reasons about,
5222
+ * - `get_tool_response` is the recovery path itself.
5223
+ * They also default to `keep_full` on the output axis (overridable per tool).
5224
+ */
5225
+ declare const CONTROL_PLANE_TOOL_NAMES: readonly string[];
5226
+ /**
5227
+ * Delegation tools: the arguments ARE the brief handed to the child agent — the
5228
+ * parent must be able to say what it delegated. Never digested. The child's report
5229
+ * (the output) may still be archived and paged back in.
5230
+ */
5231
+ declare const DELEGATION_TOOL_NAMES: readonly string[];
5232
+ declare const DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS = 2000;
5233
+ declare const DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS = 200;
5234
+ /** Key marking a digested argument field. Recognized as a recovery reference. */
5235
+ declare const TOOL_INPUT_DIGEST_KEY = "__digest";
5236
+ /**
5237
+ * Compact textual preview of a value for archive/structured retention. Used by
5238
+ * the summarizer when an old tool response is reduced to a placeholder. Not
5239
+ * used at tool execution time.
5240
+ */
5241
+ declare function summarizeObject(value: any): string;
5242
+ /**
5243
+ * Tool-definition-declared retention specs, keyed by tool name. Built from the
5244
+ * runtime's live tool list so a skill-bound tool contributes its own declaration.
5245
+ */
5246
+ type ToolRetentionDeclarations = Map<string, ToolRetentionSpec>;
5247
+ declare function collectToolRetentionDeclarations(tools: Array<ToolInterface<any, any, any>> | undefined): ToolRetentionDeclarations;
5248
+ /**
5249
+ * Resolves the retention policy applied by the summarizer when context limits
5250
+ * are reached. Critical tools are never reduced.
5251
+ *
5252
+ * Precedence (first match wins):
5253
+ * 1. `criticalTools` — absolute, never reduced (documented contract).
5254
+ * 2. `toolResponses.retentionByTool[name].output` — caller's two-axis override.
5255
+ * 3. `toolResponses.toolResponseRetentionByTool[name]` — legacy single-axis map.
5256
+ * 4. the tool definition's own `retention.output`.
5257
+ * 5. built-in control-plane default (`keep_full`).
5258
+ * 6. `toolResponses.defaultPolicy`.
5259
+ */
5260
+ declare function resolveSummarizationRetention(toolName: string, config: ResolvedSmartAgentConfig, declarations?: ToolRetentionDeclarations): ToolResponseRetentionPolicy;
5261
+ /**
5262
+ * Resolves the retention policy applied to a tool call's ARGUMENTS.
5263
+ *
5264
+ * Precedence (first match wins):
5265
+ * 1. control-plane + delegation tools — always `keep` (hard invariant).
5266
+ * 2. `criticalTools` — a tool whose response may never be reduced does not get
5267
+ * its request reduced either.
5268
+ * 3. `toolResponses.retentionByTool[name].input`.
5269
+ * 4. the tool definition's own `retention.input`.
5270
+ * 5. `toolResponses.defaultInputPolicy` (defaults to `keep`).
5271
+ *
5272
+ * The default is `keep`, so argument digesting never happens unless a tool or a
5273
+ * caller explicitly asks for it.
5274
+ */
5275
+ declare function resolveInputRetention(toolName: string, config: ResolvedSmartAgentConfig, declarations?: ToolRetentionDeclarations): ToolInputRetentionPolicy;
5276
+ type ToolInputDigestOptions = {
5277
+ /** Per-field character threshold. Strings at or below this are preserved verbatim. */
5278
+ maxFieldChars?: number;
5279
+ /** Leading characters of a digested field kept as a preview. */
5280
+ headChars?: number;
5281
+ /** Execution id embedded in each marker so the model can page the original back in. */
5282
+ executionId?: string;
5283
+ };
5284
+ type ToolInputDigestResult = {
5285
+ /** The rewritten value. Identical reference when nothing was digested. */
5286
+ value: unknown;
5287
+ /** Dotted paths of the fields that were replaced by a digest marker. */
5288
+ digestedPaths: string[];
5289
+ /** Characters reclaimed from the serialized arguments. */
5290
+ reclaimedChars: number;
5291
+ };
5292
+ /**
5293
+ * Field-level argument digest.
5294
+ *
5295
+ * Walks the argument structure and replaces ONLY string leaves longer than
5296
+ * `maxFieldChars` with a compact descriptor. Every other field — paths, ids,
5297
+ * modes, indexes, booleans, short strings — is preserved verbatim, so a call like
5298
+ *
5299
+ * { filePath: "/reports/q3.md", mode: "append", section: 3, content: "<60k>" }
5300
+ *
5301
+ * compacts to
5302
+ *
5303
+ * { filePath: "/reports/q3.md", mode: "append", section: 3,
5304
+ * content: { __digest: { chars: 61840, sha256: "…", head: "# Q3 …", recover: "…" } } }
5305
+ *
5306
+ * The model can still state exactly what it did; only the payload it no longer
5307
+ * needs to re-read is gone. Idempotent: an existing digest marker is left alone.
5308
+ */
5309
+ declare function digestToolInputValue(value: unknown, options?: ToolInputDigestOptions): ToolInputDigestResult;
5310
+ /**
5311
+ * Digest a serialized `tool_call.function.arguments` JSON string in place.
5312
+ * Returns the input string unchanged when nothing needed digesting, when the
5313
+ * string is not parseable JSON (never guess at a non-JSON payload), or when the
5314
+ * result would not actually be smaller.
5315
+ */
5316
+ declare function digestToolInputArguments(argumentsJson: string, options?: ToolInputDigestOptions): {
5317
+ arguments: string;
5318
+ digestedPaths: string[];
5319
+ reclaimedChars: number;
5320
+ };
5321
+ /**
5322
+ * Parse tool arguments against the tool's schema.
5323
+ *
5324
+ * Two passes, and the order is the contract: the raw arguments are validated
5325
+ * FIRST, so a model that emits well-typed arguments is unaffected and the schema
5326
+ * stays a real constraint. Only when that fails are the arguments run through
5327
+ * `coerceToolArgs` and re-validated — repairing the type artifacts smaller and
5328
+ * grammar-constrained backends produce (a nested object sent as a JSON string, a
5329
+ * number sent as `"60"`, `""` standing in for an omitted optional) instead of
5330
+ * spending a turn telling the model something it did not get wrong.
5331
+ *
5332
+ * Coercion never fabricates a value, so a genuinely missing required argument
5333
+ * still fails — and it fails with the ORIGINAL issues plus the shape the tool
5334
+ * actually wants, because "expected object, received string" on its own does not
5335
+ * tell a weaker model which key to fix.
5336
+ */
5337
+ declare function validateToolArgs(tool: ToolInterface<any, any, any>, args: unknown): {
5338
+ ok: true;
5339
+ value: any;
5340
+ coerced?: boolean;
5341
+ } | {
5342
+ ok: false;
5343
+ message: string;
5344
+ };
5345
+
5346
+ /**
5347
+ * Re-type `value` so it satisfies `schema`, walking both together.
5348
+ *
5349
+ * Returns the original value untouched whenever nothing needs repairing or
5350
+ * nothing sensible can be done — this must never throw, because it runs on the
5351
+ * error path and a throw here would replace a useful validation message with a
5352
+ * crash.
5353
+ */
5354
+ declare function coerceToolArgs(schema: unknown, value: unknown): unknown;
5355
+
5356
+ declare function fileSink(path?: string): TraceSinkConfig;
5357
+ type CustomSinkArg = ((event: TraceEventRecord) => void | Promise<void>) | {
5358
+ onEvent?: (event: TraceEventRecord) => void | Promise<void>;
5359
+ onSession?: (session: TraceSessionFile) => void | Promise<void>;
5360
+ };
5361
+ declare function customSink(handler: CustomSinkArg): TraceSinkConfig;
5362
+ declare function cognipeerSink(apiKey: string): TraceSinkConfig;
5363
+ declare function cognipeerSink(url: string | undefined, apiKey: string): TraceSinkConfig;
5364
+ declare function httpSink(url: string, headers?: Record<string, string>): TraceSinkConfig;
5365
+ /**
5366
+ * Create an OTLP/HTTP JSON sink that exports traces in OpenTelemetry format.
5367
+ * @param endpoint OTLP endpoint URL (e.g. "https://console.cognipeer.com/api/client/v1/traces")
5368
+ * @param headers Optional headers (e.g. { Authorization: "Bearer ..." })
5369
+ */
5370
+ declare function otlpSink(endpoint: string, headers?: Record<string, string>): TraceSinkConfig;
5371
+ /**
5372
+ * Convert a complete TraceSessionFile into an OTLP ExportTraceServiceRequest (JSON).
5373
+ * Produces a root span for the session and child spans for each event.
5374
+ */
5375
+ declare function traceSessionToOtlp(session: TraceSessionFile): Record<string, unknown>;
5376
+ /** Generate a W3C-compatible trace ID (32 hex chars / 128-bit). */
5377
+ declare function generateTraceId(): string;
5378
+ /** Generate an OTel span ID (16 hex chars / 64-bit). */
5379
+ declare function generateSpanId(): string;
5380
+ /**
5381
+ * Build the `tool_definitions` section for one model call, or undefined when
5382
+ * nothing usable was supplied. Exported for provider/node code that assembles
5383
+ * sections itself.
5384
+ */
5385
+ declare function buildToolDefinitionsSection(toolDefinitions: Array<{
5386
+ name: string;
5387
+ description?: string;
5388
+ parameters?: Record<string, any>;
5389
+ }>): TraceToolDefinitionsSection | undefined;
5390
+ /**
5391
+ * Build the `response_format` section for one model call, or undefined when
5392
+ * nothing usable was supplied.
5393
+ *
5394
+ * Accepts either the invoke-options wrapper produced by
5395
+ * `NativeJsonSchemaStrategy.buildResponseFormat()` (`{ response_format: {…} }`)
5396
+ * or a bare `response_format` object, so callers can pass whatever they hold.
5397
+ * Exported for provider/node code that assembles sections itself.
5398
+ */
5399
+ declare function buildResponseFormatSection(responseFormat: Record<string, any> | undefined, strategy?: "native" | "tool_based"): TraceResponseFormatSection | undefined;
5400
+ /**
5401
+ * Start a streaming trace session. Should be called before recording events in streaming mode.
5402
+ * This sends the session start to the remote endpoint immediately.
5403
+ */
5404
+ declare function startStreamingSession(session: TraceSessionRuntime | undefined, agentRuntime?: AgentRuntimeConfig): Promise<void>;
5405
+
3314
5406
  type ProviderRetryPolicy = {
3315
5407
  /** Maximum number of retries on 429/5xx responses. Default: 3. */
3316
5408
  maxRetries?: number;
@@ -3527,4 +5619,4 @@ declare function fromNativeProvider(provider: BaseProvider, options?: NativeMode
3527
5619
  */
3528
5620
  declare function createProvider(config: ProviderConfig): BaseProvider;
3529
5621
 
3530
- export { type AIMessage, ASK_USER_TOOL_NAME, type AgentInstance, type AgentInvokeResult, type AgentLimits, type AgentOptions, type AgentRuleOptions, type AgentRuntimeConfig, type AgentSnapshot, type AgentSnapshotMetadata, type AgentState, AnthropicProvider, type AnthropicProviderConfig, type AudioContent, AzureProvider, type AzureProviderConfig, type BaseChatMessage, type BaseChatMessagePart, type BaseChatModel, type BaseMessage, BaseProvider, BedrockProvider, type BedrockProviderConfig, type BuildChildConfig, type BuiltInRuntimeProfile, CCRStore, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, type CancellationTokenLike, type CancelledEvent, type ChatCompletionChunk, type ChatCompletionRequest, type ChatCompletionResponse, type ChildContextPolicy, type CodeDetectionRuleOptions, type CodeGuardrailOptions, type CompressToolOutputParams, type ContextPilotCCRConfig, type ContextPilotCacheAlignmentConfig, type ContextPilotCompressionConfig, type ContextPilotCompressionStats, type ContextPilotCompressorKind, type ContextPilotConfig, type ContextPilotDedupConfig, type ContextPilotDiffCompressionConfig, type ContextPilotJsonCompressionConfig, type ContextPilotLogCompressionConfig, type ContextPilotResult, type ContextPilotRuntime, type ContextPilotSearchCompressionConfig, type ContextPilotTextCompressionConfig, type ContextPolicy, type ContextToolsStateRef, type ConversationGuardrail, type CustomRuleCallback, type CustomRuleOptions, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, type DelegationEventStamp, type DelegationMode, type EvalCase, type EvalCaseResult, type EvalFamily, type EvalHarnessMetrics, type EvalHarnessParams, type EvalHarnessResult, type EvalProfileDescriptor, type EvalProfileTarget, type FileContent, type FinalAnswerEvent, type FinishReason, type GuardrailContext, type GuardrailDisposition, type GuardrailEvent, type GuardrailIncident, type GuardrailOutcome, GuardrailPhase, type GuardrailRule, type HandoffDescriptor, type HandoffEvent, type HumanInTheLoopAskUserConfig, type HumanInTheLoopOptions, type HumanInTheLoopRuntimeConfig, type ImageContent, InMemoryMemoryStore, type InvokeConfig, type JsonGuardrailOptions, type JsonSchemaRuleOptions, type LoadSkillsOptions, type MemoryFact, type MemoryProviderKind, type MemoryReadPolicy, type MemoryScope, type MemoryStore, type MemoryWritePolicy, type Message, type MetadataEvent, type ModelCapabilities, NativeJsonSchemaStrategy, type NativeModelOptions, type NativeReasoningConfig, OpenAICompatibleProvider, type OpenAICompatibleProviderConfig, OpenAIProvider, type OpenAIProviderConfig, PREOPEN_TOOL_CALL_PREFIX, type PendingToolApproval, type PendingUserQuestion, type PlanEvent, type PlanStepRecord, type PlanningMode, type PreopenSkillsResult, type ProfileConfig, type ProgressEvent, type ProgressUpdate, type PromptHooks, type ProviderConfig, ProviderError, type ToolCall as ProviderToolCall, type ToolDefinition as ProviderToolDefinition, type ProviderType, type ReasoningConfig, type ReasoningLevel, type ReflectionCadence, type ReflectionConfig, type ReflectionEvent, type ReflectionHookContext, type ReflectionRecord, type RegexGuardrailOptions, type RegexRuleOptions, type ReplanPolicy, type ResolvedContextPilotConfig, type ResolvedSmartAgentConfig, type ResolvedTraceConfig, type ResolvedTraceSink, type RestoreSnapshotOptions, type RuntimeProfile, SMALL_TIER_SKILL_POLICY, type SerializableSmartState, type Skill, type SkillDisclosure, type SkillExecutionContext, type SkillFrontmatter, type SkillFs, type SkillModelTier, type SkillPolicy, type SkillRegistryRef, type SkillToolDeps, type SkillToolHeader, type SmartAgentBudgetConfig, type SmartAgentContextConfig, type SmartAgentCustomProfileConfig, type SmartAgentDelegationConfig, type SmartAgentEvent, type SmartAgentInstance, type SmartAgentLimits, type SmartAgentMemoryConfig, type SmartAgentOptions, type SmartAgentPlanningConfig, type SmartAgentSummarizationConfig, type SmartAgentToolResponseConfig, type SmartAgentTracingConfig, type SmartModel, type SmartState, type SmartToolFn, type SnapshotOptions, type SnapshotRuntimeHint, type StreamChunk, type StreamEvent, type StructuredOutputError, type StructuredOutputFieldError, StructuredOutputManager, type StructuredOutputManagerConfig, type StructuredOutputResult, type StructuredOutputStrategy, type StructuredSummary, type SubagentDef, type SubagentEvent, type SubagentMode, type SubagentPendingRecord, type SubagentPolicy, type SubagentRegistryRef, type SubagentResult, type SubagentToolDeps, type SubagentToolNames, type SummarizationEvent, type SummarizationMode, type SummaryFactItem, type SummaryIntegrityCheck, TOOL_INPUT_DIGEST_KEY, type TextContent, type TokenCounter, type TokenUsage, type ToolApprovalEvent, type ToolApprovalResolution, type ToolApprovalStatus, ToolBasedStrategy, type ToolCachePolicy, type ToolCallEvent, type ToolInputDigestOptions, type ToolInputDigestResult, type ToolInputRetentionPolicy, type ToolInterface, type ToolResponseClassification, type ToolResponseRetentionPolicy, type ToolRetentionDeclarations, type ToolRetentionSpec, type ToolRetryPolicy, type TraceDataSection, type TraceErrorRecord, type TraceEventRecord, type TraceMessageSection, type TraceMetadataSection, type TraceSessionConfigSnapshot, type TraceSessionFile, type TraceSessionStatus, type TraceSessionSummary, type TraceSinkCognipeerConfig, type TraceSinkConfig, type TraceSinkCustomConfig, type TraceSinkFileConfig, type TraceSinkHttpConfig, type TraceSinkOtlpConfig, type TraceSinkSnapshot, type TraceSummarySection, type TraceToolCallSection, type TraceToolDefinition, type TraceToolDefinitionsSection, type TraceToolDetails, type TraceToolResponseSection, type TraceToolResultSection, type TracingConfig, type TracingMode, type UnifiedMessage, type UserQuestionAnswer, type UserQuestionAnswerSet, type UserQuestionEvent, type UserQuestionItem, type UserQuestionOption, type UserQuestionResolution, type UserQuestionStatus, VertexProvider, type VertexProviderConfig, type VolatileContentFinding, type VolatileContentPattern, agentVerdictRule, appendBoundTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, codePresenceRule, coerceToolArgs, cognipeerSink, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customSink, dedupeToolsByName, defaultTokenCounter, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpSink, isSmartModel, jsonSchemaRule, loadSkillsFromDisk, normalizeSmartAgentOptions, otlpSink, parseSkillFrontmatter, preopenSkills, preopenToolCallId, readMemoryFacts, regexRule, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, setTokenCounter, startStreamingSession, summarizeObject, tokenize, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, withTools, withinDepth, writeSummaryFactsToMemory };
5622
+ export { type AIMessage, ASK_USER_TOOL_NAME, type AgentInstance, type AgentInvokeResult, type AgentLimits, type AgentOptions, type AgentPlugin, type AgentRuleOptions, type AgentRuntimeConfig, type AgentSnapshot, type AgentSnapshotMetadata, type AgentState, AnthropicProvider, type AnthropicProviderConfig, type ApprovalTransport, type AudioContent, type AuditEntry, type AuditLogConfig, type AzureContentSafetyConfig, AzureProvider, type AzureProviderConfig, type BaseChatMessage, type BaseChatMessagePart, type BaseChatModel, type BaseMessage, BaseProvider, type BedrockGuardrailConfig, BedrockProvider, type BedrockProviderConfig, type BudgetGuardConfig, type BuildChildConfig, type BuiltInRuntimeProfile, CCRStore, CONSOLE_HOOK_MAP, CONTEXT_PILOT_JSON_MARKER_KEY, CONTROL_PLANE_TOOL_NAMES, type CancellationTokenLike, type CancelledEvent, type CapabilityStatus, type ChatCompletionChunk, type ChatCompletionRequest, type ChatCompletionResponse, type CheckpointPluginConfig, type CheckpointStore, type ChildContextPolicy, type CodeDetectionRuleOptions, type CodeGuardrailOptions, type CognipeerGuardrailConfig, type CompressToolOutputParams, type ContextBuilder, type ContextPilotCCRConfig, type ContextPilotCacheAlignmentConfig, type ContextPilotCompressionConfig, type ContextPilotCompressionStats, type ContextPilotCompressorKind, type ContextPilotConfig, type ContextPilotDedupConfig, type ContextPilotDiffCompressionConfig, type ContextPilotJsonCompressionConfig, type ContextPilotLogCompressionConfig, type ContextPilotResult, type ContextPilotRuntime, type ContextPilotSearchCompressionConfig, type ContextPilotTextCompressionConfig, type ContextPolicy, type ContextToolsStateRef, type ConversationGuardrail, type ConversationPluginConfig, type ConversationStore, type CostEstimator, type CustomRuleCallback, type CustomRuleOptions, DEFAULT_MAX_TOOL_INPUT_FIELD_CHARS, DEFAULT_PROFILE_CONFIGS, DEFAULT_SKILL_POLICY, DEFAULT_SUBAGENT_POLICY, DEFAULT_SUBAGENT_TOOL_NAMES, DEFAULT_TOOL_INPUT_DIGEST_HEAD_CHARS, DELEGATION_TOOL_NAMES, DedupTracker, type DelegationEventStamp, type DelegationMode, type EvalCase, type EvalCaseResult, type EvalFamily, type EvalHarnessMetrics, type EvalHarnessParams, type EvalHarnessResult, type EvalProfileDescriptor, type EvalProfileTarget, type FileContent, type FinalAnswerEvent, type FinishReason, type GateResult, type GuardrailCallContext, type GuardrailContext, type GuardrailDisposition, type GuardrailEvent, type GuardrailIncident, type GuardrailOutcome, GuardrailPhase, type GuardrailPhaseName, type GuardrailPluginOptions, type GuardrailRequest, type GuardrailRule, type GuardrailRuleResult, type GuardrailTransport, type GuardrailVerdict, type GuardrailViolation, HOOK_CONTRACT_VERSION, HOOK_NAMES, type HandoffDescriptor, type HandoffEvent, type HookContext, type HookDecision, type HookHandler, type HookMap, type HookName, type HookRegistrations, HookTimeoutError, type HttpGuardrailOptions, type HumanInTheLoopAskUserConfig, type HumanInTheLoopOptions, type HumanInTheLoopRuntimeConfig, type ImageContent, InMemoryMemoryStore, type InjectionScan, type InvokeConfig, type JsonGuardrailOptions, type JsonSchemaRuleOptions, type LangfuseBuildContext, type LangfuseEvent, type LangfuseEventKind, type LangfuseTracingConfig, type LanguageGuardConfig, type LoadSkillsOptions, type MaybePromise, type McpConfig, type McpConnection, type MediaAttachment, type MediaKind, type MediaPolicyConfig, type MemoryFact, type MemoryProviderKind, type MemoryReadPolicy, type MemoryScope, type MemoryStore, type MemoryWritePolicy, type Message, type MetadataEvent, type ModelCapabilities, NativeJsonSchemaStrategy, type NativeModelOptions, type NativeReasoningConfig, OpenAICompatibleProvider, type OpenAICompatibleProviderConfig, type OpenAIModerationConfig, OpenAIProvider, type OpenAIProviderConfig, type OtelTracingConfig, type OutputGuardConfig, PREOPEN_TOOL_CALL_PREFIX, type PendingToolApproval, type PendingUserQuestion, type PiiDetector, type PiiEntity, type PiiRedactionConfig, type PlanEvent, type PlanStepRecord, type PlanningMode, type PluginContributions, type PluginEvent, type PluginFailureMode, type PluginHost, type PluginHostOptions, type PluginLogger, type PluginProvides, type PluginRunHost, type PluginSetupContext, type PortkeyGatewayConfig, type PortkeyGuardrailConfig, type PreopenSkillsResult, type ProfileConfig, type ProgressEvent, type ProgressUpdate, type PromptHooks, type PromptInjectionFamily, type PromptInjectionGuardConfig, type PromptSource, type ProviderConfig, ProviderError, type ToolCall as ProviderToolCall, type ToolDefinition as ProviderToolDefinition, type ProviderType, type RateLimitConfig, type ReasoningConfig, type ReasoningLevel, type RedactionResult, type ReflectionCadence, type ReflectionConfig, type ReflectionEvent, type ReflectionHookContext, type ReflectionRecord, type RegexGuardrailConfig, type RegexGuardrailOptions, type RegexRuleOptions, type ReplanPolicy, type ResolvedContextPilotConfig, type ResolvedSmartAgentConfig, type ResolvedTraceConfig, type ResolvedTraceSink, type ResponseCacheConfig, type RestoreSnapshotOptions, type RuntimeProfile, SMALL_TIER_SKILL_POLICY, type SdkCapabilities, type SerializableSmartState, type SessionMetrics, type SessionMetricsConfig, type Skill, type SkillDisclosure, type SkillExecutionContext, type SkillFrontmatter, type SkillFs, type SkillModelTier, type SkillPolicy, type SkillRegistryRef, type SkillSource, type SkillToolDeps, type SkillToolHeader, type SlotName, type SmartAgentBudgetConfig, type SmartAgentContextConfig, type SmartAgentCustomProfileConfig, type SmartAgentDelegationConfig, type SmartAgentEvent, type SmartAgentInstance, type SmartAgentLimits, type SmartAgentMemoryConfig, type SmartAgentOptions, type SmartAgentPlanningConfig, type SmartAgentSummarizationConfig, type SmartAgentToolResponseConfig, type SmartAgentTracingConfig, type SmartModel, type SmartState, type SmartToolFn, type SnapshotOptions, type SnapshotRuntimeHint, type StreamChunk, type StreamEvent, type StructuredOutputError, type StructuredOutputFieldError, StructuredOutputManager, type StructuredOutputManagerConfig, type StructuredOutputResult, type StructuredOutputStrategy, type StructuredSummary, type SubagentDef, type SubagentEvent, type SubagentMode, type SubagentPendingRecord, type SubagentPolicy, type SubagentRegistryRef, type SubagentResult, type SubagentToolDeps, type SubagentToolNames, type SummarizationEvent, type SummarizationMode, type SummarizerInput, type SummarizerResult, type SummarizerStrategy, type SummaryFactItem, type SummaryIntegrityCheck, TOOL_INPUT_DIGEST_KEY, type TextContent, type TokenCounter, type TokenUsage, type ToolApprovalEvent, type ToolApprovalResolution, type ToolApprovalStatus, ToolBasedStrategy, type ToolCachePolicy, type ToolCallEvent, type ToolInputDigestOptions, type ToolInputDigestResult, type ToolInputRetentionPolicy, type ToolInterface, type ToolPolicyConfig, type ToolResponseClassification, type ToolResponseRetentionPolicy, type ToolRetentionDeclarations, type ToolRetentionSpec, type ToolRetryPolicy, type ToolRule, type TraceDataSection, type TraceErrorRecord, type TraceEventRecord, type TraceMessageSection, type TraceMetadataSection, type TraceSessionConfigSnapshot, type TraceSessionFile, type TraceSessionStatus, type TraceSessionSummary, type TraceSinkCognipeerConfig, type TraceSinkConfig, type TraceSinkCustomConfig, type TraceSinkFileConfig, type TraceSinkHttpConfig, type TraceSinkOtlpConfig, type TraceSinkSnapshot, type TraceSummarySection, type TraceToolCallSection, type TraceToolDefinition, type TraceToolDefinitionsSection, type TraceToolDetails, type TraceToolResponseSection, type TraceToolResultSection, type TracingConfig, type TracingMode, type UnifiedMessage, type UserQuestionAnswer, type UserQuestionAnswerSet, type UserQuestionEvent, type UserQuestionItem, type UserQuestionOption, type UserQuestionResolution, type UserQuestionStatus, VertexProvider, type VertexProviderConfig, type VolatileContentFinding, type VolatileContentPattern, type WebhookApprovalConfig, agentVerdictRule, appendBoundTools, auditLog, azureContentSafety, bedrockGuardrail, budgetGuard, buildHandoffTools, buildResponseFormatSection, buildSkillHeaderBlock, buildSubagentCatalogBlock, buildSystemPrompt, buildToolDefinitionsSection, canOpenSkill, canSpawn, captureSnapshot, checkpointing, codePresenceRule, coerceToolArgs, cognipeerGuardrail, cognipeerSink, collectAttachments, collectToolRetentionDeclarations, composeToolSets, compressDiffOutput, compressJsonOutput, compressLogOutput, compressSearchOutput, compressTextOutput, compressToolOutput, contentToString, conversationHistory, countApproxTokens, countMessagesTokens, createAgent, createAgentNode, createAskUserQuestionTool, createBindSkillToolsTool, createCodeGuardrail, createContextPilotRuntime, createContextSummarizeNode, createContextTools, createDelegateTool, createGetToolResponseTool, createGuardrail, createGuardrailPlugin, createJsonGuardrail, createManageTodoListAliasTool, createManageTodoTool, createOpenSkillTool, createParallelTool, createPluginHost, createProvider, createRegexGuardrail, createResolverNode, createSearchSkillsTool, createSkillRegistryRef, createSkillTools, createSmartAgent, createSpawnTool, createSubagentRegistryRef, createSubagentTools, createTool, createToolLimitFinalizeNode, createToolsNode, customCallbackRule, customGuardrail, customSink, dedupeToolsByName, defaultTokenCounter, defineHook, definePlugin, detectLanguage, detectTextFormat, detectVolatileContent, digestToolInputArguments, digestToolInputValue, emptyUsage, evaluateGuardrails, extractLatestUserQuery, extractMessageText, fileCheckpointStore, fileSink, findSubagent, formatZodError, fromLangchainModel, fromLangchainTools, fromNativeProvider, generateSpanId, generateTraceId, getModelCapabilities, getNestedValue, getResolvedSmartConfig, getTokenCounter, hasToolResponseRecoveryReference, httpGuardrail, httpSink, inMemoryCheckpointStore, inMemoryConversationStore, isHookImplemented, isSmartModel, isValidIban, isValidLuhn, isValidTckn, jsonSchemaRule, defaultBuildPayload as langfuseDefaultPayload, langfuseTracing, languageGuard, loadSkillsFromDisk, mapConsoleHookVerdict, mapTextParts, mcp, mediaPolicy, normalizeSmartAgentOptions, normalizeVerdicts, openAIModeration, otelTracing, otlpSink, outputGuard, parseApprovalDecision, parseSkillFrontmatter, pathSandbox, piiRedaction, pluginCapabilities, portkeyGateway, portkeyGuardrail, preopenSkills, preopenToolCallId, promptInjectionGuard, rateLimit, readMemoryFacts, redactText, regexGuardrail, regexRule, replaceTextContent, resolveAvailableSkills, resolveAvailableSubagents, resolveInputRetention, resolveMemoryStore, resolveReasoning, resolveStrategy, resolveSubagentTools, resolveSummarizationRetention, resolveToolApprovalState, resolveUserQuestionState, responseCache, restoreSnapshot, runSmartAgentEvalHarness, scoreItemsByRelevance, searchSkills, seedChildMessages, selectTopIndicesInOrder, sessionMetrics, setTokenCounter, startStreamingSession, summarizeObject, textFromContent, tokenize, toolPolicy, traceSessionToOtlp, validateReasoningConfig, validateToolArgs, webhookApproval, withTools, withinDepth, writeSummaryFactsToMemory };