@xopcai/xopc 0.0.219 → 0.0.221
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-ext/manifest.json +1 -1
- package/dist/extensions/telegram/xopc.extension.json +1 -1
- package/dist/gateway/static/root/assets/{activity-store-slG02hSm.js → activity-store-NItGQmvR.js} +1 -1
- package/dist/gateway/static/root/assets/{agent-avatar-dicebear-DZ6ETNIk.js → agent-avatar-dicebear-B8SBTGg3.js} +1 -1
- package/dist/gateway/static/root/assets/{agents-DxaIH0Ep.js → agents-Brs2-m6t.js} +1 -1
- package/dist/gateway/static/root/assets/{api-Tz57QxiN.js → api-53ZXsuyr.js} +1 -1
- package/dist/gateway/static/root/assets/{app-management-settings-panel-DdR1L4LR.js → app-management-settings-panel-BtmPXaqu.js} +1 -1
- package/dist/gateway/static/root/assets/{appearance-settings-wYbwqmee.js → appearance-settings-t7HoJyNN.js} +1 -1
- package/dist/gateway/static/root/assets/{apps-page-CyWr6KyO.js → apps-page-DJ_Dsb1j.js} +1 -1
- package/dist/gateway/static/root/assets/{archive-plugin-DKXa160O.js → archive-plugin-D8o8CP9Y.js} +1 -1
- package/dist/gateway/static/root/assets/{attachment-load-CzwA9g2y.js → attachment-load-CsLXzas8.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-page-DwAXyWAY.js → automations-page-D-zgoAKz.js} +1 -1
- package/dist/gateway/static/root/assets/{automations-workspace-CL7ieYIt.js → automations-workspace-DehLRXfd.js} +1 -1
- package/dist/gateway/static/root/assets/{binary-plugins-DoQ_DnT7.js → binary-plugins-B-MjP_22.js} +1 -1
- package/dist/gateway/static/root/assets/{block-editor-Bj_Uxxng.js → block-editor-i4CfDqLG.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-settings-page-BYa_FNC1.js → browser-settings-page-C3QIO4Ti.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflow-inputs-D4roXE6r.js → browser-workflow-inputs-Bi6RSSpD.js} +1 -1
- package/dist/gateway/static/root/assets/{browser-workflows-page-CleKTAKD.js → browser-workflows-page-EEFHUm1i.js} +1 -1
- package/dist/gateway/static/root/assets/{capabilities-settings-panel-DYG37N0k.js → capabilities-settings-panel-BHhUp7FW.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-api-wtEN6Ss6.js → capability-presets-api-pC2fno7r.js} +1 -1
- package/dist/gateway/static/root/assets/{capability-presets-settings-panel-C0Q4dFq-.js → capability-presets-settings-panel-DoClNVLz.js} +1 -1
- package/dist/gateway/static/root/assets/{channel-recipient-api-DhuS2RJ3.js → channel-recipient-api-B5Szgu_z.js} +1 -1
- package/dist/gateway/static/root/assets/{channels-settings-CpO6Xg0n.js → channels-settings-Je-9a5ZC.js} +1 -1
- package/dist/gateway/static/root/assets/channels-status-swr-ByRbxC6z.js +1 -0
- package/dist/gateway/static/root/assets/{chat-terminal-dock-ClQMDe2n.js → chat-terminal-dock-DT-OFl4r.js} +1 -1
- package/dist/gateway/static/root/assets/{connectors-page-BvyiPdKU.js → connectors-page-D8z9Trw4.js} +1 -1
- package/dist/gateway/static/root/assets/{cron-expression-4DvCFs-v.js → cron-expression-MZ_AJqrm.js} +1 -1
- package/dist/gateway/static/root/assets/{date-picker-B6FSjt4Z.js → date-picker-Bv9hZLuD.js} +1 -1
- package/dist/gateway/static/root/assets/{dependency-picker-Za18eMp1.js → dependency-picker-D-6oO_Vk.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-DUUf3yyJ.js → desktop-pet-CiI5caKj.js} +1 -1
- package/dist/gateway/static/root/assets/{desktop-pet-settings-Dwx3GfB8.js → desktop-pet-settings-DhkSOy4K.js} +1 -1
- package/dist/gateway/static/root/assets/{directory-picker-path-field-C6dfTCsl.js → directory-picker-path-field-C4s4Pz8I.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-debug-page-Cordpg4X.js → extension-debug-page-DE7J1-6W.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-page-Dw0dGyMl.js → extension-page-DSnACD7E.js} +1 -1
- package/dist/gateway/static/root/assets/{extension-settings-page-B2pUMaXm.js → extension-settings-page-Dk7k2Pok.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-api-DAZUOEQh.js → gateway-config-api-IOA1OlHx.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-config-swr-BIqRg-zo.js → gateway-config-swr-BzTbnu4O.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-settings-ik2f-pmV.js → gateway-settings-FX7QsgSQ.js} +1 -1
- package/dist/gateway/static/root/assets/{gateway-startup-retry-BFjWYOCS.js → gateway-startup-retry-B2zpkNvi.js} +1 -1
- package/dist/gateway/static/root/assets/{heartbeat-settings-BE81XJ8F.js → heartbeat-settings-D5CGVyci.js} +1 -1
- package/dist/gateway/static/root/assets/{home-page-BTWXJu_m.js → home-page-DzfZFZx5.js} +1 -1
- package/dist/gateway/static/root/assets/{image-generation-api-HXAWlgm6.js → image-generation-api-BXRjz-iY.js} +1 -1
- package/dist/gateway/static/root/assets/index-Dcj5KJRg.css +2 -0
- package/dist/gateway/static/root/assets/{index-B6gWYy08.js → index-EvA8c7fo.js} +11 -45
- package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-ROqQ_Xlo.js → keyboard-shortcuts-settings-BjYiM4xq.js} +1 -1
- package/dist/gateway/static/root/assets/{local-app-workbench-page-Dcaf190G.js → local-app-workbench-page-hPyTaVYU.js} +1 -1
- package/dist/gateway/static/root/assets/{local-apps-page-Be79cyMG.js → local-apps-page-7DHvwSgA.js} +1 -1
- package/dist/gateway/static/root/assets/{locale-store-DfK-Hofd.js → locale-store-iKjqemWG.js} +1 -1
- package/dist/gateway/static/root/assets/{logs-page-C2pjbXno.js → logs-page-DW0xMKWP.js} +1 -1
- package/dist/gateway/static/root/assets/{management-settings-CRspx0oY.js → management-settings-BSxppo9Z.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-split-G3PTpGw3.js → markdown-split-D4oDjZtl.js} +1 -1
- package/dist/gateway/static/root/assets/{markdown-view-D4FPJZ91.js → markdown-view-DYkxMtJA.js} +1 -1
- package/dist/gateway/static/root/assets/{media-plugins-DT0P7j7u.js → media-plugins-BPNTGROA.js} +1 -1
- package/dist/gateway/static/root/assets/messages-kx5W39dO.js +3 -0
- package/dist/gateway/static/root/assets/{notes-api-q7HjYO07.js → notes-api-DJizatxh.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-page-Cgl2h7AR.js → notes-page-DU5tKPTq.js} +1 -1
- package/dist/gateway/static/root/assets/{notes-workbench-DFMQYyGJ.js → notes-workbench-D669d98r.js} +2 -2
- package/dist/gateway/static/root/assets/pcm-capture-worklet-uW_SEACy.js +1 -0
- package/dist/gateway/static/root/assets/{product-open-page-ComKLO4D.js → product-open-page-CPoQvD6P.js} +1 -1
- package/dist/gateway/static/root/assets/{project-detail-page-DUFmQscH.js → project-detail-page-CpsQ9PTA.js} +1 -1
- package/dist/gateway/static/root/assets/{projects-page-CTWxt3dv.js → projects-page-CitO1LMc.js} +1 -1
- package/dist/gateway/static/root/assets/{registry-api-BBoJ7khF.js → registry-api-Cx3JxXSL.js} +1 -1
- package/dist/gateway/static/root/assets/{remote-access-hub-qmG-3qjj.js → remote-access-hub-C9-bL4V6.js} +1 -1
- package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CXHQc53b.js → runtime-tools-settings-panel-xqnWcvIv.js} +1 -1
- package/dist/gateway/static/root/assets/{schema-form-3jTDF2lJ.js → schema-form-CuIDPYu6.js} +1 -1
- package/dist/gateway/static/root/assets/{sessions-page-D_We4_MV.js → sessions-page-CPSARi4y.js} +1 -1
- package/dist/gateway/static/root/assets/settings-advanced-gate-BxT80Fmr.js +1 -0
- package/dist/gateway/static/root/assets/{settings-form-section-CUDozALU.js → settings-form-section-DkAv9ncE.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-loading-skeleton-H3ZH6a6l.js → settings-loading-skeleton-BJUQiEKb.js} +1 -1
- package/dist/gateway/static/root/assets/{settings-page-tx29z21o.js → settings-page-KHRbLwmw.js} +1 -1
- package/dist/gateway/static/root/assets/{setup-status-panel-VunfXpTX.js → setup-status-panel-C8jd20Db.js} +1 -1
- package/dist/gateway/static/root/assets/{share-preview-page-MyThymEx.js → share-preview-page-WCVtJ3sX.js} +1 -1
- package/dist/gateway/static/root/assets/{shares-settings-DkZvY1cr.js → shares-settings-DrQ_cOXh.js} +1 -1
- package/dist/gateway/static/root/assets/skill-reload-api-C_4cG30x.js +1 -0
- package/dist/gateway/static/root/assets/{skills-page-BOOyMnno.js → skills-page-CKhR9J81.js} +1 -1
- package/dist/gateway/static/root/assets/{skills-page.utils-Bl5Yv3Cx.js → skills-page.utils-AYX-e5sD.js} +1 -1
- package/dist/gateway/static/root/assets/{system-settings-panel-DwQ3O1ta.js → system-settings-panel-IIF-K9ML.js} +1 -1
- package/dist/gateway/static/root/assets/{task-detail-page-BwOyrADL.js → task-detail-page-CYjsecEr.js} +1 -1
- package/dist/gateway/static/root/assets/{theme-store-Br4BtK4x.js → theme-store-BOD2D0dJ.js} +1 -1
- package/dist/gateway/static/root/assets/{use-autosave-DRS3RwS9.js → use-autosave-DcktF1j1.js} +1 -1
- package/dist/gateway/static/root/assets/{user-context-page-ClV2r3Cr.js → user-context-page-Cy1D2hkt.js} +1 -1
- package/dist/gateway/static/root/assets/{voice-api-key-field-CGTE5156.js → voice-api-key-field-BMkNTHHE.js} +1 -1
- package/dist/gateway/static/root/assets/{work-discovery-overlay-CW-HKD7h.js → work-discovery-overlay-DVoiXekA.js} +1 -1
- package/dist/gateway/static/root/assets/{workflow-run-setup-panel-Dtr9fDC8.js → workflow-run-setup-panel-Cw4LQjuM.js} +1 -1
- package/dist/gateway/static/root/assets/{workflows-page-CDOyNgZf.js → workflows-page-DKKH1_Yt.js} +1 -1
- package/dist/gateway/static/root/index.html +12 -12
- package/dist/package.js +1 -1
- package/dist/src/agent/agent-manager.js +3 -3
- package/dist/src/agent/embedded/model-runtime.js +1 -1
- package/dist/src/agent/embedded/run-for-session.js +1 -1
- package/dist/src/agent/image/tool-model-config.js +1 -1
- package/dist/src/agent/ipc/inbox.js +1 -1
- package/dist/src/agent/service.js +2 -2
- package/dist/src/agent/session/session-inspector.js +1 -1
- package/dist/src/agent/skills/hub-lock.js +1 -1
- package/dist/src/agent/tasks/task-judge-service.js +3 -3
- package/dist/src/ai-assist/text-assist.js +1 -1
- package/dist/src/auth/credentials.js +2 -2
- package/dist/src/auth/profiles/store.js +1 -1
- package/dist/src/auth/sync-provider-auth.js +2 -2
- package/dist/src/browser/providers/browser-ext-install.js +1 -1
- package/dist/src/cli/commands/doctor/checks/database-schema.js +1 -1
- package/dist/src/cli/commands/doctor/checks/provider-auth.js +1 -1
- package/dist/src/cli/commands/extension-marketplace.js +1 -1
- package/dist/src/cli/commands/extension.js +1 -1
- package/dist/src/cli/commands/models.js +1 -1
- package/dist/src/config/index.js +4 -4
- package/dist/src/config/loader.js +1 -1
- package/dist/src/config/models-json.js +1 -1
- package/dist/src/connectors/connected-source-understanding.js +6 -5
- package/dist/src/connectors/learning-coordinator.js +11 -2
- package/dist/src/extensions/lockfile.js +1 -1
- package/dist/src/extensions/update.js +1 -1
- package/dist/src/gateway/agents-admin.js +1 -1
- package/dist/src/gateway/file-path-classifier.js +1 -1
- package/dist/src/gateway/hono/lib/config-payload.js +1 -1
- package/dist/src/gateway/hono/routes/auth-registry-extensions.js +1 -1
- package/dist/src/gateway/hono/routes/models.js +1 -1
- package/dist/src/gateway/hono/routes/understanding-sources.d.ts +9 -0
- package/dist/src/gateway/hono/routes/understanding-sources.js +47 -14
- package/dist/src/gateway/hono/routes/work-discovery.js +13 -3
- package/dist/src/gateway/service/agent-runner.d.ts +4 -0
- package/dist/src/gateway/service/agent-runner.js +6 -0
- package/dist/src/gateway/service/config-coordinator.js +2 -2
- package/dist/src/gateway/service/run-gateway-agent.js +13 -8
- package/dist/src/gateway/service/sessions-api.d.ts +9 -0
- package/dist/src/gateway/service/sessions-api.js +3 -0
- package/dist/src/gateway/service.js +5 -4
- package/dist/src/infra/update-runner.js +1 -1
- package/dist/src/knowledge/connected-knowledge-pipeline.d.ts +6 -0
- package/dist/src/knowledge/connected-knowledge-pipeline.js +35 -4
- package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
- package/dist/src/providers/index.js +2 -2
- package/dist/src/providers/model-registry.js +1 -1
- package/dist/src/providers/register-runtime-providers.js +1 -1
- package/dist/src/retrieval/queryProfile.d.ts +2 -0
- package/dist/src/retrieval/queryProfile.js +11 -1
- package/dist/src/storage/sqlite/index.d.ts +2 -2
- package/dist/src/storage/sqlite/index.js +3 -3
- package/dist/src/storage/sqlite/knowledge-repository.d.ts +5 -1
- package/dist/src/storage/sqlite/knowledge-repository.js +16 -1
- package/dist/src/storage/sqlite/memory-records-repository.d.ts +2 -0
- package/dist/src/storage/sqlite/memory-records-repository.js +21 -1
- package/dist/src/storage/sqlite/migrations/133_archive_legacy_work_discovery_profile_facts.sql +11 -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/session-repository.js +2 -2
- package/dist/src/tasks/home-query-service.d.ts +14 -0
- package/dist/src/tasks/home-query-service.js +19 -2
- package/dist/src/tui/tui-startup-resources.js +1 -1
- package/dist/src/tui/tui.js +1 -1
- package/dist/src/user-context/consolidation.d.ts +1 -0
- package/dist/src/user-context/consolidation.js +62 -2
- package/dist/src/user-context/focus-lifecycle.d.ts +2 -0
- package/dist/src/user-context/focus-lifecycle.js +26 -0
- package/dist/src/user-context/planner.js +46 -13
- package/dist/src/work-discovery/analyzer.js +6 -4
- package/dist/src/work-discovery/index.js +2 -2
- package/dist/src/work-discovery/service.d.ts +12 -3
- package/dist/src/work-discovery/service.js +164 -83
- package/dist/src/work-discovery/source-repository.d.ts +1 -0
- package/dist/src/work-discovery/source-repository.js +10 -4
- package/dist/src/work-discovery/types.d.ts +2 -1
- package/dist/src/workflows/service/workflow-run-service.js +1 -1
- package/package.json +3 -3
- package/dist/gateway/static/root/assets/channels-status-swr-CXhPeiNj.js +0 -1
- package/dist/gateway/static/root/assets/index-CDkuz_YC.css +0 -2
- package/dist/gateway/static/root/assets/messages-B701TEZ5.js +0 -3
- package/dist/gateway/static/root/assets/settings-advanced-gate-B_QhPgU0.js +0 -1
- package/dist/gateway/static/root/assets/skill-reload-api-DVDOh1iY.js +0 -1
|
@@ -423,6 +423,26 @@ function deleteMemoryRecord(recordId) {
|
|
|
423
423
|
return db.prepare(`DELETE FROM memory_records WHERE record_id = ?`).run(recordId).changes > 0;
|
|
424
424
|
});
|
|
425
425
|
}
|
|
426
|
+
function countMemoryRecordsBySourceInstanceId(sourceInstanceId) {
|
|
427
|
+
const row = getSqliteDatabase().prepare(`SELECT COUNT(*) AS count FROM memory_records
|
|
428
|
+
WHERE json_extract(source_json, '$.sourceInstanceId') = ?`).get(sourceInstanceId);
|
|
429
|
+
return Number(row.count);
|
|
430
|
+
}
|
|
431
|
+
function deleteMemoryRecordsBySourceInstanceId(sourceInstanceId) {
|
|
432
|
+
return runSqliteWriteTransaction((db) => {
|
|
433
|
+
const recordIds = db.prepare(`SELECT record_id FROM memory_records
|
|
434
|
+
WHERE json_extract(source_json, '$.sourceInstanceId') = ?`).all(sourceInstanceId).map((row) => row.record_id);
|
|
435
|
+
if (!recordIds.length) return 0;
|
|
436
|
+
const removeFts = db.prepare("DELETE FROM memory_records_fts WHERE record_id = ?");
|
|
437
|
+
const removeRecord = db.prepare("DELETE FROM memory_records WHERE record_id = ?");
|
|
438
|
+
let deleted = 0;
|
|
439
|
+
for (const recordId of recordIds) {
|
|
440
|
+
removeFts.run(recordId);
|
|
441
|
+
deleted += Number(removeRecord.run(recordId).changes);
|
|
442
|
+
}
|
|
443
|
+
return deleted;
|
|
444
|
+
});
|
|
445
|
+
}
|
|
426
446
|
/** Change lifecycle status without reconstructing or weakening the record's provenance. */
|
|
427
447
|
function setMemoryRecordStatus(recordId, status, nowMs = Date.now()) {
|
|
428
448
|
return runSqliteWriteTransaction((db) => {
|
|
@@ -658,4 +678,4 @@ function parseJsonValue(json, fallback) {
|
|
|
658
678
|
}
|
|
659
679
|
}
|
|
660
680
|
//#endregion
|
|
661
|
-
export { appendMemorySignal, appendMemoryTraceEvent, deleteMemoryRecord, getMemoryProviderState, getMemoryRecord, getMemoryTurnFeedback, hasUnresolvedMemoryConflict, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, markMemoryRecordsConflicted, searchMemoryRecords, setMemoryProviderState, setMemoryRecordStatus, setMemoryTurnFeedback, summarizeMemoryRecallFeedback, upsertMemoryRecord };
|
|
681
|
+
export { appendMemorySignal, appendMemoryTraceEvent, countMemoryRecordsBySourceInstanceId, deleteMemoryRecord, deleteMemoryRecordsBySourceInstanceId, getMemoryProviderState, getMemoryRecord, getMemoryTurnFeedback, hasUnresolvedMemoryConflict, listMemoryRecords, listMemorySignals, listMemoryTraceEvents, markMemoryRecordsConflicted, searchMemoryRecords, setMemoryProviderState, setMemoryRecordStatus, setMemoryTurnFeedback, summarizeMemoryRecallFeedback, upsertMemoryRecord };
|
package/dist/src/storage/sqlite/migrations/133_archive_legacy_work_discovery_profile_facts.sql
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
-- Project stack, repository workflow, and current focus now live in work discovery
|
|
2
|
+
-- summaries/threads/focuses instead of the user's durable profile.
|
|
3
|
+
UPDATE user_understandings
|
|
4
|
+
SET status = 'archived',
|
|
5
|
+
updated_at = CAST(strftime('%s', 'now') AS INTEGER) * 1000
|
|
6
|
+
WHERE status IN ('candidate', 'active', 'needs_review', 'stale')
|
|
7
|
+
AND (
|
|
8
|
+
canonical_key LIKE 'work-discovery:technology:%'
|
|
9
|
+
OR canonical_key LIKE 'work-discovery:workflow:%'
|
|
10
|
+
OR canonical_key LIKE 'work-discovery:focus:%'
|
|
11
|
+
);
|
|
@@ -3,7 +3,7 @@ import type { ApplyMigrationsOptions } from './types.js';
|
|
|
3
3
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
4
4
|
export declare const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
5
5
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
6
|
-
export declare const XOPC_DB_SCHEMA_VERSION =
|
|
6
|
+
export declare const XOPC_DB_SCHEMA_VERSION = 133;
|
|
7
7
|
export declare function resolveMigrationsDir(override?: string): string;
|
|
8
8
|
/**
|
|
9
9
|
* Apply sequential SQL migrations from (currentVersion + 1) through targetVersion.
|
|
@@ -12,7 +12,7 @@ const log = createLogger("Sqlite:Migrations");
|
|
|
12
12
|
/** Baseline schema version applied from schema.sql on first open. */
|
|
13
13
|
const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
14
14
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
15
|
-
const XOPC_DB_SCHEMA_VERSION =
|
|
15
|
+
const XOPC_DB_SCHEMA_VERSION = 133;
|
|
16
16
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
17
17
|
function backupBeforeTaskCutover(db, databasePath) {
|
|
18
18
|
db.exec("PRAGMA wal_checkpoint(FULL)");
|
|
@@ -57,7 +57,7 @@ function applySingleMigration(db, migration) {
|
|
|
57
57
|
* Each step runs in its own transaction and updates schema_meta on success.
|
|
58
58
|
*/
|
|
59
59
|
function applyPendingMigrations(db, options = {}) {
|
|
60
|
-
const targetVersion = options.targetVersion ??
|
|
60
|
+
const targetVersion = options.targetVersion ?? 133;
|
|
61
61
|
let currentVersion = readSchemaVersion(db);
|
|
62
62
|
if (currentVersion > targetVersion) throw new DatabaseSchemaTooNewError(currentVersion, targetVersion);
|
|
63
63
|
if (currentVersion >= targetVersion) return currentVersion;
|
|
@@ -94,7 +94,7 @@ function applyPendingMigrations(db, options = {}) {
|
|
|
94
94
|
}
|
|
95
95
|
/** Inspect schema version without mutating the database. */
|
|
96
96
|
function inspectSchemaMigrationStatus(db, options = {}) {
|
|
97
|
-
const appVersion = options.targetVersion ??
|
|
97
|
+
const appVersion = options.targetVersion ?? 133;
|
|
98
98
|
const dbVersion = readSchemaVersion(db);
|
|
99
99
|
if (dbVersion > appVersion) return {
|
|
100
100
|
dbVersion,
|
|
@@ -19,7 +19,7 @@ const log = createLogger('Sqlite:Migrations');
|
|
|
19
19
|
export const XOPC_DB_BASELINE_SCHEMA_VERSION = 11;
|
|
20
20
|
|
|
21
21
|
/** Latest schema version this release supports (increment when adding migrations). */
|
|
22
|
-
export const XOPC_DB_SCHEMA_VERSION =
|
|
22
|
+
export const XOPC_DB_SCHEMA_VERSION = 133;
|
|
23
23
|
|
|
24
24
|
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
|
|
25
25
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getSqliteDatabase, runSqliteWriteTransaction } from "./transaction.js";
|
|
2
|
-
import {
|
|
2
|
+
import { buildFts5SearchQuery } from "./fts.js";
|
|
3
3
|
import { buildDefaultSessionMetadata } from "./session-metadata.js";
|
|
4
4
|
import { buildGlobalSessionStats, metadataToSessionInsert, sessionRowToMetadata } from "./row-mappers.js";
|
|
5
5
|
import { validateSessionId } from "../../session/session-id.js";
|
|
@@ -129,7 +129,7 @@ function listSessionMetadata(query = {}) {
|
|
|
129
129
|
let searchKeys = null;
|
|
130
130
|
if (query.search?.trim()) {
|
|
131
131
|
const rawSearch = query.search.trim();
|
|
132
|
-
const ftsQuery =
|
|
132
|
+
const ftsQuery = buildFts5SearchQuery(rawSearch);
|
|
133
133
|
const ftsRows = db.prepare(`SELECT DISTINCT session_key FROM transcript_fts WHERE transcript_fts MATCH ? LIMIT 500`).all(ftsQuery);
|
|
134
134
|
const ftsKeys = new Set(ftsRows.map((r) => r.session_key));
|
|
135
135
|
const like = `%${rawSearch.toLowerCase()}%`;
|
|
@@ -30,6 +30,20 @@ interface HomeGatewayPort {
|
|
|
30
30
|
readonly automationServiceInstance: AutomationService;
|
|
31
31
|
readonly projects: ProjectService;
|
|
32
32
|
readonly proactiveInbox: ProactiveInboxService;
|
|
33
|
+
readonly sessions: {
|
|
34
|
+
listActiveRuns(): Array<{
|
|
35
|
+
sessionKey: string;
|
|
36
|
+
runId: string;
|
|
37
|
+
}>;
|
|
38
|
+
getSession(key: string): Promise<{
|
|
39
|
+
name?: string;
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
lastInteractionAt?: string;
|
|
42
|
+
routing?: {
|
|
43
|
+
agentId?: string;
|
|
44
|
+
};
|
|
45
|
+
} | null>;
|
|
46
|
+
};
|
|
33
47
|
createWorkflowRunService(): WorkflowRunService;
|
|
34
48
|
}
|
|
35
49
|
export declare function decisionFromTask(model: TaskReadModel, projectName?: string, locale?: string): HomeDecision | null;
|
|
@@ -294,7 +294,8 @@ var HomeQueryService = class {
|
|
|
294
294
|
const workflowRunStore = this.service.createWorkflowRunService().createRunStore(defaultAgent?.id ?? agents.defaultId);
|
|
295
295
|
const nowMs = Date.now();
|
|
296
296
|
const tasks = this.#tasks.list({ limit: 60 });
|
|
297
|
-
const
|
|
297
|
+
const activeRuns = this.service.sessions.listActiveRuns();
|
|
298
|
+
const [workflowRuns, automations, automationRuns, projects, connectorApprovals, activeRunSessions] = await Promise.all([
|
|
298
299
|
workflowRunStore.listRunSummaries(20),
|
|
299
300
|
this.service.automationServiceInstance.list(),
|
|
300
301
|
this.service.automationServiceInstance.listRuns({ limit: 10 }),
|
|
@@ -303,8 +304,23 @@ var HomeQueryService = class {
|
|
|
303
304
|
principalId: "local-owner",
|
|
304
305
|
status: "pending",
|
|
305
306
|
limit: 100
|
|
306
|
-
}))
|
|
307
|
+
})),
|
|
308
|
+
Promise.all(activeRuns.map(async (run) => ({
|
|
309
|
+
...run,
|
|
310
|
+
session: await this.service.sessions.getSession(run.sessionKey)
|
|
311
|
+
})))
|
|
307
312
|
]);
|
|
313
|
+
const runningConversations = activeRunSessions.filter((item) => Boolean(item.session)).map((item) => {
|
|
314
|
+
const session = item.session;
|
|
315
|
+
const updatedAt = Date.parse(session.lastInteractionAt ?? session.updatedAt);
|
|
316
|
+
return {
|
|
317
|
+
sessionKey: item.sessionKey,
|
|
318
|
+
runId: item.runId,
|
|
319
|
+
...session.name?.trim() ? { title: session.name.trim() } : {},
|
|
320
|
+
...session.routing?.agentId ? { agentId: session.routing.agentId } : {},
|
|
321
|
+
updatedAt: Number.isFinite(updatedAt) ? updatedAt : nowMs
|
|
322
|
+
};
|
|
323
|
+
}).sort((left, right) => right.updatedAt - left.updatedAt);
|
|
308
324
|
const activeTasks = tasks.filter((task) => task.phase !== "closed");
|
|
309
325
|
const projectsById = new Map(projects.items.map((project) => [project.id, project]));
|
|
310
326
|
const activeWorkflowRuns = workflowRuns.filter((run) => run.status === "queued" || run.status === "running").map(toHomeWorkflowRun);
|
|
@@ -395,6 +411,7 @@ var HomeQueryService = class {
|
|
|
395
411
|
scheduled: upcomingAutomations,
|
|
396
412
|
nowMs
|
|
397
413
|
}),
|
|
414
|
+
runningConversations,
|
|
398
415
|
decisions,
|
|
399
416
|
attentionPolicy: governed.policy
|
|
400
417
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveStateDir } from "../config/paths-state.js";
|
|
2
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
3
2
|
import { init_paths, resolveAgentProfileDir, resolveBundledSkillsDir } from "../config/paths.js";
|
|
3
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
4
4
|
import { resolveBootstrapFilesSync } from "../agent/bootstrap/bootstrap-files.js";
|
|
5
5
|
import { createSkillConfigManager, isSkillEnabled } from "../agent/skills/config.js";
|
|
6
6
|
import { loadSkills } from "../agent/skills/index.js";
|
package/dist/src/tui/tui.js
CHANGED
|
@@ -2,10 +2,10 @@ import { version } from "../../package.js";
|
|
|
2
2
|
import { resolveStateDir, resolveXopcDatabasePath } from "../config/paths-state.js";
|
|
3
3
|
import { parseAgentSessionKey } from "../routing/session-key-utils.js";
|
|
4
4
|
import { init_agent_session_key, normalizeAgentId } from "../routing/agent-session-key.js";
|
|
5
|
-
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
6
5
|
import { init_paths } from "../config/paths.js";
|
|
7
6
|
import { loadConfig } from "../config/loader.js";
|
|
8
7
|
import { getAllModels, getAllProviders, getApiKey, init_providers, isProviderConfiguredSync } from "../providers/index.js";
|
|
8
|
+
import { resolveEffectiveAgentProfileForSession } from "../config/agent-profile.js";
|
|
9
9
|
import { ProjectTrustStore, hasTrustRequiringProjectResources } from "../project-trust/trust-store.js";
|
|
10
10
|
import { renderWorkflowFinalSummary, renderWorkflowPanel } from "../agent/workflow/snapshot.js";
|
|
11
11
|
import { ensureStarterAgentsInitialized } from "../agent/starter-agents.js";
|
|
@@ -1,9 +1,67 @@
|
|
|
1
1
|
import { finishContextConsolidationRun, recordContextConsolidationDecision, startContextConsolidationRun } from "../storage/sqlite/context-consolidation-repository.js";
|
|
2
|
-
import { listUnderstandingEvidence, listUnderstandings, setUnderstandingStatus } from "../storage/sqlite/user-context-repository.js";
|
|
2
|
+
import { createUnderstanding, linkUnderstandingEvidence, listUnderstandingEvidence, listUnderstandings, setUnderstandingStatus } from "../storage/sqlite/user-context-repository.js";
|
|
3
3
|
import "../storage/sqlite/index.js";
|
|
4
4
|
//#region src/user-context/consolidation.ts
|
|
5
5
|
const USER_CONTEXT_CONSOLIDATION_TOKEN = "__xopc_user_context_consolidation__";
|
|
6
6
|
const USER_CONTEXT_CONSOLIDATION_AUTOMATION_ID = "system-user-context-consolidation";
|
|
7
|
+
const GLOBAL_CANDIDATE_KINDS = new Set(["preference", "routine"]);
|
|
8
|
+
function stricterSensitivity(items) {
|
|
9
|
+
const order = [
|
|
10
|
+
"normal",
|
|
11
|
+
"personal",
|
|
12
|
+
"secret",
|
|
13
|
+
"regulated"
|
|
14
|
+
];
|
|
15
|
+
return order[Math.max(...items.map((item) => order.indexOf(item.sensitivity)))] ?? "personal";
|
|
16
|
+
}
|
|
17
|
+
function stricterDisclosurePolicy(items) {
|
|
18
|
+
if (items.some((item) => item.disclosurePolicy === "silent")) return "silent";
|
|
19
|
+
if (items.some((item) => item.disclosurePolicy === "ask_before_reference")) return "ask_before_reference";
|
|
20
|
+
return "referenceable";
|
|
21
|
+
}
|
|
22
|
+
function createCrossProjectGlobalCandidates(minProjects) {
|
|
23
|
+
const all = listUnderstandings();
|
|
24
|
+
const existingGlobalKeys = new Set(all.filter((item) => item.scope.type === "global" && item.status !== "archived" && item.status !== "rejected").map((item) => item.canonicalKey));
|
|
25
|
+
const groups = /* @__PURE__ */ new Map();
|
|
26
|
+
for (const item of all) {
|
|
27
|
+
if (item.status !== "active" || item.scope.type !== "project" || !item.scope.id || !GLOBAL_CANDIDATE_KINDS.has(item.kind)) continue;
|
|
28
|
+
const normalizedStatement = item.statement.normalize("NFKC").toLocaleLowerCase().replace(/\s+/g, " ").trim();
|
|
29
|
+
const groupKey = `${item.canonicalKey}\u0000${normalizedStatement}`;
|
|
30
|
+
const group = groups.get(groupKey) ?? [];
|
|
31
|
+
group.push(item);
|
|
32
|
+
groups.set(groupKey, group);
|
|
33
|
+
}
|
|
34
|
+
let created = 0;
|
|
35
|
+
for (const items of groups.values()) {
|
|
36
|
+
const canonicalKey = items[0].canonicalKey;
|
|
37
|
+
const projectCount = new Set(items.map((item) => item.scope.id)).size;
|
|
38
|
+
if (projectCount < Math.max(2, minProjects) || existingGlobalKeys.has(canonicalKey)) continue;
|
|
39
|
+
const exemplar = [...items].sort((left, right) => right.confidence - left.confidence)[0];
|
|
40
|
+
const global = createUnderstanding({
|
|
41
|
+
kind: exemplar.kind,
|
|
42
|
+
canonicalKey,
|
|
43
|
+
status: "candidate",
|
|
44
|
+
scope: { type: "global" },
|
|
45
|
+
explicitness: "inferred",
|
|
46
|
+
durability: exemplar.durability,
|
|
47
|
+
sensitivity: stricterSensitivity(items),
|
|
48
|
+
disclosurePolicy: stricterDisclosurePolicy(items),
|
|
49
|
+
confidence: items.reduce((sum, item) => sum + item.confidence, 0) / items.length,
|
|
50
|
+
statement: exemplar.statement,
|
|
51
|
+
createdBy: "consolidation",
|
|
52
|
+
changeReason: `Repeated across ${projectCount} projects`
|
|
53
|
+
});
|
|
54
|
+
const linked = /* @__PURE__ */ new Set();
|
|
55
|
+
for (const item of items) for (const evidence of listUnderstandingEvidence(item.id, "supports")) {
|
|
56
|
+
if (linked.has(evidence.id)) continue;
|
|
57
|
+
linkUnderstandingEvidence(global.versionId, evidence.id, "supports", item.confidence);
|
|
58
|
+
linked.add(evidence.id);
|
|
59
|
+
}
|
|
60
|
+
existingGlobalKeys.add(canonicalKey);
|
|
61
|
+
created += 1;
|
|
62
|
+
}
|
|
63
|
+
return created;
|
|
64
|
+
}
|
|
7
65
|
function distinctEvidenceCount(understandingId, relation) {
|
|
8
66
|
return new Set(listUnderstandingEvidence(understandingId, relation).map((evidence) => `${evidence.sourceType}:${evidence.sourceInstanceId ?? ""}:${evidence.sourceRef}`)).size;
|
|
9
67
|
}
|
|
@@ -29,7 +87,8 @@ async function runContextConsolidation(input) {
|
|
|
29
87
|
const metrics = {
|
|
30
88
|
scanned: 0,
|
|
31
89
|
needsReview: 0,
|
|
32
|
-
stale: 0
|
|
90
|
+
stale: 0,
|
|
91
|
+
globalCandidates: 0
|
|
33
92
|
};
|
|
34
93
|
try {
|
|
35
94
|
const understandings = listUnderstandings(["candidate", "active"]).slice(0, resolved.limit);
|
|
@@ -89,6 +148,7 @@ async function runContextConsolidation(input) {
|
|
|
89
148
|
metrics.needsReview += 1;
|
|
90
149
|
}
|
|
91
150
|
}
|
|
151
|
+
metrics.globalCandidates = createCrossProjectGlobalCandidates(resolved.minEvidenceSources);
|
|
92
152
|
return {
|
|
93
153
|
run: finishContextConsolidationRun({
|
|
94
154
|
runId: run.runId,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/user-context/focus-lifecycle.ts
|
|
2
|
+
const DAY_MS = 1440 * 60 * 1e3;
|
|
3
|
+
const HORIZON_DAYS = {
|
|
4
|
+
current: {
|
|
5
|
+
review: 14,
|
|
6
|
+
valid: 30
|
|
7
|
+
},
|
|
8
|
+
ongoing: {
|
|
9
|
+
review: 30,
|
|
10
|
+
valid: 120
|
|
11
|
+
},
|
|
12
|
+
long_term: {
|
|
13
|
+
review: 90,
|
|
14
|
+
valid: 365
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function focusLifecycle(horizon, now = Date.now()) {
|
|
18
|
+
const days = HORIZON_DAYS[horizon];
|
|
19
|
+
return {
|
|
20
|
+
validFrom: now,
|
|
21
|
+
reviewAt: now + days.review * DAY_MS,
|
|
22
|
+
validTo: now + days.valid * DAY_MS
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { focusLifecycle };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { consumeContextConsent, ensureContextConsent, getUserProfile, listCollaborationRules, listUnderstandingEvidence, recordContextRun } from "../storage/sqlite/user-context-repository.js";
|
|
1
|
+
import { consumeContextConsent, ensureContextConsent, getUserProfile, listCollaborationRules, listUnderstandingEvidence, listUnderstandings, recordContextRun } from "../storage/sqlite/user-context-repository.js";
|
|
2
2
|
import { retrievalLexicalSimilarity } from "../retrieval/textFeatures.js";
|
|
3
3
|
import { buildRetrievalQueryProfile } from "../retrieval/queryProfile.js";
|
|
4
4
|
import "../storage/sqlite/index.js";
|
|
5
5
|
import { init_session_key, parseSessionKey } from "../routing/session-key.js";
|
|
6
|
+
import { ProjectStore } from "../projects/project-store.js";
|
|
6
7
|
import { readAgentMessageContent } from "../agent/memory/agent-message-access.js";
|
|
7
8
|
import { buildUserContextBlock } from "../agent/memory/context-fence.js";
|
|
8
9
|
import { getUnderstandingSourceGrant, getUnderstandingSourceRun, listUserFocuses } from "./sources/repository.js";
|
|
@@ -13,8 +14,21 @@ import { randomUUID } from "node:crypto";
|
|
|
13
14
|
init_session_key();
|
|
14
15
|
const DEFAULT_MAX_CONTEXT_CHARS = 6e3;
|
|
15
16
|
const DEFAULT_MAX_RESULTS = 12;
|
|
17
|
+
const SELF_REVIEW_MAX_CONTEXT_CHARS = 16e3;
|
|
18
|
+
const SELF_REVIEW_MAX_RESULTS = 50;
|
|
16
19
|
const MAX_FOCUS_RESULTS = 3;
|
|
17
20
|
const MIN_RELEVANCE_SCORE = .25;
|
|
21
|
+
function selfReviewScore(item) {
|
|
22
|
+
const authority = item.explicitness === "explicit" ? .2 : item.explicitness === "observed" ? .1 : 0;
|
|
23
|
+
const durable = item.durability === "durable" ? .1 : item.durability === "recurring" ? .05 : 0;
|
|
24
|
+
return Math.min(1, item.confidence * .7 + authority + durable);
|
|
25
|
+
}
|
|
26
|
+
function scopeLabel(scope, projects) {
|
|
27
|
+
if (scope.type === "global") return "Global";
|
|
28
|
+
if (scope.type === "project") return `Project: ${scope.id ? projects.get(scope.id)?.name ?? scope.id : "unknown"}`;
|
|
29
|
+
if (scope.type === "workspace") return `Workspace: ${scope.id ?? "unknown"}`;
|
|
30
|
+
return "This conversation";
|
|
31
|
+
}
|
|
18
32
|
function prependAgentContext(message, block) {
|
|
19
33
|
if (!block) return message;
|
|
20
34
|
const prefix = `${block}\n\n`;
|
|
@@ -121,8 +135,15 @@ function focusScore(focus, query, scopeInput) {
|
|
|
121
135
|
function renderContextBlock(params) {
|
|
122
136
|
const understandingItems = params.items.filter((item) => item.objectType === "understanding");
|
|
123
137
|
return [
|
|
138
|
+
params.selfReview ? [
|
|
139
|
+
"<user-context-review>",
|
|
140
|
+
"The user explicitly asked what xopc understands about them. This is a review of active, non-sensitive structured understanding across scopes.",
|
|
141
|
+
"Scope labels describe where each item applies. Do not present project facts as global personality traits.",
|
|
142
|
+
"An empty memory_search result does not mean structured user understanding is empty.",
|
|
143
|
+
"</user-context-review>"
|
|
144
|
+
].join("\n") : "",
|
|
124
145
|
params.profileLines.length ? `<user-profile>\n${params.profileLines.join("\n")}\n</user-profile>` : "",
|
|
125
|
-
params.focuses.length ? `<active-focuses>\n${params.focuses.map((focus) => `- ${focus.title}: ${focus.summary} (${focus.horizon})`).join("\n")}\n</active-focuses>` : "",
|
|
146
|
+
params.focuses.length ? `<active-focuses>\n${params.focuses.map((focus) => `- ${params.selfReview ? `[${scopeLabel(focus.scope, params.projects)}] ` : ""}${focus.title}: ${focus.summary} (${focus.horizon})`).join("\n")}\n</active-focuses>` : "",
|
|
126
147
|
params.rules.length ? `<collaboration-contract>\n${params.rules.map((rule) => `- ${rule.statement}`).join("\n")}\n</collaboration-contract>` : "",
|
|
127
148
|
understandingItems.length ? buildUserContextBlock(understandingItems.map((item) => `- ${item.content}\n Evidence: ${params.understandingSources.get(item.recordId) ?? "Unknown source"}`).join("\n")) : ""
|
|
128
149
|
].filter(Boolean).join("\n\n");
|
|
@@ -143,14 +164,18 @@ var UserContextPlanner = class {
|
|
|
143
164
|
};
|
|
144
165
|
const started = Date.now();
|
|
145
166
|
const now = Date.now();
|
|
146
|
-
const
|
|
147
|
-
const
|
|
167
|
+
const requestedMaxResults = params.allocation?.maxResults;
|
|
168
|
+
const requestedMaxChars = params.allocation?.maxChars;
|
|
148
169
|
const scopeInput = {
|
|
149
170
|
sessionKey: params.sessionKey,
|
|
150
171
|
workspaceId: params.workspaceId,
|
|
151
172
|
...params.projectId ? { projectId: params.projectId } : {}
|
|
152
173
|
};
|
|
153
174
|
const queryProfile = buildRetrievalQueryProfile(query, scopeInput);
|
|
175
|
+
const selfReview = queryProfile.selfReview;
|
|
176
|
+
const maxResults = requestedMaxResults ?? (selfReview ? SELF_REVIEW_MAX_RESULTS : DEFAULT_MAX_RESULTS);
|
|
177
|
+
const maxChars = requestedMaxChars ?? (selfReview ? SELF_REVIEW_MAX_CONTEXT_CHARS : DEFAULT_MAX_CONTEXT_CHARS);
|
|
178
|
+
const projects = new ProjectStore();
|
|
154
179
|
const excluded = new Set(params.excludedRecordIds ?? []);
|
|
155
180
|
const rejected = [];
|
|
156
181
|
const consentRequests = [];
|
|
@@ -166,6 +191,8 @@ var UserContextPlanner = class {
|
|
|
166
191
|
rules: selectedRules,
|
|
167
192
|
items,
|
|
168
193
|
understandingSources,
|
|
194
|
+
selfReview,
|
|
195
|
+
projects,
|
|
169
196
|
...overrides
|
|
170
197
|
});
|
|
171
198
|
const profile = getUserProfile();
|
|
@@ -211,14 +238,16 @@ var UserContextPlanner = class {
|
|
|
211
238
|
const rankedFocuses = listUserFocuses(["active"]).map((focus) => ({
|
|
212
239
|
focus,
|
|
213
240
|
score: focusScore(focus, query, scopeInput)
|
|
214
|
-
})).sort((left, right) => right.score - left.score || right.focus.updatedAt - left.focus.updatedAt);
|
|
241
|
+
})).sort((left, right) => selfReview ? right.focus.confidence - left.focus.confidence || right.focus.updatedAt - left.focus.updatedAt : right.score - left.score || right.focus.updatedAt - left.focus.updatedAt);
|
|
215
242
|
for (const { focus, score } of rankedFocuses) {
|
|
216
243
|
const source = focusSourceDescription(focus);
|
|
217
244
|
let reason = focusRejectionReason(focus, scopeInput, now);
|
|
218
|
-
if (
|
|
219
|
-
if (!reason &&
|
|
245
|
+
if (selfReview && reason === "scope_mismatch") reason = void 0;
|
|
246
|
+
if (!reason && !selfReview && score <= MIN_RELEVANCE_SCORE) reason = "low_score";
|
|
247
|
+
if (!reason && selectedFocuses.length >= (selfReview ? maxResults : MAX_FOCUS_RESULTS)) reason = "budget";
|
|
220
248
|
if (!reason && items.length >= maxResults) reason = "budget";
|
|
221
|
-
const
|
|
249
|
+
const focusScope = scopeLabel(focus.scope, projects);
|
|
250
|
+
const content = `${selfReview ? `[${focusScope}] ` : ""}${focus.title}: ${focus.summary} (${focus.horizon})`;
|
|
222
251
|
const nextChars = render({ focuses: [...selectedFocuses, focus] }).length;
|
|
223
252
|
if (!reason && nextChars > maxChars) reason = "budget";
|
|
224
253
|
if (reason) {
|
|
@@ -306,16 +335,19 @@ var UserContextPlanner = class {
|
|
|
306
335
|
injectedChars: addedChars
|
|
307
336
|
});
|
|
308
337
|
}
|
|
309
|
-
const ranked =
|
|
338
|
+
const ranked = (selfReview ? listUnderstandings(["active"]).map((item) => ({
|
|
339
|
+
item,
|
|
340
|
+
score: selfReviewScore(item)
|
|
341
|
+
})).sort((left, right) => right.score - left.score || right.item.updatedAt - left.item.updatedAt) : this.retriever.retrieve({
|
|
310
342
|
query,
|
|
311
343
|
sessionKey: params.sessionKey,
|
|
312
344
|
workspaceId: params.workspaceId,
|
|
313
345
|
...params.projectId ? { projectId: params.projectId } : {},
|
|
314
346
|
maxCandidates: Math.max(maxResults * 5, 50)
|
|
315
|
-
}).
|
|
347
|
+
}).map((result) => ({
|
|
316
348
|
item: result.understanding,
|
|
317
349
|
score: result.score
|
|
318
|
-
}));
|
|
350
|
+
}))).filter(({ item }) => !excluded.has(item.id));
|
|
319
351
|
for (const { item, score } of ranked) {
|
|
320
352
|
const source = sourceDescription(item);
|
|
321
353
|
if (items.length >= maxResults) {
|
|
@@ -338,7 +370,8 @@ var UserContextPlanner = class {
|
|
|
338
370
|
continue;
|
|
339
371
|
}
|
|
340
372
|
let reason = rejectionReason(item, scopeInput, now, queryProfile.timeHints);
|
|
341
|
-
if (
|
|
373
|
+
if (selfReview && reason === "scope_mismatch") reason = void 0;
|
|
374
|
+
if (!reason && !selfReview && score <= MIN_RELEVANCE_SCORE) reason = "low_score";
|
|
342
375
|
if (!reason && item.disclosurePolicy === "ask_before_reference") {
|
|
343
376
|
const consentStatus = consumeContextConsent(item.id, params.sessionKey);
|
|
344
377
|
if (consentStatus !== "granted") {
|
|
@@ -377,7 +410,7 @@ var UserContextPlanner = class {
|
|
|
377
410
|
recordId: item.id,
|
|
378
411
|
objectType: "understanding",
|
|
379
412
|
versionId: item.versionId,
|
|
380
|
-
content: item.statement,
|
|
413
|
+
content: selfReview ? `[${scopeLabel(item.scope, projects)}] ${item.statement}` : item.statement,
|
|
381
414
|
score,
|
|
382
415
|
section: sectionFor(item),
|
|
383
416
|
citation: `user-context://${item.id}`,
|
|
@@ -82,7 +82,7 @@ function validateSuggestion(value, allowedPaths) {
|
|
|
82
82
|
function validateProfileCandidate(value, allowedRefs) {
|
|
83
83
|
if (!value || typeof value !== "object") return null;
|
|
84
84
|
const item = value;
|
|
85
|
-
const category = item.category === "role" || item.category === "
|
|
85
|
+
const category = item.category === "role" || item.category === "responsibility" || item.category === "preference" || item.category === "routine" ? item.category : void 0;
|
|
86
86
|
if (!category || typeof item.statement !== "string") return null;
|
|
87
87
|
const statement = item.statement.trim().slice(0, 500);
|
|
88
88
|
if (statement.length < 4) return null;
|
|
@@ -181,8 +181,9 @@ async function analyzeWorkContext(input) {
|
|
|
181
181
|
"You help a user resume real work in one explicitly selected local folder.",
|
|
182
182
|
"Analyze only the supplied bounded snapshot. Never claim that you ran commands, tests, or inspected anything absent from it.",
|
|
183
183
|
"Return only one JSON object with projectSummary, currentState, uncertainties, suggestions, profileCandidates, workThreads, conversationStarter, lowConfidence, and contextQuestion.",
|
|
184
|
-
"profileCandidates contains
|
|
185
|
-
"
|
|
184
|
+
"profileCandidates contains only user-specific role, responsibility, preference, or routine facts that are directly supported and would remain useful outside this repository snapshot.",
|
|
185
|
+
"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.",
|
|
186
187
|
USER_FACING_UNDERSTANDING_WRITING_GUIDANCE,
|
|
187
188
|
"Do not infer sensitive traits, identity, health, finances, political views, or anything not directly supported by the work evidence.",
|
|
188
189
|
"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.",
|
|
@@ -286,7 +287,8 @@ async function analyzeUnderstandingBatch(input) {
|
|
|
286
287
|
"Analyze one bounded batch from a source the user explicitly chose to connect.",
|
|
287
288
|
"Return only one JSON object with profileCandidates and workThreads.",
|
|
288
289
|
"Return at most 8 profileCandidates and at most 8 workThreads. Prefer the strongest distinct findings.",
|
|
289
|
-
"
|
|
290
|
+
"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.",
|
|
290
292
|
USER_FACING_UNDERSTANDING_WRITING_GUIDANCE,
|
|
291
293
|
"Each work thread has topicKey, title, summary, status, horizon, confidence, and evidenceRefs.",
|
|
292
294
|
"Every evidenceRefs value must be one of the supplied refs. Omit anything without direct support.",
|
|
@@ -8,6 +8,6 @@ import { appendWorkUnderstandingEvidence, createWorkUnderstandingInvestigation,
|
|
|
8
8
|
import { DEFAULT_WORK_INVESTIGATION_BUDGET, investigateWorkContext } from "./investigator.js";
|
|
9
9
|
import { persistWorkThreadsFromDiscovery } from "./thread-service.js";
|
|
10
10
|
import { getWorkDiscoveryDirectorySource, listWorkDiscoveryDirectorySources, revokeWorkDiscoveryDirectorySource, upsertWorkDiscoveryDirectorySource } from "./source-repository.js";
|
|
11
|
-
import { WorkDiscoveryService } from "./service.js";
|
|
11
|
+
import { WorkDiscoveryService, normalizeUnderstandingSourceItems } from "./service.js";
|
|
12
12
|
import { evaluateQuickUnderstandingCase, evaluateWorkUnderstandingCase, meetsQuickUnderstandingGate } from "./evaluation.js";
|
|
13
|
-
export { DEFAULT_WORK_INVESTIGATION_BUDGET, WORK_DISCOVERY_SCAN_POLICY_VERSION, WorkDiscoveryService, analyzeUnderstandingSources, analyzeWorkContext, appendWorkUnderstandingEvidence, canonicalWorkDiscoveryRoot, createWorkDiscoveryRun, createWorkUnderstandingInvestigation, discoverWorkCandidates, evaluateQuickUnderstandingCase, evaluateWorkUnderstandingCase, findActiveWorkDiscoverySourceRefresh, getWorkDiscoveryDirectorySource, getWorkDiscoveryOnboardingState, getWorkDiscoveryRun, getWorkDiscoveryRunByIdempotencyKey, getWorkUnderstandingInvestigation, getWorkUnderstandingInvestigationForRun, investigateWorkContext, listWorkDiscoveryDirectorySources, listWorkDiscoverySourceRefreshes, listWorkUnderstandingEvidence, meetsQuickUnderstandingGate, persistWorkThreadsFromDiscovery, previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, readWorkDiscoveryTextExcerpt, recordWorkDiscoverySourceRefresh, resetWorkUnderstandingInvestigation, resolvePersonalWorkRoots, revokeWorkDiscoveryDirectorySource, searchWorkDiscoveryText, setWorkDiscoveryFeedback, setWorkDiscoveryOnboardingState, summarizeWorkContextSnapshot, updateWorkDiscoveryRun, updateWorkDiscoverySourceRefreshForRun, updateWorkUnderstandingEvidenceObservation, updateWorkUnderstandingInvestigation, upsertWorkDiscoveryDirectorySource, workDiscoveryFingerprintsEqual, workDiscoveryResultMarkdown };
|
|
13
|
+
export { DEFAULT_WORK_INVESTIGATION_BUDGET, WORK_DISCOVERY_SCAN_POLICY_VERSION, WorkDiscoveryService, analyzeUnderstandingSources, analyzeWorkContext, appendWorkUnderstandingEvidence, canonicalWorkDiscoveryRoot, createWorkDiscoveryRun, createWorkUnderstandingInvestigation, discoverWorkCandidates, evaluateQuickUnderstandingCase, evaluateWorkUnderstandingCase, findActiveWorkDiscoverySourceRefresh, getWorkDiscoveryDirectorySource, getWorkDiscoveryOnboardingState, getWorkDiscoveryRun, getWorkDiscoveryRunByIdempotencyKey, getWorkUnderstandingInvestigation, getWorkUnderstandingInvestigationForRun, investigateWorkContext, listWorkDiscoveryDirectorySources, listWorkDiscoverySourceRefreshes, listWorkUnderstandingEvidence, meetsQuickUnderstandingGate, normalizeUnderstandingSourceItems, persistWorkThreadsFromDiscovery, previewWorkDiscoveryRoot, probeWorkDiscoveryRoot, readWorkDiscoveryTextExcerpt, recordWorkDiscoverySourceRefresh, resetWorkUnderstandingInvestigation, resolvePersonalWorkRoots, revokeWorkDiscoveryDirectorySource, searchWorkDiscoveryText, setWorkDiscoveryFeedback, setWorkDiscoveryOnboardingState, summarizeWorkContextSnapshot, updateWorkDiscoveryRun, updateWorkDiscoverySourceRefreshForRun, updateWorkUnderstandingEvidenceObservation, updateWorkUnderstandingInvestigation, upsertWorkDiscoveryDirectorySource, workDiscoveryFingerprintsEqual, workDiscoveryResultMarkdown };
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import type { Config } from '../config/schema.js';
|
|
2
2
|
import type { ProjectService } from '../projects/project-service.js';
|
|
3
3
|
import type { SessionIndex } from '../session/manager.js';
|
|
4
|
+
import type { UnderstandingSourceItem } from '../user-context/sources/types.js';
|
|
4
5
|
import type { WorkDiscoveryCandidate, WorkDiscoveryOnboardingState, WorkDiscoveryRecognitionDecision, WorkDiscoveryRun, WorkDiscoverySource } from './types.js';
|
|
6
|
+
export type ModelProcessingPolicy = 'local_only' | 'remote_allowed';
|
|
7
|
+
/** Sanitize and round-robin local sources so one verbose source cannot starve the rest. */
|
|
8
|
+
export declare function normalizeUnderstandingSourceItems(rawItems: unknown[]): UnderstandingSourceItem[];
|
|
5
9
|
export interface WorkDiscoveryServiceOptions {
|
|
6
10
|
projects: ProjectService;
|
|
7
11
|
sessions: SessionIndex;
|
|
@@ -24,7 +28,11 @@ export declare class WorkDiscoveryService {
|
|
|
24
28
|
};
|
|
25
29
|
discoverCandidates(signal?: AbortSignal): Promise<WorkDiscoveryCandidate[]>;
|
|
26
30
|
listDirectorySources(): import("./types.js").WorkDiscoveryDirectorySource[];
|
|
27
|
-
|
|
31
|
+
getModelProcessingTarget(): {
|
|
32
|
+
provider: string;
|
|
33
|
+
remoteModel: boolean;
|
|
34
|
+
};
|
|
35
|
+
grantDirectorySource(rootPath: string, processingPolicy: ModelProcessingPolicy): Promise<import("./types.js").WorkDiscoveryDirectorySource>;
|
|
28
36
|
checkDirectorySources(): Promise<any[]>;
|
|
29
37
|
refreshDirectorySourceIfChanged(input: {
|
|
30
38
|
id: string;
|
|
@@ -46,7 +54,7 @@ export declare class WorkDiscoveryService {
|
|
|
46
54
|
reused?: undefined;
|
|
47
55
|
}>;
|
|
48
56
|
revokeDirectorySource(id: string): import("./types.js").WorkDiscoveryDirectorySource;
|
|
49
|
-
importUnderstandingSources(rawItems: unknown[], signal?: AbortSignal, runId?: string, rawCheckpoints?: Record<string, unknown>): Promise<{
|
|
57
|
+
importUnderstandingSources(rawItems: unknown[], processingPolicy: ModelProcessingPolicy, signal?: AbortSignal, runId?: string, rawCheckpoints?: Record<string, unknown>): Promise<{
|
|
50
58
|
profileCandidates: any[];
|
|
51
59
|
workThreads: any[];
|
|
52
60
|
focuses: any[];
|
|
@@ -59,7 +67,7 @@ export declare class WorkDiscoveryService {
|
|
|
59
67
|
status: "rejected" | "pending";
|
|
60
68
|
understandingId: string;
|
|
61
69
|
id: string;
|
|
62
|
-
category: "role" | "
|
|
70
|
+
category: "role" | "responsibility" | "preference" | "routine";
|
|
63
71
|
statement: string;
|
|
64
72
|
confidence: "high" | "medium" | "low";
|
|
65
73
|
evidence: string[];
|
|
@@ -86,6 +94,7 @@ export declare class WorkDiscoveryService {
|
|
|
86
94
|
}): Promise<WorkDiscoveryRun>;
|
|
87
95
|
startQuickRun(input: {
|
|
88
96
|
idempotencyKey: string;
|
|
97
|
+
processingPolicy: ModelProcessingPolicy;
|
|
89
98
|
}): Promise<WorkDiscoveryRun>;
|
|
90
99
|
startRun(input: {
|
|
91
100
|
rootPath: string;
|