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
package/dist/sdk.js
CHANGED
|
@@ -363,7 +363,7 @@ function closeAllDatabases() {
|
|
|
363
363
|
_dbCache.delete(key);
|
|
364
364
|
}
|
|
365
365
|
}
|
|
366
|
-
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;
|
|
366
|
+
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;
|
|
367
367
|
var init_sqlite_db = __esm({
|
|
368
368
|
"src/store/sqlite-db.ts"() {
|
|
369
369
|
"use strict";
|
|
@@ -629,6 +629,17 @@ CREATE TABLE IF NOT EXISTS observation_code_refs (
|
|
|
629
629
|
" UNIQUE(projectId, sourceEpoch)",
|
|
630
630
|
");"
|
|
631
631
|
].join("\n");
|
|
632
|
+
CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE = [
|
|
633
|
+
"CREATE TABLE IF NOT EXISTS code_state_snapshot_files (",
|
|
634
|
+
" snapshotId TEXT NOT NULL,",
|
|
635
|
+
" projectId TEXT NOT NULL,",
|
|
636
|
+
" fileId TEXT NOT NULL,",
|
|
637
|
+
" path TEXT NOT NULL,",
|
|
638
|
+
" contentHash TEXT NOT NULL,",
|
|
639
|
+
" PRIMARY KEY (snapshotId, path),",
|
|
640
|
+
" FOREIGN KEY (snapshotId) REFERENCES code_state_snapshots(id) ON DELETE CASCADE",
|
|
641
|
+
");"
|
|
642
|
+
].join("\n");
|
|
632
643
|
CREATE_KNOWLEDGE_CLAIMS_TABLE = `
|
|
633
644
|
CREATE TABLE IF NOT EXISTS knowledge_claims (
|
|
634
645
|
id TEXT PRIMARY KEY,
|
|
@@ -839,6 +850,19 @@ CREATE TABLE IF NOT EXISTS long_term_memory_events (
|
|
|
839
850
|
createdAt TEXT NOT NULL,
|
|
840
851
|
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
841
852
|
);
|
|
853
|
+
`;
|
|
854
|
+
CREATE_MEMORY_OUTCOME_SIGNALS_TABLE = `
|
|
855
|
+
CREATE TABLE IF NOT EXISTS memory_outcome_signals (
|
|
856
|
+
id TEXT PRIMARY KEY,
|
|
857
|
+
projectId TEXT NOT NULL,
|
|
858
|
+
candidateKind TEXT NOT NULL,
|
|
859
|
+
candidateId TEXT NOT NULL,
|
|
860
|
+
kind TEXT NOT NULL,
|
|
861
|
+
sourceRef TEXT NOT NULL,
|
|
862
|
+
snapshotId TEXT,
|
|
863
|
+
detail TEXT,
|
|
864
|
+
observedAt TEXT NOT NULL
|
|
865
|
+
);
|
|
842
866
|
`;
|
|
843
867
|
CREATE_MEDIA_ASSETS_TABLE = `
|
|
844
868
|
CREATE TABLE IF NOT EXISTS media_assets (
|
|
@@ -1081,6 +1105,20 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1081
1105
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_edges_snapshot ON code_edges(projectId, snapshotId)");
|
|
1082
1106
|
}
|
|
1083
1107
|
},
|
|
1108
|
+
{
|
|
1109
|
+
id: "1.4-codegraph-snapshot-manifest",
|
|
1110
|
+
apply: (db2) => {
|
|
1111
|
+
db2.exec(CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE);
|
|
1112
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_snapshot_files_project_path ON code_state_snapshot_files(projectId, path)");
|
|
1113
|
+
}
|
|
1114
|
+
},
|
|
1115
|
+
{
|
|
1116
|
+
id: "1.4-memory-outcome-signals",
|
|
1117
|
+
apply: (db2) => {
|
|
1118
|
+
db2.exec(CREATE_MEMORY_OUTCOME_SIGNALS_TABLE);
|
|
1119
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_outcomes_candidate ON memory_outcome_signals(projectId, candidateKind, candidateId, observedAt DESC)");
|
|
1120
|
+
}
|
|
1121
|
+
},
|
|
1084
1122
|
{
|
|
1085
1123
|
id: "1.2-knowledge-claim-ledger",
|
|
1086
1124
|
apply: (db2) => {
|
|
@@ -2280,17 +2318,17 @@ var init_mini_skill_store = __esm({
|
|
|
2280
2318
|
|
|
2281
2319
|
// src/compact/token-budget.ts
|
|
2282
2320
|
import { countTokens, isWithinTokenLimit } from "gpt-tokenizer";
|
|
2283
|
-
function countTextTokens(
|
|
2284
|
-
return countTokens(
|
|
2321
|
+
function countTextTokens(text2) {
|
|
2322
|
+
return countTokens(text2);
|
|
2285
2323
|
}
|
|
2286
|
-
function fitsInBudget(
|
|
2287
|
-
return isWithinTokenLimit(
|
|
2324
|
+
function fitsInBudget(text2, limit2) {
|
|
2325
|
+
return isWithinTokenLimit(text2, limit2);
|
|
2288
2326
|
}
|
|
2289
|
-
function truncateToTokenBudget(
|
|
2290
|
-
if (fitsInBudget(
|
|
2291
|
-
return
|
|
2327
|
+
function truncateToTokenBudget(text2, budget) {
|
|
2328
|
+
if (fitsInBudget(text2, budget) !== false) {
|
|
2329
|
+
return text2;
|
|
2292
2330
|
}
|
|
2293
|
-
const sentences =
|
|
2331
|
+
const sentences = text2.split(/(?<=[.!?])\s+/);
|
|
2294
2332
|
let result = "";
|
|
2295
2333
|
for (const sentence of sentences) {
|
|
2296
2334
|
const candidate = result ? `${result} ${sentence}` : sentence;
|
|
@@ -2301,12 +2339,12 @@ function truncateToTokenBudget(text, budget) {
|
|
|
2301
2339
|
}
|
|
2302
2340
|
if (!result) {
|
|
2303
2341
|
const estimatedChars = budget * 2;
|
|
2304
|
-
result =
|
|
2342
|
+
result = text2.slice(0, estimatedChars);
|
|
2305
2343
|
while (fitsInBudget(result, budget) === false && result.length > 0) {
|
|
2306
2344
|
result = result.slice(0, Math.floor(result.length * 0.9));
|
|
2307
2345
|
}
|
|
2308
|
-
if (result.length <
|
|
2309
|
-
const nextCharacter =
|
|
2346
|
+
if (result.length < text2.length) {
|
|
2347
|
+
const nextCharacter = text2.charAt(result.length);
|
|
2310
2348
|
if (nextCharacter && !/[\s.,;:!?)}\]]/.test(nextCharacter)) {
|
|
2311
2349
|
const boundary = result.search(/\s+\S*$/);
|
|
2312
2350
|
result = boundary > 0 ? result.slice(0, boundary).trimEnd() : "";
|
|
@@ -3438,8 +3476,8 @@ import { createHash } from "crypto";
|
|
|
3438
3476
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
3439
3477
|
import { join as join2 } from "path";
|
|
3440
3478
|
import { homedir as homedir6 } from "os";
|
|
3441
|
-
function textHash(
|
|
3442
|
-
return createHash("sha256").update(
|
|
3479
|
+
function textHash(text2) {
|
|
3480
|
+
return createHash("sha256").update(text2).digest("hex").slice(0, 16);
|
|
3443
3481
|
}
|
|
3444
3482
|
async function loadDiskCache() {
|
|
3445
3483
|
try {
|
|
@@ -3502,11 +3540,11 @@ var init_fastembed_provider = __esm({
|
|
|
3502
3540
|
async embedInputs(inputs, options = {}) {
|
|
3503
3541
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3504
3542
|
}
|
|
3505
|
-
async embed(
|
|
3506
|
-
const hash4 = textHash(
|
|
3543
|
+
async embed(text2) {
|
|
3544
|
+
const hash4 = textHash(text2);
|
|
3507
3545
|
const cached = cache.get(hash4);
|
|
3508
3546
|
if (cached) return cached;
|
|
3509
|
-
const raw = await this.model.queryEmbed(
|
|
3547
|
+
const raw = await this.model.queryEmbed(text2);
|
|
3510
3548
|
const result = Array.from(raw);
|
|
3511
3549
|
if (result.length !== this.dimensions) {
|
|
3512
3550
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
@@ -3602,10 +3640,10 @@ var init_transformers_provider = __esm({
|
|
|
3602
3640
|
async embedInputs(inputs, options = {}) {
|
|
3603
3641
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3604
3642
|
}
|
|
3605
|
-
async embed(
|
|
3606
|
-
const cached = cache2.get(
|
|
3643
|
+
async embed(text2) {
|
|
3644
|
+
const cached = cache2.get(text2);
|
|
3607
3645
|
if (cached) return cached;
|
|
3608
|
-
const output = await this.extractor(
|
|
3646
|
+
const output = await this.extractor(text2, {
|
|
3609
3647
|
pooling: "mean",
|
|
3610
3648
|
normalize: true
|
|
3611
3649
|
});
|
|
@@ -3613,7 +3651,7 @@ var init_transformers_provider = __esm({
|
|
|
3613
3651
|
if (result.length !== this.dimensions) {
|
|
3614
3652
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
3615
3653
|
}
|
|
3616
|
-
this.cacheSet(
|
|
3654
|
+
this.cacheSet(text2, result);
|
|
3617
3655
|
return result;
|
|
3618
3656
|
}
|
|
3619
3657
|
async embedBatch(texts) {
|
|
@@ -3676,8 +3714,8 @@ function dimsCacheFile() {
|
|
|
3676
3714
|
function cacheMetaFile() {
|
|
3677
3715
|
return join3(cacheDir(), ".embedding-api-cache-meta.json");
|
|
3678
3716
|
}
|
|
3679
|
-
function normalizeText(
|
|
3680
|
-
return
|
|
3717
|
+
function normalizeText(text2) {
|
|
3718
|
+
return text2.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
|
|
3681
3719
|
}
|
|
3682
3720
|
function cacheNamespace(config) {
|
|
3683
3721
|
return [
|
|
@@ -3687,8 +3725,8 @@ function cacheNamespace(config) {
|
|
|
3687
3725
|
config.requestedDimensions ?? "native"
|
|
3688
3726
|
].join("|");
|
|
3689
3727
|
}
|
|
3690
|
-
function textHash2(
|
|
3691
|
-
return createHash2("sha256").update(`${namespace}\0${
|
|
3728
|
+
function textHash2(text2, namespace) {
|
|
3729
|
+
return createHash2("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
3692
3730
|
}
|
|
3693
3731
|
function inputIdentity(input, options = {}) {
|
|
3694
3732
|
return JSON.stringify({
|
|
@@ -4100,8 +4138,8 @@ var init_api_provider = __esm({
|
|
|
4100
4138
|
if (!embedding) throw new Error("API probe returned no embeddings; check model name and API key");
|
|
4101
4139
|
return embedding.length;
|
|
4102
4140
|
}
|
|
4103
|
-
async embed(
|
|
4104
|
-
const normalized = normalizeText(
|
|
4141
|
+
async embed(text2, options) {
|
|
4142
|
+
const normalized = normalizeText(text2);
|
|
4105
4143
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
4106
4144
|
return this.embedInput({ modality: "text", text: normalized }, { intent: "document", ...options });
|
|
4107
4145
|
}
|
|
@@ -4158,7 +4196,7 @@ var init_api_provider = __esm({
|
|
|
4158
4196
|
}
|
|
4159
4197
|
async embedBatch(texts, options) {
|
|
4160
4198
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
4161
|
-
return Promise.all(texts.map((
|
|
4199
|
+
return Promise.all(texts.map((text2) => this.embedInput({ modality: "text", text: text2 }, { intent: "document", ...options })));
|
|
4162
4200
|
}
|
|
4163
4201
|
await ensureDiskCacheLoaded();
|
|
4164
4202
|
const normalizedTexts = texts.map(normalizeText);
|
|
@@ -4237,8 +4275,8 @@ var init_api_provider = __esm({
|
|
|
4237
4275
|
}
|
|
4238
4276
|
async getCachedEmbeddings(texts) {
|
|
4239
4277
|
await ensureDiskCacheLoaded();
|
|
4240
|
-
return texts.map((
|
|
4241
|
-
const hash4 = textHash2(normalizeText(
|
|
4278
|
+
return texts.map((text2) => {
|
|
4279
|
+
const hash4 = textHash2(normalizeText(text2), this.cacheKeyNamespace);
|
|
4242
4280
|
return cache3.get(hash4) ?? null;
|
|
4243
4281
|
});
|
|
4244
4282
|
}
|
|
@@ -4468,9 +4506,9 @@ function wrapProvider(candidate) {
|
|
|
4468
4506
|
return {
|
|
4469
4507
|
name: candidate.name,
|
|
4470
4508
|
dimensions: candidate.dimensions,
|
|
4471
|
-
async embed(
|
|
4509
|
+
async embed(text2, options) {
|
|
4472
4510
|
try {
|
|
4473
|
-
return await candidate.embed(
|
|
4511
|
+
return await candidate.embed(text2, options);
|
|
4474
4512
|
} catch (error) {
|
|
4475
4513
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
4476
4514
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -4478,7 +4516,7 @@ function wrapProvider(candidate) {
|
|
|
4478
4516
|
if (fallback) {
|
|
4479
4517
|
provider = wrapProvider(fallback);
|
|
4480
4518
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
4481
|
-
return provider.embed(
|
|
4519
|
+
return provider.embed(text2, options);
|
|
4482
4520
|
}
|
|
4483
4521
|
}
|
|
4484
4522
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -5037,8 +5075,8 @@ async function readResponseText(response, signal, maxBytes = MAX_LLM_RESPONSE_BY
|
|
|
5037
5075
|
}
|
|
5038
5076
|
}
|
|
5039
5077
|
async function readResponseJson(response, signal, maxBytes = MAX_LLM_RESPONSE_BYTES) {
|
|
5040
|
-
const
|
|
5041
|
-
return JSON.parse(
|
|
5078
|
+
const text2 = await readResponseText(response, signal, maxBytes);
|
|
5079
|
+
return JSON.parse(text2);
|
|
5042
5080
|
}
|
|
5043
5081
|
async function* callLLMWithToolsStream(messages, tools) {
|
|
5044
5082
|
if (!currentConfig) {
|
|
@@ -5591,8 +5629,8 @@ function isCjkHeavy(query) {
|
|
|
5591
5629
|
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
5592
5630
|
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
5593
5631
|
}
|
|
5594
|
-
function normalizeExpansion(
|
|
5595
|
-
return
|
|
5632
|
+
function normalizeExpansion(text2) {
|
|
5633
|
+
return text2.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
|
|
5596
5634
|
}
|
|
5597
5635
|
async function maybeExpandSearchQuery(query) {
|
|
5598
5636
|
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
@@ -5955,9 +5993,9 @@ function shouldSkipCompression(narrative, type) {
|
|
|
5955
5993
|
if (specialChars / narrative.length > 0.35) return true;
|
|
5956
5994
|
return false;
|
|
5957
5995
|
}
|
|
5958
|
-
function estimateTokens(
|
|
5959
|
-
const cjkChars = (
|
|
5960
|
-
const otherChars =
|
|
5996
|
+
function estimateTokens(text2) {
|
|
5997
|
+
const cjkChars = (text2.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
|
|
5998
|
+
const otherChars = text2.length - cjkChars;
|
|
5961
5999
|
return Math.ceil(cjkChars / 1.5 + otherChars / 4);
|
|
5962
6000
|
}
|
|
5963
6001
|
var COMPRESS_PROMPT, COMPRESS_PROMPT_GENTLE, RERANK_PROMPT, SKIP_PATTERNS, LOW_COMPRESSION_TYPES;
|
|
@@ -6260,10 +6298,10 @@ function isEmbeddingEnabled() {
|
|
|
6260
6298
|
function getVectorDimensions() {
|
|
6261
6299
|
return embeddingEnabled ? embeddingDimensions : null;
|
|
6262
6300
|
}
|
|
6263
|
-
async function generateEmbedding(
|
|
6301
|
+
async function generateEmbedding(text2) {
|
|
6264
6302
|
const provider2 = await getEmbeddingProvider();
|
|
6265
6303
|
if (!provider2) return null;
|
|
6266
|
-
return provider2.embedInput ? provider2.embedInput({ modality: "text", text }, { intent: "document" }) : provider2.embed(
|
|
6304
|
+
return provider2.embedInput ? provider2.embedInput({ modality: "text", text: text2 }, { intent: "document" }) : provider2.embed(text2);
|
|
6267
6305
|
}
|
|
6268
6306
|
async function generateEmbeddingInput(input, options = {}) {
|
|
6269
6307
|
const provider2 = await getEmbeddingProvider();
|
|
@@ -7595,9 +7633,9 @@ var init_entity_extractor = __esm({
|
|
|
7595
7633
|
});
|
|
7596
7634
|
|
|
7597
7635
|
// src/memory/secret-filter.ts
|
|
7598
|
-
function applyRedaction(
|
|
7599
|
-
if (!
|
|
7600
|
-
let out =
|
|
7636
|
+
function applyRedaction(text2) {
|
|
7637
|
+
if (!text2) return text2;
|
|
7638
|
+
let out = text2;
|
|
7601
7639
|
out = out.replace(
|
|
7602
7640
|
/((?:password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret)\s*[:=]\s*["']?)([^\s"',;\n]{6,})/gi,
|
|
7603
7641
|
"$1[REDACTED]"
|
|
@@ -7611,11 +7649,11 @@ function applyRedaction(text) {
|
|
|
7611
7649
|
out = out.replace(/\beyJ[A-Za-z0-9._-]{40,}\b/g, "[REDACTED]");
|
|
7612
7650
|
return out;
|
|
7613
7651
|
}
|
|
7614
|
-
function sanitizeCredentials(
|
|
7615
|
-
return applyRedaction(
|
|
7652
|
+
function sanitizeCredentials(text2) {
|
|
7653
|
+
return applyRedaction(text2);
|
|
7616
7654
|
}
|
|
7617
|
-
function redactCredentials(
|
|
7618
|
-
return applyRedaction(
|
|
7655
|
+
function redactCredentials(text2) {
|
|
7656
|
+
return applyRedaction(text2);
|
|
7619
7657
|
}
|
|
7620
7658
|
var init_secret_filter = __esm({
|
|
7621
7659
|
"src/memory/secret-filter.ts"() {
|
|
@@ -7666,8 +7704,8 @@ function clampPositiveInteger(value, fallback) {
|
|
|
7666
7704
|
return Math.max(1, Math.floor(value));
|
|
7667
7705
|
}
|
|
7668
7706
|
function errorText(error) {
|
|
7669
|
-
const
|
|
7670
|
-
return sanitizeCredentials(
|
|
7707
|
+
const text2 = error instanceof Error ? error.message : String(error);
|
|
7708
|
+
return sanitizeCredentials(text2).slice(0, MAX_ERROR_LENGTH);
|
|
7671
7709
|
}
|
|
7672
7710
|
function normalizedKinds(kinds) {
|
|
7673
7711
|
if (!kinds) return void 0;
|
|
@@ -8761,9 +8799,9 @@ __export(consolidation_exports, {
|
|
|
8761
8799
|
executeConsolidation: () => executeConsolidation,
|
|
8762
8800
|
findConsolidationCandidates: () => findConsolidationCandidates
|
|
8763
8801
|
});
|
|
8764
|
-
function tokenize(
|
|
8802
|
+
function tokenize(text2) {
|
|
8765
8803
|
return new Set(
|
|
8766
|
-
|
|
8804
|
+
text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t2) => t2.length > 1)
|
|
8767
8805
|
);
|
|
8768
8806
|
}
|
|
8769
8807
|
function jaccardSimilarity(a, b) {
|
|
@@ -17915,8 +17953,8 @@ var init_headers = __esm({
|
|
|
17915
17953
|
});
|
|
17916
17954
|
|
|
17917
17955
|
// packages/ai/dist/utils/sanitize-unicode.js
|
|
17918
|
-
function sanitizeSurrogates(
|
|
17919
|
-
return
|
|
17956
|
+
function sanitizeSurrogates(text2) {
|
|
17957
|
+
return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
17920
17958
|
}
|
|
17921
17959
|
var init_sanitize_unicode = __esm({
|
|
17922
17960
|
"packages/ai/dist/utils/sanitize-unicode.js"() {
|
|
@@ -18398,9 +18436,9 @@ var init_values = __esm({
|
|
|
18398
18436
|
}
|
|
18399
18437
|
return n;
|
|
18400
18438
|
};
|
|
18401
|
-
safeJSON = (
|
|
18439
|
+
safeJSON = (text2) => {
|
|
18402
18440
|
try {
|
|
18403
|
-
return JSON.parse(
|
|
18441
|
+
return JSON.parse(text2);
|
|
18404
18442
|
} catch (err) {
|
|
18405
18443
|
return void 0;
|
|
18406
18444
|
}
|
|
@@ -19563,8 +19601,8 @@ async function defaultParseResponse(client, props) {
|
|
|
19563
19601
|
const json2 = await response.json();
|
|
19564
19602
|
return addRequestID(json2, response);
|
|
19565
19603
|
}
|
|
19566
|
-
const
|
|
19567
|
-
return
|
|
19604
|
+
const text2 = await response.text();
|
|
19605
|
+
return text2;
|
|
19568
19606
|
})();
|
|
19569
19607
|
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
19570
19608
|
retryOfRequestLogID,
|
|
@@ -32934,7 +32972,7 @@ var init_models_generated = __esm({
|
|
|
32934
32972
|
provider: "minimax",
|
|
32935
32973
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
32936
32974
|
reasoning: true,
|
|
32937
|
-
input: ["text", "image"],
|
|
32975
|
+
input: ["text", "image", "video"],
|
|
32938
32976
|
cost: {
|
|
32939
32977
|
input: 0.3,
|
|
32940
32978
|
output: 1.2,
|
|
@@ -32987,7 +33025,7 @@ var init_models_generated = __esm({
|
|
|
32987
33025
|
provider: "minimax-cn",
|
|
32988
33026
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
32989
33027
|
reasoning: true,
|
|
32990
|
-
input: ["text", "image"],
|
|
33028
|
+
input: ["text", "image", "video"],
|
|
32991
33029
|
cost: {
|
|
32992
33030
|
input: 0.3,
|
|
32993
33031
|
output: 1.2,
|
|
@@ -45182,9 +45220,9 @@ var init_values2 = __esm({
|
|
|
45182
45220
|
}
|
|
45183
45221
|
return n;
|
|
45184
45222
|
};
|
|
45185
|
-
safeJSON2 = (
|
|
45223
|
+
safeJSON2 = (text2) => {
|
|
45186
45224
|
try {
|
|
45187
|
-
return JSON.parse(
|
|
45225
|
+
return JSON.parse(text2);
|
|
45188
45226
|
} catch (err) {
|
|
45189
45227
|
return void 0;
|
|
45190
45228
|
}
|
|
@@ -45958,8 +45996,8 @@ async function defaultParseResponse2(client, props) {
|
|
|
45958
45996
|
const json2 = await response.json();
|
|
45959
45997
|
return addRequestID2(json2, response);
|
|
45960
45998
|
}
|
|
45961
|
-
const
|
|
45962
|
-
return
|
|
45999
|
+
const text2 = await response.text();
|
|
46000
|
+
return text2;
|
|
45963
46001
|
})();
|
|
45964
46002
|
loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
|
|
45965
46003
|
retryOfRequestLogID,
|
|
@@ -52262,11 +52300,11 @@ var init_simple_options = __esm({
|
|
|
52262
52300
|
});
|
|
52263
52301
|
|
|
52264
52302
|
// packages/ai/dist/providers/transform-messages.js
|
|
52265
|
-
function
|
|
52303
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52266
52304
|
const result = [];
|
|
52267
52305
|
let previousWasPlaceholder = false;
|
|
52268
52306
|
for (const block of content) {
|
|
52269
|
-
if (block.type ===
|
|
52307
|
+
if (block.type === dropType) {
|
|
52270
52308
|
if (!previousWasPlaceholder) {
|
|
52271
52309
|
result.push({ type: "text", text: placeholder });
|
|
52272
52310
|
}
|
|
@@ -52274,33 +52312,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52274
52312
|
continue;
|
|
52275
52313
|
}
|
|
52276
52314
|
result.push(block);
|
|
52277
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52315
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52278
52316
|
}
|
|
52279
52317
|
return result;
|
|
52280
52318
|
}
|
|
52281
|
-
function
|
|
52282
|
-
|
|
52319
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52320
|
+
const supportsImage = model.input.includes("image");
|
|
52321
|
+
const supportsVideo = model.input.includes("video");
|
|
52322
|
+
if (supportsImage && supportsVideo) {
|
|
52283
52323
|
return messages;
|
|
52284
52324
|
}
|
|
52285
52325
|
return messages.map((msg) => {
|
|
52286
52326
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52287
|
-
|
|
52288
|
-
|
|
52289
|
-
content
|
|
52290
|
-
|
|
52327
|
+
let content = msg.content;
|
|
52328
|
+
if (!supportsImage)
|
|
52329
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52330
|
+
if (!supportsVideo)
|
|
52331
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52332
|
+
return { ...msg, content };
|
|
52291
52333
|
}
|
|
52292
52334
|
if (msg.role === "toolResult") {
|
|
52293
|
-
|
|
52294
|
-
|
|
52295
|
-
content
|
|
52296
|
-
|
|
52335
|
+
let content = msg.content;
|
|
52336
|
+
if (!supportsImage)
|
|
52337
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52338
|
+
if (!supportsVideo)
|
|
52339
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52340
|
+
return { ...msg, content };
|
|
52297
52341
|
}
|
|
52298
52342
|
return msg;
|
|
52299
52343
|
});
|
|
52300
52344
|
}
|
|
52301
52345
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52302
52346
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52303
|
-
const imageAwareMessages =
|
|
52347
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52304
52348
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52305
52349
|
if (msg.role === "user") {
|
|
52306
52350
|
return msg;
|
|
@@ -52412,13 +52456,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52412
52456
|
insertSyntheticToolResults();
|
|
52413
52457
|
return result;
|
|
52414
52458
|
}
|
|
52415
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52459
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52416
52460
|
var init_transform_messages = __esm({
|
|
52417
52461
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52418
52462
|
"use strict";
|
|
52419
52463
|
init_esm_shims();
|
|
52420
52464
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52421
52465
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52466
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52467
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52422
52468
|
}
|
|
52423
52469
|
});
|
|
52424
52470
|
|
|
@@ -52449,8 +52495,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52449
52495
|
};
|
|
52450
52496
|
}
|
|
52451
52497
|
function convertContentBlocks(content) {
|
|
52452
|
-
const
|
|
52453
|
-
if (!
|
|
52498
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52499
|
+
if (!hasMedia) {
|
|
52454
52500
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52455
52501
|
}
|
|
52456
52502
|
const blocks = content.map((block) => {
|
|
@@ -52460,6 +52506,16 @@ function convertContentBlocks(content) {
|
|
|
52460
52506
|
text: sanitizeSurrogates(block.text)
|
|
52461
52507
|
};
|
|
52462
52508
|
}
|
|
52509
|
+
if (block.type === "video") {
|
|
52510
|
+
return {
|
|
52511
|
+
type: "video",
|
|
52512
|
+
source: {
|
|
52513
|
+
type: "base64",
|
|
52514
|
+
media_type: block.mimeType,
|
|
52515
|
+
data: block.data
|
|
52516
|
+
}
|
|
52517
|
+
};
|
|
52518
|
+
}
|
|
52463
52519
|
return {
|
|
52464
52520
|
type: "image",
|
|
52465
52521
|
source: {
|
|
@@ -52473,7 +52529,7 @@ function convertContentBlocks(content) {
|
|
|
52473
52529
|
if (!hasText) {
|
|
52474
52530
|
blocks.unshift({
|
|
52475
52531
|
type: "text",
|
|
52476
|
-
text: "(see attached
|
|
52532
|
+
text: "(see attached media)"
|
|
52477
52533
|
});
|
|
52478
52534
|
}
|
|
52479
52535
|
return blocks;
|
|
@@ -52534,9 +52590,9 @@ function decodeSseLine(line, state) {
|
|
|
52534
52590
|
}
|
|
52535
52591
|
return null;
|
|
52536
52592
|
}
|
|
52537
|
-
function nextLineBreakIndex(
|
|
52538
|
-
const carriageReturnIndex =
|
|
52539
|
-
const newlineIndex =
|
|
52593
|
+
function nextLineBreakIndex(text2) {
|
|
52594
|
+
const carriageReturnIndex = text2.indexOf("\r");
|
|
52595
|
+
const newlineIndex = text2.indexOf("\n");
|
|
52540
52596
|
if (carriageReturnIndex === -1) {
|
|
52541
52597
|
return newlineIndex;
|
|
52542
52598
|
}
|
|
@@ -52545,18 +52601,18 @@ function nextLineBreakIndex(text) {
|
|
|
52545
52601
|
}
|
|
52546
52602
|
return Math.min(carriageReturnIndex, newlineIndex);
|
|
52547
52603
|
}
|
|
52548
|
-
function consumeLine(
|
|
52549
|
-
const lineBreakIndex = nextLineBreakIndex(
|
|
52604
|
+
function consumeLine(text2) {
|
|
52605
|
+
const lineBreakIndex = nextLineBreakIndex(text2);
|
|
52550
52606
|
if (lineBreakIndex === -1) {
|
|
52551
52607
|
return null;
|
|
52552
52608
|
}
|
|
52553
52609
|
let nextIndex = lineBreakIndex + 1;
|
|
52554
|
-
if (
|
|
52610
|
+
if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
|
|
52555
52611
|
nextIndex += 1;
|
|
52556
52612
|
}
|
|
52557
52613
|
return {
|
|
52558
|
-
line:
|
|
52559
|
-
rest:
|
|
52614
|
+
line: text2.slice(0, lineBreakIndex),
|
|
52615
|
+
rest: text2.slice(nextIndex)
|
|
52560
52616
|
};
|
|
52561
52617
|
}
|
|
52562
52618
|
async function* iterateSseMessages(body, signal) {
|
|
@@ -52823,6 +52879,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52823
52879
|
type: "text",
|
|
52824
52880
|
text: sanitizeSurrogates(item.text)
|
|
52825
52881
|
};
|
|
52882
|
+
} else if (item.type === "video") {
|
|
52883
|
+
return {
|
|
52884
|
+
type: "video",
|
|
52885
|
+
source: {
|
|
52886
|
+
type: "base64",
|
|
52887
|
+
media_type: item.mimeType,
|
|
52888
|
+
data: item.data
|
|
52889
|
+
}
|
|
52890
|
+
};
|
|
52826
52891
|
} else {
|
|
52827
52892
|
return {
|
|
52828
52893
|
type: "image",
|
|
@@ -52903,6 +52968,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52903
52968
|
toolResults.push({
|
|
52904
52969
|
type: "tool_result",
|
|
52905
52970
|
tool_use_id: msg.toolCallId,
|
|
52971
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
52972
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
52906
52973
|
content: convertContentBlocks(msg.content),
|
|
52907
52974
|
is_error: msg.isError
|
|
52908
52975
|
});
|
|
@@ -52929,7 +52996,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52929
52996
|
if (lastMessage.role === "user") {
|
|
52930
52997
|
if (Array.isArray(lastMessage.content)) {
|
|
52931
52998
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
52932
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
52999
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
52933
53000
|
lastBlock.cache_control = cacheControl;
|
|
52934
53001
|
}
|
|
52935
53002
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -54712,8 +54779,8 @@ var require_common = __commonJS({
|
|
|
54712
54779
|
}
|
|
54713
54780
|
function redactString(obj, key) {
|
|
54714
54781
|
if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
|
|
54715
|
-
const
|
|
54716
|
-
if (/grant_type=/i.test(
|
|
54782
|
+
const text2 = obj[key];
|
|
54783
|
+
if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
|
|
54717
54784
|
obj[key] = REDACT;
|
|
54718
54785
|
}
|
|
54719
54786
|
}
|
|
@@ -61541,8 +61608,8 @@ var init_body = __esm({
|
|
|
61541
61608
|
* @return Promise
|
|
61542
61609
|
*/
|
|
61543
61610
|
async json() {
|
|
61544
|
-
const
|
|
61545
|
-
return JSON.parse(
|
|
61611
|
+
const text2 = await this.text();
|
|
61612
|
+
return JSON.parse(text2);
|
|
61546
61613
|
}
|
|
61547
61614
|
/**
|
|
61548
61615
|
* Decode response as text
|
|
@@ -62694,7 +62761,7 @@ var require_gaxios = __commonJS({
|
|
|
62694
62761
|
var retry_js_1 = require_retry3();
|
|
62695
62762
|
var stream_1 = __require("stream");
|
|
62696
62763
|
var interceptor_js_1 = require_interceptor();
|
|
62697
|
-
var
|
|
62764
|
+
var randomUUID17 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
62698
62765
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
62699
62766
|
var Gaxios = class {
|
|
62700
62767
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -62967,7 +63034,7 @@ var require_gaxios = __commonJS({
|
|
|
62967
63034
|
*/
|
|
62968
63035
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
62969
63036
|
if (opts.multipart?.length) {
|
|
62970
|
-
const boundary = await
|
|
63037
|
+
const boundary = await randomUUID17();
|
|
62971
63038
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
62972
63039
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
62973
63040
|
} else if (shouldDirectlyPassData) {
|
|
@@ -64718,18 +64785,18 @@ var require_parse = __commonJS({
|
|
|
64718
64785
|
n: "\n",
|
|
64719
64786
|
r: "\r",
|
|
64720
64787
|
t: " "
|
|
64721
|
-
},
|
|
64788
|
+
}, text2, error = function(m2) {
|
|
64722
64789
|
throw {
|
|
64723
64790
|
name: "SyntaxError",
|
|
64724
64791
|
message: m2,
|
|
64725
64792
|
at,
|
|
64726
|
-
text
|
|
64793
|
+
text: text2
|
|
64727
64794
|
};
|
|
64728
64795
|
}, next = function(c) {
|
|
64729
64796
|
if (c && c !== ch) {
|
|
64730
64797
|
error("Expected '" + c + "' instead of '" + ch + "'");
|
|
64731
64798
|
}
|
|
64732
|
-
ch =
|
|
64799
|
+
ch = text2.charAt(at);
|
|
64733
64800
|
at += 1;
|
|
64734
64801
|
return ch;
|
|
64735
64802
|
}, number44 = function() {
|
|
@@ -64776,12 +64843,12 @@ var require_parse = __commonJS({
|
|
|
64776
64843
|
var startAt = at;
|
|
64777
64844
|
while (next()) {
|
|
64778
64845
|
if (ch === '"') {
|
|
64779
|
-
if (at - 1 > startAt) string474 +=
|
|
64846
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
64780
64847
|
next();
|
|
64781
64848
|
return string474;
|
|
64782
64849
|
}
|
|
64783
64850
|
if (ch === "\\") {
|
|
64784
|
-
if (at - 1 > startAt) string474 +=
|
|
64851
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
64785
64852
|
next();
|
|
64786
64853
|
if (ch === "u") {
|
|
64787
64854
|
uffff = 0;
|
|
@@ -64914,7 +64981,7 @@ var require_parse = __commonJS({
|
|
|
64914
64981
|
};
|
|
64915
64982
|
return function(source, reviver) {
|
|
64916
64983
|
var result;
|
|
64917
|
-
|
|
64984
|
+
text2 = source + "";
|
|
64918
64985
|
at = 0;
|
|
64919
64986
|
ch = " ";
|
|
64920
64987
|
result = value();
|
|
@@ -65826,8 +65893,8 @@ var require_crypto = __commonJS({
|
|
|
65826
65893
|
const result = new TextDecoder().decode(uint8array);
|
|
65827
65894
|
return result;
|
|
65828
65895
|
}
|
|
65829
|
-
encodeBase64StringUtf8(
|
|
65830
|
-
const uint8array = new TextEncoder().encode(
|
|
65896
|
+
encodeBase64StringUtf8(text2) {
|
|
65897
|
+
const uint8array = new TextEncoder().encode(text2);
|
|
65831
65898
|
const result = base64js.fromByteArray(uint8array);
|
|
65832
65899
|
return result;
|
|
65833
65900
|
}
|
|
@@ -65896,8 +65963,8 @@ var require_crypto2 = __commonJS({
|
|
|
65896
65963
|
decodeBase64StringUtf8(base64) {
|
|
65897
65964
|
return Buffer.from(base64, "base64").toString("utf-8");
|
|
65898
65965
|
}
|
|
65899
|
-
encodeBase64StringUtf8(
|
|
65900
|
-
return Buffer.from(
|
|
65966
|
+
encodeBase64StringUtf8(text2) {
|
|
65967
|
+
return Buffer.from(text2, "utf-8").toString("base64");
|
|
65901
65968
|
}
|
|
65902
65969
|
/**
|
|
65903
65970
|
* Computes the SHA-256 hash of the provided string.
|
|
@@ -86342,8 +86409,8 @@ async function defaultParseResponse3(client, props) {
|
|
|
86342
86409
|
const json2 = await response.json();
|
|
86343
86410
|
return json2;
|
|
86344
86411
|
}
|
|
86345
|
-
const
|
|
86346
|
-
return
|
|
86412
|
+
const text2 = await response.text();
|
|
86413
|
+
return text2;
|
|
86347
86414
|
})();
|
|
86348
86415
|
loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
|
|
86349
86416
|
retryOfRequestLogID,
|
|
@@ -87920,7 +87987,7 @@ var init_node = __esm({
|
|
|
87920
87987
|
if (this.candidates && this.candidates.length > 1) {
|
|
87921
87988
|
console.warn("there are multiple candidates in the response, returning text from the first one.");
|
|
87922
87989
|
}
|
|
87923
|
-
let
|
|
87990
|
+
let text2 = "";
|
|
87924
87991
|
let anyTextPartText = false;
|
|
87925
87992
|
const nonTextParts = [];
|
|
87926
87993
|
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 : []) {
|
|
@@ -87934,13 +88001,13 @@ var init_node = __esm({
|
|
|
87934
88001
|
continue;
|
|
87935
88002
|
}
|
|
87936
88003
|
anyTextPartText = true;
|
|
87937
|
-
|
|
88004
|
+
text2 += part.text;
|
|
87938
88005
|
}
|
|
87939
88006
|
}
|
|
87940
88007
|
if (nonTextParts.length > 0) {
|
|
87941
88008
|
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.`);
|
|
87942
88009
|
}
|
|
87943
|
-
return anyTextPartText ?
|
|
88010
|
+
return anyTextPartText ? text2 : void 0;
|
|
87944
88011
|
}
|
|
87945
88012
|
/**
|
|
87946
88013
|
* Returns the concatenation of all inline data parts from the first candidate
|
|
@@ -88193,7 +88260,7 @@ var init_node = __esm({
|
|
|
88193
88260
|
*/
|
|
88194
88261
|
get text() {
|
|
88195
88262
|
var _a5, _b, _c;
|
|
88196
|
-
let
|
|
88263
|
+
let text2 = "";
|
|
88197
88264
|
let anyTextPartFound = false;
|
|
88198
88265
|
const nonTextParts = [];
|
|
88199
88266
|
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 : []) {
|
|
@@ -88207,13 +88274,13 @@ var init_node = __esm({
|
|
|
88207
88274
|
continue;
|
|
88208
88275
|
}
|
|
88209
88276
|
anyTextPartFound = true;
|
|
88210
|
-
|
|
88277
|
+
text2 += part.text;
|
|
88211
88278
|
}
|
|
88212
88279
|
}
|
|
88213
88280
|
if (nonTextParts.length > 0) {
|
|
88214
88281
|
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.`);
|
|
88215
88282
|
}
|
|
88216
|
-
return anyTextPartFound ?
|
|
88283
|
+
return anyTextPartFound ? text2 : void 0;
|
|
88217
88284
|
}
|
|
88218
88285
|
/**
|
|
88219
88286
|
* Returns the concatenation of all inline data parts from the server content if present.
|
|
@@ -92885,9 +92952,9 @@ var init_node = __esm({
|
|
|
92885
92952
|
}
|
|
92886
92953
|
return n;
|
|
92887
92954
|
};
|
|
92888
|
-
safeJSON3 = (
|
|
92955
|
+
safeJSON3 = (text2) => {
|
|
92889
92956
|
try {
|
|
92890
|
-
return JSON.parse(
|
|
92957
|
+
return JSON.parse(text2);
|
|
92891
92958
|
} catch (err) {
|
|
92892
92959
|
return void 0;
|
|
92893
92960
|
}
|
|
@@ -110750,8 +110817,8 @@ function findBoundary(buf) {
|
|
|
110750
110817
|
return null;
|
|
110751
110818
|
}
|
|
110752
110819
|
function parseMessage2(chunk, parse2, state, dataRequired) {
|
|
110753
|
-
const
|
|
110754
|
-
const lines =
|
|
110820
|
+
const text2 = new TextDecoder().decode(chunk);
|
|
110821
|
+
const lines = text2.split(/\r\n|\r|\n/);
|
|
110755
110822
|
const dataLines = [];
|
|
110756
110823
|
const ret = {};
|
|
110757
110824
|
let ignore = true;
|
|
@@ -133625,10 +133692,10 @@ function formatMistralError(error) {
|
|
|
133625
133692
|
}
|
|
133626
133693
|
return safeJsonStringify(error);
|
|
133627
133694
|
}
|
|
133628
|
-
function truncateErrorText(
|
|
133629
|
-
if (
|
|
133630
|
-
return
|
|
133631
|
-
return `${
|
|
133695
|
+
function truncateErrorText(text2, maxChars) {
|
|
133696
|
+
if (text2.length <= maxChars)
|
|
133697
|
+
return text2;
|
|
133698
|
+
return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
|
|
133632
133699
|
}
|
|
133633
133700
|
function safeJsonStringify(value) {
|
|
133634
133701
|
try {
|
|
@@ -133748,7 +133815,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
|
|
|
133748
133815
|
continue;
|
|
133749
133816
|
}
|
|
133750
133817
|
if (item.type === "thinking") {
|
|
133751
|
-
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((
|
|
133818
|
+
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
|
|
133752
133819
|
const thinkingDelta = sanitizeSurrogates(deltaText);
|
|
133753
133820
|
if (!thinkingDelta)
|
|
133754
133821
|
continue;
|
|
@@ -133945,8 +134012,8 @@ function toChatMessages(messages, supportsImages) {
|
|
|
133945
134012
|
}
|
|
133946
134013
|
return result;
|
|
133947
134014
|
}
|
|
133948
|
-
function buildToolResultText(
|
|
133949
|
-
const trimmed =
|
|
134015
|
+
function buildToolResultText(text2, hasImages, supportsImages, isError) {
|
|
134016
|
+
const trimmed = text2.trim();
|
|
133950
134017
|
const errorPrefix = isError ? "[tool error] " : "";
|
|
133951
134018
|
if (trimmed.length > 0) {
|
|
133952
134019
|
const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
|
|
@@ -134747,14 +134814,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
134747
134814
|
};
|
|
134748
134815
|
const onMessage = (event) => {
|
|
134749
134816
|
void (async () => {
|
|
134750
|
-
let
|
|
134817
|
+
let text2 = null;
|
|
134751
134818
|
try {
|
|
134752
134819
|
if (!event || typeof event !== "object" || !("data" in event))
|
|
134753
134820
|
return;
|
|
134754
|
-
|
|
134755
|
-
if (!
|
|
134821
|
+
text2 = await decodeWebSocketData(event.data);
|
|
134822
|
+
if (!text2)
|
|
134756
134823
|
return;
|
|
134757
|
-
const parsed = JSON.parse(
|
|
134824
|
+
const parsed = JSON.parse(text2);
|
|
134758
134825
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
134759
134826
|
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
134760
134827
|
sawCompletion = true;
|
|
@@ -134765,7 +134832,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
134765
134832
|
} catch (cause) {
|
|
134766
134833
|
failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
|
|
134767
134834
|
cause,
|
|
134768
|
-
payload:
|
|
134835
|
+
payload: text2
|
|
134769
134836
|
});
|
|
134770
134837
|
done = true;
|
|
134771
134838
|
wake();
|
|
@@ -142958,11 +143025,11 @@ function videoRequestConfig(input) {
|
|
|
142958
143025
|
};
|
|
142959
143026
|
}
|
|
142960
143027
|
async function readMiniMaxJson(response) {
|
|
142961
|
-
const
|
|
143028
|
+
const text2 = await response.text();
|
|
142962
143029
|
let body = {};
|
|
142963
|
-
if (
|
|
143030
|
+
if (text2) {
|
|
142964
143031
|
try {
|
|
142965
|
-
const parsed = JSON.parse(
|
|
143032
|
+
const parsed = JSON.parse(text2);
|
|
142966
143033
|
if (isRecord2(parsed)) body = parsed;
|
|
142967
143034
|
} catch {
|
|
142968
143035
|
throw new Error("MiniMax video API returned invalid JSON");
|
|
@@ -143865,6 +143932,7 @@ __export(store_exports, {
|
|
|
143865
143932
|
CodeGraphStore: () => CodeGraphStore
|
|
143866
143933
|
});
|
|
143867
143934
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
143935
|
+
import { posix as pathPosix } from "path";
|
|
143868
143936
|
function rowToFile(row) {
|
|
143869
143937
|
return {
|
|
143870
143938
|
id: row.id,
|
|
@@ -143915,6 +143983,26 @@ function rowToEdge(row) {
|
|
|
143915
143983
|
...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
|
|
143916
143984
|
};
|
|
143917
143985
|
}
|
|
143986
|
+
function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
|
|
143987
|
+
const target = evidence?.trim().replace(/\\/g, "/");
|
|
143988
|
+
if (!target?.startsWith(".")) return void 0;
|
|
143989
|
+
const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
|
|
143990
|
+
if (!base || base === ".." || base.startsWith("../")) return void 0;
|
|
143991
|
+
const candidates = [base];
|
|
143992
|
+
const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
|
|
143993
|
+
const hasExtension = Boolean(extensionMatch);
|
|
143994
|
+
if (!hasExtension) {
|
|
143995
|
+
const extensions = [...new Set([...fileByPath.keys()].map((path33) => path33.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
|
|
143996
|
+
for (const extension3 of extensions) {
|
|
143997
|
+
candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
|
|
143998
|
+
}
|
|
143999
|
+
} else {
|
|
144000
|
+
const sourceStem = base.slice(0, -extensionMatch[1].length);
|
|
144001
|
+
const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
|
|
144002
|
+
for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
|
|
144003
|
+
}
|
|
144004
|
+
return candidates.map((candidate) => fileByPath.get(candidate)).find((file) => Boolean(file));
|
|
144005
|
+
}
|
|
143918
144006
|
function rowToRef(row) {
|
|
143919
144007
|
return {
|
|
143920
144008
|
id: row.id,
|
|
@@ -143975,6 +144063,18 @@ function rowToSnapshot(row) {
|
|
|
143975
144063
|
...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
|
|
143976
144064
|
};
|
|
143977
144065
|
}
|
|
144066
|
+
function rowToSnapshotFile(row) {
|
|
144067
|
+
return {
|
|
144068
|
+
snapshotId: row.snapshotId,
|
|
144069
|
+
projectId: row.projectId,
|
|
144070
|
+
fileId: row.fileId,
|
|
144071
|
+
path: row.path,
|
|
144072
|
+
contentHash: row.contentHash
|
|
144073
|
+
};
|
|
144074
|
+
}
|
|
144075
|
+
function snapshotIsIncomplete(snapshot) {
|
|
144076
|
+
return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
|
|
144077
|
+
}
|
|
143978
144078
|
var CodeGraphStore;
|
|
143979
144079
|
var init_store = __esm({
|
|
143980
144080
|
"src/codegraph/store.ts"() {
|
|
@@ -144146,6 +144246,7 @@ var init_store = __esm({
|
|
|
144146
144246
|
}
|
|
144147
144247
|
});
|
|
144148
144248
|
tx();
|
|
144249
|
+
this.reconcileLocalImportTargets(projectId);
|
|
144149
144250
|
}
|
|
144150
144251
|
/**
|
|
144151
144252
|
* Reconcile only files whose source changed plus files that disappeared.
|
|
@@ -144155,7 +144256,10 @@ var init_store = __esm({
|
|
|
144155
144256
|
const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
|
|
144156
144257
|
const metadataOnly = (input.metadataOnly ?? []).filter((file) => file.projectId === projectId);
|
|
144157
144258
|
const removedFileIds = input.removedFileIds ?? [];
|
|
144158
|
-
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0)
|
|
144259
|
+
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
|
|
144260
|
+
this.reconcileLocalImportTargets(projectId);
|
|
144261
|
+
return;
|
|
144262
|
+
}
|
|
144159
144263
|
const staleRefsForFile = this.db.prepare(`
|
|
144160
144264
|
UPDATE observation_code_refs
|
|
144161
144265
|
SET status = 'stale', updatedAt = ?
|
|
@@ -144165,9 +144269,18 @@ var init_store = __esm({
|
|
|
144165
144269
|
)
|
|
144166
144270
|
)
|
|
144167
144271
|
`);
|
|
144168
|
-
const
|
|
144272
|
+
const deleteEdgesFromFile = this.db.prepare(`
|
|
144273
|
+
DELETE FROM code_edges
|
|
144274
|
+
WHERE projectId = ? AND fromFileId = ?
|
|
144275
|
+
`);
|
|
144276
|
+
const clearImportTargetsForFile = this.db.prepare(`
|
|
144277
|
+
UPDATE code_edges
|
|
144278
|
+
SET toFileId = NULL
|
|
144279
|
+
WHERE projectId = ? AND toFileId = ? AND type = 'imports'
|
|
144280
|
+
`);
|
|
144281
|
+
const deleteOtherIncomingEdgesForFile = this.db.prepare(`
|
|
144169
144282
|
DELETE FROM code_edges
|
|
144170
|
-
WHERE projectId = ? AND
|
|
144283
|
+
WHERE projectId = ? AND toFileId = ? AND type != 'imports'
|
|
144171
144284
|
`);
|
|
144172
144285
|
const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
|
|
144173
144286
|
const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
|
|
@@ -144204,14 +144317,18 @@ var init_store = __esm({
|
|
|
144204
144317
|
const staleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
144205
144318
|
for (const fileId of removedFileIds) {
|
|
144206
144319
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
144207
|
-
|
|
144320
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
144321
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
144322
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
144208
144323
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
144209
144324
|
deleteFile.run(projectId, fileId);
|
|
144210
144325
|
}
|
|
144211
144326
|
for (const delta of changed) {
|
|
144212
144327
|
const fileId = delta.file.id;
|
|
144213
144328
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
144214
|
-
|
|
144329
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
144330
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
144331
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
144215
144332
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
144216
144333
|
writeFile7(delta.file);
|
|
144217
144334
|
for (const symbol of delta.symbols) {
|
|
@@ -144249,6 +144366,7 @@ var init_store = __esm({
|
|
|
144249
144366
|
for (const file of metadataOnly) writeFile7(file);
|
|
144250
144367
|
});
|
|
144251
144368
|
tx();
|
|
144369
|
+
this.reconcileLocalImportTargets(projectId);
|
|
144252
144370
|
}
|
|
144253
144371
|
upsertObservationRefs(refs) {
|
|
144254
144372
|
if (refs.length === 0) return;
|
|
@@ -144310,6 +144428,25 @@ var init_store = __esm({
|
|
|
144310
144428
|
});
|
|
144311
144429
|
tx();
|
|
144312
144430
|
}
|
|
144431
|
+
/**
|
|
144432
|
+
* Lite import extraction records the original import text first. Resolve only
|
|
144433
|
+
* local relative imports against the current index after each refresh, so an
|
|
144434
|
+
* added or removed target cannot leave a fabricated file-to-file relation.
|
|
144435
|
+
*/
|
|
144436
|
+
reconcileLocalImportTargets(projectId) {
|
|
144437
|
+
const fileById = new Map(this.listFiles(projectId).map((file) => [file.id, file]));
|
|
144438
|
+
const fileByPath = new Map([...fileById.values()].map((file) => [file.path, file]));
|
|
144439
|
+
const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
|
|
144440
|
+
const tx = this.db.transaction(() => {
|
|
144441
|
+
for (const edge of this.listEdges(projectId)) {
|
|
144442
|
+
if (edge.type !== "imports" || !edge.fromFileId) continue;
|
|
144443
|
+
const source = fileById.get(edge.fromFileId);
|
|
144444
|
+
const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
|
|
144445
|
+
update2.run(target?.id ?? null, edge.id);
|
|
144446
|
+
}
|
|
144447
|
+
});
|
|
144448
|
+
tx();
|
|
144449
|
+
}
|
|
144313
144450
|
getFile(projectId, path33) {
|
|
144314
144451
|
const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path33));
|
|
144315
144452
|
return row ? rowToFile(row) : null;
|
|
@@ -144384,6 +144521,18 @@ var init_store = __esm({
|
|
|
144384
144521
|
ORDER BY observationId, status, id
|
|
144385
144522
|
`).all(projectId).map(rowToRef);
|
|
144386
144523
|
}
|
|
144524
|
+
/** Count distinct observations whose binding to these exact files is stale. */
|
|
144525
|
+
countStaleObservationRefsForFiles(projectId, fileIds) {
|
|
144526
|
+
const ids = [...new Set(fileIds.filter(Boolean))];
|
|
144527
|
+
if (ids.length === 0) return 0;
|
|
144528
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
144529
|
+
const row = this.db.prepare(`
|
|
144530
|
+
SELECT COUNT(DISTINCT observationId) AS count
|
|
144531
|
+
FROM observation_code_refs
|
|
144532
|
+
WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
|
|
144533
|
+
`).get(projectId, ...ids);
|
|
144534
|
+
return Number(row?.count ?? 0);
|
|
144535
|
+
}
|
|
144387
144536
|
listReferencedSymbols(projectId) {
|
|
144388
144537
|
return this.db.prepare(`
|
|
144389
144538
|
SELECT DISTINCT symbols.*
|
|
@@ -144405,6 +144554,94 @@ var init_store = __esm({
|
|
|
144405
144554
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
144406
144555
|
).all(projectId, safeLimit2).map(rowToSnapshot);
|
|
144407
144556
|
}
|
|
144557
|
+
listSnapshotFiles(snapshotId) {
|
|
144558
|
+
return this.db.prepare(`
|
|
144559
|
+
SELECT snapshotId, projectId, fileId, path, contentHash
|
|
144560
|
+
FROM code_state_snapshot_files
|
|
144561
|
+
WHERE snapshotId = ?
|
|
144562
|
+
ORDER BY path
|
|
144563
|
+
`).all(snapshotId).map(rowToSnapshotFile);
|
|
144564
|
+
}
|
|
144565
|
+
diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
|
|
144566
|
+
const snapshots = this.db.prepare(`
|
|
144567
|
+
SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
|
|
144568
|
+
`).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
|
|
144569
|
+
if (snapshots.length !== 2) {
|
|
144570
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
|
|
144571
|
+
}
|
|
144572
|
+
if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
|
|
144573
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
|
|
144574
|
+
}
|
|
144575
|
+
if (snapshots.some(snapshotIsIncomplete)) {
|
|
144576
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
|
|
144577
|
+
}
|
|
144578
|
+
const before = this.listSnapshotFiles(fromSnapshotId);
|
|
144579
|
+
const after = this.listSnapshotFiles(toSnapshotId);
|
|
144580
|
+
if (before.length === 0 || after.length === 0) {
|
|
144581
|
+
return {
|
|
144582
|
+
projectId,
|
|
144583
|
+
fromSnapshotId,
|
|
144584
|
+
toSnapshotId,
|
|
144585
|
+
available: false,
|
|
144586
|
+
reason: "legacy-snapshot-without-manifest",
|
|
144587
|
+
changes: []
|
|
144588
|
+
};
|
|
144589
|
+
}
|
|
144590
|
+
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
144591
|
+
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
144592
|
+
const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
|
|
144593
|
+
const changes = [];
|
|
144594
|
+
for (const path33 of paths) {
|
|
144595
|
+
const oldFile = beforeByPath.get(path33);
|
|
144596
|
+
const newFile = afterByPath.get(path33);
|
|
144597
|
+
if (!oldFile && newFile) {
|
|
144598
|
+
changes.push({ path: path33, kind: "added", afterHash: newFile.contentHash });
|
|
144599
|
+
} else if (oldFile && !newFile) {
|
|
144600
|
+
changes.push({ path: path33, kind: "removed", beforeHash: oldFile.contentHash });
|
|
144601
|
+
} else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
|
|
144602
|
+
changes.push({ path: path33, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
|
|
144603
|
+
}
|
|
144604
|
+
}
|
|
144605
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
|
|
144606
|
+
}
|
|
144607
|
+
impactSlice(projectId, changedPaths, maxRelations = 24) {
|
|
144608
|
+
const safeLimit2 = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
|
|
144609
|
+
const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
|
|
144610
|
+
const files = this.listFiles(projectId);
|
|
144611
|
+
const fileById = new Map(files.map((file) => [file.id, file.path]));
|
|
144612
|
+
const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol) => [symbol.id, symbol.fileId]));
|
|
144613
|
+
const changedIds = new Set(files.filter((file) => normalizedPaths.includes(file.path)).map((file) => file.id));
|
|
144614
|
+
const direct = /* @__PURE__ */ new Set();
|
|
144615
|
+
let relationCount = 0;
|
|
144616
|
+
let truncated = false;
|
|
144617
|
+
for (const edge of this.listEdges(projectId)) {
|
|
144618
|
+
const endpoints = [
|
|
144619
|
+
edge.fromFileId,
|
|
144620
|
+
edge.toFileId,
|
|
144621
|
+
edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
|
|
144622
|
+
edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
|
|
144623
|
+
].filter((id) => Boolean(id));
|
|
144624
|
+
if (!endpoints.some((id) => changedIds.has(id))) continue;
|
|
144625
|
+
const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path33) => Boolean(path33));
|
|
144626
|
+
if (relatedPaths.length === 0) continue;
|
|
144627
|
+
if (relationCount >= safeLimit2) {
|
|
144628
|
+
truncated = true;
|
|
144629
|
+
break;
|
|
144630
|
+
}
|
|
144631
|
+
relationCount += 1;
|
|
144632
|
+
for (const path33 of relatedPaths) direct.add(path33);
|
|
144633
|
+
}
|
|
144634
|
+
const snapshot = this.latestSnapshot(projectId);
|
|
144635
|
+
return {
|
|
144636
|
+
projectId,
|
|
144637
|
+
...snapshot ? { snapshotId: snapshot.id } : {},
|
|
144638
|
+
changedPaths: normalizedPaths,
|
|
144639
|
+
directlyConnectedPaths: [...direct].sort(),
|
|
144640
|
+
relationCount,
|
|
144641
|
+
truncated,
|
|
144642
|
+
provider: snapshot?.provider ?? "lite"
|
|
144643
|
+
};
|
|
144644
|
+
}
|
|
144408
144645
|
/**
|
|
144409
144646
|
* Record a completed scan and mark all current structural facts with its
|
|
144410
144647
|
* epoch. The snapshot is written only after refresh reconciliation succeeds,
|
|
@@ -144446,6 +144683,16 @@ var init_store = __esm({
|
|
|
144446
144683
|
this.db.prepare(
|
|
144447
144684
|
"UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
|
|
144448
144685
|
).run(id, input.projectId);
|
|
144686
|
+
const snapshotFileRows = this.db.prepare(`
|
|
144687
|
+
SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
|
|
144688
|
+
`).all(input.projectId);
|
|
144689
|
+
const insertSnapshotFile = this.db.prepare(`
|
|
144690
|
+
INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
|
|
144691
|
+
VALUES (?, ?, ?, ?, ?)
|
|
144692
|
+
`);
|
|
144693
|
+
for (const file of snapshotFileRows) {
|
|
144694
|
+
insertSnapshotFile.run(id, file.projectId, file.id, file.path, file.contentHash);
|
|
144695
|
+
}
|
|
144449
144696
|
snapshot = {
|
|
144450
144697
|
...input,
|
|
144451
144698
|
id,
|
|
@@ -144611,8 +144858,8 @@ __export(lite_provider_exports, {
|
|
|
144611
144858
|
import { createHash as createHash7 } from "crypto";
|
|
144612
144859
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
144613
144860
|
import { join as join4, relative } from "path";
|
|
144614
|
-
function hashText(
|
|
144615
|
-
return createHash7("sha256").update(
|
|
144861
|
+
function hashText(text2) {
|
|
144862
|
+
return createHash7("sha256").update(text2).digest("hex");
|
|
144616
144863
|
}
|
|
144617
144864
|
function extension2(path33) {
|
|
144618
144865
|
const index = path33.lastIndexOf(".");
|
|
@@ -144656,19 +144903,19 @@ function walk(root, exclude, maxFiles) {
|
|
|
144656
144903
|
visit(root);
|
|
144657
144904
|
return out;
|
|
144658
144905
|
}
|
|
144659
|
-
function lineOf(
|
|
144660
|
-
return
|
|
144906
|
+
function lineOf(text2, index) {
|
|
144907
|
+
return text2.slice(0, index).split(/\r?\n/).length;
|
|
144661
144908
|
}
|
|
144662
|
-
function extractSymbols(projectId, file,
|
|
144909
|
+
function extractSymbols(projectId, file, text2, indexedAt) {
|
|
144663
144910
|
const symbols = [];
|
|
144664
144911
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
144665
144912
|
const patterns = profile?.symbols ?? [];
|
|
144666
144913
|
for (const { kind, re } of patterns) {
|
|
144667
144914
|
re.lastIndex = 0;
|
|
144668
|
-
for (const match2 of
|
|
144915
|
+
for (const match2 of text2.matchAll(re)) {
|
|
144669
144916
|
const name = match2[1];
|
|
144670
144917
|
if (!name || name.includes("\n")) continue;
|
|
144671
|
-
const startLine = lineOf(
|
|
144918
|
+
const startLine = lineOf(text2, match2.index ?? 0);
|
|
144672
144919
|
const id = makeCodeSymbolId({ projectId, path: file.path, qualifiedName: name, kind });
|
|
144673
144920
|
symbols.push({
|
|
144674
144921
|
id,
|
|
@@ -144688,13 +144935,13 @@ function extractSymbols(projectId, file, text, indexedAt) {
|
|
|
144688
144935
|
}
|
|
144689
144936
|
return symbols;
|
|
144690
144937
|
}
|
|
144691
|
-
function extractImportEdges(projectId, file,
|
|
144938
|
+
function extractImportEdges(projectId, file, text2, indexedAt) {
|
|
144692
144939
|
const edges = [];
|
|
144693
144940
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
144694
144941
|
const imports = profile?.imports ?? [];
|
|
144695
144942
|
for (const re of imports) {
|
|
144696
144943
|
re.lastIndex = 0;
|
|
144697
|
-
for (const match2 of
|
|
144944
|
+
for (const match2 of text2.matchAll(re)) {
|
|
144698
144945
|
const target = (match2[1] ?? "").trim();
|
|
144699
144946
|
if (!target) continue;
|
|
144700
144947
|
if (target.includes("\n")) {
|
|
@@ -144729,14 +144976,14 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
144729
144976
|
function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
144730
144977
|
const rel = normalizeCodePath(relative(projectRoot, abs));
|
|
144731
144978
|
try {
|
|
144732
|
-
const
|
|
144979
|
+
const text2 = readFileSync6(abs, "utf-8");
|
|
144733
144980
|
const stat4 = fileStat ?? statSync3(abs);
|
|
144734
144981
|
const file = {
|
|
144735
144982
|
id: makeCodeFileId(projectId, rel),
|
|
144736
144983
|
projectId,
|
|
144737
144984
|
path: rel,
|
|
144738
144985
|
language: languageForPath(rel),
|
|
144739
|
-
contentHash: hashText(
|
|
144986
|
+
contentHash: hashText(text2),
|
|
144740
144987
|
// Preserve filesystem precision. Rounding here made same-size edits in
|
|
144741
144988
|
// a short Windows timestamp window indistinguishable to refresh.
|
|
144742
144989
|
mtimeMs: Number(stat4.mtimeMs),
|
|
@@ -144746,8 +144993,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
|
144746
144993
|
return {
|
|
144747
144994
|
delta: {
|
|
144748
144995
|
file,
|
|
144749
|
-
symbols: extractSymbols(projectId, file,
|
|
144750
|
-
edges: extractImportEdges(projectId, file,
|
|
144996
|
+
symbols: extractSymbols(projectId, file, text2, indexedAt),
|
|
144997
|
+
edges: extractImportEdges(projectId, file, text2, indexedAt)
|
|
144751
144998
|
},
|
|
144752
144999
|
unreadable: false
|
|
144753
145000
|
};
|
|
@@ -145026,18 +145273,18 @@ __export(binder_exports, {
|
|
|
145026
145273
|
function observationText(obs) {
|
|
145027
145274
|
return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
|
|
145028
145275
|
}
|
|
145029
|
-
function mentionsSymbol(
|
|
145276
|
+
function mentionsSymbol(text2, symbol) {
|
|
145030
145277
|
const name = symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
145031
|
-
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(
|
|
145278
|
+
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
|
|
145032
145279
|
}
|
|
145033
|
-
function identifierCandidates(
|
|
145034
|
-
return [...new Set(
|
|
145280
|
+
function identifierCandidates(text2) {
|
|
145281
|
+
return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
|
|
145035
145282
|
}
|
|
145036
|
-
function codeIdentifierCandidates(
|
|
145283
|
+
function codeIdentifierCandidates(text2) {
|
|
145037
145284
|
const explicit = /* @__PURE__ */ new Set();
|
|
145038
|
-
for (const match2 of
|
|
145039
|
-
for (const match2 of
|
|
145040
|
-
return identifierCandidates(
|
|
145285
|
+
for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
|
|
145286
|
+
for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
|
|
145287
|
+
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));
|
|
145041
145288
|
}
|
|
145042
145289
|
function fileRef(projectId, obs, file) {
|
|
145043
145290
|
return {
|
|
@@ -145067,7 +145314,7 @@ function symbolRef(projectId, obs, file, symbol) {
|
|
|
145067
145314
|
}
|
|
145068
145315
|
function resolveObservationCodeRefs(obs, lookup2) {
|
|
145069
145316
|
const refs = /* @__PURE__ */ new Map();
|
|
145070
|
-
const
|
|
145317
|
+
const text2 = observationText(obs);
|
|
145071
145318
|
const candidateFiles = /* @__PURE__ */ new Map();
|
|
145072
145319
|
for (const rawPath of obs.filesModified ?? []) {
|
|
145073
145320
|
const file = lookup2.findFile(normalizeCodePath(rawPath));
|
|
@@ -145077,7 +145324,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
145077
145324
|
refs.set(ref.id, ref);
|
|
145078
145325
|
}
|
|
145079
145326
|
const hintedFileIds = new Set(candidateFiles.keys());
|
|
145080
|
-
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(
|
|
145327
|
+
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
|
|
145081
145328
|
const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
|
|
145082
145329
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
145083
145330
|
for (const symbol of symbols) {
|
|
@@ -145088,7 +145335,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
145088
145335
|
for (const group of symbolsByName.values()) {
|
|
145089
145336
|
const candidates = group.length === 1 ? group : [];
|
|
145090
145337
|
for (const symbol of candidates) {
|
|
145091
|
-
if (!mentionsSymbol(
|
|
145338
|
+
if (!mentionsSymbol(text2, symbol)) continue;
|
|
145092
145339
|
const file = candidateFiles.get(symbol.fileId) ?? lookup2.findFile(symbol.path);
|
|
145093
145340
|
if (!file) continue;
|
|
145094
145341
|
candidateFiles.set(file.id, file);
|
|
@@ -145816,8 +146063,8 @@ function taskTokens(task) {
|
|
|
145816
146063
|
return normalizedTokens(task);
|
|
145817
146064
|
}
|
|
145818
146065
|
function scoreClaim(claim, tokens) {
|
|
145819
|
-
const
|
|
145820
|
-
const words = normalizedTokens(
|
|
146066
|
+
const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
|
|
146067
|
+
const words = normalizedTokens(text2);
|
|
145821
146068
|
let matches = 0;
|
|
145822
146069
|
for (const token of tokens) {
|
|
145823
146070
|
if (words.has(token)) matches += 1;
|
|
@@ -146717,6 +146964,128 @@ var init_workflow_store = __esm({
|
|
|
146717
146964
|
}
|
|
146718
146965
|
});
|
|
146719
146966
|
|
|
146967
|
+
// src/knowledge/outcome-types.ts
|
|
146968
|
+
function qualityFromOutcome(signal) {
|
|
146969
|
+
if (!signal) return void 0;
|
|
146970
|
+
if (signal.kind === "verification-failed" || signal.kind === "user-correction" || signal.kind === "source-changed" || signal.kind === "conflict-confirmed") {
|
|
146971
|
+
return "degraded";
|
|
146972
|
+
}
|
|
146973
|
+
if (signal.kind === "verification-passed" || signal.kind === "verified-reuse" || signal.kind === "user-pin") {
|
|
146974
|
+
return "verified";
|
|
146975
|
+
}
|
|
146976
|
+
return void 0;
|
|
146977
|
+
}
|
|
146978
|
+
var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
|
|
146979
|
+
var init_outcome_types = __esm({
|
|
146980
|
+
"src/knowledge/outcome-types.ts"() {
|
|
146981
|
+
"use strict";
|
|
146982
|
+
init_esm_shims();
|
|
146983
|
+
MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
|
|
146984
|
+
MEMORY_OUTCOME_SIGNAL_KINDS = [
|
|
146985
|
+
"verification-passed",
|
|
146986
|
+
"verification-failed",
|
|
146987
|
+
"verified-reuse",
|
|
146988
|
+
"user-pin",
|
|
146989
|
+
"user-correction",
|
|
146990
|
+
"source-changed",
|
|
146991
|
+
"conflict-confirmed",
|
|
146992
|
+
"manual-review"
|
|
146993
|
+
];
|
|
146994
|
+
}
|
|
146995
|
+
});
|
|
146996
|
+
|
|
146997
|
+
// src/knowledge/outcome-store.ts
|
|
146998
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
146999
|
+
function optionalText4(value) {
|
|
147000
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
147001
|
+
}
|
|
147002
|
+
function text(value, field, max = 1e3) {
|
|
147003
|
+
const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
|
|
147004
|
+
if (!safe) throw new Error("Outcome signal " + field + " is required.");
|
|
147005
|
+
if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
|
|
147006
|
+
return safe;
|
|
147007
|
+
}
|
|
147008
|
+
function oneOf(value, values, field) {
|
|
147009
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
147010
|
+
throw new Error("Outcome signal " + field + " is invalid.");
|
|
147011
|
+
}
|
|
147012
|
+
return value;
|
|
147013
|
+
}
|
|
147014
|
+
function rowToSignal(row) {
|
|
147015
|
+
return {
|
|
147016
|
+
id: row.id,
|
|
147017
|
+
projectId: row.projectId,
|
|
147018
|
+
candidateKind: row.candidateKind,
|
|
147019
|
+
candidateId: row.candidateId,
|
|
147020
|
+
kind: row.kind,
|
|
147021
|
+
sourceRef: row.sourceRef,
|
|
147022
|
+
...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
|
|
147023
|
+
...optionalText4(row.detail) ? { detail: row.detail } : {},
|
|
147024
|
+
observedAt: row.observedAt
|
|
147025
|
+
};
|
|
147026
|
+
}
|
|
147027
|
+
var OutcomeStore;
|
|
147028
|
+
var init_outcome_store = __esm({
|
|
147029
|
+
"src/knowledge/outcome-store.ts"() {
|
|
147030
|
+
"use strict";
|
|
147031
|
+
init_esm_shims();
|
|
147032
|
+
init_secret_filter();
|
|
147033
|
+
init_sqlite_db();
|
|
147034
|
+
init_outcome_types();
|
|
147035
|
+
OutcomeStore = class {
|
|
147036
|
+
db = null;
|
|
147037
|
+
async init(dataDir) {
|
|
147038
|
+
this.db = getDatabase(dataDir);
|
|
147039
|
+
}
|
|
147040
|
+
record(input) {
|
|
147041
|
+
const signal = {
|
|
147042
|
+
id: randomUUID10(),
|
|
147043
|
+
projectId: text(input.projectId, "project id"),
|
|
147044
|
+
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
147045
|
+
candidateId: text(input.candidateId, "candidate id"),
|
|
147046
|
+
kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
|
|
147047
|
+
sourceRef: text(input.sourceRef, "source reference"),
|
|
147048
|
+
...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
|
|
147049
|
+
...input.detail ? { detail: text(input.detail, "detail") } : {},
|
|
147050
|
+
observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
147051
|
+
};
|
|
147052
|
+
this.db.prepare(`
|
|
147053
|
+
INSERT INTO memory_outcome_signals (
|
|
147054
|
+
id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
|
|
147055
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
147056
|
+
`).run(
|
|
147057
|
+
signal.id,
|
|
147058
|
+
signal.projectId,
|
|
147059
|
+
signal.candidateKind,
|
|
147060
|
+
signal.candidateId,
|
|
147061
|
+
signal.kind,
|
|
147062
|
+
signal.sourceRef,
|
|
147063
|
+
signal.snapshotId ?? null,
|
|
147064
|
+
signal.detail ?? null,
|
|
147065
|
+
signal.observedAt
|
|
147066
|
+
);
|
|
147067
|
+
return signal;
|
|
147068
|
+
}
|
|
147069
|
+
latestForCandidates(projectId, candidateKind, candidateIds) {
|
|
147070
|
+
const ids = [...new Set(candidateIds.filter(Boolean))];
|
|
147071
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
147072
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
147073
|
+
const rows = this.db.prepare(`
|
|
147074
|
+
SELECT * FROM memory_outcome_signals
|
|
147075
|
+
WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
|
|
147076
|
+
ORDER BY observedAt DESC, id DESC
|
|
147077
|
+
`).all(projectId, candidateKind, ...ids);
|
|
147078
|
+
const latest = /* @__PURE__ */ new Map();
|
|
147079
|
+
for (const row of rows) {
|
|
147080
|
+
const signal = rowToSignal(row);
|
|
147081
|
+
if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
|
|
147082
|
+
}
|
|
147083
|
+
return latest;
|
|
147084
|
+
}
|
|
147085
|
+
};
|
|
147086
|
+
}
|
|
147087
|
+
});
|
|
147088
|
+
|
|
146720
147089
|
// src/codegraph/task-lens.ts
|
|
146721
147090
|
var task_lens_exports = {};
|
|
146722
147091
|
__export(task_lens_exports, {
|
|
@@ -146733,31 +147102,31 @@ __export(task_lens_exports, {
|
|
|
146733
147102
|
function normalizePath2(path33) {
|
|
146734
147103
|
return path33.replace(/\\/g, "/");
|
|
146735
147104
|
}
|
|
146736
|
-
function tokenize3(
|
|
146737
|
-
return (
|
|
147105
|
+
function tokenize3(text2) {
|
|
147106
|
+
return (text2.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1 && !STOP_WORDS.has(token));
|
|
146738
147107
|
}
|
|
146739
|
-
function containsTaskKeyword(
|
|
147108
|
+
function containsTaskKeyword(text2, keyword) {
|
|
146740
147109
|
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");
|
|
146741
147110
|
let match2;
|
|
146742
|
-
while ((match2 = matcher.exec(
|
|
147111
|
+
while ((match2 = matcher.exec(text2)) !== null) {
|
|
146743
147112
|
const keywordIndex = match2.index + (match2[1]?.length ?? 0);
|
|
146744
|
-
if (!isNegatedTaskKeyword(
|
|
147113
|
+
if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
|
|
146745
147114
|
}
|
|
146746
147115
|
return false;
|
|
146747
147116
|
}
|
|
146748
|
-
function isNegatedTaskKeyword(
|
|
147117
|
+
function isNegatedTaskKeyword(text2, keywordIndex) {
|
|
146749
147118
|
const boundary = Math.max(
|
|
146750
|
-
|
|
146751
|
-
|
|
146752
|
-
|
|
146753
|
-
|
|
146754
|
-
|
|
146755
|
-
|
|
146756
|
-
|
|
146757
|
-
|
|
146758
|
-
|
|
147119
|
+
text2.lastIndexOf(".", keywordIndex - 1),
|
|
147120
|
+
text2.lastIndexOf("!", keywordIndex - 1),
|
|
147121
|
+
text2.lastIndexOf("?", keywordIndex - 1),
|
|
147122
|
+
text2.lastIndexOf(";", keywordIndex - 1),
|
|
147123
|
+
text2.lastIndexOf("\n", keywordIndex - 1),
|
|
147124
|
+
text2.lastIndexOf("\u3002", keywordIndex - 1),
|
|
147125
|
+
text2.lastIndexOf("\uFF01", keywordIndex - 1),
|
|
147126
|
+
text2.lastIndexOf("\uFF1F", keywordIndex - 1),
|
|
147127
|
+
text2.lastIndexOf("\uFF1B", keywordIndex - 1)
|
|
146759
147128
|
);
|
|
146760
|
-
let prefix =
|
|
147129
|
+
let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
|
|
146761
147130
|
const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
|
|
146762
147131
|
let contrastMatch;
|
|
146763
147132
|
let contrastEnd = -1;
|
|
@@ -146780,9 +147149,9 @@ function resolveTaskLens(task) {
|
|
|
146780
147149
|
};
|
|
146781
147150
|
for (const id of LENS_PRIORITY) {
|
|
146782
147151
|
const score = KEYWORDS[id].reduce((sum, keyword) => sum + (containsTaskKeyword(normalized, keyword) ? 1 : 0), 0);
|
|
146783
|
-
const
|
|
146784
|
-
if (score > best.score || score === best.score && score > 0 &&
|
|
146785
|
-
best = { id, score, priority };
|
|
147152
|
+
const priority2 = LENS_PRIORITY.indexOf(id);
|
|
147153
|
+
if (score > best.score || score === best.score && score > 0 && priority2 < best.priority) {
|
|
147154
|
+
best = { id, score, priority: priority2 };
|
|
146786
147155
|
}
|
|
146787
147156
|
}
|
|
146788
147157
|
return best.score > 0 ? LENSES[best.id] : LENSES.general;
|
|
@@ -146824,20 +147193,20 @@ function pathKindScore(path33, lens) {
|
|
|
146824
147193
|
return 0;
|
|
146825
147194
|
}
|
|
146826
147195
|
}
|
|
146827
|
-
function tokenScore(
|
|
147196
|
+
function tokenScore(text2, tokens) {
|
|
146828
147197
|
if (tokens.length === 0) return 0;
|
|
146829
|
-
const normalized =
|
|
147198
|
+
const normalized = text2.toLowerCase();
|
|
146830
147199
|
return tokens.reduce((sum, token) => sum + (normalized.includes(token) ? 12 : 0), 0);
|
|
146831
147200
|
}
|
|
146832
147201
|
function sourceTaskMatchScore(source, task) {
|
|
146833
147202
|
const tokens = tokenize3(task ?? "");
|
|
146834
147203
|
if (tokens.length === 0) return 0;
|
|
146835
|
-
const
|
|
147204
|
+
const text2 = [
|
|
146836
147205
|
source.title,
|
|
146837
147206
|
source.path ?? "",
|
|
146838
147207
|
source.symbol ?? ""
|
|
146839
147208
|
].join("\n").toLowerCase();
|
|
146840
|
-
const matches = tokens.filter((token) =>
|
|
147209
|
+
const matches = tokens.filter((token) => text2.includes(token)).length;
|
|
146841
147210
|
if (matches >= 2) return 40;
|
|
146842
147211
|
if (matches === 1) return 24;
|
|
146843
147212
|
return 0;
|
|
@@ -146876,8 +147245,8 @@ function lensPathCandidates(lens) {
|
|
|
146876
147245
|
}
|
|
146877
147246
|
function scoreLensSource(source, lens, task) {
|
|
146878
147247
|
const tokens = tokenize3(task ?? "");
|
|
146879
|
-
const
|
|
146880
|
-
return pathKindScore(source.path ?? "", lens) + tokenScore(
|
|
147248
|
+
const text2 = [source.title, source.type, source.path ?? "", source.symbol ?? ""].join("\n");
|
|
147249
|
+
return pathKindScore(source.path ?? "", lens) + tokenScore(text2, tokens) + sourceTaskMatchScore(source, task);
|
|
146881
147250
|
}
|
|
146882
147251
|
function rankLensSources(sources, lens, task) {
|
|
146883
147252
|
return [...sources].map((source, index) => ({
|
|
@@ -147120,7 +147489,7 @@ function requiredText(data, key) {
|
|
|
147120
147489
|
}
|
|
147121
147490
|
return value.trim();
|
|
147122
147491
|
}
|
|
147123
|
-
function
|
|
147492
|
+
function optionalText5(data, key) {
|
|
147124
147493
|
const value = data[key];
|
|
147125
147494
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
147126
147495
|
if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
|
|
@@ -147163,11 +147532,11 @@ function phaseFromValue(value, index) {
|
|
|
147163
147532
|
}
|
|
147164
147533
|
const data = value;
|
|
147165
147534
|
const title = requiredText(data, "title");
|
|
147166
|
-
const phaseId =
|
|
147535
|
+
const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
|
|
147167
147536
|
return {
|
|
147168
147537
|
id: phaseId,
|
|
147169
147538
|
title,
|
|
147170
|
-
instructions:
|
|
147539
|
+
instructions: optionalText5(data, "instructions") ?? "",
|
|
147171
147540
|
branches: optionalStringArray(data, "branches"),
|
|
147172
147541
|
expectedOutputs: optionalStringArray(data, "expectedOutputs"),
|
|
147173
147542
|
verificationGates: optionalStringArray(data, "verificationGates")
|
|
@@ -147276,7 +147645,7 @@ function parsedWorkflow(data, body, input) {
|
|
|
147276
147645
|
id: requiredText(data, "id"),
|
|
147277
147646
|
workspaceId: input.workspaceId,
|
|
147278
147647
|
title: requiredText(data, "title"),
|
|
147279
|
-
description:
|
|
147648
|
+
description: optionalText5(data, "description") ?? "",
|
|
147280
147649
|
status: optionalStatus(data),
|
|
147281
147650
|
version: optionalNumber(data, "version", 1),
|
|
147282
147651
|
taskLenses: optionalStringArray(data, "taskLenses"),
|
|
@@ -147295,9 +147664,9 @@ function parsedWorkflow(data, body, input) {
|
|
|
147295
147664
|
sourcePath: normalizeSourcePath(input.sourcePath),
|
|
147296
147665
|
sourceHash: "",
|
|
147297
147666
|
contentHash: input.contentHash,
|
|
147298
|
-
createdAt:
|
|
147299
|
-
updatedAt:
|
|
147300
|
-
...
|
|
147667
|
+
createdAt: optionalText5(data, "createdAt") ?? now2(),
|
|
147668
|
+
updatedAt: optionalText5(data, "updatedAt") ?? now2(),
|
|
147669
|
+
...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
|
|
147301
147670
|
};
|
|
147302
147671
|
if (candidate.phases.length === 0) {
|
|
147303
147672
|
throw new Error("workflow must contain at least one phase or a non-empty body");
|
|
@@ -147396,11 +147765,11 @@ async function syncCanonicalWorkflows(workspace) {
|
|
|
147396
147765
|
return { workflows, errors };
|
|
147397
147766
|
}
|
|
147398
147767
|
function inferTaskLenses(value) {
|
|
147399
|
-
const
|
|
147400
|
-
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) =>
|
|
147768
|
+
const text2 = value.toLowerCase();
|
|
147769
|
+
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
|
|
147401
147770
|
}
|
|
147402
147771
|
function taskScore(workflow, task) {
|
|
147403
|
-
const
|
|
147772
|
+
const text2 = task.toLowerCase();
|
|
147404
147773
|
let score = 0;
|
|
147405
147774
|
const reasons = [];
|
|
147406
147775
|
const matchedLenses = /* @__PURE__ */ new Set();
|
|
@@ -147667,7 +148036,31 @@ async function recordWorkflowRun(input) {
|
|
|
147667
148036
|
throw new Error("Workflow was not found for this workspace");
|
|
147668
148037
|
}
|
|
147669
148038
|
if (!input.run.task.trim()) throw new Error("Workflow run task is required");
|
|
147670
|
-
|
|
148039
|
+
const run = store.recordRun(input.run);
|
|
148040
|
+
const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
|
|
148041
|
+
if (!kind) return run;
|
|
148042
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
148043
|
+
evidence.set(workflow.id, "workflow");
|
|
148044
|
+
for (const reference of run.selectedEvidence) {
|
|
148045
|
+
const match2 = /^(claim|durable):(.+)$/.exec(reference);
|
|
148046
|
+
if (!match2) continue;
|
|
148047
|
+
evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
|
|
148048
|
+
}
|
|
148049
|
+
const outcomes = new OutcomeStore();
|
|
148050
|
+
await outcomes.init(workflowStoreDataDir(input.workspace));
|
|
148051
|
+
for (const [candidateId, candidateKind] of evidence) {
|
|
148052
|
+
outcomes.record({
|
|
148053
|
+
projectId: run.projectId,
|
|
148054
|
+
candidateKind,
|
|
148055
|
+
candidateId,
|
|
148056
|
+
kind,
|
|
148057
|
+
sourceRef: "workflow-run:" + run.id,
|
|
148058
|
+
...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
|
|
148059
|
+
...run.failureReason ? { detail: run.failureReason } : {},
|
|
148060
|
+
observedAt: run.completedAt ?? run.startedAt
|
|
148061
|
+
});
|
|
148062
|
+
}
|
|
148063
|
+
return run;
|
|
147671
148064
|
}
|
|
147672
148065
|
async function selectWorkspaceWorkflows(input) {
|
|
147673
148066
|
const synced = await syncCanonicalWorkflows(input.workspace);
|
|
@@ -147692,6 +148085,7 @@ var init_workflows2 = __esm({
|
|
|
147692
148085
|
init_workflow_sync();
|
|
147693
148086
|
init_workspace();
|
|
147694
148087
|
init_workflow_store();
|
|
148088
|
+
init_outcome_store();
|
|
147695
148089
|
init_task_lens();
|
|
147696
148090
|
KNOWN_AGENTS = [
|
|
147697
148091
|
"windsurf",
|
|
@@ -149717,8 +150111,8 @@ async function extractFactsWithLLM(narrative, title, existingFacts) {
|
|
|
149717
150111
|
Content: ${narrative}${existingFacts.length > 0 ? `
|
|
149718
150112
|
Already known facts (don't repeat): ${existingFacts.join("; ")}` : ""}`;
|
|
149719
150113
|
const response = await callLLM2(LLM_EXTRACT_PROMPT, input);
|
|
149720
|
-
const
|
|
149721
|
-
const jsonMatch =
|
|
150114
|
+
const text2 = response.content.trim();
|
|
150115
|
+
const jsonMatch = text2.match(/\{[\s\S]*\}/);
|
|
149722
150116
|
if (!jsonMatch) return [];
|
|
149723
150117
|
const parsed = JSON.parse(jsonMatch[0]);
|
|
149724
150118
|
const facts = parsed.facts;
|
|
@@ -149971,8 +150365,8 @@ Facts: ${extracted.facts.join("; ")}
|
|
|
149971
150365
|
EXISTING MEMORIES:
|
|
149972
150366
|
${existingMemories.map((m2) => `[ID:${m2.id}] ${m2.title} | ${m2.content} | Facts: ${m2.facts}`).join("\n")}`;
|
|
149973
150367
|
const response = await callLLM2(LLM_RESOLVE_PROMPT, input);
|
|
149974
|
-
const
|
|
149975
|
-
const jsonMatch =
|
|
150368
|
+
const text2 = response.content.trim();
|
|
150369
|
+
const jsonMatch = text2.match(/\{[\s\S]*\}/);
|
|
149976
150370
|
if (!jsonMatch) return null;
|
|
149977
150371
|
const parsed = JSON.parse(jsonMatch[0]);
|
|
149978
150372
|
const action = parsed.action?.toUpperCase();
|
|
@@ -150753,8 +151147,8 @@ function isNoiseObservation(obs) {
|
|
|
150753
151147
|
return NOISE_PATTERNS2.some((pattern) => pattern.test(title)) || isCommandTrace(obs);
|
|
150754
151148
|
}
|
|
150755
151149
|
function isSystemSelfObservation(obs) {
|
|
150756
|
-
const
|
|
150757
|
-
return SYSTEM_SELF_PATTERNS.some((pattern) => pattern.test(
|
|
151150
|
+
const text2 = stringifyObservation(obs, false);
|
|
151151
|
+
return SYSTEM_SELF_PATTERNS.some((pattern) => pattern.test(text2));
|
|
150758
151152
|
}
|
|
150759
151153
|
function readerForAlias(reader, aliases, observation) {
|
|
150760
151154
|
if (!reader) return void 0;
|
|
@@ -150777,8 +151171,8 @@ function continuationTaskTokens(task) {
|
|
|
150777
151171
|
function continuationScore(observation, projectTokens, task) {
|
|
150778
151172
|
let score = scoreObservationForSessionContext(observation, projectTokens);
|
|
150779
151173
|
if (observation.type === "session-request" || observation.type === "what-changed") score += 1;
|
|
150780
|
-
const
|
|
150781
|
-
const matches = continuationTaskTokens(task).filter((token) =>
|
|
151174
|
+
const text2 = stringifyObservation(observation);
|
|
151175
|
+
const matches = continuationTaskTokens(task).filter((token) => text2.includes(token)).length;
|
|
150782
151176
|
score += Math.min(matches, 2) * 2;
|
|
150783
151177
|
return score;
|
|
150784
151178
|
}
|
|
@@ -150812,8 +151206,8 @@ async function getSessionResumeBrief(projectId, task, reader) {
|
|
|
150812
151206
|
memories
|
|
150813
151207
|
};
|
|
150814
151208
|
}
|
|
150815
|
-
function compactResumeText(
|
|
150816
|
-
const normalized =
|
|
151209
|
+
function compactResumeText(text2, limit2) {
|
|
151210
|
+
const normalized = text2.replace(/\s+/g, " ").trim();
|
|
150817
151211
|
return normalized.length <= limit2 ? normalized : `${normalized.slice(0, Math.max(0, limit2 - 3)).trimEnd()}...`;
|
|
150818
151212
|
}
|
|
150819
151213
|
function renderSessionResumeCard(brief) {
|
|
@@ -150835,11 +151229,11 @@ function renderSessionResumeCard(brief) {
|
|
|
150835
151229
|
}
|
|
150836
151230
|
function scoreObservationForSessionContext(obs, projectTokens, now3 = Date.now()) {
|
|
150837
151231
|
let score = TYPE_WEIGHTS2[obs.type] ?? 1;
|
|
150838
|
-
const
|
|
151232
|
+
const text2 = stringifyObservation(obs);
|
|
150839
151233
|
const ageDays = Math.max(0, (now3 - new Date(obs.createdAt).getTime()) / (1e3 * 60 * 60 * 24));
|
|
150840
151234
|
score += Math.max(0.2, 2.5 - Math.min(ageDays, 45) * 0.05);
|
|
150841
151235
|
if (projectTokens.length > 0) {
|
|
150842
|
-
const matchingTokens = projectTokens.filter((token) =>
|
|
151236
|
+
const matchingTokens = projectTokens.filter((token) => text2.includes(token));
|
|
150843
151237
|
if (matchingTokens.length > 0) {
|
|
150844
151238
|
score += 2 + matchingTokens.length * 0.6;
|
|
150845
151239
|
} else if ((obs.filesModified?.length ?? 0) > 0) {
|
|
@@ -151155,7 +151549,7 @@ var owner_exports = {};
|
|
|
151155
151549
|
__export(owner_exports, {
|
|
151156
151550
|
resolveLocalMemoryOwner: () => resolveLocalMemoryOwner
|
|
151157
151551
|
});
|
|
151158
|
-
import { randomUUID as
|
|
151552
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
151159
151553
|
import { promises as fs17 } from "fs";
|
|
151160
151554
|
import path25 from "path";
|
|
151161
151555
|
function ownerPath(dataDir) {
|
|
@@ -151185,7 +151579,7 @@ async function resolveLocalMemoryOwner(dataDir, options = {}) {
|
|
|
151185
151579
|
await fs17.mkdir(path25.dirname(filePath), { recursive: true });
|
|
151186
151580
|
const created = {
|
|
151187
151581
|
version: 1,
|
|
151188
|
-
id: "local-" +
|
|
151582
|
+
id: "local-" + randomUUID11(),
|
|
151189
151583
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
151190
151584
|
};
|
|
151191
151585
|
try {
|
|
@@ -151208,8 +151602,8 @@ var init_owner = __esm({
|
|
|
151208
151602
|
});
|
|
151209
151603
|
|
|
151210
151604
|
// src/memory/long-term-store.ts
|
|
151211
|
-
import { randomUUID as
|
|
151212
|
-
function
|
|
151605
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
151606
|
+
function optionalText6(value) {
|
|
151213
151607
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
151214
151608
|
}
|
|
151215
151609
|
function arrayValue2(value) {
|
|
@@ -151234,17 +151628,17 @@ function rowToMemory(row) {
|
|
|
151234
151628
|
content: row.content,
|
|
151235
151629
|
facts: arrayValue2(row.factsJson),
|
|
151236
151630
|
tags: arrayValue2(row.tagsJson),
|
|
151237
|
-
...
|
|
151631
|
+
...optionalText6(row.applicability) ? { applicability: row.applicability } : {},
|
|
151238
151632
|
origin: row.origin,
|
|
151239
151633
|
createdAt: row.createdAt,
|
|
151240
151634
|
updatedAt: row.updatedAt,
|
|
151241
|
-
...
|
|
151242
|
-
...
|
|
151243
|
-
...
|
|
151244
|
-
...
|
|
151245
|
-
...
|
|
151635
|
+
...optionalText6(row.qualifiedAt) ? { qualifiedAt: row.qualifiedAt } : {},
|
|
151636
|
+
...optionalText6(row.approvedAt) ? { approvedAt: row.approvedAt } : {},
|
|
151637
|
+
...optionalText6(row.archivedAt) ? { archivedAt: row.archivedAt } : {},
|
|
151638
|
+
...optionalText6(row.supersededBy) ? { supersededBy: row.supersededBy } : {},
|
|
151639
|
+
...optionalText6(row.lastValidatedAt) ? { lastValidatedAt: row.lastValidatedAt } : {},
|
|
151246
151640
|
accessCount: Number(row.accessCount ?? 0),
|
|
151247
|
-
...
|
|
151641
|
+
...optionalText6(row.lastAccessedAt) ? { lastAccessedAt: row.lastAccessedAt } : {}
|
|
151248
151642
|
};
|
|
151249
151643
|
}
|
|
151250
151644
|
function rowToEvidence2(row) {
|
|
@@ -151254,8 +151648,8 @@ function rowToEvidence2(row) {
|
|
|
151254
151648
|
kind: row.kind,
|
|
151255
151649
|
referenceId: row.referenceId,
|
|
151256
151650
|
relation: row.relation,
|
|
151257
|
-
...
|
|
151258
|
-
...
|
|
151651
|
+
...optionalText6(row.locator) ? { locator: row.locator } : {},
|
|
151652
|
+
...optionalText6(row.capturedHash) ? { capturedHash: row.capturedHash } : {},
|
|
151259
151653
|
createdAt: row.createdAt
|
|
151260
151654
|
};
|
|
151261
151655
|
}
|
|
@@ -151264,9 +151658,9 @@ function rowToEvent2(row) {
|
|
|
151264
151658
|
id: row.id,
|
|
151265
151659
|
memoryId: row.memoryId,
|
|
151266
151660
|
kind: row.kind,
|
|
151267
|
-
...
|
|
151268
|
-
...
|
|
151269
|
-
...
|
|
151661
|
+
...optionalText6(row.fromState) ? { fromState: row.fromState } : {},
|
|
151662
|
+
...optionalText6(row.toState) ? { toState: row.toState } : {},
|
|
151663
|
+
...optionalText6(row.detail) ? { detail: row.detail } : {},
|
|
151270
151664
|
createdAt: row.createdAt
|
|
151271
151665
|
};
|
|
151272
151666
|
}
|
|
@@ -151368,7 +151762,7 @@ var init_long_term_store = __esm({
|
|
|
151368
151762
|
}
|
|
151369
151763
|
insertEvidence(input) {
|
|
151370
151764
|
const evidence = {
|
|
151371
|
-
id:
|
|
151765
|
+
id: randomUUID12(),
|
|
151372
151766
|
...input,
|
|
151373
151767
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
151374
151768
|
};
|
|
@@ -151395,7 +151789,7 @@ var init_long_term_store = __esm({
|
|
|
151395
151789
|
}
|
|
151396
151790
|
recordEvent(input) {
|
|
151397
151791
|
const event = {
|
|
151398
|
-
id:
|
|
151792
|
+
id: randomUUID12(),
|
|
151399
151793
|
...input,
|
|
151400
151794
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
151401
151795
|
};
|
|
@@ -151483,7 +151877,7 @@ __export(long_term_exports, {
|
|
|
151483
151877
|
selectLongTermMemoriesForTask: () => selectLongTermMemoriesForTask,
|
|
151484
151878
|
supersedeLongTermMemory: () => supersedeLongTermMemory
|
|
151485
151879
|
});
|
|
151486
|
-
import { randomUUID as
|
|
151880
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
151487
151881
|
function isOneOf(value, values) {
|
|
151488
151882
|
return typeof value === "string" && values.includes(value);
|
|
151489
151883
|
}
|
|
@@ -151665,7 +152059,7 @@ async function createManualLongTermMemory(input) {
|
|
|
151665
152059
|
const owner = await resolveLocalMemoryOwner(input.dataDir, { create: true });
|
|
151666
152060
|
if (!owner) throw new Error("Memorix could not resolve a local memory owner.");
|
|
151667
152061
|
assertScope(input.scope);
|
|
151668
|
-
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" +
|
|
152062
|
+
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID13(), relation: "supports" }];
|
|
151669
152063
|
return createLongTermMemoryWithDataDir({
|
|
151670
152064
|
dataDir: input.dataDir,
|
|
151671
152065
|
originProjectId: input.projectId,
|
|
@@ -151720,7 +152114,7 @@ async function createLongTermMemoryWithDataDir(input) {
|
|
|
151720
152114
|
assertPortableEvidence(input.scope, portability, evidenceInputs);
|
|
151721
152115
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
151722
152116
|
const memory = {
|
|
151723
|
-
id:
|
|
152117
|
+
id: randomUUID13(),
|
|
151724
152118
|
originProjectId: compactText2(input.originProjectId, "origin project id", 1e3),
|
|
151725
152119
|
ownerId: compactText2(input.ownerId, "owner id", 160),
|
|
151726
152120
|
scope: input.scope,
|
|
@@ -151971,12 +152365,99 @@ var init_long_term = __esm({
|
|
|
151971
152365
|
}
|
|
151972
152366
|
});
|
|
151973
152367
|
|
|
152368
|
+
// src/knowledge/governor.ts
|
|
152369
|
+
function clampRelevance(value) {
|
|
152370
|
+
if (!Number.isFinite(value)) return 0;
|
|
152371
|
+
return Math.max(0, Math.min(1, value));
|
|
152372
|
+
}
|
|
152373
|
+
function classify(candidate) {
|
|
152374
|
+
const freshness = candidate.freshness ?? "unknown";
|
|
152375
|
+
const trust = candidate.trust ?? "historical";
|
|
152376
|
+
const quality = candidate.quality ?? "probationary";
|
|
152377
|
+
const conflict = candidate.conflict ?? "none";
|
|
152378
|
+
if (!candidate.scopeAllowed) {
|
|
152379
|
+
return { disposition: "exclude", reasons: ["scope-forbidden"] };
|
|
152380
|
+
}
|
|
152381
|
+
if (conflict === "confirmed") {
|
|
152382
|
+
return { disposition: "exclude", reasons: ["confirmed-conflict"] };
|
|
152383
|
+
}
|
|
152384
|
+
if (quality === "blocked") {
|
|
152385
|
+
return { disposition: "exclude", reasons: ["blocked-quality"] };
|
|
152386
|
+
}
|
|
152387
|
+
if (quality === "degraded") {
|
|
152388
|
+
return { disposition: "defer", reasons: ["degraded-quality"] };
|
|
152389
|
+
}
|
|
152390
|
+
if (freshness === "stale") {
|
|
152391
|
+
return { disposition: "defer", reasons: ["stale-evidence"] };
|
|
152392
|
+
}
|
|
152393
|
+
const reasons = [];
|
|
152394
|
+
let disposition = "include";
|
|
152395
|
+
if (freshness === "unknown") {
|
|
152396
|
+
disposition = "compact";
|
|
152397
|
+
reasons.push("unknown-freshness");
|
|
152398
|
+
}
|
|
152399
|
+
if (conflict === "possible") {
|
|
152400
|
+
disposition = "compact";
|
|
152401
|
+
reasons.push("possible-conflict");
|
|
152402
|
+
}
|
|
152403
|
+
if (quality === "probationary") {
|
|
152404
|
+
disposition = "compact";
|
|
152405
|
+
reasons.push("probationary-evidence");
|
|
152406
|
+
}
|
|
152407
|
+
if (disposition === "include" && freshness === "current" && trust === "source-backed") {
|
|
152408
|
+
reasons.push("current-source-backed-evidence");
|
|
152409
|
+
} else if (reasons.length === 0) {
|
|
152410
|
+
reasons.push("relevant-evidence");
|
|
152411
|
+
}
|
|
152412
|
+
return { disposition, reasons };
|
|
152413
|
+
}
|
|
152414
|
+
function priority(decision) {
|
|
152415
|
+
const dispositionWeight = {
|
|
152416
|
+
include: 3,
|
|
152417
|
+
compact: 2,
|
|
152418
|
+
defer: 1,
|
|
152419
|
+
exclude: 0
|
|
152420
|
+
};
|
|
152421
|
+
const evidence = Math.min(3, decision.candidate.evidenceCount ?? 0) / 10;
|
|
152422
|
+
return dispositionWeight[decision.disposition] + clampRelevance(decision.candidate.relevance) + evidence;
|
|
152423
|
+
}
|
|
152424
|
+
function governContextCandidates(candidates, maxTokens) {
|
|
152425
|
+
const safeBudget = Math.max(0, Math.floor(maxTokens));
|
|
152426
|
+
const decisions = candidates.map((candidate) => ({ candidate, ...classify(candidate) }));
|
|
152427
|
+
const eligible = decisions.filter((decision) => decision.disposition === "include" || decision.disposition === "compact").sort((left, right) => priority(right) - priority(left));
|
|
152428
|
+
let usedTokens = 0;
|
|
152429
|
+
for (const decision of eligible) {
|
|
152430
|
+
const tokens = Math.max(0, Math.ceil(decision.candidate.estimatedTokens));
|
|
152431
|
+
if (usedTokens + tokens <= safeBudget) {
|
|
152432
|
+
usedTokens += tokens;
|
|
152433
|
+
continue;
|
|
152434
|
+
}
|
|
152435
|
+
decision.disposition = "defer";
|
|
152436
|
+
decision.reasons = [...decision.reasons, "token-budget"];
|
|
152437
|
+
}
|
|
152438
|
+
const delivered = decisions.filter((decision) => decision.disposition === "include" || decision.disposition === "compact");
|
|
152439
|
+
const mode = delivered.length === 0 ? "abstain" : delivered.some((decision) => decision.disposition === "include") ? "workset" : "card";
|
|
152440
|
+
const cautions = [...new Set(decisions.filter((decision) => decision.disposition !== "include").flatMap((decision) => decision.reasons))];
|
|
152441
|
+
return {
|
|
152442
|
+
mode,
|
|
152443
|
+
budget: { maxTokens: safeBudget, usedTokens },
|
|
152444
|
+
decisions,
|
|
152445
|
+
cautions: cautions.length > 0 ? cautions : ["no-qualified-evidence"]
|
|
152446
|
+
};
|
|
152447
|
+
}
|
|
152448
|
+
var init_governor = __esm({
|
|
152449
|
+
"src/knowledge/governor.ts"() {
|
|
152450
|
+
"use strict";
|
|
152451
|
+
init_esm_shims();
|
|
152452
|
+
}
|
|
152453
|
+
});
|
|
152454
|
+
|
|
151974
152455
|
// src/knowledge/workset.ts
|
|
151975
152456
|
function unique(values) {
|
|
151976
152457
|
return [...new Set(values.filter(Boolean))];
|
|
151977
152458
|
}
|
|
151978
|
-
function short(
|
|
151979
|
-
const safe = sanitizeCredentials(
|
|
152459
|
+
function short(text2, budget = 28) {
|
|
152460
|
+
const safe = sanitizeCredentials(text2).replace(/\s+/g, " ").trim();
|
|
151980
152461
|
return countTextTokens(safe) <= budget ? safe : truncateToTokenBudget(safe, budget);
|
|
151981
152462
|
}
|
|
151982
152463
|
function claimAssertion(claim) {
|
|
@@ -152107,6 +152588,65 @@ function receiptOmissions(omitted, hiddenCautionMemoryCount) {
|
|
|
152107
152588
|
function scheduledActions(cautions) {
|
|
152108
152589
|
return cautions.filter((caution) => caution.kind === "codegraph-refresh-queued").map((caution) => short(caution.message, 28));
|
|
152109
152590
|
}
|
|
152591
|
+
function isGovernedDelivery(disposition) {
|
|
152592
|
+
return disposition === "include" || disposition === "compact";
|
|
152593
|
+
}
|
|
152594
|
+
function governOptionalArtifacts(input) {
|
|
152595
|
+
const candidates = [
|
|
152596
|
+
...input.reliableMemory.map((memory, index) => ({
|
|
152597
|
+
kind: "memory",
|
|
152598
|
+
id: "memory:" + memory.id,
|
|
152599
|
+
estimatedTokens: 10,
|
|
152600
|
+
relevance: Math.max(0.2, 0.9 - index * 0.1),
|
|
152601
|
+
scopeAllowed: true,
|
|
152602
|
+
freshness: freshnessForMemory(memory.status),
|
|
152603
|
+
trust: "historical",
|
|
152604
|
+
quality: memory.status === "current" ? "verified" : "degraded"
|
|
152605
|
+
})),
|
|
152606
|
+
...input.claims.map((claim, index) => ({
|
|
152607
|
+
kind: "claim",
|
|
152608
|
+
id: "claim:" + claim.id,
|
|
152609
|
+
estimatedTokens: 12,
|
|
152610
|
+
relevance: Math.max(0.2, 0.95 - index * 0.1),
|
|
152611
|
+
scopeAllowed: true,
|
|
152612
|
+
freshness: claim.status === "active" ? "current" : "unknown",
|
|
152613
|
+
trust: "source-backed",
|
|
152614
|
+
quality: claim.reviewState === "approved" ? "verified" : "probationary",
|
|
152615
|
+
conflict: claim.status === "disputed" ? "confirmed" : "none",
|
|
152616
|
+
evidenceCount: claim.evidenceRefs.length
|
|
152617
|
+
})),
|
|
152618
|
+
...input.durableMemory.map((memory, index) => ({
|
|
152619
|
+
kind: "durable-memory",
|
|
152620
|
+
id: "durable:" + memory.id,
|
|
152621
|
+
estimatedTokens: 14,
|
|
152622
|
+
relevance: Math.max(0.2, 0.8 - index * 0.1),
|
|
152623
|
+
scopeAllowed: true,
|
|
152624
|
+
freshness: memory.state === "approved" ? "current" : "unknown",
|
|
152625
|
+
trust: "source-backed",
|
|
152626
|
+
quality: memory.quality,
|
|
152627
|
+
evidenceCount: memory.evidenceRefs.length
|
|
152628
|
+
})),
|
|
152629
|
+
...input.workflows.map((workflow, index) => ({
|
|
152630
|
+
kind: "workflow",
|
|
152631
|
+
id: "workflow:" + workflow.id,
|
|
152632
|
+
estimatedTokens: 14,
|
|
152633
|
+
relevance: Math.max(0.2, 0.85 - index * 0.1),
|
|
152634
|
+
scopeAllowed: true,
|
|
152635
|
+
freshness: "current",
|
|
152636
|
+
trust: "source-backed",
|
|
152637
|
+
quality: "verified"
|
|
152638
|
+
}))
|
|
152639
|
+
];
|
|
152640
|
+
const plan = governContextCandidates(candidates, Number.MAX_SAFE_INTEGER);
|
|
152641
|
+
const permitted = new Set(plan.decisions.filter((decision) => isGovernedDelivery(decision.disposition)).map((decision) => decision.candidate.id));
|
|
152642
|
+
return {
|
|
152643
|
+
plan,
|
|
152644
|
+
reliableMemory: input.reliableMemory.filter((memory) => permitted.has("memory:" + memory.id)),
|
|
152645
|
+
claims: input.claims.filter((claim) => permitted.has("claim:" + claim.id)),
|
|
152646
|
+
durableMemory: input.durableMemory.filter((memory) => permitted.has("durable:" + memory.id)),
|
|
152647
|
+
workflows: input.workflows.filter((workflow) => permitted.has("workflow:" + workflow.id))
|
|
152648
|
+
};
|
|
152649
|
+
}
|
|
152110
152650
|
function renderTaskWorksetPrompt(input) {
|
|
152111
152651
|
const maxTokens = input.budget?.maxTokens ?? 180;
|
|
152112
152652
|
const omitted = [];
|
|
@@ -152234,6 +152774,56 @@ function renderTaskWorksetPrompt(input) {
|
|
|
152234
152774
|
trust: "source-backed"
|
|
152235
152775
|
});
|
|
152236
152776
|
}
|
|
152777
|
+
if (input.codeEvolution && input.codeEvolution.changes.length > 0) {
|
|
152778
|
+
appendLine(lines, "", maxTokens, omitted, "code-evolution-heading");
|
|
152779
|
+
appendLine(lines, "Code changes since prior scan", maxTokens, omitted, "code-evolution-heading");
|
|
152780
|
+
for (const change of input.codeEvolution.changes.slice(0, 3)) {
|
|
152781
|
+
appendLine(
|
|
152782
|
+
lines,
|
|
152783
|
+
"- " + change.kind + ": " + change.path,
|
|
152784
|
+
maxTokens,
|
|
152785
|
+
omitted,
|
|
152786
|
+
"code-evolution-change",
|
|
152787
|
+
selected,
|
|
152788
|
+
{
|
|
152789
|
+
kind: "code-state",
|
|
152790
|
+
id: "snapshot:" + input.codeEvolution.toSnapshotId,
|
|
152791
|
+
reason: "exact file hash change between complete CodeGraph snapshots",
|
|
152792
|
+
freshness: "current",
|
|
152793
|
+
trust: "source-backed"
|
|
152794
|
+
}
|
|
152795
|
+
);
|
|
152796
|
+
}
|
|
152797
|
+
for (const path33 of input.codeEvolution.directlyConnectedPaths.slice(0, 2)) {
|
|
152798
|
+
appendLine(
|
|
152799
|
+
lines,
|
|
152800
|
+
"- connected now: " + path33,
|
|
152801
|
+
maxTokens,
|
|
152802
|
+
omitted,
|
|
152803
|
+
"code-evolution-impact",
|
|
152804
|
+
selected,
|
|
152805
|
+
{
|
|
152806
|
+
kind: "code-state",
|
|
152807
|
+
id: "snapshot:" + input.codeEvolution.toSnapshotId,
|
|
152808
|
+
reason: "bounded current CodeGraph impact relation",
|
|
152809
|
+
freshness: "current",
|
|
152810
|
+
trust: "derived"
|
|
152811
|
+
}
|
|
152812
|
+
);
|
|
152813
|
+
}
|
|
152814
|
+
if ((input.codeEvolution.affectedMemoryCount ?? 0) > 0) {
|
|
152815
|
+
appendLine(
|
|
152816
|
+
lines,
|
|
152817
|
+
"- " + input.codeEvolution.affectedMemoryCount + " stored memory link(s) reference this changed code; reread source before relying on their conclusions.",
|
|
152818
|
+
maxTokens,
|
|
152819
|
+
omitted,
|
|
152820
|
+
"code-evolution-stale-memory"
|
|
152821
|
+
);
|
|
152822
|
+
}
|
|
152823
|
+
if (input.codeEvolution.truncated) {
|
|
152824
|
+
appendLine(lines, "- More connected files exist; inspect CodeGraph before assuming complete impact.", maxTokens, omitted, "code-evolution-truncated");
|
|
152825
|
+
}
|
|
152826
|
+
}
|
|
152237
152827
|
if (input.semanticCode && (input.semanticCode.entryPoints.length > 0 || input.semanticCode.relations.length > 0)) {
|
|
152238
152828
|
appendLine(lines, "", maxTokens, omitted, "semantic-code-heading");
|
|
152239
152829
|
appendLine(lines, "Semantic code outline", maxTokens, omitted, "semantic-code-heading");
|
|
@@ -152424,6 +153014,17 @@ async function buildTaskWorkset(input) {
|
|
|
152424
153014
|
}));
|
|
152425
153015
|
let durableMemory = [];
|
|
152426
153016
|
let durableEvidence = [];
|
|
153017
|
+
let outcomeStore;
|
|
153018
|
+
try {
|
|
153019
|
+
outcomeStore = new OutcomeStore();
|
|
153020
|
+
await outcomeStore.init(input.dataDir);
|
|
153021
|
+
} catch {
|
|
153022
|
+
}
|
|
153023
|
+
const claimQuality = outcomeStore ? outcomeStore.latestForCandidates(input.projectId, "claim", claims.map((claim) => claim.id)) : /* @__PURE__ */ new Map();
|
|
153024
|
+
for (const claim of claims) {
|
|
153025
|
+
const outcomeQuality = qualityFromOutcome(claimQuality.get(claim.id));
|
|
153026
|
+
if (outcomeQuality === "degraded") claim.reviewState = "needs-review";
|
|
153027
|
+
}
|
|
152427
153028
|
if (task) {
|
|
152428
153029
|
try {
|
|
152429
153030
|
const selected = await selectLongTermMemoriesForTask({
|
|
@@ -152434,11 +153035,13 @@ async function buildTaskWorkset(input) {
|
|
|
152434
153035
|
...input.reader?.isTeamMember ? { isTeamMember: true } : {},
|
|
152435
153036
|
limit: 3
|
|
152436
153037
|
});
|
|
153038
|
+
const durableQuality = outcomeStore ? outcomeStore.latestForCandidates(input.projectId, "durable-memory", selected.map((item) => item.memory.id)) : /* @__PURE__ */ new Map();
|
|
152437
153039
|
durableMemory = selected.map((item) => ({
|
|
152438
153040
|
id: item.memory.id,
|
|
152439
153041
|
kind: item.memory.kind,
|
|
152440
153042
|
scope: item.memory.scope,
|
|
152441
153043
|
state: item.memory.state,
|
|
153044
|
+
quality: qualityFromOutcome(durableQuality.get(item.memory.id)) ?? (item.memory.state === "approved" ? "verified" : "probationary"),
|
|
152442
153045
|
title: item.memory.title,
|
|
152443
153046
|
summary: renderLongTermMemorySummary(item.memory, 20),
|
|
152444
153047
|
evidenceRefs: item.evidence.map((evidence) => evidence.id),
|
|
@@ -152484,18 +153087,25 @@ async function buildTaskWorkset(input) {
|
|
|
152484
153087
|
}
|
|
152485
153088
|
} catch {
|
|
152486
153089
|
}
|
|
152487
|
-
const evidenceIds = unique(selection.claims.flatMap((claim) => evidenceIdsForClaim(
|
|
152488
|
-
claim,
|
|
152489
|
-
evidenceByClaim.get(claim.id) ?? []
|
|
152490
|
-
)).concat(
|
|
152491
|
-
durableMemory.map((memory) => "durable:" + memory.id),
|
|
152492
|
-
durableEvidence.map((evidence) => "durable-evidence:" + evidence.id)
|
|
152493
|
-
));
|
|
152494
153090
|
const verification = unique([
|
|
152495
153091
|
...workflows.flatMap((workflow) => workflow.verificationGates),
|
|
152496
153092
|
...input.verificationHints
|
|
152497
153093
|
]).slice(0, 4);
|
|
152498
153094
|
const normalizedCautions = unique(cautions.map((caution) => caution.kind)).map((kind) => cautions.find((caution) => caution.kind === kind)).slice(0, 6);
|
|
153095
|
+
const governed = governOptionalArtifacts({
|
|
153096
|
+
reliableMemory: input.reliableMemory?.slice(0, 3) ?? [],
|
|
153097
|
+
claims,
|
|
153098
|
+
durableMemory,
|
|
153099
|
+
workflows
|
|
153100
|
+
});
|
|
153101
|
+
const governedDurableIds = new Set(governed.durableMemory.map((memory) => memory.id));
|
|
153102
|
+
const evidenceIds = unique(governed.claims.flatMap((claim) => evidenceIdsForClaim(
|
|
153103
|
+
claim,
|
|
153104
|
+
evidenceByClaim.get(claim.id) ?? []
|
|
153105
|
+
)).concat(
|
|
153106
|
+
governed.durableMemory.map((memory) => "durable:" + memory.id),
|
|
153107
|
+
durableEvidence.filter((evidence) => governedDurableIds.has(evidence.memoryId)).map((evidence) => "durable-evidence:" + evidence.id)
|
|
153108
|
+
));
|
|
152499
153109
|
const continuation = input.continuation && (input.continuation.previousSession || input.continuation.memories.length > 0 || input.continuation.compactCheckpoint) ? {
|
|
152500
153110
|
...input.continuation.previousSession ? {
|
|
152501
153111
|
previousSession: {
|
|
@@ -152522,15 +153132,16 @@ async function buildTaskWorkset(input) {
|
|
|
152522
153132
|
currentFacts: input.currentFacts?.map((fact) => fact.startsWith("Historical note:") ? short(fact, 48) : short(fact, 28)).slice(0, 4) ?? [],
|
|
152523
153133
|
...continuation ? { continuation } : {},
|
|
152524
153134
|
...input.codeState ? { codeState: short(input.codeState, 28) } : {},
|
|
153135
|
+
...input.codeEvolution ? { codeEvolution: input.codeEvolution } : {},
|
|
152525
153136
|
startHere: unique(input.startHere).slice(0, 5),
|
|
152526
153137
|
...input.semanticCode ? { semanticCode: input.semanticCode } : {},
|
|
152527
|
-
reliableMemory:
|
|
153138
|
+
reliableMemory: governed.reliableMemory,
|
|
152528
153139
|
cautionMemory: input.cautionMemory?.slice(0, 3) ?? [],
|
|
152529
153140
|
hiddenCautionMemoryCount: input.hiddenCautionMemoryCount ?? 0,
|
|
152530
|
-
claims,
|
|
152531
|
-
pages,
|
|
152532
|
-
durableMemory,
|
|
152533
|
-
workflows,
|
|
153141
|
+
claims: governed.claims,
|
|
153142
|
+
pages: pages.filter((page) => page.claimIds.some((claimId) => governed.claims.some((claim) => claim.id === claimId))),
|
|
153143
|
+
durableMemory: governed.durableMemory,
|
|
153144
|
+
workflows: governed.workflows,
|
|
152534
153145
|
cautions: normalizedCautions,
|
|
152535
153146
|
verification,
|
|
152536
153147
|
evidenceIds,
|
|
@@ -152555,6 +153166,17 @@ async function buildTaskWorkset(input) {
|
|
|
152555
153166
|
},
|
|
152556
153167
|
selected: rendered.selected,
|
|
152557
153168
|
omitted: receiptOmissions(rendered.omittedItems, base.hiddenCautionMemoryCount),
|
|
153169
|
+
governance: {
|
|
153170
|
+
scope: "optional-evidence",
|
|
153171
|
+
mode: governed.plan.mode,
|
|
153172
|
+
decisions: governed.plan.decisions.map((decision) => ({
|
|
153173
|
+
kind: decision.candidate.kind,
|
|
153174
|
+
...decision.candidate.id ? { id: decision.candidate.id } : {},
|
|
153175
|
+
disposition: decision.disposition,
|
|
153176
|
+
reasons: decision.reasons
|
|
153177
|
+
})),
|
|
153178
|
+
cautions: governed.plan.cautions
|
|
153179
|
+
},
|
|
152558
153180
|
scheduledActions: scheduledActions(normalizedCautions)
|
|
152559
153181
|
};
|
|
152560
153182
|
return {
|
|
@@ -152580,8 +153202,11 @@ var init_workset = __esm({
|
|
|
152580
153202
|
init_workspace_store();
|
|
152581
153203
|
init_workspace();
|
|
152582
153204
|
init_workflow_store();
|
|
153205
|
+
init_outcome_store();
|
|
153206
|
+
init_outcome_types();
|
|
152583
153207
|
init_workflows2();
|
|
152584
153208
|
init_long_term();
|
|
153209
|
+
init_governor();
|
|
152585
153210
|
CONTINUATION_DETAIL_TOKEN_BUDGET = 20;
|
|
152586
153211
|
}
|
|
152587
153212
|
});
|
|
@@ -152604,19 +153229,19 @@ function readTextIfExists(filePath) {
|
|
|
152604
153229
|
}
|
|
152605
153230
|
}
|
|
152606
153231
|
function readPackageVersion(rootPath) {
|
|
152607
|
-
const
|
|
152608
|
-
if (!
|
|
153232
|
+
const text2 = readTextIfExists(path26.join(rootPath, "package.json"));
|
|
153233
|
+
if (!text2) return void 0;
|
|
152609
153234
|
try {
|
|
152610
|
-
const parsed = JSON.parse(
|
|
153235
|
+
const parsed = JSON.parse(text2);
|
|
152611
153236
|
return typeof parsed.version === "string" ? parsed.version : void 0;
|
|
152612
153237
|
} catch {
|
|
152613
153238
|
return void 0;
|
|
152614
153239
|
}
|
|
152615
153240
|
}
|
|
152616
153241
|
function readLatestChangelog(rootPath) {
|
|
152617
|
-
const
|
|
152618
|
-
if (!
|
|
152619
|
-
const match2 =
|
|
153242
|
+
const text2 = readTextIfExists(path26.join(rootPath, "CHANGELOG.md"));
|
|
153243
|
+
if (!text2) return void 0;
|
|
153244
|
+
const match2 = text2.match(/^##\s+\[?v?([^\]\s]+)\]?\s*(?:-\s*(\d{4}-\d{2}-\d{2}))?/m);
|
|
152620
153245
|
if (!match2) return void 0;
|
|
152621
153246
|
return {
|
|
152622
153247
|
version: match2[1],
|
|
@@ -152679,6 +153304,7 @@ function compareDateStrings(a, b) {
|
|
|
152679
153304
|
}
|
|
152680
153305
|
function detectStaleProgressNotes(input) {
|
|
152681
153306
|
const candidates = [
|
|
153307
|
+
"ACTIVE_WORK.md",
|
|
152682
153308
|
"progress.txt",
|
|
152683
153309
|
"docs/dev-log/progress.txt",
|
|
152684
153310
|
"docs/memcode/dev-log/progress.txt"
|
|
@@ -152816,6 +153442,7 @@ function providerQuality(input) {
|
|
|
152816
153442
|
capabilities: {
|
|
152817
153443
|
declarations: true,
|
|
152818
153444
|
importHints: true,
|
|
153445
|
+
localRelativeImportTargets: true,
|
|
152819
153446
|
resolvedRelations: false,
|
|
152820
153447
|
exactLocations: false
|
|
152821
153448
|
},
|
|
@@ -153337,8 +153964,8 @@ var compaction_checkpoint_store_exports = {};
|
|
|
153337
153964
|
__export(compaction_checkpoint_store_exports, {
|
|
153338
153965
|
CompactionCheckpointStore: () => CompactionCheckpointStore
|
|
153339
153966
|
});
|
|
153340
|
-
import { createHash as createHash14, randomUUID as
|
|
153341
|
-
function
|
|
153967
|
+
import { createHash as createHash14, randomUUID as randomUUID14 } from "crypto";
|
|
153968
|
+
function optionalText7(value) {
|
|
153342
153969
|
return typeof value === "string" && value ? value : void 0;
|
|
153343
153970
|
}
|
|
153344
153971
|
function optionalNumber2(value) {
|
|
@@ -153392,15 +154019,15 @@ function rowToCheckpoint(row) {
|
|
|
153392
154019
|
reason: row.reason,
|
|
153393
154020
|
sourceEvent: row.source_event,
|
|
153394
154021
|
sourceKey: row.source_key,
|
|
153395
|
-
...
|
|
154022
|
+
...optionalText7(row.summary) ? { summary: row.summary } : {},
|
|
153396
154023
|
...optionalNumber2(row.tokens_before) !== void 0 ? { tokensBefore: Number(row.tokens_before) } : {},
|
|
153397
|
-
...
|
|
154024
|
+
...optionalText7(row.first_kept_entry_id) ? { firstKeptEntryId: row.first_kept_entry_id } : {},
|
|
153398
154025
|
...parseDetails(row.details_json) ? { details: parseDetails(row.details_json) } : {},
|
|
153399
154026
|
transcriptAvailable: Boolean(row.transcript_available),
|
|
153400
154027
|
status: row.status,
|
|
153401
154028
|
preCapturedAt: row.pre_captured_at,
|
|
153402
|
-
...
|
|
153403
|
-
...
|
|
154029
|
+
...optionalText7(row.completed_at) ? { completedAt: row.completed_at } : {},
|
|
154030
|
+
...optionalText7(row.delivered_at) ? { deliveredAt: row.delivered_at } : {},
|
|
153404
154031
|
deliveryCount: Number(row.delivery_count ?? 0),
|
|
153405
154032
|
createdAt: row.created_at,
|
|
153406
154033
|
updatedAt: row.updated_at
|
|
@@ -153438,7 +154065,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
153438
154065
|
if (pending) return rowToCheckpoint(pending);
|
|
153439
154066
|
const now3 = input.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
153440
154067
|
const checkpoint = {
|
|
153441
|
-
id:
|
|
154068
|
+
id: randomUUID14(),
|
|
153442
154069
|
projectId: input.projectId,
|
|
153443
154070
|
sessionId: input.sessionId,
|
|
153444
154071
|
agent: input.agent,
|
|
@@ -153446,7 +154073,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
153446
154073
|
captureKind: "preflight",
|
|
153447
154074
|
reason: safeReason(input.reason),
|
|
153448
154075
|
sourceEvent: input.sourceEvent,
|
|
153449
|
-
sourceKey: `pre:${
|
|
154076
|
+
sourceKey: `pre:${randomUUID14()}`,
|
|
153450
154077
|
transcriptAvailable: Boolean(input.transcriptAvailable),
|
|
153451
154078
|
status: "active",
|
|
153452
154079
|
preCapturedAt: now3,
|
|
@@ -153512,7 +154139,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
153512
154139
|
return this.get(checkpoint2.id);
|
|
153513
154140
|
}
|
|
153514
154141
|
const checkpoint = {
|
|
153515
|
-
id:
|
|
154142
|
+
id: randomUUID14(),
|
|
153516
154143
|
projectId: input.projectId,
|
|
153517
154144
|
sessionId: input.sessionId,
|
|
153518
154145
|
agent: input.agent,
|
|
@@ -153774,6 +154401,25 @@ async function buildAutoProjectContext(input) {
|
|
|
153774
154401
|
const overview = explain.overview;
|
|
153775
154402
|
const currentFacts = collectCurrentProjectFacts({ project: input.project, now: now3 });
|
|
153776
154403
|
const latestSnapshot = overview.code.latestSnapshot;
|
|
154404
|
+
let codeEvolution;
|
|
154405
|
+
if (continuationRequested && latestSnapshot?.previousSnapshotId && latestSnapshot.changedPathCount > 0) {
|
|
154406
|
+
const diff = store.diffSnapshots(input.project.id, latestSnapshot.previousSnapshotId, latestSnapshot.id);
|
|
154407
|
+
if (diff.available && diff.changes.length > 0) {
|
|
154408
|
+
const impact = store.impactSlice(input.project.id, diff.changes.map((change) => change.path));
|
|
154409
|
+
const changedFileIds = new Set([
|
|
154410
|
+
...store.listSnapshotFiles(diff.fromSnapshotId),
|
|
154411
|
+
...store.listSnapshotFiles(diff.toSnapshotId)
|
|
154412
|
+
].filter((file) => diff.changes.some((change) => change.path === file.path)).map((file) => file.fileId));
|
|
154413
|
+
codeEvolution = {
|
|
154414
|
+
fromSnapshotId: diff.fromSnapshotId,
|
|
154415
|
+
toSnapshotId: diff.toSnapshotId,
|
|
154416
|
+
changes: diff.changes.slice(0, 5).map((change) => ({ path: change.path, kind: change.kind })),
|
|
154417
|
+
directlyConnectedPaths: impact.directlyConnectedPaths.slice(0, 3),
|
|
154418
|
+
affectedMemoryCount: store.countStaleObservationRefsForFiles(input.project.id, [...changedFileIds]),
|
|
154419
|
+
truncated: impact.truncated || diff.changes.length > 5
|
|
154420
|
+
};
|
|
154421
|
+
}
|
|
154422
|
+
}
|
|
153777
154423
|
const sourceSets = lensSourceSets({ task, lens, explain });
|
|
153778
154424
|
let externalOutline;
|
|
153779
154425
|
let externalCaution;
|
|
@@ -153850,6 +154496,7 @@ async function buildAutoProjectContext(input) {
|
|
|
153850
154496
|
currentFacts: worksetFactLines(currentFacts),
|
|
153851
154497
|
...continuation ? { continuation } : {},
|
|
153852
154498
|
codeState: codeStateLine(overview),
|
|
154499
|
+
...codeEvolution ? { codeEvolution } : {},
|
|
153853
154500
|
reliableMemory: sourceSets.reliableSources.slice(0, lens.sourceLimit).map((source) => ({
|
|
153854
154501
|
id: source.observationId,
|
|
153855
154502
|
title: source.title,
|
|
@@ -153901,9 +154548,9 @@ async function buildAutoProjectContext(input) {
|
|
|
153901
154548
|
function formatLanguages(overview) {
|
|
153902
154549
|
return overview.code.languages.length > 0 ? overview.code.languages.map((item) => `${item.language} ${item.files}`).join(", ") : "none indexed yet";
|
|
153903
154550
|
}
|
|
153904
|
-
function compactContinuationText(
|
|
154551
|
+
function compactContinuationText(text2, budget) {
|
|
153905
154552
|
return truncateToTokenBudget(
|
|
153906
|
-
sanitizeCredentials(
|
|
154553
|
+
sanitizeCredentials(text2).replace(/\s+/g, " ").trim(),
|
|
153907
154554
|
budget
|
|
153908
154555
|
);
|
|
153909
154556
|
}
|
|
@@ -154178,8 +154825,8 @@ __export(context_pack_exports, {
|
|
|
154178
154825
|
function uniq2(items) {
|
|
154179
154826
|
return [...new Set(items)];
|
|
154180
154827
|
}
|
|
154181
|
-
function tokenize4(
|
|
154182
|
-
return (
|
|
154828
|
+
function tokenize4(text2) {
|
|
154829
|
+
return (text2.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1);
|
|
154183
154830
|
}
|
|
154184
154831
|
function timestampOf(observation) {
|
|
154185
154832
|
return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
|
|
@@ -154781,7 +155428,7 @@ __export(team_store_exports, {
|
|
|
154781
155428
|
isTeamStoreInitialized: () => isTeamStoreInitialized,
|
|
154782
155429
|
resetTeamStore: () => resetTeamStore
|
|
154783
155430
|
});
|
|
154784
|
-
import { randomUUID as
|
|
155431
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
154785
155432
|
import path28 from "path";
|
|
154786
155433
|
import fs18 from "fs";
|
|
154787
155434
|
function getTeamStore() {
|
|
@@ -155070,7 +155717,7 @@ var init_team_store = __esm({
|
|
|
155070
155717
|
* reactivate it (preserving agent_id). Otherwise create a new one.
|
|
155071
155718
|
*/
|
|
155072
155719
|
registerAgent(input) {
|
|
155073
|
-
const instanceId = input.instanceId ||
|
|
155720
|
+
const instanceId = input.instanceId || randomUUID15();
|
|
155074
155721
|
const now3 = Date.now();
|
|
155075
155722
|
const existing = this.stmtAgentFindByInstance.get(
|
|
155076
155723
|
input.projectId,
|
|
@@ -155096,7 +155743,7 @@ var init_team_store = __esm({
|
|
|
155096
155743
|
this.eventBus?.emit("agent:joined", { agentId: row2.agent_id, projectId: input.projectId, agentType: input.agentType });
|
|
155097
155744
|
return row2;
|
|
155098
155745
|
}
|
|
155099
|
-
const agentId =
|
|
155746
|
+
const agentId = randomUUID15();
|
|
155100
155747
|
this.stmtAgentUpsert.run({
|
|
155101
155748
|
agent_id: agentId,
|
|
155102
155749
|
project_id: input.projectId,
|
|
@@ -155198,7 +155845,7 @@ var init_team_store = __esm({
|
|
|
155198
155845
|
return { error: `Recipient agent '${input.recipientAgentId}' not found \u2014 cannot send to unknown agent` };
|
|
155199
155846
|
}
|
|
155200
155847
|
}
|
|
155201
|
-
const id =
|
|
155848
|
+
const id = randomUUID15();
|
|
155202
155849
|
const now3 = Date.now();
|
|
155203
155850
|
const row = {
|
|
155204
155851
|
id,
|
|
@@ -155248,7 +155895,7 @@ var init_team_store = __esm({
|
|
|
155248
155895
|
// Task Operations (with atomic claim semantics)
|
|
155249
155896
|
// ═══════════════════════════════════════════════════════════════════
|
|
155250
155897
|
createTask(input) {
|
|
155251
|
-
const taskId =
|
|
155898
|
+
const taskId = randomUUID15();
|
|
155252
155899
|
const now3 = Date.now();
|
|
155253
155900
|
const row = {
|
|
155254
155901
|
task_id: taskId,
|
|
@@ -155520,7 +156167,7 @@ var init_team_store = __esm({
|
|
|
155520
156167
|
for (const [agentId, msgs] of Object.entries(snap.messages.inboxes)) {
|
|
155521
156168
|
for (const msg of msgs) {
|
|
155522
156169
|
this.stmtMsgInsert.run({
|
|
155523
|
-
id: msg.id ??
|
|
156170
|
+
id: msg.id ?? randomUUID15(),
|
|
155524
156171
|
project_id: "migrated",
|
|
155525
156172
|
sender_agent_id: msg.from ?? "unknown",
|
|
155526
156173
|
recipient_agent_id: msg.to === "__broadcast__" ? null : msg.to ?? agentId,
|
|
@@ -155793,19 +156440,19 @@ function buildCompactionWorkset(checkpoint, options = {}) {
|
|
|
155793
156440
|
const source = sanitizeCredentials(checkpoint.summary?.trim() || fallback);
|
|
155794
156441
|
const available = Math.max(0, budget - countTextTokens(header) - 4);
|
|
155795
156442
|
let excerpt = source ? truncateToTokenBudget(source, available) : "";
|
|
155796
|
-
let
|
|
156443
|
+
let text2 = `${header}${excerpt ? `### Host checkpoint
|
|
155797
156444
|
${excerpt}` : ""}`.trim();
|
|
155798
|
-
while (excerpt && countTextTokens(
|
|
156445
|
+
while (excerpt && countTextTokens(text2) > budget) {
|
|
155799
156446
|
const nextExcerptBudget = Math.max(1, Math.floor(countTextTokens(excerpt) * 0.8));
|
|
155800
156447
|
excerpt = truncateToTokenBudget(excerpt, nextExcerptBudget);
|
|
155801
|
-
|
|
156448
|
+
text2 = `${header}${excerpt ? `### Host checkpoint
|
|
155802
156449
|
${excerpt}` : ""}`.trim();
|
|
155803
156450
|
}
|
|
155804
|
-
if (countTextTokens(
|
|
156451
|
+
if (countTextTokens(text2) > budget) text2 = truncateToTokenBudget(text2, budget);
|
|
155805
156452
|
return {
|
|
155806
156453
|
checkpointId: checkpoint.id,
|
|
155807
|
-
text,
|
|
155808
|
-
tokens: countTextTokens(
|
|
156454
|
+
text: text2,
|
|
156455
|
+
tokens: countTextTokens(text2)
|
|
155809
156456
|
};
|
|
155810
156457
|
}
|
|
155811
156458
|
function sourceEvent(input) {
|
|
@@ -157696,15 +158343,15 @@ function validateSemantics(graph) {
|
|
|
157696
158343
|
return warnings;
|
|
157697
158344
|
}
|
|
157698
158345
|
function extractJson(raw) {
|
|
157699
|
-
let
|
|
158346
|
+
let text2 = raw;
|
|
157700
158347
|
try {
|
|
157701
158348
|
const envelope = JSON.parse(raw.trim());
|
|
157702
158349
|
if (envelope && typeof envelope.result === "string" && envelope.type === "result") {
|
|
157703
|
-
|
|
158350
|
+
text2 = envelope.result;
|
|
157704
158351
|
}
|
|
157705
158352
|
} catch {
|
|
157706
158353
|
}
|
|
157707
|
-
if (
|
|
158354
|
+
if (text2 === raw && raw.includes('"type"')) {
|
|
157708
158355
|
const textBlocks = [];
|
|
157709
158356
|
for (const line of raw.split("\n")) {
|
|
157710
158357
|
const trimmed = line.trim();
|
|
@@ -157728,27 +158375,27 @@ function extractJson(raw) {
|
|
|
157728
158375
|
}
|
|
157729
158376
|
}
|
|
157730
158377
|
if (textBlocks.length > 0) {
|
|
157731
|
-
|
|
158378
|
+
text2 = textBlocks.join("");
|
|
157732
158379
|
}
|
|
157733
158380
|
}
|
|
157734
|
-
const fenced =
|
|
158381
|
+
const fenced = text2.match(/```(?:json)?\s*\n?([\s\S]*?)```/);
|
|
157735
158382
|
if (fenced) {
|
|
157736
158383
|
const candidate = fenced[1].trim();
|
|
157737
158384
|
if (candidate.startsWith("{")) return candidate;
|
|
157738
158385
|
}
|
|
157739
|
-
const braceStart =
|
|
158386
|
+
const braceStart = text2.indexOf("{");
|
|
157740
158387
|
if (braceStart !== -1) {
|
|
157741
|
-
const extracted = extractBalancedJson(
|
|
158388
|
+
const extracted = extractBalancedJson(text2, braceStart);
|
|
157742
158389
|
if (extracted) return extracted;
|
|
157743
158390
|
}
|
|
157744
158391
|
return null;
|
|
157745
158392
|
}
|
|
157746
|
-
function extractBalancedJson(
|
|
158393
|
+
function extractBalancedJson(text2, startIdx) {
|
|
157747
158394
|
let depth = 0;
|
|
157748
158395
|
let inString = false;
|
|
157749
158396
|
let escape2 = false;
|
|
157750
|
-
for (let i2 = startIdx; i2 <
|
|
157751
|
-
const ch =
|
|
158397
|
+
for (let i2 = startIdx; i2 < text2.length; i2++) {
|
|
158398
|
+
const ch = text2[i2];
|
|
157752
158399
|
if (escape2) {
|
|
157753
158400
|
escape2 = false;
|
|
157754
158401
|
continue;
|
|
@@ -157766,7 +158413,7 @@ function extractBalancedJson(text, startIdx) {
|
|
|
157766
158413
|
else if (ch === "}") {
|
|
157767
158414
|
depth--;
|
|
157768
158415
|
if (depth === 0) {
|
|
157769
|
-
return
|
|
158416
|
+
return text2.slice(startIdx, i2 + 1);
|
|
157770
158417
|
}
|
|
157771
158418
|
}
|
|
157772
158419
|
}
|
|
@@ -157985,7 +158632,7 @@ __export(planner_exports, {
|
|
|
157985
158632
|
materializeTaskGraph: () => materializeTaskGraph,
|
|
157986
158633
|
seedAutonomousPipeline: () => seedAutonomousPipeline
|
|
157987
158634
|
});
|
|
157988
|
-
import { randomUUID as
|
|
158635
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
157989
158636
|
function isPlannerTask(metadata) {
|
|
157990
158637
|
if (!metadata) return null;
|
|
157991
158638
|
try {
|
|
@@ -158043,7 +158690,7 @@ function seedAutonomousPipeline(teamStore, projectId, config, opts) {
|
|
|
158043
158690
|
const maxIterations = config.maxIterations ?? 3;
|
|
158044
158691
|
const taskBudget = config.taskBudget ?? 15;
|
|
158045
158692
|
const structuredPlan = opts?.structuredPlan ?? true;
|
|
158046
|
-
const pipelineId =
|
|
158693
|
+
const pipelineId = randomUUID16();
|
|
158047
158694
|
const meta = {
|
|
158048
158695
|
plannerType: "plan",
|
|
158049
158696
|
pipelineId,
|
|
@@ -158488,8 +159135,8 @@ async function callVisionLLM(systemPrompt, imageBase64, mimeType) {
|
|
|
158488
159135
|
return data.choices[0]?.message?.content ?? "";
|
|
158489
159136
|
}
|
|
158490
159137
|
function normalizeText4(value, fallback = "") {
|
|
158491
|
-
const
|
|
158492
|
-
return sanitizeCredentials(
|
|
159138
|
+
const text2 = typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
159139
|
+
return sanitizeCredentials(text2).slice(0, MAX_VISION_DESCRIPTION_CHARS);
|
|
158493
159140
|
}
|
|
158494
159141
|
function normalizeLabels(value) {
|
|
158495
159142
|
if (!Array.isArray(value)) return [];
|
|
@@ -161179,7 +161826,7 @@ function evidenceScore2(obs) {
|
|
|
161179
161826
|
}
|
|
161180
161827
|
function scoreForPacket(obs, queryTokens, referenceTime, broadMemoryQuery) {
|
|
161181
161828
|
let score = 0;
|
|
161182
|
-
const
|
|
161829
|
+
const text2 = normalizeText3([
|
|
161183
161830
|
obs.title,
|
|
161184
161831
|
obs.narrative,
|
|
161185
161832
|
obs.entityName,
|
|
@@ -161188,15 +161835,15 @@ function scoreForPacket(obs, queryTokens, referenceTime, broadMemoryQuery) {
|
|
|
161188
161835
|
...obs.relatedEntities ?? [],
|
|
161189
161836
|
...obs.relatedCommits ?? []
|
|
161190
161837
|
].join(" "));
|
|
161191
|
-
const matchingTokens = queryTokens.filter((token) =>
|
|
161838
|
+
const matchingTokens = queryTokens.filter((token) => text2.includes(token));
|
|
161192
161839
|
score += matchingTokens.length * 4;
|
|
161193
161840
|
if (queryTokens.length > 0 && matchingTokens.length === 0) {
|
|
161194
161841
|
score -= 8;
|
|
161195
161842
|
}
|
|
161196
|
-
if (broadMemoryQuery && /memorix|memcode|memory-(?:graph|injection|runtime|quality|formation)|graph-context/.test(
|
|
161843
|
+
if (broadMemoryQuery && /memorix|memcode|memory-(?:graph|injection|runtime|quality|formation)|graph-context/.test(text2)) {
|
|
161197
161844
|
score += 8;
|
|
161198
161845
|
}
|
|
161199
|
-
if (/\bmemory[- ]?game\b|e2e-test\/memory-game|team-handoff/.test(
|
|
161846
|
+
if (/\bmemory[- ]?game\b|e2e-test\/memory-game|team-handoff/.test(text2)) {
|
|
161200
161847
|
score -= broadMemoryQuery ? 12 : 4;
|
|
161201
161848
|
}
|
|
161202
161849
|
score += obs.valueCategory === "core" ? 6 : 0;
|
|
@@ -164129,7 +164776,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
164129
164776
|
};
|
|
164130
164777
|
const server = existingServer ?? new McpServer({
|
|
164131
164778
|
name: "memorix",
|
|
164132
|
-
version: true ? "1.4.
|
|
164779
|
+
version: true ? "1.4.2" : "1.0.1"
|
|
164133
164780
|
});
|
|
164134
164781
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
164135
164782
|
server.registerTool = ((name, ...args) => {
|
|
@@ -164865,10 +165512,10 @@ Use this as the \`topicKey\` parameter in \`memorix_store\` to enable upsert beh
|
|
|
164865
165512
|
const duplicate = blockCoveredAutopilotEvidence("memorix_search", result.entries.map((entry) => entry.id), force);
|
|
164866
165513
|
if (duplicate) return duplicate;
|
|
164867
165514
|
}
|
|
164868
|
-
let
|
|
165515
|
+
let text2 = result.formatted;
|
|
164869
165516
|
try {
|
|
164870
165517
|
const { getLastSearchMode: getLastSearchMode2 } = await Promise.resolve().then(() => (init_orama_store(), orama_store_exports));
|
|
164871
|
-
|
|
165518
|
+
text2 += `
|
|
164872
165519
|
|
|
164873
165520
|
_Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
164874
165521
|
} catch {
|
|
@@ -164877,7 +165524,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
164877
165524
|
content: [
|
|
164878
165525
|
{
|
|
164879
165526
|
type: "text",
|
|
164880
|
-
text
|
|
165527
|
+
text: text2
|
|
164881
165528
|
}
|
|
164882
165529
|
]
|
|
164883
165530
|
};
|
|
@@ -164910,14 +165557,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
164910
165557
|
query,
|
|
164911
165558
|
limit: limit2 != null ? coerceNumber(limit2, 5) : void 0
|
|
164912
165559
|
});
|
|
164913
|
-
const
|
|
165560
|
+
const text2 = format === "summary" ? [
|
|
164914
165561
|
`Graph context packet for ${project.name}`,
|
|
164915
165562
|
`- ${packet.summary}`,
|
|
164916
165563
|
"",
|
|
164917
165564
|
...packet.entities.map((entity) => `* ${entity.name} (#${entity.observationIds.join(", #")})`)
|
|
164918
165565
|
].join("\n") : formatGraphContextPrompt(packet);
|
|
164919
165566
|
return {
|
|
164920
|
-
content: [{ type: "text", text }]
|
|
165567
|
+
content: [{ type: "text", text: text2 }]
|
|
164921
165568
|
};
|
|
164922
165569
|
}
|
|
164923
165570
|
);
|
|
@@ -164977,7 +165624,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
164977
165624
|
});
|
|
164978
165625
|
}
|
|
164979
165626
|
});
|
|
164980
|
-
const
|
|
165627
|
+
const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
|
|
164981
165628
|
autopilotRetrievalBoundary = {
|
|
164982
165629
|
projectId: project.id,
|
|
164983
165630
|
issuedAt: Date.now(),
|
|
@@ -164989,7 +165636,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
164989
165636
|
readOnly: READ_ONLY_TASK_PATTERN.test(task ?? "")
|
|
164990
165637
|
};
|
|
164991
165638
|
return {
|
|
164992
|
-
content: [{ type: "text", text }]
|
|
165639
|
+
content: [{ type: "text", text: text2 }]
|
|
164993
165640
|
};
|
|
164994
165641
|
}
|
|
164995
165642
|
);
|
|
@@ -165117,9 +165764,9 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165117
165764
|
...external.caution ? { runtimeCautions: [{ kind: "external-codegraph-fallback", message: external.caution }] } : {},
|
|
165118
165765
|
reader: getObservationReader()
|
|
165119
165766
|
});
|
|
165120
|
-
const
|
|
165767
|
+
const text2 = buildContextPackPrompt2(pack);
|
|
165121
165768
|
return {
|
|
165122
|
-
content: [{ type: "text", text }]
|
|
165769
|
+
content: [{ type: "text", text: text2 }]
|
|
165123
165770
|
};
|
|
165124
165771
|
}
|
|
165125
165772
|
);
|
|
@@ -165181,7 +165828,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165181
165828
|
}) => {
|
|
165182
165829
|
const unresolved = requireResolvedProject("manage the Knowledge Workspace for the current project");
|
|
165183
165830
|
if (unresolved) return unresolved;
|
|
165184
|
-
const
|
|
165831
|
+
const text2 = (value, isError = false) => ({
|
|
165185
165832
|
content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
|
|
165186
165833
|
...isError ? { isError: true } : {}
|
|
165187
165834
|
});
|
|
@@ -165218,7 +165865,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165218
165865
|
]);
|
|
165219
165866
|
if (action === "workspace_init") {
|
|
165220
165867
|
if (modeValue === "versioned" && !requireText(workspacePath, "path")) {
|
|
165221
|
-
return
|
|
165868
|
+
return text2({ error: "path is required to initialize a versioned Knowledge Workspace." }, true);
|
|
165222
165869
|
}
|
|
165223
165870
|
const workspace2 = await initializeKnowledgeWorkspace2({
|
|
165224
165871
|
projectId: project.id,
|
|
@@ -165226,7 +165873,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165226
165873
|
mode: modeValue,
|
|
165227
165874
|
...modeValue === "versioned" ? { projectRoot: project.rootPath, rootPath: requireText(workspacePath, "path") } : {}
|
|
165228
165875
|
});
|
|
165229
|
-
return
|
|
165876
|
+
return text2({
|
|
165230
165877
|
workspace: {
|
|
165231
165878
|
id: workspace2.id,
|
|
165232
165879
|
mode: workspace2.mode,
|
|
@@ -165238,7 +165885,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165238
165885
|
}
|
|
165239
165886
|
const workspace = await loadKnowledgeWorkspace2({ projectId: project.id, dataDir: projectDir2, mode: modeValue });
|
|
165240
165887
|
if (!workspace) {
|
|
165241
|
-
return
|
|
165888
|
+
return text2({ error: "Knowledge Workspace is not initialized. Run workspace_init first." }, true);
|
|
165242
165889
|
}
|
|
165243
165890
|
const claims = new ClaimStore2();
|
|
165244
165891
|
const workspaceStore = new KnowledgeWorkspaceStore2();
|
|
@@ -165246,7 +165893,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165246
165893
|
if (action === "status") {
|
|
165247
165894
|
const pages = workspaceStore.listPages(workspace.id);
|
|
165248
165895
|
const pending = workspaceStore.listProposals(workspace.id, "pending");
|
|
165249
|
-
return
|
|
165896
|
+
return text2({
|
|
165250
165897
|
workspace: {
|
|
165251
165898
|
id: workspace.id,
|
|
165252
165899
|
mode: workspace.mode,
|
|
@@ -165264,7 +165911,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165264
165911
|
});
|
|
165265
165912
|
}
|
|
165266
165913
|
if (action === "claim_list") {
|
|
165267
|
-
return
|
|
165914
|
+
return text2({
|
|
165268
165915
|
claims: claims.listClaims(project.id, { limit: 100 }).map((claim) => ({
|
|
165269
165916
|
id: claim.id,
|
|
165270
165917
|
subject: claim.subject,
|
|
@@ -165283,18 +165930,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165283
165930
|
const requestedClaimId = requireText(claimId, "claimId");
|
|
165284
165931
|
const detail = requireText(reviewDetail, "reviewDetail");
|
|
165285
165932
|
if (!requestedClaimId || !claimReviewState || !detail) {
|
|
165286
|
-
return
|
|
165933
|
+
return text2({ error: "claimId, claimReviewState, and reviewDetail are required for claim_review." }, true);
|
|
165287
165934
|
}
|
|
165288
165935
|
const existing = claims.getClaim(requestedClaimId);
|
|
165289
165936
|
if (!existing || existing.projectId !== project.id) {
|
|
165290
|
-
return
|
|
165937
|
+
return text2({ error: "Claim was not found for the current project." }, true);
|
|
165291
165938
|
}
|
|
165292
165939
|
const claim = reviewClaim2(claims, {
|
|
165293
165940
|
claimId: requestedClaimId,
|
|
165294
165941
|
reviewState: claimReviewState,
|
|
165295
165942
|
detail
|
|
165296
165943
|
});
|
|
165297
|
-
return
|
|
165944
|
+
return text2({
|
|
165298
165945
|
claim: {
|
|
165299
165946
|
id: claim.id,
|
|
165300
165947
|
status: claim.status,
|
|
@@ -165306,7 +165953,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165306
165953
|
}
|
|
165307
165954
|
if (action === "compile") {
|
|
165308
165955
|
const result = await compileKnowledgeWorkspace2({ workspace, claims });
|
|
165309
|
-
return
|
|
165956
|
+
return text2({
|
|
165310
165957
|
proposals: result.proposals.map((proposal) => ({
|
|
165311
165958
|
id: proposal.id,
|
|
165312
165959
|
targetPath: proposal.targetPath,
|
|
@@ -165321,17 +165968,17 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165321
165968
|
const codeStore = new CodeGraphStore2();
|
|
165322
165969
|
await codeStore.init(projectDir2);
|
|
165323
165970
|
const result = await lintKnowledgeWorkspace2({ workspace, claims, codeStore });
|
|
165324
|
-
return
|
|
165971
|
+
return text2(result);
|
|
165325
165972
|
}
|
|
165326
165973
|
if (action === "proposal_apply") {
|
|
165327
165974
|
const proposal = requireText(proposalId, "proposalId");
|
|
165328
|
-
if (!proposal) return
|
|
165975
|
+
if (!proposal) return text2({ error: "proposalId is required for proposal_apply." }, true);
|
|
165329
165976
|
const result = await applyKnowledgeProposal2({
|
|
165330
165977
|
workspace,
|
|
165331
165978
|
proposalId: proposal,
|
|
165332
165979
|
allowManualOverwrite: !!allowManualOverwrite
|
|
165333
165980
|
});
|
|
165334
|
-
return
|
|
165981
|
+
return text2({
|
|
165335
165982
|
proposal: { id: result.proposal.id, status: result.proposal.status },
|
|
165336
165983
|
targetPath: result.targetPath
|
|
165337
165984
|
});
|
|
@@ -165341,7 +165988,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165341
165988
|
const projectRoot = workspace.projectRoot ?? project.rootPath;
|
|
165342
165989
|
if (action === "workflow_import") {
|
|
165343
165990
|
const result = await importWindsurfWorkflows2({ workspace, projectRoot });
|
|
165344
|
-
return
|
|
165991
|
+
return text2({
|
|
165345
165992
|
imported: result.imported.map((workflow2) => ({
|
|
165346
165993
|
id: workflow2.id,
|
|
165347
165994
|
title: workflow2.title,
|
|
@@ -165354,7 +166001,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165354
166001
|
}
|
|
165355
166002
|
const synced = await syncCanonicalWorkflows2(workspace);
|
|
165356
166003
|
if (action === "workflow_list") {
|
|
165357
|
-
return
|
|
166004
|
+
return text2({
|
|
165358
166005
|
workflows: workflowStore.listWorkflows(workspace.id).map((workflow2) => ({
|
|
165359
166006
|
id: workflow2.id,
|
|
165360
166007
|
title: workflow2.title,
|
|
@@ -165369,9 +166016,9 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165369
166016
|
}
|
|
165370
166017
|
if (action === "workflow_select") {
|
|
165371
166018
|
const selectedTask = requireText(task, "task");
|
|
165372
|
-
if (!selectedTask) return
|
|
166019
|
+
if (!selectedTask) return text2({ error: "task is required for workflow_select." }, true);
|
|
165373
166020
|
const result = await selectWorkspaceWorkflows2({ workspace, task: selectedTask });
|
|
165374
|
-
return
|
|
166021
|
+
return text2({
|
|
165375
166022
|
selections: result.selections.map((selection) => ({
|
|
165376
166023
|
id: selection.workflow.id,
|
|
165377
166024
|
title: selection.workflow.title,
|
|
@@ -165383,16 +166030,16 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165383
166030
|
});
|
|
165384
166031
|
}
|
|
165385
166032
|
const requestedWorkflowId = requireText(workflowId, "workflowId");
|
|
165386
|
-
if (!requestedWorkflowId) return
|
|
166033
|
+
if (!requestedWorkflowId) return text2({ error: "workflowId is required for this workflow action." }, true);
|
|
165387
166034
|
const workflow = workflowStore.getWorkflow(requestedWorkflowId);
|
|
165388
166035
|
if (!workflow || workflow.workspaceId !== workspace.id) {
|
|
165389
|
-
return
|
|
166036
|
+
return text2({ error: "Workflow was not found for this Knowledge Workspace." }, true);
|
|
165390
166037
|
}
|
|
165391
166038
|
if (action === "workflow_preview" || action === "workflow_apply") {
|
|
165392
166039
|
const targetAgent = requireText(agent, "agent");
|
|
165393
|
-
if (!targetAgent) return
|
|
166040
|
+
if (!targetAgent) return text2({ error: "agent is required for a workflow adapter action." }, true);
|
|
165394
166041
|
const result = action === "workflow_preview" ? await previewWorkflowAdapter2({ workflow, projectRoot, agent: targetAgent }) : await applyWorkflowAdapter2({ workflow, projectRoot, agent: targetAgent });
|
|
165395
|
-
return
|
|
166042
|
+
return text2({
|
|
165396
166043
|
workflowId: workflow.id,
|
|
165397
166044
|
agent: targetAgent,
|
|
165398
166045
|
status: result.status,
|
|
@@ -165403,8 +166050,8 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165403
166050
|
}
|
|
165404
166051
|
if (action === "workflow_run") {
|
|
165405
166052
|
const runTask = requireText(task, "task");
|
|
165406
|
-
if (!runTask) return
|
|
165407
|
-
if (!outcome) return
|
|
166053
|
+
if (!runTask) return text2({ error: "task is required for workflow_run." }, true);
|
|
166054
|
+
if (!outcome) return text2({ error: "outcome is required for workflow_run." }, true);
|
|
165408
166055
|
const result = await recordWorkflowRun2({
|
|
165409
166056
|
workspace,
|
|
165410
166057
|
run: {
|
|
@@ -165418,14 +166065,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165418
166065
|
selectedEvidence: [...new Set((evidenceIds ?? []).map((item) => item.trim()).filter(Boolean))]
|
|
165419
166066
|
}
|
|
165420
166067
|
});
|
|
165421
|
-
return
|
|
166068
|
+
return text2({
|
|
165422
166069
|
id: result.id,
|
|
165423
166070
|
workflowId: result.workflowId,
|
|
165424
166071
|
outcome: result.outcome,
|
|
165425
166072
|
verificationVerdict: result.verificationVerdict
|
|
165426
166073
|
});
|
|
165427
166074
|
}
|
|
165428
|
-
return
|
|
166075
|
+
return text2({ error: "Unsupported knowledge action." }, true);
|
|
165429
166076
|
}
|
|
165430
166077
|
);
|
|
165431
166078
|
server.registerTool(
|
|
@@ -166900,10 +167547,10 @@ Ensure the path points to a directory containing a .git folder (or a subdirector
|
|
|
166900
167547
|
];
|
|
166901
167548
|
const allSkills = await loadMiniSkills2(projectDir2, project.id);
|
|
166902
167549
|
const miniSkills = allSkills.filter((s2) => {
|
|
166903
|
-
const
|
|
167550
|
+
const text2 = `${s2.title}
|
|
166904
167551
|
${s2.sourceEntity}
|
|
166905
167552
|
${s2.instruction}`.toLowerCase();
|
|
166906
|
-
return !SKILL_NOISE.some((p) => p.test(
|
|
167553
|
+
return !SKILL_NOISE.some((p) => p.test(text2));
|
|
166907
167554
|
});
|
|
166908
167555
|
if (miniSkills.length > 0) {
|
|
166909
167556
|
const formatted = formatMiniSkillsForInjection2(miniSkills);
|