@xopcai/xopc 0.0.228 → 0.0.229

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 (129) 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/{agent-avatar-dicebear-CjGZBs4C.js → agent-avatar-dicebear-CsFAJTIN.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agents-B0NI4_NI.js → agents-DA4b6_0C.js} +1 -1
  5. package/dist/gateway/static/root/assets/{app-management-settings-panel--SjycrXk.js → app-management-settings-panel-7KcMWuah.js} +1 -1
  6. package/dist/gateway/static/root/assets/{appearance-settings-8G-TVUtg.js → appearance-settings-Cqlw7Fif.js} +1 -1
  7. package/dist/gateway/static/root/assets/{apps-page-2NiqD-YP.js → apps-page-CsnhdGZ2.js} +1 -1
  8. package/dist/gateway/static/root/assets/{attachment-load-Bx44zSpz.js → attachment-load-q4pDpqkF.js} +1 -1
  9. package/dist/gateway/static/root/assets/{automations-page-CrKAHqc0.js → automations-page-BuTqjKGX.js} +1 -1
  10. package/dist/gateway/static/root/assets/{automations-workspace-Q3g9cf0h.js → automations-workspace-CD0E2ThS.js} +1 -1
  11. package/dist/gateway/static/root/assets/{binary-plugins-DjDwnHAQ.js → binary-plugins-DUce1Bsc.js} +1 -1
  12. package/dist/gateway/static/root/assets/{block-editor-7aMOKoZM.js → block-editor-D8Ejp-QR.js} +1 -1
  13. package/dist/gateway/static/root/assets/{browser-settings-page-DTwPkmAC.js → browser-settings-page-CY1k3MMd.js} +1 -1
  14. package/dist/gateway/static/root/assets/{browser-workflows-page-DVLrWKz_.js → browser-workflows-page-BDvZbR9v.js} +1 -1
  15. package/dist/gateway/static/root/assets/{capabilities-settings-panel-YcP4FbN7.js → capabilities-settings-panel-D1VfotHQ.js} +1 -1
  16. package/dist/gateway/static/root/assets/{capability-presets-settings-panel-AcPjHHia.js → capability-presets-settings-panel-DXHqRLpU.js} +1 -1
  17. package/dist/gateway/static/root/assets/{channels-settings-Ca94Q1D-.js → channels-settings-DrFL57M_.js} +1 -1
  18. package/dist/gateway/static/root/assets/{chat-terminal-dock-BR-_7KC0.js → chat-terminal-dock-h1CKexNz.js} +1 -1
  19. package/dist/gateway/static/root/assets/{connectors-page-SGxfLTd6.js → connectors-page-DUAyfFCF.js} +1 -1
  20. package/dist/gateway/static/root/assets/{cron-expression-D8-c-Tkw.js → cron-expression-DlaQQOId.js} +1 -1
  21. package/dist/gateway/static/root/assets/{date-picker-kV-Jyl9J.js → date-picker-8R1sXJKb.js} +1 -1
  22. package/dist/gateway/static/root/assets/{dependency-picker-CwKcrfGj.js → dependency-picker-CWur0821.js} +1 -1
  23. package/dist/gateway/static/root/assets/{desktop-pet-D9rnchu3.js → desktop-pet-Knl-zNDU.js} +1 -1
  24. package/dist/gateway/static/root/assets/{desktop-pet-settings-CTs5WGzk.js → desktop-pet-settings-CAQMLVtd.js} +1 -1
  25. package/dist/gateway/static/root/assets/{directory-picker-path-field-CCl0aaDm.js → directory-picker-path-field-Caaz4Rw5.js} +1 -1
  26. package/dist/gateway/static/root/assets/{extension-debug-page-Cau40SvC.js → extension-debug-page-B965Mc15.js} +1 -1
  27. package/dist/gateway/static/root/assets/{extension-page-BsJXdvIL.js → extension-page-C0UnkBi5.js} +1 -1
  28. package/dist/gateway/static/root/assets/{extension-settings-page-qWqJyF7-.js → extension-settings-page-BUSIAZCR.js} +1 -1
  29. package/dist/gateway/static/root/assets/{gateway-config-api-BI0SELXm.js → gateway-config-api-DkH0eEgy.js} +1 -1
  30. package/dist/gateway/static/root/assets/{gateway-settings-6ZdOIC7F.js → gateway-settings-BBgLDm6I.js} +1 -1
  31. package/dist/gateway/static/root/assets/{heartbeat-settings-KBwhXeFD.js → heartbeat-settings-BtEHVXWD.js} +1 -1
  32. package/dist/gateway/static/root/assets/{home-page-BA2M4CLi.js → home-page-5SU2TNJj.js} +1 -1
  33. package/dist/gateway/static/root/assets/{index-BX0dz1JK.js → index-BNWhgmjs.js} +8 -8
  34. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-kHtpnyEm.js → keyboard-shortcuts-settings-CsRz8NrS.js} +1 -1
  35. package/dist/gateway/static/root/assets/{local-app-workbench-page-D2nkn09R.js → local-app-workbench-page-DYPEUgpP.js} +1 -1
  36. package/dist/gateway/static/root/assets/{local-apps-page-BCXa0oUa.js → local-apps-page-CTBNUG4a.js} +1 -1
  37. package/dist/gateway/static/root/assets/{logs-page-D3sNst0K.js → logs-page-B0P7rG2B.js} +1 -1
  38. package/dist/gateway/static/root/assets/{management-settings-tHnlfOAQ.js → management-settings-YqUAEwQo.js} +1 -1
  39. package/dist/gateway/static/root/assets/{markdown-split-BMLqHHr5.js → markdown-split-dxpSCXb8.js} +1 -1
  40. package/dist/gateway/static/root/assets/{media-plugins-DybwqTgv.js → media-plugins-CJ00i1Lg.js} +1 -1
  41. package/dist/gateway/static/root/assets/{notes-page-C24SfF6r.js → notes-page-DEnbnkIt.js} +1 -1
  42. package/dist/gateway/static/root/assets/{notes-workbench-CTdZc3ov.js → notes-workbench-DmVYu_Oc.js} +2 -2
  43. package/dist/gateway/static/root/assets/{product-open-page-DBfCVlJq.js → product-open-page-BHxo9U95.js} +1 -1
  44. package/dist/gateway/static/root/assets/{project-detail-page-COHaEpbA.js → project-detail-page-DV2nGmsq.js} +1 -1
  45. package/dist/gateway/static/root/assets/{projects-page-lMnST7D_.js → projects-page-BNIFwFfc.js} +1 -1
  46. package/dist/gateway/static/root/assets/{remote-access-hub-BIRKBvO_.js → remote-access-hub-DLXqKiA_.js} +1 -1
  47. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BPEGTip5.js → runtime-tools-settings-panel-BpQ2GI-0.js} +1 -1
  48. package/dist/gateway/static/root/assets/{schema-form-Dxlu60Td.js → schema-form-HE1G26Lx.js} +1 -1
  49. package/dist/gateway/static/root/assets/{sessions-page-CATO9G3y.js → sessions-page-DWaXf_25.js} +1 -1
  50. package/dist/gateway/static/root/assets/settings-advanced-gate-JFCbnCL2.js +1 -0
  51. package/dist/gateway/static/root/assets/{settings-form-section-ChXh3Bwk.js → settings-form-section-CXAn0Xhy.js} +1 -1
  52. package/dist/gateway/static/root/assets/{settings-loading-skeleton-BCAUqIe2.js → settings-loading-skeleton-DsFu7Bcv.js} +1 -1
  53. package/dist/gateway/static/root/assets/{settings-page-D25W9Okr.js → settings-page-C4iib9nO.js} +1 -1
  54. package/dist/gateway/static/root/assets/{setup-status-panel-DsN7Z4Fl.js → setup-status-panel-BA83Wr1d.js} +1 -1
  55. package/dist/gateway/static/root/assets/{share-preview-page-CRFnUaNb.js → share-preview-page-BOGl3s6M.js} +1 -1
  56. package/dist/gateway/static/root/assets/{shares-settings-CAX0eNaP.js → shares-settings-Q2MdGaBi.js} +1 -1
  57. package/dist/gateway/static/root/assets/{skill-reload-api-Doy1gghe.js → skill-reload-api-cFtfVeFU.js} +1 -1
  58. package/dist/gateway/static/root/assets/{skills-page-Cl7jjTK7.js → skills-page-CdaFtNw9.js} +1 -1
  59. package/dist/gateway/static/root/assets/{skills-page.utils-BiCl4nb5.js → skills-page.utils-DYaAddUL.js} +1 -1
  60. package/dist/gateway/static/root/assets/{system-settings-panel-BuESR7ZT.js → system-settings-panel-Co7gilRd.js} +1 -1
  61. package/dist/gateway/static/root/assets/{task-detail-page-BRiy8NL3.js → task-detail-page-5B1pswu8.js} +1 -1
  62. package/dist/gateway/static/root/assets/{use-autosave-Dg1mgJ_l.js → use-autosave-DnnZtMpA.js} +1 -1
  63. package/dist/gateway/static/root/assets/{user-context-page-CqoADNKu.js → user-context-page-Dr1FKjXv.js} +1 -1
  64. package/dist/gateway/static/root/assets/{voice-api-key-field-BDNexlVR.js → voice-api-key-field-wetUpi3i.js} +1 -1
  65. package/dist/gateway/static/root/assets/{work-discovery-overlay-BHTfeaWL.js → work-discovery-overlay-tbTWASJJ.js} +1 -1
  66. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cf_w-NZy.js → workflow-run-setup-panel-Dy0fDs8w.js} +1 -1
  67. package/dist/gateway/static/root/assets/{workflows-page-j0P-uECz.js → workflows-page-IVP3GSkI.js} +1 -1
  68. package/dist/gateway/static/root/index.html +1 -1
  69. package/dist/package.js +1 -1
  70. package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
  71. package/dist/src/agent/agent-manager.d.ts +1 -1
  72. package/dist/src/agent/agent-manager.js +18 -3
  73. package/dist/src/agent/background-review/prompts.d.ts +8 -2
  74. package/dist/src/agent/background-review/prompts.js +25 -12
  75. package/dist/src/agent/background-review/run-background-review.d.ts +7 -2
  76. package/dist/src/agent/background-review/run-background-review.js +175 -160
  77. package/dist/src/agent/memory/index.d.ts +1 -1
  78. package/dist/src/agent/memory/index.js +2 -2
  79. package/dist/src/agent/memory/manager.d.ts +1 -11
  80. package/dist/src/agent/memory/manager.js +0 -16
  81. package/dist/src/agent/memory/understanding/service.d.ts +0 -11
  82. package/dist/src/agent/memory/understanding/service.js +7 -173
  83. package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -3
  84. package/dist/src/agent/memory/user-context-coordinator.js +3 -66
  85. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
  86. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  87. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  88. package/dist/src/config/schema.d.ts +4 -0
  89. package/dist/src/config/schema.js +1 -0
  90. package/dist/src/connectors/connected-source-understanding.js +35 -21
  91. package/dist/src/connectors/learning-coordinator.js +1 -42
  92. package/dist/src/gateway/chat-stream/mapper.d.ts +2 -0
  93. package/dist/src/gateway/chat-stream/mapper.js +5 -0
  94. package/dist/src/gateway/hono/routes/understanding-sources.js +4 -1
  95. package/dist/src/gateway/hono/routes/you.js +29 -11
  96. package/dist/src/gateway/service/run-gateway-agent.js +5 -1
  97. package/dist/src/knowledge/index.d.ts +0 -1
  98. package/dist/src/knowledge/index.js +1 -2
  99. package/dist/src/notifications/planner.js +5 -1
  100. package/dist/src/storage/sqlite/index.d.ts +1 -1
  101. package/dist/src/storage/sqlite/index.js +2 -2
  102. package/dist/src/storage/sqlite/migrations/137_understanding_status_audit.sql +71 -0
  103. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  104. package/dist/src/storage/sqlite/migrations/runner.js +3 -3
  105. package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
  106. package/dist/src/storage/sqlite/schema.js +1 -1
  107. package/dist/src/storage/sqlite/user-context-repository.d.ts +16 -4
  108. package/dist/src/storage/sqlite/user-context-repository.js +56 -12
  109. package/dist/src/user-context/config.d.ts +8 -0
  110. package/dist/src/user-context/config.js +3 -0
  111. package/dist/src/user-context/consolidation.js +16 -4
  112. package/dist/src/user-context/extraction/executor.d.ts +22 -0
  113. package/dist/src/user-context/extraction/executor.js +142 -0
  114. package/dist/src/user-context/extraction/registry.d.ts +1 -1
  115. package/dist/src/user-context/extraction/registry.js +5 -34
  116. package/dist/src/user-context/extraction/repair.js +4 -1
  117. package/dist/src/user-context/extraction/semantic.d.ts +18 -0
  118. package/dist/src/user-context/extraction/semantic.js +148 -0
  119. package/dist/src/user-context/understandingQuality.js +4 -0
  120. package/dist/src/work-discovery/analyzer.js +9 -4
  121. package/dist/src/work-discovery/service.d.ts +1 -0
  122. package/dist/src/work-discovery/service.js +5 -4
  123. package/dist/src/work-discovery/types.d.ts +1 -0
  124. package/package.json +14 -8
  125. package/dist/gateway/static/root/assets/settings-advanced-gate-Cco_W41x.js +0 -1
  126. package/dist/src/agent/memory/understanding/correction.d.ts +0 -3
  127. package/dist/src/agent/memory/understanding/correction.js +0 -39
  128. package/dist/src/knowledge/connected-understanding-pipeline.d.ts +0 -17
  129. package/dist/src/knowledge/connected-understanding-pipeline.js +0 -278
@@ -39,17 +39,6 @@ export declare class MemoryManager {
39
39
  queuePrefetchAll(query: string, options?: {
40
40
  sessionId?: string;
41
41
  }): void;
42
- syncAll(userContent: string, assistantContent: string, options?: {
43
- sessionId?: string;
44
- }): Promise<void>;
45
- captureTurnUnderstanding(userContent: string, assistantContent: string, options?: {
46
- agentId?: string;
47
- sessionId?: string;
48
- turnId?: string;
49
- workspaceId?: string;
50
- projectId?: string;
51
- correctionTargetRecordIds?: string[];
52
- }): Promise<import('./understanding/types.js').UnderstandingReviewResult>;
53
42
  syncProvidersForTurn(userContent: string, assistantContent: string, options?: {
54
43
  sessionId?: string;
55
44
  turnId?: string;
@@ -67,6 +56,7 @@ export declare class MemoryManager {
67
56
  source?: MemoryRecord['source'];
68
57
  reviewSource?: 'turn' | 'background';
69
58
  extractionRunId?: string;
59
+ supersedesRecordIds?: string[];
70
60
  }): Promise<import('./understanding/types.js').UnderstandingReviewResult>;
71
61
  getExternalToolEntries(): Array<{
72
62
  providerId: string;
@@ -81,22 +81,6 @@ var MemoryManager = class {
81
81
  }, "queuePrefetch failed (non-fatal)");
82
82
  }
83
83
  }
84
- async syncAll(userContent, assistantContent, options) {
85
- await this.captureTurnUnderstanding(userContent, assistantContent, options);
86
- await this.syncProvidersForTurn(userContent, assistantContent, options);
87
- }
88
- async captureTurnUnderstanding(userContent, assistantContent, options) {
89
- const sessionContext = options?.sessionId ? this.sessionContexts.get(options.sessionId) : void 0;
90
- return await this.understanding.reviewTurn({
91
- userContent,
92
- assistantContent,
93
- sessionKey: options?.sessionId,
94
- turnId: options?.turnId,
95
- workspaceId: options?.workspaceId ?? sessionContext?.workspace ?? sessionContext?.agentWorkspace,
96
- projectId: options?.projectId,
97
- correctionTargetRecordIds: options?.correctionTargetRecordIds
98
- });
99
- }
100
84
  async syncProvidersForTurn(userContent, assistantContent, options) {
101
85
  const provenance = options?.provenance;
102
86
  const event = {
@@ -1,16 +1,5 @@
1
1
  import type { UnderstandingCandidate, UnderstandingReviewResult } from './types.js';
2
- export declare function extractExplicitUnderstandingCandidates(userContent: string): UnderstandingCandidate[];
3
- export declare function extractHighSignalUnderstandingCandidates(userContent: string): UnderstandingCandidate[];
4
2
  export declare class UserUnderstandingService {
5
- reviewTurn(params: {
6
- userContent: string;
7
- assistantContent: string;
8
- sessionKey?: string;
9
- turnId?: string;
10
- workspaceId?: string;
11
- projectId?: string;
12
- correctionTargetRecordIds?: string[];
13
- }): Promise<UnderstandingReviewResult>;
14
3
  applyCandidates(candidates: UnderstandingCandidate[], context: {
15
4
  sessionKey?: string;
16
5
  workspaceId?: string;
@@ -1,27 +1,12 @@
1
- import { finishContextExtractionRun, getContextExtractionRun, listContextExtractionOutputs } from "../../../storage/sqlite/context-extraction-repository.js";
1
+ import { getContextExtractionRun } from "../../../storage/sqlite/context-extraction-repository.js";
2
2
  import { closeTemporalAssertions, createTemporalAssertion, linkContextObjects } from "../../../storage/sqlite/context-relation-repository.js";
3
3
  import { closeUnderstandingValidity, createContextEvidence, createUnderstanding, getUnderstanding, isUnderstandingSuppressed, linkUnderstandingEvidence, listUnderstandings, setUnderstandingStatus } from "../../../storage/sqlite/user-context-repository.js";
4
4
  import "../../../storage/sqlite/index.js";
5
- import { extractExplicitUnderstandingCorrectionContent } from "./correction.js";
6
- import { claimRegisteredExtraction, extractionInputHash, getRegisteredExtractorDefinition } from "../../../user-context/extraction/registry.js";
5
+ import { getRegisteredExtractorDefinition } from "../../../user-context/extraction/registry.js";
7
6
  import { canonicalUnderstandingKey, findContradictoryUnderstanding, findDuplicateUnderstanding } from "../../../user-context/understanding.js";
8
7
  import { inferMemorySensitivity, redactSensitiveMemoryText } from "../sensitivity.js";
9
8
  //#region src/agent/memory/understanding/service.ts
10
9
  const MAX_CANDIDATE_CHARS = 600;
11
- const EXPLICIT_PATTERNS = [
12
- /\b(?:please\s+)?remember(?:\s+that)?\s+(.+)/i,
13
- /\bkeep\s+in\s+mind(?:\s+that)?\s+(.+)/i,
14
- /(?:请)?记住[::\s]*(.+)/
15
- ];
16
- const HIGH_SIGNAL_PATTERNS = [
17
- /(?:从现在起|今后|以后)(?:都)?(?:请)?[::\s]*(.+)/,
18
- /下次(?:请)?[::\s]*(.+)/,
19
- /(?:默认|每次|每回)(?:都)?(?:请)?[::\s]*(.+)/,
20
- /((?:我|本人)(?:一直|通常|一般|更)?(?:喜欢|偏好|习惯|希望|不希望|不喜欢).+)/,
21
- /\b(?:from now on|going forward|next time|by default|whenever)\b[,:\s]*(.+)/i,
22
- /(\bi\s+(?:always|usually|generally)\s+(?:prefer|like|want|need|avoid)\b.+)/i,
23
- /(\bi\s+(?:prefer|like|want|need)\s+.+\s+(?:every time|by default|going forward)\b.*)/i
24
- ];
25
10
  const SENSITIVITY_RANK = {
26
11
  normal: 0,
27
12
  personal: 1,
@@ -40,50 +25,6 @@ function candidateTime(value) {
40
25
  const parsed = Date.parse(value);
41
26
  return Number.isFinite(parsed) ? parsed : void 0;
42
27
  }
43
- function inferKind(content) {
44
- if (/\b(don't|do not|never|avoid)\b/i.test(content) || /不要|不用|无需|别再|禁止|底线/.test(content)) return "boundary";
45
- if (/\b(prefer|preference|like)\b/i.test(content) || /喜欢|偏好|习惯/.test(content)) return "preference";
46
- if (/\b(project|repo|codebase|workspace)\b/i.test(content) || /项目|仓库|代码库/.test(content)) return "project_context";
47
- if (/\b(goal|plan|deadline)\b/i.test(content) || /目标|计划|截止/.test(content)) return "long_term_goal";
48
- if (/\b(next time|lesson|failed|error)\b/i.test(content) || /教训|失败|错误/.test(content)) return "task_lesson";
49
- if (/习惯|每周|每天|usually|routine/i.test(content)) return "routine";
50
- return "current_state";
51
- }
52
- function extractExplicitUnderstandingCandidates(userContent) {
53
- const correction = extractExplicitUnderstandingCorrectionContent(userContent);
54
- const matched = correction ?? userContent.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).flatMap((line) => EXPLICIT_PATTERNS.map((pattern) => pattern.exec(line)?.[1] ?? "")).map(normalizeContent).find((content) => content.length >= 8);
55
- if (!matched) return [];
56
- const content = normalizeContent(matched);
57
- const kind = inferKind(content);
58
- return [{
59
- kind,
60
- content,
61
- canonicalKey: canonicalUnderstandingKey(kind, content),
62
- confidence: correction ? .98 : .95,
63
- importance: kind === "boundary" ? .9 : .8,
64
- explicitness: "explicit",
65
- durability: "durable",
66
- sensitivity: inferMemorySensitivity(content),
67
- disclosurePolicy: kind === "boundary" ? "silent" : "referenceable"
68
- }];
69
- }
70
- function extractHighSignalUnderstandingCandidates(userContent) {
71
- if (extractExplicitUnderstandingCorrectionContent(userContent)) return [];
72
- const matched = userContent.split(/\r?\n/).map((line) => line.trim()).filter(Boolean).flatMap((line) => HIGH_SIGNAL_PATTERNS.map((pattern) => pattern.exec(line)?.[1] ?? "")).map(normalizeContent).find((content) => content.length >= 6);
73
- if (!matched) return [];
74
- const kind = inferKind(matched);
75
- return [{
76
- kind,
77
- content: matched,
78
- canonicalKey: canonicalUnderstandingKey(kind, matched),
79
- confidence: .85,
80
- importance: kind === "boundary" ? .9 : .75,
81
- explicitness: "observed",
82
- durability: "durable",
83
- sensitivity: inferMemorySensitivity(matched),
84
- disclosurePolicy: kind === "boundary" ? "silent" : "referenceable"
85
- }];
86
- }
87
28
  function scopeForCandidate(candidate, context) {
88
29
  if (candidate.durability === "ephemeral" && context.sessionKey) return {
89
30
  type: "session",
@@ -100,116 +41,6 @@ function scopeForCandidate(candidate, context) {
100
41
  return { type: "global" };
101
42
  }
102
43
  var UserUnderstandingService = class {
103
- async reviewTurn(params) {
104
- params.assistantContent;
105
- const explicitCandidates = extractExplicitUnderstandingCandidates(params.userContent);
106
- const candidates = explicitCandidates.length > 0 ? explicitCandidates : extractHighSignalUnderstandingCandidates(params.userContent);
107
- const turnRef = params.turnId ?? `untracked-${extractionInputHash(params.userContent).slice(0, 16)}`;
108
- const extraction = claimRegisteredExtraction({
109
- extractorId: explicitCandidates.length > 0 ? "explicit-command" : "deterministic-signal",
110
- sourceRef: params.sessionKey ? `session:${params.sessionKey}:turn:${turnRef}` : `turn:${turnRef}`,
111
- contentForHash: params.userContent,
112
- processingPolicy: "local_only",
113
- destination: "deterministic"
114
- });
115
- if (!extraction.shouldExecute) {
116
- const previous = listContextExtractionOutputs(extraction.run.id);
117
- return {
118
- proposed: candidates.length,
119
- created: 0,
120
- deduplicated: previous.filter((output) => output.outcome !== "rejected").length,
121
- rejected: previous.filter((output) => output.outcome === "rejected").length,
122
- createdRecords: []
123
- };
124
- }
125
- if (candidates.length === 0) {
126
- finishContextExtractionRun({
127
- runId: extraction.run.id,
128
- status: "completed",
129
- outputs: []
130
- });
131
- return {
132
- proposed: 0,
133
- created: 0,
134
- deduplicated: 0,
135
- rejected: 0,
136
- createdRecords: []
137
- };
138
- }
139
- const safeCandidates = candidates.filter((candidate) => {
140
- const content = normalizeContent(candidate.content);
141
- const sensitivity = effectiveSensitivity(candidate.sensitivity, content);
142
- return sensitivity !== "secret" && sensitivity !== "regulated";
143
- });
144
- if (!safeCandidates.length) {
145
- finishContextExtractionRun({
146
- runId: extraction.run.id,
147
- status: "completed",
148
- outputs: candidates.map((candidate) => ({
149
- candidateKey: candidate.canonicalKey ?? canonicalUnderstandingKey(candidate.kind, candidate.content),
150
- outcome: "rejected"
151
- }))
152
- });
153
- return {
154
- proposed: candidates.length,
155
- created: 0,
156
- deduplicated: 0,
157
- rejected: candidates.length,
158
- createdRecords: []
159
- };
160
- }
161
- const evidence = createContextEvidence({
162
- sourceType: "conversation",
163
- sourceRef: params.sessionKey ? `session:${params.sessionKey}:turn:${turnRef}` : `turn:${turnRef}`,
164
- sourceRunId: extraction.run.id,
165
- ...params.sessionKey ? { sessionId: params.sessionKey } : {},
166
- turnId: turnRef,
167
- contentHash: extractionInputHash(params.userContent),
168
- retentionPolicy: "derived_only",
169
- processingPolicy: "local_only",
170
- extractorId: extraction.run.extractorId,
171
- extractorVersion: extraction.run.extractorVersion,
172
- redactedExcerpt: redactSensitiveMemoryText(safeCandidates.map((candidate) => candidate.content).join("\n")).slice(0, MAX_CANDIDATE_CHARS),
173
- trustLevel: "owner",
174
- observedAt: Date.now()
175
- });
176
- let result;
177
- try {
178
- result = await this.applyCandidates(safeCandidates, {
179
- sessionKey: params.sessionKey,
180
- workspaceId: params.workspaceId,
181
- projectId: params.projectId,
182
- evidenceIds: [evidence.id],
183
- reviewSource: "turn",
184
- supersedesRecordIds: params.correctionTargetRecordIds,
185
- extractionRunId: extraction.run.id
186
- });
187
- } catch (error) {
188
- finishContextExtractionRun({
189
- runId: extraction.run.id,
190
- status: "failed",
191
- errorCode: "write_failed"
192
- });
193
- throw error;
194
- }
195
- finishContextExtractionRun({
196
- runId: extraction.run.id,
197
- status: "completed",
198
- outputs: result.writeOutputs?.map((output) => ({
199
- candidateKey: output.candidateKey,
200
- objectType: output.objectId ? "understanding" : void 0,
201
- objectId: output.objectId,
202
- versionId: output.versionId,
203
- outcome: output.outcome
204
- })) ?? []
205
- });
206
- return {
207
- ...result,
208
- proposed: candidates.length,
209
- rejected: result.rejected + candidates.length - safeCandidates.length,
210
- sourceItemId: evidence.id
211
- };
212
- }
213
44
  async applyCandidates(candidates, context) {
214
45
  let created = 0;
215
46
  let deduplicated = 0;
@@ -332,7 +163,10 @@ var UserUnderstandingService = class {
332
163
  objectId: supersededId,
333
164
  validTo: closedAt
334
165
  });
335
- setUnderstandingStatus(supersededId, "archived");
166
+ setUnderstandingStatus(supersededId, "archived", {
167
+ actorType: "user",
168
+ source: "semantic-memory-superseded"
169
+ });
336
170
  }
337
171
  const assertionType = record.kind === "current_state" ? "current_state" : record.kind === "routine" ? "routine" : record.kind === "relationship" ? "relationship" : record.kind === "project_context" ? "project_status" : void 0;
338
172
  if (assertionType) createTemporalAssertion({
@@ -372,4 +206,4 @@ var UserUnderstandingService = class {
372
206
  }
373
207
  };
374
208
  //#endregion
375
- export { UserUnderstandingService, extractExplicitUnderstandingCandidates, extractHighSignalUnderstandingCandidates };
209
+ export { UserUnderstandingService };
@@ -5,7 +5,6 @@ import type { MemoryManager } from './manager.js';
5
5
  export interface UserContextCoordinatorOptions {
6
6
  getConfig: () => Config | undefined;
7
7
  isEnabledForSession: (sessionKey: string) => boolean;
8
- getAgentIdForSession: (sessionKey: string) => string;
9
8
  getWorkspaceIdForSession?: (sessionKey: string) => string;
10
9
  getProjectIdForSession?: (sessionKey: string) => string | undefined;
11
10
  getMemoryManagerForSession: (sessionKey: string) => MemoryManager;
@@ -15,11 +14,10 @@ export declare class UserContextCoordinator {
15
14
  private readonly options;
16
15
  private readonly userTurn;
17
16
  private readonly lastTurnId;
18
- private readonly correctionTargets;
19
17
  private readonly planner;
20
18
  constructor(options: UserContextCoordinatorOptions);
21
19
  forgetSession(sessionKey: string): void;
22
20
  clear(): void;
23
21
  prepare(userMessage: AgentMessage, sessionKey: string, turnId: string): Promise<UserContextPlan>;
24
- afterTurn(sessionKey: string, userPlainText: string): Promise<import('./understanding/types.js').UnderstandingReviewResult | undefined>;
22
+ afterTurn(sessionKey: string, userPlainText: string): Promise<void>;
25
23
  }
@@ -1,19 +1,12 @@
1
- import { createLogger } from "../../utils/logger/index.js";
2
- import { init_logger } from "../../utils/logger.js";
3
- import { getTurnPersonalization, recordContextFeedback, setUnderstandingStatus } from "../../storage/sqlite/user-context-repository.js";
4
- import "../../storage/sqlite/index.js";
5
1
  import { init_session_key, parseSessionKey } from "../../routing/session-key.js";
6
2
  import { assembleTaskContext } from "../../tasks/task-context-assembler.js";
7
3
  import { shouldPlanUserContextThisTurn } from "./memory-config.js";
8
4
  import { UserContextPlanner, prependAgentContext } from "../../user-context/planner.js";
9
- import { isExplicitUnderstandingCorrection } from "./understanding/correction.js";
10
5
  import { extractAgentUserPlainText } from "./user-message-text.js";
11
6
  import { consumeTurnMemoryProvenance, markTurnRecalledContext } from "./turn-provenance.js";
12
7
  import { planTrustedRecall } from "./trusted-recall.js";
13
8
  //#region src/agent/memory/user-context-coordinator.ts
14
9
  init_session_key();
15
- init_logger();
16
- const log = createLogger("UserContextCoordinator");
17
10
  function isPrivateSession(sessionKey) {
18
11
  const parsed = parseSessionKey(sessionKey);
19
12
  return !parsed || parsed.peerKind === "direct";
@@ -21,7 +14,6 @@ function isPrivateSession(sessionKey) {
21
14
  var UserContextCoordinator = class {
22
15
  userTurn = /* @__PURE__ */ new Map();
23
16
  lastTurnId = /* @__PURE__ */ new Map();
24
- correctionTargets = /* @__PURE__ */ new Map();
25
17
  planner = new UserContextPlanner();
26
18
  constructor(options) {
27
19
  this.options = options;
@@ -29,12 +21,10 @@ var UserContextCoordinator = class {
29
21
  forgetSession(sessionKey) {
30
22
  this.userTurn.delete(sessionKey);
31
23
  this.lastTurnId.delete(sessionKey);
32
- this.correctionTargets.delete(sessionKey);
33
24
  }
34
25
  clear() {
35
26
  this.userTurn.clear();
36
27
  this.lastTurnId.clear();
37
- this.correctionTargets.clear();
38
28
  }
39
29
  async prepare(userMessage, sessionKey, turnId) {
40
30
  const empty = () => ({
@@ -50,37 +40,9 @@ var UserContextCoordinator = class {
50
40
  if (!this.options.isEnabledForSession(sessionKey)) return empty();
51
41
  const config = this.options.getConfig();
52
42
  if (!isPrivateSession(sessionKey)) return empty();
53
- const userQuery = extractAgentUserPlainText(userMessage);
54
- const taskContext = assembleTaskContext(sessionKey, userQuery);
43
+ const taskContext = assembleTaskContext(sessionKey, extractAgentUserPlainText(userMessage));
55
44
  const query = taskContext.retrievalQuery;
56
- const previousTurnId = this.lastTurnId.get(sessionKey);
57
45
  this.lastTurnId.set(sessionKey, turnId);
58
- this.correctionTargets.delete(sessionKey);
59
- let excludedRecordIds;
60
- if (previousTurnId && isExplicitUnderstandingCorrection(userQuery)) try {
61
- const personalization = getTurnPersonalization(previousTurnId);
62
- const selectedIds = personalization?.items.filter((item) => item.objectType === "understanding" && item.decision === "selected").map((item) => item.objectId) ?? [];
63
- if (personalization && selectedIds.length) {
64
- for (const recordId of selectedIds) {
65
- recordContextFeedback({
66
- turnId: previousTurnId,
67
- runId: personalization.runId,
68
- objectType: "understanding",
69
- objectId: recordId,
70
- rating: "wrong",
71
- reason: "detected_explicit_user_correction"
72
- });
73
- setUnderstandingStatus(recordId, "needs_review");
74
- }
75
- this.correctionTargets.set(sessionKey, selectedIds);
76
- excludedRecordIds = selectedIds;
77
- }
78
- } catch (err) {
79
- log.debug({
80
- err,
81
- sessionKey
82
- }, "Understanding correction feedback was not persisted");
83
- }
84
46
  const turn = (this.userTurn.get(sessionKey) ?? 0) + 1;
85
47
  this.userTurn.set(sessionKey, turn);
86
48
  if (!shouldPlanUserContextThisTurn(config, turn)) return empty();
@@ -92,7 +54,6 @@ var UserContextCoordinator = class {
92
54
  turnId,
93
55
  query,
94
56
  userMessage,
95
- excludedRecordIds,
96
57
  allocation: taskContext.allocation
97
58
  });
98
59
  const totalChars = taskContext.allocation.maxChars;
@@ -134,36 +95,12 @@ var UserContextCoordinator = class {
134
95
  };
135
96
  }
136
97
  async afterTurn(sessionKey, userPlainText) {
137
- if (!this.options.isEnabledForSession(sessionKey)) return void 0;
98
+ if (!this.options.isEnabledForSession(sessionKey)) return;
138
99
  const memoryManager = this.options.getMemoryManagerForSession(sessionKey);
139
100
  const assistantContent = this.options.getLastAssistantContent(sessionKey) ?? "";
140
- if (!isPrivateSession(sessionKey)) return void 0;
141
- const correctionTargetRecordIds = this.correctionTargets.get(sessionKey);
101
+ if (!isPrivateSession(sessionKey)) return;
142
102
  const turnId = this.lastTurnId.get(sessionKey);
143
103
  const provenance = turnId ? consumeTurnMemoryProvenance(sessionKey, turnId) : void 0;
144
- this.correctionTargets.delete(sessionKey);
145
- try {
146
- const review = await memoryManager.captureTurnUnderstanding(userPlainText, assistantContent, {
147
- agentId: this.options.getAgentIdForSession(sessionKey),
148
- sessionId: sessionKey,
149
- turnId,
150
- workspaceId: this.options.getWorkspaceIdForSession?.(sessionKey),
151
- projectId: this.options.getProjectIdForSession?.(sessionKey),
152
- correctionTargetRecordIds
153
- });
154
- memoryManager.syncProvidersForTurn(userPlainText, assistantContent, {
155
- sessionId: sessionKey,
156
- turnId,
157
- provenance
158
- });
159
- memoryManager.queuePrefetchAll(userPlainText, { sessionId: sessionKey });
160
- return review;
161
- } catch (err) {
162
- log.warn({
163
- err,
164
- sessionKey
165
- }, "Turn understanding capture failed");
166
- }
167
104
  memoryManager.syncProvidersForTurn(userPlainText, assistantContent, {
168
105
  sessionId: sessionKey,
169
106
  turnId,
@@ -110,7 +110,7 @@ var AgentOrchestrator = class {
110
110
  clearPendingTranscriptUserMessage(sessionKey, userMessage);
111
111
  }
112
112
  })();
113
- const understandingReview = await this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory);
113
+ const understandingReview = await this.agentManager.afterAgentTurn(sessionKey, userPlainForMemory, turnId);
114
114
  if (understandingReview?.createdRecords.length) {
115
115
  const captured = understandingReview.createdRecords.filter((record) => record.status === "active");
116
116
  const candidates = understandingReview.createdRecords.filter((record) => record.status === "candidate");
@@ -116,7 +116,7 @@ async function runDirectAgentTurn(deps, input) {
116
116
  beforeTurn: () => deps.agentManager.beginBackgroundReviewUserTurn(input.sessionKey),
117
117
  onEvent: input.onEvent
118
118
  });
119
- const understandingReview = await deps.agentManager.afterAgentTurn(input.sessionKey, userPlain);
119
+ const understandingReview = await deps.agentManager.afterAgentTurn(input.sessionKey, userPlain, turnId);
120
120
  if (understandingReview?.createdRecords.length) {
121
121
  const captured = understandingReview.createdRecords.filter((record) => record.status === "active");
122
122
  const candidates = understandingReview.createdRecords.filter((record) => record.status === "candidate");
@@ -52,7 +52,7 @@ async function checkDatabaseSchema(ctx) {
52
52
  id: "database-schema",
53
53
  label: "Database schema",
54
54
  status: "pass",
55
- message: `SQLite schema v${status.dbVersion} (current release v136).`,
55
+ message: `SQLite schema v${status.dbVersion} (current release v137).`,
56
56
  hints: []
57
57
  };
58
58
  }
@@ -1572,6 +1572,10 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1572
1572
  }, z.core.$strict>>;
1573
1573
  understanding: z.ZodDefault<z.ZodObject<{
1574
1574
  enabled: z.ZodDefault<z.ZodBoolean>;
1575
+ processingPolicy: z.ZodDefault<z.ZodEnum<{
1576
+ local_only: "local_only";
1577
+ remote_allowed: "remote_allowed";
1578
+ }>>;
1575
1579
  adaptiveCadence: z.ZodDefault<z.ZodBoolean>;
1576
1580
  reviewIntervalTurns: z.ZodDefault<z.ZodNumber>;
1577
1581
  maxHistoryMessages: z.ZodDefault<z.ZodNumber>;
@@ -1059,6 +1059,7 @@ workDiscoveryOnboarding: z.boolean().default(true) }).strict().default({ workDis
1059
1059
  },
1060
1060
  understanding: {
1061
1061
  enabled: true,
1062
+ processingPolicy: "remote_allowed",
1062
1063
  adaptiveCadence: true,
1063
1064
  reviewIntervalTurns: 10,
1064
1065
  maxHistoryMessages: 80,
@@ -6,7 +6,6 @@ import { upsertUserFocus } from "../user-context/sources/repository.js";
6
6
  import { claimRegisteredExtraction } from "../user-context/extraction/registry.js";
7
7
  import { allowsRemoteSourceProcessing } from "../user-context/sources/processing-policy.js";
8
8
  import { analyzeUnderstandingSources } from "../work-discovery/analyzer.js";
9
- import { createHash } from "node:crypto";
10
9
  //#region src/connectors/connected-source-understanding.ts
11
10
  const MAX_CONNECTED_ITEMS = 150;
12
11
  function normalizedValue(item) {
@@ -60,17 +59,14 @@ function connectedItemsForUnderstanding(items) {
60
59
  }];
61
60
  });
62
61
  }
63
- function understandingKind(category) {
64
- if (category === "preference") return "preference";
65
- if (category === "routine") return "routine";
66
- return "project_context";
62
+ function isConnectedPortraitCandidate(candidate) {
63
+ return candidate.category === "preference" || candidate.category === "routine";
67
64
  }
68
65
  function understandingCandidate(candidate) {
69
- const normalized = candidate.statement.toLocaleLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
70
66
  return {
71
- kind: understandingKind(candidate.category),
67
+ kind: candidate.category,
72
68
  content: candidate.statement,
73
- canonicalKey: `connected-semantic:${candidate.category}:${createHash("sha256").update(normalized).digest("hex").slice(0, 20)}`,
69
+ canonicalKey: `understanding:${candidate.category}:${candidate.factKey}`,
74
70
  confidence: candidate.confidence === "high" ? .9 : candidate.confidence === "medium" ? .72 : .55,
75
71
  importance: .68,
76
72
  explicitness: "inferred",
@@ -84,6 +80,18 @@ function hasLongVerbatimOverlap(value, sourceTexts, minimumLength = 32) {
84
80
  if (normalized.length < minimumLength) return false;
85
81
  return sourceTexts.some((source) => source.replace(/\s+/g, " ").includes(normalized));
86
82
  }
83
+ function evidenceDate(item) {
84
+ const timestamp = item.occurredAt ?? item.modifiedAt;
85
+ return timestamp == null ? void 0 : new Date(timestamp).toISOString().slice(0, 10);
86
+ }
87
+ function durableConnectedEvidence(candidate, itemsByRef) {
88
+ if (candidate.confidence !== "high") return [];
89
+ const items = [...new Set(candidate.evidenceRefs ?? [])].flatMap((ref) => itemsByRef.get(ref) ?? []);
90
+ if (items.some((item) => item.ownerAttribution !== "user")) return [];
91
+ const required = candidate.category === "routine" ? 3 : 2;
92
+ const dates = new Set(items.map(evidenceDate).filter((value) => Boolean(value)));
93
+ return items.length >= required && dates.size >= required ? items : [];
94
+ }
87
95
  async function deriveConnectedSourceUnderstanding(input) {
88
96
  const knowledgeItems = listKnowledgeSourceItems({
89
97
  agentId: input.agentId,
@@ -115,22 +123,28 @@ async function deriveConnectedSourceUnderstanding(input) {
115
123
  items
116
124
  });
117
125
  const rawTexts = items.flatMap((item) => item.text ? [item.text] : []);
118
- const profileCandidates = analysis.profileCandidates.filter((candidate) => !hasLongVerbatimOverlap(candidate.statement, rawTexts));
119
- const sourceItemIds = [...new Set([...profileCandidates.flatMap((candidate) => candidate.evidenceRefs ?? []), ...analysis.workThreadCandidates.flatMap((candidate) => candidate.evidenceRefs)].map((ref) => ref.startsWith("knowledge-source://") ? ref.slice(19) : ""))].filter(Boolean).slice(0, 20);
120
- const reviewed = profileCandidates.length ? await input.memoryManager.applyUnderstandingCandidates(profileCandidates.map(understandingCandidate), {
121
- agentId: input.agentId,
122
- sourceItemIds,
123
- sourceText: "Bounded semantic synthesis from explicitly connected work sources.",
124
- source: {
125
- provider: "connected-sources",
126
- sourceInstanceId: input.sourceInstanceId
127
- },
128
- reviewSource: "background",
129
- extractionRunId: extraction.run.id
130
- }) : {
126
+ const itemsByRef = new Map(items.map((item) => [item.evidenceRef, item]));
127
+ const profileCandidates = analysis.profileCandidates.filter(isConnectedPortraitCandidate).filter((candidate) => !hasLongVerbatimOverlap(candidate.statement, rawTexts) && durableConnectedEvidence(candidate, itemsByRef).length > 0);
128
+ const reviewed = {
131
129
  created: 0,
132
130
  writeOutputs: []
133
131
  };
132
+ for (const candidate of profileCandidates) {
133
+ const evidenceItems = durableConnectedEvidence(candidate, itemsByRef);
134
+ const applied = await input.memoryManager.applyUnderstandingCandidates([understandingCandidate(candidate)], {
135
+ agentId: input.agentId,
136
+ sourceItemIds: evidenceItems.map((item) => item.id).slice(0, 20),
137
+ sourceText: "Bounded semantic synthesis from explicitly connected work sources.",
138
+ source: {
139
+ provider: "connected-sources",
140
+ sourceInstanceId: input.sourceInstanceId
141
+ },
142
+ reviewSource: "background",
143
+ extractionRunId: extraction.run.id
144
+ });
145
+ reviewed.created += applied.created;
146
+ reviewed.writeOutputs.push(...applied.writeOutputs ?? []);
147
+ }
134
148
  const focuses = analysis.workThreadCandidates.filter((candidate) => !hasLongVerbatimOverlap(candidate.title, rawTexts) && !hasLongVerbatimOverlap(candidate.summary, rawTexts)).map((candidate) => upsertUserFocus({
135
149
  canonicalKey: `connected-focus:${candidate.topicKey}`,
136
150
  title: candidate.title,
@@ -1,6 +1,5 @@
1
1
  import { createLogger } from "../utils/logger/index.js";
2
2
  import { init_logger } from "../utils/logger.js";
3
- import { finishContextExtractionRun } from "../storage/sqlite/context-extraction-repository.js";
4
3
  import { claimNextConnectorLearningJob, enqueueConnectorLearningJob, listConnectorLearningJobs, recoverStaleConnectorLearningJobs, setConnectorLearningPaused, updateConnectorLearningJob } from "../storage/sqlite/connector-learning-repository.js";
5
4
  import { getConnectorInstallation, listConnectorConnections, upsertConnectorConnection } from "../storage/sqlite/connector-repository.js";
6
5
  import { getConnectorAccount, reconcileConnectorAccount } from "../storage/sqlite/connector-account-repository.js";
@@ -11,10 +10,8 @@ import { ComposioSessionsAdapter } from "./composio-sessions.js";
11
10
  import { buildConnectorLearningArguments, getConnectorLearningPlan } from "./learning-recipes.js";
12
11
  import { getConnectorDefinition } from "./catalog.js";
13
12
  import { createUnderstandingSourceRun, getUnderstandingSourceGrant, listUnderstandingSourceRuns, updateUnderstandingSourceGrantCheckpoint, updateUnderstandingSourceRun, upsertUnderstandingSourceGrant } from "../user-context/sources/repository.js";
14
- import { claimRegisteredExtraction } from "../user-context/extraction/registry.js";
15
13
  import { getWorkspacePath } from "../config/workspace-path-helpers.js";
16
14
  import { ConnectedKnowledgePipeline } from "../knowledge/connected-knowledge-pipeline.js";
17
- import { ConnectedUnderstandingPipeline } from "../knowledge/connected-understanding-pipeline.js";
18
15
  import "../knowledge/index.js";
19
16
  import { ingestComposioConnectedSource } from "./connected-source-ingestion.js";
20
17
  import { deriveConnectedSourceUnderstanding } from "./connected-source-understanding.js";
@@ -210,44 +207,6 @@ function startConnectorLearningCoordinator(options) {
210
207
  itemsIndexed
211
208
  }));
212
209
  publish(updateConnectorLearningJob(job.id, { phase: "deriving" }));
213
- const structuralExtraction = claimRegisteredExtraction({
214
- extractorId: "connector-structural",
215
- sourceRef: `understanding-source-run:${sourceRun.id}`,
216
- contentForHash: `${job.sourceInstanceId}:${itemsSeen}:${itemsIndexed}`,
217
- processingPolicy: "local_only",
218
- destination: "deterministic"
219
- });
220
- let understanding = {
221
- proposed: 0,
222
- created: 0,
223
- deduplicated: 0,
224
- rejected: 0,
225
- createdRecords: [],
226
- writeOutputs: []
227
- };
228
- if (structuralExtraction.shouldExecute) try {
229
- understanding = await new ConnectedUnderstandingPipeline(options.getMemoryManager()).process(job.agentId, structuralExtraction.run.id);
230
- finishContextExtractionRun({
231
- runId: structuralExtraction.run.id,
232
- status: "completed",
233
- outputs: (understanding.writeOutputs ?? []).map((output) => ({
234
- candidateKey: output.candidateKey,
235
- ...output.objectId ? {
236
- objectType: "understanding",
237
- objectId: output.objectId
238
- } : {},
239
- ...output.versionId ? { versionId: output.versionId } : {},
240
- outcome: output.outcome
241
- }))
242
- });
243
- } catch (error) {
244
- finishContextExtractionRun({
245
- runId: structuralExtraction.run.id,
246
- status: "failed",
247
- errorCode: "extractor_failed"
248
- });
249
- throw error;
250
- }
251
210
  let semantic = {
252
211
  created: 0,
253
212
  focusCount: 0,
@@ -276,7 +235,7 @@ function startConnectorLearningCoordinator(options) {
276
235
  connectorId: job.connectorId
277
236
  }, `Connected source semantic analysis failed: ${errorMessage}`);
278
237
  }
279
- const candidatesCreated = understanding.created + semantic.created + semantic.focusCount;
238
+ const candidatesCreated = semantic.created + semantic.focusCount;
280
239
  const incomplete = enrichmentErrors.length > 0 || semantic.status !== "completed";
281
240
  const completed = updateConnectorLearningJob(job.id, {
282
241
  status: "completed",
@@ -15,6 +15,7 @@ export declare class ChatStreamMapper {
15
15
  private currentAssistantMessageId;
16
16
  private lastAssistantMessageId;
17
17
  private currentAssistantText;
18
+ private lastAssistantText;
18
19
  private currentAssistantReviewEmitted;
19
20
  private toolCallToMessageId;
20
21
  private turnDiffs;
@@ -28,6 +29,7 @@ export declare class ChatStreamMapper {
28
29
  start(): ChatStreamEvent[];
29
30
  end(status: ChatStreamStatus, summary?: string): ChatStreamEvent[];
30
31
  error(message: string, code?: string): ChatStreamEvent[];
32
+ getLastAssistantText(): string;
31
33
  private mapMessageStart;
32
34
  private mapMessageUpdate;
33
35
  private mapAssistantSnapshot;