caveat-cli 0.19.9 → 0.19.10
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/dist/{chunk-ITQLGM4K.js → chunk-PFYFYJNS.js} +103 -41
- package/dist/chunk-PFYFYJNS.js.map +1 -0
- package/dist/index.js +93 -11
- package/dist/index.js.map +1 -1
- package/dist/{server-H4BWLLZ2.js → server-JXBPTQNU.js} +55 -2
- package/dist/server-JXBPTQNU.js.map +1 -0
- package/package.json +3 -3
- package/dist/chunk-ITQLGM4K.js.map +0 -1
- package/dist/server-H4BWLLZ2.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -37,6 +37,8 @@ import {
|
|
|
37
37
|
isPrivateOwnerStat,
|
|
38
38
|
isWindows,
|
|
39
39
|
isWindowsEnv,
|
|
40
|
+
jevObservationId,
|
|
41
|
+
listJevObservations,
|
|
40
42
|
listRecent,
|
|
41
43
|
listStale,
|
|
42
44
|
loadConfig,
|
|
@@ -59,6 +61,7 @@ import {
|
|
|
59
61
|
releaseReindexLock,
|
|
60
62
|
resetAutoSyncFailureState,
|
|
61
63
|
resolvePaths,
|
|
64
|
+
reviewJevObservation,
|
|
62
65
|
runAutoSync,
|
|
63
66
|
runWindowsAcl,
|
|
64
67
|
runtimeErrorsDiagnostics,
|
|
@@ -71,10 +74,12 @@ import {
|
|
|
71
74
|
toolErrorReminderText,
|
|
72
75
|
triggerAutoSync,
|
|
73
76
|
updateEntry,
|
|
77
|
+
updateJevDelivery,
|
|
74
78
|
userPromptSubmitReminderText,
|
|
75
79
|
writeDigestMarker,
|
|
80
|
+
writeJevObservation,
|
|
76
81
|
writeUserConfigPatch
|
|
77
|
-
} from "./chunk-
|
|
82
|
+
} from "./chunk-PFYFYJNS.js";
|
|
78
83
|
|
|
79
84
|
// ../../node_modules/.pnpm/ajv@8.18.0/node_modules/ajv/dist/compile/codegen/code.js
|
|
80
85
|
var require_code = __commonJS({
|
|
@@ -8390,7 +8395,7 @@ function runStats(ctx) {
|
|
|
8390
8395
|
|
|
8391
8396
|
// src/commands/serve.ts
|
|
8392
8397
|
async function runServe(opts) {
|
|
8393
|
-
const { startServer } = await import("./server-
|
|
8398
|
+
const { startServer } = await import("./server-JXBPTQNU.js");
|
|
8394
8399
|
const { port, host } = startServer({ port: opts.port });
|
|
8395
8400
|
process.stdout.write(`[caveat] web portal: http://${host}:${port}/
|
|
8396
8401
|
`);
|
|
@@ -33274,12 +33279,23 @@ async function judgeStruggle(key, turns, ask = callJev) {
|
|
|
33274
33279
|
criteria: { ...options, none: "No listed term would retrieve useful knowledge about this problem." }
|
|
33275
33280
|
};
|
|
33276
33281
|
const response = await ask(key, { turns }, questions);
|
|
33277
|
-
const
|
|
33278
|
-
|
|
33279
|
-
|
|
33282
|
+
const repeatedProblem = noul(response.answers.repeated_problem);
|
|
33283
|
+
const clearlyStuck = noul(response.answers.clearly_stuck);
|
|
33284
|
+
const struggling = repeatedProblem >= STRUGGLE_THRESHOLD && clearlyStuck >= STRUGGLE_THRESHOLD;
|
|
33285
|
+
const choice = terms.length > 0 ? response.answers.search_term : void 0;
|
|
33286
|
+
const selected = terms.length > 0 ? searchTermChoices(choice, terms) : [];
|
|
33287
|
+
const termChoices = terms.map((term, index) => ({ term, probability: choice.probabilities[`term_${index}`] }));
|
|
33288
|
+
return {
|
|
33289
|
+
struggling,
|
|
33290
|
+
terms: struggling ? selected : [],
|
|
33291
|
+
repeatedProblem,
|
|
33292
|
+
clearlyStuck,
|
|
33293
|
+
termChoices,
|
|
33294
|
+
noneProbability: choice ? choice.probabilities.none : null
|
|
33295
|
+
};
|
|
33280
33296
|
}
|
|
33281
33297
|
async function rankKnowledge(key, turns, candidates, ask = callJev) {
|
|
33282
|
-
if (candidates.length === 0) return null;
|
|
33298
|
+
if (candidates.length === 0) return { selected: null, scores: [] };
|
|
33283
33299
|
const state = {
|
|
33284
33300
|
turns,
|
|
33285
33301
|
currentHostOs: fingerprint().os,
|
|
@@ -33302,14 +33318,16 @@ async function rankKnowledge(key, turns, candidates, ask = callJev) {
|
|
|
33302
33318
|
const response = await ask(key, state, questions);
|
|
33303
33319
|
let best = null;
|
|
33304
33320
|
let bestScore = MATCH_THRESHOLD;
|
|
33321
|
+
const scores = [];
|
|
33305
33322
|
for (let index = 0; index < candidates.length; index++) {
|
|
33306
33323
|
const score = noul(response.answers[`candidate_${index}`]);
|
|
33324
|
+
scores.push(score);
|
|
33307
33325
|
if (score >= MATCH_THRESHOLD && (best === null || score > bestScore)) {
|
|
33308
33326
|
best = candidates[index];
|
|
33309
33327
|
bestScore = score;
|
|
33310
33328
|
}
|
|
33311
33329
|
}
|
|
33312
|
-
return best;
|
|
33330
|
+
return { selected: best, scores };
|
|
33313
33331
|
}
|
|
33314
33332
|
function quotePowerShell(value) {
|
|
33315
33333
|
return `'${value.replaceAll("'", "''")}'`;
|
|
@@ -33374,13 +33392,46 @@ async function runJevStruggle(ctx, host, payload, deps = {}) {
|
|
|
33374
33392
|
const key = (deps.readKey ?? readJevKey)(ctx.caveatHome);
|
|
33375
33393
|
const ask = deps.ask ?? callJev;
|
|
33376
33394
|
const judgment = await judgeStruggle(key, context.turns, ask);
|
|
33395
|
+
const observationId = jevObservationId(host, sessionId, turnKey);
|
|
33396
|
+
const base = {
|
|
33397
|
+
schema: "caveat.jev_observation.v1",
|
|
33398
|
+
id: observationId,
|
|
33399
|
+
observedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33400
|
+
host,
|
|
33401
|
+
sessionId,
|
|
33402
|
+
projectRoot,
|
|
33403
|
+
transcriptPath,
|
|
33404
|
+
turns: context.turns.map(({ originSessionId, turnNumber, truncated }) => ({ originSessionId, turnNumber, truncated })),
|
|
33405
|
+
thinkingAvailable: context.thinkingAvailable,
|
|
33406
|
+
model: MODEL,
|
|
33407
|
+
repeatedProblem: judgment.repeatedProblem,
|
|
33408
|
+
clearlyStuck: judgment.clearlyStuck,
|
|
33409
|
+
struggleThreshold: STRUGGLE_THRESHOLD,
|
|
33410
|
+
struggling: judgment.struggling,
|
|
33411
|
+
termChoices: judgment.termChoices,
|
|
33412
|
+
noneProbability: judgment.noneProbability,
|
|
33413
|
+
selectedTerms: judgment.terms,
|
|
33414
|
+
query: judgment.terms.join(" "),
|
|
33415
|
+
matchThreshold: MATCH_THRESHOLD,
|
|
33416
|
+
review: null
|
|
33417
|
+
};
|
|
33377
33418
|
state.lastTurn = turnKey;
|
|
33378
33419
|
if (!judgment.struggling) {
|
|
33420
|
+
writeJevObservation(ctx.caveatHome, {
|
|
33421
|
+
...base,
|
|
33422
|
+
ftsHits: [],
|
|
33423
|
+
candidates: [],
|
|
33424
|
+
selectedRef: null,
|
|
33425
|
+
noticeText: null,
|
|
33426
|
+
decision: "below_struggle_threshold",
|
|
33427
|
+
delivery: "none"
|
|
33428
|
+
});
|
|
33379
33429
|
saveState(ctx.caveatHome, sessionId, state);
|
|
33380
33430
|
return null;
|
|
33381
33431
|
}
|
|
33382
33432
|
let candidates = [];
|
|
33383
33433
|
const query = judgment.terms.join(" ");
|
|
33434
|
+
let ftsHits = [];
|
|
33384
33435
|
if (query) {
|
|
33385
33436
|
if (!existsSync14(ctx.paths.dbPath)) throw new Error("jev_knowledge_index_missing");
|
|
33386
33437
|
const db = openDb({ path: ctx.paths.dbPath });
|
|
@@ -33388,26 +33439,41 @@ async function runJevStruggle(ctx, host, payload, deps = {}) {
|
|
|
33388
33439
|
const taskText = context.turns.map((turn) => `${turn.user}
|
|
33389
33440
|
${turn.assistant}
|
|
33390
33441
|
${turn.thinking}`).join("\n");
|
|
33391
|
-
|
|
33442
|
+
const hits = search(db, { query, limit: MAX_CANDIDATES });
|
|
33443
|
+
ftsHits = hits.map((hit) => `${hit.source}/${hit.id}`);
|
|
33444
|
+
candidates = hits.filter((hit) => environmentAppliesToTask(hit.environment, taskText, fingerprint().os)).map((hit) => ({ hit, entry: get(db, hit.id, hit.source) })).filter((item) => item.entry !== null).filter((item) => Boolean(item.entry.sections.Resolution));
|
|
33392
33445
|
} finally {
|
|
33393
33446
|
db.close();
|
|
33394
33447
|
}
|
|
33395
33448
|
}
|
|
33396
|
-
const
|
|
33449
|
+
const ranked = await rankKnowledge(key, context.turns, candidates, ask);
|
|
33450
|
+
const selected = ranked.selected;
|
|
33397
33451
|
const id = selected ? `${selected.hit.source}/${selected.hit.id}` : null;
|
|
33398
33452
|
const term = query || "_none";
|
|
33399
|
-
|
|
33453
|
+
const suppressed = Boolean(id && (state.deliveredIds.includes(id) || wasHitDelivered(ctx.caveatHome, sessionId, id)) || !id && state.notifiedTerms.includes(term));
|
|
33454
|
+
const noticeText = reminder(selected);
|
|
33455
|
+
writeJevObservation(ctx.caveatHome, {
|
|
33456
|
+
...base,
|
|
33457
|
+
ftsHits,
|
|
33458
|
+
candidates: candidates.map((candidate, index) => ({ ref: `${candidate.hit.source}/${candidate.hit.id}`, score: ranked.scores[index] })),
|
|
33459
|
+
selectedRef: id,
|
|
33460
|
+
noticeText: suppressed ? null : noticeText,
|
|
33461
|
+
decision: id ? "matched" : !query ? "no_terms" : candidates.length === 0 ? "no_candidates" : "below_match_threshold",
|
|
33462
|
+
delivery: suppressed ? "suppressed" : "pending"
|
|
33463
|
+
});
|
|
33464
|
+
if (suppressed) {
|
|
33400
33465
|
saveState(ctx.caveatHome, sessionId, state);
|
|
33401
33466
|
return null;
|
|
33402
33467
|
}
|
|
33403
33468
|
return {
|
|
33404
|
-
text:
|
|
33469
|
+
text: noticeText,
|
|
33405
33470
|
ref: id,
|
|
33406
33471
|
delivered: () => {
|
|
33407
33472
|
const current = loadState(ctx.caveatHome, sessionId);
|
|
33408
33473
|
current.lastTurn = turnKey;
|
|
33409
33474
|
if (id && !current.deliveredIds.includes(id)) current.deliveredIds.push(id);
|
|
33410
33475
|
if (!id && !current.notifiedTerms.includes(term)) current.notifiedTerms.push(term);
|
|
33476
|
+
updateJevDelivery(ctx.caveatHome, observationId);
|
|
33411
33477
|
saveState(ctx.caveatHome, sessionId, current);
|
|
33412
33478
|
if (selected) {
|
|
33413
33479
|
const db = openDb({ path: ctx.paths.dbPath });
|
|
@@ -34689,6 +34755,15 @@ function jevStatus(ctx) {
|
|
|
34689
34755
|
})}
|
|
34690
34756
|
`);
|
|
34691
34757
|
}
|
|
34758
|
+
function listJevCases(ctx) {
|
|
34759
|
+
process.stdout.write(`${JSON.stringify({ schema: "caveat.jev_cases.v1", cases: listJevObservations(ctx.caveatHome) })}
|
|
34760
|
+
`);
|
|
34761
|
+
}
|
|
34762
|
+
function reviewJevCase(ctx, id, verdict, note) {
|
|
34763
|
+
const item = reviewJevObservation(ctx.caveatHome, id, verdict, note);
|
|
34764
|
+
process.stdout.write(`${JSON.stringify({ id: item.id, review: item.review })}
|
|
34765
|
+
`);
|
|
34766
|
+
}
|
|
34692
34767
|
|
|
34693
34768
|
// src/index.ts
|
|
34694
34769
|
var program = new Command();
|
|
@@ -34717,6 +34792,13 @@ jev.command("disable").action(() => {
|
|
|
34717
34792
|
jev.command("status").action(() => {
|
|
34718
34793
|
jevStatus(buildContext(stdoutLogger));
|
|
34719
34794
|
});
|
|
34795
|
+
jev.command("cases").requiredOption("--json", "emit case records").action(() => {
|
|
34796
|
+
listJevCases(buildContext(stdoutLogger));
|
|
34797
|
+
});
|
|
34798
|
+
jev.command("review <id> <verdict>").description("Review one case: correct | incorrect | missed | none | unclear").option("--note <text>", "short reason for the verdict", "").action((id, verdict, opts) => {
|
|
34799
|
+
if (!["correct", "incorrect", "missed", "none", "unclear"].includes(verdict)) throw new Error("jev_review_verdict_invalid");
|
|
34800
|
+
reviewJevCase(buildContext(stdoutLogger), id, verdict, opts.note);
|
|
34801
|
+
});
|
|
34720
34802
|
var parseLimit = (value) => {
|
|
34721
34803
|
const parsed = parseCursor(value);
|
|
34722
34804
|
if (parsed < 1 || parsed > 256) throw Error("invalid_limit");
|