memorix 1.5.0 → 1.6.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 +37 -0
- package/README.md +3 -3
- package/README.zh-CN.md +3 -3
- package/dist/cli/index.js +452 -109
- package/dist/index.js +376 -87
- package/dist/maintenance-runner.js +174 -41
- package/dist/media-audio-runner.js +174 -41
- package/dist/media-video-runner.js +174 -41
- package/dist/memcode-runtime/CHANGELOG.md +37 -0
- package/dist/sdk.js +375 -86
- package/dist/types.d.ts +2 -0
- package/dist/vector-backfill-runner.js +174 -41
- package/docs/1.2.4-PERSISTENT-MEMORY-DELIVERY.md +1 -1
- package/docs/API_REFERENCE.md +1 -1
- package/docs/DEVELOPMENT.md +5 -3
- 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/cli/commands/codegraph.ts +48 -5
- package/src/cli/commands/context.ts +20 -4
- package/src/cli/commands/resume.ts +4 -0
- package/src/codegraph/auto-context.ts +4 -1
- package/src/codegraph/context-pack.ts +3 -1
- package/src/codegraph/external-provider.ts +93 -0
- package/src/embedding/api-provider.ts +105 -22
- package/src/embedding/provider.ts +2 -0
- package/src/hooks/installers/index.ts +1 -1
- package/src/hooks/official-skills.ts +3 -3
- package/src/hooks/rules/memorix-agent-rules.md +1 -1
- package/src/knowledge/context-receipt.ts +41 -0
- package/src/knowledge/workflows.ts +6 -3
- package/src/knowledge/workset.ts +56 -2
- package/src/llm/provider.ts +17 -8
- 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/long-term.ts +7 -1
- package/src/server.ts +29 -13
- package/src/store/orama-store.ts +6 -4
- package/src/timeout.ts +67 -0
- package/src/types.ts +2 -0
|
@@ -2083,22 +2083,23 @@ function getLLMConfig() {
|
|
|
2083
2083
|
function setLLMConfig(config) {
|
|
2084
2084
|
currentConfig = config;
|
|
2085
2085
|
}
|
|
2086
|
-
async function callLLM(systemPrompt, userMessage) {
|
|
2086
|
+
async function callLLM(systemPrompt, userMessage, signal) {
|
|
2087
2087
|
if (!currentConfig) {
|
|
2088
2088
|
throw new Error("LLM not configured. Set MEMORIX_LLM_API_KEY or OPENAI_API_KEY.");
|
|
2089
2089
|
}
|
|
2090
2090
|
if (currentConfig.provider === "anthropic") {
|
|
2091
|
-
return callAnthropic(systemPrompt, userMessage);
|
|
2091
|
+
return callAnthropic(systemPrompt, userMessage, signal);
|
|
2092
2092
|
}
|
|
2093
|
-
return callOpenAICompatible(systemPrompt, userMessage);
|
|
2093
|
+
return callOpenAICompatible(systemPrompt, userMessage, signal);
|
|
2094
2094
|
}
|
|
2095
|
-
async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
2095
|
+
async function callOpenAICompatible(systemPrompt, userMessage, signal) {
|
|
2096
2096
|
const config = currentConfig;
|
|
2097
2097
|
let base = config.baseUrl.replace(/\/+$/, "");
|
|
2098
2098
|
if (!base.endsWith("/v1")) base += "/v1";
|
|
2099
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);
|
|
2100
2101
|
const response = await fetch(url, {
|
|
2101
|
-
signal:
|
|
2102
|
+
signal: fetchSignal,
|
|
2102
2103
|
method: "POST",
|
|
2103
2104
|
headers: {
|
|
2104
2105
|
"Content-Type": "application/json",
|
|
@@ -2115,10 +2116,10 @@ async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
|
2115
2116
|
})
|
|
2116
2117
|
});
|
|
2117
2118
|
if (!response.ok) {
|
|
2118
|
-
const error = await readResponseText(response,
|
|
2119
|
+
const error = await readResponseText(response, signal, 64 * 1024).catch(() => "unknown error");
|
|
2119
2120
|
throw new Error(`LLM API error (${response.status}): ${error}`);
|
|
2120
2121
|
}
|
|
2121
|
-
const data = await readResponseJson(response);
|
|
2122
|
+
const data = await readResponseJson(response, signal);
|
|
2122
2123
|
return {
|
|
2123
2124
|
content: data.choices[0]?.message?.content ?? "",
|
|
2124
2125
|
usage: data.usage ? {
|
|
@@ -2127,11 +2128,12 @@ async function callOpenAICompatible(systemPrompt, userMessage) {
|
|
|
2127
2128
|
} : void 0
|
|
2128
2129
|
};
|
|
2129
2130
|
}
|
|
2130
|
-
async function callAnthropic(systemPrompt, userMessage) {
|
|
2131
|
+
async function callAnthropic(systemPrompt, userMessage, signal) {
|
|
2131
2132
|
const config = currentConfig;
|
|
2132
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);
|
|
2133
2135
|
const response = await fetch(url, {
|
|
2134
|
-
signal:
|
|
2136
|
+
signal: fetchSignal,
|
|
2135
2137
|
method: "POST",
|
|
2136
2138
|
headers: {
|
|
2137
2139
|
"Content-Type": "application/json",
|
|
@@ -2149,10 +2151,10 @@ async function callAnthropic(systemPrompt, userMessage) {
|
|
|
2149
2151
|
})
|
|
2150
2152
|
});
|
|
2151
2153
|
if (!response.ok) {
|
|
2152
|
-
const error = await readResponseText(response,
|
|
2154
|
+
const error = await readResponseText(response, signal, 64 * 1024).catch(() => "unknown error");
|
|
2153
2155
|
throw new Error(`Anthropic API error (${response.status}): ${error}`);
|
|
2154
2156
|
}
|
|
2155
|
-
const data = await readResponseJson(response);
|
|
2157
|
+
const data = await readResponseJson(response, signal);
|
|
2156
2158
|
return {
|
|
2157
2159
|
content: data.content[0]?.text ?? "",
|
|
2158
2160
|
usage: data.usage ? {
|
|
@@ -3855,6 +3857,8 @@ function getPreferredBatchSize(config) {
|
|
|
3855
3857
|
}
|
|
3856
3858
|
function parseBatchLimit(error) {
|
|
3857
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;
|
|
3858
3862
|
const explicit = error.message.match(/should not be larger than\s+(\d+)/i);
|
|
3859
3863
|
if (explicit) return parseInt(explicit[1], 10);
|
|
3860
3864
|
if (/batch size/i.test(error.message)) {
|
|
@@ -3867,37 +3871,99 @@ async function fetchWithRetry(url, apiKey, body, options = {}, attempt = 0, nati
|
|
|
3867
3871
|
const controller = new AbortController();
|
|
3868
3872
|
const timeoutMs = typeof options.timeoutMs === "number" && Number.isFinite(options.timeoutMs) ? Math.max(100, Math.min(Math.floor(options.timeoutMs), 6e4)) : 1e4;
|
|
3869
3873
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
3874
|
+
const signal = options.signal ? AbortSignal.any([options.signal, controller.signal]) : controller.signal;
|
|
3870
3875
|
let response;
|
|
3871
3876
|
try {
|
|
3872
3877
|
response = await fetch(url, {
|
|
3873
3878
|
method: "POST",
|
|
3874
3879
|
headers: nativeGemini ? { "Content-Type": "application/json", "x-goog-api-key": apiKey } : { "Content-Type": "application/json", "Authorization": `Bearer ${apiKey}` },
|
|
3875
3880
|
body: JSON.stringify(body),
|
|
3876
|
-
signal
|
|
3881
|
+
signal
|
|
3877
3882
|
});
|
|
3878
3883
|
} catch (err) {
|
|
3879
3884
|
clearTimeout(timeout);
|
|
3880
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
3885
|
+
if (err instanceof Error && (err.name === "AbortError" || controller.signal.aborted || options.signal?.aborted)) {
|
|
3881
3886
|
throw new Error(`Embedding API timeout after ${timeoutMs}ms: ${url}`);
|
|
3882
3887
|
}
|
|
3883
3888
|
throw err;
|
|
3884
3889
|
}
|
|
3885
|
-
|
|
3886
|
-
|
|
3887
|
-
|
|
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);
|
|
3888
3918
|
}
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
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) {
|
|
3894
3947
|
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
3895
|
-
return
|
|
3948
|
+
return;
|
|
3896
3949
|
}
|
|
3897
|
-
const
|
|
3898
|
-
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
|
+
});
|
|
3899
3965
|
}
|
|
3900
|
-
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;
|
|
3901
3967
|
var init_api_provider = __esm({
|
|
3902
3968
|
"src/embedding/api-provider.ts"() {
|
|
3903
3969
|
"use strict";
|
|
@@ -3916,6 +3982,14 @@ var init_api_provider = __esm({
|
|
|
3916
3982
|
DASHSCOPE_MAX_BATCH_SIZE = 10;
|
|
3917
3983
|
MAX_RETRIES2 = 3;
|
|
3918
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
|
+
};
|
|
3919
3993
|
APIEmbeddingProvider = class _APIEmbeddingProvider {
|
|
3920
3994
|
name;
|
|
3921
3995
|
dimensions;
|
|
@@ -4127,15 +4201,14 @@ var init_api_provider = __esm({
|
|
|
4127
4201
|
}
|
|
4128
4202
|
} catch (error) {
|
|
4129
4203
|
const providerLimit = parseBatchLimit(error);
|
|
4130
|
-
|
|
4131
|
-
if (chunkTexts.length > 1 && fallbackSize < chunkTexts.length) {
|
|
4204
|
+
if (providerLimit !== null && chunkTexts.length > 1 && providerLimit < chunkTexts.length) {
|
|
4132
4205
|
console.error(
|
|
4133
|
-
`[memorix] Embedding batch too large for provider, retrying in chunks of ${
|
|
4206
|
+
`[memorix] Embedding batch too large for provider, retrying in chunks of ${providerLimit}`
|
|
4134
4207
|
);
|
|
4135
|
-
for (let start = 0; start < chunkTexts.length; start +=
|
|
4208
|
+
for (let start = 0; start < chunkTexts.length; start += providerLimit) {
|
|
4136
4209
|
await processChunk(
|
|
4137
|
-
chunkTexts.slice(start, start +
|
|
4138
|
-
chunkIndices.slice(start, start +
|
|
4210
|
+
chunkTexts.slice(start, start + providerLimit),
|
|
4211
|
+
chunkIndices.slice(start, start + providerLimit)
|
|
4139
4212
|
);
|
|
4140
4213
|
}
|
|
4141
4214
|
return;
|
|
@@ -4959,6 +5032,57 @@ function withTimeout(promise, ms, label) {
|
|
|
4959
5032
|
);
|
|
4960
5033
|
});
|
|
4961
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
|
+
}
|
|
4962
5086
|
var init_timeout = __esm({
|
|
4963
5087
|
"src/timeout.ts"() {
|
|
4964
5088
|
"use strict";
|
|
@@ -5823,16 +5947,18 @@ async function searchObservations(options) {
|
|
|
5823
5947
|
);
|
|
5824
5948
|
} else {
|
|
5825
5949
|
const EMBEDDING_TIMEOUT_MS = 15e3;
|
|
5826
|
-
queryVector = await
|
|
5827
|
-
provider2.embedInput ? provider2.embedInput(
|
|
5950
|
+
queryVector = await withTimeoutSignal(
|
|
5951
|
+
(signal) => provider2.embedInput ? provider2.embedInput(
|
|
5828
5952
|
{ modality: "text", text: expandedEmbeddingQuery },
|
|
5829
|
-
{ intent: "query", timeoutMs: EMBEDDING_TIMEOUT_MS, retry: false }
|
|
5953
|
+
{ intent: "query", timeoutMs: EMBEDDING_TIMEOUT_MS, retry: false, signal }
|
|
5830
5954
|
) : provider2.embed(expandedEmbeddingQuery, {
|
|
5831
5955
|
timeoutMs: EMBEDDING_TIMEOUT_MS,
|
|
5832
|
-
retry: false
|
|
5956
|
+
retry: false,
|
|
5957
|
+
signal
|
|
5833
5958
|
}),
|
|
5834
5959
|
EMBEDDING_TIMEOUT_MS,
|
|
5835
|
-
"Embedding"
|
|
5960
|
+
"Embedding",
|
|
5961
|
+
options.signal
|
|
5836
5962
|
);
|
|
5837
5963
|
mark("embedding");
|
|
5838
5964
|
const cjkRatio = (originalQuery.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length / originalQuery.length;
|
|
@@ -143295,7 +143421,13 @@ async function maintainLongTermMemories(input) {
|
|
|
143295
143421
|
}
|
|
143296
143422
|
for (const group of groups.values()) {
|
|
143297
143423
|
if (group.length < 2) continue;
|
|
143298
|
-
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
|
+
});
|
|
143299
143431
|
const newest = group[0];
|
|
143300
143432
|
for (const older of group.slice(1)) {
|
|
143301
143433
|
try {
|
|
@@ -146687,6 +146819,7 @@ var init_task_lens = __esm({
|
|
|
146687
146819
|
var workflows_exports = {};
|
|
146688
146820
|
__export(workflows_exports, {
|
|
146689
146821
|
WORKFLOW_ADAPTER_TARGETS: () => WORKFLOW_ADAPTER_TARGETS,
|
|
146822
|
+
WORKFLOW_AGENT_TARGETS: () => WORKFLOW_AGENT_TARGETS,
|
|
146690
146823
|
applyWorkflowAdapter: () => applyWorkflowAdapter,
|
|
146691
146824
|
importWindsurfWorkflows: () => importWindsurfWorkflows,
|
|
146692
146825
|
parseWorkflowMarkdown: () => parseWorkflowMarkdown,
|
|
@@ -146752,7 +146885,7 @@ function optionalStatus(data) {
|
|
|
146752
146885
|
return value;
|
|
146753
146886
|
}
|
|
146754
146887
|
function normalizeAgents(values) {
|
|
146755
|
-
const unknown3 = values.filter((value) => !
|
|
146888
|
+
const unknown3 = values.filter((value) => !WORKFLOW_AGENT_TARGETS.includes(value));
|
|
146756
146889
|
if (unknown3.length > 0) {
|
|
146757
146890
|
throw new Error("workflow frontmatter has unsupported agent: " + unknown3[0]);
|
|
146758
146891
|
}
|
|
@@ -147028,7 +147161,7 @@ function taskScore(workflow, task) {
|
|
|
147028
147161
|
return { score, reasons: [...new Set(reasons)] };
|
|
147029
147162
|
}
|
|
147030
147163
|
function selectWorkflows(input) {
|
|
147031
|
-
const selected = input.workflows.filter((workflow) => workflow.status === "active").map((workflow) => {
|
|
147164
|
+
const selected = input.workflows.filter((workflow) => workflow.status === "active" && (!input.agent || workflow.compatibleAgents.includes(input.agent))).map((workflow) => {
|
|
147032
147165
|
const match2 = taskScore(workflow, input.task);
|
|
147033
147166
|
const cautions = input.store && input.projectId ? input.store.recentFailureCautions(input.projectId, workflow.id) : [];
|
|
147034
147167
|
return {
|
|
@@ -147308,7 +147441,7 @@ async function selectWorkspaceWorkflows(input) {
|
|
|
147308
147441
|
errors: synced.errors
|
|
147309
147442
|
};
|
|
147310
147443
|
}
|
|
147311
|
-
var
|
|
147444
|
+
var WORKFLOW_AGENT_TARGETS, WORKFLOW_ADAPTER_TARGETS, STATUS_VALUES, LENS_TERMS, GENERIC_WORKFLOW_LENSES, GENERIC_WORKFLOW_TERMS;
|
|
147312
147445
|
var init_workflows2 = __esm({
|
|
147313
147446
|
"src/knowledge/workflows.ts"() {
|
|
147314
147447
|
"use strict";
|
|
@@ -147320,7 +147453,7 @@ var init_workflows2 = __esm({
|
|
|
147320
147453
|
init_workflow_store();
|
|
147321
147454
|
init_outcome_store();
|
|
147322
147455
|
init_task_lens();
|
|
147323
|
-
|
|
147456
|
+
WORKFLOW_AGENT_TARGETS = [
|
|
147324
147457
|
"windsurf",
|
|
147325
147458
|
"cursor",
|
|
147326
147459
|
"claude-code",
|