@humwick/server 0.130.1 → 0.130.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/docs/guides/tools-administration.md +4 -0
- package/docs/guides/tools-coordination.md +1 -0
- package/docs/guides/tools-tasks.md +8 -0
- package/docs/guides/workflows.md +58 -0
- package/docs/openapi.json +414 -1
- package/package.json +8 -17
- package/public/assets/{MessageBubble-BWpoBjl4.js → MessageBubble-BWLqMGKG.js} +2 -2
- package/public/assets/{PlanGraphPanel-C0auck3n.js → PlanGraphPanel-3TlIQpjk.js} +2 -2
- package/public/assets/{TraceView-DBnOx7AQ.js → TraceView-Wimm0Czv.js} +2 -2
- package/public/assets/{VaultDecisionCard-0kp2oNBC.js → VaultDecisionCard-Bau_vNax.js} +2 -2
- package/public/assets/{activity-yLztXEBt.js → activity-CrSurn-r.js} +2 -2
- package/public/assets/{agent-lineage-BbJDR1dW.js → agent-lineage-CknAJKcb.js} +2 -2
- package/public/assets/agent-liveness-CaNwK0Zf.js +2 -0
- package/public/assets/{agent-name-CTZBrSD9.js → agent-name-DKbiIhBo.js} +2 -2
- package/public/assets/agent-profiles-DwF6EQ4R.js +2 -0
- package/public/assets/{agent-project-badge-9TqzUUYE.js → agent-project-badge-Diz4Sjjb.js} +2 -2
- package/public/assets/{agent-tools-D4n40pn8.js → agent-tools-CRhpRQza.js} +2 -2
- package/public/assets/{agent-type-icon-D6FUarOf.js → agent-type-icon-LrUEU3lB.js} +2 -2
- package/public/assets/{agents-BYDslkJc.js → agents-B-v66C-4.js} +2 -2
- package/public/assets/{analytics-B-XSbEMC.js → analytics-BqCb-LKi.js} +2 -2
- package/public/assets/{artifact-viewer-DdWIfV6M.js → artifact-viewer-kf4pGuAR.js} +2 -2
- package/public/assets/{artifacts-oBOqks-2.js → artifacts-D32zyw4Y.js} +2 -2
- package/public/assets/{artifacts-DPN1q4pA.js → artifacts-DJevXcvg.js} +2 -2
- package/public/assets/{automation-4KcRFXEu.js → automation-BpRajx_5.js} +2 -2
- package/public/assets/{backlog-Cw9xPTCF.js → backlog-D_UjTdzX.js} +2 -2
- package/public/assets/{busy-health-CTu32MZt.js → busy-health-N3VEh4ao.js} +2 -2
- package/public/assets/{channels-BiXzg1G9.js → channels-9jopungq.js} +2 -2
- package/public/assets/{chat-Ctk2qwvA.js → chat-CSXrTB3C.js} +2 -2
- package/public/assets/{code-preview-Bm1wWqAp.js → code-preview-p1NnmqK0.js} +2 -2
- package/public/assets/{connectors-C36ax4Vw.js → connectors-CZdqlDNL.js} +2 -2
- package/public/assets/{cosmos-Jj9LK2Wf.js → cosmos-BgdsE4dG.js} +2 -2
- package/public/assets/{crate-agent-H6S7-B9T.js → crate-agent-30aXTKva.js} +2 -2
- package/public/assets/{dependency-graph-Cd1E23wa.js → dependency-graph-B_jvw2GE.js} +2 -2
- package/public/assets/{deploys-Bwfq146q.js → deploys-DoN6bAb5.js} +2 -2
- package/public/assets/{display-CfO7rTuF.js → display-BrKWFGJz.js} +2 -2
- package/public/assets/{files-DhhZI2Ih.js → files-D6XEu8Ng.js} +2 -2
- package/public/assets/{fleet-B_rFEbnL.js → fleet-C7jQWbw2.js} +2 -2
- package/public/assets/{fleet-metrics-BkHP-P3R.js → fleet-metrics-BiDs3MLx.js} +2 -2
- package/public/assets/{formatted-body-Cm1RrzmN.js → formatted-body-CQBwc1fb.js} +3 -3
- package/public/assets/{formatted-body-impl-DQiOuOD1.js → formatted-body-impl-DyG0WsQS.js} +2 -2
- package/public/assets/{host-providers-dialog-CHqwXTov.js → host-providers-dialog-DKaW31dN.js} +2 -2
- package/public/assets/index-CRHep3M9.js +15 -0
- package/public/assets/index-MYAIwYTX.css +2 -0
- package/public/assets/{insights-fH1EL-qZ.js → insights-CzrtkpOE.js} +2 -2
- package/public/assets/{integrations-C5Oix6ng.js → integrations-aVsUmigt.js} +2 -2
- package/public/assets/{issue-ref-chip-ODyondIa.js → issue-ref-chip-BnSlM_95.js} +2 -2
- package/public/assets/{log-viewer-Cvfy6PW7.js → log-viewer-qe7Ee47Z.js} +2 -2
- package/public/assets/{maintenance-D8CDH5wZ.js → maintenance-NfjqFZAk.js} +2 -2
- package/public/assets/{managed-agents-egllbpij.js → managed-agents-BiH0HgaE.js} +2 -2
- package/public/assets/{markdown-preview-CYSFgVgK.js → markdown-preview-BixaT3Xr.js} +3 -3
- package/public/assets/{markdown-preview-impl-BteVIjX4.js → markdown-preview-impl-DNGlWIS3.js} +2 -2
- package/public/assets/{memory-C8WmXsyr.js → memory-DNsCl6UX.js} +2 -2
- package/public/assets/{messages-BzQdqlO6.js → messages-DopU1L1X.js} +2 -2
- package/public/assets/{orchestrators-B1HxzkNw.js → orchestrators-Cq7ckLQT.js} +2 -2
- package/public/assets/{overview-DCUnI4Z7.js → overview-C1DCTzzV.js} +2 -2
- package/public/assets/{pairs-ftCd2XcD.js → pairs-DE_m6rrE.js} +2 -2
- package/public/assets/{profile-icon-B2zH8DMH.js → profile-icon-B3rfh77F.js} +2 -2
- package/public/assets/project-profile-instructions-DQWZE0kA.js +2 -0
- package/public/assets/projects-Br2Bd2h1.js +2 -0
- package/public/assets/{prompt-settings-Bftq9czX.js → prompt-settings-BKvFsvGD.js} +2 -2
- package/public/assets/provider-display-DsuWMvVL.js +2 -0
- package/public/assets/{registry-DWCU5c8q.js → registry-Cw38_6gW.js} +2 -2
- package/public/assets/run-card-CpKqRbhg.js +2 -0
- package/public/assets/scroll-text-BKXS1ahr.js +2 -0
- package/public/assets/{secrets-C7GIUATz.js → secrets-DxI-vzSq.js} +2 -2
- package/public/assets/{service-access-settings-C3aujqTG.js → service-access-settings-D9s_VJbd.js} +2 -2
- package/public/assets/{settings-C6sZ9eBa.js → settings-CKZTVGIx.js} +2 -2
- package/public/assets/{shipping-Bu8p1gEw.js → shipping-B9YtnwtG.js} +2 -2
- package/public/assets/{stats-V9Z-GxUd.js → stats-DyUBKyWI.js} +2 -2
- package/public/assets/{status-dot-CVv0iGHL.js → status-dot-DYqlEUhJ.js} +2 -2
- package/public/assets/{store-BvtFdlGX.js → store-DcClXLH0.js} +3 -3
- package/public/assets/{tasks-CXU75HRF.js → tasks-Bh7Chr4-.js} +2 -2
- package/public/assets/{teams-BPf976zb.js → teams-bowI7qVY.js} +2 -2
- package/public/assets/{terminal-viewer-DE9BOe-8.js → terminal-viewer-BgVLHdsU.js} +3 -3
- package/public/assets/{terminal-viewer-impl-D04pjmGh.js → terminal-viewer-impl-Dz22UPy6.js} +2 -2
- package/public/assets/token-estimate-Co-Jdphh.js +2 -0
- package/public/assets/{use-agent-terminal-B1yR456R.js → use-agent-terminal-DSQQ-iY7.js} +2 -2
- package/public/assets/{use-decisions-D-S4tpDf.js → use-decisions-samMQhQf.js} +2 -2
- package/public/assets/use-project-list-59LheVP7.js +2 -0
- package/public/assets/{use-selectors-CnrAk2YP.js → use-selectors-BZa25xEB.js} +2 -2
- package/public/assets/{user-avatar-nBFIcR4M.js → user-avatar-DHxlvUvV.js} +2 -2
- package/public/assets/versioned-prompt-editor-BmED5DnJ.js +8 -0
- package/public/assets/{work-queue-TCjJxeT-.js → work-queue-CSvpuNLz.js} +2 -2
- package/public/assets/{workflow-marker-Cf3Hf2fN.js → workflow-marker-DAZcj5qt.js} +2 -2
- package/public/assets/{workflows-CXQX20Qj.js → workflows-DdmxRSyg.js} +2 -2
- package/public/assets/{workspaces-qSYzKYMA.js → workspaces-BxeKfVuF.js} +2 -2
- package/public/cosmos.html +4 -4
- package/public/index.html +31 -29
- package/runner/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/runner/plugins/claude/hooks/gate-run-guard.provisioned.mjs +31 -1
- package/runner/src/adapters/claude-effort.ts +2 -4
- package/runner/src/adapters/codex-launch-config.ts +4 -5
- package/runner/src/adapters/codex.ts +1 -1
- package/runner/src/adapters/opencode-provider.ts +7 -22
- package/runner/src/adapters/opencode.ts +4 -4
- package/runner/src/agent-runner/credentials.ts +42 -12
- package/runner/src/agent-runner/inbox.ts +27 -0
- package/runner/src/agent-runner/lifecycle-milestones.ts +0 -2
- package/runner/src/bin/claude.ts +4 -0
- package/runner/src/bin/codex.ts +4 -0
- package/runner/src/bin/opencode.ts +4 -0
- package/runner/src/index.ts +5 -2
- package/runner/src/provider-setup.ts +34 -0
- package/runner/src/providers.ts +2 -1
- package/runner/src/runner-core.ts +18 -23
- package/runner/src/spawn-input.ts +2 -1
- package/runner/src/test-run-dedup.ts +59 -56
- package/scripts/cd-config.ts +8 -0
- package/scripts/gate-run-lease.ts +10 -7
- package/scripts/gate.sh +5 -1
- package/src/branch-land-notice.ts +93 -0
- package/src/branch-landed.ts +7 -76
- package/src/bus.ts +19 -20
- package/src/cd-deploy-notify.ts +30 -2
- package/src/cd-host-lag-notify.ts +7 -6
- package/src/ci/incidents.ts +2 -2
- package/src/ci/monitor.ts +5 -8
- package/src/ci/root-missing.ts +2 -7
- package/src/ci/transition-notify.ts +7 -39
- package/src/cli/cd-pauses.ts +19 -0
- package/src/cli/orchestrator.ts +1 -1
- package/src/cli/state.ts +2 -19
- package/src/cli/task-edit.ts +22 -0
- package/src/cli/task.ts +3 -1
- package/src/cli/workflow.ts +8 -2
- package/src/commands-db.ts +3 -3
- package/src/config-store-write.ts +13 -1
- package/src/config-store.ts +25 -14
- package/src/db/activity-async.ts +6 -1
- package/src/db/activity-write-ops.ts +12 -1
- package/src/db/activity.ts +1 -14
- package/src/db/agent-search.ts +1 -15
- package/src/db/agents-async.ts +52 -5
- package/src/db/agents-write-ops.ts +12 -3
- package/src/db/agents.ts +81 -54
- package/src/db/ci-incidents-async.ts +5 -5
- package/src/db/ci-incidents-write-ops.ts +2 -2
- package/src/db/command-row.ts +10 -2
- package/src/db/commands-list-query.ts +2 -0
- package/src/db/commands-spawn-read.ts +1 -1
- package/src/db/config-store-write-ops.ts +7 -2
- package/src/db/continuation-archives-async.ts +5 -0
- package/src/db/continuation-archives-write-ops.ts +7 -0
- package/src/db/continuations.ts +2 -2
- package/src/db/db-writer-worker.ts +8 -1
- package/src/db/deploy-events-async.ts +1 -0
- package/src/db/deploy-events-read-ops.ts +2 -1
- package/src/db/deploy-events.ts +35 -4
- package/src/db/hosts-registration.ts +10 -2
- package/src/db/hosts.ts +9 -6
- package/src/db/inbox.ts +0 -14
- package/src/db/index.ts +2 -0
- package/src/db/integrations-async.ts +8 -0
- package/src/db/integrations-ops.ts +15 -0
- package/src/db/integrations.ts +15 -21
- package/src/db/issue-lifecycle.ts +3 -4
- package/src/db/issue-refs-async.ts +20 -0
- package/src/db/issue-refs-write-ops.ts +29 -0
- package/src/db/issue-refs.ts +7 -8
- package/src/db/long-running-work.ts +2 -2
- package/src/db/main-connection-writes.ts +23 -2
- package/src/db/maintenance-job-reconcile.ts +61 -0
- package/src/db/maintenance-job-runs-async.ts +14 -0
- package/src/db/maintenance-job-write-ops.ts +9 -0
- package/src/db/mappers.ts +2 -14
- package/src/db/merge-lease.ts +1 -15
- package/src/db/migrations.ts +7 -15
- package/src/db/orchestrators.ts +4 -72
- package/src/db/pairs.ts +1 -13
- package/src/db/project-profile-instructions.ts +50 -0
- package/src/db/prompt-versions.ts +9 -2
- package/src/db/provider-config-history.ts +8 -3
- package/src/db/provider-model-seed.ts +34 -0
- package/src/db/read-op-marshaling-fixtures.ts +5 -0
- package/src/db/read-ops.ts +4 -0
- package/src/db/routing-policy.ts +2 -3
- package/src/db/schema.ts +9 -3
- package/src/db/spawn-delegation-state.ts +11 -4
- package/src/db/stats-async.ts +4 -3
- package/src/db/task-entity.ts +23 -2
- package/src/db/task-list.ts +3 -1
- package/src/db/tasks.ts +1 -17
- package/src/db/timer-ingress.ts +7 -1
- package/src/db/token-db-write-ops.ts +17 -0
- package/src/db/token-standing.ts +15 -11
- package/src/db/workflow-contact.ts +1 -1
- package/src/db/workflow-task-read-ops.ts +30 -0
- package/src/db/write-ops.ts +6 -0
- package/src/db/writer-gateway.ts +17 -11
- package/src/dispatch-availability.ts +10 -6
- package/src/ephemeral/{landing-ingress-proof-worker.ts → landing-ingress-proof.test-fixture.ts} +4 -2
- package/src/host/disk-alert.ts +121 -0
- package/src/lifecycle-manager.ts +3 -2
- package/src/maintenance/cd-watcher.ts +3 -3
- package/src/maintenance/critical-job-watchdog.ts +16 -17
- package/src/maintenance/index.ts +1 -0
- package/src/maintenance/jobs.ts +3 -2
- package/src/maintenance/scheduler.ts +84 -128
- package/src/maintenance/stalled-delivery-pager.ts +6 -5
- package/src/maintenance/workspaces.ts +1 -1
- package/src/managed-policy.ts +31 -27
- package/src/mcp/index.ts +5 -2
- package/src/mcp/output-descriptions.ts +8 -8
- package/src/mcp/presentation.ts +4 -4
- package/src/mcp/project-profile-instructions.ts +32 -0
- package/src/mcp/tool-groups.ts +1 -1
- package/src/mcp/tools-spawn.ts +4 -3
- package/src/mcp-agent-action.ts +1 -2
- package/src/mcp-issue-ref-tools.ts +12 -11
- package/src/mcp-maintenance-tools.ts +2 -2
- package/src/mcp-profile-trust-tools.ts +4 -4
- package/src/mcp-provider-catalog.ts +2 -2
- package/src/mcp-task-tools.ts +11 -5
- package/src/mcp-team-template-tools.ts +3 -3
- package/src/mcp-workflow-tools.ts +10 -3
- package/src/notification-types.ts +2 -1
- package/src/operator-alarm.ts +26 -11
- package/src/project-instructions.ts +4 -0
- package/src/project-profile-instruction-text.ts +6 -0
- package/src/project-profile-instructions.ts +20 -0
- package/src/provider-catalog-store.ts +3 -49
- package/src/provider-config-store.ts +12 -11
- package/src/provider-model-seed.ts +1 -18
- package/src/provider-quota-config-store.ts +5 -4
- package/src/provider-secrets.test-fixture.ts +3 -3
- package/src/recipe-runner.ts +2 -2
- package/src/repo-config-source.ts +10 -4
- package/src/routes/agent-profiles.ts +6 -6
- package/src/routes/agents-spawn.ts +1 -1
- package/src/routes/agents.ts +6 -6
- package/src/routes/commands-listing.ts +4 -0
- package/src/routes/commands.ts +2 -2
- package/src/routes/continuation-archives.ts +2 -2
- package/src/routes/index.ts +10 -1
- package/src/routes/integrations.ts +24 -50
- package/src/routes/issue-refs.ts +7 -7
- package/src/routes/orchestrator-bootstrap.ts +1 -1
- package/src/routes/orchestrator-host-registration.ts +2 -2
- package/src/routes/orchestrator-host-utilization.ts +3 -1
- package/src/routes/orchestrator-proxy.ts +2 -2
- package/src/routes/orchestrator.ts +2 -2
- package/src/routes/project-profile-instructions.ts +27 -0
- package/src/routes/project-trust.ts +2 -2
- package/src/routes/provider-config.ts +6 -6
- package/src/routes/provider-quota-config.ts +2 -2
- package/src/routes/settings.ts +5 -5
- package/src/routes/stats.ts +6 -6
- package/src/routes/task-http.ts +15 -1
- package/src/routes/task-issues.ts +11 -26
- package/src/routes/tasks.ts +22 -53
- package/src/routes/team-templates.ts +5 -5
- package/src/routes/teams-config.ts +2 -2
- package/src/routes/tokens.ts +12 -5
- package/src/routes/workflows.ts +20 -5
- package/src/routing-policy-normalize.ts +1 -2
- package/src/routing-step-defaults.ts +0 -2
- package/src/runner-token-mint-limit.ts +63 -0
- package/src/runtime-grant.ts +4 -2
- package/src/runtime-tokens.ts +39 -7
- package/src/security.ts +13 -20
- package/src/server-background.ts +1 -1
- package/src/server.ts +5 -2
- package/src/services/host-utilization.ts +23 -0
- package/src/services/idle-epics.ts +5 -6
- package/src/services/issue-lifecycle.ts +57 -61
- package/src/services/issue-refs.ts +9 -13
- package/src/services/kernel-timers-cutover-chaos-worker.ts +10 -7
- package/src/services/kernel-timers-ingress.ts +1 -1
- package/src/services/landed-ancestry.ts +19 -3
- package/src/services/memory-areas.ts +15 -51
- package/src/services/plan-ci-notice.ts +57 -0
- package/src/services/plan-ci-recovery.ts +2 -55
- package/src/services/plan-wake-digest.ts +1 -0
- package/src/services/profile-trust.ts +4 -3
- package/src/services/project-config-read.ts +70 -0
- package/src/services/project-profile-instructions.ts +54 -0
- package/src/services/provisioning-harness/budget-baseline.json +4 -4
- package/src/services/restart-spawn.ts +61 -49
- package/src/services/self-care-state.ts +2 -1
- package/src/services/self-effort.ts +5 -5
- package/src/services/send-message.ts +5 -1
- package/src/services/spawn-agent.ts +13 -2
- package/src/services/spawn-chain-inspector.ts +6 -13
- package/src/services/spawn-policy.ts +68 -0
- package/src/services/spawn-tree-cleanup.ts +2 -2
- package/src/services/task-dispatch.ts +3 -0
- package/src/services/task-state-reconcile.ts +6 -14
- package/src/services/team-templates.ts +9 -8
- package/src/services/transient-agent-reaper.ts +3 -1
- package/src/services/workflow-auto-start.ts +25 -13
- package/src/services/workflow-ci-main.ts +1 -1
- package/src/services/workflow-deferred-cleanup.ts +4 -2
- package/src/services/workflow-effect-driver.ts +2 -0
- package/src/services/workflow-effects.ts +18 -11
- package/src/services/workflow-land-notice.ts +10 -0
- package/src/services/workflow-pause-text.ts +43 -0
- package/src/services/workflow-reconcile.ts +13 -11
- package/src/services/workflow-run-view.ts +2 -0
- package/src/services/workflow-runs.ts +29 -13
- package/src/services/workflow-supervisor-state.ts +5 -0
- package/src/services/workflow-supervisor.ts +7 -3
- package/src/settings/registry.ts +1 -2
- package/src/spawn-command.ts +4 -4
- package/src/spawn-models.ts +10 -12
- package/src/spawn-placement.ts +1 -1
- package/src/spawn-targets.ts +1 -1
- package/src/startup-context-injection.ts +1 -0
- package/src/state-adoption/cd-cutover.ts +53 -7
- package/src/state-adoption/fleet-cutover.ts +35 -0
- package/src/state-adoption/fleet-plan.ts +36 -0
- package/src/state-adoption/index.ts +2 -2
- package/src/state-adoption/linux-plan.ts +2 -2
- package/src/state-adoption/linux.ts +2 -2
- package/src/state-adoption/macos-plan.ts +2 -2
- package/src/state-adoption/macos.ts +1 -1
- package/src/steward.ts +7 -6
- package/src/task-dispatch-live.ts +1 -1
- package/src/task-dispatcher.ts +1 -1
- package/src/teams-config-store.ts +4 -3
- package/src/token-db-write.ts +10 -0
- package/src/workspace-command-settle.ts +2 -1
- package/src/workspace-steward-wake.ts +2 -2
- package/node_modules/@humwick/kernel/LICENSE +0 -167
- package/node_modules/@humwick/kernel/async-entity-persistence.ts +0 -344
- package/node_modules/@humwick/kernel/async-event-log.ts +0 -107
- package/node_modules/@humwick/kernel/automations.pilot.ts +0 -147
- package/node_modules/@humwick/kernel/config.ts +0 -111
- package/node_modules/@humwick/kernel/contract.ts +0 -572
- package/node_modules/@humwick/kernel/control-authz.ts +0 -281
- package/node_modules/@humwick/kernel/control.ts +0 -645
- package/node_modules/@humwick/kernel/effects.ts +0 -493
- package/node_modules/@humwick/kernel/event-log.ts +0 -319
- package/node_modules/@humwick/kernel/http-transport.ts +0 -384
- package/node_modules/@humwick/kernel/identity-grammar.ts +0 -20
- package/node_modules/@humwick/kernel/identity.ts +0 -248
- package/node_modules/@humwick/kernel/index.ts +0 -28
- package/node_modules/@humwick/kernel/kernel-persistence.ts +0 -181
- package/node_modules/@humwick/kernel/landing-incident.ts +0 -306
- package/node_modules/@humwick/kernel/landing.ts +0 -953
- package/node_modules/@humwick/kernel/manifest-validation.ts +0 -460
- package/node_modules/@humwick/kernel/mcp-transport.ts +0 -109
- package/node_modules/@humwick/kernel/message-authority-chaos-worker.ts +0 -200
- package/node_modules/@humwick/kernel/message-authority.ts +0 -281
- package/node_modules/@humwick/kernel/module-host.ts +0 -722
- package/node_modules/@humwick/kernel/openapi-init.ts +0 -14
- package/node_modules/@humwick/kernel/package.json +0 -39
- package/node_modules/@humwick/kernel/persistence-schema.ts +0 -248
- package/node_modules/@humwick/kernel/persistence.ts +0 -510
- package/node_modules/@humwick/kernel/registry.ts +0 -60
- package/node_modules/@humwick/kernel/sqlite-kernel-persistence.ts +0 -499
- package/node_modules/@humwick/kernel/sqlite-module-host.ts +0 -87
- package/node_modules/@humwick/kernel/timers-chaos-worker.ts +0 -186
- package/node_modules/@humwick/kernel/timers.pilot.ts +0 -1411
- package/node_modules/@humwick/kernel/workflow-activation.ts +0 -25
- package/node_modules/@humwick/kernel/workflow-backstop.ts +0 -40
- package/node_modules/@humwick/kernel/workflow-cancel-tree.ts +0 -20
- package/node_modules/@humwick/kernel/workflow-chaos-worker.ts +0 -213
- package/node_modules/@humwick/kernel/workflow-composition.ts +0 -231
- package/node_modules/@humwick/kernel/workflow-container.ts +0 -72
- package/node_modules/@humwick/kernel/workflow-control.test-fixture.ts +0 -42
- package/node_modules/@humwick/kernel/workflow-control.ts +0 -178
- package/node_modules/@humwick/kernel/workflow-definition.ts +0 -507
- package/node_modules/@humwick/kernel/workflow-dispatch.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-foreach.ts +0 -167
- package/node_modules/@humwick/kernel/workflow-journal-codec.ts +0 -339
- package/node_modules/@humwick/kernel/workflow-journal.ts +0 -922
- package/node_modules/@humwick/kernel/workflow-lane.ts +0 -48
- package/node_modules/@humwick/kernel/workflow-lease-owner.ts +0 -60
- package/node_modules/@humwick/kernel/workflow-recovery.test-fixture.ts +0 -19
- package/node_modules/@humwick/kernel/workflow-runtime.ts +0 -938
- package/node_modules/@humwick/kernel/workflow-script.ts +0 -11
- package/node_modules/@humwick/kernel/workflow-state.ts +0 -299
- package/node_modules/@humwick/kernel/workflow-step-commit.ts +0 -195
- package/node_modules/@humwick/kernel/workflow-transitions.ts +0 -317
- package/node_modules/@humwick/kernel/workflow-values.ts +0 -153
- package/node_modules/@humwick/kernel/workflow.pilot.ts +0 -376
- package/node_modules/@humwick/offload/LICENSE +0 -167
- package/node_modules/@humwick/offload/README.md +0 -57
- package/node_modules/@humwick/offload/dist/async-runner.d.ts +0 -18
- package/node_modules/@humwick/offload/dist/async-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/async-runner.js +0 -158
- package/node_modules/@humwick/offload/dist/async-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.d.ts +0 -25
- package/node_modules/@humwick/offload/dist/envelope.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/envelope.js +0 -80
- package/node_modules/@humwick/offload/dist/envelope.js.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts +0 -10
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js +0 -59
- package/node_modules/@humwick/offload/dist/fixtures/worker-task.js.map +0 -1
- package/node_modules/@humwick/offload/dist/index.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/index.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/index.js +0 -5
- package/node_modules/@humwick/offload/dist/index.js.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts +0 -62
- package/node_modules/@humwick/offload/dist/subprocess-runner.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/subprocess-runner.js +0 -295
- package/node_modules/@humwick/offload/dist/subprocess-runner.js.map +0 -1
- package/node_modules/@humwick/offload/dist/types.d.ts +0 -111
- package/node_modules/@humwick/offload/dist/types.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/types.js +0 -176
- package/node_modules/@humwick/offload/dist/types.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts +0 -23
- package/node_modules/@humwick/offload/dist/worker-pool.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-pool.js +0 -435
- package/node_modules/@humwick/offload/dist/worker-pool.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts +0 -2
- package/node_modules/@humwick/offload/dist/worker-runtime.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker-runtime.js +0 -27
- package/node_modules/@humwick/offload/dist/worker-runtime.js.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.d.ts +0 -5
- package/node_modules/@humwick/offload/dist/worker.d.ts.map +0 -1
- package/node_modules/@humwick/offload/dist/worker.js +0 -1
- package/node_modules/@humwick/offload/dist/worker.js.map +0 -1
- package/node_modules/@humwick/offload/package.json +0 -42
- package/node_modules/@humwick/offload/src/async-runner.ts +0 -170
- package/node_modules/@humwick/offload/src/envelope.ts +0 -92
- package/node_modules/@humwick/offload/src/fixtures/worker-task.ts +0 -49
- package/node_modules/@humwick/offload/src/index.ts +0 -4
- package/node_modules/@humwick/offload/src/subprocess-runner.ts +0 -334
- package/node_modules/@humwick/offload/src/types.ts +0 -235
- package/node_modules/@humwick/offload/src/worker-pool.ts +0 -463
- package/node_modules/@humwick/offload/src/worker-runtime.ts +0 -32
- package/node_modules/@humwick/offload/src/worker.ts +0 -5
- package/public/assets/agent-liveness-DyqxfB-t.js +0 -2
- package/public/assets/agent-profiles-BpI_jTxq.js +0 -2
- package/public/assets/index-B7ZerHLY.css +0 -2
- package/public/assets/index-BU3uWo2t.js +0 -15
- package/public/assets/projects-B_lmcqfO.js +0 -2
- package/public/assets/provider-display-DbLWpP3j.js +0 -2
- package/public/assets/run-card-CO_bguQf.js +0 -2
- package/public/assets/use-project-list-B-T2Bnnn.js +0 -2
- package/public/assets/versioned-prompt-editor-Diu8BIaM.js +0 -8
- package/runner/src/gate-run-lease-probe.ts +0 -38
- package/src/db/claude-catalog-reconcile.ts +0 -27
- package/src/routing-model-aliases.ts +0 -21
package/src/mcp/tools-spawn.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { workflowForBuilderSpawn } from "../services/workflow-auto-start";
|
|
|
16
16
|
import { optionalEnum } from "../validation";
|
|
17
17
|
import { cleanTaskDispatch } from "../db/task-entity";
|
|
18
18
|
import { DISPATCH_SHAPE_SCHEMA } from "./dispatch-shape-schema";
|
|
19
|
-
import { APPROVAL_MODES, AUTO_MERGE_POLICIES, LAUNCH_MODES, REPORT_VERBOSITIES, SPAWN_PROVIDERS, stringValue, VALID_AGENT_LIFECYCLES,
|
|
19
|
+
import { APPROVAL_MODES, AUTO_MERGE_POLICIES, LAUNCH_MODES, REPORT_VERBOSITIES, SPAWN_PROVIDERS, stringValue, VALID_AGENT_LIFECYCLES, VALID_WORKSPACE_MODES } from "@humwick/sdk";
|
|
20
20
|
import type { ProviderEffort } from "@humwick/sdk/provider-catalog";
|
|
21
21
|
import type { AgentCard, AgentLifecycle, Command, SpawnApprovalMode, SpawnProvider, WorkspaceAutoMergePolicy, WorkspaceLandingPolicy, WorkspaceLandMechanism, WorkspaceMode, WorkspaceRecord } from "../types";
|
|
22
22
|
import { projectMyAgent, projectSpawnTargets, type MyAgentFullPresentation, type PresentationVerbosity } from "./presentation";
|
|
@@ -43,7 +43,7 @@ export const SPAWN_TOOLS: ToolDefinition[] = [
|
|
|
43
43
|
env: { type: "object", additionalProperties: { type: "string" }, description: "Vault refs: secret:<name>." },
|
|
44
44
|
label: { type: "string" },
|
|
45
45
|
model: { type: "string" },
|
|
46
|
-
effort: {
|
|
46
|
+
effort: { type: "string" },
|
|
47
47
|
approvalMode: { enum: APPROVAL_MODES, description: "Use open; read-only blocks reports/tests; guarded waits for prompts." },
|
|
48
48
|
prompt: { type: "string" },
|
|
49
49
|
taskId: { oneOf: [{ type: "integer", minimum: 1 }, { type: "string" }], description: "Task id or TNNNN; loads its spec." },
|
|
@@ -70,7 +70,7 @@ export const SPAWN_TOOLS: ToolDefinition[] = [
|
|
|
70
70
|
hostPinned: { type: "boolean" },
|
|
71
71
|
landBlocked: { type: "boolean", description: "Permanent ban; for review use a Task hold." },
|
|
72
72
|
selfEffort: { type: "boolean" },
|
|
73
|
-
selfEffortCeiling: {
|
|
73
|
+
selfEffortCeiling: { type: "string" },
|
|
74
74
|
profile: { type: "string" },
|
|
75
75
|
role: { type: "string", description: "Default-branch project role; mutually exclusive with profile." },
|
|
76
76
|
tags: { type: "array", items: { type: "string" } },
|
|
@@ -229,6 +229,7 @@ export async function relaySpawnAgent(auth: McpAuthContext, args: Record<string,
|
|
|
229
229
|
...(result.taskId !== undefined ? { taskId: result.taskId } : {}),
|
|
230
230
|
...(result.task ? { task: result.task } : {}),
|
|
231
231
|
...(result.warnings ? { warnings: result.warnings } : {}),
|
|
232
|
+
...(result.spawnPolicy ? { spawnPolicy: result.spawnPolicy } : {}),
|
|
232
233
|
...(result.dispatchDecision ? { dispatchDecision: { target: result.dispatchDecision.target, rationale: result.dispatchDecision.rationale, warnings: result.dispatchDecision.warnings } } : {}),
|
|
233
234
|
...(workflow.reason ? { workflow: { started: false, reason: workflow.reason } } : {}),
|
|
234
235
|
};
|
package/src/mcp-agent-action.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { REPORT_VERBOSITIES } from "@humwick/sdk";
|
|
2
2
|
import { setAgentReportVerbosity } from "./services/agent-reporting";
|
|
3
3
|
import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
|
|
4
|
-
import { VALID_EFFORTS } from "@humwick/sdk/provider-catalog";
|
|
5
4
|
import { cleanEnum, cleanString } from "./validation";
|
|
6
5
|
import { AgentActionTargetError, dispatchAgentAction, type AgentAction } from "./services/agent-action";
|
|
7
6
|
import { authContextFromMcp } from "./services/auth-context";
|
|
@@ -37,7 +36,7 @@ export const SET_EFFORT_TOOL = {
|
|
|
37
36
|
inputSchema: {
|
|
38
37
|
type: "object",
|
|
39
38
|
properties: {
|
|
40
|
-
effort: { type: "string"
|
|
39
|
+
effort: { type: "string" },
|
|
41
40
|
reason: { type: "string" },
|
|
42
41
|
requestId: { type: "string" },
|
|
43
42
|
},
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getIssueRef, getIssueRefByExternalKey, issueRefClosedCompleted, issueRefForRefString, listIssueRefs } from "./db/issue-refs";
|
|
2
|
+
import { deleteIssueRefAsync, resolveIssueRefByExternalKeyAsync, resolveIssueRefFromStringAsync, updateIssueRefAsync, upsertIssueRefAsync } from "./db/issue-refs-async";
|
|
2
3
|
import { McpNotFoundError } from "./mcp-errors";
|
|
3
4
|
import { cleanEnum, cleanString, optionalEnum } from "./validation";
|
|
4
5
|
import { ISSUE_REF_CLOSE_REASONS, ISSUE_PROVIDERS, ISSUE_REF_STATUSES, isRecord, type IssueProvider, type IssueRef, type IssueRefCloseReason, type IssueRefStatus } from "./types";
|
|
5
6
|
import { ValidationError } from "./db";
|
|
6
|
-
import {
|
|
7
|
+
import { advanceTerminalPlanRefsAsync } from "./services/plan-terminal-refs";
|
|
7
8
|
|
|
8
9
|
export const ISSUE_REF_TOOLS = [
|
|
9
10
|
{
|
|
@@ -126,11 +127,11 @@ function currentRefFor(args: Record<string, unknown>) {
|
|
|
126
127
|
return null;
|
|
127
128
|
}
|
|
128
129
|
|
|
129
|
-
export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: Record<string, unknown>): Record<string, unknown
|
|
130
|
+
export async function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: Record<string, unknown>): Promise<Record<string, unknown>> {
|
|
130
131
|
if (!isRecord(args)) throw new ValidationError("arguments must be an object");
|
|
131
132
|
if (name === "relay_issue_ref_upsert") {
|
|
132
133
|
const before = currentRefFor(args);
|
|
133
|
-
const issueRef =
|
|
134
|
+
const issueRef = await upsertIssueRefAsync({
|
|
134
135
|
provider: providerArg(args.provider),
|
|
135
136
|
repo: cleanString(args.repo, "repo", { required: true, max: 500 })!,
|
|
136
137
|
externalKey: cleanString(args.externalKey, "externalKey", { required: true, max: 240 })!,
|
|
@@ -141,7 +142,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
|
|
|
141
142
|
statusSyncedAt: timestampArg(args.statusSyncedAt),
|
|
142
143
|
});
|
|
143
144
|
// #2520 — the cached ref flipped to a completed close: propagate to bound plan nodes.
|
|
144
|
-
if (issueRefClosedCompleted(before, issueRef))
|
|
145
|
+
if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
|
|
145
146
|
return issueRef as unknown as Record<string, unknown>;
|
|
146
147
|
}
|
|
147
148
|
if (name === "relay_issue_ref_resolve") {
|
|
@@ -153,7 +154,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
|
|
|
153
154
|
? issueRefForRefString(ref, cleanString(args.defaultRepo ?? args.repo, "defaultRepo", { max: 500 }))
|
|
154
155
|
: currentRefFor(args);
|
|
155
156
|
const issueRef = (ref
|
|
156
|
-
?
|
|
157
|
+
? await resolveIssueRefFromStringAsync({
|
|
157
158
|
ref,
|
|
158
159
|
defaultRepo: cleanString(args.defaultRepo ?? args.repo, "defaultRepo", { max: 500 }),
|
|
159
160
|
provider: optionalEnum(args.provider, "provider", ISSUE_PROVIDERS, "github") as IssueProvider,
|
|
@@ -162,7 +163,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
|
|
|
162
163
|
closeReason: closeReasonArg(args.closeReason),
|
|
163
164
|
statusSyncedAt: timestampArg(args.statusSyncedAt),
|
|
164
165
|
})
|
|
165
|
-
:
|
|
166
|
+
: await resolveIssueRefByExternalKeyAsync({
|
|
166
167
|
provider: providerArg(args.provider),
|
|
167
168
|
repo: cleanString(args.repo, "repo", { required: true, max: 500 })!,
|
|
168
169
|
externalKey: cleanString(args.externalKey, "externalKey", { required: true, max: 240 })!,
|
|
@@ -172,7 +173,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
|
|
|
172
173
|
closeReason: closeReasonArg(args.closeReason),
|
|
173
174
|
statusSyncedAt: timestampArg(args.statusSyncedAt),
|
|
174
175
|
})) as unknown as IssueRef;
|
|
175
|
-
if (issueRefClosedCompleted(before, issueRef))
|
|
176
|
+
if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
|
|
176
177
|
return issueRef as unknown as Record<string, unknown>;
|
|
177
178
|
}
|
|
178
179
|
if (name === "relay_issue_ref_get") {
|
|
@@ -192,7 +193,7 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
|
|
|
192
193
|
}
|
|
193
194
|
if (name === "relay_issue_ref_update") {
|
|
194
195
|
const before = currentRefFor(args);
|
|
195
|
-
const issueRef =
|
|
196
|
+
const issueRef = await updateIssueRefAsync(cleanString(args.id, "id", { required: true, max: 120 })!, {
|
|
196
197
|
url: cleanString(args.url, "url", { max: 2000 }),
|
|
197
198
|
title: cleanString(args.title, "title", { max: 500 }),
|
|
198
199
|
status: statusArg(args.status),
|
|
@@ -201,11 +202,11 @@ export function relayIssueRefTool(_auth: IssueRefToolAuth, name: string, args: R
|
|
|
201
202
|
});
|
|
202
203
|
if (!issueRef) throw new McpNotFoundError("issue ref not found");
|
|
203
204
|
// #2520 — the cached ref flipped to a completed close: propagate to bound plan nodes.
|
|
204
|
-
if (issueRefClosedCompleted(before, issueRef))
|
|
205
|
+
if (issueRefClosedCompleted(before, issueRef)) await advanceTerminalPlanRefsAsync({ issueRefId: issueRef.id, actor: _auth.actor });
|
|
205
206
|
return { issueRef };
|
|
206
207
|
}
|
|
207
208
|
if (name === "relay_issue_ref_delete") {
|
|
208
|
-
const deleted =
|
|
209
|
+
const deleted = await deleteIssueRefAsync(cleanString(args.id, "id", { required: true, max: 120 })!);
|
|
209
210
|
if (!deleted) throw new McpNotFoundError("issue ref not found");
|
|
210
211
|
return { deleted };
|
|
211
212
|
}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import { ValidationError } from "./db";
|
|
13
13
|
import { McpNotFoundError } from "./mcp-errors";
|
|
14
|
-
import {
|
|
14
|
+
import { listMaintenanceJobsAsync } from "./maintenance";
|
|
15
15
|
import { listPauses, pauseJob, resumeJobAsync } from "./maintenance/pauses";
|
|
16
16
|
import { authContextFromMcp } from "./services/auth-context";
|
|
17
17
|
import { cleanString } from "./validation";
|
|
@@ -72,7 +72,7 @@ export async function relayMaintenanceTool(auth: McpAuthLike, name: string, args
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
if (name === "relay_maintenance_jobs") {
|
|
75
|
-
const jobs =
|
|
75
|
+
const jobs = await listMaintenanceJobsAsync();
|
|
76
76
|
const jobId = cleanString(args.jobId, "jobId", { max: 120 });
|
|
77
77
|
if (!jobId) return { jobs, count: jobs.length };
|
|
78
78
|
const job = jobs.find(candidate => candidate.id === jobId);
|
|
@@ -3,7 +3,7 @@ import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
|
|
|
3
3
|
import { ValidationError } from "./db";
|
|
4
4
|
import { callerAgentId } from "./mcp/identity";
|
|
5
5
|
import { optionalEnum } from "./validation";
|
|
6
|
-
import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES,
|
|
6
|
+
import { approveProfileProjectTrust, PROJECT_REVIEW_MODES, PROJECT_TRUST_CAPABILITIES, updateProfileProjectTrustAsync } from "./services/profile-trust";
|
|
7
7
|
import type { McpAuthContext, ToolDefinition } from "./mcp/types";
|
|
8
8
|
|
|
9
9
|
export const PROFILE_TRUST_TOOL: ToolDefinition = {
|
|
@@ -31,17 +31,17 @@ function text(args: Record<string, unknown>, field: string): string {
|
|
|
31
31
|
return value.trim();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
export function relayProfileTrust(auth: McpAuthContext, args: Record<string, unknown>): unknown {
|
|
34
|
+
export async function relayProfileTrust(auth: McpAuthContext, args: Record<string, unknown>): Promise<unknown> {
|
|
35
35
|
const name = text(args, "profile");
|
|
36
36
|
const by = callerAgentId(auth) ?? auth.actor;
|
|
37
37
|
if (args.action === "set-review") {
|
|
38
38
|
const review = optionalEnum(args.review, "review", PROJECT_REVIEW_MODES);
|
|
39
39
|
if (!review) throw new ValidationError("review is required");
|
|
40
|
-
return { trust:
|
|
40
|
+
return { trust: (await updateProfileProjectTrustAsync(name, { review }, by)).value.sources?.project?.trust };
|
|
41
41
|
}
|
|
42
42
|
const capability = optionalEnum(args.capability, "capability", PROJECT_TRUST_CAPABILITIES);
|
|
43
43
|
if (!capability) throw new ValidationError("capability is required");
|
|
44
|
-
if (args.action === "ack") return { ack:
|
|
44
|
+
if (args.action === "ack") return { ack: (await updateProfileProjectTrustAsync(name, { ack: [capability] }, by)).value.sources?.project?.[capability]?.ack };
|
|
45
45
|
if (args.action === "approve") return { approval: approveProfileProjectTrust({ name, capability, repoKey: text(args, "repoKey"), value: text(args, "value"), by }) };
|
|
46
46
|
throw new ValidationError("action must be set-review, ack or approve");
|
|
47
47
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isRecord } from "@humwick/sdk";
|
|
2
2
|
import { effectiveProviderEffortLevelsAsync } from "./db";
|
|
3
3
|
|
|
4
4
|
export async function providerCatalogToolInputSchema(name: string, inputSchema: Record<string, unknown>): Promise<Record<string, unknown>> {
|
|
5
5
|
if (name !== "relay_spawn_agent") return inputSchema;
|
|
6
6
|
const efforts = await effectiveProviderEffortLevelsAsync();
|
|
7
7
|
const properties = isRecord(inputSchema.properties) ? inputSchema.properties : {};
|
|
8
|
-
return { ...inputSchema, properties: { ...properties, effort: { type: "string", enum: efforts
|
|
8
|
+
return { ...inputSchema, properties: { ...properties, effort: { type: "string", enum: efforts }, selfEffortCeiling: { type: "string", enum: efforts } } };
|
|
9
9
|
}
|
package/src/mcp-task-tools.ts
CHANGED
|
@@ -74,7 +74,7 @@ const TASK_ID_PROP = { oneOf: [{ type: "integer", minimum: 1 }, { type: "string"
|
|
|
74
74
|
export const TASK_TOOLS = [
|
|
75
75
|
{
|
|
76
76
|
name: "relay_task_create",
|
|
77
|
-
description: "Create
|
|
77
|
+
description: "Create Task; fromIssue imports GitHub content; explicit fields win.",
|
|
78
78
|
requiredScopes: ["task:write"],
|
|
79
79
|
inputSchema: {
|
|
80
80
|
type: "object",
|
|
@@ -84,9 +84,11 @@ export const TASK_TOOLS = [
|
|
|
84
84
|
intent: { type: "string" },
|
|
85
85
|
fromIssue: { type: "string", description: "GitHub URL or owner/repo#number. Fetch once before atomic create." },
|
|
86
86
|
tags: { type: "array", items: { type: "string" } },
|
|
87
|
+
paths: { type: "array", items: { type: "string" } },
|
|
87
88
|
complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES },
|
|
88
89
|
context: { type: "string" },
|
|
89
|
-
terminalStage: {
|
|
90
|
+
terminalStage: { enum: TASK_TERMINAL_STAGES },
|
|
91
|
+
onDeploy: { type: "string" },
|
|
90
92
|
doneWhen: { type: "string" },
|
|
91
93
|
teamId: { type: "string" },
|
|
92
94
|
projectId: { type: "string" },
|
|
@@ -108,8 +110,8 @@ export const TASK_TOOLS = [
|
|
|
108
110
|
},
|
|
109
111
|
},
|
|
110
112
|
{ name: "relay_task_get", description: "Read a lean Task hydration; verbose:true includes full intent, gates and history projections.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, verbose: { type: "boolean" } }, required: ["taskId"], additionalProperties: false } },
|
|
111
|
-
{ name: "relay_task_list", description: "List your Tasks by default; mine:false lists all. mode:brief is id/label/status; lean is default.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { status: {
|
|
112
|
-
{ name: "relay_task_update", description: "Update Task intent, steer, criteria or dispatch.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, refreshIssue: { type: "object", description: "
|
|
113
|
+
{ name: "relay_task_list", description: "List your Tasks by default; mine:false lists all. mode:brief is id/label/status; lean is default.", requiredScopes: ["task:read"], inputSchema: { type: "object", properties: { status: { enum: DELIVERABLE_STATUS_ENUM }, deliverableStage: { enum: [...TASK_DELIVERABLE_STAGES, "awaiting-deploy"] }, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, mine: { type: "boolean" }, inFlight: { type: "boolean" }, staleOwnerGone: { type: "boolean" }, limit: { type: "integer", minimum: 1, maximum: 500 }, mode: { type: "string", enum: ["brief", "lean", "full"] }, verbose: { type: "boolean" } }, additionalProperties: false } },
|
|
114
|
+
{ name: "relay_task_update", description: "Update Task intent, steer, criteria or dispatch.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, refreshIssue: { type: "object", description: "{expectedRevision, resolutions?: {title|intent|doneWhen|tags: source|local}}." }, verbose: { type: "boolean" }, title: { type: "string" }, label: { type: "string" }, intent: { type: "string" }, complexity: { type: "string", enum: TASK_DISPATCH_COMPLEXITIES }, context: { type: "string" }, latestSteer: { type: "string" }, onDeploy: { type: "string" }, doneWhen: { type: "string" }, terminalStage: { enum: [...TASK_TERMINAL_STAGES, null] }, dispatch: DISPATCH_SHAPE_SCHEMA, teamId: { type: "string" }, projectId: { type: "string" }, repo: { type: "string" }, paths: { type: "array", items: { type: "string" } } }, required: ["taskId"], additionalProperties: false } },
|
|
113
115
|
{ name: "relay_task_set_status", description: "Transition Task execution status. done requires met validation; force requires explicit override authority.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, status: { type: "string", enum: DELIVERABLE_STATUS_ENUM }, force: { type: "boolean" }, blockedBy: { type: "array", items: BLOCKER_SCHEMA }, note: { type: "string" }, verbose: { type: "boolean" } }, required: ["taskId", "status"], additionalProperties: false } },
|
|
114
116
|
{ name: "relay_task_set_stage", description: "Set Task delivery stage/branch/commit; normally maintained by the land/deploy pipeline.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, deliverableStage: { type: "string", enum: TASK_DELIVERABLE_STAGES }, branch: { type: "string" }, commit: COMMIT_SCHEMA }, required: ["taskId", "deliverableStage"], additionalProperties: false } },
|
|
115
117
|
{ name: "relay_task_confirm_carry", description: "Confirm a protected-tip revert's delivered change was carried to current main; clears only carry-pending.", requiredScopes: ["task:write"], inputSchema: { type: "object", properties: { taskId: TASK_ID_PROP, commit: COMMIT_SCHEMA, branch: { type: "string" }, note: { type: "string" } }, required: ["taskId"], additionalProperties: false } },
|
|
@@ -175,6 +177,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
|
|
|
175
177
|
complexity: optionalEnum(args.complexity, "complexity", TASK_DISPATCH_COMPLEXITIES),
|
|
176
178
|
context: cleanString(args.context, "context", { max: 1_000_000 }),
|
|
177
179
|
terminalStage: optionalEnum(args.terminalStage, "terminalStage", TASK_TERMINAL_STAGES),
|
|
180
|
+
onDeploy: cleanString(args.onDeploy, "onDeploy", { max: 500 }),
|
|
178
181
|
doneWhen: cleanString(args.doneWhen, "doneWhen", { max: 1_000_000 }),
|
|
179
182
|
teamId: cleanString(args.teamId, "teamId", { max: 200 }),
|
|
180
183
|
projectId: cleanString(args.projectId, "projectId", { max: 120 }),
|
|
@@ -182,6 +185,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
|
|
|
182
185
|
branch: cleanString(args.branch, "branch", { max: 500 }),
|
|
183
186
|
dispatch: args.dispatch as TaskDispatch | undefined,
|
|
184
187
|
tags: args.tags as string[] | undefined,
|
|
188
|
+
paths: args.paths as string[] | undefined,
|
|
185
189
|
// Alias-tolerant (#2214): a ref passed as `refs`/`issues`/`externalKey`/… used to be dropped
|
|
186
190
|
// silently, leaving the Task's issues[] empty and its spawn brief without the linked spec.
|
|
187
191
|
issueRefs: issueRefsFromArgs(args),
|
|
@@ -218,7 +222,7 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
|
|
|
218
222
|
if (name === "relay_task_list") {
|
|
219
223
|
const tasks = await listTaskEntitySummariesAsync({
|
|
220
224
|
status: optionalEnum(args.status, "status", DELIVERABLE_STATUS_ENUM),
|
|
221
|
-
deliverableStage: optionalEnum(args.deliverableStage, "deliverableStage", TASK_DELIVERABLE_STAGES),
|
|
225
|
+
deliverableStage: optionalEnum(args.deliverableStage, "deliverableStage", [...TASK_DELIVERABLE_STAGES, "awaiting-deploy"] as const),
|
|
222
226
|
teamId: cleanString(args.teamId, "teamId", { max: 200 }),
|
|
223
227
|
projectId: cleanString(args.projectId, "projectId", { max: 120 }),
|
|
224
228
|
repo: cleanString(args.repo, "repo", { max: 500 }),
|
|
@@ -246,12 +250,14 @@ export async function relayTaskTool(auth: McpAuthLike, name: string, args: Recor
|
|
|
246
250
|
...(args.complexity !== undefined ? { complexity: optionalEnum(args.complexity, "complexity", TASK_DISPATCH_COMPLEXITIES) } : {}),
|
|
247
251
|
...(args.context !== undefined ? { context: cleanString(args.context, "context", { max: 1_000_000 }) ?? "" } : {}),
|
|
248
252
|
...(args.latestSteer !== undefined ? { latestSteer: cleanString(args.latestSteer, "latestSteer", { max: 1_000_000 }) ?? "" } : {}),
|
|
253
|
+
...(args.onDeploy !== undefined ? { onDeploy: cleanString(args.onDeploy, "onDeploy", { max: 500 }) ?? "" } : {}),
|
|
249
254
|
...(args.doneWhen !== undefined ? { doneWhen: cleanString(args.doneWhen, "doneWhen", { max: 1_000_000 }) ?? "" } : {}),
|
|
250
255
|
...(args.terminalStage !== undefined ? { terminalStage: args.terminalStage === null ? null : optionalEnum(args.terminalStage, "terminalStage", TASK_TERMINAL_STAGES) } : {}),
|
|
251
256
|
...(args.dispatch !== undefined ? { dispatch: args.dispatch as TaskDispatch } : {}),
|
|
252
257
|
...(args.teamId !== undefined ? { teamId: cleanString(args.teamId, "teamId", { max: 200 }) ?? "" } : {}),
|
|
253
258
|
...(args.projectId !== undefined ? { projectId: cleanString(args.projectId, "projectId", { max: 120 }) ?? "" } : {}),
|
|
254
259
|
...(args.repo !== undefined ? { repo: cleanString(args.repo, "repo", { max: 500 }) ?? "" } : {}),
|
|
260
|
+
...(args.paths !== undefined ? { paths: args.paths as string[] | null } : {}),
|
|
255
261
|
};
|
|
256
262
|
const task = await updateTaskEntityAsync(taskIdArg(args.taskId), { ...patch, actor });
|
|
257
263
|
if (args.verbose === true) return task as unknown as Record<string, unknown>;
|
|
@@ -2,7 +2,7 @@ import { INCLUDED_TOOL_SCOPE_NEEDS } from "./mcp/tool-groups";
|
|
|
2
2
|
import { APPROVAL_MODES, SPAWN_PROVIDERS, VALID_AGENT_LIFECYCLES, VALID_WORKSPACE_MODES } from "@humwick/sdk";
|
|
3
3
|
import { McpAuthError } from "./mcp-errors";
|
|
4
4
|
import { authContextFromMcp } from "./services/auth-context";
|
|
5
|
-
import {
|
|
5
|
+
import { deleteTeamTemplateAsync, getTeamTemplate, instantiateTeamTemplate, listTeamTemplates, saveTeamTemplateAsync } from "./services/team-templates";
|
|
6
6
|
import { summarizeSpawnCommandForCaller } from "./services/spawn-agent";
|
|
7
7
|
import { ValidationError } from "./db";
|
|
8
8
|
|
|
@@ -111,7 +111,7 @@ function slugArg(args: Record<string, unknown>): string {
|
|
|
111
111
|
export async function relayTeamTemplateTool(auth: McpAuthLike, name: string, args: Record<string, unknown>): Promise<Record<string, unknown>> {
|
|
112
112
|
if (name === "relay_team_template_save") {
|
|
113
113
|
requireScope(auth, "teams:write");
|
|
114
|
-
return
|
|
114
|
+
return await saveTeamTemplateAsync(args, auth.actor) as unknown as Record<string, unknown>;
|
|
115
115
|
}
|
|
116
116
|
if (name === "relay_team_template_list") return { templates: listTeamTemplates() };
|
|
117
117
|
if (name === "relay_team_template_get") {
|
|
@@ -121,7 +121,7 @@ export async function relayTeamTemplateTool(auth: McpAuthLike, name: string, arg
|
|
|
121
121
|
}
|
|
122
122
|
if (name === "relay_team_template_delete") {
|
|
123
123
|
requireScope(auth, "teams:write");
|
|
124
|
-
return { slug: slugArg(args), deleted:
|
|
124
|
+
return { slug: slugArg(args), deleted: await deleteTeamTemplateAsync(slugArg(args), auth.actor) };
|
|
125
125
|
}
|
|
126
126
|
if (name === "relay_team_spawn_from_template") {
|
|
127
127
|
requireScope(auth, "teams:write");
|
|
@@ -5,7 +5,7 @@ import { McpAuthError } from "./mcp-errors";
|
|
|
5
5
|
import { ValidationError } from "./db";
|
|
6
6
|
import { authContextFromMcp } from "./services/auth-context";
|
|
7
7
|
import { ServiceAuthError } from "./services/errors";
|
|
8
|
-
import { cancelWorkflowRun, getWorkflowRun, resumeWorkflowRun, startWorkflowRun } from "./services/workflow-runs";
|
|
8
|
+
import { cancelWorkflowRun, getWorkflowRun, pauseWorkflowRun, resumeWorkflowRun, startWorkflowRun } from "./services/workflow-runs";
|
|
9
9
|
import { parseWorkflowPins } from "./services/workflow-pins";
|
|
10
10
|
import { cleanString, taskIdField } from "./validation";
|
|
11
11
|
|
|
@@ -48,7 +48,7 @@ export const WORKFLOW_TOOLS = [
|
|
|
48
48
|
{
|
|
49
49
|
name: "relay_workflow_resume",
|
|
50
50
|
description:
|
|
51
|
-
"Resume or answer/escalate a decision.",
|
|
51
|
+
"Resume, pause/unpause, or answer/escalate a decision.",
|
|
52
52
|
requiredScopes: ["task:write"],
|
|
53
53
|
inputSchema: {
|
|
54
54
|
type: "object",
|
|
@@ -66,6 +66,7 @@ export const WORKFLOW_TOOLS = [
|
|
|
66
66
|
activationId: { type: "string" },
|
|
67
67
|
step: { type: "string" },
|
|
68
68
|
note: { type: "string" },
|
|
69
|
+
pause: { type: "boolean" },
|
|
69
70
|
pins: PINS_PROP,
|
|
70
71
|
},
|
|
71
72
|
required: ["runId"],
|
|
@@ -112,7 +113,7 @@ type McpAuthLike = Parameters<typeof authContextFromMcp>[0];
|
|
|
112
113
|
|
|
113
114
|
function mutationReceipt(full: Record<string, unknown>, verbose: unknown): Record<string, unknown> {
|
|
114
115
|
if (verbose === true) return full;
|
|
115
|
-
const fields = ["runId", "taskId", "workflow", "status", "step", "round", "callerAgentId", "budget", "existing", "resumed", "cancelled", "reason", "warnings"];
|
|
116
|
+
const fields = ["runId", "taskId", "workflow", "status", "step", "round", "callerAgentId", "budget", "existing", "resumed", "cancelled", "paused", "reason", "warnings"];
|
|
116
117
|
return Object.fromEntries(fields.filter(key => full[key] !== undefined).map(key => [key, full[key]]));
|
|
117
118
|
}
|
|
118
119
|
|
|
@@ -132,6 +133,12 @@ export async function relayWorkflowTool(auth: McpAuthLike, name: string, args: R
|
|
|
132
133
|
if (!runId) throw new ValidationError("runId is required");
|
|
133
134
|
const step = cleanString(args.step, "step", { max: 64 });
|
|
134
135
|
const note = cleanString(args.note, "note", { max: 8000 });
|
|
136
|
+
if (args.pause !== undefined) {
|
|
137
|
+
// #3757 — pause (note is the required reason) or unpause; nothing else rides along.
|
|
138
|
+
if (typeof args.pause !== "boolean") throw new ValidationError("pause must be a boolean");
|
|
139
|
+
if (step || args.pins !== undefined || args.decision !== undefined || args.activationId !== undefined) throw new ValidationError("pause takes only runId and, to pause, note as the reason");
|
|
140
|
+
return mutationReceipt(await pauseWorkflowRun({ runId, pause: args.pause, ...(note ? { reason: note } : {}) }, ctx), args.verbose);
|
|
141
|
+
}
|
|
135
142
|
const pins = parseWorkflowPins(args.pins);
|
|
136
143
|
return mutationReceipt(await resumeWorkflowRun({ runId, decision: parseWorkflowDecisionResponse(args.decision), activationId: cleanString(args.activationId, "activationId", { max: 2000 }), ...(step ? { step } : {}), ...(note ? { note } : {}), ...(pins ? { pins } : {}) }, ctx), args.verbose);
|
|
137
144
|
}
|
|
@@ -97,7 +97,8 @@ export type NotificationType =
|
|
|
97
97
|
| "ci.config_mismatch"
|
|
98
98
|
| "ci.root_missing"
|
|
99
99
|
// #1645 — a critical maintenance job is not running (disabled, held indefinitely, a lapsed pause
|
|
100
|
-
// nobody resumed, or simply silent past several of its own intervals).
|
|
100
|
+
// nobody resumed, or simply silent past several of its own intervals). Also carries host disk
|
|
101
|
+
// alerts (#3762) — a new type would grow three MCP tool schemas past their pinned budgets.
|
|
101
102
|
| "maintenance.degraded";
|
|
102
103
|
|
|
103
104
|
/**
|
package/src/operator-alarm.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createActivityEventWithResult } from "./db";
|
|
2
|
+
import { createActivityEventByClientIdAsync } from "./db/activity-async";
|
|
2
3
|
import { emitRelayEvent } from "./events";
|
|
3
4
|
|
|
4
5
|
export interface OperatorAlarmInput {
|
|
@@ -20,22 +21,36 @@ export interface OperatorAlarmInput {
|
|
|
20
21
|
// done. This raises a distinct `operator.alarm` relay event (dashboard banner) plus a
|
|
21
22
|
// persisted `operator`-kind activity event, so a relay with no reachable escalation target
|
|
22
23
|
// is observable instead of looping forever in the dark.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
const alarmEvent = (input: OperatorAlarmInput) => ({
|
|
25
|
+
clientId: input.clientId,
|
|
26
|
+
kind: "operator" as const,
|
|
27
|
+
title: input.subject,
|
|
28
|
+
body: input.detail,
|
|
29
|
+
icon: "ti-alert-octagon",
|
|
30
|
+
view: input.view ?? "orchestrators",
|
|
31
|
+
metadata: { source: input.source, operatorAlarm: true, ...(input.metadata ?? {}) },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
function emitAlarm(input: OperatorAlarmInput): void {
|
|
34
35
|
emitRelayEvent({
|
|
35
36
|
type: "operator.alarm",
|
|
36
37
|
source: input.source,
|
|
37
38
|
subject: input.subject,
|
|
38
39
|
data: { subject: input.subject, detail: input.detail, ...(input.metadata ?? {}) },
|
|
39
40
|
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function raiseOperatorAlarm(input: OperatorAlarmInput): boolean {
|
|
44
|
+
const { created } = createActivityEventWithResult(alarmEvent(input));
|
|
45
|
+
if (input.dedupeEvent && !created) return false;
|
|
46
|
+
emitAlarm(input);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Same as `raiseOperatorAlarm`, with the activity row written on the writer thread. */
|
|
51
|
+
export async function raiseOperatorAlarmAsync(input: OperatorAlarmInput): Promise<boolean> {
|
|
52
|
+
const { created } = await createActivityEventByClientIdAsync(alarmEvent(input));
|
|
53
|
+
if (input.dedupeEvent && !created) return false;
|
|
54
|
+
emitAlarm(input);
|
|
40
55
|
return true;
|
|
41
56
|
}
|
|
@@ -2,6 +2,7 @@ import { composeMemoryPreambleAsync } from "./memory-preamble-async";
|
|
|
2
2
|
import { composeHostAwareness } from "./host-awareness";
|
|
3
3
|
import { composeGuideIndex } from "./guides";
|
|
4
4
|
import { profileInstructionBlocks } from "./profile-instruction-blocks";
|
|
5
|
+
import { projectProfileInstructionBlock } from "./project-profile-instructions";
|
|
5
6
|
// Spawn-time instruction sources (#557) — the relay-owned composer that assembles what a spawned
|
|
6
7
|
// agent's systemPromptAppend says, from declared sources only, never from host CLAUDE.md.
|
|
7
8
|
//
|
|
@@ -283,6 +284,7 @@ export function composeSpawnInstructionsWithEvents(input: {
|
|
|
283
284
|
* host → project`, audience-filtered by `profile`). Absent → no memory block at all, so a
|
|
284
285
|
* caller that does not know the identity produces a byte-identical pre-#1565 spawn. */
|
|
285
286
|
memoryIdentity?: MemoryIdentity;
|
|
287
|
+
projectId?: string;
|
|
286
288
|
profile?: Pick<AgentProfile, "instructions" | "maxSpawnedAgents" | "hostAwareness" | "roleAssets"> & { name?: string; relay?: AgentProfile["relay"] };
|
|
287
289
|
spawnedBy?: string;
|
|
288
290
|
/** #3045 — a workflow step agent: its step reporting block replaces the spawned-child report-up. */
|
|
@@ -475,6 +477,8 @@ export function composeSpawnInstructionsWithEvents(input: {
|
|
|
475
477
|
const { system: profileSystem, append: profileAppend } = profileInstructionBlocks(input.profile, input.memoryIdentity?.provider);
|
|
476
478
|
if (profileSystem) appendBlocks.push(profileSystem);
|
|
477
479
|
appendBlocks.push(...profileAppend);
|
|
480
|
+
const projectProfile = projectProfileInstructionBlock(input.projectId ?? input.memoryIdentity?.projectId, input.profile?.name ?? input.memoryIdentity?.profile);
|
|
481
|
+
if (projectProfile) { appendBlocks.push(projectProfile.content); relayInjectionEvents.push(projectProfile.event); }
|
|
478
482
|
// After the profile, so the step rule is the last word over a charter's report-to-spawner text.
|
|
479
483
|
if (input.workflowRunId) {
|
|
480
484
|
const instruction = renderTemplate("spawn.reportup.workflow-step", { runId: input.workflowRunId });
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { assertNoControlBytes, ValidationError } from "@humwick/sdk";
|
|
2
|
+
|
|
3
|
+
export function validateProjectProfileInstructionText(value: unknown, source: string): asserts value is string {
|
|
4
|
+
if (typeof value !== "string" || value.length > 16_000) throw new ValidationError(`${source} must be a string up to 16000 characters`);
|
|
5
|
+
assertNoControlBytes(value, source);
|
|
6
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { errMessage } from "@humwick/sdk";
|
|
2
|
+
import { getProjectProfileInstructions } from "./db/project-profile-instructions";
|
|
3
|
+
import { validateProjectProfileInstructionText } from "./project-profile-instruction-text";
|
|
4
|
+
|
|
5
|
+
/** #3515 — one optional block at the charter seam, independent of project memory's switch. */
|
|
6
|
+
export function projectProfileInstructionBlock(projectId: string | undefined, profile: string | undefined) {
|
|
7
|
+
if (!projectId || !profile) return;
|
|
8
|
+
const source = `project ${projectId} profile ${profile} instructions`;
|
|
9
|
+
try {
|
|
10
|
+
const entry = getProjectProfileInstructions({ projectId, profile });
|
|
11
|
+
validateProjectProfileInstructionText(entry.template, source);
|
|
12
|
+
const content = entry.template.trim();
|
|
13
|
+
if (!content) return;
|
|
14
|
+
return { content, event: { category: "instructions" as const,
|
|
15
|
+
summary: `injected ${source} v${entry.version}`,
|
|
16
|
+
detail: { source: "project-profile-instructions", projectId, profile, version: entry.version, content } } };
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.warn(`[launch] skipped ${source}: ${errMessage(error)}`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deriveProviderDisabledState,
|
|
3
3
|
disabledProviderSet,
|
|
4
|
-
|
|
4
|
+
providerMetadataList,
|
|
5
5
|
type ProviderCatalogEntry,
|
|
6
6
|
type ProviderContextThreshold,
|
|
7
7
|
type ProviderEnablementSetting,
|
|
@@ -44,7 +44,7 @@ export interface ProviderModelOverrideInput {
|
|
|
44
44
|
|
|
45
45
|
function listProviderModelOverrides(): ProviderModelOverride[] {
|
|
46
46
|
const rows = getDb()
|
|
47
|
-
.query("SELECT * FROM provider_model_overrides ORDER BY provider ASC,
|
|
47
|
+
.query("SELECT * FROM provider_model_overrides ORDER BY provider ASC, rowid ASC")
|
|
48
48
|
.all() as ProviderModelOverrideRow[];
|
|
49
49
|
return rows.map(rowToOverride).filter((entry): entry is ProviderModelOverride => Boolean(entry));
|
|
50
50
|
}
|
|
@@ -120,7 +120,7 @@ export function setProviderDefaultModel(provider: SpawnProvider, alias: string,
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
export function effectiveProviderCatalogList(now = Date.now()): ProviderCatalogEntry[] {
|
|
123
|
-
const catalog = mergeProviderCatalog(
|
|
123
|
+
const catalog = mergeProviderCatalog(providerMetadataList(), listProviderModelOverrides());
|
|
124
124
|
const defaults = getDb().query("SELECT provider, alias FROM provider_model_defaults").all() as Array<{ provider: string; alias: string }>;
|
|
125
125
|
for (const { provider, alias } of defaults) {
|
|
126
126
|
const entry = catalog.find((item) => item.provider === provider);
|
|
@@ -215,9 +215,6 @@ function normalizeOverrideInput(input: ProviderModelOverrideInput): ProviderMode
|
|
|
215
215
|
if (limits) entry.limits = limits;
|
|
216
216
|
else delete entry.limits;
|
|
217
217
|
delete entry.disabled;
|
|
218
|
-
// #368 — unavailable is a static catalog fact (provider-side suspension), not an operator toggle;
|
|
219
|
-
// strip it from DB overrides so an admin can't accidentally clear a catalog-level suspension.
|
|
220
|
-
delete entry.unavailable;
|
|
221
218
|
// #2598 — `deleted` is a row-level tombstone column, never part of a stored entry blob.
|
|
222
219
|
delete (entry as unknown as Record<string, unknown>).deleted;
|
|
223
220
|
return {
|
|
@@ -288,49 +285,6 @@ function allowlistedLimitConfidence(value: unknown): ProviderModelLimitWindow["c
|
|
|
288
285
|
: "declared";
|
|
289
286
|
}
|
|
290
287
|
|
|
291
|
-
/**
|
|
292
|
-
* #2598 — additive, idempotent backfill of every static-catalog model into `provider_model_overrides`,
|
|
293
|
-
* so the whole catalogue is uniformly DB-backed and operator-editable. Rules:
|
|
294
|
-
* - INSERT-ONLY-IF-ABSENT (`ON CONFLICT DO NOTHING`): an existing row — a prior seed OR an operator
|
|
295
|
-
* edit OR an operator delete-tombstone — is never touched, so operator edits ALWAYS win and a
|
|
296
|
-
* deleted static model is never resurrected. Re-runnable; a re-run inserts only genuinely NEW
|
|
297
|
-
* static models (e.g. added by a later release).
|
|
298
|
-
* - SKIP disabled/unavailable static models: materializing them would strip those flags at the
|
|
299
|
-
* write chokepoint (#368/#643) and resurrect a suspended model as spawnable. They stay
|
|
300
|
-
* static-only until an operator explicitly adds them.
|
|
301
|
-
* Stamped `updated_by = <stamp>` (e.g. `seed:<version>`) purely for provenance; precedence is decided
|
|
302
|
-
* by row EXISTENCE, not by parsing the stamp.
|
|
303
|
-
*/
|
|
304
|
-
export function seedProviderModelOverrides(stamp: string, now = Date.now()): { inserted: number } {
|
|
305
|
-
const db = getDb();
|
|
306
|
-
const existing = new Map<string, Set<string>>();
|
|
307
|
-
for (const row of db.query("SELECT provider, alias FROM provider_model_overrides").all() as Array<{ provider: string; alias: string }>) {
|
|
308
|
-
let aliases = existing.get(row.provider);
|
|
309
|
-
if (!aliases) existing.set(row.provider, (aliases = new Set()));
|
|
310
|
-
aliases.add(row.alias);
|
|
311
|
-
}
|
|
312
|
-
let inserted = 0;
|
|
313
|
-
const insert = db.query(`
|
|
314
|
-
INSERT INTO provider_model_overrides (provider, alias, entry, deleted, disabled, updated_at, updated_by)
|
|
315
|
-
VALUES (?, ?, ?, 0, 0, ?, ?)
|
|
316
|
-
ON CONFLICT(provider, alias) DO NOTHING
|
|
317
|
-
`);
|
|
318
|
-
const seed = db.transaction(() => {
|
|
319
|
-
for (const providerEntry of providerCatalogList()) {
|
|
320
|
-
const seen = existing.get(providerEntry.provider);
|
|
321
|
-
for (const model of providerEntry.models) {
|
|
322
|
-
if (model.disabled || model.unavailable) continue;
|
|
323
|
-
if (seen?.has(model.alias)) continue;
|
|
324
|
-
const normalized = normalizeOverrideInput({ provider: providerEntry.provider, alias: model.alias, entry: model, updatedBy: stamp });
|
|
325
|
-
const result = insert.run(normalized.provider, normalized.alias, JSON.stringify(normalized.entry), now, normalized.updatedBy ?? null);
|
|
326
|
-
if (result.changes > 0) inserted++;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
});
|
|
330
|
-
seed();
|
|
331
|
-
return { inserted };
|
|
332
|
-
}
|
|
333
|
-
|
|
334
288
|
function rowToOverride(row: ProviderModelOverrideRow): ProviderModelOverride | undefined {
|
|
335
289
|
const parsed = parseJson<ProviderModelCatalogEntry | undefined>(row.entry, undefined);
|
|
336
290
|
if (!parsed || typeof parsed.alias !== "string") return undefined;
|