@xopcai/xopc 0.0.315 → 0.0.317

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 (160) 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-BbFOF2SH.js → agent-avatar-dicebear-BmmO4j0u.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-D9T-QGmd.js → agent-defaults-settings-panel-2NGwyCKB.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agents-Ds5sQcPd.js → agents-Cb4lfXqA.js} +1 -1
  6. package/dist/gateway/static/root/assets/{api-BzloAiIG.js → api-Fu9gSeAI.js} +1 -1
  7. package/dist/gateway/static/root/assets/{app-management-settings-panel-BpUHskXq.js → app-management-settings-panel-BhIQOlam.js} +1 -1
  8. package/dist/gateway/static/root/assets/{appearance-settings-CQd5Vo6f.js → appearance-settings-DwW3wrBX.js} +1 -1
  9. package/dist/gateway/static/root/assets/{apps-page-B7VIsfye.js → apps-page-ByLoHKiD.js} +1 -1
  10. package/dist/gateway/static/root/assets/{archive-plugin-BM4O6WfL.js → archive-plugin-DzQeKhMy.js} +1 -1
  11. package/dist/gateway/static/root/assets/{attachment-load-Cdn9MYmI.js → attachment-load-CNWbDfHi.js} +1 -1
  12. package/dist/gateway/static/root/assets/{automations-page-DnRx-Ra4.js → automations-page-CZcaFAco.js} +1 -1
  13. package/dist/gateway/static/root/assets/automations-workspace-CGTrgDlW.js +7 -0
  14. package/dist/gateway/static/root/assets/{binary-plugins-dkhUf4bm.js → binary-plugins-D5-gEs50.js} +1 -1
  15. package/dist/gateway/static/root/assets/{block-editor-BTzqEuAy.js → block-editor-DngH5soo.js} +5 -5
  16. package/dist/gateway/static/root/assets/{browser-automation-inputs-Bowij-nJ.js → browser-automation-inputs-DeGdfGUg.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-automations-page-CQ7SYTQj.js → browser-automations-page-D_vsV9Og.js} +1 -1
  18. package/dist/gateway/static/root/assets/browser-settings-page-DCpyjtI7.js +3 -0
  19. package/dist/gateway/static/root/assets/capabilities-settings-panel-C3clEWb3.js +8 -0
  20. package/dist/gateway/static/root/assets/channels-settings-Dibm8FJG.js +1 -0
  21. package/dist/gateway/static/root/assets/{chat-terminal-dock-DzgFHd6l.js → chat-terminal-dock-DyoR9vy9.js} +1 -1
  22. package/dist/gateway/static/root/assets/{computer-settings-page-380_vIqO.js → computer-settings-page-Dp1d7MGE.js} +1 -1
  23. package/dist/gateway/static/root/assets/{connector-service-page-DILFakXb.js → connector-service-page--SapHT59.js} +1 -1
  24. package/dist/gateway/static/root/assets/connectors-page-CV2K0GsR.js +2 -0
  25. package/dist/gateway/static/root/assets/{date-picker-CRVun-T5.js → date-picker-BpJiursq.js} +1 -1
  26. package/dist/gateway/static/root/assets/{dependency-picker-BoWqt5yU.js → dependency-picker-BKLcvu4-.js} +1 -1
  27. package/dist/gateway/static/root/assets/{desktop-pet-DPlkBjft.js → desktop-pet-DNBeDygk.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-settings-D7FgfX_K.js → desktop-pet-settings-C1wzPZky.js} +1 -1
  29. package/dist/gateway/static/root/assets/device-pairing-wizard-tCgXlVNO.js +1 -0
  30. package/dist/gateway/static/root/assets/{extension-debug-page-CT_QkSN_.js → extension-debug-page-BoG796xN.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-BF1NdcKP.js → extension-page-DatEJD_W.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-CKQVZ3Xc.js → extension-settings-page-cs0pcgqa.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-swr-BPsZPoAT.js → gateway-config-swr-CYa7aVok.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-settings-3bIy7XMr.js → gateway-settings-DSxwMkLj.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-startup-retry-cG6EqUJw.js → gateway-startup-retry-FZix2Im1.js} +1 -1
  36. package/dist/gateway/static/root/assets/home-page-3cToq8Ic.js +1 -0
  37. package/dist/gateway/static/root/assets/{image-generation-api-DI_QutIx.js → image-generation-api-IDhumota.js} +1 -1
  38. package/dist/gateway/static/root/assets/{imports-page-BUG6G72F.js → imports-page-BZ-0tsFU.js} +1 -1
  39. package/dist/gateway/static/root/assets/index-Ca4fdHsK.css +1 -0
  40. package/dist/gateway/static/root/assets/index-DqxyVarz.js +89 -0
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-qnG-4FJs.js → keyboard-shortcuts-settings-CyXLl8PE.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-app-workbench-page-B3iJWhjN.js → local-app-workbench-page-ZjNFRbSU.js} +2 -2
  43. package/dist/gateway/static/root/assets/{local-apps-page-BpEGeURS.js → local-apps-page-BmcNQOEx.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-BlgpZORR.js → locale-store-BrnrrtSS.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-0QPGj-5c.js → logs-page-DoaBVsR2.js} +2 -2
  46. package/dist/gateway/static/root/assets/{management-settings-Sl0wwidS.js → management-settings-BkCC5j8K.js} +1 -1
  47. package/dist/gateway/static/root/assets/{markdown-view-BzjjpL2H.js → markdown-view-DUfjxG4s.js} +1 -1
  48. package/dist/gateway/static/root/assets/{media-plugins-Bzkdhotn.js → media-plugins-DFNzifXX.js} +1 -1
  49. package/dist/gateway/static/root/assets/messages-BoEi2k2p.js +3 -0
  50. package/dist/gateway/static/root/assets/note-detail-panel-CLxgY3Xq.js +5 -0
  51. package/dist/gateway/static/root/assets/notes-page-CgQEb3ks.js +8 -0
  52. package/dist/gateway/static/root/assets/{page-context-capture-button-CFt4hXQ6.js → page-context-capture-button-Beu5hjB5.js} +1 -1
  53. package/dist/gateway/static/root/assets/{page-tabs-Dz_x22MQ.js → page-tabs-DWppfGs6.js} +1 -1
  54. package/dist/gateway/static/root/assets/{preview-open-alternatives-C1mkgFAl.js → preview-open-alternatives-CjBsxcGv.js} +1 -1
  55. package/dist/gateway/static/root/assets/{product-open-page-DHZgzSDV.js → product-open-page-BYoaBpad.js} +1 -1
  56. package/dist/gateway/static/root/assets/project-detail-page-BtiNnPuJ.js +1 -0
  57. package/dist/gateway/static/root/assets/{projects-page-CEr8DX9I.js → projects-page-_Qc8812P.js} +1 -1
  58. package/dist/gateway/static/root/assets/{registry-api-DMW2apOO.js → registry-api-DgKqRZl1.js} +1 -1
  59. package/dist/gateway/static/root/assets/{remote-access-hub-Db-B-Mf3.js → remote-access-hub-CpI6OjSj.js} +1 -1
  60. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DEJi0BLL.js → runtime-tools-settings-panel-Dykdq60b.js} +1 -1
  61. package/dist/gateway/static/root/assets/scenes-page-hP1OhIG6.js +2 -0
  62. package/dist/gateway/static/root/assets/{schema-form-RVltVpuG.js → schema-form-BPeMGXnp.js} +1 -1
  63. package/dist/gateway/static/root/assets/sessions-page-Dmncs4GP.js +1 -0
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-CV2LhIvd.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-form-section-BkBO7woF.js → settings-form-section-OfLwze5k.js} +1 -1
  66. package/dist/gateway/static/root/assets/{settings-page-zl0XY203.js → settings-page-D-koQ_0e.js} +1 -1
  67. package/dist/gateway/static/root/assets/{settings-page-layout-lLvHc-zF.js → settings-page-layout-r1Q31sB_.js} +1 -1
  68. package/dist/gateway/static/root/assets/{setup-status-panel-Difrpr4T.js → setup-status-panel-MiIbmzZu.js} +1 -1
  69. package/dist/gateway/static/root/assets/{share-preview-page-NC4Gj867.js → share-preview-page-BkSzw3wN.js} +1 -1
  70. package/dist/gateway/static/root/assets/{shares-settings-DPLvEcB-.js → shares-settings-BT9NIsiS.js} +1 -1
  71. package/dist/gateway/static/root/assets/skill-reload-api-BgxB-kmG.js +1 -0
  72. package/dist/gateway/static/root/assets/{skills-page-CzekvBNQ.js → skills-page-CfL2BT9s.js} +1 -1
  73. package/dist/gateway/static/root/assets/{skills-page.utils-BLeiN245.js → skills-page.utils-BKdQtHAI.js} +1 -1
  74. package/dist/gateway/static/root/assets/{system-settings-panel-Bp75s9nl.js → system-settings-panel-Del-7fwn.js} +1 -1
  75. package/dist/gateway/static/root/assets/task-detail-page-q8NLbitF.js +1 -0
  76. package/dist/gateway/static/root/assets/{tunnel-api-BDiaC6an.js → tunnel-api-DK9ICDPw.js} +1 -1
  77. package/dist/gateway/static/root/assets/{use-autosave-C_ntK_Zu.js → use-autosave-BLZSp59v.js} +1 -1
  78. package/dist/gateway/static/root/assets/user-model-page-DPfaWuJs.js +2 -0
  79. package/dist/gateway/static/root/assets/{voice-api-key-field-D4cfuMp1.js → voice-api-key-field-Lzm2ik7J.js} +1 -1
  80. package/dist/gateway/static/root/assets/{voice-config-api-Cjvd6maH.js → voice-config-api-F6NsgxNd.js} +1 -1
  81. package/dist/gateway/static/root/assets/work-discovery-overlay-CkC8ANVw.js +1 -0
  82. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C80nrmKi.js → workflow-run-setup-panel-DoevvbCd.js} +2 -2
  83. package/dist/gateway/static/root/assets/workflows-page-CZxaaUK8.js +6 -0
  84. package/dist/gateway/static/root/index.html +8 -8
  85. package/dist/package.js +1 -1
  86. package/dist/src/agent/agent-manager.js +14 -13
  87. package/dist/src/agent/embedded/run-turn.js +28 -15
  88. package/dist/src/agent/embedded/system-prompt-override.js +14 -3
  89. package/dist/src/agent/embedded/xopc-stream-bridge.js +13 -2
  90. package/dist/src/agent/memory/context-budget.js +1 -1
  91. package/dist/src/agent/orchestration/agent-turn-policy.d.ts +2 -2
  92. package/dist/src/agent/prompt/agent-system-prompt.d.ts +3 -0
  93. package/dist/src/agent/prompt/agent-system-prompt.js +16 -0
  94. package/dist/src/agent/tools/knowledge-memory-tool.js +1 -0
  95. package/dist/src/agent-config/schema.d.ts +8 -8
  96. package/dist/src/ai-assist/text-assist.js +2 -1
  97. package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
  98. package/dist/src/config/schema.d.ts +5 -5
  99. package/dist/src/connectors/connected-source-ingestion.d.ts +1 -0
  100. package/dist/src/connectors/connected-source-ingestion.js +1 -0
  101. package/dist/src/connectors/connected-source-understanding.d.ts +1 -0
  102. package/dist/src/connectors/connected-source-understanding.js +91 -31
  103. package/dist/src/connectors/content-enrichment.d.ts +1 -0
  104. package/dist/src/connectors/content-enrichment.js +3 -1
  105. package/dist/src/connectors/learning-coordinator.js +24 -24
  106. package/dist/src/gateway/chat-stream/mapper.js +9 -4
  107. package/dist/src/gateway/chat-stream/protocol.d.ts +2 -1
  108. package/dist/src/gateway/hono/lib/config-payload.d.ts +2 -2
  109. package/dist/src/gateway/hono/routes/user-model-refresh.js +2 -2
  110. package/dist/src/gateway/hono/routes/voice.js +1 -1
  111. package/dist/src/gateway/service.js +6 -6
  112. package/dist/src/knowledge/ingestion-service.d.ts +5 -2
  113. package/dist/src/knowledge/ingestion-service.js +24 -15
  114. package/dist/src/knowledge-memory/domain.d.ts +1 -1
  115. package/dist/src/platform/client.d.ts +1 -1
  116. package/dist/src/platform/contracts.d.ts +1 -1
  117. package/dist/src/providers/extension-stream-bridge.js +6 -4
  118. package/dist/src/providers/model-call.js +3 -3
  119. package/dist/src/providers/presentation.js +4 -3
  120. package/dist/src/storage/sqlite/context-extraction-repository.d.ts +1 -2
  121. package/dist/src/storage/sqlite/context-extraction-repository.js +1 -9
  122. package/dist/src/storage/sqlite/index.d.ts +1 -2
  123. package/dist/src/storage/sqlite/index.js +2 -3
  124. package/dist/src/storage/sqlite/knowledge-repository.d.ts +1 -0
  125. package/dist/src/storage/sqlite/knowledge-repository.js +3 -0
  126. package/dist/src/storage/sqlite/migrations/200_connected_work_threads.sql +92 -0
  127. package/dist/src/storage/sqlite/migrations/201_connector_extraction_audit.sql +127 -0
  128. package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
  129. package/dist/src/storage/sqlite/migrations/runner.js +4 -4
  130. package/dist/src/storage/sqlite/schema.js +1 -1
  131. package/dist/src/storage/sqlite/schema.sql +1 -1
  132. package/dist/src/user-context/domain.d.ts +0 -13
  133. package/dist/src/user-context/sources/index.js +2 -2
  134. package/dist/src/user-context/sources/repository.d.ts +10 -0
  135. package/dist/src/user-context/sources/repository.js +19 -4
  136. package/dist/src/user-context/sources/types.d.ts +1 -0
  137. package/package.json +8 -8
  138. package/dist/gateway/static/root/assets/automations-workspace-B5s10G5F.js +0 -7
  139. package/dist/gateway/static/root/assets/browser-settings-page-vqLoPOOg.js +0 -3
  140. package/dist/gateway/static/root/assets/capabilities-settings-panel-DI68WGYd.js +0 -8
  141. package/dist/gateway/static/root/assets/channels-settings-Cimssy-S.js +0 -1
  142. package/dist/gateway/static/root/assets/connectors-page-COmFp9HC.js +0 -2
  143. package/dist/gateway/static/root/assets/device-pairing-wizard-BP6yxut8.js +0 -1
  144. package/dist/gateway/static/root/assets/home-page-DFNDLFgv.js +0 -1
  145. package/dist/gateway/static/root/assets/index-BCi8nfxs.js +0 -89
  146. package/dist/gateway/static/root/assets/index-DWgd1VK2.css +0 -1
  147. package/dist/gateway/static/root/assets/messages-2GhUD7SC.js +0 -3
  148. package/dist/gateway/static/root/assets/note-detail-panel-BXtD71j1.js +0 -5
  149. package/dist/gateway/static/root/assets/notes-page-DNY4vW-u.js +0 -8
  150. package/dist/gateway/static/root/assets/project-detail-page-D3NhZ7ZZ.js +0 -1
  151. package/dist/gateway/static/root/assets/scenes-page-BUUX-PnI.js +0 -2
  152. package/dist/gateway/static/root/assets/sessions-page-Rm4H2okS.js +0 -1
  153. package/dist/gateway/static/root/assets/settings-advanced-gate-VxPItcOG.js +0 -1
  154. package/dist/gateway/static/root/assets/skill-reload-api-CKdLCf_-.js +0 -1
  155. package/dist/gateway/static/root/assets/task-detail-page-Bh8H4FYR.js +0 -1
  156. package/dist/gateway/static/root/assets/user-model-page-C7gFCGAV.js +0 -2
  157. package/dist/gateway/static/root/assets/work-discovery-overlay-Ce6ToB0O.js +0 -1
  158. package/dist/gateway/static/root/assets/workflows-page-CVQjo3RI.js +0 -6
  159. package/dist/src/storage/sqlite/context-relation-repository.d.ts +0 -50
  160. package/dist/src/storage/sqlite/context-relation-repository.js +0 -98
@@ -24,6 +24,7 @@ import { markTurnToolResult } from "../memory/turn-provenance.js";
24
24
  import { RepositoryInstructions } from "../coding/repository-instructions.js";
25
25
  import { RunVerification } from "../coding/run-verification.js";
26
26
  import { withDelegationScope } from "../orchestration/delegation-scope.js";
27
+ import { getCurrentSystemPrompt, getCurrentTools } from "@earendil-works/pi-ai";
27
28
  //#region src/agent/embedded/run-turn.ts
28
29
  init_connection_wait_repository();
29
30
  init_logger();
@@ -107,7 +108,7 @@ async function maybeRecoverContextOverflow(params) {
107
108
  policy: params.policy,
108
109
  budget: {
109
110
  contextWindow: params.model.contextWindow ?? 128e3,
110
- systemPrompt: params.agent.state.systemPrompt,
111
+ systemPrompt: params.systemPrompt,
111
112
  tools: params.agent.state.tools,
112
113
  reserveTokens: params.policy.reserveTokens,
113
114
  triggerThreshold: params.policy.triggerThreshold,
@@ -202,11 +203,13 @@ async function runXopcEmbeddedTurn(params) {
202
203
  timestamp: Date.now()
203
204
  }]
204
205
  };
206
+ let effectiveSystemPrompt = getCurrentSystemPrompt(effectiveContext.messages);
207
+ let effectiveTools = getCurrentTools(effectiveContext.messages);
205
208
  const projection = projectContextForModel({
206
209
  messages: effectiveContext.messages,
207
210
  contextWindow: streamModel.contextWindow ?? 128e3,
208
- systemPrompt: effectiveContext.systemPrompt,
209
- tools: effectiveContext.tools,
211
+ systemPrompt: effectiveSystemPrompt,
212
+ tools: effectiveTools,
210
213
  reserveTokens: compactionPolicy.reserveTokens,
211
214
  minToolResultKeepChars: compactionPolicy.minToolResultKeepChars,
212
215
  canCompact: false,
@@ -217,6 +220,8 @@ async function runXopcEmbeddedTurn(params) {
217
220
  ...effectiveContext,
218
221
  messages: projection.messages
219
222
  };
223
+ effectiveSystemPrompt = getCurrentSystemPrompt(effectiveContext.messages);
224
+ effectiveTools = getCurrentTools(effectiveContext.messages);
220
225
  log.warn({
221
226
  conversationId,
222
227
  runId,
@@ -229,8 +234,8 @@ async function runXopcEmbeddedTurn(params) {
229
234
  const assessed = assessContext({
230
235
  messages: effectiveContext.messages,
231
236
  contextWindow: streamModel.contextWindow ?? 128e3,
232
- systemPrompt: effectiveContext.systemPrompt,
233
- tools: effectiveContext.tools,
237
+ systemPrompt: effectiveSystemPrompt,
238
+ tools: effectiveTools,
234
239
  reserveTokens: compactionPolicy.reserveTokens,
235
240
  minToolResultKeepChars: compactionPolicy.minToolResultKeepChars
236
241
  }, compactionPolicy.maxActiveTranscriptBytes);
@@ -239,10 +244,12 @@ async function runXopcEmbeddedTurn(params) {
239
244
  ...effectiveContext,
240
245
  messages: assessed.messages
241
246
  };
247
+ effectiveSystemPrompt = getCurrentSystemPrompt(effectiveContext.messages);
248
+ effectiveTools = getCurrentTools(effectiveContext.messages);
242
249
  const promptCacheSnapshot = buildPromptCacheSnapshot({
243
250
  model: streamModel,
244
- systemPrompt: effectiveContext.systemPrompt,
245
- tools: effectiveContext.tools,
251
+ systemPrompt: effectiveSystemPrompt,
252
+ tools: effectiveTools,
246
253
  reasoning: options?.reasoning
247
254
  });
248
255
  const promptCacheChanges = observePromptCacheSnapshot(conversationId, promptCacheSnapshot);
@@ -251,18 +258,18 @@ async function runXopcEmbeddedTurn(params) {
251
258
  runId,
252
259
  reusedRunner: reused,
253
260
  modelRef: `${streamModel.provider}/${streamModel.id}`,
254
- systemPromptLength: effectiveContext.systemPrompt?.length ?? 0,
255
- messageCount: effectiveContext.messages.length,
261
+ systemPromptLength: effectiveSystemPrompt.length,
262
+ messageCount: effectiveContext.messages.filter((message) => message.role !== "system").length,
256
263
  transcriptRepaired: hygienicMessages !== sourceMessages,
257
- toolCount: effectiveContext.tools?.length ?? 0,
264
+ toolCount: effectiveTools.length,
258
265
  lastUserMessagePreview: getLastUserMessagePreview(effectiveContext.messages),
259
266
  loopWarningInjected: !!loopGuard.injection,
260
267
  promptCache: promptCacheSnapshot,
261
268
  promptCacheChanges,
262
269
  ...process.env.XOPC_LOG_LLM_PAYLOAD === "true" ? { effectiveContext: {
263
- systemPrompt: effectiveContext.systemPrompt,
264
- messages: effectiveContext.messages,
265
- tools: effectiveContext.tools
270
+ systemPrompt: effectiveSystemPrompt,
271
+ messages: effectiveContext.messages.filter((message) => message.role !== "system"),
272
+ tools: effectiveTools
266
273
  } } : {}
267
274
  }, "Sending messages to AI");
268
275
  return streamFnWithXopcExtensions(streamModel, effectiveContext, { ...options });
@@ -339,9 +346,13 @@ async function runXopcEmbeddedTurn(params) {
339
346
  });
340
347
  return checked;
341
348
  };
342
- session.agent.shouldStopAfterTurn = (context) => {
349
+ const baseFinishTurn = session.agent.finishTurn;
350
+ session.agent.finishTurn = async (context, signal) => {
351
+ const baseDecision = await baseFinishTurn?.(context, signal);
352
+ if (baseDecision && baseDecision.action === "end") return { action: "end" };
343
353
  policyStopped ||= params.turnPolicy?.shouldStopAfterTurn(context) ?? false;
344
- return policyStopped || connectionStopped || clarificationStopped;
354
+ if (policyStopped || connectionStopped || clarificationStopped) return { action: "end" };
355
+ if (baseDecision && baseDecision.action === "continue") return { action: "continue" };
345
356
  };
346
357
  unsubscribe = subscribeEmbeddedSessionEvents(session, (event) => {
347
358
  if (event.type === "message_end" && event.message.role === "assistant") recordPromptCacheTouch(conversationId, resolvedModel, event.message.usage);
@@ -392,6 +403,7 @@ async function runXopcEmbeddedTurn(params) {
392
403
  conversationId,
393
404
  transcriptRuntime,
394
405
  policy: compactionPolicy,
406
+ systemPrompt: [systemPrompt, rootInstructions].filter(Boolean).join("\n\n"),
395
407
  abortSignal: runAbortSignal,
396
408
  onEvent
397
409
  });
@@ -443,6 +455,7 @@ async function runXopcEmbeddedTurn(params) {
443
455
  lastAssistantText: lastAssistantPlainText(session)
444
456
  };
445
457
  } finally {
458
+ session.agent.finishTurn = baseFinishTurn;
446
459
  runAbortSignal.removeEventListener("abort", abortListener);
447
460
  }
448
461
  } catch (err) {
@@ -1,10 +1,21 @@
1
+ import { replaceAgentSystemPrompt } from "../prompt/agent-system-prompt.js";
1
2
  //#region src/agent/embedded/system-prompt-override.ts
2
3
  function applySystemPromptOverrideToSession(session, override) {
3
4
  const prompt = override.trim();
4
- session.agent.state.systemPrompt = prompt;
5
5
  const mutableSession = session;
6
- mutableSession._baseSystemPrompt = prompt;
7
- mutableSession._rebuildSystemPrompt = () => prompt;
6
+ const applyOverride = (options) => {
7
+ if (options) options.forceSystemPrompt = prompt;
8
+ };
9
+ applyOverride(mutableSession._baseSystemPromptOptions);
10
+ applyOverride(mutableSession._runSystemPromptOptions);
11
+ const originalRebuild = mutableSession._xopcOriginalRebuildSystemPrompt ?? mutableSession._rebuildSystemPrompt?.bind(session);
12
+ if (originalRebuild && !mutableSession._xopcOriginalRebuildSystemPrompt) mutableSession._xopcOriginalRebuildSystemPrompt = originalRebuild;
13
+ if (originalRebuild) mutableSession._rebuildSystemPrompt = (toolNames) => {
14
+ const result = originalRebuild(toolNames);
15
+ applyOverride(mutableSession._baseSystemPromptOptions);
16
+ return result;
17
+ };
18
+ replaceAgentSystemPrompt(session.agent, prompt);
8
19
  }
9
20
  //#endregion
10
21
  export { applySystemPromptOverrideToSession };
@@ -2,6 +2,7 @@ import "../../providers/constants.js";
2
2
  import { init_providers } from "../../providers/index.js";
3
3
  import { createExtensionAwareStreamFn } from "../../providers/extension-stream-bridge.js";
4
4
  import { preparePromptCacheContext, withPromptCachePayloadTransform } from "../../providers/prompt-cache-payload.js";
5
+ import { getCurrentSystemPrompt, getCurrentTools, normalizeContext } from "@earendil-works/pi-ai";
5
6
  //#region src/agent/embedded/xopc-stream-bridge.ts
6
7
  init_providers();
7
8
  /**
@@ -16,8 +17,18 @@ init_providers();
16
17
  function wrapStreamFnForXopcExtensions(originalStreamFn, promptCachePolicy) {
17
18
  const extensionStreamFn = createExtensionAwareStreamFn();
18
19
  return ((model, context, options) => {
19
- if (model.baseUrl === "extension://provider-plugin") return extensionStreamFn(model, preparePromptCacheContext(model, context), options);
20
- return originalStreamFn(model, preparePromptCacheContext(model, context), withPromptCachePayloadTransform(model, context, options, promptCachePolicy));
20
+ const promptContext = {
21
+ systemPrompt: getCurrentSystemPrompt(context.messages),
22
+ tools: getCurrentTools(context.messages)
23
+ };
24
+ const preparedContext = preparePromptCacheContext(model, promptContext);
25
+ const providerContext = preparedContext.systemPrompt === promptContext.systemPrompt ? context : normalizeContext({
26
+ systemPrompt: preparedContext.systemPrompt,
27
+ tools: promptContext.tools,
28
+ messages: context.messages.filter((message) => message.role !== "system")
29
+ });
30
+ if (model.baseUrl === "extension://provider-plugin") return extensionStreamFn(model, providerContext, options);
31
+ return originalStreamFn(model, providerContext, withPromptCachePayloadTransform(model, promptContext, options, promptCachePolicy));
21
32
  });
22
33
  }
23
34
  //#endregion
@@ -45,7 +45,7 @@ function evaluateContextBudget(input) {
45
45
  const hardLimitTokens = Math.max(1024, contextWindow - reserveTokens);
46
46
  const triggerThreshold = Math.min(.98, Math.max(.1, input.triggerThreshold ?? .8));
47
47
  const triggerTokens = Math.min(hardLimitTokens, Math.floor(contextWindow * triggerThreshold));
48
- const transcriptTokens = estimateMessagesTokens(input.messages);
48
+ const transcriptTokens = estimateMessagesTokens(input.systemPrompt === void 0 ? input.messages : input.messages.filter((message) => message.role !== "system"));
49
49
  const systemPromptTokens = estimateTextTokens(input.systemPrompt ?? "");
50
50
  const currentUserTokens = input.currentUserMessage ? estimateMessageTokens(input.currentUserMessage) : 0;
51
51
  const toolSchemaTokens = estimateToolSchemaTokens(input.tools ?? []);
@@ -1,9 +1,9 @@
1
- import type { AfterToolCallContext, BeforeToolCallContext, BeforeToolCallResult, ShouldStopAfterTurnContext } from '@earendil-works/pi-agent-core';
1
+ import type { AfterToolCallContext, AgentTurnContext, BeforeToolCallContext, BeforeToolCallResult } from '@earendil-works/pi-agent-core';
2
2
  export interface AgentTurnPolicy {
3
3
  reset(): void;
4
4
  beforeToolCall(context: BeforeToolCallContext, signal?: AbortSignal): Promise<BeforeToolCallResult | undefined>;
5
5
  afterToolCall(context: AfterToolCallContext): Promise<undefined>;
6
- shouldStopAfterTurn(context: ShouldStopAfterTurnContext): boolean;
6
+ shouldStopAfterTurn(context: AgentTurnContext): boolean;
7
7
  }
8
8
  export interface AgentTurnPolicyOptions {
9
9
  maxTurns?: number;
@@ -0,0 +1,3 @@
1
+ import type { Agent } from '@earendil-works/pi-agent-core';
2
+ /** Replace the replayed prompt while preserving the transcript's current tool declarations. */
3
+ export declare function replaceAgentSystemPrompt(agent: Agent, systemPrompt: string): void;
@@ -0,0 +1,16 @@
1
+ import { getCurrentSystemMessage } from "@earendil-works/pi-ai";
2
+ //#region src/agent/prompt/agent-system-prompt.ts
3
+ /** Replace the replayed prompt while preserving the transcript's current tool declarations. */
4
+ function replaceAgentSystemPrompt(agent, systemPrompt) {
5
+ const messages = agent.state.messages;
6
+ const current = getCurrentSystemMessage(messages);
7
+ const systemMessage = {
8
+ role: "system",
9
+ content: systemPrompt,
10
+ ...current?.toolsAdded ? { toolsAdded: current.toolsAdded } : {},
11
+ timestamp: current?.timestamp ?? Date.now()
12
+ };
13
+ agent.state.messages = [systemMessage, ...messages.filter((message) => message.role !== "system")];
14
+ }
15
+ //#endregion
16
+ export { replaceAgentSystemPrompt };
@@ -12,6 +12,7 @@ const SearchSchema = Type.Object({
12
12
  const GetSchema = Type.Object({ id: Type.String() });
13
13
  const WriteSchema = Type.Object({
14
14
  kind: Type.Union([
15
+ Type.Literal("work_thread"),
15
16
  Type.Literal("project_fact"),
16
17
  Type.Literal("workspace_fact"),
17
18
  Type.Literal("decision"),
@@ -23,10 +23,10 @@ export declare const ComputerModelRouteSchema: z.ZodObject<{
23
23
  export declare const ModelIntentSchema: z.ZodEnum<{
24
24
  review: "review";
25
25
  coding: "coding";
26
- understanding: "understanding";
27
26
  fast: "fast";
28
27
  reasoning: "reasoning";
29
28
  vision: "vision";
29
+ understanding: "understanding";
30
30
  }>;
31
31
  export declare const AgentModelsDefaultsSchema: z.ZodObject<{
32
32
  chat: z.ZodObject<{
@@ -36,10 +36,10 @@ export declare const AgentModelsDefaultsSchema: z.ZodObject<{
36
36
  intents: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
37
37
  review: "review";
38
38
  coding: "coding";
39
- understanding: "understanding";
40
39
  fast: "fast";
41
40
  reasoning: "reasoning";
42
41
  vision: "vision";
42
+ understanding: "understanding";
43
43
  }> & z.core.$partial, z.ZodObject<{
44
44
  primary: z.ZodString;
45
45
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -67,10 +67,10 @@ export declare const AgentModelsOverrideSchema: z.ZodObject<{
67
67
  intents: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
68
68
  review: "review";
69
69
  coding: "coding";
70
- understanding: "understanding";
71
70
  fast: "fast";
72
71
  reasoning: "reasoning";
73
72
  vision: "vision";
73
+ understanding: "understanding";
74
74
  }> & z.core.$partial, z.ZodNullable<z.ZodObject<{
75
75
  primary: z.ZodString;
76
76
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -169,10 +169,10 @@ export declare const AgentDefaultsSchema: z.ZodObject<{
169
169
  intents: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
170
170
  review: "review";
171
171
  coding: "coding";
172
- understanding: "understanding";
173
172
  fast: "fast";
174
173
  reasoning: "reasoning";
175
174
  vision: "vision";
175
+ understanding: "understanding";
176
176
  }> & z.core.$partial, z.ZodObject<{
177
177
  primary: z.ZodString;
178
178
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -260,10 +260,10 @@ export declare const AgentEntrySchema: z.ZodObject<{
260
260
  intents: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
261
261
  review: "review";
262
262
  coding: "coding";
263
- understanding: "understanding";
264
263
  fast: "fast";
265
264
  reasoning: "reasoning";
266
265
  vision: "vision";
266
+ understanding: "understanding";
267
267
  }> & z.core.$partial, z.ZodNullable<z.ZodObject<{
268
268
  primary: z.ZodString;
269
269
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -343,10 +343,10 @@ export declare const AgentsConfigSchema: z.ZodObject<{
343
343
  intents: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
344
344
  review: "review";
345
345
  coding: "coding";
346
- understanding: "understanding";
347
346
  fast: "fast";
348
347
  reasoning: "reasoning";
349
348
  vision: "vision";
349
+ understanding: "understanding";
350
350
  }> & z.core.$partial, z.ZodObject<{
351
351
  primary: z.ZodString;
352
352
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -430,10 +430,10 @@ export declare const AgentsConfigSchema: z.ZodObject<{
430
430
  intents: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
431
431
  review: "review";
432
432
  coding: "coding";
433
- understanding: "understanding";
434
433
  fast: "fast";
435
434
  reasoning: "reasoning";
436
435
  vision: "vision";
436
+ understanding: "understanding";
437
437
  }> & z.core.$partial, z.ZodNullable<z.ZodObject<{
438
438
  primary: z.ZodString;
439
439
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -519,10 +519,10 @@ export declare const EffectiveAgentConfigSchema: z.ZodObject<{
519
519
  intents: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
520
520
  review: "review";
521
521
  coding: "coding";
522
- understanding: "understanding";
523
522
  fast: "fast";
524
523
  reasoning: "reasoning";
525
524
  vision: "vision";
525
+ understanding: "understanding";
526
526
  }> & z.core.$partial, z.ZodObject<{
527
527
  primary: z.ZodString;
528
528
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -4,6 +4,7 @@ import { getDefaultModelSync, init_providers, resolveModel } from "../providers/
4
4
  import { createExtensionAwareStreamFn } from "../providers/extension-stream-bridge.js";
5
5
  import { isLocalModelBaseUrl, resolveModelCallApiKey, resolveModelCallOptions } from "../providers/model-call.js";
6
6
  import { getAssistantMessageErrorReason, stripCodeFences } from "../providers/model-response.js";
7
+ import { normalizeContext } from "@earendil-works/pi-ai";
7
8
  //#region src/ai-assist/text-assist.ts
8
9
  init_providers();
9
10
  init_logger();
@@ -244,7 +245,7 @@ async function* streamTextAssist(request, config, signal) {
244
245
  modelId: model.id,
245
246
  scenario: scenario.id
246
247
  };
247
- const stream = await createExtensionAwareStreamFn()(model, prompt, modelCallOptions);
248
+ const stream = await createExtensionAwareStreamFn()(model, normalizeContext(prompt), modelCallOptions);
248
249
  let streamedText = "";
249
250
  for await (const event of stream) {
250
251
  const streamEvent = event;
@@ -53,7 +53,7 @@ async function checkDatabaseSchema(ctx) {
53
53
  id: "database-schema",
54
54
  label: "Database schema",
55
55
  status: "pass",
56
- message: `SQLite schema v${status.dbVersion} (current release v199).`,
56
+ message: `SQLite schema v${status.dbVersion} (current release v201).`,
57
57
  hints: []
58
58
  };
59
59
  }
@@ -29,10 +29,10 @@ export declare const AgentModelsSchema: z.ZodObject<{
29
29
  intents: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
30
30
  review: "review";
31
31
  coding: "coding";
32
- understanding: "understanding";
33
32
  fast: "fast";
34
33
  reasoning: "reasoning";
35
34
  vision: "vision";
35
+ understanding: "understanding";
36
36
  }> & z.core.$partial, z.ZodNullable<z.ZodObject<{
37
37
  primary: z.ZodString;
38
38
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -64,10 +64,10 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
64
64
  intents: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
65
65
  review: "review";
66
66
  coding: "coding";
67
- understanding: "understanding";
68
67
  fast: "fast";
69
68
  reasoning: "reasoning";
70
69
  vision: "vision";
70
+ understanding: "understanding";
71
71
  }> & z.core.$partial, z.ZodObject<{
72
72
  primary: z.ZodString;
73
73
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -151,10 +151,10 @@ export declare const AgentsConfigSchema: z.ZodDefault<z.ZodObject<{
151
151
  intents: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
152
152
  review: "review";
153
153
  coding: "coding";
154
- understanding: "understanding";
155
154
  fast: "fast";
156
155
  reasoning: "reasoning";
157
156
  vision: "vision";
157
+ understanding: "understanding";
158
158
  }> & z.core.$partial, z.ZodNullable<z.ZodObject<{
159
159
  primary: z.ZodString;
160
160
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -1586,10 +1586,10 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1586
1586
  intents: z.ZodDefault<z.ZodRecord<z.ZodEnum<{
1587
1587
  review: "review";
1588
1588
  coding: "coding";
1589
- understanding: "understanding";
1590
1589
  fast: "fast";
1591
1590
  reasoning: "reasoning";
1592
1591
  vision: "vision";
1592
+ understanding: "understanding";
1593
1593
  }> & z.core.$partial, z.ZodObject<{
1594
1594
  primary: z.ZodString;
1595
1595
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -1673,10 +1673,10 @@ export declare const ConfigSchema: z.ZodDefault<z.ZodObject<{
1673
1673
  intents: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
1674
1674
  review: "review";
1675
1675
  coding: "coding";
1676
- understanding: "understanding";
1677
1676
  fast: "fast";
1678
1677
  reasoning: "reasoning";
1679
1678
  vision: "vision";
1679
+ understanding: "understanding";
1680
1680
  }> & z.core.$partial, z.ZodNullable<z.ZodObject<{
1681
1681
  primary: z.ZodString;
1682
1682
  fallbacks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -19,6 +19,7 @@ export declare function ingestComposioConnectedSource(input: {
19
19
  sourceInstanceId: string;
20
20
  itemsSeen: number;
21
21
  itemsIndexed: number;
22
+ sourceItemIds: string[];
22
23
  recordIds: string[];
23
24
  }>;
24
25
  export declare function ingestLocalFolderSource(input: {
@@ -335,6 +335,7 @@ async function ingestComposioConnectedSource(input) {
335
335
  sourceInstanceId,
336
336
  itemsSeen: syncRun.itemsSeen,
337
337
  itemsIndexed: syncRun.itemsCreated + syncRun.itemsUpdated,
338
+ sourceItemIds: syncRun.changedItemIds,
338
339
  recordIds
339
340
  };
340
341
  }
@@ -7,6 +7,7 @@ export declare function deriveConnectedSourceUnderstanding(input: {
7
7
  config: Config;
8
8
  agentId: string;
9
9
  sourceInstanceId: string;
10
+ sourceItemIds: string[];
10
11
  sourceRunId: string;
11
12
  processingPolicy: 'local_only' | 'remote_allowed';
12
13
  analyze?: typeof analyzeUnderstandingSources;
@@ -1,6 +1,8 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
1
3
  import { finishContextExtractionRun } from "../storage/sqlite/context-extraction-repository.js";
2
4
  import { createContextEvidence } from "../storage/sqlite/context-evidence-repository.js";
3
- import { listKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
5
+ import { getKnowledgeSourceItem } from "../storage/sqlite/knowledge-repository.js";
4
6
  import "../storage/sqlite/index.js";
5
7
  import { writeKnowledgeItem } from "../knowledge-memory/repository.js";
6
8
  import "../knowledge-memory/index.js";
@@ -9,8 +11,14 @@ import "../user-model/index.js";
9
11
  import { claimRegisteredExtraction } from "../user-context/extraction/registry.js";
10
12
  import { allowsRemoteSourceProcessing } from "../user-context/sources/processing-policy.js";
11
13
  import { analyzeUnderstandingSources } from "../work-discovery/analyzer.js";
14
+ import { createHash } from "node:crypto";
12
15
  //#region src/connectors/connected-source-understanding.ts
16
+ init_logger();
13
17
  const MAX_CONNECTED_ITEMS = 150;
18
+ const log = createLogger("ConnectedSourceUnderstanding");
19
+ function evidenceKey(sourceInstanceId, evidenceRefs) {
20
+ return `connected-thread:${sourceInstanceId}:${createHash("sha256").update([...evidenceRefs].sort().join("\n")).digest("hex").slice(0, 24)}`;
21
+ }
14
22
  function normalizedValue(item) {
15
23
  if (!item.normalizedText) return {};
16
24
  try {
@@ -66,22 +74,25 @@ function durableEvidence(candidate, items) {
66
74
  return candidate.confidence === "high" && evidence.every((item) => item.ownerAttribution === "user") && evidence.length >= required && dates.size >= required ? evidence : [];
67
75
  }
68
76
  async function deriveConnectedSourceUnderstanding(input) {
69
- const sourceItems = listKnowledgeSourceItems({
70
- agentId: input.agentId,
71
- sourceInstanceId: input.sourceInstanceId,
72
- includeDeleted: false,
73
- limit: MAX_CONNECTED_ITEMS
74
- });
77
+ const sourceItems = [...new Set(input.sourceItemIds)].slice(0, MAX_CONNECTED_ITEMS).flatMap((itemId) => getKnowledgeSourceItem(itemId) ?? []).filter((item) => item.sourceInstanceId === input.sourceInstanceId && item.metadata.agentId === input.agentId && !item.deletedAt);
75
78
  const items = connectedItemsForUnderstanding(sourceItems);
76
- if (!items.length) return {
77
- created: 0,
78
- knowledgeCount: 0,
79
- status: "completed"
80
- };
79
+ if (!items.length) {
80
+ log.info({
81
+ sourceRunId: input.sourceRunId,
82
+ sourceInstanceId: input.sourceInstanceId,
83
+ sourceItemCount: 0,
84
+ reason: "no_changed_items"
85
+ }, "Connected source semantic analysis skipped");
86
+ return {
87
+ created: 0,
88
+ knowledgeCount: 0,
89
+ status: "completed"
90
+ };
91
+ }
81
92
  const extraction = claimRegisteredExtraction({
82
93
  extractorId: "connector-semantic",
83
94
  sourceRef: `understanding-source-run:${input.sourceRunId}`,
84
- contentForHash: sourceItems.map((item) => `${item.id}:${item.sourceUpdatedAt ?? ""}`).join("\n"),
95
+ contentForHash: sourceItems.map((item) => `${item.id}:${item.contentHash}`).join("\n"),
85
96
  processingPolicy: input.processingPolicy,
86
97
  destination: "remote_model"
87
98
  });
@@ -97,10 +108,20 @@ async function deriveConnectedSourceUnderstanding(input) {
97
108
  });
98
109
  input.assertAuthorized?.();
99
110
  const byRef = new Map(items.map((item) => [item.evidenceRef, item]));
111
+ const outputs = [];
100
112
  let created = 0;
101
113
  for (const candidate of analysis.profileCandidates.filter(isPortraitCandidate)) {
102
114
  const evidenceItems = durableEvidence(candidate, byRef);
103
- if (!evidenceItems.length) continue;
115
+ const candidateKey = `connected-profile:${candidate.category}:${candidate.factKey}`;
116
+ if (!evidenceItems.length) {
117
+ outputs.push({
118
+ candidateKey,
119
+ outcome: "rejected"
120
+ });
121
+ continue;
122
+ }
123
+ let assertionId;
124
+ let candidateCreated = false;
104
125
  for (const [index, evidenceItem] of evidenceItems.entries()) {
105
126
  const evidence = createContextEvidence({
106
127
  sourceType: "connector",
@@ -135,32 +156,71 @@ async function deriveConnectedSourceUnderstanding(input) {
135
156
  evidenceId: evidence.id,
136
157
  evidenceConfidence: .9
137
158
  });
159
+ assertionId = result.assertion?.id ?? assertionId;
160
+ candidateCreated ||= result.action === "created" || result.action === "superseded";
138
161
  if (index === 0 && result.action === "created") created += 1;
139
162
  }
163
+ outputs.push({
164
+ candidateKey,
165
+ ...assertionId ? {
166
+ objectType: "assertion",
167
+ objectId: assertionId
168
+ } : {},
169
+ outcome: assertionId ? candidateCreated ? "created" : "deduplicated" : "rejected"
170
+ });
140
171
  }
141
172
  let knowledgeCount = 0;
142
- for (const thread of analysis.workThreadCandidates) if (writeKnowledgeItem({
143
- kind: "project_fact",
144
- scope: {
145
- type: "agent",
146
- id: input.agentId
147
- },
148
- content: `${thread.title}: ${thread.summary}`,
149
- canonicalKey: `connected-thread:${input.sourceInstanceId}:${thread.topicKey}`,
150
- confidence: thread.confidence === "high" ? .9 : thread.confidence === "medium" ? .72 : .55,
151
- importance: thread.horizon === "current" ? .75 : .5,
152
- originClass: "untrusted",
153
- sourceAgentId: input.agentId,
154
- source: {
155
- sourceRunId: input.sourceRunId,
156
- evidenceRefs: thread.evidenceRefs
173
+ for (const thread of analysis.workThreadCandidates) {
174
+ const evidenceRefs = [...new Set(thread.evidenceRefs)].filter((ref) => byRef.has(ref));
175
+ const candidateKey = evidenceKey(input.sourceInstanceId, evidenceRefs);
176
+ if (!evidenceRefs.length) {
177
+ outputs.push({
178
+ candidateKey,
179
+ outcome: "rejected"
180
+ });
181
+ continue;
157
182
  }
158
- }).created) knowledgeCount += 1;
183
+ const result = writeKnowledgeItem({
184
+ kind: "work_thread",
185
+ scope: { type: "global" },
186
+ content: `${thread.title}: ${thread.summary}`,
187
+ canonicalKey: candidateKey,
188
+ confidence: thread.confidence === "high" ? .9 : thread.confidence === "medium" ? .72 : .55,
189
+ importance: thread.horizon === "current" ? .75 : .5,
190
+ originClass: "untrusted",
191
+ sourceAgentId: input.agentId,
192
+ source: {
193
+ sourceRunId: input.sourceRunId,
194
+ evidenceRefs
195
+ },
196
+ replaceExisting: true
197
+ });
198
+ if (result.created) knowledgeCount += 1;
199
+ outputs.push({
200
+ candidateKey,
201
+ ...result.item ? {
202
+ objectType: "knowledge",
203
+ objectId: result.item.id
204
+ } : {},
205
+ outcome: result.created ? "created" : result.item ? "deduplicated" : "rejected"
206
+ });
207
+ }
159
208
  finishContextExtractionRun({
160
209
  runId: extraction.run.id,
161
- status: "completed"
210
+ status: "completed",
211
+ outputs
162
212
  });
163
213
  const sourceStatus = analysis.sourceStatuses.find((item) => item.sourceId === "connected-work");
214
+ log.info({
215
+ sourceRunId: input.sourceRunId,
216
+ sourceInstanceId: input.sourceInstanceId,
217
+ sourceItemCount: sourceItems.length,
218
+ assertionCreated: created,
219
+ knowledgeCreated: knowledgeCount,
220
+ deduplicated: outputs.filter((output) => output.outcome === "deduplicated").length,
221
+ rejected: outputs.filter((output) => output.outcome === "rejected").length,
222
+ sourceStatus: sourceStatus?.status ?? "failed"
223
+ }, "Connected source semantic analysis finished");
164
224
  return {
165
225
  created,
166
226
  knowledgeCount,
@@ -15,6 +15,7 @@ export type ConnectedContentReadResult = {
15
15
  sourceItemId: string;
16
16
  error: string;
17
17
  }>;
18
+ sourceItemIds: string[];
18
19
  recordIds: string[];
19
20
  };
20
21
  export declare function listConnectedContentCandidates(options: {
@@ -194,6 +194,7 @@ async function readConnectedContent(input) {
194
194
  requested: sourceItemIds.length,
195
195
  completed: 0,
196
196
  failed: [],
197
+ sourceItemIds: [],
197
198
  recordIds: []
198
199
  };
199
200
  const updatedSources = /* @__PURE__ */ new Set();
@@ -242,7 +243,8 @@ async function readConnectedContent(input) {
242
243
  if (execution.decision !== "allowed") throw new Error(execution.reason);
243
244
  const content = recipe.mode === "inline" ? inlineContent(execution.result) : await downloadedContent(execution.result, downloadDirectory);
244
245
  if (!content.trim()) throw new Error("The connector returned empty text content.");
245
- upsertKnowledgeSourceItems([updatedSourceItem(item, content, recipe.actionId)]);
246
+ const stored = upsertKnowledgeSourceItems([updatedSourceItem(item, content, recipe.actionId)]);
247
+ result.sourceItemIds.push(...stored.changedItemIds);
246
248
  completedReads.add(item.id);
247
249
  updatedSources.add(item.sourceInstanceId);
248
250
  result.completed += 1;