tapps-agents 3.6.0__py3-none-any.whl → 3.6.1__py3-none-any.whl
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.
- tapps_agents/__init__.py +2 -2
- tapps_agents/agents/__init__.py +22 -22
- tapps_agents/agents/analyst/__init__.py +5 -5
- tapps_agents/agents/architect/__init__.py +5 -5
- tapps_agents/agents/architect/agent.py +1033 -1033
- tapps_agents/agents/architect/pattern_detector.py +75 -75
- tapps_agents/agents/cleanup/__init__.py +7 -7
- tapps_agents/agents/cleanup/agent.py +445 -445
- tapps_agents/agents/debugger/__init__.py +7 -7
- tapps_agents/agents/debugger/agent.py +310 -310
- tapps_agents/agents/debugger/error_analyzer.py +437 -437
- tapps_agents/agents/designer/__init__.py +5 -5
- tapps_agents/agents/designer/agent.py +786 -786
- tapps_agents/agents/designer/visual_designer.py +638 -638
- tapps_agents/agents/documenter/__init__.py +7 -7
- tapps_agents/agents/documenter/agent.py +531 -531
- tapps_agents/agents/documenter/doc_generator.py +472 -472
- tapps_agents/agents/documenter/doc_validator.py +393 -393
- tapps_agents/agents/documenter/framework_doc_updater.py +493 -493
- tapps_agents/agents/enhancer/__init__.py +7 -7
- tapps_agents/agents/evaluator/__init__.py +7 -7
- tapps_agents/agents/evaluator/agent.py +443 -443
- tapps_agents/agents/evaluator/priority_evaluator.py +641 -641
- tapps_agents/agents/evaluator/quality_analyzer.py +147 -147
- tapps_agents/agents/evaluator/report_generator.py +344 -344
- tapps_agents/agents/evaluator/usage_analyzer.py +192 -192
- tapps_agents/agents/evaluator/workflow_analyzer.py +189 -189
- tapps_agents/agents/implementer/__init__.py +7 -7
- tapps_agents/agents/implementer/agent.py +798 -798
- tapps_agents/agents/implementer/auto_fix.py +1119 -1119
- tapps_agents/agents/implementer/code_generator.py +73 -73
- tapps_agents/agents/improver/__init__.py +1 -1
- tapps_agents/agents/improver/agent.py +753 -753
- tapps_agents/agents/ops/__init__.py +1 -1
- tapps_agents/agents/ops/agent.py +619 -619
- tapps_agents/agents/ops/dependency_analyzer.py +600 -600
- tapps_agents/agents/orchestrator/__init__.py +5 -5
- tapps_agents/agents/orchestrator/agent.py +522 -522
- tapps_agents/agents/planner/__init__.py +7 -7
- tapps_agents/agents/planner/agent.py +1127 -1127
- tapps_agents/agents/reviewer/__init__.py +24 -24
- tapps_agents/agents/reviewer/agent.py +3513 -3513
- tapps_agents/agents/reviewer/aggregator.py +213 -213
- tapps_agents/agents/reviewer/batch_review.py +448 -448
- tapps_agents/agents/reviewer/cache.py +443 -443
- tapps_agents/agents/reviewer/context7_enhancer.py +630 -630
- tapps_agents/agents/reviewer/context_detector.py +203 -203
- tapps_agents/agents/reviewer/docker_compose_validator.py +158 -158
- tapps_agents/agents/reviewer/dockerfile_validator.py +176 -176
- tapps_agents/agents/reviewer/error_handling.py +126 -126
- tapps_agents/agents/reviewer/feedback_generator.py +490 -490
- tapps_agents/agents/reviewer/influxdb_validator.py +316 -316
- tapps_agents/agents/reviewer/issue_tracking.py +169 -169
- tapps_agents/agents/reviewer/library_detector.py +295 -295
- tapps_agents/agents/reviewer/library_patterns.py +268 -268
- tapps_agents/agents/reviewer/maintainability_scorer.py +593 -593
- tapps_agents/agents/reviewer/metric_strategies.py +276 -276
- tapps_agents/agents/reviewer/mqtt_validator.py +160 -160
- tapps_agents/agents/reviewer/output_enhancer.py +105 -105
- tapps_agents/agents/reviewer/pattern_detector.py +241 -241
- tapps_agents/agents/reviewer/performance_scorer.py +357 -357
- tapps_agents/agents/reviewer/phased_review.py +516 -516
- tapps_agents/agents/reviewer/progressive_review.py +435 -435
- tapps_agents/agents/reviewer/react_scorer.py +331 -331
- tapps_agents/agents/reviewer/score_constants.py +228 -228
- tapps_agents/agents/reviewer/score_validator.py +507 -507
- tapps_agents/agents/reviewer/scorer_registry.py +373 -373
- tapps_agents/agents/reviewer/service_discovery.py +534 -534
- tapps_agents/agents/reviewer/tools/parallel_executor.py +581 -581
- tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -250
- tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -284
- tapps_agents/agents/reviewer/typescript_scorer.py +1142 -1142
- tapps_agents/agents/reviewer/validation.py +208 -208
- tapps_agents/agents/reviewer/websocket_validator.py +132 -132
- tapps_agents/agents/tester/__init__.py +7 -7
- tapps_agents/agents/tester/accessibility_auditor.py +309 -309
- tapps_agents/agents/tester/agent.py +1080 -1080
- tapps_agents/agents/tester/batch_generator.py +54 -54
- tapps_agents/agents/tester/context_learner.py +51 -51
- tapps_agents/agents/tester/coverage_analyzer.py +386 -386
- tapps_agents/agents/tester/coverage_test_generator.py +290 -290
- tapps_agents/agents/tester/debug_enhancer.py +238 -238
- tapps_agents/agents/tester/device_emulator.py +241 -241
- tapps_agents/agents/tester/integration_generator.py +62 -62
- tapps_agents/agents/tester/network_recorder.py +300 -300
- tapps_agents/agents/tester/performance_monitor.py +320 -320
- tapps_agents/agents/tester/test_fixer.py +316 -316
- tapps_agents/agents/tester/test_generator.py +632 -632
- tapps_agents/agents/tester/trace_manager.py +234 -234
- tapps_agents/agents/tester/visual_regression.py +291 -291
- tapps_agents/analysis/pattern_detector.py +36 -36
- tapps_agents/beads/hydration.py +213 -213
- tapps_agents/beads/parse.py +32 -32
- tapps_agents/beads/specs.py +206 -206
- tapps_agents/cli/__init__.py +9 -9
- tapps_agents/cli/__main__.py +8 -8
- tapps_agents/cli/base.py +478 -478
- tapps_agents/cli/command_classifier.py +72 -72
- tapps_agents/cli/commands/__init__.py +2 -2
- tapps_agents/cli/commands/analyst.py +173 -173
- tapps_agents/cli/commands/architect.py +109 -109
- tapps_agents/cli/commands/cleanup_agent.py +92 -92
- tapps_agents/cli/commands/common.py +126 -126
- tapps_agents/cli/commands/debugger.py +90 -90
- tapps_agents/cli/commands/designer.py +112 -112
- tapps_agents/cli/commands/documenter.py +136 -136
- tapps_agents/cli/commands/enhancer.py +110 -110
- tapps_agents/cli/commands/evaluator.py +255 -255
- tapps_agents/cli/commands/implementer.py +301 -301
- tapps_agents/cli/commands/improver.py +91 -91
- tapps_agents/cli/commands/knowledge.py +111 -111
- tapps_agents/cli/commands/learning.py +172 -172
- tapps_agents/cli/commands/observability.py +283 -283
- tapps_agents/cli/commands/ops.py +135 -135
- tapps_agents/cli/commands/orchestrator.py +116 -116
- tapps_agents/cli/commands/planner.py +237 -237
- tapps_agents/cli/commands/reviewer.py +1872 -1872
- tapps_agents/cli/commands/status.py +285 -285
- tapps_agents/cli/commands/task.py +227 -227
- tapps_agents/cli/commands/tester.py +191 -191
- tapps_agents/cli/feedback.py +936 -936
- tapps_agents/cli/formatters.py +608 -608
- tapps_agents/cli/help/__init__.py +7 -7
- tapps_agents/cli/help/static_help.py +425 -425
- tapps_agents/cli/network_detection.py +110 -110
- tapps_agents/cli/output_compactor.py +274 -274
- tapps_agents/cli/parsers/__init__.py +2 -2
- tapps_agents/cli/parsers/analyst.py +186 -186
- tapps_agents/cli/parsers/architect.py +167 -167
- tapps_agents/cli/parsers/cleanup_agent.py +228 -228
- tapps_agents/cli/parsers/debugger.py +116 -116
- tapps_agents/cli/parsers/designer.py +182 -182
- tapps_agents/cli/parsers/documenter.py +134 -134
- tapps_agents/cli/parsers/enhancer.py +113 -113
- tapps_agents/cli/parsers/evaluator.py +213 -213
- tapps_agents/cli/parsers/implementer.py +168 -168
- tapps_agents/cli/parsers/improver.py +132 -132
- tapps_agents/cli/parsers/ops.py +159 -159
- tapps_agents/cli/parsers/orchestrator.py +98 -98
- tapps_agents/cli/parsers/planner.py +145 -145
- tapps_agents/cli/parsers/reviewer.py +462 -462
- tapps_agents/cli/parsers/tester.py +124 -124
- tapps_agents/cli/progress_heartbeat.py +254 -254
- tapps_agents/cli/streaming_progress.py +336 -336
- tapps_agents/cli/utils/__init__.py +6 -6
- tapps_agents/cli/utils/agent_lifecycle.py +48 -48
- tapps_agents/cli/utils/error_formatter.py +82 -82
- tapps_agents/cli/utils/error_recovery.py +188 -188
- tapps_agents/cli/utils/output_handler.py +59 -59
- tapps_agents/cli/utils/prompt_enhancer.py +319 -319
- tapps_agents/cli/validators/__init__.py +9 -9
- tapps_agents/cli/validators/command_validator.py +81 -81
- tapps_agents/context7/__init__.py +112 -112
- tapps_agents/context7/agent_integration.py +869 -869
- tapps_agents/context7/analytics.py +382 -382
- tapps_agents/context7/analytics_dashboard.py +299 -299
- tapps_agents/context7/async_cache.py +681 -681
- tapps_agents/context7/backup_client.py +958 -958
- tapps_agents/context7/cache_locking.py +194 -194
- tapps_agents/context7/cache_metadata.py +214 -214
- tapps_agents/context7/cache_prewarm.py +488 -488
- tapps_agents/context7/cache_structure.py +168 -168
- tapps_agents/context7/cache_warming.py +604 -604
- tapps_agents/context7/circuit_breaker.py +376 -376
- tapps_agents/context7/cleanup.py +461 -461
- tapps_agents/context7/commands.py +858 -858
- tapps_agents/context7/credential_validation.py +276 -276
- tapps_agents/context7/cross_reference_resolver.py +168 -168
- tapps_agents/context7/cross_references.py +424 -424
- tapps_agents/context7/doc_manager.py +225 -225
- tapps_agents/context7/fuzzy_matcher.py +369 -369
- tapps_agents/context7/kb_cache.py +404 -404
- tapps_agents/context7/language_detector.py +219 -219
- tapps_agents/context7/library_detector.py +725 -725
- tapps_agents/context7/lookup.py +738 -738
- tapps_agents/context7/metadata.py +258 -258
- tapps_agents/context7/refresh_queue.py +300 -300
- tapps_agents/context7/security.py +373 -373
- tapps_agents/context7/staleness_policies.py +278 -278
- tapps_agents/context7/tiles_integration.py +47 -47
- tapps_agents/continuous_bug_fix/__init__.py +20 -20
- tapps_agents/continuous_bug_fix/bug_finder.py +306 -306
- tapps_agents/continuous_bug_fix/bug_fix_coordinator.py +177 -177
- tapps_agents/continuous_bug_fix/commit_manager.py +178 -178
- tapps_agents/continuous_bug_fix/continuous_bug_fixer.py +322 -322
- tapps_agents/continuous_bug_fix/proactive_bug_finder.py +285 -285
- tapps_agents/core/__init__.py +298 -298
- tapps_agents/core/adaptive_cache_config.py +432 -432
- tapps_agents/core/agent_base.py +647 -647
- tapps_agents/core/agent_cache.py +466 -466
- tapps_agents/core/agent_learning.py +1865 -1865
- tapps_agents/core/analytics_dashboard.py +563 -563
- tapps_agents/core/analytics_enhancements.py +597 -597
- tapps_agents/core/anonymization.py +274 -274
- tapps_agents/core/ast_parser.py +228 -228
- tapps_agents/core/async_file_ops.py +402 -402
- tapps_agents/core/best_practice_consultant.py +299 -299
- tapps_agents/core/brownfield_analyzer.py +299 -299
- tapps_agents/core/brownfield_review.py +541 -541
- tapps_agents/core/browser_controller.py +513 -513
- tapps_agents/core/capability_registry.py +418 -418
- tapps_agents/core/change_impact_analyzer.py +190 -190
- tapps_agents/core/checkpoint_manager.py +377 -377
- tapps_agents/core/code_generator.py +329 -329
- tapps_agents/core/code_validator.py +276 -276
- tapps_agents/core/command_registry.py +327 -327
- tapps_agents/core/context_gathering/__init__.py +2 -2
- tapps_agents/core/context_gathering/repository_explorer.py +28 -28
- tapps_agents/core/context_intelligence/__init__.py +2 -2
- tapps_agents/core/context_intelligence/relevance_scorer.py +24 -24
- tapps_agents/core/context_intelligence/token_budget_manager.py +27 -27
- tapps_agents/core/context_manager.py +240 -240
- tapps_agents/core/cursor_feedback_monitor.py +146 -146
- tapps_agents/core/cursor_verification.py +290 -290
- tapps_agents/core/customization_loader.py +280 -280
- tapps_agents/core/customization_schema.py +260 -260
- tapps_agents/core/customization_template.py +238 -238
- tapps_agents/core/debug_logger.py +124 -124
- tapps_agents/core/design_validator.py +298 -298
- tapps_agents/core/diagram_generator.py +226 -226
- tapps_agents/core/docker_utils.py +232 -232
- tapps_agents/core/document_generator.py +617 -617
- tapps_agents/core/domain_detector.py +30 -30
- tapps_agents/core/error_envelope.py +454 -454
- tapps_agents/core/error_handler.py +270 -270
- tapps_agents/core/estimation_tracker.py +189 -189
- tapps_agents/core/eval_prompt_engine.py +116 -116
- tapps_agents/core/evaluation_base.py +119 -119
- tapps_agents/core/evaluation_models.py +320 -320
- tapps_agents/core/evaluation_orchestrator.py +225 -225
- tapps_agents/core/evaluators/__init__.py +7 -7
- tapps_agents/core/evaluators/architectural_evaluator.py +205 -205
- tapps_agents/core/evaluators/behavioral_evaluator.py +160 -160
- tapps_agents/core/evaluators/performance_profile_evaluator.py +160 -160
- tapps_agents/core/evaluators/security_posture_evaluator.py +148 -148
- tapps_agents/core/evaluators/spec_compliance_evaluator.py +181 -181
- tapps_agents/core/exceptions.py +107 -107
- tapps_agents/core/expert_config_generator.py +293 -293
- tapps_agents/core/export_schema.py +202 -202
- tapps_agents/core/external_feedback_models.py +102 -102
- tapps_agents/core/external_feedback_storage.py +213 -213
- tapps_agents/core/fallback_strategy.py +314 -314
- tapps_agents/core/feedback_analyzer.py +162 -162
- tapps_agents/core/feedback_collector.py +178 -178
- tapps_agents/core/git_operations.py +445 -445
- tapps_agents/core/hardware_profiler.py +151 -151
- tapps_agents/core/instructions.py +324 -324
- tapps_agents/core/io_guardrails.py +69 -69
- tapps_agents/core/issue_manifest.py +249 -249
- tapps_agents/core/issue_schema.py +139 -139
- tapps_agents/core/json_utils.py +128 -128
- tapps_agents/core/knowledge_graph.py +446 -446
- tapps_agents/core/language_detector.py +296 -296
- tapps_agents/core/learning_confidence.py +242 -242
- tapps_agents/core/learning_dashboard.py +246 -246
- tapps_agents/core/learning_decision.py +384 -384
- tapps_agents/core/learning_explainability.py +578 -578
- tapps_agents/core/learning_export.py +287 -287
- tapps_agents/core/learning_integration.py +228 -228
- tapps_agents/core/llm_behavior.py +232 -232
- tapps_agents/core/long_duration_support.py +786 -786
- tapps_agents/core/mcp_setup.py +106 -106
- tapps_agents/core/memory_integration.py +396 -396
- tapps_agents/core/meta_learning.py +666 -666
- tapps_agents/core/module_path_sanitizer.py +199 -199
- tapps_agents/core/multi_agent_orchestrator.py +382 -382
- tapps_agents/core/network_errors.py +125 -125
- tapps_agents/core/nfr_validator.py +336 -336
- tapps_agents/core/offline_mode.py +158 -158
- tapps_agents/core/output_contracts.py +300 -300
- tapps_agents/core/output_formatter.py +300 -300
- tapps_agents/core/path_normalizer.py +174 -174
- tapps_agents/core/path_validator.py +322 -322
- tapps_agents/core/pattern_library.py +250 -250
- tapps_agents/core/performance_benchmark.py +301 -301
- tapps_agents/core/performance_monitor.py +184 -184
- tapps_agents/core/playwright_mcp_controller.py +771 -771
- tapps_agents/core/policy_loader.py +135 -135
- tapps_agents/core/progress.py +166 -166
- tapps_agents/core/project_profile.py +354 -354
- tapps_agents/core/project_type_detector.py +454 -454
- tapps_agents/core/prompt_base.py +223 -223
- tapps_agents/core/prompt_learning/__init__.py +2 -2
- tapps_agents/core/prompt_learning/learning_loop.py +24 -24
- tapps_agents/core/prompt_learning/project_prompt_store.py +25 -25
- tapps_agents/core/prompt_learning/skills_prompt_analyzer.py +35 -35
- tapps_agents/core/prompt_optimization/__init__.py +6 -6
- tapps_agents/core/prompt_optimization/ab_tester.py +114 -114
- tapps_agents/core/prompt_optimization/correlation_analyzer.py +160 -160
- tapps_agents/core/prompt_optimization/progressive_refiner.py +129 -129
- tapps_agents/core/prompt_optimization/prompt_library.py +37 -37
- tapps_agents/core/requirements_evaluator.py +431 -431
- tapps_agents/core/resource_aware_executor.py +449 -449
- tapps_agents/core/resource_monitor.py +343 -343
- tapps_agents/core/resume_handler.py +298 -298
- tapps_agents/core/retry_handler.py +197 -197
- tapps_agents/core/review_checklists.py +479 -479
- tapps_agents/core/role_loader.py +201 -201
- tapps_agents/core/role_template_loader.py +201 -201
- tapps_agents/core/runtime_mode.py +60 -60
- tapps_agents/core/security_scanner.py +342 -342
- tapps_agents/core/skill_agent_registry.py +194 -194
- tapps_agents/core/skill_integration.py +208 -208
- tapps_agents/core/skill_loader.py +492 -492
- tapps_agents/core/skill_template.py +341 -341
- tapps_agents/core/skill_validator.py +478 -478
- tapps_agents/core/stack_analyzer.py +35 -35
- tapps_agents/core/startup.py +174 -174
- tapps_agents/core/storage_manager.py +397 -397
- tapps_agents/core/storage_models.py +166 -166
- tapps_agents/core/story_evaluator.py +410 -410
- tapps_agents/core/subprocess_utils.py +170 -170
- tapps_agents/core/task_duration.py +296 -296
- tapps_agents/core/task_memory.py +582 -582
- tapps_agents/core/task_state.py +226 -226
- tapps_agents/core/tech_stack_priorities.py +208 -208
- tapps_agents/core/temp_directory.py +194 -194
- tapps_agents/core/template_merger.py +600 -600
- tapps_agents/core/template_selector.py +280 -280
- tapps_agents/core/test_generator.py +286 -286
- tapps_agents/core/tiered_context.py +253 -253
- tapps_agents/core/token_monitor.py +345 -345
- tapps_agents/core/traceability.py +254 -254
- tapps_agents/core/trajectory_tracker.py +50 -50
- tapps_agents/core/unicode_safe.py +143 -143
- tapps_agents/core/unified_cache_config.py +170 -170
- tapps_agents/core/unified_state.py +324 -324
- tapps_agents/core/validate_cursor_setup.py +237 -237
- tapps_agents/core/validation_registry.py +136 -136
- tapps_agents/core/validators/__init__.py +4 -4
- tapps_agents/core/validators/python_validator.py +87 -87
- tapps_agents/core/verification_agent.py +90 -90
- tapps_agents/core/visual_feedback.py +644 -644
- tapps_agents/core/workflow_validator.py +197 -197
- tapps_agents/core/worktree.py +367 -367
- tapps_agents/docker/__init__.py +10 -10
- tapps_agents/docker/analyzer.py +186 -186
- tapps_agents/docker/debugger.py +229 -229
- tapps_agents/docker/error_patterns.py +216 -216
- tapps_agents/epic/__init__.py +22 -22
- tapps_agents/epic/beads_sync.py +115 -115
- tapps_agents/epic/markdown_sync.py +105 -105
- tapps_agents/epic/models.py +96 -96
- tapps_agents/experts/__init__.py +163 -163
- tapps_agents/experts/agent_integration.py +243 -243
- tapps_agents/experts/auto_generator.py +331 -331
- tapps_agents/experts/base_expert.py +536 -536
- tapps_agents/experts/builtin_registry.py +261 -261
- tapps_agents/experts/business_metrics.py +565 -565
- tapps_agents/experts/cache.py +266 -266
- tapps_agents/experts/confidence_breakdown.py +306 -306
- tapps_agents/experts/confidence_calculator.py +336 -336
- tapps_agents/experts/confidence_metrics.py +236 -236
- tapps_agents/experts/domain_config.py +311 -311
- tapps_agents/experts/domain_detector.py +550 -550
- tapps_agents/experts/domain_utils.py +84 -84
- tapps_agents/experts/expert_config.py +113 -113
- tapps_agents/experts/expert_engine.py +465 -465
- tapps_agents/experts/expert_registry.py +744 -744
- tapps_agents/experts/expert_synthesizer.py +70 -70
- tapps_agents/experts/governance.py +197 -197
- tapps_agents/experts/history_logger.py +312 -312
- tapps_agents/experts/knowledge/README.md +180 -180
- tapps_agents/experts/knowledge/accessibility/accessible-forms.md +331 -331
- tapps_agents/experts/knowledge/accessibility/aria-patterns.md +344 -344
- tapps_agents/experts/knowledge/accessibility/color-contrast.md +285 -285
- tapps_agents/experts/knowledge/accessibility/keyboard-navigation.md +332 -332
- tapps_agents/experts/knowledge/accessibility/screen-readers.md +282 -282
- tapps_agents/experts/knowledge/accessibility/semantic-html.md +355 -355
- tapps_agents/experts/knowledge/accessibility/testing-accessibility.md +369 -369
- tapps_agents/experts/knowledge/accessibility/wcag-2.1.md +296 -296
- tapps_agents/experts/knowledge/accessibility/wcag-2.2.md +211 -211
- tapps_agents/experts/knowledge/agent-learning/best-practices.md +715 -715
- tapps_agents/experts/knowledge/agent-learning/pattern-extraction.md +282 -282
- tapps_agents/experts/knowledge/agent-learning/prompt-optimization.md +320 -320
- tapps_agents/experts/knowledge/ai-frameworks/model-optimization.md +90 -90
- tapps_agents/experts/knowledge/ai-frameworks/openvino-patterns.md +260 -260
- tapps_agents/experts/knowledge/api-design-integration/api-gateway-patterns.md +309 -309
- tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +521 -521
- tapps_agents/experts/knowledge/api-design-integration/api-versioning.md +421 -421
- tapps_agents/experts/knowledge/api-design-integration/async-protocol-patterns.md +61 -61
- tapps_agents/experts/knowledge/api-design-integration/contract-testing.md +221 -221
- tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +489 -489
- tapps_agents/experts/knowledge/api-design-integration/fastapi-patterns.md +360 -360
- tapps_agents/experts/knowledge/api-design-integration/fastapi-testing.md +262 -262
- tapps_agents/experts/knowledge/api-design-integration/graphql-patterns.md +582 -582
- tapps_agents/experts/knowledge/api-design-integration/grpc-best-practices.md +499 -499
- tapps_agents/experts/knowledge/api-design-integration/mqtt-patterns.md +455 -455
- tapps_agents/experts/knowledge/api-design-integration/rate-limiting.md +507 -507
- tapps_agents/experts/knowledge/api-design-integration/restful-api-design.md +618 -618
- tapps_agents/experts/knowledge/api-design-integration/websocket-patterns.md +480 -480
- tapps_agents/experts/knowledge/cloud-infrastructure/cloud-native-patterns.md +175 -175
- tapps_agents/experts/knowledge/cloud-infrastructure/container-health-checks.md +261 -261
- tapps_agents/experts/knowledge/cloud-infrastructure/containerization.md +222 -222
- tapps_agents/experts/knowledge/cloud-infrastructure/cost-optimization.md +122 -122
- tapps_agents/experts/knowledge/cloud-infrastructure/disaster-recovery.md +153 -153
- tapps_agents/experts/knowledge/cloud-infrastructure/dockerfile-patterns.md +285 -285
- tapps_agents/experts/knowledge/cloud-infrastructure/infrastructure-as-code.md +187 -187
- tapps_agents/experts/knowledge/cloud-infrastructure/kubernetes-patterns.md +253 -253
- tapps_agents/experts/knowledge/cloud-infrastructure/multi-cloud-strategies.md +155 -155
- tapps_agents/experts/knowledge/cloud-infrastructure/serverless-architecture.md +200 -200
- tapps_agents/experts/knowledge/code-quality-analysis/README.md +16 -16
- tapps_agents/experts/knowledge/code-quality-analysis/code-metrics.md +137 -137
- tapps_agents/experts/knowledge/code-quality-analysis/complexity-analysis.md +181 -181
- tapps_agents/experts/knowledge/code-quality-analysis/technical-debt-patterns.md +191 -191
- tapps_agents/experts/knowledge/data-privacy-compliance/anonymization.md +313 -313
- tapps_agents/experts/knowledge/data-privacy-compliance/ccpa.md +255 -255
- tapps_agents/experts/knowledge/data-privacy-compliance/consent-management.md +282 -282
- tapps_agents/experts/knowledge/data-privacy-compliance/data-minimization.md +275 -275
- tapps_agents/experts/knowledge/data-privacy-compliance/data-retention.md +297 -297
- tapps_agents/experts/knowledge/data-privacy-compliance/data-subject-rights.md +383 -383
- tapps_agents/experts/knowledge/data-privacy-compliance/encryption-privacy.md +285 -285
- tapps_agents/experts/knowledge/data-privacy-compliance/gdpr.md +344 -344
- tapps_agents/experts/knowledge/data-privacy-compliance/hipaa.md +385 -385
- tapps_agents/experts/knowledge/data-privacy-compliance/privacy-by-design.md +280 -280
- tapps_agents/experts/knowledge/database-data-management/acid-vs-cap.md +164 -164
- tapps_agents/experts/knowledge/database-data-management/backup-and-recovery.md +182 -182
- tapps_agents/experts/knowledge/database-data-management/data-modeling.md +172 -172
- tapps_agents/experts/knowledge/database-data-management/database-design.md +187 -187
- tapps_agents/experts/knowledge/database-data-management/flux-query-optimization.md +342 -342
- tapps_agents/experts/knowledge/database-data-management/influxdb-connection-patterns.md +432 -432
- tapps_agents/experts/knowledge/database-data-management/influxdb-patterns.md +442 -442
- tapps_agents/experts/knowledge/database-data-management/migration-strategies.md +216 -216
- tapps_agents/experts/knowledge/database-data-management/nosql-patterns.md +259 -259
- tapps_agents/experts/knowledge/database-data-management/scalability-patterns.md +184 -184
- tapps_agents/experts/knowledge/database-data-management/sql-optimization.md +175 -175
- tapps_agents/experts/knowledge/database-data-management/time-series-modeling.md +444 -444
- tapps_agents/experts/knowledge/development-workflow/README.md +16 -16
- tapps_agents/experts/knowledge/development-workflow/automation-best-practices.md +216 -216
- tapps_agents/experts/knowledge/development-workflow/build-strategies.md +198 -198
- tapps_agents/experts/knowledge/development-workflow/deployment-patterns.md +205 -205
- tapps_agents/experts/knowledge/development-workflow/git-workflows.md +205 -205
- tapps_agents/experts/knowledge/documentation-knowledge-management/README.md +16 -16
- tapps_agents/experts/knowledge/documentation-knowledge-management/api-documentation-patterns.md +231 -231
- tapps_agents/experts/knowledge/documentation-knowledge-management/documentation-standards.md +191 -191
- tapps_agents/experts/knowledge/documentation-knowledge-management/knowledge-management.md +171 -171
- tapps_agents/experts/knowledge/documentation-knowledge-management/technical-writing-guide.md +192 -192
- tapps_agents/experts/knowledge/observability-monitoring/alerting-patterns.md +461 -461
- tapps_agents/experts/knowledge/observability-monitoring/apm-tools.md +459 -459
- tapps_agents/experts/knowledge/observability-monitoring/distributed-tracing.md +367 -367
- tapps_agents/experts/knowledge/observability-monitoring/logging-strategies.md +478 -478
- tapps_agents/experts/knowledge/observability-monitoring/metrics-and-monitoring.md +510 -510
- tapps_agents/experts/knowledge/observability-monitoring/observability-best-practices.md +492 -492
- tapps_agents/experts/knowledge/observability-monitoring/open-telemetry.md +573 -573
- tapps_agents/experts/knowledge/observability-monitoring/slo-sli-sla.md +419 -419
- tapps_agents/experts/knowledge/performance/anti-patterns.md +284 -284
- tapps_agents/experts/knowledge/performance/api-performance.md +256 -256
- tapps_agents/experts/knowledge/performance/caching.md +327 -327
- tapps_agents/experts/knowledge/performance/database-performance.md +252 -252
- tapps_agents/experts/knowledge/performance/optimization-patterns.md +327 -327
- tapps_agents/experts/knowledge/performance/profiling.md +297 -297
- tapps_agents/experts/knowledge/performance/resource-management.md +293 -293
- tapps_agents/experts/knowledge/performance/scalability.md +306 -306
- tapps_agents/experts/knowledge/security/owasp-top10.md +209 -209
- tapps_agents/experts/knowledge/security/secure-coding-practices.md +207 -207
- tapps_agents/experts/knowledge/security/threat-modeling.md +220 -220
- tapps_agents/experts/knowledge/security/vulnerability-patterns.md +342 -342
- tapps_agents/experts/knowledge/software-architecture/docker-compose-patterns.md +314 -314
- tapps_agents/experts/knowledge/software-architecture/microservices-patterns.md +379 -379
- tapps_agents/experts/knowledge/software-architecture/service-communication.md +316 -316
- tapps_agents/experts/knowledge/testing/best-practices.md +310 -310
- tapps_agents/experts/knowledge/testing/coverage-analysis.md +293 -293
- tapps_agents/experts/knowledge/testing/mocking.md +256 -256
- tapps_agents/experts/knowledge/testing/test-automation.md +276 -276
- tapps_agents/experts/knowledge/testing/test-data.md +271 -271
- tapps_agents/experts/knowledge/testing/test-design-patterns.md +280 -280
- tapps_agents/experts/knowledge/testing/test-maintenance.md +236 -236
- tapps_agents/experts/knowledge/testing/test-strategies.md +311 -311
- tapps_agents/experts/knowledge/user-experience/information-architecture.md +325 -325
- tapps_agents/experts/knowledge/user-experience/interaction-design.md +363 -363
- tapps_agents/experts/knowledge/user-experience/prototyping.md +293 -293
- tapps_agents/experts/knowledge/user-experience/usability-heuristics.md +337 -337
- tapps_agents/experts/knowledge/user-experience/usability-testing.md +311 -311
- tapps_agents/experts/knowledge/user-experience/user-journeys.md +296 -296
- tapps_agents/experts/knowledge/user-experience/user-research.md +373 -373
- tapps_agents/experts/knowledge/user-experience/ux-principles.md +340 -340
- tapps_agents/experts/knowledge_freshness.py +321 -321
- tapps_agents/experts/knowledge_ingestion.py +438 -438
- tapps_agents/experts/knowledge_need_detector.py +93 -93
- tapps_agents/experts/knowledge_validator.py +382 -382
- tapps_agents/experts/observability.py +440 -440
- tapps_agents/experts/passive_notifier.py +238 -238
- tapps_agents/experts/proactive_orchestrator.py +32 -32
- tapps_agents/experts/rag_chunker.py +205 -205
- tapps_agents/experts/rag_embedder.py +152 -152
- tapps_agents/experts/rag_evaluation.py +299 -299
- tapps_agents/experts/rag_index.py +303 -303
- tapps_agents/experts/rag_metrics.py +293 -293
- tapps_agents/experts/rag_safety.py +263 -263
- tapps_agents/experts/report_generator.py +296 -296
- tapps_agents/experts/setup_wizard.py +441 -441
- tapps_agents/experts/simple_rag.py +431 -431
- tapps_agents/experts/vector_rag.py +354 -354
- tapps_agents/experts/weight_distributor.py +304 -304
- tapps_agents/health/__init__.py +24 -24
- tapps_agents/health/base.py +75 -75
- tapps_agents/health/checks/__init__.py +22 -22
- tapps_agents/health/checks/automation.py +127 -127
- tapps_agents/health/checks/context7_cache.py +210 -210
- tapps_agents/health/checks/environment.py +116 -116
- tapps_agents/health/checks/execution.py +170 -170
- tapps_agents/health/checks/knowledge_base.py +187 -187
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +324 -0
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +324 -0
- tapps_agents/health/checks/outcomes.py +324 -324
- tapps_agents/health/collector.py +280 -280
- tapps_agents/health/dashboard.py +137 -137
- tapps_agents/health/metrics.py +151 -151
- tapps_agents/health/registry.py +166 -166
- tapps_agents/hooks/__init__.py +33 -33
- tapps_agents/hooks/config.py +140 -140
- tapps_agents/hooks/events.py +135 -135
- tapps_agents/hooks/executor.py +128 -128
- tapps_agents/hooks/manager.py +143 -143
- tapps_agents/integration/__init__.py +8 -8
- tapps_agents/integration/service_integrator.py +121 -121
- tapps_agents/integrations/__init__.py +10 -10
- tapps_agents/integrations/clawdbot.py +525 -525
- tapps_agents/integrations/memory_bridge.py +356 -356
- tapps_agents/mcp/__init__.py +18 -18
- tapps_agents/mcp/gateway.py +112 -112
- tapps_agents/mcp/servers/__init__.py +13 -13
- tapps_agents/mcp/servers/analysis.py +204 -204
- tapps_agents/mcp/servers/context7.py +198 -198
- tapps_agents/mcp/servers/filesystem.py +218 -218
- tapps_agents/mcp/servers/git.py +201 -201
- tapps_agents/mcp/tool_registry.py +115 -115
- tapps_agents/quality/__init__.py +54 -54
- tapps_agents/quality/coverage_analyzer.py +379 -379
- tapps_agents/quality/enforcement.py +82 -82
- tapps_agents/quality/gates/__init__.py +37 -37
- tapps_agents/quality/gates/approval_gate.py +255 -255
- tapps_agents/quality/gates/base.py +84 -84
- tapps_agents/quality/gates/exceptions.py +43 -43
- tapps_agents/quality/gates/policy_gate.py +195 -195
- tapps_agents/quality/gates/registry.py +239 -239
- tapps_agents/quality/gates/security_gate.py +156 -156
- tapps_agents/quality/quality_gates.py +369 -369
- tapps_agents/quality/secret_scanner.py +335 -335
- tapps_agents/resources/__init__.py +5 -0
- tapps_agents/resources/claude/__init__.py +1 -0
- tapps_agents/resources/claude/commands/README.md +156 -0
- tapps_agents/resources/claude/commands/__init__.py +1 -0
- tapps_agents/resources/claude/commands/build-fix.md +22 -0
- tapps_agents/resources/claude/commands/build.md +77 -0
- tapps_agents/resources/claude/commands/debug.md +53 -0
- tapps_agents/resources/claude/commands/design.md +68 -0
- tapps_agents/resources/claude/commands/docs.md +53 -0
- tapps_agents/resources/claude/commands/e2e.md +22 -0
- tapps_agents/resources/claude/commands/fix.md +54 -0
- tapps_agents/resources/claude/commands/implement.md +53 -0
- tapps_agents/resources/claude/commands/improve.md +53 -0
- tapps_agents/resources/claude/commands/library-docs.md +64 -0
- tapps_agents/resources/claude/commands/lint.md +52 -0
- tapps_agents/resources/claude/commands/plan.md +65 -0
- tapps_agents/resources/claude/commands/refactor-clean.md +21 -0
- tapps_agents/resources/claude/commands/refactor.md +55 -0
- tapps_agents/resources/claude/commands/review.md +67 -0
- tapps_agents/resources/claude/commands/score.md +60 -0
- tapps_agents/resources/claude/commands/security-review.md +22 -0
- tapps_agents/resources/claude/commands/security-scan.md +54 -0
- tapps_agents/resources/claude/commands/tdd.md +24 -0
- tapps_agents/resources/claude/commands/test-coverage.md +21 -0
- tapps_agents/resources/claude/commands/test.md +54 -0
- tapps_agents/resources/claude/commands/update-codemaps.md +20 -0
- tapps_agents/resources/claude/commands/update-docs.md +21 -0
- tapps_agents/resources/claude/skills/__init__.py +1 -0
- tapps_agents/resources/claude/skills/analyst/SKILL.md +272 -0
- tapps_agents/resources/claude/skills/analyst/__init__.py +1 -0
- tapps_agents/resources/claude/skills/architect/SKILL.md +282 -0
- tapps_agents/resources/claude/skills/architect/__init__.py +1 -0
- tapps_agents/resources/claude/skills/backend-patterns/SKILL.md +30 -0
- tapps_agents/resources/claude/skills/backend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/coding-standards/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/coding-standards/__init__.py +1 -0
- tapps_agents/resources/claude/skills/debugger/SKILL.md +203 -0
- tapps_agents/resources/claude/skills/debugger/__init__.py +1 -0
- tapps_agents/resources/claude/skills/designer/SKILL.md +243 -0
- tapps_agents/resources/claude/skills/designer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/documenter/SKILL.md +252 -0
- tapps_agents/resources/claude/skills/documenter/__init__.py +1 -0
- tapps_agents/resources/claude/skills/enhancer/SKILL.md +307 -0
- tapps_agents/resources/claude/skills/enhancer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/evaluator/SKILL.md +204 -0
- tapps_agents/resources/claude/skills/evaluator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/frontend-patterns/SKILL.md +29 -0
- tapps_agents/resources/claude/skills/frontend-patterns/__init__.py +1 -0
- tapps_agents/resources/claude/skills/implementer/SKILL.md +188 -0
- tapps_agents/resources/claude/skills/implementer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/improver/SKILL.md +218 -0
- tapps_agents/resources/claude/skills/improver/__init__.py +1 -0
- tapps_agents/resources/claude/skills/ops/SKILL.md +281 -0
- tapps_agents/resources/claude/skills/ops/__init__.py +1 -0
- tapps_agents/resources/claude/skills/orchestrator/SKILL.md +390 -0
- tapps_agents/resources/claude/skills/orchestrator/__init__.py +1 -0
- tapps_agents/resources/claude/skills/planner/SKILL.md +254 -0
- tapps_agents/resources/claude/skills/planner/__init__.py +1 -0
- tapps_agents/resources/claude/skills/reviewer/SKILL.md +434 -0
- tapps_agents/resources/claude/skills/reviewer/__init__.py +1 -0
- tapps_agents/resources/claude/skills/security-review/SKILL.md +31 -0
- tapps_agents/resources/claude/skills/security-review/__init__.py +1 -0
- tapps_agents/resources/claude/skills/simple-mode/SKILL.md +695 -0
- tapps_agents/resources/claude/skills/simple-mode/__init__.py +1 -0
- tapps_agents/resources/claude/skills/tester/SKILL.md +219 -0
- tapps_agents/resources/claude/skills/tester/__init__.py +1 -0
- tapps_agents/resources/cursor/.cursorignore +35 -0
- tapps_agents/resources/cursor/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/__init__.py +1 -0
- tapps_agents/resources/cursor/commands/build-fix.md +11 -0
- tapps_agents/resources/cursor/commands/build.md +11 -0
- tapps_agents/resources/cursor/commands/e2e.md +11 -0
- tapps_agents/resources/cursor/commands/fix.md +11 -0
- tapps_agents/resources/cursor/commands/refactor-clean.md +11 -0
- tapps_agents/resources/cursor/commands/review.md +11 -0
- tapps_agents/resources/cursor/commands/security-review.md +11 -0
- tapps_agents/resources/cursor/commands/tdd.md +11 -0
- tapps_agents/resources/cursor/commands/test-coverage.md +11 -0
- tapps_agents/resources/cursor/commands/test.md +11 -0
- tapps_agents/resources/cursor/commands/update-codemaps.md +10 -0
- tapps_agents/resources/cursor/commands/update-docs.md +11 -0
- tapps_agents/resources/cursor/rules/__init__.py +1 -0
- tapps_agents/resources/cursor/rules/agent-capabilities.mdc +687 -0
- tapps_agents/resources/cursor/rules/coding-style.mdc +31 -0
- tapps_agents/resources/cursor/rules/command-reference.mdc +2081 -0
- tapps_agents/resources/cursor/rules/cursor-mode-usage.mdc +125 -0
- tapps_agents/resources/cursor/rules/git-workflow.mdc +29 -0
- tapps_agents/resources/cursor/rules/performance.mdc +29 -0
- tapps_agents/resources/cursor/rules/project-context.mdc +163 -0
- tapps_agents/resources/cursor/rules/project-profiling.mdc +197 -0
- tapps_agents/resources/cursor/rules/quick-reference.mdc +630 -0
- tapps_agents/resources/cursor/rules/security.mdc +32 -0
- tapps_agents/resources/cursor/rules/simple-mode.mdc +500 -0
- tapps_agents/resources/cursor/rules/testing.mdc +31 -0
- tapps_agents/resources/cursor/rules/when-to-use.mdc +156 -0
- tapps_agents/resources/cursor/rules/workflow-presets.mdc +179 -0
- tapps_agents/resources/customizations/__init__.py +1 -0
- tapps_agents/resources/customizations/example-custom.yaml +83 -0
- tapps_agents/resources/hooks/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/README.md +5 -0
- tapps_agents/resources/hooks/templates/__init__.py +1 -0
- tapps_agents/resources/hooks/templates/add-project-context.yaml +8 -0
- tapps_agents/resources/hooks/templates/auto-format-js.yaml +10 -0
- tapps_agents/resources/hooks/templates/auto-format-python.yaml +10 -0
- tapps_agents/resources/hooks/templates/git-commit-check.yaml +7 -0
- tapps_agents/resources/hooks/templates/notify-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/quality-gate.yaml +8 -0
- tapps_agents/resources/hooks/templates/security-scan-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/session-end-log.yaml +7 -0
- tapps_agents/resources/hooks/templates/show-beads-ready.yaml +8 -0
- tapps_agents/resources/hooks/templates/test-on-edit.yaml +10 -0
- tapps_agents/resources/hooks/templates/update-docs-on-complete.yaml +8 -0
- tapps_agents/resources/hooks/templates/user-prompt-log.yaml +7 -0
- tapps_agents/resources/scripts/__init__.py +1 -0
- tapps_agents/resources/scripts/set_bd_path.ps1 +51 -0
- tapps_agents/resources/workflows/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/__init__.py +1 -0
- tapps_agents/resources/workflows/presets/brownfield-analysis.yaml +235 -0
- tapps_agents/resources/workflows/presets/fix.yaml +78 -0
- tapps_agents/resources/workflows/presets/full-sdlc.yaml +122 -0
- tapps_agents/resources/workflows/presets/quality.yaml +82 -0
- tapps_agents/resources/workflows/presets/rapid-dev.yaml +84 -0
- tapps_agents/session/__init__.py +19 -19
- tapps_agents/session/manager.py +256 -256
- tapps_agents/simple_mode/__init__.py +66 -66
- tapps_agents/simple_mode/agent_contracts.py +357 -357
- tapps_agents/simple_mode/beads_hooks.py +151 -151
- tapps_agents/simple_mode/code_snippet_handler.py +382 -382
- tapps_agents/simple_mode/documentation_manager.py +395 -395
- tapps_agents/simple_mode/documentation_reader.py +187 -187
- tapps_agents/simple_mode/file_inference.py +292 -292
- tapps_agents/simple_mode/framework_change_detector.py +268 -268
- tapps_agents/simple_mode/intent_parser.py +510 -510
- tapps_agents/simple_mode/learning_progression.py +358 -358
- tapps_agents/simple_mode/nl_handler.py +700 -700
- tapps_agents/simple_mode/onboarding.py +253 -253
- tapps_agents/simple_mode/orchestrators/__init__.py +38 -38
- tapps_agents/simple_mode/orchestrators/breakdown_orchestrator.py +49 -49
- tapps_agents/simple_mode/orchestrators/brownfield_orchestrator.py +135 -135
- tapps_agents/simple_mode/orchestrators/deliverable_checklist.py +349 -349
- tapps_agents/simple_mode/orchestrators/enhance_orchestrator.py +53 -53
- tapps_agents/simple_mode/orchestrators/epic_orchestrator.py +122 -122
- tapps_agents/simple_mode/orchestrators/explore_orchestrator.py +184 -184
- tapps_agents/simple_mode/orchestrators/plan_analysis_orchestrator.py +206 -206
- tapps_agents/simple_mode/orchestrators/pr_orchestrator.py +237 -237
- tapps_agents/simple_mode/orchestrators/refactor_orchestrator.py +222 -222
- tapps_agents/simple_mode/orchestrators/requirements_tracer.py +262 -262
- tapps_agents/simple_mode/orchestrators/resume_orchestrator.py +210 -210
- tapps_agents/simple_mode/orchestrators/review_orchestrator.py +161 -161
- tapps_agents/simple_mode/orchestrators/test_orchestrator.py +82 -82
- tapps_agents/simple_mode/output_aggregator.py +340 -340
- tapps_agents/simple_mode/result_formatters.py +598 -598
- tapps_agents/simple_mode/step_dependencies.py +382 -382
- tapps_agents/simple_mode/step_results.py +276 -276
- tapps_agents/simple_mode/streaming.py +388 -388
- tapps_agents/simple_mode/variations.py +129 -129
- tapps_agents/simple_mode/visual_feedback.py +238 -238
- tapps_agents/simple_mode/zero_config.py +274 -274
- tapps_agents/suggestions/__init__.py +8 -8
- tapps_agents/suggestions/inline_suggester.py +52 -52
- tapps_agents/templates/__init__.py +8 -8
- tapps_agents/templates/microservice_generator.py +274 -274
- tapps_agents/utils/env_validator.py +291 -291
- tapps_agents/workflow/__init__.py +171 -171
- tapps_agents/workflow/acceptance_verifier.py +132 -132
- tapps_agents/workflow/agent_handlers/__init__.py +41 -41
- tapps_agents/workflow/agent_handlers/analyst_handler.py +75 -75
- tapps_agents/workflow/agent_handlers/architect_handler.py +107 -107
- tapps_agents/workflow/agent_handlers/base.py +84 -84
- tapps_agents/workflow/agent_handlers/debugger_handler.py +100 -100
- tapps_agents/workflow/agent_handlers/designer_handler.py +110 -110
- tapps_agents/workflow/agent_handlers/documenter_handler.py +94 -94
- tapps_agents/workflow/agent_handlers/implementer_handler.py +235 -235
- tapps_agents/workflow/agent_handlers/ops_handler.py +62 -62
- tapps_agents/workflow/agent_handlers/orchestrator_handler.py +43 -43
- tapps_agents/workflow/agent_handlers/planner_handler.py +98 -98
- tapps_agents/workflow/agent_handlers/registry.py +119 -119
- tapps_agents/workflow/agent_handlers/reviewer_handler.py +119 -119
- tapps_agents/workflow/agent_handlers/tester_handler.py +69 -69
- tapps_agents/workflow/analytics_accessor.py +337 -337
- tapps_agents/workflow/analytics_alerts.py +416 -416
- tapps_agents/workflow/analytics_dashboard_cursor.py +281 -281
- tapps_agents/workflow/analytics_dual_write.py +103 -103
- tapps_agents/workflow/analytics_integration.py +119 -119
- tapps_agents/workflow/analytics_query_parser.py +278 -278
- tapps_agents/workflow/analytics_visualizer.py +259 -259
- tapps_agents/workflow/artifact_helper.py +204 -204
- tapps_agents/workflow/audit_logger.py +263 -263
- tapps_agents/workflow/auto_execution_config.py +340 -340
- tapps_agents/workflow/auto_progression.py +586 -586
- tapps_agents/workflow/branch_cleanup.py +349 -349
- tapps_agents/workflow/checkpoint.py +256 -256
- tapps_agents/workflow/checkpoint_manager.py +178 -178
- tapps_agents/workflow/code_artifact.py +179 -179
- tapps_agents/workflow/common_enums.py +96 -96
- tapps_agents/workflow/confirmation_handler.py +130 -130
- tapps_agents/workflow/context_analyzer.py +222 -222
- tapps_agents/workflow/context_artifact.py +230 -230
- tapps_agents/workflow/cursor_chat.py +94 -94
- tapps_agents/workflow/cursor_skill_helper.py +516 -516
- tapps_agents/workflow/dependency_resolver.py +244 -244
- tapps_agents/workflow/design_artifact.py +156 -156
- tapps_agents/workflow/detector.py +751 -751
- tapps_agents/workflow/direct_execution_fallback.py +301 -301
- tapps_agents/workflow/docs_artifact.py +168 -168
- tapps_agents/workflow/enforcer.py +389 -389
- tapps_agents/workflow/enhancement_artifact.py +142 -142
- tapps_agents/workflow/error_recovery.py +806 -806
- tapps_agents/workflow/event_bus.py +183 -183
- tapps_agents/workflow/event_log.py +612 -612
- tapps_agents/workflow/events.py +63 -63
- tapps_agents/workflow/exceptions.py +43 -43
- tapps_agents/workflow/execution_graph.py +498 -498
- tapps_agents/workflow/execution_plan.py +126 -126
- tapps_agents/workflow/file_utils.py +186 -186
- tapps_agents/workflow/gate_evaluator.py +182 -182
- tapps_agents/workflow/gate_integration.py +200 -200
- tapps_agents/workflow/graph_visualizer.py +130 -130
- tapps_agents/workflow/health_checker.py +206 -206
- tapps_agents/workflow/logging_helper.py +243 -243
- tapps_agents/workflow/manifest.py +582 -582
- tapps_agents/workflow/marker_writer.py +250 -250
- tapps_agents/workflow/messaging.py +325 -325
- tapps_agents/workflow/metadata_models.py +91 -91
- tapps_agents/workflow/metrics_integration.py +226 -226
- tapps_agents/workflow/migration_utils.py +116 -116
- tapps_agents/workflow/models.py +148 -148
- tapps_agents/workflow/nlp_config.py +198 -198
- tapps_agents/workflow/nlp_error_handler.py +207 -207
- tapps_agents/workflow/nlp_executor.py +163 -163
- tapps_agents/workflow/nlp_parser.py +528 -528
- tapps_agents/workflow/observability_dashboard.py +451 -451
- tapps_agents/workflow/observer.py +170 -170
- tapps_agents/workflow/ops_artifact.py +257 -257
- tapps_agents/workflow/output_passing.py +214 -214
- tapps_agents/workflow/parallel_executor.py +463 -463
- tapps_agents/workflow/planning_artifact.py +179 -179
- tapps_agents/workflow/preset_loader.py +285 -285
- tapps_agents/workflow/preset_recommender.py +270 -270
- tapps_agents/workflow/progress_logger.py +145 -145
- tapps_agents/workflow/progress_manager.py +303 -303
- tapps_agents/workflow/progress_monitor.py +186 -186
- tapps_agents/workflow/progress_updates.py +423 -423
- tapps_agents/workflow/quality_artifact.py +158 -158
- tapps_agents/workflow/quality_loopback.py +101 -101
- tapps_agents/workflow/recommender.py +387 -387
- tapps_agents/workflow/remediation_loop.py +166 -166
- tapps_agents/workflow/result_aggregator.py +300 -300
- tapps_agents/workflow/review_artifact.py +185 -185
- tapps_agents/workflow/schema_validator.py +522 -522
- tapps_agents/workflow/session_handoff.py +178 -178
- tapps_agents/workflow/skill_invoker.py +648 -648
- tapps_agents/workflow/state_manager.py +756 -756
- tapps_agents/workflow/state_persistence_config.py +331 -331
- tapps_agents/workflow/status_monitor.py +449 -449
- tapps_agents/workflow/step_checkpoint.py +314 -314
- tapps_agents/workflow/step_details.py +201 -201
- tapps_agents/workflow/story_models.py +147 -147
- tapps_agents/workflow/streaming.py +416 -416
- tapps_agents/workflow/suggestion_engine.py +552 -552
- tapps_agents/workflow/testing_artifact.py +186 -186
- tapps_agents/workflow/timeline.py +158 -158
- tapps_agents/workflow/token_integration.py +209 -209
- tapps_agents/workflow/validation.py +217 -217
- tapps_agents/workflow/visual_feedback.py +391 -391
- tapps_agents/workflow/workflow_chain.py +95 -95
- tapps_agents/workflow/workflow_summary.py +219 -219
- tapps_agents/workflow/worktree_manager.py +724 -724
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/METADATA +672 -672
- tapps_agents-3.6.1.dist-info/RECORD +883 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/licenses/LICENSE +22 -22
- tapps_agents-3.6.0.dist-info/RECORD +0 -758
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/WHEEL +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.6.0.dist-info → tapps_agents-3.6.1.dist-info}/top_level.txt +0 -0
|
@@ -1,431 +1,431 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Simple File-Based RAG System for Industry Experts
|
|
3
|
-
|
|
4
|
-
Provides knowledge retrieval from markdown files in a knowledge/ directory
|
|
5
|
-
using keyword search and context extraction. No vector DB required.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
import logging
|
|
9
|
-
import re
|
|
10
|
-
from dataclasses import dataclass
|
|
11
|
-
from pathlib import Path
|
|
12
|
-
|
|
13
|
-
logger = logging.getLogger(__name__)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
@dataclass
|
|
17
|
-
class KnowledgeChunk:
|
|
18
|
-
"""A chunk of knowledge from a knowledge base file."""
|
|
19
|
-
|
|
20
|
-
content: str
|
|
21
|
-
source_file: Path
|
|
22
|
-
line_start: int
|
|
23
|
-
line_end: int
|
|
24
|
-
score: float = 0.0 # Relevance score (0.0-1.0)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class SimpleKnowledgeBase:
|
|
28
|
-
"""
|
|
29
|
-
Simple file-based knowledge base for RAG.
|
|
30
|
-
|
|
31
|
-
Features:
|
|
32
|
-
- Keyword search in markdown files
|
|
33
|
-
- Context extraction around matches
|
|
34
|
-
- File-based storage (no vector DB)
|
|
35
|
-
- Markdown-aware chunking
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
def __init__(self, knowledge_dir: Path, domain: str | None = None):
|
|
39
|
-
"""
|
|
40
|
-
Initialize knowledge base.
|
|
41
|
-
|
|
42
|
-
Args:
|
|
43
|
-
knowledge_dir: Directory containing knowledge files (markdown)
|
|
44
|
-
domain: Optional domain filter (only load files matching domain)
|
|
45
|
-
"""
|
|
46
|
-
self.knowledge_dir = Path(knowledge_dir)
|
|
47
|
-
self.domain = domain
|
|
48
|
-
self.files: dict[Path, str] = {} # Cache of loaded files
|
|
49
|
-
self._load_knowledge_files()
|
|
50
|
-
|
|
51
|
-
def _load_knowledge_files(self):
|
|
52
|
-
"""Load all markdown files from knowledge directory."""
|
|
53
|
-
if not self.knowledge_dir.exists():
|
|
54
|
-
return # No knowledge base directory
|
|
55
|
-
|
|
56
|
-
# Load .md files
|
|
57
|
-
for md_file in self.knowledge_dir.rglob("*.md"):
|
|
58
|
-
# Filter by domain if specified
|
|
59
|
-
if self.domain:
|
|
60
|
-
# Check if file path or name contains domain
|
|
61
|
-
if (
|
|
62
|
-
self.domain.lower() not in md_file.stem.lower()
|
|
63
|
-
and self.domain.lower() not in str(md_file).lower()
|
|
64
|
-
):
|
|
65
|
-
continue
|
|
66
|
-
|
|
67
|
-
try:
|
|
68
|
-
content = md_file.read_text(encoding="utf-8")
|
|
69
|
-
self.files[md_file] = content
|
|
70
|
-
except Exception:
|
|
71
|
-
# Skip files that can't be read
|
|
72
|
-
logger.debug("Failed to read knowledge file %s", md_file, exc_info=True)
|
|
73
|
-
continue # nosec B112 - best-effort load
|
|
74
|
-
|
|
75
|
-
def _normalize_query(self, query: str) -> set[str]:
|
|
76
|
-
"""
|
|
77
|
-
Normalize query by removing stop words, stemming, and extracting keywords.
|
|
78
|
-
|
|
79
|
-
Args:
|
|
80
|
-
query: Raw query string
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
Set of normalized keywords
|
|
84
|
-
"""
|
|
85
|
-
# Common stop words (technical domain focused)
|
|
86
|
-
stop_words = {
|
|
87
|
-
"the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for",
|
|
88
|
-
"of", "with", "by", "from", "as", "is", "was", "are", "were", "be",
|
|
89
|
-
"been", "have", "has", "had", "do", "does", "did", "will", "would",
|
|
90
|
-
"should", "could", "may", "might", "must", "can", "this", "that",
|
|
91
|
-
"these", "those", "i", "you", "he", "she", "it", "we", "they",
|
|
92
|
-
"what", "how", "why", "when", "where", "which", "who"
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
# Normalize: lowercase, remove punctuation, split
|
|
96
|
-
query_lower = query.lower()
|
|
97
|
-
# Remove punctuation except hyphens (for compound terms)
|
|
98
|
-
query_clean = re.sub(r'[^\w\s-]', ' ', query_lower)
|
|
99
|
-
words = query_clean.split()
|
|
100
|
-
|
|
101
|
-
# Filter: remove stop words and short words
|
|
102
|
-
keywords = {
|
|
103
|
-
word.lower() for word in words
|
|
104
|
-
if len(word) > 2 and word.lower() not in stop_words
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return keywords
|
|
108
|
-
|
|
109
|
-
def search(
|
|
110
|
-
self, query: str, max_results: int = 5, context_lines: int = 10
|
|
111
|
-
) -> list[KnowledgeChunk]:
|
|
112
|
-
"""
|
|
113
|
-
Search knowledge base for relevant chunks.
|
|
114
|
-
|
|
115
|
-
Args:
|
|
116
|
-
query: Search query (keywords)
|
|
117
|
-
max_results: Maximum number of chunks to return
|
|
118
|
-
context_lines: Number of lines of context around matches
|
|
119
|
-
|
|
120
|
-
Returns:
|
|
121
|
-
List of KnowledgeChunk objects sorted by relevance
|
|
122
|
-
"""
|
|
123
|
-
query_keywords = self._normalize_query(query)
|
|
124
|
-
|
|
125
|
-
chunks: list[KnowledgeChunk] = []
|
|
126
|
-
|
|
127
|
-
for file_path, content in self.files.items():
|
|
128
|
-
file_chunks = self._extract_relevant_chunks(
|
|
129
|
-
file_path, content, query_keywords, context_lines
|
|
130
|
-
)
|
|
131
|
-
chunks.extend(file_chunks)
|
|
132
|
-
|
|
133
|
-
# Sort by score (highest first)
|
|
134
|
-
chunks.sort(key=lambda c: c.score, reverse=True)
|
|
135
|
-
|
|
136
|
-
# Return top results
|
|
137
|
-
return chunks[:max_results]
|
|
138
|
-
|
|
139
|
-
def _extract_relevant_chunks(
|
|
140
|
-
self, file_path: Path, content: str, query_keywords: set, context_lines: int
|
|
141
|
-
) -> list[KnowledgeChunk]:
|
|
142
|
-
"""
|
|
143
|
-
Extract relevant chunks from a file based on keyword matches.
|
|
144
|
-
|
|
145
|
-
Uses markdown-aware chunking (respects headers, paragraphs).
|
|
146
|
-
"""
|
|
147
|
-
lines = content.split("\n")
|
|
148
|
-
chunks: list[KnowledgeChunk] = []
|
|
149
|
-
|
|
150
|
-
# Score each line by keyword matches with improved scoring
|
|
151
|
-
line_scores: dict[int, float] = {}
|
|
152
|
-
for i, line in enumerate(lines):
|
|
153
|
-
line_lower = line.lower()
|
|
154
|
-
|
|
155
|
-
# Base score: count keyword matches
|
|
156
|
-
base_score = sum(1.0 for keyword in query_keywords if keyword in line_lower)
|
|
157
|
-
|
|
158
|
-
# Boost for exact phrase matches (consecutive keywords)
|
|
159
|
-
if len(query_keywords) > 1:
|
|
160
|
-
query_phrase = " ".join(sorted(query_keywords))
|
|
161
|
-
if query_phrase in line_lower or any(
|
|
162
|
-
keyword1 in line_lower and keyword2 in line_lower
|
|
163
|
-
for keyword1 in query_keywords
|
|
164
|
-
for keyword2 in query_keywords
|
|
165
|
-
if keyword1 != keyword2
|
|
166
|
-
):
|
|
167
|
-
base_score *= 1.3
|
|
168
|
-
|
|
169
|
-
# Boost score for headers (marked by #)
|
|
170
|
-
header_boost = 1.0
|
|
171
|
-
if line.strip().startswith("#"):
|
|
172
|
-
# H1 gets highest boost, H2 less, etc.
|
|
173
|
-
header_level = len(line) - len(line.lstrip("#"))
|
|
174
|
-
header_boost = 2.0 - (header_level * 0.2)
|
|
175
|
-
|
|
176
|
-
# Boost for code blocks (examples are valuable)
|
|
177
|
-
if line.strip().startswith("```"):
|
|
178
|
-
base_score *= 1.4
|
|
179
|
-
|
|
180
|
-
# Boost for lines with lists (structured information)
|
|
181
|
-
if line.strip().startswith("- ") or line.strip().startswith("* "):
|
|
182
|
-
base_score *= 1.2
|
|
183
|
-
|
|
184
|
-
score = base_score * header_boost
|
|
185
|
-
|
|
186
|
-
if score > 0:
|
|
187
|
-
line_scores[i] = score
|
|
188
|
-
|
|
189
|
-
if not line_scores:
|
|
190
|
-
return chunks # No matches
|
|
191
|
-
|
|
192
|
-
# Group consecutive high-scoring lines into chunks
|
|
193
|
-
current_chunk_start: int | None = None
|
|
194
|
-
current_chunk_lines: list[int] = []
|
|
195
|
-
|
|
196
|
-
for i in sorted(line_scores.keys()):
|
|
197
|
-
if current_chunk_start is None:
|
|
198
|
-
current_chunk_start = i
|
|
199
|
-
current_chunk_lines = [i]
|
|
200
|
-
elif i - current_chunk_lines[-1] <= context_lines:
|
|
201
|
-
# Within context distance, add to current chunk
|
|
202
|
-
current_chunk_lines.append(i)
|
|
203
|
-
else:
|
|
204
|
-
# New chunk needed
|
|
205
|
-
if current_chunk_start is not None:
|
|
206
|
-
chunk = self._create_chunk_from_lines(
|
|
207
|
-
file_path,
|
|
208
|
-
lines,
|
|
209
|
-
current_chunk_start,
|
|
210
|
-
current_chunk_lines[-1],
|
|
211
|
-
context_lines,
|
|
212
|
-
query_keywords,
|
|
213
|
-
)
|
|
214
|
-
if chunk:
|
|
215
|
-
chunks.append(chunk)
|
|
216
|
-
|
|
217
|
-
current_chunk_start = i
|
|
218
|
-
current_chunk_lines = [i]
|
|
219
|
-
|
|
220
|
-
# Add final chunk
|
|
221
|
-
if current_chunk_start is not None:
|
|
222
|
-
chunk = self._create_chunk_from_lines(
|
|
223
|
-
file_path,
|
|
224
|
-
lines,
|
|
225
|
-
current_chunk_start,
|
|
226
|
-
current_chunk_lines[-1],
|
|
227
|
-
context_lines,
|
|
228
|
-
query_keywords,
|
|
229
|
-
)
|
|
230
|
-
if chunk:
|
|
231
|
-
chunks.append(chunk)
|
|
232
|
-
|
|
233
|
-
return chunks
|
|
234
|
-
|
|
235
|
-
def _create_chunk_from_lines(
|
|
236
|
-
self,
|
|
237
|
-
file_path: Path,
|
|
238
|
-
lines: list[str],
|
|
239
|
-
start_line: int,
|
|
240
|
-
end_line: int,
|
|
241
|
-
context_lines: int,
|
|
242
|
-
query_keywords: set,
|
|
243
|
-
) -> KnowledgeChunk | None:
|
|
244
|
-
"""Create a KnowledgeChunk from line range with context."""
|
|
245
|
-
# Expand range with context
|
|
246
|
-
actual_start = max(0, start_line - context_lines)
|
|
247
|
-
actual_end = min(len(lines), end_line + context_lines)
|
|
248
|
-
|
|
249
|
-
# Try to align to markdown boundaries (headers)
|
|
250
|
-
for i in range(actual_start, start_line):
|
|
251
|
-
if lines[i].strip().startswith("#"):
|
|
252
|
-
actual_start = i
|
|
253
|
-
break
|
|
254
|
-
|
|
255
|
-
# Extract chunk content
|
|
256
|
-
chunk_lines = lines[actual_start:actual_end]
|
|
257
|
-
content = "\n".join(chunk_lines).strip()
|
|
258
|
-
|
|
259
|
-
if not content:
|
|
260
|
-
return None
|
|
261
|
-
|
|
262
|
-
# Calculate relevance score
|
|
263
|
-
content_lower = content.lower()
|
|
264
|
-
matches = sum(1.0 for keyword in query_keywords if keyword in content_lower)
|
|
265
|
-
score = matches / len(query_keywords) if query_keywords else 0.0
|
|
266
|
-
|
|
267
|
-
return KnowledgeChunk(
|
|
268
|
-
content=content,
|
|
269
|
-
source_file=file_path,
|
|
270
|
-
line_start=actual_start + 1, # 1-indexed
|
|
271
|
-
line_end=actual_end,
|
|
272
|
-
score=score,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
def get_context(self, query: str, max_length: int = 2000) -> str:
|
|
276
|
-
"""
|
|
277
|
-
Get formatted context string for a query with deduplication and prioritization.
|
|
278
|
-
|
|
279
|
-
Args:
|
|
280
|
-
query: Search query
|
|
281
|
-
max_length: Maximum character length of context
|
|
282
|
-
|
|
283
|
-
Returns:
|
|
284
|
-
Formatted context string with sources
|
|
285
|
-
"""
|
|
286
|
-
chunks = self.search(query, max_results=10) # Get more chunks for better selection
|
|
287
|
-
|
|
288
|
-
if not chunks:
|
|
289
|
-
return "No relevant knowledge found in knowledge base."
|
|
290
|
-
|
|
291
|
-
# Deduplicate: Remove chunks with very similar content
|
|
292
|
-
unique_chunks = self._deduplicate_chunks(chunks)
|
|
293
|
-
|
|
294
|
-
# Prioritize: Sort by score, then by source file importance
|
|
295
|
-
prioritized_chunks = self._prioritize_chunks(unique_chunks)
|
|
296
|
-
|
|
297
|
-
context_parts = []
|
|
298
|
-
current_length = 0
|
|
299
|
-
seen_sources = set()
|
|
300
|
-
|
|
301
|
-
for chunk in prioritized_chunks:
|
|
302
|
-
# Skip if we've seen this source file (avoid redundancy)
|
|
303
|
-
source_key = str(chunk.source_file)
|
|
304
|
-
if source_key in seen_sources:
|
|
305
|
-
# Only allow multiple chunks from same file if they're significantly different
|
|
306
|
-
continue
|
|
307
|
-
|
|
308
|
-
chunk_text = f"[From: {chunk.source_file.name}] (score: {chunk.score:.2f})\n{chunk.content}\n"
|
|
309
|
-
|
|
310
|
-
if current_length + len(chunk_text) > max_length:
|
|
311
|
-
# Try to include partial chunk if it fits
|
|
312
|
-
remaining = max_length - current_length
|
|
313
|
-
if remaining > 200: # Only include if meaningful portion remains
|
|
314
|
-
chunk_text = chunk_text[:remaining] + "..."
|
|
315
|
-
context_parts.append(chunk_text)
|
|
316
|
-
break
|
|
317
|
-
|
|
318
|
-
context_parts.append(chunk_text)
|
|
319
|
-
current_length += len(chunk_text)
|
|
320
|
-
seen_sources.add(source_key)
|
|
321
|
-
|
|
322
|
-
if not context_parts:
|
|
323
|
-
return "No relevant knowledge found in knowledge base."
|
|
324
|
-
|
|
325
|
-
return "\n---\n".join(context_parts)
|
|
326
|
-
|
|
327
|
-
def _deduplicate_chunks(self, chunks: list[KnowledgeChunk], similarity_threshold: float = 0.8) -> list[KnowledgeChunk]:
|
|
328
|
-
"""
|
|
329
|
-
Remove duplicate or very similar chunks.
|
|
330
|
-
|
|
331
|
-
Args:
|
|
332
|
-
chunks: List of chunks to deduplicate
|
|
333
|
-
similarity_threshold: Threshold for considering chunks similar (0.0-1.0)
|
|
334
|
-
|
|
335
|
-
Returns:
|
|
336
|
-
Deduplicated list of chunks
|
|
337
|
-
"""
|
|
338
|
-
if not chunks:
|
|
339
|
-
return chunks
|
|
340
|
-
|
|
341
|
-
unique_chunks: list[KnowledgeChunk] = [chunks[0]]
|
|
342
|
-
|
|
343
|
-
for chunk in chunks[1:]:
|
|
344
|
-
is_duplicate = False
|
|
345
|
-
chunk_content = chunk.content.lower().strip()
|
|
346
|
-
|
|
347
|
-
for existing_chunk in unique_chunks:
|
|
348
|
-
existing_content = existing_chunk.content.lower().strip()
|
|
349
|
-
|
|
350
|
-
# Simple similarity check: check if one content is mostly contained in the other
|
|
351
|
-
if len(chunk_content) > 0 and len(existing_content) > 0:
|
|
352
|
-
if chunk_content in existing_content or existing_content in chunk_content:
|
|
353
|
-
is_duplicate = True
|
|
354
|
-
break
|
|
355
|
-
# Check word overlap (simple Jaccard similarity)
|
|
356
|
-
chunk_words = set(chunk_content.split())
|
|
357
|
-
existing_words = set(existing_content.split())
|
|
358
|
-
if chunk_words and existing_words:
|
|
359
|
-
overlap = len(chunk_words & existing_words)
|
|
360
|
-
union = len(chunk_words | existing_words)
|
|
361
|
-
similarity = overlap / union if union > 0 else 0.0
|
|
362
|
-
if similarity > similarity_threshold:
|
|
363
|
-
is_duplicate = True
|
|
364
|
-
break
|
|
365
|
-
|
|
366
|
-
if not is_duplicate:
|
|
367
|
-
unique_chunks.append(chunk)
|
|
368
|
-
|
|
369
|
-
return unique_chunks
|
|
370
|
-
|
|
371
|
-
def _prioritize_chunks(self, chunks: list[KnowledgeChunk]) -> list[KnowledgeChunk]:
|
|
372
|
-
"""
|
|
373
|
-
Prioritize chunks by score and source importance.
|
|
374
|
-
|
|
375
|
-
Args:
|
|
376
|
-
chunks: List of chunks to prioritize
|
|
377
|
-
|
|
378
|
-
Returns:
|
|
379
|
-
Prioritized list of chunks (sorted by importance)
|
|
380
|
-
"""
|
|
381
|
-
# Sort by score (already done in search), but also consider:
|
|
382
|
-
# - Chunks from files with better names (containing keywords)
|
|
383
|
-
# - Higher-scoring chunks first
|
|
384
|
-
# - Shorter chunks (more focused) get slight boost
|
|
385
|
-
|
|
386
|
-
def priority_key(chunk: KnowledgeChunk) -> tuple:
|
|
387
|
-
# Primary: score (higher is better, so negate)
|
|
388
|
-
# Secondary: prefer shorter, focused chunks (but not too short)
|
|
389
|
-
content_length = len(chunk.content)
|
|
390
|
-
length_score = 1.0 / max(content_length / 500, 1.0) # Prefer 200-500 char chunks
|
|
391
|
-
|
|
392
|
-
return (-chunk.score, -length_score)
|
|
393
|
-
|
|
394
|
-
return sorted(chunks, key=priority_key)
|
|
395
|
-
|
|
396
|
-
def get_sources(self, query: str, max_results: int = 5) -> list[str]:
|
|
397
|
-
"""
|
|
398
|
-
Get source file paths for a query.
|
|
399
|
-
|
|
400
|
-
Args:
|
|
401
|
-
query: Search query
|
|
402
|
-
max_results: Maximum number of sources to return
|
|
403
|
-
|
|
404
|
-
Returns:
|
|
405
|
-
List of source file paths (relative to knowledge_dir)
|
|
406
|
-
"""
|
|
407
|
-
chunks = self.search(query, max_results=max_results)
|
|
408
|
-
|
|
409
|
-
# Get unique source files
|
|
410
|
-
sources = set()
|
|
411
|
-
for chunk in chunks:
|
|
412
|
-
# Return relative path from knowledge_dir
|
|
413
|
-
try:
|
|
414
|
-
rel_path = chunk.source_file.relative_to(self.knowledge_dir)
|
|
415
|
-
sources.add(str(rel_path))
|
|
416
|
-
except ValueError:
|
|
417
|
-
# File not in knowledge_dir, use absolute path
|
|
418
|
-
sources.add(str(chunk.source_file))
|
|
419
|
-
|
|
420
|
-
return list(sources)
|
|
421
|
-
|
|
422
|
-
def list_all_files(self) -> list[str]:
|
|
423
|
-
"""List all knowledge files in the knowledge base."""
|
|
424
|
-
return [
|
|
425
|
-
(
|
|
426
|
-
str(f.relative_to(self.knowledge_dir))
|
|
427
|
-
if self.knowledge_dir in f.parents
|
|
428
|
-
else str(f)
|
|
429
|
-
)
|
|
430
|
-
for f in self.files.keys()
|
|
431
|
-
]
|
|
1
|
+
"""
|
|
2
|
+
Simple File-Based RAG System for Industry Experts
|
|
3
|
+
|
|
4
|
+
Provides knowledge retrieval from markdown files in a knowledge/ directory
|
|
5
|
+
using keyword search and context extraction. No vector DB required.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
import re
|
|
10
|
+
from dataclasses import dataclass
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class KnowledgeChunk:
|
|
18
|
+
"""A chunk of knowledge from a knowledge base file."""
|
|
19
|
+
|
|
20
|
+
content: str
|
|
21
|
+
source_file: Path
|
|
22
|
+
line_start: int
|
|
23
|
+
line_end: int
|
|
24
|
+
score: float = 0.0 # Relevance score (0.0-1.0)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class SimpleKnowledgeBase:
|
|
28
|
+
"""
|
|
29
|
+
Simple file-based knowledge base for RAG.
|
|
30
|
+
|
|
31
|
+
Features:
|
|
32
|
+
- Keyword search in markdown files
|
|
33
|
+
- Context extraction around matches
|
|
34
|
+
- File-based storage (no vector DB)
|
|
35
|
+
- Markdown-aware chunking
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, knowledge_dir: Path, domain: str | None = None):
|
|
39
|
+
"""
|
|
40
|
+
Initialize knowledge base.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
knowledge_dir: Directory containing knowledge files (markdown)
|
|
44
|
+
domain: Optional domain filter (only load files matching domain)
|
|
45
|
+
"""
|
|
46
|
+
self.knowledge_dir = Path(knowledge_dir)
|
|
47
|
+
self.domain = domain
|
|
48
|
+
self.files: dict[Path, str] = {} # Cache of loaded files
|
|
49
|
+
self._load_knowledge_files()
|
|
50
|
+
|
|
51
|
+
def _load_knowledge_files(self):
|
|
52
|
+
"""Load all markdown files from knowledge directory."""
|
|
53
|
+
if not self.knowledge_dir.exists():
|
|
54
|
+
return # No knowledge base directory
|
|
55
|
+
|
|
56
|
+
# Load .md files
|
|
57
|
+
for md_file in self.knowledge_dir.rglob("*.md"):
|
|
58
|
+
# Filter by domain if specified
|
|
59
|
+
if self.domain:
|
|
60
|
+
# Check if file path or name contains domain
|
|
61
|
+
if (
|
|
62
|
+
self.domain.lower() not in md_file.stem.lower()
|
|
63
|
+
and self.domain.lower() not in str(md_file).lower()
|
|
64
|
+
):
|
|
65
|
+
continue
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
content = md_file.read_text(encoding="utf-8")
|
|
69
|
+
self.files[md_file] = content
|
|
70
|
+
except Exception:
|
|
71
|
+
# Skip files that can't be read
|
|
72
|
+
logger.debug("Failed to read knowledge file %s", md_file, exc_info=True)
|
|
73
|
+
continue # nosec B112 - best-effort load
|
|
74
|
+
|
|
75
|
+
def _normalize_query(self, query: str) -> set[str]:
|
|
76
|
+
"""
|
|
77
|
+
Normalize query by removing stop words, stemming, and extracting keywords.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
query: Raw query string
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
Set of normalized keywords
|
|
84
|
+
"""
|
|
85
|
+
# Common stop words (technical domain focused)
|
|
86
|
+
stop_words = {
|
|
87
|
+
"the", "a", "an", "and", "or", "but", "in", "on", "at", "to", "for",
|
|
88
|
+
"of", "with", "by", "from", "as", "is", "was", "are", "were", "be",
|
|
89
|
+
"been", "have", "has", "had", "do", "does", "did", "will", "would",
|
|
90
|
+
"should", "could", "may", "might", "must", "can", "this", "that",
|
|
91
|
+
"these", "those", "i", "you", "he", "she", "it", "we", "they",
|
|
92
|
+
"what", "how", "why", "when", "where", "which", "who"
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# Normalize: lowercase, remove punctuation, split
|
|
96
|
+
query_lower = query.lower()
|
|
97
|
+
# Remove punctuation except hyphens (for compound terms)
|
|
98
|
+
query_clean = re.sub(r'[^\w\s-]', ' ', query_lower)
|
|
99
|
+
words = query_clean.split()
|
|
100
|
+
|
|
101
|
+
# Filter: remove stop words and short words
|
|
102
|
+
keywords = {
|
|
103
|
+
word.lower() for word in words
|
|
104
|
+
if len(word) > 2 and word.lower() not in stop_words
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return keywords
|
|
108
|
+
|
|
109
|
+
def search(
|
|
110
|
+
self, query: str, max_results: int = 5, context_lines: int = 10
|
|
111
|
+
) -> list[KnowledgeChunk]:
|
|
112
|
+
"""
|
|
113
|
+
Search knowledge base for relevant chunks.
|
|
114
|
+
|
|
115
|
+
Args:
|
|
116
|
+
query: Search query (keywords)
|
|
117
|
+
max_results: Maximum number of chunks to return
|
|
118
|
+
context_lines: Number of lines of context around matches
|
|
119
|
+
|
|
120
|
+
Returns:
|
|
121
|
+
List of KnowledgeChunk objects sorted by relevance
|
|
122
|
+
"""
|
|
123
|
+
query_keywords = self._normalize_query(query)
|
|
124
|
+
|
|
125
|
+
chunks: list[KnowledgeChunk] = []
|
|
126
|
+
|
|
127
|
+
for file_path, content in self.files.items():
|
|
128
|
+
file_chunks = self._extract_relevant_chunks(
|
|
129
|
+
file_path, content, query_keywords, context_lines
|
|
130
|
+
)
|
|
131
|
+
chunks.extend(file_chunks)
|
|
132
|
+
|
|
133
|
+
# Sort by score (highest first)
|
|
134
|
+
chunks.sort(key=lambda c: c.score, reverse=True)
|
|
135
|
+
|
|
136
|
+
# Return top results
|
|
137
|
+
return chunks[:max_results]
|
|
138
|
+
|
|
139
|
+
def _extract_relevant_chunks(
|
|
140
|
+
self, file_path: Path, content: str, query_keywords: set, context_lines: int
|
|
141
|
+
) -> list[KnowledgeChunk]:
|
|
142
|
+
"""
|
|
143
|
+
Extract relevant chunks from a file based on keyword matches.
|
|
144
|
+
|
|
145
|
+
Uses markdown-aware chunking (respects headers, paragraphs).
|
|
146
|
+
"""
|
|
147
|
+
lines = content.split("\n")
|
|
148
|
+
chunks: list[KnowledgeChunk] = []
|
|
149
|
+
|
|
150
|
+
# Score each line by keyword matches with improved scoring
|
|
151
|
+
line_scores: dict[int, float] = {}
|
|
152
|
+
for i, line in enumerate(lines):
|
|
153
|
+
line_lower = line.lower()
|
|
154
|
+
|
|
155
|
+
# Base score: count keyword matches
|
|
156
|
+
base_score = sum(1.0 for keyword in query_keywords if keyword in line_lower)
|
|
157
|
+
|
|
158
|
+
# Boost for exact phrase matches (consecutive keywords)
|
|
159
|
+
if len(query_keywords) > 1:
|
|
160
|
+
query_phrase = " ".join(sorted(query_keywords))
|
|
161
|
+
if query_phrase in line_lower or any(
|
|
162
|
+
keyword1 in line_lower and keyword2 in line_lower
|
|
163
|
+
for keyword1 in query_keywords
|
|
164
|
+
for keyword2 in query_keywords
|
|
165
|
+
if keyword1 != keyword2
|
|
166
|
+
):
|
|
167
|
+
base_score *= 1.3
|
|
168
|
+
|
|
169
|
+
# Boost score for headers (marked by #)
|
|
170
|
+
header_boost = 1.0
|
|
171
|
+
if line.strip().startswith("#"):
|
|
172
|
+
# H1 gets highest boost, H2 less, etc.
|
|
173
|
+
header_level = len(line) - len(line.lstrip("#"))
|
|
174
|
+
header_boost = 2.0 - (header_level * 0.2)
|
|
175
|
+
|
|
176
|
+
# Boost for code blocks (examples are valuable)
|
|
177
|
+
if line.strip().startswith("```"):
|
|
178
|
+
base_score *= 1.4
|
|
179
|
+
|
|
180
|
+
# Boost for lines with lists (structured information)
|
|
181
|
+
if line.strip().startswith("- ") or line.strip().startswith("* "):
|
|
182
|
+
base_score *= 1.2
|
|
183
|
+
|
|
184
|
+
score = base_score * header_boost
|
|
185
|
+
|
|
186
|
+
if score > 0:
|
|
187
|
+
line_scores[i] = score
|
|
188
|
+
|
|
189
|
+
if not line_scores:
|
|
190
|
+
return chunks # No matches
|
|
191
|
+
|
|
192
|
+
# Group consecutive high-scoring lines into chunks
|
|
193
|
+
current_chunk_start: int | None = None
|
|
194
|
+
current_chunk_lines: list[int] = []
|
|
195
|
+
|
|
196
|
+
for i in sorted(line_scores.keys()):
|
|
197
|
+
if current_chunk_start is None:
|
|
198
|
+
current_chunk_start = i
|
|
199
|
+
current_chunk_lines = [i]
|
|
200
|
+
elif i - current_chunk_lines[-1] <= context_lines:
|
|
201
|
+
# Within context distance, add to current chunk
|
|
202
|
+
current_chunk_lines.append(i)
|
|
203
|
+
else:
|
|
204
|
+
# New chunk needed
|
|
205
|
+
if current_chunk_start is not None:
|
|
206
|
+
chunk = self._create_chunk_from_lines(
|
|
207
|
+
file_path,
|
|
208
|
+
lines,
|
|
209
|
+
current_chunk_start,
|
|
210
|
+
current_chunk_lines[-1],
|
|
211
|
+
context_lines,
|
|
212
|
+
query_keywords,
|
|
213
|
+
)
|
|
214
|
+
if chunk:
|
|
215
|
+
chunks.append(chunk)
|
|
216
|
+
|
|
217
|
+
current_chunk_start = i
|
|
218
|
+
current_chunk_lines = [i]
|
|
219
|
+
|
|
220
|
+
# Add final chunk
|
|
221
|
+
if current_chunk_start is not None:
|
|
222
|
+
chunk = self._create_chunk_from_lines(
|
|
223
|
+
file_path,
|
|
224
|
+
lines,
|
|
225
|
+
current_chunk_start,
|
|
226
|
+
current_chunk_lines[-1],
|
|
227
|
+
context_lines,
|
|
228
|
+
query_keywords,
|
|
229
|
+
)
|
|
230
|
+
if chunk:
|
|
231
|
+
chunks.append(chunk)
|
|
232
|
+
|
|
233
|
+
return chunks
|
|
234
|
+
|
|
235
|
+
def _create_chunk_from_lines(
|
|
236
|
+
self,
|
|
237
|
+
file_path: Path,
|
|
238
|
+
lines: list[str],
|
|
239
|
+
start_line: int,
|
|
240
|
+
end_line: int,
|
|
241
|
+
context_lines: int,
|
|
242
|
+
query_keywords: set,
|
|
243
|
+
) -> KnowledgeChunk | None:
|
|
244
|
+
"""Create a KnowledgeChunk from line range with context."""
|
|
245
|
+
# Expand range with context
|
|
246
|
+
actual_start = max(0, start_line - context_lines)
|
|
247
|
+
actual_end = min(len(lines), end_line + context_lines)
|
|
248
|
+
|
|
249
|
+
# Try to align to markdown boundaries (headers)
|
|
250
|
+
for i in range(actual_start, start_line):
|
|
251
|
+
if lines[i].strip().startswith("#"):
|
|
252
|
+
actual_start = i
|
|
253
|
+
break
|
|
254
|
+
|
|
255
|
+
# Extract chunk content
|
|
256
|
+
chunk_lines = lines[actual_start:actual_end]
|
|
257
|
+
content = "\n".join(chunk_lines).strip()
|
|
258
|
+
|
|
259
|
+
if not content:
|
|
260
|
+
return None
|
|
261
|
+
|
|
262
|
+
# Calculate relevance score
|
|
263
|
+
content_lower = content.lower()
|
|
264
|
+
matches = sum(1.0 for keyword in query_keywords if keyword in content_lower)
|
|
265
|
+
score = matches / len(query_keywords) if query_keywords else 0.0
|
|
266
|
+
|
|
267
|
+
return KnowledgeChunk(
|
|
268
|
+
content=content,
|
|
269
|
+
source_file=file_path,
|
|
270
|
+
line_start=actual_start + 1, # 1-indexed
|
|
271
|
+
line_end=actual_end,
|
|
272
|
+
score=score,
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
def get_context(self, query: str, max_length: int = 2000) -> str:
|
|
276
|
+
"""
|
|
277
|
+
Get formatted context string for a query with deduplication and prioritization.
|
|
278
|
+
|
|
279
|
+
Args:
|
|
280
|
+
query: Search query
|
|
281
|
+
max_length: Maximum character length of context
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
Formatted context string with sources
|
|
285
|
+
"""
|
|
286
|
+
chunks = self.search(query, max_results=10) # Get more chunks for better selection
|
|
287
|
+
|
|
288
|
+
if not chunks:
|
|
289
|
+
return "No relevant knowledge found in knowledge base."
|
|
290
|
+
|
|
291
|
+
# Deduplicate: Remove chunks with very similar content
|
|
292
|
+
unique_chunks = self._deduplicate_chunks(chunks)
|
|
293
|
+
|
|
294
|
+
# Prioritize: Sort by score, then by source file importance
|
|
295
|
+
prioritized_chunks = self._prioritize_chunks(unique_chunks)
|
|
296
|
+
|
|
297
|
+
context_parts = []
|
|
298
|
+
current_length = 0
|
|
299
|
+
seen_sources = set()
|
|
300
|
+
|
|
301
|
+
for chunk in prioritized_chunks:
|
|
302
|
+
# Skip if we've seen this source file (avoid redundancy)
|
|
303
|
+
source_key = str(chunk.source_file)
|
|
304
|
+
if source_key in seen_sources:
|
|
305
|
+
# Only allow multiple chunks from same file if they're significantly different
|
|
306
|
+
continue
|
|
307
|
+
|
|
308
|
+
chunk_text = f"[From: {chunk.source_file.name}] (score: {chunk.score:.2f})\n{chunk.content}\n"
|
|
309
|
+
|
|
310
|
+
if current_length + len(chunk_text) > max_length:
|
|
311
|
+
# Try to include partial chunk if it fits
|
|
312
|
+
remaining = max_length - current_length
|
|
313
|
+
if remaining > 200: # Only include if meaningful portion remains
|
|
314
|
+
chunk_text = chunk_text[:remaining] + "..."
|
|
315
|
+
context_parts.append(chunk_text)
|
|
316
|
+
break
|
|
317
|
+
|
|
318
|
+
context_parts.append(chunk_text)
|
|
319
|
+
current_length += len(chunk_text)
|
|
320
|
+
seen_sources.add(source_key)
|
|
321
|
+
|
|
322
|
+
if not context_parts:
|
|
323
|
+
return "No relevant knowledge found in knowledge base."
|
|
324
|
+
|
|
325
|
+
return "\n---\n".join(context_parts)
|
|
326
|
+
|
|
327
|
+
def _deduplicate_chunks(self, chunks: list[KnowledgeChunk], similarity_threshold: float = 0.8) -> list[KnowledgeChunk]:
|
|
328
|
+
"""
|
|
329
|
+
Remove duplicate or very similar chunks.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
chunks: List of chunks to deduplicate
|
|
333
|
+
similarity_threshold: Threshold for considering chunks similar (0.0-1.0)
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
Deduplicated list of chunks
|
|
337
|
+
"""
|
|
338
|
+
if not chunks:
|
|
339
|
+
return chunks
|
|
340
|
+
|
|
341
|
+
unique_chunks: list[KnowledgeChunk] = [chunks[0]]
|
|
342
|
+
|
|
343
|
+
for chunk in chunks[1:]:
|
|
344
|
+
is_duplicate = False
|
|
345
|
+
chunk_content = chunk.content.lower().strip()
|
|
346
|
+
|
|
347
|
+
for existing_chunk in unique_chunks:
|
|
348
|
+
existing_content = existing_chunk.content.lower().strip()
|
|
349
|
+
|
|
350
|
+
# Simple similarity check: check if one content is mostly contained in the other
|
|
351
|
+
if len(chunk_content) > 0 and len(existing_content) > 0:
|
|
352
|
+
if chunk_content in existing_content or existing_content in chunk_content:
|
|
353
|
+
is_duplicate = True
|
|
354
|
+
break
|
|
355
|
+
# Check word overlap (simple Jaccard similarity)
|
|
356
|
+
chunk_words = set(chunk_content.split())
|
|
357
|
+
existing_words = set(existing_content.split())
|
|
358
|
+
if chunk_words and existing_words:
|
|
359
|
+
overlap = len(chunk_words & existing_words)
|
|
360
|
+
union = len(chunk_words | existing_words)
|
|
361
|
+
similarity = overlap / union if union > 0 else 0.0
|
|
362
|
+
if similarity > similarity_threshold:
|
|
363
|
+
is_duplicate = True
|
|
364
|
+
break
|
|
365
|
+
|
|
366
|
+
if not is_duplicate:
|
|
367
|
+
unique_chunks.append(chunk)
|
|
368
|
+
|
|
369
|
+
return unique_chunks
|
|
370
|
+
|
|
371
|
+
def _prioritize_chunks(self, chunks: list[KnowledgeChunk]) -> list[KnowledgeChunk]:
|
|
372
|
+
"""
|
|
373
|
+
Prioritize chunks by score and source importance.
|
|
374
|
+
|
|
375
|
+
Args:
|
|
376
|
+
chunks: List of chunks to prioritize
|
|
377
|
+
|
|
378
|
+
Returns:
|
|
379
|
+
Prioritized list of chunks (sorted by importance)
|
|
380
|
+
"""
|
|
381
|
+
# Sort by score (already done in search), but also consider:
|
|
382
|
+
# - Chunks from files with better names (containing keywords)
|
|
383
|
+
# - Higher-scoring chunks first
|
|
384
|
+
# - Shorter chunks (more focused) get slight boost
|
|
385
|
+
|
|
386
|
+
def priority_key(chunk: KnowledgeChunk) -> tuple:
|
|
387
|
+
# Primary: score (higher is better, so negate)
|
|
388
|
+
# Secondary: prefer shorter, focused chunks (but not too short)
|
|
389
|
+
content_length = len(chunk.content)
|
|
390
|
+
length_score = 1.0 / max(content_length / 500, 1.0) # Prefer 200-500 char chunks
|
|
391
|
+
|
|
392
|
+
return (-chunk.score, -length_score)
|
|
393
|
+
|
|
394
|
+
return sorted(chunks, key=priority_key)
|
|
395
|
+
|
|
396
|
+
def get_sources(self, query: str, max_results: int = 5) -> list[str]:
|
|
397
|
+
"""
|
|
398
|
+
Get source file paths for a query.
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
query: Search query
|
|
402
|
+
max_results: Maximum number of sources to return
|
|
403
|
+
|
|
404
|
+
Returns:
|
|
405
|
+
List of source file paths (relative to knowledge_dir)
|
|
406
|
+
"""
|
|
407
|
+
chunks = self.search(query, max_results=max_results)
|
|
408
|
+
|
|
409
|
+
# Get unique source files
|
|
410
|
+
sources = set()
|
|
411
|
+
for chunk in chunks:
|
|
412
|
+
# Return relative path from knowledge_dir
|
|
413
|
+
try:
|
|
414
|
+
rel_path = chunk.source_file.relative_to(self.knowledge_dir)
|
|
415
|
+
sources.add(str(rel_path))
|
|
416
|
+
except ValueError:
|
|
417
|
+
# File not in knowledge_dir, use absolute path
|
|
418
|
+
sources.add(str(chunk.source_file))
|
|
419
|
+
|
|
420
|
+
return list(sources)
|
|
421
|
+
|
|
422
|
+
def list_all_files(self) -> list[str]:
|
|
423
|
+
"""List all knowledge files in the knowledge base."""
|
|
424
|
+
return [
|
|
425
|
+
(
|
|
426
|
+
str(f.relative_to(self.knowledge_dir))
|
|
427
|
+
if self.knowledge_dir in f.parents
|
|
428
|
+
else str(f)
|
|
429
|
+
)
|
|
430
|
+
for f in self.files.keys()
|
|
431
|
+
]
|