@hoilab/ada-cli 0.84.21 → 0.84.22
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/CHANGELOG.md +20 -0
- package/README.es.md +163 -0
- package/README.md +99 -652
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +2 -2
- package/dist/cli/home-screen.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +9 -3
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +57 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +449 -73
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -3
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/engine-personality.d.ts +12 -0
- package/dist/core/engine-personality.d.ts.map +1 -0
- package/dist/core/engine-personality.js +53 -0
- package/dist/core/engine-personality.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +10 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/memory-engine/audit-export.d.ts +54 -0
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-export.js +85 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +7 -8
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +2 -3
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +148 -50
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/inverted-index.d.ts.map +1 -1
- package/dist/core/memory-engine/inverted-index.js +67 -10
- package/dist/core/memory-engine/inverted-index.js.map +1 -1
- package/dist/core/memory-engine/keychain.d.ts.map +1 -1
- package/dist/core/memory-engine/keychain.js +1 -6
- package/dist/core/memory-engine/keychain.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +1 -0
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +37 -8
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/scanner.d.ts.map +1 -1
- package/dist/core/memory-engine/scanner.js +25 -5
- package/dist/core/memory-engine/scanner.js.map +1 -1
- package/dist/core/memory-engine/security.d.ts.map +1 -1
- package/dist/core/memory-engine/security.js +131 -23
- package/dist/core/memory-engine/security.js.map +1 -1
- package/dist/core/memory-engine/session-indexer.d.ts.map +1 -1
- package/dist/core/memory-engine/session-indexer.js +8 -2
- package/dist/core/memory-engine/session-indexer.js.map +1 -1
- package/dist/core/memory-engine/tools.d.ts +2 -2
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +14 -7
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/vault.d.ts.map +1 -1
- package/dist/core/memory-engine/vault.js +2 -2
- package/dist/core/memory-engine/vault.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +12 -6
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/prompt-optimizer.d.ts +53 -0
- package/dist/core/prompt-optimizer.d.ts.map +1 -0
- package/dist/core/prompt-optimizer.js +138 -0
- package/dist/core/prompt-optimizer.js.map +1 -0
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +50 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +233 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +52 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +204 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +2 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/project-memory-tool.d.ts.map +1 -1
- package/dist/core/tools/project-memory-tool.js +4 -1
- package/dist/core/tools/project-memory-tool.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/workflows/agent-runner.d.ts +86 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -0
- package/dist/core/workflows/agent-runner.js +225 -0
- package/dist/core/workflows/agent-runner.js.map +1 -0
- package/dist/core/workflows/builtins.d.ts +41 -0
- package/dist/core/workflows/builtins.d.ts.map +1 -0
- package/dist/core/workflows/builtins.js +282 -0
- package/dist/core/workflows/builtins.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +134 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/engine.js +462 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -0
- package/dist/core/workflows/goal-engine/errors.d.ts +7 -0
- package/dist/core/workflows/goal-engine/errors.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/errors.js +9 -0
- package/dist/core/workflows/goal-engine/errors.js.map +1 -0
- package/dist/core/workflows/goal-engine/index.d.ts +13 -0
- package/dist/core/workflows/goal-engine/index.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/index.js +8 -0
- package/dist/core/workflows/goal-engine/index.js.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts +31 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.js +145 -0
- package/dist/core/workflows/goal-engine/persistence.js.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts +37 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.js +131 -0
- package/dist/core/workflows/goal-engine/prompts.js.map +1 -0
- package/dist/core/workflows/goal-engine/state.d.ts +41 -0
- package/dist/core/workflows/goal-engine/state.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/state.js +397 -0
- package/dist/core/workflows/goal-engine/state.js.map +1 -0
- package/dist/core/workflows/goal-engine/tools.d.ts +31 -0
- package/dist/core/workflows/goal-engine/tools.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/tools.js +211 -0
- package/dist/core/workflows/goal-engine/tools.js.map +1 -0
- package/dist/core/workflows/goal-engine/types.d.ts +286 -0
- package/dist/core/workflows/goal-engine/types.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/types.js +17 -0
- package/dist/core/workflows/goal-engine/types.js.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts +23 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js +72 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js.map +1 -0
- package/dist/core/workflows/graph-sync.d.ts +67 -0
- package/dist/core/workflows/graph-sync.d.ts.map +1 -0
- package/dist/core/workflows/graph-sync.js +188 -0
- package/dist/core/workflows/graph-sync.js.map +1 -0
- package/dist/core/workflows/graph.d.ts +143 -0
- package/dist/core/workflows/graph.d.ts.map +1 -0
- package/dist/core/workflows/graph.js +319 -0
- package/dist/core/workflows/graph.js.map +1 -0
- package/dist/core/workflows/index.d.ts +18 -0
- package/dist/core/workflows/index.d.ts.map +1 -0
- package/dist/core/workflows/index.js +14 -0
- package/dist/core/workflows/index.js.map +1 -0
- package/dist/core/workflows/journal.d.ts +68 -0
- package/dist/core/workflows/journal.d.ts.map +1 -0
- package/dist/core/workflows/journal.js +83 -0
- package/dist/core/workflows/journal.js.map +1 -0
- package/dist/core/workflows/manager.d.ts +112 -0
- package/dist/core/workflows/manager.d.ts.map +1 -0
- package/dist/core/workflows/manager.js +327 -0
- package/dist/core/workflows/manager.js.map +1 -0
- package/dist/core/workflows/resolve-script.d.ts +35 -0
- package/dist/core/workflows/resolve-script.d.ts.map +1 -0
- package/dist/core/workflows/resolve-script.js +66 -0
- package/dist/core/workflows/resolve-script.js.map +1 -0
- package/dist/core/workflows/runtime.d.ts +49 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -0
- package/dist/core/workflows/runtime.js +301 -0
- package/dist/core/workflows/runtime.js.map +1 -0
- package/dist/core/workflows/shared-store.d.ts +31 -0
- package/dist/core/workflows/shared-store.d.ts.map +1 -0
- package/dist/core/workflows/shared-store.js +80 -0
- package/dist/core/workflows/shared-store.js.map +1 -0
- package/dist/core/workflows/subagent-host.d.ts +50 -0
- package/dist/core/workflows/subagent-host.d.ts.map +1 -0
- package/dist/core/workflows/subagent-host.js +225 -0
- package/dist/core/workflows/subagent-host.js.map +1 -0
- package/dist/core/workflows/tool-workflow.d.ts +22 -0
- package/dist/core/workflows/tool-workflow.d.ts.map +1 -0
- package/dist/core/workflows/tool-workflow.js +120 -0
- package/dist/core/workflows/tool-workflow.js.map +1 -0
- package/dist/core/workflows/types.d.ts +142 -0
- package/dist/core/workflows/types.d.ts.map +1 -0
- package/dist/core/workflows/types.js +26 -0
- package/dist/core/workflows/types.js.map +1 -0
- package/dist/core/workflows/worktree.d.ts +42 -0
- package/dist/core/workflows/worktree.d.ts.map +1 -0
- package/dist/core/workflows/worktree.js +107 -0
- package/dist/core/workflows/worktree.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +16 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +2 -2
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +16 -6
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/prompt-optimization.d.ts +16 -0
- package/dist/modes/interactive/components/prompt-optimization.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-optimization.js +46 -0
- package/dist/modes/interactive/components/prompt-optimization.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +19 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +247 -46
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +8 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +29 -3
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +24 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +677 -34
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +173 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +29 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/skills/ada-engine/SKILL.md +153 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/extensions.md +11 -2
- package/docs/json.md +7 -2
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/rpc.md +9 -3
- package/docs/settings.md +2 -2
- package/docs/skills.md +4 -3
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +2 -12
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-host.d.ts","sourceRoot":"","sources":["../../../src/core/workflows/subagent-host.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGzD,MAAM,WAAW,4BAA4B;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,WAAW,CAAC,EAAE,cAAc,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6EAA4E;IAC5E,SAAS,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,eAAe,CAAC,CAyC3G;AAsDD,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAItG;AA2CD;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GAAG,SAAS,GACtB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,CAwDjC","sourcesContent":["/**\n * SubagentHost — subagente de producción: crea una sesión real del SDK\n * (createAgentSession) con el modelo resuelto, tools configuradas y límites.\n *\n * El subagente comparte el mismo runtime (memoria/vault/redacción) porque\n * createAgentSession construye un DefaultResourceLoader con el mismo agentDir\n * y el SettingsManager compartido → los subagentes heredan la memoria, el\n * vault (@vault:) y la censura de secretos (adversarial §17).\n *\n * NOTA (seguridad, fairy-tales): los subagentes usan un agentDir PROPIO\n * efímero cuando se pide aislamiento (nada de extensiones/paquetes dentro);\n * las guardas del engine se re-inyectan explícitamente.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Model } from \"@earendil-works/pi-ai\";\nimport type { AgentSession } from \"../agent-session.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { ModelRuntime } from \"../model-runtime.ts\";\nimport { createAgentSession } from \"../sdk.ts\";\nimport type { SubagentSession } from \"./agent-runner.ts\";\nimport type { AgentUsage } from \"./types.ts\";\n\nexport interface CreateSubagentSessionOptions {\n\tcwd: string;\n\tagentDir: string;\n\tmodelSpec?: string;\n\ttools?: string[];\n\tcustomTools?: ToolDefinition[];\n\tsessionName?: string;\n\tinstructions?: string;\n\t/** Modelo de la sesión principal: los subagentes lo HEREDAN por defecto. */\n\thostModel?: { provider: string; modelId: string };\n}\n\n/**\n * Crea un subagente real. Devuelve la sesión con su disposición y el usage.\n */\nexport async function createSubagentSession(options: CreateSubagentSessionOptions): Promise<SubagentSession> {\n\t// Routing por spec/tier (§16.2 budget): \"tier:cheap\" resuelve el modelo\n\t// barato, \"provider/model\" el explícito, y cualquier fallo cae al default.\n\tlet model = await resolveSubagentModel(options.agentDir, options.modelSpec);\n\t// Los subagentes HEREDAN el modelo de la sesión principal: si no hay spec/tier\n\t// explícito y el host tiene un modelo en uso, ese es el que se usa (misma\n\t// auth → misma API key del chat).\n\tif (!model && options.hostModel?.provider && options.hostModel.modelId) {\n\t\tmodel =\n\t\t\t(await resolveSubagentModel(options.agentDir, `${options.hostModel.provider}/${options.hostModel.modelId}`)) ??\n\t\t\tundefined;\n\t}\n\t// Thinking por tier: solo cuando el spec es tier:X y hay override en settings.\n\tconst tierMatch = options.modelSpec?.startsWith(\"tier:\")\n\t\t? (options.modelSpec.slice(5) as \"cheap\" | \"main\" | \"judge\")\n\t\t: undefined;\n\tconst thinkingLevel = tierMatch ? thinkingForTier(options.agentDir, tierMatch) : undefined;\n\n\tconst { session } = await createAgentSession({\n\t\tcwd: options.cwd,\n\t\tagentDir: options.agentDir,\n\t\ttools: options.tools,\n\t\tcustomTools: options.customTools,\n\t\t...(model ? { model } : {}),\n\t\t...(thinkingLevel ? { thinkingLevel: thinkingLevel as never } : {}),\n\t\tisSubagent: true, // anti-recursión: el HOST es el único dueño del bucle del goal\n\t});\n\n\t// Nombre de sesión + instrucciones: no hay opción directa en\n\t// createAgentSession para ambos; la instrucción va en el prompt.\n\treturn {\n\t\tsession,\n\t\tdispose: () => {\n\t\t\ttry {\n\t\t\t\tsession.dispose();\n\t\t\t} catch {\n\t\t\t\t// best-effort\n\t\t\t}\n\t\t},\n\t\tgetUsage: () => usageFromSession(session),\n\t};\n}\n\n/** Extraer el usage real de la sesión del subagente. */\nfunction usageFromSession(session: AgentSession): AgentUsage {\n\ttry {\n\t\tconst stats = session.getSessionStats();\n\t\tconst tokens = stats.tokens;\n\t\treturn {\n\t\t\tinput: tokens.input,\n\t\t\toutput: tokens.output,\n\t\t\ttotal: tokens.total,\n\t\t\tcost: stats.cost ?? 0,\n\t\t\tcacheRead: tokens.cacheRead,\n\t\t\tcacheWrite: tokens.cacheWrite,\n\t\t};\n\t} catch {\n\t\treturn { input: 0, output: 0, total: 0, cost: 0, cacheRead: 0, cacheWrite: 0 };\n\t}\n}\n\n/**\n * Fallback de emergencia: solo se usa si el discovery dinámico no encuentra\n * NINGÚN modelo con coste entre los proveedores conectados. Cada entrada se\n * valida con hasConfiguredAuth — sin credenciales se cae al default (fail-safe).\n */\nconst CHEAP_MODEL_CANDIDATES: Array<[provider: string, modelId: string]> = [\n\t[\"anthropic\", \"claude-haiku-4-5\"],\n\t[\"google\", \"gemini-2.5-flash\"],\n\t[\"google\", \"gemini-2.0-flash\"],\n\t[\"openai\", \"gpt-4o-mini\"],\n\t[\"openai\", \"gpt-5-mini\"],\n];\n\ninterface ModelsConfig {\n\tcheap?: string;\n\tmain?: string;\n\tjudge?: string;\n\tcheapCandidates?: string[];\n\tcheapThinking?: string;\n\tmainThinking?: string;\n\tjudgeThinking?: string;\n}\n\n/** Lee workflows.models del settings.json del agentDir (sin SettingsManager — función pura). */\nfunction readModelsConfig(agentDir: string): ModelsConfig {\n\ttry {\n\t\tconst raw = readFileSync(join(agentDir, \"settings.json\"), \"utf-8\");\n\t\tconst parsed = JSON.parse(raw) as { workflows?: { models?: ModelsConfig } };\n\t\treturn parsed?.workflows?.models ?? {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Thinking level del tier (workflows.models.<tier>Thinking); undefined = default. */\nexport function thinkingForTier(agentDir: string, tier: \"cheap\" | \"main\" | \"judge\"): string | undefined {\n\tconst cfg = readModelsConfig(agentDir);\n\tconst value = tier === \"cheap\" ? cfg.cheapThinking : tier === \"judge\" ? cfg.judgeThinking : cfg.mainThinking;\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\n/** Parsea \"provider/model\" → [provider, model]; null si malformado. */\nfunction parseSpec(spec: string): [string, string] | null {\n\tconst slash = spec.indexOf(\"/\");\n\tif (slash <= 0 || slash === spec.length - 1) return null;\n\treturn [spec.slice(0, slash), spec.slice(slash + 1)];\n}\n\n/**\n * Discovery DINÁMICO de modelos baratos: recorre los proveedores CONECTADOS\n * (hasConfiguredAuth) del runtime, toma sus modelos con coste declarado y los\n * ordena por precio (input+output) ascendente. La lista siempre refleja lo\n * que el usuario tiene disponible de verdad — nunca modelos inexistentes.\n */\nfunction discoverCheapModels(runtime: ModelRuntime, max = 6): Array<[string, string]> {\n\tconst scored: Array<{ provider: string; model: string; cost: number }> = [];\n\tfor (const provider of runtime.getProviders()) {\n\t\tif (!runtime.hasConfiguredAuth(provider.id)) continue;\n\t\tfor (const model of runtime.getModels(provider.id)) {\n\t\t\tconst m = model as { modelId?: string; id?: string; cost?: { input?: number; output?: number } };\n\t\t\tconst modelId = m.modelId ?? m.id;\n\t\t\tconst cost = m.cost;\n\t\t\tif (!modelId || !cost || typeof cost.input !== \"number\" || typeof cost.output !== \"number\") continue;\n\t\t\tscored.push({ provider: provider.id, model: modelId, cost: cost.input + cost.output });\n\t\t}\n\t}\n\treturn scored\n\t\t.sort((a, b) => a.cost - b.cost)\n\t\t.slice(0, max)\n\t\t.map((x) => [x.provider, x.model]);\n}\n\n/** Lista del usuario (workflows.models.cheapCandidates). [] si no está configurada. */\nfunction userCheapCandidates(agentDir: string): Array<[string, string]> {\n\tconst configured = readModelsConfig(agentDir).cheapCandidates;\n\tif (!Array.isArray(configured) || configured.length === 0) return [];\n\t// Solo entradas válidas \"provider/model\" (las malas se saltan).\n\treturn configured\n\t\t.map((c) => (typeof c === \"string\" ? parseSpec(c) : null))\n\t\t.filter((c): c is [string, string] => c !== null);\n}\n\n/**\n * Resuelve el modelSpec de un subagente a un Model concreto.\n * - \"tier:cheap\" → cascada:\n * 1. workflows.models.cheap (\"provider/model\" directo)\n * 2. workflows.models.cheapCandidates (lista del usuario, en orden)\n * 3. DISCOVERY DINÁMICO: el modelo más barato con coste declarado de los\n * proveedores CONECTADOS (refleja siempre el catálogo real del SDK)\n * 4. fallback estático curado (solo si el discovery no encontró nada)\n * - \"tier:main\"/\"tier:judge\" → workflows.models.main/judge, si no default.\n * - \"provider/model\" → directo si está autenticado.\n * Devuelve undefined → createAgentSession usa su resolución por defecto.\n */\nexport async function resolveSubagentModel(\n\tagentDir: string,\n\tspec: string | undefined,\n): Promise<Model<any> | undefined> {\n\tif (!spec) return undefined;\n\tlet runtime: ModelRuntime;\n\ttry {\n\t\truntime = await ModelRuntime.create({\n\t\t\tauthPath: join(agentDir, \"auth.json\"),\n\t\t\tmodelsPath: join(agentDir, \"models.json\"),\n\t\t});\n\t} catch {\n\t\treturn undefined; // fail-safe: default\n\t}\n\tconst tryGet = (provider: string, modelId: string): Model<any> | undefined => {\n\t\tconst m = runtime.getModel(provider, modelId);\n\t\treturn m && runtime.hasConfiguredAuth(provider) ? m : undefined;\n\t};\n\n\tif (spec.startsWith(\"tier:\")) {\n\t\tconst tier = spec.slice(5);\n\t\t// Settings override PRIMERO: workflows.models.<tier> = \"provider/model\"\n\t\tconst models = readModelsConfig(agentDir);\n\t\tconst override = tier === \"cheap\" ? models.cheap : tier === \"judge\" ? models.judge : models.main;\n\t\tconst overrideSpec = override ? parseSpec(override) : null;\n\t\tif (overrideSpec) {\n\t\t\tconst m = tryGet(overrideSpec[0], overrideSpec[1]);\n\t\t\tif (m) return m;\n\t\t}\n\t\tif (tier === \"cheap\") {\n\t\t\t// 1. Lista explícita del usuario (workflows.models.cheapCandidates).\n\t\t\tfor (const candidate of userCheapCandidates(agentDir)) {\n\t\t\t\tconst m = tryGet(candidate[0], candidate[1]);\n\t\t\t\tif (m) return m;\n\t\t\t}\n\t\t\t// 2. DISCOVERY DINÁMICO: el más barato con coste declarado entre los\n\t\t\t// proveedores CONECTADOS — refleja siempre el catálogo real del SDK.\n\t\t\tfor (const [providerId, modelId] of discoverCheapModels(runtime)) {\n\t\t\t\tconst m = tryGet(providerId, modelId);\n\t\t\t\tif (m) return m;\n\t\t\t}\n\t\t\t// 3. Fallback estático de emergencia (solo si el discovery no encontró\n\t\t\t// nada — p.ej. catálogos sin costes declarados).\n\t\t\tfor (const candidate of CHEAP_MODEL_CANDIDATES) {\n\t\t\t\tconst m = tryGet(candidate[0], candidate[1]);\n\t\t\t\tif (m) return m;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\t// tier:main / tier:judge sin override → default del host (fail-safe)\n\t\treturn undefined;\n\t}\n\n\t// \"provider/model\" explícito\n\tconst slash = spec.indexOf(\"/\");\n\tif (slash <= 0 || slash === spec.length - 1) return undefined;\n\tconst provider = spec.slice(0, slash);\n\tconst modelId = spec.slice(slash + 1);\n\treturn tryGet(provider, modelId) ?? undefined;\n}\n"]}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SubagentHost — subagente de producción: crea una sesión real del SDK
|
|
3
|
+
* (createAgentSession) con el modelo resuelto, tools configuradas y límites.
|
|
4
|
+
*
|
|
5
|
+
* El subagente comparte el mismo runtime (memoria/vault/redacción) porque
|
|
6
|
+
* createAgentSession construye un DefaultResourceLoader con el mismo agentDir
|
|
7
|
+
* y el SettingsManager compartido → los subagentes heredan la memoria, el
|
|
8
|
+
* vault (@vault:) y la censura de secretos (adversarial §17).
|
|
9
|
+
*
|
|
10
|
+
* NOTA (seguridad, fairy-tales): los subagentes usan un agentDir PROPIO
|
|
11
|
+
* efímero cuando se pide aislamiento (nada de extensiones/paquetes dentro);
|
|
12
|
+
* las guardas del engine se re-inyectan explícitamente.
|
|
13
|
+
*/
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { ModelRuntime } from "../model-runtime.js";
|
|
17
|
+
import { createAgentSession } from "../sdk.js";
|
|
18
|
+
/**
|
|
19
|
+
* Crea un subagente real. Devuelve la sesión con su disposición y el usage.
|
|
20
|
+
*/
|
|
21
|
+
export async function createSubagentSession(options) {
|
|
22
|
+
// Routing por spec/tier (§16.2 budget): "tier:cheap" resuelve el modelo
|
|
23
|
+
// barato, "provider/model" el explícito, y cualquier fallo cae al default.
|
|
24
|
+
let model = await resolveSubagentModel(options.agentDir, options.modelSpec);
|
|
25
|
+
// Los subagentes HEREDAN el modelo de la sesión principal: si no hay spec/tier
|
|
26
|
+
// explícito y el host tiene un modelo en uso, ese es el que se usa (misma
|
|
27
|
+
// auth → misma API key del chat).
|
|
28
|
+
if (!model && options.hostModel?.provider && options.hostModel.modelId) {
|
|
29
|
+
model =
|
|
30
|
+
(await resolveSubagentModel(options.agentDir, `${options.hostModel.provider}/${options.hostModel.modelId}`)) ??
|
|
31
|
+
undefined;
|
|
32
|
+
}
|
|
33
|
+
// Thinking por tier: solo cuando el spec es tier:X y hay override en settings.
|
|
34
|
+
const tierMatch = options.modelSpec?.startsWith("tier:")
|
|
35
|
+
? options.modelSpec.slice(5)
|
|
36
|
+
: undefined;
|
|
37
|
+
const thinkingLevel = tierMatch ? thinkingForTier(options.agentDir, tierMatch) : undefined;
|
|
38
|
+
const { session } = await createAgentSession({
|
|
39
|
+
cwd: options.cwd,
|
|
40
|
+
agentDir: options.agentDir,
|
|
41
|
+
tools: options.tools,
|
|
42
|
+
customTools: options.customTools,
|
|
43
|
+
...(model ? { model } : {}),
|
|
44
|
+
...(thinkingLevel ? { thinkingLevel: thinkingLevel } : {}),
|
|
45
|
+
isSubagent: true, // anti-recursión: el HOST es el único dueño del bucle del goal
|
|
46
|
+
});
|
|
47
|
+
// Nombre de sesión + instrucciones: no hay opción directa en
|
|
48
|
+
// createAgentSession para ambos; la instrucción va en el prompt.
|
|
49
|
+
return {
|
|
50
|
+
session,
|
|
51
|
+
dispose: () => {
|
|
52
|
+
try {
|
|
53
|
+
session.dispose();
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// best-effort
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
getUsage: () => usageFromSession(session),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** Extraer el usage real de la sesión del subagente. */
|
|
63
|
+
function usageFromSession(session) {
|
|
64
|
+
try {
|
|
65
|
+
const stats = session.getSessionStats();
|
|
66
|
+
const tokens = stats.tokens;
|
|
67
|
+
return {
|
|
68
|
+
input: tokens.input,
|
|
69
|
+
output: tokens.output,
|
|
70
|
+
total: tokens.total,
|
|
71
|
+
cost: stats.cost ?? 0,
|
|
72
|
+
cacheRead: tokens.cacheRead,
|
|
73
|
+
cacheWrite: tokens.cacheWrite,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return { input: 0, output: 0, total: 0, cost: 0, cacheRead: 0, cacheWrite: 0 };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Fallback de emergencia: solo se usa si el discovery dinámico no encuentra
|
|
82
|
+
* NINGÚN modelo con coste entre los proveedores conectados. Cada entrada se
|
|
83
|
+
* valida con hasConfiguredAuth — sin credenciales se cae al default (fail-safe).
|
|
84
|
+
*/
|
|
85
|
+
const CHEAP_MODEL_CANDIDATES = [
|
|
86
|
+
["anthropic", "claude-haiku-4-5"],
|
|
87
|
+
["google", "gemini-2.5-flash"],
|
|
88
|
+
["google", "gemini-2.0-flash"],
|
|
89
|
+
["openai", "gpt-4o-mini"],
|
|
90
|
+
["openai", "gpt-5-mini"],
|
|
91
|
+
];
|
|
92
|
+
/** Lee workflows.models del settings.json del agentDir (sin SettingsManager — función pura). */
|
|
93
|
+
function readModelsConfig(agentDir) {
|
|
94
|
+
try {
|
|
95
|
+
const raw = readFileSync(join(agentDir, "settings.json"), "utf-8");
|
|
96
|
+
const parsed = JSON.parse(raw);
|
|
97
|
+
return parsed?.workflows?.models ?? {};
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return {};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Thinking level del tier (workflows.models.<tier>Thinking); undefined = default. */
|
|
104
|
+
export function thinkingForTier(agentDir, tier) {
|
|
105
|
+
const cfg = readModelsConfig(agentDir);
|
|
106
|
+
const value = tier === "cheap" ? cfg.cheapThinking : tier === "judge" ? cfg.judgeThinking : cfg.mainThinking;
|
|
107
|
+
return typeof value === "string" && value.length > 0 ? value : undefined;
|
|
108
|
+
}
|
|
109
|
+
/** Parsea "provider/model" → [provider, model]; null si malformado. */
|
|
110
|
+
function parseSpec(spec) {
|
|
111
|
+
const slash = spec.indexOf("/");
|
|
112
|
+
if (slash <= 0 || slash === spec.length - 1)
|
|
113
|
+
return null;
|
|
114
|
+
return [spec.slice(0, slash), spec.slice(slash + 1)];
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Discovery DINÁMICO de modelos baratos: recorre los proveedores CONECTADOS
|
|
118
|
+
* (hasConfiguredAuth) del runtime, toma sus modelos con coste declarado y los
|
|
119
|
+
* ordena por precio (input+output) ascendente. La lista siempre refleja lo
|
|
120
|
+
* que el usuario tiene disponible de verdad — nunca modelos inexistentes.
|
|
121
|
+
*/
|
|
122
|
+
function discoverCheapModels(runtime, max = 6) {
|
|
123
|
+
const scored = [];
|
|
124
|
+
for (const provider of runtime.getProviders()) {
|
|
125
|
+
if (!runtime.hasConfiguredAuth(provider.id))
|
|
126
|
+
continue;
|
|
127
|
+
for (const model of runtime.getModels(provider.id)) {
|
|
128
|
+
const m = model;
|
|
129
|
+
const modelId = m.modelId ?? m.id;
|
|
130
|
+
const cost = m.cost;
|
|
131
|
+
if (!modelId || !cost || typeof cost.input !== "number" || typeof cost.output !== "number")
|
|
132
|
+
continue;
|
|
133
|
+
scored.push({ provider: provider.id, model: modelId, cost: cost.input + cost.output });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return scored
|
|
137
|
+
.sort((a, b) => a.cost - b.cost)
|
|
138
|
+
.slice(0, max)
|
|
139
|
+
.map((x) => [x.provider, x.model]);
|
|
140
|
+
}
|
|
141
|
+
/** Lista del usuario (workflows.models.cheapCandidates). [] si no está configurada. */
|
|
142
|
+
function userCheapCandidates(agentDir) {
|
|
143
|
+
const configured = readModelsConfig(agentDir).cheapCandidates;
|
|
144
|
+
if (!Array.isArray(configured) || configured.length === 0)
|
|
145
|
+
return [];
|
|
146
|
+
// Solo entradas válidas "provider/model" (las malas se saltan).
|
|
147
|
+
return configured
|
|
148
|
+
.map((c) => (typeof c === "string" ? parseSpec(c) : null))
|
|
149
|
+
.filter((c) => c !== null);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Resuelve el modelSpec de un subagente a un Model concreto.
|
|
153
|
+
* - "tier:cheap" → cascada:
|
|
154
|
+
* 1. workflows.models.cheap ("provider/model" directo)
|
|
155
|
+
* 2. workflows.models.cheapCandidates (lista del usuario, en orden)
|
|
156
|
+
* 3. DISCOVERY DINÁMICO: el modelo más barato con coste declarado de los
|
|
157
|
+
* proveedores CONECTADOS (refleja siempre el catálogo real del SDK)
|
|
158
|
+
* 4. fallback estático curado (solo si el discovery no encontró nada)
|
|
159
|
+
* - "tier:main"/"tier:judge" → workflows.models.main/judge, si no default.
|
|
160
|
+
* - "provider/model" → directo si está autenticado.
|
|
161
|
+
* Devuelve undefined → createAgentSession usa su resolución por defecto.
|
|
162
|
+
*/
|
|
163
|
+
export async function resolveSubagentModel(agentDir, spec) {
|
|
164
|
+
if (!spec)
|
|
165
|
+
return undefined;
|
|
166
|
+
let runtime;
|
|
167
|
+
try {
|
|
168
|
+
runtime = await ModelRuntime.create({
|
|
169
|
+
authPath: join(agentDir, "auth.json"),
|
|
170
|
+
modelsPath: join(agentDir, "models.json"),
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return undefined; // fail-safe: default
|
|
175
|
+
}
|
|
176
|
+
const tryGet = (provider, modelId) => {
|
|
177
|
+
const m = runtime.getModel(provider, modelId);
|
|
178
|
+
return m && runtime.hasConfiguredAuth(provider) ? m : undefined;
|
|
179
|
+
};
|
|
180
|
+
if (spec.startsWith("tier:")) {
|
|
181
|
+
const tier = spec.slice(5);
|
|
182
|
+
// Settings override PRIMERO: workflows.models.<tier> = "provider/model"
|
|
183
|
+
const models = readModelsConfig(agentDir);
|
|
184
|
+
const override = tier === "cheap" ? models.cheap : tier === "judge" ? models.judge : models.main;
|
|
185
|
+
const overrideSpec = override ? parseSpec(override) : null;
|
|
186
|
+
if (overrideSpec) {
|
|
187
|
+
const m = tryGet(overrideSpec[0], overrideSpec[1]);
|
|
188
|
+
if (m)
|
|
189
|
+
return m;
|
|
190
|
+
}
|
|
191
|
+
if (tier === "cheap") {
|
|
192
|
+
// 1. Lista explícita del usuario (workflows.models.cheapCandidates).
|
|
193
|
+
for (const candidate of userCheapCandidates(agentDir)) {
|
|
194
|
+
const m = tryGet(candidate[0], candidate[1]);
|
|
195
|
+
if (m)
|
|
196
|
+
return m;
|
|
197
|
+
}
|
|
198
|
+
// 2. DISCOVERY DINÁMICO: el más barato con coste declarado entre los
|
|
199
|
+
// proveedores CONECTADOS — refleja siempre el catálogo real del SDK.
|
|
200
|
+
for (const [providerId, modelId] of discoverCheapModels(runtime)) {
|
|
201
|
+
const m = tryGet(providerId, modelId);
|
|
202
|
+
if (m)
|
|
203
|
+
return m;
|
|
204
|
+
}
|
|
205
|
+
// 3. Fallback estático de emergencia (solo si el discovery no encontró
|
|
206
|
+
// nada — p.ej. catálogos sin costes declarados).
|
|
207
|
+
for (const candidate of CHEAP_MODEL_CANDIDATES) {
|
|
208
|
+
const m = tryGet(candidate[0], candidate[1]);
|
|
209
|
+
if (m)
|
|
210
|
+
return m;
|
|
211
|
+
}
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
// tier:main / tier:judge sin override → default del host (fail-safe)
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
// "provider/model" explícito
|
|
218
|
+
const slash = spec.indexOf("/");
|
|
219
|
+
if (slash <= 0 || slash === spec.length - 1)
|
|
220
|
+
return undefined;
|
|
221
|
+
const provider = spec.slice(0, slash);
|
|
222
|
+
const modelId = spec.slice(slash + 1);
|
|
223
|
+
return tryGet(provider, modelId) ?? undefined;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=subagent-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent-host.js","sourceRoot":"","sources":["../../../src/core/workflows/subagent-host.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SubagentHost — subagente de producción: crea una sesión real del SDK\n * (createAgentSession) con el modelo resuelto, tools configuradas y límites.\n *\n * El subagente comparte el mismo runtime (memoria/vault/redacción) porque\n * createAgentSession construye un DefaultResourceLoader con el mismo agentDir\n * y el SettingsManager compartido → los subagentes heredan la memoria, el\n * vault (@vault:) y la censura de secretos (adversarial §17).\n *\n * NOTA (seguridad, fairy-tales): los subagentes usan un agentDir PROPIO\n * efímero cuando se pide aislamiento (nada de extensiones/paquetes dentro);\n * las guardas del engine se re-inyectan explícitamente.\n */\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { Model } from \"@earendil-works/pi-ai\";\nimport type { AgentSession } from \"../agent-session.ts\";\nimport type { ToolDefinition } from \"../extensions/types.ts\";\nimport { ModelRuntime } from \"../model-runtime.ts\";\nimport { createAgentSession } from \"../sdk.ts\";\nimport type { SubagentSession } from \"./agent-runner.ts\";\nimport type { AgentUsage } from \"./types.ts\";\n\nexport interface CreateSubagentSessionOptions {\n\tcwd: string;\n\tagentDir: string;\n\tmodelSpec?: string;\n\ttools?: string[];\n\tcustomTools?: ToolDefinition[];\n\tsessionName?: string;\n\tinstructions?: string;\n\t/** Modelo de la sesión principal: los subagentes lo HEREDAN por defecto. */\n\thostModel?: { provider: string; modelId: string };\n}\n\n/**\n * Crea un subagente real. Devuelve la sesión con su disposición y el usage.\n */\nexport async function createSubagentSession(options: CreateSubagentSessionOptions): Promise<SubagentSession> {\n\t// Routing por spec/tier (§16.2 budget): \"tier:cheap\" resuelve el modelo\n\t// barato, \"provider/model\" el explícito, y cualquier fallo cae al default.\n\tlet model = await resolveSubagentModel(options.agentDir, options.modelSpec);\n\t// Los subagentes HEREDAN el modelo de la sesión principal: si no hay spec/tier\n\t// explícito y el host tiene un modelo en uso, ese es el que se usa (misma\n\t// auth → misma API key del chat).\n\tif (!model && options.hostModel?.provider && options.hostModel.modelId) {\n\t\tmodel =\n\t\t\t(await resolveSubagentModel(options.agentDir, `${options.hostModel.provider}/${options.hostModel.modelId}`)) ??\n\t\t\tundefined;\n\t}\n\t// Thinking por tier: solo cuando el spec es tier:X y hay override en settings.\n\tconst tierMatch = options.modelSpec?.startsWith(\"tier:\")\n\t\t? (options.modelSpec.slice(5) as \"cheap\" | \"main\" | \"judge\")\n\t\t: undefined;\n\tconst thinkingLevel = tierMatch ? thinkingForTier(options.agentDir, tierMatch) : undefined;\n\n\tconst { session } = await createAgentSession({\n\t\tcwd: options.cwd,\n\t\tagentDir: options.agentDir,\n\t\ttools: options.tools,\n\t\tcustomTools: options.customTools,\n\t\t...(model ? { model } : {}),\n\t\t...(thinkingLevel ? { thinkingLevel: thinkingLevel as never } : {}),\n\t\tisSubagent: true, // anti-recursión: el HOST es el único dueño del bucle del goal\n\t});\n\n\t// Nombre de sesión + instrucciones: no hay opción directa en\n\t// createAgentSession para ambos; la instrucción va en el prompt.\n\treturn {\n\t\tsession,\n\t\tdispose: () => {\n\t\t\ttry {\n\t\t\t\tsession.dispose();\n\t\t\t} catch {\n\t\t\t\t// best-effort\n\t\t\t}\n\t\t},\n\t\tgetUsage: () => usageFromSession(session),\n\t};\n}\n\n/** Extraer el usage real de la sesión del subagente. */\nfunction usageFromSession(session: AgentSession): AgentUsage {\n\ttry {\n\t\tconst stats = session.getSessionStats();\n\t\tconst tokens = stats.tokens;\n\t\treturn {\n\t\t\tinput: tokens.input,\n\t\t\toutput: tokens.output,\n\t\t\ttotal: tokens.total,\n\t\t\tcost: stats.cost ?? 0,\n\t\t\tcacheRead: tokens.cacheRead,\n\t\t\tcacheWrite: tokens.cacheWrite,\n\t\t};\n\t} catch {\n\t\treturn { input: 0, output: 0, total: 0, cost: 0, cacheRead: 0, cacheWrite: 0 };\n\t}\n}\n\n/**\n * Fallback de emergencia: solo se usa si el discovery dinámico no encuentra\n * NINGÚN modelo con coste entre los proveedores conectados. Cada entrada se\n * valida con hasConfiguredAuth — sin credenciales se cae al default (fail-safe).\n */\nconst CHEAP_MODEL_CANDIDATES: Array<[provider: string, modelId: string]> = [\n\t[\"anthropic\", \"claude-haiku-4-5\"],\n\t[\"google\", \"gemini-2.5-flash\"],\n\t[\"google\", \"gemini-2.0-flash\"],\n\t[\"openai\", \"gpt-4o-mini\"],\n\t[\"openai\", \"gpt-5-mini\"],\n];\n\ninterface ModelsConfig {\n\tcheap?: string;\n\tmain?: string;\n\tjudge?: string;\n\tcheapCandidates?: string[];\n\tcheapThinking?: string;\n\tmainThinking?: string;\n\tjudgeThinking?: string;\n}\n\n/** Lee workflows.models del settings.json del agentDir (sin SettingsManager — función pura). */\nfunction readModelsConfig(agentDir: string): ModelsConfig {\n\ttry {\n\t\tconst raw = readFileSync(join(agentDir, \"settings.json\"), \"utf-8\");\n\t\tconst parsed = JSON.parse(raw) as { workflows?: { models?: ModelsConfig } };\n\t\treturn parsed?.workflows?.models ?? {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Thinking level del tier (workflows.models.<tier>Thinking); undefined = default. */\nexport function thinkingForTier(agentDir: string, tier: \"cheap\" | \"main\" | \"judge\"): string | undefined {\n\tconst cfg = readModelsConfig(agentDir);\n\tconst value = tier === \"cheap\" ? cfg.cheapThinking : tier === \"judge\" ? cfg.judgeThinking : cfg.mainThinking;\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\n/** Parsea \"provider/model\" → [provider, model]; null si malformado. */\nfunction parseSpec(spec: string): [string, string] | null {\n\tconst slash = spec.indexOf(\"/\");\n\tif (slash <= 0 || slash === spec.length - 1) return null;\n\treturn [spec.slice(0, slash), spec.slice(slash + 1)];\n}\n\n/**\n * Discovery DINÁMICO de modelos baratos: recorre los proveedores CONECTADOS\n * (hasConfiguredAuth) del runtime, toma sus modelos con coste declarado y los\n * ordena por precio (input+output) ascendente. La lista siempre refleja lo\n * que el usuario tiene disponible de verdad — nunca modelos inexistentes.\n */\nfunction discoverCheapModels(runtime: ModelRuntime, max = 6): Array<[string, string]> {\n\tconst scored: Array<{ provider: string; model: string; cost: number }> = [];\n\tfor (const provider of runtime.getProviders()) {\n\t\tif (!runtime.hasConfiguredAuth(provider.id)) continue;\n\t\tfor (const model of runtime.getModels(provider.id)) {\n\t\t\tconst m = model as { modelId?: string; id?: string; cost?: { input?: number; output?: number } };\n\t\t\tconst modelId = m.modelId ?? m.id;\n\t\t\tconst cost = m.cost;\n\t\t\tif (!modelId || !cost || typeof cost.input !== \"number\" || typeof cost.output !== \"number\") continue;\n\t\t\tscored.push({ provider: provider.id, model: modelId, cost: cost.input + cost.output });\n\t\t}\n\t}\n\treturn scored\n\t\t.sort((a, b) => a.cost - b.cost)\n\t\t.slice(0, max)\n\t\t.map((x) => [x.provider, x.model]);\n}\n\n/** Lista del usuario (workflows.models.cheapCandidates). [] si no está configurada. */\nfunction userCheapCandidates(agentDir: string): Array<[string, string]> {\n\tconst configured = readModelsConfig(agentDir).cheapCandidates;\n\tif (!Array.isArray(configured) || configured.length === 0) return [];\n\t// Solo entradas válidas \"provider/model\" (las malas se saltan).\n\treturn configured\n\t\t.map((c) => (typeof c === \"string\" ? parseSpec(c) : null))\n\t\t.filter((c): c is [string, string] => c !== null);\n}\n\n/**\n * Resuelve el modelSpec de un subagente a un Model concreto.\n * - \"tier:cheap\" → cascada:\n * 1. workflows.models.cheap (\"provider/model\" directo)\n * 2. workflows.models.cheapCandidates (lista del usuario, en orden)\n * 3. DISCOVERY DINÁMICO: el modelo más barato con coste declarado de los\n * proveedores CONECTADOS (refleja siempre el catálogo real del SDK)\n * 4. fallback estático curado (solo si el discovery no encontró nada)\n * - \"tier:main\"/\"tier:judge\" → workflows.models.main/judge, si no default.\n * - \"provider/model\" → directo si está autenticado.\n * Devuelve undefined → createAgentSession usa su resolución por defecto.\n */\nexport async function resolveSubagentModel(\n\tagentDir: string,\n\tspec: string | undefined,\n): Promise<Model<any> | undefined> {\n\tif (!spec) return undefined;\n\tlet runtime: ModelRuntime;\n\ttry {\n\t\truntime = await ModelRuntime.create({\n\t\t\tauthPath: join(agentDir, \"auth.json\"),\n\t\t\tmodelsPath: join(agentDir, \"models.json\"),\n\t\t});\n\t} catch {\n\t\treturn undefined; // fail-safe: default\n\t}\n\tconst tryGet = (provider: string, modelId: string): Model<any> | undefined => {\n\t\tconst m = runtime.getModel(provider, modelId);\n\t\treturn m && runtime.hasConfiguredAuth(provider) ? m : undefined;\n\t};\n\n\tif (spec.startsWith(\"tier:\")) {\n\t\tconst tier = spec.slice(5);\n\t\t// Settings override PRIMERO: workflows.models.<tier> = \"provider/model\"\n\t\tconst models = readModelsConfig(agentDir);\n\t\tconst override = tier === \"cheap\" ? models.cheap : tier === \"judge\" ? models.judge : models.main;\n\t\tconst overrideSpec = override ? parseSpec(override) : null;\n\t\tif (overrideSpec) {\n\t\t\tconst m = tryGet(overrideSpec[0], overrideSpec[1]);\n\t\t\tif (m) return m;\n\t\t}\n\t\tif (tier === \"cheap\") {\n\t\t\t// 1. Lista explícita del usuario (workflows.models.cheapCandidates).\n\t\t\tfor (const candidate of userCheapCandidates(agentDir)) {\n\t\t\t\tconst m = tryGet(candidate[0], candidate[1]);\n\t\t\t\tif (m) return m;\n\t\t\t}\n\t\t\t// 2. DISCOVERY DINÁMICO: el más barato con coste declarado entre los\n\t\t\t// proveedores CONECTADOS — refleja siempre el catálogo real del SDK.\n\t\t\tfor (const [providerId, modelId] of discoverCheapModels(runtime)) {\n\t\t\t\tconst m = tryGet(providerId, modelId);\n\t\t\t\tif (m) return m;\n\t\t\t}\n\t\t\t// 3. Fallback estático de emergencia (solo si el discovery no encontró\n\t\t\t// nada — p.ej. catálogos sin costes declarados).\n\t\t\tfor (const candidate of CHEAP_MODEL_CANDIDATES) {\n\t\t\t\tconst m = tryGet(candidate[0], candidate[1]);\n\t\t\t\tif (m) return m;\n\t\t\t}\n\t\t\treturn undefined;\n\t\t}\n\t\t// tier:main / tier:judge sin override → default del host (fail-safe)\n\t\treturn undefined;\n\t}\n\n\t// \"provider/model\" explícito\n\tconst slash = spec.indexOf(\"/\");\n\tif (slash <= 0 || slash === spec.length - 1) return undefined;\n\tconst provider = spec.slice(0, slash);\n\tconst modelId = spec.slice(slash + 1);\n\treturn tryGet(provider, modelId) ?? undefined;\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ada Intelligence Engine — tool `workflow` para el agente principal (§16.1).
|
|
3
|
+
*
|
|
4
|
+
* Permite al agente lanzar/consultar/abortar workflows con CONFIRMACIÓN de
|
|
5
|
+
* coste estimado (nunca ejecuta un run costoso a ciegas). Resuelve el
|
|
6
|
+
* WorkflowManager por llamada vía getter inyectado.
|
|
7
|
+
*/
|
|
8
|
+
import type { ToolDefinition } from "../extensions/types.ts";
|
|
9
|
+
import type { WorkflowManager } from "./manager.ts";
|
|
10
|
+
export interface WorkflowToolContext {
|
|
11
|
+
/** getter que devuelve el mangager (lazy). */
|
|
12
|
+
getManager: () => WorkflowManager | null;
|
|
13
|
+
/** Confirmación humana inyectable (para tests). Devuelve true si ok. */
|
|
14
|
+
confirm?: (prompt: string) => Promise<boolean>;
|
|
15
|
+
/** agentDir para resolver scripts guardados del usuario. */
|
|
16
|
+
agentDir?: string;
|
|
17
|
+
/** SessionId de la sesión que lanza (el panel filtra los runs por esto). */
|
|
18
|
+
sessionId?: () => string | undefined;
|
|
19
|
+
}
|
|
20
|
+
/** Crea la tool workflow para la sesión principal. */
|
|
21
|
+
export declare function createWorkflowTool(ctx: WorkflowToolContext): ToolDefinition;
|
|
22
|
+
//# sourceMappingURL=tool-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-workflow.d.ts","sourceRoot":"","sources":["../../../src/core/workflows/tool-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAqC,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGpD,MAAM,WAAW,mBAAmB;IACnC,8CAA8C;IAC9C,UAAU,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;IACzC,yEAAwE;IACxE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,MAAM,GAAG,SAAS,CAAC;CACrC;AAaD,uDAAsD;AACtD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,mBAAmB,GAAG,cAAc,CAsG3E","sourcesContent":["/**\n * Ada Intelligence Engine — tool `workflow` para el agente principal (§16.1).\n *\n * Permite al agente lanzar/consultar/abortar workflows con CONFIRMACIÓN de\n * coste estimado (nunca ejecuta un run costoso a ciegas). Resuelve el\n * WorkflowManager por llamada vía getter inyectado.\n */\n\nimport { Type } from \"typebox\";\nimport type { AgentToolResult, ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport type { WorkflowManager } from \"./manager.ts\";\nimport { resolveBuiltinWorkflowScript, resolveWorkflowScriptByName } from \"./resolve-script.ts\";\n\nexport interface WorkflowToolContext {\n\t/** getter que devuelve el mangager (lazy). */\n\tgetManager: () => WorkflowManager | null;\n\t/** Confirmación humana inyectable (para tests). Devuelve true si ok. */\n\tconfirm?: (prompt: string) => Promise<boolean>;\n\t/** agentDir para resolver scripts guardados del usuario. */\n\tagentDir?: string;\n\t/** SessionId de la sesión que lanza (el panel filtra los runs por esto). */\n\tsessionId?: () => string | undefined;\n}\n\ntype OkResult = AgentToolResult<undefined>;\n\nfunction reply(ok: boolean, text: unknown): OkResult {\n\treturn {\n\t\tdetails: undefined,\n\t\tcontent: [\n\t\t\t{ type: \"text\", text: JSON.stringify({ ok, ...(typeof text === \"object\" ? text : { message: text }) }) },\n\t\t],\n\t};\n}\n\n/** Crea la tool workflow para la sesión principal. */\nexport function createWorkflowTool(ctx: WorkflowToolContext): ToolDefinition {\n\tconst confirm = ctx.confirm ?? (async () => true);\n\treturn {\n\t\tname: \"workflow\",\n\t\tlabel: \"Workflow\",\n\t\tdescription:\n\t\t\t\"Lanza o gestiona un workflow del Ada Intelligence Engine (deep-research, code-review, product-build, multi-perspective, o un script guardado). SIEMPRE pide confirmación del coste estimado antes de lanzar un run costoso. Subcomandos: run | list | status | abort.\",\n\t\tpromptSnippet: \"Lanza/gestiona workflows con confirmación de coste (workflow run|list|status|abort)\",\n\t\tpromptGuidelines: [\n\t\t\t\"Usa workflow run para lanzar deep-research o code-review; pide siempre confirmación de coste.\",\n\t\t\t\"Usa workflow status para consultar el estado de un run en curso.\",\n\t\t\t\"Usa workflow abort para cancelar un run.\",\n\t\t],\n\t\tparameters: Type.Object({\n\t\t\tcommand: Type.Union([\n\t\t\t\tType.Literal(\"run\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"status\"),\n\t\t\t\tType.Literal(\"abort\"),\n\t\t\t]),\n\t\t\tname: Type.Optional(\n\t\t\t\tType.String({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Nombre del workflow / del run (deep_research, code_review, product_build, multi_perspective o script guardado)\",\n\t\t\t\t}),\n\t\t\t),\n\t\t\tquestion: Type.Optional(Type.String({ description: \"Pregunta o brief (para deep-research)\" })),\n\t\t\trunId: Type.Optional(Type.String({ description: \"id del run (para status/abort)\" })),\n\t\t\tawait: Type.Optional(Type.Boolean({ description: \"Esperar a que termine (default true)\" })),\n\t\t}),\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: {\n\t\t\t\tcommand: \"run\" | \"list\" | \"status\" | \"abort\";\n\t\t\t\tname?: string;\n\t\t\t\tquestion?: string;\n\t\t\t\trunId?: string;\n\t\t\t\tawait?: boolean;\n\t\t\t},\n\t\t\t_signal: AbortSignal | undefined,\n\t\t\t_onUpdate: unknown,\n\t\t\t_ctx: ExtensionContext,\n\t\t): Promise<OkResult> {\n\t\t\tconst manager = ctx.getManager();\n\n\t\t\tswitch (input.command) {\n\t\t\t\tcase \"list\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tconst runs = await manager.list().catch(() => []);\n\t\t\t\t\treturn reply(true, { runs: runs.slice(0, 20), count: runs.length });\n\t\t\t\t}\n\t\t\t\tcase \"status\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tif (!input.runId) return reply(false, \"workflow status exige runId\");\n\t\t\t\t\tconst state = await manager.state(input.runId).catch(() => null);\n\t\t\t\t\treturn state\n\t\t\t\t\t\t? reply(true, {\n\t\t\t\t\t\t\t\trunId: state.runId,\n\t\t\t\t\t\t\t\tname: state.name,\n\t\t\t\t\t\t\t\tstatus: state.status,\n\t\t\t\t\t\t\t\tagentCount: state.agentCount,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: reply(false, \"run no encontrado\");\n\t\t\t\t}\n\t\t\t\tcase \"abort\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tif (!input.runId) return reply(false, \"workflow abort exige runId\");\n\t\t\t\t\tconst aborted = manager.abort(input.runId);\n\t\t\t\t\treturn reply(true, { aborted, runId: input.runId });\n\t\t\t\t}\n\t\t\t\tcase \"run\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tconst name = input.name ?? \"\";\n\t\t\t\t\tif (!name) return reply(false, \"workflow run exige name\");\n\t\t\t\t\t// Confirmación de coste estimado (nunca a ciegas).\n\t\t\t\t\tconst estimated = estimateCost(name);\n\t\t\t\t\tconst ok = await confirm(\n\t\t\t\t\t\t`Lanzar workflow \"${name}\"${input.question ? ` (${input.question})` : \"\"}.\\n` +\n\t\t\t\t\t\t\t`Coste estimado: ~${estimated.usd} USD / ${estimated.tokens} tokens. ¿Continuar?`,\n\t\t\t\t\t);\n\t\t\t\t\tif (!ok) return reply(false, \"lanzamiento cancelado por el usuario\");\n\t\t\t\t\tconst script = resolveWorkflowScript(ctx.agentDir, name);\n\t\t\t\t\tif (!script)\n\t\t\t\t\t\treturn reply(\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t`script de workflow no encontrado: ${name} (builtin o <agentDir>/workflows/${name}.js)`,\n\t\t\t\t\t\t);\n\t\t\t\t\tconst toolSid = ctx.sessionId?.();\n\t\t\t\t\tconst result = await manager\n\t\t\t\t\t\t.execute(script, {\n\t\t\t\t\t\t\targs: { question: input.question, name },\n\t\t\t\t\t\t\tawait: input.await ?? true,\n\t\t\t\t\t\t\tdisplayName: name,\n\t\t\t\t\t\t\t...(toolSid ? { sessionId: toolSid } : {}),\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => ({ error: e instanceof Error ? e.message : String(e) }));\n\t\t\t\t\tif (\"error\" in result && result.error) return reply(false, result.error);\n\t\t\t\t\treturn reply(true, result);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n\n/** Coste estimado por tipo de workflow (heurística simple). */\nfunction estimateCost(name: string): { usd: number; tokens: number } {\n\tconst tokens = name.includes(\"deep\") || name.includes(\"product\") ? 60000 : 25000;\n\treturn { usd: Math.round(tokens * 0.00001 * 100) / 100, tokens };\n}\n\n/** Resuelve el script del workflow: builtin o guardado en <agentDir>/workflows/. */\nfunction resolveWorkflowScript(agentDir: string | undefined, name: string): string | null {\n\tif (!agentDir) return resolveBuiltinWorkflowScript(name);\n\treturn resolveWorkflowScriptByName(agentDir, name)?.script ?? null;\n}\n"]}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ada Intelligence Engine — tool `workflow` para el agente principal (§16.1).
|
|
3
|
+
*
|
|
4
|
+
* Permite al agente lanzar/consultar/abortar workflows con CONFIRMACIÓN de
|
|
5
|
+
* coste estimado (nunca ejecuta un run costoso a ciegas). Resuelve el
|
|
6
|
+
* WorkflowManager por llamada vía getter inyectado.
|
|
7
|
+
*/
|
|
8
|
+
import { Type } from "typebox";
|
|
9
|
+
import { resolveBuiltinWorkflowScript, resolveWorkflowScriptByName } from "./resolve-script.js";
|
|
10
|
+
function reply(ok, text) {
|
|
11
|
+
return {
|
|
12
|
+
details: undefined,
|
|
13
|
+
content: [
|
|
14
|
+
{ type: "text", text: JSON.stringify({ ok, ...(typeof text === "object" ? text : { message: text }) }) },
|
|
15
|
+
],
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Crea la tool workflow para la sesión principal. */
|
|
19
|
+
export function createWorkflowTool(ctx) {
|
|
20
|
+
const confirm = ctx.confirm ?? (async () => true);
|
|
21
|
+
return {
|
|
22
|
+
name: "workflow",
|
|
23
|
+
label: "Workflow",
|
|
24
|
+
description: "Lanza o gestiona un workflow del Ada Intelligence Engine (deep-research, code-review, product-build, multi-perspective, o un script guardado). SIEMPRE pide confirmación del coste estimado antes de lanzar un run costoso. Subcomandos: run | list | status | abort.",
|
|
25
|
+
promptSnippet: "Lanza/gestiona workflows con confirmación de coste (workflow run|list|status|abort)",
|
|
26
|
+
promptGuidelines: [
|
|
27
|
+
"Usa workflow run para lanzar deep-research o code-review; pide siempre confirmación de coste.",
|
|
28
|
+
"Usa workflow status para consultar el estado de un run en curso.",
|
|
29
|
+
"Usa workflow abort para cancelar un run.",
|
|
30
|
+
],
|
|
31
|
+
parameters: Type.Object({
|
|
32
|
+
command: Type.Union([
|
|
33
|
+
Type.Literal("run"),
|
|
34
|
+
Type.Literal("list"),
|
|
35
|
+
Type.Literal("status"),
|
|
36
|
+
Type.Literal("abort"),
|
|
37
|
+
]),
|
|
38
|
+
name: Type.Optional(Type.String({
|
|
39
|
+
description: "Nombre del workflow / del run (deep_research, code_review, product_build, multi_perspective o script guardado)",
|
|
40
|
+
})),
|
|
41
|
+
question: Type.Optional(Type.String({ description: "Pregunta o brief (para deep-research)" })),
|
|
42
|
+
runId: Type.Optional(Type.String({ description: "id del run (para status/abort)" })),
|
|
43
|
+
await: Type.Optional(Type.Boolean({ description: "Esperar a que termine (default true)" })),
|
|
44
|
+
}),
|
|
45
|
+
async execute(_toolCallId, input, _signal, _onUpdate, _ctx) {
|
|
46
|
+
const manager = ctx.getManager();
|
|
47
|
+
switch (input.command) {
|
|
48
|
+
case "list": {
|
|
49
|
+
if (!manager)
|
|
50
|
+
return reply(false, "workflow manager no disponible");
|
|
51
|
+
const runs = await manager.list().catch(() => []);
|
|
52
|
+
return reply(true, { runs: runs.slice(0, 20), count: runs.length });
|
|
53
|
+
}
|
|
54
|
+
case "status": {
|
|
55
|
+
if (!manager)
|
|
56
|
+
return reply(false, "workflow manager no disponible");
|
|
57
|
+
if (!input.runId)
|
|
58
|
+
return reply(false, "workflow status exige runId");
|
|
59
|
+
const state = await manager.state(input.runId).catch(() => null);
|
|
60
|
+
return state
|
|
61
|
+
? reply(true, {
|
|
62
|
+
runId: state.runId,
|
|
63
|
+
name: state.name,
|
|
64
|
+
status: state.status,
|
|
65
|
+
agentCount: state.agentCount,
|
|
66
|
+
})
|
|
67
|
+
: reply(false, "run no encontrado");
|
|
68
|
+
}
|
|
69
|
+
case "abort": {
|
|
70
|
+
if (!manager)
|
|
71
|
+
return reply(false, "workflow manager no disponible");
|
|
72
|
+
if (!input.runId)
|
|
73
|
+
return reply(false, "workflow abort exige runId");
|
|
74
|
+
const aborted = manager.abort(input.runId);
|
|
75
|
+
return reply(true, { aborted, runId: input.runId });
|
|
76
|
+
}
|
|
77
|
+
case "run": {
|
|
78
|
+
if (!manager)
|
|
79
|
+
return reply(false, "workflow manager no disponible");
|
|
80
|
+
const name = input.name ?? "";
|
|
81
|
+
if (!name)
|
|
82
|
+
return reply(false, "workflow run exige name");
|
|
83
|
+
// Confirmación de coste estimado (nunca a ciegas).
|
|
84
|
+
const estimated = estimateCost(name);
|
|
85
|
+
const ok = await confirm(`Lanzar workflow "${name}"${input.question ? ` (${input.question})` : ""}.\n` +
|
|
86
|
+
`Coste estimado: ~${estimated.usd} USD / ${estimated.tokens} tokens. ¿Continuar?`);
|
|
87
|
+
if (!ok)
|
|
88
|
+
return reply(false, "lanzamiento cancelado por el usuario");
|
|
89
|
+
const script = resolveWorkflowScript(ctx.agentDir, name);
|
|
90
|
+
if (!script)
|
|
91
|
+
return reply(false, `script de workflow no encontrado: ${name} (builtin o <agentDir>/workflows/${name}.js)`);
|
|
92
|
+
const toolSid = ctx.sessionId?.();
|
|
93
|
+
const result = await manager
|
|
94
|
+
.execute(script, {
|
|
95
|
+
args: { question: input.question, name },
|
|
96
|
+
await: input.await ?? true,
|
|
97
|
+
displayName: name,
|
|
98
|
+
...(toolSid ? { sessionId: toolSid } : {}),
|
|
99
|
+
})
|
|
100
|
+
.catch((e) => ({ error: e instanceof Error ? e.message : String(e) }));
|
|
101
|
+
if ("error" in result && result.error)
|
|
102
|
+
return reply(false, result.error);
|
|
103
|
+
return reply(true, result);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/** Coste estimado por tipo de workflow (heurística simple). */
|
|
110
|
+
function estimateCost(name) {
|
|
111
|
+
const tokens = name.includes("deep") || name.includes("product") ? 60000 : 25000;
|
|
112
|
+
return { usd: Math.round(tokens * 0.00001 * 100) / 100, tokens };
|
|
113
|
+
}
|
|
114
|
+
/** Resuelve el script del workflow: builtin o guardado en <agentDir>/workflows/. */
|
|
115
|
+
function resolveWorkflowScript(agentDir, name) {
|
|
116
|
+
if (!agentDir)
|
|
117
|
+
return resolveBuiltinWorkflowScript(name);
|
|
118
|
+
return resolveWorkflowScriptByName(agentDir, name)?.script ?? null;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=tool-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-workflow.js","sourceRoot":"","sources":["../../../src/core/workflows/tool-workflow.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Ada Intelligence Engine — tool `workflow` para el agente principal (§16.1).\n *\n * Permite al agente lanzar/consultar/abortar workflows con CONFIRMACIÓN de\n * coste estimado (nunca ejecuta un run costoso a ciegas). Resuelve el\n * WorkflowManager por llamada vía getter inyectado.\n */\n\nimport { Type } from \"typebox\";\nimport type { AgentToolResult, ExtensionContext, ToolDefinition } from \"../extensions/types.ts\";\nimport type { WorkflowManager } from \"./manager.ts\";\nimport { resolveBuiltinWorkflowScript, resolveWorkflowScriptByName } from \"./resolve-script.ts\";\n\nexport interface WorkflowToolContext {\n\t/** getter que devuelve el mangager (lazy). */\n\tgetManager: () => WorkflowManager | null;\n\t/** Confirmación humana inyectable (para tests). Devuelve true si ok. */\n\tconfirm?: (prompt: string) => Promise<boolean>;\n\t/** agentDir para resolver scripts guardados del usuario. */\n\tagentDir?: string;\n\t/** SessionId de la sesión que lanza (el panel filtra los runs por esto). */\n\tsessionId?: () => string | undefined;\n}\n\ntype OkResult = AgentToolResult<undefined>;\n\nfunction reply(ok: boolean, text: unknown): OkResult {\n\treturn {\n\t\tdetails: undefined,\n\t\tcontent: [\n\t\t\t{ type: \"text\", text: JSON.stringify({ ok, ...(typeof text === \"object\" ? text : { message: text }) }) },\n\t\t],\n\t};\n}\n\n/** Crea la tool workflow para la sesión principal. */\nexport function createWorkflowTool(ctx: WorkflowToolContext): ToolDefinition {\n\tconst confirm = ctx.confirm ?? (async () => true);\n\treturn {\n\t\tname: \"workflow\",\n\t\tlabel: \"Workflow\",\n\t\tdescription:\n\t\t\t\"Lanza o gestiona un workflow del Ada Intelligence Engine (deep-research, code-review, product-build, multi-perspective, o un script guardado). SIEMPRE pide confirmación del coste estimado antes de lanzar un run costoso. Subcomandos: run | list | status | abort.\",\n\t\tpromptSnippet: \"Lanza/gestiona workflows con confirmación de coste (workflow run|list|status|abort)\",\n\t\tpromptGuidelines: [\n\t\t\t\"Usa workflow run para lanzar deep-research o code-review; pide siempre confirmación de coste.\",\n\t\t\t\"Usa workflow status para consultar el estado de un run en curso.\",\n\t\t\t\"Usa workflow abort para cancelar un run.\",\n\t\t],\n\t\tparameters: Type.Object({\n\t\t\tcommand: Type.Union([\n\t\t\t\tType.Literal(\"run\"),\n\t\t\t\tType.Literal(\"list\"),\n\t\t\t\tType.Literal(\"status\"),\n\t\t\t\tType.Literal(\"abort\"),\n\t\t\t]),\n\t\t\tname: Type.Optional(\n\t\t\t\tType.String({\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t\"Nombre del workflow / del run (deep_research, code_review, product_build, multi_perspective o script guardado)\",\n\t\t\t\t}),\n\t\t\t),\n\t\t\tquestion: Type.Optional(Type.String({ description: \"Pregunta o brief (para deep-research)\" })),\n\t\t\trunId: Type.Optional(Type.String({ description: \"id del run (para status/abort)\" })),\n\t\t\tawait: Type.Optional(Type.Boolean({ description: \"Esperar a que termine (default true)\" })),\n\t\t}),\n\t\tasync execute(\n\t\t\t_toolCallId: string,\n\t\t\tinput: {\n\t\t\t\tcommand: \"run\" | \"list\" | \"status\" | \"abort\";\n\t\t\t\tname?: string;\n\t\t\t\tquestion?: string;\n\t\t\t\trunId?: string;\n\t\t\t\tawait?: boolean;\n\t\t\t},\n\t\t\t_signal: AbortSignal | undefined,\n\t\t\t_onUpdate: unknown,\n\t\t\t_ctx: ExtensionContext,\n\t\t): Promise<OkResult> {\n\t\t\tconst manager = ctx.getManager();\n\n\t\t\tswitch (input.command) {\n\t\t\t\tcase \"list\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tconst runs = await manager.list().catch(() => []);\n\t\t\t\t\treturn reply(true, { runs: runs.slice(0, 20), count: runs.length });\n\t\t\t\t}\n\t\t\t\tcase \"status\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tif (!input.runId) return reply(false, \"workflow status exige runId\");\n\t\t\t\t\tconst state = await manager.state(input.runId).catch(() => null);\n\t\t\t\t\treturn state\n\t\t\t\t\t\t? reply(true, {\n\t\t\t\t\t\t\t\trunId: state.runId,\n\t\t\t\t\t\t\t\tname: state.name,\n\t\t\t\t\t\t\t\tstatus: state.status,\n\t\t\t\t\t\t\t\tagentCount: state.agentCount,\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t: reply(false, \"run no encontrado\");\n\t\t\t\t}\n\t\t\t\tcase \"abort\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tif (!input.runId) return reply(false, \"workflow abort exige runId\");\n\t\t\t\t\tconst aborted = manager.abort(input.runId);\n\t\t\t\t\treturn reply(true, { aborted, runId: input.runId });\n\t\t\t\t}\n\t\t\t\tcase \"run\": {\n\t\t\t\t\tif (!manager) return reply(false, \"workflow manager no disponible\");\n\t\t\t\t\tconst name = input.name ?? \"\";\n\t\t\t\t\tif (!name) return reply(false, \"workflow run exige name\");\n\t\t\t\t\t// Confirmación de coste estimado (nunca a ciegas).\n\t\t\t\t\tconst estimated = estimateCost(name);\n\t\t\t\t\tconst ok = await confirm(\n\t\t\t\t\t\t`Lanzar workflow \"${name}\"${input.question ? ` (${input.question})` : \"\"}.\\n` +\n\t\t\t\t\t\t\t`Coste estimado: ~${estimated.usd} USD / ${estimated.tokens} tokens. ¿Continuar?`,\n\t\t\t\t\t);\n\t\t\t\t\tif (!ok) return reply(false, \"lanzamiento cancelado por el usuario\");\n\t\t\t\t\tconst script = resolveWorkflowScript(ctx.agentDir, name);\n\t\t\t\t\tif (!script)\n\t\t\t\t\t\treturn reply(\n\t\t\t\t\t\t\tfalse,\n\t\t\t\t\t\t\t`script de workflow no encontrado: ${name} (builtin o <agentDir>/workflows/${name}.js)`,\n\t\t\t\t\t\t);\n\t\t\t\t\tconst toolSid = ctx.sessionId?.();\n\t\t\t\t\tconst result = await manager\n\t\t\t\t\t\t.execute(script, {\n\t\t\t\t\t\t\targs: { question: input.question, name },\n\t\t\t\t\t\t\tawait: input.await ?? true,\n\t\t\t\t\t\t\tdisplayName: name,\n\t\t\t\t\t\t\t...(toolSid ? { sessionId: toolSid } : {}),\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.catch((e) => ({ error: e instanceof Error ? e.message : String(e) }));\n\t\t\t\t\tif (\"error\" in result && result.error) return reply(false, result.error);\n\t\t\t\t\treturn reply(true, result);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t};\n}\n\n/** Coste estimado por tipo de workflow (heurística simple). */\nfunction estimateCost(name: string): { usd: number; tokens: number } {\n\tconst tokens = name.includes(\"deep\") || name.includes(\"product\") ? 60000 : 25000;\n\treturn { usd: Math.round(tokens * 0.00001 * 100) / 100, tokens };\n}\n\n/** Resuelve el script del workflow: builtin o guardado en <agentDir>/workflows/. */\nfunction resolveWorkflowScript(agentDir: string | undefined, name: string): string | null {\n\tif (!agentDir) return resolveBuiltinWorkflowScript(name);\n\treturn resolveWorkflowScriptByName(agentDir, name)?.script ?? null;\n}\n"]}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ada Intelligence Engine — shared types (Fase 1).
|
|
3
|
+
*
|
|
4
|
+
* Workflows dinámicos: scripts JS en sandbox vm con agent/parallel/pipeline/
|
|
5
|
+
* store/phase/workflow/checkpoint; subagentes via AgentSessionRuntime; journal
|
|
6
|
+
* con resume determinista; SharedStore con deltas por agente.
|
|
7
|
+
*/
|
|
8
|
+
import type { TSchema } from "typebox";
|
|
9
|
+
import type { ToolDefinition } from "../extensions/types.ts";
|
|
10
|
+
export interface WorkflowPhase {
|
|
11
|
+
title: string;
|
|
12
|
+
detail?: string;
|
|
13
|
+
model?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface WorkflowMeta {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
phases?: WorkflowPhase[];
|
|
19
|
+
/** Modelo por defecto para agentes sin ruta de fase ni model/tier. */
|
|
20
|
+
model?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface WorkflowLimits {
|
|
23
|
+
maxAgentsPerRun: number;
|
|
24
|
+
maxConcurrency: number;
|
|
25
|
+
maxRetries: number;
|
|
26
|
+
/** Timeout por agente en ms; null = sin timeout. */
|
|
27
|
+
agentTimeoutMs: number | null;
|
|
28
|
+
/** Timeout del script vm en ms. */
|
|
29
|
+
scriptTimeoutMs: number;
|
|
30
|
+
/** Timeout del drain de agentes in-flight en ms (finito — adversarial B). */
|
|
31
|
+
drainTimeoutMs: number;
|
|
32
|
+
}
|
|
33
|
+
export declare const DEFAULT_WORKFLOW_LIMITS: WorkflowLimits;
|
|
34
|
+
export interface AgentRunOptions<TSchemaDef extends TSchema | undefined = TSchema | undefined> {
|
|
35
|
+
prompt: string;
|
|
36
|
+
label?: string;
|
|
37
|
+
/** Modelo "provider/model" o "model" — MODEL_NOT_FOUND si no resuelve. */
|
|
38
|
+
model?: string;
|
|
39
|
+
/** Tier ("small"|"medium"|"big") con fallback al modelo de sesión. */
|
|
40
|
+
tier?: string;
|
|
41
|
+
/** Fase actual (routing + UI). */
|
|
42
|
+
phase?: string;
|
|
43
|
+
/** Structured output (typebox). */
|
|
44
|
+
schema?: TSchemaDef;
|
|
45
|
+
/** Tools extra (web_search/web_fetch…). Se AÑADEN a las del agente. */
|
|
46
|
+
tools?: ToolDefinition[];
|
|
47
|
+
/**
|
|
48
|
+
* Mínimo privilegio: el agente solo puede leer (`read`/`grep`/`find`/`ls`).
|
|
49
|
+
* Para fases de análisis que no deben poder escribir ni ejecutar comandos.
|
|
50
|
+
* No es un sandbox de SO — acota las tools del subagente, nada más.
|
|
51
|
+
*/
|
|
52
|
+
readOnly?: boolean;
|
|
53
|
+
instructions?: string;
|
|
54
|
+
/** Aislamiento git. */
|
|
55
|
+
isolation?: "none" | "worktree";
|
|
56
|
+
/** Clave determinista del worktree (runId:callIndex) — la pone el runtime. */
|
|
57
|
+
isolationKey?: string;
|
|
58
|
+
timeoutMs?: number | null;
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
/** Clave estable para cache/resume (el autor declara idempotencia). */
|
|
61
|
+
stableKey?: string;
|
|
62
|
+
/** cwd del agente (base o worktree). Default: cwd del run. */
|
|
63
|
+
cwd?: string;
|
|
64
|
+
}
|
|
65
|
+
export interface AgentUsage {
|
|
66
|
+
input: number;
|
|
67
|
+
output: number;
|
|
68
|
+
total: number;
|
|
69
|
+
cost: number;
|
|
70
|
+
cacheRead?: number;
|
|
71
|
+
cacheWrite?: number;
|
|
72
|
+
}
|
|
73
|
+
export interface AgentRunResult<T = unknown> {
|
|
74
|
+
result: T | null;
|
|
75
|
+
text: string;
|
|
76
|
+
usage: AgentUsage;
|
|
77
|
+
sessionId?: string;
|
|
78
|
+
/** Rama `ada/wf/*` con el trabajo del agente, si corrió aislado y escribió. */
|
|
79
|
+
worktreeBranch?: string;
|
|
80
|
+
}
|
|
81
|
+
export interface JournalEntry {
|
|
82
|
+
index: number;
|
|
83
|
+
runId?: string;
|
|
84
|
+
/** sha256 de la identidad (prompt+model+phase+schema+stableKey). */
|
|
85
|
+
hash: string;
|
|
86
|
+
result: unknown;
|
|
87
|
+
/** Deltas del store escritos por este agente (replay aditivo). */
|
|
88
|
+
storeDelta?: Record<string, unknown>;
|
|
89
|
+
/** Marcado cuando el resultado vino de extracción de prosa (fallback schema). */
|
|
90
|
+
origin?: "structured" | "recovered";
|
|
91
|
+
}
|
|
92
|
+
export interface SharedStoreApi {
|
|
93
|
+
put(key: string, value: unknown): void;
|
|
94
|
+
get<T = unknown>(key: string): T | undefined;
|
|
95
|
+
has(key: string): boolean;
|
|
96
|
+
delete(key: string): void;
|
|
97
|
+
entries(): Array<[string, unknown]>;
|
|
98
|
+
}
|
|
99
|
+
export interface CheckpointOptions {
|
|
100
|
+
default?: unknown;
|
|
101
|
+
headless?: "default" | "abort";
|
|
102
|
+
kind?: "confirm" | "input" | "select";
|
|
103
|
+
choices?: string[];
|
|
104
|
+
}
|
|
105
|
+
export interface WorkflowApi {
|
|
106
|
+
agent(options: AgentRunOptions): Promise<unknown>;
|
|
107
|
+
parallel<R>(fns: Array<() => Promise<R>>): Promise<Array<Awaited<R>>>;
|
|
108
|
+
pipeline<R>(fns: Array<(prev?: Awaited<R>) => Promise<R>>): Promise<Awaited<R>>;
|
|
109
|
+
phase(title: string, detail?: string): void;
|
|
110
|
+
store: SharedStoreApi;
|
|
111
|
+
checkpoint<T>(promptText: string, options?: CheckpointOptions): Promise<T>;
|
|
112
|
+
args: Record<string, unknown>;
|
|
113
|
+
cwd: string;
|
|
114
|
+
runId: string;
|
|
115
|
+
log(message: string): void;
|
|
116
|
+
}
|
|
117
|
+
export interface WorkflowRunResult<T = unknown> {
|
|
118
|
+
meta: WorkflowMeta;
|
|
119
|
+
result: T;
|
|
120
|
+
logs: string[];
|
|
121
|
+
phases: string[];
|
|
122
|
+
agentCount: number;
|
|
123
|
+
durationMs: number;
|
|
124
|
+
runId: string;
|
|
125
|
+
tokenUsage: {
|
|
126
|
+
input: number;
|
|
127
|
+
output: number;
|
|
128
|
+
total: number;
|
|
129
|
+
cost: number;
|
|
130
|
+
cacheRead?: number;
|
|
131
|
+
cacheWrite?: number;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export type WorkflowErrorCode = "WORKFLOW_INVALID_SCRIPT" | "WORKFLOW_SCRIPT_TIMEOUT" | "WORKFLOW_AGENT_TIMEOUT" | "WORKFLOW_MAX_AGENTS" | "WORKFLOW_ABORTED" | "WORKFLOW_BUDGET_EXCEEDED" | "WORKFLOW_RESUME_CORRUPT" | "MODEL_NOT_FOUND";
|
|
135
|
+
export declare class WorkflowError extends Error {
|
|
136
|
+
readonly code: WorkflowErrorCode;
|
|
137
|
+
readonly recoverable: boolean;
|
|
138
|
+
constructor(code: WorkflowErrorCode, message: string, options?: {
|
|
139
|
+
recoverable?: boolean;
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=types.d.ts.map
|