moai-adk 0.25.4__py3-none-any.whl → 0.32.8__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.
Potentially problematic release.
This version of moai-adk might be problematic. Click here for more details.
- moai_adk/__init__.py +2 -5
- moai_adk/__main__.py +114 -82
- moai_adk/cli/__init__.py +6 -1
- moai_adk/cli/commands/__init__.py +1 -3
- moai_adk/cli/commands/analyze.py +5 -16
- moai_adk/cli/commands/doctor.py +6 -18
- moai_adk/cli/commands/init.py +56 -125
- moai_adk/cli/commands/language.py +14 -35
- moai_adk/cli/commands/status.py +9 -15
- moai_adk/cli/commands/update.py +1555 -190
- moai_adk/cli/prompts/init_prompts.py +112 -56
- moai_adk/cli/spec_status.py +263 -0
- moai_adk/cli/ui/__init__.py +44 -0
- moai_adk/cli/ui/progress.py +422 -0
- moai_adk/cli/ui/prompts.py +389 -0
- moai_adk/cli/ui/theme.py +129 -0
- moai_adk/cli/worktree/__init__.py +27 -0
- moai_adk/cli/worktree/__main__.py +31 -0
- moai_adk/cli/worktree/cli.py +672 -0
- moai_adk/cli/worktree/exceptions.py +89 -0
- moai_adk/cli/worktree/manager.py +490 -0
- moai_adk/cli/worktree/models.py +65 -0
- moai_adk/cli/worktree/registry.py +128 -0
- moai_adk/core/PHASE2_OPTIMIZATIONS.md +467 -0
- moai_adk/core/analysis/session_analyzer.py +17 -56
- moai_adk/core/claude_integration.py +26 -54
- moai_adk/core/command_helpers.py +10 -10
- moai_adk/core/comprehensive_monitoring_system.py +1183 -0
- moai_adk/core/config/auto_spec_config.py +5 -11
- moai_adk/core/config/migration.py +19 -9
- moai_adk/core/config/unified.py +436 -0
- moai_adk/core/context_manager.py +6 -12
- moai_adk/core/enterprise_features.py +1404 -0
- moai_adk/core/error_recovery_system.py +725 -112
- moai_adk/core/event_driven_hook_system.py +1371 -0
- moai_adk/core/git/__init__.py +8 -0
- moai_adk/core/git/branch_manager.py +3 -11
- moai_adk/core/git/checkpoint.py +1 -3
- moai_adk/core/git/conflict_detector.py +413 -0
- moai_adk/core/git/manager.py +91 -1
- moai_adk/core/hooks/post_tool_auto_spec_completion.py +56 -80
- moai_adk/core/input_validation_middleware.py +1006 -0
- moai_adk/core/integration/engine.py +6 -18
- moai_adk/core/integration/integration_tester.py +10 -9
- moai_adk/core/integration/utils.py +1 -1
- moai_adk/core/issue_creator.py +10 -28
- moai_adk/core/jit_context_loader.py +956 -0
- moai_adk/core/jit_enhanced_hook_manager.py +1987 -0
- moai_adk/core/language_config_resolver.py +485 -0
- moai_adk/core/language_validator.py +28 -41
- moai_adk/core/mcp/setup.py +15 -12
- moai_adk/core/merge/__init__.py +9 -0
- moai_adk/core/merge/analyzer.py +481 -0
- moai_adk/core/migration/alfred_to_moai_migrator.py +383 -0
- moai_adk/core/migration/backup_manager.py +78 -9
- moai_adk/core/migration/custom_element_scanner.py +358 -0
- moai_adk/core/migration/file_migrator.py +8 -17
- moai_adk/core/migration/interactive_checkbox_ui.py +488 -0
- moai_adk/core/migration/selective_restorer.py +470 -0
- moai_adk/core/migration/template_utils.py +74 -0
- moai_adk/core/migration/user_selection_ui.py +338 -0
- moai_adk/core/migration/version_detector.py +6 -10
- moai_adk/core/migration/version_migrator.py +3 -3
- moai_adk/core/performance/cache_system.py +8 -10
- moai_adk/core/phase_optimized_hook_scheduler.py +879 -0
- moai_adk/core/project/checker.py +2 -4
- moai_adk/core/project/detector.py +1 -3
- moai_adk/core/project/initializer.py +135 -23
- moai_adk/core/project/phase_executor.py +54 -81
- moai_adk/core/project/validator.py +6 -12
- moai_adk/core/quality/trust_checker.py +9 -27
- moai_adk/core/realtime_monitoring_dashboard.py +1724 -0
- moai_adk/core/robust_json_parser.py +611 -0
- moai_adk/core/rollback_manager.py +73 -148
- moai_adk/core/session_manager.py +10 -26
- moai_adk/core/skill_loading_system.py +579 -0
- moai_adk/core/spec/confidence_scoring.py +31 -100
- moai_adk/core/spec/ears_template_engine.py +351 -286
- moai_adk/core/spec/quality_validator.py +35 -69
- moai_adk/core/spec_status_manager.py +64 -74
- moai_adk/core/template/backup.py +45 -20
- moai_adk/core/template/config.py +112 -39
- moai_adk/core/template/merger.py +11 -19
- moai_adk/core/template/processor.py +253 -149
- moai_adk/core/template_engine.py +73 -40
- moai_adk/core/template_variable_synchronizer.py +417 -0
- moai_adk/core/unified_permission_manager.py +745 -0
- moai_adk/core/user_behavior_analytics.py +851 -0
- moai_adk/core/version_sync.py +429 -0
- moai_adk/foundation/__init__.py +56 -0
- moai_adk/foundation/backend.py +1027 -0
- moai_adk/foundation/database.py +1115 -0
- moai_adk/foundation/devops.py +1585 -0
- moai_adk/foundation/ears.py +431 -0
- moai_adk/foundation/frontend.py +870 -0
- moai_adk/foundation/git/commit_templates.py +4 -12
- moai_adk/foundation/git.py +376 -0
- moai_adk/foundation/langs.py +484 -0
- moai_adk/foundation/ml_ops.py +1162 -0
- moai_adk/foundation/testing.py +1524 -0
- moai_adk/foundation/trust/trust_principles.py +23 -72
- moai_adk/foundation/trust/validation_checklist.py +57 -162
- moai_adk/project/__init__.py +0 -0
- moai_adk/project/configuration.py +1084 -0
- moai_adk/project/documentation.py +566 -0
- moai_adk/project/schema.py +447 -0
- moai_adk/statusline/alfred_detector.py +1 -3
- moai_adk/statusline/config.py +13 -4
- moai_adk/statusline/enhanced_output_style_detector.py +23 -15
- moai_adk/statusline/main.py +51 -15
- moai_adk/statusline/renderer.py +104 -48
- moai_adk/statusline/update_checker.py +3 -9
- moai_adk/statusline/version_reader.py +140 -46
- moai_adk/templates/.claude/agents/moai/ai-nano-banana.md +549 -0
- moai_adk/templates/.claude/agents/moai/builder-agent.md +445 -0
- moai_adk/templates/.claude/agents/moai/builder-command.md +1132 -0
- moai_adk/templates/.claude/agents/moai/builder-skill.md +601 -0
- moai_adk/templates/.claude/agents/moai/expert-backend.md +831 -0
- moai_adk/templates/.claude/agents/moai/expert-database.md +774 -0
- moai_adk/templates/.claude/agents/moai/expert-debug.md +396 -0
- moai_adk/templates/.claude/agents/moai/expert-devops.md +711 -0
- moai_adk/templates/.claude/agents/moai/expert-frontend.md +666 -0
- moai_adk/templates/.claude/agents/moai/expert-security.md +474 -0
- moai_adk/templates/.claude/agents/moai/expert-uiux.md +1038 -0
- moai_adk/templates/.claude/agents/moai/manager-claude-code.md +429 -0
- moai_adk/templates/.claude/agents/moai/manager-docs.md +570 -0
- moai_adk/templates/.claude/agents/moai/manager-git.md +937 -0
- moai_adk/templates/.claude/agents/moai/manager-project.md +891 -0
- moai_adk/templates/.claude/agents/moai/manager-quality.md +598 -0
- moai_adk/templates/.claude/agents/moai/manager-spec.md +713 -0
- moai_adk/templates/.claude/agents/moai/manager-strategy.md +600 -0
- moai_adk/templates/.claude/agents/moai/manager-tdd.md +603 -0
- moai_adk/templates/.claude/agents/moai/mcp-context7.md +369 -0
- moai_adk/templates/.claude/agents/moai/mcp-figma.md +1567 -0
- moai_adk/templates/.claude/agents/moai/mcp-notion.md +749 -0
- moai_adk/templates/.claude/agents/moai/mcp-playwright.md +427 -0
- moai_adk/templates/.claude/agents/moai/mcp-sequential-thinking.md +994 -0
- moai_adk/templates/.claude/commands/moai/0-project.md +1143 -0
- moai_adk/templates/.claude/commands/moai/1-plan.md +1435 -0
- moai_adk/templates/.claude/commands/moai/2-run.md +883 -0
- moai_adk/templates/.claude/commands/moai/3-sync.md +993 -0
- moai_adk/templates/.claude/commands/moai/9-feedback.md +314 -0
- moai_adk/templates/.claude/hooks/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/__init__.py +8 -0
- moai_adk/templates/.claude/hooks/moai/lib/__init__.py +85 -0
- moai_adk/templates/.claude/hooks/moai/lib/checkpoint.py +244 -0
- moai_adk/templates/.claude/hooks/moai/lib/common.py +131 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_manager.py +446 -0
- moai_adk/templates/.claude/hooks/moai/lib/config_validator.py +639 -0
- moai_adk/templates/.claude/hooks/moai/lib/example_config.json +104 -0
- moai_adk/templates/.claude/hooks/moai/lib/git_operations_manager.py +590 -0
- moai_adk/templates/.claude/hooks/moai/lib/language_validator.py +317 -0
- moai_adk/templates/.claude/hooks/moai/lib/models.py +102 -0
- moai_adk/templates/.claude/hooks/moai/lib/path_utils.py +28 -0
- moai_adk/templates/.claude/hooks/moai/lib/project.py +768 -0
- moai_adk/templates/.claude/hooks/moai/lib/test_hooks_improvements.py +443 -0
- moai_adk/templates/.claude/hooks/moai/lib/timeout.py +160 -0
- moai_adk/templates/.claude/hooks/moai/lib/unified_timeout_manager.py +530 -0
- moai_adk/templates/.claude/hooks/moai/session_end__auto_cleanup.py +862 -0
- moai_adk/templates/.claude/hooks/moai/session_start__show_project_info.py +921 -0
- moai_adk/templates/.claude/output-styles/moai/r2d2.md +380 -0
- moai_adk/templates/.claude/output-styles/moai/yoda.md +338 -0
- moai_adk/templates/.claude/settings.json +172 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/SKILL.md +247 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/README.md +44 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/api-documentation.md +130 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/code-documentation.md +152 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/multi-format-output.md +178 -0
- moai_adk/templates/.claude/skills/moai-docs-generation/modules/user-guides.md +147 -0
- moai_adk/templates/.claude/skills/moai-domain-backend/SKILL.md +319 -0
- moai_adk/templates/.claude/skills/moai-domain-database/SKILL.md +320 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/README.md +53 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/mongodb.md +231 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/postgresql.md +169 -0
- moai_adk/templates/.claude/skills/moai-domain-database/modules/redis.md +262 -0
- moai_adk/templates/.claude/skills/moai-domain-frontend/SKILL.md +496 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/SKILL.md +453 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/examples.md +560 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/accessibility-wcag.md +260 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/component-architecture.md +228 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/design-system-tokens.md +405 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/icon-libraries.md +401 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/modules/theming-system.md +373 -0
- moai_adk/templates/.claude/skills/moai-domain-uiux/reference.md +243 -0
- moai_adk/templates/.claude/skills/moai-formats-data/SKILL.md +491 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/README.md +98 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/SKILL-MODULARIZATION-TEMPLATE.md +278 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/caching-performance.md +459 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/data-validation.md +485 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/json-optimization.md +374 -0
- moai_adk/templates/.claude/skills/moai-formats-data/modules/toon-encoding.md +308 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/SKILL.md +201 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/best-practices-checklist.md +616 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-custom-slash-commands-official.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-hooks-official.md +560 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-iam-official.md +635 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-memory-official.md +543 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-settings-official.md +663 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-skills-official.md +113 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/claude-code-sub-agents-official.md +238 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/complete-configuration-guide.md +175 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-examples.md +1674 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/skill-formatting-guide.md +729 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-examples.md +1513 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-formatting-guide.md +1086 -0
- moai_adk/templates/.claude/skills/moai-foundation-claude/reference/sub-agents/sub-agent-integration-patterns.md +1100 -0
- moai_adk/templates/.claude/skills/moai-foundation-context/SKILL.md +438 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/SKILL.md +515 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/README.md +296 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/agents-reference.md +346 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/commands-reference.md +432 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/delegation-patterns.md +757 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/execution-rules.md +687 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/modular-system.md +665 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/progressive-disclosure.md +649 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/spec-first-tdd.md +864 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/token-optimization.md +708 -0
- moai_adk/templates/.claude/skills/moai-foundation-core/modules/trust-5-framework.md +981 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/SKILL.md +362 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/examples.md +1232 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/best-practices.md +261 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/integration-patterns.md +194 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/proactive-analysis.md +229 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/modules/trust5-validation.md +169 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/reference.md +1266 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/scripts/quality-gate.sh +668 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/github-actions-quality.yml +481 -0
- moai_adk/templates/.claude/skills/moai-foundation-quality/templates/quality-config.yaml +519 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/SKILL.md +352 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/README.md +52 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/error-handling.md +334 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/integration-patterns.md +310 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/security-authentication.md +256 -0
- moai_adk/templates/.claude/skills/moai-integration-mcp/modules/server-architecture.md +253 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/README.md +133 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/SKILL.md +296 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/examples.md +1269 -0
- moai_adk/templates/.claude/skills/moai-lang-unified/reference.md +331 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/SKILL.md +298 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/advanced-patterns.md +465 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/examples.md +270 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/optimization.md +440 -0
- moai_adk/templates/.claude/skills/moai-library-mermaid/reference.md +228 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/SKILL.md +316 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/advanced-patterns.md +336 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-deployment-patterns.md +182 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/advanced-patterns.md +17 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/configuration.md +57 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/content-architecture-optimization.md +162 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/deployment.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/framework-core-configuration.md +186 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/i18n-setup.md +55 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/modules/mdx-components.md +52 -0
- moai_adk/templates/.claude/skills/moai-library-nextra/optimization.md +303 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/SKILL.md +370 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/examples.md +575 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/advanced-patterns.md +394 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/optimization.md +278 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-components.md +457 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/modules/shadcn-theming.md +373 -0
- moai_adk/templates/.claude/skills/moai-library-shadcn/reference.md +74 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/README.md +186 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/SKILL.md +290 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/examples.md +1225 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/reference.md +567 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/scripts/provider-selector.py +323 -0
- moai_adk/templates/.claude/skills/moai-platform-baas/templates/stack-config.yaml +204 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/SKILL.md +446 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/advanced-patterns.md +379 -0
- moai_adk/templates/.claude/skills/moai-workflow-jit-docs/optimization.md +286 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/README.md +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/SKILL.md +387 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/__init__.py +520 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/complete_workflow_demo_fixed.py +574 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_project_setup.py +317 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/complete_workflow_demo.py +663 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/config-migration-example.json +190 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/question-examples.json +135 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/examples/quick_start.py +196 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/__init__.py +17 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/advanced-patterns.md +158 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/ask_user_integration.py +340 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/batch_questions.py +713 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/config_manager.py +538 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/documentation_manager.py +1336 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/language_initializer.py +730 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/migration_manager.py +608 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/modules/template_optimizer.py +1005 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/config-schema.json +316 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/schemas/tab_schema.json +1362 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/config-template.json +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/product-template.md +44 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/structure-template.md +48 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/doc-templates/tech-template.md +71 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/config-manager-setup.json +109 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/language-initializer.json +228 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/menu-project-config.json +130 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/project-batch-questions.json +97 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/templates/question-templates/spec-workflow-setup.json +150 -0
- moai_adk/templates/.claude/skills/moai-workflow-project/test_integration_simple.py +436 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/SKILL.md +374 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/code-templates.md +124 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/feedback-templates.md +100 -0
- moai_adk/templates/.claude/skills/moai-workflow-templates/modules/template-optimizer.md +138 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/LICENSE.txt +202 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/SKILL.md +453 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/advanced-patterns.md +576 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/ai-powered-testing.py +294 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/console_logging.py +35 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/element_discovery.py +40 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/examples/static_html_automation.py +34 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/README.md +220 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/ai-debugging.md +845 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/automated-code-review.md +1416 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/performance-optimization.md +1234 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/smart-refactoring.md +1243 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/modules/tdd-context7.md +1260 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/optimization.md +505 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/reference/playwright-best-practices.md +57 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/scripts/with_server.py +218 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/templates/alfred-integration.md +376 -0
- moai_adk/templates/.claude/skills/moai-workflow-testing/workflows/enterprise-testing-workflow.py +571 -0
- moai_adk/templates/.claude/skills/moai-worktree/SKILL.md +410 -0
- moai_adk/templates/.claude/skills/moai-worktree/examples.md +606 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/integration-patterns.md +982 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/parallel-development.md +778 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-commands.md +646 -0
- moai_adk/templates/.claude/skills/moai-worktree/modules/worktree-management.md +782 -0
- moai_adk/templates/.claude/skills/moai-worktree/reference.md +357 -0
- moai_adk/templates/.git-hooks/pre-commit +103 -41
- moai_adk/templates/.git-hooks/pre-push +116 -21
- moai_adk/templates/.github/workflows/ci-universal.yml +513 -0
- moai_adk/templates/.github/workflows/security-secrets-check.yml +179 -0
- moai_adk/templates/.gitignore +184 -44
- moai_adk/templates/.mcp.json +7 -9
- moai_adk/templates/.moai/cache/personalization.json +10 -0
- moai_adk/templates/.moai/config/config.yaml +344 -0
- moai_adk/templates/.moai/config/presets/manual.yaml +28 -0
- moai_adk/templates/.moai/config/presets/personal.yaml +30 -0
- moai_adk/templates/.moai/config/presets/team.yaml +33 -0
- moai_adk/templates/.moai/config/questions/_schema.yaml +79 -0
- moai_adk/templates/.moai/config/questions/tab1-user.yaml +108 -0
- moai_adk/templates/.moai/config/questions/tab2-project.yaml +122 -0
- moai_adk/templates/.moai/config/questions/tab3-git.yaml +542 -0
- moai_adk/templates/.moai/config/questions/tab4-quality.yaml +167 -0
- moai_adk/templates/.moai/config/questions/tab5-system.yaml +152 -0
- moai_adk/templates/.moai/config/sections/git-strategy.yaml +40 -0
- moai_adk/templates/.moai/config/sections/language.yaml +11 -0
- moai_adk/templates/.moai/config/sections/project.yaml +13 -0
- moai_adk/templates/.moai/config/sections/quality.yaml +15 -0
- moai_adk/templates/.moai/config/sections/system.yaml +14 -0
- moai_adk/templates/.moai/config/sections/user.yaml +5 -0
- moai_adk/templates/.moai/config/statusline-config.yaml +86 -0
- moai_adk/templates/.moai/scripts/setup-glm.py +136 -0
- moai_adk/templates/CLAUDE.md +382 -501
- moai_adk/utils/__init__.py +24 -1
- moai_adk/utils/banner.py +7 -10
- moai_adk/utils/common.py +16 -30
- moai_adk/utils/link_validator.py +4 -12
- moai_adk/utils/safe_file_reader.py +2 -6
- moai_adk/utils/timeout.py +160 -0
- moai_adk/utils/toon_utils.py +256 -0
- moai_adk/version.py +22 -0
- moai_adk-0.32.8.dist-info/METADATA +2478 -0
- moai_adk-0.32.8.dist-info/RECORD +396 -0
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/WHEEL +1 -1
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/entry_points.txt +1 -0
- moai_adk/cli/commands/backup.py +0 -82
- moai_adk/cli/commands/improve_user_experience.py +0 -348
- moai_adk/cli/commands/migrate.py +0 -158
- moai_adk/cli/commands/validate_links.py +0 -118
- moai_adk/templates/.github/workflows/moai-gitflow.yml +0 -413
- moai_adk/templates/.github/workflows/moai-release-create.yml +0 -100
- moai_adk/templates/.github/workflows/moai-release-pipeline.yml +0 -188
- moai_adk/utils/user_experience.py +0 -531
- moai_adk-0.25.4.dist-info/METADATA +0 -2279
- moai_adk-0.25.4.dist-info/RECORD +0 -112
- {moai_adk-0.25.4.dist-info → moai_adk-0.32.8.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,956 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
JIT Context Loading System
|
|
4
|
+
|
|
5
|
+
Phase-based token optimization system that achieves 85%+ efficiency through
|
|
6
|
+
intelligent context loading, skill filtering, and budget management.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import hashlib
|
|
10
|
+
import json
|
|
11
|
+
import logging
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import time
|
|
15
|
+
from collections import OrderedDict
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from datetime import datetime
|
|
18
|
+
from enum import Enum
|
|
19
|
+
from pathlib import Path
|
|
20
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
21
|
+
|
|
22
|
+
import psutil
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class Phase(Enum):
|
|
28
|
+
"""Development phases with different token budgets"""
|
|
29
|
+
|
|
30
|
+
SPEC = "spec" # 30K budget
|
|
31
|
+
RED = "red" # 25K budget
|
|
32
|
+
GREEN = "green" # 25K budget
|
|
33
|
+
REFACTOR = "refactor" # 20K budget
|
|
34
|
+
SYNC = "sync" # 40K budget
|
|
35
|
+
DEBUG = "debug" # 15K budget
|
|
36
|
+
PLANNING = "planning" # 35K budget
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class PhaseConfig:
|
|
41
|
+
"""Configuration for each development phase"""
|
|
42
|
+
|
|
43
|
+
max_tokens: int
|
|
44
|
+
essential_skills: List[str]
|
|
45
|
+
essential_documents: List[str]
|
|
46
|
+
cache_clear_on_phase_change: bool = False
|
|
47
|
+
context_compression: bool = True
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@dataclass
|
|
51
|
+
class ContextMetrics:
|
|
52
|
+
"""Metrics for context loading performance"""
|
|
53
|
+
|
|
54
|
+
load_time: float
|
|
55
|
+
token_count: int
|
|
56
|
+
cache_hit: bool
|
|
57
|
+
phase: str
|
|
58
|
+
skills_loaded: int
|
|
59
|
+
docs_loaded: int
|
|
60
|
+
compression_ratio: float = 1.0
|
|
61
|
+
memory_usage: int = 0
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
@dataclass
|
|
65
|
+
class SkillInfo:
|
|
66
|
+
"""Information about a skill for filtering decisions"""
|
|
67
|
+
|
|
68
|
+
name: str
|
|
69
|
+
path: str
|
|
70
|
+
size: int
|
|
71
|
+
tokens: int
|
|
72
|
+
categories: List[str]
|
|
73
|
+
dependencies: List[str] = field(default_factory=list)
|
|
74
|
+
priority: int = 1 # 1=high, 2=medium, 3=low
|
|
75
|
+
last_used: Optional[datetime] = None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass
|
|
79
|
+
class ContextEntry:
|
|
80
|
+
"""Entry in the context cache"""
|
|
81
|
+
|
|
82
|
+
key: str
|
|
83
|
+
content: Any
|
|
84
|
+
token_count: int
|
|
85
|
+
created_at: datetime
|
|
86
|
+
last_accessed: datetime
|
|
87
|
+
access_count: int = 0
|
|
88
|
+
phase: Optional[str] = None
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class PhaseDetector:
|
|
92
|
+
"""Intelligently detects current development phase from context"""
|
|
93
|
+
|
|
94
|
+
def __init__(self):
|
|
95
|
+
self.phase_patterns = {
|
|
96
|
+
Phase.SPEC: [
|
|
97
|
+
r"/moai:1-plan",
|
|
98
|
+
r"SPEC-\d+",
|
|
99
|
+
r"spec|requirements|design",
|
|
100
|
+
r"create.*spec|define.*requirements",
|
|
101
|
+
r"plan.*feature|design.*system",
|
|
102
|
+
],
|
|
103
|
+
Phase.RED: [
|
|
104
|
+
r"/moai:2-run.*RED",
|
|
105
|
+
r"test.*fail|failing.*test",
|
|
106
|
+
r"red.*phase|tdd.*red",
|
|
107
|
+
r"2-run.*RED|write.*test",
|
|
108
|
+
r"create.*test.*failure",
|
|
109
|
+
],
|
|
110
|
+
Phase.GREEN: [
|
|
111
|
+
r"/moai:2-run.*GREEN",
|
|
112
|
+
r"test.*pass|passing.*test",
|
|
113
|
+
r"green.*phase|tdd.*green",
|
|
114
|
+
r"2-run.*GREEN|minimal.*implementation",
|
|
115
|
+
r"make.*test.*pass|implement.*minimum",
|
|
116
|
+
],
|
|
117
|
+
Phase.REFACTOR: [
|
|
118
|
+
r"/moai:2-run.*REFACTOR",
|
|
119
|
+
r"refactor|clean.*code",
|
|
120
|
+
r"quality.*improvement|improve.*code",
|
|
121
|
+
r"optimize.*code|code.*cleanup",
|
|
122
|
+
],
|
|
123
|
+
Phase.SYNC: [
|
|
124
|
+
r"/moai:3-sync",
|
|
125
|
+
r"documentation.*sync|sync.*docs",
|
|
126
|
+
r"generate.*docs|create.*documentation",
|
|
127
|
+
r"update.*documentation",
|
|
128
|
+
],
|
|
129
|
+
Phase.DEBUG: [
|
|
130
|
+
r"debug|troubleshoot",
|
|
131
|
+
r"error.*analysis|analyze.*error",
|
|
132
|
+
r"fix.*bug|error.*investigation",
|
|
133
|
+
r"problem.*solving",
|
|
134
|
+
],
|
|
135
|
+
Phase.PLANNING: [
|
|
136
|
+
r"plan.*implementation|implementation.*plan",
|
|
137
|
+
r"architecture.*design|design.*architecture",
|
|
138
|
+
r"task.*decomposition|breakdown.*task",
|
|
139
|
+
r"plan.*development|development.*planning",
|
|
140
|
+
],
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
self.last_phase = Phase.SPEC
|
|
144
|
+
self.phase_history = []
|
|
145
|
+
self.max_history = 10
|
|
146
|
+
|
|
147
|
+
def detect_phase(self, user_input: str, conversation_history: List[str] = None) -> Phase:
|
|
148
|
+
"""Detect current phase from user input and conversation context"""
|
|
149
|
+
import re
|
|
150
|
+
|
|
151
|
+
# Combine user input with recent conversation history
|
|
152
|
+
context = user_input.lower()
|
|
153
|
+
if conversation_history:
|
|
154
|
+
recent_history = " ".join(conversation_history[-3:]) # Last 3 messages
|
|
155
|
+
context += " " + recent_history.lower()
|
|
156
|
+
|
|
157
|
+
# Score each phase based on pattern matches
|
|
158
|
+
phase_scores = {}
|
|
159
|
+
for phase, patterns in self.phase_patterns.items():
|
|
160
|
+
score = 0
|
|
161
|
+
for pattern in patterns:
|
|
162
|
+
matches = len(re.findall(pattern, context, re.IGNORECASE))
|
|
163
|
+
score += matches
|
|
164
|
+
phase_scores[phase] = score
|
|
165
|
+
|
|
166
|
+
# Find phase with highest score
|
|
167
|
+
if phase_scores:
|
|
168
|
+
best_phase = max(phase_scores, key=phase_scores.get)
|
|
169
|
+
else:
|
|
170
|
+
best_phase = self.last_phase
|
|
171
|
+
|
|
172
|
+
# If no clear winner (all scores 0), use last known phase
|
|
173
|
+
if phase_scores[best_phase] == 0:
|
|
174
|
+
best_phase = self.last_phase
|
|
175
|
+
|
|
176
|
+
# Update history
|
|
177
|
+
if best_phase != self.last_phase:
|
|
178
|
+
self.phase_history.append(
|
|
179
|
+
{
|
|
180
|
+
"from": self.last_phase.value,
|
|
181
|
+
"to": best_phase.value,
|
|
182
|
+
"timestamp": datetime.now(),
|
|
183
|
+
"context": (user_input[:100] + "..." if len(user_input) > 100 else user_input),
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
if len(self.phase_history) > self.max_history:
|
|
188
|
+
self.phase_history.pop(0)
|
|
189
|
+
|
|
190
|
+
self.last_phase = best_phase
|
|
191
|
+
return best_phase
|
|
192
|
+
|
|
193
|
+
def get_phase_config(self, phase: Phase) -> PhaseConfig:
|
|
194
|
+
"""Get configuration for a specific phase"""
|
|
195
|
+
configs = {
|
|
196
|
+
Phase.SPEC: PhaseConfig(
|
|
197
|
+
max_tokens=30000,
|
|
198
|
+
essential_skills=[
|
|
199
|
+
"moai-foundation-ears",
|
|
200
|
+
"moai-foundation-specs",
|
|
201
|
+
"moai-essentials-review",
|
|
202
|
+
"moai-domain-backend",
|
|
203
|
+
"moai-lang-python",
|
|
204
|
+
"moai-core-spec-authoring",
|
|
205
|
+
],
|
|
206
|
+
essential_documents=[
|
|
207
|
+
".moai/specs/template.md",
|
|
208
|
+
".claude/skills/moai-foundation-ears/SKILL.md",
|
|
209
|
+
],
|
|
210
|
+
cache_clear_on_phase_change=True,
|
|
211
|
+
),
|
|
212
|
+
Phase.RED: PhaseConfig(
|
|
213
|
+
max_tokens=25000,
|
|
214
|
+
essential_skills=[
|
|
215
|
+
"moai-domain-testing",
|
|
216
|
+
"moai-foundation-trust",
|
|
217
|
+
"moai-essentials-review",
|
|
218
|
+
"moai-core-code-reviewer",
|
|
219
|
+
"moai-essentials-debug",
|
|
220
|
+
"moai-lang-python",
|
|
221
|
+
],
|
|
222
|
+
essential_documents=[
|
|
223
|
+
".moai/specs/{spec_id}/spec.md",
|
|
224
|
+
".claude/skills/moai-domain-testing/SKILL.md",
|
|
225
|
+
],
|
|
226
|
+
),
|
|
227
|
+
Phase.GREEN: PhaseConfig(
|
|
228
|
+
max_tokens=25000,
|
|
229
|
+
essential_skills=[
|
|
230
|
+
"moai-lang-python",
|
|
231
|
+
"moai-domain-backend",
|
|
232
|
+
"moai-essentials-review",
|
|
233
|
+
],
|
|
234
|
+
essential_documents=[".moai/specs/{spec_id}/spec.md"],
|
|
235
|
+
),
|
|
236
|
+
Phase.REFACTOR: PhaseConfig(
|
|
237
|
+
max_tokens=20000,
|
|
238
|
+
essential_skills=[
|
|
239
|
+
"moai-essentials-refactor",
|
|
240
|
+
"moai-essentials-review",
|
|
241
|
+
"moai-core-code-reviewer",
|
|
242
|
+
"moai-essentials-debug",
|
|
243
|
+
],
|
|
244
|
+
essential_documents=[
|
|
245
|
+
"src/{module}/current_implementation.py",
|
|
246
|
+
".claude/skills/moai-essentials-refactor/SKILL.md",
|
|
247
|
+
],
|
|
248
|
+
),
|
|
249
|
+
Phase.SYNC: PhaseConfig(
|
|
250
|
+
max_tokens=40000,
|
|
251
|
+
essential_skills=[
|
|
252
|
+
"moai-docs-unified",
|
|
253
|
+
"moai-nextra-architecture",
|
|
254
|
+
"moai-core-spec-authoring",
|
|
255
|
+
"moai-cc-configuration",
|
|
256
|
+
],
|
|
257
|
+
essential_documents=[
|
|
258
|
+
".moai/specs/{spec_id}/implementation.md",
|
|
259
|
+
".moai/specs/{spec_id}/test-cases.md",
|
|
260
|
+
],
|
|
261
|
+
cache_clear_on_phase_change=True,
|
|
262
|
+
),
|
|
263
|
+
Phase.DEBUG: PhaseConfig(
|
|
264
|
+
max_tokens=15000,
|
|
265
|
+
essential_skills=["moai-essentials-debug", "moai-core-code-reviewer"],
|
|
266
|
+
essential_documents=[".moai/logs/latest_error.log"],
|
|
267
|
+
),
|
|
268
|
+
Phase.PLANNING: PhaseConfig(
|
|
269
|
+
max_tokens=35000,
|
|
270
|
+
essential_skills=[
|
|
271
|
+
"moai-core-practices",
|
|
272
|
+
"moai-essentials-review",
|
|
273
|
+
"moai-foundation-specs",
|
|
274
|
+
],
|
|
275
|
+
essential_documents=[".moai/specs/{spec_id}/spec.md"],
|
|
276
|
+
),
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return configs.get(phase, configs[Phase.SPEC])
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class SkillFilterEngine:
|
|
283
|
+
"""Intelligently filters and selects skills based on phase and context"""
|
|
284
|
+
|
|
285
|
+
def __init__(self, skills_dir: str = ".claude/skills"):
|
|
286
|
+
self.skills_dir = Path(skills_dir)
|
|
287
|
+
self.skills_cache: Dict[str, Any] = {}
|
|
288
|
+
self.skill_index: Dict[str, SkillInfo] = {}
|
|
289
|
+
self.phase_preferences = self._load_phase_preferences()
|
|
290
|
+
self._build_skill_index()
|
|
291
|
+
|
|
292
|
+
def _load_phase_preferences(self) -> Dict[str, Dict[str, int]]:
|
|
293
|
+
"""Load phase-based skill preferences"""
|
|
294
|
+
return {
|
|
295
|
+
"spec": {
|
|
296
|
+
"moai-foundation-ears": 1,
|
|
297
|
+
"moai-foundation-specs": 1,
|
|
298
|
+
"moai-essentials-review": 2,
|
|
299
|
+
"moai-domain-backend": 2,
|
|
300
|
+
"moai-lang-python": 3,
|
|
301
|
+
"moai-core-spec-authoring": 1,
|
|
302
|
+
},
|
|
303
|
+
"red": {
|
|
304
|
+
"moai-domain-testing": 1,
|
|
305
|
+
"moai-foundation-trust": 1,
|
|
306
|
+
"moai-essentials-review": 2,
|
|
307
|
+
"moai-core-code-reviewer": 2,
|
|
308
|
+
"moai-essentials-debug": 2,
|
|
309
|
+
"moai-lang-python": 3,
|
|
310
|
+
},
|
|
311
|
+
"green": {
|
|
312
|
+
"moai-lang-python": 1,
|
|
313
|
+
"moai-domain-backend": 1,
|
|
314
|
+
"moai-essentials-review": 2,
|
|
315
|
+
},
|
|
316
|
+
"refactor": {
|
|
317
|
+
"moai-essentials-refactor": 1,
|
|
318
|
+
"moai-essentials-review": 2,
|
|
319
|
+
"moai-core-code-reviewer": 2,
|
|
320
|
+
"moai-essentials-debug": 3,
|
|
321
|
+
},
|
|
322
|
+
"sync": {
|
|
323
|
+
"moai-docs-unified": 1,
|
|
324
|
+
"moai-nextra-architecture": 1,
|
|
325
|
+
"moai-core-spec-authoring": 2,
|
|
326
|
+
"moai-cc-configuration": 2,
|
|
327
|
+
},
|
|
328
|
+
"debug": {"moai-essentials-debug": 1, "moai-core-code-reviewer": 2},
|
|
329
|
+
"planning": {
|
|
330
|
+
"moai-core-practices": 1,
|
|
331
|
+
"moai-essentials-review": 2,
|
|
332
|
+
"moai-foundation-specs": 2,
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
def _build_skill_index(self):
|
|
337
|
+
"""Build index of all available skills with metadata"""
|
|
338
|
+
if not self.skills_dir.exists():
|
|
339
|
+
logger.warning(f"Skills directory not found: {self.skills_dir}")
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
for skill_dir in self.skills_dir.iterdir():
|
|
343
|
+
if skill_dir.is_dir():
|
|
344
|
+
skill_file = skill_dir / "SKILL.md"
|
|
345
|
+
if skill_file.exists():
|
|
346
|
+
skill_info = self._analyze_skill(skill_file)
|
|
347
|
+
if skill_info:
|
|
348
|
+
self.skill_index[skill_info.name] = skill_info
|
|
349
|
+
|
|
350
|
+
def _analyze_skill(self, skill_file: Path) -> Optional[SkillInfo]:
|
|
351
|
+
"""Analyze a skill file to extract metadata"""
|
|
352
|
+
try:
|
|
353
|
+
stat = skill_file.stat()
|
|
354
|
+
|
|
355
|
+
# Read skill content to extract categories
|
|
356
|
+
with open(skill_file, "r", encoding="utf-8") as f:
|
|
357
|
+
content = f.read()
|
|
358
|
+
|
|
359
|
+
# Extract skill name from directory
|
|
360
|
+
skill_name = skill_file.parent.name
|
|
361
|
+
|
|
362
|
+
# Estimate tokens (rough approximation: 1 token ≈ 4 characters)
|
|
363
|
+
estimated_tokens = len(content) // 4
|
|
364
|
+
|
|
365
|
+
# Extract categories from content (look for keywords)
|
|
366
|
+
categories = []
|
|
367
|
+
if any(keyword in content.lower() for keyword in ["python", "javascript", "typescript", "go", "rust"]):
|
|
368
|
+
categories.append("language")
|
|
369
|
+
if any(keyword in content.lower() for keyword in ["backend", "frontend", "database", "security"]):
|
|
370
|
+
categories.append("domain")
|
|
371
|
+
if any(keyword in content.lower() for keyword in ["testing", "debug", "refactor", "review"]):
|
|
372
|
+
categories.append("development")
|
|
373
|
+
if any(keyword in content.lower() for keyword in ["foundation", "essential", "core"]):
|
|
374
|
+
categories.append("core")
|
|
375
|
+
|
|
376
|
+
return SkillInfo(
|
|
377
|
+
name=skill_name,
|
|
378
|
+
path=str(skill_file),
|
|
379
|
+
size=stat.st_size,
|
|
380
|
+
tokens=estimated_tokens,
|
|
381
|
+
categories=categories,
|
|
382
|
+
priority=1,
|
|
383
|
+
)
|
|
384
|
+
|
|
385
|
+
except Exception as e:
|
|
386
|
+
logger.error(f"Error analyzing skill {skill_file}: {e}")
|
|
387
|
+
return None
|
|
388
|
+
|
|
389
|
+
def filter_skills(self, phase: Phase, token_budget: int, context: Dict[str, Any] = None) -> List[SkillInfo]:
|
|
390
|
+
"""Filter skills based on phase, token budget, and context"""
|
|
391
|
+
phase_name = phase.value
|
|
392
|
+
preferences = self.phase_preferences.get(phase_name, {})
|
|
393
|
+
|
|
394
|
+
# Get all relevant skills for this phase
|
|
395
|
+
relevant_skills = []
|
|
396
|
+
for skill_name, skill_info in self.skill_index.items():
|
|
397
|
+
# Check if skill is relevant for this phase
|
|
398
|
+
if skill_name in preferences:
|
|
399
|
+
# Apply priority from preferences
|
|
400
|
+
skill_info.priority = preferences[skill_name]
|
|
401
|
+
relevant_skills.append(skill_info)
|
|
402
|
+
|
|
403
|
+
# Sort by priority and token efficiency
|
|
404
|
+
relevant_skills.sort(key=lambda s: (s.priority, s.tokens))
|
|
405
|
+
|
|
406
|
+
# Select skills within token budget
|
|
407
|
+
selected_skills = []
|
|
408
|
+
used_tokens = 0
|
|
409
|
+
|
|
410
|
+
for skill in relevant_skills:
|
|
411
|
+
if used_tokens + skill.tokens <= token_budget:
|
|
412
|
+
selected_skills.append(skill)
|
|
413
|
+
used_tokens += skill.tokens
|
|
414
|
+
else:
|
|
415
|
+
break
|
|
416
|
+
|
|
417
|
+
return selected_skills
|
|
418
|
+
|
|
419
|
+
def get_skill_stats(self) -> Dict[str, Any]:
|
|
420
|
+
"""Get statistics about available skills"""
|
|
421
|
+
total_skills = len(self.skill_index)
|
|
422
|
+
total_tokens = sum(skill.tokens for skill in self.skill_index.values())
|
|
423
|
+
|
|
424
|
+
categories: Dict[str, int] = {}
|
|
425
|
+
for skill in self.skill_index.values():
|
|
426
|
+
for category in skill.categories:
|
|
427
|
+
categories[category] = categories.get(category, 0) + 1
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
"total_skills": total_skills,
|
|
431
|
+
"total_tokens": total_tokens,
|
|
432
|
+
"categories": categories,
|
|
433
|
+
"average_tokens_per_skill": (total_tokens / total_skills if total_skills > 0 else 0),
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
|
|
437
|
+
class TokenBudgetManager:
|
|
438
|
+
"""Manages token budgets and usage across phases"""
|
|
439
|
+
|
|
440
|
+
def __init__(self, max_total_tokens: int = 180000):
|
|
441
|
+
self.max_total_tokens = max_total_tokens
|
|
442
|
+
self.phase_budgets = self._initialize_phase_budgets()
|
|
443
|
+
self.current_usage = 0
|
|
444
|
+
self.usage_history: List[Dict[str, Any]] = []
|
|
445
|
+
self.budget_warnings: List[Dict[str, Any]] = []
|
|
446
|
+
|
|
447
|
+
def _initialize_phase_budgets(self) -> Dict[str, int]:
|
|
448
|
+
"""Initialize token budgets for each phase"""
|
|
449
|
+
return {
|
|
450
|
+
"spec": 30000,
|
|
451
|
+
"red": 25000,
|
|
452
|
+
"green": 25000,
|
|
453
|
+
"refactor": 20000,
|
|
454
|
+
"sync": 40000,
|
|
455
|
+
"debug": 15000,
|
|
456
|
+
"planning": 35000,
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
def check_budget(self, phase: Phase, requested_tokens: int) -> Tuple[bool, int]:
|
|
460
|
+
"""Check if requested tokens fit in budget"""
|
|
461
|
+
phase_budget = self.phase_budgets.get(phase.value, 30000)
|
|
462
|
+
|
|
463
|
+
if requested_tokens <= phase_budget:
|
|
464
|
+
return True, phase_budget - requested_tokens
|
|
465
|
+
else:
|
|
466
|
+
return False, phase_budget
|
|
467
|
+
|
|
468
|
+
def record_usage(self, phase: Phase, tokens_used: int, context: str = ""):
|
|
469
|
+
"""Record actual token usage"""
|
|
470
|
+
usage_entry = {
|
|
471
|
+
"phase": phase.value,
|
|
472
|
+
"tokens": tokens_used,
|
|
473
|
+
"timestamp": datetime.now(),
|
|
474
|
+
"context": context[:100],
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
self.usage_history.append(usage_entry)
|
|
478
|
+
self.current_usage += tokens_used
|
|
479
|
+
|
|
480
|
+
# Keep only recent history (last 50 entries)
|
|
481
|
+
if len(self.usage_history) > 50:
|
|
482
|
+
self.usage_history.pop(0)
|
|
483
|
+
|
|
484
|
+
# Check for budget warnings
|
|
485
|
+
phase_budget = self.phase_budgets.get(phase.value, 30000)
|
|
486
|
+
if tokens_used > phase_budget:
|
|
487
|
+
warning = f"Phase {phase.value} exceeded budget: {tokens_used} > {phase_budget}"
|
|
488
|
+
self.budget_warnings.append({"warning": warning, "timestamp": datetime.now()})
|
|
489
|
+
logger.warning(warning)
|
|
490
|
+
|
|
491
|
+
def get_efficiency_metrics(self) -> Dict[str, Any]:
|
|
492
|
+
"""Calculate and return efficiency metrics"""
|
|
493
|
+
if not self.usage_history:
|
|
494
|
+
return {
|
|
495
|
+
"efficiency_score": 0,
|
|
496
|
+
"average_phase_efficiency": {},
|
|
497
|
+
"budget_compliance": 100,
|
|
498
|
+
"total_usage": 0,
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
# Calculate efficiency by phase
|
|
502
|
+
phase_usage = {}
|
|
503
|
+
phase_efficiency = {}
|
|
504
|
+
|
|
505
|
+
for entry in self.usage_history:
|
|
506
|
+
phase = entry["phase"]
|
|
507
|
+
tokens = entry["tokens"]
|
|
508
|
+
budget = self.phase_budgets.get(phase, 30000)
|
|
509
|
+
|
|
510
|
+
if phase not in phase_usage:
|
|
511
|
+
phase_usage[phase] = {"total": 0, "count": 0, "over_budget": 0}
|
|
512
|
+
|
|
513
|
+
phase_usage[phase]["total"] += tokens
|
|
514
|
+
phase_usage[phase]["count"] += 1
|
|
515
|
+
if tokens > budget:
|
|
516
|
+
phase_usage[phase]["over_budget"] += 1
|
|
517
|
+
|
|
518
|
+
# Calculate efficiency scores
|
|
519
|
+
for phase, usage in phase_usage.items():
|
|
520
|
+
budget = self.phase_budgets.get(phase, 30000)
|
|
521
|
+
actual = usage["total"] / usage["count"] if usage["count"] > 0 else 0
|
|
522
|
+
efficiency = min(100, (budget / actual * 100) if actual > 0 else 100)
|
|
523
|
+
phase_efficiency[phase] = efficiency
|
|
524
|
+
|
|
525
|
+
# Overall efficiency
|
|
526
|
+
overall_efficiency = sum(phase_efficiency.values()) / len(phase_efficiency) if phase_efficiency else 0
|
|
527
|
+
|
|
528
|
+
# Budget compliance
|
|
529
|
+
total_entries = len(self.usage_history)
|
|
530
|
+
over_budget_entries = sum(usage["over_budget"] for usage in phase_usage.values())
|
|
531
|
+
budget_compliance = ((total_entries - over_budget_entries) / total_entries * 100) if total_entries > 0 else 100
|
|
532
|
+
|
|
533
|
+
return {
|
|
534
|
+
"efficiency_score": overall_efficiency,
|
|
535
|
+
"average_phase_efficiency": phase_efficiency,
|
|
536
|
+
"budget_compliance": budget_compliance,
|
|
537
|
+
"total_usage": self.current_usage,
|
|
538
|
+
"phase_usage": phase_usage,
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
class ContextCache:
|
|
543
|
+
"""LRU Cache for context entries with phase-aware eviction"""
|
|
544
|
+
|
|
545
|
+
def __init__(self, max_size: int = 100, max_memory_mb: int = 50):
|
|
546
|
+
self.max_size = max_size
|
|
547
|
+
self.max_memory_bytes = max_memory_mb * 1024 * 1024
|
|
548
|
+
self.cache: OrderedDict[str, ContextEntry] = OrderedDict()
|
|
549
|
+
self.current_memory = 0
|
|
550
|
+
self.hits = 0
|
|
551
|
+
self.misses = 0
|
|
552
|
+
self.evictions = 0
|
|
553
|
+
|
|
554
|
+
def _calculate_memory_usage(self, entry: ContextEntry) -> int:
|
|
555
|
+
"""Calculate memory usage of a cache entry"""
|
|
556
|
+
|
|
557
|
+
# Rough estimation of memory usage
|
|
558
|
+
content_size = sys.getsizeof(entry.content)
|
|
559
|
+
entry_overhead = sys.getsizeof(entry.key) + sys.getsizeof(str(entry.token_count))
|
|
560
|
+
total_size = content_size + entry_overhead
|
|
561
|
+
|
|
562
|
+
return total_size
|
|
563
|
+
|
|
564
|
+
def get(self, key: str) -> Optional[ContextEntry]:
|
|
565
|
+
"""Get entry from cache"""
|
|
566
|
+
if key in self.cache:
|
|
567
|
+
entry = self.cache[key]
|
|
568
|
+
entry.last_accessed = datetime.now()
|
|
569
|
+
entry.access_count += 1
|
|
570
|
+
self.cache.move_to_end(key)
|
|
571
|
+
self.hits += 1
|
|
572
|
+
return entry
|
|
573
|
+
|
|
574
|
+
self.misses += 1
|
|
575
|
+
return None
|
|
576
|
+
|
|
577
|
+
def put(self, key: str, content: Any, token_count: int, phase: Optional[str] = None):
|
|
578
|
+
"""Put entry in cache with LRU eviction"""
|
|
579
|
+
entry = ContextEntry(
|
|
580
|
+
key=key,
|
|
581
|
+
content=content,
|
|
582
|
+
token_count=token_count,
|
|
583
|
+
created_at=datetime.now(),
|
|
584
|
+
last_accessed=datetime.now(),
|
|
585
|
+
phase=phase,
|
|
586
|
+
)
|
|
587
|
+
|
|
588
|
+
entry_memory = self._calculate_memory_usage(entry)
|
|
589
|
+
|
|
590
|
+
# Check if we need to evict entries
|
|
591
|
+
while len(self.cache) >= self.max_size or self.current_memory + entry_memory > self.max_memory_bytes:
|
|
592
|
+
if not self.cache:
|
|
593
|
+
break
|
|
594
|
+
|
|
595
|
+
oldest_key = next(iter(self.cache))
|
|
596
|
+
oldest_entry = self.cache.pop(oldest_key)
|
|
597
|
+
self.current_memory -= self._calculate_memory_usage(oldest_entry)
|
|
598
|
+
self.evictions += 1
|
|
599
|
+
|
|
600
|
+
# Add new entry
|
|
601
|
+
self.cache[key] = entry
|
|
602
|
+
self.current_memory += entry_memory
|
|
603
|
+
|
|
604
|
+
def clear_phase(self, phase: str):
|
|
605
|
+
"""Clear all entries for a specific phase"""
|
|
606
|
+
keys_to_remove = [key for key, entry in self.cache.items() if entry.phase == phase]
|
|
607
|
+
for key in keys_to_remove:
|
|
608
|
+
entry = self.cache.pop(key)
|
|
609
|
+
self.current_memory -= self._calculate_memory_usage(entry)
|
|
610
|
+
|
|
611
|
+
def clear(self):
|
|
612
|
+
"""Clear all cache entries"""
|
|
613
|
+
self.cache.clear()
|
|
614
|
+
self.current_memory = 0
|
|
615
|
+
|
|
616
|
+
def get_stats(self) -> Dict[str, Any]:
|
|
617
|
+
"""Get cache statistics"""
|
|
618
|
+
total_requests = self.hits + self.misses
|
|
619
|
+
hit_rate = (self.hits / total_requests * 100) if total_requests > 0 else 0
|
|
620
|
+
|
|
621
|
+
return {
|
|
622
|
+
"entries": len(self.cache),
|
|
623
|
+
"memory_usage_bytes": self.current_memory,
|
|
624
|
+
"memory_usage_mb": self.current_memory / (1024 * 1024),
|
|
625
|
+
"hit_rate": hit_rate,
|
|
626
|
+
"hits": self.hits,
|
|
627
|
+
"misses": self.misses,
|
|
628
|
+
"evictions": self.evictions,
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
class JITContextLoader:
|
|
633
|
+
"""Main JIT Context Loading System orchestrator"""
|
|
634
|
+
|
|
635
|
+
def __init__(self, cache_size: int = 100, cache_memory_mb: int = 50):
|
|
636
|
+
self.phase_detector = PhaseDetector()
|
|
637
|
+
self.skill_filter = SkillFilterEngine()
|
|
638
|
+
self.token_manager = TokenBudgetManager()
|
|
639
|
+
self.context_cache = ContextCache(cache_size, cache_memory_mb)
|
|
640
|
+
|
|
641
|
+
self.metrics_history: List[ContextMetrics] = []
|
|
642
|
+
self.current_phase = Phase.SPEC
|
|
643
|
+
|
|
644
|
+
# Performance monitoring
|
|
645
|
+
self.performance_stats: Dict[str, Any] = {
|
|
646
|
+
"total_loads": 0,
|
|
647
|
+
"average_load_time": 0,
|
|
648
|
+
"cache_hit_rate": 0,
|
|
649
|
+
"efficiency_score": 0,
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
async def load_context(
|
|
653
|
+
self,
|
|
654
|
+
user_input: str,
|
|
655
|
+
conversation_history: List[str] = None,
|
|
656
|
+
context: Dict[str, Any] = None,
|
|
657
|
+
) -> Tuple[Dict[str, Any], ContextMetrics]:
|
|
658
|
+
"""Load optimized context based on current phase and requirements"""
|
|
659
|
+
start_time = time.time()
|
|
660
|
+
|
|
661
|
+
# Detect current phase
|
|
662
|
+
self.current_phase = self.phase_detector.detect_phase(user_input, conversation_history or [])
|
|
663
|
+
phase_config = self.phase_detector.get_phase_config(self.current_phase)
|
|
664
|
+
|
|
665
|
+
# Generate cache key
|
|
666
|
+
cache_key = self._generate_cache_key(self.current_phase, user_input, context or {})
|
|
667
|
+
|
|
668
|
+
# Check cache first
|
|
669
|
+
cached_entry = self.context_cache.get(cache_key)
|
|
670
|
+
if cached_entry:
|
|
671
|
+
metrics = ContextMetrics(
|
|
672
|
+
load_time=time.time() - start_time,
|
|
673
|
+
token_count=cached_entry.token_count,
|
|
674
|
+
cache_hit=True,
|
|
675
|
+
phase=self.current_phase.value,
|
|
676
|
+
skills_loaded=len(cached_entry.content.get("skills", [])),
|
|
677
|
+
docs_loaded=len(cached_entry.content.get("documents", [])),
|
|
678
|
+
memory_usage=psutil.Process().memory_info().rss,
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
self._record_metrics(metrics)
|
|
682
|
+
return cached_entry.content, metrics
|
|
683
|
+
|
|
684
|
+
# Load fresh context
|
|
685
|
+
context_data = await self._build_context(self.current_phase, phase_config, context or {})
|
|
686
|
+
|
|
687
|
+
# Calculate total tokens
|
|
688
|
+
total_tokens = self._calculate_total_tokens(context_data)
|
|
689
|
+
|
|
690
|
+
# Check token budget
|
|
691
|
+
within_budget, remaining_budget = self.token_manager.check_budget(self.current_phase, total_tokens)
|
|
692
|
+
|
|
693
|
+
if not within_budget:
|
|
694
|
+
# Apply aggressive optimization
|
|
695
|
+
context_data = await self._optimize_context_aggressively(context_data, remaining_budget)
|
|
696
|
+
total_tokens = self._calculate_total_tokens(context_data)
|
|
697
|
+
|
|
698
|
+
# Cache the result
|
|
699
|
+
self.context_cache.put(cache_key, context_data, total_tokens, self.current_phase.value)
|
|
700
|
+
|
|
701
|
+
# Record usage
|
|
702
|
+
load_time = time.time() - start_time
|
|
703
|
+
self.token_manager.record_usage(self.current_phase, total_tokens, user_input)
|
|
704
|
+
|
|
705
|
+
metrics = ContextMetrics(
|
|
706
|
+
load_time=load_time,
|
|
707
|
+
token_count=total_tokens,
|
|
708
|
+
cache_hit=False,
|
|
709
|
+
phase=self.current_phase.value,
|
|
710
|
+
skills_loaded=len(context_data.get("skills", [])),
|
|
711
|
+
docs_loaded=len(context_data.get("documents", [])),
|
|
712
|
+
memory_usage=psutil.Process().memory_info().rss,
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
self._record_metrics(metrics)
|
|
716
|
+
return context_data, metrics
|
|
717
|
+
|
|
718
|
+
def _generate_cache_key(self, phase: Phase, user_input: str, context: Dict[str, Any]) -> str:
|
|
719
|
+
"""Generate unique cache key for context request"""
|
|
720
|
+
key_data = {
|
|
721
|
+
"phase": phase.value,
|
|
722
|
+
"input_hash": hashlib.md5(user_input.encode(), usedforsecurity=False).hexdigest()[:16],
|
|
723
|
+
"context_keys": sorted(context.keys()),
|
|
724
|
+
"timestamp": datetime.now().strftime("%Y%m%d"), # Daily cache
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
return hashlib.md5(json.dumps(key_data, sort_keys=True).encode(), usedforsecurity=False).hexdigest()
|
|
728
|
+
|
|
729
|
+
async def _build_context(self, phase: Phase, phase_config: PhaseConfig, context: Dict[str, Any]) -> Dict[str, Any]:
|
|
730
|
+
"""Build optimized context for the current phase"""
|
|
731
|
+
context_data: Dict[str, Any] = {
|
|
732
|
+
"phase": phase.value,
|
|
733
|
+
"skills": [],
|
|
734
|
+
"documents": [],
|
|
735
|
+
"metadata": {
|
|
736
|
+
"created_at": datetime.now().isoformat(),
|
|
737
|
+
"max_tokens": phase_config.max_tokens,
|
|
738
|
+
"compression_enabled": phase_config.context_compression,
|
|
739
|
+
},
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
# Filter and load skills
|
|
743
|
+
skills = self.skill_filter.filter_skills(phase, phase_config.max_tokens // 2, context)
|
|
744
|
+
for skill in skills:
|
|
745
|
+
skill_content = await self._load_skill_content(skill)
|
|
746
|
+
if skill_content:
|
|
747
|
+
skills_list = context_data["skills"]
|
|
748
|
+
if isinstance(skills_list, list):
|
|
749
|
+
skills_list.append(
|
|
750
|
+
{
|
|
751
|
+
"name": skill.name,
|
|
752
|
+
"content": skill_content,
|
|
753
|
+
"tokens": skill.tokens,
|
|
754
|
+
"categories": skill.categories,
|
|
755
|
+
"priority": skill.priority,
|
|
756
|
+
}
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
# Load essential documents
|
|
760
|
+
for doc_path in phase_config.essential_documents:
|
|
761
|
+
doc_content = await self._load_document(doc_path, context)
|
|
762
|
+
if doc_content:
|
|
763
|
+
docs_list = context_data["documents"]
|
|
764
|
+
if isinstance(docs_list, list):
|
|
765
|
+
docs_list.append(
|
|
766
|
+
{
|
|
767
|
+
"path": doc_path,
|
|
768
|
+
"content": doc_content["content"],
|
|
769
|
+
"tokens": doc_content["tokens"],
|
|
770
|
+
"type": doc_content["type"],
|
|
771
|
+
}
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
return context_data
|
|
775
|
+
|
|
776
|
+
async def _load_skill_content(self, skill: SkillInfo) -> Optional[str]:
|
|
777
|
+
"""Load content of a skill file"""
|
|
778
|
+
try:
|
|
779
|
+
with open(skill.path, "r", encoding="utf-8") as f:
|
|
780
|
+
content = f.read()
|
|
781
|
+
return content
|
|
782
|
+
except Exception as e:
|
|
783
|
+
logger.error(f"Error loading skill {skill.name}: {e}")
|
|
784
|
+
return None
|
|
785
|
+
|
|
786
|
+
async def _load_document(self, doc_path: str, context: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
787
|
+
"""Load and process a document"""
|
|
788
|
+
try:
|
|
789
|
+
# Apply context variable substitution
|
|
790
|
+
formatted_path = doc_path.format(
|
|
791
|
+
spec_id=context.get("spec_id", "SPEC-XXX"),
|
|
792
|
+
module=context.get("module", "unknown"),
|
|
793
|
+
language=context.get("language", "python"),
|
|
794
|
+
)
|
|
795
|
+
|
|
796
|
+
if os.path.exists(formatted_path):
|
|
797
|
+
with open(formatted_path, "r", encoding="utf-8") as f:
|
|
798
|
+
content = f.read()
|
|
799
|
+
|
|
800
|
+
return {
|
|
801
|
+
"content": content,
|
|
802
|
+
"tokens": len(content) // 4, # Rough token estimation
|
|
803
|
+
"type": self._detect_document_type(formatted_path),
|
|
804
|
+
}
|
|
805
|
+
except Exception as e:
|
|
806
|
+
logger.error(f"Error loading document {doc_path}: {e}")
|
|
807
|
+
return None
|
|
808
|
+
|
|
809
|
+
def _detect_document_type(self, file_path: str) -> str:
|
|
810
|
+
"""Detect document type from file path"""
|
|
811
|
+
if file_path.endswith(".md"):
|
|
812
|
+
return "markdown"
|
|
813
|
+
elif file_path.endswith(".py"):
|
|
814
|
+
return "python"
|
|
815
|
+
elif file_path.endswith(".json"):
|
|
816
|
+
return "json"
|
|
817
|
+
elif file_path.endswith(".yaml") or file_path.endswith(".yml"):
|
|
818
|
+
return "yaml"
|
|
819
|
+
else:
|
|
820
|
+
return "text"
|
|
821
|
+
|
|
822
|
+
async def _optimize_context_aggressively(self, context_data: Dict[str, Any], token_budget: int) -> Dict[str, Any]:
|
|
823
|
+
"""Apply aggressive optimization to fit token budget"""
|
|
824
|
+
current_tokens = self._calculate_total_tokens(context_data)
|
|
825
|
+
|
|
826
|
+
if current_tokens <= token_budget:
|
|
827
|
+
return context_data
|
|
828
|
+
|
|
829
|
+
# Strategy 1: Remove low-priority skills
|
|
830
|
+
skills = context_data.get("skills", [])
|
|
831
|
+
skills.sort(key=lambda s: s.get("priority", 3)) # Remove low priority first
|
|
832
|
+
|
|
833
|
+
optimized_skills = []
|
|
834
|
+
used_tokens = 0
|
|
835
|
+
|
|
836
|
+
for skill in skills:
|
|
837
|
+
if used_tokens + skill.get("tokens", 0) <= token_budget * 0.7: # Reserve 30% for docs
|
|
838
|
+
optimized_skills.append(skill)
|
|
839
|
+
used_tokens += skill.get("tokens", 0)
|
|
840
|
+
else:
|
|
841
|
+
break
|
|
842
|
+
|
|
843
|
+
context_data["skills"] = optimized_skills
|
|
844
|
+
|
|
845
|
+
# Strategy 2: Compress documents if still over budget
|
|
846
|
+
if self._calculate_total_tokens(context_data) > token_budget:
|
|
847
|
+
documents = context_data.get("documents", [])
|
|
848
|
+
for doc in documents:
|
|
849
|
+
if doc.get("tokens", 0) > 1000: # Only compress large documents
|
|
850
|
+
doc["content"] = self._compress_text(doc["content"])
|
|
851
|
+
doc["tokens"] = len(doc["content"]) // 4
|
|
852
|
+
doc["compressed"] = True
|
|
853
|
+
|
|
854
|
+
return context_data
|
|
855
|
+
|
|
856
|
+
def _compress_text(self, text: str) -> str:
|
|
857
|
+
"""Simple text compression by removing redundancy"""
|
|
858
|
+
lines = text.split("\n")
|
|
859
|
+
compressed_lines = []
|
|
860
|
+
|
|
861
|
+
for line in lines:
|
|
862
|
+
stripped = line.strip()
|
|
863
|
+
# Skip empty lines and common comment patterns
|
|
864
|
+
if stripped and not stripped.startswith("#") and not stripped.startswith("//") and len(stripped) > 10:
|
|
865
|
+
compressed_lines.append(stripped)
|
|
866
|
+
|
|
867
|
+
return "\n".join(compressed_lines)
|
|
868
|
+
|
|
869
|
+
def _calculate_total_tokens(self, context_data: Dict[str, Any]) -> int:
|
|
870
|
+
"""Calculate total tokens in context data"""
|
|
871
|
+
total_tokens = 0
|
|
872
|
+
|
|
873
|
+
# Count skill tokens
|
|
874
|
+
for skill in context_data.get("skills", []):
|
|
875
|
+
total_tokens += skill.get("tokens", 0)
|
|
876
|
+
|
|
877
|
+
# Count document tokens
|
|
878
|
+
for doc in context_data.get("documents", []):
|
|
879
|
+
total_tokens += doc.get("tokens", 0)
|
|
880
|
+
|
|
881
|
+
# Add overhead (approximate)
|
|
882
|
+
total_tokens += 1000 # Metadata and structure overhead
|
|
883
|
+
|
|
884
|
+
return total_tokens
|
|
885
|
+
|
|
886
|
+
def _record_metrics(self, metrics: ContextMetrics):
|
|
887
|
+
"""Record performance metrics"""
|
|
888
|
+
self.metrics_history.append(metrics)
|
|
889
|
+
|
|
890
|
+
# Keep only recent metrics (last 100)
|
|
891
|
+
if len(self.metrics_history) > 100:
|
|
892
|
+
self.metrics_history.pop(0)
|
|
893
|
+
|
|
894
|
+
# Update performance stats
|
|
895
|
+
self.performance_stats["total_loads"] += 1
|
|
896
|
+
self.performance_stats["average_load_time"] = sum(m.load_time for m in self.metrics_history) / len(
|
|
897
|
+
self.metrics_history
|
|
898
|
+
)
|
|
899
|
+
|
|
900
|
+
cache_hits = sum(1 for m in self.metrics_history if m.cache_hit)
|
|
901
|
+
self.performance_stats["cache_hit_rate"] = cache_hits / len(self.metrics_history) * 100
|
|
902
|
+
|
|
903
|
+
# Update efficiency score from token manager
|
|
904
|
+
efficiency_metrics = self.token_manager.get_efficiency_metrics()
|
|
905
|
+
self.performance_stats["efficiency_score"] = efficiency_metrics["efficiency_score"]
|
|
906
|
+
|
|
907
|
+
def get_comprehensive_stats(self) -> Dict[str, Any]:
|
|
908
|
+
"""Get comprehensive system statistics"""
|
|
909
|
+
return {
|
|
910
|
+
"performance": self.performance_stats,
|
|
911
|
+
"cache": self.context_cache.get_stats(),
|
|
912
|
+
"token_efficiency": self.token_manager.get_efficiency_metrics(),
|
|
913
|
+
"skill_filter": self.skill_filter.get_skill_stats(),
|
|
914
|
+
"current_phase": self.current_phase.value,
|
|
915
|
+
"phase_history": self.phase_detector.phase_history[-5:], # Last 5 phase changes
|
|
916
|
+
"metrics_count": len(self.metrics_history),
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
# Global instance for easy import
|
|
921
|
+
jit_context_loader = JITContextLoader()
|
|
922
|
+
|
|
923
|
+
|
|
924
|
+
# Convenience functions
|
|
925
|
+
async def load_optimized_context(
|
|
926
|
+
user_input: str,
|
|
927
|
+
conversation_history: List[str] = None,
|
|
928
|
+
context: Dict[str, Any] = None,
|
|
929
|
+
) -> Tuple[Dict[str, Any], ContextMetrics]:
|
|
930
|
+
"""Load optimized context using global JIT loader instance"""
|
|
931
|
+
return await jit_context_loader.load_context(user_input, conversation_history, context)
|
|
932
|
+
|
|
933
|
+
|
|
934
|
+
def get_jit_stats() -> Dict[str, Any]:
|
|
935
|
+
"""Get comprehensive JIT system statistics"""
|
|
936
|
+
return jit_context_loader.get_comprehensive_stats()
|
|
937
|
+
|
|
938
|
+
|
|
939
|
+
def clear_jit_cache(phase: Optional[str] = None):
|
|
940
|
+
"""Clear JIT cache (optionally for specific phase)"""
|
|
941
|
+
if phase:
|
|
942
|
+
jit_context_loader.context_cache.clear_phase(phase)
|
|
943
|
+
else:
|
|
944
|
+
jit_context_loader.context_cache.clear()
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
# Initial setup
|
|
948
|
+
def initialize_jit_system():
|
|
949
|
+
"""Initialize JIT Context Loading System"""
|
|
950
|
+
logger.info("Initializing JIT Context Loading System...")
|
|
951
|
+
|
|
952
|
+
stats = get_jit_stats()
|
|
953
|
+
logger.info(f"JIT System initialized with {stats['skill_filter']['total_skills']} skills")
|
|
954
|
+
logger.info(f"Cache configured: {stats['cache']['entries']} entries, {stats['cache']['memory_usage_mb']:.1f}MB")
|
|
955
|
+
|
|
956
|
+
return True
|