memorix 1.2.6 → 1.2.7
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 +12 -0
- package/README.md +6 -3
- package/README.zh-CN.md +5 -2
- package/dist/cli/index.js +954 -72
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/memcode.js +0 -0
- package/dist/index.js +632 -27
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.js +39 -1
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +12 -0
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.js +632 -27
- package/dist/sdk.js.map +1 -1
- package/dist/types.d.ts +38 -1
- package/dist/types.js.map +1 -1
- package/docs/1.2.7-CONTEXT-CONTINUITY.md +68 -0
- package/docs/API_REFERENCE.md +6 -2
- package/docs/dev-log/progress.txt +23 -0
- package/docs/hooks-architecture.md +2 -1
- package/package.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/extensions/memorix.js +17 -0
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/extensions/memorix.js +17 -0
- package/plugins/pi/memorix/package.json +1 -1
- package/src/cli/capability-map.ts +1 -0
- package/src/cli/command-guide.ts +10 -0
- package/src/cli/commands/checkpoint.ts +144 -0
- package/src/cli/index.ts +3 -1
- package/src/codegraph/auto-context.ts +51 -5
- package/src/hooks/handler.ts +103 -11
- package/src/hooks/normalizer.ts +85 -1
- package/src/hooks/types.ts +16 -0
- package/src/knowledge/workset.ts +43 -2
- package/src/memory/compaction.ts +165 -0
- package/src/server/tool-profile.ts +1 -0
- package/src/server.ts +94 -0
- package/src/store/compaction-checkpoint-store.ts +397 -0
- package/src/store/sqlite-db.ts +41 -0
- package/src/types.ts +46 -0
package/dist/cli/index.js
CHANGED
|
@@ -3212,7 +3212,7 @@ ${import_picocolors.default.gray(m3)} ${s2}
|
|
|
3212
3212
|
|
|
3213
3213
|
// src/cli/version.ts
|
|
3214
3214
|
function getCliVersion() {
|
|
3215
|
-
return true ? "1.2.
|
|
3215
|
+
return true ? "1.2.7" : pkg.version;
|
|
3216
3216
|
}
|
|
3217
3217
|
var init_version = __esm({
|
|
3218
3218
|
"src/cli/version.ts"() {
|
|
@@ -9304,6 +9304,7 @@ function getDatabase(dataDir) {
|
|
|
9304
9304
|
db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
|
|
9305
9305
|
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
9306
9306
|
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
9307
|
+
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
9307
9308
|
try {
|
|
9308
9309
|
db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
|
|
9309
9310
|
} catch {
|
|
@@ -9344,7 +9345,7 @@ function getDatabase(dataDir) {
|
|
|
9344
9345
|
_dbCache.set(normalized, db2);
|
|
9345
9346
|
return db2;
|
|
9346
9347
|
}
|
|
9347
|
-
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_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_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
9348
|
+
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_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_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
9348
9349
|
var init_sqlite_db = __esm({
|
|
9349
9350
|
"src/store/sqlite-db.ts"() {
|
|
9350
9351
|
"use strict";
|
|
@@ -9796,6 +9797,31 @@ CREATE TABLE IF NOT EXISTS maintenance_targets (
|
|
|
9796
9797
|
data_dir TEXT NOT NULL,
|
|
9797
9798
|
updated_at INTEGER NOT NULL
|
|
9798
9799
|
);
|
|
9800
|
+
`;
|
|
9801
|
+
CREATE_COMPACTION_CHECKPOINTS_TABLE = `
|
|
9802
|
+
CREATE TABLE IF NOT EXISTS compaction_checkpoints (
|
|
9803
|
+
id TEXT PRIMARY KEY,
|
|
9804
|
+
project_id TEXT NOT NULL,
|
|
9805
|
+
session_id TEXT NOT NULL,
|
|
9806
|
+
agent TEXT NOT NULL,
|
|
9807
|
+
phase TEXT NOT NULL,
|
|
9808
|
+
capture_kind TEXT NOT NULL,
|
|
9809
|
+
reason TEXT NOT NULL DEFAULT 'unknown',
|
|
9810
|
+
source_event TEXT NOT NULL,
|
|
9811
|
+
source_key TEXT NOT NULL,
|
|
9812
|
+
summary TEXT,
|
|
9813
|
+
tokens_before INTEGER,
|
|
9814
|
+
first_kept_entry_id TEXT,
|
|
9815
|
+
details_json TEXT NOT NULL DEFAULT '{}',
|
|
9816
|
+
transcript_available INTEGER NOT NULL DEFAULT 0,
|
|
9817
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
9818
|
+
pre_captured_at TEXT NOT NULL,
|
|
9819
|
+
completed_at TEXT,
|
|
9820
|
+
delivered_at TEXT,
|
|
9821
|
+
delivery_count INTEGER NOT NULL DEFAULT 0,
|
|
9822
|
+
created_at TEXT NOT NULL,
|
|
9823
|
+
updated_at TEXT NOT NULL
|
|
9824
|
+
);
|
|
9799
9825
|
`;
|
|
9800
9826
|
CREATE_INDEXES = `
|
|
9801
9827
|
CREATE INDEX IF NOT EXISTS idx_observations_projectId ON observations(projectId);
|
|
@@ -9843,6 +9869,9 @@ CREATE INDEX IF NOT EXISTS idx_knowledge_workflow_runs_project_workflow ON knowl
|
|
|
9843
9869
|
CREATE INDEX IF NOT EXISTS idx_maintenance_jobs_ready ON maintenance_jobs(status, run_after);
|
|
9844
9870
|
CREATE INDEX IF NOT EXISTS idx_maintenance_jobs_project ON maintenance_jobs(project_id, status, run_after);
|
|
9845
9871
|
CREATE INDEX IF NOT EXISTS idx_maintenance_targets_updated ON maintenance_targets(updated_at);
|
|
9872
|
+
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_project_recent ON compaction_checkpoints(project_id, status, completed_at DESC, pre_captured_at DESC);
|
|
9873
|
+
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_session_pending ON compaction_checkpoints(project_id, session_id, agent, phase, status, pre_captured_at DESC);
|
|
9874
|
+
CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_source ON compaction_checkpoints(project_id, source_key);
|
|
9846
9875
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
9847
9876
|
ON maintenance_jobs(project_id, kind, dedupe_key)
|
|
9848
9877
|
WHERE status IN ('pending', 'running', 'retry');
|
|
@@ -9916,6 +9945,15 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
9916
9945
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_knowledge_workflows_workspace_status ON knowledge_workflows(workspaceId, status, updatedAt DESC)");
|
|
9917
9946
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_knowledge_workflow_runs_project_workflow ON knowledge_workflow_runs(projectId, workflowId, startedAt DESC)");
|
|
9918
9947
|
}
|
|
9948
|
+
},
|
|
9949
|
+
{
|
|
9950
|
+
id: "1.2.7-compaction-checkpoints",
|
|
9951
|
+
apply: (db2) => {
|
|
9952
|
+
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
9953
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_project_recent ON compaction_checkpoints(project_id, status, completed_at DESC, pre_captured_at DESC)");
|
|
9954
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_session_pending ON compaction_checkpoints(project_id, session_id, agent, phase, status, pre_captured_at DESC)");
|
|
9955
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_source ON compaction_checkpoints(project_id, source_key)");
|
|
9956
|
+
}
|
|
9919
9957
|
}
|
|
9920
9958
|
];
|
|
9921
9959
|
_dbCache = /* @__PURE__ */ new Map();
|
|
@@ -18126,10 +18164,10 @@ var init_store = __esm({
|
|
|
18126
18164
|
return row ? rowToSnapshot(row) : void 0;
|
|
18127
18165
|
}
|
|
18128
18166
|
listSnapshots(projectId, limit = 20) {
|
|
18129
|
-
const
|
|
18167
|
+
const safeLimit2 = Number.isFinite(limit) ? Math.max(1, Math.min(200, Math.floor(limit))) : 20;
|
|
18130
18168
|
return this.db.prepare(
|
|
18131
18169
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
18132
|
-
).all(projectId,
|
|
18170
|
+
).all(projectId, safeLimit2).map(rowToSnapshot);
|
|
18133
18171
|
}
|
|
18134
18172
|
/**
|
|
18135
18173
|
* Record a completed scan and mark all current structural facts with its
|
|
@@ -34934,7 +34972,7 @@ function renderTaskWorksetPrompt(input) {
|
|
|
34934
34972
|
});
|
|
34935
34973
|
appendLine(lines, "Task lens: " + input.lens, maxTokens, omitted, "lens");
|
|
34936
34974
|
const hasContinuation = Boolean(
|
|
34937
|
-
input.continuation?.previousSession || (input.continuation?.memories.length ?? 0) > 0
|
|
34975
|
+
input.continuation?.previousSession || (input.continuation?.memories.length ?? 0) > 0 || input.continuation?.compactCheckpoint
|
|
34938
34976
|
);
|
|
34939
34977
|
if (hasContinuation && input.continuation) {
|
|
34940
34978
|
appendLine(lines, "", maxTokens, omitted, "continuation-heading");
|
|
@@ -34974,6 +35012,24 @@ function renderTaskWorksetPrompt(input) {
|
|
|
34974
35012
|
}
|
|
34975
35013
|
);
|
|
34976
35014
|
}
|
|
35015
|
+
if (input.continuation.compactCheckpoint) {
|
|
35016
|
+
const checkpoint = input.continuation.compactCheckpoint;
|
|
35017
|
+
const source = `${checkpoint.agent}, ${checkpoint.captureKind}, ${checkpoint.reason}`;
|
|
35018
|
+
appendLine(
|
|
35019
|
+
lines,
|
|
35020
|
+
"- Recent host compact checkpoint (" + source + "): " + short(checkpoint.summary, 36),
|
|
35021
|
+
maxTokens,
|
|
35022
|
+
omitted,
|
|
35023
|
+
"continuation-compact-checkpoint",
|
|
35024
|
+
selected,
|
|
35025
|
+
{
|
|
35026
|
+
kind: "continuation",
|
|
35027
|
+
id: "compact:" + checkpoint.id,
|
|
35028
|
+
reason: "recent host-native compact lifecycle evidence",
|
|
35029
|
+
trust: "historical"
|
|
35030
|
+
}
|
|
35031
|
+
);
|
|
35032
|
+
}
|
|
34977
35033
|
}
|
|
34978
35034
|
if (input.cautions.length > 0 || input.cautionMemory.length > 0) {
|
|
34979
35035
|
appendLine(lines, "", maxTokens, omitted, "caution-heading");
|
|
@@ -35243,7 +35299,7 @@ async function buildTaskWorkset(input) {
|
|
|
35243
35299
|
...input.verificationHints
|
|
35244
35300
|
]).slice(0, 4);
|
|
35245
35301
|
const normalizedCautions = unique(cautions.map((caution) => caution.kind)).map((kind) => cautions.find((caution) => caution.kind === kind)).slice(0, 6);
|
|
35246
|
-
const continuation = input.continuation && (input.continuation.previousSession || input.continuation.memories.length > 0) ? {
|
|
35302
|
+
const continuation = input.continuation && (input.continuation.previousSession || input.continuation.memories.length > 0 || input.continuation.compactCheckpoint) ? {
|
|
35247
35303
|
...input.continuation.previousSession ? {
|
|
35248
35304
|
previousSession: {
|
|
35249
35305
|
...input.continuation.previousSession,
|
|
@@ -35254,7 +35310,13 @@ async function buildTaskWorkset(input) {
|
|
|
35254
35310
|
...memory,
|
|
35255
35311
|
title: short(memory.title, 20),
|
|
35256
35312
|
...memory.detail ? { detail: short(memory.detail, CONTINUATION_DETAIL_TOKEN_BUDGET) } : {}
|
|
35257
|
-
}))
|
|
35313
|
+
})),
|
|
35314
|
+
...input.continuation.compactCheckpoint ? {
|
|
35315
|
+
compactCheckpoint: {
|
|
35316
|
+
...input.continuation.compactCheckpoint,
|
|
35317
|
+
summary: short(input.continuation.compactCheckpoint.summary, 44)
|
|
35318
|
+
}
|
|
35319
|
+
} : {}
|
|
35258
35320
|
} : void 0;
|
|
35259
35321
|
const base = {
|
|
35260
35322
|
version: "1.2",
|
|
@@ -37477,6 +37539,311 @@ var init_session = __esm({
|
|
|
37477
37539
|
}
|
|
37478
37540
|
});
|
|
37479
37541
|
|
|
37542
|
+
// src/store/compaction-checkpoint-store.ts
|
|
37543
|
+
var compaction_checkpoint_store_exports = {};
|
|
37544
|
+
__export(compaction_checkpoint_store_exports, {
|
|
37545
|
+
CompactionCheckpointStore: () => CompactionCheckpointStore
|
|
37546
|
+
});
|
|
37547
|
+
import { createHash as createHash10, randomUUID as randomUUID9 } from "crypto";
|
|
37548
|
+
function optionalText5(value) {
|
|
37549
|
+
return typeof value === "string" && value ? value : void 0;
|
|
37550
|
+
}
|
|
37551
|
+
function optionalNumber2(value) {
|
|
37552
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
37553
|
+
}
|
|
37554
|
+
function parseDetails(value) {
|
|
37555
|
+
if (typeof value !== "string" || !value) return void 0;
|
|
37556
|
+
try {
|
|
37557
|
+
const parsed = JSON.parse(value);
|
|
37558
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
37559
|
+
} catch {
|
|
37560
|
+
return void 0;
|
|
37561
|
+
}
|
|
37562
|
+
}
|
|
37563
|
+
function sanitizeSummary(value) {
|
|
37564
|
+
if (!value?.trim()) return void 0;
|
|
37565
|
+
return sanitizeCredentials(value).slice(0, MAX_SUMMARY_CHARS).trim() || void 0;
|
|
37566
|
+
}
|
|
37567
|
+
function sanitizeDetails(value) {
|
|
37568
|
+
if (!value) return void 0;
|
|
37569
|
+
try {
|
|
37570
|
+
const sanitized = sanitizeCredentials(JSON.stringify(value));
|
|
37571
|
+
if (sanitized.length > MAX_DETAILS_CHARS) return { truncated: true };
|
|
37572
|
+
const parsed = JSON.parse(sanitized);
|
|
37573
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
|
|
37574
|
+
} catch {
|
|
37575
|
+
return { unavailable: true };
|
|
37576
|
+
}
|
|
37577
|
+
}
|
|
37578
|
+
function sourceKeyFor(input, summary) {
|
|
37579
|
+
if (input.sourceKey?.trim()) return input.sourceKey.trim().slice(0, 300);
|
|
37580
|
+
const material = [
|
|
37581
|
+
input.projectId,
|
|
37582
|
+
input.sessionId,
|
|
37583
|
+
input.agent,
|
|
37584
|
+
input.sourceEvent,
|
|
37585
|
+
summary ?? "",
|
|
37586
|
+
input.tokensBefore ?? "",
|
|
37587
|
+
input.firstKeptEntryId ?? ""
|
|
37588
|
+
].join("\0");
|
|
37589
|
+
return `derived:${createHash10("sha256").update(material).digest("hex").slice(0, 32)}`;
|
|
37590
|
+
}
|
|
37591
|
+
function rowToCheckpoint(row) {
|
|
37592
|
+
return {
|
|
37593
|
+
id: row.id,
|
|
37594
|
+
projectId: row.project_id,
|
|
37595
|
+
sessionId: row.session_id,
|
|
37596
|
+
agent: row.agent,
|
|
37597
|
+
phase: row.phase,
|
|
37598
|
+
captureKind: row.capture_kind,
|
|
37599
|
+
reason: row.reason,
|
|
37600
|
+
sourceEvent: row.source_event,
|
|
37601
|
+
sourceKey: row.source_key,
|
|
37602
|
+
...optionalText5(row.summary) ? { summary: row.summary } : {},
|
|
37603
|
+
...optionalNumber2(row.tokens_before) !== void 0 ? { tokensBefore: Number(row.tokens_before) } : {},
|
|
37604
|
+
...optionalText5(row.first_kept_entry_id) ? { firstKeptEntryId: row.first_kept_entry_id } : {},
|
|
37605
|
+
...parseDetails(row.details_json) ? { details: parseDetails(row.details_json) } : {},
|
|
37606
|
+
transcriptAvailable: Boolean(row.transcript_available),
|
|
37607
|
+
status: row.status,
|
|
37608
|
+
preCapturedAt: row.pre_captured_at,
|
|
37609
|
+
...optionalText5(row.completed_at) ? { completedAt: row.completed_at } : {},
|
|
37610
|
+
...optionalText5(row.delivered_at) ? { deliveredAt: row.delivered_at } : {},
|
|
37611
|
+
deliveryCount: Number(row.delivery_count ?? 0),
|
|
37612
|
+
createdAt: row.created_at,
|
|
37613
|
+
updatedAt: row.updated_at
|
|
37614
|
+
};
|
|
37615
|
+
}
|
|
37616
|
+
function safeReason(value) {
|
|
37617
|
+
return value === "manual" || value === "auto" ? value : "unknown";
|
|
37618
|
+
}
|
|
37619
|
+
function safeLimit(value, fallback) {
|
|
37620
|
+
if (!Number.isFinite(value) || value == null) return fallback;
|
|
37621
|
+
return Math.max(1, Math.min(500, Math.floor(value)));
|
|
37622
|
+
}
|
|
37623
|
+
var MAX_SUMMARY_CHARS, MAX_DETAILS_CHARS, CompactionCheckpointStore;
|
|
37624
|
+
var init_compaction_checkpoint_store = __esm({
|
|
37625
|
+
"src/store/compaction-checkpoint-store.ts"() {
|
|
37626
|
+
"use strict";
|
|
37627
|
+
init_esm_shims();
|
|
37628
|
+
init_secret_filter();
|
|
37629
|
+
init_sqlite_db();
|
|
37630
|
+
MAX_SUMMARY_CHARS = 24e3;
|
|
37631
|
+
MAX_DETAILS_CHARS = 4e3;
|
|
37632
|
+
CompactionCheckpointStore = class {
|
|
37633
|
+
db;
|
|
37634
|
+
constructor(dataDir) {
|
|
37635
|
+
this.db = getDatabase(dataDir);
|
|
37636
|
+
}
|
|
37637
|
+
recordPreflight(input) {
|
|
37638
|
+
const pending = this.db.prepare(`
|
|
37639
|
+
SELECT * FROM compaction_checkpoints
|
|
37640
|
+
WHERE project_id = ? AND session_id = ? AND agent = ?
|
|
37641
|
+
AND phase = 'pre' AND status = 'active'
|
|
37642
|
+
ORDER BY pre_captured_at DESC, created_at DESC
|
|
37643
|
+
LIMIT 1
|
|
37644
|
+
`).get(input.projectId, input.sessionId, input.agent);
|
|
37645
|
+
if (pending) return rowToCheckpoint(pending);
|
|
37646
|
+
const now3 = input.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
37647
|
+
const checkpoint = {
|
|
37648
|
+
id: randomUUID9(),
|
|
37649
|
+
projectId: input.projectId,
|
|
37650
|
+
sessionId: input.sessionId,
|
|
37651
|
+
agent: input.agent,
|
|
37652
|
+
phase: "pre",
|
|
37653
|
+
captureKind: "preflight",
|
|
37654
|
+
reason: safeReason(input.reason),
|
|
37655
|
+
sourceEvent: input.sourceEvent,
|
|
37656
|
+
sourceKey: `pre:${randomUUID9()}`,
|
|
37657
|
+
transcriptAvailable: Boolean(input.transcriptAvailable),
|
|
37658
|
+
status: "active",
|
|
37659
|
+
preCapturedAt: now3,
|
|
37660
|
+
deliveryCount: 0,
|
|
37661
|
+
createdAt: now3,
|
|
37662
|
+
updatedAt: now3
|
|
37663
|
+
};
|
|
37664
|
+
this.insert(checkpoint);
|
|
37665
|
+
return checkpoint;
|
|
37666
|
+
}
|
|
37667
|
+
complete(input) {
|
|
37668
|
+
const completedAt = input.completedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
37669
|
+
const summary = sanitizeSummary(input.summary);
|
|
37670
|
+
const pending = this.db.prepare(`
|
|
37671
|
+
SELECT * FROM compaction_checkpoints
|
|
37672
|
+
WHERE project_id = ? AND session_id = ? AND agent = ?
|
|
37673
|
+
AND phase = 'pre' AND status = 'active'
|
|
37674
|
+
ORDER BY pre_captured_at DESC, created_at DESC
|
|
37675
|
+
LIMIT 1
|
|
37676
|
+
`).get(input.projectId, input.sessionId, input.agent);
|
|
37677
|
+
if (!input.sourceKey?.trim() && !summary && input.tokensBefore === void 0 && !input.firstKeptEntryId && !pending) {
|
|
37678
|
+
const priorLifecycle = this.db.prepare(`
|
|
37679
|
+
SELECT * FROM compaction_checkpoints
|
|
37680
|
+
WHERE project_id = ? AND session_id = ? AND agent = ?
|
|
37681
|
+
AND phase = 'complete' AND capture_kind = 'lifecycle'
|
|
37682
|
+
AND source_event = ? AND status = 'active'
|
|
37683
|
+
ORDER BY completed_at DESC, created_at DESC
|
|
37684
|
+
LIMIT 1
|
|
37685
|
+
`).get(input.projectId, input.sessionId, input.agent, input.sourceEvent);
|
|
37686
|
+
if (priorLifecycle) return rowToCheckpoint(priorLifecycle);
|
|
37687
|
+
}
|
|
37688
|
+
const sourceKey = input.sourceKey?.trim() ? input.sourceKey.trim().slice(0, 300) : pending ? `lifecycle:${pending.id}` : sourceKeyFor(input, summary);
|
|
37689
|
+
const existing = this.db.prepare(`
|
|
37690
|
+
SELECT * FROM compaction_checkpoints
|
|
37691
|
+
WHERE project_id = ? AND source_key = ?
|
|
37692
|
+
LIMIT 1
|
|
37693
|
+
`).get(input.projectId, sourceKey);
|
|
37694
|
+
if (existing) return rowToCheckpoint(existing);
|
|
37695
|
+
const captureKind = summary ? "native-summary" : "lifecycle";
|
|
37696
|
+
const details = sanitizeDetails(input.details);
|
|
37697
|
+
if (pending) {
|
|
37698
|
+
const checkpoint2 = rowToCheckpoint(pending);
|
|
37699
|
+
const nextReason = safeReason(input.reason) === "unknown" ? checkpoint2.reason : safeReason(input.reason);
|
|
37700
|
+
this.db.prepare(`
|
|
37701
|
+
UPDATE compaction_checkpoints
|
|
37702
|
+
SET phase = 'complete', capture_kind = ?, reason = ?, source_event = ?, source_key = ?,
|
|
37703
|
+
summary = ?, tokens_before = ?, first_kept_entry_id = ?, details_json = ?,
|
|
37704
|
+
completed_at = ?, updated_at = ?
|
|
37705
|
+
WHERE id = ?
|
|
37706
|
+
`).run(
|
|
37707
|
+
captureKind,
|
|
37708
|
+
nextReason,
|
|
37709
|
+
input.sourceEvent,
|
|
37710
|
+
sourceKey,
|
|
37711
|
+
summary ?? null,
|
|
37712
|
+
input.tokensBefore ?? null,
|
|
37713
|
+
input.firstKeptEntryId ?? null,
|
|
37714
|
+
JSON.stringify(details ?? {}),
|
|
37715
|
+
completedAt,
|
|
37716
|
+
completedAt,
|
|
37717
|
+
checkpoint2.id
|
|
37718
|
+
);
|
|
37719
|
+
return this.get(checkpoint2.id);
|
|
37720
|
+
}
|
|
37721
|
+
const checkpoint = {
|
|
37722
|
+
id: randomUUID9(),
|
|
37723
|
+
projectId: input.projectId,
|
|
37724
|
+
sessionId: input.sessionId,
|
|
37725
|
+
agent: input.agent,
|
|
37726
|
+
phase: "complete",
|
|
37727
|
+
captureKind,
|
|
37728
|
+
reason: safeReason(input.reason),
|
|
37729
|
+
sourceEvent: input.sourceEvent,
|
|
37730
|
+
sourceKey,
|
|
37731
|
+
...summary ? { summary } : {},
|
|
37732
|
+
...input.tokensBefore !== void 0 ? { tokensBefore: input.tokensBefore } : {},
|
|
37733
|
+
...input.firstKeptEntryId ? { firstKeptEntryId: input.firstKeptEntryId } : {},
|
|
37734
|
+
...details ? { details } : {},
|
|
37735
|
+
transcriptAvailable: false,
|
|
37736
|
+
status: "active",
|
|
37737
|
+
preCapturedAt: completedAt,
|
|
37738
|
+
completedAt,
|
|
37739
|
+
deliveryCount: 0,
|
|
37740
|
+
createdAt: completedAt,
|
|
37741
|
+
updatedAt: completedAt
|
|
37742
|
+
};
|
|
37743
|
+
this.insert(checkpoint);
|
|
37744
|
+
return checkpoint;
|
|
37745
|
+
}
|
|
37746
|
+
get(id) {
|
|
37747
|
+
const row = this.db.prepare("SELECT * FROM compaction_checkpoints WHERE id = ?").get(id);
|
|
37748
|
+
return row ? rowToCheckpoint(row) : void 0;
|
|
37749
|
+
}
|
|
37750
|
+
list(options2) {
|
|
37751
|
+
const conditions = ["project_id = ?"];
|
|
37752
|
+
const values = [options2.projectId];
|
|
37753
|
+
if (options2.sessionId) {
|
|
37754
|
+
conditions.push("session_id = ?");
|
|
37755
|
+
values.push(options2.sessionId);
|
|
37756
|
+
}
|
|
37757
|
+
if (options2.agent) {
|
|
37758
|
+
conditions.push("agent = ?");
|
|
37759
|
+
values.push(options2.agent);
|
|
37760
|
+
}
|
|
37761
|
+
if (!options2.includeArchived) {
|
|
37762
|
+
conditions.push("status = 'active'");
|
|
37763
|
+
}
|
|
37764
|
+
const rows = this.db.prepare(`
|
|
37765
|
+
SELECT * FROM compaction_checkpoints
|
|
37766
|
+
WHERE ${conditions.join(" AND ")}
|
|
37767
|
+
ORDER BY COALESCE(completed_at, pre_captured_at) DESC, created_at DESC
|
|
37768
|
+
LIMIT ?
|
|
37769
|
+
`).all(...values, safeLimit(options2.limit, 20));
|
|
37770
|
+
return rows.map(rowToCheckpoint);
|
|
37771
|
+
}
|
|
37772
|
+
findUndelivered(projectId, sessionId, agent) {
|
|
37773
|
+
const row = this.db.prepare(`
|
|
37774
|
+
SELECT * FROM compaction_checkpoints
|
|
37775
|
+
WHERE project_id = ? AND session_id = ? AND agent = ?
|
|
37776
|
+
AND phase = 'complete' AND status = 'active' AND delivered_at IS NULL
|
|
37777
|
+
ORDER BY completed_at DESC, created_at DESC
|
|
37778
|
+
LIMIT 1
|
|
37779
|
+
`).get(projectId, sessionId, agent);
|
|
37780
|
+
return row ? rowToCheckpoint(row) : void 0;
|
|
37781
|
+
}
|
|
37782
|
+
findLatestCompleted(projectId, options2 = {}) {
|
|
37783
|
+
const excludeSession = options2.excludeSession;
|
|
37784
|
+
const exclusion = excludeSession ? " AND NOT (session_id = ? AND agent = ? )" : "";
|
|
37785
|
+
const values = excludeSession ? [projectId, excludeSession.sessionId, excludeSession.agent] : [projectId];
|
|
37786
|
+
const row = this.db.prepare(`
|
|
37787
|
+
SELECT * FROM compaction_checkpoints
|
|
37788
|
+
WHERE project_id = ? AND phase = 'complete' AND status = 'active'
|
|
37789
|
+
${exclusion}
|
|
37790
|
+
ORDER BY completed_at DESC, created_at DESC
|
|
37791
|
+
LIMIT 1
|
|
37792
|
+
`).get(...values);
|
|
37793
|
+
return row ? rowToCheckpoint(row) : void 0;
|
|
37794
|
+
}
|
|
37795
|
+
archive(id, archivedAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
37796
|
+
const result = this.db.prepare(`
|
|
37797
|
+
UPDATE compaction_checkpoints
|
|
37798
|
+
SET status = 'archived', updated_at = ?
|
|
37799
|
+
WHERE id = ? AND status = 'active'
|
|
37800
|
+
`).run(archivedAt, id);
|
|
37801
|
+
return Number(result.changes ?? 0) > 0 ? this.get(id) : void 0;
|
|
37802
|
+
}
|
|
37803
|
+
markDelivered(id, deliveredAt = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
37804
|
+
const result = this.db.prepare(`
|
|
37805
|
+
UPDATE compaction_checkpoints
|
|
37806
|
+
SET delivered_at = ?, delivery_count = delivery_count + 1, updated_at = ?
|
|
37807
|
+
WHERE id = ? AND phase = 'complete' AND status = 'active' AND delivered_at IS NULL
|
|
37808
|
+
`).run(deliveredAt, deliveredAt, id);
|
|
37809
|
+
return Number(result.changes ?? 0) > 0 ? this.get(id) : void 0;
|
|
37810
|
+
}
|
|
37811
|
+
insert(checkpoint) {
|
|
37812
|
+
this.db.prepare(`
|
|
37813
|
+
INSERT INTO compaction_checkpoints (
|
|
37814
|
+
id, project_id, session_id, agent, phase, capture_kind, reason,
|
|
37815
|
+
source_event, source_key, summary, tokens_before, first_kept_entry_id,
|
|
37816
|
+
details_json, transcript_available, status, pre_captured_at, completed_at,
|
|
37817
|
+
delivered_at, delivery_count, created_at, updated_at
|
|
37818
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
37819
|
+
`).run(
|
|
37820
|
+
checkpoint.id,
|
|
37821
|
+
checkpoint.projectId,
|
|
37822
|
+
checkpoint.sessionId,
|
|
37823
|
+
checkpoint.agent,
|
|
37824
|
+
checkpoint.phase,
|
|
37825
|
+
checkpoint.captureKind,
|
|
37826
|
+
checkpoint.reason,
|
|
37827
|
+
checkpoint.sourceEvent,
|
|
37828
|
+
checkpoint.sourceKey,
|
|
37829
|
+
checkpoint.summary ?? null,
|
|
37830
|
+
checkpoint.tokensBefore ?? null,
|
|
37831
|
+
checkpoint.firstKeptEntryId ?? null,
|
|
37832
|
+
JSON.stringify(checkpoint.details ?? {}),
|
|
37833
|
+
checkpoint.transcriptAvailable ? 1 : 0,
|
|
37834
|
+
checkpoint.status,
|
|
37835
|
+
checkpoint.preCapturedAt,
|
|
37836
|
+
checkpoint.completedAt ?? null,
|
|
37837
|
+
checkpoint.deliveredAt ?? null,
|
|
37838
|
+
checkpoint.deliveryCount,
|
|
37839
|
+
checkpoint.createdAt,
|
|
37840
|
+
checkpoint.updatedAt
|
|
37841
|
+
);
|
|
37842
|
+
}
|
|
37843
|
+
};
|
|
37844
|
+
}
|
|
37845
|
+
});
|
|
37846
|
+
|
|
37480
37847
|
// src/codegraph/auto-context.ts
|
|
37481
37848
|
var auto_context_exports = {};
|
|
37482
37849
|
__export(auto_context_exports, {
|
|
@@ -37662,6 +38029,22 @@ async function buildAutoProjectContext(input) {
|
|
|
37662
38029
|
if (continuationRequested) {
|
|
37663
38030
|
await initSessionStore(input.dataDir);
|
|
37664
38031
|
continuation = await getSessionResumeBrief(input.project.id, task, input.reader);
|
|
38032
|
+
const { CompactionCheckpointStore: CompactionCheckpointStore2 } = await Promise.resolve().then(() => (init_compaction_checkpoint_store(), compaction_checkpoint_store_exports));
|
|
38033
|
+
const checkpoint = new CompactionCheckpointStore2(input.dataDir).findLatestCompleted(
|
|
38034
|
+
input.project.id,
|
|
38035
|
+
input.excludeCompactionCheckpointFor ? { excludeSession: input.excludeCompactionCheckpointFor } : void 0
|
|
38036
|
+
);
|
|
38037
|
+
const completedAtMs = checkpoint ? Date.parse(checkpoint.completedAt ?? checkpoint.preCapturedAt) : Number.NaN;
|
|
38038
|
+
if (checkpoint && Number.isFinite(completedAtMs) && completedAtMs <= now3.getTime() && now3.getTime() - completedAtMs <= COMPACT_CHECKPOINT_MAX_AGE_MS) {
|
|
38039
|
+
continuation.compactCheckpoint = {
|
|
38040
|
+
id: checkpoint.id,
|
|
38041
|
+
agent: checkpoint.agent,
|
|
38042
|
+
captureKind: checkpoint.captureKind === "native-summary" ? "native-summary" : "lifecycle",
|
|
38043
|
+
reason: checkpoint.reason,
|
|
38044
|
+
...checkpoint.completedAt ? { completedAt: checkpoint.completedAt } : {},
|
|
38045
|
+
summary: checkpoint.summary ?? "The host completed context compaction without exposing a native summary. Reconstruct only what the current task needs from current code and durable evidence."
|
|
38046
|
+
};
|
|
38047
|
+
}
|
|
37665
38048
|
}
|
|
37666
38049
|
const workset = await buildTaskWorkset({
|
|
37667
38050
|
projectId: input.project.id,
|
|
@@ -37870,7 +38253,7 @@ function formatAutoProjectContextSummary(context) {
|
|
|
37870
38253
|
reliableSources.length > 0 ? `- ${reliableSources.length} current code-bound memory link(s)` : "- none yet"
|
|
37871
38254
|
);
|
|
37872
38255
|
const continuation = context.workset.continuation;
|
|
37873
|
-
if (continuation?.previousSession || continuation?.memories.length) {
|
|
38256
|
+
if (continuation?.previousSession || continuation?.memories.length || continuation?.compactCheckpoint) {
|
|
37874
38257
|
lines.push("", "Resume from prior work");
|
|
37875
38258
|
if (continuation.previousSession) {
|
|
37876
38259
|
const session = continuation.previousSession;
|
|
@@ -37885,6 +38268,12 @@ function formatAutoProjectContextSummary(context) {
|
|
|
37885
38268
|
"- #" + memory.id + " " + memory.type + ": " + compactContinuationText(memory.title, 18) + detail
|
|
37886
38269
|
);
|
|
37887
38270
|
}
|
|
38271
|
+
if (continuation.compactCheckpoint) {
|
|
38272
|
+
const checkpoint = continuation.compactCheckpoint;
|
|
38273
|
+
lines.push(
|
|
38274
|
+
"- Recent host compact checkpoint (" + [checkpoint.agent, checkpoint.captureKind, checkpoint.reason].join(", ") + "): " + compactContinuationText(checkpoint.summary, 36)
|
|
38275
|
+
);
|
|
38276
|
+
}
|
|
37888
38277
|
}
|
|
37889
38278
|
return lines.join("\n");
|
|
37890
38279
|
}
|
|
@@ -37951,7 +38340,7 @@ function formatLegacyAutoProjectContextPrompt(context) {
|
|
|
37951
38340
|
);
|
|
37952
38341
|
return lines.join("\n");
|
|
37953
38342
|
}
|
|
37954
|
-
var DEFAULT_MAX_AGE_MS;
|
|
38343
|
+
var DEFAULT_MAX_AGE_MS, COMPACT_CHECKPOINT_MAX_AGE_MS;
|
|
37955
38344
|
var init_auto_context = __esm({
|
|
37956
38345
|
"src/codegraph/auto-context.ts"() {
|
|
37957
38346
|
"use strict";
|
|
@@ -37971,6 +38360,7 @@ var init_auto_context = __esm({
|
|
|
37971
38360
|
init_session_store();
|
|
37972
38361
|
init_task_lens();
|
|
37973
38362
|
DEFAULT_MAX_AGE_MS = 10 * 60 * 1e3;
|
|
38363
|
+
COMPACT_CHECKPOINT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
37974
38364
|
}
|
|
37975
38365
|
});
|
|
37976
38366
|
|
|
@@ -38235,7 +38625,7 @@ function addDefaultVerificationHints(input) {
|
|
|
38235
38625
|
return uniq2(hints);
|
|
38236
38626
|
}
|
|
38237
38627
|
function selectRelevantObservations(observations2, task, limit) {
|
|
38238
|
-
const
|
|
38628
|
+
const safeLimit2 = Number.isFinite(limit) && limit > 0 ? Math.floor(limit) : 20;
|
|
38239
38629
|
const taskTokens2 = tokenize4(task);
|
|
38240
38630
|
const ranked = observations2.map((observation, index) => ({
|
|
38241
38631
|
observation,
|
|
@@ -38245,7 +38635,7 @@ function selectRelevantObservations(observations2, task, limit) {
|
|
|
38245
38635
|
}));
|
|
38246
38636
|
const positives = ranked.filter((item) => item.score > 0);
|
|
38247
38637
|
const pool = positives.length > 0 ? positives : ranked;
|
|
38248
|
-
return pool.sort((a3, b3) => b3.score - a3.score || b3.time - a3.time || b3.index - a3.index).slice(0,
|
|
38638
|
+
return pool.sort((a3, b3) => b3.score - a3.score || b3.time - a3.time || b3.index - a3.index).slice(0, safeLimit2).map((item) => item.observation);
|
|
38249
38639
|
}
|
|
38250
38640
|
function assembleContextPackForTask(input) {
|
|
38251
38641
|
const selected = selectRelevantObservations(input.observations, input.task, input.limit ?? 20);
|
|
@@ -38642,12 +39032,277 @@ ${formatUsageHint()}`;
|
|
|
38642
39032
|
}
|
|
38643
39033
|
});
|
|
38644
39034
|
|
|
39035
|
+
// src/memory/compaction.ts
|
|
39036
|
+
var compaction_exports = {};
|
|
39037
|
+
__export(compaction_exports, {
|
|
39038
|
+
buildCompactionWorkset: () => buildCompactionWorkset,
|
|
39039
|
+
captureCompactionCheckpoint: () => captureCompactionCheckpoint,
|
|
39040
|
+
consumeCompactionWorkset: () => consumeCompactionWorkset
|
|
39041
|
+
});
|
|
39042
|
+
function normalizeBudget(value) {
|
|
39043
|
+
if (!Number.isFinite(value) || value == null) return DEFAULT_WORKSET_BUDGET;
|
|
39044
|
+
return Math.max(MIN_WORKSET_BUDGET, Math.min(2e3, Math.floor(value)));
|
|
39045
|
+
}
|
|
39046
|
+
function sourceLabel(checkpoint) {
|
|
39047
|
+
if (checkpoint.captureKind === "native-summary") return "native host summary";
|
|
39048
|
+
if (checkpoint.captureKind === "preflight") return "pre-compact lifecycle marker";
|
|
39049
|
+
return "host lifecycle marker";
|
|
39050
|
+
}
|
|
39051
|
+
function buildCompactionWorkset(checkpoint, options2 = {}) {
|
|
39052
|
+
const budget = normalizeBudget(options2.maxTokens);
|
|
39053
|
+
const task = options2.task?.trim() ? truncateToTokenBudget(sanitizeCredentials(options2.task.trim()), Math.max(8, Math.floor(budget * 0.25))) : "";
|
|
39054
|
+
const headerLines = [
|
|
39055
|
+
"## Compact Continuation",
|
|
39056
|
+
`- Host: ${checkpoint.agent} (${sourceLabel(checkpoint)})`,
|
|
39057
|
+
`- Trigger: ${checkpoint.reason}`,
|
|
39058
|
+
task ? `- Task now: ${task}` : "",
|
|
39059
|
+
"- Current code remains authoritative."
|
|
39060
|
+
].filter(Boolean);
|
|
39061
|
+
const header = `${headerLines.join("\n")}
|
|
39062
|
+
|
|
39063
|
+
`;
|
|
39064
|
+
const fallback = checkpoint.captureKind === "native-summary" ? "" : "The host did not expose a native compact summary. Reconstruct only what the current task needs from current code and Memorix evidence.";
|
|
39065
|
+
const source = sanitizeCredentials(checkpoint.summary?.trim() || fallback);
|
|
39066
|
+
const available = Math.max(0, budget - countTextTokens(header) - 4);
|
|
39067
|
+
let excerpt = source ? truncateToTokenBudget(source, available) : "";
|
|
39068
|
+
let text = `${header}${excerpt ? `### Host checkpoint
|
|
39069
|
+
${excerpt}` : ""}`.trim();
|
|
39070
|
+
while (excerpt && countTextTokens(text) > budget) {
|
|
39071
|
+
const nextExcerptBudget = Math.max(1, Math.floor(countTextTokens(excerpt) * 0.8));
|
|
39072
|
+
excerpt = truncateToTokenBudget(excerpt, nextExcerptBudget);
|
|
39073
|
+
text = `${header}${excerpt ? `### Host checkpoint
|
|
39074
|
+
${excerpt}` : ""}`.trim();
|
|
39075
|
+
}
|
|
39076
|
+
if (countTextTokens(text) > budget) text = truncateToTokenBudget(text, budget);
|
|
39077
|
+
return {
|
|
39078
|
+
checkpointId: checkpoint.id,
|
|
39079
|
+
text,
|
|
39080
|
+
tokens: countTextTokens(text)
|
|
39081
|
+
};
|
|
39082
|
+
}
|
|
39083
|
+
function sourceEvent(input) {
|
|
39084
|
+
const raw = input.raw;
|
|
39085
|
+
const event = raw.hook_event_name ?? raw.event ?? raw.type;
|
|
39086
|
+
return typeof event === "string" && event ? event : input.event;
|
|
39087
|
+
}
|
|
39088
|
+
async function captureCompactionCheckpoint(input) {
|
|
39089
|
+
const isCompactResume = input.event === "session_start" && input.sessionStartReason?.trim().toLowerCase() === "compact";
|
|
39090
|
+
if (input.event !== "pre_compact" && input.event !== "post_compact" && !isCompactResume) return null;
|
|
39091
|
+
if (!input.sessionId || !input.cwd) return null;
|
|
39092
|
+
const [
|
|
39093
|
+
{ detectProject: detectProject2 },
|
|
39094
|
+
{ getProjectDataDir: getProjectDataDir2 },
|
|
39095
|
+
{ initAliasRegistry: initAliasRegistry2, registerAlias: registerAlias2 }
|
|
39096
|
+
] = await Promise.all([
|
|
39097
|
+
Promise.resolve().then(() => (init_detector(), detector_exports)),
|
|
39098
|
+
Promise.resolve().then(() => (init_persistence(), persistence_exports)),
|
|
39099
|
+
Promise.resolve().then(() => (init_aliases(), aliases_exports))
|
|
39100
|
+
]);
|
|
39101
|
+
const project = detectProject2(input.cwd);
|
|
39102
|
+
if (!project) return null;
|
|
39103
|
+
const dataDir = await getProjectDataDir2(project.id);
|
|
39104
|
+
initAliasRegistry2(dataDir);
|
|
39105
|
+
const projectId = await registerAlias2(project);
|
|
39106
|
+
const store2 = new CompactionCheckpointStore(dataDir);
|
|
39107
|
+
if (input.event === "pre_compact") {
|
|
39108
|
+
return store2.recordPreflight({
|
|
39109
|
+
projectId,
|
|
39110
|
+
sessionId: input.sessionId,
|
|
39111
|
+
agent: input.agent,
|
|
39112
|
+
reason: input.compaction?.reason,
|
|
39113
|
+
sourceEvent: sourceEvent(input),
|
|
39114
|
+
transcriptAvailable: Boolean(input.transcriptPath),
|
|
39115
|
+
capturedAt: input.timestamp
|
|
39116
|
+
});
|
|
39117
|
+
}
|
|
39118
|
+
return store2.complete({
|
|
39119
|
+
projectId,
|
|
39120
|
+
sessionId: input.sessionId,
|
|
39121
|
+
agent: input.agent,
|
|
39122
|
+
reason: input.compaction?.reason,
|
|
39123
|
+
sourceEvent: sourceEvent(input),
|
|
39124
|
+
sourceKey: input.compaction?.sourceKey,
|
|
39125
|
+
summary: input.compaction?.summary,
|
|
39126
|
+
tokensBefore: input.compaction?.tokensBefore,
|
|
39127
|
+
firstKeptEntryId: input.compaction?.firstKeptEntryId,
|
|
39128
|
+
details: input.compaction?.details,
|
|
39129
|
+
completedAt: input.timestamp
|
|
39130
|
+
});
|
|
39131
|
+
}
|
|
39132
|
+
async function consumeCompactionWorkset(input, options2 = {}) {
|
|
39133
|
+
if (!input.sessionId || !input.cwd) return null;
|
|
39134
|
+
const [
|
|
39135
|
+
{ detectProject: detectProject2 },
|
|
39136
|
+
{ getProjectDataDir: getProjectDataDir2 },
|
|
39137
|
+
{ initAliasRegistry: initAliasRegistry2, registerAlias: registerAlias2 }
|
|
39138
|
+
] = await Promise.all([
|
|
39139
|
+
Promise.resolve().then(() => (init_detector(), detector_exports)),
|
|
39140
|
+
Promise.resolve().then(() => (init_persistence(), persistence_exports)),
|
|
39141
|
+
Promise.resolve().then(() => (init_aliases(), aliases_exports))
|
|
39142
|
+
]);
|
|
39143
|
+
const project = detectProject2(input.cwd);
|
|
39144
|
+
if (!project) return null;
|
|
39145
|
+
const dataDir = await getProjectDataDir2(project.id);
|
|
39146
|
+
initAliasRegistry2(dataDir);
|
|
39147
|
+
const projectId = await registerAlias2(project);
|
|
39148
|
+
const store2 = new CompactionCheckpointStore(dataDir);
|
|
39149
|
+
const checkpoint = store2.findUndelivered(projectId, input.sessionId, input.agent);
|
|
39150
|
+
if (!checkpoint) return null;
|
|
39151
|
+
const workset = buildCompactionWorkset(checkpoint, options2);
|
|
39152
|
+
if (!workset.text) return null;
|
|
39153
|
+
store2.markDelivered(checkpoint.id);
|
|
39154
|
+
return workset;
|
|
39155
|
+
}
|
|
39156
|
+
var DEFAULT_WORKSET_BUDGET, MIN_WORKSET_BUDGET;
|
|
39157
|
+
var init_compaction = __esm({
|
|
39158
|
+
"src/memory/compaction.ts"() {
|
|
39159
|
+
"use strict";
|
|
39160
|
+
init_esm_shims();
|
|
39161
|
+
init_token_budget();
|
|
39162
|
+
init_secret_filter();
|
|
39163
|
+
init_compaction_checkpoint_store();
|
|
39164
|
+
DEFAULT_WORKSET_BUDGET = 420;
|
|
39165
|
+
MIN_WORKSET_BUDGET = 48;
|
|
39166
|
+
}
|
|
39167
|
+
});
|
|
39168
|
+
|
|
39169
|
+
// src/cli/commands/checkpoint.ts
|
|
39170
|
+
var checkpoint_exports = {};
|
|
39171
|
+
__export(checkpoint_exports, {
|
|
39172
|
+
default: () => checkpoint_default
|
|
39173
|
+
});
|
|
39174
|
+
async function getCheckpointContext() {
|
|
39175
|
+
const context = await getCliProjectContext();
|
|
39176
|
+
const { initAliasRegistry: initAliasRegistry2, registerAlias: registerAlias2 } = await Promise.resolve().then(() => (init_aliases(), aliases_exports));
|
|
39177
|
+
initAliasRegistry2(context.dataDir);
|
|
39178
|
+
const canonicalId = await registerAlias2(context.project);
|
|
39179
|
+
return {
|
|
39180
|
+
...context,
|
|
39181
|
+
project: { ...context.project, id: canonicalId },
|
|
39182
|
+
store: new CompactionCheckpointStore(context.dataDir)
|
|
39183
|
+
};
|
|
39184
|
+
}
|
|
39185
|
+
function assertProjectCheckpoint(checkpoint, projectId, id) {
|
|
39186
|
+
if (!checkpoint || checkpoint.projectId !== projectId) {
|
|
39187
|
+
throw new Error(`No compact checkpoint "${id}" exists for this project.`);
|
|
39188
|
+
}
|
|
39189
|
+
return checkpoint;
|
|
39190
|
+
}
|
|
39191
|
+
function formatCheckpoint(checkpoint) {
|
|
39192
|
+
const completion = checkpoint.completedAt ? `, completed ${checkpoint.completedAt}` : "";
|
|
39193
|
+
const delivery = checkpoint.deliveredAt ? `, delivered ${checkpoint.deliveryCount}x` : "";
|
|
39194
|
+
return [
|
|
39195
|
+
`${shortId(checkpoint.id)} ${checkpoint.phase} ${checkpoint.agent} (${checkpoint.captureKind}, ${checkpoint.reason})`,
|
|
39196
|
+
` session: ${checkpoint.sessionId}`,
|
|
39197
|
+
` source: ${checkpoint.sourceEvent}${completion}${delivery}`,
|
|
39198
|
+
` status: ${checkpoint.status}${checkpoint.transcriptAvailable ? ", transcript marker available" : ""}`,
|
|
39199
|
+
...checkpoint.summary ? [` summary: ${checkpoint.summary.replace(/\s+/g, " ").slice(0, 220)}`] : []
|
|
39200
|
+
].join("\n");
|
|
39201
|
+
}
|
|
39202
|
+
function usage() {
|
|
39203
|
+
console.log("Memorix Compact Checkpoints");
|
|
39204
|
+
console.log("");
|
|
39205
|
+
console.log("Usage:");
|
|
39206
|
+
console.log(" memorix checkpoint list [--session <id>] [--agent <name>] [--all]");
|
|
39207
|
+
console.log(" memorix checkpoint show --id <checkpoint-id>");
|
|
39208
|
+
console.log(' memorix checkpoint context [--id <checkpoint-id>] [--task "..."] [--budget 420]');
|
|
39209
|
+
console.log(" memorix checkpoint archive --id <checkpoint-id>");
|
|
39210
|
+
}
|
|
39211
|
+
var checkpoint_default;
|
|
39212
|
+
var init_checkpoint = __esm({
|
|
39213
|
+
"src/cli/commands/checkpoint.ts"() {
|
|
39214
|
+
"use strict";
|
|
39215
|
+
init_esm_shims();
|
|
39216
|
+
init_dist2();
|
|
39217
|
+
init_compaction();
|
|
39218
|
+
init_compaction_checkpoint_store();
|
|
39219
|
+
init_operator_shared();
|
|
39220
|
+
checkpoint_default = defineCommand({
|
|
39221
|
+
meta: {
|
|
39222
|
+
name: "checkpoint",
|
|
39223
|
+
description: "Inspect and manage native compact continuity checkpoints"
|
|
39224
|
+
},
|
|
39225
|
+
args: {
|
|
39226
|
+
id: { type: "string", description: "Checkpoint ID" },
|
|
39227
|
+
session: { type: "string", description: "Filter by host session ID" },
|
|
39228
|
+
agent: { type: "string", description: "Filter by host agent name" },
|
|
39229
|
+
task: { type: "string", description: "Current task for a bounded continuation workset" },
|
|
39230
|
+
budget: { type: "string", description: "Maximum workset token budget (default: 420)" },
|
|
39231
|
+
limit: { type: "string", description: "Maximum checkpoints to list (default: 20)" },
|
|
39232
|
+
all: { type: "boolean", description: "Include archived checkpoints in list output" },
|
|
39233
|
+
json: { type: "boolean", description: "Emit machine-readable JSON output" }
|
|
39234
|
+
},
|
|
39235
|
+
run: async ({ args }) => {
|
|
39236
|
+
const positional = args._ ?? [];
|
|
39237
|
+
const action = (positional[0] ?? "list").toLowerCase();
|
|
39238
|
+
const asJson = Boolean(args.json);
|
|
39239
|
+
try {
|
|
39240
|
+
const { project, store: store2 } = await getCheckpointContext();
|
|
39241
|
+
const id = args.id?.trim();
|
|
39242
|
+
switch (action) {
|
|
39243
|
+
case "list": {
|
|
39244
|
+
const checkpoints = store2.list({
|
|
39245
|
+
projectId: project.id,
|
|
39246
|
+
sessionId: args.session?.trim() || void 0,
|
|
39247
|
+
agent: args.agent?.trim() || void 0,
|
|
39248
|
+
includeArchived: Boolean(args.all),
|
|
39249
|
+
limit: parsePositiveInt(args.limit, 20)
|
|
39250
|
+
});
|
|
39251
|
+
emitResult(
|
|
39252
|
+
{ project, checkpoints },
|
|
39253
|
+
checkpoints.length ? checkpoints.map(formatCheckpoint).join("\n\n") : "No compact checkpoints for this project.",
|
|
39254
|
+
asJson
|
|
39255
|
+
);
|
|
39256
|
+
return;
|
|
39257
|
+
}
|
|
39258
|
+
case "show": {
|
|
39259
|
+
if (!id) throw new Error('id is required for "memorix checkpoint show".');
|
|
39260
|
+
const checkpoint = assertProjectCheckpoint(store2.get(id), project.id, id);
|
|
39261
|
+
emitResult({ project, checkpoint }, formatCheckpoint(checkpoint), asJson);
|
|
39262
|
+
return;
|
|
39263
|
+
}
|
|
39264
|
+
case "context": {
|
|
39265
|
+
const checkpoint = id ? assertProjectCheckpoint(store2.get(id), project.id, id) : store2.list({
|
|
39266
|
+
projectId: project.id,
|
|
39267
|
+
sessionId: args.session?.trim() || void 0,
|
|
39268
|
+
agent: args.agent?.trim() || void 0,
|
|
39269
|
+
limit: parsePositiveInt(args.limit, 20)
|
|
39270
|
+
}).find((entry) => entry.phase === "complete");
|
|
39271
|
+
if (!checkpoint) {
|
|
39272
|
+
throw new Error("No completed compact checkpoint is available for this project and filter.");
|
|
39273
|
+
}
|
|
39274
|
+
const workset = buildCompactionWorkset(checkpoint, {
|
|
39275
|
+
task: args.task?.trim(),
|
|
39276
|
+
maxTokens: parsePositiveInt(args.budget, 420)
|
|
39277
|
+
});
|
|
39278
|
+
emitResult({ project, checkpoint, workset }, workset.text, asJson);
|
|
39279
|
+
return;
|
|
39280
|
+
}
|
|
39281
|
+
case "archive": {
|
|
39282
|
+
if (!id) throw new Error('id is required for "memorix checkpoint archive".');
|
|
39283
|
+
assertProjectCheckpoint(store2.get(id), project.id, id);
|
|
39284
|
+
const checkpoint = store2.archive(id);
|
|
39285
|
+
if (!checkpoint) throw new Error(`Compact checkpoint "${id}" is already archived.`);
|
|
39286
|
+
emitResult({ project, checkpoint }, `Archived compact checkpoint ${shortId(checkpoint.id)}.`, asJson);
|
|
39287
|
+
return;
|
|
39288
|
+
}
|
|
39289
|
+
default:
|
|
39290
|
+
usage();
|
|
39291
|
+
}
|
|
39292
|
+
} catch (error2) {
|
|
39293
|
+
emitError(error2 instanceof Error ? error2.message : String(error2), asJson);
|
|
39294
|
+
}
|
|
39295
|
+
}
|
|
39296
|
+
});
|
|
39297
|
+
}
|
|
39298
|
+
});
|
|
39299
|
+
|
|
38645
39300
|
// src/knowledge/markdown.ts
|
|
38646
|
-
import { createHash as
|
|
39301
|
+
import { createHash as createHash11 } from "crypto";
|
|
38647
39302
|
import { promises as fs16 } from "fs";
|
|
38648
39303
|
import path23 from "path";
|
|
38649
39304
|
function hashContent(content) {
|
|
38650
|
-
return
|
|
39305
|
+
return createHash11("sha256").update(content).digest("hex");
|
|
38651
39306
|
}
|
|
38652
39307
|
function stringField(data, key) {
|
|
38653
39308
|
const value = data[key];
|
|
@@ -38773,11 +39428,11 @@ __export(wiki_exports, {
|
|
|
38773
39428
|
lintKnowledgeWorkspace: () => lintKnowledgeWorkspace,
|
|
38774
39429
|
readKnowledgePage: () => readKnowledgePage
|
|
38775
39430
|
});
|
|
38776
|
-
import { createHash as
|
|
39431
|
+
import { createHash as createHash12 } from "crypto";
|
|
38777
39432
|
import { promises as fs17 } from "fs";
|
|
38778
39433
|
import path24 from "path";
|
|
38779
39434
|
function hash3(value) {
|
|
38780
|
-
return
|
|
39435
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
38781
39436
|
}
|
|
38782
39437
|
function now2() {
|
|
38783
39438
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -39218,7 +39873,7 @@ function modeFrom(value) {
|
|
|
39218
39873
|
if (value === "versioned") return "versioned";
|
|
39219
39874
|
throw new Error("knowledge mode must be local or versioned");
|
|
39220
39875
|
}
|
|
39221
|
-
function
|
|
39876
|
+
function usage2() {
|
|
39222
39877
|
return [
|
|
39223
39878
|
"Memorix Knowledge Commands",
|
|
39224
39879
|
"",
|
|
@@ -39439,7 +40094,7 @@ var init_knowledge = __esm({
|
|
|
39439
40094
|
);
|
|
39440
40095
|
return;
|
|
39441
40096
|
}
|
|
39442
|
-
emitResult({ usage:
|
|
40097
|
+
emitResult({ usage: usage2() }, usage2(), asJson);
|
|
39443
40098
|
return;
|
|
39444
40099
|
}
|
|
39445
40100
|
switch (action) {
|
|
@@ -39498,7 +40153,7 @@ var init_knowledge = __esm({
|
|
|
39498
40153
|
return;
|
|
39499
40154
|
}
|
|
39500
40155
|
default:
|
|
39501
|
-
emitResult({ usage:
|
|
40156
|
+
emitResult({ usage: usage2() }, usage2(), asJson);
|
|
39502
40157
|
}
|
|
39503
40158
|
} catch (error2) {
|
|
39504
40159
|
emitError(error2 instanceof Error ? error2.message : String(error2), asJson);
|
|
@@ -46812,7 +47467,7 @@ __export(planner_exports, {
|
|
|
46812
47467
|
materializeTaskGraph: () => materializeTaskGraph,
|
|
46813
47468
|
seedAutonomousPipeline: () => seedAutonomousPipeline
|
|
46814
47469
|
});
|
|
46815
|
-
import { randomUUID as
|
|
47470
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
46816
47471
|
function isPlannerTask(metadata) {
|
|
46817
47472
|
if (!metadata) return null;
|
|
46818
47473
|
try {
|
|
@@ -46870,7 +47525,7 @@ function seedAutonomousPipeline(teamStore, projectId, config2, opts) {
|
|
|
46870
47525
|
const maxIterations = config2.maxIterations ?? 3;
|
|
46871
47526
|
const taskBudget = config2.taskBudget ?? 15;
|
|
46872
47527
|
const structuredPlan = opts?.structuredPlan ?? true;
|
|
46873
|
-
const pipelineId =
|
|
47528
|
+
const pipelineId = randomUUID10();
|
|
46874
47529
|
const meta = {
|
|
46875
47530
|
plannerType: "plan",
|
|
46876
47531
|
pipelineId,
|
|
@@ -47789,11 +48444,11 @@ __export(receipt_service_exports, {
|
|
|
47789
48444
|
buildHandoffReceipt: () => buildHandoffReceipt,
|
|
47790
48445
|
formatHandoffReceipt: () => formatHandoffReceipt
|
|
47791
48446
|
});
|
|
47792
|
-
import { createHash as
|
|
48447
|
+
import { createHash as createHash13 } from "crypto";
|
|
47793
48448
|
import { existsSync as existsSync16, readFileSync as readFileSync12 } from "fs";
|
|
47794
48449
|
import path26 from "path";
|
|
47795
48450
|
function sha256(value) {
|
|
47796
|
-
return `sha256:${
|
|
48451
|
+
return `sha256:${createHash13("sha256").update(value).digest("hex")}`;
|
|
47797
48452
|
}
|
|
47798
48453
|
function hashId(projectId, id) {
|
|
47799
48454
|
return sha256(`${projectId}:obs:${id}`);
|
|
@@ -48039,6 +48694,7 @@ var init_tool_profile = __esm({
|
|
|
48039
48694
|
memorix_rules_sync: ["full"],
|
|
48040
48695
|
memorix_workspace_sync: ["full"],
|
|
48041
48696
|
memorix_ingest_image: ["full"],
|
|
48697
|
+
memorix_compaction_checkpoint: ["full"],
|
|
48042
48698
|
// ── MCP Official Memory Server compatibility (KG tools) ──────────
|
|
48043
48699
|
// These are only useful to users specifically migrating from the
|
|
48044
48700
|
// reference mcp-memory server. Hide them unless explicitly enabled.
|
|
@@ -66294,9 +66950,9 @@ var init_graph_scope = __esm({
|
|
|
66294
66950
|
});
|
|
66295
66951
|
|
|
66296
66952
|
// src/rules/utils.ts
|
|
66297
|
-
import { createHash as
|
|
66953
|
+
import { createHash as createHash14 } from "crypto";
|
|
66298
66954
|
function hashContent2(content) {
|
|
66299
|
-
return
|
|
66955
|
+
return createHash14("sha256").update(content.trim()).digest("hex").substring(0, 16);
|
|
66300
66956
|
}
|
|
66301
66957
|
function generateRuleId(source, filePath) {
|
|
66302
66958
|
const sanitized = filePath.replace(/[\/\\]/g, "-").replace(/^\./, "");
|
|
@@ -70075,7 +70731,7 @@ __export(server_exports2, {
|
|
|
70075
70731
|
createMemorixServer: () => createMemorixServer,
|
|
70076
70732
|
shouldAwaitProjectRuntime: () => shouldAwaitProjectRuntime
|
|
70077
70733
|
});
|
|
70078
|
-
import { createHash as
|
|
70734
|
+
import { createHash as createHash15 } from "crypto";
|
|
70079
70735
|
function formatFormationStageDurations(stageDurationsMs) {
|
|
70080
70736
|
const orderedStages = ["extract", "resolve", "evaluate"];
|
|
70081
70737
|
const parts = orderedStages.filter((stage) => stageDurationsMs[stage] !== void 0).map((stage) => `${stage}=${stageDurationsMs[stage]}ms`);
|
|
@@ -70157,7 +70813,7 @@ function coerceObjectArray(val) {
|
|
|
70157
70813
|
return [];
|
|
70158
70814
|
}
|
|
70159
70815
|
function createDeterministicInstanceId(projectId, agentType, agentName) {
|
|
70160
|
-
const digest2 =
|
|
70816
|
+
const digest2 = createHash15("sha256").update(projectId).update("\n").update(agentType).update("\n").update(agentName ?? "").digest("hex").slice(0, 24);
|
|
70161
70817
|
return `auto-${digest2}`;
|
|
70162
70818
|
}
|
|
70163
70819
|
function shouldAwaitProjectRuntime(toolName) {
|
|
@@ -70430,7 +71086,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
70430
71086
|
};
|
|
70431
71087
|
const server = existingServer ?? new McpServer({
|
|
70432
71088
|
name: "memorix",
|
|
70433
|
-
version: true ? "1.2.
|
|
71089
|
+
version: true ? "1.2.7" : "1.0.1"
|
|
70434
71090
|
});
|
|
70435
71091
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
70436
71092
|
server.registerTool = ((name, ...args) => {
|
|
@@ -71078,12 +71734,12 @@ Use this as the \`topicKey\` parameter in \`memorix_store\` to enable upsert beh
|
|
|
71078
71734
|
if (boundary) return boundary;
|
|
71079
71735
|
}
|
|
71080
71736
|
return withFreshIndex(async () => {
|
|
71081
|
-
const
|
|
71737
|
+
const safeLimit2 = limit != null ? coerceNumber(limit, 20) : void 0;
|
|
71082
71738
|
const safeMaxTokens = maxTokens != null ? coerceNumber(maxTokens, 0) : void 0;
|
|
71083
71739
|
const TIMEOUT_MS = 3e4;
|
|
71084
71740
|
const searchPromise = compactSearch({
|
|
71085
71741
|
query,
|
|
71086
|
-
limit:
|
|
71742
|
+
limit: safeLimit2,
|
|
71087
71743
|
type,
|
|
71088
71744
|
maxTokens: safeMaxTokens,
|
|
71089
71745
|
since,
|
|
@@ -71884,10 +72540,10 @@ Entity: ${entityName} | ${facts.length} facts | ${obs.tokens} tokens${reasoningA
|
|
|
71884
72540
|
const unresolved = requireResolvedProject("search reasoning in the current project");
|
|
71885
72541
|
if (unresolved) return unresolved;
|
|
71886
72542
|
}
|
|
71887
|
-
const
|
|
72543
|
+
const safeLimit2 = limit != null ? coerceNumber(limit, 10) : 10;
|
|
71888
72544
|
const result = await withFreshIndex(() => compactSearch({
|
|
71889
72545
|
query,
|
|
71890
|
-
limit:
|
|
72546
|
+
limit: safeLimit2,
|
|
71891
72547
|
type: "reasoning",
|
|
71892
72548
|
projectId: scope === "global" ? void 0 : project.id,
|
|
71893
72549
|
status: "active",
|
|
@@ -73210,9 +73866,9 @@ ${summary ? "Summary saved for next session context injection." : "No summary pr
|
|
|
73210
73866
|
}
|
|
73211
73867
|
},
|
|
73212
73868
|
async ({ limit }) => {
|
|
73213
|
-
const
|
|
73869
|
+
const safeLimit2 = limit != null ? coerceNumber(limit, 3) : 3;
|
|
73214
73870
|
const { getSessionContext: getSessionContext2, listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session(), session_exports));
|
|
73215
|
-
const context = await getSessionContext2(projectDir2, project.id,
|
|
73871
|
+
const context = await getSessionContext2(projectDir2, project.id, safeLimit2, getObservationReader());
|
|
73216
73872
|
const sessions = await listSessions2(projectDir2, project.id);
|
|
73217
73873
|
const activeSessions = sessions.filter((s2) => s2.status === "active");
|
|
73218
73874
|
const completedSessions = sessions.filter((s2) => s2.status === "completed");
|
|
@@ -73233,6 +73889,86 @@ ${summary ? "Summary saved for next session context injection." : "No summary pr
|
|
|
73233
73889
|
};
|
|
73234
73890
|
}
|
|
73235
73891
|
);
|
|
73892
|
+
server.registerTool(
|
|
73893
|
+
"memorix_compaction_checkpoint",
|
|
73894
|
+
{
|
|
73895
|
+
title: "Compact Continuity Checkpoints",
|
|
73896
|
+
description: "Inspect, preview, or archive bounded checkpoints recorded around a host-native context compaction. Use only to debug or explicitly review compaction continuity. These are lifecycle records, not durable memories or transcript backups. CLI equivalent: memorix checkpoint list|show|context|archive.",
|
|
73897
|
+
inputSchema: {
|
|
73898
|
+
action: external_exports.enum(["list", "show", "context", "archive"]).default("list"),
|
|
73899
|
+
id: external_exports.string().optional().describe("Checkpoint ID for show, context, or archive"),
|
|
73900
|
+
sessionId: external_exports.string().optional().describe("Optional host session ID filter"),
|
|
73901
|
+
agent: external_exports.string().optional().describe("Optional host agent filter"),
|
|
73902
|
+
task: external_exports.string().optional().describe("Current task for a bounded context preview"),
|
|
73903
|
+
maxTokens: external_exports.number().optional().describe("Maximum tokens for action=context (default: 420)"),
|
|
73904
|
+
limit: external_exports.number().optional().describe("Maximum records for action=list (default: 20)"),
|
|
73905
|
+
includeArchived: external_exports.boolean().optional().default(false).describe("Include archived records in action=list")
|
|
73906
|
+
}
|
|
73907
|
+
},
|
|
73908
|
+
async ({ action, id, sessionId, agent, task, maxTokens, limit, includeArchived }) => {
|
|
73909
|
+
const unresolved = requireResolvedProject("inspect compact continuity checkpoints");
|
|
73910
|
+
if (unresolved) return unresolved;
|
|
73911
|
+
const [{ CompactionCheckpointStore: CompactionCheckpointStore2 }, { buildCompactionWorkset: buildCompactionWorkset2 }] = await Promise.all([
|
|
73912
|
+
Promise.resolve().then(() => (init_compaction_checkpoint_store(), compaction_checkpoint_store_exports)),
|
|
73913
|
+
Promise.resolve().then(() => (init_compaction(), compaction_exports))
|
|
73914
|
+
]);
|
|
73915
|
+
const store2 = new CompactionCheckpointStore2(projectDir2);
|
|
73916
|
+
const assertCheckpoint = (checkpointId) => {
|
|
73917
|
+
const checkpoint2 = store2.get(checkpointId);
|
|
73918
|
+
if (!checkpoint2 || checkpoint2.projectId !== project.id) return null;
|
|
73919
|
+
return checkpoint2;
|
|
73920
|
+
};
|
|
73921
|
+
if (action === "list") {
|
|
73922
|
+
const checkpoints = store2.list({
|
|
73923
|
+
projectId: project.id,
|
|
73924
|
+
sessionId: sessionId?.trim() || void 0,
|
|
73925
|
+
agent: agent?.trim() || void 0,
|
|
73926
|
+
includeArchived: Boolean(includeArchived),
|
|
73927
|
+
limit: limit != null ? Math.max(1, Math.min(100, coerceNumber(limit, 20))) : 20
|
|
73928
|
+
});
|
|
73929
|
+
return {
|
|
73930
|
+
content: [{ type: "text", text: JSON.stringify({ projectId: project.id, checkpoints }, null, 2) }]
|
|
73931
|
+
};
|
|
73932
|
+
}
|
|
73933
|
+
if (!id?.trim()) {
|
|
73934
|
+
return {
|
|
73935
|
+
content: [{ type: "text", text: "id is required for this checkpoint action." }],
|
|
73936
|
+
isError: true
|
|
73937
|
+
};
|
|
73938
|
+
}
|
|
73939
|
+
const checkpoint = assertCheckpoint(id.trim());
|
|
73940
|
+
if (!checkpoint) {
|
|
73941
|
+
return {
|
|
73942
|
+
content: [{ type: "text", text: `Checkpoint "${id.trim()}" was not found for the current project.` }],
|
|
73943
|
+
isError: true
|
|
73944
|
+
};
|
|
73945
|
+
}
|
|
73946
|
+
if (action === "show") {
|
|
73947
|
+
return {
|
|
73948
|
+
content: [{ type: "text", text: JSON.stringify({ projectId: project.id, checkpoint }, null, 2) }]
|
|
73949
|
+
};
|
|
73950
|
+
}
|
|
73951
|
+
if (action === "context") {
|
|
73952
|
+
const workset = buildCompactionWorkset2(checkpoint, {
|
|
73953
|
+
task: task?.trim(),
|
|
73954
|
+
maxTokens: maxTokens != null ? coerceNumber(maxTokens, 420) : 420
|
|
73955
|
+
});
|
|
73956
|
+
return {
|
|
73957
|
+
content: [{ type: "text", text: workset.text }]
|
|
73958
|
+
};
|
|
73959
|
+
}
|
|
73960
|
+
const archived = store2.archive(checkpoint.id);
|
|
73961
|
+
if (!archived) {
|
|
73962
|
+
return {
|
|
73963
|
+
content: [{ type: "text", text: `Checkpoint "${checkpoint.id}" is already archived.` }],
|
|
73964
|
+
isError: true
|
|
73965
|
+
};
|
|
73966
|
+
}
|
|
73967
|
+
return {
|
|
73968
|
+
content: [{ type: "text", text: `Archived compact checkpoint ${archived.id}.` }]
|
|
73969
|
+
};
|
|
73970
|
+
}
|
|
73971
|
+
);
|
|
73236
73972
|
server.registerTool(
|
|
73237
73973
|
"memorix_transfer",
|
|
73238
73974
|
{
|
|
@@ -76147,7 +76883,7 @@ var init_serve_http = __esm({
|
|
|
76147
76883
|
},
|
|
76148
76884
|
run: async ({ args }) => {
|
|
76149
76885
|
const { createServer: createServer2 } = await import("http");
|
|
76150
|
-
const { randomUUID:
|
|
76886
|
+
const { randomUUID: randomUUID11 } = await import("crypto");
|
|
76151
76887
|
const { StreamableHTTPServerTransport: StreamableHTTPServerTransport2 } = await Promise.resolve().then(() => (init_streamableHttp(), streamableHttp_exports));
|
|
76152
76888
|
const { isInitializeRequest: isInitializeRequest2 } = await Promise.resolve().then(() => (init_types4(), types_exports));
|
|
76153
76889
|
const { createMemorixServer: createMemorixServer2 } = await Promise.resolve().then(() => (init_server4(), server_exports2));
|
|
@@ -76331,7 +77067,7 @@ var init_serve_http = __esm({
|
|
|
76331
77067
|
if (!sessionId && isInitializeRequest2(body)) {
|
|
76332
77068
|
let createdState = null;
|
|
76333
77069
|
const transport = new StreamableHTTPServerTransport2({
|
|
76334
|
-
sessionIdGenerator: () =>
|
|
77070
|
+
sessionIdGenerator: () => randomUUID11(),
|
|
76335
77071
|
enableJsonResponse: true,
|
|
76336
77072
|
onsessioninitialized: (sid) => {
|
|
76337
77073
|
if (createdState) sessions.set(sid, createdState);
|
|
@@ -78121,6 +78857,44 @@ function stringifyValue(value) {
|
|
|
78121
78857
|
return String(value);
|
|
78122
78858
|
}
|
|
78123
78859
|
}
|
|
78860
|
+
function firstNumber2(...values) {
|
|
78861
|
+
for (const value of values) {
|
|
78862
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
78863
|
+
if (typeof value === "string" && value.trim()) {
|
|
78864
|
+
const parsed = Number(value);
|
|
78865
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
78866
|
+
}
|
|
78867
|
+
}
|
|
78868
|
+
return void 0;
|
|
78869
|
+
}
|
|
78870
|
+
function normalizeCompactionReason(value) {
|
|
78871
|
+
const normalized = value?.trim().toLowerCase();
|
|
78872
|
+
if (normalized === "manual" || normalized === "auto") return normalized;
|
|
78873
|
+
return "unknown";
|
|
78874
|
+
}
|
|
78875
|
+
function normalizeCompactionMetadata(payload, ...records) {
|
|
78876
|
+
const nestedSources = records.filter((record2) => Boolean(record2));
|
|
78877
|
+
const sources = [payload, ...nestedSources];
|
|
78878
|
+
const from = (field) => sources.map((source) => source[field]);
|
|
78879
|
+
const fromNested = (field) => nestedSources.map((source) => source[field]);
|
|
78880
|
+
const summary = firstString(...from("summary"), ...from("compaction_summary"));
|
|
78881
|
+
const sourceKey = firstString(...from("compaction_id"), ...from("entry_id"), ...fromNested("id"));
|
|
78882
|
+
const reasonValue = firstString(...from("trigger"), ...from("reason"), ...from("compaction_reason"));
|
|
78883
|
+
const tokensBefore = firstNumber2(...from("tokensBefore"), ...from("tokens_before"));
|
|
78884
|
+
const firstKeptEntryId = firstString(...from("firstKeptEntryId"), ...from("first_kept_entry_id"));
|
|
78885
|
+
const details = sources.map((source) => asRecord(source.details)).find((value) => Boolean(value));
|
|
78886
|
+
if (!summary && !sourceKey && !tokensBefore && !firstKeptEntryId && !details && !reasonValue) {
|
|
78887
|
+
return void 0;
|
|
78888
|
+
}
|
|
78889
|
+
return {
|
|
78890
|
+
...reasonValue ? { reason: normalizeCompactionReason(reasonValue) } : {},
|
|
78891
|
+
...sourceKey ? { sourceKey } : {},
|
|
78892
|
+
...summary ? { summary } : {},
|
|
78893
|
+
...tokensBefore !== void 0 ? { tokensBefore } : {},
|
|
78894
|
+
...firstKeptEntryId ? { firstKeptEntryId } : {},
|
|
78895
|
+
...details ? { details } : {}
|
|
78896
|
+
};
|
|
78897
|
+
}
|
|
78124
78898
|
function detectAgent(payload) {
|
|
78125
78899
|
if (typeof payload._memorix_agent === "string") {
|
|
78126
78900
|
return payload._memorix_agent;
|
|
@@ -78206,6 +78980,10 @@ function normalizeClaude(payload, event) {
|
|
|
78206
78980
|
if (assistantMessage) {
|
|
78207
78981
|
result.aiResponse = assistantMessage;
|
|
78208
78982
|
}
|
|
78983
|
+
if (event === "session_start") {
|
|
78984
|
+
const source = firstString(payload.source, payload.session_start_reason, payload.reason);
|
|
78985
|
+
if (source) result.sessionStartReason = source;
|
|
78986
|
+
}
|
|
78209
78987
|
return result;
|
|
78210
78988
|
}
|
|
78211
78989
|
function normalizeWindsurf(payload, event) {
|
|
@@ -78344,6 +79122,10 @@ function normalizeGemini(payload, event) {
|
|
|
78344
79122
|
if (event === "user_prompt") {
|
|
78345
79123
|
result.userPrompt = payload.prompt ?? "";
|
|
78346
79124
|
}
|
|
79125
|
+
if (event === "session_start") {
|
|
79126
|
+
const source = firstString(payload.source, payload.session_start_reason, payload.reason);
|
|
79127
|
+
if (source) result.sessionStartReason = source;
|
|
79128
|
+
}
|
|
78347
79129
|
return result;
|
|
78348
79130
|
}
|
|
78349
79131
|
function normalizeOpenCode(payload, event) {
|
|
@@ -78380,7 +79162,8 @@ function normalizeOpenCode(payload, event) {
|
|
|
78380
79162
|
function normalizePi(payload, event) {
|
|
78381
79163
|
const result = {
|
|
78382
79164
|
sessionId: payload.session_id ?? payload.sessionId ?? "",
|
|
78383
|
-
cwd: payload.cwd ?? ""
|
|
79165
|
+
cwd: payload.cwd ?? "",
|
|
79166
|
+
transcriptPath: payload.transcript_path ?? payload.transcriptPath
|
|
78384
79167
|
};
|
|
78385
79168
|
const toolName = payload.tool_name ?? "";
|
|
78386
79169
|
if (toolName) {
|
|
@@ -78402,6 +79185,10 @@ function normalizePi(payload, event) {
|
|
|
78402
79185
|
if (event === "post_command") {
|
|
78403
79186
|
result.command = payload.command ?? "";
|
|
78404
79187
|
}
|
|
79188
|
+
if (event === "session_start") {
|
|
79189
|
+
const source = firstString(payload.source, payload.reason);
|
|
79190
|
+
if (source) result.sessionStartReason = source;
|
|
79191
|
+
}
|
|
78405
79192
|
if (result.toolInput && typeof result.toolInput === "object") {
|
|
78406
79193
|
const filePath = result.toolInput.file_path ?? result.toolInput.filePath ?? result.toolInput.path;
|
|
78407
79194
|
if (filePath) result.filePath = filePath;
|
|
@@ -78454,6 +79241,10 @@ function normalizeBridgePayload(payload, event) {
|
|
|
78454
79241
|
openclawContext?.message
|
|
78455
79242
|
) ?? stringifyValue(openclawEvent?.message) ?? "";
|
|
78456
79243
|
}
|
|
79244
|
+
if (event === "session_start") {
|
|
79245
|
+
const source = firstString(payload.source, bridgePayload?.source, bridgeKwargs?.source, openclawEvent?.reason);
|
|
79246
|
+
if (source) result.sessionStartReason = source;
|
|
79247
|
+
}
|
|
78457
79248
|
return result;
|
|
78458
79249
|
}
|
|
78459
79250
|
function normalizeHookInput(payload) {
|
|
@@ -78499,6 +79290,15 @@ function normalizeHookInput(payload) {
|
|
|
78499
79290
|
default:
|
|
78500
79291
|
agentSpecific = { sessionId: "", cwd: "" };
|
|
78501
79292
|
}
|
|
79293
|
+
const openclawEvent = asRecord(payload.openclaw_event);
|
|
79294
|
+
const genericCompaction = event === "pre_compact" || event === "post_compact" ? normalizeCompactionMetadata(
|
|
79295
|
+
payload,
|
|
79296
|
+
asRecord(payload.compaction),
|
|
79297
|
+
asRecord(payload.compaction_entry),
|
|
79298
|
+
asRecord(payload.compactionEntry),
|
|
79299
|
+
asRecord(openclawEvent?.compaction),
|
|
79300
|
+
asRecord(openclawEvent?.compaction_entry)
|
|
79301
|
+
) : void 0;
|
|
78502
79302
|
return {
|
|
78503
79303
|
event,
|
|
78504
79304
|
agent,
|
|
@@ -78506,7 +79306,8 @@ function normalizeHookInput(payload) {
|
|
|
78506
79306
|
sessionId: agentSpecific.sessionId ?? "",
|
|
78507
79307
|
cwd: agentSpecific.cwd ?? "",
|
|
78508
79308
|
raw: payload,
|
|
78509
|
-
...agentSpecific
|
|
79309
|
+
...agentSpecific,
|
|
79310
|
+
...genericCompaction ? { compaction: genericCompaction } : {}
|
|
78510
79311
|
};
|
|
78511
79312
|
}
|
|
78512
79313
|
var EVENT_MAP;
|
|
@@ -78760,10 +79561,10 @@ __export(handler_exports, {
|
|
|
78760
79561
|
resetCooldowns: () => resetCooldowns,
|
|
78761
79562
|
runHook: () => runHook
|
|
78762
79563
|
});
|
|
78763
|
-
import { createHash as
|
|
79564
|
+
import { createHash as createHash16 } from "crypto";
|
|
78764
79565
|
function deriveHookActorId(input) {
|
|
78765
79566
|
const material = `${input.agent ?? "unknown"}\0${input.sessionId ?? "unknown"}`;
|
|
78766
|
-
return `hook:${
|
|
79567
|
+
return `hook:${createHash16("sha256").update(material).digest("hex").slice(0, 24)}`;
|
|
78767
79568
|
}
|
|
78768
79569
|
function classifyTool(input) {
|
|
78769
79570
|
if (input.event === "post_edit") return "file_modify";
|
|
@@ -78944,6 +79745,15 @@ async function buildHookProjectContext(input, task, target) {
|
|
|
78944
79745
|
refresh: "auto",
|
|
78945
79746
|
reader: { projectId: canonicalId },
|
|
78946
79747
|
continuation: "always",
|
|
79748
|
+
...input.sessionId ? {
|
|
79749
|
+
// A native compact recovery is delivered once per host session.
|
|
79750
|
+
// Do not echo that same checkpoint back through the generic
|
|
79751
|
+
// continuation brief on later events from this session.
|
|
79752
|
+
excludeCompactionCheckpointFor: {
|
|
79753
|
+
sessionId: input.sessionId,
|
|
79754
|
+
agent: input.agent
|
|
79755
|
+
}
|
|
79756
|
+
} : {},
|
|
78947
79757
|
enqueueRefresh: () => Promise.resolve().then(() => (init_lifecycle(), lifecycle_exports)).then(({ enqueueCodegraphRefresh: enqueueCodegraphRefresh2 }) => {
|
|
78948
79758
|
enqueueCodegraphRefresh2({
|
|
78949
79759
|
dataDir,
|
|
@@ -78965,27 +79775,80 @@ async function buildHookProjectContext(input, task, target) {
|
|
|
78965
79775
|
return null;
|
|
78966
79776
|
}
|
|
78967
79777
|
}
|
|
79778
|
+
function isCompactSessionStart(input) {
|
|
79779
|
+
return input.event === "session_start" && input.sessionStartReason?.trim().toLowerCase() === "compact";
|
|
79780
|
+
}
|
|
79781
|
+
async function consumeCompactContinuation(input, task) {
|
|
79782
|
+
try {
|
|
79783
|
+
const { consumeCompactionWorkset: consumeCompactionWorkset2 } = await Promise.resolve().then(() => (init_compaction(), compaction_exports));
|
|
79784
|
+
const workset = await consumeCompactionWorkset2(input, { task, maxTokens: 420 });
|
|
79785
|
+
return workset?.text;
|
|
79786
|
+
} catch (error2) {
|
|
79787
|
+
console.error("[memorix] compact continuation failed:", error2?.message ?? error2);
|
|
79788
|
+
return void 0;
|
|
79789
|
+
}
|
|
79790
|
+
}
|
|
78968
79791
|
async function buildClaudeContinuationPromptContext(input) {
|
|
78969
79792
|
if (input.agent !== "claude" || input.event !== "user_prompt" || !input.userPrompt?.trim()) {
|
|
78970
79793
|
return void 0;
|
|
78971
79794
|
}
|
|
78972
|
-
const { isContinuationTask: isContinuationTask2 } = await Promise.resolve().then(() => (init_task_lens(), task_lens_exports));
|
|
78973
|
-
if (!isContinuationTask2(input.userPrompt)) return void 0;
|
|
78974
79795
|
if (await getHookInjectionMode(input) === "silent") return void 0;
|
|
78975
|
-
const
|
|
78976
|
-
if (
|
|
78977
|
-
|
|
78978
|
-
|
|
78979
|
-
|
|
78980
|
-
|
|
78981
|
-
|
|
78982
|
-
|
|
79796
|
+
const compactContinuation = await consumeCompactContinuation(input, input.userPrompt);
|
|
79797
|
+
if (compactContinuation) {
|
|
79798
|
+
return [
|
|
79799
|
+
"Memorix recovered one bounded checkpoint after the host compacted this session.",
|
|
79800
|
+
"Treat it as background context; current code and the user request win.",
|
|
79801
|
+
"",
|
|
79802
|
+
compactContinuation
|
|
79803
|
+
].join("\n");
|
|
79804
|
+
}
|
|
79805
|
+
const { isContinuationTask: isContinuationTask2, resolveTaskLens: resolveTaskLens2 } = await Promise.resolve().then(() => (init_task_lens(), task_lens_exports));
|
|
79806
|
+
const continuationRequested = isContinuationTask2(input.userPrompt);
|
|
79807
|
+
if (continuationRequested) {
|
|
79808
|
+
const context = await buildHookProjectContext(input, input.userPrompt, "hook-user-prompt");
|
|
79809
|
+
if (context?.hasContinuation) {
|
|
79810
|
+
return [
|
|
79811
|
+
"Memorix prepared a bounded prior-work brief for this explicit continuation request.",
|
|
79812
|
+
"Treat it as background context; current code wins. Use it before broad Git or file-history archaeology.",
|
|
79813
|
+
"",
|
|
79814
|
+
context.prompt
|
|
79815
|
+
].join("\n");
|
|
79816
|
+
}
|
|
79817
|
+
}
|
|
79818
|
+
if (continuationRequested || resolveTaskLens2(input.userPrompt).id === "onboarding") {
|
|
79819
|
+
return [
|
|
79820
|
+
"Memorix is available for this handoff or continuation.",
|
|
79821
|
+
"Before broad file or Git exploration, call memorix_project_context with the user's actual task.",
|
|
79822
|
+
"If it is not visible yet, use Claude Code tool search for memorix_project_context; use CLI only when MCP discovery is unavailable."
|
|
79823
|
+
].join(" ");
|
|
79824
|
+
}
|
|
79825
|
+
return void 0;
|
|
78983
79826
|
}
|
|
78984
79827
|
async function handleSessionStart(input) {
|
|
78985
79828
|
const injectMode = await getHookInjectionMode(input);
|
|
78986
79829
|
if (injectMode === "silent") {
|
|
78987
79830
|
return { observation: null, output: { continue: true } };
|
|
78988
79831
|
}
|
|
79832
|
+
if (input.agent === "codex" && isCompactSessionStart(input)) {
|
|
79833
|
+
const compactContinuation = await consumeCompactContinuation(
|
|
79834
|
+
input,
|
|
79835
|
+
"Continue after the host compacted the current session."
|
|
79836
|
+
);
|
|
79837
|
+
if (compactContinuation) {
|
|
79838
|
+
return {
|
|
79839
|
+
observation: null,
|
|
79840
|
+
output: {
|
|
79841
|
+
continue: true,
|
|
79842
|
+
systemMessage: [
|
|
79843
|
+
"Memorix recovered one bounded checkpoint after the host compacted this session.",
|
|
79844
|
+
"Treat it as background context; current code and the user request win.",
|
|
79845
|
+
"",
|
|
79846
|
+
compactContinuation
|
|
79847
|
+
].join("\n")
|
|
79848
|
+
}
|
|
79849
|
+
};
|
|
79850
|
+
}
|
|
79851
|
+
}
|
|
78989
79852
|
let contextSummary = "";
|
|
78990
79853
|
if (injectMode === "full") {
|
|
78991
79854
|
const context = await buildHookProjectContext(input, "Continue the current task.", "hook-session-start");
|
|
@@ -79194,6 +80057,12 @@ async function runHook(agentOverride, eventOverride) {
|
|
|
79194
80057
|
payload._memorix_event = eventOverride;
|
|
79195
80058
|
}
|
|
79196
80059
|
const input = normalizeHookInput(payload);
|
|
80060
|
+
try {
|
|
80061
|
+
const { captureCompactionCheckpoint: captureCompactionCheckpoint2 } = await Promise.resolve().then(() => (init_compaction(), compaction_exports));
|
|
80062
|
+
await captureCompactionCheckpoint2(input);
|
|
80063
|
+
} catch (checkpointError) {
|
|
80064
|
+
console.error("[memorix] compact checkpoint failed:", checkpointError?.message ?? checkpointError);
|
|
80065
|
+
}
|
|
79197
80066
|
const { observation, output } = await handleHookEvent(input, { deferMaintenance: true });
|
|
79198
80067
|
if (observation) {
|
|
79199
80068
|
try {
|
|
@@ -84986,32 +85855,32 @@ __export(cost_tracker_exports, {
|
|
|
84986
85855
|
formatCostSummary: () => formatCostSummary,
|
|
84987
85856
|
isBudgetExceeded: () => isBudgetExceeded
|
|
84988
85857
|
});
|
|
84989
|
-
function calculateModelCost(model,
|
|
85858
|
+
function calculateModelCost(model, usage3, customPrices) {
|
|
84990
85859
|
const prices = { ...DEFAULT_PRICES, ...customPrices };
|
|
84991
85860
|
const price = findPrice(model, prices);
|
|
84992
85861
|
if (!price) return null;
|
|
84993
|
-
const inputCost =
|
|
84994
|
-
const outputCost =
|
|
84995
|
-
const cacheReadCost =
|
|
84996
|
-
const cacheWriteCost =
|
|
85862
|
+
const inputCost = usage3.inputTokens / 1e6 * price.inputPer1M;
|
|
85863
|
+
const outputCost = usage3.outputTokens / 1e6 * price.outputPer1M;
|
|
85864
|
+
const cacheReadCost = usage3.cacheReadTokens / 1e6 * (price.cacheReadPer1M ?? 0);
|
|
85865
|
+
const cacheWriteCost = usage3.cacheWriteTokens / 1e6 * (price.cacheWritePer1M ?? 0);
|
|
84997
85866
|
return inputCost + outputCost + cacheReadCost + cacheWriteCost;
|
|
84998
85867
|
}
|
|
84999
85868
|
function calculatePipelineCost(tokenUsage, budgetUSD, customPrices) {
|
|
85000
85869
|
const models2 = [];
|
|
85001
85870
|
let totalUSD = 0;
|
|
85002
85871
|
let hasAnyPrice = false;
|
|
85003
|
-
for (const [model,
|
|
85004
|
-
const cost = calculateModelCost(model,
|
|
85872
|
+
for (const [model, usage3] of Object.entries(tokenUsage)) {
|
|
85873
|
+
const cost = calculateModelCost(model, usage3, customPrices);
|
|
85005
85874
|
if (cost !== null) {
|
|
85006
85875
|
hasAnyPrice = true;
|
|
85007
85876
|
totalUSD = (totalUSD ?? 0) + cost;
|
|
85008
85877
|
}
|
|
85009
85878
|
models2.push({
|
|
85010
85879
|
model,
|
|
85011
|
-
inputTokens:
|
|
85012
|
-
outputTokens:
|
|
85013
|
-
cacheReadTokens:
|
|
85014
|
-
cacheWriteTokens:
|
|
85880
|
+
inputTokens: usage3.inputTokens,
|
|
85881
|
+
outputTokens: usage3.outputTokens,
|
|
85882
|
+
cacheReadTokens: usage3.cacheReadTokens,
|
|
85883
|
+
cacheWriteTokens: usage3.cacheWriteTokens,
|
|
85015
85884
|
costUSD: cost !== null ? Math.round(cost * 1e4) / 1e4 : null
|
|
85016
85885
|
// Round to 4 decimals
|
|
85017
85886
|
});
|
|
@@ -85310,7 +86179,7 @@ var init_permission = __esm({
|
|
|
85310
86179
|
});
|
|
85311
86180
|
|
|
85312
86181
|
// src/orchestrate/memorix-bridge.ts
|
|
85313
|
-
import { createHash as
|
|
86182
|
+
import { createHash as createHash17 } from "crypto";
|
|
85314
86183
|
async function getStoreObservation() {
|
|
85315
86184
|
if (!_storeObservation) {
|
|
85316
86185
|
const mod = await Promise.resolve().then(() => (init_observations(), observations_exports));
|
|
@@ -85326,7 +86195,7 @@ async function getSearchObservations() {
|
|
|
85326
86195
|
return _searchObservations;
|
|
85327
86196
|
}
|
|
85328
86197
|
function automaticActorId(...parts) {
|
|
85329
|
-
return `orchestrator:${
|
|
86198
|
+
return `orchestrator:${createHash17("sha256").update(parts.join("\0")).digest("hex").slice(0, 24)}`;
|
|
85330
86199
|
}
|
|
85331
86200
|
function isEligibleAutomaticLesson(entry) {
|
|
85332
86201
|
return entry.admissionState !== "candidate" && entry.admissionState !== "ephemeral";
|
|
@@ -85473,7 +86342,7 @@ function sanitizeErrorPattern(text) {
|
|
|
85473
86342
|
}
|
|
85474
86343
|
function hashErrorPattern(errorOutput) {
|
|
85475
86344
|
const sanitized = sanitizeErrorPattern(errorOutput).slice(0, 500);
|
|
85476
|
-
return
|
|
86345
|
+
return createHash17("sha256").update(sanitized).digest("hex").slice(0, 12);
|
|
85477
86346
|
}
|
|
85478
86347
|
function sleep2(ms) {
|
|
85479
86348
|
return new Promise((resolve6) => setTimeout(() => resolve6([]), ms));
|
|
@@ -85934,12 +86803,12 @@ ${formatCostSummary(costSummary)}`);
|
|
|
85934
86803
|
activeDispatches.splice(settled.idx, 1);
|
|
85935
86804
|
const { dispatch, result } = settled;
|
|
85936
86805
|
if (result.tokenUsage) {
|
|
85937
|
-
for (const [model,
|
|
86806
|
+
for (const [model, usage3] of Object.entries(result.tokenUsage)) {
|
|
85938
86807
|
const prev = pipelineUsage[model] ?? { inputTokens: 0, outputTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, model };
|
|
85939
|
-
prev.inputTokens +=
|
|
85940
|
-
prev.outputTokens +=
|
|
85941
|
-
prev.cacheReadTokens +=
|
|
85942
|
-
prev.cacheWriteTokens +=
|
|
86808
|
+
prev.inputTokens += usage3.inputTokens;
|
|
86809
|
+
prev.outputTokens += usage3.outputTokens;
|
|
86810
|
+
prev.cacheReadTokens += usage3.cacheReadTokens;
|
|
86811
|
+
prev.cacheWriteTokens += usage3.cacheWriteTokens;
|
|
85943
86812
|
pipelineUsage[model] = prev;
|
|
85944
86813
|
}
|
|
85945
86814
|
if (traceDb && pipelineId) {
|
|
@@ -86885,10 +87754,10 @@ ${"\u2550".repeat(60)}`);
|
|
|
86885
87754
|
if (result.tokenUsage) {
|
|
86886
87755
|
console.error(`
|
|
86887
87756
|
[COST] Token Usage:`);
|
|
86888
|
-
for (const [model,
|
|
86889
|
-
const total =
|
|
86890
|
-
const cacheHits =
|
|
86891
|
-
console.error(` ${model}: ${total.toLocaleString()} tokens (in: ${
|
|
87757
|
+
for (const [model, usage3] of Object.entries(result.tokenUsage)) {
|
|
87758
|
+
const total = usage3.inputTokens + usage3.outputTokens;
|
|
87759
|
+
const cacheHits = usage3.cacheReadTokens;
|
|
87760
|
+
console.error(` ${model}: ${total.toLocaleString()} tokens (in: ${usage3.inputTokens.toLocaleString()}, out: ${usage3.outputTokens.toLocaleString()}${cacheHits > 0 ? `, cache: ${cacheHits.toLocaleString()}` : ""})`);
|
|
86892
87761
|
}
|
|
86893
87762
|
}
|
|
86894
87763
|
if (result.costSummary) {
|
|
@@ -91394,6 +92263,16 @@ var GUIDES = {
|
|
|
91394
92263
|
'memorix codegraph context-pack --task "trace the auth flow" [--limit 20]'
|
|
91395
92264
|
]
|
|
91396
92265
|
},
|
|
92266
|
+
checkpoint: {
|
|
92267
|
+
summary: "Inspect bounded recovery checkpoints created around host-native context compaction.",
|
|
92268
|
+
usage: [
|
|
92269
|
+
"memorix checkpoint list [--session <id>] [--agent <name>]",
|
|
92270
|
+
"memorix checkpoint show --id <checkpoint-id>",
|
|
92271
|
+
'memorix checkpoint context [--id <checkpoint-id>] [--task "continue auth fix"]',
|
|
92272
|
+
"memorix checkpoint archive --id <checkpoint-id>"
|
|
92273
|
+
],
|
|
92274
|
+
notes: ["Checkpoints are host lifecycle evidence, not durable project memory and not transcript backups."]
|
|
92275
|
+
},
|
|
91397
92276
|
knowledge: {
|
|
91398
92277
|
summary: "Manage the reviewed, source-backed Knowledge Workspace and project workflows.",
|
|
91399
92278
|
usage: [
|
|
@@ -91709,6 +92588,7 @@ var main = defineCommand({
|
|
|
91709
92588
|
resume: () => Promise.resolve().then(() => (init_resume(), resume_exports)).then((m4) => m4.default),
|
|
91710
92589
|
explain: () => Promise.resolve().then(() => (init_explain(), explain_exports)).then((m4) => m4.default),
|
|
91711
92590
|
codegraph: () => Promise.resolve().then(() => (init_codegraph(), codegraph_exports)).then((m4) => m4.default),
|
|
92591
|
+
checkpoint: () => Promise.resolve().then(() => (init_checkpoint(), checkpoint_exports)).then((m4) => m4.default),
|
|
91712
92592
|
knowledge: () => Promise.resolve().then(() => (init_knowledge(), knowledge_exports)).then((m4) => m4.default),
|
|
91713
92593
|
reasoning: () => Promise.resolve().then(() => (init_reasoning(), reasoning_exports)).then((m4) => m4.default),
|
|
91714
92594
|
retention: () => Promise.resolve().then(() => (init_retention2(), retention_exports2)).then((m4) => m4.default),
|
|
@@ -91790,6 +92670,7 @@ var main = defineCommand({
|
|
|
91790
92670
|
"resume",
|
|
91791
92671
|
"explain",
|
|
91792
92672
|
"codegraph",
|
|
92673
|
+
"checkpoint",
|
|
91793
92674
|
"knowledge",
|
|
91794
92675
|
"reasoning",
|
|
91795
92676
|
"retention",
|
|
@@ -91858,6 +92739,7 @@ var main = defineCommand({
|
|
|
91858
92739
|
console.error(" resume Resume prior work with one bounded project brief");
|
|
91859
92740
|
console.error(" explain Explain where Memorix project context comes from");
|
|
91860
92741
|
console.error(" codegraph Refresh/status/context-pack for CodeGraph Memory");
|
|
92742
|
+
console.error(" checkpoint Inspect native compact continuity checkpoints");
|
|
91861
92743
|
console.error(" knowledge Review source-backed knowledge pages and project workflows");
|
|
91862
92744
|
console.error(" reasoning Store/search decision rationale");
|
|
91863
92745
|
console.error(" retention Inspect stale/archive status");
|