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
|
@@ -1,329 +0,0 @@
|
|
|
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
|
-
* Memory→knowledge promotion branch for `akm distill`.
|
|
6
|
-
*
|
|
7
|
-
* This is an entire second command that used to be inlined inside `akmDistill`:
|
|
8
|
-
* when a `memory:*` ref is reinforced enough (per the deterministic stability
|
|
9
|
-
* heuristic in `distill-promotion-policy`), distill graduates it into a
|
|
10
|
-
* `knowledge:*` proposal instead of a lesson. The branch owns its own LLM
|
|
11
|
-
* contradiction-merge (mem0 ADD/UPDATE/NOOP), quality gate, proposal creation,
|
|
12
|
-
* and `distill_invoked` event emit.
|
|
13
|
-
*
|
|
14
|
-
* {@link promoteMemoryToKnowledge} returns the finished {@link AkmDistillResult}
|
|
15
|
-
* when the branch fired, or `null` when the ref is not a promotion candidate —
|
|
16
|
-
* in which case the caller falls through to the ordinary lesson/knowledge LLM
|
|
17
|
-
* path. Logic is byte-identical to the pre-extraction inline code.
|
|
18
|
-
*/
|
|
19
|
-
import fs from "node:fs";
|
|
20
|
-
import { parseFrontmatter } from "../../../core/asset/frontmatter.js";
|
|
21
|
-
import { ConfigError } from "../../../core/errors.js";
|
|
22
|
-
import { appendEvent } from "../../../core/events.js";
|
|
23
|
-
import { parseEmbeddedJsonResponse } from "../../../core/parse.js";
|
|
24
|
-
import { callStructured } from "../../../llm/structured-call.js";
|
|
25
|
-
import { isProposalSkipped } from "../../proposal/repository.js";
|
|
26
|
-
import { assessMemoryKnowledgePromotionCandidate } from "../distill-promotion-policy.js";
|
|
27
|
-
import { emitProposal } from "../proposal-envelope.js";
|
|
28
|
-
import { durableImproveRef } from "../source-identity.js";
|
|
29
|
-
import { persistOutputEncodingSalience, runLessonQualityJudge, writeQualityRejection } from "./quality-gate.js";
|
|
30
|
-
/** Read-only classification of the deterministic promotion path and destination conflict. */
|
|
31
|
-
export async function planMemoryKnowledgePromotion(ctx) {
|
|
32
|
-
const durableInputRef = ctx.durableInputRef ?? ctx.inputRef;
|
|
33
|
-
const promotion = ctx.targetKind === "lesson"
|
|
34
|
-
? null
|
|
35
|
-
: assessMemoryKnowledgePromotionCandidate({
|
|
36
|
-
inputRef: durableInputRef,
|
|
37
|
-
assetContent: ctx.assetContent,
|
|
38
|
-
feedbackEvents: ctx.filteredEvents.map((event) => ({
|
|
39
|
-
...(event.metadata !== undefined ? { metadata: event.metadata } : {}),
|
|
40
|
-
})),
|
|
41
|
-
});
|
|
42
|
-
if (!(promotion?.promote && promotion.content && (ctx.targetKind === "knowledge" || ctx.targetKind === "auto"))) {
|
|
43
|
-
return null;
|
|
44
|
-
}
|
|
45
|
-
const existingKnowledgePath = await ctx.lookup(durableImproveRef(promotion.knowledgeRef));
|
|
46
|
-
let existingKnowledgeContent = null;
|
|
47
|
-
if (existingKnowledgePath && fs.existsSync(existingKnowledgePath)) {
|
|
48
|
-
try {
|
|
49
|
-
existingKnowledgeContent = fs.readFileSync(existingKnowledgePath, "utf8");
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
existingKnowledgeContent = null;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
return { promotion: promotion, existingKnowledgeContent };
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* PRECHECK (tier3-0917): read-only classification of whether distill would
|
|
59
|
-
* promote this memory to knowledge — used by the improve loop's distill
|
|
60
|
-
* pre-generation proposal guard (`loop-stages.ts`) to pre-check the SAME ref
|
|
61
|
-
* {@link planMemoryKnowledgePromotion} will target at dispatch time
|
|
62
|
-
* (knowledgeRef when this resolves `true`, the derived lesson ref
|
|
63
|
-
* otherwise), rather than guessing which of the two a guard hit applies to.
|
|
64
|
-
* Delegates to {@link planMemoryKnowledgePromotion} itself so the
|
|
65
|
-
* classification can never drift from the real dispatch decision — no LLM
|
|
66
|
-
* call, no side effect. Every {@link PromoteMemoryContext} field this
|
|
67
|
-
* classification does not read (chat, fetchSimilarLessonsFn,
|
|
68
|
-
* existingRefVocabulary, …) is a safe placeholder here.
|
|
69
|
-
*/
|
|
70
|
-
export async function wouldPromoteMemoryToKnowledge(args) {
|
|
71
|
-
const plan = await planMemoryKnowledgePromotion({
|
|
72
|
-
targetKind: "auto",
|
|
73
|
-
inputRef: args.inputRef,
|
|
74
|
-
durableInputRef: args.durableInputRef,
|
|
75
|
-
assetContent: args.assetContent,
|
|
76
|
-
filteredEvents: args.feedbackEvents,
|
|
77
|
-
config: args.config,
|
|
78
|
-
stash: args.stash,
|
|
79
|
-
lookup: args.lookup,
|
|
80
|
-
fetchSimilarLessonsFn: () => Promise.resolve([]),
|
|
81
|
-
existingRefVocabulary: new Set(),
|
|
82
|
-
outcomeWeightEnabled: false,
|
|
83
|
-
eligMeta: {},
|
|
84
|
-
exclusionSetSize: 0,
|
|
85
|
-
filteredFeedbackCount: 0,
|
|
86
|
-
feedbackFullyFiltered: false,
|
|
87
|
-
});
|
|
88
|
-
return plan !== null;
|
|
89
|
-
}
|
|
90
|
-
/** Whether a classified promotion will actually call merge generation and/or the judge. */
|
|
91
|
-
export function memoryKnowledgePromotionRequiresDispatch(ctx, plan) {
|
|
92
|
-
const hasRunner = Boolean(ctx.llmRunner);
|
|
93
|
-
return ((Boolean(plan.existingKnowledgeContent) && hasRunner) ||
|
|
94
|
-
(ctx.strategy?.processes?.distill?.qualityGate?.enabled ?? true));
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Resolve the knowledge content to propose when a memory promotes to knowledge,
|
|
98
|
-
* reconciling it with any existing knowledge file at the destination (D-1 / #369).
|
|
99
|
-
*
|
|
100
|
-
* When the destination already exists and an LLM is configured, follows the
|
|
101
|
-
* mem0 ADD/UPDATE/NOOP pattern (arXiv:2504.19413 §3.2): ADD/UPDATE swap in the
|
|
102
|
-
* merged content, NOOP short-circuits with a terminal "skipped" result. Without
|
|
103
|
-
* an LLM the existing content is appended as reviewer-reference context so the
|
|
104
|
-
* merge can be done by hand. Logic is byte-identical to the prior inline block.
|
|
105
|
-
*/
|
|
106
|
-
async function resolveKnowledgePromotionContent(ctx, plan) {
|
|
107
|
-
const durableInputRef = ctx.durableInputRef ?? ctx.inputRef;
|
|
108
|
-
const baseContent = plan.promotion.content;
|
|
109
|
-
const knowledgeRef = plan.promotion.knowledgeRef;
|
|
110
|
-
let resolvedPromotionContent = baseContent;
|
|
111
|
-
const existingKnowledgeContent = plan.existingKnowledgeContent;
|
|
112
|
-
const runner = ctx.llmRunner;
|
|
113
|
-
if (existingKnowledgeContent && runner) {
|
|
114
|
-
// Existing content found: call LLM for contradiction-resolution merge.
|
|
115
|
-
const mergePrompt = [
|
|
116
|
-
"You are merging two versions of a knowledge document.",
|
|
117
|
-
"Existing content is already committed; new content comes from a memory distillation run.",
|
|
118
|
-
"Choose one of: ADD (combine both), UPDATE (replace existing with new), NOOP (keep existing unchanged).",
|
|
119
|
-
'Return ONLY valid JSON: {"action": "ADD"|"UPDATE"|"NOOP", "content": "<merged markdown if ADD/UPDATE, empty string if NOOP>"}',
|
|
120
|
-
"",
|
|
121
|
-
"## Existing knowledge content",
|
|
122
|
-
"```",
|
|
123
|
-
existingKnowledgeContent.slice(0, 3000),
|
|
124
|
-
"```",
|
|
125
|
-
"",
|
|
126
|
-
"## New content from distillation",
|
|
127
|
-
"```",
|
|
128
|
-
baseContent.slice(0, 3000),
|
|
129
|
-
"```",
|
|
130
|
-
].join("\n");
|
|
131
|
-
try {
|
|
132
|
-
const mergeResponse = await callStructured({
|
|
133
|
-
feature: "distill",
|
|
134
|
-
runner,
|
|
135
|
-
...(ctx.lease ? { lease: ctx.lease } : {}),
|
|
136
|
-
messages: [
|
|
137
|
-
{ role: "system", content: "Return only valid JSON. No prose." },
|
|
138
|
-
{ role: "user", content: mergePrompt },
|
|
139
|
-
],
|
|
140
|
-
request: {
|
|
141
|
-
...(ctx.signal ? { signal: ctx.signal } : {}),
|
|
142
|
-
...(ctx.chat ? { chat: ctx.chat } : {}),
|
|
143
|
-
},
|
|
144
|
-
parse: (raw) => raw ?? "",
|
|
145
|
-
onError: () => "",
|
|
146
|
-
fallback: "",
|
|
147
|
-
...(ctx.onNotices ? { onNotices: ctx.onNotices } : {}),
|
|
148
|
-
});
|
|
149
|
-
const mergeResult = parseEmbeddedJsonResponse(mergeResponse);
|
|
150
|
-
if (mergeResult?.action === "NOOP") {
|
|
151
|
-
// Existing content is authoritative — no update needed.
|
|
152
|
-
appendEvent({
|
|
153
|
-
eventType: "distill_invoked",
|
|
154
|
-
// Use item_ref when resolved, otherwise the input conceptId.
|
|
155
|
-
ref: ctx.itemRef ?? durableInputRef,
|
|
156
|
-
metadata: {
|
|
157
|
-
outcome: "skipped",
|
|
158
|
-
proposalRef: knowledgeRef,
|
|
159
|
-
message: "D-1: LLM resolved destination conflict as NOOP — existing content kept",
|
|
160
|
-
...ctx.eligMeta,
|
|
161
|
-
},
|
|
162
|
-
}, ctx.eventsCtx);
|
|
163
|
-
return {
|
|
164
|
-
earlyResult: {
|
|
165
|
-
schemaVersion: 1,
|
|
166
|
-
ok: true,
|
|
167
|
-
outcome: "skipped",
|
|
168
|
-
inputRef: ctx.inputRef,
|
|
169
|
-
proposalRef: knowledgeRef,
|
|
170
|
-
skipReason: "conflict_noop",
|
|
171
|
-
message: "Existing knowledge content unchanged (contradiction resolution: NOOP)",
|
|
172
|
-
},
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
if (mergeResult?.action && (mergeResult.action === "ADD" || mergeResult.action === "UPDATE")) {
|
|
176
|
-
if (mergeResult.content?.trim()) {
|
|
177
|
-
resolvedPromotionContent = mergeResult.content;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
catch (error) {
|
|
182
|
-
if (error instanceof ConfigError)
|
|
183
|
-
throw error;
|
|
184
|
-
// LLM merge failed — fall through with the original promotion content.
|
|
185
|
-
// The reviewer will see both versions in the proposal diff.
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
else if (existingKnowledgeContent) {
|
|
189
|
-
// No LLM configured: include existing content as context in the proposal
|
|
190
|
-
// so the reviewer can do the contradiction resolution manually.
|
|
191
|
-
resolvedPromotionContent = [
|
|
192
|
-
baseContent,
|
|
193
|
-
"",
|
|
194
|
-
"---",
|
|
195
|
-
"<!-- D-1 / #369: Existing knowledge content is shown below for reviewer reference. -->",
|
|
196
|
-
"<!-- Review: decide whether to ADD (merge), UPDATE (replace), or NOOP (keep existing). -->",
|
|
197
|
-
"",
|
|
198
|
-
"## Existing content (for reviewer reference)",
|
|
199
|
-
"",
|
|
200
|
-
existingKnowledgeContent,
|
|
201
|
-
].join("\n");
|
|
202
|
-
}
|
|
203
|
-
return { resolvedContent: resolvedPromotionContent };
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Run the memory→knowledge promotion branch. Returns the finished distill
|
|
207
|
-
* result when promotion fired (all paths terminal), or `null` when the ref is
|
|
208
|
-
* not a promotion candidate and the caller should continue to the ordinary
|
|
209
|
-
* lesson/knowledge distillation path.
|
|
210
|
-
*/
|
|
211
|
-
export async function promoteMemoryToKnowledge(ctx, planned) {
|
|
212
|
-
const { inputRef, assetContent, config, chat, stash, fetchSimilarLessonsFn, existingRefVocabulary, outcomeWeightEnabled, eligMeta, exclusionSetSize, filteredFeedbackCount, feedbackFullyFiltered, } = ctx;
|
|
213
|
-
const durableInputRef = ctx.durableInputRef ?? inputRef;
|
|
214
|
-
const promotionPlan = planned === undefined ? await planMemoryKnowledgePromotion(ctx) : planned;
|
|
215
|
-
if (!promotionPlan)
|
|
216
|
-
return null;
|
|
217
|
-
const promotion = promotionPlan.promotion;
|
|
218
|
-
// D-1 / #369: When the destination knowledge file already exists, route
|
|
219
|
-
// through the LLM for contradiction resolution instead of silently
|
|
220
|
-
// overwriting. Follows mem0 ADD/UPDATE/DELETE/NOOP pattern (arXiv:2504.19413 §3.2)
|
|
221
|
-
// and A-MEM dynamic linking (arXiv:2502.12110).
|
|
222
|
-
const merged = await resolveKnowledgePromotionContent(ctx, promotionPlan);
|
|
223
|
-
if ("earlyResult" in merged)
|
|
224
|
-
return merged.earlyResult;
|
|
225
|
-
const resolvedPromotionContent = merged.resolvedContent;
|
|
226
|
-
// Apply quality gate to fast-path knowledge promotion (Risk 4 fix).
|
|
227
|
-
// D-5 / #388: Three-band system — review_needed band queues to proposal
|
|
228
|
-
// queue with review_needed outcome rather than auto-rejecting.
|
|
229
|
-
let knowledgeJudgeConfidence;
|
|
230
|
-
if (ctx.strategy?.processes?.distill?.qualityGate?.enabled ?? true) {
|
|
231
|
-
// D-4 / #390: retrieve top-3 similar lessons for dedup check in judge.
|
|
232
|
-
const similarLessons = await fetchSimilarLessonsFn(resolvedPromotionContent.slice(0, 500), 3);
|
|
233
|
-
const judgeResult = await runLessonQualityJudge(config, resolvedPromotionContent, assetContent ?? "", chat, {
|
|
234
|
-
...(similarLessons.length > 0 ? { similarLessons } : {}),
|
|
235
|
-
...(ctx.llmRunner ? { llmRunner: ctx.llmRunner } : {}),
|
|
236
|
-
...(ctx.lease ? { lease: ctx.lease } : {}),
|
|
237
|
-
...(ctx.signal ? { signal: ctx.signal } : {}),
|
|
238
|
-
...(ctx.onNotices ? { onNotices: ctx.onNotices } : {}),
|
|
239
|
-
});
|
|
240
|
-
if (!judgeResult.pass) {
|
|
241
|
-
const proposalOpts = {
|
|
242
|
-
...(ctx.proposalsCtx ? { proposalsCtx: ctx.proposalsCtx } : {}),
|
|
243
|
-
...(ctx.sourceRun !== undefined ? { sourceRun: ctx.sourceRun } : {}),
|
|
244
|
-
...(ctx.llmRunner?.connection.model ? { modelId: ctx.llmRunner.connection.model } : {}),
|
|
245
|
-
};
|
|
246
|
-
if (judgeResult.reviewNeeded) {
|
|
247
|
-
// Uncertainty band (2.5–3.5): queue as review_needed instead of rejecting.
|
|
248
|
-
return writeQualityRejection(stash, inputRef, promotion.knowledgeRef, resolvedPromotionContent, judgeResult.score, judgeResult.reason, { reviewNeeded: true, ...(judgeResult.criteria ? { criteria: judgeResult.criteria } : {}) }, ctx.eligibilitySource, ctx.eventsCtx, proposalOpts);
|
|
249
|
-
}
|
|
250
|
-
return writeQualityRejection(stash, inputRef, promotion.knowledgeRef, resolvedPromotionContent, judgeResult.score, judgeResult.reason, judgeResult.criteria ? { criteria: judgeResult.criteria } : {}, ctx.eligibilitySource, ctx.eventsCtx, proposalOpts);
|
|
251
|
-
}
|
|
252
|
-
// Normalize 1-5 judge score to [0, 1]. Only a real passing verdict reaches
|
|
253
|
-
// here (07 P0-2: the judge now fails CLOSED on no-LLM / timeout / parse
|
|
254
|
-
// failure, so those return pass:false and early-return above). The score>0
|
|
255
|
-
// guard defensively leaves confidence undefined for any non-positive score.
|
|
256
|
-
if (judgeResult.score > 0)
|
|
257
|
-
knowledgeJudgeConfidence = judgeResult.score / 5;
|
|
258
|
-
}
|
|
259
|
-
const knowledgeParsed = parseFrontmatter(resolvedPromotionContent);
|
|
260
|
-
const proposalResult = emitProposal({ stashDir: stash, proposalsCtx: ctx.proposalsCtx }, {
|
|
261
|
-
ref: promotion.knowledgeRef,
|
|
262
|
-
source: "distill",
|
|
263
|
-
// §23.6 fingerprint model-id term (WI-6.4).
|
|
264
|
-
...(ctx.llmRunner?.connection.model ? { modelId: ctx.llmRunner.connection.model } : {}),
|
|
265
|
-
...(ctx.sourceRun !== undefined ? { sourceRun: ctx.sourceRun } : {}),
|
|
266
|
-
payload: {
|
|
267
|
-
content: resolvedPromotionContent,
|
|
268
|
-
...(Object.keys(knowledgeParsed.data).length > 0 ? { frontmatter: knowledgeParsed.data } : {}),
|
|
269
|
-
},
|
|
270
|
-
...(knowledgeJudgeConfidence !== undefined ? { confidence: knowledgeJudgeConfidence } : {}),
|
|
271
|
-
// Attribution tagging: persist the eligibility lane on the proposal.
|
|
272
|
-
...(ctx.eligibilitySource ? { eligibilitySource: ctx.eligibilitySource } : {}),
|
|
273
|
-
});
|
|
274
|
-
if (isProposalSkipped(proposalResult)) {
|
|
275
|
-
appendEvent({
|
|
276
|
-
eventType: "distill_invoked",
|
|
277
|
-
// Use item_ref when resolved, otherwise the input conceptId.
|
|
278
|
-
ref: ctx.itemRef ?? durableInputRef,
|
|
279
|
-
metadata: {
|
|
280
|
-
outcome: "skipped",
|
|
281
|
-
proposalRef: promotion.knowledgeRef,
|
|
282
|
-
message: proposalResult.message,
|
|
283
|
-
skipReason: proposalResult.reason,
|
|
284
|
-
...eligMeta,
|
|
285
|
-
},
|
|
286
|
-
}, ctx.eventsCtx);
|
|
287
|
-
return {
|
|
288
|
-
schemaVersion: 1,
|
|
289
|
-
ok: true,
|
|
290
|
-
outcome: "skipped",
|
|
291
|
-
inputRef,
|
|
292
|
-
proposalRef: promotion.knowledgeRef,
|
|
293
|
-
skipReason: proposalResult.reason,
|
|
294
|
-
message: proposalResult.message,
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
const proposal = proposalResult;
|
|
298
|
-
// G4: content-score the distilled OUTPUT so it carries a real encoding
|
|
299
|
-
// salience (encoding_source='content') from creation.
|
|
300
|
-
persistOutputEncodingSalience(durableImproveRef(promotion.knowledgeRef), resolvedPromotionContent, existingRefVocabulary, outcomeWeightEnabled);
|
|
301
|
-
appendEvent({
|
|
302
|
-
eventType: "distill_invoked",
|
|
303
|
-
// Use item_ref when resolved, otherwise the input conceptId.
|
|
304
|
-
ref: ctx.itemRef ?? durableInputRef,
|
|
305
|
-
metadata: {
|
|
306
|
-
outcome: "queued",
|
|
307
|
-
proposalRef: promotion.knowledgeRef,
|
|
308
|
-
proposalKind: "knowledge",
|
|
309
|
-
proposalId: proposal.id,
|
|
310
|
-
// R3: judge verdicts are longitudinally queryable, not just a one-shot
|
|
311
|
-
// proposal.confidence write (normalized 1–5 score / 5).
|
|
312
|
-
...(knowledgeJudgeConfidence !== undefined ? { judgeConfidence: knowledgeJudgeConfidence } : {}),
|
|
313
|
-
...(ctx.sourceRun !== undefined ? { sourceRun: ctx.sourceRun } : {}),
|
|
314
|
-
...(exclusionSetSize > 0 ? { filteredFeedbackCount } : {}),
|
|
315
|
-
...eligMeta,
|
|
316
|
-
},
|
|
317
|
-
}, ctx.eventsCtx);
|
|
318
|
-
return {
|
|
319
|
-
schemaVersion: 1,
|
|
320
|
-
ok: true,
|
|
321
|
-
outcome: "queued",
|
|
322
|
-
inputRef,
|
|
323
|
-
proposalRef: promotion.knowledgeRef,
|
|
324
|
-
proposalKind: "knowledge",
|
|
325
|
-
proposalId: proposal.id,
|
|
326
|
-
proposal,
|
|
327
|
-
...(exclusionSetSize > 0 ? { filteredFeedbackCount, feedbackFullyFiltered } : {}),
|
|
328
|
-
};
|
|
329
|
-
}
|