@xopcai/xopc 0.0.254 → 0.0.256

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 (198) 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-Ci5Rxmi_.js → activity-store-DYb6xFC3.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-D82jpmFL.js → agent-avatar-dicebear-BZJZvmYw.js} +1 -1
  5. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-Bq7GNF1L.js +1 -0
  6. package/dist/gateway/static/root/assets/{agents-p3kWyz1T.js → agents-1vtaw07m.js} +1 -1
  7. package/dist/gateway/static/root/assets/{api-CXIzQJ2Z.js → api-NADZ8X8B.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-mhxcQpkQ.js → app-management-settings-panel-DG64SQsx.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-BIMwACUF.js → appearance-settings-BRWQdIIy.js} +1 -1
  10. package/dist/gateway/static/root/assets/apps-page-D3ziBisx.js +1 -0
  11. package/dist/gateway/static/root/assets/{archive-plugin-C63Xp_sU.js → archive-plugin-D3FQ9VzV.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-D12KYOav.js → attachment-load-Cid3dBaW.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-DXj0o5CY.js → automations-page-BUTNaZtj.js} +1 -1
  14. package/dist/gateway/static/root/assets/automations-workspace-D4NJSE8l.js +6 -0
  15. package/dist/gateway/static/root/assets/{binary-plugins-Bcv8hun6.js → binary-plugins-BSYMCuaB.js} +1 -1
  16. package/dist/gateway/static/root/assets/block-editor-qDlC3t7b.js +159 -0
  17. package/dist/gateway/static/root/assets/{browser-automation-inputs-CAclu735.js → browser-automation-inputs-rA2QROKe.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-automations-page-BITfKX8L.js → browser-automations-page-Du1KVE01.js} +2 -2
  19. package/dist/gateway/static/root/assets/browser-settings-page-WZ0Jt5Hp.js +8 -0
  20. package/dist/gateway/static/root/assets/capabilities-settings-panel-D1AYoRx4.js +7 -0
  21. package/dist/gateway/static/root/assets/channels-settings-CZnlYu2L.js +1 -0
  22. package/dist/gateway/static/root/assets/{channels-status-swr-Cmbx0E8O.js → channels-status-swr-B2aMPOSM.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-CNBgHN9U.js → chat-terminal-dock-CY-I_bCe.js} +2 -2
  24. package/dist/gateway/static/root/assets/{chunk-KS7C4IRE-BaASWQor.js → chunk-KS7C4IRE-Cq1tE_3b.js} +2 -2
  25. package/dist/gateway/static/root/assets/code-editor-CXIH8jQw.js +1 -0
  26. package/dist/gateway/static/root/assets/connectors-page-CkH3gaqs.js +2 -0
  27. package/dist/gateway/static/root/assets/{cron-expression-DCTN4QAG.js → cron-expression-z4WOWyBU.js} +1 -1
  28. package/dist/gateway/static/root/assets/date-picker-vKUcJeQZ.js +1 -0
  29. package/dist/gateway/static/root/assets/{dependency-picker-l6IXzk0C.js → dependency-picker-BpZ9A2gi.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-cGn_20DO.js → desktop-pet-ClrAMqgn.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-DIfccDKS.js → desktop-pet-settings-DKNKGiEG.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-CTS5RP_D.js → extension-debug-page-C39hFkJm.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-Dg9YssYH.js → extension-page-DkqVsWB7.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-settings-page-CWZYL8Fi.js → extension-settings-page-Be4lFw8f.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-config-swr-Chsr5wGH.js → gateway-config-swr-DEKSw3d-.js} +1 -1
  36. package/dist/gateway/static/root/assets/gateway-settings-HIHGY-0Y.js +1 -0
  37. package/dist/gateway/static/root/assets/{gateway-startup-retry-C9ynH6VV.js → gateway-startup-retry-Dlyt2VhF.js} +1 -1
  38. package/dist/gateway/static/root/assets/{heartbeat-settings-WUhSfvob.js → heartbeat-settings-DiYjWa1F.js} +1 -1
  39. package/dist/gateway/static/root/assets/home-page-BLZNEVmk.js +1 -0
  40. package/dist/gateway/static/root/assets/{image-generation-api-D_TsVe7h.js → image-generation-api-CJIPVk_d.js} +1 -1
  41. package/dist/gateway/static/root/assets/index-50Kr6L6C.css +2 -0
  42. package/dist/gateway/static/root/assets/index-BWdn9NaX.js +76 -0
  43. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-DGBf6YfD.js → keyboard-shortcuts-settings-ge76J038.js} +1 -1
  44. package/dist/gateway/static/root/assets/languages-BFe8nIOO.js +2 -0
  45. package/dist/gateway/static/root/assets/local-app-workbench-page-E47xrPDI.js +2 -0
  46. package/dist/gateway/static/root/assets/{local-apps-page-DGWP_xsQ.js → local-apps-page-gkw7VRL4.js} +1 -1
  47. package/dist/gateway/static/root/assets/{locale-store-B2v8mNJw.js → locale-store-DJPCr2mb.js} +1 -1
  48. package/dist/gateway/static/root/assets/logs-page-HHtDMSUW.js +2 -0
  49. package/dist/gateway/static/root/assets/{management-settings-DUAZ-dtt.js → management-settings-DOfCSojd.js} +1 -1
  50. package/dist/gateway/static/root/assets/markdown-editor-BhBJANcx.js +1 -0
  51. package/dist/gateway/static/root/assets/{markdown-view-DBWu9d_n.js → markdown-view-k_PJsY2C.js} +2 -2
  52. package/dist/gateway/static/root/assets/{media-plugins-CsUjcIBy.js → media-plugins-D8wMcUtB.js} +1 -1
  53. package/dist/gateway/static/root/assets/messages-BeIiRpmk.js +3 -0
  54. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-Dxu8twiQ.js → mobile-pairing-wizard-B4Ewewwr.js} +1 -1
  55. package/dist/gateway/static/root/assets/note-detail-panel-DPd5L2A9.js +5 -0
  56. package/dist/gateway/static/root/assets/notes-page-CE_De-iQ.js +8 -0
  57. package/dist/gateway/static/root/assets/{page-tabs-YeJKwV-7.js → page-tabs-DoxnT3X4.js} +1 -1
  58. package/dist/gateway/static/root/assets/popover-select-CKBYnT3c.js +1 -0
  59. package/dist/gateway/static/root/assets/{preview-open-alternatives-BfJ3jMDG.js → preview-open-alternatives-D4oL1yua.js} +1 -1
  60. package/dist/gateway/static/root/assets/product-open-page-CeStuxSl.js +1 -0
  61. package/dist/gateway/static/root/assets/project-detail-page-DXhBJzJy.js +1 -0
  62. package/dist/gateway/static/root/assets/projects-page-CcqhmZoX.js +1 -0
  63. package/dist/gateway/static/root/assets/{registry-api-B9OZUdwC.js → registry-api-Dalzf2w0.js} +1 -1
  64. package/dist/gateway/static/root/assets/remote-access-hub-ulmJT_Ac.js +1 -0
  65. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-uJ8Br3ZL.js → runtime-tools-settings-panel-CrOpchy5.js} +2 -2
  66. package/dist/gateway/static/root/assets/{schema-form-CXwn6up5.js → schema-form-Dk52v4cQ.js} +1 -1
  67. package/dist/gateway/static/root/assets/sessions-page-RM0kAsNa.js +1 -0
  68. package/dist/gateway/static/root/assets/settings-advanced-gate-BfLbu67w.js +1 -0
  69. package/dist/gateway/static/root/assets/{settings-form-section-YVNYsR0U.js → settings-form-section-dvGi1APN.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-cHqrIdVR.js → settings-page-CEYjEm2D.js} +1 -1
  71. package/dist/gateway/static/root/assets/setup-status-panel-BZ4i0CYX.js +1 -0
  72. package/dist/gateway/static/root/assets/{share-preview-page-DnjSDQru.js → share-preview-page-DP4Qgsv6.js} +1 -1
  73. package/dist/gateway/static/root/assets/shares-settings-B5yHTrGO.js +1 -0
  74. package/dist/gateway/static/root/assets/skill-reload-api-BicZK04u.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-DkrGEdiY.js → skills-page-Dlr1Ue1w.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-CqZbiZuK.js → skills-page.utils-I1wcnceD.js} +1 -1
  77. package/dist/gateway/static/root/assets/source-workspace-editor-DunRD1gY.js +1 -0
  78. package/dist/gateway/static/root/assets/{system-settings-panel-Dmw0RfxZ.js → system-settings-panel-DIaFAHT0.js} +1 -1
  79. package/dist/gateway/static/root/assets/task-detail-page-4_5g-V8B.js +1 -0
  80. package/dist/gateway/static/root/assets/{theme-store-CubltMKm.js → theme-store-DYDrhfnD.js} +1 -1
  81. package/dist/gateway/static/root/assets/{tunnel-api-CiieC6HP.js → tunnel-api-DAXx1rHF.js} +1 -1
  82. package/dist/gateway/static/root/assets/{use-autosave-XQ3SuyB9.js → use-autosave-BwEFbveP.js} +1 -1
  83. package/dist/gateway/static/root/assets/user-model-page-CQnXw4ba.js +2 -0
  84. package/dist/gateway/static/root/assets/{vendor-codemirror-Qdcjid65.js → vendor-codemirror-DFxP3B9T.js} +16 -16
  85. package/dist/gateway/static/root/assets/{voice-api-key-field-D4QzVgdt.js → voice-api-key-field-C-WbC2fM.js} +1 -1
  86. package/dist/gateway/static/root/assets/{voice-config-api-B1ZbyVmF.js → voice-config-api-Ds0z9O11.js} +1 -1
  87. package/dist/gateway/static/root/assets/{work-discovery-overlay-D5Tf8GRZ.js → work-discovery-overlay-DiGw5KKj.js} +1 -1
  88. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-BW9p8Maz.js → workflow-run-setup-panel-BIU2wg99.js} +2 -2
  89. package/dist/gateway/static/root/assets/workflows-page-D3Z7JVHH.js +6 -0
  90. package/dist/gateway/static/root/index.html +12 -12
  91. package/dist/package.js +1 -1
  92. package/dist/packages/gateway-contract/src/user-message-display.js +0 -18
  93. package/dist/src/agent/context/execution-context.js +34 -21
  94. package/dist/src/agent/context/execution-context.types.d.ts +2 -0
  95. package/dist/src/agent/inbound/attachment-pipeline.d.ts +1 -0
  96. package/dist/src/agent/inbound/attachment-pipeline.js +6 -1
  97. package/dist/src/agent/prompt/sections/memory-skills.js +2 -1
  98. package/dist/src/agent/prompt/sections/tooling.js +2 -0
  99. package/dist/src/agent/tools/create-share-tool.js +39 -1
  100. package/dist/src/agent/tools/delegate-tool.js +1 -0
  101. package/dist/src/agent/tools/factory.js +14 -1
  102. package/dist/src/agent/tools/index.d.ts +1 -1
  103. package/dist/src/agent/tools/index.js +2 -2
  104. package/dist/src/agent/tools/user-context-tool.d.ts +3 -0
  105. package/dist/src/agent/tools/user-context-tool.js +147 -4
  106. package/dist/src/agent/workflow/catalog.js +6 -2
  107. package/dist/src/chat-commands/builtins/workflow.js +1 -1
  108. package/dist/src/cli/commands/tunnel.js +3 -3
  109. package/dist/src/connectors/connected-source-understanding.js +4 -4
  110. package/dist/src/gateway/agent-builtin-tools.d.ts +7 -1
  111. package/dist/src/gateway/agent-builtin-tools.js +7 -0
  112. package/dist/src/gateway/device-routes.js +1 -1
  113. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  114. package/dist/src/gateway/hono/routes/lazy-bundles.js +2 -2
  115. package/dist/src/gateway/hono/routes/sessions.js +1 -1
  116. package/dist/src/gateway/hono/routes/shares.js +404 -7
  117. package/dist/src/gateway/hono/routes/site-shares.js +19 -13
  118. package/dist/src/gateway/hono/routes/tunnel.js +1 -1
  119. package/dist/src/gateway/hono/routes/user-model.js +35 -102
  120. package/dist/src/gateway/hono/routes/workflows.js +7 -4
  121. package/dist/src/gateway/service/sessions-api.js +1 -1
  122. package/dist/src/gateway/service.js +6 -6
  123. package/dist/src/remote-access/exposure-manager.js +1 -1
  124. package/dist/src/session/index.js +1 -1
  125. package/dist/src/session/store.js +1 -1
  126. package/dist/src/share/hosted-note-publication.d.ts +22 -0
  127. package/dist/src/share/hosted-note-publication.js +96 -0
  128. package/dist/src/share/hosted-session-share.d.ts +86 -7
  129. package/dist/src/share/hosted-session-share.js +72 -15
  130. package/dist/src/share/hosted-static-site-publication.d.ts +16 -0
  131. package/dist/src/share/hosted-static-site-publication.js +108 -0
  132. package/dist/src/share/hosted-static-site-publish.d.ts +23 -0
  133. package/dist/src/share/hosted-static-site-publish.js +53 -0
  134. package/dist/src/share/note-share-service.d.ts +1 -0
  135. package/dist/src/share/note-share-service.js +4 -4
  136. package/dist/src/share/share-url.d.ts +1 -1
  137. package/dist/src/share/share-url.js +14 -9
  138. package/dist/src/tui/backends/embedded-backend.js +2 -2
  139. package/dist/src/tui/tui-agent-events.js +1 -1
  140. package/dist/src/tui/tui-workflow-slash.d.ts +3 -6
  141. package/dist/src/tui/tui-workflow-slash.js +3 -6
  142. package/dist/src/tunnel/index.js +1 -1
  143. package/dist/src/tunnel/tunnel-service.js +1 -1
  144. package/dist/src/user-model/bootstrap.d.ts +17 -0
  145. package/dist/src/user-model/bootstrap.js +118 -0
  146. package/dist/src/user-model/index.d.ts +3 -0
  147. package/dist/src/user-model/index.js +4 -1
  148. package/dist/src/user-model/profile.d.ts +5 -0
  149. package/dist/src/user-model/profile.js +98 -0
  150. package/dist/src/user-model/usage-policy.d.ts +2 -0
  151. package/dist/src/user-model/usage-policy.js +6 -0
  152. package/dist/src/voice/realtime/agentEngine.js +17 -0
  153. package/dist/src/voice/realtime/memory-context.js +1 -1
  154. package/dist/src/voice/realtime/playback-echo.d.ts +2 -0
  155. package/dist/src/voice/realtime/playback-echo.js +15 -0
  156. package/dist/src/work-discovery/analyzer.js +8 -6
  157. package/dist/src/work-discovery/service.d.ts +1 -1
  158. package/dist/src/work-discovery/service.js +4 -4
  159. package/dist/src/work-discovery/types.d.ts +1 -1
  160. package/dist/src/workflows/domain/run.d.ts +8 -1
  161. package/dist/src/workflows/domain/validation.d.ts +3 -4
  162. package/dist/src/workflows/domain/validation.js +119 -8
  163. package/dist/src/workflows/service/workflow-run-service.js +8 -1
  164. package/package.json +5 -5
  165. package/dist/gateway/static/root/assets/agent-defaults-settings-panel-vul32IsP.js +0 -1
  166. package/dist/gateway/static/root/assets/apps-page-CJFJKNwS.js +0 -1
  167. package/dist/gateway/static/root/assets/automations-workspace-B2wxcpgq.js +0 -6
  168. package/dist/gateway/static/root/assets/block-editor-C61LqK_-.js +0 -185
  169. package/dist/gateway/static/root/assets/browser-settings-page-BMjY8cyv.js +0 -8
  170. package/dist/gateway/static/root/assets/capabilities-settings-panel-wB3Vgmp3.js +0 -7
  171. package/dist/gateway/static/root/assets/channels-settings-U5ffzu4r.js +0 -1
  172. package/dist/gateway/static/root/assets/connectors-page-BGaF--m5.js +0 -2
  173. package/dist/gateway/static/root/assets/date-picker-BuEyUxZn.js +0 -1
  174. package/dist/gateway/static/root/assets/gateway-settings-vHI_Que8.js +0 -1
  175. package/dist/gateway/static/root/assets/home-page-CYjlMzPx.js +0 -1
  176. package/dist/gateway/static/root/assets/index-BBlJYVxR.js +0 -74
  177. package/dist/gateway/static/root/assets/index-_I0dD2LN.css +0 -2
  178. package/dist/gateway/static/root/assets/languages-5WaOu0Lf.js +0 -2
  179. package/dist/gateway/static/root/assets/local-app-workbench-page-CLlIl83V.js +0 -2
  180. package/dist/gateway/static/root/assets/logs-page-DuhCigiB.js +0 -2
  181. package/dist/gateway/static/root/assets/markdown-editor-BjMTIM-m.js +0 -1
  182. package/dist/gateway/static/root/assets/messages-ChSTFZR5.js +0 -3
  183. package/dist/gateway/static/root/assets/note-detail-panel-DMdbaTZp.js +0 -5
  184. package/dist/gateway/static/root/assets/notes-page-xe_vX0nM.js +0 -8
  185. package/dist/gateway/static/root/assets/popover-select-C-Hj-nXR.js +0 -1
  186. package/dist/gateway/static/root/assets/product-open-page-B7NRGPox.js +0 -1
  187. package/dist/gateway/static/root/assets/project-detail-page-hG7ELibZ.js +0 -1
  188. package/dist/gateway/static/root/assets/projects-page-C5G2ET4w.js +0 -1
  189. package/dist/gateway/static/root/assets/remote-access-hub-DTO-faxH.js +0 -1
  190. package/dist/gateway/static/root/assets/sessions-page-CwzsUCgP.js +0 -1
  191. package/dist/gateway/static/root/assets/settings-advanced-gate-Djc3EdoO.js +0 -1
  192. package/dist/gateway/static/root/assets/setup-status-panel-MUAMcZLD.js +0 -1
  193. package/dist/gateway/static/root/assets/shares-settings-C7A0aywX.js +0 -1
  194. package/dist/gateway/static/root/assets/skill-reload-api-D1xSGJAQ.js +0 -1
  195. package/dist/gateway/static/root/assets/source-workspace-editor-CVWzt0oT.js +0 -1
  196. package/dist/gateway/static/root/assets/task-detail-page-BvZSCLUH.js +0 -1
  197. package/dist/gateway/static/root/assets/user-model-page-BKJC7tyW.js +0 -2
  198. package/dist/gateway/static/root/assets/workflows-page-DuqRodIc.js +0 -5
@@ -5,6 +5,7 @@ import "../../knowledge-memory/index.js";
5
5
  import { retrievalLexicalSimilarity } from "../../retrieval/textFeatures.js";
6
6
  import { calculateExecutionValue } from "../../user-model/importance.js";
7
7
  import { listUserAssertions } from "../../user-model/repository.js";
8
+ import { isWorkingAssumption } from "../../user-model/usage-policy.js";
8
9
  import { getExecutionContextFeedbackScores } from "./audit.js";
9
10
  import { buildUserContextBlock } from "../memory/context-fence.js";
10
11
  import { randomUUID } from "node:crypto";
@@ -43,24 +44,27 @@ function urgency(assertion, asOf) {
43
44
  }
44
45
  function rankAssertion(assertion, query, asOf, feedbackScore) {
45
46
  const taskRelevance = retrievalLexicalSimilarity(query, `${assertion.statement} ${assertion.normalizedValue}`);
47
+ const score = calculateExecutionValue({
48
+ declaredImportance: assertion.declaredImportance,
49
+ inferredImportance: assertion.inferredImportance,
50
+ consequence: assertion.consequence,
51
+ actionability: assertion.actionability,
52
+ taskRelevance,
53
+ urgency: urgency(assertion, asOf)
54
+ }) + feedbackScore;
55
+ const reasons = [
56
+ taskRelevance >= .35 ? "task_relevant" : "",
57
+ assertion.declaredImportance !== void 0 ? "user_declared_importance" : "",
58
+ assertion.consequence === "critical" || assertion.consequence === "high" ? "high_consequence" : "",
59
+ assertion.kind === "identity" || assertion.kind === "preference" ? "stable_personalization" : "",
60
+ feedbackScore > 0 ? "historically_helpful" : "",
61
+ feedbackScore < 0 ? "historically_irrelevant" : ""
62
+ ].filter(Boolean);
46
63
  return {
47
64
  assertion,
48
- score: calculateExecutionValue({
49
- declaredImportance: assertion.declaredImportance,
50
- inferredImportance: assertion.inferredImportance,
51
- consequence: assertion.consequence,
52
- actionability: assertion.actionability,
53
- taskRelevance,
54
- urgency: urgency(assertion, asOf)
55
- }) + feedbackScore,
56
- reasons: [
57
- taskRelevance >= .35 ? "task_relevant" : "",
58
- assertion.declaredImportance !== void 0 ? "user_declared_importance" : "",
59
- assertion.consequence === "critical" || assertion.consequence === "high" ? "high_consequence" : "",
60
- assertion.kind === "identity" || assertion.kind === "preference" ? "stable_personalization" : "",
61
- feedbackScore > 0 ? "historically_helpful" : "",
62
- feedbackScore < 0 ? "historically_irrelevant" : ""
63
- ].filter(Boolean)
65
+ usage: assertion.status === "active" ? "confirmed" : "working_assumption",
66
+ score: assertion.status === "candidate" ? score - .05 : score,
67
+ reasons
64
68
  };
65
69
  }
66
70
  function ruleEnforcement(conditions) {
@@ -91,6 +95,7 @@ function loadGoals(context, asOf) {
91
95
  title: row.title,
92
96
  desiredOutcome: row.desired_outcome,
93
97
  status: row.status,
98
+ usage: row.status === "active" ? "confirmed" : "working_assumption",
94
99
  ...row.declared_importance === null ? {} : { declaredImportance: row.declared_importance },
95
100
  ...row.target_at === null ? {} : { targetAt: row.target_at }
96
101
  }));
@@ -115,10 +120,12 @@ function buildExecutionContext(request) {
115
120
  const asOf = request.asOf ?? Date.now();
116
121
  const includeUserModel = request.includeUserModel !== false;
117
122
  const feedbackScores = getExecutionContextFeedbackScores();
118
- const assertions = includeUserModel ? listUserAssertions({
119
- statuses: ["active"],
123
+ const assertionLimit = Math.max(1, Math.min(100, request.maxAssertions ?? 20));
124
+ const rankedAssertions = includeUserModel ? listUserAssertions({
125
+ statuses: ["active", "candidate"],
120
126
  limit: 1e3
121
- }).filter((item) => scopeVisible(getAssertionScope(item.slotId), request)).filter((item) => applicabilityVisible(item.applicability, request)).filter((item) => (item.validFrom === void 0 || item.validFrom <= asOf) && (item.validTo === void 0 || item.validTo >= asOf)).filter((item) => item.authority !== "external_untrusted").filter((item) => item.sensitivity !== "secret" && item.sensitivity !== "regulated" && item.disclosurePolicy !== "ask_before_reference").map((item) => rankAssertion(item, request.query, asOf, feedbackScores.get(`assertion:${item.id}`) ?? 0)).filter((item) => item.score >= .12 || item.reasons.includes("high_consequence")).sort((left, right) => right.score - left.score).slice(0, Math.max(1, Math.min(100, request.maxAssertions ?? 20))) : [];
127
+ }).filter((item) => scopeVisible(getAssertionScope(item.slotId), request)).filter((item) => applicabilityVisible(item.applicability, request)).filter((item) => (item.validFrom === void 0 || item.validFrom <= asOf) && (item.validTo === void 0 || item.validTo >= asOf)).filter((item) => item.authority !== "external_untrusted").filter((item) => item.sensitivity !== "secret" && item.sensitivity !== "regulated" && item.disclosurePolicy !== "ask_before_reference").filter((item) => item.status === "active" || isWorkingAssumption(item)).map((item) => rankAssertion(item, request.query, asOf, feedbackScores.get(`assertion:${item.id}`) ?? 0)).filter((item) => item.score >= .12 || item.reasons.includes("high_consequence")).sort((left, right) => right.score - left.score) : [];
128
+ const assertions = [...rankedAssertions.filter((item) => item.usage === "confirmed"), ...rankedAssertions.filter((item) => item.usage === "working_assumption")].slice(0, assertionLimit);
122
129
  const maxKnowledge = Math.max(0, Math.min(100, request.maxKnowledge ?? 12));
123
130
  const knowledge = request.includeKnowledge === false || maxKnowledge === 0 ? [] : searchKnowledgeItems({
124
131
  query: request.query,
@@ -153,8 +160,14 @@ function getAssertionScope(slotId) {
153
160
  function renderExecutionContext(context) {
154
161
  const sections = [];
155
162
  if (context.rules.length) sections.push(`Collaboration rules:\n${context.rules.map((rule) => `- ${rule.statement}`).join("\n")}`);
156
- if (context.assertions.length) sections.push(`Relevant user facts:\n${context.assertions.map((item) => `- ${item.assertion.statement}`).join("\n")}`);
157
- if (context.goals.length) sections.push(`Active goals:\n${context.goals.map((goal) => `- ${goal.title}: ${goal.desiredOutcome}`).join("\n")}`);
163
+ const confirmedAssertions = context.assertions.filter((item) => item.usage === "confirmed");
164
+ const workingAssumptions = context.assertions.filter((item) => item.usage === "working_assumption");
165
+ if (confirmedAssertions.length) sections.push(`Confirmed user context:\n${confirmedAssertions.map((item) => `- ${item.assertion.statement}`).join("\n")}`);
166
+ if (workingAssumptions.length) sections.push(`Working assumptions (may be wrong; adapt quietly, never present them as confirmed facts, and accept corrections immediately):\n${workingAssumptions.map((item) => `- ${item.assertion.statement} (confidence ${item.assertion.confidence.toFixed(2)})`).join("\n")}`);
167
+ const confirmedGoals = context.goals.filter((goal) => goal.usage === "confirmed");
168
+ const assumedGoals = context.goals.filter((goal) => goal.usage === "working_assumption");
169
+ if (confirmedGoals.length) sections.push(`Confirmed goals:\n${confirmedGoals.map((goal) => `- ${goal.title}: ${goal.desiredOutcome}`).join("\n")}`);
170
+ if (assumedGoals.length) sections.push(`Possible goals (not yet confirmed):\n${assumedGoals.map((goal) => `- ${goal.title}: ${goal.desiredOutcome}`).join("\n")}`);
158
171
  if (context.priorities.length) sections.push(`Current priorities:\n${context.priorities.map((item) => `- ${item.rank}: ${item.targetType}/${item.targetId}`).join("\n")}`);
159
172
  if (context.knowledge.length) sections.push(`Relevant knowledge:\n${context.knowledge.map((item) => `- ${item.content}`).join("\n")}`);
160
173
  return sections.join("\n\n");
@@ -10,6 +10,7 @@ export interface ExecutionRule {
10
10
  }
11
11
  export interface RankedExecutionAssertion {
12
12
  assertion: UserAssertion;
13
+ usage: 'confirmed' | 'working_assumption';
13
14
  score: number;
14
15
  reasons: string[];
15
16
  }
@@ -18,6 +19,7 @@ export interface ExecutionGoal {
18
19
  title: string;
19
20
  desiredOutcome: string;
20
21
  status: string;
22
+ usage: 'confirmed' | 'working_assumption';
21
23
  declaredImportance?: number;
22
24
  targetAt?: number;
23
25
  }
@@ -31,6 +31,7 @@ export declare function hydrateUserTurnForLlm(opts: {
31
31
  modelRef: string;
32
32
  }): Promise<LlmUserTurn>;
33
33
  export declare function setPendingTranscriptUserMessage(sessionKey: string, message: TranscriptUserMessage): void;
34
+ export declare function getPendingTranscriptUserText(sessionKey: string): string | undefined;
34
35
  export declare function takePendingTranscriptUserMessage(sessionKey: string): TranscriptUserMessage | undefined;
35
36
  export declare function clearPendingTranscriptUserMessage(sessionKey: string, message?: TranscriptUserMessage): void;
36
37
  export declare function pendingTranscriptReferencesMediaUri(sessionKey: string, uri: string): boolean;
@@ -144,6 +144,11 @@ function setPendingTranscriptUserMessage(sessionKey, message) {
144
144
  assertTranscriptUserMessage(message);
145
145
  pendingTranscriptBySession.set(sessionKey, message);
146
146
  }
147
+ function getPendingTranscriptUserText(sessionKey) {
148
+ const message = pendingTranscriptBySession.get(sessionKey);
149
+ if (!message) return void 0;
150
+ return stripRuntimeUserMessageEnvelope(messageTextForPendingCompare(message)).trim();
151
+ }
147
152
  function takePendingTranscriptUserMessage(sessionKey) {
148
153
  const msg = pendingTranscriptBySession.get(sessionKey);
149
154
  pendingTranscriptBySession.delete(sessionKey);
@@ -171,4 +176,4 @@ function transformUserMessageForPersistence(sessionKey, message) {
171
176
  return message;
172
177
  }
173
178
  //#endregion
174
- export { assertTranscriptUserMessage, buildTranscriptUserMessage, clearPendingTranscriptUserMessage, hydrateUserTurnForLlm, pendingTranscriptReferencesMediaUri, setPendingTranscriptUserMessage, takePendingTranscriptUserMessage, transformUserMessageForPersistence };
179
+ export { assertTranscriptUserMessage, buildTranscriptUserMessage, clearPendingTranscriptUserMessage, getPendingTranscriptUserText, hydrateUserTurnForLlm, pendingTranscriptReferencesMediaUri, setPendingTranscriptUserMessage, takePendingTranscriptUserMessage, transformUserMessageForPersistence };
@@ -13,10 +13,11 @@ function buildMemorySection(params) {
13
13
  const lines = [
14
14
  "## Context and memory",
15
15
  "",
16
- "Relevant user facts, goals, priorities, collaboration rules, and task knowledge are selected for each turn.",
16
+ "Confirmed user context, labeled working assumptions, goals, priorities, collaboration rules, and task knowledge are selected for each turn.",
17
17
  "When exact or additional context is needed:"
18
18
  ];
19
19
  if (names.has("user_context_search")) lines.push("- Use `user_context_search` for user identity, preferences, routines, and current state.");
20
+ if (names.has("user_context_update")) lines.push("- When the current user explicitly corrects, confirms, rejects, or asks to forget an existing user assertion, use `user_context_update` immediately and include an exact quote as evidence. Never use it for an inference of your own.");
20
21
  if (names.has("knowledge_search")) lines.push("- Use `knowledge_search` for project facts, decisions, lessons, commitments, and open questions.");
21
22
  if (names.has("session_recall")) lines.push("- Use `session_recall` for exact raw content from the current session.");
22
23
  if (names.has("session_search")) lines.push("- Use `session_search` for other conversations.");
@@ -17,6 +17,7 @@ const CORE_TOOL_ORDER = [
17
17
  "publish_artifacts",
18
18
  "user_context_search",
19
19
  "user_context_get",
20
+ "user_context_update",
20
21
  "knowledge_search",
21
22
  "knowledge_get",
22
23
  "knowledge_write",
@@ -57,6 +58,7 @@ const CORE_TOOL_SUMMARIES = {
57
58
  publish_artifacts: "Publish final generated files as durable chat deliverables",
58
59
  user_context_search: "Search typed user facts, preferences, routines, and current state",
59
60
  user_context_get: "Read one typed user assertion with its scope and authority",
61
+ user_context_update: "Apply an explicit user confirmation, correction, rejection, or forget request to an existing assertion",
60
62
  knowledge_search: "Search scoped project, workspace, and session knowledge",
61
63
  knowledge_get: "Read one knowledge item returned by search",
62
64
  knowledge_write: "Store a scoped knowledge candidate with provenance",
@@ -6,6 +6,7 @@ import { mergeWithDefaults } from "../../share/site-share-config.js";
6
6
  import { getShareStore } from "../../share/share-store.js";
7
7
  import { getSiteShareStore } from "../../share/site-share-store.js";
8
8
  import { resolveShareUrl, resolveSiteShareUrl } from "../../share/share-url.js";
9
+ import { publishHostedStaticSite } from "../../share/hosted-static-site-publish.js";
9
10
  import { resolveReverseProxyPublicUrl } from "../../gateway/public-url.js";
10
11
  import { audienceDefaults, decideShareKind, makeDescription, makeTitle, probeShareTarget, rememberStagedSite, stageSingleHtmlAsSite } from "../../share/share-auto.js";
11
12
  import { scheduleThumbnail } from "../../share/share-thumbnail.js";
@@ -110,6 +111,44 @@ function createCreateShareTool(deps) {
110
111
  const siteStore = getSiteShareStore(siteCfg);
111
112
  let sitePath = relPath;
112
113
  let stagedDir = null;
114
+ const titleOut = makeTitle(probe.kind === "directory" ? relPath.split("/").pop() || relPath : probe.absolutePath.split(/[\\/]/).pop() || relPath, p.title);
115
+ if (resolveSiteShareUrl({
116
+ ...urlCtx,
117
+ token: "reachability-check",
118
+ subdomainLabel: "reachability-check",
119
+ publicHostSuffix: siteCfg.publicHostSuffix
120
+ }).reachability !== "public") {
121
+ const { binding } = await publishHostedStaticSite({
122
+ workspaceRoot: workspace,
123
+ path: sitePath,
124
+ title: titleOut,
125
+ description: p.description,
126
+ spaFallback: true,
127
+ ttlMs,
128
+ maxViews: maxViews ?? null,
129
+ agentId: deps.getAgentId?.()
130
+ });
131
+ return successResult(locale, {
132
+ kind: "site",
133
+ delivery: "hosted",
134
+ shareUrl: binding.shareUrl,
135
+ thumbnailUrl: "",
136
+ reachability: "public",
137
+ reachabilityHint: null,
138
+ title: binding.title,
139
+ description: makeDescription({
140
+ audience,
141
+ expiresAt: binding.expiresAt,
142
+ override: p.description
143
+ }),
144
+ expiresAt: binding.expiresAt,
145
+ maxViews: binding.maxViews,
146
+ routing: {
147
+ reason: decision.reason,
148
+ hint: decision.hint
149
+ }
150
+ });
151
+ }
113
152
  if (probe.kind === "file") {
114
153
  const staged = await stageSingleHtmlAsSite(workspace, probe.absolutePath);
115
154
  sitePath = staged.relativePath;
@@ -142,7 +181,6 @@ function createCreateShareTool(deps) {
142
181
  internalBaseUrl: shareCfg.thumbnail.internalGatewayUrl ?? `http://127.0.0.1:${gatewayPort}`
143
182
  });
144
183
  siteStore.setThumbnailStatus(siteRec.id, "pending");
145
- const titleOut = makeTitle(probe.kind === "directory" ? relPath.split("/").pop() || relPath : probe.absolutePath.split(/[\\/]/).pop() || relPath, p.title);
146
184
  const descOut = makeDescription({
147
185
  audience,
148
186
  expiresAt: siteRec.expiresAt,
@@ -28,6 +28,7 @@ const DELEGATE_BLOCKED_TOOLS = new Set([
28
28
  "session_search",
29
29
  "user_context_search",
30
30
  "user_context_get",
31
+ "user_context_update",
31
32
  "knowledge_search",
32
33
  "knowledge_get",
33
34
  "knowledge_write",
@@ -19,7 +19,7 @@ import { createListDirTool } from "./list-dir.js";
19
19
  import { createPublishArtifactsTool } from "./publish-artifacts.js";
20
20
  import { createExecCommandTool } from "./exec-command.js";
21
21
  import { createApplyPatchTool } from "./apply-patch.js";
22
- import { createUserContextGetTool, createUserContextSearchTool } from "./user-context-tool.js";
22
+ import { createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool } from "./user-context-tool.js";
23
23
  import { createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool } from "./knowledge-memory-tool.js";
24
24
  import { createSessionSearchTool } from "./session-search-tool.js";
25
25
  import { createSessionRecallTool } from "./session-recall-tool.js";
@@ -40,6 +40,7 @@ import { BrowserRuntime } from "../../browser/runtime/browser-runtime.js";
40
40
  import { createBrowserDriver } from "../../browser/drivers/create-driver.js";
41
41
  import { checkBrowserReadiness } from "../../browser/readiness.js";
42
42
  import "../../browser/index.js";
43
+ import { getPendingTranscriptUserText } from "../inbound/attachment-pipeline.js";
43
44
  import { createDelegateTool } from "./delegate-tool.js";
44
45
  import { createWorkflowTool } from "./workflow-tool.js";
45
46
  import { createAutomationTool } from "./automation-tool.js";
@@ -324,6 +325,18 @@ var AgentToolsFactory = class AgentToolsFactory {
324
325
  getProjectId: currentProjectId,
325
326
  canRead: () => currentAccess().userModel
326
327
  }),
328
+ createUserContextUpdateTool({
329
+ agentId: resolvedAgentId,
330
+ workspaceId: workspace,
331
+ getSessionId: currentSessionKey,
332
+ getProjectId: currentProjectId,
333
+ canRead: () => currentAccess().userModel,
334
+ canWrite: () => currentAccess().userModel,
335
+ getCurrentUserText: () => {
336
+ const sessionKey = currentSessionKey();
337
+ return sessionKey ? getPendingTranscriptUserText(sessionKey) : void 0;
338
+ }
339
+ }),
327
340
  createKnowledgeSearchTool({
328
341
  agentId: resolvedAgentId,
329
342
  workspaceId: workspace,
@@ -5,7 +5,7 @@ export { createWriteFileTool, writeFileTool } from './write.js';
5
5
  export { createListDirTool, listDirTool } from './list-dir.js';
6
6
  export { createExecCommandTool, type ExecCommandDetails, type ExecCommandUpdateDetails, } from './exec-command.js';
7
7
  export { createApplyPatchTool, type AppliedPatchChange, type ApplyPatchDetails, } from './apply-patch.js';
8
- export { createUserContextSearchTool, createUserContextGetTool, type UserContextToolOptions, } from './user-context-tool.js';
8
+ export { createUserContextSearchTool, createUserContextGetTool, createUserContextUpdateTool, type UserContextToolOptions, } from './user-context-tool.js';
9
9
  export { createKnowledgeSearchTool, createKnowledgeGetTool, createKnowledgeWriteTool, type KnowledgeToolOptions, } from './knowledge-memory-tool.js';
10
10
  export { createSessionSearchTool } from './session-search-tool.js';
11
11
  export { createSessionRecallTool, type SessionRecallToolDeps } from './session-recall-tool.js';
@@ -8,7 +8,7 @@ import { createPublishArtifactsTool } from "./publish-artifacts.js";
8
8
  import { createExecCommandTool } from "./exec-command.js";
9
9
  import { fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom } from "./edit-diff.js";
10
10
  import { createApplyPatchTool } from "./apply-patch.js";
11
- import { createUserContextGetTool, createUserContextSearchTool } from "./user-context-tool.js";
11
+ import { createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool } from "./user-context-tool.js";
12
12
  import { createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool } from "./knowledge-memory-tool.js";
13
13
  import { createSessionSearchTool } from "./session-search-tool.js";
14
14
  import { createSessionRecallTool } from "./session-recall-tool.js";
@@ -43,4 +43,4 @@ import { createDesktopPetTool } from "./desktop-pet-tool.js";
43
43
  import { createManagedJobTool } from "./managed-job-tool.js";
44
44
  import { createImageTool } from "./image-tool.js";
45
45
  import { createImageGenerateTool, resolveImageGenerationModelConfigForTool } from "./image-generate-tool.js";
46
- export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
46
+ export { BrowserRuntime, DEFAULT_DELEGATE_TOOLS, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, DEFAULT_TOOL_METADATA, DEFAULT_WEB_EXTRACT_MAX_LENGTH, DELEGATE_BLOCKED_TOOLS, GREP_MAX_LINE_LENGTH, MAX_RAW_HTML_CHARS_FOR_WEB_EXTRACT, TodoStore, ToolConcurrencyController, assertBrowserUrlAllowed, createApplyPatchTool, createAutomationTool, createBrowserAutomationTool, createClarifyTool, createCreateShareTool, createDelegateTool, createDesktopPetTool, createExecCommandTool, createFindTool, createGrepTool, createImageGenerateTool, createImageTool, createKnowledgeGetTool, createKnowledgeSearchTool, createKnowledgeWriteTool, createListDirTool, createManagedJobTool, createMemoryMaintenanceTool, createMessageTool, createPublishArtifactsTool, createReadFileTool, createReadMediaTool, createSendMediaTool, createSessionRecallTool, createSessionSearchTool, createSessionStatusTool, createSkillInstallTool, createSkillManageTool, createSkillViewTool, createSkillsListTool, createSkillsMarketplaceSearchTool, createTodoTool, createToolManualTool, createUpdatePlanTool, createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool, createWebExtractTool, createWebFetchTool, createWebSearchTool, createWorkflowTool, createWriteFileTool, createXopcUseTool, findTool, formatSize, fuzzyFindText, generateDiffString, getToolMetadata, grepTool, isShareToolAvailable, listDirTool, normalizeForFuzzyMatch, normalizeToLF, resolveImageGenerationModelConfigForTool, resolveImageModelConfigForTool, resolveToolLockMode, restoreLineEndings, stripBom, stripHtmlBoilerplate, truncateHead, truncateLine, truncateTail, writeFileTool };
@@ -5,6 +5,9 @@ export interface UserContextToolOptions {
5
5
  getSessionId: () => string | undefined;
6
6
  getProjectId?: () => string | undefined;
7
7
  canRead: () => boolean;
8
+ canWrite?: () => boolean;
9
+ getCurrentUserText?: () => string | undefined;
8
10
  }
9
11
  export declare function createUserContextSearchTool(options: UserContextToolOptions): AgentTool;
10
12
  export declare function createUserContextGetTool(options: UserContextToolOptions): AgentTool;
13
+ export declare function createUserContextUpdateTool(options: UserContextToolOptions): AgentTool;
@@ -1,5 +1,6 @@
1
1
  import { retrievalLexicalSimilarity } from "../../retrieval/textFeatures.js";
2
- import { getAssertionSlot, getUserAssertion, listUserAssertions } from "../../user-model/repository.js";
2
+ import { getAssertionSlot, getUserAssertion, listUserAssertions, reconcileAssertion, setAssertionStatus } from "../../user-model/repository.js";
3
+ import { isWorkingAssumption } from "../../user-model/usage-policy.js";
3
4
  import "../../user-model/index.js";
4
5
  import { Type } from "@sinclair/typebox";
5
6
  //#region src/agent/tools/user-context-tool.ts
@@ -11,12 +12,27 @@ const SearchSchema = Type.Object({
11
12
  }))
12
13
  });
13
14
  const GetSchema = Type.Object({ id: Type.String() });
15
+ const UpdateSchema = Type.Object({
16
+ id: Type.String(),
17
+ action: Type.Union([
18
+ Type.Literal("confirm"),
19
+ Type.Literal("correct"),
20
+ Type.Literal("reject"),
21
+ Type.Literal("forget"),
22
+ Type.Literal("review")
23
+ ]),
24
+ replacement: Type.Optional(Type.String({ maxLength: 500 })),
25
+ userEvidence: Type.String({
26
+ minLength: 1,
27
+ maxLength: 500
28
+ })
29
+ });
14
30
  function visible(options, slotId) {
15
31
  const scope = getAssertionSlot(slotId)?.scope;
16
32
  return scope?.type === "global" || scope?.type === "agent" && scope.id === options.agentId || scope?.type === "workspace" && scope.id === options.workspaceId || scope?.type === "project" && scope.id === options.getProjectId?.() || scope?.type === "session" && scope.id === options.getSessionId();
17
33
  }
18
34
  function referenceable(assertion) {
19
- return assertion.status === "active" && assertion.authority !== "external_untrusted" && assertion.sensitivity !== "secret" && assertion.sensitivity !== "regulated" && assertion.disclosurePolicy !== "ask_before_reference";
35
+ return (assertion.status === "active" || isWorkingAssumption(assertion)) && assertion.authority !== "external_untrusted" && assertion.sensitivity !== "secret" && assertion.sensitivity !== "regulated" && assertion.disclosurePolicy !== "ask_before_reference";
20
36
  }
21
37
  function createUserContextSearchTool(options) {
22
38
  return {
@@ -34,7 +50,7 @@ function createUserContextSearchTool(options) {
34
50
  };
35
51
  const input = raw;
36
52
  const results = listUserAssertions({
37
- statuses: ["active"],
53
+ statuses: ["active", "candidate"],
38
54
  limit: 1e3
39
55
  }).filter((assertion) => visible(options, assertion.slotId)).filter(referenceable).map((assertion) => ({
40
56
  assertion,
@@ -94,5 +110,132 @@ function createUserContextGetTool(options) {
94
110
  }
95
111
  };
96
112
  }
113
+ function createUserContextUpdateTool(options) {
114
+ return {
115
+ name: "user_context_update",
116
+ label: "User Context Update",
117
+ description: "Confirm, correct, reject, forget, or flag an existing user assertion. Use only when the current user explicitly confirms or requests the change; userEvidence must quote that request.",
118
+ parameters: UpdateSchema,
119
+ async execute(_toolCallId, raw) {
120
+ if (!options.canRead() || !options.canWrite?.()) return {
121
+ content: [{
122
+ type: "text",
123
+ text: "User-context updates are disabled for this session."
124
+ }],
125
+ details: { error: "user_context_update_disabled" }
126
+ };
127
+ const input = raw;
128
+ const current = getUserAssertion(input.id);
129
+ const slot = current ? getAssertionSlot(current.slotId) : void 0;
130
+ if (!current || !slot || !visible(options, current.slotId)) return {
131
+ content: [{
132
+ type: "text",
133
+ text: `User assertion not found: ${input.id}`
134
+ }],
135
+ details: {
136
+ error: "assertion_not_found",
137
+ id: input.id
138
+ }
139
+ };
140
+ const evidence = input.userEvidence.trim();
141
+ if (!evidence) return {
142
+ content: [{
143
+ type: "text",
144
+ text: "A quote from the current user message is required."
145
+ }],
146
+ details: { error: "user_evidence_required" }
147
+ };
148
+ const currentUserText = options.getCurrentUserText?.();
149
+ if (options.getCurrentUserText && (!currentUserText || !currentUserText.includes(evidence))) return {
150
+ content: [{
151
+ type: "text",
152
+ text: "userEvidence must be an exact quote from the current user message."
153
+ }],
154
+ details: { error: "user_evidence_mismatch" }
155
+ };
156
+ try {
157
+ if (input.action === "correct") {
158
+ const replacement = input.replacement?.trim();
159
+ if (!replacement) return {
160
+ content: [{
161
+ type: "text",
162
+ text: "A replacement is required for correction."
163
+ }],
164
+ details: { error: "replacement_required" }
165
+ };
166
+ const receipt = {
167
+ action: "corrected",
168
+ assertion: reconcileAssertion({
169
+ subject: slot.subject,
170
+ predicate: slot.predicate,
171
+ cardinality: slot.cardinality,
172
+ scope: slot.scope,
173
+ kind: current.kind,
174
+ value: replacement,
175
+ normalizedValue: replacement.toLocaleLowerCase(),
176
+ statement: replacement,
177
+ authority: "user_explicit",
178
+ confidence: 1,
179
+ ...current.declaredImportance === void 0 ? {} : { declaredImportance: current.declaredImportance },
180
+ inferredImportance: current.inferredImportance,
181
+ consequence: current.consequence,
182
+ actionability: current.actionability,
183
+ volatility: current.volatility,
184
+ sensitivity: current.sensitivity,
185
+ disclosurePolicy: current.disclosurePolicy,
186
+ applicability: current.applicability,
187
+ observedAt: Date.now(),
188
+ createdBy: "user",
189
+ correctionOfAssertionId: current.id
190
+ }).assertion,
191
+ previousAssertionId: current.id,
192
+ userEvidence: evidence
193
+ };
194
+ return {
195
+ content: [{
196
+ type: "text",
197
+ text: JSON.stringify(receipt, null, 2)
198
+ }],
199
+ details: receipt
200
+ };
201
+ }
202
+ const status = {
203
+ confirm: "active",
204
+ reject: "rejected",
205
+ forget: "archived",
206
+ review: "needs_review"
207
+ }[input.action];
208
+ const assertion = setAssertionStatus(current.id, status, {
209
+ actor: "user",
210
+ reason: `User requested ${input.action}: ${evidence}`
211
+ });
212
+ const receipt = {
213
+ action: input.action,
214
+ assertion,
215
+ userEvidence: evidence
216
+ };
217
+ return {
218
+ content: [{
219
+ type: "text",
220
+ text: JSON.stringify(receipt, null, 2)
221
+ }],
222
+ details: receipt
223
+ };
224
+ } catch (error) {
225
+ const message = error instanceof Error ? error.message : String(error);
226
+ return {
227
+ content: [{
228
+ type: "text",
229
+ text: message
230
+ }],
231
+ details: {
232
+ error: "user_context_update_failed",
233
+ message
234
+ }
235
+ };
236
+ }
237
+ }
238
+ };
239
+ }
97
240
  //#endregion
98
- export { createUserContextGetTool, createUserContextSearchTool };
241
+ export { createUserContextGetTool, createUserContextSearchTool, createUserContextUpdateTool };
@@ -2,7 +2,7 @@ import { requireXopcDatabase } from "../../storage/sqlite/connection.js";
2
2
  import { runSqliteWriteTransaction } from "../../storage/sqlite/transaction.js";
3
3
  import { DurableState } from "../../storage/sqlite/durable-state.js";
4
4
  import { buildWorkflowDefinition } from "../../workflows/domain/definition-utils.js";
5
- import { validateWorkflowGraph } from "../../workflows/domain/validation.js";
5
+ import { validateWorkflowDefinitionInput } from "../../workflows/domain/validation.js";
6
6
  import { BUILTIN_WORKFLOWS } from "./builtins/index.js";
7
7
  //#region src/agent/workflow/catalog.ts
8
8
  const NAME_RE = /^[a-z][a-z0-9_-]*$/;
@@ -26,7 +26,11 @@ function createWorkflowCatalog() {
26
26
  const save = (input) => {
27
27
  const name = input.name.trim();
28
28
  requireValidName(name);
29
- const validation = validateWorkflowGraph(input.graph);
29
+ const validation = validateWorkflowDefinitionInput({
30
+ name,
31
+ graph: input.graph,
32
+ manifest: input.manifest
33
+ });
30
34
  if (!validation.valid) throw new Error(validation.errors.map((issue) => issue.message).join(" "));
31
35
  requireXopcDatabase();
32
36
  return runSqliteWriteTransaction(() => {
@@ -48,7 +48,7 @@ function formatWorkflowListContent(entries) {
48
48
  const workflowsCommand = {
49
49
  id: "system.workflows",
50
50
  name: "workflows",
51
- description: "List saved workflows (built-in + ~/.xopc/workflows/)",
51
+ description: "List built-in and saved workflows",
52
52
  category: "system",
53
53
  scope: [
54
54
  "global",
@@ -2,12 +2,12 @@ import { createLogger } from "../../utils/logger/index.js";
2
2
  import { init_logger } from "../../utils/logger.js";
3
3
  import { loadConfig, saveConfig } from "../../config/loader.js";
4
4
  import { resolveGatewayEffectiveHost } from "../../config/gateway-bind.js";
5
- import { loadTunnelState } from "../../tunnel/tunnel-state.js";
6
- import { formatExamples, register } from "../registry.js";
7
- import "../../config/index.js";
8
5
  import { ensureFrpcBinary } from "../../tunnel/frpc-binary.js";
9
6
  import { resolveTunnelBrokerUrl, resolveTunnelRegistrationSecret } from "../../tunnel/env.js";
7
+ import { loadTunnelState } from "../../tunnel/tunnel-state.js";
10
8
  import { getTunnelService } from "../../tunnel/tunnel-service.js";
9
+ import { formatExamples, register } from "../registry.js";
10
+ import "../../config/index.js";
11
11
  import { TUNNEL_RISK_SUMMARY_LINES, TunnelConsentError, assertTunnelMayStart, hasValidTunnelConsent } from "../../tunnel/consent.js";
12
12
  import { resolveFrpSubdomainHost } from "../../tunnel/frp-subdomain-host.js";
13
13
  import { applyTunnelConsentToConfig, mergeTunnelConfigPatch, setTunnelEnabledInConfig } from "../../tunnel/tunnel-config.js";
@@ -57,7 +57,7 @@ function connectedItemsForUnderstanding(items) {
57
57
  });
58
58
  }
59
59
  function isPortraitCandidate(candidate) {
60
- return candidate.category === "preference" || candidate.category === "routine";
60
+ return candidate.category === "preference" || candidate.category === "routine" || candidate.category === "communication";
61
61
  }
62
62
  function durableEvidence(candidate, items) {
63
63
  const evidence = [...new Set(candidate.evidenceRefs ?? [])].flatMap((ref) => items.get(ref) ?? []);
@@ -120,7 +120,7 @@ async function deriveConnectedSourceUnderstanding(input) {
120
120
  type: "agent",
121
121
  id: input.agentId
122
122
  },
123
- kind: candidate.category,
123
+ kind: candidate.category === "communication" ? "preference" : candidate.category,
124
124
  value: candidate.statement,
125
125
  normalizedValue: candidate.statement.toLocaleLowerCase(),
126
126
  statement: candidate.statement,
@@ -129,8 +129,8 @@ async function deriveConnectedSourceUnderstanding(input) {
129
129
  inferredImportance: .65,
130
130
  consequence: "medium",
131
131
  actionability: .6,
132
- volatility: candidate.category === "routine" ? "slow" : "stable",
133
- sensitivity: "personal",
132
+ volatility: candidate.category === "routine" || candidate.category === "communication" ? "slow" : "stable",
133
+ sensitivity: "normal",
134
134
  disclosurePolicy: "referenceable",
135
135
  observedAt: evidenceItem.occurredAt ?? evidenceItem.modifiedAt ?? Date.now(),
136
136
  createdBy: "connector",
@@ -174,6 +174,12 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
174
174
  readonly en: "Read a typed user assertion.";
175
175
  readonly zh: "读取一条结构化用户事实。";
176
176
  };
177
+ }, {
178
+ readonly id: "user_context_update";
179
+ readonly description: {
180
+ readonly en: "Apply an explicit user correction to an existing assertion.";
181
+ readonly zh: "根据用户明确表达修正已有用户理解。";
182
+ };
177
183
  }, {
178
184
  readonly id: "knowledge_search";
179
185
  readonly description: {
@@ -265,4 +271,4 @@ export declare const GATEWAY_BUILTIN_TOOLS: readonly [{
265
271
  readonly zh: "使用已验证的参数执行选定的外部工具。";
266
272
  };
267
273
  }];
268
- export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "xopc_tool_execute" | "user_context_search" | "user_context_get" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
274
+ export declare const GATEWAY_BUILTIN_TOOL_IDS: ("automation" | "workflow" | "find" | "image" | "web_search" | "web_fetch" | "browser_use" | "grep" | "session_search" | "read_file" | "list_dir" | "write_file" | "apply_patch" | "exec_command" | "update_plan" | "todo" | "clarify" | "web_extract" | "image_generate" | "skills_list" | "skill_view" | "skill_manage" | "skills_marketplace_search" | "xopc_tool_search" | "xopc_tool_describe" | "xopc_tool_execute" | "user_context_search" | "user_context_get" | "user_context_update" | "knowledge_search" | "knowledge_get" | "knowledge_write" | "send_message" | "send_media" | "read_media" | "create_share" | "session_status" | "memory_maintenance" | "tool_manual" | "delegate_task" | "skill_install" | "text_to_speech" | "execute_code" | "create_desktop_pet")[];
@@ -199,6 +199,13 @@ const GATEWAY_BUILTIN_TOOLS = [
199
199
  zh: "读取一条结构化用户事实。"
200
200
  }
201
201
  },
202
+ {
203
+ id: "user_context_update",
204
+ description: {
205
+ en: "Apply an explicit user correction to an existing assertion.",
206
+ zh: "根据用户明确表达修正已有用户理解。"
207
+ }
208
+ },
202
209
  {
203
210
  id: "knowledge_search",
204
211
  description: {
@@ -1,6 +1,6 @@
1
+ import { getTunnelService } from "../tunnel/tunnel-service.js";
1
2
  import { resolveReverseProxyPublicUrl } from "./public-url.js";
2
3
  import { getTailscaleExposureState } from "./tailscale-lifecycle.js";
3
- import { getTunnelService } from "../tunnel/tunnel-service.js";
4
4
  import crypto from "node:crypto";
5
5
  //#region src/gateway/device-routes.ts
6
6
  function secureUrl(value) {
@@ -8,10 +8,10 @@ import { getProviderRegistry, init_plugin_registry } from "../../../providers/pl
8
8
  import { getAllProviders, init_providers, isProviderConfigured } from "../../../providers/index.js";
9
9
  import { normalizeConfiguredMcpServers } from "../../../config/mcp-config-normalize.js";
10
10
  import { resolveShareConfig } from "../../../share/share-config.js";
11
+ import { maskTunnelSecretForWeb } from "../../../tunnel/env.js";
11
12
  import { resolveSessionConfigForWeb, resolveUpdateConfigForWeb } from "../../../config/web-patch.js";
12
13
  import { GENERIC_MASKED_SECRET, maskSecretLength } from "./mask-secret-length.js";
13
14
  import { safeToolsWebForGet } from "../../config-tools-web.js";
14
- import { maskTunnelSecretForWeb } from "../../../tunnel/env.js";
15
15
  import { buildSafeProvidersConfigForWeb } from "./safe-providers-config.js";
16
16
  import { maskRealtimeVoiceConfigForWeb, maskSttConfigForWeb, maskTtsConfigForWeb } from "./safe-voice-config.js";
17
17
  //#region src/gateway/hono/lib/config-payload.ts