code-muse 0.0.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.
- code_muse/__init__.py +26 -0
- code_muse/__main__.py +10 -0
- code_muse/agents/__init__.py +31 -0
- code_muse/agents/_builder.py +214 -0
- code_muse/agents/_compaction.py +506 -0
- code_muse/agents/_diagnostics.py +171 -0
- code_muse/agents/_history.py +382 -0
- code_muse/agents/_key_listeners.py +148 -0
- code_muse/agents/_non_streaming_render.py +148 -0
- code_muse/agents/_runtime.py +596 -0
- code_muse/agents/agent_creator_agent.py +603 -0
- code_muse/agents/agent_helios.py +47 -0
- code_muse/agents/agent_manager.py +740 -0
- code_muse/agents/agent_muse.py +78 -0
- code_muse/agents/agent_planning.py +44 -0
- code_muse/agents/agent_qa_melpomene.py +207 -0
- code_muse/agents/base_agent.py +194 -0
- code_muse/agents/event_stream_handler.py +361 -0
- code_muse/agents/json_agent.py +201 -0
- code_muse/agents/prompt_v3.py +521 -0
- code_muse/agents/subagent_stream_handler.py +273 -0
- code_muse/callbacks.py +941 -0
- code_muse/chatgpt_codex_client.py +333 -0
- code_muse/claude_cache_client.py +853 -0
- code_muse/cli_runner/__init__.py +319 -0
- code_muse/cli_runner/args.py +63 -0
- code_muse/cli_runner/loop.py +510 -0
- code_muse/cli_runner/resume.py +72 -0
- code_muse/cli_runner/runner.py +161 -0
- code_muse/command_line/__init__.py +1 -0
- code_muse/command_line/add_model_menu.py +1331 -0
- code_muse/command_line/agent_menu.py +674 -0
- code_muse/command_line/attachments.py +397 -0
- code_muse/command_line/autosave_menu.py +709 -0
- code_muse/command_line/clipboard.py +528 -0
- code_muse/command_line/colors_menu.py +530 -0
- code_muse/command_line/command_handler.py +262 -0
- code_muse/command_line/command_registry.py +150 -0
- code_muse/command_line/config_commands.py +711 -0
- code_muse/command_line/core_commands.py +740 -0
- code_muse/command_line/diff_menu.py +865 -0
- code_muse/command_line/file_path_completion.py +73 -0
- code_muse/command_line/load_context_completion.py +57 -0
- code_muse/command_line/model_picker_completion.py +512 -0
- code_muse/command_line/model_settings_menu.py +983 -0
- code_muse/command_line/onboarding_slides.py +162 -0
- code_muse/command_line/onboarding_wizard.py +337 -0
- code_muse/command_line/pagination.py +41 -0
- code_muse/command_line/pin_command_completion.py +329 -0
- code_muse/command_line/prompt_toolkit_completion.py +886 -0
- code_muse/command_line/session_commands.py +304 -0
- code_muse/command_line/shell_passthrough.py +145 -0
- code_muse/command_line/skills_completion.py +158 -0
- code_muse/command_line/types.py +18 -0
- code_muse/command_line/uc_menu.py +908 -0
- code_muse/command_line/utils.py +105 -0
- code_muse/command_line/wiggum_state.py +77 -0
- code_muse/config.py +1138 -0
- code_muse/config_agent.py +168 -0
- code_muse/config_appearance.py +241 -0
- code_muse/config_model.py +357 -0
- code_muse/config_security.py +73 -0
- code_muse/error_logging.py +132 -0
- code_muse/evals/__init__.py +35 -0
- code_muse/evals/eval_helpers.py +81 -0
- code_muse/evals/eval_runner.py +299 -0
- code_muse/evals/sample_evals/__init__.py +1 -0
- code_muse/evals/sample_evals/eval_frugal_reads.py +59 -0
- code_muse/evals/sample_evals/eval_memory_planning.py +31 -0
- code_muse/evals/sample_evals/eval_shell_efficiency.py +39 -0
- code_muse/evals/sample_evals/eval_tool_masking.py +33 -0
- code_muse/fs_scan_cache/__init__.py +31 -0
- code_muse/fs_scan_cache/invalidation_hooks.py +89 -0
- code_muse/fs_scan_cache/scan_cache_core.cpython-314-darwin.so +0 -0
- code_muse/fs_scan_cache/scan_cache_core.pyx +203 -0
- code_muse/fs_scan_cache/tool_integration.py +309 -0
- code_muse/fs_scan_cache/ttl_policy.py +44 -0
- code_muse/gemini_code_assist.py +383 -0
- code_muse/gemini_model.py +838 -0
- code_muse/hook_engine/README.md +105 -0
- code_muse/hook_engine/__init__.py +21 -0
- code_muse/hook_engine/aliases.py +153 -0
- code_muse/hook_engine/engine.py +221 -0
- code_muse/hook_engine/executor.py +347 -0
- code_muse/hook_engine/matcher.py +154 -0
- code_muse/hook_engine/models.py +245 -0
- code_muse/hook_engine/registry.py +114 -0
- code_muse/hook_engine/trust.py +268 -0
- code_muse/hook_engine/validator.py +144 -0
- code_muse/http_utils.py +360 -0
- code_muse/keymap.py +128 -0
- code_muse/list_filtering.py +26 -0
- code_muse/main.py +10 -0
- code_muse/messaging/__init__.py +259 -0
- code_muse/messaging/bus.py +621 -0
- code_muse/messaging/commands.py +166 -0
- code_muse/messaging/markdown_patches.py +57 -0
- code_muse/messaging/message_queue.py +397 -0
- code_muse/messaging/messages.py +591 -0
- code_muse/messaging/queue_console.py +269 -0
- code_muse/messaging/renderers.py +308 -0
- code_muse/messaging/rich_renderer.py +1158 -0
- code_muse/messaging/shimmer.py +154 -0
- code_muse/messaging/spinner/__init__.py +87 -0
- code_muse/messaging/spinner/console_spinner.py +250 -0
- code_muse/messaging/spinner/spinner_base.py +82 -0
- code_muse/messaging/subagent_console.py +458 -0
- code_muse/model_factory.py +1203 -0
- code_muse/model_switching.py +59 -0
- code_muse/model_utils.py +156 -0
- code_muse/models.json +66 -0
- code_muse/models_cache/__init__.py +26 -0
- code_muse/models_cache/blocking_lru_cache.py +98 -0
- code_muse/models_cache/cache_writer.py +86 -0
- code_muse/models_cache/sha256_hash.cpython-314-darwin.so +0 -0
- code_muse/models_cache/sha256_hash.pyx +34 -0
- code_muse/models_cache/startup_integration.py +75 -0
- code_muse/models_dev_api.json +1 -0
- code_muse/models_dev_parser.py +590 -0
- code_muse/motion.py +126 -0
- code_muse/plugins/__init__.py +471 -0
- code_muse/plugins/agent_skills/__init__.py +32 -0
- code_muse/plugins/agent_skills/config.py +176 -0
- code_muse/plugins/agent_skills/discovery.py +309 -0
- code_muse/plugins/agent_skills/downloader.py +389 -0
- code_muse/plugins/agent_skills/installer.py +19 -0
- code_muse/plugins/agent_skills/metadata.py +293 -0
- code_muse/plugins/agent_skills/prompt_builder.py +66 -0
- code_muse/plugins/agent_skills/register_callbacks.py +298 -0
- code_muse/plugins/agent_skills/remote_catalog.py +320 -0
- code_muse/plugins/agent_skills/skill_catalog.py +254 -0
- code_muse/plugins/agent_skills/skills_install_menu.py +690 -0
- code_muse/plugins/agent_skills/skills_menu.py +791 -0
- code_muse/plugins/autonomous_memory/__init__.py +39 -0
- code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-darwin.so +0 -0
- code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/autonomous_memory/bm25_scorer.pyx +291 -0
- code_muse/plugins/autonomous_memory/consolidation.py +82 -0
- code_muse/plugins/autonomous_memory/extraction.py +382 -0
- code_muse/plugins/autonomous_memory/lease_lock.py +105 -0
- code_muse/plugins/autonomous_memory/memory_injection.py +59 -0
- code_muse/plugins/autonomous_memory/register_callbacks.py +268 -0
- code_muse/plugins/autonomous_memory/secret_scanner.py +62 -0
- code_muse/plugins/autonomous_memory/session_scanner.py +163 -0
- code_muse/plugins/aws_bedrock/__init__.py +14 -0
- code_muse/plugins/aws_bedrock/config.py +99 -0
- code_muse/plugins/aws_bedrock/register_callbacks.py +241 -0
- code_muse/plugins/aws_bedrock/utils.py +153 -0
- code_muse/plugins/azure_foundry/README.md +238 -0
- code_muse/plugins/azure_foundry/__init__.py +15 -0
- code_muse/plugins/azure_foundry/config.py +125 -0
- code_muse/plugins/azure_foundry/discovery.py +187 -0
- code_muse/plugins/azure_foundry/register_callbacks.py +495 -0
- code_muse/plugins/azure_foundry/token.py +180 -0
- code_muse/plugins/azure_foundry/utils.py +345 -0
- code_muse/plugins/build_filter/__init__.py +1 -0
- code_muse/plugins/build_filter/register_callbacks.py +201 -0
- code_muse/plugins/build_filter/strategies/__init__.py +1 -0
- code_muse/plugins/build_filter/strategies/build.py +397 -0
- code_muse/plugins/chatgpt_oauth/__init__.py +6 -0
- code_muse/plugins/chatgpt_oauth/config.py +52 -0
- code_muse/plugins/chatgpt_oauth/oauth_flow.py +338 -0
- code_muse/plugins/chatgpt_oauth/register_callbacks.py +172 -0
- code_muse/plugins/chatgpt_oauth/test_plugin.py +301 -0
- code_muse/plugins/chatgpt_oauth/utils.py +538 -0
- code_muse/plugins/checkpointing/__init__.py +29 -0
- code_muse/plugins/checkpointing/checkpoint_hook.py +51 -0
- code_muse/plugins/checkpointing/conversation_snapshots.py +117 -0
- code_muse/plugins/checkpointing/register_callbacks.py +51 -0
- code_muse/plugins/checkpointing/restore_command.py +263 -0
- code_muse/plugins/checkpointing/rewind_shortcut.py +88 -0
- code_muse/plugins/checkpointing/shadow_git.py +90 -0
- code_muse/plugins/claude_code_hooks/__init__.py +1 -0
- code_muse/plugins/claude_code_hooks/config.py +188 -0
- code_muse/plugins/claude_code_hooks/register_callbacks.py +208 -0
- code_muse/plugins/claude_code_oauth/README.md +167 -0
- code_muse/plugins/claude_code_oauth/SETUP.md +93 -0
- code_muse/plugins/claude_code_oauth/__init__.py +25 -0
- code_muse/plugins/claude_code_oauth/config.py +52 -0
- code_muse/plugins/claude_code_oauth/fast_mode.py +124 -0
- code_muse/plugins/claude_code_oauth/prompt_handler.py +63 -0
- code_muse/plugins/claude_code_oauth/register_callbacks.py +547 -0
- code_muse/plugins/claude_code_oauth/test_fast_mode.py +165 -0
- code_muse/plugins/claude_code_oauth/test_plugin.py +283 -0
- code_muse/plugins/claude_code_oauth/token_refresh_heartbeat.py +237 -0
- code_muse/plugins/claude_code_oauth/utils.py +664 -0
- code_muse/plugins/copilot_auth/__init__.py +11 -0
- code_muse/plugins/copilot_auth/config.py +91 -0
- code_muse/plugins/copilot_auth/reasoning_client.py +409 -0
- code_muse/plugins/copilot_auth/register_callbacks.py +461 -0
- code_muse/plugins/copilot_auth/utils.py +584 -0
- code_muse/plugins/custom_commands/__init__.py +14 -0
- code_muse/plugins/custom_commands/args_injection.py +82 -0
- code_muse/plugins/custom_commands/command_discovery.py +89 -0
- code_muse/plugins/custom_commands/command_toml_schema.py +71 -0
- code_muse/plugins/custom_commands/register_callbacks.py +176 -0
- code_muse/plugins/customizable_commands/__init__.py +0 -0
- code_muse/plugins/customizable_commands/register_callbacks.py +136 -0
- code_muse/plugins/destructive_command_guard/__init__.py +14 -0
- code_muse/plugins/destructive_command_guard/detector.py +375 -0
- code_muse/plugins/destructive_command_guard/register_callbacks.py +148 -0
- code_muse/plugins/example_custom_command/README.md +280 -0
- code_muse/plugins/example_custom_command/register_callbacks.py +51 -0
- code_muse/plugins/file_permission_handler/__init__.py +4 -0
- code_muse/plugins/file_permission_handler/register_callbacks.py +441 -0
- code_muse/plugins/filter_engine/__init__.py +30 -0
- code_muse/plugins/filter_engine/classifier.py +153 -0
- code_muse/plugins/filter_engine/content_detector.py +184 -0
- code_muse/plugins/filter_engine/dispatcher.py +244 -0
- code_muse/plugins/filter_engine/register_callbacks.py +188 -0
- code_muse/plugins/filter_engine/registry.py +279 -0
- code_muse/plugins/filter_engine/strategies/__init__.py +8 -0
- code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/ast_compressor.pyx +348 -0
- code_muse/plugins/filter_engine/strategies/ast_parser.py +167 -0
- code_muse/plugins/filter_engine/strategies/code.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/code.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/code.pyx +584 -0
- code_muse/plugins/filter_engine/strategies/git.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/git.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/git.pyx +438 -0
- code_muse/plugins/filter_engine/strategies/json_compressor.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/json_compressor.pyx +253 -0
- code_muse/plugins/filter_engine/strategies/json_patterns.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/json_patterns.pyx +178 -0
- code_muse/plugins/filter_engine/strategies/lint.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/lint.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/lint.pyx +626 -0
- code_muse/plugins/filter_engine/strategies/test.cpython-314-darwin.so +0 -0
- code_muse/plugins/filter_engine/strategies/test.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/plugins/filter_engine/strategies/test.pyx +431 -0
- code_muse/plugins/filter_engine/verbosity.py +63 -0
- code_muse/plugins/force_push_guard/__init__.py +5 -0
- code_muse/plugins/force_push_guard/detector.py +96 -0
- code_muse/plugins/force_push_guard/register_callbacks.py +144 -0
- code_muse/plugins/force_push_guard/test_detector.py +143 -0
- code_muse/plugins/frontend_emitter/__init__.py +25 -0
- code_muse/plugins/frontend_emitter/emitter.py +121 -0
- code_muse/plugins/frontend_emitter/register_callbacks.py +259 -0
- code_muse/plugins/gac/__init__.py +4 -0
- code_muse/plugins/gac/git_ops.py +136 -0
- code_muse/plugins/gac/prompt.py +191 -0
- code_muse/plugins/gac/register_callbacks.py +82 -0
- code_muse/plugins/hook_creator/__init__.py +1 -0
- code_muse/plugins/hook_creator/register_callbacks.py +34 -0
- code_muse/plugins/hook_manager/__init__.py +1 -0
- code_muse/plugins/hook_manager/config.py +289 -0
- code_muse/plugins/hook_manager/hooks_menu.py +563 -0
- code_muse/plugins/hook_manager/register_callbacks.py +227 -0
- code_muse/plugins/hook_monitor/register_callbacks.py +36 -0
- code_muse/plugins/mindpack/__init__.py +0 -0
- code_muse/plugins/mindpack/factory.py +930 -0
- code_muse/plugins/mindpack/judge.py +573 -0
- code_muse/plugins/mindpack/memory.py +100 -0
- code_muse/plugins/mindpack/mindpack_menu.py +1552 -0
- code_muse/plugins/mindpack/orchestration.py +605 -0
- code_muse/plugins/mindpack/register_callbacks.py +175 -0
- code_muse/plugins/mindpack/schemas.py +358 -0
- code_muse/plugins/mindpack/tools.py +387 -0
- code_muse/plugins/oauth_muse_html.py +226 -0
- code_muse/plugins/ollama_setup/__init__.py +5 -0
- code_muse/plugins/ollama_setup/completer.py +36 -0
- code_muse/plugins/ollama_setup/register_callbacks.py +410 -0
- code_muse/plugins/plan_command/__init__.py +0 -0
- code_muse/plugins/plan_command/register_callbacks.py +206 -0
- code_muse/plugins/plan_mode/__init__.py +37 -0
- code_muse/plugins/plan_mode/mode_cycling.py +40 -0
- code_muse/plugins/plan_mode/plan_generation.py +68 -0
- code_muse/plugins/plan_mode/plan_hooks.py +74 -0
- code_muse/plugins/plan_mode/plan_mode_tools.py +138 -0
- code_muse/plugins/plan_mode/register_callbacks.py +121 -0
- code_muse/plugins/plugin_trust/register_callbacks.py +140 -0
- code_muse/plugins/policy_engine/__init__.py +46 -0
- code_muse/plugins/policy_engine/approval_flow_integration.py +59 -0
- code_muse/plugins/policy_engine/policy_evaluator.py +75 -0
- code_muse/plugins/policy_engine/policy_file_discovery.py +90 -0
- code_muse/plugins/policy_engine/policy_toml_schema.py +115 -0
- code_muse/plugins/policy_engine/register_callbacks.py +112 -0
- code_muse/plugins/pop_command/__init__.py +1 -0
- code_muse/plugins/pop_command/register_callbacks.py +189 -0
- code_muse/plugins/prompt_newline/__init__.py +13 -0
- code_muse/plugins/prompt_newline/config.py +19 -0
- code_muse/plugins/prompt_newline/register_callbacks.py +159 -0
- code_muse/plugins/safety_status/__init__.py +0 -0
- code_muse/plugins/safety_status/register_callbacks.py +113 -0
- code_muse/plugins/semantic_compression/__init__.py +6 -0
- code_muse/plugins/semantic_compression/compressor.py +295 -0
- code_muse/plugins/semantic_compression/config.py +123 -0
- code_muse/plugins/semantic_compression/register_callbacks.py +320 -0
- code_muse/plugins/shell_minimizer/__init__.py +50 -0
- code_muse/plugins/shell_minimizer/builtin_filters.toml +393 -0
- code_muse/plugins/shell_minimizer/pipeline.py +556 -0
- code_muse/plugins/shell_minimizer/primitives.py +482 -0
- code_muse/plugins/shell_minimizer/register_callbacks.py +276 -0
- code_muse/plugins/shell_safety/__init__.py +6 -0
- code_muse/plugins/shell_safety/agent_shell_safety.py +69 -0
- code_muse/plugins/shell_safety/command_cache.py +149 -0
- code_muse/plugins/shell_safety/register_callbacks.py +202 -0
- code_muse/plugins/synthetic_status/__init__.py +1 -0
- code_muse/plugins/synthetic_status/register_callbacks.py +128 -0
- code_muse/plugins/synthetic_status/status_api.py +145 -0
- code_muse/plugins/token_caching/__init__.py +21 -0
- code_muse/plugins/token_caching/cache_hit_tracking.py +128 -0
- code_muse/plugins/token_caching/cacheable_prefix_detection.py +28 -0
- code_muse/plugins/token_caching/register_callbacks.py +54 -0
- code_muse/plugins/token_caching/stats_display.py +35 -0
- code_muse/plugins/token_tracking/__init__.py +26 -0
- code_muse/plugins/token_tracking/database.py +381 -0
- code_muse/plugins/token_tracking/edit_analyzer.py +97 -0
- code_muse/plugins/token_tracking/record.py +55 -0
- code_muse/plugins/token_tracking/register_callbacks.py +277 -0
- code_muse/plugins/token_tracking/reports.py +329 -0
- code_muse/plugins/universal_constructor/__init__.py +13 -0
- code_muse/plugins/universal_constructor/models.py +136 -0
- code_muse/plugins/universal_constructor/register_callbacks.py +47 -0
- code_muse/plugins/universal_constructor/registry.py +390 -0
- code_muse/plugins/universal_constructor/runner.py +474 -0
- code_muse/plugins/universal_constructor/safety.py +440 -0
- code_muse/plugins/universal_constructor/sandbox.py +584 -0
- code_muse/provider_identity.py +105 -0
- code_muse/pydantic_patches.py +410 -0
- code_muse/reopenable_async_client.py +233 -0
- code_muse/round_robin_model.py +151 -0
- code_muse/secret_storage.py +74 -0
- code_muse/security/__init__.py +1 -0
- code_muse/security/redaction.cpython-314-darwin.so +0 -0
- code_muse/security/redaction.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/security/redaction.pyx +135 -0
- code_muse/session_storage.py +565 -0
- code_muse/status_display.py +261 -0
- code_muse/stream_parser/__init__.py +76 -0
- code_muse/stream_parser/assistant_text_parser.py +90 -0
- code_muse/stream_parser/citation_parser.py +76 -0
- code_muse/stream_parser/inline_hidden_tag_parser.py +236 -0
- code_muse/stream_parser/proposed_plan_parser.py +158 -0
- code_muse/stream_parser/stream_text_chunk.py +23 -0
- code_muse/stream_parser/stream_text_parser.py +27 -0
- code_muse/stream_parser/tagged_line_parser.cpython-314-darwin.so +0 -0
- code_muse/stream_parser/tagged_line_parser.pyx +251 -0
- code_muse/stream_parser/utf8_stream_parser.cpython-314-darwin.so +0 -0
- code_muse/stream_parser/utf8_stream_parser.pyx +206 -0
- code_muse/summarization_agent.py +308 -0
- code_muse/terminal_utils.cpython-314-darwin.so +0 -0
- code_muse/terminal_utils.cpython-314-x86_64-linux-gnu.so +0 -0
- code_muse/terminal_utils.pyx +483 -0
- code_muse/tools/__init__.py +459 -0
- code_muse/tools/agent_tools.py +613 -0
- code_muse/tools/ask_user_question/__init__.py +26 -0
- code_muse/tools/ask_user_question/constants.py +73 -0
- code_muse/tools/ask_user_question/demo_tui.py +55 -0
- code_muse/tools/ask_user_question/handler.py +232 -0
- code_muse/tools/ask_user_question/models.py +302 -0
- code_muse/tools/ask_user_question/registration.py +37 -0
- code_muse/tools/ask_user_question/renderers.py +336 -0
- code_muse/tools/ask_user_question/terminal_ui.py +327 -0
- code_muse/tools/ask_user_question/theme.py +156 -0
- code_muse/tools/ask_user_question/tui_loop.py +422 -0
- code_muse/tools/background_jobs.py +99 -0
- code_muse/tools/browser/__init__.py +37 -0
- code_muse/tools/browser/browser_control.py +289 -0
- code_muse/tools/browser/browser_interactions.py +545 -0
- code_muse/tools/browser/browser_locators.py +640 -0
- code_muse/tools/browser/browser_manager.py +376 -0
- code_muse/tools/browser/browser_navigation.py +251 -0
- code_muse/tools/browser/browser_screenshot.py +180 -0
- code_muse/tools/browser/browser_scripts.py +462 -0
- code_muse/tools/browser/browser_workflows.py +222 -0
- code_muse/tools/chrome_cdp/__init__.py +1070 -0
- code_muse/tools/chrome_cdp/register_callbacks.py +61 -0
- code_muse/tools/command_runner.py +1401 -0
- code_muse/tools/common.py +1407 -0
- code_muse/tools/display.py +87 -0
- code_muse/tools/file_modifications.py +1099 -0
- code_muse/tools/file_operations.py +860 -0
- code_muse/tools/image_tools.py +185 -0
- code_muse/tools/meetin_proxy/__init__.py +243 -0
- code_muse/tools/meetin_proxy/capture_addon.py +82 -0
- code_muse/tools/meetin_proxy/proxy_manager.py +326 -0
- code_muse/tools/meetin_proxy/register_callbacks.py +45 -0
- code_muse/tools/path_policy.py +219 -0
- code_muse/tools/skills_tools.py +586 -0
- code_muse/tools/subagent_context.py +158 -0
- code_muse/tools/tools_content.py +50 -0
- code_muse/tools/universal_constructor.py +965 -0
- code_muse/uvx_detection.py +241 -0
- code_muse/version_checker.py +86 -0
- code_muse-0.0.1.data/data/code_muse/models.json +66 -0
- code_muse-0.0.1.data/data/code_muse/models_dev_api.json +1 -0
- code_muse-0.0.1.dist-info/METADATA +845 -0
- code_muse-0.0.1.dist-info/RECORD +394 -0
- code_muse-0.0.1.dist-info/WHEEL +4 -0
- code_muse-0.0.1.dist-info/entry_points.txt +2 -0
- code_muse-0.0.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from collections.abc import AsyncIterator
|
|
3
|
+
from contextlib import asynccontextmanager, suppress
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from pydantic_ai._run_context import RunContext
|
|
8
|
+
from pydantic_ai.models import (
|
|
9
|
+
Model,
|
|
10
|
+
ModelMessage,
|
|
11
|
+
ModelRequestParameters,
|
|
12
|
+
ModelResponse,
|
|
13
|
+
ModelSettings,
|
|
14
|
+
StreamedResponse,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
from opentelemetry.context import get_current_span
|
|
19
|
+
except ImportError:
|
|
20
|
+
# If opentelemetry is not installed, provide a dummy implementation
|
|
21
|
+
def get_current_span():
|
|
22
|
+
class DummySpan:
|
|
23
|
+
def is_recording(self):
|
|
24
|
+
return False
|
|
25
|
+
|
|
26
|
+
def set_attributes(self, attributes):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
return DummySpan()
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(init=False)
|
|
33
|
+
class RoundRobinModel(Model):
|
|
34
|
+
"""A model that cycles through multiple models in a round-robin fashion.
|
|
35
|
+
|
|
36
|
+
This model distributes requests across multiple candidate models to help
|
|
37
|
+
overcome rate limits or distribute load.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
models: list[Model]
|
|
41
|
+
_current_index: int = field(default=0, repr=False)
|
|
42
|
+
_model_name: str = field(repr=False)
|
|
43
|
+
_rotate_every: int = field(default=1, repr=False)
|
|
44
|
+
_request_count: int = field(default=0, repr=False)
|
|
45
|
+
_lock: asyncio.Lock = field(default_factory=asyncio.Lock, repr=False)
|
|
46
|
+
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
*models: Model,
|
|
50
|
+
rotate_every: int = 1,
|
|
51
|
+
settings: ModelSettings | None = None,
|
|
52
|
+
):
|
|
53
|
+
"""Initialize a round-robin model instance.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
models: The model instances to cycle through.
|
|
57
|
+
rotate_every: Number of requests before rotating to the next model (default: 1).
|
|
58
|
+
settings: Model settings that will be used as defaults for this model.
|
|
59
|
+
"""
|
|
60
|
+
super().__init__(settings=settings)
|
|
61
|
+
if not models:
|
|
62
|
+
raise ValueError("At least one model must be provided")
|
|
63
|
+
if rotate_every < 1:
|
|
64
|
+
raise ValueError("rotate_every must be at least 1")
|
|
65
|
+
self.models = list(models)
|
|
66
|
+
self._current_index = 0
|
|
67
|
+
self._request_count = 0
|
|
68
|
+
self._rotate_every = rotate_every
|
|
69
|
+
self._lock = asyncio.Lock()
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def model_name(self) -> str:
|
|
73
|
+
"""The model name showing this is a round-robin model with its candidates."""
|
|
74
|
+
base_name = f"round_robin:{','.join(model.model_name for model in self.models)}"
|
|
75
|
+
if self._rotate_every != 1:
|
|
76
|
+
return f"{base_name}:rotate_every={self._rotate_every}"
|
|
77
|
+
return base_name
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def system(self) -> str:
|
|
81
|
+
"""System prompt from the current model."""
|
|
82
|
+
return self.models[self._current_index].system
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def base_url(self) -> str | None:
|
|
86
|
+
"""Base URL from the current model."""
|
|
87
|
+
return self.models[self._current_index].base_url
|
|
88
|
+
|
|
89
|
+
async def _get_next_model(self) -> Model:
|
|
90
|
+
"""Get the next model in the round-robin sequence and update the index."""
|
|
91
|
+
async with self._lock:
|
|
92
|
+
model = self.models[self._current_index]
|
|
93
|
+
self._request_count += 1
|
|
94
|
+
if self._request_count >= self._rotate_every:
|
|
95
|
+
self._current_index = (self._current_index + 1) % len(self.models)
|
|
96
|
+
self._request_count = 0
|
|
97
|
+
return model
|
|
98
|
+
|
|
99
|
+
async def request(
|
|
100
|
+
self,
|
|
101
|
+
messages: list[ModelMessage],
|
|
102
|
+
model_settings: ModelSettings | None,
|
|
103
|
+
model_request_parameters: ModelRequestParameters,
|
|
104
|
+
) -> ModelResponse:
|
|
105
|
+
"""Make a request using the next model in the round-robin sequence."""
|
|
106
|
+
current_model = await self._get_next_model()
|
|
107
|
+
# Use prepare_request to merge settings and customize parameters
|
|
108
|
+
merged_settings, prepared_params = current_model.prepare_request(
|
|
109
|
+
model_settings, model_request_parameters
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
try:
|
|
113
|
+
response = await current_model.request(
|
|
114
|
+
messages, merged_settings, prepared_params
|
|
115
|
+
)
|
|
116
|
+
self._set_span_attributes(current_model)
|
|
117
|
+
return response
|
|
118
|
+
except Exception:
|
|
119
|
+
# Unlike FallbackModel, we don't try other models here
|
|
120
|
+
# The round-robin strategy is about distribution, not failover
|
|
121
|
+
raise
|
|
122
|
+
|
|
123
|
+
@asynccontextmanager
|
|
124
|
+
async def request_stream(
|
|
125
|
+
self,
|
|
126
|
+
messages: list[ModelMessage],
|
|
127
|
+
model_settings: ModelSettings | None,
|
|
128
|
+
model_request_parameters: ModelRequestParameters,
|
|
129
|
+
run_context: RunContext[Any] | None = None,
|
|
130
|
+
) -> AsyncIterator[StreamedResponse]:
|
|
131
|
+
"""Make a streaming request using the next model in the round-robin sequence."""
|
|
132
|
+
current_model = await self._get_next_model()
|
|
133
|
+
# Use prepare_request to merge settings and customize parameters
|
|
134
|
+
merged_settings, prepared_params = current_model.prepare_request(
|
|
135
|
+
model_settings, model_request_parameters
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
async with current_model.request_stream(
|
|
139
|
+
messages, merged_settings, prepared_params, run_context
|
|
140
|
+
) as response:
|
|
141
|
+
self._set_span_attributes(current_model)
|
|
142
|
+
yield response
|
|
143
|
+
|
|
144
|
+
def _set_span_attributes(self, model: Model):
|
|
145
|
+
"""Set span attributes for observability."""
|
|
146
|
+
with suppress(Exception):
|
|
147
|
+
span = get_current_span()
|
|
148
|
+
if span.is_recording():
|
|
149
|
+
attributes = getattr(span, "attributes", {})
|
|
150
|
+
if attributes.get("gen_ai.request.model") == self.model_name:
|
|
151
|
+
span.set_attributes(model.model_attributes(model))
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""Atomic private file storage helpers for sensitive data.
|
|
2
|
+
|
|
3
|
+
Implements fail-closed helpers that create files with restrictive permissions
|
|
4
|
+
from the start, fsync before rename, and warn when existing files are too
|
|
5
|
+
broadly permissioned.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import json
|
|
9
|
+
import logging
|
|
10
|
+
import os
|
|
11
|
+
import stat
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
from typing import Any
|
|
14
|
+
|
|
15
|
+
logger = logging.getLogger(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def ensure_private_dir(path: Path) -> Path:
|
|
19
|
+
"""Create *path* (and parents) with mode ``0o700``.
|
|
20
|
+
|
|
21
|
+
If the directory already exists its mode is corrected if necessary.
|
|
22
|
+
"""
|
|
23
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
24
|
+
os.chmod(path, 0o700)
|
|
25
|
+
return path
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def atomic_write_private_bytes(path: Path, data: bytes) -> None:
|
|
29
|
+
"""Atomically write *data* to *path* with mode ``0o600``.
|
|
30
|
+
|
|
31
|
+
Uses a temporary sibling file created with ``O_CREAT | O_EXCL`` so there
|
|
32
|
+
is no race window where another observer can open the file before the
|
|
33
|
+
mode is set. After writing, ``fsync`` flushes data to disk and
|
|
34
|
+
``os.replace`` atomically moves the temp file into place.
|
|
35
|
+
"""
|
|
36
|
+
tmp_path = Path(str(path) + ".tmp")
|
|
37
|
+
fd: int | None = None
|
|
38
|
+
try:
|
|
39
|
+
fd = os.open(
|
|
40
|
+
str(tmp_path),
|
|
41
|
+
os.O_CREAT | os.O_EXCL | os.O_WRONLY,
|
|
42
|
+
0o600,
|
|
43
|
+
)
|
|
44
|
+
os.write(fd, data)
|
|
45
|
+
os.fsync(fd)
|
|
46
|
+
finally:
|
|
47
|
+
if fd is not None:
|
|
48
|
+
os.close(fd)
|
|
49
|
+
os.replace(str(tmp_path), path)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def atomic_write_private_json(path: Path, data: dict[str, Any]) -> None:
|
|
53
|
+
"""Atomically write a JSON object to *path* with mode ``0o600``."""
|
|
54
|
+
payload = json.dumps(data, indent=2).encode("utf-8")
|
|
55
|
+
atomic_write_private_bytes(path, payload)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def warn_or_fix_private_file_mode(path: Path, expected_mode: int = 0o600) -> None:
|
|
59
|
+
"""Check *path* permissions and fix them if they are too broad.
|
|
60
|
+
|
|
61
|
+
Emits a warning when the mode differs from *expected_mode* so operators
|
|
62
|
+
know the file was created by an older version or another process.
|
|
63
|
+
"""
|
|
64
|
+
if not path.exists():
|
|
65
|
+
return
|
|
66
|
+
current_mode = stat.S_IMODE(path.stat().st_mode)
|
|
67
|
+
if current_mode != expected_mode:
|
|
68
|
+
logger.warning(
|
|
69
|
+
"File %s has mode %04o; fixing to %04o",
|
|
70
|
+
path,
|
|
71
|
+
current_mode,
|
|
72
|
+
expected_mode,
|
|
73
|
+
)
|
|
74
|
+
path.chmod(expected_mode)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Security helpers for Muse."""
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# cython: language_level=3
|
|
2
|
+
"""Redaction helpers to prevent secret leakage in logs and output."""
|
|
3
|
+
|
|
4
|
+
import json
|
|
5
|
+
import re
|
|
6
|
+
import urllib.parse
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
# Keys whose values should always be redacted in structured data.
|
|
10
|
+
SENSITIVE_KEYS: frozenset = frozenset(
|
|
11
|
+
{
|
|
12
|
+
"access_token",
|
|
13
|
+
"refresh_token",
|
|
14
|
+
"id_token",
|
|
15
|
+
"api_key",
|
|
16
|
+
"code",
|
|
17
|
+
"code_verifier",
|
|
18
|
+
"code_challenge",
|
|
19
|
+
"client_secret",
|
|
20
|
+
"client_id",
|
|
21
|
+
"password",
|
|
22
|
+
"token",
|
|
23
|
+
"secret",
|
|
24
|
+
"authorization",
|
|
25
|
+
"bearer",
|
|
26
|
+
"apikey",
|
|
27
|
+
"auth_token",
|
|
28
|
+
"session_token",
|
|
29
|
+
"csrf_token",
|
|
30
|
+
}
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
REDACTED = "<redacted>"
|
|
34
|
+
|
|
35
|
+
# Pre-compiled regex patterns for performance.
|
|
36
|
+
cdef object _BEARER_HEADER_RE = re.compile(
|
|
37
|
+
r"(?i)(authorization\s*:\s*bearer\s+)\S+"
|
|
38
|
+
)
|
|
39
|
+
cdef object _BEARER_STANDALONE_RE = re.compile(r"(?i)(bearer\s+)\S+")
|
|
40
|
+
cdef object _ENV_ASSIGNMENT_RE = re.compile(
|
|
41
|
+
r"(?i)([A-Z_]*(?:API_KEY|SECRET|TOKEN|PASSWORD|AUTH|CREDENTIALS)[A-Z_]*=)(.+?)(?=[\s&]+[A-Z_][A-Z0-9_]+=|$)"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
cdef bint _is_sensitive_key(str key):
|
|
46
|
+
return key.lower() in SENSITIVE_KEYS
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
cpdef str _redact_url_query_params(str value):
|
|
50
|
+
cdef object parsed
|
|
51
|
+
cdef dict qs
|
|
52
|
+
cdef bint redacted = False
|
|
53
|
+
cdef str k
|
|
54
|
+
try:
|
|
55
|
+
parsed = urllib.parse.urlparse(value)
|
|
56
|
+
if not parsed.query:
|
|
57
|
+
return value
|
|
58
|
+
qs = urllib.parse.parse_qs(parsed.query)
|
|
59
|
+
for k in list(qs):
|
|
60
|
+
if _is_sensitive_key(k):
|
|
61
|
+
qs[k] = [REDACTED]
|
|
62
|
+
redacted = True
|
|
63
|
+
if redacted:
|
|
64
|
+
new_query = urllib.parse.urlencode(qs, doseq=True)
|
|
65
|
+
return urllib.parse.urlunparse(parsed._replace(query=new_query))
|
|
66
|
+
except Exception:
|
|
67
|
+
pass
|
|
68
|
+
return value
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
cpdef str _redact_bearer_tokens(str value):
|
|
72
|
+
value = _BEARER_HEADER_RE.sub(r"\1" + REDACTED, value)
|
|
73
|
+
value = _BEARER_STANDALONE_RE.sub(r"\1" + REDACTED, value)
|
|
74
|
+
return value
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
cpdef str _redact_env_assignments(str value):
|
|
78
|
+
return _ENV_ASSIGNMENT_RE.sub(r"\1" + REDACTED, value)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
cpdef str _redact_json_string(str value):
|
|
82
|
+
cdef str stripped = value.strip()
|
|
83
|
+
if not stripped.startswith(("{", "[")):
|
|
84
|
+
return value
|
|
85
|
+
try:
|
|
86
|
+
parsed = json.loads(stripped)
|
|
87
|
+
redacted = redact_secrets(parsed)
|
|
88
|
+
return json.dumps(redacted, separators=(",", ":"))
|
|
89
|
+
except Exception:
|
|
90
|
+
return value
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def redact_secrets(value: Any, _parent_key: str = "") -> Any:
|
|
94
|
+
"""Recursively redact secrets from strings, dicts, and lists.
|
|
95
|
+
|
|
96
|
+
Covers:
|
|
97
|
+
- URL query parameters containing sensitive keys
|
|
98
|
+
- JSON/dict keys matching known sensitive names
|
|
99
|
+
- ``Authorization: Bearer ...`` headers
|
|
100
|
+
- OAuth response bodies (via recursive dict redaction)
|
|
101
|
+
- Environment-variable-style assignments of sensitive names
|
|
102
|
+
|
|
103
|
+
Returns deterministic ``<redacted>`` output; never logs token length.
|
|
104
|
+
"""
|
|
105
|
+
cdef str s
|
|
106
|
+
cdef dict d
|
|
107
|
+
cdef list lst
|
|
108
|
+
cdef object k, v
|
|
109
|
+
|
|
110
|
+
if isinstance(value, bytes):
|
|
111
|
+
try:
|
|
112
|
+
return redact_secrets(value.decode("utf-8"))
|
|
113
|
+
except UnicodeDecodeError:
|
|
114
|
+
return REDACTED.encode("utf-8")
|
|
115
|
+
if isinstance(value, str):
|
|
116
|
+
s = value
|
|
117
|
+
s = _redact_bearer_tokens(s)
|
|
118
|
+
s = _redact_url_query_params(s)
|
|
119
|
+
s = _redact_env_assignments(s)
|
|
120
|
+
s = _redact_json_string(s)
|
|
121
|
+
return s
|
|
122
|
+
if isinstance(value, dict):
|
|
123
|
+
d = {}
|
|
124
|
+
for k, v in value.items():
|
|
125
|
+
if _is_sensitive_key(k):
|
|
126
|
+
d[k] = REDACTED
|
|
127
|
+
else:
|
|
128
|
+
d[k] = redact_secrets(v, k)
|
|
129
|
+
return d
|
|
130
|
+
if isinstance(value, list):
|
|
131
|
+
lst = []
|
|
132
|
+
for v in value:
|
|
133
|
+
lst.append(redact_secrets(v, _parent_key))
|
|
134
|
+
return lst
|
|
135
|
+
return value
|