akm-cli 0.9.0-rc.0 → 0.9.0-rc.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 +339 -2
- package/SECURITY.md +23 -24
- package/dist/assets/help/help-improve.md +10 -10
- package/dist/assets/hints/cli-hints-full.md +44 -10
- package/dist/assets/hints/cli-hints-short.md +6 -2
- package/dist/assets/{profiles → improve-strategies}/default.json +1 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +1 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +2 -3
- package/dist/assets/{profiles → improve-strategies}/reflect-distill.json +3 -4
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +28 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +12 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +11 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +98 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +63 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +127 -0
- package/dist/assets/tasks/core/backup.yml +1 -0
- package/dist/assets/tasks/core/extract.yml +1 -0
- package/dist/assets/tasks/core/improve.yml +1 -0
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +1 -0
- package/dist/assets/tasks/graph-refresh-weekly.yml +4 -4
- package/dist/assets/templates/html/health.html +5 -1
- package/dist/cli/config-migrate.js +31 -138
- package/dist/cli/config-validate.js +10 -8
- package/dist/cli.js +48 -14
- package/dist/commands/agent/agent-dispatch.js +17 -16
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +5 -15
- package/dist/commands/backup-cli.js +54 -0
- package/dist/commands/config-cli.js +45 -159
- package/dist/commands/env/env-binding.js +95 -0
- package/dist/commands/env/env-cli.js +8 -65
- package/dist/commands/env/secret.js +8 -5
- package/dist/commands/health/checks.js +130 -83
- package/dist/commands/health/html-report.js +4 -0
- package/dist/commands/health/improve-metrics.js +30 -32
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +4 -0
- package/dist/commands/health/metrics.js +2 -1
- package/dist/commands/health/surfaces.js +5 -4
- package/dist/commands/health.js +1 -1
- package/dist/commands/improve/consolidate/chunking.js +2 -2
- package/dist/commands/improve/consolidate.js +28 -25
- package/dist/commands/improve/distill/promote-memory.js +5 -12
- package/dist/commands/improve/distill/quality-gate.js +5 -7
- package/dist/commands/improve/distill.js +16 -5
- package/dist/commands/improve/eligibility.js +22 -12
- package/dist/commands/improve/extract-cli.js +47 -19
- package/dist/commands/improve/extract.js +110 -62
- package/dist/commands/improve/improve-cli.js +38 -16
- package/dist/commands/improve/improve-result-file.js +30 -24
- package/dist/commands/improve/improve-strategies.js +137 -0
- package/dist/commands/improve/improve.js +60 -30
- package/dist/commands/improve/locks.js +66 -45
- package/dist/commands/improve/loop-stages.js +75 -33
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +12 -4
- package/dist/commands/improve/preparation.js +71 -73
- package/dist/commands/improve/procedural.js +3 -2
- package/dist/commands/improve/recombine.js +2 -1
- package/dist/commands/improve/reflect.js +119 -214
- package/dist/commands/improve/shared.js +11 -5
- package/dist/commands/lint/base-linter.js +152 -42
- package/dist/commands/mv-cli.js +809 -0
- package/dist/commands/proposal/proposal-cli.js +18 -8
- package/dist/commands/proposal/propose.js +64 -69
- package/dist/commands/read/knowledge.js +436 -4
- package/dist/commands/read/remember-cli.js +39 -2
- package/dist/commands/read/search-cli.js +6 -1
- package/dist/commands/registry-cli.js +29 -14
- package/dist/commands/remember.js +2 -0
- package/dist/commands/sources/init.js +13 -14
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +2 -4
- package/dist/commands/sources/source-add.js +62 -73
- package/dist/commands/sources/source-manage.js +50 -46
- package/dist/commands/sources/stash-cli.js +41 -4
- package/dist/commands/tasks/default-tasks.js +12 -12
- package/dist/commands/tasks/tasks-cli.js +7 -3
- package/dist/commands/tasks/tasks.js +113 -18
- package/dist/commands/wiki-cli.js +9 -10
- package/dist/commands/workflow-cli.js +276 -12
- package/dist/core/asset/asset-spec.js +58 -1
- package/dist/core/asset/frontmatter.js +12 -2
- package/dist/core/common.js +5 -3
- package/dist/core/config/config-io.js +28 -17
- package/dist/core/config/config-schema.js +379 -66
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +98 -27
- package/dist/core/config/config.js +132 -266
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +32 -0
- package/dist/core/errors.js +2 -2
- package/dist/core/extra-params.js +61 -0
- package/dist/core/file-lock.js +201 -56
- package/dist/core/improve-result.js +178 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/maintenance-barrier.js +119 -0
- package/dist/core/migration-backup.js +416 -0
- package/dist/core/paths.js +3 -0
- package/dist/core/redaction.js +358 -0
- package/dist/core/state/migrations.js +17 -2
- package/dist/core/state-db.js +44 -1
- package/dist/indexer/db/db.js +118 -2
- package/dist/indexer/graph/graph-extraction.js +28 -16
- package/dist/indexer/index-writer-lock.js +31 -24
- package/dist/indexer/index-written-assets.js +15 -6
- package/dist/indexer/indexer.js +47 -2
- package/dist/indexer/passes/memory-inference.js +10 -6
- package/dist/indexer/passes/metadata.js +250 -0
- package/dist/indexer/search/db-search.js +111 -44
- package/dist/indexer/search/fts-query.js +41 -0
- package/dist/indexer/search/ranking-contributors.js +48 -0
- package/dist/indexer/search/ranking.js +36 -23
- package/dist/indexer/search/search-fields.js +11 -1
- package/dist/indexer/walk/matchers.js +39 -0
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -50
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +202 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/runner-dispatch.js +91 -4
- package/dist/integrations/agent/runner.js +76 -207
- package/dist/integrations/agent/spawn.js +141 -20
- package/dist/integrations/harnesses/aider/agent-builder.js +112 -0
- package/dist/integrations/harnesses/aider/index.js +57 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +152 -0
- package/dist/integrations/harnesses/amazonq/index.js +58 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/index.js +25 -25
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/codex/agent-builder.js +136 -0
- package/dist/integrations/harnesses/codex/index.js +62 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +121 -0
- package/dist/integrations/harnesses/copilot/index.js +59 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +59 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/index.js +27 -28
- package/dist/integrations/harnesses/opencode/agent-builder.js +2 -3
- package/dist/integrations/harnesses/opencode/index.js +15 -22
- package/dist/integrations/harnesses/opencode-sdk/harness.js +60 -0
- package/dist/integrations/harnesses/opencode-sdk/index.js +8 -32
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +125 -0
- package/dist/integrations/harnesses/openhands/index.js +57 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +103 -0
- package/dist/integrations/harnesses/pi/index.js +57 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/types.js +8 -32
- package/dist/integrations/lockfile.js +32 -21
- package/dist/integrations/session-logs/index.js +24 -11
- package/dist/llm/client.js +48 -14
- package/dist/llm/feature-gate.js +15 -47
- package/dist/llm/graph-extract.js +1 -1
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer-impl.js +1 -1
- package/dist/llm/usage-persist.js +4 -0
- package/dist/llm/usage-telemetry.js +35 -5
- package/dist/output/renderers.js +3 -2
- package/dist/output/shapes/helpers.js +2 -1
- package/dist/output/shapes/passthrough.js +6 -0
- package/dist/output/text/helpers.js +215 -2
- package/dist/output/text/workflow.js +3 -1
- package/dist/schemas/akm-config.json +16638 -0
- package/dist/schemas/akm-task.json +87 -0
- package/dist/schemas/akm-workflow.json +372 -0
- package/dist/scripts/migrate-storage.js +10944 -8801
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9247 -350
- package/dist/setup/detected-engines.js +142 -0
- package/dist/setup/engine-config.js +89 -0
- package/dist/setup/setup.js +236 -132
- package/dist/setup/steps/connection.js +61 -32
- package/dist/setup/steps/platforms.js +4 -4
- package/dist/setup/steps.js +3 -2
- package/dist/storage/database.js +13 -1
- package/dist/storage/engines/sqlite-migrations.js +1 -0
- package/dist/storage/repositories/improve-runs-repository.js +5 -5
- package/dist/storage/repositories/task-history-repository.js +78 -0
- package/dist/storage/repositories/workflow-runs-repository.js +190 -1
- package/dist/tasks/parser.js +138 -52
- package/dist/tasks/runner.js +71 -75
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/validator.js +11 -6
- package/dist/text-import-hook.mjs +1 -1
- package/dist/wiki/wiki.js +9 -8
- package/dist/workflows/authoring/authoring.js +123 -10
- package/dist/workflows/authoring/workflow-program-template.yaml +31 -0
- package/dist/workflows/cli.js +4 -0
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/db.js +200 -13
- package/dist/workflows/exec/brief.js +478 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1034 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1355 -0
- package/dist/workflows/exec/run-workflow.js +609 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1212 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/watch.js +116 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +375 -0
- package/dist/workflows/ir/freeze.js +243 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +545 -0
- package/dist/workflows/parser.js +10 -1
- package/dist/workflows/program/expressions.js +369 -0
- package/dist/workflows/program/parser.js +869 -0
- package/dist/workflows/program/project.js +104 -0
- package/dist/workflows/program/schema.js +54 -0
- package/dist/workflows/renderer.js +82 -5
- package/dist/workflows/resource-limits.js +20 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/plan-classifier.js +187 -0
- package/dist/workflows/runtime/runs.js +246 -69
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +42 -1
- package/dist/workflows/validate-summary.js +24 -3
- package/dist/workflows/validator.js +26 -1
- package/docs/data-and-telemetry.md +4 -3
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +5 -4
- package/docs/migration/release-notes/0.9.0-beta.60.md +19 -0
- package/docs/migration/v0.8-to-v0.9.md +401 -0
- package/package.json +4 -2
- package/schemas/akm-config.json +16638 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +372 -0
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/llm/call-ai.js +0 -62
- package/dist/setup/legacy-config.js +0 -106
- package/docs/README.md +0 -104
- /package/dist/assets/{profiles → improve-strategies}/catchup.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/consolidate.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/frequent.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/memory-focus.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/quick.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/recombine-only.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/synthesize.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/thorough.json +0 -0
|
@@ -2,111 +2,158 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { spawnSync } from "node:child_process";
|
|
5
|
+
import { createRequire } from "node:module";
|
|
5
6
|
import { loadConfig } from "../../core/config/config.js";
|
|
6
|
-
import {
|
|
7
|
+
import { resolveEngine } from "../../integrations/agent/engine-resolution.js";
|
|
8
|
+
import { resolveModel } from "../../integrations/agent/model-aliases.js";
|
|
7
9
|
import { TASK_FAIL_RATE_WARN, } from "./types.js";
|
|
8
10
|
const ACTIVE_RUN_WARN_MS = 15 * 60 * 1000;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
14
|
-
export function runAgentProbe() {
|
|
15
|
-
const config = loadConfig();
|
|
16
|
-
// v2: check profiles.agent first
|
|
17
|
-
if (config.profiles?.agent) {
|
|
18
|
-
const defaultName = config.defaults?.agent;
|
|
19
|
-
const profileCount = Object.keys(config.profiles.agent).length;
|
|
20
|
-
if (profileCount === 0) {
|
|
21
|
-
return {
|
|
22
|
-
name: "agent-profile",
|
|
23
|
-
kind: "deterministic",
|
|
24
|
-
status: "unknown",
|
|
25
|
-
confidence: "high",
|
|
26
|
-
message: "No agent profiles configured in profiles.agent.",
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
const profileName = defaultName ?? Object.keys(config.profiles.agent)[0];
|
|
30
|
-
const profile = config.profiles.agent[profileName];
|
|
11
|
+
export function runDefaultEngineProbe(deps = {}) {
|
|
12
|
+
const config = deps.loadConfig?.() ?? loadConfig();
|
|
13
|
+
const engineName = config.defaults?.engine ?? config.defaults?.llmEngine;
|
|
14
|
+
if (!engineName) {
|
|
31
15
|
return {
|
|
32
|
-
name: "
|
|
33
|
-
kind: "deterministic",
|
|
34
|
-
status: "pass",
|
|
35
|
-
confidence: "high",
|
|
36
|
-
message: `v2 agent profile "${profileName}" configured (platform: ${profile?.platform ?? "unknown"}).`,
|
|
37
|
-
evidence: { profile: profileName, platform: profile?.platform, profileCount },
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
if (!config.profiles?.agent && !config.defaults?.agent) {
|
|
41
|
-
return {
|
|
42
|
-
name: "agent-profile",
|
|
16
|
+
name: "default-engine",
|
|
43
17
|
kind: "deterministic",
|
|
44
18
|
status: "unknown",
|
|
45
19
|
confidence: "high",
|
|
46
|
-
message: "No
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
let profile;
|
|
50
|
-
try {
|
|
51
|
-
profile = requireAgentProfile(config);
|
|
52
|
-
}
|
|
53
|
-
catch (error) {
|
|
54
|
-
return {
|
|
55
|
-
name: "agent-profile",
|
|
56
|
-
kind: "deterministic",
|
|
57
|
-
status: "warn",
|
|
58
|
-
confidence: "high",
|
|
59
|
-
message: error instanceof Error ? error.message : String(error),
|
|
20
|
+
message: "No default engine is configured.",
|
|
60
21
|
};
|
|
61
22
|
}
|
|
62
|
-
|
|
23
|
+
const configuredEngine = config.engines?.[engineName];
|
|
24
|
+
if (configuredEngine?.kind === "agent" && configuredEngine.platform === "opencode-sdk") {
|
|
25
|
+
let packageAvailable = false;
|
|
26
|
+
try {
|
|
27
|
+
const resolvePackage = deps.resolvePackage ?? ((name) => createRequire(import.meta.url).resolve(name));
|
|
28
|
+
resolvePackage("@opencode-ai/sdk");
|
|
29
|
+
packageAvailable = true;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
packageAvailable = false;
|
|
33
|
+
}
|
|
34
|
+
const binary = configuredEngine.bin ?? "opencode";
|
|
35
|
+
const version = (deps.spawnSync ?? spawnSync)(binary, ["--version"], { encoding: "utf8", timeout: 5_000 });
|
|
36
|
+
const binaryAvailable = (version.status ?? 1) === 0;
|
|
37
|
+
const fallbackEngine = configuredEngine.llmEngine ?? config.defaults?.llmEngine;
|
|
38
|
+
let fallback;
|
|
39
|
+
let sdkRunner;
|
|
40
|
+
const resolve = deps.resolveEngine ?? resolveEngine;
|
|
41
|
+
try {
|
|
42
|
+
const resolved = resolve(engineName, config);
|
|
43
|
+
if (resolved.kind === "sdk")
|
|
44
|
+
sdkRunner = resolved;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
sdkRunner = undefined;
|
|
48
|
+
}
|
|
49
|
+
if (sdkRunner?.fallbackConnection) {
|
|
50
|
+
fallback = { kind: "llm", connection: sdkRunner.fallbackConnection };
|
|
51
|
+
}
|
|
52
|
+
else if (fallbackEngine) {
|
|
53
|
+
try {
|
|
54
|
+
const resolved = resolve(fallbackEngine, config);
|
|
55
|
+
if (resolved.kind === "llm")
|
|
56
|
+
fallback = resolved;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
fallback = undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const configuredModel = configuredEngine.model
|
|
63
|
+
? resolveModel(configuredEngine.model, "opencode-sdk", configuredEngine.modelAliases, config.modelAliases)
|
|
64
|
+
: undefined;
|
|
65
|
+
const effectiveModel = sdkRunner?.profile.model ?? configuredModel ?? fallback?.connection.model;
|
|
66
|
+
const missing = [
|
|
67
|
+
!packageAvailable ? "@opencode-ai/sdk package" : undefined,
|
|
68
|
+
!binaryAvailable ? `${binary} binary` : undefined,
|
|
69
|
+
!fallback ? "fallback LLM connection" : undefined,
|
|
70
|
+
!effectiveModel ? "effective SDK model" : undefined,
|
|
71
|
+
].filter((value) => value !== undefined);
|
|
63
72
|
return {
|
|
64
|
-
name: "
|
|
73
|
+
name: "default-engine",
|
|
65
74
|
kind: "deterministic",
|
|
66
|
-
status:
|
|
75
|
+
status: missing.length === 0 ? "pass" : "warn",
|
|
67
76
|
confidence: "high",
|
|
68
|
-
message:
|
|
69
|
-
? `SDK
|
|
70
|
-
: `SDK
|
|
71
|
-
evidence: {
|
|
77
|
+
message: missing.length === 0
|
|
78
|
+
? `SDK engine "${engineName}" is available.`
|
|
79
|
+
: `SDK engine "${engineName}" is incomplete: missing ${missing.join(", ")}.`,
|
|
80
|
+
evidence: {
|
|
81
|
+
engine: engineName,
|
|
82
|
+
platform: configuredEngine.platform,
|
|
83
|
+
runtimeKind: "sdk",
|
|
84
|
+
binary,
|
|
85
|
+
binaryAvailable,
|
|
86
|
+
package: "@opencode-ai/sdk",
|
|
87
|
+
packageAvailable,
|
|
88
|
+
model: effectiveModel ?? null,
|
|
89
|
+
configuredModel: configuredModel ?? null,
|
|
90
|
+
modelSource: configuredModel ? "sdk" : effectiveModel ? "fallback" : null,
|
|
91
|
+
fallbackEngine: fallbackEngine ?? null,
|
|
92
|
+
fallbackEndpoint: fallback?.connection.endpoint ?? null,
|
|
93
|
+
fallbackModel: fallback?.connection.model ?? null,
|
|
94
|
+
},
|
|
72
95
|
};
|
|
73
96
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
97
|
+
try {
|
|
98
|
+
const runner = (deps.resolveEngine ?? resolveEngine)(engineName, config);
|
|
99
|
+
if (runner.kind === "llm") {
|
|
100
|
+
return {
|
|
101
|
+
name: "default-engine",
|
|
102
|
+
kind: "deterministic",
|
|
103
|
+
status: "pass",
|
|
104
|
+
confidence: "high",
|
|
105
|
+
message: `LLM engine "${engineName}" is configured.`,
|
|
106
|
+
evidence: {
|
|
107
|
+
engine: engineName,
|
|
108
|
+
platform: null,
|
|
109
|
+
runtimeKind: "llm",
|
|
110
|
+
model: runner.connection.model,
|
|
111
|
+
endpoint: runner.connection.endpoint,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const profile = runner.profile;
|
|
116
|
+
if (runner.kind === "sdk")
|
|
117
|
+
throw new Error(`SDK engine "${engineName}" has no matching SDK config.`);
|
|
118
|
+
const version = (deps.spawnSync ?? spawnSync)(profile.bin, ["--version"], { encoding: "utf8", timeout: 5_000 });
|
|
119
|
+
if ((version.status ?? 1) !== 0) {
|
|
120
|
+
return {
|
|
121
|
+
name: "default-engine",
|
|
122
|
+
kind: "deterministic",
|
|
123
|
+
status: "warn",
|
|
124
|
+
confidence: "medium",
|
|
125
|
+
message: `Agent engine "${engineName}" was found but \`--version\` failed.`,
|
|
126
|
+
evidence: {
|
|
127
|
+
engine: engineName,
|
|
128
|
+
platform: profile.platform ?? null,
|
|
129
|
+
runtimeKind: "agent",
|
|
130
|
+
model: profile.model ?? null,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
77
134
|
return {
|
|
78
|
-
name: "
|
|
135
|
+
name: "default-engine",
|
|
79
136
|
kind: "deterministic",
|
|
80
|
-
status: "
|
|
137
|
+
status: "pass",
|
|
81
138
|
confidence: "high",
|
|
82
|
-
message: `
|
|
83
|
-
evidence: {
|
|
139
|
+
message: `Agent engine "${engineName}" is available.`,
|
|
140
|
+
evidence: {
|
|
141
|
+
engine: engineName,
|
|
142
|
+
platform: profile.platform ?? null,
|
|
143
|
+
runtimeKind: "agent",
|
|
144
|
+
model: profile.model ?? null,
|
|
145
|
+
},
|
|
84
146
|
};
|
|
85
147
|
}
|
|
86
|
-
|
|
87
|
-
if ((version.status ?? 1) !== 0) {
|
|
148
|
+
catch (error) {
|
|
88
149
|
return {
|
|
89
|
-
name: "
|
|
150
|
+
name: "default-engine",
|
|
90
151
|
kind: "deterministic",
|
|
91
152
|
status: "warn",
|
|
92
|
-
confidence: "
|
|
93
|
-
message:
|
|
94
|
-
evidence: {
|
|
95
|
-
profile: profile.name,
|
|
96
|
-
bin: profile.bin,
|
|
97
|
-
exitCode: version.status ?? null,
|
|
98
|
-
stderr: (version.stderr ?? "").trim(),
|
|
99
|
-
},
|
|
153
|
+
confidence: "high",
|
|
154
|
+
message: error instanceof Error ? error.message : String(error),
|
|
100
155
|
};
|
|
101
156
|
}
|
|
102
|
-
return {
|
|
103
|
-
name: "agent-profile",
|
|
104
|
-
kind: "deterministic",
|
|
105
|
-
status: "pass",
|
|
106
|
-
confidence: "high",
|
|
107
|
-
message: `Agent profile "${profile.name}" is available.`,
|
|
108
|
-
evidence: { profile: profile.name, bin: profile.bin, version: (version.stdout ?? "").trim() },
|
|
109
|
-
};
|
|
110
157
|
}
|
|
111
158
|
/**
|
|
112
159
|
* The ordered health-check registry. ORDER IS LOAD-BEARING: `akmHealth`
|
|
@@ -185,9 +232,9 @@ export const HEALTH_CHECKS = [
|
|
|
185
232
|
}),
|
|
186
233
|
},
|
|
187
234
|
{
|
|
188
|
-
name: "
|
|
235
|
+
name: "default-engine",
|
|
189
236
|
channel: "hard",
|
|
190
|
-
run: () =>
|
|
237
|
+
run: () => runDefaultEngineProbe(),
|
|
191
238
|
},
|
|
192
239
|
{
|
|
193
240
|
// C2 (13-bus-factor): the cron task-failure rate was computed and rendered
|
|
@@ -93,6 +93,8 @@ function reshapeRun(r) {
|
|
|
93
93
|
return {
|
|
94
94
|
id: r.id,
|
|
95
95
|
taskId: r.taskId ?? "manual",
|
|
96
|
+
strategy: r.strategy,
|
|
97
|
+
legacyProfile: r.legacyProfile,
|
|
96
98
|
startedAt: r.startedAt,
|
|
97
99
|
completedAt: r.completedAt,
|
|
98
100
|
wallTimeMs: wall,
|
|
@@ -295,6 +297,8 @@ export function buildHealthHtmlReplacements(result, opts) {
|
|
|
295
297
|
totalTokens: 0,
|
|
296
298
|
reasoningTokens: 0,
|
|
297
299
|
byStage: {},
|
|
300
|
+
byProcess: {},
|
|
301
|
+
byEngine: {},
|
|
298
302
|
};
|
|
299
303
|
const totalRuns = runs.length;
|
|
300
304
|
const failedRuns = runs.filter((r) => !r.ok).length;
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import { decodeImproveResult } from "../../core/improve-result.js";
|
|
4
5
|
import { queryImproveRuns } from "../../storage/repositories/improve-runs-repository.js";
|
|
6
|
+
import { decodeTaskHistoryMetadata } from "../../storage/repositories/task-history-repository.js";
|
|
5
7
|
import { summarizeCalibration } from "../improve/calibration.js";
|
|
6
8
|
export function roundRate(value) {
|
|
7
9
|
return Number(value.toFixed(4));
|
|
8
10
|
}
|
|
9
11
|
export function parseTaskMetadata(row) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
const metadata = decodeTaskHistoryMetadata(row.metadata_json);
|
|
13
|
+
return {
|
|
14
|
+
...(metadata.durationMs !== undefined ? { durationMs: metadata.durationMs } : {}),
|
|
15
|
+
...(metadata.detail ? { detail: metadata.detail } : {}),
|
|
16
|
+
...(metadata.metadataVersion === 2 && metadata.engine !== undefined ? { engine: metadata.engine } : {}),
|
|
17
|
+
...(metadata.metadataVersion === 1 && metadata.legacyProfile !== undefined
|
|
18
|
+
? { legacyProfile: metadata.legacyProfile }
|
|
19
|
+
: {}),
|
|
20
|
+
};
|
|
16
21
|
}
|
|
17
22
|
function createUnknownImproveMetrics() {
|
|
18
23
|
return {
|
|
@@ -21,7 +26,7 @@ function createUnknownImproveMetrics() {
|
|
|
21
26
|
skipped: 0,
|
|
22
27
|
skipReasons: {},
|
|
23
28
|
plannedRefs: 0,
|
|
24
|
-
|
|
29
|
+
strategyFilteredRefs: 0,
|
|
25
30
|
actions: {
|
|
26
31
|
reflect: { ok: 0, failed: 0, cooldown: 0, skipped: 0, guardRejected: 0, skippedByReason: {} },
|
|
27
32
|
distill: {
|
|
@@ -181,12 +186,14 @@ function projectRunMetrics(result) {
|
|
|
181
186
|
const plannedRefs = result.plannedRefs;
|
|
182
187
|
if (Array.isArray(plannedRefs))
|
|
183
188
|
metrics.plannedRefs += plannedRefs.length;
|
|
184
|
-
//
|
|
189
|
+
// strategyFilteredRefs (array of {ref, reason}) — 2026-05-27: pre-filter
|
|
185
190
|
// bucket from `collectEligibleRefs` so the metric reflects work the
|
|
186
191
|
// planner dropped before signal-delta / per-pass dispatch.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
192
|
+
// Health v3 reports strategy metrics only. Historical v1 profile filtering
|
|
193
|
+
// remains legacy data and must not be silently relabelled as a strategy metric.
|
|
194
|
+
const strategyFilteredRefs = result.schemaVersion === 2 ? result.strategyFilteredRefs : undefined;
|
|
195
|
+
if (Array.isArray(strategyFilteredRefs))
|
|
196
|
+
metrics.strategyFilteredRefs += strategyFilteredRefs.length;
|
|
190
197
|
// actions: split reflect / distill by outcome, count others.
|
|
191
198
|
const actions = result.actions;
|
|
192
199
|
if (Array.isArray(actions)) {
|
|
@@ -496,8 +503,8 @@ function finalizeImproveMetrics(metrics) {
|
|
|
496
503
|
*/
|
|
497
504
|
function mergeImproveMetrics(dst, src) {
|
|
498
505
|
dst.plannedRefs += src.plannedRefs;
|
|
499
|
-
//
|
|
500
|
-
// active
|
|
506
|
+
// strategyFilteredRefs is the count of refs the planner drops up-front for the
|
|
507
|
+
// active strategy — recomputed against the (stable) stash every run, so it is a
|
|
501
508
|
// snapshot, NOT a per-run increment. Summing it re-counts the same refs each
|
|
502
509
|
// run (the ~2.4M bug). Set from the most recent run in summarizeImproveRuns.
|
|
503
510
|
dst.actions.reflect.ok += src.actions.reflect.ok;
|
|
@@ -613,22 +620,16 @@ export function summarizeImproveRuns(db, since, until) {
|
|
|
613
620
|
// MOST RECENT run's snapshot (current state) — not a sum across runs.
|
|
614
621
|
let latestStartMs = Number.NEGATIVE_INFINITY;
|
|
615
622
|
let latestMemorySummary;
|
|
616
|
-
let
|
|
623
|
+
let latestStrategyFilteredRefs = 0;
|
|
617
624
|
for (const row of rows) {
|
|
618
|
-
|
|
619
|
-
try {
|
|
620
|
-
result = JSON.parse(row.result_json);
|
|
621
|
-
}
|
|
622
|
-
catch {
|
|
623
|
-
continue;
|
|
624
|
-
}
|
|
625
|
+
const result = decodeImproveResult(row.result_json).envelope;
|
|
625
626
|
const perRow = projectRunMetrics(result);
|
|
626
627
|
mergeImproveMetrics(accum, perRow);
|
|
627
628
|
const startMs = new Date(row.started_at).getTime();
|
|
628
629
|
if (Number.isFinite(startMs) && startMs >= latestStartMs) {
|
|
629
630
|
latestStartMs = startMs;
|
|
630
631
|
latestMemorySummary = perRow.memorySummary;
|
|
631
|
-
|
|
632
|
+
latestStrategyFilteredRefs = perRow.strategyFilteredRefs;
|
|
632
633
|
}
|
|
633
634
|
// Collect per-phase durations directly off the envelope. consolidation's
|
|
634
635
|
// duration lives inside the sub-object; memoryInference and graphExtraction
|
|
@@ -648,7 +649,7 @@ export function summarizeImproveRuns(db, since, until) {
|
|
|
648
649
|
finalizeImproveMetrics(accum);
|
|
649
650
|
if (latestMemorySummary)
|
|
650
651
|
accum.memorySummary = latestMemorySummary;
|
|
651
|
-
accum.
|
|
652
|
+
accum.strategyFilteredRefs = latestStrategyFilteredRefs;
|
|
652
653
|
accum.wallTime.byPhase = {
|
|
653
654
|
consolidation: summarizePhaseDurations(phaseDurations.consolidation),
|
|
654
655
|
memoryInference: summarizePhaseDurations(phaseDurations.memoryInference),
|
|
@@ -680,13 +681,8 @@ export function summarizePhaseDurations(samples) {
|
|
|
680
681
|
* Used by `akm health --detail per-run`.
|
|
681
682
|
*/
|
|
682
683
|
export function projectImproveRunSummary(row, wallTimeMs, taskId) {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
result = JSON.parse(row.result_json);
|
|
686
|
-
}
|
|
687
|
-
catch {
|
|
688
|
-
// fall through with empty result so per-stage rollups are zeros
|
|
689
|
-
}
|
|
684
|
+
const decoded = decodeImproveResult(row.result_json);
|
|
685
|
+
const result = decoded.envelope;
|
|
690
686
|
const perRow = projectRunMetrics(result);
|
|
691
687
|
finalizeImproveMetrics(perRow);
|
|
692
688
|
const orphansPurged = toFiniteNumber(result.orphansPurged);
|
|
@@ -699,6 +695,8 @@ export function projectImproveRunSummary(row, wallTimeMs, taskId) {
|
|
|
699
695
|
completedAt: row.completed_at,
|
|
700
696
|
wallTimeMs,
|
|
701
697
|
ok: row.ok === 1,
|
|
698
|
+
strategy: row.strategy,
|
|
699
|
+
legacyProfile: row.legacyProfile,
|
|
702
700
|
scope: {
|
|
703
701
|
mode: row.scope_mode,
|
|
704
702
|
...(row.scope_value ? { value: row.scope_value } : {}),
|
|
@@ -744,10 +742,10 @@ export function buildImproveSkipSummary(events) {
|
|
|
744
742
|
// - Per-occurrence (no `count`): one event per skipped ref → SUM is correct.
|
|
745
743
|
// - Aggregated snapshot (carries `count`): a single per-run event whose count
|
|
746
744
|
// is the number of refs that hit a STABLE, whole-stash condition that run
|
|
747
|
-
// (`no_new_signal`, `
|
|
745
|
+
// (`no_new_signal`, `strategy_filtered_all_passes`). Each run re-counts the
|
|
748
746
|
// same stable set, so summing across the window re-counts it N times (the
|
|
749
747
|
// 2.7M / 3M inflation). For these we keep the MOST RECENT run's count — the
|
|
750
|
-
// current snapshot — matching how memorySummary/
|
|
748
|
+
// current snapshot — matching how memorySummary/strategyFilteredRefs are
|
|
751
749
|
// handled. Events arrive in chronological (offset) order, so the last
|
|
752
750
|
// count-bearing event per reason is the latest run's value.
|
|
753
751
|
const summed = {};
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { readEvents } from "../../core/events.js";
|
|
9
9
|
import { LLM_USAGE_EVENT } from "../../llm/usage-persist.js";
|
|
10
|
-
import {
|
|
10
|
+
import { decodeLlmUsageRecord } from "../../llm/usage-telemetry.js";
|
|
11
11
|
/** Stage key used for `llm_usage` events recorded outside any stage scope. */
|
|
12
12
|
const UNATTRIBUTED_STAGE = "unattributed";
|
|
13
13
|
function emptyLlmUsageStageAggregate() {
|
|
@@ -21,7 +21,7 @@ function emptyLlmUsageStageAggregate() {
|
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
function emptyLlmUsageAggregate() {
|
|
24
|
-
return { ...emptyLlmUsageStageAggregate(), byStage: {} };
|
|
24
|
+
return { ...emptyLlmUsageStageAggregate(), byStage: {}, byProcess: {}, byEngine: {} };
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Aggregate `llm_usage` events (#576) into a window total plus a per-stage
|
|
@@ -32,25 +32,25 @@ function emptyLlmUsageAggregate() {
|
|
|
32
32
|
export function summarizeLlmUsage(events) {
|
|
33
33
|
const aggregate = emptyLlmUsageAggregate();
|
|
34
34
|
for (const event of events) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
aggregate.byStage
|
|
35
|
+
const record = decodeLlmUsageRecord(event.metadata);
|
|
36
|
+
if (!record)
|
|
37
|
+
continue;
|
|
38
|
+
const dimensions = [];
|
|
39
|
+
for (const [groups, key] of [
|
|
40
|
+
[aggregate.byStage, record.stage ?? UNATTRIBUTED_STAGE],
|
|
41
|
+
[aggregate.byProcess, record.process ?? UNATTRIBUTED_STAGE],
|
|
42
|
+
[aggregate.byEngine, record.engine ?? UNATTRIBUTED_STAGE],
|
|
43
|
+
]) {
|
|
44
|
+
groups[key] ??= emptyLlmUsageStageAggregate();
|
|
45
|
+
dimensions.push(groups[key]);
|
|
41
46
|
}
|
|
42
|
-
const
|
|
43
|
-
const promptTokens = toFiniteNumber(meta.promptTokens);
|
|
44
|
-
const completionTokens = toFiniteNumber(meta.completionTokens);
|
|
45
|
-
const totalTokens = toFiniteNumber(meta.totalTokens);
|
|
46
|
-
const reasoningTokens = toFiniteNumber(meta.reasoningTokens);
|
|
47
|
-
for (const target of [aggregate, stage]) {
|
|
47
|
+
for (const target of [aggregate, ...dimensions]) {
|
|
48
48
|
target.calls += 1;
|
|
49
|
-
target.totalDurationMs += durationMs;
|
|
50
|
-
target.promptTokens += promptTokens;
|
|
51
|
-
target.completionTokens += completionTokens;
|
|
52
|
-
target.totalTokens += totalTokens;
|
|
53
|
-
target.reasoningTokens += reasoningTokens;
|
|
49
|
+
target.totalDurationMs += record.durationMs;
|
|
50
|
+
target.promptTokens += record.promptTokens ?? 0;
|
|
51
|
+
target.completionTokens += record.completionTokens ?? 0;
|
|
52
|
+
target.totalTokens += record.totalTokens ?? 0;
|
|
53
|
+
target.reasoningTokens += record.reasoningTokens ?? 0;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
return aggregate;
|
|
@@ -28,6 +28,8 @@ export function renderRunsDetailMd(runs) {
|
|
|
28
28
|
const headers = [
|
|
29
29
|
"ts",
|
|
30
30
|
"ok",
|
|
31
|
+
"strategy",
|
|
32
|
+
"legacy_profile",
|
|
31
33
|
"actions",
|
|
32
34
|
"refl_ok/fail/cd/skip",
|
|
33
35
|
"distill_q/llm-fail/qrej/cfg/skip",
|
|
@@ -54,6 +56,8 @@ export function renderRunsDetailMd(runs) {
|
|
|
54
56
|
return [
|
|
55
57
|
r.startedAt,
|
|
56
58
|
String(r.ok),
|
|
59
|
+
r.strategy ?? "",
|
|
60
|
+
r.legacyProfile ?? "",
|
|
57
61
|
String(totalActions),
|
|
58
62
|
`${r.actions.reflect.ok}/${r.actions.reflect.failed}/${r.actions.reflect.cooldown}/${r.actions.reflect.skipped}`,
|
|
59
63
|
`${r.actions.distill.queued}/${r.actions.distill.llmFailed}/${r.actions.distill.qualityRejected}/${r.actions.distill.configDisabled}/${r.actions.distill.skipped}`,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* minting rollup, and the WS-5 per-run degradation metrics.
|
|
8
8
|
*/
|
|
9
9
|
import { appendEvent, readEvents } from "../../core/events.js";
|
|
10
|
+
import { decodeImproveResult } from "../../core/improve-result.js";
|
|
10
11
|
import { queryImproveRuns } from "../../storage/repositories/improve-runs-repository.js";
|
|
11
12
|
import { listProposalGateDecisions, listStateProposals } from "../../storage/repositories/proposals-repository.js";
|
|
12
13
|
import { gateDecisionsToSamples, summarizeCalibration } from "../improve/calibration.js";
|
|
@@ -221,7 +222,7 @@ export function computeDegradationMetrics(db, since, until) {
|
|
|
221
222
|
let totalProcessed = 0;
|
|
222
223
|
for (const row of runs) {
|
|
223
224
|
try {
|
|
224
|
-
const result =
|
|
225
|
+
const result = decodeImproveResult(row.result_json).envelope;
|
|
225
226
|
const cons = result.consolidation;
|
|
226
227
|
if (cons) {
|
|
227
228
|
totalContradicted += toFiniteNumber(cons.contradicted);
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import fs from "node:fs";
|
|
20
20
|
import path from "node:path";
|
|
21
|
-
import { CURRENT_CONFIG_VERSION
|
|
21
|
+
import { CURRENT_CONFIG_VERSION } from "../../core/config/config-schema.js";
|
|
22
|
+
import { compareConfigVersion } from "../../core/config/config-version.js";
|
|
22
23
|
const GROUP_OTHER_BITS = 0o077;
|
|
23
24
|
const OFFENDER_EVIDENCE_CAP = 50;
|
|
24
25
|
function modeOctal(mode) {
|
|
@@ -182,10 +183,10 @@ export function collectEgressAdvisory(config) {
|
|
|
182
183
|
continue;
|
|
183
184
|
endpoints.push(`source ${source.name ?? "(unnamed)"} (${source.type ?? "?"}): ${source.url}`);
|
|
184
185
|
}
|
|
185
|
-
for (const [name,
|
|
186
|
-
if (!
|
|
186
|
+
for (const [name, engine] of Object.entries(config.engines ?? {})) {
|
|
187
|
+
if (engine?.kind !== "llm" || !engine.endpoint)
|
|
187
188
|
continue;
|
|
188
|
-
endpoints.push(`llm ${name}: ${
|
|
189
|
+
endpoints.push(`llm ${name}: ${engine.endpoint}`);
|
|
189
190
|
}
|
|
190
191
|
if (config.embedding?.endpoint)
|
|
191
192
|
endpoints.push(`embedding: ${config.embedding.endpoint}`);
|
package/dist/commands/health.js
CHANGED
|
@@ -33,9 +33,9 @@ const PROMPT_OVERHEAD_TOKENS = 2_000;
|
|
|
33
33
|
* chunk content.
|
|
34
34
|
* - When the HTTP path is used (an LLM profile is selected), only the akm
|
|
35
35
|
* system prompt and user prompt are sent, so the budget can be set to the
|
|
36
|
-
* model's actual context length via
|
|
36
|
+
* model's actual context length via the selected LLM engine's contextLength.
|
|
37
37
|
*
|
|
38
|
-
* Set
|
|
38
|
+
* Set the selected LLM engine's contextLength in your config file to the
|
|
39
39
|
* model's actual context window to allow larger chunks on the HTTP path.
|
|
40
40
|
*/
|
|
41
41
|
export const DEFAULT_CONTEXT_LENGTH_TOKENS = 4_096;
|