memorix 1.9.2 → 1.9.3
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 +11 -0
- package/dist/cli/index.js +318 -141
- package/dist/index.js +243 -120
- package/dist/maintenance-runner.js +184 -93
- package/dist/media-audio-runner.js +184 -93
- package/dist/media-video-runner.js +184 -93
- package/dist/memcode-runtime/CHANGELOG.md +11 -0
- package/dist/sdk.js +242 -119
- package/dist/vector-backfill-runner.js +184 -93
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +15 -0
- package/docs/ARCHITECTURE.md +23 -0
- package/docs/DEVELOPMENT.md +1 -1
- package/docs/PERFORMANCE.md +50 -0
- package/docs/README.md +1 -1
- package/package.json +1 -1
- package/plugins/antigravity/memorix/plugin.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-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/hermes/memorix/plugin.yaml +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/server.json +2 -2
- package/src/cli/commands/doctor.ts +78 -17
- package/src/store/mini-skill-store.ts +31 -22
- package/src/store/obs-store.ts +46 -30
- package/src/store/session-store.ts +35 -21
- package/src/store/sqlite-db.ts +16 -7
- package/src/store/sqlite-reliability.ts +87 -0
- package/src/store/sqlite-store.ts +4 -1
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.9.
|
|
3235
|
+
return true ? "1.9.3" : pkg.version;
|
|
3236
3236
|
}
|
|
3237
3237
|
var init_version = __esm({
|
|
3238
3238
|
"src/cli/version.ts"() {
|
|
@@ -9515,70 +9515,79 @@ function getDatabase(dataDir) {
|
|
|
9515
9515
|
loadBetterSqlite3();
|
|
9516
9516
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
9517
9517
|
const dbPath = path3.join(dataDir, "memorix.db");
|
|
9518
|
-
|
|
9519
|
-
db2.pragma("journal_mode = WAL");
|
|
9520
|
-
db2.pragma("busy_timeout = 5000");
|
|
9521
|
-
db2.pragma("foreign_keys = ON");
|
|
9522
|
-
db2.exec(CREATE_OBSERVATIONS_TABLE);
|
|
9523
|
-
db2.exec(CREATE_MINI_SKILLS_TABLE);
|
|
9524
|
-
db2.exec(CREATE_SESSIONS_TABLE);
|
|
9525
|
-
db2.exec(CREATE_META_TABLE);
|
|
9526
|
-
db2.exec(CREATE_TEAM_AGENTS_TABLE);
|
|
9527
|
-
db2.exec(CREATE_TEAM_TASKS_TABLE);
|
|
9528
|
-
db2.exec(CREATE_TEAM_TASK_DEPS_TABLE);
|
|
9529
|
-
db2.exec(CREATE_TEAM_MESSAGES_TABLE);
|
|
9530
|
-
db2.exec(CREATE_TEAM_LOCKS_TABLE);
|
|
9531
|
-
db2.exec(CREATE_TEAM_ROLES_TABLE);
|
|
9532
|
-
db2.exec(CREATE_GRAPH_ENTITIES_TABLE);
|
|
9533
|
-
db2.exec(CREATE_GRAPH_RELATIONS_TABLE);
|
|
9534
|
-
db2.exec(CREATE_CHAT_TRANSCRIPT_TABLE);
|
|
9535
|
-
db2.exec(CREATE_CODE_FILES_TABLE);
|
|
9536
|
-
db2.exec(CREATE_CODE_SYMBOLS_TABLE);
|
|
9537
|
-
db2.exec(CREATE_CODE_EDGES_TABLE);
|
|
9538
|
-
db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
|
|
9539
|
-
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
9540
|
-
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
9541
|
-
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
9518
|
+
let db2;
|
|
9542
9519
|
try {
|
|
9543
|
-
db2
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
db2.exec(
|
|
9548
|
-
|
|
9549
|
-
|
|
9550
|
-
|
|
9551
|
-
db2.exec(
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
db2.exec(
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
db2.exec(
|
|
9560
|
-
|
|
9561
|
-
|
|
9562
|
-
|
|
9563
|
-
db2.exec(
|
|
9564
|
-
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9571
|
-
|
|
9572
|
-
|
|
9520
|
+
db2 = createDatabase(dbPath);
|
|
9521
|
+
db2.pragma("busy_timeout = 5000");
|
|
9522
|
+
db2.pragma("journal_mode = WAL");
|
|
9523
|
+
db2.pragma("foreign_keys = ON");
|
|
9524
|
+
db2.exec(CREATE_OBSERVATIONS_TABLE);
|
|
9525
|
+
db2.exec(CREATE_MINI_SKILLS_TABLE);
|
|
9526
|
+
db2.exec(CREATE_SESSIONS_TABLE);
|
|
9527
|
+
db2.exec(CREATE_META_TABLE);
|
|
9528
|
+
db2.exec(CREATE_TEAM_AGENTS_TABLE);
|
|
9529
|
+
db2.exec(CREATE_TEAM_TASKS_TABLE);
|
|
9530
|
+
db2.exec(CREATE_TEAM_TASK_DEPS_TABLE);
|
|
9531
|
+
db2.exec(CREATE_TEAM_MESSAGES_TABLE);
|
|
9532
|
+
db2.exec(CREATE_TEAM_LOCKS_TABLE);
|
|
9533
|
+
db2.exec(CREATE_TEAM_ROLES_TABLE);
|
|
9534
|
+
db2.exec(CREATE_GRAPH_ENTITIES_TABLE);
|
|
9535
|
+
db2.exec(CREATE_GRAPH_RELATIONS_TABLE);
|
|
9536
|
+
db2.exec(CREATE_CHAT_TRANSCRIPT_TABLE);
|
|
9537
|
+
db2.exec(CREATE_CODE_FILES_TABLE);
|
|
9538
|
+
db2.exec(CREATE_CODE_SYMBOLS_TABLE);
|
|
9539
|
+
db2.exec(CREATE_CODE_EDGES_TABLE);
|
|
9540
|
+
db2.exec(CREATE_OBSERVATION_CODE_REFS_TABLE);
|
|
9541
|
+
db2.exec(CREATE_MAINTENANCE_JOBS_TABLE);
|
|
9542
|
+
db2.exec(CREATE_MAINTENANCE_TARGETS_TABLE);
|
|
9543
|
+
db2.exec(CREATE_COMPACTION_CHECKPOINTS_TABLE);
|
|
9544
|
+
try {
|
|
9545
|
+
db2.exec(`ALTER TABLE mini_skills ADD COLUMN sourceSnapshot TEXT NOT NULL DEFAULT ''`);
|
|
9546
|
+
} catch {
|
|
9547
|
+
}
|
|
9548
|
+
try {
|
|
9549
|
+
db2.exec(`ALTER TABLE mini_skills ADD COLUMN updatedAt TEXT`);
|
|
9550
|
+
} catch {
|
|
9551
|
+
}
|
|
9552
|
+
try {
|
|
9553
|
+
db2.exec(`ALTER TABLE observations ADD COLUMN createdByAgentId TEXT`);
|
|
9554
|
+
} catch {
|
|
9555
|
+
}
|
|
9556
|
+
try {
|
|
9557
|
+
db2.exec(`ALTER TABLE observations ADD COLUMN writeGeneration INTEGER DEFAULT 0`);
|
|
9558
|
+
} catch {
|
|
9559
|
+
}
|
|
9560
|
+
try {
|
|
9561
|
+
db2.exec(`ALTER TABLE team_tasks ADD COLUMN required_role TEXT`);
|
|
9562
|
+
} catch {
|
|
9563
|
+
}
|
|
9564
|
+
try {
|
|
9565
|
+
db2.exec(`ALTER TABLE team_tasks ADD COLUMN preferred_role TEXT`);
|
|
9566
|
+
} catch {
|
|
9567
|
+
}
|
|
9568
|
+
try {
|
|
9569
|
+
db2.exec(`ALTER TABLE team_messages ADD COLUMN to_role TEXT`);
|
|
9570
|
+
} catch {
|
|
9571
|
+
}
|
|
9572
|
+
try {
|
|
9573
|
+
db2.exec(`ALTER TABLE team_messages ADD COLUMN handoff_status TEXT`);
|
|
9574
|
+
} catch {
|
|
9575
|
+
}
|
|
9576
|
+
applySchemaMigrations(db2);
|
|
9577
|
+
db2.exec(CREATE_INDEXES);
|
|
9578
|
+
initializeObservationLexicalIndex(db2);
|
|
9579
|
+
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
9580
|
+
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
9581
|
+
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
9582
|
+
_dbCache.set(normalized, db2);
|
|
9583
|
+
return db2;
|
|
9584
|
+
} catch (error40) {
|
|
9585
|
+
try {
|
|
9586
|
+
db2?.close();
|
|
9587
|
+
} catch {
|
|
9588
|
+
}
|
|
9589
|
+
throw error40;
|
|
9573
9590
|
}
|
|
9574
|
-
applySchemaMigrations(db2);
|
|
9575
|
-
db2.exec(CREATE_INDEXES);
|
|
9576
|
-
initializeObservationLexicalIndex(db2);
|
|
9577
|
-
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('storage_generation', '0')`).run();
|
|
9578
|
-
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('next_id', '1')`).run();
|
|
9579
|
-
db2.prepare(`INSERT OR IGNORE INTO meta (key, value) VALUES ('mini_skills_generation', '0')`).run();
|
|
9580
|
-
_dbCache.set(normalized, db2);
|
|
9581
|
-
return db2;
|
|
9582
9591
|
}
|
|
9583
9592
|
function closeAllDatabases() {
|
|
9584
9593
|
for (const [key, db2] of _dbCache) {
|
|
@@ -10568,6 +10577,74 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
10568
10577
|
}
|
|
10569
10578
|
});
|
|
10570
10579
|
|
|
10580
|
+
// src/store/sqlite-reliability.ts
|
|
10581
|
+
function isTransientSqliteError(error40) {
|
|
10582
|
+
const code = error40?.code;
|
|
10583
|
+
if (typeof code === "string") {
|
|
10584
|
+
return /^SQLITE_BUSY(?:_|$)/i.test(code);
|
|
10585
|
+
}
|
|
10586
|
+
return error40 instanceof Error && /\bdatabase is locked\b|\bdatabase is busy\b/i.test(error40.message);
|
|
10587
|
+
}
|
|
10588
|
+
function isSqliteUnavailableError(error40) {
|
|
10589
|
+
return error40 instanceof SqliteUnavailableError || error40 instanceof Error && /SQLite is not available|better-sqlite3.*failed|node:sqlite.*failed|bun:sqlite.*failed/i.test(error40.message);
|
|
10590
|
+
}
|
|
10591
|
+
function degradedReadError(storeName) {
|
|
10592
|
+
return new Error(`[memorix] Cannot read ${storeName}: SQLite backend unavailable (memory is not loaded)`);
|
|
10593
|
+
}
|
|
10594
|
+
function degradedWriteError(storeName) {
|
|
10595
|
+
return new Error(`[memorix] Cannot write ${storeName}: SQLite backend unavailable (degraded mode; read-only)`);
|
|
10596
|
+
}
|
|
10597
|
+
function formatSqliteFailure(error40) {
|
|
10598
|
+
return error40 instanceof Error && error40.message ? error40.message : String(error40);
|
|
10599
|
+
}
|
|
10600
|
+
function delay(ms2) {
|
|
10601
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms2));
|
|
10602
|
+
}
|
|
10603
|
+
async function retrySqliteBusy(operation, label) {
|
|
10604
|
+
for (let attempt = 0; ; attempt++) {
|
|
10605
|
+
try {
|
|
10606
|
+
return await operation();
|
|
10607
|
+
} catch (error40) {
|
|
10608
|
+
if (!isTransientSqliteError(error40) || attempt >= SQLITE_BUSY_RETRY_DELAYS_MS.length) throw error40;
|
|
10609
|
+
const waitMs = SQLITE_BUSY_RETRY_DELAYS_MS[attempt];
|
|
10610
|
+
console.error(
|
|
10611
|
+
`[memorix] ${label} SQLite busy (attempt ${attempt + 1}/${SQLITE_BUSY_RETRY_DELAYS_MS.length + 1}), retrying in ${waitMs}ms`
|
|
10612
|
+
);
|
|
10613
|
+
await delay(waitMs);
|
|
10614
|
+
}
|
|
10615
|
+
}
|
|
10616
|
+
}
|
|
10617
|
+
async function initializeSqliteStore(factory, dataDir, label) {
|
|
10618
|
+
try {
|
|
10619
|
+
loadBetterSqlite3();
|
|
10620
|
+
} catch (error40) {
|
|
10621
|
+
throw new SqliteUnavailableError(error40);
|
|
10622
|
+
}
|
|
10623
|
+
return retrySqliteBusy(async () => {
|
|
10624
|
+
const store2 = factory();
|
|
10625
|
+
await store2.init(dataDir);
|
|
10626
|
+
return store2;
|
|
10627
|
+
}, label);
|
|
10628
|
+
}
|
|
10629
|
+
var SQLITE_BUSY_RETRY_DELAYS_MS, SqliteUnavailableError;
|
|
10630
|
+
var init_sqlite_reliability = __esm({
|
|
10631
|
+
"src/store/sqlite-reliability.ts"() {
|
|
10632
|
+
"use strict";
|
|
10633
|
+
init_esm_shims();
|
|
10634
|
+
init_sqlite_db();
|
|
10635
|
+
SQLITE_BUSY_RETRY_DELAYS_MS = [50, 150, 400, 1e3, 2500];
|
|
10636
|
+
SqliteUnavailableError = class extends Error {
|
|
10637
|
+
code = "MEMORIX_SQLITE_UNAVAILABLE";
|
|
10638
|
+
constructor(cause) {
|
|
10639
|
+
super(
|
|
10640
|
+
cause instanceof Error && cause.message ? cause.message : "[memorix] SQLite is unavailable (install a supported SQLite runtime)"
|
|
10641
|
+
);
|
|
10642
|
+
this.name = "SqliteUnavailableError";
|
|
10643
|
+
}
|
|
10644
|
+
};
|
|
10645
|
+
}
|
|
10646
|
+
});
|
|
10647
|
+
|
|
10571
10648
|
// src/store/file-lock.ts
|
|
10572
10649
|
import { promises as fs2 } from "fs";
|
|
10573
10650
|
import { randomUUID } from "crypto";
|
|
@@ -11065,16 +11142,18 @@ async function initMiniSkillStore(dataDir) {
|
|
|
11065
11142
|
if (_store && _storeDataDir === dataDir) return _store;
|
|
11066
11143
|
_store = null;
|
|
11067
11144
|
_storeDataDir = null;
|
|
11145
|
+
let degradedReason = "SQLite runtime unavailable";
|
|
11068
11146
|
try {
|
|
11069
|
-
const store3 = new MiniSkillSqliteStore();
|
|
11070
|
-
await store3.init(dataDir);
|
|
11147
|
+
const store3 = await initializeSqliteStore(() => new MiniSkillSqliteStore(), dataDir, "Mini-skill store");
|
|
11071
11148
|
_store = store3;
|
|
11072
11149
|
_storeDataDir = dataDir;
|
|
11073
11150
|
return store3;
|
|
11074
11151
|
} catch (err) {
|
|
11075
|
-
|
|
11152
|
+
if (!isSqliteUnavailableError(err)) throw err;
|
|
11153
|
+
degradedReason = err instanceof Error ? err.message : String(err);
|
|
11154
|
+
console.error(`[memorix] MiniSkillSqliteStore unavailable, running in degraded read-only mode: ${degradedReason}`);
|
|
11076
11155
|
}
|
|
11077
|
-
const store2 = new MiniSkillGracefulDegrade();
|
|
11156
|
+
const store2 = new MiniSkillGracefulDegrade(degradedReason);
|
|
11078
11157
|
await store2.init(dataDir);
|
|
11079
11158
|
_store = store2;
|
|
11080
11159
|
_storeDataDir = dataDir;
|
|
@@ -11086,6 +11165,7 @@ var init_mini_skill_store = __esm({
|
|
|
11086
11165
|
"use strict";
|
|
11087
11166
|
init_esm_shims();
|
|
11088
11167
|
init_sqlite_db();
|
|
11168
|
+
init_sqlite_reliability();
|
|
11089
11169
|
MiniSkillSqliteStore = class {
|
|
11090
11170
|
db = null;
|
|
11091
11171
|
dataDir = "";
|
|
@@ -11194,7 +11274,7 @@ var init_mini_skill_store = __esm({
|
|
|
11194
11274
|
* SQLite serializes write transactions, so concurrent calls are safely sequenced.
|
|
11195
11275
|
*/
|
|
11196
11276
|
async atomicInsertWithId(skillWithoutId) {
|
|
11197
|
-
|
|
11277
|
+
return retrySqliteBusy(async () => this.db.transaction(() => {
|
|
11198
11278
|
const row = this.stmtGetMeta.get("mini_skills_next_id");
|
|
11199
11279
|
const nextId2 = row ? parseInt(row.value, 10) : 1;
|
|
11200
11280
|
const skill2 = { ...skillWithoutId, id: nextId2 };
|
|
@@ -11203,8 +11283,7 @@ var init_mini_skill_store = __esm({
|
|
|
11203
11283
|
this.stmtBumpGeneration.run();
|
|
11204
11284
|
this.knownGeneration = this.readGeneration();
|
|
11205
11285
|
return skill2;
|
|
11206
|
-
})();
|
|
11207
|
-
return result;
|
|
11286
|
+
})(), "Mini-skill promotion");
|
|
11208
11287
|
}
|
|
11209
11288
|
// ── Freshness ────────────────────────────────────────────────────
|
|
11210
11289
|
async ensureFresh() {
|
|
@@ -11223,10 +11302,17 @@ var init_mini_skill_store = __esm({
|
|
|
11223
11302
|
}
|
|
11224
11303
|
};
|
|
11225
11304
|
MiniSkillGracefulDegrade = class {
|
|
11305
|
+
constructor(reason = "SQLite runtime unavailable") {
|
|
11306
|
+
this.reason = reason;
|
|
11307
|
+
}
|
|
11308
|
+
reason;
|
|
11226
11309
|
warned = false;
|
|
11310
|
+
unavailableRead() {
|
|
11311
|
+
return degradedReadError("mini-skills");
|
|
11312
|
+
}
|
|
11227
11313
|
warn() {
|
|
11228
11314
|
if (!this.warned) {
|
|
11229
|
-
console.error("[memorix] MiniSkillStore: SQLite unavailable \u2014 mini-skills
|
|
11315
|
+
console.error("[memorix] MiniSkillStore: SQLite unavailable \u2014 mini-skills cannot be read or written. Install a supported SQLite runtime.");
|
|
11230
11316
|
this.warned = true;
|
|
11231
11317
|
}
|
|
11232
11318
|
}
|
|
@@ -11234,28 +11320,33 @@ var init_mini_skill_store = __esm({
|
|
|
11234
11320
|
this.warn();
|
|
11235
11321
|
}
|
|
11236
11322
|
async loadAll() {
|
|
11237
|
-
|
|
11323
|
+
throw this.unavailableRead();
|
|
11238
11324
|
}
|
|
11239
11325
|
async loadByProject(_projectId) {
|
|
11240
|
-
|
|
11326
|
+
throw this.unavailableRead();
|
|
11241
11327
|
}
|
|
11242
11328
|
async loadIdCounter() {
|
|
11243
|
-
|
|
11329
|
+
throw this.unavailableRead();
|
|
11244
11330
|
}
|
|
11245
11331
|
async insert(_skill) {
|
|
11246
11332
|
this.warn();
|
|
11333
|
+
throw degradedWriteError("mini-skills");
|
|
11247
11334
|
}
|
|
11248
11335
|
async update(_skill) {
|
|
11249
11336
|
this.warn();
|
|
11337
|
+
throw degradedWriteError("mini-skills");
|
|
11250
11338
|
}
|
|
11251
11339
|
async remove(_id) {
|
|
11252
11340
|
this.warn();
|
|
11341
|
+
throw degradedWriteError("mini-skills");
|
|
11253
11342
|
}
|
|
11254
11343
|
async saveIdCounter(_nextId) {
|
|
11344
|
+
this.warn();
|
|
11345
|
+
throw degradedWriteError("mini-skills");
|
|
11255
11346
|
}
|
|
11256
11347
|
async atomicInsertWithId(skillWithoutId) {
|
|
11257
11348
|
this.warn();
|
|
11258
|
-
|
|
11349
|
+
throw degradedWriteError("mini-skills");
|
|
11259
11350
|
}
|
|
11260
11351
|
async ensureFresh() {
|
|
11261
11352
|
return false;
|
|
@@ -11266,6 +11357,9 @@ var init_mini_skill_store = __esm({
|
|
|
11266
11357
|
getBackendName() {
|
|
11267
11358
|
return "degraded";
|
|
11268
11359
|
}
|
|
11360
|
+
getBackendReason() {
|
|
11361
|
+
return this.reason;
|
|
11362
|
+
}
|
|
11269
11363
|
};
|
|
11270
11364
|
_store = null;
|
|
11271
11365
|
_storeDataDir = null;
|
|
@@ -23207,10 +23301,10 @@ async function fetchWithRetry(url2, apiKey, body, options = {}, attempt = 0, nat
|
|
|
23207
23301
|
);
|
|
23208
23302
|
}
|
|
23209
23303
|
if (options.retry !== false && (response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
|
|
23210
|
-
const
|
|
23304
|
+
const delay3 = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
23211
23305
|
const retryAfter = response.headers.get("retry-after");
|
|
23212
23306
|
const parsedRetryAfter = retryAfter ? parseInt(retryAfter, 10) * 1e3 : NaN;
|
|
23213
|
-
const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter :
|
|
23307
|
+
const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter : delay3;
|
|
23214
23308
|
console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES2} in ${waitMs}ms`);
|
|
23215
23309
|
await waitForRetry(waitMs, options.signal);
|
|
23216
23310
|
return fetchWithRetry(url2, apiKey, body, options, attempt + 1, nativeGemini);
|
|
@@ -25242,6 +25336,7 @@ var init_sqlite_store = __esm({
|
|
|
25242
25336
|
"use strict";
|
|
25243
25337
|
init_esm_shims();
|
|
25244
25338
|
init_sqlite_db();
|
|
25339
|
+
init_sqlite_reliability();
|
|
25245
25340
|
init_sqlite_fts();
|
|
25246
25341
|
SqliteBackend = class {
|
|
25247
25342
|
db = null;
|
|
@@ -25519,7 +25614,9 @@ var init_sqlite_store = __esm({
|
|
|
25519
25614
|
// ── Compound atomic operation ────────────────────────────────────
|
|
25520
25615
|
async atomic(fn2) {
|
|
25521
25616
|
const run = this._atomicQueue.catch(() => void 0).then(async () => {
|
|
25522
|
-
|
|
25617
|
+
await retrySqliteBusy(async () => {
|
|
25618
|
+
this.db.prepare("BEGIN IMMEDIATE").run();
|
|
25619
|
+
}, "Observation atomic write");
|
|
25523
25620
|
try {
|
|
25524
25621
|
const tx = {
|
|
25525
25622
|
loadAll: async () => this.rawLoadAll(),
|
|
@@ -25618,15 +25715,15 @@ function resetObservationStore() {
|
|
|
25618
25715
|
async function createObservationStore(dataDir) {
|
|
25619
25716
|
try {
|
|
25620
25717
|
const { SqliteBackend: SqliteBackend2 } = await Promise.resolve().then(() => (init_sqlite_store(), sqlite_store_exports));
|
|
25621
|
-
|
|
25622
|
-
await store3.init(dataDir);
|
|
25623
|
-
return store3;
|
|
25718
|
+
return await initializeSqliteStore(() => new SqliteBackend2(), dataDir, "Observation store");
|
|
25624
25719
|
} catch (err) {
|
|
25625
|
-
|
|
25720
|
+
if (!isSqliteUnavailableError(err)) throw err;
|
|
25721
|
+
const reason = formatSqliteFailure(err);
|
|
25722
|
+
console.error(`[memorix] SQLite module unavailable \u2014 degraded mode (reads/writes disabled): ${reason}`);
|
|
25723
|
+
const degraded = new DegradedBackend(reason);
|
|
25724
|
+
await degraded.init(dataDir);
|
|
25725
|
+
return degraded;
|
|
25626
25726
|
}
|
|
25627
|
-
const store2 = new DegradedBackend();
|
|
25628
|
-
await store2.init(dataDir);
|
|
25629
|
-
return store2;
|
|
25630
25727
|
}
|
|
25631
25728
|
async function initObservationStore(dataDir) {
|
|
25632
25729
|
if (_store2 && _storeDataDir2 === dataDir) {
|
|
@@ -25650,36 +25747,44 @@ var init_obs_store = __esm({
|
|
|
25650
25747
|
"src/store/obs-store.ts"() {
|
|
25651
25748
|
"use strict";
|
|
25652
25749
|
init_esm_shims();
|
|
25750
|
+
init_sqlite_reliability();
|
|
25653
25751
|
_store2 = null;
|
|
25654
25752
|
_storeDataDir2 = null;
|
|
25655
25753
|
DegradedBackend = class {
|
|
25754
|
+
constructor(reason = "SQLite runtime unavailable") {
|
|
25755
|
+
this.reason = reason;
|
|
25756
|
+
}
|
|
25757
|
+
reason;
|
|
25656
25758
|
dataDir = "";
|
|
25759
|
+
unavailableRead() {
|
|
25760
|
+
return degradedReadError("observations");
|
|
25761
|
+
}
|
|
25657
25762
|
async init(dataDir) {
|
|
25658
25763
|
this.dataDir = dataDir;
|
|
25659
25764
|
}
|
|
25660
25765
|
async loadAll() {
|
|
25661
|
-
|
|
25766
|
+
throw this.unavailableRead();
|
|
25662
25767
|
}
|
|
25663
25768
|
async loadByProject(_projectId, _options) {
|
|
25664
|
-
|
|
25769
|
+
throw this.unavailableRead();
|
|
25665
25770
|
}
|
|
25666
25771
|
async countByProject(_projectId, _options) {
|
|
25667
|
-
|
|
25772
|
+
throw this.unavailableRead();
|
|
25668
25773
|
}
|
|
25669
25774
|
async getById(_id) {
|
|
25670
|
-
|
|
25775
|
+
throw this.unavailableRead();
|
|
25671
25776
|
}
|
|
25672
25777
|
async loadIdCounter() {
|
|
25673
|
-
|
|
25778
|
+
throw this.unavailableRead();
|
|
25674
25779
|
}
|
|
25675
25780
|
async countAll() {
|
|
25676
|
-
|
|
25781
|
+
throw this.unavailableRead();
|
|
25677
25782
|
}
|
|
25678
25783
|
async listProjectIds() {
|
|
25679
|
-
|
|
25784
|
+
throw this.unavailableRead();
|
|
25680
25785
|
}
|
|
25681
25786
|
async searchLexical(_options) {
|
|
25682
|
-
|
|
25787
|
+
throw this.unavailableRead();
|
|
25683
25788
|
}
|
|
25684
25789
|
hasLexicalIndex() {
|
|
25685
25790
|
return false;
|
|
@@ -25688,25 +25793,25 @@ var init_obs_store = __esm({
|
|
|
25688
25793
|
return false;
|
|
25689
25794
|
}
|
|
25690
25795
|
async insert(_obs) {
|
|
25691
|
-
throw
|
|
25796
|
+
throw degradedWriteError("observations");
|
|
25692
25797
|
}
|
|
25693
25798
|
async update(_obs) {
|
|
25694
|
-
throw
|
|
25799
|
+
throw degradedWriteError("observations");
|
|
25695
25800
|
}
|
|
25696
25801
|
async remove(_id) {
|
|
25697
|
-
throw
|
|
25802
|
+
throw degradedWriteError("observations");
|
|
25698
25803
|
}
|
|
25699
25804
|
async bulkReplace(_obs) {
|
|
25700
|
-
throw
|
|
25805
|
+
throw degradedWriteError("observations");
|
|
25701
25806
|
}
|
|
25702
25807
|
async bulkRemoveByIds(_ids) {
|
|
25703
|
-
throw
|
|
25808
|
+
throw degradedWriteError("observations");
|
|
25704
25809
|
}
|
|
25705
25810
|
async saveIdCounter(_nextId) {
|
|
25706
|
-
throw
|
|
25811
|
+
throw degradedWriteError("observations");
|
|
25707
25812
|
}
|
|
25708
25813
|
async atomic(_fn) {
|
|
25709
|
-
throw
|
|
25814
|
+
throw degradedWriteError("observations");
|
|
25710
25815
|
}
|
|
25711
25816
|
async ensureFresh() {
|
|
25712
25817
|
return false;
|
|
@@ -25719,6 +25824,9 @@ var init_obs_store = __esm({
|
|
|
25719
25824
|
getBackendName() {
|
|
25720
25825
|
return "degraded";
|
|
25721
25826
|
}
|
|
25827
|
+
getBackendReason() {
|
|
25828
|
+
return this.reason;
|
|
25829
|
+
}
|
|
25722
25830
|
};
|
|
25723
25831
|
}
|
|
25724
25832
|
});
|
|
@@ -73579,10 +73687,10 @@ var require_retry3 = __commonJS({
|
|
|
73579
73687
|
if (!await shouldRetryFn(err)) {
|
|
73580
73688
|
return { shouldRetry: false, config: err.config };
|
|
73581
73689
|
}
|
|
73582
|
-
const
|
|
73690
|
+
const delay3 = getNextRetryDelay(config2);
|
|
73583
73691
|
err.config.retryConfig.currentRetryAttempt += 1;
|
|
73584
|
-
const backoff = config2.retryBackoff ? config2.retryBackoff(err,
|
|
73585
|
-
setTimeout(resolve9,
|
|
73692
|
+
const backoff = config2.retryBackoff ? config2.retryBackoff(err, delay3) : new Promise((resolve9) => {
|
|
73693
|
+
setTimeout(resolve9, delay3);
|
|
73586
73694
|
});
|
|
73587
73695
|
if (config2.onRetryAttempt) {
|
|
73588
73696
|
await config2.onRetryAttempt(err);
|
|
@@ -127107,7 +127215,7 @@ async function retryBackoff(fn2, strategy) {
|
|
|
127107
127215
|
retryInterval = initialInterval * Math.pow(x5, exponent) + Math.random() * 1e3;
|
|
127108
127216
|
}
|
|
127109
127217
|
const d4 = Math.min(retryInterval, maxInterval);
|
|
127110
|
-
await
|
|
127218
|
+
await delay2(d4);
|
|
127111
127219
|
x5++;
|
|
127112
127220
|
}
|
|
127113
127221
|
}
|
|
@@ -127128,8 +127236,8 @@ function retryIntervalFromResponse(res) {
|
|
|
127128
127236
|
}
|
|
127129
127237
|
return 0;
|
|
127130
127238
|
}
|
|
127131
|
-
async function
|
|
127132
|
-
return new Promise((resolve9) => setTimeout(resolve9,
|
|
127239
|
+
async function delay2(delay3) {
|
|
127240
|
+
return new Promise((resolve9) => setTimeout(resolve9, delay3));
|
|
127133
127241
|
}
|
|
127134
127242
|
var defaultBackoff, PermanentError, TemporaryError, codeRangeRE2;
|
|
127135
127243
|
var init_retries = __esm({
|
|
@@ -191552,16 +191660,18 @@ async function initSessionStore(dataDir) {
|
|
|
191552
191660
|
if (_store3 && _storeDataDir3 === dataDir) return _store3;
|
|
191553
191661
|
_store3 = null;
|
|
191554
191662
|
_storeDataDir3 = null;
|
|
191663
|
+
let degradedReason = "SQLite runtime unavailable";
|
|
191555
191664
|
try {
|
|
191556
|
-
const store3 = new SessionSqliteStore();
|
|
191557
|
-
await store3.init(dataDir);
|
|
191665
|
+
const store3 = await initializeSqliteStore(() => new SessionSqliteStore(), dataDir, "Session store");
|
|
191558
191666
|
_store3 = store3;
|
|
191559
191667
|
_storeDataDir3 = dataDir;
|
|
191560
191668
|
return store3;
|
|
191561
191669
|
} catch (err) {
|
|
191562
|
-
|
|
191670
|
+
if (!isSqliteUnavailableError(err)) throw err;
|
|
191671
|
+
degradedReason = formatSqliteFailure(err);
|
|
191672
|
+
console.error(`[memorix] SessionSqliteStore unavailable, running in degraded read-only mode: ${degradedReason}`);
|
|
191563
191673
|
}
|
|
191564
|
-
const store2 = new SessionGracefulDegrade();
|
|
191674
|
+
const store2 = new SessionGracefulDegrade(degradedReason);
|
|
191565
191675
|
await store2.init(dataDir);
|
|
191566
191676
|
_store3 = store2;
|
|
191567
191677
|
_storeDataDir3 = dataDir;
|
|
@@ -191573,6 +191683,7 @@ var init_session_store = __esm({
|
|
|
191573
191683
|
"use strict";
|
|
191574
191684
|
init_esm_shims();
|
|
191575
191685
|
init_sqlite_db();
|
|
191686
|
+
init_sqlite_reliability();
|
|
191576
191687
|
SessionSqliteStore = class {
|
|
191577
191688
|
db = null;
|
|
191578
191689
|
dataDir = "";
|
|
@@ -191661,7 +191772,7 @@ var init_session_store = __esm({
|
|
|
191661
191772
|
}
|
|
191662
191773
|
const stmtComplete = this._stmtCompleteActive;
|
|
191663
191774
|
const stmtIns = this.stmtInsert;
|
|
191664
|
-
|
|
191775
|
+
return retrySqliteBusy(async () => this.db.transaction(() => {
|
|
191665
191776
|
let completedCount = 0;
|
|
191666
191777
|
for (const pid of projectIds) {
|
|
191667
191778
|
const info2 = stmtComplete.run({ pid, now: now3 });
|
|
@@ -191669,18 +191780,24 @@ var init_session_store = __esm({
|
|
|
191669
191780
|
}
|
|
191670
191781
|
stmtIns.run(sessionToRow(newSession));
|
|
191671
191782
|
return completedCount;
|
|
191672
|
-
})();
|
|
191673
|
-
return result;
|
|
191783
|
+
})(), "Session rollover");
|
|
191674
191784
|
}
|
|
191675
191785
|
getBackendName() {
|
|
191676
191786
|
return "sqlite";
|
|
191677
191787
|
}
|
|
191678
191788
|
};
|
|
191679
191789
|
SessionGracefulDegrade = class {
|
|
191790
|
+
constructor(reason = "SQLite runtime unavailable") {
|
|
191791
|
+
this.reason = reason;
|
|
191792
|
+
}
|
|
191793
|
+
reason;
|
|
191680
191794
|
warned = false;
|
|
191795
|
+
unavailableRead() {
|
|
191796
|
+
return degradedReadError("sessions");
|
|
191797
|
+
}
|
|
191681
191798
|
warn() {
|
|
191682
191799
|
if (!this.warned) {
|
|
191683
|
-
console.error("[memorix] SessionStore: SQLite unavailable \u2014 sessions
|
|
191800
|
+
console.error("[memorix] SessionStore: SQLite unavailable \u2014 sessions cannot be read or written. Install a supported SQLite runtime.");
|
|
191684
191801
|
this.warned = true;
|
|
191685
191802
|
}
|
|
191686
191803
|
}
|
|
@@ -191688,33 +191805,39 @@ var init_session_store = __esm({
|
|
|
191688
191805
|
this.warn();
|
|
191689
191806
|
}
|
|
191690
191807
|
async loadAll() {
|
|
191691
|
-
|
|
191808
|
+
throw this.unavailableRead();
|
|
191692
191809
|
}
|
|
191693
191810
|
async getById(_id) {
|
|
191694
|
-
|
|
191811
|
+
throw this.unavailableRead();
|
|
191695
191812
|
}
|
|
191696
191813
|
async loadByProject(_projectId) {
|
|
191697
|
-
|
|
191814
|
+
throw this.unavailableRead();
|
|
191698
191815
|
}
|
|
191699
191816
|
async loadActive(_projectId) {
|
|
191700
|
-
|
|
191817
|
+
throw this.unavailableRead();
|
|
191701
191818
|
}
|
|
191702
191819
|
async insert(_session) {
|
|
191703
191820
|
this.warn();
|
|
191821
|
+
throw degradedWriteError("sessions");
|
|
191704
191822
|
}
|
|
191705
191823
|
async update(_session) {
|
|
191706
191824
|
this.warn();
|
|
191825
|
+
throw degradedWriteError("sessions");
|
|
191707
191826
|
}
|
|
191708
191827
|
async bulkUpdate(_sessions) {
|
|
191709
191828
|
this.warn();
|
|
191829
|
+
throw degradedWriteError("sessions");
|
|
191710
191830
|
}
|
|
191711
191831
|
async atomicRolloverInsert(_newSession, _projectIds, _now) {
|
|
191712
191832
|
this.warn();
|
|
191713
|
-
|
|
191833
|
+
throw degradedWriteError("sessions");
|
|
191714
191834
|
}
|
|
191715
191835
|
getBackendName() {
|
|
191716
191836
|
return "degraded";
|
|
191717
191837
|
}
|
|
191838
|
+
getBackendReason() {
|
|
191839
|
+
return this.reason;
|
|
191840
|
+
}
|
|
191718
191841
|
};
|
|
191719
191842
|
_store3 = null;
|
|
191720
191843
|
_storeDataDir3 = null;
|
|
@@ -207835,7 +207958,7 @@ var init_tool_profile = __esm({
|
|
|
207835
207958
|
function getMcpServerInfo() {
|
|
207836
207959
|
return {
|
|
207837
207960
|
name: "memorix",
|
|
207838
|
-
version: true ? "1.9.
|
|
207961
|
+
version: true ? "1.9.3" : "1.0.1"
|
|
207839
207962
|
};
|
|
207840
207963
|
}
|
|
207841
207964
|
function createMcpDiscoverResult(capabilities, serverInfo) {
|
|
@@ -281651,22 +281774,39 @@ var init_doctor = __esm({
|
|
|
281651
281774
|
let activeCount = 0;
|
|
281652
281775
|
let ranCount = 0;
|
|
281653
281776
|
let backendName = "unknown";
|
|
281777
|
+
let backendReason;
|
|
281778
|
+
let observationFailure;
|
|
281654
281779
|
try {
|
|
281655
281780
|
const { initObservationStore: initObservationStore2, getObservationStore: getObservationStore2 } = await Promise.resolve().then(() => (init_obs_store(), obs_store_exports));
|
|
281656
281781
|
await initObservationStore2(dataDir);
|
|
281657
281782
|
const store2 = getObservationStore2();
|
|
281658
281783
|
backendName = store2.getBackendName();
|
|
281784
|
+
backendReason = store2.getBackendReason?.();
|
|
281659
281785
|
const { filterReadableObservations: filterReadableObservations2 } = await Promise.resolve().then(() => (init_visibility(), visibility_exports));
|
|
281660
281786
|
projectObservations = projectId ? filterReadableObservations2(await store2.loadAll(), { projectId }) : [];
|
|
281661
281787
|
obsCount = projectObservations.length;
|
|
281662
281788
|
activeCount = projectObservations.filter((o4) => (o4.status ?? "active") === "active").length;
|
|
281663
281789
|
ranCount = projectObservations.filter((o4) => /^Ran:\s/i.test(o4.title ?? "")).length;
|
|
281664
|
-
} catch {
|
|
281665
|
-
|
|
281666
|
-
|
|
281667
|
-
|
|
281668
|
-
|
|
281790
|
+
} catch (error40) {
|
|
281791
|
+
observationFailure = error40 instanceof Error ? error40.message : String(error40);
|
|
281792
|
+
}
|
|
281793
|
+
if (observationFailure) {
|
|
281794
|
+
lines.push(fail2(`Observations: storage unavailable \u2014 ${observationFailure}`));
|
|
281795
|
+
issues.push(`Observation store could not be opened: ${observationFailure}`);
|
|
281796
|
+
report.data = {
|
|
281797
|
+
backend: "unavailable",
|
|
281798
|
+
observations: null,
|
|
281799
|
+
active: null,
|
|
281800
|
+
commandLogs: null,
|
|
281801
|
+
error: observationFailure
|
|
281802
|
+
};
|
|
281803
|
+
} else if (backendName === "degraded") {
|
|
281804
|
+
lines.push(fail2(`Backend: degraded (read-only; writes disabled${backendReason ? `; ${backendReason}` : ""})`));
|
|
281805
|
+
lines.push(fail2("Observations: unavailable \u2014 count not reported"));
|
|
281806
|
+
issues.push("SQLite backend unavailable \u2014 observation storage is in degraded read-only mode; observations are not being persisted.");
|
|
281807
|
+
report.data = { backend: "degraded", ...backendReason ? { backendReason } : {}, observations: null, active: null, commandLogs: null };
|
|
281669
281808
|
} else {
|
|
281809
|
+
lines.push(ok("Backend: sqlite (read-write)"));
|
|
281670
281810
|
lines.push(ok(`Observations: ${obsCount} total, ${activeCount} active`));
|
|
281671
281811
|
if (ranCount > 0) {
|
|
281672
281812
|
const pct = Math.round(ranCount / obsCount * 100);
|
|
@@ -281676,29 +281816,63 @@ var init_doctor = __esm({
|
|
|
281676
281816
|
}
|
|
281677
281817
|
}
|
|
281678
281818
|
}
|
|
281679
|
-
report.data
|
|
281819
|
+
if (!report.data) {
|
|
281820
|
+
report.data = { backend: backendName, observations: obsCount, active: activeCount, commandLogs: ranCount };
|
|
281821
|
+
} else if (!report.data.backend) {
|
|
281822
|
+
report.data.backend = backendName;
|
|
281823
|
+
}
|
|
281824
|
+
let sessionBackend = "unknown";
|
|
281825
|
+
let sessionReason;
|
|
281680
281826
|
try {
|
|
281681
281827
|
const { initSessionStore: initSessionStore2, getSessionStore: getSessionStore2 } = await Promise.resolve().then(() => (init_session_store(), session_store_exports));
|
|
281682
281828
|
await initSessionStore2(dataDir);
|
|
281683
281829
|
const sessStore = getSessionStore2();
|
|
281684
|
-
|
|
281685
|
-
|
|
281686
|
-
|
|
281687
|
-
|
|
281688
|
-
|
|
281689
|
-
|
|
281830
|
+
sessionBackend = sessStore.getBackendName();
|
|
281831
|
+
sessionReason = sessStore.getBackendReason?.();
|
|
281832
|
+
if (sessionBackend === "degraded") {
|
|
281833
|
+
lines.push(fail2(`Sessions: unavailable \u2014 read-only degraded backend${sessionReason ? `; ${sessionReason}` : ""}`));
|
|
281834
|
+
issues.push("Session storage is in degraded read-only mode.");
|
|
281835
|
+
report.data.sessions = null;
|
|
281836
|
+
if (sessionReason) report.data.sessionBackendReason = sessionReason;
|
|
281837
|
+
} else {
|
|
281838
|
+
const sess = await sessStore.loadAll();
|
|
281839
|
+
const sessCount = sess.length;
|
|
281840
|
+
const activeSess = sess.filter((s4) => s4.status === "active").length;
|
|
281841
|
+
lines.push(ok(`Sessions: ${sessCount} total, ${activeSess} active`));
|
|
281842
|
+
report.data.sessions = sessCount;
|
|
281843
|
+
}
|
|
281844
|
+
} catch (error40) {
|
|
281845
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
281846
|
+
lines.push(fail2(`Sessions: unavailable (${message})`));
|
|
281847
|
+
issues.push(`Session storage is unavailable: ${message}`);
|
|
281848
|
+
report.data.sessions = null;
|
|
281690
281849
|
}
|
|
281850
|
+
let skillBackend = "unknown";
|
|
281851
|
+
let skillReason;
|
|
281691
281852
|
try {
|
|
281692
281853
|
const { initMiniSkillStore: initMiniSkillStore2, getMiniSkillStore: getMiniSkillStore2 } = await Promise.resolve().then(() => (init_mini_skill_store(), mini_skill_store_exports));
|
|
281693
281854
|
await initMiniSkillStore2(dataDir);
|
|
281694
281855
|
const skillStore = getMiniSkillStore2();
|
|
281695
|
-
|
|
281696
|
-
|
|
281697
|
-
if (
|
|
281698
|
-
lines.push(
|
|
281699
|
-
|
|
281856
|
+
skillBackend = skillStore.getBackendName();
|
|
281857
|
+
skillReason = skillStore.getBackendReason?.();
|
|
281858
|
+
if (skillBackend === "degraded") {
|
|
281859
|
+
lines.push(fail2(`Mini-skills: unavailable \u2014 read-only degraded backend${skillReason ? `; ${skillReason}` : ""}`));
|
|
281860
|
+
issues.push("Mini-skill storage is in degraded read-only mode.");
|
|
281861
|
+
report.data.miniSkills = null;
|
|
281862
|
+
if (skillReason) report.data.miniSkillBackendReason = skillReason;
|
|
281863
|
+
} else {
|
|
281864
|
+
const skills = await skillStore.loadAll();
|
|
281865
|
+
const skillCount = skills.length;
|
|
281866
|
+
if (skillCount > 0) {
|
|
281867
|
+
lines.push(ok(`Mini-skills: ${skillCount}`));
|
|
281868
|
+
report.data.miniSkills = skillCount;
|
|
281869
|
+
}
|
|
281700
281870
|
}
|
|
281701
|
-
} catch {
|
|
281871
|
+
} catch (error40) {
|
|
281872
|
+
const message = error40 instanceof Error ? error40.message : String(error40);
|
|
281873
|
+
lines.push(fail2(`Mini-skills: unavailable (${message})`));
|
|
281874
|
+
issues.push(`Mini-skill storage is unavailable: ${message}`);
|
|
281875
|
+
report.data.miniSkills = null;
|
|
281702
281876
|
}
|
|
281703
281877
|
} else {
|
|
281704
281878
|
lines.push(warn2("No data directory found for current project"));
|
|
@@ -281946,6 +282120,9 @@ var init_doctor = __esm({
|
|
|
281946
282120
|
} else {
|
|
281947
282121
|
console.log(lines.join("\n"));
|
|
281948
282122
|
}
|
|
282123
|
+
if (issues.some((issue2) => /^(Observation store could not be opened|Observation storage |Session storage |Mini-skill storage |SQLite backend unavailable)/.test(issue2))) {
|
|
282124
|
+
process.exitCode = 1;
|
|
282125
|
+
}
|
|
281949
282126
|
}
|
|
281950
282127
|
});
|
|
281951
282128
|
}
|
|
@@ -284393,12 +284570,12 @@ function classifyError(ctx, taskId) {
|
|
|
284393
284570
|
if (taskId) backoffState.set(taskId, attempt);
|
|
284394
284571
|
const baseDelay = 2e3;
|
|
284395
284572
|
const maxDelay = 3e4;
|
|
284396
|
-
const
|
|
284397
|
-
const jitter =
|
|
284573
|
+
const delay3 = Math.min(baseDelay * Math.pow(2, attempt - 1), maxDelay);
|
|
284574
|
+
const jitter = delay3 * 0.25 * (Math.random() * 2 - 1);
|
|
284398
284575
|
return {
|
|
284399
284576
|
category: "transient",
|
|
284400
284577
|
strategy: "backoff_and_retry",
|
|
284401
|
-
delayMs: Math.round(
|
|
284578
|
+
delayMs: Math.round(delay3 + jitter),
|
|
284402
284579
|
reason: `Transient error detected (attempt ${attempt})`,
|
|
284403
284580
|
backoffAttempt: attempt
|
|
284404
284581
|
};
|