@prismshadow/penguin-core 0.0.1

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,487 @@
1
+ import { O as OmniMessage, S as StopReason, T as ToolDefinition, a as ToolCallPayload, A as ApprovalDecision } from './types-D6FERSdT.js';
2
+
3
+ /** Foreground process exit info. At most one of `code`/`signal` is set (consistent with Node child's exit event). */
4
+ interface ProcessExit {
5
+ code: number | null;
6
+ signal: NodeJS.Signals | null;
7
+ }
8
+ /** Arguments required to start a command. */
9
+ interface SpawnOptions {
10
+ /** Command string handed to `bash -lc`. */
11
+ cmd: string;
12
+ /** Working directory (absolute path). */
13
+ cwd: string;
14
+ /** Child process environment variables (the caller has already injected hardening entries like PAGER/TERM). */
15
+ env: NodeJS.ProcessEnv;
16
+ }
17
+ declare class ManagedSession {
18
+ /** Timestamp of the last access (used for LRU / idle reaping). */
19
+ lastUsed: number;
20
+ private readonly child;
21
+ private readonly buffer;
22
+ private exited;
23
+ private exitInfo;
24
+ private spawnError;
25
+ private killed;
26
+ private killTimer;
27
+ private readonly wakeSignal;
28
+ constructor(opts: SpawnOptions);
29
+ /** Signals the process group; ignores the case where the process/group has already exited (ESRCH). */
30
+ private signalGroup;
31
+ private handleData;
32
+ private handleExit;
33
+ private handleError;
34
+ /** Whether the command is still running (hasn't exited, spawn hasn't failed). */
35
+ get running(): boolean;
36
+ get exit(): ProcessExit | null;
37
+ get error(): Error | null;
38
+ /**
39
+ * Streams output deltas within `yieldMs` (data is yielded as soon as it arrives). Once done,
40
+ * the terminal state is determined via `running`/`exit`/`error`:
41
+ * - Exits mid-window -> the trailing output is yielded along with it (extra ≤POST_EXIT_DRAIN_MS drain);
42
+ * - Still running once the window expires -> whatever output exists is yielded and collection ends, with the process switching to background;
43
+ * - `signal` aborts -> whatever output exists is yielded and collection ends immediately (the process isn't killed; the caller decides whether to keep it).
44
+ */
45
+ collect(yieldMs: number, signal?: AbortSignal): AsyncGenerator<string>;
46
+ write(chars: string): void;
47
+ interrupt(): void;
48
+ /** Closes out: sends SIGTERM to the process group, then SIGKILL after a grace period (reaping leftover background child processes); idempotent. */
49
+ kill(): void;
50
+ /** Synchronous hard kill (process 'exit' fallback: the event loop has already stopped at this point, so timers aren't available). */
51
+ killHard(): void;
52
+ }
53
+
54
+ /**
55
+ * CommandSessionManager — registry and lifecycle management for long-running command sessions.
56
+ *
57
+ * Constructed by Environment (one per Session), injected via services and shared by the
58
+ * `exec_command` and `input_command` tools. Registry responsibilities (id allocation, concurrency
59
+ * cap, dispose, process 'exit' fallback) are handled by the generic `BackgroundRegistry` (shared
60
+ * with subagent sessions, see `../background/registry.ts`); this class only retains
61
+ * command-domain logic: spawning processes and assembling the child process environment (vault
62
+ * injection + hardening).
63
+ * Docs: /docs/tools § "Background session caps".
64
+ */
65
+
66
+ declare class CommandSessionManager {
67
+ private readonly registry;
68
+ /** Agent vault environment variables: injected into the child process on every spawn (values never enter the model context, only the environment). */
69
+ private readonly vault;
70
+ constructor(opts?: {
71
+ vault?: Record<string, string>;
72
+ });
73
+ /** Starts a command, returning an **unregistered** session (no process_id yet). */
74
+ spawn(opts: {
75
+ cmd: string;
76
+ cwd: string;
77
+ }): ManagedSession;
78
+ /** Registers a still-running session as a background process, allocating and returning a unique `process_id`. */
79
+ register(session: ManagedSession): string;
80
+ /** Looks up a session by process_id and refreshes its access time; returns undefined if it doesn't exist. */
81
+ get(processId: string): ManagedSession | undefined;
82
+ /** Removes from the registry and cleans up the process group (called after the session exits). */
83
+ remove(processId: string): void;
84
+ /** Disposes: removes the fallback registration and kills all sessions (the process 'exit' fallback is hooked up by the registry itself). Idempotent. */
85
+ dispose(): void;
86
+ }
87
+
88
+ /**
89
+ * ManagedSubagentSession — a subagent session capable of running in the background.
90
+ *
91
+ * Holds a `SubagentHandle` and drives its `run` (pump): the same child Session may run across
92
+ * multiple rounds (the first round is initiated by `run_subagent`, later rounds append a Prompt
93
+ * via `input_subagent`). Structurally mirrors a command session (ManagedSession): the parent tool
94
+ * call collects output live within the yield window; output produced outside the window (while
95
+ * running in the background) goes into a buffer, delivered all at once on the next access.
96
+ *
97
+ * Three kinds of output, each with its own destination:
98
+ * - **Message buffer**: all of the child session's OmniMessage (already tagged with origin), for
99
+ * the parent tool call to forward to the frontend for rendering; capped in count, overflow
100
+ * drops the oldest (only affects frontend replay — the child Session's own Trace loses no
101
+ * data);
102
+ * - **Text buffer**: assistant text deltas from the direct child layer (origin one hop), fed back
103
+ * as the parent tool's own output to the LLM; capped in capacity (prevents memory bloat),
104
+ * overflow drops the oldest with a marker;
105
+ * - **Approval queue**: the child session's tool approval requests. While running in the
106
+ * background, the parent session may have no active tool call to forward approval through, so
107
+ * the request is queued and the child session blocks waiting; the parent tool call
108
+ * (run_subagent / input_subagent) attaches an approval sink (`attachApprovalSink`) within its
109
+ * window to consult Human one request at a time — if detached mid-consultation (window ends),
110
+ * the request stays queued, and a late-arriving decision still takes effect (settled guard,
111
+ * first to arrive wins).
112
+ *
113
+ * Cleanup: `kill()` aborts the current run via AbortSignal, denies all pending approvals, and
114
+ * releases child Session resources; idempotent. The child Session runs in-process, so there's no
115
+ * need for a separate synchronous hard-kill path (its command sessions are reaped by their own
116
+ * exit fallback); `killHard` is equivalent to `kill`.
117
+ */
118
+
119
+ /** Terminal state of one run. */
120
+ interface SubagentExit {
121
+ status: "completed" | "failed";
122
+ note?: string;
123
+ }
124
+ declare class ManagedSubagentSession {
125
+ /** Timestamp of the last access (used for the eviction policy). */
126
+ lastUsed: number;
127
+ private readonly handle;
128
+ private readonly abortCtrl;
129
+ private messages;
130
+ private readonly textBuffer;
131
+ private isRunning;
132
+ private exitInfo;
133
+ private killed;
134
+ private readonly approvals;
135
+ private sink;
136
+ private sinkEpoch;
137
+ private pumpingApprovals;
138
+ private readonly wakeSignal;
139
+ constructor(handle: SubagentHandle);
140
+ /** Child Session id (one hop of a message's origin); `subagent_id` is derived from its tail so the frontend can correlate it. */
141
+ get sessionId(): string;
142
+ /** Whether a round of the task is currently running. */
143
+ get running(): boolean;
144
+ /** Terminal state of the most recent run; null if no round has ever completed. */
145
+ get exit(): SubagentExit | null;
146
+ /** Number of pending approval requests (the parent tool uses this to hint the model to poll again). */
147
+ get pendingApprovals(): number;
148
+ /** Whether there's unread output (buffered messages or text); used to re-check the predicate before waiting (see collect.ts). */
149
+ get hasPending(): boolean;
150
+ /**
151
+ * Starts a new round of the task on the child Session (async pump, doesn't block the caller).
152
+ * Throws if already disposed or still running (converted to an explanatory output by the
153
+ * caller).
154
+ */
155
+ startRun(prompt: string): void;
156
+ /** Takes the buffered child-session messages (already tagged with origin, for the parent tool to forward). */
157
+ drainMessages(): OmniMessage[];
158
+ /** Takes the currently unread child Agent text (including the drop marker); clears the buffer. */
159
+ drainText(): string;
160
+ /** External wakeup (e.g. the parent tool call was aborted): makes a waiting `waitWake` return immediately. */
161
+ wakeup(): void;
162
+ /** Waits for "woken up" or `ms` to expire, whichever comes first. */
163
+ waitWake(ms: number): Promise<void>;
164
+ /**
165
+ * Attaches an approval sink: the parent tool call active within the window hands in its own
166
+ * `ctx.approve`, and queued approval requests are consulted with Human through it one at a
167
+ * time. Returns a detach function (called when the window ends); a later attach replaces the
168
+ * former one.
169
+ */
170
+ attachApprovalSink(approve: ApproveFn): () => void;
171
+ /** Cleanup: aborts the current run, denies pending approvals, releases child Session resources; idempotent. */
172
+ kill(): void;
173
+ /** Synchronous hard-kill path: the child Session runs in-process with no separate OS resources, so this is equivalent to `kill`. */
174
+ killHard(): void;
175
+ /** Drives one round of `handle.run`: buffers messages and text, settling the terminal state when it ends. */
176
+ private pump;
177
+ private bufferMessage;
178
+ private appendText;
179
+ /** Approval callback handed to the child Session: the request is queued and waits for some parent tool call to consult Human and give a decision. */
180
+ private readonly childApprove;
181
+ /** Settles an approval decision: first to arrive wins, late/duplicate decisions are ignored. */
182
+ private settle;
183
+ /**
184
+ * Hands the request at the head of the queue to the currently attached approval sink, one at a
185
+ * time. Stops when the window ends (the sink is detached); unresolved requests stay queued for
186
+ * the next sink; if a consultation already in flight resolves late, the decision still takes
187
+ * effect via settle.
188
+ */
189
+ private pumpApprovals;
190
+ }
191
+
192
+ declare class SubagentSessionManager {
193
+ private readonly registry;
194
+ /** Whether the manager has been disposed (the host Session has ended). */
195
+ get isDisposed(): boolean;
196
+ /** Whether there's still room for a new background session (evicting a completed, idle one if needed; never evicts a running one). */
197
+ makeRoom(): boolean;
198
+ /**
199
+ * Registers a still-running session as a background session, allocating and returning a
200
+ * unique `subagent_id`: `subagent-<last 8 hex of child Session id>` (falls back to random on
201
+ * collision), whose suffix aligns with the message origin/frontend nesting label
202
+ * (`agent-<last 3 chars>`) for correlation.
203
+ */
204
+ register(session: ManagedSubagentSession): string;
205
+ /** Looks up a session by subagent_id and refreshes its access time; returns undefined if not found. */
206
+ get(subagentId: string): ManagedSubagentSession | undefined;
207
+ /** Disposes: removes the fallback registration and finalizes all sessions (the process 'exit' fallback is hooked by the registry itself). Idempotent. */
208
+ dispose(): void;
209
+ }
210
+
211
+ /**
212
+ * Session-level uniqueness for tool_call_id.
213
+ *
214
+ * Some providers don't produce a real call id: e.g. Gemini's functionCall has no id, so AgentHub
215
+ * uses the **function name** as the `tool_call_id` — consecutive/parallel calls to the same tool then
216
+ * all share one id. But the OmniMessage world (engine dispatch/pairing, approval routing, frontend
217
+ * tool-card attribution) keys on `tool_call_id`, and a collision lets a later call overwrite the
218
+ * earlier one (parallel same-name calls in one turn can even be dropped entirely).
219
+ *
220
+ * Approach: inbound, `EventTranslator` disambiguates duplicate ids with a `#n` suffix (the first keeps
221
+ * the original id); outbound (returning tool_result, replaying history on resume) uses
222
+ * `stripToolCallIdSuffix` to strip the suffix and restore the original — Gemini's functionResponse
223
+ * pairs by using `tool_call_id` as the name, so it must be restored to the function name. The registry
224
+ * lives at Session level (the new GenerativeModel rebuilt on compaction shares the same instance), and
225
+ * on resume `setHistory` seeds it with historical ids, so the uniqueness scope covers the entire
226
+ * context the frontend renders.
227
+ * Docs: /docs/interfaces § "The built-in implementation: GenerativeModel".
228
+ */
229
+ declare class ToolCallIdAllocator {
230
+ /** OmniMessage-level tool_call_ids already taken in this Session (history-seeded + allocated). */
231
+ private used;
232
+ /** Register an already-used id (for resume seeding); registering twice is harmless. */
233
+ markUsed(id: string): void;
234
+ /**
235
+ * Allocate a Session-unique id for a provider-reported tool_call_id: if unused, keep the original;
236
+ * if already used (a repeat call from a name-as-id provider), take the first free `origId#n` (n from 2).
237
+ * Providers with truly unique ids (OpenAI `call_*` / Claude `toolu_*`) never collide, so they pass through unchanged.
238
+ */
239
+ allocate(providerId: string): string;
240
+ }
241
+ /**
242
+ * Strip the `#n` suffix added by `allocate`, restoring the provider's original id (returns as-is when
243
+ * there's no suffix; idempotent). On resume there's no registry to compare against, so it trims by
244
+ * shape: real ids from known providers (OpenAI/Claude `call_*`/`toolu_*`, Gemini function names — `#`
245
+ * isn't a valid function-name char) never end in `#<digits>`, so they aren't harmed.
246
+ */
247
+ declare function stripToolCallIdSuffix(id: string): string;
248
+
249
+ /**
250
+ * Internal SDK interface contracts: LLM, Environment.
251
+ *
252
+ * `context_engine` only handles OmniMessage; protocol conversion and concrete implementations
253
+ * are each interface's own responsibility.
254
+ * Human is not an "interface/class with methods" but the SDK's input/output boundary itself:
255
+ * output is streamed by `Session.run()` as an async generator, and input is delivered via
256
+ * `run`'s `RunOptions` — approvals are requested one at a time through the injected `approve`
257
+ * callback, and interruption goes through `signal`. Hence no Human interface is defined here.
258
+ *
259
+ * These types form the foundational contract shared by all units; implementing units integrate
260
+ * against them.
261
+ *
262
+ * Docs: packages/docs/content/interfaces.{zh,en}.md (site path /docs/interfaces) explains each
263
+ * contract and its extension seams — keep the page in sync when changing signatures here.
264
+ */
265
+
266
+ /** Tool permission: read-only / read-write. */
267
+ type ToolPermission = "r" | "rw";
268
+ /**
269
+ * Runtime configuration for a single tool.
270
+ * Docs: /docs/tools § "Configuration fields".
271
+ */
272
+ interface ToolDefinitionConfig {
273
+ name: string;
274
+ description: string;
275
+ parameters?: Record<string, unknown>;
276
+ permission?: ToolPermission;
277
+ /**
278
+ * Which class of session model this entry targets: `"vision"` only for models that support
279
+ * images (e.g. read_image), `"text-only"` only for text-only models (e.g. describe_image);
280
+ * omitted means available for all models. Filtered by session model at assembly time
281
+ * (see `selectBuiltinToolsForModel`).
282
+ */
283
+ forModel?: "vision" | "text-only";
284
+ /** Timeout for a single tool call (ms); on timeout, ends as `failed`; <=0 disables it. */
285
+ timeoutMs?: number;
286
+ /** Max length of tool output; Environment truncates from the front (keeping the head) if exceeded; <=0 disables it. */
287
+ maxOutputLength?: number;
288
+ }
289
+ interface MCPServerConfig {
290
+ name: string;
291
+ config: Record<string, unknown>;
292
+ }
293
+ /** Set of tool configs required to initialize Environment. */
294
+ interface ToolConfig {
295
+ customTools: ToolDefinitionConfig[];
296
+ mcpServers: MCPServerConfig[];
297
+ }
298
+ /**
299
+ * Per-tool approval callback: the Human boundary gives allow/deny for each complete `tool_call`.
300
+ * `context_engine` calls it once per tool call within a turn. Subagents forward the parent's
301
+ * approval callback, so the child Agent **inherits the parent Agent's approval mode**.
302
+ * Docs: /docs/interfaces § "ApproveFn".
303
+ */
304
+ type ApproveFn = (toolCall: OmniMessage<ToolCallPayload>) => Promise<ApprovalDecision>;
305
+ type ThinkingLevelName = "none" | "low" | "medium" | "high" | "xhigh";
306
+ /**
307
+ * GenerativeModel initialization config.
308
+ * Docs: /docs/interfaces § "GenerativeModelConfig".
309
+ */
310
+ interface GenerativeModelConfig {
311
+ modelId: string;
312
+ apiKey?: string;
313
+ baseUrl?: string;
314
+ /**
315
+ * AgentHub client protocol (`openai` / `claude-4-8` / `deepseek-v4` / …). If omitted, AgentHub
316
+ * infers it from `modelId`; custom-named models or third-party models using the OpenAI protocol
317
+ * must specify it explicitly.
318
+ */
319
+ clientType?: string;
320
+ tools: ToolDefinition[];
321
+ /** Full system Prompt after placeholder substitution in the system_config.system_prompt template. */
322
+ systemPrompt?: string;
323
+ contextWindow?: number;
324
+ maxTokens?: number;
325
+ thinkingLevel?: ThinkingLevelName;
326
+ /** LLM Request timeout (ms): from system_config.model.timeoutMs; <=0 disables it. Defaults to 120000. */
327
+ requestTimeoutMs?: number;
328
+ /**
329
+ * tool_call_id uniqueness registry (Session-level). Pass the same instance when rebuilding a new
330
+ * GenerativeModel on compaction so the uniqueness scope covers the whole Session; defaults to a fresh
331
+ * one. See llm/tool-call-ids.ts.
332
+ */
333
+ toolCallIds?: ToolCallIdAllocator;
334
+ }
335
+ interface GenerativeModelParameters {
336
+ /** OmniMessage array for the input newly added this turn; implementations must merge it into a single UniMessage (multiple roles not accepted). */
337
+ newMessages: OmniMessage[];
338
+ signal?: AbortSignal;
339
+ }
340
+ /**
341
+ * The terminal state of an LLM request, returned as the **return value** of the `streamGenerate`
342
+ * async generator (not a yielded message). The status values share the same five-value protocol
343
+ * as OmniMessage `stop_reason`:
344
+ * - `completed`: finished normally (already produced `token_usage`);
345
+ * - `timeout`: LLM timed out or lost connection, needs reconnect — retried by `context_engine`
346
+ * within the same run;
347
+ * - `malformed`: AgentHub response failed JSON parsing, needs reconnect — also retried by
348
+ * `context_engine`;
349
+ * - `aborted`: user-initiated interruption — stop and hand back to the user;
350
+ * - `failed`: other non-retryable errors (auth/params, etc.) — stop and hand back to the user
351
+ * (`message` provides the display text).
352
+ * Docs: /docs/interfaces § "LLMOutcome semantics".
353
+ */
354
+ interface LLMOutcome {
355
+ status: StopReason;
356
+ message?: string;
357
+ }
358
+ /**
359
+ * A stateful LLM object attached to a Session.
360
+ * `streamGenerate` yields streaming `partial_*` messages as an async generator, and appends the
361
+ * corresponding complete `model_msg` once each fragment ends; Token usage is emitted as a
362
+ * `token_usage` event_msg. **Never throws to `context_engine`**: any interruption/exception is
363
+ * closed off in well-formed structure and returned normally, and **must** report the terminal
364
+ * state via `LLMOutcome` — error handling happens entirely inside the LLM interface, and
365
+ * `context_engine` only decides subsequent actions based on the outcome.
366
+ * Docs: /docs/interfaces § "LLMInterface".
367
+ */
368
+ interface LLMInterface {
369
+ streamGenerate(parameters: GenerativeModelParameters): AsyncGenerator<OmniMessage, LLMOutcome>;
370
+ }
371
+ /**
372
+ * Handle for a child Agent session: derived by `SubagentRunner.spawn`,
373
+ * representing a child Session that can run over multiple turns. Deriving (spawn) is separate
374
+ * from running (run), so the same child Session can accept an additional Prompt and keep running
375
+ * after a turn ends (a long-running subagent, accessed via `input_subagent`).
376
+ * Docs: /docs/interfaces § "Subagent interfaces".
377
+ */
378
+ interface SubagentHandle {
379
+ /** The child Session's id: the origin hop of messages produced by run; `subagent_id` is derived from its tail for the frontend to correlate. */
380
+ sessionId: string;
381
+ /**
382
+ * Runs one turn of a task on the child Session. Emitted child-session messages **all already
383
+ * carry the origin marker** (the child Session id); the first message of the first run is the
384
+ * child Session's `session_meta`, and tool_calls received by the forwarded approval callback
385
+ * carry origin as well.
386
+ */
387
+ run(input: {
388
+ /** The task Prompt handed to the child Agent. */
389
+ prompt: string;
390
+ signal?: AbortSignal;
391
+ /** The parent Agent's approval callback; forwarded to the child Session to inherit the parent's approval mode. */
392
+ approve?: ApproveFn;
393
+ }): AsyncGenerator<OmniMessage>;
394
+ /** Releases runtime resources held by the child Session (e.g. its managed command sessions). Idempotent. */
395
+ dispose(): void;
396
+ }
397
+ /**
398
+ * Child Agent runner: injected into the `run_subagent` tool so it can
399
+ * derive and run a child Agent without a reverse dependency on Agent/Session, avoiding circular
400
+ * dependencies. The concrete implementation is provided by the SDK composition layer (where
401
+ * `createAgent` lives), which internally derives via `createAgent` → `createSession` and hands
402
+ * back a `SubagentHandle`.
403
+ * Docs: /docs/interfaces § "Subagent interfaces".
404
+ */
405
+ interface SubagentRunner {
406
+ /**
407
+ * Derives a child Agent and creates a child Session. Precheck errors such as exceeding the
408
+ * depth limit or a nonexistent target agent are expressed by throwing (collapsed to `failed`
409
+ * by Environment).
410
+ */
411
+ spawn(input: {
412
+ /** The child Agent's agentId; if omitted, reuses the current Agent (self-invocation). */
413
+ agentId?: string;
414
+ /** The Model used by the child Session; if omitted, uses the Project's default Model. */
415
+ modelId?: string;
416
+ }): Promise<SubagentHandle>;
417
+ }
418
+ /**
419
+ * Proxy-reading service for describe_image: injected when the session model doesn't support
420
+ * images (vision=false) — images are handed to the configured vision model for description and
421
+ * the tool returns text, avoiding a 400 from feeding images back into a tool_result for a
422
+ * provider that doesn't support images.
423
+ * Docs: /docs/interfaces § "VisionDescriberService".
424
+ */
425
+ interface VisionDescriberService {
426
+ /** Vision model id; null when the Project has no `vision_model` configured (or it's invalid), in which case the tool ends with a failed explanation. */
427
+ modelId: string | null;
428
+ /** Constructs a single-shot LLM for this vision model (no tools, no system prompt); omitted when `modelId` is null. */
429
+ createLLM?: () => LLMInterface;
430
+ }
431
+ /**
432
+ * Runtime services Environment injects into individual tools (e.g. `run_subagent` needs `SubagentRunner`); most tools don't use these.
433
+ * Docs: /docs/interfaces § "ToolExecutionRequest and EnvironmentConfig".
434
+ */
435
+ interface EnvironmentServices {
436
+ subagentRunner?: SubagentRunner;
437
+ /** Injected when the session model doesn't support images: for describe_image's single-shot vision-model proxy reading. */
438
+ visionDescriber?: VisionDescriberService;
439
+ /** Registry of long-running command sessions (shared by `exec_command` / `input_command`); constructed and injected internally by Environment. */
440
+ commandSessions?: CommandSessionManager;
441
+ /** Registry of background subagent sessions (shared by `run_subagent` / `input_subagent`); constructed and injected internally by Environment. */
442
+ subagentSessions?: SubagentSessionManager;
443
+ }
444
+ /** Docs: /docs/interfaces § "ToolExecutionRequest and EnvironmentConfig". */
445
+ interface EnvironmentConfig {
446
+ workspaceDir: string;
447
+ toolConfig: ToolConfig;
448
+ /** Runtime services (optional); Environment forwards these to each tool factory to use as needed. */
449
+ services?: EnvironmentServices;
450
+ /**
451
+ * Agent vault environment variables (key-value pairs, taken from the Agent's
452
+ * `agent_state/.vault.toml`): injected into the exec_command / input_command subprocess
453
+ * environment; hardened entries cannot be overridden.
454
+ */
455
+ vault?: Record<string, string>;
456
+ }
457
+ /**
458
+ * An approved tool-call execution request.
459
+ * Docs: /docs/interfaces § "ToolExecutionRequest and EnvironmentConfig".
460
+ */
461
+ interface ToolExecutionRequest {
462
+ /** The OmniMessage whose payload.type === "tool_call". */
463
+ toolCall: OmniMessage<ToolCallPayload>;
464
+ signal?: AbortSignal;
465
+ /** The parent Agent's approval callback; forwarded to tools that need to derive a child Session (run_subagent), implementing approval inheritance. */
466
+ approve?: ApproveFn;
467
+ }
468
+ /**
469
+ * Environment interface: executes approved tool calls within the Workspace.
470
+ * `executeTool` yields `partial_tool_call_output` as an async generator and ends with exactly one
471
+ * complete `tool_call_output`; nested session messages carrying an origin marker (e.g. forwarded
472
+ * by run_subagent) pass through unchanged.
473
+ *
474
+ * **Rendering** of tool calls is not this interface's concern (nor core's): streaming rendering is
475
+ * handled by the CLI / Web frontend itself.
476
+ * Docs: /docs/interfaces § "EnvironmentInterface".
477
+ */
478
+ interface EnvironmentInterface {
479
+ listTools(): Promise<ToolDefinition[]>;
480
+ executeTool(request: ToolExecutionRequest): AsyncGenerator<OmniMessage>;
481
+ /** Looks up a tool's permission level (for frontend permission-mode decisions); returns undefined for unknown tools. */
482
+ toolPermission(name: string): ToolPermission | undefined;
483
+ /** Releases runtime resources held by the environment (e.g. managed long-running command sessions); called by the host when the Session ends. Optional, idempotent. */
484
+ dispose?(): void;
485
+ }
486
+
487
+ export { type ApproveFn as A, CommandSessionManager as C, type EnvironmentInterface as E, type GenerativeModelConfig as G, type LLMInterface as L, type MCPServerConfig as M, type ProcessExit as P, type SpawnOptions as S, type ToolDefinitionConfig as T, type VisionDescriberService as V, type ThinkingLevelName as a, type ToolConfig as b, ToolCallIdAllocator as c, type GenerativeModelParameters as d, type LLMOutcome as e, type EnvironmentConfig as f, type ToolPermission as g, type ToolExecutionRequest as h, type EnvironmentServices as i, ManagedSession as j, ManagedSubagentSession as k, type SubagentHandle as l, type SubagentRunner as m, SubagentSessionManager as n, stripToolCallIdSuffix as s };
@@ -0,0 +1,2 @@
1
+ export { T as ToolDefinition } from './types-D6FERSdT.js';
2
+ export { A as ApproveFn, f as EnvironmentConfig, E as EnvironmentInterface, i as EnvironmentServices, G as GenerativeModelConfig, d as GenerativeModelParameters, L as LLMInterface, e as LLMOutcome, M as MCPServerConfig, l as SubagentHandle, m as SubagentRunner, a as ThinkingLevelName, b as ToolConfig, T as ToolDefinitionConfig, h as ToolExecutionRequest, g as ToolPermission, V as VisionDescriberService } from './interfaces-CMSN7-pO.js';
@@ -0,0 +1,2 @@
1
+ import "./chunk-HRIXWKKE.js";
2
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}