@tekmidian/pai 0.42.4 → 0.42.6
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/ARCHITECTURE.md +9 -9
- package/README.md +26 -8
- package/dist/{aibroker-client-BP74gGwD.mjs → aibroker-client-Bn9SnGMa.mjs} +3 -3
- package/dist/{aibroker-client-BP74gGwD.mjs.map → aibroker-client-Bn9SnGMa.mjs.map} +1 -1
- package/dist/{aibroker-client-C6m71p6O.mjs → aibroker-client-D5NT0S1N.mjs} +1 -1
- package/dist/{auto-route-_5zzJz5q.mjs → auto-route-CcD0OWWB.mjs} +4 -4
- package/dist/{auto-route-_5zzJz5q.mjs.map → auto-route-CcD0OWWB.mjs.map} +1 -1
- package/dist/{chain-DTII7xeL.mjs → chain-BbcfP77K.mjs} +5 -4
- package/dist/{chain-DTII7xeL.mjs.map → chain-BbcfP77K.mjs.map} +1 -1
- package/dist/cli/index.mjs +23 -21
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/program.d.mts.map +1 -1
- package/dist/cli/program.mjs +23 -21
- package/dist/{clusters-j0ZuNYp9.mjs → clusters-Cw_P6lO-.mjs} +2 -2
- package/dist/{clusters-j0ZuNYp9.mjs.map → clusters-Cw_P6lO-.mjs.map} +1 -1
- package/dist/{config-B64vFg14.mjs → config-DCu8THKi.mjs} +41 -9
- package/dist/{config-B64vFg14.mjs.map → config-DCu8THKi.mjs.map} +1 -1
- package/dist/config-DeqFqa1N.mjs +3 -0
- package/dist/config-DxMZjpvY.mjs +1289 -0
- package/dist/config-DxMZjpvY.mjs.map +1 -0
- package/dist/context-handover-cache-B9NKSjwR.mjs +3242 -0
- package/dist/context-handover-cache-B9NKSjwR.mjs.map +1 -0
- package/dist/daemon/index.mjs +23 -22
- package/dist/daemon/index.mjs.map +1 -1
- package/dist/daemon-BNjbVsQU.mjs +24 -0
- package/dist/{daemon-B8N1egl0.mjs → daemon-BppziPi6.mjs} +52 -38
- package/dist/daemon-BppziPi6.mjs.map +1 -0
- package/dist/daemon-mcp/index.mjs +144 -117
- package/dist/daemon-mcp/index.mjs.map +1 -1
- package/dist/db-BOBfewFH.mjs +3 -0
- package/dist/{db-a1ixZQjr.mjs → db-DJ8rk0VM.mjs} +15 -6
- package/dist/{db-a1ixZQjr.mjs.map → db-DJ8rk0VM.mjs.map} +1 -1
- package/dist/db-DbY2O8QO.mjs +3 -0
- package/dist/{db-Ca5qfsMC.mjs → db-Ddns80yf.mjs} +15 -6
- package/dist/{db-Ca5qfsMC.mjs.map → db-Ddns80yf.mjs.map} +1 -1
- package/dist/{detect-CdaA48EI.mjs → detect-Bf2z-oKB.mjs} +1 -1
- package/dist/{detect-CdaA48EI.mjs.map → detect-Bf2z-oKB.mjs.map} +1 -1
- package/dist/detector-CkwkXuGh.mjs +5 -0
- package/dist/{detector-C73Nxm94.mjs → detector-DWXkeTlk.mjs} +2 -2
- package/dist/{detector-C73Nxm94.mjs.map → detector-DWXkeTlk.mjs.map} +1 -1
- package/dist/{embeddings-CEBGrzwu.mjs → embeddings-ClqKtLZ8.mjs} +1 -1
- package/dist/{embeddings-DOLZnT1X.mjs → embeddings-DvRKcQyt.mjs} +1 -1
- package/dist/{embeddings-DOLZnT1X.mjs.map → embeddings-DvRKcQyt.mjs.map} +1 -1
- package/dist/factory-47Qf_df7.mjs +3 -0
- package/dist/{factory-DEb9NmHJ.mjs → factory-DNYAqjH0.mjs} +8 -8
- package/dist/{factory-DEb9NmHJ.mjs.map → factory-DNYAqjH0.mjs.map} +1 -1
- package/dist/{fallback-oJl3BaIN.mjs → fallback-Cwt4hmh5.mjs} +182 -122
- package/dist/fallback-Cwt4hmh5.mjs.map +1 -0
- package/dist/{helpers-IjZkXBhj.mjs → helpers-crDEr6S2.mjs} +1 -1
- package/dist/{helpers-IjZkXBhj.mjs.map → helpers-crDEr6S2.mjs.map} +1 -1
- package/dist/hooks/capture-all-events.mjs +117 -34
- package/dist/hooks/capture-all-events.mjs.map +4 -4
- package/dist/hooks/capture-session-summary.mjs +110 -33
- package/dist/hooks/capture-session-summary.mjs.map +4 -4
- package/dist/hooks/capture-tool-output.mjs +105 -28
- package/dist/hooks/capture-tool-output.mjs.map +4 -4
- package/dist/hooks/cleanup-session-files.mjs +54 -13
- package/dist/hooks/cleanup-session-files.mjs.map +2 -2
- package/dist/hooks/context-compression-hook.mjs +7565 -122
- package/dist/hooks/context-compression-hook.mjs.map +4 -4
- package/dist/hooks/initialize-session.mjs +55 -14
- package/dist/hooks/initialize-session.mjs.map +2 -2
- package/dist/hooks/inject-observations.mjs +79 -18
- package/dist/hooks/inject-observations.mjs.map +3 -3
- package/dist/hooks/load-core-context.mjs +55 -14
- package/dist/hooks/load-core-context.mjs.map +2 -2
- package/dist/hooks/load-project-context.mjs +185 -103
- package/dist/hooks/load-project-context.mjs.map +4 -4
- package/dist/hooks/mcp-deferred-gate.mjs +54 -13
- package/dist/hooks/mcp-deferred-gate.mjs.map +2 -2
- package/dist/hooks/mcp-deferred-reminder.mjs +9 -0
- package/dist/hooks/mcp-deferred-reminder.mjs.map +3 -3
- package/dist/hooks/observe.mjs +54 -13
- package/dist/hooks/observe.mjs.map +2 -2
- package/dist/hooks/post-compact-inject.mjs +7419 -16
- package/dist/hooks/post-compact-inject.mjs.map +4 -4
- package/dist/hooks/route-agents-to-worker.mjs +7778 -171
- package/dist/hooks/route-agents-to-worker.mjs.map +4 -4
- package/dist/hooks/route-edits-to-worker.mjs +90 -0
- package/dist/hooks/route-edits-to-worker.mjs.map +7 -0
- package/dist/hooks/security-validator.mjs +147 -6
- package/dist/hooks/security-validator.mjs.map +4 -4
- package/dist/hooks/session-commands.mjs +9 -0
- package/dist/hooks/session-commands.mjs.map +3 -3
- package/dist/hooks/stop-hook.mjs +182 -105
- package/dist/hooks/stop-hook.mjs.map +4 -4
- package/dist/hooks/subagent-stop-hook.mjs +3 -0
- package/dist/hooks/subagent-stop-hook.mjs.map +1 -1
- package/dist/hooks/sync-todo-to-md.mjs +54 -13
- package/dist/hooks/sync-todo-to-md.mjs.map +2 -2
- package/dist/hooks/update-tab-on-action.mjs +3 -0
- package/dist/hooks/update-tab-on-action.mjs.map +1 -1
- package/dist/hooks/update-tab-titles.mjs +3 -0
- package/dist/hooks/update-tab-titles.mjs.map +1 -1
- package/dist/hooks/whisper-reinject.mjs +3 -0
- package/dist/hooks/whisper-reinject.mjs.map +1 -1
- package/dist/hooks/whisper-rules.mjs +134 -29
- package/dist/hooks/whisper-rules.mjs.map +4 -4
- package/dist/hooks/worker-proxy.mjs +7737 -117
- package/dist/hooks/worker-proxy.mjs.map +4 -4
- package/dist/hooks/worker-status-line.mjs +7791 -144
- package/dist/hooks/worker-status-line.mjs.map +4 -4
- package/dist/hooks/worker-supervision.mjs +7721 -115
- package/dist/hooks/worker-supervision.mjs.map +4 -4
- package/dist/index.d.mts +4 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +10 -10
- package/dist/{indexer-backend-BPTzKFZU.mjs → indexer-backend-CdvCJCkD.mjs} +3 -3
- package/dist/{indexer-backend-BPTzKFZU.mjs.map → indexer-backend-CdvCJCkD.mjs.map} +1 -1
- package/dist/{ipc-client-BmypMNYk.mjs → ipc-client-C6NryMMb.mjs} +2 -2
- package/dist/{ipc-client-BmypMNYk.mjs.map → ipc-client-C6NryMMb.mjs.map} +1 -1
- package/dist/{kg-entity-r8duqhi9.mjs → kg-entity-BSjM5xZh.mjs} +1 -1
- package/dist/{kg-entity-r8duqhi9.mjs.map → kg-entity-BSjM5xZh.mjs.map} +1 -1
- package/dist/{latent-ideas-CtSca4qG.mjs → latent-ideas-BfL4nCQ3.mjs} +4 -4
- package/dist/{latent-ideas-CtSca4qG.mjs.map → latent-ideas-BfL4nCQ3.mjs.map} +1 -1
- package/dist/{link-boost-Bucnz3n8.mjs → link-boost-C5PaNdzm.mjs} +1 -1
- package/dist/{link-boost-Bucnz3n8.mjs.map → link-boost-C5PaNdzm.mjs.map} +1 -1
- package/dist/main-resolver-CnfnWa8C.mjs +7 -0
- package/dist/{main-resolver-DnkxPYkr.mjs → main-resolver-DvYu9jbl.mjs} +21 -11
- package/dist/main-resolver-DvYu9jbl.mjs.map +1 -0
- package/dist/{migrate-Cjzeefn9.mjs → migrate-CfERwXhY.mjs} +2 -2
- package/dist/{migrate-Cjzeefn9.mjs.map → migrate-CfERwXhY.mjs.map} +1 -1
- package/dist/{neighborhood-CM7Jgb51.mjs → neighborhood-CETR_P4y.mjs} +2 -2
- package/dist/{neighborhood-CM7Jgb51.mjs.map → neighborhood-CETR_P4y.mjs.map} +1 -1
- package/dist/{note-context-DCwE2A-M.mjs → note-context-DCcRWBoN.mjs} +1 -1
- package/dist/{note-context-DCwE2A-M.mjs.map → note-context-DCcRWBoN.mjs.map} +1 -1
- package/dist/pai-home-ChAOupZc.mjs +164 -0
- package/dist/pai-home-ChAOupZc.mjs.map +1 -0
- package/dist/{pai-marker-CHtbJMwJ.mjs → pai-marker-B20KqhA8.mjs} +1 -1
- package/dist/{pai-marker-CHtbJMwJ.mjs.map → pai-marker-B20KqhA8.mjs.map} +1 -1
- package/dist/{planner-D5Ui7DAm.mjs → planner-pXRc-8yt.mjs} +7 -6
- package/dist/{planner-D5Ui7DAm.mjs.map → planner-pXRc-8yt.mjs.map} +1 -1
- package/dist/{postgres-CtOzfoQU.mjs → postgres-CUSXWgTG.mjs} +2 -2
- package/dist/{postgres-CtOzfoQU.mjs.map → postgres-CUSXWgTG.mjs.map} +1 -1
- package/dist/{program-zpoYnJGz.mjs → program-LLNPpxlj.mjs} +8308 -6065
- package/dist/program-LLNPpxlj.mjs.map +1 -0
- package/dist/query-feedback-C7rSfiXU.mjs +3 -0
- package/dist/{query-feedback-Dqz-HC__.mjs → query-feedback-CYyOGi3y.mjs} +20 -6
- package/dist/query-feedback-CYyOGi3y.mjs.map +1 -0
- package/dist/{reranker-CwTCNsgA.mjs → reranker-B5qUTamW.mjs} +1 -1
- package/dist/{reranker-xPm04PXx.mjs → reranker-HHmhZk6v.mjs} +1 -1
- package/dist/{reranker-xPm04PXx.mjs.map → reranker-HHmhZk6v.mjs.map} +1 -1
- package/dist/router-CremHKTI.mjs +3 -0
- package/dist/{router-DD6D4j31.mjs → router-DBAZfE7X.mjs} +2 -2
- package/dist/{router-DD6D4j31.mjs.map → router-DBAZfE7X.mjs.map} +1 -1
- package/dist/{run-D7K5UALn.mjs → run-DDdT9teG.mjs} +530 -210
- package/dist/run-DDdT9teG.mjs.map +1 -0
- package/dist/{runtime-paths-rni52zHX.mjs → runtime-paths-B0P1TvUr.mjs} +1 -1
- package/dist/{runtime-paths-rni52zHX.mjs.map → runtime-paths-B0P1TvUr.mjs.map} +1 -1
- package/dist/{search-Rpk1cSBC.mjs → search-B69cQwDB.mjs} +3 -3
- package/dist/{search-Rpk1cSBC.mjs.map → search-B69cQwDB.mjs.map} +1 -1
- package/dist/{search-CfPpJAWQ.mjs → search-fb-5ovj4.mjs} +2 -2
- package/dist/{server-D4vAieF4.mjs → server-Ch99xt5K.mjs} +15 -14
- package/dist/server-Ch99xt5K.mjs.map +1 -0
- package/dist/skills/Advisor/SKILL.md +3 -3
- package/dist/skills/Providers/SKILL.md +30 -0
- package/dist/skills/Reconstruct/SKILL.md +1 -1
- package/dist/skills/VaultContext/SKILL.md +1 -1
- package/dist/skills/Whisper/SKILL.md +3 -3
- package/dist/skills/Worker/SKILL.md +1 -1
- package/dist/{sources-CS43CpuS.mjs → sources-KBGEA_E6.mjs} +2 -2
- package/dist/{sources-CS43CpuS.mjs.map → sources-KBGEA_E6.mjs.map} +1 -1
- package/dist/{sqlite-Cq3gJcq9.mjs → sqlite-By6r2YhZ.mjs} +3 -3
- package/dist/{sqlite-Cq3gJcq9.mjs.map → sqlite-By6r2YhZ.mjs.map} +1 -1
- package/dist/{state-CY6I-Hnc.mjs → state-DnYGRmS7.mjs} +1 -1
- package/dist/{state-BRdB-Bf1.mjs → state-PJrgfDLW.mjs} +1 -1
- package/dist/{state-BRdB-Bf1.mjs.map → state-PJrgfDLW.mjs.map} +1 -1
- package/dist/{stop-words-Hfu8u22w.mjs → stop-words-BaMEGVeY.mjs} +1 -1
- package/dist/{stop-words-Hfu8u22w.mjs.map → stop-words-BaMEGVeY.mjs.map} +1 -1
- package/dist/{sync-BWbe8JTg.mjs → sync-Btcb6xA4.mjs} +3 -3
- package/dist/{sync-BWbe8JTg.mjs.map → sync-Btcb6xA4.mjs.map} +1 -1
- package/dist/{themes-B7h9YDiy.mjs → themes-BVoAnLZj.mjs} +3 -3
- package/dist/{themes-B7h9YDiy.mjs.map → themes-BVoAnLZj.mjs.map} +1 -1
- package/dist/{tools-BW3NLMPk.mjs → tools-BradfQk7.mjs} +4 -3
- package/dist/{tools-LlzcV_eK.mjs → tools-UrSHIe29.mjs} +30 -233
- package/dist/tools-UrSHIe29.mjs.map +1 -0
- package/dist/{trace-u4hT-pLD.mjs → trace-Cy8quQTm.mjs} +1 -1
- package/dist/{trace-u4hT-pLD.mjs.map → trace-Cy8quQTm.mjs.map} +1 -1
- package/dist/{utils-DhMex3Ox.mjs → utils-BD8g8oSf.mjs} +1 -1
- package/dist/{utils-9Err2RBW.mjs → utils-CJymHkYm.mjs} +1 -1
- package/dist/{utils-9Err2RBW.mjs.map → utils-CJymHkYm.mjs.map} +1 -1
- package/dist/{vault-indexer-mata9S7b.mjs → vault-indexer-C5i-OAyr.mjs} +2 -2
- package/dist/{vault-indexer-mata9S7b.mjs.map → vault-indexer-C5i-OAyr.mjs.map} +1 -1
- package/dist/wakeup-TnGjJY3I.mjs +218 -0
- package/dist/wakeup-TnGjJY3I.mjs.map +1 -0
- package/dist/work-queue-worker-BA5IDBwQ.mjs +567 -0
- package/dist/work-queue-worker-BA5IDBwQ.mjs.map +1 -0
- package/dist/work-queue-worker-DLM2wlqM.mjs +14 -0
- package/dist/{zettelkasten-F0D_XfQ4.mjs → zettelkasten-BBjA7GcP.mjs} +4 -4
- package/dist/{zettelkasten-F0D_XfQ4.mjs.map → zettelkasten-BBjA7GcP.mjs.map} +1 -1
- package/docs/commands/README.md +30 -3
- package/docs/commands/audit.md +88 -0
- package/docs/commands/backup.md +2 -2
- package/docs/commands/clear-names.md +1 -1
- package/docs/commands/config.md +59 -0
- package/docs/commands/daemon.md +1 -1
- package/docs/commands/db.md +1 -1
- package/docs/commands/end.md +1 -1
- package/docs/commands/help.md +1 -1
- package/docs/commands/identity.md +1 -1
- package/docs/commands/kg.md +1 -1
- package/docs/commands/launch.md +45 -0
- package/docs/commands/mcp.md +1 -1
- package/docs/commands/memory.md +3 -3
- package/docs/commands/notify.md +1 -1
- package/docs/commands/observation.md +1 -1
- package/docs/commands/obsidian.md +1 -1
- package/docs/commands/pause.md +1 -1
- package/docs/commands/project.md +46 -1
- package/docs/commands/projects.md +46 -1
- package/docs/commands/registry.md +1 -1
- package/docs/commands/restore.md +1 -1
- package/docs/commands/session.md +1 -1
- package/docs/commands/sessions.md +1 -1
- package/docs/commands/setup.md +1 -1
- package/docs/commands/shell-init.md +1 -1
- package/docs/commands/skill.md +1 -1
- package/docs/commands/task.md +1 -1
- package/docs/commands/topic.md +1 -1
- package/docs/commands/update.md +1 -1
- package/docs/commands/worker.md +95 -6
- package/docs/commands/zettel.md +1 -1
- package/docs/provider-abstraction.md +1 -1
- package/docs/provider-independence-details.md +8 -5
- package/docs/task-bus.md +1 -1
- package/docs/worker.md +136 -83
- package/docs/workers-config.md +446 -0
- package/package.json +4 -2
- package/scripts/build-hooks.mjs +56 -3
- package/src/hooks/pre-compact.sh +5 -2
- package/src/hooks/session-stop.sh +29 -4
- package/src/hooks/ts/capture-all-events.ts +3 -3
- package/src/hooks/ts/lib/advisor-budget.test.ts +98 -0
- package/src/hooks/ts/lib/advisor-budget.ts +90 -0
- package/src/hooks/ts/lib/agent-gate.test.ts +101 -0
- package/src/hooks/ts/lib/agent-gate.ts +112 -0
- package/src/hooks/ts/lib/context-fill.ts +2 -2
- package/src/hooks/ts/lib/edit-gate.test.ts +52 -0
- package/src/hooks/ts/lib/edit-gate.ts +51 -0
- package/src/hooks/ts/lib/mcp-deferred-reminder.test.ts +8 -0
- package/src/hooks/ts/lib/pai-paths.test.ts +93 -0
- package/src/hooks/ts/lib/pai-paths.ts +168 -24
- package/src/hooks/ts/lib/project-utils/index.ts +1 -0
- package/src/hooks/ts/lib/project-utils/paths.ts +5 -4
- package/src/hooks/ts/lib/project-utils.ts +1 -0
- package/src/hooks/ts/post-tool-use/capture-tool-output.ts +2 -2
- package/src/hooks/ts/pre-compact/context-compression-hook.ts +1 -1
- package/src/hooks/ts/pre-tool-use/route-agents-to-worker.ts +46 -99
- package/src/hooks/ts/pre-tool-use/route-edits-to-worker.test.ts +47 -0
- package/src/hooks/ts/pre-tool-use/route-edits-to-worker.ts +96 -0
- package/src/hooks/ts/pre-tool-use/security-validator.ts +2 -1
- package/src/hooks/ts/session-end/capture-session-summary.ts +4 -4
- package/src/hooks/ts/session-start/initialize-session.ts +3 -3
- package/src/hooks/ts/session-start/inject-observations.test.ts +56 -0
- package/src/hooks/ts/session-start/inject-observations.ts +28 -8
- package/src/hooks/ts/session-start/load-core-context.ts +4 -4
- package/src/hooks/ts/session-start/load-project-context.ts +2 -2
- package/src/hooks/ts/session-start/mcp-deferred-reminder.ts +2 -0
- package/src/hooks/ts/session-start/session-commands.ts +4 -0
- package/src/hooks/ts/session-start/session-start-worker-guard.test.ts +36 -0
- package/src/hooks/ts/stop/stop-hook.ts +6 -11
- package/src/hooks/ts/user-prompt/whisper-rules.test.ts +49 -0
- package/src/hooks/ts/user-prompt/whisper-rules.ts +88 -47
- package/statusline-command.sh +277 -116
- package/templates/agent-prefs.example.md +8 -8
- package/templates/claude-md.template.md +1 -1
- package/templates/voices.example.json +3 -3
- package/dist/config-C_ErGddD.mjs +0 -3
- package/dist/config-_lQI_W08.mjs +0 -640
- package/dist/config-_lQI_W08.mjs.map +0 -1
- package/dist/context-handover-cache-pNFdBNrU.mjs +0 -1548
- package/dist/context-handover-cache-pNFdBNrU.mjs.map +0 -1
- package/dist/daemon-B8N1egl0.mjs.map +0 -1
- package/dist/daemon-DHfyoTlk.mjs +0 -23
- package/dist/db-O-cyAPfS.mjs +0 -3
- package/dist/db-XEwJbuGO.mjs +0 -3
- package/dist/detector-C-7KRi42.mjs +0 -5
- package/dist/factory-Dbo8yNPi.mjs +0 -3
- package/dist/fallback-oJl3BaIN.mjs.map +0 -1
- package/dist/main-resolver-BAfOMppW.mjs +0 -7
- package/dist/main-resolver-DnkxPYkr.mjs.map +0 -1
- package/dist/program-zpoYnJGz.mjs.map +0 -1
- package/dist/query-feedback-DGoVRaWD.mjs +0 -3
- package/dist/query-feedback-Dqz-HC__.mjs.map +0 -1
- package/dist/router-BTIGZR2_.mjs +0 -3
- package/dist/run-D7K5UALn.mjs.map +0 -1
- package/dist/server-D4vAieF4.mjs.map +0 -1
- package/dist/tools-LlzcV_eK.mjs.map +0 -1
- package/dist/work-queue-worker-AEmfVE0F.mjs +0 -14
- package/dist/work-queue-worker-DIT-VLSh.mjs +0 -2136
- package/dist/work-queue-worker-DIT-VLSh.mjs.map +0 -1
- /package/dist/{indexer-D7MvSQPY.mjs → indexer-C5Le7XE7.mjs} +0 -0
|
@@ -1,12 +1,43 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { C as
|
|
1
|
+
import { n as CONFIG_FILE } from "./config-DCu8THKi.mjs";
|
|
2
|
+
import { N as readJsonStrict, P as writeJsonAtomic, b as resolveProviderKey, f as isModelCapability, g as providerCostTier, h as nativeAnthropicProvider, i as PROVIDER_TAGS, k as workersYamlPath, m as maskKey, n as DEFAULT_LOG_DIR, o as WorkersConfigError, p as keysDir, r as MODEL_CAPABILITIES, t as ANTHROPIC_NATIVE, u as expandHome, v as readWorkersSection, x as writeWorkersSection, y as resolveModelCapability } from "./config-DxMZjpvY.mjs";
|
|
3
|
+
import { C as ageOf, D as isChatPane, E as contextPercent, L as shortText, S as UNLABELED, T as contextLabel, _ as resolveSession, a as renderReport, d as workerDepth, h as currentTabKey, i as parseWorkerReport, k as loadStatuses, l as readInbox, u as sayToWorker, v as sessionTag, w as alive, y as workerInScope } from "./run-DDdT9teG.mjs";
|
|
4
|
+
import { _ as workersLogDir, a as clearCooldown, c as probeQuota, l as quotaSkipThreshold, p as eventsPath, u as resolveTarget } from "./server-Ch99xt5K.mjs";
|
|
4
5
|
import { chmodSync, closeSync, existsSync, mkdirSync, openSync, readFileSync, readSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
6
|
import { homedir } from "node:os";
|
|
6
|
-
import { basename, join, relative } from "node:path";
|
|
7
|
+
import { basename, join, relative, resolve } from "node:path";
|
|
7
8
|
import { execFileSync, spawn } from "node:child_process";
|
|
8
9
|
import { createInterface } from "node:readline";
|
|
9
10
|
|
|
11
|
+
//#region src/workers/specfile.ts
|
|
12
|
+
/**
|
|
13
|
+
* specfile.ts — `--spec <path>` reads a worker's prompt from a file (or stdin
|
|
14
|
+
* via `--spec -`) instead of an inline `-p '<prompt>'`, which has repeatedly
|
|
15
|
+
* died on shell quoting for anything long or multi-line.
|
|
16
|
+
*/
|
|
17
|
+
/** The path a --spec value resolves to for display/recording; "-" (stdin) passes through unchanged. */
|
|
18
|
+
function resolveSpecPath(spec, cwd) {
|
|
19
|
+
return spec === "-" ? "-" : resolve(cwd, spec);
|
|
20
|
+
}
|
|
21
|
+
/** The prompt text a --spec value reads: the file's exact bytes, or stdin's. */
|
|
22
|
+
function readSpecPrompt(spec, cwd) {
|
|
23
|
+
if (spec === "-") {
|
|
24
|
+
let content;
|
|
25
|
+
try {
|
|
26
|
+
content = readFileSync(0, "utf8");
|
|
27
|
+
} catch (e) {
|
|
28
|
+
throw new Error(`--spec -: could not read stdin: ${e.message}`);
|
|
29
|
+
}
|
|
30
|
+
if (!content) throw new Error("--spec -: stdin was empty");
|
|
31
|
+
return content;
|
|
32
|
+
}
|
|
33
|
+
const path = resolveSpecPath(spec, cwd);
|
|
34
|
+
if (!existsSync(path)) throw new Error(`--spec: file not found: ${path}`);
|
|
35
|
+
const content = readFileSync(path, "utf8");
|
|
36
|
+
if (!content) throw new Error(`--spec: file is empty: ${path}`);
|
|
37
|
+
return content;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
10
41
|
//#region src/workers/chatui.ts
|
|
11
42
|
/** Dim hint shown once behind the cursor until the first line is typed. */
|
|
12
43
|
const CHAT_HINT = "type here and press Enter · /help for commands";
|
|
@@ -360,32 +391,6 @@ function tickerText(secs, intent, tool, meter) {
|
|
|
360
391
|
const line = tail ? `${head} · ${tail}` : head;
|
|
361
392
|
return meter ? `${line} · ${meter}` : line;
|
|
362
393
|
}
|
|
363
|
-
/** `4m12s` — the runtime shape the status row shows. */
|
|
364
|
-
function fmtElapsed(secs) {
|
|
365
|
-
const s = Math.max(0, Math.floor(secs));
|
|
366
|
-
return `${Math.floor(s / 60)}m${String(s % 60).padStart(2, "0")}s`;
|
|
367
|
-
}
|
|
368
|
-
/**
|
|
369
|
-
* The chat pane's status row (always visible while following):
|
|
370
|
-
* `[glm/glm-5.3] ctx 84k/200k (42%) · turns 12 · tools 7 · 4m12s · ⋯ 7s · <intent> · <tool>`
|
|
371
|
-
* — context yellow past 70 %, red past 85 %, dropped when unknown; once the
|
|
372
|
-
* worker finished, the ticker part is replaced by `✓ done` / `✗ failed`.
|
|
373
|
-
*/
|
|
374
|
-
function chatStatusRow(c, s) {
|
|
375
|
-
const parts = [];
|
|
376
|
-
const pct = contextPercent(s);
|
|
377
|
-
if (pct !== null) {
|
|
378
|
-
const label = contextLabel(s);
|
|
379
|
-
parts.push(pct > 85 ? c("red", label) : pct > 70 ? c("yellow", label) : label);
|
|
380
|
-
}
|
|
381
|
-
parts.push(`turns ${s.turns}`, `tools ${s.tools}`, fmtElapsed(s.elapsed));
|
|
382
|
-
if (s.state && s.state !== "running") parts.push(s.state === "done" ? c("green", "✓ done") : c("red", "✗ failed"));
|
|
383
|
-
else {
|
|
384
|
-
parts.push(`⋯ ${Math.max(0, Math.floor(s.idle ?? 0))}s`);
|
|
385
|
-
for (const p of [s.intent, s.tool]) if (p && p.trim()) parts.push(p.trim());
|
|
386
|
-
}
|
|
387
|
-
return `[${s.provider}${s.model ? "/" + s.model : ""}] ${parts.join(" · ")}`;
|
|
388
|
-
}
|
|
389
394
|
/**
|
|
390
395
|
* One blank line between turns, none inside one: a blank goes before an
|
|
391
396
|
* assistant message that follows a tool result or an operator message (the
|
|
@@ -473,7 +478,8 @@ function renderEvent(c, prefix, e, cwd, tools, gutter) {
|
|
|
473
478
|
function headerLine(c, s) {
|
|
474
479
|
const bits = [s.provider ? `[${s.provider}]` : "", sessionTag(s)].filter(Boolean).join(" ");
|
|
475
480
|
const sep = bits ? ` ${bits}` : "";
|
|
476
|
-
|
|
481
|
+
const specBit = s.spec ? ` spec: ${s.spec}` : "";
|
|
482
|
+
return c("bold", `━━ ${s.id}${sep} ${s.label} (${basename(s.cwd)})${specBit}`);
|
|
477
483
|
}
|
|
478
484
|
/** The chain label behind a stage label: strip the trailing " · <stage>". */
|
|
479
485
|
function chainLabelOf(stages) {
|
|
@@ -558,51 +564,113 @@ function renderTable(c, statuses, scopeLabel, now = /* @__PURE__ */ new Date(),
|
|
|
558
564
|
return lines.join("\n");
|
|
559
565
|
}
|
|
560
566
|
/**
|
|
561
|
-
* The
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
*
|
|
565
|
-
*
|
|
567
|
+
* The one place a model id is compacted for display, so every renderer
|
|
568
|
+
* shortens identically: the vendor prefix goes (the provider column already
|
|
569
|
+
* says who serves it), a release-date suffix goes, version segments read as
|
|
570
|
+
* dots, and a `[1m]` window marker is kept because it changes what the run
|
|
571
|
+
* costs. `claude-opus-5[1m]` → `opus-5[1m]`, `claude-haiku-4-5-20251001` →
|
|
572
|
+
* `haiku-4.5`, `glm-5.3[1m]` and `k3[1m]` unchanged. Empty in, empty out.
|
|
566
573
|
*/
|
|
567
|
-
function
|
|
568
|
-
const
|
|
569
|
-
if (
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
}
|
|
574
|
-
|
|
574
|
+
function shortModel(model) {
|
|
575
|
+
const raw = String(model ?? "").trim();
|
|
576
|
+
if (!raw) return "";
|
|
577
|
+
const wide = /\[1m\]$/i.test(raw);
|
|
578
|
+
let id = wide ? raw.slice(0, -4) : raw;
|
|
579
|
+
id = id.replace(/^(?:us\.|eu\.|apac\.)?(?:anthropic|claude|openai|google|models)[./-]/i, "");
|
|
580
|
+
id = id.replace(/-\d{8}$/, "");
|
|
581
|
+
const parts = id.split("-");
|
|
582
|
+
const nums = [];
|
|
583
|
+
while (parts.length > 1 && /^\d+(?:\.\d+)*$/.test(parts[parts.length - 1])) nums.unshift(parts.pop());
|
|
584
|
+
if (nums.length) id = `${parts.join("-")}-${nums.join(".")}`;
|
|
585
|
+
return wide ? `${id}[1m]` : id;
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* The goal of a statusline row: what the worker is FOR, never what it is doing
|
|
589
|
+
* this second. The operator's `--label` is the goal and is preferred over
|
|
590
|
+
* anything the model wrote; an unlabelled run's label already holds its prompt
|
|
591
|
+
* (see run.ts), so the same path shortens that to its first sentence, cut on a
|
|
592
|
+
* word boundary. A run with neither label nor prompt reads "unlabeled". Width
|
|
593
|
+
* fitting goes through shortText, the repo's one truncation helper.
|
|
594
|
+
*/
|
|
595
|
+
function goalOf(s, max = 40) {
|
|
596
|
+
const raw = String(s.label ?? "").trim();
|
|
597
|
+
if (!raw || raw === "(no prompt)") return UNLABELED;
|
|
598
|
+
const first = raw.split(/(?<=[.!?])\s+/)[0] ?? raw;
|
|
599
|
+
if (first.length <= max) return shortText(first, max);
|
|
600
|
+
return shortText(`${first.slice(0, max - 1).replace(/\s+\S*$/, "") || first.slice(0, max - 1)}…`, max);
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* A worker pane's bottom line: `<goal> · <model> · started HH:MM · <age>` —
|
|
604
|
+
* what the pane is FOR and how long it has run, never the tool call it
|
|
605
|
+
* happens to be executing this second (that is `pai worker ps` / `follow`
|
|
606
|
+
* territory). `columns`, when known, shrinks the goal so the fixed
|
|
607
|
+
* `model · started · age` tail always survives — trimming that tail instead
|
|
608
|
+
* would defeat the one thing an operator scanning several panes needs at a
|
|
609
|
+
* glance. A legacy status with no recorded model omits that field rather
|
|
610
|
+
* than rendering a bare gap.
|
|
611
|
+
*/
|
|
612
|
+
function paneStatusRow(s, now = /* @__PURE__ */ new Date(), columns = null) {
|
|
613
|
+
const model = shortModel(s.model);
|
|
614
|
+
const started = String(s.started ?? "").slice(11, 16);
|
|
615
|
+
const age = ageOf(s.started, now);
|
|
616
|
+
const tail = [
|
|
617
|
+
model,
|
|
618
|
+
started ? `started ${started}` : "",
|
|
619
|
+
age
|
|
620
|
+
].filter(Boolean).join(" · ");
|
|
621
|
+
return `${goalOf(s, columns !== null ? Math.max(1, columns - tail.length - 3) : 40)} · ${tail}`;
|
|
575
622
|
}
|
|
576
623
|
/**
|
|
577
|
-
* The statusline bar: `provider ▶N
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
624
|
+
* The statusline bar: `provider ▶N · <models> · oldest <age>` and today's
|
|
625
|
+
* ✓/✗ tail. Three workers used to spell out three goals, three ages and three
|
|
626
|
+
* models on one line and none of it fit; each worker's own pane bottom line
|
|
627
|
+
* now carries `goal · model · started · age` (paneStatusRow) and `pai worker
|
|
628
|
+
* ps` has the full table, so the bar only has to answer how many workers are
|
|
629
|
+
* running, on what models, and how long the oldest has been going. `<models>`
|
|
630
|
+
* lists distinct short model names, most-populous first (ties broken by
|
|
631
|
+
* name), each suffixed `×N` past one; an empty model counts under `?` rather
|
|
632
|
+
* than vanishing (a legacy status with no recorded model is still a worker).
|
|
633
|
+
* `columns`, when known, shrinks only the models segment (shortText) so the
|
|
634
|
+
* head, the `▶N` count and the today tally — the three things worth reading
|
|
635
|
+
* at a glance — never get cut for the one segment that can grow without
|
|
636
|
+
* bound. The chat pane contributes nothing but its provider: its age, state
|
|
637
|
+
* and inbox live in `pai worker ps`, not here.
|
|
583
638
|
*/
|
|
584
|
-
function renderStatusLine(mine, now = /* @__PURE__ */ new Date()) {
|
|
585
|
-
|
|
639
|
+
function renderStatusLine(mine, now = /* @__PURE__ */ new Date(), active = null, columns = null) {
|
|
640
|
+
const live = active && active !== "auto" ? active : null;
|
|
641
|
+
if (!mine.length) return live ?? "";
|
|
586
642
|
const isChat = isChatPane;
|
|
587
643
|
const chat = mine.find((s) => isChat(s) && s.state === "running" && alive(s.pid));
|
|
588
|
-
const running = mine.filter((s) => !isChat(s) && s.state === "running" && alive(s.pid))
|
|
644
|
+
const running = mine.filter((s) => !isChat(s) && s.state === "running" && alive(s.pid));
|
|
589
645
|
const today = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
|
|
590
646
|
const doneToday = mine.filter((s) => s.state !== "running" && s.started.startsWith(today));
|
|
591
647
|
const ok = doneToday.filter((s) => s.state === "done").length;
|
|
592
648
|
const bad = doneToday.length - ok;
|
|
593
|
-
const rows = running.slice(0, 3).map((s) => {
|
|
594
|
-
return `${`${running.some((o) => o !== s && o.label === s.label) ? `#${s.id.slice(-4)} ` : ""}${s.label.slice(0, 26)}`} · ${ageOf(s.started, now)} · ${stepOf(s.last)}`;
|
|
595
|
-
});
|
|
596
649
|
let head;
|
|
597
|
-
if (
|
|
650
|
+
if (live) head = live;
|
|
651
|
+
else if (chat) head = chat.provider;
|
|
598
652
|
else {
|
|
599
653
|
const providers = new Set(running.map((s) => s.provider));
|
|
600
654
|
head = providers.size === 1 ? [...providers][0] : "workers";
|
|
601
655
|
}
|
|
602
656
|
if (running.length) head += ` ▶${running.length}`;
|
|
603
|
-
|
|
604
|
-
if (
|
|
605
|
-
|
|
657
|
+
const tail = doneToday.length ? ` ✓${ok} ✗${bad} today` : "";
|
|
658
|
+
if (!running.length) return head + tail;
|
|
659
|
+
const counts = /* @__PURE__ */ new Map();
|
|
660
|
+
for (const s of running) {
|
|
661
|
+
const m = shortModel(s.model) || "?";
|
|
662
|
+
counts.set(m, (counts.get(m) ?? 0) + 1);
|
|
663
|
+
}
|
|
664
|
+
const modelsFull = [...counts.entries()].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).map(([m, n]) => n > 1 ? `${m} ×${n}` : m).join(" · ");
|
|
665
|
+
const oldestPart = `oldest ${ageOf(running.reduce((a, b) => a.started < b.started ? a : b).started, now)}`;
|
|
666
|
+
let models = modelsFull;
|
|
667
|
+
const fixedLen = head.length + 3 + oldestPart.length + tail.length;
|
|
668
|
+
if (columns !== null && fixedLen + 3 + modelsFull.length > columns) {
|
|
669
|
+
const budget = columns - fixedLen - 3;
|
|
670
|
+
models = budget > 0 ? shortText(modelsFull, budget) : "";
|
|
671
|
+
}
|
|
672
|
+
const mid = [models, oldestPart].filter(Boolean).join(" · ");
|
|
673
|
+
return `${head} · ${mid}${tail}`;
|
|
606
674
|
}
|
|
607
675
|
|
|
608
676
|
//#endregion
|
|
@@ -825,6 +893,7 @@ async function followWorkers(logDir, target, showAll, autoExit, env = process.en
|
|
|
825
893
|
let aborted = false;
|
|
826
894
|
let lastEventAt = Date.now();
|
|
827
895
|
let meterStatus = null;
|
|
896
|
+
let paneStatus;
|
|
828
897
|
const onInt = () => {
|
|
829
898
|
aborted = true;
|
|
830
899
|
};
|
|
@@ -856,29 +925,11 @@ async function followWorkers(logDir, target, showAll, autoExit, env = process.en
|
|
|
856
925
|
if (tty) out_.write("\r\x1B[K");
|
|
857
926
|
};
|
|
858
927
|
let ticker = initialFollowState();
|
|
859
|
-
const statusRowOf = (st, secs) => {
|
|
860
|
-
const fin = finished.has(st.id);
|
|
861
|
-
const startedAt = Date.parse((st.started ?? "").replace(" ", "T"));
|
|
862
|
-
const elapsed = fin && st.secs !== null ? st.secs : Number.isNaN(startedAt) ? 0 : Math.floor((Date.now() - startedAt) / 1e3);
|
|
863
|
-
return {
|
|
864
|
-
provider: st.provider,
|
|
865
|
-
model: st.model,
|
|
866
|
-
contextTokens: st.contextTokens,
|
|
867
|
-
contextWindow: st.contextWindow,
|
|
868
|
-
turns: st.turns,
|
|
869
|
-
tools: st.tools,
|
|
870
|
-
elapsed,
|
|
871
|
-
idle: secs,
|
|
872
|
-
intent: ticker.intent,
|
|
873
|
-
tool: ticker.tool,
|
|
874
|
-
state: fin ? st.state === "running" ? "done" : st.state : null
|
|
875
|
-
};
|
|
876
|
-
};
|
|
877
928
|
const writeLiveness = () => {
|
|
878
929
|
if (!tty) return;
|
|
879
930
|
const secs = Math.max(0, Math.floor((Date.now() - lastEventAt) / 1e3));
|
|
880
931
|
if (chat) {
|
|
881
|
-
const text =
|
|
932
|
+
const text = paneStatus ? paneStatusRow(paneStatus, /* @__PURE__ */ new Date(), columns()) : tickerText(secs, ticker.intent, ticker.tool);
|
|
882
933
|
out_.write(chatTickerRow(text, rows, promptCursorCol()));
|
|
883
934
|
} else {
|
|
884
935
|
const meter = meterStatus ? contextMeter(c, meterStatus) : null;
|
|
@@ -1111,6 +1162,7 @@ async function followWorkers(logDir, target, showAll, autoExit, env = process.en
|
|
|
1111
1162
|
for (;;) {
|
|
1112
1163
|
if (aborted) return;
|
|
1113
1164
|
const statuses = new Map(loadStatuses(logDir).map((s) => [s.id, s]));
|
|
1165
|
+
if (target) paneStatus = statuses.get(target) ?? paneStatus;
|
|
1114
1166
|
const wanted = target ? [target] : runningIds();
|
|
1115
1167
|
for (const wid of wanted) {
|
|
1116
1168
|
if (handles.has(wid) || finished.has(wid)) continue;
|
|
@@ -1242,13 +1294,13 @@ function sleep(ms) {
|
|
|
1242
1294
|
return new Promise((r) => setTimeout(r, ms));
|
|
1243
1295
|
}
|
|
1244
1296
|
/** Workers of this terminal for the status bar; "" when there are none. */
|
|
1245
|
-
function statusLineOutput(logDir, term, cwd, claudeSession = "", now = /* @__PURE__ */ new Date()) {
|
|
1297
|
+
function statusLineOutput(logDir, term, cwd, claudeSession = "", now = /* @__PURE__ */ new Date(), active = null) {
|
|
1246
1298
|
return renderStatusLine(loadStatuses(logDir).filter((s) => {
|
|
1247
1299
|
const sameScope = term && workerInScope(s, term);
|
|
1248
1300
|
const spawnedHere = claudeSession && s.spawnerSession === claudeSession;
|
|
1249
1301
|
const sameDir = cwd && s.cwd.startsWith(cwd);
|
|
1250
1302
|
return sameScope || spawnedHere || !term && sameDir;
|
|
1251
|
-
}), now);
|
|
1303
|
+
}), now, active);
|
|
1252
1304
|
}
|
|
1253
1305
|
|
|
1254
1306
|
//#endregion
|
|
@@ -1261,10 +1313,12 @@ function statusLineOutput(logDir, term, cwd, claudeSession = "", now = /* @__PUR
|
|
|
1261
1313
|
* section, and writes it back atomically — the file is shared with everything
|
|
1262
1314
|
* else PAI runs, so a torn write is not an option.
|
|
1263
1315
|
*
|
|
1264
|
-
*
|
|
1265
|
-
*
|
|
1266
|
-
*
|
|
1267
|
-
*
|
|
1316
|
+
* The CLI's `--key` writes the token inline as `key:` in workers.yaml
|
|
1317
|
+
* (quoted, and the file is kept 0600 — see workers-config.ts); `--key-file`
|
|
1318
|
+
* still writes only a path. The MCP `add` tool instead accepts a raw `key`
|
|
1319
|
+
* and parks it in ~/.claude/pai/keys/<name>, mode 0600, storing only the
|
|
1320
|
+
* path in the config — a chat is not a place to leave a credential lying
|
|
1321
|
+
* around.
|
|
1268
1322
|
*/
|
|
1269
1323
|
function addProvider(input) {
|
|
1270
1324
|
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(input.name)) throw new WorkersConfigError(`provider name "${input.name}" may only contain letters, digits, - and _`);
|
|
@@ -1284,12 +1338,13 @@ function addProvider(input) {
|
|
|
1284
1338
|
} catch {}
|
|
1285
1339
|
keyFile = path;
|
|
1286
1340
|
}
|
|
1287
|
-
const { raw, workers } = readWorkersSection();
|
|
1341
|
+
const { raw, workers } = readWorkersSection(input.configPath);
|
|
1288
1342
|
const provider = {
|
|
1289
1343
|
enabled: true,
|
|
1290
1344
|
protocol: input.protocol ?? "anthropic",
|
|
1291
1345
|
baseUrl: input.baseUrl,
|
|
1292
1346
|
keyFile,
|
|
1347
|
+
...input.inlineKey ? { key: input.inlineKey } : {},
|
|
1293
1348
|
models: input.fastModel ? {
|
|
1294
1349
|
default: input.model,
|
|
1295
1350
|
fast: input.fastModel
|
|
@@ -1321,12 +1376,12 @@ function addProvider(input) {
|
|
|
1321
1376
|
image: input.name
|
|
1322
1377
|
};
|
|
1323
1378
|
}
|
|
1324
|
-
writeWorkersSection(raw, workers);
|
|
1379
|
+
writeWorkersSection(raw, workers, input.configPath);
|
|
1325
1380
|
return workers;
|
|
1326
1381
|
}
|
|
1327
1382
|
/** Change costTier / tags on an existing provider (MCP action "update"). */
|
|
1328
|
-
function updateProvider(name, changes) {
|
|
1329
|
-
const { raw, workers } = readWorkersSection();
|
|
1383
|
+
function updateProvider(name, changes, configPath) {
|
|
1384
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1330
1385
|
const p = workers.providers[name];
|
|
1331
1386
|
if (!p) throw new WorkersConfigError(`no provider named "${name}". Configured: ${Object.keys(workers.providers).join(", ") || "(none)"}`);
|
|
1332
1387
|
if (changes.costTier !== void 0) {
|
|
@@ -1337,23 +1392,23 @@ function updateProvider(name, changes) {
|
|
|
1337
1392
|
for (const t of changes.tags) if (!PROVIDER_TAGS.includes(t)) throw new WorkersConfigError(`"${t}" is not a tag (from: ${PROVIDER_TAGS.join(", ")})`);
|
|
1338
1393
|
p.tags = changes.tags;
|
|
1339
1394
|
}
|
|
1340
|
-
writeWorkersSection(raw, workers);
|
|
1395
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1341
1396
|
return workers;
|
|
1342
1397
|
}
|
|
1343
|
-
function removeProvider(name) {
|
|
1344
|
-
const { raw, workers } = readWorkersSection();
|
|
1398
|
+
function removeProvider(name, configPath) {
|
|
1399
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1345
1400
|
if (!workers.providers[name]) throw new WorkersConfigError(`no provider named "${name}"`);
|
|
1346
1401
|
delete workers.providers[name];
|
|
1347
1402
|
for (const [cls, target] of Object.entries(workers.classes)) if ((typeof target === "string" ? target.split("/")[0] : target.provider) === name) delete workers.classes[cls];
|
|
1348
1403
|
if (workers.active === name) workers.active = null;
|
|
1349
|
-
writeWorkersSection(raw, workers);
|
|
1404
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1350
1405
|
return workers;
|
|
1351
1406
|
}
|
|
1352
|
-
function useProvider(name) {
|
|
1353
|
-
const { raw, workers } = readWorkersSection();
|
|
1407
|
+
function useProvider(name, configPath) {
|
|
1408
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1354
1409
|
if (name !== ANTHROPIC_NATIVE && !workers.providers[name]) throw new WorkersConfigError(`no provider named "${name}". Configured: ${Object.keys(workers.providers).join(", ") || "(none)"}`);
|
|
1355
1410
|
workers.active = name;
|
|
1356
|
-
writeWorkersSection(raw, workers);
|
|
1411
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1357
1412
|
return workers;
|
|
1358
1413
|
}
|
|
1359
1414
|
/**
|
|
@@ -1382,13 +1437,13 @@ function setProviderModel(name, capability, model, configPath) {
|
|
|
1382
1437
|
writeWorkersSection(raw, workers, configPath);
|
|
1383
1438
|
return workers;
|
|
1384
1439
|
}
|
|
1385
|
-
function setProviderEnabled(name, enabled) {
|
|
1386
|
-
const { raw, workers } = readWorkersSection();
|
|
1440
|
+
function setProviderEnabled(name, enabled, configPath) {
|
|
1441
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1387
1442
|
const p = workers.providers[name];
|
|
1388
1443
|
if (!p) throw new WorkersConfigError(`no provider named "${name}"`);
|
|
1389
1444
|
p.enabled = enabled;
|
|
1390
|
-
writeWorkersSection(raw, workers);
|
|
1391
|
-
if (enabled) clearCooldown(workersLogDir(
|
|
1445
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1446
|
+
if (enabled) clearCooldown(workersLogDir(workers), name);
|
|
1392
1447
|
return workers;
|
|
1393
1448
|
}
|
|
1394
1449
|
/**
|
|
@@ -1396,8 +1451,8 @@ function setProviderEnabled(name, enabled) {
|
|
|
1396
1451
|
* provider + optional mcp/maxCostTier/requireTags/order). An object without
|
|
1397
1452
|
* a provider only constrains auto-routing for that class.
|
|
1398
1453
|
*/
|
|
1399
|
-
function setClass(name, target) {
|
|
1400
|
-
const { raw, workers } = readWorkersSection();
|
|
1454
|
+
function setClass(name, target, configPath) {
|
|
1455
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1401
1456
|
if (typeof target === "string") {
|
|
1402
1457
|
const [provider, alias] = target.split("/");
|
|
1403
1458
|
const native = provider === ANTHROPIC_NATIVE;
|
|
@@ -1411,20 +1466,20 @@ function setClass(name, target) {
|
|
|
1411
1466
|
if (target.provider !== ANTHROPIC_NATIVE && !workers.providers[target.provider]) throw new WorkersConfigError(`no provider named "${target.provider}". Configured: ${Object.keys(workers.providers).join(", ") || "(none)"}`);
|
|
1412
1467
|
}
|
|
1413
1468
|
workers.classes[name] = target;
|
|
1414
|
-
writeWorkersSection(raw, workers);
|
|
1469
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1415
1470
|
return workers;
|
|
1416
1471
|
}
|
|
1417
|
-
function unsetClass(name) {
|
|
1418
|
-
const { raw, workers } = readWorkersSection();
|
|
1472
|
+
function unsetClass(name, configPath) {
|
|
1473
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1419
1474
|
if (!(name in workers.classes)) throw new WorkersConfigError(`no class named "${name}"`);
|
|
1420
1475
|
delete workers.classes[name];
|
|
1421
|
-
writeWorkersSection(raw, workers);
|
|
1476
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1422
1477
|
return workers;
|
|
1423
1478
|
}
|
|
1424
|
-
function setWorkersEnabled(enabled) {
|
|
1425
|
-
const { raw, workers } = readWorkersSection();
|
|
1479
|
+
function setWorkersEnabled(enabled, configPath) {
|
|
1480
|
+
const { raw, workers } = readWorkersSection(configPath);
|
|
1426
1481
|
workers.enabled = enabled;
|
|
1427
|
-
writeWorkersSection(raw, workers);
|
|
1482
|
+
writeWorkersSection(raw, workers, configPath);
|
|
1428
1483
|
return workers;
|
|
1429
1484
|
}
|
|
1430
1485
|
/** `glm/fast` | `{provider, mcp, …}` → one printable target line. */
|
|
@@ -1460,15 +1515,23 @@ function describeModels(workers) {
|
|
|
1460
1515
|
}
|
|
1461
1516
|
return lines;
|
|
1462
1517
|
}
|
|
1518
|
+
/** Classes (in declaration order) whose target resolves to this provider. */
|
|
1519
|
+
function classesForProvider(workers, name) {
|
|
1520
|
+
return Object.entries(workers.classes).filter(([, target]) => (typeof target === "string" ? target.split("/")[0] : target.provider) === name).map(([cls]) => cls);
|
|
1521
|
+
}
|
|
1463
1522
|
/** Human-readable provider listing (quota probe included when configured). */
|
|
1464
|
-
function describeProviders(workers) {
|
|
1523
|
+
function describeProviders(workers, configPath = CONFIG_FILE) {
|
|
1465
1524
|
const lines = [];
|
|
1466
1525
|
const nativeActive = workers.active === ANTHROPIC_NATIVE;
|
|
1467
1526
|
lines.push(`${ANTHROPIC_NATIVE} [built-in${nativeActive ? ", active" : ""}] Claude Code's own OAuth/Max-plan login — no base URL, no API key`);
|
|
1527
|
+
lines.push(` ${modelPrefsText(nativeAnthropicProvider(workers.nativeModels))}`);
|
|
1528
|
+
const nativeClasses = classesForProvider(workers, ANTHROPIC_NATIVE);
|
|
1529
|
+
lines.push(` classes: ${nativeClasses.length ? nativeClasses.join(", ") : "(none)"}`);
|
|
1468
1530
|
const names = Object.keys(workers.providers);
|
|
1469
1531
|
if (!names.length) {
|
|
1470
1532
|
lines.push(`no other providers configured. Add one with:`);
|
|
1471
1533
|
lines.push(` pai worker providers add <name> --base-url <url> --key-file <path> --model <model>`);
|
|
1534
|
+
lines.push(`config: ${existsSync(workersYamlPath()) ? workersYamlPath() : configPath}`);
|
|
1472
1535
|
return lines;
|
|
1473
1536
|
}
|
|
1474
1537
|
for (const name of names) {
|
|
@@ -1480,17 +1543,19 @@ function describeProviders(workers) {
|
|
|
1480
1543
|
lines.push(`${name} [${flags.join(", ")}] ${p.baseUrl}`);
|
|
1481
1544
|
lines.push(` ${modelPrefsText(p)}${quotaNote}`);
|
|
1482
1545
|
lines.push(` ${tierTags}`);
|
|
1546
|
+
if (p.key) lines.push(` key ${maskKey(p.key)}`);
|
|
1483
1547
|
if (p.keyFile) lines.push(` key file ${expandHome(p.keyFile)}`);
|
|
1484
|
-
|
|
1548
|
+
if (!p.key && !p.keyFile) lines.push(` no key file (token "local")`);
|
|
1485
1549
|
if (p.note) lines.push(` ${p.note}`);
|
|
1486
1550
|
if (p.protocol === "openai") lines.push(` via PAI proxy ← ${p.upstreamUrl ?? "(upstreamUrl missing)"}`);
|
|
1487
1551
|
if (p.engine === "codex") lines.push(` engine codex (runs through the Codex CLI)`);
|
|
1552
|
+
const cls = classesForProvider(workers, name);
|
|
1553
|
+
lines.push(` classes: ${cls.length ? cls.join(", ") : "(none)"}`);
|
|
1488
1554
|
}
|
|
1489
1555
|
const setNames = Object.keys(workers.mcpSets);
|
|
1490
1556
|
if (setNames.length) lines.push(`mcp sets: ${setNames.map((s) => `${s}=[${workers.mcpSets[s].join(",")}]`).join(" ")}`);
|
|
1491
|
-
const classNames = Object.keys(workers.classes);
|
|
1492
|
-
if (classNames.length) lines.push(`classes: ${classNames.map((cl) => `${cl}=${classTargetText(workers.classes[cl])}`).join(" ")}`);
|
|
1493
1557
|
if (workers.active === "auto") lines.push(`routing: auto — order [${workers.routing.order.join(", ")}], cooldown ${workers.routing.cooldownMinutes}m`);
|
|
1558
|
+
lines.push(`config: ${existsSync(workersYamlPath()) ? workersYamlPath() : configPath}`);
|
|
1494
1559
|
return lines;
|
|
1495
1560
|
}
|
|
1496
1561
|
|
|
@@ -1509,7 +1574,7 @@ function describeProviders(workers) {
|
|
|
1509
1574
|
* and pins the top-level `model` to the provider's default model.
|
|
1510
1575
|
*
|
|
1511
1576
|
* What settings.json carried before the switch is saved under
|
|
1512
|
-
* `workers.fallback.saved` in
|
|
1577
|
+
* `workers.fallback.saved` in the PAI config file (CONFIG_FILE); `fallback off`
|
|
1513
1578
|
* restores it exactly and removes the added keys. Both files are written
|
|
1514
1579
|
* atomically; nothing else in them is touched. While fallback is on the
|
|
1515
1580
|
* Agent hook keeps routing subagents to workers, unchanged — those runs set
|
|
@@ -1536,12 +1601,7 @@ function fallbackNotePath(logDir) {
|
|
|
1536
1601
|
* buildRunEnv uses), the provider's own env, and the two fallback constants.
|
|
1537
1602
|
*/
|
|
1538
1603
|
function fallbackEnv(provider) {
|
|
1539
|
-
|
|
1540
|
-
const keyPath = providerKeyPath(provider);
|
|
1541
|
-
if (keyPath) {
|
|
1542
|
-
token = readFileSync(keyPath, "utf8").trim();
|
|
1543
|
-
if (!token) throw new WorkersConfigError(`key file is empty: ${keyPath}`);
|
|
1544
|
-
}
|
|
1604
|
+
const token = resolveProviderKey(provider) ?? "local";
|
|
1545
1605
|
return {
|
|
1546
1606
|
ANTHROPIC_BASE_URL: provider.baseUrl,
|
|
1547
1607
|
ANTHROPIC_AUTH_TOKEN: token,
|
|
@@ -1764,5 +1824,5 @@ function fallbackStatusText(s) {
|
|
|
1764
1824
|
}
|
|
1765
1825
|
|
|
1766
1826
|
//#endregion
|
|
1767
|
-
export { statusLineOutput as S, updateProvider as _, addProvider as a, psOutput as b, describeProviders as c, resolveProviderName as d, setClass as f, unsetClass as g, setWorkersEnabled as h, fallbackStatusText as i, modelPrefsText as l, setProviderModel as m, fallbackOn as n, classTargetText as o, setProviderEnabled as p, fallbackStatus as r, describeModels as s, fallbackOff as t, removeProvider as u, useProvider as v, replayOutput as x, followWorkers as y };
|
|
1768
|
-
//# sourceMappingURL=fallback-
|
|
1827
|
+
export { readSpecPrompt as C, statusLineOutput as S, updateProvider as _, addProvider as a, psOutput as b, describeProviders as c, resolveProviderName as d, setClass as f, unsetClass as g, setWorkersEnabled as h, fallbackStatusText as i, modelPrefsText as l, setProviderModel as m, fallbackOn as n, classTargetText as o, setProviderEnabled as p, fallbackStatus as r, describeModels as s, fallbackOff as t, removeProvider as u, useProvider as v, resolveSpecPath as w, replayOutput as x, followWorkers as y };
|
|
1828
|
+
//# sourceMappingURL=fallback-Cwt4hmh5.mjs.map
|