akm-cli 0.9.0-rc.1 → 0.9.0-rc.13
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 +1190 -52
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- 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 +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +13 -9
- package/dist/commands/env/env-cli.js +76 -159
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +75 -228
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -855
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -73
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -58
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +8 -3
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +78 -13
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +48 -279
- package/dist/integrations/harnesses/aider/agent-builder.js +9 -8
- package/dist/integrations/harnesses/aider/index.js +2 -12
- package/dist/integrations/harnesses/amazonq/agent-builder.js +10 -16
- package/dist/integrations/harnesses/amazonq/index.js +3 -17
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +1 -14
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +8 -7
- package/dist/integrations/harnesses/codex/index.js +2 -13
- package/dist/integrations/harnesses/copilot/agent-builder.js +9 -9
- package/dist/integrations/harnesses/copilot/index.js +1 -13
- package/dist/integrations/harnesses/gemini/agent-builder.js +8 -9
- package/dist/integrations/harnesses/gemini/index.js +1 -13
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +31 -33
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +1 -18
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +3 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +12 -10
- package/dist/integrations/harnesses/openhands/index.js +2 -12
- package/dist/integrations/harnesses/pi/agent-builder.js +11 -18
- package/dist/integrations/harnesses/pi/index.js +3 -16
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +38 -34
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +24 -40
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +15 -281
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +8 -40
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1375
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +1 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +68 -35
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/workflows/authoring/authoring.js +96 -148
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -20
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +25 -59
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +157 -94
- package/dist/workflows/exec/report.js +365 -200
- package/dist/workflows/exec/run-workflow.js +46 -40
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +239 -205
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/ir/compile.js +141 -283
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +537 -1
- package/dist/workflows/parser.js +878 -306
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +99 -121
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +200 -113
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +235 -97
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +4 -26
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/{dist/schemas → schemas}/akm-workflow.json +127 -82
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -316
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1414
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -25
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/schemas/akm-config.json +0 -14225
- package/dist/scripts/migrate-storage.js +0 -13169
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -10169
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/db.js +0 -350
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -760
- package/dist/workflows/program/project.js +0 -105
- package/docs/data-and-telemetry.md +0 -227
- package/docs/migration/release-notes/0.9.0-beta.60.md +0 -19
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Calls the configured `/embeddings` endpoint and L2-normalizes the returned
|
|
8
8
|
* vectors so the scoring pipeline's L2-to-cosine conversion is correct.
|
|
9
9
|
*/
|
|
10
|
-
import { fetchWithTimeout, isHttpUrl } from "../../core/common.js";
|
|
10
|
+
import { fetchWithTimeout, isHttpUrl, readBodyWithByteCap } from "../../core/common.js";
|
|
11
11
|
import { resolveSecret } from "../../core/config/config.js";
|
|
12
12
|
const DEFAULT_REMOTE_BATCH_SIZE = 100;
|
|
13
13
|
/** Cheap token estimator: 4 chars ≈ 1 token. Used in verbose logging and error messages. */
|
|
@@ -39,17 +39,24 @@ export class RemoteEmbedder {
|
|
|
39
39
|
if (ollamaOpts) {
|
|
40
40
|
body.options = ollamaOpts;
|
|
41
41
|
}
|
|
42
|
+
// `signal` MUST go through fetchWithTimeout's dedicated 4th parameter, not
|
|
43
|
+
// the RequestInit: fetchWithTimeout replaces `opts.signal` with its own
|
|
44
|
+
// controller (`{ ...opts, signal: controller.signal }`), so a signal passed
|
|
45
|
+
// inside `opts` is silently dropped and caller cancellation never fires.
|
|
42
46
|
const response = await fetchWithTimeout(normalizeEmbeddingEndpoint(this.endpoint), {
|
|
43
47
|
method: "POST",
|
|
44
48
|
headers,
|
|
45
49
|
body: JSON.stringify(body),
|
|
46
|
-
|
|
47
|
-
});
|
|
50
|
+
}, 30_000, signal);
|
|
48
51
|
if (!response.ok) {
|
|
49
|
-
const errBody = await response
|
|
52
|
+
const errBody = await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }).catch((err) => {
|
|
53
|
+
if (signal?.aborted)
|
|
54
|
+
throw err;
|
|
55
|
+
return "";
|
|
56
|
+
});
|
|
50
57
|
throw new Error(`Embedding request failed (${response.status}): ${errBody}`);
|
|
51
58
|
}
|
|
52
|
-
const json = (await response
|
|
59
|
+
const json = JSON.parse(await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }));
|
|
53
60
|
if (!json.data?.[0]?.embedding) {
|
|
54
61
|
throw new Error(`Unexpected embedding response format: missing data[0].embedding.${embeddingEndpointPathHint(this.endpoint)}`);
|
|
55
62
|
}
|
|
@@ -74,17 +81,22 @@ export class RemoteEmbedder {
|
|
|
74
81
|
if (ollamaOpts) {
|
|
75
82
|
body.options = ollamaOpts;
|
|
76
83
|
}
|
|
84
|
+
// See embed(): `signal` goes through the 4th parameter, not the
|
|
85
|
+
// RequestInit, or fetchWithTimeout drops it.
|
|
77
86
|
const response = await fetchWithTimeout(normalizeEmbeddingEndpoint(this.endpoint), {
|
|
78
87
|
method: "POST",
|
|
79
88
|
headers,
|
|
80
89
|
body: JSON.stringify(body),
|
|
81
|
-
|
|
82
|
-
});
|
|
90
|
+
}, 30_000, signal);
|
|
83
91
|
if (!response.ok) {
|
|
84
|
-
const respBody = await response
|
|
92
|
+
const respBody = await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }).catch((err) => {
|
|
93
|
+
if (signal?.aborted)
|
|
94
|
+
throw err;
|
|
95
|
+
return "";
|
|
96
|
+
});
|
|
85
97
|
throw new Error(`Embedding batch request failed (${response.status}): ${respBody}`);
|
|
86
98
|
}
|
|
87
|
-
const json = (await response
|
|
99
|
+
const json = JSON.parse(await readBodyWithByteCap(response, undefined, { bodyTimeoutMs: 30_000, signal }));
|
|
88
100
|
if (!json.data || json.data.length !== batch.length) {
|
|
89
101
|
throw new Error(`Unexpected embedding batch response: expected ${batch.length} embeddings, got ${json.data?.length ?? 0}.${embeddingEndpointPathHint(this.endpoint)}`);
|
|
90
102
|
}
|
package/dist/llm/feature-gate.js
CHANGED
|
@@ -3,54 +3,33 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
5
|
* For each feature key, return the effective enabled state by reading the
|
|
6
|
-
*
|
|
6
|
+
* 0.9.0 config shape.
|
|
7
7
|
*/
|
|
8
|
-
// Defaults below mirror the legacy LlmFeatureFlags docstrings so existing
|
|
9
|
-
// behaviour is preserved when a config is silent on a flag.
|
|
10
8
|
const FEATURE_LOCATION = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
memory_consolidation: (cfg) => cfg.profiles?.improve?.default?.processes?.consolidate?.enabled ?? false,
|
|
14
|
-
// 0.8.0 unified gate: replaces the legacy `feedback_distillation` key.
|
|
15
|
-
// The orchestration gate (planner) and the LLM-call gate now share the same
|
|
16
|
-
// source of truth: `processes.distill.enabled`. Default: true (matches the
|
|
17
|
-
// built-in `default` profile).
|
|
18
|
-
distill: (cfg) => cfg.profiles?.improve?.default?.processes?.distill?.enabled ?? true,
|
|
19
|
-
// Legacy default: true
|
|
20
|
-
memory_inference: (cfg) => cfg.profiles?.improve?.default?.processes?.memoryInference?.enabled ?? true,
|
|
21
|
-
// Legacy default: true
|
|
22
|
-
graph_extraction: (cfg) => cfg.profiles?.improve?.default?.processes?.graphExtraction?.enabled ?? true,
|
|
23
|
-
// Legacy default: false
|
|
9
|
+
memory_inference: (cfg) => cfg.index?.memory?.enabled ?? true,
|
|
10
|
+
graph_extraction: (cfg) => cfg.index?.graph?.enabled ?? true,
|
|
24
11
|
metadata_enhance: (cfg) => cfg.index?.metadataEnhance?.enabled ?? false,
|
|
25
|
-
// Default ON since R3 (docs/design/improve-self-learning-analysis.md G5):
|
|
26
|
-
// distill is a primary acquisition path, so the gate guards minted content by
|
|
27
|
-
// default. The judge fails CLOSED (07 P0-2): no LLM / timeout / parse failure
|
|
28
|
-
// reject the proposal rather than passing it through — an unjudgeable proposal
|
|
29
|
-
// must not slip into the stash. Opt out via
|
|
30
|
-
// profiles.improve.default.processes.distill.qualityGate.enabled: false.
|
|
31
|
-
lesson_quality_gate: (cfg) => cfg.profiles?.improve?.default?.processes?.distill?.qualityGate?.enabled ?? true,
|
|
32
|
-
// Legacy default: false
|
|
33
|
-
proposal_quality_gate: (cfg) => cfg.profiles?.improve?.default?.processes?.reflect?.qualityGate?.enabled ?? false,
|
|
34
|
-
// Legacy default: false
|
|
35
|
-
memory_contradiction_detection: (cfg) => cfg.profiles?.improve?.default?.processes?.consolidate?.contradictionDetection?.enabled ?? false,
|
|
36
12
|
// Always on at the LLM-wrapper level. Enablement is decided ONCE at the
|
|
37
13
|
// extract entry point (`akmExtract`): the `extract.enabled` process toggle
|
|
38
|
-
// gates extract as a STAGE of `akm improve` (the active improve
|
|
14
|
+
// gates extract as a STAGE of `akm improve` (the active improve strategy, per
|
|
39
15
|
// #593/#594), while an explicit `akm extract` command always runs. Gating the
|
|
40
16
|
// inner LLM calls on `default.processes.extract.enabled` here was a footgun —
|
|
41
|
-
// dropping extract from the daily improve
|
|
17
|
+
// dropping extract from the daily improve strategy silently disabled the
|
|
42
18
|
// standalone `akm extract` command. (cfg unused — kept for resolver signature.)
|
|
43
19
|
session_extraction: (_cfg) => true,
|
|
44
20
|
};
|
|
45
21
|
/**
|
|
46
22
|
* Pure predicate: is the named feature gate enabled in `config`?
|
|
47
23
|
*
|
|
48
|
-
* Reads from the unified 0.
|
|
49
|
-
* `LlmFeatureFlags` docstring defaults.
|
|
24
|
+
* Reads from the unified 0.9.0 config shape.
|
|
50
25
|
*/
|
|
51
|
-
export function isLlmFeatureEnabled(config, feature) {
|
|
26
|
+
export function isLlmFeatureEnabled(config, feature, improveEnabled) {
|
|
52
27
|
if (!config)
|
|
53
28
|
return false;
|
|
29
|
+
// Improve resolves enablement from its selected strategy and passes the
|
|
30
|
+
// decision in. This module does not own a second improve config lookup.
|
|
31
|
+
if (improveEnabled !== undefined)
|
|
32
|
+
return improveEnabled;
|
|
54
33
|
const resolver = FEATURE_LOCATION[feature];
|
|
55
34
|
if (!resolver)
|
|
56
35
|
return false;
|
|
@@ -67,13 +46,13 @@ const DEFAULT_TIMEOUT_MS = 600_000;
|
|
|
67
46
|
*/
|
|
68
47
|
export async function tryLlmFeature(feature, config, fn, fallback, opts) {
|
|
69
48
|
const resolveFallback = async () => typeof fallback === "function" ? await fallback() : fallback;
|
|
70
|
-
if (!isLlmFeatureEnabled(config, feature)) {
|
|
49
|
+
if (!isLlmFeatureEnabled(config, feature, opts?.enabled)) {
|
|
71
50
|
opts?.onFallback?.({ feature, reason: "disabled" });
|
|
72
51
|
return resolveFallback();
|
|
73
52
|
}
|
|
74
|
-
const timeoutMs = opts
|
|
53
|
+
const timeoutMs = opts && Object.hasOwn(opts, "timeoutMs") ? (opts.timeoutMs ?? null) : DEFAULT_TIMEOUT_MS;
|
|
75
54
|
try {
|
|
76
|
-
if (timeoutMs <= 0) {
|
|
55
|
+
if (timeoutMs === null || timeoutMs <= 0) {
|
|
77
56
|
return await fn();
|
|
78
57
|
}
|
|
79
58
|
return await runWithTimeout(fn, timeoutMs, feature);
|
|
@@ -86,17 +65,15 @@ export async function tryLlmFeature(feature, config, fn, fallback, opts) {
|
|
|
86
65
|
}
|
|
87
66
|
}
|
|
88
67
|
/**
|
|
89
|
-
* Section-agnostic process gate
|
|
90
|
-
*
|
|
91
|
-
* call sites that knew the (section, processName) pair don't all need to
|
|
92
|
-
* relearn the new mapping.
|
|
68
|
+
* Section-agnostic process gate that maps process identifiers to their current
|
|
69
|
+
* config locations.
|
|
93
70
|
*
|
|
94
71
|
* For unknown (section, processName) pairs the result is `false`.
|
|
95
72
|
*/
|
|
96
73
|
export function isProcessEnabled(section, processName, config) {
|
|
97
74
|
if (!config)
|
|
98
75
|
return false;
|
|
99
|
-
//
|
|
76
|
+
// Index passes are first-class 0.9 entries.
|
|
100
77
|
if (section === "index") {
|
|
101
78
|
if (processName === "metadata_enhance" || processName === "metadataEnhance") {
|
|
102
79
|
return config.index?.metadataEnhance?.enabled ?? true;
|
|
@@ -108,23 +85,6 @@ export function isProcessEnabled(section, processName, config) {
|
|
|
108
85
|
return isLlmFeatureEnabled(config, "graph_extraction");
|
|
109
86
|
}
|
|
110
87
|
}
|
|
111
|
-
if (section === "improve") {
|
|
112
|
-
const processes = config.profiles?.improve?.default?.processes;
|
|
113
|
-
const entry = processes?.[processName];
|
|
114
|
-
if (entry && typeof entry.enabled === "boolean")
|
|
115
|
-
return entry.enabled;
|
|
116
|
-
// Fallback to default-enabled state for known processes.
|
|
117
|
-
switch (processName) {
|
|
118
|
-
case "reflect":
|
|
119
|
-
case "distill":
|
|
120
|
-
case "consolidate":
|
|
121
|
-
case "memoryInference":
|
|
122
|
-
case "graphExtraction":
|
|
123
|
-
return true;
|
|
124
|
-
default:
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
88
|
return false;
|
|
129
89
|
}
|
|
130
90
|
/** Specific error class so call sites and the wrapper can tell timeouts apart from generic throws. */
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* Given a single asset body (typically a `memory:` or `knowledge:` file),
|
|
8
8
|
* asks the configured LLM to surface the entities mentioned in it and the
|
|
9
9
|
* relations between them. The pass itself
|
|
10
|
-
* (`src/indexer/graph-extraction.ts`) is responsible for deciding which
|
|
10
|
+
* (`src/indexer/graph/graph-extraction.ts`) is responsible for deciding which
|
|
11
11
|
* files to extract, persisting the resulting nodes/edges to the index DB,
|
|
12
12
|
* and feeding the graph data into the FTS5+boosts
|
|
13
13
|
* search pipeline as a single boost component.
|
|
@@ -15,16 +15,15 @@
|
|
|
15
15
|
* This module is intentionally tiny and stateless so tests can stub it via
|
|
16
16
|
* `mock.module("../src/llm/graph-extract", ...)` without hitting a network.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* the connection via `resolveIndexPassLLM("graph", config)` and pass it
|
|
21
|
-
* straight through.
|
|
18
|
+
* The LLM connection comes from the selected named engine. Callers obtain it
|
|
19
|
+
* via `resolveIndexPassLLM("graph", config)` and pass it straight through.
|
|
22
20
|
*/
|
|
23
21
|
import systemPromptTemplate from "../assets/prompts/graph-extract-system.md" with { type: "text" };
|
|
24
22
|
import userPromptTemplate from "../assets/prompts/graph-extract-user-prompt.md" with { type: "text" };
|
|
25
23
|
import { toErrorMessage } from "../core/common.js";
|
|
24
|
+
import { parseEmbeddedJsonResponse } from "../core/parse.js";
|
|
26
25
|
import { warn, warnVerbose } from "../core/warn.js";
|
|
27
|
-
import { chatCompletion, isContextSizeError
|
|
26
|
+
import { chatCompletion, isContextSizeError } from "./client.js";
|
|
28
27
|
import { tryLlmFeature } from "./feature-gate.js";
|
|
29
28
|
import { callStructured } from "./structured-call.js";
|
|
30
29
|
/**
|
|
@@ -47,11 +46,6 @@ const SYSTEM_PROMPT = systemPromptTemplate;
|
|
|
47
46
|
const USER_PROMPT_PREFIX = userPromptTemplate
|
|
48
47
|
.replace("{{MAX_ENTITIES}}", String(MAX_ENTITIES_PER_ASSET))
|
|
49
48
|
.replace("{{MAX_RELATIONS}}", String(MAX_RELATIONS_PER_ASSET));
|
|
50
|
-
// `isContextSizeError` is defined in `./client` and re-exported here so the
|
|
51
|
-
// graph extractor and the retry classifier (`isRetryable`) share one
|
|
52
|
-
// definition (#496). Re-exported (not just imported) to preserve existing
|
|
53
|
-
// importers of this module — including its unit test.
|
|
54
|
-
export { isContextSizeError } from "./client.js";
|
|
55
49
|
const GENERIC_ENTITIES = new Set([
|
|
56
50
|
"agent",
|
|
57
51
|
"application",
|
|
@@ -749,5 +743,10 @@ export async function extractGraphFromBody(llmConfig, body, signal, akmConfig, o
|
|
|
749
743
|
onFallback,
|
|
750
744
|
});
|
|
751
745
|
}
|
|
752
|
-
// deduplicateGraph
|
|
753
|
-
|
|
746
|
+
// deduplicateGraph lives in src/indexer/graph/graph-dedup.ts (pure utility, no
|
|
747
|
+
// LLM calls) — import it from there directly. The re-export that used to live
|
|
748
|
+
// here created a value edge back to graph-dedup.ts, which (via its type-only
|
|
749
|
+
// import of GraphExtraction/GraphRelation below) formed a 2-file import cycle
|
|
750
|
+
// (chunk 9 WI-9.8 KILL 4 sever). No src or test consumer used this re-export
|
|
751
|
+
// (graph-extraction.ts and the test suite already import graph-dedup.ts
|
|
752
|
+
// directly), so it is deleted outright rather than repointed.
|
package/dist/llm/index-passes.js
CHANGED
|
@@ -1,50 +1,16 @@
|
|
|
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 {
|
|
4
|
+
import { materializeLlmConnection, resolveLlmEngineUse } from "../integrations/agent/engine-resolution.js";
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* no improve-profile counterpart return undefined and resolve via the
|
|
9
|
-
* default LLM only.
|
|
6
|
+
* Resolve standalone index passes from the index section only. Improve
|
|
7
|
+
* strategies own improve-triggered calls and are intentionally not consulted.
|
|
10
8
|
*/
|
|
11
|
-
function improveProcessKeyForPass(passName) {
|
|
12
|
-
switch (passName) {
|
|
13
|
-
case "memory":
|
|
14
|
-
return "memoryInference";
|
|
15
|
-
case "graph":
|
|
16
|
-
return "graphExtraction";
|
|
17
|
-
default:
|
|
18
|
-
return undefined;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
9
|
export function resolveIndexPassLLM(passName, config) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (passConfig?.llm === false)
|
|
10
|
+
const pass = config.index?.[passName];
|
|
11
|
+
if (pass?.enabled === false)
|
|
25
12
|
return undefined;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
// actually take effect on the graph pass instead of being silently
|
|
30
|
-
// ignored.
|
|
31
|
-
const processKey = improveProcessKeyForPass(passName);
|
|
32
|
-
if (processKey) {
|
|
33
|
-
const processConfig = config.profiles?.improve?.default?.processes?.[processKey];
|
|
34
|
-
// Honor enabled === false here too — an explicit disable wins.
|
|
35
|
-
if (processConfig?.enabled === false)
|
|
36
|
-
return undefined;
|
|
37
|
-
const profileName = processConfig?.profile;
|
|
38
|
-
if (profileName) {
|
|
39
|
-
const profile = config.profiles?.llm?.[profileName];
|
|
40
|
-
if (profile)
|
|
41
|
-
return profile;
|
|
42
|
-
// A named-but-missing profile is a configuration error in spirit, but
|
|
43
|
-
// we fall through to default rather than throwing — callers gracefully
|
|
44
|
-
// treat `undefined` as "pass disabled" and emitting a hard throw here
|
|
45
|
-
// would take the whole improve run down on a typo.
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Gate 3 — fall back to the default LLM profile.
|
|
49
|
-
return getDefaultLlmConfig(config);
|
|
13
|
+
const defaults = config.index?.defaults;
|
|
14
|
+
const resolved = resolveLlmEngineUse(config, [defaults ?? {}, pass ?? {}], { optional: true });
|
|
15
|
+
return resolved ? materializeLlmConnection(resolved) : undefined;
|
|
50
16
|
}
|
package/dist/llm/memory-infer.js
CHANGED
|
@@ -1,4 +1,147 @@
|
|
|
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
|
-
|
|
4
|
+
/**
|
|
5
|
+
* LLM helper for the `akm index` memory-inference pass (#201).
|
|
6
|
+
*
|
|
7
|
+
* Compresses a single memory body into one higher-signal derived memory. The
|
|
8
|
+
* pass itself (in `src/indexer/passes/memory-inference.ts`) is responsible for
|
|
9
|
+
* deciding which memories are pending, persisting the derived memory with the
|
|
10
|
+
* correct frontmatter (`inferred: true`, `source: <parent-ref>`), and marking
|
|
11
|
+
* the parent as processed for idempotency.
|
|
12
|
+
*
|
|
13
|
+
* This module is intentionally tiny and stateless so tests can stub it via
|
|
14
|
+
* `mock.module("../src/llm/memory-infer", ...)` without hitting a network.
|
|
15
|
+
*
|
|
16
|
+
* The LLM connection comes from the selected named engine. Callers obtain it
|
|
17
|
+
* via `resolveIndexPassLLM("memory", config)` and pass it straight through.
|
|
18
|
+
*/
|
|
19
|
+
import memoryInferSystemPrompt from "../assets/prompts/memory-infer-system.md" with { type: "text" };
|
|
20
|
+
import memoryInferUserPrompt from "../assets/prompts/memory-infer-user.md" with { type: "text" };
|
|
21
|
+
import { toErrorMessage } from "../core/common.js";
|
|
22
|
+
import { parseEmbeddedJsonResponse } from "../core/parse.js";
|
|
23
|
+
import { warn } from "../core/warn.js";
|
|
24
|
+
import { callStructured } from "./structured-call.js";
|
|
25
|
+
/** Hard cap on body chars sent to the model — pragmatic and matches `runLlmEnrich`. */
|
|
26
|
+
const MAX_BODY_CHARS = 4000;
|
|
27
|
+
const SYSTEM_PROMPT = memoryInferSystemPrompt;
|
|
28
|
+
const USER_PROMPT_PREFIX = memoryInferUserPrompt;
|
|
29
|
+
const PROMPT_PLACEHOLDERS = new Set([
|
|
30
|
+
"short title string",
|
|
31
|
+
"one sentence summary string",
|
|
32
|
+
"tag1",
|
|
33
|
+
"tag2",
|
|
34
|
+
"search phrase 1",
|
|
35
|
+
"search phrase 2",
|
|
36
|
+
"2-3 sentence compressed body preserving key facts verbatim",
|
|
37
|
+
]);
|
|
38
|
+
/**
|
|
39
|
+
* Strict JSON Schema for the derived-memory payload. Sent to providers that
|
|
40
|
+
* opt in via `ChatCompletionConfig.supportsJsonSchema = true`; the client
|
|
41
|
+
* silently drops the schema for providers that don't.
|
|
42
|
+
*
|
|
43
|
+
* Extends the responseSchema lift (PR 1, asset-writers-investigation §5) to
|
|
44
|
+
* the memory-inference path. Mirrors the validation gate below
|
|
45
|
+
* (title/description/content + non-empty tags/searchHints) so a
|
|
46
|
+
* schema-compliant response is guaranteed to pass the downstream check
|
|
47
|
+
* — no more "incomplete derived memory payload from LLM; skipping memory"
|
|
48
|
+
* for shape-only failures.
|
|
49
|
+
*/
|
|
50
|
+
const DERIVED_MEMORY_JSON_SCHEMA = {
|
|
51
|
+
type: "object",
|
|
52
|
+
properties: {
|
|
53
|
+
title: { type: "string", minLength: 1 },
|
|
54
|
+
description: { type: "string", minLength: 1 },
|
|
55
|
+
content: { type: "string", minLength: 1 },
|
|
56
|
+
tags: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 8 },
|
|
57
|
+
searchHints: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 6 },
|
|
58
|
+
},
|
|
59
|
+
required: ["title", "description", "content", "tags", "searchHints"],
|
|
60
|
+
additionalProperties: false,
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Compress a single memory body into one derived memory via the configured LLM.
|
|
64
|
+
*
|
|
65
|
+
* Returns `undefined` on any failure (timeout, invalid JSON, empty response).
|
|
66
|
+
* Errors are logged via `warn()` but never thrown — a failed split for one memory
|
|
67
|
+
* must not abort the rest of the index pass.
|
|
68
|
+
*
|
|
69
|
+
* Routes through `callStructured({ feature: "memory_inference", ... })` so the
|
|
70
|
+
* feature gate, error classification, and onFallback hook are honoured uniformly
|
|
71
|
+
* (Fix C5).
|
|
72
|
+
*/
|
|
73
|
+
export async function compressMemoryToDerivedMemory(llmConfig, body, signal, akmConfig, onFallback, telemetry, onRetryAttempt) {
|
|
74
|
+
const trimmedBody = body.trim();
|
|
75
|
+
if (!trimmedBody)
|
|
76
|
+
return undefined;
|
|
77
|
+
const userPrompt = `${USER_PROMPT_PREFIX}${trimmedBody.slice(0, MAX_BODY_CHARS)}`;
|
|
78
|
+
// Memory inference is always gated: no config closes the gate instead of
|
|
79
|
+
// taking callStructured's ungated path for direct callers.
|
|
80
|
+
if (!akmConfig) {
|
|
81
|
+
onFallback?.({ feature: "memory_inference", reason: "disabled" });
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
return callStructured({
|
|
85
|
+
feature: "memory_inference",
|
|
86
|
+
akmConfig,
|
|
87
|
+
config: llmConfig,
|
|
88
|
+
messages: [
|
|
89
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
90
|
+
{ role: "user", content: userPrompt },
|
|
91
|
+
],
|
|
92
|
+
request: {
|
|
93
|
+
temperature: 0.1,
|
|
94
|
+
timeoutMs: llmConfig.timeoutMs,
|
|
95
|
+
signal,
|
|
96
|
+
responseSchema: DERIVED_MEMORY_JSON_SCHEMA,
|
|
97
|
+
onRetryAttempt,
|
|
98
|
+
},
|
|
99
|
+
parse: (raw) => {
|
|
100
|
+
if (!raw)
|
|
101
|
+
return undefined;
|
|
102
|
+
const parsed = parseEmbeddedJsonResponse(raw);
|
|
103
|
+
if (!parsed) {
|
|
104
|
+
warn("memory inference: invalid JSON response from LLM; skipping memory.");
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
const title = typeof parsed.title === "string" ? parsed.title.trim() : "";
|
|
108
|
+
const description = typeof parsed.description === "string" ? parsed.description.trim() : "";
|
|
109
|
+
const content = typeof parsed.content === "string" ? parsed.content.trim() : "";
|
|
110
|
+
const tags = Array.isArray(parsed.tags)
|
|
111
|
+
? parsed.tags
|
|
112
|
+
.filter((t) => typeof t === "string")
|
|
113
|
+
.map((t) => t.trim())
|
|
114
|
+
.filter(Boolean)
|
|
115
|
+
.slice(0, 8)
|
|
116
|
+
: [];
|
|
117
|
+
const searchHints = Array.isArray(parsed.searchHints)
|
|
118
|
+
? parsed.searchHints
|
|
119
|
+
.filter((h) => typeof h === "string")
|
|
120
|
+
.map((h) => h.trim())
|
|
121
|
+
.filter(Boolean)
|
|
122
|
+
.slice(0, 6)
|
|
123
|
+
: [];
|
|
124
|
+
if (!title || !description || !content || tags.length === 0 || searchHints.length === 0) {
|
|
125
|
+
warn("memory inference: incomplete derived memory payload from LLM; skipping memory.");
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
if ([title, description, content, ...tags, ...searchHints].some((value) => PROMPT_PLACEHOLDERS.has(value.toLowerCase()))) {
|
|
129
|
+
warn("memory inference: prompt placeholder response from LLM; skipping memory.");
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
return { title, description, tags, searchHints, content };
|
|
133
|
+
},
|
|
134
|
+
onError: (cls, err) => {
|
|
135
|
+
if (cls === "html") {
|
|
136
|
+
if (telemetry)
|
|
137
|
+
telemetry.htmlErrorCount = (telemetry.htmlErrorCount ?? 0) + 1;
|
|
138
|
+
warn(`memory inference: provider returned HTML instead of JSON; skipping memory: ${toErrorMessage(err)}`);
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
warn(`memory inference failed: ${toErrorMessage(err)}`);
|
|
142
|
+
return undefined;
|
|
143
|
+
},
|
|
144
|
+
fallback: undefined,
|
|
145
|
+
onFallback,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* LLM-driven metadata enhancement for stash entries.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* transport client in `client.ts`.
|
|
7
|
+
* Keeps the higher-level workflow for improving descriptions, tags, and search
|
|
8
|
+
* hints separate from the low-level transport client.
|
|
10
9
|
*/
|
|
11
10
|
import metadataEnhanceSystemPrompt from "../assets/prompts/metadata-enhance-system.md" with { type: "text" };
|
|
12
|
-
import { parseJsonResponse } from "
|
|
11
|
+
import { parseJsonResponse } from "../core/parse.js";
|
|
13
12
|
import { callStructured } from "./structured-call.js";
|
|
14
13
|
const SYSTEM_PROMPT = metadataEnhanceSystemPrompt;
|
|
15
14
|
/**
|
|
@@ -17,10 +16,11 @@ const SYSTEM_PROMPT = metadataEnhanceSystemPrompt;
|
|
|
17
16
|
* generate searchHints, and suggest tags.
|
|
18
17
|
*
|
|
19
18
|
* When `akmConfig` is provided, routes through
|
|
20
|
-
* `tryLlmFeature("metadata_enhance", ...)` so the feature gate is honoured
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* the
|
|
19
|
+
* `tryLlmFeature("metadata_enhance", ...)` so the feature gate is honoured: a
|
|
20
|
+
* closed gate yields `{ status: "skipped" }` and a thrown/timed-out call yields
|
|
21
|
+
* `{ status: "failed" }` — neither is reported as an enrichment. When
|
|
22
|
+
* `akmConfig` is `undefined` the gate is bypassed entirely: the LLM call runs
|
|
23
|
+
* unconditionally and errors propagate to direct callers such as tests.
|
|
24
24
|
*/
|
|
25
25
|
export async function enhanceMetadata(config, entry, fileContent, signal, akmConfig) {
|
|
26
26
|
const contextParts = [`Name: ${entry.name}`, `Type: ${entry.type}`];
|
|
@@ -41,12 +41,14 @@ Generate improved metadata for this ${entry.type}. Return JSON with these fields
|
|
|
41
41
|
- "tags": an array of 3-8 relevant keyword tags
|
|
42
42
|
|
|
43
43
|
Return ONLY the JSON object, no explanation.`;
|
|
44
|
-
// `parse` owns the raw response: the `!raw`/unparseable case ⇒
|
|
45
|
-
// description/searchHints/tags shaping.
|
|
46
|
-
// never bumps telemetry
|
|
47
|
-
//
|
|
48
|
-
// ungated path (akmConfig === undefined) propagates
|
|
49
|
-
|
|
44
|
+
// `parse` owns the raw response: the `!raw`/unparseable case ⇒ empty metadata
|
|
45
|
+
// (still a genuine success), plus the description/searchHints/tags shaping.
|
|
46
|
+
// `enhanceMetadata` never warns and never bumps telemetry — `onError` (gated
|
|
47
|
+
// path only) reports `failed` WITHOUT warning, carrying the message so the
|
|
48
|
+
// caller can surface it. The ungated path (akmConfig === undefined) propagates
|
|
49
|
+
// errors via callStructured.
|
|
50
|
+
let timedOut = false;
|
|
51
|
+
const outcome = await callStructured({
|
|
50
52
|
feature: "metadata_enhance",
|
|
51
53
|
akmConfig,
|
|
52
54
|
config,
|
|
@@ -57,23 +59,36 @@ Return ONLY the JSON object, no explanation.`;
|
|
|
57
59
|
request: { signal, timeoutMs: config.timeoutMs },
|
|
58
60
|
parse: (raw) => {
|
|
59
61
|
const parsed = raw ? parseJsonResponse(raw) : undefined;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const metadata = {};
|
|
63
|
+
if (parsed) {
|
|
64
|
+
if (typeof parsed.description === "string" && parsed.description) {
|
|
65
|
+
metadata.description = parsed.description;
|
|
66
|
+
}
|
|
67
|
+
if (Array.isArray(parsed.searchHints)) {
|
|
68
|
+
metadata.searchHints = parsed.searchHints
|
|
69
|
+
.filter((s) => typeof s === "string" && s.trim().length > 0)
|
|
70
|
+
.slice(0, 8);
|
|
71
|
+
}
|
|
72
|
+
if (Array.isArray(parsed.tags)) {
|
|
73
|
+
metadata.tags = parsed.tags
|
|
74
|
+
.filter((s) => typeof s === "string" && s.trim().length > 0)
|
|
75
|
+
.slice(0, 10);
|
|
76
|
+
}
|
|
65
77
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
78
|
+
return { status: "enriched", metadata };
|
|
79
|
+
},
|
|
80
|
+
onError: (_cls, err) => ({ status: "failed", error: err instanceof Error ? err.message : String(err) }),
|
|
81
|
+
fallback: { status: "skipped" },
|
|
82
|
+
// The seam returns the `skipped` fallback for a closed gate AND for a
|
|
83
|
+
// wrapper-level timeout. Record the timeout so we can reclassify it below —
|
|
84
|
+
// a timed-out call is a failure, not a silent skip.
|
|
85
|
+
onFallback: (event) => {
|
|
86
|
+
if (event.reason === "timeout")
|
|
87
|
+
timedOut = true;
|
|
75
88
|
},
|
|
76
|
-
onError: () => ({}),
|
|
77
|
-
fallback: {},
|
|
78
89
|
});
|
|
90
|
+
if (outcome.status === "skipped" && timedOut) {
|
|
91
|
+
return { status: "failed", error: "metadata_enhance timed out" };
|
|
92
|
+
}
|
|
93
|
+
return outcome;
|
|
79
94
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
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 { chatCompletion, isContextSizeError, LlmCallError } from "./client.js";
|
|
4
|
+
import { chatCompletion, isContextSizeError, LlmCallError, } from "./client.js";
|
|
5
5
|
import { tryLlmFeature } from "./feature-gate.js";
|
|
6
6
|
/**
|
|
7
7
|
* Classify a thrown LLM error into one of the three buckets. This is the single
|
|
@@ -17,14 +17,21 @@ export function classifyLlmError(err) {
|
|
|
17
17
|
return "other";
|
|
18
18
|
}
|
|
19
19
|
export async function callStructured(opts) {
|
|
20
|
-
const { feature, akmConfig, config, messages, request, parse, onError, fallback, onFallback } = opts;
|
|
20
|
+
const { feature, akmConfig, enabled, config, messages, request, parse, onError, fallback, onFallback } = opts;
|
|
21
21
|
const chat = request?.chat ?? chatCompletion;
|
|
22
|
+
// Forward each option key ONLY when present on `request` — see the
|
|
23
|
+
// key-presence semantics note on CallStructuredRequest: for `timeoutMs`,
|
|
24
|
+
// present-but-undefined means "explicitly disabled" while absent means
|
|
25
|
+
// "use the default", both in the feature-gate wrapper and the transport.
|
|
26
|
+
const has = (key) => request !== undefined && Object.hasOwn(request, key);
|
|
22
27
|
const chatOptions = {
|
|
23
|
-
temperature: request?.temperature,
|
|
24
|
-
timeoutMs: request?.timeoutMs,
|
|
25
|
-
signal: request?.signal,
|
|
26
|
-
responseSchema: request?.responseSchema,
|
|
27
|
-
|
|
28
|
+
...(has("temperature") ? { temperature: request?.temperature } : {}),
|
|
29
|
+
...(has("timeoutMs") ? { timeoutMs: request?.timeoutMs } : {}),
|
|
30
|
+
...(has("signal") ? { signal: request?.signal } : {}),
|
|
31
|
+
...(has("responseSchema") ? { responseSchema: request?.responseSchema } : {}),
|
|
32
|
+
...(has("maxTokens") ? { maxTokens: request?.maxTokens } : {}),
|
|
33
|
+
...(has("enableThinking") ? { enableThinking: request?.enableThinking } : {}),
|
|
34
|
+
...(has("onRetryAttempt") ? { onRetryAttempt: request?.onRetryAttempt } : {}),
|
|
28
35
|
};
|
|
29
36
|
// UNGATED: run the chat+parse directly. Errors propagate — no `onError`
|
|
30
37
|
// funnel — matching the pre-gate behaviour of direct callers.
|
|
@@ -43,7 +50,8 @@ export async function callStructured(opts) {
|
|
|
43
50
|
return onError(classifyLlmError(err), err);
|
|
44
51
|
}
|
|
45
52
|
}, fallback, {
|
|
46
|
-
timeoutMs: request?.timeoutMs,
|
|
53
|
+
...(has("timeoutMs") ? { timeoutMs: request?.timeoutMs } : {}),
|
|
54
|
+
...(enabled !== undefined ? { enabled } : {}),
|
|
47
55
|
onFallback,
|
|
48
56
|
});
|
|
49
57
|
}
|