conatus 0.1.0
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/LICENSE +21 -0
- package/README.md +189 -0
- package/dist/adapter-layer.d.ts +67 -0
- package/dist/adapter-layer.d.ts.map +1 -0
- package/dist/adapter-layer.js +50 -0
- package/dist/adapter-layer.js.map +1 -0
- package/dist/adapters/a2a-adapter.d.ts +49 -0
- package/dist/adapters/a2a-adapter.d.ts.map +1 -0
- package/dist/adapters/a2a-adapter.js +211 -0
- package/dist/adapters/a2a-adapter.js.map +1 -0
- package/dist/adapters/a2a-client.d.ts +28 -0
- package/dist/adapters/a2a-client.d.ts.map +1 -0
- package/dist/adapters/a2a-client.js +178 -0
- package/dist/adapters/a2a-client.js.map +1 -0
- package/dist/adapters/browser-use-cli.d.ts +19 -0
- package/dist/adapters/browser-use-cli.d.ts.map +1 -0
- package/dist/adapters/browser-use-cli.js +112 -0
- package/dist/adapters/browser-use-cli.js.map +1 -0
- package/dist/adapters/claude-api.d.ts +10 -0
- package/dist/adapters/claude-api.d.ts.map +1 -0
- package/dist/adapters/claude-api.js +63 -0
- package/dist/adapters/claude-api.js.map +1 -0
- package/dist/adapters/claude-code-cli.d.ts +14 -0
- package/dist/adapters/claude-code-cli.d.ts.map +1 -0
- package/dist/adapters/claude-code-cli.js +99 -0
- package/dist/adapters/claude-code-cli.js.map +1 -0
- package/dist/adapters/file-existence-datasource.d.ts +16 -0
- package/dist/adapters/file-existence-datasource.d.ts.map +1 -0
- package/dist/adapters/file-existence-datasource.js +71 -0
- package/dist/adapters/file-existence-datasource.js.map +1 -0
- package/dist/adapters/github-issue-datasource.d.ts +45 -0
- package/dist/adapters/github-issue-datasource.d.ts.map +1 -0
- package/dist/adapters/github-issue-datasource.js +329 -0
- package/dist/adapters/github-issue-datasource.js.map +1 -0
- package/dist/adapters/github-issue.d.ts +87 -0
- package/dist/adapters/github-issue.d.ts.map +1 -0
- package/dist/adapters/github-issue.js +497 -0
- package/dist/adapters/github-issue.js.map +1 -0
- package/dist/adapters/openai-codex.d.ts +26 -0
- package/dist/adapters/openai-codex.d.ts.map +1 -0
- package/dist/adapters/openai-codex.js +112 -0
- package/dist/adapters/openai-codex.js.map +1 -0
- package/dist/adapters/shell-datasource.d.ts +36 -0
- package/dist/adapters/shell-datasource.d.ts.map +1 -0
- package/dist/adapters/shell-datasource.js +138 -0
- package/dist/adapters/shell-datasource.js.map +1 -0
- package/dist/capability-detector.d.ts +124 -0
- package/dist/capability-detector.d.ts.map +1 -0
- package/dist/capability-detector.js +576 -0
- package/dist/capability-detector.js.map +1 -0
- package/dist/character-config.d.ts +34 -0
- package/dist/character-config.d.ts.map +1 -0
- package/dist/character-config.js +53 -0
- package/dist/character-config.js.map +1 -0
- package/dist/cli/cli-logger.d.ts +3 -0
- package/dist/cli/cli-logger.d.ts.map +1 -0
- package/dist/cli/cli-logger.js +12 -0
- package/dist/cli/cli-logger.js.map +1 -0
- package/dist/cli/commands/config.d.ts +12 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +345 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +6 -0
- package/dist/cli/commands/daemon.d.ts.map +1 -0
- package/dist/cli/commands/daemon.js +99 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/goal-raw.d.ts +7 -0
- package/dist/cli/commands/goal-raw.d.ts.map +1 -0
- package/dist/cli/commands/goal-raw.js +93 -0
- package/dist/cli/commands/goal-raw.js.map +1 -0
- package/dist/cli/commands/goal-utils.d.ts +41 -0
- package/dist/cli/commands/goal-utils.d.ts.map +1 -0
- package/dist/cli/commands/goal-utils.js +184 -0
- package/dist/cli/commands/goal-utils.js.map +1 -0
- package/dist/cli/commands/goal.d.ts +22 -0
- package/dist/cli/commands/goal.d.ts.map +1 -0
- package/dist/cli/commands/goal.js +382 -0
- package/dist/cli/commands/goal.js.map +1 -0
- package/dist/cli/commands/plugin.d.ts +9 -0
- package/dist/cli/commands/plugin.d.ts.map +1 -0
- package/dist/cli/commands/plugin.js +336 -0
- package/dist/cli/commands/plugin.js.map +1 -0
- package/dist/cli/commands/report.d.ts +3 -0
- package/dist/cli/commands/report.d.ts.map +1 -0
- package/dist/cli/commands/report.js +29 -0
- package/dist/cli/commands/report.js.map +1 -0
- package/dist/cli/commands/run.d.ts +10 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +159 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/suggest.d.ts +7 -0
- package/dist/cli/commands/suggest.d.ts.map +1 -0
- package/dist/cli/commands/suggest.js +466 -0
- package/dist/cli/commands/suggest.js.map +1 -0
- package/dist/cli/ensure-api-key.d.ts +14 -0
- package/dist/cli/ensure-api-key.d.ts.map +1 -0
- package/dist/cli/ensure-api-key.js +28 -0
- package/dist/cli/ensure-api-key.js.map +1 -0
- package/dist/cli/setup.d.ts +18 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +147 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/utils.d.ts +9 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +113 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/cli-runner.d.ts +32 -0
- package/dist/cli-runner.d.ts.map +1 -0
- package/dist/cli-runner.js +467 -0
- package/dist/cli-runner.js.map +1 -0
- package/dist/codex-llm-client.d.ts +47 -0
- package/dist/codex-llm-client.d.ts.map +1 -0
- package/dist/codex-llm-client.js +193 -0
- package/dist/codex-llm-client.js.map +1 -0
- package/dist/context-provider.d.ts +16 -0
- package/dist/context-provider.d.ts.map +1 -0
- package/dist/context-provider.js +107 -0
- package/dist/context-provider.js.map +1 -0
- package/dist/context-providers/workspace-context.d.ts +8 -0
- package/dist/context-providers/workspace-context.d.ts.map +1 -0
- package/dist/context-providers/workspace-context.js +217 -0
- package/dist/context-providers/workspace-context.js.map +1 -0
- package/dist/core/suggest/repo-context.d.ts +8 -0
- package/dist/core/suggest/repo-context.d.ts.map +1 -0
- package/dist/core/suggest/repo-context.js +154 -0
- package/dist/core/suggest/repo-context.js.map +1 -0
- package/dist/core-loop.d.ts +63 -0
- package/dist/core-loop.d.ts.map +1 -0
- package/dist/core-loop.js +521 -0
- package/dist/core-loop.js.map +1 -0
- package/dist/cross-goal-portfolio.d.ts +153 -0
- package/dist/cross-goal-portfolio.d.ts.map +1 -0
- package/dist/cross-goal-portfolio.js +790 -0
- package/dist/cross-goal-portfolio.js.map +1 -0
- package/dist/curiosity-engine.d.ts +177 -0
- package/dist/curiosity-engine.d.ts.map +1 -0
- package/dist/curiosity-engine.js +736 -0
- package/dist/curiosity-engine.js.map +1 -0
- package/dist/daemon-runner.d.ts +109 -0
- package/dist/daemon-runner.d.ts.map +1 -0
- package/dist/daemon-runner.js +389 -0
- package/dist/daemon-runner.js.map +1 -0
- package/dist/data-source-adapter.d.ts +42 -0
- package/dist/data-source-adapter.d.ts.map +1 -0
- package/dist/data-source-adapter.js +223 -0
- package/dist/data-source-adapter.js.map +1 -0
- package/dist/drive/drive-scorer.d.ts +96 -0
- package/dist/drive/drive-scorer.d.ts.map +1 -0
- package/dist/drive/drive-scorer.js +240 -0
- package/dist/drive/drive-scorer.js.map +1 -0
- package/dist/drive/drive-system.d.ts +99 -0
- package/dist/drive/drive-system.d.ts.map +1 -0
- package/dist/drive/drive-system.js +344 -0
- package/dist/drive/drive-system.js.map +1 -0
- package/dist/drive/gap-calculator.d.ts +80 -0
- package/dist/drive/gap-calculator.d.ts.map +1 -0
- package/dist/drive/gap-calculator.js +219 -0
- package/dist/drive/gap-calculator.js.map +1 -0
- package/dist/drive/reward-log.d.ts +51 -0
- package/dist/drive/reward-log.d.ts.map +1 -0
- package/dist/drive/reward-log.js +48 -0
- package/dist/drive/reward-log.js.map +1 -0
- package/dist/drive/satisficing-helpers.d.ts +28 -0
- package/dist/drive/satisficing-helpers.d.ts.map +1 -0
- package/dist/drive/satisficing-helpers.js +111 -0
- package/dist/drive/satisficing-helpers.js.map +1 -0
- package/dist/drive/satisficing-judge.d.ts +140 -0
- package/dist/drive/satisficing-judge.d.ts.map +1 -0
- package/dist/drive/satisficing-judge.js +432 -0
- package/dist/drive/satisficing-judge.js.map +1 -0
- package/dist/drive/satisficing-propagation.d.ts +30 -0
- package/dist/drive/satisficing-propagation.d.ts.map +1 -0
- package/dist/drive/satisficing-propagation.js +196 -0
- package/dist/drive/satisficing-propagation.js.map +1 -0
- package/dist/drive/stall-detector.d.ts +113 -0
- package/dist/drive/stall-detector.d.ts.map +1 -0
- package/dist/drive/stall-detector.js +378 -0
- package/dist/drive/stall-detector.js.map +1 -0
- package/dist/drive-scorer.d.ts +96 -0
- package/dist/drive-scorer.d.ts.map +1 -0
- package/dist/drive-scorer.js +235 -0
- package/dist/drive-scorer.js.map +1 -0
- package/dist/drive-system.d.ts +92 -0
- package/dist/drive-system.d.ts.map +1 -0
- package/dist/drive-system.js +325 -0
- package/dist/drive-system.js.map +1 -0
- package/dist/embedding-client.d.ts +49 -0
- package/dist/embedding-client.d.ts.map +1 -0
- package/dist/embedding-client.js +141 -0
- package/dist/embedding-client.js.map +1 -0
- package/dist/ethics-gate.d.ts +70 -0
- package/dist/ethics-gate.d.ts.map +1 -0
- package/dist/ethics-gate.js +567 -0
- package/dist/ethics-gate.js.map +1 -0
- package/dist/event-server.d.ts +23 -0
- package/dist/event-server.d.ts.map +1 -0
- package/dist/event-server.js +69 -0
- package/dist/event-server.js.map +1 -0
- package/dist/execution/adapter-layer.d.ts +88 -0
- package/dist/execution/adapter-layer.d.ts.map +1 -0
- package/dist/execution/adapter-layer.js +123 -0
- package/dist/execution/adapter-layer.js.map +1 -0
- package/dist/execution/checkpoint-manager.d.ts +49 -0
- package/dist/execution/checkpoint-manager.d.ts.map +1 -0
- package/dist/execution/checkpoint-manager.js +143 -0
- package/dist/execution/checkpoint-manager.js.map +1 -0
- package/dist/execution/context-budget.d.ts +35 -0
- package/dist/execution/context-budget.d.ts.map +1 -0
- package/dist/execution/context-budget.js +73 -0
- package/dist/execution/context-budget.js.map +1 -0
- package/dist/execution/dimension-selector.d.ts +22 -0
- package/dist/execution/dimension-selector.d.ts.map +1 -0
- package/dist/execution/dimension-selector.js +57 -0
- package/dist/execution/dimension-selector.js.map +1 -0
- package/dist/execution/impact-analyzer.d.ts +24 -0
- package/dist/execution/impact-analyzer.d.ts.map +1 -0
- package/dist/execution/impact-analyzer.js +88 -0
- package/dist/execution/impact-analyzer.js.map +1 -0
- package/dist/execution/parallel-executor.d.ts +35 -0
- package/dist/execution/parallel-executor.d.ts.map +1 -0
- package/dist/execution/parallel-executor.js +162 -0
- package/dist/execution/parallel-executor.js.map +1 -0
- package/dist/execution/pipeline-executor.d.ts +54 -0
- package/dist/execution/pipeline-executor.d.ts.map +1 -0
- package/dist/execution/pipeline-executor.js +250 -0
- package/dist/execution/pipeline-executor.js.map +1 -0
- package/dist/execution/reflection-generator.d.ts +24 -0
- package/dist/execution/reflection-generator.d.ts.map +1 -0
- package/dist/execution/reflection-generator.js +143 -0
- package/dist/execution/reflection-generator.js.map +1 -0
- package/dist/execution/result-reconciler.d.ts +23 -0
- package/dist/execution/result-reconciler.d.ts.map +1 -0
- package/dist/execution/result-reconciler.js +109 -0
- package/dist/execution/result-reconciler.js.map +1 -0
- package/dist/execution/session-manager.d.ts +182 -0
- package/dist/execution/session-manager.d.ts.map +1 -0
- package/dist/execution/session-manager.js +506 -0
- package/dist/execution/session-manager.js.map +1 -0
- package/dist/execution/task-approval-check.d.ts +9 -0
- package/dist/execution/task-approval-check.d.ts.map +1 -0
- package/dist/execution/task-approval-check.js +14 -0
- package/dist/execution/task-approval-check.js.map +1 -0
- package/dist/execution/task-approval.d.ts +37 -0
- package/dist/execution/task-approval.d.ts.map +1 -0
- package/dist/execution/task-approval.js +147 -0
- package/dist/execution/task-approval.js.map +1 -0
- package/dist/execution/task-execution-types.d.ts +14 -0
- package/dist/execution/task-execution-types.d.ts.map +1 -0
- package/dist/execution/task-execution-types.js +2 -0
- package/dist/execution/task-execution-types.js.map +1 -0
- package/dist/execution/task-executor.d.ts +30 -0
- package/dist/execution/task-executor.d.ts.map +1 -0
- package/dist/execution/task-executor.js +196 -0
- package/dist/execution/task-executor.js.map +1 -0
- package/dist/execution/task-generation.d.ts +154 -0
- package/dist/execution/task-generation.d.ts.map +1 -0
- package/dist/execution/task-generation.js +406 -0
- package/dist/execution/task-generation.js.map +1 -0
- package/dist/execution/task-health-check.d.ts +38 -0
- package/dist/execution/task-health-check.d.ts.map +1 -0
- package/dist/execution/task-health-check.js +66 -0
- package/dist/execution/task-health-check.js.map +1 -0
- package/dist/execution/task-lifecycle.d.ts +122 -0
- package/dist/execution/task-lifecycle.d.ts.map +1 -0
- package/dist/execution/task-lifecycle.js +303 -0
- package/dist/execution/task-lifecycle.js.map +1 -0
- package/dist/execution/task-pipeline-cycle.d.ts +45 -0
- package/dist/execution/task-pipeline-cycle.d.ts.map +1 -0
- package/dist/execution/task-pipeline-cycle.js +134 -0
- package/dist/execution/task-pipeline-cycle.js.map +1 -0
- package/dist/execution/task-prompt-builder.d.ts +9 -0
- package/dist/execution/task-prompt-builder.d.ts.map +1 -0
- package/dist/execution/task-prompt-builder.js +165 -0
- package/dist/execution/task-prompt-builder.js.map +1 -0
- package/dist/execution/task-verifier.d.ts +112 -0
- package/dist/execution/task-verifier.d.ts.map +1 -0
- package/dist/execution/task-verifier.js +782 -0
- package/dist/execution/task-verifier.js.map +1 -0
- package/dist/gap-calculator.d.ts +80 -0
- package/dist/gap-calculator.d.ts.map +1 -0
- package/dist/gap-calculator.js +218 -0
- package/dist/gap-calculator.js.map +1 -0
- package/dist/goal/goal-decomposer.d.ts +30 -0
- package/dist/goal/goal-decomposer.d.ts.map +1 -0
- package/dist/goal/goal-decomposer.js +167 -0
- package/dist/goal/goal-decomposer.js.map +1 -0
- package/dist/goal/goal-dependency-graph.d.ts +119 -0
- package/dist/goal/goal-dependency-graph.d.ts.map +1 -0
- package/dist/goal/goal-dependency-graph.js +322 -0
- package/dist/goal/goal-dependency-graph.js.map +1 -0
- package/dist/goal/goal-negotiator.d.ts +66 -0
- package/dist/goal/goal-negotiator.d.ts.map +1 -0
- package/dist/goal/goal-negotiator.js +260 -0
- package/dist/goal/goal-negotiator.js.map +1 -0
- package/dist/goal/goal-suggest.d.ts +85 -0
- package/dist/goal/goal-suggest.d.ts.map +1 -0
- package/dist/goal/goal-suggest.js +178 -0
- package/dist/goal/goal-suggest.js.map +1 -0
- package/dist/goal/goal-tree-manager.d.ts +71 -0
- package/dist/goal/goal-tree-manager.d.ts.map +1 -0
- package/dist/goal/goal-tree-manager.js +580 -0
- package/dist/goal/goal-tree-manager.js.map +1 -0
- package/dist/goal/goal-tree-pruner.d.ts +25 -0
- package/dist/goal/goal-tree-pruner.d.ts.map +1 -0
- package/dist/goal/goal-tree-pruner.js +93 -0
- package/dist/goal/goal-tree-pruner.js.map +1 -0
- package/dist/goal/goal-tree-quality.d.ts +22 -0
- package/dist/goal/goal-tree-quality.d.ts.map +1 -0
- package/dist/goal/goal-tree-quality.js +183 -0
- package/dist/goal/goal-tree-quality.js.map +1 -0
- package/dist/goal/goal-validation.d.ts +20 -0
- package/dist/goal/goal-validation.d.ts.map +1 -0
- package/dist/goal/goal-validation.js +93 -0
- package/dist/goal/goal-validation.js.map +1 -0
- package/dist/goal/negotiator-context.d.ts +13 -0
- package/dist/goal/negotiator-context.d.ts.map +1 -0
- package/dist/goal/negotiator-context.js +119 -0
- package/dist/goal/negotiator-context.js.map +1 -0
- package/dist/goal/negotiator-prompts.d.ts +31 -0
- package/dist/goal/negotiator-prompts.d.ts.map +1 -0
- package/dist/goal/negotiator-prompts.js +65 -0
- package/dist/goal/negotiator-prompts.js.map +1 -0
- package/dist/goal/negotiator-steps.d.ts +59 -0
- package/dist/goal/negotiator-steps.d.ts.map +1 -0
- package/dist/goal/negotiator-steps.js +269 -0
- package/dist/goal/negotiator-steps.js.map +1 -0
- package/dist/goal/state-aggregator.d.ts +89 -0
- package/dist/goal/state-aggregator.d.ts.map +1 -0
- package/dist/goal/state-aggregator.js +292 -0
- package/dist/goal/state-aggregator.js.map +1 -0
- package/dist/goal/tree-loop-orchestrator.d.ts +79 -0
- package/dist/goal/tree-loop-orchestrator.d.ts.map +1 -0
- package/dist/goal/tree-loop-orchestrator.js +230 -0
- package/dist/goal/tree-loop-orchestrator.js.map +1 -0
- package/dist/goal-dependency-graph.d.ts +112 -0
- package/dist/goal-dependency-graph.d.ts.map +1 -0
- package/dist/goal-dependency-graph.js +291 -0
- package/dist/goal-dependency-graph.js.map +1 -0
- package/dist/goal-negotiator.d.ts +109 -0
- package/dist/goal-negotiator.d.ts.map +1 -0
- package/dist/goal-negotiator.js +1044 -0
- package/dist/goal-negotiator.js.map +1 -0
- package/dist/goal-tree-manager.d.ts +120 -0
- package/dist/goal-tree-manager.d.ts.map +1 -0
- package/dist/goal-tree-manager.js +954 -0
- package/dist/goal-tree-manager.js.map +1 -0
- package/dist/guardrail-runner.d.ts +29 -0
- package/dist/guardrail-runner.d.ts.map +1 -0
- package/dist/guardrail-runner.js +81 -0
- package/dist/guardrail-runner.js.map +1 -0
- package/dist/index.d.ts +95 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge/drive-score-adapter.d.ts +39 -0
- package/dist/knowledge/drive-score-adapter.d.ts.map +1 -0
- package/dist/knowledge/drive-score-adapter.js +32 -0
- package/dist/knowledge/drive-score-adapter.js.map +1 -0
- package/dist/knowledge/embedding-client.d.ts +49 -0
- package/dist/knowledge/embedding-client.d.ts.map +1 -0
- package/dist/knowledge/embedding-client.js +141 -0
- package/dist/knowledge/embedding-client.js.map +1 -0
- package/dist/knowledge/knowledge-decisions.d.ts +41 -0
- package/dist/knowledge/knowledge-decisions.d.ts.map +1 -0
- package/dist/knowledge/knowledge-decisions.js +191 -0
- package/dist/knowledge/knowledge-decisions.js.map +1 -0
- package/dist/knowledge/knowledge-graph.d.ts +74 -0
- package/dist/knowledge/knowledge-graph.d.ts.map +1 -0
- package/dist/knowledge/knowledge-graph.js +207 -0
- package/dist/knowledge/knowledge-graph.js.map +1 -0
- package/dist/knowledge/knowledge-manager.d.ts +138 -0
- package/dist/knowledge/knowledge-manager.d.ts.map +1 -0
- package/dist/knowledge/knowledge-manager.js +497 -0
- package/dist/knowledge/knowledge-manager.js.map +1 -0
- package/dist/knowledge/knowledge-revalidation.d.ts +27 -0
- package/dist/knowledge/knowledge-revalidation.d.ts.map +1 -0
- package/dist/knowledge/knowledge-revalidation.js +130 -0
- package/dist/knowledge/knowledge-revalidation.js.map +1 -0
- package/dist/knowledge/knowledge-search.d.ts +49 -0
- package/dist/knowledge/knowledge-search.d.ts.map +1 -0
- package/dist/knowledge/knowledge-search.js +108 -0
- package/dist/knowledge/knowledge-search.js.map +1 -0
- package/dist/knowledge/knowledge-transfer-prompts.d.ts +45 -0
- package/dist/knowledge/knowledge-transfer-prompts.d.ts.map +1 -0
- package/dist/knowledge/knowledge-transfer-prompts.js +72 -0
- package/dist/knowledge/knowledge-transfer-prompts.js.map +1 -0
- package/dist/knowledge/knowledge-transfer.d.ts +148 -0
- package/dist/knowledge/knowledge-transfer.d.ts.map +1 -0
- package/dist/knowledge/knowledge-transfer.js +718 -0
- package/dist/knowledge/knowledge-transfer.js.map +1 -0
- package/dist/knowledge/learning-cross-goal.d.ts +19 -0
- package/dist/knowledge/learning-cross-goal.d.ts.map +1 -0
- package/dist/knowledge/learning-cross-goal.js +173 -0
- package/dist/knowledge/learning-cross-goal.js.map +1 -0
- package/dist/knowledge/learning-feedback.d.ts +26 -0
- package/dist/knowledge/learning-feedback.d.ts.map +1 -0
- package/dist/knowledge/learning-feedback.js +183 -0
- package/dist/knowledge/learning-feedback.js.map +1 -0
- package/dist/knowledge/learning-pipeline-prompts.d.ts +134 -0
- package/dist/knowledge/learning-pipeline-prompts.d.ts.map +1 -0
- package/dist/knowledge/learning-pipeline-prompts.js +103 -0
- package/dist/knowledge/learning-pipeline-prompts.js.map +1 -0
- package/dist/knowledge/learning-pipeline.d.ts +108 -0
- package/dist/knowledge/learning-pipeline.d.ts.map +1 -0
- package/dist/knowledge/learning-pipeline.js +467 -0
- package/dist/knowledge/learning-pipeline.js.map +1 -0
- package/dist/knowledge/memory-compression.d.ts +44 -0
- package/dist/knowledge/memory-compression.d.ts.map +1 -0
- package/dist/knowledge/memory-compression.js +289 -0
- package/dist/knowledge/memory-compression.js.map +1 -0
- package/dist/knowledge/memory-distill.d.ts +31 -0
- package/dist/knowledge/memory-distill.d.ts.map +1 -0
- package/dist/knowledge/memory-distill.js +170 -0
- package/dist/knowledge/memory-distill.js.map +1 -0
- package/dist/knowledge/memory-index.d.ts +11 -0
- package/dist/knowledge/memory-index.d.ts.map +1 -0
- package/dist/knowledge/memory-index.js +134 -0
- package/dist/knowledge/memory-index.js.map +1 -0
- package/dist/knowledge/memory-lifecycle.d.ts +172 -0
- package/dist/knowledge/memory-lifecycle.d.ts.map +1 -0
- package/dist/knowledge/memory-lifecycle.js +398 -0
- package/dist/knowledge/memory-lifecycle.js.map +1 -0
- package/dist/knowledge/memory-persistence.d.ts +30 -0
- package/dist/knowledge/memory-persistence.d.ts.map +1 -0
- package/dist/knowledge/memory-persistence.js +120 -0
- package/dist/knowledge/memory-persistence.js.map +1 -0
- package/dist/knowledge/memory-phases.d.ts +14 -0
- package/dist/knowledge/memory-phases.d.ts.map +1 -0
- package/dist/knowledge/memory-phases.js +14 -0
- package/dist/knowledge/memory-phases.js.map +1 -0
- package/dist/knowledge/memory-query.d.ts +4 -0
- package/dist/knowledge/memory-query.d.ts.map +1 -0
- package/dist/knowledge/memory-query.js +64 -0
- package/dist/knowledge/memory-query.js.map +1 -0
- package/dist/knowledge/memory-selection.d.ts +80 -0
- package/dist/knowledge/memory-selection.d.ts.map +1 -0
- package/dist/knowledge/memory-selection.js +356 -0
- package/dist/knowledge/memory-selection.js.map +1 -0
- package/dist/knowledge/memory-stats.d.ts +7 -0
- package/dist/knowledge/memory-stats.d.ts.map +1 -0
- package/dist/knowledge/memory-stats.js +162 -0
- package/dist/knowledge/memory-stats.js.map +1 -0
- package/dist/knowledge/memory-tier.d.ts +47 -0
- package/dist/knowledge/memory-tier.d.ts.map +1 -0
- package/dist/knowledge/memory-tier.js +212 -0
- package/dist/knowledge/memory-tier.js.map +1 -0
- package/dist/knowledge/transfer-trust.d.ts +40 -0
- package/dist/knowledge/transfer-trust.d.ts.map +1 -0
- package/dist/knowledge/transfer-trust.js +137 -0
- package/dist/knowledge/transfer-trust.js.map +1 -0
- package/dist/knowledge/vector-index.d.ts +65 -0
- package/dist/knowledge/vector-index.d.ts.map +1 -0
- package/dist/knowledge/vector-index.js +153 -0
- package/dist/knowledge/vector-index.js.map +1 -0
- package/dist/knowledge-graph.d.ts +70 -0
- package/dist/knowledge-graph.d.ts.map +1 -0
- package/dist/knowledge-graph.js +194 -0
- package/dist/knowledge-graph.js.map +1 -0
- package/dist/knowledge-manager.d.ts +110 -0
- package/dist/knowledge-manager.d.ts.map +1 -0
- package/dist/knowledge-manager.js +544 -0
- package/dist/knowledge-manager.js.map +1 -0
- package/dist/knowledge-transfer.d.ts +101 -0
- package/dist/knowledge-transfer.d.ts.map +1 -0
- package/dist/knowledge-transfer.js +484 -0
- package/dist/knowledge-transfer.js.map +1 -0
- package/dist/learning-pipeline.d.ts +107 -0
- package/dist/learning-pipeline.d.ts.map +1 -0
- package/dist/learning-pipeline.js +840 -0
- package/dist/learning-pipeline.js.map +1 -0
- package/dist/llm/base-llm-client.d.ts +20 -0
- package/dist/llm/base-llm-client.d.ts.map +1 -0
- package/dist/llm/base-llm-client.js +48 -0
- package/dist/llm/base-llm-client.js.map +1 -0
- package/dist/llm/codex-llm-client.d.ts +41 -0
- package/dist/llm/codex-llm-client.d.ts.map +1 -0
- package/dist/llm/codex-llm-client.js +188 -0
- package/dist/llm/codex-llm-client.js.map +1 -0
- package/dist/llm/llm-client.d.ts +54 -0
- package/dist/llm/llm-client.d.ts.map +1 -0
- package/dist/llm/llm-client.js +148 -0
- package/dist/llm/llm-client.js.map +1 -0
- package/dist/llm/ollama-client.d.ts +24 -0
- package/dist/llm/ollama-client.d.ts.map +1 -0
- package/dist/llm/ollama-client.js +94 -0
- package/dist/llm/ollama-client.js.map +1 -0
- package/dist/llm/openai-client.d.ts +34 -0
- package/dist/llm/openai-client.d.ts.map +1 -0
- package/dist/llm/openai-client.js +140 -0
- package/dist/llm/openai-client.js.map +1 -0
- package/dist/llm/provider-config.d.ts +55 -0
- package/dist/llm/provider-config.d.ts.map +1 -0
- package/dist/llm/provider-config.js +136 -0
- package/dist/llm/provider-config.js.map +1 -0
- package/dist/llm/provider-factory.d.ts +25 -0
- package/dist/llm/provider-factory.d.ts.map +1 -0
- package/dist/llm/provider-factory.js +111 -0
- package/dist/llm/provider-factory.js.map +1 -0
- package/dist/llm-client.d.ts +65 -0
- package/dist/llm-client.d.ts.map +1 -0
- package/dist/llm-client.js +151 -0
- package/dist/llm-client.js.map +1 -0
- package/dist/logger.d.ts +30 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +121 -0
- package/dist/logger.js.map +1 -0
- package/dist/loop/core-loop-capability.d.ts +19 -0
- package/dist/loop/core-loop-capability.d.ts.map +1 -0
- package/dist/loop/core-loop-capability.js +107 -0
- package/dist/loop/core-loop-capability.js.map +1 -0
- package/dist/loop/core-loop-learning.d.ts +34 -0
- package/dist/loop/core-loop-learning.d.ts.map +1 -0
- package/dist/loop/core-loop-learning.js +78 -0
- package/dist/loop/core-loop-learning.js.map +1 -0
- package/dist/loop/core-loop-phases-b.d.ts +25 -0
- package/dist/loop/core-loop-phases-b.d.ts.map +1 -0
- package/dist/loop/core-loop-phases-b.js +510 -0
- package/dist/loop/core-loop-phases-b.js.map +1 -0
- package/dist/loop/core-loop-phases.d.ts +40 -0
- package/dist/loop/core-loop-phases.d.ts.map +1 -0
- package/dist/loop/core-loop-phases.js +228 -0
- package/dist/loop/core-loop-phases.js.map +1 -0
- package/dist/loop/core-loop-types.d.ts +202 -0
- package/dist/loop/core-loop-types.d.ts.map +1 -0
- package/dist/loop/core-loop-types.js +38 -0
- package/dist/loop/core-loop-types.js.map +1 -0
- package/dist/loop/tree-loop-runner.d.ts +24 -0
- package/dist/loop/tree-loop-runner.d.ts.map +1 -0
- package/dist/loop/tree-loop-runner.js +116 -0
- package/dist/loop/tree-loop-runner.js.map +1 -0
- package/dist/memory-lifecycle.d.ts +244 -0
- package/dist/memory-lifecycle.d.ts.map +1 -0
- package/dist/memory-lifecycle.js +1328 -0
- package/dist/memory-lifecycle.js.map +1 -0
- package/dist/notification-dispatcher.d.ts +36 -0
- package/dist/notification-dispatcher.d.ts.map +1 -0
- package/dist/notification-dispatcher.js +363 -0
- package/dist/notification-dispatcher.js.map +1 -0
- package/dist/observation/capability-dependencies.d.ts +45 -0
- package/dist/observation/capability-dependencies.d.ts.map +1 -0
- package/dist/observation/capability-dependencies.js +208 -0
- package/dist/observation/capability-dependencies.js.map +1 -0
- package/dist/observation/capability-detector.d.ts +72 -0
- package/dist/observation/capability-detector.d.ts.map +1 -0
- package/dist/observation/capability-detector.js +372 -0
- package/dist/observation/capability-detector.js.map +1 -0
- package/dist/observation/capability-registry.d.ts +48 -0
- package/dist/observation/capability-registry.d.ts.map +1 -0
- package/dist/observation/capability-registry.js +131 -0
- package/dist/observation/capability-registry.js.map +1 -0
- package/dist/observation/context-provider.d.ts +39 -0
- package/dist/observation/context-provider.d.ts.map +1 -0
- package/dist/observation/context-provider.js +177 -0
- package/dist/observation/context-provider.js.map +1 -0
- package/dist/observation/data-source-adapter.d.ts +42 -0
- package/dist/observation/data-source-adapter.d.ts.map +1 -0
- package/dist/observation/data-source-adapter.js +227 -0
- package/dist/observation/data-source-adapter.js.map +1 -0
- package/dist/observation/observation-apply.d.ts +18 -0
- package/dist/observation/observation-apply.d.ts.map +1 -0
- package/dist/observation/observation-apply.js +138 -0
- package/dist/observation/observation-apply.js.map +1 -0
- package/dist/observation/observation-datasource.d.ts +21 -0
- package/dist/observation/observation-datasource.d.ts.map +1 -0
- package/dist/observation/observation-datasource.js +96 -0
- package/dist/observation/observation-datasource.js.map +1 -0
- package/dist/observation/observation-engine.d.ts +156 -0
- package/dist/observation/observation-engine.d.ts.map +1 -0
- package/dist/observation/observation-engine.js +359 -0
- package/dist/observation/observation-engine.js.map +1 -0
- package/dist/observation/observation-helpers.d.ts +112 -0
- package/dist/observation/observation-helpers.d.ts.map +1 -0
- package/dist/observation/observation-helpers.js +173 -0
- package/dist/observation/observation-helpers.js.map +1 -0
- package/dist/observation/observation-llm.d.ts +46 -0
- package/dist/observation/observation-llm.d.ts.map +1 -0
- package/dist/observation/observation-llm.js +220 -0
- package/dist/observation/observation-llm.js.map +1 -0
- package/dist/observation/observation-task.d.ts +29 -0
- package/dist/observation/observation-task.d.ts.map +1 -0
- package/dist/observation/observation-task.js +51 -0
- package/dist/observation/observation-task.js.map +1 -0
- package/dist/observation/workspace-context.d.ts +8 -0
- package/dist/observation/workspace-context.d.ts.map +1 -0
- package/dist/observation/workspace-context.js +229 -0
- package/dist/observation/workspace-context.js.map +1 -0
- package/dist/observation-engine.d.ts +218 -0
- package/dist/observation-engine.d.ts.map +1 -0
- package/dist/observation-engine.js +711 -0
- package/dist/observation-engine.js.map +1 -0
- package/dist/ollama-client.d.ts +30 -0
- package/dist/ollama-client.d.ts.map +1 -0
- package/dist/ollama-client.js +112 -0
- package/dist/ollama-client.js.map +1 -0
- package/dist/openai-client.d.ts +40 -0
- package/dist/openai-client.d.ts.map +1 -0
- package/dist/openai-client.js +155 -0
- package/dist/openai-client.js.map +1 -0
- package/dist/pid-manager.d.ts +18 -0
- package/dist/pid-manager.d.ts.map +1 -0
- package/dist/pid-manager.js +64 -0
- package/dist/pid-manager.js.map +1 -0
- package/dist/portfolio-manager.d.ts +147 -0
- package/dist/portfolio-manager.d.ts.map +1 -0
- package/dist/portfolio-manager.js +371 -0
- package/dist/portfolio-manager.js.map +1 -0
- package/dist/portfolio-rebalance.d.ts +75 -0
- package/dist/portfolio-rebalance.d.ts.map +1 -0
- package/dist/portfolio-rebalance.js +254 -0
- package/dist/portfolio-rebalance.js.map +1 -0
- package/dist/prompt/context-assembler.d.ts +70 -0
- package/dist/prompt/context-assembler.d.ts.map +1 -0
- package/dist/prompt/context-assembler.js +346 -0
- package/dist/prompt/context-assembler.js.map +1 -0
- package/dist/prompt/formatters.d.ts +49 -0
- package/dist/prompt/formatters.d.ts.map +1 -0
- package/dist/prompt/formatters.js +136 -0
- package/dist/prompt/formatters.js.map +1 -0
- package/dist/prompt/gateway.d.ts +30 -0
- package/dist/prompt/gateway.d.ts.map +1 -0
- package/dist/prompt/gateway.js +43 -0
- package/dist/prompt/gateway.js.map +1 -0
- package/dist/prompt/index.d.ts +12 -0
- package/dist/prompt/index.d.ts.map +1 -0
- package/dist/prompt/index.js +9 -0
- package/dist/prompt/index.js.map +1 -0
- package/dist/prompt/purposes/capability.d.ts +64 -0
- package/dist/prompt/purposes/capability.d.ts.map +1 -0
- package/dist/prompt/purposes/capability.js +38 -0
- package/dist/prompt/purposes/capability.js.map +1 -0
- package/dist/prompt/purposes/checkpoint.d.ts +22 -0
- package/dist/prompt/purposes/checkpoint.d.ts.map +1 -0
- package/dist/prompt/purposes/checkpoint.js +17 -0
- package/dist/prompt/purposes/checkpoint.js.map +1 -0
- package/dist/prompt/purposes/curiosity.d.ts +41 -0
- package/dist/prompt/purposes/curiosity.d.ts.map +1 -0
- package/dist/prompt/purposes/curiosity.js +20 -0
- package/dist/prompt/purposes/curiosity.js.map +1 -0
- package/dist/prompt/purposes/dependency.d.ts +34 -0
- package/dist/prompt/purposes/dependency.d.ts.map +1 -0
- package/dist/prompt/purposes/dependency.js +21 -0
- package/dist/prompt/purposes/dependency.js.map +1 -0
- package/dist/prompt/purposes/ethics.d.ts +47 -0
- package/dist/prompt/purposes/ethics.d.ts.map +1 -0
- package/dist/prompt/purposes/ethics.js +89 -0
- package/dist/prompt/purposes/ethics.js.map +1 -0
- package/dist/prompt/purposes/final-migration.d.ts +15 -0
- package/dist/prompt/purposes/final-migration.d.ts.map +1 -0
- package/dist/prompt/purposes/final-migration.js +15 -0
- package/dist/prompt/purposes/final-migration.js.map +1 -0
- package/dist/prompt/purposes/goal-decomposition.d.ts +46 -0
- package/dist/prompt/purposes/goal-decomposition.d.ts.map +1 -0
- package/dist/prompt/purposes/goal-decomposition.js +20 -0
- package/dist/prompt/purposes/goal-decomposition.js.map +1 -0
- package/dist/prompt/purposes/goal-quality.d.ts +61 -0
- package/dist/prompt/purposes/goal-quality.d.ts.map +1 -0
- package/dist/prompt/purposes/goal-quality.js +37 -0
- package/dist/prompt/purposes/goal-quality.js.map +1 -0
- package/dist/prompt/purposes/index.d.ts +29 -0
- package/dist/prompt/purposes/index.d.ts.map +1 -0
- package/dist/prompt/purposes/index.js +320 -0
- package/dist/prompt/purposes/index.js.map +1 -0
- package/dist/prompt/purposes/knowledge-transfer.d.ts +81 -0
- package/dist/prompt/purposes/knowledge-transfer.d.ts.map +1 -0
- package/dist/prompt/purposes/knowledge-transfer.js +33 -0
- package/dist/prompt/purposes/knowledge-transfer.js.map +1 -0
- package/dist/prompt/purposes/knowledge.d.ts +88 -0
- package/dist/prompt/purposes/knowledge.d.ts.map +1 -0
- package/dist/prompt/purposes/knowledge.js +59 -0
- package/dist/prompt/purposes/knowledge.js.map +1 -0
- package/dist/prompt/purposes/learning.d.ts +70 -0
- package/dist/prompt/purposes/learning.d.ts.map +1 -0
- package/dist/prompt/purposes/learning.js +32 -0
- package/dist/prompt/purposes/learning.js.map +1 -0
- package/dist/prompt/purposes/memory-distill.d.ts +75 -0
- package/dist/prompt/purposes/memory-distill.d.ts.map +1 -0
- package/dist/prompt/purposes/memory-distill.js +27 -0
- package/dist/prompt/purposes/memory-distill.js.map +1 -0
- package/dist/prompt/purposes/observation.d.ts +25 -0
- package/dist/prompt/purposes/observation.d.ts.map +1 -0
- package/dist/prompt/purposes/observation.js +17 -0
- package/dist/prompt/purposes/observation.js.map +1 -0
- package/dist/prompt/purposes/strategy-template.d.ts +57 -0
- package/dist/prompt/purposes/strategy-template.d.ts.map +1 -0
- package/dist/prompt/purposes/strategy-template.js +31 -0
- package/dist/prompt/purposes/strategy-template.js.map +1 -0
- package/dist/prompt/purposes/strategy.d.ts +41 -0
- package/dist/prompt/purposes/strategy.d.ts.map +1 -0
- package/dist/prompt/purposes/strategy.js +19 -0
- package/dist/prompt/purposes/strategy.js.map +1 -0
- package/dist/prompt/purposes/task-generation.d.ts +26 -0
- package/dist/prompt/purposes/task-generation.d.ts.map +1 -0
- package/dist/prompt/purposes/task-generation.js +22 -0
- package/dist/prompt/purposes/task-generation.js.map +1 -0
- package/dist/prompt/purposes/verification.d.ts +25 -0
- package/dist/prompt/purposes/verification.d.ts.map +1 -0
- package/dist/prompt/purposes/verification.js +17 -0
- package/dist/prompt/purposes/verification.js.map +1 -0
- package/dist/prompt/slot-definitions 2.d.ts +33 -0
- package/dist/prompt/slot-definitions 2.d.ts.map +1 -0
- package/dist/prompt/slot-definitions 2.js +332 -0
- package/dist/prompt/slot-definitions 2.js.map +1 -0
- package/dist/prompt/slot-definitions.d.ts +33 -0
- package/dist/prompt/slot-definitions.d.ts.map +1 -0
- package/dist/prompt/slot-definitions.js +383 -0
- package/dist/prompt/slot-definitions.js.map +1 -0
- package/dist/provider-config.d.ts +43 -0
- package/dist/provider-config.d.ts.map +1 -0
- package/dist/provider-config.js +131 -0
- package/dist/provider-config.js.map +1 -0
- package/dist/provider-factory.d.ts +23 -0
- package/dist/provider-factory.d.ts.map +1 -0
- package/dist/provider-factory.js +83 -0
- package/dist/provider-factory.js.map +1 -0
- package/dist/reporting-engine.d.ts +58 -0
- package/dist/reporting-engine.d.ts.map +1 -0
- package/dist/reporting-engine.js +592 -0
- package/dist/reporting-engine.js.map +1 -0
- package/dist/runtime/daemon-runner.d.ts +147 -0
- package/dist/runtime/daemon-runner.d.ts.map +1 -0
- package/dist/runtime/daemon-runner.js +549 -0
- package/dist/runtime/daemon-runner.js.map +1 -0
- package/dist/runtime/event-server.d.ts +50 -0
- package/dist/runtime/event-server.d.ts.map +1 -0
- package/dist/runtime/event-server.js +192 -0
- package/dist/runtime/event-server.js.map +1 -0
- package/dist/runtime/logger.d.ts +57 -0
- package/dist/runtime/logger.d.ts.map +1 -0
- package/dist/runtime/logger.js +254 -0
- package/dist/runtime/logger.js.map +1 -0
- package/dist/runtime/notification-dispatcher.d.ts +49 -0
- package/dist/runtime/notification-dispatcher.d.ts.map +1 -0
- package/dist/runtime/notification-dispatcher.js +444 -0
- package/dist/runtime/notification-dispatcher.js.map +1 -0
- package/dist/runtime/notifier-registry.d.ts +26 -0
- package/dist/runtime/notifier-registry.d.ts.map +1 -0
- package/dist/runtime/notifier-registry.js +36 -0
- package/dist/runtime/notifier-registry.js.map +1 -0
- package/dist/runtime/pid-manager.d.ts +18 -0
- package/dist/runtime/pid-manager.d.ts.map +1 -0
- package/dist/runtime/pid-manager.js +61 -0
- package/dist/runtime/pid-manager.js.map +1 -0
- package/dist/runtime/plugin-loader.d.ts +78 -0
- package/dist/runtime/plugin-loader.d.ts.map +1 -0
- package/dist/runtime/plugin-loader.js +349 -0
- package/dist/runtime/plugin-loader.js.map +1 -0
- package/dist/satisficing-judge.d.ts +113 -0
- package/dist/satisficing-judge.d.ts.map +1 -0
- package/dist/satisficing-judge.js +592 -0
- package/dist/satisficing-judge.js.map +1 -0
- package/dist/session-manager.d.ts +159 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +458 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/stall-detector.d.ts +100 -0
- package/dist/stall-detector.d.ts.map +1 -0
- package/dist/stall-detector.js +306 -0
- package/dist/stall-detector.js.map +1 -0
- package/dist/state-aggregator.d.ts +89 -0
- package/dist/state-aggregator.d.ts.map +1 -0
- package/dist/state-aggregator.js +290 -0
- package/dist/state-aggregator.js.map +1 -0
- package/dist/state-manager.d.ts +121 -0
- package/dist/state-manager.d.ts.map +1 -0
- package/dist/state-manager.js +547 -0
- package/dist/state-manager.js.map +1 -0
- package/dist/strategy/cross-goal-portfolio.d.ts +118 -0
- package/dist/strategy/cross-goal-portfolio.d.ts.map +1 -0
- package/dist/strategy/cross-goal-portfolio.js +431 -0
- package/dist/strategy/cross-goal-portfolio.js.map +1 -0
- package/dist/strategy/portfolio-allocation.d.ts +36 -0
- package/dist/strategy/portfolio-allocation.d.ts.map +1 -0
- package/dist/strategy/portfolio-allocation.js +215 -0
- package/dist/strategy/portfolio-allocation.js.map +1 -0
- package/dist/strategy/portfolio-momentum.d.ts +11 -0
- package/dist/strategy/portfolio-momentum.d.ts.map +1 -0
- package/dist/strategy/portfolio-momentum.js +64 -0
- package/dist/strategy/portfolio-momentum.js.map +1 -0
- package/dist/strategy/portfolio-scheduling.d.ts +25 -0
- package/dist/strategy/portfolio-scheduling.d.ts.map +1 -0
- package/dist/strategy/portfolio-scheduling.js +133 -0
- package/dist/strategy/portfolio-scheduling.js.map +1 -0
- package/dist/strategy/strategy-helpers.d.ts +109 -0
- package/dist/strategy/strategy-helpers.d.ts.map +1 -0
- package/dist/strategy/strategy-helpers.js +125 -0
- package/dist/strategy/strategy-helpers.js.map +1 -0
- package/dist/strategy/strategy-manager-base.d.ts +95 -0
- package/dist/strategy/strategy-manager-base.d.ts.map +1 -0
- package/dist/strategy/strategy-manager-base.js +363 -0
- package/dist/strategy/strategy-manager-base.js.map +1 -0
- package/dist/strategy/strategy-manager.d.ts +65 -0
- package/dist/strategy/strategy-manager.d.ts.map +1 -0
- package/dist/strategy/strategy-manager.js +226 -0
- package/dist/strategy/strategy-manager.js.map +1 -0
- package/dist/strategy/strategy-template-registry.d.ts +84 -0
- package/dist/strategy/strategy-template-registry.d.ts.map +1 -0
- package/dist/strategy/strategy-template-registry.js +350 -0
- package/dist/strategy/strategy-template-registry.js.map +1 -0
- package/dist/strategy-manager.d.ts +128 -0
- package/dist/strategy-manager.d.ts.map +1 -0
- package/dist/strategy-manager.js +579 -0
- package/dist/strategy-manager.js.map +1 -0
- package/dist/strategy-template-registry.d.ts +80 -0
- package/dist/strategy-template-registry.d.ts.map +1 -0
- package/dist/strategy-template-registry.js +320 -0
- package/dist/strategy-template-registry.js.map +1 -0
- package/dist/task-lifecycle.d.ts +167 -0
- package/dist/task-lifecycle.d.ts.map +1 -0
- package/dist/task-lifecycle.js +1161 -0
- package/dist/task-lifecycle.js.map +1 -0
- package/dist/traits/character-config.d.ts +34 -0
- package/dist/traits/character-config.d.ts.map +1 -0
- package/dist/traits/character-config.js +53 -0
- package/dist/traits/character-config.js.map +1 -0
- package/dist/traits/curiosity-engine.d.ts +185 -0
- package/dist/traits/curiosity-engine.d.ts.map +1 -0
- package/dist/traits/curiosity-engine.js +530 -0
- package/dist/traits/curiosity-engine.js.map +1 -0
- package/dist/traits/curiosity-proposals.d.ts +38 -0
- package/dist/traits/curiosity-proposals.d.ts.map +1 -0
- package/dist/traits/curiosity-proposals.js +259 -0
- package/dist/traits/curiosity-proposals.js.map +1 -0
- package/dist/traits/curiosity-transfer.d.ts +27 -0
- package/dist/traits/curiosity-transfer.d.ts.map +1 -0
- package/dist/traits/curiosity-transfer.js +50 -0
- package/dist/traits/curiosity-transfer.js.map +1 -0
- package/dist/traits/ethics-gate.d.ts +72 -0
- package/dist/traits/ethics-gate.d.ts.map +1 -0
- package/dist/traits/ethics-gate.js +591 -0
- package/dist/traits/ethics-gate.js.map +1 -0
- package/dist/traits/trust-manager.d.ts +90 -0
- package/dist/traits/trust-manager.d.ts.map +1 -0
- package/dist/traits/trust-manager.js +276 -0
- package/dist/traits/trust-manager.js.map +1 -0
- package/dist/tree-loop-orchestrator.d.ts +79 -0
- package/dist/tree-loop-orchestrator.d.ts.map +1 -0
- package/dist/tree-loop-orchestrator.js +225 -0
- package/dist/tree-loop-orchestrator.js.map +1 -0
- package/dist/trust-manager.d.ts +67 -0
- package/dist/trust-manager.d.ts.map +1 -0
- package/dist/trust-manager.js +201 -0
- package/dist/trust-manager.js.map +1 -0
- package/dist/tui/actions.d.ts +38 -0
- package/dist/tui/actions.d.ts.map +1 -0
- package/dist/tui/actions.js +229 -0
- package/dist/tui/actions.js.map +1 -0
- package/dist/tui/app.d.ts +24 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +159 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/approval-overlay.d.ts +8 -0
- package/dist/tui/approval-overlay.d.ts.map +1 -0
- package/dist/tui/approval-overlay.js +20 -0
- package/dist/tui/approval-overlay.js.map +1 -0
- package/dist/tui/chat.d.ts +15 -0
- package/dist/tui/chat.d.ts.map +1 -0
- package/dist/tui/chat.js +196 -0
- package/dist/tui/chat.js.map +1 -0
- package/dist/tui/dashboard.d.ts +9 -0
- package/dist/tui/dashboard.d.ts.map +1 -0
- package/dist/tui/dashboard.js +69 -0
- package/dist/tui/dashboard.js.map +1 -0
- package/dist/tui/entry.d.ts +3 -0
- package/dist/tui/entry.d.ts.map +1 -0
- package/dist/tui/entry.js +222 -0
- package/dist/tui/entry.js.map +1 -0
- package/dist/tui/fuzzy.d.ts +22 -0
- package/dist/tui/fuzzy.d.ts.map +1 -0
- package/dist/tui/fuzzy.js +66 -0
- package/dist/tui/fuzzy.js.map +1 -0
- package/dist/tui/help-overlay.d.ts +6 -0
- package/dist/tui/help-overlay.d.ts.map +1 -0
- package/dist/tui/help-overlay.js +12 -0
- package/dist/tui/help-overlay.js.map +1 -0
- package/dist/tui/intent-recognizer.d.ts +19 -0
- package/dist/tui/intent-recognizer.d.ts.map +1 -0
- package/dist/tui/intent-recognizer.js +125 -0
- package/dist/tui/intent-recognizer.js.map +1 -0
- package/dist/tui/markdown-renderer.d.ts +37 -0
- package/dist/tui/markdown-renderer.d.ts.map +1 -0
- package/dist/tui/markdown-renderer.js +220 -0
- package/dist/tui/markdown-renderer.js.map +1 -0
- package/dist/tui/report-view.d.ts +6 -0
- package/dist/tui/report-view.d.ts.map +1 -0
- package/dist/tui/report-view.js +79 -0
- package/dist/tui/report-view.js.map +1 -0
- package/dist/tui/use-loop.d.ts +54 -0
- package/dist/tui/use-loop.d.ts.map +1 -0
- package/dist/tui/use-loop.js +185 -0
- package/dist/tui/use-loop.js.map +1 -0
- package/dist/types/a2a.d.ts +972 -0
- package/dist/types/a2a.d.ts.map +1 -0
- package/dist/types/a2a.js +130 -0
- package/dist/types/a2a.js.map +1 -0
- package/dist/types/capability.d.ts +292 -0
- package/dist/types/capability.d.ts.map +1 -0
- package/dist/types/capability.js +53 -0
- package/dist/types/capability.js.map +1 -0
- package/dist/types/character.d.ts +20 -0
- package/dist/types/character.d.ts.map +1 -0
- package/dist/types/character.js +10 -0
- package/dist/types/character.js.map +1 -0
- package/dist/types/checkpoint.d.ts +109 -0
- package/dist/types/checkpoint.d.ts.map +1 -0
- package/dist/types/checkpoint.js +27 -0
- package/dist/types/checkpoint.js.map +1 -0
- package/dist/types/core.d.ts +175 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +154 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/cross-portfolio.d.ts +378 -0
- package/dist/types/cross-portfolio.d.ts.map +1 -0
- package/dist/types/cross-portfolio.js +155 -0
- package/dist/types/cross-portfolio.js.map +1 -0
- package/dist/types/curiosity.d.ts +443 -0
- package/dist/types/curiosity.d.ts.map +1 -0
- package/dist/types/curiosity.js +86 -0
- package/dist/types/curiosity.js.map +1 -0
- package/dist/types/daemon.d.ts +111 -0
- package/dist/types/daemon.d.ts.map +1 -0
- package/dist/types/daemon.js +37 -0
- package/dist/types/daemon.js.map +1 -0
- package/dist/types/data-source.d.ts +311 -0
- package/dist/types/data-source.d.ts.map +1 -0
- package/dist/types/data-source.js +53 -0
- package/dist/types/data-source.js.map +1 -0
- package/dist/types/dependency.d.ts +108 -0
- package/dist/types/dependency.d.ts.map +1 -0
- package/dist/types/dependency.js +21 -0
- package/dist/types/dependency.js.map +1 -0
- package/dist/types/drive.d.ts +194 -0
- package/dist/types/drive.d.ts.map +1 -0
- package/dist/types/drive.js +77 -0
- package/dist/types/drive.js.map +1 -0
- package/dist/types/embedding.d.ts +59 -0
- package/dist/types/embedding.d.ts.map +1 -0
- package/dist/types/embedding.js +22 -0
- package/dist/types/embedding.js.map +1 -0
- package/dist/types/ethics.d.ts +169 -0
- package/dist/types/ethics.d.ts.map +1 -0
- package/dist/types/ethics.js +47 -0
- package/dist/types/ethics.js.map +1 -0
- package/dist/types/gap.d.ts +146 -0
- package/dist/types/gap.d.ts.map +1 -0
- package/dist/types/gap.js +41 -0
- package/dist/types/gap.js.map +1 -0
- package/dist/types/goal-tree.d.ts +180 -0
- package/dist/types/goal-tree.d.ts.map +1 -0
- package/dist/types/goal-tree.js +73 -0
- package/dist/types/goal-tree.js.map +1 -0
- package/dist/types/goal.d.ts +1233 -0
- package/dist/types/goal.d.ts.map +1 -0
- package/dist/types/goal.js +119 -0
- package/dist/types/goal.js.map +1 -0
- package/dist/types/guardrail.d.ts +104 -0
- package/dist/types/guardrail.d.ts.map +1 -0
- package/dist/types/guardrail.js +34 -0
- package/dist/types/guardrail.js.map +1 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +31 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/knowledge.d.ts +402 -0
- package/dist/types/knowledge.d.ts.map +1 -0
- package/dist/types/knowledge.js +116 -0
- package/dist/types/knowledge.js.map +1 -0
- package/dist/types/learning.d.ts +292 -0
- package/dist/types/learning.d.ts.map +1 -0
- package/dist/types/learning.js +120 -0
- package/dist/types/learning.js.map +1 -0
- package/dist/types/memory-lifecycle.d.ts +617 -0
- package/dist/types/memory-lifecycle.d.ts.map +1 -0
- package/dist/types/memory-lifecycle.js +159 -0
- package/dist/types/memory-lifecycle.js.map +1 -0
- package/dist/types/negotiation.d.ts +450 -0
- package/dist/types/negotiation.d.ts.map +1 -0
- package/dist/types/negotiation.js +84 -0
- package/dist/types/negotiation.js.map +1 -0
- package/dist/types/notification.d.ts +879 -0
- package/dist/types/notification.d.ts.map +1 -0
- package/dist/types/notification.js +75 -0
- package/dist/types/notification.js.map +1 -0
- package/dist/types/pipeline.d.ts +191 -0
- package/dist/types/pipeline.d.ts.map +1 -0
- package/dist/types/pipeline.js +62 -0
- package/dist/types/pipeline.js.map +1 -0
- package/dist/types/plugin.d.ts +335 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +61 -0
- package/dist/types/plugin.js.map +1 -0
- package/dist/types/portfolio.d.ts +146 -0
- package/dist/types/portfolio.d.ts.map +1 -0
- package/dist/types/portfolio.js +55 -0
- package/dist/types/portfolio.js.map +1 -0
- package/dist/types/reflection.d.ts +34 -0
- package/dist/types/reflection.d.ts.map +1 -0
- package/dist/types/reflection.js +14 -0
- package/dist/types/reflection.js.map +1 -0
- package/dist/types/report.d.ts +205 -0
- package/dist/types/report.d.ts.map +1 -0
- package/dist/types/report.js +59 -0
- package/dist/types/report.js.map +1 -0
- package/dist/types/satisficing.d.ts +130 -0
- package/dist/types/satisficing.d.ts.map +1 -0
- package/dist/types/satisficing.js +54 -0
- package/dist/types/satisficing.js.map +1 -0
- package/dist/types/session.d.ts +95 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +36 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/stall.d.ts +68 -0
- package/dist/types/stall.d.ts.map +1 -0
- package/dist/types/stall.js +28 -0
- package/dist/types/stall.js.map +1 -0
- package/dist/types/state.d.ts +245 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +36 -0
- package/dist/types/state.js.map +1 -0
- package/dist/types/strategy.d.ts +541 -0
- package/dist/types/strategy.d.ts.map +1 -0
- package/dist/types/strategy.js +55 -0
- package/dist/types/strategy.js.map +1 -0
- package/dist/types/suggest.d.ts +92 -0
- package/dist/types/suggest.d.ts.map +1 -0
- package/dist/types/suggest.js +15 -0
- package/dist/types/suggest.js.map +1 -0
- package/dist/types/task-group.d.ts +231 -0
- package/dist/types/task-group.d.ts.map +1 -0
- package/dist/types/task-group.js +14 -0
- package/dist/types/task-group.js.map +1 -0
- package/dist/types/task.d.ts +258 -0
- package/dist/types/task.d.ts.map +1 -0
- package/dist/types/task.js +66 -0
- package/dist/types/task.js.map +1 -0
- package/dist/types/trust.d.ts +126 -0
- package/dist/types/trust.d.ts.map +1 -0
- package/dist/types/trust.js +38 -0
- package/dist/types/trust.js.map +1 -0
- package/dist/utils/errors.d.ts +17 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +34 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/json-io.d.ts +28 -0
- package/dist/utils/json-io.d.ts.map +1 -0
- package/dist/utils/json-io.js +71 -0
- package/dist/utils/json-io.js.map +1 -0
- package/dist/utils/paths.d.ts +14 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +38 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/sleep.d.ts +2 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +4 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/vector-index.d.ts +39 -0
- package/dist/vector-index.d.ts.map +1 -0
- package/dist/vector-index.js +111 -0
- package/dist/vector-index.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,1328 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ShortTermEntrySchema, LessonEntrySchema, StatisticalSummarySchema, MemoryIndexSchema, RetentionConfigSchema, } from "./types/memory-lifecycle.js";
|
|
6
|
+
/**
|
|
7
|
+
* DriveScoreAdapter adapts DriveScore[] output from DriveScorer
|
|
8
|
+
* to the IDriveScorer interface expected by MemoryLifecycleManager.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* const adapter = new DriveScoreAdapter();
|
|
12
|
+
* // After each drive scoring step in CoreLoop:
|
|
13
|
+
* adapter.update(driveScores);
|
|
14
|
+
* // MemoryLifecycleManager reads via getDissatisfactionScore()
|
|
15
|
+
*/
|
|
16
|
+
export class DriveScoreAdapter {
|
|
17
|
+
scores = new Map();
|
|
18
|
+
/**
|
|
19
|
+
* Replace the stored drive scores with the latest batch.
|
|
20
|
+
* Each entry must have a dimension_name and dissatisfaction score.
|
|
21
|
+
*/
|
|
22
|
+
update(driveScores) {
|
|
23
|
+
this.scores.clear();
|
|
24
|
+
for (const s of driveScores) {
|
|
25
|
+
this.scores.set(s.dimension_name, s.dissatisfaction);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Returns the stored dissatisfaction score for the given dimension.
|
|
30
|
+
* Returns 0 if the dimension is unknown (safe default: no delay inflation).
|
|
31
|
+
*/
|
|
32
|
+
getDissatisfactionScore(dimension) {
|
|
33
|
+
return this.scores.get(dimension) ?? 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// ─── LLM response schemas ───
|
|
37
|
+
const PatternExtractionResponseSchema = z.object({
|
|
38
|
+
patterns: z.array(z.string()),
|
|
39
|
+
});
|
|
40
|
+
const LessonDistillationResponseSchema = z.object({
|
|
41
|
+
lessons: z.array(z.object({
|
|
42
|
+
type: z.enum(["strategy_outcome", "success_pattern", "failure_pattern"]),
|
|
43
|
+
context: z.string(),
|
|
44
|
+
action: z.string().optional(),
|
|
45
|
+
outcome: z.string().optional(),
|
|
46
|
+
lesson: z.string(),
|
|
47
|
+
relevance_tags: z.array(z.string()).default([]),
|
|
48
|
+
failure_reason: z.string().optional(),
|
|
49
|
+
avoidance_hint: z.string().optional(),
|
|
50
|
+
applicability: z.string().optional(),
|
|
51
|
+
})),
|
|
52
|
+
});
|
|
53
|
+
// ─── MemoryLifecycleManager ───
|
|
54
|
+
/**
|
|
55
|
+
* MemoryLifecycleManager handles the 3-tier memory model:
|
|
56
|
+
* - Working Memory: view/selection from Short-term + Long-term (1 session lifetime)
|
|
57
|
+
* - Short-term Memory: raw data, configurable retention (default: 100 loops)
|
|
58
|
+
* - Long-term Memory: compressed lessons + statistics (permanent)
|
|
59
|
+
*
|
|
60
|
+
* Directory layout:
|
|
61
|
+
* <base>/memory/short-term/goals/<goal_id>/{experience-log,observations,strategies,tasks}.json
|
|
62
|
+
* <base>/memory/short-term/index.json
|
|
63
|
+
* <base>/memory/long-term/lessons/by-goal/<goal_id>.json
|
|
64
|
+
* <base>/memory/long-term/lessons/by-dimension/<dim>.json
|
|
65
|
+
* <base>/memory/long-term/lessons/global.json
|
|
66
|
+
* <base>/memory/long-term/statistics/<goal_id>.json
|
|
67
|
+
* <base>/memory/long-term/index.json
|
|
68
|
+
* <base>/memory/archive/<goal_id>/{lessons,statistics}.json
|
|
69
|
+
*/
|
|
70
|
+
export class MemoryLifecycleManager {
|
|
71
|
+
baseDir;
|
|
72
|
+
memoryDir;
|
|
73
|
+
llmClient;
|
|
74
|
+
config;
|
|
75
|
+
embeddingClient;
|
|
76
|
+
vectorIndex;
|
|
77
|
+
driveScorer;
|
|
78
|
+
// Phase 2: internal map for early compression candidates
|
|
79
|
+
earlyCompressionCandidates = new Map();
|
|
80
|
+
constructor(baseDir, llmClient, config, embeddingClient, vectorIndex, driveScorer) {
|
|
81
|
+
this.baseDir = baseDir;
|
|
82
|
+
this.memoryDir = path.join(baseDir, "memory");
|
|
83
|
+
this.llmClient = llmClient;
|
|
84
|
+
this.config = RetentionConfigSchema.parse(config ?? {});
|
|
85
|
+
this.embeddingClient = embeddingClient;
|
|
86
|
+
this.vectorIndex = vectorIndex;
|
|
87
|
+
this.driveScorer = driveScorer;
|
|
88
|
+
}
|
|
89
|
+
// ─── Directory Initialization ───
|
|
90
|
+
/** Create directory structure for memory storage */
|
|
91
|
+
initializeDirectories() {
|
|
92
|
+
const dirs = [
|
|
93
|
+
path.join(this.memoryDir, "short-term", "goals"),
|
|
94
|
+
path.join(this.memoryDir, "long-term", "lessons", "by-goal"),
|
|
95
|
+
path.join(this.memoryDir, "long-term", "lessons", "by-dimension"),
|
|
96
|
+
path.join(this.memoryDir, "long-term", "statistics"),
|
|
97
|
+
path.join(this.memoryDir, "archive"),
|
|
98
|
+
];
|
|
99
|
+
for (const dir of dirs) {
|
|
100
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
101
|
+
}
|
|
102
|
+
// Initialize index files if they don't exist
|
|
103
|
+
this.initializeIndex("short-term");
|
|
104
|
+
this.initializeIndex("long-term");
|
|
105
|
+
// Initialize global lessons file
|
|
106
|
+
const globalPath = path.join(this.memoryDir, "long-term", "lessons", "global.json");
|
|
107
|
+
if (!fs.existsSync(globalPath)) {
|
|
108
|
+
this.atomicWrite(globalPath, []);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// ─── Short-term Memory ───
|
|
112
|
+
/**
|
|
113
|
+
* Record an entry to short-term memory.
|
|
114
|
+
* Appends to the appropriate data file and updates the short-term index.
|
|
115
|
+
*/
|
|
116
|
+
recordToShortTerm(goalId, dataType, data, options) {
|
|
117
|
+
// Ensure goal directory exists
|
|
118
|
+
const goalDir = path.join(this.memoryDir, "short-term", "goals", goalId);
|
|
119
|
+
fs.mkdirSync(goalDir, { recursive: true });
|
|
120
|
+
const now = new Date().toISOString();
|
|
121
|
+
const entry = ShortTermEntrySchema.parse({
|
|
122
|
+
id: this.generateId("st"),
|
|
123
|
+
goal_id: goalId,
|
|
124
|
+
data_type: dataType,
|
|
125
|
+
loop_number: options?.loopNumber ?? 0,
|
|
126
|
+
timestamp: now,
|
|
127
|
+
dimensions: options?.dimensions ?? [],
|
|
128
|
+
tags: options?.tags ?? [],
|
|
129
|
+
data,
|
|
130
|
+
});
|
|
131
|
+
// Append to appropriate file
|
|
132
|
+
const dataFile = this.getDataFile(goalId, dataType);
|
|
133
|
+
const existing = this.readJsonFile(dataFile, z.array(ShortTermEntrySchema));
|
|
134
|
+
const entries = existing ?? [];
|
|
135
|
+
entries.push(entry);
|
|
136
|
+
this.atomicWrite(dataFile, entries);
|
|
137
|
+
// Update short-term index
|
|
138
|
+
this.updateIndex("short-term", {
|
|
139
|
+
id: this.generateId("idx"),
|
|
140
|
+
goal_id: goalId,
|
|
141
|
+
dimensions: entry.dimensions,
|
|
142
|
+
tags: entry.tags,
|
|
143
|
+
timestamp: entry.timestamp,
|
|
144
|
+
data_file: path.relative(path.join(this.memoryDir, "short-term"), dataFile),
|
|
145
|
+
entry_id: entry.id,
|
|
146
|
+
last_accessed: now,
|
|
147
|
+
access_count: 0,
|
|
148
|
+
embedding_id: null,
|
|
149
|
+
});
|
|
150
|
+
// Phase 2: fire-and-forget embedding indexing
|
|
151
|
+
if (this.vectorIndex) {
|
|
152
|
+
const textToEmbed = `${dataType}: ${JSON.stringify(data).slice(0, 500)}`;
|
|
153
|
+
this.vectorIndex
|
|
154
|
+
.add(entry.id, textToEmbed, { goal_id: goalId, data_type: dataType })
|
|
155
|
+
.then(() => {
|
|
156
|
+
entry.embedding_id = entry.id;
|
|
157
|
+
})
|
|
158
|
+
.catch(() => {
|
|
159
|
+
// Non-fatal: embedding failures are ignored
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return entry;
|
|
163
|
+
}
|
|
164
|
+
// ─── Long-term Compression ───
|
|
165
|
+
/**
|
|
166
|
+
* Compress short-term entries to long-term using LLM-based pattern extraction.
|
|
167
|
+
* Never deletes short-term data if LLM compression fails.
|
|
168
|
+
*/
|
|
169
|
+
async compressToLongTerm(goalId, dataType) {
|
|
170
|
+
const now = new Date().toISOString();
|
|
171
|
+
const dataFile = this.getDataFile(goalId, dataType);
|
|
172
|
+
const allEntries = this.readJsonFile(dataFile, z.array(ShortTermEntrySchema)) ?? [];
|
|
173
|
+
// Determine the retention limit for this goal
|
|
174
|
+
const retentionLimit = this.getRetentionLimit(goalId);
|
|
175
|
+
// Find entries eligible for compression (loop_number exceeds retention limit)
|
|
176
|
+
const maxLoopNumber = allEntries.reduce((max, e) => Math.max(max, e.loop_number), 0);
|
|
177
|
+
const cutoffLoop = maxLoopNumber - retentionLimit;
|
|
178
|
+
const expiredEntries = allEntries.filter((e) => e.loop_number <= cutoffLoop);
|
|
179
|
+
if (expiredEntries.length === 0) {
|
|
180
|
+
return {
|
|
181
|
+
goal_id: goalId,
|
|
182
|
+
data_type: dataType,
|
|
183
|
+
entries_compressed: 0,
|
|
184
|
+
lessons_generated: 0,
|
|
185
|
+
statistics_updated: false,
|
|
186
|
+
quality_check: {
|
|
187
|
+
passed: true,
|
|
188
|
+
failure_coverage_ratio: 1,
|
|
189
|
+
contradictions_found: 0,
|
|
190
|
+
},
|
|
191
|
+
compressed_at: now,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
let lessons = [];
|
|
195
|
+
let qualityCheck = {
|
|
196
|
+
passed: false,
|
|
197
|
+
failure_coverage_ratio: 0,
|
|
198
|
+
contradictions_found: 0,
|
|
199
|
+
};
|
|
200
|
+
try {
|
|
201
|
+
// Step 1: Extract patterns from entries
|
|
202
|
+
const patterns = await this.extractPatterns(expiredEntries);
|
|
203
|
+
// Step 2: Distill lessons from patterns
|
|
204
|
+
const rawLessons = await this.distillLessons(patterns, expiredEntries);
|
|
205
|
+
// Attach metadata to each lesson
|
|
206
|
+
const sourceLoops = expiredEntries.map((e) => `loop_${e.loop_number}`);
|
|
207
|
+
lessons = rawLessons.map((l) => LessonEntrySchema.parse({
|
|
208
|
+
...l,
|
|
209
|
+
lesson_id: this.generateId("lesson"),
|
|
210
|
+
goal_id: goalId,
|
|
211
|
+
source_loops: sourceLoops,
|
|
212
|
+
extracted_at: now,
|
|
213
|
+
status: "active",
|
|
214
|
+
superseded_by: undefined,
|
|
215
|
+
}));
|
|
216
|
+
// Step 3: Quality check
|
|
217
|
+
qualityCheck = this.validateCompressionQuality(lessons, expiredEntries);
|
|
218
|
+
if (!qualityCheck.passed) {
|
|
219
|
+
// Quality check failed — do NOT delete short-term data
|
|
220
|
+
return {
|
|
221
|
+
goal_id: goalId,
|
|
222
|
+
data_type: dataType,
|
|
223
|
+
entries_compressed: 0,
|
|
224
|
+
lessons_generated: 0,
|
|
225
|
+
statistics_updated: false,
|
|
226
|
+
quality_check: {
|
|
227
|
+
passed: false,
|
|
228
|
+
failure_coverage_ratio: qualityCheck.failure_coverage_ratio,
|
|
229
|
+
contradictions_found: qualityCheck.contradictions_found,
|
|
230
|
+
},
|
|
231
|
+
compressed_at: now,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
// Step 4: Store lessons in long-term (by-goal, by-dimension, global)
|
|
235
|
+
this.storeLessonsLongTerm(goalId, lessons, expiredEntries);
|
|
236
|
+
// Phase 2 (5.2c): Auto-register lesson entries in VectorIndex
|
|
237
|
+
if (this.vectorIndex) {
|
|
238
|
+
for (const lesson of lessons) {
|
|
239
|
+
const lessonText = `${lesson.type}: ${lesson.context}. ${lesson.lesson}`;
|
|
240
|
+
this.vectorIndex
|
|
241
|
+
.add(lesson.lesson_id, lessonText, {
|
|
242
|
+
goal_id: goalId,
|
|
243
|
+
is_lesson: true,
|
|
244
|
+
lesson_type: lesson.type,
|
|
245
|
+
})
|
|
246
|
+
.catch(() => {
|
|
247
|
+
// Non-fatal: embedding failures are ignored
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Step 5: Update statistics
|
|
252
|
+
this.updateStatistics(goalId, expiredEntries);
|
|
253
|
+
// Step 6: Purge compressed short-term entries (only if compression succeeded)
|
|
254
|
+
const compressedIds = new Set(expiredEntries.map((e) => e.id));
|
|
255
|
+
const remaining = allEntries.filter((e) => !compressedIds.has(e.id));
|
|
256
|
+
this.atomicWrite(dataFile, remaining);
|
|
257
|
+
// Remove purged entries from the short-term index
|
|
258
|
+
this.removeFromIndex("short-term", compressedIds);
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
// LLM failure — never delete short-term data
|
|
262
|
+
return {
|
|
263
|
+
goal_id: goalId,
|
|
264
|
+
data_type: dataType,
|
|
265
|
+
entries_compressed: 0,
|
|
266
|
+
lessons_generated: 0,
|
|
267
|
+
statistics_updated: false,
|
|
268
|
+
quality_check: {
|
|
269
|
+
passed: false,
|
|
270
|
+
failure_coverage_ratio: 0,
|
|
271
|
+
contradictions_found: 0,
|
|
272
|
+
},
|
|
273
|
+
compressed_at: now,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
goal_id: goalId,
|
|
278
|
+
data_type: dataType,
|
|
279
|
+
entries_compressed: expiredEntries.length,
|
|
280
|
+
lessons_generated: lessons.length,
|
|
281
|
+
statistics_updated: true,
|
|
282
|
+
quality_check: {
|
|
283
|
+
passed: qualityCheck.passed,
|
|
284
|
+
failure_coverage_ratio: qualityCheck.failure_coverage_ratio,
|
|
285
|
+
contradictions_found: qualityCheck.contradictions_found,
|
|
286
|
+
},
|
|
287
|
+
compressed_at: now,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
// ─── Working Memory Selection ───
|
|
291
|
+
/**
|
|
292
|
+
* Select relevant entries for working memory.
|
|
293
|
+
* Phase 1: tag exact-match + recency sort.
|
|
294
|
+
* Phase 2 (5.2b): semantic search fallback via VectorIndex if tag results are insufficient.
|
|
295
|
+
* Phase 2 (5.2c): includes cross-goal lessons (up to 25% of budget).
|
|
296
|
+
*/
|
|
297
|
+
selectForWorkingMemory(goalId, dimensions, tags, maxEntries = 10) {
|
|
298
|
+
// 1. Tag-based query: short-term entries for this goal matching dimensions/tags
|
|
299
|
+
const stIndex = this.loadIndex("short-term");
|
|
300
|
+
const matchingIndexEntries = stIndex.entries.filter((ie) => ie.goal_id === goalId &&
|
|
301
|
+
(dimensions.some((d) => ie.dimensions.includes(d)) ||
|
|
302
|
+
tags.some((t) => ie.tags.includes(t))));
|
|
303
|
+
// Sort by last_accessed descending
|
|
304
|
+
matchingIndexEntries.sort((a, b) => new Date(b.last_accessed).getTime() -
|
|
305
|
+
new Date(a.last_accessed).getTime());
|
|
306
|
+
// Load the actual entries
|
|
307
|
+
const shortTermEntries = [];
|
|
308
|
+
const seenEntryIds = new Set();
|
|
309
|
+
for (const idxEntry of matchingIndexEntries) {
|
|
310
|
+
if (shortTermEntries.length >= maxEntries)
|
|
311
|
+
break;
|
|
312
|
+
if (seenEntryIds.has(idxEntry.entry_id))
|
|
313
|
+
continue;
|
|
314
|
+
const dataFilePath = path.join(this.memoryDir, "short-term", idxEntry.data_file);
|
|
315
|
+
const allEntries = this.readJsonFile(dataFilePath, z.array(ShortTermEntrySchema)) ?? [];
|
|
316
|
+
const found = allEntries.find((e) => e.id === idxEntry.entry_id);
|
|
317
|
+
if (found) {
|
|
318
|
+
shortTermEntries.push(found);
|
|
319
|
+
seenEntryIds.add(idxEntry.entry_id);
|
|
320
|
+
// Update access metadata in index
|
|
321
|
+
this.touchIndexEntry("short-term", idxEntry.id);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Phase 2 (5.2b): If results are fewer than needed and VectorIndex available, do sync lookup
|
|
325
|
+
// Note: selectForWorkingMemory is sync — semantic search via vectorIndex happens in
|
|
326
|
+
// selectForWorkingMemorySemantic (async). Here we merge from the index directly.
|
|
327
|
+
if (shortTermEntries.length < maxEntries && this.vectorIndex) {
|
|
328
|
+
// Pull all goal entries from the short-term index (not yet in result set) as semantic candidates
|
|
329
|
+
const remaining = stIndex.entries.filter((ie) => ie.goal_id === goalId && !seenEntryIds.has(ie.entry_id));
|
|
330
|
+
// Sort by access count + recency as a proxy
|
|
331
|
+
remaining.sort((a, b) => b.access_count - a.access_count ||
|
|
332
|
+
new Date(b.last_accessed).getTime() - new Date(a.last_accessed).getTime());
|
|
333
|
+
for (const idxEntry of remaining) {
|
|
334
|
+
if (shortTermEntries.length >= maxEntries)
|
|
335
|
+
break;
|
|
336
|
+
if (seenEntryIds.has(idxEntry.entry_id))
|
|
337
|
+
continue;
|
|
338
|
+
const dataFilePath = path.join(this.memoryDir, "short-term", idxEntry.data_file);
|
|
339
|
+
const allEntries = this.readJsonFile(dataFilePath, z.array(ShortTermEntrySchema)) ?? [];
|
|
340
|
+
const found = allEntries.find((e) => e.id === idxEntry.entry_id);
|
|
341
|
+
if (found) {
|
|
342
|
+
shortTermEntries.push(found);
|
|
343
|
+
seenEntryIds.add(idxEntry.entry_id);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Re-sort by relevanceScore if driveScorer is available
|
|
347
|
+
if (this.driveScorer) {
|
|
348
|
+
shortTermEntries.sort((a, b) => this.relevanceScore(b, { goalId, dimensions, tags }) -
|
|
349
|
+
this.relevanceScore(a, { goalId, dimensions, tags }));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
// 2. Query long-term lessons matching tags (cross-goal OK for lessons)
|
|
353
|
+
const goalLessons = this.queryLessons(tags, dimensions, Math.ceil(maxEntries * 0.75));
|
|
354
|
+
// Phase 2 (5.2c): Include cross-goal lessons (up to 25% of budget)
|
|
355
|
+
const crossGoalBudget = Math.max(1, Math.floor(maxEntries * 0.25));
|
|
356
|
+
const crossGoalLessons = this.queryCrossGoalLessons(tags, dimensions, goalId, crossGoalBudget);
|
|
357
|
+
// Deduplicate cross-goal lessons against goal lessons
|
|
358
|
+
const seenLessonIds = new Set(goalLessons.map((l) => l.lesson_id));
|
|
359
|
+
const dedupedCrossGoal = crossGoalLessons.filter((l) => !seenLessonIds.has(l.lesson_id));
|
|
360
|
+
const lessons = [...goalLessons, ...dedupedCrossGoal];
|
|
361
|
+
return { shortTerm: shortTermEntries, lessons };
|
|
362
|
+
}
|
|
363
|
+
// ─── Phase 2: Drive-based Memory Management ───
|
|
364
|
+
/**
|
|
365
|
+
* Dissatisfaction drive: delay compression up to 2x for high-dissatisfaction dimensions.
|
|
366
|
+
* For each dimension, if dissatisfaction > 0.7, delay_factor = 1 + dissatisfaction (max 2.0).
|
|
367
|
+
* Returns map of dimension -> delay_factor.
|
|
368
|
+
*/
|
|
369
|
+
getCompressionDelay(driveScores) {
|
|
370
|
+
const result = new Map();
|
|
371
|
+
for (const { dimension, dissatisfaction } of driveScores) {
|
|
372
|
+
if (dissatisfaction > 0.7) {
|
|
373
|
+
const delayFactor = Math.min(2.0, 1 + dissatisfaction);
|
|
374
|
+
result.set(dimension, delayFactor);
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
result.set(dimension, 1.0);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return result;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Deadline drive: boost Working Memory priority up to 30%.
|
|
384
|
+
* For each dimension, bonus = min(deadline * 0.3, 0.3).
|
|
385
|
+
* Returns map of dimension -> bonus_factor.
|
|
386
|
+
*/
|
|
387
|
+
getDeadlineBonus(driveScores) {
|
|
388
|
+
const result = new Map();
|
|
389
|
+
for (const { dimension, deadline } of driveScores) {
|
|
390
|
+
result.set(dimension, Math.min(deadline * 0.3, 0.3));
|
|
391
|
+
}
|
|
392
|
+
return result;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* SatisficingJudge hook: mark satisfied dimensions for early compression.
|
|
396
|
+
* Records these dimensions as candidates for early compression.
|
|
397
|
+
*/
|
|
398
|
+
markForEarlyCompression(goalId, satisfiedDimensions) {
|
|
399
|
+
if (!this.earlyCompressionCandidates.has(goalId)) {
|
|
400
|
+
this.earlyCompressionCandidates.set(goalId, new Set());
|
|
401
|
+
}
|
|
402
|
+
const candidates = this.earlyCompressionCandidates.get(goalId);
|
|
403
|
+
for (const dim of satisfiedDimensions) {
|
|
404
|
+
candidates.add(dim);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Return the set of dimensions marked for early compression for a goal.
|
|
409
|
+
*/
|
|
410
|
+
getEarlyCompressionCandidates(goalId) {
|
|
411
|
+
return this.earlyCompressionCandidates.get(goalId) ?? new Set();
|
|
412
|
+
}
|
|
413
|
+
// ─── Phase 2 (5.2a): Drive-scorer-aware helpers ───
|
|
414
|
+
/**
|
|
415
|
+
* Compute a relevance score for a short-term entry given a context.
|
|
416
|
+
*
|
|
417
|
+
* Score = tag_match_ratio * drive_weight * freshness_factor
|
|
418
|
+
* - tag_match_ratio = matching tags / total unique tags (0 if no tags)
|
|
419
|
+
* - drive_weight = DriveScorer dissatisfaction score for first matching
|
|
420
|
+
* dimension (1.0 if no DriveScorer or no dimensions)
|
|
421
|
+
* - freshness_factor = Math.exp(-daysSinceCreation / 30)
|
|
422
|
+
*/
|
|
423
|
+
relevanceScore(entry, context) {
|
|
424
|
+
// 1. Tag match ratio
|
|
425
|
+
const allTags = new Set([...entry.tags, ...context.tags]);
|
|
426
|
+
const matchingTags = entry.tags.filter((t) => context.tags.includes(t)).length;
|
|
427
|
+
const tagMatchRatio = allTags.size > 0 ? matchingTags / allTags.size : 0;
|
|
428
|
+
// 2. Drive weight
|
|
429
|
+
let driveWeight = 1.0;
|
|
430
|
+
if (this.driveScorer) {
|
|
431
|
+
// Use the first dimension that matches entry dimensions or context dimensions
|
|
432
|
+
const relevantDimensions = entry.dimensions.length > 0
|
|
433
|
+
? entry.dimensions
|
|
434
|
+
: context.dimensions;
|
|
435
|
+
if (relevantDimensions.length > 0) {
|
|
436
|
+
const dim = relevantDimensions[0];
|
|
437
|
+
driveWeight = this.driveScorer.getDissatisfactionScore(dim);
|
|
438
|
+
// Clamp to [0.1, 2]: floor at 0.1 so satisfied dimensions don't zero out tag-perfect matches
|
|
439
|
+
driveWeight = Math.max(0.1, driveWeight);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
// 3. Freshness factor (exponential decay over 30 days)
|
|
443
|
+
const createdAt = new Date(entry.timestamp).getTime();
|
|
444
|
+
const daysSinceCreation = (Date.now() - createdAt) / (1000 * 60 * 60 * 24);
|
|
445
|
+
const freshnessFactor = Math.exp(-daysSinceCreation / 30);
|
|
446
|
+
return tagMatchRatio * driveWeight * freshnessFactor;
|
|
447
|
+
}
|
|
448
|
+
/**
|
|
449
|
+
* Compute the effective retention period for a goal/dimension combination.
|
|
450
|
+
*
|
|
451
|
+
* If DriveScorer is available:
|
|
452
|
+
* dissatisfaction > 0.7 → retention_period * 2.0
|
|
453
|
+
* dissatisfaction > 0.4 → retention_period * 1.5
|
|
454
|
+
* otherwise → retention_period
|
|
455
|
+
* If no DriveScorer → retention_period (unchanged).
|
|
456
|
+
*/
|
|
457
|
+
compressionDelay(goalId, dimension) {
|
|
458
|
+
const retentionPeriod = this.getRetentionLimit(goalId);
|
|
459
|
+
if (!this.driveScorer) {
|
|
460
|
+
return retentionPeriod;
|
|
461
|
+
}
|
|
462
|
+
const dissatisfaction = this.driveScorer.getDissatisfactionScore(dimension);
|
|
463
|
+
if (dissatisfaction > 0.7) {
|
|
464
|
+
return retentionPeriod * 2.0;
|
|
465
|
+
}
|
|
466
|
+
else if (dissatisfaction > 0.4) {
|
|
467
|
+
return retentionPeriod * 1.5;
|
|
468
|
+
}
|
|
469
|
+
return retentionPeriod;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Hook called when the SatisficingJudge determines a dimension is satisfied.
|
|
473
|
+
* Marks the dimension for early compression if satisfied, clears the mark if not.
|
|
474
|
+
*/
|
|
475
|
+
onSatisficingJudgment(goalId, dimension, isSatisfied) {
|
|
476
|
+
if (isSatisfied) {
|
|
477
|
+
// Mark dimension for early compression
|
|
478
|
+
if (!this.earlyCompressionCandidates.has(goalId)) {
|
|
479
|
+
this.earlyCompressionCandidates.set(goalId, new Set());
|
|
480
|
+
}
|
|
481
|
+
this.earlyCompressionCandidates.get(goalId).add(dimension);
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
// Remove from early compression candidates if previously marked
|
|
485
|
+
const candidates = this.earlyCompressionCandidates.get(goalId);
|
|
486
|
+
if (candidates) {
|
|
487
|
+
candidates.delete(dimension);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
// ─── Phase 2 (5.2c): Cross-Goal Lesson Search ───
|
|
492
|
+
/**
|
|
493
|
+
* Search long-term lessons across ALL goals using semantic search.
|
|
494
|
+
* Falls back to tag-based global search if VectorIndex is unavailable.
|
|
495
|
+
*
|
|
496
|
+
* @param query - natural language search query
|
|
497
|
+
* @param topK - maximum number of lessons to return (default 5)
|
|
498
|
+
*/
|
|
499
|
+
async searchCrossGoalLessons(query, topK = 5) {
|
|
500
|
+
if (this.vectorIndex) {
|
|
501
|
+
// Semantic search in vector index
|
|
502
|
+
const results = await this.vectorIndex.search(query, topK * 2, 0.0);
|
|
503
|
+
// Filter to lesson entries (metadata.is_lesson === true)
|
|
504
|
+
const lessonResults = results.filter((r) => r.metadata.is_lesson === true);
|
|
505
|
+
// Load actual lessons from global file
|
|
506
|
+
const globalPath = path.join(this.memoryDir, "long-term", "lessons", "global.json");
|
|
507
|
+
const globalLessons = this.readJsonFile(globalPath, z.array(LessonEntrySchema)) ?? [];
|
|
508
|
+
const lessonMap = new Map(globalLessons.map((l) => [l.lesson_id, l]));
|
|
509
|
+
const matched = [];
|
|
510
|
+
for (const r of lessonResults) {
|
|
511
|
+
const lesson = lessonMap.get(r.id);
|
|
512
|
+
if (lesson && lesson.status === "active") {
|
|
513
|
+
matched.push(lesson);
|
|
514
|
+
if (matched.length >= topK)
|
|
515
|
+
break;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
// If we got enough results from semantic search, return them
|
|
519
|
+
if (matched.length > 0) {
|
|
520
|
+
return matched;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
// Fallback: tag-based global search
|
|
524
|
+
const globalPath = path.join(this.memoryDir, "long-term", "lessons", "global.json");
|
|
525
|
+
const globalLessons = this.readJsonFile(globalPath, z.array(LessonEntrySchema)) ?? [];
|
|
526
|
+
// Simple text match on lesson content
|
|
527
|
+
const queryLower = query.toLowerCase();
|
|
528
|
+
const matching = globalLessons.filter((l) => l.status === "active" &&
|
|
529
|
+
(l.lesson.toLowerCase().includes(queryLower) ||
|
|
530
|
+
l.context.toLowerCase().includes(queryLower) ||
|
|
531
|
+
l.relevance_tags.some((t) => t.toLowerCase().includes(queryLower))));
|
|
532
|
+
// Sort by recency
|
|
533
|
+
matching.sort((a, b) => new Date(b.extracted_at).getTime() - new Date(a.extracted_at).getTime());
|
|
534
|
+
return matching.slice(0, topK);
|
|
535
|
+
}
|
|
536
|
+
// ─── Phase 2: Semantic Working Memory Selection ───
|
|
537
|
+
/**
|
|
538
|
+
* Semantic variant of selectForWorkingMemory.
|
|
539
|
+
* Uses VectorIndex.search() to find semantically relevant entries.
|
|
540
|
+
* Applies deadline bonus to relevance scores.
|
|
541
|
+
* Falls back to existing sync method if no vectorIndex available.
|
|
542
|
+
*/
|
|
543
|
+
async selectForWorkingMemorySemantic(goalId, query, dimensions, tags, maxEntries = 10, driveScores) {
|
|
544
|
+
// Fall back to sync method if no vectorIndex
|
|
545
|
+
if (!this.vectorIndex) {
|
|
546
|
+
return this.selectForWorkingMemory(goalId, dimensions, tags, maxEntries);
|
|
547
|
+
}
|
|
548
|
+
// Compute deadline bonuses per dimension
|
|
549
|
+
const deadlineBonus = driveScores
|
|
550
|
+
? this.getDeadlineBonus(driveScores.map((d) => ({ dimension: d.dimension, deadline: d.deadline })))
|
|
551
|
+
: new Map();
|
|
552
|
+
const maxBonus = deadlineBonus.size > 0
|
|
553
|
+
? Math.max(...Array.from(deadlineBonus.values()))
|
|
554
|
+
: 0;
|
|
555
|
+
// Search vector index for semantically similar entries
|
|
556
|
+
const searchResults = await this.vectorIndex.search(query, maxEntries * 2, 0.0);
|
|
557
|
+
// Filter to this goal's entries
|
|
558
|
+
const goalResults = searchResults.filter((r) => r.metadata.goal_id === goalId);
|
|
559
|
+
// Load short-term index for recency data
|
|
560
|
+
const stIndex = this.loadIndex("short-term");
|
|
561
|
+
const indexEntryMap = new Map(stIndex.entries.map((ie) => [ie.entry_id, ie]));
|
|
562
|
+
// Score entries by combining semantic score + recency + deadline bonus
|
|
563
|
+
const now = Date.now();
|
|
564
|
+
const scoredEntries = [];
|
|
565
|
+
const seenEntryIds = new Set();
|
|
566
|
+
for (const result of goalResults) {
|
|
567
|
+
if (seenEntryIds.has(result.id))
|
|
568
|
+
continue;
|
|
569
|
+
const idxEntry = indexEntryMap.get(result.id);
|
|
570
|
+
if (!idxEntry)
|
|
571
|
+
continue;
|
|
572
|
+
// Compute recency score: normalize last_accessed relative to now
|
|
573
|
+
const ageMs = now - new Date(idxEntry.last_accessed).getTime();
|
|
574
|
+
const ageHours = ageMs / (1000 * 60 * 60);
|
|
575
|
+
const recencyScore = Math.max(0, 1 - ageHours / (24 * 7)); // decay over 1 week
|
|
576
|
+
const combinedScore = result.similarity + recencyScore * 0.3 + maxBonus;
|
|
577
|
+
// Load the actual entry from disk
|
|
578
|
+
const dataFilePath = path.join(this.memoryDir, "short-term", idxEntry.data_file);
|
|
579
|
+
const allEntries = this.readJsonFile(dataFilePath, z.array(ShortTermEntrySchema)) ?? [];
|
|
580
|
+
const found = allEntries.find((e) => e.id === idxEntry.entry_id);
|
|
581
|
+
if (found) {
|
|
582
|
+
scoredEntries.push({ entry: found, combinedScore });
|
|
583
|
+
seenEntryIds.add(result.id);
|
|
584
|
+
this.touchIndexEntry("short-term", idxEntry.id);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
// Sort by combined score descending and take top maxEntries
|
|
588
|
+
scoredEntries.sort((a, b) => b.combinedScore - a.combinedScore);
|
|
589
|
+
const shortTermEntries = scoredEntries
|
|
590
|
+
.slice(0, maxEntries)
|
|
591
|
+
.map((s) => s.entry);
|
|
592
|
+
// Still use tag/dimension-based lesson query for long-term
|
|
593
|
+
const lessons = this.queryLessons(tags, dimensions, maxEntries);
|
|
594
|
+
return { shortTerm: shortTermEntries, lessons };
|
|
595
|
+
}
|
|
596
|
+
// ─── Retention Policy ───
|
|
597
|
+
/**
|
|
598
|
+
* Apply retention policy — check each data type and trigger compression if needed.
|
|
599
|
+
* Phase 2 (5.2a): uses compressionDelay() per dimension for drive-based retention.
|
|
600
|
+
*/
|
|
601
|
+
async applyRetentionPolicy(goalId) {
|
|
602
|
+
const dataTypes = [
|
|
603
|
+
"experience_log",
|
|
604
|
+
"observation",
|
|
605
|
+
"strategy",
|
|
606
|
+
"task",
|
|
607
|
+
"knowledge",
|
|
608
|
+
];
|
|
609
|
+
const results = [];
|
|
610
|
+
for (const dataType of dataTypes) {
|
|
611
|
+
const dataFile = this.getDataFile(goalId, dataType);
|
|
612
|
+
if (!fs.existsSync(dataFile))
|
|
613
|
+
continue;
|
|
614
|
+
const entries = this.readJsonFile(dataFile, z.array(ShortTermEntrySchema)) ?? [];
|
|
615
|
+
if (entries.length === 0)
|
|
616
|
+
continue;
|
|
617
|
+
const maxLoopNumber = entries.reduce((max, e) => Math.max(max, e.loop_number), 0);
|
|
618
|
+
const minLoopNumber = entries.reduce((min, e) => Math.min(min, e.loop_number), Infinity);
|
|
619
|
+
// Phase 2 (5.2a): compute effective retention limit using drive-based delay.
|
|
620
|
+
// Use the dimensions present in the entries to find the most conservative (highest) delay.
|
|
621
|
+
const allDimensions = [...new Set(entries.flatMap((e) => e.dimensions))];
|
|
622
|
+
let effectiveRetentionLimit;
|
|
623
|
+
if (allDimensions.length > 0 && this.driveScorer) {
|
|
624
|
+
// Take the maximum delay across all dimensions (most conservative = longest retention)
|
|
625
|
+
effectiveRetentionLimit = Math.max(...allDimensions.map((dim) => this.compressionDelay(goalId, dim)));
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
effectiveRetentionLimit = this.getRetentionLimit(goalId);
|
|
629
|
+
}
|
|
630
|
+
// Check for early compression candidates — reduce retention limit if any dimension is satisfied
|
|
631
|
+
const earlyDims = this.earlyCompressionCandidates.get(goalId);
|
|
632
|
+
if (earlyDims && allDimensions.some(d => earlyDims.has(d))) {
|
|
633
|
+
effectiveRetentionLimit = Math.min(effectiveRetentionLimit, Math.floor(this.getRetentionLimit(goalId) * 0.5));
|
|
634
|
+
}
|
|
635
|
+
// Trigger compression if span of loops exceeds effective retention limit
|
|
636
|
+
if (maxLoopNumber - minLoopNumber >= effectiveRetentionLimit) {
|
|
637
|
+
const result = await this.compressToLongTerm(goalId, dataType);
|
|
638
|
+
results.push(result);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
return results;
|
|
642
|
+
}
|
|
643
|
+
// ─── Goal Close ───
|
|
644
|
+
/**
|
|
645
|
+
* Handle goal completion or cancellation.
|
|
646
|
+
* Compresses all remaining short-term data, then archives.
|
|
647
|
+
*/
|
|
648
|
+
async onGoalClose(goalId, reason) {
|
|
649
|
+
const dataTypes = [
|
|
650
|
+
"experience_log",
|
|
651
|
+
"observation",
|
|
652
|
+
"strategy",
|
|
653
|
+
"task",
|
|
654
|
+
"knowledge",
|
|
655
|
+
];
|
|
656
|
+
// Step 1: Compress all remaining short-term data (best-effort)
|
|
657
|
+
for (const dataType of dataTypes) {
|
|
658
|
+
const dataFile = this.getDataFile(goalId, dataType);
|
|
659
|
+
if (!fs.existsSync(dataFile))
|
|
660
|
+
continue;
|
|
661
|
+
const entries = this.readJsonFile(dataFile, z.array(ShortTermEntrySchema)) ?? [];
|
|
662
|
+
if (entries.length === 0)
|
|
663
|
+
continue;
|
|
664
|
+
try {
|
|
665
|
+
// Force-compress all remaining entries regardless of loop count
|
|
666
|
+
await this.compressAllRemainingToLongTerm(goalId, dataType, entries);
|
|
667
|
+
}
|
|
668
|
+
catch {
|
|
669
|
+
// Failure is acceptable on close — proceed to archive anyway
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
// Step 2: Archive short-term data directory
|
|
673
|
+
const goalShortTermDir = path.join(this.memoryDir, "short-term", "goals", goalId);
|
|
674
|
+
const archiveGoalDir = path.join(this.memoryDir, "archive", goalId);
|
|
675
|
+
if (fs.existsSync(goalShortTermDir)) {
|
|
676
|
+
fs.mkdirSync(archiveGoalDir, { recursive: true });
|
|
677
|
+
// Archive all files from the short-term goal directory
|
|
678
|
+
const files = fs.readdirSync(goalShortTermDir);
|
|
679
|
+
for (const file of files) {
|
|
680
|
+
const srcPath = path.join(goalShortTermDir, file);
|
|
681
|
+
const destPath = path.join(archiveGoalDir, file);
|
|
682
|
+
fs.copyFileSync(srcPath, destPath);
|
|
683
|
+
}
|
|
684
|
+
// Remove from short-term
|
|
685
|
+
fs.rmSync(goalShortTermDir, { recursive: true, force: true });
|
|
686
|
+
// Remove goal's entries from short-term index
|
|
687
|
+
this.removeGoalFromIndex("short-term", goalId);
|
|
688
|
+
}
|
|
689
|
+
// Step 3: Archive long-term data (lessons + statistics) for this goal
|
|
690
|
+
const byGoalLessonsPath = path.join(this.memoryDir, "long-term", "lessons", "by-goal", `${goalId}.json`);
|
|
691
|
+
const statisticsPath = path.join(this.memoryDir, "long-term", "statistics", `${goalId}.json`);
|
|
692
|
+
if (fs.existsSync(byGoalLessonsPath)) {
|
|
693
|
+
fs.mkdirSync(archiveGoalDir, { recursive: true });
|
|
694
|
+
const archiveLessonsPath = path.join(archiveGoalDir, "lessons.json");
|
|
695
|
+
const existingArchive = this.readJsonFile(archiveLessonsPath, z.array(LessonEntrySchema)) ?? [];
|
|
696
|
+
const goalLessons = this.readJsonFile(byGoalLessonsPath, z.array(LessonEntrySchema)) ?? [];
|
|
697
|
+
this.atomicWrite(archiveLessonsPath, [
|
|
698
|
+
...existingArchive,
|
|
699
|
+
...goalLessons,
|
|
700
|
+
]);
|
|
701
|
+
}
|
|
702
|
+
if (fs.existsSync(statisticsPath)) {
|
|
703
|
+
fs.mkdirSync(archiveGoalDir, { recursive: true });
|
|
704
|
+
const archiveStatsPath = path.join(archiveGoalDir, "statistics.json");
|
|
705
|
+
const stats = this.readJsonFile(statisticsPath, StatisticalSummarySchema);
|
|
706
|
+
if (stats) {
|
|
707
|
+
this.atomicWrite(archiveStatsPath, stats);
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
// Step 4: Mark all goal lessons as archived in long-term
|
|
711
|
+
if (fs.existsSync(byGoalLessonsPath)) {
|
|
712
|
+
const lessons = this.readJsonFile(byGoalLessonsPath, z.array(LessonEntrySchema)) ?? [];
|
|
713
|
+
const archived = lessons.map((l) => LessonEntrySchema.parse({ ...l, status: "archived" }));
|
|
714
|
+
this.atomicWrite(byGoalLessonsPath, archived);
|
|
715
|
+
}
|
|
716
|
+
void reason; // used for potential future audit logging
|
|
717
|
+
}
|
|
718
|
+
// ─── Statistics ───
|
|
719
|
+
/**
|
|
720
|
+
* Read and return the statistical summary for a goal.
|
|
721
|
+
*/
|
|
722
|
+
getStatistics(goalId) {
|
|
723
|
+
const statsPath = path.join(this.memoryDir, "long-term", "statistics", `${goalId}.json`);
|
|
724
|
+
return this.readJsonFile(statsPath, StatisticalSummarySchema);
|
|
725
|
+
}
|
|
726
|
+
// ─── Garbage Collection ───
|
|
727
|
+
/**
|
|
728
|
+
* Run garbage collection to enforce size limits.
|
|
729
|
+
* Short-term: 10MB per goal (default). Long-term: 100MB total (default).
|
|
730
|
+
*/
|
|
731
|
+
async runGarbageCollection() {
|
|
732
|
+
const shortTermGoalsDir = path.join(this.memoryDir, "short-term", "goals");
|
|
733
|
+
if (!fs.existsSync(shortTermGoalsDir))
|
|
734
|
+
return;
|
|
735
|
+
const goalDirs = fs
|
|
736
|
+
.readdirSync(shortTermGoalsDir, { withFileTypes: true })
|
|
737
|
+
.filter((d) => d.isDirectory())
|
|
738
|
+
.map((d) => d.name);
|
|
739
|
+
const shortTermLimitBytes = this.config.size_limits.short_term_per_goal_mb * 1024 * 1024;
|
|
740
|
+
// Check short-term size per goal
|
|
741
|
+
for (const goalId of goalDirs) {
|
|
742
|
+
const goalDir = path.join(shortTermGoalsDir, goalId);
|
|
743
|
+
const size = this.getDirectorySize(goalDir);
|
|
744
|
+
if (size > shortTermLimitBytes) {
|
|
745
|
+
// Trigger early compression for all data types
|
|
746
|
+
const dataTypes = [
|
|
747
|
+
"experience_log",
|
|
748
|
+
"observation",
|
|
749
|
+
"strategy",
|
|
750
|
+
"task",
|
|
751
|
+
"knowledge",
|
|
752
|
+
];
|
|
753
|
+
for (const dataType of dataTypes) {
|
|
754
|
+
try {
|
|
755
|
+
await this.compressToLongTerm(goalId, dataType);
|
|
756
|
+
}
|
|
757
|
+
catch {
|
|
758
|
+
// Compression failure is non-fatal for GC
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
// Check long-term total size
|
|
764
|
+
const longTermDir = path.join(this.memoryDir, "long-term");
|
|
765
|
+
if (fs.existsSync(longTermDir)) {
|
|
766
|
+
const longTermSize = this.getDirectorySize(longTermDir);
|
|
767
|
+
const longTermLimitBytes = this.config.size_limits.long_term_total_mb * 1024 * 1024;
|
|
768
|
+
if (longTermSize > longTermLimitBytes) {
|
|
769
|
+
// Archive oldest (by last_accessed) lessons from long-term index
|
|
770
|
+
this.archiveOldestLongTermEntries();
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
// ─── Private: Index Management ───
|
|
775
|
+
initializeIndex(layer) {
|
|
776
|
+
const indexPath = path.join(this.memoryDir, layer, "index.json");
|
|
777
|
+
if (!fs.existsSync(indexPath)) {
|
|
778
|
+
const emptyIndex = MemoryIndexSchema.parse({
|
|
779
|
+
version: 1,
|
|
780
|
+
last_updated: new Date().toISOString(),
|
|
781
|
+
entries: [],
|
|
782
|
+
});
|
|
783
|
+
fs.mkdirSync(path.dirname(indexPath), { recursive: true });
|
|
784
|
+
this.atomicWrite(indexPath, emptyIndex);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
loadIndex(layer) {
|
|
788
|
+
const indexPath = path.join(this.memoryDir, layer, "index.json");
|
|
789
|
+
const raw = this.readJsonFile(indexPath, MemoryIndexSchema);
|
|
790
|
+
if (raw === null) {
|
|
791
|
+
return MemoryIndexSchema.parse({
|
|
792
|
+
version: 1,
|
|
793
|
+
last_updated: new Date().toISOString(),
|
|
794
|
+
entries: [],
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
return raw;
|
|
798
|
+
}
|
|
799
|
+
saveIndex(layer, index) {
|
|
800
|
+
const indexPath = path.join(this.memoryDir, layer, "index.json");
|
|
801
|
+
fs.mkdirSync(path.dirname(indexPath), { recursive: true });
|
|
802
|
+
const updated = MemoryIndexSchema.parse({
|
|
803
|
+
...index,
|
|
804
|
+
last_updated: new Date().toISOString(),
|
|
805
|
+
});
|
|
806
|
+
this.atomicWrite(indexPath, updated);
|
|
807
|
+
}
|
|
808
|
+
updateIndex(layer, entry) {
|
|
809
|
+
const index = this.loadIndex(layer);
|
|
810
|
+
index.entries.push(entry);
|
|
811
|
+
this.saveIndex(layer, index);
|
|
812
|
+
}
|
|
813
|
+
removeFromIndex(layer, entryIds) {
|
|
814
|
+
const index = this.loadIndex(layer);
|
|
815
|
+
index.entries = index.entries.filter((ie) => !entryIds.has(ie.entry_id));
|
|
816
|
+
this.saveIndex(layer, index);
|
|
817
|
+
}
|
|
818
|
+
removeGoalFromIndex(layer, goalId) {
|
|
819
|
+
const index = this.loadIndex(layer);
|
|
820
|
+
index.entries = index.entries.filter((ie) => ie.goal_id !== goalId);
|
|
821
|
+
this.saveIndex(layer, index);
|
|
822
|
+
}
|
|
823
|
+
touchIndexEntry(layer, indexId) {
|
|
824
|
+
const index = this.loadIndex(layer);
|
|
825
|
+
const now = new Date().toISOString();
|
|
826
|
+
const updated = index.entries.map((ie) => {
|
|
827
|
+
if (ie.id === indexId) {
|
|
828
|
+
return { ...ie, last_accessed: now, access_count: ie.access_count + 1 };
|
|
829
|
+
}
|
|
830
|
+
return ie;
|
|
831
|
+
});
|
|
832
|
+
this.saveIndex(layer, { ...index, entries: updated });
|
|
833
|
+
}
|
|
834
|
+
archiveOldestLongTermEntries() {
|
|
835
|
+
const index = this.loadIndex("long-term");
|
|
836
|
+
// Sort by last_accessed ascending (oldest first)
|
|
837
|
+
const sorted = [...index.entries].sort((a, b) => new Date(a.last_accessed).getTime() -
|
|
838
|
+
new Date(b.last_accessed).getTime());
|
|
839
|
+
// Archive oldest 10% of entries
|
|
840
|
+
const archiveCount = Math.max(1, Math.floor(sorted.length * 0.1));
|
|
841
|
+
const toArchive = sorted.slice(0, archiveCount);
|
|
842
|
+
const toArchiveIds = new Set(toArchive.map((ie) => ie.entry_id));
|
|
843
|
+
// Remove from active index
|
|
844
|
+
index.entries = index.entries.filter((ie) => !toArchiveIds.has(ie.entry_id));
|
|
845
|
+
this.saveIndex("long-term", index);
|
|
846
|
+
}
|
|
847
|
+
// ─── Private: Lesson Storage ───
|
|
848
|
+
storeLessonsLongTerm(goalId, lessons, sourceEntries) {
|
|
849
|
+
// 1. Store by-goal
|
|
850
|
+
const byGoalPath = path.join(this.memoryDir, "long-term", "lessons", "by-goal", `${goalId}.json`);
|
|
851
|
+
const existingByGoal = this.readJsonFile(byGoalPath, z.array(LessonEntrySchema)) ??
|
|
852
|
+
[];
|
|
853
|
+
this.atomicWrite(byGoalPath, [...existingByGoal, ...lessons]);
|
|
854
|
+
// 2. Store by-dimension (for each unique dimension in source entries)
|
|
855
|
+
const allDimensions = new Set(sourceEntries.flatMap((e) => e.dimensions));
|
|
856
|
+
for (const dim of allDimensions) {
|
|
857
|
+
if (!dim)
|
|
858
|
+
continue;
|
|
859
|
+
const byDimPath = path.join(this.memoryDir, "long-term", "lessons", "by-dimension", `${dim}.json`);
|
|
860
|
+
const existingByDim = this.readJsonFile(byDimPath, z.array(LessonEntrySchema)) ??
|
|
861
|
+
[];
|
|
862
|
+
// Store lessons that have this dimension's tag or are from these source entries
|
|
863
|
+
const relevantLessons = lessons.filter((l) => l.relevance_tags.includes(dim) ||
|
|
864
|
+
l.relevance_tags.length === 0 // include all if no tags
|
|
865
|
+
);
|
|
866
|
+
if (relevantLessons.length > 0) {
|
|
867
|
+
this.atomicWrite(byDimPath, [...existingByDim, ...relevantLessons]);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
// 3. Store in global (all lessons are cross-goal knowledge)
|
|
871
|
+
const globalPath = path.join(this.memoryDir, "long-term", "lessons", "global.json");
|
|
872
|
+
const existingGlobal = this.readJsonFile(globalPath, z.array(LessonEntrySchema)) ?? [];
|
|
873
|
+
this.atomicWrite(globalPath, [...existingGlobal, ...lessons]);
|
|
874
|
+
// 4. Update long-term index
|
|
875
|
+
const now = new Date().toISOString();
|
|
876
|
+
for (const lesson of lessons) {
|
|
877
|
+
this.updateIndex("long-term", {
|
|
878
|
+
id: this.generateId("ltidx"),
|
|
879
|
+
goal_id: goalId,
|
|
880
|
+
dimensions: sourceEntries
|
|
881
|
+
.filter((e) => lesson.source_loops.includes(`loop_${e.loop_number}`))
|
|
882
|
+
.flatMap((e) => e.dimensions),
|
|
883
|
+
tags: lesson.relevance_tags,
|
|
884
|
+
timestamp: lesson.extracted_at,
|
|
885
|
+
data_file: path.join("lessons", "by-goal", `${goalId}.json`),
|
|
886
|
+
entry_id: lesson.lesson_id,
|
|
887
|
+
last_accessed: now,
|
|
888
|
+
access_count: 0,
|
|
889
|
+
embedding_id: null,
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
// ─── Private: Statistics ───
|
|
894
|
+
updateStatistics(goalId, entries) {
|
|
895
|
+
const statsPath = path.join(this.memoryDir, "long-term", "statistics", `${goalId}.json`);
|
|
896
|
+
const now = new Date().toISOString();
|
|
897
|
+
// Load existing or create fresh
|
|
898
|
+
const existing = this.readJsonFile(statsPath, StatisticalSummarySchema);
|
|
899
|
+
// Compute task statistics from task entries
|
|
900
|
+
const taskEntries = entries.filter((e) => e.data_type === "task");
|
|
901
|
+
const taskCategoryMap = new Map();
|
|
902
|
+
for (const entry of taskEntries) {
|
|
903
|
+
const category = typeof entry.data["task_category"] === "string"
|
|
904
|
+
? entry.data["task_category"]
|
|
905
|
+
: "unknown";
|
|
906
|
+
const status = typeof entry.data["status"] === "string" ? entry.data["status"] : "";
|
|
907
|
+
const durationHours = typeof entry.data["duration_hours"] === "number"
|
|
908
|
+
? entry.data["duration_hours"]
|
|
909
|
+
: 0;
|
|
910
|
+
const current = taskCategoryMap.get(category) ?? {
|
|
911
|
+
total: 0,
|
|
912
|
+
success: 0,
|
|
913
|
+
durations: [],
|
|
914
|
+
};
|
|
915
|
+
current.total++;
|
|
916
|
+
if (status === "completed")
|
|
917
|
+
current.success++;
|
|
918
|
+
if (durationHours > 0)
|
|
919
|
+
current.durations.push(durationHours);
|
|
920
|
+
taskCategoryMap.set(category, current);
|
|
921
|
+
}
|
|
922
|
+
const taskStats = Array.from(taskCategoryMap.entries()).map(([category, stats]) => ({
|
|
923
|
+
task_category: category,
|
|
924
|
+
goal_id: goalId,
|
|
925
|
+
stats: {
|
|
926
|
+
total_count: stats.total,
|
|
927
|
+
success_rate: stats.total > 0 ? stats.success / stats.total : 0,
|
|
928
|
+
avg_duration_hours: stats.durations.length > 0
|
|
929
|
+
? stats.durations.reduce((a, b) => a + b, 0) /
|
|
930
|
+
stats.durations.length
|
|
931
|
+
: 0,
|
|
932
|
+
common_failure_reason: undefined,
|
|
933
|
+
},
|
|
934
|
+
period: this.computePeriod(entries),
|
|
935
|
+
updated_at: now,
|
|
936
|
+
}));
|
|
937
|
+
// Compute dimension statistics from observation entries
|
|
938
|
+
const observationEntries = entries.filter((e) => e.data_type === "observation");
|
|
939
|
+
const dimMap = new Map();
|
|
940
|
+
for (const entry of observationEntries) {
|
|
941
|
+
for (const dim of entry.dimensions) {
|
|
942
|
+
const value = typeof entry.data["value"] === "number" ? entry.data["value"] : null;
|
|
943
|
+
if (value !== null) {
|
|
944
|
+
const arr = dimMap.get(dim) ?? [];
|
|
945
|
+
arr.push(value);
|
|
946
|
+
dimMap.set(dim, arr);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
const dimensionStats = Array.from(dimMap.entries())
|
|
951
|
+
.filter(([, values]) => values.length > 0)
|
|
952
|
+
.map(([dim, values]) => {
|
|
953
|
+
const avg = values.reduce((a, b) => a + b, 0) / values.length;
|
|
954
|
+
const variance = values.reduce((sum, v) => sum + Math.pow(v - avg, 2), 0) /
|
|
955
|
+
values.length;
|
|
956
|
+
const stdDev = Math.sqrt(variance);
|
|
957
|
+
const trend = this.computeTrend(values);
|
|
958
|
+
return {
|
|
959
|
+
dimension_name: dim,
|
|
960
|
+
goal_id: goalId,
|
|
961
|
+
stats: {
|
|
962
|
+
avg_value: avg,
|
|
963
|
+
std_deviation: stdDev,
|
|
964
|
+
trend,
|
|
965
|
+
anomaly_frequency: 0,
|
|
966
|
+
observation_count: values.length,
|
|
967
|
+
},
|
|
968
|
+
period: this.computePeriod(entries),
|
|
969
|
+
updated_at: now,
|
|
970
|
+
};
|
|
971
|
+
});
|
|
972
|
+
// Overall stats
|
|
973
|
+
const totalLoops = entries.length > 0
|
|
974
|
+
? entries[entries.length - 1].loop_number -
|
|
975
|
+
entries[0].loop_number +
|
|
976
|
+
1
|
|
977
|
+
: 0;
|
|
978
|
+
const totalTasks = taskEntries.length;
|
|
979
|
+
const successfulTasks = taskEntries.filter((e) => e.data["status"] === "completed").length;
|
|
980
|
+
const overallSuccessRate = totalTasks > 0 ? successfulTasks / totalTasks : 0;
|
|
981
|
+
// Merge with existing stats
|
|
982
|
+
const mergedTaskStats = this.mergeTaskStats(existing?.task_stats ?? [], taskStats);
|
|
983
|
+
const mergedDimStats = this.mergeDimStats(existing?.dimension_stats ?? [], dimensionStats);
|
|
984
|
+
const summary = StatisticalSummarySchema.parse({
|
|
985
|
+
goal_id: goalId,
|
|
986
|
+
task_stats: mergedTaskStats,
|
|
987
|
+
dimension_stats: mergedDimStats,
|
|
988
|
+
overall: {
|
|
989
|
+
total_loops: (existing?.overall.total_loops ?? 0) + totalLoops,
|
|
990
|
+
total_tasks: (existing?.overall.total_tasks ?? 0) + totalTasks,
|
|
991
|
+
overall_success_rate: overallSuccessRate,
|
|
992
|
+
active_period: this.computePeriod(entries),
|
|
993
|
+
},
|
|
994
|
+
updated_at: now,
|
|
995
|
+
});
|
|
996
|
+
this.atomicWrite(statsPath, summary);
|
|
997
|
+
}
|
|
998
|
+
mergeTaskStats(existing, incoming) {
|
|
999
|
+
const map = new Map(existing.map((s) => [s.task_category, s]));
|
|
1000
|
+
for (const inc of incoming) {
|
|
1001
|
+
const prev = map.get(inc.task_category);
|
|
1002
|
+
if (!prev) {
|
|
1003
|
+
map.set(inc.task_category, inc);
|
|
1004
|
+
continue;
|
|
1005
|
+
}
|
|
1006
|
+
const totalCount = prev.stats.total_count + inc.stats.total_count;
|
|
1007
|
+
const prevSuccess = prev.stats.success_rate * prev.stats.total_count;
|
|
1008
|
+
const incSuccess = inc.stats.success_rate * inc.stats.total_count;
|
|
1009
|
+
map.set(inc.task_category, {
|
|
1010
|
+
...inc,
|
|
1011
|
+
stats: {
|
|
1012
|
+
total_count: totalCount,
|
|
1013
|
+
success_rate: totalCount > 0 ? (prevSuccess + incSuccess) / totalCount : 0,
|
|
1014
|
+
avg_duration_hours: (prev.stats.avg_duration_hours + inc.stats.avg_duration_hours) / 2,
|
|
1015
|
+
common_failure_reason: inc.stats.common_failure_reason,
|
|
1016
|
+
},
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
return Array.from(map.values());
|
|
1020
|
+
}
|
|
1021
|
+
mergeDimStats(existing, incoming) {
|
|
1022
|
+
const map = new Map(existing.map((s) => [s.dimension_name, s]));
|
|
1023
|
+
for (const inc of incoming) {
|
|
1024
|
+
map.set(inc.dimension_name, inc); // Replace with latest computation
|
|
1025
|
+
}
|
|
1026
|
+
return Array.from(map.values());
|
|
1027
|
+
}
|
|
1028
|
+
computeTrend(values) {
|
|
1029
|
+
if (values.length < 2)
|
|
1030
|
+
return "stable";
|
|
1031
|
+
const first = values.slice(0, Math.floor(values.length / 2));
|
|
1032
|
+
const second = values.slice(Math.floor(values.length / 2));
|
|
1033
|
+
const avgFirst = first.reduce((a, b) => a + b, 0) / first.length;
|
|
1034
|
+
const avgSecond = second.reduce((a, b) => a + b, 0) / second.length;
|
|
1035
|
+
const delta = avgSecond - avgFirst;
|
|
1036
|
+
const threshold = Math.abs(avgFirst) * 0.05; // 5% change threshold
|
|
1037
|
+
if (delta > threshold)
|
|
1038
|
+
return "rising";
|
|
1039
|
+
if (delta < -threshold)
|
|
1040
|
+
return "falling";
|
|
1041
|
+
return "stable";
|
|
1042
|
+
}
|
|
1043
|
+
computePeriod(entries) {
|
|
1044
|
+
if (entries.length === 0)
|
|
1045
|
+
return "unknown";
|
|
1046
|
+
const timestamps = entries.map((e) => e.timestamp).sort();
|
|
1047
|
+
const first = timestamps[0]?.slice(0, 10) ?? "unknown";
|
|
1048
|
+
const last = timestamps[timestamps.length - 1]?.slice(0, 10) ?? "unknown";
|
|
1049
|
+
return first === last ? first : `${first} to ${last}`;
|
|
1050
|
+
}
|
|
1051
|
+
// ─── Private: Force-compress remaining entries on goal close ───
|
|
1052
|
+
async compressAllRemainingToLongTerm(goalId, dataType, entries) {
|
|
1053
|
+
if (entries.length === 0)
|
|
1054
|
+
return;
|
|
1055
|
+
const now = new Date().toISOString();
|
|
1056
|
+
const patterns = await this.extractPatterns(entries);
|
|
1057
|
+
const rawLessons = await this.distillLessons(patterns, entries);
|
|
1058
|
+
const sourceLoops = entries.map((e) => `loop_${e.loop_number}`);
|
|
1059
|
+
const lessons = rawLessons.map((l) => LessonEntrySchema.parse({
|
|
1060
|
+
...l,
|
|
1061
|
+
lesson_id: this.generateId("lesson"),
|
|
1062
|
+
goal_id: goalId,
|
|
1063
|
+
source_loops: sourceLoops,
|
|
1064
|
+
extracted_at: now,
|
|
1065
|
+
status: "active",
|
|
1066
|
+
superseded_by: undefined,
|
|
1067
|
+
}));
|
|
1068
|
+
this.storeLessonsLongTerm(goalId, lessons, entries);
|
|
1069
|
+
this.updateStatistics(goalId, entries);
|
|
1070
|
+
void dataType; // type info available for future audit logging
|
|
1071
|
+
}
|
|
1072
|
+
// ─── Private: Lesson Query ───
|
|
1073
|
+
queryLessons(tags, dimensions, maxCount) {
|
|
1074
|
+
const results = [];
|
|
1075
|
+
const seen = new Set();
|
|
1076
|
+
// Query by-dimension lessons
|
|
1077
|
+
for (const dim of dimensions) {
|
|
1078
|
+
const byDimPath = path.join(this.memoryDir, "long-term", "lessons", "by-dimension", `${dim}.json`);
|
|
1079
|
+
const lessons = this.readJsonFile(byDimPath, z.array(LessonEntrySchema)) ??
|
|
1080
|
+
[];
|
|
1081
|
+
for (const l of lessons) {
|
|
1082
|
+
if (!seen.has(l.lesson_id) &&
|
|
1083
|
+
l.status === "active" &&
|
|
1084
|
+
results.length < maxCount) {
|
|
1085
|
+
results.push(l);
|
|
1086
|
+
seen.add(l.lesson_id);
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
// Query global lessons matching tags
|
|
1091
|
+
if (results.length < maxCount && tags.length > 0) {
|
|
1092
|
+
const globalPath = path.join(this.memoryDir, "long-term", "lessons", "global.json");
|
|
1093
|
+
const globalLessons = this.readJsonFile(globalPath, z.array(LessonEntrySchema)) ?? [];
|
|
1094
|
+
const matching = globalLessons.filter((l) => !seen.has(l.lesson_id) &&
|
|
1095
|
+
l.status === "active" &&
|
|
1096
|
+
tags.some((t) => l.relevance_tags.includes(t)));
|
|
1097
|
+
// Sort by extracted_at descending (most recent first)
|
|
1098
|
+
matching.sort((a, b) => new Date(b.extracted_at).getTime() -
|
|
1099
|
+
new Date(a.extracted_at).getTime());
|
|
1100
|
+
for (const l of matching) {
|
|
1101
|
+
if (results.length >= maxCount)
|
|
1102
|
+
break;
|
|
1103
|
+
results.push(l);
|
|
1104
|
+
seen.add(l.lesson_id);
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
return results;
|
|
1108
|
+
}
|
|
1109
|
+
// ─── Private: Cross-Goal Lesson Query ───
|
|
1110
|
+
/**
|
|
1111
|
+
* Query lessons from ALL goals except the specified goalId.
|
|
1112
|
+
* Used for cross-goal knowledge transfer in selectForWorkingMemory.
|
|
1113
|
+
*/
|
|
1114
|
+
queryCrossGoalLessons(tags, dimensions, excludeGoalId, maxCount) {
|
|
1115
|
+
const results = [];
|
|
1116
|
+
const seen = new Set();
|
|
1117
|
+
// Query global lessons (which include all goals)
|
|
1118
|
+
const globalPath = path.join(this.memoryDir, "long-term", "lessons", "global.json");
|
|
1119
|
+
const globalLessons = this.readJsonFile(globalPath, z.array(LessonEntrySchema)) ?? [];
|
|
1120
|
+
// Filter to lessons from other goals that match tags or dimensions
|
|
1121
|
+
const crossGoalLessons = globalLessons.filter((l) => l.goal_id !== excludeGoalId &&
|
|
1122
|
+
l.status === "active" &&
|
|
1123
|
+
(tags.some((t) => l.relevance_tags.includes(t)) ||
|
|
1124
|
+
dimensions.some((d) => l.relevance_tags.includes(d))));
|
|
1125
|
+
// Sort by recency
|
|
1126
|
+
crossGoalLessons.sort((a, b) => new Date(b.extracted_at).getTime() - new Date(a.extracted_at).getTime());
|
|
1127
|
+
for (const l of crossGoalLessons) {
|
|
1128
|
+
if (results.length >= maxCount)
|
|
1129
|
+
break;
|
|
1130
|
+
if (!seen.has(l.lesson_id)) {
|
|
1131
|
+
results.push(l);
|
|
1132
|
+
seen.add(l.lesson_id);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
return results;
|
|
1136
|
+
}
|
|
1137
|
+
// ─── Private: LLM Helpers ───
|
|
1138
|
+
/**
|
|
1139
|
+
* Call LLM to extract recurring patterns from a set of short-term entries.
|
|
1140
|
+
*/
|
|
1141
|
+
async extractPatterns(entries) {
|
|
1142
|
+
const prompt = `Analyze the following experience log entries and extract recurring patterns, key insights, and lessons learned. Focus on what worked, what failed, and why.
|
|
1143
|
+
|
|
1144
|
+
Return a JSON object with a "patterns" array of pattern strings:
|
|
1145
|
+
{
|
|
1146
|
+
"patterns": ["pattern 1", "pattern 2", ...]
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
Entries (${entries.length} total):
|
|
1150
|
+
${JSON.stringify(entries.slice(0, 20).map((e) => ({
|
|
1151
|
+
data_type: e.data_type,
|
|
1152
|
+
loop_number: e.loop_number,
|
|
1153
|
+
dimensions: e.dimensions,
|
|
1154
|
+
tags: e.tags,
|
|
1155
|
+
data: e.data,
|
|
1156
|
+
})), null, 2)}`;
|
|
1157
|
+
const response = await this.llmClient.sendMessage([{ role: "user", content: prompt }], {
|
|
1158
|
+
system: "You are a pattern extraction engine. Analyze experience logs and identify recurring patterns, successes, and failures. Respond with JSON only.",
|
|
1159
|
+
max_tokens: 2048,
|
|
1160
|
+
});
|
|
1161
|
+
try {
|
|
1162
|
+
const parsed = this.llmClient.parseJSON(response.content, PatternExtractionResponseSchema);
|
|
1163
|
+
return parsed.patterns;
|
|
1164
|
+
}
|
|
1165
|
+
catch {
|
|
1166
|
+
return [];
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Call LLM to convert extracted patterns into structured LessonEntry objects.
|
|
1171
|
+
*/
|
|
1172
|
+
async distillLessons(patterns, entries) {
|
|
1173
|
+
if (patterns.length === 0)
|
|
1174
|
+
return [];
|
|
1175
|
+
const failureEntries = entries.filter((e) => e.data["status"] === "failed" ||
|
|
1176
|
+
e.data["verdict"] === "fail" ||
|
|
1177
|
+
e.data["outcome"] === "failure");
|
|
1178
|
+
const prompt = `Convert the following patterns into structured lessons. For each pattern, determine if it represents a strategy outcome, success pattern, or failure pattern.
|
|
1179
|
+
|
|
1180
|
+
Patterns:
|
|
1181
|
+
${patterns.map((p, i) => `${i + 1}. ${p}`).join("\n")}
|
|
1182
|
+
|
|
1183
|
+
Failure context (${failureEntries.length} failure entries found):
|
|
1184
|
+
${JSON.stringify(failureEntries.slice(0, 5).map((e) => e.data), null, 2)}
|
|
1185
|
+
|
|
1186
|
+
Return a JSON object with a "lessons" array:
|
|
1187
|
+
{
|
|
1188
|
+
"lessons": [
|
|
1189
|
+
{
|
|
1190
|
+
"type": "strategy_outcome" | "success_pattern" | "failure_pattern",
|
|
1191
|
+
"context": "what situation this lesson applies to",
|
|
1192
|
+
"action": "what action was taken (optional)",
|
|
1193
|
+
"outcome": "what result occurred (optional)",
|
|
1194
|
+
"lesson": "the key lesson learned",
|
|
1195
|
+
"relevance_tags": ["tag1", "tag2"],
|
|
1196
|
+
"failure_reason": "why it failed (for failure_pattern only)",
|
|
1197
|
+
"avoidance_hint": "how to avoid next time (for failure_pattern only)",
|
|
1198
|
+
"applicability": "when to apply (for success_pattern only)"
|
|
1199
|
+
}
|
|
1200
|
+
]
|
|
1201
|
+
}`;
|
|
1202
|
+
const response = await this.llmClient.sendMessage([{ role: "user", content: prompt }], {
|
|
1203
|
+
system: "You are a lesson distillation engine. Convert experience patterns into structured, actionable lessons. Respond with JSON only.",
|
|
1204
|
+
max_tokens: 4096,
|
|
1205
|
+
});
|
|
1206
|
+
try {
|
|
1207
|
+
const parsed = this.llmClient.parseJSON(response.content, LessonDistillationResponseSchema);
|
|
1208
|
+
// Normalize: ensure relevance_tags is always a string[]
|
|
1209
|
+
return parsed.lessons.map((l) => ({
|
|
1210
|
+
...l,
|
|
1211
|
+
relevance_tags: l.relevance_tags ?? [],
|
|
1212
|
+
}));
|
|
1213
|
+
}
|
|
1214
|
+
catch {
|
|
1215
|
+
return [];
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* Validate compression quality.
|
|
1220
|
+
* MVP check: lesson_count >= failure_count * 0.5
|
|
1221
|
+
*/
|
|
1222
|
+
validateCompressionQuality(lessons, entries) {
|
|
1223
|
+
// Count failure entries
|
|
1224
|
+
const failureCount = entries.filter((e) => e.data["status"] === "failed" ||
|
|
1225
|
+
e.data["verdict"] === "fail" ||
|
|
1226
|
+
e.data["outcome"] === "failure").length;
|
|
1227
|
+
// MVP ratio check: lessons >= failures * 0.5
|
|
1228
|
+
const lessonCount = lessons.length;
|
|
1229
|
+
const failure_coverage_ratio = failureCount === 0
|
|
1230
|
+
? 1
|
|
1231
|
+
: Math.min(1, lessonCount / (failureCount * 0.5));
|
|
1232
|
+
const passed = failureCount === 0 || lessonCount >= failureCount * 0.5;
|
|
1233
|
+
// Contradiction detection: check for lessons with opposite type covering same context
|
|
1234
|
+
let contradictions_found = 0;
|
|
1235
|
+
for (let i = 0; i < lessons.length; i++) {
|
|
1236
|
+
for (let j = i + 1; j < lessons.length; j++) {
|
|
1237
|
+
const a = lessons[i];
|
|
1238
|
+
const b = lessons[j];
|
|
1239
|
+
const isOppositeType = (a.type === "success_pattern" && b.type === "failure_pattern") ||
|
|
1240
|
+
(a.type === "failure_pattern" && b.type === "success_pattern");
|
|
1241
|
+
const sharesTag = a.relevance_tags.some((t) => b.relevance_tags.includes(t));
|
|
1242
|
+
if (isOppositeType && sharesTag) {
|
|
1243
|
+
contradictions_found++;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return {
|
|
1248
|
+
passed,
|
|
1249
|
+
failure_coverage_ratio,
|
|
1250
|
+
contradictions_found,
|
|
1251
|
+
};
|
|
1252
|
+
}
|
|
1253
|
+
// ─── Private: File Helpers ───
|
|
1254
|
+
atomicWrite(filePath, data) {
|
|
1255
|
+
const dir = path.dirname(filePath);
|
|
1256
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
1257
|
+
const tmpPath = filePath + ".tmp";
|
|
1258
|
+
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2), "utf-8");
|
|
1259
|
+
fs.renameSync(tmpPath, filePath);
|
|
1260
|
+
}
|
|
1261
|
+
readJsonFile(filePath, schema) {
|
|
1262
|
+
if (!fs.existsSync(filePath))
|
|
1263
|
+
return null;
|
|
1264
|
+
try {
|
|
1265
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
1266
|
+
const raw = JSON.parse(content);
|
|
1267
|
+
return schema.parse(raw);
|
|
1268
|
+
}
|
|
1269
|
+
catch {
|
|
1270
|
+
return null;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* Map MemoryDataType to the corresponding short-term JSON file path.
|
|
1275
|
+
*/
|
|
1276
|
+
getDataFile(goalId, dataType) {
|
|
1277
|
+
const fileNames = {
|
|
1278
|
+
experience_log: "experience-log.json",
|
|
1279
|
+
observation: "observations.json",
|
|
1280
|
+
strategy: "strategies.json",
|
|
1281
|
+
task: "tasks.json",
|
|
1282
|
+
knowledge: "knowledge.json",
|
|
1283
|
+
};
|
|
1284
|
+
return path.join(this.memoryDir, "short-term", "goals", goalId, fileNames[dataType]);
|
|
1285
|
+
}
|
|
1286
|
+
generateId(prefix) {
|
|
1287
|
+
return `${prefix}_${randomUUID().replace(/-/g, "").slice(0, 12)}`;
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Compute total size of a directory recursively in bytes.
|
|
1291
|
+
*/
|
|
1292
|
+
getDirectorySize(dirPath) {
|
|
1293
|
+
if (!fs.existsSync(dirPath))
|
|
1294
|
+
return 0;
|
|
1295
|
+
let total = 0;
|
|
1296
|
+
const entries = fs.readdirSync(dirPath, { withFileTypes: true });
|
|
1297
|
+
for (const entry of entries) {
|
|
1298
|
+
const entryPath = path.join(dirPath, entry.name);
|
|
1299
|
+
if (entry.isDirectory()) {
|
|
1300
|
+
total += this.getDirectorySize(entryPath);
|
|
1301
|
+
}
|
|
1302
|
+
else {
|
|
1303
|
+
try {
|
|
1304
|
+
total += fs.statSync(entryPath).size;
|
|
1305
|
+
}
|
|
1306
|
+
catch {
|
|
1307
|
+
// Ignore stat errors
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
return total;
|
|
1312
|
+
}
|
|
1313
|
+
/**
|
|
1314
|
+
* Get the retention loop limit for a goal, considering goal_type_overrides.
|
|
1315
|
+
* Since goalId does not encode goal type in MVP, use default unless caller
|
|
1316
|
+
* configures an override keyed by goalId prefix.
|
|
1317
|
+
*/
|
|
1318
|
+
getRetentionLimit(goalId) {
|
|
1319
|
+
// Check if any override key is a prefix of goalId
|
|
1320
|
+
for (const [key, limit] of Object.entries(this.config.goal_type_overrides)) {
|
|
1321
|
+
if (goalId.startsWith(key) || goalId.includes(key)) {
|
|
1322
|
+
return limit;
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
return this.config.default_retention_loops;
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
//# sourceMappingURL=memory-lifecycle.js.map
|