@substrate-ai/core 0.19.54
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/README.md +55 -0
- package/dist/__tests__/adapter.test.d.ts +12 -0
- package/dist/__tests__/adapter.test.d.ts.map +1 -0
- package/dist/__tests__/adapter.test.js +259 -0
- package/dist/__tests__/adapter.test.js.map +1 -0
- package/dist/__tests__/event-bus.test.d.ts +14 -0
- package/dist/__tests__/event-bus.test.d.ts.map +1 -0
- package/dist/__tests__/event-bus.test.js +199 -0
- package/dist/__tests__/event-bus.test.js.map +1 -0
- package/dist/__tests__/output-quality.test.d.ts +8 -0
- package/dist/__tests__/output-quality.test.d.ts.map +1 -0
- package/dist/__tests__/output-quality.test.js +166 -0
- package/dist/__tests__/output-quality.test.js.map +1 -0
- package/dist/__tests__/schema-suffix.test.d.ts +9 -0
- package/dist/__tests__/schema-suffix.test.d.ts.map +1 -0
- package/dist/__tests__/schema-suffix.test.js +126 -0
- package/dist/__tests__/schema-suffix.test.js.map +1 -0
- package/dist/__tests__/yaml-parser.test.d.ts +18 -0
- package/dist/__tests__/yaml-parser.test.d.ts.map +1 -0
- package/dist/__tests__/yaml-parser.test.js +475 -0
- package/dist/__tests__/yaml-parser.test.js.map +1 -0
- package/dist/__type-checks__.d.ts +11 -0
- package/dist/__type-checks__.d.ts.map +1 -0
- package/dist/__type-checks__.js +19 -0
- package/dist/__type-checks__.js.map +1 -0
- package/dist/adapters/__tests__/adapter-output-normalizer.test.d.ts +12 -0
- package/dist/adapters/__tests__/adapter-output-normalizer.test.d.ts.map +1 -0
- package/dist/adapters/__tests__/adapter-output-normalizer.test.js +193 -0
- package/dist/adapters/__tests__/adapter-output-normalizer.test.js.map +1 -0
- package/dist/adapters/adapter-format-error.d.ts +35 -0
- package/dist/adapters/adapter-format-error.d.ts.map +1 -0
- package/dist/adapters/adapter-format-error.js +38 -0
- package/dist/adapters/adapter-format-error.js.map +1 -0
- package/dist/adapters/adapter-output-normalizer.d.ts +50 -0
- package/dist/adapters/adapter-output-normalizer.d.ts.map +1 -0
- package/dist/adapters/adapter-output-normalizer.js +233 -0
- package/dist/adapters/adapter-output-normalizer.js.map +1 -0
- package/dist/adapters/adapter-registry.d.ts +50 -0
- package/dist/adapters/adapter-registry.d.ts.map +1 -0
- package/dist/adapters/adapter-registry.js +101 -0
- package/dist/adapters/adapter-registry.js.map +1 -0
- package/dist/adapters/claude-adapter.d.ts +59 -0
- package/dist/adapters/claude-adapter.d.ts.map +1 -0
- package/dist/adapters/claude-adapter.js +367 -0
- package/dist/adapters/claude-adapter.js.map +1 -0
- package/dist/adapters/codex-adapter.d.ts +64 -0
- package/dist/adapters/codex-adapter.d.ts.map +1 -0
- package/dist/adapters/codex-adapter.js +263 -0
- package/dist/adapters/codex-adapter.js.map +1 -0
- package/dist/adapters/gemini-adapter.d.ts +57 -0
- package/dist/adapters/gemini-adapter.d.ts.map +1 -0
- package/dist/adapters/gemini-adapter.js +311 -0
- package/dist/adapters/gemini-adapter.js.map +1 -0
- package/dist/adapters/index.d.ts +10 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +14 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/schemas.d.ts +137 -0
- package/dist/adapters/schemas.d.ts.map +1 -0
- package/dist/adapters/schemas.js +140 -0
- package/dist/adapters/schemas.js.map +1 -0
- package/dist/adapters/types.d.ts +245 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +6 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/worker-adapter.d.ts +188 -0
- package/dist/adapters/worker-adapter.d.ts.map +1 -0
- package/dist/adapters/worker-adapter.js +19 -0
- package/dist/adapters/worker-adapter.js.map +1 -0
- package/dist/budget/budget-tracker.d.ts +22 -0
- package/dist/budget/budget-tracker.d.ts.map +1 -0
- package/dist/budget/budget-tracker.js +39 -0
- package/dist/budget/budget-tracker.js.map +1 -0
- package/dist/budget/index.d.ts +6 -0
- package/dist/budget/index.d.ts.map +1 -0
- package/dist/budget/index.js +5 -0
- package/dist/budget/index.js.map +1 -0
- package/dist/config/config-migrator.d.ts +58 -0
- package/dist/config/config-migrator.d.ts.map +1 -0
- package/dist/config/config-migrator.js +158 -0
- package/dist/config/config-migrator.js.map +1 -0
- package/dist/config/config-system-impl.d.ts +63 -0
- package/dist/config/config-system-impl.d.ts.map +1 -0
- package/dist/config/config-system-impl.js +364 -0
- package/dist/config/config-system-impl.js.map +1 -0
- package/dist/config/config-watcher.d.ts +59 -0
- package/dist/config/config-watcher.d.ts.map +1 -0
- package/dist/config/config-watcher.js +137 -0
- package/dist/config/config-watcher.js.map +1 -0
- package/dist/config/defaults.d.ts +13 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +62 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/errors.d.ts +25 -0
- package/dist/config/errors.d.ts.map +1 -0
- package/dist/config/errors.js +49 -0
- package/dist/config/errors.js.map +1 -0
- package/dist/config/index.d.ts +19 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +39 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/types.d.ts +456 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +174 -0
- package/dist/config/types.js.map +1 -0
- package/dist/config/version-utils.d.ts +39 -0
- package/dist/config/version-utils.d.ts.map +1 -0
- package/dist/config/version-utils.js +66 -0
- package/dist/config/version-utils.js.map +1 -0
- package/dist/context/index.d.ts +2 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +2 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/types.d.ts +113 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +59 -0
- package/dist/context/types.js.map +1 -0
- package/dist/cost-tracker/cost-tracker-impl.d.ts +51 -0
- package/dist/cost-tracker/cost-tracker-impl.d.ts.map +1 -0
- package/dist/cost-tracker/cost-tracker-impl.js +85 -0
- package/dist/cost-tracker/cost-tracker-impl.js.map +1 -0
- package/dist/cost-tracker/cost-tracker-subscriber.d.ts +31 -0
- package/dist/cost-tracker/cost-tracker-subscriber.d.ts.map +1 -0
- package/dist/cost-tracker/cost-tracker-subscriber.js +116 -0
- package/dist/cost-tracker/cost-tracker-subscriber.js.map +1 -0
- package/dist/cost-tracker/index.d.ts +11 -0
- package/dist/cost-tracker/index.d.ts.map +1 -0
- package/dist/cost-tracker/index.js +7 -0
- package/dist/cost-tracker/index.js.map +1 -0
- package/dist/cost-tracker/token-rates.d.ts +25 -0
- package/dist/cost-tracker/token-rates.d.ts.map +1 -0
- package/dist/cost-tracker/token-rates.js +99 -0
- package/dist/cost-tracker/token-rates.js.map +1 -0
- package/dist/cost-tracker/types.d.ts +6 -0
- package/dist/cost-tracker/types.d.ts.map +1 -0
- package/dist/cost-tracker/types.js +2 -0
- package/dist/cost-tracker/types.js.map +1 -0
- package/dist/dispatch/dispatcher-impl.d.ts +92 -0
- package/dist/dispatch/dispatcher-impl.d.ts.map +1 -0
- package/dist/dispatch/dispatcher-impl.js +847 -0
- package/dist/dispatch/dispatcher-impl.js.map +1 -0
- package/dist/dispatch/index.d.ts +15 -0
- package/dist/dispatch/index.d.ts.map +1 -0
- package/dist/dispatch/index.js +14 -0
- package/dist/dispatch/index.js.map +1 -0
- package/dist/dispatch/interface-change-detector.d.ts +46 -0
- package/dist/dispatch/interface-change-detector.d.ts.map +1 -0
- package/dist/dispatch/interface-change-detector.js +135 -0
- package/dist/dispatch/interface-change-detector.js.map +1 -0
- package/dist/dispatch/output-quality.d.ts +43 -0
- package/dist/dispatch/output-quality.d.ts.map +1 -0
- package/dist/dispatch/output-quality.js +148 -0
- package/dist/dispatch/output-quality.js.map +1 -0
- package/dist/dispatch/types.d.ts +271 -0
- package/dist/dispatch/types.d.ts.map +1 -0
- package/dist/dispatch/types.js +76 -0
- package/dist/dispatch/types.js.map +1 -0
- package/dist/dispatch/yaml-parser.d.ts +40 -0
- package/dist/dispatch/yaml-parser.d.ts.map +1 -0
- package/dist/dispatch/yaml-parser.js +323 -0
- package/dist/dispatch/yaml-parser.js.map +1 -0
- package/dist/events/core-events.d.ts +288 -0
- package/dist/events/core-events.d.ts.map +1 -0
- package/dist/events/core-events.js +10 -0
- package/dist/events/core-events.js.map +1 -0
- package/dist/events/event-bus.d.ts +55 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +52 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/events/index.d.ts +9 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +6 -0
- package/dist/events/index.js.map +1 -0
- package/dist/events/types.d.ts +21 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +8 -0
- package/dist/events/types.js.map +1 -0
- package/dist/git/git-manager.d.ts +31 -0
- package/dist/git/git-manager.d.ts.map +1 -0
- package/dist/git/git-manager.js +46 -0
- package/dist/git/git-manager.js.map +1 -0
- package/dist/git/git-utils.d.ts +166 -0
- package/dist/git/git-utils.d.ts.map +1 -0
- package/dist/git/git-utils.js +347 -0
- package/dist/git/git-utils.js.map +1 -0
- package/dist/git/git-worktree-manager-impl.d.ts +58 -0
- package/dist/git/git-worktree-manager-impl.d.ts.map +1 -0
- package/dist/git/git-worktree-manager-impl.js +336 -0
- package/dist/git/git-worktree-manager-impl.js.map +1 -0
- package/dist/git/git-worktree-manager.d.ts +122 -0
- package/dist/git/git-worktree-manager.d.ts.map +1 -0
- package/dist/git/git-worktree-manager.js +14 -0
- package/dist/git/git-worktree-manager.js.map +1 -0
- package/dist/git/index.d.ts +11 -0
- package/dist/git/index.d.ts.map +1 -0
- package/dist/git/index.js +8 -0
- package/dist/git/index.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +47 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/client.d.ts +42 -0
- package/dist/llm/client.d.ts.map +1 -0
- package/dist/llm/client.js +27 -0
- package/dist/llm/client.js.map +1 -0
- package/dist/monitor/index.d.ts +15 -0
- package/dist/monitor/index.d.ts.map +1 -0
- package/dist/monitor/index.js +9 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/monitor/monitor-agent-impl.d.ts +56 -0
- package/dist/monitor/monitor-agent-impl.d.ts.map +1 -0
- package/dist/monitor/monitor-agent-impl.js +178 -0
- package/dist/monitor/monitor-agent-impl.js.map +1 -0
- package/dist/monitor/monitor-agent.d.ts +36 -0
- package/dist/monitor/monitor-agent.d.ts.map +1 -0
- package/dist/monitor/monitor-agent.js +6 -0
- package/dist/monitor/monitor-agent.js.map +1 -0
- package/dist/monitor/performance-aggregates.d.ts +41 -0
- package/dist/monitor/performance-aggregates.d.ts.map +1 -0
- package/dist/monitor/performance-aggregates.js +6 -0
- package/dist/monitor/performance-aggregates.js.map +1 -0
- package/dist/monitor/recommendation-engine.d.ts +27 -0
- package/dist/monitor/recommendation-engine.d.ts.map +1 -0
- package/dist/monitor/recommendation-engine.js +140 -0
- package/dist/monitor/recommendation-engine.js.map +1 -0
- package/dist/monitor/recommendation-types.d.ts +30 -0
- package/dist/monitor/recommendation-types.d.ts.map +1 -0
- package/dist/monitor/recommendation-types.js +43 -0
- package/dist/monitor/recommendation-types.js.map +1 -0
- package/dist/monitor/report-generator.d.ts +48 -0
- package/dist/monitor/report-generator.d.ts.map +1 -0
- package/dist/monitor/report-generator.js +123 -0
- package/dist/monitor/report-generator.js.map +1 -0
- package/dist/monitor/task-type-classifier.d.ts +19 -0
- package/dist/monitor/task-type-classifier.d.ts.map +1 -0
- package/dist/monitor/task-type-classifier.js +68 -0
- package/dist/monitor/task-type-classifier.js.map +1 -0
- package/dist/persistence/adapter.d.ts +4 -0
- package/dist/persistence/adapter.d.ts.map +1 -0
- package/dist/persistence/adapter.js +56 -0
- package/dist/persistence/adapter.js.map +1 -0
- package/dist/persistence/cost-types.d.ts +87 -0
- package/dist/persistence/cost-types.d.ts.map +1 -0
- package/dist/persistence/cost-types.js +14 -0
- package/dist/persistence/cost-types.js.map +1 -0
- package/dist/persistence/dolt-adapter-transaction.test.d.ts +10 -0
- package/dist/persistence/dolt-adapter-transaction.test.d.ts.map +1 -0
- package/dist/persistence/dolt-adapter-transaction.test.js +359 -0
- package/dist/persistence/dolt-adapter-transaction.test.js.map +1 -0
- package/dist/persistence/dolt-adapter.d.ts +77 -0
- package/dist/persistence/dolt-adapter.d.ts.map +1 -0
- package/dist/persistence/dolt-adapter.js +98 -0
- package/dist/persistence/dolt-adapter.js.map +1 -0
- package/dist/persistence/dolt-client.d.ts +69 -0
- package/dist/persistence/dolt-client.d.ts.map +1 -0
- package/dist/persistence/dolt-client.js +278 -0
- package/dist/persistence/dolt-client.js.map +1 -0
- package/dist/persistence/dolt-errors.d.ts +10 -0
- package/dist/persistence/dolt-errors.d.ts.map +1 -0
- package/dist/persistence/dolt-errors.js +15 -0
- package/dist/persistence/dolt-errors.js.map +1 -0
- package/dist/persistence/dolt-init.d.ts +64 -0
- package/dist/persistence/dolt-init.d.ts.map +1 -0
- package/dist/persistence/dolt-init.js +233 -0
- package/dist/persistence/dolt-init.js.map +1 -0
- package/dist/persistence/index.d.ts +23 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +23 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/memory-adapter.d.ts +156 -0
- package/dist/persistence/memory-adapter.d.ts.map +1 -0
- package/dist/persistence/memory-adapter.js +1167 -0
- package/dist/persistence/memory-adapter.js.map +1 -0
- package/dist/persistence/monitor-database.d.ts +113 -0
- package/dist/persistence/monitor-database.d.ts.map +1 -0
- package/dist/persistence/monitor-database.js +345 -0
- package/dist/persistence/monitor-database.js.map +1 -0
- package/dist/persistence/queries/amendments.d.ts +91 -0
- package/dist/persistence/queries/amendments.d.ts.map +1 -0
- package/dist/persistence/queries/amendments.js +185 -0
- package/dist/persistence/queries/amendments.js.map +1 -0
- package/dist/persistence/queries/cost.d.ts +130 -0
- package/dist/persistence/queries/cost.d.ts.map +1 -0
- package/dist/persistence/queries/cost.js +384 -0
- package/dist/persistence/queries/cost.js.map +1 -0
- package/dist/persistence/queries/decisions.d.ts +131 -0
- package/dist/persistence/queries/decisions.d.ts.map +1 -0
- package/dist/persistence/queries/decisions.js +339 -0
- package/dist/persistence/queries/decisions.js.map +1 -0
- package/dist/persistence/queries/metrics.d.ts +155 -0
- package/dist/persistence/queries/metrics.d.ts.map +1 -0
- package/dist/persistence/queries/metrics.js +237 -0
- package/dist/persistence/queries/metrics.js.map +1 -0
- package/dist/persistence/queries/retry-escalated.d.ts +35 -0
- package/dist/persistence/queries/retry-escalated.d.ts.map +1 -0
- package/dist/persistence/queries/retry-escalated.js +83 -0
- package/dist/persistence/queries/retry-escalated.js.map +1 -0
- package/dist/persistence/schema-version.d.ts +89 -0
- package/dist/persistence/schema-version.d.ts.map +1 -0
- package/dist/persistence/schema-version.js +67 -0
- package/dist/persistence/schema-version.js.map +1 -0
- package/dist/persistence/schema.d.ts +26 -0
- package/dist/persistence/schema.d.ts.map +1 -0
- package/dist/persistence/schema.js +509 -0
- package/dist/persistence/schema.js.map +1 -0
- package/dist/persistence/schemas/decisions.d.ts +176 -0
- package/dist/persistence/schemas/decisions.d.ts.map +1 -0
- package/dist/persistence/schemas/decisions.js +139 -0
- package/dist/persistence/schemas/decisions.js.map +1 -0
- package/dist/persistence/schemas/operational.d.ts +194 -0
- package/dist/persistence/schemas/operational.d.ts.map +1 -0
- package/dist/persistence/schemas/operational.js +197 -0
- package/dist/persistence/schemas/operational.js.map +1 -0
- package/dist/persistence/types.d.ts +98 -0
- package/dist/persistence/types.d.ts.map +1 -0
- package/dist/persistence/types.js +22 -0
- package/dist/persistence/types.js.map +1 -0
- package/dist/quality-gates/index.d.ts +2 -0
- package/dist/quality-gates/index.d.ts.map +1 -0
- package/dist/quality-gates/index.js +2 -0
- package/dist/quality-gates/index.js.map +1 -0
- package/dist/quality-gates/types.d.ts +106 -0
- package/dist/quality-gates/types.d.ts.map +1 -0
- package/dist/quality-gates/types.js +5 -0
- package/dist/quality-gates/types.js.map +1 -0
- package/dist/routing/index.d.ts +19 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +32 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/model-routing-config.d.ts +75 -0
- package/dist/routing/model-routing-config.d.ts.map +1 -0
- package/dist/routing/model-routing-config.js +110 -0
- package/dist/routing/model-routing-config.js.map +1 -0
- package/dist/routing/model-routing-resolver.d.ts +48 -0
- package/dist/routing/model-routing-resolver.d.ts.map +1 -0
- package/dist/routing/model-routing-resolver.js +105 -0
- package/dist/routing/model-routing-resolver.js.map +1 -0
- package/dist/routing/model-tier.d.ts +21 -0
- package/dist/routing/model-tier.d.ts.map +1 -0
- package/dist/routing/model-tier.js +34 -0
- package/dist/routing/model-tier.js.map +1 -0
- package/dist/routing/provider-status.d.ts +99 -0
- package/dist/routing/provider-status.d.ts.map +1 -0
- package/dist/routing/provider-status.js +163 -0
- package/dist/routing/provider-status.js.map +1 -0
- package/dist/routing/routing-decision.d.ts +127 -0
- package/dist/routing/routing-decision.d.ts.map +1 -0
- package/dist/routing/routing-decision.js +111 -0
- package/dist/routing/routing-decision.js.map +1 -0
- package/dist/routing/routing-engine-impl.d.ts +132 -0
- package/dist/routing/routing-engine-impl.d.ts.map +1 -0
- package/dist/routing/routing-engine-impl.js +450 -0
- package/dist/routing/routing-engine-impl.js.map +1 -0
- package/dist/routing/routing-engine.d.ts +83 -0
- package/dist/routing/routing-engine.d.ts.map +1 -0
- package/dist/routing/routing-engine.js +24 -0
- package/dist/routing/routing-engine.js.map +1 -0
- package/dist/routing/routing-policy.d.ts +138 -0
- package/dist/routing/routing-policy.d.ts.map +1 -0
- package/dist/routing/routing-policy.js +159 -0
- package/dist/routing/routing-policy.js.map +1 -0
- package/dist/routing/routing-recommender.d.ts +60 -0
- package/dist/routing/routing-recommender.d.ts.map +1 -0
- package/dist/routing/routing-recommender.js +209 -0
- package/dist/routing/routing-recommender.js.map +1 -0
- package/dist/routing/routing-telemetry.d.ts +36 -0
- package/dist/routing/routing-telemetry.d.ts.map +1 -0
- package/dist/routing/routing-telemetry.js +39 -0
- package/dist/routing/routing-telemetry.js.map +1 -0
- package/dist/routing/routing-token-accumulator.d.ts +68 -0
- package/dist/routing/routing-token-accumulator.d.ts.map +1 -0
- package/dist/routing/routing-token-accumulator.js +111 -0
- package/dist/routing/routing-token-accumulator.js.map +1 -0
- package/dist/routing/routing-tuner.d.ts +69 -0
- package/dist/routing/routing-tuner.d.ts.map +1 -0
- package/dist/routing/routing-tuner.js +217 -0
- package/dist/routing/routing-tuner.js.map +1 -0
- package/dist/routing/types.d.ts +152 -0
- package/dist/routing/types.d.ts.map +1 -0
- package/dist/routing/types.js +13 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/supervisor/analysis.d.ts +178 -0
- package/dist/supervisor/analysis.d.ts.map +1 -0
- package/dist/supervisor/analysis.js +420 -0
- package/dist/supervisor/analysis.js.map +1 -0
- package/dist/supervisor/experimenter.d.ts +118 -0
- package/dist/supervisor/experimenter.d.ts.map +1 -0
- package/dist/supervisor/experimenter.js +493 -0
- package/dist/supervisor/experimenter.js.map +1 -0
- package/dist/supervisor/index.d.ts +13 -0
- package/dist/supervisor/index.d.ts.map +1 -0
- package/dist/supervisor/index.js +11 -0
- package/dist/supervisor/index.js.map +1 -0
- package/dist/telemetry/batch-buffer.d.ts +53 -0
- package/dist/telemetry/batch-buffer.d.ts.map +1 -0
- package/dist/telemetry/batch-buffer.js +83 -0
- package/dist/telemetry/batch-buffer.js.map +1 -0
- package/dist/telemetry/categorizer.d.ts +65 -0
- package/dist/telemetry/categorizer.d.ts.map +1 -0
- package/dist/telemetry/categorizer.js +338 -0
- package/dist/telemetry/categorizer.js.map +1 -0
- package/dist/telemetry/consumer-analyzer.d.ts +53 -0
- package/dist/telemetry/consumer-analyzer.d.ts.map +1 -0
- package/dist/telemetry/consumer-analyzer.js +182 -0
- package/dist/telemetry/consumer-analyzer.js.map +1 -0
- package/dist/telemetry/cost-table.d.ts +36 -0
- package/dist/telemetry/cost-table.d.ts.map +1 -0
- package/dist/telemetry/cost-table.js +127 -0
- package/dist/telemetry/cost-table.js.map +1 -0
- package/dist/telemetry/efficiency-scorer.d.ts +103 -0
- package/dist/telemetry/efficiency-scorer.d.ts.map +1 -0
- package/dist/telemetry/efficiency-scorer.js +311 -0
- package/dist/telemetry/efficiency-scorer.js.map +1 -0
- package/dist/telemetry/index.d.ts +28 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +37 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/ingestion-server.d.ts +99 -0
- package/dist/telemetry/ingestion-server.d.ts.map +1 -0
- package/dist/telemetry/ingestion-server.js +315 -0
- package/dist/telemetry/ingestion-server.js.map +1 -0
- package/dist/telemetry/log-turn-analyzer.d.ts +35 -0
- package/dist/telemetry/log-turn-analyzer.d.ts.map +1 -0
- package/dist/telemetry/log-turn-analyzer.js +132 -0
- package/dist/telemetry/log-turn-analyzer.js.map +1 -0
- package/dist/telemetry/normalizer.d.ts +43 -0
- package/dist/telemetry/normalizer.d.ts.map +1 -0
- package/dist/telemetry/normalizer.js +320 -0
- package/dist/telemetry/normalizer.js.map +1 -0
- package/dist/telemetry/recommender.d.ts +116 -0
- package/dist/telemetry/recommender.d.ts.map +1 -0
- package/dist/telemetry/recommender.js +532 -0
- package/dist/telemetry/recommender.js.map +1 -0
- package/dist/telemetry/source-detector.d.ts +19 -0
- package/dist/telemetry/source-detector.d.ts.map +1 -0
- package/dist/telemetry/source-detector.js +73 -0
- package/dist/telemetry/source-detector.js.map +1 -0
- package/dist/telemetry/task-baselines.d.ts +30 -0
- package/dist/telemetry/task-baselines.d.ts.map +1 -0
- package/dist/telemetry/task-baselines.js +44 -0
- package/dist/telemetry/task-baselines.js.map +1 -0
- package/dist/telemetry/telemetry-pipeline.d.ts +122 -0
- package/dist/telemetry/telemetry-pipeline.d.ts.map +1 -0
- package/dist/telemetry/telemetry-pipeline.js +349 -0
- package/dist/telemetry/telemetry-pipeline.js.map +1 -0
- package/dist/telemetry/timestamp-normalizer.d.ts +32 -0
- package/dist/telemetry/timestamp-normalizer.d.ts.map +1 -0
- package/dist/telemetry/timestamp-normalizer.js +133 -0
- package/dist/telemetry/timestamp-normalizer.js.map +1 -0
- package/dist/telemetry/token-extractor.d.ts +57 -0
- package/dist/telemetry/token-extractor.d.ts.map +1 -0
- package/dist/telemetry/token-extractor.js +200 -0
- package/dist/telemetry/token-extractor.js.map +1 -0
- package/dist/telemetry/turn-analyzer.d.ts +34 -0
- package/dist/telemetry/turn-analyzer.d.ts.map +1 -0
- package/dist/telemetry/turn-analyzer.js +101 -0
- package/dist/telemetry/turn-analyzer.js.map +1 -0
- package/dist/telemetry/types.d.ts +456 -0
- package/dist/telemetry/types.d.ts.map +1 -0
- package/dist/telemetry/types.js +186 -0
- package/dist/telemetry/types.js.map +1 -0
- package/dist/types.d.ts +80 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/version-manager/index.d.ts +11 -0
- package/dist/version-manager/index.d.ts.map +1 -0
- package/dist/version-manager/index.js +8 -0
- package/dist/version-manager/index.js.map +1 -0
- package/dist/version-manager/update-checker.d.ts +44 -0
- package/dist/version-manager/update-checker.d.ts.map +1 -0
- package/dist/version-manager/update-checker.js +171 -0
- package/dist/version-manager/update-checker.js.map +1 -0
- package/dist/version-manager/version-cache.d.ts +42 -0
- package/dist/version-manager/version-cache.d.ts.map +1 -0
- package/dist/version-manager/version-cache.js +69 -0
- package/dist/version-manager/version-cache.js.map +1 -0
- package/dist/version-manager/version-manager-impl.d.ts +81 -0
- package/dist/version-manager/version-manager-impl.d.ts.map +1 -0
- package/dist/version-manager/version-manager-impl.js +223 -0
- package/dist/version-manager/version-manager-impl.js.map +1 -0
- package/dist/version-manager/version-manager.d.ts +70 -0
- package/dist/version-manager/version-manager.d.ts.map +1 -0
- package/dist/version-manager/version-manager.js +8 -0
- package/dist/version-manager/version-manager.js.map +1 -0
- package/package.json +27 -0
|
@@ -0,0 +1,532 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recommender — analyzes telemetry context and generates actionable recommendations.
|
|
3
|
+
*
|
|
4
|
+
* Implements 9 rules across three categories:
|
|
5
|
+
* - Consumer rules: biggest_consumers, large_file_reads, expensive_bash, repeated_tool_calls
|
|
6
|
+
* - Context/trend rules: context_growth_spike, growing_categories
|
|
7
|
+
* - Efficiency rules: cache_efficiency, per_model_comparison, cache_delta_regression
|
|
8
|
+
*
|
|
9
|
+
* Architecture constraints:
|
|
10
|
+
* - Pure analysis service — no DB access; caller assembles RecommenderContext
|
|
11
|
+
* - Constructor injection: accepts ILogger (defaults to console)
|
|
12
|
+
* - No Math.random() or Date.now() — all timestamps injected via context.generatedAt
|
|
13
|
+
* - ID generation: sha256(ruleId:storyKey:actionTarget:index) via node:crypto
|
|
14
|
+
*
|
|
15
|
+
* Migrated to @substrate-ai/core in story 41-6b.
|
|
16
|
+
*/
|
|
17
|
+
import { createHash } from 'node:crypto';
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Recommender
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
export class Recommender {
|
|
22
|
+
_logger;
|
|
23
|
+
constructor(logger) {
|
|
24
|
+
this._logger = logger ?? console;
|
|
25
|
+
}
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Public API
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/**
|
|
30
|
+
* Run all rules against the given context and return sorted recommendations.
|
|
31
|
+
* Output is sorted: critical → warning → info, then by potentialSavingsTokens descending.
|
|
32
|
+
* No Date.now() or Math.random() is called — generatedAt comes from context.
|
|
33
|
+
*/
|
|
34
|
+
analyze(context) {
|
|
35
|
+
const allRecs = [
|
|
36
|
+
...this._runBiggestConsumers(context),
|
|
37
|
+
...this._runExpensiveBash(context),
|
|
38
|
+
...this._runLargeFileReads(context),
|
|
39
|
+
...this._runRepeatedToolCalls(context),
|
|
40
|
+
...this._runContextGrowthSpikes(context),
|
|
41
|
+
...this._runGrowingCategories(context),
|
|
42
|
+
...this._runCacheEfficiency(context),
|
|
43
|
+
...this._runModelComparison(context),
|
|
44
|
+
...this._runCacheDeltaRegression(context),
|
|
45
|
+
];
|
|
46
|
+
// Sort: critical first, then warning, then info; within tier by potentialSavingsTokens desc
|
|
47
|
+
const severityOrder = {
|
|
48
|
+
critical: 0,
|
|
49
|
+
warning: 1,
|
|
50
|
+
info: 2,
|
|
51
|
+
};
|
|
52
|
+
return allRecs.sort((a, b) => {
|
|
53
|
+
const sA = severityOrder[a.severity];
|
|
54
|
+
const sB = severityOrder[b.severity];
|
|
55
|
+
if (sA !== sB)
|
|
56
|
+
return sA - sB;
|
|
57
|
+
const savA = a.potentialSavingsTokens ?? 0;
|
|
58
|
+
const savB = b.potentialSavingsTokens ?? 0;
|
|
59
|
+
return savB - savA;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Helpers
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
/**
|
|
66
|
+
* Generate a 16-char hex ID from the sha256 of `ruleId:storyKey:actionTarget:index`.
|
|
67
|
+
*/
|
|
68
|
+
_makeId(ruleId, storyKey, actionTarget, index) {
|
|
69
|
+
return createHash('sha256')
|
|
70
|
+
.update(`${ruleId}:${storyKey}:${actionTarget}:${index}`)
|
|
71
|
+
.digest('hex')
|
|
72
|
+
.slice(0, 16);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Map a token percentage to a severity level.
|
|
76
|
+
* >25% → critical, >10% → warning, ≤10% → info.
|
|
77
|
+
*/
|
|
78
|
+
_assignSeverity(tokenPercent) {
|
|
79
|
+
if (tokenPercent > 25)
|
|
80
|
+
return 'critical';
|
|
81
|
+
if (tokenPercent > 10)
|
|
82
|
+
return 'warning';
|
|
83
|
+
return 'info';
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Compute total tokens across all spans. Guards against empty arrays.
|
|
87
|
+
*/
|
|
88
|
+
_totalSpanTokens(spans) {
|
|
89
|
+
return spans.reduce((sum, s) => sum + s.inputTokens + s.outputTokens, 0);
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// Rule: biggest_consumers
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
/**
|
|
95
|
+
* Minimum absolute token count for a consumer to be flagged.
|
|
96
|
+
* Below this, the consumer is too small to be actionable regardless of percentage.
|
|
97
|
+
*/
|
|
98
|
+
static MIN_SIGNIFICANT_TOKENS = 10_000;
|
|
99
|
+
/**
|
|
100
|
+
* Identify top 3 token consumers (by inputTokens + outputTokens) where pct >5%
|
|
101
|
+
* AND absolute tokens exceed MIN_SIGNIFICANT_TOKENS.
|
|
102
|
+
*
|
|
103
|
+
* Filters out model-only consumers (empty toolName, format "model|") since those
|
|
104
|
+
* just indicate which model ran — not an actionable optimization target.
|
|
105
|
+
*
|
|
106
|
+
* Severity factors both percentage share and absolute magnitude:
|
|
107
|
+
* - percentage-based tier via _assignSeverity()
|
|
108
|
+
* - capped at 'warning' when absolute tokens < 50,000
|
|
109
|
+
* - capped at 'info' when absolute tokens < 20,000
|
|
110
|
+
*/
|
|
111
|
+
_runBiggestConsumers(ctx) {
|
|
112
|
+
const { consumers, storyKey, sprintId, generatedAt } = ctx;
|
|
113
|
+
if (consumers.length === 0)
|
|
114
|
+
return [];
|
|
115
|
+
const grandTotal = consumers.reduce((sum, c) => sum + c.totalTokens, 0);
|
|
116
|
+
if (grandTotal === 0)
|
|
117
|
+
return [];
|
|
118
|
+
const sorted = [...consumers].sort((a, b) => b.totalTokens - a.totalTokens);
|
|
119
|
+
const top3 = sorted.slice(0, 3).filter((c) => {
|
|
120
|
+
// Must exceed both percentage and absolute thresholds
|
|
121
|
+
if (c.percentage <= 5)
|
|
122
|
+
return false;
|
|
123
|
+
if (c.totalTokens < Recommender.MIN_SIGNIFICANT_TOKENS)
|
|
124
|
+
return false;
|
|
125
|
+
// Filter out model-only consumers (format: "operationName|" with empty toolName)
|
|
126
|
+
// These just identify which model ran, not an actionable operation
|
|
127
|
+
if (c.consumerKey.endsWith('|') && !c.consumerKey.includes('|', 0))
|
|
128
|
+
return false;
|
|
129
|
+
const parts = c.consumerKey.split('|');
|
|
130
|
+
if (parts.length === 2 && parts[1] === '')
|
|
131
|
+
return false;
|
|
132
|
+
return true;
|
|
133
|
+
});
|
|
134
|
+
return top3.map((consumer, index) => {
|
|
135
|
+
const pct = consumer.percentage;
|
|
136
|
+
let severity = this._assignSeverity(pct);
|
|
137
|
+
// Cap severity based on absolute token magnitude
|
|
138
|
+
if (consumer.totalTokens < 20_000 && severity !== 'info')
|
|
139
|
+
severity = 'info';
|
|
140
|
+
else if (consumer.totalTokens < 50_000 && severity === 'critical')
|
|
141
|
+
severity = 'warning';
|
|
142
|
+
const actionTarget = consumer.consumerKey;
|
|
143
|
+
const id = this._makeId('biggest_consumers', storyKey, actionTarget, index);
|
|
144
|
+
return {
|
|
145
|
+
id,
|
|
146
|
+
storyKey,
|
|
147
|
+
sprintId,
|
|
148
|
+
ruleId: 'biggest_consumers',
|
|
149
|
+
severity,
|
|
150
|
+
title: `High token consumer: ${consumer.consumerKey}`,
|
|
151
|
+
description: `"${consumer.consumerKey}" consumed ${consumer.totalTokens.toLocaleString()} tokens (${pct.toFixed(1)}% of total). Consider reducing the frequency or size of this operation.`,
|
|
152
|
+
potentialSavingsTokens: Math.round(consumer.totalTokens * 0.3),
|
|
153
|
+
actionTarget,
|
|
154
|
+
generatedAt,
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
// Rule: large_file_reads
|
|
160
|
+
// ---------------------------------------------------------------------------
|
|
161
|
+
/**
|
|
162
|
+
* Flag file-read spans with inputTokens > 3000.
|
|
163
|
+
* Suggest using line ranges to reduce token count.
|
|
164
|
+
*/
|
|
165
|
+
_runLargeFileReads(ctx) {
|
|
166
|
+
const { allSpans, storyKey, sprintId, generatedAt } = ctx;
|
|
167
|
+
if (allSpans.length === 0)
|
|
168
|
+
return [];
|
|
169
|
+
const grandTotal = this._totalSpanTokens(allSpans);
|
|
170
|
+
const largReads = allSpans.filter((s) => s.operationName === 'file_read' && s.inputTokens > 3000);
|
|
171
|
+
return largReads.map((span, index) => {
|
|
172
|
+
const pct = grandTotal > 0 ? ((span.inputTokens + span.outputTokens) / grandTotal) * 100 : 0;
|
|
173
|
+
const severity = this._assignSeverity(pct);
|
|
174
|
+
const actionTarget = span.attributes?.['file.path'] ?? span.name;
|
|
175
|
+
const id = this._makeId('large_file_reads', storyKey, actionTarget, index);
|
|
176
|
+
return {
|
|
177
|
+
id,
|
|
178
|
+
storyKey,
|
|
179
|
+
sprintId,
|
|
180
|
+
ruleId: 'large_file_reads',
|
|
181
|
+
severity,
|
|
182
|
+
title: `Large file read: ${actionTarget}`,
|
|
183
|
+
description: `File read of "${actionTarget}" consumed ${span.inputTokens.toLocaleString()} input tokens. Consider specifying line ranges (e.g., offset/limit) to reduce context size.`,
|
|
184
|
+
potentialSavingsTokens: Math.round(span.inputTokens * 0.5),
|
|
185
|
+
actionTarget,
|
|
186
|
+
generatedAt,
|
|
187
|
+
};
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Rule: expensive_bash
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
/**
|
|
194
|
+
* Flag bash/execute_command spans with outputTokens > 3000.
|
|
195
|
+
* Suggest filtering or truncating command output.
|
|
196
|
+
*/
|
|
197
|
+
_runExpensiveBash(ctx) {
|
|
198
|
+
const { allSpans, storyKey, sprintId, generatedAt } = ctx;
|
|
199
|
+
if (allSpans.length === 0)
|
|
200
|
+
return [];
|
|
201
|
+
const grandTotal = this._totalSpanTokens(allSpans);
|
|
202
|
+
const expensiveBash = allSpans.filter((s) => (s.attributes?.['tool.name'] === 'bash' ||
|
|
203
|
+
s.attributes?.['tool.name'] === 'execute_command' ||
|
|
204
|
+
s.name === 'bash' ||
|
|
205
|
+
s.name === 'execute_command' ||
|
|
206
|
+
(s.operationName !== undefined &&
|
|
207
|
+
(s.operationName === 'bash' || s.operationName === 'execute_command'))) &&
|
|
208
|
+
s.outputTokens > 3000);
|
|
209
|
+
return expensiveBash.map((span, index) => {
|
|
210
|
+
const pct = grandTotal > 0 ? ((span.inputTokens + span.outputTokens) / grandTotal) * 100 : 0;
|
|
211
|
+
const severity = this._assignSeverity(pct);
|
|
212
|
+
const actionTarget = span.attributes?.['bash.command']
|
|
213
|
+
?? span.name
|
|
214
|
+
?? 'bash';
|
|
215
|
+
const id = this._makeId('expensive_bash', storyKey, actionTarget, index);
|
|
216
|
+
return {
|
|
217
|
+
id,
|
|
218
|
+
storyKey,
|
|
219
|
+
sprintId,
|
|
220
|
+
ruleId: 'expensive_bash',
|
|
221
|
+
severity,
|
|
222
|
+
title: `Expensive bash output: ${actionTarget}`,
|
|
223
|
+
description: `Bash command "${actionTarget}" produced ${span.outputTokens.toLocaleString()} output tokens. Consider filtering output (e.g., piping to head/grep) to reduce token consumption.`,
|
|
224
|
+
potentialSavingsTokens: Math.round(span.outputTokens * 0.5),
|
|
225
|
+
actionTarget,
|
|
226
|
+
generatedAt,
|
|
227
|
+
};
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// Rule: repeated_tool_calls
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
/**
|
|
234
|
+
* Detect tool calls with the same actionTarget appearing more than once.
|
|
235
|
+
* Suggests caching the result to avoid redundant token consumption.
|
|
236
|
+
*/
|
|
237
|
+
_runRepeatedToolCalls(ctx) {
|
|
238
|
+
const { turns, storyKey, sprintId, generatedAt, allSpans } = ctx;
|
|
239
|
+
// Collect all child spans from turns plus allSpans as fallback
|
|
240
|
+
const allChildSpans = [];
|
|
241
|
+
for (const turn of turns) {
|
|
242
|
+
for (const child of turn.childSpans) {
|
|
243
|
+
const entry = {
|
|
244
|
+
name: child.name,
|
|
245
|
+
};
|
|
246
|
+
if (child.toolName !== undefined)
|
|
247
|
+
entry.toolName = child.toolName;
|
|
248
|
+
allChildSpans.push(entry);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// Also include allSpans if turns childSpans are empty
|
|
252
|
+
if (allChildSpans.length === 0 && allSpans.length > 0) {
|
|
253
|
+
for (const span of allSpans) {
|
|
254
|
+
const spanToolName = span.attributes?.['tool.name'];
|
|
255
|
+
const spanFilePath = span.attributes?.['file.path'];
|
|
256
|
+
const entry = {
|
|
257
|
+
name: span.name,
|
|
258
|
+
};
|
|
259
|
+
if (spanToolName !== undefined)
|
|
260
|
+
entry.toolName = spanToolName;
|
|
261
|
+
if (spanFilePath !== undefined)
|
|
262
|
+
entry.actionTarget = spanFilePath;
|
|
263
|
+
allChildSpans.push(entry);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Group by toolName:actionTarget
|
|
267
|
+
const groups = new Map();
|
|
268
|
+
for (const span of allChildSpans) {
|
|
269
|
+
const key = `${span.toolName ?? ''}:${span.actionTarget ?? span.name}`;
|
|
270
|
+
groups.set(key, (groups.get(key) ?? 0) + 1);
|
|
271
|
+
}
|
|
272
|
+
const recommendations = [];
|
|
273
|
+
let index = 0;
|
|
274
|
+
for (const [key, count] of groups) {
|
|
275
|
+
if (count > 1) {
|
|
276
|
+
const id = this._makeId('repeated_tool_calls', storyKey, key, index);
|
|
277
|
+
recommendations.push({
|
|
278
|
+
id,
|
|
279
|
+
storyKey,
|
|
280
|
+
sprintId,
|
|
281
|
+
ruleId: 'repeated_tool_calls',
|
|
282
|
+
severity: 'warning',
|
|
283
|
+
title: `Repeated tool call: ${key}`,
|
|
284
|
+
description: `"${key}" was invoked ${count} times. Consider caching the result after the first call to avoid redundant token consumption.`,
|
|
285
|
+
actionTarget: key,
|
|
286
|
+
generatedAt,
|
|
287
|
+
});
|
|
288
|
+
index++;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return recommendations;
|
|
292
|
+
}
|
|
293
|
+
// ---------------------------------------------------------------------------
|
|
294
|
+
// Rule: context_growth_spike
|
|
295
|
+
// ---------------------------------------------------------------------------
|
|
296
|
+
/**
|
|
297
|
+
* Flag turns where isContextSpike is true.
|
|
298
|
+
* Severity is always at least 'warning'.
|
|
299
|
+
*/
|
|
300
|
+
_runContextGrowthSpikes(ctx) {
|
|
301
|
+
const { turns, storyKey, sprintId, generatedAt, allSpans } = ctx;
|
|
302
|
+
if (turns.length === 0)
|
|
303
|
+
return [];
|
|
304
|
+
const grandTotal = this._totalSpanTokens(allSpans);
|
|
305
|
+
const spiketurns = turns.filter((t) => t.isContextSpike);
|
|
306
|
+
return spiketurns.map((turn, index) => {
|
|
307
|
+
const pct = grandTotal > 0 ? ((turn.inputTokens + turn.outputTokens) / grandTotal) * 100 : 0;
|
|
308
|
+
// context_growth_spike is always at least 'warning'
|
|
309
|
+
const baseSeverity = this._assignSeverity(pct);
|
|
310
|
+
const severity = baseSeverity === 'info' ? 'warning' : baseSeverity;
|
|
311
|
+
// Sort child spans by token consumption, take top 3
|
|
312
|
+
const topContributors = [...turn.childSpans]
|
|
313
|
+
.sort((a, b) => b.inputTokens + b.outputTokens - (a.inputTokens + a.outputTokens))
|
|
314
|
+
.slice(0, 3)
|
|
315
|
+
.map((c) => c.name);
|
|
316
|
+
const actionTarget = `turn:${turn.turnNumber}`;
|
|
317
|
+
const id = this._makeId('context_growth_spike', storyKey, actionTarget, index);
|
|
318
|
+
return {
|
|
319
|
+
id,
|
|
320
|
+
storyKey,
|
|
321
|
+
sprintId,
|
|
322
|
+
ruleId: 'context_growth_spike',
|
|
323
|
+
severity,
|
|
324
|
+
title: `Context spike at turn ${turn.turnNumber}`,
|
|
325
|
+
description: `Turn ${turn.turnNumber} had a context spike with ${turn.inputTokens.toLocaleString()} input tokens. Top contributors: ${topContributors.length > 0 ? topContributors.join(', ') : 'none identified'}. Consider compressing or evicting context before this turn.`,
|
|
326
|
+
potentialSavingsTokens: Math.round(turn.contextDelta * 0.3),
|
|
327
|
+
actionTarget,
|
|
328
|
+
generatedAt,
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
// Rule: growing_categories
|
|
334
|
+
// ---------------------------------------------------------------------------
|
|
335
|
+
/**
|
|
336
|
+
* Categories whose growth is inherent to normal agentic work and not actionable.
|
|
337
|
+
* tool_outputs grows as the agent reads files, runs commands, etc. — expected behavior.
|
|
338
|
+
* conversation_history grows naturally as conversations progress.
|
|
339
|
+
*/
|
|
340
|
+
static EXPECTED_GROWTH_CATEGORIES = new Set([
|
|
341
|
+
'tool_outputs',
|
|
342
|
+
'conversation_history',
|
|
343
|
+
]);
|
|
344
|
+
/**
|
|
345
|
+
* Flag semantic categories with trend === 'growing'.
|
|
346
|
+
* Severity is 'info' by default; 'warning' if percentage > 25%.
|
|
347
|
+
* Skips categories whose growth is inherent to normal agentic work.
|
|
348
|
+
*/
|
|
349
|
+
_runGrowingCategories(ctx) {
|
|
350
|
+
const { categories, storyKey, sprintId, generatedAt } = ctx;
|
|
351
|
+
if (categories.length === 0)
|
|
352
|
+
return [];
|
|
353
|
+
const growing = categories.filter((c) => c.trend === 'growing' && !Recommender.EXPECTED_GROWTH_CATEGORIES.has(c.category));
|
|
354
|
+
return growing.map((cat, index) => {
|
|
355
|
+
// growing_categories: floor is 'info'; only 'warning' if pct > 25
|
|
356
|
+
const severity = cat.percentage > 25 ? 'warning' : 'info';
|
|
357
|
+
const actionTarget = cat.category;
|
|
358
|
+
const id = this._makeId('growing_categories', storyKey, actionTarget, index);
|
|
359
|
+
return {
|
|
360
|
+
id,
|
|
361
|
+
storyKey,
|
|
362
|
+
sprintId,
|
|
363
|
+
ruleId: 'growing_categories',
|
|
364
|
+
severity,
|
|
365
|
+
title: `Growing category: ${cat.category}`,
|
|
366
|
+
description: `The "${cat.category}" category is growing across turns, currently at ${cat.percentage.toFixed(1)}% of total tokens (${cat.totalTokens.toLocaleString()} tokens). This trend suggests increasing context pressure from this source.`,
|
|
367
|
+
potentialSavingsTokens: Math.round(cat.totalTokens * 0.2),
|
|
368
|
+
actionTarget,
|
|
369
|
+
generatedAt,
|
|
370
|
+
};
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
// ---------------------------------------------------------------------------
|
|
374
|
+
// Rule: cache_efficiency
|
|
375
|
+
// ---------------------------------------------------------------------------
|
|
376
|
+
/**
|
|
377
|
+
* If cache hit rate < 30%, flag the worst-performing operations and compute
|
|
378
|
+
* potential savings as totalCacheMissTokens * 0.5.
|
|
379
|
+
*/
|
|
380
|
+
_runCacheEfficiency(ctx) {
|
|
381
|
+
const { efficiencyScore, allSpans, storyKey, sprintId, generatedAt } = ctx;
|
|
382
|
+
// Guard against NaN cache hit rate — treat as 0
|
|
383
|
+
const cacheHitRate = isNaN(efficiencyScore.avgCacheHitRate)
|
|
384
|
+
? 0
|
|
385
|
+
: efficiencyScore.avgCacheHitRate;
|
|
386
|
+
if (cacheHitRate >= 0.3)
|
|
387
|
+
return [];
|
|
388
|
+
if (allSpans.length === 0)
|
|
389
|
+
return [];
|
|
390
|
+
// Compute total cache-miss tokens across all spans
|
|
391
|
+
const totalCacheMissTokens = allSpans.reduce((sum, s) => {
|
|
392
|
+
const missTokens = s.inputTokens - s.cacheReadTokens;
|
|
393
|
+
return sum + Math.max(0, missTokens);
|
|
394
|
+
}, 0);
|
|
395
|
+
if (totalCacheMissTokens === 0)
|
|
396
|
+
return [];
|
|
397
|
+
const potentialSavingsTokens = Math.round(totalCacheMissTokens * 0.5);
|
|
398
|
+
// Find top 3 worst spans by individual cache hit rate
|
|
399
|
+
const spansWithRate = allSpans
|
|
400
|
+
.filter((s) => s.inputTokens > 0)
|
|
401
|
+
.map((s) => ({
|
|
402
|
+
span: s,
|
|
403
|
+
hitRate: s.cacheReadTokens / s.inputTokens,
|
|
404
|
+
}))
|
|
405
|
+
.sort((a, b) => a.hitRate - b.hitRate)
|
|
406
|
+
.slice(0, 3);
|
|
407
|
+
const worstOps = spansWithRate.map((e) => e.span.name).join(', ');
|
|
408
|
+
const actionTarget = worstOps || 'unknown';
|
|
409
|
+
const id = this._makeId('cache_efficiency', storyKey, actionTarget, 0);
|
|
410
|
+
this._logger.debug({ storyKey, cacheHitRate, potentialSavingsTokens }, 'cache_efficiency recommendation generated');
|
|
411
|
+
return [
|
|
412
|
+
{
|
|
413
|
+
id,
|
|
414
|
+
storyKey,
|
|
415
|
+
sprintId,
|
|
416
|
+
ruleId: 'cache_efficiency',
|
|
417
|
+
severity: 'warning',
|
|
418
|
+
title: 'Low cache hit rate',
|
|
419
|
+
description: `Overall cache hit rate is ${(cacheHitRate * 100).toFixed(1)}% (below 30% threshold). Worst performing operations: ${worstOps || 'none identified'}. Potential savings if hit rate reached 50%: ${potentialSavingsTokens.toLocaleString()} tokens.`,
|
|
420
|
+
potentialSavingsTokens,
|
|
421
|
+
actionTarget,
|
|
422
|
+
generatedAt,
|
|
423
|
+
},
|
|
424
|
+
];
|
|
425
|
+
}
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
// Rule: per_model_comparison
|
|
428
|
+
// ---------------------------------------------------------------------------
|
|
429
|
+
/**
|
|
430
|
+
* Models known to be intentionally routed for lightweight tasks.
|
|
431
|
+
* These should not be flagged as "underperforming" — the orchestrator chose them
|
|
432
|
+
* deliberately for cost/speed reasons, not as a performance optimization target.
|
|
433
|
+
*/
|
|
434
|
+
static INTENTIONAL_LIGHTWEIGHT_MODELS = new Set([
|
|
435
|
+
'claude-haiku-4-5-20251001',
|
|
436
|
+
'claude-haiku-4-5',
|
|
437
|
+
]);
|
|
438
|
+
/**
|
|
439
|
+
* If more than one model is present, flag the underperforming model.
|
|
440
|
+
* Severity is 'info' by default; 'warning' if cache efficiency gap > 20pp.
|
|
441
|
+
* Skips flagging models that are intentionally routed for lightweight tasks.
|
|
442
|
+
*/
|
|
443
|
+
_runModelComparison(ctx) {
|
|
444
|
+
const { efficiencyScore, storyKey, sprintId, generatedAt } = ctx;
|
|
445
|
+
const models = efficiencyScore.perModelBreakdown;
|
|
446
|
+
if (models.length <= 1)
|
|
447
|
+
return [];
|
|
448
|
+
// Find best and worst by cache hit rate
|
|
449
|
+
const sorted = [...models].sort((a, b) => b.cacheHitRate - a.cacheHitRate);
|
|
450
|
+
const best = sorted[0];
|
|
451
|
+
const worst = sorted[sorted.length - 1];
|
|
452
|
+
// Don't flag lightweight models that are intentionally routed
|
|
453
|
+
if (Recommender.INTENTIONAL_LIGHTWEIGHT_MODELS.has(worst.model))
|
|
454
|
+
return [];
|
|
455
|
+
// Don't compare a model to itself
|
|
456
|
+
if (best.model === worst.model)
|
|
457
|
+
return [];
|
|
458
|
+
const gapPP = (best.cacheHitRate - worst.cacheHitRate) * 100;
|
|
459
|
+
const severity = gapPP > 20 ? 'warning' : 'info';
|
|
460
|
+
const actionTarget = worst.model;
|
|
461
|
+
const id = this._makeId('per_model_comparison', storyKey, actionTarget, 0);
|
|
462
|
+
return [
|
|
463
|
+
{
|
|
464
|
+
id,
|
|
465
|
+
storyKey,
|
|
466
|
+
sprintId,
|
|
467
|
+
ruleId: 'per_model_comparison',
|
|
468
|
+
severity,
|
|
469
|
+
title: `Underperforming model: ${worst.model}`,
|
|
470
|
+
description: `Model "${worst.model}" has a cache hit rate of ${(worst.cacheHitRate * 100).toFixed(1)}% vs. "${best.model}" at ${(best.cacheHitRate * 100).toFixed(1)}% (gap: ${gapPP.toFixed(1)} percentage points). Consider routing tasks to the higher-performing model.`,
|
|
471
|
+
actionTarget,
|
|
472
|
+
generatedAt,
|
|
473
|
+
},
|
|
474
|
+
];
|
|
475
|
+
}
|
|
476
|
+
// ---------------------------------------------------------------------------
|
|
477
|
+
// Rule: cache_delta_regression
|
|
478
|
+
// ---------------------------------------------------------------------------
|
|
479
|
+
/**
|
|
480
|
+
* Detect significant cache hit rate drops between consecutive dispatches.
|
|
481
|
+
* >30pp drop → warning; >50pp drop → critical.
|
|
482
|
+
* Requires dispatchScores with at least 2 entries; otherwise returns [].
|
|
483
|
+
*/
|
|
484
|
+
_runCacheDeltaRegression(ctx) {
|
|
485
|
+
const { dispatchScores, storyKey, sprintId, generatedAt } = ctx;
|
|
486
|
+
if (dispatchScores === undefined || dispatchScores.length < 2)
|
|
487
|
+
return [];
|
|
488
|
+
// Sort chronologically — dispatch timestamps are set sequentially in pipeline
|
|
489
|
+
const sorted = [...dispatchScores].sort((a, b) => a.timestamp - b.timestamp);
|
|
490
|
+
const recs = [];
|
|
491
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
492
|
+
const prev = sorted[i];
|
|
493
|
+
const curr = sorted[i + 1];
|
|
494
|
+
const deltaPP = (prev.avgCacheHitRate - curr.avgCacheHitRate) * 100;
|
|
495
|
+
if (deltaPP <= 30)
|
|
496
|
+
continue;
|
|
497
|
+
const severity = deltaPP > 50 ? 'critical' : 'warning';
|
|
498
|
+
const prevId = prev.dispatchId ?? `dispatch-${i}`;
|
|
499
|
+
const currId = curr.dispatchId ?? `dispatch-${i + 1}`;
|
|
500
|
+
const pairKey = `${prevId}→${currId}`;
|
|
501
|
+
const id = this._makeId('cache_delta_regression', storyKey, pairKey, i);
|
|
502
|
+
recs.push({
|
|
503
|
+
id,
|
|
504
|
+
storyKey,
|
|
505
|
+
sprintId,
|
|
506
|
+
ruleId: 'cache_delta_regression',
|
|
507
|
+
severity,
|
|
508
|
+
title: `Cache regression between dispatches: ${pairKey}`,
|
|
509
|
+
description: `Cache hit rate dropped ${deltaPP.toFixed(1)} percentage points between dispatch "${prevId}" (${(prev.avgCacheHitRate * 100).toFixed(1)}%) and "${currId}" (${(curr.avgCacheHitRate * 100).toFixed(1)}%). This likely indicates a prompt prefix change broke cache alignment. Investigate whether the system prompt or context prefix was restructured between these dispatches.`,
|
|
510
|
+
actionTarget: pairKey,
|
|
511
|
+
generatedAt,
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
return recs;
|
|
515
|
+
}
|
|
516
|
+
// ---------------------------------------------------------------------------
|
|
517
|
+
// Internal rule helpers (type narrowing)
|
|
518
|
+
// ---------------------------------------------------------------------------
|
|
519
|
+
_isToolNameMatch(span) {
|
|
520
|
+
const toolName = span.attributes?.['tool.name'];
|
|
521
|
+
return (toolName === 'bash' ||
|
|
522
|
+
toolName === 'execute_command' ||
|
|
523
|
+
span.name === 'bash' ||
|
|
524
|
+
span.name === 'execute_command' ||
|
|
525
|
+
span.operationName === 'bash' ||
|
|
526
|
+
span.operationName === 'execute_command');
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
// Re-expose _isToolNameMatch inline to keep _runExpensiveBash self-contained
|
|
530
|
+
// (the method above is still accessible as a private helper if needed)
|
|
531
|
+
void ((_) => _); // prevent unused-import lint
|
|
532
|
+
//# sourceMappingURL=recommender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recommender.js","sourceRoot":"","sources":["../../src/telemetry/recommender.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* source-detector — detects the OTLP source from a raw payload.
|
|
3
|
+
*
|
|
4
|
+
* Inspects the `service.name` and `telemetry.sdk.name` resource attributes
|
|
5
|
+
* from either `resourceSpans` or `resourceLogs` envelope formats and maps
|
|
6
|
+
* the values to a known source identifier.
|
|
7
|
+
*/
|
|
8
|
+
export type { OtlpSource } from './types.js';
|
|
9
|
+
import type { OtlpSource } from './types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Detect the OTLP source from a raw payload.
|
|
12
|
+
*
|
|
13
|
+
* Inspects `service.name` and `telemetry.sdk.name` from resource attributes
|
|
14
|
+
* in both `resourceSpans` and `resourceLogs` envelope formats.
|
|
15
|
+
*
|
|
16
|
+
* Returns 'unknown' when no match is found or input is malformed.
|
|
17
|
+
*/
|
|
18
|
+
export declare function detectSource(body: unknown): OtlpSource;
|
|
19
|
+
//# sourceMappingURL=source-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-detector.d.ts","sourceRoot":"","sources":["../../src/telemetry/source-detector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAoF5C;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAQtD"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* source-detector — detects the OTLP source from a raw payload.
|
|
3
|
+
*
|
|
4
|
+
* Inspects the `service.name` and `telemetry.sdk.name` resource attributes
|
|
5
|
+
* from either `resourceSpans` or `resourceLogs` envelope formats and maps
|
|
6
|
+
* the values to a known source identifier.
|
|
7
|
+
*/
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Detection table
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
const SOURCE_DETECTION_TABLE = [
|
|
12
|
+
{ pattern: /claude[\s-]?code/i, source: 'claude-code' },
|
|
13
|
+
{ pattern: /claude/i, source: 'claude-code' },
|
|
14
|
+
{ pattern: /codex/i, source: 'codex' },
|
|
15
|
+
{ pattern: /openai/i, source: 'codex' },
|
|
16
|
+
{ pattern: /ollama|llama|local/i, source: 'local-llm' },
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Extract string values for service.name and telemetry.sdk.name from
|
|
20
|
+
* raw OTLP resource attributes, supporting both resourceSpans and resourceLogs.
|
|
21
|
+
*/
|
|
22
|
+
function extractAttributes(body) {
|
|
23
|
+
if (!body || typeof body !== 'object')
|
|
24
|
+
return [];
|
|
25
|
+
const values = [];
|
|
26
|
+
const keysOfInterest = ['service.name', 'telemetry.sdk.name'];
|
|
27
|
+
const extractFromResources = (resources) => {
|
|
28
|
+
if (!Array.isArray(resources))
|
|
29
|
+
return;
|
|
30
|
+
for (const entry of resources) {
|
|
31
|
+
if (!entry?.resource?.attributes)
|
|
32
|
+
continue;
|
|
33
|
+
for (const attr of entry.resource.attributes) {
|
|
34
|
+
if (!attr?.key || !keysOfInterest.includes(attr.key))
|
|
35
|
+
continue;
|
|
36
|
+
const v = attr.value;
|
|
37
|
+
if (!v)
|
|
38
|
+
continue;
|
|
39
|
+
const str = v.stringValue ??
|
|
40
|
+
(v.intValue !== undefined ? String(v.intValue) : undefined) ??
|
|
41
|
+
(v.doubleValue !== undefined ? String(v.doubleValue) : undefined);
|
|
42
|
+
if (str !== undefined)
|
|
43
|
+
values.push(str);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const payload = body;
|
|
48
|
+
extractFromResources(payload.resourceSpans);
|
|
49
|
+
extractFromResources(payload.resourceLogs);
|
|
50
|
+
return values;
|
|
51
|
+
}
|
|
52
|
+
// ---------------------------------------------------------------------------
|
|
53
|
+
// detectSource
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
/**
|
|
56
|
+
* Detect the OTLP source from a raw payload.
|
|
57
|
+
*
|
|
58
|
+
* Inspects `service.name` and `telemetry.sdk.name` from resource attributes
|
|
59
|
+
* in both `resourceSpans` and `resourceLogs` envelope formats.
|
|
60
|
+
*
|
|
61
|
+
* Returns 'unknown' when no match is found or input is malformed.
|
|
62
|
+
*/
|
|
63
|
+
export function detectSource(body) {
|
|
64
|
+
const values = extractAttributes(body);
|
|
65
|
+
for (const value of values) {
|
|
66
|
+
for (const { pattern, source } of SOURCE_DETECTION_TABLE) {
|
|
67
|
+
if (pattern.test(value))
|
|
68
|
+
return source;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return 'unknown';
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=source-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-detector.js","sourceRoot":"","sources":["../../src/telemetry/source-detector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAWH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,MAAM,sBAAsB,GAAmD;IAC7E,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,EAAE,aAAa,EAAE;IACvD,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE;IAC7C,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE;IACtC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE;IACvC,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,WAAW,EAAE;CACxD,CAAA;AAiCD;;;GAGG;AACH,SAAS,iBAAiB,CAAC,IAAa;IACtC,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAA;IAEhD,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,MAAM,cAAc,GAAG,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAA;IAE7D,MAAM,oBAAoB,GAAG,CAAC,SAA0C,EAAQ,EAAE;QAChF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,OAAM;QACrC,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;YAC9B,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU;gBAAE,SAAQ;YAC1C,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;gBAC7C,IAAI,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;oBAAE,SAAQ;gBAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA;gBACpB,IAAI,CAAC,CAAC;oBAAE,SAAQ;gBAChB,MAAM,GAAG,GACP,CAAC,CAAC,WAAW;oBACb,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;oBAC3D,CAAC,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;gBACnE,IAAI,GAAG,KAAK,SAAS;oBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACzC,CAAC;QACH,CAAC;IACH,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,IAAkD,CAAA;IAClE,oBAAoB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAA;IAC3C,oBAAoB,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAE1C,OAAO,MAAM,CAAA;AACf,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAa;IACxC,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAA;IACtC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,sBAAsB,EAAE,CAAC;YACzD,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,MAAM,CAAA;QACxC,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC"}
|