@xopcai/xopc 0.0.228 → 0.0.230
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-CjGZBs4C.js → agent-avatar-dicebear-Bp_wmuGW.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-B0NI4_NI.js → agents-CKG93dlc.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel--SjycrXk.js → app-management-settings-panel-CwAPK4Jm.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-8G-TVUtg.js → appearance-settings-DsGLvqTb.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-2NiqD-YP.js → apps-page-Ee9qOQEx.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-Bx44zSpz.js → attachment-load-B4qqigAQ.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-CrKAHqc0.js → automations-page-B8ImehSW.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-Q3g9cf0h.js → automations-workspace-BNFAfNwC.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DjDwnHAQ.js → binary-plugins-DaJbyYc2.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-7aMOKoZM.js → block-editor-Kl25XWJc.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-DTwPkmAC.js → browser-settings-page-Cg6NgwE_.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-DVLrWKz_.js → browser-workflows-page-DjMxs33B.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-YcP4FbN7.js → capabilities-settings-panel-NvJKgF1u.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-AcPjHHia.js → capability-presets-settings-panel-C2uBdALe.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-Ca94Q1D-.js → channels-settings-CIcYKMEs.js} +1 -1
- package/dist/gateway/static/root/assets/{chat-terminal-dock-BR-_7KC0.js → chat-terminal-dock-BiU_4Rq6.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-SGxfLTd6.js → connectors-page-CEEcmUiP.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-D8-c-Tkw.js → cron-expression-Cs_5pUPT.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-kV-Jyl9J.js → date-picker-y1kWrFVU.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-CwKcrfGj.js → dependency-picker-skc62zrn.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-CTs5WGzk.js → desktop-pet-settings-BVVCBgYK.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-D9rnchu3.js → desktop-pet-ux9DxchT.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-CCl0aaDm.js → directory-picker-path-field-V8vZP0Dy.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-Cau40SvC.js → extension-debug-page-Dh6DDuvQ.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-BsJXdvIL.js → extension-page-8OKQDEat.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-qWqJyF7-.js → extension-settings-page-BgSV0Nny.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-BI0SELXm.js → gateway-config-api-Dlc6eaTG.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-6ZdOIC7F.js → gateway-settings-DqQgiAUv.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-KBwhXeFD.js → heartbeat-settings-Pxqk5GFH.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-BA2M4CLi.js → home-page-1xjo6wE4.js} +1 -1
- package/dist/gateway/static/root/assets/{index-BX0dz1JK.js → index-Bbd_dXui.js} +17 -17
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-kHtpnyEm.js → keyboard-shortcuts-settings-BSFNqxzY.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-D2nkn09R.js → local-app-workbench-page-heQ4-PJ7.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-BCXa0oUa.js → local-apps-page-DzU6yZ9-.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-D3sNst0K.js → logs-page-BblnS6Jy.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-tHnlfOAQ.js → management-settings-B8hM56HS.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-BMLqHHr5.js → markdown-split-DRbZjxMK.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DybwqTgv.js → media-plugins-B8vMe5VX.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-C24SfF6r.js → notes-page-B-YZ7iuK.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-CTdZc3ov.js → notes-workbench-CAM09C8b.js} +2 -2
- package/dist/gateway/static/root/assets/{product-open-page-DBfCVlJq.js → product-open-page-DkWcyki5.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-COHaEpbA.js → project-detail-page-BIPIwgU2.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-lMnST7D_.js → projects-page-B_kzTn1K.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-BIRKBvO_.js → remote-access-hub-CtD8DsD-.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-BPEGTip5.js → runtime-tools-settings-panel-Bq_ETeal.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-Dxlu60Td.js → schema-form-BogTlrsP.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-CATO9G3y.js → sessions-page-B8n9HI1y.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-xlhdRTME.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-ChXh3Bwk.js → settings-form-section-Coy1Cbp6.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-BCAUqIe2.js → settings-loading-skeleton-B5GU7iCG.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-D25W9Okr.js → settings-page-Dd-BRu12.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-DsN7Z4Fl.js → setup-status-panel-CwEFAVWx.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-CRFnUaNb.js → share-preview-page-DzXw9UQJ.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-CAX0eNaP.js → shares-settings-Bk6UQOwS.js} +1 -1
- package/dist/gateway/static/root/assets/{skill-reload-api-Doy1gghe.js → skill-reload-api-DrmQZ3Au.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page-Cl7jjTK7.js → skills-page-Brxb6QnW.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-BiCl4nb5.js → skills-page.utils-FB5LtEGm.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-BuESR7ZT.js → system-settings-panel-ChosWt8n.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-BRiy8NL3.js → task-detail-page-CW2sJbdc.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-Dg1mgJ_l.js → use-autosave-2SqnmSKD.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-CqoADNKu.js → user-context-page-Bq9KB-Oj.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-BDNexlVR.js → voice-api-key-field-DtTIF6M8.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-BHTfeaWL.js → work-discovery-overlay-CK3aZDdE.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Cf_w-NZy.js → workflow-run-setup-panel-BjOuddkX.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-j0P-uECz.js → workflows-page-CcbGEQol.js} +1 -1
- package/dist/gateway/static/root/index.html +1 -1
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-instance-gateway.d.ts +1 -1
- package/dist/src/agent/agent-manager.d.ts +1 -1
- package/dist/src/agent/agent-manager.js +18 -3
- package/dist/src/agent/background-review/prompts.d.ts +8 -2
- package/dist/src/agent/background-review/prompts.js +25 -12
- package/dist/src/agent/background-review/run-background-review.d.ts +7 -2
- package/dist/src/agent/background-review/run-background-review.js +175 -160
- package/dist/src/agent/inbound/turn-dispatcher.js +1 -1
- package/dist/src/agent/memory/index.d.ts +1 -1
- package/dist/src/agent/memory/index.js +2 -2
- package/dist/src/agent/memory/manager.d.ts +1 -11
- package/dist/src/agent/memory/manager.js +0 -16
- package/dist/src/agent/memory/understanding/service.d.ts +0 -11
- package/dist/src/agent/memory/understanding/service.js +7 -173
- package/dist/src/agent/memory/user-context-coordinator.d.ts +1 -3
- package/dist/src/agent/memory/user-context-coordinator.js +3 -66
- package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
- package/dist/src/agent/service/direct-turn-helpers.js +1 -1
- package/dist/src/agent/service/process-direct-streaming.js +4 -1
- package/dist/src/agent/service/webchat-tts.d.ts +2 -0
- package/dist/src/agent/service/webchat-tts.js +15 -2
- package/dist/src/agent/tools/tts-tool.js +19 -13
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/config/schema.d.ts +4 -0
- package/dist/src/config/schema.js +1 -0
- package/dist/src/connectors/connected-source-understanding.js +35 -21
- package/dist/src/connectors/learning-coordinator.js +1 -42
- package/dist/src/gateway/chat-stream/mapper.d.ts +2 -0
- package/dist/src/gateway/chat-stream/mapper.js +16 -0
- package/dist/src/gateway/hono/routes/understanding-sources.js +4 -1
- package/dist/src/gateway/hono/routes/voice.js +1 -1
- package/dist/src/gateway/hono/routes/you.js +29 -11
- package/dist/src/gateway/service/run-gateway-agent.js +5 -1
- package/dist/src/knowledge/index.d.ts +0 -1
- package/dist/src/knowledge/index.js +1 -2
- package/dist/src/notifications/planner.js +5 -1
- package/dist/src/storage/sqlite/index.d.ts +1 -1
- package/dist/src/storage/sqlite/index.js +2 -2
- package/dist/src/storage/sqlite/migrations/137_understanding_status_audit.sql +71 -0
- package/dist/src/storage/sqlite/migrations/runner.d.ts +1 -1
- package/dist/src/storage/sqlite/migrations/runner.js +3 -3
- package/dist/src/storage/sqlite/migrations/runner.ts +1 -1
- package/dist/src/storage/sqlite/schema.js +1 -1
- package/dist/src/storage/sqlite/user-context-repository.d.ts +16 -4
- package/dist/src/storage/sqlite/user-context-repository.js +56 -12
- package/dist/src/user-context/config.d.ts +8 -0
- package/dist/src/user-context/config.js +3 -0
- package/dist/src/user-context/consolidation.js +16 -4
- package/dist/src/user-context/extraction/executor.d.ts +22 -0
- package/dist/src/user-context/extraction/executor.js +142 -0
- package/dist/src/user-context/extraction/registry.d.ts +1 -1
- package/dist/src/user-context/extraction/registry.js +5 -34
- package/dist/src/user-context/extraction/repair.js +4 -1
- package/dist/src/user-context/extraction/semantic.d.ts +18 -0
- package/dist/src/user-context/extraction/semantic.js +148 -0
- package/dist/src/user-context/understandingQuality.js +4 -0
- package/dist/src/work-discovery/analyzer.js +9 -4
- package/dist/src/work-discovery/service.d.ts +1 -0
- package/dist/src/work-discovery/service.js +5 -4
- package/dist/src/work-discovery/types.d.ts +1 -0
- package/package.json +14 -8
- package/dist/gateway/static/root/assets/settings-advanced-gate-Cco_W41x.js +0 -1
- package/dist/src/agent/memory/understanding/correction.d.ts +0 -3
- package/dist/src/agent/memory/understanding/correction.js +0 -39
- package/dist/src/knowledge/connected-understanding-pipeline.d.ts +0 -17
- package/dist/src/knowledge/connected-understanding-pipeline.js +0 -278
|
@@ -83,7 +83,9 @@ function validateProfileCandidate(value, allowedRefs) {
|
|
|
83
83
|
if (!value || typeof value !== "object") return null;
|
|
84
84
|
const item = value;
|
|
85
85
|
const category = item.category === "role" || item.category === "responsibility" || item.category === "preference" || item.category === "routine" ? item.category : void 0;
|
|
86
|
-
if (!category || typeof item.statement !== "string") return null;
|
|
86
|
+
if (!category || typeof item.statement !== "string" || typeof item.factKey !== "string") return null;
|
|
87
|
+
const factKey = item.factKey.trim().toLocaleLowerCase();
|
|
88
|
+
if (!/^[a-z0-9][a-z0-9:-]{2,119}$/.test(factKey)) return null;
|
|
87
89
|
const statement = item.statement.trim().slice(0, 500);
|
|
88
90
|
if (statement.length < 4) return null;
|
|
89
91
|
const confidence = item.confidence === "high" || item.confidence === "low" ? item.confidence : "medium";
|
|
@@ -92,6 +94,7 @@ function validateProfileCandidate(value, allowedRefs) {
|
|
|
92
94
|
return {
|
|
93
95
|
id: randomUUID(),
|
|
94
96
|
category,
|
|
97
|
+
factKey,
|
|
95
98
|
statement,
|
|
96
99
|
confidence,
|
|
97
100
|
evidence: strings(item.evidence, 4).map((entry) => entry.slice(0, 300)),
|
|
@@ -183,7 +186,8 @@ async function analyzeWorkContext(input) {
|
|
|
183
186
|
"Return only one JSON object with projectSummary, currentState, uncertainties, suggestions, profileCandidates, workThreads, conversationStarter, lowConfidence, and contextQuestion.",
|
|
184
187
|
"profileCandidates contains only user-specific role, responsibility, preference, or routine facts that are directly supported and would remain useful outside this repository snapshot.",
|
|
185
188
|
"Do not put the project stack, packages, architecture, deployment setup, repository conventions, or current task in profileCandidates. Put project facts in projectSummary/currentState and current work in workThreads.",
|
|
186
|
-
"Each profile candidate has category (role, responsibility, preference, or routine), statement, confidence, and evidence.",
|
|
189
|
+
"Each profile candidate has category (role, responsibility, preference, or routine), factKey, statement, confidence, and evidence.",
|
|
190
|
+
"factKey is a stable language-neutral lowercase identifier such as workflow:code-review:github; equivalent facts in different languages must use the same factKey.",
|
|
187
191
|
USER_FACING_UNDERSTANDING_WRITING_GUIDANCE,
|
|
188
192
|
"Do not infer sensitive traits, identity, health, finances, political views, or anything not directly supported by the work evidence.",
|
|
189
193
|
"workThreads contains every distinct evidence-backed work stream with topicKey, title, summary, horizon, status, confidence, and evidenceRefs. Do not merge unrelated streams to force a fixed count.",
|
|
@@ -288,7 +292,8 @@ async function analyzeUnderstandingBatch(input) {
|
|
|
288
292
|
"Return only one JSON object with profileCandidates and workThreads.",
|
|
289
293
|
"Return at most 8 profileCandidates and at most 8 workThreads. Prefer the strongest distinct findings.",
|
|
290
294
|
"profileCandidates contains only user-specific role, responsibility, preference, or routine facts with direct support. Current tasks belong in workThreads; project technologies, packages, architecture, and repository conventions are not user facts.",
|
|
291
|
-
"Each profile candidate has category (role, responsibility, preference, or routine), statement, confidence, evidence, and evidenceRefs.",
|
|
295
|
+
"Each profile candidate has category (role, responsibility, preference, or routine), factKey, statement, confidence, evidence, and evidenceRefs.",
|
|
296
|
+
"factKey is a stable language-neutral lowercase identifier such as workflow:code-review:github; equivalent facts in different languages must use the same factKey.",
|
|
292
297
|
USER_FACING_UNDERSTANDING_WRITING_GUIDANCE,
|
|
293
298
|
"Each work thread has topicKey, title, summary, status, horizon, confidence, and evidenceRefs.",
|
|
294
299
|
"Every evidenceRefs value must be one of the supplied refs. Omit anything without direct support.",
|
|
@@ -359,7 +364,7 @@ function mergeProfileCandidates(candidates) {
|
|
|
359
364
|
high: 3
|
|
360
365
|
};
|
|
361
366
|
for (const candidate of candidates) {
|
|
362
|
-
const key = `${candidate.category}:${candidate.
|
|
367
|
+
const key = `${candidate.category}:${candidate.factKey}`;
|
|
363
368
|
const existing = merged.get(key);
|
|
364
369
|
if (!existing) {
|
|
365
370
|
merged.set(key, candidate);
|
|
@@ -164,8 +164,7 @@ function understandingKind(category) {
|
|
|
164
164
|
return "project_context";
|
|
165
165
|
}
|
|
166
166
|
function understandingKey(candidate) {
|
|
167
|
-
|
|
168
|
-
return `work-discovery:${candidate.category}:${createHash("sha256").update(normalized).digest("hex").slice(0, 20)}`;
|
|
167
|
+
return `understanding:${understandingKind(candidate.category)}:${candidate.factKey}`;
|
|
169
168
|
}
|
|
170
169
|
function sameScope(left, right) {
|
|
171
170
|
return left.type === right.type && left.id === right.id;
|
|
@@ -202,7 +201,7 @@ function decideUnderstanding(input, expectedSourcePrefix) {
|
|
|
202
201
|
const current = getUnderstanding(input.understandingId);
|
|
203
202
|
const owned = current && listUnderstandingEvidence(current.id).some((evidence) => evidence.sourceRef.startsWith(expectedSourcePrefix));
|
|
204
203
|
if (!current || !owned || current.status === "archived") return void 0;
|
|
205
|
-
if (input.status === "rejected") return rejectUnderstanding(current.id, "Rejected from work discovery review");
|
|
204
|
+
if (input.status === "rejected") return rejectUnderstanding(current.id, "Rejected from work discovery review", "user");
|
|
206
205
|
const statement = input.status === "edited" ? input.statement?.trim().slice(0, 500) : void 0;
|
|
207
206
|
if (input.status === "edited" && !statement) return void 0;
|
|
208
207
|
return setUnderstandingStatus((statement ? reviseUnderstanding(current.id, statement, {
|
|
@@ -211,7 +210,9 @@ function decideUnderstanding(input, expectedSourcePrefix) {
|
|
|
211
210
|
changeReason: "Edited during work discovery review"
|
|
212
211
|
}) : current).id, "active", {
|
|
213
212
|
explicitness: "explicit",
|
|
214
|
-
confidence: 1
|
|
213
|
+
confidence: 1,
|
|
214
|
+
actorType: "user",
|
|
215
|
+
source: "work-discovery-review"
|
|
215
216
|
});
|
|
216
217
|
}
|
|
217
218
|
function sessionMetadata(agentId, peerId) {
|
|
@@ -167,6 +167,7 @@ export interface WorkDiscoveryProfileCandidate {
|
|
|
167
167
|
id: string;
|
|
168
168
|
understandingId?: string;
|
|
169
169
|
category: 'role' | 'responsibility' | 'preference' | 'routine';
|
|
170
|
+
factKey: string;
|
|
170
171
|
statement: string;
|
|
171
172
|
confidence: 'high' | 'medium' | 'low';
|
|
172
173
|
evidence: string[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xopcai/xopc",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.230",
|
|
4
4
|
"description": "Local-first personal AI assistant with reviewable user understanding, durable tasks, workflows, automations, and local or cloud models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -108,22 +108,27 @@
|
|
|
108
108
|
"zod": "^4.4.3"
|
|
109
109
|
},
|
|
110
110
|
"peerDependencies": {
|
|
111
|
+
"@huggingface/transformers": "3.8.1",
|
|
111
112
|
"@larksuiteoapi/node-sdk": "^1.66.0",
|
|
112
|
-
"playwright-core": "^1.60.0"
|
|
113
|
+
"playwright-core": "^1.60.0",
|
|
114
|
+
"sherpa-onnx-node": "1.13.4"
|
|
113
115
|
},
|
|
114
116
|
"peerDependenciesMeta": {
|
|
117
|
+
"@huggingface/transformers": {
|
|
118
|
+
"optional": true
|
|
119
|
+
},
|
|
115
120
|
"@larksuiteoapi/node-sdk": {
|
|
116
121
|
"optional": true
|
|
117
122
|
},
|
|
118
123
|
"playwright-core": {
|
|
119
124
|
"optional": true
|
|
125
|
+
},
|
|
126
|
+
"sherpa-onnx-node": {
|
|
127
|
+
"optional": true
|
|
120
128
|
}
|
|
121
129
|
},
|
|
122
|
-
"optionalDependencies": {
|
|
123
|
-
"@huggingface/transformers": "3.8.1",
|
|
124
|
-
"sherpa-onnx-node": "1.13.4"
|
|
125
|
-
},
|
|
126
130
|
"devDependencies": {
|
|
131
|
+
"@huggingface/transformers": "3.8.1",
|
|
127
132
|
"@larksuiteoapi/node-sdk": "^1.66.0",
|
|
128
133
|
"@resvg/resvg-js": "^2.6.2",
|
|
129
134
|
"@tailwindcss/vite": "^4.3.0",
|
|
@@ -147,6 +152,7 @@
|
|
|
147
152
|
"onnxruntime-common": "1.21.0",
|
|
148
153
|
"node-pty": "1.1.0",
|
|
149
154
|
"playwright-core": "^1.60.0",
|
|
155
|
+
"sherpa-onnx-node": "1.13.4",
|
|
150
156
|
"svgo": "4.0.2",
|
|
151
157
|
"tailwindcss": "^4.3.0",
|
|
152
158
|
"tsdown": "0.21.10",
|
|
@@ -158,9 +164,9 @@
|
|
|
158
164
|
"vitest": "4.1.5",
|
|
159
165
|
"vue": "^3.5.35",
|
|
160
166
|
"@xopcai/endpoint-tools-protocol": "0.0.0",
|
|
161
|
-
"@xopcai/realtime-protocol": "0.0.0",
|
|
162
167
|
"@xopcai/gateway-contract": "0.0.0",
|
|
163
|
-
"@xopcai/realtime-client": "0.0.0"
|
|
168
|
+
"@xopcai/realtime-client": "0.0.0",
|
|
169
|
+
"@xopcai/realtime-protocol": "0.0.0"
|
|
164
170
|
},
|
|
165
171
|
"scripts": {
|
|
166
172
|
"assets:brand": "node scripts/generate-brand-assets.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Or as e}from"./index-BX0dz1JK.js";function t(t){let{children:n,fallback:r}=t,i=r===void 0?null:r;return e()?n:i}export{t};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare function isExplicitUnderstandingCorrection(text: string): boolean;
|
|
2
|
-
/** Returns only a concrete replacement statement; pure denials intentionally return null. */
|
|
3
|
-
export declare function extractExplicitUnderstandingCorrectionContent(text: string): string | null;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
//#region src/agent/memory/understanding/correction.ts
|
|
2
|
-
const UNDERSTANDING_CORRECTION_PATTERNS = [
|
|
3
|
-
/(?:你|您)(?:记错|理解错|搞错)(?:了)?(?:我|我的)/,
|
|
4
|
-
/(?:这|那)(?:不是|并非)我的(?:偏好|习惯|情况|信息|边界)/,
|
|
5
|
-
/我(?:没有|从没|从未)(?:说过|表示过|要求过)(?:这|那|这个|那个)/,
|
|
6
|
-
/(?:不要|别再)(?:认为|假设|记成)(?:我|我的)/,
|
|
7
|
-
/you (?:remembered|understood|got) (?:me|my .+?) wrong\b/i,
|
|
8
|
-
/that(?:'s| is) not my (?:preference|habit|situation|information|boundary)\b/i,
|
|
9
|
-
/i (?:never|did not|didn't) (?:say|said|tell you|told you|ask for|asked for) that\b/i,
|
|
10
|
-
/do not assume that about me\b/i
|
|
11
|
-
];
|
|
12
|
-
const UNDERSTANDING_CORRECTION_CONTENT_PATTERNS = [
|
|
13
|
-
/(?:你|您)(?:记错|理解错|搞错)(?:了)?(?:我|我的)(?:偏好|习惯|情况|信息|边界|工作方式)?[,,::;;。]\s*(?:其实|实际上|正确的是)?\s*(.+)$/,
|
|
14
|
-
/(?:这|那)(?:不是|并非)我的(?:偏好|习惯|情况|信息|边界)[,,::;;。]\s*(.+)$/,
|
|
15
|
-
/you (?:remembered|understood|got) (?:me|my .+?) wrong\b[,:;.]?\s*(?:actually[,:]?\s*)?(.+)$/i,
|
|
16
|
-
/that(?:'s| is) not my (?:preference|habit|situation|information|boundary)\b[,:;.]?\s*(.+)$/i
|
|
17
|
-
];
|
|
18
|
-
function normalizeCorrectionContent(content) {
|
|
19
|
-
const normalized = content.replace(/^[“”‘’"'\s]+|[“”‘’"'\s]+$/g, "").replace(/\s+/g, " ").trim();
|
|
20
|
-
return normalized.length >= 4 ? normalized.slice(0, 600) : null;
|
|
21
|
-
}
|
|
22
|
-
function isExplicitUnderstandingCorrection(text) {
|
|
23
|
-
const normalized = text.replace(/\s+/g, " ").trim();
|
|
24
|
-
return normalized.length > 0 && UNDERSTANDING_CORRECTION_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
25
|
-
}
|
|
26
|
-
/** Returns only a concrete replacement statement; pure denials intentionally return null. */
|
|
27
|
-
function extractExplicitUnderstandingCorrectionContent(text) {
|
|
28
|
-
const normalized = text.replace(/\s+/g, " ").trim();
|
|
29
|
-
if (!isExplicitUnderstandingCorrection(normalized)) return null;
|
|
30
|
-
for (const pattern of UNDERSTANDING_CORRECTION_CONTENT_PATTERNS) {
|
|
31
|
-
const match = pattern.exec(normalized);
|
|
32
|
-
if (!match?.[1]) continue;
|
|
33
|
-
const content = normalizeCorrectionContent(match[1]);
|
|
34
|
-
if (content) return content;
|
|
35
|
-
}
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
//#endregion
|
|
39
|
-
export { extractExplicitUnderstandingCorrectionContent, isExplicitUnderstandingCorrection };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { UnderstandingCandidate, UnderstandingReviewResult } from '../agent/memory/understanding/types.js';
|
|
2
|
-
import type { MemoryManager } from '../agent/memory/manager.js';
|
|
3
|
-
import type { KnowledgeSourceItem } from './types.js';
|
|
4
|
-
export type ClaimObservation = {
|
|
5
|
-
class: 'relationship' | 'project' | 'routine';
|
|
6
|
-
key: string;
|
|
7
|
-
value: Record<string, unknown>;
|
|
8
|
-
items: KnowledgeSourceItem[];
|
|
9
|
-
windowDays: number;
|
|
10
|
-
};
|
|
11
|
-
export declare function deriveConnectedClaimObservations(items: KnowledgeSourceItem[]): ClaimObservation[];
|
|
12
|
-
export declare function renderConnectedObservation(observation: ClaimObservation): UnderstandingCandidate;
|
|
13
|
-
export declare class ConnectedUnderstandingPipeline {
|
|
14
|
-
private readonly memoryManager;
|
|
15
|
-
constructor(memoryManager: MemoryManager);
|
|
16
|
-
process(agentId: string, extractionRunId: string): Promise<UnderstandingReviewResult>;
|
|
17
|
-
}
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import { listKnowledgeSourceItems } from "../storage/sqlite/knowledge-repository.js";
|
|
2
|
-
import "../storage/sqlite/index.js";
|
|
3
|
-
import { clusterUnderstandingSignals } from "../user-context/sources/signal-clustering.js";
|
|
4
|
-
import { personIdForIdentity, personIdentityKey, rebuildUserPeopleIndex } from "../user-context/relationships/indexer.js";
|
|
5
|
-
//#region src/knowledge/connected-understanding-pipeline.ts
|
|
6
|
-
function logicalEventKey(item) {
|
|
7
|
-
const value = item.metadata.logicalEventKey;
|
|
8
|
-
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
9
|
-
}
|
|
10
|
-
function eventTime(item) {
|
|
11
|
-
if (!item.occurredAt) return void 0;
|
|
12
|
-
const value = Date.parse(item.occurredAt);
|
|
13
|
-
return Number.isFinite(value) ? value : void 0;
|
|
14
|
-
}
|
|
15
|
-
function normalizedRecord(item) {
|
|
16
|
-
if (!item.normalizedText) return {};
|
|
17
|
-
try {
|
|
18
|
-
const value = JSON.parse(item.normalizedText);
|
|
19
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
20
|
-
} catch {
|
|
21
|
-
return {};
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function textField(record, ...fields) {
|
|
25
|
-
for (const field of fields) {
|
|
26
|
-
const value = record[field];
|
|
27
|
-
if (typeof value === "string" && value.trim()) return value.trim();
|
|
28
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
29
|
-
const nested = value;
|
|
30
|
-
for (const nestedField of [
|
|
31
|
-
"name",
|
|
32
|
-
"full_name",
|
|
33
|
-
"fullName",
|
|
34
|
-
"title"
|
|
35
|
-
]) {
|
|
36
|
-
const nestedValue = nested[nestedField];
|
|
37
|
-
if (typeof nestedValue === "string" && nestedValue.trim()) return nestedValue.trim();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function normalizeConversationTitle(value) {
|
|
43
|
-
return value.replace(/^(?:(?:re|fwd?|回复|转发)\s*[::]\s*)+/i, "").trim();
|
|
44
|
-
}
|
|
45
|
-
function projectSignal(item) {
|
|
46
|
-
if (item.metadata.actorAttributed !== true) return void 0;
|
|
47
|
-
const observationKind = item.metadata.observationKind;
|
|
48
|
-
if (![
|
|
49
|
-
"activity",
|
|
50
|
-
"message",
|
|
51
|
-
"calendar_event",
|
|
52
|
-
"external_task",
|
|
53
|
-
"document_metadata"
|
|
54
|
-
].includes(String(observationKind))) return;
|
|
55
|
-
const title = textField(normalizedRecord(item), "subject", "title", "repository", "project", "fullName", "full_name", "name");
|
|
56
|
-
const subjectKey = typeof item.metadata.subjectKey === "string" && item.metadata.subjectKey.trim() ? item.metadata.subjectKey.trim() : void 0;
|
|
57
|
-
const displayTitle = title ? normalizeConversationTitle(title) : subjectKey;
|
|
58
|
-
if (!displayTitle) return void 0;
|
|
59
|
-
return {
|
|
60
|
-
evidenceRef: item.id,
|
|
61
|
-
sourceId: item.sourceInstanceId,
|
|
62
|
-
title: displayTitle,
|
|
63
|
-
group: typeof item.metadata.toolkit === "string" ? item.metadata.toolkit : void 0,
|
|
64
|
-
subjectKey,
|
|
65
|
-
occurredAt: eventTime(item)
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
function recent(items, days) {
|
|
69
|
-
const now = Date.now();
|
|
70
|
-
const cutoff = now - days * 864e5;
|
|
71
|
-
return items.filter((item) => {
|
|
72
|
-
const time = eventTime(item);
|
|
73
|
-
return time !== void 0 && time >= cutoff && time <= now + 3e5 && logicalEventKey(item);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
function person(value) {
|
|
77
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
78
|
-
const row = value;
|
|
79
|
-
const read = (field) => typeof row[field] === "string" && row[field].trim() ? row[field].trim().slice(0, 160) : void 0;
|
|
80
|
-
const result = {
|
|
81
|
-
name: read("name"),
|
|
82
|
-
email: read("email"),
|
|
83
|
-
username: read("username")
|
|
84
|
-
};
|
|
85
|
-
return result.name || result.email || result.username ? result : void 0;
|
|
86
|
-
}
|
|
87
|
-
function relationshipObservations(items) {
|
|
88
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
89
|
-
for (const item of recent(items, 90)) {
|
|
90
|
-
if (item.metadata.actorAttributed !== true) continue;
|
|
91
|
-
const owners = new Set(Array.isArray(item.metadata.ownerIdentities) ? item.metadata.ownerIdentities.filter((value) => typeof value === "string").map((value) => value.toLowerCase()) : []);
|
|
92
|
-
const values = item.metadata.personEntities;
|
|
93
|
-
if (!Array.isArray(values)) continue;
|
|
94
|
-
for (const value of values) {
|
|
95
|
-
const signal = person(value);
|
|
96
|
-
if (!signal) continue;
|
|
97
|
-
const strongIdentity = (signal.email ?? signal.username)?.toLowerCase();
|
|
98
|
-
if (strongIdentity && owners.has(strongIdentity)) continue;
|
|
99
|
-
const label = signal.name ?? signal.email ?? signal.username;
|
|
100
|
-
const identityKey = personIdentityKey(signal, item.sourceInstanceId);
|
|
101
|
-
const personId = personIdForIdentity(signal, item.sourceInstanceId);
|
|
102
|
-
if (!identityKey || !personId) continue;
|
|
103
|
-
const entry = grouped.get(identityKey) ?? {
|
|
104
|
-
label,
|
|
105
|
-
personId,
|
|
106
|
-
events: /* @__PURE__ */ new Map()
|
|
107
|
-
};
|
|
108
|
-
const eventKey = logicalEventKey(item);
|
|
109
|
-
if (!entry.events.has(eventKey)) entry.events.set(eventKey, item);
|
|
110
|
-
grouped.set(identityKey, entry);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return [...grouped.values()].sort((left, right) => right.events.size - left.events.size).slice(0, 8).map((entry) => ({
|
|
114
|
-
class: "relationship",
|
|
115
|
-
key: `person:${entry.personId}`,
|
|
116
|
-
value: {
|
|
117
|
-
label: entry.label,
|
|
118
|
-
personId: entry.personId
|
|
119
|
-
},
|
|
120
|
-
items: [...entry.events.values()],
|
|
121
|
-
windowDays: 90
|
|
122
|
-
}));
|
|
123
|
-
}
|
|
124
|
-
function routineObservations(items) {
|
|
125
|
-
const slots = /* @__PURE__ */ new Map();
|
|
126
|
-
for (const item of recent(items, 120).filter((candidate) => candidate.itemType === "calendar_event")) {
|
|
127
|
-
const date = new Date(item.occurredAt);
|
|
128
|
-
const slot = `${date.getUTCDay()}:${date.getUTCHours()}`;
|
|
129
|
-
const events = slots.get(slot) ?? /* @__PURE__ */ new Map();
|
|
130
|
-
const eventKey = logicalEventKey(item);
|
|
131
|
-
if (!events.has(eventKey)) events.set(eventKey, item);
|
|
132
|
-
slots.set(slot, events);
|
|
133
|
-
}
|
|
134
|
-
return [...slots.entries()].sort((left, right) => right[1].size - left[1].size).slice(0, 4).map(([slot, events]) => {
|
|
135
|
-
const [weekday, hour] = slot.split(":").map(Number);
|
|
136
|
-
return {
|
|
137
|
-
class: "routine",
|
|
138
|
-
key: `calendar-slot:${slot}`,
|
|
139
|
-
value: {
|
|
140
|
-
weekday,
|
|
141
|
-
hour,
|
|
142
|
-
timezone: "UTC"
|
|
143
|
-
},
|
|
144
|
-
items: [...events.values()],
|
|
145
|
-
windowDays: 120
|
|
146
|
-
};
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
function projectObservations(items) {
|
|
150
|
-
const recentItems = recent(items, 60);
|
|
151
|
-
const byId = new Map(recentItems.map((item) => [item.id, item]));
|
|
152
|
-
return clusterUnderstandingSignals(recentItems.map(projectSignal).filter((signal) => Boolean(signal))).flatMap((cluster) => {
|
|
153
|
-
const events = /* @__PURE__ */ new Map();
|
|
154
|
-
for (const signal of cluster.signals) {
|
|
155
|
-
const item = byId.get(signal.evidenceRef);
|
|
156
|
-
const eventKey = item && logicalEventKey(item);
|
|
157
|
-
if (item && eventKey && !events.has(eventKey)) events.set(eventKey, item);
|
|
158
|
-
}
|
|
159
|
-
if (![...events.values()].some((item) => item.itemType !== "calendar_event")) return [];
|
|
160
|
-
return [{
|
|
161
|
-
class: "project",
|
|
162
|
-
key: `project:${cluster.key}`,
|
|
163
|
-
value: { label: cluster.title },
|
|
164
|
-
items: [...events.values()],
|
|
165
|
-
windowDays: 60
|
|
166
|
-
}];
|
|
167
|
-
}).sort((left, right) => right.items.length - left.items.length).slice(0, 8);
|
|
168
|
-
}
|
|
169
|
-
function deriveConnectedClaimObservations(items) {
|
|
170
|
-
const active = items.filter((item) => !item.deletedAt && item.synthesisPipeline === "connected_knowledge" && item.sensitivity !== "secret" && item.sensitivity !== "regulated" && item.metadata.observationKind !== "inventory");
|
|
171
|
-
return [
|
|
172
|
-
...relationshipObservations(active),
|
|
173
|
-
...routineObservations(active),
|
|
174
|
-
...projectObservations(active)
|
|
175
|
-
];
|
|
176
|
-
}
|
|
177
|
-
function confidenceFor(observation) {
|
|
178
|
-
const days = new Set(observation.items.map((item) => item.occurredAt?.slice(0, 10)).filter(Boolean)).size;
|
|
179
|
-
return Math.min(.92, .48 + Math.min(observation.items.length, 8) * .035 + Math.min(days, 5) * .045);
|
|
180
|
-
}
|
|
181
|
-
function isDurableObservation(observation) {
|
|
182
|
-
const days = new Set(observation.items.map((item) => item.occurredAt?.slice(0, 10)).filter(Boolean)).size;
|
|
183
|
-
return observation.items.length >= 3 && days >= (observation.class === "routine" ? 3 : 2);
|
|
184
|
-
}
|
|
185
|
-
function renderConnectedObservation(observation) {
|
|
186
|
-
const label = typeof observation.value.label === "string" ? observation.value.label : "";
|
|
187
|
-
const confidence = confidenceFor(observation);
|
|
188
|
-
if (observation.class === "relationship") return {
|
|
189
|
-
kind: "relationship",
|
|
190
|
-
content: `Frequently collaborates with ${label}.`,
|
|
191
|
-
canonicalKey: `connected:${observation.key}`,
|
|
192
|
-
payload: typeof observation.value.personId === "string" ? { personId: observation.value.personId } : void 0,
|
|
193
|
-
confidence,
|
|
194
|
-
importance: .65,
|
|
195
|
-
explicitness: "inferred",
|
|
196
|
-
durability: "recurring",
|
|
197
|
-
sensitivity: "personal",
|
|
198
|
-
disclosurePolicy: "ask_before_reference"
|
|
199
|
-
};
|
|
200
|
-
if (observation.class === "project") return {
|
|
201
|
-
kind: "project_context",
|
|
202
|
-
content: `Recently contributed repeatedly to ${label}.`,
|
|
203
|
-
canonicalKey: `connected:${observation.key}`,
|
|
204
|
-
confidence,
|
|
205
|
-
importance: .72,
|
|
206
|
-
explicitness: "inferred",
|
|
207
|
-
durability: "recurring",
|
|
208
|
-
sensitivity: "personal",
|
|
209
|
-
disclosurePolicy: "referenceable"
|
|
210
|
-
};
|
|
211
|
-
const weekday = Number(observation.value.weekday);
|
|
212
|
-
const hour = Number(observation.value.hour);
|
|
213
|
-
return {
|
|
214
|
-
kind: "routine",
|
|
215
|
-
content: `Often has calendar activity on ${[
|
|
216
|
-
"Sunday",
|
|
217
|
-
"Monday",
|
|
218
|
-
"Tuesday",
|
|
219
|
-
"Wednesday",
|
|
220
|
-
"Thursday",
|
|
221
|
-
"Friday",
|
|
222
|
-
"Saturday"
|
|
223
|
-
][weekday] ?? "Unknown"} around ${String(hour).padStart(2, "0")}:00 UTC.`,
|
|
224
|
-
canonicalKey: `connected:${observation.key}`,
|
|
225
|
-
confidence,
|
|
226
|
-
importance: .58,
|
|
227
|
-
explicitness: "inferred",
|
|
228
|
-
durability: "recurring",
|
|
229
|
-
sensitivity: "personal",
|
|
230
|
-
disclosurePolicy: "referenceable"
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
var ConnectedUnderstandingPipeline = class {
|
|
234
|
-
constructor(memoryManager) {
|
|
235
|
-
this.memoryManager = memoryManager;
|
|
236
|
-
}
|
|
237
|
-
async process(agentId, extractionRunId) {
|
|
238
|
-
rebuildUserPeopleIndex();
|
|
239
|
-
const observations = deriveConnectedClaimObservations(listKnowledgeSourceItems({
|
|
240
|
-
agentId,
|
|
241
|
-
includeDeleted: false,
|
|
242
|
-
limit: 500
|
|
243
|
-
}));
|
|
244
|
-
const totals = {
|
|
245
|
-
proposed: observations.length,
|
|
246
|
-
created: 0,
|
|
247
|
-
deduplicated: 0,
|
|
248
|
-
rejected: 0,
|
|
249
|
-
createdRecords: []
|
|
250
|
-
};
|
|
251
|
-
for (const observation of observations) {
|
|
252
|
-
if (!isDurableObservation(observation)) continue;
|
|
253
|
-
const sourceInstanceIds = [...new Set(observation.items.map((item) => item.sourceInstanceId))];
|
|
254
|
-
const result = await this.memoryManager.applyUnderstandingCandidates([renderConnectedObservation(observation)], {
|
|
255
|
-
sourceItemIds: observation.items.map((item) => item.id).slice(0, 20),
|
|
256
|
-
sourceText: JSON.stringify({
|
|
257
|
-
independentEvidenceCount: observation.items.length,
|
|
258
|
-
activeDays: new Set(observation.items.map((item) => item.occurredAt?.slice(0, 10))).size,
|
|
259
|
-
windowDays: observation.windowDays
|
|
260
|
-
}),
|
|
261
|
-
source: {
|
|
262
|
-
provider: "connected-sources",
|
|
263
|
-
...sourceInstanceIds.length === 1 ? { sourceInstanceId: sourceInstanceIds[0] } : {}
|
|
264
|
-
},
|
|
265
|
-
reviewSource: "background",
|
|
266
|
-
extractionRunId
|
|
267
|
-
});
|
|
268
|
-
totals.created += result.created;
|
|
269
|
-
totals.deduplicated += result.deduplicated;
|
|
270
|
-
totals.rejected += result.rejected;
|
|
271
|
-
totals.createdRecords.push(...result.createdRecords);
|
|
272
|
-
totals.writeOutputs = [...totals.writeOutputs ?? [], ...result.writeOutputs ?? []];
|
|
273
|
-
}
|
|
274
|
-
return totals;
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
//#endregion
|
|
278
|
-
export { ConnectedUnderstandingPipeline, deriveConnectedClaimObservations, renderConnectedObservation };
|