@theokit/agents 4.23.0 → 4.24.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.
@@ -0,0 +1,57 @@
1
+ import { UIMessage } from 'ai';
2
+ import { R as RequestContext, U as UseAgentStatus, A as ApprovalDecision, a as AgentHandle, b as AgentTransport } from './agent-handle-DNbFlkrw.js';
3
+
4
+ interface UseAgentReturn<TInput = unknown, TToolNames extends string = string> {
5
+ /** The CURRENT turn's assistant messages (per-turn; reset each `send`). Back-compat since M41. */
6
+ messages: UIMessage[];
7
+ /**
8
+ * M46 — the full conversation to render: committed turns + the current turn's user + in-flight
9
+ * assistant, accumulated across sends with stable ids. Prefer this over hand-rolling a transcript
10
+ * from `messages`. Same shape on every surface (web/desktop/TUI) — it lives in the core store.
11
+ */
12
+ thread: UIMessage[];
13
+ status: UseAgentStatus;
14
+ /** The last error, or `undefined`. */
15
+ error: Error | undefined;
16
+ /** Send a request; opens a new stream. Typed to the agent's `input` schema. */
17
+ send: (input: TInput) => void;
18
+ /** Abort an in-flight stream. */
19
+ abort: () => void;
20
+ /** Clear messages + error, back to idle. */
21
+ reset: () => void;
22
+ /** Settle a paused HITL approval (HTTP `POST /approve/<id>` for web; the inline callback in-process). */
23
+ approve: (approvalId: string, decision: ApprovalDecision) => Promise<void>;
24
+ /** Resume an interrupted stream (M37 durable transport for web; a no-op in-process). */
25
+ reconnect: () => void;
26
+ /**
27
+ * The union of tool names this agent can emit (M8), carried end-to-end from the `agent()` builder's
28
+ * accumulated tool-name type through the generated `@theo/agents` client. Type-only witness (never
29
+ * populated at runtime). Resolves to the literal union for builder agents, `string` otherwise.
30
+ */
31
+ readonly __toolNames?: TToolNames;
32
+ }
33
+ interface UseAgentOptions {
34
+ /**
35
+ * Extra request headers (e.g., auth) — applied when a string path builds an `HttpTransport`. Read on
36
+ * EVERY request, so a value that changes across renders (a rotating JWT) is never sent stale.
37
+ */
38
+ headers?: Record<string, string>;
39
+ /** Override fetch (primarily for tests) — captured when a string path builds an `HttpTransport`. */
40
+ fetch?: typeof fetch;
41
+ /**
42
+ * M43 — per-request context attached uniformly to EVERY transport (`headers` → HTTP request headers;
43
+ * `metadata` → the in-process runner / Tauri invoke). A value OR a resolver evaluated on every
44
+ * send/reconnect, so a rotating token/tenant is never stale.
45
+ */
46
+ context?: RequestContext | (() => RequestContext | undefined);
47
+ }
48
+ /**
49
+ * Bind to an agent by endpoint path (`/api/agents/<name>`), by a typed {@link AgentHandle} (M47 — the
50
+ * generated `chat` handle; kills the magic string + duplicated input type), or by an explicit
51
+ * {@link AgentTransport}. Prefer the generated `useAgent` from `@theo/agents` (typed by agent name or
52
+ * handle); this base accepts all three. The store is created once per binding identity — memoize a
53
+ * transport before passing it.
54
+ */
55
+ declare function useAgent<TInput = unknown>(binding: string | AgentHandle<TInput> | AgentTransport, options?: UseAgentOptions): UseAgentReturn<TInput>;
56
+
57
+ export { type UseAgentOptions, type UseAgentReturn, UseAgentStatus, useAgent };
@@ -0,0 +1,55 @@
1
+ import {
2
+ AgentClient,
3
+ HttpTransport,
4
+ isAgentHandle
5
+ } from "./chunk-M2JFE6IM.js";
6
+ import {
7
+ __name
8
+ } from "./chunk-7QVYU63E.js";
9
+
10
+ // src/client/use-agent.ts
11
+ import { useMemo, useRef, useSyncExternalStore } from "react";
12
+ function useAgent(binding, options = {}) {
13
+ const optionsRef = useRef(options);
14
+ optionsRef.current = options;
15
+ let api;
16
+ if (typeof binding === "string") api = binding;
17
+ else if (isAgentHandle(binding)) api = binding.path;
18
+ const bindingIdentity = api ?? binding;
19
+ const client = useMemo(
20
+ () => new AgentClient(
21
+ api !== void 0 ? new HttpTransport({
22
+ api,
23
+ headers: /* @__PURE__ */ __name(() => optionsRef.current.headers, "headers"),
24
+ fetch: optionsRef.current.fetch
25
+ }) : binding,
26
+ // M43 — resolve context live from the ref each send/reconnect (never stale). A value or a resolver.
27
+ () => {
28
+ const ctx = optionsRef.current.context;
29
+ return typeof ctx === "function" ? ctx() : ctx;
30
+ }
31
+ ),
32
+ // bindingIdentity captures api/binding; options resolve live via optionsRef (rebuild would drop messages).
33
+ // eslint-disable-next-line react-hooks/exhaustive-deps
34
+ [
35
+ bindingIdentity
36
+ ]
37
+ );
38
+ const state = useSyncExternalStore(client.subscribe, client.getSnapshot, client.getSnapshot);
39
+ return {
40
+ messages: state.messages,
41
+ thread: state.thread,
42
+ status: state.status,
43
+ error: state.error,
44
+ send: client.send,
45
+ abort: client.abort,
46
+ reset: client.reset,
47
+ approve: client.approve,
48
+ reconnect: client.reconnect
49
+ };
50
+ }
51
+ __name(useAgent, "useAgent");
52
+ export {
53
+ useAgent
54
+ };
55
+ //# sourceMappingURL=client-react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/use-agent.ts"],"sourcesContent":["import type { UIMessage } from 'ai'\nimport { useMemo, useRef, useSyncExternalStore } from 'react'\n\nimport { AgentClient, type UseAgentStatus } from './agent-client.js'\nimport { type AgentHandle, isAgentHandle } from './agent-handle.js'\nimport { HttpTransport } from './http-transport.js'\nimport type { AgentTransport, ApprovalDecision, RequestContext } from './transport.js'\n\n/**\n * M2 (theokit-ai-first) / M41 (ADR-0050) — `useAgent`, the ONE typed client hook for the\n * `agents/*.ts` convention, unified across surfaces.\n *\n * Pass an endpoint path (web) OR an {@link AgentTransport} (terminal/desktop). A string is wrapped in\n * an {@link HttpTransport} (exact back-compat with the pre-M41 fetch+SSE hook); an `InProcessTransport`\n * drives the SAME hook in a single process. The hook is a thin binding over the framework-agnostic\n * {@link AgentClient} store via React's native `useSyncExternalStore` (no test-DOM dependency). The\n * generated `@theo/agents` module types `send` to the agent's `input` schema — inferred end-to-end\n * from the server `defineAgent({ input })` with ZERO manual wiring.\n */\nexport type { UseAgentStatus }\n\nexport interface UseAgentReturn<TInput = unknown, TToolNames extends string = string> {\n /** The CURRENT turn's assistant messages (per-turn; reset each `send`). Back-compat since M41. */\n messages: UIMessage[]\n /**\n * M46 — the full conversation to render: committed turns + the current turn's user + in-flight\n * assistant, accumulated across sends with stable ids. Prefer this over hand-rolling a transcript\n * from `messages`. Same shape on every surface (web/desktop/TUI) — it lives in the core store.\n */\n thread: UIMessage[]\n status: UseAgentStatus\n /** The last error, or `undefined`. */\n error: Error | undefined\n /** Send a request; opens a new stream. Typed to the agent's `input` schema. */\n send: (input: TInput) => void\n /** Abort an in-flight stream. */\n abort: () => void\n /** Clear messages + error, back to idle. */\n reset: () => void\n /** Settle a paused HITL approval (HTTP `POST /approve/<id>` for web; the inline callback in-process). */\n approve: (approvalId: string, decision: ApprovalDecision) => Promise<void>\n /** Resume an interrupted stream (M37 durable transport for web; a no-op in-process). */\n reconnect: () => void\n /**\n * The union of tool names this agent can emit (M8), carried end-to-end from the `agent()` builder's\n * accumulated tool-name type through the generated `@theo/agents` client. Type-only witness (never\n * populated at runtime). Resolves to the literal union for builder agents, `string` otherwise.\n */\n readonly __toolNames?: TToolNames\n}\n\nexport interface UseAgentOptions {\n /**\n * Extra request headers (e.g., auth) — applied when a string path builds an `HttpTransport`. Read on\n * EVERY request, so a value that changes across renders (a rotating JWT) is never sent stale.\n */\n headers?: Record<string, string>\n /** Override fetch (primarily for tests) — captured when a string path builds an `HttpTransport`. */\n fetch?: typeof fetch\n /**\n * M43 — per-request context attached uniformly to EVERY transport (`headers` → HTTP request headers;\n * `metadata` → the in-process runner / Tauri invoke). A value OR a resolver evaluated on every\n * send/reconnect, so a rotating token/tenant is never stale.\n */\n context?: RequestContext | (() => RequestContext | undefined)\n}\n\n/**\n * Bind to an agent by endpoint path (`/api/agents/<name>`), by a typed {@link AgentHandle} (M47 — the\n * generated `chat` handle; kills the magic string + duplicated input type), or by an explicit\n * {@link AgentTransport}. Prefer the generated `useAgent` from `@theo/agents` (typed by agent name or\n * handle); this base accepts all three. The store is created once per binding identity — memoize a\n * transport before passing it.\n */\nexport function useAgent<TInput = unknown>(\n binding: string | AgentHandle<TInput> | AgentTransport,\n options: UseAgentOptions = {},\n): UseAgentReturn<TInput> {\n // Track the latest options so the built HttpTransport reads current headers per request (dynamic\n // auth is never stale) without rebuilding the store — which would drop in-flight messages.\n const optionsRef = useRef(options)\n optionsRef.current = options\n\n // A handle resolves to its HTTP path; a string is already a path — both build an HttpTransport. A\n // transport is used as-is. `api` is undefined only for a transport binding.\n let api: string | undefined\n if (typeof binding === 'string') api = binding\n else if (isAgentHandle(binding)) api = binding.path\n // Identity is the binding (a handle's path OR a transport instance) — a stable key for the memo.\n const bindingIdentity = api ?? binding\n\n const client = useMemo(\n () =>\n new AgentClient<TInput>(\n api !== undefined\n ? new HttpTransport({\n api,\n headers: () => optionsRef.current.headers,\n fetch: optionsRef.current.fetch,\n })\n : (binding as AgentTransport),\n // M43 — resolve context live from the ref each send/reconnect (never stale). A value or a resolver.\n () => {\n const ctx = optionsRef.current.context\n return typeof ctx === 'function' ? ctx() : ctx\n },\n ),\n // bindingIdentity captures api/binding; options resolve live via optionsRef (rebuild would drop messages).\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [bindingIdentity],\n )\n\n const state = useSyncExternalStore(client.subscribe, client.getSnapshot, client.getSnapshot)\n\n return {\n messages: state.messages,\n thread: state.thread,\n status: state.status,\n error: state.error,\n send: client.send,\n abort: client.abort,\n reset: client.reset,\n approve: client.approve,\n reconnect: client.reconnect,\n }\n}\n"],"mappings":";;;;;;;;;;AACA,SAASA,SAASC,QAAQC,4BAA4B;AAyE/C,SAASC,SACdC,SACAC,UAA2B,CAAC,GAAC;AAI7B,QAAMC,aAAaC,OAAOF,OAAAA;AAC1BC,aAAWE,UAAUH;AAIrB,MAAII;AACJ,MAAI,OAAOL,YAAY,SAAUK,OAAML;WAC9BM,cAAcN,OAAAA,EAAUK,OAAML,QAAQO;AAE/C,QAAMC,kBAAkBH,OAAOL;AAE/B,QAAMS,SAASC;IACb,MACE,IAAIC;MACFN,QAAQO,SACJ,IAAIC,cAAc;QAChBR;QACAS,SAAS,6BAAMZ,WAAWE,QAAQU,SAAzB;QACTC,OAAOb,WAAWE,QAAQW;MAC5B,CAAA,IACCf;;MAEL,MAAA;AACE,cAAMgB,MAAMd,WAAWE,QAAQa;AAC/B,eAAO,OAAOD,QAAQ,aAAaA,IAAAA,IAAQA;MAC7C;IAAA;;;IAIJ;MAACR;;EAAgB;AAGnB,QAAMU,QAAQC,qBAAqBV,OAAOW,WAAWX,OAAOY,aAAaZ,OAAOY,WAAW;AAE3F,SAAO;IACLC,UAAUJ,MAAMI;IAChBC,QAAQL,MAAMK;IACdC,QAAQN,MAAMM;IACdC,OAAOP,MAAMO;IACbC,MAAMjB,OAAOiB;IACbC,OAAOlB,OAAOkB;IACdC,OAAOnB,OAAOmB;IACdC,SAASpB,OAAOoB;IAChBC,WAAWrB,OAAOqB;EACpB;AACF;AAnDgB/B;","names":["useMemo","useRef","useSyncExternalStore","useAgent","binding","options","optionsRef","useRef","current","api","isAgentHandle","path","bindingIdentity","client","useMemo","AgentClient","undefined","HttpTransport","headers","fetch","ctx","context","state","useSyncExternalStore","subscribe","getSnapshot","messages","thread","status","error","send","abort","reset","approve","reconnect"]}
@@ -0,0 +1,81 @@
1
+ import { b as AgentTransport, A as ApprovalDecision } from './agent-handle-DNbFlkrw.js';
2
+ export { c as AgentClient, d as AgentClientState, a as AgentHandle, C as ChannelPushSource, e as ChannelTransport, f as ChannelTransportOptions, g as ChannelTurnHandlers, I as InProcessApprovalRequestLike, h as InProcessAwaitApproval, i as InProcessRunInput, j as InProcessRunner, k as InProcessTransport, l as InProcessTransportOptions, R as RequestContext, U as UseAgentStatus, m as agentHandle, n as isAgentHandle } from './agent-handle-DNbFlkrw.js';
3
+ import { ChatTransport, UIMessage, UIMessageChunk } from 'ai';
4
+
5
+ /** Extra request headers — a static record OR a resolver called per request (for dynamic auth). */
6
+ type HeadersResolver = Record<string, string> | (() => Record<string, string> | undefined);
7
+ interface HttpTransportOptions {
8
+ /** Agent endpoint path or URL, e.g. `/api/agents/support`. */
9
+ api: string;
10
+ /**
11
+ * Extra request headers (e.g. auth). Static record OR a resolver evaluated on EVERY request — pass a
12
+ * resolver when the value is dynamic (a rotating JWT), so a stale header is never sent. Merged UNDER
13
+ * per-request headers.
14
+ */
15
+ headers?: HeadersResolver;
16
+ /** Override fetch (primarily for tests / non-browser hosts) — static; resolved once at construction. */
17
+ fetch?: typeof fetch;
18
+ }
19
+ /**
20
+ * M41 (ADR-0050 D3) — `ChatTransport` over the web agent path.
21
+ *
22
+ * - `sendMessages`: `POST <api>` with the UIMessageStream `accept` + the `X-Theo-Action` CSRF header
23
+ * (HTTP method + headers are identical to the pre-M41 `useAgent` fetch; the body shape is a superset —
24
+ * `{ ...input, messages: [UIMessage] }` — which the server's dual-path parser accepts, so no
25
+ * regression), captures the server-minted `x-theokit-run-id`, and returns `ReadableStream<UIMessageChunk>`
26
+ * via `ai`'s own SSE parser (`responseToChunkStream`).
27
+ * - `reconnectToStream`: `GET <api>/runs/<runId>/stream` (M37 durable transport); 404 → `null` (the run
28
+ * completed / was evicted). A caller may pass a `Last-Event-ID` header to resume only the tail; by
29
+ * default the server replays the run from the start and the client upserts by message id (idempotent).
30
+ * - `approve`: `POST <api>/approve/<id>` (out-of-band HITL settle).
31
+ *
32
+ * Implemented directly (not by subclassing `DefaultChatTransport`) because reconnect keys on our
33
+ * server-minted `runId` captured from a response header, which the base class does not expose — see
34
+ * ADR-0050 D3.
35
+ */
36
+ declare class HttpTransport implements AgentTransport {
37
+ #private;
38
+ constructor(options: HttpTransportOptions);
39
+ sendMessages(options: Parameters<ChatTransport<UIMessage>['sendMessages']>[0]): Promise<ReadableStream<UIMessageChunk>>;
40
+ reconnectToStream(options: Parameters<ChatTransport<UIMessage>['reconnectToStream']>[0]): Promise<ReadableStream<UIMessageChunk> | null>;
41
+ approve(approvalId: string, decision: ApprovalDecision): Promise<void>;
42
+ }
43
+
44
+ /**
45
+ * M2 (theokit-ai-first) — read a TheoKit agent endpoint's `UIMessageStream` SSE `Response`
46
+ * into reconstructed assistant `UIMessage`s, reusing the `ai` package's own consumer
47
+ * primitives (`parseJsonEventStream` + `readUIMessageStream`) — the exact path
48
+ * `@ai-sdk/react`'s `useChat` runs internally. No reinvented wire parser (Rule 9).
49
+ *
50
+ * `ai` is an OPTIONAL peer dependency, so it is imported dynamically: an app that never
51
+ * calls an agent never pays for it, and importing `theokit/client` does not hard-require
52
+ * `ai` (mirrors how the agent runtime dynamically imports `@theokit/sdk`). An agent app
53
+ * always has `ai` installed (it is the UIMessageStream consumer).
54
+ *
55
+ * `onMessage` is invoked on every reconstruction step with the latest snapshot of the
56
+ * assistant message, so a caller (the `useAgent` hook) can render streaming updates.
57
+ */
58
+ declare function consumeUIMessageStream(response: Response, onMessage: (message: UIMessage) => void): Promise<void>;
59
+ /**
60
+ * M41 (ADR-0050 D3) — the reusable middle piece: a UIMessageStream SSE `Response` →
61
+ * `ReadableStream<UIMessageChunk>`, reusing `ai`'s own `parseJsonEventStream` (the exact primitive
62
+ * `useChat` runs). This is precisely what a `ChatTransport.sendMessages` returns, so `HttpTransport`
63
+ * builds on it directly (no reinvented wire parser — Rule 9). A body-less response yields an empty stream.
64
+ */
65
+ declare function responseToChunkStream(response: Response): Promise<ReadableStream<UIMessageChunk>>;
66
+ /**
67
+ * M41 (ADR-0050 D6) — read a `ReadableStream<UIMessageChunk>` into reconstructed assistant
68
+ * `UIMessage`s via `ai`'s `readUIMessageStream`. Shared by `consumeUIMessageStream` (Response path)
69
+ * and the framework-agnostic `AgentClient` store (transport path). `onMessage` fires on every
70
+ * reconstruction step so a caller can render streaming updates.
71
+ */
72
+ declare function consumeChunkStream(stream: ReadableStream<UIMessageChunk>, onMessage: (message: UIMessage) => void): Promise<void>;
73
+
74
+ /**
75
+ * M41/M42 — extract the turn text from the last user message's text parts. Shared by the transports
76
+ * that hand a plain `message` string to an in-process/push runner (`InProcessTransport`,
77
+ * `ChannelTransport`) rather than POSTing the `messages[]` array (`HttpTransport`). One definition (G12).
78
+ */
79
+ declare function extractLastUserText(messages: readonly UIMessage[]): string;
80
+
81
+ export { AgentTransport, ApprovalDecision, type HeadersResolver, HttpTransport, type HttpTransportOptions, consumeChunkStream, consumeUIMessageStream, extractLastUserText, responseToChunkStream };
package/dist/client.js ADDED
@@ -0,0 +1,26 @@
1
+ import {
2
+ AgentClient,
3
+ ChannelTransport,
4
+ HttpTransport,
5
+ InProcessTransport,
6
+ agentHandle,
7
+ consumeChunkStream,
8
+ consumeUIMessageStream,
9
+ extractLastUserText,
10
+ isAgentHandle,
11
+ responseToChunkStream
12
+ } from "./chunk-M2JFE6IM.js";
13
+ import "./chunk-7QVYU63E.js";
14
+ export {
15
+ AgentClient,
16
+ ChannelTransport,
17
+ HttpTransport,
18
+ InProcessTransport,
19
+ agentHandle,
20
+ consumeChunkStream,
21
+ consumeUIMessageStream,
22
+ extractLastUserText,
23
+ isAgentHandle,
24
+ responseToChunkStream
25
+ };
26
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { G as Guardrail, L as LoopStrategy, R as ReflectionStrategy, C as CompiledAgentOptions, M as MainLoopMeta, a as CompiledTool, b as ReasoningEffort, c as RoundStreamFactory, S as StreamEvent, D as DelegationResult, d as ContextWindowOptions, e as SkillsOptions, T as ToolOptions, A as ApprovalOptions, H as HumanInTheLoopOptions, f as AgentManifestEntry } from './bridge-entry-DMh--RZ5.js';
2
- export { g as AGENT_BRAND, h as AfterToolCallContext, i as AgentBuilder, j as AgentDefinition, k as AgentDefinitionError, l as AgentExecutionContext, m as AgentManifest, n as AgentManifestSource, o as AgentManifestTool, p as AgentOptions, q as AgentRoute, r as AgentRouteContext, s as AgentRunInfo, t as AgentStreamEvent, u as AgentTurnMetadata, v as AgentsPluginOptions, w as ApiErrorContext, x as ApiErrorDecision, y as ApiErrorPolicy, z as ApprovalRequiredEvent, B as ArtifactChunkEvent, E as ArtifactStartEvent, F as BackgroundDelegation, I as BeforeToolCallContext, J as BudgetExceededError, K as BudgetOptions, N as CheckpointSavedEvent, O as CompiledContextWindow, P as ContextualTool, Q as CostBudgetExceededError, U as DEFAULT_MAX_ITERATIONS, V as DefineAgentConfig, W as DelegateFn, X as DelegateOptions, Y as DelegationError, Z as DoneEvent, _ as ErrorEvent, $ as FileEditEvent, a0 as GuardrailAction, a1 as GuardrailPhase, a2 as GuardrailResult, a3 as GuardrailViolationError, a4 as HitlDecision, a5 as HookHandlers, a6 as InferAgentInput, a7 as InferAgentToolNames, a8 as IterationEvent, a9 as LLMCallContext, aa as LoopFinishReason, ab as LoopOutcome, ac as LoopStrategyConfig, ad as MainLoopOptions, ae as McpApprovalSpec, af as McpRegistryConfig, ag as McpRequestContext, ah as McpSelection, ai as PartialToolCallEvent, aj as PolicyHandler, ak as ProcessInputContext, al as ReflectionContext, am as ReflectionResult, an as ReflectionStrategyConfig, ao as RunStartedEvent, ap as ScoreVerdict, aq as ScoredDelegation, ar as Scorer, as as SdkAgentHandle, at as SdkMessage, au as Segment, av as SkillsRequestContext, aw as SkillsSelection, ax as StateUpdateEvent, ay as TextDeltaEvent, az as ThinkingEvent, aA as TimeoutAction, aB as ToolCallEvent, aC as ToolCallVeto, aD as ToolHooks, aE as ToolHooksPlugin, aF as ToolResultEvent, aG as ToolWalkResult, aH as ToolboxOptions, aI as ToolboxWalkResult, aJ as agentsPlugin, aK as buildModelSelection, aL as compileAgentDefinition, aM as compileAgentModule, aN as compileContextWindow, aO as compileProjectContext, aP as compileSkills, aQ as compileTools, aR as createAgentExecutionContext, aS as createApiErrorHandler, aT as createSdkAgentStream, aU as createThinkTagExtractor, aV as createToolHooksPlugin, aW as delegate, aX as delegateBackground, aY as delegateWithScoring, aZ as extractThinkTagStream, a_ as generateAgentManifest, a$ as generateAgentRoutes, b0 as isAgentContext, b1 as isAgentDefinition, b2 as isApprovalRequired, b3 as isDone, b4 as isError, b5 as isPartialToolCall, b6 as isTextDelta, b7 as isToolCall, b8 as isToolResult, b9 as ladderReflectionStrategy, ba as loopStrategyConfigSchema, bb as mcpRegistry, bc as mcpToolApprovals, bd as noopReflectionStrategy, be as presentUIMessageStream, bf as projectContextMetadataOnlyKnobs, bg as reflectionStrategyConfigSchema, bh as resolveEnabledSkills, bi as resolveLoopStrategy, bj as resolveMcpServers, bk as runWithApiErrorHandling, bl as streamAgentResponse, bm as streamAgentUIMessages, bn as toAgentFactory, bo as translateSdkEvent } from './bridge-entry-DMh--RZ5.js';
1
+ import { G as Guardrail, L as LoopStrategy, R as ReflectionStrategy, C as CompiledAgentOptions, M as MainLoopMeta, a as CompiledTool, b as ReasoningEffort, c as RoundStreamFactory, S as StreamEvent, D as DelegationResult, d as ContextWindowOptions, e as SkillsOptions, T as ToolOptions, A as ApprovalOptions, H as HumanInTheLoopOptions, f as AgentManifestEntry, g as HitlDecision, s as streamAgentUIMessages } from './bridge-entry-Cq1aVJ_c.js';
2
+ export { h as AGENT_BRAND, i as AfterToolCallContext, j as AgentBuilder, k as AgentDefinition, l as AgentDefinitionError, m as AgentExecutionContext, n as AgentManifest, o as AgentManifestSource, p as AgentManifestTool, q as AgentOptions, r as AgentRoute, t as AgentRouteContext, u as AgentRunInfo, v as AgentStreamEvent, w as AgentTurnMetadata, x as AgentsPluginOptions, y as ApiErrorContext, z as ApiErrorDecision, B as ApiErrorPolicy, E as ApprovalRequiredEvent, F as ArtifactChunkEvent, I as ArtifactStartEvent, J as BackgroundDelegation, K as BeforeToolCallContext, N as BudgetExceededError, O as BudgetOptions, P as CheckpointSavedEvent, Q as CompiledContextWindow, U as ContextualTool, V as CostBudgetExceededError, W as DEFAULT_MAX_ITERATIONS, X as DefineAgentConfig, Y as DelegateFn, Z as DelegateOptions, _ as DelegationError, $ as DoneEvent, a0 as ErrorEvent, a1 as FileEditEvent, a2 as GuardrailAction, a3 as GuardrailPhase, a4 as GuardrailResult, a5 as GuardrailViolationError, a6 as HookHandlers, a7 as InferAgentInput, a8 as InferAgentToolNames, a9 as IterationEvent, aa as LLMCallContext, ab as LoopFinishReason, ac as LoopOutcome, ad as LoopStrategyConfig, ae as MainLoopOptions, af as McpApprovalSpec, ag as McpRegistryConfig, ah as McpRequestContext, ai as McpSelection, aj as PartialToolCallEvent, ak as PolicyHandler, al as ProcessInputContext, am as ReflectionContext, an as ReflectionResult, ao as ReflectionStrategyConfig, ap as RunStartedEvent, aq as ScoreVerdict, ar as ScoredDelegation, as as Scorer, at as SdkAgentHandle, au as SdkMessage, av as Segment, aw as SkillsRequestContext, ax as SkillsSelection, ay as StateUpdateEvent, az as TextDeltaEvent, aA as ThinkingEvent, aB as TimeoutAction, aC as ToolCallEvent, aD as ToolCallVeto, aE as ToolHooks, aF as ToolHooksPlugin, aG as ToolResultEvent, aH as ToolWalkResult, aI as ToolboxOptions, aJ as ToolboxWalkResult, aK as agentsPlugin, aL as buildModelSelection, aM as compileAgentDefinition, aN as compileAgentModule, aO as compileContextWindow, aP as compileProjectContext, aQ as compileSkills, aR as compileTools, aS as createAgentExecutionContext, aT as createApiErrorHandler, aU as createSdkAgentStream, aV as createThinkTagExtractor, aW as createToolHooksPlugin, aX as delegate, aY as delegateBackground, aZ as delegateWithScoring, a_ as extractThinkTagStream, a$ as generateAgentManifest, b0 as generateAgentRoutes, b1 as isAgentContext, b2 as isAgentDefinition, b3 as isApprovalRequired, b4 as isDone, b5 as isError, b6 as isPartialToolCall, b7 as isTextDelta, b8 as isToolCall, b9 as isToolResult, ba as ladderReflectionStrategy, bb as loopStrategyConfigSchema, bc as mcpRegistry, bd as mcpToolApprovals, be as noopReflectionStrategy, bf as presentUIMessageStream, bg as projectContextMetadataOnlyKnobs, bh as reflectionStrategyConfigSchema, bi as resolveEnabledSkills, bj as resolveLoopStrategy, bk as resolveMcpServers, bl as runWithApiErrorHandling, bm as streamAgentResponse, bn as toAgentFactory, bo as translateSdkEvent } from './bridge-entry-Cq1aVJ_c.js';
3
3
  export * from '@theokit/sdk/errors';
4
4
  export { ConfigurationError } from '@theokit/sdk/errors';
5
5
  import { PluginsSettings, Plugin, ProviderRoutingSettings, AgentDefinition, BudgetTracker, CustomTool, GoalLoopAgent, GoalOptions, runGoalLoop, GoalEvent, GoalResult, InlineSkill } from '@theokit/sdk';
@@ -15,8 +15,8 @@ export * from '@theokit/sdk/concurrency';
15
15
  export * from '@theokit/sdk/messages';
16
16
  export * from '@theokit/sdk/models';
17
17
  export { discoverSubagents, loadSubagentDefinition } from '@theokit/sdk/subagents-loader';
18
+ import { UIMessageChunk } from 'ai';
18
19
  import '@theokit/http';
19
- import 'ai';
20
20
 
21
21
  /**
22
22
  * M9 (theokit-ai-first) — built-in guardrail detectors.
@@ -981,4 +981,73 @@ declare class AcpClient {
981
981
  private handleServerRequest;
982
982
  }
983
983
 
984
- export { type A2AAuth, type A2ACapabilities, type A2ASkill, type A2AToolConfig, AcpClient, AcpMessageDecoder, type AcpTransport, type AgentCard, type AgentConfig, AgentConfigCapability, AgentManifestEntry, AgentRunner, AgentRunnerBuilder, type AgentRunnerRunOptions, ApprovalOptions, type BuildAgentCardOptions, type Capability, CapabilityConflictError, CapabilityPreset, CapabilityRegistry, CheckpointCapability, type CompactionCallOptions, type CompactionStrategyConfig, CompiledAgentOptions, type CompiledAgentOptionsDraft, CompiledTool, ContextWindowCapability, type CostGuardOptions, DEFAULT_KEEP_TOKENS, DelegationResult, FieldCapability, type FinalizedDraft, GoalRunner, type GoalRunnerDeps, Guardrail, GuardrailsCapability, HumanInTheLoopCapability, HumanInTheLoopOptions, LoopStrategy, MCP_PROTOCOL_VERSION, MainLoopCapability, MainLoopMeta, type McpJsonSchema, type McpServerInfo, McpServersCapability, type McpToolDescriptor, MemoryCapability, ModelCapability, type OutputModerationOptions, type PiiOptions, PluginsCapability, ProjectContextCapability, type PromptInjectionOptions, type ProvenanceEntry, ReasoningEffort, ReflectionStrategy, RoundStreamFactory, RunContextCapability, SettingSourcesCapability, SkillsCapability, SkillsOptionsCapability, SkillsResolverCapability, StreamEvent, SubAgentsCapability, type Summarize, type ToolDeclaration, ToolOptions, ToolboxCapability, type ToolboxSource, ToolsCapability, type TranscriptCompactionStrategy, UnknownCapabilityError, applyCapabilities, buildAgentCard, buildMcpToolDescriptors, compactionStrategyConfigSchema, costGuard, createA2ATool, createDraft, deriveConversationId, encodeAcpMessage, estimateTokens, mcpServerInfo, moderateOutputStream, outputModeration, parseConversationId, piiDetector, promptInjectionDetector, resolveCompactionStrategy, runInputGuards, runOutputGuards, setOnce, tokenBudgetCompactionStrategy, unicodeNormalizer, wellKnownCardPath };
984
+ /**
985
+ * M35 (multi-surface) — the in-process agent-turn seam (Model A).
986
+ *
987
+ * The FRAMEWORK-owned sibling of the HTTP `mountAgent` and the stdout `runAgentInTerminal`: it runs a
988
+ * compiled agent with the SAME `compileAgentModule` + SAME `streamAgentUIMessages` (G2 — reuses the
989
+ * SDK runtime, reimplements nothing), but returns the raw `UIMessageChunk` generator so ANY consumer
990
+ * drives it directly — the Ink TUI (M35), a Tauri window (M36), or a test — in a SINGLE process with
991
+ * NO HTTP loopback, NO port, and NO CSRF (there is no network boundary to defend).
992
+ *
993
+ * The ONLY difference from the HTTP mount is HITL resolution: the mount pauses the run and resolves
994
+ * the approval via a SECOND HTTP request to `/approve/:id` (the approval registry). In-process there
995
+ * is no second request — the caller resolves the approval INLINE via `awaitApproval` (e.g. the Ink
996
+ * TUI's y/n prompt). The gated-tool map is `compiled.hitl` verbatim, so the pause semantics are
997
+ * byte-identical to the HTTP path; only the resolver differs. Parity with the mount is by
998
+ * construction: both compile the module, resolve function-form skills, and call `streamAgentUIMessages`
999
+ * with the same `{ message, sessionId, hitl }`.
1000
+ *
1001
+ * Consumers WILL still receive `tool-approval-request` chunks from the returned generator — they are
1002
+ * INFORMATIONAL (render them or ignore them). The authoritative human gate is `awaitApproval`, which
1003
+ * the SDK awaits BEFORE the gated tool runs; the chunk is not the gate.
1004
+ */
1005
+
1006
+ /** An inline approval request handed to the caller's `awaitApproval` (the Ink/Tauri prompt). */
1007
+ interface InProcessApprovalRequest {
1008
+ approvalId: string;
1009
+ toolName: string;
1010
+ opts: HumanInTheLoopOptions;
1011
+ }
1012
+ /** Resolve one gated-tool approval inline (approve/deny, or a structured {@link HitlDecision}). */
1013
+ type InProcessAwaitApproval = (req: InProcessApprovalRequest) => Promise<boolean | HitlDecision>;
1014
+ interface StreamAgentTurnInProcessInput {
1015
+ message: string;
1016
+ /**
1017
+ * M35 (multimodal) — images to send alongside the text. Threaded to the SDK's structured
1018
+ * `SDKUserMessage { text, images }` send form. Absent ⇒ the string send path is byte-unchanged.
1019
+ */
1020
+ images?: Parameters<typeof streamAgentUIMessages>[2]['images'];
1021
+ /** Resume key; a fresh id per run when omitted. */
1022
+ sessionId?: string;
1023
+ /**
1024
+ * Inline HITL resolver — required IFF the agent has `@HumanInTheLoop`-gated tools. Omitting it for a
1025
+ * gated agent is a fail-fast error, never a silent bypass (Rule 8, the #99 lesson).
1026
+ */
1027
+ awaitApproval?: InProcessAwaitApproval;
1028
+ /** Labels a fail-fast `AgentDefinitionError` (the file path). */
1029
+ source?: string;
1030
+ /** Abort signal forwarded to the SDK stream (client disconnect / window close). */
1031
+ signal?: AbortSignal;
1032
+ }
1033
+ /** Injectable stream fn (defaults to the real SDK bridge) — lets tests drive a deterministic stream. */
1034
+ interface StreamAgentTurnDeps {
1035
+ stream: typeof streamAgentUIMessages;
1036
+ }
1037
+ /**
1038
+ * Thrown when a gated agent is run in-process without an `awaitApproval` resolver. Refusing loudly is
1039
+ * the correct posture: silently running a `@HumanInTheLoop`-gated tool with no human gate is exactly
1040
+ * the #99 class of bug. Typed so callers can catch it distinctly.
1041
+ */
1042
+ declare class InProcessApprovalRequiredError extends Error {
1043
+ constructor(toolNames: readonly string[]);
1044
+ }
1045
+ /**
1046
+ * Run a compiled agent in-process and return its `UIMessageChunk` stream. `apiKey` is resolved by the
1047
+ * caller (same contract as the HTTP mount). Validation + compile happen SYNCHRONOUSLY (so a gated
1048
+ * agent without a resolver throws at call time, not lazily on first iteration); the returned value is
1049
+ * the SDK's `streamAgentUIMessages` generator.
1050
+ */
1051
+ declare function streamAgentTurnInProcess(mod: unknown, apiKey: string, input: StreamAgentTurnInProcessInput, deps?: StreamAgentTurnDeps): AsyncGenerator<UIMessageChunk>;
1052
+
1053
+ export { type A2AAuth, type A2ACapabilities, type A2ASkill, type A2AToolConfig, AcpClient, AcpMessageDecoder, type AcpTransport, type AgentCard, type AgentConfig, AgentConfigCapability, AgentManifestEntry, AgentRunner, AgentRunnerBuilder, type AgentRunnerRunOptions, ApprovalOptions, type BuildAgentCardOptions, type Capability, CapabilityConflictError, CapabilityPreset, CapabilityRegistry, CheckpointCapability, type CompactionCallOptions, type CompactionStrategyConfig, CompiledAgentOptions, type CompiledAgentOptionsDraft, CompiledTool, ContextWindowCapability, type CostGuardOptions, DEFAULT_KEEP_TOKENS, DelegationResult, FieldCapability, type FinalizedDraft, GoalRunner, type GoalRunnerDeps, Guardrail, GuardrailsCapability, HitlDecision, HumanInTheLoopCapability, HumanInTheLoopOptions, type InProcessApprovalRequest, InProcessApprovalRequiredError, type InProcessAwaitApproval, LoopStrategy, MCP_PROTOCOL_VERSION, MainLoopCapability, MainLoopMeta, type McpJsonSchema, type McpServerInfo, McpServersCapability, type McpToolDescriptor, MemoryCapability, ModelCapability, type OutputModerationOptions, type PiiOptions, PluginsCapability, ProjectContextCapability, type PromptInjectionOptions, type ProvenanceEntry, ReasoningEffort, ReflectionStrategy, RoundStreamFactory, RunContextCapability, SettingSourcesCapability, SkillsCapability, SkillsOptionsCapability, SkillsResolverCapability, type StreamAgentTurnDeps, type StreamAgentTurnInProcessInput, StreamEvent, SubAgentsCapability, type Summarize, type ToolDeclaration, ToolOptions, ToolboxCapability, type ToolboxSource, ToolsCapability, type TranscriptCompactionStrategy, UnknownCapabilityError, applyCapabilities, buildAgentCard, buildMcpToolDescriptors, compactionStrategyConfigSchema, costGuard, createA2ATool, createDraft, deriveConversationId, encodeAcpMessage, estimateTokens, mcpServerInfo, moderateOutputStream, outputModeration, parseConversationId, piiDetector, promptInjectionDetector, resolveCompactionStrategy, runInputGuards, runOutputGuards, setOnce, streamAgentTurnInProcess, streamAgentUIMessages, tokenBudgetCompactionStrategy, unicodeNormalizer, wellKnownCardPath };
package/dist/index.js CHANGED
@@ -72,7 +72,7 @@ import {
72
72
  toolRuntimeName,
73
73
  translateSdkEvent,
74
74
  unicodeNormalizer
75
- } from "./chunk-IB7I44PO.js";
75
+ } from "./chunk-2L5DI75P.js";
76
76
  import {
77
77
  __name
78
78
  } from "./chunk-7QVYU63E.js";
@@ -873,6 +873,58 @@ export * from "@theokit/sdk/concurrency";
873
873
  export * from "@theokit/sdk/messages";
874
874
  export * from "@theokit/sdk/models";
875
875
  import { discoverSubagents, loadSubagentDefinition } from "@theokit/sdk/subagents-loader";
876
+
877
+ // src/in-process-turn.ts
878
+ var InProcessApprovalRequiredError = class extends Error {
879
+ static {
880
+ __name(this, "InProcessApprovalRequiredError");
881
+ }
882
+ constructor(toolNames) {
883
+ super(`Agent has HITL-gated tool(s) [${toolNames.join(", ")}] but no \`awaitApproval\` resolver was supplied to streamAgentTurnInProcess. In-process runs must resolve approvals inline \u2014 pass awaitApproval, or remove the gate. Refused (fail-closed).`);
884
+ this.name = "InProcessApprovalRequiredError";
885
+ }
886
+ };
887
+ function streamAgentTurnInProcess(mod, apiKey, input, deps = {
888
+ stream: streamAgentUIMessages
889
+ }) {
890
+ const compiled = compileAgentModule(mod, input.source);
891
+ const gated = compiled.hitl;
892
+ if (gated && gated.size > 0 && !input.awaitApproval) {
893
+ throw new InProcessApprovalRequiredError([
894
+ ...gated.keys()
895
+ ]);
896
+ }
897
+ const resolve = input.awaitApproval;
898
+ const hitl = gated && gated.size > 0 && resolve ? {
899
+ gated,
900
+ awaitApproval: /* @__PURE__ */ __name((approvalId, opts, toolName) => resolve({
901
+ approvalId,
902
+ toolName,
903
+ opts
904
+ }), "awaitApproval")
905
+ } : void 0;
906
+ const sessionId = input.sessionId ?? crypto.randomUUID();
907
+ return (async function* () {
908
+ if (compiled.skillsResolver) {
909
+ const enabled = await resolveEnabledSkills(compiled.skillsResolver, compiled.runContext ?? {});
910
+ if (enabled !== void 0) compiled.skills = {
911
+ enabled,
912
+ autoInject: true
913
+ };
914
+ }
915
+ yield* deps.stream(compiled, apiKey, {
916
+ message: input.message,
917
+ // M35 — pass images through so the SDK send uses the structured `{ text, images }` form.
918
+ ...input.images !== void 0 ? {
919
+ images: input.images
920
+ } : {},
921
+ sessionId,
922
+ hitl,
923
+ signal: input.signal
924
+ });
925
+ })();
926
+ }
927
+ __name(streamAgentTurnInProcess, "streamAgentTurnInProcess");
876
928
  export {
877
929
  AGENT_BRAND,
878
930
  AcpClient,
@@ -903,6 +955,7 @@ export {
903
955
  GuardrailViolationError,
904
956
  GuardrailsCapability,
905
957
  HumanInTheLoopCapability,
958
+ InProcessApprovalRequiredError,
906
959
  JudgeCredentialError,
907
960
  MCP_PROTOCOL_VERSION,
908
961
  MainLoopCapability,
@@ -991,6 +1044,7 @@ export {
991
1044
  safePathJoin,
992
1045
  setOnce,
993
1046
  streamAgentResponse,
1047
+ streamAgentTurnInProcess,
994
1048
  streamAgentUIMessages,
995
1049
  toAgentFactory,
996
1050
  tokenBudgetCompactionStrategy,