@theokit/agents 0.31.0 → 0.33.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.
@@ -1,5 +1,5 @@
1
- import { A as AgentOptions, n as MainLoopOptions, m as MainLoopMeta, D as ToolOptions, E as ToolboxOptions, B as BudgetOptions, u as PolicyHandler, a as ApprovalOptions } from './skills-Dx_KJ6Eg.js';
2
- export { C as Checkpoint, b as CheckpointOptions, c as CheckpointState, d as CheckpointStorage, e as CheckpointStrategy, f as Compaction, g as CompactionDecoratorConfig, h as ContextCompactionStrategy, i as ContextWindow, j as ContextWindowOptions, G as Gateway, k as GatewayOptions, H as HumanInTheLoop, l as HumanInTheLoopOptions, I as IndexStrategy, M as MCP, o as McpServerConfig, p as McpServersMap, q as Memory, r as MemoryOptions, s as MemoryProvider, t as MemoryScope, P as PlatformName, v as ProjectContext, w as ProjectContextOptions, x as RelevanceStrategy, S as SessionStrategy, y as Skills, z as SkillsOptions, T as TimeoutAction, F as getCheckpointConfig, J as getCompactionConfig, K as getContextWindowConfig, L as getGatewayConfig, N as getHumanInTheLoopConfig, O as getMcpConfig, Q as getMemoryConfig, U as getProjectContextConfig, V as getSkillsConfig, W as resolveSessionId } from './skills-Dx_KJ6Eg.js';
1
+ import { A as AgentOptions, t as MainLoopOptions, s as MainLoopMeta, N as ToolOptions, O as ToolboxOptions, B as BudgetOptions, D as PolicyHandler, a as ApprovalOptions, G as Guardrail } from './types-S7k_lt1_.js';
2
+ export { C as Checkpoint, b as CheckpointOptions, c as CheckpointState, d as CheckpointStorage, e as CheckpointStrategy, f as Compaction, g as CompactionDecoratorConfig, h as ContextCompactionStrategy, i as ContextWindow, j as ContextWindowOptions, l as Gateway, m as GatewayOptions, H as HumanInTheLoop, r as HumanInTheLoopOptions, I as IndexStrategy, M as MCP, u as McpServerConfig, v as McpServersMap, w as Memory, x as MemoryOptions, y as MemoryProvider, z as MemoryScope, P as PlatformName, E as ProjectContext, F as ProjectContextOptions, J as RelevanceStrategy, S as SessionStrategy, K as Skills, L as SkillsOptions, T as TimeoutAction, Q as getCheckpointConfig, U as getCompactionConfig, V as getContextWindowConfig, W as getGatewayConfig, X as getHumanInTheLoopConfig, Y as getMcpConfig, Z as getMemoryConfig, _ as getProjectContextConfig, $ as getSkillsConfig, a0 as resolveSessionId } from './types-S7k_lt1_.js';
3
3
  import '@theokit/sdk';
4
4
  import 'zod';
5
5
 
@@ -32,6 +32,25 @@ declare const Audit: (value: boolean) => MethodDecorator & ClassDecorator;
32
32
  declare function SubAgents(agentClasses: Function[]): ClassDecorator;
33
33
  declare function getSubAgents(target: Function): Function[];
34
34
 
35
+ /**
36
+ * `@Guardrails([...])` — M9 class-decorator surface for input/output guardrails.
37
+ *
38
+ * The functional `defineAgent({ guardrails: [...] })` path already applies guards at the framework
39
+ * boundary (ADR-0040 § D2). This decorator gives the `@Agent` class path the SAME capability: the
40
+ * declared guards compile into `compiled.guardrails` (via `walkAgentMetadata`), so `AgentRunner`
41
+ * applies them identically. Metadata-only (like `@MCP`/`@Skills`) — it describes, the runner runs.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * @Agent({ name: 'support', route: '/api/agents/support' })
46
+ * @Guardrails([promptInjectionDetector(), piiDetector({ redact: true })])
47
+ * class SupportAgent {}
48
+ * ```
49
+ */
50
+
51
+ declare function Guardrails(guardrails: readonly Guardrail[]): ClassDecorator;
52
+ declare function getGuardrailsConfig(target: Function): readonly Guardrail[] | undefined;
53
+
35
54
  type HookPoint = 'before:llm-call' | 'after:llm-call' | 'before:tool-call' | 'after:tool-call' | 'on:iteration' | 'on:complete' | 'on:error';
36
55
  interface HookEntry {
37
56
  point: HookPoint;
@@ -171,4 +190,4 @@ declare function applyDecorators(...decorators: AnyDecorator[]): ClassDecorator
171
190
  declare function Mixin(...mixinClasses: Function[]): ClassDecorator;
172
191
  declare function getMixins(target: Function): Function[];
173
192
 
174
- export { Agent, AgentOptions, ApprovalOptions, Artifact, type ArtifactOptions, type ArtifactResult, Audit, Budget, BudgetOptions, type CommandPermissions, type CompactionStrategy, Conversation, type ConversationOptions, type ConversationStorage, EditFormat, type EditFormatType, type FilesystemPermissions, Hook, type HookEntry, type HookPoint, MainLoop, MainLoopMeta, MainLoopOptions, Mixin, Model, Observable, type ObservableEntry, Policy, PolicyHandler, RequiresApproval, RequiresCapability, Sandbox, type SandboxOptions, SubAgents, Tool, ToolOptions, Toolbox, ToolboxOptions, Trace, applyDecorators, getAgentConfig, getArtifactConfig, getConversationConfig, getHooks, getHooksByPoint, getMainLoop, getMixins, getObservableByChannel, getObservables, getSandboxConfig, getSubAgents, getToolConfig, getToolMethods, getToolboxConfig, isCommandAllowed, isPathAllowed };
193
+ export { Agent, AgentOptions, ApprovalOptions, Artifact, type ArtifactOptions, type ArtifactResult, Audit, Budget, BudgetOptions, type CommandPermissions, type CompactionStrategy, Conversation, type ConversationOptions, type ConversationStorage, EditFormat, type EditFormatType, type FilesystemPermissions, Guardrails, Hook, type HookEntry, type HookPoint, MainLoop, MainLoopMeta, MainLoopOptions, Mixin, Model, Observable, type ObservableEntry, Policy, PolicyHandler, RequiresApproval, RequiresCapability, Sandbox, type SandboxOptions, SubAgents, Tool, ToolOptions, Toolbox, ToolboxOptions, Trace, applyDecorators, getAgentConfig, getArtifactConfig, getConversationConfig, getGuardrailsConfig, getHooks, getHooksByPoint, getMainLoop, getMixins, getObservableByChannel, getObservables, getSandboxConfig, getSubAgents, getToolConfig, getToolMethods, getToolboxConfig, isCommandAllowed, isPathAllowed };
@@ -23,7 +23,7 @@ import {
23
23
  getToolboxConfig,
24
24
  isCommandAllowed,
25
25
  isPathAllowed
26
- } from "./chunk-K4MCMREI.js";
26
+ } from "./chunk-GEV2EQW2.js";
27
27
  import {
28
28
  Agent,
29
29
  Audit,
@@ -32,6 +32,7 @@ import {
32
32
  Compaction,
33
33
  ContextWindow,
34
34
  Gateway,
35
+ Guardrails,
35
36
  HumanInTheLoop,
36
37
  MCP,
37
38
  Memory,
@@ -48,6 +49,7 @@ import {
48
49
  getCompactionConfig,
49
50
  getContextWindowConfig,
50
51
  getGatewayConfig,
52
+ getGuardrailsConfig,
51
53
  getHumanInTheLoopConfig,
52
54
  getMcpConfig,
53
55
  getMemoryConfig,
@@ -56,7 +58,7 @@ import {
56
58
  getSkillsConfig,
57
59
  getSubAgents,
58
60
  resolveSessionId
59
- } from "./chunk-FI6ZG2YP.js";
61
+ } from "./chunk-MD35WBR4.js";
60
62
  import "./chunk-7QVYU63E.js";
61
63
  export {
62
64
  Agent,
@@ -69,6 +71,7 @@ export {
69
71
  Conversation,
70
72
  EditFormat,
71
73
  Gateway,
74
+ Guardrails,
72
75
  Hook,
73
76
  HumanInTheLoop,
74
77
  MCP,
@@ -95,6 +98,7 @@ export {
95
98
  getContextWindowConfig,
96
99
  getConversationConfig,
97
100
  getGatewayConfig,
101
+ getGuardrailsConfig,
98
102
  getHooks,
99
103
  getHooksByPoint,
100
104
  getHumanInTheLoopConfig,
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { Agent, Artifact, ArtifactOptions, ArtifactResult, Audit, Budget, CommandPermissions, CompactionStrategy, Conversation, ConversationOptions, ConversationStorage, EditFormat, EditFormatType, FilesystemPermissions, Hook, HookEntry, HookPoint, MainLoop, Mixin, Model, Observable, ObservableEntry, Policy, RequiresApproval, RequiresCapability, Sandbox, SandboxOptions, SubAgents, Tool, Toolbox, Trace, applyDecorators, getAgentConfig, getArtifactConfig, getConversationConfig, getHooks, getHooksByPoint, getMainLoop, getMixins, getObservableByChannel, getObservables, getSandboxConfig, getSubAgents, getToolConfig, getToolMethods, getToolboxConfig, isCommandAllowed, isPathAllowed } from './decorators.js';
2
- import { R as ReasoningEffort } from './skills-Dx_KJ6Eg.js';
3
- export { A as AgentOptions, a as ApprovalOptions, B as BudgetOptions, C as Checkpoint, b as CheckpointOptions, c as CheckpointState, d as CheckpointStorage, e as CheckpointStrategy, f as Compaction, g as CompactionDecoratorConfig, h as ContextCompactionStrategy, i as ContextWindow, j as ContextWindowOptions, G as Gateway, k as GatewayOptions, H as HumanInTheLoop, l as HumanInTheLoopOptions, I as IndexStrategy, M as MCP, m as MainLoopMeta, n as MainLoopOptions, o as McpServerConfig, p as McpServersMap, q as Memory, r as MemoryOptions, s as MemoryProvider, t as MemoryScope, P as PlatformName, u as PolicyHandler, v as ProjectContext, w as ProjectContextOptions, x as RelevanceStrategy, S as SessionStrategy, y as Skills, z as SkillsOptions, T as TimeoutAction, D as ToolOptions, E as ToolboxOptions, F as getCheckpointConfig, J as getCompactionConfig, K as getContextWindowConfig, L as getGatewayConfig, N as getHumanInTheLoopConfig, O as getMcpConfig, Q as getMemoryConfig, U as getProjectContextConfig, V as getSkillsConfig, W as resolveSessionId } from './skills-Dx_KJ6Eg.js';
4
- import { G as Guardrail, L as LoopStrategy, R as ReflectionStrategy, C as CompiledAgentOptions, a as CompiledTool, b as RoundStreamFactory, S as StreamEvent, D as DelegationResult, A as AgentManifestEntry } from './bridge-entry-DtDotZGW.js';
5
- export { c as AGENT_BRAND, d as AfterToolCallContext, e as AgentBuilder, f as AgentDefinition, g as AgentDefinitionError, h as AgentExecutionContext, i as AgentManifest, j as AgentManifestTool, k as AgentRoute, l as AgentRouteContext, m as AgentRunInfo, n as AgentStreamEvent, o as AgentWalkResult, p as AgentWarningCode, q as AgentsPluginOptions, r as ApprovalRequiredEvent, s as ArtifactChunkEvent, t as ArtifactStartEvent, B as BeforeToolCallContext, u as BudgetExceededError, v as CheckpointSavedEvent, w as CompiledContextWindow, x as ContextualTool, y as CostBudgetExceededError, z as DEFAULT_MAX_ITERATIONS, E as DefineAgentConfig, F as DelegateOptions, H as DelegationError, I as DoneEvent, J as ErrorEvent, K as FileEditEvent, M as GuardrailAction, N as GuardrailPhase, O as GuardrailResult, P as GuardrailViolationError, Q as InferAgentInput, T as InferAgentToolNames, U as IterationEvent, V as LLMCallContext, W as LoopFinishReason, X as LoopOutcome, Y as LoopStrategyConfig, Z as PartialToolCallEvent, _ as ReflectionContext, $ as ReflectionResult, a0 as ReflectionStrategyConfig, a1 as RunStartedEvent, a2 as SdkMessage, a3 as Segment, a4 as SkillsRequestContext, a5 as SkillsSelection, a6 as StateUpdateEvent, a7 as TextDeltaEvent, a8 as ThinkingEvent, a9 as ToolCallEvent, aa as ToolCallVeto, ab as ToolHooks, ac as ToolHooksPlugin, ad as ToolResultEvent, ae as ToolWalkResult, af as ToolboxWalkResult, ag as agent, ah as agentsPlugin, ai as buildModelSelection, aj as compileAgent, ak as compileAgentDefinition, al as compileAgentModule, am as compileContextWindow, an as compileProjectContext, ao as compileSkills, ap as compileTools, aq as contextualTool, ar as createAgentExecutionContext, as as createSdkAgentStream, at as createThinkTagExtractor, au as createToolHooksPlugin, av as defineAgent, aw as delegate, ax as extractThinkTagStream, ay as generateAgentManifest, az as generateAgentRoutes, aA as isAgentContext, aB as isAgentDefinition, aC as isApprovalRequired, aD as isDone, aE as isError, aF as isPartialToolCall, aG as isTextDelta, aH as isToolCall, aI as isToolResult, aJ as ladderReflectionStrategy, aK as loopStrategyConfigSchema, aL as noopReflectionStrategy, aM as projectContextMetadataOnlyKnobs, aN as reflectionStrategyConfigSchema, aO as resolveEnabledSkills, aP as resolveLoopStrategy, aQ as streamAgentResponse, aR as streamAgentUIMessages, aS as translateSdkEvent, aT as translateToUIMessageStream, aU as validateUniqueRoutes, aV as walkAgentMetadata } from './bridge-entry-DtDotZGW.js';
1
+ export { Agent, Artifact, ArtifactOptions, ArtifactResult, Audit, Budget, CommandPermissions, CompactionStrategy, Conversation, ConversationOptions, ConversationStorage, EditFormat, EditFormatType, FilesystemPermissions, Guardrails, Hook, HookEntry, HookPoint, MainLoop, Mixin, Model, Observable, ObservableEntry, Policy, RequiresApproval, RequiresCapability, Sandbox, SandboxOptions, SubAgents, Tool, Toolbox, Trace, applyDecorators, getAgentConfig, getArtifactConfig, getConversationConfig, getGuardrailsConfig, getHooks, getHooksByPoint, getMainLoop, getMixins, getObservableByChannel, getObservables, getSandboxConfig, getSubAgents, getToolConfig, getToolMethods, getToolboxConfig, isCommandAllowed, isPathAllowed } from './decorators.js';
2
+ import { G as Guardrail, R as ReasoningEffort } from './types-S7k_lt1_.js';
3
+ export { A as AgentOptions, a as ApprovalOptions, B as BudgetOptions, C as Checkpoint, b as CheckpointOptions, c as CheckpointState, d as CheckpointStorage, e as CheckpointStrategy, f as Compaction, g as CompactionDecoratorConfig, h as ContextCompactionStrategy, i as ContextWindow, j as ContextWindowOptions, k as CostBudgetExceededError, l as Gateway, m as GatewayOptions, n as GuardrailAction, o as GuardrailPhase, p as GuardrailResult, q as GuardrailViolationError, H as HumanInTheLoop, r as HumanInTheLoopOptions, I as IndexStrategy, M as MCP, s as MainLoopMeta, t as MainLoopOptions, u as McpServerConfig, v as McpServersMap, w as Memory, x as MemoryOptions, y as MemoryProvider, z as MemoryScope, P as PlatformName, D as PolicyHandler, E as ProjectContext, F as ProjectContextOptions, J as RelevanceStrategy, S as SessionStrategy, K as Skills, L as SkillsOptions, T as TimeoutAction, N as ToolOptions, O as ToolboxOptions, Q as getCheckpointConfig, U as getCompactionConfig, V as getContextWindowConfig, W as getGatewayConfig, X as getHumanInTheLoopConfig, Y as getMcpConfig, Z as getMemoryConfig, _ as getProjectContextConfig, $ as getSkillsConfig, a0 as resolveSessionId } from './types-S7k_lt1_.js';
4
+ import { L as LoopStrategy, R as ReflectionStrategy, C as CompiledAgentOptions, a as CompiledTool, b as RoundStreamFactory, S as StreamEvent, D as DelegationResult, A as AgentManifestEntry } from './bridge-entry-BydskfrI.js';
5
+ export { c as AGENT_BRAND, d as AfterToolCallContext, e as AgentBuilder, f as AgentDefinition, g as AgentDefinitionError, h as AgentExecutionContext, i as AgentManifest, j as AgentManifestTool, k as AgentRoute, l as AgentRouteContext, m as AgentRunInfo, n as AgentStreamEvent, o as AgentWalkResult, p as AgentWarningCode, q as AgentsPluginOptions, r as ApiErrorContext, s as ApiErrorDecision, t as ApiErrorPolicy, u as ApprovalRequiredEvent, v as ArtifactChunkEvent, w as ArtifactStartEvent, B as BackgroundDelegation, x as BeforeToolCallContext, y as BudgetExceededError, z as CheckpointSavedEvent, E as CompiledContextWindow, F as ContextualTool, G as DEFAULT_MAX_ITERATIONS, H as DefineAgentConfig, I as DelegateFn, J as DelegateOptions, K as DelegationError, M as DoneEvent, N as ErrorEvent, O as FileEditEvent, P as InferAgentInput, Q as InferAgentToolNames, T as IterationEvent, U as LLMCallContext, V as LoopFinishReason, W as LoopOutcome, X as LoopStrategyConfig, Y as McpApprovalSpec, Z as McpRegistryConfig, _ as McpRequestContext, $ as McpSelection, a0 as PartialToolCallEvent, a1 as ProcessInputContext, a2 as ReflectionContext, a3 as ReflectionResult, a4 as ReflectionStrategyConfig, a5 as RunStartedEvent, a6 as ScoreVerdict, a7 as ScoredDelegation, a8 as Scorer, a9 as SdkMessage, aa as Segment, ab as SkillsRequestContext, ac as SkillsSelection, ad as StateUpdateEvent, ae as TextDeltaEvent, af as ThinkingEvent, ag as ToolCallEvent, ah as ToolCallVeto, ai as ToolHooks, aj as ToolHooksPlugin, ak as ToolResultEvent, al as ToolWalkResult, am as ToolboxWalkResult, an as agent, ao as agentsPlugin, ap as buildModelSelection, aq as compileAgent, ar as compileAgentDefinition, as as compileAgentModule, at as compileContextWindow, au as compileProjectContext, av as compileSkills, aw as compileTools, ax as contextualTool, ay as createAgentExecutionContext, az as createApiErrorHandler, aA as createSdkAgentStream, aB as createThinkTagExtractor, aC as createToolHooksPlugin, aD as defineAgent, aE as delegate, aF as delegateBackground, aG as delegateWithScoring, aH as extractThinkTagStream, aI as generateAgentManifest, aJ as generateAgentRoutes, aK as isAgentContext, aL as isAgentDefinition, aM as isApprovalRequired, aN as isDone, aO as isError, aP as isPartialToolCall, aQ as isTextDelta, aR as isToolCall, aS as isToolResult, aT as ladderReflectionStrategy, aU as loopStrategyConfigSchema, aV as mcpRegistry, aW as mcpToolApprovals, aX as noopReflectionStrategy, aY as projectContextMetadataOnlyKnobs, aZ as reflectionStrategyConfigSchema, a_ as resolveEnabledSkills, a$ as resolveLoopStrategy, b0 as resolveMcpServers, b1 as runWithApiErrorHandling, b2 as streamAgentResponse, b3 as streamAgentUIMessages, b4 as translateSdkEvent, b5 as translateToUIMessageStream, b6 as validateUniqueRoutes, b7 as walkAgentMetadata } from './bridge-entry-BydskfrI.js';
6
6
  import { PluginsSettings, Plugin, ProviderRoutingSettings, AgentDefinition, BudgetTracker, ConversationStorageAdapter, CustomTool } from '@theokit/sdk';
7
7
  import { RetryOptions } from '@theokit/sdk/retry';
8
8
  import { CompressibleMessage } from '@theokit/sdk/compaction';
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  getToolboxConfig,
24
24
  isCommandAllowed,
25
25
  isPathAllowed
26
- } from "./chunk-K4MCMREI.js";
26
+ } from "./chunk-GEV2EQW2.js";
27
27
  import {
28
28
  AGENT_BRAND,
29
29
  AgentDefinitionError,
@@ -50,11 +50,14 @@ import {
50
50
  contextualTool,
51
51
  costGuard,
52
52
  createAgentExecutionContext,
53
+ createApiErrorHandler,
53
54
  createSdkAgentStream,
54
55
  createThinkTagExtractor,
55
56
  createToolHooksPlugin,
56
57
  defineAgent,
57
58
  delegate,
59
+ delegateBackground,
60
+ delegateWithScoring,
58
61
  estimateTokens,
59
62
  extractThinkTagStream,
60
63
  generateAgentManifest,
@@ -70,6 +73,8 @@ import {
70
73
  isToolResult,
71
74
  ladderReflectionStrategy,
72
75
  loopStrategyConfigSchema,
76
+ mcpRegistry,
77
+ mcpToolApprovals,
73
78
  moderateOutputStream,
74
79
  noopReflectionStrategy,
75
80
  outputModeration,
@@ -79,8 +84,10 @@ import {
79
84
  reflectionStrategyConfigSchema,
80
85
  resolveCompactionStrategy,
81
86
  resolveLoopStrategy,
87
+ resolveMcpServers,
82
88
  runInputGuards,
83
89
  runOutputGuards,
90
+ runWithApiErrorHandling,
84
91
  streamAgentResponse,
85
92
  streamAgentUIMessages,
86
93
  tokenBudgetCompactionStrategy,
@@ -89,7 +96,7 @@ import {
89
96
  unicodeNormalizer,
90
97
  validateUniqueRoutes,
91
98
  walkAgentMetadata
92
- } from "./chunk-BWYBOMKR.js";
99
+ } from "./chunk-TXEY3IUO.js";
93
100
  import {
94
101
  Agent,
95
102
  Audit,
@@ -98,6 +105,7 @@ import {
98
105
  Compaction,
99
106
  ContextWindow,
100
107
  Gateway,
108
+ Guardrails,
101
109
  HumanInTheLoop,
102
110
  MCP,
103
111
  Memory,
@@ -114,6 +122,7 @@ import {
114
122
  getCompactionConfig,
115
123
  getContextWindowConfig,
116
124
  getGatewayConfig,
125
+ getGuardrailsConfig,
117
126
  getHumanInTheLoopConfig,
118
127
  getMcpConfig,
119
128
  getMemoryConfig,
@@ -122,7 +131,7 @@ import {
122
131
  getSkillsConfig,
123
132
  getSubAgents,
124
133
  resolveSessionId
125
- } from "./chunk-FI6ZG2YP.js";
134
+ } from "./chunk-MD35WBR4.js";
126
135
  import {
127
136
  __name
128
137
  } from "./chunk-7QVYU63E.js";
@@ -418,6 +427,7 @@ export {
418
427
  EditFormat,
419
428
  Gateway,
420
429
  GuardrailViolationError,
430
+ Guardrails,
421
431
  Hook,
422
432
  HumanInTheLoop,
423
433
  MCP,
@@ -455,11 +465,14 @@ export {
455
465
  costGuard,
456
466
  createA2ATool,
457
467
  createAgentExecutionContext,
468
+ createApiErrorHandler,
458
469
  createSdkAgentStream,
459
470
  createThinkTagExtractor,
460
471
  createToolHooksPlugin,
461
472
  defineAgent,
462
473
  delegate,
474
+ delegateBackground,
475
+ delegateWithScoring,
463
476
  deriveConversationId,
464
477
  encodeAcpMessage,
465
478
  estimateTokens,
@@ -473,6 +486,7 @@ export {
473
486
  getContextWindowConfig,
474
487
  getConversationConfig,
475
488
  getGatewayConfig,
489
+ getGuardrailsConfig,
476
490
  getHooks,
477
491
  getHooksByPoint,
478
492
  getHumanInTheLoopConfig,
@@ -502,7 +516,9 @@ export {
502
516
  isToolResult,
503
517
  ladderReflectionStrategy,
504
518
  loopStrategyConfigSchema,
519
+ mcpRegistry,
505
520
  mcpServerInfo,
521
+ mcpToolApprovals,
506
522
  moderateOutputStream,
507
523
  noopReflectionStrategy,
508
524
  outputModeration,
@@ -514,9 +530,11 @@ export {
514
530
  resolveCompactionStrategy,
515
531
  resolveEnabledSkills,
516
532
  resolveLoopStrategy,
533
+ resolveMcpServers,
517
534
  resolveSessionId,
518
535
  runInputGuards,
519
536
  runOutputGuards,
537
+ runWithApiErrorHandling,
520
538
  streamAgentResponse,
521
539
  streamAgentUIMessages,
522
540
  tokenBudgetCompactionStrategy,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/a2a/agent-card.ts","../src/a2a/mcp-server-manifest.ts","../src/a2a/a2a-client.ts","../src/conversation-scope.ts","../src/skills-resolver.ts","../src/acp/protocol.ts","../src/acp/client.ts"],"sourcesContent":["/**\n * M15 (theokit-ai-first) — A2A agent card generation (ADR-0040 § D2, home/discovery concern).\n *\n * Produces an [A2A](https://github.com/google/A2A)-spec Agent Card from the framework's\n * `AgentManifestEntry`, so other systems can discover a TheoKit agent's capabilities over HTTP at\n * `/.well-known/<name>/agent-card.json`. Pure data transform — no LLM, no runtime (G2).\n */\nimport type { AgentManifestEntry } from '../manifest/agent-manifest.js'\n\n/** A single capability exposed by an A2A agent (maps from a TheoKit tool). */\nexport interface A2ASkill {\n id: string\n name: string\n description: string\n}\n\n/** A2A agent-card capabilities block. */\nexport interface A2ACapabilities {\n streaming: boolean\n pushNotifications: boolean\n stateTransitionHistory: boolean\n}\n\n/** An A2A-spec Agent Card (the subset TheoKit advertises). */\nexport interface AgentCard {\n name: string\n description: string\n url: string\n version: string\n capabilities: A2ACapabilities\n defaultInputModes: string[]\n defaultOutputModes: string[]\n skills: A2ASkill[]\n}\n\nexport interface BuildAgentCardOptions {\n /** Absolute base URL of the deployment (e.g. `https://app.example.com`). A trailing slash is trimmed. */\n baseUrl: string\n /** Human description of the agent. Defaults to a generated sentence when omitted (spec requires non-empty). */\n description?: string\n}\n\n/** Strip a single trailing slash so `${baseUrl}${route}` never doubles the separator. */\nfunction trimTrailingSlash(url: string): string {\n return url.endsWith('/') ? url.slice(0, -1) : url\n}\n\n/** Build an A2A agent card from a manifest entry. */\nexport function buildAgentCard(entry: AgentManifestEntry, options: BuildAgentCardOptions): AgentCard {\n const base = trimTrailingSlash(options.baseUrl)\n return {\n name: entry.name,\n description: options.description ?? `TheoKit agent \"${entry.name}\".`,\n url: `${base}${entry.route}`,\n version: '1.0',\n capabilities: {\n streaming: entry.stream,\n pushNotifications: false,\n stateTransitionHistory: false,\n },\n defaultInputModes: ['text'],\n defaultOutputModes: ['text'],\n skills: entry.tools.map((t) => ({ id: t.name, name: t.name, description: t.description })),\n }\n}\n\n/** The A2A discovery path for an agent: `/.well-known/<name>/agent-card.json`. */\nexport function wellKnownCardPath(agentName: string): string {\n return `/.well-known/${agentName}/agent-card.json`\n}\n","/**\n * M16 (theokit-ai-first) — MCP server manifest generation (ADR-0040 § D2, home concern).\n *\n * Exposes a TheoKit agent's tools to external MCP clients as `tools/list` descriptors, so the app\n * can advertise its agents over its OWN HTTP routes. Pure data transform — no LLM, no runtime, and\n * NO stdio transport (that stays SDK-side per sdk-runtime.md). Serving these over `GET /mcp` and the\n * JSON-RPC envelope are follow-ups (mount path).\n */\nimport type { AgentManifestEntry } from '../manifest/agent-manifest.js'\n\n/** The MCP protocol revision these descriptors target. */\nexport const MCP_PROTOCOL_VERSION = '2024-11-05'\n\n/** A JSON-schema object (the shape MCP expects for a tool's `inputSchema`). */\nexport interface McpJsonSchema {\n type: 'object'\n properties: Record<string, unknown>\n required?: string[]\n}\n\n/** An MCP `tools/list` tool descriptor. */\nexport interface McpToolDescriptor {\n name: string\n description: string\n inputSchema: McpJsonSchema\n}\n\n/** MCP `initialize` server info. */\nexport interface McpServerInfo {\n name: string\n version: string\n protocolVersion: string\n}\n\n/**\n * Map an agent's tools to MCP tool descriptors. The manifest tool carries name + description; the\n * per-tool JSON schema is not retained in the manifest, so a permissive empty-object schema is\n * emitted (MCP clients accept it and pass through arbitrary args). Wiring the real per-tool schema\n * is a follow-up once the manifest carries it.\n */\nexport function buildMcpToolDescriptors(entry: AgentManifestEntry): McpToolDescriptor[] {\n return entry.tools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: { type: 'object', properties: {} },\n }))\n}\n\n/** Build the MCP `initialize` server-info block for an agent. */\nexport function mcpServerInfo(entry: AgentManifestEntry): McpServerInfo {\n return { name: entry.name, version: '1.0', protocolVersion: MCP_PROTOCOL_VERSION }\n}\n","/**\n * M15 (theokit-ai-first) — A2A client: call a remote A2A agent as a tool (ADR-0040 § D2).\n *\n * `createA2ATool` returns a `CustomTool` whose handler POSTs the input message to a remote agent's\n * HTTP endpoint and returns its text response — cross-network delegation. Uses `fetch` (Web\n * Standards, G8). The target is a remote AGENT endpoint, not an LLM provider, so the G2 grep guard\n * (`openrouter.ai|api.openai.com|api.anthropic.com`) is unaffected. `fetchImpl` is injectable for tests.\n */\nimport type { CustomTool } from '@theokit/sdk'\n\n/** How to authenticate to the remote agent. */\nexport interface A2AAuth {\n /** Bearer token → `Authorization: Bearer <token>`. */\n bearer?: string\n /** API-key header pair → `<name>: <value>` (e.g. `x-api-key`). */\n apiKey?: { header: string; value: string }\n}\n\nexport interface A2AToolConfig {\n /** Remote agent endpoint URL (POST target). */\n url: string\n /** Tool name the model calls. */\n name: string\n /** Tool description surfaced to the model. */\n description: string\n /** Static headers merged into every request. */\n headers?: Record<string, string>\n /** Auth applied to every request. */\n auth?: A2AAuth\n /** Injected fetch (defaults to the global). Narrowed to the call shape this client uses. */\n fetchImpl?: (url: string, init: RequestInit) => Promise<Response>\n}\n\n/** Build the request headers from static headers + auth. */\nfunction buildHeaders(config: A2AToolConfig): Record<string, string> {\n const headers: Record<string, string> = { 'content-type': 'application/json', ...config.headers }\n if (config.auth?.bearer) headers.authorization = `Bearer ${config.auth.bearer}`\n if (config.auth?.apiKey) headers[config.auth.apiKey.header] = config.auth.apiKey.value\n return headers\n}\n\n/**\n * Create a tool that delegates to a remote A2A agent. The remote is expected to answer a\n * `{ message }` POST with a JSON body carrying a `response` (or `text`) string.\n */\nexport function createA2ATool(config: A2AToolConfig): CustomTool {\n const doFetch = config.fetchImpl ?? fetch\n return {\n name: config.name,\n description: config.description,\n inputSchema: {\n type: 'object',\n properties: { message: { type: 'string', description: 'The message to send to the remote agent.' } },\n required: ['message'],\n },\n handler: async (input: Record<string, unknown>): Promise<string> => {\n // The input schema requires `message: string`; narrow defensively (never base-to-string).\n const message = typeof input.message === 'string' ? input.message : ''\n const res = await doFetch(config.url, {\n method: 'POST',\n headers: buildHeaders(config),\n body: JSON.stringify({ message }),\n })\n if (!res.ok) {\n throw new Error(`A2A call to \"${config.name}\" failed: ${res.status} ${res.statusText}`)\n }\n const data = (await res.json()) as { response?: string; text?: string }\n return data.response ?? data.text ?? ''\n },\n }\n}\n","/**\n * M11 (theokit-ai-first) — {resource, thread} conversation scoping (ADR-0040 § D2, home concern).\n *\n * Maps a request's (resource, thread) pair to a deterministic, collision-safe conversation id so\n * multi-tenant apps isolate history without hand-building `user-${id}-thread-${id}` strings. This\n * is the app's request→conversation mapping — NOT the SDK's storage engine (which the derived id is\n * simply handed to). Background compression of long histories stays SDK-side.\n *\n * Encoding: each component is `encodeURIComponent`-escaped and joined with `/`. Since\n * `encodeURIComponent` escapes a raw `/` to `%2F`, the separator is unambiguous — `('a/b','c')` and\n * `('a','b/c')` derive DIFFERENT ids (collision-safe). Reversible via {@link parseConversationId}.\n */\n\nconst SEPARATOR = '/'\n\n/** Derive a deterministic conversation id from a (resource, thread) pair. Fails fast on empty input. */\nexport function deriveConversationId(resource: string, thread: string): string {\n if (!resource) throw new Error('[@theokit/agents] deriveConversationId: resource must be non-empty')\n if (!thread) throw new Error('[@theokit/agents] deriveConversationId: thread must be non-empty')\n return `${encodeURIComponent(resource)}${SEPARATOR}${encodeURIComponent(thread)}`\n}\n\n/**\n * Reverse a derived conversation id back to its (resource, thread). Returns `null` for a value that\n * is not a derived scope id (no separator, or an empty component) — callers treat that as \"opaque id,\n * not scoped\".\n */\nexport function parseConversationId(id: string): { resource: string; thread: string } | null {\n const idx = id.indexOf(SEPARATOR)\n if (idx <= 0 || idx >= id.length - 1) return null\n const resource = decodeURIComponent(id.slice(0, idx))\n const thread = decodeURIComponent(id.slice(idx + 1))\n if (!resource || !thread) return null\n return { resource, thread }\n}\n","/**\n * M13 (theokit-ai-first) — per-request skills resolution (ADR-0040 § D2, home/boundary concern).\n *\n * The static `skills.enabled` filter already works (`compile-skills` maps `include` → the SDK's\n * `enabled`). This adds a PER-REQUEST resolver so multi-tenant apps expose different skill sets to\n * different users. A selection is either a static list or a function of the request context (the M7\n * run-context). Discovery + injection stay in the SDK; this only CHOOSES the enabled set per call.\n */\n\n/** The request context handed to a skills resolver (the M7 run-context — opaque per-request data). */\nexport type SkillsRequestContext = Record<string, unknown>\n\n/**\n * How the enabled skill set is chosen:\n * - `string[]` — a static list (same shape `skills.enabled` accepts today).\n * - a function — resolved per request from the {@link SkillsRequestContext} (sync or async).\n */\nexport type SkillsSelection =\n | readonly string[]\n | ((ctx: SkillsRequestContext) => readonly string[] | Promise<readonly string[]>)\n\n/**\n * Resolve the enabled skill names for a request. Returns `undefined` when no selection is given (the\n * SDK then enables every discovered skill). Fails fast if a resolver returns a non-array.\n */\nexport async function resolveEnabledSkills(\n selection: SkillsSelection | undefined,\n ctx: SkillsRequestContext,\n): Promise<string[] | undefined> {\n if (selection === undefined) return undefined\n if (typeof selection !== 'function') return [...selection]\n const resolved = await selection(ctx)\n if (!Array.isArray(resolved)) {\n throw new Error('[@theokit/agents] skills resolver must return an array of skill names')\n }\n return [...resolved]\n}\n","/**\n * M17 (theokit-ai-first) — ACP (Agent Client Protocol) stdio framing.\n *\n * ACP talks to a coding agent (Claude Code, Amp, Codex) over stdio as newline-delimited JSON. This\n * is the transport-agnostic CORE: encode a message to a line, and decode a byte/char stream that may\n * split a message across chunks. Pure — no subprocess, no Node API. The subprocess spawn lives in the\n * adapter layer (G8) / SDK; `createACPTool` (wrapping this codec + an injected transport) is a\n * follow-up once the adapter ships.\n */\n\n/** Serialize a message to a single newline-terminated JSON line. */\nexport function encodeAcpMessage(message: unknown): string {\n return `${JSON.stringify(message)}\\n`\n}\n\n/**\n * Incremental decoder for newline-delimited JSON. Feed it chunks with {@link push}; it buffers a\n * partial trailing line across calls and returns every WHOLE message parsed so far. Blank lines are\n * skipped. A completed non-JSON line fails fast with a typed error (error-handling.md) — a corrupt\n * frame must never be silently dropped.\n */\nexport class AcpMessageDecoder {\n private buffer = ''\n\n /** Feed a chunk; returns the messages completed by this chunk (possibly empty). */\n push(chunk: string): unknown[] {\n this.buffer += chunk\n const messages: unknown[] = []\n let newlineIndex = this.buffer.indexOf('\\n')\n while (newlineIndex !== -1) {\n const line = this.buffer.slice(0, newlineIndex).trim()\n this.buffer = this.buffer.slice(newlineIndex + 1)\n if (line.length > 0) {\n try {\n messages.push(JSON.parse(line))\n } catch (cause) {\n throw new Error(`[@theokit/agents] ACP decode failed on line: ${line}`, { cause })\n }\n }\n newlineIndex = this.buffer.indexOf('\\n')\n }\n return messages\n }\n}\n","/**\n * M17 (theokit-ai-first) — ACP client: JSON-RPC over the stdio framing.\n *\n * Drives a coding agent (Claude Code, Amp, Codex) over an INJECTED {@link AcpTransport}. The\n * subprocess spawn is a Node API and lives in the adapter layer (G8); this client is transport-\n * agnostic and testable. It correlates responses to requests by `id`, and dispatches server→client\n * requests (e.g. `session/request_permission`) to a registered handler, replying with its decision.\n */\nimport { AcpMessageDecoder, encodeAcpMessage } from './protocol.js'\n\n/** The stdio channel to the coding-agent subprocess (abstracted for testability + G8). */\nexport interface AcpTransport {\n /** Write one already-encoded (newline-terminated) line to the agent's stdin. */\n send(line: string): void\n /** Subscribe to raw lines/chunks from the agent's stdout. */\n subscribe(onData: (chunk: string) => void): void\n}\n\ninterface JsonRpcResponse {\n id: number\n result?: unknown\n error?: { code: number; message: string }\n}\ninterface JsonRpcServerRequest {\n id: number\n method: string\n params?: unknown\n}\n\ninterface Pending {\n resolve: (value: unknown) => void\n reject: (err: Error) => void\n}\n/** Return a value or a Promise — `unknown` already includes `Promise<unknown>`; `await` handles both. */\ntype ServerRequestHandler = (params: unknown) => unknown\n\nfunction isResponse(m: Record<string, unknown>): m is JsonRpcResponse & Record<string, unknown> {\n return typeof m.id === 'number' && (('result' in m) || ('error' in m)) && !('method' in m)\n}\nfunction isServerRequest(m: Record<string, unknown>): m is JsonRpcServerRequest & Record<string, unknown> {\n return typeof m.method === 'string' && typeof m.id === 'number'\n}\n\nexport class AcpClient {\n private nextId = 1\n private readonly pending = new Map<number, Pending>()\n private readonly handlers = new Map<string, ServerRequestHandler>()\n private readonly decoder = new AcpMessageDecoder()\n\n constructor(private readonly transport: AcpTransport) {\n transport.subscribe((chunk) => {\n for (const message of this.decoder.push(chunk)) {\n this.dispatch(message as Record<string, unknown>)\n }\n })\n }\n\n /** Send a JSON-RPC request and resolve with its `result` (or reject on `error`). */\n request(method: string, params: unknown): Promise<unknown> {\n const id = this.nextId++\n return new Promise<unknown>((resolve, reject) => {\n this.pending.set(id, { resolve, reject })\n this.transport.send(encodeAcpMessage({ jsonrpc: '2.0', id, method, params }))\n })\n }\n\n /** Register a handler for a server→client request method (e.g. `session/request_permission`). */\n onRequest(method: string, handler: ServerRequestHandler): void {\n this.handlers.set(method, handler)\n }\n\n private dispatch(message: Record<string, unknown>): void {\n if (isResponse(message)) {\n const entry = this.pending.get(message.id)\n if (!entry) return\n this.pending.delete(message.id)\n if (message.error) entry.reject(new Error(message.error.message))\n else entry.resolve(message.result)\n return\n }\n if (isServerRequest(message)) {\n void this.handleServerRequest(message)\n }\n }\n\n private async handleServerRequest(req: JsonRpcServerRequest): Promise<void> {\n const handler = this.handlers.get(req.method)\n if (!handler) {\n this.transport.send(\n encodeAcpMessage({ jsonrpc: '2.0', id: req.id, error: { code: -32601, message: `No handler: ${req.method}` } }),\n )\n return\n }\n try {\n const result = await handler(req.params)\n this.transport.send(encodeAcpMessage({ jsonrpc: '2.0', id: req.id, result }))\n } catch (err) {\n this.transport.send(\n encodeAcpMessage({\n jsonrpc: '2.0',\n id: req.id,\n error: { code: -32603, message: err instanceof Error ? err.message : 'handler failed' },\n }),\n )\n }\n }\n}\n"],"mappings":"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","names":["trimTrailingSlash","url","endsWith","slice","buildAgentCard","entry","options","base","baseUrl","name","description","route","version","capabilities","streaming","stream","pushNotifications","stateTransitionHistory","defaultInputModes","defaultOutputModes","skills","tools","map","t","id","wellKnownCardPath","agentName","MCP_PROTOCOL_VERSION","buildMcpToolDescriptors","entry","tools","map","t","name","description","inputSchema","type","properties","mcpServerInfo","version","protocolVersion","buildHeaders","config","headers","auth","bearer","authorization","apiKey","header","value","createA2ATool","doFetch","fetchImpl","fetch","name","description","inputSchema","type","properties","message","required","handler","input","res","url","method","body","JSON","stringify","ok","Error","status","statusText","data","json","response","text","SEPARATOR","deriveConversationId","resource","thread","Error","encodeURIComponent","parseConversationId","id","idx","indexOf","length","decodeURIComponent","slice","resolveEnabledSkills","selection","ctx","undefined","resolved","Array","isArray","Error","encodeAcpMessage","message","JSON","stringify","AcpMessageDecoder","buffer","push","chunk","messages","newlineIndex","indexOf","line","slice","trim","length","parse","cause","Error","isResponse","m","id","isServerRequest","method","AcpClient","nextId","pending","Map","handlers","decoder","AcpMessageDecoder","transport","subscribe","chunk","message","push","dispatch","request","params","Promise","resolve","reject","set","send","encodeAcpMessage","jsonrpc","onRequest","handler","entry","get","delete","error","Error","result","handleServerRequest","req","code","err"]}
1
+ {"version":3,"sources":["../src/a2a/agent-card.ts","../src/a2a/mcp-server-manifest.ts","../src/a2a/a2a-client.ts","../src/conversation-scope.ts","../src/skills-resolver.ts","../src/acp/protocol.ts","../src/acp/client.ts"],"sourcesContent":["/**\n * M15 (theokit-ai-first) — A2A agent card generation (ADR-0040 § D2, home/discovery concern).\n *\n * Produces an [A2A](https://github.com/google/A2A)-spec Agent Card from the framework's\n * `AgentManifestEntry`, so other systems can discover a TheoKit agent's capabilities over HTTP at\n * `/.well-known/<name>/agent-card.json`. Pure data transform — no LLM, no runtime (G2).\n */\nimport type { AgentManifestEntry } from '../manifest/agent-manifest.js'\n\n/** A single capability exposed by an A2A agent (maps from a TheoKit tool). */\nexport interface A2ASkill {\n id: string\n name: string\n description: string\n}\n\n/** A2A agent-card capabilities block. */\nexport interface A2ACapabilities {\n streaming: boolean\n pushNotifications: boolean\n stateTransitionHistory: boolean\n}\n\n/** An A2A-spec Agent Card (the subset TheoKit advertises). */\nexport interface AgentCard {\n name: string\n description: string\n url: string\n version: string\n capabilities: A2ACapabilities\n defaultInputModes: string[]\n defaultOutputModes: string[]\n skills: A2ASkill[]\n}\n\nexport interface BuildAgentCardOptions {\n /** Absolute base URL of the deployment (e.g. `https://app.example.com`). A trailing slash is trimmed. */\n baseUrl: string\n /** Human description of the agent. Defaults to a generated sentence when omitted (spec requires non-empty). */\n description?: string\n}\n\n/** Strip a single trailing slash so `${baseUrl}${route}` never doubles the separator. */\nfunction trimTrailingSlash(url: string): string {\n return url.endsWith('/') ? url.slice(0, -1) : url\n}\n\n/** Build an A2A agent card from a manifest entry. */\nexport function buildAgentCard(entry: AgentManifestEntry, options: BuildAgentCardOptions): AgentCard {\n const base = trimTrailingSlash(options.baseUrl)\n return {\n name: entry.name,\n description: options.description ?? `TheoKit agent \"${entry.name}\".`,\n url: `${base}${entry.route}`,\n version: '1.0',\n capabilities: {\n streaming: entry.stream,\n pushNotifications: false,\n stateTransitionHistory: false,\n },\n defaultInputModes: ['text'],\n defaultOutputModes: ['text'],\n skills: entry.tools.map((t) => ({ id: t.name, name: t.name, description: t.description })),\n }\n}\n\n/** The A2A discovery path for an agent: `/.well-known/<name>/agent-card.json`. */\nexport function wellKnownCardPath(agentName: string): string {\n return `/.well-known/${agentName}/agent-card.json`\n}\n","/**\n * M16 (theokit-ai-first) — MCP server manifest generation (ADR-0040 § D2, home concern).\n *\n * Exposes a TheoKit agent's tools to external MCP clients as `tools/list` descriptors, so the app\n * can advertise its agents over its OWN HTTP routes. Pure data transform — no LLM, no runtime, and\n * NO stdio transport (that stays SDK-side per sdk-runtime.md). Serving these over `GET /mcp` and the\n * JSON-RPC envelope are follow-ups (mount path).\n */\nimport type { AgentManifestEntry } from '../manifest/agent-manifest.js'\n\n/** The MCP protocol revision these descriptors target. */\nexport const MCP_PROTOCOL_VERSION = '2024-11-05'\n\n/** A JSON-schema object (the shape MCP expects for a tool's `inputSchema`). */\nexport interface McpJsonSchema {\n type: 'object'\n properties: Record<string, unknown>\n required?: string[]\n}\n\n/** An MCP `tools/list` tool descriptor. */\nexport interface McpToolDescriptor {\n name: string\n description: string\n inputSchema: McpJsonSchema\n}\n\n/** MCP `initialize` server info. */\nexport interface McpServerInfo {\n name: string\n version: string\n protocolVersion: string\n}\n\n/**\n * Map an agent's tools to MCP tool descriptors. The manifest tool carries name + description; the\n * per-tool JSON schema is not retained in the manifest, so a permissive empty-object schema is\n * emitted (MCP clients accept it and pass through arbitrary args). Wiring the real per-tool schema\n * is a follow-up once the manifest carries it.\n */\nexport function buildMcpToolDescriptors(entry: AgentManifestEntry): McpToolDescriptor[] {\n return entry.tools.map((t) => ({\n name: t.name,\n description: t.description,\n inputSchema: { type: 'object', properties: {} },\n }))\n}\n\n/** Build the MCP `initialize` server-info block for an agent. */\nexport function mcpServerInfo(entry: AgentManifestEntry): McpServerInfo {\n return { name: entry.name, version: '1.0', protocolVersion: MCP_PROTOCOL_VERSION }\n}\n","/**\n * M15 (theokit-ai-first) — A2A client: call a remote A2A agent as a tool (ADR-0040 § D2).\n *\n * `createA2ATool` returns a `CustomTool` whose handler POSTs the input message to a remote agent's\n * HTTP endpoint and returns its text response — cross-network delegation. Uses `fetch` (Web\n * Standards, G8). The target is a remote AGENT endpoint, not an LLM provider, so the G2 grep guard\n * (`openrouter.ai|api.openai.com|api.anthropic.com`) is unaffected. `fetchImpl` is injectable for tests.\n */\nimport type { CustomTool } from '@theokit/sdk'\n\n/** How to authenticate to the remote agent. */\nexport interface A2AAuth {\n /** Bearer token → `Authorization: Bearer <token>`. */\n bearer?: string\n /** API-key header pair → `<name>: <value>` (e.g. `x-api-key`). */\n apiKey?: { header: string; value: string }\n}\n\nexport interface A2AToolConfig {\n /** Remote agent endpoint URL (POST target). */\n url: string\n /** Tool name the model calls. */\n name: string\n /** Tool description surfaced to the model. */\n description: string\n /** Static headers merged into every request. */\n headers?: Record<string, string>\n /** Auth applied to every request. */\n auth?: A2AAuth\n /** Injected fetch (defaults to the global). Narrowed to the call shape this client uses. */\n fetchImpl?: (url: string, init: RequestInit) => Promise<Response>\n}\n\n/** Build the request headers from static headers + auth. */\nfunction buildHeaders(config: A2AToolConfig): Record<string, string> {\n const headers: Record<string, string> = { 'content-type': 'application/json', ...config.headers }\n if (config.auth?.bearer) headers.authorization = `Bearer ${config.auth.bearer}`\n if (config.auth?.apiKey) headers[config.auth.apiKey.header] = config.auth.apiKey.value\n return headers\n}\n\n/**\n * Create a tool that delegates to a remote A2A agent. The remote is expected to answer a\n * `{ message }` POST with a JSON body carrying a `response` (or `text`) string.\n */\nexport function createA2ATool(config: A2AToolConfig): CustomTool {\n const doFetch = config.fetchImpl ?? fetch\n return {\n name: config.name,\n description: config.description,\n inputSchema: {\n type: 'object',\n properties: { message: { type: 'string', description: 'The message to send to the remote agent.' } },\n required: ['message'],\n },\n handler: async (input: Record<string, unknown>): Promise<string> => {\n // The input schema requires `message: string`; narrow defensively (never base-to-string).\n const message = typeof input.message === 'string' ? input.message : ''\n const res = await doFetch(config.url, {\n method: 'POST',\n headers: buildHeaders(config),\n body: JSON.stringify({ message }),\n })\n if (!res.ok) {\n throw new Error(`A2A call to \"${config.name}\" failed: ${res.status} ${res.statusText}`)\n }\n const data = (await res.json()) as { response?: string; text?: string }\n return data.response ?? data.text ?? ''\n },\n }\n}\n","/**\n * M11 (theokit-ai-first) — {resource, thread} conversation scoping (ADR-0040 § D2, home concern).\n *\n * Maps a request's (resource, thread) pair to a deterministic, collision-safe conversation id so\n * multi-tenant apps isolate history without hand-building `user-${id}-thread-${id}` strings. This\n * is the app's request→conversation mapping — NOT the SDK's storage engine (which the derived id is\n * simply handed to). Background compression of long histories stays SDK-side.\n *\n * Encoding: each component is `encodeURIComponent`-escaped and joined with `/`. Since\n * `encodeURIComponent` escapes a raw `/` to `%2F`, the separator is unambiguous — `('a/b','c')` and\n * `('a','b/c')` derive DIFFERENT ids (collision-safe). Reversible via {@link parseConversationId}.\n */\n\nconst SEPARATOR = '/'\n\n/** Derive a deterministic conversation id from a (resource, thread) pair. Fails fast on empty input. */\nexport function deriveConversationId(resource: string, thread: string): string {\n if (!resource) throw new Error('[@theokit/agents] deriveConversationId: resource must be non-empty')\n if (!thread) throw new Error('[@theokit/agents] deriveConversationId: thread must be non-empty')\n return `${encodeURIComponent(resource)}${SEPARATOR}${encodeURIComponent(thread)}`\n}\n\n/**\n * Reverse a derived conversation id back to its (resource, thread). Returns `null` for a value that\n * is not a derived scope id (no separator, or an empty component) — callers treat that as \"opaque id,\n * not scoped\".\n */\nexport function parseConversationId(id: string): { resource: string; thread: string } | null {\n const idx = id.indexOf(SEPARATOR)\n if (idx <= 0 || idx >= id.length - 1) return null\n const resource = decodeURIComponent(id.slice(0, idx))\n const thread = decodeURIComponent(id.slice(idx + 1))\n if (!resource || !thread) return null\n return { resource, thread }\n}\n","/**\n * M13 (theokit-ai-first) — per-request skills resolution (ADR-0040 § D2, home/boundary concern).\n *\n * The static `skills.enabled` filter already works (`compile-skills` maps `include` → the SDK's\n * `enabled`). This adds a PER-REQUEST resolver so multi-tenant apps expose different skill sets to\n * different users. A selection is either a static list or a function of the request context (the M7\n * run-context). Discovery + injection stay in the SDK; this only CHOOSES the enabled set per call.\n */\n\n/** The request context handed to a skills resolver (the M7 run-context — opaque per-request data). */\nexport type SkillsRequestContext = Record<string, unknown>\n\n/**\n * How the enabled skill set is chosen:\n * - `string[]` — a static list (same shape `skills.enabled` accepts today).\n * - a function — resolved per request from the {@link SkillsRequestContext} (sync or async).\n */\nexport type SkillsSelection =\n | readonly string[]\n | ((ctx: SkillsRequestContext) => readonly string[] | Promise<readonly string[]>)\n\n/**\n * Resolve the enabled skill names for a request. Returns `undefined` when no selection is given (the\n * SDK then enables every discovered skill). Fails fast if a resolver returns a non-array.\n */\nexport async function resolveEnabledSkills(\n selection: SkillsSelection | undefined,\n ctx: SkillsRequestContext,\n): Promise<string[] | undefined> {\n if (selection === undefined) return undefined\n if (typeof selection !== 'function') return [...selection]\n const resolved = await selection(ctx)\n if (!Array.isArray(resolved)) {\n throw new Error('[@theokit/agents] skills resolver must return an array of skill names')\n }\n return [...resolved]\n}\n","/**\n * M17 (theokit-ai-first) — ACP (Agent Client Protocol) stdio framing.\n *\n * ACP talks to a coding agent (Claude Code, Amp, Codex) over stdio as newline-delimited JSON. This\n * is the transport-agnostic CORE: encode a message to a line, and decode a byte/char stream that may\n * split a message across chunks. Pure — no subprocess, no Node API. The subprocess spawn lives in the\n * adapter layer (G8) / SDK; `createACPTool` (wrapping this codec + an injected transport) is a\n * follow-up once the adapter ships.\n */\n\n/** Serialize a message to a single newline-terminated JSON line. */\nexport function encodeAcpMessage(message: unknown): string {\n return `${JSON.stringify(message)}\\n`\n}\n\n/**\n * Incremental decoder for newline-delimited JSON. Feed it chunks with {@link push}; it buffers a\n * partial trailing line across calls and returns every WHOLE message parsed so far. Blank lines are\n * skipped. A completed non-JSON line fails fast with a typed error (error-handling.md) — a corrupt\n * frame must never be silently dropped.\n */\nexport class AcpMessageDecoder {\n private buffer = ''\n\n /** Feed a chunk; returns the messages completed by this chunk (possibly empty). */\n push(chunk: string): unknown[] {\n this.buffer += chunk\n const messages: unknown[] = []\n let newlineIndex = this.buffer.indexOf('\\n')\n while (newlineIndex !== -1) {\n const line = this.buffer.slice(0, newlineIndex).trim()\n this.buffer = this.buffer.slice(newlineIndex + 1)\n if (line.length > 0) {\n try {\n messages.push(JSON.parse(line))\n } catch (cause) {\n throw new Error(`[@theokit/agents] ACP decode failed on line: ${line}`, { cause })\n }\n }\n newlineIndex = this.buffer.indexOf('\\n')\n }\n return messages\n }\n}\n","/**\n * M17 (theokit-ai-first) — ACP client: JSON-RPC over the stdio framing.\n *\n * Drives a coding agent (Claude Code, Amp, Codex) over an INJECTED {@link AcpTransport}. The\n * subprocess spawn is a Node API and lives in the adapter layer (G8); this client is transport-\n * agnostic and testable. It correlates responses to requests by `id`, and dispatches server→client\n * requests (e.g. `session/request_permission`) to a registered handler, replying with its decision.\n */\nimport { AcpMessageDecoder, encodeAcpMessage } from './protocol.js'\n\n/** The stdio channel to the coding-agent subprocess (abstracted for testability + G8). */\nexport interface AcpTransport {\n /** Write one already-encoded (newline-terminated) line to the agent's stdin. */\n send(line: string): void\n /** Subscribe to raw lines/chunks from the agent's stdout. */\n subscribe(onData: (chunk: string) => void): void\n}\n\ninterface JsonRpcResponse {\n id: number\n result?: unknown\n error?: { code: number; message: string }\n}\ninterface JsonRpcServerRequest {\n id: number\n method: string\n params?: unknown\n}\n\ninterface Pending {\n resolve: (value: unknown) => void\n reject: (err: Error) => void\n}\n/** Return a value or a Promise — `unknown` already includes `Promise<unknown>`; `await` handles both. */\ntype ServerRequestHandler = (params: unknown) => unknown\n\nfunction isResponse(m: Record<string, unknown>): m is JsonRpcResponse & Record<string, unknown> {\n return typeof m.id === 'number' && (('result' in m) || ('error' in m)) && !('method' in m)\n}\nfunction isServerRequest(m: Record<string, unknown>): m is JsonRpcServerRequest & Record<string, unknown> {\n return typeof m.method === 'string' && typeof m.id === 'number'\n}\n\nexport class AcpClient {\n private nextId = 1\n private readonly pending = new Map<number, Pending>()\n private readonly handlers = new Map<string, ServerRequestHandler>()\n private readonly decoder = new AcpMessageDecoder()\n\n constructor(private readonly transport: AcpTransport) {\n transport.subscribe((chunk) => {\n for (const message of this.decoder.push(chunk)) {\n this.dispatch(message as Record<string, unknown>)\n }\n })\n }\n\n /** Send a JSON-RPC request and resolve with its `result` (or reject on `error`). */\n request(method: string, params: unknown): Promise<unknown> {\n const id = this.nextId++\n return new Promise<unknown>((resolve, reject) => {\n this.pending.set(id, { resolve, reject })\n this.transport.send(encodeAcpMessage({ jsonrpc: '2.0', id, method, params }))\n })\n }\n\n /** Register a handler for a server→client request method (e.g. `session/request_permission`). */\n onRequest(method: string, handler: ServerRequestHandler): void {\n this.handlers.set(method, handler)\n }\n\n private dispatch(message: Record<string, unknown>): void {\n if (isResponse(message)) {\n const entry = this.pending.get(message.id)\n if (!entry) return\n this.pending.delete(message.id)\n if (message.error) entry.reject(new Error(message.error.message))\n else entry.resolve(message.result)\n return\n }\n if (isServerRequest(message)) {\n void this.handleServerRequest(message)\n }\n }\n\n private async handleServerRequest(req: JsonRpcServerRequest): Promise<void> {\n const handler = this.handlers.get(req.method)\n if (!handler) {\n this.transport.send(\n encodeAcpMessage({ jsonrpc: '2.0', id: req.id, error: { code: -32601, message: `No handler: ${req.method}` } }),\n )\n return\n }\n try {\n const result = await handler(req.params)\n this.transport.send(encodeAcpMessage({ jsonrpc: '2.0', id: req.id, result }))\n } catch (err) {\n this.transport.send(\n encodeAcpMessage({\n jsonrpc: '2.0',\n id: req.id,\n error: { code: -32603, message: err instanceof Error ? err.message : 'handler failed' },\n }),\n )\n }\n }\n}\n"],"mappings":"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","names":["trimTrailingSlash","url","endsWith","slice","buildAgentCard","entry","options","base","baseUrl","name","description","route","version","capabilities","streaming","stream","pushNotifications","stateTransitionHistory","defaultInputModes","defaultOutputModes","skills","tools","map","t","id","wellKnownCardPath","agentName","MCP_PROTOCOL_VERSION","buildMcpToolDescriptors","entry","tools","map","t","name","description","inputSchema","type","properties","mcpServerInfo","version","protocolVersion","buildHeaders","config","headers","auth","bearer","authorization","apiKey","header","value","createA2ATool","doFetch","fetchImpl","fetch","name","description","inputSchema","type","properties","message","required","handler","input","res","url","method","body","JSON","stringify","ok","Error","status","statusText","data","json","response","text","SEPARATOR","deriveConversationId","resource","thread","Error","encodeURIComponent","parseConversationId","id","idx","indexOf","length","decodeURIComponent","slice","resolveEnabledSkills","selection","ctx","undefined","resolved","Array","isArray","Error","encodeAcpMessage","message","JSON","stringify","AcpMessageDecoder","buffer","push","chunk","messages","newlineIndex","indexOf","line","slice","trim","length","parse","cause","Error","isResponse","m","id","isServerRequest","method","AcpClient","nextId","pending","Map","handlers","decoder","AcpMessageDecoder","transport","subscribe","chunk","message","push","dispatch","request","params","Promise","resolve","reject","set","send","encodeAcpMessage","jsonrpc","onRequest","handler","entry","get","delete","error","Error","result","handleServerRequest","req","code","err"]}
@@ -194,6 +194,12 @@ interface HumanInTheLoopOptions {
194
194
  onTimeout?: TimeoutAction;
195
195
  /** Show the tool input to the approver (default: true). */
196
196
  showInput?: boolean;
197
+ /**
198
+ * M20 — an optional JSON-schema descriptor of the custom payload the approver may attach (edited
199
+ * args, a review note). Carried into the `approval_required` event + `GET /approvals` so the UI
200
+ * knows what to collect. A plain JSON object, not a live Zod schema (keeps the wire serializable).
201
+ */
202
+ payloadSchema?: Record<string, unknown>;
197
203
  }
198
204
  declare function HumanInTheLoop(options: HumanInTheLoopOptions): MethodDecorator;
199
205
  declare function getHumanInTheLoopConfig(target: Function, propertyKey: string | symbol): HumanInTheLoopOptions | undefined;
@@ -257,4 +263,51 @@ interface SkillsOptions {
257
263
  declare function Skills(namesOrOptions: string[] | SkillsOptions): ClassDecorator;
258
264
  declare function getSkillsConfig(target: Function): SkillsOptions | undefined;
259
265
 
260
- export { type AgentOptions as A, type BudgetOptions as B, Checkpoint as C, type ToolOptions as D, type ToolboxOptions as E, getCheckpointConfig as F, Gateway as G, HumanInTheLoop as H, type IndexStrategy as I, getCompactionConfig as J, getContextWindowConfig as K, getGatewayConfig as L, MCP as M, getHumanInTheLoopConfig as N, getMcpConfig as O, type PlatformName as P, getMemoryConfig as Q, type ReasoningEffort as R, type SessionStrategy as S, type TimeoutAction as T, getProjectContextConfig as U, getSkillsConfig as V, resolveSessionId as W, type ApprovalOptions as a, type CheckpointOptions as b, type CheckpointState as c, type CheckpointStorage as d, type CheckpointStrategy as e, Compaction as f, type CompactionDecoratorConfig as g, type ContextCompactionStrategy as h, ContextWindow as i, type ContextWindowOptions as j, type GatewayOptions as k, type HumanInTheLoopOptions as l, type MainLoopMeta as m, type MainLoopOptions as n, type McpServerConfig as o, type McpServersMap as p, Memory as q, type MemoryOptions as r, type MemoryProvider as s, type MemoryScope as t, type PolicyHandler as u, ProjectContext as v, type ProjectContextOptions as w, type RelevanceStrategy as x, Skills as y, type SkillsOptions as z };
266
+ /**
267
+ * M9 (theokit-ai-first) — guardrail contract + typed errors.
268
+ *
269
+ * ADR-0040 § D2: guardrails are a HOME/BOUNDARY concern (filter user input before the SDK,
270
+ * filter model output before the client). They REUSE the SDK runtime — this module makes zero
271
+ * LLM calls. A guard reports one of three actions; the pipeline (`pipeline.ts`) enforces them.
272
+ */
273
+ /** What a guard decided for a piece of text. */
274
+ type GuardrailAction = 'allow' | 'block' | 'redact';
275
+ /**
276
+ * The result of a single guard check.
277
+ * - `allow` — text passes untouched.
278
+ * - `block` — the pipeline throws {@link GuardrailViolationError}; the run stops fail-fast.
279
+ * - `redact` — the pipeline replaces the text with {@link GuardrailResult.text} and continues.
280
+ */
281
+ interface GuardrailResult {
282
+ action: GuardrailAction;
283
+ /** Human-readable reason — required in spirit for `block`, surfaced in the thrown error. */
284
+ reason?: string;
285
+ /** The transformed text — present (and used) only when `action === 'redact'`. */
286
+ text?: string;
287
+ }
288
+ /**
289
+ * A guardrail. A guard MAY inspect input (before the model), output (after the model), or both.
290
+ * A guard that omits a phase hook is skipped for that phase.
291
+ */
292
+ interface Guardrail {
293
+ readonly name: string;
294
+ checkInput?(text: string): GuardrailResult | Promise<GuardrailResult>;
295
+ checkOutput?(text: string): GuardrailResult | Promise<GuardrailResult>;
296
+ }
297
+ /** Which boundary phase a violation happened in. */
298
+ type GuardrailPhase = 'input' | 'output';
299
+ /** Thrown (fail-fast) when a guard returns `action: 'block'`. Typed per error-handling.md. */
300
+ declare class GuardrailViolationError extends Error {
301
+ readonly guardName: string;
302
+ readonly phase: GuardrailPhase;
303
+ readonly reason: string;
304
+ constructor(guardName: string, phase: GuardrailPhase, reason: string);
305
+ }
306
+ /** Thrown when {@link costGuard}'s cumulative token budget is exceeded. */
307
+ declare class CostBudgetExceededError extends Error {
308
+ readonly usedTokens: number;
309
+ readonly maxTokens: number;
310
+ constructor(usedTokens: number, maxTokens: number);
311
+ }
312
+
313
+ export { getSkillsConfig as $, type AgentOptions as A, type BudgetOptions as B, Checkpoint as C, type PolicyHandler as D, ProjectContext as E, type ProjectContextOptions as F, type Guardrail as G, HumanInTheLoop as H, type IndexStrategy as I, type RelevanceStrategy as J, Skills as K, type SkillsOptions as L, MCP as M, type ToolOptions as N, type ToolboxOptions as O, type PlatformName as P, getCheckpointConfig as Q, type ReasoningEffort as R, type SessionStrategy as S, type TimeoutAction as T, getCompactionConfig as U, getContextWindowConfig as V, getGatewayConfig as W, getHumanInTheLoopConfig as X, getMcpConfig as Y, getMemoryConfig as Z, getProjectContextConfig as _, type ApprovalOptions as a, resolveSessionId as a0, type CheckpointOptions as b, type CheckpointState as c, type CheckpointStorage as d, type CheckpointStrategy as e, Compaction as f, type CompactionDecoratorConfig as g, type ContextCompactionStrategy as h, ContextWindow as i, type ContextWindowOptions as j, CostBudgetExceededError as k, Gateway as l, type GatewayOptions as m, type GuardrailAction as n, type GuardrailPhase as o, type GuardrailResult as p, GuardrailViolationError as q, type HumanInTheLoopOptions as r, type MainLoopMeta as s, type MainLoopOptions as t, type McpServerConfig as u, type McpServersMap as v, Memory as w, type MemoryOptions as x, type MemoryProvider as y, type MemoryScope as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theokit/agents",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Unified decorator runtime — AI agents as first-class citizens of the TheoKit pipeline. @Agent() compiles to SDK Agent.create(), @Tool() compiles to defineTool().",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -29,9 +29,14 @@
29
29
  "README.md",
30
30
  "LICENSE"
31
31
  ],
32
+ "scripts": {
33
+ "build": "tsup",
34
+ "test": "vitest run",
35
+ "test:watch": "vitest"
36
+ },
32
37
  "peerDependencies": {
33
38
  "@theokit/http": ">=0.1.0-alpha.0",
34
- "@theokit/sdk": ">=2.13.0",
39
+ "@theokit/sdk": ">=2.20.0",
35
40
  "@theokit/sdk-tools": ">=0.2.0",
36
41
  "ai": ">=7.0.0",
37
42
  "reflect-metadata": ">=0.2.0",
@@ -46,22 +51,17 @@
46
51
  }
47
52
  },
48
53
  "devDependencies": {
49
- "@theokit/sdk": "^2.13.0",
54
+ "@theokit/http": "workspace:*",
55
+ "@theokit/sdk": "^2.20.0",
50
56
  "@theokit/sdk-tools": "^0.2.0",
51
57
  "ai": "^7.0.14",
52
58
  "reflect-metadata": "^0.2.2",
53
59
  "tsup": "^8.5.1",
54
60
  "typescript": "^5.9.3",
55
61
  "vitest": "^3.2.6",
56
- "zod": "^4.4.3",
57
- "@theokit/http": "0.5.4"
62
+ "zod": "^4.4.3"
58
63
  },
59
64
  "engines": {
60
65
  "node": ">=22.12.0"
61
- },
62
- "scripts": {
63
- "build": "tsup",
64
- "test": "vitest run",
65
- "test:watch": "vitest"
66
66
  }
67
- }
67
+ }