akm-cli 0.9.17-alpha.2 → 0.9.17-alpha.4
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 +756 -0
- package/dist/akm +94 -196
- package/dist/cli/shared.js +6 -2
- package/dist/cli.js +22 -9
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +2 -2
- package/dist/commands/health/checks.js +30 -75
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +0 -38
- package/dist/commands/health/improve-metrics.js +123 -562
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +11 -106
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -73
- package/dist/commands/health.js +122 -143
- package/dist/commands/improve/consolidate/chunking.js +25 -100
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +538 -1075
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1075
- package/dist/commands/improve/eligibility.js +126 -400
- package/dist/commands/improve/execution.js +3 -5
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +29 -166
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +12 -7
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +443 -1063
- package/dist/commands/improve/ledger.js +114 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +459 -1172
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +14 -118
- package/dist/commands/improve/memory/memory-improve.js +4 -3
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -10
- package/dist/commands/improve/preparation.js +851 -2339
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +621 -1367
- package/dist/commands/improve/salience.js +46 -232
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +323 -0
- package/dist/commands/proposal/drain.js +251 -644
- package/dist/commands/proposal/proposal-cli.js +3 -18
- package/dist/commands/proposal/proposal-types.js +20 -41
- package/dist/commands/proposal/proposal.js +1 -2
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +502 -1487
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +13 -89
- package/dist/commands/read/curate.js +63 -413
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +2 -13
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +7 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +2 -11
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/stash-cli.js +1 -1
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +9 -8
- package/dist/commands/tasks/tasks.js +326 -930
- package/dist/commands/tasks/validate.js +42 -21
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +0 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +11 -12
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +291 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +1 -33
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +163 -68
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +21 -95
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-lock.js +76 -173
- package/dist/core/logs-db.js +2 -2
- package/dist/core/paths.js +0 -27
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +108 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +293 -1012
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/graph-db.js +106 -46
- package/dist/indexer/ensure-index.js +44 -85
- package/dist/indexer/graph/graph-extraction.js +340 -562
- package/dist/indexer/graph/graph-related.js +130 -0
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +139 -151
- package/dist/indexer/indexer.js +524 -846
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +81 -90
- package/dist/indexer/passes/metadata.js +132 -200
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +1 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +181 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +2 -7
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +10 -15
- package/dist/llm/graph-extract.js +3 -12
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/metadata-enhance.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +2 -34
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +60 -23
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +1 -2
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +43937 -93313
- package/dist/scripts/akm-migrate.js +43697 -93071
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +0 -17
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +168 -0
- package/dist/storage/repositories/index-connection.js +34 -70
- package/dist/storage/repositories/index-entries-repository.js +69 -111
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +83 -269
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +192 -220
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +35 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +34 -27
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +129 -277
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +125 -745
- package/dist/tasks/backends/schtasks.js +101 -620
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/scheduler-binding.js +18 -238
- package/dist/tasks/scheduler-invocation.js +52 -52
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +363 -679
- package/dist/tasks/source/parse-task-source.js +160 -10
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +2 -2
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +41 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
- package/docs/reference/cli.md +182 -125
- package/docs/reference/configuration.md +49 -56
- package/docs/reference/data-and-telemetry.md +19 -20
- package/docs/reference/tasks.md +86 -38
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +87 -406
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -146
- package/dist/commands/improve/distill/promote-memory.js +0 -329
- package/dist/commands/improve/distill/quality-gate.js +0 -500
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -21
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/config/retired-experimental-keys-shim.js +0 -62
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -78
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -63,6 +63,46 @@ import { isExactSemver, isSemverRange, maxSatisfying, satisfiesRange } from "../
|
|
|
63
63
|
function claudePluginsDir() {
|
|
64
64
|
return process.env.AKM_CLAUDE_PLUGINS_DIR ?? path.join(os.homedir(), ".claude", "plugins");
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Root of OpenCode's package cache, same override pattern as
|
|
68
|
+
* {@link claudePluginsDir} (`AKM_OPENCODE_CACHE_DIR` for tests).
|
|
69
|
+
* The OpenCode plugin (`akm-opencode`) bundles its own `akm-cli` under
|
|
70
|
+
* `packages/akm-opencode/node_modules/akm-cli` and runs it in-process,
|
|
71
|
+
* sharing the host's databases with every other akm install — its version
|
|
72
|
+
* lag matters the same way a stale Claude plugin's does.
|
|
73
|
+
*/
|
|
74
|
+
function opencodeCacheDir() {
|
|
75
|
+
return process.env.AKM_OPENCODE_CACHE_DIR ?? path.join(os.homedir(), ".cache", "opencode");
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Read the OpenCode plugin's bundled `akm-cli` version from its
|
|
79
|
+
* `package.json` — never executed, just parsed, mirroring
|
|
80
|
+
* {@link detectInstalledPlugins}'s manifest read. `undefined` when the
|
|
81
|
+
* OpenCode plugin, or its bundled akm-cli, is not installed.
|
|
82
|
+
*/
|
|
83
|
+
function detectOpencodeBundledAkmVersion(cacheRoot) {
|
|
84
|
+
const pkgPath = path.join(cacheRoot, "packages", "akm-opencode", "node_modules", "akm-cli", "package.json");
|
|
85
|
+
try {
|
|
86
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
87
|
+
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function buildOpencodeBundledAdvisory(bundledVersion, cliVersion) {
|
|
94
|
+
const stale = bundledVersion !== cliVersion;
|
|
95
|
+
return {
|
|
96
|
+
name: "opencode-plugin-version",
|
|
97
|
+
kind: "deterministic",
|
|
98
|
+
status: stale ? "warn" : "pass",
|
|
99
|
+
confidence: "high",
|
|
100
|
+
message: stale
|
|
101
|
+
? `OpenCode's bundled akm-cli is v${bundledVersion}, but the running CLI is v${cliVersion} — it shares the same databases in-process; update the OpenCode plugin.`
|
|
102
|
+
: `OpenCode's bundled akm-cli matches the running v${cliVersion}.`,
|
|
103
|
+
evidence: { bundledVersion, cliVersion },
|
|
104
|
+
};
|
|
105
|
+
}
|
|
66
106
|
/**
|
|
67
107
|
* Scan `<pluginsRoot>/cache/<marketplace>/akm/<version>/` for every
|
|
68
108
|
* `akm` plugin cache entry, picking the highest cached version per
|
|
@@ -165,14 +205,24 @@ const realListRemoteTags = (marketplaceDir) => {
|
|
|
165
205
|
return [...new Set(tags)];
|
|
166
206
|
};
|
|
167
207
|
/**
|
|
168
|
-
* Build one `plugin-version` advisory per detected `akm` harness plugin
|
|
169
|
-
*
|
|
208
|
+
* Build one `plugin-version` advisory per detected `akm` harness plugin,
|
|
209
|
+
* plus one `opencode-plugin-version` advisory when the
|
|
210
|
+
* OpenCode plugin's bundled `akm-cli` is found — it shares the host's
|
|
211
|
+
* databases in-process, so its lag matters the same way a stale Claude
|
|
212
|
+
* plugin's does. Returns `[]` when neither is installed — the benign,
|
|
213
|
+
* common case.
|
|
170
214
|
*/
|
|
171
215
|
export function collectPluginStalenessAdvisories(options) {
|
|
172
216
|
const pluginsRoot = options.pluginsRoot ?? claudePluginsDir();
|
|
173
217
|
const listRemoteTags = options.listRemoteTags ?? realListRemoteTags;
|
|
174
218
|
const plugins = detectInstalledPlugins(pluginsRoot);
|
|
175
|
-
|
|
219
|
+
const results = plugins.map((plugin) => buildAdvisory(plugin, options.cliVersion, pluginsRoot, listRemoteTags));
|
|
220
|
+
const opencodeCacheRoot = options.opencodeCacheRoot ?? opencodeCacheDir();
|
|
221
|
+
const bundledVersion = detectOpencodeBundledAkmVersion(opencodeCacheRoot);
|
|
222
|
+
if (bundledVersion !== undefined) {
|
|
223
|
+
results.push(buildOpencodeBundledAdvisory(bundledVersion, options.cliVersion));
|
|
224
|
+
}
|
|
225
|
+
return results;
|
|
176
226
|
}
|
|
177
227
|
function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags) {
|
|
178
228
|
const pluginRef = `${plugin.pluginName}@${plugin.marketplace}`;
|
|
@@ -2,7 +2,7 @@
|
|
|
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
|
/**
|
|
5
|
-
* `akm health` document renderers
|
|
5
|
+
* `akm health` document renderers.
|
|
6
6
|
*
|
|
7
7
|
* Both handlers are **pure functions of the shaped result**. Everything the
|
|
8
8
|
* rich report needs — per-run rows, window-compare deltas, the pending
|
|
@@ -13,12 +13,19 @@
|
|
|
13
13
|
* renderer to call order and made the command branch on the output format to
|
|
14
14
|
* know when to bind it. Putting the data in the envelope removed both.
|
|
15
15
|
*
|
|
16
|
+
* The Markdown renderer registers into the shared per-command registry (D7,
|
|
17
|
+
* `../../output/render-registry.ts`) alongside every other command's `--format
|
|
18
|
+
* md` renderer. The HTML renderer does not: `health` was, and remains, the
|
|
19
|
+
* only command with a bespoke HTML report, so `cli/shared.ts` calls
|
|
20
|
+
* {@link renderHealthHtml} directly instead of going through a registry with
|
|
21
|
+
* exactly one possible registrant.
|
|
22
|
+
*
|
|
16
23
|
* Returning `null` falls through to the generic renderer, so a result without
|
|
17
24
|
* the report dataset still renders — generically — instead of erroring or
|
|
18
25
|
* emitting an empty table.
|
|
19
26
|
*/
|
|
20
27
|
import { renderHtml, resolveTemplatePath } from "../../output/html-render.js";
|
|
21
|
-
import {
|
|
28
|
+
import { registerMdRenderer } from "../../output/render-registry.js";
|
|
22
29
|
import { buildHealthHtmlReplacements } from "./html-report.js";
|
|
23
30
|
import { renderRunsDetailMd, renderWindowCompareMd } from "./md-report.js";
|
|
24
31
|
function isHealthResult(value) {
|
|
@@ -34,7 +41,8 @@ registerMdRenderer("health", (result) => {
|
|
|
34
41
|
return renderRunsDetailMd(result.runs);
|
|
35
42
|
return null;
|
|
36
43
|
});
|
|
37
|
-
|
|
44
|
+
/** `--format html` renderer for `akm health`, called directly from `cli/shared.ts`. */
|
|
45
|
+
export function renderHealthHtml(result) {
|
|
38
46
|
if (!isHealthResult(result) || !result.report)
|
|
39
47
|
return null;
|
|
40
48
|
return renderHtml(resolveTemplatePath("health"), buildHealthHtmlReplacements(result, {
|
|
@@ -44,4 +52,4 @@ registerHtmlRenderer("health", (result) => {
|
|
|
44
52
|
proposals: result.report.pendingProposals,
|
|
45
53
|
deltas: result.deltas,
|
|
46
54
|
}));
|
|
47
|
-
}
|
|
55
|
+
}
|
|
@@ -79,31 +79,18 @@ function reshapeRun(r) {
|
|
|
79
79
|
completedAt: r.completedAt,
|
|
80
80
|
wallTimeMs: wall,
|
|
81
81
|
ok: r.ok,
|
|
82
|
-
mode: r.scope.mode,
|
|
83
82
|
consDurationMs: consMs,
|
|
84
83
|
miDurationMs: miMs,
|
|
85
84
|
geDurationMs: geMs,
|
|
86
85
|
otherMs: Math.max(0, wall - consMs - miMs - geMs),
|
|
87
|
-
consRan: cons.ran,
|
|
88
86
|
promoted: cons.promoted,
|
|
89
87
|
merged: cons.merged,
|
|
90
88
|
deleted: cons.deleted,
|
|
91
89
|
contradicted: cons.contradicted,
|
|
92
90
|
judgedNoAction: cons.judgedNoAction,
|
|
93
|
-
processed: cons.processed,
|
|
94
|
-
failedChunks: cons.failedChunks,
|
|
95
|
-
totalChunks: cons.totalChunks,
|
|
96
91
|
miWritten: mi.written,
|
|
97
|
-
miConsidered: mi.considered,
|
|
98
|
-
miYieldRate: mi.yieldRate,
|
|
99
|
-
miCacheHits: mi.cacheHits,
|
|
100
92
|
geEntities: ge.entities,
|
|
101
93
|
geRelations: ge.relations,
|
|
102
|
-
geCacheHitRate: ge.cacheHitRate,
|
|
103
|
-
geFailures: ge.failures,
|
|
104
|
-
distillSkipped: r.actions.distill.skipped,
|
|
105
|
-
distillQueued: r.actions.distill.queued,
|
|
106
|
-
distillLlmFailed: r.actions.distill.llmFailed,
|
|
107
94
|
distillByReason: r.actions.distill.skippedByReason,
|
|
108
95
|
reflectOk: r.actions.reflect.ok,
|
|
109
96
|
reflectFailed: r.actions.reflect.failed,
|
|
@@ -111,8 +98,6 @@ function reshapeRun(r) {
|
|
|
111
98
|
eligible: r.memorySummary.eligible,
|
|
112
99
|
lintFlagged: r.lintFlagged,
|
|
113
100
|
lintFixed: r.lintFixed,
|
|
114
|
-
reflectsWithErrorContext: r.reflectsWithErrorContext,
|
|
115
|
-
orphansPurged: r.orphansPurged,
|
|
116
101
|
};
|
|
117
102
|
}
|
|
118
103
|
function compareRuns(a, b) {
|
|
@@ -135,11 +120,7 @@ function classify(deltas, metricKeys, lowerIsBetter = false) {
|
|
|
135
120
|
}
|
|
136
121
|
function buildTrend(deltas) {
|
|
137
122
|
const decisionQuality = classify(deltas, ["improve.memoryInference.yieldRate", "improve.consolidation.promoted"]);
|
|
138
|
-
const outputVolume = classify(deltas, [
|
|
139
|
-
"improve.consolidation.promoted",
|
|
140
|
-
"improve.memoryInference.written",
|
|
141
|
-
"improve.sessionExtraction.proposalsCreated",
|
|
142
|
-
]);
|
|
123
|
+
const outputVolume = classify(deltas, ["improve.consolidation.promoted", "improve.memoryInference.written"]);
|
|
143
124
|
const failures = classify(deltas, ["improve.graphExtraction.failures"], true);
|
|
144
125
|
const latency = classify(deltas, ["improve.wallTime.medianMs", "improve.wallTime.p95Ms"], true);
|
|
145
126
|
const score = [decisionQuality, outputVolume, failures, latency].reduce((acc, d) => acc + (d === "up" ? 1 : d === "down" ? -1 : 0), 0);
|
|
@@ -205,19 +186,7 @@ function buildAggregatesPhase(result, runsPhase) {
|
|
|
205
186
|
const mi = improve.memoryInference;
|
|
206
187
|
const ge = improve.graphExtraction;
|
|
207
188
|
const wallTime = improve.wallTime;
|
|
208
|
-
// WS-5: perf telemetry, coverage, and degradation metrics.
|
|
209
|
-
const perf = improve.perfTelemetry ?? {
|
|
210
|
-
dedupPoolSize: 0,
|
|
211
|
-
llmPoolSize: 0,
|
|
212
|
-
embedMs: 0,
|
|
213
|
-
embedCacheHits: 0,
|
|
214
|
-
embedCacheMisses: 0,
|
|
215
|
-
overBudgetRuns: 0,
|
|
216
|
-
runsWithTelemetry: 0,
|
|
217
|
-
};
|
|
218
189
|
const coverage = improve.coverage;
|
|
219
|
-
const degradation = improve.degradation;
|
|
220
|
-
const minting = improve.enrichmentMinting;
|
|
221
190
|
// #576: real per-stage LLM token/time accounting (replaces the GPU-time
|
|
222
191
|
// proxy). Optional-guarded so reports built from older health JSON without
|
|
223
192
|
// the aggregate still render.
|
|
@@ -242,10 +211,7 @@ function buildAggregatesPhase(result, runsPhase) {
|
|
|
242
211
|
memoryInference: mi,
|
|
243
212
|
graphExtraction: ge,
|
|
244
213
|
wallTime,
|
|
245
|
-
perf,
|
|
246
214
|
coverage,
|
|
247
|
-
degradation,
|
|
248
|
-
minting,
|
|
249
215
|
llm,
|
|
250
216
|
memorySummary: improve.memorySummary,
|
|
251
217
|
includedResultRows: improve.resultRows?.included ?? totalRuns,
|
|
@@ -343,7 +309,7 @@ function groupProposalsBySource(proposals) {
|
|
|
343
309
|
}
|
|
344
310
|
/** Summary table rows: the base metric set + the WS-5 coverage/minting/perf/degradation extensions, when present. */
|
|
345
311
|
function buildSummaryRows(aggregates, trend) {
|
|
346
|
-
const { consolidation: cons, graphExtraction: ge, wallTime, llm, coverage
|
|
312
|
+
const { consolidation: cons, graphExtraction: ge, wallTime, llm, coverage } = aggregates;
|
|
347
313
|
const summaryRows = [
|
|
348
314
|
["Task fail rate", aggregates.taskFailRate, "flat"],
|
|
349
315
|
["Agent fail rate", aggregates.agentFailRate, "flat"],
|
|
@@ -388,80 +354,19 @@ function buildSummaryRows(aggregates, trend) {
|
|
|
388
354
|
"Tokens spent on model reasoning/thinking, billed separately from prompt and completion.",
|
|
389
355
|
],
|
|
390
356
|
["LLM wall time", fmtMs(llm.totalDurationMs), trend.latency],
|
|
391
|
-
|
|
392
|
-
// WS-5: denominator-fixed coverage rows (only when we have real data).
|
|
393
|
-
if (coverage && !Number.isNaN(coverage.rate)) {
|
|
394
|
-
summaryRows.push([
|
|
395
|
-
"Coverage rate",
|
|
396
|
-
pct(coverage.rate, 1),
|
|
397
|
-
"flat",
|
|
398
|
-
"Distinct accepted refs / total stash assets (denominator-fixed). Shows what fraction of the corpus has been touched.",
|
|
399
|
-
], [
|
|
400
|
-
"Eligible fraction",
|
|
401
|
-
pct(coverage.eligibleFraction, 1),
|
|
402
|
-
"flat",
|
|
403
|
-
"Eligible assets / total stash assets. Fraction the improve pipeline actively considers.",
|
|
404
|
-
], [
|
|
357
|
+
[
|
|
405
358
|
"Coverage accepted",
|
|
406
359
|
num(coverage.acceptedProposals),
|
|
407
360
|
"flat",
|
|
408
|
-
"
|
|
409
|
-
],
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
"Accepted proposals / distinct refs touched. >1.5 = the loop is repeatedly rewriting the same assets (churn, not coverage).",
|
|
414
|
-
]);
|
|
415
|
-
}
|
|
416
|
-
// Enrichment-vs-minting policy rollup (reporting-only).
|
|
417
|
-
if (minting && Number.isFinite(minting.share)) {
|
|
418
|
-
summaryRows.push([
|
|
419
|
-
"Enrichment-lane minted share",
|
|
420
|
-
pct(minting.share, 1),
|
|
421
|
-
minting.share > 0.05 ? "down" : "flat",
|
|
422
|
-
`New assets minted by enrichment lanes / their accepted total (${minting.minted} minted vs ${minting.updated} updated). Enrichment lanes are ratified to edit existing assets only; WARN >5%, FAIL >15%.`,
|
|
423
|
-
]);
|
|
424
|
-
}
|
|
425
|
-
// WS-5: perf telemetry rows (only when at least one run reported telemetry).
|
|
426
|
-
if (perf.runsWithTelemetry > 0) {
|
|
427
|
-
const embedCacheTotal = perf.embedCacheHits + perf.embedCacheMisses;
|
|
428
|
-
const embedCacheHitRate = embedCacheTotal > 0 ? pct(perf.embedCacheHits / embedCacheTotal, 1) : "—";
|
|
429
|
-
summaryRows.push([
|
|
430
|
-
"Embed cache hit rate",
|
|
431
|
-
embedCacheHitRate,
|
|
432
|
-
"flat",
|
|
433
|
-
"Fraction of embedding lookups served from cache (>95% is healthy). Aggregated across WS-5 runs.",
|
|
434
|
-
], [
|
|
435
|
-
"Embed wall time",
|
|
436
|
-
fmtMs(perf.embedMs),
|
|
437
|
-
"flat",
|
|
438
|
-
"Cumulative embedding wall-clock time across consolidation runs in the window.",
|
|
439
|
-
], [
|
|
440
|
-
"Dedup pool size",
|
|
441
|
-
num(perf.dedupPoolSize),
|
|
442
|
-
"flat",
|
|
443
|
-
"Memory pool size after incremental narrowing, before the limit cap. WS-5 perf telemetry.",
|
|
444
|
-
], [
|
|
445
|
-
"Over-budget consolidation runs",
|
|
446
|
-
String(perf.overBudgetRuns),
|
|
447
|
-
perf.overBudgetRuns > 0 ? "down" : "flat",
|
|
448
|
-
"Runs where consolidation alone exceeded the total run budget (estimatedBudgetFractionUsed > 1.0).",
|
|
449
|
-
]);
|
|
450
|
-
}
|
|
451
|
-
// WS-5: degradation metrics rows.
|
|
452
|
-
if (degradation) {
|
|
453
|
-
summaryRows.push([
|
|
454
|
-
"Corpus diversity (Gini)",
|
|
455
|
-
num(degradation.corpusCentroidDistance),
|
|
456
|
-
degradation.entrenchmentFlagged || degradation.salienceUniformityFlagged ? "down" : "flat",
|
|
457
|
-
`Gini coefficient of positive retrieval_salience values across ${degradation.retrievalSalienceSampleSize} resolvable assets. Two-tailed: >0.35 = entrenchment risk; <0.08 = collapsed toward uniform.`,
|
|
458
|
-
], [
|
|
459
|
-
"Merge fidelity contradiction rate",
|
|
460
|
-
pct(degradation.mergeFidelityContradictionRate, 1),
|
|
361
|
+
"Accepted proposals in the window (raw volume — includes repeated rewrites of the same asset).",
|
|
362
|
+
],
|
|
363
|
+
[
|
|
364
|
+
"Distinct assets touched",
|
|
365
|
+
num(coverage.distinctRefs),
|
|
461
366
|
"flat",
|
|
462
|
-
"
|
|
463
|
-
]
|
|
464
|
-
|
|
367
|
+
"Distinct assets touched by accepted proposals in the window.",
|
|
368
|
+
],
|
|
369
|
+
];
|
|
465
370
|
return summaryRows;
|
|
466
371
|
}
|
|
467
372
|
/**
|
|
@@ -2,28 +2,13 @@
|
|
|
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
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* New-asset generation belongs to the signal-gated minting lanes
|
|
8
|
-
* (extract/distill/memory-inference).
|
|
9
|
-
*/
|
|
10
|
-
export const ENRICHMENT_LANES = ["proactive", "high-salience", "signal-delta"];
|
|
11
|
-
/** Minted share of enrichment-lane accepts that triggers a WARN advisory. */
|
|
12
|
-
export const ENRICHMENT_MINTED_WARN_SHARE = 0.05;
|
|
13
|
-
/** Minted share of enrichment-lane accepts that triggers a FAIL advisory. */
|
|
14
|
-
export const ENRICHMENT_MINTED_FAIL_SHARE = 0.15;
|
|
15
|
-
/**
|
|
16
|
-
* Cron task failure rate at or above which the `task-fail-rate` health advisory
|
|
17
|
-
* warns. 0.05 (5%) is the SAME threshold the HTML report already applies as its
|
|
18
|
-
* fail-rate pass/warn cutoff (`failOk = taskFailRate < 0.05` in
|
|
19
|
-
* src/commands/health/html-report.ts) — this constant makes it the single
|
|
20
|
-
* source so the advisory and the rendered badge cannot drift.
|
|
5
|
+
* Cron task failure rate at or above which the `task-fail-rate` advisory
|
|
6
|
+
* warns; also the HTML report's fail-rate badge cutoff, so the two cannot drift.
|
|
21
7
|
*/
|
|
22
8
|
export const TASK_FAIL_RATE_WARN = 0.05;
|
|
23
9
|
/**
|
|
24
10
|
* Minimum task_history rows a single task_id needs in the window before its
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* run) reading as a 100% fail rate off a single noisy sample.
|
|
11
|
+
* own fail rate feeds `task-fail-rate` — a task run once and failed once is
|
|
12
|
+
* not a 100% signal.
|
|
28
13
|
*/
|
|
29
14
|
export const MIN_ROWS_FOR_WORST_TASK_FAIL_RATE = 5;
|
|
@@ -3,17 +3,14 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
5
|
* Window handling for `akm health`: `--window-compare` / `--windows` parsing,
|
|
6
|
-
* per-window metric assembly,
|
|
6
|
+
* per-window metric assembly, and delta computation between two windows.
|
|
7
7
|
*/
|
|
8
|
-
import fs from "node:fs";
|
|
9
8
|
import { UsageError } from "../../core/errors.js";
|
|
10
9
|
import { readEvents } from "../../core/events.js";
|
|
11
|
-
import { buildTaskRunId, getLoggedRunIds } from "../../core/logs-db.js";
|
|
12
10
|
import { DURATION_UNITS, parseDuration } from "../../core/time.js";
|
|
13
11
|
import { queryTaskHistory } from "../../storage/repositories/task-history-repository.js";
|
|
14
|
-
import { buildImproveSkipSummary, computeWallTimeStats, countAgentFailureReasons, isAgentTaskHistoryRow, roundRate,
|
|
12
|
+
import { buildImproveSkipSummary, computeWallTimeStats, computeWindowProposalCoverage, countAgentFailureReasons, isAgentTaskHistoryRow, roundRate, summarizeImproveRuns, taskFailureDetail, } from "./improve-metrics.js";
|
|
15
13
|
import { readLlmUsageAggregate } from "./llm-usage.js";
|
|
16
|
-
import { computeDegradationMetrics, computeDenominatorFixedCoverage } from "./metrics.js";
|
|
17
14
|
import { buildPerRunSummaries } from "./task-runs.js";
|
|
18
15
|
import { ACTIVE_RUN_WARN_MS, IMPROVE_COMPLETED_EVENT, } from "./types.js";
|
|
19
16
|
/**
|
|
@@ -71,28 +68,30 @@ export function parseWindowSpec(raw) {
|
|
|
71
68
|
...(fields.until ? { until: fields.until } : {}),
|
|
72
69
|
};
|
|
73
70
|
}
|
|
74
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Metric paths diffed between the earliest and latest window (`deltas` in the
|
|
73
|
+
* JSON result; the delta column of `--format md`). Paths are relative to a
|
|
74
|
+
* {@link WindowResult}.
|
|
75
|
+
*/
|
|
75
76
|
export const INTERESTING_DELTA_PATHS = [
|
|
76
77
|
"improve.actions.reflect.failed",
|
|
77
|
-
"improve.actions.reflect.guardRejected",
|
|
78
|
-
"improve.actions.distill.llmFailed",
|
|
79
78
|
"improve.actions.distill.queued",
|
|
80
|
-
"improve.actions.distill.
|
|
79
|
+
"improve.actions.distill.llmFailed",
|
|
81
80
|
"improve.consolidation.promoted",
|
|
82
81
|
"improve.memoryInference.written",
|
|
83
82
|
"improve.memoryInference.yieldRate",
|
|
84
83
|
"improve.memoryInference.skippedNoFacts",
|
|
85
|
-
"improve.memoryInference.htmlErrorCount",
|
|
86
|
-
"improve.graphExtraction.cacheHitRate",
|
|
87
84
|
"improve.graphExtraction.failures",
|
|
88
|
-
"improve.graphExtraction.htmlErrors",
|
|
89
|
-
"improve.graphExtraction.nonArrayBatchFailures",
|
|
90
|
-
"improve.sessionExtraction.sessionsScanned",
|
|
91
|
-
"improve.sessionExtraction.proposalsCreated",
|
|
92
85
|
"improve.autoAccept.promoted",
|
|
93
86
|
"improve.autoAccept.validationFailed",
|
|
87
|
+
"improve.coverage.acceptedProposals",
|
|
88
|
+
"improve.coverage.distinctRefs",
|
|
94
89
|
"improve.wallTime.medianMs",
|
|
95
90
|
"improve.wallTime.p95Ms",
|
|
91
|
+
"metrics.llmUsage.calls",
|
|
92
|
+
"metrics.llmUsage.totalTokens",
|
|
93
|
+
"metrics.llmUsage.totalDurationMs",
|
|
94
|
+
"metrics.llmUsage.failures",
|
|
96
95
|
];
|
|
97
96
|
export function readNumericPath(obj, path) {
|
|
98
97
|
const parts = path.split(".");
|
|
@@ -123,74 +122,66 @@ export function computeDeltas(first, last) {
|
|
|
123
122
|
return out;
|
|
124
123
|
}
|
|
125
124
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
125
|
+
* Task-history-derived rates, shared by the main health path
|
|
126
|
+
* (`health.ts`'s `gatherTaskHistoryPhase`) and {@link buildWindowMetrics}
|
|
127
|
+
* below — previously computed twice with the only difference being whether
|
|
128
|
+
* the caller had already bounded `taskRows` by an `until`. Pure projection of
|
|
129
|
+
* already-queried rows; callers own the `since`/`until` query.
|
|
131
130
|
*/
|
|
132
|
-
export function
|
|
133
|
-
const withLogs = taskRows.filter((row) => row.log_path !== null);
|
|
134
|
-
const loggedRunIds = logsDb
|
|
135
|
-
? getLoggedRunIds(logsDb, withLogs.map((row) => buildTaskRunId(row.task_id, row.started_at)))
|
|
136
|
-
: new Set();
|
|
137
|
-
const backed = withLogs.filter((row) => loggedRunIds.has(buildTaskRunId(row.task_id, row.started_at)) ||
|
|
138
|
-
(row.log_path !== null && fs.existsSync(row.log_path)));
|
|
139
|
-
return { withLogs, backed };
|
|
140
|
-
}
|
|
141
|
-
export function buildWindowMetrics(db, stateDbPath, since, until, now = () => Date.now(), logsDb) {
|
|
142
|
-
const taskRows = queryTaskHistory(db, { since }).filter((row) => {
|
|
143
|
-
const startMs = new Date(row.started_at).getTime();
|
|
144
|
-
const untilMs = new Date(until).getTime();
|
|
145
|
-
return !Number.isFinite(untilMs) || startMs < untilMs;
|
|
146
|
-
});
|
|
147
|
-
const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
|
|
131
|
+
export function computeTaskWindowRates(taskRows, now) {
|
|
148
132
|
const failedTaskRows = taskRows.filter((row) => row.status === "failed");
|
|
149
133
|
const activeRows = taskRows.filter((row) => row.status === "active" && row.completed_at === null);
|
|
150
|
-
const
|
|
134
|
+
const stuckActiveRows = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS);
|
|
151
135
|
const agentRows = taskRows.filter((row) => isAgentTaskHistoryRow(row));
|
|
152
136
|
const agentFailures = agentRows.filter((row) => {
|
|
153
137
|
const detail = taskFailureDetail(row);
|
|
154
138
|
return typeof detail?.reason === "string" && detail.reason.length > 0;
|
|
155
139
|
});
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
140
|
+
return {
|
|
141
|
+
taskFailRate: taskRows.length === 0 ? 0 : failedTaskRows.length / taskRows.length,
|
|
142
|
+
agentFailureRate: agentRows.length === 0 ? 0 : agentFailures.length / agentRows.length,
|
|
143
|
+
agentFailureReasonCounts: countAgentFailureReasons(agentFailures),
|
|
144
|
+
stuckActiveRuns: stuckActiveRows.length,
|
|
145
|
+
stuckActiveRows,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Improve-pipeline window summary, shared by the main health path
|
|
150
|
+
* (`health.ts`) and {@link buildWindowMetrics} below: events-derived
|
|
151
|
+
* invoked/completed/skipped counts, the `result_json` aggregate, wall-time
|
|
152
|
+
* stats from the same per-run rows, and accepted-proposal coverage, all over
|
|
153
|
+
* one `[since, until)`.
|
|
154
|
+
*/
|
|
155
|
+
export function buildImproveWindowSummary(db, stateDbPath, since, until) {
|
|
156
|
+
const untilMs = new Date(until).getTime();
|
|
157
|
+
const eventsBeforeUntil = (type) => readEvents({ since, type }, { dbPath: stateDbPath }).events.filter((event) => new Date(event.ts ?? since).getTime() < untilMs);
|
|
158
|
+
const { metrics: improve, runCount } = summarizeImproveRuns(db, since, until);
|
|
159
|
+
improve.invoked = eventsBeforeUntil("improve_invoked").length;
|
|
160
|
+
improve.completed = eventsBeforeUntil(IMPROVE_COMPLETED_EVENT).length;
|
|
161
|
+
const skipSummary = buildImproveSkipSummary(eventsBeforeUntil("improve_skipped"));
|
|
162
|
+
improve.skipped = skipSummary.skipped;
|
|
163
|
+
improve.skipReasons = skipSummary.skipReasons;
|
|
164
|
+
// Wall times come from the same improve-runs window as the per-run
|
|
165
|
+
// reporting so counts and percentiles stay aligned with it.
|
|
173
166
|
const perRunSummaries = buildPerRunSummaries(db, since, until);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
167
|
+
improve.wallTime = computeWallTimeStats(perRunSummaries.map((run) => run.wallTimeMs).filter((ms) => Number.isFinite(ms) && ms > 0));
|
|
168
|
+
improve.coverage = computeWindowProposalCoverage(db, since, until);
|
|
169
|
+
return { improve, runCount, perRunSummaries };
|
|
170
|
+
}
|
|
171
|
+
export function buildWindowMetrics(db, stateDbPath, since, until, now = () => Date.now()) {
|
|
172
|
+
const untilMs = new Date(until).getTime();
|
|
173
|
+
const taskRows = queryTaskHistory(db, { since }).filter((row) => {
|
|
174
|
+
const startMs = new Date(row.started_at).getTime();
|
|
175
|
+
return !Number.isFinite(untilMs) || startMs < untilMs;
|
|
176
|
+
});
|
|
177
|
+
const rates = computeTaskWindowRates(taskRows, now);
|
|
178
|
+
const { improve, runCount } = buildImproveWindowSummary(db, stateDbPath, since, until);
|
|
186
179
|
const metrics = {
|
|
187
|
-
taskFailRate: roundRate(taskFailRate),
|
|
188
|
-
agentFailureRate: roundRate(agentFailureRate),
|
|
189
|
-
agentFailureReasonCounts,
|
|
190
|
-
stuckActiveRuns,
|
|
191
|
-
logBackingRate: roundRate(logBackingRate),
|
|
192
|
-
probeRoundTripMs: null,
|
|
180
|
+
taskFailRate: roundRate(rates.taskFailRate),
|
|
181
|
+
agentFailureRate: roundRate(rates.agentFailureRate),
|
|
182
|
+
agentFailureReasonCounts: rates.agentFailureReasonCounts,
|
|
183
|
+
stuckActiveRuns: rates.stuckActiveRuns,
|
|
193
184
|
llmUsage: readLlmUsageAggregate(stateDbPath, since, until),
|
|
194
185
|
};
|
|
195
|
-
return { improve
|
|
186
|
+
return { improve, metrics, runs: runCount };
|
|
196
187
|
}
|