memorix 1.7.2 → 1.8.0
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/CHANGELOG.md +59 -1
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/assets/star-history-dark.svg +4 -4
- package/assets/star-history-light.svg +4 -4
- package/assets/star-history.json +47 -3
- package/dist/cli/index.js +1801 -254
- package/dist/dashboard/static/app.js +88 -4
- package/dist/dashboard/static/index.html +10 -0
- package/dist/dashboard/static/style.css +86 -0
- package/dist/index.js +1241 -224
- package/dist/maintenance-runner.js +972 -126
- package/dist/media-audio-runner.js +967 -121
- package/dist/media-video-runner.js +972 -126
- package/dist/memcode-runtime/CHANGELOG.md +59 -1
- package/dist/sdk.js +1240 -223
- package/dist/types.d.ts +8 -0
- package/dist/vector-backfill-runner.js +972 -126
- package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
- package/docs/1.8.0-RELEASE-CANDIDATE-SPEC.md +75 -0
- package/docs/API_REFERENCE.md +37 -1
- package/docs/ARCHITECTURE.md +1 -1
- package/docs/CONFIGURATION.md +57 -1
- package/docs/DASHBOARD.md +10 -0
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/INTEGRATIONS.md +1 -1
- package/docs/PERFORMANCE.md +3 -1
- package/docs/README.md +11 -1
- package/docs/SETUP.md +2 -1
- package/package.json +1 -1
- package/plugins/antigravity/memorix/rules/memorix.md +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/memorix/SKILL.md +1 -1
- package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/plugins/gemini/memorix/GEMINI.md +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +2 -2
- package/server.json +2 -2
- package/src/cli/capability-map.ts +2 -0
- package/src/cli/commands/config-migrate.ts +7 -0
- package/src/cli/commands/context.ts +11 -0
- package/src/cli/commands/doctor.ts +5 -1
- package/src/cli/commands/evidence.ts +56 -0
- package/src/cli/commands/feedback.ts +58 -0
- package/src/cli/commands/init.ts +17 -0
- package/src/cli/commands/resume.ts +2 -0
- package/src/cli/commands/serve-http.ts +201 -12
- package/src/cli/commands/status.ts +2 -0
- package/src/cli/fallback-budget.ts +59 -0
- package/src/cli/index.ts +5 -1
- package/src/compact/engine.ts +26 -1
- package/src/config/dotenv-loader.ts +17 -0
- package/src/config/resolved-config.ts +110 -12
- package/src/config/toml-loader.ts +8 -0
- package/src/config/yaml-loader.ts +9 -0
- package/src/dashboard/config-provenance.ts +17 -0
- package/src/dashboard/evidence.ts +63 -0
- package/src/dashboard/server.ts +93 -68
- package/src/dashboard/static/index.html +10 -0
- package/src/dashboard/static/style.css +86 -0
- package/src/hooks/installers/index.ts +1 -1
- package/src/hooks/official-skills.ts +3 -3
- package/src/hooks/rules/memorix-agent-rules.md +1 -1
- package/src/llm/provider.ts +33 -7
- package/src/memory/feedback-model.ts +4 -0
- package/src/memory/feedback.ts +220 -0
- package/src/memory/observations.ts +19 -0
- package/src/memory/retention.ts +38 -5
- package/src/multimodal/image-loader.ts +6 -3
- package/src/rerank/http-provider.ts +125 -0
- package/src/rerank/index.ts +81 -0
- package/src/rerank/policy.ts +88 -0
- package/src/server/mcp-binding-store.ts +79 -0
- package/src/server/mcp-diagnostics.ts +40 -0
- package/src/server/tool-profile.ts +4 -0
- package/src/server.ts +121 -1
- package/src/store/evidence-store.ts +261 -0
- package/src/store/orama-store.ts +79 -53
- package/src/store/sqlite-db.ts +104 -0
- package/src/types.ts +8 -0
package/dist/cli/index.js
CHANGED
|
@@ -3232,7 +3232,7 @@ ${import_picocolors.default.gray(m3)} ${s4}
|
|
|
3232
3232
|
|
|
3233
3233
|
// src/cli/version.ts
|
|
3234
3234
|
function getCliVersion() {
|
|
3235
|
-
return true ? "1.
|
|
3235
|
+
return true ? "1.8.0" : pkg.version;
|
|
3236
3236
|
}
|
|
3237
3237
|
var init_version = __esm({
|
|
3238
3238
|
"src/cli/version.ts"() {
|
|
@@ -9465,7 +9465,7 @@ function closeAllDatabases() {
|
|
|
9465
9465
|
_dbCache.delete(key);
|
|
9466
9466
|
}
|
|
9467
9467
|
}
|
|
9468
|
-
var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEMORY_OUTCOME_SIGNALS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
9468
|
+
var BetterSqlite3, CREATE_OBSERVATIONS_TABLE, CREATE_MINI_SKILLS_TABLE, CREATE_SESSIONS_TABLE, CREATE_META_TABLE, CREATE_TEAM_AGENTS_TABLE, CREATE_TEAM_MESSAGES_TABLE, CREATE_TEAM_TASKS_TABLE, CREATE_TEAM_TASK_DEPS_TABLE, CREATE_TEAM_LOCKS_TABLE, CREATE_TEAM_ROLES_TABLE, CREATE_CHAT_TRANSCRIPT_TABLE, CREATE_GRAPH_ENTITIES_TABLE, CREATE_GRAPH_RELATIONS_TABLE, CREATE_CODE_FILES_TABLE, CREATE_CODE_SYMBOLS_TABLE, CREATE_CODE_EDGES_TABLE, CREATE_OBSERVATION_CODE_REFS_TABLE, CREATE_SCHEMA_MIGRATIONS_TABLE, CREATE_CODE_STATE_SNAPSHOTS_TABLE, CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE, CREATE_KNOWLEDGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_CLAIM_EVIDENCE_TABLE, CREATE_KNOWLEDGE_CLAIM_EVENTS_TABLE, CREATE_KNOWLEDGE_WORKSPACES_TABLE, CREATE_KNOWLEDGE_PAGES_TABLE, CREATE_KNOWLEDGE_PAGE_CLAIMS_TABLE, CREATE_KNOWLEDGE_PAGE_LINKS_TABLE, CREATE_KNOWLEDGE_PROPOSALS_TABLE, CREATE_KNOWLEDGE_WORKFLOWS_TABLE, CREATE_KNOWLEDGE_WORKFLOW_RUNS_TABLE, CREATE_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MEMORY_OUTCOME_SIGNALS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_EVIDENCE_CARDS_TABLE, CREATE_EVIDENCE_CARD_EVENTS_TABLE, CREATE_MEMORY_FEEDBACK_STATES_TABLE, CREATE_MEMORY_FEEDBACK_EVENTS_TABLE, CREATE_MCP_BINDINGS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
9469
9469
|
var init_sqlite_db = __esm({
|
|
9470
9470
|
"src/store/sqlite-db.ts"() {
|
|
9471
9471
|
"use strict";
|
|
@@ -10111,6 +10111,79 @@ CREATE TABLE IF NOT EXISTS compaction_checkpoints (
|
|
|
10111
10111
|
created_at TEXT NOT NULL,
|
|
10112
10112
|
updated_at TEXT NOT NULL
|
|
10113
10113
|
);
|
|
10114
|
+
`;
|
|
10115
|
+
CREATE_EVIDENCE_CARDS_TABLE = `
|
|
10116
|
+
CREATE TABLE IF NOT EXISTS evidence_cards (
|
|
10117
|
+
id TEXT PRIMARY KEY,
|
|
10118
|
+
project_id TEXT NOT NULL,
|
|
10119
|
+
candidate_kind TEXT NOT NULL,
|
|
10120
|
+
candidate_id TEXT NOT NULL,
|
|
10121
|
+
title TEXT NOT NULL,
|
|
10122
|
+
summary TEXT NOT NULL DEFAULT '',
|
|
10123
|
+
entity_name TEXT,
|
|
10124
|
+
source_kind TEXT NOT NULL,
|
|
10125
|
+
source_ref TEXT NOT NULL,
|
|
10126
|
+
locator TEXT,
|
|
10127
|
+
captured_hash TEXT,
|
|
10128
|
+
session_id TEXT,
|
|
10129
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
10130
|
+
verification TEXT NOT NULL DEFAULT 'unverified',
|
|
10131
|
+
freshness TEXT NOT NULL DEFAULT 'current',
|
|
10132
|
+
stale_reason TEXT,
|
|
10133
|
+
files_json TEXT NOT NULL DEFAULT '[]',
|
|
10134
|
+
related_entities_json TEXT NOT NULL DEFAULT '[]',
|
|
10135
|
+
created_at TEXT NOT NULL,
|
|
10136
|
+
updated_at TEXT NOT NULL,
|
|
10137
|
+
UNIQUE(project_id, candidate_kind, candidate_id)
|
|
10138
|
+
);
|
|
10139
|
+
`;
|
|
10140
|
+
CREATE_EVIDENCE_CARD_EVENTS_TABLE = `
|
|
10141
|
+
CREATE TABLE IF NOT EXISTS evidence_card_events (
|
|
10142
|
+
id TEXT PRIMARY KEY,
|
|
10143
|
+
project_id TEXT NOT NULL,
|
|
10144
|
+
card_id TEXT NOT NULL,
|
|
10145
|
+
kind TEXT NOT NULL,
|
|
10146
|
+
detail TEXT,
|
|
10147
|
+
created_at TEXT NOT NULL,
|
|
10148
|
+
FOREIGN KEY (card_id) REFERENCES evidence_cards(id) ON DELETE CASCADE
|
|
10149
|
+
);
|
|
10150
|
+
`;
|
|
10151
|
+
CREATE_MEMORY_FEEDBACK_STATES_TABLE = `
|
|
10152
|
+
CREATE TABLE IF NOT EXISTS memory_feedback_states (
|
|
10153
|
+
project_id TEXT NOT NULL,
|
|
10154
|
+
candidate_kind TEXT NOT NULL,
|
|
10155
|
+
candidate_id TEXT NOT NULL,
|
|
10156
|
+
weight REAL NOT NULL DEFAULT 1.0,
|
|
10157
|
+
lifecycle_status TEXT NOT NULL DEFAULT 'active',
|
|
10158
|
+
updated_at TEXT NOT NULL,
|
|
10159
|
+
PRIMARY KEY (project_id, candidate_kind, candidate_id)
|
|
10160
|
+
);
|
|
10161
|
+
`;
|
|
10162
|
+
CREATE_MEMORY_FEEDBACK_EVENTS_TABLE = `
|
|
10163
|
+
CREATE TABLE IF NOT EXISTS memory_feedback_events (
|
|
10164
|
+
id TEXT PRIMARY KEY,
|
|
10165
|
+
project_id TEXT NOT NULL,
|
|
10166
|
+
candidate_kind TEXT NOT NULL,
|
|
10167
|
+
candidate_id TEXT NOT NULL,
|
|
10168
|
+
signal TEXT NOT NULL,
|
|
10169
|
+
actor TEXT,
|
|
10170
|
+
note TEXT,
|
|
10171
|
+
source_ref TEXT NOT NULL,
|
|
10172
|
+
target_event_id TEXT,
|
|
10173
|
+
delta REAL NOT NULL DEFAULT 0,
|
|
10174
|
+
observed_at TEXT NOT NULL
|
|
10175
|
+
);
|
|
10176
|
+
`;
|
|
10177
|
+
CREATE_MCP_BINDINGS_TABLE = `
|
|
10178
|
+
CREATE TABLE IF NOT EXISTS mcp_bindings (
|
|
10179
|
+
handle_id TEXT PRIMARY KEY,
|
|
10180
|
+
project_id TEXT NOT NULL,
|
|
10181
|
+
project_root TEXT NOT NULL,
|
|
10182
|
+
data_dir TEXT NOT NULL,
|
|
10183
|
+
created_at TEXT NOT NULL,
|
|
10184
|
+
last_used_at TEXT NOT NULL,
|
|
10185
|
+
expires_at TEXT
|
|
10186
|
+
);
|
|
10114
10187
|
`;
|
|
10115
10188
|
CREATE_INDEXES = `
|
|
10116
10189
|
CREATE INDEX IF NOT EXISTS idx_observations_projectId ON observations(projectId);
|
|
@@ -10173,6 +10246,12 @@ CREATE INDEX IF NOT EXISTS idx_maintenance_targets_updated ON maintenance_target
|
|
|
10173
10246
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_project_recent ON compaction_checkpoints(project_id, status, completed_at DESC, pre_captured_at DESC);
|
|
10174
10247
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_session_pending ON compaction_checkpoints(project_id, session_id, agent, phase, status, pre_captured_at DESC);
|
|
10175
10248
|
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_source ON compaction_checkpoints(project_id, source_key);
|
|
10249
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_cards_project ON evidence_cards(project_id, status, updated_at DESC);
|
|
10250
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(project_id, candidate_kind, candidate_id);
|
|
10251
|
+
CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at);
|
|
10252
|
+
CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC);
|
|
10253
|
+
CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC);
|
|
10254
|
+
CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC);
|
|
10176
10255
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
10177
10256
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
10178
10257
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -10328,6 +10407,22 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
10328
10407
|
}
|
|
10329
10408
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_media_jobs_source_asset ON media_jobs(project_id, source_asset_id, status)");
|
|
10330
10409
|
}
|
|
10410
|
+
},
|
|
10411
|
+
{
|
|
10412
|
+
id: "1.8-context-control-plane",
|
|
10413
|
+
apply: (db2) => {
|
|
10414
|
+
db2.exec(CREATE_EVIDENCE_CARDS_TABLE);
|
|
10415
|
+
db2.exec(CREATE_EVIDENCE_CARD_EVENTS_TABLE);
|
|
10416
|
+
db2.exec(CREATE_MEMORY_FEEDBACK_STATES_TABLE);
|
|
10417
|
+
db2.exec(CREATE_MEMORY_FEEDBACK_EVENTS_TABLE);
|
|
10418
|
+
db2.exec(CREATE_MCP_BINDINGS_TABLE);
|
|
10419
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_cards_project ON evidence_cards(project_id, status, updated_at DESC)");
|
|
10420
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_cards_candidate ON evidence_cards(project_id, candidate_kind, candidate_id)");
|
|
10421
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_evidence_card_events_card ON evidence_card_events(card_id, created_at)");
|
|
10422
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_states_project ON memory_feedback_states(project_id, candidate_kind, updated_at DESC)");
|
|
10423
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_feedback_events_candidate ON memory_feedback_events(project_id, candidate_kind, candidate_id, observed_at DESC)");
|
|
10424
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_mcp_bindings_project ON mcp_bindings(project_id, last_used_at DESC)");
|
|
10425
|
+
}
|
|
10331
10426
|
}
|
|
10332
10427
|
];
|
|
10333
10428
|
_dbCache = /* @__PURE__ */ new Map();
|
|
@@ -20748,6 +20843,7 @@ function loadYamlConfig(projectRoot) {
|
|
|
20748
20843
|
llm: { ...userConfig.llm, ...projectConfig.llm },
|
|
20749
20844
|
agent: { ...userConfig.agent, ...projectConfig.agent },
|
|
20750
20845
|
embedding: { ...userConfig.embedding, ...projectConfig.embedding },
|
|
20846
|
+
rerank: { ...userConfig.rerank, ...projectConfig.rerank },
|
|
20751
20847
|
git: { ...userConfig.git, ...projectConfig.git },
|
|
20752
20848
|
codegraph: { ...userConfig.codegraph, ...projectConfig.codegraph },
|
|
20753
20849
|
behavior: { ...userConfig.behavior, ...projectConfig.behavior },
|
|
@@ -21024,6 +21120,7 @@ function mergeTomlConfig(base, override) {
|
|
|
21024
21120
|
llm: { ...base.memory?.llm, ...override.memory?.llm }
|
|
21025
21121
|
},
|
|
21026
21122
|
embedding: { ...base.embedding, ...override.embedding },
|
|
21123
|
+
rerank: { ...base.rerank, ...override.rerank },
|
|
21027
21124
|
hooks: { ...base.hooks, ...override.hooks },
|
|
21028
21125
|
git: { ...base.git, ...override.git },
|
|
21029
21126
|
codegraph: { ...base.codegraph, ...override.codegraph },
|
|
@@ -21512,6 +21609,8 @@ var require_main = __commonJS({
|
|
|
21512
21609
|
var dotenv_loader_exports = {};
|
|
21513
21610
|
__export(dotenv_loader_exports, {
|
|
21514
21611
|
getLoadedEnvFiles: () => getLoadedEnvFiles,
|
|
21612
|
+
getLoadedEnvKeys: () => getLoadedEnvKeys,
|
|
21613
|
+
getLoadedEnvValue: () => getLoadedEnvValue,
|
|
21515
21614
|
loadDotenv: () => loadDotenv,
|
|
21516
21615
|
resetDotenv: () => resetDotenv
|
|
21517
21616
|
});
|
|
@@ -21522,6 +21621,8 @@ function loadEnvFile(filePath) {
|
|
|
21522
21621
|
const parsed = (0, import_dotenv.parse)(readFileSync7(filePath, "utf-8"));
|
|
21523
21622
|
for (const [key, value] of Object.entries(parsed)) {
|
|
21524
21623
|
if (!(key in process.env)) {
|
|
21624
|
+
loadedEnvKeys.add(key);
|
|
21625
|
+
loadedEnvValues.set(key, value);
|
|
21525
21626
|
process.env[key] = value;
|
|
21526
21627
|
injectedKeys.add(key);
|
|
21527
21628
|
}
|
|
@@ -21534,6 +21635,8 @@ function loadDotenv(projectRoot, options = {}) {
|
|
|
21534
21635
|
resetDotenv();
|
|
21535
21636
|
}
|
|
21536
21637
|
loadedEnvFiles.length = 0;
|
|
21638
|
+
loadedEnvKeys.clear();
|
|
21639
|
+
loadedEnvValues.clear();
|
|
21537
21640
|
if (projectRoot) {
|
|
21538
21641
|
loadEnvFile(getProjectDotenvPath(projectRoot));
|
|
21539
21642
|
}
|
|
@@ -21549,11 +21652,18 @@ function resetDotenv() {
|
|
|
21549
21652
|
dotenvLoaded = false;
|
|
21550
21653
|
dotenvProjectRoot = null;
|
|
21551
21654
|
loadedEnvFiles.length = 0;
|
|
21655
|
+
loadedEnvKeys.clear();
|
|
21552
21656
|
}
|
|
21553
21657
|
function getLoadedEnvFiles() {
|
|
21554
21658
|
return loadedEnvFiles;
|
|
21555
21659
|
}
|
|
21556
|
-
|
|
21660
|
+
function getLoadedEnvKeys() {
|
|
21661
|
+
return loadedEnvKeys;
|
|
21662
|
+
}
|
|
21663
|
+
function getLoadedEnvValue(key) {
|
|
21664
|
+
return loadedEnvValues.get(key);
|
|
21665
|
+
}
|
|
21666
|
+
var import_dotenv, dotenvLoaded, dotenvProjectRoot, loadedEnvFiles, loadedEnvKeys, loadedEnvValues, injectedKeys;
|
|
21557
21667
|
var init_dotenv_loader = __esm({
|
|
21558
21668
|
"src/config/dotenv-loader.ts"() {
|
|
21559
21669
|
"use strict";
|
|
@@ -21563,6 +21673,8 @@ var init_dotenv_loader = __esm({
|
|
|
21563
21673
|
dotenvLoaded = false;
|
|
21564
21674
|
dotenvProjectRoot = null;
|
|
21565
21675
|
loadedEnvFiles = [];
|
|
21676
|
+
loadedEnvKeys = /* @__PURE__ */ new Set();
|
|
21677
|
+
loadedEnvValues = /* @__PURE__ */ new Map();
|
|
21566
21678
|
injectedKeys = /* @__PURE__ */ new Set();
|
|
21567
21679
|
}
|
|
21568
21680
|
});
|
|
@@ -21575,6 +21687,7 @@ __export(resolved_config_exports, {
|
|
|
21575
21687
|
getResolvedConfigForCwd: () => getResolvedConfigForCwd,
|
|
21576
21688
|
getResolvedEmbeddingLane: () => getResolvedEmbeddingLane,
|
|
21577
21689
|
getResolvedMemoryLane: () => getResolvedMemoryLane,
|
|
21690
|
+
getResolvedRerankLane: () => getResolvedRerankLane,
|
|
21578
21691
|
resetResolvedConfigCache: () => resetResolvedConfigCache
|
|
21579
21692
|
});
|
|
21580
21693
|
import { homedir as homedir5 } from "os";
|
|
@@ -21607,6 +21720,16 @@ function getResolvedConfig(options = {}) {
|
|
|
21607
21720
|
legacy.llm?.baseUrl
|
|
21608
21721
|
);
|
|
21609
21722
|
const openRouterMemoryLlmApiKey = isOpenRouterMemoryLane(memoryLlmProvider, memoryLlmBaseUrl) ? process.env.OPENROUTER_API_KEY : void 0;
|
|
21723
|
+
const memoryLlmApiKey = first(
|
|
21724
|
+
process.env.MEMORIX_LLM_API_KEY,
|
|
21725
|
+
process.env.MEMORIX_API_KEY,
|
|
21726
|
+
toml.memory?.llm?.api_key,
|
|
21727
|
+
yaml.llm?.apiKey,
|
|
21728
|
+
legacy.llm?.apiKey,
|
|
21729
|
+
process.env.OPENAI_API_KEY,
|
|
21730
|
+
process.env.ANTHROPIC_API_KEY,
|
|
21731
|
+
openRouterMemoryLlmApiKey
|
|
21732
|
+
);
|
|
21610
21733
|
const resolved = {
|
|
21611
21734
|
agent: {
|
|
21612
21735
|
provider: first(
|
|
@@ -21647,16 +21770,7 @@ function getResolvedConfig(options = {}) {
|
|
|
21647
21770
|
provider: memoryLlmProvider,
|
|
21648
21771
|
model: memoryLlmModel,
|
|
21649
21772
|
baseUrl: memoryLlmBaseUrl,
|
|
21650
|
-
apiKey:
|
|
21651
|
-
process.env.MEMORIX_LLM_API_KEY,
|
|
21652
|
-
process.env.MEMORIX_API_KEY,
|
|
21653
|
-
toml.memory?.llm?.api_key,
|
|
21654
|
-
yaml.llm?.apiKey,
|
|
21655
|
-
legacy.llm?.apiKey,
|
|
21656
|
-
process.env.OPENAI_API_KEY,
|
|
21657
|
-
process.env.ANTHROPIC_API_KEY,
|
|
21658
|
-
openRouterMemoryLlmApiKey
|
|
21659
|
-
)
|
|
21773
|
+
apiKey: memoryLlmApiKey
|
|
21660
21774
|
}
|
|
21661
21775
|
},
|
|
21662
21776
|
embedding: {
|
|
@@ -21666,6 +21780,12 @@ function getResolvedConfig(options = {}) {
|
|
|
21666
21780
|
apiKey: first(process.env.MEMORIX_EMBEDDING_API_KEY, toml.embedding?.api_key, yaml.embedding?.apiKey, legacy.embeddingApi?.apiKey, openRouterEmbeddingApiKey),
|
|
21667
21781
|
dimensions: firstNumber(parseNumber(process.env.MEMORIX_EMBEDDING_DIMENSIONS), toml.embedding?.dimensions, yaml.embedding?.dimensions, legacy.embeddingApi?.dimensions)
|
|
21668
21782
|
},
|
|
21783
|
+
rerank: resolveRerankLane({
|
|
21784
|
+
toml,
|
|
21785
|
+
yaml,
|
|
21786
|
+
memoryLlmApiKey,
|
|
21787
|
+
memoryLlmBaseUrl
|
|
21788
|
+
}),
|
|
21669
21789
|
git: {
|
|
21670
21790
|
autoHook: firstBool(toml.git?.auto_hook, yaml.git?.autoHook),
|
|
21671
21791
|
ingestOnCommit: firstBool(toml.git?.ingest_on_commit, yaml.git?.ingestOnCommit),
|
|
@@ -21735,6 +21855,9 @@ function getResolvedMemoryLane(options = {}) {
|
|
|
21735
21855
|
function getResolvedEmbeddingLane(options = {}) {
|
|
21736
21856
|
return getResolvedConfig(options).embedding;
|
|
21737
21857
|
}
|
|
21858
|
+
function getResolvedRerankLane(options = {}) {
|
|
21859
|
+
return getResolvedConfig(options).rerank;
|
|
21860
|
+
}
|
|
21738
21861
|
function resetResolvedConfigCache() {
|
|
21739
21862
|
}
|
|
21740
21863
|
function first(...values) {
|
|
@@ -21777,6 +21900,10 @@ function getEnvSourceNames() {
|
|
|
21777
21900
|
"MEMORIX_EMBEDDING_BASE_URL",
|
|
21778
21901
|
"MEMORIX_EMBEDDING_MODEL",
|
|
21779
21902
|
"MEMORIX_EMBEDDING_DIMENSIONS",
|
|
21903
|
+
"MEMORIX_RERANK_PROVIDER",
|
|
21904
|
+
"MEMORIX_RERANK_MODEL",
|
|
21905
|
+
"MEMORIX_RERANK_BASE_URL",
|
|
21906
|
+
"MEMORIX_RERANK_API_KEY",
|
|
21780
21907
|
"MEMORIX_CODEGRAPH_EXTERNAL_CONTEXT",
|
|
21781
21908
|
"MEMORIX_CODEGRAPH_EXTERNAL_COMMAND",
|
|
21782
21909
|
"MEMORIX_CODEGRAPH_EXTERNAL_TIMEOUT_MS",
|
|
@@ -21800,6 +21927,63 @@ function normalizeExternalContext(value) {
|
|
|
21800
21927
|
if (normalized === "auto" || normalized === "off") return normalized;
|
|
21801
21928
|
return void 0;
|
|
21802
21929
|
}
|
|
21930
|
+
function normalizeRerankProvider(value) {
|
|
21931
|
+
const normalized = value?.trim().toLowerCase();
|
|
21932
|
+
if (normalized === "http") return "http";
|
|
21933
|
+
return "off";
|
|
21934
|
+
}
|
|
21935
|
+
function resolveRerankLane(args) {
|
|
21936
|
+
const provider2 = normalizeRerankProvider(first(
|
|
21937
|
+
process.env.MEMORIX_RERANK_PROVIDER,
|
|
21938
|
+
args.toml.rerank?.provider,
|
|
21939
|
+
args.yaml.rerank?.provider,
|
|
21940
|
+
"off"
|
|
21941
|
+
));
|
|
21942
|
+
const model = first(
|
|
21943
|
+
process.env.MEMORIX_RERANK_MODEL,
|
|
21944
|
+
args.toml.rerank?.model,
|
|
21945
|
+
args.yaml.rerank?.model
|
|
21946
|
+
);
|
|
21947
|
+
const explicitBaseUrl = first(
|
|
21948
|
+
process.env.MEMORIX_RERANK_BASE_URL,
|
|
21949
|
+
args.toml.rerank?.base_url,
|
|
21950
|
+
args.yaml.rerank?.baseUrl
|
|
21951
|
+
);
|
|
21952
|
+
const baseUrl = provider2 === "http" ? first(explicitBaseUrl, args.memoryLlmBaseUrl) : explicitBaseUrl;
|
|
21953
|
+
const dedicatedApiKey = first(
|
|
21954
|
+
process.env.MEMORIX_RERANK_API_KEY,
|
|
21955
|
+
args.toml.rerank?.api_key,
|
|
21956
|
+
args.yaml.rerank?.apiKey
|
|
21957
|
+
);
|
|
21958
|
+
const sameEndpoint = provider2 === "http" && sameTrustedEndpoint(baseUrl, args.memoryLlmBaseUrl);
|
|
21959
|
+
const inheritedApiKey = sameEndpoint ? args.memoryLlmApiKey : void 0;
|
|
21960
|
+
const apiKey = first(dedicatedApiKey, inheritedApiKey);
|
|
21961
|
+
const canSendRequest = provider2 === "http" && Boolean(baseUrl) && (Boolean(apiKey) || !args.memoryLlmApiKey || sameEndpoint);
|
|
21962
|
+
return { provider: provider2, model, baseUrl, apiKey, canSendRequest };
|
|
21963
|
+
}
|
|
21964
|
+
function sameTrustedEndpoint(left, right) {
|
|
21965
|
+
const a4 = normalizeTrustedEndpoint(left);
|
|
21966
|
+
const b4 = normalizeTrustedEndpoint(right);
|
|
21967
|
+
return Boolean(a4 && b4 && a4 === b4);
|
|
21968
|
+
}
|
|
21969
|
+
function normalizeTrustedEndpoint(value) {
|
|
21970
|
+
const trimmed = value?.trim();
|
|
21971
|
+
if (!trimmed) return void 0;
|
|
21972
|
+
try {
|
|
21973
|
+
const url2 = new URL(trimmed);
|
|
21974
|
+
const protocol = url2.protocol.toLowerCase();
|
|
21975
|
+
const hostname2 = url2.hostname.toLowerCase();
|
|
21976
|
+
const port = url2.port;
|
|
21977
|
+
let pathname = url2.pathname.replace(/\/+$/, "");
|
|
21978
|
+
if (pathname.toLowerCase().endsWith("/rerank")) {
|
|
21979
|
+
pathname = pathname.slice(0, -"/rerank".length).replace(/\/+$/, "");
|
|
21980
|
+
}
|
|
21981
|
+
return `${protocol}//${hostname2}${port ? `:${port}` : ""}${pathname}`;
|
|
21982
|
+
} catch {
|
|
21983
|
+
const fallback = trimmed.replace(/\/+$/, "").replace(/\/rerank$/i, "").replace(/\/+$/, "");
|
|
21984
|
+
return fallback.toLowerCase() || void 0;
|
|
21985
|
+
}
|
|
21986
|
+
}
|
|
21803
21987
|
var init_resolved_config = __esm({
|
|
21804
21988
|
"src/config/resolved-config.ts"() {
|
|
21805
21989
|
"use strict";
|
|
@@ -24035,9 +24219,27 @@ __export(provider_exports2, {
|
|
|
24035
24219
|
getLLMConfig: () => getLLMConfig,
|
|
24036
24220
|
initLLM: () => initLLM,
|
|
24037
24221
|
isLLMEnabled: () => isLLMEnabled,
|
|
24222
|
+
normalizeOpenAICompatibleBaseUrl: () => normalizeOpenAICompatibleBaseUrl,
|
|
24038
24223
|
parseLLMTimeoutMs: () => parseLLMTimeoutMs,
|
|
24039
24224
|
setLLMConfig: () => setLLMConfig
|
|
24040
24225
|
});
|
|
24226
|
+
function normalizeOpenAICompatibleBaseUrl(baseUrl) {
|
|
24227
|
+
const base = baseUrl.trim().replace(/\/+$/, "");
|
|
24228
|
+
if (!base) return base;
|
|
24229
|
+
let pathname = "";
|
|
24230
|
+
try {
|
|
24231
|
+
pathname = new URL(base).pathname.replace(/\/+$/, "");
|
|
24232
|
+
} catch {
|
|
24233
|
+
pathname = base.split(/[?#]/, 1)[0].replace(/\/+$/, "");
|
|
24234
|
+
}
|
|
24235
|
+
const lastSegment = pathname.split("/").filter(Boolean).at(-1);
|
|
24236
|
+
if (lastSegment && OPENAI_API_VERSION_SEGMENT.test(lastSegment)) {
|
|
24237
|
+
return base;
|
|
24238
|
+
}
|
|
24239
|
+
const queryOrHash = base.match(/[?#].*$/)?.[0] ?? "";
|
|
24240
|
+
const pathWithoutQuery = base.slice(0, base.length - queryOrHash.length).replace(/\/+$/, "");
|
|
24241
|
+
return `${pathWithoutQuery}/v1${queryOrHash}`;
|
|
24242
|
+
}
|
|
24041
24243
|
function parseLLMTimeoutMs(raw) {
|
|
24042
24244
|
if (raw === void 0 || raw.trim() === "") return LLM_TIMEOUT_DEFAULT_MS;
|
|
24043
24245
|
const parsed = Number(raw);
|
|
@@ -24141,8 +24343,7 @@ async function callLLM(systemPrompt, userMessage, signal) {
|
|
|
24141
24343
|
}
|
|
24142
24344
|
async function callOpenAICompatible(systemPrompt, userMessage, signal) {
|
|
24143
24345
|
const config2 = currentConfig;
|
|
24144
|
-
|
|
24145
|
-
if (!base.endsWith("/v1")) base += "/v1";
|
|
24346
|
+
const base = normalizeOpenAICompatibleBaseUrl(config2.baseUrl);
|
|
24146
24347
|
const url2 = `${base}/chat/completions`;
|
|
24147
24348
|
const fetchSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(LLM_CALL_TIMEOUT_MS)]) : AbortSignal.timeout(LLM_CALL_TIMEOUT_MS);
|
|
24148
24349
|
const response = await fetch(url2, {
|
|
@@ -24221,8 +24422,7 @@ async function callLLMWithTools(messages, tools, signal) {
|
|
|
24221
24422
|
}
|
|
24222
24423
|
async function callOpenAIWithTools(messages, tools, signal) {
|
|
24223
24424
|
const config2 = currentConfig;
|
|
24224
|
-
|
|
24225
|
-
if (!base.endsWith("/v1")) base += "/v1";
|
|
24425
|
+
const base = normalizeOpenAICompatibleBaseUrl(config2.baseUrl);
|
|
24226
24426
|
const url2 = `${base}/chat/completions`;
|
|
24227
24427
|
const openaiMessages = messages.map((msg) => {
|
|
24228
24428
|
if (msg.role === "tool") {
|
|
@@ -24372,8 +24572,7 @@ async function callAnthropicWithTools(messages, tools, signal) {
|
|
|
24372
24572
|
}
|
|
24373
24573
|
async function* callOpenAIWithToolsStream(messages, tools) {
|
|
24374
24574
|
const config2 = currentConfig;
|
|
24375
|
-
|
|
24376
|
-
if (!base.endsWith("/v1")) base += "/v1";
|
|
24575
|
+
const base = normalizeOpenAICompatibleBaseUrl(config2.baseUrl);
|
|
24377
24576
|
const url2 = `${base}/chat/completions`;
|
|
24378
24577
|
const openaiMessages = messages.map((msg) => {
|
|
24379
24578
|
if (msg.role === "tool") {
|
|
@@ -24621,7 +24820,7 @@ async function* callAnthropicWithToolsStream(messages, tools) {
|
|
|
24621
24820
|
}
|
|
24622
24821
|
};
|
|
24623
24822
|
}
|
|
24624
|
-
var LLM_TIMEOUT_DEFAULT_MS, LLM_TIMEOUT_MIN_MS, LLM_TIMEOUT_MAX_MS, MAX_LLM_RESPONSE_BYTES, LLM_CALL_TIMEOUT_MS, PROVIDER_DEFAULTS, currentConfig;
|
|
24823
|
+
var LLM_TIMEOUT_DEFAULT_MS, LLM_TIMEOUT_MIN_MS, LLM_TIMEOUT_MAX_MS, MAX_LLM_RESPONSE_BYTES, OPENAI_API_VERSION_SEGMENT, LLM_CALL_TIMEOUT_MS, PROVIDER_DEFAULTS, currentConfig;
|
|
24625
24824
|
var init_provider2 = __esm({
|
|
24626
24825
|
"src/llm/provider.ts"() {
|
|
24627
24826
|
"use strict";
|
|
@@ -24631,6 +24830,7 @@ var init_provider2 = __esm({
|
|
|
24631
24830
|
LLM_TIMEOUT_MIN_MS = 1e3;
|
|
24632
24831
|
LLM_TIMEOUT_MAX_MS = 3e5;
|
|
24633
24832
|
MAX_LLM_RESPONSE_BYTES = 2 * 1024 * 1024;
|
|
24833
|
+
OPENAI_API_VERSION_SEGMENT = /^v\d+(?:[a-z][a-z0-9-]*)?$/i;
|
|
24634
24834
|
LLM_CALL_TIMEOUT_MS = parseLLMTimeoutMs(process.env.MEMORIX_LLM_TIMEOUT_MS);
|
|
24635
24835
|
PROVIDER_DEFAULTS = {
|
|
24636
24836
|
openai: { baseUrl: "https://api.openai.com/v1", model: "gpt-4.1-nano" },
|
|
@@ -24690,6 +24890,48 @@ Rules:
|
|
|
24690
24890
|
}
|
|
24691
24891
|
});
|
|
24692
24892
|
|
|
24893
|
+
// src/rerank/policy.ts
|
|
24894
|
+
function parseRerankTimeoutMs(raw) {
|
|
24895
|
+
const value = raw?.trim();
|
|
24896
|
+
if (!value) return DEFAULT_RERANK_TIMEOUT_MS;
|
|
24897
|
+
const parsed = Number(value);
|
|
24898
|
+
if (!Number.isInteger(parsed) || Number.isNaN(parsed)) {
|
|
24899
|
+
console.warn(
|
|
24900
|
+
`[memorix] MEMORIX_RERANK_TIMEOUT_MS="${raw}" is invalid (must be a positive integer between ${RERANK_TIMEOUT_MIN_MS}-${RERANK_TIMEOUT_MAX_MS}ms). Using default ${DEFAULT_RERANK_TIMEOUT_MS}ms.`
|
|
24901
|
+
);
|
|
24902
|
+
return DEFAULT_RERANK_TIMEOUT_MS;
|
|
24903
|
+
}
|
|
24904
|
+
if (parsed < RERANK_TIMEOUT_MIN_MS) return RERANK_TIMEOUT_MIN_MS;
|
|
24905
|
+
if (parsed > RERANK_TIMEOUT_MAX_MS) return RERANK_TIMEOUT_MAX_MS;
|
|
24906
|
+
return parsed;
|
|
24907
|
+
}
|
|
24908
|
+
function resolveRerankTimeoutMs(explicitTimeoutMs) {
|
|
24909
|
+
if (typeof explicitTimeoutMs === "number" && Number.isFinite(explicitTimeoutMs) && explicitTimeoutMs > 0) {
|
|
24910
|
+
return explicitTimeoutMs;
|
|
24911
|
+
}
|
|
24912
|
+
return parseRerankTimeoutMs(process.env.MEMORIX_RERANK_TIMEOUT_MS);
|
|
24913
|
+
}
|
|
24914
|
+
function shouldAttemptHttpRerank(input) {
|
|
24915
|
+
return input.quality === "thorough" && input.hasQuery && input.candidateCount >= MIN_RERANK_CANDIDATES;
|
|
24916
|
+
}
|
|
24917
|
+
function shouldAttemptLlmRerank(input) {
|
|
24918
|
+
if (input.httpRerankConfigured) return false;
|
|
24919
|
+
if (input.quality !== "thorough" || input.tier !== "heavy" || !input.hasQuery) return false;
|
|
24920
|
+
if (input.candidateCount < MIN_RERANK_CANDIDATES) return false;
|
|
24921
|
+
return input.topScore > 0 && input.secondScore / input.topScore > 0.7;
|
|
24922
|
+
}
|
|
24923
|
+
var DEFAULT_RERANK_TIMEOUT_MS, RERANK_TIMEOUT_MIN_MS, RERANK_TIMEOUT_MAX_MS, MIN_RERANK_CANDIDATES;
|
|
24924
|
+
var init_policy = __esm({
|
|
24925
|
+
"src/rerank/policy.ts"() {
|
|
24926
|
+
"use strict";
|
|
24927
|
+
init_esm_shims();
|
|
24928
|
+
DEFAULT_RERANK_TIMEOUT_MS = 3e4;
|
|
24929
|
+
RERANK_TIMEOUT_MIN_MS = 1e3;
|
|
24930
|
+
RERANK_TIMEOUT_MAX_MS = 3e5;
|
|
24931
|
+
MIN_RERANK_CANDIDATES = 3;
|
|
24932
|
+
}
|
|
24933
|
+
});
|
|
24934
|
+
|
|
24693
24935
|
// src/timeout.ts
|
|
24694
24936
|
function withTimeout(promise2, ms2, label) {
|
|
24695
24937
|
return new Promise((resolve6, reject) => {
|
|
@@ -24975,6 +25217,148 @@ var init_aliases = __esm({
|
|
|
24975
25217
|
}
|
|
24976
25218
|
});
|
|
24977
25219
|
|
|
25220
|
+
// src/rerank/http-provider.ts
|
|
25221
|
+
function buildRerankUrl(baseUrl) {
|
|
25222
|
+
const trimmed = baseUrl.trim().replace(/\/+$/, "");
|
|
25223
|
+
if (trimmed.endsWith("/rerank")) return trimmed;
|
|
25224
|
+
return `${trimmed}/rerank`;
|
|
25225
|
+
}
|
|
25226
|
+
function parseRerankResponse(payload) {
|
|
25227
|
+
const rows = extractRows(payload);
|
|
25228
|
+
if (rows.length === 0) {
|
|
25229
|
+
throw new Error("Neural rerank response contained no ranked results");
|
|
25230
|
+
}
|
|
25231
|
+
return rows.sort((a4, b4) => b4.score - a4.score);
|
|
25232
|
+
}
|
|
25233
|
+
function extractRows(payload) {
|
|
25234
|
+
if (Array.isArray(payload)) {
|
|
25235
|
+
return payload.map(rowFromUnknown).filter((row) => row !== null);
|
|
25236
|
+
}
|
|
25237
|
+
if (payload && typeof payload === "object" && "results" in payload) {
|
|
25238
|
+
const results = payload.results;
|
|
25239
|
+
if (Array.isArray(results)) {
|
|
25240
|
+
return results.map(rowFromUnknown).filter((row) => row !== null);
|
|
25241
|
+
}
|
|
25242
|
+
}
|
|
25243
|
+
throw new Error("Neural rerank response was not Cohere or TEI shaped");
|
|
25244
|
+
}
|
|
25245
|
+
function rowFromUnknown(value) {
|
|
25246
|
+
if (!value || typeof value !== "object") return null;
|
|
25247
|
+
const row = value;
|
|
25248
|
+
if (typeof row.index !== "number" || !Number.isFinite(row.index)) return null;
|
|
25249
|
+
const score = typeof row.relevance_score === "number" ? row.relevance_score : typeof row.score === "number" ? row.score : null;
|
|
25250
|
+
if (score === null || !Number.isFinite(score)) return null;
|
|
25251
|
+
return { index: row.index, score };
|
|
25252
|
+
}
|
|
25253
|
+
function buildRerankBody(query, documents, model) {
|
|
25254
|
+
const body = {
|
|
25255
|
+
query,
|
|
25256
|
+
documents,
|
|
25257
|
+
top_n: documents.length,
|
|
25258
|
+
return_documents: false
|
|
25259
|
+
};
|
|
25260
|
+
const trimmed = model?.trim();
|
|
25261
|
+
if (trimmed) body.model = trimmed;
|
|
25262
|
+
return body;
|
|
25263
|
+
}
|
|
25264
|
+
async function rerankViaHttp(query, documents, config2) {
|
|
25265
|
+
if (documents.length === 0) return [];
|
|
25266
|
+
const url2 = buildRerankUrl(config2.baseUrl);
|
|
25267
|
+
const headers = {
|
|
25268
|
+
"content-type": "application/json"
|
|
25269
|
+
};
|
|
25270
|
+
if (config2.apiKey) {
|
|
25271
|
+
headers.authorization = `Bearer ${config2.apiKey}`;
|
|
25272
|
+
}
|
|
25273
|
+
const controller = new AbortController();
|
|
25274
|
+
const timeoutMs = resolveRerankTimeoutMs(config2.timeoutMs);
|
|
25275
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
25276
|
+
try {
|
|
25277
|
+
const fetchImpl = config2.fetchImpl ?? fetch;
|
|
25278
|
+
const response = await fetchImpl(url2, {
|
|
25279
|
+
method: "POST",
|
|
25280
|
+
headers,
|
|
25281
|
+
signal: controller.signal,
|
|
25282
|
+
body: JSON.stringify(buildRerankBody(query, documents, config2.model))
|
|
25283
|
+
});
|
|
25284
|
+
if (!response.ok) {
|
|
25285
|
+
throw new Error(`Neural rerank HTTP ${response.status} from ${url2}`);
|
|
25286
|
+
}
|
|
25287
|
+
return parseRerankResponse(await response.json());
|
|
25288
|
+
} finally {
|
|
25289
|
+
clearTimeout(timer);
|
|
25290
|
+
}
|
|
25291
|
+
}
|
|
25292
|
+
var init_http_provider = __esm({
|
|
25293
|
+
"src/rerank/http-provider.ts"() {
|
|
25294
|
+
"use strict";
|
|
25295
|
+
init_esm_shims();
|
|
25296
|
+
init_policy();
|
|
25297
|
+
}
|
|
25298
|
+
});
|
|
25299
|
+
|
|
25300
|
+
// src/rerank/index.ts
|
|
25301
|
+
var rerank_exports = {};
|
|
25302
|
+
__export(rerank_exports, {
|
|
25303
|
+
DEFAULT_RERANK_TIMEOUT_MS: () => DEFAULT_RERANK_TIMEOUT_MS,
|
|
25304
|
+
MIN_RERANK_CANDIDATES: () => MIN_RERANK_CANDIDATES,
|
|
25305
|
+
isNeuralRerankEnabled: () => isNeuralRerankEnabled,
|
|
25306
|
+
neuralRerankCandidates: () => neuralRerankCandidates,
|
|
25307
|
+
parseRerankTimeoutMs: () => parseRerankTimeoutMs,
|
|
25308
|
+
resolveRerankTimeoutMs: () => resolveRerankTimeoutMs,
|
|
25309
|
+
shouldAttemptHttpRerank: () => shouldAttemptHttpRerank,
|
|
25310
|
+
shouldAttemptLlmRerank: () => shouldAttemptLlmRerank
|
|
25311
|
+
});
|
|
25312
|
+
function isNeuralRerankEnabled(options = {}) {
|
|
25313
|
+
const lane = getResolvedRerankLane(options);
|
|
25314
|
+
return lane.provider === "http" && Boolean(lane.baseUrl);
|
|
25315
|
+
}
|
|
25316
|
+
async function neuralRerankCandidates(query, candidates, options = {}) {
|
|
25317
|
+
if (!isNeuralRerankEnabled(options) || candidates.length === 0) return null;
|
|
25318
|
+
const lane = getResolvedRerankLane(options);
|
|
25319
|
+
if (!lane.canSendRequest || !lane.baseUrl) return null;
|
|
25320
|
+
const toRerank = candidates.slice(0, MAX_RERANK);
|
|
25321
|
+
const rest = candidates.slice(MAX_RERANK);
|
|
25322
|
+
const documents = toRerank.map((candidate2) => candidateText(candidate2));
|
|
25323
|
+
const ranked = await rerankViaHttp(query, documents, {
|
|
25324
|
+
provider: "http",
|
|
25325
|
+
model: lane.model,
|
|
25326
|
+
baseUrl: lane.baseUrl,
|
|
25327
|
+
apiKey: lane.apiKey,
|
|
25328
|
+
timeoutMs: resolveRerankTimeoutMs()
|
|
25329
|
+
});
|
|
25330
|
+
const seen = /* @__PURE__ */ new Set();
|
|
25331
|
+
const reranked = [];
|
|
25332
|
+
for (const row of ranked) {
|
|
25333
|
+
const candidate2 = toRerank[row.index];
|
|
25334
|
+
if (!candidate2 || seen.has(row.index)) continue;
|
|
25335
|
+
reranked.push(candidate2);
|
|
25336
|
+
seen.add(row.index);
|
|
25337
|
+
}
|
|
25338
|
+
for (const [index, candidate2] of toRerank.entries()) {
|
|
25339
|
+
if (!seen.has(index)) reranked.push(candidate2);
|
|
25340
|
+
}
|
|
25341
|
+
reranked.push(...rest);
|
|
25342
|
+
return reranked;
|
|
25343
|
+
}
|
|
25344
|
+
function candidateText(candidate2) {
|
|
25345
|
+
const narrative = candidate2.narrative?.trim();
|
|
25346
|
+
if (narrative) return `${candidate2.title} \u2014 ${narrative.slice(0, 200)}`;
|
|
25347
|
+
return candidate2.title;
|
|
25348
|
+
}
|
|
25349
|
+
var MAX_RERANK;
|
|
25350
|
+
var init_rerank = __esm({
|
|
25351
|
+
"src/rerank/index.ts"() {
|
|
25352
|
+
"use strict";
|
|
25353
|
+
init_esm_shims();
|
|
25354
|
+
init_resolved_config();
|
|
25355
|
+
init_http_provider();
|
|
25356
|
+
init_policy();
|
|
25357
|
+
init_policy();
|
|
25358
|
+
MAX_RERANK = 10;
|
|
25359
|
+
}
|
|
25360
|
+
});
|
|
25361
|
+
|
|
24978
25362
|
// src/llm/quality.ts
|
|
24979
25363
|
var quality_exports = {};
|
|
24980
25364
|
__export(quality_exports, {
|
|
@@ -25014,9 +25398,9 @@ async function rerankResults(query, candidates) {
|
|
|
25014
25398
|
if (!isLLMEnabled() || candidates.length <= 2) {
|
|
25015
25399
|
return { reranked: candidates, usedLLM: false };
|
|
25016
25400
|
}
|
|
25017
|
-
const
|
|
25018
|
-
const toRerank = candidates.slice(0,
|
|
25019
|
-
const rest = candidates.slice(
|
|
25401
|
+
const MAX_RERANK2 = 10;
|
|
25402
|
+
const toRerank = candidates.slice(0, MAX_RERANK2);
|
|
25403
|
+
const rest = candidates.slice(MAX_RERANK2);
|
|
25020
25404
|
try {
|
|
25021
25405
|
const candidateList = toRerank.map(
|
|
25022
25406
|
(c6) => `[ID: ${c6.id}] (${c6.type}) ${c6.title}${c6.narrative ? ` \u2014 ${c6.narrative.substring(0, 100)}` : ""}`
|
|
@@ -26334,6 +26718,234 @@ var init_lifecycle = __esm({
|
|
|
26334
26718
|
}
|
|
26335
26719
|
});
|
|
26336
26720
|
|
|
26721
|
+
// src/store/evidence-store.ts
|
|
26722
|
+
var evidence_store_exports = {};
|
|
26723
|
+
__export(evidence_store_exports, {
|
|
26724
|
+
EvidenceCardStore: () => EvidenceCardStore,
|
|
26725
|
+
buildEvidenceCardId: () => buildEvidenceCardId
|
|
26726
|
+
});
|
|
26727
|
+
import { createHash as createHash3, randomUUID as randomUUID3 } from "crypto";
|
|
26728
|
+
function safeJson(value, fallback) {
|
|
26729
|
+
if (typeof value !== "string" || value.length === 0) return fallback;
|
|
26730
|
+
try {
|
|
26731
|
+
return JSON.parse(value);
|
|
26732
|
+
} catch {
|
|
26733
|
+
return fallback;
|
|
26734
|
+
}
|
|
26735
|
+
}
|
|
26736
|
+
function rowToCard(row) {
|
|
26737
|
+
return {
|
|
26738
|
+
id: String(row.id),
|
|
26739
|
+
projectId: String(row.project_id),
|
|
26740
|
+
candidateKind: row.candidate_kind,
|
|
26741
|
+
candidateId: String(row.candidate_id),
|
|
26742
|
+
title: String(row.title),
|
|
26743
|
+
summary: String(row.summary ?? ""),
|
|
26744
|
+
...row.entity_name ? { entityName: String(row.entity_name) } : {},
|
|
26745
|
+
sourceKind: String(row.source_kind),
|
|
26746
|
+
sourceRef: String(row.source_ref),
|
|
26747
|
+
...row.locator ? { locator: String(row.locator) } : {},
|
|
26748
|
+
...row.captured_hash ? { capturedHash: String(row.captured_hash) } : {},
|
|
26749
|
+
...row.session_id ? { sessionId: String(row.session_id) } : {},
|
|
26750
|
+
status: String(row.status ?? "active"),
|
|
26751
|
+
verification: row.verification,
|
|
26752
|
+
freshness: row.freshness,
|
|
26753
|
+
...row.stale_reason ? { staleReason: String(row.stale_reason) } : {},
|
|
26754
|
+
files: safeJson(row.files_json, []),
|
|
26755
|
+
relatedEntities: safeJson(row.related_entities_json, []),
|
|
26756
|
+
createdAt: String(row.created_at),
|
|
26757
|
+
updatedAt: String(row.updated_at)
|
|
26758
|
+
};
|
|
26759
|
+
}
|
|
26760
|
+
function observationHash(observation) {
|
|
26761
|
+
return createHash3("sha256").update(JSON.stringify({
|
|
26762
|
+
projectId: observation.projectId,
|
|
26763
|
+
id: observation.id,
|
|
26764
|
+
title: observation.title,
|
|
26765
|
+
narrative: observation.narrative,
|
|
26766
|
+
facts: observation.facts,
|
|
26767
|
+
files: observation.filesModified,
|
|
26768
|
+
relatedEntities: observation.relatedEntities
|
|
26769
|
+
})).digest("hex");
|
|
26770
|
+
}
|
|
26771
|
+
function sourceKind(observation) {
|
|
26772
|
+
if (observation.source === "git" || observation.sourceDetail === "git-ingest") return "git";
|
|
26773
|
+
if (observation.sourceDetail === "hook") return "hook";
|
|
26774
|
+
return observation.source ?? "agent";
|
|
26775
|
+
}
|
|
26776
|
+
function buildEvidenceCardId(projectId, candidateKind, candidateId) {
|
|
26777
|
+
return `evidence:${candidateKind}:${projectId}:${candidateId}`;
|
|
26778
|
+
}
|
|
26779
|
+
var EvidenceCardStore;
|
|
26780
|
+
var init_evidence_store = __esm({
|
|
26781
|
+
"src/store/evidence-store.ts"() {
|
|
26782
|
+
"use strict";
|
|
26783
|
+
init_esm_shims();
|
|
26784
|
+
init_sqlite_db();
|
|
26785
|
+
EvidenceCardStore = class {
|
|
26786
|
+
db = null;
|
|
26787
|
+
async init(dataDir) {
|
|
26788
|
+
this.db = getDatabase(dataDir);
|
|
26789
|
+
}
|
|
26790
|
+
requireDb() {
|
|
26791
|
+
if (!this.db) throw new Error("EvidenceCardStore is not initialized.");
|
|
26792
|
+
return this.db;
|
|
26793
|
+
}
|
|
26794
|
+
upsertObservation(observation) {
|
|
26795
|
+
const db2 = this.requireDb();
|
|
26796
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
26797
|
+
const card = {
|
|
26798
|
+
id: `evidence:observation:${observation.projectId}:${observation.id}`,
|
|
26799
|
+
projectId: observation.projectId,
|
|
26800
|
+
candidateKind: "observation",
|
|
26801
|
+
candidateId: String(observation.id),
|
|
26802
|
+
title: observation.title,
|
|
26803
|
+
summary: observation.narrative.slice(0, 500),
|
|
26804
|
+
entityName: observation.entityName,
|
|
26805
|
+
sourceKind: sourceKind(observation),
|
|
26806
|
+
sourceRef: `observation:${observation.id}`,
|
|
26807
|
+
locator: observation.filesModified?.join(", ") || `observation:${observation.id}`,
|
|
26808
|
+
capturedHash: observationHash(observation),
|
|
26809
|
+
...observation.sessionId ? { sessionId: observation.sessionId } : {},
|
|
26810
|
+
status: observation.status ?? "active",
|
|
26811
|
+
verification: observation.status === "resolved" ? "verified" : "unverified",
|
|
26812
|
+
freshness: "current",
|
|
26813
|
+
files: observation.filesModified ?? [],
|
|
26814
|
+
relatedEntities: observation.relatedEntities ?? [],
|
|
26815
|
+
createdAt: observation.createdAt,
|
|
26816
|
+
updatedAt: now3
|
|
26817
|
+
};
|
|
26818
|
+
db2.prepare(`
|
|
26819
|
+
INSERT INTO evidence_cards (
|
|
26820
|
+
id, project_id, candidate_kind, candidate_id, title, summary, entity_name,
|
|
26821
|
+
source_kind, source_ref, locator, captured_hash, session_id, status,
|
|
26822
|
+
verification, freshness, stale_reason, files_json, related_entities_json,
|
|
26823
|
+
created_at, updated_at
|
|
26824
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?, ?, ?, ?)
|
|
26825
|
+
ON CONFLICT(project_id, candidate_kind, candidate_id) DO UPDATE SET
|
|
26826
|
+
title = excluded.title,
|
|
26827
|
+
summary = excluded.summary,
|
|
26828
|
+
entity_name = excluded.entity_name,
|
|
26829
|
+
source_kind = excluded.source_kind,
|
|
26830
|
+
source_ref = excluded.source_ref,
|
|
26831
|
+
locator = excluded.locator,
|
|
26832
|
+
captured_hash = excluded.captured_hash,
|
|
26833
|
+
session_id = excluded.session_id,
|
|
26834
|
+
status = excluded.status,
|
|
26835
|
+
freshness = 'current',
|
|
26836
|
+
stale_reason = NULL,
|
|
26837
|
+
files_json = excluded.files_json,
|
|
26838
|
+
related_entities_json = excluded.related_entities_json,
|
|
26839
|
+
updated_at = excluded.updated_at
|
|
26840
|
+
`).run(
|
|
26841
|
+
card.id,
|
|
26842
|
+
card.projectId,
|
|
26843
|
+
card.candidateKind,
|
|
26844
|
+
card.candidateId,
|
|
26845
|
+
card.title,
|
|
26846
|
+
card.summary,
|
|
26847
|
+
card.entityName ?? null,
|
|
26848
|
+
card.sourceKind,
|
|
26849
|
+
card.sourceRef,
|
|
26850
|
+
card.locator ?? null,
|
|
26851
|
+
card.capturedHash ?? null,
|
|
26852
|
+
card.sessionId ?? null,
|
|
26853
|
+
card.status,
|
|
26854
|
+
card.verification,
|
|
26855
|
+
card.freshness,
|
|
26856
|
+
JSON.stringify(card.files),
|
|
26857
|
+
JSON.stringify(card.relatedEntities),
|
|
26858
|
+
card.createdAt,
|
|
26859
|
+
card.updatedAt
|
|
26860
|
+
);
|
|
26861
|
+
return this.get(card.projectId, card.candidateKind, card.candidateId) ?? card;
|
|
26862
|
+
}
|
|
26863
|
+
get(projectId, candidateKind, candidateId) {
|
|
26864
|
+
const row = this.requireDb().prepare(`
|
|
26865
|
+
SELECT * FROM evidence_cards WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
26866
|
+
`).get(projectId, candidateKind, candidateId);
|
|
26867
|
+
return row ? rowToCard(row) : void 0;
|
|
26868
|
+
}
|
|
26869
|
+
list(projectId, options = {}) {
|
|
26870
|
+
const limit2 = Math.min(100, Math.max(1, Math.floor(options.limit ?? 20)));
|
|
26871
|
+
const clauses = ["project_id = ?"];
|
|
26872
|
+
const args = [projectId];
|
|
26873
|
+
if (options.freshness) {
|
|
26874
|
+
clauses.push("freshness = ?");
|
|
26875
|
+
args.push(options.freshness);
|
|
26876
|
+
}
|
|
26877
|
+
if (options.status) {
|
|
26878
|
+
clauses.push("status = ?");
|
|
26879
|
+
args.push(options.status);
|
|
26880
|
+
}
|
|
26881
|
+
args.push(limit2);
|
|
26882
|
+
const rows = this.requireDb().prepare(`
|
|
26883
|
+
SELECT * FROM evidence_cards WHERE ${clauses.join(" AND ")} ORDER BY updated_at DESC, id DESC LIMIT ?
|
|
26884
|
+
`).all(...args);
|
|
26885
|
+
return rows.map(rowToCard);
|
|
26886
|
+
}
|
|
26887
|
+
syncObservations(observations2) {
|
|
26888
|
+
return observations2.map((observation) => this.upsertObservation(observation));
|
|
26889
|
+
}
|
|
26890
|
+
markStaleForPaths(projectId, paths, reason = "source file changed") {
|
|
26891
|
+
const normalized = new Set(paths.map((value) => value.replace(/\\/g, "/").toLowerCase()));
|
|
26892
|
+
if (normalized.size === 0) return 0;
|
|
26893
|
+
const db2 = this.requireDb();
|
|
26894
|
+
const rows = db2.prepare(`SELECT * FROM evidence_cards WHERE project_id = ? AND freshness != 'stale'`).all(projectId);
|
|
26895
|
+
const update2 = db2.prepare(`
|
|
26896
|
+
UPDATE evidence_cards SET freshness = 'stale', stale_reason = ?, updated_at = ?
|
|
26897
|
+
WHERE id = ?
|
|
26898
|
+
`);
|
|
26899
|
+
let changed = 0;
|
|
26900
|
+
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
26901
|
+
const run = db2.transaction(() => {
|
|
26902
|
+
for (const row of rows) {
|
|
26903
|
+
const files = safeJson(row.files_json, []);
|
|
26904
|
+
if (!files.some((file2) => normalized.has(file2.replace(/\\/g, "/").toLowerCase()))) continue;
|
|
26905
|
+
update2.run(reason, now3, row.id);
|
|
26906
|
+
changed++;
|
|
26907
|
+
}
|
|
26908
|
+
});
|
|
26909
|
+
run();
|
|
26910
|
+
return changed;
|
|
26911
|
+
}
|
|
26912
|
+
setVerification(projectId, cardId, verification) {
|
|
26913
|
+
this.requireDb().prepare(`
|
|
26914
|
+
UPDATE evidence_cards SET verification = ?, updated_at = ? WHERE project_id = ? AND id = ?
|
|
26915
|
+
`).run(verification, (/* @__PURE__ */ new Date()).toISOString(), projectId, cardId);
|
|
26916
|
+
}
|
|
26917
|
+
recordEvent(projectId, cardId, kind, detail) {
|
|
26918
|
+
const event = {
|
|
26919
|
+
id: randomUUID3(),
|
|
26920
|
+
projectId,
|
|
26921
|
+
cardId,
|
|
26922
|
+
kind,
|
|
26923
|
+
...detail ? { detail: detail.slice(0, 2e3) } : {},
|
|
26924
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
26925
|
+
};
|
|
26926
|
+
this.requireDb().prepare(`
|
|
26927
|
+
INSERT INTO evidence_card_events (id, project_id, card_id, kind, detail, created_at)
|
|
26928
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
26929
|
+
`).run(event.id, event.projectId, event.cardId, event.kind, event.detail ?? null, event.createdAt);
|
|
26930
|
+
return event;
|
|
26931
|
+
}
|
|
26932
|
+
listEvents(cardId, limit2 = 50) {
|
|
26933
|
+
const rows = this.requireDb().prepare(`
|
|
26934
|
+
SELECT * FROM evidence_card_events WHERE card_id = ? ORDER BY created_at DESC LIMIT ?
|
|
26935
|
+
`).all(cardId, Math.min(200, Math.max(1, Math.floor(limit2))));
|
|
26936
|
+
return rows.map((row) => ({
|
|
26937
|
+
id: String(row.id),
|
|
26938
|
+
projectId: String(row.project_id),
|
|
26939
|
+
cardId: String(row.card_id),
|
|
26940
|
+
kind: String(row.kind),
|
|
26941
|
+
...row.detail ? { detail: String(row.detail) } : {},
|
|
26942
|
+
createdAt: String(row.created_at)
|
|
26943
|
+
}));
|
|
26944
|
+
}
|
|
26945
|
+
};
|
|
26946
|
+
}
|
|
26947
|
+
});
|
|
26948
|
+
|
|
26337
26949
|
// src/runtime/isolated-maintenance.ts
|
|
26338
26950
|
import { spawn } from "child_process";
|
|
26339
26951
|
import { existsSync as existsSync10 } from "fs";
|
|
@@ -26495,7 +27107,7 @@ var workspace_store_exports = {};
|
|
|
26495
27107
|
__export(workspace_store_exports, {
|
|
26496
27108
|
KnowledgeWorkspaceStore: () => KnowledgeWorkspaceStore
|
|
26497
27109
|
});
|
|
26498
|
-
import { randomUUID as
|
|
27110
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
26499
27111
|
function arrayValue(raw) {
|
|
26500
27112
|
if (typeof raw !== "string" || !raw) return [];
|
|
26501
27113
|
try {
|
|
@@ -26636,7 +27248,7 @@ var init_workspace_store = __esm({
|
|
|
26636
27248
|
}
|
|
26637
27249
|
createProposal(input) {
|
|
26638
27250
|
const proposal = {
|
|
26639
|
-
id: input.id ??
|
|
27251
|
+
id: input.id ?? randomUUID4(),
|
|
26640
27252
|
...input,
|
|
26641
27253
|
status: input.status ?? "pending",
|
|
26642
27254
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -26689,13 +27301,13 @@ __export(workspace_exports, {
|
|
|
26689
27301
|
loadKnowledgeWorkspace: () => loadKnowledgeWorkspace,
|
|
26690
27302
|
resolveKnowledgeWorkspaceFile: () => resolveKnowledgeWorkspaceFile
|
|
26691
27303
|
});
|
|
26692
|
-
import { createHash as
|
|
27304
|
+
import { createHash as createHash4 } from "crypto";
|
|
26693
27305
|
import { execFile } from "child_process";
|
|
26694
27306
|
import { promises as fs8 } from "fs";
|
|
26695
27307
|
import path12 from "path";
|
|
26696
27308
|
import { promisify } from "util";
|
|
26697
27309
|
function hash(value) {
|
|
26698
|
-
return
|
|
27310
|
+
return createHash4("sha256").update(value).digest("hex");
|
|
26699
27311
|
}
|
|
26700
27312
|
function workspaceId(projectId, mode) {
|
|
26701
27313
|
return "workspace:" + hash(projectId + ":" + mode).slice(0, 24);
|
|
@@ -27295,7 +27907,7 @@ var media_store_exports = {};
|
|
|
27295
27907
|
__export(media_store_exports, {
|
|
27296
27908
|
MediaStore: () => MediaStore
|
|
27297
27909
|
});
|
|
27298
|
-
import { randomUUID as
|
|
27910
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
27299
27911
|
function asOptionalText(value) {
|
|
27300
27912
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
27301
27913
|
}
|
|
@@ -27465,7 +28077,7 @@ var init_media_store = __esm({
|
|
|
27465
28077
|
return { asset: this.getAsset(input.projectId, existing.id), deduplicated: true };
|
|
27466
28078
|
}
|
|
27467
28079
|
const asset = {
|
|
27468
|
-
id:
|
|
28080
|
+
id: randomUUID5(),
|
|
27469
28081
|
...input,
|
|
27470
28082
|
createdAt: now3,
|
|
27471
28083
|
updatedAt: now3
|
|
@@ -27545,7 +28157,7 @@ var init_media_store = __esm({
|
|
|
27545
28157
|
`).get(input.assetId, input.observationId ?? null, input.role);
|
|
27546
28158
|
if (existing) return rowToLink(existing);
|
|
27547
28159
|
const link = {
|
|
27548
|
-
id:
|
|
28160
|
+
id: randomUUID5(),
|
|
27549
28161
|
assetId: input.assetId,
|
|
27550
28162
|
projectId: input.projectId,
|
|
27551
28163
|
...input.observationId !== void 0 ? { observationId: input.observationId } : {},
|
|
@@ -27584,7 +28196,7 @@ var init_media_store = __esm({
|
|
|
27584
28196
|
return rowToDerivation(this.db.prepare("SELECT * FROM media_derivations WHERE id = ?").get(existing.id));
|
|
27585
28197
|
}
|
|
27586
28198
|
const derivation = {
|
|
27587
|
-
id:
|
|
28199
|
+
id: randomUUID5(),
|
|
27588
28200
|
...input,
|
|
27589
28201
|
content,
|
|
27590
28202
|
...error40 ? { error: error40 } : {},
|
|
@@ -27671,7 +28283,7 @@ var init_media_store = __esm({
|
|
|
27671
28283
|
createJob(input) {
|
|
27672
28284
|
const now3 = Date.now();
|
|
27673
28285
|
const job = {
|
|
27674
|
-
id:
|
|
28286
|
+
id: randomUUID5(),
|
|
27675
28287
|
projectId: input.projectId,
|
|
27676
28288
|
kind: input.kind,
|
|
27677
28289
|
status: "queued",
|
|
@@ -27847,14 +28459,14 @@ __export(asset_store_exports, {
|
|
|
27847
28459
|
readMediaAsset: () => readMediaAsset,
|
|
27848
28460
|
removeMediaAsset: () => removeMediaAsset
|
|
27849
28461
|
});
|
|
27850
|
-
import { createHash as
|
|
28462
|
+
import { createHash as createHash5, randomUUID as randomUUID6 } from "crypto";
|
|
27851
28463
|
import { copyFile, lstat, mkdir as mkdir3, open, readFile as readFile3, readdir, rename as rename2, rm, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
27852
28464
|
import path13 from "path";
|
|
27853
28465
|
function mediaRoot(dataDir) {
|
|
27854
28466
|
return path13.resolve(dataDir, "media");
|
|
27855
28467
|
}
|
|
27856
28468
|
function projectStorageKey(projectId) {
|
|
27857
|
-
return
|
|
28469
|
+
return createHash5("sha256").update(projectId).digest("hex").slice(0, 16);
|
|
27858
28470
|
}
|
|
27859
28471
|
function validateUnderRoot(root, candidate2) {
|
|
27860
28472
|
const resolved = path13.resolve(candidate2);
|
|
@@ -27914,14 +28526,14 @@ async function readHeader(filePath, bytes = 32) {
|
|
|
27914
28526
|
}
|
|
27915
28527
|
async function sha256File(filePath) {
|
|
27916
28528
|
const bytes = await readFile3(filePath);
|
|
27917
|
-
return
|
|
28529
|
+
return createHash5("sha256").update(bytes).digest("hex");
|
|
27918
28530
|
}
|
|
27919
28531
|
function destinationFor(root, projectId, sha2562, extension3) {
|
|
27920
28532
|
const relative3 = path13.join("assets", projectStorageKey(projectId), sha2562.slice(0, 2), `${sha2562}${extension3}`);
|
|
27921
28533
|
return { relative: relative3, absolute: validateUnderRoot(root, path13.join(root, relative3)) };
|
|
27922
28534
|
}
|
|
27923
28535
|
function deletionStagingPath(root, assetId) {
|
|
27924
|
-
return validateUnderRoot(root, path13.join(root, ".trash", `${assetId}.${
|
|
28536
|
+
return validateUnderRoot(root, path13.join(root, ".trash", `${assetId}.${randomUUID6()}.pending-delete`));
|
|
27925
28537
|
}
|
|
27926
28538
|
async function destinationExists(destination) {
|
|
27927
28539
|
try {
|
|
@@ -27935,7 +28547,7 @@ async function destinationExists(destination) {
|
|
|
27935
28547
|
async function persistFile(source, destination) {
|
|
27936
28548
|
await mkdir3(path13.dirname(destination), { recursive: true });
|
|
27937
28549
|
if (await destinationExists(destination)) return false;
|
|
27938
|
-
const temporary = `${destination}.${
|
|
28550
|
+
const temporary = `${destination}.${randomUUID6()}.tmp`;
|
|
27939
28551
|
try {
|
|
27940
28552
|
await copyFile(source, temporary);
|
|
27941
28553
|
await rename2(temporary, destination);
|
|
@@ -27951,7 +28563,7 @@ async function persistFile(source, destination) {
|
|
|
27951
28563
|
async function persistBuffer(bytes, destination) {
|
|
27952
28564
|
await mkdir3(path13.dirname(destination), { recursive: true });
|
|
27953
28565
|
if (await destinationExists(destination)) return false;
|
|
27954
|
-
const temporary = `${destination}.${
|
|
28566
|
+
const temporary = `${destination}.${randomUUID6()}.tmp`;
|
|
27955
28567
|
try {
|
|
27956
28568
|
await writeFile3(temporary, bytes, { flag: "wx" });
|
|
27957
28569
|
await rename2(temporary, destination);
|
|
@@ -28020,7 +28632,7 @@ async function importMediaBuffer(input) {
|
|
|
28020
28632
|
if (input.bytes.length === 0) throw new Error("Media import rejects empty payloads");
|
|
28021
28633
|
if (input.bytes.length > maxBytes) throw new Error(`Media payload is too large (${input.bytes.length} bytes; limit ${maxBytes})`);
|
|
28022
28634
|
const detected = detectMedia(input.bytes.subarray(0, 32));
|
|
28023
|
-
const sha2562 =
|
|
28635
|
+
const sha2562 = createHash5("sha256").update(input.bytes).digest("hex");
|
|
28024
28636
|
return importKnownMedia({
|
|
28025
28637
|
dataDir: input.dataDir,
|
|
28026
28638
|
projectId: input.projectId,
|
|
@@ -28038,7 +28650,7 @@ async function readMediaAsset(dataDir, asset, maxBytes = DEFAULT_MAX_MEDIA_BYTES
|
|
|
28038
28650
|
if (asset.byteSize > maxBytes) throw new Error(`Media asset exceeds read limit (${asset.byteSize} bytes; limit ${maxBytes})`);
|
|
28039
28651
|
const bytes = await readFile3(getMediaAssetPath(dataDir, asset));
|
|
28040
28652
|
if (bytes.length !== asset.byteSize) throw new Error(`Media asset size no longer matches metadata: ${asset.id}`);
|
|
28041
|
-
const sha2562 =
|
|
28653
|
+
const sha2562 = createHash5("sha256").update(bytes).digest("hex");
|
|
28042
28654
|
if (sha2562 !== asset.sha256) throw new Error(`Media asset hash no longer matches metadata: ${asset.id}`);
|
|
28043
28655
|
return bytes;
|
|
28044
28656
|
}
|
|
@@ -80908,7 +81520,7 @@ var require_gaxios = __commonJS({
|
|
|
80908
81520
|
var retry_js_1 = require_retry3();
|
|
80909
81521
|
var stream_1 = __require("stream");
|
|
80910
81522
|
var interceptor_js_1 = require_interceptor();
|
|
80911
|
-
var
|
|
81523
|
+
var randomUUID20 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
80912
81524
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
80913
81525
|
var Gaxios = class {
|
|
80914
81526
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -81181,7 +81793,7 @@ var require_gaxios = __commonJS({
|
|
|
81181
81793
|
*/
|
|
81182
81794
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
81183
81795
|
if (opts.multipart?.length) {
|
|
81184
|
-
const boundary = await
|
|
81796
|
+
const boundary = await randomUUID20();
|
|
81185
81797
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
81186
81798
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
81187
81799
|
} else if (shouldDirectlyPassData) {
|
|
@@ -93408,7 +94020,7 @@ var require_websocket = __commonJS({
|
|
|
93408
94020
|
var http3 = __require("http");
|
|
93409
94021
|
var net = __require("net");
|
|
93410
94022
|
var tls = __require("tls");
|
|
93411
|
-
var { randomBytes: randomBytes3, createHash:
|
|
94023
|
+
var { randomBytes: randomBytes3, createHash: createHash22 } = __require("crypto");
|
|
93412
94024
|
var { Duplex, Readable: Readable3 } = __require("stream");
|
|
93413
94025
|
var { URL: URL2 } = __require("url");
|
|
93414
94026
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
@@ -94076,7 +94688,7 @@ var require_websocket = __commonJS({
|
|
|
94076
94688
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
94077
94689
|
return;
|
|
94078
94690
|
}
|
|
94079
|
-
const digest2 =
|
|
94691
|
+
const digest2 = createHash22("sha1").update(key + GUID).digest("base64");
|
|
94080
94692
|
if (res.headers["sec-websocket-accept"] !== digest2) {
|
|
94081
94693
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
94082
94694
|
return;
|
|
@@ -94448,7 +95060,7 @@ var require_websocket_server = __commonJS({
|
|
|
94448
95060
|
var EventEmitter2 = __require("events");
|
|
94449
95061
|
var http3 = __require("http");
|
|
94450
95062
|
var { Duplex } = __require("stream");
|
|
94451
|
-
var { createHash:
|
|
95063
|
+
var { createHash: createHash22 } = __require("crypto");
|
|
94452
95064
|
var extension3 = require_extension();
|
|
94453
95065
|
var PerMessageDeflate2 = require_permessage_deflate();
|
|
94454
95066
|
var subprotocol2 = require_subprotocol();
|
|
@@ -94755,7 +95367,7 @@ var require_websocket_server = __commonJS({
|
|
|
94755
95367
|
);
|
|
94756
95368
|
}
|
|
94757
95369
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
94758
|
-
const digest2 =
|
|
95370
|
+
const digest2 = createHash22("sha1").update(key + GUID).digest("base64");
|
|
94759
95371
|
const headers = [
|
|
94760
95372
|
"HTTP/1.1 101 Switching Protocols",
|
|
94761
95373
|
"Upgrade: websocket",
|
|
@@ -168158,8 +168770,8 @@ var init_session_resources = __esm({
|
|
|
168158
168770
|
});
|
|
168159
168771
|
|
|
168160
168772
|
// packages/ai/dist/utils/abort-signals.js
|
|
168161
|
-
function combineAbortSignals(
|
|
168162
|
-
const activeSignals =
|
|
168773
|
+
function combineAbortSignals(signals2) {
|
|
168774
|
+
const activeSignals = signals2.filter((signal) => signal !== void 0);
|
|
168163
168775
|
if (activeSignals.length === 0) {
|
|
168164
168776
|
return { cleanup: () => {
|
|
168165
168777
|
} };
|
|
@@ -177872,6 +178484,186 @@ var init_audio_jobs = __esm({
|
|
|
177872
178484
|
}
|
|
177873
178485
|
});
|
|
177874
178486
|
|
|
178487
|
+
// src/memory/feedback-model.ts
|
|
178488
|
+
function feedbackWeightMultiplier(weight) {
|
|
178489
|
+
return Math.max(0.35, Math.min(1.4, 0.35 + Math.max(0, Math.min(2, weight)) * 0.525));
|
|
178490
|
+
}
|
|
178491
|
+
var init_feedback_model = __esm({
|
|
178492
|
+
"src/memory/feedback-model.ts"() {
|
|
178493
|
+
"use strict";
|
|
178494
|
+
init_esm_shims();
|
|
178495
|
+
}
|
|
178496
|
+
});
|
|
178497
|
+
|
|
178498
|
+
// src/memory/feedback.ts
|
|
178499
|
+
var feedback_exports = {};
|
|
178500
|
+
__export(feedback_exports, {
|
|
178501
|
+
FEEDBACK_DELTAS: () => FEEDBACK_DELTAS,
|
|
178502
|
+
MemoryFeedbackStore: () => MemoryFeedbackStore,
|
|
178503
|
+
applyMemoryFeedback: () => applyMemoryFeedback,
|
|
178504
|
+
feedbackWeightMultiplier: () => feedbackWeightMultiplier
|
|
178505
|
+
});
|
|
178506
|
+
import { randomUUID as randomUUID7 } from "crypto";
|
|
178507
|
+
function applyMemoryFeedback(current, event) {
|
|
178508
|
+
const delta = event.signal === "revoke" ? 0 : FEEDBACK_DELTAS[event.signal];
|
|
178509
|
+
const weight = Math.max(0, Math.min(2, current.weight + delta));
|
|
178510
|
+
const status = (event.signal === "code-conflict" || event.signal === "user-correction" || event.signal === "weaken") && weight < 0.5 ? "archived" : current.status;
|
|
178511
|
+
return { weight, status, audit: [...current.audit, { ...event }] };
|
|
178512
|
+
}
|
|
178513
|
+
function rowToEvent(row) {
|
|
178514
|
+
return {
|
|
178515
|
+
id: String(row.id),
|
|
178516
|
+
projectId: String(row.project_id),
|
|
178517
|
+
candidateKind: row.candidate_kind,
|
|
178518
|
+
candidateId: String(row.candidate_id),
|
|
178519
|
+
signal: row.signal,
|
|
178520
|
+
...row.observed_at ? { at: String(row.observed_at) } : { at: (/* @__PURE__ */ new Date()).toISOString() },
|
|
178521
|
+
...row.actor ? { actor: String(row.actor) } : {},
|
|
178522
|
+
...row.note ? { note: String(row.note) } : {},
|
|
178523
|
+
...row.source_ref ? { sourceRef: String(row.source_ref) } : {},
|
|
178524
|
+
...row.target_event_id ? { targetEventId: String(row.target_event_id) } : {},
|
|
178525
|
+
delta: Number(row.delta ?? 0)
|
|
178526
|
+
};
|
|
178527
|
+
}
|
|
178528
|
+
var FEEDBACK_DELTAS, MemoryFeedbackStore;
|
|
178529
|
+
var init_feedback = __esm({
|
|
178530
|
+
"src/memory/feedback.ts"() {
|
|
178531
|
+
"use strict";
|
|
178532
|
+
init_esm_shims();
|
|
178533
|
+
init_sqlite_db();
|
|
178534
|
+
init_feedback_model();
|
|
178535
|
+
FEEDBACK_DELTAS = {
|
|
178536
|
+
"user-correction": -0.35,
|
|
178537
|
+
"verification-success": 0.25,
|
|
178538
|
+
"verification-failure": -0.25,
|
|
178539
|
+
"code-change": -0.15,
|
|
178540
|
+
used: 0.1,
|
|
178541
|
+
"not-used": -0.05,
|
|
178542
|
+
"code-conflict": -0.4,
|
|
178543
|
+
strengthen: 0.2,
|
|
178544
|
+
weaken: -0.2
|
|
178545
|
+
};
|
|
178546
|
+
MemoryFeedbackStore = class {
|
|
178547
|
+
db = null;
|
|
178548
|
+
async init(dataDir) {
|
|
178549
|
+
this.db = getDatabase(dataDir);
|
|
178550
|
+
}
|
|
178551
|
+
requireDb() {
|
|
178552
|
+
if (!this.db) throw new Error("MemoryFeedbackStore is not initialized.");
|
|
178553
|
+
return this.db;
|
|
178554
|
+
}
|
|
178555
|
+
loadEvents(projectId, candidateKind, candidateId) {
|
|
178556
|
+
return this.requireDb().prepare(`
|
|
178557
|
+
SELECT * FROM memory_feedback_events
|
|
178558
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
178559
|
+
ORDER BY observed_at ASC, rowid ASC
|
|
178560
|
+
`).all(projectId, candidateKind, candidateId).map(rowToEvent);
|
|
178561
|
+
}
|
|
178562
|
+
rebuild(projectId, candidateKind, candidateId) {
|
|
178563
|
+
const events = this.loadEvents(projectId, candidateKind, candidateId);
|
|
178564
|
+
const revoked = new Set(events.filter((event) => event.signal === "revoke" && event.targetEventId).map((event) => event.targetEventId));
|
|
178565
|
+
let state = { weight: 1, status: "active", audit: [] };
|
|
178566
|
+
for (const event of events) {
|
|
178567
|
+
if (event.signal === "revoke" || revoked.has(event.id)) {
|
|
178568
|
+
state.audit.push(event);
|
|
178569
|
+
continue;
|
|
178570
|
+
}
|
|
178571
|
+
state = applyMemoryFeedback(state, event);
|
|
178572
|
+
}
|
|
178573
|
+
this.requireDb().prepare(`
|
|
178574
|
+
INSERT INTO memory_feedback_states (project_id, candidate_kind, candidate_id, weight, lifecycle_status, updated_at)
|
|
178575
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
178576
|
+
ON CONFLICT(project_id, candidate_kind, candidate_id) DO UPDATE SET
|
|
178577
|
+
weight = excluded.weight, lifecycle_status = excluded.lifecycle_status, updated_at = excluded.updated_at
|
|
178578
|
+
`).run(projectId, candidateKind, candidateId, state.weight, state.status, (/* @__PURE__ */ new Date()).toISOString());
|
|
178579
|
+
return state;
|
|
178580
|
+
}
|
|
178581
|
+
getState(projectId, candidateKind, candidateId) {
|
|
178582
|
+
const row = this.requireDb().prepare(`
|
|
178583
|
+
SELECT weight, lifecycle_status FROM memory_feedback_states
|
|
178584
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
178585
|
+
`).get(projectId, candidateKind, candidateId);
|
|
178586
|
+
if (!row) return { weight: 1, status: "active", audit: [] };
|
|
178587
|
+
return {
|
|
178588
|
+
weight: Number(row.weight ?? 1),
|
|
178589
|
+
status: row.lifecycle_status ?? "active",
|
|
178590
|
+
audit: this.loadEvents(projectId, candidateKind, candidateId)
|
|
178591
|
+
};
|
|
178592
|
+
}
|
|
178593
|
+
listStates(projectId, candidateKind = "observation") {
|
|
178594
|
+
return this.requireDb().prepare(`
|
|
178595
|
+
SELECT candidate_id, weight, lifecycle_status, updated_at
|
|
178596
|
+
FROM memory_feedback_states WHERE project_id = ? AND candidate_kind = ?
|
|
178597
|
+
ORDER BY updated_at DESC
|
|
178598
|
+
`).all(projectId, candidateKind).map((row) => ({
|
|
178599
|
+
candidateId: String(row.candidate_id),
|
|
178600
|
+
weight: Number(row.weight),
|
|
178601
|
+
status: row.lifecycle_status,
|
|
178602
|
+
updatedAt: String(row.updated_at)
|
|
178603
|
+
}));
|
|
178604
|
+
}
|
|
178605
|
+
weights(projectId, candidateKind = "observation") {
|
|
178606
|
+
const states = /* @__PURE__ */ new Map();
|
|
178607
|
+
for (const row of this.listStates(projectId, candidateKind)) {
|
|
178608
|
+
states.set(row.candidateId, this.getState(projectId, candidateKind, row.candidateId));
|
|
178609
|
+
}
|
|
178610
|
+
return states;
|
|
178611
|
+
}
|
|
178612
|
+
record(input) {
|
|
178613
|
+
if (input.signal === "revoke" && !input.targetEventId) {
|
|
178614
|
+
throw new Error("A revoke feedback event requires targetEventId.");
|
|
178615
|
+
}
|
|
178616
|
+
if (input.signal === "revoke") {
|
|
178617
|
+
const target = this.requireDb().prepare(`
|
|
178618
|
+
SELECT 1 FROM memory_feedback_events
|
|
178619
|
+
WHERE id = ? AND project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
178620
|
+
`).get(input.targetEventId, input.projectId, input.candidateKind, input.candidateId);
|
|
178621
|
+
if (!target) throw new Error("The feedback event to revoke was not found in the same candidate scope.");
|
|
178622
|
+
}
|
|
178623
|
+
const event = {
|
|
178624
|
+
id: randomUUID7(),
|
|
178625
|
+
projectId: input.projectId,
|
|
178626
|
+
candidateKind: input.candidateKind,
|
|
178627
|
+
candidateId: input.candidateId,
|
|
178628
|
+
signal: input.signal,
|
|
178629
|
+
sourceRef: input.sourceRef,
|
|
178630
|
+
...input.actor ? { actor: input.actor } : {},
|
|
178631
|
+
...input.note ? { note: input.note.slice(0, 2e3) } : {},
|
|
178632
|
+
...input.targetEventId ? { targetEventId: input.targetEventId } : {},
|
|
178633
|
+
at: input.at ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
178634
|
+
delta: input.signal === "revoke" ? 0 : FEEDBACK_DELTAS[input.signal]
|
|
178635
|
+
};
|
|
178636
|
+
this.requireDb().prepare(`
|
|
178637
|
+
INSERT INTO memory_feedback_events (
|
|
178638
|
+
id, project_id, candidate_kind, candidate_id, signal, actor, note,
|
|
178639
|
+
source_ref, target_event_id, delta, observed_at
|
|
178640
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
178641
|
+
`).run(
|
|
178642
|
+
event.id,
|
|
178643
|
+
event.projectId,
|
|
178644
|
+
event.candidateKind,
|
|
178645
|
+
event.candidateId,
|
|
178646
|
+
event.signal,
|
|
178647
|
+
event.actor ?? null,
|
|
178648
|
+
event.note ?? null,
|
|
178649
|
+
event.sourceRef,
|
|
178650
|
+
event.targetEventId ?? null,
|
|
178651
|
+
event.delta,
|
|
178652
|
+
event.at
|
|
178653
|
+
);
|
|
178654
|
+
return { event, state: this.rebuild(input.projectId, input.candidateKind, input.candidateId) };
|
|
178655
|
+
}
|
|
178656
|
+
audit(projectId, candidateKind, candidateId, limit2 = 100) {
|
|
178657
|
+
return this.requireDb().prepare(`
|
|
178658
|
+
SELECT * FROM memory_feedback_events
|
|
178659
|
+
WHERE project_id = ? AND candidate_kind = ? AND candidate_id = ?
|
|
178660
|
+
ORDER BY observed_at DESC, rowid DESC LIMIT ?
|
|
178661
|
+
`).all(projectId, candidateKind, candidateId, Math.min(200, Math.max(1, Math.floor(limit2)))).map(rowToEvent);
|
|
178662
|
+
}
|
|
178663
|
+
};
|
|
178664
|
+
}
|
|
178665
|
+
});
|
|
178666
|
+
|
|
177875
178667
|
// src/memory/retention.ts
|
|
177876
178668
|
var retention_exports = {};
|
|
177877
178669
|
__export(retention_exports, {
|
|
@@ -177913,6 +178705,7 @@ function getEffectiveRetentionDays(doc) {
|
|
|
177913
178705
|
}
|
|
177914
178706
|
function isImmune(doc) {
|
|
177915
178707
|
if (doc.type === "probe") return false;
|
|
178708
|
+
if (doc.feedbackStatus === "archived") return false;
|
|
177916
178709
|
if (doc.admissionState === "candidate" || doc.admissionState === "ephemeral") return false;
|
|
177917
178710
|
if (doc.valueCategory === "core") return true;
|
|
177918
178711
|
const importance = getImportanceLevel(doc);
|
|
@@ -177945,7 +178738,8 @@ function calculateRelevance(doc, referenceTime) {
|
|
|
177945
178738
|
const decayFactor = Math.exp(-ageDays / retention);
|
|
177946
178739
|
const accessCount = doc.accessCount ?? 0;
|
|
177947
178740
|
const accessBoost = Math.min(2, 1 + 0.1 * accessCount);
|
|
177948
|
-
|
|
178741
|
+
const feedbackMultiplier = doc.feedbackWeight === void 0 ? 1 : feedbackWeightMultiplier(doc.feedbackWeight);
|
|
178742
|
+
let totalScore = base * decayFactor * accessBoost * feedbackMultiplier;
|
|
177949
178743
|
const immune = isImmune(doc);
|
|
177950
178744
|
if (immune) {
|
|
177951
178745
|
totalScore = Math.max(totalScore, 0.5);
|
|
@@ -177957,7 +178751,8 @@ function calculateRelevance(doc, referenceTime) {
|
|
|
177957
178751
|
decayFactor,
|
|
177958
178752
|
accessBoost,
|
|
177959
178753
|
ageDays,
|
|
177960
|
-
isImmune: immune
|
|
178754
|
+
isImmune: immune,
|
|
178755
|
+
feedbackMultiplier
|
|
177961
178756
|
};
|
|
177962
178757
|
}
|
|
177963
178758
|
function rankByRelevance(docs, referenceTime) {
|
|
@@ -177965,6 +178760,7 @@ function rankByRelevance(docs, referenceTime) {
|
|
|
177965
178760
|
}
|
|
177966
178761
|
function getRetentionZone(doc, referenceTime) {
|
|
177967
178762
|
const now3 = referenceTime ?? /* @__PURE__ */ new Date();
|
|
178763
|
+
if (doc.feedbackStatus === "archived") return "archive-candidate";
|
|
177968
178764
|
const importance = getImportanceLevel(doc);
|
|
177969
178765
|
const retention = getEffectiveRetentionDays(doc);
|
|
177970
178766
|
const createdAt = new Date(doc.createdAt);
|
|
@@ -178036,7 +178832,7 @@ function explainRetention(doc, referenceTime) {
|
|
|
178036
178832
|
summary: parts.join(" ; ")
|
|
178037
178833
|
};
|
|
178038
178834
|
}
|
|
178039
|
-
function toRetentionDocument(obs, accessMap) {
|
|
178835
|
+
function toRetentionDocument(obs, accessMap, feedback) {
|
|
178040
178836
|
const access4 = accessMap?.get(obs.id);
|
|
178041
178837
|
return {
|
|
178042
178838
|
id: `obs-${obs.id}`,
|
|
@@ -178058,11 +178854,12 @@ function toRetentionDocument(obs, accessMap) {
|
|
|
178058
178854
|
sourceDetail: obs.sourceDetail ?? "",
|
|
178059
178855
|
valueCategory: obs.valueCategory ?? "",
|
|
178060
178856
|
admissionState: obs.admissionState ?? "",
|
|
178061
|
-
admissionReason: obs.admissionReason ?? ""
|
|
178857
|
+
admissionReason: obs.admissionReason ?? "",
|
|
178858
|
+
...feedback ? { feedbackWeight: feedback.weight, feedbackStatus: feedback.status } : {}
|
|
178062
178859
|
};
|
|
178063
178860
|
}
|
|
178064
178861
|
function projectObservationRetention(observation, options = {}) {
|
|
178065
|
-
const document2 = toRetentionDocument(observation, options.accessMap);
|
|
178862
|
+
const document2 = toRetentionDocument(observation, options.accessMap, options.feedback);
|
|
178066
178863
|
const relevance = calculateRelevance(document2, options.referenceTime);
|
|
178067
178864
|
const explanation = explainRetention(document2, options.referenceTime);
|
|
178068
178865
|
return {
|
|
@@ -178087,7 +178884,17 @@ function summarizeRetentionProjections(projections) {
|
|
|
178087
178884
|
}
|
|
178088
178885
|
return { active, stale, archiveCandidates, immune };
|
|
178089
178886
|
}
|
|
178090
|
-
async function
|
|
178887
|
+
async function loadFeedbackStore(dataDir) {
|
|
178888
|
+
try {
|
|
178889
|
+
const { MemoryFeedbackStore: MemoryFeedbackStore2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
178890
|
+
const store2 = new MemoryFeedbackStore2();
|
|
178891
|
+
await store2.init(dataDir);
|
|
178892
|
+
return store2;
|
|
178893
|
+
} catch {
|
|
178894
|
+
return void 0;
|
|
178895
|
+
}
|
|
178896
|
+
}
|
|
178897
|
+
async function archiveExpiredBatch(projectDir2, options) {
|
|
178091
178898
|
const store2 = getObservationStore();
|
|
178092
178899
|
const limit2 = Math.min(500, Math.max(1, Math.floor(options.limit ?? 100)));
|
|
178093
178900
|
const afterId = Math.max(0, Math.floor(options.afterId ?? 0));
|
|
@@ -178096,11 +178903,13 @@ async function archiveExpiredBatch(_projectDir, options) {
|
|
|
178096
178903
|
afterId,
|
|
178097
178904
|
limit: limit2 + 1
|
|
178098
178905
|
});
|
|
178906
|
+
const feedback = await loadFeedbackStore(projectDir2);
|
|
178099
178907
|
const hasMore = page.length > limit2;
|
|
178100
178908
|
const scanned = hasMore ? page.slice(0, limit2) : page;
|
|
178101
178909
|
const candidateIds = scanned.filter((observation) => !options.reader || canManageObservation(observation, options.reader)).filter((observation) => projectObservationRetention(observation, {
|
|
178102
178910
|
accessMap: options.accessMap,
|
|
178103
|
-
referenceTime: options.referenceTime
|
|
178911
|
+
referenceTime: options.referenceTime,
|
|
178912
|
+
...feedback ? { feedback: feedback.getState(options.projectId, "observation", String(observation.id)) } : {}
|
|
178104
178913
|
}).zone === "archive-candidate").map((observation) => observation.id);
|
|
178105
178914
|
const archived = candidateIds.length === 0 ? 0 : await store2.atomic(async (tx) => {
|
|
178106
178915
|
const updates = await Promise.all(
|
|
@@ -178131,6 +178940,7 @@ async function archiveExpired(projectDir2, referenceTime, accessMap, projectId,
|
|
|
178131
178940
|
const remaining = reader2 ? remainingObservations.filter((observation) => canManageObservation(observation, reader2)).length : remainingObservations.length;
|
|
178132
178941
|
return { archived, remaining };
|
|
178133
178942
|
}
|
|
178943
|
+
const feedback = await loadFeedbackStore(projectDir2);
|
|
178134
178944
|
return await store2.atomic(async (tx) => {
|
|
178135
178945
|
const allObs = await tx.loadAll();
|
|
178136
178946
|
const activeObs = allObs.filter(
|
|
@@ -178138,7 +178948,11 @@ async function archiveExpired(projectDir2, referenceTime, accessMap, projectId,
|
|
|
178138
178948
|
);
|
|
178139
178949
|
const archivedIds = [];
|
|
178140
178950
|
for (const obs of activeObs) {
|
|
178141
|
-
const retention = projectObservationRetention(obs, {
|
|
178951
|
+
const retention = projectObservationRetention(obs, {
|
|
178952
|
+
accessMap,
|
|
178953
|
+
referenceTime,
|
|
178954
|
+
...feedback ? { feedback: feedback.getState(obs.projectId, "observation", String(obs.id)) } : {}
|
|
178955
|
+
});
|
|
178142
178956
|
if (retention.zone === "archive-candidate") {
|
|
178143
178957
|
archivedIds.push(obs.id);
|
|
178144
178958
|
}
|
|
@@ -178158,6 +178972,7 @@ var init_retention = __esm({
|
|
|
178158
178972
|
init_esm_shims();
|
|
178159
178973
|
init_obs_store();
|
|
178160
178974
|
init_visibility();
|
|
178975
|
+
init_feedback_model();
|
|
178161
178976
|
RETENTION_DAYS = {
|
|
178162
178977
|
critical: 365,
|
|
178163
178978
|
high: 180,
|
|
@@ -178198,7 +179013,7 @@ var owner_exports = {};
|
|
|
178198
179013
|
__export(owner_exports, {
|
|
178199
179014
|
resolveLocalMemoryOwner: () => resolveLocalMemoryOwner
|
|
178200
179015
|
});
|
|
178201
|
-
import { randomUUID as
|
|
179016
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
178202
179017
|
import { promises as fs11 } from "fs";
|
|
178203
179018
|
import path19 from "path";
|
|
178204
179019
|
function ownerPath(dataDir) {
|
|
@@ -178228,7 +179043,7 @@ async function resolveLocalMemoryOwner(dataDir, options = {}) {
|
|
|
178228
179043
|
await fs11.mkdir(path19.dirname(filePath), { recursive: true });
|
|
178229
179044
|
const created = {
|
|
178230
179045
|
version: 1,
|
|
178231
|
-
id: "local-" +
|
|
179046
|
+
id: "local-" + randomUUID8(),
|
|
178232
179047
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
178233
179048
|
};
|
|
178234
179049
|
try {
|
|
@@ -178255,7 +179070,7 @@ var long_term_store_exports = {};
|
|
|
178255
179070
|
__export(long_term_store_exports, {
|
|
178256
179071
|
LongTermMemoryStore: () => LongTermMemoryStore
|
|
178257
179072
|
});
|
|
178258
|
-
import { randomUUID as
|
|
179073
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
178259
179074
|
function optionalText2(value) {
|
|
178260
179075
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
178261
179076
|
}
|
|
@@ -178306,7 +179121,7 @@ function rowToEvidence(row) {
|
|
|
178306
179121
|
createdAt: row.createdAt
|
|
178307
179122
|
};
|
|
178308
179123
|
}
|
|
178309
|
-
function
|
|
179124
|
+
function rowToEvent2(row) {
|
|
178310
179125
|
return {
|
|
178311
179126
|
id: row.id,
|
|
178312
179127
|
memoryId: row.memoryId,
|
|
@@ -178415,7 +179230,7 @@ var init_long_term_store = __esm({
|
|
|
178415
179230
|
}
|
|
178416
179231
|
insertEvidence(input) {
|
|
178417
179232
|
const evidence = {
|
|
178418
|
-
id:
|
|
179233
|
+
id: randomUUID9(),
|
|
178419
179234
|
...input,
|
|
178420
179235
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
178421
179236
|
};
|
|
@@ -178442,7 +179257,7 @@ var init_long_term_store = __esm({
|
|
|
178442
179257
|
}
|
|
178443
179258
|
recordEvent(input) {
|
|
178444
179259
|
const event = {
|
|
178445
|
-
id:
|
|
179260
|
+
id: randomUUID9(),
|
|
178446
179261
|
...input,
|
|
178447
179262
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
178448
179263
|
};
|
|
@@ -178463,7 +179278,7 @@ var init_long_term_store = __esm({
|
|
|
178463
179278
|
listEvents(memoryId) {
|
|
178464
179279
|
return this.db.prepare(`
|
|
178465
179280
|
SELECT * FROM long_term_memory_events WHERE memoryId = ? ORDER BY createdAt ASC, rowid ASC
|
|
178466
|
-
`).all(memoryId).map(
|
|
179281
|
+
`).all(memoryId).map(rowToEvent2);
|
|
178467
179282
|
}
|
|
178468
179283
|
markAccess(ids, at2 = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
178469
179284
|
const unique3 = [...new Set(ids.filter(Boolean))];
|
|
@@ -178532,7 +179347,7 @@ __export(long_term_exports, {
|
|
|
178532
179347
|
selectLongTermMemoriesForTask: () => selectLongTermMemoriesForTask,
|
|
178533
179348
|
supersedeLongTermMemory: () => supersedeLongTermMemory
|
|
178534
179349
|
});
|
|
178535
|
-
import { randomUUID as
|
|
179350
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
178536
179351
|
function isOneOf(value, values) {
|
|
178537
179352
|
return typeof value === "string" && values.includes(value);
|
|
178538
179353
|
}
|
|
@@ -178714,7 +179529,7 @@ async function createManualLongTermMemory(input) {
|
|
|
178714
179529
|
const owner = await resolveLocalMemoryOwner(input.dataDir, { create: true });
|
|
178715
179530
|
if (!owner) throw new Error("Memorix could not resolve a local memory owner.");
|
|
178716
179531
|
assertScope(input.scope);
|
|
178717
|
-
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" +
|
|
179532
|
+
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID10(), relation: "supports" }];
|
|
178718
179533
|
return createLongTermMemoryWithDataDir({
|
|
178719
179534
|
dataDir: input.dataDir,
|
|
178720
179535
|
originProjectId: input.projectId,
|
|
@@ -178769,7 +179584,7 @@ async function createLongTermMemoryWithDataDir(input) {
|
|
|
178769
179584
|
assertPortableEvidence(input.scope, portability, evidenceInputs);
|
|
178770
179585
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
178771
179586
|
const memory = {
|
|
178772
|
-
id:
|
|
179587
|
+
id: randomUUID10(),
|
|
178773
179588
|
originProjectId: compactText(input.originProjectId, "origin project id", 1e3),
|
|
178774
179589
|
ownerId: compactText(input.ownerId, "owner id", 160),
|
|
178775
179590
|
scope: input.scope,
|
|
@@ -179087,9 +179902,9 @@ var init_long_term = __esm({
|
|
|
179087
179902
|
});
|
|
179088
179903
|
|
|
179089
179904
|
// src/codegraph/ids.ts
|
|
179090
|
-
import { createHash as
|
|
179905
|
+
import { createHash as createHash6 } from "crypto";
|
|
179091
179906
|
function digest(input) {
|
|
179092
|
-
return
|
|
179907
|
+
return createHash6("sha256").update(input).digest("hex").slice(0, 16);
|
|
179093
179908
|
}
|
|
179094
179909
|
function normalizeCodePath(path48) {
|
|
179095
179910
|
return path48.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/");
|
|
@@ -179124,7 +179939,7 @@ var store_exports = {};
|
|
|
179124
179939
|
__export(store_exports, {
|
|
179125
179940
|
CodeGraphStore: () => CodeGraphStore
|
|
179126
179941
|
});
|
|
179127
|
-
import { randomUUID as
|
|
179942
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
179128
179943
|
import { posix as pathPosix } from "path";
|
|
179129
179944
|
function rowToFile(row) {
|
|
179130
179945
|
return {
|
|
@@ -179841,7 +180656,7 @@ var init_store = __esm({
|
|
|
179841
180656
|
* so an interrupted scan cannot be advertised as complete.
|
|
179842
180657
|
*/
|
|
179843
180658
|
recordCodeStateSnapshot(input) {
|
|
179844
|
-
const id =
|
|
180659
|
+
const id = randomUUID11();
|
|
179845
180660
|
let snapshot;
|
|
179846
180661
|
const tx = this.db.transaction(() => {
|
|
179847
180662
|
const previous = this.db.prepare(
|
|
@@ -179919,7 +180734,7 @@ var init_store = __esm({
|
|
|
179919
180734
|
|
|
179920
180735
|
// src/codegraph/code-state.ts
|
|
179921
180736
|
import { execFile as execFile2 } from "child_process";
|
|
179922
|
-
import { createHash as
|
|
180737
|
+
import { createHash as createHash7 } from "crypto";
|
|
179923
180738
|
import { promisify as promisify3 } from "util";
|
|
179924
180739
|
async function runGit(rootPath, args) {
|
|
179925
180740
|
try {
|
|
@@ -179948,7 +180763,7 @@ function changedPathCount(status) {
|
|
|
179948
180763
|
return count3;
|
|
179949
180764
|
}
|
|
179950
180765
|
function fingerprint(baseRevision, status) {
|
|
179951
|
-
return
|
|
180766
|
+
return createHash7("sha256").update(baseRevision ?? "").update("\0").update(status).digest("hex");
|
|
179952
180767
|
}
|
|
179953
180768
|
async function collectCodeStateSnapshot(input) {
|
|
179954
180769
|
const [revision, status] = await Promise.all([
|
|
@@ -180048,11 +180863,11 @@ __export(lite_provider_exports, {
|
|
|
180048
180863
|
indexProjectLite: () => indexProjectLite,
|
|
180049
180864
|
refreshProjectLite: () => refreshProjectLite
|
|
180050
180865
|
});
|
|
180051
|
-
import { createHash as
|
|
180866
|
+
import { createHash as createHash8 } from "crypto";
|
|
180052
180867
|
import { readdirSync as readdirSync2, readFileSync as readFileSync8, statSync as statSync4 } from "fs";
|
|
180053
180868
|
import { join as join5, relative } from "path";
|
|
180054
180869
|
function hashText(text2) {
|
|
180055
|
-
return
|
|
180870
|
+
return createHash8("sha256").update(text2).digest("hex");
|
|
180056
180871
|
}
|
|
180057
180872
|
function extension2(path48) {
|
|
180058
180873
|
const index = path48.lastIndexOf(".");
|
|
@@ -180619,7 +181434,7 @@ var claim_store_exports = {};
|
|
|
180619
181434
|
__export(claim_store_exports, {
|
|
180620
181435
|
ClaimStore: () => ClaimStore
|
|
180621
181436
|
});
|
|
180622
|
-
import { createHash as
|
|
181437
|
+
import { createHash as createHash9, randomUUID as randomUUID12 } from "crypto";
|
|
180623
181438
|
function optionalText3(value) {
|
|
180624
181439
|
return typeof value === "string" && value ? value : void 0;
|
|
180625
181440
|
}
|
|
@@ -180658,7 +181473,7 @@ function rowToEvidence2(row) {
|
|
|
180658
181473
|
createdAt: row.createdAt
|
|
180659
181474
|
};
|
|
180660
181475
|
}
|
|
180661
|
-
function
|
|
181476
|
+
function rowToEvent3(row) {
|
|
180662
181477
|
return {
|
|
180663
181478
|
id: row.id,
|
|
180664
181479
|
projectId: row.projectId,
|
|
@@ -180672,7 +181487,7 @@ function rowToEvent2(row) {
|
|
|
180672
181487
|
};
|
|
180673
181488
|
}
|
|
180674
181489
|
function evidenceKey(input) {
|
|
180675
|
-
return
|
|
181490
|
+
return createHash9("sha256").update(JSON.stringify([
|
|
180676
181491
|
input.evidenceKind,
|
|
180677
181492
|
input.evidenceId,
|
|
180678
181493
|
input.relation,
|
|
@@ -180803,7 +181618,7 @@ var init_claim_store = __esm({
|
|
|
180803
181618
|
locator, capturedHash, evidenceKey, createdAt
|
|
180804
181619
|
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
180805
181620
|
`).run(
|
|
180806
|
-
|
|
181621
|
+
randomUUID12(),
|
|
180807
181622
|
input.claimId,
|
|
180808
181623
|
input.evidenceKind,
|
|
180809
181624
|
input.evidenceId,
|
|
@@ -180825,7 +181640,7 @@ var init_claim_store = __esm({
|
|
|
180825
181640
|
}
|
|
180826
181641
|
recordEvent(input) {
|
|
180827
181642
|
const event = {
|
|
180828
|
-
id:
|
|
181643
|
+
id: randomUUID12(),
|
|
180829
181644
|
...input,
|
|
180830
181645
|
...input.detail ? { detail: sanitizeCredentials(input.detail) } : {},
|
|
180831
181646
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -180853,7 +181668,7 @@ var init_claim_store = __esm({
|
|
|
180853
181668
|
SELECT * FROM knowledge_claim_events
|
|
180854
181669
|
WHERE claimId = ?
|
|
180855
181670
|
ORDER BY createdAt ASC, id
|
|
180856
|
-
`).all(claimId).map(
|
|
181671
|
+
`).all(claimId).map(rowToEvent3);
|
|
180857
181672
|
}
|
|
180858
181673
|
};
|
|
180859
181674
|
}
|
|
@@ -180870,7 +181685,7 @@ __export(claims_exports, {
|
|
|
180870
181685
|
supersedeClaim: () => supersedeClaim,
|
|
180871
181686
|
writeClaim: () => writeClaim
|
|
180872
181687
|
});
|
|
180873
|
-
import { createHash as
|
|
181688
|
+
import { createHash as createHash10, randomUUID as randomUUID13 } from "crypto";
|
|
180874
181689
|
function compactText2(value, field) {
|
|
180875
181690
|
if (typeof value !== "string") throw new Error("Claim " + field + " must be text");
|
|
180876
181691
|
const sanitized = sanitizeCredentials(value).trim().replace(/\s+/g, " ");
|
|
@@ -180882,7 +181697,7 @@ function normalizedTerm(value) {
|
|
|
180882
181697
|
return compactText2(value, "identity").toLocaleLowerCase("en-US");
|
|
180883
181698
|
}
|
|
180884
181699
|
function hashIdentity(parts) {
|
|
180885
|
-
return
|
|
181700
|
+
return createHash10("sha256").update(parts.join(String.fromCharCode(31))).digest("hex");
|
|
180886
181701
|
}
|
|
180887
181702
|
function buildClaimIdentity(input) {
|
|
180888
181703
|
const subject = normalizedTerm(input.subject);
|
|
@@ -180956,7 +181771,7 @@ function normalizeClaimInput(input) {
|
|
|
180956
181771
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
180957
181772
|
return {
|
|
180958
181773
|
claim: {
|
|
180959
|
-
id:
|
|
181774
|
+
id: randomUUID13(),
|
|
180960
181775
|
projectId,
|
|
180961
181776
|
subject,
|
|
180962
181777
|
predicate,
|
|
@@ -181123,7 +181938,7 @@ function supersedeClaim(store2, input) {
|
|
|
181123
181938
|
});
|
|
181124
181939
|
}
|
|
181125
181940
|
function hashObservation(observation) {
|
|
181126
|
-
return
|
|
181941
|
+
return createHash10("sha256").update(JSON.stringify([
|
|
181127
181942
|
observation.title,
|
|
181128
181943
|
observation.narrative,
|
|
181129
181944
|
observation.facts,
|
|
@@ -181367,11 +182182,11 @@ var init_frontmatter = __esm({
|
|
|
181367
182182
|
});
|
|
181368
182183
|
|
|
181369
182184
|
// src/knowledge/markdown.ts
|
|
181370
|
-
import { createHash as
|
|
182185
|
+
import { createHash as createHash11 } from "crypto";
|
|
181371
182186
|
import { promises as fs12 } from "fs";
|
|
181372
182187
|
import path20 from "path";
|
|
181373
182188
|
function hashContent(content) {
|
|
181374
|
-
return
|
|
182189
|
+
return createHash11("sha256").update(content).digest("hex");
|
|
181375
182190
|
}
|
|
181376
182191
|
function stringField(data, key) {
|
|
181377
182192
|
const value = data[key];
|
|
@@ -181497,11 +182312,11 @@ __export(wiki_exports, {
|
|
|
181497
182312
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
181498
182313
|
readKnowledgePage: () => readKnowledgePage
|
|
181499
182314
|
});
|
|
181500
|
-
import { createHash as
|
|
182315
|
+
import { createHash as createHash12 } from "crypto";
|
|
181501
182316
|
import { promises as fs13 } from "fs";
|
|
181502
182317
|
import path21 from "path";
|
|
181503
182318
|
function hash2(value) {
|
|
181504
|
-
return
|
|
182319
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
181505
182320
|
}
|
|
181506
182321
|
function now() {
|
|
181507
182322
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -182045,7 +182860,7 @@ var workflow_store_exports = {};
|
|
|
182045
182860
|
__export(workflow_store_exports, {
|
|
182046
182861
|
WorkflowStore: () => WorkflowStore
|
|
182047
182862
|
});
|
|
182048
|
-
import { randomUUID as
|
|
182863
|
+
import { randomUUID as randomUUID14 } from "crypto";
|
|
182049
182864
|
function parseJson(value, fallback) {
|
|
182050
182865
|
if (typeof value !== "string" || !value) return fallback;
|
|
182051
182866
|
try {
|
|
@@ -182145,7 +182960,7 @@ var init_workflow_store = __esm({
|
|
|
182145
182960
|
}
|
|
182146
182961
|
recordRun(input) {
|
|
182147
182962
|
const run = {
|
|
182148
|
-
id:
|
|
182963
|
+
id: randomUUID14(),
|
|
182149
182964
|
workflowId: input.workflowId,
|
|
182150
182965
|
projectId: input.projectId,
|
|
182151
182966
|
task: input.task.trim(),
|
|
@@ -182223,7 +183038,7 @@ var init_outcome_types = __esm({
|
|
|
182223
183038
|
});
|
|
182224
183039
|
|
|
182225
183040
|
// src/knowledge/outcome-store.ts
|
|
182226
|
-
import { randomUUID as
|
|
183041
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
182227
183042
|
function optionalText5(value) {
|
|
182228
183043
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
182229
183044
|
}
|
|
@@ -182267,7 +183082,7 @@ var init_outcome_store = __esm({
|
|
|
182267
183082
|
}
|
|
182268
183083
|
record(input) {
|
|
182269
183084
|
const signal = {
|
|
182270
|
-
id:
|
|
183085
|
+
id: randomUUID15(),
|
|
182271
183086
|
projectId: text(input.projectId, "project id"),
|
|
182272
183087
|
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
182273
183088
|
candidateId: text(input.candidateId, "candidate id"),
|
|
@@ -182694,11 +183509,11 @@ __export(workflows_exports, {
|
|
|
182694
183509
|
syncCanonicalWorkflows: () => syncCanonicalWorkflows,
|
|
182695
183510
|
writeCanonicalWorkflow: () => writeCanonicalWorkflow
|
|
182696
183511
|
});
|
|
182697
|
-
import { createHash as
|
|
183512
|
+
import { createHash as createHash13 } from "crypto";
|
|
182698
183513
|
import { promises as fs14 } from "fs";
|
|
182699
183514
|
import path22 from "path";
|
|
182700
183515
|
function hash3(value) {
|
|
182701
|
-
return
|
|
183516
|
+
return createHash13("sha256").update(value).digest("hex");
|
|
182702
183517
|
}
|
|
182703
183518
|
function now2() {
|
|
182704
183519
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -184095,6 +184910,16 @@ async function bindObservationCodeRefsBestEffort(observation) {
|
|
|
184095
184910
|
} catch {
|
|
184096
184911
|
}
|
|
184097
184912
|
}
|
|
184913
|
+
async function persistEvidenceCard(observation) {
|
|
184914
|
+
if (!projectDir) return;
|
|
184915
|
+
try {
|
|
184916
|
+
const evidence = new EvidenceCardStore();
|
|
184917
|
+
await evidence.init(projectDir);
|
|
184918
|
+
evidence.upsertObservation(observation);
|
|
184919
|
+
} catch (error40) {
|
|
184920
|
+
console.error(`[memorix] Evidence card projection failed for obs-${observation.id}: ${error40 instanceof Error ? error40.message : String(error40)}`);
|
|
184921
|
+
}
|
|
184922
|
+
}
|
|
184098
184923
|
function queueClaimDerivation(observation) {
|
|
184099
184924
|
const dataDir = projectDir;
|
|
184100
184925
|
const isExplicit = observation.sourceDetail === "explicit";
|
|
@@ -184441,6 +185266,7 @@ async function storeObservation(input) {
|
|
|
184441
185266
|
}
|
|
184442
185267
|
if (!persistedCallbackInvoked) await input.onPersisted?.(observation);
|
|
184443
185268
|
await bindObservationCodeRefsBestEffort(observation);
|
|
185269
|
+
await persistEvidenceCard(observation);
|
|
184444
185270
|
queueObservationQualification(observation);
|
|
184445
185271
|
if (resolveObservationVisibility(observation) === "project") {
|
|
184446
185272
|
queueClaimDerivation(observation);
|
|
@@ -184533,6 +185359,7 @@ async function upsertObservation(existing, input, now3) {
|
|
|
184533
185359
|
await store2.update(existing);
|
|
184534
185360
|
}
|
|
184535
185361
|
await bindObservationCodeRefsBestEffort(existing);
|
|
185362
|
+
await persistEvidenceCard(existing);
|
|
184536
185363
|
queueObservationQualification(existing);
|
|
184537
185364
|
if (resolveObservationVisibility(existing) === "project") {
|
|
184538
185365
|
queueClaimDerivation(existing);
|
|
@@ -184666,6 +185493,7 @@ async function resolveObservations(ids, status = "resolved") {
|
|
|
184666
185493
|
await Promise.all(changed.map((observation) => tx.update(observation)));
|
|
184667
185494
|
});
|
|
184668
185495
|
}
|
|
185496
|
+
for (const observation of changed) await persistEvidenceCard(observation);
|
|
184669
185497
|
return { resolved, notFound };
|
|
184670
185498
|
}
|
|
184671
185499
|
function getProjectObservations(projectId) {
|
|
@@ -185003,6 +185831,7 @@ var init_observations = __esm({
|
|
|
185003
185831
|
init_secret_filter();
|
|
185004
185832
|
init_lifecycle();
|
|
185005
185833
|
init_visibility();
|
|
185834
|
+
init_evidence_store();
|
|
185006
185835
|
observations = [];
|
|
185007
185836
|
nextId = 1;
|
|
185008
185837
|
projectDir = null;
|
|
@@ -185792,46 +186621,78 @@ async function searchObservations(options) {
|
|
|
185792
186621
|
}
|
|
185793
186622
|
}
|
|
185794
186623
|
}
|
|
185795
|
-
const
|
|
185796
|
-
|
|
185797
|
-
|
|
185798
|
-
|
|
185799
|
-
})
|
|
185800
|
-
|
|
185801
|
-
|
|
185802
|
-
|
|
185803
|
-
|
|
185804
|
-
|
|
185805
|
-
|
|
185806
|
-
|
|
185807
|
-
|
|
185808
|
-
|
|
185809
|
-
|
|
185810
|
-
|
|
185811
|
-
|
|
185812
|
-
|
|
185813
|
-
|
|
185814
|
-
|
|
185815
|
-
|
|
185816
|
-
|
|
185817
|
-
|
|
185818
|
-
|
|
185819
|
-
|
|
185820
|
-
|
|
185821
|
-
|
|
185822
|
-
|
|
185823
|
-
|
|
185824
|
-
|
|
185825
|
-
|
|
185826
|
-
|
|
185827
|
-
|
|
185828
|
-
|
|
185829
|
-
|
|
185830
|
-
|
|
186624
|
+
const httpGate = shouldAttemptHttpRerank({
|
|
186625
|
+
quality,
|
|
186626
|
+
hasQuery: Boolean(hasQuery),
|
|
186627
|
+
candidateCount: intermediate.length
|
|
186628
|
+
});
|
|
186629
|
+
const llmGateWithoutHttp = shouldAttemptLlmRerank({
|
|
186630
|
+
quality,
|
|
186631
|
+
tier,
|
|
186632
|
+
hasQuery: Boolean(hasQuery),
|
|
186633
|
+
candidateCount: intermediate.length,
|
|
186634
|
+
topScore: intermediate[0]?.score ?? 0,
|
|
186635
|
+
secondScore: intermediate[1]?.score ?? 0,
|
|
186636
|
+
httpRerankConfigured: false
|
|
186637
|
+
});
|
|
186638
|
+
if (httpGate || llmGateWithoutHttp) {
|
|
186639
|
+
const narrativeMap = /* @__PURE__ */ new Map();
|
|
186640
|
+
for (const hit of results.hits) {
|
|
186641
|
+
const doc = hit.document;
|
|
186642
|
+
narrativeMap.set(makeEntryKey(doc.projectId, doc.observationId), doc.narrative);
|
|
186643
|
+
}
|
|
186644
|
+
const RERANK_TOP_K = 5;
|
|
186645
|
+
const toRerank = intermediate.slice(0, RERANK_TOP_K);
|
|
186646
|
+
const candidates = toRerank.map((e5, index) => ({
|
|
186647
|
+
id: `r${index + 1}`,
|
|
186648
|
+
title: e5.title,
|
|
186649
|
+
type: e5.type,
|
|
186650
|
+
score: e5.score,
|
|
186651
|
+
narrative: narrativeMap.get(makeEntryKey(e5.projectId, e5.id))
|
|
186652
|
+
}));
|
|
186653
|
+
const RERANK_TIMEOUT_MS = parseRerankTimeoutMs(process.env.MEMORIX_RERANK_TIMEOUT_MS);
|
|
186654
|
+
const candidateMap = new Map(candidates.map((candidate2, index) => [candidate2.id, toRerank[index]]));
|
|
186655
|
+
const { isNeuralRerankEnabled: isNeuralRerankEnabled2, neuralRerankCandidates: neuralRerankCandidates2 } = await Promise.resolve().then(() => (init_rerank(), rerank_exports));
|
|
186656
|
+
const httpConfigured = isNeuralRerankEnabled2();
|
|
186657
|
+
if (httpConfigured && httpGate) {
|
|
186658
|
+
try {
|
|
186659
|
+
const neural = await withTimeout(
|
|
186660
|
+
neuralRerankCandidates2(originalQuery, candidates),
|
|
186661
|
+
RERANK_TIMEOUT_MS,
|
|
186662
|
+
"neural rerank"
|
|
186663
|
+
);
|
|
186664
|
+
if (neural && neural.length > 0) {
|
|
186665
|
+
const rerankedTop = neural.map((row) => candidateMap.get(row.id)).filter((entry) => entry != null);
|
|
186666
|
+
if (rerankedTop.length > 0) {
|
|
186667
|
+
intermediate = [...rerankedTop, ...intermediate.slice(RERANK_TOP_K)];
|
|
186668
|
+
lastSearchModeByProject.set(modeKey, (lastSearchModeByProject.get(modeKey) ?? "fulltext") + " + neural rerank");
|
|
186669
|
+
mark("rerank(usedNeural=true)");
|
|
186670
|
+
}
|
|
185831
186671
|
}
|
|
186672
|
+
} catch {
|
|
186673
|
+
console.error("[memorix] neural rerank failed or timed out; keeping original order");
|
|
185832
186674
|
}
|
|
185833
|
-
}
|
|
185834
|
-
|
|
186675
|
+
} else if (!httpConfigured && llmGateWithoutHttp) {
|
|
186676
|
+
try {
|
|
186677
|
+
const { rerankResults: rerankResults2 } = await Promise.resolve().then(() => (init_quality(), quality_exports));
|
|
186678
|
+
const { reranked, usedLLM } = await withTimeout(
|
|
186679
|
+
rerankResults2(originalQuery, candidates),
|
|
186680
|
+
RERANK_TIMEOUT_MS,
|
|
186681
|
+
"LLM rerank"
|
|
186682
|
+
);
|
|
186683
|
+
mark(`rerank(usedLLM=${usedLLM})`);
|
|
186684
|
+
if (usedLLM) {
|
|
186685
|
+
lastSearchModeByProject.set(modeKey, (lastSearchModeByProject.get(modeKey) ?? "fulltext") + " + LLM rerank");
|
|
186686
|
+
const rerankedTop = reranked.map((row) => candidateMap.get(row.id)).filter((entry) => entry != null);
|
|
186687
|
+
if (rerankedTop.length > 0) {
|
|
186688
|
+
intermediate = [...rerankedTop, ...intermediate.slice(RERANK_TOP_K)];
|
|
186689
|
+
}
|
|
186690
|
+
}
|
|
186691
|
+
} catch {
|
|
186692
|
+
console.error("[memorix] LLM rerank failed or timed out, using original order");
|
|
186693
|
+
}
|
|
186694
|
+
} else {
|
|
186695
|
+
mark(`rerank(skipped,tier=${tier})`);
|
|
185835
186696
|
}
|
|
185836
186697
|
} else {
|
|
185837
186698
|
mark(`rerank(skipped,tier=${tier})`);
|
|
@@ -186013,6 +186874,7 @@ var init_orama_store = __esm({
|
|
|
186013
186874
|
init_project_affinity();
|
|
186014
186875
|
init_intent_detector();
|
|
186015
186876
|
init_query_expansion();
|
|
186877
|
+
init_policy();
|
|
186016
186878
|
init_timeout();
|
|
186017
186879
|
db = null;
|
|
186018
186880
|
dbInitPromise = null;
|
|
@@ -186402,9 +187264,27 @@ function normalizeMemoryBrowseQuery(query) {
|
|
|
186402
187264
|
async function compactSearch(options, surface = "mcp") {
|
|
186403
187265
|
await ensureFreshIndex();
|
|
186404
187266
|
const searchOptions = { ...options, query: normalizeMemoryBrowseQuery(options.query) };
|
|
186405
|
-
|
|
187267
|
+
let entries = (await searchObservations(searchOptions)).map(
|
|
186406
187268
|
(entry) => entry.projectId || !options.projectId ? entry : { ...entry, projectId: options.projectId }
|
|
186407
187269
|
);
|
|
187270
|
+
if (options.projectId) {
|
|
187271
|
+
try {
|
|
187272
|
+
const feedback = new MemoryFeedbackStore();
|
|
187273
|
+
await feedback.init(await getProjectDataDir(options.projectId));
|
|
187274
|
+
const states = feedback.weights(options.projectId, "observation");
|
|
187275
|
+
entries = entries.map((entry) => {
|
|
187276
|
+
const state = states.get(String(entry.id));
|
|
187277
|
+
if (!state) return entry;
|
|
187278
|
+
return {
|
|
187279
|
+
...entry,
|
|
187280
|
+
score: (entry.score ?? 0) * feedbackWeightMultiplier(state.weight),
|
|
187281
|
+
feedbackWeight: state.weight,
|
|
187282
|
+
feedbackStatus: state.status
|
|
187283
|
+
};
|
|
187284
|
+
}).filter((entry) => entry.feedbackStatus !== "archived" || options.status === "all").sort((a4, b4) => (b4.score ?? 0) - (a4.score ?? 0));
|
|
187285
|
+
} catch {
|
|
187286
|
+
}
|
|
187287
|
+
}
|
|
186408
187288
|
let formatted = formatIndexTable(entries, searchOptions.query, !options.projectId, surface);
|
|
186409
187289
|
if (entries.length === 0 && options.projectId) {
|
|
186410
187290
|
const allObservations = filterReadableObservations(getAllObservations(), options.reader);
|
|
@@ -186723,6 +187603,8 @@ var init_engine3 = __esm({
|
|
|
186723
187603
|
init_mini_skills();
|
|
186724
187604
|
init_secret_filter();
|
|
186725
187605
|
init_visibility();
|
|
187606
|
+
init_persistence();
|
|
187607
|
+
init_feedback();
|
|
186726
187608
|
}
|
|
186727
187609
|
});
|
|
186728
187610
|
|
|
@@ -186737,7 +187619,7 @@ __export(team_store_exports, {
|
|
|
186737
187619
|
isTeamStoreInitialized: () => isTeamStoreInitialized,
|
|
186738
187620
|
resetTeamStore: () => resetTeamStore
|
|
186739
187621
|
});
|
|
186740
|
-
import { randomUUID as
|
|
187622
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
186741
187623
|
import path24 from "path";
|
|
186742
187624
|
import fs15 from "fs";
|
|
186743
187625
|
function getTeamStore() {
|
|
@@ -187026,7 +187908,7 @@ var init_team_store = __esm({
|
|
|
187026
187908
|
* reactivate it (preserving agent_id). Otherwise create a new one.
|
|
187027
187909
|
*/
|
|
187028
187910
|
registerAgent(input) {
|
|
187029
|
-
const instanceId = input.instanceId ||
|
|
187911
|
+
const instanceId = input.instanceId || randomUUID16();
|
|
187030
187912
|
const now3 = Date.now();
|
|
187031
187913
|
const existing = this.stmtAgentFindByInstance.get(
|
|
187032
187914
|
input.projectId,
|
|
@@ -187052,7 +187934,7 @@ var init_team_store = __esm({
|
|
|
187052
187934
|
this.eventBus?.emit("agent:joined", { agentId: row2.agent_id, projectId: input.projectId, agentType: input.agentType });
|
|
187053
187935
|
return row2;
|
|
187054
187936
|
}
|
|
187055
|
-
const agentId =
|
|
187937
|
+
const agentId = randomUUID16();
|
|
187056
187938
|
this.stmtAgentUpsert.run({
|
|
187057
187939
|
agent_id: agentId,
|
|
187058
187940
|
project_id: input.projectId,
|
|
@@ -187154,7 +188036,7 @@ var init_team_store = __esm({
|
|
|
187154
188036
|
return { error: `Recipient agent '${input.recipientAgentId}' not found \u2014 cannot send to unknown agent` };
|
|
187155
188037
|
}
|
|
187156
188038
|
}
|
|
187157
|
-
const id =
|
|
188039
|
+
const id = randomUUID16();
|
|
187158
188040
|
const now3 = Date.now();
|
|
187159
188041
|
const row = {
|
|
187160
188042
|
id,
|
|
@@ -187204,7 +188086,7 @@ var init_team_store = __esm({
|
|
|
187204
188086
|
// Task Operations (with atomic claim semantics)
|
|
187205
188087
|
// ═══════════════════════════════════════════════════════════════════
|
|
187206
188088
|
createTask(input) {
|
|
187207
|
-
const taskId =
|
|
188089
|
+
const taskId = randomUUID16();
|
|
187208
188090
|
const now3 = Date.now();
|
|
187209
188091
|
const row = {
|
|
187210
188092
|
task_id: taskId,
|
|
@@ -187476,7 +188358,7 @@ var init_team_store = __esm({
|
|
|
187476
188358
|
for (const [agentId, msgs] of Object.entries(snap.messages.inboxes)) {
|
|
187477
188359
|
for (const msg of msgs) {
|
|
187478
188360
|
this.stmtMsgInsert.run({
|
|
187479
|
-
id: msg.id ??
|
|
188361
|
+
id: msg.id ?? randomUUID16(),
|
|
187480
188362
|
project_id: "migrated",
|
|
187481
188363
|
sender_agent_id: msg.from ?? "unknown",
|
|
187482
188364
|
recipient_agent_id: msg.to === "__broadcast__" ? null : msg.to ?? agentId,
|
|
@@ -190318,6 +191200,16 @@ function buildInitTomlConfig(options) {
|
|
|
190318
191200
|
}
|
|
190319
191201
|
}
|
|
190320
191202
|
lines.push("");
|
|
191203
|
+
lines.push("[rerank]");
|
|
191204
|
+
lines.push("# Optional HTTP rerank against any Cohere-compatible /rerank API.");
|
|
191205
|
+
lines.push('# provider = "http"');
|
|
191206
|
+
lines.push('# model = "rerank-model"');
|
|
191207
|
+
lines.push("# base_url inherits [memory.llm] when unset.");
|
|
191208
|
+
if (isGlobal) {
|
|
191209
|
+
lines.push("# Bearer inherits the memory LLM key only when that endpoint matches.");
|
|
191210
|
+
lines.push("# A different rerank URL needs MEMORIX_RERANK_API_KEY.");
|
|
191211
|
+
}
|
|
191212
|
+
lines.push("");
|
|
190321
191213
|
lines.push("[git]");
|
|
190322
191214
|
lines.push(`auto_hook = ${options.gitAutoHook}`);
|
|
190323
191215
|
lines.push("ingest_on_commit = true");
|
|
@@ -190490,6 +191382,12 @@ var init_init = __esm({
|
|
|
190490
191382
|
envLines.push("# MEMORIX_EMBEDDING_BASE_URL=https://api.openai.com/v1");
|
|
190491
191383
|
envLines.push("");
|
|
190492
191384
|
}
|
|
191385
|
+
envLines.push("# Optional HTTP rerank (Cohere-compatible POST {base_url}/rerank)");
|
|
191386
|
+
envLines.push("# MEMORIX_RERANK_PROVIDER=http");
|
|
191387
|
+
envLines.push("# MEMORIX_RERANK_MODEL=rerank-model");
|
|
191388
|
+
envLines.push("# MEMORIX_RERANK_BASE_URL=https://api.example.com/v1");
|
|
191389
|
+
envLines.push("# MEMORIX_RERANK_API_KEY= # required when BASE_URL is not the memory LLM endpoint");
|
|
191390
|
+
envLines.push("");
|
|
190493
191391
|
envLines.push("# Optional memory LLM simple key (does not apply to embedding or agent lanes)");
|
|
190494
191392
|
envLines.push("# MEMORIX_API_KEY=sk-your-key-here");
|
|
190495
191393
|
envLines.push("");
|
|
@@ -191893,8 +192791,8 @@ var init_official_skills = __esm({
|
|
|
191893
192791
|
"",
|
|
191894
192792
|
"| Situation | Prefer | CLI fallback |",
|
|
191895
192793
|
"|---|---|---|",
|
|
191896
|
-
'| Starting a coding task and needing the best task-lensed project map | `memorix_project_context` with the user\'s task | `memorix context "<task>" --brief-json` |',
|
|
191897
|
-
'| Continuing prior project work | `memorix_project_context` with the user\'s task | `memorix resume "<task>" --brief-json` |',
|
|
192794
|
+
'| Starting a coding task and needing the best task-lensed project map | `memorix_project_context` with the user\'s task | `memorix context "<task>" --fallback --brief-json` |',
|
|
192795
|
+
'| Continuing prior project work | `memorix_project_context` with the user\'s task | `memorix resume "<task>" --fallback --brief-json` |',
|
|
191898
192796
|
'| Need structured refs/freshness for code-bound memories | `memorix_context_pack` | `memorix codegraph context-pack --task "<topic>"` |',
|
|
191899
192797
|
'| Explicit memory graph question | `memorix_graph_context` | `memorix memory graph-context --query "<topic>"` |',
|
|
191900
192798
|
'| Specific past decision, bug, file, or change | `memorix_search` | `memorix memory search --query "<topic>"` |',
|
|
@@ -191907,7 +192805,7 @@ var init_official_skills = __esm({
|
|
|
191907
192805
|
"",
|
|
191908
192806
|
"- Default first step for non-trivial coding work: call `memorix_project_context` before progress files, dev-log reads, ad-hoc file reads, or git archaeology. Pass the user's actual task so Memorix can choose a bugfix, feature, release, onboarding, refactor, docs, test, or general brief. Start by reading its suggested files.",
|
|
191909
192807
|
"- In Claude Code headless/print-mode, an initial MCP `pending` status is not a failure by itself. Prefer MCP first: use the client's tool discovery/dynamic loading to find `memorix_project_context` when it is not in the first visible tool list.",
|
|
191910
|
-
'- Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run `memorix resume "<task>" --brief-json` exactly once before inspecting files, Git history, progress notes, or guessing. The absence of `.memorix` or visible memory files never proves project memory is empty. For a new task, use `memorix context "<task>" --brief-json` instead. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally; do not probe help, enumerate commands, or chain broad searches.',
|
|
192808
|
+
'- Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run `memorix resume "<task>" --fallback --brief-json` exactly once before inspecting files, Git history, progress notes, or guessing. The absence of `.memorix` or visible memory files never proves project memory is empty. For a new task, use `memorix context "<task>" --fallback --brief-json` instead. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally; do not probe help, enumerate commands, or chain broad searches.',
|
|
191911
192809
|
"- After a successful `memorix_project_context`, the brief is the default retrieval boundary. Do not call more Memorix retrieval tools after a complete brief. Use Context Pack, search, or detail only when the brief lacks a specific reference, freshness field, or fact needed for the task, or when the user explicitly asks for deeper history. In MCP, name that missing fact in `purpose` when intentionally expanding beyond the brief. Do not retrieve the same decision twice just to confirm an already-complete brief.",
|
|
191912
192810
|
"- If the user asks for read-only work or says not to modify files, do not call `memorix_store` just to record an assessment. Store only when the user explicitly asks to preserve it.",
|
|
191913
192811
|
"- Use `memorix_search` for a specific decision, bug, file, or prior change that the project context did not answer. Fetch detail only for a result you still need after the brief.",
|
|
@@ -193166,7 +194064,7 @@ alwaysApply: true
|
|
|
193166
194064
|
"",
|
|
193167
194065
|
`Default first step for non-trivial coding work: call \`memorix_project_context\` with the user's actual task before progress files, dev-log reads, ad-hoc file reads, or git archaeology. Memorix will choose a task-lensed brief (bugfix, feature, release, onboarding, refactor, docs, test, or general). When the task is continuing prior work, the same brief also includes a bounded prior-work projection. Treat its "Start here" files as the first ${contextNoun} files to inspect.`,
|
|
193168
194066
|
"",
|
|
193169
|
-
'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run exactly one CLI brief with the user\'s real task before inspecting files, Git history, progress notes, or guessing: `memorix resume "<task>" --brief-json`. For a new task, use `memorix context "<task>" --brief-json` instead. The absence of `.memorix` or visible memory files never proves project memory is empty. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally. Do not probe help, enumerate commands, chain broad searches, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
|
|
194067
|
+
'If the MCP tool is not visible yet but the client supports tool discovery or dynamic loading, search/select `memorix_project_context` first. Continuation fallback is mandatory: when the user asks to continue, resume, take over, or explain prior work and MCP cannot be called in this turn, run exactly one CLI brief with the user\'s real task before inspecting files, Git history, progress notes, or guessing: `memorix resume "<task>" --fallback --brief-json`. For a new task, use `memorix context "<task>" --fallback --brief-json` instead. The absence of `.memorix` or visible memory files never proves project memory is empty. Use `--json` only when a diagnostic needs the detailed legacy payload. If that one command fails, report it and proceed normally. Do not probe help, enumerate commands, chain broad searches, wait indefinitely on MCP startup, or hand-write tool-call syntax.',
|
|
193170
194068
|
"",
|
|
193171
194069
|
"After a successful `memorix_project_context` result, the brief is the default retrieval boundary. Do not call more Memorix retrieval tools after a complete brief. Use `memorix_context_pack`, `memorix_search`, or `memorix_detail` only when the brief lacks a specific reference, freshness field, or fact needed for the task, or when the user explicitly asks for deeper history. In MCP, name that missing fact in `purpose` when intentionally expanding beyond the brief. Do not retrieve the same decision twice just to confirm an already-complete brief.",
|
|
193172
194070
|
"If the user asks for read-only work or says not to modify files, do not call `memorix_store` just to record an assessment. Store only when the user explicitly asks to preserve it.",
|
|
@@ -194916,6 +195814,12 @@ function serializeResolvedConfigToToml(config2, options = {}) {
|
|
|
194916
195814
|
api_key: includeSecrets ? config2.embedding.apiKey : void 0,
|
|
194917
195815
|
dimensions: config2.embedding.dimensions
|
|
194918
195816
|
});
|
|
195817
|
+
writeSection(lines, "rerank", {
|
|
195818
|
+
provider: config2.rerank.provider,
|
|
195819
|
+
model: config2.rerank.model,
|
|
195820
|
+
base_url: config2.rerank.baseUrl,
|
|
195821
|
+
api_key: includeSecrets ? config2.rerank.apiKey : void 0
|
|
195822
|
+
});
|
|
194919
195823
|
writeSection(lines, "memory", {
|
|
194920
195824
|
inject: config2.memory.inject,
|
|
194921
195825
|
formation: config2.memory.formation,
|
|
@@ -197668,7 +198572,7 @@ var compaction_checkpoint_store_exports = {};
|
|
|
197668
198572
|
__export(compaction_checkpoint_store_exports, {
|
|
197669
198573
|
CompactionCheckpointStore: () => CompactionCheckpointStore
|
|
197670
198574
|
});
|
|
197671
|
-
import { createHash as
|
|
198575
|
+
import { createHash as createHash14, randomUUID as randomUUID17 } from "crypto";
|
|
197672
198576
|
function optionalText7(value) {
|
|
197673
198577
|
return typeof value === "string" && value ? value : void 0;
|
|
197674
198578
|
}
|
|
@@ -197710,7 +198614,7 @@ function sourceKeyFor(input, summary) {
|
|
|
197710
198614
|
input.tokensBefore ?? "",
|
|
197711
198615
|
input.firstKeptEntryId ?? ""
|
|
197712
198616
|
].join("\0");
|
|
197713
|
-
return `derived:${
|
|
198617
|
+
return `derived:${createHash14("sha256").update(material).digest("hex").slice(0, 32)}`;
|
|
197714
198618
|
}
|
|
197715
198619
|
function rowToCheckpoint(row) {
|
|
197716
198620
|
return {
|
|
@@ -197769,7 +198673,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
197769
198673
|
if (pending) return rowToCheckpoint(pending);
|
|
197770
198674
|
const now3 = input.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
197771
198675
|
const checkpoint = {
|
|
197772
|
-
id:
|
|
198676
|
+
id: randomUUID17(),
|
|
197773
198677
|
projectId: input.projectId,
|
|
197774
198678
|
sessionId: input.sessionId,
|
|
197775
198679
|
agent: input.agent,
|
|
@@ -197777,7 +198681,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
197777
198681
|
captureKind: "preflight",
|
|
197778
198682
|
reason: safeReason(input.reason),
|
|
197779
198683
|
sourceEvent: input.sourceEvent,
|
|
197780
|
-
sourceKey: `pre:${
|
|
198684
|
+
sourceKey: `pre:${randomUUID17()}`,
|
|
197781
198685
|
transcriptAvailable: Boolean(input.transcriptAvailable),
|
|
197782
198686
|
status: "active",
|
|
197783
198687
|
preCapturedAt: now3,
|
|
@@ -197843,7 +198747,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
197843
198747
|
return this.get(checkpoint2.id);
|
|
197844
198748
|
}
|
|
197845
198749
|
const checkpoint = {
|
|
197846
|
-
id:
|
|
198750
|
+
id: randomUUID17(),
|
|
197847
198751
|
projectId: input.projectId,
|
|
197848
198752
|
sessionId: input.sessionId,
|
|
197849
198753
|
agent: input.agent,
|
|
@@ -198591,6 +199495,59 @@ var init_context_receipt = __esm({
|
|
|
198591
199495
|
}
|
|
198592
199496
|
});
|
|
198593
199497
|
|
|
199498
|
+
// src/cli/fallback-budget.ts
|
|
199499
|
+
import { createHash as createHash15 } from "crypto";
|
|
199500
|
+
function fallbackRequestKey(projectId, task) {
|
|
199501
|
+
const normalized = (task ?? "").trim().toLowerCase().replace(/\s+/g, " ");
|
|
199502
|
+
return createHash15("sha256").update(`${projectId}
|
|
199503
|
+
${normalized}`).digest("hex").slice(0, 32);
|
|
199504
|
+
}
|
|
199505
|
+
var DEFAULT_FALLBACK_TTL_MS, CliFallbackBudget;
|
|
199506
|
+
var init_fallback_budget = __esm({
|
|
199507
|
+
"src/cli/fallback-budget.ts"() {
|
|
199508
|
+
"use strict";
|
|
199509
|
+
init_esm_shims();
|
|
199510
|
+
init_sqlite_db();
|
|
199511
|
+
DEFAULT_FALLBACK_TTL_MS = 10 * 60 * 1e3;
|
|
199512
|
+
CliFallbackBudget = class {
|
|
199513
|
+
db = null;
|
|
199514
|
+
async init(dataDir) {
|
|
199515
|
+
this.db = getDatabase(dataDir);
|
|
199516
|
+
this.db.exec(`
|
|
199517
|
+
CREATE TABLE IF NOT EXISTS cli_fallback_attempts (
|
|
199518
|
+
project_id TEXT NOT NULL,
|
|
199519
|
+
request_key TEXT NOT NULL,
|
|
199520
|
+
count INTEGER NOT NULL DEFAULT 0,
|
|
199521
|
+
last_attempt_at INTEGER NOT NULL,
|
|
199522
|
+
expires_at INTEGER NOT NULL,
|
|
199523
|
+
PRIMARY KEY (project_id, request_key)
|
|
199524
|
+
)
|
|
199525
|
+
`);
|
|
199526
|
+
}
|
|
199527
|
+
claim(projectId, task, now3 = Date.now(), ttlMs = DEFAULT_FALLBACK_TTL_MS) {
|
|
199528
|
+
if (!this.db) throw new Error("CliFallbackBudget is not initialized.");
|
|
199529
|
+
const key = fallbackRequestKey(projectId, task);
|
|
199530
|
+
const current = this.db.prepare(`
|
|
199531
|
+
SELECT count, expires_at FROM cli_fallback_attempts WHERE project_id = ? AND request_key = ?
|
|
199532
|
+
`).get(projectId, key);
|
|
199533
|
+
const count3 = Number(current?.count ?? 0);
|
|
199534
|
+
if (current && Number(current.expires_at) > now3 && count3 >= 1) {
|
|
199535
|
+
return { allowed: false, key, count: count3, reason: "Fallback budget exhausted for this task. Stop probing and continue with the current project files." };
|
|
199536
|
+
}
|
|
199537
|
+
this.db.prepare(`
|
|
199538
|
+
INSERT INTO cli_fallback_attempts (project_id, request_key, count, last_attempt_at, expires_at)
|
|
199539
|
+
VALUES (?, ?, 1, ?, ?)
|
|
199540
|
+
ON CONFLICT(project_id, request_key) DO UPDATE SET
|
|
199541
|
+
count = CASE WHEN excluded.expires_at > cli_fallback_attempts.expires_at THEN 1 ELSE cli_fallback_attempts.count + 1 END,
|
|
199542
|
+
last_attempt_at = excluded.last_attempt_at,
|
|
199543
|
+
expires_at = CASE WHEN excluded.expires_at > cli_fallback_attempts.expires_at THEN excluded.expires_at ELSE cli_fallback_attempts.expires_at END
|
|
199544
|
+
`).run(projectId, key, now3, now3 + Math.max(1e3, ttlMs));
|
|
199545
|
+
return { allowed: true, key, count: 1 };
|
|
199546
|
+
}
|
|
199547
|
+
};
|
|
199548
|
+
}
|
|
199549
|
+
});
|
|
199550
|
+
|
|
198594
199551
|
// src/cli/commands/context.ts
|
|
198595
199552
|
var context_exports = {};
|
|
198596
199553
|
__export(context_exports, {
|
|
@@ -198619,6 +199576,7 @@ var init_context2 = __esm({
|
|
|
198619
199576
|
init_context_receipt();
|
|
198620
199577
|
init_workflows2();
|
|
198621
199578
|
init_operator_shared();
|
|
199579
|
+
init_fallback_budget();
|
|
198622
199580
|
context_default = defineCommand({
|
|
198623
199581
|
meta: {
|
|
198624
199582
|
name: "context",
|
|
@@ -198635,13 +199593,23 @@ var init_context2 = __esm({
|
|
|
198635
199593
|
refresh: { type: "string", description: "Project scan policy: auto, always, or never" },
|
|
198636
199594
|
agent: { type: "string", description: "Optional target agent for compatible workflow selection" },
|
|
198637
199595
|
json: { type: "boolean", description: "Emit machine-readable JSON output" },
|
|
198638
|
-
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON" }
|
|
199596
|
+
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON" },
|
|
199597
|
+
fallback: { type: "boolean", description: "Mark this as the one-shot MCP-unavailable fallback for the task" }
|
|
198639
199598
|
},
|
|
198640
199599
|
run: async ({ args }) => {
|
|
198641
199600
|
const asJson = !!args.json || !!args.briefJson;
|
|
198642
199601
|
const task = args.task?.trim() || args.input?.trim() || void 0;
|
|
198643
199602
|
try {
|
|
198644
199603
|
const { project, dataDir, reader: reader2 } = await getCliProjectContext();
|
|
199604
|
+
if (args.fallback) {
|
|
199605
|
+
const budget = new CliFallbackBudget();
|
|
199606
|
+
await budget.init(dataDir);
|
|
199607
|
+
const claim = budget.claim(project.id, task);
|
|
199608
|
+
if (!claim.allowed) {
|
|
199609
|
+
emitError(claim.reason ?? "CLI fallback budget exhausted for this task.", asJson);
|
|
199610
|
+
return;
|
|
199611
|
+
}
|
|
199612
|
+
}
|
|
198645
199613
|
const context = await buildAutoProjectContext({
|
|
198646
199614
|
project,
|
|
198647
199615
|
dataDir,
|
|
@@ -198699,7 +199667,8 @@ var init_resume = __esm({
|
|
|
198699
199667
|
refresh: { type: "string", description: "Project scan policy: auto, always, or never" },
|
|
198700
199668
|
agent: { type: "string", description: "Optional target agent for compatible workflow selection" },
|
|
198701
199669
|
json: { type: "boolean", description: "Emit machine-readable JSON output" },
|
|
198702
|
-
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON" }
|
|
199670
|
+
briefJson: { type: "boolean", description: "Emit only the bounded agent brief and receipt JSON" },
|
|
199671
|
+
fallback: { type: "boolean", description: "Mark this as the one-shot MCP-unavailable fallback for the task" }
|
|
198703
199672
|
},
|
|
198704
199673
|
async run({ args }) {
|
|
198705
199674
|
await context_default.run?.({
|
|
@@ -198710,6 +199679,7 @@ var init_resume = __esm({
|
|
|
198710
199679
|
agent: args.agent,
|
|
198711
199680
|
json: args.json,
|
|
198712
199681
|
briefJson: args.briefJson,
|
|
199682
|
+
fallback: args.fallback,
|
|
198713
199683
|
resume: true
|
|
198714
199684
|
},
|
|
198715
199685
|
rawArgs: [],
|
|
@@ -199965,6 +200935,166 @@ var init_knowledge = __esm({
|
|
|
199965
200935
|
}
|
|
199966
200936
|
});
|
|
199967
200937
|
|
|
200938
|
+
// src/cli/commands/evidence.ts
|
|
200939
|
+
var evidence_exports = {};
|
|
200940
|
+
__export(evidence_exports, {
|
|
200941
|
+
default: () => evidence_default
|
|
200942
|
+
});
|
|
200943
|
+
var evidence_default;
|
|
200944
|
+
var init_evidence = __esm({
|
|
200945
|
+
"src/cli/commands/evidence.ts"() {
|
|
200946
|
+
"use strict";
|
|
200947
|
+
init_esm_shims();
|
|
200948
|
+
init_dist2();
|
|
200949
|
+
init_obs_store();
|
|
200950
|
+
init_evidence_store();
|
|
200951
|
+
init_operator_shared();
|
|
200952
|
+
evidence_default = defineCommand({
|
|
200953
|
+
meta: { name: "evidence", description: "Inspect project-scoped evidence cards and provenance" },
|
|
200954
|
+
args: {
|
|
200955
|
+
action: { type: "positional", description: "list, get, sync, stale, or events", required: false },
|
|
200956
|
+
id: { type: "string", description: "Candidate id, usually an observation id" },
|
|
200957
|
+
paths: { type: "string", description: "Comma-separated changed paths for stale" },
|
|
200958
|
+
reason: { type: "string", description: "Why the source became stale" },
|
|
200959
|
+
query: { type: "string", description: "Search title/source fields" },
|
|
200960
|
+
limit: { type: "string", description: "Maximum cards/events" },
|
|
200961
|
+
json: { type: "boolean", description: "Emit JSON" }
|
|
200962
|
+
},
|
|
200963
|
+
async run({ args }) {
|
|
200964
|
+
const action = args.action || "list";
|
|
200965
|
+
const asJson = !!args.json;
|
|
200966
|
+
try {
|
|
200967
|
+
const context = action === "list" || action === "get" || action === "events" ? await getCliReadContext() : await getCliProjectContext({ searchIndex: false });
|
|
200968
|
+
const { project, dataDir } = context;
|
|
200969
|
+
const store2 = new EvidenceCardStore();
|
|
200970
|
+
await store2.init(dataDir);
|
|
200971
|
+
const limit2 = Math.min(100, Math.max(1, Number(args.limit || 20)));
|
|
200972
|
+
if (action === "sync") {
|
|
200973
|
+
const synced = store2.syncObservations(await getObservationStore().loadByProject(project.id));
|
|
200974
|
+
emitResult({ project, synced: synced.length }, `Synced ${synced.length} evidence card(s).`, asJson);
|
|
200975
|
+
return;
|
|
200976
|
+
}
|
|
200977
|
+
if (action === "stale") {
|
|
200978
|
+
const paths = String(args.paths || "").split(",").map((value) => value.trim()).filter(Boolean);
|
|
200979
|
+
const changed = store2.markStaleForPaths(project.id, paths, String(args.reason || "source file changed"));
|
|
200980
|
+
emitResult({ project, staleMarked: changed, paths }, `Marked ${changed} evidence card(s) stale.`, asJson);
|
|
200981
|
+
return;
|
|
200982
|
+
}
|
|
200983
|
+
const id = String(args.id || "").trim();
|
|
200984
|
+
if (action === "get" || action === "events") {
|
|
200985
|
+
if (!id) {
|
|
200986
|
+
emitError(`--id is required for evidence ${action}.`, asJson);
|
|
200987
|
+
return;
|
|
200988
|
+
}
|
|
200989
|
+
const card = store2.get(project.id, "observation", id);
|
|
200990
|
+
if (!card) {
|
|
200991
|
+
emitError(`Evidence card for observation ${id} was not found.`, asJson);
|
|
200992
|
+
return;
|
|
200993
|
+
}
|
|
200994
|
+
const result = action === "events" ? store2.listEvents(card.id, limit2) : { card, events: store2.listEvents(card.id) };
|
|
200995
|
+
emitResult({ project, result }, JSON.stringify(result, null, 2), asJson);
|
|
200996
|
+
return;
|
|
200997
|
+
}
|
|
200998
|
+
if (action !== "list") {
|
|
200999
|
+
emitError("action must be list, get, sync, stale, or events.", asJson);
|
|
201000
|
+
return;
|
|
201001
|
+
}
|
|
201002
|
+
const query = String(args.query || "").trim().toLowerCase();
|
|
201003
|
+
const cards = store2.list(project.id, { limit: 100 }).filter((card) => !query || [card.title, card.summary, card.sourceRef, card.locator || ""].join(" ").toLowerCase().includes(query)).slice(0, limit2);
|
|
201004
|
+
emitResult({ project, cards }, cards.length === 0 ? "No evidence cards found." : cards.map((card) => `- ${card.candidateId} ${card.title} [${card.freshness}] ${card.sourceRef}`).join("\n"), asJson);
|
|
201005
|
+
} catch (error40) {
|
|
201006
|
+
emitError(error40 instanceof Error ? error40.message : String(error40), asJson);
|
|
201007
|
+
}
|
|
201008
|
+
}
|
|
201009
|
+
});
|
|
201010
|
+
}
|
|
201011
|
+
});
|
|
201012
|
+
|
|
201013
|
+
// src/cli/commands/feedback.ts
|
|
201014
|
+
var feedback_exports2 = {};
|
|
201015
|
+
__export(feedback_exports2, {
|
|
201016
|
+
default: () => feedback_default
|
|
201017
|
+
});
|
|
201018
|
+
var signals, feedback_default;
|
|
201019
|
+
var init_feedback2 = __esm({
|
|
201020
|
+
"src/cli/commands/feedback.ts"() {
|
|
201021
|
+
"use strict";
|
|
201022
|
+
init_esm_shims();
|
|
201023
|
+
init_dist2();
|
|
201024
|
+
init_feedback();
|
|
201025
|
+
init_operator_shared();
|
|
201026
|
+
signals = ["user-correction", "verification-success", "verification-failure", "code-change", "used", "not-used", "code-conflict", "strengthen", "weaken", "revoke"];
|
|
201027
|
+
feedback_default = defineCommand({
|
|
201028
|
+
meta: { name: "feedback", description: "Record and audit memory feedback" },
|
|
201029
|
+
args: {
|
|
201030
|
+
action: { type: "positional", description: "record, show, or audit", required: false },
|
|
201031
|
+
id: { type: "string", description: "Candidate id" },
|
|
201032
|
+
kind: { type: "string", description: "observation, claim, durable-memory, or workflow" },
|
|
201033
|
+
signal: { type: "string", description: "Feedback signal" },
|
|
201034
|
+
source: { type: "string", description: "Source reference for the feedback" },
|
|
201035
|
+
actor: { type: "string", description: "Actor id or human label" },
|
|
201036
|
+
note: { type: "string", description: "Short audit note" },
|
|
201037
|
+
targetEventId: { type: "string", description: "Event id to revoke" },
|
|
201038
|
+
limit: { type: "string", description: "Maximum audit rows" },
|
|
201039
|
+
json: { type: "boolean", description: "Emit JSON" }
|
|
201040
|
+
},
|
|
201041
|
+
async run({ args }) {
|
|
201042
|
+
const action = args.action || "show";
|
|
201043
|
+
const asJson = !!args.json;
|
|
201044
|
+
try {
|
|
201045
|
+
const context = action === "show" || action === "audit" ? await getCliReadContext() : await getCliProjectContext({ searchIndex: false });
|
|
201046
|
+
const { project, dataDir } = context;
|
|
201047
|
+
const id = String(args.id || "").trim();
|
|
201048
|
+
const kind = String(args.kind || "observation").trim() || "observation";
|
|
201049
|
+
if (!id) {
|
|
201050
|
+
emitError("--id is required.", asJson);
|
|
201051
|
+
return;
|
|
201052
|
+
}
|
|
201053
|
+
if (!["observation", "claim", "durable-memory", "workflow"].includes(kind)) {
|
|
201054
|
+
emitError("Invalid --kind.", asJson);
|
|
201055
|
+
return;
|
|
201056
|
+
}
|
|
201057
|
+
const store2 = new MemoryFeedbackStore();
|
|
201058
|
+
await store2.init(dataDir);
|
|
201059
|
+
if (action === "show") {
|
|
201060
|
+
const result2 = store2.getState(project.id, kind, id);
|
|
201061
|
+
emitResult({ project, result: result2 }, JSON.stringify(result2, null, 2), asJson);
|
|
201062
|
+
return;
|
|
201063
|
+
}
|
|
201064
|
+
if (action === "audit") {
|
|
201065
|
+
const result2 = store2.audit(project.id, kind, id, Number(args.limit || 100));
|
|
201066
|
+
emitResult({ project, result: result2 }, JSON.stringify(result2, null, 2), asJson);
|
|
201067
|
+
return;
|
|
201068
|
+
}
|
|
201069
|
+
if (action !== "record") {
|
|
201070
|
+
emitError("action must be record, show, or audit.", asJson);
|
|
201071
|
+
return;
|
|
201072
|
+
}
|
|
201073
|
+
const signal = String(args.signal || "").trim();
|
|
201074
|
+
const sourceRef = String(args.source || "").trim();
|
|
201075
|
+
if (!signals.includes(signal) || !sourceRef) {
|
|
201076
|
+
emitError(`record requires --signal (${signals.join(", ")}) and --source.`, asJson);
|
|
201077
|
+
return;
|
|
201078
|
+
}
|
|
201079
|
+
const result = store2.record({
|
|
201080
|
+
projectId: project.id,
|
|
201081
|
+
candidateKind: kind,
|
|
201082
|
+
candidateId: id,
|
|
201083
|
+
signal,
|
|
201084
|
+
sourceRef,
|
|
201085
|
+
...args.actor ? { actor: String(args.actor) } : {},
|
|
201086
|
+
...args.note ? { note: String(args.note) } : {},
|
|
201087
|
+
...args.targetEventId ? { targetEventId: String(args.targetEventId) } : {}
|
|
201088
|
+
});
|
|
201089
|
+
emitResult({ project, result }, `Recorded ${signal} for ${kind}:${id}; weight=${result.state.weight.toFixed(2)}.`, asJson);
|
|
201090
|
+
} catch (error40) {
|
|
201091
|
+
emitError(error40 instanceof Error ? error40.message : String(error40), asJson);
|
|
201092
|
+
}
|
|
201093
|
+
}
|
|
201094
|
+
});
|
|
201095
|
+
}
|
|
201096
|
+
});
|
|
201097
|
+
|
|
199968
201098
|
// src/cli/commands/reasoning.ts
|
|
199969
201099
|
var reasoning_exports = {};
|
|
199970
201100
|
__export(reasoning_exports, {
|
|
@@ -203165,7 +204295,7 @@ __export(planner_exports, {
|
|
|
203165
204295
|
materializeTaskGraph: () => materializeTaskGraph,
|
|
203166
204296
|
seedAutonomousPipeline: () => seedAutonomousPipeline
|
|
203167
204297
|
});
|
|
203168
|
-
import { randomUUID as
|
|
204298
|
+
import { randomUUID as randomUUID18 } from "crypto";
|
|
203169
204299
|
function isPlannerTask(metadata) {
|
|
203170
204300
|
if (!metadata) return null;
|
|
203171
204301
|
try {
|
|
@@ -203223,7 +204353,7 @@ function seedAutonomousPipeline(teamStore, projectId, config2, opts) {
|
|
|
203223
204353
|
const maxIterations = config2.maxIterations ?? 3;
|
|
203224
204354
|
const taskBudget = config2.taskBudget ?? 15;
|
|
203225
204355
|
const structuredPlan = opts?.structuredPlan ?? true;
|
|
203226
|
-
const pipelineId =
|
|
204356
|
+
const pipelineId = randomUUID18();
|
|
203227
204357
|
const meta = {
|
|
203228
204358
|
plannerType: "plan",
|
|
203229
204359
|
pipelineId,
|
|
@@ -204142,11 +205272,11 @@ __export(receipt_service_exports, {
|
|
|
204142
205272
|
buildHandoffReceipt: () => buildHandoffReceipt,
|
|
204143
205273
|
formatHandoffReceipt: () => formatHandoffReceipt
|
|
204144
205274
|
});
|
|
204145
|
-
import { createHash as
|
|
205275
|
+
import { createHash as createHash16 } from "crypto";
|
|
204146
205276
|
import { existsSync as existsSync21, readFileSync as readFileSync13 } from "fs";
|
|
204147
205277
|
import path36 from "path";
|
|
204148
205278
|
function sha256(value) {
|
|
204149
|
-
return `sha256:${
|
|
205279
|
+
return `sha256:${createHash16("sha256").update(value).digest("hex")}`;
|
|
204150
205280
|
}
|
|
204151
205281
|
function hashId(projectId, id) {
|
|
204152
205282
|
return sha256(`${projectId}:obs:${id}`);
|
|
@@ -204367,6 +205497,10 @@ var init_tool_profile = __esm({
|
|
|
204367
205497
|
// multimodal support to one additional schema rather than enabling lite.
|
|
204368
205498
|
memorix_session_start: ["micro", "lite", "team", "full"],
|
|
204369
205499
|
memorix_media: ["micro", "lite", "team", "full"],
|
|
205500
|
+
// Evidence and feedback are deliberate operator/context-control surfaces;
|
|
205501
|
+
// keep the default micro profile at its nine-tool token budget.
|
|
205502
|
+
memorix_evidence: ["lite", "team", "full"],
|
|
205503
|
+
memorix_feedback: ["lite", "team", "full"],
|
|
204370
205504
|
// ── lite: extended solo memory surface ────────────────────────────
|
|
204371
205505
|
memorix_graph_context: ["lite", "team", "full"],
|
|
204372
205506
|
memorix_timeline: ["lite", "team", "full"],
|
|
@@ -216321,9 +217455,9 @@ var init_graph_scope = __esm({
|
|
|
216321
217455
|
});
|
|
216322
217456
|
|
|
216323
217457
|
// src/rules/utils.ts
|
|
216324
|
-
import { createHash as
|
|
217458
|
+
import { createHash as createHash17 } from "crypto";
|
|
216325
217459
|
function hashContent2(content) {
|
|
216326
|
-
return
|
|
217460
|
+
return createHash17("sha256").update(content.trim()).digest("hex").substring(0, 16);
|
|
216327
217461
|
}
|
|
216328
217462
|
function generateRuleId(source, filePath) {
|
|
216329
217463
|
const sanitized = filePath.replace(/[\/\\]/g, "-").replace(/^\./, "");
|
|
@@ -218027,6 +219161,18 @@ var init_cleanup = __esm({
|
|
|
218027
219161
|
});
|
|
218028
219162
|
|
|
218029
219163
|
// src/dashboard/maintenance.ts
|
|
219164
|
+
var maintenance_exports = {};
|
|
219165
|
+
__export(maintenance_exports, {
|
|
219166
|
+
DashboardMaintenanceError: () => DashboardMaintenanceError,
|
|
219167
|
+
executeCleanup: () => executeCleanup,
|
|
219168
|
+
executeConsolidate: () => executeConsolidate,
|
|
219169
|
+
executeDeduplicate: () => executeDeduplicate,
|
|
219170
|
+
executeRetentionArchive: () => executeRetentionArchive,
|
|
219171
|
+
previewCleanup: () => previewCleanup,
|
|
219172
|
+
previewConsolidate: () => previewConsolidate,
|
|
219173
|
+
previewDeduplicate: () => previewDeduplicate,
|
|
219174
|
+
previewRetentionArchive: () => previewRetentionArchive
|
|
219175
|
+
});
|
|
218030
219176
|
import { createHmac, randomBytes, timingSafeEqual } from "crypto";
|
|
218031
219177
|
function reader(projectId) {
|
|
218032
219178
|
return { projectId };
|
|
@@ -218268,6 +219414,23 @@ var init_maintenance = __esm({
|
|
|
218268
219414
|
}
|
|
218269
219415
|
});
|
|
218270
219416
|
|
|
219417
|
+
// src/dashboard/config-provenance.ts
|
|
219418
|
+
function resolveDashboardKeySource({ value, envKeys, configSource }) {
|
|
219419
|
+
for (const envKey of envKeys) {
|
|
219420
|
+
const envValue = process.env[envKey];
|
|
219421
|
+
if (envValue !== value) continue;
|
|
219422
|
+
return getLoadedEnvValue(envKey) === envValue ? ".env" : `env:${envKey}`;
|
|
219423
|
+
}
|
|
219424
|
+
return configSource;
|
|
219425
|
+
}
|
|
219426
|
+
var init_config_provenance = __esm({
|
|
219427
|
+
"src/dashboard/config-provenance.ts"() {
|
|
219428
|
+
"use strict";
|
|
219429
|
+
init_esm_shims();
|
|
219430
|
+
init_dotenv_loader();
|
|
219431
|
+
}
|
|
219432
|
+
});
|
|
219433
|
+
|
|
218271
219434
|
// src/dashboard/project-classification.ts
|
|
218272
219435
|
var project_classification_exports = {};
|
|
218273
219436
|
__export(project_classification_exports, {
|
|
@@ -219047,6 +220210,20 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
219047
220210
|
sendJson(res, observations2);
|
|
219048
220211
|
break;
|
|
219049
220212
|
}
|
|
220213
|
+
case "/evidence": {
|
|
220214
|
+
const observations2 = filterDashboardObservations(
|
|
220215
|
+
await getObservationStore().loadByProject(effectiveProjectId, { status: "active" }),
|
|
220216
|
+
effectiveProjectId
|
|
220217
|
+
);
|
|
220218
|
+
const evidenceStore = new EvidenceCardStore();
|
|
220219
|
+
await evidenceStore.init(effectiveDataDir);
|
|
220220
|
+
evidenceStore.syncObservations(observations2);
|
|
220221
|
+
const query = url2.searchParams.get("q") || "";
|
|
220222
|
+
const limit2 = Number(url2.searchParams.get("limit") || 20);
|
|
220223
|
+
const cards = evidenceStore.list(effectiveProjectId, { limit: Math.min(100, Math.max(1, limit2)) }).filter((card) => !query || [card.title, card.summary, card.sourceRef, card.locator ?? ""].join(" ").toLowerCase().includes(query.toLowerCase()));
|
|
220224
|
+
sendJson(res, { cards, projectId: effectiveProjectId });
|
|
220225
|
+
break;
|
|
220226
|
+
}
|
|
219050
220227
|
case "/sessions": {
|
|
219051
220228
|
const allSessions = await getSessionStore().loadAll();
|
|
219052
220229
|
const sessions = filterByProject(allSessions, effectiveProjectId);
|
|
@@ -219094,8 +220271,13 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
219094
220271
|
filesModified: o4.filesModified
|
|
219095
220272
|
}));
|
|
219096
220273
|
const retentionReferenceTime = new Date(now3);
|
|
220274
|
+
const feedback = new MemoryFeedbackStore();
|
|
220275
|
+
await feedback.init(effectiveDataDir).catch(() => void 0);
|
|
219097
220276
|
const retention = summarizeRetentionProjections(
|
|
219098
|
-
observations2.filter((observation) => observation.type !== "probe").map((observation) => projectObservationRetention(observation, {
|
|
220277
|
+
observations2.filter((observation) => observation.type !== "probe").map((observation) => projectObservationRetention(observation, {
|
|
220278
|
+
referenceTime: retentionReferenceTime,
|
|
220279
|
+
feedback: feedback.getState(effectiveProjectId, "observation", String(observation.id))
|
|
220280
|
+
}))
|
|
219099
220281
|
);
|
|
219100
220282
|
const retentionSummary = {
|
|
219101
220283
|
active: retention.active,
|
|
@@ -219189,9 +220371,14 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
219189
220371
|
effectiveProjectId
|
|
219190
220372
|
);
|
|
219191
220373
|
const referenceTime = /* @__PURE__ */ new Date();
|
|
220374
|
+
const feedback = new MemoryFeedbackStore();
|
|
220375
|
+
await feedback.init(effectiveDataDir).catch(() => void 0);
|
|
219192
220376
|
const rows = observations2.filter((observation) => observation.type !== "probe").map((observation) => ({
|
|
219193
220377
|
observation,
|
|
219194
|
-
retention: projectObservationRetention(observation, {
|
|
220378
|
+
retention: projectObservationRetention(observation, {
|
|
220379
|
+
referenceTime,
|
|
220380
|
+
feedback: feedback.getState(effectiveProjectId, "observation", String(observation.id))
|
|
220381
|
+
})
|
|
219195
220382
|
})).sort((a4, b4) => b4.retention.displayScore - a4.retention.displayScore);
|
|
219196
220383
|
const summary = summarizeRetentionProjections(rows.map((row) => row.retention));
|
|
219197
220384
|
const scored = rows.map(({ observation, retention }) => ({
|
|
@@ -219262,23 +220449,13 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
219262
220449
|
const os9 = await import("os");
|
|
219263
220450
|
const { existsSync: existsSync34 } = await import("fs");
|
|
219264
220451
|
const { join: join34 } = await import("path");
|
|
219265
|
-
let yml = {};
|
|
219266
220452
|
const configProjectRoot = effectiveProjectRoot;
|
|
219267
|
-
|
|
219268
|
-
const { loadYamlConfig: loadYamlConfig2 } = await Promise.resolve().then(() => (init_yaml_loader(), yaml_loader_exports));
|
|
219269
|
-
yml = configProjectRoot ? loadYamlConfig2(configProjectRoot) : loadYamlConfig2(null);
|
|
219270
|
-
} catch {
|
|
219271
|
-
}
|
|
219272
|
-
if (configProjectRoot) {
|
|
219273
|
-
try {
|
|
219274
|
-
const { loadDotenv: loadDotenv2 } = await Promise.resolve().then(() => (init_dotenv_loader(), dotenv_loader_exports));
|
|
219275
|
-
loadDotenv2(configProjectRoot);
|
|
219276
|
-
} catch {
|
|
219277
|
-
}
|
|
219278
|
-
}
|
|
220453
|
+
const resolved = getResolvedConfig({ projectRoot: configProjectRoot });
|
|
219279
220454
|
const files = {
|
|
219280
220455
|
"project memorix.yml": { exists: false, path: "", unavailable: !configProjectRoot },
|
|
219281
220456
|
"user memorix.yml": { exists: false, path: "" },
|
|
220457
|
+
"project memorix.toml": { exists: false, path: "", unavailable: !configProjectRoot },
|
|
220458
|
+
"user config.toml": { exists: false, path: "" },
|
|
219282
220459
|
"project .env": { exists: false, path: "", unavailable: !configProjectRoot },
|
|
219283
220460
|
"user .env": { exists: false, path: "" },
|
|
219284
220461
|
"legacy config.json": { exists: false, path: "" }
|
|
@@ -219288,6 +220465,8 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
219288
220465
|
const paths = {
|
|
219289
220466
|
"project memorix.yml": configProjectRoot ? join34(configProjectRoot, "memorix.yml") : null,
|
|
219290
220467
|
"user memorix.yml": join34(home, ".memorix", "memorix.yml"),
|
|
220468
|
+
"project memorix.toml": configProjectRoot ? join34(configProjectRoot, "memorix.toml") : null,
|
|
220469
|
+
"user config.toml": join34(home, ".memorix", "config.toml"),
|
|
219291
220470
|
"project .env": configProjectRoot ? join34(configProjectRoot, ".env") : null,
|
|
219292
220471
|
"user .env": join34(home, ".memorix", ".env"),
|
|
219293
220472
|
"legacy config.json": join34(home, ".memorix", "config.json")
|
|
@@ -219302,67 +220481,61 @@ async function handleApi(req, res, dataDir, projectId, projectName, baseDir, pro
|
|
|
219302
220481
|
} catch {
|
|
219303
220482
|
}
|
|
219304
220483
|
const values = [];
|
|
219305
|
-
const
|
|
219306
|
-
|
|
219307
|
-
|
|
219308
|
-
|
|
219309
|
-
|
|
219310
|
-
|
|
219311
|
-
|
|
219312
|
-
|
|
219313
|
-
|
|
219314
|
-
|
|
219315
|
-
|
|
219316
|
-
|
|
219317
|
-
|
|
219318
|
-
|
|
219319
|
-
|
|
219320
|
-
|
|
219321
|
-
|
|
220484
|
+
const tomlSource = configProjectRoot && files["project memorix.toml"].exists ? "memorix.toml" : files["user config.toml"].exists ? "config.toml" : "default";
|
|
220485
|
+
const legacySource = files["project memorix.yml"].exists || files["user memorix.yml"].exists ? "memorix.yml" : files["legacy config.json"].exists ? "config.json" : "default";
|
|
220486
|
+
const configSource = resolved.sources.toml.length > 0 ? tomlSource : resolved.sources.legacy.length > 0 ? legacySource : "default";
|
|
220487
|
+
const source = (envKey) => resolveDashboardKeySource({
|
|
220488
|
+
value: process.env[envKey] ?? "",
|
|
220489
|
+
envKeys: [envKey],
|
|
220490
|
+
configSource
|
|
220491
|
+
});
|
|
220492
|
+
if (resolved.memory.llm.provider) values.push({ key: "llm.provider", value: resolved.memory.llm.provider, source: source("MEMORIX_LLM_PROVIDER") });
|
|
220493
|
+
if (resolved.memory.llm.model) values.push({ key: "llm.model", value: resolved.memory.llm.model, source: source("MEMORIX_LLM_MODEL") });
|
|
220494
|
+
const llmKey = resolved.memory.llm.apiKey;
|
|
220495
|
+
const memoryKeyEnv = [
|
|
220496
|
+
"MEMORIX_LLM_API_KEY",
|
|
220497
|
+
"MEMORIX_API_KEY",
|
|
220498
|
+
"OPENAI_API_KEY",
|
|
220499
|
+
"ANTHROPIC_API_KEY",
|
|
220500
|
+
...resolved.memory.llm.provider === "openrouter" || resolved.memory.llm.baseUrl?.includes("openrouter.ai") ? ["OPENROUTER_API_KEY"] : []
|
|
220501
|
+
];
|
|
219322
220502
|
if (llmKey) {
|
|
219323
|
-
|
|
219324
|
-
if (process.env.MEMORIX_LLM_API_KEY) src2 = await getEnvSource("MEMORIX_LLM_API_KEY");
|
|
219325
|
-
else if (process.env.MEMORIX_API_KEY) src2 = await getEnvSource("MEMORIX_API_KEY");
|
|
219326
|
-
else if (yml.llm?.apiKey) src2 = "memorix.yml (move to .env!)";
|
|
219327
|
-
else if (process.env.OPENAI_API_KEY) src2 = await getEnvSource("OPENAI_API_KEY");
|
|
220503
|
+
const src2 = resolveDashboardKeySource({ value: llmKey, envKeys: memoryKeyEnv, configSource });
|
|
219328
220504
|
values.push({ key: "llm.apiKey", value: "****" + llmKey.slice(-4), source: src2, sensitive: true });
|
|
219329
220505
|
} else {
|
|
219330
220506
|
values.push({ key: "llm.apiKey", value: "not set", source: "none" });
|
|
219331
220507
|
}
|
|
219332
|
-
|
|
219333
|
-
|
|
219334
|
-
|
|
219335
|
-
|
|
219336
|
-
|
|
219337
|
-
|
|
219338
|
-
|
|
219339
|
-
}
|
|
219340
|
-
const agentModel = process.env.MEMORIX_AGENT_MODEL || process.env.MEMORIX_AGENT_LLM_MODEL || yml.agent?.model;
|
|
219341
|
-
if (agentModel) {
|
|
219342
|
-
let source;
|
|
219343
|
-
if (process.env.MEMORIX_AGENT_MODEL) source = await getEnvSource("MEMORIX_AGENT_MODEL");
|
|
219344
|
-
else if (process.env.MEMORIX_AGENT_LLM_MODEL) source = `${await getEnvSource("MEMORIX_AGENT_LLM_MODEL")} (legacy)`;
|
|
219345
|
-
else source = yml.agent?.model ? "memorix.yml" : "default";
|
|
219346
|
-
values.push({ key: "agent.model", value: agentModel, source });
|
|
219347
|
-
}
|
|
219348
|
-
const agentKey = process.env.MEMORIX_AGENT_API_KEY || process.env.MEMORIX_AGENT_LLM_API_KEY || yml.agent?.apiKey;
|
|
220508
|
+
if (resolved.agent.provider) {
|
|
220509
|
+
values.push({ key: "agent.provider", value: resolved.agent.provider, source: source("MEMORIX_AGENT_PROVIDER") });
|
|
220510
|
+
}
|
|
220511
|
+
if (resolved.agent.model) {
|
|
220512
|
+
values.push({ key: "agent.model", value: resolved.agent.model, source: source("MEMORIX_AGENT_MODEL") });
|
|
220513
|
+
}
|
|
220514
|
+
const agentKey = resolved.agent.apiKey;
|
|
219349
220515
|
if (agentKey) {
|
|
219350
|
-
|
|
219351
|
-
|
|
219352
|
-
|
|
219353
|
-
|
|
220516
|
+
const src2 = resolveDashboardKeySource({
|
|
220517
|
+
value: agentKey,
|
|
220518
|
+
envKeys: ["MEMORIX_AGENT_API_KEY", "MEMORIX_AGENT_LLM_API_KEY"],
|
|
220519
|
+
configSource
|
|
220520
|
+
});
|
|
219354
220521
|
values.push({ key: "agent.apiKey", value: "****" + agentKey.slice(-4), source: src2, sensitive: true });
|
|
219355
220522
|
} else {
|
|
219356
|
-
values.push({
|
|
219357
|
-
|
|
219358
|
-
|
|
219359
|
-
|
|
219360
|
-
|
|
219361
|
-
|
|
219362
|
-
|
|
219363
|
-
if (
|
|
219364
|
-
|
|
219365
|
-
|
|
220523
|
+
values.push({
|
|
220524
|
+
key: "agent.apiKey",
|
|
220525
|
+
value: "fallback to llm.apiKey",
|
|
220526
|
+
source: llmKey ? resolveDashboardKeySource({ value: llmKey, envKeys: memoryKeyEnv, configSource }) : "default"
|
|
220527
|
+
});
|
|
220528
|
+
}
|
|
220529
|
+
values.push({ key: "embedding.provider", value: resolved.embedding.provider || "off", source: source("MEMORIX_EMBEDDING") });
|
|
220530
|
+
if (resolved.embedding.model) values.push({ key: "embedding.model", value: resolved.embedding.model, source: source("MEMORIX_EMBEDDING_MODEL") });
|
|
220531
|
+
if (resolved.rerank.provider !== "off") {
|
|
220532
|
+
values.push({ key: "rerank.provider", value: resolved.rerank.provider, source: source("MEMORIX_RERANK_PROVIDER") });
|
|
220533
|
+
if (resolved.rerank.model) values.push({ key: "rerank.model", value: resolved.rerank.model, source: source("MEMORIX_RERANK_MODEL") });
|
|
220534
|
+
}
|
|
220535
|
+
values.push({ key: "git.autoHook", value: String(resolved.git.autoHook ?? false), source: configSource });
|
|
220536
|
+
values.push({ key: "git.skipMergeCommits", value: String(resolved.git.skipMergeCommits ?? true), source: configSource });
|
|
220537
|
+
values.push({ key: "server.transport", value: resolved.server.transport || "stdio", source: configSource });
|
|
220538
|
+
values.push({ key: "server.dashboard", value: String(resolved.server.dashboard ?? true), source: configSource });
|
|
219366
220539
|
sendJson(res, { files, values });
|
|
219367
220540
|
break;
|
|
219368
220541
|
}
|
|
@@ -219810,10 +220983,14 @@ var init_server3 = __esm({
|
|
|
219810
220983
|
init_dotenv_loader();
|
|
219811
220984
|
init_yaml_loader();
|
|
219812
220985
|
init_yaml_loader();
|
|
220986
|
+
init_resolved_config();
|
|
219813
220987
|
init_graph_scope();
|
|
219814
220988
|
init_retention();
|
|
219815
220989
|
init_visibility();
|
|
220990
|
+
init_evidence_store();
|
|
220991
|
+
init_feedback();
|
|
219816
220992
|
init_maintenance();
|
|
220993
|
+
init_config_provenance();
|
|
219817
220994
|
MIME_TYPES = {
|
|
219818
220995
|
".html": "text/html; charset=utf-8",
|
|
219819
220996
|
".css": "text/css; charset=utf-8",
|
|
@@ -259680,8 +260857,7 @@ async function callVisionLLM(systemPrompt, imageBase64, mimeType) {
|
|
|
259680
260857
|
if (!apiKey) {
|
|
259681
260858
|
throw new Error("No LLM API key configured for image analysis.");
|
|
259682
260859
|
}
|
|
259683
|
-
|
|
259684
|
-
if (!baseUrl.endsWith("/v1")) baseUrl += "/v1";
|
|
260860
|
+
const baseUrl = normalizeOpenAICompatibleBaseUrl(getLLMBaseUrl("https://api.openai.com/v1"));
|
|
259685
260861
|
const model = getLLMModel("gpt-4o");
|
|
259686
260862
|
const response = await fetch(`${baseUrl}/chat/completions`, {
|
|
259687
260863
|
method: "POST",
|
|
@@ -259846,7 +261022,7 @@ __export(server_exports2, {
|
|
|
259846
261022
|
createMemorixServer: () => createMemorixServer,
|
|
259847
261023
|
shouldAwaitProjectRuntime: () => shouldAwaitProjectRuntime
|
|
259848
261024
|
});
|
|
259849
|
-
import { createHash as
|
|
261025
|
+
import { createHash as createHash18 } from "crypto";
|
|
259850
261026
|
function formatFormationStageDurations(stageDurationsMs) {
|
|
259851
261027
|
const orderedStages = ["extract", "resolve", "evaluate"];
|
|
259852
261028
|
const parts = orderedStages.filter((stage) => stageDurationsMs[stage] !== void 0).map((stage) => `${stage}=${stageDurationsMs[stage]}ms`);
|
|
@@ -259928,7 +261104,7 @@ function coerceObjectArray(val) {
|
|
|
259928
261104
|
return [];
|
|
259929
261105
|
}
|
|
259930
261106
|
function createDeterministicInstanceId(projectId, agentType, agentName) {
|
|
259931
|
-
const digest2 =
|
|
261107
|
+
const digest2 = createHash18("sha256").update(projectId).update("\n").update(agentType).update("\n").update(agentName ?? "").digest("hex").slice(0, 24);
|
|
259932
261108
|
return `auto-${digest2}`;
|
|
259933
261109
|
}
|
|
259934
261110
|
function shouldAwaitProjectRuntime(toolName) {
|
|
@@ -260220,7 +261396,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
260220
261396
|
};
|
|
260221
261397
|
const server = existingServer ?? new McpServer({
|
|
260222
261398
|
name: "memorix",
|
|
260223
|
-
version: true ? "1.
|
|
261399
|
+
version: true ? "1.8.0" : "1.0.1"
|
|
260224
261400
|
});
|
|
260225
261401
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
260226
261402
|
server.registerTool = ((name, ...args) => {
|
|
@@ -263399,7 +264575,7 @@ ${json4}
|
|
|
263399
264575
|
dashboardRunning = true;
|
|
263400
264576
|
const { exec: execCmd } = await import("child_process");
|
|
263401
264577
|
const openCmd = process.platform === "win32" ? `start "" "${url2}"` : process.platform === "darwin" ? `open "${url2}"` : `xdg-open "${url2}"`;
|
|
263402
|
-
execCmd(openCmd, () => {
|
|
264578
|
+
execCmd(openCmd, { windowsHide: true }, () => {
|
|
263403
264579
|
});
|
|
263404
264580
|
return {
|
|
263405
264581
|
content: [{
|
|
@@ -263423,6 +264599,113 @@ ${json4}
|
|
|
263423
264599
|
}
|
|
263424
264600
|
}
|
|
263425
264601
|
);
|
|
264602
|
+
server.registerTool(
|
|
264603
|
+
"memorix_evidence",
|
|
264604
|
+
{
|
|
264605
|
+
title: "Evidence Cards",
|
|
264606
|
+
description: "Inspect the bounded, project-scoped provenance cards behind Memorix context. Use list for a compact index, get/events for one source, sync to repair the projection, and stale when known source files changed. Cards expose sourceRef, locator, capturedHash, and freshness.",
|
|
264607
|
+
inputSchema: {
|
|
264608
|
+
action: external_exports2.enum(["list", "get", "sync", "stale", "events"]).describe("Evidence operation"),
|
|
264609
|
+
candidateKind: external_exports2.enum(["observation", "code", "git", "test", "document", "workflow", "graph"]).optional().default("observation"),
|
|
264610
|
+
candidateId: external_exports2.string().optional().describe("Candidate id, usually an observation id"),
|
|
264611
|
+
query: external_exports2.string().optional().describe("Optional title/source query for list"),
|
|
264612
|
+
paths: external_exports2.array(external_exports2.string()).max(200).optional().describe("Changed source paths for stale"),
|
|
264613
|
+
reason: external_exports2.string().max(500).optional().describe("Why evidence became stale"),
|
|
264614
|
+
limit: external_exports2.number().int().positive().max(100).optional().default(20)
|
|
264615
|
+
}
|
|
264616
|
+
},
|
|
264617
|
+
async ({ action, candidateKind, candidateId, query, paths, reason, limit: limit2 }) => {
|
|
264618
|
+
const unresolved = requireResolvedProject("inspect evidence cards for the current project");
|
|
264619
|
+
if (unresolved) return unresolved;
|
|
264620
|
+
const cards = new EvidenceCardStore();
|
|
264621
|
+
await cards.init(projectDir2);
|
|
264622
|
+
if (action === "sync") {
|
|
264623
|
+
const observations2 = await getObservationStore().loadByProject(project.id);
|
|
264624
|
+
const synced = cards.syncObservations(observations2);
|
|
264625
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, synced: synced.length, cards: synced.slice(0, limit2 ?? 20) }, null, 2) }] };
|
|
264626
|
+
}
|
|
264627
|
+
if (action === "stale") {
|
|
264628
|
+
const changed = cards.markStaleForPaths(project.id, paths ?? [], reason ?? "source file changed");
|
|
264629
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, staleMarked: changed, paths: paths ?? [] }, null, 2) }] };
|
|
264630
|
+
}
|
|
264631
|
+
if (action === "get") {
|
|
264632
|
+
if (!candidateId?.trim()) return { content: [{ type: "text", text: "candidateId is required for evidence get." }], isError: true };
|
|
264633
|
+
const card = cards.get(project.id, candidateKind ?? "observation", candidateId.trim());
|
|
264634
|
+
if (!card) return { content: [{ type: "text", text: "Evidence card not found." }], isError: true };
|
|
264635
|
+
return { content: [{ type: "text", text: JSON.stringify({ card, events: cards.listEvents(card.id), projectId: project.id }, null, 2) }] };
|
|
264636
|
+
}
|
|
264637
|
+
if (action === "events") {
|
|
264638
|
+
if (!candidateId?.trim()) return { content: [{ type: "text", text: "candidateId is required for evidence events." }], isError: true };
|
|
264639
|
+
const card = cards.get(project.id, candidateKind ?? "observation", candidateId.trim());
|
|
264640
|
+
if (!card) return { content: [{ type: "text", text: "Evidence card not found." }], isError: true };
|
|
264641
|
+
return { content: [{ type: "text", text: JSON.stringify(cards.listEvents(card.id, limit2), null, 2) }] };
|
|
264642
|
+
}
|
|
264643
|
+
const needle = query?.trim().toLowerCase();
|
|
264644
|
+
const listed = cards.list(project.id, { limit: Math.max(limit2 ?? 20, 100) }).filter((card) => !needle || [card.title, card.summary, card.sourceRef, card.locator ?? ""].join(" ").toLowerCase().includes(needle)).slice(0, limit2 ?? 20);
|
|
264645
|
+
return { content: [{ type: "text", text: JSON.stringify({ projectId: project.id, cards: listed }, null, 2) }] };
|
|
264646
|
+
}
|
|
264647
|
+
);
|
|
264648
|
+
server.registerTool(
|
|
264649
|
+
"memorix_feedback",
|
|
264650
|
+
{
|
|
264651
|
+
title: "Memory Feedback",
|
|
264652
|
+
description: "Record or inspect auditable memory outcomes. Positive verification/use strengthens recall; correction, conflict, source change, or weaken lowers it. Use revoke with targetEventId to undo one prior signal without deleting audit history.",
|
|
264653
|
+
inputSchema: {
|
|
264654
|
+
action: external_exports2.enum(["record", "show", "audit"]).describe("Feedback operation"),
|
|
264655
|
+
candidateKind: external_exports2.enum(["observation", "claim", "durable-memory", "workflow"]).optional().default("observation"),
|
|
264656
|
+
candidateId: external_exports2.string().describe("Memory or knowledge candidate id"),
|
|
264657
|
+
signal: external_exports2.enum(["user-correction", "verification-success", "verification-failure", "code-change", "used", "not-used", "code-conflict", "strengthen", "weaken", "revoke"]).optional(),
|
|
264658
|
+
sourceRef: external_exports2.string().max(500).optional().describe("Source of this feedback, such as test:run-42 or user:chat"),
|
|
264659
|
+
actor: external_exports2.string().max(200).optional(),
|
|
264660
|
+
note: external_exports2.string().max(2e3).optional(),
|
|
264661
|
+
targetEventId: external_exports2.string().optional().describe("Existing event id when action=record and signal=revoke"),
|
|
264662
|
+
limit: external_exports2.number().int().positive().max(200).optional().default(100)
|
|
264663
|
+
}
|
|
264664
|
+
},
|
|
264665
|
+
async ({ action, candidateKind, candidateId, signal, sourceRef, actor, note, targetEventId, limit: limit2 }) => {
|
|
264666
|
+
const unresolved = requireResolvedProject("record memory feedback for the current project");
|
|
264667
|
+
if (unresolved) return unresolved;
|
|
264668
|
+
const feedback = new MemoryFeedbackStore();
|
|
264669
|
+
await feedback.init(projectDir2);
|
|
264670
|
+
const kind = candidateKind ?? "observation";
|
|
264671
|
+
if (action === "show") {
|
|
264672
|
+
return { content: [{ type: "text", text: JSON.stringify(feedback.getState(project.id, kind, candidateId), null, 2) }] };
|
|
264673
|
+
}
|
|
264674
|
+
if (action === "audit") {
|
|
264675
|
+
return { content: [{ type: "text", text: JSON.stringify(feedback.audit(project.id, kind, candidateId, limit2), null, 2) }] };
|
|
264676
|
+
}
|
|
264677
|
+
if (!signal || !sourceRef?.trim()) {
|
|
264678
|
+
return { content: [{ type: "text", text: "record requires signal and sourceRef." }], isError: true };
|
|
264679
|
+
}
|
|
264680
|
+
try {
|
|
264681
|
+
const result = feedback.record({
|
|
264682
|
+
projectId: project.id,
|
|
264683
|
+
candidateKind: kind,
|
|
264684
|
+
candidateId,
|
|
264685
|
+
signal,
|
|
264686
|
+
sourceRef,
|
|
264687
|
+
...actor || currentAgentId ? { actor: actor ?? currentAgentId } : {},
|
|
264688
|
+
...note ? { note } : {},
|
|
264689
|
+
...targetEventId ? { targetEventId } : {}
|
|
264690
|
+
});
|
|
264691
|
+
if (kind === "observation") {
|
|
264692
|
+
const cards = new EvidenceCardStore();
|
|
264693
|
+
await cards.init(projectDir2);
|
|
264694
|
+
const card = cards.get(project.id, "observation", candidateId);
|
|
264695
|
+
if (card) {
|
|
264696
|
+
const verification = signal === "verification-success" || signal === "strengthen" ? "verified" : signal === "user-correction" || signal === "code-conflict" || signal === "weaken" ? "conflicted" : card.verification;
|
|
264697
|
+
cards.recordEvent(project.id, card.id, `feedback:${signal}`, note);
|
|
264698
|
+
if (verification !== card.verification) {
|
|
264699
|
+
cards.setVerification(project.id, card.id, verification);
|
|
264700
|
+
}
|
|
264701
|
+
}
|
|
264702
|
+
}
|
|
264703
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
264704
|
+
} catch (error40) {
|
|
264705
|
+
return { content: [{ type: "text", text: error40 instanceof Error ? error40.message : String(error40) }], isError: true };
|
|
264706
|
+
}
|
|
264707
|
+
}
|
|
264708
|
+
);
|
|
263426
264709
|
if (teamFeaturesEnabled) {
|
|
263427
264710
|
const { initTeamStore: initTeamStore2 } = await Promise.resolve().then(() => (init_team_store(), team_store_exports));
|
|
263428
264711
|
initTeamStoreForProject = initTeamStore2;
|
|
@@ -264478,6 +265761,8 @@ var init_server4 = __esm({
|
|
|
264478
265761
|
init_launch_root();
|
|
264479
265762
|
init_aliases();
|
|
264480
265763
|
init_persistence();
|
|
265764
|
+
init_evidence_store();
|
|
265765
|
+
init_feedback();
|
|
264481
265766
|
init_syncer();
|
|
264482
265767
|
init_engine5();
|
|
264483
265768
|
init_tool_profile();
|
|
@@ -264964,6 +266249,35 @@ var init_serve = __esm({
|
|
|
264964
266249
|
}
|
|
264965
266250
|
});
|
|
264966
266251
|
|
|
266252
|
+
// src/server/mcp-diagnostics.ts
|
|
266253
|
+
function getMcpDiagnostics() {
|
|
266254
|
+
return {
|
|
266255
|
+
serverName: MCP_SERVER_NAME,
|
|
266256
|
+
protocol: {
|
|
266257
|
+
current: CURRENT_MCP_PROTOCOL_VERSION,
|
|
266258
|
+
legacy: LEGACY_MCP_PROTOCOL_VERSION,
|
|
266259
|
+
statelessRequests: "supported",
|
|
266260
|
+
statefulStreamableHttp: "supported"
|
|
266261
|
+
},
|
|
266262
|
+
capabilities: {
|
|
266263
|
+
tasks: "unsupported",
|
|
266264
|
+
polling: "unsupported",
|
|
266265
|
+
listCache: "supported",
|
|
266266
|
+
explicitProjectHandle: "supported"
|
|
266267
|
+
}
|
|
266268
|
+
};
|
|
266269
|
+
}
|
|
266270
|
+
var CURRENT_MCP_PROTOCOL_VERSION, LEGACY_MCP_PROTOCOL_VERSION, MCP_SERVER_NAME;
|
|
266271
|
+
var init_mcp_diagnostics = __esm({
|
|
266272
|
+
"src/server/mcp-diagnostics.ts"() {
|
|
266273
|
+
"use strict";
|
|
266274
|
+
init_esm_shims();
|
|
266275
|
+
CURRENT_MCP_PROTOCOL_VERSION = "2026-07-28";
|
|
266276
|
+
LEGACY_MCP_PROTOCOL_VERSION = "2024-11-05";
|
|
266277
|
+
MCP_SERVER_NAME = "io.github.AVIDS2/memorix";
|
|
266278
|
+
}
|
|
266279
|
+
});
|
|
266280
|
+
|
|
264967
266281
|
// src/cli/port.ts
|
|
264968
266282
|
function parseTcpPort(value, defaultPort) {
|
|
264969
266283
|
const raw = value?.trim() || String(defaultPort);
|
|
@@ -267060,6 +268374,79 @@ var init_streamableHttp = __esm({
|
|
|
267060
268374
|
}
|
|
267061
268375
|
});
|
|
267062
268376
|
|
|
268377
|
+
// src/server/mcp-binding-store.ts
|
|
268378
|
+
var mcp_binding_store_exports = {};
|
|
268379
|
+
__export(mcp_binding_store_exports, {
|
|
268380
|
+
McpBindingStore: () => McpBindingStore
|
|
268381
|
+
});
|
|
268382
|
+
import { randomUUID as randomUUID19 } from "crypto";
|
|
268383
|
+
function rowToBinding(row) {
|
|
268384
|
+
return {
|
|
268385
|
+
handleId: String(row.handle_id),
|
|
268386
|
+
projectId: String(row.project_id),
|
|
268387
|
+
projectRoot: String(row.project_root),
|
|
268388
|
+
dataDir: String(row.data_dir),
|
|
268389
|
+
createdAt: String(row.created_at),
|
|
268390
|
+
lastUsedAt: String(row.last_used_at),
|
|
268391
|
+
...row.expires_at ? { expiresAt: String(row.expires_at) } : {}
|
|
268392
|
+
};
|
|
268393
|
+
}
|
|
268394
|
+
var McpBindingStore;
|
|
268395
|
+
var init_mcp_binding_store = __esm({
|
|
268396
|
+
"src/server/mcp-binding-store.ts"() {
|
|
268397
|
+
"use strict";
|
|
268398
|
+
init_esm_shims();
|
|
268399
|
+
init_sqlite_db();
|
|
268400
|
+
McpBindingStore = class {
|
|
268401
|
+
db = null;
|
|
268402
|
+
async init(dataDir) {
|
|
268403
|
+
this.db = getDatabase(dataDir);
|
|
268404
|
+
}
|
|
268405
|
+
requireDb() {
|
|
268406
|
+
if (!this.db) throw new Error("McpBindingStore is not initialized.");
|
|
268407
|
+
return this.db;
|
|
268408
|
+
}
|
|
268409
|
+
create(input) {
|
|
268410
|
+
const now3 = /* @__PURE__ */ new Date();
|
|
268411
|
+
const binding = {
|
|
268412
|
+
handleId: `mxh_${randomUUID19().replace(/-/g, "")}`,
|
|
268413
|
+
projectId: input.projectId,
|
|
268414
|
+
projectRoot: input.projectRoot,
|
|
268415
|
+
dataDir: input.dataDir,
|
|
268416
|
+
createdAt: now3.toISOString(),
|
|
268417
|
+
lastUsedAt: now3.toISOString(),
|
|
268418
|
+
...input.ttlMs && input.ttlMs > 0 ? { expiresAt: new Date(now3.getTime() + input.ttlMs).toISOString() } : {}
|
|
268419
|
+
};
|
|
268420
|
+
this.requireDb().prepare(`
|
|
268421
|
+
INSERT INTO mcp_bindings (handle_id, project_id, project_root, data_dir, created_at, last_used_at, expires_at)
|
|
268422
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
268423
|
+
`).run(binding.handleId, binding.projectId, binding.projectRoot, binding.dataDir, binding.createdAt, binding.lastUsedAt, binding.expiresAt ?? null);
|
|
268424
|
+
return binding;
|
|
268425
|
+
}
|
|
268426
|
+
get(handleId) {
|
|
268427
|
+
const row = this.requireDb().prepare(`SELECT * FROM mcp_bindings WHERE handle_id = ?`).get(handleId);
|
|
268428
|
+
if (!row) return void 0;
|
|
268429
|
+
const binding = rowToBinding(row);
|
|
268430
|
+
if (binding.expiresAt && Date.parse(binding.expiresAt) <= Date.now()) {
|
|
268431
|
+
this.delete(handleId);
|
|
268432
|
+
return void 0;
|
|
268433
|
+
}
|
|
268434
|
+
return binding;
|
|
268435
|
+
}
|
|
268436
|
+
touch(handleId) {
|
|
268437
|
+
const binding = this.get(handleId);
|
|
268438
|
+
if (!binding) return void 0;
|
|
268439
|
+
const lastUsedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
268440
|
+
this.requireDb().prepare(`UPDATE mcp_bindings SET last_used_at = ? WHERE handle_id = ?`).run(lastUsedAt, handleId);
|
|
268441
|
+
return { ...binding, lastUsedAt };
|
|
268442
|
+
}
|
|
268443
|
+
delete(handleId) {
|
|
268444
|
+
this.requireDb().prepare(`DELETE FROM mcp_bindings WHERE handle_id = ?`).run(handleId);
|
|
268445
|
+
}
|
|
268446
|
+
};
|
|
268447
|
+
}
|
|
268448
|
+
});
|
|
268449
|
+
|
|
267063
268450
|
// src/runtime/control-plane-maintenance.ts
|
|
267064
268451
|
var control_plane_maintenance_exports = {};
|
|
267065
268452
|
__export(control_plane_maintenance_exports, {
|
|
@@ -267127,6 +268514,7 @@ var serve_http_exports = {};
|
|
|
267127
268514
|
__export(serve_http_exports, {
|
|
267128
268515
|
DEFAULT_SESSION_TIMEOUT_MS: () => DEFAULT_SESSION_TIMEOUT_MS,
|
|
267129
268516
|
EXPIRED_SESSION_TTL_MS: () => EXPIRED_SESSION_TTL_MS,
|
|
268517
|
+
MCP_SDK_COMPAT_PROTOCOL_VERSION: () => MCP_SDK_COMPAT_PROTOCOL_VERSION,
|
|
267130
268518
|
_testing: () => _testing2,
|
|
267131
268519
|
default: () => serve_http_default,
|
|
267132
268520
|
parseSessionTimeoutMs: () => parseSessionTimeoutMs,
|
|
@@ -267148,7 +268536,7 @@ function resolveServeHttpDefaults(argsPort, configured) {
|
|
|
267148
268536
|
const transportNotice = configured.transport === "stdio" ? '[memorix] config server.transport = "stdio"; serve-http continues on HTTP (the explicit command wins).' : void 0;
|
|
267149
268537
|
return { port, transportNotice };
|
|
267150
268538
|
}
|
|
267151
|
-
var DEFAULT_SESSION_TIMEOUT_MS, EXPIRED_SESSION_TTL_MS, serve_http_default, _testing2;
|
|
268539
|
+
var DEFAULT_SESSION_TIMEOUT_MS, EXPIRED_SESSION_TTL_MS, MCP_SDK_COMPAT_PROTOCOL_VERSION, serve_http_default, _testing2;
|
|
267152
268540
|
var init_serve_http = __esm({
|
|
267153
268541
|
"src/cli/commands/serve-http.ts"() {
|
|
267154
268542
|
"use strict";
|
|
@@ -267158,10 +268546,12 @@ var init_serve_http = __esm({
|
|
|
267158
268546
|
init_graph_scope();
|
|
267159
268547
|
init_retention();
|
|
267160
268548
|
init_visibility();
|
|
268549
|
+
init_mcp_diagnostics();
|
|
267161
268550
|
init_port();
|
|
267162
268551
|
init_mcp_root_path();
|
|
267163
268552
|
DEFAULT_SESSION_TIMEOUT_MS = 12 * 60 * 60 * 1e3;
|
|
267164
268553
|
EXPIRED_SESSION_TTL_MS = 10 * 60 * 1e3;
|
|
268554
|
+
MCP_SDK_COMPAT_PROTOCOL_VERSION = "2025-11-25";
|
|
267165
268555
|
serve_http_default = defineCommand({
|
|
267166
268556
|
meta: {
|
|
267167
268557
|
name: "serve-http",
|
|
@@ -267191,7 +268581,7 @@ var init_serve_http = __esm({
|
|
|
267191
268581
|
},
|
|
267192
268582
|
run: async ({ args }) => {
|
|
267193
268583
|
const { createServer: createServer3 } = await import("http");
|
|
267194
|
-
const { randomUUID:
|
|
268584
|
+
const { randomUUID: randomUUID20 } = await import("crypto");
|
|
267195
268585
|
const { StreamableHTTPServerTransport: StreamableHTTPServerTransport2 } = await Promise.resolve().then(() => (init_streamableHttp(), streamableHttp_exports));
|
|
267196
268586
|
const { isInitializeRequest: isInitializeRequest2 } = await Promise.resolve().then(() => (init_types8(), types_exports3));
|
|
267197
268587
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
|
|
@@ -267199,6 +268589,8 @@ var init_serve_http = __esm({
|
|
|
267199
268589
|
const { findGitInSubdirs: findGitInSubdirs2 } = await Promise.resolve().then(() => (init_detector(), detector_exports));
|
|
267200
268590
|
const { writeFileSync: writeFileSync12, mkdirSync: mkdirSync12 } = await import("fs");
|
|
267201
268591
|
const { homedir: homedir36 } = await import("os");
|
|
268592
|
+
const { McpBindingStore: McpBindingStore2 } = await Promise.resolve().then(() => (init_mcp_binding_store(), mcp_binding_store_exports));
|
|
268593
|
+
const { MemoryFeedbackStore: MemoryFeedbackStore2 } = await Promise.resolve().then(() => (init_feedback(), feedback_exports));
|
|
267202
268594
|
let configuredDefaults = {};
|
|
267203
268595
|
try {
|
|
267204
268596
|
const { getServerConfig: getServerConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
@@ -267251,9 +268643,8 @@ var init_serve_http = __esm({
|
|
|
267251
268643
|
teamStoreCache.set(dataDir, store2);
|
|
267252
268644
|
return store2;
|
|
267253
268645
|
}
|
|
267254
|
-
const
|
|
267255
|
-
|
|
267256
|
-
const sharedTeamStore = await getTeamStore2(teamDataDir);
|
|
268646
|
+
const statelessBindingStore = new McpBindingStore2();
|
|
268647
|
+
await statelessBindingStore.init(persistMod.getBaseDataDir());
|
|
267257
268648
|
const sessions = /* @__PURE__ */ new Map();
|
|
267258
268649
|
const sessionLastActivity = /* @__PURE__ */ new Map();
|
|
267259
268650
|
const expiredSessions = /* @__PURE__ */ new Map();
|
|
@@ -267393,12 +268784,91 @@ var init_serve_http = __esm({
|
|
|
267393
268784
|
res.setHeader("Vary", "Origin");
|
|
267394
268785
|
}
|
|
267395
268786
|
res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
|
|
267396
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Mcp-Session-Id, Last-Event-Id");
|
|
267397
|
-
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
|
|
268787
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Mcp-Session-Id, Mcp-Project-Handle, Mcp-Project-Root, Mcp-Stateless, Last-Event-Id");
|
|
268788
|
+
res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id, Mcp-Project-Handle, Mcp-Protocol-Version, Mcp-Method, Mcp-Name");
|
|
268789
|
+
res.setHeader("Mcp-Protocol-Version", req.headers["mcp-protocol-version"] || CURRENT_MCP_PROTOCOL_VERSION);
|
|
268790
|
+
res.setHeader("Mcp-Method", req.method || "UNKNOWN");
|
|
268791
|
+
res.setHeader("Mcp-Name", MCP_SERVER_NAME);
|
|
268792
|
+
}
|
|
268793
|
+
async function handleStatelessPost(req, res, body) {
|
|
268794
|
+
const handleId = typeof req.headers["mcp-project-handle"] === "string" ? req.headers["mcp-project-handle"] : void 0;
|
|
268795
|
+
const persisted = handleId ? statelessBindingStore.touch(handleId) : void 0;
|
|
268796
|
+
if (handleId && !persisted) {
|
|
268797
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
268798
|
+
res.end(JSON.stringify({ jsonrpc: "2.0", error: { code: -32001, message: "MCP project handle not found or expired; initialize again." }, id: null }));
|
|
268799
|
+
return;
|
|
268800
|
+
}
|
|
268801
|
+
const requestedRoot = typeof req.headers["mcp-project-root"] === "string" ? req.headers["mcp-project-root"] : void 0;
|
|
268802
|
+
const root = persisted?.projectRoot ?? requestedRoot ?? projectRoot;
|
|
268803
|
+
if (!persisted && !isInitializeRequest2(body)) {
|
|
268804
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
268805
|
+
res.end(JSON.stringify({ jsonrpc: "2.0", error: { code: -32e3, message: "Stateless MCP requests require Mcp-Project-Handle; initialize first." }, id: null }));
|
|
268806
|
+
return;
|
|
268807
|
+
}
|
|
268808
|
+
const { createMemorixServer: createMemorixServer3 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
|
|
268809
|
+
const { createProjectBindingController: createProjectBindingController3 } = await Promise.resolve().then(() => (init_request_context(), request_context_exports));
|
|
268810
|
+
const binding = createProjectBindingController3(root);
|
|
268811
|
+
const { server, projectId, handleTransportClose } = await createMemorixServer3(
|
|
268812
|
+
root,
|
|
268813
|
+
void 0,
|
|
268814
|
+
void 0,
|
|
268815
|
+
{
|
|
268816
|
+
allowUntrackedFallback: false,
|
|
268817
|
+
deferProjectInitUntilBound: true,
|
|
268818
|
+
deferProjectRuntimeInit: true,
|
|
268819
|
+
dashboardMode: "control-plane",
|
|
268820
|
+
dashboardPort: port,
|
|
268821
|
+
toolProfile,
|
|
268822
|
+
projectBinding: binding
|
|
268823
|
+
}
|
|
268824
|
+
);
|
|
268825
|
+
const transport = new StreamableHTTPServerTransport2({
|
|
268826
|
+
// No Mcp-Session-Id: the protocol state is carried by our explicit
|
|
268827
|
+
// durable project handle and reconstructed on every request.
|
|
268828
|
+
sessionIdGenerator: void 0,
|
|
268829
|
+
enableJsonResponse: true
|
|
268830
|
+
});
|
|
268831
|
+
try {
|
|
268832
|
+
await server.connect(transport);
|
|
268833
|
+
let effectiveHandle = persisted;
|
|
268834
|
+
if (!effectiveHandle && projectId !== "__unresolved__") {
|
|
268835
|
+
effectiveHandle = statelessBindingStore.create({
|
|
268836
|
+
projectId,
|
|
268837
|
+
projectRoot: root,
|
|
268838
|
+
dataDir: await persistMod.getProjectDataDir(projectId)
|
|
268839
|
+
});
|
|
268840
|
+
}
|
|
268841
|
+
if (effectiveHandle) res.setHeader("Mcp-Project-Handle", effectiveHandle.handleId);
|
|
268842
|
+
const sdkBody = body && typeof body === "object" ? JSON.parse(JSON.stringify(body)) : body;
|
|
268843
|
+
const sdkRequest = sdkBody;
|
|
268844
|
+
if (sdkRequest && typeof sdkRequest === "object" && sdkRequest.method === "initialize" && sdkRequest.params) {
|
|
268845
|
+
sdkRequest.params.protocolVersion = MCP_SDK_COMPAT_PROTOCOL_VERSION;
|
|
268846
|
+
}
|
|
268847
|
+
if (req.headers["mcp-protocol-version"]) {
|
|
268848
|
+
req.headers["mcp-protocol-version"] = MCP_SDK_COMPAT_PROTOCOL_VERSION;
|
|
268849
|
+
for (let i4 = 0; i4 < req.rawHeaders.length; i4 += 2) {
|
|
268850
|
+
if (req.rawHeaders[i4].toLowerCase() === "mcp-protocol-version") {
|
|
268851
|
+
req.rawHeaders[i4 + 1] = MCP_SDK_COMPAT_PROTOCOL_VERSION;
|
|
268852
|
+
break;
|
|
268853
|
+
}
|
|
268854
|
+
}
|
|
268855
|
+
}
|
|
268856
|
+
patchMcpResponse(res);
|
|
268857
|
+
await transport.handleRequest(req, res, sdkBody);
|
|
268858
|
+
} finally {
|
|
268859
|
+
handleTransportClose();
|
|
268860
|
+
await transport.close().catch(() => void 0);
|
|
268861
|
+
}
|
|
267398
268862
|
}
|
|
267399
268863
|
async function handlePost(req, res) {
|
|
267400
268864
|
const sessionId = req.headers["mcp-session-id"];
|
|
267401
268865
|
const body = await parseBody(req);
|
|
268866
|
+
const requestedProtocol = req.headers["mcp-protocol-version"];
|
|
268867
|
+
const statelessRequested = req.headers["mcp-stateless"] === "true" || requestedProtocol === CURRENT_MCP_PROTOCOL_VERSION;
|
|
268868
|
+
if (!sessionId && statelessRequested) {
|
|
268869
|
+
await handleStatelessPost(req, res, body);
|
|
268870
|
+
return;
|
|
268871
|
+
}
|
|
267402
268872
|
if (sessionId && sessions.has(sessionId)) {
|
|
267403
268873
|
sessionLastActivity.set(sessionId, Date.now());
|
|
267404
268874
|
patchMcpResponse(res);
|
|
@@ -267412,7 +268882,7 @@ var init_serve_http = __esm({
|
|
|
267412
268882
|
if (!sessionId && isInitializeRequest2(body)) {
|
|
267413
268883
|
let createdState = null;
|
|
267414
268884
|
const transport = new StreamableHTTPServerTransport2({
|
|
267415
|
-
sessionIdGenerator: () =>
|
|
268885
|
+
sessionIdGenerator: () => randomUUID20(),
|
|
267416
268886
|
enableJsonResponse: true,
|
|
267417
268887
|
onsessioninitialized: (sid) => {
|
|
267418
268888
|
if (createdState) sessions.set(sid, createdState);
|
|
@@ -267445,7 +268915,7 @@ var init_serve_http = __esm({
|
|
|
267445
268915
|
const { server, switchProject, handleTransportClose } = await createMemorixServer2(
|
|
267446
268916
|
projectRoot,
|
|
267447
268917
|
void 0,
|
|
267448
|
-
|
|
268918
|
+
void 0,
|
|
267449
268919
|
{
|
|
267450
268920
|
allowUntrackedFallback: false,
|
|
267451
268921
|
deferProjectInitUntilBound: true,
|
|
@@ -267587,6 +269057,18 @@ var init_serve_http = __esm({
|
|
|
267587
269057
|
{ projectId }
|
|
267588
269058
|
);
|
|
267589
269059
|
}
|
|
269060
|
+
async function loadProjectFeedback(dataDir, projectId) {
|
|
269061
|
+
const result = /* @__PURE__ */ new Map();
|
|
269062
|
+
try {
|
|
269063
|
+
const feedback = new MemoryFeedbackStore2();
|
|
269064
|
+
await feedback.init(dataDir);
|
|
269065
|
+
for (const state of feedback.listStates(projectId, "observation")) {
|
|
269066
|
+
result.set(state.candidateId, { weight: state.weight, status: state.status });
|
|
269067
|
+
}
|
|
269068
|
+
} catch {
|
|
269069
|
+
}
|
|
269070
|
+
return result;
|
|
269071
|
+
}
|
|
267590
269072
|
const cliDir = pathModule.default.dirname(fileURLToPath10(import.meta.url));
|
|
267591
269073
|
const dashStaticDir = pathModule.default.join(cliDir, "..", "dashboard", "static");
|
|
267592
269074
|
const MIME_TYPES2 = {
|
|
@@ -267645,9 +269127,41 @@ var init_serve_http = __esm({
|
|
|
267645
269127
|
sendJson2({ ok: true, scope: "per-request" });
|
|
267646
269128
|
return;
|
|
267647
269129
|
}
|
|
269130
|
+
const maintenanceMatch = apiPath.match(/^\/maintenance\/(cleanup|deduplicate|consolidate|retention)\/(preview|execute)$/);
|
|
269131
|
+
if (maintenanceMatch) {
|
|
269132
|
+
if (req.method !== "POST") {
|
|
269133
|
+
sendJson2({ error: "Maintenance actions require POST." }, 405);
|
|
269134
|
+
return;
|
|
269135
|
+
}
|
|
269136
|
+
const bodyValue = await parseBody(req);
|
|
269137
|
+
const body = bodyValue && typeof bodyValue === "object" && !Array.isArray(bodyValue) ? bodyValue : {};
|
|
269138
|
+
const { projectId: maintenanceProjectId, dataDir: maintenanceDataDir } = await resolveRequestProject(url2);
|
|
269139
|
+
const maintenanceStore = await getDashboardObservationStore(maintenanceDataDir);
|
|
269140
|
+
const context = {
|
|
269141
|
+
dataDir: maintenanceDataDir,
|
|
269142
|
+
projectId: maintenanceProjectId,
|
|
269143
|
+
projectRoot: maintenanceProjectId === defaultProject.id ? projectRoot : null,
|
|
269144
|
+
store: maintenanceStore
|
|
269145
|
+
};
|
|
269146
|
+
const maintenance = await Promise.resolve().then(() => (init_maintenance(), maintenance_exports));
|
|
269147
|
+
const action = maintenanceMatch[1];
|
|
269148
|
+
const phase = maintenanceMatch[2];
|
|
269149
|
+
let result;
|
|
269150
|
+
if (action === "cleanup") {
|
|
269151
|
+
result = phase === "preview" ? await maintenance.previewCleanup(context, body.includeNoise === true) : await maintenance.executeCleanup(context, body.payload, body.token);
|
|
269152
|
+
} else if (action === "deduplicate") {
|
|
269153
|
+
result = phase === "preview" ? await maintenance.previewDeduplicate(context) : await maintenance.executeDeduplicate(context, body.payload, body.token);
|
|
269154
|
+
} else if (action === "consolidate") {
|
|
269155
|
+
result = phase === "preview" ? await maintenance.previewConsolidate(context) : await maintenance.executeConsolidate(context, body.payload, body.token);
|
|
269156
|
+
} else {
|
|
269157
|
+
result = phase === "preview" ? await maintenance.previewRetentionArchive(context) : await maintenance.executeRetentionArchive(context, body.payload, body.token);
|
|
269158
|
+
}
|
|
269159
|
+
sendJson2(result);
|
|
269160
|
+
return;
|
|
269161
|
+
}
|
|
267648
269162
|
if (apiPath === "/team") {
|
|
267649
|
-
const { projectId: teamProjectId } = await resolveRequestProject(url2);
|
|
267650
|
-
const ts2 =
|
|
269163
|
+
const { projectId: teamProjectId, dataDir: teamDataDir } = await resolveRequestProject(url2);
|
|
269164
|
+
const ts2 = await getTeamStore2(teamDataDir);
|
|
267651
269165
|
const scope = url2.searchParams.get("scope") || "project";
|
|
267652
269166
|
const effectiveTeamProjectId = scope === "global" ? void 0 : teamProjectId;
|
|
267653
269167
|
const agents = effectiveTeamProjectId ? ts2.listAgents(effectiveTeamProjectId) : ts2.listAllAgents();
|
|
@@ -267748,6 +269262,7 @@ var init_serve_http = __esm({
|
|
|
267748
269262
|
await initGraphStore2(statsDataDir);
|
|
267749
269263
|
const graph = { entities: getGraphStore2().loadEntities(), relations: getGraphStore2().loadRelations() };
|
|
267750
269264
|
const observations2 = await loadDashboardProjectObservations(statsDataDir, statsProjectId, "active");
|
|
269265
|
+
const feedback = await loadProjectFeedback(statsDataDir, statsProjectId);
|
|
267751
269266
|
const statsStore = await getDashboardObservationStore(statsDataDir);
|
|
267752
269267
|
const nextId2 = await statsStore.loadIdCounter();
|
|
267753
269268
|
const typeCounts = {};
|
|
@@ -267782,7 +269297,10 @@ var init_serve_http = __esm({
|
|
|
267782
269297
|
filesModified: o4.filesModified
|
|
267783
269298
|
}));
|
|
267784
269299
|
const retention = summarizeRetentionProjections(
|
|
267785
|
-
observations2.filter((observation) => observation.type !== "probe").map((observation) => projectObservationRetention(observation, {
|
|
269300
|
+
observations2.filter((observation) => observation.type !== "probe").map((observation) => projectObservationRetention(observation, {
|
|
269301
|
+
referenceTime: new Date(now3),
|
|
269302
|
+
feedback: feedback.get(String(observation.id))
|
|
269303
|
+
}))
|
|
267786
269304
|
);
|
|
267787
269305
|
const retentionSummary = {
|
|
267788
269306
|
active: retention.active,
|
|
@@ -267889,6 +269407,19 @@ var init_serve_http = __esm({
|
|
|
267889
269407
|
sendJson2(await loadDashboardProjectObservations(obsDataDir, obsProjectId, "active"));
|
|
267890
269408
|
return;
|
|
267891
269409
|
}
|
|
269410
|
+
if (apiPath === "/evidence") {
|
|
269411
|
+
const { projectId: evidenceProjectId, dataDir: evidenceDataDir } = await resolveRequestProject(url2);
|
|
269412
|
+
const { EvidenceCardStore: EvidenceCardStore2 } = await Promise.resolve().then(() => (init_evidence_store(), evidence_store_exports));
|
|
269413
|
+
const evidenceStore = new EvidenceCardStore2();
|
|
269414
|
+
await evidenceStore.init(evidenceDataDir);
|
|
269415
|
+
const observations2 = await loadDashboardProjectObservations(evidenceDataDir, evidenceProjectId, "active");
|
|
269416
|
+
evidenceStore.syncObservations(observations2);
|
|
269417
|
+
const query = (url2.searchParams.get("q") || "").trim().toLowerCase();
|
|
269418
|
+
const limit2 = Math.min(100, Math.max(1, Number(url2.searchParams.get("limit") || 20)));
|
|
269419
|
+
const cards = evidenceStore.list(evidenceProjectId, { limit: 100 }).filter((card) => !query || [card.title, card.summary, card.sourceRef, card.locator ?? ""].join(" ").toLowerCase().includes(query)).slice(0, limit2).map((card) => ({ ...card, events: evidenceStore.listEvents(card.id, 8) }));
|
|
269420
|
+
sendJson2({ projectId: evidenceProjectId, cards });
|
|
269421
|
+
return;
|
|
269422
|
+
}
|
|
267892
269423
|
if (apiPath === "/graph") {
|
|
267893
269424
|
const { projectId: graphProjectId, dataDir: graphDataDir } = await resolveRequestProject(url2);
|
|
267894
269425
|
const { initGraphStore: initGraphStore2, getGraphStore: getGraphStore2 } = await Promise.resolve().then(() => (init_graph_store(), graph_store_exports));
|
|
@@ -267910,10 +269441,11 @@ var init_serve_http = __esm({
|
|
|
267910
269441
|
if (apiPath === "/retention") {
|
|
267911
269442
|
const { projectId: retProjectId, dataDir: retDataDir } = await resolveRequestProject(url2);
|
|
267912
269443
|
const observations2 = await loadDashboardProjectObservations(retDataDir, retProjectId, "active");
|
|
269444
|
+
const feedback = await loadProjectFeedback(retDataDir, retProjectId);
|
|
267913
269445
|
const referenceTime = /* @__PURE__ */ new Date();
|
|
267914
269446
|
const rows = observations2.filter((observation) => observation.type !== "probe").map((observation) => ({
|
|
267915
269447
|
observation,
|
|
267916
|
-
retention: projectObservationRetention(observation, { referenceTime })
|
|
269448
|
+
retention: projectObservationRetention(observation, { referenceTime, feedback: feedback.get(String(observation.id)) })
|
|
267917
269449
|
})).sort((a4, b4) => b4.retention.displayScore - a4.retention.displayScore);
|
|
267918
269450
|
const summary = summarizeRetentionProjections(rows.map((row) => row.retention));
|
|
267919
269451
|
const items = rows.map(({ observation, retention }) => ({
|
|
@@ -268290,6 +269822,11 @@ var init_serve_http = __esm({
|
|
|
268290
269822
|
}));
|
|
268291
269823
|
return;
|
|
268292
269824
|
}
|
|
269825
|
+
if (url2.pathname === "/protocol-diagnostics") {
|
|
269826
|
+
res.writeHead(200, { "Content-Type": "application/json; charset=utf-8", "Cache-Control": "public, max-age=60" });
|
|
269827
|
+
res.end(JSON.stringify(getMcpDiagnostics()));
|
|
269828
|
+
return;
|
|
269829
|
+
}
|
|
268293
269830
|
if (url2.pathname === "/mcp") {
|
|
268294
269831
|
const accept = req.headers["accept"] || "";
|
|
268295
269832
|
const needs = [];
|
|
@@ -268586,6 +270123,7 @@ var init_status = __esm({
|
|
|
268586
270123
|
diagLines.push(` Agent lane: ${formatLane(agent.provider, agent.model, agent.baseUrl, agent.apiKey)}`);
|
|
268587
270124
|
diagLines.push(` Memory LLM lane: ${formatLane(resolved.memory.llm.provider, resolved.memory.llm.model, resolved.memory.llm.baseUrl, resolved.memory.llm.apiKey)}`);
|
|
268588
270125
|
diagLines.push(` Embedding lane: ${formatLane(resolved.embedding.provider, resolved.embedding.model, resolved.embedding.baseUrl, resolved.embedding.apiKey)}`);
|
|
270126
|
+
diagLines.push(` Rerank lane: ${formatLane(resolved.rerank.provider, resolved.rerank.model, resolved.rerank.baseUrl, resolved.rerank.apiKey)}`);
|
|
268589
270127
|
diagLines.push(` Memory behavior: inject=${resolved.memory.inject ?? "default"}, formation=${resolved.memory.formation ?? "default"}, autoCleanup=${resolved.memory.autoCleanup ?? "default"}`);
|
|
268590
270128
|
diagLines.push(` Git behavior: autoHook=${resolved.git.autoHook ?? "default"}, ingestOnCommit=${resolved.git.ingestOnCommit ?? "default"}, maxDiffSize=${resolved.git.maxDiffSize ?? "default"}, skipMergeCommits=${resolved.git.skipMergeCommits ?? "default"}`);
|
|
268591
270129
|
diagLines.push(` Server: transport=${resolved.server.transport ?? "default"}, dashboard=${resolved.server.dashboard ?? "default"}, dashboardPort=${resolved.server.dashboardPort ?? "default"}`);
|
|
@@ -268619,7 +270157,8 @@ var init_status = __esm({
|
|
|
268619
270157
|
lanes: {
|
|
268620
270158
|
agent: summarizeLane(agent.provider, agent.model, agent.baseUrl, agent.apiKey),
|
|
268621
270159
|
memoryLlm: summarizeLane(resolved.memory.llm.provider, resolved.memory.llm.model, resolved.memory.llm.baseUrl, resolved.memory.llm.apiKey),
|
|
268622
|
-
embedding: summarizeLane(resolved.embedding.provider, resolved.embedding.model, resolved.embedding.baseUrl, resolved.embedding.apiKey)
|
|
270160
|
+
embedding: summarizeLane(resolved.embedding.provider, resolved.embedding.model, resolved.embedding.baseUrl, resolved.embedding.apiKey),
|
|
270161
|
+
rerank: summarizeLane(resolved.rerank.provider, resolved.rerank.model, resolved.rerank.baseUrl, resolved.rerank.apiKey)
|
|
268623
270162
|
},
|
|
268624
270163
|
memory: {
|
|
268625
270164
|
inject: resolved.memory.inject ?? "default",
|
|
@@ -270162,10 +271701,10 @@ __export(handler_exports, {
|
|
|
270162
271701
|
resetCooldowns: () => resetCooldowns,
|
|
270163
271702
|
runHook: () => runHook
|
|
270164
271703
|
});
|
|
270165
|
-
import { createHash as
|
|
271704
|
+
import { createHash as createHash19 } from "crypto";
|
|
270166
271705
|
function deriveHookActorId(input) {
|
|
270167
271706
|
const material = `${input.agent ?? "unknown"}\0${input.sessionId ?? "unknown"}`;
|
|
270168
|
-
return `hook:${
|
|
271707
|
+
return `hook:${createHash19("sha256").update(material).digest("hex").slice(0, 24)}`;
|
|
270169
271708
|
}
|
|
270170
271709
|
function classifyTool(input) {
|
|
270171
271710
|
if (input.event === "post_edit") return "file_modify";
|
|
@@ -272110,10 +273649,10 @@ var init_ingest = __esm({
|
|
|
272110
273649
|
});
|
|
272111
273650
|
|
|
272112
273651
|
// src/media/embedding.ts
|
|
272113
|
-
import { createHash as
|
|
273652
|
+
import { createHash as createHash20 } from "crypto";
|
|
272114
273653
|
function profileKey(provider2, asset) {
|
|
272115
273654
|
const identity = `${provider2.name}\0${provider2.dimensions}\0${asset.kind}`;
|
|
272116
|
-
return `media:${
|
|
273655
|
+
return `media:${createHash20("sha256").update(identity).digest("hex").slice(0, 20)}`;
|
|
272117
273656
|
}
|
|
272118
273657
|
function supportsAsset(provider2, asset) {
|
|
272119
273658
|
return !!provider2.embedInput && (provider2.supportedModalities?.includes(asset.kind) ?? false);
|
|
@@ -274942,7 +276481,9 @@ var init_doctor = __esm({
|
|
|
274942
276481
|
if (isLLMEnabled2()) {
|
|
274943
276482
|
const config2 = getLLMConfig2();
|
|
274944
276483
|
lines.push(ok(`Provider: ${config2?.provider}/${config2?.model}`));
|
|
274945
|
-
|
|
276484
|
+
const { isNeuralRerankEnabled: isNeuralRerankEnabled2 } = await Promise.resolve().then(() => (init_rerank(), rerank_exports));
|
|
276485
|
+
const rerankCap = isNeuralRerankEnabled2() ? "HTTP rerank" : "LLM rerank";
|
|
276486
|
+
lines.push(info2(`Capabilities: fact extraction, auto-dedup, ${rerankCap}`));
|
|
274946
276487
|
report.llm = { enabled: true, provider: config2?.provider, model: config2?.model };
|
|
274947
276488
|
} else {
|
|
274948
276489
|
lines.push(info2("LLM mode: off (heuristic dedup only)"));
|
|
@@ -277724,7 +279265,7 @@ function safeWrite(path48, content) {
|
|
|
277724
279265
|
} catch {
|
|
277725
279266
|
}
|
|
277726
279267
|
}
|
|
277727
|
-
var
|
|
279268
|
+
var init_evidence2 = __esm({
|
|
277728
279269
|
"src/orchestrate/evidence.ts"() {
|
|
277729
279270
|
"use strict";
|
|
277730
279271
|
init_esm_shims();
|
|
@@ -277850,7 +279391,7 @@ var init_permission = __esm({
|
|
|
277850
279391
|
});
|
|
277851
279392
|
|
|
277852
279393
|
// src/orchestrate/memorix-bridge.ts
|
|
277853
|
-
import { createHash as
|
|
279394
|
+
import { createHash as createHash21 } from "crypto";
|
|
277854
279395
|
async function getStoreObservation() {
|
|
277855
279396
|
if (!_storeObservation) {
|
|
277856
279397
|
const mod = await Promise.resolve().then(() => (init_observations(), observations_exports));
|
|
@@ -277866,7 +279407,7 @@ async function getSearchObservations() {
|
|
|
277866
279407
|
return _searchObservations;
|
|
277867
279408
|
}
|
|
277868
279409
|
function automaticActorId(...parts) {
|
|
277869
|
-
return `orchestrator:${
|
|
279410
|
+
return `orchestrator:${createHash21("sha256").update(parts.join("\0")).digest("hex").slice(0, 24)}`;
|
|
277870
279411
|
}
|
|
277871
279412
|
function isEligibleAutomaticLesson(entry) {
|
|
277872
279413
|
return entry.admissionState !== "candidate" && entry.admissionState !== "ephemeral";
|
|
@@ -278013,7 +279554,7 @@ function sanitizeErrorPattern(text2) {
|
|
|
278013
279554
|
}
|
|
278014
279555
|
function hashErrorPattern(errorOutput) {
|
|
278015
279556
|
const sanitized = sanitizeErrorPattern(errorOutput).slice(0, 500);
|
|
278016
|
-
return
|
|
279557
|
+
return createHash21("sha256").update(sanitized).digest("hex").slice(0, 12);
|
|
278017
279558
|
}
|
|
278018
279559
|
function sleep6(ms2) {
|
|
278019
279560
|
return new Promise((resolve6) => setTimeout(() => resolve6([]), ms2));
|
|
@@ -279019,7 +280560,7 @@ var init_coordinator = __esm({
|
|
|
279019
280560
|
init_verify_gate();
|
|
279020
280561
|
init_error_recovery();
|
|
279021
280562
|
init_cost_tracker();
|
|
279022
|
-
|
|
280563
|
+
init_evidence2();
|
|
279023
280564
|
init_permission();
|
|
279024
280565
|
init_memorix_bridge();
|
|
279025
280566
|
}
|
|
@@ -284270,6 +285811,8 @@ var main2 = defineCommand({
|
|
|
284270
285811
|
codegraph: () => Promise.resolve().then(() => (init_codegraph(), codegraph_exports)).then((m6) => m6.default),
|
|
284271
285812
|
checkpoint: () => Promise.resolve().then(() => (init_checkpoint2(), checkpoint_exports)).then((m6) => m6.default),
|
|
284272
285813
|
knowledge: () => Promise.resolve().then(() => (init_knowledge(), knowledge_exports)).then((m6) => m6.default),
|
|
285814
|
+
evidence: () => Promise.resolve().then(() => (init_evidence(), evidence_exports)).then((m6) => m6.default),
|
|
285815
|
+
feedback: () => Promise.resolve().then(() => (init_feedback2(), feedback_exports2)).then((m6) => m6.default),
|
|
284273
285816
|
reasoning: () => Promise.resolve().then(() => (init_reasoning(), reasoning_exports)).then((m6) => m6.default),
|
|
284274
285817
|
retention: () => Promise.resolve().then(() => (init_retention2(), retention_exports2)).then((m6) => m6.default),
|
|
284275
285818
|
formation: () => Promise.resolve().then(() => (init_formation2(), formation_exports2)).then((m6) => m6.default),
|
|
@@ -284368,6 +285911,8 @@ var main2 = defineCommand({
|
|
|
284368
285911
|
"lock",
|
|
284369
285912
|
"handoff",
|
|
284370
285913
|
"poll",
|
|
285914
|
+
"evidence",
|
|
285915
|
+
"feedback",
|
|
284371
285916
|
"receipt",
|
|
284372
285917
|
"serve",
|
|
284373
285918
|
"serve-http",
|
|
@@ -284425,6 +285970,8 @@ var main2 = defineCommand({
|
|
|
284425
285970
|
console.error(" codegraph Refresh/status/context-pack for CodeGraph Memory");
|
|
284426
285971
|
console.error(" checkpoint Inspect native compact continuity checkpoints");
|
|
284427
285972
|
console.error(" knowledge Review source-backed knowledge pages and project workflows");
|
|
285973
|
+
console.error(" evidence Inspect source-backed evidence cards");
|
|
285974
|
+
console.error(" feedback Record or audit memory feedback");
|
|
284428
285975
|
console.error(" reasoning Store/search decision rationale");
|
|
284429
285976
|
console.error(" retention Inspect stale/archive status");
|
|
284430
285977
|
console.error(" formation Inspect Memory Formation metrics");
|