memorix 1.2.10 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +28 -2
- package/README.zh-CN.md +28 -2
- package/assets/star-history-dark.svg +30 -0
- package/assets/star-history-light.svg +30 -0
- package/assets/star-history.json +599 -0
- package/dist/cli/index.js +1783 -557
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +1292 -267
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.js +97 -21
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +15 -0
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.js +1294 -269
- package/dist/sdk.js.map +1 -1
- package/dist/types.d.ts +99 -1
- package/dist/types.js.map +1 -1
- package/dist/vector-backfill-runner.js +97 -21
- package/dist/vector-backfill-runner.js.map +1 -1
- package/docs/1.3-MEMORY-ARCHITECTURE.md +236 -0
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +3 -1
- package/docs/API_REFERENCE.md +20 -1
- package/docs/ARCHITECTURE.md +34 -1
- package/docs/DEVELOPMENT.md +3 -2
- package/docs/MODULES.md +27 -1
- package/docs/README.md +3 -3
- package/docs/dev-log/progress.txt +22 -0
- package/llms-full.txt +5 -1
- package/llms.txt +2 -0
- package/package.json +2 -1
- package/plugins/antigravity/memorix/rules/memorix.md +2 -0
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/copilot/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/cursor/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/plugins/gemini/memorix/GEMINI.md +2 -0
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/plugins/pi/memorix/skills/memorix-memory/SKILL.md +3 -0
- package/server.json +2 -2
- package/src/cli/command-guide.ts +9 -1
- package/src/cli/commands/codegraph.ts +1 -0
- package/src/cli/commands/memory.ts +217 -1
- package/src/codegraph/auto-context.ts +11 -0
- package/src/codegraph/context-pack.ts +3 -0
- package/src/embedding/api-provider.ts +23 -9
- package/src/embedding/provider.ts +21 -10
- package/src/hooks/installers/index.ts +2 -0
- package/src/knowledge/context-assembly.ts +2 -1
- package/src/knowledge/workset.ts +77 -4
- package/src/memory/long-term-store.ts +242 -0
- package/src/memory/long-term-types.ts +136 -0
- package/src/memory/long-term.ts +626 -0
- package/src/memory/owner.ts +75 -0
- package/src/server.ts +112 -30
- package/src/store/sqlite-db.ts +74 -0
- package/src/types.ts +20 -0
|
@@ -279,7 +279,7 @@ function closeAllDatabases() {
|
|
|
279
279
|
_dbCache.delete(key);
|
|
280
280
|
}
|
|
281
281
|
}
|
|
282
|
-
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;
|
|
282
|
+
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_LONG_TERM_MEMORIES_TABLE, CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE, CREATE_LONG_TERM_MEMORY_EVENTS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
283
283
|
var init_sqlite_db = __esm({
|
|
284
284
|
"src/store/sqlite-db.ts"() {
|
|
285
285
|
"use strict";
|
|
@@ -705,6 +705,57 @@ CREATE TABLE IF NOT EXISTS knowledge_claim_events (
|
|
|
705
705
|
" FOREIGN KEY (workflowId) REFERENCES knowledge_workflows(id) ON DELETE CASCADE",
|
|
706
706
|
");"
|
|
707
707
|
].join("\n");
|
|
708
|
+
CREATE_LONG_TERM_MEMORIES_TABLE = `
|
|
709
|
+
CREATE TABLE IF NOT EXISTS long_term_memories (
|
|
710
|
+
id TEXT PRIMARY KEY,
|
|
711
|
+
originProjectId TEXT NOT NULL,
|
|
712
|
+
ownerId TEXT NOT NULL,
|
|
713
|
+
scope TEXT NOT NULL,
|
|
714
|
+
kind TEXT NOT NULL,
|
|
715
|
+
state TEXT NOT NULL,
|
|
716
|
+
portability TEXT NOT NULL DEFAULT 'project-bound',
|
|
717
|
+
title TEXT NOT NULL,
|
|
718
|
+
content TEXT NOT NULL,
|
|
719
|
+
factsJson TEXT NOT NULL DEFAULT '[]',
|
|
720
|
+
tagsJson TEXT NOT NULL DEFAULT '[]',
|
|
721
|
+
applicability TEXT,
|
|
722
|
+
origin TEXT NOT NULL,
|
|
723
|
+
createdAt TEXT NOT NULL,
|
|
724
|
+
updatedAt TEXT NOT NULL,
|
|
725
|
+
qualifiedAt TEXT,
|
|
726
|
+
approvedAt TEXT,
|
|
727
|
+
archivedAt TEXT,
|
|
728
|
+
supersededBy TEXT,
|
|
729
|
+
lastValidatedAt TEXT,
|
|
730
|
+
accessCount INTEGER NOT NULL DEFAULT 0,
|
|
731
|
+
lastAccessedAt TEXT
|
|
732
|
+
);
|
|
733
|
+
`;
|
|
734
|
+
CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE = `
|
|
735
|
+
CREATE TABLE IF NOT EXISTS long_term_memory_evidence (
|
|
736
|
+
id TEXT PRIMARY KEY,
|
|
737
|
+
memoryId TEXT NOT NULL,
|
|
738
|
+
kind TEXT NOT NULL,
|
|
739
|
+
referenceId TEXT NOT NULL,
|
|
740
|
+
relation TEXT NOT NULL,
|
|
741
|
+
locator TEXT,
|
|
742
|
+
capturedHash TEXT,
|
|
743
|
+
createdAt TEXT NOT NULL,
|
|
744
|
+
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
745
|
+
);
|
|
746
|
+
`;
|
|
747
|
+
CREATE_LONG_TERM_MEMORY_EVENTS_TABLE = `
|
|
748
|
+
CREATE TABLE IF NOT EXISTS long_term_memory_events (
|
|
749
|
+
id TEXT PRIMARY KEY,
|
|
750
|
+
memoryId TEXT NOT NULL,
|
|
751
|
+
kind TEXT NOT NULL,
|
|
752
|
+
fromState TEXT,
|
|
753
|
+
toState TEXT,
|
|
754
|
+
detail TEXT,
|
|
755
|
+
createdAt TEXT NOT NULL,
|
|
756
|
+
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
757
|
+
);
|
|
758
|
+
`;
|
|
708
759
|
CREATE_MAINTENANCE_JOBS_TABLE = `
|
|
709
760
|
CREATE TABLE IF NOT EXISTS maintenance_jobs (
|
|
710
761
|
id TEXT PRIMARY KEY,
|
|
@@ -800,6 +851,11 @@ CREATE INDEX IF NOT EXISTS idx_knowledge_page_claims_claim ON knowledge_page_cla
|
|
|
800
851
|
CREATE INDEX IF NOT EXISTS idx_knowledge_proposals_workspace_status ON knowledge_proposals(workspaceId, status, createdAt DESC);
|
|
801
852
|
CREATE INDEX IF NOT EXISTS idx_knowledge_workflows_workspace_status ON knowledge_workflows(workspaceId, status, updatedAt DESC);
|
|
802
853
|
CREATE INDEX IF NOT EXISTS idx_knowledge_workflow_runs_project_workflow ON knowledge_workflow_runs(projectId, workflowId, startedAt DESC);
|
|
854
|
+
CREATE INDEX IF NOT EXISTS idx_long_term_memories_owner_state ON long_term_memories(ownerId, state, updatedAt DESC);
|
|
855
|
+
CREATE INDEX IF NOT EXISTS idx_long_term_memories_project_state ON long_term_memories(originProjectId, state, updatedAt DESC);
|
|
856
|
+
CREATE INDEX IF NOT EXISTS idx_long_term_memories_scope_portability ON long_term_memories(scope, portability, state, updatedAt DESC);
|
|
857
|
+
CREATE INDEX IF NOT EXISTS idx_long_term_memory_evidence_memory ON long_term_memory_evidence(memoryId, createdAt);
|
|
858
|
+
CREATE INDEX IF NOT EXISTS idx_long_term_memory_events_memory ON long_term_memory_events(memoryId, createdAt);
|
|
803
859
|
CREATE INDEX IF NOT EXISTS idx_maintenance_jobs_ready ON maintenance_jobs(status, run_after);
|
|
804
860
|
CREATE INDEX IF NOT EXISTS idx_maintenance_jobs_project ON maintenance_jobs(project_id, status, run_after);
|
|
805
861
|
CREATE INDEX IF NOT EXISTS idx_maintenance_targets_updated ON maintenance_targets(updated_at);
|
|
@@ -888,6 +944,19 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
888
944
|
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)");
|
|
889
945
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_compaction_checkpoints_source ON compaction_checkpoints(project_id, source_key)");
|
|
890
946
|
}
|
|
947
|
+
},
|
|
948
|
+
{
|
|
949
|
+
id: "1.3-long-term-memory",
|
|
950
|
+
apply: (db2) => {
|
|
951
|
+
db2.exec(CREATE_LONG_TERM_MEMORIES_TABLE);
|
|
952
|
+
db2.exec(CREATE_LONG_TERM_MEMORY_EVIDENCE_TABLE);
|
|
953
|
+
db2.exec(CREATE_LONG_TERM_MEMORY_EVENTS_TABLE);
|
|
954
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_long_term_memories_owner_state ON long_term_memories(ownerId, state, updatedAt DESC)");
|
|
955
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_long_term_memories_project_state ON long_term_memories(originProjectId, state, updatedAt DESC)");
|
|
956
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_long_term_memories_scope_portability ON long_term_memories(scope, portability, state, updatedAt DESC)");
|
|
957
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_long_term_memory_evidence_memory ON long_term_memory_evidence(memoryId, createdAt)");
|
|
958
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_long_term_memory_events_memory ON long_term_memory_events(memoryId, createdAt)");
|
|
959
|
+
}
|
|
891
960
|
}
|
|
892
961
|
];
|
|
893
962
|
_dbCache = /* @__PURE__ */ new Map();
|
|
@@ -3435,9 +3504,10 @@ function parseBatchLimit(error) {
|
|
|
3435
3504
|
}
|
|
3436
3505
|
return null;
|
|
3437
3506
|
}
|
|
3438
|
-
async function fetchWithRetry(url, apiKey, body, attempt = 0) {
|
|
3507
|
+
async function fetchWithRetry(url, apiKey, body, options = {}, attempt = 0) {
|
|
3439
3508
|
const controller = new AbortController();
|
|
3440
|
-
const
|
|
3509
|
+
const timeoutMs = typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs) ? Math.max(100, Math.min(Math.floor(options.timeoutMs), 6e4)) : 1e4;
|
|
3510
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
3441
3511
|
let response;
|
|
3442
3512
|
try {
|
|
3443
3513
|
response = await fetch(url, {
|
|
@@ -3452,7 +3522,7 @@ async function fetchWithRetry(url, apiKey, body, attempt = 0) {
|
|
|
3452
3522
|
} catch (err) {
|
|
3453
3523
|
clearTimeout(timeout);
|
|
3454
3524
|
if (err instanceof Error && err.name === "AbortError") {
|
|
3455
|
-
throw new Error(`Embedding API timeout after
|
|
3525
|
+
throw new Error(`Embedding API timeout after ${timeoutMs}ms: ${url}`);
|
|
3456
3526
|
}
|
|
3457
3527
|
throw err;
|
|
3458
3528
|
}
|
|
@@ -3460,13 +3530,13 @@ async function fetchWithRetry(url, apiKey, body, attempt = 0) {
|
|
|
3460
3530
|
if (response.ok) {
|
|
3461
3531
|
return response.json();
|
|
3462
3532
|
}
|
|
3463
|
-
if ((response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
|
|
3533
|
+
if (options.retry !== false && (response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
|
|
3464
3534
|
const delay = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
3465
3535
|
const retryAfter = response.headers.get("retry-after");
|
|
3466
3536
|
const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : delay;
|
|
3467
3537
|
console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES2} in ${waitMs}ms`);
|
|
3468
3538
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
3469
|
-
return fetchWithRetry(url, apiKey, body, attempt + 1);
|
|
3539
|
+
return fetchWithRetry(url, apiKey, body, options, attempt + 1);
|
|
3470
3540
|
}
|
|
3471
3541
|
const errorText2 = await response.text().catch(() => "unknown error");
|
|
3472
3542
|
throw new Error(`Embedding API error (${response.status}): ${errorText2}`);
|
|
@@ -3522,7 +3592,10 @@ var init_api_provider = __esm({
|
|
|
3522
3592
|
}
|
|
3523
3593
|
} else {
|
|
3524
3594
|
if (!allowNetworkProbe) return null;
|
|
3525
|
-
probeDimensions = await _APIEmbeddingProvider.probeAPI(config
|
|
3595
|
+
probeDimensions = await _APIEmbeddingProvider.probeAPI(config, {
|
|
3596
|
+
timeoutMs: options.requestTimeoutMs,
|
|
3597
|
+
retry: options.retry
|
|
3598
|
+
});
|
|
3526
3599
|
console.error(`[memorix] API embedding: ${config.model} @ ${config.baseUrl} (${probeDimensions}d)`);
|
|
3527
3600
|
saveCachedDims(config, probeDimensions).catch(() => {
|
|
3528
3601
|
});
|
|
@@ -3564,7 +3637,7 @@ var init_api_provider = __esm({
|
|
|
3564
3637
|
baseUrl = baseUrl.replace(/\/+$/, "");
|
|
3565
3638
|
return { apiKey, baseUrl, model, requestedDimensions };
|
|
3566
3639
|
}
|
|
3567
|
-
static async probeAPI(config) {
|
|
3640
|
+
static async probeAPI(config, options) {
|
|
3568
3641
|
const body = {
|
|
3569
3642
|
model: config.model,
|
|
3570
3643
|
input: "dimension probe"
|
|
@@ -3575,14 +3648,15 @@ var init_api_provider = __esm({
|
|
|
3575
3648
|
const response = await fetchWithRetry(
|
|
3576
3649
|
`${config.baseUrl}/embeddings`,
|
|
3577
3650
|
config.apiKey,
|
|
3578
|
-
body
|
|
3651
|
+
body,
|
|
3652
|
+
options
|
|
3579
3653
|
);
|
|
3580
3654
|
if (response.data.length === 0 || !response.data[0].embedding) {
|
|
3581
3655
|
throw new Error("API probe returned no embeddings; check model name and API key");
|
|
3582
3656
|
}
|
|
3583
3657
|
return response.data[0].embedding.length;
|
|
3584
3658
|
}
|
|
3585
|
-
async embed(text) {
|
|
3659
|
+
async embed(text, options) {
|
|
3586
3660
|
const normalized = normalizeText(text);
|
|
3587
3661
|
const hash4 = textHash2(normalized, this.cacheKeyNamespace);
|
|
3588
3662
|
if (diskCacheLoaded) {
|
|
@@ -3600,7 +3674,8 @@ var init_api_provider = __esm({
|
|
|
3600
3674
|
const response = await fetchWithRetry(
|
|
3601
3675
|
`${this.config.baseUrl}/embeddings`,
|
|
3602
3676
|
this.config.apiKey,
|
|
3603
|
-
body
|
|
3677
|
+
body,
|
|
3678
|
+
options
|
|
3604
3679
|
);
|
|
3605
3680
|
const embedding2 = response.data[0].embedding;
|
|
3606
3681
|
if (embedding2.length !== this.dimensions) {
|
|
@@ -3634,7 +3709,7 @@ var init_api_provider = __esm({
|
|
|
3634
3709
|
scheduleDiskSave();
|
|
3635
3710
|
return embedding;
|
|
3636
3711
|
}
|
|
3637
|
-
async embedBatch(texts) {
|
|
3712
|
+
async embedBatch(texts, options) {
|
|
3638
3713
|
await ensureDiskCacheLoaded();
|
|
3639
3714
|
const normalizedTexts = texts.map(normalizeText);
|
|
3640
3715
|
const results = new Array(texts.length);
|
|
@@ -3668,7 +3743,8 @@ var init_api_provider = __esm({
|
|
|
3668
3743
|
const response = await fetchWithRetry(
|
|
3669
3744
|
`${this.config.baseUrl}/embeddings`,
|
|
3670
3745
|
this.config.apiKey,
|
|
3671
|
-
body
|
|
3746
|
+
body,
|
|
3747
|
+
options
|
|
3672
3748
|
);
|
|
3673
3749
|
this.trackUsage(response);
|
|
3674
3750
|
for (const item of response.data) {
|
|
@@ -3845,9 +3921,9 @@ function wrapProvider(candidate) {
|
|
|
3845
3921
|
return {
|
|
3846
3922
|
name: candidate.name,
|
|
3847
3923
|
dimensions: candidate.dimensions,
|
|
3848
|
-
async embed(text) {
|
|
3924
|
+
async embed(text, options) {
|
|
3849
3925
|
try {
|
|
3850
|
-
return await candidate.embed(text);
|
|
3926
|
+
return await candidate.embed(text, options);
|
|
3851
3927
|
} catch (error) {
|
|
3852
3928
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
3853
3929
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -3855,7 +3931,7 @@ function wrapProvider(candidate) {
|
|
|
3855
3931
|
if (fallback) {
|
|
3856
3932
|
provider = wrapProvider(fallback);
|
|
3857
3933
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
3858
|
-
return provider.embed(text);
|
|
3934
|
+
return provider.embed(text, options);
|
|
3859
3935
|
}
|
|
3860
3936
|
}
|
|
3861
3937
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -3864,9 +3940,9 @@ function wrapProvider(candidate) {
|
|
|
3864
3940
|
throw error;
|
|
3865
3941
|
}
|
|
3866
3942
|
},
|
|
3867
|
-
async embedBatch(texts) {
|
|
3943
|
+
async embedBatch(texts, options) {
|
|
3868
3944
|
try {
|
|
3869
|
-
return await candidate.embedBatch(texts);
|
|
3945
|
+
return await candidate.embedBatch(texts, options);
|
|
3870
3946
|
} catch (error) {
|
|
3871
3947
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
3872
3948
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -3874,7 +3950,7 @@ function wrapProvider(candidate) {
|
|
|
3874
3950
|
if (fallback) {
|
|
3875
3951
|
provider = wrapProvider(fallback);
|
|
3876
3952
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
3877
|
-
return provider.embedBatch(texts);
|
|
3953
|
+
return provider.embedBatch(texts, options);
|
|
3878
3954
|
}
|
|
3879
3955
|
}
|
|
3880
3956
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -3930,14 +4006,14 @@ async function getEmbeddingProvider(options = {}) {
|
|
|
3930
4006
|
return provider;
|
|
3931
4007
|
}
|
|
3932
4008
|
if (mode === "api") {
|
|
3933
|
-
const initialized = await createAPIProvider();
|
|
4009
|
+
const initialized = await createAPIProvider(options);
|
|
3934
4010
|
if (!initialized) return null;
|
|
3935
4011
|
provider = wrapProvider(initialized);
|
|
3936
4012
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|
|
3937
4013
|
return provider;
|
|
3938
4014
|
}
|
|
3939
4015
|
if (hasAPIEmbeddingConfig()) {
|
|
3940
|
-
const initialized = await createAPIProvider();
|
|
4016
|
+
const initialized = await createAPIProvider(options);
|
|
3941
4017
|
if (initialized) {
|
|
3942
4018
|
provider = wrapProvider(initialized);
|
|
3943
4019
|
warnOnce(`[memorix] Embedding provider: ${provider.name} (${provider.dimensions}d)`);
|