@xopcai/xopc 0.0.361 → 0.0.363

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.
Files changed (220) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{activity-store-tpFInIoh.js → activity-store-GvR2gZ0T.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DUhFW_Go.js → agent-avatar-dicebear-DkcXyPH0.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-BNILmgey.js → agent-defaults-settings-panel-B-l5AaYN.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agent-plugin-dialog-CnWci4JJ.js → agent-plugin-dialog-BY6tPYOK.js} +1 -1
  7. package/dist/gateway/static/root/assets/{agents-CKS5LUUs.js → agents-CdSEoeje.js} +3 -3
  8. package/dist/gateway/static/root/assets/{agents-admin-api-CiAjB2iQ.js → agents-admin-api-BkXb7VEZ.js} +1 -1
  9. package/dist/gateway/static/root/assets/{app-management-settings-panel-DEig00YU.js → app-management-settings-panel-BtD53cfe.js} +1 -1
  10. package/dist/gateway/static/root/assets/{appearance-settings-CccnRRrL.js → appearance-settings-BAweWgX_.js} +1 -1
  11. package/dist/gateway/static/root/assets/{apps-page-CkT6UNZW.js → apps-page-CS6-hrIB.js} +1 -1
  12. package/dist/gateway/static/root/assets/{archive-plugin-CIlmZBe5.js → archive-plugin-CKe3qAaL.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-8kZugDcf.js → automations-page-CtE8r9Y2.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-workspace-3V54ShL0.js → automations-workspace-pnMgR4Da.js} +1 -1
  15. package/dist/gateway/static/root/assets/{binary-plugins-BuQiee_b.js → binary-plugins-J51oS7-D.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-BFFRbsKX.js → block-editor-D5hf6WcP.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automation-inputs-CWujpdCx.js → browser-automation-inputs-5B3qAdmb.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-automations-page-HVXiBKXE.js → browser-automations-page-PZDQlXH4.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-settings-page-DpxAXNvM.js → browser-settings-page-2YDV-ZWt.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capabilities-CngwB2JU.js → capabilities-BKu9BqPe.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capabilities-RMlKKfGF.js → capabilities-CT_ZW9fT.js} +1 -1
  22. package/dist/gateway/static/root/assets/{capabilities-page-BBi4ef3u.js → capabilities-page-CB-iX3Fy.js} +2 -2
  23. package/dist/gateway/static/root/assets/{capabilities-settings-panel-IxszGl-Q.js → capabilities-settings-panel-BCTuWNaW.js} +1 -1
  24. package/dist/gateway/static/root/assets/{capability-header-actions-BLOIJvIZ.js → capability-header-actions--aC5XB9E.js} +1 -1
  25. package/dist/gateway/static/root/assets/{channels-Ced5nFBc.js → channels-JnAQP1bt.js} +1 -1
  26. package/dist/gateway/static/root/assets/{chat-terminal-dock-BskUzDCS.js → chat-terminal-dock-BFZEpvzn.js} +1 -1
  27. package/dist/gateway/static/root/assets/{computer-settings-page-De-pjlvn.js → computer-settings-page-Dc9ooEM-.js} +1 -1
  28. package/dist/gateway/static/root/assets/{connector-service-page-Qc1mVfp9.js → connector-service-page-1_QB5D-t.js} +1 -1
  29. package/dist/gateway/static/root/assets/{connectors-page-CPqeY1x5.js → connectors-page-Um_Jy5zh.js} +1 -1
  30. package/dist/gateway/static/root/assets/{date-picker-7ppMIGfQ.js → date-picker-C9ZqTPui.js} +1 -1
  31. package/dist/gateway/static/root/assets/dependency-picker-DBz0Pmyr.js +1 -0
  32. package/dist/gateway/static/root/assets/{desktop-pet-GKEfqHDF.js → desktop-pet-BLtp2MmX.js} +1 -1
  33. package/dist/gateway/static/root/assets/{desktop-pet-settings-qoFZBKe9.js → desktop-pet-settings-BNGbqwec.js} +1 -1
  34. package/dist/gateway/static/root/assets/{device-pairing-wizard-D8sTDd5s.js → device-pairing-wizard-7rdo-A7d.js} +1 -1
  35. package/dist/gateway/static/root/assets/{directory-picker-path-field-BC87CZa2.js → directory-picker-path-field-BnilGgwM.js} +1 -1
  36. package/dist/gateway/static/root/assets/{extension-debug-page-VxCq29jC.js → extension-debug-page-BGyJpRv4.js} +1 -1
  37. package/dist/gateway/static/root/assets/{extension-page-DypBVBTt.js → extension-page-DsrVktRN.js} +1 -1
  38. package/dist/gateway/static/root/assets/{extension-provider-wlvxPese.js → extension-provider-F9JzOWZ3.js} +1 -1
  39. package/dist/gateway/static/root/assets/{extension-settings-page-DzzkBN9y.js → extension-settings-page-jeb0ytRK.js} +1 -1
  40. package/dist/gateway/static/root/assets/{fallback-models-s4qTRcPJ.js → fallback-models-bZcxkEDz.js} +1 -1
  41. package/dist/gateway/static/root/assets/{gateway-config-swr-ZM72jovc.js → gateway-config-swr-CoRoOG1l.js} +1 -1
  42. package/dist/gateway/static/root/assets/{gateway-realtime-B-hrykag.js → gateway-realtime-D0ygm6bc.js} +1 -1
  43. package/dist/gateway/static/root/assets/gateway-realtime-store-DBvCRclh.js +1 -0
  44. package/dist/gateway/static/root/assets/{gateway-settings--M7ZH_37.js → gateway-settings-A9SzLsGp.js} +1 -1
  45. package/dist/gateway/static/root/assets/{gateway-startup-retry-DjWuTj8B.js → gateway-startup-retry-FDS6S6qa.js} +1 -1
  46. package/dist/gateway/static/root/assets/{home-page-KFs5suD1.js → home-page-CnHzaH9K.js} +1 -1
  47. package/dist/gateway/static/root/assets/{image-generation-api-C9cwrqCr.js → image-generation-api-BPd76jW5.js} +1 -1
  48. package/dist/gateway/static/root/assets/{imports-page-BKy0ImXk.js → imports-page-CzpsV6Vz.js} +1 -1
  49. package/dist/gateway/static/root/assets/{index-C0JT9Ja4.js → index-BYNmHn-z.js} +7 -7
  50. package/dist/gateway/static/root/assets/index-CbJNcWAn.css +1 -0
  51. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CexiL-Ey.js → keyboard-shortcuts-settings-D90Dvlwo.js} +1 -1
  52. package/dist/gateway/static/root/assets/{local-app-workbench-page-CcU1OLWQ.js → local-app-workbench-page-_9IKMkV8.js} +1 -1
  53. package/dist/gateway/static/root/assets/{local-apps-page-BcLijQx4.js → local-apps-page-D6gejARs.js} +1 -1
  54. package/dist/gateway/static/root/assets/{local-session-drafts-C7QjBMNp.js → local-session-drafts-gbemPamv.js} +1 -1
  55. package/dist/gateway/static/root/assets/{locale-store-5sV3dDRG.js → locale-store-DId6-v2R.js} +1 -1
  56. package/dist/gateway/static/root/assets/{logs-page-48nrZNQe.js → logs-page--t8d-oLb.js} +1 -1
  57. package/dist/gateway/static/root/assets/{management-settings-B_gzl_Vh.js → management-settings-DVDmXzTg.js} +1 -1
  58. package/dist/gateway/static/root/assets/{markdown-view-V0f5NW7D.js → markdown-view-DQZ51j9e.js} +1 -1
  59. package/dist/gateway/static/root/assets/{media-plugins-_obxSZmT.js → media-plugins-XLewwq2q.js} +1 -1
  60. package/dist/gateway/static/root/assets/{messages-CaURu8bb.js → messages-BHvpZNe9.js} +2 -2
  61. package/dist/gateway/static/root/assets/models-hub-cache-B9SKjidc.js +1 -0
  62. package/dist/gateway/static/root/assets/{note-detail-panel-B9AeX98W.js → note-detail-panel-DuZAEfU1.js} +3 -3
  63. package/dist/gateway/static/root/assets/{notes-api-CBnMq6Nc.js → notes-api-Byt65v3r.js} +1 -1
  64. package/dist/gateway/static/root/assets/{notes-page-CKTTfxw-.js → notes-page-CgWNESGp.js} +1 -1
  65. package/dist/gateway/static/root/assets/{oauth-api-Bu2RoLF2.js → oauth-api-BYsCbyGZ.js} +1 -1
  66. package/dist/gateway/static/root/assets/{page-context-capture-button-BsxBAWD_.js → page-context-capture-button-Z72eiQZn.js} +1 -1
  67. package/dist/gateway/static/root/assets/{personal-page-Cfl1FR3i.js → personal-page-BtMatL9a.js} +1 -1
  68. package/dist/gateway/static/root/assets/{product-open-page-D1ARqS3r.js → product-open-page-w5Hdf0hQ.js} +1 -1
  69. package/dist/gateway/static/root/assets/{project-detail-page-Cro1OE8P.js → project-detail-page-CP6I3ZCV.js} +1 -1
  70. package/dist/gateway/static/root/assets/{projects-page-CdEmmBCz.js → projects-page-DYs6XrrK.js} +1 -1
  71. package/dist/gateway/static/root/assets/{registry-api-j1rNFkP2.js → registry-api-7F2WNEZC.js} +1 -1
  72. package/dist/gateway/static/root/assets/{remote-access-hub-C9_ea_4p.js → remote-access-hub-DjYoYAEw.js} +1 -1
  73. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DtmQbC72.js → runtime-tools-settings-panel-Qar_DXLv.js} +1 -1
  74. package/dist/gateway/static/root/assets/{scenes-page-DeFdMf2q.js → scenes-page-BSIcDCa-.js} +1 -1
  75. package/dist/gateway/static/root/assets/{schema-form-ByEHHW6n.js → schema-form-C_cJLGgF.js} +1 -1
  76. package/dist/gateway/static/root/assets/{send-session-input-CO_vUCb8.js → send-session-input-D1oc6BC6.js} +1 -1
  77. package/dist/gateway/static/root/assets/{session-api-CYPGi01d.js → session-api-N3N37MrR.js} +1 -1
  78. package/dist/gateway/static/root/assets/{session-manager-BdJThQQ6.js → session-manager-CMGUwtbN.js} +2 -2
  79. package/dist/gateway/static/root/assets/{sessions-page-CV0JlaXS.js → sessions-page-BBV5Z24a.js} +1 -1
  80. package/dist/gateway/static/root/assets/settings-advanced-gate-DRc9IDJf.js +1 -0
  81. package/dist/gateway/static/root/assets/{settings-page-CHKsZFAN.js → settings-page-F2vGXBw7.js} +1 -1
  82. package/dist/gateway/static/root/assets/{setup-status-panel-CC58OVOe.js → setup-status-panel-DJxbjUOg.js} +1 -1
  83. package/dist/gateway/static/root/assets/{share-link-dialog-ZOdnHkmb.js → share-link-dialog-TBBGJPfT.js} +1 -1
  84. package/dist/gateway/static/root/assets/{share-preview-page-BPDWUuH_.js → share-preview-page-DyRLPsPv.js} +1 -1
  85. package/dist/gateway/static/root/assets/{shares-api-T5gR8yqz.js → shares-api-DU0fHP2G.js} +1 -1
  86. package/dist/gateway/static/root/assets/{shares-settings-DaXvdH8c.js → shares-settings-CJa6FBpP.js} +1 -1
  87. package/dist/gateway/static/root/assets/{skill-api-CHCLMcfO.js → skill-api-C340XD9d.js} +1 -1
  88. package/dist/gateway/static/root/assets/{skill-reload-api-C-RoiUJi.js → skill-reload-api-ClyFqHk7.js} +1 -1
  89. package/dist/gateway/static/root/assets/{skills-page-a9UQQnqn.js → skills-page-C4lF94m5.js} +1 -1
  90. package/dist/gateway/static/root/assets/{system-settings-panel-Dho_dlBS.js → system-settings-panel-CmJUu3lb.js} +1 -1
  91. package/dist/gateway/static/root/assets/task-detail-page-De-Rr8W6.js +2 -0
  92. package/dist/gateway/static/root/assets/{theme-store-CEl74p7l.js → theme-store-OhcbFEUR.js} +1 -1
  93. package/dist/gateway/static/root/assets/tracing-settings-page-DoBJ0TYY.js +1 -0
  94. package/dist/gateway/static/root/assets/{tunnel-api-BDqCyf8G.js → tunnel-api-Bl4nrCuE.js} +1 -1
  95. package/dist/gateway/static/root/assets/{usage-page-DKwKfszc.js → usage-page-QZEAaa8n.js} +1 -1
  96. package/dist/gateway/static/root/assets/{use-autosave-D09eZTLp.js → use-autosave-veoM0dHn.js} +1 -1
  97. package/dist/gateway/static/root/assets/{use-composer-attachments-CkvJM8Km.js → use-composer-attachments-DB0bBGzZ.js} +1 -1
  98. package/dist/gateway/static/root/assets/{use-file-preview-expanded-J3HnG8OH.js → use-file-preview-expanded-Bope6MW6.js} +2 -2
  99. package/dist/gateway/static/root/assets/{user-model-page-BsgADrGL.js → user-model-page-Crh2oNpZ.js} +1 -1
  100. package/dist/gateway/static/root/assets/{voice-api-key-field-DH-to9Rd.js → voice-api-key-field-CwD6a3KQ.js} +1 -1
  101. package/dist/gateway/static/root/assets/{voice-config-api-CmCfVy3H.js → voice-config-api-Daexehmc.js} +1 -1
  102. package/dist/gateway/static/root/assets/{work-discovery-overlay-x1vZDBhu.js → work-discovery-overlay-9jnjEAaz.js} +1 -1
  103. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-DGatvmK1.js → workflow-run-setup-panel-BAcPxdcT.js} +1 -1
  104. package/dist/gateway/static/root/assets/{workflows-page-DgNy6mBQ.js → workflows-page-D8Zm-ooa.js} +1 -1
  105. package/dist/gateway/static/root/assets/{workspace-api-DzPw92Kx.js → workspace-api-Cs4sjV2A.js} +2 -2
  106. package/dist/gateway/static/root/connector-icons/README.md +5 -2
  107. package/dist/gateway/static/root/connector-icons/SOURCES.md +15 -1
  108. package/dist/gateway/static/root/connector-icons/amap.ico +0 -0
  109. package/dist/gateway/static/root/connector-icons/antv-chart.png +0 -0
  110. package/dist/gateway/static/root/connector-icons/bailian.png +0 -0
  111. package/dist/gateway/static/root/connector-icons/dida365.png +0 -0
  112. package/dist/gateway/static/root/connector-icons/flomo.png +0 -0
  113. package/dist/gateway/static/root/connector-icons/gmail.svg +1 -3
  114. package/dist/gateway/static/root/connector-icons/jira.svg +3 -14
  115. package/dist/gateway/static/root/connector-icons/railway-12306.jpg +0 -0
  116. package/dist/gateway/static/root/connector-icons/railway-query.svg +1 -0
  117. package/dist/gateway/static/root/connector-icons/tencent-docs.ico +0 -0
  118. package/dist/gateway/static/root/connector-icons/yuque.png +0 -0
  119. package/dist/gateway/static/root/index.html +28 -28
  120. package/dist/package.js +1 -1
  121. package/dist/packages/gateway-contract/src/task-result-delivery.js +2 -2
  122. package/dist/src/agent/agent-manager.js +10 -6
  123. package/dist/src/agent/embedded/model-runtime.js +1 -1
  124. package/dist/src/agent/embedded/run-for-session.js +28 -3
  125. package/dist/src/agent/embedded/run-turn.js +18 -3
  126. package/dist/src/agent/image/tool-model-config.js +1 -1
  127. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  128. package/dist/src/agent/service.js +5 -3
  129. package/dist/src/agent/skills/hub-lock.js +1 -1
  130. package/dist/src/agent/tasks/task-judge-service.js +1 -1
  131. package/dist/src/agent-catalog/migrations/legacy-config-cutover.js +1 -1
  132. package/dist/src/agent-catalog/repository.js +1 -1
  133. package/dist/src/auth/credentials.js +2 -2
  134. package/dist/src/auth/oauth-provider-lock.js +1 -1
  135. package/dist/src/auth/profiles/store.js +1 -1
  136. package/dist/src/auth/sync-provider-auth.js +1 -1
  137. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  138. package/dist/src/chat-commands/agent-edit.js +1 -1
  139. package/dist/src/chat-commands/builtins/config.js +1 -1
  140. package/dist/src/cli/commands/agent.js +1 -1
  141. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  142. package/dist/src/cli/commands/doctor/checks/image-providers.js +1 -1
  143. package/dist/src/cli/commands/doctor/checks/provider-auth.js +3 -3
  144. package/dist/src/cli/commands/models.js +1 -1
  145. package/dist/src/cli/commands/onboard/model.js +3 -3
  146. package/dist/src/config/agent-profile.js +1 -1
  147. package/dist/src/config/index.js +4 -4
  148. package/dist/src/config/loader.js +2 -2
  149. package/dist/src/config/models-json.js +1 -1
  150. package/dist/src/config/reload.d.ts +1 -0
  151. package/dist/src/config/reload.js +4 -0
  152. package/dist/src/config/rules.js +5 -0
  153. package/dist/src/config/schema.d.ts +23 -0
  154. package/dist/src/config/schema.js +6 -3
  155. package/dist/src/connectors/china-catalog.js +572 -0
  156. package/dist/src/connectors/cli/authorization.js +3 -2
  157. package/dist/src/connectors/cli/installer.js +3 -1
  158. package/dist/src/extensions/activation-context.js +1 -1
  159. package/dist/src/extensions/lockfile.js +1 -1
  160. package/dist/src/gateway/file-path-classifier.js +1 -1
  161. package/dist/src/gateway/hono/lib/config-payload.js +2 -2
  162. package/dist/src/gateway/hono/routes/agents.js +1 -1
  163. package/dist/src/gateway/hono/routes/config-patch/misc.js +2 -2
  164. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  165. package/dist/src/gateway/hono/routes/models.js +2 -2
  166. package/dist/src/gateway/hono/routes/observability.d.ts +3 -0
  167. package/dist/src/gateway/hono/routes/observability.js +106 -0
  168. package/dist/src/gateway/image-generation-setup.js +1 -1
  169. package/dist/src/gateway/lock.js +1 -1
  170. package/dist/src/gateway/security/gateway-scopes.js +1 -0
  171. package/dist/src/gateway/service/config-coordinator.d.ts +0 -25
  172. package/dist/src/gateway/service/config-coordinator.js +31 -0
  173. package/dist/src/gateway/service.js +5 -3
  174. package/dist/src/gateway/side-chat/manager.js +3 -2
  175. package/dist/src/observability/config.d.ts +40 -0
  176. package/dist/src/observability/config.js +31 -0
  177. package/dist/src/observability/langfuse.d.ts +31 -0
  178. package/dist/src/observability/langfuse.js +180 -0
  179. package/dist/src/observability/runtime.d.ts +57 -0
  180. package/dist/src/observability/runtime.js +404 -0
  181. package/dist/src/observability/sanitize.d.ts +3 -0
  182. package/dist/src/observability/sanitize.js +74 -0
  183. package/dist/src/observability/store.d.ts +20 -0
  184. package/dist/src/observability/store.js +128 -0
  185. package/dist/src/observability/storeWorker.d.ts +2 -0
  186. package/dist/src/observability/storeWorker.js +155 -0
  187. package/dist/src/observability/types.d.ts +21 -0
  188. package/dist/src/observability/types.js +1 -0
  189. package/dist/src/platform/index.js +1 -1
  190. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  191. package/dist/src/providers/index.js +3 -3
  192. package/dist/src/providers/model-call.js +19 -5
  193. package/dist/src/providers/model-catalog-persistence.js +1 -1
  194. package/dist/src/providers/model-registry.js +1 -1
  195. package/dist/src/providers/provider-disconnect-core.js +1 -1
  196. package/dist/src/providers/xopc-cloud-catalog-coordinator.js +1 -1
  197. package/dist/src/storage/sqlite/ai-usage-repository.d.ts +6 -0
  198. package/dist/src/storage/sqlite/ai-usage-repository.js +4 -2
  199. package/dist/src/storage/sqlite/migrations/233_observability_usage_links.sql +3 -0
  200. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  201. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  202. package/dist/src/storage/sqlite/schema.js +1 -1
  203. package/dist/src/tasks/task-result-delivery-repository.js +4 -5
  204. package/dist/src/tui/backends/embedded-backend.js +2 -2
  205. package/dist/src/tui/tui-commands.js +1 -1
  206. package/dist/src/tui/tui-startup-resources.js +1 -1
  207. package/dist/src/tui/tui.js +1 -1
  208. package/dist/src/usage/recorder.d.ts +4 -2
  209. package/dist/src/usage/recorder.js +54 -26
  210. package/dist/src/usage/types.d.ts +3 -0
  211. package/dist/src/utils/logger/context.d.ts +1 -1
  212. package/dist/src/utils/logger/context.js +4 -1
  213. package/dist/src/utils/logger/types.d.ts +3 -0
  214. package/package.json +5 -2
  215. package/dist/gateway/static/root/assets/dependency-picker-DfYC22si.js +0 -1
  216. package/dist/gateway/static/root/assets/gateway-realtime-store-B6B1fw_K.js +0 -1
  217. package/dist/gateway/static/root/assets/index-B7AHDHSO.css +0 -1
  218. package/dist/gateway/static/root/assets/models-hub-cache-Cs3E5pEA.js +0 -1
  219. package/dist/gateway/static/root/assets/settings-advanced-gate-D9sW0hKa.js +0 -1
  220. package/dist/gateway/static/root/assets/task-detail-page-B5JyH4z7.js +0 -1
@@ -0,0 +1,404 @@
1
+ import { init_context, runWithLogContext } from "../utils/logger/context.js";
2
+ import { createLogger } from "../utils/logger/index.js";
3
+ import { init_logger } from "../utils/logger.js";
4
+ import { CredentialResolver, init_credentials } from "../auth/credentials.js";
5
+ import { TracingConfigSchema, defaultTracingConfig, init_config } from "./config.js";
6
+ import { LangfuseTarget } from "./langfuse.js";
7
+ import { boundedJson, redactString } from "./sanitize.js";
8
+ import { LocalTraceStore } from "./store.js";
9
+ import { AsyncLocalStorage } from "node:async_hooks";
10
+ import { SpanStatusCode, context, createContextKey, trace } from "@opentelemetry/api";
11
+ import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
12
+ import { BasicTracerProvider } from "@opentelemetry/sdk-trace-base";
13
+ //#region src/observability/runtime.ts
14
+ init_credentials();
15
+ init_logger();
16
+ init_context();
17
+ init_config();
18
+ const log = createLogger("Observability");
19
+ let lastStorageWarning = 0;
20
+ function storageWarning(message) {
21
+ if (Date.now() - lastStorageWarning < 6e4) return;
22
+ lastStorageWarning = Date.now();
23
+ log.warn({
24
+ errorMessage: message,
25
+ phase: "local_trace_write"
26
+ }, `Local trace recording unavailable: ${message}`);
27
+ }
28
+ const localEpochKey = createContextKey("xopc.trace.localEpoch");
29
+ const scopes = new AsyncLocalStorage();
30
+ let config = defaultTracingConfig();
31
+ let store;
32
+ let target;
33
+ let provider;
34
+ let revision = 0;
35
+ let active = 0;
36
+ let dropped = 0;
37
+ const pendingLocal = /* @__PURE__ */ new Set();
38
+ let pendingLocalBytes = 0;
39
+ let remoteState = "disabled";
40
+ let knownSecrets = [];
41
+ let configureVersion = 0;
42
+ let targetSignature = "";
43
+ const targets = /* @__PURE__ */ new WeakMap();
44
+ const localEpochs = /* @__PURE__ */ new WeakMap();
45
+ const captured = /* @__PURE__ */ new WeakMap();
46
+ function secretSafe(value) {
47
+ let result = redactString(value);
48
+ for (const secret of knownSecrets) if (secret.length >= 4) result = result.split(secret).join("[REDACTED]");
49
+ return result;
50
+ }
51
+ function record(span, ended = true) {
52
+ const attrs = {};
53
+ for (const [key, value] of Object.entries(span.attributes)) if ([
54
+ "string",
55
+ "number",
56
+ "boolean"
57
+ ].includes(typeof value)) attrs[key] = typeof value === "string" ? secretSafe(value) : value;
58
+ return {
59
+ traceId: span.spanContext().traceId,
60
+ spanId: span.spanContext().spanId,
61
+ parentSpanId: span.parentSpanContext?.spanId,
62
+ name: secretSafe(span.name),
63
+ type: String(attrs["langfuse.observation.type"] ?? "span"),
64
+ startedAt: Math.floor(span.startTime[0] * 1e3 + span.startTime[1] / 1e6),
65
+ ...ended ? { endedAt: Math.floor(span.endTime[0] * 1e3 + span.endTime[1] / 1e6) } : {},
66
+ status: ended ? String(attrs["xopc.status"] ?? (span.status.code === SpanStatusCode.ERROR ? "error" : "success")) : "running",
67
+ attributes: attrs
68
+ };
69
+ }
70
+ var TraceProcessor = class {
71
+ onStart(span, parentContext) {
72
+ const scope = scopes.getStore();
73
+ if (!(scope?.config ?? config).enabled) return;
74
+ captured.set(span, true);
75
+ if (scope?.target ?? target) targets.set(span, scope?.target ?? target);
76
+ if (!span.parentSpanContext || span.attributes["xopc.localRoot"] === true) {
77
+ const epoch = localStore().begin(record(span, false)).catch(() => {
78
+ storageWarning("Trace root could not be persisted");
79
+ return -1;
80
+ });
81
+ localEpochs.set(span, epoch);
82
+ if (scope) scope.epoch = epoch;
83
+ } else {
84
+ const epoch = scope?.epoch ?? parentContext.getValue(localEpochKey);
85
+ if (epoch) localEpochs.set(span, epoch);
86
+ }
87
+ }
88
+ onEnd(span) {
89
+ if (!captured.has(span)) return;
90
+ try {
91
+ const value = record(span);
92
+ const bytes = Buffer.byteLength(JSON.stringify(value));
93
+ if (pendingLocal.size < 2e3 && pendingLocalBytes + bytes <= 8 * 1048576) {
94
+ const destination = localStore();
95
+ pendingLocalBytes += bytes;
96
+ const pending = (localEpochs.get(span) ?? Promise.resolve(void 0)).then(async (epoch) => {
97
+ await destination.write(value, epoch);
98
+ if (destination.lastError) storageWarning(destination.lastError);
99
+ }).catch(() => {
100
+ dropped++;
101
+ }).finally(() => {
102
+ pendingLocal.delete(pending);
103
+ pendingLocalBytes -= bytes;
104
+ });
105
+ pendingLocal.add(pending);
106
+ } else dropped++;
107
+ targets.get(span)?.enqueue(value);
108
+ } catch {
109
+ dropped++;
110
+ }
111
+ }
112
+ async forceFlush() {
113
+ await Promise.allSettled([...pendingLocal]);
114
+ await Promise.allSettled([store?.flush(), target?.flush()]);
115
+ }
116
+ async shutdown() {
117
+ await this.forceFlush();
118
+ target?.close();
119
+ await store?.close();
120
+ }
121
+ };
122
+ function tracer() {
123
+ if (!provider) {
124
+ context.setGlobalContextManager(new AsyncLocalStorageContextManager().enable());
125
+ process.once("beforeExit", () => {
126
+ flushTracing();
127
+ });
128
+ provider = new BasicTracerProvider({
129
+ spanProcessors: [new TraceProcessor()],
130
+ spanLimits: {
131
+ attributeCountLimit: 64,
132
+ attributeValueLengthLimit: 65536,
133
+ eventCountLimit: 0
134
+ }
135
+ });
136
+ }
137
+ return provider.getTracer("xopc.observability");
138
+ }
139
+ function localStore() {
140
+ return store ??= new LocalTraceStore(config);
141
+ }
142
+ function tracingConfig() {
143
+ return structuredClone(config);
144
+ }
145
+ async function configureTracing(value) {
146
+ const version = ++configureVersion;
147
+ const next = TracingConfigSchema.parse(value ?? {});
148
+ config = next;
149
+ revision++;
150
+ if (store) await store.request("configure", config).catch(() => {});
151
+ remoteState = !next.enabled || !next.langfuse.enabled ? "disabled" : "missing_credentials";
152
+ if (remoteState === "disabled") {
153
+ target?.close();
154
+ target = void 0;
155
+ targetSignature = "";
156
+ return;
157
+ }
158
+ try {
159
+ const secretKey = process.env.LANGFUSE_SECRET_KEY || await new CredentialResolver().revealGatewayStoredApiKey("langfuse");
160
+ const publicKey = process.env.LANGFUSE_PUBLIC_KEY || await new CredentialResolver().revealGatewayStoredApiKey("langfuse-public");
161
+ if (version !== configureVersion) return;
162
+ if (secretKey && publicKey) {
163
+ const baseUrl = process.env.LANGFUSE_BASE_URL || next.langfuse.baseUrl;
164
+ const signature = JSON.stringify([
165
+ baseUrl,
166
+ publicKey,
167
+ secretKey
168
+ ]);
169
+ knownSecrets = [...new Set([
170
+ ...knownSecrets,
171
+ secretKey,
172
+ publicKey
173
+ ])].slice(-64);
174
+ if (!target || signature !== targetSignature) {
175
+ target?.close();
176
+ target = new LangfuseTarget(baseUrl, publicKey, secretKey);
177
+ targetSignature = signature;
178
+ }
179
+ remoteState = "ready";
180
+ } else {
181
+ target?.close();
182
+ target = void 0;
183
+ targetSignature = "";
184
+ }
185
+ } catch {
186
+ remoteState = "missing_credentials";
187
+ target?.close();
188
+ target = void 0;
189
+ targetSignature = "";
190
+ }
191
+ }
192
+ async function tracingStatus() {
193
+ return {
194
+ local: {
195
+ ...await localStore().request("status").catch(() => ({ unavailable: true })),
196
+ pending: pendingLocal.size,
197
+ pendingBytes: pendingLocalBytes,
198
+ queueDropped: localStore().dropped,
199
+ lastError: localStore().lastError
200
+ },
201
+ langfuse: target?.status() ?? {
202
+ state: remoteState,
203
+ pending: 0,
204
+ dropped: 0
205
+ },
206
+ active,
207
+ dropped
208
+ };
209
+ }
210
+ function traceIds() {
211
+ const current = trace.getSpan(context.active())?.spanContext();
212
+ return current ? {
213
+ traceId: current.traceId,
214
+ spanId: current.spanId
215
+ } : {};
216
+ }
217
+ function attrs(identity, type) {
218
+ const result = {
219
+ ...type === "agent" ? { "xopc.localRoot": true } : {},
220
+ "langfuse.observation.type": type,
221
+ "xopc.configRevision": revision
222
+ };
223
+ for (const [key, value] of Object.entries(identity)) if (value) {
224
+ result[`xopc.${key}`] = value;
225
+ result[`langfuse.trace.metadata.${key}`] = value;
226
+ }
227
+ if (scopes.getStore()?.name) result["langfuse.trace.name"] = scopes.getStore().name;
228
+ if (identity.conversationId) result["langfuse.session.id"] = identity.conversationId;
229
+ return result;
230
+ }
231
+ function startObservation(name, type, identity = {}) {
232
+ const scope = scopes.getStore();
233
+ if (!(scope?.config ?? config).enabled || scope && ++scope.count > 1e3) {
234
+ if (scope?.count > 1e3) scope.root?.setAttribute("xopc.partialReason", "span_quota");
235
+ dropped++;
236
+ return {
237
+ run: (fn) => fn(),
238
+ finish() {},
239
+ input() {},
240
+ update() {}
241
+ };
242
+ }
243
+ const standalone = !scope;
244
+ if (standalone && active >= 256) {
245
+ dropped++;
246
+ return {
247
+ run: (fn) => fn(),
248
+ finish() {},
249
+ input() {},
250
+ update() {}
251
+ };
252
+ }
253
+ if (standalone) active++;
254
+ const span = tracer().startSpan(name.slice(0, 120), { attributes: attrs({
255
+ ...scope?.identity,
256
+ ...identity
257
+ }, type) });
258
+ const spanContext = trace.setSpan(context.active(), span).setValue(localEpochKey, localEpochs.get(span) ?? context.active().getValue(localEpochKey));
259
+ let ended = false;
260
+ const put = (key, value) => {
261
+ const policy = scope?.config ?? config;
262
+ if (policy.capture === "metadata") return;
263
+ const json = secretSafe(boundedJson(value, policy.capture === "detailed" && (policy.detailedUntil ?? 0) > Date.now() ? 65536 : 8192));
264
+ if (scope && (scope.bytes += Buffer.byteLength(json)) > policy.local.maxTraceKiB * 1024) {
265
+ span.setAttribute("xopc.partialReason", "capture_quota");
266
+ return;
267
+ }
268
+ span.setAttribute(key, json);
269
+ };
270
+ return {
271
+ span,
272
+ run: (fn) => context.with(spanContext, () => runWithLogContext({
273
+ ...identity,
274
+ ...traceIds()
275
+ }, fn)),
276
+ input: (value) => put("langfuse.observation.input", value),
277
+ update: (values) => {
278
+ for (const [key, value] of Object.entries(values)) if (value !== void 0) span.setAttribute(key, typeof value === "string" ? secretSafe(value.slice(0, 1024)) : value);
279
+ },
280
+ finish(status = "success", output) {
281
+ if (ended) return;
282
+ ended = true;
283
+ if (standalone) active--;
284
+ if (output !== void 0) put("langfuse.observation.output", output);
285
+ span.setAttribute("xopc.status", status);
286
+ span.setStatus({ code: status === "error" ? SpanStatusCode.ERROR : SpanStatusCode.OK });
287
+ span.end();
288
+ }
289
+ };
290
+ }
291
+ async function traceRun(name, identity, fn, input) {
292
+ if (scopes.getStore() || !config.enabled) return fn();
293
+ if (active >= 256) {
294
+ dropped++;
295
+ return scopes.run({
296
+ config: {
297
+ ...config,
298
+ enabled: false
299
+ },
300
+ identity,
301
+ name,
302
+ count: 0,
303
+ bytes: 0
304
+ }, fn);
305
+ }
306
+ active++;
307
+ const scope = {
308
+ config: structuredClone(config),
309
+ target,
310
+ identity,
311
+ name,
312
+ count: 0,
313
+ bytes: 0
314
+ };
315
+ try {
316
+ return await scopes.run(scope, async () => {
317
+ const observation = startObservation(name, "agent", identity);
318
+ scope.root = observation.span;
319
+ observation.input(input);
320
+ try {
321
+ const result = await observation.run(fn);
322
+ observation.finish(result.stopReason ? "suspended" : result.ok === false ? result.errorMessage === "aborted" ? "cancelled" : "error" : "success", result.lastAssistantText ?? result.errorMessage);
323
+ return result;
324
+ } catch (error) {
325
+ observation.finish("error", error instanceof Error ? error.message : String(error));
326
+ throw error;
327
+ }
328
+ });
329
+ } finally {
330
+ active--;
331
+ }
332
+ }
333
+ const tracedExecutions = /* @__PURE__ */ new WeakSet();
334
+ function traceTools(tools) {
335
+ return tools.map((tool) => {
336
+ if (tracedExecutions.has(tool.execute)) return tool;
337
+ const execute = (...args) => {
338
+ const observation = startObservation(`tool.${tool.name}`, "tool");
339
+ observation.update({ "xopc.toolCallId": String(args[0]) });
340
+ observation.input(args[1]);
341
+ return observation.run(async () => {
342
+ try {
343
+ const result = await tool.execute(...args);
344
+ observation.finish(result?.isError || result?.details?.isError ? "error" : "success", result);
345
+ return result;
346
+ } catch (error) {
347
+ observation.finish(args[2]?.aborted ? "cancelled" : "error", error instanceof Error ? error.message : String(error));
348
+ throw error;
349
+ }
350
+ });
351
+ };
352
+ tracedExecutions.add(execute);
353
+ return {
354
+ ...tool,
355
+ execute
356
+ };
357
+ });
358
+ }
359
+ async function flushTracing() {
360
+ const timer = new Promise((resolve) => {
361
+ setTimeout(resolve, 3e3).unref();
362
+ });
363
+ await Promise.race([(async () => {
364
+ await Promise.allSettled([...pendingLocal]);
365
+ await Promise.allSettled([store?.flush(), target?.flush()]);
366
+ })(), timer]);
367
+ }
368
+ async function testLangfuse() {
369
+ if (!target) return false;
370
+ const result = await traceRun("diagnostic.langfuse", {}, async () => ({ ok: true }));
371
+ await target.flush();
372
+ return result.ok && !target.status().lastError;
373
+ }
374
+ async function closeTracing() {
375
+ await flushTracing();
376
+ target?.close();
377
+ target = void 0;
378
+ targetSignature = "";
379
+ await store?.close();
380
+ store = void 0;
381
+ }
382
+ async function traceOperation(name, fn, attributes = {}) {
383
+ const observation = startObservation(name, "span");
384
+ observation.update(attributes);
385
+ try {
386
+ const result = await observation.run(fn);
387
+ observation.finish();
388
+ return result;
389
+ } catch (error) {
390
+ observation.finish("error", error instanceof Error ? error.message : String(error));
391
+ throw error;
392
+ }
393
+ }
394
+ function setTraceIdentity(identity) {
395
+ const scope = scopes.getStore();
396
+ if (!scope) return;
397
+ scope.identity = {
398
+ ...scope.identity,
399
+ ...identity
400
+ };
401
+ scope.root?.setAttributes(attrs(scope.identity, "agent"));
402
+ }
403
+ //#endregion
404
+ export { closeTracing, configureTracing, flushTracing, localStore, setTraceIdentity, startObservation, testLangfuse, traceIds, traceOperation, traceRun, traceTools, tracingConfig, tracingStatus };
@@ -0,0 +1,3 @@
1
+ export declare function redactString(value: string): string;
2
+ /** Bounds traversal before serializing; never materializes an entire tool/file payload. */
3
+ export declare function boundedJson(value: unknown, maxBytes?: number): string;
@@ -0,0 +1,74 @@
1
+ //#region src/observability/sanitize.ts
2
+ const SECRET_KEY = /authorization|api.?key|password|secret|access.?token|refresh.?token|bot.?token|cookie/i;
3
+ const OMIT_KEY = /^(data|base64|headers|image_url|audio|video)$/i;
4
+ function redactString(value) {
5
+ return value.replace(/Bearer\s+[^\s"']+/gi, "Bearer [REDACTED]").replace(/\b(?:sk-|pk-lf-|sk-lf-)[A-Za-z0-9_-]+/g, "[REDACTED]").replace(/((?:api[_-]?key|token|secret|password)\s*[=:]\s*)[^\s,;"']+/gi, "$1[REDACTED]").replace(/data:[^\s"']+;base64,[^\s"']+/gi, "[MEDIA OMITTED]");
6
+ }
7
+ /** Bounds traversal before serializing; never materializes an entire tool/file payload. */
8
+ function boundedJson(value, maxBytes = 8192) {
9
+ const seen = /* @__PURE__ */ new WeakSet();
10
+ let budget = Math.max(64, maxBytes - 256);
11
+ let truncated = false;
12
+ const walk = (v, depth) => {
13
+ if (budget < 32 || depth > 5) {
14
+ truncated = true;
15
+ return "[TRUNCATED]";
16
+ }
17
+ if (v === null || typeof v === "number" || typeof v === "boolean") {
18
+ budget -= 16;
19
+ return v;
20
+ }
21
+ if (typeof v === "string") {
22
+ const slice = v.slice(0, Math.min(budget, 4096));
23
+ const clean = redactString(slice);
24
+ const buf = Buffer.from(clean);
25
+ const size = Math.min(budget, 4096);
26
+ budget -= Math.min(buf.length, size);
27
+ if (slice.length < v.length || buf.length > size) truncated = true;
28
+ return buf.subarray(0, size).toString("utf8");
29
+ }
30
+ if (typeof v !== "object") return void 0;
31
+ if (seen.has(v)) return "[CIRCULAR]";
32
+ seen.add(v);
33
+ if (Array.isArray(v)) {
34
+ const values = [];
35
+ for (let i = 0; i < Math.min(v.length, 40) && budget > 32; i++) values.push(walk(v[i], depth + 1));
36
+ if (values.length < v.length) truncated = true;
37
+ return values;
38
+ }
39
+ const result = {};
40
+ let count = 0;
41
+ for (const key in v) {
42
+ if (!Object.hasOwn(v, key)) continue;
43
+ if (++count > 40 || budget < 32) {
44
+ truncated = true;
45
+ break;
46
+ }
47
+ const safeKey = key.slice(0, 80);
48
+ budget -= Buffer.byteLength(safeKey) + 8;
49
+ try {
50
+ result[safeKey] = SECRET_KEY.test(key) ? "[REDACTED]" : OMIT_KEY.test(key) ? "[OMITTED]" : walk(v[key], depth + 1);
51
+ } catch {
52
+ result[safeKey] = "[UNAVAILABLE]";
53
+ }
54
+ }
55
+ return result;
56
+ };
57
+ let data;
58
+ try {
59
+ data = walk(value, 0);
60
+ } catch {
61
+ data = "[UNAVAILABLE]";
62
+ }
63
+ const text = JSON.stringify({
64
+ preview: data,
65
+ truncated
66
+ });
67
+ if (Buffer.byteLength(text) <= maxBytes) return text;
68
+ return JSON.stringify({
69
+ preview: Buffer.from(redactString(text)).subarray(0, Math.floor(maxBytes / 8)).toString("utf8"),
70
+ truncated: true
71
+ });
72
+ }
73
+ //#endregion
74
+ export { boundedJson, redactString };
@@ -0,0 +1,20 @@
1
+ import type { TracingConfig } from './config.js';
2
+ import type { TraceRecord } from './types.js';
3
+ export declare class LocalTraceStore {
4
+ private worker?;
5
+ private sequence;
6
+ private requests;
7
+ private pendingBytes;
8
+ private epoch;
9
+ private epochReady;
10
+ dropped: number;
11
+ lastError?: string;
12
+ constructor(config: TracingConfig, file?: string);
13
+ private fail;
14
+ request(op: string, data?: unknown): Promise<any>;
15
+ begin(record: TraceRecord): Promise<number>;
16
+ write(record: TraceRecord, epoch?: number): Promise<void>;
17
+ clear(): Promise<void>;
18
+ flush(): Promise<void>;
19
+ close(): Promise<void>;
20
+ }
@@ -0,0 +1,128 @@
1
+ import { init_paths_state, resolveStateDir } from "../config/paths-state.js";
2
+ import { redactString } from "./sanitize.js";
3
+ import { traceStoreWorkerSource } from "./storeWorker.js";
4
+ import { join } from "node:path";
5
+ import { randomUUID } from "node:crypto";
6
+ import { Worker } from "node:worker_threads";
7
+ //#region src/observability/store.ts
8
+ init_paths_state();
9
+ var LocalTraceStore = class {
10
+ worker;
11
+ sequence = 0;
12
+ requests = /* @__PURE__ */ new Map();
13
+ pendingBytes = 0;
14
+ epoch = 0;
15
+ epochReady;
16
+ dropped = 0;
17
+ lastError;
18
+ constructor(config, file = join(resolveStateDir(), "traces", "traces.db")) {
19
+ try {
20
+ this.worker = new Worker(traceStoreWorkerSource, {
21
+ eval: true,
22
+ execArgv: process.execArgv.filter((arg, index, args) => !arg.startsWith("--input-type") && args[index - 1] !== "--input-type"),
23
+ workerData: {
24
+ path: file,
25
+ config,
26
+ owner: randomUUID()
27
+ }
28
+ });
29
+ this.worker.on("message", ({ id, value, error }) => {
30
+ const request = this.requests.get(id);
31
+ if (!request) return;
32
+ clearTimeout(request.timer);
33
+ this.requests.delete(id);
34
+ this.pendingBytes -= request.bytes;
35
+ if (error) {
36
+ this.lastError = error;
37
+ request.reject(new Error(error));
38
+ } else request.resolve(value);
39
+ if (!this.requests.size) this.worker?.unref();
40
+ });
41
+ this.worker.on("error", (error) => this.fail(`Trace worker unavailable: ${redactString(error instanceof Error ? error.message : "Worker startup failed").slice(0, 200)}`));
42
+ this.worker.on("exit", () => {
43
+ if (this.worker) this.fail("Trace worker stopped");
44
+ });
45
+ this.worker.unref();
46
+ this.epochReady = this.request("status").then((s) => {
47
+ this.epoch = s.epoch;
48
+ }).catch(() => {});
49
+ } catch {
50
+ this.lastError = "Trace worker unavailable";
51
+ this.epochReady = Promise.resolve();
52
+ }
53
+ }
54
+ fail(message) {
55
+ this.lastError = message;
56
+ for (const r of this.requests.values()) {
57
+ clearTimeout(r.timer);
58
+ r.reject(new Error(message));
59
+ }
60
+ this.requests.clear();
61
+ this.pendingBytes = 0;
62
+ this.worker = void 0;
63
+ }
64
+ async request(op, data) {
65
+ if (!this.worker) throw new Error(this.lastError ?? "Trace storage unavailable");
66
+ const bytes = Buffer.byteLength(JSON.stringify(data ?? null));
67
+ if (this.requests.size >= 2e3 || this.pendingBytes + bytes > 8 * 1048576) {
68
+ this.dropped++;
69
+ throw new Error("Trace queue full");
70
+ }
71
+ const id = ++this.sequence;
72
+ this.pendingBytes += bytes;
73
+ this.worker.ref();
74
+ return new Promise((resolve, reject) => {
75
+ const timer = setTimeout(() => {
76
+ this.requests.delete(id);
77
+ this.pendingBytes -= bytes;
78
+ this.dropped++;
79
+ reject(/* @__PURE__ */ new Error("Trace storage timeout"));
80
+ this.worker?.terminate();
81
+ }, 5e3);
82
+ this.requests.set(id, {
83
+ resolve,
84
+ reject,
85
+ timer,
86
+ bytes
87
+ });
88
+ this.worker.postMessage({
89
+ id,
90
+ op,
91
+ data
92
+ });
93
+ });
94
+ }
95
+ async begin(record) {
96
+ await this.epochReady;
97
+ return this.request("put", {
98
+ records: [record],
99
+ epoch: null
100
+ });
101
+ }
102
+ async write(record, epoch) {
103
+ await this.epochReady;
104
+ try {
105
+ await this.request("put", {
106
+ records: [record],
107
+ epoch: epoch ?? this.epoch
108
+ });
109
+ this.lastError = void 0;
110
+ } catch (error) {
111
+ this.dropped++;
112
+ this.lastError = error instanceof Error ? error.message : "Trace write failed";
113
+ }
114
+ }
115
+ async clear() {
116
+ this.epoch = await this.request("clear");
117
+ }
118
+ async flush() {
119
+ await this.request("status");
120
+ }
121
+ async close() {
122
+ const worker = this.worker;
123
+ this.fail("Trace store closed");
124
+ await worker?.terminate();
125
+ }
126
+ };
127
+ //#endregion
128
+ export { LocalTraceStore };
@@ -0,0 +1,2 @@
1
+ /** Self-contained worker source works in tsx, published unbundled Node, and Electron builds. */
2
+ export declare const traceStoreWorkerSource: string;