cascade-ai 0.66.2 → 0.68.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 CHANGED
@@ -5,6 +5,98 @@ import { OAuthClientInformationMixed, OAuthTokens, OAuthClientMetadata, OAuthCli
5
5
  export { OAuthClientInformationMixed, OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
6
6
  import Database from 'better-sqlite3';
7
7
 
8
+ /**
9
+ * Durable resume checkpoints.
10
+ *
11
+ * Before this, a stopped run was recoverable only through an in-memory field on
12
+ * the Cascade instance, set on exactly one path (the budget cap). So the two
13
+ * interruptions people actually hit — a crash, and Ctrl-C — lost every finished
14
+ * section, and even a budget stop was lost the moment the process exited. The
15
+ * work was on disk; the knowledge of what had been done was not.
16
+ *
17
+ * A checkpoint records the finished nodes of a run so a resume can restore them
18
+ * instead of paying to produce them a second time. Design constraints, in the
19
+ * order that shaped the code:
20
+ *
21
+ * - **A crash is one of the triggers.** Writes are atomic (temp file + rename),
22
+ * because the process dying mid-write is a case this store must survive, not
23
+ * an edge case. A half-written checkpoint that parses as valid JSON would be
24
+ * worse than none at all.
25
+ * - **A corrupt or foreign checkpoint must never break the caller.** Listing
26
+ * skips anything unreadable, unparseable, or written by a schema version this
27
+ * build doesn't know. Resume is a convenience; it may degrade, never throw.
28
+ * - **Checkpoints hold the user's prompt and partial output.** They are pruned
29
+ * by both count and age so that content does not accumulate in the workspace
30
+ * indefinitely.
31
+ */
32
+ /** Bump when the on-disk shape changes incompatibly. Older files are ignored. */
33
+ declare const RESUME_SCHEMA_VERSION = 1;
34
+ type ResumeReason = 'budget' | 'cancelled' | 'error' | 'breaker';
35
+ /** A node whose work is done and must not be re-run on resume. */
36
+ interface CompletedNode {
37
+ /** Stable id from the compiled task graph. */
38
+ id: string;
39
+ title: string;
40
+ status: 'COMPLETED' | 'PARTIAL';
41
+ output: string;
42
+ }
43
+ interface ResumeCheckpoint {
44
+ version: number;
45
+ taskId: string;
46
+ prompt: string;
47
+ /** ISO-8601. */
48
+ createdAt: string;
49
+ reason: ResumeReason;
50
+ /** Why the run stopped, in the words the user would see. */
51
+ detail?: string;
52
+ partialOutput: string;
53
+ completed: CompletedNode[];
54
+ }
55
+ interface ResumeStoreOptions {
56
+ /** Directory checkpoints live in (created on demand). */
57
+ dir: string;
58
+ /** Keep at most this many, newest first. Default 5. */
59
+ maxCheckpoints?: number;
60
+ /** Discard checkpoints older than this. Default 7 days. */
61
+ maxAgeMs?: number;
62
+ /** Injectable clock, for tests. */
63
+ now?: () => number;
64
+ }
65
+ declare class ResumeStore {
66
+ private readonly dir;
67
+ private readonly maxCheckpoints;
68
+ private readonly maxAgeMs;
69
+ private readonly now;
70
+ constructor(options: ResumeStoreOptions);
71
+ /**
72
+ * Persist a checkpoint and prune. Never throws: failing to save a resume file
73
+ * must not turn a recoverable stop into a crash, which would be a strictly
74
+ * worse outcome than the one this store exists to improve.
75
+ */
76
+ save(checkpoint: Omit<ResumeCheckpoint, 'version' | 'createdAt'> & {
77
+ createdAt?: string;
78
+ }): Promise<void>;
79
+ /** Valid, unexpired checkpoints, newest first. */
80
+ list(): Promise<ResumeCheckpoint[]>;
81
+ /** The most recent resumable run, or null. */
82
+ latest(): Promise<ResumeCheckpoint | null>;
83
+ /**
84
+ * Load a checkpoint and delete it in the same step. Resuming twice from one
85
+ * checkpoint would re-run restored work, so consumption is part of reading.
86
+ */
87
+ consume(taskId?: string): Promise<ResumeCheckpoint | null>;
88
+ /** Remove every checkpoint for a task id. */
89
+ delete(taskId: string): Promise<void>;
90
+ /** Drop expired checkpoints, then any beyond the newest `maxCheckpoints`. */
91
+ prune(): Promise<void>;
92
+ }
93
+ /**
94
+ * Render restored work for a correction planner: enough for the model to know
95
+ * what exists and not redo it, without pasting entire artifacts back into the
96
+ * prompt (which is what the token budget was being spent on in the first place).
97
+ */
98
+ declare function summarizeCompleted(completed: readonly CompletedNode[], perNodeChars?: number): string;
99
+
8
100
  type ProviderType = 'anthropic' | 'openai' | 'gemini' | 'azure' | 'openai-compatible' | 'ollama' | 'github-models';
9
101
  interface ModelInfo {
10
102
  id: string;
@@ -2344,7 +2436,20 @@ declare class T1Administrator extends BaseTier {
2344
2436
  private validatePlan;
2345
2437
  private dispatchT2Managers;
2346
2438
  /**
2347
- * Runs T2 managers respecting dependsOn declarations using Kahn's algorithm.
2439
+ * Runs T2 managers respecting dependsOn declarations.
2440
+ *
2441
+ * Graph construction, validation and cycle repair now live in
2442
+ * compileSectionGraph (orchestration/adapters.ts), and wave execution in
2443
+ * DependencyScheduler — the same pair T2 uses for its subtasks, so a plan is
2444
+ * ordered by one implementation rather than two that drifted.
2445
+ *
2446
+ * The hand-rolled Kahn pass this replaces treated every node it could not
2447
+ * reach as part of a cycle. That set also contains everything DOWNSTREAM of a
2448
+ * cycle, whose in-degree can never fall to zero while its dependency is stuck,
2449
+ * so breaking a cycle here also cut the dependencies of innocent later
2450
+ * sections and started them immediately — before the sections they consume.
2451
+ * compileTaskGraph uses strongly connected components, so only real cycle
2452
+ * members are touched.
2348
2453
  */
2349
2454
  private runT2sWithDependencies;
2350
2455
  private compileFinalOutput;
@@ -2419,8 +2524,16 @@ declare class Cascade extends EventEmitter {
2419
2524
  /** Orchestration decisions for the CURRENT run — cleared on each run(). */
2420
2525
  private decisionLog;
2421
2526
  private initialized;
2422
- /** Last task that stopped at the budget cap — powers /continue (resumeRun). */
2527
+ /**
2528
+ * Last interrupted task — powers /continue (resumeRun). Kept in memory as a
2529
+ * fast path for the same-process case; the durable copy lives in `resumeStore`
2530
+ * so a crash or an exit no longer throws away everything already finished.
2531
+ */
2423
2532
  private lastInterruptedRun?;
2533
+ /** Durable resume checkpoints. See core/orchestration/resume-store.ts. */
2534
+ private resumeStore?;
2535
+ /** Section results of the CURRENT run, so an interruption can checkpoint them. */
2536
+ private currentRunCompleted;
2424
2537
  private initPromise?;
2425
2538
  private store?;
2426
2539
  private audit?;
@@ -2556,6 +2669,24 @@ declare class Cascade extends EventEmitter {
2556
2669
  */
2557
2670
  setCurrentPageProvider(provider: CurrentPageProvider): void;
2558
2671
  private registerMediaTools;
2672
+ /**
2673
+ * Register `generate_document` where there is a real workspace to write into.
2674
+ *
2675
+ * A `.docx`/`.pptx`/`.xlsx` is a ZIP of OOXML parts, so `file_write` — which
2676
+ * does exactly what it says and writes the model's text verbatim — produced
2677
+ * files Word/Excel/PowerPoint correctly reported as corrupted. This tool owns
2678
+ * the conversion (see tools/generate-document.ts for why it isn't folded into
2679
+ * file_write).
2680
+ *
2681
+ * Registered OUTSIDE `enabledTools` for the same reason the media tools are:
2682
+ * that allowlist is a blast-radius control for tools that reach the machine
2683
+ * or the network, and this one only writes the artifact the user asked for,
2684
+ * into the workspace the run already owns. `disabledTools` still removes it.
2685
+ * A host with no filesystem (the cloud) has its own browser-side exporter and
2686
+ * simply never reaches this path — `buildDocumentTools` returns nothing
2687
+ * without a file reader, mirroring `transcribe_audio`.
2688
+ */
2689
+ private registerDocumentTools;
2559
2690
  /**
2560
2691
  * Supply per-model thumbs-up/down counts so Auto routing can weigh how models
2561
2692
  * have actually performed for this user, on top of public benchmarks.
@@ -2565,8 +2696,24 @@ declare class Cascade extends EventEmitter {
2565
2696
  * see core/router/feedback-prior.ts.
2566
2697
  */
2567
2698
  setFeedbackSource(source: FeedbackSource): void;
2568
- /** True when a task stopped at the budget cap and can be resumed via /continue. */
2699
+ /**
2700
+ * Write a durable checkpoint for an interrupted run.
2701
+ *
2702
+ * Best-effort throughout: a run is already ending badly on every path that
2703
+ * calls this, and failing to record a resume file must not make that ending
2704
+ * worse. Nothing here is allowed to throw.
2705
+ */
2706
+ private checkpointRun;
2707
+ /** True when a task can be resumed via /continue (this process or a previous one). */
2569
2708
  hasResumableRun(): boolean;
2709
+ /**
2710
+ * True when a checkpoint from ANY process is resumable. Async because the
2711
+ * durable check touches disk; `hasResumableRun` remains the sync in-memory
2712
+ * answer for callers already on a hot path.
2713
+ */
2714
+ hasDurableResume(): Promise<boolean>;
2715
+ /** Interrupted runs available to resume, newest first. */
2716
+ listResumableRuns(): Promise<ResumeCheckpoint[]>;
2570
2717
  /**
2571
2718
  * Raise the per-run token budget for a resume and return the continuation
2572
2719
  * prompt (or null when nothing is resumable). Consumes the interrupted-run
@@ -2576,6 +2723,26 @@ declare class Cascade extends EventEmitter {
2576
2723
  prepareResume(opts?: {
2577
2724
  maxTokens?: number;
2578
2725
  }): string | null;
2726
+ /**
2727
+ * Durable counterpart to prepareResume: recovers a run interrupted in ANY
2728
+ * process, including one that crashed before it could return. Consumes the
2729
+ * checkpoint, so the same finished work is never restored into two runs.
2730
+ */
2731
+ prepareDurableResume(opts?: {
2732
+ maxTokens?: number;
2733
+ taskId?: string;
2734
+ }): Promise<string | null>;
2735
+ /** A resume gets a bigger budget — the previous attempt exhausted the old one. */
2736
+ private raiseBudgetForResume;
2737
+ /**
2738
+ * The resume prompt. Completed sections are named explicitly rather than
2739
+ * gestured at: "do not recreate the files" is an instruction a planner can
2740
+ * only guess at, whereas a list of what is already done, and what it produced,
2741
+ * is something it can act on. That difference is the entire reason node
2742
+ * results are kept — a re-plan that cannot see the finished work will plan the
2743
+ * finished work again, and the user pays for it a second time.
2744
+ */
2745
+ private buildResumePrompt;
2579
2746
  /**
2580
2747
  * Resume the last budget-capped task with a raised budget (SDK/headless).
2581
2748
  * Returns null when there is nothing to resume.
@@ -2881,14 +3048,6 @@ declare class T2Manager extends BaseTier {
2881
3048
  * then reduce in-degrees of their dependents and repeat.
2882
3049
  */
2883
3050
  private runWithDependencies;
2884
- /**
2885
- * Detects cyclic dependencies using Kahn's algorithm and breaks them
2886
- * by removing back-edges. Returns a sanitized copy of assignments.
2887
- *
2888
- * A cycle like t1→t2→t3→t1 is broken at the last edge (t3→t1),
2889
- * meaning t3 will start without waiting for t1, preventing deadlock.
2890
- */
2891
- private breakCycles;
2892
3051
  private retryT3;
2893
3052
  private publishSectionOutput;
2894
3053
  private aggregateResults;
@@ -2979,6 +3138,11 @@ declare class T3Worker extends BaseTier {
2979
3138
  * needed. Best-effort: any parse/error just keeps the current output.
2980
3139
  */
2981
3140
  private reflectAndImprove;
3141
+ /**
3142
+ * Run the acceptance criteria that can be settled by looking at the workspace.
3143
+ * Reads go through the same workspace-relative resolution verifyArtifacts uses.
3144
+ */
3145
+ private checkAcceptance;
2982
3146
  private selfTest;
2983
3147
  /**
2984
3148
  * world-state v2: distill a completed subtask's output into durable
@@ -3000,6 +3164,143 @@ declare class T3Worker extends BaseTier {
3000
3164
  private isFileOperation;
3001
3165
  }
3002
3166
 
3167
+ type TaskGraphNodeKind = 'section' | 'subtask';
3168
+ type TaskGraphValidationMode = 'strict' | 'repair';
3169
+ interface TaskGraphInputNode<TPayload> {
3170
+ id: string;
3171
+ title: string;
3172
+ kind: TaskGraphNodeKind;
3173
+ dependsOn?: readonly string[];
3174
+ payload: TPayload;
3175
+ }
3176
+ interface TaskGraphNode<TPayload> {
3177
+ id: string;
3178
+ title: string;
3179
+ kind: TaskGraphNodeKind;
3180
+ dependsOn: readonly string[];
3181
+ payload: TPayload;
3182
+ /** Stable source order used to keep execution deterministic. */
3183
+ ordinal: number;
3184
+ }
3185
+ interface TaskGraph<TPayload> {
3186
+ nodes: readonly TaskGraphNode<TPayload>[];
3187
+ }
3188
+ type TaskGraphIssueCode = 'INVALID_NODE' | 'DUPLICATE_NODE_ID' | 'SELF_DEPENDENCY' | 'UNKNOWN_DEPENDENCY' | 'CYCLE_EDGE_REMOVED';
3189
+ interface TaskGraphIssue {
3190
+ code: TaskGraphIssueCode;
3191
+ message: string;
3192
+ nodeId?: string;
3193
+ dependencyId?: string;
3194
+ }
3195
+ interface CompiledTaskGraph<TPayload> {
3196
+ graph: TaskGraph<TPayload>;
3197
+ issues: readonly TaskGraphIssue[];
3198
+ }
3199
+ interface CompileTaskGraphOptions {
3200
+ /**
3201
+ * strict: reject malformed LLM plans.
3202
+ * repair: preserve today's graceful-degradation behaviour by dropping only
3203
+ * invalid dependency edges and duplicate/invalid nodes.
3204
+ */
3205
+ mode?: TaskGraphValidationMode;
3206
+ }
3207
+ declare class TaskGraphValidationError extends Error {
3208
+ readonly issues: readonly TaskGraphIssue[];
3209
+ constructor(issues: readonly TaskGraphIssue[]);
3210
+ }
3211
+ /**
3212
+ * Compile untrusted planner output into a deterministic, schedulable graph.
3213
+ * The compiler is the trust boundary between LLM-authored JSON and execution.
3214
+ */
3215
+ declare function compileTaskGraph<TPayload>(inputNodes: readonly TaskGraphInputNode<TPayload>[], options?: CompileTaskGraphOptions): CompiledTaskGraph<TPayload>;
3216
+
3217
+ type SchedulerExecutionMode = 'parallel' | 'sequential';
3218
+ interface SchedulerHooks<TPayload, TResult> {
3219
+ execute(node: TaskGraphNode<TPayload>): Promise<TResult>;
3220
+ onWaveStart?(nodes: readonly TaskGraphNode<TPayload>[], wave: number): void | Promise<void>;
3221
+ onNodeComplete?(node: TaskGraphNode<TPayload>, result: TResult): void | Promise<void>;
3222
+ }
3223
+ interface SchedulerOptions {
3224
+ mode?: SchedulerExecutionMode;
3225
+ }
3226
+ interface SchedulerResult<TResult> {
3227
+ results: ReadonlyMap<string, TResult>;
3228
+ waves: readonly (readonly string[])[];
3229
+ }
3230
+ /**
3231
+ * Shared deterministic dependency scheduler for T1 sections and T2 subtasks.
3232
+ * Graph validation/repair belongs in compileTaskGraph; this class only executes
3233
+ * a valid DAG in stable source order.
3234
+ */
3235
+ declare class DependencyScheduler<TPayload, TResult> {
3236
+ private readonly graph;
3237
+ private readonly hooks;
3238
+ private readonly options;
3239
+ constructor(graph: TaskGraph<TPayload>, hooks: SchedulerHooks<TPayload, TResult>, options?: SchedulerOptions);
3240
+ run(): Promise<SchedulerResult<TResult>>;
3241
+ }
3242
+
3243
+ declare function compileSectionGraph(sections: readonly T1ToT2Assignment[]): CompiledTaskGraph<T1ToT2Assignment>;
3244
+ /**
3245
+ * The subtask fields the graph actually needs. Generic over the whole record so
3246
+ * both the planner's `T3SubtaskSpec` and T2's richer `T2ToT3Assignment` compile
3247
+ * without a cast — they carry the same identity and dependency fields, and the
3248
+ * payload comes back out at its original type.
3249
+ */
3250
+ interface SubtaskGraphInput {
3251
+ subtaskId: string;
3252
+ subtaskTitle: string;
3253
+ dependsOn?: string[];
3254
+ }
3255
+ declare function compileSubtaskGraph<TSubtask extends SubtaskGraphInput>(subtasks: readonly TSubtask[]): CompiledTaskGraph<TSubtask>;
3256
+
3257
+ /**
3258
+ * The deterministic rung of the verification ladder.
3259
+ *
3260
+ * T1 asks the planner for acceptance criteria that are "1-3 checks a reviewer
3261
+ * could verify mechanically (file exists / contains X / command exits 0)", and
3262
+ * the planner obliges — but nothing ever checked them mechanically. Every
3263
+ * criterion went to selfTest(), an LLM call, which is both slower and a worse
3264
+ * judge of "does this file exist" than `stat` is. A grader that hallucinates a
3265
+ * pass on a file that was never written is exactly the failure the criteria
3266
+ * were introduced to prevent.
3267
+ *
3268
+ * So: decide here what can be decided by looking, and hand the rest to the
3269
+ * model unchanged. The governing rule is that **deferring is always safe and
3270
+ * deciding wrongly is not**, so every pattern below is deliberately narrow.
3271
+ * A criterion this module cannot confidently parse comes back `undecidable`
3272
+ * and the LLM grader sees it exactly as it does today.
3273
+ *
3274
+ * Shell criteria ("command exits 0") are deliberately NOT executed. Acceptance
3275
+ * text is LLM-authored and reaches this code as free prose; running it would
3276
+ * turn a plan into an arbitrary command execution channel. Those stay
3277
+ * undecidable.
3278
+ */
3279
+ type AcceptanceVerdict = 'passed' | 'failed' | 'undecidable';
3280
+ interface AcceptanceResult {
3281
+ criterion: string;
3282
+ verdict: AcceptanceVerdict;
3283
+ /** Human-readable reason, present for passed/failed. */
3284
+ detail?: string;
3285
+ }
3286
+ interface AcceptanceProbe {
3287
+ /** null when the path does not exist or is not a regular file. */
3288
+ stat(path: string): Promise<{
3289
+ size: number;
3290
+ } | null>;
3291
+ /** utf-8 contents, or null when unreadable (missing, binary, too large). */
3292
+ read(path: string): Promise<string | null>;
3293
+ }
3294
+ /**
3295
+ * Evaluate acceptance criteria, deciding only the mechanically checkable ones.
3296
+ * Order and length of the result always match `criteria`.
3297
+ */
3298
+ declare function evaluateAcceptance(criteria: readonly string[], ownedFiles: readonly string[], probe: AcceptanceProbe): Promise<AcceptanceResult[]>;
3299
+ /** The criteria that still need a model's judgement. */
3300
+ declare function undecided(results: readonly AcceptanceResult[]): string[];
3301
+ /** Failure messages, phrased so correctOutput can act on them directly. */
3302
+ declare function failures(results: readonly AcceptanceResult[]): string[];
3303
+
3003
3304
  /**
3004
3305
  * High-level SDK entry point — loads config from the workspace and runs a task.
3005
3306
  *
@@ -4032,6 +4333,257 @@ declare class GraphRetriever {
4032
4333
  format(facts: RankedFact[]): string;
4033
4334
  }
4034
4335
 
4336
+ /** File extension (lowercased, no dot), or '' when there is none. */
4337
+ declare function fileExt(name: string): string;
4338
+ /**
4339
+ * Parse CSV/TSV into rows of cells. Handles quoted fields, escaped quotes (""),
4340
+ * and embedded newlines/commas inside quotes. Delimiter is auto-detected from the
4341
+ * extension (tsv → tab) or inferred from the first line. Bounded for safety.
4342
+ */
4343
+ declare function parseDelimited(text: string, name?: string): string[][];
4344
+ /** Chart shapes we can render. Anything else falls back to a table. */
4345
+ type ChartKind = 'bar' | 'line' | 'pie' | 'doughnut' | 'area' | 'scatter';
4346
+ /** Normalise a fence's chart type, or null when it isn't one we can draw. */
4347
+ declare function chartKind(raw: string): ChartKind | null;
4348
+ interface ChartSeries {
4349
+ name: string;
4350
+ values: number[];
4351
+ }
4352
+ /** A chart's data, format-independent. Renderers decide how to draw it. */
4353
+ interface ChartSpec {
4354
+ kind: ChartKind;
4355
+ /** Optional heading, from a leading `title:` line. */
4356
+ title?: string;
4357
+ /** Label for the category axis — the header row's first cell. */
4358
+ categoryName: string;
4359
+ categories: string[];
4360
+ series: ChartSeries[];
4361
+ }
4362
+ /**
4363
+ * Parse a `chart:<kind>` fence body into a ChartSpec.
4364
+ *
4365
+ * Returns null for anything that isn't plausibly chartable (fewer than two
4366
+ * rows, or no series column). The caller then keeps the block as CODE rather
4367
+ * than dropping it, so a malformed chart is visible in the output instead of
4368
+ * silently missing.
4369
+ */
4370
+ declare function parseChartSpec(kind: ChartKind, body: string): ChartSpec | null;
4371
+ /**
4372
+ * The chart's data as table rows — the fallback for every format that cannot
4373
+ * hold a real chart object (Word and PDF; see render.ts).
4374
+ *
4375
+ * Losing the numbers would be strictly worse than the flat table this replaces,
4376
+ * so no renderer is allowed to just skip a chart block.
4377
+ */
4378
+ declare function chartToTableRows(spec: ChartSpec): string[][];
4379
+ type Block = {
4380
+ t: 'heading';
4381
+ level: number;
4382
+ text: string;
4383
+ } | {
4384
+ t: 'para';
4385
+ text: string;
4386
+ } | {
4387
+ t: 'bullet';
4388
+ ordered: boolean;
4389
+ index: number;
4390
+ text: string;
4391
+ } | {
4392
+ t: 'code';
4393
+ lines: string[];
4394
+ } | {
4395
+ t: 'quote';
4396
+ text: string;
4397
+ } | {
4398
+ t: 'table';
4399
+ rows: string[][];
4400
+ } | {
4401
+ t: 'chart';
4402
+ spec: ChartSpec;
4403
+ } | {
4404
+ t: 'hr';
4405
+ };
4406
+ declare function parseBlocks(md: string): Block[];
4407
+ /** One `![alt](url)` reference lifted out of the Markdown. */
4408
+ interface ImageRef {
4409
+ alt: string;
4410
+ url: string;
4411
+ }
4412
+ declare function matchImageLine(s: string): ImageRef | null;
4413
+ /** Format + intrinsic size, sniffed from the bytes. */
4414
+ interface ImageInfo {
4415
+ /** Narrowed to the four raster types docx's ImageRun accepts. */
4416
+ type: 'png' | 'jpg' | 'gif' | 'bmp';
4417
+ mime: string;
4418
+ width: number;
4419
+ height: number;
4420
+ }
4421
+ type LoadedImage = ImageInfo & {
4422
+ bytes: Uint8Array;
4423
+ alt: string;
4424
+ };
4425
+ /**
4426
+ * Read an image's format and pixel dimensions out of its header.
4427
+ *
4428
+ * Both renderers need this and neither can ask a host for it: docx must state
4429
+ * the type and a transformation in pixels up front, and decoding through an
4430
+ * <img> would make the exporter depend on the browser's image pipeline (and
4431
+ * fail under jsdom, and be unavailable in Node entirely). Returns null for
4432
+ * anything we can't measure, which the caller treats as "not embeddable" rather
4433
+ * than guessing a size.
4434
+ */
4435
+ declare function sniffImage(b: Uint8Array): ImageInfo | null;
4436
+ /**
4437
+ * base64 of raw bytes.
4438
+ *
4439
+ * Node's Buffer where it exists (desktop/CLI, and jsdom tests), otherwise a
4440
+ * chunked btoa so a multi-MB image can't blow the call stack through
4441
+ * String.fromCharCode's argument list. Read off globalThis rather than
4442
+ * referenced directly so a browser bundler never tries to resolve `Buffer`.
4443
+ */
4444
+ declare function bytesToBase64(bytes: Uint8Array): string;
4445
+ /** Strip inline Markdown emphasis to plain text (for renderers with no rich runs). */
4446
+ declare function stripInline(s: string): string;
4447
+ /** One styled span of a line, from inlineRuns(). */
4448
+ interface InlineRun {
4449
+ text: string;
4450
+ bold?: boolean;
4451
+ italic?: boolean;
4452
+ code?: boolean;
4453
+ }
4454
+ /**
4455
+ * Split a line's inline emphasis into styled spans.
4456
+ *
4457
+ * Kept format-neutral (plain objects, not docx TextRuns) so the Word renderer
4458
+ * and any future rich-text renderer share one understanding of what `**bold**`
4459
+ * means. A link becomes its "label (url)" text — no renderer here emits real
4460
+ * hyperlinks yet, and dropping the URL would lose information.
4461
+ */
4462
+ declare function inlineRuns(text: string): InlineRun[];
4463
+ interface Slide {
4464
+ title: string;
4465
+ body: string[];
4466
+ images: ImageRef[];
4467
+ charts: ChartSpec[];
4468
+ }
4469
+ /** Split a Markdown deck into slides: on `---` rules, else on top-level headings. */
4470
+ declare function splitSlides(md: string): Slide[];
4471
+ declare function parseSlide(chunk: string): Slide;
4472
+ /**
4473
+ * Pull `chart:` fences out of a source, returning them plus the text with those
4474
+ * fences removed.
4475
+ *
4476
+ * The spreadsheet convention is plain CSV, so a chart block inside an `.xlsx`
4477
+ * source would otherwise be parsed as three junk rows. SheetJS's community
4478
+ * build cannot write a chart OBJECT (see render.ts), so the data instead lands
4479
+ * on its own worksheet — real rows a user can select and chart in one click,
4480
+ * rather than data that vanished.
4481
+ */
4482
+ declare function extractCharts(source: string): {
4483
+ charts: ChartSpec[];
4484
+ rest: string;
4485
+ };
4486
+
4487
+ /** Office formats we can render into a real binary. */
4488
+ type DocumentFormat = 'docx' | 'pptx' | 'xlsx';
4489
+ declare const DOCUMENT_MIME: Record<DocumentFormat, string>;
4490
+ declare function isDocumentFormat(ext: string): ext is DocumentFormat;
4491
+ /**
4492
+ * Resolve a Markdown image URL to raw bytes, or null when it can't be had.
4493
+ *
4494
+ * Returning null rather than throwing is the contract: one dead image must
4495
+ * never cost the user the whole document.
4496
+ */
4497
+ type ImageByteLoader = (url: string) => Promise<Uint8Array | null>;
4498
+ interface RenderOptions {
4499
+ loadImageBytes?: ImageByteLoader;
4500
+ /** Target file name — only used to pick the CSV vs TSV delimiter for xlsx. */
4501
+ name?: string;
4502
+ }
4503
+ /**
4504
+ * CSV → a real `.xlsx` workbook.
4505
+ *
4506
+ * SheetJS's community build can WRITE cells but not chart objects — charts are
4507
+ * not part of the open-source writer's feature set at any version we can
4508
+ * depend on. So a `chart:` block in a spreadsheet source does not become an
4509
+ * Excel chart; its data lands on its own worksheet as ordinary rows, which the
4510
+ * user can select and chart in one click. Dropping it would be the one
4511
+ * genuinely bad option.
4512
+ */
4513
+ declare function renderXlsx(source: string, opts?: RenderOptions): Promise<Uint8Array>;
4514
+ /**
4515
+ * Markdown → a real `.docx`.
4516
+ *
4517
+ * CHART GAP, stated explicitly: the `docx` library exposes no chart API (it
4518
+ * writes WordprocessingML; a Word chart needs a DrawingML chart part plus an
4519
+ * embedded workbook, which the library does not model). A `chart:` block
4520
+ * therefore renders as its title plus a real Word table of the same numbers —
4521
+ * every value preserved, nothing silently dropped. If a caller needs a drawn
4522
+ * chart in Word, the path is to render it to an image first and reference it
4523
+ * with ordinary `![alt](url)` syntax, which this renderer does embed.
4524
+ */
4525
+ declare function renderDocx(md: string, opts?: RenderOptions): Promise<Uint8Array>;
4526
+ /**
4527
+ * Markdown slides → a real `.pptx`.
4528
+ *
4529
+ * A `chart:` block becomes a genuine, editable PowerPoint chart via
4530
+ * `addChart` — the numbers live in the chart part's embedded workbook, so the
4531
+ * user can click Edit Data and see the exact values the model wrote. That is
4532
+ * the whole point of the convention: an image model cannot be trusted to draw
4533
+ * an accurate axis, and a Markdown table isn't a chart.
4534
+ */
4535
+ declare function renderPptx(md: string, opts?: RenderOptions): Promise<Uint8Array>;
4536
+ /**
4537
+ * Render a document source into the real binary for `format`.
4538
+ *
4539
+ * `source` is Markdown for docx, Markdown slides for pptx, and CSV for xlsx —
4540
+ * the same conventions the hosted `file:<name>.<ext>` blocks already use, so a
4541
+ * model that can produce one can produce the other.
4542
+ */
4543
+ declare function renderDocument(format: DocumentFormat, source: string, opts?: RenderOptions): Promise<Uint8Array>;
4544
+
4545
+ /** Reads a workspace file; supplied by the host so tests need no real disk. */
4546
+ type WorkspaceFileReader = (absPath: string) => Promise<Uint8Array>;
4547
+ declare class GenerateDocumentTool extends BaseTool {
4548
+ private readFile;
4549
+ readonly name = "generate_document";
4550
+ readonly description: string;
4551
+ readonly inputSchema: {
4552
+ type: string;
4553
+ properties: {
4554
+ path: {
4555
+ type: string;
4556
+ description: string;
4557
+ };
4558
+ content: {
4559
+ type: string;
4560
+ description: string;
4561
+ };
4562
+ format: {
4563
+ type: string;
4564
+ description: string;
4565
+ };
4566
+ };
4567
+ required: string[];
4568
+ };
4569
+ /**
4570
+ * `readFile` is injected so the image loader is testable and so a host with a
4571
+ * different workspace (not plain disk) can supply its own reader.
4572
+ */
4573
+ constructor(readFile?: WorkspaceFileReader);
4574
+ isDangerous(): boolean;
4575
+ execute(input: Record<string, unknown>, options: ToolExecuteOptions): Promise<string>;
4576
+ }
4577
+ /**
4578
+ * Register the document tool only where there is a workspace to write into.
4579
+ *
4580
+ * Mirrors how buildMediaTools() conditions `transcribe_audio` on a file reader:
4581
+ * a hosted run has no disk, and a tool that always fails is worse than an
4582
+ * absent one — the planner writes steps around it and the run ends in an
4583
+ * apology. The cloud keeps its browser-side exporter instead.
4584
+ */
4585
+ declare function buildDocumentTools(readFile?: WorkspaceFileReader): BaseTool[];
4586
+
4035
4587
  /**
4036
4588
  * Lets a worker search the indexed workspace codebase by meaning + keywords and
4037
4589
  * get back the most relevant passages with their file paths. Backed by the
@@ -4543,4 +5095,4 @@ declare function gatherSyncBundle(config: CascadeConfig): SyncBundle;
4543
5095
  /** Merge a pulled bundle into a config, returning the updated config to persist. */
4544
5096
  declare function applySyncBundle(bundle: SyncBundle, config: CascadeConfig): CascadeConfig;
4545
5097
 
4546
- export { AZURE_BASE_MODELS, AZURE_BASE_URL_TEMPLATE, type ApprovalRequest, type ApprovalResponse, type AuditEntry, AuditLogger, type BenchmarksConfig, type BudgetConfig, CASCADE_AUDIT_FILE, CASCADE_CONFIG_DIR, CASCADE_CONFIG_FILE, CASCADE_DASHBOARD_SECRET_FILE, CASCADE_DB_FILE, CASCADE_IGNORE_FILE, CASCADE_KEYSTORE_FILE, CASCADE_MD_FILE, CASCADE_VERSION, CHARS_PER_TOKEN, COMPLEXITY_T2_COUNT, Cascade, CascadeCancelledError, type CascadeConfig, type CascadeEvent, type CascadeEventType, CascadeIgnore, type CascadeMessage, CascadeRouter, type CascadeRunOptions, type CascadeRunResult, type CascadeThemeName, CascadeToolError, type Chunk, type ChunkOptions, CloudClient, type CloudConversation, type CloudMessage, type CloudSession, type CloudSessionStore, type CloudTurnInput, type CloudUser, type CodeChunkOptions, type CodeChunker, CodeSearchTool, type CompleteFn, ConfigManager, type ConversationMessage, type CurrentPageProvider, type CurrentPageSnapshot, CurrentPageTool, DEFAULT_API_PORT, DEFAULT_APPROVAL_REQUIRED, DEFAULT_AUTO_SUMMARIZE_AT, DEFAULT_CLOUD_URL, DEFAULT_CONTEXT_LIMIT, DEFAULT_DASHBOARD_PORT, DEFAULT_MAX_SESSION_MESSAGES, DEFAULT_RETENTION_DAYS, DEFAULT_THEME, type DashboardConfig, DashboardServer, type DeviceStart, type DiscoveredMcpTool, type DistilledFact, type Embedder, type EncryptedBlob, type EscalationDecision, type EscalationPayload, type ExtendedContextConfig, type FileManifest, FileMcpOAuthStore, GITHUB_MODELS_API_VERSION, GITHUB_MODELS_CATALOG_URL, GITHUB_MODELS_INFERENCE_URL, GLOBAL_CONFIG_DIR, GLOBAL_CREDENTIALS_FILE, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_FILE, GLOBAL_RUNTIME_DB_FILE, type GenerateOptions, type GenerateResult, type GraphFactSource, GraphRetriever, type GraphSearchOptions, GraphSearchTool, type HookDefinition, type HooksConfig, HooksRunner, type Identity, type ImageAttachment, Keystore, LLMReranker, LM_STUDIO_BASE_URL, type LegacyThemeName, MAX_PAGE_TEXT_CHARS, MCP_TOOL_PREFIX, MODELS, type ManifestDiff, McpClient, type McpDiscoveryResult, McpOAuthProvider, type McpOAuthState, type McpOAuthStore, type McpServerConfig$1 as McpServerConfig, type McpServerRename, type MemoryConfig, MemoryStore, type Message, type MessageContent, type MessagePayload, type MessageStatus, type MessageType, type ModelInfo, type ModelOverrides, type NativeProvider, OLLAMA_BASE_URL, OpenAICompatibleEmbedder, type OpenAIEmbedderOptions, PROVIDER_DISPLAY_NAMES, type PeerMessage, type PeerMessageEvent, type PeerSyncPayload, type PeerSyncType, type PermissionDecision, type PermissionDecisionPayload, type PermissionRequest, type PermissionTrailEntry, type PlanReviewConfig, type ProviderConfig, type ProviderType, type RankedFact, type RefreshResult, type Reranker, type RetrievalContext, type RetrievalMode, type RetrievalPlan, Retriever, type RetrieverSearchOptions, type RuntimeNode, type RuntimeNodeLog, type RuntimeRefreshPayload, type RuntimeScope, type RuntimeSession, type RuntimeSnapshotPayload, type ScheduledTask, type ScoredChunk, type SearchOptions, type Session, type SessionCheckpoint, type SessionMetadata, type SessionSubscriptionPayload, SqliteVectorStore, type StatusUpdate, type StoredMessage, type StreamChunk, type SyncBundle, T1Administrator, type T1ToT2Assignment, T1_MODEL_PRIORITY, T2Manager, type T2Result, type T2ToT3Assignment, T2_MODEL_PRIORITY, type T3Result, type T3ResultPayload, type T3SubtaskSpec, T3Worker, T3_MODEL_PRIORITY, THEME_NAMES, TOOL_NAMES, type TaskComplexity, TaskScheduler, Telemetry, type TelemetryConfig, type Theme, type ThemeColors, type ThemeName, type TierConfig, type TierLimits, type TierRole, type TierStatus, type TokenUsage, type ToolCall, type ToolDefinition, type ToolExecuteOptions, ToolRegistry, type ToolResult, type ToolsConfig, VISION_MODEL_PRIORITY, type VectorStore, type WebSearchConfig, type WebhookConfig, type WorkspaceConfig, WorkspaceIndex, type WorkspaceIndexOptions, applySyncBundle, azureModelForDeployment, beginMcpOAuth, buildManifest, buildSessionTranscript, cagCharBudget, chatCompleterFromProviders, chunkCode, chunkText, completeMcpOAuth, connectMcpWithLoopbackOAuth, createCascade, decryptJSON as decryptSyncBlob, diffManifest, disambiguateMcpServerNames, discoverMcpAuthServer, discoverMcpTools, distillSessionFacts, embedderFromProviders, encryptJSON as encryptSyncBlob, fileOAuthProvider, gatherSyncBundle, hashContent, heuristicCodeChunker, inferAzureBaseModel, isMcpToolName, mcpServerPrefix, mcpToolName, nodeHttpFetch, parseRankOrder, planRetrieval, preferIpv4Host, reciprocalRankFusion, refreshMcpToken, removeMcpServerDenials, runCascade, sessionWorthRemembering, streamCascade, uniqueMcpServerName };
5098
+ export { AZURE_BASE_MODELS, AZURE_BASE_URL_TEMPLATE, type AcceptanceProbe, type AcceptanceResult, type AcceptanceVerdict, type ApprovalRequest, type ApprovalResponse, type AuditEntry, AuditLogger, type BenchmarksConfig, type Block, type BudgetConfig, CASCADE_AUDIT_FILE, CASCADE_CONFIG_DIR, CASCADE_CONFIG_FILE, CASCADE_DASHBOARD_SECRET_FILE, CASCADE_DB_FILE, CASCADE_IGNORE_FILE, CASCADE_KEYSTORE_FILE, CASCADE_MD_FILE, CASCADE_VERSION, CHARS_PER_TOKEN, COMPLEXITY_T2_COUNT, Cascade, CascadeCancelledError, type CascadeConfig, type CascadeEvent, type CascadeEventType, CascadeIgnore, type CascadeMessage, CascadeRouter, type CascadeRunOptions, type CascadeRunResult, type CascadeThemeName, CascadeToolError, type ChartSeries, type ChartSpec, type Chunk, type ChunkOptions, CloudClient, type CloudConversation, type CloudMessage, type CloudSession, type CloudSessionStore, type CloudTurnInput, type CloudUser, type CodeChunkOptions, type CodeChunker, CodeSearchTool, type CompileTaskGraphOptions, type CompiledTaskGraph, type CompleteFn, type CompletedNode, ConfigManager, type ConversationMessage, type CurrentPageProvider, type CurrentPageSnapshot, CurrentPageTool, DEFAULT_API_PORT, DEFAULT_APPROVAL_REQUIRED, DEFAULT_AUTO_SUMMARIZE_AT, DEFAULT_CLOUD_URL, DEFAULT_CONTEXT_LIMIT, DEFAULT_DASHBOARD_PORT, DEFAULT_MAX_SESSION_MESSAGES, DEFAULT_RETENTION_DAYS, DEFAULT_THEME, DOCUMENT_MIME, type DashboardConfig, DashboardServer, DependencyScheduler, type DeviceStart, type DiscoveredMcpTool, type DistilledFact, type ChartKind as DocumentChartKind, type DocumentFormat, type Embedder, type EncryptedBlob, type EscalationDecision, type EscalationPayload, type ExtendedContextConfig, type FileManifest, FileMcpOAuthStore, GITHUB_MODELS_API_VERSION, GITHUB_MODELS_CATALOG_URL, GITHUB_MODELS_INFERENCE_URL, GLOBAL_CONFIG_DIR, GLOBAL_CREDENTIALS_FILE, GLOBAL_DB_FILE, GLOBAL_KEYSTORE_FILE, GLOBAL_RUNTIME_DB_FILE, GenerateDocumentTool, type GenerateOptions, type GenerateResult, type GraphFactSource, GraphRetriever, type GraphSearchOptions, GraphSearchTool, type HookDefinition, type HooksConfig, HooksRunner, type Identity, type ImageAttachment, type ImageByteLoader, type ImageInfo, type ImageRef, type InlineRun, Keystore, LLMReranker, LM_STUDIO_BASE_URL, type LegacyThemeName, type LoadedImage, MAX_PAGE_TEXT_CHARS, MCP_TOOL_PREFIX, MODELS, type ManifestDiff, McpClient, type McpDiscoveryResult, McpOAuthProvider, type McpOAuthState, type McpOAuthStore, type McpServerConfig$1 as McpServerConfig, type McpServerRename, type MemoryConfig, MemoryStore, type Message, type MessageContent, type MessagePayload, type MessageStatus, type MessageType, type ModelInfo, type ModelOverrides, type NativeProvider, OLLAMA_BASE_URL, OpenAICompatibleEmbedder, type OpenAIEmbedderOptions, PROVIDER_DISPLAY_NAMES, type PeerMessage, type PeerMessageEvent, type PeerSyncPayload, type PeerSyncType, type PermissionDecision, type PermissionDecisionPayload, type PermissionRequest, type PermissionTrailEntry, type PlanReviewConfig, type ProviderConfig, type ProviderType, RESUME_SCHEMA_VERSION, type RankedFact, type RefreshResult, type RenderOptions, type Reranker, type ResumeCheckpoint, type ResumeReason, ResumeStore, type ResumeStoreOptions, type RetrievalContext, type RetrievalMode, type RetrievalPlan, Retriever, type RetrieverSearchOptions, type RuntimeNode, type RuntimeNodeLog, type RuntimeRefreshPayload, type RuntimeScope, type RuntimeSession, type RuntimeSnapshotPayload, type ScheduledTask, type SchedulerExecutionMode, type SchedulerHooks, type SchedulerOptions, type SchedulerResult, type ScoredChunk, type SearchOptions, type Session, type SessionCheckpoint, type SessionMetadata, type SessionSubscriptionPayload, type Slide, SqliteVectorStore, type StatusUpdate, type StoredMessage, type StreamChunk, type SyncBundle, T1Administrator, type T1ToT2Assignment, T1_MODEL_PRIORITY, T2Manager, type T2Result, type T2ToT3Assignment, T2_MODEL_PRIORITY, type T3Result, type T3ResultPayload, type T3SubtaskSpec, T3Worker, T3_MODEL_PRIORITY, THEME_NAMES, TOOL_NAMES, type TaskComplexity, type TaskGraph, type TaskGraphInputNode, type TaskGraphIssue, type TaskGraphIssueCode, type TaskGraphNode, type TaskGraphNodeKind, TaskGraphValidationError, type TaskGraphValidationMode, TaskScheduler, Telemetry, type TelemetryConfig, type Theme, type ThemeColors, type ThemeName, type TierConfig, type TierLimits, type TierRole, type TierStatus, type TokenUsage, type ToolCall, type ToolDefinition, type ToolExecuteOptions, ToolRegistry, type ToolResult, type ToolsConfig, VISION_MODEL_PRIORITY, type VectorStore, type WebSearchConfig, type WebhookConfig, type WorkspaceConfig, type WorkspaceFileReader, WorkspaceIndex, type WorkspaceIndexOptions, applySyncBundle, azureModelForDeployment, beginMcpOAuth, buildDocumentTools, buildManifest, buildSessionTranscript, bytesToBase64, cagCharBudget, chartKind, chartToTableRows, chatCompleterFromProviders, chunkCode, chunkText, compileSectionGraph, compileSubtaskGraph, compileTaskGraph, completeMcpOAuth, connectMcpWithLoopbackOAuth, createCascade, decryptJSON as decryptSyncBlob, diffManifest, disambiguateMcpServerNames, discoverMcpAuthServer, discoverMcpTools, distillSessionFacts, embedderFromProviders, encryptJSON as encryptSyncBlob, evaluateAcceptance, extractCharts, failures, fileExt, fileOAuthProvider, gatherSyncBundle, hashContent, heuristicCodeChunker, inferAzureBaseModel, inlineRuns, isDocumentFormat, isMcpToolName, matchImageLine, mcpServerPrefix, mcpToolName, nodeHttpFetch, parseBlocks, parseChartSpec, parseDelimited, parseRankOrder, parseSlide, planRetrieval, preferIpv4Host, reciprocalRankFusion, refreshMcpToken, removeMcpServerDenials, renderDocument, renderDocx, renderPptx, renderXlsx, runCascade, sessionWorthRemembering, sniffImage, splitSlides, streamCascade, stripInline, summarizeCompleted, undecided, uniqueMcpServerName };