@caupulican/pi-adaptative 0.81.38 → 0.81.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/README.md +18 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts +131 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.d.ts.map +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js +196 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.js.map +1 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/dispatch-grant.ts +308 -0
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts +22 -2
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.d.ts.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js +585 -24
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.js.map +1 -1
- package/dist/bundled-resources/extensions/tmux-agent-manager/index.ts +749 -27
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/__init__.py +43 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/fs.py +270 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/search.py +252 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/strings.py +399 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/commands/text.py +575 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/context.py +52 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/errors.py +49 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/exec.py +734 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/expand.py +238 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/main.py +132 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/nodes.py +116 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/parser.py +287 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/proc.py +137 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/state.py +100 -0
- package/dist/bundled-resources/runtimes/pi-shell-engine/tokens.py +579 -0
- package/dist/bundled-resources/skills/tool-call-repair/SKILL.md +19 -9
- package/dist/bundled-resources/skills/tool-call-repair/references/failure-grammar.md +22 -5
- package/dist/bundled-resources/skills/tool-call-repair/references/repair-catalogue.md +5 -5
- package/dist/bundled-resources/skills/tool-call-repair/references/text-protocol-grammar.md +28 -7
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +15 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-paths.d.ts +49 -0
- package/dist/core/agent-paths.d.ts.map +1 -0
- package/dist/core/agent-paths.js +107 -0
- package/dist/core/agent-paths.js.map +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +3 -3
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +234 -17
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +484 -62
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/autonomy/contracts.d.ts +9 -0
- package/dist/core/autonomy/contracts.d.ts.map +1 -1
- package/dist/core/autonomy/contracts.js.map +1 -1
- package/dist/core/autonomy/lane-tracker.d.ts +10 -1
- package/dist/core/autonomy/lane-tracker.d.ts.map +1 -1
- package/dist/core/autonomy/lane-tracker.js +5 -1
- package/dist/core/autonomy/lane-tracker.js.map +1 -1
- package/dist/core/background-lane-controller.d.ts +122 -6
- package/dist/core/background-lane-controller.d.ts.map +1 -1
- package/dist/core/background-lane-controller.js +446 -89
- package/dist/core/background-lane-controller.js.map +1 -1
- package/dist/core/bash-execution-controller.d.ts +4 -0
- package/dist/core/bash-execution-controller.d.ts.map +1 -1
- package/dist/core/bash-execution-controller.js +7 -1
- package/dist/core/bash-execution-controller.js.map +1 -1
- package/dist/core/compaction-support.d.ts +13 -3
- package/dist/core/compaction-support.d.ts.map +1 -1
- package/dist/core/compaction-support.js +43 -7
- package/dist/core/compaction-support.js.map +1 -1
- package/dist/core/context/context-audit.d.ts +33 -1
- package/dist/core/context/context-audit.d.ts.map +1 -1
- package/dist/core/context/context-audit.js +31 -5
- package/dist/core/context/context-audit.js.map +1 -1
- package/dist/core/context-gc.d.ts.map +1 -1
- package/dist/core/context-gc.js +16 -1
- package/dist/core/context-gc.js.map +1 -1
- package/dist/core/context-pipeline.d.ts +26 -4
- package/dist/core/context-pipeline.d.ts.map +1 -1
- package/dist/core/context-pipeline.js +137 -14
- package/dist/core/context-pipeline.js.map +1 -1
- package/dist/core/cost-guard.d.ts +19 -3
- package/dist/core/cost-guard.d.ts.map +1 -1
- package/dist/core/cost-guard.js +18 -3
- package/dist/core/cost-guard.js.map +1 -1
- package/dist/core/delegation/session-worker-result.d.ts +34 -4
- package/dist/core/delegation/session-worker-result.d.ts.map +1 -1
- package/dist/core/delegation/session-worker-result.js +64 -4
- package/dist/core/delegation/session-worker-result.js.map +1 -1
- package/dist/core/delegation/worker-result.d.ts +42 -1
- package/dist/core/delegation/worker-result.d.ts.map +1 -1
- package/dist/core/delegation/worker-result.js +68 -0
- package/dist/core/delegation/worker-result.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +20 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +1 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/types.d.ts +51 -0
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/goal-loop-controller.d.ts +17 -1
- package/dist/core/goal-loop-controller.d.ts.map +1 -1
- package/dist/core/goal-loop-controller.js +79 -11
- package/dist/core/goal-loop-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-controller.d.ts +48 -2
- package/dist/core/goals/goal-continuation-controller.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-controller.js +77 -0
- package/dist/core/goals/goal-continuation-controller.js.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.d.ts +39 -0
- package/dist/core/goals/goal-continuation-defaults.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-defaults.js +42 -0
- package/dist/core/goals/goal-continuation-defaults.js.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.d.ts +4 -0
- package/dist/core/goals/goal-continuation-prompt.d.ts.map +1 -1
- package/dist/core/goals/goal-continuation-prompt.js +51 -10
- package/dist/core/goals/goal-continuation-prompt.js.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.d.ts +101 -2
- package/dist/core/goals/goal-runtime-snapshot.d.ts.map +1 -1
- package/dist/core/goals/goal-runtime-snapshot.js +87 -4
- package/dist/core/goals/goal-runtime-snapshot.js.map +1 -1
- package/dist/core/goals/goal-state.d.ts +89 -1
- package/dist/core/goals/goal-state.d.ts.map +1 -1
- package/dist/core/goals/goal-state.js +71 -5
- package/dist/core/goals/goal-state.js.map +1 -1
- package/dist/core/goals/goal-tool-core.d.ts +56 -2
- package/dist/core/goals/goal-tool-core.d.ts.map +1 -1
- package/dist/core/goals/goal-tool-core.js +111 -5
- package/dist/core/goals/goal-tool-core.js.map +1 -1
- package/dist/core/goals/session-goal-state.d.ts +11 -2
- package/dist/core/goals/session-goal-state.d.ts.map +1 -1
- package/dist/core/goals/session-goal-state.js +32 -17
- package/dist/core/goals/session-goal-state.js.map +1 -1
- package/dist/core/keybindings.d.ts +10 -0
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +10 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/learning/observation-store.d.ts +12 -3
- package/dist/core/learning/observation-store.d.ts.map +1 -1
- package/dist/core/learning/observation-store.js +30 -15
- package/dist/core/learning/observation-store.js.map +1 -1
- package/dist/core/learning/skill-curator.d.ts +5 -1
- package/dist/core/learning/skill-curator.d.ts.map +1 -1
- package/dist/core/learning/skill-curator.js +21 -19
- package/dist/core/learning/skill-curator.js.map +1 -1
- package/dist/core/local-runtime-controller.d.ts +65 -3
- package/dist/core/local-runtime-controller.d.ts.map +1 -1
- package/dist/core/local-runtime-controller.js +186 -26
- package/dist/core/local-runtime-controller.js.map +1 -1
- package/dist/core/memory/providers/file-store.d.ts +1 -1
- package/dist/core/memory/providers/file-store.d.ts.map +1 -1
- package/dist/core/memory/providers/file-store.js +6 -6
- package/dist/core/memory/providers/file-store.js.map +1 -1
- package/dist/core/model-capability.d.ts +34 -0
- package/dist/core/model-capability.d.ts.map +1 -1
- package/dist/core/model-capability.js +42 -1
- package/dist/core/model-capability.js.map +1 -1
- package/dist/core/model-router/tool-escalation.d.ts +15 -0
- package/dist/core/model-router/tool-escalation.d.ts.map +1 -1
- package/dist/core/model-router/tool-escalation.js +23 -1
- package/dist/core/model-router/tool-escalation.js.map +1 -1
- package/dist/core/model-router-controller.d.ts +34 -7
- package/dist/core/model-router-controller.d.ts.map +1 -1
- package/dist/core/model-router-controller.js +95 -16
- package/dist/core/model-router-controller.js.map +1 -1
- package/dist/core/models/adaptation-store.d.ts +7 -0
- package/dist/core/models/adaptation-store.d.ts.map +1 -1
- package/dist/core/models/adaptation-store.js +47 -11
- package/dist/core/models/adaptation-store.js.map +1 -1
- package/dist/core/models/default-model-suggestions.d.ts.map +1 -1
- package/dist/core/models/default-model-suggestions.js +17 -0
- package/dist/core/models/default-model-suggestions.js.map +1 -1
- package/dist/core/models/fitness-store.d.ts +3 -0
- package/dist/core/models/fitness-store.d.ts.map +1 -1
- package/dist/core/models/fitness-store.js +11 -2
- package/dist/core/models/fitness-store.js.map +1 -1
- package/dist/core/models/llamacpp-runtime.d.ts +180 -0
- package/dist/core/models/llamacpp-runtime.d.ts.map +1 -0
- package/dist/core/models/llamacpp-runtime.js +475 -0
- package/dist/core/models/llamacpp-runtime.js.map +1 -0
- package/dist/core/models/local-registration.d.ts +40 -0
- package/dist/core/models/local-registration.d.ts.map +1 -1
- package/dist/core/models/local-registration.js +94 -5
- package/dist/core/models/local-registration.js.map +1 -1
- package/dist/core/models/local-runtime.d.ts.map +1 -1
- package/dist/core/models/local-runtime.js +6 -5
- package/dist/core/models/local-runtime.js.map +1 -1
- package/dist/core/models/model-ref.d.ts +7 -0
- package/dist/core/models/model-ref.d.ts.map +1 -1
- package/dist/core/models/model-ref.js +26 -0
- package/dist/core/models/model-ref.js.map +1 -1
- package/dist/core/models/needle-runtime.d.ts +257 -0
- package/dist/core/models/needle-runtime.d.ts.map +1 -0
- package/dist/core/models/needle-runtime.js +519 -0
- package/dist/core/models/needle-runtime.js.map +1 -0
- package/dist/core/models/prism-llamacpp-lifecycle.d.ts +89 -0
- package/dist/core/models/prism-llamacpp-lifecycle.d.ts.map +1 -0
- package/dist/core/models/prism-llamacpp-lifecycle.js +121 -0
- package/dist/core/models/prism-llamacpp-lifecycle.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -10
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/process-matrix/codes.d.ts +72 -0
- package/dist/core/process-matrix/codes.d.ts.map +1 -0
- package/dist/core/process-matrix/codes.js +15 -0
- package/dist/core/process-matrix/codes.js.map +1 -0
- package/dist/core/process-matrix/runtime.d.ts +63 -0
- package/dist/core/process-matrix/runtime.d.ts.map +1 -0
- package/dist/core/process-matrix/runtime.js +310 -0
- package/dist/core/process-matrix/runtime.js.map +1 -0
- package/dist/core/process-matrix/store.d.ts +22 -0
- package/dist/core/process-matrix/store.d.ts.map +1 -0
- package/dist/core/process-matrix/store.js +80 -0
- package/dist/core/process-matrix/store.js.map +1 -0
- package/dist/core/process-matrix/supervisor.d.ts +72 -0
- package/dist/core/process-matrix/supervisor.d.ts.map +1 -0
- package/dist/core/process-matrix/supervisor.js +130 -0
- package/dist/core/process-matrix/supervisor.js.map +1 -0
- package/dist/core/profile-registry.d.ts +7 -0
- package/dist/core/profile-registry.d.ts.map +1 -1
- package/dist/core/profile-registry.js +20 -0
- package/dist/core/profile-registry.js.map +1 -1
- package/dist/core/python-runtime.d.ts.map +1 -1
- package/dist/core/python-runtime.js +3 -3
- package/dist/core/python-runtime.js.map +1 -1
- package/dist/core/reflection-controller.d.ts +29 -5
- package/dist/core/reflection-controller.d.ts.map +1 -1
- package/dist/core/reflection-controller.js +215 -126
- package/dist/core/reflection-controller.js.map +1 -1
- package/dist/core/reload-blockers.d.ts +36 -0
- package/dist/core/reload-blockers.d.ts.map +1 -1
- package/dist/core/reload-blockers.js +44 -0
- package/dist/core/reload-blockers.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +8 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/runtime-builder.d.ts +58 -5
- package/dist/core/runtime-builder.d.ts.map +1 -1
- package/dist/core/runtime-builder.js +209 -25
- package/dist/core/runtime-builder.js.map +1 -1
- package/dist/core/scout-controller.d.ts +6 -0
- package/dist/core/scout-controller.d.ts.map +1 -1
- package/dist/core/scout-controller.js +66 -52
- package/dist/core/scout-controller.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-role.d.ts +31 -0
- package/dist/core/session-role.d.ts.map +1 -0
- package/dist/core/session-role.js +52 -0
- package/dist/core/session-role.js.map +1 -0
- package/dist/core/settings-manager.d.ts +42 -3
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +94 -60
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt-builder.d.ts +12 -0
- package/dist/core/system-prompt-builder.d.ts.map +1 -1
- package/dist/core/system-prompt-builder.js +6 -0
- package/dist/core/system-prompt-builder.js.map +1 -1
- package/dist/core/system-prompt.d.ts +14 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +20 -3
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/tasks/session-task-state.d.ts +11 -2
- package/dist/core/tasks/session-task-state.d.ts.map +1 -1
- package/dist/core/tasks/session-task-state.js +27 -11
- package/dist/core/tasks/session-task-state.js.map +1 -1
- package/dist/core/tasks/task-contract-monitor.d.ts +45 -0
- package/dist/core/tasks/task-contract-monitor.d.ts.map +1 -0
- package/dist/core/tasks/task-contract-monitor.js +56 -0
- package/dist/core/tasks/task-contract-monitor.js.map +1 -0
- package/dist/core/tasks/task-state.d.ts +8 -0
- package/dist/core/tasks/task-state.d.ts.map +1 -1
- package/dist/core/tasks/task-state.js +28 -1
- package/dist/core/tasks/task-state.js.map +1 -1
- package/dist/core/tool-gate-controller.d.ts.map +1 -1
- package/dist/core/tool-gate-controller.js +5 -0
- package/dist/core/tool-gate-controller.js.map +1 -1
- package/dist/core/tool-recovery-log-records.d.ts +7 -0
- package/dist/core/tool-recovery-log-records.d.ts.map +1 -1
- package/dist/core/tool-recovery-log-records.js +14 -6
- package/dist/core/tool-recovery-log-records.js.map +1 -1
- package/dist/core/tool-selection/promotion.d.ts +54 -0
- package/dist/core/tool-selection/promotion.d.ts.map +1 -0
- package/dist/core/tool-selection/promotion.js +81 -0
- package/dist/core/tool-selection/promotion.js.map +1 -0
- package/dist/core/tool-selection/tool-performance-store.d.ts +37 -0
- package/dist/core/tool-selection/tool-performance-store.d.ts.map +1 -1
- package/dist/core/tool-selection/tool-performance-store.js +87 -3
- package/dist/core/tool-selection/tool-performance-store.js.map +1 -1
- package/dist/core/tool-selection/tool-selection-controller.d.ts +45 -0
- package/dist/core/tool-selection/tool-selection-controller.d.ts.map +1 -1
- package/dist/core/tool-selection/tool-selection-controller.js +96 -0
- package/dist/core/tool-selection/tool-selection-controller.js.map +1 -1
- package/dist/core/tools/bash.d.ts +18 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +95 -16
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/delegate-status.d.ts +14 -0
- package/dist/core/tools/delegate-status.d.ts.map +1 -1
- package/dist/core/tools/delegate-status.js +82 -7
- package/dist/core/tools/delegate-status.js.map +1 -1
- package/dist/core/tools/delegate.d.ts.map +1 -1
- package/dist/core/tools/delegate.js +25 -8
- package/dist/core/tools/delegate.js.map +1 -1
- package/dist/core/tools/goal.d.ts +94 -3
- package/dist/core/tools/goal.d.ts.map +1 -1
- package/dist/core/tools/goal.js +165 -15
- package/dist/core/tools/goal.js.map +1 -1
- package/dist/core/tools/model-fitness.d.ts +7 -0
- package/dist/core/tools/model-fitness.d.ts.map +1 -1
- package/dist/core/tools/model-fitness.js +2 -2
- package/dist/core/tools/model-fitness.js.map +1 -1
- package/dist/core/tools/shell-contract-router.d.ts +6 -1
- package/dist/core/tools/shell-contract-router.d.ts.map +1 -1
- package/dist/core/tools/shell-contract-router.js +23 -2
- package/dist/core/tools/shell-contract-router.js.map +1 -1
- package/dist/core/tools/shell-session.d.ts +89 -0
- package/dist/core/tools/shell-session.d.ts.map +1 -0
- package/dist/core/tools/shell-session.js +432 -0
- package/dist/core/tools/shell-session.js.map +1 -0
- package/dist/core/tools/task-steps.d.ts +4 -0
- package/dist/core/tools/task-steps.d.ts.map +1 -1
- package/dist/core/tools/task-steps.js +63 -8
- package/dist/core/tools/task-steps.js.map +1 -1
- package/dist/core/tools/tmux-dispatch.d.ts +86 -0
- package/dist/core/tools/tmux-dispatch.d.ts.map +1 -0
- package/dist/core/tools/tmux-dispatch.js +91 -0
- package/dist/core/tools/tmux-dispatch.js.map +1 -0
- package/dist/core/tools/windows-shell-engine.d.ts +42 -0
- package/dist/core/tools/windows-shell-engine.d.ts.map +1 -0
- package/dist/core/tools/windows-shell-engine.js +153 -0
- package/dist/core/tools/windows-shell-engine.js.map +1 -0
- package/dist/core/tools/windows-shell-state.d.ts +40 -0
- package/dist/core/tools/windows-shell-state.d.ts.map +1 -0
- package/dist/core/tools/windows-shell-state.js +59 -0
- package/dist/core/tools/windows-shell-state.js.map +1 -0
- package/dist/core/tools/worktree-sync.d.ts +24 -0
- package/dist/core/tools/worktree-sync.d.ts.map +1 -0
- package/dist/core/tools/worktree-sync.js +338 -0
- package/dist/core/tools/worktree-sync.js.map +1 -0
- package/dist/core/trust-manager.d.ts +4 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +20 -2
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/util/atomic-file.d.ts +55 -0
- package/dist/core/util/atomic-file.d.ts.map +1 -0
- package/dist/core/util/atomic-file.js +255 -0
- package/dist/core/util/atomic-file.js.map +1 -0
- package/dist/core/util/minimatch-cache.d.ts +33 -0
- package/dist/core/util/minimatch-cache.d.ts.map +1 -0
- package/dist/core/util/minimatch-cache.js +0 -0
- package/dist/core/util/minimatch-cache.js.map +1 -0
- package/dist/core/worktree-sync/codes.d.ts +227 -0
- package/dist/core/worktree-sync/codes.d.ts.map +1 -0
- package/dist/core/worktree-sync/codes.js +14 -0
- package/dist/core/worktree-sync/codes.js.map +1 -0
- package/dist/core/worktree-sync/git-engine.d.ts +156 -0
- package/dist/core/worktree-sync/git-engine.d.ts.map +1 -0
- package/dist/core/worktree-sync/git-engine.js +1191 -0
- package/dist/core/worktree-sync/git-engine.js.map +1 -0
- package/dist/core/worktree-sync/lane-gate.d.ts +75 -0
- package/dist/core/worktree-sync/lane-gate.d.ts.map +1 -0
- package/dist/core/worktree-sync/lane-gate.js +360 -0
- package/dist/core/worktree-sync/lane-gate.js.map +1 -0
- package/dist/core/worktree-sync/runtime.d.ts +47 -0
- package/dist/core/worktree-sync/runtime.d.ts.map +1 -0
- package/dist/core/worktree-sync/runtime.js +96 -0
- package/dist/core/worktree-sync/runtime.js.map +1 -0
- package/dist/core/worktree-sync/store.d.ts +69 -0
- package/dist/core/worktree-sync/store.d.ts.map +1 -0
- package/dist/core/worktree-sync/store.js +247 -0
- package/dist/core/worktree-sync/store.js.map +1 -0
- package/dist/core/worktree-sync/watcher.d.ts +29 -0
- package/dist/core/worktree-sync/watcher.d.ts.map +1 -0
- package/dist/core/worktree-sync/watcher.js +93 -0
- package/dist/core/worktree-sync/watcher.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +94 -0
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +9 -0
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +38 -0
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/auto-learn-controller.d.ts +16 -1
- package/dist/modes/interactive/auto-learn-controller.d.ts.map +1 -1
- package/dist/modes/interactive/auto-learn-controller.js +50 -8
- package/dist/modes/interactive/auto-learn-controller.js.map +1 -1
- package/dist/modes/interactive/components/profile-resource-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/profile-resource-editor.js +23 -1
- package/dist/modes/interactive/components/profile-resource-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +4 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/local-model-commands.d.ts +43 -0
- package/dist/modes/interactive/local-model-commands.d.ts.map +1 -1
- package/dist/modes/interactive/local-model-commands.js +290 -3
- package/dist/modes/interactive/local-model-commands.js.map +1 -1
- package/dist/modes/interactive/session-flow-commands.d.ts.map +1 -1
- package/dist/modes/interactive/session-flow-commands.js +24 -4
- package/dist/modes/interactive/session-flow-commands.js.map +1 -1
- package/dist/utils/fs-watch.d.ts +11 -0
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +20 -2
- package/dist/utils/fs-watch.js.map +1 -1
- package/dist/utils/highlight-js-languages.d.ts +4 -0
- package/dist/utils/highlight-js-languages.d.ts.map +1 -0
- package/dist/utils/highlight-js-languages.js +573 -0
- package/dist/utils/highlight-js-languages.js.map +1 -0
- package/dist/utils/shell.d.ts +7 -1
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +21 -6
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +53 -5
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +112 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/process-matrix.md +120 -0
- package/docs/settings.md +3 -0
- package/docs/tmux-agent-manager.md +85 -2
- package/docs/windows.md +52 -3
- package/docs/work-directory.md +29 -0
- package/docs/worktree-sync.md +250 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/npm-shrinkwrap.json +12 -12
- package/package.json +10 -4
- package/docs/integration-sweep-builder-blueprint-2026-07-09.md +0 -365
- package/docs/integration-sweep-resume-2026-07-09.md +0 -407
|
@@ -9,6 +9,17 @@ export interface LocalRegistrationResult {
|
|
|
9
9
|
export declare const OLLAMA_PROVIDER = "ollama";
|
|
10
10
|
/** Provider name for pi-managed Hugging Face Transformers sidecar models. */
|
|
11
11
|
export declare const HF_TRANSFORMERS_PROVIDER = "pi-hf-transformers";
|
|
12
|
+
/**
|
|
13
|
+
* Provider name for pi-managed prism llama.cpp models (Bonsai-27B and future curated prism-ml
|
|
14
|
+
* models). This is the built-in `KnownProvider` "llama-cpp" (see packages/ai/src/types.ts and the
|
|
15
|
+
* static `llama-cpp/local` catalog entry in models.generated.ts for a user-run server on the
|
|
16
|
+
* conventional port 8080) — model-registry.ts already treats it as auth-exempt, so registration
|
|
17
|
+
* here never needs a synthetic apiKey the way registerTransformersModel does. Because it is a
|
|
18
|
+
* SHARED built-in namespace (not a pi-invented provider name like the two above), registration only
|
|
19
|
+
* ever touches this provider's `models` array — never the whole provider object — so a user's own
|
|
20
|
+
* hand-authored `llama-cpp` override (e.g. for their own server) is never destroyed.
|
|
21
|
+
*/
|
|
22
|
+
export declare const PRISM_LLAMACPP_PROVIDER = "llama-cpp";
|
|
12
23
|
export declare function registerLocalModel(args: {
|
|
13
24
|
agentDir: string;
|
|
14
25
|
ref: string;
|
|
@@ -22,6 +33,23 @@ export declare function registerTransformersModel(args: {
|
|
|
22
33
|
baseUrl: string;
|
|
23
34
|
contextWindow?: number;
|
|
24
35
|
}): LocalRegistrationResult;
|
|
36
|
+
/**
|
|
37
|
+
* Register a pi-managed prism llama.cpp model (e.g. Bonsai-27B) under the shared built-in
|
|
38
|
+
* "llama-cpp" provider. Unlike registerLocalModel/registerTransformersModel, this never writes
|
|
39
|
+
* provider-level baseUrl/api/apiKey: "llama-cpp" is a built-in KnownProvider, so model-registry.ts
|
|
40
|
+
* inherits api/baseUrl defaults from the built-in `llama-cpp/local` catalog entry when a model
|
|
41
|
+
* definition omits them, and treats the whole provider as auth-exempt regardless. Each model
|
|
42
|
+
* definition still sets its OWN baseUrl explicitly (this server's actual host:port), which
|
|
43
|
+
* model-registry.ts's `modelDef.baseUrl ?? providerConfig.baseUrl ?? builtInDefaults?.baseUrl`
|
|
44
|
+
* precedence picks up ahead of the built-in default.
|
|
45
|
+
*/
|
|
46
|
+
export declare function registerPrismLlamaCppModel(args: {
|
|
47
|
+
agentDir: string;
|
|
48
|
+
modelId: string;
|
|
49
|
+
baseUrl: string;
|
|
50
|
+
contextWindow: number;
|
|
51
|
+
servedContextWindow?: number;
|
|
52
|
+
}): LocalRegistrationResult;
|
|
25
53
|
export declare function unregisterLocalModel(args: {
|
|
26
54
|
agentDir: string;
|
|
27
55
|
ref: string;
|
|
@@ -30,4 +58,16 @@ export declare function unregisterTransformersModel(args: {
|
|
|
30
58
|
agentDir: string;
|
|
31
59
|
modelId: string;
|
|
32
60
|
}): LocalRegistrationResult;
|
|
61
|
+
/**
|
|
62
|
+
* Drop a pi-registered model entry from the shared "llama-cpp" provider. Deliberately never
|
|
63
|
+
* deletes the whole provider object even when its `models` array empties out — see
|
|
64
|
+
* {@link PRISM_LLAMACPP_PROVIDER}'s doc comment: unlike OLLAMA_PROVIDER/HF_TRANSFORMERS_PROVIDER
|
|
65
|
+
* (pi-invented namespaces pi fully owns), "llama-cpp" is a built-in provider a user may have
|
|
66
|
+
* independently configured (e.g. a baseUrl override for their own server); this must not remove
|
|
67
|
+
* fields it didn't write.
|
|
68
|
+
*/
|
|
69
|
+
export declare function unregisterPrismLlamaCppModel(args: {
|
|
70
|
+
agentDir: string;
|
|
71
|
+
modelId: string;
|
|
72
|
+
}): LocalRegistrationResult;
|
|
33
73
|
//# sourceMappingURL=local-registration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-registration.d.ts","sourceRoot":"","sources":["../../../src/core/models/local-registration.ts"],"names":[],"mappings":"AA4CA,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,2FAA2F;AAC3F,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAyC7D,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,uBAAuB,CAoC1B;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,uBAAuB,CAqC1B;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAgBrG;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAchH","sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Persistent registration for pulled local models: merges an \"ollama\" provider entry into the\n * user's `<agentDir>/models.json` — the exact file ModelRegistry loads at startup — so a pulled\n * model resolves as `ollama/<ref>` immediately AND across sessions (usable as session model,\n * lane model, judge, or curator).\n *\n * Non-destructive contract: the file is parsed with STRICT JSON first; a file that only parses\n * with comments/relaxed syntax is the user's hand-authored config and is never rewritten — the\n * caller gets `manualSnippet` to show instead.\n */\n\ninterface ModelsJsonModel {\n\tid: string;\n\tname?: string;\n\tapi?: string;\n\tbaseUrl?: string;\n\tcontextWindow?: number;\n\t/** Measured by the local capacity probe; compaction uses min(contextWindow, servedContextWindow). */\n\tservedContextWindow?: number;\n\tmaxTokens?: number;\n\treasoning?: boolean;\n\ttextToolCallProtocol?: boolean;\n\tinput?: string[];\n\tcost?: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\tcompat?: Record<string, unknown>;\n}\n\ninterface ModelsJson {\n\tproviders: Record<\n\t\tstring,\n\t\t{\n\t\t\tbaseUrl?: string;\n\t\t\tapi?: string;\n\t\t\tapiKey?: string;\n\t\t\tmodels?: ModelsJsonModel[];\n\t\t\t[key: string]: unknown;\n\t\t}\n\t>;\n\t[key: string]: unknown;\n}\n\nexport interface LocalRegistrationResult {\n\tok: boolean;\n\tmodelsJsonPath: string;\n\treason?: string;\n\t/** When the file cannot be safely rewritten: the entry the user should add by hand. */\n\tmanualSnippet?: string;\n}\n\n/** Provider name pi registers pulled local models under (see registerLocalModel below). */\nexport const OLLAMA_PROVIDER = \"ollama\";\n/** Provider name for pi-managed Hugging Face Transformers sidecar models. */\nexport const HF_TRANSFORMERS_PROVIDER = \"pi-hf-transformers\";\n\nfunction localModelEntry(ref: string, contextWindow: number, servedContextWindow?: number): ModelsJsonModel {\n\treturn {\n\t\tid: ref,\n\t\tname: ref,\n\t\tcontextWindow,\n\t\t...(servedContextWindow !== undefined ? { servedContextWindow } : {}),\n\t\tmaxTokens: 2048,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n\nfunction transformersModelEntry(args: { modelId: string; baseUrl: string; contextWindow?: number }): ModelsJsonModel {\n\treturn {\n\t\tid: args.modelId,\n\t\tname: args.modelId,\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tcontextWindow: args.contextWindow ?? 131_072,\n\t\tmaxTokens: 1024,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcompat: { supportsUsageInStreaming: false },\n\t};\n}\n\nfunction loadStrict(path: string): { json?: ModelsJson; reason?: string } {\n\tif (!existsSync(path)) return { json: { providers: {} } };\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\")) as ModelsJson;\n\t\tif (!parsed || typeof parsed !== \"object\") return { reason: \"models.json is not a JSON object\" };\n\t\tparsed.providers = parsed.providers ?? {};\n\t\treturn { json: parsed };\n\t} catch {\n\t\treturn { reason: \"models.json uses comments/relaxed JSON — pi will not rewrite a hand-authored file\" };\n\t}\n}\n\nexport function registerLocalModel(args: {\n\tagentDir: string;\n\tref: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n\tservedContextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst contextWindow = args.contextWindow ?? 8192;\n\tconst entry = localModelEntry(args.ref, contextWindow, args.servedContextWindow);\n\tconst providerBase = {\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"ollama\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [OLLAMA_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[OLLAMA_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.ref);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function registerTransformersModel(args: {\n\tagentDir: string;\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst entry = transformersModelEntry(args);\n\tconst providerBase = {\n\t\tname: \"Hugging Face Transformers (pi-managed)\",\n\t\tbaseUrl: entry.baseUrl,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"pi-transformers\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [HF_TRANSFORMERS_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[HF_TRANSFORMERS_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tprovider.name ??= providerBase.name;\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.modelId);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterLocalModel(args: { agentDir: string; ref: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.ref);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\t// Drop the whole provider entry when its last pi-registered model goes (leave user fields alone\n\t// if they added any models themselves — only an all-pi-managed empty list is removed).\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[OLLAMA_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterTransformersModel(args: { agentDir: string; modelId: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.modelId);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[HF_TRANSFORMERS_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"local-registration.d.ts","sourceRoot":"","sources":["../../../src/core/models/local-registration.ts"],"names":[],"mappings":"AA4CA,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,uFAAuF;IACvF,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,2FAA2F;AAC3F,eAAO,MAAM,eAAe,WAAW,CAAC;AACxC,6EAA6E;AAC7E,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D;;;;;;;;;GASG;AACH,eAAO,MAAM,uBAAuB,cAAc,CAAC;AA8DnD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,uBAAuB,CAoC1B;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB,GAAG,uBAAuB,CAqC1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B,GAAG,uBAAuB,CA4B1B;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAgBrG;AAED,wBAAgB,2BAA2B,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAchH;AAED;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,IAAI,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,uBAAuB,CAWjH","sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { configFile } from \"../agent-paths.ts\";\n\n/**\n * Persistent registration for pulled local models: merges an \"ollama\" provider entry into the\n * user's `<agentDir>/models.json` — the exact file ModelRegistry loads at startup — so a pulled\n * model resolves as `ollama/<ref>` immediately AND across sessions (usable as session model,\n * lane model, judge, or curator).\n *\n * Non-destructive contract: the file is parsed with STRICT JSON first; a file that only parses\n * with comments/relaxed syntax is the user's hand-authored config and is never rewritten — the\n * caller gets `manualSnippet` to show instead.\n */\n\ninterface ModelsJsonModel {\n\tid: string;\n\tname?: string;\n\tapi?: string;\n\tbaseUrl?: string;\n\tcontextWindow?: number;\n\t/** Measured by the local capacity probe; compaction uses min(contextWindow, servedContextWindow). */\n\tservedContextWindow?: number;\n\tmaxTokens?: number;\n\treasoning?: boolean;\n\ttextToolCallProtocol?: boolean;\n\tinput?: string[];\n\tcost?: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\tcompat?: Record<string, unknown>;\n}\n\ninterface ModelsJson {\n\tproviders: Record<\n\t\tstring,\n\t\t{\n\t\t\tbaseUrl?: string;\n\t\t\tapi?: string;\n\t\t\tapiKey?: string;\n\t\t\tmodels?: ModelsJsonModel[];\n\t\t\t[key: string]: unknown;\n\t\t}\n\t>;\n\t[key: string]: unknown;\n}\n\nexport interface LocalRegistrationResult {\n\tok: boolean;\n\tmodelsJsonPath: string;\n\treason?: string;\n\t/** When the file cannot be safely rewritten: the entry the user should add by hand. */\n\tmanualSnippet?: string;\n}\n\n/** Provider name pi registers pulled local models under (see registerLocalModel below). */\nexport const OLLAMA_PROVIDER = \"ollama\";\n/** Provider name for pi-managed Hugging Face Transformers sidecar models. */\nexport const HF_TRANSFORMERS_PROVIDER = \"pi-hf-transformers\";\n/**\n * Provider name for pi-managed prism llama.cpp models (Bonsai-27B and future curated prism-ml\n * models). This is the built-in `KnownProvider` \"llama-cpp\" (see packages/ai/src/types.ts and the\n * static `llama-cpp/local` catalog entry in models.generated.ts for a user-run server on the\n * conventional port 8080) — model-registry.ts already treats it as auth-exempt, so registration\n * here never needs a synthetic apiKey the way registerTransformersModel does. Because it is a\n * SHARED built-in namespace (not a pi-invented provider name like the two above), registration only\n * ever touches this provider's `models` array — never the whole provider object — so a user's own\n * hand-authored `llama-cpp` override (e.g. for their own server) is never destroyed.\n */\nexport const PRISM_LLAMACPP_PROVIDER = \"llama-cpp\";\n\nfunction localModelEntry(ref: string, contextWindow: number, servedContextWindow?: number): ModelsJsonModel {\n\treturn {\n\t\tid: ref,\n\t\tname: ref,\n\t\tcontextWindow,\n\t\t...(servedContextWindow !== undefined ? { servedContextWindow } : {}),\n\t\tmaxTokens: 2048,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n\nfunction transformersModelEntry(args: { modelId: string; baseUrl: string; contextWindow?: number }): ModelsJsonModel {\n\treturn {\n\t\tid: args.modelId,\n\t\tname: args.modelId,\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tcontextWindow: args.contextWindow ?? 131_072,\n\t\tmaxTokens: 1024,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcompat: { supportsUsageInStreaming: false },\n\t};\n}\n\nfunction prismLlamaCppModelEntry(args: {\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow: number;\n\tservedContextWindow: number;\n}): ModelsJsonModel {\n\treturn {\n\t\tid: args.modelId,\n\t\tname: args.modelId,\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tcontextWindow: args.contextWindow,\n\t\tservedContextWindow: args.servedContextWindow,\n\t\tmaxTokens: 2048,\n\t\treasoning: false,\n\t\t// Vision rides along via the served mmproj file — unlike localModelEntry's Ollama entries,\n\t\t// which are text-only until per-model vision plumbing exists there too.\n\t\tinput: [\"text\", \"image\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n\nfunction loadStrict(path: string): { json?: ModelsJson; reason?: string } {\n\tif (!existsSync(path)) return { json: { providers: {} } };\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\")) as ModelsJson;\n\t\tif (!parsed || typeof parsed !== \"object\") return { reason: \"models.json is not a JSON object\" };\n\t\tparsed.providers = parsed.providers ?? {};\n\t\treturn { json: parsed };\n\t} catch {\n\t\treturn { reason: \"models.json uses comments/relaxed JSON — pi will not rewrite a hand-authored file\" };\n\t}\n}\n\nexport function registerLocalModel(args: {\n\tagentDir: string;\n\tref: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n\tservedContextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst contextWindow = args.contextWindow ?? 8192;\n\tconst entry = localModelEntry(args.ref, contextWindow, args.servedContextWindow);\n\tconst providerBase = {\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"ollama\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [OLLAMA_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[OLLAMA_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.ref);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function registerTransformersModel(args: {\n\tagentDir: string;\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst entry = transformersModelEntry(args);\n\tconst providerBase = {\n\t\tname: \"Hugging Face Transformers (pi-managed)\",\n\t\tbaseUrl: entry.baseUrl,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"pi-transformers\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [HF_TRANSFORMERS_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[HF_TRANSFORMERS_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tprovider.name ??= providerBase.name;\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.modelId);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\n/**\n * Register a pi-managed prism llama.cpp model (e.g. Bonsai-27B) under the shared built-in\n * \"llama-cpp\" provider. Unlike registerLocalModel/registerTransformersModel, this never writes\n * provider-level baseUrl/api/apiKey: \"llama-cpp\" is a built-in KnownProvider, so model-registry.ts\n * inherits api/baseUrl defaults from the built-in `llama-cpp/local` catalog entry when a model\n * definition omits them, and treats the whole provider as auth-exempt regardless. Each model\n * definition still sets its OWN baseUrl explicitly (this server's actual host:port), which\n * model-registry.ts's `modelDef.baseUrl ?? providerConfig.baseUrl ?? builtInDefaults?.baseUrl`\n * precedence picks up ahead of the built-in default.\n */\nexport function registerPrismLlamaCppModel(args: {\n\tagentDir: string;\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow: number;\n\tservedContextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst entry = prismLlamaCppModelEntry({\n\t\tmodelId: args.modelId,\n\t\tbaseUrl: args.baseUrl,\n\t\tcontextWindow: args.contextWindow,\n\t\tservedContextWindow: args.servedContextWindow ?? args.contextWindow,\n\t});\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify({ providers: { [PRISM_LLAMACPP_PROVIDER]: { models: [entry] } } }, null, \"\\t\"),\n\t\t};\n\t}\n\tjson.providers[PRISM_LLAMACPP_PROVIDER] ??= { models: [] };\n\tconst provider = json.providers[PRISM_LLAMACPP_PROVIDER];\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.modelId);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterLocalModel(args: { agentDir: string; ref: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.ref);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\t// Drop the whole provider entry when its last pi-registered model goes (leave user fields alone\n\t// if they added any models themselves — only an all-pi-managed empty list is removed).\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[OLLAMA_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterTransformersModel(args: { agentDir: string; modelId: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.modelId);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[HF_TRANSFORMERS_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\n/**\n * Drop a pi-registered model entry from the shared \"llama-cpp\" provider. Deliberately never\n * deletes the whole provider object even when its `models` array empties out — see\n * {@link PRISM_LLAMACPP_PROVIDER}'s doc comment: unlike OLLAMA_PROVIDER/HF_TRANSFORMERS_PROVIDER\n * (pi-invented namespaces pi fully owns), \"llama-cpp\" is a built-in provider a user may have\n * independently configured (e.g. a baseUrl override for their own server); this must not remove\n * fields it didn't write.\n */\nexport function unregisterPrismLlamaCppModel(args: { agentDir: string; modelId: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[PRISM_LLAMACPP_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.modelId);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n"]}
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
-
import {
|
|
2
|
+
import { configFile } from "../agent-paths.js";
|
|
3
3
|
/** Provider name pi registers pulled local models under (see registerLocalModel below). */
|
|
4
4
|
export const OLLAMA_PROVIDER = "ollama";
|
|
5
5
|
/** Provider name for pi-managed Hugging Face Transformers sidecar models. */
|
|
6
6
|
export const HF_TRANSFORMERS_PROVIDER = "pi-hf-transformers";
|
|
7
|
+
/**
|
|
8
|
+
* Provider name for pi-managed prism llama.cpp models (Bonsai-27B and future curated prism-ml
|
|
9
|
+
* models). This is the built-in `KnownProvider` "llama-cpp" (see packages/ai/src/types.ts and the
|
|
10
|
+
* static `llama-cpp/local` catalog entry in models.generated.ts for a user-run server on the
|
|
11
|
+
* conventional port 8080) — model-registry.ts already treats it as auth-exempt, so registration
|
|
12
|
+
* here never needs a synthetic apiKey the way registerTransformersModel does. Because it is a
|
|
13
|
+
* SHARED built-in namespace (not a pi-invented provider name like the two above), registration only
|
|
14
|
+
* ever touches this provider's `models` array — never the whole provider object — so a user's own
|
|
15
|
+
* hand-authored `llama-cpp` override (e.g. for their own server) is never destroyed.
|
|
16
|
+
*/
|
|
17
|
+
export const PRISM_LLAMACPP_PROVIDER = "llama-cpp";
|
|
7
18
|
function localModelEntry(ref, contextWindow, servedContextWindow) {
|
|
8
19
|
return {
|
|
9
20
|
id: ref,
|
|
@@ -29,6 +40,21 @@ function transformersModelEntry(args) {
|
|
|
29
40
|
compat: { supportsUsageInStreaming: false },
|
|
30
41
|
};
|
|
31
42
|
}
|
|
43
|
+
function prismLlamaCppModelEntry(args) {
|
|
44
|
+
return {
|
|
45
|
+
id: args.modelId,
|
|
46
|
+
name: args.modelId,
|
|
47
|
+
baseUrl: `${args.baseUrl.replace(/\/$/, "")}/v1`,
|
|
48
|
+
contextWindow: args.contextWindow,
|
|
49
|
+
servedContextWindow: args.servedContextWindow,
|
|
50
|
+
maxTokens: 2048,
|
|
51
|
+
reasoning: false,
|
|
52
|
+
// Vision rides along via the served mmproj file — unlike localModelEntry's Ollama entries,
|
|
53
|
+
// which are text-only until per-model vision plumbing exists there too.
|
|
54
|
+
input: ["text", "image"],
|
|
55
|
+
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
32
58
|
function loadStrict(path) {
|
|
33
59
|
if (!existsSync(path))
|
|
34
60
|
return { json: { providers: {} } };
|
|
@@ -44,7 +70,7 @@ function loadStrict(path) {
|
|
|
44
70
|
}
|
|
45
71
|
}
|
|
46
72
|
export function registerLocalModel(args) {
|
|
47
|
-
const modelsJsonPath =
|
|
73
|
+
const modelsJsonPath = configFile(args.agentDir, "models.json");
|
|
48
74
|
const contextWindow = args.contextWindow ?? 8192;
|
|
49
75
|
const entry = localModelEntry(args.ref, contextWindow, args.servedContextWindow);
|
|
50
76
|
const providerBase = {
|
|
@@ -78,7 +104,7 @@ export function registerLocalModel(args) {
|
|
|
78
104
|
return { ok: true, modelsJsonPath };
|
|
79
105
|
}
|
|
80
106
|
export function registerTransformersModel(args) {
|
|
81
|
-
const modelsJsonPath =
|
|
107
|
+
const modelsJsonPath = configFile(args.agentDir, "models.json");
|
|
82
108
|
const entry = transformersModelEntry(args);
|
|
83
109
|
const providerBase = {
|
|
84
110
|
name: "Hugging Face Transformers (pi-managed)",
|
|
@@ -112,8 +138,48 @@ export function registerTransformersModel(args) {
|
|
|
112
138
|
writeFileSync(modelsJsonPath, `${JSON.stringify(json, null, "\t")}\n`, "utf-8");
|
|
113
139
|
return { ok: true, modelsJsonPath };
|
|
114
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Register a pi-managed prism llama.cpp model (e.g. Bonsai-27B) under the shared built-in
|
|
143
|
+
* "llama-cpp" provider. Unlike registerLocalModel/registerTransformersModel, this never writes
|
|
144
|
+
* provider-level baseUrl/api/apiKey: "llama-cpp" is a built-in KnownProvider, so model-registry.ts
|
|
145
|
+
* inherits api/baseUrl defaults from the built-in `llama-cpp/local` catalog entry when a model
|
|
146
|
+
* definition omits them, and treats the whole provider as auth-exempt regardless. Each model
|
|
147
|
+
* definition still sets its OWN baseUrl explicitly (this server's actual host:port), which
|
|
148
|
+
* model-registry.ts's `modelDef.baseUrl ?? providerConfig.baseUrl ?? builtInDefaults?.baseUrl`
|
|
149
|
+
* precedence picks up ahead of the built-in default.
|
|
150
|
+
*/
|
|
151
|
+
export function registerPrismLlamaCppModel(args) {
|
|
152
|
+
const modelsJsonPath = configFile(args.agentDir, "models.json");
|
|
153
|
+
const entry = prismLlamaCppModelEntry({
|
|
154
|
+
modelId: args.modelId,
|
|
155
|
+
baseUrl: args.baseUrl,
|
|
156
|
+
contextWindow: args.contextWindow,
|
|
157
|
+
servedContextWindow: args.servedContextWindow ?? args.contextWindow,
|
|
158
|
+
});
|
|
159
|
+
const { json, reason } = loadStrict(modelsJsonPath);
|
|
160
|
+
if (!json) {
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
modelsJsonPath,
|
|
164
|
+
reason,
|
|
165
|
+
manualSnippet: JSON.stringify({ providers: { [PRISM_LLAMACPP_PROVIDER]: { models: [entry] } } }, null, "\t"),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
json.providers[PRISM_LLAMACPP_PROVIDER] ??= { models: [] };
|
|
169
|
+
const provider = json.providers[PRISM_LLAMACPP_PROVIDER];
|
|
170
|
+
provider.models ??= [];
|
|
171
|
+
const existing = provider.models.findIndex((model) => model.id === args.modelId);
|
|
172
|
+
if (existing >= 0) {
|
|
173
|
+
provider.models[existing] = { ...provider.models[existing], ...entry };
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
provider.models.push(entry);
|
|
177
|
+
}
|
|
178
|
+
writeFileSync(modelsJsonPath, `${JSON.stringify(json, null, "\t")}\n`, "utf-8");
|
|
179
|
+
return { ok: true, modelsJsonPath };
|
|
180
|
+
}
|
|
115
181
|
export function unregisterLocalModel(args) {
|
|
116
|
-
const modelsJsonPath =
|
|
182
|
+
const modelsJsonPath = configFile(args.agentDir, "models.json");
|
|
117
183
|
const { json, reason } = loadStrict(modelsJsonPath);
|
|
118
184
|
if (!json)
|
|
119
185
|
return { ok: false, modelsJsonPath, reason };
|
|
@@ -133,7 +199,7 @@ export function unregisterLocalModel(args) {
|
|
|
133
199
|
return { ok: true, modelsJsonPath };
|
|
134
200
|
}
|
|
135
201
|
export function unregisterTransformersModel(args) {
|
|
136
|
-
const modelsJsonPath =
|
|
202
|
+
const modelsJsonPath = configFile(args.agentDir, "models.json");
|
|
137
203
|
const { json, reason } = loadStrict(modelsJsonPath);
|
|
138
204
|
if (!json)
|
|
139
205
|
return { ok: false, modelsJsonPath, reason };
|
|
@@ -150,4 +216,27 @@ export function unregisterTransformersModel(args) {
|
|
|
150
216
|
writeFileSync(modelsJsonPath, `${JSON.stringify(json, null, "\t")}\n`, "utf-8");
|
|
151
217
|
return { ok: true, modelsJsonPath };
|
|
152
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* Drop a pi-registered model entry from the shared "llama-cpp" provider. Deliberately never
|
|
221
|
+
* deletes the whole provider object even when its `models` array empties out — see
|
|
222
|
+
* {@link PRISM_LLAMACPP_PROVIDER}'s doc comment: unlike OLLAMA_PROVIDER/HF_TRANSFORMERS_PROVIDER
|
|
223
|
+
* (pi-invented namespaces pi fully owns), "llama-cpp" is a built-in provider a user may have
|
|
224
|
+
* independently configured (e.g. a baseUrl override for their own server); this must not remove
|
|
225
|
+
* fields it didn't write.
|
|
226
|
+
*/
|
|
227
|
+
export function unregisterPrismLlamaCppModel(args) {
|
|
228
|
+
const modelsJsonPath = configFile(args.agentDir, "models.json");
|
|
229
|
+
const { json, reason } = loadStrict(modelsJsonPath);
|
|
230
|
+
if (!json)
|
|
231
|
+
return { ok: false, modelsJsonPath, reason };
|
|
232
|
+
const provider = json.providers[PRISM_LLAMACPP_PROVIDER];
|
|
233
|
+
if (!provider?.models)
|
|
234
|
+
return { ok: true, modelsJsonPath };
|
|
235
|
+
const before = provider.models.length;
|
|
236
|
+
provider.models = provider.models.filter((model) => model.id !== args.modelId);
|
|
237
|
+
if (provider.models.length === before)
|
|
238
|
+
return { ok: true, modelsJsonPath };
|
|
239
|
+
writeFileSync(modelsJsonPath, `${JSON.stringify(json, null, "\t")}\n`, "utf-8");
|
|
240
|
+
return { ok: true, modelsJsonPath };
|
|
241
|
+
}
|
|
153
242
|
//# sourceMappingURL=local-registration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-registration.js","sourceRoot":"","sources":["../../../src/core/models/local-registration.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Persistent registration for pulled local models: merges an \"ollama\" provider entry into the\n * user's `<agentDir>/models.json` — the exact file ModelRegistry loads at startup — so a pulled\n * model resolves as `ollama/<ref>` immediately AND across sessions (usable as session model,\n * lane model, judge, or curator).\n *\n * Non-destructive contract: the file is parsed with STRICT JSON first; a file that only parses\n * with comments/relaxed syntax is the user's hand-authored config and is never rewritten — the\n * caller gets `manualSnippet` to show instead.\n */\n\ninterface ModelsJsonModel {\n\tid: string;\n\tname?: string;\n\tapi?: string;\n\tbaseUrl?: string;\n\tcontextWindow?: number;\n\t/** Measured by the local capacity probe; compaction uses min(contextWindow, servedContextWindow). */\n\tservedContextWindow?: number;\n\tmaxTokens?: number;\n\treasoning?: boolean;\n\ttextToolCallProtocol?: boolean;\n\tinput?: string[];\n\tcost?: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\tcompat?: Record<string, unknown>;\n}\n\ninterface ModelsJson {\n\tproviders: Record<\n\t\tstring,\n\t\t{\n\t\t\tbaseUrl?: string;\n\t\t\tapi?: string;\n\t\t\tapiKey?: string;\n\t\t\tmodels?: ModelsJsonModel[];\n\t\t\t[key: string]: unknown;\n\t\t}\n\t>;\n\t[key: string]: unknown;\n}\n\nexport interface LocalRegistrationResult {\n\tok: boolean;\n\tmodelsJsonPath: string;\n\treason?: string;\n\t/** When the file cannot be safely rewritten: the entry the user should add by hand. */\n\tmanualSnippet?: string;\n}\n\n/** Provider name pi registers pulled local models under (see registerLocalModel below). */\nexport const OLLAMA_PROVIDER = \"ollama\";\n/** Provider name for pi-managed Hugging Face Transformers sidecar models. */\nexport const HF_TRANSFORMERS_PROVIDER = \"pi-hf-transformers\";\n\nfunction localModelEntry(ref: string, contextWindow: number, servedContextWindow?: number): ModelsJsonModel {\n\treturn {\n\t\tid: ref,\n\t\tname: ref,\n\t\tcontextWindow,\n\t\t...(servedContextWindow !== undefined ? { servedContextWindow } : {}),\n\t\tmaxTokens: 2048,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n\nfunction transformersModelEntry(args: { modelId: string; baseUrl: string; contextWindow?: number }): ModelsJsonModel {\n\treturn {\n\t\tid: args.modelId,\n\t\tname: args.modelId,\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tcontextWindow: args.contextWindow ?? 131_072,\n\t\tmaxTokens: 1024,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcompat: { supportsUsageInStreaming: false },\n\t};\n}\n\nfunction loadStrict(path: string): { json?: ModelsJson; reason?: string } {\n\tif (!existsSync(path)) return { json: { providers: {} } };\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\")) as ModelsJson;\n\t\tif (!parsed || typeof parsed !== \"object\") return { reason: \"models.json is not a JSON object\" };\n\t\tparsed.providers = parsed.providers ?? {};\n\t\treturn { json: parsed };\n\t} catch {\n\t\treturn { reason: \"models.json uses comments/relaxed JSON — pi will not rewrite a hand-authored file\" };\n\t}\n}\n\nexport function registerLocalModel(args: {\n\tagentDir: string;\n\tref: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n\tservedContextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst contextWindow = args.contextWindow ?? 8192;\n\tconst entry = localModelEntry(args.ref, contextWindow, args.servedContextWindow);\n\tconst providerBase = {\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"ollama\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [OLLAMA_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[OLLAMA_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.ref);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function registerTransformersModel(args: {\n\tagentDir: string;\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst entry = transformersModelEntry(args);\n\tconst providerBase = {\n\t\tname: \"Hugging Face Transformers (pi-managed)\",\n\t\tbaseUrl: entry.baseUrl,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"pi-transformers\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [HF_TRANSFORMERS_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[HF_TRANSFORMERS_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tprovider.name ??= providerBase.name;\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.modelId);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterLocalModel(args: { agentDir: string; ref: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.ref);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\t// Drop the whole provider entry when its last pi-registered model goes (leave user fields alone\n\t// if they added any models themselves — only an all-pi-managed empty list is removed).\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[OLLAMA_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterTransformersModel(args: { agentDir: string; modelId: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = join(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.modelId);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[HF_TRANSFORMERS_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"local-registration.js","sourceRoot":"","sources":["../../../src/core/models/local-registration.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { configFile } from \"../agent-paths.ts\";\n\n/**\n * Persistent registration for pulled local models: merges an \"ollama\" provider entry into the\n * user's `<agentDir>/models.json` — the exact file ModelRegistry loads at startup — so a pulled\n * model resolves as `ollama/<ref>` immediately AND across sessions (usable as session model,\n * lane model, judge, or curator).\n *\n * Non-destructive contract: the file is parsed with STRICT JSON first; a file that only parses\n * with comments/relaxed syntax is the user's hand-authored config and is never rewritten — the\n * caller gets `manualSnippet` to show instead.\n */\n\ninterface ModelsJsonModel {\n\tid: string;\n\tname?: string;\n\tapi?: string;\n\tbaseUrl?: string;\n\tcontextWindow?: number;\n\t/** Measured by the local capacity probe; compaction uses min(contextWindow, servedContextWindow). */\n\tservedContextWindow?: number;\n\tmaxTokens?: number;\n\treasoning?: boolean;\n\ttextToolCallProtocol?: boolean;\n\tinput?: string[];\n\tcost?: { input: number; output: number; cacheRead: number; cacheWrite: number };\n\tcompat?: Record<string, unknown>;\n}\n\ninterface ModelsJson {\n\tproviders: Record<\n\t\tstring,\n\t\t{\n\t\t\tbaseUrl?: string;\n\t\t\tapi?: string;\n\t\t\tapiKey?: string;\n\t\t\tmodels?: ModelsJsonModel[];\n\t\t\t[key: string]: unknown;\n\t\t}\n\t>;\n\t[key: string]: unknown;\n}\n\nexport interface LocalRegistrationResult {\n\tok: boolean;\n\tmodelsJsonPath: string;\n\treason?: string;\n\t/** When the file cannot be safely rewritten: the entry the user should add by hand. */\n\tmanualSnippet?: string;\n}\n\n/** Provider name pi registers pulled local models under (see registerLocalModel below). */\nexport const OLLAMA_PROVIDER = \"ollama\";\n/** Provider name for pi-managed Hugging Face Transformers sidecar models. */\nexport const HF_TRANSFORMERS_PROVIDER = \"pi-hf-transformers\";\n/**\n * Provider name for pi-managed prism llama.cpp models (Bonsai-27B and future curated prism-ml\n * models). This is the built-in `KnownProvider` \"llama-cpp\" (see packages/ai/src/types.ts and the\n * static `llama-cpp/local` catalog entry in models.generated.ts for a user-run server on the\n * conventional port 8080) — model-registry.ts already treats it as auth-exempt, so registration\n * here never needs a synthetic apiKey the way registerTransformersModel does. Because it is a\n * SHARED built-in namespace (not a pi-invented provider name like the two above), registration only\n * ever touches this provider's `models` array — never the whole provider object — so a user's own\n * hand-authored `llama-cpp` override (e.g. for their own server) is never destroyed.\n */\nexport const PRISM_LLAMACPP_PROVIDER = \"llama-cpp\";\n\nfunction localModelEntry(ref: string, contextWindow: number, servedContextWindow?: number): ModelsJsonModel {\n\treturn {\n\t\tid: ref,\n\t\tname: ref,\n\t\tcontextWindow,\n\t\t...(servedContextWindow !== undefined ? { servedContextWindow } : {}),\n\t\tmaxTokens: 2048,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n\nfunction transformersModelEntry(args: { modelId: string; baseUrl: string; contextWindow?: number }): ModelsJsonModel {\n\treturn {\n\t\tid: args.modelId,\n\t\tname: args.modelId,\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tcontextWindow: args.contextWindow ?? 131_072,\n\t\tmaxTokens: 1024,\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcompat: { supportsUsageInStreaming: false },\n\t};\n}\n\nfunction prismLlamaCppModelEntry(args: {\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow: number;\n\tservedContextWindow: number;\n}): ModelsJsonModel {\n\treturn {\n\t\tid: args.modelId,\n\t\tname: args.modelId,\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tcontextWindow: args.contextWindow,\n\t\tservedContextWindow: args.servedContextWindow,\n\t\tmaxTokens: 2048,\n\t\treasoning: false,\n\t\t// Vision rides along via the served mmproj file — unlike localModelEntry's Ollama entries,\n\t\t// which are text-only until per-model vision plumbing exists there too.\n\t\tinput: [\"text\", \"image\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t};\n}\n\nfunction loadStrict(path: string): { json?: ModelsJson; reason?: string } {\n\tif (!existsSync(path)) return { json: { providers: {} } };\n\ttry {\n\t\tconst parsed = JSON.parse(readFileSync(path, \"utf-8\")) as ModelsJson;\n\t\tif (!parsed || typeof parsed !== \"object\") return { reason: \"models.json is not a JSON object\" };\n\t\tparsed.providers = parsed.providers ?? {};\n\t\treturn { json: parsed };\n\t} catch {\n\t\treturn { reason: \"models.json uses comments/relaxed JSON — pi will not rewrite a hand-authored file\" };\n\t}\n}\n\nexport function registerLocalModel(args: {\n\tagentDir: string;\n\tref: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n\tservedContextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst contextWindow = args.contextWindow ?? 8192;\n\tconst entry = localModelEntry(args.ref, contextWindow, args.servedContextWindow);\n\tconst providerBase = {\n\t\tbaseUrl: `${args.baseUrl.replace(/\\/$/, \"\")}/v1`,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"ollama\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [OLLAMA_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[OLLAMA_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.ref);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function registerTransformersModel(args: {\n\tagentDir: string;\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst entry = transformersModelEntry(args);\n\tconst providerBase = {\n\t\tname: \"Hugging Face Transformers (pi-managed)\",\n\t\tbaseUrl: entry.baseUrl,\n\t\tapi: \"openai-completions\",\n\t\tapiKey: \"pi-transformers\",\n\t};\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify(\n\t\t\t\t{ providers: { [HF_TRANSFORMERS_PROVIDER]: { ...providerBase, models: [entry] } } },\n\t\t\t\tnull,\n\t\t\t\t\"\\t\",\n\t\t\t),\n\t\t};\n\t}\n\tjson.providers[HF_TRANSFORMERS_PROVIDER] ??= { ...providerBase, models: [] };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tprovider.name ??= providerBase.name;\n\tprovider.baseUrl ??= providerBase.baseUrl;\n\tprovider.api ??= providerBase.api;\n\tprovider.apiKey ??= providerBase.apiKey;\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.modelId);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\n/**\n * Register a pi-managed prism llama.cpp model (e.g. Bonsai-27B) under the shared built-in\n * \"llama-cpp\" provider. Unlike registerLocalModel/registerTransformersModel, this never writes\n * provider-level baseUrl/api/apiKey: \"llama-cpp\" is a built-in KnownProvider, so model-registry.ts\n * inherits api/baseUrl defaults from the built-in `llama-cpp/local` catalog entry when a model\n * definition omits them, and treats the whole provider as auth-exempt regardless. Each model\n * definition still sets its OWN baseUrl explicitly (this server's actual host:port), which\n * model-registry.ts's `modelDef.baseUrl ?? providerConfig.baseUrl ?? builtInDefaults?.baseUrl`\n * precedence picks up ahead of the built-in default.\n */\nexport function registerPrismLlamaCppModel(args: {\n\tagentDir: string;\n\tmodelId: string;\n\tbaseUrl: string;\n\tcontextWindow: number;\n\tservedContextWindow?: number;\n}): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst entry = prismLlamaCppModelEntry({\n\t\tmodelId: args.modelId,\n\t\tbaseUrl: args.baseUrl,\n\t\tcontextWindow: args.contextWindow,\n\t\tservedContextWindow: args.servedContextWindow ?? args.contextWindow,\n\t});\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\tmodelsJsonPath,\n\t\t\treason,\n\t\t\tmanualSnippet: JSON.stringify({ providers: { [PRISM_LLAMACPP_PROVIDER]: { models: [entry] } } }, null, \"\\t\"),\n\t\t};\n\t}\n\tjson.providers[PRISM_LLAMACPP_PROVIDER] ??= { models: [] };\n\tconst provider = json.providers[PRISM_LLAMACPP_PROVIDER];\n\tprovider.models ??= [];\n\tconst existing = provider.models.findIndex((model) => model.id === args.modelId);\n\tif (existing >= 0) {\n\t\tprovider.models[existing] = { ...provider.models[existing], ...entry };\n\t} else {\n\t\tprovider.models.push(entry);\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterLocalModel(args: { agentDir: string; ref: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[OLLAMA_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.ref);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\t// Drop the whole provider entry when its last pi-registered model goes (leave user fields alone\n\t// if they added any models themselves — only an all-pi-managed empty list is removed).\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[OLLAMA_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\nexport function unregisterTransformersModel(args: { agentDir: string; modelId: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[HF_TRANSFORMERS_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.modelId);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\tif (provider.models.length === 0) {\n\t\tdelete json.providers[HF_TRANSFORMERS_PROVIDER];\n\t}\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n\n/**\n * Drop a pi-registered model entry from the shared \"llama-cpp\" provider. Deliberately never\n * deletes the whole provider object even when its `models` array empties out — see\n * {@link PRISM_LLAMACPP_PROVIDER}'s doc comment: unlike OLLAMA_PROVIDER/HF_TRANSFORMERS_PROVIDER\n * (pi-invented namespaces pi fully owns), \"llama-cpp\" is a built-in provider a user may have\n * independently configured (e.g. a baseUrl override for their own server); this must not remove\n * fields it didn't write.\n */\nexport function unregisterPrismLlamaCppModel(args: { agentDir: string; modelId: string }): LocalRegistrationResult {\n\tconst modelsJsonPath = configFile(args.agentDir, \"models.json\");\n\tconst { json, reason } = loadStrict(modelsJsonPath);\n\tif (!json) return { ok: false, modelsJsonPath, reason };\n\tconst provider = json.providers[PRISM_LLAMACPP_PROVIDER];\n\tif (!provider?.models) return { ok: true, modelsJsonPath };\n\tconst before = provider.models.length;\n\tprovider.models = provider.models.filter((model) => model.id !== args.modelId);\n\tif (provider.models.length === before) return { ok: true, modelsJsonPath };\n\twriteFileSync(modelsJsonPath, `${JSON.stringify(json, null, \"\\t\")}\\n`, \"utf-8\");\n\treturn { ok: true, modelsJsonPath };\n}\n"]}
|