cascade-ai 0.71.0 → 0.73.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.cts CHANGED
@@ -1797,6 +1797,33 @@ declare class CascadeRouter extends EventEmitter {
1797
1797
  private sessionCostUsd;
1798
1798
  private runTokens;
1799
1799
  private runCostUsd;
1800
+ /**
1801
+ * Budget held for calls that are IN FLIGHT — admitted by the preflight check
1802
+ * but not yet counted by recordStats. Without these, concurrent calls all
1803
+ * measure themselves against the same unspent allowance and are all admitted.
1804
+ * Released when each call settles; reset by beginRun() alongside the totals.
1805
+ */
1806
+ private reservedTokens;
1807
+ private reservedCostUsd;
1808
+ /**
1809
+ * Fires when this run's budget is spent, cancelling work already in flight.
1810
+ *
1811
+ * The kill switch was previously only a flag, which stops calls that have
1812
+ * not yet submitted. A parallel wave's earlier members are already at the
1813
+ * provider by then, and they carried on generating for a run whose output
1814
+ * would be discarded. Every provider call chains to this, so tripping the
1815
+ * ceiling reaches the requests that are running, not just the ones queued.
1816
+ */
1817
+ private runAbort;
1818
+ /**
1819
+ * Bumped by every beginRun(). A release handle remembers the generation it
1820
+ * was issued in and does nothing if that has moved on: beginRun() zeroes the
1821
+ * counters, so a call still in flight from the previous run would otherwise
1822
+ * subtract its estimate from the NEW run's totals and drive them negative —
1823
+ * leaving later preflights believing there is more allowance than the cap
1824
+ * actually holds, which is worse than no gate at all.
1825
+ */
1826
+ private runGeneration;
1800
1827
  private runBudgetExceeded;
1801
1828
  private runBudgetExceededReason;
1802
1829
  /**
@@ -2046,6 +2073,13 @@ declare class CascadeRouter extends EventEmitter {
2046
2073
  private getProvider;
2047
2074
  private createProvider;
2048
2075
  private getAnyModelForProvider;
2076
+ /**
2077
+ * `runGeneration` is the generation the call was ADMITTED in — see
2078
+ * `generate()`. Session-wide accounting always applies (the spend is real
2079
+ * whenever it lands), but the per-RUN ceiling is only meaningful for the run
2080
+ * the call belongs to, so a straggler from a finished run is left out of it.
2081
+ * Omitted by the direct callers in tests, which have no run to straddle.
2082
+ */
2049
2083
  private recordStats;
2050
2084
  /**
2051
2085
  * Resets per-run accounting at the start of each `cascade run`. Session
@@ -2053,6 +2087,60 @@ declare class CascadeRouter extends EventEmitter {
2053
2087
  * per-task ceiling is cleared so the next task starts with a fresh allowance.
2054
2088
  */
2055
2089
  beginRun(): void;
2090
+ /**
2091
+ * Refuse a call whose input alone cannot fit what is left of the run budget.
2092
+ *
2093
+ * `enforceRunBudget()` below runs AFTER a call returns, which makes the caps
2094
+ * a stop rather than a pre-authorisation: the tokens are already bought by
2095
+ * the time it looks. That was tolerable while a prompt could not exceed
2096
+ * 20,000 characters, and stopped being so when that cap was removed in
2097
+ * 0.72.0 — a multi-megabyte prompt is billed in full on the very first call
2098
+ * (the complexity classifier sends the whole thing), and no ceiling
2099
+ * configured downstream can give that money back.
2100
+ *
2101
+ * Deliberately narrow, because a false refusal is worse than a late stop:
2102
+ *
2103
+ * • INPUT ONLY. What a call returns is not knowable in advance, and
2104
+ * charging a worst-case `maxTokens` of output against the budget would
2105
+ * decline runs that would have finished comfortably. Input is the part
2106
+ * that is already determined, and it is the part the removed cap used to
2107
+ * bound.
2108
+ * • Compared against what REMAINS (`cap - spent`), not the whole cap, so a
2109
+ * call is judged on the budget it can actually draw from.
2110
+ * • Skipped when the model has no usable price. An estimate cannot be made,
2111
+ * and refusing on ignorance would break every self-hosted and local model
2112
+ * the moment a cost cap is set. The post-hoc stop still applies there.
2113
+ * • Skipped entirely when no cap is configured — there is nothing to
2114
+ * pre-authorise against.
2115
+ *
2116
+ * The message names the cap AND the estimate, because "too expensive" with
2117
+ * no numbers gives the user nothing to change.
2118
+ */
2119
+ private enforcePreflightBudget;
2120
+ /**
2121
+ * What this call will send, in tokens.
2122
+ *
2123
+ * Text is the bulk of it, but not all of it: providers bill the serialized
2124
+ * TOOL DEFINITIONS on every native-tool call (Anthropic sends each name,
2125
+ * description and input schema), and an image is billed by its own size
2126
+ * rather than as the `[image]` placeholder `contentToText` reduces it to. A
2127
+ * tool-heavy or vision request could therefore pass either cap while its real
2128
+ * input already exceeded the allowance.
2129
+ */
2130
+ private estimateInputTokens;
2131
+ /**
2132
+ * Report a wait that ended because something asked it to stop, the same way
2133
+ * the provider call below reports one.
2134
+ *
2135
+ * The queue waits sit OUTSIDE the try/catch that maps aborts, so without
2136
+ * this a cancellation surfaced as whatever the queue happened to throw and
2137
+ * was retried or failed over like an ordinary error. A budget abort keeps
2138
+ * saying it ran out of budget — otherwise the reason the run stopped is lost
2139
+ * on the way up — and anything else that was aborted becomes a cancellation.
2140
+ */
2141
+ private asAbortFailure;
2142
+ /** Trips the same run-level flag a post-hoc overrun does, and reports it the same way. */
2143
+ private failPreflight;
2056
2144
  /**
2057
2145
  * Enforce the hard per-task ceiling. Once tripped, the flag makes every
2058
2146
  * subsequent (and concurrent) generate() call in this run fail fast.
@@ -2179,6 +2267,16 @@ declare class ToolRegistry extends EventEmitter {
2179
2267
  private plugins;
2180
2268
  constructor(config: ToolsConfig, workspaceRoot?: string);
2181
2269
  register(tool: BaseTool): void;
2270
+ /**
2271
+ * The directory every registered tool resolves relative paths against.
2272
+ *
2273
+ * Exposed so a caller that has to reason about a file a tool WROTE can look
2274
+ * in the same place the tool wrote it. `process.cwd()` is not that place
2275
+ * outside a plain CLI run: the hosted server's cwd is the app directory
2276
+ * while the run's workspace is the tenant's scratch dir, and Electron's cwd
2277
+ * is the app bundle rather than the user's chosen folder.
2278
+ */
2279
+ getWorkspaceRoot(): string;
2182
2280
  /**
2183
2281
  * Wait until a named tool is registered, resolving immediately if it already exists.
2184
2282
  * T3 workers can call this after encountering a missing-tool error to resume
@@ -3033,6 +3131,7 @@ interface BroadcastMessage {
3033
3131
  timestamp: string;
3034
3132
  }
3035
3133
  declare class PeerBus extends EventEmitter {
3134
+ constructor();
3036
3135
  private outputs;
3037
3136
  private waiters;
3038
3137
  private members;
@@ -3294,6 +3393,20 @@ declare class T3Worker extends BaseTier {
3294
3393
  */
3295
3394
  private coordinateFileIntents;
3296
3395
  private requiresArtifact;
3396
+ /**
3397
+ * Where a file a tool wrote actually lives.
3398
+ *
3399
+ * This used to be `process.cwd()`, which is only the workspace in a plain
3400
+ * CLI run. The hosted server runs with cwd at the app directory while the
3401
+ * run's workspace is the tenant's scratch dir, and Electron's cwd is the app
3402
+ * bundle rather than the folder the user picked. So the tool wrote
3403
+ * `<workspace>/report.docx`, verification stat'd `<cwd>/report.docx`, found
3404
+ * nothing, and the worker looped and then threw WorkerStallError — surfacing
3405
+ * as "no file was created" on a file that had in fact been created, followed
3406
+ * by a failed node. Asking the registry is exact: it is the same root every
3407
+ * registered tool was configured with (registry.registerDefaults).
3408
+ */
3409
+ private artifactRoot;
3297
3410
  private extractArtifactPaths;
3298
3411
  private verifyArtifacts;
3299
3412
  /**
package/dist/index.d.ts CHANGED
@@ -1797,6 +1797,33 @@ declare class CascadeRouter extends EventEmitter {
1797
1797
  private sessionCostUsd;
1798
1798
  private runTokens;
1799
1799
  private runCostUsd;
1800
+ /**
1801
+ * Budget held for calls that are IN FLIGHT — admitted by the preflight check
1802
+ * but not yet counted by recordStats. Without these, concurrent calls all
1803
+ * measure themselves against the same unspent allowance and are all admitted.
1804
+ * Released when each call settles; reset by beginRun() alongside the totals.
1805
+ */
1806
+ private reservedTokens;
1807
+ private reservedCostUsd;
1808
+ /**
1809
+ * Fires when this run's budget is spent, cancelling work already in flight.
1810
+ *
1811
+ * The kill switch was previously only a flag, which stops calls that have
1812
+ * not yet submitted. A parallel wave's earlier members are already at the
1813
+ * provider by then, and they carried on generating for a run whose output
1814
+ * would be discarded. Every provider call chains to this, so tripping the
1815
+ * ceiling reaches the requests that are running, not just the ones queued.
1816
+ */
1817
+ private runAbort;
1818
+ /**
1819
+ * Bumped by every beginRun(). A release handle remembers the generation it
1820
+ * was issued in and does nothing if that has moved on: beginRun() zeroes the
1821
+ * counters, so a call still in flight from the previous run would otherwise
1822
+ * subtract its estimate from the NEW run's totals and drive them negative —
1823
+ * leaving later preflights believing there is more allowance than the cap
1824
+ * actually holds, which is worse than no gate at all.
1825
+ */
1826
+ private runGeneration;
1800
1827
  private runBudgetExceeded;
1801
1828
  private runBudgetExceededReason;
1802
1829
  /**
@@ -2046,6 +2073,13 @@ declare class CascadeRouter extends EventEmitter {
2046
2073
  private getProvider;
2047
2074
  private createProvider;
2048
2075
  private getAnyModelForProvider;
2076
+ /**
2077
+ * `runGeneration` is the generation the call was ADMITTED in — see
2078
+ * `generate()`. Session-wide accounting always applies (the spend is real
2079
+ * whenever it lands), but the per-RUN ceiling is only meaningful for the run
2080
+ * the call belongs to, so a straggler from a finished run is left out of it.
2081
+ * Omitted by the direct callers in tests, which have no run to straddle.
2082
+ */
2049
2083
  private recordStats;
2050
2084
  /**
2051
2085
  * Resets per-run accounting at the start of each `cascade run`. Session
@@ -2053,6 +2087,60 @@ declare class CascadeRouter extends EventEmitter {
2053
2087
  * per-task ceiling is cleared so the next task starts with a fresh allowance.
2054
2088
  */
2055
2089
  beginRun(): void;
2090
+ /**
2091
+ * Refuse a call whose input alone cannot fit what is left of the run budget.
2092
+ *
2093
+ * `enforceRunBudget()` below runs AFTER a call returns, which makes the caps
2094
+ * a stop rather than a pre-authorisation: the tokens are already bought by
2095
+ * the time it looks. That was tolerable while a prompt could not exceed
2096
+ * 20,000 characters, and stopped being so when that cap was removed in
2097
+ * 0.72.0 — a multi-megabyte prompt is billed in full on the very first call
2098
+ * (the complexity classifier sends the whole thing), and no ceiling
2099
+ * configured downstream can give that money back.
2100
+ *
2101
+ * Deliberately narrow, because a false refusal is worse than a late stop:
2102
+ *
2103
+ * • INPUT ONLY. What a call returns is not knowable in advance, and
2104
+ * charging a worst-case `maxTokens` of output against the budget would
2105
+ * decline runs that would have finished comfortably. Input is the part
2106
+ * that is already determined, and it is the part the removed cap used to
2107
+ * bound.
2108
+ * • Compared against what REMAINS (`cap - spent`), not the whole cap, so a
2109
+ * call is judged on the budget it can actually draw from.
2110
+ * • Skipped when the model has no usable price. An estimate cannot be made,
2111
+ * and refusing on ignorance would break every self-hosted and local model
2112
+ * the moment a cost cap is set. The post-hoc stop still applies there.
2113
+ * • Skipped entirely when no cap is configured — there is nothing to
2114
+ * pre-authorise against.
2115
+ *
2116
+ * The message names the cap AND the estimate, because "too expensive" with
2117
+ * no numbers gives the user nothing to change.
2118
+ */
2119
+ private enforcePreflightBudget;
2120
+ /**
2121
+ * What this call will send, in tokens.
2122
+ *
2123
+ * Text is the bulk of it, but not all of it: providers bill the serialized
2124
+ * TOOL DEFINITIONS on every native-tool call (Anthropic sends each name,
2125
+ * description and input schema), and an image is billed by its own size
2126
+ * rather than as the `[image]` placeholder `contentToText` reduces it to. A
2127
+ * tool-heavy or vision request could therefore pass either cap while its real
2128
+ * input already exceeded the allowance.
2129
+ */
2130
+ private estimateInputTokens;
2131
+ /**
2132
+ * Report a wait that ended because something asked it to stop, the same way
2133
+ * the provider call below reports one.
2134
+ *
2135
+ * The queue waits sit OUTSIDE the try/catch that maps aborts, so without
2136
+ * this a cancellation surfaced as whatever the queue happened to throw and
2137
+ * was retried or failed over like an ordinary error. A budget abort keeps
2138
+ * saying it ran out of budget — otherwise the reason the run stopped is lost
2139
+ * on the way up — and anything else that was aborted becomes a cancellation.
2140
+ */
2141
+ private asAbortFailure;
2142
+ /** Trips the same run-level flag a post-hoc overrun does, and reports it the same way. */
2143
+ private failPreflight;
2056
2144
  /**
2057
2145
  * Enforce the hard per-task ceiling. Once tripped, the flag makes every
2058
2146
  * subsequent (and concurrent) generate() call in this run fail fast.
@@ -2179,6 +2267,16 @@ declare class ToolRegistry extends EventEmitter {
2179
2267
  private plugins;
2180
2268
  constructor(config: ToolsConfig, workspaceRoot?: string);
2181
2269
  register(tool: BaseTool): void;
2270
+ /**
2271
+ * The directory every registered tool resolves relative paths against.
2272
+ *
2273
+ * Exposed so a caller that has to reason about a file a tool WROTE can look
2274
+ * in the same place the tool wrote it. `process.cwd()` is not that place
2275
+ * outside a plain CLI run: the hosted server's cwd is the app directory
2276
+ * while the run's workspace is the tenant's scratch dir, and Electron's cwd
2277
+ * is the app bundle rather than the user's chosen folder.
2278
+ */
2279
+ getWorkspaceRoot(): string;
2182
2280
  /**
2183
2281
  * Wait until a named tool is registered, resolving immediately if it already exists.
2184
2282
  * T3 workers can call this after encountering a missing-tool error to resume
@@ -3033,6 +3131,7 @@ interface BroadcastMessage {
3033
3131
  timestamp: string;
3034
3132
  }
3035
3133
  declare class PeerBus extends EventEmitter {
3134
+ constructor();
3036
3135
  private outputs;
3037
3136
  private waiters;
3038
3137
  private members;
@@ -3294,6 +3393,20 @@ declare class T3Worker extends BaseTier {
3294
3393
  */
3295
3394
  private coordinateFileIntents;
3296
3395
  private requiresArtifact;
3396
+ /**
3397
+ * Where a file a tool wrote actually lives.
3398
+ *
3399
+ * This used to be `process.cwd()`, which is only the workspace in a plain
3400
+ * CLI run. The hosted server runs with cwd at the app directory while the
3401
+ * run's workspace is the tenant's scratch dir, and Electron's cwd is the app
3402
+ * bundle rather than the folder the user picked. So the tool wrote
3403
+ * `<workspace>/report.docx`, verification stat'd `<cwd>/report.docx`, found
3404
+ * nothing, and the worker looped and then threw WorkerStallError — surfacing
3405
+ * as "no file was created" on a file that had in fact been created, followed
3406
+ * by a failed node. Asking the registry is exact: it is the same root every
3407
+ * registered tool was configured with (registry.registerDefaults).
3408
+ */
3409
+ private artifactRoot;
3297
3410
  private extractArtifactPaths;
3298
3411
  private verifyArtifacts;
3299
3412
  /**