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
|
@@ -307,7 +307,7 @@ function closeAllDatabases() {
|
|
|
307
307
|
_dbCache.delete(key);
|
|
308
308
|
}
|
|
309
309
|
}
|
|
310
|
-
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;
|
|
310
|
+
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;
|
|
311
311
|
var init_sqlite_db = __esm({
|
|
312
312
|
"src/store/sqlite-db.ts"() {
|
|
313
313
|
"use strict";
|
|
@@ -573,6 +573,17 @@ CREATE TABLE IF NOT EXISTS observation_code_refs (
|
|
|
573
573
|
" UNIQUE(projectId, sourceEpoch)",
|
|
574
574
|
");"
|
|
575
575
|
].join("\n");
|
|
576
|
+
CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE = [
|
|
577
|
+
"CREATE TABLE IF NOT EXISTS code_state_snapshot_files (",
|
|
578
|
+
" snapshotId TEXT NOT NULL,",
|
|
579
|
+
" projectId TEXT NOT NULL,",
|
|
580
|
+
" fileId TEXT NOT NULL,",
|
|
581
|
+
" path TEXT NOT NULL,",
|
|
582
|
+
" contentHash TEXT NOT NULL,",
|
|
583
|
+
" PRIMARY KEY (snapshotId, path),",
|
|
584
|
+
" FOREIGN KEY (snapshotId) REFERENCES code_state_snapshots(id) ON DELETE CASCADE",
|
|
585
|
+
");"
|
|
586
|
+
].join("\n");
|
|
576
587
|
CREATE_KNOWLEDGE_CLAIMS_TABLE = `
|
|
577
588
|
CREATE TABLE IF NOT EXISTS knowledge_claims (
|
|
578
589
|
id TEXT PRIMARY KEY,
|
|
@@ -783,6 +794,19 @@ CREATE TABLE IF NOT EXISTS long_term_memory_events (
|
|
|
783
794
|
createdAt TEXT NOT NULL,
|
|
784
795
|
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
785
796
|
);
|
|
797
|
+
`;
|
|
798
|
+
CREATE_MEMORY_OUTCOME_SIGNALS_TABLE = `
|
|
799
|
+
CREATE TABLE IF NOT EXISTS memory_outcome_signals (
|
|
800
|
+
id TEXT PRIMARY KEY,
|
|
801
|
+
projectId TEXT NOT NULL,
|
|
802
|
+
candidateKind TEXT NOT NULL,
|
|
803
|
+
candidateId TEXT NOT NULL,
|
|
804
|
+
kind TEXT NOT NULL,
|
|
805
|
+
sourceRef TEXT NOT NULL,
|
|
806
|
+
snapshotId TEXT,
|
|
807
|
+
detail TEXT,
|
|
808
|
+
observedAt TEXT NOT NULL
|
|
809
|
+
);
|
|
786
810
|
`;
|
|
787
811
|
CREATE_MEDIA_ASSETS_TABLE = `
|
|
788
812
|
CREATE TABLE IF NOT EXISTS media_assets (
|
|
@@ -1025,6 +1049,20 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1025
1049
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_edges_snapshot ON code_edges(projectId, snapshotId)");
|
|
1026
1050
|
}
|
|
1027
1051
|
},
|
|
1052
|
+
{
|
|
1053
|
+
id: "1.4-codegraph-snapshot-manifest",
|
|
1054
|
+
apply: (db2) => {
|
|
1055
|
+
db2.exec(CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE);
|
|
1056
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_snapshot_files_project_path ON code_state_snapshot_files(projectId, path)");
|
|
1057
|
+
}
|
|
1058
|
+
},
|
|
1059
|
+
{
|
|
1060
|
+
id: "1.4-memory-outcome-signals",
|
|
1061
|
+
apply: (db2) => {
|
|
1062
|
+
db2.exec(CREATE_MEMORY_OUTCOME_SIGNALS_TABLE);
|
|
1063
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_outcomes_candidate ON memory_outcome_signals(projectId, candidateKind, candidateId, observedAt DESC)");
|
|
1064
|
+
}
|
|
1065
|
+
},
|
|
1028
1066
|
{
|
|
1029
1067
|
id: "1.2-knowledge-claim-ledger",
|
|
1030
1068
|
apply: (db2) => {
|
|
@@ -1985,8 +2023,8 @@ async function readResponseText(response, signal, maxBytes = MAX_LLM_RESPONSE_BY
|
|
|
1985
2023
|
}
|
|
1986
2024
|
}
|
|
1987
2025
|
async function readResponseJson(response, signal, maxBytes = MAX_LLM_RESPONSE_BYTES) {
|
|
1988
|
-
const
|
|
1989
|
-
return JSON.parse(
|
|
2026
|
+
const text2 = await readResponseText(response, signal, maxBytes);
|
|
2027
|
+
return JSON.parse(text2);
|
|
1990
2028
|
}
|
|
1991
2029
|
async function* callLLMWithToolsStream(messages, tools) {
|
|
1992
2030
|
if (!currentConfig) {
|
|
@@ -3158,8 +3196,8 @@ var init_mini_skill_store = __esm({
|
|
|
3158
3196
|
|
|
3159
3197
|
// src/compact/token-budget.ts
|
|
3160
3198
|
import { countTokens, isWithinTokenLimit } from "gpt-tokenizer";
|
|
3161
|
-
function countTextTokens(
|
|
3162
|
-
return countTokens(
|
|
3199
|
+
function countTextTokens(text2) {
|
|
3200
|
+
return countTokens(text2);
|
|
3163
3201
|
}
|
|
3164
3202
|
var init_token_budget = __esm({
|
|
3165
3203
|
"src/compact/token-budget.ts"() {
|
|
@@ -3265,8 +3303,8 @@ import { createHash } from "crypto";
|
|
|
3265
3303
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
3266
3304
|
import { join as join2 } from "path";
|
|
3267
3305
|
import { homedir as homedir6 } from "os";
|
|
3268
|
-
function textHash(
|
|
3269
|
-
return createHash("sha256").update(
|
|
3306
|
+
function textHash(text2) {
|
|
3307
|
+
return createHash("sha256").update(text2).digest("hex").slice(0, 16);
|
|
3270
3308
|
}
|
|
3271
3309
|
async function loadDiskCache() {
|
|
3272
3310
|
try {
|
|
@@ -3329,11 +3367,11 @@ var init_fastembed_provider = __esm({
|
|
|
3329
3367
|
async embedInputs(inputs, options = {}) {
|
|
3330
3368
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3331
3369
|
}
|
|
3332
|
-
async embed(
|
|
3333
|
-
const hash4 = textHash(
|
|
3370
|
+
async embed(text2) {
|
|
3371
|
+
const hash4 = textHash(text2);
|
|
3334
3372
|
const cached = cache.get(hash4);
|
|
3335
3373
|
if (cached) return cached;
|
|
3336
|
-
const raw = await this.model.queryEmbed(
|
|
3374
|
+
const raw = await this.model.queryEmbed(text2);
|
|
3337
3375
|
const result = Array.from(raw);
|
|
3338
3376
|
if (result.length !== this.dimensions) {
|
|
3339
3377
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
@@ -3429,10 +3467,10 @@ var init_transformers_provider = __esm({
|
|
|
3429
3467
|
async embedInputs(inputs, options = {}) {
|
|
3430
3468
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3431
3469
|
}
|
|
3432
|
-
async embed(
|
|
3433
|
-
const cached = cache2.get(
|
|
3470
|
+
async embed(text2) {
|
|
3471
|
+
const cached = cache2.get(text2);
|
|
3434
3472
|
if (cached) return cached;
|
|
3435
|
-
const output = await this.extractor(
|
|
3473
|
+
const output = await this.extractor(text2, {
|
|
3436
3474
|
pooling: "mean",
|
|
3437
3475
|
normalize: true
|
|
3438
3476
|
});
|
|
@@ -3440,7 +3478,7 @@ var init_transformers_provider = __esm({
|
|
|
3440
3478
|
if (result.length !== this.dimensions) {
|
|
3441
3479
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
3442
3480
|
}
|
|
3443
|
-
this.cacheSet(
|
|
3481
|
+
this.cacheSet(text2, result);
|
|
3444
3482
|
return result;
|
|
3445
3483
|
}
|
|
3446
3484
|
async embedBatch(texts) {
|
|
@@ -3503,8 +3541,8 @@ function dimsCacheFile() {
|
|
|
3503
3541
|
function cacheMetaFile() {
|
|
3504
3542
|
return join3(cacheDir(), ".embedding-api-cache-meta.json");
|
|
3505
3543
|
}
|
|
3506
|
-
function normalizeText(
|
|
3507
|
-
return
|
|
3544
|
+
function normalizeText(text2) {
|
|
3545
|
+
return text2.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
|
|
3508
3546
|
}
|
|
3509
3547
|
function cacheNamespace(config) {
|
|
3510
3548
|
return [
|
|
@@ -3514,8 +3552,8 @@ function cacheNamespace(config) {
|
|
|
3514
3552
|
config.requestedDimensions ?? "native"
|
|
3515
3553
|
].join("|");
|
|
3516
3554
|
}
|
|
3517
|
-
function textHash2(
|
|
3518
|
-
return createHash2("sha256").update(`${namespace}\0${
|
|
3555
|
+
function textHash2(text2, namespace) {
|
|
3556
|
+
return createHash2("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
3519
3557
|
}
|
|
3520
3558
|
function inputIdentity(input, options = {}) {
|
|
3521
3559
|
return JSON.stringify({
|
|
@@ -3927,8 +3965,8 @@ var init_api_provider = __esm({
|
|
|
3927
3965
|
if (!embedding) throw new Error("API probe returned no embeddings; check model name and API key");
|
|
3928
3966
|
return embedding.length;
|
|
3929
3967
|
}
|
|
3930
|
-
async embed(
|
|
3931
|
-
const normalized = normalizeText(
|
|
3968
|
+
async embed(text2, options) {
|
|
3969
|
+
const normalized = normalizeText(text2);
|
|
3932
3970
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
3933
3971
|
return this.embedInput({ modality: "text", text: normalized }, { intent: "document", ...options });
|
|
3934
3972
|
}
|
|
@@ -3985,7 +4023,7 @@ var init_api_provider = __esm({
|
|
|
3985
4023
|
}
|
|
3986
4024
|
async embedBatch(texts, options) {
|
|
3987
4025
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
3988
|
-
return Promise.all(texts.map((
|
|
4026
|
+
return Promise.all(texts.map((text2) => this.embedInput({ modality: "text", text: text2 }, { intent: "document", ...options })));
|
|
3989
4027
|
}
|
|
3990
4028
|
await ensureDiskCacheLoaded();
|
|
3991
4029
|
const normalizedTexts = texts.map(normalizeText);
|
|
@@ -4064,8 +4102,8 @@ var init_api_provider = __esm({
|
|
|
4064
4102
|
}
|
|
4065
4103
|
async getCachedEmbeddings(texts) {
|
|
4066
4104
|
await ensureDiskCacheLoaded();
|
|
4067
|
-
return texts.map((
|
|
4068
|
-
const hash4 = textHash2(normalizeText(
|
|
4105
|
+
return texts.map((text2) => {
|
|
4106
|
+
const hash4 = textHash2(normalizeText(text2), this.cacheKeyNamespace);
|
|
4069
4107
|
return cache3.get(hash4) ?? null;
|
|
4070
4108
|
});
|
|
4071
4109
|
}
|
|
@@ -4295,9 +4333,9 @@ function wrapProvider(candidate) {
|
|
|
4295
4333
|
return {
|
|
4296
4334
|
name: candidate.name,
|
|
4297
4335
|
dimensions: candidate.dimensions,
|
|
4298
|
-
async embed(
|
|
4336
|
+
async embed(text2, options) {
|
|
4299
4337
|
try {
|
|
4300
|
-
return await candidate.embed(
|
|
4338
|
+
return await candidate.embed(text2, options);
|
|
4301
4339
|
} catch (error) {
|
|
4302
4340
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
4303
4341
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -4305,7 +4343,7 @@ function wrapProvider(candidate) {
|
|
|
4305
4343
|
if (fallback) {
|
|
4306
4344
|
provider = wrapProvider(fallback);
|
|
4307
4345
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
4308
|
-
return provider.embed(
|
|
4346
|
+
return provider.embed(text2, options);
|
|
4309
4347
|
}
|
|
4310
4348
|
}
|
|
4311
4349
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -4804,8 +4842,8 @@ function isCjkHeavy(query) {
|
|
|
4804
4842
|
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
4805
4843
|
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
4806
4844
|
}
|
|
4807
|
-
function normalizeExpansion(
|
|
4808
|
-
return
|
|
4845
|
+
function normalizeExpansion(text2) {
|
|
4846
|
+
return text2.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
|
|
4809
4847
|
}
|
|
4810
4848
|
async function maybeExpandSearchQuery(query) {
|
|
4811
4849
|
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
@@ -5168,9 +5206,9 @@ function shouldSkipCompression(narrative, type) {
|
|
|
5168
5206
|
if (specialChars / narrative.length > 0.35) return true;
|
|
5169
5207
|
return false;
|
|
5170
5208
|
}
|
|
5171
|
-
function estimateTokens(
|
|
5172
|
-
const cjkChars = (
|
|
5173
|
-
const otherChars =
|
|
5209
|
+
function estimateTokens(text2) {
|
|
5210
|
+
const cjkChars = (text2.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
|
|
5211
|
+
const otherChars = text2.length - cjkChars;
|
|
5174
5212
|
return Math.ceil(cjkChars / 1.5 + otherChars / 4);
|
|
5175
5213
|
}
|
|
5176
5214
|
var COMPRESS_PROMPT, COMPRESS_PROMPT_GENTLE, RERANK_PROMPT, SKIP_PATTERNS, LOW_COMPRESSION_TYPES;
|
|
@@ -5473,10 +5511,10 @@ function isEmbeddingEnabled() {
|
|
|
5473
5511
|
function getVectorDimensions() {
|
|
5474
5512
|
return embeddingEnabled ? embeddingDimensions : null;
|
|
5475
5513
|
}
|
|
5476
|
-
async function generateEmbedding(
|
|
5514
|
+
async function generateEmbedding(text2) {
|
|
5477
5515
|
const provider2 = await getEmbeddingProvider();
|
|
5478
5516
|
if (!provider2) return null;
|
|
5479
|
-
return provider2.embedInput ? provider2.embedInput({ modality: "text", text }, { intent: "document" }) : provider2.embed(
|
|
5517
|
+
return provider2.embedInput ? provider2.embedInput({ modality: "text", text: text2 }, { intent: "document" }) : provider2.embed(text2);
|
|
5480
5518
|
}
|
|
5481
5519
|
async function generateEmbeddingInput(input, options = {}) {
|
|
5482
5520
|
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;
|
|
@@ -7340,9 +7378,9 @@ __export(consolidation_exports, {
|
|
|
7340
7378
|
executeConsolidation: () => executeConsolidation,
|
|
7341
7379
|
findConsolidationCandidates: () => findConsolidationCandidates
|
|
7342
7380
|
});
|
|
7343
|
-
function tokenize(
|
|
7381
|
+
function tokenize(text2) {
|
|
7344
7382
|
return new Set(
|
|
7345
|
-
|
|
7383
|
+
text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t2) => t2.length > 1)
|
|
7346
7384
|
);
|
|
7347
7385
|
}
|
|
7348
7386
|
function jaccardSimilarity(a, b) {
|
|
@@ -16300,8 +16338,8 @@ var init_headers = __esm({
|
|
|
16300
16338
|
});
|
|
16301
16339
|
|
|
16302
16340
|
// packages/ai/dist/utils/sanitize-unicode.js
|
|
16303
|
-
function sanitizeSurrogates(
|
|
16304
|
-
return
|
|
16341
|
+
function sanitizeSurrogates(text2) {
|
|
16342
|
+
return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
16305
16343
|
}
|
|
16306
16344
|
var init_sanitize_unicode = __esm({
|
|
16307
16345
|
"packages/ai/dist/utils/sanitize-unicode.js"() {
|
|
@@ -16783,9 +16821,9 @@ var init_values = __esm({
|
|
|
16783
16821
|
}
|
|
16784
16822
|
return n;
|
|
16785
16823
|
};
|
|
16786
|
-
safeJSON = (
|
|
16824
|
+
safeJSON = (text2) => {
|
|
16787
16825
|
try {
|
|
16788
|
-
return JSON.parse(
|
|
16826
|
+
return JSON.parse(text2);
|
|
16789
16827
|
} catch (err) {
|
|
16790
16828
|
return void 0;
|
|
16791
16829
|
}
|
|
@@ -17948,8 +17986,8 @@ async function defaultParseResponse(client, props) {
|
|
|
17948
17986
|
const json2 = await response.json();
|
|
17949
17987
|
return addRequestID(json2, response);
|
|
17950
17988
|
}
|
|
17951
|
-
const
|
|
17952
|
-
return
|
|
17989
|
+
const text2 = await response.text();
|
|
17990
|
+
return text2;
|
|
17953
17991
|
})();
|
|
17954
17992
|
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
17955
17993
|
retryOfRequestLogID,
|
|
@@ -31308,7 +31346,7 @@ var init_models_generated = __esm({
|
|
|
31308
31346
|
provider: "minimax",
|
|
31309
31347
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
31310
31348
|
reasoning: true,
|
|
31311
|
-
input: ["text", "image"],
|
|
31349
|
+
input: ["text", "image", "video"],
|
|
31312
31350
|
cost: {
|
|
31313
31351
|
input: 0.3,
|
|
31314
31352
|
output: 1.2,
|
|
@@ -31361,7 +31399,7 @@ var init_models_generated = __esm({
|
|
|
31361
31399
|
provider: "minimax-cn",
|
|
31362
31400
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
31363
31401
|
reasoning: true,
|
|
31364
|
-
input: ["text", "image"],
|
|
31402
|
+
input: ["text", "image", "video"],
|
|
31365
31403
|
cost: {
|
|
31366
31404
|
input: 0.3,
|
|
31367
31405
|
output: 1.2,
|
|
@@ -43556,9 +43594,9 @@ var init_values2 = __esm({
|
|
|
43556
43594
|
}
|
|
43557
43595
|
return n;
|
|
43558
43596
|
};
|
|
43559
|
-
safeJSON2 = (
|
|
43597
|
+
safeJSON2 = (text2) => {
|
|
43560
43598
|
try {
|
|
43561
|
-
return JSON.parse(
|
|
43599
|
+
return JSON.parse(text2);
|
|
43562
43600
|
} catch (err) {
|
|
43563
43601
|
return void 0;
|
|
43564
43602
|
}
|
|
@@ -44332,8 +44370,8 @@ async function defaultParseResponse2(client, props) {
|
|
|
44332
44370
|
const json2 = await response.json();
|
|
44333
44371
|
return addRequestID2(json2, response);
|
|
44334
44372
|
}
|
|
44335
|
-
const
|
|
44336
|
-
return
|
|
44373
|
+
const text2 = await response.text();
|
|
44374
|
+
return text2;
|
|
44337
44375
|
})();
|
|
44338
44376
|
loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
|
|
44339
44377
|
retryOfRequestLogID,
|
|
@@ -50636,11 +50674,11 @@ var init_simple_options = __esm({
|
|
|
50636
50674
|
});
|
|
50637
50675
|
|
|
50638
50676
|
// packages/ai/dist/providers/transform-messages.js
|
|
50639
|
-
function
|
|
50677
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
50640
50678
|
const result = [];
|
|
50641
50679
|
let previousWasPlaceholder = false;
|
|
50642
50680
|
for (const block of content) {
|
|
50643
|
-
if (block.type ===
|
|
50681
|
+
if (block.type === dropType) {
|
|
50644
50682
|
if (!previousWasPlaceholder) {
|
|
50645
50683
|
result.push({ type: "text", text: placeholder });
|
|
50646
50684
|
}
|
|
@@ -50648,33 +50686,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
50648
50686
|
continue;
|
|
50649
50687
|
}
|
|
50650
50688
|
result.push(block);
|
|
50651
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
50689
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
50652
50690
|
}
|
|
50653
50691
|
return result;
|
|
50654
50692
|
}
|
|
50655
|
-
function
|
|
50656
|
-
|
|
50693
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
50694
|
+
const supportsImage = model.input.includes("image");
|
|
50695
|
+
const supportsVideo = model.input.includes("video");
|
|
50696
|
+
if (supportsImage && supportsVideo) {
|
|
50657
50697
|
return messages;
|
|
50658
50698
|
}
|
|
50659
50699
|
return messages.map((msg) => {
|
|
50660
50700
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
50661
|
-
|
|
50662
|
-
|
|
50663
|
-
content
|
|
50664
|
-
|
|
50701
|
+
let content = msg.content;
|
|
50702
|
+
if (!supportsImage)
|
|
50703
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
50704
|
+
if (!supportsVideo)
|
|
50705
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
50706
|
+
return { ...msg, content };
|
|
50665
50707
|
}
|
|
50666
50708
|
if (msg.role === "toolResult") {
|
|
50667
|
-
|
|
50668
|
-
|
|
50669
|
-
content
|
|
50670
|
-
|
|
50709
|
+
let content = msg.content;
|
|
50710
|
+
if (!supportsImage)
|
|
50711
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
50712
|
+
if (!supportsVideo)
|
|
50713
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
50714
|
+
return { ...msg, content };
|
|
50671
50715
|
}
|
|
50672
50716
|
return msg;
|
|
50673
50717
|
});
|
|
50674
50718
|
}
|
|
50675
50719
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
50676
50720
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
50677
|
-
const imageAwareMessages =
|
|
50721
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
50678
50722
|
const transformed = imageAwareMessages.map((msg) => {
|
|
50679
50723
|
if (msg.role === "user") {
|
|
50680
50724
|
return msg;
|
|
@@ -50786,13 +50830,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
50786
50830
|
insertSyntheticToolResults();
|
|
50787
50831
|
return result;
|
|
50788
50832
|
}
|
|
50789
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
50833
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
50790
50834
|
var init_transform_messages = __esm({
|
|
50791
50835
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
50792
50836
|
"use strict";
|
|
50793
50837
|
init_esm_shims();
|
|
50794
50838
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
50795
50839
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
50840
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
50841
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
50796
50842
|
}
|
|
50797
50843
|
});
|
|
50798
50844
|
|
|
@@ -50823,8 +50869,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
50823
50869
|
};
|
|
50824
50870
|
}
|
|
50825
50871
|
function convertContentBlocks(content) {
|
|
50826
|
-
const
|
|
50827
|
-
if (!
|
|
50872
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
50873
|
+
if (!hasMedia) {
|
|
50828
50874
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
50829
50875
|
}
|
|
50830
50876
|
const blocks = content.map((block) => {
|
|
@@ -50834,6 +50880,16 @@ function convertContentBlocks(content) {
|
|
|
50834
50880
|
text: sanitizeSurrogates(block.text)
|
|
50835
50881
|
};
|
|
50836
50882
|
}
|
|
50883
|
+
if (block.type === "video") {
|
|
50884
|
+
return {
|
|
50885
|
+
type: "video",
|
|
50886
|
+
source: {
|
|
50887
|
+
type: "base64",
|
|
50888
|
+
media_type: block.mimeType,
|
|
50889
|
+
data: block.data
|
|
50890
|
+
}
|
|
50891
|
+
};
|
|
50892
|
+
}
|
|
50837
50893
|
return {
|
|
50838
50894
|
type: "image",
|
|
50839
50895
|
source: {
|
|
@@ -50847,7 +50903,7 @@ function convertContentBlocks(content) {
|
|
|
50847
50903
|
if (!hasText) {
|
|
50848
50904
|
blocks.unshift({
|
|
50849
50905
|
type: "text",
|
|
50850
|
-
text: "(see attached
|
|
50906
|
+
text: "(see attached media)"
|
|
50851
50907
|
});
|
|
50852
50908
|
}
|
|
50853
50909
|
return blocks;
|
|
@@ -50908,9 +50964,9 @@ function decodeSseLine(line, state) {
|
|
|
50908
50964
|
}
|
|
50909
50965
|
return null;
|
|
50910
50966
|
}
|
|
50911
|
-
function nextLineBreakIndex(
|
|
50912
|
-
const carriageReturnIndex =
|
|
50913
|
-
const newlineIndex =
|
|
50967
|
+
function nextLineBreakIndex(text2) {
|
|
50968
|
+
const carriageReturnIndex = text2.indexOf("\r");
|
|
50969
|
+
const newlineIndex = text2.indexOf("\n");
|
|
50914
50970
|
if (carriageReturnIndex === -1) {
|
|
50915
50971
|
return newlineIndex;
|
|
50916
50972
|
}
|
|
@@ -50919,18 +50975,18 @@ function nextLineBreakIndex(text) {
|
|
|
50919
50975
|
}
|
|
50920
50976
|
return Math.min(carriageReturnIndex, newlineIndex);
|
|
50921
50977
|
}
|
|
50922
|
-
function consumeLine(
|
|
50923
|
-
const lineBreakIndex = nextLineBreakIndex(
|
|
50978
|
+
function consumeLine(text2) {
|
|
50979
|
+
const lineBreakIndex = nextLineBreakIndex(text2);
|
|
50924
50980
|
if (lineBreakIndex === -1) {
|
|
50925
50981
|
return null;
|
|
50926
50982
|
}
|
|
50927
50983
|
let nextIndex = lineBreakIndex + 1;
|
|
50928
|
-
if (
|
|
50984
|
+
if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
|
|
50929
50985
|
nextIndex += 1;
|
|
50930
50986
|
}
|
|
50931
50987
|
return {
|
|
50932
|
-
line:
|
|
50933
|
-
rest:
|
|
50988
|
+
line: text2.slice(0, lineBreakIndex),
|
|
50989
|
+
rest: text2.slice(nextIndex)
|
|
50934
50990
|
};
|
|
50935
50991
|
}
|
|
50936
50992
|
async function* iterateSseMessages(body, signal) {
|
|
@@ -51197,6 +51253,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
51197
51253
|
type: "text",
|
|
51198
51254
|
text: sanitizeSurrogates(item.text)
|
|
51199
51255
|
};
|
|
51256
|
+
} else if (item.type === "video") {
|
|
51257
|
+
return {
|
|
51258
|
+
type: "video",
|
|
51259
|
+
source: {
|
|
51260
|
+
type: "base64",
|
|
51261
|
+
media_type: item.mimeType,
|
|
51262
|
+
data: item.data
|
|
51263
|
+
}
|
|
51264
|
+
};
|
|
51200
51265
|
} else {
|
|
51201
51266
|
return {
|
|
51202
51267
|
type: "image",
|
|
@@ -51277,6 +51342,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
51277
51342
|
toolResults.push({
|
|
51278
51343
|
type: "tool_result",
|
|
51279
51344
|
tool_use_id: msg.toolCallId,
|
|
51345
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
51346
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
51280
51347
|
content: convertContentBlocks(msg.content),
|
|
51281
51348
|
is_error: msg.isError
|
|
51282
51349
|
});
|
|
@@ -51303,7 +51370,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
51303
51370
|
if (lastMessage.role === "user") {
|
|
51304
51371
|
if (Array.isArray(lastMessage.content)) {
|
|
51305
51372
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
51306
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
51373
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
51307
51374
|
lastBlock.cache_control = cacheControl;
|
|
51308
51375
|
}
|
|
51309
51376
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -53086,8 +53153,8 @@ var require_common = __commonJS({
|
|
|
53086
53153
|
}
|
|
53087
53154
|
function redactString(obj, key) {
|
|
53088
53155
|
if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
|
|
53089
|
-
const
|
|
53090
|
-
if (/grant_type=/i.test(
|
|
53156
|
+
const text2 = obj[key];
|
|
53157
|
+
if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
|
|
53091
53158
|
obj[key] = REDACT;
|
|
53092
53159
|
}
|
|
53093
53160
|
}
|
|
@@ -59915,8 +59982,8 @@ var init_body = __esm({
|
|
|
59915
59982
|
* @return Promise
|
|
59916
59983
|
*/
|
|
59917
59984
|
async json() {
|
|
59918
|
-
const
|
|
59919
|
-
return JSON.parse(
|
|
59985
|
+
const text2 = await this.text();
|
|
59986
|
+
return JSON.parse(text2);
|
|
59920
59987
|
}
|
|
59921
59988
|
/**
|
|
59922
59989
|
* Decode response as text
|
|
@@ -61068,7 +61135,7 @@ var require_gaxios = __commonJS({
|
|
|
61068
61135
|
var retry_js_1 = require_retry3();
|
|
61069
61136
|
var stream_1 = __require("stream");
|
|
61070
61137
|
var interceptor_js_1 = require_interceptor();
|
|
61071
|
-
var
|
|
61138
|
+
var randomUUID11 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
61072
61139
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
61073
61140
|
var Gaxios = class {
|
|
61074
61141
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -61341,7 +61408,7 @@ var require_gaxios = __commonJS({
|
|
|
61341
61408
|
*/
|
|
61342
61409
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
61343
61410
|
if (opts.multipart?.length) {
|
|
61344
|
-
const boundary = await
|
|
61411
|
+
const boundary = await randomUUID11();
|
|
61345
61412
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
61346
61413
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
61347
61414
|
} else if (shouldDirectlyPassData) {
|
|
@@ -63092,18 +63159,18 @@ var require_parse = __commonJS({
|
|
|
63092
63159
|
n: "\n",
|
|
63093
63160
|
r: "\r",
|
|
63094
63161
|
t: " "
|
|
63095
|
-
},
|
|
63162
|
+
}, text2, error = function(m2) {
|
|
63096
63163
|
throw {
|
|
63097
63164
|
name: "SyntaxError",
|
|
63098
63165
|
message: m2,
|
|
63099
63166
|
at,
|
|
63100
|
-
text
|
|
63167
|
+
text: text2
|
|
63101
63168
|
};
|
|
63102
63169
|
}, next = function(c) {
|
|
63103
63170
|
if (c && c !== ch) {
|
|
63104
63171
|
error("Expected '" + c + "' instead of '" + ch + "'");
|
|
63105
63172
|
}
|
|
63106
|
-
ch =
|
|
63173
|
+
ch = text2.charAt(at);
|
|
63107
63174
|
at += 1;
|
|
63108
63175
|
return ch;
|
|
63109
63176
|
}, number44 = function() {
|
|
@@ -63150,12 +63217,12 @@ var require_parse = __commonJS({
|
|
|
63150
63217
|
var startAt = at;
|
|
63151
63218
|
while (next()) {
|
|
63152
63219
|
if (ch === '"') {
|
|
63153
|
-
if (at - 1 > startAt) string474 +=
|
|
63220
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
63154
63221
|
next();
|
|
63155
63222
|
return string474;
|
|
63156
63223
|
}
|
|
63157
63224
|
if (ch === "\\") {
|
|
63158
|
-
if (at - 1 > startAt) string474 +=
|
|
63225
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
63159
63226
|
next();
|
|
63160
63227
|
if (ch === "u") {
|
|
63161
63228
|
uffff = 0;
|
|
@@ -63288,7 +63355,7 @@ var require_parse = __commonJS({
|
|
|
63288
63355
|
};
|
|
63289
63356
|
return function(source, reviver) {
|
|
63290
63357
|
var result;
|
|
63291
|
-
|
|
63358
|
+
text2 = source + "";
|
|
63292
63359
|
at = 0;
|
|
63293
63360
|
ch = " ";
|
|
63294
63361
|
result = value();
|
|
@@ -64200,8 +64267,8 @@ var require_crypto = __commonJS({
|
|
|
64200
64267
|
const result = new TextDecoder().decode(uint8array);
|
|
64201
64268
|
return result;
|
|
64202
64269
|
}
|
|
64203
|
-
encodeBase64StringUtf8(
|
|
64204
|
-
const uint8array = new TextEncoder().encode(
|
|
64270
|
+
encodeBase64StringUtf8(text2) {
|
|
64271
|
+
const uint8array = new TextEncoder().encode(text2);
|
|
64205
64272
|
const result = base64js.fromByteArray(uint8array);
|
|
64206
64273
|
return result;
|
|
64207
64274
|
}
|
|
@@ -64270,8 +64337,8 @@ var require_crypto2 = __commonJS({
|
|
|
64270
64337
|
decodeBase64StringUtf8(base64) {
|
|
64271
64338
|
return Buffer.from(base64, "base64").toString("utf-8");
|
|
64272
64339
|
}
|
|
64273
|
-
encodeBase64StringUtf8(
|
|
64274
|
-
return Buffer.from(
|
|
64340
|
+
encodeBase64StringUtf8(text2) {
|
|
64341
|
+
return Buffer.from(text2, "utf-8").toString("base64");
|
|
64275
64342
|
}
|
|
64276
64343
|
/**
|
|
64277
64344
|
* Computes the SHA-256 hash of the provided string.
|
|
@@ -84716,8 +84783,8 @@ async function defaultParseResponse3(client, props) {
|
|
|
84716
84783
|
const json2 = await response.json();
|
|
84717
84784
|
return json2;
|
|
84718
84785
|
}
|
|
84719
|
-
const
|
|
84720
|
-
return
|
|
84786
|
+
const text2 = await response.text();
|
|
84787
|
+
return text2;
|
|
84721
84788
|
})();
|
|
84722
84789
|
loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
|
|
84723
84790
|
retryOfRequestLogID,
|
|
@@ -86294,7 +86361,7 @@ var init_node = __esm({
|
|
|
86294
86361
|
if (this.candidates && this.candidates.length > 1) {
|
|
86295
86362
|
console.warn("there are multiple candidates in the response, returning text from the first one.");
|
|
86296
86363
|
}
|
|
86297
|
-
let
|
|
86364
|
+
let text2 = "";
|
|
86298
86365
|
let anyTextPartText = false;
|
|
86299
86366
|
const nonTextParts = [];
|
|
86300
86367
|
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 : []) {
|
|
@@ -86308,13 +86375,13 @@ var init_node = __esm({
|
|
|
86308
86375
|
continue;
|
|
86309
86376
|
}
|
|
86310
86377
|
anyTextPartText = true;
|
|
86311
|
-
|
|
86378
|
+
text2 += part.text;
|
|
86312
86379
|
}
|
|
86313
86380
|
}
|
|
86314
86381
|
if (nonTextParts.length > 0) {
|
|
86315
86382
|
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.`);
|
|
86316
86383
|
}
|
|
86317
|
-
return anyTextPartText ?
|
|
86384
|
+
return anyTextPartText ? text2 : void 0;
|
|
86318
86385
|
}
|
|
86319
86386
|
/**
|
|
86320
86387
|
* Returns the concatenation of all inline data parts from the first candidate
|
|
@@ -86567,7 +86634,7 @@ var init_node = __esm({
|
|
|
86567
86634
|
*/
|
|
86568
86635
|
get text() {
|
|
86569
86636
|
var _a5, _b, _c;
|
|
86570
|
-
let
|
|
86637
|
+
let text2 = "";
|
|
86571
86638
|
let anyTextPartFound = false;
|
|
86572
86639
|
const nonTextParts = [];
|
|
86573
86640
|
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 : []) {
|
|
@@ -86581,13 +86648,13 @@ var init_node = __esm({
|
|
|
86581
86648
|
continue;
|
|
86582
86649
|
}
|
|
86583
86650
|
anyTextPartFound = true;
|
|
86584
|
-
|
|
86651
|
+
text2 += part.text;
|
|
86585
86652
|
}
|
|
86586
86653
|
}
|
|
86587
86654
|
if (nonTextParts.length > 0) {
|
|
86588
86655
|
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.`);
|
|
86589
86656
|
}
|
|
86590
|
-
return anyTextPartFound ?
|
|
86657
|
+
return anyTextPartFound ? text2 : void 0;
|
|
86591
86658
|
}
|
|
86592
86659
|
/**
|
|
86593
86660
|
* Returns the concatenation of all inline data parts from the server content if present.
|
|
@@ -91259,9 +91326,9 @@ var init_node = __esm({
|
|
|
91259
91326
|
}
|
|
91260
91327
|
return n;
|
|
91261
91328
|
};
|
|
91262
|
-
safeJSON3 = (
|
|
91329
|
+
safeJSON3 = (text2) => {
|
|
91263
91330
|
try {
|
|
91264
|
-
return JSON.parse(
|
|
91331
|
+
return JSON.parse(text2);
|
|
91265
91332
|
} catch (err) {
|
|
91266
91333
|
return void 0;
|
|
91267
91334
|
}
|
|
@@ -109124,8 +109191,8 @@ function findBoundary(buf) {
|
|
|
109124
109191
|
return null;
|
|
109125
109192
|
}
|
|
109126
109193
|
function parseMessage2(chunk, parse2, state, dataRequired) {
|
|
109127
|
-
const
|
|
109128
|
-
const lines =
|
|
109194
|
+
const text2 = new TextDecoder().decode(chunk);
|
|
109195
|
+
const lines = text2.split(/\r\n|\r|\n/);
|
|
109129
109196
|
const dataLines = [];
|
|
109130
109197
|
const ret = {};
|
|
109131
109198
|
let ignore = true;
|
|
@@ -131999,10 +132066,10 @@ function formatMistralError(error) {
|
|
|
131999
132066
|
}
|
|
132000
132067
|
return safeJsonStringify(error);
|
|
132001
132068
|
}
|
|
132002
|
-
function truncateErrorText(
|
|
132003
|
-
if (
|
|
132004
|
-
return
|
|
132005
|
-
return `${
|
|
132069
|
+
function truncateErrorText(text2, maxChars) {
|
|
132070
|
+
if (text2.length <= maxChars)
|
|
132071
|
+
return text2;
|
|
132072
|
+
return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
|
|
132006
132073
|
}
|
|
132007
132074
|
function safeJsonStringify(value) {
|
|
132008
132075
|
try {
|
|
@@ -132122,7 +132189,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
|
|
|
132122
132189
|
continue;
|
|
132123
132190
|
}
|
|
132124
132191
|
if (item.type === "thinking") {
|
|
132125
|
-
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((
|
|
132192
|
+
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
|
|
132126
132193
|
const thinkingDelta = sanitizeSurrogates(deltaText);
|
|
132127
132194
|
if (!thinkingDelta)
|
|
132128
132195
|
continue;
|
|
@@ -132319,8 +132386,8 @@ function toChatMessages(messages, supportsImages) {
|
|
|
132319
132386
|
}
|
|
132320
132387
|
return result;
|
|
132321
132388
|
}
|
|
132322
|
-
function buildToolResultText(
|
|
132323
|
-
const trimmed =
|
|
132389
|
+
function buildToolResultText(text2, hasImages, supportsImages, isError) {
|
|
132390
|
+
const trimmed = text2.trim();
|
|
132324
132391
|
const errorPrefix = isError ? "[tool error] " : "";
|
|
132325
132392
|
if (trimmed.length > 0) {
|
|
132326
132393
|
const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
|
|
@@ -133121,14 +133188,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
133121
133188
|
};
|
|
133122
133189
|
const onMessage = (event) => {
|
|
133123
133190
|
void (async () => {
|
|
133124
|
-
let
|
|
133191
|
+
let text2 = null;
|
|
133125
133192
|
try {
|
|
133126
133193
|
if (!event || typeof event !== "object" || !("data" in event))
|
|
133127
133194
|
return;
|
|
133128
|
-
|
|
133129
|
-
if (!
|
|
133195
|
+
text2 = await decodeWebSocketData(event.data);
|
|
133196
|
+
if (!text2)
|
|
133130
133197
|
return;
|
|
133131
|
-
const parsed = JSON.parse(
|
|
133198
|
+
const parsed = JSON.parse(text2);
|
|
133132
133199
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
133133
133200
|
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
133134
133201
|
sawCompletion = true;
|
|
@@ -133139,7 +133206,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
133139
133206
|
} catch (cause) {
|
|
133140
133207
|
failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
|
|
133141
133208
|
cause,
|
|
133142
|
-
payload:
|
|
133209
|
+
payload: text2
|
|
133143
133210
|
});
|
|
133144
133211
|
done = true;
|
|
133145
133212
|
wake();
|
|
@@ -141303,11 +141370,11 @@ function videoRequestConfig(input) {
|
|
|
141303
141370
|
};
|
|
141304
141371
|
}
|
|
141305
141372
|
async function readMiniMaxJson(response) {
|
|
141306
|
-
const
|
|
141373
|
+
const text2 = await response.text();
|
|
141307
141374
|
let body = {};
|
|
141308
|
-
if (
|
|
141375
|
+
if (text2) {
|
|
141309
141376
|
try {
|
|
141310
|
-
const parsed = JSON.parse(
|
|
141377
|
+
const parsed = JSON.parse(text2);
|
|
141311
141378
|
if (isRecord(parsed)) body = parsed;
|
|
141312
141379
|
} catch {
|
|
141313
141380
|
throw new Error("MiniMax video API returned invalid JSON");
|
|
@@ -142128,6 +142195,7 @@ __export(store_exports, {
|
|
|
142128
142195
|
CodeGraphStore: () => CodeGraphStore
|
|
142129
142196
|
});
|
|
142130
142197
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
142198
|
+
import { posix as pathPosix } from "path";
|
|
142131
142199
|
function rowToFile(row) {
|
|
142132
142200
|
return {
|
|
142133
142201
|
id: row.id,
|
|
@@ -142178,6 +142246,26 @@ function rowToEdge(row) {
|
|
|
142178
142246
|
...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
|
|
142179
142247
|
};
|
|
142180
142248
|
}
|
|
142249
|
+
function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
|
|
142250
|
+
const target = evidence?.trim().replace(/\\/g, "/");
|
|
142251
|
+
if (!target?.startsWith(".")) return void 0;
|
|
142252
|
+
const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
|
|
142253
|
+
if (!base || base === ".." || base.startsWith("../")) return void 0;
|
|
142254
|
+
const candidates = [base];
|
|
142255
|
+
const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
|
|
142256
|
+
const hasExtension = Boolean(extensionMatch);
|
|
142257
|
+
if (!hasExtension) {
|
|
142258
|
+
const extensions = [...new Set([...fileByPath.keys()].map((path19) => path19.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
|
|
142259
|
+
for (const extension3 of extensions) {
|
|
142260
|
+
candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
|
|
142261
|
+
}
|
|
142262
|
+
} else {
|
|
142263
|
+
const sourceStem = base.slice(0, -extensionMatch[1].length);
|
|
142264
|
+
const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
|
|
142265
|
+
for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
|
|
142266
|
+
}
|
|
142267
|
+
return candidates.map((candidate) => fileByPath.get(candidate)).find((file) => Boolean(file));
|
|
142268
|
+
}
|
|
142181
142269
|
function rowToRef(row) {
|
|
142182
142270
|
return {
|
|
142183
142271
|
id: row.id,
|
|
@@ -142238,6 +142326,18 @@ function rowToSnapshot(row) {
|
|
|
142238
142326
|
...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
|
|
142239
142327
|
};
|
|
142240
142328
|
}
|
|
142329
|
+
function rowToSnapshotFile(row) {
|
|
142330
|
+
return {
|
|
142331
|
+
snapshotId: row.snapshotId,
|
|
142332
|
+
projectId: row.projectId,
|
|
142333
|
+
fileId: row.fileId,
|
|
142334
|
+
path: row.path,
|
|
142335
|
+
contentHash: row.contentHash
|
|
142336
|
+
};
|
|
142337
|
+
}
|
|
142338
|
+
function snapshotIsIncomplete(snapshot) {
|
|
142339
|
+
return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
|
|
142340
|
+
}
|
|
142241
142341
|
var CodeGraphStore;
|
|
142242
142342
|
var init_store = __esm({
|
|
142243
142343
|
"src/codegraph/store.ts"() {
|
|
@@ -142409,6 +142509,7 @@ var init_store = __esm({
|
|
|
142409
142509
|
}
|
|
142410
142510
|
});
|
|
142411
142511
|
tx();
|
|
142512
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142412
142513
|
}
|
|
142413
142514
|
/**
|
|
142414
142515
|
* Reconcile only files whose source changed plus files that disappeared.
|
|
@@ -142418,7 +142519,10 @@ var init_store = __esm({
|
|
|
142418
142519
|
const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
|
|
142419
142520
|
const metadataOnly = (input.metadataOnly ?? []).filter((file) => file.projectId === projectId);
|
|
142420
142521
|
const removedFileIds = input.removedFileIds ?? [];
|
|
142421
|
-
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0)
|
|
142522
|
+
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
|
|
142523
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142524
|
+
return;
|
|
142525
|
+
}
|
|
142422
142526
|
const staleRefsForFile = this.db.prepare(`
|
|
142423
142527
|
UPDATE observation_code_refs
|
|
142424
142528
|
SET status = 'stale', updatedAt = ?
|
|
@@ -142428,9 +142532,18 @@ var init_store = __esm({
|
|
|
142428
142532
|
)
|
|
142429
142533
|
)
|
|
142430
142534
|
`);
|
|
142431
|
-
const
|
|
142535
|
+
const deleteEdgesFromFile = this.db.prepare(`
|
|
142432
142536
|
DELETE FROM code_edges
|
|
142433
|
-
WHERE projectId = ? AND
|
|
142537
|
+
WHERE projectId = ? AND fromFileId = ?
|
|
142538
|
+
`);
|
|
142539
|
+
const clearImportTargetsForFile = this.db.prepare(`
|
|
142540
|
+
UPDATE code_edges
|
|
142541
|
+
SET toFileId = NULL
|
|
142542
|
+
WHERE projectId = ? AND toFileId = ? AND type = 'imports'
|
|
142543
|
+
`);
|
|
142544
|
+
const deleteOtherIncomingEdgesForFile = this.db.prepare(`
|
|
142545
|
+
DELETE FROM code_edges
|
|
142546
|
+
WHERE projectId = ? AND toFileId = ? AND type != 'imports'
|
|
142434
142547
|
`);
|
|
142435
142548
|
const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
|
|
142436
142549
|
const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
|
|
@@ -142467,14 +142580,18 @@ var init_store = __esm({
|
|
|
142467
142580
|
const staleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
142468
142581
|
for (const fileId of removedFileIds) {
|
|
142469
142582
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
142470
|
-
|
|
142583
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
142584
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
142585
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
142471
142586
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
142472
142587
|
deleteFile.run(projectId, fileId);
|
|
142473
142588
|
}
|
|
142474
142589
|
for (const delta of changed) {
|
|
142475
142590
|
const fileId = delta.file.id;
|
|
142476
142591
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
142477
|
-
|
|
142592
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
142593
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
142594
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
142478
142595
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
142479
142596
|
writeFile5(delta.file);
|
|
142480
142597
|
for (const symbol of delta.symbols) {
|
|
@@ -142512,6 +142629,7 @@ var init_store = __esm({
|
|
|
142512
142629
|
for (const file of metadataOnly) writeFile5(file);
|
|
142513
142630
|
});
|
|
142514
142631
|
tx();
|
|
142632
|
+
this.reconcileLocalImportTargets(projectId);
|
|
142515
142633
|
}
|
|
142516
142634
|
upsertObservationRefs(refs) {
|
|
142517
142635
|
if (refs.length === 0) return;
|
|
@@ -142573,6 +142691,25 @@ var init_store = __esm({
|
|
|
142573
142691
|
});
|
|
142574
142692
|
tx();
|
|
142575
142693
|
}
|
|
142694
|
+
/**
|
|
142695
|
+
* Lite import extraction records the original import text first. Resolve only
|
|
142696
|
+
* local relative imports against the current index after each refresh, so an
|
|
142697
|
+
* added or removed target cannot leave a fabricated file-to-file relation.
|
|
142698
|
+
*/
|
|
142699
|
+
reconcileLocalImportTargets(projectId) {
|
|
142700
|
+
const fileById = new Map(this.listFiles(projectId).map((file) => [file.id, file]));
|
|
142701
|
+
const fileByPath = new Map([...fileById.values()].map((file) => [file.path, file]));
|
|
142702
|
+
const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
|
|
142703
|
+
const tx = this.db.transaction(() => {
|
|
142704
|
+
for (const edge of this.listEdges(projectId)) {
|
|
142705
|
+
if (edge.type !== "imports" || !edge.fromFileId) continue;
|
|
142706
|
+
const source = fileById.get(edge.fromFileId);
|
|
142707
|
+
const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
|
|
142708
|
+
update2.run(target?.id ?? null, edge.id);
|
|
142709
|
+
}
|
|
142710
|
+
});
|
|
142711
|
+
tx();
|
|
142712
|
+
}
|
|
142576
142713
|
getFile(projectId, path19) {
|
|
142577
142714
|
const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path19));
|
|
142578
142715
|
return row ? rowToFile(row) : null;
|
|
@@ -142647,6 +142784,18 @@ var init_store = __esm({
|
|
|
142647
142784
|
ORDER BY observationId, status, id
|
|
142648
142785
|
`).all(projectId).map(rowToRef);
|
|
142649
142786
|
}
|
|
142787
|
+
/** Count distinct observations whose binding to these exact files is stale. */
|
|
142788
|
+
countStaleObservationRefsForFiles(projectId, fileIds) {
|
|
142789
|
+
const ids = [...new Set(fileIds.filter(Boolean))];
|
|
142790
|
+
if (ids.length === 0) return 0;
|
|
142791
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
142792
|
+
const row = this.db.prepare(`
|
|
142793
|
+
SELECT COUNT(DISTINCT observationId) AS count
|
|
142794
|
+
FROM observation_code_refs
|
|
142795
|
+
WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
|
|
142796
|
+
`).get(projectId, ...ids);
|
|
142797
|
+
return Number(row?.count ?? 0);
|
|
142798
|
+
}
|
|
142650
142799
|
listReferencedSymbols(projectId) {
|
|
142651
142800
|
return this.db.prepare(`
|
|
142652
142801
|
SELECT DISTINCT symbols.*
|
|
@@ -142668,6 +142817,94 @@ var init_store = __esm({
|
|
|
142668
142817
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
142669
142818
|
).all(projectId, safeLimit).map(rowToSnapshot);
|
|
142670
142819
|
}
|
|
142820
|
+
listSnapshotFiles(snapshotId) {
|
|
142821
|
+
return this.db.prepare(`
|
|
142822
|
+
SELECT snapshotId, projectId, fileId, path, contentHash
|
|
142823
|
+
FROM code_state_snapshot_files
|
|
142824
|
+
WHERE snapshotId = ?
|
|
142825
|
+
ORDER BY path
|
|
142826
|
+
`).all(snapshotId).map(rowToSnapshotFile);
|
|
142827
|
+
}
|
|
142828
|
+
diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
|
|
142829
|
+
const snapshots = this.db.prepare(`
|
|
142830
|
+
SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
|
|
142831
|
+
`).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
|
|
142832
|
+
if (snapshots.length !== 2) {
|
|
142833
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
|
|
142834
|
+
}
|
|
142835
|
+
if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
|
|
142836
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
|
|
142837
|
+
}
|
|
142838
|
+
if (snapshots.some(snapshotIsIncomplete)) {
|
|
142839
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
|
|
142840
|
+
}
|
|
142841
|
+
const before = this.listSnapshotFiles(fromSnapshotId);
|
|
142842
|
+
const after = this.listSnapshotFiles(toSnapshotId);
|
|
142843
|
+
if (before.length === 0 || after.length === 0) {
|
|
142844
|
+
return {
|
|
142845
|
+
projectId,
|
|
142846
|
+
fromSnapshotId,
|
|
142847
|
+
toSnapshotId,
|
|
142848
|
+
available: false,
|
|
142849
|
+
reason: "legacy-snapshot-without-manifest",
|
|
142850
|
+
changes: []
|
|
142851
|
+
};
|
|
142852
|
+
}
|
|
142853
|
+
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
142854
|
+
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
142855
|
+
const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
|
|
142856
|
+
const changes = [];
|
|
142857
|
+
for (const path19 of paths) {
|
|
142858
|
+
const oldFile = beforeByPath.get(path19);
|
|
142859
|
+
const newFile = afterByPath.get(path19);
|
|
142860
|
+
if (!oldFile && newFile) {
|
|
142861
|
+
changes.push({ path: path19, kind: "added", afterHash: newFile.contentHash });
|
|
142862
|
+
} else if (oldFile && !newFile) {
|
|
142863
|
+
changes.push({ path: path19, kind: "removed", beforeHash: oldFile.contentHash });
|
|
142864
|
+
} else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
|
|
142865
|
+
changes.push({ path: path19, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
|
|
142866
|
+
}
|
|
142867
|
+
}
|
|
142868
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
|
|
142869
|
+
}
|
|
142870
|
+
impactSlice(projectId, changedPaths, maxRelations = 24) {
|
|
142871
|
+
const safeLimit = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
|
|
142872
|
+
const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
|
|
142873
|
+
const files = this.listFiles(projectId);
|
|
142874
|
+
const fileById = new Map(files.map((file) => [file.id, file.path]));
|
|
142875
|
+
const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol) => [symbol.id, symbol.fileId]));
|
|
142876
|
+
const changedIds = new Set(files.filter((file) => normalizedPaths.includes(file.path)).map((file) => file.id));
|
|
142877
|
+
const direct = /* @__PURE__ */ new Set();
|
|
142878
|
+
let relationCount = 0;
|
|
142879
|
+
let truncated = false;
|
|
142880
|
+
for (const edge of this.listEdges(projectId)) {
|
|
142881
|
+
const endpoints = [
|
|
142882
|
+
edge.fromFileId,
|
|
142883
|
+
edge.toFileId,
|
|
142884
|
+
edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
|
|
142885
|
+
edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
|
|
142886
|
+
].filter((id) => Boolean(id));
|
|
142887
|
+
if (!endpoints.some((id) => changedIds.has(id))) continue;
|
|
142888
|
+
const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path19) => Boolean(path19));
|
|
142889
|
+
if (relatedPaths.length === 0) continue;
|
|
142890
|
+
if (relationCount >= safeLimit) {
|
|
142891
|
+
truncated = true;
|
|
142892
|
+
break;
|
|
142893
|
+
}
|
|
142894
|
+
relationCount += 1;
|
|
142895
|
+
for (const path19 of relatedPaths) direct.add(path19);
|
|
142896
|
+
}
|
|
142897
|
+
const snapshot = this.latestSnapshot(projectId);
|
|
142898
|
+
return {
|
|
142899
|
+
projectId,
|
|
142900
|
+
...snapshot ? { snapshotId: snapshot.id } : {},
|
|
142901
|
+
changedPaths: normalizedPaths,
|
|
142902
|
+
directlyConnectedPaths: [...direct].sort(),
|
|
142903
|
+
relationCount,
|
|
142904
|
+
truncated,
|
|
142905
|
+
provider: snapshot?.provider ?? "lite"
|
|
142906
|
+
};
|
|
142907
|
+
}
|
|
142671
142908
|
/**
|
|
142672
142909
|
* Record a completed scan and mark all current structural facts with its
|
|
142673
142910
|
* epoch. The snapshot is written only after refresh reconciliation succeeds,
|
|
@@ -142709,6 +142946,16 @@ var init_store = __esm({
|
|
|
142709
142946
|
this.db.prepare(
|
|
142710
142947
|
"UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
|
|
142711
142948
|
).run(id, input.projectId);
|
|
142949
|
+
const snapshotFileRows = this.db.prepare(`
|
|
142950
|
+
SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
|
|
142951
|
+
`).all(input.projectId);
|
|
142952
|
+
const insertSnapshotFile = this.db.prepare(`
|
|
142953
|
+
INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
|
|
142954
|
+
VALUES (?, ?, ?, ?, ?)
|
|
142955
|
+
`);
|
|
142956
|
+
for (const file of snapshotFileRows) {
|
|
142957
|
+
insertSnapshotFile.run(id, file.projectId, file.id, file.path, file.contentHash);
|
|
142958
|
+
}
|
|
142712
142959
|
snapshot = {
|
|
142713
142960
|
...input,
|
|
142714
142961
|
id,
|
|
@@ -142874,8 +143121,8 @@ __export(lite_provider_exports, {
|
|
|
142874
143121
|
import { createHash as createHash7 } from "crypto";
|
|
142875
143122
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
142876
143123
|
import { join as join4, relative } from "path";
|
|
142877
|
-
function hashText(
|
|
142878
|
-
return createHash7("sha256").update(
|
|
143124
|
+
function hashText(text2) {
|
|
143125
|
+
return createHash7("sha256").update(text2).digest("hex");
|
|
142879
143126
|
}
|
|
142880
143127
|
function extension2(path19) {
|
|
142881
143128
|
const index = path19.lastIndexOf(".");
|
|
@@ -142919,19 +143166,19 @@ function walk(root, exclude, maxFiles) {
|
|
|
142919
143166
|
visit(root);
|
|
142920
143167
|
return out;
|
|
142921
143168
|
}
|
|
142922
|
-
function lineOf(
|
|
142923
|
-
return
|
|
143169
|
+
function lineOf(text2, index) {
|
|
143170
|
+
return text2.slice(0, index).split(/\r?\n/).length;
|
|
142924
143171
|
}
|
|
142925
|
-
function extractSymbols(projectId, file,
|
|
143172
|
+
function extractSymbols(projectId, file, text2, indexedAt) {
|
|
142926
143173
|
const symbols = [];
|
|
142927
143174
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
142928
143175
|
const patterns = profile?.symbols ?? [];
|
|
142929
143176
|
for (const { kind, re } of patterns) {
|
|
142930
143177
|
re.lastIndex = 0;
|
|
142931
|
-
for (const match2 of
|
|
143178
|
+
for (const match2 of text2.matchAll(re)) {
|
|
142932
143179
|
const name = match2[1];
|
|
142933
143180
|
if (!name || name.includes("\n")) continue;
|
|
142934
|
-
const startLine = lineOf(
|
|
143181
|
+
const startLine = lineOf(text2, match2.index ?? 0);
|
|
142935
143182
|
const id = makeCodeSymbolId({ projectId, path: file.path, qualifiedName: name, kind });
|
|
142936
143183
|
symbols.push({
|
|
142937
143184
|
id,
|
|
@@ -142951,13 +143198,13 @@ function extractSymbols(projectId, file, text, indexedAt) {
|
|
|
142951
143198
|
}
|
|
142952
143199
|
return symbols;
|
|
142953
143200
|
}
|
|
142954
|
-
function extractImportEdges(projectId, file,
|
|
143201
|
+
function extractImportEdges(projectId, file, text2, indexedAt) {
|
|
142955
143202
|
const edges = [];
|
|
142956
143203
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
142957
143204
|
const imports = profile?.imports ?? [];
|
|
142958
143205
|
for (const re of imports) {
|
|
142959
143206
|
re.lastIndex = 0;
|
|
142960
|
-
for (const match2 of
|
|
143207
|
+
for (const match2 of text2.matchAll(re)) {
|
|
142961
143208
|
const target = (match2[1] ?? "").trim();
|
|
142962
143209
|
if (!target) continue;
|
|
142963
143210
|
if (target.includes("\n")) {
|
|
@@ -142992,14 +143239,14 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
142992
143239
|
function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
142993
143240
|
const rel = normalizeCodePath(relative(projectRoot, abs));
|
|
142994
143241
|
try {
|
|
142995
|
-
const
|
|
143242
|
+
const text2 = readFileSync6(abs, "utf-8");
|
|
142996
143243
|
const stat4 = fileStat ?? statSync3(abs);
|
|
142997
143244
|
const file = {
|
|
142998
143245
|
id: makeCodeFileId(projectId, rel),
|
|
142999
143246
|
projectId,
|
|
143000
143247
|
path: rel,
|
|
143001
143248
|
language: languageForPath(rel),
|
|
143002
|
-
contentHash: hashText(
|
|
143249
|
+
contentHash: hashText(text2),
|
|
143003
143250
|
// Preserve filesystem precision. Rounding here made same-size edits in
|
|
143004
143251
|
// a short Windows timestamp window indistinguishable to refresh.
|
|
143005
143252
|
mtimeMs: Number(stat4.mtimeMs),
|
|
@@ -143009,8 +143256,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
|
143009
143256
|
return {
|
|
143010
143257
|
delta: {
|
|
143011
143258
|
file,
|
|
143012
|
-
symbols: extractSymbols(projectId, file,
|
|
143013
|
-
edges: extractImportEdges(projectId, file,
|
|
143259
|
+
symbols: extractSymbols(projectId, file, text2, indexedAt),
|
|
143260
|
+
edges: extractImportEdges(projectId, file, text2, indexedAt)
|
|
143014
143261
|
},
|
|
143015
143262
|
unreadable: false
|
|
143016
143263
|
};
|
|
@@ -143289,18 +143536,18 @@ __export(binder_exports, {
|
|
|
143289
143536
|
function observationText(obs) {
|
|
143290
143537
|
return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
|
|
143291
143538
|
}
|
|
143292
|
-
function mentionsSymbol(
|
|
143539
|
+
function mentionsSymbol(text2, symbol) {
|
|
143293
143540
|
const name = symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
143294
|
-
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(
|
|
143541
|
+
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
|
|
143295
143542
|
}
|
|
143296
|
-
function identifierCandidates(
|
|
143297
|
-
return [...new Set(
|
|
143543
|
+
function identifierCandidates(text2) {
|
|
143544
|
+
return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
|
|
143298
143545
|
}
|
|
143299
|
-
function codeIdentifierCandidates(
|
|
143546
|
+
function codeIdentifierCandidates(text2) {
|
|
143300
143547
|
const explicit = /* @__PURE__ */ new Set();
|
|
143301
|
-
for (const match2 of
|
|
143302
|
-
for (const match2 of
|
|
143303
|
-
return identifierCandidates(
|
|
143548
|
+
for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
|
|
143549
|
+
for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
|
|
143550
|
+
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));
|
|
143304
143551
|
}
|
|
143305
143552
|
function fileRef(projectId, obs, file) {
|
|
143306
143553
|
return {
|
|
@@ -143330,7 +143577,7 @@ function symbolRef(projectId, obs, file, symbol) {
|
|
|
143330
143577
|
}
|
|
143331
143578
|
function resolveObservationCodeRefs(obs, lookup2) {
|
|
143332
143579
|
const refs = /* @__PURE__ */ new Map();
|
|
143333
|
-
const
|
|
143580
|
+
const text2 = observationText(obs);
|
|
143334
143581
|
const candidateFiles = /* @__PURE__ */ new Map();
|
|
143335
143582
|
for (const rawPath of obs.filesModified ?? []) {
|
|
143336
143583
|
const file = lookup2.findFile(normalizeCodePath(rawPath));
|
|
@@ -143340,7 +143587,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
143340
143587
|
refs.set(ref.id, ref);
|
|
143341
143588
|
}
|
|
143342
143589
|
const hintedFileIds = new Set(candidateFiles.keys());
|
|
143343
|
-
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(
|
|
143590
|
+
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
|
|
143344
143591
|
const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
|
|
143345
143592
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
143346
143593
|
for (const symbol of symbols) {
|
|
@@ -143351,7 +143598,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
143351
143598
|
for (const group of symbolsByName.values()) {
|
|
143352
143599
|
const candidates = group.length === 1 ? group : [];
|
|
143353
143600
|
for (const symbol of candidates) {
|
|
143354
|
-
if (!mentionsSymbol(
|
|
143601
|
+
if (!mentionsSymbol(text2, symbol)) continue;
|
|
143355
143602
|
const file = candidateFiles.get(symbol.fileId) ?? lookup2.findFile(symbol.path);
|
|
143356
143603
|
if (!file) continue;
|
|
143357
143604
|
candidateFiles.set(file.id, file);
|
|
@@ -144079,8 +144326,8 @@ function taskTokens(task) {
|
|
|
144079
144326
|
return normalizedTokens(task);
|
|
144080
144327
|
}
|
|
144081
144328
|
function scoreClaim(claim, tokens) {
|
|
144082
|
-
const
|
|
144083
|
-
const words = normalizedTokens(
|
|
144329
|
+
const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
|
|
144330
|
+
const words = normalizedTokens(text2);
|
|
144084
144331
|
let matches = 0;
|
|
144085
144332
|
for (const token of tokens) {
|
|
144086
144333
|
if (words.has(token)) matches += 1;
|
|
@@ -144976,29 +145223,141 @@ var init_workflow_store = __esm({
|
|
|
144976
145223
|
}
|
|
144977
145224
|
});
|
|
144978
145225
|
|
|
145226
|
+
// src/knowledge/outcome-types.ts
|
|
145227
|
+
var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
|
|
145228
|
+
var init_outcome_types = __esm({
|
|
145229
|
+
"src/knowledge/outcome-types.ts"() {
|
|
145230
|
+
"use strict";
|
|
145231
|
+
init_esm_shims();
|
|
145232
|
+
MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
|
|
145233
|
+
MEMORY_OUTCOME_SIGNAL_KINDS = [
|
|
145234
|
+
"verification-passed",
|
|
145235
|
+
"verification-failed",
|
|
145236
|
+
"verified-reuse",
|
|
145237
|
+
"user-pin",
|
|
145238
|
+
"user-correction",
|
|
145239
|
+
"source-changed",
|
|
145240
|
+
"conflict-confirmed",
|
|
145241
|
+
"manual-review"
|
|
145242
|
+
];
|
|
145243
|
+
}
|
|
145244
|
+
});
|
|
145245
|
+
|
|
145246
|
+
// src/knowledge/outcome-store.ts
|
|
145247
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
145248
|
+
function optionalText4(value) {
|
|
145249
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
145250
|
+
}
|
|
145251
|
+
function text(value, field, max = 1e3) {
|
|
145252
|
+
const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
|
|
145253
|
+
if (!safe) throw new Error("Outcome signal " + field + " is required.");
|
|
145254
|
+
if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
|
|
145255
|
+
return safe;
|
|
145256
|
+
}
|
|
145257
|
+
function oneOf(value, values, field) {
|
|
145258
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
145259
|
+
throw new Error("Outcome signal " + field + " is invalid.");
|
|
145260
|
+
}
|
|
145261
|
+
return value;
|
|
145262
|
+
}
|
|
145263
|
+
function rowToSignal(row) {
|
|
145264
|
+
return {
|
|
145265
|
+
id: row.id,
|
|
145266
|
+
projectId: row.projectId,
|
|
145267
|
+
candidateKind: row.candidateKind,
|
|
145268
|
+
candidateId: row.candidateId,
|
|
145269
|
+
kind: row.kind,
|
|
145270
|
+
sourceRef: row.sourceRef,
|
|
145271
|
+
...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
|
|
145272
|
+
...optionalText4(row.detail) ? { detail: row.detail } : {},
|
|
145273
|
+
observedAt: row.observedAt
|
|
145274
|
+
};
|
|
145275
|
+
}
|
|
145276
|
+
var OutcomeStore;
|
|
145277
|
+
var init_outcome_store = __esm({
|
|
145278
|
+
"src/knowledge/outcome-store.ts"() {
|
|
145279
|
+
"use strict";
|
|
145280
|
+
init_esm_shims();
|
|
145281
|
+
init_secret_filter();
|
|
145282
|
+
init_sqlite_db();
|
|
145283
|
+
init_outcome_types();
|
|
145284
|
+
OutcomeStore = class {
|
|
145285
|
+
db = null;
|
|
145286
|
+
async init(dataDir) {
|
|
145287
|
+
this.db = getDatabase(dataDir);
|
|
145288
|
+
}
|
|
145289
|
+
record(input) {
|
|
145290
|
+
const signal = {
|
|
145291
|
+
id: randomUUID10(),
|
|
145292
|
+
projectId: text(input.projectId, "project id"),
|
|
145293
|
+
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
145294
|
+
candidateId: text(input.candidateId, "candidate id"),
|
|
145295
|
+
kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
|
|
145296
|
+
sourceRef: text(input.sourceRef, "source reference"),
|
|
145297
|
+
...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
|
|
145298
|
+
...input.detail ? { detail: text(input.detail, "detail") } : {},
|
|
145299
|
+
observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
145300
|
+
};
|
|
145301
|
+
this.db.prepare(`
|
|
145302
|
+
INSERT INTO memory_outcome_signals (
|
|
145303
|
+
id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
|
|
145304
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
145305
|
+
`).run(
|
|
145306
|
+
signal.id,
|
|
145307
|
+
signal.projectId,
|
|
145308
|
+
signal.candidateKind,
|
|
145309
|
+
signal.candidateId,
|
|
145310
|
+
signal.kind,
|
|
145311
|
+
signal.sourceRef,
|
|
145312
|
+
signal.snapshotId ?? null,
|
|
145313
|
+
signal.detail ?? null,
|
|
145314
|
+
signal.observedAt
|
|
145315
|
+
);
|
|
145316
|
+
return signal;
|
|
145317
|
+
}
|
|
145318
|
+
latestForCandidates(projectId, candidateKind, candidateIds) {
|
|
145319
|
+
const ids = [...new Set(candidateIds.filter(Boolean))];
|
|
145320
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
145321
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
145322
|
+
const rows = this.db.prepare(`
|
|
145323
|
+
SELECT * FROM memory_outcome_signals
|
|
145324
|
+
WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
|
|
145325
|
+
ORDER BY observedAt DESC, id DESC
|
|
145326
|
+
`).all(projectId, candidateKind, ...ids);
|
|
145327
|
+
const latest = /* @__PURE__ */ new Map();
|
|
145328
|
+
for (const row of rows) {
|
|
145329
|
+
const signal = rowToSignal(row);
|
|
145330
|
+
if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
|
|
145331
|
+
}
|
|
145332
|
+
return latest;
|
|
145333
|
+
}
|
|
145334
|
+
};
|
|
145335
|
+
}
|
|
145336
|
+
});
|
|
145337
|
+
|
|
144979
145338
|
// src/codegraph/task-lens.ts
|
|
144980
|
-
function containsTaskKeyword(
|
|
145339
|
+
function containsTaskKeyword(text2, keyword) {
|
|
144981
145340
|
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");
|
|
144982
145341
|
let match2;
|
|
144983
|
-
while ((match2 = matcher.exec(
|
|
145342
|
+
while ((match2 = matcher.exec(text2)) !== null) {
|
|
144984
145343
|
const keywordIndex = match2.index + (match2[1]?.length ?? 0);
|
|
144985
|
-
if (!isNegatedTaskKeyword(
|
|
145344
|
+
if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
|
|
144986
145345
|
}
|
|
144987
145346
|
return false;
|
|
144988
145347
|
}
|
|
144989
|
-
function isNegatedTaskKeyword(
|
|
145348
|
+
function isNegatedTaskKeyword(text2, keywordIndex) {
|
|
144990
145349
|
const boundary = Math.max(
|
|
144991
|
-
|
|
144992
|
-
|
|
144993
|
-
|
|
144994
|
-
|
|
144995
|
-
|
|
144996
|
-
|
|
144997
|
-
|
|
144998
|
-
|
|
144999
|
-
|
|
145350
|
+
text2.lastIndexOf(".", keywordIndex - 1),
|
|
145351
|
+
text2.lastIndexOf("!", keywordIndex - 1),
|
|
145352
|
+
text2.lastIndexOf("?", keywordIndex - 1),
|
|
145353
|
+
text2.lastIndexOf(";", keywordIndex - 1),
|
|
145354
|
+
text2.lastIndexOf("\n", keywordIndex - 1),
|
|
145355
|
+
text2.lastIndexOf("\u3002", keywordIndex - 1),
|
|
145356
|
+
text2.lastIndexOf("\uFF01", keywordIndex - 1),
|
|
145357
|
+
text2.lastIndexOf("\uFF1F", keywordIndex - 1),
|
|
145358
|
+
text2.lastIndexOf("\uFF1B", keywordIndex - 1)
|
|
145000
145359
|
);
|
|
145001
|
-
let prefix =
|
|
145360
|
+
let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
|
|
145002
145361
|
const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
|
|
145003
145362
|
let contrastMatch;
|
|
145004
145363
|
let contrastEnd = -1;
|
|
@@ -145057,7 +145416,7 @@ function requiredText(data, key) {
|
|
|
145057
145416
|
}
|
|
145058
145417
|
return value.trim();
|
|
145059
145418
|
}
|
|
145060
|
-
function
|
|
145419
|
+
function optionalText5(data, key) {
|
|
145061
145420
|
const value = data[key];
|
|
145062
145421
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
145063
145422
|
if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
|
|
@@ -145100,11 +145459,11 @@ function phaseFromValue(value, index) {
|
|
|
145100
145459
|
}
|
|
145101
145460
|
const data = value;
|
|
145102
145461
|
const title = requiredText(data, "title");
|
|
145103
|
-
const phaseId =
|
|
145462
|
+
const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
|
|
145104
145463
|
return {
|
|
145105
145464
|
id: phaseId,
|
|
145106
145465
|
title,
|
|
145107
|
-
instructions:
|
|
145466
|
+
instructions: optionalText5(data, "instructions") ?? "",
|
|
145108
145467
|
branches: optionalStringArray(data, "branches"),
|
|
145109
145468
|
expectedOutputs: optionalStringArray(data, "expectedOutputs"),
|
|
145110
145469
|
verificationGates: optionalStringArray(data, "verificationGates")
|
|
@@ -145213,7 +145572,7 @@ function parsedWorkflow(data, body, input) {
|
|
|
145213
145572
|
id: requiredText(data, "id"),
|
|
145214
145573
|
workspaceId: input.workspaceId,
|
|
145215
145574
|
title: requiredText(data, "title"),
|
|
145216
|
-
description:
|
|
145575
|
+
description: optionalText5(data, "description") ?? "",
|
|
145217
145576
|
status: optionalStatus(data),
|
|
145218
145577
|
version: optionalNumber(data, "version", 1),
|
|
145219
145578
|
taskLenses: optionalStringArray(data, "taskLenses"),
|
|
@@ -145232,9 +145591,9 @@ function parsedWorkflow(data, body, input) {
|
|
|
145232
145591
|
sourcePath: normalizeSourcePath(input.sourcePath),
|
|
145233
145592
|
sourceHash: "",
|
|
145234
145593
|
contentHash: input.contentHash,
|
|
145235
|
-
createdAt:
|
|
145236
|
-
updatedAt:
|
|
145237
|
-
...
|
|
145594
|
+
createdAt: optionalText5(data, "createdAt") ?? now2(),
|
|
145595
|
+
updatedAt: optionalText5(data, "updatedAt") ?? now2(),
|
|
145596
|
+
...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
|
|
145238
145597
|
};
|
|
145239
145598
|
if (candidate.phases.length === 0) {
|
|
145240
145599
|
throw new Error("workflow must contain at least one phase or a non-empty body");
|
|
@@ -145333,11 +145692,11 @@ async function syncCanonicalWorkflows(workspace) {
|
|
|
145333
145692
|
return { workflows, errors };
|
|
145334
145693
|
}
|
|
145335
145694
|
function inferTaskLenses(value) {
|
|
145336
|
-
const
|
|
145337
|
-
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) =>
|
|
145695
|
+
const text2 = value.toLowerCase();
|
|
145696
|
+
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
|
|
145338
145697
|
}
|
|
145339
145698
|
function taskScore(workflow, task) {
|
|
145340
|
-
const
|
|
145699
|
+
const text2 = task.toLowerCase();
|
|
145341
145700
|
let score = 0;
|
|
145342
145701
|
const reasons = [];
|
|
145343
145702
|
const matchedLenses = /* @__PURE__ */ new Set();
|
|
@@ -145604,7 +145963,31 @@ async function recordWorkflowRun(input) {
|
|
|
145604
145963
|
throw new Error("Workflow was not found for this workspace");
|
|
145605
145964
|
}
|
|
145606
145965
|
if (!input.run.task.trim()) throw new Error("Workflow run task is required");
|
|
145607
|
-
|
|
145966
|
+
const run = store.recordRun(input.run);
|
|
145967
|
+
const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
|
|
145968
|
+
if (!kind) return run;
|
|
145969
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
145970
|
+
evidence.set(workflow.id, "workflow");
|
|
145971
|
+
for (const reference of run.selectedEvidence) {
|
|
145972
|
+
const match2 = /^(claim|durable):(.+)$/.exec(reference);
|
|
145973
|
+
if (!match2) continue;
|
|
145974
|
+
evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
|
|
145975
|
+
}
|
|
145976
|
+
const outcomes = new OutcomeStore();
|
|
145977
|
+
await outcomes.init(workflowStoreDataDir(input.workspace));
|
|
145978
|
+
for (const [candidateId, candidateKind] of evidence) {
|
|
145979
|
+
outcomes.record({
|
|
145980
|
+
projectId: run.projectId,
|
|
145981
|
+
candidateKind,
|
|
145982
|
+
candidateId,
|
|
145983
|
+
kind,
|
|
145984
|
+
sourceRef: "workflow-run:" + run.id,
|
|
145985
|
+
...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
|
|
145986
|
+
...run.failureReason ? { detail: run.failureReason } : {},
|
|
145987
|
+
observedAt: run.completedAt ?? run.startedAt
|
|
145988
|
+
});
|
|
145989
|
+
}
|
|
145990
|
+
return run;
|
|
145608
145991
|
}
|
|
145609
145992
|
async function selectWorkspaceWorkflows(input) {
|
|
145610
145993
|
const synced = await syncCanonicalWorkflows(input.workspace);
|
|
@@ -145629,6 +146012,7 @@ var init_workflows2 = __esm({
|
|
|
145629
146012
|
init_workflow_sync();
|
|
145630
146013
|
init_workspace();
|
|
145631
146014
|
init_workflow_store();
|
|
146015
|
+
init_outcome_store();
|
|
145632
146016
|
init_task_lens();
|
|
145633
146017
|
KNOWN_AGENTS = [
|
|
145634
146018
|
"windsurf",
|