@xopcai/xopc 0.0.408 → 0.0.410
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.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-B0em9Xfs.js → agent-avatar-dicebear-ColV_Z1C.js} +1 -1
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-rgRXzBCX.js +1 -0
- package/dist/gateway/static/root/assets/agents-C1rSl_yE.js +77 -0
- package/dist/gateway/static/root/assets/app-management-settings-panel-B-Cl1lzt.js +1 -0
- package/dist/gateway/static/root/assets/appearance-settings-byEnJz9H.js +1 -0
- package/dist/gateway/static/root/assets/apps-page-BfVMfjkC.js +1 -0
- package/dist/gateway/static/root/assets/{archive-plugin-BjWaZIHe.js → archive-plugin-BXssEuq3.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-IkrLEkMb.js → automations-page-C-puATkS.js} +1 -1
- package/dist/gateway/static/root/assets/automations-workspace-b7MTHd-X.js +6 -0
- package/dist/gateway/static/root/assets/{binary-plugins-DKy1DC62.js → binary-plugins-DBz_2AhG.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-4E-OdmNm.js → block-editor-BOO5kjIl.js} +4 -4
- package/dist/gateway/static/root/assets/browser-automation-inputs-D8bZ9iz2.js +1 -0
- package/dist/gateway/static/root/assets/browser-automations-page-DMqDOJgO.js +3 -0
- package/dist/gateway/static/root/assets/browser-settings-page-KZStwhX7.js +3 -0
- package/dist/gateway/static/root/assets/button-aIC072nz.js +1 -0
- package/dist/gateway/static/root/assets/capabilities-page-DeJuO2rf.js +2 -0
- package/dist/gateway/static/root/assets/capabilities-settings-panel-DPxL_3Km.js +8 -0
- package/dist/gateway/static/root/assets/capability-header-actions-yfPUz5Wt.js +1 -0
- package/dist/gateway/static/root/assets/channels-Cp4F9zPz.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-vb3kBSeI.js → chat-terminal-dock-Dlzn80cK.js} +2 -2
- package/dist/gateway/static/root/assets/computer-settings-page-BXhmUWbA.js +1 -0
- package/dist/gateway/static/root/assets/connector-service-page-B1oJCj74.js +1 -0
- package/dist/gateway/static/root/assets/connectors-page-Da_M7h3m.js +1 -0
- package/dist/gateway/static/root/assets/date-picker-DGjpqOKx.js +1 -0
- package/dist/gateway/static/root/assets/dependency-picker-BfWUD3LG.js +1 -0
- package/dist/gateway/static/root/assets/{desktop-pet-Bb-s29ag.js → desktop-pet-CPEi55Vt.js} +1 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-CmQ_H-nM.js +1 -0
- package/dist/gateway/static/root/assets/device-pairing-wizard-BeTjXc3C.js +1 -0
- package/dist/gateway/static/root/assets/{directory-picker-path-field-CkGfC105.js → directory-picker-path-field-CwT1LcLR.js} +1 -1
- package/dist/gateway/static/root/assets/dist-C3DSFZCi.js +1 -0
- package/dist/gateway/static/root/assets/{extension-debug-page-Cm0F3rcI.js → extension-debug-page-DX-hX_d0.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-B72a-tnZ.js → extension-page-Cji87mN9.js} +1 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BulzpwBD.js +1 -0
- package/dist/gateway/static/root/assets/file-archive-DanfQJNe.js +1 -0
- package/dist/gateway/static/root/assets/file-braces-BoAMI_k9.js +1 -0
- package/dist/gateway/static/root/assets/file-image-CDUPkZvG.js +1 -0
- package/dist/gateway/static/root/assets/gateway-settings-CIdEroWr.js +1 -0
- package/dist/gateway/static/root/assets/globe-DSSGFWFn.js +1 -0
- package/dist/gateway/static/root/assets/{highlighted-body-KQOG7T2V-BWjkqT5j.js → highlighted-body-KQOG7T2V-BgTqMa_d.js} +1 -1
- package/dist/gateway/static/root/assets/home-page-BSbYrVda.js +2 -0
- package/dist/gateway/static/root/assets/image-generation-api-BfPYnMoc.js +1 -0
- package/dist/gateway/static/root/assets/imports-page-DYSOfHfw.js +1 -0
- package/dist/gateway/static/root/assets/index-D2hEKnTM.js +267 -0
- package/dist/gateway/static/root/assets/index-SmKNPEmJ.css +1 -0
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-Cf29ltoI.js → keyboard-shortcuts-settings-BwsGM6Yd.js} +1 -1
- package/dist/gateway/static/root/assets/loader-circle-CifKLtgG.js +1 -0
- package/dist/gateway/static/root/assets/local-app-workbench-page-K6UR6cAx.js +1 -0
- package/dist/gateway/static/root/assets/local-apps-page-gkdwtjDE.js +1 -0
- package/dist/gateway/static/root/assets/logs-page-BAQNYk0e.js +2 -0
- package/dist/gateway/static/root/assets/management-settings-CMVRLGox.js +1 -0
- package/dist/gateway/static/root/assets/{markdown-view-B35a4o1v.js → markdown-view-Ljt0bhfF.js} +6 -6
- package/dist/gateway/static/root/assets/{media-plugins-Bl1Xga_v.js → media-plugins-DQJXvbr_.js} +1 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-Cx0bXBqu.js +1 -0
- package/dist/gateway/static/root/assets/note-detail-panel-1GCqp26U.js +5 -0
- package/dist/gateway/static/root/assets/note-image-lightbox-B7RA-WsY.js +1 -0
- package/dist/gateway/static/root/assets/notes-page-DnjlEdzM.js +8 -0
- package/dist/gateway/static/root/assets/page-context-capture-button-BAwI_3uh.js +1 -0
- package/dist/gateway/static/root/assets/personal-page-XoLrcR0U.js +1 -0
- package/dist/gateway/static/root/assets/personal-settings-panel-DzubCRqj.js +1 -0
- package/dist/gateway/static/root/assets/plugin-details-dialog-BjzIp3T5.js +1 -0
- package/dist/gateway/static/root/assets/popover-select-DGKUpVsz.js +1 -0
- package/dist/gateway/static/root/assets/{preview-open-alternatives-6XU-2lVI.js → preview-open-alternatives-2YjwlRHu.js} +1 -1
- package/dist/gateway/static/root/assets/product-open-page-Bfqez8Je.js +1 -0
- package/dist/gateway/static/root/assets/product-preview-content-D7wLwrqj.js +1 -0
- package/dist/gateway/static/root/assets/project-detail-page-1ueRCmXg.js +1 -0
- package/dist/gateway/static/root/assets/projects-page-CDQycMPo.js +1 -0
- package/dist/gateway/static/root/assets/remote-access-hub-YvVmZA4K.js +1 -0
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-DSsANtha.js +1 -0
- package/dist/gateway/static/root/assets/schema-form-vbhv4JE6.js +1 -0
- package/dist/gateway/static/root/assets/sessions-page-B3rPljgr.js +1 -0
- package/dist/gateway/static/root/assets/settings-advanced-gate-Ch20Ptzp.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-Cl0eF4hl.js → settings-form-section-4nn0sb6v.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-1jcGeVtB.js → settings-page-_HB9FC08.js} +1 -1
- package/dist/gateway/static/root/assets/settings-shell-dialog-layer-BU3UuiJr.js +1 -0
- package/dist/gateway/static/root/assets/setup-status-panel-L1HHrvzi.js +1 -0
- package/dist/gateway/static/root/assets/share-preview-page-C4lC0W3d.js +2 -0
- package/dist/gateway/static/root/assets/shares-settings-DtHZ9z5K.js +1 -0
- package/dist/gateway/static/root/assets/skeleton-BI5TyibZ.js +1 -0
- package/dist/gateway/static/root/assets/{skill-api-BxCyuPhf.js → skill-api-CyO89DKl.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-Drg356Pb.js +1 -0
- package/dist/gateway/static/root/assets/skills-page-XhCLHKlK.js +2 -0
- package/dist/gateway/static/root/assets/style-DTLpCnuA.js +7 -0
- package/dist/gateway/static/root/assets/{system-settings-panel-C9ejxax1.js → system-settings-panel-bSogz4S-.js} +1 -1
- package/dist/gateway/static/root/assets/task-detail-page-CSv2x4q-.js +2 -0
- package/dist/gateway/static/root/assets/{task-expandable-content-BMCvE36l.js → task-expandable-content-4s_FTl-9.js} +1 -1
- package/dist/gateway/static/root/assets/tracing-settings-page-CZ5XLQmX.js +1 -0
- package/dist/gateway/static/root/assets/tunnel-api-DOUyF9Ew.js +1 -0
- package/dist/gateway/static/root/assets/usage-page-Bv3fdfw1.js +1 -0
- package/dist/gateway/static/root/assets/use-autosave-D0MhLMD2.js +1 -0
- package/dist/gateway/static/root/assets/user-model-page-BD7WvhI0.js +2 -0
- package/dist/gateway/static/root/assets/{voice-api-key-field-Bk947X8N.js → voice-api-key-field-Ds_ADBQH.js} +1 -1
- package/dist/gateway/static/root/assets/work-discovery-overlay-CDJp2_l2.js +1 -0
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-xQUvtVUU.js → workflow-run-setup-panel-CR4fRhZZ.js} +2 -2
- package/dist/gateway/static/root/assets/workflows-page-BeJw5liC.js +6 -0
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-Di-oEpCt.js +1 -0
- package/dist/gateway/static/root/index.html +13 -7
- package/dist/package.js +1 -1
- package/dist/src/agent/background-review/prompts.d.ts +8 -0
- package/dist/src/agent/background-review/prompts.js +9 -2
- package/dist/src/agent/background-review/run-background-review.js +73 -11
- package/dist/src/agent/inbound/attachment-pipeline.d.ts +2 -0
- package/dist/src/agent/inbound/attachment-pipeline.js +10 -5
- package/dist/src/agent/tools/factory.js +15 -1
- package/dist/src/agent/tools/session-recall-tool.d.ts +3 -0
- package/dist/src/agent/tools/session-recall-tool.js +3 -0
- package/dist/src/agent/tools/session-search-tool.d.ts +3 -0
- package/dist/src/agent/tools/session-search-tool.js +20 -4
- package/dist/src/knowledge-memory/repository.d.ts +3 -1
- package/dist/src/knowledge-memory/repository.js +10 -3
- package/dist/src/memory-learning/forget-capture.d.ts +14 -0
- package/dist/src/memory-learning/forget-capture.js +100 -0
- package/dist/src/memory-learning/forgotten-history.d.ts +5 -0
- package/dist/src/memory-learning/forgotten-history.js +33 -0
- package/dist/src/memory-learning/work-capture.js +2 -1
- package/dist/src/providers/domestic-presets.d.ts +12 -5
- package/dist/src/providers/domestic-presets.js +27 -28
- package/dist/src/providers/presentation.js +7 -19
- package/dist/src/providers/setup/engine.js +2 -2
- package/dist/src/session/store.d.ts +1 -0
- package/dist/src/storage/sqlite/fts.d.ts +4 -0
- package/dist/src/storage/sqlite/fts.js +13 -4
- package/dist/src/storage/sqlite/session-repository.js +6 -3
- package/dist/src/storage/sqlite/transcript-repository.d.ts +1 -0
- package/dist/src/storage/sqlite/transcript-repository.js +14 -12
- package/dist/src/user-model/capture/semantic.d.ts +18 -1
- package/dist/src/user-model/capture/semantic.js +26 -1
- package/package.json +10 -10
- package/dist/gateway/static/root/assets/agent-defaults-settings-panel-CtE1h2xU.js +0 -1
- package/dist/gateway/static/root/assets/agents-DAgFeHEb.js +0 -77
- package/dist/gateway/static/root/assets/app-management-settings-panel-B1qR8ElB.js +0 -1
- package/dist/gateway/static/root/assets/appearance-settings-GA819R2q.js +0 -1
- package/dist/gateway/static/root/assets/apps-page-DZptDZ7h.js +0 -1
- package/dist/gateway/static/root/assets/automations-workspace-qfEjk_ws.js +0 -6
- package/dist/gateway/static/root/assets/browser-automation-inputs-Bs-AkQ1q.js +0 -1
- package/dist/gateway/static/root/assets/browser-automations-page-D0Vbe1Q_.js +0 -3
- package/dist/gateway/static/root/assets/browser-settings-page-BXCNNpQd.js +0 -3
- package/dist/gateway/static/root/assets/capabilities-page-DMtxaYgt.js +0 -2
- package/dist/gateway/static/root/assets/capabilities-settings-panel-BlWrMG6Z.js +0 -8
- package/dist/gateway/static/root/assets/capability-header-actions-BMffrHhT.js +0 -1
- package/dist/gateway/static/root/assets/channels-C96r2Rqq.js +0 -1
- package/dist/gateway/static/root/assets/computer-settings-page-75SDQxQW.js +0 -1
- package/dist/gateway/static/root/assets/connector-service-page-DmJ9dIql.js +0 -1
- package/dist/gateway/static/root/assets/connectors-page-Bua_nhSH.js +0 -1
- package/dist/gateway/static/root/assets/date-picker-BEDH1AbM.js +0 -1
- package/dist/gateway/static/root/assets/dependency-picker-LwWL5fo8.js +0 -1
- package/dist/gateway/static/root/assets/desktop-pet-settings-Btt-DzyT.js +0 -1
- package/dist/gateway/static/root/assets/device-pairing-wizard-_UWo9-4N.js +0 -1
- package/dist/gateway/static/root/assets/ellipsis-0k4rZLoy.js +0 -1
- package/dist/gateway/static/root/assets/extension-settings-page-BEDAm_Ib.js +0 -1
- package/dist/gateway/static/root/assets/eye-CABVeTq0.js +0 -1
- package/dist/gateway/static/root/assets/files-Bw4SBGdM.js +0 -1
- package/dist/gateway/static/root/assets/folder-open-CyzJ19I9.js +0 -1
- package/dist/gateway/static/root/assets/gateway-settings-BapgXAhB.js +0 -1
- package/dist/gateway/static/root/assets/home-page-DNGjF6h4.js +0 -2
- package/dist/gateway/static/root/assets/image-generation-api-Bi1-Hvtr.js +0 -1
- package/dist/gateway/static/root/assets/imports-page-b4VDs6Bd.js +0 -1
- package/dist/gateway/static/root/assets/index-Cgd4fGVP.js +0 -267
- package/dist/gateway/static/root/assets/index-gYRNcY2Q.css +0 -1
- package/dist/gateway/static/root/assets/local-app-workbench-page-dgUxHhW8.js +0 -1
- package/dist/gateway/static/root/assets/local-apps-page-D3k9GjgF.js +0 -1
- package/dist/gateway/static/root/assets/logs-page-BUlU7t8l.js +0 -2
- package/dist/gateway/static/root/assets/management-settings-2L7XFZXc.js +0 -1
- package/dist/gateway/static/root/assets/mermaid-MCJ5UELQ-Bi62iXra.js +0 -1
- package/dist/gateway/static/root/assets/note-detail-panel-ogBu93h0.js +0 -5
- package/dist/gateway/static/root/assets/note-image-lightbox-Dxvo_WsE.js +0 -1
- package/dist/gateway/static/root/assets/notes-page-CNdoxzIZ.js +0 -8
- package/dist/gateway/static/root/assets/page-context-capture-button-Bq4Xpop5.js +0 -1
- package/dist/gateway/static/root/assets/personal-page-7P2leCsB.js +0 -1
- package/dist/gateway/static/root/assets/personal-settings-panel-D6n6TObP.js +0 -1
- package/dist/gateway/static/root/assets/plugin-details-dialog-JTxDbMI4.js +0 -1
- package/dist/gateway/static/root/assets/product-open-page-BpB0klIl.js +0 -1
- package/dist/gateway/static/root/assets/product-preview-content-DxQaoQew.js +0 -1
- package/dist/gateway/static/root/assets/project-detail-page-LilHE2OV.js +0 -1
- package/dist/gateway/static/root/assets/projects-page-D4Jxhuhq.js +0 -1
- package/dist/gateway/static/root/assets/remote-access-hub-Cy71CCQq.js +0 -1
- package/dist/gateway/static/root/assets/runtime-tools-settings-panel-CrbjrokA.js +0 -1
- package/dist/gateway/static/root/assets/schema-form-DITi2cne.js +0 -1
- package/dist/gateway/static/root/assets/sessions-page-D1THmRXE.js +0 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-CjRLXfoo.js +0 -1
- package/dist/gateway/static/root/assets/setup-status-panel-CFhDHkyK.js +0 -1
- package/dist/gateway/static/root/assets/share-preview-page-By4IKKgg.js +0 -2
- package/dist/gateway/static/root/assets/shares-settings-q2sa1VvF.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-CIHSQxr1.js +0 -1
- package/dist/gateway/static/root/assets/skills-page-BQaej_2C.js +0 -2
- package/dist/gateway/static/root/assets/style-Dt_oHNvB.js +0 -7
- package/dist/gateway/static/root/assets/task-detail-page-SipLlGGk.js +0 -2
- package/dist/gateway/static/root/assets/tracing-settings-page-bn9vnLrf.js +0 -1
- package/dist/gateway/static/root/assets/tunnel-api-BeTAD8BN.js +0 -1
- package/dist/gateway/static/root/assets/usage-page-BPuc6leN.js +0 -1
- package/dist/gateway/static/root/assets/use-autosave-DwcmmxWR.js +0 -1
- package/dist/gateway/static/root/assets/user-model-page-YWSqv_kR.js +0 -2
- package/dist/gateway/static/root/assets/work-discovery-overlay-mjj7w_wU.js +0 -1
- package/dist/gateway/static/root/assets/workflows-page-DbKRAEWP.js +0 -6
- package/dist/gateway/static/root/assets/xopc-cloud-account-card-C4jQM6Uo.js +0 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createLogger } from "../utils/logger/index.js";
|
|
2
|
+
import { init_logger } from "../utils/logger.js";
|
|
3
|
+
import { init_transaction, runSqliteWriteTransaction } from "../storage/sqlite/transaction.js";
|
|
4
|
+
import { createCollaborationRule, init_collaboration_rule_repository, listCollaborationRules } from "../storage/sqlite/collaboration-rule-repository.js";
|
|
5
|
+
import { canUseKnowledge } from "../knowledge-memory/usage-policy.js";
|
|
6
|
+
import { deleteKnowledgeItem, getKnowledgeItem, writeKnowledgeItem } from "../knowledge-memory/repository.js";
|
|
7
|
+
import "../knowledge-memory/index.js";
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
//#region src/memory-learning/forget-capture.ts
|
|
10
|
+
init_logger();
|
|
11
|
+
init_transaction();
|
|
12
|
+
init_collaboration_rule_repository();
|
|
13
|
+
const log = createLogger("MemoryLearning:Forget");
|
|
14
|
+
/** Only grounded owner requests can forget derived knowledge visible in this scope. */
|
|
15
|
+
function applyKnowledgeDeletions(input) {
|
|
16
|
+
return runSqliteWriteTransaction((db) => {
|
|
17
|
+
const outputs = [];
|
|
18
|
+
for (const operation of input.interpretation.knowledgeDeletions ?? []) {
|
|
19
|
+
if (!operation.evidenceRefs.length || operation.evidenceRefs.some((ref) => !input.evidence.some((entry) => entry.ref === ref && entry.role === "user"))) continue;
|
|
20
|
+
if (!operation.evidence?.length || operation.evidence.some((claim) => !input.evidence.some((entry) => entry.ref === claim.ref && entry.role === "user" && entry.text.normalize("NFKC").toLowerCase().includes(claim.quote.normalize("NFKC").toLowerCase())))) continue;
|
|
21
|
+
let targets = operation.targetKnowledgeIds.flatMap((id) => {
|
|
22
|
+
const item = input.allowedTargetIds.includes(id) ? getKnowledgeItem(id) : void 0;
|
|
23
|
+
return item && item.recordClass === "memory" && canUseKnowledge(item, input.context) ? [item] : [];
|
|
24
|
+
});
|
|
25
|
+
const requestedRetention = operation.retained ?? [];
|
|
26
|
+
const invalidTargets = new Set(requestedRetention.filter((part) => {
|
|
27
|
+
const item = targets.find((target) => target.id === part.targetKnowledgeId);
|
|
28
|
+
return !item || !part.spans.length || part.spans.some((span) => !span.trim() || !item.content.includes(span));
|
|
29
|
+
}).map((part) => part.targetKnowledgeId));
|
|
30
|
+
if (invalidTargets.size) log.warn({
|
|
31
|
+
phase: "forget_retention",
|
|
32
|
+
count: invalidTargets.size,
|
|
33
|
+
conversationId: input.context.conversationId
|
|
34
|
+
}, "Ungrounded retained spans rejected; affected knowledge was preserved");
|
|
35
|
+
targets = targets.filter((item) => !invalidTargets.has(item.id));
|
|
36
|
+
const retained = requestedRetention.filter((part) => targets.some((item) => item.id === part.targetKnowledgeId));
|
|
37
|
+
for (const part of retained) {
|
|
38
|
+
const item = targets.find((target) => target.id === part.targetKnowledgeId);
|
|
39
|
+
const content = [...new Set(part.spans)].join(";");
|
|
40
|
+
const links = db.prepare(`SELECT evidence_id, content_hash, consent_receipt_id FROM knowledge_evidence_links
|
|
41
|
+
WHERE knowledge_id = ?`).all(item.id);
|
|
42
|
+
const saved = writeKnowledgeItem({
|
|
43
|
+
...item,
|
|
44
|
+
content,
|
|
45
|
+
canonicalKey: `${item.canonicalKey}:retained:${createHash("sha256").update(content).digest("hex").slice(0, 16)}`,
|
|
46
|
+
evidence: links.map((link) => ({
|
|
47
|
+
id: link.evidence_id,
|
|
48
|
+
contentHash: link.content_hash ?? void 0,
|
|
49
|
+
consentReceiptId: link.consent_receipt_id ?? void 0
|
|
50
|
+
})),
|
|
51
|
+
source: {
|
|
52
|
+
...item.source,
|
|
53
|
+
evidenceQuotes: void 0,
|
|
54
|
+
retainedFromKnowledgeId: item.id
|
|
55
|
+
},
|
|
56
|
+
replaceExisting: false
|
|
57
|
+
});
|
|
58
|
+
if (!saved.item) throw new Error("Unable to retain unforgotten knowledge; deletion was rolled back.");
|
|
59
|
+
outputs.push({
|
|
60
|
+
candidateKey: saved.item.canonicalKey,
|
|
61
|
+
objectType: "knowledge",
|
|
62
|
+
objectId: saved.item.id,
|
|
63
|
+
outcome: "created"
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const forgottenEntries = targets.flatMap((item) => db.prepare(`SELECT DISTINCT e.conversation_id, e.message_id
|
|
67
|
+
FROM context_evidence e WHERE e.conversation_id IS NOT NULL AND e.message_id IS NOT NULL
|
|
68
|
+
AND (e.evidence_id IN (SELECT evidence_id FROM knowledge_evidence_links WHERE knowledge_id=?)
|
|
69
|
+
OR e.message_id IN (SELECT value FROM knowledge_revisions r, json_each(r.source_json, '$.evidenceRefs')
|
|
70
|
+
WHERE r.knowledge_id=?))`).all(item.id, item.id).flatMap((entry) => [`${entry.conversation_id}:${entry.message_id}`, `${entry.conversation_id}:*`]));
|
|
71
|
+
for (const item of targets) {
|
|
72
|
+
deleteKnowledgeItem(item.id, Date.now(), { includeRelated: false });
|
|
73
|
+
outputs.push({
|
|
74
|
+
candidateKey: item.id,
|
|
75
|
+
objectType: "knowledge",
|
|
76
|
+
objectId: item.id,
|
|
77
|
+
outcome: "rejected"
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
for (const scope of new Map(targets.map((item) => [JSON.stringify(item.scope), item.scope])).values()) {
|
|
81
|
+
if (scope.type === "agent") continue;
|
|
82
|
+
if (!listCollaborationRules().some((rule) => rule.category === "boundary" && rule.status === "active" && JSON.stringify(rule.scope) === JSON.stringify(scope) && rule.statement === operation.boundary && forgottenEntries.every((entry) => Array.isArray(rule.conditions.forgottenHistoryEntries) && rule.conditions.forgottenHistoryEntries.includes(entry)))) createCollaborationRule({
|
|
83
|
+
category: "boundary",
|
|
84
|
+
priority: 0,
|
|
85
|
+
scope,
|
|
86
|
+
conditions: {
|
|
87
|
+
enforcementLevel: "prompt",
|
|
88
|
+
forgottenHistoryEntries: [...new Set(forgottenEntries)],
|
|
89
|
+
reread: operation.reread
|
|
90
|
+
},
|
|
91
|
+
statement: operation.boundary,
|
|
92
|
+
status: "active"
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return outputs;
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
//#endregion
|
|
100
|
+
export { applyKnowledgeDeletions };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CaptureScopeContext } from '../user-model/capture/executor.js';
|
|
2
|
+
/** A later source-specific read request does not authorize saving forgotten facts again. */
|
|
3
|
+
export declare function explicitlyReadsOriginalHistory(text: string): boolean;
|
|
4
|
+
export declare function forgottenHistoryEntries(context: CaptureScopeContext, userText?: string): Set<string>;
|
|
5
|
+
export declare const FORGOTTEN_HISTORY_EXCERPT = "[This entry supported information the user asked to forget. Automatic recall is withheld. A later explicit request to re-read original records is required; do not infer the hidden values.]";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { isXopcDatabaseOpen } from "../storage/sqlite/connection.js";
|
|
2
|
+
import { init_collaboration_rule_repository, listCollaborationRules } from "../storage/sqlite/collaboration-rule-repository.js";
|
|
3
|
+
import { init_sqlite } from "../storage/sqlite/index.js";
|
|
4
|
+
//#region src/memory-learning/forgotten-history.ts
|
|
5
|
+
init_sqlite();
|
|
6
|
+
init_collaboration_rule_repository();
|
|
7
|
+
/** A later source-specific read request does not authorize saving forgotten facts again. */
|
|
8
|
+
function explicitlyReadsOriginalHistory(text) {
|
|
9
|
+
if (/(?:引文|引用|改写|措辞|不是要|quoted|rephrase)/iu.test(text)) return false;
|
|
10
|
+
if (/(?:不要|别|不必|禁止)\s*(?:再|去)?(?:恢复|查阅|查出|读取|找回|查)|(?:do not|don't)\s+(?:read|look|recover|retrieve|restore)/iu.test(text)) return false;
|
|
11
|
+
return /(?:原始|旧|先前|过去).{0,8}(?:记录|对话|原文)|(?:original|old|previous|past).{0,20}(?:record|conversation|transcript|history)/iu.test(text) && /(?:^|\n)\s*(?:(?:请|麻烦|本次|这次|现在|please|this time)[,,\s]*){0,3}[^。\n!?]{0,150}(?:恢复|查阅|查出|读取|找回|read|look up|retrieve|recover|restore)/iu.test(text);
|
|
12
|
+
}
|
|
13
|
+
function forgottenHistoryEntries(context, userText = "") {
|
|
14
|
+
if (!isXopcDatabaseOpen()) return /* @__PURE__ */ new Set();
|
|
15
|
+
const entries = /* @__PURE__ */ new Set();
|
|
16
|
+
for (const rule of listCollaborationRules()) {
|
|
17
|
+
if (rule.status !== "active" || rule.category !== "boundary") continue;
|
|
18
|
+
if (!(rule.scope.type === "global" || rule.scope.id === {
|
|
19
|
+
agent: context.agentId,
|
|
20
|
+
workspace: context.workspaceId,
|
|
21
|
+
project: context.projectId,
|
|
22
|
+
session: context.conversationId
|
|
23
|
+
}[rule.scope.type]) || !Array.isArray(rule.conditions.forgottenHistoryEntries)) continue;
|
|
24
|
+
const binding = rule.conditions.reread;
|
|
25
|
+
const property = binding?.property === "date_time" ? /日期|时间|哪天|哪日|几点|日程|\b(?:date|time|when|schedule)\b/iu : binding?.property === "price" ? /票价|报价|价格|总价|金额|费用|花费|价钱|\b(?:price|cost|amount)\b/iu : void 0;
|
|
26
|
+
if (typeof binding?.subject === "string" && binding.subject.length > 0 && property && userText.split(/[。;;,,!?!?\n]/u).some((clause) => explicitlyReadsOriginalHistory(clause) && clause.normalize("NFKC").toLowerCase().includes(binding.subject.normalize("NFKC").toLowerCase()) && property.test(clause))) continue;
|
|
27
|
+
for (const entry of rule.conditions.forgottenHistoryEntries) if (typeof entry === "string") entries.add(entry);
|
|
28
|
+
}
|
|
29
|
+
return entries;
|
|
30
|
+
}
|
|
31
|
+
const FORGOTTEN_HISTORY_EXCERPT = "[This entry supported information the user asked to forget. Automatic recall is withheld. A later explicit request to re-read original records is required; do not infer the hidden values.]";
|
|
32
|
+
//#endregion
|
|
33
|
+
export { FORGOTTEN_HISTORY_EXCERPT, explicitlyReadsOriginalHistory, forgottenHistoryEntries };
|
|
@@ -112,7 +112,8 @@ function applyWorkCandidates(input) {
|
|
|
112
112
|
replaceExisting: true,
|
|
113
113
|
source: {
|
|
114
114
|
extractor: "work-synthesis",
|
|
115
|
-
evidenceRefs: candidate.evidence.map((claim) => claim.ref),
|
|
115
|
+
evidenceRefs: [...new Set(candidate.evidence.map((claim) => claim.ref))],
|
|
116
|
+
evidenceQuotes: candidate.evidence,
|
|
116
117
|
...input.source ? {
|
|
117
118
|
sourceInstanceId: input.source.instanceId,
|
|
118
119
|
sourceItemId: input.source.itemId,
|
|
@@ -390,8 +390,15 @@ export declare const DOMESTIC_PROVIDER_PRESETS: readonly [{
|
|
|
390
390
|
readonly baseUrl: "https://api.xiaomimimo.com/v1";
|
|
391
391
|
}];
|
|
392
392
|
readonly defaultBaseUrlPreset: "api";
|
|
393
|
-
readonly defaultModel: "mimo-v2.
|
|
394
|
-
readonly models: DomesticProviderModelPreset[]
|
|
393
|
+
readonly defaultModel: "mimo-v2.6-pro";
|
|
394
|
+
readonly models: [...DomesticProviderModelPreset[], {
|
|
395
|
+
readonly id: "mimo-v2.6-pro-ultraspeed";
|
|
396
|
+
readonly name: "MiMo V2.6 Pro UltraSpeed";
|
|
397
|
+
readonly contextWindow: 1048576;
|
|
398
|
+
readonly maxTokens: 131072;
|
|
399
|
+
readonly reasoning: true;
|
|
400
|
+
readonly input: ["text", "image"];
|
|
401
|
+
}];
|
|
395
402
|
readonly aliases: ["xiaomi", "mimo", "xiaomimimo"];
|
|
396
403
|
readonly quirks: ["Some MiMo plans document api-key style auth; keep auth header behavior configurable if needed."];
|
|
397
404
|
}, {
|
|
@@ -409,7 +416,7 @@ export declare const DOMESTIC_PROVIDER_PRESETS: readonly [{
|
|
|
409
416
|
readonly baseUrl: "https://token-plan-cn.xiaomimimo.com/v1";
|
|
410
417
|
}];
|
|
411
418
|
readonly defaultBaseUrlPreset: "cn";
|
|
412
|
-
readonly defaultModel: "mimo-v2.
|
|
419
|
+
readonly defaultModel: "mimo-v2.6-pro";
|
|
413
420
|
readonly models: DomesticProviderModelPreset[];
|
|
414
421
|
readonly aliases: ["xiaomi token plan cn", "mimo token plan cn"];
|
|
415
422
|
}, {
|
|
@@ -427,7 +434,7 @@ export declare const DOMESTIC_PROVIDER_PRESETS: readonly [{
|
|
|
427
434
|
readonly baseUrl: "https://token-plan-ams.xiaomimimo.com/v1";
|
|
428
435
|
}];
|
|
429
436
|
readonly defaultBaseUrlPreset: "ams";
|
|
430
|
-
readonly defaultModel: "mimo-v2.
|
|
437
|
+
readonly defaultModel: "mimo-v2.6-pro";
|
|
431
438
|
readonly models: DomesticProviderModelPreset[];
|
|
432
439
|
readonly aliases: ["xiaomi token plan ams", "mimo token plan ams"];
|
|
433
440
|
}, {
|
|
@@ -445,7 +452,7 @@ export declare const DOMESTIC_PROVIDER_PRESETS: readonly [{
|
|
|
445
452
|
readonly baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1";
|
|
446
453
|
}];
|
|
447
454
|
readonly defaultBaseUrlPreset: "sgp";
|
|
448
|
-
readonly defaultModel: "mimo-v2.
|
|
455
|
+
readonly defaultModel: "mimo-v2.6-pro";
|
|
449
456
|
readonly models: DomesticProviderModelPreset[];
|
|
450
457
|
readonly aliases: ["xiaomi token plan sgp", "mimo token plan sgp"];
|
|
451
458
|
}, {
|
|
@@ -42,29 +42,21 @@ const STEPFUN_MODELS = [
|
|
|
42
42
|
input: ["text"]
|
|
43
43
|
}
|
|
44
44
|
];
|
|
45
|
-
const MIMO_MODELS = [
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
id: "mimo-v2.5",
|
|
62
|
-
name: "MiMo V2.5",
|
|
63
|
-
contextWindow: 1e6,
|
|
64
|
-
reasoning: true,
|
|
65
|
-
input: ["text", "image"]
|
|
66
|
-
}
|
|
67
|
-
];
|
|
45
|
+
const MIMO_MODELS = [{
|
|
46
|
+
id: "mimo-v2.6-pro",
|
|
47
|
+
name: "MiMo V2.6 Pro",
|
|
48
|
+
contextWindow: 1048576,
|
|
49
|
+
maxTokens: 131072,
|
|
50
|
+
reasoning: true,
|
|
51
|
+
input: ["text", "image"]
|
|
52
|
+
}, {
|
|
53
|
+
id: "mimo-v2.6-flash",
|
|
54
|
+
name: "MiMo V2.6 Flash",
|
|
55
|
+
contextWindow: 1048576,
|
|
56
|
+
maxTokens: 131072,
|
|
57
|
+
reasoning: true,
|
|
58
|
+
input: ["text", "image"]
|
|
59
|
+
}];
|
|
68
60
|
const MINIMAX_MODELS = [
|
|
69
61
|
{
|
|
70
62
|
id: "MiniMax-M3",
|
|
@@ -527,8 +519,15 @@ const DOMESTIC_PROVIDER_PRESETS = [
|
|
|
527
519
|
baseUrl: "https://api.xiaomimimo.com/v1"
|
|
528
520
|
}],
|
|
529
521
|
defaultBaseUrlPreset: "api",
|
|
530
|
-
defaultModel: "mimo-v2.
|
|
531
|
-
models: MIMO_MODELS,
|
|
522
|
+
defaultModel: "mimo-v2.6-pro",
|
|
523
|
+
models: [...MIMO_MODELS, {
|
|
524
|
+
id: "mimo-v2.6-pro-ultraspeed",
|
|
525
|
+
name: "MiMo V2.6 Pro UltraSpeed",
|
|
526
|
+
contextWindow: 1048576,
|
|
527
|
+
maxTokens: 131072,
|
|
528
|
+
reasoning: true,
|
|
529
|
+
input: ["text", "image"]
|
|
530
|
+
}],
|
|
532
531
|
aliases: [
|
|
533
532
|
"xiaomi",
|
|
534
533
|
"mimo",
|
|
@@ -551,7 +550,7 @@ const DOMESTIC_PROVIDER_PRESETS = [
|
|
|
551
550
|
baseUrl: "https://token-plan-cn.xiaomimimo.com/v1"
|
|
552
551
|
}],
|
|
553
552
|
defaultBaseUrlPreset: "cn",
|
|
554
|
-
defaultModel: "mimo-v2.
|
|
553
|
+
defaultModel: "mimo-v2.6-pro",
|
|
555
554
|
models: MIMO_MODELS,
|
|
556
555
|
aliases: ["xiaomi token plan cn", "mimo token plan cn"]
|
|
557
556
|
},
|
|
@@ -570,7 +569,7 @@ const DOMESTIC_PROVIDER_PRESETS = [
|
|
|
570
569
|
baseUrl: "https://token-plan-ams.xiaomimimo.com/v1"
|
|
571
570
|
}],
|
|
572
571
|
defaultBaseUrlPreset: "ams",
|
|
573
|
-
defaultModel: "mimo-v2.
|
|
572
|
+
defaultModel: "mimo-v2.6-pro",
|
|
574
573
|
models: MIMO_MODELS,
|
|
575
574
|
aliases: ["xiaomi token plan ams", "mimo token plan ams"]
|
|
576
575
|
},
|
|
@@ -589,7 +588,7 @@ const DOMESTIC_PROVIDER_PRESETS = [
|
|
|
589
588
|
baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1"
|
|
590
589
|
}],
|
|
591
590
|
defaultBaseUrlPreset: "sgp",
|
|
592
|
-
defaultModel: "mimo-v2.
|
|
591
|
+
defaultModel: "mimo-v2.6-pro",
|
|
593
592
|
models: MIMO_MODELS,
|
|
594
593
|
aliases: ["xiaomi token plan sgp", "mimo token plan sgp"]
|
|
595
594
|
},
|
|
@@ -54,7 +54,7 @@ const PROVIDER_HINTS = {
|
|
|
54
54
|
deepseek: "DeepSeek V4 models with strong price/performance.",
|
|
55
55
|
moonshotai: "Kimi models through Moonshot International.",
|
|
56
56
|
"moonshotai-cn": "Kimi models through Moonshot China.",
|
|
57
|
-
"kimi-coding": "Kimi dedicated coding endpoint with
|
|
57
|
+
"kimi-coding": "Kimi dedicated coding endpoint with OpenAI-compatible Chat Completions requests.",
|
|
58
58
|
stepfun: "StepFun OpenAI-compatible endpoint.",
|
|
59
59
|
"stepfun-cn": "StepFun China OpenAI-compatible endpoint.",
|
|
60
60
|
"stepfun-intl": "StepFun international OpenAI-compatible endpoint.",
|
|
@@ -184,25 +184,13 @@ const RECOMMENDED_MODEL_PATTERNS = {
|
|
|
184
184
|
/^step-3\.5-flash$/i
|
|
185
185
|
],
|
|
186
186
|
xiaomi: [
|
|
187
|
-
/^mimo-v2\.
|
|
188
|
-
/^mimo-v2\.
|
|
189
|
-
/^mimo-v2\.
|
|
190
|
-
],
|
|
191
|
-
"xiaomi-token-plan-cn": [
|
|
192
|
-
/^mimo-v2\.5-pro$/i,
|
|
193
|
-
/^mimo-v2\.5-pro-ultraspeed$/i,
|
|
194
|
-
/^mimo-v2\.5$/i
|
|
195
|
-
],
|
|
196
|
-
"xiaomi-token-plan-ams": [
|
|
197
|
-
/^mimo-v2\.5-pro$/i,
|
|
198
|
-
/^mimo-v2\.5-pro-ultraspeed$/i,
|
|
199
|
-
/^mimo-v2\.5$/i
|
|
200
|
-
],
|
|
201
|
-
"xiaomi-token-plan-sgp": [
|
|
202
|
-
/^mimo-v2\.5-pro$/i,
|
|
203
|
-
/^mimo-v2\.5-pro-ultraspeed$/i,
|
|
204
|
-
/^mimo-v2\.5$/i
|
|
187
|
+
/^mimo-v2\.6-pro$/i,
|
|
188
|
+
/^mimo-v2\.6-pro-ultraspeed$/i,
|
|
189
|
+
/^mimo-v2\.6-flash$/i
|
|
205
190
|
],
|
|
191
|
+
"xiaomi-token-plan-cn": [/^mimo-v2\.6-pro$/i, /^mimo-v2\.6-flash$/i],
|
|
192
|
+
"xiaomi-token-plan-ams": [/^mimo-v2\.6-pro$/i, /^mimo-v2\.6-flash$/i],
|
|
193
|
+
"xiaomi-token-plan-sgp": [/^mimo-v2\.6-pro$/i, /^mimo-v2\.6-flash$/i],
|
|
206
194
|
"ant-ling": [
|
|
207
195
|
/^Ling-2\.6-1T$/i,
|
|
208
196
|
/^Ling-2\.6-flash$/i,
|
|
@@ -20,8 +20,8 @@ const preferred = {
|
|
|
20
20
|
reasoning: ["advanced", "auto"]
|
|
21
21
|
},
|
|
22
22
|
"xiaomi-token-plan-cn": {
|
|
23
|
-
fast: ["mimo-v2.
|
|
24
|
-
reasoning: ["mimo-v2.
|
|
23
|
+
fast: ["mimo-v2.6-flash", "mimo-v2.6-pro"],
|
|
24
|
+
reasoning: ["mimo-v2.6-pro", "mimo-v2.6-flash"]
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
const uses = [
|
|
@@ -209,6 +209,7 @@ export declare class SessionStore {
|
|
|
209
209
|
limit?: number;
|
|
210
210
|
beforeSeq?: number;
|
|
211
211
|
orderBySeq?: boolean;
|
|
212
|
+
matchMode?: 'keyword' | 'phrase';
|
|
212
213
|
}): import("../storage/sqlite/transcript-repository.js").SessionTranscriptRecallMatch[];
|
|
213
214
|
exportSession(key: string, format: ExportFormat): Promise<string>;
|
|
214
215
|
importSessionExport(targetKey: string, jsonContent: string): Promise<{
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/** Quote a user query for FTS5 phrase/prefix-safe matching. */
|
|
2
2
|
export declare function escapeFts5Query(raw: string): string;
|
|
3
3
|
/** Build a syntax-safe, recall-oriented query for natural-language memory search. */
|
|
4
|
+
export declare function sessionSearchTerms(raw: string): string[];
|
|
4
5
|
export declare function buildFts5SearchQuery(raw: string): string;
|
|
6
|
+
/** unicode61 does not split Han words; use literal substrings for those terms. */
|
|
7
|
+
export declare function sessionHanSearchTerms(raw: string): string[];
|
|
8
|
+
export declare function escapeSqlLike(raw: string): string;
|
|
5
9
|
/** Normalize FTS5 BM25 ranks, where a more-negative rank is a better match. */
|
|
6
10
|
export declare function fts5RankToScore(rank: number, bestRank: number, worstRank: number): number;
|
|
@@ -7,10 +7,19 @@ function escapeFts5Query(raw) {
|
|
|
7
7
|
return `"${trimmed.replace(/"/g, "\"\"")}"`;
|
|
8
8
|
}
|
|
9
9
|
/** Build a syntax-safe, recall-oriented query for natural-language memory search. */
|
|
10
|
-
function
|
|
10
|
+
function sessionSearchTerms(raw) {
|
|
11
11
|
const terms = raw.normalize("NFKC").match(/[\p{L}\p{N}_]+/gu)?.map((term) => term.toLowerCase()).filter((term) => term.length > 1 && !FTS_SEARCH_STOP_WORDS.has(term));
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
return [...new Set(terms?.length ? terms : [raw.trim()])].slice(0, 12);
|
|
13
|
+
}
|
|
14
|
+
function buildFts5SearchQuery(raw) {
|
|
15
|
+
return sessionSearchTerms(raw).map(escapeFts5Query).join(" OR ");
|
|
16
|
+
}
|
|
17
|
+
/** unicode61 does not split Han words; use literal substrings for those terms. */
|
|
18
|
+
function sessionHanSearchTerms(raw) {
|
|
19
|
+
return sessionSearchTerms(raw).filter((term) => /\p{Script=Han}/u.test(term));
|
|
20
|
+
}
|
|
21
|
+
function escapeSqlLike(raw) {
|
|
22
|
+
return raw.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
14
23
|
}
|
|
15
24
|
/** Normalize FTS5 BM25 ranks, where a more-negative rank is a better match. */
|
|
16
25
|
function fts5RankToScore(rank, bestRank, worstRank) {
|
|
@@ -61,4 +70,4 @@ var init_fts = __esmMin((() => {
|
|
|
61
70
|
}));
|
|
62
71
|
//#endregion
|
|
63
72
|
init_fts();
|
|
64
|
-
export { buildFts5SearchQuery, escapeFts5Query, fts5RankToScore, init_fts };
|
|
73
|
+
export { buildFts5SearchQuery, escapeFts5Query, escapeSqlLike, fts5RankToScore, init_fts, sessionHanSearchTerms, sessionSearchTerms };
|
|
@@ -10,7 +10,7 @@ import { buildGlobalSessionStats, init_row_mappers, metadataToSessionInsert, ses
|
|
|
10
10
|
import { cancelConnectionObjective, init_connection_wait_repository } from "./connection-wait-repository.js";
|
|
11
11
|
import { init_changes, notifyUserContextChange } from "../../user-context/changes.js";
|
|
12
12
|
import { SESSION_PURPOSE_SQL, SESSION_SOURCE_SQL, init_session_identity_sql } from "./session-identity-sql.js";
|
|
13
|
-
import { buildFts5SearchQuery, init_fts } from "./fts.js";
|
|
13
|
+
import { buildFts5SearchQuery, escapeSqlLike, init_fts, sessionHanSearchTerms } from "./fts.js";
|
|
14
14
|
import { SESSION_COLUMNS, SESSION_FROM_JOIN, getSessionMetadata, init_session_read_repository, readSessionRow } from "./session-read-repository.js";
|
|
15
15
|
import { randomUUID } from "node:crypto";
|
|
16
16
|
//#region src/storage/sqlite/session-repository.ts
|
|
@@ -166,14 +166,17 @@ function listSessionMetadata(query = {}) {
|
|
|
166
166
|
if (query.search?.trim()) {
|
|
167
167
|
const rawSearch = query.search.trim();
|
|
168
168
|
const like = `%${rawSearch.toLowerCase()}%`;
|
|
169
|
+
const hanTerms = sessionHanSearchTerms(rawSearch);
|
|
169
170
|
conditions.push(`(s.conversation_id IN (
|
|
170
171
|
SELECT conversation_id FROM transcript_fts WHERE transcript_fts MATCH ?
|
|
171
|
-
) OR
|
|
172
|
+
) ${hanTerms.length ? `OR s.conversation_id IN (
|
|
173
|
+
SELECT conversation_id FROM transcript_fts WHERE ${hanTerms.map(() => "content LIKE ? ESCAPE '\\'").join(" OR ")}
|
|
174
|
+
)` : ""} OR LOWER(s.conversation_id) LIKE ?
|
|
172
175
|
OR LOWER(COALESCE(s.name, '')) LIKE ?
|
|
173
176
|
OR LOWER(s.source_channel) LIKE ?
|
|
174
177
|
OR LOWER(s.source_chat_id) LIKE ?
|
|
175
178
|
OR LOWER(s.tags_json) LIKE ?)`);
|
|
176
|
-
params.push(buildFts5SearchQuery(rawSearch), like, like, like, like, like);
|
|
179
|
+
params.push(buildFts5SearchQuery(rawSearch), ...hanTerms.map((term) => `%${escapeSqlLike(term)}%`), like, like, like, like, like);
|
|
177
180
|
}
|
|
178
181
|
const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
179
182
|
const sortColumn = sessionSortColumn(query.sortBy);
|
|
@@ -34,6 +34,7 @@ export declare function searchSessionTranscript(conversationId: string, query: s
|
|
|
34
34
|
limit?: number;
|
|
35
35
|
beforeSeq?: number;
|
|
36
36
|
orderBySeq?: boolean;
|
|
37
|
+
matchMode?: 'keyword' | 'phrase';
|
|
37
38
|
}): SessionTranscriptRecallMatch[];
|
|
38
39
|
export declare function loadTranscriptRowsForSession(conversationId: string): TranscriptStoredRow[];
|
|
39
40
|
export declare function loadTranscriptHistoryRowsForSession(conversationId: string): TranscriptStoredRow[];
|
|
@@ -3,7 +3,7 @@ import { getSqliteDatabase, init_transaction, runSqliteWriteTransaction } from "
|
|
|
3
3
|
import { readCurrentTranscriptId } from "./session-instance-repository.js";
|
|
4
4
|
import { buildSessionContextForLlm, init_session_context_for_llm, isRuntimeOnlyTranscriptMessage } from "../../session/session-context-for-llm.js";
|
|
5
5
|
import { classifyStoredRow, estimateTokensFromMessages, extractFtsContent, init_row_mappers, transcriptEntryRowToStoredRow } from "./row-mappers.js";
|
|
6
|
-
import { escapeFts5Query, init_fts } from "./fts.js";
|
|
6
|
+
import { buildFts5SearchQuery, escapeFts5Query, escapeSqlLike, init_fts, sessionHanSearchTerms } from "./fts.js";
|
|
7
7
|
import { getCurrentTranscriptId, init_session_repository } from "./session-repository.js";
|
|
8
8
|
import { createHash, randomUUID } from "node:crypto";
|
|
9
9
|
//#region src/storage/sqlite/transcript-repository.ts
|
|
@@ -167,25 +167,27 @@ function searchSessionTranscript(conversationId, query, options = {}) {
|
|
|
167
167
|
const limit = Math.min(20, Math.max(1, options.limit ?? 8));
|
|
168
168
|
const beforeSeq = options.beforeSeq ?? Number.MAX_SAFE_INTEGER;
|
|
169
169
|
const db = getSqliteDatabase();
|
|
170
|
+
const phrase = options.matchMode !== "keyword";
|
|
171
|
+
const hanTerms = phrase ? [] : sessionHanSearchTerms(normalized);
|
|
170
172
|
const ftsRows = db.prepare(`SELECT e.entry_id, e.seq, e.role, e.created_at, f.content
|
|
171
173
|
FROM transcript_fts f
|
|
172
174
|
JOIN transcript_entries e
|
|
173
175
|
ON e.transcript_id = f.transcript_id AND e.entry_id = f.entry_id
|
|
174
|
-
WHERE transcript_fts MATCH ?
|
|
176
|
+
WHERE (transcript_fts MATCH ?)
|
|
175
177
|
AND f.transcript_id = ?
|
|
176
178
|
AND e.entry_kind <> 'compaction'
|
|
177
179
|
AND e.seq < ?
|
|
178
180
|
ORDER BY ${options.orderBySeq ? "e.seq DESC" : "bm25(transcript_fts), e.seq DESC"}
|
|
179
|
-
LIMIT ?`).all(escapeFts5Query(normalized), transcriptId, beforeSeq, limit);
|
|
180
|
-
const
|
|
181
|
-
const literalRows = db.prepare(`SELECT entry_id, seq, role, created_at, payload_json AS content
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
181
|
+
LIMIT ?`).all(phrase ? escapeFts5Query(normalized) : buildFts5SearchQuery(normalized), transcriptId, beforeSeq, limit);
|
|
182
|
+
const literalTerms = [normalized, ...hanTerms];
|
|
183
|
+
const literalRows = phrase ? db.prepare(`SELECT entry_id, seq, role, created_at, payload_json AS content
|
|
184
|
+
FROM transcript_entries WHERE transcript_id = ? AND entry_kind <> 'compaction' AND seq < ?
|
|
185
|
+
AND payload_json LIKE ? ESCAPE '\\' ORDER BY seq DESC LIMIT ?`).all(transcriptId, beforeSeq, `%${escapeSqlLike(normalized)}%`, limit) : db.prepare(`SELECT e.entry_id, e.seq, e.role, e.created_at, f.content
|
|
186
|
+
FROM transcript_fts f JOIN transcript_entries e
|
|
187
|
+
ON e.transcript_id = f.transcript_id AND e.entry_id = f.entry_id
|
|
188
|
+
WHERE f.transcript_id = ? AND e.entry_kind <> 'compaction' AND e.seq < ?
|
|
189
|
+
AND (${literalTerms.map(() => "f.content LIKE ? ESCAPE '\\'").join(" OR ")})
|
|
190
|
+
ORDER BY e.seq DESC LIMIT ?`).all(transcriptId, beforeSeq, ...literalTerms.map((term) => `%${escapeSqlLike(term)}%`), limit);
|
|
189
191
|
const seen = /* @__PURE__ */ new Set();
|
|
190
192
|
const matches = [...ftsRows, ...literalRows].flatMap((row) => {
|
|
191
193
|
const result = row;
|
|
@@ -34,6 +34,23 @@ export interface ParsedCollaborationRuleCandidate {
|
|
|
34
34
|
}
|
|
35
35
|
export interface UserModelInterpretation {
|
|
36
36
|
knowledge?: WorkCandidate[];
|
|
37
|
+
knowledgeDeletions?: Array<{
|
|
38
|
+
targetKnowledgeIds: string[];
|
|
39
|
+
boundary: string;
|
|
40
|
+
reread?: {
|
|
41
|
+
subject: string;
|
|
42
|
+
property: 'date_time' | 'price';
|
|
43
|
+
};
|
|
44
|
+
evidenceRefs: string[];
|
|
45
|
+
evidence: Array<{
|
|
46
|
+
ref: string;
|
|
47
|
+
quote: string;
|
|
48
|
+
}>;
|
|
49
|
+
retained?: Array<{
|
|
50
|
+
targetKnowledgeId: string;
|
|
51
|
+
spans: string[];
|
|
52
|
+
}>;
|
|
53
|
+
}>;
|
|
37
54
|
intent: UserModelCaptureIntent;
|
|
38
55
|
assertions: ParsedAssertionOperation[];
|
|
39
56
|
goals?: ParsedGoalCandidate[];
|
|
@@ -48,4 +65,4 @@ export interface InterpretationParseFailure {
|
|
|
48
65
|
code: string;
|
|
49
66
|
}>;
|
|
50
67
|
}
|
|
51
|
-
export declare function parseUserModelInterpretation(raw: string, evidence: CaptureEvidence[], allowedTargetIds?: string[], onInvalid?: (failure: InterpretationParseFailure) => void): UserModelInterpretation | null;
|
|
68
|
+
export declare function parseUserModelInterpretation(raw: string, evidence: CaptureEvidence[], allowedTargetIds?: string[], onInvalid?: (failure: InterpretationParseFailure) => void, allowedKnowledgeIds?: string[]): UserModelInterpretation | null;
|
|
@@ -154,6 +154,18 @@ const CollaborationRuleSchema = z.object({
|
|
|
154
154
|
}).merge(GroundingSchema).strict();
|
|
155
155
|
const InterpretationSchema = z.object({
|
|
156
156
|
knowledge: z.array(WorkCandidateSchema).max(8).default([]),
|
|
157
|
+
knowledgeDeletions: z.array(z.object({
|
|
158
|
+
targetKnowledgeIds: z.array(z.string().min(1)).min(1).max(16),
|
|
159
|
+
boundary: z.string().min(4).max(600),
|
|
160
|
+
reread: z.object({
|
|
161
|
+
subject: z.string().min(1).max(160),
|
|
162
|
+
property: z.enum(["date_time", "price"])
|
|
163
|
+
}).strict().optional(),
|
|
164
|
+
retained: z.array(z.object({
|
|
165
|
+
targetKnowledgeId: z.string().min(1),
|
|
166
|
+
spans: z.array(z.string().min(1).max(600)).min(1).max(8)
|
|
167
|
+
}).strict()).max(8).default([])
|
|
168
|
+
}).merge(GroundingSchema).strict()).max(4).default([]),
|
|
157
169
|
intent: z.enum(USER_MODEL_CAPTURE_INTENTS),
|
|
158
170
|
assertions: z.array(AssertionOperationSchema).max(8),
|
|
159
171
|
goals: z.array(GoalSchema).max(4).default([]),
|
|
@@ -184,7 +196,7 @@ function groundedEvidenceRefs(item, evidenceByRef) {
|
|
|
184
196
|
return source?.role === "user" && comparable(source.text).includes(comparable(claim.quote));
|
|
185
197
|
}) ? [...new Set(item.evidence.map((claim) => claim.ref))] : void 0;
|
|
186
198
|
}
|
|
187
|
-
function parseUserModelInterpretation(raw, evidence, allowedTargetIds = [], onInvalid) {
|
|
199
|
+
function parseUserModelInterpretation(raw, evidence, allowedTargetIds = [], onInvalid, allowedKnowledgeIds = []) {
|
|
188
200
|
if (!raw.trim()) {
|
|
189
201
|
onInvalid?.({
|
|
190
202
|
reason: "empty_output",
|
|
@@ -296,6 +308,19 @@ function parseUserModelInterpretation(raw, evidence, allowedTargetIds = [], onIn
|
|
|
296
308
|
});
|
|
297
309
|
return {
|
|
298
310
|
knowledge: parsed.knowledge,
|
|
311
|
+
knowledgeDeletions: parsed.knowledgeDeletions.flatMap((item) => {
|
|
312
|
+
const evidenceRefs = groundedEvidenceRefs(item, evidenceByRef);
|
|
313
|
+
if (!evidenceRefs || (item.intent ?? parsed.intent) !== "forget") return [];
|
|
314
|
+
const targetKnowledgeIds = [...new Set(item.targetKnowledgeIds.filter((id) => allowedKnowledgeIds.includes(id)))];
|
|
315
|
+
return targetKnowledgeIds.length ? [{
|
|
316
|
+
targetKnowledgeIds,
|
|
317
|
+
boundary: item.boundary,
|
|
318
|
+
evidenceRefs,
|
|
319
|
+
evidence: item.evidence,
|
|
320
|
+
retained: item.retained.filter((retained) => targetKnowledgeIds.includes(retained.targetKnowledgeId)),
|
|
321
|
+
...item.reread && item.evidence.some((claim) => claim.quote.includes(item.reread.subject)) ? { reread: item.reread } : {}
|
|
322
|
+
}] : [];
|
|
323
|
+
}),
|
|
299
324
|
intent: parsed.intent,
|
|
300
325
|
assertions,
|
|
301
326
|
goals,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.410",
|
|
4
4
|
"description": "Local-first personal AI with Ada, task delegation, files, projects, workflows, and automations. Use cloud or local models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -69,13 +69,13 @@
|
|
|
69
69
|
"@composio/core": "0.21.0",
|
|
70
70
|
"@dicebear/collection": "9.4.2",
|
|
71
71
|
"@dicebear/core": "9.4.2",
|
|
72
|
-
"@earendil-works/chord": "1.
|
|
73
|
-
"@earendil-works/pi-agent-core": "1.
|
|
74
|
-
"@earendil-works/pi-ai": "1.
|
|
75
|
-
"@earendil-works/pi-codemode": "1.
|
|
76
|
-
"@earendil-works/pi-coding-agent": "1.
|
|
77
|
-
"@earendil-works/pi-mcp": "1.
|
|
78
|
-
"@earendil-works/pi-tui": "1.
|
|
72
|
+
"@earendil-works/chord": "1.4.0",
|
|
73
|
+
"@earendil-works/pi-agent-core": "1.4.0",
|
|
74
|
+
"@earendil-works/pi-ai": "1.4.0",
|
|
75
|
+
"@earendil-works/pi-codemode": "1.4.0",
|
|
76
|
+
"@earendil-works/pi-coding-agent": "1.4.0",
|
|
77
|
+
"@earendil-works/pi-mcp": "1.4.0",
|
|
78
|
+
"@earendil-works/pi-tui": "1.4.0",
|
|
79
79
|
"@grammyjs/runner": "^2.0.3",
|
|
80
80
|
"@hono/node-server": "^2.0.4",
|
|
81
81
|
"@inquirer/prompts": "^8.5.0",
|
|
@@ -170,12 +170,12 @@
|
|
|
170
170
|
"xlsx": "file:web/vendor/xlsx-0.20.3.tgz",
|
|
171
171
|
"@xopcai/browser-control-contract": "0.1.0",
|
|
172
172
|
"@xopcai/computer-control-contract": "0.1.0",
|
|
173
|
-
"@xopcai/endpoint-tools-client": "0.0.0",
|
|
174
173
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
175
174
|
"@xopcai/gateway-contract": "0.0.0",
|
|
176
175
|
"@xopcai/image-providers": "0.1.0",
|
|
177
176
|
"@xopcai/realtime-client": "0.0.0",
|
|
178
|
-
"@xopcai/realtime-protocol": "0.0.0"
|
|
177
|
+
"@xopcai/realtime-protocol": "0.0.0",
|
|
178
|
+
"@xopcai/endpoint-tools-client": "0.0.0"
|
|
179
179
|
},
|
|
180
180
|
"scripts": {
|
|
181
181
|
"generate:device-tools": "tsx scripts/devices/generate-mobile-tools.mts",
|