@foldrun/core 0.4.0 → 0.6.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/README.md +7 -4
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -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 +148 -0
- package/dist/src/browser-pod.js +333 -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/container.d.ts +9 -0
- package/dist/src/container.js +115 -5
- package/dist/src/context-tools.d.ts +1 -1
- 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 +9 -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/host-env.js +5 -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 +247 -0
- package/dist/src/model-credential.d.ts +14 -0
- package/dist/src/model-credential.js +58 -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 +424 -43
- package/dist/src/runner.d.ts +177 -9
- package/dist/src/runner.js +1146 -154
- package/dist/src/runtime.d.ts +52 -0
- package/dist/src/runtime.js +493 -58
- package/dist/src/script-tools.d.ts +17 -2
- package/dist/src/script-tools.js +82 -10
- 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 +72 -2
- package/dist/src/step-exec.js +431 -37
- 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 +222 -37
- package/dist/src/store.js +349 -62
- package/dist/src/subagents.d.ts +75 -0
- package/dist/src/subagents.js +149 -0
- package/dist/src/test-mode.d.ts +17 -2
- package/dist/src/test-mode.js +53 -13
- 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 +4 -0
- package/package.json +3 -3
- package/src/account.ts +149 -0
- package/src/api-tools.ts +32 -4
- package/src/browser-pod.ts +350 -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/container.ts +112 -5
- package/src/context-tools.ts +1 -1
- package/src/deploy.ts +137 -6
- package/src/egress.ts +13 -1
- package/src/eol.ts +7 -0
- package/src/evals.ts +14 -2
- package/src/flow-lint.ts +253 -1
- package/src/flow-patterns.ts +597 -0
- package/src/gitrepo.ts +48 -0
- package/src/host-env.ts +5 -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 +318 -0
- package/src/model-credential.ts +71 -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 +460 -44
- package/src/runner.ts +1168 -155
- package/src/runtime.ts +487 -55
- package/src/script-tools.ts +81 -10
- 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 +447 -38
- package/src/step-removal.ts +59 -0
- package/src/storage.ts +141 -22
- package/src/store.ts +506 -70
- package/src/subagents.ts +189 -0
- package/src/test-mode.ts +51 -11
- 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/blog-desk/agents/writer/agent.md +1 -1
- package/templates/hello/agents/curator/agent.md +4 -4
- package/templates/hello/agents/notetaker/agent.md +3 -3
package/dist/src/store.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { BrowserPodOutcome } from "./browser-pod.ts";
|
|
1
2
|
import { singleWorkspace } from "./paths.ts";
|
|
2
3
|
import type { TestEffect } from "./test-mode.ts";
|
|
4
|
+
import type { OperatorEvent } from "./operator.ts";
|
|
3
5
|
/**
|
|
4
6
|
* The frontmatter of one markdown file, as the runtime reads it. Exported
|
|
5
7
|
* for the CLI: `foldrun probe` used to import gray-matter itself, which is
|
|
@@ -54,9 +56,10 @@ export declare function workspaceDir(tenant: string, workspace: string): string;
|
|
|
54
56
|
* The account root — where `library/`, account secrets and the account-wide
|
|
55
57
|
* AGENTS.md live.
|
|
56
58
|
*
|
|
57
|
-
* On a laptop
|
|
58
|
-
*
|
|
59
|
-
* rule libraryDir uses, so the two never
|
|
59
|
+
* On a laptop it is wherever `singleAccountRoot` says: the workspace's parent
|
|
60
|
+
* for a flat `my-desk/`, and the account root two levels up for a workspace
|
|
61
|
+
* inside `my-account/workspaces/`. Same rule libraryDir uses, so the two never
|
|
62
|
+
* disagree about where "up" is.
|
|
60
63
|
*/
|
|
61
64
|
export declare function accountDir(tenant: string): string;
|
|
62
65
|
/**
|
|
@@ -111,6 +114,10 @@ export declare function assertCanonicalCase(rel: string): void;
|
|
|
111
114
|
export declare const PLATFORM_FILES: string[];
|
|
112
115
|
/** True for anything the platform, not the author or the agent, writes. */
|
|
113
116
|
export declare function isPlatformPath(rel: string): boolean;
|
|
117
|
+
/** What a deploy keeps whatever it ships — the rule above saveWorkspace's
|
|
118
|
+
* body. planDeploy reports removals through the same test, so a plan never
|
|
119
|
+
* lists a file the save would keep. */
|
|
120
|
+
export declare function keptOnDeploy(rel: string, shipped: ReadonlySet<string>): boolean;
|
|
114
121
|
export declare function saveWorkspace(tenant: string, workspace: string, files: DeployFile[],
|
|
115
122
|
/** Attribution for the revision this save records. A deploy passes the
|
|
116
123
|
* commit, which becomes the revision's id. */
|
|
@@ -132,19 +139,25 @@ export interface McpSpec {
|
|
|
132
139
|
url?: string;
|
|
133
140
|
headers: Record<string, string>;
|
|
134
141
|
}
|
|
135
|
-
|
|
142
|
+
/** `outward: true` in a tool's frontmatter: this one sends, posts, buys,
|
|
143
|
+
* publishes or uploads. It changes nothing at run time — `check` uses it to
|
|
144
|
+
* insist the step that grants it has a verify or a gate. */
|
|
145
|
+
export type OutwardMark = {
|
|
146
|
+
outward?: boolean;
|
|
147
|
+
};
|
|
148
|
+
export type ToolDef = ({
|
|
136
149
|
kind: "http";
|
|
137
150
|
name: string;
|
|
138
151
|
spec: ApiSpec;
|
|
139
|
-
} | {
|
|
152
|
+
} & OutwardMark) | ({
|
|
140
153
|
kind: "script";
|
|
141
154
|
name: string;
|
|
142
155
|
spec: Record<string, unknown>;
|
|
143
|
-
} | {
|
|
156
|
+
} & OutwardMark) | ({
|
|
144
157
|
kind: "mcp";
|
|
145
158
|
name: string;
|
|
146
159
|
spec: McpSpec;
|
|
147
|
-
};
|
|
160
|
+
} & OutwardMark);
|
|
148
161
|
/**
|
|
149
162
|
* The program inside a single-file script tool: the first fenced block whose
|
|
150
163
|
* language tag names a runnable language. By tag, not by position — a body
|
|
@@ -168,6 +181,13 @@ export declare function fencedCodeBlock(body: string): {
|
|
|
168
181
|
start: number;
|
|
169
182
|
end: number;
|
|
170
183
|
} | null;
|
|
184
|
+
/**
|
|
185
|
+
* `outward: true` — this tool changes something that is not ours: it sends,
|
|
186
|
+
* posts, buys, publishes, uploads. The runtime does not treat it differently;
|
|
187
|
+
* `check` does, because the step that uses one is the step where a silent
|
|
188
|
+
* failure costs something that cannot be taken back. See `lintFlow`.
|
|
189
|
+
*/
|
|
190
|
+
export declare function toolIsOutward(data: Record<string, unknown>): boolean;
|
|
171
191
|
export declare function parseToolDef(data: Record<string, unknown>, fallbackName: string, body?: string): ToolDef | null;
|
|
172
192
|
/**
|
|
173
193
|
* Tools in a directory, in both shapes.
|
|
@@ -190,6 +210,19 @@ export declare function parseToolDef(data: Record<string, unknown>, fallbackName
|
|
|
190
210
|
*
|
|
191
211
|
* Flat files keep working unchanged — the shape is a migration, not a break.
|
|
192
212
|
*/
|
|
213
|
+
/**
|
|
214
|
+
* A folder tool's `requirements.txt` and `package.json`, as a `runtime:`
|
|
215
|
+
* block. Requirement lines only: comments and blanks are left out, and so
|
|
216
|
+
* are options — whole option lines (`-r`, `--index-url`, `-e`) and the ones
|
|
217
|
+
* a requirement carries (`--hash=…`). Options never reach the installer,
|
|
218
|
+
* which takes them from the same argv as its operands; their NAMES are kept
|
|
219
|
+
* in `ignored`, never their values (an index URL can carry a password), so
|
|
220
|
+
* the build log can say what was not applied. Anything else that is not a
|
|
221
|
+
* requirement is refused later by parseRuntime with a log line, the same as
|
|
222
|
+
* it would be in tool.md. `dependencies` only — a tool's dev dependencies
|
|
223
|
+
* are its author's, not its runtime's.
|
|
224
|
+
*/
|
|
225
|
+
export declare function folderRuntime(folder: string): Record<string, unknown> | null;
|
|
193
226
|
declare function readToolDir(dir: string, scope?: "workspace" | "account"): Record<string, ToolDef>;
|
|
194
227
|
/** Definitions that exist on disk but could not be read, for the scopes an
|
|
195
228
|
* agent draws on. Empty when everything parsed. */
|
|
@@ -212,7 +245,9 @@ export interface ApiSpec {
|
|
|
212
245
|
openapi?: string;
|
|
213
246
|
/** Which of the document's operations to expose — operationIds or
|
|
214
247
|
* `"METHOD /path"` strings. Absent: every operation, capped at 60.
|
|
215
|
-
* Present: only these, and the generic `call_<api>` tool is withheld
|
|
248
|
+
* Present: only these, and the generic `call_<api>` tool is withheld —
|
|
249
|
+
* always. If none of them resolve (document missing, moved, or an
|
|
250
|
+
* operation renamed) the API gets no tools that run: it fails closed. */
|
|
216
251
|
operations?: string[];
|
|
217
252
|
/** Calls per second this API may see from one step: `count` is the burst
|
|
218
253
|
* the bucket holds, `perSec` the refill rate. `"5/s"` → {5, 5};
|
|
@@ -242,9 +277,15 @@ export interface AgentInfo {
|
|
|
242
277
|
/** Names still written under the removed `use:` key. Nothing is granted
|
|
243
278
|
* for them; `foldrun check` and the run log say what to write instead. */
|
|
244
279
|
legacyUse: string[];
|
|
280
|
+
/** Retired built-in names still in `tools:` (files, bash) — granted, but
|
|
281
|
+
* `check` says what to write instead. */
|
|
282
|
+
retiredTools: string[];
|
|
245
283
|
/** Colleagues this agent may consult mid-run (`agents:`) — each becomes a
|
|
246
284
|
* consult_<name> tool. The team's edges, as the author drew them. */
|
|
247
285
|
consults: string[];
|
|
286
|
+
/** Colleagues this agent may DELEGATE to (`subagents:`) — each runs with
|
|
287
|
+
* its own context and its own tools, no wider than this agent's. */
|
|
288
|
+
subagents: string[];
|
|
248
289
|
/** The `skills:` allowlist, or null when the field is absent — which is
|
|
249
290
|
* not the same thing: absent inherits every skill in scope, an empty
|
|
250
291
|
* list withholds all of them. */
|
|
@@ -256,6 +297,32 @@ export interface AgentInfo {
|
|
|
256
297
|
budget: number | null;
|
|
257
298
|
/** What is wrong with the `budget:` line, or null. */
|
|
258
299
|
budgetProblem: string | null;
|
|
300
|
+
/** `timezone:` — the calendar this agent works to, nearest-wins over its
|
|
301
|
+
* flow's, its workspace's and the account's. Null inherits. */
|
|
302
|
+
timezone: string | null;
|
|
303
|
+
/** What is wrong with the `timezone:` line, or null. */
|
|
304
|
+
timezoneProblem: string | null;
|
|
305
|
+
languageProblem: string | null;
|
|
306
|
+
/** region:/currency:/units:/calendar: values that cannot be read. */
|
|
307
|
+
localeProblems: string[];
|
|
308
|
+
/** `web:` values that cannot work. The run says
|
|
309
|
+
* so in its trail and carries on; check and deploy say so first. */
|
|
310
|
+
webProblems: string[];
|
|
311
|
+
/** `web:` that works but should change — the old `session:` key, a pinned
|
|
312
|
+
* user agent behind the runner image's Chrome (when this process knows
|
|
313
|
+
* that Chrome: FOLDRUN_RUNNER_ENGINES). Warnings, never refusals. */
|
|
314
|
+
webWarnings: string[];
|
|
315
|
+
/** `schedule:` written on an agent, which nothing runs — only a flow has
|
|
316
|
+
* a clock. The message, or null when there is no such line. */
|
|
317
|
+
scheduleProblem: string | null;
|
|
318
|
+
/** `limits:` — the agent's own per-step call limits, as readable. */
|
|
319
|
+
limits: Record<string, number>;
|
|
320
|
+
/** What is wrong with the `limits:` block's shape; key-vs-grant problems
|
|
321
|
+
* need the tool lists, and `check` adds them (limits.ts limitKeyProblems). */
|
|
322
|
+
limitProblems: string[];
|
|
323
|
+
/** Tools this agent declares inline rather than in `tools:` — `apis:`,
|
|
324
|
+
* `scripts:` and `mcpServers:` names — which a limit may also name. */
|
|
325
|
+
inlineTools: string[];
|
|
259
326
|
}
|
|
260
327
|
export declare const MODEL_TIERS: Record<string, string>;
|
|
261
328
|
export type Tier = keyof typeof MODEL_TIERS;
|
|
@@ -287,6 +354,11 @@ export declare function parseApis(raw: unknown): ApiSpec[];
|
|
|
287
354
|
export interface FlowStep {
|
|
288
355
|
agent: string;
|
|
289
356
|
instruction: string;
|
|
357
|
+
/** The instruction was written over more than one line and the parser
|
|
358
|
+
* joined them. It runs, but `foldrun check` says so: a wrapped
|
|
359
|
+
* instruction is one editor keystroke away from being a paragraph of
|
|
360
|
+
* prose the parser has to guess about. */
|
|
361
|
+
wrapped?: boolean;
|
|
290
362
|
group: number;
|
|
291
363
|
optional: boolean;
|
|
292
364
|
/** Set when the step targets another flow (`[[flow:name]]`) instead of an agent. */
|
|
@@ -381,6 +453,9 @@ export interface FlowStep {
|
|
|
381
453
|
/** `max_turns:` — the most model turns this step may take before it is
|
|
382
454
|
* stopped, beside `budget:` (money) and `timeout:` (time). */
|
|
383
455
|
maxTurns?: number;
|
|
456
|
+
/** `limits: {web.search: 10}` — this step's call limits, over the agent's
|
|
457
|
+
* (nearest wins per key). See limits.ts. */
|
|
458
|
+
limits?: Record<string, number>;
|
|
384
459
|
/** 1-indexed line in the flow file. Diagnostics without a line make you
|
|
385
460
|
* search; every real linter emits file:line. */
|
|
386
461
|
line?: number;
|
|
@@ -426,7 +501,10 @@ export interface FlowInfo {
|
|
|
426
501
|
* with `on:` saying which endings count. The finished run's summary and
|
|
427
502
|
* result become this run's task. */
|
|
428
503
|
after: string | null;
|
|
429
|
-
|
|
504
|
+
/** `blocked` is a completed run whose verdict is BLOCKED — the work
|
|
505
|
+
* refused itself. `completed` no longer includes those: a follow-up to a
|
|
506
|
+
* publish that did not happen should not run as if it had. */
|
|
507
|
+
on: "completed" | "failed" | "blocked" | "any";
|
|
430
508
|
/** `trigger: once` — an ISO 8601 instant; fires the first tick at or after
|
|
431
509
|
* it, once, then never again. */
|
|
432
510
|
at: string | null;
|
|
@@ -470,6 +548,13 @@ export interface FlowInfo {
|
|
|
470
548
|
* failed all week is not going to fix itself, and every one of those runs
|
|
471
549
|
* costs money and sends mail. Null: never quarantined. */
|
|
472
550
|
disableAfter: number | null;
|
|
551
|
+
/** `pause_when:` — a marker (DONE, NOTHING LEFT) that, leading a line of
|
|
552
|
+
* any step's reply in the flow's latest run, pauses its schedule: the
|
|
553
|
+
* work is finished, so firing again would only spend money saying so.
|
|
554
|
+
* Derived from that run, like disable_after, so a run that finds work
|
|
555
|
+
* again (a person clicking Run after adding some) lifts it by itself.
|
|
556
|
+
* Null: never paused. */
|
|
557
|
+
pauseWhen: string | null;
|
|
473
558
|
/** `sla:` — seconds a run of this flow is expected to take. A run still
|
|
474
559
|
* going well past it is reported once, as a notification, and keeps
|
|
475
560
|
* running: this is a smoke alarm, not a timeout. Null: no expectation. */
|
|
@@ -488,6 +573,15 @@ export interface FlowInfo {
|
|
|
488
573
|
* default them to test: in a preview workspace, and as an eval's subject.
|
|
489
574
|
* Only ever an opt-out of the safe default, never the other way round. */
|
|
490
575
|
live: boolean;
|
|
576
|
+
/** `description:` — one line on what this flow is for, shown in listings
|
|
577
|
+
* and the trace. Read here so a documented, scaffolded field means
|
|
578
|
+
* something rather than sitting in every file unread. */
|
|
579
|
+
description: string | null;
|
|
580
|
+
/** Flow-level frontmatter values the parser could not read — a bad
|
|
581
|
+
* `overlap:`/`priority:`/`catchup:`/`on:`/`signature:`, or a step line
|
|
582
|
+
* whose `[[target]]` is malformed. Errors, the way a bad step option is,
|
|
583
|
+
* rather than a silent default. */
|
|
584
|
+
frontProblems: string[];
|
|
491
585
|
steps: FlowStep[];
|
|
492
586
|
}
|
|
493
587
|
export declare const FLOW_TRIGGERS: readonly ["manual", "schedule", "webhook", "email", "flow", "once", "watch", "storage"];
|
|
@@ -529,7 +623,7 @@ export declare function parseInstant(raw: unknown): string | null;
|
|
|
529
623
|
* removed a leading OR a trailing quote independently, so a value that
|
|
530
624
|
* merely *ended* with one lost it — and
|
|
531
625
|
*
|
|
532
|
-
* verify: test "$(cat
|
|
626
|
+
* verify: test "$(cat workspace/storage/draft/published.run)" = "$FOLDRUN_RUN_ID"
|
|
533
627
|
*
|
|
534
628
|
* reached bash unbalanced, which exited 2 with "unexpected EOF" on every
|
|
535
629
|
* run. The step could never pass, whatever the agent did, and nothing said
|
|
@@ -563,6 +657,13 @@ export declare function unquote(raw: string): string;
|
|
|
563
657
|
* The marker must also END at a boundary, so BLOCKED does not match
|
|
564
658
|
* BLOCKEDBY.
|
|
565
659
|
*/
|
|
660
|
+
/**
|
|
661
|
+
* The path of a `when: rows of <path>` condition, or null when the condition
|
|
662
|
+
* is a marker. `rows of` is the phrase `each:` uses for the same file, so a
|
|
663
|
+
* flow reads a CSV one way in both. The whole phrase is required: a bare
|
|
664
|
+
* `when: ROWS` stays the marker it always was.
|
|
665
|
+
*/
|
|
666
|
+
export declare function whenRowsPath(when: string): string | null;
|
|
566
667
|
export declare function markerPresent(text: string | null | undefined, marker: string): boolean;
|
|
567
668
|
export declare function parseFlow(file: string, raw: string): FlowInfo;
|
|
568
669
|
/** A schema written out: JSON, or YAML (parsed as frontmatter is, by the
|
|
@@ -593,40 +694,24 @@ export declare function flowHasLiveRun(tenant: string, workspace: string, flowNa
|
|
|
593
694
|
* and the diff is exactly the lines that changed. A flow with no
|
|
594
695
|
* frontmatter gains the smallest one that can carry the trigger.
|
|
595
696
|
*/
|
|
596
|
-
|
|
697
|
+
declare function setFlowTriggerLF(raw: string, opts: {
|
|
597
698
|
trigger: FlowTrigger;
|
|
598
699
|
schedule?: string;
|
|
599
700
|
timezone?: string;
|
|
600
701
|
}): string;
|
|
601
|
-
|
|
602
|
-
* Rewrite one step's option lines — the board's step editor. Surgical, like
|
|
603
|
-
* every flow rewrite: only the managed option lines of block `index` change;
|
|
604
|
-
* the step line, its unmanaged options (approve stays the `!` marker's
|
|
605
|
-
* business), other steps, comments and frontmatter survive verbatim.
|
|
606
|
-
* `null` clears an option; values are clamped exactly as parseFlow reads
|
|
607
|
-
* them, so what the editor writes is what the runner will do.
|
|
608
|
-
*/
|
|
609
|
-
/**
|
|
610
|
-
* Rewrite one step's instruction, and nothing else.
|
|
611
|
-
*
|
|
612
|
-
* The step line carries four things — the group number, the optional/approve
|
|
613
|
-
* marker, the wikilink, and the instruction — and only the last is being
|
|
614
|
-
* edited. Rebuilding the line from the parsed step would silently normalise
|
|
615
|
-
* the other three (a "2?" becoming "2.", an en dash becoming an em dash), so
|
|
616
|
-
* the prefix is taken verbatim from the file and only the tail replaced. A
|
|
617
|
-
* flow's markdown stays the author's.
|
|
618
|
-
*/
|
|
619
|
-
export declare function updateFlowStepInstruction(raw: string, index: number, instruction: string): string;
|
|
620
|
-
export declare function updateFlowStep(raw: string, index: number, options: Partial<Record<"model" | "effort" | "retry" | "timeout" | "verify" | "when" | "case" | "else" | "loop" | "until" | "each" | "max", string | number | null>>): string;
|
|
621
|
-
export declare function reorderFlowSteps(raw: string, groups: number[][]): string;
|
|
702
|
+
declare function updateFlowStepLF(raw: string, index: number, options: Partial<Record<"model" | "effort" | "retry" | "timeout" | "verify" | "when" | "case" | "else" | "loop" | "until" | "each" | "max" | "limits", string | number | null>>): string;
|
|
622
703
|
/** Append a step as its own group at the end of the flow. */
|
|
623
|
-
|
|
704
|
+
declare function addFlowStepLF(raw: string, step: {
|
|
624
705
|
target: string;
|
|
625
706
|
subflow?: boolean;
|
|
626
707
|
instruction?: string;
|
|
627
708
|
}): string;
|
|
628
|
-
|
|
629
|
-
export declare
|
|
709
|
+
export declare const setFlowTrigger: (raw: string, opts: Parameters<typeof setFlowTriggerLF>[1]) => string;
|
|
710
|
+
export declare const updateFlowStepInstruction: (raw: string, index: number, instruction: string) => string;
|
|
711
|
+
export declare const updateFlowStep: (raw: string, index: number, options: Parameters<typeof updateFlowStepLF>[2]) => string;
|
|
712
|
+
export declare const reorderFlowSteps: (raw: string, groups: number[][]) => string;
|
|
713
|
+
export declare const addFlowStep: (raw: string, step: Parameters<typeof addFlowStepLF>[1]) => string;
|
|
714
|
+
export declare const removeFlowStep: (raw: string, index: number) => string;
|
|
630
715
|
export declare function listFlows(tenant: string, workspace: string): FlowInfo[];
|
|
631
716
|
/** One flow of a workspace by name, or null. The same read listFlows makes,
|
|
632
717
|
* named so callers that want a single flow — the approval rules, the
|
|
@@ -784,12 +869,50 @@ export interface RunEvent {
|
|
|
784
869
|
* state write, a withheld secret. The run page lists these; the text is
|
|
785
870
|
* still the trace's line. See test-mode.ts. */
|
|
786
871
|
effect?: TestEffect;
|
|
872
|
+
/** Set when a person was involved mid-step: a question the agent asked
|
|
873
|
+
* (ask_person), its answer, or a message a person sent in (operator.ts). */
|
|
874
|
+
operator?: OperatorEvent;
|
|
875
|
+
/** Set on a tool event a SUB-AGENT made (`subagents:`): its name. The
|
|
876
|
+
* trace labels the call with it; cost stays the step's. */
|
|
877
|
+
subagent?: string;
|
|
878
|
+
/** Set on an error a failed check wrote — `verify:` (its headline and its
|
|
879
|
+
* detail), `output: json`, a schema. What the runner reads to decline a
|
|
880
|
+
* retry of an outward step whose tools already ran. */
|
|
881
|
+
check?: boolean;
|
|
882
|
+
}
|
|
883
|
+
/** A question an agent asked a person while its step ran (tools: [ask]). */
|
|
884
|
+
export interface StepQuestion {
|
|
885
|
+
id: string;
|
|
886
|
+
question: string;
|
|
887
|
+
options?: string[];
|
|
888
|
+
askedAt: string;
|
|
889
|
+
answer?: string;
|
|
890
|
+
answeredAt?: string;
|
|
891
|
+
by?: string | null;
|
|
892
|
+
/** true when the wait ran out with no answer. */
|
|
893
|
+
unanswered?: boolean;
|
|
894
|
+
}
|
|
895
|
+
/** A message a person sent into a running step, and when the agent got it. */
|
|
896
|
+
export interface StepMessage {
|
|
897
|
+
text: string;
|
|
898
|
+
by?: string | null;
|
|
899
|
+
at: string;
|
|
900
|
+
deliveredAt: string;
|
|
787
901
|
}
|
|
788
902
|
/** One attempt of a step — see StepRecord.tries. */
|
|
789
903
|
export interface StepAttempt {
|
|
790
|
-
/** Which
|
|
904
|
+
/** Which try, 1-based, in the order they ran: a retry is the next try,
|
|
905
|
+
* and so is the full re-run after a slim go the browser pod was lost
|
|
906
|
+
* under. Equal to the step's attempt (`attempts` at the time) unless
|
|
907
|
+
* `attempt` says otherwise. */
|
|
791
908
|
n: number;
|
|
792
|
-
|
|
909
|
+
/** The step's attempt this try belongs to, written only when it is not
|
|
910
|
+
* `n` — after a lost slim go, its full re-run is try 2 of attempt 1. */
|
|
911
|
+
attempt?: number;
|
|
912
|
+
/** `lost`: a slim go the account's browser pod went away under, which
|
|
913
|
+
* the step ran again on the full image within the same attempt — a row
|
|
914
|
+
* of its own (image slim), before the full go's. */
|
|
915
|
+
status: "completed" | "failed" | "lost";
|
|
793
916
|
costUsd: number | null;
|
|
794
917
|
tokens: {
|
|
795
918
|
input: number;
|
|
@@ -800,6 +923,11 @@ export interface StepAttempt {
|
|
|
800
923
|
finishedAt: string;
|
|
801
924
|
/** The last error event this attempt wrote, when it failed. */
|
|
802
925
|
error?: string;
|
|
926
|
+
/** The runner image this attempt ended on, and — when it browsed through
|
|
927
|
+
* the account's pod from slim — what happened to the pod: reconnects,
|
|
928
|
+
* the re-run on full, or why it was not re-run. */
|
|
929
|
+
image?: "full" | "slim";
|
|
930
|
+
browserPod?: string;
|
|
803
931
|
}
|
|
804
932
|
/** The step's totals across its attempts, from the rows. Null where no
|
|
805
933
|
* attempt reported the figure — an in-process step rents no sandbox, and
|
|
@@ -808,6 +936,11 @@ export declare function sumAttempts(tries: StepAttempt[]): Pick<StepAttempt, "co
|
|
|
808
936
|
export interface StepRecord {
|
|
809
937
|
agent: string;
|
|
810
938
|
instruction: string;
|
|
939
|
+
/** Questions the agent asked a person mid-step (tools: [ask]), newest
|
|
940
|
+
* last. One without an answer (and not `unanswered`) is still open. */
|
|
941
|
+
questions?: StepQuestion[];
|
|
942
|
+
/** Messages a person sent into the running step, as delivered. */
|
|
943
|
+
messages?: StepMessage[];
|
|
811
944
|
group: number;
|
|
812
945
|
optional: boolean;
|
|
813
946
|
/** Carried from the flow — see FlowStep. Both are resolved at run
|
|
@@ -850,6 +983,31 @@ export interface StepRecord {
|
|
|
850
983
|
/** A size class a retry moved the step up to (an evicted or OOM-killed
|
|
851
984
|
* attempt), overriding the agent's own `size:` for the attempts after. */
|
|
852
985
|
sizeUp?: "large" | "heavy";
|
|
986
|
+
/** Which runner image the step's sandbox ran: `full` (browsers in it) or
|
|
987
|
+
* `slim`, why, and `pod` when a browsing step ran slim and browsed
|
|
988
|
+
* through the account's browser pod. The last attempt's; absent where
|
|
989
|
+
* the executor has one image (docker, in-process). */
|
|
990
|
+
image?: {
|
|
991
|
+
variant: "full" | "slim";
|
|
992
|
+
why?: string;
|
|
993
|
+
pod?: boolean;
|
|
994
|
+
} | null;
|
|
995
|
+
/** Which model credential the step ran on, by its variable — "API key
|
|
996
|
+
* (ANTHROPIC_API_KEY)", "Claude login token (CLAUDE_CODE_OAUTH_TOKEN)",
|
|
997
|
+
* "provider: …" — or "none set" (model-credential.ts). */
|
|
998
|
+
credential?: string;
|
|
999
|
+
/** Slim browsing through the account's pod (browser-pod.ts): reconnect
|
|
1000
|
+
* tries and how many got through; when the pod was lost, why and what
|
|
1001
|
+
* the step had written by then; and what happened — `fallback` (the
|
|
1002
|
+
* step had only read and ran again on the full image) or `failure` (it
|
|
1003
|
+
* had written, so it was not re-run). */
|
|
1004
|
+
browserPod?: (BrowserPodOutcome & {
|
|
1005
|
+
fallback?: string;
|
|
1006
|
+
failure?: string;
|
|
1007
|
+
}) | null;
|
|
1008
|
+
/** The slim go a lost browser pod ended, set aside while the step re-runs
|
|
1009
|
+
* on full; recordAttempt makes it a `lost` row of `tries` and clears it. */
|
|
1010
|
+
podLostTry?: Omit<StepAttempt, "n" | "attempt" | "startedAt"> | null;
|
|
853
1011
|
/** When the step actually started and finished executing — not when the
|
|
854
1012
|
* run reached it. A step's events approximate this (first and last), but
|
|
855
1013
|
* a model can think for minutes before its first tool call, and a step
|
|
@@ -876,6 +1034,7 @@ export interface StepRecord {
|
|
|
876
1034
|
schemaPath?: string;
|
|
877
1035
|
parallel?: number;
|
|
878
1036
|
maxTurns?: number;
|
|
1037
|
+
limits?: Record<string, number>;
|
|
879
1038
|
/** The parsed JSON an `output: json` step returned. Kept beside the prose
|
|
880
1039
|
* result rather than instead of it: the reply is still what a person
|
|
881
1040
|
* reads on the run page, and the data is what the next step computes on. */
|
|
@@ -1001,6 +1160,20 @@ export interface RunRecord {
|
|
|
1001
1160
|
* simply gets its first line — which is still better than a status.
|
|
1002
1161
|
*/
|
|
1003
1162
|
summary?: string | null;
|
|
1163
|
+
/**
|
|
1164
|
+
* What the run's work concluded, when its summary leads with one of the
|
|
1165
|
+
* four verdict words every desk ends on: GOOD, BAD, QUIET, BLOCKED.
|
|
1166
|
+
*
|
|
1167
|
+
* `status` says whether the machine ran — a step crashed, a budget ran
|
|
1168
|
+
* out. The verdict says what the agents found when it did. They are
|
|
1169
|
+
* different facts: a publisher that checks, sees the wrong change in
|
|
1170
|
+
* front of it and refuses to push has run perfectly, and its run is
|
|
1171
|
+
* `completed`. Until this field, that run was a green tick beside a line
|
|
1172
|
+
* reading BLOCKED (run-mu4sdg8z-1otr, 2026-09-17) — the one outcome a
|
|
1173
|
+
* person most needed to see, drawn as success. Null: the summary does
|
|
1174
|
+
* not lead with a verdict, and the run reads exactly as it always did.
|
|
1175
|
+
*/
|
|
1176
|
+
verdict?: Verdict | null;
|
|
1004
1177
|
/** The flow's per-run `budget:` at the time this run started, so the cap
|
|
1005
1178
|
* a run was held to is on its record rather than read from a file that
|
|
1006
1179
|
* may since have changed. Null: none. */
|
|
@@ -1214,6 +1387,18 @@ export declare function runFailure(run: RunRecord): {
|
|
|
1214
1387
|
* runFailure, which puts the reason for a failure on the list for the same
|
|
1215
1388
|
* reason — the sentence was in the record all along.
|
|
1216
1389
|
*/
|
|
1390
|
+
export declare const VERDICTS: readonly ["GOOD", "BAD", "QUIET", "BLOCKED"];
|
|
1391
|
+
export type Verdict = (typeof VERDICTS)[number];
|
|
1392
|
+
/**
|
|
1393
|
+
* The verdict a headline leads with, or null. Leading, whole-word and
|
|
1394
|
+
* upper-case only — "GOOD — 6 links applied", "**BLOCKED**: nothing
|
|
1395
|
+
* pushed", "BAD: 3 pages dropped". A summary that merely contains the word
|
|
1396
|
+
* ("no BLOCKED items") has no verdict, for the reason markerPresent gives.
|
|
1397
|
+
*/
|
|
1398
|
+
export declare function verdictOf(summary: string | null | undefined): Verdict | null;
|
|
1399
|
+
/** A run's verdict: recorded when it finished, else read from its summary,
|
|
1400
|
+
* so runs from before the field existed show one too. */
|
|
1401
|
+
export declare function runVerdict(run: Pick<RunRecord, "verdict" | "summary">): Verdict | null;
|
|
1217
1402
|
export declare function runSummary(run: RunRecord): string | null;
|
|
1218
1403
|
/**
|
|
1219
1404
|
* What one step concluded, in a line.
|