memorix 1.4.0 → 1.4.2
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 +31 -0
- package/CLAUDE.md +9 -9
- package/README.md +7 -2
- package/README.zh-CN.md +6 -2
- package/dist/cli/index.js +1216 -485
- package/dist/index.js +984 -337
- package/dist/maintenance-runner.js +564 -180
- package/dist/media-video-runner.js +564 -180
- package/dist/memcode/index.js +53 -21
- package/dist/memcode-runtime/CHANGELOG.md +31 -0
- package/dist/sdk.js +983 -336
- package/dist/vector-backfill-runner.js +564 -180
- package/docs/1.4.2-EVIDENCE-GOVERNED-MEMORY-SPEC.md +434 -0
- package/docs/API_REFERENCE.md +1 -1
- package/docs/KNOWN_ISSUES_AND_ROADMAP.md +52 -128
- package/package.json +5 -2
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/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 +83 -2
- package/src/codegraph/auto-context.ts +20 -0
- package/src/codegraph/current-facts.ts +1 -0
- package/src/codegraph/external-provider.ts +1 -0
- package/src/codegraph/store.ts +216 -5
- package/src/codegraph/types.ts +42 -0
- package/src/knowledge/context-assembly.ts +25 -0
- package/src/knowledge/governor.ts +156 -0
- package/src/knowledge/outcome-store.ts +102 -0
- package/src/knowledge/outcome-types.ts +49 -0
- package/src/knowledge/workflows.ts +32 -1
- package/src/knowledge/workset.ts +203 -13
- package/src/store/sqlite-db.ts +42 -0
- package/docs/dev-log/progress.txt +0 -388
|
@@ -495,7 +495,7 @@ function closeAllDatabases() {
|
|
|
495
495
|
_dbCache.delete(key);
|
|
496
496
|
}
|
|
497
497
|
}
|
|
498
|
-
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_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
498
|
+
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_CODE_STATE_SNAPSHOT_FILES_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_MEMORY_OUTCOME_SIGNALS_TABLE, CREATE_MEDIA_ASSETS_TABLE, CREATE_MEDIA_ASSET_LINKS_TABLE, CREATE_MEDIA_DERIVATIONS_TABLE, CREATE_MEDIA_EMBEDDING_PROFILES_TABLE, CREATE_MEDIA_EMBEDDINGS_TABLE, CREATE_MEDIA_JOBS_TABLE, CREATE_MAINTENANCE_JOBS_TABLE, CREATE_MAINTENANCE_TARGETS_TABLE, CREATE_COMPACTION_CHECKPOINTS_TABLE, CREATE_INDEXES, SCHEMA_MIGRATIONS, _dbCache;
|
|
499
499
|
var init_sqlite_db = __esm({
|
|
500
500
|
"src/store/sqlite-db.ts"() {
|
|
501
501
|
"use strict";
|
|
@@ -761,6 +761,17 @@ CREATE TABLE IF NOT EXISTS observation_code_refs (
|
|
|
761
761
|
" UNIQUE(projectId, sourceEpoch)",
|
|
762
762
|
");"
|
|
763
763
|
].join("\n");
|
|
764
|
+
CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE = [
|
|
765
|
+
"CREATE TABLE IF NOT EXISTS code_state_snapshot_files (",
|
|
766
|
+
" snapshotId TEXT NOT NULL,",
|
|
767
|
+
" projectId TEXT NOT NULL,",
|
|
768
|
+
" fileId TEXT NOT NULL,",
|
|
769
|
+
" path TEXT NOT NULL,",
|
|
770
|
+
" contentHash TEXT NOT NULL,",
|
|
771
|
+
" PRIMARY KEY (snapshotId, path),",
|
|
772
|
+
" FOREIGN KEY (snapshotId) REFERENCES code_state_snapshots(id) ON DELETE CASCADE",
|
|
773
|
+
");"
|
|
774
|
+
].join("\n");
|
|
764
775
|
CREATE_KNOWLEDGE_CLAIMS_TABLE = `
|
|
765
776
|
CREATE TABLE IF NOT EXISTS knowledge_claims (
|
|
766
777
|
id TEXT PRIMARY KEY,
|
|
@@ -971,6 +982,19 @@ CREATE TABLE IF NOT EXISTS long_term_memory_events (
|
|
|
971
982
|
createdAt TEXT NOT NULL,
|
|
972
983
|
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
973
984
|
);
|
|
985
|
+
`;
|
|
986
|
+
CREATE_MEMORY_OUTCOME_SIGNALS_TABLE = `
|
|
987
|
+
CREATE TABLE IF NOT EXISTS memory_outcome_signals (
|
|
988
|
+
id TEXT PRIMARY KEY,
|
|
989
|
+
projectId TEXT NOT NULL,
|
|
990
|
+
candidateKind TEXT NOT NULL,
|
|
991
|
+
candidateId TEXT NOT NULL,
|
|
992
|
+
kind TEXT NOT NULL,
|
|
993
|
+
sourceRef TEXT NOT NULL,
|
|
994
|
+
snapshotId TEXT,
|
|
995
|
+
detail TEXT,
|
|
996
|
+
observedAt TEXT NOT NULL
|
|
997
|
+
);
|
|
974
998
|
`;
|
|
975
999
|
CREATE_MEDIA_ASSETS_TABLE = `
|
|
976
1000
|
CREATE TABLE IF NOT EXISTS media_assets (
|
|
@@ -1213,6 +1237,20 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1213
1237
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_edges_snapshot ON code_edges(projectId, snapshotId)");
|
|
1214
1238
|
}
|
|
1215
1239
|
},
|
|
1240
|
+
{
|
|
1241
|
+
id: "1.4-codegraph-snapshot-manifest",
|
|
1242
|
+
apply: (db2) => {
|
|
1243
|
+
db2.exec(CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE);
|
|
1244
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_snapshot_files_project_path ON code_state_snapshot_files(projectId, path)");
|
|
1245
|
+
}
|
|
1246
|
+
},
|
|
1247
|
+
{
|
|
1248
|
+
id: "1.4-memory-outcome-signals",
|
|
1249
|
+
apply: (db2) => {
|
|
1250
|
+
db2.exec(CREATE_MEMORY_OUTCOME_SIGNALS_TABLE);
|
|
1251
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_outcomes_candidate ON memory_outcome_signals(projectId, candidateKind, candidateId, observedAt DESC)");
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1216
1254
|
{
|
|
1217
1255
|
id: "1.2-knowledge-claim-ledger",
|
|
1218
1256
|
apply: (db2) => {
|
|
@@ -1411,8 +1449,8 @@ var init_mini_skill_store = __esm({
|
|
|
1411
1449
|
|
|
1412
1450
|
// src/compact/token-budget.ts
|
|
1413
1451
|
import { countTokens, isWithinTokenLimit } from "gpt-tokenizer";
|
|
1414
|
-
function countTextTokens(
|
|
1415
|
-
return countTokens(
|
|
1452
|
+
function countTextTokens(text2) {
|
|
1453
|
+
return countTokens(text2);
|
|
1416
1454
|
}
|
|
1417
1455
|
var init_token_budget = __esm({
|
|
1418
1456
|
"src/compact/token-budget.ts"() {
|
|
@@ -2165,8 +2203,8 @@ import { createHash } from "crypto";
|
|
|
2165
2203
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
2166
2204
|
import { join as join2 } from "path";
|
|
2167
2205
|
import { homedir as homedir6 } from "os";
|
|
2168
|
-
function textHash(
|
|
2169
|
-
return createHash("sha256").update(
|
|
2206
|
+
function textHash(text2) {
|
|
2207
|
+
return createHash("sha256").update(text2).digest("hex").slice(0, 16);
|
|
2170
2208
|
}
|
|
2171
2209
|
async function loadDiskCache() {
|
|
2172
2210
|
try {
|
|
@@ -2229,11 +2267,11 @@ var init_fastembed_provider = __esm({
|
|
|
2229
2267
|
async embedInputs(inputs, options = {}) {
|
|
2230
2268
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
2231
2269
|
}
|
|
2232
|
-
async embed(
|
|
2233
|
-
const hash4 = textHash(
|
|
2270
|
+
async embed(text2) {
|
|
2271
|
+
const hash4 = textHash(text2);
|
|
2234
2272
|
const cached = cache.get(hash4);
|
|
2235
2273
|
if (cached) return cached;
|
|
2236
|
-
const raw = await this.model.queryEmbed(
|
|
2274
|
+
const raw = await this.model.queryEmbed(text2);
|
|
2237
2275
|
const result = Array.from(raw);
|
|
2238
2276
|
if (result.length !== this.dimensions) {
|
|
2239
2277
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
@@ -2329,10 +2367,10 @@ var init_transformers_provider = __esm({
|
|
|
2329
2367
|
async embedInputs(inputs, options = {}) {
|
|
2330
2368
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
2331
2369
|
}
|
|
2332
|
-
async embed(
|
|
2333
|
-
const cached = cache2.get(
|
|
2370
|
+
async embed(text2) {
|
|
2371
|
+
const cached = cache2.get(text2);
|
|
2334
2372
|
if (cached) return cached;
|
|
2335
|
-
const output = await this.extractor(
|
|
2373
|
+
const output = await this.extractor(text2, {
|
|
2336
2374
|
pooling: "mean",
|
|
2337
2375
|
normalize: true
|
|
2338
2376
|
});
|
|
@@ -2340,7 +2378,7 @@ var init_transformers_provider = __esm({
|
|
|
2340
2378
|
if (result.length !== this.dimensions) {
|
|
2341
2379
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
2342
2380
|
}
|
|
2343
|
-
this.cacheSet(
|
|
2381
|
+
this.cacheSet(text2, result);
|
|
2344
2382
|
return result;
|
|
2345
2383
|
}
|
|
2346
2384
|
async embedBatch(texts) {
|
|
@@ -2403,8 +2441,8 @@ function dimsCacheFile() {
|
|
|
2403
2441
|
function cacheMetaFile() {
|
|
2404
2442
|
return join3(cacheDir(), ".embedding-api-cache-meta.json");
|
|
2405
2443
|
}
|
|
2406
|
-
function normalizeText(
|
|
2407
|
-
return
|
|
2444
|
+
function normalizeText(text2) {
|
|
2445
|
+
return text2.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
|
|
2408
2446
|
}
|
|
2409
2447
|
function cacheNamespace(config) {
|
|
2410
2448
|
return [
|
|
@@ -2414,8 +2452,8 @@ function cacheNamespace(config) {
|
|
|
2414
2452
|
config.requestedDimensions ?? "native"
|
|
2415
2453
|
].join("|");
|
|
2416
2454
|
}
|
|
2417
|
-
function textHash2(
|
|
2418
|
-
return createHash2("sha256").update(`${namespace}\0${
|
|
2455
|
+
function textHash2(text2, namespace) {
|
|
2456
|
+
return createHash2("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
2419
2457
|
}
|
|
2420
2458
|
function inputIdentity(input, options = {}) {
|
|
2421
2459
|
return JSON.stringify({
|
|
@@ -2827,8 +2865,8 @@ var init_api_provider = __esm({
|
|
|
2827
2865
|
if (!embedding) throw new Error("API probe returned no embeddings; check model name and API key");
|
|
2828
2866
|
return embedding.length;
|
|
2829
2867
|
}
|
|
2830
|
-
async embed(
|
|
2831
|
-
const normalized = normalizeText(
|
|
2868
|
+
async embed(text2, options) {
|
|
2869
|
+
const normalized = normalizeText(text2);
|
|
2832
2870
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
2833
2871
|
return this.embedInput({ modality: "text", text: normalized }, { intent: "document", ...options });
|
|
2834
2872
|
}
|
|
@@ -2885,7 +2923,7 @@ var init_api_provider = __esm({
|
|
|
2885
2923
|
}
|
|
2886
2924
|
async embedBatch(texts, options) {
|
|
2887
2925
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
2888
|
-
return Promise.all(texts.map((
|
|
2926
|
+
return Promise.all(texts.map((text2) => this.embedInput({ modality: "text", text: text2 }, { intent: "document", ...options })));
|
|
2889
2927
|
}
|
|
2890
2928
|
await ensureDiskCacheLoaded();
|
|
2891
2929
|
const normalizedTexts = texts.map(normalizeText);
|
|
@@ -2964,8 +3002,8 @@ var init_api_provider = __esm({
|
|
|
2964
3002
|
}
|
|
2965
3003
|
async getCachedEmbeddings(texts) {
|
|
2966
3004
|
await ensureDiskCacheLoaded();
|
|
2967
|
-
return texts.map((
|
|
2968
|
-
const hash4 = textHash2(normalizeText(
|
|
3005
|
+
return texts.map((text2) => {
|
|
3006
|
+
const hash4 = textHash2(normalizeText(text2), this.cacheKeyNamespace);
|
|
2969
3007
|
return cache3.get(hash4) ?? null;
|
|
2970
3008
|
});
|
|
2971
3009
|
}
|
|
@@ -3195,9 +3233,9 @@ function wrapProvider(candidate) {
|
|
|
3195
3233
|
return {
|
|
3196
3234
|
name: candidate.name,
|
|
3197
3235
|
dimensions: candidate.dimensions,
|
|
3198
|
-
async embed(
|
|
3236
|
+
async embed(text2, options) {
|
|
3199
3237
|
try {
|
|
3200
|
-
return await candidate.embed(
|
|
3238
|
+
return await candidate.embed(text2, options);
|
|
3201
3239
|
} catch (error) {
|
|
3202
3240
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
3203
3241
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -3205,7 +3243,7 @@ function wrapProvider(candidate) {
|
|
|
3205
3243
|
if (fallback) {
|
|
3206
3244
|
provider = wrapProvider(fallback);
|
|
3207
3245
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
3208
|
-
return provider.embed(
|
|
3246
|
+
return provider.embed(text2, options);
|
|
3209
3247
|
}
|
|
3210
3248
|
}
|
|
3211
3249
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -3764,8 +3802,8 @@ async function readResponseText(response, signal, maxBytes = MAX_LLM_RESPONSE_BY
|
|
|
3764
3802
|
}
|
|
3765
3803
|
}
|
|
3766
3804
|
async function readResponseJson(response, signal, maxBytes = MAX_LLM_RESPONSE_BYTES) {
|
|
3767
|
-
const
|
|
3768
|
-
return JSON.parse(
|
|
3805
|
+
const text2 = await readResponseText(response, signal, maxBytes);
|
|
3806
|
+
return JSON.parse(text2);
|
|
3769
3807
|
}
|
|
3770
3808
|
async function* callLLMWithToolsStream(messages, tools) {
|
|
3771
3809
|
if (!currentConfig) {
|
|
@@ -4318,8 +4356,8 @@ function isCjkHeavy(query) {
|
|
|
4318
4356
|
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
4319
4357
|
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
4320
4358
|
}
|
|
4321
|
-
function normalizeExpansion(
|
|
4322
|
-
return
|
|
4359
|
+
function normalizeExpansion(text2) {
|
|
4360
|
+
return text2.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
|
|
4323
4361
|
}
|
|
4324
4362
|
async function maybeExpandSearchQuery(query) {
|
|
4325
4363
|
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
@@ -4682,9 +4720,9 @@ function shouldSkipCompression(narrative, type) {
|
|
|
4682
4720
|
if (specialChars / narrative.length > 0.35) return true;
|
|
4683
4721
|
return false;
|
|
4684
4722
|
}
|
|
4685
|
-
function estimateTokens(
|
|
4686
|
-
const cjkChars = (
|
|
4687
|
-
const otherChars =
|
|
4723
|
+
function estimateTokens(text2) {
|
|
4724
|
+
const cjkChars = (text2.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
|
|
4725
|
+
const otherChars = text2.length - cjkChars;
|
|
4688
4726
|
return Math.ceil(cjkChars / 1.5 + otherChars / 4);
|
|
4689
4727
|
}
|
|
4690
4728
|
var COMPRESS_PROMPT, COMPRESS_PROMPT_GENTLE, RERANK_PROMPT, SKIP_PATTERNS, LOW_COMPRESSION_TYPES;
|
|
@@ -4987,10 +5025,10 @@ function isEmbeddingEnabled() {
|
|
|
4987
5025
|
function getVectorDimensions() {
|
|
4988
5026
|
return embeddingEnabled ? embeddingDimensions : null;
|
|
4989
5027
|
}
|
|
4990
|
-
async function generateEmbedding(
|
|
5028
|
+
async function generateEmbedding(text2) {
|
|
4991
5029
|
const provider2 = await getEmbeddingProvider();
|
|
4992
5030
|
if (!provider2) return null;
|
|
4993
|
-
return provider2.embedInput ? provider2.embedInput({ modality: "text", text }, { intent: "document" }) : provider2.embed(
|
|
5031
|
+
return provider2.embedInput ? provider2.embedInput({ modality: "text", text: text2 }, { intent: "document" }) : provider2.embed(text2);
|
|
4994
5032
|
}
|
|
4995
5033
|
async function generateEmbeddingInput(input, options = {}) {
|
|
4996
5034
|
const provider2 = await getEmbeddingProvider();
|
|
@@ -6322,9 +6360,9 @@ var init_entity_extractor = __esm({
|
|
|
6322
6360
|
});
|
|
6323
6361
|
|
|
6324
6362
|
// src/memory/secret-filter.ts
|
|
6325
|
-
function applyRedaction(
|
|
6326
|
-
if (!
|
|
6327
|
-
let out =
|
|
6363
|
+
function applyRedaction(text2) {
|
|
6364
|
+
if (!text2) return text2;
|
|
6365
|
+
let out = text2;
|
|
6328
6366
|
out = out.replace(
|
|
6329
6367
|
/((?:password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret)\s*[:=]\s*["']?)([^\s"',;\n]{6,})/gi,
|
|
6330
6368
|
"$1[REDACTED]"
|
|
@@ -6338,8 +6376,8 @@ function applyRedaction(text) {
|
|
|
6338
6376
|
out = out.replace(/\beyJ[A-Za-z0-9._-]{40,}\b/g, "[REDACTED]");
|
|
6339
6377
|
return out;
|
|
6340
6378
|
}
|
|
6341
|
-
function sanitizeCredentials(
|
|
6342
|
-
return applyRedaction(
|
|
6379
|
+
function sanitizeCredentials(text2) {
|
|
6380
|
+
return applyRedaction(text2);
|
|
6343
6381
|
}
|
|
6344
6382
|
var init_secret_filter = __esm({
|
|
6345
6383
|
"src/memory/secret-filter.ts"() {
|
|
@@ -6390,8 +6428,8 @@ function clampPositiveInteger(value, fallback) {
|
|
|
6390
6428
|
return Math.max(1, Math.floor(value));
|
|
6391
6429
|
}
|
|
6392
6430
|
function errorText(error) {
|
|
6393
|
-
const
|
|
6394
|
-
return sanitizeCredentials(
|
|
6431
|
+
const text2 = error instanceof Error ? error.message : String(error);
|
|
6432
|
+
return sanitizeCredentials(text2).slice(0, MAX_ERROR_LENGTH);
|
|
6395
6433
|
}
|
|
6396
6434
|
function normalizedKinds(kinds) {
|
|
6397
6435
|
if (!kinds) return void 0;
|
|
@@ -7313,9 +7351,9 @@ __export(consolidation_exports, {
|
|
|
7313
7351
|
executeConsolidation: () => executeConsolidation,
|
|
7314
7352
|
findConsolidationCandidates: () => findConsolidationCandidates
|
|
7315
7353
|
});
|
|
7316
|
-
function tokenize(
|
|
7354
|
+
function tokenize(text2) {
|
|
7317
7355
|
return new Set(
|
|
7318
|
-
|
|
7356
|
+
text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t2) => t2.length > 1)
|
|
7319
7357
|
);
|
|
7320
7358
|
}
|
|
7321
7359
|
function jaccardSimilarity(a, b) {
|
|
@@ -16273,8 +16311,8 @@ var init_headers = __esm({
|
|
|
16273
16311
|
});
|
|
16274
16312
|
|
|
16275
16313
|
// packages/ai/dist/utils/sanitize-unicode.js
|
|
16276
|
-
function sanitizeSurrogates(
|
|
16277
|
-
return
|
|
16314
|
+
function sanitizeSurrogates(text2) {
|
|
16315
|
+
return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
16278
16316
|
}
|
|
16279
16317
|
var init_sanitize_unicode = __esm({
|
|
16280
16318
|
"packages/ai/dist/utils/sanitize-unicode.js"() {
|
|
@@ -16756,9 +16794,9 @@ var init_values = __esm({
|
|
|
16756
16794
|
}
|
|
16757
16795
|
return n;
|
|
16758
16796
|
};
|
|
16759
|
-
safeJSON = (
|
|
16797
|
+
safeJSON = (text2) => {
|
|
16760
16798
|
try {
|
|
16761
|
-
return JSON.parse(
|
|
16799
|
+
return JSON.parse(text2);
|
|
16762
16800
|
} catch (err) {
|
|
16763
16801
|
return void 0;
|
|
16764
16802
|
}
|
|
@@ -17921,8 +17959,8 @@ async function defaultParseResponse(client, props) {
|
|
|
17921
17959
|
const json2 = await response.json();
|
|
17922
17960
|
return addRequestID(json2, response);
|
|
17923
17961
|
}
|
|
17924
|
-
const
|
|
17925
|
-
return
|
|
17962
|
+
const text2 = await response.text();
|
|
17963
|
+
return text2;
|
|
17926
17964
|
})();
|
|
17927
17965
|
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
17928
17966
|
retryOfRequestLogID,
|
|
@@ -31281,7 +31319,7 @@ var init_models_generated = __esm({
|
|
|
31281
31319
|
provider: "minimax",
|
|
31282
31320
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
31283
31321
|
reasoning: true,
|
|
31284
|
-
input: ["text", "image"],
|
|
31322
|
+
input: ["text", "image", "video"],
|
|
31285
31323
|
cost: {
|
|
31286
31324
|
input: 0.3,
|
|
31287
31325
|
output: 1.2,
|
|
@@ -31334,7 +31372,7 @@ var init_models_generated = __esm({
|
|
|
31334
31372
|
provider: "minimax-cn",
|
|
31335
31373
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
31336
31374
|
reasoning: true,
|
|
31337
|
-
input: ["text", "image"],
|
|
31375
|
+
input: ["text", "image", "video"],
|
|
31338
31376
|
cost: {
|
|
31339
31377
|
input: 0.3,
|
|
31340
31378
|
output: 1.2,
|
|
@@ -43529,9 +43567,9 @@ var init_values2 = __esm({
|
|
|
43529
43567
|
}
|
|
43530
43568
|
return n;
|
|
43531
43569
|
};
|
|
43532
|
-
safeJSON2 = (
|
|
43570
|
+
safeJSON2 = (text2) => {
|
|
43533
43571
|
try {
|
|
43534
|
-
return JSON.parse(
|
|
43572
|
+
return JSON.parse(text2);
|
|
43535
43573
|
} catch (err) {
|
|
43536
43574
|
return void 0;
|
|
43537
43575
|
}
|
|
@@ -44305,8 +44343,8 @@ async function defaultParseResponse2(client, props) {
|
|
|
44305
44343
|
const json2 = await response.json();
|
|
44306
44344
|
return addRequestID2(json2, response);
|
|
44307
44345
|
}
|
|
44308
|
-
const
|
|
44309
|
-
return
|
|
44346
|
+
const text2 = await response.text();
|
|
44347
|
+
return text2;
|
|
44310
44348
|
})();
|
|
44311
44349
|
loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
|
|
44312
44350
|
retryOfRequestLogID,
|
|
@@ -50609,11 +50647,11 @@ var init_simple_options = __esm({
|
|
|
50609
50647
|
});
|
|
50610
50648
|
|
|
50611
50649
|
// packages/ai/dist/providers/transform-messages.js
|
|
50612
|
-
function
|
|
50650
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
50613
50651
|
const result = [];
|
|
50614
50652
|
let previousWasPlaceholder = false;
|
|
50615
50653
|
for (const block of content) {
|
|
50616
|
-
if (block.type ===
|
|
50654
|
+
if (block.type === dropType) {
|
|
50617
50655
|
if (!previousWasPlaceholder) {
|
|
50618
50656
|
result.push({ type: "text", text: placeholder });
|
|
50619
50657
|
}
|
|
@@ -50621,33 +50659,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
50621
50659
|
continue;
|
|
50622
50660
|
}
|
|
50623
50661
|
result.push(block);
|
|
50624
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
50662
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
50625
50663
|
}
|
|
50626
50664
|
return result;
|
|
50627
50665
|
}
|
|
50628
|
-
function
|
|
50629
|
-
|
|
50666
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
50667
|
+
const supportsImage = model.input.includes("image");
|
|
50668
|
+
const supportsVideo = model.input.includes("video");
|
|
50669
|
+
if (supportsImage && supportsVideo) {
|
|
50630
50670
|
return messages;
|
|
50631
50671
|
}
|
|
50632
50672
|
return messages.map((msg) => {
|
|
50633
50673
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
50634
|
-
|
|
50635
|
-
|
|
50636
|
-
content
|
|
50637
|
-
|
|
50674
|
+
let content = msg.content;
|
|
50675
|
+
if (!supportsImage)
|
|
50676
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
50677
|
+
if (!supportsVideo)
|
|
50678
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
50679
|
+
return { ...msg, content };
|
|
50638
50680
|
}
|
|
50639
50681
|
if (msg.role === "toolResult") {
|
|
50640
|
-
|
|
50641
|
-
|
|
50642
|
-
content
|
|
50643
|
-
|
|
50682
|
+
let content = msg.content;
|
|
50683
|
+
if (!supportsImage)
|
|
50684
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
50685
|
+
if (!supportsVideo)
|
|
50686
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
50687
|
+
return { ...msg, content };
|
|
50644
50688
|
}
|
|
50645
50689
|
return msg;
|
|
50646
50690
|
});
|
|
50647
50691
|
}
|
|
50648
50692
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
50649
50693
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
50650
|
-
const imageAwareMessages =
|
|
50694
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
50651
50695
|
const transformed = imageAwareMessages.map((msg) => {
|
|
50652
50696
|
if (msg.role === "user") {
|
|
50653
50697
|
return msg;
|
|
@@ -50759,13 +50803,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
50759
50803
|
insertSyntheticToolResults();
|
|
50760
50804
|
return result;
|
|
50761
50805
|
}
|
|
50762
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
50806
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
50763
50807
|
var init_transform_messages = __esm({
|
|
50764
50808
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
50765
50809
|
"use strict";
|
|
50766
50810
|
init_esm_shims();
|
|
50767
50811
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
50768
50812
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
50813
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
50814
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
50769
50815
|
}
|
|
50770
50816
|
});
|
|
50771
50817
|
|
|
@@ -50796,8 +50842,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
50796
50842
|
};
|
|
50797
50843
|
}
|
|
50798
50844
|
function convertContentBlocks(content) {
|
|
50799
|
-
const
|
|
50800
|
-
if (!
|
|
50845
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
50846
|
+
if (!hasMedia) {
|
|
50801
50847
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
50802
50848
|
}
|
|
50803
50849
|
const blocks = content.map((block) => {
|
|
@@ -50807,6 +50853,16 @@ function convertContentBlocks(content) {
|
|
|
50807
50853
|
text: sanitizeSurrogates(block.text)
|
|
50808
50854
|
};
|
|
50809
50855
|
}
|
|
50856
|
+
if (block.type === "video") {
|
|
50857
|
+
return {
|
|
50858
|
+
type: "video",
|
|
50859
|
+
source: {
|
|
50860
|
+
type: "base64",
|
|
50861
|
+
media_type: block.mimeType,
|
|
50862
|
+
data: block.data
|
|
50863
|
+
}
|
|
50864
|
+
};
|
|
50865
|
+
}
|
|
50810
50866
|
return {
|
|
50811
50867
|
type: "image",
|
|
50812
50868
|
source: {
|
|
@@ -50820,7 +50876,7 @@ function convertContentBlocks(content) {
|
|
|
50820
50876
|
if (!hasText) {
|
|
50821
50877
|
blocks.unshift({
|
|
50822
50878
|
type: "text",
|
|
50823
|
-
text: "(see attached
|
|
50879
|
+
text: "(see attached media)"
|
|
50824
50880
|
});
|
|
50825
50881
|
}
|
|
50826
50882
|
return blocks;
|
|
@@ -50881,9 +50937,9 @@ function decodeSseLine(line, state) {
|
|
|
50881
50937
|
}
|
|
50882
50938
|
return null;
|
|
50883
50939
|
}
|
|
50884
|
-
function nextLineBreakIndex(
|
|
50885
|
-
const carriageReturnIndex =
|
|
50886
|
-
const newlineIndex =
|
|
50940
|
+
function nextLineBreakIndex(text2) {
|
|
50941
|
+
const carriageReturnIndex = text2.indexOf("\r");
|
|
50942
|
+
const newlineIndex = text2.indexOf("\n");
|
|
50887
50943
|
if (carriageReturnIndex === -1) {
|
|
50888
50944
|
return newlineIndex;
|
|
50889
50945
|
}
|
|
@@ -50892,18 +50948,18 @@ function nextLineBreakIndex(text) {
|
|
|
50892
50948
|
}
|
|
50893
50949
|
return Math.min(carriageReturnIndex, newlineIndex);
|
|
50894
50950
|
}
|
|
50895
|
-
function consumeLine(
|
|
50896
|
-
const lineBreakIndex = nextLineBreakIndex(
|
|
50951
|
+
function consumeLine(text2) {
|
|
50952
|
+
const lineBreakIndex = nextLineBreakIndex(text2);
|
|
50897
50953
|
if (lineBreakIndex === -1) {
|
|
50898
50954
|
return null;
|
|
50899
50955
|
}
|
|
50900
50956
|
let nextIndex = lineBreakIndex + 1;
|
|
50901
|
-
if (
|
|
50957
|
+
if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
|
|
50902
50958
|
nextIndex += 1;
|
|
50903
50959
|
}
|
|
50904
50960
|
return {
|
|
50905
|
-
line:
|
|
50906
|
-
rest:
|
|
50961
|
+
line: text2.slice(0, lineBreakIndex),
|
|
50962
|
+
rest: text2.slice(nextIndex)
|
|
50907
50963
|
};
|
|
50908
50964
|
}
|
|
50909
50965
|
async function* iterateSseMessages(body, signal) {
|
|
@@ -51170,6 +51226,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
51170
51226
|
type: "text",
|
|
51171
51227
|
text: sanitizeSurrogates(item.text)
|
|
51172
51228
|
};
|
|
51229
|
+
} else if (item.type === "video") {
|
|
51230
|
+
return {
|
|
51231
|
+
type: "video",
|
|
51232
|
+
source: {
|
|
51233
|
+
type: "base64",
|
|
51234
|
+
media_type: item.mimeType,
|
|
51235
|
+
data: item.data
|
|
51236
|
+
}
|
|
51237
|
+
};
|
|
51173
51238
|
} else {
|
|
51174
51239
|
return {
|
|
51175
51240
|
type: "image",
|
|
@@ -51250,6 +51315,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
51250
51315
|
toolResults.push({
|
|
51251
51316
|
type: "tool_result",
|
|
51252
51317
|
tool_use_id: msg.toolCallId,
|
|
51318
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
51319
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
51253
51320
|
content: convertContentBlocks(msg.content),
|
|
51254
51321
|
is_error: msg.isError
|
|
51255
51322
|
});
|
|
@@ -51276,7 +51343,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
51276
51343
|
if (lastMessage.role === "user") {
|
|
51277
51344
|
if (Array.isArray(lastMessage.content)) {
|
|
51278
51345
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
51279
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
51346
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
51280
51347
|
lastBlock.cache_control = cacheControl;
|
|
51281
51348
|
}
|
|
51282
51349
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -53059,8 +53126,8 @@ var require_common = __commonJS({
|
|
|
53059
53126
|
}
|
|
53060
53127
|
function redactString(obj, key) {
|
|
53061
53128
|
if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
|
|
53062
|
-
const
|
|
53063
|
-
if (/grant_type=/i.test(
|
|
53129
|
+
const text2 = obj[key];
|
|
53130
|
+
if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
|
|
53064
53131
|
obj[key] = REDACT;
|
|
53065
53132
|
}
|
|
53066
53133
|
}
|
|
@@ -59888,8 +59955,8 @@ var init_body = __esm({
|
|
|
59888
59955
|
* @return Promise
|
|
59889
59956
|
*/
|
|
59890
59957
|
async json() {
|
|
59891
|
-
const
|
|
59892
|
-
return JSON.parse(
|
|
59958
|
+
const text2 = await this.text();
|
|
59959
|
+
return JSON.parse(text2);
|
|
59893
59960
|
}
|
|
59894
59961
|
/**
|
|
59895
59962
|
* Decode response as text
|
|
@@ -61041,7 +61108,7 @@ var require_gaxios = __commonJS({
|
|
|
61041
61108
|
var retry_js_1 = require_retry3();
|
|
61042
61109
|
var stream_1 = __require("stream");
|
|
61043
61110
|
var interceptor_js_1 = require_interceptor();
|
|
61044
|
-
var
|
|
61111
|
+
var randomUUID11 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
61045
61112
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
61046
61113
|
var Gaxios = class {
|
|
61047
61114
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -61314,7 +61381,7 @@ var require_gaxios = __commonJS({
|
|
|
61314
61381
|
*/
|
|
61315
61382
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
61316
61383
|
if (opts.multipart?.length) {
|
|
61317
|
-
const boundary = await
|
|
61384
|
+
const boundary = await randomUUID11();
|
|
61318
61385
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
61319
61386
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
61320
61387
|
} else if (shouldDirectlyPassData) {
|
|
@@ -63065,18 +63132,18 @@ var require_parse = __commonJS({
|
|
|
63065
63132
|
n: "\n",
|
|
63066
63133
|
r: "\r",
|
|
63067
63134
|
t: " "
|
|
63068
|
-
},
|
|
63135
|
+
}, text2, error = function(m2) {
|
|
63069
63136
|
throw {
|
|
63070
63137
|
name: "SyntaxError",
|
|
63071
63138
|
message: m2,
|
|
63072
63139
|
at,
|
|
63073
|
-
text
|
|
63140
|
+
text: text2
|
|
63074
63141
|
};
|
|
63075
63142
|
}, next = function(c) {
|
|
63076
63143
|
if (c && c !== ch) {
|
|
63077
63144
|
error("Expected '" + c + "' instead of '" + ch + "'");
|
|
63078
63145
|
}
|
|
63079
|
-
ch =
|
|
63146
|
+
ch = text2.charAt(at);
|
|
63080
63147
|
at += 1;
|
|
63081
63148
|
return ch;
|
|
63082
63149
|
}, number44 = function() {
|
|
@@ -63123,12 +63190,12 @@ var require_parse = __commonJS({
|
|
|
63123
63190
|
var startAt = at;
|
|
63124
63191
|
while (next()) {
|
|
63125
63192
|
if (ch === '"') {
|
|
63126
|
-
if (at - 1 > startAt) string474 +=
|
|
63193
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
63127
63194
|
next();
|
|
63128
63195
|
return string474;
|
|
63129
63196
|
}
|
|
63130
63197
|
if (ch === "\\") {
|
|
63131
|
-
if (at - 1 > startAt) string474 +=
|
|
63198
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
63132
63199
|
next();
|
|
63133
63200
|
if (ch === "u") {
|
|
63134
63201
|
uffff = 0;
|
|
@@ -63261,7 +63328,7 @@ var require_parse = __commonJS({
|
|
|
63261
63328
|
};
|
|
63262
63329
|
return function(source, reviver) {
|
|
63263
63330
|
var result;
|
|
63264
|
-
|
|
63331
|
+
text2 = source + "";
|
|
63265
63332
|
at = 0;
|
|
63266
63333
|
ch = " ";
|
|
63267
63334
|
result = value();
|
|
@@ -64173,8 +64240,8 @@ var require_crypto = __commonJS({
|
|
|
64173
64240
|
const result = new TextDecoder().decode(uint8array);
|
|
64174
64241
|
return result;
|
|
64175
64242
|
}
|
|
64176
|
-
encodeBase64StringUtf8(
|
|
64177
|
-
const uint8array = new TextEncoder().encode(
|
|
64243
|
+
encodeBase64StringUtf8(text2) {
|
|
64244
|
+
const uint8array = new TextEncoder().encode(text2);
|
|
64178
64245
|
const result = base64js.fromByteArray(uint8array);
|
|
64179
64246
|
return result;
|
|
64180
64247
|
}
|
|
@@ -64243,8 +64310,8 @@ var require_crypto2 = __commonJS({
|
|
|
64243
64310
|
decodeBase64StringUtf8(base64) {
|
|
64244
64311
|
return Buffer.from(base64, "base64").toString("utf-8");
|
|
64245
64312
|
}
|
|
64246
|
-
encodeBase64StringUtf8(
|
|
64247
|
-
return Buffer.from(
|
|
64313
|
+
encodeBase64StringUtf8(text2) {
|
|
64314
|
+
return Buffer.from(text2, "utf-8").toString("base64");
|
|
64248
64315
|
}
|
|
64249
64316
|
/**
|
|
64250
64317
|
* Computes the SHA-256 hash of the provided string.
|
|
@@ -84689,8 +84756,8 @@ async function defaultParseResponse3(client, props) {
|
|
|
84689
84756
|
const json2 = await response.json();
|
|
84690
84757
|
return json2;
|
|
84691
84758
|
}
|
|
84692
|
-
const
|
|
84693
|
-
return
|
|
84759
|
+
const text2 = await response.text();
|
|
84760
|
+
return text2;
|
|
84694
84761
|
})();
|
|
84695
84762
|
loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
|
|
84696
84763
|
retryOfRequestLogID,
|
|
@@ -86267,7 +86334,7 @@ var init_node = __esm({
|
|
|
86267
86334
|
if (this.candidates && this.candidates.length > 1) {
|
|
86268
86335
|
console.warn("there are multiple candidates in the response, returning text from the first one.");
|
|
86269
86336
|
}
|
|
86270
|
-
let
|
|
86337
|
+
let text2 = "";
|
|
86271
86338
|
let anyTextPartText = false;
|
|
86272
86339
|
const nonTextParts = [];
|
|
86273
86340
|
for (const part of (_h = (_g = (_f = (_e = this.candidates) === null || _e === void 0 ? void 0 : _e[0]) === null || _f === void 0 ? void 0 : _f.content) === null || _g === void 0 ? void 0 : _g.parts) !== null && _h !== void 0 ? _h : []) {
|
|
@@ -86281,13 +86348,13 @@ var init_node = __esm({
|
|
|
86281
86348
|
continue;
|
|
86282
86349
|
}
|
|
86283
86350
|
anyTextPartText = true;
|
|
86284
|
-
|
|
86351
|
+
text2 += part.text;
|
|
86285
86352
|
}
|
|
86286
86353
|
}
|
|
86287
86354
|
if (nonTextParts.length > 0) {
|
|
86288
86355
|
console.warn(`there are non-text parts ${nonTextParts} in the response, returning concatenation of all text parts. Please refer to the non text parts for a full response from model.`);
|
|
86289
86356
|
}
|
|
86290
|
-
return anyTextPartText ?
|
|
86357
|
+
return anyTextPartText ? text2 : void 0;
|
|
86291
86358
|
}
|
|
86292
86359
|
/**
|
|
86293
86360
|
* Returns the concatenation of all inline data parts from the first candidate
|
|
@@ -86540,7 +86607,7 @@ var init_node = __esm({
|
|
|
86540
86607
|
*/
|
|
86541
86608
|
get text() {
|
|
86542
86609
|
var _a5, _b, _c;
|
|
86543
|
-
let
|
|
86610
|
+
let text2 = "";
|
|
86544
86611
|
let anyTextPartFound = false;
|
|
86545
86612
|
const nonTextParts = [];
|
|
86546
86613
|
for (const part of (_c = (_b = (_a5 = this.serverContent) === null || _a5 === void 0 ? void 0 : _a5.modelTurn) === null || _b === void 0 ? void 0 : _b.parts) !== null && _c !== void 0 ? _c : []) {
|
|
@@ -86554,13 +86621,13 @@ var init_node = __esm({
|
|
|
86554
86621
|
continue;
|
|
86555
86622
|
}
|
|
86556
86623
|
anyTextPartFound = true;
|
|
86557
|
-
|
|
86624
|
+
text2 += part.text;
|
|
86558
86625
|
}
|
|
86559
86626
|
}
|
|
86560
86627
|
if (nonTextParts.length > 0) {
|
|
86561
86628
|
console.warn(`there are non-text parts ${nonTextParts} in the response, returning concatenation of all text parts. Please refer to the non text parts for a full response from model.`);
|
|
86562
86629
|
}
|
|
86563
|
-
return anyTextPartFound ?
|
|
86630
|
+
return anyTextPartFound ? text2 : void 0;
|
|
86564
86631
|
}
|
|
86565
86632
|
/**
|
|
86566
86633
|
* Returns the concatenation of all inline data parts from the server content if present.
|
|
@@ -91232,9 +91299,9 @@ var init_node = __esm({
|
|
|
91232
91299
|
}
|
|
91233
91300
|
return n;
|
|
91234
91301
|
};
|
|
91235
|
-
safeJSON3 = (
|
|
91302
|
+
safeJSON3 = (text2) => {
|
|
91236
91303
|
try {
|
|
91237
|
-
return JSON.parse(
|
|
91304
|
+
return JSON.parse(text2);
|
|
91238
91305
|
} catch (err) {
|
|
91239
91306
|
return void 0;
|
|
91240
91307
|
}
|
|
@@ -109097,8 +109164,8 @@ function findBoundary(buf) {
|
|
|
109097
109164
|
return null;
|
|
109098
109165
|
}
|
|
109099
109166
|
function parseMessage2(chunk, parse2, state, dataRequired) {
|
|
109100
|
-
const
|
|
109101
|
-
const lines =
|
|
109167
|
+
const text2 = new TextDecoder().decode(chunk);
|
|
109168
|
+
const lines = text2.split(/\r\n|\r|\n/);
|
|
109102
109169
|
const dataLines = [];
|
|
109103
109170
|
const ret = {};
|
|
109104
109171
|
let ignore = true;
|
|
@@ -131972,10 +132039,10 @@ function formatMistralError(error) {
|
|
|
131972
132039
|
}
|
|
131973
132040
|
return safeJsonStringify(error);
|
|
131974
132041
|
}
|
|
131975
|
-
function truncateErrorText(
|
|
131976
|
-
if (
|
|
131977
|
-
return
|
|
131978
|
-
return `${
|
|
132042
|
+
function truncateErrorText(text2, maxChars) {
|
|
132043
|
+
if (text2.length <= maxChars)
|
|
132044
|
+
return text2;
|
|
132045
|
+
return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
|
|
131979
132046
|
}
|
|
131980
132047
|
function safeJsonStringify(value) {
|
|
131981
132048
|
try {
|
|
@@ -132095,7 +132162,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
|
|
|
132095
132162
|
continue;
|
|
132096
132163
|
}
|
|
132097
132164
|
if (item.type === "thinking") {
|
|
132098
|
-
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((
|
|
132165
|
+
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
|
|
132099
132166
|
const thinkingDelta = sanitizeSurrogates(deltaText);
|
|
132100
132167
|
if (!thinkingDelta)
|
|
132101
132168
|
continue;
|
|
@@ -132292,8 +132359,8 @@ function toChatMessages(messages, supportsImages) {
|
|
|
132292
132359
|
}
|
|
132293
132360
|
return result;
|
|
132294
132361
|
}
|
|
132295
|
-
function buildToolResultText(
|
|
132296
|
-
const trimmed =
|
|
132362
|
+
function buildToolResultText(text2, hasImages, supportsImages, isError) {
|
|
132363
|
+
const trimmed = text2.trim();
|
|
132297
132364
|
const errorPrefix = isError ? "[tool error] " : "";
|
|
132298
132365
|
if (trimmed.length > 0) {
|
|
132299
132366
|
const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
|
|
@@ -133094,14 +133161,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
133094
133161
|
};
|
|
133095
133162
|
const onMessage = (event) => {
|
|
133096
133163
|
void (async () => {
|
|
133097
|
-
let
|
|
133164
|
+
let text2 = null;
|
|
133098
133165
|
try {
|
|
133099
133166
|
if (!event || typeof event !== "object" || !("data" in event))
|
|
133100
133167
|
return;
|
|
133101
|
-
|
|
133102
|
-
if (!
|
|
133168
|
+
text2 = await decodeWebSocketData(event.data);
|
|
133169
|
+
if (!text2)
|
|
133103
133170
|
return;
|
|
133104
|
-
const parsed = JSON.parse(
|
|
133171
|
+
const parsed = JSON.parse(text2);
|
|
133105
133172
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
133106
133173
|
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
133107
133174
|
sawCompletion = true;
|
|
@@ -133112,7 +133179,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
133112
133179
|
} catch (cause) {
|
|
133113
133180
|
failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
|
|
133114
133181
|
cause,
|
|
133115
|
-
payload:
|
|
133182
|
+
payload: text2
|
|
133116
133183
|
});
|
|
133117
133184
|
done = true;
|
|
133118
133185
|
wake();
|
|
@@ -141276,11 +141343,11 @@ function videoRequestConfig(input) {
|
|
|
141276
141343
|
};
|
|
141277
141344
|
}
|
|
141278
141345
|
async function readMiniMaxJson(response) {
|
|
141279
|
-
const
|
|
141346
|
+
const text2 = await response.text();
|
|
141280
141347
|
let body = {};
|
|
141281
|
-
if (
|
|
141348
|
+
if (text2) {
|
|
141282
141349
|
try {
|
|
141283
|
-
const parsed = JSON.parse(
|
|
141350
|
+
const parsed = JSON.parse(text2);
|
|
141284
141351
|
if (isRecord(parsed)) body = parsed;
|
|
141285
141352
|
} catch {
|
|
141286
141353
|
throw new Error("MiniMax video API returned invalid JSON");
|
|
@@ -142101,6 +142168,7 @@ __export(store_exports, {
|
|
|
142101
142168
|
CodeGraphStore: () => CodeGraphStore
|
|
142102
142169
|
});
|
|
142103
142170
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
142171
|
+
import { posix as pathPosix } from "path";
|
|
142104
142172
|
function rowToFile(row) {
|
|
142105
142173
|
return {
|
|
142106
142174
|
id: row.id,
|
|
@@ -142151,6 +142219,26 @@ function rowToEdge(row) {
|
|
|
142151
142219
|
...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
|
|
142152
142220
|
};
|
|
142153
142221
|
}
|
|
142222
|
+
function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
|
|
142223
|
+
const target = evidence?.trim().replace(/\\/g, "/");
|
|
142224
|
+
if (!target?.startsWith(".")) return void 0;
|
|
142225
|
+
const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
|
|
142226
|
+
if (!base || base === ".." || base.startsWith("../")) return void 0;
|
|
142227
|
+
const candidates = [base];
|
|
142228
|
+
const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
|
|
142229
|
+
const hasExtension = Boolean(extensionMatch);
|
|
142230
|
+
if (!hasExtension) {
|
|
142231
|
+
const extensions = [...new Set([...fileByPath.keys()].map((path19) => path19.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
|
|
142232
|
+
for (const extension3 of extensions) {
|
|
142233
|
+
candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
|
|
142234
|
+
}
|
|
142235
|
+
} else {
|
|
142236
|
+
const sourceStem = base.slice(0, -extensionMatch[1].length);
|
|
142237
|
+
const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
|
|
142238
|
+
for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
|
|
142239
|
+
}
|
|
142240
|
+
return candidates.map((candidate) => fileByPath.get(candidate)).find((file) => Boolean(file));
|
|
142241
|
+
}
|
|
142154
142242
|
function rowToRef(row) {
|
|
142155
142243
|
return {
|
|
142156
142244
|
id: row.id,
|
|
@@ -142211,6 +142299,18 @@ function rowToSnapshot(row) {
|
|
|
142211
142299
|
...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
|
|
142212
142300
|
};
|
|
142213
142301
|
}
|
|
142302
|
+
function rowToSnapshotFile(row) {
|
|
142303
|
+
return {
|
|
142304
|
+
snapshotId: row.snapshotId,
|
|
142305
|
+
projectId: row.projectId,
|
|
142306
|
+
fileId: row.fileId,
|
|
142307
|
+
path: row.path,
|
|
142308
|
+
contentHash: row.contentHash
|
|
142309
|
+
};
|
|
142310
|
+
}
|
|
142311
|
+
function snapshotIsIncomplete(snapshot) {
|
|
142312
|
+
return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
|
|
142313
|
+
}
|
|
142214
142314
|
var CodeGraphStore;
|
|
142215
142315
|
var init_store = __esm({
|
|
142216
142316
|
"src/codegraph/store.ts"() {
|
|
@@ -142382,6 +142482,7 @@ var init_store = __esm({
|
|
|
142382
142482
|
}
|
|
142383
142483
|
});
|
|
142384
142484
|
tx();
|
|
142485
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142385
142486
|
}
|
|
142386
142487
|
/**
|
|
142387
142488
|
* Reconcile only files whose source changed plus files that disappeared.
|
|
@@ -142391,7 +142492,10 @@ var init_store = __esm({
|
|
|
142391
142492
|
const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
|
|
142392
142493
|
const metadataOnly = (input.metadataOnly ?? []).filter((file) => file.projectId === projectId);
|
|
142393
142494
|
const removedFileIds = input.removedFileIds ?? [];
|
|
142394
|
-
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0)
|
|
142495
|
+
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
|
|
142496
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142497
|
+
return;
|
|
142498
|
+
}
|
|
142395
142499
|
const staleRefsForFile = this.db.prepare(`
|
|
142396
142500
|
UPDATE observation_code_refs
|
|
142397
142501
|
SET status = 'stale', updatedAt = ?
|
|
@@ -142401,9 +142505,18 @@ var init_store = __esm({
|
|
|
142401
142505
|
)
|
|
142402
142506
|
)
|
|
142403
142507
|
`);
|
|
142404
|
-
const
|
|
142508
|
+
const deleteEdgesFromFile = this.db.prepare(`
|
|
142405
142509
|
DELETE FROM code_edges
|
|
142406
|
-
WHERE projectId = ? AND
|
|
142510
|
+
WHERE projectId = ? AND fromFileId = ?
|
|
142511
|
+
`);
|
|
142512
|
+
const clearImportTargetsForFile = this.db.prepare(`
|
|
142513
|
+
UPDATE code_edges
|
|
142514
|
+
SET toFileId = NULL
|
|
142515
|
+
WHERE projectId = ? AND toFileId = ? AND type = 'imports'
|
|
142516
|
+
`);
|
|
142517
|
+
const deleteOtherIncomingEdgesForFile = this.db.prepare(`
|
|
142518
|
+
DELETE FROM code_edges
|
|
142519
|
+
WHERE projectId = ? AND toFileId = ? AND type != 'imports'
|
|
142407
142520
|
`);
|
|
142408
142521
|
const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
|
|
142409
142522
|
const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
|
|
@@ -142440,14 +142553,18 @@ var init_store = __esm({
|
|
|
142440
142553
|
const staleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
142441
142554
|
for (const fileId of removedFileIds) {
|
|
142442
142555
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
142443
|
-
|
|
142556
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
142557
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
142558
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
142444
142559
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
142445
142560
|
deleteFile.run(projectId, fileId);
|
|
142446
142561
|
}
|
|
142447
142562
|
for (const delta of changed) {
|
|
142448
142563
|
const fileId = delta.file.id;
|
|
142449
142564
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
142450
|
-
|
|
142565
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
142566
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
142567
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
142451
142568
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
142452
142569
|
writeFile5(delta.file);
|
|
142453
142570
|
for (const symbol of delta.symbols) {
|
|
@@ -142485,6 +142602,7 @@ var init_store = __esm({
|
|
|
142485
142602
|
for (const file of metadataOnly) writeFile5(file);
|
|
142486
142603
|
});
|
|
142487
142604
|
tx();
|
|
142605
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142488
142606
|
}
|
|
142489
142607
|
upsertObservationRefs(refs) {
|
|
142490
142608
|
if (refs.length === 0) return;
|
|
@@ -142546,6 +142664,25 @@ var init_store = __esm({
|
|
|
142546
142664
|
});
|
|
142547
142665
|
tx();
|
|
142548
142666
|
}
|
|
142667
|
+
/**
|
|
142668
|
+
* Lite import extraction records the original import text first. Resolve only
|
|
142669
|
+
* local relative imports against the current index after each refresh, so an
|
|
142670
|
+
* added or removed target cannot leave a fabricated file-to-file relation.
|
|
142671
|
+
*/
|
|
142672
|
+
reconcileLocalImportTargets(projectId) {
|
|
142673
|
+
const fileById = new Map(this.listFiles(projectId).map((file) => [file.id, file]));
|
|
142674
|
+
const fileByPath = new Map([...fileById.values()].map((file) => [file.path, file]));
|
|
142675
|
+
const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
|
|
142676
|
+
const tx = this.db.transaction(() => {
|
|
142677
|
+
for (const edge of this.listEdges(projectId)) {
|
|
142678
|
+
if (edge.type !== "imports" || !edge.fromFileId) continue;
|
|
142679
|
+
const source = fileById.get(edge.fromFileId);
|
|
142680
|
+
const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
|
|
142681
|
+
update2.run(target?.id ?? null, edge.id);
|
|
142682
|
+
}
|
|
142683
|
+
});
|
|
142684
|
+
tx();
|
|
142685
|
+
}
|
|
142549
142686
|
getFile(projectId, path19) {
|
|
142550
142687
|
const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path19));
|
|
142551
142688
|
return row ? rowToFile(row) : null;
|
|
@@ -142620,6 +142757,18 @@ var init_store = __esm({
|
|
|
142620
142757
|
ORDER BY observationId, status, id
|
|
142621
142758
|
`).all(projectId).map(rowToRef);
|
|
142622
142759
|
}
|
|
142760
|
+
/** Count distinct observations whose binding to these exact files is stale. */
|
|
142761
|
+
countStaleObservationRefsForFiles(projectId, fileIds) {
|
|
142762
|
+
const ids = [...new Set(fileIds.filter(Boolean))];
|
|
142763
|
+
if (ids.length === 0) return 0;
|
|
142764
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
142765
|
+
const row = this.db.prepare(`
|
|
142766
|
+
SELECT COUNT(DISTINCT observationId) AS count
|
|
142767
|
+
FROM observation_code_refs
|
|
142768
|
+
WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
|
|
142769
|
+
`).get(projectId, ...ids);
|
|
142770
|
+
return Number(row?.count ?? 0);
|
|
142771
|
+
}
|
|
142623
142772
|
listReferencedSymbols(projectId) {
|
|
142624
142773
|
return this.db.prepare(`
|
|
142625
142774
|
SELECT DISTINCT symbols.*
|
|
@@ -142641,6 +142790,94 @@ var init_store = __esm({
|
|
|
142641
142790
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
142642
142791
|
).all(projectId, safeLimit).map(rowToSnapshot);
|
|
142643
142792
|
}
|
|
142793
|
+
listSnapshotFiles(snapshotId) {
|
|
142794
|
+
return this.db.prepare(`
|
|
142795
|
+
SELECT snapshotId, projectId, fileId, path, contentHash
|
|
142796
|
+
FROM code_state_snapshot_files
|
|
142797
|
+
WHERE snapshotId = ?
|
|
142798
|
+
ORDER BY path
|
|
142799
|
+
`).all(snapshotId).map(rowToSnapshotFile);
|
|
142800
|
+
}
|
|
142801
|
+
diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
|
|
142802
|
+
const snapshots = this.db.prepare(`
|
|
142803
|
+
SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
|
|
142804
|
+
`).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
|
|
142805
|
+
if (snapshots.length !== 2) {
|
|
142806
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
|
|
142807
|
+
}
|
|
142808
|
+
if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
|
|
142809
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
|
|
142810
|
+
}
|
|
142811
|
+
if (snapshots.some(snapshotIsIncomplete)) {
|
|
142812
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
|
|
142813
|
+
}
|
|
142814
|
+
const before = this.listSnapshotFiles(fromSnapshotId);
|
|
142815
|
+
const after = this.listSnapshotFiles(toSnapshotId);
|
|
142816
|
+
if (before.length === 0 || after.length === 0) {
|
|
142817
|
+
return {
|
|
142818
|
+
projectId,
|
|
142819
|
+
fromSnapshotId,
|
|
142820
|
+
toSnapshotId,
|
|
142821
|
+
available: false,
|
|
142822
|
+
reason: "legacy-snapshot-without-manifest",
|
|
142823
|
+
changes: []
|
|
142824
|
+
};
|
|
142825
|
+
}
|
|
142826
|
+
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
142827
|
+
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
142828
|
+
const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
|
|
142829
|
+
const changes = [];
|
|
142830
|
+
for (const path19 of paths) {
|
|
142831
|
+
const oldFile = beforeByPath.get(path19);
|
|
142832
|
+
const newFile = afterByPath.get(path19);
|
|
142833
|
+
if (!oldFile && newFile) {
|
|
142834
|
+
changes.push({ path: path19, kind: "added", afterHash: newFile.contentHash });
|
|
142835
|
+
} else if (oldFile && !newFile) {
|
|
142836
|
+
changes.push({ path: path19, kind: "removed", beforeHash: oldFile.contentHash });
|
|
142837
|
+
} else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
|
|
142838
|
+
changes.push({ path: path19, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
|
|
142839
|
+
}
|
|
142840
|
+
}
|
|
142841
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
|
|
142842
|
+
}
|
|
142843
|
+
impactSlice(projectId, changedPaths, maxRelations = 24) {
|
|
142844
|
+
const safeLimit = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
|
|
142845
|
+
const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
|
|
142846
|
+
const files = this.listFiles(projectId);
|
|
142847
|
+
const fileById = new Map(files.map((file) => [file.id, file.path]));
|
|
142848
|
+
const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol) => [symbol.id, symbol.fileId]));
|
|
142849
|
+
const changedIds = new Set(files.filter((file) => normalizedPaths.includes(file.path)).map((file) => file.id));
|
|
142850
|
+
const direct = /* @__PURE__ */ new Set();
|
|
142851
|
+
let relationCount = 0;
|
|
142852
|
+
let truncated = false;
|
|
142853
|
+
for (const edge of this.listEdges(projectId)) {
|
|
142854
|
+
const endpoints = [
|
|
142855
|
+
edge.fromFileId,
|
|
142856
|
+
edge.toFileId,
|
|
142857
|
+
edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
|
|
142858
|
+
edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
|
|
142859
|
+
].filter((id) => Boolean(id));
|
|
142860
|
+
if (!endpoints.some((id) => changedIds.has(id))) continue;
|
|
142861
|
+
const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path19) => Boolean(path19));
|
|
142862
|
+
if (relatedPaths.length === 0) continue;
|
|
142863
|
+
if (relationCount >= safeLimit) {
|
|
142864
|
+
truncated = true;
|
|
142865
|
+
break;
|
|
142866
|
+
}
|
|
142867
|
+
relationCount += 1;
|
|
142868
|
+
for (const path19 of relatedPaths) direct.add(path19);
|
|
142869
|
+
}
|
|
142870
|
+
const snapshot = this.latestSnapshot(projectId);
|
|
142871
|
+
return {
|
|
142872
|
+
projectId,
|
|
142873
|
+
...snapshot ? { snapshotId: snapshot.id } : {},
|
|
142874
|
+
changedPaths: normalizedPaths,
|
|
142875
|
+
directlyConnectedPaths: [...direct].sort(),
|
|
142876
|
+
relationCount,
|
|
142877
|
+
truncated,
|
|
142878
|
+
provider: snapshot?.provider ?? "lite"
|
|
142879
|
+
};
|
|
142880
|
+
}
|
|
142644
142881
|
/**
|
|
142645
142882
|
* Record a completed scan and mark all current structural facts with its
|
|
142646
142883
|
* epoch. The snapshot is written only after refresh reconciliation succeeds,
|
|
@@ -142682,6 +142919,16 @@ var init_store = __esm({
|
|
|
142682
142919
|
this.db.prepare(
|
|
142683
142920
|
"UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
|
|
142684
142921
|
).run(id, input.projectId);
|
|
142922
|
+
const snapshotFileRows = this.db.prepare(`
|
|
142923
|
+
SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
|
|
142924
|
+
`).all(input.projectId);
|
|
142925
|
+
const insertSnapshotFile = this.db.prepare(`
|
|
142926
|
+
INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
|
|
142927
|
+
VALUES (?, ?, ?, ?, ?)
|
|
142928
|
+
`);
|
|
142929
|
+
for (const file of snapshotFileRows) {
|
|
142930
|
+
insertSnapshotFile.run(id, file.projectId, file.id, file.path, file.contentHash);
|
|
142931
|
+
}
|
|
142685
142932
|
snapshot = {
|
|
142686
142933
|
...input,
|
|
142687
142934
|
id,
|
|
@@ -142847,8 +143094,8 @@ __export(lite_provider_exports, {
|
|
|
142847
143094
|
import { createHash as createHash7 } from "crypto";
|
|
142848
143095
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
142849
143096
|
import { join as join4, relative } from "path";
|
|
142850
|
-
function hashText(
|
|
142851
|
-
return createHash7("sha256").update(
|
|
143097
|
+
function hashText(text2) {
|
|
143098
|
+
return createHash7("sha256").update(text2).digest("hex");
|
|
142852
143099
|
}
|
|
142853
143100
|
function extension2(path19) {
|
|
142854
143101
|
const index = path19.lastIndexOf(".");
|
|
@@ -142892,19 +143139,19 @@ function walk(root, exclude, maxFiles) {
|
|
|
142892
143139
|
visit(root);
|
|
142893
143140
|
return out;
|
|
142894
143141
|
}
|
|
142895
|
-
function lineOf(
|
|
142896
|
-
return
|
|
143142
|
+
function lineOf(text2, index) {
|
|
143143
|
+
return text2.slice(0, index).split(/\r?\n/).length;
|
|
142897
143144
|
}
|
|
142898
|
-
function extractSymbols(projectId, file,
|
|
143145
|
+
function extractSymbols(projectId, file, text2, indexedAt) {
|
|
142899
143146
|
const symbols = [];
|
|
142900
143147
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
142901
143148
|
const patterns = profile?.symbols ?? [];
|
|
142902
143149
|
for (const { kind, re } of patterns) {
|
|
142903
143150
|
re.lastIndex = 0;
|
|
142904
|
-
for (const match2 of
|
|
143151
|
+
for (const match2 of text2.matchAll(re)) {
|
|
142905
143152
|
const name = match2[1];
|
|
142906
143153
|
if (!name || name.includes("\n")) continue;
|
|
142907
|
-
const startLine = lineOf(
|
|
143154
|
+
const startLine = lineOf(text2, match2.index ?? 0);
|
|
142908
143155
|
const id = makeCodeSymbolId({ projectId, path: file.path, qualifiedName: name, kind });
|
|
142909
143156
|
symbols.push({
|
|
142910
143157
|
id,
|
|
@@ -142924,13 +143171,13 @@ function extractSymbols(projectId, file, text, indexedAt) {
|
|
|
142924
143171
|
}
|
|
142925
143172
|
return symbols;
|
|
142926
143173
|
}
|
|
142927
|
-
function extractImportEdges(projectId, file,
|
|
143174
|
+
function extractImportEdges(projectId, file, text2, indexedAt) {
|
|
142928
143175
|
const edges = [];
|
|
142929
143176
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
142930
143177
|
const imports = profile?.imports ?? [];
|
|
142931
143178
|
for (const re of imports) {
|
|
142932
143179
|
re.lastIndex = 0;
|
|
142933
|
-
for (const match2 of
|
|
143180
|
+
for (const match2 of text2.matchAll(re)) {
|
|
142934
143181
|
const target = (match2[1] ?? "").trim();
|
|
142935
143182
|
if (!target) continue;
|
|
142936
143183
|
if (target.includes("\n")) {
|
|
@@ -142965,14 +143212,14 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
142965
143212
|
function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
142966
143213
|
const rel = normalizeCodePath(relative(projectRoot, abs));
|
|
142967
143214
|
try {
|
|
142968
|
-
const
|
|
143215
|
+
const text2 = readFileSync6(abs, "utf-8");
|
|
142969
143216
|
const stat4 = fileStat ?? statSync3(abs);
|
|
142970
143217
|
const file = {
|
|
142971
143218
|
id: makeCodeFileId(projectId, rel),
|
|
142972
143219
|
projectId,
|
|
142973
143220
|
path: rel,
|
|
142974
143221
|
language: languageForPath(rel),
|
|
142975
|
-
contentHash: hashText(
|
|
143222
|
+
contentHash: hashText(text2),
|
|
142976
143223
|
// Preserve filesystem precision. Rounding here made same-size edits in
|
|
142977
143224
|
// a short Windows timestamp window indistinguishable to refresh.
|
|
142978
143225
|
mtimeMs: Number(stat4.mtimeMs),
|
|
@@ -142982,8 +143229,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
|
142982
143229
|
return {
|
|
142983
143230
|
delta: {
|
|
142984
143231
|
file,
|
|
142985
|
-
symbols: extractSymbols(projectId, file,
|
|
142986
|
-
edges: extractImportEdges(projectId, file,
|
|
143232
|
+
symbols: extractSymbols(projectId, file, text2, indexedAt),
|
|
143233
|
+
edges: extractImportEdges(projectId, file, text2, indexedAt)
|
|
142987
143234
|
},
|
|
142988
143235
|
unreadable: false
|
|
142989
143236
|
};
|
|
@@ -143262,18 +143509,18 @@ __export(binder_exports, {
|
|
|
143262
143509
|
function observationText(obs) {
|
|
143263
143510
|
return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
|
|
143264
143511
|
}
|
|
143265
|
-
function mentionsSymbol(
|
|
143512
|
+
function mentionsSymbol(text2, symbol) {
|
|
143266
143513
|
const name = symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
143267
|
-
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(
|
|
143514
|
+
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
|
|
143268
143515
|
}
|
|
143269
|
-
function identifierCandidates(
|
|
143270
|
-
return [...new Set(
|
|
143516
|
+
function identifierCandidates(text2) {
|
|
143517
|
+
return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
|
|
143271
143518
|
}
|
|
143272
|
-
function codeIdentifierCandidates(
|
|
143519
|
+
function codeIdentifierCandidates(text2) {
|
|
143273
143520
|
const explicit = /* @__PURE__ */ new Set();
|
|
143274
|
-
for (const match2 of
|
|
143275
|
-
for (const match2 of
|
|
143276
|
-
return identifierCandidates(
|
|
143521
|
+
for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
|
|
143522
|
+
for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
|
|
143523
|
+
return identifierCandidates(text2).filter((candidate) => explicit.has(candidate) || candidate.includes("::") || /[!?=]$/.test(candidate) || /^[A-Z]/.test(candidate) || /[_$]/.test(candidate) || /[a-z0-9][A-Z]/.test(candidate) || /[A-Z]{2}/.test(candidate));
|
|
143277
143524
|
}
|
|
143278
143525
|
function fileRef(projectId, obs, file) {
|
|
143279
143526
|
return {
|
|
@@ -143303,7 +143550,7 @@ function symbolRef(projectId, obs, file, symbol) {
|
|
|
143303
143550
|
}
|
|
143304
143551
|
function resolveObservationCodeRefs(obs, lookup2) {
|
|
143305
143552
|
const refs = /* @__PURE__ */ new Map();
|
|
143306
|
-
const
|
|
143553
|
+
const text2 = observationText(obs);
|
|
143307
143554
|
const candidateFiles = /* @__PURE__ */ new Map();
|
|
143308
143555
|
for (const rawPath of obs.filesModified ?? []) {
|
|
143309
143556
|
const file = lookup2.findFile(normalizeCodePath(rawPath));
|
|
@@ -143313,7 +143560,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
143313
143560
|
refs.set(ref.id, ref);
|
|
143314
143561
|
}
|
|
143315
143562
|
const hintedFileIds = new Set(candidateFiles.keys());
|
|
143316
|
-
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(
|
|
143563
|
+
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
|
|
143317
143564
|
const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
|
|
143318
143565
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
143319
143566
|
for (const symbol of symbols) {
|
|
@@ -143324,7 +143571,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
143324
143571
|
for (const group of symbolsByName.values()) {
|
|
143325
143572
|
const candidates = group.length === 1 ? group : [];
|
|
143326
143573
|
for (const symbol of candidates) {
|
|
143327
|
-
if (!mentionsSymbol(
|
|
143574
|
+
if (!mentionsSymbol(text2, symbol)) continue;
|
|
143328
143575
|
const file = candidateFiles.get(symbol.fileId) ?? lookup2.findFile(symbol.path);
|
|
143329
143576
|
if (!file) continue;
|
|
143330
143577
|
candidateFiles.set(file.id, file);
|
|
@@ -144052,8 +144299,8 @@ function taskTokens(task) {
|
|
|
144052
144299
|
return normalizedTokens(task);
|
|
144053
144300
|
}
|
|
144054
144301
|
function scoreClaim(claim, tokens) {
|
|
144055
|
-
const
|
|
144056
|
-
const words = normalizedTokens(
|
|
144302
|
+
const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
|
|
144303
|
+
const words = normalizedTokens(text2);
|
|
144057
144304
|
let matches = 0;
|
|
144058
144305
|
for (const token of tokens) {
|
|
144059
144306
|
if (words.has(token)) matches += 1;
|
|
@@ -144949,29 +145196,141 @@ var init_workflow_store = __esm({
|
|
|
144949
145196
|
}
|
|
144950
145197
|
});
|
|
144951
145198
|
|
|
145199
|
+
// src/knowledge/outcome-types.ts
|
|
145200
|
+
var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
|
|
145201
|
+
var init_outcome_types = __esm({
|
|
145202
|
+
"src/knowledge/outcome-types.ts"() {
|
|
145203
|
+
"use strict";
|
|
145204
|
+
init_esm_shims();
|
|
145205
|
+
MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
|
|
145206
|
+
MEMORY_OUTCOME_SIGNAL_KINDS = [
|
|
145207
|
+
"verification-passed",
|
|
145208
|
+
"verification-failed",
|
|
145209
|
+
"verified-reuse",
|
|
145210
|
+
"user-pin",
|
|
145211
|
+
"user-correction",
|
|
145212
|
+
"source-changed",
|
|
145213
|
+
"conflict-confirmed",
|
|
145214
|
+
"manual-review"
|
|
145215
|
+
];
|
|
145216
|
+
}
|
|
145217
|
+
});
|
|
145218
|
+
|
|
145219
|
+
// src/knowledge/outcome-store.ts
|
|
145220
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
145221
|
+
function optionalText4(value) {
|
|
145222
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
145223
|
+
}
|
|
145224
|
+
function text(value, field, max = 1e3) {
|
|
145225
|
+
const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
|
|
145226
|
+
if (!safe) throw new Error("Outcome signal " + field + " is required.");
|
|
145227
|
+
if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
|
|
145228
|
+
return safe;
|
|
145229
|
+
}
|
|
145230
|
+
function oneOf(value, values, field) {
|
|
145231
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
145232
|
+
throw new Error("Outcome signal " + field + " is invalid.");
|
|
145233
|
+
}
|
|
145234
|
+
return value;
|
|
145235
|
+
}
|
|
145236
|
+
function rowToSignal(row) {
|
|
145237
|
+
return {
|
|
145238
|
+
id: row.id,
|
|
145239
|
+
projectId: row.projectId,
|
|
145240
|
+
candidateKind: row.candidateKind,
|
|
145241
|
+
candidateId: row.candidateId,
|
|
145242
|
+
kind: row.kind,
|
|
145243
|
+
sourceRef: row.sourceRef,
|
|
145244
|
+
...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
|
|
145245
|
+
...optionalText4(row.detail) ? { detail: row.detail } : {},
|
|
145246
|
+
observedAt: row.observedAt
|
|
145247
|
+
};
|
|
145248
|
+
}
|
|
145249
|
+
var OutcomeStore;
|
|
145250
|
+
var init_outcome_store = __esm({
|
|
145251
|
+
"src/knowledge/outcome-store.ts"() {
|
|
145252
|
+
"use strict";
|
|
145253
|
+
init_esm_shims();
|
|
145254
|
+
init_secret_filter();
|
|
145255
|
+
init_sqlite_db();
|
|
145256
|
+
init_outcome_types();
|
|
145257
|
+
OutcomeStore = class {
|
|
145258
|
+
db = null;
|
|
145259
|
+
async init(dataDir) {
|
|
145260
|
+
this.db = getDatabase(dataDir);
|
|
145261
|
+
}
|
|
145262
|
+
record(input) {
|
|
145263
|
+
const signal = {
|
|
145264
|
+
id: randomUUID10(),
|
|
145265
|
+
projectId: text(input.projectId, "project id"),
|
|
145266
|
+
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
145267
|
+
candidateId: text(input.candidateId, "candidate id"),
|
|
145268
|
+
kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
|
|
145269
|
+
sourceRef: text(input.sourceRef, "source reference"),
|
|
145270
|
+
...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
|
|
145271
|
+
...input.detail ? { detail: text(input.detail, "detail") } : {},
|
|
145272
|
+
observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
145273
|
+
};
|
|
145274
|
+
this.db.prepare(`
|
|
145275
|
+
INSERT INTO memory_outcome_signals (
|
|
145276
|
+
id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
|
|
145277
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
145278
|
+
`).run(
|
|
145279
|
+
signal.id,
|
|
145280
|
+
signal.projectId,
|
|
145281
|
+
signal.candidateKind,
|
|
145282
|
+
signal.candidateId,
|
|
145283
|
+
signal.kind,
|
|
145284
|
+
signal.sourceRef,
|
|
145285
|
+
signal.snapshotId ?? null,
|
|
145286
|
+
signal.detail ?? null,
|
|
145287
|
+
signal.observedAt
|
|
145288
|
+
);
|
|
145289
|
+
return signal;
|
|
145290
|
+
}
|
|
145291
|
+
latestForCandidates(projectId, candidateKind, candidateIds) {
|
|
145292
|
+
const ids = [...new Set(candidateIds.filter(Boolean))];
|
|
145293
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
145294
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
145295
|
+
const rows = this.db.prepare(`
|
|
145296
|
+
SELECT * FROM memory_outcome_signals
|
|
145297
|
+
WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
|
|
145298
|
+
ORDER BY observedAt DESC, id DESC
|
|
145299
|
+
`).all(projectId, candidateKind, ...ids);
|
|
145300
|
+
const latest = /* @__PURE__ */ new Map();
|
|
145301
|
+
for (const row of rows) {
|
|
145302
|
+
const signal = rowToSignal(row);
|
|
145303
|
+
if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
|
|
145304
|
+
}
|
|
145305
|
+
return latest;
|
|
145306
|
+
}
|
|
145307
|
+
};
|
|
145308
|
+
}
|
|
145309
|
+
});
|
|
145310
|
+
|
|
144952
145311
|
// src/codegraph/task-lens.ts
|
|
144953
|
-
function containsTaskKeyword(
|
|
145312
|
+
function containsTaskKeyword(text2, keyword) {
|
|
144954
145313
|
const matcher = /^[a-z0-9_-]+$/i.test(keyword) ? new RegExp(`(^|[^a-z0-9_-])${keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}(?=[^a-z0-9_-]|$)`, "gi") : new RegExp(keyword.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
144955
145314
|
let match2;
|
|
144956
|
-
while ((match2 = matcher.exec(
|
|
145315
|
+
while ((match2 = matcher.exec(text2)) !== null) {
|
|
144957
145316
|
const keywordIndex = match2.index + (match2[1]?.length ?? 0);
|
|
144958
|
-
if (!isNegatedTaskKeyword(
|
|
145317
|
+
if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
|
|
144959
145318
|
}
|
|
144960
145319
|
return false;
|
|
144961
145320
|
}
|
|
144962
|
-
function isNegatedTaskKeyword(
|
|
145321
|
+
function isNegatedTaskKeyword(text2, keywordIndex) {
|
|
144963
145322
|
const boundary = Math.max(
|
|
144964
|
-
|
|
144965
|
-
|
|
144966
|
-
|
|
144967
|
-
|
|
144968
|
-
|
|
144969
|
-
|
|
144970
|
-
|
|
144971
|
-
|
|
144972
|
-
|
|
145323
|
+
text2.lastIndexOf(".", keywordIndex - 1),
|
|
145324
|
+
text2.lastIndexOf("!", keywordIndex - 1),
|
|
145325
|
+
text2.lastIndexOf("?", keywordIndex - 1),
|
|
145326
|
+
text2.lastIndexOf(";", keywordIndex - 1),
|
|
145327
|
+
text2.lastIndexOf("\n", keywordIndex - 1),
|
|
145328
|
+
text2.lastIndexOf("\u3002", keywordIndex - 1),
|
|
145329
|
+
text2.lastIndexOf("\uFF01", keywordIndex - 1),
|
|
145330
|
+
text2.lastIndexOf("\uFF1F", keywordIndex - 1),
|
|
145331
|
+
text2.lastIndexOf("\uFF1B", keywordIndex - 1)
|
|
144973
145332
|
);
|
|
144974
|
-
let prefix =
|
|
145333
|
+
let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
|
|
144975
145334
|
const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
|
|
144976
145335
|
let contrastMatch;
|
|
144977
145336
|
let contrastEnd = -1;
|
|
@@ -145030,7 +145389,7 @@ function requiredText(data, key) {
|
|
|
145030
145389
|
}
|
|
145031
145390
|
return value.trim();
|
|
145032
145391
|
}
|
|
145033
|
-
function
|
|
145392
|
+
function optionalText5(data, key) {
|
|
145034
145393
|
const value = data[key];
|
|
145035
145394
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
145036
145395
|
if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
|
|
@@ -145073,11 +145432,11 @@ function phaseFromValue(value, index) {
|
|
|
145073
145432
|
}
|
|
145074
145433
|
const data = value;
|
|
145075
145434
|
const title = requiredText(data, "title");
|
|
145076
|
-
const phaseId =
|
|
145435
|
+
const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
|
|
145077
145436
|
return {
|
|
145078
145437
|
id: phaseId,
|
|
145079
145438
|
title,
|
|
145080
|
-
instructions:
|
|
145439
|
+
instructions: optionalText5(data, "instructions") ?? "",
|
|
145081
145440
|
branches: optionalStringArray(data, "branches"),
|
|
145082
145441
|
expectedOutputs: optionalStringArray(data, "expectedOutputs"),
|
|
145083
145442
|
verificationGates: optionalStringArray(data, "verificationGates")
|
|
@@ -145186,7 +145545,7 @@ function parsedWorkflow(data, body, input) {
|
|
|
145186
145545
|
id: requiredText(data, "id"),
|
|
145187
145546
|
workspaceId: input.workspaceId,
|
|
145188
145547
|
title: requiredText(data, "title"),
|
|
145189
|
-
description:
|
|
145548
|
+
description: optionalText5(data, "description") ?? "",
|
|
145190
145549
|
status: optionalStatus(data),
|
|
145191
145550
|
version: optionalNumber(data, "version", 1),
|
|
145192
145551
|
taskLenses: optionalStringArray(data, "taskLenses"),
|
|
@@ -145205,9 +145564,9 @@ function parsedWorkflow(data, body, input) {
|
|
|
145205
145564
|
sourcePath: normalizeSourcePath(input.sourcePath),
|
|
145206
145565
|
sourceHash: "",
|
|
145207
145566
|
contentHash: input.contentHash,
|
|
145208
|
-
createdAt:
|
|
145209
|
-
updatedAt:
|
|
145210
|
-
...
|
|
145567
|
+
createdAt: optionalText5(data, "createdAt") ?? now2(),
|
|
145568
|
+
updatedAt: optionalText5(data, "updatedAt") ?? now2(),
|
|
145569
|
+
...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
|
|
145211
145570
|
};
|
|
145212
145571
|
if (candidate.phases.length === 0) {
|
|
145213
145572
|
throw new Error("workflow must contain at least one phase or a non-empty body");
|
|
@@ -145306,11 +145665,11 @@ async function syncCanonicalWorkflows(workspace) {
|
|
|
145306
145665
|
return { workflows, errors };
|
|
145307
145666
|
}
|
|
145308
145667
|
function inferTaskLenses(value) {
|
|
145309
|
-
const
|
|
145310
|
-
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) =>
|
|
145668
|
+
const text2 = value.toLowerCase();
|
|
145669
|
+
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
|
|
145311
145670
|
}
|
|
145312
145671
|
function taskScore(workflow, task) {
|
|
145313
|
-
const
|
|
145672
|
+
const text2 = task.toLowerCase();
|
|
145314
145673
|
let score = 0;
|
|
145315
145674
|
const reasons = [];
|
|
145316
145675
|
const matchedLenses = /* @__PURE__ */ new Set();
|
|
@@ -145577,7 +145936,31 @@ async function recordWorkflowRun(input) {
|
|
|
145577
145936
|
throw new Error("Workflow was not found for this workspace");
|
|
145578
145937
|
}
|
|
145579
145938
|
if (!input.run.task.trim()) throw new Error("Workflow run task is required");
|
|
145580
|
-
|
|
145939
|
+
const run = store.recordRun(input.run);
|
|
145940
|
+
const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
|
|
145941
|
+
if (!kind) return run;
|
|
145942
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
145943
|
+
evidence.set(workflow.id, "workflow");
|
|
145944
|
+
for (const reference of run.selectedEvidence) {
|
|
145945
|
+
const match2 = /^(claim|durable):(.+)$/.exec(reference);
|
|
145946
|
+
if (!match2) continue;
|
|
145947
|
+
evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
|
|
145948
|
+
}
|
|
145949
|
+
const outcomes = new OutcomeStore();
|
|
145950
|
+
await outcomes.init(workflowStoreDataDir(input.workspace));
|
|
145951
|
+
for (const [candidateId, candidateKind] of evidence) {
|
|
145952
|
+
outcomes.record({
|
|
145953
|
+
projectId: run.projectId,
|
|
145954
|
+
candidateKind,
|
|
145955
|
+
candidateId,
|
|
145956
|
+
kind,
|
|
145957
|
+
sourceRef: "workflow-run:" + run.id,
|
|
145958
|
+
...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
|
|
145959
|
+
...run.failureReason ? { detail: run.failureReason } : {},
|
|
145960
|
+
observedAt: run.completedAt ?? run.startedAt
|
|
145961
|
+
});
|
|
145962
|
+
}
|
|
145963
|
+
return run;
|
|
145581
145964
|
}
|
|
145582
145965
|
async function selectWorkspaceWorkflows(input) {
|
|
145583
145966
|
const synced = await syncCanonicalWorkflows(input.workspace);
|
|
@@ -145602,6 +145985,7 @@ var init_workflows2 = __esm({
|
|
|
145602
145985
|
init_workflow_sync();
|
|
145603
145986
|
init_workspace();
|
|
145604
145987
|
init_workflow_store();
|
|
145988
|
+
init_outcome_store();
|
|
145605
145989
|
init_task_lens();
|
|
145606
145990
|
KNOWN_AGENTS = [
|
|
145607
145991
|
"windsurf",
|