@mono-agent/agent-runtime 0.15.3 → 0.15.4

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.
Files changed (36) hide show
  1. package/README.md +43 -6
  2. package/package.json +5 -1
  3. package/src/agent/tools/agent-tool.js +859 -0
  4. package/src/agent/tools/bash.js +241 -123
  5. package/src/agent/tools/exec.js +238 -0
  6. package/src/agent/tools/index.js +10 -3
  7. package/src/agent/tools/node-repl.js +231 -95
  8. package/src/agent/tools/pi-bridge.js +115 -24
  9. package/src/agent/tools/shared/process-runner.js +162 -0
  10. package/src/agent/tools/shared/semaphore.js +73 -0
  11. package/src/agent/tools/web-browser-render.js +221 -0
  12. package/src/agent/tools/web-controller.js +160 -0
  13. package/src/agent/tools/web-fetch.js +653 -68
  14. package/src/agent/tools/web-search.js +568 -16
  15. package/src/ai/providers/pi-native/stream-subscriber.js +37 -0
  16. package/src/ai/providers/pi-native/turn-runner.js +60 -5
  17. package/src/ai/providers/pi-native.js +49 -5
  18. package/src/ai/runtime/router.js +302 -166
  19. package/src/ai/types.js +52 -1
  20. package/src/runtime.js +51 -1
  21. package/types/agent/tools/agent-tool.d.ts +60 -0
  22. package/types/agent/tools/bash.d.ts +55 -7
  23. package/types/agent/tools/exec.d.ts +53 -0
  24. package/types/agent/tools/index.d.ts +5 -3
  25. package/types/agent/tools/node-repl.d.ts +28 -3
  26. package/types/agent/tools/pi-bridge.d.ts +6 -2
  27. package/types/agent/tools/shared/process-runner.d.ts +33 -0
  28. package/types/agent/tools/shared/semaphore.d.ts +29 -0
  29. package/types/agent/tools/web-browser-render.d.ts +16 -0
  30. package/types/agent/tools/web-controller.d.ts +20 -0
  31. package/types/agent/tools/web-fetch.d.ts +74 -5
  32. package/types/agent/tools/web-search.d.ts +81 -5
  33. package/types/ai/providers/pi-native/turn-runner.d.ts +34 -2
  34. package/types/ai/providers/pi-native.d.ts +12 -0
  35. package/types/ai/runtime/router.d.ts +23 -3
  36. package/types/ai/types.d.ts +163 -1
package/src/runtime.js CHANGED
@@ -140,7 +140,48 @@ export function createRuntime(host = {}) {
140
140
  // THIS object so later runs of this instance observe the update.
141
141
  const toolContext = createToolContext({ ...toolRuntime, runtimeBrand });
142
142
 
143
- return {
143
+ /** @type {*} */
144
+ let self;
145
+
146
+ /**
147
+ * Kernel fallback for `subagents.run`, so the `Agent` built-in works from a
148
+ * bare `createRuntime` with no host wiring. Hosts replace it to route child
149
+ * turns through their own runtime (fallback chain, retries, recording).
150
+ *
151
+ * Scope of the guarantee, precisely: this fallback rebuilds the child bag with
152
+ * stripped session/steering state, but a HOST-SUPPLIED `run` is installed
153
+ * verbatim and is a privileged seam — it is responsible for its own session
154
+ * isolation. Recursion is blocked independently of the callback: the `Agent`
155
+ * tool stamps `depth + 1` into every descriptor it hands out, and
156
+ * `getPiBuiltinTools` refuses to register the tool at depth >= 1, so a custom
157
+ * callback cannot produce a grandchild even if it ignores the rest.
158
+ * @param {*} request
159
+ */
160
+ const defaultSubagentRun = async (request) => self.run(request.systemPrompt, {
161
+ model: request.model,
162
+ // A child must never be less confined than its parent. The policy is a
163
+ // per-run option, not a host key, so without forwarding it the child would
164
+ // run with no sandbox at all — and its default tools include WebFetch and
165
+ // WebSearch, so even a read-only profile could bypass network policy.
166
+ ...(request.sandboxPolicy === undefined ? {} : { sandboxPolicy: request.sandboxPolicy }),
167
+ ...(request.sandboxEngine === undefined ? {} : { sandboxEngine: request.sandboxEngine }),
168
+ ...(request.executionMode === undefined ? {} : { executionMode: request.executionMode }),
169
+ ...(request.cwd === undefined ? {} : { cwd: request.cwd }),
170
+ // A profile that pins effort — declared or authored at call time — means it
171
+ // on this path too; dropping it would silently run the child at the
172
+ // parent's level while reporting the profile's.
173
+ ...(request.definition?.effort === undefined ? {} : { effort: request.definition.effort }),
174
+ messages: [{ role: "user", content: request.prompt }],
175
+ maxTurns: request.maxTurns,
176
+ allowedTools: request.definition?.allowedTools,
177
+ disallowedTools: request.definition?.disallowedTools,
178
+ mcpServers: request.definition?.mcpServers ?? {},
179
+ abortSignal: request.abortSignal,
180
+ onEvent: request.onEvent,
181
+ subagents: { depth: (request.depth ?? 1) },
182
+ });
183
+
184
+ self = {
144
185
  /**
145
186
  * @param {string} systemPrompt
146
187
  * @param {Partial<RuntimeRunOptions>} [options] Optional only so the
@@ -162,9 +203,16 @@ export function createRuntime(host = {}) {
162
203
  });
163
204
  const liveInput = instrumentLiveInputAppliedEvents(options.liveInput, hub.emit);
164
205
  const prompts = resolvePrompts(host.prompts, options.prompts);
206
+ // Default the nested-run callback so the Agent built-in is usable without
207
+ // host wiring; the depth field is left exactly as the caller set it, since
208
+ // defaultSubagentRun is what increments it for the child.
209
+ const subagents = options.subagents === undefined
210
+ ? undefined
211
+ : { ...options.subagents, run: options.subagents.run ?? defaultSubagentRun };
165
212
  const result = await bridge.execute(systemPrompt, {
166
213
  ...hostDefaults,
167
214
  ...options,
215
+ ...(subagents === undefined ? {} : { subagents }),
168
216
  // `...options` alone doesn't carry the `options.model` narrowing above
169
217
  // (spread reads the parameter's declared — Partial — type); re-assert
170
218
  // the already-validated model so the request satisfies RuntimeRequest.
@@ -204,4 +252,6 @@ export function createRuntime(host = {}) {
204
252
  return disposeAllProviderSessions();
205
253
  },
206
254
  };
255
+
256
+ return self;
207
257
  }
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Build the `Agent` tool, or null when subagents are unavailable for this run.
3
+ *
4
+ * @param {RuntimeSubagentsOptions|null|undefined} subagents
5
+ * @param {{model?: *, executionMode?: string, cwd?: string, parentRunId?: string, sandboxPolicy?: *, sandboxEngine?: *, onEvent?: (event: *) => void}} [context]
6
+ * @returns {*|null}
7
+ */
8
+ export function createAgentTool(subagents: RuntimeSubagentsOptions | null | undefined, context?: {
9
+ model?: any;
10
+ executionMode?: string;
11
+ cwd?: string;
12
+ parentRunId?: string;
13
+ sandboxPolicy?: any;
14
+ sandboxEngine?: any;
15
+ onEvent?: (event: any) => void;
16
+ }): any | null;
17
+ /**
18
+ * A subagent that fails, times out, or says nothing still returns its activity
19
+ * log: that log is the most useful artifact of a failed delegation, and a
20
+ * thrown tool error would discard it.
21
+ *
22
+ * @param {{profileName: string, label?: string, outcome: {status: string, answer: string, reason?: string}, durationMs: number, activity: ReadonlyArray<{name: string, args: unknown, ms?: number, isError: boolean}>, maxBytes?: number, cwd?: string, notice?: string}} input
23
+ * @returns {string}
24
+ */
25
+ export function formatSubagentResult({ profileName, label, outcome, durationMs, activity, maxBytes, cwd, notice }: {
26
+ profileName: string;
27
+ label?: string;
28
+ outcome: {
29
+ status: string;
30
+ answer: string;
31
+ reason?: string;
32
+ };
33
+ durationMs: number;
34
+ activity: ReadonlyArray<{
35
+ name: string;
36
+ args: unknown;
37
+ ms?: number;
38
+ isError: boolean;
39
+ }>;
40
+ maxBytes?: number;
41
+ cwd?: string;
42
+ notice?: string;
43
+ }): string;
44
+ /** @typedef {import('../../ai/types.js').RuntimeSubagentDefinition} RuntimeSubagentDefinition */
45
+ /** @typedef {import('../../ai/types.js').RuntimeSubagentsOptions} RuntimeSubagentsOptions */
46
+ export const GENERAL_PURPOSE_SUBAGENT: "general-purpose";
47
+ /**
48
+ * Read-only by default. A profile that needs a shell or writes must say so in
49
+ * config: widening a subagent's reach is an operator decision, not one the
50
+ * model makes at call time.
51
+ */
52
+ export const DEFAULT_SUBAGENT_TOOLS: readonly string[];
53
+ /**
54
+ * Never available to a subagent, whatever a profile asks for. `Agent` is the
55
+ * third independent recursion lock; the rest would let a helper hijack the
56
+ * user's conversation or post to a channel on the main agent's behalf.
57
+ */
58
+ export const SUBAGENT_HARD_DENY: readonly string[];
59
+ export type RuntimeSubagentDefinition = import("../../ai/types.js").RuntimeSubagentDefinition;
60
+ export type RuntimeSubagentsOptions = import("../../ai/types.js").RuntimeSubagentsOptions;
@@ -1,16 +1,64 @@
1
- export function normalizeBashTimeoutMs(value: any, fallback?: number): number;
2
1
  /**
3
- * @param {{command: string, timeout?: number, max_output_chars?: number, workdir?: string}} params
4
- * @param {{signal?: any, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any}} [options]
2
+ * Legacy Bash timeout normalization. Values up to 600 are seconds; larger
3
+ * values are milliseconds. New callers should use `timeout_ms`.
5
4
  */
6
- export function bashToolImpl({ command, timeout, max_output_chars, workdir }: {
5
+ export function normalizeBashTimeoutMs(value: any, fallback?: number): any;
6
+ /**
7
+ * Exact millisecond timeout used by Bash.timeout_ms and Exec.timeout_ms.
8
+ */
9
+ export function normalizeProcessTimeoutMs(value: any, fallback?: number): any;
10
+ /**
11
+ * Compatibility wrapper retained for direct callers and tests.
12
+ *
13
+ * @param {{command: string, timeout?: number, timeout_ms?: number, max_output_chars?: number, workdir?: string}} params
14
+ * @param {{signal?: AbortSignal, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any}} [options]
15
+ */
16
+ export function bashToolImpl(params: {
17
+ command: string;
18
+ timeout?: number;
19
+ timeout_ms?: number;
20
+ max_output_chars?: number;
21
+ workdir?: string;
22
+ }, options?: {
23
+ signal?: AbortSignal;
24
+ sandboxPolicy?: any;
25
+ sandboxEngine?: any;
26
+ ctx?: any;
27
+ }): Promise<any>;
28
+ /**
29
+ * Structured Bash execution used by the Pi bridge.
30
+ *
31
+ * @param {{command: string, timeout?: number, timeout_ms?: number, max_output_chars?: number, workdir?: string}} params
32
+ * @param {{signal?: AbortSignal, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any}} [options]
33
+ */
34
+ export function bashToolRun({ command, timeout, timeout_ms, max_output_chars, workdir, }: {
7
35
  command: string;
8
36
  timeout?: number;
37
+ timeout_ms?: number;
9
38
  max_output_chars?: number;
10
39
  workdir?: string;
11
- }, { signal, sandboxPolicy, sandboxEngine, ctx }?: {
12
- signal?: any;
40
+ }, { signal, sandboxPolicy, sandboxEngine, ctx, }?: {
41
+ signal?: AbortSignal;
13
42
  sandboxPolicy?: any;
14
43
  sandboxEngine?: any;
15
44
  ctx?: any;
16
- }): Promise<string>;
45
+ }): Promise<{
46
+ text: any;
47
+ outcome: {
48
+ status: string;
49
+ code: any;
50
+ retryable: boolean;
51
+ attempts: number;
52
+ durationMs: number;
53
+ bytes: number;
54
+ truncated: boolean;
55
+ exitCode: any;
56
+ signal: any;
57
+ timedOut: boolean;
58
+ };
59
+ error: boolean;
60
+ } | {
61
+ text: string;
62
+ outcome: any;
63
+ error: boolean;
64
+ }>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @param {{executable: string, args?: string[], workdir?: string, timeout_ms?: number, max_output_chars?: number}} params
3
+ * @param {{signal?: AbortSignal, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any}} [options]
4
+ */
5
+ export function execToolImpl(params: {
6
+ executable: string;
7
+ args?: string[];
8
+ workdir?: string;
9
+ timeout_ms?: number;
10
+ max_output_chars?: number;
11
+ }, options?: {
12
+ signal?: AbortSignal;
13
+ sandboxPolicy?: any;
14
+ sandboxEngine?: any;
15
+ ctx?: any;
16
+ }): Promise<any>;
17
+ /**
18
+ * Execute an argv vector directly, without shell parsing.
19
+ *
20
+ * @param {{executable: string, args?: string[], workdir?: string, timeout_ms?: number, max_output_chars?: number}} params
21
+ * @param {{signal?: AbortSignal, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any}} [options]
22
+ */
23
+ export function execToolRun({ executable, args, workdir, timeout_ms, max_output_chars, }: {
24
+ executable: string;
25
+ args?: string[];
26
+ workdir?: string;
27
+ timeout_ms?: number;
28
+ max_output_chars?: number;
29
+ }, { signal, sandboxPolicy, sandboxEngine, ctx, }?: {
30
+ signal?: AbortSignal;
31
+ sandboxPolicy?: any;
32
+ sandboxEngine?: any;
33
+ ctx?: any;
34
+ }): Promise<{
35
+ text: any;
36
+ outcome: {
37
+ status: string;
38
+ code: any;
39
+ retryable: boolean;
40
+ attempts: number;
41
+ durationMs: number;
42
+ bytes: number;
43
+ truncated: boolean;
44
+ exitCode: any;
45
+ signal: any;
46
+ timedOut: boolean;
47
+ };
48
+ error: boolean;
49
+ } | {
50
+ text: string;
51
+ outcome: any;
52
+ error: any;
53
+ }>;
@@ -3,8 +3,10 @@ export { writeToolImpl } from "./write.js";
3
3
  export { editToolImpl } from "./edit.js";
4
4
  export { globToolImpl } from "./glob.js";
5
5
  export { grepToolImpl } from "./grep.js";
6
- export { webFetchToolImpl } from "./web-fetch.js";
7
- export { webSearchToolImpl } from "./web-search.js";
6
+ export { createWebToolController } from "./web-controller.js";
8
7
  export { resolveRgPath } from "./shared/ripgrep.js";
9
- export { bashToolImpl, normalizeBashTimeoutMs } from "./bash.js";
8
+ export { bashToolImpl, bashToolRun, normalizeBashTimeoutMs, normalizeProcessTimeoutMs } from "./bash.js";
9
+ export { execToolImpl, execToolRun } from "./exec.js";
10
+ export { webFetchToolImpl, performWebFetch } from "./web-fetch.js";
11
+ export { webSearchToolImpl, performWebSearch } from "./web-search.js";
10
12
  export { isPathAllowed, isWorkdirAllowed } from "./shared/path-resolver.js";
@@ -9,11 +9,36 @@ export function createNodeReplController({ cwd, maxOutputChars, sandboxPolicy, s
9
9
  sandboxEngine?: any;
10
10
  ctx?: any;
11
11
  }): {
12
- /** @param {{code: string}} params @param {{signal?: AbortSignal}} [execution] */
13
- execute({ code }: {
12
+ execute: ({ code }: {
14
13
  code: string;
15
14
  }, { signal }?: {
16
15
  signal?: AbortSignal;
17
- }): Promise<any>;
16
+ }) => Promise<any>;
17
+ /** Structured result used by the Pi bridge so telemetry does not depend on text prefixes. */
18
+ executeDetailed(params: any, execution?: {}): Promise<{
19
+ text: any;
20
+ outcome: {
21
+ status: string;
22
+ code: string;
23
+ retryable: boolean;
24
+ attempts: number;
25
+ durationMs: number;
26
+ bytes: number;
27
+ truncated: boolean;
28
+ };
29
+ error: boolean;
30
+ } | {
31
+ text: string;
32
+ outcome: {
33
+ status: string;
34
+ code: any;
35
+ retryable: boolean;
36
+ attempts: number;
37
+ durationMs: number;
38
+ bytes: number;
39
+ truncated: boolean;
40
+ };
41
+ error: boolean;
42
+ }>;
18
43
  close(): Promise<void>;
19
44
  };
@@ -35,9 +35,9 @@ export function createStructuredOutputTool(outputSchema: any, onStructuredOutput
35
35
  };
36
36
  /**
37
37
  * @param {any} allowedTools
38
- * @param {{disallowedTools?: any[], skillNames?: any[], skills?: any[], skillsRoot?: any, dataDir?: any, cwd?: any, onEvent?: (event: any) => void, toolLimits?: any, persistArtifact?: any, onTruncate?: any, toolPayloadMaxBytes?: number, imageInlineMaxBytes?: any, toolPolicy?: any, sandboxPolicy?: any, sandboxEngine?: any, approvalManager?: any, approvalModel?: any, nodeReplController?: any, ctx?: any}} [options]
38
+ * @param {{disallowedTools?: any[], skillNames?: any[], skills?: any[], skillsRoot?: any, dataDir?: any, cwd?: any, onEvent?: (event: any) => void, toolLimits?: any, persistArtifact?: any, onTruncate?: any, toolPayloadMaxBytes?: number, imageInlineMaxBytes?: any, toolPolicy?: any, sandboxPolicy?: any, sandboxEngine?: any, approvalManager?: any, approvalModel?: any, nodeReplController?: any, webController?: any, toolExecutionMode?: "sequential"|"safe-parallel", subagents?: any, subagentContext?: any, ctx?: any}} [options]
39
39
  */
40
- export function getPiBuiltinTools(allowedTools: any, { disallowedTools, skillNames, skills, skillsRoot, dataDir, cwd, onEvent, toolLimits, persistArtifact, onTruncate, toolPayloadMaxBytes, imageInlineMaxBytes, toolPolicy, sandboxPolicy, sandboxEngine, approvalManager, approvalModel, nodeReplController, ctx, }?: {
40
+ export function getPiBuiltinTools(allowedTools: any, { disallowedTools, skillNames, skills, skillsRoot, dataDir, cwd, onEvent, toolLimits, persistArtifact, onTruncate, toolPayloadMaxBytes, imageInlineMaxBytes, toolPolicy, sandboxPolicy, sandboxEngine, approvalManager, approvalModel, nodeReplController, webController, subagents, subagentContext, toolExecutionMode, ctx, }?: {
41
41
  disallowedTools?: any[];
42
42
  skillNames?: any[];
43
43
  skills?: any[];
@@ -56,6 +56,10 @@ export function getPiBuiltinTools(allowedTools: any, { disallowedTools, skillNam
56
56
  approvalManager?: any;
57
57
  approvalModel?: any;
58
58
  nodeReplController?: any;
59
+ webController?: any;
60
+ toolExecutionMode?: "sequential" | "safe-parallel";
61
+ subagents?: any;
62
+ subagentContext?: any;
59
63
  ctx?: any;
60
64
  }): any[];
61
65
  export function resolveMcpStdioCwd(cfg?: {}, cwd?: any): any;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Run one already-prepared executable without adding a shell.
3
+ *
4
+ * The result is deliberately loss-aware: stdout/stderr are retained up to the
5
+ * shared byte cap even when the child times out, is aborted, exits by signal,
6
+ * or exceeds that cap.
7
+ *
8
+ * @param {{command: string, args?: string[], cwd?: string, env?: Record<string, string|undefined>}} commandSpec
9
+ * @param {{timeoutMs?: number, signal?: AbortSignal, maxBufferBytes?: number}} [options]
10
+ */
11
+ export function runPreparedProcess(commandSpec: {
12
+ command: string;
13
+ args?: string[];
14
+ cwd?: string;
15
+ env?: Record<string, string | undefined>;
16
+ }, { timeoutMs, signal, maxBufferBytes, }?: {
17
+ timeoutMs?: number;
18
+ signal?: AbortSignal;
19
+ maxBufferBytes?: number;
20
+ }): Promise<any>;
21
+ /**
22
+ * @param {import("node:child_process").ChildProcess} child
23
+ * @param {NodeJS.Signals} signal
24
+ */
25
+ export function killProcessGroup(child: import("node:child_process").ChildProcess, signal: NodeJS.Signals): void;
26
+ /**
27
+ * @param {{stdout?: string, stderr?: string}} result
28
+ */
29
+ export function combinedProcessOutput(result: {
30
+ stdout?: string;
31
+ stderr?: string;
32
+ }): string;
33
+ export const DEFAULT_PROCESS_BUFFER_BYTES: number;
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @typedef {Object} CountingSemaphore
3
+ * @property {(signal?: AbortSignal) => Promise<() => void>} acquire Resolves with
4
+ * a single-use release function once a slot is free. Rejects if `signal`
5
+ * aborts while queued; an already-acquired slot is never leaked.
6
+ * @property {() => number} inFlight Slots currently held.
7
+ * @property {() => number} queued Waiters not yet admitted.
8
+ */
9
+ /**
10
+ * @param {number} limit Maximum simultaneous holders. Values below 1 are clamped.
11
+ * @returns {CountingSemaphore}
12
+ */
13
+ export function createCountingSemaphore(limit: number): CountingSemaphore;
14
+ export type CountingSemaphore = {
15
+ /**
16
+ * Resolves with
17
+ * a single-use release function once a slot is free. Rejects if `signal`
18
+ * aborts while queued; an already-acquired slot is never leaked.
19
+ */
20
+ acquire: (signal?: AbortSignal) => Promise<() => void>;
21
+ /**
22
+ * Slots currently held.
23
+ */
24
+ inFlight: () => number;
25
+ /**
26
+ * Waiters not yet admitted.
27
+ */
28
+ queued: () => number;
29
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Render one public page in a fresh anonymous agent-browser session.
3
+ *
4
+ * @param {string} url
5
+ * @param {{browserCommand?: string, namespace?: string, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any, signal?: AbortSignal, registerCleanup?: (cleanup: () => Promise<void>) => () => void}} [options]
6
+ */
7
+ export function renderWithAgentBrowser(url: string, { browserCommand, namespace, sandboxPolicy, sandboxEngine, ctx, signal, registerCleanup, }?: {
8
+ browserCommand?: string;
9
+ namespace?: string;
10
+ sandboxPolicy?: any;
11
+ sandboxEngine?: any;
12
+ ctx?: any;
13
+ signal?: AbortSignal;
14
+ registerCleanup?: (cleanup: () => Promise<void>) => () => void;
15
+ }): Promise<any>;
16
+ export function extractBrowserText(output: any): any;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * One ephemeral web-tool controller for one model run. It owns in-memory
3
+ * deduplication, result caches, anonymous browser namespaces, and cleanup.
4
+ *
5
+ * @param {{searchConfig?: any, fetchConfig?: any, sandboxPolicy?: any, sandboxEngine?: any, ctx?: any, fetchImpl?: typeof fetch, browserRenderer?: any}} [options]
6
+ */
7
+ export function createWebToolController({ searchConfig, fetchConfig, sandboxPolicy, sandboxEngine, ctx, fetchImpl, browserRenderer, }?: {
8
+ searchConfig?: any;
9
+ fetchConfig?: any;
10
+ sandboxPolicy?: any;
11
+ sandboxEngine?: any;
12
+ ctx?: any;
13
+ fetchImpl?: typeof fetch;
14
+ browserRenderer?: any;
15
+ }): {
16
+ namespace: string;
17
+ search(params: any, execution?: {}): Promise<any>;
18
+ fetch(params: any, execution?: {}): Promise<any>;
19
+ close(): Promise<void>;
20
+ };
@@ -1,13 +1,82 @@
1
1
  /**
2
- * @param {{url: string, headers?: Record<string, string>, max_output_chars?: number}} params
3
- * @param {{sandboxPolicy?: any, ctx?: any, retryDelaysMs?: number[]}} [options]
2
+ * Compatibility wrapper for direct callers.
3
+ *
4
+ * @param {{url: string, headers?: Record<string, string>, max_output_chars?: number, format?: string, render?: string}} params
5
+ * @param {{sandboxPolicy?: any, sandboxEngine?: any, ctx?: any, signal?: AbortSignal, retryDelaysMs?: number[], fetchConfig?: any, fetchImpl?: typeof fetch, browserRenderer?: typeof renderWithAgentBrowser, namespace?: string, registerCleanup?: (cleanup: () => Promise<void>) => () => void}} [options]
4
6
  */
5
- export function webFetchToolImpl({ url, headers, max_output_chars }: {
7
+ export function webFetchToolImpl(params: {
6
8
  url: string;
7
9
  headers?: Record<string, string>;
8
10
  max_output_chars?: number;
9
- }, { sandboxPolicy, ctx, retryDelaysMs }?: {
11
+ format?: string;
12
+ render?: string;
13
+ }, options?: {
10
14
  sandboxPolicy?: any;
15
+ sandboxEngine?: any;
11
16
  ctx?: any;
17
+ signal?: AbortSignal;
12
18
  retryDelaysMs?: number[];
13
- }): Promise<string>;
19
+ fetchConfig?: any;
20
+ fetchImpl?: typeof fetch;
21
+ browserRenderer?: typeof renderWithAgentBrowser;
22
+ namespace?: string;
23
+ registerCleanup?: (cleanup: () => Promise<void>) => () => void;
24
+ }): Promise<any>;
25
+ /**
26
+ * Fetch and locally extract one public URL.
27
+ *
28
+ * @param {{url: string, headers?: Record<string, string>, max_output_chars?: number, format?: string, render?: string}} params
29
+ * @param {{sandboxPolicy?: any, sandboxEngine?: any, ctx?: any, signal?: AbortSignal, retryDelaysMs?: number[], fetchConfig?: any, fetchImpl?: typeof fetch, browserRenderer?: typeof renderWithAgentBrowser, namespace?: string, registerCleanup?: (cleanup: () => Promise<void>) => () => void}} [options]
30
+ */
31
+ export function performWebFetch({ url, headers, max_output_chars, format, render, }: {
32
+ url: string;
33
+ headers?: Record<string, string>;
34
+ max_output_chars?: number;
35
+ format?: string;
36
+ render?: string;
37
+ }, { sandboxPolicy, sandboxEngine, ctx, signal, retryDelaysMs, fetchConfig, fetchImpl, browserRenderer, namespace, registerCleanup, }?: {
38
+ sandboxPolicy?: any;
39
+ sandboxEngine?: any;
40
+ ctx?: any;
41
+ signal?: AbortSignal;
42
+ retryDelaysMs?: number[];
43
+ fetchConfig?: any;
44
+ fetchImpl?: typeof fetch;
45
+ browserRenderer?: typeof renderWithAgentBrowser;
46
+ namespace?: string;
47
+ registerCleanup?: (cleanup: () => Promise<void>) => () => void;
48
+ }): Promise<{
49
+ text: any;
50
+ outcome: {
51
+ status: string;
52
+ code: any;
53
+ retryable: boolean;
54
+ attempts: number;
55
+ backend: string;
56
+ cacheHit: boolean;
57
+ durationMs: number;
58
+ bytes: number;
59
+ truncated: boolean;
60
+ };
61
+ error: boolean;
62
+ } | {
63
+ text: string;
64
+ outcome: {
65
+ status: string;
66
+ code: string;
67
+ retryable: boolean;
68
+ attempts: number;
69
+ backend: string;
70
+ cacheHit: boolean;
71
+ durationMs: number;
72
+ bytes: number;
73
+ truncated: boolean;
74
+ statusCode: any;
75
+ redirectCount: number;
76
+ rendered: boolean;
77
+ renderFailed: boolean;
78
+ contentKind: string;
79
+ };
80
+ error: boolean;
81
+ }>;
82
+ import { renderWithAgentBrowser } from "./web-browser-render.js";
@@ -1,11 +1,87 @@
1
1
  /**
2
- * @param {{query: string, limit?: number}} params
3
- * @param {{sandboxPolicy?: any, ctx?: any}} [options]
2
+ * Compatibility wrapper for direct callers.
3
+ *
4
+ * @param {{query: string, limit?: number, alternate_queries?: string[], domains?: string[], exclude_domains?: string[], language?: string, time_range?: string}} params
5
+ * @param {{sandboxPolicy?: any, ctx?: any, signal?: AbortSignal, searchConfig?: any, fetchImpl?: typeof fetch}} [options]
4
6
  */
5
- export function webSearchToolImpl({ query, limit }: {
7
+ export function webSearchToolImpl(params: {
6
8
  query: string;
7
9
  limit?: number;
8
- }, { sandboxPolicy, ctx }?: {
10
+ alternate_queries?: string[];
11
+ domains?: string[];
12
+ exclude_domains?: string[];
13
+ language?: string;
14
+ time_range?: string;
15
+ }, options?: {
9
16
  sandboxPolicy?: any;
10
17
  ctx?: any;
11
- }): Promise<string>;
18
+ signal?: AbortSignal;
19
+ searchConfig?: any;
20
+ fetchImpl?: typeof fetch;
21
+ }): Promise<any>;
22
+ /**
23
+ * Search through an operator-owned SearXNG endpoint and/or the keyless HTML
24
+ * fallback chain. Returns a structured internal outcome for the Pi bridge.
25
+ *
26
+ * @param {{query: string, limit?: number, alternate_queries?: string[], domains?: string[], exclude_domains?: string[], language?: string, time_range?: string}} params
27
+ * @param {{sandboxPolicy?: any, ctx?: any, signal?: AbortSignal, searchConfig?: any, fetchImpl?: typeof fetch}} [options]
28
+ */
29
+ export function performWebSearch({ query, limit, alternate_queries, domains, exclude_domains, language, time_range, }: {
30
+ query: string;
31
+ limit?: number;
32
+ alternate_queries?: string[];
33
+ domains?: string[];
34
+ exclude_domains?: string[];
35
+ language?: string;
36
+ time_range?: string;
37
+ }, { sandboxPolicy, ctx, signal, searchConfig, fetchImpl, }?: {
38
+ sandboxPolicy?: any;
39
+ ctx?: any;
40
+ signal?: AbortSignal;
41
+ searchConfig?: any;
42
+ fetchImpl?: typeof fetch;
43
+ }): Promise<{
44
+ text: any;
45
+ outcome: {
46
+ status: string;
47
+ code: any;
48
+ retryable: boolean;
49
+ attempts: number;
50
+ backend: string;
51
+ cacheHit: boolean;
52
+ durationMs: number;
53
+ bytes: number;
54
+ truncated: boolean;
55
+ };
56
+ error: boolean;
57
+ } | {
58
+ text: string;
59
+ outcome: {
60
+ status: string;
61
+ code: string;
62
+ retryable: boolean;
63
+ attempts: number;
64
+ backend: any;
65
+ cacheHit: boolean;
66
+ durationMs: number;
67
+ bytes: number;
68
+ truncated: boolean;
69
+ resultCount: number;
70
+ providerFailureCount: number;
71
+ };
72
+ error: boolean;
73
+ }>;
74
+ export function parseDuckDuckGoResults(html: any): {
75
+ title: string;
76
+ url: string;
77
+ snippet: string;
78
+ backend: string;
79
+ }[];
80
+ export function parseStartpageResults(html: any): {
81
+ title: string;
82
+ url: string;
83
+ snippet: string;
84
+ backend: string;
85
+ }[];
86
+ export function canonicalizeSearchUrl(value: any, base: any): string;
87
+ export function mergeRankedResults(rankedLists: any, limit?: number): any[];