@intentface/latch-core 0.9.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.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/dist/agent.d.ts +200 -0
  4. package/dist/agent.d.ts.map +1 -0
  5. package/dist/agent.js +9 -0
  6. package/dist/agent.js.map +1 -0
  7. package/dist/compaction.d.ts +33 -0
  8. package/dist/compaction.d.ts.map +1 -0
  9. package/dist/compaction.js +104 -0
  10. package/dist/compaction.js.map +1 -0
  11. package/dist/connections.d.ts +16 -0
  12. package/dist/connections.d.ts.map +1 -0
  13. package/dist/connections.js +41 -0
  14. package/dist/connections.js.map +1 -0
  15. package/dist/context.d.ts +41 -0
  16. package/dist/context.d.ts.map +1 -0
  17. package/dist/context.js +25 -0
  18. package/dist/context.js.map +1 -0
  19. package/dist/current-date.d.ts +12 -0
  20. package/dist/current-date.d.ts.map +1 -0
  21. package/dist/current-date.js +25 -0
  22. package/dist/current-date.js.map +1 -0
  23. package/dist/extensions.d.ts +333 -0
  24. package/dist/extensions.d.ts.map +1 -0
  25. package/dist/extensions.js +569 -0
  26. package/dist/extensions.js.map +1 -0
  27. package/dist/harness/index.d.ts +17 -0
  28. package/dist/harness/index.d.ts.map +1 -0
  29. package/dist/harness/index.js +15 -0
  30. package/dist/harness/index.js.map +1 -0
  31. package/dist/harness/tools.d.ts +88 -0
  32. package/dist/harness/tools.d.ts.map +1 -0
  33. package/dist/harness/tools.js +296 -0
  34. package/dist/harness/tools.js.map +1 -0
  35. package/dist/harness/web-fetch.d.ts +47 -0
  36. package/dist/harness/web-fetch.d.ts.map +1 -0
  37. package/dist/harness/web-fetch.js +247 -0
  38. package/dist/harness/web-fetch.js.map +1 -0
  39. package/dist/index.d.ts +25 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +25 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/limits.d.ts +152 -0
  44. package/dist/limits.d.ts.map +1 -0
  45. package/dist/limits.js +97 -0
  46. package/dist/limits.js.map +1 -0
  47. package/dist/memory.d.ts +93 -0
  48. package/dist/memory.d.ts.map +1 -0
  49. package/dist/memory.js +13 -0
  50. package/dist/memory.js.map +1 -0
  51. package/dist/message.d.ts +46 -0
  52. package/dist/message.d.ts.map +1 -0
  53. package/dist/message.js +2 -0
  54. package/dist/message.js.map +1 -0
  55. package/dist/models/catalog.d.ts +56 -0
  56. package/dist/models/catalog.d.ts.map +1 -0
  57. package/dist/models/catalog.js +211 -0
  58. package/dist/models/catalog.js.map +1 -0
  59. package/dist/models/defaults.d.ts +23 -0
  60. package/dist/models/defaults.d.ts.map +1 -0
  61. package/dist/models/defaults.js +19 -0
  62. package/dist/models/defaults.js.map +1 -0
  63. package/dist/models/index.d.ts +23 -0
  64. package/dist/models/index.d.ts.map +1 -0
  65. package/dist/models/index.js +19 -0
  66. package/dist/models/index.js.map +1 -0
  67. package/dist/models/prompt-caching.d.ts +19 -0
  68. package/dist/models/prompt-caching.d.ts.map +1 -0
  69. package/dist/models/prompt-caching.js +18 -0
  70. package/dist/models/prompt-caching.js.map +1 -0
  71. package/dist/models/provider.d.ts +19 -0
  72. package/dist/models/provider.d.ts.map +1 -0
  73. package/dist/models/provider.js +22 -0
  74. package/dist/models/provider.js.map +1 -0
  75. package/dist/models/reasoning.d.ts +21 -0
  76. package/dist/models/reasoning.d.ts.map +1 -0
  77. package/dist/models/reasoning.js +59 -0
  78. package/dist/models/reasoning.js.map +1 -0
  79. package/dist/pricing.d.ts +52 -0
  80. package/dist/pricing.d.ts.map +1 -0
  81. package/dist/pricing.js +37 -0
  82. package/dist/pricing.js.map +1 -0
  83. package/dist/principal.d.ts +37 -0
  84. package/dist/principal.d.ts.map +1 -0
  85. package/dist/principal.js +30 -0
  86. package/dist/principal.js.map +1 -0
  87. package/dist/projections.d.ts +37 -0
  88. package/dist/projections.d.ts.map +1 -0
  89. package/dist/projections.js +128 -0
  90. package/dist/projections.js.map +1 -0
  91. package/dist/prompt-caching.d.ts +106 -0
  92. package/dist/prompt-caching.d.ts.map +1 -0
  93. package/dist/prompt-caching.js +165 -0
  94. package/dist/prompt-caching.js.map +1 -0
  95. package/dist/runtime.d.ts +670 -0
  96. package/dist/runtime.d.ts.map +1 -0
  97. package/dist/runtime.js +2425 -0
  98. package/dist/runtime.js.map +1 -0
  99. package/dist/scheduler.d.ts +31 -0
  100. package/dist/scheduler.d.ts.map +1 -0
  101. package/dist/scheduler.js +43 -0
  102. package/dist/scheduler.js.map +1 -0
  103. package/dist/storage.d.ts +389 -0
  104. package/dist/storage.d.ts.map +1 -0
  105. package/dist/storage.js +38 -0
  106. package/dist/storage.js.map +1 -0
  107. package/dist/telemetry.d.ts +155 -0
  108. package/dist/telemetry.d.ts.map +1 -0
  109. package/dist/telemetry.js +2 -0
  110. package/dist/telemetry.js.map +1 -0
  111. package/dist/vault-node.d.ts +20 -0
  112. package/dist/vault-node.d.ts.map +1 -0
  113. package/dist/vault-node.js +30 -0
  114. package/dist/vault-node.js.map +1 -0
  115. package/dist/vault.d.ts +62 -0
  116. package/dist/vault.d.ts.map +1 -0
  117. package/dist/vault.js +88 -0
  118. package/dist/vault.js.map +1 -0
  119. package/package.json +95 -0
@@ -0,0 +1,88 @@
1
+ import type { Tool } from "ai";
2
+ import type { Runtime } from "../runtime.js";
3
+ /**
4
+ * The default harness tools — what every host used to copy from the platform:
5
+ *
6
+ * - sandbox: `bash` / `read_file` / `write_file` / `glob` / `grep`, thin
7
+ * wrappers over the AI SDK's `Experimental_SandboxSession` (read from
8
+ * `options.experimental_sandbox`, resolved per turn by `RuntimeConfig.sandbox`).
9
+ * - app: `web_fetch` (clean markdown/text, images/PDFs as viewable media,
10
+ * SSRF-gated, DNS-pinned), `askUser` (client-handled pause for a
11
+ * multiple-choice question), `list_schedules` / `cancel_schedule` (over the
12
+ * runtime the turn is running in — every tool receives it as
13
+ * `options.context.runtime`).
14
+ *
15
+ * `web_fetch` is the only tool with dependencies beyond `ai`: `turndown` and
16
+ * `@intentface/latch-net` are OPTIONAL peers of core, imported lazily on first
17
+ * call, so a host that never grants `web_fetch` never loads them.
18
+ */
19
+ /** The model-facing tool-result shape (`ai` doesn't re-export it directly). */
20
+ type ToolResultOutput = Awaited<ReturnType<NonNullable<Tool["toModelOutput"]>>>;
21
+ /**
22
+ * What the runtime puts on `options.context` for every tool (see
23
+ * `buildTurn`'s toolsContext): the host's runtime context, the principal, the
24
+ * run, the writer — and the runtime itself.
25
+ */
26
+ export interface HarnessToolContext<P = unknown> {
27
+ principal: P;
28
+ run?: {
29
+ id: string;
30
+ chatId: string;
31
+ agent: string;
32
+ };
33
+ runtime?: Runtime<P>;
34
+ }
35
+ export declare const harnessContextOf: <P = unknown>(o: unknown) => HarnessToolContext<P>;
36
+ /** Keep the tail of long output (errors/results usually land at the end). */
37
+ export declare function tail(text: string, maxLines?: number, maxBytes?: number): {
38
+ text: string;
39
+ truncated: boolean;
40
+ };
41
+ /** web_fetch's stored output — text page, fetched media, or an error. */
42
+ export type WebFetchToolOutput = {
43
+ ok: true;
44
+ kind?: "text";
45
+ status: number;
46
+ contentType: string;
47
+ body: string;
48
+ truncated: boolean;
49
+ } | {
50
+ ok: true;
51
+ kind: "media";
52
+ status: number;
53
+ contentType: string;
54
+ mediaType: string;
55
+ /** Base64 bytes — surfaced to the model as an image/document block. */
56
+ data: string;
57
+ bytes: number;
58
+ url: string;
59
+ } | {
60
+ ok: false;
61
+ error: string;
62
+ };
63
+ /**
64
+ * What the model sees of a web_fetch result. Media becomes a real file block —
65
+ * an image the model can look at, a PDF Anthropic renders as a document — with
66
+ * a text line alongside so providers that can't take media in tool results
67
+ * still leave the model oriented instead of staring at a silently-emptied
68
+ * result. Text results keep the default JSON view.
69
+ */
70
+ export declare function webFetchToModelOutput({ output }: {
71
+ output: unknown;
72
+ }): ToolResultOutput;
73
+ /** Sandbox-backed tools (need an agent with `sandbox: true`). */
74
+ export declare const sandboxTools: Record<string, unknown>;
75
+ /** App-process default tools (granted by `defaultTools`; no sandbox needed). */
76
+ export declare const appTools: Record<string, unknown>;
77
+ /**
78
+ * The `RuntimeConfig.harnessTools` bundle: sandbox + app tools, no default
79
+ * approval gates (nothing here persists a side effect the user hasn't asked
80
+ * for in the turn). Spread a host's own additions over `app` / `approval`.
81
+ */
82
+ export declare function defaultHarnessTools(): {
83
+ sandbox: Record<string, unknown>;
84
+ app: Record<string, unknown>;
85
+ approval: Record<string, unknown>;
86
+ };
87
+ export {};
88
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/harness/tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAA+B,IAAI,EAAE,MAAM,IAAI,CAAC;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C;;;;;;;;;;;;;;;GAeG;AAEH,+EAA+E;AAC/E,KAAK,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;AAUhF;;;;GAIG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,GAAG,OAAO;IAC7C,SAAS,EAAE,CAAC,CAAC;IACb,GAAG,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CACtB;AACD,eAAO,MAAM,gBAAgB,GAAI,CAAC,GAAG,OAAO,EAAE,GAAG,OAAO,KAAG,kBAAkB,CAAC,CAAC,CACM,CAAC;AAKtF,6EAA6E;AAC7E,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAM,EAAE,QAAQ,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAa1G;AAyGD,yEAAyE;AACzE,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAClG;IACE,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AASjC;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,GAAG,gBAAgB,CAYvF;AA8JD,iEAAiE;AACjE,eAAO,MAAM,YAAY,EAAkD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACnG,gFAAgF;AAChF,eAAO,MAAM,QAAQ,EAA8D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3G;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI;IACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC,CAEA"}
@@ -0,0 +1,296 @@
1
+ import { tool, jsonSchema } from "ai";
2
+ const sandboxOf = (o) => {
3
+ const s = o.experimental_sandbox;
4
+ if (!s)
5
+ throw new Error("No sandbox available for this turn.");
6
+ return s;
7
+ };
8
+ export const harnessContextOf = (o) => o.context ?? {};
9
+ /** Single-quote a value for safe interpolation into a shell command. */
10
+ const q = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
11
+ /** Keep the tail of long output (errors/results usually land at the end). */
12
+ export function tail(text, maxLines = 400, maxBytes = 20_000) {
13
+ let out = text;
14
+ let truncated = false;
15
+ const lines = out.split("\n");
16
+ if (lines.length > maxLines) {
17
+ out = lines.slice(-maxLines).join("\n");
18
+ truncated = true;
19
+ }
20
+ if (Buffer.byteLength(out) > maxBytes) {
21
+ out = out.slice(-maxBytes);
22
+ truncated = true;
23
+ }
24
+ return { text: out, truncated };
25
+ }
26
+ // ── Sandbox tools ───────────────────────────────────────────────────────────
27
+ const bash = tool({
28
+ description: "Run a shell command in the sandbox workspace (cwd /workspace). Use for " +
29
+ "listing, moving, inspecting, and combining files with pipes. Depending " +
30
+ "on the sandbox backend, the root may also hold READ-ONLY mounts of " +
31
+ "connected services — run `ls /` to discover them and browse with " +
32
+ "ls/cat/grep. Output is tail-truncated if very long.",
33
+ inputSchema: jsonSchema({
34
+ type: "object",
35
+ properties: { command: { type: "string", description: "Shell command to run." } },
36
+ required: ["command"],
37
+ additionalProperties: false,
38
+ }),
39
+ execute: async ({ command }, options) => {
40
+ const r = await sandboxOf(options).run({ command });
41
+ const so = tail(r.stdout);
42
+ const se = tail(r.stderr);
43
+ return { exitCode: r.exitCode, stdout: so.text, stderr: se.text, truncated: so.truncated || se.truncated };
44
+ },
45
+ });
46
+ const read_file = tool({
47
+ description: "Read a text file from the sandbox, returned with 1-based line numbers. " +
48
+ "Optionally restrict to a line range. Read before you write.",
49
+ inputSchema: jsonSchema({
50
+ type: "object",
51
+ properties: {
52
+ path: { type: "string" },
53
+ start_line: { type: "number", description: "1-based inclusive start line." },
54
+ end_line: { type: "number", description: "1-based inclusive end line." },
55
+ },
56
+ required: ["path"],
57
+ additionalProperties: false,
58
+ }),
59
+ execute: async ({ path, start_line, end_line }, options) => {
60
+ const text = await sandboxOf(options).readTextFile({ path, startLine: start_line, endLine: end_line });
61
+ if (text == null)
62
+ return { found: false };
63
+ const start = start_line ?? 1;
64
+ const numbered = text
65
+ .split("\n")
66
+ .map((l, i) => `${start + i}\t${l}`)
67
+ .join("\n");
68
+ return { found: true, content: numbered };
69
+ },
70
+ });
71
+ const write_file = tool({
72
+ description: "Write a complete file to the sandbox (overwrites; creates parent dirs). " +
73
+ "Prefer reading the file first when editing an existing one.",
74
+ inputSchema: jsonSchema({
75
+ type: "object",
76
+ properties: { path: { type: "string" }, content: { type: "string" } },
77
+ required: ["path", "content"],
78
+ additionalProperties: false,
79
+ }),
80
+ execute: async ({ path, content }, options) => {
81
+ await sandboxOf(options).writeTextFile({ path, content });
82
+ return { ok: true, bytes: Buffer.byteLength(content) };
83
+ },
84
+ });
85
+ const glob = tool({
86
+ description: "Find files by name pattern (recursively from a directory, default the " +
87
+ "workspace root). Pattern matches the file name, e.g. '*.ts'.",
88
+ inputSchema: jsonSchema({
89
+ type: "object",
90
+ properties: { pattern: { type: "string" }, path: { type: "string" } },
91
+ required: ["pattern"],
92
+ additionalProperties: false,
93
+ }),
94
+ execute: async ({ pattern, path }, options) => {
95
+ const r = await sandboxOf(options).run({ command: `find ${q(path ?? ".")} -type f -name ${q(pattern)}` });
96
+ const files = r.stdout.split("\n").map((s) => s.trim()).filter(Boolean);
97
+ return { files: files.slice(0, 500), truncated: files.length > 500 };
98
+ },
99
+ });
100
+ const grep = tool({
101
+ description: "Search file contents by regex in the sandbox (ripgrep), returning " +
102
+ "file:line:match. Searches the workspace root by default.",
103
+ inputSchema: jsonSchema({
104
+ type: "object",
105
+ properties: { pattern: { type: "string" }, path: { type: "string" } },
106
+ required: ["pattern"],
107
+ additionalProperties: false,
108
+ }),
109
+ execute: async ({ pattern, path }, options) => {
110
+ // Plain `rg <pattern> <path>` already emits file:line:match.
111
+ const r = await sandboxOf(options).run({ command: `rg ${q(pattern)} ${q(path ?? ".")}` });
112
+ // rg exits 1 when there are no matches — that's not an error.
113
+ const { text, truncated } = tail(r.stdout);
114
+ return { matches: text, truncated, noMatches: r.exitCode === 1 && !r.stdout };
115
+ },
116
+ });
117
+ /** Human-readable size — never "0 KB" for a real payload. */
118
+ function formatBytes(n) {
119
+ if (n < 1024)
120
+ return `${n} B`;
121
+ if (n < 1024 * 1024)
122
+ return `${Math.round(n / 1024)} KB`;
123
+ return `${(n / (1024 * 1024)).toFixed(1)} MB`;
124
+ }
125
+ /**
126
+ * What the model sees of a web_fetch result. Media becomes a real file block —
127
+ * an image the model can look at, a PDF Anthropic renders as a document — with
128
+ * a text line alongside so providers that can't take media in tool results
129
+ * still leave the model oriented instead of staring at a silently-emptied
130
+ * result. Text results keep the default JSON view.
131
+ */
132
+ export function webFetchToModelOutput({ output }) {
133
+ const r = output;
134
+ if (r && typeof r === "object" && r.ok && r.kind === "media") {
135
+ return {
136
+ type: "content",
137
+ value: [
138
+ { type: "text", text: `Fetched ${r.mediaType} (${formatBytes(r.bytes)}) from ${r.url}:` },
139
+ { type: "file", mediaType: r.mediaType, data: { type: "data", data: r.data } },
140
+ ],
141
+ };
142
+ }
143
+ return { type: "json", value: output };
144
+ }
145
+ /** Lazy: `turndown` + `@intentface/latch-net` load on first use, never at import. */
146
+ let webFetchImpl;
147
+ const loadWebFetch = () => (webFetchImpl ??= import("./web-fetch.js").then((m) => m.webFetch).catch((e) => {
148
+ webFetchImpl = undefined;
149
+ throw new Error(`web_fetch needs its optional peers installed (turndown, @intentface/latch-net): ${e instanceof Error ? e.message : String(e)}`);
150
+ }));
151
+ const web_fetch = tool({
152
+ description: "Fetch a public http(s) URL and return its content. HTML is converted to " +
153
+ "clean markdown (default) or text — not raw markup — so it's compact and " +
154
+ "readable. Images (png/jpeg/gif/webp) and PDFs are returned as viewable " +
155
+ "attachments — you SEE them, not their bytes. Runs in the app, not the " +
156
+ "sandbox; private/loopback hosts blocked.",
157
+ inputSchema: jsonSchema({
158
+ type: "object",
159
+ properties: {
160
+ url: { type: "string", description: "Fully-formed http(s) URL to fetch." },
161
+ format: {
162
+ type: "string",
163
+ enum: ["markdown", "text", "html"],
164
+ description: 'Output format; HTML is converted to it. Defaults to "markdown".',
165
+ },
166
+ timeout: { type: "number", minimum: 0, description: "Timeout in seconds (default 30, max 120)." },
167
+ },
168
+ required: ["url"],
169
+ additionalProperties: false,
170
+ }),
171
+ execute: async ({ url, format, timeout }) => {
172
+ const webFetch = await loadWebFetch();
173
+ const r = await webFetch({ url, format, timeout });
174
+ if (!r.ok)
175
+ return { ok: false, error: r.error };
176
+ if (r.kind === "media") {
177
+ return {
178
+ ok: true,
179
+ kind: "media",
180
+ status: r.status,
181
+ contentType: r.contentType,
182
+ mediaType: r.mediaType,
183
+ data: r.data,
184
+ bytes: r.bytes,
185
+ url,
186
+ };
187
+ }
188
+ return { ok: true, status: r.status, contentType: r.contentType, body: r.content, truncated: r.truncated };
189
+ },
190
+ toModelOutput: webFetchToModelOutput,
191
+ });
192
+ // ── askUser ─────────────────────────────────────────────────────────────────
193
+ /**
194
+ * Ask the user one or more multiple-choice questions and wait for their answer.
195
+ * Has NO `execute`: the SDK leaves the call in `input-available`, the turn
196
+ * pauses, and the client renders a questionnaire and supplies the result via
197
+ * `addToolResult` (output = a JSON object mapping each question → the picked
198
+ * answer), which resumes the run.
199
+ */
200
+ const askUser = tool({
201
+ description: "Ask the user one or more multiple-choice questions when you need a " +
202
+ "decision or clarification before continuing. The conversation pauses " +
203
+ "until the user answers. Prefer this over guessing.",
204
+ inputSchema: jsonSchema({
205
+ type: "object",
206
+ properties: {
207
+ questions: {
208
+ type: "array",
209
+ items: {
210
+ type: "object",
211
+ properties: {
212
+ question: { type: "string" },
213
+ header: { type: "string" },
214
+ multiSelect: { type: "boolean" },
215
+ options: {
216
+ type: "array",
217
+ items: {
218
+ type: "object",
219
+ properties: { label: { type: "string" }, description: { type: "string" } },
220
+ required: ["label", "description"],
221
+ additionalProperties: false,
222
+ },
223
+ },
224
+ },
225
+ required: ["question", "options"],
226
+ additionalProperties: false,
227
+ },
228
+ },
229
+ },
230
+ required: ["questions"],
231
+ additionalProperties: false,
232
+ }),
233
+ // No `execute` — client-handled. The answer comes back via addToolResult.
234
+ });
235
+ // ── Schedules (read + cancel; creation is host policy) ──────────────────────
236
+ // Everything a tool needs is on `options.context`: the principal AND the
237
+ // runtime the turn runs in — no host-global required. Creating a schedule
238
+ // stays with the host (it decides delivery targets, rate floors, approval).
239
+ const list_schedules = tool({
240
+ description: "List the user's scheduled runs (all agents), with ids for cancel_schedule.",
241
+ inputSchema: jsonSchema({ type: "object", properties: {}, additionalProperties: false }),
242
+ execute: async (_args, options) => {
243
+ const { principal, runtime } = harnessContextOf(options);
244
+ if (!principal || !runtime)
245
+ return { error: "No principal/runtime for this turn." };
246
+ const schedules = await runtime.listSchedules({ principal });
247
+ return {
248
+ schedules: schedules.map((s) => ({
249
+ id: s.id,
250
+ agent: s.agent,
251
+ cron: s.cron ?? "one-off",
252
+ timezone: s.timezone ?? "UTC",
253
+ prompt: s.prompt,
254
+ enabled: s.enabled,
255
+ nextRunAt: new Date(s.nextRunAt).toISOString(),
256
+ })),
257
+ };
258
+ },
259
+ });
260
+ const cancel_schedule = tool({
261
+ description: "Cancel one of the user's scheduled runs by id (from list_schedules). Use this " +
262
+ "when they say to stop a recurring run.",
263
+ inputSchema: jsonSchema({
264
+ type: "object",
265
+ properties: { id: { type: "string", description: "Schedule id from list_schedules." } },
266
+ required: ["id"],
267
+ additionalProperties: false,
268
+ }),
269
+ execute: async (args, options) => {
270
+ const { principal, runtime } = harnessContextOf(options);
271
+ if (!principal || !runtime)
272
+ return { error: "No principal/runtime for this turn." };
273
+ // `unschedule` is owner-fenced and returns void, so a stale or foreign id
274
+ // deletes nothing silently. Confirm it exists first — otherwise the model
275
+ // tells the user a schedule was cancelled when it wasn't.
276
+ const mine = await runtime.listSchedules({ principal });
277
+ if (!mine.some((s) => s.id === args.id)) {
278
+ return { error: `No schedule ${args.id} — call list_schedules for current ids.` };
279
+ }
280
+ await runtime.unschedule({ principal, id: args.id });
281
+ return { cancelled: args.id };
282
+ },
283
+ });
284
+ /** Sandbox-backed tools (need an agent with `sandbox: true`). */
285
+ export const sandboxTools = { bash, read_file, write_file, glob, grep };
286
+ /** App-process default tools (granted by `defaultTools`; no sandbox needed). */
287
+ export const appTools = { web_fetch, askUser, list_schedules, cancel_schedule };
288
+ /**
289
+ * The `RuntimeConfig.harnessTools` bundle: sandbox + app tools, no default
290
+ * approval gates (nothing here persists a side effect the user hasn't asked
291
+ * for in the turn). Spread a host's own additions over `app` / `approval`.
292
+ */
293
+ export function defaultHarnessTools() {
294
+ return { sandbox: { ...sandboxTools }, app: { ...appTools }, approval: {} };
295
+ }
296
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/harness/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AA2BtC,MAAM,SAAS,GAAG,CAAC,CAAU,EAA+B,EAAE;IAC5D,MAAM,CAAC,GAAI,CAAiB,CAAC,oBAAoB,CAAC;IAClD,IAAI,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IAC/D,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAYF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAc,CAAU,EAAyB,EAAE,CAChF,CAAyC,CAAC,OAAO,IAAK,EAA4B,CAAC;AAEtF,wEAAwE;AACxE,MAAM,CAAC,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,QAAQ,GAAG,GAAG,EAAE,QAAQ,GAAG,MAAM;IAClE,IAAI,GAAG,GAAG,IAAI,CAAC;IACf,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,MAAM,GAAG,QAAQ,EAAE,CAAC;QAC5B,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,QAAQ,EAAE,CAAC;QACtC,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC3B,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;AAClC,CAAC;AAED,+EAA+E;AAE/E,MAAM,IAAI,GAAG,IAAI,CAAC;IAChB,WAAW,EACT,yEAAyE;QACzE,yEAAyE;QACzE,qEAAqE;QACrE,mEAAmE;QACnE,qDAAqD;IACvD,WAAW,EAAE,UAAU,CAAsB;QAC3C,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE,EAAE;QACjF,QAAQ,EAAE,CAAC,SAAS,CAAC;QACrB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE;QACtC,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1B,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1B,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,SAAS,EAAE,CAAC;IAC7G,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,IAAI,CAAC;IACrB,WAAW,EACT,yEAAyE;QACzE,6DAA6D;IAC/D,WAAW,EAAE,UAAU,CAA2D;QAChF,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACxB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+BAA+B,EAAE;YAC5E,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;SACzE;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;QAClB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE;QACzD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvG,IAAI,IAAI,IAAI,IAAI;YAAE,OAAO,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,UAAU,IAAI,CAAC,CAAC;QAC9B,MAAM,QAAQ,GAAG,IAAI;aAClB,KAAK,CAAC,IAAI,CAAC;aACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;aACnC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IACrD,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,IAAI,CAAC;IACtB,WAAW,EACT,0EAA0E;QAC1E,6DAA6D;IAC/D,WAAW,EAAE,UAAU,CAAoC;QACzD,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACrE,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;QAC7B,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE;QAC5C,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IACzD,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,IAAI,CAAC;IAChB,WAAW,EACT,wEAAwE;QACxE,8DAA8D;IAChE,WAAW,EAAE,UAAU,CAAqC;QAC1D,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACrE,QAAQ,EAAE,CAAC,SAAS,CAAC;QACrB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;QAC5C,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1G,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;IACvE,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,IAAI,GAAG,IAAI,CAAC;IAChB,WAAW,EACT,oEAAoE;QACpE,0DAA0D;IAC5D,WAAW,EAAE,UAAU,CAAqC;QAC1D,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;QACrE,QAAQ,EAAE,CAAC,SAAS,CAAC;QACrB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,EAAE;QAC5C,6DAA6D;QAC7D,MAAM,CAAC,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QAC1F,8DAA8D;QAC9D,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;IAChF,CAAC;CACF,CAAC,CAAC;AAoBH,6DAA6D;AAC7D,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,IAAI,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACzD,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAE,MAAM,EAAuB;IACnE,MAAM,CAAC,GAAG,MAA4B,CAAC;IACvC,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC7D,OAAO;YACL,IAAI,EAAE,SAAS;YACf,KAAK,EAAE;gBACL,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,GAAG,EAAE;gBACzF,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE;aAC/E;SACF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAe,EAAE,CAAC;AAClD,CAAC;AAED,qFAAqF;AACrF,IAAI,YAAgI,CAAC;AACrI,MAAM,YAAY,GAAG,GAAG,EAAE,CACxB,CAAC,YAAY,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IAC7E,YAAY,GAAG,SAAS,CAAC;IACzB,MAAM,IAAI,KAAK,CACb,mFAAmF,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAChI,CAAC;AACJ,CAAC,CAAC,CAAC,CAAC;AAEN,MAAM,SAAS,GAAG,IAAI,CAAC;IACrB,WAAW,EACT,0EAA0E;QAC1E,0EAA0E;QAC1E,yEAAyE;QACzE,wEAAwE;QACxE,0CAA0C;IAC5C,WAAW,EAAE,UAAU,CAA2E;QAChG,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oCAAoC,EAAE;YAC1E,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC;gBAClC,WAAW,EAAE,iEAAiE;aAC/E;YACD,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,2CAA2C,EAAE;SAClG;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC;QACjB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,EAA+B,EAAE;QACvE,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,MAAM,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;QAChD,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO;gBACL,EAAE,EAAE,IAAI;gBACR,IAAI,EAAE,OAAO;gBACb,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,GAAG;aACJ,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IAC7G,CAAC;IACD,aAAa,EAAE,qBAAqB;CACrC,CAAC,CAAC;AAEH,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,OAAO,GAAG,IAAI,CAAC;IACnB,WAAW,EACT,qEAAqE;QACrE,uEAAuE;QACvE,oDAAoD;IACtD,WAAW,EAAE,UAAU,CAOpB;QACD,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACV,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAC5B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBAC1B,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;wBAChC,OAAO,EAAE;4BACP,IAAI,EAAE,OAAO;4BACb,KAAK,EAAE;gCACL,IAAI,EAAE,QAAQ;gCACd,UAAU,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;gCAC1E,QAAQ,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC;gCAClC,oBAAoB,EAAE,KAAK;6BAC5B;yBACF;qBACF;oBACD,QAAQ,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC;oBACjC,oBAAoB,EAAE,KAAK;iBAC5B;aACF;SACF;QACD,QAAQ,EAAE,CAAC,WAAW,CAAC;QACvB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,0EAA0E;CAC3E,CAAC,CAAC;AAEH,+EAA+E;AAC/E,yEAAyE;AACzE,0EAA0E;AAC1E,4EAA4E;AAE5E,MAAM,cAAc,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,4EAA4E;IACzF,WAAW,EAAE,UAAU,CAAwB,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,KAAK,EAAE,CAAC;IAC/G,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;QACpF,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QAC7D,OAAO;YACL,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;gBACzB,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,KAAK;gBAC7B,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,OAAO,EAAE,CAAC,CAAC,OAAO;gBAClB,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE;aAC/C,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;CACF,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,IAAI,CAAC;IAC3B,WAAW,EACT,gFAAgF;QAChF,wCAAwC;IAC1C,WAAW,EAAE,UAAU,CAAiB;QACtC,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,EAAE,EAAE;QACvF,QAAQ,EAAE,CAAC,IAAI,CAAC;QAChB,oBAAoB,EAAE,KAAK;KAC5B,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QAC/B,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,SAAS,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;QACpF,0EAA0E;QAC1E,0EAA0E;QAC1E,0DAA0D;QAC1D,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACxC,OAAO,EAAE,KAAK,EAAE,eAAe,IAAI,CAAC,EAAE,yCAAyC,EAAE,CAAC;QACpF,CAAC;QACD,MAAM,OAAO,CAAC,UAAU,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC;IAChC,CAAC;CACF,CAAC,CAAC;AAEH,iEAAiE;AACjE,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAA6B,CAAC;AACnG,gFAAgF;AAChF,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAA6B,CAAC;AAE3G;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IAKjC,OAAO,EAAE,OAAO,EAAE,EAAE,GAAG,YAAY,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,47 @@
1
+ export type WebFetchFormat = "markdown" | "text" | "html";
2
+ export type WebFetchResult = {
3
+ ok: true;
4
+ kind: "text";
5
+ status: number;
6
+ contentType: string;
7
+ content: string;
8
+ truncated: boolean;
9
+ } | {
10
+ ok: true;
11
+ kind: "media";
12
+ status: number;
13
+ contentType: string;
14
+ /** The normalized type the model-facing file part will carry. */
15
+ mediaType: SupportedMediaType;
16
+ /** Base64-encoded bytes. */
17
+ data: string;
18
+ /** Original (pre-base64) size. */
19
+ bytes: number;
20
+ } | {
21
+ ok: false;
22
+ error: string;
23
+ };
24
+ /**
25
+ * Media the fetch returns as bytes for the model to SEE rather than as decoded
26
+ * text: the image types every provider's vision input accepts, plus PDF
27
+ * (Anthropic renders it as a document block; providers without tool-result PDF
28
+ * support drop the part but keep the accompanying text).
29
+ */
30
+ export type SupportedMediaType = "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "application/pdf";
31
+ /**
32
+ * What media the body is, if it's a type worth showing the model. The
33
+ * Content-Type header decides when it's one of ours; magic bytes rescue the
34
+ * common case of a server that lies (application/octet-stream, text/plain) —
35
+ * sniffing is deliberately limited to unambiguous signatures.
36
+ */
37
+ export declare function detectMedia(contentType: string, bytes: Uint8Array): SupportedMediaType | null;
38
+ /** HTML → Markdown (Turndown), dropping script/style/meta/link noise. */
39
+ export declare function convertHtmlToMarkdown(html: string): string;
40
+ /** Strip HTML to readable text (no Turndown) — for `format: "text"`. */
41
+ export declare function extractTextFromHtml(html: string): string;
42
+ export declare function webFetch(args: {
43
+ url: string;
44
+ format?: WebFetchFormat;
45
+ timeout?: number;
46
+ }): Promise<WebFetchResult>;
47
+ //# sourceMappingURL=web-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../src/harness/web-fetch.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAE1D,MAAM,MAAM,cAAc,GACtB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GACpG;IACE,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,SAAS,EAAE,kBAAkB,CAAC;IAC9B,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B,WAAW,GACX,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,iBAAiB,CAAC;AAQtB;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,kBAAkB,GAAG,IAAI,CA0B7F;AA2BD,yEAAyE;AACzE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU1D;AAaD,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAexD;AAkBD,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,cAAc,CAAC,CAqH1B"}