chainlesschain 0.166.109 → 0.166.114
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -6
- package/package.json +3 -2
- package/src/assets/linux-subreaper/linux-arm64/manifest.json +1 -1
- package/src/assets/linux-subreaper/linux-x64/manifest.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AIOps-DkrNbDzS.js → AIOps-CVac3rIN.js} +1 -1
- package/src/assets/web-panel/assets/{ActionButton-DJjFXDhv.js → ActionButton-ChM9GxMl.js} +1 -1
- package/src/assets/web-panel/assets/{Analytics-DyUbagRn.js → Analytics-CV5399Js.js} +3 -3
- package/src/assets/web-panel/assets/{AppLayout-p7kJWSvn.js → AppLayout-CuonVXhg.js} +3 -3
- package/src/assets/web-panel/assets/{Artifacts-C3rVh4Ak.js → Artifacts-D9qKfgb6.js} +1 -1
- package/src/assets/web-panel/assets/{Audit-Bch_L_YO.js → Audit-DUvLysQc.js} +1 -1
- package/src/assets/web-panel/assets/{BackgroundAgents-BNHy8zP6.js → BackgroundAgents-DfKohQeT.js} +1 -1
- package/src/assets/web-panel/assets/{Backup-BUaye_Ys.js → Backup-CohoEI8R.js} +1 -1
- package/src/assets/web-panel/assets/{BaseInput-D49mzAVz.js → BaseInput-BwdoA3xv.js} +1 -1
- package/src/assets/web-panel/assets/{Chat-2MDzM_us.js → Chat-DRkuz1d2.js} +5 -5
- package/src/assets/web-panel/assets/ChatBubbleRenderer-v3pzeHNC.js +1 -0
- package/src/assets/web-panel/assets/{Checkbox-5p1T_KEq.js → Checkbox-B-GNGpKv.js} +1 -1
- package/src/assets/web-panel/assets/{Codegen-TKtiLaoZ.js → Codegen-Bs2lAsoZ.js} +1 -1
- package/src/assets/web-panel/assets/{Col-BVCMG9mS.js → Col-Bk1mJKDZ.js} +1 -1
- package/src/assets/web-panel/assets/{Community-D09-QczH.js → Community-B_FDSCOo.js} +1 -1
- package/src/assets/web-panel/assets/{Compact-QuRMCnj7.js → Compact-No1qSLLH.js} +1 -1
- package/src/assets/web-panel/assets/{Compliance-CN0PV7fk.js → Compliance-CcrG43-d.js} +1 -1
- package/src/assets/web-panel/assets/{Cowork-5N2zhAty.js → Cowork-DLkj2ywK.js} +3 -3
- package/src/assets/web-panel/assets/{Cron-BxT8UZ0S.js → Cron-sQHELVEz.js} +2 -2
- package/src/assets/web-panel/assets/{Crosschain-Dp-noQl4.js → Crosschain-CRTZ3GZg.js} +1 -1
- package/src/assets/web-panel/assets/{DID-B7MZFkjG.js → DID-Ds2bjvxE.js} +2 -2
- package/src/assets/web-panel/assets/{Dashboard-DulJ3rKV.js → Dashboard-DOONG2NX.js} +2 -2
- package/src/assets/web-panel/assets/{Dropdown-DV4ov4zF.js → Dropdown-Br3PNA2L.js} +1 -1
- package/src/assets/web-panel/assets/{EmailListRenderer-DB2-ooz6.js → EmailListRenderer-DT6UUqjZ.js} +1 -1
- package/src/assets/web-panel/assets/{EvolutionSettings-B1Rb6p7q.js → EvolutionSettings-BSLuEjlT.js} +1 -1
- package/src/assets/web-panel/assets/{FamilyGuardDashboard-U8aHayx-.js → FamilyGuardDashboard-2aEM9avE.js} +1 -1
- package/src/assets/web-panel/assets/{Federation-BkQULBHY.js → Federation-D3B0tlQU.js} +1 -1
- package/src/assets/web-panel/assets/{FormItemContext-CtviG260.js → FormItemContext-DTVkVVQP.js} +1 -1
- package/src/assets/web-panel/assets/{GenericCardRenderer-DnPirB24.js → GenericCardRenderer-BgFEgP4y.js} +1 -1
- package/src/assets/web-panel/assets/{Git-CK57Oro6.js → Git-3t71m6Xd.js} +2 -2
- package/src/assets/web-panel/assets/{Governance-DbI-LB8-.js → Governance-DS7WvlaX.js} +1 -1
- package/src/assets/web-panel/assets/{Inference-sEG4T1Jg.js → Inference-CeT-xWrI.js} +1 -1
- package/src/assets/web-panel/assets/{KnowledgeGraph-9SLJR3h9.js → KnowledgeGraph-BQzMncp5.js} +1 -1
- package/src/assets/web-panel/assets/{Logs-BIZYcISQ.js → Logs-CC5DOKhV.js} +2 -2
- package/src/assets/web-panel/assets/{MarkdownRenderer-9nfWupWP.js → MarkdownRenderer-5jYM4kYG.js} +1 -1
- package/src/assets/web-panel/assets/{Marketplace-CRmLLwAE.js → Marketplace-CpYDyy3o.js} +1 -1
- package/src/assets/web-panel/assets/{McpTools-DkOFkSO1.js → McpTools-DRdAZPMr.js} +3 -3
- package/src/assets/web-panel/assets/{Memory-M29Kd9TU.js → Memory-CBLRr-l8.js} +2 -2
- package/src/assets/web-panel/assets/{MobileBridge-Tl6JvPw_.js → MobileBridge-Bnj9veNN.js} +1 -1
- package/src/assets/web-panel/assets/{MobileProjects-Bq-FPDzS.js → MobileProjects-lYFPD24p.js} +1 -1
- package/src/assets/web-panel/assets/{Mtc-DkUjX1F5.js → Mtc-BMU_C9vD.js} +2 -2
- package/src/assets/web-panel/assets/{MtcAudit-BCqr1I4q.js → MtcAudit-DQV-zumU.js} +4 -4
- package/src/assets/web-panel/assets/{Multisig-DmoqYGQ5.js → Multisig-LpqpqV1d.js} +3 -3
- package/src/assets/web-panel/assets/{NLProgramming-DNRQeRke.js → NLProgramming-C4OMklSO.js} +1 -1
- package/src/assets/web-panel/assets/{Notes-CQSBeiY6.js → Notes-Cg0QCinP.js} +3 -3
- package/src/assets/web-panel/assets/{NotificationSettings-gNY9bbH6.js → NotificationSettings-amoZoMna.js} +1 -1
- package/src/assets/web-panel/assets/{OrderTableRenderer-DW0CNjh8.js → OrderTableRenderer-CxNvhf5n.js} +1 -1
- package/src/assets/web-panel/assets/{Organization-CthnbKag.js → Organization-BetJmyX5.js} +4 -4
- package/src/assets/web-panel/assets/{Overflow-_GQ3sbXu.js → Overflow-DbeoPtVD.js} +1 -1
- package/src/assets/web-panel/assets/{P2P-BTr7ea6W.js → P2P-B5sitQWT.js} +2 -2
- package/src/assets/web-panel/assets/PdhVaultBrowser-AP9SG2ic.js +7 -0
- package/src/assets/web-panel/assets/{Permissions-DMny2Cjs.js → Permissions-Bc7fgNKx.js} +4 -4
- package/src/assets/web-panel/assets/{PersonalDataHub-CyYlMSoI.js → PersonalDataHub-BwdGMcWZ.js} +3 -3
- package/src/assets/web-panel/assets/{Pipeline-FASu2Oc4.js → Pipeline-DVuJA9BA.js} +1 -1
- package/src/assets/web-panel/assets/{Privacy-9bC5FnsJ.js → Privacy-BGzwOYRG.js} +1 -1
- package/src/assets/web-panel/assets/{ProjectInit-BOYZwB5G.js → ProjectInit-BpHcC5br.js} +2 -2
- package/src/assets/web-panel/assets/{ProjectSettings-45DViNG-.js → ProjectSettings-BI5G5gsc.js} +2 -2
- package/src/assets/web-panel/assets/{Projects-C2fZzMZc.js → Projects-Ce92-l1V.js} +1 -1
- package/src/assets/web-panel/assets/{Providers-BgjvZx9F.js → Providers-CRHCcLFS.js} +1 -1
- package/src/assets/web-panel/assets/{QrScannerModal-Brw-3csB.js → QrScannerModal-qSeg5xag.js} +1 -1
- package/src/assets/web-panel/assets/QuickAsk-CA8oSceR.js +1 -0
- package/src/assets/web-panel/assets/{Recommend-DuQGxjIR.js → Recommend-DMvPodNo.js} +1 -1
- package/src/assets/web-panel/assets/{RemoteSession-T1cdSSRL.js → RemoteSession-BWsapEyN.js} +2 -2
- package/src/assets/web-panel/assets/{Reputation-9FT2dI4G.js → Reputation-BZJETVmC.js} +1 -1
- package/src/assets/web-panel/assets/{Row-yNIbNftX.js → Row-CUE1OSMp.js} +1 -1
- package/src/assets/web-panel/assets/{RssFeed-BIchNoPd.js → RssFeed-DvMazcUD.js} +2 -2
- package/src/assets/web-panel/assets/{Search-msDJ8UTZ.js → Search-e1c-NXWv.js} +1 -1
- package/src/assets/web-panel/assets/{Security-DE46oBYT.js → Security-Dc9GZsx2.js} +3 -3
- package/src/assets/web-panel/assets/{Services-Dori7vc3.js → Services-AFz6ke-4.js} +2 -2
- package/src/assets/web-panel/assets/{Skeleton-D3O3sUFz.js → Skeleton-gow6MYcY.js} +1 -1
- package/src/assets/web-panel/assets/{Skills-BV0ct8SO.js → Skills-h6AxYjUP.js} +1 -1
- package/src/assets/web-panel/assets/{Sla-DflIVOrh.js → Sla-Cr4CkJ0O.js} +1 -1
- package/src/assets/web-panel/assets/{SpeechSettings-Cpbv2Zz6.js → SpeechSettings-Bd5yuBtH.js} +1 -1
- package/src/assets/web-panel/assets/{SyncSettings-Dgg6-wbe.js → SyncSettings-1t4QZMLW.js} +2 -2
- package/src/assets/web-panel/assets/{Tasks-Cb6e4Klx.js → Tasks-u-DrjLRM.js} +1 -1
- package/src/assets/web-panel/assets/{Templates-GfdAATGz.js → Templates-C0yLUC9b.js} +1 -1
- package/src/assets/web-panel/assets/{Tenant-D0gecLXl.js → Tenant-ds1YT5iS.js} +1 -1
- package/src/assets/web-panel/assets/{Terminal-BFRPJt-0.js → Terminal-BoIskW2m.js} +2 -2
- package/src/assets/web-panel/assets/{TimelineRenderer-BobtChxX.js → TimelineRenderer-BkdVK24X.js} +1 -1
- package/src/assets/web-panel/assets/{Tokens-CifeZtHV.js → Tokens-djyDgmfk.js} +1 -1
- package/src/assets/web-panel/assets/{Trigger-BHBvbBCf.js → Trigger-CYefDS3H.js} +1 -1
- package/src/assets/web-panel/assets/{Trust-6lvqjKYp.js → Trust-CE_dbep_.js} +1 -1
- package/src/assets/web-panel/assets/{UkeySign-CqzMc-G5.js → UkeySign-DwVs_fey.js} +1 -1
- package/src/assets/web-panel/assets/{VideoEditing-OIiRG582.js → VideoEditing-BTUqMHAV.js} +1 -1
- package/src/assets/web-panel/assets/{Wallet-4MeKq0q_.js → Wallet-Bu_E7Rrc.js} +4 -4
- package/src/assets/web-panel/assets/{WebAuthn-eHBRjGQG.js → WebAuthn-DTbre5AB.js} +4 -4
- package/src/assets/web-panel/assets/{WorkflowEditor-DlzYdEqW.js → WorkflowEditor-BsBzd3gt.js} +1 -1
- package/src/assets/web-panel/assets/{chat-CBcjOzkX.js → chat-tdifQQvu.js} +1 -1
- package/src/assets/web-panel/assets/{colors-zgwsYQSa.js → colors-D3SNW2Vx.js} +1 -1
- package/src/assets/web-panel/assets/{compact-item-Dcd9H5Bn.js → compact-item-UBlCjrAW.js} +1 -1
- package/src/assets/web-panel/assets/{createContext-DR1tO-8r.js → createContext-DKsnEnFt.js} +1 -1
- package/src/assets/web-panel/assets/devWarning-BBnVfJHh.js +1 -0
- package/src/assets/web-panel/assets/{hasIn-CtfbUH_p.js → hasIn-BkeySXWe.js} +1 -1
- package/src/assets/web-panel/assets/{index-BXfGHUz_.js → index-6Nvzgytx.js} +1 -1
- package/src/assets/web-panel/assets/index-B2w_3mtS.js +1 -0
- package/src/assets/web-panel/assets/{index-DYPMJ5Mb.js → index-BEiHKah0.js} +25 -25
- package/src/assets/web-panel/assets/{index-LN7Hkl1C.js → index-BIeFLaMV.js} +1 -1
- package/src/assets/web-panel/assets/{index-DA2-Bhy8.js → index-BV2zQteq.js} +1 -1
- package/src/assets/web-panel/assets/{index-CwHgaYVH.js → index-BVvz3ntc.js} +1 -1
- package/src/assets/web-panel/assets/index-BoHurydC.js +1 -0
- package/src/assets/web-panel/assets/{index-DVpp9YSQ.js → index-Bw0k3VgD.js} +1 -1
- package/src/assets/web-panel/assets/{index-CaGNqkY0.js → index-C-KTHSUE.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWuCGhHa.js → index-C9ImNw5O.js} +1 -1
- package/src/assets/web-panel/assets/{index-DTx4FyLU.js → index-CG_b1xyX.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cur8LNNn.js → index-CUjyL0ZS.js} +1 -1
- package/src/assets/web-panel/assets/{index-DfzOYmOj.js → index-CXkn77ZN.js} +1 -1
- package/src/assets/web-panel/assets/{index-Cdhy5ckh.js → index-CZ6JUooI.js} +1 -1
- package/src/assets/web-panel/assets/{index-D1GxtY-h.js → index-Cuz2QCFT.js} +1 -1
- package/src/assets/web-panel/assets/{index-C0kP88Pb.js → index-D5Umd_Z-.js} +1 -1
- package/src/assets/web-panel/assets/{index-DHEiuvhA.js → index-D6es7MSG.js} +1 -1
- package/src/assets/web-panel/assets/{index-CPLLgPxA.js → index-D93iSDUw.js} +1 -1
- package/src/assets/web-panel/assets/{index-B3QUK1ks.js → index-D9m1HQzl.js} +1 -1
- package/src/assets/web-panel/assets/{index-DWG98orp.js → index-D9um0YVl.js} +1 -1
- package/src/assets/web-panel/assets/{index-hTcre7U9.js → index-DD6dD3LV.js} +1 -1
- package/src/assets/web-panel/assets/{index-C5XGvJb0.js → index-DFMrIEIt.js} +1 -1
- package/src/assets/web-panel/assets/{index-DvPOpvvH.js → index-DSCiZJXb.js} +1 -1
- package/src/assets/web-panel/assets/{index-D8WPohye.js → index-DSe_7MSy.js} +1 -1
- package/src/assets/web-panel/assets/{index-JSfldpw4.js → index-DYFjOyTH.js} +1 -1
- package/src/assets/web-panel/assets/{index-5XaB_Tjg.js → index-DdyTv6yc.js} +1 -1
- package/src/assets/web-panel/assets/{index-BoxowMYS.js → index-DfrW-iVs.js} +1 -1
- package/src/assets/web-panel/assets/{index-DSvcz0RO.js → index-Dg8-Duze.js} +1 -1
- package/src/assets/web-panel/assets/{index-J-ORW1i6.js → index-DiDgwRty.js} +1 -1
- package/src/assets/web-panel/assets/{index-CT7zIkqP.js → index-DlEIp1gJ.js} +1 -1
- package/src/assets/web-panel/assets/{index-D7ZOiIKb.js → index-DlO6HdD9.js} +1 -1
- package/src/assets/web-panel/assets/{index-DeAi4CNt.js → index-DtxUSZSS.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmVIM-m2.js → index-DugZRCiI.js} +1 -1
- package/src/assets/web-panel/assets/{index-oWOlF7CM.js → index-P-ailFQY.js} +1 -1
- package/src/assets/web-panel/assets/{index-dvF6C39V.js → index-PWScrdlX.js} +1 -1
- package/src/assets/web-panel/assets/{index-CSQCHpDo.js → index-SpQ26gD6.js} +1 -1
- package/src/assets/web-panel/assets/{index-CmzQzTY5.js → index-TLBpgN30.js} +1 -1
- package/src/assets/web-panel/assets/{index-z8lrkcb-.js → index-bOIcWW8F.js} +1 -1
- package/src/assets/web-panel/assets/{index-BndPtS9D.js → index-pgGKNvmm.js} +1 -1
- package/src/assets/web-panel/assets/{initDefaultProps-CVMtDrWZ.js → initDefaultProps-CVCXG2Hv.js} +1 -1
- package/src/assets/web-panel/assets/{motion-Dye3IU8k.js → motion-Dv00jw87.js} +1 -1
- package/src/assets/web-panel/assets/{move-C251Zo34.js → move-BFz51iHf.js} +1 -1
- package/src/assets/web-panel/assets/{mtc-parser-BDiOORoQ.js → mtc-parser-BK2woIDE.js} +1 -1
- package/src/assets/web-panel/assets/{omit-DTDA_RHv.js → omit-D2X_Gwoo.js} +1 -1
- package/src/assets/web-panel/assets/{pickAttrs-CqEUTPcT.js → pickAttrs-CLmFyJ1q.js} +1 -1
- package/src/assets/web-panel/assets/{placementArrow-BOB8QWH3.js → placementArrow-CCzPddQm.js} +1 -1
- package/src/assets/web-panel/assets/{responsiveObserve-CZDXP1d9.js → responsiveObserve-hcm_Zlxd.js} +1 -1
- package/src/assets/web-panel/assets/{slide-DPaRw3E9.js → slide-BxfZEFVp.js} +1 -1
- package/src/assets/web-panel/assets/{statusUtils-Ba9d7XZ7.js → statusUtils-kzB9pT-t.js} +1 -1
- package/src/assets/web-panel/assets/{styleChecker-mZKU3lvW.js → styleChecker-CDFd7YCI.js} +1 -1
- package/src/assets/web-panel/assets/{useFlexGapSupport-VcauLq0M.js → useFlexGapSupport-Czl7NNhS.js} +1 -1
- package/src/assets/web-panel/assets/{useFs-Cal9KRcx.js → useFs-y0SAzirG.js} +1 -1
- package/src/assets/web-panel/assets/{usePersonalDataHub-DISoRyQB.js → usePersonalDataHub-BvdPznrA.js} +1 -1
- package/src/assets/web-panel/assets/{vnode-B58C6w6B.js → vnode-D8mNbyZ7.js} +1 -1
- package/src/assets/web-panel/assets/{zoom-BPlBAMKB.js → zoom-_hun6w9W.js} +1 -1
- package/src/assets/web-panel/index.html +1 -1
- package/src/command-help-index.json +1 -1
- package/src/commands/agent.js +12 -5
- package/src/commands/ask.js +96 -21
- package/src/commands/complete.js +14 -10
- package/src/commands/llm.js +23 -41
- package/src/commands/session.js +2 -2
- package/src/commands/stream.js +9 -5
- package/src/commands/ui.js +30 -2
- package/src/data/changelog.json +65 -0
- package/src/gateways/ws/llm-chat-protocol.js +131 -40
- package/src/gateways/ws/llm-creds.js +29 -79
- package/src/gateways/ws/message-dispatcher.js +2 -0
- package/src/gateways/ws/ws-agent-handler.js +1 -1
- package/src/gateways/ws/ws-session-gateway.js +26 -12
- package/src/lib/__tests__/provider-stream.test.js +70 -4
- package/src/lib/chat-core.js +186 -24
- package/src/lib/cowork-adapter.js +29 -15
- package/src/lib/evolution/agent-evolution-runtime-composition.js +10 -7
- package/src/lib/evolution/evolution-deployment-config.js +36 -4
- package/src/lib/evolution/evolution-deployment-loader.js +117 -4
- package/src/lib/evolution/evolution-deployment-profile.js +2 -2
- package/src/lib/evolution/evolution-evidence-projector.js +18 -3
- package/src/lib/evolution/evolution-file-witness.js +10 -0
- package/src/lib/evolution/evolution-ledger.js +237 -28
- package/src/lib/evolution/evolution-windows-directory-durability.js +322 -0
- package/src/lib/evolution/governed-hub-llm.js +2 -1
- package/src/lib/evolution/governed-model-turn.js +4 -1
- package/src/lib/evolution/local-ui-evolution-deployment.js +768 -0
- package/src/lib/evolution/local-ui-evolution-host.mjs +44 -0
- package/src/lib/evolution/local-ui-evolution-runtime.js +624 -0
- package/src/lib/evolution/opaque-hex-id.js +28 -0
- package/src/lib/hub-llm-client.js +22 -14
- package/src/lib/image-input.js +19 -3
- package/src/lib/llm-config-defaults.js +19 -30
- package/src/lib/llm-connection-config.js +4 -0
- package/src/lib/llm-connection-probe.js +5 -1
- package/src/lib/llm-connection-resolution.js +94 -0
- package/src/lib/llm-providers.js +33 -11
- package/src/lib/ollama-base-url.js +14 -0
- package/src/lib/provider-protocol.js +104 -0
- package/src/lib/provider-stream.js +163 -4
- package/src/lib/runnable-provider.js +1 -0
- package/src/repl/chat-repl.js +58 -11
- package/src/runtime/agent-core.js +26 -43
- package/src/runtime/headless-runner.js +11 -4
- package/src/runtime/headless-stream.js +10 -4
- package/src/runtime/policies/agent-policy.js +17 -11
- package/src/assets/web-panel/assets/ChatBubbleRenderer-DOX3Y5EJ.js +0 -1
- package/src/assets/web-panel/assets/PdhVaultBrowser-D9McHF9I.js +0 -7
- package/src/assets/web-panel/assets/QuickAsk-DWG-A5zB.js +0 -1
- package/src/assets/web-panel/assets/devWarning-DYhpRtve.js +0 -1
- package/src/assets/web-panel/assets/index-DPJXFIY7.js +0 -1
- package/src/assets/web-panel/assets/index-DjBhR5M_.js +0 -1
package/src/lib/chat-core.js
CHANGED
|
@@ -11,6 +11,13 @@ import { providerFetch } from "./formal-budget-provider-scope.js";
|
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import { BUILT_IN_PROVIDERS } from "./llm-providers.js";
|
|
14
|
+
import { normalizeOllamaBaseUrl } from "./ollama-base-url.js";
|
|
15
|
+
import {
|
|
16
|
+
geminiGenerateContentUrl,
|
|
17
|
+
geminiRequestBody,
|
|
18
|
+
geminiUsage,
|
|
19
|
+
normalizeProviderBaseUrl,
|
|
20
|
+
} from "./provider-protocol.js";
|
|
14
21
|
import { appendTokenUsage } from "../harness/jsonl-session-store.js";
|
|
15
22
|
import {
|
|
16
23
|
isRetryableStreamError,
|
|
@@ -134,18 +141,21 @@ export async function streamOllama(
|
|
|
134
141
|
guard.bump();
|
|
135
142
|
let response;
|
|
136
143
|
try {
|
|
137
|
-
response = await providerFetch(
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
:
|
|
148
|
-
|
|
144
|
+
response = await providerFetch(
|
|
145
|
+
`${normalizeOllamaBaseUrl(baseUrl)}/api/chat`,
|
|
146
|
+
{
|
|
147
|
+
method: "POST",
|
|
148
|
+
headers: { "Content-Type": "application/json" },
|
|
149
|
+
body: JSON.stringify({
|
|
150
|
+
model,
|
|
151
|
+
messages,
|
|
152
|
+
stream: true,
|
|
153
|
+
}),
|
|
154
|
+
signal: options.signal
|
|
155
|
+
? AbortSignal.any([guard.signal, options.signal])
|
|
156
|
+
: guard.signal,
|
|
157
|
+
},
|
|
158
|
+
);
|
|
149
159
|
} catch (e) {
|
|
150
160
|
guard.stop();
|
|
151
161
|
throw guard.stalled() && !isFormalBudgetError(e)
|
|
@@ -249,7 +259,9 @@ export async function streamOpenAI(
|
|
|
249
259
|
guard.bump();
|
|
250
260
|
let response;
|
|
251
261
|
try {
|
|
252
|
-
response = await providerFetch(
|
|
262
|
+
response = await providerFetch(
|
|
263
|
+
`${normalizeProviderBaseUrl(baseUrl)}/chat/completions`,
|
|
264
|
+
{
|
|
253
265
|
method: "POST",
|
|
254
266
|
headers: {
|
|
255
267
|
"Content-Type": "application/json",
|
|
@@ -266,7 +278,8 @@ export async function streamOpenAI(
|
|
|
266
278
|
signal: options.signal
|
|
267
279
|
? AbortSignal.any([guard.signal, options.signal])
|
|
268
280
|
: guard.signal,
|
|
269
|
-
|
|
281
|
+
},
|
|
282
|
+
);
|
|
270
283
|
} catch (e) {
|
|
271
284
|
guard.stop();
|
|
272
285
|
throw guard.stalled() && !isFormalBudgetError(e)
|
|
@@ -394,7 +407,9 @@ export async function streamAnthropic(
|
|
|
394
407
|
guard.bump();
|
|
395
408
|
let response;
|
|
396
409
|
try {
|
|
397
|
-
response = await providerFetch(
|
|
410
|
+
response = await providerFetch(
|
|
411
|
+
`${normalizeProviderBaseUrl(baseUrl)}/messages`,
|
|
412
|
+
{
|
|
398
413
|
method: "POST",
|
|
399
414
|
headers: {
|
|
400
415
|
"Content-Type": "application/json",
|
|
@@ -411,7 +426,8 @@ export async function streamAnthropic(
|
|
|
411
426
|
signal: options.signal
|
|
412
427
|
? AbortSignal.any([guard.signal, options.signal])
|
|
413
428
|
: guard.signal,
|
|
414
|
-
|
|
429
|
+
},
|
|
430
|
+
);
|
|
415
431
|
} catch (e) {
|
|
416
432
|
guard.stop();
|
|
417
433
|
throw guard.stalled() && !isFormalBudgetError(e)
|
|
@@ -517,6 +533,128 @@ export async function streamAnthropic(
|
|
|
517
533
|
return fullResponse;
|
|
518
534
|
}
|
|
519
535
|
|
|
536
|
+
/** Stream Google's native Gemini generateContent SSE API. */
|
|
537
|
+
export async function streamGemini(
|
|
538
|
+
messages,
|
|
539
|
+
model,
|
|
540
|
+
baseUrl,
|
|
541
|
+
apiKey,
|
|
542
|
+
onToken,
|
|
543
|
+
onUsage,
|
|
544
|
+
onStall,
|
|
545
|
+
options = {},
|
|
546
|
+
) {
|
|
547
|
+
const guard = makeStallGuard(STREAM_STALL_MS, { onHint: onStall });
|
|
548
|
+
guard.bump();
|
|
549
|
+
let response;
|
|
550
|
+
try {
|
|
551
|
+
response = await providerFetch(
|
|
552
|
+
geminiGenerateContentUrl(baseUrl, model, { stream: true }),
|
|
553
|
+
{
|
|
554
|
+
method: "POST",
|
|
555
|
+
headers: {
|
|
556
|
+
"Content-Type": "application/json",
|
|
557
|
+
"x-goog-api-key": apiKey,
|
|
558
|
+
},
|
|
559
|
+
body: JSON.stringify(geminiRequestBody(messages)),
|
|
560
|
+
signal: options.signal
|
|
561
|
+
? AbortSignal.any([guard.signal, options.signal])
|
|
562
|
+
: guard.signal,
|
|
563
|
+
},
|
|
564
|
+
);
|
|
565
|
+
} catch (error) {
|
|
566
|
+
guard.stop();
|
|
567
|
+
throw guard.stalled() && !isFormalBudgetError(error)
|
|
568
|
+
? new Error(
|
|
569
|
+
`Gemini request stalled (no response in ${STREAM_STALL_MS / 1000}s)`,
|
|
570
|
+
)
|
|
571
|
+
: error;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (!response.ok || !response.body) {
|
|
575
|
+
guard.stop();
|
|
576
|
+
throw attachStreamRetryMetadata(
|
|
577
|
+
new Error(`Gemini error: ${response.status} ${response.statusText}`),
|
|
578
|
+
captureStreamRetryMetadata(response),
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
const retryMetadata = captureStreamRetryMetadata(response);
|
|
583
|
+
const reader = response.body.getReader();
|
|
584
|
+
const decoder = new TextDecoder();
|
|
585
|
+
let buffer = "";
|
|
586
|
+
let fullResponse = "";
|
|
587
|
+
let completed = false;
|
|
588
|
+
let latestUsage = null;
|
|
589
|
+
|
|
590
|
+
const consumeLine = async (raw) => {
|
|
591
|
+
const line = raw.trim();
|
|
592
|
+
if (!line.startsWith("data:")) return;
|
|
593
|
+
const payload = line.slice(5).trim();
|
|
594
|
+
if (!payload || payload === "[DONE]") return;
|
|
595
|
+
const data = JSON.parse(payload);
|
|
596
|
+
if (data.error) {
|
|
597
|
+
throw new Error(
|
|
598
|
+
typeof data.error.message === "string"
|
|
599
|
+
? data.error.message
|
|
600
|
+
: "Gemini stream returned an error",
|
|
601
|
+
);
|
|
602
|
+
}
|
|
603
|
+
const candidate = data.candidates?.[0];
|
|
604
|
+
if (candidate?.finishReason || data.promptFeedback?.blockReason)
|
|
605
|
+
completed = true;
|
|
606
|
+
const usage = geminiUsage(data);
|
|
607
|
+
if (usage) latestUsage = usage;
|
|
608
|
+
for (const part of candidate?.content?.parts || []) {
|
|
609
|
+
if (part?.thought === true || typeof part?.text !== "string") continue;
|
|
610
|
+
fullResponse += part.text;
|
|
611
|
+
await _deliverToken(onToken, part.text, guard, options);
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
try {
|
|
616
|
+
while (true) {
|
|
617
|
+
const { done, value } = await reader.read();
|
|
618
|
+
if (done) break;
|
|
619
|
+
guard.bump();
|
|
620
|
+
buffer += decoder.decode(value, { stream: true });
|
|
621
|
+
const lines = buffer.split("\n");
|
|
622
|
+
buffer = lines.pop() || "";
|
|
623
|
+
for (const line of lines) {
|
|
624
|
+
try {
|
|
625
|
+
await consumeLine(line);
|
|
626
|
+
} catch (error) {
|
|
627
|
+
if (
|
|
628
|
+
options.requireCompletion ||
|
|
629
|
+
error?.isOutputBackpressureFailure === true
|
|
630
|
+
)
|
|
631
|
+
throw error;
|
|
632
|
+
// Non-governed streaming keeps its historical best-effort parsing.
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
buffer += decoder.decode();
|
|
637
|
+
if (buffer.trim()) await consumeLine(buffer);
|
|
638
|
+
} catch (error) {
|
|
639
|
+
throw attachStreamRetryMetadata(
|
|
640
|
+
guard.stalled() && !isFormalBudgetError(error)
|
|
641
|
+
? new Error(
|
|
642
|
+
`Gemini stream stalled (no data in ${STREAM_STALL_MS / 1000}s)`,
|
|
643
|
+
)
|
|
644
|
+
: error,
|
|
645
|
+
retryMetadata,
|
|
646
|
+
);
|
|
647
|
+
} finally {
|
|
648
|
+
guard.stop();
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
if (latestUsage && onUsage) onUsage(latestUsage);
|
|
652
|
+
options.signal?.throwIfAborted();
|
|
653
|
+
if (options.requireCompletion && !completed)
|
|
654
|
+
throw new Error("Model stream ended before its completion marker");
|
|
655
|
+
return fullResponse;
|
|
656
|
+
}
|
|
657
|
+
|
|
520
658
|
/**
|
|
521
659
|
* Async generator that streams a chat response.
|
|
522
660
|
*
|
|
@@ -578,10 +716,9 @@ export async function* chatStream(messages, options) {
|
|
|
578
716
|
);
|
|
579
717
|
} else if (provider === "anthropic") {
|
|
580
718
|
const providerDef = BUILT_IN_PROVIDERS.anthropic;
|
|
581
|
-
const url =
|
|
582
|
-
baseUrl
|
|
583
|
-
|
|
584
|
-
: providerDef?.baseUrl || "https://api.anthropic.com/v1";
|
|
719
|
+
const url = normalizeProviderBaseUrl(
|
|
720
|
+
baseUrl || providerDef?.baseUrl || "https://api.anthropic.com/v1",
|
|
721
|
+
);
|
|
585
722
|
const key =
|
|
586
723
|
apiKey ||
|
|
587
724
|
(providerDef?.apiKeyEnv ? process.env[providerDef.apiKeyEnv] : null);
|
|
@@ -601,12 +738,37 @@ export async function* chatStream(messages, options) {
|
|
|
601
738
|
options.onStall,
|
|
602
739
|
options,
|
|
603
740
|
);
|
|
741
|
+
} else if (provider === "gemini") {
|
|
742
|
+
const providerDef = BUILT_IN_PROVIDERS.gemini;
|
|
743
|
+
const url = normalizeProviderBaseUrl(
|
|
744
|
+
baseUrl ||
|
|
745
|
+
providerDef?.baseUrl ||
|
|
746
|
+
"https://generativelanguage.googleapis.com/v1beta",
|
|
747
|
+
);
|
|
748
|
+
const key =
|
|
749
|
+
apiKey ||
|
|
750
|
+
(providerDef?.apiKeyEnv ? process.env[providerDef.apiKeyEnv] : null);
|
|
751
|
+
if (!key) {
|
|
752
|
+
throw new Error(
|
|
753
|
+
`API key required for gemini (set ${providerDef?.apiKeyEnv || "GEMINI_API_KEY"})`,
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
providerCall = () =>
|
|
757
|
+
streamGemini(
|
|
758
|
+
messages,
|
|
759
|
+
model,
|
|
760
|
+
url,
|
|
761
|
+
key,
|
|
762
|
+
onToken,
|
|
763
|
+
onUsage,
|
|
764
|
+
options.onStall,
|
|
765
|
+
options,
|
|
766
|
+
);
|
|
604
767
|
} else {
|
|
605
768
|
const providerDef = BUILT_IN_PROVIDERS[provider];
|
|
606
|
-
const url =
|
|
607
|
-
baseUrl
|
|
608
|
-
|
|
609
|
-
: providerDef?.baseUrl || "https://api.openai.com/v1";
|
|
769
|
+
const url = normalizeProviderBaseUrl(
|
|
770
|
+
baseUrl || providerDef?.baseUrl || "https://api.openai.com/v1",
|
|
771
|
+
);
|
|
610
772
|
const key =
|
|
611
773
|
apiKey ||
|
|
612
774
|
(providerDef?.apiKeyEnv ? process.env[providerDef.apiKeyEnv] : null);
|
|
@@ -12,6 +12,11 @@ import { LLMProviderRegistry, BUILT_IN_PROVIDERS } from "./llm-providers.js";
|
|
|
12
12
|
import { loadConfig } from "./config-manager.js";
|
|
13
13
|
import { applyConfigLlmDefaults } from "./llm-config-defaults.js";
|
|
14
14
|
import { captureAgentEvolutionIngress } from "./evolution/agent-evolution-ingress.js";
|
|
15
|
+
import { normalizeOllamaBaseUrl } from "./ollama-base-url.js";
|
|
16
|
+
import {
|
|
17
|
+
normalizeProviderBaseUrl,
|
|
18
|
+
openAICompatibleBaseUrl,
|
|
19
|
+
} from "./provider-protocol.js";
|
|
15
20
|
|
|
16
21
|
function plainUsage(value) {
|
|
17
22
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
@@ -175,17 +180,20 @@ export function createChatFn(options = {}) {
|
|
|
175
180
|
currentModel,
|
|
176
181
|
async ({ signal = opts.signal || resolved.signal } = {}) => {
|
|
177
182
|
const modelMessages = await prepareMessages();
|
|
178
|
-
const res = await providerFetch(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
183
|
+
const res = await providerFetch(
|
|
184
|
+
`${normalizeOllamaBaseUrl(baseUrl)}/api/chat`,
|
|
185
|
+
{
|
|
186
|
+
method: "POST",
|
|
187
|
+
signal: requestSignal(signal),
|
|
188
|
+
headers: { "Content-Type": "application/json" },
|
|
189
|
+
body: JSON.stringify({
|
|
190
|
+
model: currentModel,
|
|
191
|
+
messages: modelMessages,
|
|
192
|
+
stream: false,
|
|
193
|
+
options: { num_predict: maxTokens },
|
|
194
|
+
}),
|
|
195
|
+
},
|
|
196
|
+
);
|
|
189
197
|
if (!res.ok) throw new Error(`Ollama error: ${res.status}`);
|
|
190
198
|
const data = await res.json();
|
|
191
199
|
return chatEnvelope(
|
|
@@ -215,7 +223,9 @@ export function createChatFn(options = {}) {
|
|
|
215
223
|
? { system: systemMsgs.map((m) => m.content).join("\n") }
|
|
216
224
|
: {}),
|
|
217
225
|
};
|
|
218
|
-
const res = await providerFetch(
|
|
226
|
+
const res = await providerFetch(
|
|
227
|
+
`${normalizeProviderBaseUrl(baseUrl)}/messages`,
|
|
228
|
+
{
|
|
219
229
|
method: "POST",
|
|
220
230
|
signal: requestSignal(signal),
|
|
221
231
|
headers: {
|
|
@@ -224,7 +234,8 @@ export function createChatFn(options = {}) {
|
|
|
224
234
|
"anthropic-version": "2023-06-01",
|
|
225
235
|
},
|
|
226
236
|
body: JSON.stringify(body),
|
|
227
|
-
|
|
237
|
+
},
|
|
238
|
+
);
|
|
228
239
|
if (!res.ok) throw new Error(`Anthropic error: ${res.status}`);
|
|
229
240
|
const data = await res.json();
|
|
230
241
|
return chatEnvelope(
|
|
@@ -246,7 +257,9 @@ export function createChatFn(options = {}) {
|
|
|
246
257
|
currentModel,
|
|
247
258
|
async ({ signal = opts.signal || resolved.signal } = {}) => {
|
|
248
259
|
const modelMessages = await prepareMessages();
|
|
249
|
-
const res = await providerFetch(
|
|
260
|
+
const res = await providerFetch(
|
|
261
|
+
`${openAICompatibleBaseUrl(provider, baseUrl)}/chat/completions`,
|
|
262
|
+
{
|
|
250
263
|
method: "POST",
|
|
251
264
|
signal: requestSignal(signal),
|
|
252
265
|
headers: {
|
|
@@ -258,7 +271,8 @@ export function createChatFn(options = {}) {
|
|
|
258
271
|
messages: modelMessages,
|
|
259
272
|
max_tokens: maxTokens,
|
|
260
273
|
}),
|
|
261
|
-
|
|
274
|
+
},
|
|
275
|
+
);
|
|
262
276
|
if (!res.ok) throw new Error(`API error: ${res.status}`);
|
|
263
277
|
const data = await res.json();
|
|
264
278
|
return chatEnvelope(
|
|
@@ -22,6 +22,7 @@ import { EvolutionRunLedgerAdapter } from "./evolution-run-ledger-adapter.js";
|
|
|
22
22
|
import { createEvolutionRunWikiEvidenceResolver } from "./evolution-run-wiki-evidence-resolver.js";
|
|
23
23
|
import { WikiMaintainerLedgerAdapter } from "./wiki-maintainer-ledger-adapter.js";
|
|
24
24
|
import { EvidenceBackedWikiMaintainer } from "./evidence-backed-wiki-maintainer.js";
|
|
25
|
+
import { ensureDirectoryTreeDurable } from "./evolution-windows-directory-durability.js";
|
|
25
26
|
import { createWikiEvidenceCommitGuard } from "./wiki-evidence-commit-guard.js";
|
|
26
27
|
import { EvolutionWorkbenchMetricsLedgerAdapter } from "./evolution-workbench-metrics-ledger-adapter.js";
|
|
27
28
|
import { EvolutionReleaseTrainLedgerAdapter } from "./evolution-release-train-ledger-adapter.js";
|
|
@@ -158,7 +159,7 @@ function normalizeClock(clock) {
|
|
|
158
159
|
});
|
|
159
160
|
}
|
|
160
161
|
|
|
161
|
-
function layout(stateRootDir, tenantId, runId, initialize = true) {
|
|
162
|
+
function layout(stateRootDir, tenantId, runId, initialize = true, fsImpl = fs) {
|
|
162
163
|
if (typeof stateRootDir !== "string" || stateRootDir.trim() === "") {
|
|
163
164
|
throw new TypeError("stateRootDir is required");
|
|
164
165
|
}
|
|
@@ -176,11 +177,12 @@ function layout(stateRootDir, tenantId, runId, initialize = true) {
|
|
|
176
177
|
ledgerAuthorityRootDir: path.join(scope, "ledger-authority"),
|
|
177
178
|
witnessFilePath: path.join(scope, "witness", "checkpoint.json"),
|
|
178
179
|
});
|
|
179
|
-
if (initialize)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
if (initialize) {
|
|
181
|
+
ensureDirectoryTreeDurable(
|
|
182
|
+
fsImpl,
|
|
183
|
+
path.dirname(result.witnessFilePath),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
184
186
|
return result;
|
|
185
187
|
}
|
|
186
188
|
|
|
@@ -408,7 +410,7 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
408
410
|
capture(authorities.witness?.signer, "sign", "witness signer");
|
|
409
411
|
capture(authorities.witness?.verifier, "verify", "witness verifier");
|
|
410
412
|
assertIndependentSigningAuthorities(authorities.ledger, authorities.witness);
|
|
411
|
-
const storage = layout(stateRootDir, tenantId, runId);
|
|
413
|
+
const storage = layout(stateRootDir, tenantId, runId, true, fsImpl ?? fs);
|
|
412
414
|
const artifactPorts = new EvolutionArtifactPorts({
|
|
413
415
|
tenantId,
|
|
414
416
|
audience,
|
|
@@ -712,6 +714,7 @@ export function createAgentEvolutionRuntimeComposition({
|
|
|
712
714
|
tenantId,
|
|
713
715
|
sourceRunId,
|
|
714
716
|
false,
|
|
717
|
+
fsImpl ?? fs,
|
|
715
718
|
);
|
|
716
719
|
if (!fs.existsSync(sourceStorage.witnessFilePath))
|
|
717
720
|
throw new Error("Cache source Run witness does not exist");
|
|
@@ -103,6 +103,9 @@ function withDeploymentReadiness(status) {
|
|
|
103
103
|
return Object.freeze({
|
|
104
104
|
...status,
|
|
105
105
|
readiness: Object.freeze({
|
|
106
|
+
ui: assessEvolutionDeploymentReadiness(status, {
|
|
107
|
+
requiredCommands: ["ui"],
|
|
108
|
+
}),
|
|
106
109
|
ask: assessEvolutionDeploymentReadiness(status, {
|
|
107
110
|
requiredCommands: ["ask"],
|
|
108
111
|
}),
|
|
@@ -197,6 +200,23 @@ export async function configureEvolutionDeployment(
|
|
|
197
200
|
options,
|
|
198
201
|
);
|
|
199
202
|
updateEvolutionDeploymentProfile((current) => {
|
|
203
|
+
if (
|
|
204
|
+
options.expectedProfile &&
|
|
205
|
+
JSON.stringify(current) !== JSON.stringify(options.expectedProfile)
|
|
206
|
+
) {
|
|
207
|
+
const error = new Error(
|
|
208
|
+
"Evolution deployment profile changed during local migration",
|
|
209
|
+
);
|
|
210
|
+
error.code = "EVOLUTION_DEPLOYMENT_PROFILE_CHANGED";
|
|
211
|
+
throw error;
|
|
212
|
+
}
|
|
213
|
+
if (options.expectedProfileAbsent === true && current) {
|
|
214
|
+
const error = new Error(
|
|
215
|
+
"Evolution deployment profile was configured during local initialization",
|
|
216
|
+
);
|
|
217
|
+
error.code = "EVOLUTION_DEPLOYMENT_PROFILE_ALREADY_CONFIGURED";
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
200
220
|
if (
|
|
201
221
|
current?.activeTrustRootDigest &&
|
|
202
222
|
current.activeTrustRootDigest !== verified.descriptor.trustRootDigest
|
|
@@ -245,6 +265,11 @@ export async function configureEvolutionDeployment(
|
|
|
245
265
|
verified.descriptor.revision,
|
|
246
266
|
),
|
|
247
267
|
};
|
|
268
|
+
const preserveLocalMode =
|
|
269
|
+
deploymentMode === undefined &&
|
|
270
|
+
current?.deploymentMode === "local" &&
|
|
271
|
+
current.descriptorPath === verified.descriptorPath &&
|
|
272
|
+
current.trustRootPath === verified.trustRootPath;
|
|
248
273
|
const preserveTestMode =
|
|
249
274
|
deploymentMode === undefined &&
|
|
250
275
|
current?.deploymentMode === "test" &&
|
|
@@ -257,10 +282,17 @@ export async function configureEvolutionDeployment(
|
|
|
257
282
|
revisionFloors,
|
|
258
283
|
activeTrustRootDigest: verified.descriptor.trustRootDigest,
|
|
259
284
|
revokedDescriptorRevisions,
|
|
260
|
-
deploymentMode:
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
285
|
+
deploymentMode: preserveLocalMode
|
|
286
|
+
? "local"
|
|
287
|
+
: preserveTestMode
|
|
288
|
+
? "test"
|
|
289
|
+
: deploymentMode || "managed",
|
|
290
|
+
testPrivateKeyPath:
|
|
291
|
+
deploymentMode === "test"
|
|
292
|
+
? testPrivateKeyPath || null
|
|
293
|
+
: preserveTestMode
|
|
294
|
+
? current.testPrivateKeyPath
|
|
295
|
+
: null,
|
|
264
296
|
};
|
|
265
297
|
}, options);
|
|
266
298
|
return getEvolutionDeploymentStatus(options);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash, createPublicKey, verify } from "node:crypto";
|
|
2
2
|
import { readFile, realpath } from "node:fs/promises";
|
|
3
|
-
import { isAbsolute } from "node:path";
|
|
3
|
+
import { dirname, isAbsolute, join } from "node:path";
|
|
4
4
|
import { types as utilTypes } from "node:util";
|
|
5
5
|
import {
|
|
6
6
|
assertEvolutionDeploymentActiveTrustRoot,
|
|
@@ -622,7 +622,9 @@ async function loadBuiltInFactories(commandName) {
|
|
|
622
622
|
import("./evolution-eval-process-supervisor.js"),
|
|
623
623
|
import("./governed-skill-synthesis-attestor-trust-approval-client.js"),
|
|
624
624
|
import("./governed-skill-synthesis-attestor-trust-operations-client.js"),
|
|
625
|
-
import(
|
|
625
|
+
import(
|
|
626
|
+
"./governed-skill-synthesis-attestor-trust-operations-cli-host.js"
|
|
627
|
+
),
|
|
626
628
|
]);
|
|
627
629
|
factories.createEvolutionWorkbenchCliHost = createEvolutionWorkbenchCliHost;
|
|
628
630
|
factories.createEvolutionWorkbenchReviewRuntime =
|
|
@@ -840,6 +842,15 @@ function bindFactoriesToModule(factories, moduleDigest) {
|
|
|
840
842
|
return factories[name](options);
|
|
841
843
|
};
|
|
842
844
|
}
|
|
845
|
+
if (typeof factories.createLocalUiEvolutionComposition === "function") {
|
|
846
|
+
result.createLocalUiEvolutionComposition = (options = {}) => {
|
|
847
|
+
if (options?.handlerArtifactDigest !== moduleDigest)
|
|
848
|
+
throw new Error(
|
|
849
|
+
"Local UI Evolution host digest must equal the authenticated deployment module digest",
|
|
850
|
+
);
|
|
851
|
+
return factories.createLocalUiEvolutionComposition(options);
|
|
852
|
+
};
|
|
853
|
+
}
|
|
843
854
|
for (const name of [
|
|
844
855
|
"createSkillEvaluatedPromotionProvider",
|
|
845
856
|
"createSkillPromotionReviewProvider",
|
|
@@ -1012,19 +1023,62 @@ export async function loadEvolutionDeploymentCommandDependencies(
|
|
|
1012
1023
|
commandName,
|
|
1013
1024
|
{
|
|
1014
1025
|
env = process.env,
|
|
1026
|
+
cwd = process.cwd(),
|
|
1015
1027
|
read = readFile,
|
|
1016
1028
|
resolveRealPath = realpath,
|
|
1017
1029
|
importModule = (url) => import(url),
|
|
1018
1030
|
additionalFactories = {},
|
|
1031
|
+
initializeDefaultLocalUi = false,
|
|
1032
|
+
initializeDefaultLocalModels = true,
|
|
1019
1033
|
} = {},
|
|
1020
1034
|
) {
|
|
1021
1035
|
if (!SUPPORTED_COMMANDS.has(commandName)) return null;
|
|
1036
|
+
const localModelDependencies = () =>
|
|
1037
|
+
dependencies(
|
|
1038
|
+
{
|
|
1039
|
+
evolutionCompositionFactory: async (context) => {
|
|
1040
|
+
const { initializeDefaultLocalUiEvolutionDeployment } = await import(
|
|
1041
|
+
"./local-ui-evolution-deployment.js"
|
|
1042
|
+
);
|
|
1043
|
+
await initializeDefaultLocalUiEvolutionDeployment({ env, cwd });
|
|
1044
|
+
const admitted = await loadEvolutionDeploymentCommandDependencies(
|
|
1045
|
+
commandName,
|
|
1046
|
+
{
|
|
1047
|
+
env,
|
|
1048
|
+
cwd,
|
|
1049
|
+
read,
|
|
1050
|
+
resolveRealPath,
|
|
1051
|
+
importModule,
|
|
1052
|
+
additionalFactories,
|
|
1053
|
+
initializeDefaultLocalModels: false,
|
|
1054
|
+
},
|
|
1055
|
+
);
|
|
1056
|
+
if (typeof admitted?.evolutionCompositionFactory !== "function")
|
|
1057
|
+
throw new Error(
|
|
1058
|
+
"Local model command requires an authenticated Evolution deployment",
|
|
1059
|
+
);
|
|
1060
|
+
return admitted.evolutionCompositionFactory(context);
|
|
1061
|
+
},
|
|
1062
|
+
},
|
|
1063
|
+
commandName,
|
|
1064
|
+
);
|
|
1022
1065
|
let descriptorPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_DESCRIPTOR;
|
|
1023
1066
|
let trustRootPath = env.CHAINLESSCHAIN_EVOLUTION_DEPLOYMENT_TRUST_ROOT;
|
|
1067
|
+
if (
|
|
1068
|
+
initializeDefaultLocalUi === true &&
|
|
1069
|
+
commandName === "ui" &&
|
|
1070
|
+
!descriptorPath &&
|
|
1071
|
+
!trustRootPath
|
|
1072
|
+
) {
|
|
1073
|
+
const { initializeDefaultLocalUiEvolutionDeployment } = await import(
|
|
1074
|
+
"./local-ui-evolution-deployment.js"
|
|
1075
|
+
);
|
|
1076
|
+
await initializeDefaultLocalUiEvolutionDeployment({ env, cwd });
|
|
1077
|
+
}
|
|
1024
1078
|
let fromSavedProfile = false;
|
|
1025
1079
|
let saved = null;
|
|
1026
1080
|
if (!descriptorPath && !trustRootPath) {
|
|
1027
|
-
saved = await readEvolutionDeploymentProfile({ env });
|
|
1081
|
+
saved = await readEvolutionDeploymentProfile({ env, cwd });
|
|
1028
1082
|
if (saved.error) {
|
|
1029
1083
|
return deniedAgentDependencies(
|
|
1030
1084
|
commandName,
|
|
@@ -1039,6 +1093,15 @@ export async function loadEvolutionDeploymentCommandDependencies(
|
|
|
1039
1093
|
"Saved evolution deployment profile is disabled",
|
|
1040
1094
|
);
|
|
1041
1095
|
}
|
|
1096
|
+
if (
|
|
1097
|
+
initializeDefaultLocalModels &&
|
|
1098
|
+
["agent", "ask", "chat"].includes(commandName) &&
|
|
1099
|
+
!saved.profile
|
|
1100
|
+
) {
|
|
1101
|
+
// Registration/help is read-only. Bootstrap only when a real command
|
|
1102
|
+
// requests its authenticated composition, then re-read current policy.
|
|
1103
|
+
return localModelDependencies();
|
|
1104
|
+
}
|
|
1042
1105
|
if (!saved.error && saved.profile?.enabled) {
|
|
1043
1106
|
descriptorPath = saved.profile.descriptorPath;
|
|
1044
1107
|
trustRootPath = saved.profile.trustRootPath;
|
|
@@ -1086,6 +1149,39 @@ export async function loadEvolutionDeploymentCommandDependencies(
|
|
|
1086
1149
|
throw error;
|
|
1087
1150
|
}
|
|
1088
1151
|
const { descriptor, moduleBytes } = verified;
|
|
1152
|
+
const localProfile =
|
|
1153
|
+
fromSavedProfile && saved.profile.deploymentMode === "local";
|
|
1154
|
+
if (localProfile) {
|
|
1155
|
+
const generation = saved.profile.descriptorPath.endsWith(
|
|
1156
|
+
"deployment-v2.json",
|
|
1157
|
+
)
|
|
1158
|
+
? 2
|
|
1159
|
+
: 1;
|
|
1160
|
+
const localHostPath = join(
|
|
1161
|
+
dirname(saved.filePath),
|
|
1162
|
+
"local-ui-host",
|
|
1163
|
+
generation === 2 ? "ui-host-v2.mjs" : "ui-host.mjs",
|
|
1164
|
+
);
|
|
1165
|
+
const canonicalLocalHostPath = await realpath(localHostPath);
|
|
1166
|
+
if (
|
|
1167
|
+
!(
|
|
1168
|
+
["ui"].join(",") === descriptor.commands.join(",") ||
|
|
1169
|
+
"agent,ask,chat,ui" === descriptor.commands.join(",")
|
|
1170
|
+
) ||
|
|
1171
|
+
verified.modulePath !== canonicalLocalHostPath
|
|
1172
|
+
) {
|
|
1173
|
+
throw new Error(
|
|
1174
|
+
"Local Evolution deployment is not the protected UI host",
|
|
1175
|
+
);
|
|
1176
|
+
}
|
|
1177
|
+
if (
|
|
1178
|
+
initializeDefaultLocalModels &&
|
|
1179
|
+
["agent", "ask", "chat", "ui"].includes(commandName) &&
|
|
1180
|
+
descriptor.commands.length === 1 &&
|
|
1181
|
+
descriptor.commands[0] === "ui"
|
|
1182
|
+
)
|
|
1183
|
+
return localModelDependencies();
|
|
1184
|
+
}
|
|
1089
1185
|
if (!descriptor.commands.includes(commandName)) {
|
|
1090
1186
|
return deniedAgentDependencies(
|
|
1091
1187
|
commandName,
|
|
@@ -1105,8 +1201,25 @@ export async function loadEvolutionDeploymentCommandDependencies(
|
|
|
1105
1201
|
throw new Error(
|
|
1106
1202
|
"evolution deployment module must export createChainlessChainCommandDependencies",
|
|
1107
1203
|
);
|
|
1204
|
+
const builtIn = await loadBuiltInFactories(commandName);
|
|
1205
|
+
let localFactories = null;
|
|
1206
|
+
if (localProfile) {
|
|
1207
|
+
const { createLocalUiEvolutionComposition } = await import(
|
|
1208
|
+
"./local-ui-evolution-runtime.js"
|
|
1209
|
+
);
|
|
1210
|
+
localFactories = {
|
|
1211
|
+
createLocalUiEvolutionComposition: (options = {}) =>
|
|
1212
|
+
createLocalUiEvolutionComposition({
|
|
1213
|
+
...options,
|
|
1214
|
+
commandName,
|
|
1215
|
+
localDirectory: join(dirname(saved.filePath), "local-ui-host"),
|
|
1216
|
+
env,
|
|
1217
|
+
cwd,
|
|
1218
|
+
}),
|
|
1219
|
+
};
|
|
1220
|
+
}
|
|
1108
1221
|
const builtInFactories = bindFactoriesToModule(
|
|
1109
|
-
|
|
1222
|
+
{ ...builtIn, ...(localFactories || {}) },
|
|
1110
1223
|
descriptor.moduleDigest,
|
|
1111
1224
|
);
|
|
1112
1225
|
if (
|
|
@@ -124,7 +124,7 @@ function normalizeProfile(value) {
|
|
|
124
124
|
const deploymentMode = beforeDeploymentMode
|
|
125
125
|
? "managed"
|
|
126
126
|
: value.deploymentMode;
|
|
127
|
-
if (!["managed", "test"].includes(deploymentMode))
|
|
127
|
+
if (!["managed", "test", "local"].includes(deploymentMode))
|
|
128
128
|
throw new TypeError("evolution deployment profile mode is invalid");
|
|
129
129
|
const testPrivateKeyPath = beforeDeploymentMode
|
|
130
130
|
? null
|
|
@@ -133,7 +133,7 @@ function normalizeProfile(value) {
|
|
|
133
133
|
(deploymentMode === "test" &&
|
|
134
134
|
(typeof testPrivateKeyPath !== "string" ||
|
|
135
135
|
!isAbsolute(testPrivateKeyPath))) ||
|
|
136
|
-
(deploymentMode
|
|
136
|
+
(deploymentMode !== "test" && testPrivateKeyPath !== null)
|
|
137
137
|
) {
|
|
138
138
|
throw new TypeError(
|
|
139
139
|
"evolution deployment profile test private key path is invalid",
|