@dcyfr/ai 1.0.3 → 2.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/CHANGELOG.md +106 -0
- package/LICENSE +27 -1
- package/README.md +720 -9
- package/dist/ai/agents/agent-loader.d.ts +12 -0
- package/dist/ai/agents/agent-loader.d.ts.map +1 -1
- package/dist/ai/agents/agent-loader.js +74 -65
- package/dist/ai/agents/agent-loader.js.map +1 -1
- package/dist/ai/agents/agent-registry.d.ts +2 -0
- package/dist/ai/agents/agent-registry.d.ts.map +1 -1
- package/dist/ai/agents/agent-registry.js +15 -14
- package/dist/ai/agents/agent-registry.js.map +1 -1
- package/dist/ai/agents/agent-router.d.ts +20 -5
- package/dist/ai/agents/agent-router.d.ts.map +1 -1
- package/dist/ai/agents/agent-router.js +89 -43
- package/dist/ai/agents/agent-router.js.map +1 -1
- package/dist/ai/agents/index.d.ts +6 -1
- package/dist/ai/agents/index.d.ts.map +1 -1
- package/dist/ai/agents/index.js +9 -3
- package/dist/ai/agents/index.js.map +1 -1
- package/dist/ai/agents/instruction-template.d.ts +45 -0
- package/dist/ai/agents/instruction-template.d.ts.map +1 -0
- package/dist/ai/agents/instruction-template.js +197 -0
- package/dist/ai/agents/instruction-template.js.map +1 -0
- package/dist/ai/agents/persona-resolver.d.ts +90 -0
- package/dist/ai/agents/persona-resolver.d.ts.map +1 -0
- package/dist/ai/agents/persona-resolver.js +121 -0
- package/dist/ai/agents/persona-resolver.js.map +1 -0
- package/dist/ai/agents/schema.d.ts +166 -0
- package/dist/ai/agents/schema.d.ts.map +1 -0
- package/dist/ai/agents/schema.js +94 -0
- package/dist/ai/agents/schema.js.map +1 -0
- package/dist/ai/agents/types.d.ts +102 -0
- package/dist/ai/agents/types.d.ts.map +1 -1
- package/dist/ai/agents-builtin/architecture/index.js +3 -3
- package/dist/ai/agents-builtin/content/index.js +1 -1
- package/dist/ai/agents-builtin/data/index.js +1 -1
- package/dist/ai/agents-builtin/development/index.js +4 -4
- package/dist/ai/agents-builtin/devops/index.js +1 -1
- package/dist/ai/agents-builtin/index.js +33 -33
- package/dist/ai/agents-builtin/performance/index.js +1 -1
- package/dist/ai/agents-builtin/research/index.js +1 -1
- package/dist/ai/agents-builtin/security/index.js +1 -1
- package/dist/ai/agents-builtin/testing/index.js +2 -2
- package/dist/ai/config/loader.d.ts.map +1 -1
- package/dist/ai/config/loader.js +6 -3
- package/dist/ai/config/loader.js.map +1 -1
- package/dist/ai/config/schema.d.ts +242 -1156
- package/dist/ai/config/schema.d.ts.map +1 -1
- package/dist/ai/config/schema.js +69 -20
- package/dist/ai/config/schema.js.map +1 -1
- package/dist/ai/core/provider-registry.d.ts +32 -0
- package/dist/ai/core/provider-registry.d.ts.map +1 -1
- package/dist/ai/core/provider-registry.js +189 -14
- package/dist/ai/core/provider-registry.js.map +1 -1
- package/dist/ai/core/telemetry-engine.d.ts +26 -0
- package/dist/ai/core/telemetry-engine.d.ts.map +1 -1
- package/dist/ai/core/telemetry-engine.js +81 -1
- package/dist/ai/core/telemetry-engine.js.map +1 -1
- package/dist/ai/delegation/agent-registry.d.ts +143 -0
- package/dist/ai/delegation/agent-registry.d.ts.map +1 -0
- package/dist/ai/delegation/agent-registry.js +231 -0
- package/dist/ai/delegation/agent-registry.js.map +1 -0
- package/dist/ai/delegation/blast-radius-tracker.d.ts +65 -0
- package/dist/ai/delegation/blast-radius-tracker.d.ts.map +1 -0
- package/dist/ai/delegation/blast-radius-tracker.js +81 -0
- package/dist/ai/delegation/blast-radius-tracker.js.map +1 -0
- package/dist/ai/delegation/capability-bootstrap.d.ts +40 -0
- package/dist/ai/delegation/capability-bootstrap.d.ts.map +1 -0
- package/dist/ai/delegation/capability-bootstrap.js +431 -0
- package/dist/ai/delegation/capability-bootstrap.js.map +1 -0
- package/dist/ai/delegation/capability-registry.d.ts +81 -0
- package/dist/ai/delegation/capability-registry.d.ts.map +1 -0
- package/dist/ai/delegation/capability-registry.js +339 -0
- package/dist/ai/delegation/capability-registry.js.map +1 -0
- package/dist/ai/delegation/chain-tracker.d.ts +152 -0
- package/dist/ai/delegation/chain-tracker.d.ts.map +1 -0
- package/dist/ai/delegation/chain-tracker.js +336 -0
- package/dist/ai/delegation/chain-tracker.js.map +1 -0
- package/dist/ai/delegation/circuit-breaker.d.ts +59 -0
- package/dist/ai/delegation/circuit-breaker.d.ts.map +1 -0
- package/dist/ai/delegation/circuit-breaker.js +153 -0
- package/dist/ai/delegation/circuit-breaker.js.map +1 -0
- package/dist/ai/delegation/contract-manager.d.ts +415 -0
- package/dist/ai/delegation/contract-manager.d.ts.map +1 -0
- package/dist/ai/delegation/contract-manager.js +1258 -0
- package/dist/ai/delegation/contract-manager.js.map +1 -0
- package/dist/ai/delegation/delegation-manager.d.ts +505 -0
- package/dist/ai/delegation/delegation-manager.d.ts.map +1 -0
- package/dist/ai/delegation/delegation-manager.js +773 -0
- package/dist/ai/delegation/delegation-manager.js.map +1 -0
- package/dist/ai/delegation/event-schemas.d.ts +101 -0
- package/dist/ai/delegation/event-schemas.d.ts.map +1 -0
- package/dist/ai/delegation/event-schemas.js +59 -0
- package/dist/ai/delegation/event-schemas.js.map +1 -0
- package/dist/ai/delegation/execution-mode-dashboard.d.ts +109 -0
- package/dist/ai/delegation/execution-mode-dashboard.d.ts.map +1 -0
- package/dist/ai/delegation/execution-mode-dashboard.js +167 -0
- package/dist/ai/delegation/execution-mode-dashboard.js.map +1 -0
- package/dist/ai/delegation/feature-flags.d.ts +191 -0
- package/dist/ai/delegation/feature-flags.d.ts.map +1 -0
- package/dist/ai/delegation/feature-flags.js +332 -0
- package/dist/ai/delegation/feature-flags.js.map +1 -0
- package/dist/ai/delegation/index.d.ts +51 -0
- package/dist/ai/delegation/index.d.ts.map +1 -0
- package/dist/ai/delegation/index.js +39 -0
- package/dist/ai/delegation/index.js.map +1 -0
- package/dist/ai/delegation/middleware/chain-depth-middleware.d.ts +39 -0
- package/dist/ai/delegation/middleware/chain-depth-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/chain-depth-middleware.js +77 -0
- package/dist/ai/delegation/middleware/chain-depth-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/chain-tracker-middleware.d.ts +46 -0
- package/dist/ai/delegation/middleware/chain-tracker-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/chain-tracker-middleware.js +89 -0
- package/dist/ai/delegation/middleware/chain-tracker-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/content-policy-middleware.d.ts +31 -0
- package/dist/ai/delegation/middleware/content-policy-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/content-policy-middleware.js +82 -0
- package/dist/ai/delegation/middleware/content-policy-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/feature-flag-middleware.d.ts +46 -0
- package/dist/ai/delegation/middleware/feature-flag-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/feature-flag-middleware.js +59 -0
- package/dist/ai/delegation/middleware/feature-flag-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/identity-middleware.d.ts +23 -0
- package/dist/ai/delegation/middleware/identity-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/identity-middleware.js +64 -0
- package/dist/ai/delegation/middleware/identity-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/permissions-middleware.d.ts +48 -0
- package/dist/ai/delegation/middleware/permissions-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/permissions-middleware.js +107 -0
- package/dist/ai/delegation/middleware/permissions-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/rate-limiter-middleware.d.ts +38 -0
- package/dist/ai/delegation/middleware/rate-limiter-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/rate-limiter-middleware.js +65 -0
- package/dist/ai/delegation/middleware/rate-limiter-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/reputation-middleware.d.ts +39 -0
- package/dist/ai/delegation/middleware/reputation-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/reputation-middleware.js +75 -0
- package/dist/ai/delegation/middleware/reputation-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/resource-limiter-middleware.d.ts +52 -0
- package/dist/ai/delegation/middleware/resource-limiter-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/resource-limiter-middleware.js +112 -0
- package/dist/ai/delegation/middleware/resource-limiter-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/threat-validator-middleware.d.ts +23 -0
- package/dist/ai/delegation/middleware/threat-validator-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/threat-validator-middleware.js +83 -0
- package/dist/ai/delegation/middleware/threat-validator-middleware.js.map +1 -0
- package/dist/ai/delegation/middleware/tlp-middleware.d.ts +23 -0
- package/dist/ai/delegation/middleware/tlp-middleware.d.ts.map +1 -0
- package/dist/ai/delegation/middleware/tlp-middleware.js +59 -0
- package/dist/ai/delegation/middleware/tlp-middleware.js.map +1 -0
- package/dist/ai/delegation/monitoring.d.ts +298 -0
- package/dist/ai/delegation/monitoring.d.ts.map +1 -0
- package/dist/ai/delegation/monitoring.js +584 -0
- package/dist/ai/delegation/monitoring.js.map +1 -0
- package/dist/ai/delegation/security-middleware-chain.d.ts +71 -0
- package/dist/ai/delegation/security-middleware-chain.d.ts.map +1 -0
- package/dist/ai/delegation/security-middleware-chain.js +163 -0
- package/dist/ai/delegation/security-middleware-chain.js.map +1 -0
- package/dist/ai/delegation/session-checkpoint.d.ts +77 -0
- package/dist/ai/delegation/session-checkpoint.d.ts.map +1 -0
- package/dist/ai/delegation/session-checkpoint.js +131 -0
- package/dist/ai/delegation/session-checkpoint.js.map +1 -0
- package/dist/ai/delegation/session-manager.d.ts +131 -0
- package/dist/ai/delegation/session-manager.d.ts.map +1 -0
- package/dist/ai/delegation/session-manager.js +243 -0
- package/dist/ai/delegation/session-manager.js.map +1 -0
- package/dist/ai/delegation/session-queue.d.ts +95 -0
- package/dist/ai/delegation/session-queue.d.ts.map +1 -0
- package/dist/ai/delegation/session-queue.js +136 -0
- package/dist/ai/delegation/session-queue.js.map +1 -0
- package/dist/ai/delegation/timeout-watchdog.d.ts +60 -0
- package/dist/ai/delegation/timeout-watchdog.d.ts.map +1 -0
- package/dist/ai/delegation/timeout-watchdog.js +100 -0
- package/dist/ai/delegation/timeout-watchdog.js.map +1 -0
- package/dist/ai/examples/integration-demo.d.ts +27 -0
- package/dist/ai/examples/integration-demo.d.ts.map +1 -0
- package/dist/ai/examples/integration-demo.js +536 -0
- package/dist/ai/examples/integration-demo.js.map +1 -0
- package/dist/ai/index.d.ts +27 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +32 -10
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/mcp/index.d.ts +14 -2
- package/dist/ai/mcp/index.d.ts.map +1 -1
- package/dist/ai/mcp/index.js +11 -1
- package/dist/ai/mcp/index.js.map +1 -1
- package/dist/ai/mcp/servers/analytics/index.d.ts +19 -0
- package/dist/ai/mcp/servers/analytics/index.d.ts.map +1 -0
- package/dist/ai/mcp/servers/analytics/index.js +612 -0
- package/dist/ai/mcp/servers/analytics/index.js.map +1 -0
- package/dist/ai/mcp/servers/content-manager/content-provider.d.ts +61 -0
- package/dist/ai/mcp/servers/content-manager/content-provider.d.ts.map +1 -0
- package/dist/ai/mcp/servers/content-manager/content-provider.js +8 -0
- package/dist/ai/mcp/servers/content-manager/content-provider.js.map +1 -0
- package/dist/ai/mcp/servers/content-manager/index.d.ts +19 -0
- package/dist/ai/mcp/servers/content-manager/index.d.ts.map +1 -0
- package/dist/ai/mcp/servers/content-manager/index.js +282 -0
- package/dist/ai/mcp/servers/content-manager/index.js.map +1 -0
- package/dist/ai/mcp/servers/delegation-monitor/index.d.ts +36 -0
- package/dist/ai/mcp/servers/delegation-monitor/index.d.ts.map +1 -0
- package/dist/ai/mcp/servers/delegation-monitor/index.js +757 -0
- package/dist/ai/mcp/servers/delegation-monitor/index.js.map +1 -0
- package/dist/ai/mcp/servers/design-tokens/index.d.ts +19 -0
- package/dist/ai/mcp/servers/design-tokens/index.d.ts.map +1 -0
- package/dist/ai/mcp/servers/design-tokens/index.js +445 -0
- package/dist/ai/mcp/servers/design-tokens/index.js.map +1 -0
- package/dist/ai/mcp/servers/design-tokens/token-provider.d.ts +59 -0
- package/dist/ai/mcp/servers/design-tokens/token-provider.d.ts.map +1 -0
- package/dist/ai/mcp/servers/design-tokens/token-provider.js +8 -0
- package/dist/ai/mcp/servers/design-tokens/token-provider.js.map +1 -0
- package/dist/ai/mcp/servers/promptintel/index.d.ts +19 -0
- package/dist/ai/mcp/servers/promptintel/index.d.ts.map +1 -0
- package/dist/ai/mcp/servers/promptintel/index.js +335 -0
- package/dist/ai/mcp/servers/promptintel/index.js.map +1 -0
- package/dist/ai/mcp/servers/shared/cache.d.ts +62 -0
- package/dist/ai/mcp/servers/shared/cache.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/cache.js +117 -0
- package/dist/ai/mcp/servers/shared/cache.js.map +1 -0
- package/dist/ai/mcp/servers/shared/promptintel-client.d.ts +53 -0
- package/dist/ai/mcp/servers/shared/promptintel-client.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/promptintel-client.js +185 -0
- package/dist/ai/mcp/servers/shared/promptintel-client.js.map +1 -0
- package/dist/ai/mcp/servers/shared/promptintel-types.d.ts +85 -0
- package/dist/ai/mcp/servers/shared/promptintel-types.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/promptintel-types.js +7 -0
- package/dist/ai/mcp/servers/shared/promptintel-types.js.map +1 -0
- package/dist/ai/mcp/servers/shared/rate-limiter.d.ts +54 -0
- package/dist/ai/mcp/servers/shared/rate-limiter.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/rate-limiter.js +124 -0
- package/dist/ai/mcp/servers/shared/rate-limiter.js.map +1 -0
- package/dist/ai/mcp/servers/shared/redis-client.d.ts +54 -0
- package/dist/ai/mcp/servers/shared/redis-client.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/redis-client.js +232 -0
- package/dist/ai/mcp/servers/shared/redis-client.js.map +1 -0
- package/dist/ai/mcp/servers/shared/types.d.ts +301 -0
- package/dist/ai/mcp/servers/shared/types.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/types.js +6 -0
- package/dist/ai/mcp/servers/shared/types.js.map +1 -0
- package/dist/ai/mcp/servers/shared/utils.d.ts +49 -0
- package/dist/ai/mcp/servers/shared/utils.d.ts.map +1 -0
- package/dist/ai/mcp/servers/shared/utils.js +233 -0
- package/dist/ai/mcp/servers/shared/utils.js.map +1 -0
- package/dist/ai/memory/config.d.ts +102 -0
- package/dist/ai/memory/config.d.ts.map +1 -0
- package/dist/ai/memory/config.js +200 -0
- package/dist/ai/memory/config.js.map +1 -0
- package/dist/ai/memory/dcyfr-memory.d.ts +67 -0
- package/dist/ai/memory/dcyfr-memory.d.ts.map +1 -0
- package/dist/ai/memory/dcyfr-memory.js +308 -0
- package/dist/ai/memory/dcyfr-memory.js.map +1 -0
- package/dist/ai/memory/index.d.ts +15 -0
- package/dist/ai/memory/index.d.ts.map +1 -0
- package/dist/ai/memory/index.js +15 -0
- package/dist/ai/memory/index.js.map +1 -0
- package/dist/ai/memory/mem0-client.d.ts +108 -0
- package/dist/ai/memory/mem0-client.d.ts.map +1 -0
- package/dist/ai/memory/mem0-client.js +205 -0
- package/dist/ai/memory/mem0-client.js.map +1 -0
- package/dist/ai/memory/types.d.ts +175 -0
- package/dist/ai/memory/types.d.ts.map +1 -0
- package/dist/ai/memory/types.js +10 -0
- package/dist/ai/memory/types.js.map +1 -0
- package/dist/ai/permissions/attenuation-engine.d.ts +159 -0
- package/dist/ai/permissions/attenuation-engine.d.ts.map +1 -0
- package/dist/ai/permissions/attenuation-engine.js +511 -0
- package/dist/ai/permissions/attenuation-engine.js.map +1 -0
- package/dist/ai/plugins/plugin-loader.d.ts +4 -0
- package/dist/ai/plugins/plugin-loader.d.ts.map +1 -1
- package/dist/ai/plugins/plugin-loader.js +28 -28
- package/dist/ai/plugins/plugin-loader.js.map +1 -1
- package/dist/ai/reputation/execution-mode-reputation.d.ts +104 -0
- package/dist/ai/reputation/execution-mode-reputation.d.ts.map +1 -0
- package/dist/ai/reputation/execution-mode-reputation.js +142 -0
- package/dist/ai/reputation/execution-mode-reputation.js.map +1 -0
- package/dist/ai/reputation/reputation-engine.d.ts +204 -0
- package/dist/ai/reputation/reputation-engine.d.ts.map +1 -0
- package/dist/ai/reputation/reputation-engine.js +426 -0
- package/dist/ai/reputation/reputation-engine.js.map +1 -0
- package/dist/ai/runtime/agent-runtime.d.ts +193 -0
- package/dist/ai/runtime/agent-runtime.d.ts.map +1 -0
- package/dist/ai/runtime/agent-runtime.js +1009 -0
- package/dist/ai/runtime/agent-runtime.js.map +1 -0
- package/dist/ai/runtime/index.d.ts +11 -0
- package/dist/ai/runtime/index.d.ts.map +1 -0
- package/dist/ai/runtime/index.js +9 -0
- package/dist/ai/runtime/index.js.map +1 -0
- package/dist/ai/runtime/telemetry-schema.d.ts +192 -0
- package/dist/ai/runtime/telemetry-schema.d.ts.map +1 -0
- package/dist/ai/runtime/telemetry-schema.js +200 -0
- package/dist/ai/runtime/telemetry-schema.js.map +1 -0
- package/dist/ai/runtime/types.d.ts +236 -0
- package/dist/ai/runtime/types.d.ts.map +1 -0
- package/dist/ai/runtime/types.js +10 -0
- package/dist/ai/runtime/types.js.map +1 -0
- package/dist/ai/src/batch-processor.d.ts +298 -0
- package/dist/ai/src/batch-processor.d.ts.map +1 -0
- package/dist/ai/src/batch-processor.js +520 -0
- package/dist/ai/src/batch-processor.js.map +1 -0
- package/dist/ai/src/capability-bootstrap.d.ts +222 -0
- package/dist/ai/src/capability-bootstrap.d.ts.map +1 -0
- package/dist/ai/src/capability-bootstrap.js +421 -0
- package/dist/ai/src/capability-bootstrap.js.map +1 -0
- package/dist/ai/src/capability-manifest-generator.d.ts +52 -0
- package/dist/ai/src/capability-manifest-generator.d.ts.map +1 -0
- package/dist/ai/src/capability-manifest-generator.js +691 -0
- package/dist/ai/src/capability-manifest-generator.js.map +1 -0
- package/dist/ai/src/capability-registry.d.ts +157 -0
- package/dist/ai/src/capability-registry.d.ts.map +1 -0
- package/dist/ai/src/capability-registry.js +577 -0
- package/dist/ai/src/capability-registry.js.map +1 -0
- package/dist/ai/src/cli/telemetry-dashboard.d.ts +132 -0
- package/dist/ai/src/cli/telemetry-dashboard.d.ts.map +1 -0
- package/dist/ai/src/cli/telemetry-dashboard.js +565 -0
- package/dist/ai/src/cli/telemetry-dashboard.js.map +1 -0
- package/dist/ai/src/delegation/feature-flags.d.ts +213 -0
- package/dist/ai/src/delegation/feature-flags.d.ts.map +1 -0
- package/dist/ai/src/delegation/feature-flags.js +395 -0
- package/dist/ai/src/delegation/feature-flags.js.map +1 -0
- package/dist/ai/src/delegation/liability-firebreak.d.ts +303 -0
- package/dist/ai/src/delegation/liability-firebreak.d.ts.map +1 -0
- package/dist/ai/src/delegation/liability-firebreak.js +643 -0
- package/dist/ai/src/delegation/liability-firebreak.js.map +1 -0
- package/dist/ai/src/delegation/security-threat-model.d.ts +171 -0
- package/dist/ai/src/delegation/security-threat-model.d.ts.map +1 -0
- package/dist/ai/src/delegation/security-threat-model.js +723 -0
- package/dist/ai/src/delegation/security-threat-model.js.map +1 -0
- package/dist/ai/src/delegation/tlp-enforcement.d.ts +146 -0
- package/dist/ai/src/delegation/tlp-enforcement.d.ts.map +1 -0
- package/dist/ai/src/delegation/tlp-enforcement.js +382 -0
- package/dist/ai/src/delegation/tlp-enforcement.js.map +1 -0
- package/dist/ai/src/delegation-capability-integration.d.ts +154 -0
- package/dist/ai/src/delegation-capability-integration.d.ts.map +1 -0
- package/dist/ai/src/delegation-capability-integration.js +351 -0
- package/dist/ai/src/delegation-capability-integration.js.map +1 -0
- package/dist/ai/src/end-to-end-workflow-orchestrator.d.ts +325 -0
- package/dist/ai/src/end-to-end-workflow-orchestrator.d.ts.map +1 -0
- package/dist/ai/src/end-to-end-workflow-orchestrator.js +801 -0
- package/dist/ai/src/end-to-end-workflow-orchestrator.js.map +1 -0
- package/dist/ai/src/enhanced-capability-detection.d.ts +237 -0
- package/dist/ai/src/enhanced-capability-detection.d.ts.map +1 -0
- package/dist/ai/src/enhanced-capability-detection.js +448 -0
- package/dist/ai/src/enhanced-capability-detection.js.map +1 -0
- package/dist/ai/src/intelligent-cache-manager.d.ts +327 -0
- package/dist/ai/src/intelligent-cache-manager.d.ts.map +1 -0
- package/dist/ai/src/intelligent-cache-manager.js +634 -0
- package/dist/ai/src/intelligent-cache-manager.js.map +1 -0
- package/dist/ai/src/mcp-auto-configuration.d.ts +232 -0
- package/dist/ai/src/mcp-auto-configuration.d.ts.map +1 -0
- package/dist/ai/src/mcp-auto-configuration.js +445 -0
- package/dist/ai/src/mcp-auto-configuration.js.map +1 -0
- package/dist/ai/src/performance-profiler.d.ts +351 -0
- package/dist/ai/src/performance-profiler.d.ts.map +1 -0
- package/dist/ai/src/performance-profiler.js +475 -0
- package/dist/ai/src/performance-profiler.js.map +1 -0
- package/dist/ai/src/personas/hooks/before-llm-call.d.ts +96 -0
- package/dist/ai/src/personas/hooks/before-llm-call.d.ts.map +1 -0
- package/dist/ai/src/personas/hooks/before-llm-call.js +83 -0
- package/dist/ai/src/personas/hooks/before-llm-call.js.map +1 -0
- package/dist/ai/src/personas/index.d.ts +10 -0
- package/dist/ai/src/personas/index.d.ts.map +1 -0
- package/dist/ai/src/personas/index.js +10 -0
- package/dist/ai/src/personas/index.js.map +1 -0
- package/dist/ai/src/personas/persona-loader.d.ts +42 -0
- package/dist/ai/src/personas/persona-loader.d.ts.map +1 -0
- package/dist/ai/src/personas/persona-loader.js +162 -0
- package/dist/ai/src/personas/persona-loader.js.map +1 -0
- package/dist/ai/src/personas/types.d.ts +199 -0
- package/dist/ai/src/personas/types.d.ts.map +1 -0
- package/dist/ai/src/personas/types.js +7 -0
- package/dist/ai/src/personas/types.js.map +1 -0
- package/dist/ai/src/personas/voice-resolver.d.ts +40 -0
- package/dist/ai/src/personas/voice-resolver.d.ts.map +1 -0
- package/dist/ai/src/personas/voice-resolver.js +201 -0
- package/dist/ai/src/personas/voice-resolver.js.map +1 -0
- package/dist/ai/src/resource-monitor.d.ts +311 -0
- package/dist/ai/src/resource-monitor.d.ts.map +1 -0
- package/dist/ai/src/resource-monitor.js +475 -0
- package/dist/ai/src/resource-monitor.js.map +1 -0
- package/dist/ai/src/runtime/agent-runtime.d.ts +340 -0
- package/dist/ai/src/runtime/agent-runtime.d.ts.map +1 -0
- package/dist/ai/src/runtime/agent-runtime.js +1084 -0
- package/dist/ai/src/runtime/agent-runtime.js.map +1 -0
- package/dist/ai/src/telemetry/delegation-telemetry.d.ts +287 -0
- package/dist/ai/src/telemetry/delegation-telemetry.d.ts.map +1 -0
- package/dist/ai/src/telemetry/delegation-telemetry.js +389 -0
- package/dist/ai/src/telemetry/delegation-telemetry.js.map +1 -0
- package/dist/ai/src/telemetry/index.d.ts +48 -0
- package/dist/ai/src/telemetry/index.d.ts.map +1 -0
- package/dist/ai/src/telemetry/index.js +48 -0
- package/dist/ai/src/telemetry/index.js.map +1 -0
- package/dist/ai/src/telemetry/runtime-telemetry-integration.d.ts +67 -0
- package/dist/ai/src/telemetry/runtime-telemetry-integration.d.ts.map +1 -0
- package/dist/ai/src/telemetry/runtime-telemetry-integration.js +415 -0
- package/dist/ai/src/telemetry/runtime-telemetry-integration.js.map +1 -0
- package/dist/ai/src/telemetry/telemetry-utils.d.ts +119 -0
- package/dist/ai/src/telemetry/telemetry-utils.d.ts.map +1 -0
- package/dist/ai/src/telemetry/telemetry-utils.js +250 -0
- package/dist/ai/src/telemetry/telemetry-utils.js.map +1 -0
- package/dist/ai/src/types/agent-capabilities.d.ts +227 -0
- package/dist/ai/src/types/agent-capabilities.d.ts.map +1 -0
- package/dist/ai/src/types/agent-capabilities.js +11 -0
- package/dist/ai/src/types/agent-capabilities.js.map +1 -0
- package/dist/ai/src/types/context-verification.d.ts +158 -0
- package/dist/ai/src/types/context-verification.d.ts.map +1 -0
- package/dist/ai/src/types/context-verification.js +73 -0
- package/dist/ai/src/types/context-verification.js.map +1 -0
- package/dist/ai/src/types/delegation-contracts.d.ts +296 -0
- package/dist/ai/src/types/delegation-contracts.d.ts.map +1 -0
- package/dist/ai/src/types/delegation-contracts.js +17 -0
- package/dist/ai/src/types/delegation-contracts.js.map +1 -0
- package/dist/ai/src/validation-pipeline-integration.d.ts +266 -0
- package/dist/ai/src/validation-pipeline-integration.d.ts.map +1 -0
- package/dist/ai/src/validation-pipeline-integration.js +695 -0
- package/dist/ai/src/validation-pipeline-integration.js.map +1 -0
- package/dist/ai/src/verification/multi-modal-formatters.d.ts +57 -0
- package/dist/ai/src/verification/multi-modal-formatters.d.ts.map +1 -0
- package/dist/ai/src/verification/multi-modal-formatters.js +655 -0
- package/dist/ai/src/verification/multi-modal-formatters.js.map +1 -0
- package/dist/ai/src/verification/output-formatter.d.ts +186 -0
- package/dist/ai/src/verification/output-formatter.d.ts.map +1 -0
- package/dist/ai/src/verification/output-formatter.js +296 -0
- package/dist/ai/src/verification/output-formatter.js.map +1 -0
- package/dist/ai/src/verification/parser-integration.d.ts +137 -0
- package/dist/ai/src/verification/parser-integration.d.ts.map +1 -0
- package/dist/ai/src/verification/parser-integration.js +273 -0
- package/dist/ai/src/verification/parser-integration.js.map +1 -0
- package/dist/ai/types/agent-capabilities.d.ts +387 -0
- package/dist/ai/types/agent-capabilities.d.ts.map +1 -0
- package/dist/ai/types/agent-capabilities.js +32 -0
- package/dist/ai/types/agent-capabilities.js.map +1 -0
- package/dist/ai/types/delegation-contracts.d.ts +291 -0
- package/dist/ai/types/delegation-contracts.d.ts.map +1 -0
- package/dist/ai/types/delegation-contracts.js +14 -0
- package/dist/ai/types/delegation-contracts.js.map +1 -0
- package/dist/ai/types/index.d.ts +4 -1
- package/dist/ai/types/index.d.ts.map +1 -1
- package/dist/ai/types/index.js +4 -1
- package/dist/ai/types/index.js.map +1 -1
- package/dist/ai/types/permission-tokens.d.ts +365 -0
- package/dist/ai/types/permission-tokens.d.ts.map +1 -0
- package/dist/ai/types/permission-tokens.js +13 -0
- package/dist/ai/types/permission-tokens.js.map +1 -0
- package/dist/ai/types/security-middleware.d.ts +130 -0
- package/dist/ai/types/security-middleware.d.ts.map +1 -0
- package/dist/ai/types/security-middleware.js +13 -0
- package/dist/ai/types/security-middleware.js.map +1 -0
- package/dist/ai/utils/storage.d.ts.map +1 -1
- package/dist/ai/utils/storage.js +6 -3
- package/dist/ai/utils/storage.js.map +1 -1
- package/dist/ai/validation/validation-framework.js +1 -1
- package/dist/ai/verification/policy-framework.d.ts +161 -0
- package/dist/ai/verification/policy-framework.d.ts.map +1 -0
- package/dist/ai/verification/policy-framework.js +436 -0
- package/dist/ai/verification/policy-framework.js.map +1 -0
- package/package.json +56 -6
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DCYFR Delegation Manager — Ralph Loop V2
|
|
3
|
+
* TLP:AMBER - Internal Use Only
|
|
4
|
+
*
|
|
5
|
+
* High-level orchestration layer on top of DelegationContractManager.
|
|
6
|
+
* Provides failure analysis (analyzeFailure) to categorise why a contract
|
|
7
|
+
* failed so that the Ralph Loop can rewrite the prompt and retry.
|
|
8
|
+
*
|
|
9
|
+
* @module delegation/delegation-manager
|
|
10
|
+
* @version 1.0.0
|
|
11
|
+
* @date 2026-02-26
|
|
12
|
+
*
|
|
13
|
+
* ## Failure Categories
|
|
14
|
+
*
|
|
15
|
+
* | Category | Primary Signal |
|
|
16
|
+
* |------------------------|---------------------------------------------|
|
|
17
|
+
* | context_overflow | "token limit" / "truncated" in logs |
|
|
18
|
+
* | wrong_direction | file changes outside declared task scope |
|
|
19
|
+
* | missing_requirements | "Cannot find name" TypeScript errors |
|
|
20
|
+
* | stuck_on_complexity | 0 commits after > 2 hours |
|
|
21
|
+
* | unknown | no other signal detected |
|
|
22
|
+
*/
|
|
23
|
+
import { appendFile, mkdir } from 'node:fs/promises';
|
|
24
|
+
import { dirname } from 'node:path';
|
|
25
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
// Constants
|
|
27
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
28
|
+
const TWO_HOURS_MS = 2 * 60 * 60 * 1000;
|
|
29
|
+
/** Maximum retry attempts before human escalation */
|
|
30
|
+
const MAX_RETRIES = 3;
|
|
31
|
+
/** Default JSONL log path (relative to process.cwd) */
|
|
32
|
+
const DEFAULT_REWRITE_LOG_PATH = 'data/rewrite-history.jsonl';
|
|
33
|
+
/**
|
|
34
|
+
* Phrases that indicate the model hit a context/token limit.
|
|
35
|
+
* Matched case-insensitively against logs + error_output.
|
|
36
|
+
*/
|
|
37
|
+
const CONTEXT_OVERFLOW_SIGNALS = [
|
|
38
|
+
'token limit',
|
|
39
|
+
'truncated',
|
|
40
|
+
'context length exceeded',
|
|
41
|
+
'max_tokens',
|
|
42
|
+
'maximum context',
|
|
43
|
+
'context window',
|
|
44
|
+
'too many tokens',
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Phrases that indicate missing TypeScript / module requirements.
|
|
48
|
+
* Matched case-insensitively against logs + error_output.
|
|
49
|
+
*/
|
|
50
|
+
const MISSING_REQUIREMENTS_SIGNALS = [
|
|
51
|
+
'Cannot find name',
|
|
52
|
+
'Cannot find module',
|
|
53
|
+
'has no exported member',
|
|
54
|
+
'Property .* does not exist',
|
|
55
|
+
];
|
|
56
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
57
|
+
// Public types
|
|
58
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* Why a delegation contract failed.
|
|
61
|
+
*
|
|
62
|
+
* Used by Ralph Loop V2 to select the appropriate prompt-rewrite strategy.
|
|
63
|
+
*/
|
|
64
|
+
export var FailureCategory;
|
|
65
|
+
(function (FailureCategory) {
|
|
66
|
+
/** Agent ran out of context window / token budget */
|
|
67
|
+
FailureCategory["CONTEXT_OVERFLOW"] = "context_overflow";
|
|
68
|
+
/** Agent made changes outside the declared task scope */
|
|
69
|
+
FailureCategory["WRONG_DIRECTION"] = "wrong_direction";
|
|
70
|
+
/** TypeScript / module requirements were not satisfied */
|
|
71
|
+
FailureCategory["MISSING_REQUIREMENTS"] = "missing_requirements";
|
|
72
|
+
/** Agent made no progress (zero commits) after the 2-hour threshold */
|
|
73
|
+
FailureCategory["STUCK_ON_COMPLEXITY"] = "stuck_on_complexity";
|
|
74
|
+
/** No specific signal detected — generic failure */
|
|
75
|
+
FailureCategory["UNKNOWN"] = "unknown";
|
|
76
|
+
})(FailureCategory || (FailureCategory = {}));
|
|
77
|
+
/**
|
|
78
|
+
* Number of memory entries to retrieve per category during rewriting.
|
|
79
|
+
* Kept small to avoid token bloat — the Ralph Loop prioritises precision.
|
|
80
|
+
*/
|
|
81
|
+
const MEMORY_QUERY_LIMIT = 3;
|
|
82
|
+
/**
|
|
83
|
+
* Default context window size in tokens.
|
|
84
|
+
*
|
|
85
|
+
* 128,000 tokens covers GPT-4o, Claude 3.5 Sonnet, and most Gemini variants.
|
|
86
|
+
* Override per-task via `RewriteTask.contextWindowTokens` when targeting a
|
|
87
|
+
* model with a different window.
|
|
88
|
+
*/
|
|
89
|
+
const DEFAULT_CONTEXT_WINDOW_TOKENS = 128_000;
|
|
90
|
+
/**
|
|
91
|
+
* Fraction of the context window reserved for the prompt.
|
|
92
|
+
*
|
|
93
|
+
* The remaining 20% is left for the model's output tokens. When a rewritten
|
|
94
|
+
* prompt would exceed this budget, older injected context blocks are
|
|
95
|
+
* summarised to a 1-sentence placeholder, while the last 3 blocks are kept
|
|
96
|
+
* verbatim.
|
|
97
|
+
*/
|
|
98
|
+
const PROMPT_BUDGET_RATIO = 0.8;
|
|
99
|
+
/**
|
|
100
|
+
* Maximum number of injected context blocks to keep verbatim when trimming.
|
|
101
|
+
* Older blocks (lower index) are summarised to a 1-sentence placeholder.
|
|
102
|
+
*/
|
|
103
|
+
const VERBATIM_BLOCK_KEEP_COUNT = 3;
|
|
104
|
+
/**
|
|
105
|
+
* Minimum successful retries a pattern must have before it is considered
|
|
106
|
+
* high-confidence and used to short-circuit the standard rewrite strategies.
|
|
107
|
+
*/
|
|
108
|
+
const HIGH_CONFIDENCE_MIN = 5;
|
|
109
|
+
/**
|
|
110
|
+
* Isolated memory namespace for all Ralph Loop V2 prompt patterns.
|
|
111
|
+
* Using a dedicated namespace prevents pattern data from polluting regular
|
|
112
|
+
* agent workflow memories.
|
|
113
|
+
*/
|
|
114
|
+
const PATTERN_NAMESPACE = 'ralph-loop-v2-patterns';
|
|
115
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
116
|
+
// DelegationManager
|
|
117
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
118
|
+
/**
|
|
119
|
+
* High-level delegation orchestration.
|
|
120
|
+
*
|
|
121
|
+
* Ralph Loop V2 entry point — wraps `DelegationContractManager` and adds the
|
|
122
|
+
* `analyzeFailure()` method used to categorise failures before prompt rewrite.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```typescript
|
|
126
|
+
* import { DelegationManager } from './delegation-manager.js';
|
|
127
|
+
*
|
|
128
|
+
* const dm = new DelegationManager();
|
|
129
|
+
* const analysis = dm.analyzeFailure({
|
|
130
|
+
* contract: myContract,
|
|
131
|
+
* logs: contractLogs,
|
|
132
|
+
* changed_files: ['src/billing/invoice.ts', 'README.md'],
|
|
133
|
+
* task_scope_paths: ['src/billing'],
|
|
134
|
+
* commit_count: 0,
|
|
135
|
+
* elapsed_ms: 3 * 60 * 60 * 1000,
|
|
136
|
+
* });
|
|
137
|
+
*
|
|
138
|
+
* // analysis.category === FailureCategory.STUCK_ON_COMPLEXITY
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export class DelegationManager {
|
|
142
|
+
// ------------------------------------------------------------------
|
|
143
|
+
// Private helpers
|
|
144
|
+
// ------------------------------------------------------------------
|
|
145
|
+
/**
|
|
146
|
+
* Returns `true` when any phrase in `needles` appears case-insensitively
|
|
147
|
+
* in `haystack`.
|
|
148
|
+
*/
|
|
149
|
+
static containsAny(haystack, needles) {
|
|
150
|
+
const lower = haystack.toLowerCase();
|
|
151
|
+
return needles.some(n => lower.includes(n.toLowerCase()));
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Checks whether `file` is outside ALL of `scopePaths`.
|
|
155
|
+
* A file is "in scope" when it starts with at least one scope prefix.
|
|
156
|
+
*/
|
|
157
|
+
static isOutOfScope(file, scopePaths) {
|
|
158
|
+
return !scopePaths.some(prefix => file.startsWith(prefix));
|
|
159
|
+
}
|
|
160
|
+
// ------------------------------------------------------------------
|
|
161
|
+
// Public API
|
|
162
|
+
// ------------------------------------------------------------------
|
|
163
|
+
/**
|
|
164
|
+
* Analyses why a delegation contract failed and returns a structured
|
|
165
|
+
* `FailureAnalysis` for use by Ralph Loop V2 prompt rewriting.
|
|
166
|
+
*
|
|
167
|
+
* Detection priority (highest confidence first):
|
|
168
|
+
* 1. `context_overflow` — keyword match in logs/error_output
|
|
169
|
+
* 2. `missing_requirements` — "Cannot find name" / module errors
|
|
170
|
+
* 3. `wrong_direction` — out-of-scope file changes
|
|
171
|
+
* 4. `stuck_on_complexity` — zero commits > 2 h
|
|
172
|
+
* 5. `unknown` — no signal found
|
|
173
|
+
*
|
|
174
|
+
* All four checks are run; the category with the highest confidence wins.
|
|
175
|
+
* Every detected signal is included in `analysis.signals` regardless of
|
|
176
|
+
* which category is selected, giving the rewriter a complete picture.
|
|
177
|
+
*/
|
|
178
|
+
analyzeFailure(result) {
|
|
179
|
+
const signals = [];
|
|
180
|
+
const candidates = [];
|
|
181
|
+
const combinedText = `${result.logs ?? ''} ${result.error_output ?? ''}`.trim();
|
|
182
|
+
// ── 1. Context overflow ────────────────────────────────────────────────
|
|
183
|
+
const overflowMatches = CONTEXT_OVERFLOW_SIGNALS.filter(phrase => combinedText.toLowerCase().includes(phrase.toLowerCase()));
|
|
184
|
+
if (overflowMatches.length > 0) {
|
|
185
|
+
for (const phrase of overflowMatches) {
|
|
186
|
+
signals.push(`context_overflow signal: "${phrase}" found in logs`);
|
|
187
|
+
}
|
|
188
|
+
candidates.push({ category: FailureCategory.CONTEXT_OVERFLOW, confidence: 1.0 });
|
|
189
|
+
}
|
|
190
|
+
// ── 2. Missing requirements ────────────────────────────────────────────
|
|
191
|
+
const missingMatches = MISSING_REQUIREMENTS_SIGNALS.filter(phrase => DelegationManager.containsAny(combinedText, [phrase]));
|
|
192
|
+
if (missingMatches.length > 0) {
|
|
193
|
+
for (const phrase of missingMatches) {
|
|
194
|
+
signals.push(`missing_requirements signal: "${phrase}" found in output`);
|
|
195
|
+
}
|
|
196
|
+
candidates.push({ category: FailureCategory.MISSING_REQUIREMENTS, confidence: 1.0 });
|
|
197
|
+
}
|
|
198
|
+
// ── 3. Wrong direction ─────────────────────────────────────────────────
|
|
199
|
+
const changedFiles = result.changed_files ?? [];
|
|
200
|
+
const scopePaths = result.task_scope_paths ?? [];
|
|
201
|
+
if (changedFiles.length > 0 && scopePaths.length > 0) {
|
|
202
|
+
const outOfScope = changedFiles.filter(f => DelegationManager.isOutOfScope(f, scopePaths));
|
|
203
|
+
if (outOfScope.length > 0) {
|
|
204
|
+
for (const f of outOfScope) {
|
|
205
|
+
signals.push(`wrong_direction signal: "${f}" is outside task scope (${scopePaths.join(', ')})`);
|
|
206
|
+
}
|
|
207
|
+
const confidence = outOfScope.length / changedFiles.length;
|
|
208
|
+
candidates.push({ category: FailureCategory.WRONG_DIRECTION, confidence });
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
// ── 4. Stuck on complexity ────────────────────────────────────────────
|
|
212
|
+
const commitCount = result.commit_count ?? -1;
|
|
213
|
+
const elapsedMs = result.elapsed_ms ?? 0;
|
|
214
|
+
if (commitCount === 0 && elapsedMs > TWO_HOURS_MS) {
|
|
215
|
+
const hoursElapsed = (elapsedMs / (60 * 60 * 1000)).toFixed(1);
|
|
216
|
+
signals.push(`stuck_on_complexity signal: 0 commits after ${hoursElapsed}h (threshold: 2h)`);
|
|
217
|
+
candidates.push({ category: FailureCategory.STUCK_ON_COMPLEXITY, confidence: 1.0 });
|
|
218
|
+
}
|
|
219
|
+
// ── 5. Select winner ─────────────────────────────────────────────────
|
|
220
|
+
if (candidates.length === 0) {
|
|
221
|
+
return {
|
|
222
|
+
category: FailureCategory.UNKNOWN,
|
|
223
|
+
confidence: 0.3,
|
|
224
|
+
signals: ['no specific failure signal detected'],
|
|
225
|
+
contract_id: result.contract.contract_id,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
// Sort descending by confidence; stable sort keeps insertion order on ties
|
|
229
|
+
const sorted = candidates.slice().sort((a, b) => b.confidence - a.confidence);
|
|
230
|
+
const winner = sorted[0];
|
|
231
|
+
return {
|
|
232
|
+
category: winner.category,
|
|
233
|
+
confidence: winner.confidence,
|
|
234
|
+
signals,
|
|
235
|
+
contract_id: result.contract.contract_id,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
// ------------------------------------------------------------------
|
|
239
|
+
// rewritePrompt
|
|
240
|
+
// ------------------------------------------------------------------
|
|
241
|
+
/**
|
|
242
|
+
* Rewrites a task prompt based on the failure category detected by
|
|
243
|
+
* `analyzeFailure()`, optionally enriching it with context retrieved
|
|
244
|
+
* from the memory layer.
|
|
245
|
+
*
|
|
246
|
+
* Strategy per category:
|
|
247
|
+
* - `context_overflow` — scope the prompt to the 3 most relevant files
|
|
248
|
+
* - `wrong_direction` — prepend customer requirement quotes from memory
|
|
249
|
+
* - `missing_requirements` — append type definitions from memory
|
|
250
|
+
* - `stuck_on_complexity` — decompose the task into 2–3 sub-tasks
|
|
251
|
+
* - `unknown` — return the original prompt unchanged
|
|
252
|
+
*
|
|
253
|
+
* @param task - Task information including the original prompt
|
|
254
|
+
* @param failureCategory - Category identified by `analyzeFailure()`
|
|
255
|
+
* @param memory - Memory layer instance for context lookups
|
|
256
|
+
* @returns Rewritten prompt + audit log of applied context
|
|
257
|
+
*/
|
|
258
|
+
async rewritePrompt(task, failureCategory, memory) {
|
|
259
|
+
let raw = null;
|
|
260
|
+
// ── Pattern shortcut — check for a high-confidence learned pattern first ───
|
|
261
|
+
// Skip pattern lookup for UNKNOWN: no strategy exists so there can be no
|
|
262
|
+
// learned pattern, and the memory round-trip would produce no useful result.
|
|
263
|
+
if (failureCategory !== FailureCategory.UNKNOWN) {
|
|
264
|
+
const pattern = await this.queryHighConfidencePattern(task.agentId ?? task.taskId, failureCategory, memory);
|
|
265
|
+
if (pattern !== null) {
|
|
266
|
+
const rewrittenPrompt = pattern.effectiveRewrite
|
|
267
|
+
? `HIGH CONFIDENCE PATTERN (${pattern.successCount} prior successes — using learned strategy):\n` +
|
|
268
|
+
`${pattern.effectiveRewrite}\n\n` +
|
|
269
|
+
task.originalPrompt
|
|
270
|
+
: task.originalPrompt;
|
|
271
|
+
raw = {
|
|
272
|
+
rewrittenPrompt,
|
|
273
|
+
strategy: failureCategory,
|
|
274
|
+
appliedContext: [
|
|
275
|
+
`pattern shortcut: using high-confidence pattern for ${failureCategory} ` +
|
|
276
|
+
`(capability=${pattern.capability}, successCount=${pattern.successCount}, ` +
|
|
277
|
+
`lastSuccessAt=${pattern.lastSuccessAt})`,
|
|
278
|
+
],
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (raw === null) {
|
|
283
|
+
switch (failureCategory) {
|
|
284
|
+
case FailureCategory.CONTEXT_OVERFLOW:
|
|
285
|
+
raw = await this.rewriteForContextOverflow(task, memory);
|
|
286
|
+
break;
|
|
287
|
+
case FailureCategory.WRONG_DIRECTION:
|
|
288
|
+
raw = await this.rewriteForWrongDirection(task, memory);
|
|
289
|
+
break;
|
|
290
|
+
case FailureCategory.MISSING_REQUIREMENTS:
|
|
291
|
+
raw = await this.rewriteForMissingRequirements(task, memory);
|
|
292
|
+
break;
|
|
293
|
+
case FailureCategory.STUCK_ON_COMPLEXITY:
|
|
294
|
+
raw = await this.rewriteForStuckOnComplexity(task, memory);
|
|
295
|
+
break;
|
|
296
|
+
default:
|
|
297
|
+
raw = {
|
|
298
|
+
rewrittenPrompt: task.originalPrompt,
|
|
299
|
+
strategy: FailureCategory.UNKNOWN,
|
|
300
|
+
appliedContext: ['no rewrite strategy for unknown category — prompt returned unchanged'],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return this.applyTokenBudget(raw, task);
|
|
305
|
+
}
|
|
306
|
+
// ------------------------------------------------------------------
|
|
307
|
+
// Private rewrite strategies
|
|
308
|
+
// ------------------------------------------------------------------
|
|
309
|
+
/**
|
|
310
|
+
* Trim scope: query memory for the most relevant 3 files to this task
|
|
311
|
+
* and rewrite the prompt to focus only on those files.
|
|
312
|
+
*/
|
|
313
|
+
async rewriteForContextOverflow(task, memory) {
|
|
314
|
+
const appliedContext = [];
|
|
315
|
+
const memResults = await memory.searchAgentMemories(task.agentId ?? task.taskId, `relevant files for ${task.taskId}`, MEMORY_QUERY_LIMIT);
|
|
316
|
+
const relevantFiles = memResults.map(r => r.content);
|
|
317
|
+
appliedContext.push(`context_overflow: queried memory for relevant files (found ${relevantFiles.length})`);
|
|
318
|
+
// Also honour explicit changedFiles — intersection with scope paths
|
|
319
|
+
const scopedFiles = (task.changedFiles ?? [])
|
|
320
|
+
.filter(f => (task.taskScopePaths ?? []).some(p => f.startsWith(p)))
|
|
321
|
+
.slice(0, MEMORY_QUERY_LIMIT);
|
|
322
|
+
const allFiles = [...new Set([...relevantFiles, ...scopedFiles])].slice(0, MEMORY_QUERY_LIMIT);
|
|
323
|
+
let rewrittenPrompt = task.originalPrompt;
|
|
324
|
+
if (allFiles.length > 0) {
|
|
325
|
+
const fileList = allFiles.map(f => `- ${f}`).join('\n');
|
|
326
|
+
rewrittenPrompt =
|
|
327
|
+
`SCOPE RESTRICTION (context budget exceeded on previous attempt):\n` +
|
|
328
|
+
`Focus ONLY on these ${allFiles.length} file(s):\n${fileList}\n\n` +
|
|
329
|
+
task.originalPrompt;
|
|
330
|
+
appliedContext.push(`context_overflow: scoped prompt to files: ${allFiles.join(', ')}`);
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
appliedContext.push('context_overflow: no files found in memory — trimming strategy adds scope header only');
|
|
334
|
+
rewrittenPrompt =
|
|
335
|
+
`SCOPE RESTRICTION (context budget exceeded on previous attempt):\n` +
|
|
336
|
+
`Complete only the minimal change needed for this task.\n\n` +
|
|
337
|
+
task.originalPrompt;
|
|
338
|
+
}
|
|
339
|
+
return { rewrittenPrompt, strategy: FailureCategory.CONTEXT_OVERFLOW, appliedContext };
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Add customer requirement quotes: query memory for meeting notes / customer
|
|
343
|
+
* quotes relevant to the task and prepend them as alignment context.
|
|
344
|
+
*/
|
|
345
|
+
async rewriteForWrongDirection(task, memory) {
|
|
346
|
+
const appliedContext = [];
|
|
347
|
+
const memResults = await memory.searchAgentMemories(task.agentId ?? task.taskId, `customer requirements meeting notes ${task.taskId}`, MEMORY_QUERY_LIMIT);
|
|
348
|
+
appliedContext.push(`wrong_direction: queried memory for customer quotes (found ${memResults.length})`);
|
|
349
|
+
let rewrittenPrompt = task.originalPrompt;
|
|
350
|
+
if (memResults.length > 0) {
|
|
351
|
+
const quotes = memResults
|
|
352
|
+
.map((r, i) => `[Requirement ${i + 1}] ${r.content}`)
|
|
353
|
+
.join('\n\n');
|
|
354
|
+
rewrittenPrompt =
|
|
355
|
+
`ALIGNMENT CONTEXT (previous attempt went out of scope):\n` +
|
|
356
|
+
`These are the customer requirements this task must satisfy:\n\n` +
|
|
357
|
+
`${quotes}\n\n` +
|
|
358
|
+
`Stay strictly within the following scope: ${(task.taskScopePaths ?? []).join(', ')}\n\n` +
|
|
359
|
+
task.originalPrompt;
|
|
360
|
+
for (const r of memResults) {
|
|
361
|
+
appliedContext.push(`wrong_direction: injected customer quote (relevance ${r.relevance.toFixed(2)}): "${r.content.slice(0, 80)}..."`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
const scopeNote = (task.taskScopePaths ?? []).length > 0
|
|
366
|
+
? `Stay strictly within: ${task.taskScopePaths.join(', ')}`
|
|
367
|
+
: 'Stay strictly within the originally declared task scope.';
|
|
368
|
+
rewrittenPrompt =
|
|
369
|
+
`SCOPE REMINDER (previous attempt went out of scope):\n` +
|
|
370
|
+
`${scopeNote}\n\n` +
|
|
371
|
+
task.originalPrompt;
|
|
372
|
+
appliedContext.push('wrong_direction: no memory quotes found — added scope reminder header');
|
|
373
|
+
}
|
|
374
|
+
return { rewrittenPrompt, strategy: FailureCategory.WRONG_DIRECTION, appliedContext };
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Append type definitions: query memory for type definitions relevant to
|
|
378
|
+
* the task and append them as explicit type context.
|
|
379
|
+
*/
|
|
380
|
+
async rewriteForMissingRequirements(task, memory) {
|
|
381
|
+
const appliedContext = [];
|
|
382
|
+
const memResults = await memory.searchAgentMemories(task.agentId ?? task.taskId, `TypeScript type definitions interfaces for ${task.taskId}`, MEMORY_QUERY_LIMIT);
|
|
383
|
+
appliedContext.push(`missing_requirements: queried memory for type definitions (found ${memResults.length})`);
|
|
384
|
+
let rewrittenPrompt = task.originalPrompt;
|
|
385
|
+
if (memResults.length > 0) {
|
|
386
|
+
const typeDefs = memResults
|
|
387
|
+
.map((r, i) => `// Type Definition ${i + 1}\n${r.content}`)
|
|
388
|
+
.join('\n\n');
|
|
389
|
+
rewrittenPrompt =
|
|
390
|
+
task.originalPrompt +
|
|
391
|
+
`\n\nREQUIRED TYPE DEFINITIONS (use exactly as shown):\n` +
|
|
392
|
+
`\`\`\`typescript\n${typeDefs}\n\`\`\``;
|
|
393
|
+
for (const r of memResults) {
|
|
394
|
+
appliedContext.push(`missing_requirements: appended type def (relevance ${r.relevance.toFixed(2)})`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
rewrittenPrompt =
|
|
399
|
+
task.originalPrompt +
|
|
400
|
+
`\n\nNOTE: Ensure all required TypeScript types and module imports are ` +
|
|
401
|
+
`declared before use. Run \`tsc --noEmit\` and fix all type errors before submitting.`;
|
|
402
|
+
appliedContext.push('missing_requirements: no type defs in memory — added tsc reminder');
|
|
403
|
+
}
|
|
404
|
+
return { rewrittenPrompt, strategy: FailureCategory.MISSING_REQUIREMENTS, appliedContext };
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Decompose into sub-tasks: break the original prompt into 2–3 focused
|
|
408
|
+
* sub-tasks so the agent can make incremental forward progress.
|
|
409
|
+
*/
|
|
410
|
+
async rewriteForStuckOnComplexity(task, memory) {
|
|
411
|
+
const appliedContext = [];
|
|
412
|
+
// Query memory for any prior decomposition patterns for this task type
|
|
413
|
+
const memResults = await memory.searchAgentMemories(task.agentId ?? task.taskId, `task decomposition sub-tasks breakdown ${task.taskId}`, MEMORY_QUERY_LIMIT);
|
|
414
|
+
appliedContext.push(`stuck_on_complexity: queried memory for decomposition patterns (found ${memResults.length})`);
|
|
415
|
+
let subTaskBlock;
|
|
416
|
+
if (memResults.length > 0) {
|
|
417
|
+
// Use memory-sourced decomposition
|
|
418
|
+
subTaskBlock = memResults
|
|
419
|
+
.map((r, i) => `Sub-task ${i + 1}: ${r.content}`)
|
|
420
|
+
.join('\n\n');
|
|
421
|
+
appliedContext.push('stuck_on_complexity: using memory-sourced sub-task decomposition');
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
// Heuristic decomposition — split the original prompt into 3 phases
|
|
425
|
+
subTaskBlock =
|
|
426
|
+
`Sub-task 1: Write the minimal implementation skeleton (types + function signatures only; no logic yet)\n` +
|
|
427
|
+
`Sub-task 2: Implement the core logic and add unit tests\n` +
|
|
428
|
+
`Sub-task 3: Wire up integration points, fix type errors, and verify with \`npm run test\``;
|
|
429
|
+
appliedContext.push('stuck_on_complexity: heuristic 3-phase decomposition applied');
|
|
430
|
+
}
|
|
431
|
+
const rewrittenPrompt = `TASK DECOMPOSITION (agent was stuck — complete one sub-task at a time and commit after each):\n\n` +
|
|
432
|
+
`${subTaskBlock}\n\n` +
|
|
433
|
+
`Original task for reference:\n${task.originalPrompt}`;
|
|
434
|
+
return { rewrittenPrompt, strategy: FailureCategory.STUCK_ON_COMPLEXITY, appliedContext };
|
|
435
|
+
}
|
|
436
|
+
// ------------------------------------------------------------------
|
|
437
|
+
// Pattern learning
|
|
438
|
+
// ------------------------------------------------------------------
|
|
439
|
+
/**
|
|
440
|
+
* Persist a rewrite pattern to the memory layer after a successful retry.
|
|
441
|
+
*
|
|
442
|
+
* Call this from `runWithRetry` callbacks (or from application code) when a
|
|
443
|
+
* rewritten prompt leads to a successful contract execution. Each stored
|
|
444
|
+
* pattern carries a `successCount`; once a pattern reaches
|
|
445
|
+
* `HIGH_CONFIDENCE_MIN` (5) successes it will be used as a shortcut by
|
|
446
|
+
* `rewritePrompt()`.
|
|
447
|
+
*
|
|
448
|
+
* @param options - Pattern metadata including capability, category, and count
|
|
449
|
+
* @param memory - Memory layer instance to persist the pattern into
|
|
450
|
+
* @returns The memory ID assigned by the provider
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* ```typescript
|
|
454
|
+
* await dm.learnPattern(
|
|
455
|
+
* {
|
|
456
|
+
* agentId: 'my-agent',
|
|
457
|
+
* taskId: 'task-auth',
|
|
458
|
+
* capability: 'code_generation',
|
|
459
|
+
* failureCategory: FailureCategory.CONTEXT_OVERFLOW,
|
|
460
|
+
* contextType: 'scope_restriction',
|
|
461
|
+
* successCount: existingPattern ? existingPattern.successCount + 1 : 1,
|
|
462
|
+
* effectiveRewrite: rewriteResult.rewrittenPrompt,
|
|
463
|
+
* },
|
|
464
|
+
* memory,
|
|
465
|
+
* );
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
async learnPattern(options, memory) {
|
|
469
|
+
const pattern = {
|
|
470
|
+
capability: options.capability,
|
|
471
|
+
failureCategory: options.failureCategory,
|
|
472
|
+
contextType: options.contextType,
|
|
473
|
+
successCount: options.successCount,
|
|
474
|
+
lastSuccessAt: new Date().toISOString(),
|
|
475
|
+
effectiveRewrite: options.effectiveRewrite,
|
|
476
|
+
};
|
|
477
|
+
const sessionId = `${options.capability}__${options.failureCategory}__${options.taskId}`;
|
|
478
|
+
return memory.addAgentMemory(PATTERN_NAMESPACE, sessionId, pattern);
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Queries the memory layer for a high-confidence pattern matching the given
|
|
482
|
+
* failure category and agent.
|
|
483
|
+
*
|
|
484
|
+
* A pattern is considered high-confidence when `successCount >=
|
|
485
|
+
* HIGH_CONFIDENCE_MIN` (5). The method returns the best matching
|
|
486
|
+
* high-confidence pattern or `null` if none is found.
|
|
487
|
+
*
|
|
488
|
+
* @param agentId - Agent namespace for the pattern lookup
|
|
489
|
+
* @param failureCategory - Category to search for
|
|
490
|
+
* @param memory - Memory layer instance
|
|
491
|
+
* @returns Highest-successCount high-confidence pattern, or `null`
|
|
492
|
+
*/
|
|
493
|
+
async queryHighConfidencePattern(agentId, failureCategory, memory) {
|
|
494
|
+
let results;
|
|
495
|
+
try {
|
|
496
|
+
results = await memory.searchAgentMemories(PATTERN_NAMESPACE, `${failureCategory} ${agentId}`, HIGH_CONFIDENCE_MIN);
|
|
497
|
+
}
|
|
498
|
+
catch {
|
|
499
|
+
// Memory lookup failures must never break the rewrite pipeline
|
|
500
|
+
return null;
|
|
501
|
+
}
|
|
502
|
+
const patterns = [];
|
|
503
|
+
for (const r of results) {
|
|
504
|
+
// Primary path: structured data via metadata.state (dcyfr-memory impl)
|
|
505
|
+
const state = r.metadata?.['state'];
|
|
506
|
+
if (state?.failureCategory === failureCategory && typeof state.successCount === 'number') {
|
|
507
|
+
patterns.push(state);
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
// Fallback: try JSON.parse on content (some providers serialise inline)
|
|
511
|
+
try {
|
|
512
|
+
const parsed = JSON.parse(r.content);
|
|
513
|
+
if (parsed?.failureCategory === failureCategory && typeof parsed.successCount === 'number') {
|
|
514
|
+
patterns.push(parsed);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
catch {
|
|
518
|
+
// Not JSON — skip
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
const highConfidence = patterns.filter(p => p.successCount >= HIGH_CONFIDENCE_MIN);
|
|
522
|
+
if (highConfidence.length === 0)
|
|
523
|
+
return null;
|
|
524
|
+
// Return the pattern with the highest successCount
|
|
525
|
+
return highConfidence.reduce((best, p) => p.successCount > best.successCount ? p : best);
|
|
526
|
+
}
|
|
527
|
+
// ------------------------------------------------------------------
|
|
528
|
+
// Token budget management
|
|
529
|
+
// ------------------------------------------------------------------
|
|
530
|
+
/**
|
|
531
|
+
* Estimates the token count of a string using the 1-token ≈ 4-characters
|
|
532
|
+
* heuristic (industry standard for English prose and TypeScript code).
|
|
533
|
+
*
|
|
534
|
+
* The result is intentionally an over-estimate for safety — it is slightly
|
|
535
|
+
* higher than exact tiktoken counts on average, which means the budget cap
|
|
536
|
+
* will trigger a little early rather than too late.
|
|
537
|
+
*
|
|
538
|
+
* @param text - The string to estimate tokens for
|
|
539
|
+
* @returns Estimated token count (always ≥ 1)
|
|
540
|
+
*/
|
|
541
|
+
estimateTokens(text) {
|
|
542
|
+
return Math.max(1, Math.ceil(text.length / 4));
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Summarises older injected context blocks to a 1-sentence placeholder,
|
|
546
|
+
* keeping the `keepVerbatim` most-recent blocks intact.
|
|
547
|
+
*
|
|
548
|
+
* Blocks are delimited by double newlines. If there are `keepVerbatim` or
|
|
549
|
+
* fewer blocks the section is returned unmodified.
|
|
550
|
+
*
|
|
551
|
+
* @param section - The injected section text (header or footer)
|
|
552
|
+
* @param keepVerbatim - Number of recent blocks to preserve verbatim
|
|
553
|
+
* @returns The (possibly summarised) section text
|
|
554
|
+
*/
|
|
555
|
+
summarizeInjectedSection(section, keepVerbatim) {
|
|
556
|
+
const trimmed = section.trim();
|
|
557
|
+
if (!trimmed)
|
|
558
|
+
return section;
|
|
559
|
+
const blocks = section.split(/\n\n+/);
|
|
560
|
+
const nonEmpty = blocks.filter(b => b.trim());
|
|
561
|
+
if (nonEmpty.length <= keepVerbatim)
|
|
562
|
+
return section;
|
|
563
|
+
const olderCount = nonEmpty.length - keepVerbatim;
|
|
564
|
+
const keptBlocks = nonEmpty.slice(olderCount);
|
|
565
|
+
const summary = `[${olderCount} earlier context block(s) summarized to save token budget — ` +
|
|
566
|
+
`see rewrite log for full content]`;
|
|
567
|
+
return summary + '\n\n' + keptBlocks.join('\n\n');
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Applies the token budget cap to a raw `RewriteResult`.
|
|
571
|
+
*
|
|
572
|
+
* 1. Estimates `originalTokens`, `addedTokens`, and `finalTokens`.
|
|
573
|
+
* 2. If `finalTokens > budgetTokens` (80% of context window), trims the
|
|
574
|
+
* injected additions by summarising older context blocks while keeping
|
|
575
|
+
* the last `VERBATIM_BLOCK_KEEP_COUNT` (3) blocks verbatim.
|
|
576
|
+
* 3. The original prompt is always preserved verbatim.
|
|
577
|
+
* 4. Appends token budget telemetry to `appliedContext`.
|
|
578
|
+
*
|
|
579
|
+
* @param result - Raw rewrite result from a strategy or pattern shortcut
|
|
580
|
+
* @param task - Original task (used for context window override + prompt)
|
|
581
|
+
* @returns Updated result with `tokenBudget` populated
|
|
582
|
+
*/
|
|
583
|
+
applyTokenBudget(result, task) {
|
|
584
|
+
const contextWindowTokens = task.contextWindowTokens ?? DEFAULT_CONTEXT_WINDOW_TOKENS;
|
|
585
|
+
const budgetTokens = Math.floor(contextWindowTokens * PROMPT_BUDGET_RATIO);
|
|
586
|
+
const originalTokens = this.estimateTokens(task.originalPrompt);
|
|
587
|
+
let { rewrittenPrompt } = result;
|
|
588
|
+
const rawTokens = this.estimateTokens(rewrittenPrompt);
|
|
589
|
+
const wasOverBudget = rawTokens > budgetTokens;
|
|
590
|
+
if (wasOverBudget) {
|
|
591
|
+
// Locate the original prompt within the rewritten output so we can split
|
|
592
|
+
// it into header (prepended context) and footer (appended context).
|
|
593
|
+
const origIdx = rewrittenPrompt.indexOf(task.originalPrompt);
|
|
594
|
+
if (origIdx !== -1) {
|
|
595
|
+
const header = rewrittenPrompt.slice(0, origIdx);
|
|
596
|
+
const footer = rewrittenPrompt.slice(origIdx + task.originalPrompt.length);
|
|
597
|
+
const trimmedHeader = this.summarizeInjectedSection(header, VERBATIM_BLOCK_KEEP_COUNT);
|
|
598
|
+
const trimmedFooter = this.summarizeInjectedSection(footer, VERBATIM_BLOCK_KEEP_COUNT);
|
|
599
|
+
rewrittenPrompt = trimmedHeader + task.originalPrompt + trimmedFooter;
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
const finalTokens = this.estimateTokens(rewrittenPrompt);
|
|
603
|
+
const addedTokens = Math.max(0, finalTokens - originalTokens);
|
|
604
|
+
const tokenBudget = {
|
|
605
|
+
originalTokens,
|
|
606
|
+
addedTokens,
|
|
607
|
+
finalTokens,
|
|
608
|
+
budgetTokens,
|
|
609
|
+
overBudget: wasOverBudget,
|
|
610
|
+
};
|
|
611
|
+
const appliedContext = [...result.appliedContext];
|
|
612
|
+
if (wasOverBudget) {
|
|
613
|
+
appliedContext.push(`token-budget: over-budget — trimmed injected blocks ` +
|
|
614
|
+
`(raw=${rawTokens}, final=${finalTokens}, budget=${budgetTokens} tokens)`);
|
|
615
|
+
}
|
|
616
|
+
appliedContext.push(`token-budget: originalTokens=${originalTokens}, addedTokens=${addedTokens}, ` +
|
|
617
|
+
`finalTokens=${finalTokens}, budgetTokens=${budgetTokens}`);
|
|
618
|
+
return { ...result, rewrittenPrompt, appliedContext, tokenBudget };
|
|
619
|
+
}
|
|
620
|
+
// ------------------------------------------------------------------
|
|
621
|
+
// runWithRetry — Ralph Loop V2 orchestration
|
|
622
|
+
// ------------------------------------------------------------------
|
|
623
|
+
/**
|
|
624
|
+
* Ralph Loop V2 retry orchestration.
|
|
625
|
+
*
|
|
626
|
+
* Runs `executeAttempt` up to `maxRetries` times. After each failure:
|
|
627
|
+
* 1. Calls `analyzeFailure()` to categorise the problem.
|
|
628
|
+
* 2. Calls `rewritePrompt()` to produce an improved prompt.
|
|
629
|
+
* 3. Logs the rewrite to `data/rewrite-history.jsonl`.
|
|
630
|
+
*
|
|
631
|
+
* If the maximum number of attempts is reached without success, an
|
|
632
|
+
* escalation notification is sent via Telegram (requires
|
|
633
|
+
* `TELEGRAM_BOT_TOKEN` + `TELEGRAM_CHAT_ID` env vars).
|
|
634
|
+
*
|
|
635
|
+
* @example
|
|
636
|
+
* ```typescript
|
|
637
|
+
* const result = await dm.runWithRetry({
|
|
638
|
+
* initialPrompt: 'Implement auth module.',
|
|
639
|
+
* taskId: 'task-auth',
|
|
640
|
+
* memory,
|
|
641
|
+
* executeAttempt: async (prompt) => {
|
|
642
|
+
* // ... run agent, return ContractResult
|
|
643
|
+
* },
|
|
644
|
+
* isSuccess: (r) => (r.commit_count ?? 0) > 0 && !r.error_output,
|
|
645
|
+
* });
|
|
646
|
+
* ```
|
|
647
|
+
*/
|
|
648
|
+
async runWithRetry(options) {
|
|
649
|
+
const maxRetries = options.maxRetries ?? MAX_RETRIES;
|
|
650
|
+
const logPath = options.logPath === null ? null : (options.logPath ?? DEFAULT_REWRITE_LOG_PATH);
|
|
651
|
+
const attempts = [];
|
|
652
|
+
let currentPrompt = options.initialPrompt;
|
|
653
|
+
let escalated = false;
|
|
654
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
655
|
+
const result = await options.executeAttempt(currentPrompt, attempt);
|
|
656
|
+
if (options.isSuccess(result)) {
|
|
657
|
+
attempts.push({ attempt, prompt: currentPrompt, result });
|
|
658
|
+
return {
|
|
659
|
+
success: true,
|
|
660
|
+
attempts,
|
|
661
|
+
finalResult: result,
|
|
662
|
+
totalAttempts: attempt,
|
|
663
|
+
escalated: false,
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
const analysis = this.analyzeFailure(result);
|
|
667
|
+
if (attempt === maxRetries) {
|
|
668
|
+
// Final attempt failed — escalate before returning
|
|
669
|
+
attempts.push({ attempt, prompt: currentPrompt, result, analysis });
|
|
670
|
+
escalated = await this.sendTelegramEscalation(options.taskId, maxRetries, analysis);
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
const rewriteTask = {
|
|
674
|
+
originalPrompt: currentPrompt,
|
|
675
|
+
taskId: options.taskId,
|
|
676
|
+
agentId: options.agentId,
|
|
677
|
+
changedFiles: result.changed_files,
|
|
678
|
+
taskScopePaths: options.taskScopePaths ?? result.task_scope_paths,
|
|
679
|
+
};
|
|
680
|
+
const rewrite = await this.rewritePrompt(rewriteTask, analysis.category, options.memory);
|
|
681
|
+
if (logPath !== null) {
|
|
682
|
+
await this.appendRewriteLog(logPath, {
|
|
683
|
+
taskId: options.taskId,
|
|
684
|
+
contractId: result.contract.contract_id,
|
|
685
|
+
attempt,
|
|
686
|
+
failureCategory: analysis.category,
|
|
687
|
+
confidence: analysis.confidence,
|
|
688
|
+
signals: analysis.signals,
|
|
689
|
+
promptBeforeLength: currentPrompt.length,
|
|
690
|
+
promptAfterLength: rewrite.rewrittenPrompt.length,
|
|
691
|
+
appliedContext: rewrite.appliedContext,
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
attempts.push({ attempt, prompt: currentPrompt, result, analysis, rewrite });
|
|
695
|
+
currentPrompt = rewrite.rewrittenPrompt;
|
|
696
|
+
}
|
|
697
|
+
return {
|
|
698
|
+
success: false,
|
|
699
|
+
attempts,
|
|
700
|
+
finalResult: attempts[attempts.length - 1].result,
|
|
701
|
+
totalAttempts: attempts.length,
|
|
702
|
+
escalated,
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
// ------------------------------------------------------------------
|
|
706
|
+
// Private helpers — escalation + logging
|
|
707
|
+
// ------------------------------------------------------------------
|
|
708
|
+
/**
|
|
709
|
+
* Sends a Telegram message to notify humans of a triple-failure escalation.
|
|
710
|
+
*
|
|
711
|
+
* Reads `TELEGRAM_BOT_TOKEN` and `TELEGRAM_CHAT_ID` from `process.env`.
|
|
712
|
+
* When either is missing, logs a warning and returns `false` (silent skip).
|
|
713
|
+
*
|
|
714
|
+
* @returns `true` if the message was sent, `false` otherwise.
|
|
715
|
+
*/
|
|
716
|
+
async sendTelegramEscalation(taskId, maxRetries, analysis) {
|
|
717
|
+
const token = process.env['TELEGRAM_BOT_TOKEN'];
|
|
718
|
+
const chatId = process.env['TELEGRAM_CHAT_ID'];
|
|
719
|
+
if (!token || !chatId) {
|
|
720
|
+
// Not configured — skip silently (warn in case someone is watching)
|
|
721
|
+
process.stderr.write(`[DelegationManager] Telegram escalation skipped: ` +
|
|
722
|
+
`TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID not set.\n`);
|
|
723
|
+
return false;
|
|
724
|
+
}
|
|
725
|
+
const message = `🚨 *Ralph Loop V2 Escalation*\n` +
|
|
726
|
+
`Task *${taskId}* failed after *${maxRetries}* attempt(s).\n` +
|
|
727
|
+
`Category: \`${analysis.category}\` (confidence: ${(analysis.confidence * 100).toFixed(0)}%)\n` +
|
|
728
|
+
`Signals:\n${analysis.signals.map(s => `• ${s}`).join('\n')}\n` +
|
|
729
|
+
`Contract: \`${analysis.contract_id}\`\n` +
|
|
730
|
+
`Requires human review.`;
|
|
731
|
+
const url = `https://api.telegram.org/bot${token}/sendMessage`;
|
|
732
|
+
try {
|
|
733
|
+
const response = await fetch(url, {
|
|
734
|
+
method: 'POST',
|
|
735
|
+
headers: { 'Content-Type': 'application/json' },
|
|
736
|
+
body: JSON.stringify({ chat_id: chatId, text: message, parse_mode: 'Markdown' }),
|
|
737
|
+
});
|
|
738
|
+
if (!response.ok) {
|
|
739
|
+
const body = await response.text();
|
|
740
|
+
process.stderr.write(`[DelegationManager] Telegram API error ${response.status}: ${body}\n`);
|
|
741
|
+
return false;
|
|
742
|
+
}
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
catch (err) {
|
|
746
|
+
process.stderr.write(`[DelegationManager] Telegram fetch failed: ${String(err)}\n`);
|
|
747
|
+
return false;
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Appends one JSONL entry to the rewrite-history log.
|
|
752
|
+
* Creates the parent directory if it doesn't exist.
|
|
753
|
+
*/
|
|
754
|
+
async appendRewriteLog(logPath, entry) {
|
|
755
|
+
const record = JSON.stringify({
|
|
756
|
+
timestamp: new Date().toISOString(),
|
|
757
|
+
...entry,
|
|
758
|
+
});
|
|
759
|
+
try {
|
|
760
|
+
await mkdir(dirname(logPath), { recursive: true });
|
|
761
|
+
await appendFile(logPath, `${record}\n`, 'utf8');
|
|
762
|
+
}
|
|
763
|
+
catch (err) {
|
|
764
|
+
// Non-fatal — log errors should never break the retry loop
|
|
765
|
+
process.stderr.write(`[DelegationManager] Failed to write rewrite log: ${String(err)}\n`);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Default singleton — suitable for non-test usage.
|
|
771
|
+
*/
|
|
772
|
+
export const delegationManager = new DelegationManager();
|
|
773
|
+
//# sourceMappingURL=delegation-manager.js.map
|