memorix 1.4.6 → 1.5.1
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 +38 -0
- package/TEAM.md +86 -86
- package/dist/cli/index.js +225 -70
- package/dist/cli/memcode.js +0 -0
- package/dist/index.js +225 -70
- package/dist/maintenance-runner.js +183 -38
- package/dist/media-audio-runner.js +183 -38
- package/dist/media-video-runner.js +183 -38
- package/dist/memcode-runtime/CHANGELOG.md +38 -0
- package/dist/sdk.js +224 -69
- package/dist/types.d.ts +2 -0
- package/dist/vector-backfill-runner.js +183 -38
- package/docs/CONFIGURATION.md +12 -0
- package/docs/DESIGN_DECISIONS.md +357 -357
- package/package.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/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/audit/index.ts +156 -156
- package/src/cli/commands/formation.ts +48 -48
- package/src/cli/commands/git-hook-install.ts +111 -111
- package/src/cli/commands/handoff.ts +54 -54
- package/src/cli/commands/hooks-status.ts +63 -63
- package/src/cli/commands/ingest.ts +44 -44
- package/src/cli/commands/integrate-shared.ts +15 -15
- package/src/cli/commands/lock.ts +82 -82
- package/src/cli/commands/message.ts +104 -104
- package/src/cli/commands/poll.ts +58 -58
- package/src/cli/commands/reasoning.ts +118 -118
- package/src/cli/commands/skills.ts +114 -114
- package/src/cli/commands/task.ts +167 -167
- package/src/cli/commands/transfer.ts +47 -47
- package/src/cli/index.ts +406 -406
- package/src/cli/tui/ChatView.tsx +234 -234
- package/src/cli/tui/CommandBar.tsx +312 -312
- package/src/cli/tui/ContextRail.tsx +118 -118
- package/src/cli/tui/HeaderBar.tsx +72 -72
- package/src/cli/tui/LogoBanner.tsx +51 -51
- package/src/cli/tui/index.ts +41 -41
- package/src/cli/version.ts +7 -7
- package/src/cli/workbench.ts +1 -1
- package/src/config.ts +23 -2
- package/src/dashboard/project-classification.ts +64 -64
- package/src/embedding/api-provider.ts +105 -22
- package/src/embedding/provider.ts +2 -0
- package/src/git/hooks-path.ts +85 -85
- package/src/hooks/pattern-detector.ts +173 -173
- package/src/hooks/significance-filter.ts +250 -250
- package/src/llm/memory-manager.ts +328 -328
- package/src/llm/provider.ts +17 -8
- package/src/llm/quality.ts +248 -248
- package/src/memory/attribution-guard.ts +249 -249
- package/src/memory/disclosure-policy.ts +135 -135
- package/src/memory/entity-extractor.ts +197 -197
- package/src/memory/formation/evaluate.ts +217 -217
- package/src/memory/formation/extract.ts +6 -3
- package/src/memory/formation/index.ts +2 -1
- package/src/memory/formation/resolve.ts +10 -6
- package/src/memory/formation/types.ts +3 -1
- package/src/memory/freshness.ts +122 -122
- package/src/memory/graph.ts +197 -197
- package/src/memory/long-term.ts +7 -1
- package/src/memory/refs.ts +94 -94
- package/src/memory/secret-filter.ts +79 -79
- package/src/orchestrate/adapters/claude-stream.ts +192 -192
- package/src/orchestrate/adapters/claude.ts +111 -111
- package/src/orchestrate/adapters/codex-stream.ts +134 -134
- package/src/orchestrate/adapters/codex.ts +41 -41
- package/src/orchestrate/adapters/gemini-stream.ts +166 -166
- package/src/orchestrate/adapters/gemini.ts +42 -42
- package/src/orchestrate/adapters/index.ts +73 -73
- package/src/orchestrate/adapters/opencode-stream.ts +143 -143
- package/src/orchestrate/adapters/opencode.ts +47 -47
- package/src/orchestrate/adapters/types.ts +77 -77
- package/src/orchestrate/capability-router.ts +284 -284
- package/src/orchestrate/cost-tracker.ts +219 -219
- package/src/orchestrate/error-recovery.ts +191 -191
- package/src/orchestrate/evidence.ts +140 -140
- package/src/orchestrate/ledger.ts +110 -110
- package/src/orchestrate/memorix-bridge.ts +343 -343
- package/src/orchestrate/output-budget.ts +80 -80
- package/src/orchestrate/permission.ts +152 -152
- package/src/orchestrate/pipeline-trace.ts +131 -131
- package/src/orchestrate/prompt-builder.ts +155 -155
- package/src/orchestrate/ring-buffer.ts +37 -37
- package/src/orchestrate/task-graph.ts +389 -389
- package/src/project/aliases.ts +374 -374
- package/src/rules/adapters/trae.ts +56 -56
- package/src/rules/syncer.ts +235 -235
- package/src/search/query-expansion.ts +52 -52
- package/src/server/formation-timeout.ts +27 -27
- package/src/server.ts +14 -10
- package/src/skills/mini-skills.ts +386 -386
- package/src/store/chat-store.ts +119 -119
- package/src/store/graph-store.ts +249 -249
- package/src/store/mini-skill-store.ts +349 -349
- package/src/store/orama-store.ts +6 -4
- package/src/store/persistence-json.ts +212 -212
- package/src/store/persistence.ts +291 -291
- package/src/store/project-affinity.ts +195 -195
- package/src/team/event-bus.ts +76 -76
- package/src/team/handoff.ts +161 -161
- package/src/team/poll.ts +132 -132
- package/src/timeout.ts +67 -0
- package/src/types.ts +2 -0
- package/src/workspace/mcp-adapters/codex.ts +191 -191
- package/src/workspace/mcp-adapters/copilot.ts +105 -105
- package/src/workspace/mcp-adapters/cursor.ts +53 -53
- package/src/workspace/mcp-adapters/kiro.ts +64 -64
- package/src/workspace/mcp-adapters/opencode.ts +123 -123
- package/src/workspace/mcp-adapters/trae.ts +134 -134
- package/src/workspace/mcp-adapters/windsurf.ts +91 -91
- package/src/workspace/sanitizer.ts +60 -60
|
@@ -1868,6 +1868,7 @@ var init_resolved_config = __esm({
|
|
|
1868
1868
|
// src/config.ts
|
|
1869
1869
|
var config_exports = {};
|
|
1870
1870
|
__export(config_exports, {
|
|
1871
|
+
defaultEmbeddingModelFor: () => defaultEmbeddingModelFor,
|
|
1871
1872
|
getAgentLLMApiKey: () => getAgentLLMApiKey,
|
|
1872
1873
|
getAgentLLMBaseUrl: () => getAgentLLMBaseUrl,
|
|
1873
1874
|
getAgentLLMModel: () => getAgentLLMModel,
|
|
@@ -1930,7 +1931,19 @@ function getEmbeddingBaseUrl() {
|
|
|
1930
1931
|
return getResolvedEmbeddingLane().baseUrl || "https://api.openai.com/v1";
|
|
1931
1932
|
}
|
|
1932
1933
|
function getEmbeddingModel() {
|
|
1933
|
-
|
|
1934
|
+
const lane = getResolvedEmbeddingLane();
|
|
1935
|
+
return defaultEmbeddingModelFor(lane.baseUrl, lane.model);
|
|
1936
|
+
}
|
|
1937
|
+
function defaultEmbeddingModelFor(baseUrl, explicitModel) {
|
|
1938
|
+
if (explicitModel) return explicitModel;
|
|
1939
|
+
try {
|
|
1940
|
+
const url = baseUrl ? new URL(baseUrl) : null;
|
|
1941
|
+
if (url && (url.hostname === "openrouter.ai" || url.hostname.endsWith(".openrouter.ai"))) {
|
|
1942
|
+
return "qwen/qwen3-embedding-8b";
|
|
1943
|
+
}
|
|
1944
|
+
} catch {
|
|
1945
|
+
}
|
|
1946
|
+
return "text-embedding-3-small";
|
|
1934
1947
|
}
|
|
1935
1948
|
function getEmbeddingDimensions() {
|
|
1936
1949
|
return getResolvedEmbeddingLane().dimensions ?? null;
|
|
@@ -2070,22 +2083,23 @@ function getLLMConfig() {
|
|
|
2070
2083
|
function setLLMConfig(config) {
|
|
2071
2084
|
currentConfig = config;
|
|
2072
2085
|
}
|
|
2073
|
-
async function callLLM(systemPrompt, userMessage) {
|
|
2086
|
+
async function callLLM(systemPrompt, userMessage, signal) {
|
|
2074
2087
|
if (!currentConfig) {
|
|
2075
2088
|
throw new Error("LLM not configured. Set MEMORIX_LLM_API_KEY or OPENAI_API_KEY.");
|
|
2076
2089
|
}
|
|
2077
2090
|
if (currentConfig.provider === "anthropic") {
|
|
2078
|
-
return callAnthropic(systemPrompt, userMessage);
|
|
2091
|
+
return callAnthropic(systemPrompt, userMessage, signal);
|
|
2079
2092
|
}
|
|
2080
|
-
return callOpenAICompatible(systemPrompt, userMessage);
|
|
2093
|
+
return callOpenAICompatible(systemPrompt, userMessage, signal);
|
|
2081
2094
|
}
|
|
2082
|
-
async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
2095
|
+
async function callOpenAICompatible(systemPrompt, userMessage, signal) {
|
|
2083
2096
|
const config = currentConfig;
|
|
2084
2097
|
let base = config.baseUrl.replace(/\/+$/, "");
|
|
2085
2098
|
if (!base.endsWith("/v1")) base += "/v1";
|
|
2086
2099
|
const url = `${base}/chat/completions`;
|
|
2100
|
+
const fetchSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(LLM_CALL_TIMEOUT_MS)]) : AbortSignal.timeout(LLM_CALL_TIMEOUT_MS);
|
|
2087
2101
|
const response = await fetch(url, {
|
|
2088
|
-
signal:
|
|
2102
|
+
signal: fetchSignal,
|
|
2089
2103
|
method: "POST",
|
|
2090
2104
|
headers: {
|
|
2091
2105
|
"Content-Type": "application/json",
|
|
@@ -2102,10 +2116,10 @@ async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
|
2102
2116
|
})
|
|
2103
2117
|
});
|
|
2104
2118
|
if (!response.ok) {
|
|
2105
|
-
const error = await readResponseText(response,
|
|
2119
|
+
const error = await readResponseText(response, signal, 64 * 1024).catch(() => "unknown error");
|
|
2106
2120
|
throw new Error(`LLM API error (${response.status}): ${error}`);
|
|
2107
2121
|
}
|
|
2108
|
-
const data = await readResponseJson(response);
|
|
2122
|
+
const data = await readResponseJson(response, signal);
|
|
2109
2123
|
return {
|
|
2110
2124
|
content: data.choices[0]?.message?.content ?? "",
|
|
2111
2125
|
usage: data.usage ? {
|
|
@@ -2114,11 +2128,12 @@ async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
|
2114
2128
|
} : void 0
|
|
2115
2129
|
};
|
|
2116
2130
|
}
|
|
2117
|
-
async function callAnthropic(systemPrompt, userMessage) {
|
|
2131
|
+
async function callAnthropic(systemPrompt, userMessage, signal) {
|
|
2118
2132
|
const config = currentConfig;
|
|
2119
2133
|
const url = `${config.baseUrl}/messages`;
|
|
2134
|
+
const fetchSignal = signal ? AbortSignal.any([signal, AbortSignal.timeout(LLM_CALL_TIMEOUT_MS)]) : AbortSignal.timeout(LLM_CALL_TIMEOUT_MS);
|
|
2120
2135
|
const response = await fetch(url, {
|
|
2121
|
-
signal:
|
|
2136
|
+
signal: fetchSignal,
|
|
2122
2137
|
method: "POST",
|
|
2123
2138
|
headers: {
|
|
2124
2139
|
"Content-Type": "application/json",
|
|
@@ -2136,10 +2151,10 @@ async function callAnthropic(systemPrompt, userMessage) {
|
|
|
2136
2151
|
})
|
|
2137
2152
|
});
|
|
2138
2153
|
if (!response.ok) {
|
|
2139
|
-
const error = await readResponseText(response,
|
|
2154
|
+
const error = await readResponseText(response, signal, 64 * 1024).catch(() => "unknown error");
|
|
2140
2155
|
throw new Error(`Anthropic API error (${response.status}): ${error}`);
|
|
2141
2156
|
}
|
|
2142
|
-
const data = await readResponseJson(response);
|
|
2157
|
+
const data = await readResponseJson(response, signal);
|
|
2143
2158
|
return {
|
|
2144
2159
|
content: data.content[0]?.text ?? "",
|
|
2145
2160
|
usage: data.usage ? {
|
|
@@ -3842,6 +3857,8 @@ function getPreferredBatchSize(config) {
|
|
|
3842
3857
|
}
|
|
3843
3858
|
function parseBatchLimit(error) {
|
|
3844
3859
|
if (!(error instanceof Error)) return null;
|
|
3860
|
+
const status = error instanceof EmbeddingAPIError ? error.status : Number(error.message.match(/Embedding API error \((\d{3})\)/i)?.[1] ?? 0);
|
|
3861
|
+
if (status > 0 && status !== 400) return null;
|
|
3845
3862
|
const explicit = error.message.match(/should not be larger than\s+(\d+)/i);
|
|
3846
3863
|
if (explicit) return parseInt(explicit[1], 10);
|
|
3847
3864
|
if (/batch size/i.test(error.message)) {
|
|
@@ -3854,37 +3871,99 @@ async function fetchWithRetry(url, apiKey, body, options = {}, attempt = 0, nati
|
|
|
3854
3871
|
const controller = new AbortController();
|
|
3855
3872
|
const timeoutMs = typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs) ? Math.max(100, Math.min(Math.floor(options.timeoutMs), 6e4)) : 1e4;
|
|
3856
3873
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
3874
|
+
const signal = options.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;
|
|
3857
3875
|
let response;
|
|
3858
3876
|
try {
|
|
3859
3877
|
response = await fetch(url, {
|
|
3860
3878
|
method: "POST",
|
|
3861
3879
|
headers: nativeGemini ? { "Content-Type": "application/json", "x-goog-api-key": apiKey } : { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}` },
|
|
3862
3880
|
body: JSON.stringify(body),
|
|
3863
|
-
signal
|
|
3881
|
+
signal
|
|
3864
3882
|
});
|
|
3865
3883
|
} catch (err) {
|
|
3866
3884
|
clearTimeout(timeout);
|
|
3867
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
3885
|
+
if (err instanceof Error && (err.name === "AbortError" || controller.signal.aborted || options.signal?.aborted)) {
|
|
3868
3886
|
throw new Error(`Embedding API timeout after ${timeoutMs}ms: ${url}`);
|
|
3869
3887
|
}
|
|
3870
3888
|
throw err;
|
|
3871
3889
|
}
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3890
|
+
try {
|
|
3891
|
+
if (response.ok) {
|
|
3892
|
+
return await raceWithAbort(
|
|
3893
|
+
response.json(),
|
|
3894
|
+
signal
|
|
3895
|
+
);
|
|
3896
|
+
}
|
|
3897
|
+
if (options.retry !== false && (response.status === 429 || response.status >= 500) && attempt < MAX_RETRIES2) {
|
|
3898
|
+
const delay2 = BASE_DELAY_MS * Math.pow(2, attempt);
|
|
3899
|
+
const retryAfter = response.headers.get("retry-after");
|
|
3900
|
+
const parsedRetryAfter = retryAfter ? parseInt(retryAfter, 10) * 1e3 : NaN;
|
|
3901
|
+
const waitMs = Number.isFinite(parsedRetryAfter) ? parsedRetryAfter : delay2;
|
|
3902
|
+
console.error(`[memorix] Embedding API ${response.status}, retry ${attempt + 1}/${MAX_RETRIES2} in ${waitMs}ms`);
|
|
3903
|
+
await waitForRetry(waitMs, options.signal);
|
|
3904
|
+
return fetchWithRetry(url, apiKey, body, options, attempt + 1, nativeGemini);
|
|
3905
|
+
}
|
|
3906
|
+
const errorText2 = await raceWithAbort(
|
|
3907
|
+
response.text().catch(() => "unknown error"),
|
|
3908
|
+
signal
|
|
3909
|
+
);
|
|
3910
|
+
throw new EmbeddingAPIError(response.status, errorText2);
|
|
3911
|
+
} catch (err) {
|
|
3912
|
+
if (err instanceof Error && (err.name === "AbortError" || controller.signal.aborted || options.signal?.aborted)) {
|
|
3913
|
+
throw new Error(`Embedding API timeout after ${timeoutMs}ms: ${url}`);
|
|
3914
|
+
}
|
|
3915
|
+
throw err;
|
|
3916
|
+
} finally {
|
|
3917
|
+
clearTimeout(timeout);
|
|
3875
3918
|
}
|
|
3876
|
-
|
|
3877
|
-
|
|
3878
|
-
|
|
3879
|
-
|
|
3880
|
-
|
|
3919
|
+
}
|
|
3920
|
+
function abortError() {
|
|
3921
|
+
const error = new Error("Embedding API request aborted");
|
|
3922
|
+
error.name = "AbortError";
|
|
3923
|
+
return error;
|
|
3924
|
+
}
|
|
3925
|
+
function raceWithAbort(promise, signal) {
|
|
3926
|
+
if (signal.aborted) return Promise.reject(abortError());
|
|
3927
|
+
return new Promise((resolve, reject) => {
|
|
3928
|
+
const onAbort = () => {
|
|
3929
|
+
signal.removeEventListener("abort", onAbort);
|
|
3930
|
+
reject(abortError());
|
|
3931
|
+
};
|
|
3932
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3933
|
+
promise.then(
|
|
3934
|
+
(value) => {
|
|
3935
|
+
signal.removeEventListener("abort", onAbort);
|
|
3936
|
+
resolve(value);
|
|
3937
|
+
},
|
|
3938
|
+
(error) => {
|
|
3939
|
+
signal.removeEventListener("abort", onAbort);
|
|
3940
|
+
reject(error);
|
|
3941
|
+
}
|
|
3942
|
+
);
|
|
3943
|
+
});
|
|
3944
|
+
}
|
|
3945
|
+
async function waitForRetry(waitMs, signal) {
|
|
3946
|
+
if (!signal) {
|
|
3881
3947
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
3882
|
-
return
|
|
3948
|
+
return;
|
|
3883
3949
|
}
|
|
3884
|
-
const
|
|
3885
|
-
throw new Error(
|
|
3950
|
+
const abortSignal = signal;
|
|
3951
|
+
if (abortSignal.aborted) throw new Error("Embedding API retry aborted");
|
|
3952
|
+
await new Promise((resolve, reject) => {
|
|
3953
|
+
const timer = setTimeout(done, waitMs);
|
|
3954
|
+
const onAbort = () => {
|
|
3955
|
+
clearTimeout(timer);
|
|
3956
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
3957
|
+
reject(new Error("Embedding API retry aborted"));
|
|
3958
|
+
};
|
|
3959
|
+
function done() {
|
|
3960
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
3961
|
+
resolve();
|
|
3962
|
+
}
|
|
3963
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
3964
|
+
});
|
|
3886
3965
|
}
|
|
3887
|
-
var cache3, MAX_CACHE_SIZE3, diskCacheDirty2, diskSaveTimer, diskCacheLoaded, diskCacheLoadPromise, MAX_INPUT_CHARS, MAX_CONCURRENCY, DISK_SAVE_DEBOUNCE_MS, DEFAULT_MAX_BATCH_SIZE, DASHSCOPE_MAX_BATCH_SIZE, MAX_RETRIES2, BASE_DELAY_MS, APIEmbeddingProvider;
|
|
3966
|
+
var cache3, MAX_CACHE_SIZE3, diskCacheDirty2, diskSaveTimer, diskCacheLoaded, diskCacheLoadPromise, MAX_INPUT_CHARS, MAX_CONCURRENCY, DISK_SAVE_DEBOUNCE_MS, DEFAULT_MAX_BATCH_SIZE, DASHSCOPE_MAX_BATCH_SIZE, MAX_RETRIES2, BASE_DELAY_MS, EmbeddingAPIError, APIEmbeddingProvider;
|
|
3888
3967
|
var init_api_provider = __esm({
|
|
3889
3968
|
"src/embedding/api-provider.ts"() {
|
|
3890
3969
|
"use strict";
|
|
@@ -3903,6 +3982,14 @@ var init_api_provider = __esm({
|
|
|
3903
3982
|
DASHSCOPE_MAX_BATCH_SIZE = 10;
|
|
3904
3983
|
MAX_RETRIES2 = 3;
|
|
3905
3984
|
BASE_DELAY_MS = 500;
|
|
3985
|
+
EmbeddingAPIError = class extends Error {
|
|
3986
|
+
status;
|
|
3987
|
+
constructor(status, detail) {
|
|
3988
|
+
super(`Embedding API error (${status}): ${detail}`);
|
|
3989
|
+
this.name = "EmbeddingAPIError";
|
|
3990
|
+
this.status = status;
|
|
3991
|
+
}
|
|
3992
|
+
};
|
|
3906
3993
|
APIEmbeddingProvider = class _APIEmbeddingProvider {
|
|
3907
3994
|
name;
|
|
3908
3995
|
dimensions;
|
|
@@ -4114,15 +4201,14 @@ var init_api_provider = __esm({
|
|
|
4114
4201
|
}
|
|
4115
4202
|
} catch (error) {
|
|
4116
4203
|
const providerLimit = parseBatchLimit(error);
|
|
4117
|
-
|
|
4118
|
-
if (chunkTexts.length > 1 && fallbackSize < chunkTexts.length) {
|
|
4204
|
+
if (providerLimit !== null && chunkTexts.length > 1 && providerLimit < chunkTexts.length) {
|
|
4119
4205
|
console.error(
|
|
4120
|
-
`[memorix] Embedding batch too large for provider, retrying in chunks of ${
|
|
4206
|
+
`[memorix] Embedding batch too large for provider, retrying in chunks of ${providerLimit}`
|
|
4121
4207
|
);
|
|
4122
|
-
for (let start = 0; start < chunkTexts.length; start +=
|
|
4208
|
+
for (let start = 0; start < chunkTexts.length; start += providerLimit) {
|
|
4123
4209
|
await processChunk(
|
|
4124
|
-
chunkTexts.slice(start, start +
|
|
4125
|
-
chunkIndices.slice(start, start +
|
|
4210
|
+
chunkTexts.slice(start, start + providerLimit),
|
|
4211
|
+
chunkIndices.slice(start, start + providerLimit)
|
|
4126
4212
|
);
|
|
4127
4213
|
}
|
|
4128
4214
|
return;
|
|
@@ -4946,6 +5032,57 @@ function withTimeout(promise, ms, label) {
|
|
|
4946
5032
|
);
|
|
4947
5033
|
});
|
|
4948
5034
|
}
|
|
5035
|
+
function withTimeoutSignal(operation, ms, label, parentSignal) {
|
|
5036
|
+
const controller = new AbortController();
|
|
5037
|
+
const signal = parentSignal ? AbortSignal.any([parentSignal, controller.signal]) : controller.signal;
|
|
5038
|
+
return new Promise((resolve, reject) => {
|
|
5039
|
+
let settled = false;
|
|
5040
|
+
let timedOut = false;
|
|
5041
|
+
let timer;
|
|
5042
|
+
const cleanup = () => {
|
|
5043
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
5044
|
+
parentSignal?.removeEventListener("abort", onParentAbort);
|
|
5045
|
+
};
|
|
5046
|
+
const onParentAbort = () => {
|
|
5047
|
+
if (settled || timedOut) return;
|
|
5048
|
+
settled = true;
|
|
5049
|
+
cleanup();
|
|
5050
|
+
reject(parentSignal?.reason ?? new Error(`${label} aborted`));
|
|
5051
|
+
};
|
|
5052
|
+
parentSignal?.addEventListener("abort", onParentAbort, { once: true });
|
|
5053
|
+
timer = setTimeout(() => {
|
|
5054
|
+
if (settled) return;
|
|
5055
|
+
timedOut = true;
|
|
5056
|
+
controller.abort(new Error(`${label} timed out after ${ms}ms`));
|
|
5057
|
+
settled = true;
|
|
5058
|
+
cleanup();
|
|
5059
|
+
reject(new Error(`${label} timed out after ${ms}ms`));
|
|
5060
|
+
}, ms);
|
|
5061
|
+
let pending;
|
|
5062
|
+
try {
|
|
5063
|
+
pending = operation(signal);
|
|
5064
|
+
} catch (error) {
|
|
5065
|
+
settled = true;
|
|
5066
|
+
cleanup();
|
|
5067
|
+
reject(error);
|
|
5068
|
+
return;
|
|
5069
|
+
}
|
|
5070
|
+
pending.then(
|
|
5071
|
+
(value) => {
|
|
5072
|
+
if (settled) return;
|
|
5073
|
+
settled = true;
|
|
5074
|
+
cleanup();
|
|
5075
|
+
resolve(value);
|
|
5076
|
+
},
|
|
5077
|
+
(error) => {
|
|
5078
|
+
if (settled) return;
|
|
5079
|
+
settled = true;
|
|
5080
|
+
cleanup();
|
|
5081
|
+
reject(timedOut ? new Error(`${label} timed out after ${ms}ms`) : error);
|
|
5082
|
+
}
|
|
5083
|
+
);
|
|
5084
|
+
});
|
|
5085
|
+
}
|
|
4949
5086
|
var init_timeout = __esm({
|
|
4950
5087
|
"src/timeout.ts"() {
|
|
4951
5088
|
"use strict";
|
|
@@ -5810,16 +5947,18 @@ async function searchObservations(options) {
|
|
|
5810
5947
|
);
|
|
5811
5948
|
} else {
|
|
5812
5949
|
const EMBEDDING_TIMEOUT_MS = 15e3;
|
|
5813
|
-
queryVector = await
|
|
5814
|
-
provider2.embedInput ? provider2.embedInput(
|
|
5950
|
+
queryVector = await withTimeoutSignal(
|
|
5951
|
+
(signal) => provider2.embedInput ? provider2.embedInput(
|
|
5815
5952
|
{ modality: "text", text: expandedEmbeddingQuery },
|
|
5816
|
-
{ intent: "query", timeoutMs: EMBEDDING_TIMEOUT_MS, retry: false }
|
|
5953
|
+
{ intent: "query", timeoutMs: EMBEDDING_TIMEOUT_MS, retry: false, signal }
|
|
5817
5954
|
) : provider2.embed(expandedEmbeddingQuery, {
|
|
5818
5955
|
timeoutMs: EMBEDDING_TIMEOUT_MS,
|
|
5819
|
-
retry: false
|
|
5956
|
+
retry: false,
|
|
5957
|
+
signal
|
|
5820
5958
|
}),
|
|
5821
5959
|
EMBEDDING_TIMEOUT_MS,
|
|
5822
|
-
"Embedding"
|
|
5960
|
+
"Embedding",
|
|
5961
|
+
options.signal
|
|
5823
5962
|
);
|
|
5824
5963
|
mark("embedding");
|
|
5825
5964
|
const cjkRatio = (originalQuery.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length / originalQuery.length;
|
|
@@ -143282,7 +143421,13 @@ async function maintainLongTermMemories(input) {
|
|
|
143282
143421
|
}
|
|
143283
143422
|
for (const group of groups.values()) {
|
|
143284
143423
|
if (group.length < 2) continue;
|
|
143285
|
-
group.sort((a, b) =>
|
|
143424
|
+
group.sort((a, b) => {
|
|
143425
|
+
const byCreatedAt = Date.parse(b.createdAt) - Date.parse(a.createdAt);
|
|
143426
|
+
if (byCreatedAt !== 0) return byCreatedAt;
|
|
143427
|
+
const byUpdatedAt = Date.parse(b.updatedAt) - Date.parse(a.updatedAt);
|
|
143428
|
+
if (byUpdatedAt !== 0) return byUpdatedAt;
|
|
143429
|
+
return b.id.localeCompare(a.id);
|
|
143430
|
+
});
|
|
143286
143431
|
const newest = group[0];
|
|
143287
143432
|
for (const older of group.slice(1)) {
|
|
143288
143433
|
try {
|