@nodetool-ai/cli 0.7.0-rc.22 → 0.8.1
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/README.md +79 -0
- package/dist/.nodetool-build-stamp +1 -0
- package/dist/ExecutionTree.d.ts +2 -1
- package/dist/ExecutionTree.d.ts.map +1 -1
- package/dist/ExecutionTree.js +1 -1
- package/dist/ExecutionTree.js.map +1 -1
- package/dist/affected/affected.d.ts +50 -0
- package/dist/affected/affected.d.ts.map +1 -0
- package/dist/affected/affected.js +118 -0
- package/dist/affected/affected.js.map +1 -0
- package/dist/agent-toolbelt.d.ts +15 -0
- package/dist/agent-toolbelt.d.ts.map +1 -0
- package/dist/agent-toolbelt.js +28 -0
- package/dist/agent-toolbelt.js.map +1 -0
- package/dist/api-client.d.ts +12 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +21 -0
- package/dist/api-client.js.map +1 -0
- package/dist/app-build/bundle.d.ts +15 -0
- package/dist/app-build/bundle.d.ts.map +1 -0
- package/dist/app-build/bundle.js +45 -0
- package/dist/app-build/bundle.js.map +1 -0
- package/dist/app-build/watch.d.ts +13 -0
- package/dist/app-build/watch.d.ts.map +1 -0
- package/dist/app-build/watch.js +25 -0
- package/dist/app-build/watch.js.map +1 -0
- package/dist/app-debug/app-target.d.ts +14 -0
- package/dist/app-debug/app-target.d.ts.map +1 -0
- package/dist/app-debug/app-target.js +120 -0
- package/dist/app-debug/app-target.js.map +1 -0
- package/dist/app-debug/harness.d.ts +27 -0
- package/dist/app-debug/harness.d.ts.map +1 -0
- package/dist/app-debug/harness.js +93 -0
- package/dist/app-debug/harness.js.map +1 -0
- package/dist/app-debug/index.d.ts +12 -0
- package/dist/app-debug/index.d.ts.map +1 -0
- package/dist/app-debug/index.js +9 -0
- package/dist/app-debug/index.js.map +1 -0
- package/dist/app.d.ts +38 -48
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +979 -677
- package/dist/app.js.map +1 -1
- package/dist/bash-tool.d.ts +13 -0
- package/dist/bash-tool.d.ts.map +1 -0
- package/dist/bash-tool.js +85 -0
- package/dist/bash-tool.js.map +1 -0
- package/dist/chat-codeact.d.ts +85 -0
- package/dist/chat-codeact.d.ts.map +1 -0
- package/dist/chat-codeact.js +141 -0
- package/dist/chat-codeact.js.map +1 -0
- package/dist/chat-context.d.ts +18 -0
- package/dist/chat-context.d.ts.map +1 -0
- package/dist/chat-context.js +27 -0
- package/dist/chat-context.js.map +1 -0
- package/dist/chat-media.d.ts +3 -0
- package/dist/chat-media.d.ts.map +1 -0
- package/dist/chat-media.js +46 -0
- package/dist/chat-media.js.map +1 -0
- package/dist/chat-prompts.d.ts +20 -0
- package/dist/chat-prompts.d.ts.map +1 -0
- package/dist/chat-prompts.js +42 -0
- package/dist/chat-prompts.js.map +1 -0
- package/dist/chat-sessions.d.ts +25 -0
- package/dist/chat-sessions.d.ts.map +1 -0
- package/dist/chat-sessions.js +153 -0
- package/dist/chat-sessions.js.map +1 -0
- package/dist/command-errors.d.ts +10 -0
- package/dist/command-errors.d.ts.map +1 -0
- package/dist/command-errors.js +15 -0
- package/dist/command-errors.js.map +1 -0
- package/dist/commands/__tests__/jtbd.test.d.ts +2 -0
- package/dist/commands/__tests__/jtbd.test.d.ts.map +1 -0
- package/dist/commands/__tests__/jtbd.test.js +120 -0
- package/dist/commands/__tests__/jtbd.test.js.map +1 -0
- package/dist/commands/__tests__/timeline-render-audio.test.d.ts +2 -0
- package/dist/commands/__tests__/timeline-render-audio.test.d.ts.map +1 -0
- package/dist/commands/__tests__/timeline-render-audio.test.js +53 -0
- package/dist/commands/__tests__/timeline-render-audio.test.js.map +1 -0
- package/dist/commands/__tests__/timeline-render.test.d.ts +2 -0
- package/dist/commands/__tests__/timeline-render.test.d.ts.map +1 -0
- package/dist/commands/__tests__/timeline-render.test.js +115 -0
- package/dist/commands/__tests__/timeline-render.test.js.map +1 -0
- package/dist/commands/affected.d.ts +9 -0
- package/dist/commands/affected.d.ts.map +1 -0
- package/dist/commands/affected.js +122 -0
- package/dist/commands/affected.js.map +1 -0
- package/dist/commands/agent.d.ts +26 -4
- package/dist/commands/agent.d.ts.map +1 -1
- package/dist/commands/agent.js +327 -306
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/app.d.ts +3 -0
- package/dist/commands/app.d.ts.map +1 -0
- package/dist/commands/app.js +381 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/apps.d.ts +15 -0
- package/dist/commands/apps.d.ts.map +1 -0
- package/dist/commands/apps.js +180 -0
- package/dist/commands/apps.js.map +1 -0
- package/dist/commands/auth.d.ts +12 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +154 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/collections.d.ts +10 -0
- package/dist/commands/collections.d.ts.map +1 -0
- package/dist/commands/collections.js +257 -0
- package/dist/commands/collections.js.map +1 -0
- package/dist/commands/costs.d.ts +15 -0
- package/dist/commands/costs.d.ts.map +1 -0
- package/dist/commands/costs.js +201 -0
- package/dist/commands/costs.js.map +1 -0
- package/dist/commands/db.d.ts +3 -0
- package/dist/commands/db.d.ts.map +1 -0
- package/dist/commands/db.js +176 -0
- package/dist/commands/db.js.map +1 -0
- package/dist/commands/debug.d.ts +13 -0
- package/dist/commands/debug.d.ts.map +1 -0
- package/dist/commands/debug.js +138 -0
- package/dist/commands/debug.js.map +1 -0
- package/dist/commands/deploy-helpers.d.ts +49 -18
- package/dist/commands/deploy-helpers.d.ts.map +1 -1
- package/dist/commands/deploy-helpers.js +10 -276
- package/dist/commands/deploy-helpers.js.map +1 -1
- package/dist/commands/deploy.d.ts +0 -1
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +21 -217
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/eval.d.ts +152 -0
- package/dist/commands/eval.d.ts.map +1 -0
- package/dist/commands/eval.js +688 -0
- package/dist/commands/eval.js.map +1 -0
- package/dist/commands/game.d.ts +4 -0
- package/dist/commands/game.d.ts.map +1 -0
- package/dist/commands/game.js +395 -0
- package/dist/commands/game.js.map +1 -0
- package/dist/commands/generate.d.ts +17 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +324 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/generations.d.ts +17 -0
- package/dist/commands/generations.d.ts.map +1 -0
- package/dist/commands/generations.js +408 -0
- package/dist/commands/generations.js.map +1 -0
- package/dist/commands/harness.d.ts +19 -0
- package/dist/commands/harness.d.ts.map +1 -0
- package/dist/commands/harness.js +361 -0
- package/dist/commands/harness.js.map +1 -0
- package/dist/commands/js-script-validation-output.d.ts +7 -0
- package/dist/commands/js-script-validation-output.d.ts.map +1 -0
- package/dist/commands/js-script-validation-output.js +5 -0
- package/dist/commands/js-script-validation-output.js.map +1 -0
- package/dist/commands/js-script-versions.d.ts +53 -0
- package/dist/commands/js-script-versions.d.ts.map +1 -0
- package/dist/commands/js-script-versions.js +89 -0
- package/dist/commands/js-script-versions.js.map +1 -0
- package/dist/commands/js-script.d.ts +29 -0
- package/dist/commands/js-script.d.ts.map +1 -0
- package/dist/commands/js-script.js +227 -0
- package/dist/commands/js-script.js.map +1 -0
- package/dist/commands/jtbd.d.ts +38 -0
- package/dist/commands/jtbd.d.ts.map +1 -0
- package/dist/commands/jtbd.js +261 -0
- package/dist/commands/jtbd.js.map +1 -0
- package/dist/commands/local-db.d.ts +16 -0
- package/dist/commands/local-db.d.ts.map +1 -0
- package/dist/commands/local-db.js +33 -0
- package/dist/commands/local-db.js.map +1 -0
- package/dist/commands/migrate-code-inputs.d.ts +24 -0
- package/dist/commands/migrate-code-inputs.d.ts.map +1 -0
- package/dist/commands/migrate-code-inputs.js +120 -0
- package/dist/commands/migrate-code-inputs.js.map +1 -0
- package/dist/commands/models-hf.js +4 -4
- package/dist/commands/models-hf.js.map +1 -1
- package/dist/commands/models-recommended.d.ts.map +1 -1
- package/dist/commands/models-recommended.js +16 -24
- package/dist/commands/models-recommended.js.map +1 -1
- package/dist/commands/node.d.ts +10 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +72 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/output.d.ts +24 -0
- package/dist/commands/output.d.ts.map +1 -0
- package/dist/commands/output.js +132 -0
- package/dist/commands/output.js.map +1 -0
- package/dist/commands/package-helpers.d.ts +1 -7
- package/dist/commands/package-helpers.d.ts.map +1 -1
- package/dist/commands/package-helpers.js +3 -26
- package/dist/commands/package-helpers.js.map +1 -1
- package/dist/commands/package.js +2 -2
- package/dist/commands/package.js.map +1 -1
- package/dist/commands/packs.d.ts +13 -0
- package/dist/commands/packs.d.ts.map +1 -0
- package/dist/commands/packs.js +60 -0
- package/dist/commands/packs.js.map +1 -0
- package/dist/commands/reliability.d.ts +14 -0
- package/dist/commands/reliability.d.ts.map +1 -0
- package/dist/commands/reliability.js +80 -0
- package/dist/commands/reliability.js.map +1 -0
- package/dist/commands/resource-read.d.ts +28 -0
- package/dist/commands/resource-read.d.ts.map +1 -0
- package/dist/commands/resource-read.js +316 -0
- package/dist/commands/resource-read.js.map +1 -0
- package/dist/commands/sketch-validation-output.d.ts +7 -0
- package/dist/commands/sketch-validation-output.d.ts.map +1 -0
- package/dist/commands/sketch-validation-output.js +5 -0
- package/dist/commands/sketch-validation-output.js.map +1 -0
- package/dist/commands/sketch-versions.d.ts +66 -0
- package/dist/commands/sketch-versions.d.ts.map +1 -0
- package/dist/commands/sketch-versions.js +108 -0
- package/dist/commands/sketch-versions.js.map +1 -0
- package/dist/commands/sketch.d.ts +21 -0
- package/dist/commands/sketch.d.ts.map +1 -0
- package/dist/commands/sketch.js +117 -0
- package/dist/commands/sketch.js.map +1 -0
- package/dist/commands/storage.d.ts +24 -0
- package/dist/commands/storage.d.ts.map +1 -0
- package/dist/commands/storage.js +112 -0
- package/dist/commands/storage.js.map +1 -0
- package/dist/commands/telegram.d.ts +11 -0
- package/dist/commands/telegram.d.ts.map +1 -0
- package/dist/commands/telegram.js +66 -0
- package/dist/commands/telegram.js.map +1 -0
- package/dist/commands/timeline-render.d.ts +80 -0
- package/dist/commands/timeline-render.d.ts.map +1 -0
- package/dist/commands/timeline-render.js +465 -0
- package/dist/commands/timeline-render.js.map +1 -0
- package/dist/commands/timeline-validation-output.d.ts +7 -0
- package/dist/commands/timeline-validation-output.d.ts.map +1 -0
- package/dist/commands/timeline-validation-output.js +9 -0
- package/dist/commands/timeline-validation-output.js.map +1 -0
- package/dist/commands/timeline-versions.d.ts +72 -0
- package/dist/commands/timeline-versions.d.ts.map +1 -0
- package/dist/commands/timeline-versions.js +108 -0
- package/dist/commands/timeline-versions.js.map +1 -0
- package/dist/commands/timeline.d.ts +22 -0
- package/dist/commands/timeline.d.ts.map +1 -0
- package/dist/commands/timeline.js +119 -0
- package/dist/commands/timeline.js.map +1 -0
- package/dist/commands/validate.d.ts +22 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +127 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/validation-output.d.ts +25 -0
- package/dist/commands/validation-output.d.ts.map +1 -0
- package/dist/commands/validation-output.js +29 -0
- package/dist/commands/validation-output.js.map +1 -0
- package/dist/commands/version-commands.d.ts +94 -0
- package/dist/commands/version-commands.d.ts.map +1 -0
- package/dist/commands/version-commands.js +227 -0
- package/dist/commands/version-commands.js.map +1 -0
- package/dist/commands/worker-models.d.ts +13 -0
- package/dist/commands/worker-models.d.ts.map +1 -0
- package/dist/commands/worker-models.js +207 -0
- package/dist/commands/worker-models.js.map +1 -0
- package/dist/commands/worker.d.ts +23 -0
- package/dist/commands/worker.d.ts.map +1 -0
- package/dist/commands/worker.js +374 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/debug/browser-runner.d.ts +21 -0
- package/dist/debug/browser-runner.d.ts.map +1 -0
- package/dist/debug/browser-runner.js +196 -0
- package/dist/debug/browser-runner.js.map +1 -0
- package/dist/debug/collector.d.ts +9 -0
- package/dist/debug/collector.d.ts.map +1 -0
- package/dist/debug/collector.js +9 -0
- package/dist/debug/collector.js.map +1 -0
- package/dist/debug/diff.d.ts +48 -0
- package/dist/debug/diff.d.ts.map +1 -0
- package/dist/debug/diff.js +68 -0
- package/dist/debug/diff.js.map +1 -0
- package/dist/debug/harness.d.ts +11 -0
- package/dist/debug/harness.d.ts.map +1 -0
- package/dist/debug/harness.js +103 -0
- package/dist/debug/harness.js.map +1 -0
- package/dist/debug/index.d.ts +17 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +16 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/debug/markdown.d.ts +3 -0
- package/dist/debug/markdown.d.ts.map +1 -0
- package/dist/debug/markdown.js +127 -0
- package/dist/debug/markdown.js.map +1 -0
- package/dist/debug/server-runner.d.ts +22 -0
- package/dist/debug/server-runner.d.ts.map +1 -0
- package/dist/debug/server-runner.js +164 -0
- package/dist/debug/server-runner.js.map +1 -0
- package/dist/debug/target.d.ts +34 -0
- package/dist/debug/target.d.ts.map +1 -0
- package/dist/debug/target.js +104 -0
- package/dist/debug/target.js.map +1 -0
- package/dist/debug/trace.d.ts +30 -0
- package/dist/debug/trace.d.ts.map +1 -0
- package/dist/debug/trace.js +87 -0
- package/dist/debug/trace.js.map +1 -0
- package/dist/debug/types.d.ts +82 -0
- package/dist/debug/types.d.ts.map +1 -0
- package/dist/debug/types.js +13 -0
- package/dist/debug/types.js.map +1 -0
- package/dist/debug/verdict.d.ts +3 -0
- package/dist/debug/verdict.d.ts.map +1 -0
- package/dist/debug/verdict.js +78 -0
- package/dist/debug/verdict.js.map +1 -0
- package/dist/debug/watch.d.ts +23 -0
- package/dist/debug/watch.d.ts.map +1 -0
- package/dist/debug/watch.js +68 -0
- package/dist/debug/watch.js.map +1 -0
- package/dist/diagnose.d.ts +139 -0
- package/dist/diagnose.d.ts.map +1 -0
- package/dist/diagnose.js +418 -0
- package/dist/diagnose.js.map +1 -0
- package/dist/evals/graph-runner.d.ts +8 -0
- package/dist/evals/graph-runner.d.ts.map +1 -0
- package/dist/evals/graph-runner.js +136 -0
- package/dist/evals/graph-runner.js.map +1 -0
- package/dist/harness/capability-coverage.d.ts +161 -0
- package/dist/harness/capability-coverage.d.ts.map +1 -0
- package/dist/harness/capability-coverage.js +266 -0
- package/dist/harness/capability-coverage.js.map +1 -0
- package/dist/harness/capability-table.d.ts +17 -0
- package/dist/harness/capability-table.d.ts.map +1 -0
- package/dist/harness/capability-table.js +3576 -0
- package/dist/harness/capability-table.js.map +1 -0
- package/dist/harness/changed-files.d.ts +18 -0
- package/dist/harness/changed-files.d.ts.map +1 -0
- package/dist/harness/changed-files.js +76 -0
- package/dist/harness/changed-files.js.map +1 -0
- package/dist/harness/declared-capabilities.d.ts +12 -0
- package/dist/harness/declared-capabilities.d.ts.map +1 -0
- package/dist/harness/declared-capabilities.js +21 -0
- package/dist/harness/declared-capabilities.js.map +1 -0
- package/dist/harness/registry.d.ts +162 -0
- package/dist/harness/registry.d.ts.map +1 -0
- package/dist/harness/registry.js +1738 -0
- package/dist/harness/registry.js.map +1 -0
- package/dist/index.js +121 -130
- package/dist/index.js.map +1 -1
- package/dist/interaction-script.d.ts +17 -0
- package/dist/interaction-script.d.ts.map +1 -0
- package/dist/interaction-script.js +47 -0
- package/dist/interaction-script.js.map +1 -0
- package/dist/js-script-debug/harness.d.ts +114 -0
- package/dist/js-script-debug/harness.d.ts.map +1 -0
- package/dist/js-script-debug/harness.js +252 -0
- package/dist/js-script-debug/harness.js.map +1 -0
- package/dist/js-script-debug/index.d.ts +9 -0
- package/dist/js-script-debug/index.d.ts.map +1 -0
- package/dist/js-script-debug/index.js +9 -0
- package/dist/js-script-debug/index.js.map +1 -0
- package/dist/js-script-debug/interactions.d.ts +19 -0
- package/dist/js-script-debug/interactions.d.ts.map +1 -0
- package/dist/js-script-debug/interactions.js +17 -0
- package/dist/js-script-debug/interactions.js.map +1 -0
- package/dist/js-script-debug/target.d.ts +20 -0
- package/dist/js-script-debug/target.d.ts.map +1 -0
- package/dist/js-script-debug/target.js +78 -0
- package/dist/js-script-debug/target.js.map +1 -0
- package/dist/local-model-interfaces.d.ts +20 -0
- package/dist/local-model-interfaces.d.ts.map +1 -0
- package/dist/local-model-interfaces.js +64 -0
- package/dist/local-model-interfaces.js.map +1 -0
- package/dist/local-secrets.d.ts +3 -0
- package/dist/local-secrets.d.ts.map +1 -0
- package/dist/local-secrets.js +16 -0
- package/dist/local-secrets.js.map +1 -0
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +7 -2
- package/dist/markdown.js.map +1 -1
- package/dist/node/run-node.d.ts +28 -0
- package/dist/node/run-node.d.ts.map +1 -0
- package/dist/node/run-node.js +76 -0
- package/dist/node/run-node.js.map +1 -0
- package/dist/node-registry.d.ts +13 -0
- package/dist/node-registry.d.ts.map +1 -0
- package/dist/node-registry.js +36 -0
- package/dist/node-registry.js.map +1 -0
- package/dist/nodetool.js +845 -309
- package/dist/nodetool.js.map +1 -1
- package/dist/numeric-options.d.ts +22 -0
- package/dist/numeric-options.d.ts.map +1 -0
- package/dist/numeric-options.js +45 -0
- package/dist/numeric-options.js.map +1 -0
- package/dist/permission-gate.d.ts +55 -0
- package/dist/permission-gate.d.ts.map +1 -0
- package/dist/permission-gate.js +118 -0
- package/dist/permission-gate.js.map +1 -0
- package/dist/predicates.d.ts +6 -0
- package/dist/predicates.d.ts.map +1 -0
- package/dist/predicates.js +6 -0
- package/dist/predicates.js.map +1 -0
- package/dist/providers.d.ts +73 -10
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +329 -97
- package/dist/providers.js.map +1 -1
- package/dist/readline-input.d.ts +13 -19
- package/dist/readline-input.d.ts.map +1 -1
- package/dist/readline-input.js +201 -190
- package/dist/readline-input.js.map +1 -1
- package/dist/run-budget.d.ts +40 -0
- package/dist/run-budget.d.ts.map +1 -0
- package/dist/run-budget.js +119 -0
- package/dist/run-budget.js.map +1 -0
- package/dist/run-dsl-supervised.d.ts +11 -0
- package/dist/run-dsl-supervised.d.ts.map +1 -0
- package/dist/run-dsl-supervised.js +82 -0
- package/dist/run-dsl-supervised.js.map +1 -0
- package/dist/run-dsl.d.ts +23 -0
- package/dist/run-dsl.d.ts.map +1 -1
- package/dist/run-dsl.js +40 -9
- package/dist/run-dsl.js.map +1 -1
- package/dist/run-json.d.ts +24 -0
- package/dist/run-json.d.ts.map +1 -0
- package/dist/run-json.js +132 -0
- package/dist/run-json.js.map +1 -0
- package/dist/sandbox-catalog.d.ts +12 -0
- package/dist/sandbox-catalog.d.ts.map +1 -0
- package/dist/sandbox-catalog.js +27 -0
- package/dist/sandbox-catalog.js.map +1 -0
- package/dist/settings.d.ts +11 -10
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +71 -13
- package/dist/settings.js.map +1 -1
- package/dist/sketch-debug/harness.d.ts +87 -0
- package/dist/sketch-debug/harness.d.ts.map +1 -0
- package/dist/sketch-debug/harness.js +178 -0
- package/dist/sketch-debug/harness.js.map +1 -0
- package/dist/sketch-debug/index.d.ts +9 -0
- package/dist/sketch-debug/index.d.ts.map +1 -0
- package/dist/sketch-debug/index.js +9 -0
- package/dist/sketch-debug/index.js.map +1 -0
- package/dist/sketch-debug/interactions.d.ts +19 -0
- package/dist/sketch-debug/interactions.d.ts.map +1 -0
- package/dist/sketch-debug/interactions.js +17 -0
- package/dist/sketch-debug/interactions.js.map +1 -0
- package/dist/sketch-debug/target.d.ts +48 -0
- package/dist/sketch-debug/target.d.ts.map +1 -0
- package/dist/sketch-debug/target.js +138 -0
- package/dist/sketch-debug/target.js.map +1 -0
- package/dist/stdin.d.ts +18 -19
- package/dist/stdin.d.ts.map +1 -1
- package/dist/stdin.js +159 -157
- package/dist/stdin.js.map +1 -1
- package/dist/supervisor.d.ts +97 -0
- package/dist/supervisor.d.ts.map +1 -0
- package/dist/supervisor.js +194 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/terminal-clipboard.d.ts +3 -0
- package/dist/terminal-clipboard.d.ts.map +1 -0
- package/dist/terminal-clipboard.js +24 -0
- package/dist/terminal-clipboard.js.map +1 -0
- package/dist/terminal-mouse.d.ts +24 -0
- package/dist/terminal-mouse.d.ts.map +1 -0
- package/dist/terminal-mouse.js +84 -0
- package/dist/terminal-mouse.js.map +1 -0
- package/dist/terminal-screen.d.ts +41 -0
- package/dist/terminal-screen.d.ts.map +1 -0
- package/dist/terminal-screen.js +228 -0
- package/dist/terminal-screen.js.map +1 -0
- package/dist/timeline-debug/harness.d.ts +79 -0
- package/dist/timeline-debug/harness.d.ts.map +1 -0
- package/dist/timeline-debug/harness.js +155 -0
- package/dist/timeline-debug/harness.js.map +1 -0
- package/dist/timeline-debug/index.d.ts +9 -0
- package/dist/timeline-debug/index.d.ts.map +1 -0
- package/dist/timeline-debug/index.js +9 -0
- package/dist/timeline-debug/index.js.map +1 -0
- package/dist/timeline-debug/interactions.d.ts +19 -0
- package/dist/timeline-debug/interactions.d.ts.map +1 -0
- package/dist/timeline-debug/interactions.js +17 -0
- package/dist/timeline-debug/interactions.js.map +1 -0
- package/dist/timeline-debug/target.d.ts +34 -0
- package/dist/timeline-debug/target.d.ts.map +1 -0
- package/dist/timeline-debug/target.js +132 -0
- package/dist/timeline-debug/target.js.map +1 -0
- package/dist/tool-format.d.ts +54 -0
- package/dist/tool-format.d.ts.map +1 -0
- package/dist/tool-format.js +360 -0
- package/dist/tool-format.js.map +1 -0
- package/dist/useExecutionState.d.ts.map +1 -1
- package/dist/useExecutionState.js +8 -4
- package/dist/useExecutionState.js.map +1 -1
- package/dist/validate/index.d.ts +28 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +51 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/websocket-client.d.ts +78 -15
- package/dist/websocket-client.d.ts.map +1 -1
- package/dist/websocket-client.js +497 -171
- package/dist/websocket-client.js.map +1 -1
- package/package.json +62 -31
package/dist/commands/agent.js
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `nodetool agent` —
|
|
2
|
+
* `nodetool agent` — run one CodeAct turn over the default toolbelt, with full
|
|
3
|
+
* trace output.
|
|
4
|
+
*
|
|
5
|
+
* The loop is the chat's loop: the belt is assembled by `buildCliAgentBelt`
|
|
6
|
+
* and the turn by `createCliCodeActTurn`, both shared with `--stdin` chat, so
|
|
7
|
+
* the provider is offered `execute_code` and the toolbelt lives in the sandbox.
|
|
8
|
+
* `create_plan` and `execute_plan` are on the belt, so an objective that wants
|
|
9
|
+
* a plan gets one and the `planning_update` / `task_update` events stream.
|
|
3
10
|
*
|
|
4
11
|
* Subcommands:
|
|
5
|
-
* nodetool agent run
|
|
6
|
-
* nodetool agent
|
|
7
|
-
* nodetool agent list <dir> # list YAML configs in a directory
|
|
12
|
+
* nodetool agent run --objective "..." # objective may also come from stdin
|
|
13
|
+
* nodetool agent diagnose <job_id> # aggregate a failed run into a report
|
|
8
14
|
*/
|
|
9
15
|
import * as fs from "node:fs";
|
|
10
16
|
import * as fsp from "node:fs/promises";
|
|
11
17
|
import * as path from "node:path";
|
|
12
|
-
import * as yaml from "js-yaml";
|
|
13
18
|
import chalk from "chalk";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
19
|
+
import { RUN_BUDGET_CONTEXT_KEY } from "@nodetool-ai/runtime";
|
|
20
|
+
import { PERMISSION_GATE_CONTEXT_KEY } from "@nodetool-ai/agents";
|
|
21
|
+
import { processChat } from "@nodetool-ai/chat";
|
|
22
|
+
import { initDb } from "@nodetool-ai/models";
|
|
17
23
|
import { getDefaultDbPath, configureLogging } from "@nodetool-ai/config";
|
|
18
24
|
import { createProvider, buildConfiguredProviders } from "../providers.js";
|
|
25
|
+
import { buildFullRegistry } from "../node-registry.js";
|
|
26
|
+
import { buildCliToolbelt } from "../agent-toolbelt.js";
|
|
27
|
+
import { applySystemPrompt, buildCliAgentBelt, createCliCodeActTurn } from "../chat-codeact.js";
|
|
28
|
+
import { createChatContext } from "../chat-context.js";
|
|
29
|
+
import { budgetStopReason, budgetSummaryLine, createCliRunBudget } from "../run-budget.js";
|
|
30
|
+
import { createCliPermissionGate, parsePermissionMode, PERMISSION_MODE_NAMES } from "../permission-gate.js";
|
|
31
|
+
import { diagnoseRun, renderDiagnosis } from "../diagnose.js";
|
|
32
|
+
import { isRecord, isString } from "../predicates.js";
|
|
19
33
|
const PROVIDER_ALIASES = {
|
|
20
34
|
google: "gemini",
|
|
21
35
|
googleai: "gemini",
|
|
@@ -31,94 +45,6 @@ function expandTilde(p) {
|
|
|
31
45
|
}
|
|
32
46
|
return p;
|
|
33
47
|
}
|
|
34
|
-
/**
|
|
35
|
-
* FindModelTool that injects YAML-declared preferences as defaults when the
|
|
36
|
-
* LLM omits explicit hints.
|
|
37
|
-
*/
|
|
38
|
-
class PreferringFindModelTool extends FindModelTool {
|
|
39
|
-
prefs;
|
|
40
|
-
constructor(providers, prefs) {
|
|
41
|
-
super(providers);
|
|
42
|
-
this.prefs = prefs;
|
|
43
|
-
}
|
|
44
|
-
async process(context, params) {
|
|
45
|
-
const merged = { ...params };
|
|
46
|
-
const capability = typeof params["capability"] === "string"
|
|
47
|
-
? params["capability"]
|
|
48
|
-
: undefined;
|
|
49
|
-
if (typeof merged["provider_hint"] !== "string" &&
|
|
50
|
-
this.prefs.preferredProviders &&
|
|
51
|
-
this.prefs.preferredProviders.length > 0) {
|
|
52
|
-
merged["provider_hint"] = this.prefs.preferredProviders[0];
|
|
53
|
-
}
|
|
54
|
-
if (capability && !merged["model_hint"]) {
|
|
55
|
-
const pref = this.prefs.preferredModels?.[capability];
|
|
56
|
-
if (pref && pref.length > 0) {
|
|
57
|
-
merged["model_hint"] = pref;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return super.process(context, merged);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function buildToolMap(providers, prefs = {}) {
|
|
64
|
-
const m = {
|
|
65
|
-
find_model: new PreferringFindModelTool(providers ?? {}, prefs),
|
|
66
|
-
generate_image: new GenerateImageTool(),
|
|
67
|
-
edit_image: new EditImageTool(),
|
|
68
|
-
generate_video: new GenerateVideoTool(),
|
|
69
|
-
animate_image: new AnimateImageTool(),
|
|
70
|
-
generate_speech: new GenerateSpeechTool(),
|
|
71
|
-
transcribe_audio: new TranscribeAudioTool(),
|
|
72
|
-
embed_text: new EmbedTextTool(),
|
|
73
|
-
read_file: new ReadFileTool(),
|
|
74
|
-
write_file: new WriteFileTool(),
|
|
75
|
-
edit_file: new EditFileTool(),
|
|
76
|
-
list_directory: new ListDirectoryTool(),
|
|
77
|
-
glob: new GlobTool(),
|
|
78
|
-
grep: new GrepTool(),
|
|
79
|
-
download_file: new DownloadFileTool(),
|
|
80
|
-
http_request: new HttpRequestTool(),
|
|
81
|
-
google_search: new GoogleSearchTool(),
|
|
82
|
-
google_news: new GoogleNewsTool(),
|
|
83
|
-
google_images: new GoogleImagesTool(),
|
|
84
|
-
browser: new BrowserTool(),
|
|
85
|
-
screenshot: new ScreenshotTool(),
|
|
86
|
-
run_code: new RunCodeTool(),
|
|
87
|
-
calculator: new CalculatorTool(),
|
|
88
|
-
statistics: new StatisticsTool(),
|
|
89
|
-
geometry: new GeometryTool(),
|
|
90
|
-
conversion: new ConversionTool(),
|
|
91
|
-
extract_pdf_text: new ExtractPDFTextTool(),
|
|
92
|
-
convert_pdf_to_markdown: new ConvertPDFToMarkdownTool(),
|
|
93
|
-
convert_document: new ConvertDocumentTool(),
|
|
94
|
-
openai_web_search: new OpenAIWebSearchTool(),
|
|
95
|
-
openai_image_generation: new OpenAIImageGenerationTool(),
|
|
96
|
-
openai_text_to_speech: new OpenAITextToSpeechTool(),
|
|
97
|
-
dataseo_search: new DataForSEOSearchTool(),
|
|
98
|
-
dataseo_news: new DataForSEONewsTool(),
|
|
99
|
-
search_email: new SearchEmailTool(),
|
|
100
|
-
archive_email: new ArchiveEmailTool()
|
|
101
|
-
};
|
|
102
|
-
for (const tool of getAllMcpTools({ providers })) {
|
|
103
|
-
m[tool.name] = tool;
|
|
104
|
-
}
|
|
105
|
-
return m;
|
|
106
|
-
}
|
|
107
|
-
function resolveTools(names, providers, prefs = {}) {
|
|
108
|
-
if (!names || names.length === 0)
|
|
109
|
-
return { tools: [], unknown: [] };
|
|
110
|
-
const map = buildToolMap(providers, prefs);
|
|
111
|
-
const tools = [];
|
|
112
|
-
const unknown = [];
|
|
113
|
-
for (const name of names) {
|
|
114
|
-
const tool = map[name];
|
|
115
|
-
if (tool)
|
|
116
|
-
tools.push(tool);
|
|
117
|
-
else
|
|
118
|
-
unknown.push(name);
|
|
119
|
-
}
|
|
120
|
-
return { tools, unknown };
|
|
121
|
-
}
|
|
122
48
|
function shorten(s, n = 200) {
|
|
123
49
|
const oneLine = s.replace(/\s+/g, " ").trim();
|
|
124
50
|
return oneLine.length > n ? oneLine.slice(0, n) + "…" : oneLine;
|
|
@@ -156,8 +82,10 @@ function traceEvent(msg, opts) {
|
|
|
156
82
|
break;
|
|
157
83
|
}
|
|
158
84
|
case "step_result": {
|
|
159
|
-
const tag = msg.is_task_result
|
|
160
|
-
|
|
85
|
+
const tag = msg.is_task_result
|
|
86
|
+
? chalk.green("result★")
|
|
87
|
+
: chalk.green("step✓ ");
|
|
88
|
+
const preview = isString(msg.result)
|
|
161
89
|
? shorten(msg.result, 200)
|
|
162
90
|
: shorten(JSON.stringify(msg.result ?? null), 200);
|
|
163
91
|
process.stderr.write(`${t} ${tag} ${preview}\n`);
|
|
@@ -166,7 +94,7 @@ function traceEvent(msg, opts) {
|
|
|
166
94
|
break;
|
|
167
95
|
}
|
|
168
96
|
case "chunk":
|
|
169
|
-
if (opts.verbose && msg.content) {
|
|
97
|
+
if (opts.verbose && isString(msg.content)) {
|
|
170
98
|
process.stderr.write(`${t} ${chalk.gray("chunk")} ${shorten(msg.content, 80)}\n`);
|
|
171
99
|
}
|
|
172
100
|
break;
|
|
@@ -180,16 +108,8 @@ function traceEvent(msg, opts) {
|
|
|
180
108
|
}
|
|
181
109
|
}
|
|
182
110
|
// ---------------------------------------------------------------------------
|
|
183
|
-
//
|
|
111
|
+
// run subcommand
|
|
184
112
|
// ---------------------------------------------------------------------------
|
|
185
|
-
async function loadAgentYaml(file) {
|
|
186
|
-
const raw = await fsp.readFile(file, "utf-8");
|
|
187
|
-
const parsed = yaml.load(raw);
|
|
188
|
-
if (!parsed || typeof parsed !== "object") {
|
|
189
|
-
throw new Error(`YAML did not parse to an object: ${file}`);
|
|
190
|
-
}
|
|
191
|
-
return parsed;
|
|
192
|
-
}
|
|
193
113
|
async function readObjectiveFromStdin() {
|
|
194
114
|
if (process.stdin.isTTY)
|
|
195
115
|
return null;
|
|
@@ -200,7 +120,20 @@ async function readObjectiveFromStdin() {
|
|
|
200
120
|
const text = Buffer.concat(chunks).toString("utf-8").trim();
|
|
201
121
|
return text || null;
|
|
202
122
|
}
|
|
203
|
-
|
|
123
|
+
/** The text the run answers with: the last assistant message that carries any. */
|
|
124
|
+
function finalAssistantText(messages) {
|
|
125
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
126
|
+
const message = messages[i];
|
|
127
|
+
if (message.role !== "assistant")
|
|
128
|
+
continue;
|
|
129
|
+
if (isString(message.content) && message.content.trim()) {
|
|
130
|
+
return message.content;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
/** Exit code for the process: 0 when the turn finished without an error. */
|
|
136
|
+
export async function runAgentCommand(opts) {
|
|
204
137
|
// Quiet the runtime's INFO logger so it doesn't interleave the trace.
|
|
205
138
|
// Users who want raw logs can set NODETOOL_LOG_LEVEL=info before running.
|
|
206
139
|
if (!process.env["NODETOOL_LOG_LEVEL"]) {
|
|
@@ -214,253 +147,338 @@ async function runAgentCommand(file, opts) {
|
|
|
214
147
|
catch {
|
|
215
148
|
/* fallback to env vars */
|
|
216
149
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const providerId = opts.provider ?? normalizeProvider(cfg.model?.provider ?? "");
|
|
220
|
-
if (!providerId) {
|
|
221
|
-
throw new Error("No provider specified. Set `model.provider` in YAML or use --provider.");
|
|
150
|
+
if (!opts.provider) {
|
|
151
|
+
throw new Error("No provider specified. Use --provider <id>.");
|
|
222
152
|
}
|
|
223
|
-
const
|
|
153
|
+
const providerId = normalizeProvider(opts.provider);
|
|
154
|
+
const modelId = opts.model;
|
|
224
155
|
if (!modelId) {
|
|
225
|
-
throw new Error("No model specified.
|
|
156
|
+
throw new Error("No model specified. Use --model <id>.");
|
|
226
157
|
}
|
|
227
|
-
|
|
228
|
-
const stdinObjective = await readObjectiveFromStdin();
|
|
229
|
-
const objective = opts.objective ?? stdinObjective ?? cfg.objective;
|
|
158
|
+
const objective = opts.objective ?? (await readObjectiveFromStdin());
|
|
230
159
|
if (!objective) {
|
|
231
|
-
throw new Error(
|
|
160
|
+
throw new Error('No objective provided. Use --objective "..." or pipe it via stdin.');
|
|
232
161
|
}
|
|
233
162
|
// Configured providers (for find_model + media tool dispatch)
|
|
234
163
|
const configuredProviders = await buildConfiguredProviders();
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
prefs.preferredProviders = cfg.preferred_providers.filter((x) => typeof x === "string");
|
|
239
|
-
}
|
|
240
|
-
if (cfg.preferred_models && typeof cfg.preferred_models === "object") {
|
|
241
|
-
prefs.preferredModels = {};
|
|
242
|
-
for (const [cap, val] of Object.entries(cfg.preferred_models)) {
|
|
243
|
-
const list = typeof val === "string" ? [val] : Array.isArray(val) ? val : [];
|
|
244
|
-
const cleaned = list.filter((x) => typeof x === "string");
|
|
245
|
-
if (cleaned.length > 0)
|
|
246
|
-
prefs.preferredModels[cap] = cleaned;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
// Tools
|
|
250
|
-
const { tools, unknown } = resolveTools(cfg.tools, configuredProviders, prefs);
|
|
251
|
-
if (unknown.length > 0) {
|
|
252
|
-
process.stderr.write(chalk.yellow(`warn: ignoring unknown tools: ${unknown.join(", ")}\n`));
|
|
253
|
-
}
|
|
254
|
-
// Workspace
|
|
255
|
-
const workspaceDir = expandTilde(opts.workspace ?? cfg.workspace?.path ?? process.cwd());
|
|
256
|
-
if (cfg.workspace?.auto_create !== false) {
|
|
257
|
-
try {
|
|
258
|
-
fs.mkdirSync(workspaceDir, { recursive: true });
|
|
259
|
-
}
|
|
260
|
-
catch {
|
|
261
|
-
/* ignore */
|
|
262
|
-
}
|
|
164
|
+
const workspaceDir = expandTilde(opts.workspace ?? process.cwd());
|
|
165
|
+
try {
|
|
166
|
+
fs.mkdirSync(workspaceDir, { recursive: true });
|
|
263
167
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
if (!["loop", "plan", "multi-agent"].includes(modeArg)) {
|
|
267
|
-
throw new Error(`Invalid mode: ${modeArg}. Use loop|plan|multi-agent.`);
|
|
168
|
+
catch {
|
|
169
|
+
/* ignore — an existing dir is the common case */
|
|
268
170
|
}
|
|
269
171
|
const provider = await createProvider(providerId);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
const planningModel = cfg.planning_agent?.enabled === false ? modelId : cfg.planning_agent?.model?.id ?? modelId;
|
|
277
|
-
// Build the effective system prompt: user prompt + a preferences block so
|
|
278
|
-
// the LLM also "knows" which providers/models to favor (in addition to the
|
|
279
|
-
// hint injection inside FindModelTool).
|
|
280
|
-
const prefLines = [];
|
|
281
|
-
if (prefs.preferredProviders && prefs.preferredProviders.length > 0) {
|
|
282
|
-
prefLines.push(`Preferred providers (in order): ${prefs.preferredProviders.join(", ")}.`);
|
|
172
|
+
const context = await createChatContext({ workspaceDir });
|
|
173
|
+
// Hand the context the instances already configured above, so a tool that
|
|
174
|
+
// dispatches by provider id gets this run's provider rather than resolving a
|
|
175
|
+
// second one of its own.
|
|
176
|
+
for (const [id, configured] of Object.entries(configuredProviders)) {
|
|
177
|
+
context.registerProvider(id, configured);
|
|
283
178
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
179
|
+
const traceOpts = {
|
|
180
|
+
json: !!opts.json,
|
|
181
|
+
verbose: !!opts.verbose
|
|
182
|
+
};
|
|
183
|
+
const emit = (message) => {
|
|
184
|
+
traceEvent(message, traceOpts);
|
|
185
|
+
};
|
|
186
|
+
// The run's gate, built once. `readObjectiveFromStdin` already returned null
|
|
187
|
+
// on a TTY, so the same test says whether anyone is there to answer a
|
|
188
|
+
// prompt: an objective that arrived down a pipe leaves nobody at the
|
|
189
|
+
// keyboard, and the run gates headless with the notice below.
|
|
190
|
+
const gate = createCliPermissionGate({
|
|
191
|
+
hostName: "nodetool agent run",
|
|
192
|
+
mode: parsePermissionMode(opts.permissionMode),
|
|
193
|
+
interactive: process.stdin.isTTY === true,
|
|
194
|
+
// In `--json` the notice and any prompt ride the event stream, so it stays
|
|
195
|
+
// one JSON object per line.
|
|
196
|
+
write: (text) => {
|
|
197
|
+
if (opts.json) {
|
|
198
|
+
emit({
|
|
199
|
+
type: "log_update",
|
|
200
|
+
node_id: "agent",
|
|
201
|
+
node_name: "permissions",
|
|
202
|
+
content: text,
|
|
203
|
+
severity: "info"
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
process.stderr.write(chalk.gray(`${text}\n`));
|
|
208
|
+
}
|
|
287
209
|
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
210
|
+
});
|
|
211
|
+
// Loops this command never constructs — an `AgentNode` reached through
|
|
212
|
+
// `run_node`, a JS script — read the gate off the context rather than
|
|
213
|
+
// building an ungated run of their own (`gateFromContext`, invariant I-1).
|
|
214
|
+
context.set(PERMISSION_GATE_CONTEXT_KEY, gate);
|
|
215
|
+
// The bounds this run shares downward, created once (invariant I-2). The
|
|
216
|
+
// same channel the gate takes: a loop this command never constructs reads
|
|
217
|
+
// the budget off the context instead of opening an allowance of its own.
|
|
218
|
+
const budget = await createCliRunBudget({
|
|
219
|
+
...(opts.costCap !== undefined && { costCap: opts.costCap }),
|
|
220
|
+
...(opts.timeout !== undefined && { timeout: opts.timeout })
|
|
221
|
+
});
|
|
222
|
+
context.set(RUN_BUDGET_CONTEXT_KEY, budget);
|
|
223
|
+
// One belt, every run. A narrowing flag made each invocation its own
|
|
224
|
+
// configuration — the thing YAML configs were removed for — and an agent
|
|
225
|
+
// run that behaves differently from the last one is not reproducible.
|
|
226
|
+
const belt = buildCliAgentBelt({
|
|
227
|
+
baseTools: buildCliToolbelt(configuredProviders, buildFullRegistry()),
|
|
295
228
|
provider,
|
|
296
229
|
model: modelId,
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
planningModel
|
|
230
|
+
forwardMessage: emit,
|
|
231
|
+
gate,
|
|
232
|
+
// An objective is a job, not a conversation: the two plan capabilities are
|
|
233
|
+
// on the belt so the model can decompose one and run the DAG itself.
|
|
234
|
+
planning: true,
|
|
235
|
+
budget
|
|
304
236
|
});
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
secretResolver: getSecret
|
|
310
|
-
});
|
|
311
|
-
for (const [id, p] of Object.entries(configuredProviders)) {
|
|
312
|
-
ctx.registerProvider(id, p);
|
|
237
|
+
if (!opts.json) {
|
|
238
|
+
process.stderr.write(chalk.bold(`\n▸ agent\n`) +
|
|
239
|
+
chalk.gray(` provider=${providerId} model=${modelId} tools=${belt.length}\n`) +
|
|
240
|
+
chalk.gray(` objective: ${shorten(objective, 200)}\n\n`));
|
|
313
241
|
}
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
242
|
+
const turn = createCliCodeActTurn({
|
|
243
|
+
tools: belt,
|
|
244
|
+
context,
|
|
245
|
+
// Calls the sandbox makes have no provider tool-call id of their own.
|
|
246
|
+
onToolCall: ({ name, args }) => {
|
|
247
|
+
emit({ type: "tool_call_update", name, args });
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
const messages = [];
|
|
251
|
+
applySystemPrompt(messages, turn.systemPrompt);
|
|
319
252
|
let errored = false;
|
|
320
253
|
try {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
254
|
+
await processChat({
|
|
255
|
+
userInput: objective,
|
|
256
|
+
messages,
|
|
257
|
+
model: modelId,
|
|
258
|
+
provider,
|
|
259
|
+
context,
|
|
260
|
+
tools: turn.tools,
|
|
261
|
+
turnBudget: budget,
|
|
262
|
+
maxIterations: opts.maxIterations === undefined ? undefined : Number(opts.maxIterations),
|
|
263
|
+
callbacks: {
|
|
264
|
+
onChunk: (content) => {
|
|
265
|
+
emit({ type: "chunk", content, done: false });
|
|
266
|
+
},
|
|
267
|
+
onToolCall: (call) => {
|
|
268
|
+
emit({
|
|
269
|
+
type: "tool_call_update",
|
|
270
|
+
name: call.name,
|
|
271
|
+
args: call.args,
|
|
272
|
+
tool_call_id: call.id
|
|
273
|
+
});
|
|
274
|
+
},
|
|
275
|
+
onToolResult: (call, result) => {
|
|
276
|
+
emit({
|
|
277
|
+
type: "tool_result_update",
|
|
278
|
+
node_id: "agent",
|
|
279
|
+
name: call.name,
|
|
280
|
+
tool_call_id: call.id,
|
|
281
|
+
result: isRecord(result) ? result : { value: result }
|
|
282
|
+
});
|
|
330
283
|
}
|
|
331
284
|
}
|
|
332
|
-
|
|
333
|
-
errored = true;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
285
|
+
});
|
|
336
286
|
}
|
|
337
287
|
catch (e) {
|
|
338
288
|
errored = true;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
if (r != null) {
|
|
344
|
-
finalText = typeof r === "string" ? r : JSON.stringify(r, null, 2);
|
|
289
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
290
|
+
emit({ type: "error", message });
|
|
291
|
+
if (!opts.json) {
|
|
292
|
+
process.stderr.write(chalk.red(`\nagent failed: ${message}\n`));
|
|
345
293
|
}
|
|
346
294
|
}
|
|
295
|
+
const finalText = finalAssistantText(messages);
|
|
347
296
|
if (!opts.json)
|
|
348
297
|
process.stderr.write(chalk.bold("\n— result —\n"));
|
|
349
298
|
if (finalText)
|
|
350
299
|
process.stdout.write(finalText + "\n");
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
300
|
+
// What the whole run — this loop plus every sub-agent and node it started —
|
|
301
|
+
// committed against the shared cap.
|
|
302
|
+
const summary = budgetSummaryLine(budget);
|
|
303
|
+
if (opts.json) {
|
|
304
|
+
emit({
|
|
305
|
+
type: "log_update",
|
|
306
|
+
node_id: "agent",
|
|
307
|
+
node_name: "budget",
|
|
308
|
+
content: summary,
|
|
309
|
+
severity: "info"
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
process.stderr.write(chalk.gray(`\n${summary}\n`));
|
|
314
|
+
}
|
|
315
|
+
// A ceiling ended the run, not the model finishing its answer. Said nowhere,
|
|
316
|
+
// the two are indistinguishable from an empty transcript (invariant I-3), so
|
|
317
|
+
// the reason is reported before anything else about how the run ended.
|
|
318
|
+
const stopReason = budgetStopReason(budget);
|
|
319
|
+
if (!errored && stopReason) {
|
|
320
|
+
emit({ type: "error", message: stopReason });
|
|
321
|
+
if (!opts.json) {
|
|
322
|
+
process.stderr.write(chalk.red(`\nagent stopped: ${stopReason}\n`));
|
|
323
|
+
}
|
|
324
|
+
return 1;
|
|
325
|
+
}
|
|
326
|
+
// A run that ended on a tool call or a contentless assistant turn produced
|
|
327
|
+
// no answer. Writing nothing and exiting 0 is indistinguishable from an
|
|
328
|
+
// empty-but-successful result, so it fails instead (invariant I-3).
|
|
329
|
+
if (!errored && !finalText) {
|
|
330
|
+
const message = "agent produced no answer: the turn ended without a final assistant message";
|
|
331
|
+
emit({ type: "error", message });
|
|
332
|
+
if (!opts.json) {
|
|
333
|
+
process.stderr.write(chalk.red(`\nagent failed: ${message}\n`));
|
|
334
|
+
}
|
|
335
|
+
return 1;
|
|
363
336
|
}
|
|
364
|
-
|
|
365
|
-
|
|
337
|
+
return errored ? 1 : 0;
|
|
338
|
+
}
|
|
339
|
+
/** Parse a JSONL file into one parsed object per non-blank line. */
|
|
340
|
+
async function readJsonl(file) {
|
|
341
|
+
const text = await fsp.readFile(file, "utf-8");
|
|
342
|
+
const out = [];
|
|
343
|
+
for (const line of text.split("\n")) {
|
|
344
|
+
const trimmed = line.trim();
|
|
345
|
+
if (!trimmed)
|
|
346
|
+
continue;
|
|
347
|
+
try {
|
|
348
|
+
// SAFETY: each caller names the record shape its own bundle file was
|
|
349
|
+
// written with — this reader only splits lines and parses JSON.
|
|
350
|
+
out.push(JSON.parse(trimmed));
|
|
351
|
+
}
|
|
352
|
+
catch {
|
|
353
|
+
// Skip partial/corrupt lines (e.g. a crash mid-write).
|
|
354
|
+
}
|
|
366
355
|
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
const provider = cfg.model?.provider;
|
|
373
|
-
if (!provider)
|
|
374
|
-
issues.push("missing model.provider");
|
|
375
|
-
else
|
|
376
|
-
okLines.push(`provider: ${provider} → ${normalizeProvider(provider)}`);
|
|
377
|
-
if (!cfg.model?.id)
|
|
378
|
-
issues.push("missing model.id");
|
|
379
|
-
else
|
|
380
|
-
okLines.push(`model: ${cfg.model.id}`);
|
|
381
|
-
okLines.push(`mode: ${cfg.mode ?? "plan (default)"}`);
|
|
382
|
-
okLines.push(`system_prompt: ${cfg.system_prompt ? `${cfg.system_prompt.length} chars` : "(none)"}`);
|
|
383
|
-
const { tools, unknown } = resolveTools(cfg.tools);
|
|
384
|
-
okLines.push(`tools resolved: ${tools.map((t) => t.name).join(", ") || "(none)"}`);
|
|
385
|
-
if (unknown.length > 0)
|
|
386
|
-
issues.push(`unknown tools: ${unknown.join(", ")}`);
|
|
387
|
-
// Check provider can be instantiated
|
|
388
|
-
if (provider) {
|
|
356
|
+
return out;
|
|
357
|
+
}
|
|
358
|
+
/** First existing path among the candidates, or null. */
|
|
359
|
+
function firstExisting(candidates) {
|
|
360
|
+
for (const p of candidates) {
|
|
389
361
|
try {
|
|
390
|
-
|
|
391
|
-
|
|
362
|
+
if (fs.statSync(p).isFile())
|
|
363
|
+
return p;
|
|
392
364
|
}
|
|
393
|
-
catch
|
|
394
|
-
|
|
365
|
+
catch {
|
|
366
|
+
// Not a readable file — try the next candidate.
|
|
395
367
|
}
|
|
396
368
|
}
|
|
397
|
-
|
|
398
|
-
for (const line of okLines)
|
|
399
|
-
process.stdout.write(` ${chalk.green("✓")} ${line}\n`);
|
|
400
|
-
for (const issue of issues)
|
|
401
|
-
process.stdout.write(` ${chalk.red("✗")} ${issue}\n`);
|
|
402
|
-
process.stdout.write("\n");
|
|
403
|
-
process.exit(issues.length > 0 ? 1 : 0);
|
|
369
|
+
return null;
|
|
404
370
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
371
|
+
/**
|
|
372
|
+
* Locate a debug bundle directory for a job id. The `debug` command writes
|
|
373
|
+
* bundles to `nodetool-debug/<id>-<timestamp>/`; we pick the most recent dir
|
|
374
|
+
* whose name starts with the id, relative to cwd.
|
|
375
|
+
*/
|
|
376
|
+
function findDebugBundle(jobId) {
|
|
377
|
+
const root = path.join(process.cwd(), "nodetool-debug");
|
|
410
378
|
let entries;
|
|
411
379
|
try {
|
|
412
|
-
entries =
|
|
380
|
+
entries = fs.readdirSync(root, { withFileTypes: true });
|
|
413
381
|
}
|
|
414
|
-
catch
|
|
415
|
-
|
|
416
|
-
process.exit(1);
|
|
382
|
+
catch {
|
|
383
|
+
return null;
|
|
417
384
|
}
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
385
|
+
const matches = entries
|
|
386
|
+
.filter((e) => e.isDirectory() && e.name.startsWith(`${jobId}-`))
|
|
387
|
+
.map((e) => path.join(root, e.name))
|
|
388
|
+
.sort();
|
|
389
|
+
return matches.length > 0 ? matches[matches.length - 1] : null;
|
|
390
|
+
}
|
|
391
|
+
/** Fetch a job record over the tRPC API; null when unreachable/not found. */
|
|
392
|
+
async function fetchJob(apiUrl, jobId) {
|
|
393
|
+
try {
|
|
394
|
+
const { createApiClient } = await import("../api-client.js");
|
|
395
|
+
const client = createApiClient(apiUrl);
|
|
396
|
+
const data = await client.jobs.get.query({ id: jobId });
|
|
397
|
+
return {
|
|
398
|
+
id: isString(data["id"]) ? data["id"] : jobId,
|
|
399
|
+
status: isString(data["status"]) ? data["status"] : undefined,
|
|
400
|
+
error: isString(data["error"]) ? data["error"] : null,
|
|
401
|
+
workflowId: isString(data["workflow_id"]) ? data["workflow_id"] : null
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
catch {
|
|
405
|
+
// Server unreachable or job missing — diagnose degrades on a null job.
|
|
406
|
+
return null;
|
|
422
407
|
}
|
|
423
|
-
|
|
424
|
-
|
|
408
|
+
}
|
|
409
|
+
async function diagnoseCommand(jobId, opts) {
|
|
410
|
+
const apiUrl = opts.apiUrl ?? process.env["NODETOOL_API_URL"] ?? "http://localhost:7777";
|
|
411
|
+
const inputs = {};
|
|
412
|
+
// Job record (best-effort over the API).
|
|
413
|
+
const job = await fetchJob(apiUrl, jobId);
|
|
414
|
+
if (job)
|
|
415
|
+
inputs.job = job;
|
|
416
|
+
else
|
|
417
|
+
inputs.job = { id: jobId };
|
|
418
|
+
// Messages + trace from a debug bundle (when one exists for this job).
|
|
419
|
+
const bundle = findDebugBundle(jobId);
|
|
420
|
+
if (bundle) {
|
|
421
|
+
const messagesPath = firstExisting([
|
|
422
|
+
path.join(bundle, "server", "messages.jsonl")
|
|
423
|
+
]);
|
|
424
|
+
if (messagesPath) {
|
|
425
|
+
try {
|
|
426
|
+
inputs.messages = await readJsonl(messagesPath);
|
|
427
|
+
}
|
|
428
|
+
catch {
|
|
429
|
+
// Unreadable — leave messages unset so the report flags it missing.
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Trace spans: --trace-file > NODETOOL_TRACE_FILE > the bundle's trace.jsonl.
|
|
434
|
+
const tracePath = firstExisting([
|
|
435
|
+
opts.traceFile,
|
|
436
|
+
process.env["NODETOOL_TRACE_FILE"],
|
|
437
|
+
bundle ? path.join(bundle, "server", "trace.jsonl") : undefined
|
|
438
|
+
].filter((p) => p != null));
|
|
439
|
+
if (tracePath) {
|
|
425
440
|
try {
|
|
426
|
-
|
|
427
|
-
process.stdout.write(`${chalk.bold(e.name)} ${chalk.gray(cfg.model?.provider ?? "?")}/${chalk.gray(cfg.model?.id ?? "?")}\n ${cfg.description ?? "(no description)"}\n`);
|
|
441
|
+
inputs.spans = await readJsonl(tracePath);
|
|
428
442
|
}
|
|
429
|
-
catch
|
|
430
|
-
|
|
443
|
+
catch {
|
|
444
|
+
// Unreadable — report flags trace as missing.
|
|
431
445
|
}
|
|
432
446
|
}
|
|
447
|
+
const report = diagnoseRun(inputs);
|
|
448
|
+
if (opts.json) {
|
|
449
|
+
process.stdout.write(JSON.stringify(report, null, 2) + "\n");
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
process.stdout.write(renderDiagnosis(report) + "\n");
|
|
453
|
+
}
|
|
454
|
+
process.exit(report.ok ? 0 : 1);
|
|
433
455
|
}
|
|
434
456
|
// ---------------------------------------------------------------------------
|
|
435
457
|
// Registration
|
|
436
458
|
// ---------------------------------------------------------------------------
|
|
437
459
|
export function registerAgentCommands(program) {
|
|
438
|
-
const agent = program
|
|
460
|
+
const agent = program
|
|
461
|
+
.command("agent")
|
|
462
|
+
.description("Run the agent loop from the command line");
|
|
439
463
|
agent
|
|
440
|
-
.command("run
|
|
441
|
-
.description("Run an agent
|
|
442
|
-
.option("-o, --objective <text>", "Objective for the agent
|
|
443
|
-
.option("--
|
|
444
|
-
.option("-
|
|
445
|
-
.option("-
|
|
446
|
-
.option("-
|
|
464
|
+
.command("run")
|
|
465
|
+
.description("Run an agent over the default toolbelt (objective via --objective or stdin)")
|
|
466
|
+
.option("-o, --objective <text>", "Objective for the agent")
|
|
467
|
+
.option("-p, --provider <id>", "Provider id")
|
|
468
|
+
.option("-m, --model <id>", "Model id")
|
|
469
|
+
.option("-w, --workspace <path>", "Workspace dir (default: cwd)")
|
|
470
|
+
.option("--max-iterations <n>", "Tool-calling rounds in the turn (default 25)")
|
|
471
|
+
.option("--permission-mode <mode>", `Permission mode (${PERMISSION_MODE_NAMES.join(" | ")}); on a TTY the ` +
|
|
472
|
+
"default asks before each write, execute or external call")
|
|
473
|
+
.option("--cost-cap <usd>", "Ceiling on provider spend for the whole run, shared by every loop it " +
|
|
474
|
+
"starts; 0 lifts it (default: NODETOOL_AGENT_TURN_COST_CAP_USD)")
|
|
475
|
+
.option("--timeout <s>", "Wall-clock bound on the run in seconds; 0 leaves it no time at all " +
|
|
476
|
+
"(default: NODETOOL_AGENT_TURN_DEADLINE_MS)")
|
|
447
477
|
.option("--json", "Emit each event as a JSON line on stderr")
|
|
448
478
|
.option("-v, --verbose", "Include chunk/other low-level events in trace")
|
|
449
|
-
.action(async (
|
|
450
|
-
try {
|
|
451
|
-
await runAgentCommand(file, opts);
|
|
452
|
-
}
|
|
453
|
-
catch (e) {
|
|
454
|
-
process.stderr.write(chalk.red(`error: ${String(e)}\n`));
|
|
455
|
-
process.exit(1);
|
|
456
|
-
}
|
|
457
|
-
});
|
|
458
|
-
agent
|
|
459
|
-
.command("test <yaml-file>")
|
|
460
|
-
.description("Validate an agent YAML config (provider, model, tools)")
|
|
461
|
-
.action(async (file) => {
|
|
479
|
+
.action(async (opts) => {
|
|
462
480
|
try {
|
|
463
|
-
await
|
|
481
|
+
process.exit(await runAgentCommand(opts));
|
|
464
482
|
}
|
|
465
483
|
catch (e) {
|
|
466
484
|
process.stderr.write(chalk.red(`error: ${String(e)}\n`));
|
|
@@ -468,11 +486,14 @@ export function registerAgentCommands(program) {
|
|
|
468
486
|
}
|
|
469
487
|
});
|
|
470
488
|
agent
|
|
471
|
-
.command("
|
|
472
|
-
.description("
|
|
473
|
-
.
|
|
489
|
+
.command("diagnose <job_id>")
|
|
490
|
+
.description("Aggregate a failed run (failing node/step, error, last LLM call, memory) into one report")
|
|
491
|
+
.option("--json", "Emit the DiagnosisReport as JSON")
|
|
492
|
+
.option("--trace-file <path>", "Trace JSONL to read the last llm.chat span from (else NODETOOL_TRACE_FILE or the debug bundle)")
|
|
493
|
+
.option("--api-url <url>", "API base URL for the job lookup")
|
|
494
|
+
.action(async (jobId, opts) => {
|
|
474
495
|
try {
|
|
475
|
-
await
|
|
496
|
+
await diagnoseCommand(jobId, opts);
|
|
476
497
|
}
|
|
477
498
|
catch (e) {
|
|
478
499
|
process.stderr.write(chalk.red(`error: ${String(e)}\n`));
|