@xopcai/xopc 0.0.219 → 0.0.221

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 (172) 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-slG02hSm.js → activity-store-NItGQmvR.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DZ6ETNIk.js → agent-avatar-dicebear-B8SBTGg3.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agents-DxaIH0Ep.js → agents-Brs2-m6t.js} +1 -1
  6. package/dist/gateway/static/root/assets/{api-Tz57QxiN.js → api-53ZXsuyr.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-DdR1L4LR.js → app-management-settings-panel-BtmPXaqu.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-wYbwqmee.js → appearance-settings-t7HoJyNN.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-CyWr6KyO.js → apps-page-DJ_Dsb1j.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-DKXa160O.js → archive-plugin-D8o8CP9Y.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-CzwA9g2y.js → attachment-load-CsLXzas8.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-DwAXyWAY.js → automations-page-D-zgoAKz.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-workspace-CL7ieYIt.js → automations-workspace-DehLRXfd.js} +1 -1
  14. package/dist/gateway/static/root/assets/{binary-plugins-DoQ_DnT7.js → binary-plugins-B-MjP_22.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-Bj_Uxxng.js → block-editor-i4CfDqLG.js} +1 -1
  16. package/dist/gateway/static/root/assets/{browser-settings-page-BYa_FNC1.js → browser-settings-page-C3QIO4Ti.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-workflow-inputs-D4roXE6r.js → browser-workflow-inputs-Bi6RSSpD.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflows-page-CleKTAKD.js → browser-workflows-page-EEFHUm1i.js} +1 -1
  19. package/dist/gateway/static/root/assets/{capabilities-settings-panel-DYG37N0k.js → capabilities-settings-panel-BHhUp7FW.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capability-presets-api-wtEN6Ss6.js → capability-presets-api-pC2fno7r.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-C0Q4dFq-.js → capability-presets-settings-panel-DoClNVLz.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channel-recipient-api-DhuS2RJ3.js → channel-recipient-api-B5Szgu_z.js} +1 -1
  23. package/dist/gateway/static/root/assets/{channels-settings-CpO6Xg0n.js → channels-settings-Je-9a5ZC.js} +1 -1
  24. package/dist/gateway/static/root/assets/channels-status-swr-ByRbxC6z.js +1 -0
  25. package/dist/gateway/static/root/assets/{chat-terminal-dock-ClQMDe2n.js → chat-terminal-dock-DT-OFl4r.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connectors-page-BvyiPdKU.js → connectors-page-D8z9Trw4.js} +1 -1
  27. package/dist/gateway/static/root/assets/{cron-expression-4DvCFs-v.js → cron-expression-MZ_AJqrm.js} +1 -1
  28. package/dist/gateway/static/root/assets/{date-picker-B6FSjt4Z.js → date-picker-Bv9hZLuD.js} +1 -1
  29. package/dist/gateway/static/root/assets/{dependency-picker-Za18eMp1.js → dependency-picker-D-6oO_Vk.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-DUUf3yyJ.js → desktop-pet-CiI5caKj.js} +1 -1
  31. package/dist/gateway/static/root/assets/{desktop-pet-settings-Dwx3GfB8.js → desktop-pet-settings-DhkSOy4K.js} +1 -1
  32. package/dist/gateway/static/root/assets/{directory-picker-path-field-C6dfTCsl.js → directory-picker-path-field-C4s4Pz8I.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-debug-page-Cordpg4X.js → extension-debug-page-DE7J1-6W.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-page-Dw0dGyMl.js → extension-page-DSnACD7E.js} +1 -1
  35. package/dist/gateway/static/root/assets/{extension-settings-page-B2pUMaXm.js → extension-settings-page-Dk7k2Pok.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-config-api-DAZUOEQh.js → gateway-config-api-IOA1OlHx.js} +1 -1
  37. package/dist/gateway/static/root/assets/{gateway-config-swr-BIqRg-zo.js → gateway-config-swr-BzTbnu4O.js} +1 -1
  38. package/dist/gateway/static/root/assets/{gateway-settings-ik2f-pmV.js → gateway-settings-FX7QsgSQ.js} +1 -1
  39. package/dist/gateway/static/root/assets/{gateway-startup-retry-BFjWYOCS.js → gateway-startup-retry-B2zpkNvi.js} +1 -1
  40. package/dist/gateway/static/root/assets/{heartbeat-settings-BE81XJ8F.js → heartbeat-settings-D5CGVyci.js} +1 -1
  41. package/dist/gateway/static/root/assets/{home-page-BTWXJu_m.js → home-page-DzfZFZx5.js} +1 -1
  42. package/dist/gateway/static/root/assets/{image-generation-api-HXAWlgm6.js → image-generation-api-BXRjz-iY.js} +1 -1
  43. package/dist/gateway/static/root/assets/index-Dcj5KJRg.css +2 -0
  44. package/dist/gateway/static/root/assets/{index-B6gWYy08.js → index-EvA8c7fo.js} +11 -45
  45. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-ROqQ_Xlo.js → keyboard-shortcuts-settings-BjYiM4xq.js} +1 -1
  46. package/dist/gateway/static/root/assets/{local-app-workbench-page-Dcaf190G.js → local-app-workbench-page-hPyTaVYU.js} +1 -1
  47. package/dist/gateway/static/root/assets/{local-apps-page-Be79cyMG.js → local-apps-page-7DHvwSgA.js} +1 -1
  48. package/dist/gateway/static/root/assets/{locale-store-DfK-Hofd.js → locale-store-iKjqemWG.js} +1 -1
  49. package/dist/gateway/static/root/assets/{logs-page-C2pjbXno.js → logs-page-DW0xMKWP.js} +1 -1
  50. package/dist/gateway/static/root/assets/{management-settings-CRspx0oY.js → management-settings-BSxppo9Z.js} +1 -1
  51. package/dist/gateway/static/root/assets/{markdown-split-G3PTpGw3.js → markdown-split-D4oDjZtl.js} +1 -1
  52. package/dist/gateway/static/root/assets/{markdown-view-D4FPJZ91.js → markdown-view-DYkxMtJA.js} +1 -1
  53. package/dist/gateway/static/root/assets/{media-plugins-DT0P7j7u.js → media-plugins-BPNTGROA.js} +1 -1
  54. package/dist/gateway/static/root/assets/messages-kx5W39dO.js +3 -0
  55. package/dist/gateway/static/root/assets/{notes-api-q7HjYO07.js → notes-api-DJizatxh.js} +1 -1
  56. package/dist/gateway/static/root/assets/{notes-page-Cgl2h7AR.js → notes-page-DU5tKPTq.js} +1 -1
  57. package/dist/gateway/static/root/assets/{notes-workbench-DFMQYyGJ.js → notes-workbench-D669d98r.js} +2 -2
  58. package/dist/gateway/static/root/assets/pcm-capture-worklet-uW_SEACy.js +1 -0
  59. package/dist/gateway/static/root/assets/{product-open-page-ComKLO4D.js → product-open-page-CPoQvD6P.js} +1 -1
  60. package/dist/gateway/static/root/assets/{project-detail-page-DUFmQscH.js → project-detail-page-CpsQ9PTA.js} +1 -1
  61. package/dist/gateway/static/root/assets/{projects-page-CTWxt3dv.js → projects-page-CitO1LMc.js} +1 -1
  62. package/dist/gateway/static/root/assets/{registry-api-BBoJ7khF.js → registry-api-Cx3JxXSL.js} +1 -1
  63. package/dist/gateway/static/root/assets/{remote-access-hub-qmG-3qjj.js → remote-access-hub-C9-bL4V6.js} +1 -1
  64. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CXHQc53b.js → runtime-tools-settings-panel-xqnWcvIv.js} +1 -1
  65. package/dist/gateway/static/root/assets/{schema-form-3jTDF2lJ.js → schema-form-CuIDPYu6.js} +1 -1
  66. package/dist/gateway/static/root/assets/{sessions-page-D_We4_MV.js → sessions-page-CPSARi4y.js} +1 -1
  67. package/dist/gateway/static/root/assets/settings-advanced-gate-BxT80Fmr.js +1 -0
  68. package/dist/gateway/static/root/assets/{settings-form-section-CUDozALU.js → settings-form-section-DkAv9ncE.js} +1 -1
  69. package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3ZH6a6l.js → settings-loading-skeleton-BJUQiEKb.js} +1 -1
  70. package/dist/gateway/static/root/assets/{settings-page-tx29z21o.js → settings-page-KHRbLwmw.js} +1 -1
  71. package/dist/gateway/static/root/assets/{setup-status-panel-VunfXpTX.js → setup-status-panel-C8jd20Db.js} +1 -1
  72. package/dist/gateway/static/root/assets/{share-preview-page-MyThymEx.js → share-preview-page-WCVtJ3sX.js} +1 -1
  73. package/dist/gateway/static/root/assets/{shares-settings-DkZvY1cr.js → shares-settings-DrQ_cOXh.js} +1 -1
  74. package/dist/gateway/static/root/assets/skill-reload-api-C_4cG30x.js +1 -0
  75. package/dist/gateway/static/root/assets/{skills-page-BOOyMnno.js → skills-page-CKhR9J81.js} +1 -1
  76. package/dist/gateway/static/root/assets/{skills-page.utils-Bl5Yv3Cx.js → skills-page.utils-AYX-e5sD.js} +1 -1
  77. package/dist/gateway/static/root/assets/{system-settings-panel-DwQ3O1ta.js → system-settings-panel-IIF-K9ML.js} +1 -1
  78. package/dist/gateway/static/root/assets/{task-detail-page-BwOyrADL.js → task-detail-page-CYjsecEr.js} +1 -1
  79. package/dist/gateway/static/root/assets/{theme-store-Br4BtK4x.js → theme-store-BOD2D0dJ.js} +1 -1
  80. package/dist/gateway/static/root/assets/{use-autosave-DRS3RwS9.js → use-autosave-DcktF1j1.js} +1 -1
  81. package/dist/gateway/static/root/assets/{user-context-page-ClV2r3Cr.js → user-context-page-Cy1D2hkt.js} +1 -1
  82. package/dist/gateway/static/root/assets/{voice-api-key-field-CGTE5156.js → voice-api-key-field-BMkNTHHE.js} +1 -1
  83. package/dist/gateway/static/root/assets/{work-discovery-overlay-CW-HKD7h.js → work-discovery-overlay-DVoiXekA.js} +1 -1
  84. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Dtr9fDC8.js → workflow-run-setup-panel-Cw4LQjuM.js} +1 -1
  85. package/dist/gateway/static/root/assets/{workflows-page-CDOyNgZf.js → workflows-page-DKKH1_Yt.js} +1 -1
  86. package/dist/gateway/static/root/index.html +12 -12
  87. package/dist/package.js +1 -1
  88. package/dist/src/agent/agent-manager.js +3 -3
  89. package/dist/src/agent/embedded/model-runtime.js +1 -1
  90. package/dist/src/agent/embedded/run-for-session.js +1 -1
  91. package/dist/src/agent/image/tool-model-config.js +1 -1
  92. package/dist/src/agent/ipc/inbox.js +1 -1
  93. package/dist/src/agent/service.js +2 -2
  94. package/dist/src/agent/session/session-inspector.js +1 -1
  95. package/dist/src/agent/skills/hub-lock.js +1 -1
  96. package/dist/src/agent/tasks/task-judge-service.js +3 -3
  97. package/dist/src/ai-assist/text-assist.js +1 -1
  98. package/dist/src/auth/credentials.js +2 -2
  99. package/dist/src/auth/profiles/store.js +1 -1
  100. package/dist/src/auth/sync-provider-auth.js +2 -2
  101. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  102. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  103. package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
  104. package/dist/src/cli/commands/extension-marketplace.js +1 -1
  105. package/dist/src/cli/commands/extension.js +1 -1
  106. package/dist/src/cli/commands/models.js +1 -1
  107. package/dist/src/config/index.js +4 -4
  108. package/dist/src/config/loader.js +1 -1
  109. package/dist/src/config/models-json.js +1 -1
  110. package/dist/src/connectors/connected-source-understanding.js +6 -5
  111. package/dist/src/connectors/learning-coordinator.js +11 -2
  112. package/dist/src/extensions/lockfile.js +1 -1
  113. package/dist/src/extensions/update.js +1 -1
  114. package/dist/src/gateway/agents-admin.js +1 -1
  115. package/dist/src/gateway/file-path-classifier.js +1 -1
  116. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  117. package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
  118. package/dist/src/gateway/hono/routes/models.js +1 -1
  119. package/dist/src/gateway/hono/routes/understanding-sources.d.ts +9 -0
  120. package/dist/src/gateway/hono/routes/understanding-sources.js +47 -14
  121. package/dist/src/gateway/hono/routes/work-discovery.js +13 -3
  122. package/dist/src/gateway/service/agent-runner.d.ts +4 -0
  123. package/dist/src/gateway/service/agent-runner.js +6 -0
  124. package/dist/src/gateway/service/config-coordinator.js +2 -2
  125. package/dist/src/gateway/service/run-gateway-agent.js +13 -8
  126. package/dist/src/gateway/service/sessions-api.d.ts +9 -0
  127. package/dist/src/gateway/service/sessions-api.js +3 -0
  128. package/dist/src/gateway/service.js +5 -4
  129. package/dist/src/infra/update-runner.js +1 -1
  130. package/dist/src/knowledge/connected-knowledge-pipeline.d.ts +6 -0
  131. package/dist/src/knowledge/connected-knowledge-pipeline.js +35 -4
  132. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  133. package/dist/src/providers/index.js +2 -2
  134. package/dist/src/providers/model-registry.js +1 -1
  135. package/dist/src/providers/register-runtime-providers.js +1 -1
  136. package/dist/src/retrieval/queryProfile.d.ts +2 -0
  137. package/dist/src/retrieval/queryProfile.js +11 -1
  138. package/dist/src/storage/sqlite/index.d.ts +2 -2
  139. package/dist/src/storage/sqlite/index.js +3 -3
  140. package/dist/src/storage/sqlite/knowledge-repository.d.ts +5 -1
  141. package/dist/src/storage/sqlite/knowledge-repository.js +16 -1
  142. package/dist/src/storage/sqlite/memory-records-repository.d.ts +2 -0
  143. package/dist/src/storage/sqlite/memory-records-repository.js +21 -1
  144. package/dist/src/storage/sqlite/migrations/133_archive_legacy_work_discovery_profile_facts.sql +11 -0
  145. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  146. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  147. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  148. package/dist/src/storage/sqlite/schema.js +1 -1
  149. package/dist/src/storage/sqlite/session-repository.js +2 -2
  150. package/dist/src/tasks/home-query-service.d.ts +14 -0
  151. package/dist/src/tasks/home-query-service.js +19 -2
  152. package/dist/src/tui/tui-startup-resources.js +1 -1
  153. package/dist/src/tui/tui.js +1 -1
  154. package/dist/src/user-context/consolidation.d.ts +1 -0
  155. package/dist/src/user-context/consolidation.js +62 -2
  156. package/dist/src/user-context/focus-lifecycle.d.ts +2 -0
  157. package/dist/src/user-context/focus-lifecycle.js +26 -0
  158. package/dist/src/user-context/planner.js +46 -13
  159. package/dist/src/work-discovery/analyzer.js +6 -4
  160. package/dist/src/work-discovery/index.js +2 -2
  161. package/dist/src/work-discovery/service.d.ts +12 -3
  162. package/dist/src/work-discovery/service.js +164 -83
  163. package/dist/src/work-discovery/source-repository.d.ts +1 -0
  164. package/dist/src/work-discovery/source-repository.js +10 -4
  165. package/dist/src/work-discovery/types.d.ts +2 -1
  166. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  167. package/package.json +3 -3
  168. package/dist/gateway/static/root/assets/channels-status-swr-CXhPeiNj.js +0 -1
  169. package/dist/gateway/static/root/assets/index-CDkuz_YC.css +0 -2
  170. package/dist/gateway/static/root/assets/messages-B701TEZ5.js +0 -3
  171. package/dist/gateway/static/root/assets/settings-advanced-gate-B_QhPgU0.js +0 -1
  172. package/dist/gateway/static/root/assets/skill-reload-api-DVDOh1iY.js +0 -1
@@ -6,7 +6,10 @@ import { ActivityService } from "../activity/service.js";
6
6
  import { getAgentDefaultModelRef, init_schema } from "../config/schema.js";
7
7
  import { buildSessionKey, init_session_key } from "../routing/session-key.js";
8
8
  import { getDefaultAgentId, init_resolve_route } from "../routing/resolve-route.js";
9
- import { createUnderstandingSourceRun, getUnderstandingSourceRun, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant, upsertUserFocus } from "../user-context/sources/repository.js";
9
+ import { init_providers, resolveModel } from "../providers/index.js";
10
+ import { isLocalModelBaseUrl } from "../providers/model-call.js";
11
+ import { createUnderstandingSourceRun, getUnderstandingSourceRun, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceGrantPolicies, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant, upsertUserFocus } from "../user-context/sources/repository.js";
12
+ import { focusLifecycle } from "../user-context/focus-lifecycle.js";
10
13
  import { allowsRemoteSourceProcessing } from "../user-context/sources/processing-policy.js";
11
14
  import { analyzeUnderstandingSources, analyzeWorkContext, workDiscoveryResultMarkdown } from "./analyzer.js";
12
15
  import { previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, summarizeWorkContextSnapshot } from "./probe.js";
@@ -23,14 +26,141 @@ import { getWorkDiscoveryDirectorySource, listWorkDiscoveryDirectorySources, rev
23
26
  import { createHash, randomUUID } from "node:crypto";
24
27
  //#region src/work-discovery/service.ts
25
28
  init_schema();
29
+ init_providers();
26
30
  init_session_key();
27
31
  init_resolve_route();
28
32
  init_logger();
29
33
  const log = createLogger("WorkDiscovery");
34
+ const MAX_UNDERSTANDING_ITEMS = 150;
35
+ const MAX_UNDERSTANDING_INPUT_ITEMS = 1200;
36
+ const MAX_UNDERSTANDING_ITEM_CHARS = 12e3;
37
+ const MAX_UNDERSTANDING_TOTAL_CHARS = 3e5;
38
+ function modelProcessingTarget(config) {
39
+ const modelRef = getAgentDefaultModelRef(config);
40
+ if (!modelRef) throw new Error("No default model configured");
41
+ const model = resolveModel(modelRef);
42
+ return {
43
+ provider: model.provider,
44
+ remoteModel: !isLocalModelBaseUrl(model.baseUrl)
45
+ };
46
+ }
47
+ function fairTextBudgets(lengths, budget) {
48
+ const allocations = lengths.map(() => 0);
49
+ let remaining = budget;
50
+ let active = lengths.map((length, index) => ({
51
+ length,
52
+ index
53
+ })).filter((item) => item.length > 0);
54
+ while (remaining > 0 && active.length > 0) {
55
+ const share = Math.max(1, Math.floor(remaining / active.length));
56
+ const next = [];
57
+ for (const item of active) {
58
+ const needed = item.length - allocations[item.index];
59
+ const granted = Math.min(needed, share, remaining);
60
+ allocations[item.index] = allocations[item.index] + granted;
61
+ remaining -= granted;
62
+ if (allocations[item.index] < item.length) next.push(item);
63
+ if (remaining === 0) break;
64
+ }
65
+ active = next;
66
+ }
67
+ return allocations;
68
+ }
69
+ /** Sanitize and round-robin local sources so one verbose source cannot starve the rest. */
70
+ function normalizeUnderstandingSourceItems(rawItems) {
71
+ const itemTypes = new Set([
72
+ "document",
73
+ "calendar_event",
74
+ "task",
75
+ "note",
76
+ "mail",
77
+ "message",
78
+ "code_activity",
79
+ "bookmark"
80
+ ]);
81
+ const ownerAttributions = new Set([
82
+ "user",
83
+ "other",
84
+ "shared",
85
+ "unknown"
86
+ ]);
87
+ const sensitivities = new Set([
88
+ "normal",
89
+ "personal",
90
+ "secret",
91
+ "regulated"
92
+ ]);
93
+ const sanitized = rawItems.slice(0, MAX_UNDERSTANDING_INPUT_ITEMS).flatMap((value) => {
94
+ if (!value || typeof value !== "object") return [];
95
+ const raw = value;
96
+ const id = typeof raw.id === "string" ? raw.id.trim().slice(0, 500) : "";
97
+ const sourceId = typeof raw.sourceId === "string" ? raw.sourceId.trim().slice(0, 200) : "";
98
+ const title = typeof raw.title === "string" ? raw.title.trim().slice(0, 300) : "";
99
+ const type = typeof raw.type === "string" && itemTypes.has(raw.type) ? raw.type : null;
100
+ const evidenceRef = typeof raw.evidenceRef === "string" ? raw.evidenceRef.trim().slice(0, 1e3) : "";
101
+ const ownerAttribution = typeof raw.ownerAttribution === "string" && ownerAttributions.has(raw.ownerAttribution) ? raw.ownerAttribution : "unknown";
102
+ const sensitivity = typeof raw.sensitivity === "string" && sensitivities.has(raw.sensitivity) ? raw.sensitivity : "personal";
103
+ if (!id || !isLocalUnderstandingSourceId(sourceId) || !title || !type || !evidenceRef.startsWith(`${sourceId}://`) || sensitivity === "secret" || sensitivity === "regulated") return [];
104
+ const timestamp = (key) => {
105
+ const candidate = raw[key];
106
+ return typeof candidate === "number" && Number.isFinite(candidate) ? candidate : void 0;
107
+ };
108
+ const resourceUri = (() => {
109
+ if (typeof raw.resourceUri !== "string") return void 0;
110
+ try {
111
+ const url = new URL(raw.resourceUri.trim());
112
+ if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash || url.pathname && url.pathname !== "/") return void 0;
113
+ return url.origin.slice(0, 1e3);
114
+ } catch {
115
+ return;
116
+ }
117
+ })();
118
+ const text = typeof raw.text === "string" ? raw.text.trim().slice(0, MAX_UNDERSTANDING_ITEM_CHARS) : "";
119
+ return [{
120
+ id,
121
+ sourceId,
122
+ type,
123
+ title,
124
+ ownerAttribution,
125
+ sensitivity,
126
+ evidenceRef,
127
+ ...text ? { text } : {},
128
+ ...typeof raw.group === "string" && raw.group.trim() ? { group: raw.group.trim().slice(0, 200) } : {},
129
+ ...resourceUri ? { resourceUri } : {},
130
+ ...timestamp("occurredAt") != null ? { occurredAt: timestamp("occurredAt") } : {},
131
+ ...timestamp("modifiedAt") != null ? { modifiedAt: timestamp("modifiedAt") } : {},
132
+ ...timestamp("startsAt") != null ? { startsAt: timestamp("startsAt") } : {},
133
+ ...timestamp("endsAt") != null ? { endsAt: timestamp("endsAt") } : {}
134
+ }];
135
+ });
136
+ const bySource = /* @__PURE__ */ new Map();
137
+ for (const item of sanitized) bySource.set(item.sourceId, [...bySource.get(item.sourceId) ?? [], item]);
138
+ const selected = [];
139
+ let round = 0;
140
+ while (selected.length < MAX_UNDERSTANDING_ITEMS) {
141
+ let added = false;
142
+ for (const sourceItems of bySource.values()) {
143
+ const item = sourceItems[round];
144
+ if (!item) continue;
145
+ selected.push(item);
146
+ added = true;
147
+ if (selected.length === MAX_UNDERSTANDING_ITEMS) break;
148
+ }
149
+ if (!added) break;
150
+ round += 1;
151
+ }
152
+ const budgets = fairTextBudgets(selected.map((item) => item.text?.length ?? 0), MAX_UNDERSTANDING_TOTAL_CHARS);
153
+ return selected.map((item, index) => {
154
+ const text = item.text?.slice(0, budgets[index]);
155
+ return {
156
+ ...item,
157
+ ...text ? { text } : { text: void 0 }
158
+ };
159
+ });
160
+ }
30
161
  function understandingKind(category) {
31
162
  if (category === "preference") return "preference";
32
- if (category === "workflow") return "routine";
33
- if (category === "focus") return "current_state";
163
+ if (category === "routine") return "routine";
34
164
  return "project_context";
35
165
  }
36
166
  function understandingKey(candidate) {
@@ -57,7 +187,7 @@ function persistUnderstandingCandidate(candidate, scope, sourceRef) {
57
187
  status: "candidate",
58
188
  scope,
59
189
  explicitness: "inferred",
60
- durability: candidate.category === "focus" ? "ephemeral" : candidate.category === "workflow" ? "recurring" : "durable",
190
+ durability: candidate.category === "routine" ? "recurring" : "durable",
61
191
  sensitivity: "normal",
62
192
  disclosurePolicy: "referenceable",
63
193
  confidence: candidate.confidence === "high" ? .9 : candidate.confidence === "medium" ? .72 : .58,
@@ -175,12 +305,17 @@ var WorkDiscoveryService = class {
175
305
  listDirectorySources() {
176
306
  return listWorkDiscoveryDirectorySources();
177
307
  }
178
- async grantDirectorySource(rootPath) {
308
+ getModelProcessingTarget() {
309
+ return modelProcessingTarget(this.options.getConfig());
310
+ }
311
+ async grantDirectorySource(rootPath, processingPolicy) {
179
312
  const preview = await previewWorkDiscoveryRoot(rootPath);
313
+ const target = this.getModelProcessingTarget();
180
314
  return upsertWorkDiscoveryDirectorySource({
181
315
  rootPath: preview.canonicalRootPath,
182
316
  displayName: preview.displayName,
183
- fingerprint: preview.fingerprint
317
+ fingerprint: preview.fingerprint,
318
+ processingPolicy: target.remoteModel ? processingPolicy : "local_only"
184
319
  });
185
320
  }
186
321
  async checkDirectorySources() {
@@ -244,75 +379,11 @@ var WorkDiscoveryService = class {
244
379
  revokeDirectorySource(id) {
245
380
  return revokeWorkDiscoveryDirectorySource(id);
246
381
  }
247
- async importUnderstandingSources(rawItems, signal, runId, rawCheckpoints) {
248
- let remaining = 3e5;
249
- const itemTypes = new Set([
250
- "document",
251
- "calendar_event",
252
- "task",
253
- "note",
254
- "mail",
255
- "message",
256
- "code_activity",
257
- "bookmark"
258
- ]);
259
- const ownerAttributions = new Set([
260
- "user",
261
- "other",
262
- "shared",
263
- "unknown"
264
- ]);
265
- const sensitivities = new Set([
266
- "normal",
267
- "personal",
268
- "secret",
269
- "regulated"
270
- ]);
271
- const items = rawItems.flatMap((value) => {
272
- if (!value || typeof value !== "object" || remaining <= 0) return [];
273
- const raw = value;
274
- const id = typeof raw.id === "string" ? raw.id.trim().slice(0, 500) : "";
275
- const sourceId = typeof raw.sourceId === "string" ? raw.sourceId.trim().slice(0, 200) : "";
276
- const title = typeof raw.title === "string" ? raw.title.trim().slice(0, 300) : "";
277
- const type = typeof raw.type === "string" && itemTypes.has(raw.type) ? raw.type : null;
278
- const evidenceRef = typeof raw.evidenceRef === "string" ? raw.evidenceRef.trim().slice(0, 1e3) : "";
279
- const ownerAttribution = typeof raw.ownerAttribution === "string" && ownerAttributions.has(raw.ownerAttribution) ? raw.ownerAttribution : "unknown";
280
- const sensitivity = typeof raw.sensitivity === "string" && sensitivities.has(raw.sensitivity) ? raw.sensitivity : "personal";
281
- if (!id || !isLocalUnderstandingSourceId(sourceId) || !title || !type || !evidenceRef.startsWith(`${sourceId}://`) || sensitivity === "secret" || sensitivity === "regulated") return [];
282
- const text = typeof raw.text === "string" ? raw.text.trim().slice(0, Math.min(12e3, remaining)) : "";
283
- remaining -= text.length;
284
- const timestamp = (key) => {
285
- const candidate = raw[key];
286
- return typeof candidate === "number" && Number.isFinite(candidate) ? candidate : void 0;
287
- };
288
- const resourceUri = (() => {
289
- if (typeof raw.resourceUri !== "string") return void 0;
290
- try {
291
- const url = new URL(raw.resourceUri.trim());
292
- if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.search || url.hash || url.pathname && url.pathname !== "/") return void 0;
293
- return url.origin.slice(0, 1e3);
294
- } catch {
295
- return;
296
- }
297
- })();
298
- return [{
299
- id,
300
- sourceId,
301
- type,
302
- title,
303
- ownerAttribution,
304
- sensitivity,
305
- evidenceRef,
306
- ...text ? { text } : {},
307
- ...typeof raw.group === "string" && raw.group.trim() ? { group: raw.group.trim().slice(0, 200) } : {},
308
- ...resourceUri ? { resourceUri } : {},
309
- ...timestamp("occurredAt") != null ? { occurredAt: timestamp("occurredAt") } : {},
310
- ...timestamp("modifiedAt") != null ? { modifiedAt: timestamp("modifiedAt") } : {},
311
- ...timestamp("startsAt") != null ? { startsAt: timestamp("startsAt") } : {},
312
- ...timestamp("endsAt") != null ? { endsAt: timestamp("endsAt") } : {}
313
- }];
314
- }).slice(0, 150);
382
+ async importUnderstandingSources(rawItems, processingPolicy, signal, runId, rawCheckpoints) {
383
+ const items = normalizeUnderstandingSourceItems(rawItems);
315
384
  if (!items.length) throw new Error("No readable understanding source items were provided");
385
+ const target = this.getModelProcessingTarget();
386
+ const effectiveProcessingPolicy = target.remoteModel ? processingPolicy : "local_only";
316
387
  const checkpoints = /* @__PURE__ */ new Map();
317
388
  for (const [sourceId, value] of Object.entries(rawCheckpoints ?? {})) {
318
389
  if (!isLocalUnderstandingSourceId(sourceId) || !value || typeof value !== "object") continue;
@@ -330,7 +401,7 @@ var WorkDiscoveryService = class {
330
401
  const sourceItems = items.filter((item) => item.sourceId === sourceId);
331
402
  const category = sourceItems.some((item) => item.type === "calendar_event") ? "calendar" : sourceItems.some((item) => item.type === "task") ? "tasks" : sourceItems.some((item) => item.type === "note") ? "notes" : sourceItems.some((item) => item.type === "mail") ? "mail" : sourceItems.some((item) => item.type === "message") ? "messages" : sourceItems.some((item) => item.type === "code_activity") ? "code_activity" : "recent_documents";
332
403
  const platform = sourceId.startsWith("apple-") ? "darwin" : sourceId.startsWith("windows-") ? "win32" : sourceId.startsWith("linux-") ? "linux" : "all";
333
- const grant = upsertUnderstandingSourceGrant({
404
+ let grant = upsertUnderstandingSourceGrant({
334
405
  sourceKey: `understanding-source:${sourceId}`,
335
406
  adapterId: sourceId,
336
407
  category,
@@ -338,9 +409,10 @@ var WorkDiscoveryService = class {
338
409
  displayName: sourceId,
339
410
  accessMode: "once",
340
411
  retentionPolicy: "derived_only",
341
- processingPolicy: "local_only",
412
+ processingPolicy: effectiveProcessingPolicy,
342
413
  config: { readOnly: true }
343
414
  });
415
+ if (grant.processingPolicy !== effectiveProcessingPolicy) grant = updateUnderstandingSourceGrantPolicies(grant.id, { processingPolicy: effectiveProcessingPolicy }) ?? grant;
344
416
  sourceGrants.set(sourceId, grant);
345
417
  const checkpoint = checkpoints.get(sourceId);
346
418
  const previousFingerprint = typeof grant.checkpoint.fingerprint === "string" ? grant.checkpoint.fingerprint : void 0;
@@ -394,7 +466,7 @@ var WorkDiscoveryService = class {
394
466
  const linkedRun = runId ? getWorkDiscoveryRun(runId) : null;
395
467
  let analysis;
396
468
  try {
397
- analysis = allowsRemoteSourceProcessing([...changedSourceIds].map((sourceId) => sourceGrants.get(sourceId)?.processingPolicy ?? "local_only")) ? await analyzeUnderstandingSources({
469
+ analysis = !target.remoteModel || allowsRemoteSourceProcessing([...changedSourceIds].map((sourceId) => sourceGrants.get(sourceId)?.processingPolicy ?? "local_only")) ? await analyzeUnderstandingSources({
398
470
  config: this.options.getConfig(),
399
471
  items: analysisItems,
400
472
  ...linkedRun?.result ? { workContext: {
@@ -535,7 +607,8 @@ var WorkDiscoveryService = class {
535
607
  status: "candidate",
536
608
  confidence: topic.confidence,
537
609
  evidenceRefs: topic.evidenceRefs,
538
- sourceRunId: sourceRuns.get(topic.sourceIds[0] ?? "")
610
+ sourceRunId: sourceRuns.get(topic.sourceIds[0] ?? ""),
611
+ ...focusLifecycle(topic.horizon)
539
612
  }));
540
613
  const modelFocuses = safeWorkThreadCandidates.filter((candidate) => !candidate.evidenceRefs.some((ref) => activityEvidence.has(ref))).map((candidate) => upsertUserFocus({
541
614
  canonicalKey: `source-focus:${candidate.topicKey}`,
@@ -545,7 +618,8 @@ var WorkDiscoveryService = class {
545
618
  status: "candidate",
546
619
  confidence: candidate.confidence === "high" ? .9 : candidate.confidence === "medium" ? .72 : .55,
547
620
  evidenceRefs: candidate.evidenceRefs,
548
- sourceRunId: sourceRuns.get(candidate.evidenceRefs[0]?.split("://", 1)[0] ?? "")
621
+ sourceRunId: sourceRuns.get(candidate.evidenceRefs[0]?.split("://", 1)[0] ?? ""),
622
+ ...focusLifecycle(candidate.horizon)
549
623
  }));
550
624
  const focuses = [...activityFocuses, ...modelFocuses];
551
625
  log.info({
@@ -579,7 +653,8 @@ var WorkDiscoveryService = class {
579
653
  upsertWorkDiscoveryDirectorySource({
580
654
  rootPath: preview.canonicalRootPath,
581
655
  displayName: preview.displayName,
582
- fingerprint: preview.fingerprint
656
+ fingerprint: preview.fingerprint,
657
+ processingPolicy: source.processingPolicy
583
658
  });
584
659
  return this.startRun({
585
660
  rootPath: preview.canonicalRootPath,
@@ -591,6 +666,7 @@ var WorkDiscoveryService = class {
591
666
  const candidates = await this.discoverCandidates();
592
667
  const primary = candidates[0];
593
668
  if (!primary) throw new Error("No accessible work projects were found");
669
+ await this.grantDirectorySource(primary.rootPath, input.processingPolicy);
594
670
  return this.startRun({
595
671
  rootPath: primary.rootPath,
596
672
  source: "onboarding_selected_directory",
@@ -605,6 +681,9 @@ var WorkDiscoveryService = class {
605
681
  const modelRef = getAgentDefaultModelRef(config);
606
682
  if (!modelRef) throw new Error("No default model configured");
607
683
  const rootPath = (await previewWorkDiscoveryRoot(input.rootPath)).canonicalRootPath;
684
+ const approvedSource = listWorkDiscoveryDirectorySources().find((source) => source.rootPath === rootPath && source.status === "active");
685
+ if (!approvedSource) throw new Error("Selected folder must be approved before analysis");
686
+ if (modelProcessingTarget(config).remoteModel && approvedSource.processingPolicy !== "remote_allowed") throw new Error("Remote model analysis requires explicit processing permission for this folder");
608
687
  const agentId = getDefaultAgentId(config);
609
688
  const match = this.options.projects.resolveOrCreateForWorkspacePath({
610
689
  workspacePath: rootPath,
@@ -798,7 +877,8 @@ var WorkDiscoveryService = class {
798
877
  type: "project",
799
878
  id: run.projectId
800
879
  },
801
- evidenceRefs: thread.evidenceIds
880
+ evidenceRefs: thread.evidenceIds,
881
+ ...focusLifecycle(thread.horizon)
802
882
  }));
803
883
  const result = this.persistProfileCandidates(run, {
804
884
  ...baseResult,
@@ -1037,7 +1117,8 @@ var WorkDiscoveryService = class {
1037
1117
  id: run.projectId
1038
1118
  },
1039
1119
  explicitness: "explicit",
1040
- evidenceRefs: [`session://${createHash("sha256").update(run.sessionKey).digest("hex").slice(0, 16)}/recognition`]
1120
+ evidenceRefs: [`session://${createHash("sha256").update(run.sessionKey).digest("hex").slice(0, 16)}/recognition`],
1121
+ ...focusLifecycle("current")
1041
1122
  });
1042
1123
  const investigation = getWorkUnderstandingInvestigationForRun(run.id);
1043
1124
  if (investigation && input.decision !== "dismissed") {
@@ -1142,4 +1223,4 @@ var WorkDiscoveryService = class {
1142
1223
  }
1143
1224
  };
1144
1225
  //#endregion
1145
- export { WorkDiscoveryService };
1226
+ export { WorkDiscoveryService, normalizeUnderstandingSourceItems };
@@ -7,6 +7,7 @@ export declare function upsertWorkDiscoveryDirectorySource(input: {
7
7
  rootPath: string;
8
8
  displayName: string;
9
9
  fingerprint?: WorkDiscoveryPreview['fingerprint'];
10
+ processingPolicy?: 'local_only' | 'remote_allowed';
10
11
  scanned?: boolean;
11
12
  nowMs?: number;
12
13
  }): WorkDiscoveryDirectorySource;
@@ -1,4 +1,4 @@
1
- import { getUnderstandingSourceGrant, listUnderstandingSourceGrants, revokeUnderstandingSourceGrant, upsertUnderstandingSourceGrant } from "../user-context/sources/repository.js";
1
+ import { getUnderstandingSourceGrant, listUnderstandingSourceGrants, revokeUnderstandingSourceGrant, updateUnderstandingSourceGrantPolicies, upsertUnderstandingSourceGrant } from "../user-context/sources/repository.js";
2
2
  //#region src/work-discovery/source-repository.ts
3
3
  const ADAPTER_ID = "local-work-folders";
4
4
  function fingerprint(value) {
@@ -15,6 +15,7 @@ function directorySource(grant) {
15
15
  displayName: grant.displayName,
16
16
  status: grant.status,
17
17
  scope: { readOnly: true },
18
+ processingPolicy: grant.processingPolicy,
18
19
  ...fingerprint(grant.checkpoint) ? { fingerprint: fingerprint(grant.checkpoint) } : {},
19
20
  ...grant.lastCollectedAt != null ? { lastScannedAt: grant.lastCollectedAt } : {},
20
21
  createdAt: grant.createdAt,
@@ -32,7 +33,7 @@ function getWorkDiscoveryDirectorySource(id) {
32
33
  }
33
34
  function upsertWorkDiscoveryDirectorySource(input) {
34
35
  const existing = listUnderstandingSourceGrants({ includeRevoked: true }).find((grant) => grant.adapterId === ADAPTER_ID && grant.config.rootPath === input.rootPath);
35
- return directorySource(upsertUnderstandingSourceGrant({
36
+ let grant = upsertUnderstandingSourceGrant({
36
37
  sourceKey: `local-work-folder:${input.rootPath}`,
37
38
  adapterId: ADAPTER_ID,
38
39
  category: "files",
@@ -40,7 +41,7 @@ function upsertWorkDiscoveryDirectorySource(input) {
40
41
  displayName: input.displayName,
41
42
  accessMode: "continuous",
42
43
  retentionPolicy: "derived_only",
43
- processingPolicy: "local_only",
44
+ processingPolicy: input.processingPolicy ?? existing?.processingPolicy ?? "local_only",
44
45
  config: {
45
46
  rootPath: input.rootPath,
46
47
  readOnly: true
@@ -51,7 +52,12 @@ function upsertWorkDiscoveryDirectorySource(input) {
51
52
  } : existing?.checkpoint,
52
53
  ...input.scanned ? { lastCollectedAt: input.nowMs ?? Date.now() } : {},
53
54
  ...input.nowMs != null ? { nowMs: input.nowMs } : {}
54
- }));
55
+ });
56
+ if (input.processingPolicy && grant.processingPolicy !== input.processingPolicy) grant = updateUnderstandingSourceGrantPolicies(grant.id, {
57
+ processingPolicy: input.processingPolicy,
58
+ ...input.nowMs != null ? { nowMs: input.nowMs } : {}
59
+ }) ?? grant;
60
+ return directorySource(grant);
55
61
  }
56
62
  function revokeWorkDiscoveryDirectorySource(id, nowMs = Date.now()) {
57
63
  if (!getWorkDiscoveryDirectorySource(id)) return null;
@@ -34,6 +34,7 @@ export interface WorkDiscoveryDirectorySource {
34
34
  scope: {
35
35
  readOnly: true;
36
36
  };
37
+ processingPolicy: 'local_only' | 'remote_allowed';
37
38
  fingerprint?: WorkDiscoveryPreview['fingerprint'];
38
39
  lastScannedAt?: number;
39
40
  createdAt: number;
@@ -165,7 +166,7 @@ export interface WorkDiscoveryResult {
165
166
  export interface WorkDiscoveryProfileCandidate {
166
167
  id: string;
167
168
  understandingId?: string;
168
- category: 'role' | 'focus' | 'technology' | 'workflow' | 'preference';
169
+ category: 'role' | 'responsibility' | 'preference' | 'routine';
169
170
  statement: string;
170
171
  confidence: 'high' | 'medium' | 'low';
171
172
  evidence: string[];
@@ -1,6 +1,6 @@
1
1
  import { getDefaultAgentId, init_resolve_route } from "../../routing/resolve-route.js";
2
- import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
3
2
  import { init_providers, resolveModel } from "../../providers/index.js";
3
+ import { extractProfileAgentId, resolveEffectiveAgentProfileForSession } from "../../config/agent-profile.js";
4
4
  import { TaskRepository } from "../../tasks/task-repository.js";
5
5
  import { TaskConversationRepository } from "../../tasks/task-conversation-repository.js";
6
6
  import { TaskRunRepository } from "../../tasks/task-run-repository.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xopcai/xopc",
3
- "version": "0.0.219",
3
+ "version": "0.0.221",
4
4
  "description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -163,10 +163,10 @@
163
163
  "vitepress": "^1.6.4",
164
164
  "vitest": "4.1.5",
165
165
  "vue": "^3.5.35",
166
+ "@xopcai/endpoint-tools-protocol": "0.0.0",
166
167
  "@xopcai/gateway-contract": "0.0.0",
167
168
  "@xopcai/realtime-protocol": "0.0.0",
168
- "@xopcai/realtime-client": "0.0.0",
169
- "@xopcai/endpoint-tools-protocol": "0.0.0"
169
+ "@xopcai/realtime-client": "0.0.0"
170
170
  },
171
171
  "scripts": {
172
172
  "assets:brand": "node scripts/generate-brand-assets.mjs",
@@ -1 +0,0 @@
1
- import{r as e}from"./locale-store-DfK-Hofd.js";import{n as t}from"./channel-recipient-api-DhuS2RJ3.js";function n(){return e(`/api/channels/status`)}var r=t;export{r as n,n as t};