@theokit/agents 11.0.0 → 12.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,107 @@
1
1
  # @theokit/agents
2
2
 
3
+ ## 12.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 8691f5c: `@theokit/agents/pty` is gone. The PTY backend now lives in `@theokit/agents-pty`, and installing `@theokit/agents` no longer compiles a terminal.
8
+
9
+ `@theokit/sdk-pty` declares `"install": "node scripts/prebuild.js || node-gyp rebuild"` — a native step that downloads a prebuild or falls back to a C++ compile. As a hard dependency of this package, **every consumer paid it**, including every web application that will never open a terminal. Measured: installing `@theokit/agents` alone took **6.7 s** with it and **1.4 s** without, and in a scaffolded app that was most of the gap in time to first green run (30.40 ± 7.50 s against Next.js's 14.93 ± 0.91 s) — with our build faster and our dependency tree smaller.
10
+
11
+ **To upgrade**, if you import the subpath:
12
+
13
+ ```diff
14
+ -import { PtyInteractiveBackend } from '@theokit/agents/pty'
15
+ +import { PtyInteractiveBackend } from '@theokit/agents-pty'
16
+ ```
17
+
18
+ plus `npm install @theokit/agents-pty`.
19
+
20
+ You do not have to find this note to know: `@theokit/agents/pty` still resolves, and using anything from it throws with the two lines above. It imports nothing, so keeping it costs no dependency and no native build — the failure is a sentence rather than an `ERR_MODULE_NOT_FOUND` you have to diagnose.
21
+
22
+ The surface is identical — the same six symbols, and the new package's test asserts they are the upstream identities rather than a wrapper. Nothing else changes.
23
+
24
+ If you do not import it, you install 5.3 s faster and there is nothing to do.
25
+
26
+ **Why a package and not an optional peer.** That was tried and reverted: a peer means _the host provides it_, and the M63 boundary forbids an application from importing `@theokit/sdk*` at all — so it would ask a consumer to declare exactly what it may not use. A sibling package is something the consumer genuinely does import, with no inversion. Recorded in `docs/adr/0004-the-terminal-is-a-separate-package.md`, along with the two alternatives rejected (a lazy `import()`, which defers nothing that is being measured, and documenting the cost, which is read after the decision it would inform).
27
+
28
+ ### Minor Changes
29
+
30
+ - ed68f9f: A configuration error now reaches the browser with its own message, instead of the generic mask.
31
+
32
+ `missing_api_key` and `malformed_api_key` are the operator's own input — the person reading the blank error is the person who forgot to set the variable. Masking them cost that person the first ten minutes of every misconfiguration, and did it next to a `transient: true` that means _do not persist in history_ on this protocol and _retry may help_ everywhere else a developer has met the word. Together they read as a network hiccup.
33
+
34
+ Everything else is unchanged. #390's default stands: a driver's message, an HTTP client's, a filesystem call's — anything that could name a host, a path, a query or a credential — still reaches the browser as `An error occurred.`, with the failure code travelling separately so consumers never go back to matching on text.
35
+
36
+ The hole is keyed on **codes**, not on the error class. `ConfigurationError` is a large surface and parts of it do describe internals, so an allowlist keyed on the parent would widen by accident the first time something new subclassed it. Adding a code to the list is a decision about what a browser may read, and the bar is written beside it.
37
+
38
+ A host that passes its own `onError` is unaffected — the allowlist is the default's behaviour, not a rule imposed above the hook.
39
+
40
+ - bf623e4: A paused run can reach its owner off the stream. `HitlWiring.onApprovalRequired` is the opt-in seam.
41
+
42
+ The framework's asynchronous promise — _the agent works and comes back when it needs your approval_ — held only while a client was attached. `ApprovalRequiredEvent` went into the run's own event stream and nowhere else, so a caller not consuming that stream never learned the run was waiting, and it stayed parked until someone opened the surface and looked (#458).
43
+
44
+ ```ts
45
+ createHitlPlugin({
46
+ gated,
47
+ emit,
48
+ awaitApproval,
49
+ onApprovalRequired: async ({ toolName, question, callbackUrl, timeoutMs }) => {
50
+ await myDelivery.send({ text: `${question} — ${toolName}`, url: `${BASE}/${callbackUrl}` })
51
+ },
52
+ })
53
+ ```
54
+
55
+ It receives the same facts the stream carries and does whatever the **application** does. Deliberately not a `@theokit/gateway` dependency: this package must not import from it, and choosing a channel is a policy decision the framework does not get to make. `@theokit/gateway`'s `DeliveryRouter` is the obvious thing to hand it, and that stays the app's decision.
56
+
57
+ **Fire-and-forget by contract, and both halves of that are tested.** The run does not wait for it, so a slow dispatch cannot hold a gated tool open; and it does not fail on it, so a Slack outage cannot decide whether a gated tool runs. A rejected promise is swallowed — the outcome belongs to the human, not to the channel.
58
+
59
+ Optional: a wiring without the hook behaves exactly as before.
60
+
61
+ ## 11.1.0
62
+
63
+ ### Minor Changes
64
+
65
+ - e01c3c2: The in-process turn can be told to retry, and a tool can read the run's real token usage.
66
+
67
+ **`retry` on the in-process turn (#474).** `streamAgentTurnInProcess` — the entry point an embedded
68
+ surface uses, and the one both surfaces of a terminal agent come through — accepts `retry?:
69
+ RetryOptions`. A transient provider failure that kills the turn before it produced anything is
70
+ recovered instead of ending it. `streamAgentUIMessages` accepts the same field, so the HTTP path
71
+ gains it too.
72
+
73
+ This is not the forwarded field the issue expected, and the difference is the whole fix.
74
+ `AgentRunnerRunOptions.retry` belongs to the reflective loop, whose round factory is allowed to
75
+ throw; this path runs one SDK turn, and — measured against the shipped `@theokit/sdk@4.52.1` —
76
+ the SDK never rejects on a provider failure. `agent.send()` resolves before the model is called, and
77
+ the loop's failure comes back as the run's terminal `status: "ERROR"` **event**. A `Retry` wrapper
78
+ around the stream's creation, which is what "thread the option through" would have produced, would
79
+ have compiled, shipped, and never fired. What ships instead treats that first `error` event as the
80
+ throw the SDK declined to make.
81
+
82
+ The retry window closes on the first event, so nothing has reached the caller and no tool has run —
83
+ a recovered failure can never re-apply an edit. Whether a failure is worth retrying is read from the
84
+ run's own typed error (`RunResult.error.cause` → `isTransientError`), never from the message text: a
85
+ rate limit retries, a bad key does not. Absent ⇒ a single attempt, byte-identical to before.
86
+
87
+ **`ctx.usage` for tool handlers (#475).** With `exposeUsageToTools: true`, every tool handler
88
+ receives the run's provider-reported token usage, read with `readRunUsage(ctx)` from
89
+ `@theokit/agents/usage`. This is what a `get_context_remaining` tool needs; before it, the only
90
+ figure reachable from inside a handler was a character-count estimate over `ctx.messages`.
91
+
92
+ The numbers come from the SDK's own `BudgetTracker`, which the agent loop calls after each LLM
93
+ completion with the provider's counts — so they are measurements, never projections. Until the first
94
+ report arrives the snapshot is `undefined`, not `0`: "not known yet" and "zero tokens used" are
95
+ different facts and only one is ever true. The context window travels with it when the model
96
+ **declared** one (`ModelSelection.contextWindow`), along with the `remainingTokens` that needs both
97
+ halves; for a bare model id both are absent rather than guessed from the model catalog, which
98
+ answers an unknown model with a conservative default and no way to tell that apart from a real
99
+ entry. A `budgetTracker` the caller already supplied is wrapped, not replaced, so an existing spend
100
+ gate keeps gating.
101
+
102
+ Both options are additive: omitting them leaves the stream, the SDK call, and the tool ctx exactly as
103
+ they were.
104
+
3
105
  ## 11.0.0
4
106
 
5
107
  ### Major Changes
@@ -3,6 +3,7 @@ import { c as AgentOptions, T as ToolOptions, P as ProjectContextOptions, H as H
3
3
  import { C as CompiledAgentOptions, a as CompiledTool, G as Guardrail, S as SkillsSelection } from './agent-compiler-tetgj6zR.js';
4
4
  import { SkillsSettings, ContextSettings, SystemPromptResolver, ModelSelection, PluginsSettings, Plugin, ProviderRoutingSettings, AgentDefinition as AgentDefinition$1, BudgetTracker, CustomTool, RunEventSink, MemorySettings } from '@theokit/sdk';
5
5
  import { S as StreamEvent, f as ApprovalRequiredEvent, a4 as MaskError } from './delegation-scoring-CQtF2Zaf.js';
6
+ import { RetryOptions } from '@theokit/sdk/retry';
6
7
  import { SandboxPosture } from '@theokit/sdk/sandbox';
7
8
  import { A as AgentDefinition, S as SettingSourcesSelection } from './define-agent-BnH1MBxs.js';
8
9
  import { z } from 'zod';
@@ -200,6 +201,31 @@ interface HitlWiring {
200
201
  * a bare boolean (legacy) OR a {@link HitlDecision} carrying an approver `reason` + `payload`.
201
202
  */
202
203
  awaitApproval: (approvalId: string, opts: HumanInTheLoopOptions, toolName: string) => Promise<boolean | HitlDecision>;
204
+ /**
205
+ * OPTIONAL — reach the owner off the stream (usetheokit/theokit#458).
206
+ *
207
+ * `emit` above puts the pause into the run's own event stream, and that was the only egress: a
208
+ * caller not currently consuming it never learned the run was waiting, so the framework's
209
+ * asynchronous promise held exactly as long as someone was watching.
210
+ *
211
+ * This receives the same facts the stream carries and does whatever the APPLICATION does — Slack,
212
+ * email, a row in a table. Deliberately not a `@theokit/gateway` dependency: this package must not
213
+ * import from it, and picking a channel is a policy decision the framework does not get to make.
214
+ *
215
+ * Fire-and-forget by contract. The run does not wait for it and does not fail on it: a dispatch
216
+ * outage must not decide whether a gated tool runs, and must not delay the pause it announces.
217
+ */
218
+ onApprovalRequired?: (request: ApprovalRequest) => void | Promise<void>;
219
+ }
220
+ /** What an application is told when a gated tool pauses. The stream's facts, off the stream. */
221
+ interface ApprovalRequest {
222
+ approvalId: string;
223
+ toolName: string;
224
+ question: string;
225
+ input: unknown;
226
+ /** Relative, exactly as the stream carries it — the app knows its own base URL; this does not. */
227
+ callbackUrl: string;
228
+ timeoutMs: number;
203
229
  }
204
230
 
205
231
  /**
@@ -408,6 +434,32 @@ interface RuntimeOverrides {
408
434
  * why the key is omitted entirely rather than set to `undefined` when absent.
409
435
  */
410
436
  onRunEvent?: RunEventSink;
437
+ /**
438
+ * theokit#474 — per-turn transient retry, opt-in.
439
+ *
440
+ * When set, the START of the turn (the SDK handshake plus its first event, before anything is
441
+ * yielded) is wrapped in the SDK `Retry`, so a 429/5xx/network blip that kills the turn before it
442
+ * produced anything is recovered instead of ending it. Absent ⇒ a single attempt, and the key is
443
+ * omitted from every downstream call, so the stream is byte-identical to before.
444
+ *
445
+ * See `turn-retry.ts` for why a rejection-shaped retry would have been inert on this path, and
446
+ * for the invariant that closes the retry window on the first event.
447
+ */
448
+ retry?: RetryOptions;
449
+ /**
450
+ * theokit#475 — expose the run's REAL token usage to tool handlers as `ctx.usage`, opt-in.
451
+ *
452
+ * When true, the adapter installs a {@link RunUsageMeter} as the run's `budgetTracker` (wrapping
453
+ * the caller's own, when there is one) and hands every tool handler a snapshot of what the
454
+ * provider has reported so far. A tool can then answer "how much context is left?" from a
455
+ * measurement instead of a character-count estimate. See `usage/run-usage.ts`.
456
+ *
457
+ * Opt-in rather than always-on because installing a `budgetTracker` changes what `Agent.create`
458
+ * receives for every run that never asked for it, and the back-compat floor here is a floor, not
459
+ * a preference. Absent ⇒ handlers are wrapped exactly as before (`ctx.usage` does not exist) and
460
+ * the SDK receives no tracker it was not already given.
461
+ */
462
+ exposeUsageToTools?: boolean;
411
463
  }
412
464
  declare function createSdkAgentStream(compiled: CompiledAgentOptions, compiledTools: CompiledTool[], apiKey: string | (() => string | Promise<string>), overrides?: RuntimeOverrides): ((message: string, sessionId: string, factoryOpts?: {
413
465
  disableTools?: boolean;
@@ -978,6 +1030,30 @@ interface StreamAgentOptions {
978
1030
  * the stream is byte-identical to before.
979
1031
  */
980
1032
  onRunEvent?: RuntimeOverrides['onRunEvent'];
1033
+ /**
1034
+ * theokit#474 — per-turn transient retry.
1035
+ *
1036
+ * `AgentRunnerRunOptions.retry` has existed since V4-P, and it belongs to the OTHER runtime: the
1037
+ * reflective loop, whose round factory is allowed to throw. This entry point runs one SDK turn,
1038
+ * and the SDK reports a provider failure as the run's terminal `error` EVENT rather than as a
1039
+ * rejection — so the option could not simply be forwarded, and a wrapper that only caught throws
1040
+ * would have been inert. See `turn-retry.ts`.
1041
+ *
1042
+ * Absent ⇒ the key is omitted from the SDK call entirely and the turn is a single attempt, exactly
1043
+ * as before.
1044
+ */
1045
+ retry?: RuntimeOverrides['retry'];
1046
+ /**
1047
+ * theokit#475 — expose the run's REAL token usage to tool handlers as `ctx.usage`.
1048
+ *
1049
+ * The seam a `get_context_remaining`-style tool needs: without it the only figure reachable from
1050
+ * inside a handler is a character-count estimate over `ctx.messages`. Read it with `readRunUsage`
1051
+ * from `@theokit/agents/usage`.
1052
+ *
1053
+ * Absent ⇒ handlers receive exactly the ctx they did before and the SDK receives no tracker it
1054
+ * was not already given.
1055
+ */
1056
+ exposeUsageToTools?: RuntimeOverrides['exposeUsageToTools'];
981
1057
  }
982
1058
  /**
983
1059
  * Run a compiled agent and yield the M0/M1 `UIMessageStream` chunks. `apiKey` is resolved by the
@@ -1426,4 +1502,4 @@ declare function agentsPlugin(opts: AgentsPluginOptions): {
1426
1502
  register(app: PluginApp): void;
1427
1503
  };
1428
1504
 
1429
- export { createApiErrorHandler as $, type AgentManifestEntry as A, type BeforeToolCallContext as B, type ContextWindowOptions as C, type DefinitionOrThunk as D, type EphemeralAgent as E, type SdkMessage as F, type SdkSendOptions as G, type HitlDecision as H, type SdkTurnHandle as I, type Segment as J, type ShouldAutoApproveOptions as K, type LLMCallContext as L, type McpApprovalSpec as M, type ToolHooks as N, type ToolHooksPlugin as O, type ProcessInputContext as P, agentsPlugin as Q, applyPosture as R, type SkillsOptions as S, type ToolCallVeto as T, buildModelSelection as U, compileAgentModule as V, WRITE_SCOPED_TOOLS as W, compileContextWindow as X, compileProjectContext as Y, compileSkills as Z, createAgentExecutionContext as _, type ApprovalPosture as a, createSdkAgentStream as a0, createThinkTagExtractor as a1, createToolHooksPlugin as a2, extractThinkTagStream as a3, generateAgentManifest as a4, generateAgentRoutes as a5, isAgentContext as a6, loadMcpJson as a7, mcpRegistry as a8, mcpToolApprovals as a9, projectContextMetadataOnlyKnobs as aa, reasoningEffortOf as ab, resolveMcpServers as ac, runWithApiErrorHandling as ad, shouldAutoApprove as ae, toAgentFactory as af, translateSdkEvent as ag, withClockCap as ah, withEphemeralAgent as ai, APPROVAL_MODES as b, type AfterToolCallContext as c, AgentBuilder as d, AgentDefinitionError as e, type AgentExecutionContext as f, type AgentManifest as g, type AgentManifestSource as h, type AgentManifestTool as i, type AgentRoute as j, type AgentRouteContext as k, type AgentRunInfo as l, type AgentsPluginOptions as m, type ApiErrorContext as n, type ApiErrorDecision as o, type ApiErrorPolicy as p, type ApprovalMode as q, type CompiledContextWindow as r, streamAgentUIMessages as s, ContextualTool as t, DelegationTimeoutError as u, McpFileError as v, type McpRegistryConfig as w, type McpRequestContext as x, type McpSelection as y, type SdkAgentHandle as z };
1505
+ export { createAgentExecutionContext as $, type AgentManifestEntry as A, type BeforeToolCallContext as B, type ContextWindowOptions as C, type DefinitionOrThunk as D, type EphemeralAgent as E, type SdkAgentHandle as F, type SdkMessage as G, type HitlDecision as H, type SdkSendOptions as I, type SdkTurnHandle as J, type Segment as K, type LLMCallContext as L, type McpApprovalSpec as M, type ShouldAutoApproveOptions as N, type ToolHooks as O, type ProcessInputContext as P, type ToolHooksPlugin as Q, agentsPlugin as R, type SkillsOptions as S, type ToolCallVeto as T, applyPosture as U, buildModelSelection as V, WRITE_SCOPED_TOOLS as W, compileAgentModule as X, compileContextWindow as Y, compileProjectContext as Z, compileSkills as _, type ApprovalPosture as a, createApiErrorHandler as a0, createSdkAgentStream as a1, createThinkTagExtractor as a2, createToolHooksPlugin as a3, extractThinkTagStream as a4, generateAgentManifest as a5, generateAgentRoutes as a6, isAgentContext as a7, loadMcpJson as a8, mcpRegistry as a9, mcpToolApprovals as aa, projectContextMetadataOnlyKnobs as ab, reasoningEffortOf as ac, resolveMcpServers as ad, runWithApiErrorHandling as ae, shouldAutoApprove as af, toAgentFactory as ag, translateSdkEvent as ah, withClockCap as ai, withEphemeralAgent as aj, APPROVAL_MODES as b, type AfterToolCallContext as c, AgentBuilder as d, AgentDefinitionError as e, type AgentExecutionContext as f, type AgentManifest as g, type AgentManifestSource as h, type AgentManifestTool as i, type AgentRoute as j, type AgentRouteContext as k, type AgentRunInfo as l, type AgentsPluginOptions as m, type ApiErrorContext as n, type ApiErrorDecision as o, type ApiErrorPolicy as p, type ApprovalMode as q, type ApprovalRequest as r, streamAgentUIMessages as s, type CompiledContextWindow as t, ContextualTool as u, DelegationTimeoutError as v, McpFileError as w, type McpRegistryConfig as x, type McpRequestContext as y, type McpSelection as z };
package/dist/bridge.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { b as APPROVAL_MODES, c as AfterToolCallContext, d as AgentBuilder, e as AgentDefinitionError, f as AgentExecutionContext, g as AgentManifest, A as AgentManifestEntry, h as AgentManifestSource, i as AgentManifestTool, j as AgentRoute, k as AgentRouteContext, l as AgentRunInfo, m as AgentsPluginOptions, n as ApiErrorContext, o as ApiErrorDecision, p as ApiErrorPolicy, q as ApprovalMode, a as ApprovalPosture, B as BeforeToolCallContext, r as CompiledContextWindow, t as ContextualTool, D as DefinitionOrThunk, u as DelegationTimeoutError, E as EphemeralAgent, L as LLMCallContext, M as McpApprovalSpec, v as McpFileError, w as McpRegistryConfig, x as McpRequestContext, y as McpSelection, P as ProcessInputContext, z as SdkAgentHandle, F as SdkMessage, G as SdkSendOptions, I as SdkTurnHandle, J as Segment, K as ShouldAutoApproveOptions, T as ToolCallVeto, N as ToolHooks, O as ToolHooksPlugin, W as WRITE_SCOPED_TOOLS, Q as agentsPlugin, R as applyPosture, U as buildModelSelection, V as compileAgentModule, X as compileContextWindow, Y as compileProjectContext, Z as compileSkills, _ as createAgentExecutionContext, $ as createApiErrorHandler, a0 as createSdkAgentStream, a1 as createThinkTagExtractor, a2 as createToolHooksPlugin, a3 as extractThinkTagStream, a4 as generateAgentManifest, a5 as generateAgentRoutes, a6 as isAgentContext, a7 as loadMcpJson, a8 as mcpRegistry, a9 as mcpToolApprovals, aa as projectContextMetadataOnlyKnobs, ab as reasoningEffortOf, ac as resolveMcpServers, ad as runWithApiErrorHandling, ae as shouldAutoApprove, s as streamAgentUIMessages, af as toAgentFactory, ag as translateSdkEvent, ah as withClockCap, ai as withEphemeralAgent } from './bridge-entry-DRAzQ7UA.js';
1
+ export { b as APPROVAL_MODES, c as AfterToolCallContext, d as AgentBuilder, e as AgentDefinitionError, f as AgentExecutionContext, g as AgentManifest, A as AgentManifestEntry, h as AgentManifestSource, i as AgentManifestTool, j as AgentRoute, k as AgentRouteContext, l as AgentRunInfo, m as AgentsPluginOptions, n as ApiErrorContext, o as ApiErrorDecision, p as ApiErrorPolicy, q as ApprovalMode, a as ApprovalPosture, B as BeforeToolCallContext, t as CompiledContextWindow, u as ContextualTool, D as DefinitionOrThunk, v as DelegationTimeoutError, E as EphemeralAgent, L as LLMCallContext, M as McpApprovalSpec, w as McpFileError, x as McpRegistryConfig, y as McpRequestContext, z as McpSelection, P as ProcessInputContext, F as SdkAgentHandle, G as SdkMessage, I as SdkSendOptions, J as SdkTurnHandle, K as Segment, N as ShouldAutoApproveOptions, T as ToolCallVeto, O as ToolHooks, Q as ToolHooksPlugin, W as WRITE_SCOPED_TOOLS, R as agentsPlugin, U as applyPosture, V as buildModelSelection, X as compileAgentModule, Y as compileContextWindow, Z as compileProjectContext, _ as compileSkills, $ as createAgentExecutionContext, a0 as createApiErrorHandler, a1 as createSdkAgentStream, a2 as createThinkTagExtractor, a3 as createToolHooksPlugin, a4 as extractThinkTagStream, a5 as generateAgentManifest, a6 as generateAgentRoutes, a7 as isAgentContext, a8 as loadMcpJson, a9 as mcpRegistry, aa as mcpToolApprovals, ab as projectContextMetadataOnlyKnobs, ac as reasoningEffortOf, ad as resolveMcpServers, ae as runWithApiErrorHandling, af as shouldAutoApprove, s as streamAgentUIMessages, ag as toAgentFactory, ah as translateSdkEvent, ai as withClockCap, aj as withEphemeralAgent } from './bridge-entry-Cv6kXSZe.js';
2
2
  export { C as CompiledAgentOptions, a as CompiledTool, T as ToolWalkResult, h as ToolboxWalkResult, i as compileTools } from './agent-compiler-tetgj6zR.js';
3
3
  export { A as AgentStopReason, d as AgentStreamEvent, e as AgentTurnMetadata, f as ApprovalRequiredEvent, g as ArtifactChunkEvent, h as ArtifactStartEvent, B as BackgroundDelegation, i as BudgetExceededError, C as CheckpointSavedEvent, k as DelegateFn, a as DelegateOptions, l as DelegationBudgetExceededError, m as DelegationError, n as DelegationPort, c as DelegationResult, D as DelegationTarget, o as DoneEvent, E as ErrorEvent, F as FileEditEvent, I as IterationEvent, P as PartialToolCallEvent, v as RunStartedEvent, w as ScoreVerdict, x as ScoredDelegation, y as Scorer, z as StateUpdateEvent, S as StreamEvent, T as TextDeltaEvent, G as ThinkingEvent, H as ToolCallEvent, J as ToolResultEvent, K as delegate, M as delegateBackground, N as delegateWithScoring, O as isApprovalRequired, Q as isDone, U as isError, V as isPartialToolCall, W as isTextDelta, X as isToolCall, Y as isToolResult, a0 as presentUIMessageStream, a3 as streamAgentResponse } from './delegation-scoring-CQtF2Zaf.js';
4
4
  export { a as AGENT_BRAND, A as AgentDefinition, D as DefineAgentConfig, I as InferAgentInput, b as InferAgentToolNames, P as ProjectSettingsGrant, c as SettingSourceCapability, S as SettingSourcesSelection, U as UntrustedSettingSourceError, d as compileAgentDefinition, i as isAgentDefinition, r as resolveSettingSources } from './define-agent-BnH1MBxs.js';
@@ -6,8 +6,8 @@ import '@theokit/http';
6
6
  import './types-C16Wuh9E.js';
7
7
  import '@theokit/sdk';
8
8
  import 'zod';
9
+ import '@theokit/sdk/retry';
9
10
  import '@theokit/sdk/sandbox';
10
11
  import './hook-handlers-Cw2FsnE5.js';
11
12
  import '@theokit/presenter/wire';
12
13
  import '@theokit/sdk/errors';
13
- import '@theokit/sdk/retry';
package/dist/bridge.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  runWithApiErrorHandling,
29
29
  streamAgentResponse,
30
30
  streamAgentUIMessages
31
- } from "./chunk-T5MBTKA2.js";
31
+ } from "./chunk-OHTXQMR2.js";
32
32
  import {
33
33
  APPROVAL_MODES,
34
34
  BudgetExceededError,
@@ -53,7 +53,7 @@ import {
53
53
  translateSdkEvent,
54
54
  withClockCap,
55
55
  withEphemeralAgent
56
- } from "./chunk-4EHZG6KN.js";
56
+ } from "./chunk-GQ3XVROU.js";
57
57
  import "./chunk-RKWCXVYG.js";
58
58
  import {
59
59
  AGENT_BRAND,
@@ -62,6 +62,7 @@ import {
62
62
  isAgentDefinition,
63
63
  resolveSettingSources
64
64
  } from "./chunk-LLIERPF3.js";
65
+ import "./chunk-OXNDJSAJ.js";
65
66
  import "./chunk-Z4QWC7IK.js";
66
67
  export {
67
68
  AGENT_BRAND,
@@ -5,6 +5,9 @@ import {
5
5
  import {
6
6
  compileAgentDefinition
7
7
  } from "./chunk-LLIERPF3.js";
8
+ import {
9
+ createRunUsageMeter
10
+ } from "./chunk-OXNDJSAJ.js";
8
11
  import {
9
12
  __name
10
13
  } from "./chunk-Z4QWC7IK.js";
@@ -377,6 +380,21 @@ function createHitlPlugin(wiring) {
377
380
  payloadSchema: opts.payloadSchema
378
381
  } : {}
379
382
  });
383
+ if (wiring.onApprovalRequired !== void 0) {
384
+ void (async () => {
385
+ try {
386
+ await wiring.onApprovalRequired?.({
387
+ approvalId,
388
+ toolName: c.name,
389
+ question: opts.question,
390
+ input: c.args,
391
+ callbackUrl: `approve/${approvalId}`,
392
+ timeoutMs: opts.timeout ?? 3e5
393
+ });
394
+ } catch {
395
+ }
396
+ })();
397
+ }
380
398
  const raw = await wiring.awaitApproval(approvalId, opts, c.name);
381
399
  const decision = typeof raw === "boolean" ? {
382
400
  approved: raw
@@ -489,6 +507,10 @@ function modelIdOf(model) {
489
507
  return typeof model === "string" ? model : model.id;
490
508
  }
491
509
  __name(modelIdOf, "modelIdOf");
510
+ function contextWindowOf(model) {
511
+ return typeof model === "string" ? void 0 : model.contextWindow;
512
+ }
513
+ __name(contextWindowOf, "contextWindowOf");
492
514
  function reasoningEffortOf(model) {
493
515
  const params = typeof model === "string" ? void 0 : model.params;
494
516
  return params?.find((p) => p.id === PARAM_THINKING)?.value;
@@ -1074,6 +1096,20 @@ function translateTimelineEvent(ev, runId, seen) {
1074
1096
  }
1075
1097
  __name(translateTimelineEvent, "translateTimelineEvent");
1076
1098
 
1099
+ // src/bridge/tool-context-injection.ts
1100
+ function withInjectedToolContext(handler, injection) {
1101
+ return (input, ctx) => handler(input, {
1102
+ ...ctx,
1103
+ ...injection.runContext !== void 0 ? {
1104
+ context: injection.runContext.value
1105
+ } : {},
1106
+ ...injection.meter !== void 0 ? {
1107
+ usage: injection.meter.snapshot()
1108
+ } : {}
1109
+ });
1110
+ }
1111
+ __name(withInjectedToolContext, "withInjectedToolContext");
1112
+
1077
1113
  // src/bridge/tool-dialect-stripper.ts
1078
1114
  var OPEN2 = "<function=";
1079
1115
  var CLOSE2 = "</tool_call>";
@@ -1172,6 +1208,61 @@ async function* stripToolDialectStream(source) {
1172
1208
  }
1173
1209
  __name(stripToolDialectStream, "stripToolDialectStream");
1174
1210
 
1211
+ // src/bridge/turn-retry.ts
1212
+ import { TheokitAgentError as TheokitAgentError2 } from "@theokit/sdk/errors";
1213
+ function asText(value) {
1214
+ return typeof value === "string" && value.length > 0 ? value : void 0;
1215
+ }
1216
+ __name(asText, "asText");
1217
+ function startFailure(event, outcome) {
1218
+ if (outcome.failure !== void 0) return outcome.failure;
1219
+ return new TheokitAgentError2(asText(event.message) ?? "The turn failed before producing any output.", {
1220
+ code: asText(event.code) ?? "TURN_START_FAILED",
1221
+ isRetryable: event.retryable === true
1222
+ });
1223
+ }
1224
+ __name(startFailure, "startFailure");
1225
+ async function startTurn(open, retry) {
1226
+ const attempt = /* @__PURE__ */ __name(async () => {
1227
+ const { stream, outcome } = open();
1228
+ const it = stream[Symbol.asyncIterator]();
1229
+ try {
1230
+ const first = await it.next();
1231
+ if (!first.done && first.value.type === "error") throw startFailure(first.value, outcome);
1232
+ return {
1233
+ it,
1234
+ first
1235
+ };
1236
+ } catch (err) {
1237
+ await it.return?.(void 0);
1238
+ throw err;
1239
+ }
1240
+ }, "attempt");
1241
+ const { Retry } = await import("@theokit/sdk/retry");
1242
+ return Retry.create(attempt, retry);
1243
+ }
1244
+ __name(startTurn, "startTurn");
1245
+ async function* withTurnStartRetry(open, retry) {
1246
+ const { it, first } = await startTurn(open, retry);
1247
+ let next = first;
1248
+ while (!next.done) {
1249
+ yield next.value;
1250
+ next = await it.next();
1251
+ }
1252
+ }
1253
+ __name(withTurnStartRetry, "withTurnStartRetry");
1254
+ function runTurnWithRetry(open, retry) {
1255
+ if (retry === void 0) return open();
1256
+ return withTurnStartRetry(() => {
1257
+ const outcome = {};
1258
+ return {
1259
+ stream: open(outcome),
1260
+ outcome
1261
+ };
1262
+ }, retry);
1263
+ }
1264
+ __name(runTurnWithRetry, "runTurnWithRetry");
1265
+
1175
1266
  // src/bridge/sdk-adapter.ts
1176
1267
  function withLeakedDialectRecovery(providers) {
1177
1268
  return {
@@ -1243,15 +1334,19 @@ function hasZodInputSchema(schema) {
1243
1334
  return typeof schema?.parse === "function";
1244
1335
  }
1245
1336
  __name(hasZodInputSchema, "hasZodInputSchema");
1246
- function withRunContext(handler, runContext) {
1247
- return (input, ctx) => handler(input, {
1248
- ...ctx,
1249
- context: runContext
1250
- });
1251
- }
1252
- __name(withRunContext, "withRunContext");
1253
- function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext) {
1254
- const has = runContext !== void 0;
1337
+ function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext, meter) {
1338
+ const injection = {
1339
+ ...runContext !== void 0 ? {
1340
+ runContext: {
1341
+ value: runContext
1342
+ }
1343
+ } : {},
1344
+ ...meter !== void 0 ? {
1345
+ meter
1346
+ } : {}
1347
+ };
1348
+ const has = injection.runContext !== void 0 || injection.meter !== void 0;
1349
+ const inject = /* @__PURE__ */ __name((h) => has ? withInjectedToolContext(h, injection) : h, "inject");
1255
1350
  return [
1256
1351
  ...compiledTools.map((t) => {
1257
1352
  if (hasZodInputSchema(t.inputSchema)) {
@@ -1259,17 +1354,17 @@ function buildSdkTools(compiledTools, defineTool, extraSdkTools = [], runContext
1259
1354
  name: t.name,
1260
1355
  description: t.description,
1261
1356
  inputSchema: t.inputSchema,
1262
- handler: has ? withRunContext(t.handler, runContext) : t.handler
1357
+ handler: inject(t.handler)
1263
1358
  });
1264
1359
  }
1265
1360
  return has ? {
1266
1361
  ...t,
1267
- handler: withRunContext(t.handler, runContext)
1362
+ handler: inject(t.handler)
1268
1363
  } : t;
1269
1364
  }),
1270
1365
  ...extraSdkTools.map((t) => has ? {
1271
1366
  ...t,
1272
- handler: withRunContext(t.handler, runContext)
1367
+ handler: inject(t.handler)
1273
1368
  } : t)
1274
1369
  ];
1275
1370
  }
@@ -1294,7 +1389,11 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
1294
1389
  };
1295
1390
  return;
1296
1391
  }
1297
- const sdkTools = buildSdkTools(compiledTools, rt.defineTool, overrides.sdkTools, runContext);
1392
+ const usageMeter = overrides.exposeUsageToTools === true ? createRunUsageMeter({
1393
+ contextWindowTokens: contextWindowOf(model),
1394
+ delegate: overrides.budgetTracker
1395
+ }) : void 0;
1396
+ const sdkTools = buildSdkTools(compiledTools, rt.defineTool, overrides.sdkTools, runContext, usageMeter);
1298
1397
  const inlineSkills = compiled.skills?.inline;
1299
1398
  if (inlineSkills !== void 0 && inlineSkills.length > 0 && rt.defineSkillReadTool !== void 0 && !compiledTools.some((t) => t.name === "skill_read")) {
1300
1399
  sdkTools.push(rt.defineSkillReadTool(inlineSkills));
@@ -1311,20 +1410,27 @@ function createSdkAgentStream(compiled, compiledTools, apiKey, overrides = {}) {
1311
1410
  source: runContextSource,
1312
1411
  keys: runContext !== void 0 ? Object.keys(runContext) : []
1313
1412
  });
1413
+ const turnOpts = {
1414
+ apiKey: await resolverApiKey(apiKey),
1415
+ model,
1416
+ reasoningEffort,
1417
+ overrides,
1418
+ parseThinkTags,
1419
+ stripToolDialect,
1420
+ sessionId,
1421
+ message,
1422
+ factoryOpts,
1423
+ runId,
1424
+ t0,
1425
+ ...usageMeter !== void 0 ? {
1426
+ usageMeter
1427
+ } : {}
1428
+ };
1314
1429
  try {
1315
- yield* streamSdkAgent(rt, compiled, sdkTools, {
1316
- apiKey: await resolverApiKey(apiKey),
1317
- model,
1318
- reasoningEffort,
1319
- overrides,
1320
- parseThinkTags,
1321
- stripToolDialect,
1322
- sessionId,
1323
- message,
1324
- factoryOpts,
1325
- runId,
1326
- t0
1327
- });
1430
+ yield* runTurnWithRetry((outcome) => streamSdkAgent(rt, compiled, sdkTools, outcome === void 0 ? turnOpts : {
1431
+ ...turnOpts,
1432
+ outcome
1433
+ }), overrides.retry);
1328
1434
  } catch (err) {
1329
1435
  yield sdkErrorEvent(err);
1330
1436
  }
@@ -1348,6 +1454,7 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
1348
1454
  baseDir: overrides.baseDir
1349
1455
  };
1350
1456
  const extra = buildExtraCreateOptions(overrides, compiled);
1457
+ if (opts.usageMeter !== void 0) extra.budgetTracker = opts.usageMeter.tracker;
1351
1458
  if (applied.length > 0) {
1352
1459
  debugLog("[THEO_AGENT_M8_RUNTIME_APPLIED]", {
1353
1460
  skills: applied.includes("skills"),
@@ -1388,7 +1495,11 @@ async function* streamSdkAgent(rt, compiled, sdkTools, opts) {
1388
1495
  }
1389
1496
  }, "emit");
1390
1497
  for await (const ev of run.events()) {
1391
- yield* emit(translateTimelineEvent(ev, runId, seen));
1498
+ const translated = translateTimelineEvent(ev, runId, seen);
1499
+ if (opts.outcome !== void 0 && state.lastEventType === "" && translated.some((e) => e.type === "error")) {
1500
+ opts.outcome.failure = (await (await sendPromise).wait()).error?.cause;
1501
+ }
1502
+ yield* emit(translated);
1392
1503
  }
1393
1504
  yield* emit(flushPendingToolResults(seen));
1394
1505
  }, "timeline");
@@ -1596,8 +1707,8 @@ var noopReflectionStrategy = {
1596
1707
  };
1597
1708
 
1598
1709
  // src/bridge/delegation-types.ts
1599
- import { TheokitAgentError as TheokitAgentError2 } from "@theokit/sdk/errors";
1600
- var DelegationBudgetExceededError = class extends TheokitAgentError2 {
1710
+ import { TheokitAgentError as TheokitAgentError3 } from "@theokit/sdk/errors";
1711
+ var DelegationBudgetExceededError = class extends TheokitAgentError3 {
1601
1712
  static {
1602
1713
  __name(this, "DelegationBudgetExceededError");
1603
1714
  }
@@ -1614,7 +1725,7 @@ var DelegationBudgetExceededError = class extends TheokitAgentError2 {
1614
1725
  }
1615
1726
  };
1616
1727
  var BudgetExceededError = DelegationBudgetExceededError;
1617
- var DelegationError = class extends TheokitAgentError2 {
1728
+ var DelegationError = class extends TheokitAgentError3 {
1618
1729
  static {
1619
1730
  __name(this, "DelegationError");
1620
1731
  }
@@ -2204,8 +2315,8 @@ async function delegate(spec, message, opts = {}) {
2204
2315
  __name(delegate, "delegate");
2205
2316
 
2206
2317
  // src/bridge/delegation-lifecycle.ts
2207
- import { TheokitAgentError as TheokitAgentError3 } from "@theokit/sdk/errors";
2208
- var DelegationTimeoutError = class extends TheokitAgentError3 {
2318
+ import { TheokitAgentError as TheokitAgentError4 } from "@theokit/sdk/errors";
2319
+ var DelegationTimeoutError = class extends TheokitAgentError4 {
2209
2320
  static {
2210
2321
  __name(this, "DelegationTimeoutError");
2211
2322
  }
@@ -2368,4 +2479,4 @@ export {
2368
2479
  delegateBackground,
2369
2480
  delegateWithScoring
2370
2481
  };
2371
- //# sourceMappingURL=chunk-4EHZG6KN.js.map
2482
+ //# sourceMappingURL=chunk-GQ3XVROU.js.map