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/index.js
CHANGED
|
@@ -312,7 +312,7 @@ function closeAllDatabases() {
|
|
|
312
312
|
_dbCache.delete(key);
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
|
-
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;
|
|
315
|
+
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;
|
|
316
316
|
var init_sqlite_db = __esm({
|
|
317
317
|
"src/store/sqlite-db.ts"() {
|
|
318
318
|
"use strict";
|
|
@@ -578,6 +578,17 @@ CREATE TABLE IF NOT EXISTS observation_code_refs (
|
|
|
578
578
|
" UNIQUE(projectId, sourceEpoch)",
|
|
579
579
|
");"
|
|
580
580
|
].join("\n");
|
|
581
|
+
CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE = [
|
|
582
|
+
"CREATE TABLE IF NOT EXISTS code_state_snapshot_files (",
|
|
583
|
+
" snapshotId TEXT NOT NULL,",
|
|
584
|
+
" projectId TEXT NOT NULL,",
|
|
585
|
+
" fileId TEXT NOT NULL,",
|
|
586
|
+
" path TEXT NOT NULL,",
|
|
587
|
+
" contentHash TEXT NOT NULL,",
|
|
588
|
+
" PRIMARY KEY (snapshotId, path),",
|
|
589
|
+
" FOREIGN KEY (snapshotId) REFERENCES code_state_snapshots(id) ON DELETE CASCADE",
|
|
590
|
+
");"
|
|
591
|
+
].join("\n");
|
|
581
592
|
CREATE_KNOWLEDGE_CLAIMS_TABLE = `
|
|
582
593
|
CREATE TABLE IF NOT EXISTS knowledge_claims (
|
|
583
594
|
id TEXT PRIMARY KEY,
|
|
@@ -788,6 +799,19 @@ CREATE TABLE IF NOT EXISTS long_term_memory_events (
|
|
|
788
799
|
createdAt TEXT NOT NULL,
|
|
789
800
|
FOREIGN KEY (memoryId) REFERENCES long_term_memories(id) ON DELETE CASCADE
|
|
790
801
|
);
|
|
802
|
+
`;
|
|
803
|
+
CREATE_MEMORY_OUTCOME_SIGNALS_TABLE = `
|
|
804
|
+
CREATE TABLE IF NOT EXISTS memory_outcome_signals (
|
|
805
|
+
id TEXT PRIMARY KEY,
|
|
806
|
+
projectId TEXT NOT NULL,
|
|
807
|
+
candidateKind TEXT NOT NULL,
|
|
808
|
+
candidateId TEXT NOT NULL,
|
|
809
|
+
kind TEXT NOT NULL,
|
|
810
|
+
sourceRef TEXT NOT NULL,
|
|
811
|
+
snapshotId TEXT,
|
|
812
|
+
detail TEXT,
|
|
813
|
+
observedAt TEXT NOT NULL
|
|
814
|
+
);
|
|
791
815
|
`;
|
|
792
816
|
CREATE_MEDIA_ASSETS_TABLE = `
|
|
793
817
|
CREATE TABLE IF NOT EXISTS media_assets (
|
|
@@ -1030,6 +1054,20 @@ CREATE UNIQUE INDEX IF NOT EXISTS idx_maintenance_jobs_active_dedupe
|
|
|
1030
1054
|
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_edges_snapshot ON code_edges(projectId, snapshotId)");
|
|
1031
1055
|
}
|
|
1032
1056
|
},
|
|
1057
|
+
{
|
|
1058
|
+
id: "1.4-codegraph-snapshot-manifest",
|
|
1059
|
+
apply: (db2) => {
|
|
1060
|
+
db2.exec(CREATE_CODE_STATE_SNAPSHOT_FILES_TABLE);
|
|
1061
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_code_snapshot_files_project_path ON code_state_snapshot_files(projectId, path)");
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
{
|
|
1065
|
+
id: "1.4-memory-outcome-signals",
|
|
1066
|
+
apply: (db2) => {
|
|
1067
|
+
db2.exec(CREATE_MEMORY_OUTCOME_SIGNALS_TABLE);
|
|
1068
|
+
db2.exec("CREATE INDEX IF NOT EXISTS idx_memory_outcomes_candidate ON memory_outcome_signals(projectId, candidateKind, candidateId, observedAt DESC)");
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1033
1071
|
{
|
|
1034
1072
|
id: "1.2-knowledge-claim-ledger",
|
|
1035
1073
|
apply: (db2) => {
|
|
@@ -2224,17 +2262,17 @@ var init_mini_skill_store = __esm({
|
|
|
2224
2262
|
|
|
2225
2263
|
// src/compact/token-budget.ts
|
|
2226
2264
|
import { countTokens, isWithinTokenLimit } from "gpt-tokenizer";
|
|
2227
|
-
function countTextTokens(
|
|
2228
|
-
return countTokens(
|
|
2265
|
+
function countTextTokens(text2) {
|
|
2266
|
+
return countTokens(text2);
|
|
2229
2267
|
}
|
|
2230
|
-
function fitsInBudget(
|
|
2231
|
-
return isWithinTokenLimit(
|
|
2268
|
+
function fitsInBudget(text2, limit2) {
|
|
2269
|
+
return isWithinTokenLimit(text2, limit2);
|
|
2232
2270
|
}
|
|
2233
|
-
function truncateToTokenBudget(
|
|
2234
|
-
if (fitsInBudget(
|
|
2235
|
-
return
|
|
2271
|
+
function truncateToTokenBudget(text2, budget) {
|
|
2272
|
+
if (fitsInBudget(text2, budget) !== false) {
|
|
2273
|
+
return text2;
|
|
2236
2274
|
}
|
|
2237
|
-
const sentences =
|
|
2275
|
+
const sentences = text2.split(/(?<=[.!?])\s+/);
|
|
2238
2276
|
let result = "";
|
|
2239
2277
|
for (const sentence of sentences) {
|
|
2240
2278
|
const candidate = result ? `${result} ${sentence}` : sentence;
|
|
@@ -2245,12 +2283,12 @@ function truncateToTokenBudget(text, budget) {
|
|
|
2245
2283
|
}
|
|
2246
2284
|
if (!result) {
|
|
2247
2285
|
const estimatedChars = budget * 2;
|
|
2248
|
-
result =
|
|
2286
|
+
result = text2.slice(0, estimatedChars);
|
|
2249
2287
|
while (fitsInBudget(result, budget) === false && result.length > 0) {
|
|
2250
2288
|
result = result.slice(0, Math.floor(result.length * 0.9));
|
|
2251
2289
|
}
|
|
2252
|
-
if (result.length <
|
|
2253
|
-
const nextCharacter =
|
|
2290
|
+
if (result.length < text2.length) {
|
|
2291
|
+
const nextCharacter = text2.charAt(result.length);
|
|
2254
2292
|
if (nextCharacter && !/[\s.,;:!?)}\]]/.test(nextCharacter)) {
|
|
2255
2293
|
const boundary = result.search(/\s+\S*$/);
|
|
2256
2294
|
result = boundary > 0 ? result.slice(0, boundary).trimEnd() : "";
|
|
@@ -3434,8 +3472,8 @@ import { createHash } from "crypto";
|
|
|
3434
3472
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
3435
3473
|
import { join as join2 } from "path";
|
|
3436
3474
|
import { homedir as homedir6 } from "os";
|
|
3437
|
-
function textHash(
|
|
3438
|
-
return createHash("sha256").update(
|
|
3475
|
+
function textHash(text2) {
|
|
3476
|
+
return createHash("sha256").update(text2).digest("hex").slice(0, 16);
|
|
3439
3477
|
}
|
|
3440
3478
|
async function loadDiskCache() {
|
|
3441
3479
|
try {
|
|
@@ -3498,11 +3536,11 @@ var init_fastembed_provider = __esm({
|
|
|
3498
3536
|
async embedInputs(inputs, options = {}) {
|
|
3499
3537
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3500
3538
|
}
|
|
3501
|
-
async embed(
|
|
3502
|
-
const hash4 = textHash(
|
|
3539
|
+
async embed(text2) {
|
|
3540
|
+
const hash4 = textHash(text2);
|
|
3503
3541
|
const cached = cache.get(hash4);
|
|
3504
3542
|
if (cached) return cached;
|
|
3505
|
-
const raw = await this.model.queryEmbed(
|
|
3543
|
+
const raw = await this.model.queryEmbed(text2);
|
|
3506
3544
|
const result = Array.from(raw);
|
|
3507
3545
|
if (result.length !== this.dimensions) {
|
|
3508
3546
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
@@ -3598,10 +3636,10 @@ var init_transformers_provider = __esm({
|
|
|
3598
3636
|
async embedInputs(inputs, options = {}) {
|
|
3599
3637
|
return Promise.all(inputs.map((input) => this.embedInput(input, options)));
|
|
3600
3638
|
}
|
|
3601
|
-
async embed(
|
|
3602
|
-
const cached = cache2.get(
|
|
3639
|
+
async embed(text2) {
|
|
3640
|
+
const cached = cache2.get(text2);
|
|
3603
3641
|
if (cached) return cached;
|
|
3604
|
-
const output = await this.extractor(
|
|
3642
|
+
const output = await this.extractor(text2, {
|
|
3605
3643
|
pooling: "mean",
|
|
3606
3644
|
normalize: true
|
|
3607
3645
|
});
|
|
@@ -3609,7 +3647,7 @@ var init_transformers_provider = __esm({
|
|
|
3609
3647
|
if (result.length !== this.dimensions) {
|
|
3610
3648
|
throw new Error(`Expected ${this.dimensions}d embedding, got ${result.length}d`);
|
|
3611
3649
|
}
|
|
3612
|
-
this.cacheSet(
|
|
3650
|
+
this.cacheSet(text2, result);
|
|
3613
3651
|
return result;
|
|
3614
3652
|
}
|
|
3615
3653
|
async embedBatch(texts) {
|
|
@@ -3672,8 +3710,8 @@ function dimsCacheFile() {
|
|
|
3672
3710
|
function cacheMetaFile() {
|
|
3673
3711
|
return join3(cacheDir(), ".embedding-api-cache-meta.json");
|
|
3674
3712
|
}
|
|
3675
|
-
function normalizeText(
|
|
3676
|
-
return
|
|
3713
|
+
function normalizeText(text2) {
|
|
3714
|
+
return text2.replace(/\s+/g, " ").trim().slice(0, MAX_INPUT_CHARS);
|
|
3677
3715
|
}
|
|
3678
3716
|
function cacheNamespace(config) {
|
|
3679
3717
|
return [
|
|
@@ -3683,8 +3721,8 @@ function cacheNamespace(config) {
|
|
|
3683
3721
|
config.requestedDimensions ?? "native"
|
|
3684
3722
|
].join("|");
|
|
3685
3723
|
}
|
|
3686
|
-
function textHash2(
|
|
3687
|
-
return createHash2("sha256").update(`${namespace}\0${
|
|
3724
|
+
function textHash2(text2, namespace) {
|
|
3725
|
+
return createHash2("sha256").update(`${namespace}\0${text2}`).digest("hex").slice(0, 16);
|
|
3688
3726
|
}
|
|
3689
3727
|
function inputIdentity(input, options = {}) {
|
|
3690
3728
|
return JSON.stringify({
|
|
@@ -4096,8 +4134,8 @@ var init_api_provider = __esm({
|
|
|
4096
4134
|
if (!embedding) throw new Error("API probe returned no embeddings; check model name and API key");
|
|
4097
4135
|
return embedding.length;
|
|
4098
4136
|
}
|
|
4099
|
-
async embed(
|
|
4100
|
-
const normalized = normalizeText(
|
|
4137
|
+
async embed(text2, options) {
|
|
4138
|
+
const normalized = normalizeText(text2);
|
|
4101
4139
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
4102
4140
|
return this.embedInput({ modality: "text", text: normalized }, { intent: "document", ...options });
|
|
4103
4141
|
}
|
|
@@ -4154,7 +4192,7 @@ var init_api_provider = __esm({
|
|
|
4154
4192
|
}
|
|
4155
4193
|
async embedBatch(texts, options) {
|
|
4156
4194
|
if (isNativeGeminiEndpoint(this.config.baseUrl)) {
|
|
4157
|
-
return Promise.all(texts.map((
|
|
4195
|
+
return Promise.all(texts.map((text2) => this.embedInput({ modality: "text", text: text2 }, { intent: "document", ...options })));
|
|
4158
4196
|
}
|
|
4159
4197
|
await ensureDiskCacheLoaded();
|
|
4160
4198
|
const normalizedTexts = texts.map(normalizeText);
|
|
@@ -4233,8 +4271,8 @@ var init_api_provider = __esm({
|
|
|
4233
4271
|
}
|
|
4234
4272
|
async getCachedEmbeddings(texts) {
|
|
4235
4273
|
await ensureDiskCacheLoaded();
|
|
4236
|
-
return texts.map((
|
|
4237
|
-
const hash4 = textHash2(normalizeText(
|
|
4274
|
+
return texts.map((text2) => {
|
|
4275
|
+
const hash4 = textHash2(normalizeText(text2), this.cacheKeyNamespace);
|
|
4238
4276
|
return cache3.get(hash4) ?? null;
|
|
4239
4277
|
});
|
|
4240
4278
|
}
|
|
@@ -4464,9 +4502,9 @@ function wrapProvider(candidate) {
|
|
|
4464
4502
|
return {
|
|
4465
4503
|
name: candidate.name,
|
|
4466
4504
|
dimensions: candidate.dimensions,
|
|
4467
|
-
async embed(
|
|
4505
|
+
async embed(text2, options) {
|
|
4468
4506
|
try {
|
|
4469
|
-
return await candidate.embed(
|
|
4507
|
+
return await candidate.embed(text2, options);
|
|
4470
4508
|
} catch (error) {
|
|
4471
4509
|
if (kind === "api" && getEmbeddingMode2() === "auto" && isTemporaryEmbeddingFailure(error)) {
|
|
4472
4510
|
warnOnce("[memorix] API embedding temporarily unavailable \u2014 switching to local fallback provider");
|
|
@@ -4474,7 +4512,7 @@ function wrapProvider(candidate) {
|
|
|
4474
4512
|
if (fallback) {
|
|
4475
4513
|
provider = wrapProvider(fallback);
|
|
4476
4514
|
warnOnce(`[memorix] Embedding fallback activated: ${provider.name} (${provider.dimensions}d)`);
|
|
4477
|
-
return provider.embed(
|
|
4515
|
+
return provider.embed(text2, options);
|
|
4478
4516
|
}
|
|
4479
4517
|
}
|
|
4480
4518
|
if (isTemporaryEmbeddingFailure(error)) {
|
|
@@ -5033,8 +5071,8 @@ async function readResponseText(response, signal, maxBytes = MAX_LLM_RESPONSE_BY
|
|
|
5033
5071
|
}
|
|
5034
5072
|
}
|
|
5035
5073
|
async function readResponseJson(response, signal, maxBytes = MAX_LLM_RESPONSE_BYTES) {
|
|
5036
|
-
const
|
|
5037
|
-
return JSON.parse(
|
|
5074
|
+
const text2 = await readResponseText(response, signal, maxBytes);
|
|
5075
|
+
return JSON.parse(text2);
|
|
5038
5076
|
}
|
|
5039
5077
|
async function* callLLMWithToolsStream(messages, tools) {
|
|
5040
5078
|
if (!currentConfig) {
|
|
@@ -5587,8 +5625,8 @@ function isCjkHeavy(query) {
|
|
|
5587
5625
|
const cjkCount = (query.match(CJK_PATTERN) || []).length;
|
|
5588
5626
|
return query.length > 0 && cjkCount / query.length > 0.3;
|
|
5589
5627
|
}
|
|
5590
|
-
function normalizeExpansion(
|
|
5591
|
-
return
|
|
5628
|
+
function normalizeExpansion(text2) {
|
|
5629
|
+
return text2.trim().replace(/^[-*]\s*/, "").replace(/^["'`]+|["'`]+$/g, "").split(/\r?\n/)[0].trim();
|
|
5592
5630
|
}
|
|
5593
5631
|
async function maybeExpandSearchQuery(query) {
|
|
5594
5632
|
if (!query || !isCjkHeavy(query) || COMMAND_LIKE_QUERY.test(query)) {
|
|
@@ -5951,9 +5989,9 @@ function shouldSkipCompression(narrative, type) {
|
|
|
5951
5989
|
if (specialChars / narrative.length > 0.35) return true;
|
|
5952
5990
|
return false;
|
|
5953
5991
|
}
|
|
5954
|
-
function estimateTokens(
|
|
5955
|
-
const cjkChars = (
|
|
5956
|
-
const otherChars =
|
|
5992
|
+
function estimateTokens(text2) {
|
|
5993
|
+
const cjkChars = (text2.match(/[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff\uac00-\ud7af]/g) || []).length;
|
|
5994
|
+
const otherChars = text2.length - cjkChars;
|
|
5957
5995
|
return Math.ceil(cjkChars / 1.5 + otherChars / 4);
|
|
5958
5996
|
}
|
|
5959
5997
|
var COMPRESS_PROMPT, COMPRESS_PROMPT_GENTLE, RERANK_PROMPT, SKIP_PATTERNS, LOW_COMPRESSION_TYPES;
|
|
@@ -6256,10 +6294,10 @@ function isEmbeddingEnabled() {
|
|
|
6256
6294
|
function getVectorDimensions() {
|
|
6257
6295
|
return embeddingEnabled ? embeddingDimensions : null;
|
|
6258
6296
|
}
|
|
6259
|
-
async function generateEmbedding(
|
|
6297
|
+
async function generateEmbedding(text2) {
|
|
6260
6298
|
const provider2 = await getEmbeddingProvider();
|
|
6261
6299
|
if (!provider2) return null;
|
|
6262
|
-
return provider2.embedInput ? provider2.embedInput({ modality: "text", text }, { intent: "document" }) : provider2.embed(
|
|
6300
|
+
return provider2.embedInput ? provider2.embedInput({ modality: "text", text: text2 }, { intent: "document" }) : provider2.embed(text2);
|
|
6263
6301
|
}
|
|
6264
6302
|
async function generateEmbeddingInput(input, options = {}) {
|
|
6265
6303
|
const provider2 = await getEmbeddingProvider();
|
|
@@ -7591,9 +7629,9 @@ var init_entity_extractor = __esm({
|
|
|
7591
7629
|
});
|
|
7592
7630
|
|
|
7593
7631
|
// src/memory/secret-filter.ts
|
|
7594
|
-
function applyRedaction(
|
|
7595
|
-
if (!
|
|
7596
|
-
let out =
|
|
7632
|
+
function applyRedaction(text2) {
|
|
7633
|
+
if (!text2) return text2;
|
|
7634
|
+
let out = text2;
|
|
7597
7635
|
out = out.replace(
|
|
7598
7636
|
/((?:password|passwd|pwd|secret|token|api[_-]?key|auth[_-]?key|access[_-]?key|private[_-]?key|client[_-]?secret)\s*[:=]\s*["']?)([^\s"',;\n]{6,})/gi,
|
|
7599
7637
|
"$1[REDACTED]"
|
|
@@ -7607,11 +7645,11 @@ function applyRedaction(text) {
|
|
|
7607
7645
|
out = out.replace(/\beyJ[A-Za-z0-9._-]{40,}\b/g, "[REDACTED]");
|
|
7608
7646
|
return out;
|
|
7609
7647
|
}
|
|
7610
|
-
function sanitizeCredentials(
|
|
7611
|
-
return applyRedaction(
|
|
7648
|
+
function sanitizeCredentials(text2) {
|
|
7649
|
+
return applyRedaction(text2);
|
|
7612
7650
|
}
|
|
7613
|
-
function redactCredentials(
|
|
7614
|
-
return applyRedaction(
|
|
7651
|
+
function redactCredentials(text2) {
|
|
7652
|
+
return applyRedaction(text2);
|
|
7615
7653
|
}
|
|
7616
7654
|
var init_secret_filter = __esm({
|
|
7617
7655
|
"src/memory/secret-filter.ts"() {
|
|
@@ -7662,8 +7700,8 @@ function clampPositiveInteger(value, fallback) {
|
|
|
7662
7700
|
return Math.max(1, Math.floor(value));
|
|
7663
7701
|
}
|
|
7664
7702
|
function errorText(error) {
|
|
7665
|
-
const
|
|
7666
|
-
return sanitizeCredentials(
|
|
7703
|
+
const text2 = error instanceof Error ? error.message : String(error);
|
|
7704
|
+
return sanitizeCredentials(text2).slice(0, MAX_ERROR_LENGTH);
|
|
7667
7705
|
}
|
|
7668
7706
|
function normalizedKinds(kinds) {
|
|
7669
7707
|
if (!kinds) return void 0;
|
|
@@ -8757,9 +8795,9 @@ __export(consolidation_exports, {
|
|
|
8757
8795
|
executeConsolidation: () => executeConsolidation,
|
|
8758
8796
|
findConsolidationCandidates: () => findConsolidationCandidates
|
|
8759
8797
|
});
|
|
8760
|
-
function tokenize(
|
|
8798
|
+
function tokenize(text2) {
|
|
8761
8799
|
return new Set(
|
|
8762
|
-
|
|
8800
|
+
text2.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff\s-]/g, " ").split(/\s+/).filter((t2) => t2.length > 1)
|
|
8763
8801
|
);
|
|
8764
8802
|
}
|
|
8765
8803
|
function jaccardSimilarity(a, b) {
|
|
@@ -17911,8 +17949,8 @@ var init_headers = __esm({
|
|
|
17911
17949
|
});
|
|
17912
17950
|
|
|
17913
17951
|
// packages/ai/dist/utils/sanitize-unicode.js
|
|
17914
|
-
function sanitizeSurrogates(
|
|
17915
|
-
return
|
|
17952
|
+
function sanitizeSurrogates(text2) {
|
|
17953
|
+
return text2.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
|
|
17916
17954
|
}
|
|
17917
17955
|
var init_sanitize_unicode = __esm({
|
|
17918
17956
|
"packages/ai/dist/utils/sanitize-unicode.js"() {
|
|
@@ -18394,9 +18432,9 @@ var init_values = __esm({
|
|
|
18394
18432
|
}
|
|
18395
18433
|
return n;
|
|
18396
18434
|
};
|
|
18397
|
-
safeJSON = (
|
|
18435
|
+
safeJSON = (text2) => {
|
|
18398
18436
|
try {
|
|
18399
|
-
return JSON.parse(
|
|
18437
|
+
return JSON.parse(text2);
|
|
18400
18438
|
} catch (err) {
|
|
18401
18439
|
return void 0;
|
|
18402
18440
|
}
|
|
@@ -19559,8 +19597,8 @@ async function defaultParseResponse(client, props) {
|
|
|
19559
19597
|
const json2 = await response.json();
|
|
19560
19598
|
return addRequestID(json2, response);
|
|
19561
19599
|
}
|
|
19562
|
-
const
|
|
19563
|
-
return
|
|
19600
|
+
const text2 = await response.text();
|
|
19601
|
+
return text2;
|
|
19564
19602
|
})();
|
|
19565
19603
|
loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
|
|
19566
19604
|
retryOfRequestLogID,
|
|
@@ -32930,7 +32968,7 @@ var init_models_generated = __esm({
|
|
|
32930
32968
|
provider: "minimax",
|
|
32931
32969
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
32932
32970
|
reasoning: true,
|
|
32933
|
-
input: ["text", "image"],
|
|
32971
|
+
input: ["text", "image", "video"],
|
|
32934
32972
|
cost: {
|
|
32935
32973
|
input: 0.3,
|
|
32936
32974
|
output: 1.2,
|
|
@@ -32983,7 +33021,7 @@ var init_models_generated = __esm({
|
|
|
32983
33021
|
provider: "minimax-cn",
|
|
32984
33022
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
32985
33023
|
reasoning: true,
|
|
32986
|
-
input: ["text", "image"],
|
|
33024
|
+
input: ["text", "image", "video"],
|
|
32987
33025
|
cost: {
|
|
32988
33026
|
input: 0.3,
|
|
32989
33027
|
output: 1.2,
|
|
@@ -45178,9 +45216,9 @@ var init_values2 = __esm({
|
|
|
45178
45216
|
}
|
|
45179
45217
|
return n;
|
|
45180
45218
|
};
|
|
45181
|
-
safeJSON2 = (
|
|
45219
|
+
safeJSON2 = (text2) => {
|
|
45182
45220
|
try {
|
|
45183
|
-
return JSON.parse(
|
|
45221
|
+
return JSON.parse(text2);
|
|
45184
45222
|
} catch (err) {
|
|
45185
45223
|
return void 0;
|
|
45186
45224
|
}
|
|
@@ -45954,8 +45992,8 @@ async function defaultParseResponse2(client, props) {
|
|
|
45954
45992
|
const json2 = await response.json();
|
|
45955
45993
|
return addRequestID2(json2, response);
|
|
45956
45994
|
}
|
|
45957
|
-
const
|
|
45958
|
-
return
|
|
45995
|
+
const text2 = await response.text();
|
|
45996
|
+
return text2;
|
|
45959
45997
|
})();
|
|
45960
45998
|
loggerFor2(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails2({
|
|
45961
45999
|
retryOfRequestLogID,
|
|
@@ -52258,11 +52296,11 @@ var init_simple_options = __esm({
|
|
|
52258
52296
|
});
|
|
52259
52297
|
|
|
52260
52298
|
// packages/ai/dist/providers/transform-messages.js
|
|
52261
|
-
function
|
|
52299
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52262
52300
|
const result = [];
|
|
52263
52301
|
let previousWasPlaceholder = false;
|
|
52264
52302
|
for (const block of content) {
|
|
52265
|
-
if (block.type ===
|
|
52303
|
+
if (block.type === dropType) {
|
|
52266
52304
|
if (!previousWasPlaceholder) {
|
|
52267
52305
|
result.push({ type: "text", text: placeholder });
|
|
52268
52306
|
}
|
|
@@ -52270,33 +52308,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52270
52308
|
continue;
|
|
52271
52309
|
}
|
|
52272
52310
|
result.push(block);
|
|
52273
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52311
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52274
52312
|
}
|
|
52275
52313
|
return result;
|
|
52276
52314
|
}
|
|
52277
|
-
function
|
|
52278
|
-
|
|
52315
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52316
|
+
const supportsImage = model.input.includes("image");
|
|
52317
|
+
const supportsVideo = model.input.includes("video");
|
|
52318
|
+
if (supportsImage && supportsVideo) {
|
|
52279
52319
|
return messages;
|
|
52280
52320
|
}
|
|
52281
52321
|
return messages.map((msg) => {
|
|
52282
52322
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52283
|
-
|
|
52284
|
-
|
|
52285
|
-
content
|
|
52286
|
-
|
|
52323
|
+
let content = msg.content;
|
|
52324
|
+
if (!supportsImage)
|
|
52325
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52326
|
+
if (!supportsVideo)
|
|
52327
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52328
|
+
return { ...msg, content };
|
|
52287
52329
|
}
|
|
52288
52330
|
if (msg.role === "toolResult") {
|
|
52289
|
-
|
|
52290
|
-
|
|
52291
|
-
content
|
|
52292
|
-
|
|
52331
|
+
let content = msg.content;
|
|
52332
|
+
if (!supportsImage)
|
|
52333
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52334
|
+
if (!supportsVideo)
|
|
52335
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52336
|
+
return { ...msg, content };
|
|
52293
52337
|
}
|
|
52294
52338
|
return msg;
|
|
52295
52339
|
});
|
|
52296
52340
|
}
|
|
52297
52341
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52298
52342
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52299
|
-
const imageAwareMessages =
|
|
52343
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52300
52344
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52301
52345
|
if (msg.role === "user") {
|
|
52302
52346
|
return msg;
|
|
@@ -52408,13 +52452,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52408
52452
|
insertSyntheticToolResults();
|
|
52409
52453
|
return result;
|
|
52410
52454
|
}
|
|
52411
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52455
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52412
52456
|
var init_transform_messages = __esm({
|
|
52413
52457
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52414
52458
|
"use strict";
|
|
52415
52459
|
init_esm_shims();
|
|
52416
52460
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52417
52461
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52462
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52463
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52418
52464
|
}
|
|
52419
52465
|
});
|
|
52420
52466
|
|
|
@@ -52445,8 +52491,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52445
52491
|
};
|
|
52446
52492
|
}
|
|
52447
52493
|
function convertContentBlocks(content) {
|
|
52448
|
-
const
|
|
52449
|
-
if (!
|
|
52494
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52495
|
+
if (!hasMedia) {
|
|
52450
52496
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52451
52497
|
}
|
|
52452
52498
|
const blocks = content.map((block) => {
|
|
@@ -52456,6 +52502,16 @@ function convertContentBlocks(content) {
|
|
|
52456
52502
|
text: sanitizeSurrogates(block.text)
|
|
52457
52503
|
};
|
|
52458
52504
|
}
|
|
52505
|
+
if (block.type === "video") {
|
|
52506
|
+
return {
|
|
52507
|
+
type: "video",
|
|
52508
|
+
source: {
|
|
52509
|
+
type: "base64",
|
|
52510
|
+
media_type: block.mimeType,
|
|
52511
|
+
data: block.data
|
|
52512
|
+
}
|
|
52513
|
+
};
|
|
52514
|
+
}
|
|
52459
52515
|
return {
|
|
52460
52516
|
type: "image",
|
|
52461
52517
|
source: {
|
|
@@ -52469,7 +52525,7 @@ function convertContentBlocks(content) {
|
|
|
52469
52525
|
if (!hasText) {
|
|
52470
52526
|
blocks.unshift({
|
|
52471
52527
|
type: "text",
|
|
52472
|
-
text: "(see attached
|
|
52528
|
+
text: "(see attached media)"
|
|
52473
52529
|
});
|
|
52474
52530
|
}
|
|
52475
52531
|
return blocks;
|
|
@@ -52530,9 +52586,9 @@ function decodeSseLine(line, state) {
|
|
|
52530
52586
|
}
|
|
52531
52587
|
return null;
|
|
52532
52588
|
}
|
|
52533
|
-
function nextLineBreakIndex(
|
|
52534
|
-
const carriageReturnIndex =
|
|
52535
|
-
const newlineIndex =
|
|
52589
|
+
function nextLineBreakIndex(text2) {
|
|
52590
|
+
const carriageReturnIndex = text2.indexOf("\r");
|
|
52591
|
+
const newlineIndex = text2.indexOf("\n");
|
|
52536
52592
|
if (carriageReturnIndex === -1) {
|
|
52537
52593
|
return newlineIndex;
|
|
52538
52594
|
}
|
|
@@ -52541,18 +52597,18 @@ function nextLineBreakIndex(text) {
|
|
|
52541
52597
|
}
|
|
52542
52598
|
return Math.min(carriageReturnIndex, newlineIndex);
|
|
52543
52599
|
}
|
|
52544
|
-
function consumeLine(
|
|
52545
|
-
const lineBreakIndex = nextLineBreakIndex(
|
|
52600
|
+
function consumeLine(text2) {
|
|
52601
|
+
const lineBreakIndex = nextLineBreakIndex(text2);
|
|
52546
52602
|
if (lineBreakIndex === -1) {
|
|
52547
52603
|
return null;
|
|
52548
52604
|
}
|
|
52549
52605
|
let nextIndex = lineBreakIndex + 1;
|
|
52550
|
-
if (
|
|
52606
|
+
if (text2[lineBreakIndex] === "\r" && text2[nextIndex] === "\n") {
|
|
52551
52607
|
nextIndex += 1;
|
|
52552
52608
|
}
|
|
52553
52609
|
return {
|
|
52554
|
-
line:
|
|
52555
|
-
rest:
|
|
52610
|
+
line: text2.slice(0, lineBreakIndex),
|
|
52611
|
+
rest: text2.slice(nextIndex)
|
|
52556
52612
|
};
|
|
52557
52613
|
}
|
|
52558
52614
|
async function* iterateSseMessages(body, signal) {
|
|
@@ -52819,6 +52875,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52819
52875
|
type: "text",
|
|
52820
52876
|
text: sanitizeSurrogates(item.text)
|
|
52821
52877
|
};
|
|
52878
|
+
} else if (item.type === "video") {
|
|
52879
|
+
return {
|
|
52880
|
+
type: "video",
|
|
52881
|
+
source: {
|
|
52882
|
+
type: "base64",
|
|
52883
|
+
media_type: item.mimeType,
|
|
52884
|
+
data: item.data
|
|
52885
|
+
}
|
|
52886
|
+
};
|
|
52822
52887
|
} else {
|
|
52823
52888
|
return {
|
|
52824
52889
|
type: "image",
|
|
@@ -52899,6 +52964,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52899
52964
|
toolResults.push({
|
|
52900
52965
|
type: "tool_result",
|
|
52901
52966
|
tool_use_id: msg.toolCallId,
|
|
52967
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
52968
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
52902
52969
|
content: convertContentBlocks(msg.content),
|
|
52903
52970
|
is_error: msg.isError
|
|
52904
52971
|
});
|
|
@@ -52925,7 +52992,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52925
52992
|
if (lastMessage.role === "user") {
|
|
52926
52993
|
if (Array.isArray(lastMessage.content)) {
|
|
52927
52994
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
52928
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
52995
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
52929
52996
|
lastBlock.cache_control = cacheControl;
|
|
52930
52997
|
}
|
|
52931
52998
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -54708,8 +54775,8 @@ var require_common = __commonJS({
|
|
|
54708
54775
|
}
|
|
54709
54776
|
function redactString(obj, key) {
|
|
54710
54777
|
if (typeof obj === "object" && obj !== null && typeof obj[key] === "string") {
|
|
54711
|
-
const
|
|
54712
|
-
if (/grant_type=/i.test(
|
|
54778
|
+
const text2 = obj[key];
|
|
54779
|
+
if (/grant_type=/i.test(text2) || /assertion=/i.test(text2) || /secret/i.test(text2)) {
|
|
54713
54780
|
obj[key] = REDACT;
|
|
54714
54781
|
}
|
|
54715
54782
|
}
|
|
@@ -61537,8 +61604,8 @@ var init_body = __esm({
|
|
|
61537
61604
|
* @return Promise
|
|
61538
61605
|
*/
|
|
61539
61606
|
async json() {
|
|
61540
|
-
const
|
|
61541
|
-
return JSON.parse(
|
|
61607
|
+
const text2 = await this.text();
|
|
61608
|
+
return JSON.parse(text2);
|
|
61542
61609
|
}
|
|
61543
61610
|
/**
|
|
61544
61611
|
* Decode response as text
|
|
@@ -62690,7 +62757,7 @@ var require_gaxios = __commonJS({
|
|
|
62690
62757
|
var retry_js_1 = require_retry3();
|
|
62691
62758
|
var stream_1 = __require("stream");
|
|
62692
62759
|
var interceptor_js_1 = require_interceptor();
|
|
62693
|
-
var
|
|
62760
|
+
var randomUUID17 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
62694
62761
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
62695
62762
|
var Gaxios = class {
|
|
62696
62763
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -62963,7 +63030,7 @@ var require_gaxios = __commonJS({
|
|
|
62963
63030
|
*/
|
|
62964
63031
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
62965
63032
|
if (opts.multipart?.length) {
|
|
62966
|
-
const boundary = await
|
|
63033
|
+
const boundary = await randomUUID17();
|
|
62967
63034
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
62968
63035
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
62969
63036
|
} else if (shouldDirectlyPassData) {
|
|
@@ -64714,18 +64781,18 @@ var require_parse = __commonJS({
|
|
|
64714
64781
|
n: "\n",
|
|
64715
64782
|
r: "\r",
|
|
64716
64783
|
t: " "
|
|
64717
|
-
},
|
|
64784
|
+
}, text2, error = function(m2) {
|
|
64718
64785
|
throw {
|
|
64719
64786
|
name: "SyntaxError",
|
|
64720
64787
|
message: m2,
|
|
64721
64788
|
at,
|
|
64722
|
-
text
|
|
64789
|
+
text: text2
|
|
64723
64790
|
};
|
|
64724
64791
|
}, next = function(c) {
|
|
64725
64792
|
if (c && c !== ch) {
|
|
64726
64793
|
error("Expected '" + c + "' instead of '" + ch + "'");
|
|
64727
64794
|
}
|
|
64728
|
-
ch =
|
|
64795
|
+
ch = text2.charAt(at);
|
|
64729
64796
|
at += 1;
|
|
64730
64797
|
return ch;
|
|
64731
64798
|
}, number44 = function() {
|
|
@@ -64772,12 +64839,12 @@ var require_parse = __commonJS({
|
|
|
64772
64839
|
var startAt = at;
|
|
64773
64840
|
while (next()) {
|
|
64774
64841
|
if (ch === '"') {
|
|
64775
|
-
if (at - 1 > startAt) string474 +=
|
|
64842
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
64776
64843
|
next();
|
|
64777
64844
|
return string474;
|
|
64778
64845
|
}
|
|
64779
64846
|
if (ch === "\\") {
|
|
64780
|
-
if (at - 1 > startAt) string474 +=
|
|
64847
|
+
if (at - 1 > startAt) string474 += text2.substring(startAt, at - 1);
|
|
64781
64848
|
next();
|
|
64782
64849
|
if (ch === "u") {
|
|
64783
64850
|
uffff = 0;
|
|
@@ -64910,7 +64977,7 @@ var require_parse = __commonJS({
|
|
|
64910
64977
|
};
|
|
64911
64978
|
return function(source, reviver) {
|
|
64912
64979
|
var result;
|
|
64913
|
-
|
|
64980
|
+
text2 = source + "";
|
|
64914
64981
|
at = 0;
|
|
64915
64982
|
ch = " ";
|
|
64916
64983
|
result = value();
|
|
@@ -65822,8 +65889,8 @@ var require_crypto = __commonJS({
|
|
|
65822
65889
|
const result = new TextDecoder().decode(uint8array);
|
|
65823
65890
|
return result;
|
|
65824
65891
|
}
|
|
65825
|
-
encodeBase64StringUtf8(
|
|
65826
|
-
const uint8array = new TextEncoder().encode(
|
|
65892
|
+
encodeBase64StringUtf8(text2) {
|
|
65893
|
+
const uint8array = new TextEncoder().encode(text2);
|
|
65827
65894
|
const result = base64js.fromByteArray(uint8array);
|
|
65828
65895
|
return result;
|
|
65829
65896
|
}
|
|
@@ -65892,8 +65959,8 @@ var require_crypto2 = __commonJS({
|
|
|
65892
65959
|
decodeBase64StringUtf8(base64) {
|
|
65893
65960
|
return Buffer.from(base64, "base64").toString("utf-8");
|
|
65894
65961
|
}
|
|
65895
|
-
encodeBase64StringUtf8(
|
|
65896
|
-
return Buffer.from(
|
|
65962
|
+
encodeBase64StringUtf8(text2) {
|
|
65963
|
+
return Buffer.from(text2, "utf-8").toString("base64");
|
|
65897
65964
|
}
|
|
65898
65965
|
/**
|
|
65899
65966
|
* Computes the SHA-256 hash of the provided string.
|
|
@@ -86338,8 +86405,8 @@ async function defaultParseResponse3(client, props) {
|
|
|
86338
86405
|
const json2 = await response.json();
|
|
86339
86406
|
return json2;
|
|
86340
86407
|
}
|
|
86341
|
-
const
|
|
86342
|
-
return
|
|
86408
|
+
const text2 = await response.text();
|
|
86409
|
+
return text2;
|
|
86343
86410
|
})();
|
|
86344
86411
|
loggerFor3(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails3({
|
|
86345
86412
|
retryOfRequestLogID,
|
|
@@ -87916,7 +87983,7 @@ var init_node = __esm({
|
|
|
87916
87983
|
if (this.candidates && this.candidates.length > 1) {
|
|
87917
87984
|
console.warn("there are multiple candidates in the response, returning text from the first one.");
|
|
87918
87985
|
}
|
|
87919
|
-
let
|
|
87986
|
+
let text2 = "";
|
|
87920
87987
|
let anyTextPartText = false;
|
|
87921
87988
|
const nonTextParts = [];
|
|
87922
87989
|
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 : []) {
|
|
@@ -87930,13 +87997,13 @@ var init_node = __esm({
|
|
|
87930
87997
|
continue;
|
|
87931
87998
|
}
|
|
87932
87999
|
anyTextPartText = true;
|
|
87933
|
-
|
|
88000
|
+
text2 += part.text;
|
|
87934
88001
|
}
|
|
87935
88002
|
}
|
|
87936
88003
|
if (nonTextParts.length > 0) {
|
|
87937
88004
|
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.`);
|
|
87938
88005
|
}
|
|
87939
|
-
return anyTextPartText ?
|
|
88006
|
+
return anyTextPartText ? text2 : void 0;
|
|
87940
88007
|
}
|
|
87941
88008
|
/**
|
|
87942
88009
|
* Returns the concatenation of all inline data parts from the first candidate
|
|
@@ -88189,7 +88256,7 @@ var init_node = __esm({
|
|
|
88189
88256
|
*/
|
|
88190
88257
|
get text() {
|
|
88191
88258
|
var _a5, _b, _c;
|
|
88192
|
-
let
|
|
88259
|
+
let text2 = "";
|
|
88193
88260
|
let anyTextPartFound = false;
|
|
88194
88261
|
const nonTextParts = [];
|
|
88195
88262
|
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 : []) {
|
|
@@ -88203,13 +88270,13 @@ var init_node = __esm({
|
|
|
88203
88270
|
continue;
|
|
88204
88271
|
}
|
|
88205
88272
|
anyTextPartFound = true;
|
|
88206
|
-
|
|
88273
|
+
text2 += part.text;
|
|
88207
88274
|
}
|
|
88208
88275
|
}
|
|
88209
88276
|
if (nonTextParts.length > 0) {
|
|
88210
88277
|
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.`);
|
|
88211
88278
|
}
|
|
88212
|
-
return anyTextPartFound ?
|
|
88279
|
+
return anyTextPartFound ? text2 : void 0;
|
|
88213
88280
|
}
|
|
88214
88281
|
/**
|
|
88215
88282
|
* Returns the concatenation of all inline data parts from the server content if present.
|
|
@@ -92881,9 +92948,9 @@ var init_node = __esm({
|
|
|
92881
92948
|
}
|
|
92882
92949
|
return n;
|
|
92883
92950
|
};
|
|
92884
|
-
safeJSON3 = (
|
|
92951
|
+
safeJSON3 = (text2) => {
|
|
92885
92952
|
try {
|
|
92886
|
-
return JSON.parse(
|
|
92953
|
+
return JSON.parse(text2);
|
|
92887
92954
|
} catch (err) {
|
|
92888
92955
|
return void 0;
|
|
92889
92956
|
}
|
|
@@ -110746,8 +110813,8 @@ function findBoundary(buf) {
|
|
|
110746
110813
|
return null;
|
|
110747
110814
|
}
|
|
110748
110815
|
function parseMessage2(chunk, parse2, state, dataRequired) {
|
|
110749
|
-
const
|
|
110750
|
-
const lines =
|
|
110816
|
+
const text2 = new TextDecoder().decode(chunk);
|
|
110817
|
+
const lines = text2.split(/\r\n|\r|\n/);
|
|
110751
110818
|
const dataLines = [];
|
|
110752
110819
|
const ret = {};
|
|
110753
110820
|
let ignore = true;
|
|
@@ -133621,10 +133688,10 @@ function formatMistralError(error) {
|
|
|
133621
133688
|
}
|
|
133622
133689
|
return safeJsonStringify(error);
|
|
133623
133690
|
}
|
|
133624
|
-
function truncateErrorText(
|
|
133625
|
-
if (
|
|
133626
|
-
return
|
|
133627
|
-
return `${
|
|
133691
|
+
function truncateErrorText(text2, maxChars) {
|
|
133692
|
+
if (text2.length <= maxChars)
|
|
133693
|
+
return text2;
|
|
133694
|
+
return `${text2.slice(0, maxChars)}... [truncated ${text2.length - maxChars} chars]`;
|
|
133628
133695
|
}
|
|
133629
133696
|
function safeJsonStringify(value) {
|
|
133630
133697
|
try {
|
|
@@ -133744,7 +133811,7 @@ async function consumeChatStream(model, output, stream2, mistralStream) {
|
|
|
133744
133811
|
continue;
|
|
133745
133812
|
}
|
|
133746
133813
|
if (item.type === "thinking") {
|
|
133747
|
-
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((
|
|
133814
|
+
const deltaText = item.thinking.map((part) => "text" in part ? part.text : "").filter((text2) => text2.length > 0).join("");
|
|
133748
133815
|
const thinkingDelta = sanitizeSurrogates(deltaText);
|
|
133749
133816
|
if (!thinkingDelta)
|
|
133750
133817
|
continue;
|
|
@@ -133941,8 +134008,8 @@ function toChatMessages(messages, supportsImages) {
|
|
|
133941
134008
|
}
|
|
133942
134009
|
return result;
|
|
133943
134010
|
}
|
|
133944
|
-
function buildToolResultText(
|
|
133945
|
-
const trimmed =
|
|
134011
|
+
function buildToolResultText(text2, hasImages, supportsImages, isError) {
|
|
134012
|
+
const trimmed = text2.trim();
|
|
133946
134013
|
const errorPrefix = isError ? "[tool error] " : "";
|
|
133947
134014
|
if (trimmed.length > 0) {
|
|
133948
134015
|
const imageSuffix = hasImages && !supportsImages ? "\n[tool image omitted: model does not support images]" : "";
|
|
@@ -134743,14 +134810,14 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
134743
134810
|
};
|
|
134744
134811
|
const onMessage = (event) => {
|
|
134745
134812
|
void (async () => {
|
|
134746
|
-
let
|
|
134813
|
+
let text2 = null;
|
|
134747
134814
|
try {
|
|
134748
134815
|
if (!event || typeof event !== "object" || !("data" in event))
|
|
134749
134816
|
return;
|
|
134750
|
-
|
|
134751
|
-
if (!
|
|
134817
|
+
text2 = await decodeWebSocketData(event.data);
|
|
134818
|
+
if (!text2)
|
|
134752
134819
|
return;
|
|
134753
|
-
const parsed = JSON.parse(
|
|
134820
|
+
const parsed = JSON.parse(text2);
|
|
134754
134821
|
const type = typeof parsed.type === "string" ? parsed.type : "";
|
|
134755
134822
|
if (type === "response.completed" || type === "response.done" || type === "response.incomplete") {
|
|
134756
134823
|
sawCompletion = true;
|
|
@@ -134761,7 +134828,7 @@ async function* parseWebSocket(socket, signal, idleTimeoutMs) {
|
|
|
134761
134828
|
} catch (cause) {
|
|
134762
134829
|
failed = new CodexProtocolError(`Invalid Codex WebSocket JSON: ${formatThrownValue(cause)}`, {
|
|
134763
134830
|
cause,
|
|
134764
|
-
payload:
|
|
134831
|
+
payload: text2
|
|
134765
134832
|
});
|
|
134766
134833
|
done = true;
|
|
134767
134834
|
wake();
|
|
@@ -142954,11 +143021,11 @@ function videoRequestConfig(input) {
|
|
|
142954
143021
|
};
|
|
142955
143022
|
}
|
|
142956
143023
|
async function readMiniMaxJson(response) {
|
|
142957
|
-
const
|
|
143024
|
+
const text2 = await response.text();
|
|
142958
143025
|
let body = {};
|
|
142959
|
-
if (
|
|
143026
|
+
if (text2) {
|
|
142960
143027
|
try {
|
|
142961
|
-
const parsed = JSON.parse(
|
|
143028
|
+
const parsed = JSON.parse(text2);
|
|
142962
143029
|
if (isRecord2(parsed)) body = parsed;
|
|
142963
143030
|
} catch {
|
|
142964
143031
|
throw new Error("MiniMax video API returned invalid JSON");
|
|
@@ -143861,6 +143928,7 @@ __export(store_exports, {
|
|
|
143861
143928
|
CodeGraphStore: () => CodeGraphStore
|
|
143862
143929
|
});
|
|
143863
143930
|
import { randomUUID as randomUUID6 } from "crypto";
|
|
143931
|
+
import { posix as pathPosix } from "path";
|
|
143864
143932
|
function rowToFile(row) {
|
|
143865
143933
|
return {
|
|
143866
143934
|
id: row.id,
|
|
@@ -143911,6 +143979,26 @@ function rowToEdge(row) {
|
|
|
143911
143979
|
...row.sourceEpoch != null ? { sourceEpoch: Number(row.sourceEpoch) } : {}
|
|
143912
143980
|
};
|
|
143913
143981
|
}
|
|
143982
|
+
function resolveRelativeImportTarget(sourcePath, evidence, fileByPath) {
|
|
143983
|
+
const target = evidence?.trim().replace(/\\/g, "/");
|
|
143984
|
+
if (!target?.startsWith(".")) return void 0;
|
|
143985
|
+
const base = normalizeCodePath(pathPosix.normalize(pathPosix.join(pathPosix.dirname(sourcePath), target)));
|
|
143986
|
+
if (!base || base === ".." || base.startsWith("../")) return void 0;
|
|
143987
|
+
const candidates = [base];
|
|
143988
|
+
const extensionMatch = base.match(/(\.[A-Za-z0-9]+)$/);
|
|
143989
|
+
const hasExtension = Boolean(extensionMatch);
|
|
143990
|
+
if (!hasExtension) {
|
|
143991
|
+
const extensions = [...new Set([...fileByPath.keys()].map((path36) => path36.match(/(\.[A-Za-z0-9]+)$/)?.[1]).filter((extension3) => Boolean(extension3)))];
|
|
143992
|
+
for (const extension3 of extensions) {
|
|
143993
|
+
candidates.push(`${base}${extension3}`, `${base}/index${extension3}`);
|
|
143994
|
+
}
|
|
143995
|
+
} else {
|
|
143996
|
+
const sourceStem = base.slice(0, -extensionMatch[1].length);
|
|
143997
|
+
const sourceExtensions = extensionMatch[1] === ".js" ? [".ts", ".tsx", ".js", ".jsx"] : extensionMatch[1] === ".mjs" ? [".mts", ".mjs"] : extensionMatch[1] === ".cjs" ? [".cts", ".cjs"] : [];
|
|
143998
|
+
for (const extension3 of sourceExtensions) candidates.push(`${sourceStem}${extension3}`);
|
|
143999
|
+
}
|
|
144000
|
+
return candidates.map((candidate) => fileByPath.get(candidate)).find((file) => Boolean(file));
|
|
144001
|
+
}
|
|
143914
144002
|
function rowToRef(row) {
|
|
143915
144003
|
return {
|
|
143916
144004
|
id: row.id,
|
|
@@ -143971,6 +144059,18 @@ function rowToSnapshot(row) {
|
|
|
143971
144059
|
...row.previousSnapshotId ? { previousSnapshotId: row.previousSnapshotId } : {}
|
|
143972
144060
|
};
|
|
143973
144061
|
}
|
|
144062
|
+
function rowToSnapshotFile(row) {
|
|
144063
|
+
return {
|
|
144064
|
+
snapshotId: row.snapshotId,
|
|
144065
|
+
projectId: row.projectId,
|
|
144066
|
+
fileId: row.fileId,
|
|
144067
|
+
path: row.path,
|
|
144068
|
+
contentHash: row.contentHash
|
|
144069
|
+
};
|
|
144070
|
+
}
|
|
144071
|
+
function snapshotIsIncomplete(snapshot) {
|
|
144072
|
+
return snapshot.completeness.skippedOversizedFiles > 0 || (snapshot.completeness.unreadableFiles ?? 0) > 0 || snapshot.completeness.removalScanDeferred;
|
|
144073
|
+
}
|
|
143974
144074
|
var CodeGraphStore;
|
|
143975
144075
|
var init_store = __esm({
|
|
143976
144076
|
"src/codegraph/store.ts"() {
|
|
@@ -144142,6 +144242,7 @@ var init_store = __esm({
|
|
|
144142
144242
|
}
|
|
144143
144243
|
});
|
|
144144
144244
|
tx();
|
|
144245
|
+
this.reconcileLocalImportTargets(projectId);
|
|
144145
144246
|
}
|
|
144146
144247
|
/**
|
|
144147
144248
|
* Reconcile only files whose source changed plus files that disappeared.
|
|
@@ -144151,7 +144252,10 @@ var init_store = __esm({
|
|
|
144151
144252
|
const changed = input.changed.filter((delta) => delta.file.projectId === projectId);
|
|
144152
144253
|
const metadataOnly = (input.metadataOnly ?? []).filter((file) => file.projectId === projectId);
|
|
144153
144254
|
const removedFileIds = input.removedFileIds ?? [];
|
|
144154
|
-
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0)
|
|
144255
|
+
if (changed.length === 0 && metadataOnly.length === 0 && removedFileIds.length === 0) {
|
|
144256
|
+
this.reconcileLocalImportTargets(projectId);
|
|
144257
|
+
return;
|
|
144258
|
+
}
|
|
144155
144259
|
const staleRefsForFile = this.db.prepare(`
|
|
144156
144260
|
UPDATE observation_code_refs
|
|
144157
144261
|
SET status = 'stale', updatedAt = ?
|
|
@@ -144161,9 +144265,18 @@ var init_store = __esm({
|
|
|
144161
144265
|
)
|
|
144162
144266
|
)
|
|
144163
144267
|
`);
|
|
144164
|
-
const
|
|
144268
|
+
const deleteEdgesFromFile = this.db.prepare(`
|
|
144269
|
+
DELETE FROM code_edges
|
|
144270
|
+
WHERE projectId = ? AND fromFileId = ?
|
|
144271
|
+
`);
|
|
144272
|
+
const clearImportTargetsForFile = this.db.prepare(`
|
|
144273
|
+
UPDATE code_edges
|
|
144274
|
+
SET toFileId = NULL
|
|
144275
|
+
WHERE projectId = ? AND toFileId = ? AND type = 'imports'
|
|
144276
|
+
`);
|
|
144277
|
+
const deleteOtherIncomingEdgesForFile = this.db.prepare(`
|
|
144165
144278
|
DELETE FROM code_edges
|
|
144166
|
-
WHERE projectId = ? AND
|
|
144279
|
+
WHERE projectId = ? AND toFileId = ? AND type != 'imports'
|
|
144167
144280
|
`);
|
|
144168
144281
|
const deleteSymbolsForFile = this.db.prepare(`DELETE FROM code_symbols WHERE projectId = ? AND fileId = ?`);
|
|
144169
144282
|
const deleteFile = this.db.prepare(`DELETE FROM code_files WHERE projectId = ? AND id = ?`);
|
|
@@ -144200,14 +144313,18 @@ var init_store = __esm({
|
|
|
144200
144313
|
const staleAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
144201
144314
|
for (const fileId of removedFileIds) {
|
|
144202
144315
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
144203
|
-
|
|
144316
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
144317
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
144318
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
144204
144319
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
144205
144320
|
deleteFile.run(projectId, fileId);
|
|
144206
144321
|
}
|
|
144207
144322
|
for (const delta of changed) {
|
|
144208
144323
|
const fileId = delta.file.id;
|
|
144209
144324
|
staleRefsForFile.run(staleAt, projectId, fileId, projectId, fileId);
|
|
144210
|
-
|
|
144325
|
+
deleteEdgesFromFile.run(projectId, fileId);
|
|
144326
|
+
clearImportTargetsForFile.run(projectId, fileId);
|
|
144327
|
+
deleteOtherIncomingEdgesForFile.run(projectId, fileId);
|
|
144211
144328
|
deleteSymbolsForFile.run(projectId, fileId);
|
|
144212
144329
|
writeFile8(delta.file);
|
|
144213
144330
|
for (const symbol of delta.symbols) {
|
|
@@ -144245,6 +144362,7 @@ var init_store = __esm({
|
|
|
144245
144362
|
for (const file of metadataOnly) writeFile8(file);
|
|
144246
144363
|
});
|
|
144247
144364
|
tx();
|
|
144365
|
+
this.reconcileLocalImportTargets(projectId);
|
|
144248
144366
|
}
|
|
144249
144367
|
upsertObservationRefs(refs) {
|
|
144250
144368
|
if (refs.length === 0) return;
|
|
@@ -144306,6 +144424,25 @@ var init_store = __esm({
|
|
|
144306
144424
|
});
|
|
144307
144425
|
tx();
|
|
144308
144426
|
}
|
|
144427
|
+
/**
|
|
144428
|
+
* Lite import extraction records the original import text first. Resolve only
|
|
144429
|
+
* local relative imports against the current index after each refresh, so an
|
|
144430
|
+
* added or removed target cannot leave a fabricated file-to-file relation.
|
|
144431
|
+
*/
|
|
144432
|
+
reconcileLocalImportTargets(projectId) {
|
|
144433
|
+
const fileById = new Map(this.listFiles(projectId).map((file) => [file.id, file]));
|
|
144434
|
+
const fileByPath = new Map([...fileById.values()].map((file) => [file.path, file]));
|
|
144435
|
+
const update2 = this.db.prepare("UPDATE code_edges SET toFileId = ? WHERE id = ?");
|
|
144436
|
+
const tx = this.db.transaction(() => {
|
|
144437
|
+
for (const edge of this.listEdges(projectId)) {
|
|
144438
|
+
if (edge.type !== "imports" || !edge.fromFileId) continue;
|
|
144439
|
+
const source = fileById.get(edge.fromFileId);
|
|
144440
|
+
const target = source ? resolveRelativeImportTarget(source.path, edge.evidence, fileByPath) : void 0;
|
|
144441
|
+
update2.run(target?.id ?? null, edge.id);
|
|
144442
|
+
}
|
|
144443
|
+
});
|
|
144444
|
+
tx();
|
|
144445
|
+
}
|
|
144309
144446
|
getFile(projectId, path36) {
|
|
144310
144447
|
const row = this.db.prepare(`SELECT * FROM code_files WHERE projectId = ? AND path = ?`).get(projectId, normalizeCodePath(path36));
|
|
144311
144448
|
return row ? rowToFile(row) : null;
|
|
@@ -144380,6 +144517,18 @@ var init_store = __esm({
|
|
|
144380
144517
|
ORDER BY observationId, status, id
|
|
144381
144518
|
`).all(projectId).map(rowToRef);
|
|
144382
144519
|
}
|
|
144520
|
+
/** Count distinct observations whose binding to these exact files is stale. */
|
|
144521
|
+
countStaleObservationRefsForFiles(projectId, fileIds) {
|
|
144522
|
+
const ids = [...new Set(fileIds.filter(Boolean))];
|
|
144523
|
+
if (ids.length === 0) return 0;
|
|
144524
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
144525
|
+
const row = this.db.prepare(`
|
|
144526
|
+
SELECT COUNT(DISTINCT observationId) AS count
|
|
144527
|
+
FROM observation_code_refs
|
|
144528
|
+
WHERE projectId = ? AND status = 'stale' AND fileId IN (${placeholders})
|
|
144529
|
+
`).get(projectId, ...ids);
|
|
144530
|
+
return Number(row?.count ?? 0);
|
|
144531
|
+
}
|
|
144383
144532
|
listReferencedSymbols(projectId) {
|
|
144384
144533
|
return this.db.prepare(`
|
|
144385
144534
|
SELECT DISTINCT symbols.*
|
|
@@ -144401,6 +144550,94 @@ var init_store = __esm({
|
|
|
144401
144550
|
"SELECT * FROM code_state_snapshots WHERE projectId = ? ORDER BY sourceEpoch DESC LIMIT ?"
|
|
144402
144551
|
).all(projectId, safeLimit2).map(rowToSnapshot);
|
|
144403
144552
|
}
|
|
144553
|
+
listSnapshotFiles(snapshotId) {
|
|
144554
|
+
return this.db.prepare(`
|
|
144555
|
+
SELECT snapshotId, projectId, fileId, path, contentHash
|
|
144556
|
+
FROM code_state_snapshot_files
|
|
144557
|
+
WHERE snapshotId = ?
|
|
144558
|
+
ORDER BY path
|
|
144559
|
+
`).all(snapshotId).map(rowToSnapshotFile);
|
|
144560
|
+
}
|
|
144561
|
+
diffSnapshots(projectId, fromSnapshotId, toSnapshotId) {
|
|
144562
|
+
const snapshots = this.db.prepare(`
|
|
144563
|
+
SELECT * FROM code_state_snapshots WHERE id IN (?, ?)
|
|
144564
|
+
`).all(fromSnapshotId, toSnapshotId).map(rowToSnapshot);
|
|
144565
|
+
if (snapshots.length !== 2) {
|
|
144566
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "missing-snapshot", changes: [] };
|
|
144567
|
+
}
|
|
144568
|
+
if (snapshots.some((snapshot) => snapshot.projectId !== projectId)) {
|
|
144569
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "project-mismatch", changes: [] };
|
|
144570
|
+
}
|
|
144571
|
+
if (snapshots.some(snapshotIsIncomplete)) {
|
|
144572
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: false, reason: "incomplete-snapshot", changes: [] };
|
|
144573
|
+
}
|
|
144574
|
+
const before = this.listSnapshotFiles(fromSnapshotId);
|
|
144575
|
+
const after = this.listSnapshotFiles(toSnapshotId);
|
|
144576
|
+
if (before.length === 0 || after.length === 0) {
|
|
144577
|
+
return {
|
|
144578
|
+
projectId,
|
|
144579
|
+
fromSnapshotId,
|
|
144580
|
+
toSnapshotId,
|
|
144581
|
+
available: false,
|
|
144582
|
+
reason: "legacy-snapshot-without-manifest",
|
|
144583
|
+
changes: []
|
|
144584
|
+
};
|
|
144585
|
+
}
|
|
144586
|
+
const beforeByPath = new Map(before.map((file) => [file.path, file]));
|
|
144587
|
+
const afterByPath = new Map(after.map((file) => [file.path, file]));
|
|
144588
|
+
const paths = [.../* @__PURE__ */ new Set([...beforeByPath.keys(), ...afterByPath.keys()])].sort();
|
|
144589
|
+
const changes = [];
|
|
144590
|
+
for (const path36 of paths) {
|
|
144591
|
+
const oldFile = beforeByPath.get(path36);
|
|
144592
|
+
const newFile = afterByPath.get(path36);
|
|
144593
|
+
if (!oldFile && newFile) {
|
|
144594
|
+
changes.push({ path: path36, kind: "added", afterHash: newFile.contentHash });
|
|
144595
|
+
} else if (oldFile && !newFile) {
|
|
144596
|
+
changes.push({ path: path36, kind: "removed", beforeHash: oldFile.contentHash });
|
|
144597
|
+
} else if (oldFile && newFile && oldFile.contentHash !== newFile.contentHash) {
|
|
144598
|
+
changes.push({ path: path36, kind: "modified", beforeHash: oldFile.contentHash, afterHash: newFile.contentHash });
|
|
144599
|
+
}
|
|
144600
|
+
}
|
|
144601
|
+
return { projectId, fromSnapshotId, toSnapshotId, available: true, changes };
|
|
144602
|
+
}
|
|
144603
|
+
impactSlice(projectId, changedPaths, maxRelations = 24) {
|
|
144604
|
+
const safeLimit2 = Number.isFinite(maxRelations) ? Math.max(1, Math.min(100, Math.floor(maxRelations))) : 24;
|
|
144605
|
+
const normalizedPaths = [...new Set(changedPaths.map(normalizeCodePath).filter(Boolean))].sort();
|
|
144606
|
+
const files = this.listFiles(projectId);
|
|
144607
|
+
const fileById = new Map(files.map((file) => [file.id, file.path]));
|
|
144608
|
+
const fileIdBySymbolId = new Map(this.listSymbols(projectId).map((symbol) => [symbol.id, symbol.fileId]));
|
|
144609
|
+
const changedIds = new Set(files.filter((file) => normalizedPaths.includes(file.path)).map((file) => file.id));
|
|
144610
|
+
const direct = /* @__PURE__ */ new Set();
|
|
144611
|
+
let relationCount = 0;
|
|
144612
|
+
let truncated = false;
|
|
144613
|
+
for (const edge of this.listEdges(projectId)) {
|
|
144614
|
+
const endpoints = [
|
|
144615
|
+
edge.fromFileId,
|
|
144616
|
+
edge.toFileId,
|
|
144617
|
+
edge.fromSymbolId ? fileIdBySymbolId.get(edge.fromSymbolId) : void 0,
|
|
144618
|
+
edge.toSymbolId ? fileIdBySymbolId.get(edge.toSymbolId) : void 0
|
|
144619
|
+
].filter((id) => Boolean(id));
|
|
144620
|
+
if (!endpoints.some((id) => changedIds.has(id))) continue;
|
|
144621
|
+
const relatedPaths = endpoints.filter((id) => !changedIds.has(id)).map((id) => fileById.get(id)).filter((path36) => Boolean(path36));
|
|
144622
|
+
if (relatedPaths.length === 0) continue;
|
|
144623
|
+
if (relationCount >= safeLimit2) {
|
|
144624
|
+
truncated = true;
|
|
144625
|
+
break;
|
|
144626
|
+
}
|
|
144627
|
+
relationCount += 1;
|
|
144628
|
+
for (const path36 of relatedPaths) direct.add(path36);
|
|
144629
|
+
}
|
|
144630
|
+
const snapshot = this.latestSnapshot(projectId);
|
|
144631
|
+
return {
|
|
144632
|
+
projectId,
|
|
144633
|
+
...snapshot ? { snapshotId: snapshot.id } : {},
|
|
144634
|
+
changedPaths: normalizedPaths,
|
|
144635
|
+
directlyConnectedPaths: [...direct].sort(),
|
|
144636
|
+
relationCount,
|
|
144637
|
+
truncated,
|
|
144638
|
+
provider: snapshot?.provider ?? "lite"
|
|
144639
|
+
};
|
|
144640
|
+
}
|
|
144404
144641
|
/**
|
|
144405
144642
|
* Record a completed scan and mark all current structural facts with its
|
|
144406
144643
|
* epoch. The snapshot is written only after refresh reconciliation succeeds,
|
|
@@ -144442,6 +144679,16 @@ var init_store = __esm({
|
|
|
144442
144679
|
this.db.prepare(
|
|
144443
144680
|
"UPDATE observation_code_refs SET snapshotId = ? WHERE projectId = ? AND status = 'current'"
|
|
144444
144681
|
).run(id, input.projectId);
|
|
144682
|
+
const snapshotFileRows = this.db.prepare(`
|
|
144683
|
+
SELECT id, projectId, path, contentHash FROM code_files WHERE projectId = ? ORDER BY path
|
|
144684
|
+
`).all(input.projectId);
|
|
144685
|
+
const insertSnapshotFile = this.db.prepare(`
|
|
144686
|
+
INSERT INTO code_state_snapshot_files (snapshotId, projectId, fileId, path, contentHash)
|
|
144687
|
+
VALUES (?, ?, ?, ?, ?)
|
|
144688
|
+
`);
|
|
144689
|
+
for (const file of snapshotFileRows) {
|
|
144690
|
+
insertSnapshotFile.run(id, file.projectId, file.id, file.path, file.contentHash);
|
|
144691
|
+
}
|
|
144445
144692
|
snapshot = {
|
|
144446
144693
|
...input,
|
|
144447
144694
|
id,
|
|
@@ -144607,8 +144854,8 @@ __export(lite_provider_exports, {
|
|
|
144607
144854
|
import { createHash as createHash7 } from "crypto";
|
|
144608
144855
|
import { readdirSync as readdirSync2, readFileSync as readFileSync6, statSync as statSync3 } from "fs";
|
|
144609
144856
|
import { join as join4, relative } from "path";
|
|
144610
|
-
function hashText(
|
|
144611
|
-
return createHash7("sha256").update(
|
|
144857
|
+
function hashText(text2) {
|
|
144858
|
+
return createHash7("sha256").update(text2).digest("hex");
|
|
144612
144859
|
}
|
|
144613
144860
|
function extension2(path36) {
|
|
144614
144861
|
const index = path36.lastIndexOf(".");
|
|
@@ -144652,19 +144899,19 @@ function walk(root, exclude, maxFiles) {
|
|
|
144652
144899
|
visit(root);
|
|
144653
144900
|
return out;
|
|
144654
144901
|
}
|
|
144655
|
-
function lineOf(
|
|
144656
|
-
return
|
|
144902
|
+
function lineOf(text2, index) {
|
|
144903
|
+
return text2.slice(0, index).split(/\r?\n/).length;
|
|
144657
144904
|
}
|
|
144658
|
-
function extractSymbols(projectId, file,
|
|
144905
|
+
function extractSymbols(projectId, file, text2, indexedAt) {
|
|
144659
144906
|
const symbols = [];
|
|
144660
144907
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
144661
144908
|
const patterns = profile?.symbols ?? [];
|
|
144662
144909
|
for (const { kind, re } of patterns) {
|
|
144663
144910
|
re.lastIndex = 0;
|
|
144664
|
-
for (const match2 of
|
|
144911
|
+
for (const match2 of text2.matchAll(re)) {
|
|
144665
144912
|
const name = match2[1];
|
|
144666
144913
|
if (!name || name.includes("\n")) continue;
|
|
144667
|
-
const startLine = lineOf(
|
|
144914
|
+
const startLine = lineOf(text2, match2.index ?? 0);
|
|
144668
144915
|
const id = makeCodeSymbolId({ projectId, path: file.path, qualifiedName: name, kind });
|
|
144669
144916
|
symbols.push({
|
|
144670
144917
|
id,
|
|
@@ -144684,13 +144931,13 @@ function extractSymbols(projectId, file, text, indexedAt) {
|
|
|
144684
144931
|
}
|
|
144685
144932
|
return symbols;
|
|
144686
144933
|
}
|
|
144687
|
-
function extractImportEdges(projectId, file,
|
|
144934
|
+
function extractImportEdges(projectId, file, text2, indexedAt) {
|
|
144688
144935
|
const edges = [];
|
|
144689
144936
|
const profile = file.language ? languageProfiles[file.language] : void 0;
|
|
144690
144937
|
const imports = profile?.imports ?? [];
|
|
144691
144938
|
for (const re of imports) {
|
|
144692
144939
|
re.lastIndex = 0;
|
|
144693
|
-
for (const match2 of
|
|
144940
|
+
for (const match2 of text2.matchAll(re)) {
|
|
144694
144941
|
const target = (match2[1] ?? "").trim();
|
|
144695
144942
|
if (!target) continue;
|
|
144696
144943
|
if (target.includes("\n")) {
|
|
@@ -144725,14 +144972,14 @@ function extractImportEdges(projectId, file, text, indexedAt) {
|
|
|
144725
144972
|
function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
144726
144973
|
const rel = normalizeCodePath(relative(projectRoot, abs));
|
|
144727
144974
|
try {
|
|
144728
|
-
const
|
|
144975
|
+
const text2 = readFileSync6(abs, "utf-8");
|
|
144729
144976
|
const stat4 = fileStat ?? statSync3(abs);
|
|
144730
144977
|
const file = {
|
|
144731
144978
|
id: makeCodeFileId(projectId, rel),
|
|
144732
144979
|
projectId,
|
|
144733
144980
|
path: rel,
|
|
144734
144981
|
language: languageForPath(rel),
|
|
144735
|
-
contentHash: hashText(
|
|
144982
|
+
contentHash: hashText(text2),
|
|
144736
144983
|
// Preserve filesystem precision. Rounding here made same-size edits in
|
|
144737
144984
|
// a short Windows timestamp window indistinguishable to refresh.
|
|
144738
144985
|
mtimeMs: Number(stat4.mtimeMs),
|
|
@@ -144742,8 +144989,8 @@ function indexFileLite(projectId, projectRoot, abs, indexedAt, fileStat) {
|
|
|
144742
144989
|
return {
|
|
144743
144990
|
delta: {
|
|
144744
144991
|
file,
|
|
144745
|
-
symbols: extractSymbols(projectId, file,
|
|
144746
|
-
edges: extractImportEdges(projectId, file,
|
|
144992
|
+
symbols: extractSymbols(projectId, file, text2, indexedAt),
|
|
144993
|
+
edges: extractImportEdges(projectId, file, text2, indexedAt)
|
|
144747
144994
|
},
|
|
144748
144995
|
unreadable: false
|
|
144749
144996
|
};
|
|
@@ -145022,18 +145269,18 @@ __export(binder_exports, {
|
|
|
145022
145269
|
function observationText(obs) {
|
|
145023
145270
|
return [obs.title, obs.narrative, ...obs.facts ?? []].join("\n");
|
|
145024
145271
|
}
|
|
145025
|
-
function mentionsSymbol(
|
|
145272
|
+
function mentionsSymbol(text2, symbol) {
|
|
145026
145273
|
const name = symbol.name.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
145027
|
-
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(
|
|
145274
|
+
return new RegExp(`(^|[^\\w$])${name}([^\\w$]|$)`).test(text2);
|
|
145028
145275
|
}
|
|
145029
|
-
function identifierCandidates(
|
|
145030
|
-
return [...new Set(
|
|
145276
|
+
function identifierCandidates(text2) {
|
|
145277
|
+
return [...new Set(text2.match(/[A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?/g) ?? [])];
|
|
145031
145278
|
}
|
|
145032
|
-
function codeIdentifierCandidates(
|
|
145279
|
+
function codeIdentifierCandidates(text2) {
|
|
145033
145280
|
const explicit = /* @__PURE__ */ new Set();
|
|
145034
|
-
for (const match2 of
|
|
145035
|
-
for (const match2 of
|
|
145036
|
-
return identifierCandidates(
|
|
145281
|
+
for (const match2 of text2.matchAll(/`([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)`/g)) explicit.add(match2[1]);
|
|
145282
|
+
for (const match2 of text2.matchAll(/\b([A-Za-z_$][\w$]*(?:::[A-Za-z_$][\w$]*)*[!?=]?)\s*\(/g)) explicit.add(match2[1]);
|
|
145283
|
+
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));
|
|
145037
145284
|
}
|
|
145038
145285
|
function fileRef(projectId, obs, file) {
|
|
145039
145286
|
return {
|
|
@@ -145063,7 +145310,7 @@ function symbolRef(projectId, obs, file, symbol) {
|
|
|
145063
145310
|
}
|
|
145064
145311
|
function resolveObservationCodeRefs(obs, lookup2) {
|
|
145065
145312
|
const refs = /* @__PURE__ */ new Map();
|
|
145066
|
-
const
|
|
145313
|
+
const text2 = observationText(obs);
|
|
145067
145314
|
const candidateFiles = /* @__PURE__ */ new Map();
|
|
145068
145315
|
for (const rawPath of obs.filesModified ?? []) {
|
|
145069
145316
|
const file = lookup2.findFile(normalizeCodePath(rawPath));
|
|
@@ -145073,7 +145320,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
145073
145320
|
refs.set(ref.id, ref);
|
|
145074
145321
|
}
|
|
145075
145322
|
const hintedFileIds = new Set(candidateFiles.keys());
|
|
145076
|
-
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(
|
|
145323
|
+
const symbolNames = hintedFileIds.size > 0 ? identifierCandidates(text2) : codeIdentifierCandidates(text2);
|
|
145077
145324
|
const symbols = lookup2.findSymbols(symbolNames, [...hintedFileIds]);
|
|
145078
145325
|
const symbolsByName = /* @__PURE__ */ new Map();
|
|
145079
145326
|
for (const symbol of symbols) {
|
|
@@ -145084,7 +145331,7 @@ function resolveObservationCodeRefs(obs, lookup2) {
|
|
|
145084
145331
|
for (const group of symbolsByName.values()) {
|
|
145085
145332
|
const candidates = group.length === 1 ? group : [];
|
|
145086
145333
|
for (const symbol of candidates) {
|
|
145087
|
-
if (!mentionsSymbol(
|
|
145334
|
+
if (!mentionsSymbol(text2, symbol)) continue;
|
|
145088
145335
|
const file = candidateFiles.get(symbol.fileId) ?? lookup2.findFile(symbol.path);
|
|
145089
145336
|
if (!file) continue;
|
|
145090
145337
|
candidateFiles.set(file.id, file);
|
|
@@ -145812,8 +146059,8 @@ function taskTokens(task) {
|
|
|
145812
146059
|
return normalizedTokens(task);
|
|
145813
146060
|
}
|
|
145814
146061
|
function scoreClaim(claim, tokens) {
|
|
145815
|
-
const
|
|
145816
|
-
const words = normalizedTokens(
|
|
146062
|
+
const text2 = [claim.subject, claim.predicate, claim.objectValue].join(" ").toLocaleLowerCase("en-US");
|
|
146063
|
+
const words = normalizedTokens(text2);
|
|
145817
146064
|
let matches = 0;
|
|
145818
146065
|
for (const token of tokens) {
|
|
145819
146066
|
if (words.has(token)) matches += 1;
|
|
@@ -146713,6 +146960,128 @@ var init_workflow_store = __esm({
|
|
|
146713
146960
|
}
|
|
146714
146961
|
});
|
|
146715
146962
|
|
|
146963
|
+
// src/knowledge/outcome-types.ts
|
|
146964
|
+
function qualityFromOutcome(signal) {
|
|
146965
|
+
if (!signal) return void 0;
|
|
146966
|
+
if (signal.kind === "verification-failed" || signal.kind === "user-correction" || signal.kind === "source-changed" || signal.kind === "conflict-confirmed") {
|
|
146967
|
+
return "degraded";
|
|
146968
|
+
}
|
|
146969
|
+
if (signal.kind === "verification-passed" || signal.kind === "verified-reuse" || signal.kind === "user-pin") {
|
|
146970
|
+
return "verified";
|
|
146971
|
+
}
|
|
146972
|
+
return void 0;
|
|
146973
|
+
}
|
|
146974
|
+
var MEMORY_OUTCOME_CANDIDATE_KINDS, MEMORY_OUTCOME_SIGNAL_KINDS;
|
|
146975
|
+
var init_outcome_types = __esm({
|
|
146976
|
+
"src/knowledge/outcome-types.ts"() {
|
|
146977
|
+
"use strict";
|
|
146978
|
+
init_esm_shims();
|
|
146979
|
+
MEMORY_OUTCOME_CANDIDATE_KINDS = ["claim", "durable-memory", "workflow"];
|
|
146980
|
+
MEMORY_OUTCOME_SIGNAL_KINDS = [
|
|
146981
|
+
"verification-passed",
|
|
146982
|
+
"verification-failed",
|
|
146983
|
+
"verified-reuse",
|
|
146984
|
+
"user-pin",
|
|
146985
|
+
"user-correction",
|
|
146986
|
+
"source-changed",
|
|
146987
|
+
"conflict-confirmed",
|
|
146988
|
+
"manual-review"
|
|
146989
|
+
];
|
|
146990
|
+
}
|
|
146991
|
+
});
|
|
146992
|
+
|
|
146993
|
+
// src/knowledge/outcome-store.ts
|
|
146994
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
146995
|
+
function optionalText4(value) {
|
|
146996
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
146997
|
+
}
|
|
146998
|
+
function text(value, field, max = 1e3) {
|
|
146999
|
+
const safe = sanitizeCredentials(value).replace(/\s+/g, " ").trim();
|
|
147000
|
+
if (!safe) throw new Error("Outcome signal " + field + " is required.");
|
|
147001
|
+
if (safe.length > max) throw new Error("Outcome signal " + field + " is too long.");
|
|
147002
|
+
return safe;
|
|
147003
|
+
}
|
|
147004
|
+
function oneOf(value, values, field) {
|
|
147005
|
+
if (typeof value !== "string" || !values.includes(value)) {
|
|
147006
|
+
throw new Error("Outcome signal " + field + " is invalid.");
|
|
147007
|
+
}
|
|
147008
|
+
return value;
|
|
147009
|
+
}
|
|
147010
|
+
function rowToSignal(row) {
|
|
147011
|
+
return {
|
|
147012
|
+
id: row.id,
|
|
147013
|
+
projectId: row.projectId,
|
|
147014
|
+
candidateKind: row.candidateKind,
|
|
147015
|
+
candidateId: row.candidateId,
|
|
147016
|
+
kind: row.kind,
|
|
147017
|
+
sourceRef: row.sourceRef,
|
|
147018
|
+
...optionalText4(row.snapshotId) ? { snapshotId: row.snapshotId } : {},
|
|
147019
|
+
...optionalText4(row.detail) ? { detail: row.detail } : {},
|
|
147020
|
+
observedAt: row.observedAt
|
|
147021
|
+
};
|
|
147022
|
+
}
|
|
147023
|
+
var OutcomeStore;
|
|
147024
|
+
var init_outcome_store = __esm({
|
|
147025
|
+
"src/knowledge/outcome-store.ts"() {
|
|
147026
|
+
"use strict";
|
|
147027
|
+
init_esm_shims();
|
|
147028
|
+
init_secret_filter();
|
|
147029
|
+
init_sqlite_db();
|
|
147030
|
+
init_outcome_types();
|
|
147031
|
+
OutcomeStore = class {
|
|
147032
|
+
db = null;
|
|
147033
|
+
async init(dataDir) {
|
|
147034
|
+
this.db = getDatabase(dataDir);
|
|
147035
|
+
}
|
|
147036
|
+
record(input) {
|
|
147037
|
+
const signal = {
|
|
147038
|
+
id: randomUUID10(),
|
|
147039
|
+
projectId: text(input.projectId, "project id"),
|
|
147040
|
+
candidateKind: oneOf(input.candidateKind, MEMORY_OUTCOME_CANDIDATE_KINDS, "candidate kind"),
|
|
147041
|
+
candidateId: text(input.candidateId, "candidate id"),
|
|
147042
|
+
kind: oneOf(input.kind, MEMORY_OUTCOME_SIGNAL_KINDS, "kind"),
|
|
147043
|
+
sourceRef: text(input.sourceRef, "source reference"),
|
|
147044
|
+
...input.snapshotId ? { snapshotId: text(input.snapshotId, "snapshot id") } : {},
|
|
147045
|
+
...input.detail ? { detail: text(input.detail, "detail") } : {},
|
|
147046
|
+
observedAt: input.observedAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
147047
|
+
};
|
|
147048
|
+
this.db.prepare(`
|
|
147049
|
+
INSERT INTO memory_outcome_signals (
|
|
147050
|
+
id, projectId, candidateKind, candidateId, kind, sourceRef, snapshotId, detail, observedAt
|
|
147051
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
147052
|
+
`).run(
|
|
147053
|
+
signal.id,
|
|
147054
|
+
signal.projectId,
|
|
147055
|
+
signal.candidateKind,
|
|
147056
|
+
signal.candidateId,
|
|
147057
|
+
signal.kind,
|
|
147058
|
+
signal.sourceRef,
|
|
147059
|
+
signal.snapshotId ?? null,
|
|
147060
|
+
signal.detail ?? null,
|
|
147061
|
+
signal.observedAt
|
|
147062
|
+
);
|
|
147063
|
+
return signal;
|
|
147064
|
+
}
|
|
147065
|
+
latestForCandidates(projectId, candidateKind, candidateIds) {
|
|
147066
|
+
const ids = [...new Set(candidateIds.filter(Boolean))];
|
|
147067
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
147068
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
147069
|
+
const rows = this.db.prepare(`
|
|
147070
|
+
SELECT * FROM memory_outcome_signals
|
|
147071
|
+
WHERE projectId = ? AND candidateKind = ? AND candidateId IN (${placeholders})
|
|
147072
|
+
ORDER BY observedAt DESC, id DESC
|
|
147073
|
+
`).all(projectId, candidateKind, ...ids);
|
|
147074
|
+
const latest = /* @__PURE__ */ new Map();
|
|
147075
|
+
for (const row of rows) {
|
|
147076
|
+
const signal = rowToSignal(row);
|
|
147077
|
+
if (!latest.has(signal.candidateId)) latest.set(signal.candidateId, signal);
|
|
147078
|
+
}
|
|
147079
|
+
return latest;
|
|
147080
|
+
}
|
|
147081
|
+
};
|
|
147082
|
+
}
|
|
147083
|
+
});
|
|
147084
|
+
|
|
146716
147085
|
// src/codegraph/task-lens.ts
|
|
146717
147086
|
var task_lens_exports = {};
|
|
146718
147087
|
__export(task_lens_exports, {
|
|
@@ -146729,31 +147098,31 @@ __export(task_lens_exports, {
|
|
|
146729
147098
|
function normalizePath2(path36) {
|
|
146730
147099
|
return path36.replace(/\\/g, "/");
|
|
146731
147100
|
}
|
|
146732
|
-
function tokenize3(
|
|
146733
|
-
return (
|
|
147101
|
+
function tokenize3(text2) {
|
|
147102
|
+
return (text2.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1 && !STOP_WORDS.has(token));
|
|
146734
147103
|
}
|
|
146735
|
-
function containsTaskKeyword(
|
|
147104
|
+
function containsTaskKeyword(text2, keyword) {
|
|
146736
147105
|
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");
|
|
146737
147106
|
let match2;
|
|
146738
|
-
while ((match2 = matcher.exec(
|
|
147107
|
+
while ((match2 = matcher.exec(text2)) !== null) {
|
|
146739
147108
|
const keywordIndex = match2.index + (match2[1]?.length ?? 0);
|
|
146740
|
-
if (!isNegatedTaskKeyword(
|
|
147109
|
+
if (!isNegatedTaskKeyword(text2, keywordIndex)) return true;
|
|
146741
147110
|
}
|
|
146742
147111
|
return false;
|
|
146743
147112
|
}
|
|
146744
|
-
function isNegatedTaskKeyword(
|
|
147113
|
+
function isNegatedTaskKeyword(text2, keywordIndex) {
|
|
146745
147114
|
const boundary = Math.max(
|
|
146746
|
-
|
|
146747
|
-
|
|
146748
|
-
|
|
146749
|
-
|
|
146750
|
-
|
|
146751
|
-
|
|
146752
|
-
|
|
146753
|
-
|
|
146754
|
-
|
|
147115
|
+
text2.lastIndexOf(".", keywordIndex - 1),
|
|
147116
|
+
text2.lastIndexOf("!", keywordIndex - 1),
|
|
147117
|
+
text2.lastIndexOf("?", keywordIndex - 1),
|
|
147118
|
+
text2.lastIndexOf(";", keywordIndex - 1),
|
|
147119
|
+
text2.lastIndexOf("\n", keywordIndex - 1),
|
|
147120
|
+
text2.lastIndexOf("\u3002", keywordIndex - 1),
|
|
147121
|
+
text2.lastIndexOf("\uFF01", keywordIndex - 1),
|
|
147122
|
+
text2.lastIndexOf("\uFF1F", keywordIndex - 1),
|
|
147123
|
+
text2.lastIndexOf("\uFF1B", keywordIndex - 1)
|
|
146755
147124
|
);
|
|
146756
|
-
let prefix =
|
|
147125
|
+
let prefix = text2.slice(boundary + 1, keywordIndex).toLowerCase();
|
|
146757
147126
|
const contrast = /(?:,|\uff0c)\s*(?:but|however|instead|yet|\u4f46\u662f|\u4f46|\u800c\u662f)\s*/gi;
|
|
146758
147127
|
let contrastMatch;
|
|
146759
147128
|
let contrastEnd = -1;
|
|
@@ -146776,9 +147145,9 @@ function resolveTaskLens(task) {
|
|
|
146776
147145
|
};
|
|
146777
147146
|
for (const id of LENS_PRIORITY) {
|
|
146778
147147
|
const score = KEYWORDS[id].reduce((sum, keyword) => sum + (containsTaskKeyword(normalized, keyword) ? 1 : 0), 0);
|
|
146779
|
-
const
|
|
146780
|
-
if (score > best.score || score === best.score && score > 0 &&
|
|
146781
|
-
best = { id, score, priority };
|
|
147148
|
+
const priority2 = LENS_PRIORITY.indexOf(id);
|
|
147149
|
+
if (score > best.score || score === best.score && score > 0 && priority2 < best.priority) {
|
|
147150
|
+
best = { id, score, priority: priority2 };
|
|
146782
147151
|
}
|
|
146783
147152
|
}
|
|
146784
147153
|
return best.score > 0 ? LENSES[best.id] : LENSES.general;
|
|
@@ -146820,20 +147189,20 @@ function pathKindScore(path36, lens) {
|
|
|
146820
147189
|
return 0;
|
|
146821
147190
|
}
|
|
146822
147191
|
}
|
|
146823
|
-
function tokenScore(
|
|
147192
|
+
function tokenScore(text2, tokens) {
|
|
146824
147193
|
if (tokens.length === 0) return 0;
|
|
146825
|
-
const normalized =
|
|
147194
|
+
const normalized = text2.toLowerCase();
|
|
146826
147195
|
return tokens.reduce((sum, token) => sum + (normalized.includes(token) ? 12 : 0), 0);
|
|
146827
147196
|
}
|
|
146828
147197
|
function sourceTaskMatchScore(source, task) {
|
|
146829
147198
|
const tokens = tokenize3(task ?? "");
|
|
146830
147199
|
if (tokens.length === 0) return 0;
|
|
146831
|
-
const
|
|
147200
|
+
const text2 = [
|
|
146832
147201
|
source.title,
|
|
146833
147202
|
source.path ?? "",
|
|
146834
147203
|
source.symbol ?? ""
|
|
146835
147204
|
].join("\n").toLowerCase();
|
|
146836
|
-
const matches = tokens.filter((token) =>
|
|
147205
|
+
const matches = tokens.filter((token) => text2.includes(token)).length;
|
|
146837
147206
|
if (matches >= 2) return 40;
|
|
146838
147207
|
if (matches === 1) return 24;
|
|
146839
147208
|
return 0;
|
|
@@ -146872,8 +147241,8 @@ function lensPathCandidates(lens) {
|
|
|
146872
147241
|
}
|
|
146873
147242
|
function scoreLensSource(source, lens, task) {
|
|
146874
147243
|
const tokens = tokenize3(task ?? "");
|
|
146875
|
-
const
|
|
146876
|
-
return pathKindScore(source.path ?? "", lens) + tokenScore(
|
|
147244
|
+
const text2 = [source.title, source.type, source.path ?? "", source.symbol ?? ""].join("\n");
|
|
147245
|
+
return pathKindScore(source.path ?? "", lens) + tokenScore(text2, tokens) + sourceTaskMatchScore(source, task);
|
|
146877
147246
|
}
|
|
146878
147247
|
function rankLensSources(sources, lens, task) {
|
|
146879
147248
|
return [...sources].map((source, index) => ({
|
|
@@ -147116,7 +147485,7 @@ function requiredText(data, key) {
|
|
|
147116
147485
|
}
|
|
147117
147486
|
return value.trim();
|
|
147118
147487
|
}
|
|
147119
|
-
function
|
|
147488
|
+
function optionalText5(data, key) {
|
|
147120
147489
|
const value = data[key];
|
|
147121
147490
|
if (value === void 0 || value === null || value === "") return void 0;
|
|
147122
147491
|
if (typeof value !== "string") throw new Error("workflow frontmatter field " + key + " must be text");
|
|
@@ -147159,11 +147528,11 @@ function phaseFromValue(value, index) {
|
|
|
147159
147528
|
}
|
|
147160
147529
|
const data = value;
|
|
147161
147530
|
const title = requiredText(data, "title");
|
|
147162
|
-
const phaseId =
|
|
147531
|
+
const phaseId = optionalText5(data, "id") ?? slug(title) + "-" + (index + 1);
|
|
147163
147532
|
return {
|
|
147164
147533
|
id: phaseId,
|
|
147165
147534
|
title,
|
|
147166
|
-
instructions:
|
|
147535
|
+
instructions: optionalText5(data, "instructions") ?? "",
|
|
147167
147536
|
branches: optionalStringArray(data, "branches"),
|
|
147168
147537
|
expectedOutputs: optionalStringArray(data, "expectedOutputs"),
|
|
147169
147538
|
verificationGates: optionalStringArray(data, "verificationGates")
|
|
@@ -147272,7 +147641,7 @@ function parsedWorkflow(data, body, input) {
|
|
|
147272
147641
|
id: requiredText(data, "id"),
|
|
147273
147642
|
workspaceId: input.workspaceId,
|
|
147274
147643
|
title: requiredText(data, "title"),
|
|
147275
|
-
description:
|
|
147644
|
+
description: optionalText5(data, "description") ?? "",
|
|
147276
147645
|
status: optionalStatus(data),
|
|
147277
147646
|
version: optionalNumber(data, "version", 1),
|
|
147278
147647
|
taskLenses: optionalStringArray(data, "taskLenses"),
|
|
@@ -147291,9 +147660,9 @@ function parsedWorkflow(data, body, input) {
|
|
|
147291
147660
|
sourcePath: normalizeSourcePath(input.sourcePath),
|
|
147292
147661
|
sourceHash: "",
|
|
147293
147662
|
contentHash: input.contentHash,
|
|
147294
|
-
createdAt:
|
|
147295
|
-
updatedAt:
|
|
147296
|
-
...
|
|
147663
|
+
createdAt: optionalText5(data, "createdAt") ?? now2(),
|
|
147664
|
+
updatedAt: optionalText5(data, "updatedAt") ?? now2(),
|
|
147665
|
+
...optionalText5(data, "importedFrom") ? { importedFrom: optionalText5(data, "importedFrom") } : {}
|
|
147297
147666
|
};
|
|
147298
147667
|
if (candidate.phases.length === 0) {
|
|
147299
147668
|
throw new Error("workflow must contain at least one phase or a non-empty body");
|
|
@@ -147392,11 +147761,11 @@ async function syncCanonicalWorkflows(workspace) {
|
|
|
147392
147761
|
return { workflows, errors };
|
|
147393
147762
|
}
|
|
147394
147763
|
function inferTaskLenses(value) {
|
|
147395
|
-
const
|
|
147396
|
-
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) =>
|
|
147764
|
+
const text2 = value.toLowerCase();
|
|
147765
|
+
return Object.entries(LENS_TERMS).filter(([, terms]) => terms.some((term) => text2.includes(term))).map(([lens]) => lens);
|
|
147397
147766
|
}
|
|
147398
147767
|
function taskScore(workflow, task) {
|
|
147399
|
-
const
|
|
147768
|
+
const text2 = task.toLowerCase();
|
|
147400
147769
|
let score = 0;
|
|
147401
147770
|
const reasons = [];
|
|
147402
147771
|
const matchedLenses = /* @__PURE__ */ new Set();
|
|
@@ -147663,7 +148032,31 @@ async function recordWorkflowRun(input) {
|
|
|
147663
148032
|
throw new Error("Workflow was not found for this workspace");
|
|
147664
148033
|
}
|
|
147665
148034
|
if (!input.run.task.trim()) throw new Error("Workflow run task is required");
|
|
147666
|
-
|
|
148035
|
+
const run = store.recordRun(input.run);
|
|
148036
|
+
const kind = run.outcome === "passed" && run.verificationVerdict === "passed" ? "verification-passed" : run.outcome === "failed" || run.verificationVerdict === "failed" ? "verification-failed" : void 0;
|
|
148037
|
+
if (!kind) return run;
|
|
148038
|
+
const evidence = /* @__PURE__ */ new Map();
|
|
148039
|
+
evidence.set(workflow.id, "workflow");
|
|
148040
|
+
for (const reference of run.selectedEvidence) {
|
|
148041
|
+
const match2 = /^(claim|durable):(.+)$/.exec(reference);
|
|
148042
|
+
if (!match2) continue;
|
|
148043
|
+
evidence.set(match2[2], match2[1] === "claim" ? "claim" : "durable-memory");
|
|
148044
|
+
}
|
|
148045
|
+
const outcomes = new OutcomeStore();
|
|
148046
|
+
await outcomes.init(workflowStoreDataDir(input.workspace));
|
|
148047
|
+
for (const [candidateId, candidateKind] of evidence) {
|
|
148048
|
+
outcomes.record({
|
|
148049
|
+
projectId: run.projectId,
|
|
148050
|
+
candidateKind,
|
|
148051
|
+
candidateId,
|
|
148052
|
+
kind,
|
|
148053
|
+
sourceRef: "workflow-run:" + run.id,
|
|
148054
|
+
...run.startingSnapshotId ? { snapshotId: run.startingSnapshotId } : {},
|
|
148055
|
+
...run.failureReason ? { detail: run.failureReason } : {},
|
|
148056
|
+
observedAt: run.completedAt ?? run.startedAt
|
|
148057
|
+
});
|
|
148058
|
+
}
|
|
148059
|
+
return run;
|
|
147667
148060
|
}
|
|
147668
148061
|
async function selectWorkspaceWorkflows(input) {
|
|
147669
148062
|
const synced = await syncCanonicalWorkflows(input.workspace);
|
|
@@ -147688,6 +148081,7 @@ var init_workflows2 = __esm({
|
|
|
147688
148081
|
init_workflow_sync();
|
|
147689
148082
|
init_workspace();
|
|
147690
148083
|
init_workflow_store();
|
|
148084
|
+
init_outcome_store();
|
|
147691
148085
|
init_task_lens();
|
|
147692
148086
|
KNOWN_AGENTS = [
|
|
147693
148087
|
"windsurf",
|
|
@@ -150711,7 +151105,7 @@ function evidenceScore2(obs) {
|
|
|
150711
151105
|
}
|
|
150712
151106
|
function scoreForPacket(obs, queryTokens, referenceTime, broadMemoryQuery) {
|
|
150713
151107
|
let score = 0;
|
|
150714
|
-
const
|
|
151108
|
+
const text2 = normalizeText3([
|
|
150715
151109
|
obs.title,
|
|
150716
151110
|
obs.narrative,
|
|
150717
151111
|
obs.entityName,
|
|
@@ -150720,15 +151114,15 @@ function scoreForPacket(obs, queryTokens, referenceTime, broadMemoryQuery) {
|
|
|
150720
151114
|
...obs.relatedEntities ?? [],
|
|
150721
151115
|
...obs.relatedCommits ?? []
|
|
150722
151116
|
].join(" "));
|
|
150723
|
-
const matchingTokens = queryTokens.filter((token) =>
|
|
151117
|
+
const matchingTokens = queryTokens.filter((token) => text2.includes(token));
|
|
150724
151118
|
score += matchingTokens.length * 4;
|
|
150725
151119
|
if (queryTokens.length > 0 && matchingTokens.length === 0) {
|
|
150726
151120
|
score -= 8;
|
|
150727
151121
|
}
|
|
150728
|
-
if (broadMemoryQuery && /memorix|memcode|memory-(?:graph|injection|runtime|quality|formation)|graph-context/.test(
|
|
151122
|
+
if (broadMemoryQuery && /memorix|memcode|memory-(?:graph|injection|runtime|quality|formation)|graph-context/.test(text2)) {
|
|
150729
151123
|
score += 8;
|
|
150730
151124
|
}
|
|
150731
|
-
if (/\bmemory[- ]?game\b|e2e-test\/memory-game|team-handoff/.test(
|
|
151125
|
+
if (/\bmemory[- ]?game\b|e2e-test\/memory-game|team-handoff/.test(text2)) {
|
|
150732
151126
|
score -= broadMemoryQuery ? 12 : 4;
|
|
150733
151127
|
}
|
|
150734
151128
|
score += obs.valueCategory === "core" ? 6 : 0;
|
|
@@ -153458,8 +153852,8 @@ async function extractFactsWithLLM(narrative, title, existingFacts) {
|
|
|
153458
153852
|
Content: ${narrative}${existingFacts.length > 0 ? `
|
|
153459
153853
|
Already known facts (don't repeat): ${existingFacts.join("; ")}` : ""}`;
|
|
153460
153854
|
const response = await callLLM2(LLM_EXTRACT_PROMPT, input);
|
|
153461
|
-
const
|
|
153462
|
-
const jsonMatch =
|
|
153855
|
+
const text2 = response.content.trim();
|
|
153856
|
+
const jsonMatch = text2.match(/\{[\s\S]*\}/);
|
|
153463
153857
|
if (!jsonMatch) return [];
|
|
153464
153858
|
const parsed = JSON.parse(jsonMatch[0]);
|
|
153465
153859
|
const facts = parsed.facts;
|
|
@@ -153712,8 +154106,8 @@ Facts: ${extracted.facts.join("; ")}
|
|
|
153712
154106
|
EXISTING MEMORIES:
|
|
153713
154107
|
${existingMemories.map((m2) => `[ID:${m2.id}] ${m2.title} | ${m2.content} | Facts: ${m2.facts}`).join("\n")}`;
|
|
153714
154108
|
const response = await callLLM2(LLM_RESOLVE_PROMPT, input);
|
|
153715
|
-
const
|
|
153716
|
-
const jsonMatch =
|
|
154109
|
+
const text2 = response.content.trim();
|
|
154110
|
+
const jsonMatch = text2.match(/\{[\s\S]*\}/);
|
|
153717
154111
|
if (!jsonMatch) return null;
|
|
153718
154112
|
const parsed = JSON.parse(jsonMatch[0]);
|
|
153719
154113
|
const action = parsed.action?.toUpperCase();
|
|
@@ -154590,8 +154984,8 @@ function isNoiseObservation(obs) {
|
|
|
154590
154984
|
return NOISE_PATTERNS2.some((pattern) => pattern.test(title)) || isCommandTrace(obs);
|
|
154591
154985
|
}
|
|
154592
154986
|
function isSystemSelfObservation(obs) {
|
|
154593
|
-
const
|
|
154594
|
-
return SYSTEM_SELF_PATTERNS.some((pattern) => pattern.test(
|
|
154987
|
+
const text2 = stringifyObservation(obs, false);
|
|
154988
|
+
return SYSTEM_SELF_PATTERNS.some((pattern) => pattern.test(text2));
|
|
154595
154989
|
}
|
|
154596
154990
|
function readerForAlias(reader, aliases, observation) {
|
|
154597
154991
|
if (!reader) return void 0;
|
|
@@ -154614,8 +155008,8 @@ function continuationTaskTokens(task) {
|
|
|
154614
155008
|
function continuationScore(observation, projectTokens, task) {
|
|
154615
155009
|
let score = scoreObservationForSessionContext(observation, projectTokens);
|
|
154616
155010
|
if (observation.type === "session-request" || observation.type === "what-changed") score += 1;
|
|
154617
|
-
const
|
|
154618
|
-
const matches = continuationTaskTokens(task).filter((token) =>
|
|
155011
|
+
const text2 = stringifyObservation(observation);
|
|
155012
|
+
const matches = continuationTaskTokens(task).filter((token) => text2.includes(token)).length;
|
|
154619
155013
|
score += Math.min(matches, 2) * 2;
|
|
154620
155014
|
return score;
|
|
154621
155015
|
}
|
|
@@ -154649,8 +155043,8 @@ async function getSessionResumeBrief(projectId, task, reader) {
|
|
|
154649
155043
|
memories
|
|
154650
155044
|
};
|
|
154651
155045
|
}
|
|
154652
|
-
function compactResumeText(
|
|
154653
|
-
const normalized =
|
|
155046
|
+
function compactResumeText(text2, limit2) {
|
|
155047
|
+
const normalized = text2.replace(/\s+/g, " ").trim();
|
|
154654
155048
|
return normalized.length <= limit2 ? normalized : `${normalized.slice(0, Math.max(0, limit2 - 3)).trimEnd()}...`;
|
|
154655
155049
|
}
|
|
154656
155050
|
function renderSessionResumeCard(brief) {
|
|
@@ -154672,11 +155066,11 @@ function renderSessionResumeCard(brief) {
|
|
|
154672
155066
|
}
|
|
154673
155067
|
function scoreObservationForSessionContext(obs, projectTokens, now3 = Date.now()) {
|
|
154674
155068
|
let score = TYPE_WEIGHTS2[obs.type] ?? 1;
|
|
154675
|
-
const
|
|
155069
|
+
const text2 = stringifyObservation(obs);
|
|
154676
155070
|
const ageDays = Math.max(0, (now3 - new Date(obs.createdAt).getTime()) / (1e3 * 60 * 60 * 24));
|
|
154677
155071
|
score += Math.max(0.2, 2.5 - Math.min(ageDays, 45) * 0.05);
|
|
154678
155072
|
if (projectTokens.length > 0) {
|
|
154679
|
-
const matchingTokens = projectTokens.filter((token) =>
|
|
155073
|
+
const matchingTokens = projectTokens.filter((token) => text2.includes(token));
|
|
154680
155074
|
if (matchingTokens.length > 0) {
|
|
154681
155075
|
score += 2 + matchingTokens.length * 0.6;
|
|
154682
155076
|
} else if ((obs.filesModified?.length ?? 0) > 0) {
|
|
@@ -154992,7 +155386,7 @@ var owner_exports = {};
|
|
|
154992
155386
|
__export(owner_exports, {
|
|
154993
155387
|
resolveLocalMemoryOwner: () => resolveLocalMemoryOwner
|
|
154994
155388
|
});
|
|
154995
|
-
import { randomUUID as
|
|
155389
|
+
import { randomUUID as randomUUID11 } from "crypto";
|
|
154996
155390
|
import { promises as fs17 } from "fs";
|
|
154997
155391
|
import path25 from "path";
|
|
154998
155392
|
function ownerPath(dataDir) {
|
|
@@ -155022,7 +155416,7 @@ async function resolveLocalMemoryOwner(dataDir, options = {}) {
|
|
|
155022
155416
|
await fs17.mkdir(path25.dirname(filePath), { recursive: true });
|
|
155023
155417
|
const created = {
|
|
155024
155418
|
version: 1,
|
|
155025
|
-
id: "local-" +
|
|
155419
|
+
id: "local-" + randomUUID11(),
|
|
155026
155420
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
155027
155421
|
};
|
|
155028
155422
|
try {
|
|
@@ -155045,8 +155439,8 @@ var init_owner = __esm({
|
|
|
155045
155439
|
});
|
|
155046
155440
|
|
|
155047
155441
|
// src/memory/long-term-store.ts
|
|
155048
|
-
import { randomUUID as
|
|
155049
|
-
function
|
|
155442
|
+
import { randomUUID as randomUUID12 } from "crypto";
|
|
155443
|
+
function optionalText6(value) {
|
|
155050
155444
|
return typeof value === "string" && value.trim() ? value : void 0;
|
|
155051
155445
|
}
|
|
155052
155446
|
function arrayValue2(value) {
|
|
@@ -155071,17 +155465,17 @@ function rowToMemory(row) {
|
|
|
155071
155465
|
content: row.content,
|
|
155072
155466
|
facts: arrayValue2(row.factsJson),
|
|
155073
155467
|
tags: arrayValue2(row.tagsJson),
|
|
155074
|
-
...
|
|
155468
|
+
...optionalText6(row.applicability) ? { applicability: row.applicability } : {},
|
|
155075
155469
|
origin: row.origin,
|
|
155076
155470
|
createdAt: row.createdAt,
|
|
155077
155471
|
updatedAt: row.updatedAt,
|
|
155078
|
-
...
|
|
155079
|
-
...
|
|
155080
|
-
...
|
|
155081
|
-
...
|
|
155082
|
-
...
|
|
155472
|
+
...optionalText6(row.qualifiedAt) ? { qualifiedAt: row.qualifiedAt } : {},
|
|
155473
|
+
...optionalText6(row.approvedAt) ? { approvedAt: row.approvedAt } : {},
|
|
155474
|
+
...optionalText6(row.archivedAt) ? { archivedAt: row.archivedAt } : {},
|
|
155475
|
+
...optionalText6(row.supersededBy) ? { supersededBy: row.supersededBy } : {},
|
|
155476
|
+
...optionalText6(row.lastValidatedAt) ? { lastValidatedAt: row.lastValidatedAt } : {},
|
|
155083
155477
|
accessCount: Number(row.accessCount ?? 0),
|
|
155084
|
-
...
|
|
155478
|
+
...optionalText6(row.lastAccessedAt) ? { lastAccessedAt: row.lastAccessedAt } : {}
|
|
155085
155479
|
};
|
|
155086
155480
|
}
|
|
155087
155481
|
function rowToEvidence2(row) {
|
|
@@ -155091,8 +155485,8 @@ function rowToEvidence2(row) {
|
|
|
155091
155485
|
kind: row.kind,
|
|
155092
155486
|
referenceId: row.referenceId,
|
|
155093
155487
|
relation: row.relation,
|
|
155094
|
-
...
|
|
155095
|
-
...
|
|
155488
|
+
...optionalText6(row.locator) ? { locator: row.locator } : {},
|
|
155489
|
+
...optionalText6(row.capturedHash) ? { capturedHash: row.capturedHash } : {},
|
|
155096
155490
|
createdAt: row.createdAt
|
|
155097
155491
|
};
|
|
155098
155492
|
}
|
|
@@ -155101,9 +155495,9 @@ function rowToEvent2(row) {
|
|
|
155101
155495
|
id: row.id,
|
|
155102
155496
|
memoryId: row.memoryId,
|
|
155103
155497
|
kind: row.kind,
|
|
155104
|
-
...
|
|
155105
|
-
...
|
|
155106
|
-
...
|
|
155498
|
+
...optionalText6(row.fromState) ? { fromState: row.fromState } : {},
|
|
155499
|
+
...optionalText6(row.toState) ? { toState: row.toState } : {},
|
|
155500
|
+
...optionalText6(row.detail) ? { detail: row.detail } : {},
|
|
155107
155501
|
createdAt: row.createdAt
|
|
155108
155502
|
};
|
|
155109
155503
|
}
|
|
@@ -155205,7 +155599,7 @@ var init_long_term_store = __esm({
|
|
|
155205
155599
|
}
|
|
155206
155600
|
insertEvidence(input) {
|
|
155207
155601
|
const evidence = {
|
|
155208
|
-
id:
|
|
155602
|
+
id: randomUUID12(),
|
|
155209
155603
|
...input,
|
|
155210
155604
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
155211
155605
|
};
|
|
@@ -155232,7 +155626,7 @@ var init_long_term_store = __esm({
|
|
|
155232
155626
|
}
|
|
155233
155627
|
recordEvent(input) {
|
|
155234
155628
|
const event = {
|
|
155235
|
-
id:
|
|
155629
|
+
id: randomUUID12(),
|
|
155236
155630
|
...input,
|
|
155237
155631
|
createdAt: input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
155238
155632
|
};
|
|
@@ -155320,7 +155714,7 @@ __export(long_term_exports, {
|
|
|
155320
155714
|
selectLongTermMemoriesForTask: () => selectLongTermMemoriesForTask,
|
|
155321
155715
|
supersedeLongTermMemory: () => supersedeLongTermMemory
|
|
155322
155716
|
});
|
|
155323
|
-
import { randomUUID as
|
|
155717
|
+
import { randomUUID as randomUUID13 } from "crypto";
|
|
155324
155718
|
function isOneOf(value, values) {
|
|
155325
155719
|
return typeof value === "string" && values.includes(value);
|
|
155326
155720
|
}
|
|
@@ -155502,7 +155896,7 @@ async function createManualLongTermMemory(input) {
|
|
|
155502
155896
|
const owner = await resolveLocalMemoryOwner(input.dataDir, { create: true });
|
|
155503
155897
|
if (!owner) throw new Error("Memorix could not resolve a local memory owner.");
|
|
155504
155898
|
assertScope(input.scope);
|
|
155505
|
-
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" +
|
|
155899
|
+
const evidence = input.scope === "user" ? [{ kind: "user", referenceId: owner.id, relation: "user-confirmed" }] : [{ kind: "manual", referenceId: "manual:" + randomUUID13(), relation: "supports" }];
|
|
155506
155900
|
return createLongTermMemoryWithDataDir({
|
|
155507
155901
|
dataDir: input.dataDir,
|
|
155508
155902
|
originProjectId: input.projectId,
|
|
@@ -155557,7 +155951,7 @@ async function createLongTermMemoryWithDataDir(input) {
|
|
|
155557
155951
|
assertPortableEvidence(input.scope, portability, evidenceInputs);
|
|
155558
155952
|
const now3 = (/* @__PURE__ */ new Date()).toISOString();
|
|
155559
155953
|
const memory = {
|
|
155560
|
-
id:
|
|
155954
|
+
id: randomUUID13(),
|
|
155561
155955
|
originProjectId: compactText2(input.originProjectId, "origin project id", 1e3),
|
|
155562
155956
|
ownerId: compactText2(input.ownerId, "owner id", 160),
|
|
155563
155957
|
scope: input.scope,
|
|
@@ -155808,12 +156202,99 @@ var init_long_term = __esm({
|
|
|
155808
156202
|
}
|
|
155809
156203
|
});
|
|
155810
156204
|
|
|
156205
|
+
// src/knowledge/governor.ts
|
|
156206
|
+
function clampRelevance(value) {
|
|
156207
|
+
if (!Number.isFinite(value)) return 0;
|
|
156208
|
+
return Math.max(0, Math.min(1, value));
|
|
156209
|
+
}
|
|
156210
|
+
function classify(candidate) {
|
|
156211
|
+
const freshness = candidate.freshness ?? "unknown";
|
|
156212
|
+
const trust = candidate.trust ?? "historical";
|
|
156213
|
+
const quality = candidate.quality ?? "probationary";
|
|
156214
|
+
const conflict = candidate.conflict ?? "none";
|
|
156215
|
+
if (!candidate.scopeAllowed) {
|
|
156216
|
+
return { disposition: "exclude", reasons: ["scope-forbidden"] };
|
|
156217
|
+
}
|
|
156218
|
+
if (conflict === "confirmed") {
|
|
156219
|
+
return { disposition: "exclude", reasons: ["confirmed-conflict"] };
|
|
156220
|
+
}
|
|
156221
|
+
if (quality === "blocked") {
|
|
156222
|
+
return { disposition: "exclude", reasons: ["blocked-quality"] };
|
|
156223
|
+
}
|
|
156224
|
+
if (quality === "degraded") {
|
|
156225
|
+
return { disposition: "defer", reasons: ["degraded-quality"] };
|
|
156226
|
+
}
|
|
156227
|
+
if (freshness === "stale") {
|
|
156228
|
+
return { disposition: "defer", reasons: ["stale-evidence"] };
|
|
156229
|
+
}
|
|
156230
|
+
const reasons = [];
|
|
156231
|
+
let disposition = "include";
|
|
156232
|
+
if (freshness === "unknown") {
|
|
156233
|
+
disposition = "compact";
|
|
156234
|
+
reasons.push("unknown-freshness");
|
|
156235
|
+
}
|
|
156236
|
+
if (conflict === "possible") {
|
|
156237
|
+
disposition = "compact";
|
|
156238
|
+
reasons.push("possible-conflict");
|
|
156239
|
+
}
|
|
156240
|
+
if (quality === "probationary") {
|
|
156241
|
+
disposition = "compact";
|
|
156242
|
+
reasons.push("probationary-evidence");
|
|
156243
|
+
}
|
|
156244
|
+
if (disposition === "include" && freshness === "current" && trust === "source-backed") {
|
|
156245
|
+
reasons.push("current-source-backed-evidence");
|
|
156246
|
+
} else if (reasons.length === 0) {
|
|
156247
|
+
reasons.push("relevant-evidence");
|
|
156248
|
+
}
|
|
156249
|
+
return { disposition, reasons };
|
|
156250
|
+
}
|
|
156251
|
+
function priority(decision) {
|
|
156252
|
+
const dispositionWeight = {
|
|
156253
|
+
include: 3,
|
|
156254
|
+
compact: 2,
|
|
156255
|
+
defer: 1,
|
|
156256
|
+
exclude: 0
|
|
156257
|
+
};
|
|
156258
|
+
const evidence = Math.min(3, decision.candidate.evidenceCount ?? 0) / 10;
|
|
156259
|
+
return dispositionWeight[decision.disposition] + clampRelevance(decision.candidate.relevance) + evidence;
|
|
156260
|
+
}
|
|
156261
|
+
function governContextCandidates(candidates, maxTokens) {
|
|
156262
|
+
const safeBudget = Math.max(0, Math.floor(maxTokens));
|
|
156263
|
+
const decisions = candidates.map((candidate) => ({ candidate, ...classify(candidate) }));
|
|
156264
|
+
const eligible = decisions.filter((decision) => decision.disposition === "include" || decision.disposition === "compact").sort((left, right) => priority(right) - priority(left));
|
|
156265
|
+
let usedTokens = 0;
|
|
156266
|
+
for (const decision of eligible) {
|
|
156267
|
+
const tokens = Math.max(0, Math.ceil(decision.candidate.estimatedTokens));
|
|
156268
|
+
if (usedTokens + tokens <= safeBudget) {
|
|
156269
|
+
usedTokens += tokens;
|
|
156270
|
+
continue;
|
|
156271
|
+
}
|
|
156272
|
+
decision.disposition = "defer";
|
|
156273
|
+
decision.reasons = [...decision.reasons, "token-budget"];
|
|
156274
|
+
}
|
|
156275
|
+
const delivered = decisions.filter((decision) => decision.disposition === "include" || decision.disposition === "compact");
|
|
156276
|
+
const mode = delivered.length === 0 ? "abstain" : delivered.some((decision) => decision.disposition === "include") ? "workset" : "card";
|
|
156277
|
+
const cautions = [...new Set(decisions.filter((decision) => decision.disposition !== "include").flatMap((decision) => decision.reasons))];
|
|
156278
|
+
return {
|
|
156279
|
+
mode,
|
|
156280
|
+
budget: { maxTokens: safeBudget, usedTokens },
|
|
156281
|
+
decisions,
|
|
156282
|
+
cautions: cautions.length > 0 ? cautions : ["no-qualified-evidence"]
|
|
156283
|
+
};
|
|
156284
|
+
}
|
|
156285
|
+
var init_governor = __esm({
|
|
156286
|
+
"src/knowledge/governor.ts"() {
|
|
156287
|
+
"use strict";
|
|
156288
|
+
init_esm_shims();
|
|
156289
|
+
}
|
|
156290
|
+
});
|
|
156291
|
+
|
|
155811
156292
|
// src/knowledge/workset.ts
|
|
155812
156293
|
function unique(values) {
|
|
155813
156294
|
return [...new Set(values.filter(Boolean))];
|
|
155814
156295
|
}
|
|
155815
|
-
function short(
|
|
155816
|
-
const safe = sanitizeCredentials(
|
|
156296
|
+
function short(text2, budget = 28) {
|
|
156297
|
+
const safe = sanitizeCredentials(text2).replace(/\s+/g, " ").trim();
|
|
155817
156298
|
return countTextTokens(safe) <= budget ? safe : truncateToTokenBudget(safe, budget);
|
|
155818
156299
|
}
|
|
155819
156300
|
function claimAssertion(claim) {
|
|
@@ -155944,6 +156425,65 @@ function receiptOmissions(omitted, hiddenCautionMemoryCount) {
|
|
|
155944
156425
|
function scheduledActions(cautions) {
|
|
155945
156426
|
return cautions.filter((caution) => caution.kind === "codegraph-refresh-queued").map((caution) => short(caution.message, 28));
|
|
155946
156427
|
}
|
|
156428
|
+
function isGovernedDelivery(disposition) {
|
|
156429
|
+
return disposition === "include" || disposition === "compact";
|
|
156430
|
+
}
|
|
156431
|
+
function governOptionalArtifacts(input) {
|
|
156432
|
+
const candidates = [
|
|
156433
|
+
...input.reliableMemory.map((memory, index) => ({
|
|
156434
|
+
kind: "memory",
|
|
156435
|
+
id: "memory:" + memory.id,
|
|
156436
|
+
estimatedTokens: 10,
|
|
156437
|
+
relevance: Math.max(0.2, 0.9 - index * 0.1),
|
|
156438
|
+
scopeAllowed: true,
|
|
156439
|
+
freshness: freshnessForMemory(memory.status),
|
|
156440
|
+
trust: "historical",
|
|
156441
|
+
quality: memory.status === "current" ? "verified" : "degraded"
|
|
156442
|
+
})),
|
|
156443
|
+
...input.claims.map((claim, index) => ({
|
|
156444
|
+
kind: "claim",
|
|
156445
|
+
id: "claim:" + claim.id,
|
|
156446
|
+
estimatedTokens: 12,
|
|
156447
|
+
relevance: Math.max(0.2, 0.95 - index * 0.1),
|
|
156448
|
+
scopeAllowed: true,
|
|
156449
|
+
freshness: claim.status === "active" ? "current" : "unknown",
|
|
156450
|
+
trust: "source-backed",
|
|
156451
|
+
quality: claim.reviewState === "approved" ? "verified" : "probationary",
|
|
156452
|
+
conflict: claim.status === "disputed" ? "confirmed" : "none",
|
|
156453
|
+
evidenceCount: claim.evidenceRefs.length
|
|
156454
|
+
})),
|
|
156455
|
+
...input.durableMemory.map((memory, index) => ({
|
|
156456
|
+
kind: "durable-memory",
|
|
156457
|
+
id: "durable:" + memory.id,
|
|
156458
|
+
estimatedTokens: 14,
|
|
156459
|
+
relevance: Math.max(0.2, 0.8 - index * 0.1),
|
|
156460
|
+
scopeAllowed: true,
|
|
156461
|
+
freshness: memory.state === "approved" ? "current" : "unknown",
|
|
156462
|
+
trust: "source-backed",
|
|
156463
|
+
quality: memory.quality,
|
|
156464
|
+
evidenceCount: memory.evidenceRefs.length
|
|
156465
|
+
})),
|
|
156466
|
+
...input.workflows.map((workflow, index) => ({
|
|
156467
|
+
kind: "workflow",
|
|
156468
|
+
id: "workflow:" + workflow.id,
|
|
156469
|
+
estimatedTokens: 14,
|
|
156470
|
+
relevance: Math.max(0.2, 0.85 - index * 0.1),
|
|
156471
|
+
scopeAllowed: true,
|
|
156472
|
+
freshness: "current",
|
|
156473
|
+
trust: "source-backed",
|
|
156474
|
+
quality: "verified"
|
|
156475
|
+
}))
|
|
156476
|
+
];
|
|
156477
|
+
const plan = governContextCandidates(candidates, Number.MAX_SAFE_INTEGER);
|
|
156478
|
+
const permitted = new Set(plan.decisions.filter((decision) => isGovernedDelivery(decision.disposition)).map((decision) => decision.candidate.id));
|
|
156479
|
+
return {
|
|
156480
|
+
plan,
|
|
156481
|
+
reliableMemory: input.reliableMemory.filter((memory) => permitted.has("memory:" + memory.id)),
|
|
156482
|
+
claims: input.claims.filter((claim) => permitted.has("claim:" + claim.id)),
|
|
156483
|
+
durableMemory: input.durableMemory.filter((memory) => permitted.has("durable:" + memory.id)),
|
|
156484
|
+
workflows: input.workflows.filter((workflow) => permitted.has("workflow:" + workflow.id))
|
|
156485
|
+
};
|
|
156486
|
+
}
|
|
155947
156487
|
function renderTaskWorksetPrompt(input) {
|
|
155948
156488
|
const maxTokens = input.budget?.maxTokens ?? 180;
|
|
155949
156489
|
const omitted = [];
|
|
@@ -156071,6 +156611,56 @@ function renderTaskWorksetPrompt(input) {
|
|
|
156071
156611
|
trust: "source-backed"
|
|
156072
156612
|
});
|
|
156073
156613
|
}
|
|
156614
|
+
if (input.codeEvolution && input.codeEvolution.changes.length > 0) {
|
|
156615
|
+
appendLine(lines, "", maxTokens, omitted, "code-evolution-heading");
|
|
156616
|
+
appendLine(lines, "Code changes since prior scan", maxTokens, omitted, "code-evolution-heading");
|
|
156617
|
+
for (const change of input.codeEvolution.changes.slice(0, 3)) {
|
|
156618
|
+
appendLine(
|
|
156619
|
+
lines,
|
|
156620
|
+
"- " + change.kind + ": " + change.path,
|
|
156621
|
+
maxTokens,
|
|
156622
|
+
omitted,
|
|
156623
|
+
"code-evolution-change",
|
|
156624
|
+
selected,
|
|
156625
|
+
{
|
|
156626
|
+
kind: "code-state",
|
|
156627
|
+
id: "snapshot:" + input.codeEvolution.toSnapshotId,
|
|
156628
|
+
reason: "exact file hash change between complete CodeGraph snapshots",
|
|
156629
|
+
freshness: "current",
|
|
156630
|
+
trust: "source-backed"
|
|
156631
|
+
}
|
|
156632
|
+
);
|
|
156633
|
+
}
|
|
156634
|
+
for (const path36 of input.codeEvolution.directlyConnectedPaths.slice(0, 2)) {
|
|
156635
|
+
appendLine(
|
|
156636
|
+
lines,
|
|
156637
|
+
"- connected now: " + path36,
|
|
156638
|
+
maxTokens,
|
|
156639
|
+
omitted,
|
|
156640
|
+
"code-evolution-impact",
|
|
156641
|
+
selected,
|
|
156642
|
+
{
|
|
156643
|
+
kind: "code-state",
|
|
156644
|
+
id: "snapshot:" + input.codeEvolution.toSnapshotId,
|
|
156645
|
+
reason: "bounded current CodeGraph impact relation",
|
|
156646
|
+
freshness: "current",
|
|
156647
|
+
trust: "derived"
|
|
156648
|
+
}
|
|
156649
|
+
);
|
|
156650
|
+
}
|
|
156651
|
+
if ((input.codeEvolution.affectedMemoryCount ?? 0) > 0) {
|
|
156652
|
+
appendLine(
|
|
156653
|
+
lines,
|
|
156654
|
+
"- " + input.codeEvolution.affectedMemoryCount + " stored memory link(s) reference this changed code; reread source before relying on their conclusions.",
|
|
156655
|
+
maxTokens,
|
|
156656
|
+
omitted,
|
|
156657
|
+
"code-evolution-stale-memory"
|
|
156658
|
+
);
|
|
156659
|
+
}
|
|
156660
|
+
if (input.codeEvolution.truncated) {
|
|
156661
|
+
appendLine(lines, "- More connected files exist; inspect CodeGraph before assuming complete impact.", maxTokens, omitted, "code-evolution-truncated");
|
|
156662
|
+
}
|
|
156663
|
+
}
|
|
156074
156664
|
if (input.semanticCode && (input.semanticCode.entryPoints.length > 0 || input.semanticCode.relations.length > 0)) {
|
|
156075
156665
|
appendLine(lines, "", maxTokens, omitted, "semantic-code-heading");
|
|
156076
156666
|
appendLine(lines, "Semantic code outline", maxTokens, omitted, "semantic-code-heading");
|
|
@@ -156261,6 +156851,17 @@ async function buildTaskWorkset(input) {
|
|
|
156261
156851
|
}));
|
|
156262
156852
|
let durableMemory = [];
|
|
156263
156853
|
let durableEvidence = [];
|
|
156854
|
+
let outcomeStore;
|
|
156855
|
+
try {
|
|
156856
|
+
outcomeStore = new OutcomeStore();
|
|
156857
|
+
await outcomeStore.init(input.dataDir);
|
|
156858
|
+
} catch {
|
|
156859
|
+
}
|
|
156860
|
+
const claimQuality = outcomeStore ? outcomeStore.latestForCandidates(input.projectId, "claim", claims.map((claim) => claim.id)) : /* @__PURE__ */ new Map();
|
|
156861
|
+
for (const claim of claims) {
|
|
156862
|
+
const outcomeQuality = qualityFromOutcome(claimQuality.get(claim.id));
|
|
156863
|
+
if (outcomeQuality === "degraded") claim.reviewState = "needs-review";
|
|
156864
|
+
}
|
|
156264
156865
|
if (task) {
|
|
156265
156866
|
try {
|
|
156266
156867
|
const selected = await selectLongTermMemoriesForTask({
|
|
@@ -156271,11 +156872,13 @@ async function buildTaskWorkset(input) {
|
|
|
156271
156872
|
...input.reader?.isTeamMember ? { isTeamMember: true } : {},
|
|
156272
156873
|
limit: 3
|
|
156273
156874
|
});
|
|
156875
|
+
const durableQuality = outcomeStore ? outcomeStore.latestForCandidates(input.projectId, "durable-memory", selected.map((item) => item.memory.id)) : /* @__PURE__ */ new Map();
|
|
156274
156876
|
durableMemory = selected.map((item) => ({
|
|
156275
156877
|
id: item.memory.id,
|
|
156276
156878
|
kind: item.memory.kind,
|
|
156277
156879
|
scope: item.memory.scope,
|
|
156278
156880
|
state: item.memory.state,
|
|
156881
|
+
quality: qualityFromOutcome(durableQuality.get(item.memory.id)) ?? (item.memory.state === "approved" ? "verified" : "probationary"),
|
|
156279
156882
|
title: item.memory.title,
|
|
156280
156883
|
summary: renderLongTermMemorySummary(item.memory, 20),
|
|
156281
156884
|
evidenceRefs: item.evidence.map((evidence) => evidence.id),
|
|
@@ -156321,18 +156924,25 @@ async function buildTaskWorkset(input) {
|
|
|
156321
156924
|
}
|
|
156322
156925
|
} catch {
|
|
156323
156926
|
}
|
|
156324
|
-
const evidenceIds = unique(selection.claims.flatMap((claim) => evidenceIdsForClaim(
|
|
156325
|
-
claim,
|
|
156326
|
-
evidenceByClaim.get(claim.id) ?? []
|
|
156327
|
-
)).concat(
|
|
156328
|
-
durableMemory.map((memory) => "durable:" + memory.id),
|
|
156329
|
-
durableEvidence.map((evidence) => "durable-evidence:" + evidence.id)
|
|
156330
|
-
));
|
|
156331
156927
|
const verification = unique([
|
|
156332
156928
|
...workflows.flatMap((workflow) => workflow.verificationGates),
|
|
156333
156929
|
...input.verificationHints
|
|
156334
156930
|
]).slice(0, 4);
|
|
156335
156931
|
const normalizedCautions = unique(cautions.map((caution) => caution.kind)).map((kind) => cautions.find((caution) => caution.kind === kind)).slice(0, 6);
|
|
156932
|
+
const governed = governOptionalArtifacts({
|
|
156933
|
+
reliableMemory: input.reliableMemory?.slice(0, 3) ?? [],
|
|
156934
|
+
claims,
|
|
156935
|
+
durableMemory,
|
|
156936
|
+
workflows
|
|
156937
|
+
});
|
|
156938
|
+
const governedDurableIds = new Set(governed.durableMemory.map((memory) => memory.id));
|
|
156939
|
+
const evidenceIds = unique(governed.claims.flatMap((claim) => evidenceIdsForClaim(
|
|
156940
|
+
claim,
|
|
156941
|
+
evidenceByClaim.get(claim.id) ?? []
|
|
156942
|
+
)).concat(
|
|
156943
|
+
governed.durableMemory.map((memory) => "durable:" + memory.id),
|
|
156944
|
+
durableEvidence.filter((evidence) => governedDurableIds.has(evidence.memoryId)).map((evidence) => "durable-evidence:" + evidence.id)
|
|
156945
|
+
));
|
|
156336
156946
|
const continuation = input.continuation && (input.continuation.previousSession || input.continuation.memories.length > 0 || input.continuation.compactCheckpoint) ? {
|
|
156337
156947
|
...input.continuation.previousSession ? {
|
|
156338
156948
|
previousSession: {
|
|
@@ -156359,15 +156969,16 @@ async function buildTaskWorkset(input) {
|
|
|
156359
156969
|
currentFacts: input.currentFacts?.map((fact) => fact.startsWith("Historical note:") ? short(fact, 48) : short(fact, 28)).slice(0, 4) ?? [],
|
|
156360
156970
|
...continuation ? { continuation } : {},
|
|
156361
156971
|
...input.codeState ? { codeState: short(input.codeState, 28) } : {},
|
|
156972
|
+
...input.codeEvolution ? { codeEvolution: input.codeEvolution } : {},
|
|
156362
156973
|
startHere: unique(input.startHere).slice(0, 5),
|
|
156363
156974
|
...input.semanticCode ? { semanticCode: input.semanticCode } : {},
|
|
156364
|
-
reliableMemory:
|
|
156975
|
+
reliableMemory: governed.reliableMemory,
|
|
156365
156976
|
cautionMemory: input.cautionMemory?.slice(0, 3) ?? [],
|
|
156366
156977
|
hiddenCautionMemoryCount: input.hiddenCautionMemoryCount ?? 0,
|
|
156367
|
-
claims,
|
|
156368
|
-
pages,
|
|
156369
|
-
durableMemory,
|
|
156370
|
-
workflows,
|
|
156978
|
+
claims: governed.claims,
|
|
156979
|
+
pages: pages.filter((page) => page.claimIds.some((claimId) => governed.claims.some((claim) => claim.id === claimId))),
|
|
156980
|
+
durableMemory: governed.durableMemory,
|
|
156981
|
+
workflows: governed.workflows,
|
|
156371
156982
|
cautions: normalizedCautions,
|
|
156372
156983
|
verification,
|
|
156373
156984
|
evidenceIds,
|
|
@@ -156392,6 +157003,17 @@ async function buildTaskWorkset(input) {
|
|
|
156392
157003
|
},
|
|
156393
157004
|
selected: rendered.selected,
|
|
156394
157005
|
omitted: receiptOmissions(rendered.omittedItems, base.hiddenCautionMemoryCount),
|
|
157006
|
+
governance: {
|
|
157007
|
+
scope: "optional-evidence",
|
|
157008
|
+
mode: governed.plan.mode,
|
|
157009
|
+
decisions: governed.plan.decisions.map((decision) => ({
|
|
157010
|
+
kind: decision.candidate.kind,
|
|
157011
|
+
...decision.candidate.id ? { id: decision.candidate.id } : {},
|
|
157012
|
+
disposition: decision.disposition,
|
|
157013
|
+
reasons: decision.reasons
|
|
157014
|
+
})),
|
|
157015
|
+
cautions: governed.plan.cautions
|
|
157016
|
+
},
|
|
156395
157017
|
scheduledActions: scheduledActions(normalizedCautions)
|
|
156396
157018
|
};
|
|
156397
157019
|
return {
|
|
@@ -156417,8 +157039,11 @@ var init_workset = __esm({
|
|
|
156417
157039
|
init_workspace_store();
|
|
156418
157040
|
init_workspace();
|
|
156419
157041
|
init_workflow_store();
|
|
157042
|
+
init_outcome_store();
|
|
157043
|
+
init_outcome_types();
|
|
156420
157044
|
init_workflows2();
|
|
156421
157045
|
init_long_term();
|
|
157046
|
+
init_governor();
|
|
156422
157047
|
CONTINUATION_DETAIL_TOKEN_BUDGET = 20;
|
|
156423
157048
|
}
|
|
156424
157049
|
});
|
|
@@ -156441,19 +157066,19 @@ function readTextIfExists(filePath) {
|
|
|
156441
157066
|
}
|
|
156442
157067
|
}
|
|
156443
157068
|
function readPackageVersion(rootPath) {
|
|
156444
|
-
const
|
|
156445
|
-
if (!
|
|
157069
|
+
const text2 = readTextIfExists(path26.join(rootPath, "package.json"));
|
|
157070
|
+
if (!text2) return void 0;
|
|
156446
157071
|
try {
|
|
156447
|
-
const parsed = JSON.parse(
|
|
157072
|
+
const parsed = JSON.parse(text2);
|
|
156448
157073
|
return typeof parsed.version === "string" ? parsed.version : void 0;
|
|
156449
157074
|
} catch {
|
|
156450
157075
|
return void 0;
|
|
156451
157076
|
}
|
|
156452
157077
|
}
|
|
156453
157078
|
function readLatestChangelog(rootPath) {
|
|
156454
|
-
const
|
|
156455
|
-
if (!
|
|
156456
|
-
const match2 =
|
|
157079
|
+
const text2 = readTextIfExists(path26.join(rootPath, "CHANGELOG.md"));
|
|
157080
|
+
if (!text2) return void 0;
|
|
157081
|
+
const match2 = text2.match(/^##\s+\[?v?([^\]\s]+)\]?\s*(?:-\s*(\d{4}-\d{2}-\d{2}))?/m);
|
|
156457
157082
|
if (!match2) return void 0;
|
|
156458
157083
|
return {
|
|
156459
157084
|
version: match2[1],
|
|
@@ -156516,6 +157141,7 @@ function compareDateStrings(a, b) {
|
|
|
156516
157141
|
}
|
|
156517
157142
|
function detectStaleProgressNotes(input) {
|
|
156518
157143
|
const candidates = [
|
|
157144
|
+
"ACTIVE_WORK.md",
|
|
156519
157145
|
"progress.txt",
|
|
156520
157146
|
"docs/dev-log/progress.txt",
|
|
156521
157147
|
"docs/memcode/dev-log/progress.txt"
|
|
@@ -156653,6 +157279,7 @@ function providerQuality(input) {
|
|
|
156653
157279
|
capabilities: {
|
|
156654
157280
|
declarations: true,
|
|
156655
157281
|
importHints: true,
|
|
157282
|
+
localRelativeImportTargets: true,
|
|
156656
157283
|
resolvedRelations: false,
|
|
156657
157284
|
exactLocations: false
|
|
156658
157285
|
},
|
|
@@ -157174,8 +157801,8 @@ var compaction_checkpoint_store_exports = {};
|
|
|
157174
157801
|
__export(compaction_checkpoint_store_exports, {
|
|
157175
157802
|
CompactionCheckpointStore: () => CompactionCheckpointStore
|
|
157176
157803
|
});
|
|
157177
|
-
import { createHash as createHash14, randomUUID as
|
|
157178
|
-
function
|
|
157804
|
+
import { createHash as createHash14, randomUUID as randomUUID14 } from "crypto";
|
|
157805
|
+
function optionalText7(value) {
|
|
157179
157806
|
return typeof value === "string" && value ? value : void 0;
|
|
157180
157807
|
}
|
|
157181
157808
|
function optionalNumber2(value) {
|
|
@@ -157229,15 +157856,15 @@ function rowToCheckpoint(row) {
|
|
|
157229
157856
|
reason: row.reason,
|
|
157230
157857
|
sourceEvent: row.source_event,
|
|
157231
157858
|
sourceKey: row.source_key,
|
|
157232
|
-
...
|
|
157859
|
+
...optionalText7(row.summary) ? { summary: row.summary } : {},
|
|
157233
157860
|
...optionalNumber2(row.tokens_before) !== void 0 ? { tokensBefore: Number(row.tokens_before) } : {},
|
|
157234
|
-
...
|
|
157861
|
+
...optionalText7(row.first_kept_entry_id) ? { firstKeptEntryId: row.first_kept_entry_id } : {},
|
|
157235
157862
|
...parseDetails(row.details_json) ? { details: parseDetails(row.details_json) } : {},
|
|
157236
157863
|
transcriptAvailable: Boolean(row.transcript_available),
|
|
157237
157864
|
status: row.status,
|
|
157238
157865
|
preCapturedAt: row.pre_captured_at,
|
|
157239
|
-
...
|
|
157240
|
-
...
|
|
157866
|
+
...optionalText7(row.completed_at) ? { completedAt: row.completed_at } : {},
|
|
157867
|
+
...optionalText7(row.delivered_at) ? { deliveredAt: row.delivered_at } : {},
|
|
157241
157868
|
deliveryCount: Number(row.delivery_count ?? 0),
|
|
157242
157869
|
createdAt: row.created_at,
|
|
157243
157870
|
updatedAt: row.updated_at
|
|
@@ -157275,7 +157902,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
157275
157902
|
if (pending) return rowToCheckpoint(pending);
|
|
157276
157903
|
const now3 = input.capturedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
157277
157904
|
const checkpoint = {
|
|
157278
|
-
id:
|
|
157905
|
+
id: randomUUID14(),
|
|
157279
157906
|
projectId: input.projectId,
|
|
157280
157907
|
sessionId: input.sessionId,
|
|
157281
157908
|
agent: input.agent,
|
|
@@ -157283,7 +157910,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
157283
157910
|
captureKind: "preflight",
|
|
157284
157911
|
reason: safeReason(input.reason),
|
|
157285
157912
|
sourceEvent: input.sourceEvent,
|
|
157286
|
-
sourceKey: `pre:${
|
|
157913
|
+
sourceKey: `pre:${randomUUID14()}`,
|
|
157287
157914
|
transcriptAvailable: Boolean(input.transcriptAvailable),
|
|
157288
157915
|
status: "active",
|
|
157289
157916
|
preCapturedAt: now3,
|
|
@@ -157349,7 +157976,7 @@ var init_compaction_checkpoint_store = __esm({
|
|
|
157349
157976
|
return this.get(checkpoint2.id);
|
|
157350
157977
|
}
|
|
157351
157978
|
const checkpoint = {
|
|
157352
|
-
id:
|
|
157979
|
+
id: randomUUID14(),
|
|
157353
157980
|
projectId: input.projectId,
|
|
157354
157981
|
sessionId: input.sessionId,
|
|
157355
157982
|
agent: input.agent,
|
|
@@ -157611,6 +158238,25 @@ async function buildAutoProjectContext(input) {
|
|
|
157611
158238
|
const overview = explain.overview;
|
|
157612
158239
|
const currentFacts = collectCurrentProjectFacts({ project: input.project, now: now3 });
|
|
157613
158240
|
const latestSnapshot = overview.code.latestSnapshot;
|
|
158241
|
+
let codeEvolution;
|
|
158242
|
+
if (continuationRequested && latestSnapshot?.previousSnapshotId && latestSnapshot.changedPathCount > 0) {
|
|
158243
|
+
const diff = store.diffSnapshots(input.project.id, latestSnapshot.previousSnapshotId, latestSnapshot.id);
|
|
158244
|
+
if (diff.available && diff.changes.length > 0) {
|
|
158245
|
+
const impact = store.impactSlice(input.project.id, diff.changes.map((change) => change.path));
|
|
158246
|
+
const changedFileIds = new Set([
|
|
158247
|
+
...store.listSnapshotFiles(diff.fromSnapshotId),
|
|
158248
|
+
...store.listSnapshotFiles(diff.toSnapshotId)
|
|
158249
|
+
].filter((file) => diff.changes.some((change) => change.path === file.path)).map((file) => file.fileId));
|
|
158250
|
+
codeEvolution = {
|
|
158251
|
+
fromSnapshotId: diff.fromSnapshotId,
|
|
158252
|
+
toSnapshotId: diff.toSnapshotId,
|
|
158253
|
+
changes: diff.changes.slice(0, 5).map((change) => ({ path: change.path, kind: change.kind })),
|
|
158254
|
+
directlyConnectedPaths: impact.directlyConnectedPaths.slice(0, 3),
|
|
158255
|
+
affectedMemoryCount: store.countStaleObservationRefsForFiles(input.project.id, [...changedFileIds]),
|
|
158256
|
+
truncated: impact.truncated || diff.changes.length > 5
|
|
158257
|
+
};
|
|
158258
|
+
}
|
|
158259
|
+
}
|
|
157614
158260
|
const sourceSets = lensSourceSets({ task, lens, explain });
|
|
157615
158261
|
let externalOutline;
|
|
157616
158262
|
let externalCaution;
|
|
@@ -157687,6 +158333,7 @@ async function buildAutoProjectContext(input) {
|
|
|
157687
158333
|
currentFacts: worksetFactLines(currentFacts),
|
|
157688
158334
|
...continuation ? { continuation } : {},
|
|
157689
158335
|
codeState: codeStateLine(overview),
|
|
158336
|
+
...codeEvolution ? { codeEvolution } : {},
|
|
157690
158337
|
reliableMemory: sourceSets.reliableSources.slice(0, lens.sourceLimit).map((source) => ({
|
|
157691
158338
|
id: source.observationId,
|
|
157692
158339
|
title: source.title,
|
|
@@ -157738,9 +158385,9 @@ async function buildAutoProjectContext(input) {
|
|
|
157738
158385
|
function formatLanguages(overview) {
|
|
157739
158386
|
return overview.code.languages.length > 0 ? overview.code.languages.map((item) => `${item.language} ${item.files}`).join(", ") : "none indexed yet";
|
|
157740
158387
|
}
|
|
157741
|
-
function compactContinuationText(
|
|
158388
|
+
function compactContinuationText(text2, budget) {
|
|
157742
158389
|
return truncateToTokenBudget(
|
|
157743
|
-
sanitizeCredentials(
|
|
158390
|
+
sanitizeCredentials(text2).replace(/\s+/g, " ").trim(),
|
|
157744
158391
|
budget
|
|
157745
158392
|
);
|
|
157746
158393
|
}
|
|
@@ -158015,8 +158662,8 @@ __export(context_pack_exports, {
|
|
|
158015
158662
|
function uniq2(items) {
|
|
158016
158663
|
return [...new Set(items)];
|
|
158017
158664
|
}
|
|
158018
|
-
function tokenize4(
|
|
158019
|
-
return (
|
|
158665
|
+
function tokenize4(text2) {
|
|
158666
|
+
return (text2.toLowerCase().match(/[a-z0-9_./-]+|[\u4e00-\u9fff]+/g) ?? []).map((token) => token.trim()).filter((token) => token.length > 1);
|
|
158020
158667
|
}
|
|
158021
158668
|
function timestampOf(observation) {
|
|
158022
158669
|
return Date.parse(observation.updatedAt ?? observation.createdAt ?? "") || 0;
|
|
@@ -158618,7 +159265,7 @@ __export(team_store_exports, {
|
|
|
158618
159265
|
isTeamStoreInitialized: () => isTeamStoreInitialized,
|
|
158619
159266
|
resetTeamStore: () => resetTeamStore
|
|
158620
159267
|
});
|
|
158621
|
-
import { randomUUID as
|
|
159268
|
+
import { randomUUID as randomUUID15 } from "crypto";
|
|
158622
159269
|
import path28 from "path";
|
|
158623
159270
|
import fs18 from "fs";
|
|
158624
159271
|
function getTeamStore() {
|
|
@@ -158907,7 +159554,7 @@ var init_team_store = __esm({
|
|
|
158907
159554
|
* reactivate it (preserving agent_id). Otherwise create a new one.
|
|
158908
159555
|
*/
|
|
158909
159556
|
registerAgent(input) {
|
|
158910
|
-
const instanceId = input.instanceId ||
|
|
159557
|
+
const instanceId = input.instanceId || randomUUID15();
|
|
158911
159558
|
const now3 = Date.now();
|
|
158912
159559
|
const existing = this.stmtAgentFindByInstance.get(
|
|
158913
159560
|
input.projectId,
|
|
@@ -158933,7 +159580,7 @@ var init_team_store = __esm({
|
|
|
158933
159580
|
this.eventBus?.emit("agent:joined", { agentId: row2.agent_id, projectId: input.projectId, agentType: input.agentType });
|
|
158934
159581
|
return row2;
|
|
158935
159582
|
}
|
|
158936
|
-
const agentId =
|
|
159583
|
+
const agentId = randomUUID15();
|
|
158937
159584
|
this.stmtAgentUpsert.run({
|
|
158938
159585
|
agent_id: agentId,
|
|
158939
159586
|
project_id: input.projectId,
|
|
@@ -159035,7 +159682,7 @@ var init_team_store = __esm({
|
|
|
159035
159682
|
return { error: `Recipient agent '${input.recipientAgentId}' not found \u2014 cannot send to unknown agent` };
|
|
159036
159683
|
}
|
|
159037
159684
|
}
|
|
159038
|
-
const id =
|
|
159685
|
+
const id = randomUUID15();
|
|
159039
159686
|
const now3 = Date.now();
|
|
159040
159687
|
const row = {
|
|
159041
159688
|
id,
|
|
@@ -159085,7 +159732,7 @@ var init_team_store = __esm({
|
|
|
159085
159732
|
// Task Operations (with atomic claim semantics)
|
|
159086
159733
|
// ═══════════════════════════════════════════════════════════════════
|
|
159087
159734
|
createTask(input) {
|
|
159088
|
-
const taskId =
|
|
159735
|
+
const taskId = randomUUID15();
|
|
159089
159736
|
const now3 = Date.now();
|
|
159090
159737
|
const row = {
|
|
159091
159738
|
task_id: taskId,
|
|
@@ -159357,7 +160004,7 @@ var init_team_store = __esm({
|
|
|
159357
160004
|
for (const [agentId, msgs] of Object.entries(snap.messages.inboxes)) {
|
|
159358
160005
|
for (const msg of msgs) {
|
|
159359
160006
|
this.stmtMsgInsert.run({
|
|
159360
|
-
id: msg.id ??
|
|
160007
|
+
id: msg.id ?? randomUUID15(),
|
|
159361
160008
|
project_id: "migrated",
|
|
159362
160009
|
sender_agent_id: msg.from ?? "unknown",
|
|
159363
160010
|
recipient_agent_id: msg.to === "__broadcast__" ? null : msg.to ?? agentId,
|
|
@@ -159630,19 +160277,19 @@ function buildCompactionWorkset(checkpoint, options = {}) {
|
|
|
159630
160277
|
const source = sanitizeCredentials(checkpoint.summary?.trim() || fallback);
|
|
159631
160278
|
const available = Math.max(0, budget - countTextTokens(header) - 4);
|
|
159632
160279
|
let excerpt = source ? truncateToTokenBudget(source, available) : "";
|
|
159633
|
-
let
|
|
160280
|
+
let text2 = `${header}${excerpt ? `### Host checkpoint
|
|
159634
160281
|
${excerpt}` : ""}`.trim();
|
|
159635
|
-
while (excerpt && countTextTokens(
|
|
160282
|
+
while (excerpt && countTextTokens(text2) > budget) {
|
|
159636
160283
|
const nextExcerptBudget = Math.max(1, Math.floor(countTextTokens(excerpt) * 0.8));
|
|
159637
160284
|
excerpt = truncateToTokenBudget(excerpt, nextExcerptBudget);
|
|
159638
|
-
|
|
160285
|
+
text2 = `${header}${excerpt ? `### Host checkpoint
|
|
159639
160286
|
${excerpt}` : ""}`.trim();
|
|
159640
160287
|
}
|
|
159641
|
-
if (countTextTokens(
|
|
160288
|
+
if (countTextTokens(text2) > budget) text2 = truncateToTokenBudget(text2, budget);
|
|
159642
160289
|
return {
|
|
159643
160290
|
checkpointId: checkpoint.id,
|
|
159644
|
-
text,
|
|
159645
|
-
tokens: countTextTokens(
|
|
160291
|
+
text: text2,
|
|
160292
|
+
tokens: countTextTokens(text2)
|
|
159646
160293
|
};
|
|
159647
160294
|
}
|
|
159648
160295
|
function sourceEvent(input) {
|
|
@@ -161533,15 +162180,15 @@ function validateSemantics(graph) {
|
|
|
161533
162180
|
return warnings;
|
|
161534
162181
|
}
|
|
161535
162182
|
function extractJson(raw) {
|
|
161536
|
-
let
|
|
162183
|
+
let text2 = raw;
|
|
161537
162184
|
try {
|
|
161538
162185
|
const envelope = JSON.parse(raw.trim());
|
|
161539
162186
|
if (envelope && typeof envelope.result === "string" && envelope.type === "result") {
|
|
161540
|
-
|
|
162187
|
+
text2 = envelope.result;
|
|
161541
162188
|
}
|
|
161542
162189
|
} catch {
|
|
161543
162190
|
}
|
|
161544
|
-
if (
|
|
162191
|
+
if (text2 === raw && raw.includes('"type"')) {
|
|
161545
162192
|
const textBlocks = [];
|
|
161546
162193
|
for (const line of raw.split("\n")) {
|
|
161547
162194
|
const trimmed = line.trim();
|
|
@@ -161565,27 +162212,27 @@ function extractJson(raw) {
|
|
|
161565
162212
|
}
|
|
161566
162213
|
}
|
|
161567
162214
|
if (textBlocks.length > 0) {
|
|
161568
|
-
|
|
162215
|
+
text2 = textBlocks.join("");
|
|
161569
162216
|
}
|
|
161570
162217
|
}
|
|
161571
|
-
const fenced =
|
|
162218
|
+
const fenced = text2.match(/```(?:json)?\s*\n?([\s\S]*?)```/);
|
|
161572
162219
|
if (fenced) {
|
|
161573
162220
|
const candidate = fenced[1].trim();
|
|
161574
162221
|
if (candidate.startsWith("{")) return candidate;
|
|
161575
162222
|
}
|
|
161576
|
-
const braceStart =
|
|
162223
|
+
const braceStart = text2.indexOf("{");
|
|
161577
162224
|
if (braceStart !== -1) {
|
|
161578
|
-
const extracted = extractBalancedJson(
|
|
162225
|
+
const extracted = extractBalancedJson(text2, braceStart);
|
|
161579
162226
|
if (extracted) return extracted;
|
|
161580
162227
|
}
|
|
161581
162228
|
return null;
|
|
161582
162229
|
}
|
|
161583
|
-
function extractBalancedJson(
|
|
162230
|
+
function extractBalancedJson(text2, startIdx) {
|
|
161584
162231
|
let depth = 0;
|
|
161585
162232
|
let inString = false;
|
|
161586
162233
|
let escape2 = false;
|
|
161587
|
-
for (let i2 = startIdx; i2 <
|
|
161588
|
-
const ch =
|
|
162234
|
+
for (let i2 = startIdx; i2 < text2.length; i2++) {
|
|
162235
|
+
const ch = text2[i2];
|
|
161589
162236
|
if (escape2) {
|
|
161590
162237
|
escape2 = false;
|
|
161591
162238
|
continue;
|
|
@@ -161603,7 +162250,7 @@ function extractBalancedJson(text, startIdx) {
|
|
|
161603
162250
|
else if (ch === "}") {
|
|
161604
162251
|
depth--;
|
|
161605
162252
|
if (depth === 0) {
|
|
161606
|
-
return
|
|
162253
|
+
return text2.slice(startIdx, i2 + 1);
|
|
161607
162254
|
}
|
|
161608
162255
|
}
|
|
161609
162256
|
}
|
|
@@ -161822,7 +162469,7 @@ __export(planner_exports, {
|
|
|
161822
162469
|
materializeTaskGraph: () => materializeTaskGraph,
|
|
161823
162470
|
seedAutonomousPipeline: () => seedAutonomousPipeline
|
|
161824
162471
|
});
|
|
161825
|
-
import { randomUUID as
|
|
162472
|
+
import { randomUUID as randomUUID16 } from "crypto";
|
|
161826
162473
|
function isPlannerTask(metadata) {
|
|
161827
162474
|
if (!metadata) return null;
|
|
161828
162475
|
try {
|
|
@@ -161880,7 +162527,7 @@ function seedAutonomousPipeline(teamStore, projectId, config, opts) {
|
|
|
161880
162527
|
const maxIterations = config.maxIterations ?? 3;
|
|
161881
162528
|
const taskBudget = config.taskBudget ?? 15;
|
|
161882
162529
|
const structuredPlan = opts?.structuredPlan ?? true;
|
|
161883
|
-
const pipelineId =
|
|
162530
|
+
const pipelineId = randomUUID16();
|
|
161884
162531
|
const meta = {
|
|
161885
162532
|
plannerType: "plan",
|
|
161886
162533
|
pipelineId,
|
|
@@ -162325,8 +162972,8 @@ async function callVisionLLM(systemPrompt, imageBase64, mimeType) {
|
|
|
162325
162972
|
return data.choices[0]?.message?.content ?? "";
|
|
162326
162973
|
}
|
|
162327
162974
|
function normalizeText4(value, fallback = "") {
|
|
162328
|
-
const
|
|
162329
|
-
return sanitizeCredentials(
|
|
162975
|
+
const text2 = typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
162976
|
+
return sanitizeCredentials(text2).slice(0, MAX_VISION_DESCRIPTION_CHARS);
|
|
162330
162977
|
}
|
|
162331
162978
|
function normalizeLabels(value) {
|
|
162332
162979
|
if (!Array.isArray(value)) return [];
|
|
@@ -164315,7 +164962,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
164315
164962
|
};
|
|
164316
164963
|
const server = existingServer ?? new McpServer({
|
|
164317
164964
|
name: "memorix",
|
|
164318
|
-
version: true ? "1.4.
|
|
164965
|
+
version: true ? "1.4.2" : "1.0.1"
|
|
164319
164966
|
});
|
|
164320
164967
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
164321
164968
|
server.registerTool = ((name, ...args) => {
|
|
@@ -165051,10 +165698,10 @@ Use this as the \`topicKey\` parameter in \`memorix_store\` to enable upsert beh
|
|
|
165051
165698
|
const duplicate = blockCoveredAutopilotEvidence("memorix_search", result.entries.map((entry) => entry.id), force);
|
|
165052
165699
|
if (duplicate) return duplicate;
|
|
165053
165700
|
}
|
|
165054
|
-
let
|
|
165701
|
+
let text2 = result.formatted;
|
|
165055
165702
|
try {
|
|
165056
165703
|
const { getLastSearchMode: getLastSearchMode2 } = await Promise.resolve().then(() => (init_orama_store(), orama_store_exports));
|
|
165057
|
-
|
|
165704
|
+
text2 += `
|
|
165058
165705
|
|
|
165059
165706
|
_Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
165060
165707
|
} catch {
|
|
@@ -165063,7 +165710,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165063
165710
|
content: [
|
|
165064
165711
|
{
|
|
165065
165712
|
type: "text",
|
|
165066
|
-
text
|
|
165713
|
+
text: text2
|
|
165067
165714
|
}
|
|
165068
165715
|
]
|
|
165069
165716
|
};
|
|
@@ -165096,14 +165743,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165096
165743
|
query,
|
|
165097
165744
|
limit: limit2 != null ? coerceNumber(limit2, 5) : void 0
|
|
165098
165745
|
});
|
|
165099
|
-
const
|
|
165746
|
+
const text2 = format === "summary" ? [
|
|
165100
165747
|
`Graph context packet for ${project.name}`,
|
|
165101
165748
|
`- ${packet.summary}`,
|
|
165102
165749
|
"",
|
|
165103
165750
|
...packet.entities.map((entity) => `* ${entity.name} (#${entity.observationIds.join(", #")})`)
|
|
165104
165751
|
].join("\n") : formatGraphContextPrompt(packet);
|
|
165105
165752
|
return {
|
|
165106
|
-
content: [{ type: "text", text }]
|
|
165753
|
+
content: [{ type: "text", text: text2 }]
|
|
165107
165754
|
};
|
|
165108
165755
|
}
|
|
165109
165756
|
);
|
|
@@ -165163,7 +165810,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165163
165810
|
});
|
|
165164
165811
|
}
|
|
165165
165812
|
});
|
|
165166
|
-
const
|
|
165813
|
+
const text2 = format === "json" ? JSON.stringify({ ...context, brief: buildAutoProjectBrief2(context) }, null, 2) : format === "summary" ? formatAutoProjectContextSummary2(context) : formatAutoProjectContextPrompt2(context);
|
|
165167
165814
|
autopilotRetrievalBoundary = {
|
|
165168
165815
|
projectId: project.id,
|
|
165169
165816
|
issuedAt: Date.now(),
|
|
@@ -165175,7 +165822,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165175
165822
|
readOnly: READ_ONLY_TASK_PATTERN.test(task ?? "")
|
|
165176
165823
|
};
|
|
165177
165824
|
return {
|
|
165178
|
-
content: [{ type: "text", text }]
|
|
165825
|
+
content: [{ type: "text", text: text2 }]
|
|
165179
165826
|
};
|
|
165180
165827
|
}
|
|
165181
165828
|
);
|
|
@@ -165303,9 +165950,9 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165303
165950
|
...external.caution ? { runtimeCautions: [{ kind: "external-codegraph-fallback", message: external.caution }] } : {},
|
|
165304
165951
|
reader: getObservationReader()
|
|
165305
165952
|
});
|
|
165306
|
-
const
|
|
165953
|
+
const text2 = buildContextPackPrompt2(pack);
|
|
165307
165954
|
return {
|
|
165308
|
-
content: [{ type: "text", text }]
|
|
165955
|
+
content: [{ type: "text", text: text2 }]
|
|
165309
165956
|
};
|
|
165310
165957
|
}
|
|
165311
165958
|
);
|
|
@@ -165367,7 +166014,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165367
166014
|
}) => {
|
|
165368
166015
|
const unresolved = requireResolvedProject("manage the Knowledge Workspace for the current project");
|
|
165369
166016
|
if (unresolved) return unresolved;
|
|
165370
|
-
const
|
|
166017
|
+
const text2 = (value, isError = false) => ({
|
|
165371
166018
|
content: [{ type: "text", text: JSON.stringify(value, null, 2) }],
|
|
165372
166019
|
...isError ? { isError: true } : {}
|
|
165373
166020
|
});
|
|
@@ -165404,7 +166051,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165404
166051
|
]);
|
|
165405
166052
|
if (action === "workspace_init") {
|
|
165406
166053
|
if (modeValue === "versioned" && !requireText(workspacePath, "path")) {
|
|
165407
|
-
return
|
|
166054
|
+
return text2({ error: "path is required to initialize a versioned Knowledge Workspace." }, true);
|
|
165408
166055
|
}
|
|
165409
166056
|
const workspace2 = await initializeKnowledgeWorkspace2({
|
|
165410
166057
|
projectId: project.id,
|
|
@@ -165412,7 +166059,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165412
166059
|
mode: modeValue,
|
|
165413
166060
|
...modeValue === "versioned" ? { projectRoot: project.rootPath, rootPath: requireText(workspacePath, "path") } : {}
|
|
165414
166061
|
});
|
|
165415
|
-
return
|
|
166062
|
+
return text2({
|
|
165416
166063
|
workspace: {
|
|
165417
166064
|
id: workspace2.id,
|
|
165418
166065
|
mode: workspace2.mode,
|
|
@@ -165424,7 +166071,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165424
166071
|
}
|
|
165425
166072
|
const workspace = await loadKnowledgeWorkspace2({ projectId: project.id, dataDir: projectDir2, mode: modeValue });
|
|
165426
166073
|
if (!workspace) {
|
|
165427
|
-
return
|
|
166074
|
+
return text2({ error: "Knowledge Workspace is not initialized. Run workspace_init first." }, true);
|
|
165428
166075
|
}
|
|
165429
166076
|
const claims = new ClaimStore2();
|
|
165430
166077
|
const workspaceStore = new KnowledgeWorkspaceStore2();
|
|
@@ -165432,7 +166079,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165432
166079
|
if (action === "status") {
|
|
165433
166080
|
const pages = workspaceStore.listPages(workspace.id);
|
|
165434
166081
|
const pending = workspaceStore.listProposals(workspace.id, "pending");
|
|
165435
|
-
return
|
|
166082
|
+
return text2({
|
|
165436
166083
|
workspace: {
|
|
165437
166084
|
id: workspace.id,
|
|
165438
166085
|
mode: workspace.mode,
|
|
@@ -165450,7 +166097,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165450
166097
|
});
|
|
165451
166098
|
}
|
|
165452
166099
|
if (action === "claim_list") {
|
|
165453
|
-
return
|
|
166100
|
+
return text2({
|
|
165454
166101
|
claims: claims.listClaims(project.id, { limit: 100 }).map((claim) => ({
|
|
165455
166102
|
id: claim.id,
|
|
165456
166103
|
subject: claim.subject,
|
|
@@ -165469,18 +166116,18 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165469
166116
|
const requestedClaimId = requireText(claimId, "claimId");
|
|
165470
166117
|
const detail = requireText(reviewDetail, "reviewDetail");
|
|
165471
166118
|
if (!requestedClaimId || !claimReviewState || !detail) {
|
|
165472
|
-
return
|
|
166119
|
+
return text2({ error: "claimId, claimReviewState, and reviewDetail are required for claim_review." }, true);
|
|
165473
166120
|
}
|
|
165474
166121
|
const existing = claims.getClaim(requestedClaimId);
|
|
165475
166122
|
if (!existing || existing.projectId !== project.id) {
|
|
165476
|
-
return
|
|
166123
|
+
return text2({ error: "Claim was not found for the current project." }, true);
|
|
165477
166124
|
}
|
|
165478
166125
|
const claim = reviewClaim2(claims, {
|
|
165479
166126
|
claimId: requestedClaimId,
|
|
165480
166127
|
reviewState: claimReviewState,
|
|
165481
166128
|
detail
|
|
165482
166129
|
});
|
|
165483
|
-
return
|
|
166130
|
+
return text2({
|
|
165484
166131
|
claim: {
|
|
165485
166132
|
id: claim.id,
|
|
165486
166133
|
status: claim.status,
|
|
@@ -165492,7 +166139,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165492
166139
|
}
|
|
165493
166140
|
if (action === "compile") {
|
|
165494
166141
|
const result = await compileKnowledgeWorkspace2({ workspace, claims });
|
|
165495
|
-
return
|
|
166142
|
+
return text2({
|
|
165496
166143
|
proposals: result.proposals.map((proposal) => ({
|
|
165497
166144
|
id: proposal.id,
|
|
165498
166145
|
targetPath: proposal.targetPath,
|
|
@@ -165507,17 +166154,17 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165507
166154
|
const codeStore = new CodeGraphStore2();
|
|
165508
166155
|
await codeStore.init(projectDir2);
|
|
165509
166156
|
const result = await lintKnowledgeWorkspace2({ workspace, claims, codeStore });
|
|
165510
|
-
return
|
|
166157
|
+
return text2(result);
|
|
165511
166158
|
}
|
|
165512
166159
|
if (action === "proposal_apply") {
|
|
165513
166160
|
const proposal = requireText(proposalId, "proposalId");
|
|
165514
|
-
if (!proposal) return
|
|
166161
|
+
if (!proposal) return text2({ error: "proposalId is required for proposal_apply." }, true);
|
|
165515
166162
|
const result = await applyKnowledgeProposal2({
|
|
165516
166163
|
workspace,
|
|
165517
166164
|
proposalId: proposal,
|
|
165518
166165
|
allowManualOverwrite: !!allowManualOverwrite
|
|
165519
166166
|
});
|
|
165520
|
-
return
|
|
166167
|
+
return text2({
|
|
165521
166168
|
proposal: { id: result.proposal.id, status: result.proposal.status },
|
|
165522
166169
|
targetPath: result.targetPath
|
|
165523
166170
|
});
|
|
@@ -165527,7 +166174,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165527
166174
|
const projectRoot = workspace.projectRoot ?? project.rootPath;
|
|
165528
166175
|
if (action === "workflow_import") {
|
|
165529
166176
|
const result = await importWindsurfWorkflows2({ workspace, projectRoot });
|
|
165530
|
-
return
|
|
166177
|
+
return text2({
|
|
165531
166178
|
imported: result.imported.map((workflow2) => ({
|
|
165532
166179
|
id: workflow2.id,
|
|
165533
166180
|
title: workflow2.title,
|
|
@@ -165540,7 +166187,7 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165540
166187
|
}
|
|
165541
166188
|
const synced = await syncCanonicalWorkflows2(workspace);
|
|
165542
166189
|
if (action === "workflow_list") {
|
|
165543
|
-
return
|
|
166190
|
+
return text2({
|
|
165544
166191
|
workflows: workflowStore.listWorkflows(workspace.id).map((workflow2) => ({
|
|
165545
166192
|
id: workflow2.id,
|
|
165546
166193
|
title: workflow2.title,
|
|
@@ -165555,9 +166202,9 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165555
166202
|
}
|
|
165556
166203
|
if (action === "workflow_select") {
|
|
165557
166204
|
const selectedTask = requireText(task, "task");
|
|
165558
|
-
if (!selectedTask) return
|
|
166205
|
+
if (!selectedTask) return text2({ error: "task is required for workflow_select." }, true);
|
|
165559
166206
|
const result = await selectWorkspaceWorkflows2({ workspace, task: selectedTask });
|
|
165560
|
-
return
|
|
166207
|
+
return text2({
|
|
165561
166208
|
selections: result.selections.map((selection) => ({
|
|
165562
166209
|
id: selection.workflow.id,
|
|
165563
166210
|
title: selection.workflow.title,
|
|
@@ -165569,16 +166216,16 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165569
166216
|
});
|
|
165570
166217
|
}
|
|
165571
166218
|
const requestedWorkflowId = requireText(workflowId, "workflowId");
|
|
165572
|
-
if (!requestedWorkflowId) return
|
|
166219
|
+
if (!requestedWorkflowId) return text2({ error: "workflowId is required for this workflow action." }, true);
|
|
165573
166220
|
const workflow = workflowStore.getWorkflow(requestedWorkflowId);
|
|
165574
166221
|
if (!workflow || workflow.workspaceId !== workspace.id) {
|
|
165575
|
-
return
|
|
166222
|
+
return text2({ error: "Workflow was not found for this Knowledge Workspace." }, true);
|
|
165576
166223
|
}
|
|
165577
166224
|
if (action === "workflow_preview" || action === "workflow_apply") {
|
|
165578
166225
|
const targetAgent = requireText(agent, "agent");
|
|
165579
|
-
if (!targetAgent) return
|
|
166226
|
+
if (!targetAgent) return text2({ error: "agent is required for a workflow adapter action." }, true);
|
|
165580
166227
|
const result = action === "workflow_preview" ? await previewWorkflowAdapter2({ workflow, projectRoot, agent: targetAgent }) : await applyWorkflowAdapter2({ workflow, projectRoot, agent: targetAgent });
|
|
165581
|
-
return
|
|
166228
|
+
return text2({
|
|
165582
166229
|
workflowId: workflow.id,
|
|
165583
166230
|
agent: targetAgent,
|
|
165584
166231
|
status: result.status,
|
|
@@ -165589,8 +166236,8 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165589
166236
|
}
|
|
165590
166237
|
if (action === "workflow_run") {
|
|
165591
166238
|
const runTask = requireText(task, "task");
|
|
165592
|
-
if (!runTask) return
|
|
165593
|
-
if (!outcome) return
|
|
166239
|
+
if (!runTask) return text2({ error: "task is required for workflow_run." }, true);
|
|
166240
|
+
if (!outcome) return text2({ error: "outcome is required for workflow_run." }, true);
|
|
165594
166241
|
const result = await recordWorkflowRun2({
|
|
165595
166242
|
workspace,
|
|
165596
166243
|
run: {
|
|
@@ -165604,14 +166251,14 @@ _Search mode: ${getLastSearchMode2(project.id)}_`;
|
|
|
165604
166251
|
selectedEvidence: [...new Set((evidenceIds ?? []).map((item) => item.trim()).filter(Boolean))]
|
|
165605
166252
|
}
|
|
165606
166253
|
});
|
|
165607
|
-
return
|
|
166254
|
+
return text2({
|
|
165608
166255
|
id: result.id,
|
|
165609
166256
|
workflowId: result.workflowId,
|
|
165610
166257
|
outcome: result.outcome,
|
|
165611
166258
|
verificationVerdict: result.verificationVerdict
|
|
165612
166259
|
});
|
|
165613
166260
|
}
|
|
165614
|
-
return
|
|
166261
|
+
return text2({ error: "Unsupported knowledge action." }, true);
|
|
165615
166262
|
}
|
|
165616
166263
|
);
|
|
165617
166264
|
server.registerTool(
|
|
@@ -167086,10 +167733,10 @@ Ensure the path points to a directory containing a .git folder (or a subdirector
|
|
|
167086
167733
|
];
|
|
167087
167734
|
const allSkills = await loadMiniSkills2(projectDir2, project.id);
|
|
167088
167735
|
const miniSkills = allSkills.filter((s2) => {
|
|
167089
|
-
const
|
|
167736
|
+
const text2 = `${s2.title}
|
|
167090
167737
|
${s2.sourceEntity}
|
|
167091
167738
|
${s2.instruction}`.toLowerCase();
|
|
167092
|
-
return !SKILL_NOISE.some((p) => p.test(
|
|
167739
|
+
return !SKILL_NOISE.some((p) => p.test(text2));
|
|
167093
167740
|
});
|
|
167094
167741
|
if (miniSkills.length > 0) {
|
|
167095
167742
|
const formatted = formatMiniSkillsForInjection2(miniSkills);
|
|
@@ -168580,7 +169227,7 @@ var init_serve_shared = __esm({
|
|
|
168580
169227
|
|
|
168581
169228
|
// src/cli/version.ts
|
|
168582
169229
|
function getCliVersion() {
|
|
168583
|
-
return true ? "1.4.
|
|
169230
|
+
return true ? "1.4.2" : pkg.version;
|
|
168584
169231
|
}
|
|
168585
169232
|
var init_version3 = __esm({
|
|
168586
169233
|
"src/cli/version.ts"() {
|