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;
|
|
@@ -6926,6 +6964,7 @@ __export(store_exports, {
|
|
|
6926
6964
|
CodeGraphStore: () => CodeGraphStore
|
|
6927
6965
|
});
|
|
6928
6966
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
6967
|
+
import { posix as pathPosix } from "path";
|
|
6929
6968
|
function rowToFile(row) {
|
|
6930
6969
|
return {
|
|
6931
6970
|
id: row.id,
|
|
@@ -6976,6 +7015,26 @@ function rowToEdge(row) {
|
|
|
6976
7015
|
...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
|
|
6977
7016
|
};
|
|
6978
7017
|
}
|
|
7018
|
+
function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
|
|
7019
|
+
const target = evidence?.trim().replace(/\\/g, "/");
|
|
7020
|
+
if (!target?.startsWith(".")) return void 0;
|
|
7021
|
+
const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
|
|
7022
|
+
if (!base || base === ".." || base.startsWith("../")) return void 0;
|
|
7023
|
+
const candidates = [base];
|
|
7024
|
+
const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
|
|
7025
|
+
const hasExtension = Boolean(extensionMatch);
|
|
7026
|
+
if (!hasExtension) {
|
|
7027
|
+
const extensions = [...new Set([...fileByPath.keys()].map((path18) => path18.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
|
|
7028
|
+
for (const extension3 of extensions) {
|
|
7029
|
+
candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
|
|
7030
|
+
}
|
|
7031
|
+
} else {
|
|
7032
|
+
const sourceStem = base.slice(0, -extensionMatch[1].length);
|
|
7033
|
+
const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
|
|
7034
|
+
for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
|
|
7035
|
+
}
|
|
7036
|
+
return candidates.map((candidate) => fileByPath.get(candidate)).find((file) => Boolean(file));
|
|
7037
|
+
}
|
|
6979
7038
|
function rowToRef(row) {
|
|
6980
7039
|
return {
|
|
6981
7040
|
id: row.id,
|
|
@@ -7036,6 +7095,18 @@ function rowToSnapshot(row) {
|
|
|
7036
7095
|
...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
|
|
7037
7096
|
};
|
|
7038
7097
|
}
|
|
7098
|
+
function rowToSnapshotFile(row) {
|
|
7099
|
+
return {
|
|
7100
|
+
snapshotId: row.snapshotId,
|
|
7101
|
+
projectId: row.projectId,
|
|
7102
|
+
fileId: row.fileId,
|
|
7103
|
+
path: row.path,
|
|
7104
|
+
contentHash: row.contentHash
|
|
7105
|
+
};
|
|
7106
|
+
}
|
|
7107
|
+
function snapshotIsIncomplete(snapshot) {
|
|
7108
|
+
return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
|
|
7109
|
+
}
|
|
7039
7110
|
var CodeGraphStore;
|
|
7040
7111
|
var init_store = __esm({
|
|
7041
7112
|
"src/codegraph/store.ts"() {
|
|
@@ -7207,6 +7278,7 @@ var init_store = __esm({
|
|
|
7207
7278
|
}
|
|
7208
7279
|
});
|
|
7209
7280
|
tx();
|
|
7281
|
+
this.reconcileLocalImportTargets(projectId);
|
|
7210
7282
|
}
|
|
7211
7283
|
/**
|
|
7212
7284
|
* Reconcile only files whose source changed plus files that disappeared.
|
|
@@ -7216,7 +7288,10 @@ var init_store = __esm({
|
|
|
7216
7288
|
const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
|
|
7217
7289
|
const metadataOnly = (input.metadataOnly ?? []).filter((file) => file.projectId === projectId);
|
|
7218
7290
|
const removedFileIds = input.removedFileIds ?? [];
|
|
7219
|
-
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0)
|
|
7291
|
+
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
|
|
7292
|
+
this.reconcileLocalImportTargets(projectId);
|
|
7293
|
+
return;
|
|
7294
|
+
}
|
|
7220
7295
|
const staleRefsForFile = this.db.prepare(`
|
|
7221
7296
|
UPDATE observation_code_refs
|
|
7222
7297
|
SET status = 'stale', updatedAt = ?
|
|
@@ -7226,9 +7301,18 @@ var init_store = __esm({
|
|
|
7226
7301
|
)
|
|
7227
7302
|
)
|
|
7228
7303
|
`);
|
|
7229
|
-
const
|
|
7304
|
+
const deleteEdgesFromFile = this.db.prepare(`
|
|
7305
|
+
DELETE FROM code_edges
|
|
7306
|
+
WHERE projectId = ? AND fromFileId = ?
|
|
7307
|
+
`);
|
|
7308
|
+
const clearImportTargetsForFile = this.db.prepare(`
|
|
7309
|
+
UPDATE code_edges
|
|
7310
|
+
SET toFileId = NULL
|
|
7311
|
+
WHERE projectId = ? AND toFileId = ? AND type = 'imports'
|
|
7312
|
+
`);
|
|
7313
|
+
const deleteOtherIncomingEdgesForFile = this.db.prepare(`
|
|
7230
7314
|
DELETE FROM code_edges
|
|
7231
|
-
WHERE projectId = ? AND
|
|
7315
|
+
WHERE projectId = ? AND toFileId = ? AND type != 'imports'
|
|
7232
7316
|
`);
|
|
7233
7317
|
const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
|
|
7234
7318
|
const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
|
|
@@ -7265,14 +7349,18 @@ var init_store = __esm({
|
|
|
7265
7349
|
const staleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7266
7350
|
for (const fileId of removedFileIds) {
|
|
7267
7351
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
7268
|
-
|
|
7352
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
7353
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
7354
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
7269
7355
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
7270
7356
|
deleteFile.run(projectId, fileId);
|
|
7271
7357
|
}
|
|
7272
7358
|
for (const delta of changed) {
|
|
7273
7359
|
const fileId = delta.file.id;
|
|
7274
7360
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
7275
|
-
|
|
7361
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
7362
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
7363
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
7276
7364
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
7277
7365
|
writeFile5(delta.file);
|
|
7278
7366
|
for (const symbol of delta.symbols) {
|
|
@@ -7310,6 +7398,7 @@ var init_store = __esm({
|
|
|
7310
7398
|
for (const file of metadataOnly) writeFile5(file);
|
|
7311
7399
|
});
|
|
7312
7400
|
tx();
|
|
7401
|
+
this.reconcileLocalImportTargets(projectId);
|
|
7313
7402
|
}
|
|
7314
7403
|
upsertObservationRefs(refs) {
|
|
7315
7404
|
if (refs.length === 0) return;
|
|
@@ -7371,6 +7460,25 @@ var init_store = __esm({
|
|
|
7371
7460
|
});
|
|
7372
7461
|
tx();
|
|
7373
7462
|
}
|
|
7463
|
+
/**
|
|
7464
|
+
* Lite import extraction records the original import text first. Resolve only
|
|
7465
|
+
* local relative imports against the current index after each refresh, so an
|
|
7466
|
+
* added or removed target cannot leave a fabricated file-to-file relation.
|
|
7467
|
+
*/
|
|
7468
|
+
reconcileLocalImportTargets(projectId) {
|
|
7469
|
+
const fileById = new Map(this.listFiles(projectId).map((file) => [file.id, file]));
|
|
7470
|
+
const fileByPath = new Map([...fileById.values()].map((file) => [file.path, file]));
|
|
7471
|
+
const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
|
|
7472
|
+
const tx = this.db.transaction(() => {
|
|
7473
|
+
for (const edge of this.listEdges(projectId)) {
|
|
7474
|
+
if (edge.type !== "imports" || !edge.fromFileId) continue;
|
|
7475
|
+
const source = fileById.get(edge.fromFileId);
|
|
7476
|
+
const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
|
|
7477
|
+
update2.run(target?.id ?? null, edge.id);
|
|
7478
|
+
}
|
|
7479
|
+
});
|
|
7480
|
+
tx();
|
|
7481
|
+
}
|
|
7374
7482
|
getFile(projectId, path18) {
|
|
7375
7483
|
const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path18));
|
|
7376
7484
|
return row ? rowToFile(row) : null;
|
|
@@ -7445,6 +7553,18 @@ var init_store = __esm({
|
|
|
7445
7553
|
ORDER BY observationId, status, id
|
|
7446
7554
|
`).all(projectId).map(rowToRef);
|
|
7447
7555
|
}
|
|
7556
|
+
/** Count distinct observations whose binding to these exact files is stale. */
|
|
7557
|
+
countStaleObservationRefsForFiles(projectId, fileIds) {
|
|
7558
|
+
const ids = [...new Set(fileIds.filter(Boolean))];
|
|
7559
|
+
if (ids.length === 0) return 0;
|
|
7560
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
7561
|
+
const row = this.db.prepare(`
|
|
7562
|
+
SELECT COUNT(DISTINCT observationId) AS count
|
|
7563
|
+
FROM observation_code_refs
|
|
7564
|
+
WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
|
|
7565
|
+
`).get(projectId, ...ids);
|
|
7566
|
+
return Number(row?.count ?? 0);
|
|
7567
|
+
}
|
|
7448
7568
|
listReferencedSymbols(projectId) {
|
|
7449
7569
|
return this.db.prepare(`
|
|
7450
7570
|
SELECT DISTINCT symbols.*
|
|
@@ -7466,6 +7586,94 @@ var init_store = __esm({
|
|
|
7466
7586
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
7467
7587
|
).all(projectId, safeLimit).map(rowToSnapshot);
|
|
7468
7588
|
}
|
|
7589
|
+
listSnapshotFiles(snapshotId) {
|
|
7590
|
+
return this.db.prepare(`
|
|
7591
|
+
SELECT snapshotId, projectId, fileId, path, contentHash
|
|
7592
|
+
FROM code_state_snapshot_files
|
|
7593
|
+
WHERE snapshotId = ?
|
|
7594
|
+
ORDER BY path
|
|
7595
|
+
`).all(snapshotId).map(rowToSnapshotFile);
|
|
7596
|
+
}
|
|
7597
|
+
diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
|
|
7598
|
+
const snapshots = this.db.prepare(`
|
|
7599
|
+
SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
|
|
7600
|
+
`).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
|
|
7601
|
+
if (snapshots.length !== 2) {
|
|
7602
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
|
|
7603
|
+
}
|
|
7604
|
+
if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
|
|
7605
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
|
|
7606
|
+
}
|
|
7607
|
+
if (snapshots.some(snapshotIsIncomplete)) {
|
|
7608
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
|
|
7609
|
+
}
|
|
7610
|
+
const before = this.listSnapshotFiles(fromSnapshotId);
|
|
7611
|
+
const after = this.listSnapshotFiles(toSnapshotId);
|
|
7612
|
+
if (before.length === 0 || after.length === 0) {
|
|
7613
|
+
return {
|
|
7614
|
+
projectId,
|
|
7615
|
+
fromSnapshotId,
|
|
7616
|
+
toSnapshotId,
|
|
7617
|
+
available: false,
|
|
7618
|
+
reason: "legacy-snapshot-without-manifest",
|
|
7619
|
+
changes: []
|
|
7620
|
+
};
|
|
7621
|
+
}
|
|
7622
|
+
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
7623
|
+
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
7624
|
+
const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
|
|
7625
|
+
const changes = [];
|
|
7626
|
+
for (const path18 of paths) {
|
|
7627
|
+
const oldFile = beforeByPath.get(path18);
|
|
7628
|
+
const newFile = afterByPath.get(path18);
|
|
7629
|
+
if (!oldFile && newFile) {
|
|
7630
|
+
changes.push({ path: path18, kind: "added", afterHash: newFile.contentHash });
|
|
7631
|
+
} else if (oldFile && !newFile) {
|
|
7632
|
+
changes.push({ path: path18, kind: "removed", beforeHash: oldFile.contentHash });
|
|
7633
|
+
} else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
|
|
7634
|
+
changes.push({ path: path18, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
|
|
7635
|
+
}
|
|
7636
|
+
}
|
|
7637
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
|
|
7638
|
+
}
|
|
7639
|
+
impactSlice(projectId, changedPaths, maxRelations = 24) {
|
|
7640
|
+
const safeLimit = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
|
|
7641
|
+
const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
|
|
7642
|
+
const files = this.listFiles(projectId);
|
|
7643
|
+
const fileById = new Map(files.map((file) => [file.id, file.path]));
|
|
7644
|
+
const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol) => [symbol.id, symbol.fileId]));
|
|
7645
|
+
const changedIds = new Set(files.filter((file) => normalizedPaths.includes(file.path)).map((file) => file.id));
|
|
7646
|
+
const direct = /* @__PURE__ */ new Set();
|
|
7647
|
+
let relationCount = 0;
|
|
7648
|
+
let truncated = false;
|
|
7649
|
+
for (const edge of this.listEdges(projectId)) {
|
|
7650
|
+
const endpoints = [
|
|
7651
|
+
edge.fromFileId,
|
|
7652
|
+
edge.toFileId,
|
|
7653
|
+
edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
|
|
7654
|
+
edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
|
|
7655
|
+
].filter((id) => Boolean(id));
|
|
7656
|
+
if (!endpoints.some((id) => changedIds.has(id))) continue;
|
|
7657
|
+
const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path18) => Boolean(path18));
|
|
7658
|
+
if (relatedPaths.length === 0) continue;
|
|
7659
|
+
if (relationCount >= safeLimit) {
|
|
7660
|
+
truncated = true;
|
|
7661
|
+
break;
|
|
7662
|
+
}
|
|
7663
|
+
relationCount += 1;
|
|
7664
|
+
for (const path18 of relatedPaths) direct.add(path18);
|
|
7665
|
+
}
|
|
7666
|
+
const snapshot = this.latestSnapshot(projectId);
|
|
7667
|
+
return {
|
|
7668
|
+
projectId,
|
|
7669
|
+
...snapshot ? { snapshotId: snapshot.id } : {},
|
|
7670
|
+
changedPaths: normalizedPaths,
|
|
7671
|
+
directlyConnectedPaths: [...direct].sort(),
|
|
7672
|
+
relationCount,
|
|
7673
|
+
truncated,
|
|
7674
|
+
provider: snapshot?.provider ?? "lite"
|
|
7675
|
+
};
|
|
7676
|
+
}
|
|
7469
7677
|
/**
|
|
7470
7678
|
* Record a completed scan and mark all current structural facts with its
|
|
7471
7679
|
* epoch. The snapshot is written only after refresh reconciliation succeeds,
|
|
@@ -7507,6 +7715,16 @@ var init_store = __esm({
|
|
|
7507
7715
|
this.db.prepare(
|
|
7508
7716
|
"UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
|
|
7509
7717
|
).run(id, input.projectId);
|
|
7718
|
+
const snapshotFileRows = this.db.prepare(`
|
|
7719
|
+
SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
|
|
7720
|
+
`).all(input.projectId);
|
|
7721
|
+
const insertSnapshotFile = this.db.prepare(`
|
|
7722
|
+
INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
|
|
7723
|
+
VALUES (?, ?, ?, ?, ?)
|
|
7724
|
+
`);
|
|
7725
|
+
for (const file of snapshotFileRows) {
|
|
7726
|
+
insertSnapshotFile.run(id, file.projectId, file.id, file.path, file.contentHash);
|
|
7727
|
+
}
|
|
7510
7728
|
snapshot = {
|
|
7511
7729
|
...input,
|
|
7512
7730
|
id,
|
|
@@ -7547,18 +7765,18 @@ __export(binder_exports, {
|
|
|
7547
7765
|
function observationText(obs) {
|
|
7548
7766
|
return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
|
|
7549
7767
|
}
|
|
7550
|
-
function mentionsSymbol(
|
|
7768
|
+
function mentionsSymbol(text2, symbol) {
|
|
7551
7769
|
const name = symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
7552
|
-
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(
|
|
7770
|
+
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
|
|
7553
7771
|
}
|
|
7554
|
-
function identifierCandidates(
|
|
7555
|
-
return [...new Set(
|
|
7772
|
+
function identifierCandidates(text2) {
|
|
7773
|
+
return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
|
|
7556
7774
|
}
|
|
7557
|
-
function codeIdentifierCandidates(
|
|
7775
|
+
function codeIdentifierCandidates(text2) {
|
|
7558
7776
|
const explicit = /* @__PURE__ */ new Set();
|
|
7559
|
-
for (const match2 of
|
|
7560
|
-
for (const match2 of
|
|
7561
|
-
return identifierCandidates(
|
|
7777
|
+
for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
|
|
7778
|
+
for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
|
|
7779
|
+
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));
|
|
7562
7780
|
}
|
|
7563
7781
|
function fileRef(projectId, obs, file) {
|
|
7564
7782
|
return {
|
|
@@ -7588,7 +7806,7 @@ function symbolRef(projectId, obs, file, symbol) {
|
|
|
7588
7806
|
}
|
|
7589
7807
|
function resolveObservationCodeRefs(obs, lookup2) {
|
|
7590
7808
|
const refs = /* @__PURE__ */ new Map();
|
|
7591
|
-
const
|
|
7809
|
+
const text2 = observationText(obs);
|
|
7592
7810
|
const candidateFiles = /* @__PURE__ */ new Map();
|
|
7593
7811
|
for (const rawPath of obs.filesModified ?? []) {
|
|
7594
7812
|
const file = lookup2.findFile(normalizeCodePath(rawPath));
|
|
@@ -7598,7 +7816,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
7598
7816
|
refs.set(ref.id, ref);
|
|
7599
7817
|
}
|
|
7600
7818
|
const hintedFileIds = new Set(candidateFiles.keys());
|
|
7601
|
-
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(
|
|
7819
|
+
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
|
|
7602
7820
|
const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
|
|
7603
7821
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
7604
7822
|
for (const symbol of symbols) {
|
|
@@ -7609,7 +7827,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
7609
7827
|
for (const group of symbolsByName.values()) {
|
|
7610
7828
|
const candidates = group.length === 1 ? group : [];
|
|
7611
7829
|
for (const symbol of candidates) {
|
|
7612
|
-
if (!mentionsSymbol(
|
|
7830
|
+
if (!mentionsSymbol(text2, symbol)) continue;
|
|
7613
7831
|
const file = candidateFiles.get(symbol.fileId) ?? lookup2.findFile(symbol.path);
|
|
7614
7832
|
if (!file) continue;
|
|
7615
7833
|
candidateFiles.set(file.id, file);
|
|
@@ -9111,9 +9329,9 @@ __export(consolidation_exports, {
|
|
|
9111
9329
|
executeConsolidation: () => executeConsolidation,
|
|
9112
9330
|
findConsolidationCandidates: () => findConsolidationCandidates
|
|
9113
9331
|
});
|
|
9114
|
-
function tokenize(
|
|
9332
|
+
function tokenize(text2) {
|
|
9115
9333
|
return new Set(
|
|
9116
|
-
|
|
9334
|
+
text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t2) => t2.length > 1)
|
|
9117
9335
|
);
|
|
9118
9336
|
}
|
|
9119
9337
|
function jaccardSimilarity(a, b) {
|
|
@@ -18071,8 +18289,8 @@ var init_headers = __esm({
|
|
|
18071
18289
|
});
|
|
18072
18290
|
|
|
18073
18291
|
// packages/ai/dist/utils/sanitize-unicode.js
|
|
18074
|
-
function sanitizeSurrogates(
|
|
18075
|
-
return
|
|
18292
|
+
function sanitizeSurrogates(text2) {
|
|
18293
|
+
return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
18076
18294
|
}
|
|
18077
18295
|
var init_sanitize_unicode = __esm({
|
|
18078
18296
|
"packages/ai/dist/utils/sanitize-unicode.js"() {
|
|
@@ -18554,9 +18772,9 @@ var init_values = __esm({
|
|
|
18554
18772
|
}
|
|
18555
18773
|
return n;
|
|
18556
18774
|
};
|
|
18557
|
-
safeJSON = (
|
|
18775
|
+
safeJSON = (text2) => {
|
|
18558
18776
|
try {
|
|
18559
|
-
return JSON.parse(
|
|
18777
|
+
return JSON.parse(text2);
|
|
18560
18778
|
} catch (err) {
|
|
18561
18779
|
return void 0;
|
|
18562
18780
|
}
|
|
@@ -19719,8 +19937,8 @@ async function defaultParseResponse(client, props) {
|
|
|
19719
19937
|
const json2 = await response.json();
|
|
19720
19938
|
return addRequestID(json2, response);
|
|
19721
19939
|
}
|
|
19722
|
-
const
|
|
19723
|
-
return
|
|
19940
|
+
const text2 = await response.text();
|
|
19941
|
+
return text2;
|
|
19724
19942
|
})();
|
|
19725
19943
|
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
19726
19944
|
retryOfRequestLogID,
|
|
@@ -33079,7 +33297,7 @@ var init_models_generated = __esm({
|
|
|
33079
33297
|
provider: "minimax",
|
|
33080
33298
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
33081
33299
|
reasoning: true,
|
|
33082
|
-
input: ["text", "image"],
|
|
33300
|
+
input: ["text", "image", "video"],
|
|
33083
33301
|
cost: {
|
|
33084
33302
|
input: 0.3,
|
|
33085
33303
|
output: 1.2,
|
|
@@ -33132,7 +33350,7 @@ var init_models_generated = __esm({
|
|
|
33132
33350
|
provider: "minimax-cn",
|
|
33133
33351
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
33134
33352
|
reasoning: true,
|
|
33135
|
-
input: ["text", "image"],
|
|
33353
|
+
input: ["text", "image", "video"],
|
|
33136
33354
|
cost: {
|
|
33137
33355
|
input: 0.3,
|
|
33138
33356
|
output: 1.2,
|
|
@@ -45327,9 +45545,9 @@ var init_values2 = __esm({
|
|
|
45327
45545
|
}
|
|
45328
45546
|
return n;
|
|
45329
45547
|
};
|
|
45330
|
-
safeJSON2 = (
|
|
45548
|
+
safeJSON2 = (text2) => {
|
|
45331
45549
|
try {
|
|
45332
|
-
return JSON.parse(
|
|
45550
|
+
return JSON.parse(text2);
|
|
45333
45551
|
} catch (err) {
|
|
45334
45552
|
return void 0;
|
|
45335
45553
|
}
|
|
@@ -46103,8 +46321,8 @@ async function defaultParseResponse2(client, props) {
|
|
|
46103
46321
|
const json2 = await response.json();
|
|
46104
46322
|
return addRequestID2(json2, response);
|
|
46105
46323
|
}
|
|
46106
|
-
const
|
|
46107
|
-
return
|
|
46324
|
+
const text2 = await response.text();
|
|
46325
|
+
return text2;
|
|
46108
46326
|
})();
|
|
46109
46327
|
loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
|
|
46110
46328
|
retryOfRequestLogID,
|
|
@@ -52407,11 +52625,11 @@ var init_simple_options = __esm({
|
|
|
52407
52625
|
});
|
|
52408
52626
|
|
|
52409
52627
|
// packages/ai/dist/providers/transform-messages.js
|
|
52410
|
-
function
|
|
52628
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52411
52629
|
const result = [];
|
|
52412
52630
|
let previousWasPlaceholder = false;
|
|
52413
52631
|
for (const block of content) {
|
|
52414
|
-
if (block.type ===
|
|
52632
|
+
if (block.type === dropType) {
|
|
52415
52633
|
if (!previousWasPlaceholder) {
|
|
52416
52634
|
result.push({ type: "text", text: placeholder });
|
|
52417
52635
|
}
|
|
@@ -52419,33 +52637,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52419
52637
|
continue;
|
|
52420
52638
|
}
|
|
52421
52639
|
result.push(block);
|
|
52422
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52640
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52423
52641
|
}
|
|
52424
52642
|
return result;
|
|
52425
52643
|
}
|
|
52426
|
-
function
|
|
52427
|
-
|
|
52644
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52645
|
+
const supportsImage = model.input.includes("image");
|
|
52646
|
+
const supportsVideo = model.input.includes("video");
|
|
52647
|
+
if (supportsImage && supportsVideo) {
|
|
52428
52648
|
return messages;
|
|
52429
52649
|
}
|
|
52430
52650
|
return messages.map((msg) => {
|
|
52431
52651
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52432
|
-
|
|
52433
|
-
|
|
52434
|
-
content
|
|
52435
|
-
|
|
52652
|
+
let content = msg.content;
|
|
52653
|
+
if (!supportsImage)
|
|
52654
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52655
|
+
if (!supportsVideo)
|
|
52656
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52657
|
+
return { ...msg, content };
|
|
52436
52658
|
}
|
|
52437
52659
|
if (msg.role === "toolResult") {
|
|
52438
|
-
|
|
52439
|
-
|
|
52440
|
-
content
|
|
52441
|
-
|
|
52660
|
+
let content = msg.content;
|
|
52661
|
+
if (!supportsImage)
|
|
52662
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52663
|
+
if (!supportsVideo)
|
|
52664
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52665
|
+
return { ...msg, content };
|
|
52442
52666
|
}
|
|
52443
52667
|
return msg;
|
|
52444
52668
|
});
|
|
52445
52669
|
}
|
|
52446
52670
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52447
52671
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52448
|
-
const imageAwareMessages =
|
|
52672
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52449
52673
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52450
52674
|
if (msg.role === "user") {
|
|
52451
52675
|
return msg;
|
|
@@ -52557,13 +52781,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52557
52781
|
insertSyntheticToolResults();
|
|
52558
52782
|
return result;
|
|
52559
52783
|
}
|
|
52560
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52784
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52561
52785
|
var init_transform_messages = __esm({
|
|
52562
52786
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52563
52787
|
"use strict";
|
|
52564
52788
|
init_esm_shims();
|
|
52565
52789
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52566
52790
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52791
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52792
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52567
52793
|
}
|
|
52568
52794
|
});
|
|
52569
52795
|
|
|
@@ -52594,8 +52820,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52594
52820
|
};
|
|
52595
52821
|
}
|
|
52596
52822
|
function convertContentBlocks(content) {
|
|
52597
|
-
const
|
|
52598
|
-
if (!
|
|
52823
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52824
|
+
if (!hasMedia) {
|
|
52599
52825
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52600
52826
|
}
|
|
52601
52827
|
const blocks = content.map((block) => {
|
|
@@ -52605,6 +52831,16 @@ function convertContentBlocks(content) {
|
|
|
52605
52831
|
text: sanitizeSurrogates(block.text)
|
|
52606
52832
|
};
|
|
52607
52833
|
}
|
|
52834
|
+
if (block.type === "video") {
|
|
52835
|
+
return {
|
|
52836
|
+
type: "video",
|
|
52837
|
+
source: {
|
|
52838
|
+
type: "base64",
|
|
52839
|
+
media_type: block.mimeType,
|
|
52840
|
+
data: block.data
|
|
52841
|
+
}
|
|
52842
|
+
};
|
|
52843
|
+
}
|
|
52608
52844
|
return {
|
|
52609
52845
|
type: "image",
|
|
52610
52846
|
source: {
|
|
@@ -52618,7 +52854,7 @@ function convertContentBlocks(content) {
|
|
|
52618
52854
|
if (!hasText) {
|
|
52619
52855
|
blocks.unshift({
|
|
52620
52856
|
type: "text",
|
|
52621
|
-
text: "(see attached
|
|
52857
|
+
text: "(see attached media)"
|
|
52622
52858
|
});
|
|
52623
52859
|
}
|
|
52624
52860
|
return blocks;
|
|
@@ -52679,9 +52915,9 @@ function decodeSseLine(line, state) {
|
|
|
52679
52915
|
}
|
|
52680
52916
|
return null;
|
|
52681
52917
|
}
|
|
52682
|
-
function nextLineBreakIndex(
|
|
52683
|
-
const carriageReturnIndex =
|
|
52684
|
-
const newlineIndex =
|
|
52918
|
+
function nextLineBreakIndex(text2) {
|
|
52919
|
+
const carriageReturnIndex = text2.indexOf("\r");
|
|
52920
|
+
const newlineIndex = text2.indexOf("\n");
|
|
52685
52921
|
if (carriageReturnIndex === -1) {
|
|
52686
52922
|
return newlineIndex;
|
|
52687
52923
|
}
|
|
@@ -52690,18 +52926,18 @@ function nextLineBreakIndex(text) {
|
|
|
52690
52926
|
}
|
|
52691
52927
|
return Math.min(carriageReturnIndex, newlineIndex);
|
|
52692
52928
|
}
|
|
52693
|
-
function consumeLine(
|
|
52694
|
-
const lineBreakIndex = nextLineBreakIndex(
|
|
52929
|
+
function consumeLine(text2) {
|
|
52930
|
+
const lineBreakIndex = nextLineBreakIndex(text2);
|
|
52695
52931
|
if (lineBreakIndex === -1) {
|
|
52696
52932
|
return null;
|
|
52697
52933
|
}
|
|
52698
52934
|
let nextIndex = lineBreakIndex + 1;
|
|
52699
|
-
if (
|
|
52935
|
+
if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
|
|
52700
52936
|
nextIndex += 1;
|
|
52701
52937
|
}
|
|
52702
52938
|
return {
|
|
52703
|
-
line:
|
|
52704
|
-
rest:
|
|
52939
|
+
line: text2.slice(0, lineBreakIndex),
|
|
52940
|
+
rest: text2.slice(nextIndex)
|
|
52705
52941
|
};
|
|
52706
52942
|
}
|
|
52707
52943
|
async function* iterateSseMessages(body, signal) {
|
|
@@ -52968,6 +53204,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52968
53204
|
type: "text",
|
|
52969
53205
|
text: sanitizeSurrogates(item.text)
|
|
52970
53206
|
};
|
|
53207
|
+
} else if (item.type === "video") {
|
|
53208
|
+
return {
|
|
53209
|
+
type: "video",
|
|
53210
|
+
source: {
|
|
53211
|
+
type: "base64",
|
|
53212
|
+
media_type: item.mimeType,
|
|
53213
|
+
data: item.data
|
|
53214
|
+
}
|
|
53215
|
+
};
|
|
52971
53216
|
} else {
|
|
52972
53217
|
return {
|
|
52973
53218
|
type: "image",
|
|
@@ -53048,6 +53293,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
53048
53293
|
toolResults.push({
|
|
53049
53294
|
type: "tool_result",
|
|
53050
53295
|
tool_use_id: msg.toolCallId,
|
|
53296
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
53297
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
53051
53298
|
content: convertContentBlocks(msg.content),
|
|
53052
53299
|
is_error: msg.isError
|
|
53053
53300
|
});
|
|
@@ -53074,7 +53321,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
53074
53321
|
if (lastMessage.role === "user") {
|
|
53075
53322
|
if (Array.isArray(lastMessage.content)) {
|
|
53076
53323
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
53077
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
53324
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
53078
53325
|
lastBlock.cache_control = cacheControl;
|
|
53079
53326
|
}
|
|
53080
53327
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -54857,8 +55104,8 @@ var require_common = __commonJS({
|
|
|
54857
55104
|
}
|
|
54858
55105
|
function redactString(obj, key) {
|
|
54859
55106
|
if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
|
|
54860
|
-
const
|
|
54861
|
-
if (/grant_type=/i.test(
|
|
55107
|
+
const text2 = obj[key];
|
|
55108
|
+
if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
|
|
54862
55109
|
obj[key] = REDACT;
|
|
54863
55110
|
}
|
|
54864
55111
|
}
|
|
@@ -61686,8 +61933,8 @@ var init_body = __esm({
|
|
|
61686
61933
|
* @return Promise
|
|
61687
61934
|
*/
|
|
61688
61935
|
async json() {
|
|
61689
|
-
const
|
|
61690
|
-
return JSON.parse(
|
|
61936
|
+
const text2 = await this.text();
|
|
61937
|
+
return JSON.parse(text2);
|
|
61691
61938
|
}
|
|
61692
61939
|
/**
|
|
61693
61940
|
* Decode response as text
|
|
@@ -62839,7 +63086,7 @@ var require_gaxios = __commonJS({
|
|
|
62839
63086
|
var retry_js_1 = require_retry3();
|
|
62840
63087
|
var stream_1 = __require("stream");
|
|
62841
63088
|
var interceptor_js_1 = require_interceptor();
|
|
62842
|
-
var
|
|
63089
|
+
var randomUUID11 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
62843
63090
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
62844
63091
|
var Gaxios = class {
|
|
62845
63092
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -63112,7 +63359,7 @@ var require_gaxios = __commonJS({
|
|
|
63112
63359
|
*/
|
|
63113
63360
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
63114
63361
|
if (opts.multipart?.length) {
|
|
63115
|
-
const boundary = await
|
|
63362
|
+
const boundary = await randomUUID11();
|
|
63116
63363
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
63117
63364
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
63118
63365
|
} else if (shouldDirectlyPassData) {
|
|
@@ -64863,18 +65110,18 @@ var require_parse = __commonJS({
|
|
|
64863
65110
|
n: "\n",
|
|
64864
65111
|
r: "\r",
|
|
64865
65112
|
t: " "
|
|
64866
|
-
},
|
|
65113
|
+
}, text2, error = function(m2) {
|
|
64867
65114
|
throw {
|
|
64868
65115
|
name: "SyntaxError",
|
|
64869
65116
|
message: m2,
|
|
64870
65117
|
at,
|
|
64871
|
-
text
|
|
65118
|
+
text: text2
|
|
64872
65119
|
};
|
|
64873
65120
|
}, next = function(c) {
|
|
64874
65121
|
if (c && c !== ch) {
|
|
64875
65122
|
error("Expected '" + c + "' instead of '" + ch + "'");
|
|
64876
65123
|
}
|
|
64877
|
-
ch =
|
|
65124
|
+
ch = text2.charAt(at);
|
|
64878
65125
|
at += 1;
|
|
64879
65126
|
return ch;
|
|
64880
65127
|
}, number44 = function() {
|
|
@@ -64921,12 +65168,12 @@ var require_parse = __commonJS({
|
|
|
64921
65168
|
var startAt = at;
|
|
64922
65169
|
while (next()) {
|
|
64923
65170
|
if (ch === '"') {
|
|
64924
|
-
if (at - 1 > startAt) string474 +=
|
|
65171
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
64925
65172
|
next();
|
|
64926
65173
|
return string474;
|
|
64927
65174
|
}
|
|
64928
65175
|
if (ch === "\\") {
|
|
64929
|
-
if (at - 1 > startAt) string474 +=
|
|
65176
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
64930
65177
|
next();
|
|
64931
65178
|
if (ch === "u") {
|
|
64932
65179
|
uffff = 0;
|
|
@@ -65059,7 +65306,7 @@ var require_parse = __commonJS({
|
|
|
65059
65306
|
};
|
|
65060
65307
|
return function(source, reviver) {
|
|
65061
65308
|
var result;
|
|
65062
|
-
|
|
65309
|
+
text2 = source + "";
|
|
65063
65310
|
at = 0;
|
|
65064
65311
|
ch = " ";
|
|
65065
65312
|
result = value();
|
|
@@ -65971,8 +66218,8 @@ var require_crypto = __commonJS({
|
|
|
65971
66218
|
const result = new TextDecoder().decode(uint8array);
|
|
65972
66219
|
return result;
|
|
65973
66220
|
}
|
|
65974
|
-
encodeBase64StringUtf8(
|
|
65975
|
-
const uint8array = new TextEncoder().encode(
|
|
66221
|
+
encodeBase64StringUtf8(text2) {
|
|
66222
|
+
const uint8array = new TextEncoder().encode(text2);
|
|
65976
66223
|
const result = base64js.fromByteArray(uint8array);
|
|
65977
66224
|
return result;
|
|
65978
66225
|
}
|
|
@@ -66041,8 +66288,8 @@ var require_crypto2 = __commonJS({
|
|
|
66041
66288
|
decodeBase64StringUtf8(base64) {
|
|
66042
66289
|
return Buffer.from(base64, "base64").toString("utf-8");
|
|
66043
66290
|
}
|
|
66044
|
-
encodeBase64StringUtf8(
|
|
66045
|
-
return Buffer.from(
|
|
66291
|
+
encodeBase64StringUtf8(text2) {
|
|
66292
|
+
return Buffer.from(text2, "utf-8").toString("base64");
|
|
66046
66293
|
}
|
|
66047
66294
|
/**
|
|
66048
66295
|
* Computes the SHA-256 hash of the provided string.
|
|
@@ -86487,8 +86734,8 @@ async function defaultParseResponse3(client, props) {
|
|
|
86487
86734
|
const json2 = await response.json();
|
|
86488
86735
|
return json2;
|
|
86489
86736
|
}
|
|
86490
|
-
const
|
|
86491
|
-
return
|
|
86737
|
+
const text2 = await response.text();
|
|
86738
|
+
return text2;
|
|
86492
86739
|
})();
|
|
86493
86740
|
loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
|
|
86494
86741
|
retryOfRequestLogID,
|
|
@@ -88065,7 +88312,7 @@ var init_node = __esm({
|
|
|
88065
88312
|
if (this.candidates && this.candidates.length > 1) {
|
|
88066
88313
|
console.warn("there are multiple candidates in the response, returning text from the first one.");
|
|
88067
88314
|
}
|
|
88068
|
-
let
|
|
88315
|
+
let text2 = "";
|
|
88069
88316
|
let anyTextPartText = false;
|
|
88070
88317
|
const nonTextParts = [];
|
|
88071
88318
|
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 : []) {
|
|
@@ -88079,13 +88326,13 @@ var init_node = __esm({
|
|
|
88079
88326
|
continue;
|
|
88080
88327
|
}
|
|
88081
88328
|
anyTextPartText = true;
|
|
88082
|
-
|
|
88329
|
+
text2 += part.text;
|
|
88083
88330
|
}
|
|
88084
88331
|
}
|
|
88085
88332
|
if (nonTextParts.length > 0) {
|
|
88086
88333
|
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.`);
|
|
88087
88334
|
}
|
|
88088
|
-
return anyTextPartText ?
|
|
88335
|
+
return anyTextPartText ? text2 : void 0;
|
|
88089
88336
|
}
|
|
88090
88337
|
/**
|
|
88091
88338
|
* Returns the concatenation of all inline data parts from the first candidate
|
|
@@ -88338,7 +88585,7 @@ var init_node = __esm({
|
|
|
88338
88585
|
*/
|
|
88339
88586
|
get text() {
|
|
88340
88587
|
var _a5, _b, _c;
|
|
88341
|
-
let
|
|
88588
|
+
let text2 = "";
|
|
88342
88589
|
let anyTextPartFound = false;
|
|
88343
88590
|
const nonTextParts = [];
|
|
88344
88591
|
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 : []) {
|
|
@@ -88352,13 +88599,13 @@ var init_node = __esm({
|
|
|
88352
88599
|
continue;
|
|
88353
88600
|
}
|
|
88354
88601
|
anyTextPartFound = true;
|
|
88355
|
-
|
|
88602
|
+
text2 += part.text;
|
|
88356
88603
|
}
|
|
88357
88604
|
}
|
|
88358
88605
|
if (nonTextParts.length > 0) {
|
|
88359
88606
|
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.`);
|
|
88360
88607
|
}
|
|
88361
|
-
return anyTextPartFound ?
|
|
88608
|
+
return anyTextPartFound ? text2 : void 0;
|
|
88362
88609
|
}
|
|
88363
88610
|
/**
|
|
88364
88611
|
* Returns the concatenation of all inline data parts from the server content if present.
|
|
@@ -93030,9 +93277,9 @@ var init_node = __esm({
|
|
|
93030
93277
|
}
|
|
93031
93278
|
return n;
|
|
93032
93279
|
};
|
|
93033
|
-
safeJSON3 = (
|
|
93280
|
+
safeJSON3 = (text2) => {
|
|
93034
93281
|
try {
|
|
93035
|
-
return JSON.parse(
|
|
93282
|
+
return JSON.parse(text2);
|
|
93036
93283
|
} catch (err) {
|
|
93037
93284
|
return void 0;
|
|
93038
93285
|
}
|
|
@@ -110895,8 +111142,8 @@ function findBoundary(buf) {
|
|
|
110895
111142
|
return null;
|
|
110896
111143
|
}
|
|
110897
111144
|
function parseMessage2(chunk, parse2, state, dataRequired) {
|
|
110898
|
-
const
|
|
110899
|
-
const lines =
|
|
111145
|
+
const text2 = new TextDecoder().decode(chunk);
|
|
111146
|
+
const lines = text2.split(/\r\n|\r|\n/);
|
|
110900
111147
|
const dataLines = [];
|
|
110901
111148
|
const ret = {};
|
|
110902
111149
|
let ignore = true;
|
|
@@ -133770,10 +134017,10 @@ function formatMistralError(error) {
|
|
|
133770
134017
|
}
|
|
133771
134018
|
return safeJsonStringify(error);
|
|
133772
134019
|
}
|
|
133773
|
-
function truncateErrorText(
|
|
133774
|
-
if (
|
|
133775
|
-
return
|
|
133776
|
-
return `${
|
|
134020
|
+
function truncateErrorText(text2, maxChars) {
|
|
134021
|
+
if (text2.length <= maxChars)
|
|
134022
|
+
return text2;
|
|
134023
|
+
return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
|
|
133777
134024
|
}
|
|
133778
134025
|
function safeJsonStringify(value) {
|
|
133779
134026
|
try {
|
|
@@ -133893,7 +134140,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
|
|
|
133893
134140
|
continue;
|
|
133894
134141
|
}
|
|
133895
134142
|
if (item.type === "thinking") {
|
|
133896
|
-
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((
|
|
134143
|
+
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
|
|
133897
134144
|
const thinkingDelta = sanitizeSurrogates(deltaText);
|
|
133898
134145
|
if (!thinkingDelta)
|
|
133899
134146
|
continue;
|
|
@@ -134090,8 +134337,8 @@ function toChatMessages(messages, supportsImages) {
|
|
|
134090
134337
|
}
|
|
134091
134338
|
return result;
|
|
134092
134339
|
}
|
|
134093
|
-
function buildToolResultText(
|
|
134094
|
-
const trimmed =
|
|
134340
|
+
function buildToolResultText(text2, hasImages, supportsImages, isError) {
|
|
134341
|
+
const trimmed = text2.trim();
|
|
134095
134342
|
const errorPrefix = isError ? "[tool error] " : "";
|
|
134096
134343
|
if (trimmed.length > 0) {
|
|
134097
134344
|
const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
|
|
@@ -134892,14 +135139,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
134892
135139
|
};
|
|
134893
135140
|
const onMessage = (event) => {
|
|
134894
135141
|
void (async () => {
|
|
134895
|
-
let
|
|
135142
|
+
let text2 = null;
|
|
134896
135143
|
try {
|
|
134897
135144
|
if (!event || typeof event !== "object" || !("data" in event))
|
|
134898
135145
|
return;
|
|
134899
|
-
|
|
134900
|
-
if (!
|
|
135146
|
+
text2 = await decodeWebSocketData(event.data);
|
|
135147
|
+
if (!text2)
|
|
134901
135148
|
return;
|
|
134902
|
-
const parsed = JSON.parse(
|
|
135149
|
+
const parsed = JSON.parse(text2);
|
|
134903
135150
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
134904
135151
|
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
134905
135152
|
sawCompletion = true;
|
|
@@ -134910,7 +135157,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
134910
135157
|
} catch (cause) {
|
|
134911
135158
|
failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
|
|
134912
135159
|
cause,
|
|
134913
|
-
payload:
|
|
135160
|
+
payload: text2
|
|
134914
135161
|
});
|
|
134915
135162
|
done = true;
|
|
134916
135163
|
wake();
|
|
@@ -143074,11 +143321,11 @@ function videoRequestConfig(input) {
|
|
|
143074
143321
|
};
|
|
143075
143322
|
}
|
|
143076
143323
|
async function readMiniMaxJson(response) {
|
|
143077
|
-
const
|
|
143324
|
+
const text2 = await response.text();
|
|
143078
143325
|
let body = {};
|
|
143079
|
-
if (
|
|
143326
|
+
if (text2) {
|
|
143080
143327
|
try {
|
|
143081
|
-
const parsed = JSON.parse(
|
|
143328
|
+
const parsed = JSON.parse(text2);
|
|
143082
143329
|
if (isRecord(parsed)) body = parsed;
|
|
143083
143330
|
} catch {
|
|
143084
143331
|
throw new Error("MiniMax video API returned invalid JSON");
|
|
@@ -143994,8 +144241,8 @@ __export(lite_provider_exports, {
|
|
|
143994
144241
|
import { createHash as createHash7 } from "crypto";
|
|
143995
144242
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
143996
144243
|
import { join as join4, relative } from "path";
|
|
143997
|
-
function hashText(
|
|
143998
|
-
return createHash7("sha256").update(
|
|
144244
|
+
function hashText(text2) {
|
|
144245
|
+
return createHash7("sha256").update(text2).digest("hex");
|
|
143999
144246
|
}
|
|
144000
144247
|
function extension2(path18) {
|
|
144001
144248
|
const index = path18.lastIndexOf(".");
|
|
@@ -144039,19 +144286,19 @@ function walk(root, exclude, maxFiles) {
|
|
|
144039
144286
|
visit(root);
|
|
144040
144287
|
return out;
|
|
144041
144288
|
}
|
|
144042
|
-
function lineOf(
|
|
144043
|
-
return
|
|
144289
|
+
function lineOf(text2, index) {
|
|
144290
|
+
return text2.slice(0, index).split(/\r?\n/).length;
|
|
144044
144291
|
}
|
|
144045
|
-
function extractSymbols(projectId, file,
|
|
144292
|
+
function extractSymbols(projectId, file, text2, indexedAt) {
|
|
144046
144293
|
const symbols = [];
|
|
144047
144294
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
144048
144295
|
const patterns = profile?.symbols ?? [];
|
|
144049
144296
|
for (const { kind, re } of patterns) {
|
|
144050
144297
|
re.lastIndex = 0;
|
|
144051
|
-
for (const match2 of
|
|
144298
|
+
for (const match2 of text2.matchAll(re)) {
|
|
144052
144299
|
const name = match2[1];
|
|
144053
144300
|
if (!name || name.includes("\n")) continue;
|
|
144054
|
-
const startLine = lineOf(
|
|
144301
|
+
const startLine = lineOf(text2, match2.index ?? 0);
|
|
144055
144302
|
const id = makeCodeSymbolId({ projectId, path: file.path, qualifiedName: name, kind });
|
|
144056
144303
|
symbols.push({
|
|
144057
144304
|
id,
|
|
@@ -144071,13 +144318,13 @@ function extractSymbols(projectId, file, text, indexedAt) {
|
|
|
144071
144318
|
}
|
|
144072
144319
|
return symbols;
|
|
144073
144320
|
}
|
|
144074
|
-
function extractImportEdges(projectId, file,
|
|
144321
|
+
function extractImportEdges(projectId, file, text2, indexedAt) {
|
|
144075
144322
|
const edges = [];
|
|
144076
144323
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
144077
144324
|
const imports = profile?.imports ?? [];
|
|
144078
144325
|
for (const re of imports) {
|
|
144079
144326
|
re.lastIndex = 0;
|
|
144080
|
-
for (const match2 of
|
|
144327
|
+
for (const match2 of text2.matchAll(re)) {
|
|
144081
144328
|
const target = (match2[1] ?? "").trim();
|
|
144082
144329
|
if (!target) continue;
|
|
144083
144330
|
if (target.includes("\n")) {
|
|
@@ -144112,14 +144359,14 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
144112
144359
|
function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
144113
144360
|
const rel = normalizeCodePath(relative(projectRoot, abs));
|
|
144114
144361
|
try {
|
|
144115
|
-
const
|
|
144362
|
+
const text2 = readFileSync6(abs, "utf-8");
|
|
144116
144363
|
const stat4 = fileStat ?? statSync3(abs);
|
|
144117
144364
|
const file = {
|
|
144118
144365
|
id: makeCodeFileId(projectId, rel),
|
|
144119
144366
|
projectId,
|
|
144120
144367
|
path: rel,
|
|
144121
144368
|
language: languageForPath(rel),
|
|
144122
|
-
contentHash: hashText(
|
|
144369
|
+
contentHash: hashText(text2),
|
|
144123
144370
|
// Preserve filesystem precision. Rounding here made same-size edits in
|
|
144124
144371
|
// a short Windows timestamp window indistinguishable to refresh.
|
|
144125
144372
|
mtimeMs: Number(stat4.mtimeMs),
|
|
@@ -144129,8 +144376,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
|
144129
144376
|
return {
|
|
144130
144377
|
delta: {
|
|
144131
144378
|
file,
|
|
144132
|
-
symbols: extractSymbols(projectId, file,
|
|
144133
|
-
edges: extractImportEdges(projectId, file,
|
|
144379
|
+
symbols: extractSymbols(projectId, file, text2, indexedAt),
|
|
144380
|
+
edges: extractImportEdges(projectId, file, text2, indexedAt)
|
|
144134
144381
|
},
|
|
144135
144382
|
unreadable: false
|
|
144136
144383
|
};
|
|
@@ -145042,8 +145289,8 @@ function taskTokens(task) {
|
|
|
145042
145289
|
return normalizedTokens(task);
|
|
145043
145290
|
}
|
|
145044
145291
|
function scoreClaim(claim, tokens) {
|
|
145045
|
-
const
|
|
145046
|
-
const words = normalizedTokens(
|
|
145292
|
+
const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
|
|
145293
|
+
const words = normalizedTokens(text2);
|
|
145047
145294
|
let matches = 0;
|
|
145048
145295
|
for (const token of tokens) {
|
|
145049
145296
|
if (words.has(token)) matches += 1;
|
|
@@ -145939,29 +146186,141 @@ var init_workflow_store = __esm({
|
|
|
145939
146186
|
}
|
|
145940
146187
|
});
|
|
145941
146188
|
|
|
146189
|
+
// src/knowledge/outcome-types.ts
|
|
146190
|
+
var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
|
|
146191
|
+
var init_outcome_types = __esm({
|
|
146192
|
+
"src/knowledge/outcome-types.ts"() {
|
|
146193
|
+
"use strict";
|
|
146194
|
+
init_esm_shims();
|
|
146195
|
+
MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
|
|
146196
|
+
MEMORY_OUTCOME_SIGNAL_KINDS = [
|
|
146197
|
+
"verification-passed",
|
|
146198
|
+
"verification-failed",
|
|
146199
|
+
"verified-reuse",
|
|
146200
|
+
"user-pin",
|
|
146201
|
+
"user-correction",
|
|
146202
|
+
"source-changed",
|
|
146203
|
+
"conflict-confirmed",
|
|
146204
|
+
"manual-review"
|
|
146205
|
+
];
|
|
146206
|
+
}
|
|
146207
|
+
});
|
|
146208
|
+
|
|
146209
|
+
// src/knowledge/outcome-store.ts
|
|
146210
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
146211
|
+
function optionalText4(value) {
|
|
146212
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
146213
|
+
}
|
|
146214
|
+
function text(value, field, max = 1e3) {
|
|
146215
|
+
const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
|
|
146216
|
+
if (!safe) throw new Error("Outcome signal " + field + " is required.");
|
|
146217
|
+
if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
|
|
146218
|
+
return safe;
|
|
146219
|
+
}
|
|
146220
|
+
function oneOf(value, values, field) {
|
|
146221
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
146222
|
+
throw new Error("Outcome signal " + field + " is invalid.");
|
|
146223
|
+
}
|
|
146224
|
+
return value;
|
|
146225
|
+
}
|
|
146226
|
+
function rowToSignal(row) {
|
|
146227
|
+
return {
|
|
146228
|
+
id: row.id,
|
|
146229
|
+
projectId: row.projectId,
|
|
146230
|
+
candidateKind: row.candidateKind,
|
|
146231
|
+
candidateId: row.candidateId,
|
|
146232
|
+
kind: row.kind,
|
|
146233
|
+
sourceRef: row.sourceRef,
|
|
146234
|
+
...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
|
|
146235
|
+
...optionalText4(row.detail) ? { detail: row.detail } : {},
|
|
146236
|
+
observedAt: row.observedAt
|
|
146237
|
+
};
|
|
146238
|
+
}
|
|
146239
|
+
var OutcomeStore;
|
|
146240
|
+
var init_outcome_store = __esm({
|
|
146241
|
+
"src/knowledge/outcome-store.ts"() {
|
|
146242
|
+
"use strict";
|
|
146243
|
+
init_esm_shims();
|
|
146244
|
+
init_secret_filter();
|
|
146245
|
+
init_sqlite_db();
|
|
146246
|
+
init_outcome_types();
|
|
146247
|
+
OutcomeStore = class {
|
|
146248
|
+
db = null;
|
|
146249
|
+
async init(dataDir) {
|
|
146250
|
+
this.db = getDatabase(dataDir);
|
|
146251
|
+
}
|
|
146252
|
+
record(input) {
|
|
146253
|
+
const signal = {
|
|
146254
|
+
id: randomUUID10(),
|
|
146255
|
+
projectId: text(input.projectId, "project id"),
|
|
146256
|
+
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
146257
|
+
candidateId: text(input.candidateId, "candidate id"),
|
|
146258
|
+
kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
|
|
146259
|
+
sourceRef: text(input.sourceRef, "source reference"),
|
|
146260
|
+
...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
|
|
146261
|
+
...input.detail ? { detail: text(input.detail, "detail") } : {},
|
|
146262
|
+
observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
146263
|
+
};
|
|
146264
|
+
this.db.prepare(`
|
|
146265
|
+
INSERT INTO memory_outcome_signals (
|
|
146266
|
+
id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
|
|
146267
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
146268
|
+
`).run(
|
|
146269
|
+
signal.id,
|
|
146270
|
+
signal.projectId,
|
|
146271
|
+
signal.candidateKind,
|
|
146272
|
+
signal.candidateId,
|
|
146273
|
+
signal.kind,
|
|
146274
|
+
signal.sourceRef,
|
|
146275
|
+
signal.snapshotId ?? null,
|
|
146276
|
+
signal.detail ?? null,
|
|
146277
|
+
signal.observedAt
|
|
146278
|
+
);
|
|
146279
|
+
return signal;
|
|
146280
|
+
}
|
|
146281
|
+
latestForCandidates(projectId, candidateKind, candidateIds) {
|
|
146282
|
+
const ids = [...new Set(candidateIds.filter(Boolean))];
|
|
146283
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
146284
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
146285
|
+
const rows = this.db.prepare(`
|
|
146286
|
+
SELECT * FROM memory_outcome_signals
|
|
146287
|
+
WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
|
|
146288
|
+
ORDER BY observedAt DESC, id DESC
|
|
146289
|
+
`).all(projectId, candidateKind, ...ids);
|
|
146290
|
+
const latest = /* @__PURE__ */ new Map();
|
|
146291
|
+
for (const row of rows) {
|
|
146292
|
+
const signal = rowToSignal(row);
|
|
146293
|
+
if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
|
|
146294
|
+
}
|
|
146295
|
+
return latest;
|
|
146296
|
+
}
|
|
146297
|
+
};
|
|
146298
|
+
}
|
|
146299
|
+
});
|
|
146300
|
+
|
|
145942
146301
|
// src/codegraph/task-lens.ts
|
|
145943
|
-
function containsTaskKeyword(
|
|
146302
|
+
function containsTaskKeyword(text2, keyword) {
|
|
145944
146303
|
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");
|
|
145945
146304
|
let match2;
|
|
145946
|
-
while ((match2 = matcher.exec(
|
|
146305
|
+
while ((match2 = matcher.exec(text2)) !== null) {
|
|
145947
146306
|
const keywordIndex = match2.index + (match2[1]?.length ?? 0);
|
|
145948
|
-
if (!isNegatedTaskKeyword(
|
|
146307
|
+
if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
|
|
145949
146308
|
}
|
|
145950
146309
|
return false;
|
|
145951
146310
|
}
|
|
145952
|
-
function isNegatedTaskKeyword(
|
|
146311
|
+
function isNegatedTaskKeyword(text2, keywordIndex) {
|
|
145953
146312
|
const boundary = Math.max(
|
|
145954
|
-
|
|
145955
|
-
|
|
145956
|
-
|
|
145957
|
-
|
|
145958
|
-
|
|
145959
|
-
|
|
145960
|
-
|
|
145961
|
-
|
|
145962
|
-
|
|
146313
|
+
text2.lastIndexOf(".", keywordIndex - 1),
|
|
146314
|
+
text2.lastIndexOf("!", keywordIndex - 1),
|
|
146315
|
+
text2.lastIndexOf("?", keywordIndex - 1),
|
|
146316
|
+
text2.lastIndexOf(";", keywordIndex - 1),
|
|
146317
|
+
text2.lastIndexOf("\n", keywordIndex - 1),
|
|
146318
|
+
text2.lastIndexOf("\u3002", keywordIndex - 1),
|
|
146319
|
+
text2.lastIndexOf("\uFF01", keywordIndex - 1),
|
|
146320
|
+
text2.lastIndexOf("\uFF1F", keywordIndex - 1),
|
|
146321
|
+
text2.lastIndexOf("\uFF1B", keywordIndex - 1)
|
|
145963
146322
|
);
|
|
145964
|
-
let prefix =
|
|
146323
|
+
let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
|
|
145965
146324
|
const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
|
|
145966
146325
|
let contrastMatch;
|
|
145967
146326
|
let contrastEnd = -1;
|
|
@@ -146020,7 +146379,7 @@ function requiredText(data, key) {
|
|
|
146020
146379
|
}
|
|
146021
146380
|
return value.trim();
|
|
146022
146381
|
}
|
|
146023
|
-
function
|
|
146382
|
+
function optionalText5(data, key) {
|
|
146024
146383
|
const value = data[key];
|
|
146025
146384
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
146026
146385
|
if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
|
|
@@ -146063,11 +146422,11 @@ function phaseFromValue(value, index) {
|
|
|
146063
146422
|
}
|
|
146064
146423
|
const data = value;
|
|
146065
146424
|
const title = requiredText(data, "title");
|
|
146066
|
-
const phaseId =
|
|
146425
|
+
const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
|
|
146067
146426
|
return {
|
|
146068
146427
|
id: phaseId,
|
|
146069
146428
|
title,
|
|
146070
|
-
instructions:
|
|
146429
|
+
instructions: optionalText5(data, "instructions") ?? "",
|
|
146071
146430
|
branches: optionalStringArray(data, "branches"),
|
|
146072
146431
|
expectedOutputs: optionalStringArray(data, "expectedOutputs"),
|
|
146073
146432
|
verificationGates: optionalStringArray(data, "verificationGates")
|
|
@@ -146176,7 +146535,7 @@ function parsedWorkflow(data, body, input) {
|
|
|
146176
146535
|
id: requiredText(data, "id"),
|
|
146177
146536
|
workspaceId: input.workspaceId,
|
|
146178
146537
|
title: requiredText(data, "title"),
|
|
146179
|
-
description:
|
|
146538
|
+
description: optionalText5(data, "description") ?? "",
|
|
146180
146539
|
status: optionalStatus(data),
|
|
146181
146540
|
version: optionalNumber(data, "version", 1),
|
|
146182
146541
|
taskLenses: optionalStringArray(data, "taskLenses"),
|
|
@@ -146195,9 +146554,9 @@ function parsedWorkflow(data, body, input) {
|
|
|
146195
146554
|
sourcePath: normalizeSourcePath(input.sourcePath),
|
|
146196
146555
|
sourceHash: "",
|
|
146197
146556
|
contentHash: input.contentHash,
|
|
146198
|
-
createdAt:
|
|
146199
|
-
updatedAt:
|
|
146200
|
-
...
|
|
146557
|
+
createdAt: optionalText5(data, "createdAt") ?? now2(),
|
|
146558
|
+
updatedAt: optionalText5(data, "updatedAt") ?? now2(),
|
|
146559
|
+
...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
|
|
146201
146560
|
};
|
|
146202
146561
|
if (candidate.phases.length === 0) {
|
|
146203
146562
|
throw new Error("workflow must contain at least one phase or a non-empty body");
|
|
@@ -146296,11 +146655,11 @@ async function syncCanonicalWorkflows(workspace) {
|
|
|
146296
146655
|
return { workflows, errors };
|
|
146297
146656
|
}
|
|
146298
146657
|
function inferTaskLenses(value) {
|
|
146299
|
-
const
|
|
146300
|
-
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) =>
|
|
146658
|
+
const text2 = value.toLowerCase();
|
|
146659
|
+
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
|
|
146301
146660
|
}
|
|
146302
146661
|
function taskScore(workflow, task) {
|
|
146303
|
-
const
|
|
146662
|
+
const text2 = task.toLowerCase();
|
|
146304
146663
|
let score = 0;
|
|
146305
146664
|
const reasons = [];
|
|
146306
146665
|
const matchedLenses = /* @__PURE__ */ new Set();
|
|
@@ -146567,7 +146926,31 @@ async function recordWorkflowRun(input) {
|
|
|
146567
146926
|
throw new Error("Workflow was not found for this workspace");
|
|
146568
146927
|
}
|
|
146569
146928
|
if (!input.run.task.trim()) throw new Error("Workflow run task is required");
|
|
146570
|
-
|
|
146929
|
+
const run = store.recordRun(input.run);
|
|
146930
|
+
const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
|
|
146931
|
+
if (!kind) return run;
|
|
146932
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
146933
|
+
evidence.set(workflow.id, "workflow");
|
|
146934
|
+
for (const reference of run.selectedEvidence) {
|
|
146935
|
+
const match2 = /^(claim|durable):(.+)$/.exec(reference);
|
|
146936
|
+
if (!match2) continue;
|
|
146937
|
+
evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
|
|
146938
|
+
}
|
|
146939
|
+
const outcomes = new OutcomeStore();
|
|
146940
|
+
await outcomes.init(workflowStoreDataDir(input.workspace));
|
|
146941
|
+
for (const [candidateId, candidateKind] of evidence) {
|
|
146942
|
+
outcomes.record({
|
|
146943
|
+
projectId: run.projectId,
|
|
146944
|
+
candidateKind,
|
|
146945
|
+
candidateId,
|
|
146946
|
+
kind,
|
|
146947
|
+
sourceRef: "workflow-run:" + run.id,
|
|
146948
|
+
...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
|
|
146949
|
+
...run.failureReason ? { detail: run.failureReason } : {},
|
|
146950
|
+
observedAt: run.completedAt ?? run.startedAt
|
|
146951
|
+
});
|
|
146952
|
+
}
|
|
146953
|
+
return run;
|
|
146571
146954
|
}
|
|
146572
146955
|
async function selectWorkspaceWorkflows(input) {
|
|
146573
146956
|
const synced = await syncCanonicalWorkflows(input.workspace);
|
|
@@ -146592,6 +146975,7 @@ var init_workflows2 = __esm({
|
|
|
146592
146975
|
init_workflow_sync();
|
|
146593
146976
|
init_workspace();
|
|
146594
146977
|
init_workflow_store();
|
|
146978
|
+
init_outcome_store();
|
|
146595
146979
|
init_task_lens();
|
|
146596
146980
|
KNOWN_AGENTS = [
|
|
146597
146981
|
"windsurf",
|