@wrongstack/core 0.9.20 → 0.10.2

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.
Files changed (67) hide show
  1. package/README.md +37 -33
  2. package/dist/{agent-bridge-Dti3KXGk.d.ts → agent-bridge-DBBGP5O4.d.ts} +1 -1
  3. package/dist/{agent-subagent-runner-U-rs7kk7.d.ts → agent-subagent-runner-KwufTWwn.d.ts} +3 -3
  4. package/dist/{compactor-D7X96RLZ.d.ts → compactor-D1RHFRmF.d.ts} +1 -1
  5. package/dist/{config-CLXMDOSs.d.ts → config-CJXBka2r.d.ts} +38 -2
  6. package/dist/{context-zkZeILpr.d.ts → context-7u93AcGD.d.ts} +94 -0
  7. package/dist/coordination/index.d.ts +12 -12
  8. package/dist/coordination/index.js +130 -58
  9. package/dist/coordination/index.js.map +1 -1
  10. package/dist/{default-config-Uzla85H-.d.ts → default-config-DEXI4jsl.d.ts} +10 -1
  11. package/dist/defaults/index.d.ts +24 -24
  12. package/dist/defaults/index.js +611 -95
  13. package/dist/defaults/index.js.map +1 -1
  14. package/dist/{events-DH-9r-_C.d.ts → events-Bw1K5E6K.d.ts} +8 -1
  15. package/dist/execution/index.d.ts +18 -15
  16. package/dist/execution/index.js +309 -61
  17. package/dist/execution/index.js.map +1 -1
  18. package/dist/extension/index.d.ts +6 -6
  19. package/dist/extension/index.js.map +1 -1
  20. package/dist/goal-store-BeRsj7YX.d.ts +188 -0
  21. package/dist/{index-CFO9QmJo.d.ts → index-DIt5TIaF.d.ts} +8 -8
  22. package/dist/{index-BIHJ4uII.d.ts → index-DgQWnZxP.d.ts} +5 -5
  23. package/dist/index.d.ts +56 -35
  24. package/dist/index.js +742 -203
  25. package/dist/index.js.map +1 -1
  26. package/dist/infrastructure/index.d.ts +6 -6
  27. package/dist/kernel/index.d.ts +9 -9
  28. package/dist/kernel/index.js +57 -8
  29. package/dist/kernel/index.js.map +1 -1
  30. package/dist/{mcp-servers-DkESgh0G.d.ts → mcp-servers-BgINZzuo.d.ts} +3 -3
  31. package/dist/models/index.d.ts +3 -3
  32. package/dist/models/index.js +163 -10
  33. package/dist/models/index.js.map +1 -1
  34. package/dist/models-registry-gwMAo6E3.d.ts +86 -0
  35. package/dist/{multi-agent-DNp6lAzg.d.ts → multi-agent-C1O8EFzb.d.ts} +45 -4
  36. package/dist/{multi-agent-coordinator-CAhsegPz.d.ts → multi-agent-coordinator-DoVSBFNx.d.ts} +2 -2
  37. package/dist/{null-fleet-bus-Dnl19vmf.d.ts → null-fleet-bus-T-s3JaOt.d.ts} +8 -6
  38. package/dist/observability/index.d.ts +2 -2
  39. package/dist/{path-resolver-CHiBL0DD.d.ts → path-resolver-BfyK-I7w.d.ts} +2 -2
  40. package/dist/{permission-H35s9Evv.d.ts → permission-B6sldrSp.d.ts} +1 -1
  41. package/dist/{permission-policy-CT-nRmTn.d.ts → permission-policy-CtNscWOA.d.ts} +10 -9
  42. package/dist/{plan-templates-Bs8iRwi6.d.ts → plan-templates-BWs6Je7j.d.ts} +8 -8
  43. package/dist/{provider-runner-BZdDrWrS.d.ts → provider-runner-BmPe2RuU.d.ts} +3 -3
  44. package/dist/{retry-policy-J9N_PM40.d.ts → retry-policy-KF18W4dg.d.ts} +1 -1
  45. package/dist/sdd/index.d.ts +8 -8
  46. package/dist/sdd/index.js +130 -58
  47. package/dist/sdd/index.js.map +1 -1
  48. package/dist/security/index.d.ts +65 -4
  49. package/dist/security/index.js +67 -19
  50. package/dist/security/index.js.map +1 -1
  51. package/dist/{selector-CFTh3Z6p.d.ts → selector-DmXxpFyM.d.ts} +1 -1
  52. package/dist/{session-reader-C7JJlxOw.d.ts → session-reader-CCSBfQmd.d.ts} +1 -1
  53. package/dist/storage/index.d.ts +7 -7
  54. package/dist/storage/index.js +125 -6
  55. package/dist/storage/index.js.map +1 -1
  56. package/dist/{system-prompt-CneIxVip.d.ts → system-prompt-CM6zOhd2.d.ts} +19 -1
  57. package/dist/{tool-executor-flTuxsqO.d.ts → tool-executor-D7RxLtg4.d.ts} +4 -4
  58. package/dist/types/index.d.ts +16 -16
  59. package/dist/types/index.js +344 -14
  60. package/dist/types/index.js.map +1 -1
  61. package/dist/utils/index.d.ts +23 -3
  62. package/dist/utils/index.js +66 -1
  63. package/dist/utils/index.js.map +1 -1
  64. package/dist/{wstack-paths-BCgmTNlG.d.ts → wstack-paths-eMXnY1_X.d.ts} +8 -0
  65. package/package.json +1 -1
  66. package/dist/goal-store-C7jcumEh.d.ts +0 -96
  67. package/dist/models-registry-OG_30xqZ.d.ts +0 -46
@@ -1,4 +1,4 @@
1
- import { T as TextBlock, c as ContentBlock, Q as Tool } from './context-zkZeILpr.js';
1
+ import { T as TextBlock, c as ContentBlock, Q as Tool } from './context-7u93AcGD.js';
2
2
 
3
3
  /**
4
4
  * Container — dependency injection with explicit bind / override / decorate.
@@ -19,10 +19,28 @@ interface BindOptions {
19
19
  }
20
20
  declare class Container {
21
21
  private readonly entries;
22
+ /**
23
+ * Tokens currently mid-resolve. Tracked so we can detect circular
24
+ * dependencies (A → B → A) and throw a structured error instead of
25
+ * overflowing the call stack with "Maximum call stack size exceeded".
26
+ *
27
+ * Not a memoization cache — the per-entry `cache` field is the source
28
+ * of truth for "have I built this before?". This set only lives for
29
+ * the duration of a single resolve call.
30
+ */
31
+ private readonly resolving;
22
32
  bind<T>(token: Token<T>, factory: Factory<T>, opts?: BindOptions): void;
23
33
  override<T>(token: Token<T>, factory: Factory<T>, opts?: BindOptions): void;
24
34
  decorate<T>(token: Token<T>, decorator: Decorator<T>, owner?: string): void;
25
35
  resolve<T>(token: Token<T>): T;
36
+ /**
37
+ * Build a human-readable description of the dependency cycle that
38
+ * caused the resolution to re-enter. Lists the tokens in the order
39
+ * they were entered, then appends the re-entered token to close the
40
+ * loop. Falls back to a generic message if the resolving set is
41
+ * somehow empty (shouldn't happen, but defensive).
42
+ */
43
+ private describeCycle;
26
44
  has<T>(token: Token<T>): boolean;
27
45
  ownerOf<T>(token: Token<T>): string | undefined;
28
46
  /**
@@ -1,8 +1,8 @@
1
- import { d as Context, n as ProviderError, Q as Tool, _ as ToolUseBlock, Y as ToolResultBlock } from './context-zkZeILpr.js';
2
- import { a as Compactor, C as CompactReport } from './compactor-D7X96RLZ.js';
3
- import { R as RecoveryDecision, E as ErrorHandler, a as RetryPolicy } from './retry-policy-J9N_PM40.js';
1
+ import { d as Context, n as ProviderError, Q as Tool, _ as ToolUseBlock, Y as ToolResultBlock } from './context-7u93AcGD.js';
2
+ import { a as Compactor, C as CompactReport } from './compactor-D1RHFRmF.js';
3
+ import { R as RecoveryDecision, E as ErrorHandler, a as RetryPolicy } from './retry-policy-KF18W4dg.js';
4
4
  import { b as ModelsRegistry } from './models-registry-BcYJDKLm.js';
5
- import { y as ToolExecutorOptions, z as ToolExecutorStrategy, T as ToolBatchResult } from './index-BIHJ4uII.js';
5
+ import { y as ToolExecutorOptions, z as ToolExecutorStrategy, T as ToolBatchResult } from './index-DgQWnZxP.js';
6
6
 
7
7
  interface CompactorOptions {
8
8
  preserveK?: number;
@@ -1,29 +1,29 @@
1
- export { A as AgentError, a as Capabilities, b as ConfigError, c as ContentBlock, E as ERROR_CODES, g as ErrorCode, h as ErrorSeverity, i as ErrorSubsystem, F as FileSnapshot, j as FsError, I as ImageBlock, J as JSONSchema, M as Message, k as MessageRole, P as Permission, l as PluginError, m as Provider, n as ProviderError, o as ProviderErrorBody, p as Request, q as Response, r as ResumedSession, s as RiskTier, S as SessionData, v as SessionError, w as SessionEvent, x as SessionMetadata, y as SessionStore, z as SessionSummary, B as SessionWriter, H as StopReason, K as StreamEvent, T as TextBlock, L as ThinkingBlock, Q as Tool, U as ToolCallContext, V as ToolError, W as ToolFinalEvent, X as ToolProgressEvent, Y as ToolResultBlock, Z as ToolStreamEvent, _ as ToolUseBlock, $ as Usage, a0 as WrongStackError, a1 as asBlocks, a2 as asText, a4 as isAgentError, a5 as isConfigError, a6 as isFsError, a7 as isImageBlock, a8 as isPluginError, a9 as isSessionError, aa as isTextBlock, ab as isThinkingBlock, ac as isToolError, ad as isToolResultBlock, ae as isToolUseBlock, af as isWrongStackError, ag as toWrongStackError } from '../context-zkZeILpr.js';
2
- export { P as ProviderRunner, R as RunProviderOptions } from '../provider-runner-BZdDrWrS.js';
3
- export { A as AutonomyConfig, C as CONTEXT_WINDOW_MODES, a as Config, b as ConfigLoader, c as ConfigStore, d as ContextConfig, e as ContextWindowAggressiveOn, f as ContextWindowConfigLike, g as ContextWindowMode, h as ContextWindowModeId, i as ContextWindowPolicy, j as ContextWindowThresholds, D as DEFAULT_CONTEXT_WINDOW_MODE_ID, F as FeaturesConfig, L as LogConfig, M as MCPServerConfig, P as PluginConfig, k as ProviderApiKey, l as ProviderConfig, S as SyncCategory, m as SyncConfig, T as ToolsConfig, n as formatContextWindowModeList, o as getContextWindowMode, p as isContextWindowModeId, q as listContextWindowModes, r as resolveContextWindowPolicy } from '../config-CLXMDOSs.js';
4
- export { C as CompactReport, a as Compactor } from '../compactor-D7X96RLZ.js';
5
- export { P as PermissionDecision, a as PermissionPolicy, T as TrustPolicy } from '../permission-H35s9Evv.js';
1
+ export { A as AgentError, a as Capabilities, b as ConfigError, c as ContentBlock, E as ERROR_CODES, g as ErrorCode, h as ErrorSeverity, i as ErrorSubsystem, F as FileSnapshot, j as FsError, I as ImageBlock, J as JSONSchema, M as Message, k as MessageRole, P as Permission, l as PluginError, m as Provider, n as ProviderError, o as ProviderErrorBody, p as Request, q as Response, r as ResumedSession, s as RiskTier, S as SessionData, v as SessionError, w as SessionEvent, x as SessionMetadata, y as SessionStore, z as SessionSummary, B as SessionWriter, H as StopReason, K as StreamEvent, T as TextBlock, L as ThinkingBlock, Q as Tool, U as ToolCallContext, V as ToolError, W as ToolFinalEvent, X as ToolProgressEvent, Y as ToolResultBlock, Z as ToolStreamEvent, _ as ToolUseBlock, $ as Usage, a0 as WrongStackError, a1 as asBlocks, a2 as asText, a4 as isAgentError, a5 as isConfigError, a6 as isFsError, a7 as isImageBlock, a8 as isPluginError, a9 as isSessionError, aa as isTextBlock, ab as isThinkingBlock, ac as isToolError, ad as isToolResultBlock, ae as isToolUseBlock, af as isWrongStackError, ag as toWrongStackError } from '../context-7u93AcGD.js';
2
+ export { P as ProviderRunner, R as RunProviderOptions } from '../provider-runner-BmPe2RuU.js';
3
+ export { A as AutonomyConfig, C as CONTEXT_WINDOW_MODES, a as Config, b as ConfigLoader, c as ConfigStore, d as ContextConfig, e as ContextWindowAggressiveOn, f as ContextWindowConfigLike, g as ContextWindowMode, h as ContextWindowModeId, i as ContextWindowPolicy, j as ContextWindowThresholds, D as DEFAULT_CONTEXT_WINDOW_MODE_ID, F as FeaturesConfig, L as LogConfig, M as MCPServerConfig, P as PluginConfig, k as ProviderApiKey, l as ProviderConfig, S as SessionLoggingConfig, m as SyncCategory, n as SyncConfig, T as ToolsConfig, o as formatContextWindowModeList, p as getContextWindowMode, q as isContextWindowModeId, r as listContextWindowModes, s as resolveContextWindowPolicy } from '../config-CJXBka2r.js';
4
+ export { C as CompactReport, a as Compactor } from '../compactor-D1RHFRmF.js';
5
+ export { P as PermissionDecision, a as PermissionPolicy, T as TrustPolicy } from '../permission-B6sldrSp.js';
6
6
  export { C as CheckpointInfo, R as RewindResult, a as RewindResultExtended, S as SessionRewinder } from '../session-rewinder-C9HnMkhP.js';
7
- export { A as AddAttachmentInput, a as Attachment, b as AttachmentKind, c as AttachmentMeta, d as AttachmentRef, e as AttachmentStore, D as DefaultSessionReader } from '../session-reader-C7JJlxOw.js';
8
- export { D as DEFAULT_AUTONOMY_CONFIG, a as DEFAULT_CONTEXT_CONFIG, b as DEFAULT_TOOLS_CONFIG } from '../default-config-Uzla85H-.js';
7
+ export { A as AddAttachmentInput, a as Attachment, b as AttachmentKind, c as AttachmentMeta, d as AttachmentRef, e as AttachmentStore, D as DefaultSessionReader } from '../session-reader-CCSBfQmd.js';
8
+ export { D as DEFAULT_AUTONOMY_CONFIG, a as DEFAULT_CONTEXT_CONFIG, b as DEFAULT_SESSION_LOGGING_CONFIG, c as DEFAULT_TOOLS_CONFIG } from '../default-config-DEXI4jsl.js';
9
9
  export { D as DefaultSecretScrubber, a as DefaultSecretVault, S as SecretVaultOptions, d as decryptConfigSecrets, e as encryptConfigSecrets, m as migratePlaintextSecrets, r as rewriteConfigEncrypted } from '../secret-scrubber-7rSC_emZ.js';
10
10
  export { D as DefaultLogger, a as DefaultLoggerOptions } from '../logger-bOzkF5LL.js';
11
- export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-CHiBL0DD.js';
11
+ export { D as DefaultPathResolver, a as DefaultTokenCounter } from '../path-resolver-BfyK-I7w.js';
12
12
  export { M as MemoryEntry, a as MemoryScope, b as MemoryStore } from '../memory-CEXuo7sz.js';
13
- export { C as CompactorOptions, D as DEFAULT_RECOVERY_STRATEGIES, a as DefaultErrorHandler, b as DefaultRetryPolicy, H as HybridCompactor, R as RecoveryStrategy, T as ToolExecutor, c as buildRecoveryStrategies } from '../tool-executor-flTuxsqO.js';
13
+ export { C as CompactorOptions, D as DEFAULT_RECOVERY_STRATEGIES, a as DefaultErrorHandler, b as DefaultRetryPolicy, H as HybridCompactor, R as RecoveryStrategy, T as ToolExecutor, c as buildRecoveryStrategies } from '../tool-executor-D7RxLtg4.js';
14
14
  export { S as SkillEntry, a as SkillLoader, b as SkillManifest } from '../skill-CxuWrsKK.js';
15
- export { a as BuildContext, c as ModelCapabilities, e as Renderer, S as SystemPromptBuilder } from '../system-prompt-CneIxVip.js';
15
+ export { a as BuildContext, c as ModelCapabilities, e as Renderer, S as SystemPromptBuilder } from '../system-prompt-CM6zOhd2.js';
16
16
  export { I as InputReader, P as PromptOption } from '../input-reader-E-ffP2ee.js';
17
- export { M as MCPRegistryView, j as MetricsSinkView, P as Plugin, k as PluginAPI, l as PluginCapabilities, m as PluginDependency, n as PluginPipelines, o as ProviderFactory, r as ProviderRegistryView, S as SessionWriterView, u as SlashCommand, v as SlashCommandRegistryView, w as SystemPromptContributor, F as ToolRegistryView } from '../index-BIHJ4uII.js';
18
- export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-OG_30xqZ.js';
17
+ export { M as MCPRegistryView, j as MetricsSinkView, P as Plugin, k as PluginAPI, l as PluginCapabilities, m as PluginDependency, n as PluginPipelines, o as ProviderFactory, r as ProviderRegistryView, S as SessionWriterView, u as SlashCommand, v as SlashCommandRegistryView, w as SystemPromptContributor, F as ToolRegistryView } from '../index-DgQWnZxP.js';
18
+ export { D as DefaultModelsRegistry, a as DefaultModelsRegistryOptions, c as classifyFamily } from '../models-registry-gwMAo6E3.js';
19
19
  export { D as DEFAULT_MODES, M as Mode, a as ModeConfig, b as ModeManifest, c as ModeStore } from '../mode-CV077NjV.js';
20
- export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-Dti3KXGk.js';
21
- export { C as CoordinatorEvents, k as CoordinatorStatus, D as DoneCondition, M as MultiAgentConfig, l as MultiAgentCoordinator, S as SpawnResult, n as SubagentConfig, o as SubagentContext, p as SubagentError, q as SubagentErrorKind, r as SubagentRunContext, s as SubagentRunOutcome, t as SubagentRunner, T as TaskDelegation, u as TaskResult, v as TaskSpec } from '../multi-agent-DNp6lAzg.js';
20
+ export { I as InMemoryAgentBridge, a as InMemoryBridgeTransport, c as createMessage } from '../agent-bridge-DBBGP5O4.js';
21
+ export { C as CoordinatorEvents, k as CoordinatorStatus, D as DoneCondition, M as MultiAgentConfig, l as MultiAgentCoordinator, S as SpawnResult, n as SubagentConfig, o as SubagentContext, p as SubagentError, q as SubagentErrorKind, r as SubagentRunContext, s as SubagentRunOutcome, t as SubagentRunner, T as TaskDelegation, u as TaskResult, v as TaskSpec } from '../multi-agent-C1O8EFzb.js';
22
22
  export { C as CriticalPathResult, D as DEFAULT_SPEC_TEMPLATE, S as SpecAnalysis, a as SpecApiEndpoint, b as SpecRequirement, c as SpecSection, d as SpecSectionType, e as SpecStatus, f as SpecTemplate, g as SpecValidationResult, h as Specification, T as TaskAssignment, i as TaskDependency, j as TaskEdge, k as TaskFilter, l as TaskGraph, m as TaskNode, n as TaskPriority, o as TaskProgress, p as TaskSort, q as TaskStatus, r as TaskType, s as computeTaskProgress, t as findCriticalPath, u as topologicalSort } from '../task-graph-D1YQbpxF.js';
23
23
  export { A as AggregateHealth, H as HealthCheck, a as HealthCheckResult, b as HealthRegistry, c as HealthStatus, M as MetricLabels, d as MetricSeries, e as MetricsSink, f as MetricsSnapshot, S as Span, T as Tracer } from '../observability-BhnVLBLS.js';
24
- import '../events-DH-9r-_C.js';
24
+ import '../events-Bw1K5E6K.js';
25
25
  import '../logger-DDd5C--Z.js';
26
- import '../retry-policy-J9N_PM40.js';
26
+ import '../retry-policy-KF18W4dg.js';
27
27
  import '../models-registry-BcYJDKLm.js';
28
28
  import '../secret-vault-DoISxaKO.js';
29
29
  import '../secret-scrubber-3MHDDAtm.js';
@@ -66,8 +66,10 @@ var ERROR_CODES = {
66
66
  // Container / Registry
67
67
  CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
68
68
  CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
69
+ CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
69
70
  REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
70
71
  REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
72
+ REGISTRY_INVALID: "REGISTRY_INVALID",
71
73
  // File system
72
74
  FS_READ_FAILED: "FS_READ_FAILED",
73
75
  FS_WRITE_FAILED: "FS_WRITE_FAILED",
@@ -315,6 +317,14 @@ var DEFAULT_CONTEXT_CONFIG = Object.freeze({
315
317
  var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
316
318
  autoProceedDelayMs: 45e3
317
319
  });
320
+ var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
321
+ auditLevel: "standard",
322
+ sampling: {
323
+ toolProgress: {
324
+ sampleRate: 8
325
+ }
326
+ }
327
+ });
318
328
 
319
329
  // src/types/secret-vault.ts
320
330
  var ENCRYPTED_PREFIX = "enc:v1:";
@@ -1481,6 +1491,71 @@ var DefaultSecretScrubber = class {
1481
1491
  return visit(obj);
1482
1492
  }
1483
1493
  };
1494
+
1495
+ // src/utils/merge-models-payload.ts
1496
+ function mergeModelsPayload(base, overlay) {
1497
+ const out = {};
1498
+ for (const [id, provider] of Object.entries(base)) {
1499
+ out[id] = cloneProvider(provider);
1500
+ }
1501
+ for (const [id, ovProvider] of Object.entries(overlay)) {
1502
+ const existing = out[id];
1503
+ out[id] = existing ? mergeProvider(existing, ovProvider) : cloneProvider(ovProvider);
1504
+ }
1505
+ return out;
1506
+ }
1507
+ function mergeProvider(base, overlay) {
1508
+ const models = {};
1509
+ for (const [mid, m] of Object.entries(base.models ?? {})) {
1510
+ models[mid] = { ...m };
1511
+ }
1512
+ for (const [mid, ovModel] of Object.entries(overlay.models ?? {})) {
1513
+ const existing = models[mid];
1514
+ models[mid] = existing ? mergeModel(existing, ovModel) : { ...ovModel };
1515
+ }
1516
+ return {
1517
+ ...base,
1518
+ // Overlay scalar fields win when explicitly provided; otherwise keep base.
1519
+ ...stripUndefined({
1520
+ id: overlay.id,
1521
+ name: overlay.name,
1522
+ npm: overlay.npm,
1523
+ api: overlay.api,
1524
+ env: overlay.env,
1525
+ doc: overlay.doc
1526
+ }),
1527
+ models
1528
+ };
1529
+ }
1530
+ function mergeModel(base, overlay) {
1531
+ const merged = { ...base, ...overlay };
1532
+ if (base.limit || overlay.limit) {
1533
+ merged.limit = { ...base.limit, ...overlay.limit };
1534
+ }
1535
+ if (base.cost || overlay.cost) {
1536
+ merged.cost = { ...base.cost, ...overlay.cost };
1537
+ }
1538
+ if (base.modalities || overlay.modalities) {
1539
+ merged.modalities = { ...base.modalities, ...overlay.modalities };
1540
+ }
1541
+ return merged;
1542
+ }
1543
+ function cloneProvider(p) {
1544
+ const models = {};
1545
+ for (const [mid, m] of Object.entries(p.models ?? {})) {
1546
+ models[mid] = { ...m };
1547
+ }
1548
+ return { ...p, models };
1549
+ }
1550
+ function stripUndefined(obj) {
1551
+ const out = {};
1552
+ for (const [k, v] of Object.entries(obj)) {
1553
+ if (v !== void 0) out[k] = v;
1554
+ }
1555
+ return out;
1556
+ }
1557
+
1558
+ // src/models/models-registry.ts
1484
1559
  var DEFAULT_URL = "https://models.dev/api.json";
1485
1560
  var DEFAULT_TTL_SECONDS = 24 * 3600;
1486
1561
  var FAMILY_BY_NPM = {
@@ -1508,7 +1583,10 @@ function classifyFamily(npm) {
1508
1583
  return FAMILY_BY_NPM[npm] ?? "unsupported";
1509
1584
  }
1510
1585
  var DefaultModelsRegistry = class {
1586
+ /** Merged (base + overlay) payload — what every reader sees. */
1511
1587
  payload;
1588
+ /** Memoised overlay payload (in-memory / fetched / file). */
1589
+ overlayPayload;
1512
1590
  fetchedAt;
1513
1591
  cacheFile;
1514
1592
  url;
@@ -1516,6 +1594,10 @@ var DefaultModelsRegistry = class {
1516
1594
  fetchImpl;
1517
1595
  seed;
1518
1596
  maxStaleAgeMs;
1597
+ overlay;
1598
+ overlayUrl;
1599
+ overlayFile;
1600
+ overlayCacheFile;
1519
1601
  constructor(opts) {
1520
1602
  this.cacheFile = opts.cacheFile;
1521
1603
  this.url = opts.url ?? DEFAULT_URL;
@@ -1524,6 +1606,10 @@ var DefaultModelsRegistry = class {
1524
1606
  this.seed = opts.seed;
1525
1607
  const maxStaleSeconds = opts.maxStaleAgeSeconds ?? 7 * 24 * 3600;
1526
1608
  this.maxStaleAgeMs = maxStaleSeconds * 1e3;
1609
+ this.overlay = opts.overlay;
1610
+ this.overlayUrl = opts.overlayUrl;
1611
+ this.overlayFile = opts.overlayFile;
1612
+ this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path4.join(path4.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
1527
1613
  }
1528
1614
  async load(opts = {}) {
1529
1615
  if (this.payload && !opts.force) return this.payload;
@@ -1532,27 +1618,45 @@ var DefaultModelsRegistry = class {
1532
1618
  this.fetchedAt = /* @__PURE__ */ new Date();
1533
1619
  return this.payload;
1534
1620
  }
1621
+ const overlay = await this.loadOverlay(opts);
1622
+ const base = await this.loadBase(opts, Object.keys(overlay).length > 0);
1623
+ this.payload = mergeModelsPayload(base, overlay);
1624
+ return this.payload;
1625
+ }
1626
+ /**
1627
+ * Load the models.dev base payload: fresh cache → network → stale cache.
1628
+ * On total failure, degrade to `{}` (so a non-empty overlay still drives
1629
+ * the catalog) rather than throwing — unless there's no curated overlay to
1630
+ * fall back on, in which case the original error propagates so pure-
1631
+ * models.dev setups still surface the problem.
1632
+ */
1633
+ async loadBase(opts = {}, overlayAvailable = false) {
1535
1634
  if (!opts.force) {
1536
- const cached = await this.readCache();
1635
+ const cached = await this.readCacheAt(this.cacheFile);
1537
1636
  if (cached && this.isFresh(cached.fetchedAt)) {
1538
- this.payload = cached.payload;
1539
1637
  this.fetchedAt = new Date(cached.fetchedAt);
1540
1638
  return cached.payload;
1541
1639
  }
1542
1640
  }
1543
1641
  try {
1544
- return await this.refresh();
1642
+ return await this.refreshBase();
1545
1643
  } catch (err) {
1546
- const cached = await this.readCache();
1644
+ const cached = await this.readCacheAt(this.cacheFile);
1547
1645
  if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {
1548
- this.payload = cached.payload;
1549
1646
  this.fetchedAt = new Date(cached.fetchedAt);
1550
1647
  return cached.payload;
1551
1648
  }
1649
+ if (overlayAvailable) {
1650
+ console.warn(
1651
+ `ModelsRegistry: models.dev unavailable (${err instanceof Error ? err.message : String(err)}); serving curated overlay only.`
1652
+ );
1653
+ return {};
1654
+ }
1552
1655
  throw err;
1553
1656
  }
1554
1657
  }
1555
- async refresh() {
1658
+ /** Fetch + cache the models.dev base. Throws on failure (used by `refresh`). */
1659
+ async refreshBase() {
1556
1660
  const res = await this.fetchImpl(this.url, {
1557
1661
  method: "GET",
1558
1662
  headers: { accept: "application/json" }
@@ -1561,7 +1665,6 @@ var DefaultModelsRegistry = class {
1561
1665
  throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);
1562
1666
  }
1563
1667
  const json = await res.json();
1564
- this.payload = json;
1565
1668
  this.fetchedAt = /* @__PURE__ */ new Date();
1566
1669
  const envelope = {
1567
1670
  fetchedAt: this.fetchedAt.toISOString(),
@@ -1571,6 +1674,68 @@ var DefaultModelsRegistry = class {
1571
1674
  await atomicWrite(this.cacheFile, JSON.stringify(envelope));
1572
1675
  return json;
1573
1676
  }
1677
+ /**
1678
+ * Resolve the curated overlay, memoised. Order: in-memory `overlay` →
1679
+ * fetched `overlayUrl` (cached, same TTL/stale rules) → `overlayFile` on
1680
+ * disk. Never throws — a missing/broken overlay yields `{}`.
1681
+ */
1682
+ async loadOverlay(opts = {}) {
1683
+ if (this.overlayPayload && !opts.force) return this.overlayPayload;
1684
+ if (this.overlay) {
1685
+ this.overlayPayload = this.overlay;
1686
+ return this.overlayPayload;
1687
+ }
1688
+ const fetched = await this.loadOverlayFromUrl(opts);
1689
+ if (fetched) {
1690
+ this.overlayPayload = fetched;
1691
+ return fetched;
1692
+ }
1693
+ const fromFile = await this.readOverlayFile();
1694
+ this.overlayPayload = fromFile ?? {};
1695
+ return this.overlayPayload;
1696
+ }
1697
+ async loadOverlayFromUrl(opts) {
1698
+ if (!this.overlayUrl || !this.overlayCacheFile) return void 0;
1699
+ if (!opts.force) {
1700
+ const cached = await this.readCacheAt(this.overlayCacheFile);
1701
+ if (cached && this.isFresh(cached.fetchedAt)) return cached.payload;
1702
+ }
1703
+ try {
1704
+ const res = await this.fetchImpl(this.overlayUrl, {
1705
+ method: "GET",
1706
+ headers: { accept: "application/json" }
1707
+ });
1708
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
1709
+ const json = await res.json();
1710
+ const envelope = {
1711
+ fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
1712
+ url: this.overlayUrl,
1713
+ payload: json
1714
+ };
1715
+ await atomicWrite(this.overlayCacheFile, JSON.stringify(envelope)).catch(() => {
1716
+ });
1717
+ return json;
1718
+ } catch {
1719
+ const cached = await this.readCacheAt(this.overlayCacheFile);
1720
+ if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) return cached.payload;
1721
+ return void 0;
1722
+ }
1723
+ }
1724
+ async readOverlayFile() {
1725
+ if (!this.overlayFile) return void 0;
1726
+ try {
1727
+ const raw = await fs.readFile(this.overlayFile, "utf8");
1728
+ return JSON.parse(raw);
1729
+ } catch {
1730
+ return void 0;
1731
+ }
1732
+ }
1733
+ async refresh() {
1734
+ const base = await this.refreshBase();
1735
+ const overlay = await this.loadOverlay({ force: true });
1736
+ this.payload = mergeModelsPayload(base, overlay);
1737
+ return this.payload;
1738
+ }
1574
1739
  async listProviders() {
1575
1740
  const payload = await this.load();
1576
1741
  return Object.values(payload).map((p) => this.resolveProvider(p));
@@ -1611,7 +1776,7 @@ var DefaultModelsRegistry = class {
1611
1776
  }
1612
1777
  async ageSeconds() {
1613
1778
  if (!this.fetchedAt) {
1614
- const cached = await this.readCache();
1779
+ const cached = await this.readCacheAt(this.cacheFile);
1615
1780
  if (!cached) return Number.POSITIVE_INFINITY;
1616
1781
  return (Date.now() - new Date(cached.fetchedAt).getTime()) / 1e3;
1617
1782
  }
@@ -1635,9 +1800,9 @@ var DefaultModelsRegistry = class {
1635
1800
  isWithinMaxStaleAge(fetchedAtIso) {
1636
1801
  return Date.now() - new Date(fetchedAtIso).getTime() < this.maxStaleAgeMs;
1637
1802
  }
1638
- async readCache() {
1803
+ async readCacheAt(file) {
1639
1804
  try {
1640
- const raw = await fs.readFile(this.cacheFile, "utf8");
1805
+ const raw = await fs.readFile(file, "utf8");
1641
1806
  return JSON.parse(raw);
1642
1807
  } catch {
1643
1808
  return void 0;
@@ -2209,6 +2374,141 @@ function topologicalSort(graph) {
2209
2374
  return result;
2210
2375
  }
2211
2376
 
2377
+ // src/security/capabilities.ts
2378
+ var ToolCapabilities = {
2379
+ /** Can execute arbitrary commands in the user's shell (the `bash` tool). */
2380
+ SHELL_ARBITRARY: "shell.arbitrary",
2381
+ /** Can write / modify / delete files inside the project. */
2382
+ FS_WRITE: "fs.write",
2383
+ /** Can write files outside the current project root (very high risk). */
2384
+ FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
2385
+ /** Proxies tools from external MCP servers (unknown capability). */
2386
+ MCP_PROXY: "mcp.proxy",
2387
+ /** Can spawn or manage subagents / multi-agent tasks. */
2388
+ SUBAGENT_SPAWN: "subagent.spawn",
2389
+ /** Can mutate global or session configuration / trust state. */
2390
+ CONFIG_MUTATE: "config.mutate",
2391
+ /** Can install packages or run package managers with side effects. */
2392
+ PACKAGE_INSTALL: "package.install"
2393
+ };
2394
+ var DANGEROUS_FOR_SUBAGENTS = [
2395
+ ToolCapabilities.SHELL_ARBITRARY,
2396
+ ToolCapabilities.FS_WRITE,
2397
+ ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
2398
+ ToolCapabilities.MCP_PROXY,
2399
+ ToolCapabilities.SUBAGENT_SPAWN,
2400
+ ToolCapabilities.CONFIG_MUTATE,
2401
+ ToolCapabilities.PACKAGE_INSTALL
2402
+ ];
2403
+ function hasDangerousCapabilityForSubagents(toolOrCaps) {
2404
+ if (!toolOrCaps) return false;
2405
+ const input = toolOrCaps;
2406
+ const caps = Array.isArray(input) ? input : input?.capabilities ?? [];
2407
+ return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c));
2408
+ }
2409
+ function getDangerousCapabilities(toolOrCaps) {
2410
+ if (!toolOrCaps) return [];
2411
+ const input = toolOrCaps;
2412
+ const caps = Array.isArray(input) ? input : input?.capabilities ?? [];
2413
+ return caps.filter(
2414
+ (c) => DANGEROUS_FOR_SUBAGENTS.includes(c)
2415
+ );
2416
+ }
2417
+
2418
+ // src/utils/json-schema-validate.ts
2419
+ function validateAgainstSchema(value, schema) {
2420
+ const errors = [];
2421
+ walk2(value, schema, "", errors);
2422
+ return { ok: errors.length === 0, errors };
2423
+ }
2424
+ function walk2(value, schema, path6, errors) {
2425
+ if (schema.enum !== void 0) {
2426
+ if (!schema.enum.some((e) => deepEqual(e, value))) {
2427
+ errors.push({
2428
+ path: path6 || "<root>",
2429
+ message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
2430
+ });
2431
+ return;
2432
+ }
2433
+ }
2434
+ if (typeof schema.type === "string") {
2435
+ if (!checkType(value, schema.type)) {
2436
+ errors.push({
2437
+ path: path6 || "<root>",
2438
+ message: `expected ${schema.type}, got ${describeType(value)}`
2439
+ });
2440
+ return;
2441
+ }
2442
+ }
2443
+ if (schema.type === "object" && isPlainObject(value)) {
2444
+ const obj = value;
2445
+ for (const req of schema.required ?? []) {
2446
+ if (!(req in obj)) {
2447
+ errors.push({ path: joinPath(path6, req), message: "required property missing" });
2448
+ }
2449
+ }
2450
+ if (schema.properties) {
2451
+ for (const [key, subSchema] of Object.entries(schema.properties)) {
2452
+ if (key in obj) {
2453
+ walk2(obj[key], subSchema, joinPath(path6, key), errors);
2454
+ }
2455
+ }
2456
+ }
2457
+ }
2458
+ if (schema.type === "array" && Array.isArray(value) && schema.items) {
2459
+ value.forEach((item, i) => walk2(item, schema.items, `${path6}[${i}]`, errors));
2460
+ }
2461
+ }
2462
+ function checkType(value, type) {
2463
+ switch (type) {
2464
+ case "string":
2465
+ return typeof value === "string";
2466
+ case "number":
2467
+ return typeof value === "number" && !Number.isNaN(value);
2468
+ case "integer":
2469
+ return typeof value === "number" && Number.isInteger(value);
2470
+ case "boolean":
2471
+ return typeof value === "boolean";
2472
+ case "null":
2473
+ return value === null;
2474
+ case "array":
2475
+ return Array.isArray(value);
2476
+ case "object":
2477
+ return isPlainObject(value);
2478
+ default:
2479
+ return true;
2480
+ }
2481
+ }
2482
+ function isPlainObject(v) {
2483
+ return typeof v === "object" && v !== null && !Array.isArray(v);
2484
+ }
2485
+ function describeType(v) {
2486
+ if (v === null) return "null";
2487
+ if (Array.isArray(v)) return "array";
2488
+ return typeof v;
2489
+ }
2490
+ function joinPath(parent, key) {
2491
+ if (!parent) return key;
2492
+ return `${parent}.${key}`;
2493
+ }
2494
+ function deepEqual(a, b) {
2495
+ if (a === b) return true;
2496
+ if (typeof a !== typeof b) return false;
2497
+ if (a === null || b === null) return a === b;
2498
+ if (Array.isArray(a) && Array.isArray(b)) {
2499
+ return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
2500
+ }
2501
+ if (typeof a === "object" && typeof b === "object") {
2502
+ const ak = Object.keys(a);
2503
+ const bk = Object.keys(b);
2504
+ if (ak.length !== bk.length) return false;
2505
+ return ak.every(
2506
+ (k) => deepEqual(a[k], b[k])
2507
+ );
2508
+ }
2509
+ return false;
2510
+ }
2511
+
2212
2512
  // src/utils/tool-output-serializer.ts
2213
2513
  function createToolOutputSerializer(opts = {}) {
2214
2514
  const capBytes = opts.perIterationOutputCapBytes ?? 1e5;
@@ -2290,18 +2590,45 @@ var ToolExecutor = class {
2290
2590
  budget = this.decrementBudget(result, budget);
2291
2591
  return { result, tool, durationMs: Date.now() - start };
2292
2592
  }
2593
+ const validation = validateAgainstSchema(use.input, tool.inputSchema);
2594
+ if (!validation.ok) {
2595
+ const errorDetails = validation.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
2596
+ const result = {
2597
+ type: "tool_result",
2598
+ tool_use_id: use.id,
2599
+ content: `Invalid arguments for tool "${tool.name}".
2600
+
2601
+ Validation errors:
2602
+ ${errorDetails}
2603
+
2604
+ Please call the tool again with arguments that match its inputSchema. You can use the "tool-help" tool with name="${tool.name}" to see the exact expected schema.`,
2605
+ is_error: true
2606
+ };
2607
+ budget = this.decrementBudget(result, budget);
2608
+ return { result, tool, durationMs: Date.now() - start };
2609
+ }
2610
+ const toolDangerousCaps = getDangerousCapabilities(tool);
2611
+ if (toolDangerousCaps.length > 0) {
2612
+ if (this.opts.events) ;
2613
+ }
2293
2614
  if (hasMalformedArguments(use.input)) {
2294
2615
  const result = this.malformedInputResult(use, extractMalformedRaw(use.input));
2295
2616
  budget = this.decrementBudget(result, budget);
2296
2617
  return { result, tool, durationMs: Date.now() - start };
2297
2618
  }
2298
2619
  const decision = await this.opts.permissionPolicy.evaluate(tool, use.input, ctx);
2299
- if (decision.permission === "deny") {
2620
+ let effectivePermission = decision.permission;
2621
+ const policy = this.opts.permissionPolicy;
2622
+ const yolo = policy.getYolo?.() === true || policy.getForceAllYolo?.() === true;
2623
+ if (toolDangerousCaps.length > 0 && effectivePermission === "auto" && !yolo) {
2624
+ effectivePermission = "confirm";
2625
+ }
2626
+ if (effectivePermission === "deny") {
2300
2627
  const result = this.deniedResult(use, decision.reason);
2301
2628
  budget = this.decrementBudget(result, budget);
2302
2629
  return { result, tool, durationMs: Date.now() - start };
2303
2630
  }
2304
- if (decision.permission === "confirm") {
2631
+ if (effectivePermission === "confirm") {
2305
2632
  if (this.opts.confirmAwaiter) {
2306
2633
  const choice = await this.opts.confirmAwaiter(tool, use.input, use.id, tool.name);
2307
2634
  if (choice !== "yes" && choice !== "always") {
@@ -2326,10 +2653,13 @@ var ToolExecutor = class {
2326
2653
  return { result: pending, tool, durationMs: Date.now() - start };
2327
2654
  }
2328
2655
  }
2656
+ const toolCapsForAudit = hasDangerousCapabilityForSubagents(tool) ? tool.capabilities ?? [] : [];
2329
2657
  const span = this.opts.tracer?.startSpan(`tool.${tool.name}`, {
2330
2658
  "tool.name": tool.name,
2331
2659
  "tool.mutating": tool.mutating,
2332
- "tool.permission": tool.permission
2660
+ "tool.permission": tool.permission,
2661
+ "tool.capabilities": JSON.stringify(tool.capabilities ?? []),
2662
+ "tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
2333
2663
  });
2334
2664
  try {
2335
2665
  const result = await this.executeTool(tool, use, ctx, budget);
@@ -2874,6 +3204,6 @@ function renderPlainText(meta, events) {
2874
3204
  return lines.join("\n");
2875
3205
  }
2876
3206
 
2877
- export { AgentError, CONTEXT_WINDOW_MODES, ConfigError, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_TOOLS_CONFIG, DefaultErrorHandler, DefaultLogger, DefaultModelsRegistry, DefaultPathResolver, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultTokenCounter, ERROR_CODES, FsError, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, PluginError, ProviderError, SessionError, ToolError, ToolExecutor, WrongStackError, asBlocks, asText, buildRecoveryStrategies, classifyFamily, computeTaskProgress, createMessage, decryptConfigSecrets, encryptConfigSecrets, findCriticalPath, formatContextWindowModeList, getContextWindowMode, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, migratePlaintextSecrets, resolveContextWindowPolicy, rewriteConfigEncrypted, toWrongStackError, topologicalSort };
3207
+ export { AgentError, CONTEXT_WINDOW_MODES, ConfigError, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SPEC_TEMPLATE, DEFAULT_TOOLS_CONFIG, DefaultErrorHandler, DefaultLogger, DefaultModelsRegistry, DefaultPathResolver, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultTokenCounter, ERROR_CODES, FsError, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, PluginError, ProviderError, SessionError, ToolError, ToolExecutor, WrongStackError, asBlocks, asText, buildRecoveryStrategies, classifyFamily, computeTaskProgress, createMessage, decryptConfigSecrets, encryptConfigSecrets, findCriticalPath, formatContextWindowModeList, getContextWindowMode, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, migratePlaintextSecrets, resolveContextWindowPolicy, rewriteConfigEncrypted, toWrongStackError, topologicalSort };
2878
3208
  //# sourceMappingURL=index.js.map
2879
3209
  //# sourceMappingURL=index.js.map