groundswell 0.0.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +26 -9
- package/dist/cache/cache-key.d.ts +86 -0
- package/dist/cache/cache-key.d.ts.map +1 -0
- package/dist/cache/cache-key.js +204 -0
- package/dist/cache/cache-key.js.map +1 -0
- package/dist/cache/cache.d.ts +104 -0
- package/dist/cache/cache.d.ts.map +1 -0
- package/dist/cache/cache.js +179 -0
- package/dist/cache/cache.js.map +1 -0
- package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +6 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/core/agent.d.ts +203 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +833 -0
- package/dist/core/agent.js.map +1 -0
- package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +80 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/event-tree.d.ts +72 -0
- package/dist/core/event-tree.d.ts.map +1 -0
- package/dist/core/event-tree.js +211 -0
- package/dist/core/event-tree.js.map +1 -0
- package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
- package/dist/core/factory.d.ts.map +1 -0
- package/dist/core/factory.js +110 -0
- package/dist/core/factory.js.map +1 -0
- package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/logger.d.ts +50 -0
- package/dist/core/logger.d.ts.map +1 -0
- package/dist/core/logger.js +91 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/mcp-handler.d.ts +127 -0
- package/dist/core/mcp-handler.d.ts.map +1 -0
- package/dist/core/mcp-handler.js +323 -0
- package/dist/core/mcp-handler.js.map +1 -0
- package/dist/core/prompt.d.ts +80 -0
- package/dist/core/prompt.d.ts.map +1 -0
- package/dist/core/prompt.js +120 -0
- package/dist/core/prompt.js.map +1 -0
- package/dist/core/workflow-context.d.ts +61 -0
- package/dist/core/workflow-context.d.ts.map +1 -0
- package/dist/core/workflow-context.js +358 -0
- package/dist/core/workflow-context.js.map +1 -0
- package/dist/core/workflow.d.ts +543 -0
- package/dist/core/workflow.d.ts.map +1 -0
- package/dist/core/workflow.js +986 -0
- package/dist/core/workflow.js.map +1 -0
- package/dist/debugger/event-replayer.d.ts +422 -0
- package/dist/debugger/event-replayer.d.ts.map +1 -0
- package/dist/debugger/event-replayer.js +639 -0
- package/dist/debugger/event-replayer.js.map +1 -0
- package/dist/debugger/index.d.ts +2 -0
- package/dist/debugger/index.d.ts.map +1 -0
- package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
- package/dist/debugger/index.js.map +1 -0
- package/dist/debugger/tree-debugger.d.ts +240 -0
- package/dist/debugger/tree-debugger.d.ts.map +1 -0
- package/dist/debugger/tree-debugger.js +620 -0
- package/dist/debugger/tree-debugger.js.map +1 -0
- package/dist/decorators/index.d.ts +4 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/observed-state.d.ts +32 -0
- package/dist/decorators/observed-state.d.ts.map +1 -0
- package/dist/decorators/observed-state.js +79 -0
- package/dist/decorators/observed-state.js.map +1 -0
- package/dist/decorators/step.d.ts +15 -0
- package/dist/decorators/step.d.ts.map +1 -0
- package/dist/decorators/step.js +192 -0
- package/dist/decorators/step.js.map +1 -0
- package/dist/decorators/task.d.ts +50 -0
- package/dist/decorators/task.d.ts.map +1 -0
- package/dist/decorators/task.js +118 -0
- package/dist/decorators/task.js.map +1 -0
- package/dist/examples/index.d.ts +3 -0
- package/dist/examples/index.d.ts.map +1 -0
- package/{src/examples/index.ts → dist/examples/index.js} +1 -0
- package/dist/examples/index.js.map +1 -0
- package/dist/examples/tdd-orchestrator.d.ts +15 -0
- package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
- package/dist/examples/tdd-orchestrator.js +121 -0
- package/dist/examples/tdd-orchestrator.js.map +1 -0
- package/dist/examples/test-cycle-workflow.d.ts +14 -0
- package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
- package/dist/examples/test-cycle-workflow.js +116 -0
- package/dist/examples/test-cycle-workflow.js.map +1 -0
- package/dist/harnesses/claude-code-harness.d.ts +391 -0
- package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
- package/dist/harnesses/claude-code-harness.js +1076 -0
- package/dist/harnesses/claude-code-harness.js.map +1 -0
- package/dist/harnesses/harness-registry.d.ts +440 -0
- package/dist/harnesses/harness-registry.d.ts.map +1 -0
- package/dist/harnesses/harness-registry.js +543 -0
- package/dist/harnesses/harness-registry.js.map +1 -0
- package/dist/harnesses/index.d.ts +12 -0
- package/dist/harnesses/index.d.ts.map +1 -0
- package/dist/harnesses/index.js +11 -0
- package/dist/harnesses/index.js.map +1 -0
- package/dist/harnesses/pi-harness.d.ts +219 -0
- package/dist/harnesses/pi-harness.d.ts.map +1 -0
- package/dist/harnesses/pi-harness.js +676 -0
- package/dist/harnesses/pi-harness.js.map +1 -0
- package/dist/harnesses/pi-schema-converter.d.ts +24 -0
- package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
- package/dist/harnesses/pi-schema-converter.js +81 -0
- package/dist/harnesses/pi-schema-converter.js.map +1 -0
- package/dist/harnesses/register-defaults.d.ts +24 -0
- package/dist/harnesses/register-defaults.d.ts.map +1 -0
- package/dist/harnesses/register-defaults.js +40 -0
- package/dist/harnesses/register-defaults.js.map +1 -0
- package/dist/harnesses/session-store.d.ts +201 -0
- package/dist/harnesses/session-store.d.ts.map +1 -0
- package/dist/harnesses/session-store.js +254 -0
- package/dist/harnesses/session-store.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/reflection/index.d.ts +5 -0
- package/dist/reflection/index.d.ts.map +1 -0
- package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
- package/dist/reflection/index.js.map +1 -0
- package/dist/reflection/reflection.d.ts +84 -0
- package/dist/reflection/reflection.d.ts.map +1 -0
- package/dist/reflection/reflection.js +344 -0
- package/dist/reflection/reflection.js.map +1 -0
- package/dist/tools/index.d.ts +6 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +11 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/introspection.d.ts +165 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js +324 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/types/agent.d.ts +1317 -0
- package/dist/types/agent.d.ts.map +1 -0
- package/dist/types/agent.js +423 -0
- package/dist/types/agent.js.map +1 -0
- package/dist/types/decorators.d.ts +40 -0
- package/dist/types/decorators.d.ts.map +1 -0
- package/dist/types/decorators.js +2 -0
- package/dist/types/decorators.js.map +1 -0
- package/dist/types/error-strategy.d.ts +13 -0
- package/dist/types/error-strategy.d.ts.map +1 -0
- package/dist/types/error-strategy.js +2 -0
- package/dist/types/error-strategy.js.map +1 -0
- package/dist/types/error.d.ts +20 -0
- package/dist/types/error.d.ts.map +1 -0
- package/dist/types/error.js +2 -0
- package/dist/types/error.js.map +1 -0
- package/dist/types/events.d.ts +113 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +2 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/harnesses.d.ts +474 -0
- package/dist/types/harnesses.d.ts.map +1 -0
- package/dist/types/harnesses.js +2 -0
- package/dist/types/harnesses.js.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logging.d.ts +24 -0
- package/dist/types/logging.d.ts.map +1 -0
- package/dist/types/logging.js +2 -0
- package/dist/types/logging.js.map +1 -0
- package/dist/types/observer.d.ts +18 -0
- package/dist/types/observer.d.ts.map +1 -0
- package/dist/types/observer.js +2 -0
- package/dist/types/observer.js.map +1 -0
- package/dist/types/prompt.d.ts +31 -0
- package/dist/types/prompt.d.ts.map +1 -0
- package/dist/types/prompt.js +6 -0
- package/dist/types/prompt.js.map +1 -0
- package/dist/types/providers.d.ts +691 -0
- package/dist/types/providers.d.ts.map +1 -0
- package/dist/types/providers.js +14 -0
- package/dist/types/providers.js.map +1 -0
- package/dist/types/reflection.d.ts +96 -0
- package/dist/types/reflection.d.ts.map +1 -0
- package/dist/types/reflection.js +24 -0
- package/dist/types/reflection.js.map +1 -0
- package/dist/types/restart.d.ts +132 -0
- package/dist/types/restart.d.ts.map +1 -0
- package/dist/types/restart.js +2 -0
- package/dist/types/restart.js.map +1 -0
- package/dist/types/sdk-primitives.d.ts +118 -0
- package/dist/types/sdk-primitives.d.ts.map +1 -0
- package/dist/types/sdk-primitives.js +6 -0
- package/dist/types/sdk-primitives.js.map +1 -0
- package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
- package/dist/types/snapshot.d.ts.map +1 -0
- package/dist/types/snapshot.js +2 -0
- package/dist/types/snapshot.js.map +1 -0
- package/dist/types/streaming.d.ts +194 -0
- package/dist/types/streaming.d.ts.map +1 -0
- package/dist/types/streaming.js +67 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/types/workflow-context.d.ts +275 -0
- package/dist/types/workflow-context.d.ts.map +1 -0
- package/dist/types/workflow-context.js +8 -0
- package/dist/types/workflow-context.js.map +1 -0
- package/dist/types/workflow.d.ts +30 -0
- package/dist/types/workflow.d.ts.map +1 -0
- package/dist/types/workflow.js +2 -0
- package/dist/types/workflow.js.map +1 -0
- package/dist/utils/agent-validation.d.ts +88 -0
- package/dist/utils/agent-validation.d.ts.map +1 -0
- package/dist/utils/agent-validation.js +87 -0
- package/dist/utils/agent-validation.js.map +1 -0
- package/dist/utils/delay.d.ts +7 -0
- package/dist/utils/delay.d.ts.map +1 -0
- package/dist/utils/delay.js +9 -0
- package/dist/utils/delay.js.map +1 -0
- package/dist/utils/harness-config.d.ts +180 -0
- package/dist/utils/harness-config.d.ts.map +1 -0
- package/dist/utils/harness-config.js +311 -0
- package/dist/utils/harness-config.js.map +1 -0
- package/dist/utils/id.d.ts +6 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +11 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/model-spec.d.ts +110 -0
- package/dist/utils/model-spec.d.ts.map +1 -0
- package/dist/utils/model-spec.js +149 -0
- package/dist/utils/model-spec.js.map +1 -0
- package/dist/utils/observable.d.ts +54 -0
- package/dist/utils/observable.d.ts.map +1 -0
- package/dist/utils/observable.js +82 -0
- package/dist/utils/observable.js.map +1 -0
- package/dist/utils/provider-config.d.ts +10 -0
- package/dist/utils/provider-config.d.ts.map +1 -0
- package/dist/utils/provider-config.js +10 -0
- package/dist/utils/provider-config.js.map +1 -0
- package/dist/utils/restart-analysis.d.ts +202 -0
- package/dist/utils/restart-analysis.d.ts.map +1 -0
- package/dist/utils/restart-analysis.js +426 -0
- package/dist/utils/restart-analysis.js.map +1 -0
- package/dist/utils/session-serialization.d.ts +118 -0
- package/dist/utils/session-serialization.d.ts.map +1 -0
- package/dist/utils/session-serialization.js +217 -0
- package/dist/utils/session-serialization.js.map +1 -0
- package/dist/utils/workflow-error-utils.d.ts +22 -0
- package/dist/utils/workflow-error-utils.d.ts.map +1 -0
- package/dist/utils/workflow-error-utils.js +45 -0
- package/dist/utils/workflow-error-utils.js.map +1 -0
- package/package.json +34 -5
- package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
- package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
- package/.claude/commands/task-breakdown.md +0 -94
- package/.claude/settings.local.json +0 -9
- package/.claude/system_prompts/task-breakdown.md +0 -101
- package/CHANGELOG.md +0 -188
- package/PRD.md +0 -543
- package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
- package/PRPs/PRDs/002-agent-prompt.md +0 -390
- package/PRPs/PRDs/003-agent-prompt.md +0 -943
- package/PRPs/PRDs/004-agent-prompt.md +0 -1136
- package/PRPs/PRDs/tasks-001.json +0 -492
- package/PRPs/README.md +0 -83
- package/PRPs/templates/prp_base.md +0 -222
- package/docs/agent.md +0 -422
- package/docs/prompt.md +0 -419
- package/docs/workflow.md +0 -600
- package/examples/README.md +0 -258
- package/examples/examples/01-basic-workflow.ts +0 -100
- package/examples/examples/02-decorator-options.ts +0 -217
- package/examples/examples/03-parent-child.ts +0 -241
- package/examples/examples/04-observers-debugger.ts +0 -340
- package/examples/examples/05-error-handling.ts +0 -387
- package/examples/examples/06-concurrent-tasks.ts +0 -352
- package/examples/examples/07-agent-loops.ts +0 -432
- package/examples/examples/08-sdk-features.ts +0 -667
- package/examples/examples/09-reflection.ts +0 -573
- package/examples/examples/10-introspection.ts +0 -550
- package/examples/examples/11-reparenting-workflows.ts +0 -269
- package/examples/index.ts +0 -147
- package/examples/utils/helpers.ts +0 -57
- package/package-lock.json +0 -2398
- package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
- package/plan/001_d3bb02af4886/backlog.json +0 -867
- package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
- package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
- package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
- package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
- package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
- package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
- package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
- package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
- package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
- package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
- package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
- package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
- package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
- package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
- package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
- package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
- package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
- package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
- package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
- package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
- package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
- package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
- package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
- package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
- package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
- package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
- package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
- package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
- package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
- package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
- package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
- package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
- package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
- package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
- package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
- package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
- package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
- package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
- package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
- package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
- package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
- package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
- package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
- package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
- package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
- package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
- package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
- package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
- package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
- package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
- package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
- package/scripts/generate-llms-full.ts +0 -206
- package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
- package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
- package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
- package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
- package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
- package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
- package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
- package/src/__tests__/adversarial/edge-case.test.ts +0 -703
- package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
- package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
- package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
- package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
- package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
- package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
- package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
- package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
- package/src/__tests__/helpers/index.ts +0 -18
- package/src/__tests__/helpers/tree-verification.ts +0 -257
- package/src/__tests__/integration/agent-workflow.test.ts +0 -256
- package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
- package/src/__tests__/integration/observer-logging.test.ts +0 -643
- package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
- package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
- package/src/__tests__/unit/agent.test.ts +0 -169
- package/src/__tests__/unit/cache-key.test.ts +0 -182
- package/src/__tests__/unit/cache.test.ts +0 -172
- package/src/__tests__/unit/context.test.ts +0 -217
- package/src/__tests__/unit/decorators.test.ts +0 -100
- package/src/__tests__/unit/introspection-tools.test.ts +0 -277
- package/src/__tests__/unit/logger.test.ts +0 -293
- package/src/__tests__/unit/observable.test.ts +0 -321
- package/src/__tests__/unit/prompt.test.ts +0 -135
- package/src/__tests__/unit/reflection.test.ts +0 -210
- package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
- package/src/__tests__/unit/tree-debugger.test.ts +0 -85
- package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
- package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
- package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
- package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
- package/src/__tests__/unit/workflow.test.ts +0 -357
- package/src/cache/cache-key.ts +0 -244
- package/src/cache/cache.ts +0 -236
- package/src/core/agent.ts +0 -593
- package/src/core/event-tree.ts +0 -260
- package/src/core/logger.ts +0 -112
- package/src/core/mcp-handler.ts +0 -184
- package/src/core/prompt.ts +0 -150
- package/src/core/workflow-context.ts +0 -351
- package/src/core/workflow.ts +0 -540
- package/src/debugger/tree-debugger.ts +0 -255
- package/src/decorators/observed-state.ts +0 -95
- package/src/decorators/step.ts +0 -139
- package/src/decorators/task.ts +0 -159
- package/src/examples/tdd-orchestrator.ts +0 -65
- package/src/examples/test-cycle-workflow.ts +0 -64
- package/src/index.ts +0 -142
- package/src/reflection/reflection.ts +0 -407
- package/src/tools/index.ts +0 -36
- package/src/tools/introspection.ts +0 -464
- package/src/types/agent.ts +0 -90
- package/src/types/decorators.ts +0 -32
- package/src/types/error-strategy.ts +0 -13
- package/src/types/error.ts +0 -20
- package/src/types/events.ts +0 -75
- package/src/types/index.ts +0 -55
- package/src/types/logging.ts +0 -24
- package/src/types/observer.ts +0 -18
- package/src/types/prompt.ts +0 -40
- package/src/types/reflection.ts +0 -117
- package/src/types/sdk-primitives.ts +0 -128
- package/src/types/workflow-context.ts +0 -163
- package/src/types/workflow.ts +0 -37
- package/src/utils/id.ts +0 -11
- package/src/utils/index.ts +0 -4
- package/src/utils/observable.ts +0 -106
- package/src/utils/workflow-error-utils.ts +0 -56
- package/tsconfig.json +0 -22
- package/vitest.config.ts +0 -16
|
@@ -1,738 +0,0 @@
|
|
|
1
|
-
# LRU Cache Integration Guide for Groundswell
|
|
2
|
-
|
|
3
|
-
**Framework Integration Patterns and Decision Matrix**
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Table of Contents
|
|
8
|
-
|
|
9
|
-
1. [Quick Decision Matrix](#quick-decision-matrix)
|
|
10
|
-
2. [Integration Strategies](#integration-strategies)
|
|
11
|
-
3. [Framework-Specific Integration](#framework-specific-integration)
|
|
12
|
-
4. [Migration Path](#migration-path)
|
|
13
|
-
5. [Troubleshooting](#troubleshooting)
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
## Quick Decision Matrix
|
|
18
|
-
|
|
19
|
-
### Choose Your Caching Strategy
|
|
20
|
-
|
|
21
|
-
| Requirement | Exact Cache | Semantic Cache | Hybrid | Comment |
|
|
22
|
-
|-------------|------------|----------------|--------|---------|
|
|
23
|
-
| **Hit Rate** | 30-40% | 60-70% | 65-75% | Semantic better for paraphrased queries |
|
|
24
|
-
| **Latency** | <1ms | 10-50ms | 5-30ms | Exact fastest, semantic requires embedding |
|
|
25
|
-
| **Memory** | Low | High | Medium | Semantic stores embeddings |
|
|
26
|
-
| **Setup** | Easy | Complex | Medium | Semantic needs embedding model |
|
|
27
|
-
| **Use Case** | Repeated identical queries | Similar meaning queries | Production | Choose based on user patterns |
|
|
28
|
-
|
|
29
|
-
### Deployment Environment
|
|
30
|
-
|
|
31
|
-
| Environment | Recommendation | Config |
|
|
32
|
-
|-------------|-----------------|--------|
|
|
33
|
-
| **Development** | Single-process in-memory | max: 100, ttl: 10min |
|
|
34
|
-
| **Staging** | Single-process with monitoring | max: 1000, ttl: 1hr |
|
|
35
|
-
| **Production (Single Node)** | In-memory with persistence | max: 5000, maxSize: 500MB |
|
|
36
|
-
| **Production (Multi-Node)** | Redis + in-memory L1 | L1: max 1000, L2: Redis |
|
|
37
|
-
| **High-Load** | Redis + semantic cache | Consider GPTCache library |
|
|
38
|
-
|
|
39
|
-
### Package Selection
|
|
40
|
-
|
|
41
|
-
| Package | When to Use | Performance | Notes |
|
|
42
|
-
|---------|------------|-------------|-------|
|
|
43
|
-
| **lru-cache** | v10+ for all cases | Excellent | Built-in types, recommended |
|
|
44
|
-
| **safe-stable-stringify** | Production LLM cache | Fast (~13k ops/sec) | Handles circular refs, zero deps |
|
|
45
|
-
| **fast-json-stable-stringify** | Performance-critical | Fastest (~17k ops/sec) | No circular ref support |
|
|
46
|
-
| **Redis (node-redis)** | Multi-node deployment | Depends on network | Shared cache across processes |
|
|
47
|
-
| **SQLite** | Persistent cache | Slow but durable | Good for offline testing |
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## Integration Strategies
|
|
52
|
-
|
|
53
|
-
### Strategy 1: Minimal Integration (Recommended for MVP)
|
|
54
|
-
|
|
55
|
-
**When:** Simple LLM query caching, single-node deployment, starting out
|
|
56
|
-
|
|
57
|
-
**Implementation:**
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
// src/services/llm-cache.ts
|
|
61
|
-
import { LRUCache } from 'lru-cache';
|
|
62
|
-
import { createHash } from 'node:crypto';
|
|
63
|
-
import safeStringify from 'safe-stable-stringify';
|
|
64
|
-
|
|
65
|
-
export class LLMCacheService {
|
|
66
|
-
private static instance: LLMCacheService;
|
|
67
|
-
private cache: LRUCache<string, any>;
|
|
68
|
-
|
|
69
|
-
private constructor() {
|
|
70
|
-
this.cache = new LRUCache({
|
|
71
|
-
max: 5000,
|
|
72
|
-
ttl: 24 * 3600 * 1000,
|
|
73
|
-
maxSize: 100 * 1024 * 1024 // 100 MB
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
static getInstance(): LLMCacheService {
|
|
78
|
-
if (!LLMCacheService.instance) {
|
|
79
|
-
LLMCacheService.instance = new LLMCacheService();
|
|
80
|
-
}
|
|
81
|
-
return LLMCacheService.instance;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async get<T>(key: string, fetcher: () => Promise<T>): Promise<T> {
|
|
85
|
-
return this.cache.fetch(key, fetcher);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private generateKey(input: any): string {
|
|
89
|
-
const normalized = safeStringify(input);
|
|
90
|
-
return createHash('sha256').update(normalized).digest('hex');
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
**Usage in workflow:**
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
// src/workflows/llm-query.workflow.ts
|
|
99
|
-
import { LLMCacheService } from '../services/llm-cache';
|
|
100
|
-
|
|
101
|
-
export class LLMQueryWorkflow {
|
|
102
|
-
private cacheService = LLMCacheService.getInstance();
|
|
103
|
-
|
|
104
|
-
async executeQuery(prompt: string, model: string): Promise<string> {
|
|
105
|
-
const cacheKey = this.generateKey(prompt, model);
|
|
106
|
-
|
|
107
|
-
return this.cacheService.get(
|
|
108
|
-
cacheKey,
|
|
109
|
-
async () => {
|
|
110
|
-
// Only called on cache miss
|
|
111
|
-
return this.callLLM(prompt, model);
|
|
112
|
-
}
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private generateKey(prompt: string, model: string): string {
|
|
117
|
-
return createHash('sha256')
|
|
118
|
-
.update(JSON.stringify({ prompt, model }))
|
|
119
|
-
.digest('hex');
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private async callLLM(prompt: string, model: string): Promise<string> {
|
|
123
|
-
// Your LLM API call
|
|
124
|
-
return 'response...';
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Pros:**
|
|
130
|
-
- Simple, minimal dependencies
|
|
131
|
-
- Easy to test
|
|
132
|
-
- Singleton pattern ensures single cache instance
|
|
133
|
-
|
|
134
|
-
**Cons:**
|
|
135
|
-
- Only works with single process
|
|
136
|
-
- No distributed caching
|
|
137
|
-
- Manual key generation in each workflow
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
### Strategy 2: Service-Based Integration (Recommended for Production)
|
|
142
|
-
|
|
143
|
-
**When:** Complex caching needs, multiple workflows, monitoring required
|
|
144
|
-
|
|
145
|
-
**Implementation:**
|
|
146
|
-
|
|
147
|
-
```typescript
|
|
148
|
-
// src/cache/cache.config.ts
|
|
149
|
-
import { LRUCache } from 'lru-cache';
|
|
150
|
-
|
|
151
|
-
export interface CacheOptions {
|
|
152
|
-
maxItems?: number;
|
|
153
|
-
maxSizeMB?: number;
|
|
154
|
-
ttlHours?: number;
|
|
155
|
-
enableMetrics?: boolean;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export const getCacheConfig = (env: string): CacheOptions => {
|
|
159
|
-
switch (env) {
|
|
160
|
-
case 'development':
|
|
161
|
-
return { maxItems: 100, maxSizeMB: 50, ttlHours: 1 };
|
|
162
|
-
case 'staging':
|
|
163
|
-
return { maxItems: 1000, maxSizeMB: 200, ttlHours: 4 };
|
|
164
|
-
case 'production':
|
|
165
|
-
return { maxItems: 5000, maxSizeMB: 500, ttlHours: 24, enableMetrics: true };
|
|
166
|
-
default:
|
|
167
|
-
return { maxItems: 500, maxSizeMB: 100, ttlHours: 2 };
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// src/cache/cache.service.ts
|
|
172
|
-
import { createHash } from 'node:crypto';
|
|
173
|
-
import safeStringify from 'safe-stable-stringify';
|
|
174
|
-
|
|
175
|
-
export class CacheService {
|
|
176
|
-
private cache: LRUCache<string, any>;
|
|
177
|
-
private metrics = {
|
|
178
|
-
hits: 0,
|
|
179
|
-
misses: 0,
|
|
180
|
-
evictions: 0,
|
|
181
|
-
latencies: [] as number[]
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
constructor(options: CacheOptions) {
|
|
185
|
-
this.cache = new LRUCache({
|
|
186
|
-
max: options.maxItems || 1000,
|
|
187
|
-
maxSize: (options.maxSizeMB || 100) * 1024 * 1024,
|
|
188
|
-
sizeCalculation: (val) => {
|
|
189
|
-
const json = JSON.stringify(val);
|
|
190
|
-
return Buffer.byteLength(json, 'utf8') + 100;
|
|
191
|
-
},
|
|
192
|
-
ttl: (options.ttlHours || 24) * 3600 * 1000,
|
|
193
|
-
updateAgeOnGet: true,
|
|
194
|
-
|
|
195
|
-
dispose: (value, key, reason) => {
|
|
196
|
-
if (reason === 'evict' && options.enableMetrics) {
|
|
197
|
-
this.metrics.evictions++;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async fetch<T>(
|
|
204
|
-
input: Record<string, any>,
|
|
205
|
-
fetcher: () => Promise<T>
|
|
206
|
-
): Promise<T> {
|
|
207
|
-
const start = performance.now();
|
|
208
|
-
const key = this.generateKey(input);
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
const result = await this.cache.fetch(key, fetcher);
|
|
212
|
-
this.recordHit(performance.now() - start);
|
|
213
|
-
return result;
|
|
214
|
-
} catch (error) {
|
|
215
|
-
this.recordMiss(performance.now() - start);
|
|
216
|
-
throw error;
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
private generateKey(input: Record<string, any>): string {
|
|
221
|
-
const normalized = safeStringify(input);
|
|
222
|
-
const hash = createHash('sha256');
|
|
223
|
-
hash.update(normalized);
|
|
224
|
-
return hash.digest('hex');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
private recordHit(latency: number): void {
|
|
228
|
-
this.metrics.hits++;
|
|
229
|
-
this.recordLatency(latency);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
private recordMiss(latency: number): void {
|
|
233
|
-
this.metrics.misses++;
|
|
234
|
-
this.recordLatency(latency);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
private recordLatency(latency: number): void {
|
|
238
|
-
this.metrics.latencies.push(latency);
|
|
239
|
-
if (this.metrics.latencies.length > 10000) {
|
|
240
|
-
this.metrics.latencies.shift();
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
getMetrics() {
|
|
245
|
-
const total = this.metrics.hits + this.metrics.misses;
|
|
246
|
-
const avgLatency = this.metrics.latencies.length > 0
|
|
247
|
-
? this.metrics.latencies.reduce((a, b) => a + b, 0) / this.metrics.latencies.length
|
|
248
|
-
: 0;
|
|
249
|
-
|
|
250
|
-
return {
|
|
251
|
-
hits: this.metrics.hits,
|
|
252
|
-
misses: this.metrics.misses,
|
|
253
|
-
hitRate: total > 0 ? ((this.metrics.hits / total) * 100).toFixed(2) + '%' : '0%',
|
|
254
|
-
avgLatency: avgLatency.toFixed(3) + ' ms',
|
|
255
|
-
cacheSize: this.cache.size,
|
|
256
|
-
evictions: this.metrics.evictions
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
clear(): void {
|
|
261
|
-
this.cache.clear();
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
**Usage in dependency injection:**
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
// src/index.ts (main entry point)
|
|
270
|
-
import { CacheService } from './cache/cache.service';
|
|
271
|
-
import { getCacheConfig } from './cache/cache.config';
|
|
272
|
-
|
|
273
|
-
// Setup
|
|
274
|
-
const env = process.env.NODE_ENV || 'development';
|
|
275
|
-
const cacheConfig = getCacheConfig(env);
|
|
276
|
-
const cacheService = new CacheService(cacheConfig);
|
|
277
|
-
|
|
278
|
-
// Export for dependency injection
|
|
279
|
-
export { cacheService };
|
|
280
|
-
|
|
281
|
-
// src/workflows/llm-query.workflow.ts
|
|
282
|
-
import { cacheService } from '../index';
|
|
283
|
-
|
|
284
|
-
export class LLMQueryWorkflow {
|
|
285
|
-
constructor(private cache = cacheService) {}
|
|
286
|
-
|
|
287
|
-
async query(input: any): Promise<string> {
|
|
288
|
-
return this.cache.fetch(
|
|
289
|
-
input,
|
|
290
|
-
async () => this.callLLMAPI(input)
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
private async callLLMAPI(input: any): Promise<string> {
|
|
295
|
-
// Implementation
|
|
296
|
-
return 'response...';
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
**Pros:**
|
|
302
|
-
- Centralized cache configuration
|
|
303
|
-
- Easy to swap implementations (Redis, etc.)
|
|
304
|
-
- Metrics built-in
|
|
305
|
-
- Testable (can inject mock)
|
|
306
|
-
|
|
307
|
-
**Cons:**
|
|
308
|
-
- More boilerplate
|
|
309
|
-
- Slightly more complex setup
|
|
310
|
-
|
|
311
|
-
---
|
|
312
|
-
|
|
313
|
-
### Strategy 3: Multi-Layer Caching (For High Performance)
|
|
314
|
-
|
|
315
|
-
**When:** Multi-node deployment, critical performance requirements
|
|
316
|
-
|
|
317
|
-
**Implementation:**
|
|
318
|
-
|
|
319
|
-
```typescript
|
|
320
|
-
// src/cache/multi-layer.cache.ts
|
|
321
|
-
import { LRUCache } from 'lru-cache';
|
|
322
|
-
import { createClient, RedisClientType } from 'redis';
|
|
323
|
-
|
|
324
|
-
export class MultiLayerCache {
|
|
325
|
-
private l1: LRUCache<string, any>; // In-process
|
|
326
|
-
private l2: RedisClientType | null = null; // Redis
|
|
327
|
-
|
|
328
|
-
constructor(
|
|
329
|
-
l1Config: any,
|
|
330
|
-
redisUrl?: string
|
|
331
|
-
) {
|
|
332
|
-
this.l1 = new LRUCache(l1Config);
|
|
333
|
-
|
|
334
|
-
// Optional Redis
|
|
335
|
-
if (redisUrl) {
|
|
336
|
-
this.initRedis(redisUrl);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
private async initRedis(url: string): Promise<void> {
|
|
341
|
-
this.l2 = createClient({ url });
|
|
342
|
-
await this.l2.connect();
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
async fetch<T>(
|
|
346
|
-
key: string,
|
|
347
|
-
fetcher: () => Promise<T>,
|
|
348
|
-
options: { ttl?: number } = {}
|
|
349
|
-
): Promise<T> {
|
|
350
|
-
// L1: In-process (nanoseconds)
|
|
351
|
-
const l1Hit = this.l1.get(key);
|
|
352
|
-
if (l1Hit !== undefined) {
|
|
353
|
-
return l1Hit;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// L2: Redis (milliseconds)
|
|
357
|
-
if (this.l2) {
|
|
358
|
-
try {
|
|
359
|
-
const l2Data = await this.l2.get(key);
|
|
360
|
-
if (l2Data) {
|
|
361
|
-
const value = JSON.parse(l2Data);
|
|
362
|
-
this.l1.set(key, value); // Promote to L1
|
|
363
|
-
return value;
|
|
364
|
-
}
|
|
365
|
-
} catch (error) {
|
|
366
|
-
console.error('L2 cache error:', error);
|
|
367
|
-
// Fall through to fetcher
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// Cache miss - fetch and store
|
|
372
|
-
const value = await fetcher();
|
|
373
|
-
|
|
374
|
-
this.l1.set(key, value);
|
|
375
|
-
if (this.l2) {
|
|
376
|
-
try {
|
|
377
|
-
const ttl = options.ttl || 24 * 3600;
|
|
378
|
-
await this.l2.setEx(
|
|
379
|
-
key,
|
|
380
|
-
Math.floor(ttl / 1000),
|
|
381
|
-
JSON.stringify(value)
|
|
382
|
-
);
|
|
383
|
-
} catch (error) {
|
|
384
|
-
console.error('Failed to store in L2:', error);
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
return value;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
async disconnect(): Promise<void> {
|
|
392
|
-
if (this.l2) {
|
|
393
|
-
await this.l2.disconnect();
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
**Usage:**
|
|
400
|
-
|
|
401
|
-
```typescript
|
|
402
|
-
// src/index.ts
|
|
403
|
-
const cache = new MultiLayerCache(
|
|
404
|
-
{
|
|
405
|
-
max: 1000,
|
|
406
|
-
maxSize: 100 * 1024 * 1024
|
|
407
|
-
},
|
|
408
|
-
process.env.REDIS_URL // Optional
|
|
409
|
-
);
|
|
410
|
-
|
|
411
|
-
export { cache };
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
**Pros:**
|
|
415
|
-
- Fast L1 lookups
|
|
416
|
-
- Distributed caching with L2
|
|
417
|
-
- Transparent failover
|
|
418
|
-
|
|
419
|
-
**Cons:**
|
|
420
|
-
- Redis dependency
|
|
421
|
-
- Additional latency on L1 miss
|
|
422
|
-
- Network overhead for L2
|
|
423
|
-
|
|
424
|
-
---
|
|
425
|
-
|
|
426
|
-
## Framework-Specific Integration
|
|
427
|
-
|
|
428
|
-
### Integration with Groundswell Workflow Engine
|
|
429
|
-
|
|
430
|
-
```typescript
|
|
431
|
-
// src/plugins/cache.plugin.ts
|
|
432
|
-
import { WorkflowPlugin } from '@groundswell/core';
|
|
433
|
-
import { CacheService } from '../cache/cache.service';
|
|
434
|
-
|
|
435
|
-
export class CachePlugin implements WorkflowPlugin {
|
|
436
|
-
private cache: CacheService;
|
|
437
|
-
|
|
438
|
-
constructor(cacheService: CacheService) {
|
|
439
|
-
this.cache = cacheService;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
async onTaskStart(context: any): Promise<void> {
|
|
443
|
-
context.cache = this.cache;
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
async onTaskComplete(context: any): Promise<void> {
|
|
447
|
-
// Optional: log metrics
|
|
448
|
-
if (context.taskName === 'llm-query') {
|
|
449
|
-
console.log('[LLM Cache]', this.cache.getMetrics());
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
// src/index.ts
|
|
455
|
-
import { createWorkflow } from '@groundswell/core';
|
|
456
|
-
import { CachePlugin } from './plugins/cache.plugin';
|
|
457
|
-
|
|
458
|
-
const workflow = createWorkflow()
|
|
459
|
-
.use(new CachePlugin(cacheService))
|
|
460
|
-
.define(/* ... */);
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### Decorator-Based Integration
|
|
464
|
-
|
|
465
|
-
```typescript
|
|
466
|
-
// src/decorators/cacheable.ts
|
|
467
|
-
import { CacheService } from '../cache/cache.service';
|
|
468
|
-
|
|
469
|
-
export function Cacheable(options: { ttlHours?: number } = {}) {
|
|
470
|
-
return function (
|
|
471
|
-
target: any,
|
|
472
|
-
propertyKey: string,
|
|
473
|
-
descriptor: PropertyDescriptor
|
|
474
|
-
) {
|
|
475
|
-
const originalMethod = descriptor.value;
|
|
476
|
-
|
|
477
|
-
descriptor.value = async function (...args: any[]) {
|
|
478
|
-
const cache = (this as any).cache || CacheService.getInstance();
|
|
479
|
-
|
|
480
|
-
const cacheKey = {
|
|
481
|
-
method: propertyKey,
|
|
482
|
-
args: args
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
return cache.fetch(
|
|
486
|
-
cacheKey,
|
|
487
|
-
() => originalMethod.apply(this, args)
|
|
488
|
-
);
|
|
489
|
-
};
|
|
490
|
-
|
|
491
|
-
return descriptor;
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
// Usage
|
|
496
|
-
class LLMService {
|
|
497
|
-
@Cacheable({ ttlHours: 24 })
|
|
498
|
-
async query(prompt: string): Promise<string> {
|
|
499
|
-
// Implementation
|
|
500
|
-
return 'response...';
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
```
|
|
504
|
-
|
|
505
|
-
### OpenAI Integration Example
|
|
506
|
-
|
|
507
|
-
```typescript
|
|
508
|
-
// src/services/openai-cached.service.ts
|
|
509
|
-
import { OpenAI } from 'openai';
|
|
510
|
-
import { CacheService } from '../cache/cache.service';
|
|
511
|
-
|
|
512
|
-
export class CachedOpenAIService {
|
|
513
|
-
private openai = new OpenAI();
|
|
514
|
-
private cache: CacheService;
|
|
515
|
-
|
|
516
|
-
constructor(cacheService: CacheService) {
|
|
517
|
-
this.cache = cacheService;
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
async chat(params: OpenAI.Chat.ChatCompletionCreateParams): Promise<string> {
|
|
521
|
-
return this.cache.fetch(
|
|
522
|
-
{
|
|
523
|
-
model: params.model,
|
|
524
|
-
messages: params.messages,
|
|
525
|
-
temperature: params.temperature
|
|
526
|
-
},
|
|
527
|
-
async () => {
|
|
528
|
-
const response = await this.openai.chat.completions.create(params);
|
|
529
|
-
return response.choices[0]?.message.content || '';
|
|
530
|
-
}
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
async embed(input: string | string[]): Promise<number[][]> {
|
|
535
|
-
return this.cache.fetch(
|
|
536
|
-
{ input },
|
|
537
|
-
async () => {
|
|
538
|
-
const response = await this.openai.embeddings.create({
|
|
539
|
-
model: 'text-embedding-3-small',
|
|
540
|
-
input
|
|
541
|
-
});
|
|
542
|
-
return response.data.map(d => d.embedding);
|
|
543
|
-
}
|
|
544
|
-
);
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
---
|
|
550
|
-
|
|
551
|
-
## Migration Path
|
|
552
|
-
|
|
553
|
-
### Phase 1: Evaluation (Week 1)
|
|
554
|
-
|
|
555
|
-
```typescript
|
|
556
|
-
// Minimal cache in test environment
|
|
557
|
-
const testCache = new LRUCache({
|
|
558
|
-
max: 100,
|
|
559
|
-
ttl: 600000 // 10 minutes
|
|
560
|
-
});
|
|
561
|
-
|
|
562
|
-
// Measure baseline metrics
|
|
563
|
-
// - API call latency
|
|
564
|
-
// - Query patterns
|
|
565
|
-
// - Cache hit rates
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
### Phase 2: Pilot (Week 2-3)
|
|
569
|
-
|
|
570
|
-
```typescript
|
|
571
|
-
// Single workflow with caching enabled
|
|
572
|
-
// Monitor:
|
|
573
|
-
// - Hit rate (target: 30%+)
|
|
574
|
-
// - Memory usage
|
|
575
|
-
// - Performance improvement
|
|
576
|
-
```
|
|
577
|
-
|
|
578
|
-
### Phase 3: Rollout (Week 4-8)
|
|
579
|
-
|
|
580
|
-
```typescript
|
|
581
|
-
// Progressive rollout to all LLM workflows
|
|
582
|
-
// Week 4: Critical paths only
|
|
583
|
-
// Week 5: 50% of workflows
|
|
584
|
-
// Week 6-8: 100% with monitoring
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### Phase 4: Optimization (Week 8+)
|
|
588
|
-
|
|
589
|
-
```typescript
|
|
590
|
-
// Add semantic caching
|
|
591
|
-
// Tune configuration
|
|
592
|
-
// Add distributed caching if needed
|
|
593
|
-
```
|
|
594
|
-
|
|
595
|
-
---
|
|
596
|
-
|
|
597
|
-
## Troubleshooting
|
|
598
|
-
|
|
599
|
-
### Issue 1: Low Cache Hit Rate (< 20%)
|
|
600
|
-
|
|
601
|
-
**Diagnosis:**
|
|
602
|
-
|
|
603
|
-
```typescript
|
|
604
|
-
// Check if keys are deterministic
|
|
605
|
-
const key1 = objectKeyHash({ a: 1, b: 2 });
|
|
606
|
-
const key2 = objectKeyHash({ b: 2, a: 1 });
|
|
607
|
-
console.log(key1 === key2); // Should be true
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
**Solutions:**
|
|
611
|
-
1. Verify using `safe-stable-stringify` (not `JSON.stringify`)
|
|
612
|
-
2. Check if prompts vary slightly (space differences, case sensitivity)
|
|
613
|
-
3. Consider semantic caching for variations
|
|
614
|
-
4. Normalize prompts before caching
|
|
615
|
-
|
|
616
|
-
### Issue 2: High Memory Usage
|
|
617
|
-
|
|
618
|
-
**Diagnosis:**
|
|
619
|
-
|
|
620
|
-
```typescript
|
|
621
|
-
// Check actual cache memory consumption
|
|
622
|
-
const metrics = cache.getMetrics();
|
|
623
|
-
console.log(`Size: ${metrics.cacheSize} items`);
|
|
624
|
-
console.log(`Memory: ${metrics.estimatedMemory} MB`);
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
**Solutions:**
|
|
628
|
-
1. Reduce `maxSize` limit
|
|
629
|
-
2. Reduce `ttl` for faster expiration
|
|
630
|
-
3. Implement `sizeCalculation` correctly
|
|
631
|
-
4. Add memory monitoring: `process.memoryUsage()`
|
|
632
|
-
|
|
633
|
-
### Issue 3: Stale Data
|
|
634
|
-
|
|
635
|
-
**Diagnosis:**
|
|
636
|
-
|
|
637
|
-
```typescript
|
|
638
|
-
// TTL items aren't deleted until accessed
|
|
639
|
-
// This is expected behavior
|
|
640
|
-
const cached = cache.get(key); // Triggers TTL check
|
|
641
|
-
```
|
|
642
|
-
|
|
643
|
-
**Solutions:**
|
|
644
|
-
1. Use shorter TTL (24 hours instead of 30)
|
|
645
|
-
2. Implement active cache purging
|
|
646
|
-
3. Use external validation (check API for updates)
|
|
647
|
-
4. Version cache keys
|
|
648
|
-
|
|
649
|
-
### Issue 4: Cache Not Working in Tests
|
|
650
|
-
|
|
651
|
-
**Solution:**
|
|
652
|
-
|
|
653
|
-
```typescript
|
|
654
|
-
// Mock or provide clean cache instance for each test
|
|
655
|
-
beforeEach(() => {
|
|
656
|
-
cache = new LRUCache({ max: 100 });
|
|
657
|
-
});
|
|
658
|
-
|
|
659
|
-
afterEach(() => {
|
|
660
|
-
cache.clear();
|
|
661
|
-
});
|
|
662
|
-
```
|
|
663
|
-
|
|
664
|
-
### Issue 5: Race Conditions
|
|
665
|
-
|
|
666
|
-
**Diagnosis:**
|
|
667
|
-
|
|
668
|
-
```typescript
|
|
669
|
-
// ❌ Wrong: Manual lookup allows duplicates
|
|
670
|
-
if (!cache.has(key)) {
|
|
671
|
-
const value = await expensiveOp();
|
|
672
|
-
cache.set(key, value);
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
// ✅ Correct: fetch() deduplicates
|
|
676
|
-
const value = await cache.fetch(key, expensiveOp);
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
**Solution:**
|
|
680
|
-
Always use `fetch()` method instead of manual lookup + set.
|
|
681
|
-
|
|
682
|
-
### Issue 6: Keys Too Long
|
|
683
|
-
|
|
684
|
-
**Problem:** 64-char SHA-256 keys add overhead
|
|
685
|
-
|
|
686
|
-
**Solution:**
|
|
687
|
-
|
|
688
|
-
```typescript
|
|
689
|
-
// Use shorter hash (8 chars) for readability
|
|
690
|
-
const key = hash.digest('hex').substring(0, 8);
|
|
691
|
-
|
|
692
|
-
// Or use composite key with prefix
|
|
693
|
-
const key = `gpt4:${hash.digest('hex').substring(0, 8)}`;
|
|
694
|
-
```
|
|
695
|
-
|
|
696
|
-
---
|
|
697
|
-
|
|
698
|
-
## Performance Tuning Checklist
|
|
699
|
-
|
|
700
|
-
- [ ] Using `safe-stable-stringify` (not `JSON.stringify`)
|
|
701
|
-
- [ ] Using `fetch()` method (not manual lookup)
|
|
702
|
-
- [ ] `max` or `maxSize` configured
|
|
703
|
-
- [ ] Appropriate `ttl` set (24 hours for LLM responses)
|
|
704
|
-
- [ ] `sizeCalculation` implemented correctly
|
|
705
|
-
- [ ] Metrics collection enabled
|
|
706
|
-
- [ ] Hit rate > 30% (exact) or > 60% (semantic)
|
|
707
|
-
- [ ] Memory usage < budget
|
|
708
|
-
- [ ] Monitoring/alerting configured
|
|
709
|
-
- [ ] Cache warming for common queries
|
|
710
|
-
|
|
711
|
-
---
|
|
712
|
-
|
|
713
|
-
## Decision Flowchart
|
|
714
|
-
|
|
715
|
-
```
|
|
716
|
-
Start: Need to cache LLM responses?
|
|
717
|
-
│
|
|
718
|
-
├─ Single node, simple? → Strategy 1 (Minimal)
|
|
719
|
-
│
|
|
720
|
-
├─ Multiple nodes?
|
|
721
|
-
│ ├─ Yes → Strategy 3 (Multi-layer)
|
|
722
|
-
│ └─ No → Strategy 2 (Service-based)
|
|
723
|
-
│
|
|
724
|
-
├─ Hit rate < 30%?
|
|
725
|
-
│ ├─ Yes, add Semantic Caching
|
|
726
|
-
│ └─ No, optimize existing
|
|
727
|
-
│
|
|
728
|
-
├─ Memory limited?
|
|
729
|
-
│ ├─ Yes → Use maxSize, reduce maxItems
|
|
730
|
-
│ └─ No → Configure generously
|
|
731
|
-
│
|
|
732
|
-
└─ Ready for production? → Add monitoring, metrics, alerts
|
|
733
|
-
```
|
|
734
|
-
|
|
735
|
-
---
|
|
736
|
-
|
|
737
|
-
**Document Version:** 1.0
|
|
738
|
-
**Last Updated:** 2025-12-08
|