@xopcai/xopc 0.0.372 → 0.0.373
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/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-BQ3PMp2q.js → activity-store-BeYLqqr8.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D4iAZErG.js → agent-avatar-dicebear--kDkSTqC.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-z4_2-Kn2.js +1 -0
- package/dist/gateway/static/root/assets/{agent-plugin-dialog-BYB0G2aF.js → agent-plugin-dialog-BYndK83K.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-D0JBkZPV.js → agents-CVo96cx1.js} +3 -3
- package/dist/gateway/static/root/assets/{agents-admin-api-HBZvVyzF.js → agents-admin-api-B4tgTbWG.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-C1tQxHaP.js → app-management-settings-panel-D9oOJKiH.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-BfavIBbb.js → appearance-settings-B0-8Cdyv.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-CUS5S1qa.js → apps-page-DasVc6i4.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-BO3I9zRP.js → archive-plugin-bI9OLnXj.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-iY0KMPSa.js → automations-page-BlCNqy2i.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-LQsa5ohY.js → automations-workspace-C8ipDP05.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-gFD7vH9R.js → binary-plugins-dOwLzjeH.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Cft0fd_O.js → block-editor-Cktlez6g.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automation-inputs-DxRoKFun.js → browser-automation-inputs-i7h1Svpf.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-automations-page-C6EWx_Y4.js → browser-automations-page-KRfDl8ej.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-CKlt_8IS.js → browser-settings-page-BraQ4wnh.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-CY4SiHcP.js → capabilities-CquUV0DP.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-gjQtMhKu.js → capabilities-D4KFLtqM.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-page-UrQ8EY_o.js → capabilities-page-B3m8xGzd.js} +2 -2
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-C9HIr2CZ.js → capabilities-settings-panel-VQ4fHuBV.js} +6 -6
- package/dist/gateway/static/root/assets/{capability-header-actions-uxIiW_2_.js → capability-header-actions-f5Ido4Eg.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-By3dmQ4Y.js → channels-N4Vc2nEG.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-DeDTSl64.js → chat-terminal-dock-BwvTKwsn.js} +1 -1
- package/dist/gateway/static/root/assets/cloud-credits-BMYMiiNn.js +1 -0
- package/dist/gateway/static/root/assets/{computer-settings-page-Cw1Z1epy.js → computer-settings-page-CAwUsKpw.js} +1 -1
- package/dist/gateway/static/root/assets/{connector-service-page-D664WEhj.js → connector-service-page-C0HuAMuH.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-sjyjY7Fl.js → connectors-page-BcBmW8JT.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-BVmFrPfX.js → date-picker-DiQxRpe-.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-YIoP-e5-.js → dependency-picker-Ds0_BJbN.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-CzS468vR.js → desktop-pet-ZMEOYwrR.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-BPcgZUcK.js → desktop-pet-settings-DkyTqD07.js} +1 -1
- package/dist/gateway/static/root/assets/{device-pairing-wizard-Cgba-4m9.js → device-pairing-wizard-CvaI5ZJZ.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-_nHmZtnY.js → directory-picker-path-field-Bfv93eK1.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-IIky9Iqr.js → extension-debug-page-CbgEonkK.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-C-7ngTTj.js → extension-page-JXKGtIdM.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-provider-VFWspV08.js → extension-provider-DxlAZ2iy.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-_hovFCWi.js → extension-settings-page-lsQ2xvbr.js} +1 -1
- package/dist/gateway/static/root/assets/{fallback-models-CUHrPpGV.js → fallback-models-7bG0AND1.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-7RKqgU_U.js → gateway-config-swr-BoRkBnsw.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-realtime-BwX_fHUS.js → gateway-realtime-C3WQQY10.js} +1 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-cLCDEe4D.js +1 -0
- package/dist/gateway/static/root/assets/{gateway-settings-sbaOzlEH.js → gateway-settings-BpbcoPx9.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-jiV5sbEX.js → gateway-startup-retry-TYSQEQcG.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-DjquRIFR.js → home-page-BxctC0aJ.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-DO4mXb6I.js → image-generation-api-_pKiNfSq.js} +1 -1
- package/dist/gateway/static/root/assets/{imports-page-xWWIeT_t.js → imports-page-Bq8CazCb.js} +1 -1
- package/dist/gateway/static/root/assets/{index-BWDK2eIj.js → index-B40-KDN8.js} +7 -7
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DWazrDgz.js → keyboard-shortcuts-settings-kkAevkl2.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-CkxDdlYU.js → local-app-workbench-page-abLaf1hW.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-BISZ4bi5.js → local-apps-page-nwsnwYjK.js} +1 -1
- package/dist/gateway/static/root/assets/{local-session-drafts-pox8evDV.js → local-session-drafts-Cg9RdsNN.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-COVscAqC.js → locale-store-rWFLl-p4.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-GiCulc9k.js → logs-page-BEgYS-Xg.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-GUpOcTqa.js → management-settings-D_JQ6_X0.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-B_qnAcW2.js → markdown-view-BHFFusQs.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-C0Pc-wSY.js → media-plugins-BVPTMWJI.js} +1 -1
- package/dist/gateway/static/root/assets/messages-C1SUo4gG.js +3 -0
- package/dist/gateway/static/root/assets/models-hub-cache-Jj8dvYcv.js +1 -0
- package/dist/gateway/static/root/assets/{note-detail-panel-CqealmSc.js → note-detail-panel-CCnfurBR.js} +3 -3
- package/dist/gateway/static/root/assets/{notes-api-sBgBcyLW.js → notes-api-CSLVCZBn.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-BtTU5mnS.js → notes-page-D9u_znxM.js} +1 -1
- package/dist/gateway/static/root/assets/{page-context-capture-button-Yt-BpPRh.js → page-context-capture-button-BO3FoRej.js} +1 -1
- package/dist/gateway/static/root/assets/{personal-page-C8SEQpEu.js → personal-page-BJn6UHAF.js} +1 -1
- package/dist/gateway/static/root/assets/{product-open-page-etM6Ijfe.js → product-open-page-Dso2_hyl.js} +1 -1
- package/dist/gateway/static/root/assets/{product-preview-content-C6aeRrWe.js → product-preview-content-CkvVb3EA.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-K4ASOTki.js → project-detail-page-UjrrzE3H.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-BssImjwl.js → projects-page-C1h63P2M.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-Bh9UBb-f.js → registry-api-CoMBYjHD.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BznC_5H0.js → remote-access-hub-BJifH8AB.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BJAzqQik.js → runtime-tools-settings-panel-vG1wqcEb.js} +1 -1
- package/dist/gateway/static/root/assets/{scenes-page-uZUXm03X.js → scenes-page-CwoAoYMX.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-SA3Ld7zf.js → schema-form-BIsHdyz7.js} +1 -1
- package/dist/gateway/static/root/assets/{send-session-input-Di3Q846r.js → send-session-input-CLhR1uEp.js} +1 -1
- package/dist/gateway/static/root/assets/{session-api-yjpEz4pP.js → session-api-u_4_kFQt.js} +1 -1
- package/dist/gateway/static/root/assets/{session-manager-CWjhJxJs.js → session-manager-B06ZCie_.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-DdL8zVrF.js → sessions-page-BcCLp3yU.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-D114UdRI.js +1 -0
- package/dist/gateway/static/root/assets/{settings-page-CUJQMNF7.js → settings-page-z9Jlk0BL.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-BGBWC0Bc.js → setup-status-panel-CrpXECqe.js} +1 -1
- package/dist/gateway/static/root/assets/{share-link-dialog-HCHM8qnf.js → share-link-dialog-XhiuPKF4.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-DJmyACyp.js → share-preview-page-Vc0TQuZ8.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-api-c0dfWz6h.js → shares-api-BVSb1vh4.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-BzqcGh7W.js → shares-settings-D9XpTJXP.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-api-9XSn7R8L.js → skill-api-DtPOf1aW.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-Ge5XymHa.js → skill-reload-api-BsLx_FXd.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-DwyDfh9g.js → skills-page-Bq9-2b9U.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-B6axBPLO.js → system-settings-panel-P7T729uD.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-ftCTqBDB.js → task-detail-page-CsB9AFx6.js} +1 -1
- package/dist/gateway/static/root/assets/{task-expandable-content-hYcgCEE3.js → task-expandable-content-DxeBTJvh.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-BOfCKgl6.js → theme-store-KcQhCg1-.js} +1 -1
- package/dist/gateway/static/root/assets/{tracing-settings-page-DDWFXcST.js → tracing-settings-page-DJRAP3nb.js} +1 -1
- package/dist/gateway/static/root/assets/{tunnel-api-BYU2v0im.js → tunnel-api-CuowqIZ7.js} +1 -1
- package/dist/gateway/static/root/assets/usage-page-avX3msoZ.js +1 -0
- package/dist/gateway/static/root/assets/{use-autosave-CSckcjFx.js → use-autosave-C-IWxbzm.js} +1 -1
- package/dist/gateway/static/root/assets/{use-composer-attachments-OFlldkKg.js → use-composer-attachments-Dxphaxk-.js} +1 -1
- package/dist/gateway/static/root/assets/{use-file-preview-expanded-BF1TeNXP.js → use-file-preview-expanded-Du37Gofn.js} +2 -2
- package/dist/gateway/static/root/assets/{user-model-page-CqnGITYf.js → user-model-page-DGDBWw7P.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-GEw5x2fU.js → voice-api-key-field-7BImy8Jc.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-config-api-3yyVwXln.js → voice-config-api-6MINytQl.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BDM7BEKH.js → work-discovery-overlay-BgJNz2tH.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BBwx-tUb.js → workflow-run-setup-panel-1I2q2J_U.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-BHigZn6E.js → workflows-page-DhJl9pnO.js} +1 -1
- package/dist/gateway/static/root/assets/{workspace-api-CTm8s6Jr.js → workspace-api-CXiyhTwv.js} +2 -2
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-CnPBP1V_.js +1 -0
- package/dist/gateway/static/root/index.html +26 -26
- package/dist/package.js +1 -1
- package/dist/packages/gateway-contract/src/cloud-credits.js +80 -0
- package/dist/packages/gateway-contract/src/index.js +2 -0
- package/dist/src/agent/agent-manager.js +4 -4
- package/dist/src/agent/background-review/run-background-review.js +1 -1
- package/dist/src/agent/client-error-format.d.ts +1 -1
- package/dist/src/agent/client-error-format.js +7 -0
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +2 -2
- package/dist/src/agent/embedded/run-turn.js +40 -4
- package/dist/src/agent/embedded/xopc-stream-bridge.js +18 -0
- package/dist/src/agent/image/generation/openai-images-provider.d.ts +2 -1
- package/dist/src/agent/image/generation/openai-images-provider.js +13 -7
- package/dist/src/agent/image/generation/providers/xopc-cloud.js +14 -2
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/service.js +3 -3
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/agent-config/schema.d.ts +4 -0
- package/dist/src/agent-config/schema.js +1 -0
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/model-credential-store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +1 -1
- package/dist/src/chat-commands/builtins/config.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/image-providers.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/models.js +42 -1
- package/dist/src/cli/commands/onboard/model.js +3 -3
- package/dist/src/computer/runtime.js +4 -1
- package/dist/src/config/index.js +3 -3
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +2 -2
- package/dist/src/extensions/activation-context.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.d.ts +1 -0
- package/dist/src/gateway/hono/lib/config-payload.js +2 -2
- package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +4 -4
- package/dist/src/gateway/hono/routes/observability.js +1 -1
- package/dist/src/gateway/hono/routes/usage.js +15 -5
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/service/config-coordinator.js +1 -1
- package/dist/src/gateway/service/session-command-service.js +1 -1
- package/dist/src/gateway/service.js +4 -4
- package/dist/src/home-intelligence/generator.js +1 -1
- package/dist/src/notes/service.js +1 -1
- package/dist/src/observability/runtime.js +1 -1
- package/dist/src/personal-agent/proactivity/service.js +2 -2
- package/dist/src/personal-agent/reply-composer.js +2 -2
- package/dist/src/platform/client.d.ts +1 -1
- package/dist/src/platform/contracts.d.ts +1 -1
- package/dist/src/platform/index.js +1 -1
- package/dist/src/providers/index.js +4 -4
- package/dist/src/providers/model-call.js +15 -1
- package/dist/src/providers/model-registry.js +2 -2
- package/dist/src/providers/provider-auth-service.js +1 -1
- package/dist/src/providers/provider-disconnect-core.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/providers/xopc-cloud-account-service.d.ts +7 -23
- package/dist/src/providers/xopc-cloud-account-service.js +49 -29
- package/dist/src/providers/xopc-cloud-catalog-coordinator.js +1 -1
- package/dist/src/providers/xopc-cloud-credit-budget.d.ts +14 -0
- package/dist/src/providers/xopc-cloud-credit-budget.js +61 -0
- package/dist/src/storage/sqlite/ai-usage-repository.d.ts +9 -0
- package/dist/src/storage/sqlite/ai-usage-repository.js +94 -5
- package/dist/src/storage/sqlite/migrations/242_cloud_usage_receipts.sql +5 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/tasks/task-main-update-decision-service.js +2 -2
- package/dist/src/tui/backends/embedded-backend.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/usage/cloud-capability.d.ts +2 -0
- package/dist/src/usage/cloud-capability.js +34 -0
- package/dist/src/usage/cloud-receipts.d.ts +10 -0
- package/dist/src/usage/cloud-receipts.js +55 -0
- package/dist/src/usage/cost.js +1 -0
- package/dist/src/usage/recorder.js +3 -1
- package/dist/src/usage/scenario-registry.js +15 -0
- package/dist/src/voice/realtime/runtime.js +27 -22
- package/dist/src/voice/stt/providers/xopc-cloud-transcription.js +28 -14
- package/dist/src/voice/tts/providers/xopc-cloud-speech.js +39 -29
- package/dist/src/voice/tts/speech-provider-types.d.ts +1 -0
- package/dist/src/work-discovery/service.js +2 -2
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +4 -4
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-BdxzGSiO.js +0 -1
- package/dist/gateway/static/root/assets/gateway-realtime-store-BheKaO6d.js +0 -1
- package/dist/gateway/static/root/assets/messages-Bb2GK-Nj.js +0 -3
- package/dist/gateway/static/root/assets/models-hub-cache-DyPPksMP.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-DmawLOHR.js +0 -1
- package/dist/gateway/static/root/assets/usage-page-BvPcpxTQ.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
2
|
import { init_paths, resolveModelsJsonPath } from "../config/paths.js";
|
|
3
|
-
import { init_register_bundled_oauth_flows, registerBundledOAuthFlows } from "./register-bundled-oauth-flows.js";
|
|
4
3
|
import { assertCurrentModelProvider, init_provider_policy } from "./provider-policy.js";
|
|
4
|
+
import { init_register_bundled_oauth_flows, registerBundledOAuthFlows } from "./register-bundled-oauth-flows.js";
|
|
5
5
|
import { CredentialResolver, init_credentials } from "../auth/credentials.js";
|
|
6
6
|
import { XopcModelCredentialStore, init_model_credential_store } from "../auth/model-credential-store.js";
|
|
7
7
|
import { init_register_runtime_providers, registerRuntimeProviders } from "./register-runtime-providers.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { getModelRegistry, init_model_registry } from "./model-registry.js";
|
|
3
4
|
import { init_oauth_provider_lock, withOAuthProviderLock } from "../auth/oauth-provider-lock.js";
|
|
4
5
|
import { CredentialResolver, init_credentials } from "../auth/credentials.js";
|
|
5
|
-
import { getModelRegistry, init_model_registry } from "./model-registry.js";
|
|
6
6
|
import { getProviderAuthService, init_provider_auth_service } from "./provider-auth-service.js";
|
|
7
7
|
import { evictAllEmbeddedSessionRunners } from "../agent/embedded/session-runner.js";
|
|
8
8
|
//#region src/providers/provider-disconnect-core.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
|
|
2
|
-
import { getOAuthProviderDefinition, init_registry } from "../auth/oauth/registry.js";
|
|
3
2
|
import { init_provider_policy, isRetiredModelProvider } from "./provider-policy.js";
|
|
4
3
|
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|
|
4
|
+
import { getOAuthProviderDefinition, init_registry } from "../auth/oauth/registry.js";
|
|
5
5
|
import { XOPC_CLOUD_PROVIDER_ID, init_xopc_cloud_config, resolveXopcModelRouterUrl } from "./xopc-cloud-config.js";
|
|
6
6
|
//#region src/providers/register-runtime-providers.ts
|
|
7
7
|
function registerRuntimeProvider(modelRuntime, source) {
|
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type CloudAccountSummary, type CloudCreditBudget, type CloudBillingReceipt } from '@xopcai/gateway-contract';
|
|
2
2
|
import { type ProviderAuthService } from './provider-auth-service.js';
|
|
3
|
-
|
|
4
|
-
balance: z.ZodObject<{
|
|
5
|
-
credits: z.ZodNumber;
|
|
6
|
-
updatedAt: z.ZodString;
|
|
7
|
-
}, z.core.$strip>;
|
|
8
|
-
usage: z.ZodObject<{
|
|
9
|
-
days: z.ZodUnion<readonly [z.ZodLiteral<1>, z.ZodLiteral<7>, z.ZodLiteral<30>]>;
|
|
10
|
-
requests: z.ZodNumber;
|
|
11
|
-
inputTokens: z.ZodNumber;
|
|
12
|
-
outputTokens: z.ZodNumber;
|
|
13
|
-
totalTokens: z.ZodNumber;
|
|
14
|
-
errors: z.ZodNumber;
|
|
15
|
-
averageLatencyMs: z.ZodNumber;
|
|
16
|
-
chargedCredits: z.ZodNumber;
|
|
17
|
-
}, z.core.$strip>;
|
|
18
|
-
links: z.ZodObject<{
|
|
19
|
-
details: z.ZodString;
|
|
20
|
-
purchase: z.ZodString;
|
|
21
|
-
}, z.core.$strip>;
|
|
22
|
-
}, z.core.$strip>;
|
|
23
|
-
export type XopcCloudAccountSummary = z.infer<typeof accountSummarySchema>;
|
|
3
|
+
export type XopcCloudAccountSummary = CloudAccountSummary;
|
|
24
4
|
export declare class XopcCloudAccountError extends Error {
|
|
25
5
|
readonly status: number;
|
|
26
6
|
readonly code?: string;
|
|
@@ -35,6 +15,10 @@ export declare class XopcCloudAccountService {
|
|
|
35
15
|
routerUrl?: string;
|
|
36
16
|
credentials?: Pick<ProviderAuthService, 'resolveApiKey'>;
|
|
37
17
|
});
|
|
18
|
+
private request;
|
|
19
|
+
private parse;
|
|
38
20
|
getSummary(days?: 1 | 7 | 30): Promise<XopcCloudAccountSummary | null>;
|
|
21
|
+
createBudget(limitCreditMicro: string, key: string): Promise<CloudCreditBudget | null>;
|
|
22
|
+
getReceipt(requestId: string): Promise<CloudBillingReceipt | null>;
|
|
23
|
+
getBudget(id: string): Promise<CloudCreditBudget | null>;
|
|
39
24
|
}
|
|
40
|
-
export {};
|
|
@@ -1,33 +1,12 @@
|
|
|
1
|
+
import { cloudAccountSummarySchema, cloudBillingReceiptSchema, cloudCreditBudgetSchema, creditMicroSchema, creditUnitSchema } from "../../packages/gateway-contract/src/cloud-credits.js";
|
|
2
|
+
import { init_src } from "../../packages/gateway-contract/src/index.js";
|
|
1
3
|
import { init_xopc_cloud_config, resolveXopcModelRouterUrl } from "./xopc-cloud-config.js";
|
|
2
4
|
import { getProviderAuthService, init_provider_auth_service } from "./provider-auth-service.js";
|
|
3
5
|
import { z } from "zod";
|
|
4
6
|
//#region src/providers/xopc-cloud-account-service.ts
|
|
7
|
+
init_src();
|
|
5
8
|
init_provider_auth_service();
|
|
6
9
|
init_xopc_cloud_config();
|
|
7
|
-
const accountSummarySchema = z.object({
|
|
8
|
-
balance: z.object({
|
|
9
|
-
credits: z.number().int().nonnegative(),
|
|
10
|
-
updatedAt: z.string().datetime()
|
|
11
|
-
}),
|
|
12
|
-
usage: z.object({
|
|
13
|
-
days: z.union([
|
|
14
|
-
z.literal(1),
|
|
15
|
-
z.literal(7),
|
|
16
|
-
z.literal(30)
|
|
17
|
-
]),
|
|
18
|
-
requests: z.number().int().nonnegative(),
|
|
19
|
-
inputTokens: z.number().int().nonnegative(),
|
|
20
|
-
outputTokens: z.number().int().nonnegative(),
|
|
21
|
-
totalTokens: z.number().int().nonnegative(),
|
|
22
|
-
errors: z.number().int().nonnegative(),
|
|
23
|
-
averageLatencyMs: z.number().nonnegative(),
|
|
24
|
-
chargedCredits: z.number().int().nonnegative()
|
|
25
|
-
}),
|
|
26
|
-
links: z.object({
|
|
27
|
-
details: z.string().url(),
|
|
28
|
-
purchase: z.string().url()
|
|
29
|
-
})
|
|
30
|
-
});
|
|
31
10
|
var XopcCloudAccountError = class extends Error {
|
|
32
11
|
constructor(message, status, code) {
|
|
33
12
|
super(message);
|
|
@@ -45,22 +24,63 @@ var XopcCloudAccountService = class {
|
|
|
45
24
|
this.routerUrl = resolveXopcModelRouterUrl(options.routerUrl);
|
|
46
25
|
this.credentials = options.credentials ?? getProviderAuthService();
|
|
47
26
|
}
|
|
48
|
-
async
|
|
27
|
+
async request(path, init) {
|
|
49
28
|
const accessToken = await this.credentials.resolveApiKey("xopc-cloud");
|
|
50
29
|
if (!accessToken) return null;
|
|
51
|
-
const response = await this.fetchImpl(`${this.routerUrl}
|
|
30
|
+
const response = await this.fetchImpl(`${this.routerUrl}${path}`, {
|
|
31
|
+
...init,
|
|
52
32
|
headers: {
|
|
33
|
+
...Object.fromEntries(new Headers(init?.headers)),
|
|
53
34
|
authorization: `Bearer ${accessToken}`,
|
|
54
35
|
accept: "application/json"
|
|
55
36
|
},
|
|
56
|
-
signal: AbortSignal.timeout(3e4)
|
|
37
|
+
signal: AbortSignal.timeout(3e4),
|
|
38
|
+
redirect: "error"
|
|
57
39
|
});
|
|
58
40
|
const body = await response.json().catch(() => null);
|
|
59
41
|
if (!response.ok) throw new XopcCloudAccountError(typeof body?.error?.message === "string" ? body.error.message : `XOPC account summary failed (${response.status})`, response.status, typeof body?.error?.code === "string" ? body.error.code : void 0);
|
|
60
|
-
|
|
61
|
-
|
|
42
|
+
if (body === null) throw new XopcCloudAccountError("XOPC Cloud returned invalid JSON", 502, "invalid_response");
|
|
43
|
+
return body;
|
|
44
|
+
}
|
|
45
|
+
parse(schema, body) {
|
|
46
|
+
if (body === null) return null;
|
|
47
|
+
const parsed = schema.safeParse(body);
|
|
48
|
+
if (!parsed.success) throw new XopcCloudAccountError("XOPC Cloud returned an invalid Credit response", 502, "invalid_response");
|
|
62
49
|
return parsed.data;
|
|
63
50
|
}
|
|
51
|
+
async getSummary(days = 7) {
|
|
52
|
+
return this.parse(cloudAccountSummarySchema, await this.request(`/account/summary?version=2&days=${days}`));
|
|
53
|
+
}
|
|
54
|
+
async createBudget(limitCreditMicro, key) {
|
|
55
|
+
creditMicroSchema.parse(limitCreditMicro);
|
|
56
|
+
if (limitCreditMicro === "0" || limitCreditMicro.length > 15 || !/^[\w:.-]{8,128}$/.test(key)) throw new Error("Invalid Credit budget");
|
|
57
|
+
return this.parse(z.object({
|
|
58
|
+
creditUnit: creditUnitSchema,
|
|
59
|
+
budget: cloudCreditBudgetSchema
|
|
60
|
+
}), await this.request("/account/budgets", {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: {
|
|
63
|
+
"content-type": "application/json",
|
|
64
|
+
"Idempotency-Key": key
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({ limitCreditMicro })
|
|
67
|
+
}))?.budget ?? null;
|
|
68
|
+
}
|
|
69
|
+
async getReceipt(requestId) {
|
|
70
|
+
z.string().min(1).max(128).parse(requestId);
|
|
71
|
+
return this.parse(z.object({
|
|
72
|
+
schemaVersion: z.literal(2),
|
|
73
|
+
creditUnit: creditUnitSchema,
|
|
74
|
+
receipt: cloudBillingReceiptSchema
|
|
75
|
+
}), await this.request(`/account/receipts/${encodeURIComponent(requestId)}`))?.receipt ?? null;
|
|
76
|
+
}
|
|
77
|
+
async getBudget(id) {
|
|
78
|
+
z.string().uuid().parse(id);
|
|
79
|
+
return this.parse(z.object({
|
|
80
|
+
creditUnit: creditUnitSchema,
|
|
81
|
+
budget: cloudCreditBudgetSchema
|
|
82
|
+
}), await this.request(`/account/budgets/${encodeURIComponent(id)}`))?.budget ?? null;
|
|
83
|
+
}
|
|
64
84
|
};
|
|
65
85
|
//#endregion
|
|
66
86
|
export { XopcCloudAccountError, XopcCloudAccountService };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createLogger } from "../utils/logger/index.js";
|
|
2
2
|
import { init_logger } from "../utils/logger.js";
|
|
3
|
-
import { init_oauth_provider_lock, withOAuthProviderLock } from "../auth/oauth-provider-lock.js";
|
|
4
3
|
import { ModelCatalogPersistence, init_model_catalog_persistence } from "./model-catalog-persistence.js";
|
|
5
4
|
import { getModelCatalogStore, init_model_catalog_store } from "./model-catalog-store.js";
|
|
6
5
|
import { getModelRegistry, init_model_registry } from "./model-registry.js";
|
|
6
|
+
import { init_oauth_provider_lock, withOAuthProviderLock } from "../auth/oauth-provider-lock.js";
|
|
7
7
|
import { reloadImageGenerationProviders } from "../agent/image/generation/provider-registry.js";
|
|
8
8
|
import { disconnectProviderCore } from "./provider-disconnect-core.js";
|
|
9
9
|
import { XopcCloudModelSource } from "./xopc-cloud-model-source.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { XopcCloudAccountService } from './xopc-cloud-account-service.js';
|
|
2
|
+
export declare function hasCloudCreditBudget(): boolean;
|
|
3
|
+
export declare function cloudCreditBudgetStopMessage(): string | undefined;
|
|
4
|
+
export declare function isCloudCreditBudgetExhausted(message: string): boolean;
|
|
5
|
+
export declare function reportCloudCreditError(message: string): void;
|
|
6
|
+
export declare function assertCloudCreditBudgetActive(): void;
|
|
7
|
+
/** Children inherit their parent's scope; repeated attempts use the same platform budget. */
|
|
8
|
+
export declare function withCloudCreditBudget<T>(options: {
|
|
9
|
+
conversationId: string;
|
|
10
|
+
runId: string;
|
|
11
|
+
limitCreditMicro?: string;
|
|
12
|
+
}, action: () => Promise<T>): Promise<T>;
|
|
13
|
+
export declare function cloudCreditBudgetHeaders(service?: Pick<XopcCloudAccountService, 'createBudget'>): Promise<Record<string, string>>;
|
|
14
|
+
export declare function rejectUnbudgetedCloudTransport(operation?: string): void;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { XopcCloudAccountService } from "./xopc-cloud-account-service.js";
|
|
4
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
//#region src/providers/xopc-cloud-credit-budget.ts
|
|
7
|
+
init_logger();
|
|
8
|
+
const log = createLogger("CloudCreditBudget");
|
|
9
|
+
const scopes = new AsyncLocalStorage();
|
|
10
|
+
const EXHAUSTED = /credit_budget_exhausted|(?:task Credit|Credit task) budget exhausted/i;
|
|
11
|
+
function hasCloudCreditBudget() {
|
|
12
|
+
return Boolean(scopes.getStore());
|
|
13
|
+
}
|
|
14
|
+
function cloudCreditBudgetStopMessage() {
|
|
15
|
+
return scopes.getStore()?.stopped;
|
|
16
|
+
}
|
|
17
|
+
function isCloudCreditBudgetExhausted(message) {
|
|
18
|
+
return EXHAUSTED.test(message);
|
|
19
|
+
}
|
|
20
|
+
function reportCloudCreditError(message) {
|
|
21
|
+
const scope = scopes.getStore();
|
|
22
|
+
if (scope && isCloudCreditBudgetExhausted(message)) scope.stopped = "credit_budget_exhausted: Credit task budget exhausted";
|
|
23
|
+
}
|
|
24
|
+
function assertCloudCreditBudgetActive() {
|
|
25
|
+
const stopped = scopes.getStore()?.stopped;
|
|
26
|
+
if (stopped) throw new Error(stopped);
|
|
27
|
+
}
|
|
28
|
+
/** Children inherit their parent's scope; repeated attempts use the same platform budget. */
|
|
29
|
+
async function withCloudCreditBudget(options, action) {
|
|
30
|
+
if (scopes.getStore() || !options.limitCreditMicro) return action();
|
|
31
|
+
const key = `xopc-run:${createHash("sha256").update(JSON.stringify([options.conversationId, options.runId])).digest("hex")}`;
|
|
32
|
+
return scopes.run({
|
|
33
|
+
key,
|
|
34
|
+
conversationId: options.conversationId,
|
|
35
|
+
runId: options.runId,
|
|
36
|
+
limitCreditMicro: options.limitCreditMicro
|
|
37
|
+
}, action);
|
|
38
|
+
}
|
|
39
|
+
async function cloudCreditBudgetHeaders(service) {
|
|
40
|
+
assertCloudCreditBudgetActive();
|
|
41
|
+
const scope = scopes.getStore();
|
|
42
|
+
if (!scope) return {};
|
|
43
|
+
scope.budget ??= (service ?? new XopcCloudAccountService()).createBudget(scope.limitCreditMicro, scope.key).then((budget) => {
|
|
44
|
+
if (budget) log.info({
|
|
45
|
+
conversationId: scope.conversationId,
|
|
46
|
+
runId: scope.runId,
|
|
47
|
+
creditBudgetId: budget.id,
|
|
48
|
+
limitCreditMicro: budget.limitCreditMicro
|
|
49
|
+
}, "Created Cloud run Credit budget");
|
|
50
|
+
return budget;
|
|
51
|
+
});
|
|
52
|
+
const budget = await scope.budget;
|
|
53
|
+
if (!budget) throw new Error("XOPC Cloud authorization is unavailable");
|
|
54
|
+
assertCloudCreditBudgetActive();
|
|
55
|
+
return { "x-xopc-credit-budget": budget.id };
|
|
56
|
+
}
|
|
57
|
+
function rejectUnbudgetedCloudTransport(operation = "realtime voice") {
|
|
58
|
+
if (scopes.getStore()) throw new Error(`Credit run budgets do not support ${operation} yet`);
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { assertCloudCreditBudgetActive, cloudCreditBudgetHeaders, cloudCreditBudgetStopMessage, hasCloudCreditBudget, isCloudCreditBudgetExhausted, rejectUnbudgetedCloudTransport, reportCloudCreditError, withCloudCreditBudget };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { AiUsageEvent, AiUsageFinish } from '../../usage/types.js';
|
|
2
|
+
import type { CloudBillingReceipt, UsageBilling, UsageTotals } from '@xopcai/gateway-contract';
|
|
2
3
|
export declare const AI_USAGE_RETENTION_MS: number;
|
|
3
4
|
export declare function insertAiUsageEvent(event: AiUsageEvent): void;
|
|
4
5
|
export declare function finishAiUsageEvent(id: string, finish: AiUsageFinish & {
|
|
@@ -7,6 +8,8 @@ export declare function finishAiUsageEvent(id: string, finish: AiUsageFinish & {
|
|
|
7
8
|
export declare function markStaleAiUsageEventsUnknown(cutoffMs: number, now?: number): number;
|
|
8
9
|
export declare function pruneAiUsageEvents(cutoffMs: number): number;
|
|
9
10
|
export declare function getAiUsageEvent(id: string): Record<string, unknown> | undefined;
|
|
11
|
+
export declare function setAiUsageCloudRequest(id: string, requestId: string): void;
|
|
12
|
+
export declare function setAiUsageCloudReceipt(id: string, receipt: CloudBillingReceipt): void;
|
|
10
13
|
export type AiUsageQuery = {
|
|
11
14
|
from: number;
|
|
12
15
|
to: number;
|
|
@@ -16,6 +19,8 @@ export type AiUsageQuery = {
|
|
|
16
19
|
agentId?: string;
|
|
17
20
|
conversationId?: string;
|
|
18
21
|
};
|
|
22
|
+
export declare function pendingAiUsageCloudReceiptIds(query: AiUsageQuery): string[];
|
|
23
|
+
export declare function markAiUsageCloudReceiptAttempt(id: string): void;
|
|
19
24
|
export type AiUsageTotals = {
|
|
20
25
|
calls: number;
|
|
21
26
|
succeededCalls: number;
|
|
@@ -28,6 +33,7 @@ export type AiUsageTotals = {
|
|
|
28
33
|
totalTokens: number;
|
|
29
34
|
knownCostUsd: string;
|
|
30
35
|
costCompleteness: 'complete' | 'partial' | 'unknown';
|
|
36
|
+
billing: NonNullable<UsageTotals['billing']>;
|
|
31
37
|
};
|
|
32
38
|
export type ConversationAiUsageTotals = Pick<AiUsageTotals, 'calls' | 'unknownCostCalls' | 'totalTokens' | 'knownCostUsd' | 'costCompleteness'>;
|
|
33
39
|
/** Aggregate all retained AI usage records for the requested conversations. */
|
|
@@ -78,6 +84,7 @@ export declare function listAiUsageEvents(query: AiUsageQuery & {
|
|
|
78
84
|
reasoningTokens: number;
|
|
79
85
|
totalTokens: number;
|
|
80
86
|
estimatedCostUsd: string;
|
|
87
|
+
billing: UsageBilling;
|
|
81
88
|
costSource: string;
|
|
82
89
|
pricingSnapshot: Record<string, number>;
|
|
83
90
|
errorSummary: string;
|
|
@@ -110,6 +117,7 @@ export declare function getAiUsageEventView(id: string): {
|
|
|
110
117
|
reasoningTokens: number;
|
|
111
118
|
totalTokens: number;
|
|
112
119
|
estimatedCostUsd: string;
|
|
120
|
+
billing: UsageBilling;
|
|
113
121
|
costSource: string;
|
|
114
122
|
pricingSnapshot: Record<string, number>;
|
|
115
123
|
errorSummary: string;
|
|
@@ -140,6 +148,7 @@ export declare function listAiUsageTrace(traceId: string): {
|
|
|
140
148
|
reasoningTokens: number;
|
|
141
149
|
totalTokens: number;
|
|
142
150
|
estimatedCostUsd: string;
|
|
151
|
+
billing: UsageBilling;
|
|
143
152
|
costSource: string;
|
|
144
153
|
pricingSnapshot: Record<string, number>;
|
|
145
154
|
errorSummary: string;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
+
import { creditMicroSchema } from "../../../packages/gateway-contract/src/cloud-credits.js";
|
|
3
|
+
import { init_src } from "../../../packages/gateway-contract/src/index.js";
|
|
2
4
|
//#region src/storage/sqlite/ai-usage-repository.ts
|
|
5
|
+
init_src();
|
|
3
6
|
init_transaction();
|
|
4
7
|
const ERROR_SUMMARY_LIMIT = 512;
|
|
5
8
|
const AI_USAGE_RETENTION_MS = 4320 * 60 * 60 * 1e3;
|
|
@@ -43,6 +46,41 @@ function pruneAiUsageEvents(cutoffMs) {
|
|
|
43
46
|
function getAiUsageEvent(id) {
|
|
44
47
|
return getSqliteDatabase().prepare("SELECT * FROM ai_usage_events WHERE id = ?").get(id);
|
|
45
48
|
}
|
|
49
|
+
function setAiUsageCloudRequest(id, requestId) {
|
|
50
|
+
if (!/^[A-Za-z0-9_.:-]{1,128}$/.test(requestId)) return;
|
|
51
|
+
runSqliteWriteTransaction((db) => {
|
|
52
|
+
db.prepare(`UPDATE ai_usage_events SET cloud_request_id = ?, updated_at = ?
|
|
53
|
+
WHERE id = ? AND provider = 'xopc-cloud' AND cloud_billing_json IS NULL`).run(requestId, Date.now(), id);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function setAiUsageCloudReceipt(id, receipt) {
|
|
57
|
+
if (![
|
|
58
|
+
"settled",
|
|
59
|
+
"released",
|
|
60
|
+
"expired",
|
|
61
|
+
"reserved",
|
|
62
|
+
"pending"
|
|
63
|
+
].includes(receipt.state)) return;
|
|
64
|
+
const state = receipt.state === "settled" ? "settled" : ["released", "expired"].includes(receipt.state) ? "released" : "pending";
|
|
65
|
+
const charged = state === "settled" ? receipt.chargedCreditMicro : state === "released" ? "0" : null;
|
|
66
|
+
if (state === "settled" && charged === null) return;
|
|
67
|
+
creditMicroSchema.parse(receipt.reservedCreditMicro);
|
|
68
|
+
creditMicroSchema.parse(receipt.releasedCreditMicro);
|
|
69
|
+
if (charged !== null) creditMicroSchema.parse(charged);
|
|
70
|
+
const billing = {
|
|
71
|
+
source: "xopc_cloud",
|
|
72
|
+
state,
|
|
73
|
+
requestId: receipt.requestId,
|
|
74
|
+
reservedCreditMicro: state === "pending" ? receipt.reservedCreditMicro : "0",
|
|
75
|
+
chargedCreditMicro: charged,
|
|
76
|
+
releasedCreditMicro: receipt.releasedCreditMicro
|
|
77
|
+
};
|
|
78
|
+
runSqliteWriteTransaction((db) => {
|
|
79
|
+
db.prepare(`UPDATE ai_usage_events SET cloud_billing_json = ?, updated_at = ?
|
|
80
|
+
WHERE id = ? AND provider = 'xopc-cloud' AND cloud_request_id = ?
|
|
81
|
+
AND COALESCE(json_extract(cloud_billing_json, '$.state'), '') NOT IN ('settled', 'released')`).run(JSON.stringify(billing), Date.now(), id, receipt.requestId);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
46
84
|
function queryWhere(query) {
|
|
47
85
|
const clauses = ["started_at >= ?", "started_at < ?"];
|
|
48
86
|
const values = [query.from, query.to];
|
|
@@ -64,6 +102,18 @@ function queryWhere(query) {
|
|
|
64
102
|
values
|
|
65
103
|
};
|
|
66
104
|
}
|
|
105
|
+
function pendingAiUsageCloudReceiptIds(query) {
|
|
106
|
+
const { sql, values } = queryWhere(query);
|
|
107
|
+
return getSqliteDatabase().prepare(`SELECT id FROM ai_usage_events WHERE ${sql}
|
|
108
|
+
AND provider = 'xopc-cloud' AND cloud_request_id IS NOT NULL
|
|
109
|
+
AND COALESCE(json_extract(cloud_billing_json, '$.state'), '') NOT IN ('settled', 'released')
|
|
110
|
+
ORDER BY updated_at ASC, id ASC LIMIT 4`).all(...values).map((row) => row.id);
|
|
111
|
+
}
|
|
112
|
+
function markAiUsageCloudReceiptAttempt(id) {
|
|
113
|
+
runSqliteWriteTransaction((db) => {
|
|
114
|
+
db.prepare(`UPDATE ai_usage_events SET updated_at = ? WHERE id = ? AND provider = 'xopc-cloud'`).run(Date.now(), id);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
67
117
|
function usd(microusd) {
|
|
68
118
|
return (microusd / 1e6).toFixed(6).replace(/0+$/, "").replace(/\.$/, "") || "0";
|
|
69
119
|
}
|
|
@@ -81,19 +131,44 @@ function totalsFromRow(row) {
|
|
|
81
131
|
cacheWriteTokens: Number(row.cache_write_tokens ?? 0),
|
|
82
132
|
totalTokens: Number(row.total_tokens ?? 0),
|
|
83
133
|
knownCostUsd: usd(Number(row.known_cost_microusd ?? 0)),
|
|
84
|
-
costCompleteness:
|
|
134
|
+
costCompleteness: Number(row.external_calls ?? 0) === 0 || unknownCostCalls === Number(row.external_calls) ? "unknown" : unknownCostCalls > 0 ? "partial" : "complete",
|
|
135
|
+
billing: {
|
|
136
|
+
external: {
|
|
137
|
+
calls: Number(row.external_calls ?? 0),
|
|
138
|
+
estimatedCostUsd: usd(Number(row.known_cost_microusd ?? 0)),
|
|
139
|
+
unknownCostCalls
|
|
140
|
+
},
|
|
141
|
+
localCalls: Number(row.local_calls ?? 0),
|
|
142
|
+
cloud: {
|
|
143
|
+
calls: Number(row.cloud_calls ?? 0),
|
|
144
|
+
settledCalls: Number(row.cloud_final_calls ?? 0),
|
|
145
|
+
pendingCalls: Number(row.cloud_pending_calls ?? 0),
|
|
146
|
+
unavailableCalls: Number(row.cloud_unavailable_calls ?? 0),
|
|
147
|
+
chargedCreditMicro: Number(row.cloud_final_calls ?? 0) > 0 ? String(row.cloud_charged_micro ?? "0") : null,
|
|
148
|
+
reservedCreditMicro: Number(row.cloud_known_reservations ?? 0) > 0 ? String(row.cloud_reserved_micro ?? "0") : null
|
|
149
|
+
}
|
|
150
|
+
}
|
|
85
151
|
};
|
|
86
152
|
}
|
|
87
153
|
const TOTALS_SQL = `COUNT(*) AS calls,
|
|
88
154
|
SUM(CASE WHEN status = 'succeeded' THEN 1 ELSE 0 END) AS succeeded_calls,
|
|
89
155
|
SUM(CASE WHEN status IN ('failed', 'aborted', 'unknown') THEN 1 ELSE 0 END) AS failed_calls,
|
|
90
|
-
SUM(CASE WHEN cost_source <> 'local' AND estimated_cost_microusd IS NULL THEN 1 ELSE 0 END) AS unknown_cost_calls,
|
|
156
|
+
SUM(CASE WHEN provider <> 'xopc-cloud' AND cost_source <> 'local' AND estimated_cost_microusd IS NULL THEN 1 ELSE 0 END) AS unknown_cost_calls,
|
|
157
|
+
SUM(CASE WHEN provider <> 'xopc-cloud' AND cost_source <> 'local' THEN 1 ELSE 0 END) AS external_calls,
|
|
158
|
+
SUM(CASE WHEN provider <> 'xopc-cloud' AND cost_source = 'local' THEN 1 ELSE 0 END) AS local_calls,
|
|
159
|
+
SUM(CASE WHEN provider = 'xopc-cloud' THEN 1 ELSE 0 END) AS cloud_calls,
|
|
160
|
+
SUM(CASE WHEN provider = 'xopc-cloud' AND json_extract(cloud_billing_json, '$.state') IN ('settled', 'released') THEN 1 ELSE 0 END) AS cloud_final_calls,
|
|
161
|
+
SUM(CASE WHEN provider = 'xopc-cloud' AND json_extract(cloud_billing_json, '$.state') = 'pending' THEN 1 ELSE 0 END) AS cloud_pending_calls,
|
|
162
|
+
SUM(CASE WHEN provider = 'xopc-cloud' AND cloud_billing_json IS NULL THEN 1 ELSE 0 END) AS cloud_unavailable_calls,
|
|
163
|
+
SUM(CASE WHEN provider = 'xopc-cloud' AND cloud_billing_json IS NOT NULL THEN 1 ELSE 0 END) AS cloud_known_reservations,
|
|
164
|
+
CAST(COALESCE(SUM(CASE WHEN provider = 'xopc-cloud' THEN CAST(json_extract(cloud_billing_json, '$.chargedCreditMicro') AS INTEGER) ELSE 0 END), 0) AS TEXT) AS cloud_charged_micro,
|
|
165
|
+
CAST(COALESCE(SUM(CASE WHEN provider = 'xopc-cloud' THEN CAST(json_extract(cloud_billing_json, '$.reservedCreditMicro') AS INTEGER) ELSE 0 END), 0) AS TEXT) AS cloud_reserved_micro,
|
|
91
166
|
COALESCE(SUM(input_tokens), 0) AS input_tokens,
|
|
92
167
|
COALESCE(SUM(output_tokens), 0) AS output_tokens,
|
|
93
168
|
COALESCE(SUM(cache_read_tokens), 0) AS cache_read_tokens,
|
|
94
169
|
COALESCE(SUM(cache_write_tokens), 0) AS cache_write_tokens,
|
|
95
170
|
COALESCE(SUM(total_tokens), 0) AS total_tokens,
|
|
96
|
-
COALESCE(SUM(estimated_cost_microusd), 0) AS known_cost_microusd`;
|
|
171
|
+
COALESCE(SUM(CASE WHEN provider <> 'xopc-cloud' AND cost_source <> 'local' THEN estimated_cost_microusd ELSE 0 END), 0) AS known_cost_microusd`;
|
|
97
172
|
/** Aggregate all retained AI usage records for the requested conversations. */
|
|
98
173
|
function summarizeAiUsageByConversations(conversationIds) {
|
|
99
174
|
const uniqueIds = [...new Set(conversationIds.filter(Boolean))];
|
|
@@ -140,6 +215,19 @@ function summarizeAiUsage(query) {
|
|
|
140
215
|
}
|
|
141
216
|
function eventFromRow(row) {
|
|
142
217
|
const pricingSnapshot = typeof row.pricing_snapshot_json === "string" ? JSON.parse(row.pricing_snapshot_json) : void 0;
|
|
218
|
+
const estimatedCostUsd = row.provider === "xopc-cloud" || row.cost_source === "local" || row.estimated_cost_microusd === null ? void 0 : usd(Number(row.estimated_cost_microusd));
|
|
219
|
+
const billing = row.provider === "xopc-cloud" ? row.cloud_billing_json ? JSON.parse(String(row.cloud_billing_json)) : {
|
|
220
|
+
source: "xopc_cloud",
|
|
221
|
+
state: "unavailable",
|
|
222
|
+
requestId: row.cloud_request_id ?? void 0,
|
|
223
|
+
reservedCreditMicro: null,
|
|
224
|
+
chargedCreditMicro: null,
|
|
225
|
+
releasedCreditMicro: null
|
|
226
|
+
} : row.cost_source === "local" ? { source: "local" } : {
|
|
227
|
+
source: "external_provider",
|
|
228
|
+
currency: "USD",
|
|
229
|
+
estimatedCostUsd
|
|
230
|
+
};
|
|
143
231
|
return {
|
|
144
232
|
id: String(row.id),
|
|
145
233
|
traceId: String(row.trace_id),
|
|
@@ -165,7 +253,8 @@ function eventFromRow(row) {
|
|
|
165
253
|
cacheWriteTokens: row.cache_write_tokens === null ? void 0 : Number(row.cache_write_tokens),
|
|
166
254
|
reasoningTokens: row.reasoning_tokens === null ? void 0 : Number(row.reasoning_tokens),
|
|
167
255
|
totalTokens: row.total_tokens === null ? void 0 : Number(row.total_tokens),
|
|
168
|
-
estimatedCostUsd
|
|
256
|
+
estimatedCostUsd,
|
|
257
|
+
billing,
|
|
169
258
|
costSource: String(row.cost_source),
|
|
170
259
|
pricingSnapshot,
|
|
171
260
|
errorSummary: row.error_summary ? String(row.error_summary) : void 0
|
|
@@ -198,4 +287,4 @@ function listAiUsageTrace(traceId) {
|
|
|
198
287
|
ORDER BY started_at ASC, id ASC`).all(traceId).map(eventFromRow);
|
|
199
288
|
}
|
|
200
289
|
//#endregion
|
|
201
|
-
export { AI_USAGE_RETENTION_MS, finishAiUsageEvent, getAiUsageEvent, getAiUsageEventView, insertAiUsageEvent, listAiUsageEvents, listAiUsageTrace, markStaleAiUsageEventsUnknown, pruneAiUsageEvents, summarizeAiUsage, summarizeAiUsageByConversations };
|
|
290
|
+
export { AI_USAGE_RETENTION_MS, finishAiUsageEvent, getAiUsageEvent, getAiUsageEventView, insertAiUsageEvent, listAiUsageEvents, listAiUsageTrace, markAiUsageCloudReceiptAttempt, markStaleAiUsageEventsUnknown, pendingAiUsageCloudReceiptIds, pruneAiUsageEvents, setAiUsageCloudReceipt, setAiUsageCloudRequest, summarizeAiUsage, summarizeAiUsageByConversations };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
ALTER TABLE ai_usage_events ADD COLUMN cloud_request_id TEXT;
|
|
2
|
+
ALTER TABLE ai_usage_events ADD COLUMN cloud_billing_json TEXT
|
|
3
|
+
CHECK(cloud_billing_json IS NULL OR json_valid(cloud_billing_json));
|
|
4
|
+
CREATE UNIQUE INDEX idx_ai_usage_cloud_request
|
|
5
|
+
ON ai_usage_events(cloud_request_id) WHERE cloud_request_id IS NOT NULL;
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 242;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration, discardOldScenes = false) {
|
|
|
57
57
|
*/
|
|
58
58
|
function applyPendingMigrations(db, options = {}) {
|
|
59
59
|
db.function("xopc_operation_id", () => currentOperationId() ?? null);
|
|
60
|
-
const targetVersion = options.targetVersion ??
|
|
60
|
+
const targetVersion = options.targetVersion ?? 242;
|
|
61
61
|
let currentVersion = readSchemaVersion(db);
|
|
62
62
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
63
63
|
if (!options.migrationsDir && currentVersion < 165) throw new DatabaseSchemaTooOldError(currentVersion, 165);
|
|
@@ -95,7 +95,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
95
95
|
}
|
|
96
96
|
/** Inspect schema version without mutating the database. */
|
|
97
97
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
98
|
-
const appVersion = options.targetVersion ??
|
|
98
|
+
const appVersion = options.targetVersion ?? 242;
|
|
99
99
|
const dbVersion = readSchemaVersion(db);
|
|
100
100
|
if (dbVersion > appVersion) return {
|
|
101
101
|
dbVersion,
|
|
@@ -137,7 +137,7 @@ var init_runner = __esmMin((() => {
|
|
|
137
137
|
init_errors();
|
|
138
138
|
log = createLogger("Sqlite:Migrations");
|
|
139
139
|
XOPC_DB_BASELINE_SCHEMA_VERSION = 165;
|
|
140
|
-
XOPC_DB_SCHEMA_VERSION =
|
|
140
|
+
XOPC_DB_SCHEMA_VERSION = 242;
|
|
141
141
|
}));
|
|
142
142
|
//#endregion
|
|
143
143
|
init_runner();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { TaskRepository, init_task_repository } from "./task-repository.js";
|
|
2
2
|
import { TaskRunRepository, init_task_run_repository } from "./task-run-repository.js";
|
|
3
|
+
import { extractAssistantText, getAssistantMessageErrorReason, stripCodeFences } from "../providers/model-response.js";
|
|
3
4
|
import { init_providers, resolveModel } from "../providers/index.js";
|
|
4
|
-
import { getPersonalAgentByConversation } from "../personal-agent/repository.js";
|
|
5
5
|
import { completeWithResolvedCredentials } from "../providers/model-call.js";
|
|
6
|
-
import {
|
|
6
|
+
import { getPersonalAgentByConversation } from "../personal-agent/repository.js";
|
|
7
7
|
import { TaskCollaborationRepository } from "./task-collaboration-repository.js";
|
|
8
8
|
//#region src/tasks/task-main-update-decision-service.ts
|
|
9
9
|
init_providers();
|
|
@@ -11,8 +11,8 @@ import { init_sqlite } from "../../storage/sqlite/index.js";
|
|
|
11
11
|
import { normalizeAgentId } from "../../agent-catalog/id.js";
|
|
12
12
|
import { init_agent_scope, listAgentEntries } from "../../agent/agent-scope.js";
|
|
13
13
|
import { AgentCatalogService } from "../../agent-catalog/service.js";
|
|
14
|
-
import { init_paths } from "../../config/paths.js";
|
|
15
14
|
import { getAgentDefaultModelRef, init_schema } from "../../config/schema.js";
|
|
15
|
+
import { init_paths } from "../../config/paths.js";
|
|
16
16
|
import { init_agent_session_key, resolveAgentIdFromConversationId } from "../../routing/agent-session-key.js";
|
|
17
17
|
import { resolveEffectiveAgentProfile } from "../../config/agent-profile.js";
|
|
18
18
|
import { effectiveWorkspacePathForSession } from "../../session/session-workspace.js";
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -2,8 +2,8 @@ import { version } from "../../package.js";
|
|
|
2
2
|
import { resolveStateDir, resolveXopcDatabasePath } from "../config/paths-state.js";
|
|
3
3
|
import { init_paths } from "../config/paths.js";
|
|
4
4
|
import { init_agent_session_key, normalizeAgentId } from "../routing/agent-session-key.js";
|
|
5
|
-
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
6
5
|
import { getAllModels, getAllProviders, getApiKey, init_providers, isProviderConfiguredSync } from "../providers/index.js";
|
|
6
|
+
import { resolveEffectiveAgentProfile } from "../config/agent-profile.js";
|
|
7
7
|
import { isTerminalWorkflowRunStatus } from "../workflows/domain/run.js";
|
|
8
8
|
import "../workflows/domain/index.js";
|
|
9
9
|
import { ProjectTrustStore, hasTrustRequiringProjectResources } from "../project-trust/trust-store.js";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { startAiUsageCall } from "./recorder.js";
|
|
2
|
+
import { getEmbeddedExecutionRunId, getEmbeddedExecutionSession } from "../agent/embedded/execution-context.js";
|
|
3
|
+
//#region src/usage/cloud-capability.ts
|
|
4
|
+
/** Cloud tools receive independent receipts even when the parent chat uses BYOK. */
|
|
5
|
+
async function trackCloudCapabilityUsage(model, operation, action) {
|
|
6
|
+
const call = startAiUsageCall({
|
|
7
|
+
provider: "xopc-cloud",
|
|
8
|
+
id: model,
|
|
9
|
+
baseUrl: void 0,
|
|
10
|
+
cost: {
|
|
11
|
+
input: 0,
|
|
12
|
+
output: 0,
|
|
13
|
+
cacheRead: 0,
|
|
14
|
+
cacheWrite: 0
|
|
15
|
+
}
|
|
16
|
+
}, {
|
|
17
|
+
operation,
|
|
18
|
+
conversationId: getEmbeddedExecutionSession(),
|
|
19
|
+
runId: getEmbeddedExecutionRunId()
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
const result = await call.run(action);
|
|
23
|
+
call.finish({ status: "succeeded" });
|
|
24
|
+
return result;
|
|
25
|
+
} catch (error) {
|
|
26
|
+
call.finish({
|
|
27
|
+
status: "failed",
|
|
28
|
+
errorSummary: error instanceof Error ? error.message : String(error)
|
|
29
|
+
});
|
|
30
|
+
throw error;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { trackCloudCapabilityUsage };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { SimpleStreamOptions } from '@earendil-works/pi-ai';
|
|
2
|
+
export declare function withUsageReceiptContext<T>(id: string, action: () => T): T;
|
|
3
|
+
export declare function captureCloudUsageResponse(response: {
|
|
4
|
+
status: number;
|
|
5
|
+
headers: Headers | Record<string, string>;
|
|
6
|
+
}): void;
|
|
7
|
+
/** Preserve existing response hooks while linking the physical Cloud request to its usage row. */
|
|
8
|
+
export declare function withCloudUsageResponse(options?: SimpleStreamOptions): SimpleStreamOptions;
|
|
9
|
+
/** Bounded, read-only synchronization. Missing authorization or receipt never becomes a zero charge. */
|
|
10
|
+
export declare function reconcileCloudUsageReceipt(id: string): Promise<void>;
|