@galaxyproject/orbit 0.0.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +123 -0
- package/LICENSE +21 -0
- package/README.md +760 -5
- package/bin/legacy-mcp-config.js +363 -0
- package/bin/orbit.js +810 -0
- package/bin/pi-extension-path.d.ts +4 -0
- package/bin/pi-extension-path.js +44 -0
- package/bin/provider-auth.d.ts +22 -0
- package/bin/provider-auth.js +77 -0
- package/bin/thinking-pref.js +38 -0
- package/bin/update-check.d.ts +15 -0
- package/bin/update-check.js +137 -0
- package/extensions/cli-update/index.ts +32 -0
- package/extensions/orbit/activity-hooks.ts +141 -0
- package/extensions/orbit/activity.ts +116 -0
- package/extensions/orbit/agent-dir.ts +11 -0
- package/extensions/orbit/auto-resume.ts +352 -0
- package/extensions/orbit/config.ts +3 -0
- package/extensions/orbit/confusables.ts +1 -0
- package/extensions/orbit/context.ts +957 -0
- package/extensions/orbit/dashboard-commands.ts +191 -0
- package/extensions/orbit/dashboard-store.ts +473 -0
- package/extensions/orbit/dashboard-tools.ts +1185 -0
- package/extensions/orbit/empty-completion.ts +99 -0
- package/extensions/orbit/evidence-gate.ts +1276 -0
- package/extensions/orbit/evidence-override-command.ts +294 -0
- package/extensions/orbit/exec-guard/bash-risk.ts +1408 -0
- package/extensions/orbit/exec-guard/gate.ts +181 -0
- package/extensions/orbit/exec-guard/guardian-config.ts +54 -0
- package/extensions/orbit/exec-guard/index.ts +1 -0
- package/extensions/orbit/exec-guard/model-tier.ts +36 -0
- package/extensions/orbit/exec-guard/path-jail.ts +54 -0
- package/extensions/orbit/exec-guard/policy.ts +342 -0
- package/extensions/orbit/exec-guard/runtime-state.ts +15 -0
- package/extensions/orbit/exec-guard/sensitive-read.ts +525 -0
- package/extensions/orbit/exec-guard/types.ts +42 -0
- package/extensions/orbit/execution-commands.ts +134 -0
- package/extensions/orbit/feedback-command.ts +81 -0
- package/extensions/orbit/feedback.ts +96 -0
- package/extensions/orbit/galaxy-api.test.ts +122 -0
- package/extensions/orbit/galaxy-api.ts +606 -0
- package/extensions/orbit/galaxy-artifact-link-guidance.ts +5 -0
- package/extensions/orbit/galaxy-destructive-gate.ts +113 -0
- package/extensions/orbit/galaxy-enrich.ts +1108 -0
- package/extensions/orbit/galaxy-failure.ts +101 -0
- package/extensions/orbit/galaxy-fixture.ts +126 -0
- package/extensions/orbit/galaxy-history-guard.ts +233 -0
- package/extensions/orbit/galaxy-job-block.ts +347 -0
- package/extensions/orbit/galaxy-job-ops.ts +288 -0
- package/extensions/orbit/galaxy-live-source.ts +929 -0
- package/extensions/orbit/galaxy-markdown-adapter.ts +248 -0
- package/extensions/orbit/galaxy-op-policy.ts +332 -0
- package/extensions/orbit/galaxy-ops-tools.ts +326 -0
- package/extensions/orbit/galaxy-output-store.ts +80 -0
- package/extensions/orbit/galaxy-output.ts +346 -0
- package/extensions/orbit/galaxy-page-binding.ts +222 -0
- package/extensions/orbit/galaxy-page-markdown-guidance.ts +15 -0
- package/extensions/orbit/galaxy-page-ops.ts +159 -0
- package/extensions/orbit/galaxy-page-sync.test.ts +417 -0
- package/extensions/orbit/galaxy-page-sync.ts +318 -0
- package/extensions/orbit/galaxy-pages-api.ts +203 -0
- package/extensions/orbit/galaxy-pages-sync.ts +409 -0
- package/extensions/orbit/galaxy-poll-guard.ts +189 -0
- package/extensions/orbit/galaxy-poller.ts +706 -0
- package/extensions/orbit/galaxy-provenance.ts +623 -0
- package/extensions/orbit/galaxy-reconcile.ts +956 -0
- package/extensions/orbit/galaxy-recovery.ts +176 -0
- package/extensions/orbit/galaxy-repeat-guard.ts +55 -0
- package/extensions/orbit/galaxy-submission-capture.ts +707 -0
- package/extensions/orbit/galaxy-submission.ts +502 -0
- package/extensions/orbit/galaxy-tool-source.ts +78 -0
- package/extensions/orbit/galaxy-tool-wrap.ts +234 -0
- package/extensions/orbit/galaxy-udt-block.ts +127 -0
- package/extensions/orbit/galaxy-upload-tus.ts +334 -0
- package/extensions/orbit/galaxy-upload.ts +300 -0
- package/extensions/orbit/galaxy-version-capture.ts +65 -0
- package/extensions/orbit/git.ts +173 -0
- package/extensions/orbit/harness-block-fields.ts +597 -0
- package/extensions/orbit/index.ts +593 -0
- package/extensions/orbit/init-gate.ts +284 -0
- package/extensions/orbit/instructions-command.ts +136 -0
- package/extensions/orbit/invocation-failure-hint.ts +57 -0
- package/extensions/orbit/iwc-plan-check.ts +94 -0
- package/extensions/orbit/lesson-command.ts +303 -0
- package/extensions/orbit/lesson-hint.ts +245 -0
- package/extensions/orbit/lesson-nudge.ts +106 -0
- package/extensions/orbit/lessons/compose.ts +177 -0
- package/extensions/orbit/lessons/counters.ts +120 -0
- package/extensions/orbit/lessons/enabled.ts +116 -0
- package/extensions/orbit/lessons/matcher.ts +346 -0
- package/extensions/orbit/lessons/paths.ts +286 -0
- package/extensions/orbit/lessons/pi-event-contract.ts +105 -0
- package/extensions/orbit/lessons/propose-replay.ts +103 -0
- package/extensions/orbit/lessons/propose-tool.ts +222 -0
- package/extensions/orbit/lessons/propose.ts +502 -0
- package/extensions/orbit/lessons/replay.ts +89 -0
- package/extensions/orbit/lessons/reproduction-index.ts +83 -0
- package/extensions/orbit/lessons/search-tool.ts +99 -0
- package/extensions/orbit/lessons/search.ts +136 -0
- package/extensions/orbit/lessons/store.ts +415 -0
- package/extensions/orbit/lessons/text.ts +36 -0
- package/extensions/orbit/lessons/types.ts +69 -0
- package/extensions/orbit/lessons/user-dir.ts +24 -0
- package/extensions/orbit/lessons/user-lesson.ts +88 -0
- package/extensions/orbit/lessons/wrapper.ts +61 -0
- package/extensions/orbit/lessons-command.ts +147 -0
- package/extensions/orbit/local-exec.ts +39 -0
- package/extensions/orbit/mcp-output.ts +179 -0
- package/extensions/orbit/mcp-servers.test.ts +24 -0
- package/extensions/orbit/mcp-servers.ts +25 -0
- package/extensions/orbit/model-script.ts +351 -0
- package/extensions/orbit/notebook-anchors.ts +342 -0
- package/extensions/orbit/notebook-writer.ts +863 -0
- package/extensions/orbit/observation-allowlists.ts +1109 -0
- package/extensions/orbit/observation-replay.ts +148 -0
- package/extensions/orbit/observation-triggers.ts +563 -0
- package/extensions/orbit/observation-ui.ts +175 -0
- package/extensions/orbit/observations-command.ts +421 -0
- package/extensions/orbit/observations-config.ts +200 -0
- package/extensions/orbit/observations.ts +1381 -0
- package/extensions/orbit/profiles.ts +270 -0
- package/extensions/orbit/progress-updates.ts +95 -0
- package/extensions/orbit/proposal-commands.ts +882 -0
- package/extensions/orbit/provenance-fs-file.ts +59 -0
- package/extensions/orbit/provenance-fs.ts +32 -0
- package/extensions/orbit/provenance-memory-fs.ts +59 -0
- package/extensions/orbit/record-store-file.ts +177 -0
- package/extensions/orbit/record-store-page.ts +77 -0
- package/extensions/orbit/record-store-seam.ts +47 -0
- package/extensions/orbit/record-store.ts +149 -0
- package/extensions/orbit/registry-carrier.ts +107 -0
- package/extensions/orbit/registry-eligibility.ts +95 -0
- package/extensions/orbit/registry-evaluation.ts +403 -0
- package/extensions/orbit/registry-evaluator.ts +519 -0
- package/extensions/orbit/registry-import.ts +91 -0
- package/extensions/orbit/registry-lock.ts +221 -0
- package/extensions/orbit/registry-memory-fs.ts +42 -0
- package/extensions/orbit/registry-page-carrier.ts +103 -0
- package/extensions/orbit/registry-proposal.ts +1348 -0
- package/extensions/orbit/registry-runtime.ts +234 -0
- package/extensions/orbit/registry-schema.ts +735 -0
- package/extensions/orbit/registry-submitter.ts +59 -0
- package/extensions/orbit/registry-templates.ts +346 -0
- package/extensions/orbit/registry.ts +476 -0
- package/extensions/orbit/sandbox/index.ts +120 -0
- package/extensions/orbit/sandbox/sandbox-bash.ts +93 -0
- package/extensions/orbit/sandbox/sandbox-config.ts +87 -0
- package/extensions/orbit/sandbox/sandbox-init-message.ts +28 -0
- package/extensions/orbit/secret-redaction.ts +247 -0
- package/extensions/orbit/session-index/cwd.ts +18 -0
- package/extensions/orbit/session-index/db.ts +56 -0
- package/extensions/orbit/session-index/indexer.ts +154 -0
- package/extensions/orbit/session-index/is-enabled.ts +17 -0
- package/extensions/orbit/session-index/parse.ts +254 -0
- package/extensions/orbit/session-index/query.ts +209 -0
- package/extensions/orbit/session-index/schema.ts +72 -0
- package/extensions/orbit/session-index/tools.ts +152 -0
- package/extensions/orbit/session-lifecycle.ts +321 -0
- package/extensions/orbit/skill-triggers.ts +159 -0
- package/extensions/orbit/skills-command.ts +48 -0
- package/extensions/orbit/skills-discovery.ts +435 -0
- package/extensions/orbit/skills.ts +84 -0
- package/extensions/orbit/sra-import-gate.ts +77 -0
- package/extensions/orbit/state.ts +265 -0
- package/extensions/orbit/submission-replay.ts +147 -0
- package/extensions/orbit/sync-command.ts +157 -0
- package/extensions/orbit/teams/critic-parser.ts +93 -0
- package/extensions/orbit/teams/dispatcher.ts +210 -0
- package/extensions/orbit/teams/is-enabled.ts +22 -0
- package/extensions/orbit/teams/tool.ts +187 -0
- package/extensions/orbit/teams/types.ts +57 -0
- package/extensions/orbit/teams/validate.ts +42 -0
- package/extensions/orbit/tester-id-command.ts +133 -0
- package/extensions/orbit/tools-sync.ts +279 -0
- package/extensions/orbit/tools.ts +1300 -0
- package/extensions/orbit/types.ts +41 -0
- package/extensions/orbit/ui-bridge.ts +55 -0
- package/extensions/orbit/ulid.ts +60 -0
- package/extensions/orbit/user-instructions.ts +388 -0
- package/extensions/orbit/vendor/skills/_catalog.json +68 -0
- package/extensions/orbit/vendor/skills/_manifest.json +1106 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/SKILL.md +112 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_provenance.json +218 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_required_tools.json +33 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/add.json +50 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-extract.json +51 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-next-step.json +42 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/draft-validate.json +140 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/cli/list.json +32 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/galaxy-tool-job-failure-reference.md +137 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-tool-summary.schema.json +175 -0
- package/extensions/orbit/vendor/skills/advance-galaxy-draft-step/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/SKILL.md +82 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_provenance.json +133 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_required_tools.json +16 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/cli/draft-validate.json +140 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/galaxy-workflow-draft-format.md +135 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/apply-galaxy-workflow-changeset/references/schemas/galaxy-workflow-draft.schema.json +2727 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/SKILL.md +84 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_provenance.json +166 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/_verify.json +29 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/galaxy-workflow-testability-design.md +136 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/iwc-test-data-conventions.md +308 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/summary-galaxy-workflow.schema.json +687 -0
- package/extensions/orbit/vendor/skills/changeset-to-galaxy-test-plan/references/schemas/tests-format.schema.json +7328 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/SKILL.md +127 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_provenance.json +198 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_required_tools.json +16 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/cli/convert.json +123 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/galaxy-data-flow-draft-contract.md +129 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/iwc-test-data-conventions.md +308 -0
- package/extensions/orbit/vendor/skills/compare-against-iwc-exemplar/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/SKILL.md +73 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_provenance.json +160 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.md +43 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-collection-semantics.yml +1250 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-tool-job-failure-reference.md +137 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/nextflow-operators-to-galaxy-collection-recipes.md +98 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/debug-galaxy-workflow-output/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/SKILL.md +174 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/_provenance.json +130 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/_required_tools.json +18 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-revisions.json +48 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-search.json +95 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/cli/tool-versions.json +39 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/notes/component-tool-shed-search.md +230 -0
- package/extensions/orbit/vendor/skills/discover-shed-tool/references/schemas/galaxy-tool-discovery.schema.json +231 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/SKILL.md +93 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_provenance.json +201 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_required_tools.json +28 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/planemo.md +44 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/cli/validate-tests.json +40 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/galaxy-workflow-testability-design.md +136 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-shortcuts-anti-patterns.md +357 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/iwc-test-data-conventions.md +308 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/galaxy-workflow-test-plan.schema.json +552 -0
- package/extensions/orbit/vendor/skills/implement-galaxy-workflow-test/references/schemas/tests-format.schema.json +7328 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/SKILL.md +81 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_provenance.json +93 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/notes/open-requirements-ledger.md +173 -0
- package/extensions/orbit/vendor/skills/interview-to-galaxy-workflow-changeset/references/schemas/summary-galaxy-workflow.schema.json +687 -0
- package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/SKILL.md +81 -0
- package/extensions/orbit/vendor/skills/pipeline-update-interview-to-galaxy/_assembly.json +23 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/SKILL.md +79 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/_provenance.json +125 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/_required_tools.json +28 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/planemo.md +44 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/cli/validate-tests.json +40 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-asserts-idioms.md +246 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/notes/planemo-workflow-test-architecture.md +151 -0
- package/extensions/orbit/vendor/skills/run-workflow-test/references/schemas/tests-format.schema.json +7328 -0
- package/extensions/orbit/vendor/skills/skills/LICENSE +21 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/README.md +39 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/SKILL.md +892 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/api-patterns.md +927 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/apply-rules.md +1482 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/test-patterns.md +996 -0
- package/extensions/orbit/vendor/skills/skills/collection-manipulation/references/tools.md +609 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-data-libraries/SKILL.md +170 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/README.md +162 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/SKILL.md +99 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/README.md +119 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/tool-checking.md +419 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/examples/workflow-testing.md +617 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/galaxy-integration.md +614 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/SKILL.md +144 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/average_col3.ipynb +68 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/extract_sample_metadata.ipynb +190 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/variant_annotation.ipynb +816 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/jupyterlite/examples/vcp_variant_map.ipynb +443 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/README.md +165 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-integration/scripts/galaxy_tool_checker.py +521 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/SKILL.md +128 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/gotchas.md +135 -0
- package/extensions/orbit/vendor/skills/skills/galaxy-mcp-reference/history-access.md +132 -0
- package/extensions/orbit/vendor/skills/skills/reproduciblify/SKILL.md +146 -0
- package/extensions/orbit/vendor/skills/skills/reproduciblify/references/directives.yml +496 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/SKILL.md +245 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/01-minimal-echo.yml +27 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/02-single-data-in-out.yml +27 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/03-multiple-data-js.yml +28 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/04-select-integer-boolean.yml +41 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/05-resource-requirements.yml +25 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/06-biocontainer-tool.yml +38 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/07-inline-python-script.yml +56 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/examples/08-configfile-script.yml +74 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/references/common-mistakes.md +76 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/references/schema-reference.md +155 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/references/templating.md +196 -0
- package/extensions/orbit/vendor/skills/skills/udt-authoring/scripts/validate.py +109 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/README.md +71 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/SKILL.md +190 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/histology-staining.md +145 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/examples/tissue-microarray-analysis.md +176 -0
- package/extensions/orbit/vendor/skills/skills/workflow-reports/references/directives.md +415 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/SKILL.md +98 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_provenance.json +93 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_required_tools.json +28 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/_verify.json +17 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/convert.json +123 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/foundry.md +25 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/cli/validate.json +142 -0
- package/extensions/orbit/vendor/skills/summarize-galaxy-workflow/references/schemas/summary-galaxy-workflow.schema.json +687 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/SKILL.md +74 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_provenance.json +71 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_required_tools.json +16 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/_verify.json +4 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/cli/validate.json +142 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-invocation-failure-reference.md +138 -0
- package/extensions/orbit/vendor/skills/validate-galaxy-workflow/references/notes/galaxy-workflow-testability-design.md +136 -0
- package/extensions/orbit/vendor-skills.ts +283 -0
- package/extensions/orbit/workspace-state-dir.ts +46 -0
- package/extensions/orbit-handoff/index.ts +73 -0
- package/extensions/orbit-handoff/orbit-launcher.ts +142 -0
- package/extensions/whats-new/index.ts +98 -0
- package/lessons/LICENSE +17 -0
- package/lessons/README.md +117 -0
- package/lessons/SCHEMA.md +187 -0
- package/lessons/build-snapshot.mjs +311 -0
- package/lessons/data/downloaded-file-is-not-what-its-extension-says.md +61 -0
- package/lessons/galaxy-api/403-history-is-a-hard-stop.md +57 -0
- package/lessons/galaxy-api/collection-into-single-dataset-input.md +61 -0
- package/lessons/galaxy-api/connectedvalue-in-command-line.md +62 -0
- package/lessons/galaxy-api/hid-is-not-an-id.md +59 -0
- package/lessons/galaxy-api/invoke-workflow-inputs-not-params.md +60 -0
- package/lessons/galaxy-api/repeat-param-pipe-keys.md +63 -0
- package/lessons/galaxy-api/run-tool-returns-on-submit.md +61 -0
- package/lessons/galaxy-tools/reference-index-not-on-server.md +62 -0
- package/lessons/log.md +42 -0
- package/lessons/reproduction/input-population-mismatch.md +59 -0
- package/lessons/reproduction/methods-text-vs-executed-parameters.md +62 -0
- package/lessons/snapshot.json +1004 -0
- package/lessons/stats/de-contrast-direction-and-sample-labels.md +63 -0
- package/lessons/stats/na-coerced-to-zero-in-filters.md +59 -0
- package/lessons/validate.mjs +1219 -0
- package/package.json +103 -5
- package/shared/agent-prompt.d.ts +8 -0
- package/shared/agent-prompt.js +15 -0
- package/shared/approval-prompt.d.ts +4 -0
- package/shared/approval-prompt.js +61 -0
- package/shared/brain-env.d.ts +14 -0
- package/shared/brain-env.js +108 -0
- package/shared/brain-exit.d.ts +20 -0
- package/shared/brain-exit.js +149 -0
- package/shared/capability-profile.d.ts +16 -0
- package/shared/capability-profile.js +75 -0
- package/shared/config-source.d.ts +13 -0
- package/shared/config-source.js +17 -0
- package/shared/confusables.d.ts +3 -0
- package/shared/confusables.js +93 -0
- package/shared/custom-provider.d.ts +45 -0
- package/shared/custom-provider.js +169 -0
- package/shared/dashboard-contract.d.ts +123 -0
- package/shared/dashboard-contract.js +560 -0
- package/shared/dashboard-layout-store.d.ts +44 -0
- package/shared/dashboard-layout-store.js +281 -0
- package/shared/feedback-contract.d.ts +61 -0
- package/shared/feedback-contract.js +146 -0
- package/shared/galaxy-artifact-links.d.ts +30 -0
- package/shared/galaxy-artifact-links.js +166 -0
- package/shared/galaxy-credentials.d.ts +26 -0
- package/shared/galaxy-credentials.js +71 -0
- package/shared/galaxy-destructive.d.ts +21 -0
- package/shared/galaxy-destructive.js +269 -0
- package/shared/galaxy-guidance.d.ts +2 -0
- package/shared/galaxy-guidance.js +53 -0
- package/shared/galaxy-live-contract.d.ts +92 -0
- package/shared/galaxy-live-contract.js +180 -0
- package/shared/galaxy-page-cells.d.ts +2 -0
- package/shared/galaxy-page-cells.js +22 -0
- package/shared/galaxy-tool-family.d.ts +5 -0
- package/shared/galaxy-tool-family.js +27 -0
- package/shared/galaxy-url.d.ts +1 -0
- package/shared/galaxy-url.js +48 -0
- package/shared/gtn.d.ts +31 -0
- package/shared/gtn.js +253 -0
- package/shared/handled-prompt.d.ts +3 -0
- package/shared/handled-prompt.js +26 -0
- package/shared/known-provider.d.ts +11 -0
- package/shared/known-provider.js +89 -0
- package/shared/lesson-hint-marker.d.ts +7 -0
- package/shared/lesson-hint-marker.js +32 -0
- package/shared/lesson-rules.d.ts +150 -0
- package/shared/lesson-rules.js +203 -0
- package/shared/malformed-object-ids.d.ts +1 -0
- package/shared/malformed-object-ids.js +37 -0
- package/shared/markdown-sections.d.ts +10 -0
- package/shared/markdown-sections.js +118 -0
- package/shared/notebook-fences.d.ts +12 -0
- package/shared/notebook-fences.js +53 -0
- package/shared/observation-contract.d.ts +91 -0
- package/shared/observation-contract.js +544 -0
- package/shared/orbit-config.d.ts +226 -0
- package/shared/orbit-config.js +189 -0
- package/shared/orbit-env.d.ts +13 -0
- package/shared/orbit-env.js +124 -0
- package/shared/orbit-shell-contract.d.ts +74 -0
- package/shared/orbit-shell-contract.js +30 -0
- package/shared/page-content-hash.d.ts +1 -0
- package/shared/page-content-hash.js +13 -0
- package/shared/pi-default-model.d.ts +7 -0
- package/shared/pi-default-model.js +41 -0
- package/shared/prompt-blocks.d.ts +87 -0
- package/shared/prompt-blocks.js +898 -0
- package/shared/provider-auth-caps.d.ts +22 -0
- package/shared/provider-auth-caps.js +57 -0
- package/shared/random.d.ts +2 -0
- package/shared/random.js +15 -0
- package/shared/record-excerpt.d.ts +4 -0
- package/shared/record-excerpt.js +16 -0
- package/shared/redirect-guard.d.ts +36 -0
- package/shared/redirect-guard.js +235 -0
- package/shared/skills-pin.d.ts +8 -0
- package/shared/skills-pin.js +9 -0
- package/shared/skills-router.d.ts +17 -0
- package/shared/skills-router.js +63 -0
- package/shared/sra-import.d.ts +34 -0
- package/shared/sra-import.js +206 -0
- package/shared/state-dir.d.ts +21 -0
- package/shared/state-dir.js +240 -0
- package/shared/team-dispatch-contract.d.ts +28 -0
- package/shared/team-dispatch-contract.js +1 -0
- package/shared/truncate-middle.d.ts +11 -0
- package/shared/truncate-middle.js +68 -0
- package/shared/version-compare.d.ts +10 -0
- package/shared/version-compare.js +74 -0
- package/shared/whats-new.d.ts +31 -0
- package/shared/whats-new.js +83 -0
- package/shared/wsl.d.ts +10 -0
- package/shared/wsl.js +24 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { validateTeamSpec } from "./validate";
|
|
2
|
+
import { parseCriticResponse } from "./critic-parser";
|
|
3
|
+
import type { DispatchDeps, TeamResult, TeamSpec, TeamTurn } from "./types";
|
|
4
|
+
|
|
5
|
+
export interface DispatchOptions {
|
|
6
|
+
tokenCeiling?: number; // default 300_000
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type OnTurnUpdate = (snapshot: {
|
|
10
|
+
round: number;
|
|
11
|
+
max_rounds: number;
|
|
12
|
+
current_role: string;
|
|
13
|
+
turns: TeamTurn[];
|
|
14
|
+
}) => void;
|
|
15
|
+
|
|
16
|
+
const DEFAULT_TOKEN_CEILING = 300_000;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Run the two-role critic loop to completion.
|
|
20
|
+
* `deps.runRoleTurn` is injected so this function is unit-testable without
|
|
21
|
+
* a real Pi runtime.
|
|
22
|
+
*/
|
|
23
|
+
export async function runTeamDispatch(
|
|
24
|
+
spec: TeamSpec,
|
|
25
|
+
deps: DispatchDeps,
|
|
26
|
+
signal: AbortSignal,
|
|
27
|
+
onTurn?: OnTurnUpdate,
|
|
28
|
+
options: DispatchOptions = {},
|
|
29
|
+
): Promise<TeamResult> {
|
|
30
|
+
validateTeamSpec(spec);
|
|
31
|
+
|
|
32
|
+
const tokenCeiling = options.tokenCeiling ?? DEFAULT_TOKEN_CEILING;
|
|
33
|
+
const maxRounds = spec.max_rounds ?? 5;
|
|
34
|
+
const [proposer, critic] = spec.roles;
|
|
35
|
+
const transcript: TeamTurn[] = [];
|
|
36
|
+
let totalUsage = { input_tokens: 0, output_tokens: 0 };
|
|
37
|
+
let currentProposal = "";
|
|
38
|
+
let currentCritique: string | null = null;
|
|
39
|
+
let round = 0;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
for (round = 1; round <= maxRounds; round++) {
|
|
43
|
+
// --- Proposer turn ---
|
|
44
|
+
if (signal.aborted) return aborted(transcript, round, currentProposal, totalUsage);
|
|
45
|
+
const proposerInput = renderProposerInput(spec.description, currentCritique);
|
|
46
|
+
const proposerPreamble = buildPreamble(spec, proposer, "proposer");
|
|
47
|
+
const proposerResult = await deps.runRoleTurn(
|
|
48
|
+
proposer,
|
|
49
|
+
proposerPreamble,
|
|
50
|
+
proposerInput,
|
|
51
|
+
signal,
|
|
52
|
+
);
|
|
53
|
+
currentProposal = proposerResult.content;
|
|
54
|
+
transcript.push({
|
|
55
|
+
round,
|
|
56
|
+
role: proposer.name,
|
|
57
|
+
content: currentProposal,
|
|
58
|
+
});
|
|
59
|
+
totalUsage = add(totalUsage, proposerResult.usage);
|
|
60
|
+
onTurn?.({ round, max_rounds: maxRounds, current_role: proposer.name, turns: transcript });
|
|
61
|
+
|
|
62
|
+
if (exceedsCeiling(totalUsage, tokenCeiling)) {
|
|
63
|
+
return budgetExhausted(transcript, round, currentProposal, totalUsage);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// --- Critic turn ---
|
|
67
|
+
if (signal.aborted) return aborted(transcript, round, currentProposal, totalUsage);
|
|
68
|
+
const criticInput = renderCriticInput(spec.description, currentProposal);
|
|
69
|
+
const criticPreamble = buildPreamble(spec, critic, "critic");
|
|
70
|
+
const criticResult = await deps.runRoleTurn(critic, criticPreamble, criticInput, signal);
|
|
71
|
+
const verdict = parseCriticResponse(criticResult.content);
|
|
72
|
+
transcript.push({
|
|
73
|
+
round,
|
|
74
|
+
role: critic.name,
|
|
75
|
+
content: criticResult.content,
|
|
76
|
+
approved: verdict.approved,
|
|
77
|
+
});
|
|
78
|
+
totalUsage = add(totalUsage, criticResult.usage);
|
|
79
|
+
onTurn?.({ round, max_rounds: maxRounds, current_role: critic.name, turns: transcript });
|
|
80
|
+
|
|
81
|
+
if (verdict.approved) {
|
|
82
|
+
return {
|
|
83
|
+
converged: true,
|
|
84
|
+
rounds: round,
|
|
85
|
+
final_output: currentProposal,
|
|
86
|
+
transcript,
|
|
87
|
+
usage: totalUsage,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
if (exceedsCeiling(totalUsage, tokenCeiling)) {
|
|
91
|
+
return budgetExhausted(transcript, round, currentProposal, totalUsage);
|
|
92
|
+
}
|
|
93
|
+
currentCritique = verdict.critique;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
converged: false,
|
|
98
|
+
rounds: maxRounds,
|
|
99
|
+
final_output: currentProposal,
|
|
100
|
+
transcript,
|
|
101
|
+
usage: totalUsage,
|
|
102
|
+
};
|
|
103
|
+
} catch (err) {
|
|
104
|
+
if (isAbortError(err) || signal.aborted) {
|
|
105
|
+
return aborted(transcript, round, currentProposal, totalUsage);
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
converged: false,
|
|
109
|
+
rounds: round,
|
|
110
|
+
final_output: currentProposal,
|
|
111
|
+
transcript,
|
|
112
|
+
usage: totalUsage,
|
|
113
|
+
error: err instanceof Error ? err.message : String(err),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// --- helpers ------------------------------------------------------------
|
|
119
|
+
|
|
120
|
+
function renderProposerInput(description: string, priorCritique: string | null): string {
|
|
121
|
+
if (priorCritique === null) {
|
|
122
|
+
return `Team task: ${description}\n\nProduce your first proposal.`;
|
|
123
|
+
}
|
|
124
|
+
return (
|
|
125
|
+
`Team task: ${description}\n\n` +
|
|
126
|
+
`The critic raised the following issues with your previous proposal:\n${priorCritique}\n\n` +
|
|
127
|
+
`Produce a revised proposal that addresses them.`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function renderCriticInput(description: string, proposal: string): string {
|
|
132
|
+
return (
|
|
133
|
+
`Team task: ${description}\n\n` +
|
|
134
|
+
`Proposer output:\n${proposal}\n\n` +
|
|
135
|
+
`Critique the proposal. End your response with a JSON line of shape ` +
|
|
136
|
+
`{"approved": boolean, "critique": string}.`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function buildPreamble(
|
|
141
|
+
spec: TeamSpec,
|
|
142
|
+
role: { system_prompt: string },
|
|
143
|
+
kind: "proposer" | "critic",
|
|
144
|
+
): string {
|
|
145
|
+
const teamContext =
|
|
146
|
+
`You are one role in a two-agent team collaborating on the task: "${spec.description}". ` +
|
|
147
|
+
`Respond only from your role's perspective.`;
|
|
148
|
+
const criticContract =
|
|
149
|
+
kind === "critic"
|
|
150
|
+
? ` When you have finished critiquing, finish your response with a JSON line: ` +
|
|
151
|
+
`{"approved": boolean, "critique": "one paragraph"}.`
|
|
152
|
+
: "";
|
|
153
|
+
return `${teamContext}${criticContract}\n\n${role.system_prompt}`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function add(
|
|
157
|
+
a: { input_tokens: number; output_tokens: number },
|
|
158
|
+
b: { input_tokens: number; output_tokens: number },
|
|
159
|
+
) {
|
|
160
|
+
return {
|
|
161
|
+
input_tokens: a.input_tokens + b.input_tokens,
|
|
162
|
+
output_tokens: a.output_tokens + b.output_tokens,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function exceedsCeiling(
|
|
167
|
+
u: { input_tokens: number; output_tokens: number },
|
|
168
|
+
ceiling: number,
|
|
169
|
+
): boolean {
|
|
170
|
+
return u.input_tokens + u.output_tokens > ceiling;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function aborted(
|
|
174
|
+
transcript: TeamTurn[],
|
|
175
|
+
round: number,
|
|
176
|
+
finalOutput: string,
|
|
177
|
+
usage: { input_tokens: number; output_tokens: number },
|
|
178
|
+
): TeamResult {
|
|
179
|
+
return {
|
|
180
|
+
converged: false,
|
|
181
|
+
aborted: true,
|
|
182
|
+
rounds: round,
|
|
183
|
+
final_output: finalOutput,
|
|
184
|
+
transcript,
|
|
185
|
+
usage,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function budgetExhausted(
|
|
190
|
+
transcript: TeamTurn[],
|
|
191
|
+
round: number,
|
|
192
|
+
finalOutput: string,
|
|
193
|
+
usage: { input_tokens: number; output_tokens: number },
|
|
194
|
+
): TeamResult {
|
|
195
|
+
return {
|
|
196
|
+
converged: false,
|
|
197
|
+
budget_exhausted: true,
|
|
198
|
+
rounds: round,
|
|
199
|
+
final_output: finalOutput,
|
|
200
|
+
transcript,
|
|
201
|
+
usage,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function isAbortError(err: unknown): boolean {
|
|
206
|
+
return (
|
|
207
|
+
err instanceof Error &&
|
|
208
|
+
(err.name === "AbortError" || err.message.toLowerCase().includes("abort"))
|
|
209
|
+
);
|
|
210
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { loadConfig } from "../config";
|
|
2
|
+
import { readEnv } from "../../../shared/orbit-env.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Whether the experimental team_dispatch tool is opted in.
|
|
6
|
+
*
|
|
7
|
+
* Resolution order (env wins so a developer can flip it for one session
|
|
8
|
+
* without touching ~/.orbit/config.json):
|
|
9
|
+
* 1. LOOM_TEAM_DISPATCH env var -- "1" -> on, "0" -> off (explicit
|
|
10
|
+
* override of an on-config), anything else -> defer to config.
|
|
11
|
+
* 2. config.experiments.teamDispatch -- boolean.
|
|
12
|
+
* 3. Default: off.
|
|
13
|
+
*
|
|
14
|
+
* Intended to be called once at extension boot, not in a hot path --
|
|
15
|
+
* each call hits loadConfig() / disk.
|
|
16
|
+
*/
|
|
17
|
+
export function isTeamDispatchEnabled(): boolean {
|
|
18
|
+
const env = readEnv("TEAM_DISPATCH");
|
|
19
|
+
if (env === "1") return true;
|
|
20
|
+
if (env === "0") return false;
|
|
21
|
+
return loadConfig().experiments?.teamDispatch === true;
|
|
22
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { Type } from "@sinclair/typebox";
|
|
3
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
4
|
+
// pi 0.80 moved the global API to /compat. The extension loader aliases the
|
|
5
|
+
// root at runtime, but the typecheck resolves the published types, so import
|
|
6
|
+
// the real path.
|
|
7
|
+
import { completeSimple } from "@earendil-works/pi-ai/compat";
|
|
8
|
+
import type { Model } from "@earendil-works/pi-ai/compat";
|
|
9
|
+
import { runTeamDispatch } from "./dispatcher";
|
|
10
|
+
import { modelScriptRefusal } from "../model-script";
|
|
11
|
+
import { validateTeamSpec } from "./validate";
|
|
12
|
+
import type { DispatchDeps, RoleTurnResult, TeamSpec, RoleSpec } from "./types";
|
|
13
|
+
import { TEAM_DISPATCH_KIND } from "../../../shared/team-dispatch-contract.js";
|
|
14
|
+
import type { TeamDispatchDetails } from "../../../shared/team-dispatch-contract.js";
|
|
15
|
+
|
|
16
|
+
const RoleSchema = Type.Object({
|
|
17
|
+
name: Type.String({ minLength: 1 }),
|
|
18
|
+
system_prompt: Type.String({ minLength: 1 }),
|
|
19
|
+
model: Type.Optional(Type.String()),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const TeamSpecSchema = Type.Object({
|
|
23
|
+
description: Type.String({ minLength: 1 }),
|
|
24
|
+
roles: Type.Array(RoleSchema, { minItems: 2, maxItems: 2 }),
|
|
25
|
+
max_rounds: Type.Optional(Type.Integer({ minimum: 1, maximum: 20 })),
|
|
26
|
+
model: Type.Optional(Type.String()),
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export function registerTeamTools(pi: ExtensionAPI): void {
|
|
30
|
+
pi.registerTool({
|
|
31
|
+
name: "team_dispatch",
|
|
32
|
+
label: "Dispatch specialist team",
|
|
33
|
+
description:
|
|
34
|
+
"Run a two-role critic loop (proposer → critic) to converge on a result. " +
|
|
35
|
+
"Use when the user asks for a 'team' to handle a bounded sub-task such as " +
|
|
36
|
+
"literature review or cross-checking findings. Each role is a pure-reasoning " +
|
|
37
|
+
"LLM call (no tools); gather any external data with your own tools first and " +
|
|
38
|
+
"include it in the `description`. Returns the converged result; persist useful " +
|
|
39
|
+
"output by editing notebook.md when the researcher wants it retained.",
|
|
40
|
+
parameters: TeamSpecSchema,
|
|
41
|
+
async execute(_toolCallId, params, signal, onUpdate, ctx) {
|
|
42
|
+
const spec = params as TeamSpec;
|
|
43
|
+
const scripted = modelScriptRefusal("team_dispatch");
|
|
44
|
+
if (scripted) return errorResult(new Error(scripted));
|
|
45
|
+
|
|
46
|
+
// 1. Spec validation (fail fast).
|
|
47
|
+
try {
|
|
48
|
+
validateTeamSpec(spec);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
return errorResult(err);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 2. Build the runRoleTurn binding over pi-ai.completeSimple.
|
|
54
|
+
const deps: DispatchDeps = {
|
|
55
|
+
runRoleTurn: async (
|
|
56
|
+
role: RoleSpec,
|
|
57
|
+
preamble,
|
|
58
|
+
userMessage,
|
|
59
|
+
runSignal,
|
|
60
|
+
): Promise<RoleTurnResult> => {
|
|
61
|
+
const model = resolveModel(ctx, role.model ?? spec.model);
|
|
62
|
+
if (!model) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`No model available: neither role "${role.name}" nor the team spec nor the session provides one.`,
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
const msg = await completeSimple(
|
|
68
|
+
model,
|
|
69
|
+
{
|
|
70
|
+
systemPrompt: preamble,
|
|
71
|
+
messages: [{ role: "user", content: userMessage, timestamp: Date.now() }],
|
|
72
|
+
},
|
|
73
|
+
{ signal: runSignal },
|
|
74
|
+
);
|
|
75
|
+
const content = extractText(msg);
|
|
76
|
+
// Count cache tokens too so the budget ceiling is honest on
|
|
77
|
+
// providers that charge for cache reads/writes (Anthropic).
|
|
78
|
+
const cacheRead = msg.usage.cacheRead ?? 0;
|
|
79
|
+
const cacheWrite = msg.usage.cacheWrite ?? 0;
|
|
80
|
+
return {
|
|
81
|
+
content,
|
|
82
|
+
usage: {
|
|
83
|
+
input_tokens: msg.usage.input + cacheRead + cacheWrite,
|
|
84
|
+
output_tokens: msg.usage.output,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// 3. Drive the loop; stream progress to the tool card.
|
|
91
|
+
const abort = signal ?? new AbortController().signal;
|
|
92
|
+
const result = await runTeamDispatch(spec, deps, abort, (snapshot) => {
|
|
93
|
+
const details: TeamDispatchDetails = {
|
|
94
|
+
kind: TEAM_DISPATCH_KIND,
|
|
95
|
+
spec: {
|
|
96
|
+
description: spec.description,
|
|
97
|
+
roles: spec.roles.map((r) => ({ name: r.name, model: r.model ?? spec.model })),
|
|
98
|
+
},
|
|
99
|
+
turns: snapshot.turns,
|
|
100
|
+
summary: `Round ${snapshot.round}/${snapshot.max_rounds} — ${snapshot.current_role} responding…`,
|
|
101
|
+
};
|
|
102
|
+
onUpdate?.({
|
|
103
|
+
content: [],
|
|
104
|
+
details,
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// 4. Final tool-card summary.
|
|
109
|
+
const finalSummary = result.converged
|
|
110
|
+
? `Team converged in ${result.rounds} round${result.rounds === 1 ? "" : "s"}`
|
|
111
|
+
: result.aborted
|
|
112
|
+
? `Team aborted after ${result.rounds} round${result.rounds === 1 ? "" : "s"}`
|
|
113
|
+
: result.budget_exhausted
|
|
114
|
+
? `Team halted on token budget after ${result.rounds} round${result.rounds === 1 ? "" : "s"}`
|
|
115
|
+
: result.error
|
|
116
|
+
? `Team errored after ${result.rounds} round${result.rounds === 1 ? "" : "s"}: ${result.error}`
|
|
117
|
+
: `Team did not converge (${result.rounds}/${spec.max_rounds ?? 5} rounds — best-so-far returned)`;
|
|
118
|
+
|
|
119
|
+
const finalDetails: TeamDispatchDetails = {
|
|
120
|
+
kind: TEAM_DISPATCH_KIND,
|
|
121
|
+
spec: {
|
|
122
|
+
description: spec.description,
|
|
123
|
+
roles: spec.roles.map((r) => ({ name: r.name, model: r.model ?? spec.model })),
|
|
124
|
+
},
|
|
125
|
+
turns: result.transcript,
|
|
126
|
+
summary: finalSummary,
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
content: [{ type: "text" as const, text: JSON.stringify(result, null, 2) }],
|
|
130
|
+
details: finalDetails,
|
|
131
|
+
};
|
|
132
|
+
},
|
|
133
|
+
renderResult: (result) => {
|
|
134
|
+
const d = result.details as { summary?: string } | undefined;
|
|
135
|
+
return new Text(d?.summary ?? "team_dispatch finished");
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// --- helpers ------------------------------------------------------------
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Resolve a Model<any> from a "provider:modelId" string, a bare Anthropic
|
|
144
|
+
* model id, or by falling back to the session model.
|
|
145
|
+
*/
|
|
146
|
+
function resolveModel(
|
|
147
|
+
ctx: ExtensionContext,
|
|
148
|
+
modelSpec: string | undefined,
|
|
149
|
+
): Model<any> | undefined {
|
|
150
|
+
if (modelSpec && modelSpec.trim().length > 0) {
|
|
151
|
+
const colon = modelSpec.indexOf(":");
|
|
152
|
+
const provider = colon >= 0 ? modelSpec.slice(0, colon) : "anthropic";
|
|
153
|
+
const modelId = colon >= 0 ? modelSpec.slice(colon + 1) : modelSpec;
|
|
154
|
+
const found = ctx.modelRegistry.find(provider, modelId);
|
|
155
|
+
if (!found) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Unknown model "${modelSpec}" (provider="${provider}", modelId="${modelId}"). ` +
|
|
158
|
+
`Check ctx.modelRegistry, or omit the model field to use the session default.`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
return found;
|
|
162
|
+
}
|
|
163
|
+
return ctx.model;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Flatten an AssistantMessage's text chunks into a single string. */
|
|
167
|
+
function extractText(msg: { content: Array<{ type: string; text?: string }> }): string {
|
|
168
|
+
return msg.content
|
|
169
|
+
.filter((c) => c.type === "text" && typeof c.text === "string")
|
|
170
|
+
.map((c) => c.text as string)
|
|
171
|
+
.join("");
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function errorResult(err: unknown) {
|
|
175
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
176
|
+
const details: TeamDispatchDetails = {
|
|
177
|
+
kind: TEAM_DISPATCH_KIND,
|
|
178
|
+
error: message,
|
|
179
|
+
summary: `team_dispatch failed: ${message}`,
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
content: [
|
|
183
|
+
{ type: "text" as const, text: JSON.stringify({ ok: false, error: message }, null, 2) },
|
|
184
|
+
],
|
|
185
|
+
details,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public types for the team_dispatch feature.
|
|
3
|
+
* See docs/superpowers/specs/2026-04-17-multi-agent-dispatch-design.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface TeamSpec {
|
|
7
|
+
description: string;
|
|
8
|
+
roles: RoleSpec[];
|
|
9
|
+
max_rounds?: number;
|
|
10
|
+
model?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface RoleSpec {
|
|
14
|
+
name: string;
|
|
15
|
+
system_prompt: string;
|
|
16
|
+
model?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface TeamResult {
|
|
20
|
+
converged: boolean;
|
|
21
|
+
rounds: number;
|
|
22
|
+
final_output: string;
|
|
23
|
+
transcript: TeamTurn[];
|
|
24
|
+
usage: { input_tokens: number; output_tokens: number };
|
|
25
|
+
aborted?: boolean;
|
|
26
|
+
budget_exhausted?: boolean;
|
|
27
|
+
error?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface TeamTurn {
|
|
31
|
+
round: number;
|
|
32
|
+
role: string;
|
|
33
|
+
content: string;
|
|
34
|
+
approved?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Side-effect surface the dispatcher needs.
|
|
39
|
+
* Injected so the dispatcher is testable without a real LLM runtime.
|
|
40
|
+
*
|
|
41
|
+
* MVP: roles are pure-reasoning — each turn is a single LLM call with no
|
|
42
|
+
* tool access. Main agent pre-gathers any external data and includes it
|
|
43
|
+
* in TeamSpec.description before dispatching.
|
|
44
|
+
*/
|
|
45
|
+
export interface DispatchDeps {
|
|
46
|
+
runRoleTurn: (
|
|
47
|
+
role: RoleSpec,
|
|
48
|
+
systemPreamble: string,
|
|
49
|
+
userMessage: string,
|
|
50
|
+
signal: AbortSignal,
|
|
51
|
+
) => Promise<RoleTurnResult>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface RoleTurnResult {
|
|
55
|
+
content: string;
|
|
56
|
+
usage: { input_tokens: number; output_tokens: number };
|
|
57
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TeamSpec } from "./types";
|
|
2
|
+
|
|
3
|
+
export class ValidationError extends Error {
|
|
4
|
+
constructor(message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "ValidationError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function validateTeamSpec(spec: TeamSpec): void {
|
|
11
|
+
if (!spec.description || spec.description.trim().length === 0) {
|
|
12
|
+
throw new ValidationError("TeamSpec.description must be a non-empty string");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const roles = spec.roles;
|
|
16
|
+
if (!Array.isArray(roles) || roles.length < 2) {
|
|
17
|
+
throw new ValidationError("TeamSpec.roles must contain at least 2 roles");
|
|
18
|
+
}
|
|
19
|
+
if (roles.length > 2) {
|
|
20
|
+
throw new ValidationError(
|
|
21
|
+
"TeamSpec.roles contains more than 2 roles; >2 roles is not implemented in this MVP",
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const seen = new Set<string>();
|
|
26
|
+
for (const role of roles) {
|
|
27
|
+
if (typeof role.name !== "string" || role.name.trim().length === 0) {
|
|
28
|
+
throw new ValidationError("Every RoleSpec must have a non-empty name");
|
|
29
|
+
}
|
|
30
|
+
if (seen.has(role.name)) {
|
|
31
|
+
throw new ValidationError(`RoleSpec.name must be unique; duplicate: "${role.name}"`);
|
|
32
|
+
}
|
|
33
|
+
seen.add(role.name);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const max = spec.max_rounds;
|
|
37
|
+
if (max !== undefined) {
|
|
38
|
+
if (!Number.isInteger(max) || max < 1 || max > 20) {
|
|
39
|
+
throw new ValidationError("TeamSpec.max_rounds must be an integer in [1, 20]");
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /tester-id -- the get-or-set counterpart to buildTesterIdBlock (#189/#191).
|
|
3
|
+
*
|
|
4
|
+
* With no argument it prints the current tester ID; with an argument it sets it.
|
|
5
|
+
*
|
|
6
|
+
* Beta onboarding asks testers to put a `testerId` in ~/.orbit/config.json. That
|
|
7
|
+
* file is a credential store, so the agent's edit/write to it is floored by the
|
|
8
|
+
* exec-guard -- a hard deny on low-capability models and an unreachable
|
|
9
|
+
* read-then-edit on every tier once #194 landed (issue #222). This gives the
|
|
10
|
+
* user a deterministic, model-independent path that sets ONLY the testerId key.
|
|
11
|
+
*
|
|
12
|
+
* It deliberately reads/echoes ONLY the testerId field (a non-secret tester code
|
|
13
|
+
* like "orbit-007", which already passes #194 redaction), never any other config
|
|
14
|
+
* value, so it cannot become a way to surface the API keys that #183/#194 lock
|
|
15
|
+
* down.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from "node:fs";
|
|
19
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
20
|
+
import { getConfigPath, loadConfig, saveConfig } from "./config.js";
|
|
21
|
+
import { readEnv } from "../../shared/orbit-env.js";
|
|
22
|
+
|
|
23
|
+
// Tester codes are opaque, non-secret strings (e.g. "orbit-007"). Constrain the
|
|
24
|
+
// shape so neither a fat-fingered user nor a pasted blob can smuggle a newline,
|
|
25
|
+
// JSON, or a giant value into the key: first char alphanumeric, then a few safe
|
|
26
|
+
// separators, capped length.
|
|
27
|
+
const TESTER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/;
|
|
28
|
+
|
|
29
|
+
export type ValidateResult = { ok: true; id: string } | { ok: false; error: string };
|
|
30
|
+
|
|
31
|
+
export function validateTesterId(raw: string): ValidateResult {
|
|
32
|
+
const id = (raw ?? "").trim();
|
|
33
|
+
if (!id) {
|
|
34
|
+
return { ok: false, error: "Usage: /tester-id <id> (e.g. /tester-id orbit-007)" };
|
|
35
|
+
}
|
|
36
|
+
if (!TESTER_ID_RE.test(id)) {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
error:
|
|
40
|
+
"Tester ID must be 1-64 characters: letters, digits, and . _ - only, " +
|
|
41
|
+
"starting with a letter or digit (e.g. orbit-007).",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { ok: true, id };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The currently-effective tester ID and where it came from. Mirrors
|
|
49
|
+
* buildTesterIdBlock's precedence (config wins over the env override). Reads
|
|
50
|
+
* ONLY testerId -- never another config field.
|
|
51
|
+
*/
|
|
52
|
+
export function getCurrentTesterId(): { id: string; source: "config" | "env" } | null {
|
|
53
|
+
const fromConfig = loadConfig().testerId;
|
|
54
|
+
if (fromConfig) return { id: fromConfig, source: "config" };
|
|
55
|
+
const fromEnv = readEnv("TESTER_ID");
|
|
56
|
+
if (fromEnv) return { id: fromEnv, source: "env" };
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Set ONLY the testerId key. Loads the full config so existing fields (API keys
|
|
62
|
+
* included) ride straight back to disk unchanged, mutates the single key, and
|
|
63
|
+
* persists via the shared atomic writer. No other field is read out, returned,
|
|
64
|
+
* or echoed.
|
|
65
|
+
*
|
|
66
|
+
* Fails closed: loadConfig() silently returns {} when an existing config can't
|
|
67
|
+
* be read or parsed, so writing that back would wipe the user's stored API
|
|
68
|
+
* keys. We refuse rather than clobber -- a genuinely absent file is still fine
|
|
69
|
+
* to create. A save failure is rewrapped in a fixed message so the raw error
|
|
70
|
+
* (whatever it carries) can never be surfaced through this command.
|
|
71
|
+
*/
|
|
72
|
+
export function setTesterId(id: string): void {
|
|
73
|
+
const configPath = getConfigPath();
|
|
74
|
+
if (fs.existsSync(configPath)) {
|
|
75
|
+
try {
|
|
76
|
+
JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
77
|
+
} catch (err) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
"~/.orbit/config.json couldn't be read, so it wasn't changed -- fix or remove the file and try again.",
|
|
80
|
+
{ cause: err },
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const cfg = loadConfig();
|
|
85
|
+
cfg.testerId = id;
|
|
86
|
+
try {
|
|
87
|
+
saveConfig(cfg);
|
|
88
|
+
} catch (err) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
"Couldn't write ~/.orbit/config.json -- check file permissions and free space, then try again.",
|
|
91
|
+
{ cause: err },
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export function registerTesterIdCommand(pi: ExtensionAPI): void {
|
|
97
|
+
pi.registerCommand("tester-id", {
|
|
98
|
+
description:
|
|
99
|
+
"Show or set your Orbit beta tester ID (writes only testerId to ~/.orbit/config.json).",
|
|
100
|
+
handler: async (args: string | undefined, ctx: ExtensionContext) => {
|
|
101
|
+
const raw = (args ?? "").trim();
|
|
102
|
+
|
|
103
|
+
if (!raw) {
|
|
104
|
+
const current = getCurrentTesterId();
|
|
105
|
+
if (!current) {
|
|
106
|
+
ctx.ui.notify(
|
|
107
|
+
"No tester ID set. Set one with /tester-id <id> (e.g. /tester-id orbit-007).",
|
|
108
|
+
"info",
|
|
109
|
+
);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const suffix = current.source === "env" ? " (from LOOM_TESTER_ID)" : "";
|
|
113
|
+
ctx.ui.notify(`Tester ID: ${current.id}${suffix}`, "info");
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const result = validateTesterId(raw);
|
|
118
|
+
if (!result.ok) {
|
|
119
|
+
ctx.ui.notify(result.error, "error");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
try {
|
|
123
|
+
setTesterId(result.id);
|
|
124
|
+
} catch (err) {
|
|
125
|
+
// setTesterId only throws messages it authored -- never a raw error
|
|
126
|
+
// that could carry config contents -- so showing it is safe.
|
|
127
|
+
ctx.ui.notify(err instanceof Error ? err.message : "Failed to save tester ID.", "error");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
ctx.ui.notify(`Tester ID set to ${result.id}.`, "info");
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
}
|