@foldrun/core 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/src/account.d.ts +45 -0
- package/dist/src/account.js +130 -0
- package/dist/src/api-tools.d.ts +8 -0
- package/dist/src/api-tools.js +22 -4
- package/dist/src/browser-pod.d.ts +129 -0
- package/dist/src/browser-pod.js +284 -0
- package/dist/src/catalog.js +2 -1
- package/dist/src/clock.d.ts +49 -0
- package/dist/src/clock.js +121 -0
- package/dist/src/completions.js +17 -8
- package/dist/src/confine.d.ts +22 -0
- package/dist/src/confine.js +218 -3
- package/dist/src/deploy.d.ts +33 -0
- package/dist/src/deploy.js +145 -6
- package/dist/src/egress.d.ts +7 -0
- package/dist/src/egress.js +6 -0
- package/dist/src/eol.d.ts +2 -0
- package/dist/src/eol.js +7 -0
- package/dist/src/evals.d.ts +5 -0
- package/dist/src/evals.js +6 -2
- package/dist/src/flow-lint.d.ts +8 -0
- package/dist/src/flow-lint.js +223 -1
- package/dist/src/flow-patterns.d.ts +141 -0
- package/dist/src/flow-patterns.js +568 -0
- package/dist/src/gitrepo.d.ts +18 -0
- package/dist/src/gitrepo.js +49 -0
- package/dist/src/kinds.js +1 -1
- package/dist/src/language.d.ts +17 -0
- package/dist/src/language.js +55 -0
- package/dist/src/layout.d.ts +69 -0
- package/dist/src/layout.js +200 -0
- package/dist/src/library.d.ts +9 -0
- package/dist/src/library.js +30 -3
- package/dist/src/limits.d.ts +84 -0
- package/dist/src/limits.js +287 -0
- package/dist/src/locale.d.ts +47 -0
- package/dist/src/locale.js +177 -0
- package/dist/src/mail.d.ts +88 -0
- package/dist/src/mail.js +245 -0
- package/dist/src/model-probe.d.ts +3 -0
- package/dist/src/model-probe.js +1 -0
- package/dist/src/notify.d.ts +53 -7
- package/dist/src/notify.js +194 -126
- package/dist/src/openapi.js +5 -3
- package/dist/src/operator.d.ts +201 -0
- package/dist/src/operator.js +251 -0
- package/dist/src/paths.d.ts +28 -0
- package/dist/src/paths.js +55 -0
- package/dist/src/platform.d.ts +43 -3
- package/dist/src/platform.js +9 -1
- package/dist/src/provider-health.js +3 -2
- package/dist/src/providers.d.ts +481 -0
- package/dist/src/providers.js +1105 -6
- package/dist/src/refusal.d.ts +83 -0
- package/dist/src/refusal.js +281 -0
- package/dist/src/run-container.d.ts +149 -13
- package/dist/src/run-container.js +403 -42
- package/dist/src/runner.d.ts +142 -9
- package/dist/src/runner.js +1027 -122
- package/dist/src/runtime.d.ts +52 -0
- package/dist/src/runtime.js +493 -58
- package/dist/src/script-tools.d.ts +3 -2
- package/dist/src/script-tools.js +35 -3
- package/dist/src/secret-files.d.ts +6 -5
- package/dist/src/secret-files.js +24 -11
- package/dist/src/secret-health.d.ts +30 -6
- package/dist/src/secret-health.js +42 -20
- package/dist/src/secrets.d.ts +19 -0
- package/dist/src/secrets.js +155 -86
- package/dist/src/starter.d.ts +9 -0
- package/dist/src/starter.js +92 -11
- package/dist/src/step-exec.d.ts +61 -2
- package/dist/src/step-exec.js +414 -36
- package/dist/src/step-removal.d.ts +15 -0
- package/dist/src/step-removal.js +49 -0
- package/dist/src/storage.d.ts +23 -4
- package/dist/src/storage.js +125 -23
- package/dist/src/store.d.ts +218 -37
- package/dist/src/store.js +347 -60
- package/dist/src/subagents.d.ts +75 -0
- package/dist/src/subagents.js +149 -0
- package/dist/src/tool-names.d.ts +13 -1
- package/dist/src/tool-names.js +38 -11
- package/dist/src/tool-programs.d.ts +26 -0
- package/dist/src/tool-programs.js +172 -0
- package/dist/src/tool-test.js +104 -12
- package/dist/src/translator.d.ts +8 -2
- package/dist/src/translator.js +69 -23
- package/dist/src/trigger-log.d.ts +1 -1
- package/dist/src/triggers.d.ts +3 -0
- package/dist/src/triggers.js +10 -2
- package/dist/src/untrusted-fetch.d.ts +11 -0
- package/dist/src/untrusted-fetch.js +77 -0
- package/dist/src/web-actions.d.ts +91 -0
- package/dist/src/web-actions.js +199 -0
- package/dist/src/webhook.d.ts +4 -0
- package/dist/src/webhook.js +39 -0
- package/index.ts +3 -0
- package/package.json +3 -3
- package/src/account.ts +149 -0
- package/src/api-tools.ts +32 -4
- package/src/browser-pod.ts +313 -0
- package/src/catalog.ts +2 -1
- package/src/clock.ts +149 -0
- package/src/completions.ts +17 -8
- package/src/confine.ts +218 -3
- package/src/deploy.ts +137 -6
- package/src/egress.ts +13 -1
- package/src/eol.ts +7 -0
- package/src/evals.ts +11 -2
- package/src/flow-lint.ts +253 -1
- package/src/flow-patterns.ts +597 -0
- package/src/gitrepo.ts +48 -0
- package/src/kinds.ts +1 -1
- package/src/language.ts +62 -0
- package/src/layout.ts +228 -0
- package/src/library.ts +37 -3
- package/src/limits.ts +290 -0
- package/src/locale.ts +217 -0
- package/src/mail.ts +316 -0
- package/src/model-probe.ts +4 -0
- package/src/notify.ts +189 -103
- package/src/openapi.ts +5 -3
- package/src/operator.ts +300 -0
- package/src/paths.ts +54 -0
- package/src/platform.ts +52 -3
- package/src/provider-health.ts +3 -2
- package/src/providers.ts +1368 -6
- package/src/refusal.ts +320 -0
- package/src/run-container.ts +439 -43
- package/src/runner.ts +1050 -122
- package/src/runtime.ts +487 -55
- package/src/script-tools.ts +38 -5
- package/src/secret-files.ts +22 -10
- package/src/secret-health.ts +64 -19
- package/src/secrets.ts +149 -87
- package/src/starter.ts +93 -11
- package/src/step-exec.ts +429 -37
- package/src/step-removal.ts +59 -0
- package/src/storage.ts +141 -22
- package/src/store.ts +500 -68
- package/src/subagents.ts +189 -0
- package/src/tool-names.ts +40 -11
- package/src/tool-programs.ts +179 -0
- package/src/tool-test.ts +110 -12
- package/src/translator.ts +72 -22
- package/src/trigger-log.ts +1 -0
- package/src/triggers.ts +10 -2
- package/src/untrusted-fetch.ts +88 -0
- package/src/web-actions.ts +237 -0
- package/src/webhook.ts +41 -0
- package/templates/hello/agents/curator/agent.md +1 -1
- package/templates/hello/agents/notetaker/agent.md +1 -1
package/dist/src/providers.d.ts
CHANGED
|
@@ -24,7 +24,197 @@ export interface ProviderPreset {
|
|
|
24
24
|
note?: string;
|
|
25
25
|
/** A tool loop was driven through this endpoint from this runtime. */
|
|
26
26
|
verified?: boolean;
|
|
27
|
+
/** Whether the endpoint runs a server-side web search, and in whose shape.
|
|
28
|
+
* Absent means it does not — `web.search: <that name>` is then an error a
|
|
29
|
+
* person should see from `check`, not an empty result at 3am. */
|
|
30
|
+
search?: SearchShape;
|
|
27
31
|
}
|
|
32
|
+
/** Whether this endpoint will execute a server-side web search, and in whose
|
|
33
|
+
* shape. Separate from `format` on purpose: speaking a wire is not the same
|
|
34
|
+
* as running a tool on it. DeepSeek's endpoint is Anthropic-shaped and still
|
|
35
|
+
* has no search at all, which is exactly the mistake this field exists to
|
|
36
|
+
* stop `check` from letting through.
|
|
37
|
+
*
|
|
38
|
+
* "anthropic" executes the `web_search_20250305` server tool as Anthropic
|
|
39
|
+
* defines it, so the runtime grants it and the endpoint answers
|
|
40
|
+
* "plugin" has its own switch rather than a tool (OpenRouter's web
|
|
41
|
+
* plugin / `:online`), fulfilled natively where the underlying
|
|
42
|
+
* model supports it and by Exa everywhere else
|
|
43
|
+
* "openai" the Responses-shaped `web_search` tool
|
|
44
|
+
* "builtin_fn" Moonshot's `$web_search`, a Chat-Completions builtin_function
|
|
45
|
+
* the client has to echo back — billed per successful call
|
|
46
|
+
* undefined no server-side search. Ours is the only way to the web. */
|
|
47
|
+
export type SearchShape = "anthropic" | "plugin" | "openai" | "builtin_fn" | "direct";
|
|
48
|
+
/** A search API the runtime calls itself, with the customer's own key.
|
|
49
|
+
*
|
|
50
|
+
* These are not model providers — none of them serves a model — so they
|
|
51
|
+
* live apart from PROVIDERS. `web.search:` accepts either kind of name, and
|
|
52
|
+
* the difference decides where the search runs: a provider's server-side
|
|
53
|
+
* tool runs on the provider's machines and is off the run record, while a
|
|
54
|
+
* direct API is called from the run's own sandbox through the egress proxy
|
|
55
|
+
* — the key never enters the pod, the call is on the record with its
|
|
56
|
+
* arguments, and it works whichever model is driving. Same switch, better
|
|
57
|
+
* audit trail. Shapes were read from each vendor's own API reference on
|
|
58
|
+
* 2026-09-16; the gallery's web tool carries the
|
|
59
|
+
* matching request and response mapping. */
|
|
60
|
+
export interface SearchApi {
|
|
61
|
+
/** The vendor's API reference the adapter was built from, the day it was
|
|
62
|
+
* last matched to it, and what that page could not confirm. Read by
|
|
63
|
+
* web-actions.ts; a check older than 90 days fails its test. */
|
|
64
|
+
docs?: string;
|
|
65
|
+
checked?: string;
|
|
66
|
+
gaps?: string;
|
|
67
|
+
name: string;
|
|
68
|
+
aliases?: string[];
|
|
69
|
+
title: string;
|
|
70
|
+
/** The one host the key may be sent to — the egress grant is for this. */
|
|
71
|
+
host: string;
|
|
72
|
+
endpoint: string;
|
|
73
|
+
method: "GET" | "POST";
|
|
74
|
+
/** The header the key travels in, and any prefix on the value. */
|
|
75
|
+
auth: {
|
|
76
|
+
header: string;
|
|
77
|
+
prefix?: string;
|
|
78
|
+
};
|
|
79
|
+
/** The vault name a customer stores their key under. */
|
|
80
|
+
secret: string;
|
|
81
|
+
index: string;
|
|
82
|
+
note?: string;
|
|
83
|
+
/** The API answers without a key (at a lower rate). The runner declares
|
|
84
|
+
* the secret only when the vault has it, so a missing key is not an
|
|
85
|
+
* error the way a declared-and-absent secret is. */
|
|
86
|
+
secretOptional?: boolean;
|
|
87
|
+
/** What the value in the vault must be, when it is not the bare key. */
|
|
88
|
+
secretFormat?: string;
|
|
89
|
+
}
|
|
90
|
+
export declare const SEARCH_APIS: readonly SearchApi[];
|
|
91
|
+
/** Names people will try that cannot work, and why — said at `check`
|
|
92
|
+
* rather than discovered at 3am. */
|
|
93
|
+
export declare const REFUSED_WEB: Record<string, string>;
|
|
94
|
+
/** Fetch APIs the runtime calls itself: a URL in, the page out, with the
|
|
95
|
+
* customer's own key. Same seam as the search APIs — `web.fetch: jina` —
|
|
96
|
+
* and the same trade: our own fetch is free and on the record; these are
|
|
97
|
+
* for the failure modes ours cannot cover, chiefly a page that refuses a
|
|
98
|
+
* plain request. Three tiers, priced accordingly: a reader (Jina,
|
|
99
|
+
* Firecrawl) turns a page into clean markdown; a search vendor's extract
|
|
100
|
+
* (Exa, Tavily, Parallel) reads many at once; an unblocker (Zyte, ScrapingBee) renders
|
|
101
|
+
* behind the anti-bot walls a reader cannot pass. */
|
|
102
|
+
export interface FetchApi extends Omit<SearchApi, "index"> {
|
|
103
|
+
tier: "reader" | "extract" | "unblocker";
|
|
104
|
+
/** How many URLs one call may carry. 1 means one call per page. */
|
|
105
|
+
batch: number;
|
|
106
|
+
what: string;
|
|
107
|
+
}
|
|
108
|
+
export declare const FETCH_APIS: readonly FetchApi[];
|
|
109
|
+
/** Remote browsers: a CDP endpoint our web browse connects to instead of
|
|
110
|
+
* the account's pod — the same tool, the same modes and actions, rendered
|
|
111
|
+
* on the vendor's machines. `web.browse: browserbase`. The one capability
|
|
112
|
+
* where the key cannot ride the egress proxy: CDP is a websocket, so the
|
|
113
|
+
* wrapper holds the real value the way it already holds a cookie secret,
|
|
114
|
+
* and creates the session itself where the vendor wants one. */
|
|
115
|
+
/** What a vendor's own session can be asked for, per its docs — the keys of
|
|
116
|
+
* `web.browse.vendor_session:` it accepts. Absent means it has no such option;
|
|
117
|
+
* naming one is an error in `check` that says which vendors do. */
|
|
118
|
+
export interface SessionSupport {
|
|
119
|
+
/** on: a proxy can be switched on; always: it is always on (true is a
|
|
120
|
+
* no-op, false an error); the rest say which parts of a location, and
|
|
121
|
+
* whether a proxy of your own is taken. */
|
|
122
|
+
proxy?: {
|
|
123
|
+
on?: boolean;
|
|
124
|
+
always?: boolean;
|
|
125
|
+
country?: boolean;
|
|
126
|
+
state?: boolean;
|
|
127
|
+
city?: boolean;
|
|
128
|
+
own?: boolean;
|
|
129
|
+
needsCountry?: boolean;
|
|
130
|
+
stateOrCity?: boolean;
|
|
131
|
+
};
|
|
132
|
+
captcha?: boolean;
|
|
133
|
+
stealth?: boolean;
|
|
134
|
+
region?: readonly string[];
|
|
135
|
+
/** The session's life, in seconds: [least, most]. */
|
|
136
|
+
timeout?: readonly [number, number];
|
|
137
|
+
/** Saved logins across runs: the vendor's contexts or profiles. */
|
|
138
|
+
keep?: boolean;
|
|
139
|
+
record?: boolean;
|
|
140
|
+
block?: readonly ("ads" | "trackers" | "cookies")[];
|
|
141
|
+
/** Where `options:` goes, as written: the session request's body, or the
|
|
142
|
+
* connection URL's query. Absent: the vendor takes none. */
|
|
143
|
+
options?: "body" | "query";
|
|
144
|
+
/** web.browse settings this vendor's browser will not take. */
|
|
145
|
+
refuses?: readonly string[];
|
|
146
|
+
}
|
|
147
|
+
/** `web.browse.vendor_session:` — what the vendor's session is asked for.
|
|
148
|
+
* Called `session:` until 2026-10-01, which a call's `session=` (a named
|
|
149
|
+
* saved login) also is; the old key is still read, and check warns. */
|
|
150
|
+
export interface BrowseSession {
|
|
151
|
+
proxy?: boolean | {
|
|
152
|
+
country?: string;
|
|
153
|
+
state?: string;
|
|
154
|
+
city?: string;
|
|
155
|
+
own?: string;
|
|
156
|
+
};
|
|
157
|
+
captcha?: boolean;
|
|
158
|
+
stealth?: boolean;
|
|
159
|
+
region?: string;
|
|
160
|
+
/** seconds */
|
|
161
|
+
timeout?: number;
|
|
162
|
+
keep?: string;
|
|
163
|
+
record?: boolean;
|
|
164
|
+
block?: ("ads" | "trackers" | "cookies")[];
|
|
165
|
+
options?: Record<string, unknown>;
|
|
166
|
+
}
|
|
167
|
+
export interface BrowserApi {
|
|
168
|
+
session?: SessionSupport;
|
|
169
|
+
/** Steps of web browse this browser cannot do, per the vendor's own docs.
|
|
170
|
+
* Kept equal to the tool's VENDORS table by the platform's gallery test. */
|
|
171
|
+
lacks?: string[];
|
|
172
|
+
/** The vendor's API reference the adapter was built from, the day it was
|
|
173
|
+
* last matched to it, and what that page could not confirm. Read by
|
|
174
|
+
* web-actions.ts; a check older than 90 days fails its test. */
|
|
175
|
+
docs?: string;
|
|
176
|
+
checked?: string;
|
|
177
|
+
gaps?: string;
|
|
178
|
+
name: string;
|
|
179
|
+
aliases?: string[];
|
|
180
|
+
title: string;
|
|
181
|
+
/** How a session is reached: a REST call that returns the endpoint, or a
|
|
182
|
+
* websocket URL the key goes straight into. */
|
|
183
|
+
how: "session" | "direct";
|
|
184
|
+
host: string;
|
|
185
|
+
secret: string;
|
|
186
|
+
secretFormat?: string;
|
|
187
|
+
what: string;
|
|
188
|
+
note?: string;
|
|
189
|
+
}
|
|
190
|
+
export declare const BROWSER_APIS: readonly BrowserApi[];
|
|
191
|
+
/** The web's actions, in the order the docs list them. */
|
|
192
|
+
export declare const WEB_ACTIONS: readonly ["search", "fetch", "browse", "crawl", "map", "extract", "answer", "monitor"];
|
|
193
|
+
export type WebAction = (typeof WEB_ACTIONS)[number];
|
|
194
|
+
/** A provider for one of the actions that came after search, fetch and
|
|
195
|
+
* browse. Only what the runtime needs — the vault name of the key and the
|
|
196
|
+
* one host it may go to — plus the docs the adapter in the `web` tool was
|
|
197
|
+
* built from. None has been called live from here: no account holds these
|
|
198
|
+
* keys yet, so each is as good as its docs page. */
|
|
199
|
+
export interface ActionApi {
|
|
200
|
+
name: string;
|
|
201
|
+
title: string;
|
|
202
|
+
host: string;
|
|
203
|
+
secret: string;
|
|
204
|
+
docs: string;
|
|
205
|
+
checked: string;
|
|
206
|
+
gaps?: string;
|
|
207
|
+
}
|
|
208
|
+
export declare const ACTION_APIS: Record<"crawl" | "map" | "extract" | "answer" | "monitor", readonly ActionApi[]>;
|
|
209
|
+
export declare function findActionApi(action: keyof typeof ACTION_APIS, name: string): ActionApi | undefined;
|
|
210
|
+
export declare function findBrowserApi(name: string): BrowserApi | undefined;
|
|
211
|
+
export declare function findFetchApi(name: string): FetchApi | undefined;
|
|
212
|
+
export declare function findSearchApi(name: string): SearchApi | undefined;
|
|
213
|
+
/** Whose index answers, for the ones that will answer at all. Checked against
|
|
214
|
+
* each vendor's own documentation on 2026-09-16. Worth stating out loud
|
|
215
|
+
* because it is the whole reason to prefer a provider's search over ours:
|
|
216
|
+
* you are buying an index we cannot crawl, not a faster endpoint. */
|
|
217
|
+
export declare const SEARCH_INDEX: Record<string, string>;
|
|
28
218
|
export declare const PROVIDERS: readonly ProviderPreset[];
|
|
29
219
|
/**
|
|
30
220
|
* Request fields `params:` may not set.
|
|
@@ -45,3 +235,294 @@ export declare function providerPreset(name: unknown): ProviderPreset | null;
|
|
|
45
235
|
* without saying `format: openai`? The heuristic the checker uses to say
|
|
46
236
|
* so before a run fails with a 404 from the wrong path. */
|
|
47
237
|
export declare function looksOpenAiShaped(baseUrl: string): boolean;
|
|
238
|
+
/** What `web.search: <name>` in an agent's frontmatter resolves to.
|
|
239
|
+
*
|
|
240
|
+
* Unset means ours: the account's own search engine, free, on the run
|
|
241
|
+
* record. Naming a provider buys that provider's index instead — which is
|
|
242
|
+
* the only reason to do it, and the reason the failure modes below are
|
|
243
|
+
* errors rather than a quiet fallback. A desk that silently searched
|
|
244
|
+
* nothing for a month is worse than one that refused to deploy.
|
|
245
|
+
*/
|
|
246
|
+
export interface SearchChoice {
|
|
247
|
+
/** null when ours answers. */
|
|
248
|
+
provider: string | null;
|
|
249
|
+
shape?: SearchShape;
|
|
250
|
+
/** Whose index answers, for the run trace and the help page. */
|
|
251
|
+
index?: string;
|
|
252
|
+
/** For a direct API: the vault name of the customer's key, and the one
|
|
253
|
+
* host the egress proxy may fill it in for. */
|
|
254
|
+
secret?: string;
|
|
255
|
+
secretOptional?: boolean;
|
|
256
|
+
host?: string;
|
|
257
|
+
/** Set when the name cannot work; `check` prints it and refuses. */
|
|
258
|
+
error?: string;
|
|
259
|
+
}
|
|
260
|
+
/** `web.search: exa`, or the long form with the customer's own vault name:
|
|
261
|
+
*
|
|
262
|
+
* web:
|
|
263
|
+
* search:
|
|
264
|
+
* name: exa
|
|
265
|
+
* key: ${MY_EXA_KEY}
|
|
266
|
+
*
|
|
267
|
+
* The same two spellings `provider:` takes. `key` is a reference, never a
|
|
268
|
+
* value — a credential written into a markdown file is refused here, the
|
|
269
|
+
* way it is refused everywhere else in foldrun. */
|
|
270
|
+
/**
|
|
271
|
+
* `web.browse:` settings — how the browser presents itself, not what one call
|
|
272
|
+
* does.
|
|
273
|
+
*
|
|
274
|
+
* web:
|
|
275
|
+
* browse:
|
|
276
|
+
* engine: firefox
|
|
277
|
+
* user_agent: "Mozilla/5.0 …"
|
|
278
|
+
*
|
|
279
|
+
* The engine and the user agent belong in the file, not in every call. They
|
|
280
|
+
* travel together: a Cloudflare clearance cookie is bound to the user agent
|
|
281
|
+
* that earned it, so a skill repeating the UA in each call is one edit away
|
|
282
|
+
* from a session that silently stops working (Medium, 2026-09-17).
|
|
283
|
+
*
|
|
284
|
+
* `via:` (or `name:`) names a remote browser vendor, which is what this key
|
|
285
|
+
* meant when it only took a string; that spelling still works. Anything a
|
|
286
|
+
* single call decides — mode, actions, wait_for, block — stays in the call.
|
|
287
|
+
*/
|
|
288
|
+
export interface BrowseSettings {
|
|
289
|
+
engine?: "chrome" | "chromium" | "firefox" | "webkit" | "lightpanda" | "obscura";
|
|
290
|
+
user_agent?: string;
|
|
291
|
+
device?: string;
|
|
292
|
+
locale?: string;
|
|
293
|
+
timezone?: string;
|
|
294
|
+
/** The NAME of a vault secret holding this site's sign-in cookies, never
|
|
295
|
+
* the cookies themselves. It sits here beside `user_agent` because the two
|
|
296
|
+
* are one thing: a Cloudflare clearance cookie is bound to the user agent
|
|
297
|
+
* that earned it, and a file that carries one without the other is a
|
|
298
|
+
* session waiting to stop working. */
|
|
299
|
+
cookies?: string;
|
|
300
|
+
cookie_domain?: string;
|
|
301
|
+
/** The NAME of a vault secret holding this site's signed-in Web Storage and
|
|
302
|
+
* IndexedDB, as JSON: `{ localStorage, sessionStorage, indexedDB }`. The
|
|
303
|
+
* sibling of `cookies:` for the sites that keep their login in storage
|
|
304
|
+
* rather than a cookie — Firebase writes a record to IndexedDB, MSAL can
|
|
305
|
+
* keep tokens in sessionStorage, and a cookie jar alone opens those pages
|
|
306
|
+
* signed out. Seeded before the page's own scripts run, never read back. */
|
|
307
|
+
storage?: string;
|
|
308
|
+
storage_origin?: string;
|
|
309
|
+
/** Named bundles of the same settings plus the per-call ones that travel
|
|
310
|
+
* with an identity — proxy, headers, geolocation, permissions,
|
|
311
|
+
* color_scheme, block — chosen on a call as `identity=<name>`. "As an
|
|
312
|
+
* Australian phone" is six settings; a name says it once. Each value is a
|
|
313
|
+
* map of text (or JSON for headers), validated here the way the block is. */
|
|
314
|
+
identities?: Record<string, Record<string, string>>;
|
|
315
|
+
/** false runs the full browser with a window, on a virtual screen where
|
|
316
|
+
* the machine has none. Unset or true is the usual no-window browser. */
|
|
317
|
+
headless?: boolean;
|
|
318
|
+
/** Which build of the engine to run: a Chrome release channel
|
|
319
|
+
* (`stable`/`beta`/`dev`) or a label naming a binary installed in the
|
|
320
|
+
* image (`/opt/browser/<engine>/<version>/`). Unset is the pinned
|
|
321
|
+
* default. Resolved in the tool, which falls back to the default and
|
|
322
|
+
* says so when the named build is not installed. */
|
|
323
|
+
version?: string;
|
|
324
|
+
/** true keeps the browser and its open page alive between this agent's
|
|
325
|
+
* calls in a step, so a multi-step form can be driven one step per call.
|
|
326
|
+
* Chromium-only (chrome/chromium). Unset: each call is a fresh page, with
|
|
327
|
+
* only cookies carried by a session. */
|
|
328
|
+
live?: boolean;
|
|
329
|
+
/** The domains this agent's browser may reach at all — pages, scripts,
|
|
330
|
+
* fetches, sockets. A lock, not a default: a call may narrow it and never
|
|
331
|
+
* widen it, so no page's text can talk the model past it. */
|
|
332
|
+
allowed_domains?: string[];
|
|
333
|
+
/** Actions this agent may never take (eval, download, upload, …), checked
|
|
334
|
+
* before a browser opens. Names from WEB_BROWSE_ACTIONS, plus js. */
|
|
335
|
+
deny?: string[];
|
|
336
|
+
/** true marks the page's words in every reply with a nonce the page cannot
|
|
337
|
+
* know, so text written to look like instructions stays the page's. */
|
|
338
|
+
boundaries?: boolean;
|
|
339
|
+
/** Workspace paths of scripts run in every page before its own. */
|
|
340
|
+
init?: string[];
|
|
341
|
+
/** Workspace paths of unpacked Chrome extensions to load (Chromium, in the step). */
|
|
342
|
+
extensions?: string[];
|
|
343
|
+
/** true gives pages WebGPU, on a software GPU where there is none. */
|
|
344
|
+
webgpu?: boolean;
|
|
345
|
+
/** true opens pages whose certificate does not check out (staging, self-signed). */
|
|
346
|
+
ignore_https_errors?: boolean;
|
|
347
|
+
/** The NAME of a vault secret whose value encrypts state= logins at rest. */
|
|
348
|
+
state_key?: string;
|
|
349
|
+
/** true records every call, so the run page always has the recording to play. */
|
|
350
|
+
video?: boolean;
|
|
351
|
+
/** false stops the tool streaming its page to the run page while the step
|
|
352
|
+
* runs. Unset is on wherever the platform can take the frames. */
|
|
353
|
+
live_view?: boolean;
|
|
354
|
+
/** What the vendor's own session is asked for (only with a vendor).
|
|
355
|
+
* Written `vendor_session:`; `session:` is the deprecated spelling. */
|
|
356
|
+
vendor_session?: BrowseSession;
|
|
357
|
+
}
|
|
358
|
+
/** Every action web browse takes, which is what `deny:` may name. The
|
|
359
|
+
* gallery test holds this equal to the tool's own list, so a new action
|
|
360
|
+
* cannot be undeniable, and a misspelt denial — which would deny nothing —
|
|
361
|
+
* is refused at check time instead. */
|
|
362
|
+
export declare const WEB_BROWSE_ACTIONS: readonly ["click", "dblclick", "rightclick", "hover", "check", "uncheck", "drag", "fill", "type", "press", "select", "wait", "goto", "screenshot", "pdf", "scroll", "paste", "upload", "download", "extract", "frame", "tab", "back", "forward", "reload", "focus", "clear", "highlight", "keyboard", "keydown", "keyup", "mouse", "wheel", "tap", "swipe", "clipboard", "eval", "get", "expect", "if", "mock", "unmock", "offline", "cookie", "localstorage", "sessionstorage", "viewport", "dialog", "solve", "pushstate", "insert", "webmcp", "login"];
|
|
363
|
+
export declare const BROWSE_ENGINES: readonly ["chromium", "chrome", "firefox", "safari", "lightpanda", "obscura"];
|
|
364
|
+
/**
|
|
365
|
+
* What each engine cannot do, and the words a refusal uses. ONE table: the
|
|
366
|
+
* tool (web/browse.mjs in the platform gallery) carries a copy that refuses a
|
|
367
|
+
* call, and `foldrun check` reads this one to refuse a `web.browse:` block
|
|
368
|
+
* that pairs an engine with something it cannot do — so the mistake is found
|
|
369
|
+
* at check time, not at 3am. The gallery test holds the tool's copy equal to
|
|
370
|
+
* this one, so neither can learn an option the other does not.
|
|
371
|
+
*
|
|
372
|
+
* An entry is what the tool prints for the option: a call argument (video,
|
|
373
|
+
* trace, block…), `mode=<mode>`, or `headless: false`. A refusal reads
|
|
374
|
+
* `<entry> <why>`. chromium and chrome can do all of it, so they have no row.
|
|
375
|
+
*/
|
|
376
|
+
export declare const BROWSE_ENGINE_LIMITS: Record<string, {
|
|
377
|
+
why: string;
|
|
378
|
+
cannot: readonly string[];
|
|
379
|
+
}>;
|
|
380
|
+
/** The refusal for one option on one engine, or null when the engine can. */
|
|
381
|
+
export declare function browseEngineRefusal(engine: string, what: string): string | null;
|
|
382
|
+
/** The shape of `web.browse.vendor_session:`, before anyone knows the vendor. What
|
|
383
|
+
* the vendor can do is browseSessionProblems' question. */
|
|
384
|
+
export declare function readBrowseSession(raw: unknown, key?: "vendor_session" | "session"): {
|
|
385
|
+
session?: BrowseSession;
|
|
386
|
+
error?: string;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Everything wrong with a session block for this vendor: a setting the
|
|
390
|
+
* vendor has no option for (naming the vendors that do), a value outside its
|
|
391
|
+
* range, and the browse settings its browser will not take. The rule the
|
|
392
|
+
* actions follow — the file is fixed, nothing is quietly dropped.
|
|
393
|
+
*/
|
|
394
|
+
export declare function browseSessionProblems(settings: BrowseSettings, vendor: string | null): string[];
|
|
395
|
+
export declare function readBrowseSettings(raw: unknown): {
|
|
396
|
+
settings: BrowseSettings;
|
|
397
|
+
rest: unknown;
|
|
398
|
+
error?: string;
|
|
399
|
+
};
|
|
400
|
+
/**
|
|
401
|
+
* `web.search:` settings — what the account's own engine (SearXNG) is asked,
|
|
402
|
+
* not who answers.
|
|
403
|
+
*
|
|
404
|
+
* web:
|
|
405
|
+
* search:
|
|
406
|
+
* engines: [bing, google cse, duckduckgo]
|
|
407
|
+
* categories: [general, news]
|
|
408
|
+
* safesearch: moderate
|
|
409
|
+
*
|
|
410
|
+
* Every SearXNG request option that changes what comes back has a key here;
|
|
411
|
+
* the ones that only change its HTML page (theme, results_on_new_tab,
|
|
412
|
+
* image_proxy, url_formatting) do not, because in JSON they do nothing and a
|
|
413
|
+
* key that does nothing is a question someone asks later. Engine and
|
|
414
|
+
* category names are checked for shape here and against the running
|
|
415
|
+
* instance by the tool (its /config), because the instance decides which of
|
|
416
|
+
* SearXNG's engines are loaded. Plugin ids are a short list that changes
|
|
417
|
+
* rarely, so a misspelt one — which would enable nothing — is refused here.
|
|
418
|
+
*
|
|
419
|
+
* The settings speak SearXNG, so they are refused beside `name:` — with
|
|
420
|
+
* `web.search: exa` they would be silently ignored.
|
|
421
|
+
*/
|
|
422
|
+
export interface SearchSettings {
|
|
423
|
+
/** Ask only these engines. A default: a call's `engines=` or
|
|
424
|
+
* `categories=` replaces it, and it beats `categories` beside it — the
|
|
425
|
+
* tool never sends SearXNG both, which would add the categories' engines
|
|
426
|
+
* to the list. */
|
|
427
|
+
engines?: string[];
|
|
428
|
+
/** Never ask these, whatever the call says. A lock, like
|
|
429
|
+
* web.browse.allowed_domains: a call may not widen it. */
|
|
430
|
+
exclude_engines?: string[];
|
|
431
|
+
/** The SearXNG categories to search (general, news, science, it, …),
|
|
432
|
+
* when no engine list is in force. A default a call replaces. */
|
|
433
|
+
categories?: string[];
|
|
434
|
+
/** 0 off, 1 moderate, 2 strict. */
|
|
435
|
+
safesearch?: 0 | 1 | 2;
|
|
436
|
+
/** The default recency when a call does not say. */
|
|
437
|
+
time_range?: "day" | "week" | "month" | "year";
|
|
438
|
+
/** Seconds SearXNG waits for its engines before answering with what it has. */
|
|
439
|
+
timeout?: number;
|
|
440
|
+
/** SearXNG plugins to switch on, and off, for this agent's searches. */
|
|
441
|
+
plugins?: string[];
|
|
442
|
+
exclude_plugins?: string[];
|
|
443
|
+
/** Where the open-access DOI rewrite plugin points a paper's link. */
|
|
444
|
+
doi_resolver?: string;
|
|
445
|
+
}
|
|
446
|
+
/** SearXNG's plugin ids (searx/plugins/*.py, 2026-09-29). The gallery test
|
|
447
|
+
* keeps this equal to the list the tool documents. */
|
|
448
|
+
export declare const WEB_SEARCH_PLUGINS: readonly ["ahmia_filter", "calculator", "hash_plugin", "hostnames", "infinite_scroll", "oa_doi_rewrite", "self_info", "time_zone", "tor_check", "tracker_url_remover", "unit_converter"];
|
|
449
|
+
/** The settings in a `web.search:` block, and the provider part with them
|
|
450
|
+
* removed — the shape readBrowseSettings has, for the same reason. */
|
|
451
|
+
export declare function readSearchSettings(raw: unknown): {
|
|
452
|
+
settings: SearchSettings;
|
|
453
|
+
rest: unknown;
|
|
454
|
+
error?: string;
|
|
455
|
+
};
|
|
456
|
+
/** The `web.search:` block's settings as the env the tool reads. Only what
|
|
457
|
+
* was said travels — an unset key is SearXNG's own default. */
|
|
458
|
+
export declare function searchSettingsEnv(s: SearchSettings): Record<string, string>;
|
|
459
|
+
export declare function resolveSearch(name: unknown, kind?: "search" | "fetch" | "browse"): SearchChoice;
|
|
460
|
+
/** A `web.browse:` block that pairs an engine with something it cannot do,
|
|
461
|
+
* in the tool's own words (BROWSE_ENGINE_LIMITS). The block's engine is
|
|
462
|
+
* checked against the block's settings; each identity is checked with its
|
|
463
|
+
* own engine (or the block's) against the block's settings and its own,
|
|
464
|
+
* because a call that picks the identity gets both. What only a call can
|
|
465
|
+
* ask for (a mode, a trace, mocks) is the tool's to refuse. */
|
|
466
|
+
export declare function browseEngineProblems(settings: BrowseSettings): string[];
|
|
467
|
+
/** Every `web:` value in a frontmatter that cannot work, each as the
|
|
468
|
+
* sentence resolveSearch gives. Computed once in core so `check`, the
|
|
469
|
+
* deploy gate and the run all refuse the same thing in the same words —
|
|
470
|
+
* the timezone rule's shape. Empty when all are unset or answerable. */
|
|
471
|
+
export declare function webProblems(front: Record<string, unknown>): string[];
|
|
472
|
+
/**
|
|
473
|
+
* The engines the runner image was built with, as the deploy wrote them into
|
|
474
|
+
* FOLDRUN_RUNNER_ENGINES (foldrun-infra dev/ci/runner-engines.sh): a comma
|
|
475
|
+
* list of names, each with `=<version>` where the image's manifest
|
|
476
|
+
* (/opt/browser/engines.json) has a dotted version —
|
|
477
|
+
* `chromium=153.0.8010.12,chrome=154.0.8037.58,firefox,lightpanda=0.4.1`.
|
|
478
|
+
* Null when unset.
|
|
479
|
+
*/
|
|
480
|
+
export declare function runnerEngines(raw?: string | undefined): Record<string, string | null> | null;
|
|
481
|
+
/** The Chrome major a user-agent string claims — `Chrome/153.0.0.0` → 153 —
|
|
482
|
+
* or null for one that names no Chrome (Firefox, Safari, an iPhone). */
|
|
483
|
+
export declare function chromeMajorOf(ua: string): number | null;
|
|
484
|
+
/**
|
|
485
|
+
* A pinned `user_agent:` that claims another Chrome than the one that will
|
|
486
|
+
* send it. The tool's own default follows the installed Chrome (its
|
|
487
|
+
* chromiumVersion()), so only a pinned string can drift — and it drifts
|
|
488
|
+
* every time the image's Chrome moves (stable is unpinned, a new major every
|
|
489
|
+
* four weeks). A site then sees `Chrome/153` in the User-Agent header beside
|
|
490
|
+
* `"Google Chrome";v="154"` in the client hints the browser still sends, and
|
|
491
|
+
* a JavaScript engine that is 154's: the mismatch bot checks look for.
|
|
492
|
+
* `chrome` is the image's version of that browser (runnerEngines().chrome,
|
|
493
|
+
* or .chromium for engine chromium); null — an image that did not say —
|
|
494
|
+
* warns about nothing.
|
|
495
|
+
*/
|
|
496
|
+
export declare function userAgentDrift(ua: string | undefined, chrome: string | null | undefined, where: string, browser?: string): string | null;
|
|
497
|
+
/**
|
|
498
|
+
* What in a `web:` block works today but should change — never a refusal.
|
|
499
|
+
* `check` prints these as warnings and the deploy reports them beside its
|
|
500
|
+
* outward-gate warnings. `opts.chrome` / `opts.chromium`: the runner image's
|
|
501
|
+
* Google Chrome and Playwright Chromium versions, when known
|
|
502
|
+
* (FOLDRUN_RUNNER_ENGINES on the platform, /api/version from the CLI); an
|
|
503
|
+
* engine whose version is unknown is not compared.
|
|
504
|
+
*/
|
|
505
|
+
export declare function webWarnings(front: Record<string, unknown>, opts?: {
|
|
506
|
+
chrome?: string | null;
|
|
507
|
+
chromium?: string | null;
|
|
508
|
+
}): string[];
|
|
509
|
+
/**
|
|
510
|
+
* The agent's `web:` block, read once for everyone — the runner, `check`
|
|
511
|
+
* and the deploy gate:
|
|
512
|
+
*
|
|
513
|
+
* tools: [web]
|
|
514
|
+
* web:
|
|
515
|
+
* actions: [search, fetch, crawl] # what it may do; all when absent
|
|
516
|
+
* search: brave # who does each; absent is foldrun
|
|
517
|
+
* browse: { engine: firefox } # search and browse also take their settings
|
|
518
|
+
*
|
|
519
|
+
* `raw` is each action's value as written. Browse alone cascades: the
|
|
520
|
+
* workspace's (or account's) `web: {browse: …}` applies when the agent's
|
|
521
|
+
* says nothing. A per-action key outside the block (`web_search:`) is not
|
|
522
|
+
* read; it is a problem naming the block.
|
|
523
|
+
*/
|
|
524
|
+
export declare function webConfig(front: Record<string, unknown>, workspaceFront?: Record<string, unknown>): {
|
|
525
|
+
actions: WebAction[] | null;
|
|
526
|
+
raw: Record<WebAction, unknown>;
|
|
527
|
+
problems: string[];
|
|
528
|
+
};
|