@iowarp/clio-coder 0.3.3 → 0.3.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/CHANGELOG.md +74 -0
- package/CONTRIBUTING.md +7 -7
- package/README.md +3 -3
- package/dist/{acp-P2AQILE2.js → acp-2BEHC4DL.js} +9 -8
- package/dist/{agents-72W3BI7I.js → agents-LNNFTM53.js} +29 -24
- package/dist/assets/codewiki.json +1 -1
- package/dist/{auth-5TWEIYDN.js → auth-KXXFI2VS.js} +14 -10
- package/dist/{chunk-GGXXDWE4.js → chunk-22NAGB7X.js} +2 -2
- package/dist/{chunk-YCWGATWI.js → chunk-24I7BN55.js} +2 -2
- package/dist/{chunk-EKMEHE4H.js → chunk-33YXPOE3.js} +2 -3
- package/dist/chunk-3BPUFZDL.js +37 -0
- package/dist/chunk-43AOLP7E.js +375 -0
- package/dist/{chunk-ZDOOVTXZ.js → chunk-4OC57DA6.js} +27 -4
- package/dist/{chunk-6SGHMWE3.js → chunk-5JGRAMKL.js} +5 -5
- package/dist/{chunk-V6RTAOC2.js → chunk-6US73PDB.js} +572 -51
- package/dist/{chunk-5UFT4SUX.js → chunk-6XXKFVSN.js} +3 -3
- package/dist/{chunk-A3CYT5EX.js → chunk-AD2SYQYC.js} +55 -2
- package/dist/chunk-AOCYTWAV.js +449 -0
- package/dist/chunk-CFGTUFWB.js +67 -0
- package/dist/chunk-CJUB2JJ2.js +1478 -0
- package/dist/{chunk-FNTMWMX5.js → chunk-CKXWIANG.js} +14 -12
- package/dist/{chunk-PIWWS5BL.js → chunk-CYQKWTG3.js} +63 -78
- package/dist/{chunk-LZSJBIVT.js → chunk-DJVECN66.js} +271 -762
- package/dist/{chunk-CBCAPZAA.js → chunk-E25LMLRW.js} +2 -2
- package/dist/{chunk-ZWMF7253.js → chunk-E2ER4LJF.js} +304 -9
- package/dist/{chunk-STBPMHSX.js → chunk-EKY57CSP.js} +51 -84
- package/dist/{chunk-DUYJ5IO6.js → chunk-EYPA3EGJ.js} +12 -4
- package/dist/{chunk-M6SHUN7Q.js → chunk-FO5ZOVUY.js} +2 -2
- package/dist/chunk-FYYLNIL5.js +313 -0
- package/dist/{chunk-OQ33BKR3.js → chunk-G7MUEIGA.js} +3 -60
- package/dist/chunk-GEYXPTRF.js +613 -0
- package/dist/chunk-GOXNB3AO.js +261 -0
- package/dist/{chunk-G4BMMOKF.js → chunk-HVDIIIQW.js} +2 -2
- package/dist/chunk-HWUFFB6L.js +83 -0
- package/dist/{chunk-4XUGQOHA.js → chunk-K7T3E2SR.js} +15 -8
- package/dist/chunk-K7VKOLQQ.js +15 -0
- package/dist/{chunk-UFIIWP2H.js → chunk-KHSFENX2.js} +8 -8
- package/dist/{chunk-BMEMKKIT.js → chunk-KOHPCX4K.js} +2 -2
- package/dist/chunk-LCGCVYZ4.js +57 -0
- package/dist/chunk-LL4KHSZI.js +22 -0
- package/dist/{chunk-PAJK6MAQ.js → chunk-LYF7OHWH.js} +42 -15
- package/dist/{chunk-POHLU5DW.js → chunk-M6L6IDJG.js} +3 -3
- package/dist/{chunk-5UUP6MWO.js → chunk-MV3K5QF2.js} +5 -436
- package/dist/{chunk-X4RCMKVQ.js → chunk-NDINPTJ4.js} +2 -2
- package/dist/{chunk-TZK7PACC.js → chunk-NILBFAPG.js} +14 -8
- package/dist/chunk-ODFEOB4F.js +1082 -0
- package/dist/{chunk-AGYYIBLL.js → chunk-OH3TOQTB.js} +6 -2
- package/dist/chunk-OZNBF4L3.js +23 -0
- package/dist/{chunk-DSELYM6W.js → chunk-PBTHKCPN.js} +30 -10
- package/dist/{verify-375KUB3Y.js → chunk-PCZJO5TI.js} +127 -42
- package/dist/{chunk-ED4KHGC3.js → chunk-PPAMZ32Z.js} +9 -2
- package/dist/{chunk-SRDMMSEP.js → chunk-QM3F2GKX.js} +1063 -1645
- package/dist/{chunk-X6IAEBZR.js → chunk-QNQHSOLF.js} +7 -7
- package/dist/{chunk-OC7FIQPC.js → chunk-R46L2BIR.js} +10 -7
- package/dist/{chunk-2TLUCQVG.js → chunk-RD5U66HV.js} +3 -3
- package/dist/{chunk-6N5PTWMY.js → chunk-RY3LY4J5.js} +50 -13
- package/dist/{chunk-OKGUZO2U.js → chunk-SPULKLCF.js} +4 -3
- package/dist/{chunk-OOJYHWRB.js → chunk-TSHXZTOQ.js} +6 -5
- package/dist/chunk-TZSKNMZG.js +434 -0
- package/dist/{chunk-7MNJORFF.js → chunk-UL3WSD3F.js} +6 -1
- package/dist/{chunk-VJWL6YS5.js → chunk-UUVG37B4.js} +2 -2
- package/dist/{chunk-COU2UHX6.js → chunk-VEZEGCGW.js} +170 -2
- package/dist/chunk-W6GROXXM.js +69 -0
- package/dist/{chunk-OAO4GE4M.js → chunk-WHGPSPT5.js} +2 -2
- package/dist/chunk-WHJYKASB.js +677 -0
- package/dist/{chunk-ORBHGJC5.js → chunk-WR67VIZY.js} +3 -3
- package/dist/{chunk-YHZX5GEU.js → chunk-XAKHZX5N.js} +2 -2
- package/dist/{chunk-TZTZS7QK.js → chunk-XE2VEJHX.js} +5 -3
- package/dist/{chunk-LM5TQCJZ.js → chunk-XF5N4U5A.js} +8 -7
- package/dist/{chunk-LWLEKMDQ.js → chunk-XXQNGV4M.js} +1073 -552
- package/dist/{chunk-KZWTDYJF.js → chunk-XYDYPRZI.js} +7 -7
- package/dist/chunk-ZGVHUX3M.js +66 -0
- package/dist/{chunk-LW6DSM3M.js → chunk-ZRGEBJ4T.js} +1192 -1119
- package/dist/{chunk-2DJ2KNFG.js → chunk-ZXF4XRKW.js} +202 -40
- package/dist/chunk-ZZMN5OM4.js +122 -0
- package/dist/cli/index.js +34 -30
- package/dist/{clio-JOU4FXVA.js → clio-M2KGYUFZ.js} +7 -6
- package/dist/{code-nav-7AX6FYE6.js → code-nav-GQNL7XA6.js} +8 -6
- package/dist/codewiki/build-worker.js +4 -4
- package/dist/{components-KELWS457.js → components-5TTYYX6G.js} +3 -3
- package/dist/{config-XCDVKR23.js → config-XUUYQIWO.js} +47 -35
- package/dist/{configure-4GAP54ZW.js → configure-IHJ7YOMV.js} +18 -15
- package/dist/{context-77FM5DV5.js → context-74JLXAWD.js} +18 -10
- package/dist/{context-4UOGGLQ5.js → context-75MIWW3U.js} +41 -29
- package/dist/{context-5VKGUVJJ.js → context-ZQ7SIFJV.js} +85 -9
- package/dist/{context-clear-XXJRLCJJ.js → context-clear-GYKWNUML.js} +41 -29
- package/dist/{context-index-BZ4UYMTC.js → context-index-SSR5ECNE.js} +3 -3
- package/dist/context-working-set-UX5KEP4J.js +1553 -0
- package/dist/{dispatch-runner-QPRDDBDX.js → dispatch-runner-GIJBHNFL.js} +47 -32
- package/dist/{docs-2C2LTVT2.js → docs-6FZSCG5B.js} +3 -3
- package/dist/{doctor-HR46URBJ.js → doctor-SVJ5BZCW.js} +12 -12
- package/dist/{eval-XSSNATB4.js → eval-CG6LLBLD.js} +54 -238
- package/dist/{evidence-6HG2PY2B.js → evidence-ZYFIEN42.js} +57 -28
- package/dist/{evolve-K7YU3NCY.js → evolve-QGEXEMDW.js} +36 -25
- package/dist/{extensions-QVDOHDGJ.js → extensions-ADGNCJJD.js} +3 -3
- package/dist/{fleet-VY3HHKN6.js → fleet-S5R4ZOQY.js} +73 -44
- package/dist/{fleet-preflight-DDN536IT.js → fleet-preflight-BHSNPBMH.js} +3 -3
- package/dist/{init-JYGXI3FK.js → init-5DRU55YR.js} +49 -37
- package/dist/memory-7YKKR6UC.js +467 -0
- package/dist/{models-I5QWSEOM.js → models-ZPOLRU2C.js} +24 -21
- package/dist/{monitor-GE4ID3IA.js → monitor-US5F5YGZ.js} +73 -46
- package/dist/{orchestrator-EM5MC3HM.js → orchestrator-E2AL4T5N.js} +1624 -1007
- package/dist/{paths-UXLN5YYZ.js → paths-E7KYAQWE.js} +3 -3
- package/dist/{reset-L2FQEE3E.js → reset-KZ652EK6.js} +6 -5
- package/dist/{run-ZU3QMZPZ.js → run-SRNBKDWD.js} +76 -54
- package/dist/{share-S5BZQC5I.js → share-CGZE33UP.js} +7 -6
- package/dist/{skills-X5VXCRNQ.js → skills-S2X4DLY5.js} +4 -4
- package/dist/{skills-eval-WKIHWTHR.js → skills-eval-W2GGIC4R.js} +40 -29
- package/dist/{targets-SNCPI2NR.js → targets-54SWINWB.js} +28 -23
- package/dist/{terminal-lease-BNAHVHBS.js → terminal-lease-SAIF2OGY.js} +6 -4
- package/dist/{uninstall-FZCQCDKC.js → uninstall-BVLWXKBT.js} +3 -3
- package/dist/{upgrade-JQHHPQ4K.js → upgrade-JKAR27XC.js} +20 -19
- package/dist/{usage-OR4O5SMZ.js → usage-MSAWCLX4.js} +79 -36
- package/dist/verifiers-NCBTHHN2.js +1220 -0
- package/dist/verify-X5HDROLA.js +25 -0
- package/dist/{wiki-generate-UEXP2ARI.js → wiki-generate-GUSOQ6ZP.js} +50 -37
- package/dist/worker/entry.js +90 -70
- package/dist/{workspace-G4ZWUIPR.js → workspace-ZJ6BFM3Q.js} +4 -4
- package/docs/README.md +8 -7
- package/docs/acp.md +1 -1
- package/docs/alcf-provider.md +1 -1
- package/docs/architecture.md +2 -2
- package/docs/artifact-placement.md +1 -2
- package/docs/artifact-versions.md +1 -1
- package/docs/built-in-agents.md +1 -1
- package/docs/capacity-and-scheduling.md +1 -1
- package/docs/commands-and-modes.md +60 -26
- package/docs/config-knobs-audit.md +1 -2
- package/docs/configuration-and-targets.md +26 -1
- package/docs/context-engine.md +67 -13
- package/docs/context-working-set.md +194 -0
- package/docs/development-pipeline.md +1 -1
- package/docs/documentation-coverage.md +6 -6
- package/docs/documentation-guide.md +7 -6
- package/docs/environment-variables.md +2 -1
- package/docs/eval-runner.md +1 -1
- package/docs/evals-internal.md +4 -32
- package/docs/evidence-and-memory.md +139 -7
- package/docs/evolution.md +1 -1
- package/docs/exit-codes-and-output.md +1 -1
- package/docs/extensions-and-sharing.md +2 -2
- package/docs/fleet-dispatch.md +49 -8
- package/docs/glossary.md +21 -1
- package/docs/installation-and-lifecycle.md +2 -2
- package/docs/middleware-and-components.md +19 -2
- package/docs/model-catalog.md +7 -9
- package/docs/observability.md +4 -4
- package/docs/proactive-memory.md +26 -16
- package/docs/prompt-envelope-and-tools.md +7 -5
- package/docs/provider-adapter-cookbook.md +1 -1
- package/docs/release-cut-checklist.md +43 -40
- package/docs/safety-model.md +49 -8
- package/docs/scientific-validation.md +21 -3
- package/docs/session-lifecycle.md +3 -3
- package/docs/skills-marketplace.md +1 -1
- package/docs/tool-usage.md +79 -12
- package/docs/trace-store.md +1 -1
- package/docs/troubleshooting.md +1 -1
- package/docs/tui-design.md +38 -4
- package/docs/worker-dispatch-mechanics.md +11 -1
- package/package.json +13 -13
- package/skills/meta/clio-test/SKILL.md +20 -17
- package/skills/meta/clio-test/evals.md +3 -3
- package/skills/meta/clio-test/references/harness.md +35 -6
- package/skills/meta/clio-test/references/test-map.md +20 -10
- package/skills/registry.yaml +2 -2
- package/skills/skill-marketplace.json +1 -1
- package/src/cli/agents.ts +2 -3
- package/src/cli/argv.ts +14 -1
- package/src/cli/context-working-set.ts +513 -0
- package/src/cli/context.ts +8 -0
- package/src/cli/evidence.ts +20 -2
- package/src/cli/fleet.ts +15 -0
- package/src/cli/index.ts +5 -1
- package/src/cli/memory.ts +272 -10
- package/src/cli/modes/json-stream.ts +2 -2
- package/src/cli/modes/print.ts +12 -1
- package/src/cli/run.ts +22 -2
- package/src/cli/targets.ts +12 -3
- package/src/cli/usage.ts +55 -7
- package/src/cli/verifiers.ts +325 -0
- package/src/core/bash-exec.ts +39 -14
- package/src/core/bus-events.ts +22 -4
- package/src/core/config.ts +54 -0
- package/src/core/defaults.ts +50 -3
- package/src/core/response-model-id.ts +134 -0
- package/src/core/toml.ts +62 -0
- package/src/core/verification-scripts.ts +6 -0
- package/src/core/workspace-files.ts +0 -1
- package/src/domains/agents/builtins/architect.md +1 -1
- package/src/domains/agents/builtins/verifier.md +3 -0
- package/src/domains/agents/catalog.ts +5 -4
- package/src/domains/agents/recipe.ts +54 -14
- package/src/domains/agents/result-contract.ts +7 -4
- package/src/domains/config/classify.ts +1 -0
- package/src/domains/context/bootstrap.ts +36 -27
- package/src/domains/context/project-metadata.ts +19 -63
- package/src/domains/context/prompt-context.ts +8 -0
- package/src/domains/context/working-set/contract.ts +161 -0
- package/src/domains/context/working-set/defaults.ts +28 -0
- package/src/domains/context/working-set/engine.ts +203 -0
- package/src/domains/context/working-set/fold.ts +62 -0
- package/src/domains/context/working-set/horizon.ts +38 -0
- package/src/domains/context/working-set/marker.ts +103 -0
- package/src/domains/context/working-set/path-index.ts +436 -0
- package/src/domains/context/working-set/payload.ts +152 -0
- package/src/domains/context/working-set/policies/age-horizon.ts +55 -0
- package/src/domains/context/working-set/policies/index.ts +20 -0
- package/src/domains/context/working-set/policies/structural.ts +160 -0
- package/src/domains/context/working-set/project.ts +132 -0
- package/src/domains/context/working-set/protect.ts +109 -0
- package/src/domains/context/working-set/recall.ts +177 -0
- package/src/domains/context/working-set/replay/controls.ts +112 -0
- package/src/domains/context/working-set/replay/load-clio.ts +199 -0
- package/src/domains/context/working-set/replay/metrics.ts +185 -0
- package/src/domains/context/working-set/replay/reference-graph.ts +79 -0
- package/src/domains/context/working-set/replay/report.ts +139 -0
- package/src/domains/context/working-set/replay/runner.ts +325 -0
- package/src/domains/context/working-set/replay/synthetic.ts +422 -0
- package/src/domains/context/working-set/replay/trace.ts +21 -0
- package/src/domains/context/working-set/visible.ts +54 -0
- package/src/domains/dispatch/budget-envelope.ts +396 -0
- package/src/domains/dispatch/contract.ts +2 -0
- package/src/domains/dispatch/extension.ts +81 -27
- package/src/domains/dispatch/orphan-recovery.ts +1 -0
- package/src/domains/dispatch/receipt-integrity.ts +4 -0
- package/src/domains/dispatch/state.ts +1 -0
- package/src/domains/dispatch/types.ts +10 -3
- package/src/domains/dispatch/validation.ts +14 -0
- package/src/domains/dispatch/worker-spawn.ts +14 -3
- package/src/domains/eval/metrics/evidence.ts +0 -116
- package/src/domains/eval/metrics/invariants.ts +1 -1
- package/src/domains/eval/runners/clio-run.ts +1 -10
- package/src/domains/eval/runners/external-command.ts +2 -29
- package/src/domains/eval/schema/suite.ts +0 -7
- package/src/domains/eval/suites/run.ts +1 -7
- package/src/domains/evidence/build.ts +112 -45
- package/src/domains/evidence/eval.ts +24 -7
- package/src/domains/evidence/index.ts +53 -0
- package/src/domains/evidence/ordering.ts +12 -0
- package/src/domains/evidence/run-trust.ts +221 -0
- package/src/domains/evidence/store.ts +46 -6
- package/src/domains/evidence/trust-status.ts +854 -0
- package/src/domains/evidence/types.ts +26 -0
- package/src/domains/memory/index.ts +22 -0
- package/src/domains/memory/operations.ts +58 -1
- package/src/domains/memory/promotion.ts +281 -0
- package/src/domains/memory/prompt-section.ts +25 -5
- package/src/domains/memory/proposal.ts +51 -7
- package/src/domains/memory/task-bank.ts +3 -2
- package/src/domains/memory/task-memory-handoff.ts +181 -24
- package/src/domains/memory/task-memory-policy.ts +3 -1
- package/src/domains/memory/types.ts +37 -0
- package/src/domains/memory/validate.ts +178 -0
- package/src/domains/middleware/memory-intervention.ts +38 -25
- package/src/domains/middleware/runtime.ts +6 -0
- package/src/domains/middleware/skills-reminder.ts +19 -4
- package/src/domains/middleware/stalled-turn.ts +208 -5
- package/src/domains/middleware/types.ts +10 -0
- package/src/domains/observability/contract.ts +6 -1
- package/src/domains/observability/cost.ts +20 -4
- package/src/domains/observability/extension.ts +2 -2
- package/src/domains/providers/index.ts +3 -0
- package/src/domains/providers/model-discovery.ts +9 -0
- package/src/domains/providers/runtime-resolution.ts +38 -1
- package/src/domains/providers/runtimes/common/probe-helpers.ts +97 -16
- package/src/domains/providers/types/context-window-slots.ts +18 -0
- package/src/domains/providers/types/runtime-descriptor.ts +3 -1
- package/src/domains/safety/autonomy.ts +1 -1
- package/src/domains/safety/call-target.ts +211 -14
- package/src/domains/safety/decision-presentation.ts +268 -0
- package/src/domains/safety/default-path-policy.ts +8 -0
- package/src/domains/safety/finish-contract.ts +4 -3
- package/src/domains/safety/policy-engine.ts +48 -6
- package/src/domains/safety/redaction.ts +73 -0
- package/src/domains/session/compaction/compact.ts +23 -1
- package/src/domains/session/compaction/cut-point.ts +2 -0
- package/src/domains/session/compaction/tokens.ts +16 -1
- package/src/domains/session/context-ledger.ts +12 -1
- package/src/domains/session/decision-board.ts +4 -0
- package/src/domains/session/entries.ts +110 -1
- package/src/domains/session/history.ts +68 -19
- package/src/domains/session/manager.ts +9 -2
- package/src/domains/session/migrations/index.ts +22 -3
- package/src/domains/session/usage.ts +24 -7
- package/src/engine/acp/event-mapper.ts +7 -0
- package/src/engine/acp/server.ts +32 -2
- package/src/engine/agent.ts +18 -1
- package/src/engine/apis/lmstudio.ts +25 -4
- package/src/engine/apis/openai-completions.ts +147 -22
- package/src/engine/claude/sdk-runtime.ts +8 -2
- package/src/engine/claude/tool-safety.ts +13 -0
- package/src/engine/loop-guard.ts +27 -3
- package/src/engine/session.ts +9 -3
- package/src/engine/worker-events.ts +4 -3
- package/src/engine/worker-runtime.ts +59 -54
- package/src/entry/orchestrator.ts +34 -5
- package/src/interactive/chat-loop-messages.ts +40 -6
- package/src/interactive/chat-loop.ts +13 -0
- package/src/interactive/chat-panel.ts +17 -1
- package/src/interactive/chat-renderer.ts +49 -24
- package/src/interactive/clio-editor.ts +44 -7
- package/src/interactive/context-meter.ts +10 -0
- package/src/interactive/context-overlay.ts +120 -7
- package/src/interactive/context-recall-command.ts +110 -0
- package/src/interactive/cost-overlay.ts +39 -8
- package/src/interactive/dispatch-board.ts +212 -35
- package/src/interactive/footer/widgets.ts +13 -0
- package/src/interactive/interactive-application.ts +6 -1
- package/src/interactive/interactive-input-runtime.ts +11 -1
- package/src/interactive/interactive-presentation.ts +11 -1
- package/src/interactive/interactive-slash-runtime.ts +37 -1
- package/src/interactive/memory-overlay.ts +89 -4
- package/src/interactive/model-session-replay.ts +21 -0
- package/src/interactive/overlay-ask-user-lifecycle.ts +1 -1
- package/src/interactive/overlay-frame.ts +5 -2
- package/src/interactive/overlay-general-openers.ts +46 -1
- package/src/interactive/overlay-key-routing.ts +41 -1
- package/src/interactive/overlay-lifecycle.ts +11 -4
- package/src/interactive/overlay-permission-lifecycle.ts +23 -8
- package/src/interactive/overlay-session-lifecycle.ts +8 -4
- package/src/interactive/overlay-transitions.ts +11 -0
- package/src/interactive/overlays/ask-user.ts +74 -30
- package/src/interactive/overlays/decisions.ts +3 -1
- package/src/interactive/permission-hint.ts +35 -0
- package/src/interactive/permission-overlay.ts +95 -45
- package/src/interactive/renderers/tool-execution.ts +37 -51
- package/src/interactive/session-last-turn.ts +8 -1
- package/src/interactive/session-transcript.ts +2 -2
- package/src/interactive/session-usage-reseed.ts +36 -10
- package/src/interactive/slash-commands.ts +31 -4
- package/src/interactive/status/summary.ts +5 -0
- package/src/interactive/status/types.ts +5 -0
- package/src/interactive/terminal-lease.ts +1 -0
- package/src/interactive/turn-context.ts +333 -110
- package/src/interactive/turn-middleware.ts +7 -6
- package/src/interactive/turn-runtime.ts +37 -8
- package/src/interactive/turn-state.ts +3 -0
- package/src/interactive/worker-progress.ts +440 -0
- package/src/interactive/worker-stream.ts +51 -110
- package/src/tools/agent-tools.ts +39 -7
- package/src/tools/ask-user.ts +21 -1
- package/src/tools/bash.ts +144 -82
- package/src/tools/builtin-tool-catalog.ts +11 -5
- package/src/tools/context/index.ts +107 -5
- package/src/tools/context/surface.ts +3 -2
- package/src/tools/core-bootstrap.ts +21 -0
- package/src/tools/dispatch-arguments.ts +8 -0
- package/src/tools/dispatch-event-text.ts +19 -0
- package/src/tools/dispatch-runner.ts +9 -7
- package/src/tools/dispatch.ts +24 -1
- package/src/tools/monitor.ts +43 -20
- package/src/tools/registry.ts +72 -10
- package/src/tools/result-disposition.ts +706 -0
- package/src/tools/result-shaping.ts +321 -20
- package/src/tools/safe-exec.ts +2 -0
- package/src/tools/verify/authoring.ts +1120 -0
- package/src/tools/verify/catalog.ts +346 -0
- package/src/tools/verify/index.ts +13 -3
- package/src/tools/verify/scripts.ts +135 -37
- package/src/tools/verify/surface.ts +9 -5
- package/src/tools/worker-evidence.ts +54 -12
- package/src/worker/spec-contract.ts +43 -3
- package/dist/chunk-J7CWMCQD.js +0 -255
- package/dist/chunk-T6YILFSB.js +0 -80
- package/dist/chunk-VAKQQHWR.js +0 -434
- package/dist/chunk-VPAYEGVX.js +0 -184
- package/dist/chunk-XBXAASKX.js +0 -18
- package/dist/memory-WFZMGYHX.js +0 -236
- package/src/domains/eval/metrics/chaos-stream.ts +0 -93
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { createRequire as __clioCreateRequire } from "node:module"; const require = __clioCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
createSentinelStripper,
|
|
4
|
+
stripTokenizerSentinels
|
|
5
|
+
} from "./chunk-CFGTUFWB.js";
|
|
2
6
|
import {
|
|
3
7
|
readSettings
|
|
4
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-AD2SYQYC.js";
|
|
5
9
|
import {
|
|
6
10
|
THINKING_LEVELS
|
|
7
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-4OC57DA6.js";
|
|
8
12
|
import {
|
|
9
13
|
authNotRequiredStatus,
|
|
10
14
|
openAuthStorage,
|
|
@@ -13,10 +17,6 @@ import {
|
|
|
13
17
|
resolveRuntimeAuthTarget,
|
|
14
18
|
targetRequiresAuth
|
|
15
19
|
} from "./chunk-4VP4KH3K.js";
|
|
16
|
-
import {
|
|
17
|
-
cwdHash,
|
|
18
|
-
sessionPaths
|
|
19
|
-
} from "./chunk-M6SHUN7Q.js";
|
|
20
20
|
import {
|
|
21
21
|
sleep
|
|
22
22
|
} from "./chunk-FQ4SKYE4.js";
|
|
@@ -24,8 +24,10 @@ import {
|
|
|
24
24
|
withStateFileLock
|
|
25
25
|
} from "./chunk-IKCO5N3L.js";
|
|
26
26
|
import {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
ceilChars,
|
|
28
|
+
estimateAgentMessageTokens,
|
|
29
|
+
toolSchemaChars
|
|
30
|
+
} from "./chunk-GEYXPTRF.js";
|
|
29
31
|
import {
|
|
30
32
|
activateExternalPluginApiBridge,
|
|
31
33
|
calculateEngineCost,
|
|
@@ -34,15 +36,20 @@ import {
|
|
|
34
36
|
getEngineSupportedThinkingLevels,
|
|
35
37
|
registerEngineApiProvider
|
|
36
38
|
} from "./chunk-FCSXB6T2.js";
|
|
39
|
+
import {
|
|
40
|
+
require_dist
|
|
41
|
+
} from "./chunk-APJ265NV.js";
|
|
37
42
|
import {
|
|
38
43
|
clioConfigDir,
|
|
39
44
|
clioStatePath,
|
|
40
45
|
resolveClioDirs
|
|
41
46
|
} from "./chunk-BNAZZHFG.js";
|
|
42
47
|
import {
|
|
43
|
-
BusChannels,
|
|
44
48
|
getSharedBus
|
|
45
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-ZGVHUX3M.js";
|
|
50
|
+
import {
|
|
51
|
+
BusChannels
|
|
52
|
+
} from "./chunk-G7MUEIGA.js";
|
|
46
53
|
import {
|
|
47
54
|
__toESM,
|
|
48
55
|
init_esm_shims
|
|
@@ -363,597 +370,15 @@ function credentialsPresent() {
|
|
|
363
370
|
return present;
|
|
364
371
|
}
|
|
365
372
|
|
|
366
|
-
// src/domains/session/context-accounting.ts
|
|
367
|
-
init_esm_shims();
|
|
368
|
-
import { appendFileSync, existsSync, readFileSync } from "node:fs";
|
|
369
|
-
import { dirname, join as join2 } from "node:path";
|
|
370
|
-
|
|
371
|
-
// src/domains/session/compaction/auto.ts
|
|
372
|
-
init_esm_shims();
|
|
373
|
-
var DEFAULT_COMPACTION_THRESHOLD = 0.8;
|
|
374
|
-
function shouldCompact(contextTokens, threshold, contextWindow) {
|
|
375
|
-
const base = {
|
|
376
|
-
shouldCompact: false,
|
|
377
|
-
pressure: null,
|
|
378
|
-
contextTokens,
|
|
379
|
-
contextWindow,
|
|
380
|
-
threshold
|
|
381
|
-
};
|
|
382
|
-
if (!Number.isFinite(threshold) || threshold <= 0 || threshold > 1) return base;
|
|
383
|
-
if (!Number.isFinite(contextTokens) || contextTokens <= 0) return base;
|
|
384
|
-
if (!Number.isFinite(contextWindow) || contextWindow <= 0) return base;
|
|
385
|
-
const pressure = contextTokens / contextWindow;
|
|
386
|
-
return {
|
|
387
|
-
shouldCompact: pressure >= threshold,
|
|
388
|
-
pressure,
|
|
389
|
-
contextTokens,
|
|
390
|
-
contextWindow,
|
|
391
|
-
threshold
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
var AutoCompactionTrigger = class {
|
|
395
|
-
inFlight = null;
|
|
396
|
-
/** True while a task is in flight. Callers can short-circuit on this. */
|
|
397
|
-
isBusy() {
|
|
398
|
-
return this.inFlight !== null;
|
|
399
|
-
}
|
|
400
|
-
/**
|
|
401
|
-
* Run `task` unless one is already in flight. Returns the Promise the
|
|
402
|
-
* task is running under. Callers always get the eventual result of the
|
|
403
|
-
* first task, never a second call. Rejections clear the slot so a later
|
|
404
|
-
* fire can start fresh.
|
|
405
|
-
*/
|
|
406
|
-
fire(task) {
|
|
407
|
-
if (this.inFlight) return this.inFlight;
|
|
408
|
-
const run = task().finally(() => {
|
|
409
|
-
this.inFlight = null;
|
|
410
|
-
});
|
|
411
|
-
this.inFlight = run;
|
|
412
|
-
return run;
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
// src/domains/session/context-ledger.ts
|
|
417
|
-
init_esm_shims();
|
|
418
|
-
var SEGMENT_CATEGORY = {
|
|
419
|
-
identity: "system",
|
|
420
|
-
"operating-contract": "system",
|
|
421
|
-
delegation: "agents",
|
|
422
|
-
skills: "skills",
|
|
423
|
-
safety: "system",
|
|
424
|
-
runtime: "system",
|
|
425
|
-
"tool-contract": "system",
|
|
426
|
-
"retrieval-hints": "system",
|
|
427
|
-
"tool-catalog": "tools",
|
|
428
|
-
"tools-and-agents": "agents",
|
|
429
|
-
"agent-fleet-deltas": "agents",
|
|
430
|
-
"skills-catalog": "skills",
|
|
431
|
-
memory: "memory",
|
|
432
|
-
"project-context": "project",
|
|
433
|
-
"context.project-rules": "project",
|
|
434
|
-
"context.operator-profile": "memory",
|
|
435
|
-
"context.clio-repo-awareness": "system",
|
|
436
|
-
"history-summary": "messages"
|
|
437
|
-
};
|
|
438
|
-
var CONTEXT_CATEGORY_LABEL = {
|
|
439
|
-
system: "System prompt",
|
|
440
|
-
tools: "Tool definitions",
|
|
441
|
-
agents: "Agent fleet",
|
|
442
|
-
skills: "Skills",
|
|
443
|
-
memory: "Memory",
|
|
444
|
-
project: "Project context",
|
|
445
|
-
messages: "Messages",
|
|
446
|
-
pending: "Pending input",
|
|
447
|
-
reserve: "Autocompact reserve",
|
|
448
|
-
free: "Free space",
|
|
449
|
-
streaming: "Streaming output"
|
|
450
|
-
};
|
|
451
|
-
var CONTENT_ORDER = [
|
|
452
|
-
"system",
|
|
453
|
-
"tools",
|
|
454
|
-
"agents",
|
|
455
|
-
"skills",
|
|
456
|
-
"memory",
|
|
457
|
-
"project",
|
|
458
|
-
"messages",
|
|
459
|
-
"pending",
|
|
460
|
-
"streaming"
|
|
461
|
-
];
|
|
462
|
-
function categoryForSegment(id) {
|
|
463
|
-
return SEGMENT_CATEGORY[id] ?? "system";
|
|
464
|
-
}
|
|
465
|
-
function finiteNonNegative(value) {
|
|
466
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 0;
|
|
467
|
-
}
|
|
468
|
-
function percentOf(tokens, window) {
|
|
469
|
-
if (window <= 0) return null;
|
|
470
|
-
return Math.min(100, tokens / window * 100);
|
|
471
|
-
}
|
|
472
|
-
function buildContextLedger(input) {
|
|
473
|
-
const window = finiteNonNegative(input.contextWindow);
|
|
474
|
-
const raw = {
|
|
475
|
-
system: 0,
|
|
476
|
-
tools: 0,
|
|
477
|
-
agents: 0,
|
|
478
|
-
skills: 0,
|
|
479
|
-
memory: 0,
|
|
480
|
-
project: 0,
|
|
481
|
-
messages: 0,
|
|
482
|
-
pending: 0,
|
|
483
|
-
reserve: 0,
|
|
484
|
-
free: 0,
|
|
485
|
-
streaming: 0
|
|
486
|
-
};
|
|
487
|
-
const segments = input.promptSegments ?? [];
|
|
488
|
-
if (segments.length > 0) {
|
|
489
|
-
for (const segment of segments) {
|
|
490
|
-
raw[categoryForSegment(segment.id)] += finiteNonNegative(segment.tokenEstimate);
|
|
491
|
-
}
|
|
492
|
-
} else {
|
|
493
|
-
raw.system += finiteNonNegative(input.systemPromptTokens);
|
|
494
|
-
}
|
|
495
|
-
raw.tools += finiteNonNegative(input.toolSchemaTokens);
|
|
496
|
-
raw.messages += finiteNonNegative(input.messageTokens);
|
|
497
|
-
raw.pending += finiteNonNegative(input.pendingTokens);
|
|
498
|
-
raw.streaming += finiteNonNegative(input.streamingTokens);
|
|
499
|
-
raw.agents += finiteNonNegative(input.agentsTokens);
|
|
500
|
-
raw.skills += finiteNonNegative(input.skillsTokens);
|
|
501
|
-
raw.memory += finiteNonNegative(input.memoryTokens);
|
|
502
|
-
raw.project += finiteNonNegative(input.projectTokens);
|
|
503
|
-
const decomposed = CONTENT_ORDER.reduce((sum, category) => sum + raw[category], 0);
|
|
504
|
-
const liveTotal = finiteNonNegative(input.liveTotalTokens);
|
|
505
|
-
if (liveTotal > decomposed) {
|
|
506
|
-
raw.messages += liveTotal - decomposed;
|
|
507
|
-
}
|
|
508
|
-
const usedTokens = Math.max(decomposed, liveTotal);
|
|
509
|
-
const effectiveThreshold = typeof input.compactionThreshold === "number" && input.compactionThreshold > 0 && input.compactionThreshold < 1 ? input.compactionThreshold : input.compactionAuto ? DEFAULT_COMPACTION_THRESHOLD : null;
|
|
510
|
-
let reserveTokens = 0;
|
|
511
|
-
let freeTokens = 0;
|
|
512
|
-
if (window > 0) {
|
|
513
|
-
const remaining = Math.max(0, window - usedTokens);
|
|
514
|
-
reserveTokens = effectiveThreshold !== null ? Math.min(Math.round(window * (1 - effectiveThreshold)), remaining) : 0;
|
|
515
|
-
freeTokens = Math.max(0, window - usedTokens - reserveTokens);
|
|
516
|
-
}
|
|
517
|
-
const groups = [];
|
|
518
|
-
for (const category of CONTENT_ORDER) {
|
|
519
|
-
const tokens = raw[category];
|
|
520
|
-
if (tokens <= 0) continue;
|
|
521
|
-
groups.push({
|
|
522
|
-
category,
|
|
523
|
-
label: CONTEXT_CATEGORY_LABEL[category],
|
|
524
|
-
tokens,
|
|
525
|
-
percent: percentOf(tokens, window)
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
const meter = [...groups];
|
|
529
|
-
if (reserveTokens > 0) {
|
|
530
|
-
meter.push({
|
|
531
|
-
category: "reserve",
|
|
532
|
-
label: CONTEXT_CATEGORY_LABEL.reserve,
|
|
533
|
-
tokens: reserveTokens,
|
|
534
|
-
percent: percentOf(reserveTokens, window)
|
|
535
|
-
});
|
|
536
|
-
}
|
|
537
|
-
if (window > 0) {
|
|
538
|
-
meter.push({
|
|
539
|
-
category: "free",
|
|
540
|
-
label: CONTEXT_CATEGORY_LABEL.free,
|
|
541
|
-
tokens: freeTokens,
|
|
542
|
-
percent: percentOf(freeTokens, window)
|
|
543
|
-
});
|
|
544
|
-
}
|
|
545
|
-
return {
|
|
546
|
-
provider: input.provider ?? null,
|
|
547
|
-
model: input.model ?? null,
|
|
548
|
-
contextWindow: window,
|
|
549
|
-
contextWindowSource: input.contextWindowSource ?? null,
|
|
550
|
-
usedTokens,
|
|
551
|
-
reserveTokens,
|
|
552
|
-
freeTokens,
|
|
553
|
-
percent: percentOf(usedTokens, window),
|
|
554
|
-
measured: input.measured === true && liveTotal > 0,
|
|
555
|
-
compactionThreshold: effectiveThreshold,
|
|
556
|
-
compactionAuto: input.compactionAuto === true,
|
|
557
|
-
projectPreload: input.projectPreload ?? null,
|
|
558
|
-
projectHandbookFiles: input.projectHandbookFiles ?? null,
|
|
559
|
-
toolCount: Math.max(0, Math.floor(input.toolCount ?? 0)),
|
|
560
|
-
groups,
|
|
561
|
-
meter,
|
|
562
|
-
lastCompaction: input.lastCompaction ?? null,
|
|
563
|
-
promptCache: input.promptCache ?? null
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
// src/domains/session/context-accounting.ts
|
|
568
|
-
var IMAGE_CHAR_ESTIMATE = 4800;
|
|
569
|
-
var TOKEN_CHARS = 4;
|
|
570
|
-
var MESSAGE_OVERHEAD_TOKENS = 16;
|
|
571
|
-
function ceilChars(chars) {
|
|
572
|
-
return Math.ceil(Math.max(0, chars) / TOKEN_CHARS);
|
|
573
|
-
}
|
|
574
|
-
function isRecord(value) {
|
|
575
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
576
|
-
}
|
|
577
|
-
function jsonLength(value) {
|
|
578
|
-
if (value === void 0 || value === null) return 0;
|
|
579
|
-
if (typeof value === "string") return value.length;
|
|
580
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value).length;
|
|
581
|
-
try {
|
|
582
|
-
return JSON.stringify(value).length;
|
|
583
|
-
} catch {
|
|
584
|
-
return String(value).length;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
function argsLength(value) {
|
|
588
|
-
if (value === void 0 || value === null) return 0;
|
|
589
|
-
return typeof value === "string" ? value.length : jsonLength(value);
|
|
590
|
-
}
|
|
591
|
-
function blockChars(block) {
|
|
592
|
-
if (typeof block === "string") return block.length;
|
|
593
|
-
if (!isRecord(block)) return jsonLength(block);
|
|
594
|
-
if (block.type === "text" && typeof block.text === "string") return block.text.length;
|
|
595
|
-
if (block.type === "thinking" && typeof block.thinking === "string") return block.thinking.length;
|
|
596
|
-
if (block.type === "image") return IMAGE_CHAR_ESTIMATE;
|
|
597
|
-
if (block.type === "toolCall") {
|
|
598
|
-
const name = typeof block.name === "string" ? block.name : "";
|
|
599
|
-
const id = typeof block.id === "string" ? block.id : "";
|
|
600
|
-
return id.length + name.length + argsLength(block.arguments ?? block.args ?? block.input);
|
|
601
|
-
}
|
|
602
|
-
if (Array.isArray(block.content)) return contentChars(block.content);
|
|
603
|
-
if (typeof block.text === "string") return block.text.length;
|
|
604
|
-
if (typeof block.thinking === "string") return block.thinking.length;
|
|
605
|
-
return jsonLength(block);
|
|
606
|
-
}
|
|
607
|
-
function contentChars(content) {
|
|
608
|
-
if (typeof content === "string") return content.length;
|
|
609
|
-
if (!Array.isArray(content)) return jsonLength(content);
|
|
610
|
-
return content.reduce((sum, block) => sum + blockChars(block), 0);
|
|
611
|
-
}
|
|
612
|
-
function messageChars(message) {
|
|
613
|
-
if (!isRecord(message)) return jsonLength(message);
|
|
614
|
-
let chars = 0;
|
|
615
|
-
chars += typeof message.role === "string" ? message.role.length : 0;
|
|
616
|
-
const payload = message.payload !== void 0 ? message.payload : message.content;
|
|
617
|
-
chars += contentChars(payload);
|
|
618
|
-
chars += typeof message.toolCallId === "string" ? message.toolCallId.length : 0;
|
|
619
|
-
chars += typeof message.toolName === "string" ? message.toolName.length : 0;
|
|
620
|
-
chars += typeof message.errorMessage === "string" ? message.errorMessage.length : 0;
|
|
621
|
-
return chars;
|
|
622
|
-
}
|
|
623
|
-
function toolSchemaChars(tool) {
|
|
624
|
-
if (!isRecord(tool)) return jsonLength(tool);
|
|
625
|
-
const name = typeof tool.name === "string" ? tool.name.length : 0;
|
|
626
|
-
const description = typeof tool.description === "string" ? tool.description.length : 0;
|
|
627
|
-
const parameters = jsonLength(tool.parameters);
|
|
628
|
-
return name + description + parameters;
|
|
629
|
-
}
|
|
630
|
-
function usageTotalTokens(usage) {
|
|
631
|
-
if (!isRecord(usage)) return null;
|
|
632
|
-
const total = usage.totalTokens;
|
|
633
|
-
if (typeof total === "number" && Number.isFinite(total) && total > 0) return total;
|
|
634
|
-
const input = typeof usage.input === "number" && Number.isFinite(usage.input) ? usage.input : 0;
|
|
635
|
-
const output = typeof usage.output === "number" && Number.isFinite(usage.output) ? usage.output : 0;
|
|
636
|
-
const cacheRead = typeof usage.cacheRead === "number" && Number.isFinite(usage.cacheRead) ? usage.cacheRead : 0;
|
|
637
|
-
const cacheWrite = typeof usage.cacheWrite === "number" && Number.isFinite(usage.cacheWrite) ? usage.cacheWrite : 0;
|
|
638
|
-
const sum = input + output + cacheRead + cacheWrite;
|
|
639
|
-
return sum > 0 ? sum : null;
|
|
640
|
-
}
|
|
641
|
-
function usageInvalidated(message) {
|
|
642
|
-
return message.contextUsageInvalidated === true;
|
|
643
|
-
}
|
|
644
|
-
function latestUsableAssistantUsage(messages) {
|
|
645
|
-
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
646
|
-
const message = messages[i];
|
|
647
|
-
if (message?.role !== "assistant") continue;
|
|
648
|
-
if (usageInvalidated(message)) continue;
|
|
649
|
-
const stopReason = message.stopReason;
|
|
650
|
-
if (stopReason === "error" || stopReason === "aborted") continue;
|
|
651
|
-
const tokens = usageTotalTokens(message.usage);
|
|
652
|
-
if (tokens !== null) return { index: i, tokens };
|
|
653
|
-
}
|
|
654
|
-
return null;
|
|
655
|
-
}
|
|
656
|
-
function finiteNonNegative2(value) {
|
|
657
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
658
|
-
}
|
|
659
|
-
function nestedNumber(root, path) {
|
|
660
|
-
let current = root;
|
|
661
|
-
for (const key of path) {
|
|
662
|
-
if (!isRecord(current)) return null;
|
|
663
|
-
current = current[key];
|
|
664
|
-
}
|
|
665
|
-
return finiteNonNegative2(current);
|
|
666
|
-
}
|
|
667
|
-
function estimateReasoningTextTokens(text) {
|
|
668
|
-
if (typeof text !== "string" || text.trim().length === 0) return null;
|
|
669
|
-
return Math.max(1, Math.round(text.length / TOKEN_CHARS));
|
|
670
|
-
}
|
|
671
|
-
function extractReasoningTokens(usage) {
|
|
672
|
-
if (!isRecord(usage)) return null;
|
|
673
|
-
const direct = finiteNonNegative2(usage.reasoningTokens) ?? finiteNonNegative2(usage.reasoning_tokens) ?? finiteNonNegative2(usage.reasoning);
|
|
674
|
-
if (direct !== null) return direct;
|
|
675
|
-
const paths = [
|
|
676
|
-
["outputDetails", "reasoningTokens"],
|
|
677
|
-
["output_details", "reasoning_tokens"],
|
|
678
|
-
["output_tokens_details", "reasoning_tokens"],
|
|
679
|
-
["completion_tokens_details", "reasoning_tokens"],
|
|
680
|
-
["completionTokensDetails", "reasoningTokens"],
|
|
681
|
-
["details", "reasoningTokens"]
|
|
682
|
-
];
|
|
683
|
-
for (const path of paths) {
|
|
684
|
-
const value = nestedNumber(usage, path);
|
|
685
|
-
if (value !== null) return value;
|
|
686
|
-
}
|
|
687
|
-
return null;
|
|
688
|
-
}
|
|
689
|
-
function estimateAgentMessageTokens(message) {
|
|
690
|
-
return ceilChars(messageChars(message)) + MESSAGE_OVERHEAD_TOKENS;
|
|
691
|
-
}
|
|
692
|
-
function estimateAgentContextBreakdown(input) {
|
|
693
|
-
return {
|
|
694
|
-
systemPromptTokens: input.systemPrompt ? ceilChars(input.systemPrompt.length) : 0,
|
|
695
|
-
messageTokens: input.messages.reduce((sum, message) => sum + estimateAgentMessageTokens(message), 0),
|
|
696
|
-
pendingUserTokens: input.pendingUserText ? ceilChars(input.pendingUserText.length) : 0,
|
|
697
|
-
toolSchemaTokens: (input.tools ?? []).reduce((sum, tool) => sum + ceilChars(toolSchemaChars(tool)), 0)
|
|
698
|
-
};
|
|
699
|
-
}
|
|
700
|
-
function estimateAgentContextTokens(input) {
|
|
701
|
-
const breakdown = estimateAgentContextBreakdown(input);
|
|
702
|
-
const projection = breakdown.systemPromptTokens + breakdown.messageTokens + breakdown.pendingUserTokens + breakdown.toolSchemaTokens;
|
|
703
|
-
const usage = latestUsableAssistantUsage(input.messages);
|
|
704
|
-
if (!usage) return projection;
|
|
705
|
-
const trailingTokens = input.messages.slice(usage.index + 1).reduce((sum, message) => sum + estimateAgentMessageTokens(message), 0);
|
|
706
|
-
const anchored = usage.tokens + trailingTokens + breakdown.pendingUserTokens + breakdown.toolSchemaTokens;
|
|
707
|
-
return Math.max(projection, anchored);
|
|
708
|
-
}
|
|
709
|
-
function contextUsageSnapshot(tokens, contextWindow, breakdown) {
|
|
710
|
-
const window = typeof contextWindow === "number" && Number.isFinite(contextWindow) ? Math.max(0, contextWindow) : 0;
|
|
711
|
-
const base = tokens === null || tokens <= 0 || window <= 0 ? { tokens, contextWindow: window, percent: null } : { tokens, contextWindow: window, percent: Math.min(100, tokens / window * 100) };
|
|
712
|
-
return breakdown ? { ...base, breakdown } : base;
|
|
713
|
-
}
|
|
714
|
-
function getSnapshotsFilePath(meta) {
|
|
715
|
-
const safeMeta = {
|
|
716
|
-
...meta,
|
|
717
|
-
cwdHash: meta.cwdHash || cwdHash(meta.cwd || process.cwd())
|
|
718
|
-
};
|
|
719
|
-
const paths = sessionPaths(safeMeta);
|
|
720
|
-
return join2(dirname(paths.current), "context-snapshots.jsonl");
|
|
721
|
-
}
|
|
722
|
-
function persistableSnapshot(snapshot) {
|
|
723
|
-
const {
|
|
724
|
-
systemPrompt: _systemPrompt,
|
|
725
|
-
conversationMessages: _messages,
|
|
726
|
-
activeToolSchemas: _tools,
|
|
727
|
-
pendingUserInput: _pending,
|
|
728
|
-
images: _images,
|
|
729
|
-
...slim
|
|
730
|
-
} = snapshot;
|
|
731
|
-
return slim;
|
|
732
|
-
}
|
|
733
|
-
function appendContextSnapshot(meta, snapshot) {
|
|
734
|
-
try {
|
|
735
|
-
const file = getSnapshotsFilePath(meta);
|
|
736
|
-
appendFileSync(file, `${JSON.stringify(persistableSnapshot(snapshot))}
|
|
737
|
-
`, "utf8");
|
|
738
|
-
} catch {
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
function getContextSnapshots(meta) {
|
|
742
|
-
try {
|
|
743
|
-
const file = getSnapshotsFilePath(meta);
|
|
744
|
-
if (!existsSync(file)) return [];
|
|
745
|
-
const content = readFileSync(file, "utf8");
|
|
746
|
-
const snapshots = [];
|
|
747
|
-
for (const line of content.split("\n")) {
|
|
748
|
-
if (line.trim().length === 0) continue;
|
|
749
|
-
try {
|
|
750
|
-
snapshots.push(JSON.parse(line));
|
|
751
|
-
} catch {
|
|
752
|
-
}
|
|
753
|
-
}
|
|
754
|
-
return snapshots;
|
|
755
|
-
} catch {
|
|
756
|
-
return [];
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
function getLatestContextSnapshot(meta) {
|
|
760
|
-
const list = getContextSnapshots(meta);
|
|
761
|
-
return list.at(-1) ?? null;
|
|
762
|
-
}
|
|
763
|
-
function buildSnapshotCategories(inputs) {
|
|
764
|
-
const raw = {
|
|
765
|
-
system: 0,
|
|
766
|
-
tools: 0,
|
|
767
|
-
agents: 0,
|
|
768
|
-
skills: 0,
|
|
769
|
-
memory: 0,
|
|
770
|
-
project: 0,
|
|
771
|
-
messages: 0
|
|
772
|
-
};
|
|
773
|
-
if (inputs.promptSegments && inputs.promptSegments.length > 0) {
|
|
774
|
-
for (const segment of inputs.promptSegments) {
|
|
775
|
-
const cat = categoryForSegment(segment.id);
|
|
776
|
-
raw[cat] = (raw[cat] ?? 0) + segment.tokenEstimate;
|
|
777
|
-
}
|
|
778
|
-
} else if (inputs.systemPrompt) {
|
|
779
|
-
raw.system += ceilChars(inputs.systemPrompt.length);
|
|
780
|
-
}
|
|
781
|
-
if (inputs.tools) {
|
|
782
|
-
for (const tool of inputs.tools) {
|
|
783
|
-
raw.tools += ceilChars(toolSchemaChars(tool));
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
if (inputs.messages) {
|
|
787
|
-
for (const msg of inputs.messages) {
|
|
788
|
-
raw.messages += estimateAgentMessageTokens(msg);
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
const decomposed = Object.keys(raw).reduce((sum, k) => sum + (raw[k] ?? 0), 0);
|
|
792
|
-
const window = inputs.effectiveContextWindow;
|
|
793
|
-
const threshold = inputs.compactionThreshold ?? DEFAULT_COMPACTION_THRESHOLD;
|
|
794
|
-
let reserve = 0;
|
|
795
|
-
let free = 0;
|
|
796
|
-
if (window > 0) {
|
|
797
|
-
const remaining = Math.max(0, window - decomposed);
|
|
798
|
-
reserve = Math.min(Math.round(window * (1 - threshold)), remaining);
|
|
799
|
-
free = Math.max(0, window - decomposed - reserve);
|
|
800
|
-
}
|
|
801
|
-
return {
|
|
802
|
-
system: raw.system,
|
|
803
|
-
tools: raw.tools,
|
|
804
|
-
agents: raw.agents,
|
|
805
|
-
skills: raw.skills,
|
|
806
|
-
memory: raw.memory,
|
|
807
|
-
project: raw.project,
|
|
808
|
-
messages: raw.messages,
|
|
809
|
-
reserve,
|
|
810
|
-
free,
|
|
811
|
-
streaming: 0
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
|
-
var SNAPSHOT_SPLIT_KEYS = ["system", "tools", "agents", "skills", "memory", "project", "messages"];
|
|
815
|
-
function estimatedSplitSources() {
|
|
816
|
-
const splits = {};
|
|
817
|
-
for (const key of SNAPSHOT_SPLIT_KEYS) splits[key] = "estimated";
|
|
818
|
-
return splits;
|
|
819
|
-
}
|
|
820
|
-
var snapshotCounter = 0;
|
|
821
|
-
function nextSnapshotId() {
|
|
822
|
-
snapshotCounter += 1;
|
|
823
|
-
return `snap-${Date.now()}-${snapshotCounter.toString(36)}-${Math.random().toString(36).slice(2, 7)}`;
|
|
824
|
-
}
|
|
825
|
-
function captureContextSnapshot(input) {
|
|
826
|
-
const categories = buildSnapshotCategories({
|
|
827
|
-
systemPrompt: input.systemPrompt,
|
|
828
|
-
promptSegments: input.promptSegments,
|
|
829
|
-
tools: input.activeToolSchemas,
|
|
830
|
-
messages: input.conversationMessages,
|
|
831
|
-
effectiveContextWindow: input.effectiveContextWindow,
|
|
832
|
-
compactionThreshold: input.compactionThreshold
|
|
833
|
-
});
|
|
834
|
-
return {
|
|
835
|
-
snapshotId: nextSnapshotId(),
|
|
836
|
-
sessionId: input.sessionId,
|
|
837
|
-
turnId: input.turnId,
|
|
838
|
-
providerId: input.providerId,
|
|
839
|
-
runtimeId: input.runtimeId,
|
|
840
|
-
modelId: input.modelId,
|
|
841
|
-
systemPrompt: input.systemPrompt,
|
|
842
|
-
promptSegments: input.promptSegments ? [...input.promptSegments] : void 0,
|
|
843
|
-
conversationMessages: [...input.conversationMessages],
|
|
844
|
-
activeToolSchemas: [...input.activeToolSchemas],
|
|
845
|
-
pendingUserInput: input.pendingUserInput,
|
|
846
|
-
images: input.images ? [...input.images] : void 0,
|
|
847
|
-
desiredContextWindow: input.desiredContextWindow,
|
|
848
|
-
effectiveContextWindow: input.effectiveContextWindow,
|
|
849
|
-
contextWindowSource: input.contextWindowSource,
|
|
850
|
-
categories,
|
|
851
|
-
sources: { total: "estimated", splits: estimatedSplitSources() },
|
|
852
|
-
promptHash: input.promptHash,
|
|
853
|
-
toolSignature: input.toolSignature,
|
|
854
|
-
messageRange: input.conversationMessages.length > 0 ? { start: 0, end: input.conversationMessages.length - 1 } : void 0
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
function snapshotInputTokens(snapshot) {
|
|
858
|
-
return SNAPSHOT_SPLIT_KEYS.reduce((sum, key) => sum + (snapshot.categories[key] ?? 0), 0);
|
|
859
|
-
}
|
|
860
|
-
function reconcileSnapshot(snapshot, usage) {
|
|
861
|
-
const exactInput = (usage.input || 0) + (usage.cacheRead || 0) + (usage.cacheWrite || 0);
|
|
862
|
-
const exactOutput = usage.output || 0;
|
|
863
|
-
if (exactInput <= 0) {
|
|
864
|
-
const updatedCategories2 = {
|
|
865
|
-
...snapshot.categories,
|
|
866
|
-
streaming: exactOutput
|
|
867
|
-
};
|
|
868
|
-
const window2 = snapshot.effectiveContextWindow;
|
|
869
|
-
const used2 = snapshotInputTokens(snapshot) + exactOutput;
|
|
870
|
-
let reserve2 = snapshot.categories.reserve;
|
|
871
|
-
let free2 = 0;
|
|
872
|
-
if (window2 > 0) {
|
|
873
|
-
const remaining = Math.max(0, window2 - used2);
|
|
874
|
-
reserve2 = Math.min(reserve2, remaining);
|
|
875
|
-
free2 = Math.max(0, window2 - used2 - reserve2);
|
|
876
|
-
}
|
|
877
|
-
updatedCategories2.reserve = reserve2;
|
|
878
|
-
updatedCategories2.free = free2;
|
|
879
|
-
return {
|
|
880
|
-
...snapshot,
|
|
881
|
-
categories: updatedCategories2,
|
|
882
|
-
sources: {
|
|
883
|
-
total: "estimated",
|
|
884
|
-
splits: snapshot.sources.splits
|
|
885
|
-
}
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
|
-
const keys = SNAPSHOT_SPLIT_KEYS;
|
|
889
|
-
const currentCategories = { ...snapshot.categories };
|
|
890
|
-
const sum = keys.reduce((s, k) => s + (currentCategories[k] ?? 0), 0);
|
|
891
|
-
let normalized;
|
|
892
|
-
if (sum === 0) {
|
|
893
|
-
normalized = keys.reduce(
|
|
894
|
-
(acc, k) => {
|
|
895
|
-
acc[k] = k === "messages" ? exactInput : 0;
|
|
896
|
-
return acc;
|
|
897
|
-
},
|
|
898
|
-
{}
|
|
899
|
-
);
|
|
900
|
-
} else {
|
|
901
|
-
normalized = {};
|
|
902
|
-
let newSum = 0;
|
|
903
|
-
for (const key of keys) {
|
|
904
|
-
const val = currentCategories[key] ?? 0;
|
|
905
|
-
const norm = Math.round(val / sum * exactInput);
|
|
906
|
-
normalized[key] = norm;
|
|
907
|
-
newSum += norm;
|
|
908
|
-
}
|
|
909
|
-
const diff = exactInput - newSum;
|
|
910
|
-
if (diff !== 0) {
|
|
911
|
-
const largestKey = keys.reduce((a, b) => (normalized[a] ?? 0) >= (normalized[b] ?? 0) ? a : b);
|
|
912
|
-
normalized[largestKey] = (normalized[largestKey] ?? 0) + diff;
|
|
913
|
-
}
|
|
914
|
-
}
|
|
915
|
-
const updatedCategories = {
|
|
916
|
-
...snapshot.categories,
|
|
917
|
-
...normalized,
|
|
918
|
-
streaming: exactOutput
|
|
919
|
-
};
|
|
920
|
-
const window = snapshot.effectiveContextWindow;
|
|
921
|
-
const used = exactInput + exactOutput;
|
|
922
|
-
let reserve = snapshot.categories.reserve;
|
|
923
|
-
let free = 0;
|
|
924
|
-
if (window > 0) {
|
|
925
|
-
const remaining = Math.max(0, window - used);
|
|
926
|
-
reserve = Math.min(reserve, remaining);
|
|
927
|
-
free = Math.max(0, window - used - reserve);
|
|
928
|
-
}
|
|
929
|
-
updatedCategories.reserve = reserve;
|
|
930
|
-
updatedCategories.free = free;
|
|
931
|
-
const splitsSources = keys.reduce(
|
|
932
|
-
(acc, k) => {
|
|
933
|
-
acc[k] = "reconciled";
|
|
934
|
-
return acc;
|
|
935
|
-
},
|
|
936
|
-
{}
|
|
937
|
-
);
|
|
938
|
-
return {
|
|
939
|
-
...snapshot,
|
|
940
|
-
categories: updatedCategories,
|
|
941
|
-
sources: {
|
|
942
|
-
total: "reconciled",
|
|
943
|
-
splits: splitsSources
|
|
944
|
-
}
|
|
945
|
-
};
|
|
946
|
-
}
|
|
947
|
-
|
|
948
373
|
// src/engine/apis/residency.ts
|
|
949
374
|
init_esm_shims();
|
|
950
375
|
|
|
951
376
|
// src/engine/apis/residency-lock.ts
|
|
952
377
|
init_esm_shims();
|
|
953
|
-
import { join as
|
|
378
|
+
import { join as join2 } from "node:path";
|
|
954
379
|
var LOCK_WAIT_MS = 12e4;
|
|
955
380
|
function lockTargetFor(targetKey) {
|
|
956
|
-
return
|
|
381
|
+
return join2(clioStatePath(), "residency-locks", targetKey.replace(/[^a-zA-Z0-9._-]+/g, "_"));
|
|
957
382
|
}
|
|
958
383
|
async function withResidencyLock(targetKey, fn) {
|
|
959
384
|
return withStateFileLock(lockTargetFor(targetKey), fn, {
|
|
@@ -1506,7 +931,7 @@ init_esm_shims();
|
|
|
1506
931
|
// src/domains/providers/types/local-model-quirks.ts
|
|
1507
932
|
init_esm_shims();
|
|
1508
933
|
var KV_CACHE_QUANTS = ["f32", "f16", "q8_0", "q4_0", "q4_1", "iq4_nl", "q5_0", "q5_1"];
|
|
1509
|
-
function
|
|
934
|
+
function isRecord(value) {
|
|
1510
935
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1511
936
|
}
|
|
1512
937
|
function asKvCacheQuant(value) {
|
|
@@ -1525,7 +950,7 @@ function asPenalty(value) {
|
|
|
1525
950
|
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1526
951
|
}
|
|
1527
952
|
function extractKvCache(raw) {
|
|
1528
|
-
if (!
|
|
953
|
+
if (!isRecord(raw)) return void 0;
|
|
1529
954
|
const out = {};
|
|
1530
955
|
const k = asKvCacheQuant(raw.kQuant);
|
|
1531
956
|
if (k !== void 0) out.kQuant = k;
|
|
@@ -1535,7 +960,7 @@ function extractKvCache(raw) {
|
|
|
1535
960
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
1536
961
|
}
|
|
1537
962
|
function extractSamplingProfile(raw) {
|
|
1538
|
-
if (!
|
|
963
|
+
if (!isRecord(raw)) return void 0;
|
|
1539
964
|
const out = {};
|
|
1540
965
|
const temperature = asPositive(raw.temperature);
|
|
1541
966
|
if (temperature !== void 0) out.temperature = temperature;
|
|
@@ -1556,7 +981,7 @@ function extractSamplingProfile(raw) {
|
|
|
1556
981
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
1557
982
|
}
|
|
1558
983
|
function extractSampling(raw) {
|
|
1559
|
-
if (!
|
|
984
|
+
if (!isRecord(raw)) return void 0;
|
|
1560
985
|
const out = {};
|
|
1561
986
|
const thinking = extractSamplingProfile(raw.thinking);
|
|
1562
987
|
if (thinking) out.thinking = thinking;
|
|
@@ -1576,7 +1001,7 @@ function asThinkingMechanism(value) {
|
|
|
1576
1001
|
return THINKING_MECHANISMS.includes(value) ? value : void 0;
|
|
1577
1002
|
}
|
|
1578
1003
|
function extractBudgetByLevel(raw) {
|
|
1579
|
-
if (!
|
|
1004
|
+
if (!isRecord(raw)) return void 0;
|
|
1580
1005
|
const out = {};
|
|
1581
1006
|
const minimal = asInteger(raw.minimal);
|
|
1582
1007
|
if (minimal !== void 0) out.minimal = minimal;
|
|
@@ -1591,7 +1016,7 @@ function extractBudgetByLevel(raw) {
|
|
|
1591
1016
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
1592
1017
|
}
|
|
1593
1018
|
function extractEffortByLevel(raw) {
|
|
1594
|
-
if (!
|
|
1019
|
+
if (!isRecord(raw)) return void 0;
|
|
1595
1020
|
const out = {};
|
|
1596
1021
|
if (typeof raw.off === "string" && raw.off.length > 0) out.off = raw.off;
|
|
1597
1022
|
if (typeof raw.minimal === "string" && raw.minimal.length > 0) out.minimal = raw.minimal;
|
|
@@ -1602,7 +1027,7 @@ function extractEffortByLevel(raw) {
|
|
|
1602
1027
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
1603
1028
|
}
|
|
1604
1029
|
function extractThinkingQuirks(raw) {
|
|
1605
|
-
if (!
|
|
1030
|
+
if (!isRecord(raw)) return void 0;
|
|
1606
1031
|
const mechanism = asThinkingMechanism(raw.mechanism);
|
|
1607
1032
|
if (!mechanism) return void 0;
|
|
1608
1033
|
const out = { mechanism };
|
|
@@ -1614,7 +1039,7 @@ function extractThinkingQuirks(raw) {
|
|
|
1614
1039
|
return out;
|
|
1615
1040
|
}
|
|
1616
1041
|
function extractLocalModelQuirks(raw) {
|
|
1617
|
-
if (!
|
|
1042
|
+
if (!isRecord(raw)) return void 0;
|
|
1618
1043
|
const out = {};
|
|
1619
1044
|
const kvCache = extractKvCache(raw.kvCache);
|
|
1620
1045
|
if (kvCache) out.kvCache = kvCache;
|
|
@@ -2279,7 +1704,7 @@ function targetRootUrl(target) {
|
|
|
2279
1704
|
|
|
2280
1705
|
// src/domains/providers/runtimes/common/lmstudio-http.ts
|
|
2281
1706
|
var catalogsByHost = /* @__PURE__ */ new Map();
|
|
2282
|
-
function
|
|
1707
|
+
function isRecord2(value) {
|
|
2283
1708
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2284
1709
|
}
|
|
2285
1710
|
function positiveNumber(value) {
|
|
@@ -2339,7 +1764,7 @@ async function requestLmStudioJson(url2, init, timeoutMs, signal) {
|
|
|
2339
1764
|
};
|
|
2340
1765
|
if (data !== void 0) result.data = data;
|
|
2341
1766
|
if (!response.ok) {
|
|
2342
|
-
const message =
|
|
1767
|
+
const message = isRecord2(data) ? nonEmptyString(data.error) : void 0;
|
|
2343
1768
|
result.error = message ?? `HTTP ${response.status}`;
|
|
2344
1769
|
}
|
|
2345
1770
|
return result;
|
|
@@ -2358,28 +1783,28 @@ function loadedInstances(value) {
|
|
|
2358
1783
|
if (!Array.isArray(value)) return [];
|
|
2359
1784
|
const instances = [];
|
|
2360
1785
|
for (const raw of value) {
|
|
2361
|
-
if (!
|
|
1786
|
+
if (!isRecord2(raw)) continue;
|
|
2362
1787
|
const id = nonEmptyString(raw.id);
|
|
2363
1788
|
if (!id) continue;
|
|
2364
|
-
instances.push({ id, config:
|
|
1789
|
+
instances.push({ id, config: isRecord2(raw.config) ? { ...raw.config } : {} });
|
|
2365
1790
|
}
|
|
2366
1791
|
return instances;
|
|
2367
1792
|
}
|
|
2368
1793
|
function reasoningOptions(capabilities2) {
|
|
2369
|
-
if (!
|
|
1794
|
+
if (!isRecord2(capabilities2) || !isRecord2(capabilities2.reasoning)) return void 0;
|
|
2370
1795
|
const allowed = capabilities2.reasoning.allowed_options;
|
|
2371
1796
|
if (!Array.isArray(allowed)) return void 0;
|
|
2372
1797
|
const options = allowed.filter((entry) => typeof entry === "string");
|
|
2373
1798
|
return options.length > 0 ? options : void 0;
|
|
2374
1799
|
}
|
|
2375
1800
|
function parseLmStudioV1Models(data) {
|
|
2376
|
-
if (!
|
|
1801
|
+
if (!isRecord2(data) || !Array.isArray(data.models)) return null;
|
|
2377
1802
|
const models = [];
|
|
2378
1803
|
for (const raw of data.models) {
|
|
2379
|
-
if (!
|
|
1804
|
+
if (!isRecord2(raw)) continue;
|
|
2380
1805
|
const key = nonEmptyString(raw.key);
|
|
2381
1806
|
if (!key) continue;
|
|
2382
|
-
const capabilities2 =
|
|
1807
|
+
const capabilities2 = isRecord2(raw.capabilities) ? raw.capabilities : void 0;
|
|
2383
1808
|
const info = {
|
|
2384
1809
|
key,
|
|
2385
1810
|
loadedInstances: loadedInstances(raw.loaded_instances),
|
|
@@ -2397,7 +1822,7 @@ function parseLmStudioV1Models(data) {
|
|
|
2397
1822
|
const options = reasoningOptions(capabilities2);
|
|
2398
1823
|
if (options) info.reasoningOptions = options;
|
|
2399
1824
|
if (capabilities2 && "reasoning" in capabilities2) {
|
|
2400
|
-
info.reasoning = capabilities2.reasoning === true ||
|
|
1825
|
+
info.reasoning = capabilities2.reasoning === true || isRecord2(capabilities2.reasoning);
|
|
2401
1826
|
}
|
|
2402
1827
|
models.push(info);
|
|
2403
1828
|
}
|
|
@@ -2495,10 +1920,10 @@ function lmStudioReasoningEffort(level, options) {
|
|
|
2495
1920
|
return "low";
|
|
2496
1921
|
}
|
|
2497
1922
|
function v0Models(data) {
|
|
2498
|
-
if (!
|
|
1923
|
+
if (!isRecord2(data) || !Array.isArray(data.data)) return null;
|
|
2499
1924
|
const models = [];
|
|
2500
1925
|
for (const raw of data.data) {
|
|
2501
|
-
if (!
|
|
1926
|
+
if (!isRecord2(raw)) continue;
|
|
2502
1927
|
const key = nonEmptyString(raw.id);
|
|
2503
1928
|
if (!key) continue;
|
|
2504
1929
|
const state = nonEmptyString(raw.state);
|
|
@@ -2522,10 +1947,10 @@ function v0Models(data) {
|
|
|
2522
1947
|
return models;
|
|
2523
1948
|
}
|
|
2524
1949
|
function openAIModels(data) {
|
|
2525
|
-
if (!
|
|
1950
|
+
if (!isRecord2(data) || !Array.isArray(data.data)) return null;
|
|
2526
1951
|
const models = [];
|
|
2527
1952
|
for (const raw of data.data) {
|
|
2528
|
-
if (!
|
|
1953
|
+
if (!isRecord2(raw)) continue;
|
|
2529
1954
|
const key = nonEmptyString(raw.id);
|
|
2530
1955
|
if (key) models.push({ key, loadedInstances: [], metadata: { ...raw } });
|
|
2531
1956
|
}
|
|
@@ -2585,7 +2010,7 @@ async function greetLmStudio(target, ctx) {
|
|
|
2585
2010
|
ctx.httpTimeoutMs,
|
|
2586
2011
|
ctx.signal
|
|
2587
2012
|
);
|
|
2588
|
-
if (result.ok &&
|
|
2013
|
+
if (result.ok && isRecord2(result.data) && result.data.lmstudio === true) {
|
|
2589
2014
|
return { ok: true, latencyMs: result.latencyMs };
|
|
2590
2015
|
}
|
|
2591
2016
|
return { ok: false, latencyMs: result.latencyMs, error: result.error ?? "endpoint did not return {lmstudio:true}" };
|
|
@@ -2914,6 +2339,15 @@ async function probeOpenAICompatReasoning(opts) {
|
|
|
2914
2339
|
|
|
2915
2340
|
// src/domains/providers/runtimes/common/probe-helpers.ts
|
|
2916
2341
|
init_esm_shims();
|
|
2342
|
+
|
|
2343
|
+
// src/domains/providers/types/context-window-slots.ts
|
|
2344
|
+
init_esm_shims();
|
|
2345
|
+
function formatContextWindowSlots(contextWindow, slots) {
|
|
2346
|
+
const format = (n) => Math.round(n).toLocaleString("en-US");
|
|
2347
|
+
return `${format(contextWindow)} (${format(slots.totalContextSize)} / ${slots.slots} slots)`;
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
// src/domains/providers/runtimes/common/probe-helpers.ts
|
|
2917
2351
|
async function probeUrl(url2, ctx, method = "GET") {
|
|
2918
2352
|
const base = { url: url2, timeoutMs: ctx.httpTimeoutMs, method };
|
|
2919
2353
|
return ctx.signal ? probeHttp({ ...base, signal: ctx.signal }) : probeHttp(base);
|
|
@@ -2958,11 +2392,15 @@ async function probeOpenAIModelCatalog(base, ctx, modelsPath = "/v1/models") {
|
|
|
2958
2392
|
const state = modelStateFromOpenAIModelEntry(row) ?? (detailRow ? modelStateFromOpenAIModelEntry(detailRow) : void 0) ?? // A reported loaded context is itself the residency answer: nothing
|
|
2959
2393
|
// serves a window for a model it has not loaded.
|
|
2960
2394
|
(loadedContext !== void 0 ? { state: "loaded" } : void 0);
|
|
2961
|
-
|
|
2395
|
+
const contextSlots = contextSlotsFromEntry(row) ?? (detailRow ? contextSlotsFromEntry(detailRow) : void 0);
|
|
2396
|
+
const withSlots = contextSlots ? { ...state ?? { state: "unknown" }, contextSlots } : state;
|
|
2397
|
+
if (withSlots) {
|
|
2398
|
+
modelStates[row.id] = loadedContext === void 0 ? withSlots : { ...withSlots, contextLength: loadedContext };
|
|
2399
|
+
}
|
|
2962
2400
|
}
|
|
2963
2401
|
return { models, modelCapabilities, modelStates };
|
|
2964
2402
|
}
|
|
2965
|
-
function
|
|
2403
|
+
function isRecord3(value) {
|
|
2966
2404
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
2967
2405
|
}
|
|
2968
2406
|
function positiveNumber2(value) {
|
|
@@ -2989,7 +2427,7 @@ function booleanFromAny(record, keys) {
|
|
|
2989
2427
|
}
|
|
2990
2428
|
function nestedRecord(record, key) {
|
|
2991
2429
|
const value = record[key];
|
|
2992
|
-
return
|
|
2430
|
+
return isRecord3(value) ? value : null;
|
|
2993
2431
|
}
|
|
2994
2432
|
function firstString(record, keys) {
|
|
2995
2433
|
if (!record) return void 0;
|
|
@@ -3012,7 +2450,9 @@ function normalizeModelState(raw) {
|
|
|
3012
2450
|
if (!value) return void 0;
|
|
3013
2451
|
if (value === "loaded" || value === "ready" || value === "running" || value === "active") return "loaded";
|
|
3014
2452
|
if (value === "loading" || value === "pending" || value === "queued" || value === "starting") return "loading";
|
|
3015
|
-
if (value === "unloaded" || value === "not-loaded" || value === "idle" || value === "
|
|
2453
|
+
if (value === "unloaded" || value === "not-loaded" || value === "idle" || value === "sleeping" || value === "stopped") {
|
|
2454
|
+
return "unloaded";
|
|
2455
|
+
}
|
|
3016
2456
|
if (value === "failed" || value === "error" || value === "errored") return "failed";
|
|
3017
2457
|
if (value === "unknown") return "unknown";
|
|
3018
2458
|
return void 0;
|
|
@@ -3043,11 +2483,14 @@ function statusArgsFromEntry(row) {
|
|
|
3043
2483
|
const status = nestedRecord(row, "status");
|
|
3044
2484
|
return argsFromStatus(status);
|
|
3045
2485
|
}
|
|
2486
|
+
function contextSlotsFromEntry(row) {
|
|
2487
|
+
return llamaCppRequestContextWindow(parseLlamaCppServerFlags(statusArgsFromEntry(row)))?.slots;
|
|
2488
|
+
}
|
|
3046
2489
|
function capabilitiesFromOpenAIModelEntry(row) {
|
|
3047
2490
|
const caps = {};
|
|
3048
2491
|
const meta = nestedRecord(row, "meta");
|
|
3049
2492
|
const flags = parseLlamaCppServerFlags(statusArgsFromEntry(row));
|
|
3050
|
-
const contextWindow =
|
|
2493
|
+
const contextWindow = llamaCppRequestContextWindow(flags)?.contextWindow ?? firstPositiveNumber(row, [
|
|
3051
2494
|
// What is actually loaded outranks what the model could support: a
|
|
3052
2495
|
// model served at 8k out of a possible 262k has an 8k window today,
|
|
3053
2496
|
// and the run has to be planned against the real one.
|
|
@@ -3100,27 +2543,45 @@ async function probeOpenAIModelEntries(base, ctx) {
|
|
|
3100
2543
|
if (!result.ok) return [];
|
|
3101
2544
|
return modelEntries(result.data);
|
|
3102
2545
|
}
|
|
2546
|
+
function llamaCppRequestContextWindow(flags) {
|
|
2547
|
+
const total = positiveNumber2(flags.contextSize);
|
|
2548
|
+
if (total === void 0) return void 0;
|
|
2549
|
+
const parallel = positiveNumber2(flags.parallel);
|
|
2550
|
+
if (parallel === void 0 || parallel <= 1 || flags.kvUnified === true) return { contextWindow: Math.floor(total) };
|
|
2551
|
+
const slots = Math.floor(parallel);
|
|
2552
|
+
return {
|
|
2553
|
+
contextWindow: Math.floor(total / slots),
|
|
2554
|
+
slots: { totalContextSize: Math.floor(total), slots }
|
|
2555
|
+
};
|
|
2556
|
+
}
|
|
3103
2557
|
function argsFromStatus(status) {
|
|
3104
|
-
if (!
|
|
2558
|
+
if (!isRecord3(status)) return [];
|
|
3105
2559
|
const args = status.args;
|
|
3106
2560
|
if (Array.isArray(args)) return args.filter((entry) => typeof entry === "string");
|
|
3107
2561
|
if (typeof args === "string") return args.trim().split(/\s+/).filter(Boolean);
|
|
3108
2562
|
return [];
|
|
3109
2563
|
}
|
|
3110
|
-
function
|
|
3111
|
-
|
|
3112
|
-
if (index < 0) return void 0;
|
|
3113
|
-
const value = args[index + 1];
|
|
3114
|
-
return value && !value.startsWith("--") ? value : void 0;
|
|
2564
|
+
function looksLikeFlag(token) {
|
|
2565
|
+
return token.startsWith("-") && Number.isNaN(Number(token));
|
|
3115
2566
|
}
|
|
3116
|
-
function
|
|
3117
|
-
const
|
|
2567
|
+
function valueAfter(args, ...flags) {
|
|
2568
|
+
for (const flag of flags) {
|
|
2569
|
+
const index = args.indexOf(flag);
|
|
2570
|
+
if (index < 0) continue;
|
|
2571
|
+
const value = args[index + 1];
|
|
2572
|
+
return value && !looksLikeFlag(value) ? value : void 0;
|
|
2573
|
+
}
|
|
2574
|
+
return void 0;
|
|
2575
|
+
}
|
|
2576
|
+
function numberFlag(args, ...flags) {
|
|
2577
|
+
const value = valueAfter(args, ...flags);
|
|
3118
2578
|
if (value === void 0) return void 0;
|
|
3119
2579
|
const parsed = Number(value);
|
|
3120
2580
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
3121
2581
|
}
|
|
3122
|
-
function booleanFlag(args,
|
|
3123
|
-
|
|
2582
|
+
function booleanFlag(args, ...flags) {
|
|
2583
|
+
const flag = flags.find((candidate) => args.includes(candidate));
|
|
2584
|
+
if (flag === void 0) return void 0;
|
|
3124
2585
|
const value = valueAfter(args, flag);
|
|
3125
2586
|
if (value === void 0) return true;
|
|
3126
2587
|
const normalized = value.toLowerCase();
|
|
@@ -3130,7 +2591,7 @@ function booleanFlag(args, flag) {
|
|
|
3130
2591
|
}
|
|
3131
2592
|
function parseLlamaCppServerFlags(args) {
|
|
3132
2593
|
const flags = {};
|
|
3133
|
-
const ctxSize = numberFlag(args, "--ctx-size");
|
|
2594
|
+
const ctxSize = numberFlag(args, "--ctx-size", "-c");
|
|
3134
2595
|
if (ctxSize !== void 0) flags.contextSize = ctxSize;
|
|
3135
2596
|
const maxTokens = numberFlag(args, "--n-predict");
|
|
3136
2597
|
if (maxTokens !== void 0) flags.maxTokens = maxTokens;
|
|
@@ -3150,8 +2611,12 @@ function parseLlamaCppServerFlags(args) {
|
|
|
3150
2611
|
if (topK !== void 0) flags.topK = topK;
|
|
3151
2612
|
const nGpuLayers = numberFlag(args, "--n-gpu-layers");
|
|
3152
2613
|
if (nGpuLayers !== void 0) flags.nGpuLayers = nGpuLayers;
|
|
3153
|
-
const parallel = numberFlag(args, "--parallel");
|
|
2614
|
+
const parallel = numberFlag(args, "--parallel", "-np");
|
|
3154
2615
|
if (parallel !== void 0) flags.parallel = parallel;
|
|
2616
|
+
const kvUnifiedAt = Math.max(args.lastIndexOf("--kv-unified"), args.lastIndexOf("-kvu"));
|
|
2617
|
+
const noKvUnifiedAt = args.lastIndexOf("--no-kv-unified");
|
|
2618
|
+
if (noKvUnifiedAt > kvUnifiedAt) flags.kvUnified = false;
|
|
2619
|
+
else if (kvUnifiedAt >= 0) flags.kvUnified = booleanFlag(args, "--kv-unified", "-kvu") ?? true;
|
|
3155
2620
|
const cacheTypeK = valueAfter(args, "--cache-type-k");
|
|
3156
2621
|
if (cacheTypeK) flags.cacheTypeK = cacheTypeK;
|
|
3157
2622
|
const cacheTypeV = valueAfter(args, "--cache-type-v");
|
|
@@ -3168,7 +2633,7 @@ function selectedModelEntry(entries, target) {
|
|
|
3168
2633
|
return entries[0] ?? null;
|
|
3169
2634
|
}
|
|
3170
2635
|
function statusNotes(id, status) {
|
|
3171
|
-
if (!
|
|
2636
|
+
if (!isRecord3(status)) return [];
|
|
3172
2637
|
const notes = [];
|
|
3173
2638
|
if (status.failed === true) notes.push(`llama.cpp router marks ${id} as failed`);
|
|
3174
2639
|
const state = typeof status.state === "string" ? status.state : void 0;
|
|
@@ -3183,7 +2648,8 @@ async function probeLlamaCppModelStatus(base, target, ctx) {
|
|
|
3183
2648
|
if (args.length === 0) return { notes: statusNotes(selected.id, selected.status) };
|
|
3184
2649
|
const flags = parseLlamaCppServerFlags(args);
|
|
3185
2650
|
const caps = {};
|
|
3186
|
-
|
|
2651
|
+
const window = llamaCppRequestContextWindow(flags);
|
|
2652
|
+
if (window !== void 0) caps.contextWindow = window.contextWindow;
|
|
3187
2653
|
if (flags.maxTokens !== void 0 && flags.maxTokens > 0) caps.maxTokens = flags.maxTokens;
|
|
3188
2654
|
if (flags.reasoning === true || flags.reasoningBudget !== void 0) caps.reasoning = true;
|
|
3189
2655
|
if (flags.mmproj) caps.vision = true;
|
|
@@ -3191,6 +2657,11 @@ async function probeLlamaCppModelStatus(base, target, ctx) {
|
|
|
3191
2657
|
const enrichment = { modelId: selected.id, serverFlags: flags };
|
|
3192
2658
|
if (Object.keys(caps).length > 0) enrichment.discoveredCapabilities = caps;
|
|
3193
2659
|
const notes = statusNotes(selected.id, selected.status);
|
|
2660
|
+
if (window?.slots) {
|
|
2661
|
+
notes.push(
|
|
2662
|
+
`${selected.id} context window ${formatContextWindowSlots(window.contextWindow, window.slots)}: --ctx-size is split across --parallel slots without --kv-unified`
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
3194
2665
|
if (notes.length > 0) enrichment.notes = notes;
|
|
3195
2666
|
return enrichment;
|
|
3196
2667
|
}
|
|
@@ -5148,6 +4619,9 @@ function loadedContextWindowForModel(status, modelId) {
|
|
|
5148
4619
|
const reported = status?.discoveredModelStates?.[modelId]?.contextLength;
|
|
5149
4620
|
return typeof reported === "number" && Number.isFinite(reported) && reported > 0 ? reported : null;
|
|
5150
4621
|
}
|
|
4622
|
+
function contextSlotsForModel(status, modelId) {
|
|
4623
|
+
return status?.discoveredModelStates?.[modelId]?.contextSlots ?? null;
|
|
4624
|
+
}
|
|
5151
4625
|
function modelResidencyForStatus(status, modelId) {
|
|
5152
4626
|
if (loadedContextWindowForModel(status, modelId) !== null) return "resident";
|
|
5153
4627
|
switch (status?.discoveredModelStates?.[modelId]?.state) {
|
|
@@ -5414,7 +4888,9 @@ function resolveRuntimeTarget(providers, input) {
|
|
|
5414
4888
|
wireModelId,
|
|
5415
4889
|
providers.knowledgeBase,
|
|
5416
4890
|
probedContextWindow,
|
|
5417
|
-
loadedContextWindow
|
|
4891
|
+
loadedContextWindow,
|
|
4892
|
+
void 0,
|
|
4893
|
+
contextSlotsForModel(status, wireModelId)
|
|
5418
4894
|
);
|
|
5419
4895
|
capabilities2.contextWindow = contextWindowDetails.effectiveContextWindow;
|
|
5420
4896
|
if (contextWindowDetails.warning) {
|
|
@@ -5495,7 +4971,8 @@ function refineRuntimeTargetWithModelHints(target, model, knowledgeBase) {
|
|
|
5495
4971
|
// one the backend has open. Re-resolving without the loaded number would
|
|
5496
4972
|
// hand the planner the declared window back on the first refinement.
|
|
5497
4973
|
target.contextWindowDetails.loadedContextWindow,
|
|
5498
|
-
modelHintContextWindow
|
|
4974
|
+
modelHintContextWindow,
|
|
4975
|
+
target.contextWindowDetails.contextWindowSlots
|
|
5499
4976
|
);
|
|
5500
4977
|
capabilities2.contextWindow = contextWindowDetails.effectiveContextWindow;
|
|
5501
4978
|
const modelRuntime = resolveModelRuntimeCapabilities({
|
|
@@ -5554,12 +5031,16 @@ function firstRuntimeResolutionError(diagnostics) {
|
|
|
5554
5031
|
function runtimeResolutionWarnings(diagnostics) {
|
|
5555
5032
|
return diagnostics.filter((entry) => entry.severity === "warning").map((entry) => entry.message);
|
|
5556
5033
|
}
|
|
5034
|
+
function runtimeResolutionWarningsBesideThinkingNotice(diagnostics, thinkingNotice) {
|
|
5035
|
+
if (thinkingNotice.trim().length === 0) return runtimeResolutionWarnings(diagnostics);
|
|
5036
|
+
return runtimeResolutionWarnings(diagnostics.filter((entry) => !entry.code.startsWith("thinking-")));
|
|
5037
|
+
}
|
|
5557
5038
|
var DESIRED_CONTEXT_WINDOW = CLIO_MIN_CONTEXT_WINDOW;
|
|
5558
5039
|
var FALLBACK_CONTEXT_WINDOW = CLIO_MIN_CONTEXT_WINDOW;
|
|
5559
5040
|
function positiveWindow(value) {
|
|
5560
5041
|
return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : void 0;
|
|
5561
5042
|
}
|
|
5562
|
-
function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase, probedContextWindow, loadedContextWindow = null, modelHintContextWindow) {
|
|
5043
|
+
function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase, probedContextWindow, loadedContextWindow = null, modelHintContextWindow, probedContextSlots = null) {
|
|
5563
5044
|
const catalogModel = getCatalogModelForRuntime(runtime.id, wireModelId);
|
|
5564
5045
|
const kbHit = knowledgeBase?.lookup(wireModelId) ?? null;
|
|
5565
5046
|
let modelDeclared;
|
|
@@ -5614,6 +5095,7 @@ function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase
|
|
|
5614
5095
|
if (source === "descriptor-default" || source === "unknown") {
|
|
5615
5096
|
provenanceNotice = `Context window ${effective} is Clio's assumed minimum, not a figure this target reported. Run 'clio-coder targets --probe' to read the real one.`;
|
|
5616
5097
|
}
|
|
5098
|
+
const contextWindowSlots = source === "probe" && probedContextSlots !== null && Math.floor(probedContextSlots.totalContextSize / probedContextSlots.slots) === effective ? probedContextSlots : null;
|
|
5617
5099
|
return {
|
|
5618
5100
|
declaredContextWindow,
|
|
5619
5101
|
probedContextWindow,
|
|
@@ -5621,6 +5103,7 @@ function resolveContextWindowDetails(target, runtime, wireModelId, knowledgeBase
|
|
|
5621
5103
|
desiredContextWindow: desired,
|
|
5622
5104
|
effectiveContextWindow: effective,
|
|
5623
5105
|
contextWindowSource: source,
|
|
5106
|
+
contextWindowSlots,
|
|
5624
5107
|
warning,
|
|
5625
5108
|
provenanceNotice
|
|
5626
5109
|
};
|
|
@@ -5837,63 +5320,6 @@ function filterGemmaChannelStream(source, enabled) {
|
|
|
5837
5320
|
return filtered;
|
|
5838
5321
|
}
|
|
5839
5322
|
|
|
5840
|
-
// src/engine/strip-tokenizer-sentinels.ts
|
|
5841
|
-
init_esm_shims();
|
|
5842
|
-
var KNOWN_SENTINELS = [
|
|
5843
|
-
"<|endoftext|>",
|
|
5844
|
-
"<|im_start|>",
|
|
5845
|
-
"<|im_end|>",
|
|
5846
|
-
"<|eot_id|>",
|
|
5847
|
-
"<|end_of_turn|>",
|
|
5848
|
-
"<|fim_prefix|>",
|
|
5849
|
-
"<|fim_middle|>",
|
|
5850
|
-
"<|fim_suffix|>",
|
|
5851
|
-
"<|file_separator|>",
|
|
5852
|
-
"<s>",
|
|
5853
|
-
"</s>"
|
|
5854
|
-
];
|
|
5855
|
-
var SENTINEL_RE = new RegExp(KNOWN_SENTINELS.map((s) => s.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&")).join("|"), "g");
|
|
5856
|
-
var MAX_SENTINEL_LEN = KNOWN_SENTINELS.reduce((max, s) => s.length > max ? s.length : max, 0);
|
|
5857
|
-
function stripTokenizerSentinels(text) {
|
|
5858
|
-
if (text.length === 0) return text;
|
|
5859
|
-
return text.replace(SENTINEL_RE, "");
|
|
5860
|
-
}
|
|
5861
|
-
function isSentinelPrefix(tail) {
|
|
5862
|
-
if (tail.length === 0) return false;
|
|
5863
|
-
for (const sentinel of KNOWN_SENTINELS) {
|
|
5864
|
-
if (sentinel.length > tail.length && sentinel.startsWith(tail)) return true;
|
|
5865
|
-
}
|
|
5866
|
-
return false;
|
|
5867
|
-
}
|
|
5868
|
-
function createSentinelStripper() {
|
|
5869
|
-
let buffer = "";
|
|
5870
|
-
return {
|
|
5871
|
-
push(chunk) {
|
|
5872
|
-
if (chunk.length === 0) return "";
|
|
5873
|
-
buffer += chunk;
|
|
5874
|
-
const stripped = buffer.replace(SENTINEL_RE, "");
|
|
5875
|
-
const holdMax = Math.min(stripped.length, MAX_SENTINEL_LEN - 1);
|
|
5876
|
-
let hold = 0;
|
|
5877
|
-
for (let take = holdMax; take > 0; take--) {
|
|
5878
|
-
const tail = stripped.slice(stripped.length - take);
|
|
5879
|
-
if (isSentinelPrefix(tail)) {
|
|
5880
|
-
hold = take;
|
|
5881
|
-
break;
|
|
5882
|
-
}
|
|
5883
|
-
}
|
|
5884
|
-
const safe = hold === 0 ? stripped : stripped.slice(0, stripped.length - hold);
|
|
5885
|
-
buffer = hold === 0 ? "" : stripped.slice(stripped.length - hold);
|
|
5886
|
-
return safe;
|
|
5887
|
-
},
|
|
5888
|
-
flush() {
|
|
5889
|
-
if (buffer.length === 0) return "";
|
|
5890
|
-
const remainder = buffer.replace(SENTINEL_RE, "");
|
|
5891
|
-
buffer = "";
|
|
5892
|
-
return remainder;
|
|
5893
|
-
}
|
|
5894
|
-
};
|
|
5895
|
-
}
|
|
5896
|
-
|
|
5897
5323
|
// src/engine/apis/output-budget.ts
|
|
5898
5324
|
init_esm_shims();
|
|
5899
5325
|
var CONTEXT_BUDGET_SAFETY_TOKENS = 1024;
|
|
@@ -6340,6 +5766,7 @@ var ollamaNativeApiProvider = {
|
|
|
6340
5766
|
|
|
6341
5767
|
// src/engine/apis/openai-completions.ts
|
|
6342
5768
|
init_esm_shims();
|
|
5769
|
+
import { TextDecoder as TextDecoder2 } from "node:util";
|
|
6343
5770
|
import {
|
|
6344
5771
|
createAssistantMessageEventStream as createAssistantMessageEventStream3
|
|
6345
5772
|
} from "@earendil-works/pi-ai";
|
|
@@ -6472,24 +5899,24 @@ var POLL_INTERVAL_MS = 500;
|
|
|
6472
5899
|
function isResidentState(state) {
|
|
6473
5900
|
return state === "loaded" || state === "loading" || state === "sleeping";
|
|
6474
5901
|
}
|
|
6475
|
-
function
|
|
5902
|
+
function isRecord4(value) {
|
|
6476
5903
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6477
5904
|
}
|
|
6478
5905
|
function routerModelState(entry) {
|
|
6479
5906
|
const status = entry.status;
|
|
6480
|
-
const state =
|
|
5907
|
+
const state = isRecord4(status) ? status.value : status;
|
|
6481
5908
|
if (state === "loaded" || state === "loading" || state === "sleeping" || state === "unloaded" || state === "failed") {
|
|
6482
5909
|
return state;
|
|
6483
5910
|
}
|
|
6484
5911
|
return "unknown";
|
|
6485
5912
|
}
|
|
6486
5913
|
function parseRouterModels(payload) {
|
|
6487
|
-
if (!
|
|
5914
|
+
if (!isRecord4(payload)) return [];
|
|
6488
5915
|
const data = payload.data;
|
|
6489
5916
|
if (!Array.isArray(data)) return [];
|
|
6490
5917
|
const models = [];
|
|
6491
5918
|
for (const entry of data) {
|
|
6492
|
-
if (!
|
|
5919
|
+
if (!isRecord4(entry) || typeof entry.id !== "string") continue;
|
|
6493
5920
|
const tags = Array.isArray(entry.tags) ? entry.tags.filter((tag) => typeof tag === "string") : [];
|
|
6494
5921
|
models.push({ id: entry.id, state: routerModelState(entry), tags });
|
|
6495
5922
|
}
|
|
@@ -6499,7 +5926,7 @@ function residentModel(model) {
|
|
|
6499
5926
|
return isResidentState(model.state);
|
|
6500
5927
|
}
|
|
6501
5928
|
function parseLlamaCppRouterProps(payload) {
|
|
6502
|
-
if (!
|
|
5929
|
+
if (!isRecord4(payload)) return {};
|
|
6503
5930
|
const maxInstances = payload.max_instances;
|
|
6504
5931
|
return typeof maxInstances === "number" && Number.isFinite(maxInstances) && maxInstances > 0 ? { maxInstances: Math.floor(maxInstances) } : {};
|
|
6505
5932
|
}
|
|
@@ -6727,6 +6154,12 @@ async function loadOwnedInstance(target, targetKey, body, apiKey, signal) {
|
|
|
6727
6154
|
if (instanceId) ownedInstances(targetKey).add(instanceId);
|
|
6728
6155
|
return instanceId;
|
|
6729
6156
|
}
|
|
6157
|
+
var announcedResidencyFacts = /* @__PURE__ */ new Set();
|
|
6158
|
+
function emitResidencyNoticeOnce(key, notice) {
|
|
6159
|
+
if (announcedResidencyFacts.has(key)) return;
|
|
6160
|
+
announcedResidencyFacts.add(key);
|
|
6161
|
+
emitResidencyNotice(notice);
|
|
6162
|
+
}
|
|
6730
6163
|
async function ensureLmStudioResidency(model, options = {}) {
|
|
6731
6164
|
const target = targetForModel(model);
|
|
6732
6165
|
if (!target) return model.id;
|
|
@@ -6749,7 +6182,7 @@ async function ensureLmStudioResidency(model, options = {}) {
|
|
|
6749
6182
|
);
|
|
6750
6183
|
}
|
|
6751
6184
|
if (resolution.wireModelId !== model.id) {
|
|
6752
|
-
|
|
6185
|
+
emitResidencyNoticeOnce(`resolved|${info.targetId}|${model.id}|${resolution.wireModelId}`, {
|
|
6753
6186
|
kind: "co-resident",
|
|
6754
6187
|
level: "info",
|
|
6755
6188
|
targetId: info.targetId,
|
|
@@ -6760,14 +6193,16 @@ async function ensureLmStudioResidency(model, options = {}) {
|
|
|
6760
6193
|
});
|
|
6761
6194
|
}
|
|
6762
6195
|
if (resolution.peerTargets.length > 0) {
|
|
6763
|
-
|
|
6196
|
+
const peers = resolution.peerTargets.join(", ");
|
|
6197
|
+
const requested = resolution.wireModelId === model.id ? "" : ` (requested '${model.id}')`;
|
|
6198
|
+
emitResidencyNoticeOnce(`peer|${info.targetId}|${model.id}|${resolution.wireModelId}|${peers}`, {
|
|
6764
6199
|
kind: "co-resident",
|
|
6765
6200
|
level: "warning",
|
|
6766
6201
|
targetId: info.targetId,
|
|
6767
6202
|
runtimeId: "lmstudio",
|
|
6768
6203
|
model: resolution.wireModelId,
|
|
6769
|
-
message: `LM Studio instance '${resolution.wireModelId}' is also loaded on ${
|
|
6770
|
-
detail: {
|
|
6204
|
+
message: `LM Studio instance '${resolution.wireModelId}'${requested} is also loaded on ${peers}; a request may be served by that LM Link peer, and the footer and usage ledger name the id that answered when it differs.`,
|
|
6205
|
+
detail: { requestedModel: model.id, wireModel: resolution.wireModelId, peerTargets: peers }
|
|
6771
6206
|
});
|
|
6772
6207
|
}
|
|
6773
6208
|
if (!load || Object.keys(load).length === 0 || resolution.instance) return resolution.wireModelId;
|
|
@@ -6853,6 +6288,98 @@ function pickSamplingProfile2(quirks, thinkingActive) {
|
|
|
6853
6288
|
function isPlainRecord(value) {
|
|
6854
6289
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
6855
6290
|
}
|
|
6291
|
+
function observeResponseModelIdLine(line, capture) {
|
|
6292
|
+
if (capture.done) return;
|
|
6293
|
+
const normalized = line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
6294
|
+
if (!normalized.startsWith("data:")) return;
|
|
6295
|
+
const data = normalized.slice("data:".length).trimStart();
|
|
6296
|
+
if (data.length === 0 || data === "[DONE]") return;
|
|
6297
|
+
try {
|
|
6298
|
+
const payload = JSON.parse(data);
|
|
6299
|
+
if (!isPlainRecord(payload)) return;
|
|
6300
|
+
const model = payload.model;
|
|
6301
|
+
if (typeof model === "string" && model.trim().length > 0) {
|
|
6302
|
+
capture.reportedModelId = model.trim();
|
|
6303
|
+
capture.done = true;
|
|
6304
|
+
}
|
|
6305
|
+
} catch {
|
|
6306
|
+
}
|
|
6307
|
+
}
|
|
6308
|
+
function observeResponseModelIdBytes(chunk, capture, flush = false) {
|
|
6309
|
+
if (capture.done || !capture.decoder) return;
|
|
6310
|
+
capture.buffer += chunk ? capture.decoder.decode(chunk, { stream: !flush }) : capture.decoder.decode();
|
|
6311
|
+
let newline = capture.buffer.indexOf("\n");
|
|
6312
|
+
while (newline >= 0) {
|
|
6313
|
+
const line = capture.buffer.slice(0, newline);
|
|
6314
|
+
capture.buffer = capture.buffer.slice(newline + 1);
|
|
6315
|
+
observeResponseModelIdLine(line, capture);
|
|
6316
|
+
if (capture.done) {
|
|
6317
|
+
capture.buffer = "";
|
|
6318
|
+
capture.decoder = null;
|
|
6319
|
+
return;
|
|
6320
|
+
}
|
|
6321
|
+
newline = capture.buffer.indexOf("\n");
|
|
6322
|
+
}
|
|
6323
|
+
if (flush && capture.buffer.length > 0) {
|
|
6324
|
+
observeResponseModelIdLine(capture.buffer, capture);
|
|
6325
|
+
capture.buffer = "";
|
|
6326
|
+
}
|
|
6327
|
+
if (capture.done || flush) capture.decoder = null;
|
|
6328
|
+
}
|
|
6329
|
+
function captureResponseModelId(response, capture) {
|
|
6330
|
+
if (!response.body || !response.headers.get("content-type")?.toLowerCase().includes("text/event-stream")) {
|
|
6331
|
+
return response;
|
|
6332
|
+
}
|
|
6333
|
+
const body = response.body.pipeThrough(
|
|
6334
|
+
new TransformStream({
|
|
6335
|
+
transform(chunk, controller) {
|
|
6336
|
+
capture.observed = true;
|
|
6337
|
+
if (!capture.done) observeResponseModelIdBytes(chunk, capture);
|
|
6338
|
+
controller.enqueue(chunk);
|
|
6339
|
+
},
|
|
6340
|
+
flush() {
|
|
6341
|
+
capture.observed = true;
|
|
6342
|
+
if (!capture.done) observeResponseModelIdBytes(void 0, capture, true);
|
|
6343
|
+
}
|
|
6344
|
+
})
|
|
6345
|
+
);
|
|
6346
|
+
return new Response(body, {
|
|
6347
|
+
status: response.status,
|
|
6348
|
+
statusText: response.statusText,
|
|
6349
|
+
headers: response.headers
|
|
6350
|
+
});
|
|
6351
|
+
}
|
|
6352
|
+
function withResponseModelIdCapture(options, sourceFactory) {
|
|
6353
|
+
const capture = {
|
|
6354
|
+
reportedModelId: null,
|
|
6355
|
+
observed: false,
|
|
6356
|
+
done: false,
|
|
6357
|
+
buffer: "",
|
|
6358
|
+
decoder: new TextDecoder2()
|
|
6359
|
+
};
|
|
6360
|
+
const fetchImpl = options.fetch ?? ((input, init) => globalThis.fetch(input, init));
|
|
6361
|
+
const capturedOptions = {
|
|
6362
|
+
...options,
|
|
6363
|
+
fetch: async (input, init) => captureResponseModelId(await fetchImpl(input, init), capture)
|
|
6364
|
+
};
|
|
6365
|
+
const source = sourceFactory(capturedOptions);
|
|
6366
|
+
const annotated = createAssistantMessageEventStream3();
|
|
6367
|
+
(async () => {
|
|
6368
|
+
try {
|
|
6369
|
+
for await (const event of source) {
|
|
6370
|
+
const observation = capture.observed ? capture.reportedModelId === null ? { state: "not-reported" } : { state: "reported", reportedModelId: capture.reportedModelId } : { state: "not-observed" };
|
|
6371
|
+
if (event.type === "done") event.message.responseModelIdObservation = observation;
|
|
6372
|
+
else if (event.type === "error") event.error.responseModelIdObservation = observation;
|
|
6373
|
+
annotated.push(event);
|
|
6374
|
+
}
|
|
6375
|
+
annotated.end();
|
|
6376
|
+
} catch (err) {
|
|
6377
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
6378
|
+
throw new Error(message);
|
|
6379
|
+
}
|
|
6380
|
+
})();
|
|
6381
|
+
return annotated;
|
|
6382
|
+
}
|
|
6856
6383
|
function samplingParamsFromProfile(profile) {
|
|
6857
6384
|
return {
|
|
6858
6385
|
...profile.topP !== void 0 ? { top_p: profile.topP } : {},
|
|
@@ -7336,16 +6863,15 @@ var openAICompletionsApiProvider = {
|
|
|
7336
6863
|
stripSentinelsFromStream(
|
|
7337
6864
|
stripNeverReasoningFromStream(
|
|
7338
6865
|
filterGemmaChannelStream(
|
|
7339
|
-
|
|
7340
|
-
model,
|
|
7341
|
-
|
|
7342
|
-
|
|
7343
|
-
|
|
7344
|
-
|
|
7345
|
-
|
|
7346
|
-
|
|
7347
|
-
effectiveContext,
|
|
7348
|
-
withRemainingContextBudget(model, effectiveContext, withSamplers)
|
|
6866
|
+
withResponseModelIdCapture(
|
|
6867
|
+
withRemainingContextBudget(model, effectiveContext, withSamplers),
|
|
6868
|
+
(capturedOptions) => withLocalResidency(
|
|
6869
|
+
model,
|
|
6870
|
+
{
|
|
6871
|
+
...options?.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
6872
|
+
...options?.signal !== void 0 ? { signal: options.signal } : {}
|
|
6873
|
+
},
|
|
6874
|
+
(requestModel) => piOpenAICompletions.stream(requestModel, effectiveContext, capturedOptions)
|
|
7349
6875
|
)
|
|
7350
6876
|
),
|
|
7351
6877
|
resolved.family === "gemma-4"
|
|
@@ -7368,16 +6894,15 @@ var openAICompletionsApiProvider = {
|
|
|
7368
6894
|
stripSentinelsFromStream(
|
|
7369
6895
|
stripNeverReasoningFromStream(
|
|
7370
6896
|
filterGemmaChannelStream(
|
|
7371
|
-
|
|
7372
|
-
model,
|
|
7373
|
-
|
|
7374
|
-
|
|
7375
|
-
|
|
7376
|
-
|
|
7377
|
-
|
|
7378
|
-
|
|
7379
|
-
effectiveContext,
|
|
7380
|
-
withRemainingContextBudget(model, effectiveContext, withSamplers)
|
|
6897
|
+
withResponseModelIdCapture(
|
|
6898
|
+
withRemainingContextBudget(model, effectiveContext, withSamplers),
|
|
6899
|
+
(capturedOptions) => withLocalResidency(
|
|
6900
|
+
model,
|
|
6901
|
+
{
|
|
6902
|
+
...options?.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
|
|
6903
|
+
...options?.signal !== void 0 ? { signal: options.signal } : {}
|
|
6904
|
+
},
|
|
6905
|
+
(requestModel) => piOpenAICompletions.streamSimple(requestModel, effectiveContext, capturedOptions)
|
|
7381
6906
|
)
|
|
7382
6907
|
),
|
|
7383
6908
|
resolved.family === "gemma-4"
|
|
@@ -7404,8 +6929,8 @@ function registerClioApiProviders() {
|
|
|
7404
6929
|
|
|
7405
6930
|
// src/domains/providers/knowledge-base-path.ts
|
|
7406
6931
|
init_esm_shims();
|
|
7407
|
-
import { existsSync
|
|
7408
|
-
import { delimiter, dirname
|
|
6932
|
+
import { existsSync, statSync as statSync2 } from "node:fs";
|
|
6933
|
+
import { delimiter, dirname, join as join3 } from "node:path";
|
|
7409
6934
|
import { fileURLToPath } from "node:url";
|
|
7410
6935
|
var MODEL_CATALOG_OVERLAY_DIR = "model-catalog.d";
|
|
7411
6936
|
var MODEL_CATALOG_DIRS_ENV = "CLIO_CODER_MODEL_CATALOG_DIRS";
|
|
@@ -7417,25 +6942,25 @@ function isDirectory(path) {
|
|
|
7417
6942
|
}
|
|
7418
6943
|
}
|
|
7419
6944
|
function resolveProvidersModelsDir(importMetaUrl) {
|
|
7420
|
-
const start =
|
|
6945
|
+
const start = dirname(fileURLToPath(importMetaUrl));
|
|
7421
6946
|
const directCandidates = [
|
|
7422
|
-
|
|
7423
|
-
|
|
7424
|
-
|
|
6947
|
+
join3(start, "models"),
|
|
6948
|
+
join3(start, "..", "domains", "providers", "models"),
|
|
6949
|
+
join3(start, "..", "providers-models")
|
|
7425
6950
|
];
|
|
7426
6951
|
for (const candidate of directCandidates) {
|
|
7427
6952
|
if (isDirectory(candidate)) return candidate;
|
|
7428
6953
|
}
|
|
7429
6954
|
let cursor = start;
|
|
7430
6955
|
for (let i = 0; i < 8; i++) {
|
|
7431
|
-
const packageJson =
|
|
7432
|
-
const sourceModels =
|
|
7433
|
-
const distModels =
|
|
7434
|
-
if (
|
|
6956
|
+
const packageJson = join3(cursor, "package.json");
|
|
6957
|
+
const sourceModels = join3(cursor, "src", "domains", "providers", "models");
|
|
6958
|
+
const distModels = join3(cursor, "dist", "providers-models");
|
|
6959
|
+
if (existsSync(packageJson)) {
|
|
7435
6960
|
if (isDirectory(sourceModels)) return sourceModels;
|
|
7436
6961
|
if (isDirectory(distModels)) return distModels;
|
|
7437
6962
|
}
|
|
7438
|
-
const parent =
|
|
6963
|
+
const parent = dirname(cursor);
|
|
7439
6964
|
if (parent === cursor) break;
|
|
7440
6965
|
cursor = parent;
|
|
7441
6966
|
}
|
|
@@ -7461,8 +6986,8 @@ function resolveProviderModelCatalogDirs(importMetaUrl, options = {}) {
|
|
|
7461
6986
|
const bundled = resolveProvidersModelsDir(importMetaUrl);
|
|
7462
6987
|
const cwd = options.cwd ?? process.cwd();
|
|
7463
6988
|
const overlays = uniqueExistingDirs([
|
|
7464
|
-
|
|
7465
|
-
|
|
6989
|
+
join3(resolveClioDirs().config, MODEL_CATALOG_OVERLAY_DIR),
|
|
6990
|
+
join3(cwd, ".clio-coder", MODEL_CATALOG_OVERLAY_DIR),
|
|
7466
6991
|
...envOverlayDirs()
|
|
7467
6992
|
]);
|
|
7468
6993
|
return {
|
|
@@ -7481,7 +7006,7 @@ function resolveProviderKnowledgeBaseRoots(importMetaUrl, options = {}) {
|
|
|
7481
7006
|
|
|
7482
7007
|
// src/domains/providers/plugins.ts
|
|
7483
7008
|
init_esm_shims();
|
|
7484
|
-
import { join as
|
|
7009
|
+
import { join as join4 } from "node:path";
|
|
7485
7010
|
function extractPluginPackages(settings) {
|
|
7486
7011
|
if (!settings || typeof settings !== "object") return [];
|
|
7487
7012
|
const raw = settings.runtimePlugins;
|
|
@@ -7490,7 +7015,7 @@ function extractPluginPackages(settings) {
|
|
|
7490
7015
|
}
|
|
7491
7016
|
async function loadPluginRuntimes(registry, settings) {
|
|
7492
7017
|
const loaded = [];
|
|
7493
|
-
const pluginDir =
|
|
7018
|
+
const pluginDir = join4(clioConfigDir(), "runtimes");
|
|
7494
7019
|
const packages = extractPluginPackages(settings);
|
|
7495
7020
|
try {
|
|
7496
7021
|
const ids = await registry.loadFromDir(pluginDir, activateExternalPluginApiBridge);
|
|
@@ -7518,8 +7043,8 @@ async function loadPluginRuntimes(registry, settings) {
|
|
|
7518
7043
|
// src/domains/providers/types/knowledge-base.ts
|
|
7519
7044
|
init_esm_shims();
|
|
7520
7045
|
var import_yaml = __toESM(require_dist(), 1);
|
|
7521
|
-
import { readdirSync as readdirSync2, readFileSync
|
|
7522
|
-
import { join as
|
|
7046
|
+
import { readdirSync as readdirSync2, readFileSync, statSync as statSync3 } from "node:fs";
|
|
7047
|
+
import { join as join5 } from "node:path";
|
|
7523
7048
|
var FileKnowledgeBase = class {
|
|
7524
7049
|
roots;
|
|
7525
7050
|
loaded = [];
|
|
@@ -7533,7 +7058,7 @@ var FileKnowledgeBase = class {
|
|
|
7533
7058
|
const files = collectYamlFiles(root.dir);
|
|
7534
7059
|
for (const file of files) {
|
|
7535
7060
|
const name = root.label ? `${root.label}:${file.name}` : file.name;
|
|
7536
|
-
const raw =
|
|
7061
|
+
const raw = readFileSync(file.path, "utf8");
|
|
7537
7062
|
const parsed = (0, import_yaml.parse)(raw);
|
|
7538
7063
|
if (!Array.isArray(parsed)) {
|
|
7539
7064
|
throw new Error(`knowledge base file ${name} must be a YAML list of KnowledgeBaseEntry`);
|
|
@@ -7591,7 +7116,7 @@ function collectYamlFiles(dir, prefix = "") {
|
|
|
7591
7116
|
const out = [];
|
|
7592
7117
|
const entries = readdirSync2(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
|
|
7593
7118
|
for (const entry of entries) {
|
|
7594
|
-
const path =
|
|
7119
|
+
const path = join5(dir, entry.name);
|
|
7595
7120
|
const name = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
7596
7121
|
if (entry.isDirectory()) {
|
|
7597
7122
|
out.push(...collectYamlFiles(path, name));
|
|
@@ -8171,24 +7696,6 @@ export {
|
|
|
8171
7696
|
getCatalogModelForRuntime,
|
|
8172
7697
|
getRuntimeRegistry,
|
|
8173
7698
|
credentialsPresent,
|
|
8174
|
-
stripTokenizerSentinels,
|
|
8175
|
-
DEFAULT_COMPACTION_THRESHOLD,
|
|
8176
|
-
shouldCompact,
|
|
8177
|
-
AutoCompactionTrigger,
|
|
8178
|
-
buildContextLedger,
|
|
8179
|
-
ceilChars,
|
|
8180
|
-
contentChars,
|
|
8181
|
-
estimateReasoningTextTokens,
|
|
8182
|
-
extractReasoningTokens,
|
|
8183
|
-
estimateAgentMessageTokens,
|
|
8184
|
-
estimateAgentContextBreakdown,
|
|
8185
|
-
estimateAgentContextTokens,
|
|
8186
|
-
contextUsageSnapshot,
|
|
8187
|
-
appendContextSnapshot,
|
|
8188
|
-
getLatestContextSnapshot,
|
|
8189
|
-
captureContextSnapshot,
|
|
8190
|
-
snapshotInputTokens,
|
|
8191
|
-
reconcileSnapshot,
|
|
8192
7699
|
setGlobalDefaultMaxOutputTokens,
|
|
8193
7700
|
resolveReservedOutputTokens,
|
|
8194
7701
|
setResidencyNoticeSink,
|
|
@@ -8207,6 +7714,7 @@ export {
|
|
|
8207
7714
|
registerClioApiProviders,
|
|
8208
7715
|
resolveProviderKnowledgeBaseRoots,
|
|
8209
7716
|
loadPluginRuntimes,
|
|
7717
|
+
formatContextWindowSlots,
|
|
8210
7718
|
registerBuiltinRuntimes,
|
|
8211
7719
|
FileKnowledgeBase,
|
|
8212
7720
|
isOrchestratorEligibleRuntime,
|
|
@@ -8228,7 +7736,8 @@ export {
|
|
|
8228
7736
|
runtimeTargetSnapshot,
|
|
8229
7737
|
firstRuntimeResolutionError,
|
|
8230
7738
|
runtimeResolutionWarnings,
|
|
7739
|
+
runtimeResolutionWarningsBesideThinkingNotice,
|
|
8231
7740
|
normalizeCostProvenance,
|
|
8232
7741
|
ProvidersDomainModule
|
|
8233
7742
|
};
|
|
8234
|
-
//# sourceMappingURL=chunk-
|
|
7743
|
+
//# sourceMappingURL=chunk-DJVECN66.js.map
|