@wrongstack/core 0.66.13 → 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.
@@ -778,6 +778,23 @@ declare class LargeAnswerStore {
778
778
  clear(): void;
779
779
  }
780
780
 
781
+ /**
782
+ * Director-specific error types. Extracted to keep the Director class
783
+ * focused on orchestration logic.
784
+ */
785
+ declare class FleetSpawnBudgetError extends Error {
786
+ readonly kind: 'max_spawns' | 'max_spawn_depth';
787
+ readonly limit: number;
788
+ readonly observed: number;
789
+ constructor(kind: 'max_spawns' | 'max_spawn_depth', limit: number, observed: number, message?: string);
790
+ }
791
+ declare class FleetCostCapError extends Error {
792
+ readonly kind: 'max_cost_usd';
793
+ readonly limit: number;
794
+ readonly observed: number;
795
+ constructor(limit: number, observed: number);
796
+ }
797
+
781
798
  /**
782
799
  * Director — high-level orchestrator that owns a `MultiAgentCoordinator`,
783
800
  * a `FleetBus`, and a `FleetUsageAggregator`. Exposes a small imperative
@@ -984,30 +1001,7 @@ interface DirectorOptions {
984
1001
  }
985
1002
  /** Either a static matrix or a live getter (re-read on every spawn). */
986
1003
  type ModelMatrixSource = Record<string, ModelMatrixEntry> | (() => Record<string, ModelMatrixEntry> | undefined);
987
- /**
988
- * Thrown by `Director.spawn()` when a configured spawn cap (`maxSpawns`,
989
- * `maxSpawnDepth`) is hit. Distinct error class so callers — including
990
- * the `spawn_subagent` tool surface — can recognize the budget case and
991
- * report it cleanly instead of treating it like an unexpected failure.
992
- */
993
- declare class FleetSpawnBudgetError extends Error {
994
- readonly kind: 'max_spawns' | 'max_spawn_depth';
995
- readonly limit: number;
996
- readonly observed: number;
997
- constructor(kind: 'max_spawns' | 'max_spawn_depth', limit: number, observed: number, message?: string);
998
- }
999
- /**
1000
- * Thrown by `Director.spawn()` when the fleet-wide cost cap is exceeded.
1001
- * Distinct from `FleetSpawnBudgetError` (spawn count/depth) — this is a
1002
- * dollar-denominated ceiling that tracks cumulative spend across all
1003
- * subagents in the fleet.
1004
- */
1005
- declare class FleetCostCapError extends Error {
1006
- readonly kind: 'max_cost_usd';
1007
- readonly limit: number;
1008
- readonly observed: number;
1009
- constructor(limit: number, observed: number);
1010
- }
1004
+
1011
1005
  declare class Director implements ICoordinator {
1012
1006
  /** Alias for the ICoordinator contract. `id` is retained for backward compatibility. */
1013
1007
  get coordinatorId(): string;
package/dist/sdd/index.js CHANGED
@@ -3197,6 +3197,71 @@ function providerStatusToCode(status, type) {
3197
3197
  return ERROR_CODES.PROVIDER_INVALID_REQUEST;
3198
3198
  }
3199
3199
 
3200
+ // src/coordination/coordinator/error-classifier.ts
3201
+ function classifySubagentError(err, hints = {}) {
3202
+ const cause = err instanceof Error ? { name: err.name, message: err.message, stack: err.stack } : void 0;
3203
+ if (err instanceof ProviderError) {
3204
+ const baseMessage2 = err.describe();
3205
+ return providerErrorToSubagentError(err, baseMessage2, cause);
3206
+ }
3207
+ const baseMessage = err instanceof Error ? err.message : String(err);
3208
+ if (err instanceof BudgetExceededError) {
3209
+ const map = {
3210
+ iterations: "budget_iterations",
3211
+ tool_calls: "budget_tool_calls",
3212
+ tokens: "budget_tokens",
3213
+ cost: "budget_cost",
3214
+ timeout: "budget_timeout",
3215
+ idle_timeout: "budget_timeout"
3216
+ };
3217
+ return {
3218
+ kind: map[err.kind],
3219
+ message: baseMessage,
3220
+ retryable: false,
3221
+ cause
3222
+ };
3223
+ }
3224
+ if (hints.parentAborted) {
3225
+ return { kind: "aborted_by_parent", message: baseMessage, retryable: false, cause };
3226
+ }
3227
+ const lower = baseMessage.toLowerCase();
3228
+ if (/agent aborted$/i.test(baseMessage)) {
3229
+ return { kind: "aborted_by_parent", message: baseMessage, retryable: false, cause };
3230
+ }
3231
+ if (/agent exhausted iteration limit$/i.test(baseMessage)) {
3232
+ return { kind: "budget_iterations", message: baseMessage, retryable: false, cause };
3233
+ }
3234
+ if (/empty response$/i.test(baseMessage)) {
3235
+ return { kind: "empty_response", message: baseMessage, retryable: false, cause };
3236
+ }
3237
+ if (/^tool failed: /i.test(baseMessage)) {
3238
+ return { kind: "tool_failed", message: baseMessage, retryable: false, cause };
3239
+ }
3240
+ if (lower.includes("bridge transport") || /bridge.*(closed|disconnect)/i.test(baseMessage)) {
3241
+ return { kind: "bridge_failed", message: baseMessage, retryable: false, cause };
3242
+ }
3243
+ if (/context length|max.*tokens?.*exceeded|prompt is too long/i.test(baseMessage)) {
3244
+ return { kind: "context_overflow", message: baseMessage, retryable: false, cause };
3245
+ }
3246
+ return { kind: "unknown", message: baseMessage, retryable: false, cause };
3247
+ }
3248
+ function providerErrorToSubagentError(err, message, cause) {
3249
+ const status = err.status;
3250
+ if (status === 429 || err.body?.type === "rate_limit_error") {
3251
+ return { kind: "provider_rate_limit", message, retryable: true, backoffMs: 5e3, cause };
3252
+ }
3253
+ if (status === 401 || status === 403 || err.body?.type === "authentication_error") {
3254
+ return { kind: "provider_auth", message, retryable: false, cause };
3255
+ }
3256
+ if (status === 408 || status === 0) {
3257
+ return { kind: "provider_timeout", message, retryable: true, cause };
3258
+ }
3259
+ if (status >= 500 && status < 600) {
3260
+ return { kind: "provider_5xx", message, retryable: true, backoffMs: 3e3, cause };
3261
+ }
3262
+ return { kind: "unknown", message, retryable: err.retryable, cause };
3263
+ }
3264
+
3200
3265
  // src/coordination/agents/types.ts
3201
3266
  var HOUR = 60 * 60 * 1e3;
3202
3267
  var LIGHT_BUDGET = {
@@ -6210,101 +6275,6 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
6210
6275
  return false;
6211
6276
  }
6212
6277
  };
6213
- function classifySubagentError(err, hints = {}) {
6214
- const cause = err instanceof Error ? { name: err.name, message: err.message, stack: err.stack } : void 0;
6215
- if (err instanceof ProviderError) {
6216
- const baseMessage2 = err.describe();
6217
- return providerErrorToSubagentError(err, baseMessage2, cause);
6218
- }
6219
- const baseMessage = err instanceof Error ? err.message : String(err);
6220
- if (err instanceof BudgetExceededError) {
6221
- const map = {
6222
- iterations: "budget_iterations",
6223
- tool_calls: "budget_tool_calls",
6224
- tokens: "budget_tokens",
6225
- cost: "budget_cost",
6226
- timeout: "budget_timeout",
6227
- idle_timeout: "budget_timeout"
6228
- };
6229
- return {
6230
- kind: map[err.kind],
6231
- message: baseMessage,
6232
- // Budgets are user-configured ceilings, not transient failures —
6233
- // retrying with the same budget will hit the same ceiling. The
6234
- // orchestrator must raise the budget or narrow the task first.
6235
- retryable: false,
6236
- cause
6237
- };
6238
- }
6239
- if (hints.parentAborted) {
6240
- return {
6241
- kind: "aborted_by_parent",
6242
- message: baseMessage,
6243
- retryable: false,
6244
- cause
6245
- };
6246
- }
6247
- const lower = baseMessage.toLowerCase();
6248
- if (/agent aborted$/i.test(baseMessage)) {
6249
- return {
6250
- kind: "aborted_by_parent",
6251
- message: baseMessage,
6252
- retryable: false,
6253
- cause
6254
- };
6255
- }
6256
- if (/agent exhausted iteration limit$/i.test(baseMessage)) {
6257
- return { kind: "budget_iterations", message: baseMessage, retryable: false, cause };
6258
- }
6259
- if (/empty response$/i.test(baseMessage)) {
6260
- return { kind: "empty_response", message: baseMessage, retryable: false, cause };
6261
- }
6262
- if (/^tool failed: /i.test(baseMessage)) {
6263
- return { kind: "tool_failed", message: baseMessage, retryable: false, cause };
6264
- }
6265
- if (lower.includes("bridge transport") || /bridge.*(closed|disconnect)/i.test(baseMessage)) {
6266
- return { kind: "bridge_failed", message: baseMessage, retryable: false, cause };
6267
- }
6268
- if (/context length|max.*tokens?.*exceeded|prompt is too long/i.test(baseMessage)) {
6269
- return { kind: "context_overflow", message: baseMessage, retryable: false, cause };
6270
- }
6271
- return {
6272
- kind: "unknown",
6273
- message: baseMessage,
6274
- retryable: false,
6275
- cause
6276
- };
6277
- }
6278
- function providerErrorToSubagentError(err, message, cause) {
6279
- const status = err.status;
6280
- if (status === 429 || err.body?.type === "rate_limit_error") {
6281
- return {
6282
- kind: "provider_rate_limit",
6283
- message,
6284
- retryable: true,
6285
- // Conservative default: 5s. Provider-specific code can override
6286
- // by emitting an error whose body carries an explicit hint.
6287
- backoffMs: 5e3,
6288
- cause
6289
- };
6290
- }
6291
- if (status === 401 || status === 403 || err.body?.type === "authentication_error") {
6292
- return { kind: "provider_auth", message, retryable: false, cause };
6293
- }
6294
- if (status === 408 || status === 0) {
6295
- return { kind: "provider_timeout", message, retryable: true, cause };
6296
- }
6297
- if (status >= 500 && status < 600) {
6298
- return {
6299
- kind: "provider_5xx",
6300
- message,
6301
- retryable: true,
6302
- backoffMs: 3e3,
6303
- cause
6304
- };
6305
- }
6306
- return { kind: "unknown", message, retryable: err.retryable, cause };
6307
- }
6308
6278
 
6309
6279
  // src/sdd/sdd-parallel-run.ts
6310
6280
  var SddParallelRun = class {