akm-cli 0.9.0-beta.2 → 0.9.0-beta.26
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 +614 -0
- package/dist/assets/prompts/consolidate-system.md +23 -0
- package/dist/assets/prompts/contradiction-judge.md +33 -0
- package/dist/assets/prompts/distill-knowledge-system.md +22 -0
- package/dist/assets/prompts/distill-lesson-system.md +36 -0
- package/dist/assets/prompts/extract-session.md +5 -1
- package/dist/assets/prompts/graph-extract-system.md +1 -0
- package/dist/assets/prompts/memory-infer-system.md +1 -0
- package/dist/assets/prompts/memory-infer-user.md +5 -0
- package/dist/assets/prompts/metadata-enhance-system.md +1 -0
- package/dist/assets/prompts/procedural-system.md +44 -0
- package/dist/assets/prompts/recombine-system.md +40 -0
- package/dist/assets/prompts/staleness-detect-system.md +6 -0
- package/dist/assets/prompts/validate-summary-judge.md +1 -0
- package/dist/assets/templates/html/default.html +78 -0
- package/dist/assets/templates/html/health.html +730 -0
- package/dist/assets/templates/html/vendor/echarts.min.js +45 -0
- package/dist/cli/shared.js +21 -5
- package/dist/cli.js +47 -5
- package/dist/commands/agent/contribute-cli.js +16 -3
- package/dist/commands/feedback-cli.js +15 -6
- package/dist/commands/graph/graph.js +75 -71
- package/dist/commands/health/checks.js +48 -0
- package/dist/commands/health/html-report.js +790 -0
- package/dist/commands/health.js +478 -15
- package/dist/commands/improve/calibration.js +161 -0
- package/dist/commands/improve/consolidate.js +634 -111
- package/dist/commands/improve/dedup.js +482 -0
- package/dist/commands/improve/distill.js +145 -69
- package/dist/commands/improve/encoding-salience.js +205 -0
- package/dist/commands/improve/extract-cli.js +115 -1
- package/dist/commands/improve/extract-prompt.js +33 -2
- package/dist/commands/improve/extract-watch.js +140 -0
- package/dist/commands/improve/extract.js +280 -35
- package/dist/commands/improve/feedback-valence.js +54 -0
- package/dist/commands/improve/homeostatic.js +467 -0
- package/dist/commands/improve/improve-auto-accept.js +139 -6
- package/dist/commands/improve/improve-profiles.js +12 -0
- package/dist/commands/improve/improve.js +1851 -515
- package/dist/commands/improve/memory/memory-contradiction-detect.js +23 -28
- package/dist/commands/improve/outcome-loop.js +256 -0
- package/dist/commands/improve/proactive-maintenance.js +87 -0
- package/dist/commands/improve/procedural.js +409 -0
- package/dist/commands/improve/recombine.js +488 -0
- package/dist/commands/improve/reflect-noise.js +0 -0
- package/dist/commands/improve/reflect.js +51 -1
- package/dist/commands/improve/related-sessions.js +120 -0
- package/dist/commands/improve/salience.js +386 -0
- package/dist/commands/improve/triage.js +95 -0
- package/dist/commands/lint/agent-linter.js +19 -24
- package/dist/commands/lint/base-linter.js +173 -60
- package/dist/commands/lint/command-linter.js +19 -24
- package/dist/commands/lint/env-key-rules.js +34 -1
- package/dist/commands/lint/index.js +30 -13
- package/dist/commands/lint/memory-linter.js +1 -1
- package/dist/commands/lint/registry.js +5 -2
- package/dist/commands/lint/task-linter.js +3 -3
- package/dist/commands/lint/workflow-linter.js +26 -1
- package/dist/commands/proposal/drain.js +73 -6
- package/dist/commands/proposal/proposal-cli.js +22 -10
- package/dist/commands/proposal/proposal.js +17 -1
- package/dist/commands/proposal/validators/proposals.js +369 -329
- package/dist/commands/read/curate.js +294 -79
- package/dist/commands/read/search-cli.js +7 -0
- package/dist/commands/read/search.js +1 -0
- package/dist/commands/remember.js +6 -2
- package/dist/commands/sources/installed-stashes.js +5 -1
- package/dist/commands/sources/stash-cli.js +10 -2
- package/dist/core/asset/frontmatter.js +166 -167
- package/dist/core/asset/markdown.js +8 -0
- package/dist/core/config/config-schema.js +241 -0
- package/dist/core/config/config.js +2 -2
- package/dist/core/logs-db.js +305 -0
- package/dist/core/paths.js +3 -0
- package/dist/core/state-db.js +706 -42
- package/dist/indexer/db/db.js +347 -38
- package/dist/indexer/db/graph-db.js +81 -86
- package/dist/indexer/ensure-index.js +152 -17
- package/dist/indexer/graph/graph-boost.js +51 -41
- package/dist/indexer/index-writer-lock.js +99 -0
- package/dist/indexer/indexer.js +114 -111
- package/dist/indexer/passes/memory-inference.js +71 -25
- package/dist/indexer/passes/staleness-detect.js +2 -5
- package/dist/indexer/search/db-search.js +15 -4
- package/dist/indexer/search/ranking.js +4 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -5
- package/dist/integrations/harnesses/opencode/session-log.js +9 -0
- package/dist/integrations/session-logs/index.js +16 -0
- package/dist/llm/client.js +38 -4
- package/dist/llm/embedder.js +27 -3
- package/dist/llm/embedders/local.js +66 -2
- package/dist/llm/graph-extract.js +2 -1
- package/dist/llm/memory-infer.js +4 -8
- package/dist/llm/metadata-enhance.js +9 -1
- package/dist/llm/usage-persist.js +77 -0
- package/dist/llm/usage-telemetry.js +103 -0
- package/dist/output/context.js +3 -2
- package/dist/output/html-render.js +73 -0
- package/dist/output/shapes/curate.js +14 -2
- package/dist/output/shapes/helpers.js +17 -1
- package/dist/output/text/helpers.js +78 -1
- package/dist/runtime.js +25 -1
- package/dist/scripts/migrate-storage.js +1194 -607
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +455 -270
- package/dist/sources/providers/tar-utils.js +16 -8
- package/dist/storage/sqlite-pragmas.js +146 -0
- package/dist/tasks/runner.js +99 -16
- package/dist/workflows/db.js +5 -2
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/data-and-telemetry.md +1 -0
- package/package.json +7 -5
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// Reliability computation
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
/** Number of fixed-width reliability buckets over [0, 1]. */
|
|
8
|
+
export const CALIBRATION_BUCKET_COUNT = 10;
|
|
9
|
+
function roundRate(value) {
|
|
10
|
+
return Number(value.toFixed(4));
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Assign a confidence in [0, 1] to one of {@link CALIBRATION_BUCKET_COUNT}
|
|
14
|
+
* fixed-width buckets. The final bucket is closed on the right so confidence
|
|
15
|
+
* === 1 lands in the top bucket rather than overflowing.
|
|
16
|
+
*/
|
|
17
|
+
function bucketIndex(confidence) {
|
|
18
|
+
const clamped = Math.min(1, Math.max(0, confidence));
|
|
19
|
+
const idx = Math.floor(clamped * CALIBRATION_BUCKET_COUNT);
|
|
20
|
+
return Math.min(CALIBRATION_BUCKET_COUNT - 1, idx);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Compute a deterministic calibration summary from a list of acted-on gate
|
|
24
|
+
* decisions. Pure: identical input always yields identical output, with no
|
|
25
|
+
* dependency on wall-clock time or randomness.
|
|
26
|
+
*/
|
|
27
|
+
export function summarizeCalibration(samples) {
|
|
28
|
+
const buckets = [];
|
|
29
|
+
const bucketCounts = new Array(CALIBRATION_BUCKET_COUNT).fill(0);
|
|
30
|
+
const bucketAccepted = new Array(CALIBRATION_BUCKET_COUNT).fill(0);
|
|
31
|
+
const bucketConfSum = new Array(CALIBRATION_BUCKET_COUNT).fill(0);
|
|
32
|
+
let accepted = 0;
|
|
33
|
+
let confSum = 0;
|
|
34
|
+
for (const sample of samples) {
|
|
35
|
+
const idx = bucketIndex(sample.confidence);
|
|
36
|
+
bucketCounts[idx] = (bucketCounts[idx] ?? 0) + 1;
|
|
37
|
+
bucketConfSum[idx] = (bucketConfSum[idx] ?? 0) + sample.confidence;
|
|
38
|
+
confSum += sample.confidence;
|
|
39
|
+
if (sample.outcome === "auto-accepted") {
|
|
40
|
+
accepted += 1;
|
|
41
|
+
bucketAccepted[idx] = (bucketAccepted[idx] ?? 0) + 1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const total = samples.length;
|
|
45
|
+
const width = 1 / CALIBRATION_BUCKET_COUNT;
|
|
46
|
+
for (let i = 0; i < CALIBRATION_BUCKET_COUNT; i += 1) {
|
|
47
|
+
const count = bucketCounts[i] ?? 0;
|
|
48
|
+
const acc = bucketAccepted[i] ?? 0;
|
|
49
|
+
buckets.push({
|
|
50
|
+
lower: roundRate(i * width),
|
|
51
|
+
upper: roundRate((i + 1) * width),
|
|
52
|
+
count,
|
|
53
|
+
accepted: acc,
|
|
54
|
+
acceptRate: count > 0 ? roundRate(acc / count) : 0,
|
|
55
|
+
meanConfidence: count > 0 ? roundRate((bucketConfSum[i] ?? 0) / count) : 0,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
const overallAcceptRate = total > 0 ? roundRate(accepted / total) : 0;
|
|
59
|
+
const meanConfidence = total > 0 ? roundRate(confSum / total) : 0;
|
|
60
|
+
return {
|
|
61
|
+
samples: total,
|
|
62
|
+
accepted,
|
|
63
|
+
rejected: total - accepted,
|
|
64
|
+
overallAcceptRate,
|
|
65
|
+
meanConfidence,
|
|
66
|
+
calibrationGap: total > 0 ? roundRate(meanConfidence - overallAcceptRate) : 0,
|
|
67
|
+
buckets,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Project a list of `gateDecision` records (read from the proposal store) into
|
|
72
|
+
* the acted-on calibration samples within an optional `[since, until)` window.
|
|
73
|
+
*
|
|
74
|
+
* Only `auto-accepted` / `auto-rejected` decisions with a finite confidence in
|
|
75
|
+
* [0, 1] contribute. `deferred` decisions and decisions missing a confidence
|
|
76
|
+
* are excluded (no realized accept/reject signal). The window filter uses each
|
|
77
|
+
* decision's `decidedAt` timestamp; decisions with an unparseable timestamp are
|
|
78
|
+
* kept only when no window is supplied.
|
|
79
|
+
*
|
|
80
|
+
* Exploration-budget promotions (`reason === "exploration-budget"`) are EXCLUDED:
|
|
81
|
+
* they are accepted regardless of confidence, so they carry no reliability signal
|
|
82
|
+
* about the gate threshold. Counting them would inflate the apparent accept-rate
|
|
83
|
+
* and bias the auto-tuner downward — they are exempt from auto-tune by design
|
|
84
|
+
* (WS-4 exploration budget).
|
|
85
|
+
*/
|
|
86
|
+
export function gateDecisionsToSamples(decisions, window) {
|
|
87
|
+
const sinceMs = window?.since ? new Date(window.since).getTime() : undefined;
|
|
88
|
+
const untilMs = window?.until ? new Date(window.until).getTime() : undefined;
|
|
89
|
+
const samples = [];
|
|
90
|
+
for (const decision of decisions) {
|
|
91
|
+
if (!decision)
|
|
92
|
+
continue;
|
|
93
|
+
if (decision.outcome !== "auto-accepted" && decision.outcome !== "auto-rejected")
|
|
94
|
+
continue;
|
|
95
|
+
if (decision.reason === "exploration-budget")
|
|
96
|
+
continue;
|
|
97
|
+
const confidence = decision.confidence;
|
|
98
|
+
if (typeof confidence !== "number" || !Number.isFinite(confidence) || confidence < 0 || confidence > 1)
|
|
99
|
+
continue;
|
|
100
|
+
if (sinceMs !== undefined || untilMs !== undefined) {
|
|
101
|
+
const ts = new Date(decision.decidedAt).getTime();
|
|
102
|
+
if (!Number.isFinite(ts))
|
|
103
|
+
continue;
|
|
104
|
+
if (sinceMs !== undefined && ts < sinceMs)
|
|
105
|
+
continue;
|
|
106
|
+
if (untilMs !== undefined && ts >= untilMs)
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
samples.push({ confidence, outcome: decision.outcome });
|
|
110
|
+
}
|
|
111
|
+
return samples;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Compute a bounded, opt-in threshold adjustment from a calibration summary.
|
|
115
|
+
* PURE and deterministic — does not mutate config or read the clock. The
|
|
116
|
+
* caller is responsible for persisting `newThreshold` and logging the result.
|
|
117
|
+
*
|
|
118
|
+
* Algorithm (deliberately simple and bounded):
|
|
119
|
+
* - When `autoTune` is false → no-op (`disabled`).
|
|
120
|
+
* - When samples < `minSamples` → no-op (`insufficient-samples`).
|
|
121
|
+
* - Otherwise nudge by at most `maxStep` toward `targetAcceptRate`, then
|
|
122
|
+
* clamp into `[minThreshold, maxThreshold]`. The step size scales with the
|
|
123
|
+
* gap from target but is capped, so a single run can never make a large
|
|
124
|
+
* swing.
|
|
125
|
+
*/
|
|
126
|
+
export function computeThresholdAutoTune(currentThreshold, summary, config) {
|
|
127
|
+
const previousThreshold = Math.round(currentThreshold);
|
|
128
|
+
const noop = (reason) => ({
|
|
129
|
+
adjusted: false,
|
|
130
|
+
previousThreshold,
|
|
131
|
+
newThreshold: previousThreshold,
|
|
132
|
+
delta: 0,
|
|
133
|
+
reason,
|
|
134
|
+
});
|
|
135
|
+
if (!config.autoTune)
|
|
136
|
+
return noop("disabled");
|
|
137
|
+
if (summary.samples < config.minSamples)
|
|
138
|
+
return noop("insufficient-samples");
|
|
139
|
+
const gap = config.targetAcceptRate - summary.overallAcceptRate;
|
|
140
|
+
// A small dead-band so tiny noise doesn't churn the threshold every run.
|
|
141
|
+
const DEAD_BAND = 0.01;
|
|
142
|
+
if (Math.abs(gap) <= DEAD_BAND)
|
|
143
|
+
return noop("within-target");
|
|
144
|
+
// gap > 0 ⇒ realized below target ⇒ raise threshold (be stricter).
|
|
145
|
+
// gap < 0 ⇒ realized above target ⇒ lower threshold (be more permissive).
|
|
146
|
+
const direction = gap > 0 ? 1 : -1;
|
|
147
|
+
// Scale the step with the gap magnitude (in points) but cap at maxStep.
|
|
148
|
+
const desiredMagnitude = Math.min(config.maxStep, Math.max(1, Math.round(Math.abs(gap) * 100)));
|
|
149
|
+
const proposed = previousThreshold + direction * desiredMagnitude;
|
|
150
|
+
const clamped = Math.min(config.maxThreshold, Math.max(config.minThreshold, proposed));
|
|
151
|
+
const delta = clamped - previousThreshold;
|
|
152
|
+
if (delta === 0)
|
|
153
|
+
return noop("clamped-at-bound");
|
|
154
|
+
return {
|
|
155
|
+
adjusted: true,
|
|
156
|
+
previousThreshold,
|
|
157
|
+
newThreshold: clamped,
|
|
158
|
+
delta,
|
|
159
|
+
reason: direction > 0 ? "below-target-raise" : "above-target-lower",
|
|
160
|
+
};
|
|
161
|
+
}
|