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.
Files changed (394) hide show
  1. code_muse/__init__.py +26 -0
  2. code_muse/__main__.py +10 -0
  3. code_muse/agents/__init__.py +31 -0
  4. code_muse/agents/_builder.py +214 -0
  5. code_muse/agents/_compaction.py +506 -0
  6. code_muse/agents/_diagnostics.py +171 -0
  7. code_muse/agents/_history.py +382 -0
  8. code_muse/agents/_key_listeners.py +148 -0
  9. code_muse/agents/_non_streaming_render.py +148 -0
  10. code_muse/agents/_runtime.py +596 -0
  11. code_muse/agents/agent_creator_agent.py +603 -0
  12. code_muse/agents/agent_helios.py +47 -0
  13. code_muse/agents/agent_manager.py +740 -0
  14. code_muse/agents/agent_muse.py +78 -0
  15. code_muse/agents/agent_planning.py +44 -0
  16. code_muse/agents/agent_qa_melpomene.py +207 -0
  17. code_muse/agents/base_agent.py +194 -0
  18. code_muse/agents/event_stream_handler.py +361 -0
  19. code_muse/agents/json_agent.py +201 -0
  20. code_muse/agents/prompt_v3.py +521 -0
  21. code_muse/agents/subagent_stream_handler.py +273 -0
  22. code_muse/callbacks.py +941 -0
  23. code_muse/chatgpt_codex_client.py +333 -0
  24. code_muse/claude_cache_client.py +853 -0
  25. code_muse/cli_runner/__init__.py +319 -0
  26. code_muse/cli_runner/args.py +63 -0
  27. code_muse/cli_runner/loop.py +510 -0
  28. code_muse/cli_runner/resume.py +72 -0
  29. code_muse/cli_runner/runner.py +161 -0
  30. code_muse/command_line/__init__.py +1 -0
  31. code_muse/command_line/add_model_menu.py +1331 -0
  32. code_muse/command_line/agent_menu.py +674 -0
  33. code_muse/command_line/attachments.py +397 -0
  34. code_muse/command_line/autosave_menu.py +709 -0
  35. code_muse/command_line/clipboard.py +528 -0
  36. code_muse/command_line/colors_menu.py +530 -0
  37. code_muse/command_line/command_handler.py +262 -0
  38. code_muse/command_line/command_registry.py +150 -0
  39. code_muse/command_line/config_commands.py +711 -0
  40. code_muse/command_line/core_commands.py +740 -0
  41. code_muse/command_line/diff_menu.py +865 -0
  42. code_muse/command_line/file_path_completion.py +73 -0
  43. code_muse/command_line/load_context_completion.py +57 -0
  44. code_muse/command_line/model_picker_completion.py +512 -0
  45. code_muse/command_line/model_settings_menu.py +983 -0
  46. code_muse/command_line/onboarding_slides.py +162 -0
  47. code_muse/command_line/onboarding_wizard.py +337 -0
  48. code_muse/command_line/pagination.py +41 -0
  49. code_muse/command_line/pin_command_completion.py +329 -0
  50. code_muse/command_line/prompt_toolkit_completion.py +886 -0
  51. code_muse/command_line/session_commands.py +304 -0
  52. code_muse/command_line/shell_passthrough.py +145 -0
  53. code_muse/command_line/skills_completion.py +158 -0
  54. code_muse/command_line/types.py +18 -0
  55. code_muse/command_line/uc_menu.py +908 -0
  56. code_muse/command_line/utils.py +105 -0
  57. code_muse/command_line/wiggum_state.py +77 -0
  58. code_muse/config.py +1138 -0
  59. code_muse/config_agent.py +168 -0
  60. code_muse/config_appearance.py +241 -0
  61. code_muse/config_model.py +357 -0
  62. code_muse/config_security.py +73 -0
  63. code_muse/error_logging.py +132 -0
  64. code_muse/evals/__init__.py +35 -0
  65. code_muse/evals/eval_helpers.py +81 -0
  66. code_muse/evals/eval_runner.py +299 -0
  67. code_muse/evals/sample_evals/__init__.py +1 -0
  68. code_muse/evals/sample_evals/eval_frugal_reads.py +59 -0
  69. code_muse/evals/sample_evals/eval_memory_planning.py +31 -0
  70. code_muse/evals/sample_evals/eval_shell_efficiency.py +39 -0
  71. code_muse/evals/sample_evals/eval_tool_masking.py +33 -0
  72. code_muse/fs_scan_cache/__init__.py +31 -0
  73. code_muse/fs_scan_cache/invalidation_hooks.py +89 -0
  74. code_muse/fs_scan_cache/scan_cache_core.cpython-314-darwin.so +0 -0
  75. code_muse/fs_scan_cache/scan_cache_core.pyx +203 -0
  76. code_muse/fs_scan_cache/tool_integration.py +309 -0
  77. code_muse/fs_scan_cache/ttl_policy.py +44 -0
  78. code_muse/gemini_code_assist.py +383 -0
  79. code_muse/gemini_model.py +838 -0
  80. code_muse/hook_engine/README.md +105 -0
  81. code_muse/hook_engine/__init__.py +21 -0
  82. code_muse/hook_engine/aliases.py +153 -0
  83. code_muse/hook_engine/engine.py +221 -0
  84. code_muse/hook_engine/executor.py +347 -0
  85. code_muse/hook_engine/matcher.py +154 -0
  86. code_muse/hook_engine/models.py +245 -0
  87. code_muse/hook_engine/registry.py +114 -0
  88. code_muse/hook_engine/trust.py +268 -0
  89. code_muse/hook_engine/validator.py +144 -0
  90. code_muse/http_utils.py +360 -0
  91. code_muse/keymap.py +128 -0
  92. code_muse/list_filtering.py +26 -0
  93. code_muse/main.py +10 -0
  94. code_muse/messaging/__init__.py +259 -0
  95. code_muse/messaging/bus.py +621 -0
  96. code_muse/messaging/commands.py +166 -0
  97. code_muse/messaging/markdown_patches.py +57 -0
  98. code_muse/messaging/message_queue.py +397 -0
  99. code_muse/messaging/messages.py +591 -0
  100. code_muse/messaging/queue_console.py +269 -0
  101. code_muse/messaging/renderers.py +308 -0
  102. code_muse/messaging/rich_renderer.py +1158 -0
  103. code_muse/messaging/shimmer.py +154 -0
  104. code_muse/messaging/spinner/__init__.py +87 -0
  105. code_muse/messaging/spinner/console_spinner.py +250 -0
  106. code_muse/messaging/spinner/spinner_base.py +82 -0
  107. code_muse/messaging/subagent_console.py +458 -0
  108. code_muse/model_factory.py +1203 -0
  109. code_muse/model_switching.py +59 -0
  110. code_muse/model_utils.py +156 -0
  111. code_muse/models.json +66 -0
  112. code_muse/models_cache/__init__.py +26 -0
  113. code_muse/models_cache/blocking_lru_cache.py +98 -0
  114. code_muse/models_cache/cache_writer.py +86 -0
  115. code_muse/models_cache/sha256_hash.cpython-314-darwin.so +0 -0
  116. code_muse/models_cache/sha256_hash.pyx +34 -0
  117. code_muse/models_cache/startup_integration.py +75 -0
  118. code_muse/models_dev_api.json +1 -0
  119. code_muse/models_dev_parser.py +590 -0
  120. code_muse/motion.py +126 -0
  121. code_muse/plugins/__init__.py +471 -0
  122. code_muse/plugins/agent_skills/__init__.py +32 -0
  123. code_muse/plugins/agent_skills/config.py +176 -0
  124. code_muse/plugins/agent_skills/discovery.py +309 -0
  125. code_muse/plugins/agent_skills/downloader.py +389 -0
  126. code_muse/plugins/agent_skills/installer.py +19 -0
  127. code_muse/plugins/agent_skills/metadata.py +293 -0
  128. code_muse/plugins/agent_skills/prompt_builder.py +66 -0
  129. code_muse/plugins/agent_skills/register_callbacks.py +298 -0
  130. code_muse/plugins/agent_skills/remote_catalog.py +320 -0
  131. code_muse/plugins/agent_skills/skill_catalog.py +254 -0
  132. code_muse/plugins/agent_skills/skills_install_menu.py +690 -0
  133. code_muse/plugins/agent_skills/skills_menu.py +791 -0
  134. code_muse/plugins/autonomous_memory/__init__.py +39 -0
  135. code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-darwin.so +0 -0
  136. code_muse/plugins/autonomous_memory/bm25_scorer.cpython-314-x86_64-linux-gnu.so +0 -0
  137. code_muse/plugins/autonomous_memory/bm25_scorer.pyx +291 -0
  138. code_muse/plugins/autonomous_memory/consolidation.py +82 -0
  139. code_muse/plugins/autonomous_memory/extraction.py +382 -0
  140. code_muse/plugins/autonomous_memory/lease_lock.py +105 -0
  141. code_muse/plugins/autonomous_memory/memory_injection.py +59 -0
  142. code_muse/plugins/autonomous_memory/register_callbacks.py +268 -0
  143. code_muse/plugins/autonomous_memory/secret_scanner.py +62 -0
  144. code_muse/plugins/autonomous_memory/session_scanner.py +163 -0
  145. code_muse/plugins/aws_bedrock/__init__.py +14 -0
  146. code_muse/plugins/aws_bedrock/config.py +99 -0
  147. code_muse/plugins/aws_bedrock/register_callbacks.py +241 -0
  148. code_muse/plugins/aws_bedrock/utils.py +153 -0
  149. code_muse/plugins/azure_foundry/README.md +238 -0
  150. code_muse/plugins/azure_foundry/__init__.py +15 -0
  151. code_muse/plugins/azure_foundry/config.py +125 -0
  152. code_muse/plugins/azure_foundry/discovery.py +187 -0
  153. code_muse/plugins/azure_foundry/register_callbacks.py +495 -0
  154. code_muse/plugins/azure_foundry/token.py +180 -0
  155. code_muse/plugins/azure_foundry/utils.py +345 -0
  156. code_muse/plugins/build_filter/__init__.py +1 -0
  157. code_muse/plugins/build_filter/register_callbacks.py +201 -0
  158. code_muse/plugins/build_filter/strategies/__init__.py +1 -0
  159. code_muse/plugins/build_filter/strategies/build.py +397 -0
  160. code_muse/plugins/chatgpt_oauth/__init__.py +6 -0
  161. code_muse/plugins/chatgpt_oauth/config.py +52 -0
  162. code_muse/plugins/chatgpt_oauth/oauth_flow.py +338 -0
  163. code_muse/plugins/chatgpt_oauth/register_callbacks.py +172 -0
  164. code_muse/plugins/chatgpt_oauth/test_plugin.py +301 -0
  165. code_muse/plugins/chatgpt_oauth/utils.py +538 -0
  166. code_muse/plugins/checkpointing/__init__.py +29 -0
  167. code_muse/plugins/checkpointing/checkpoint_hook.py +51 -0
  168. code_muse/plugins/checkpointing/conversation_snapshots.py +117 -0
  169. code_muse/plugins/checkpointing/register_callbacks.py +51 -0
  170. code_muse/plugins/checkpointing/restore_command.py +263 -0
  171. code_muse/plugins/checkpointing/rewind_shortcut.py +88 -0
  172. code_muse/plugins/checkpointing/shadow_git.py +90 -0
  173. code_muse/plugins/claude_code_hooks/__init__.py +1 -0
  174. code_muse/plugins/claude_code_hooks/config.py +188 -0
  175. code_muse/plugins/claude_code_hooks/register_callbacks.py +208 -0
  176. code_muse/plugins/claude_code_oauth/README.md +167 -0
  177. code_muse/plugins/claude_code_oauth/SETUP.md +93 -0
  178. code_muse/plugins/claude_code_oauth/__init__.py +25 -0
  179. code_muse/plugins/claude_code_oauth/config.py +52 -0
  180. code_muse/plugins/claude_code_oauth/fast_mode.py +124 -0
  181. code_muse/plugins/claude_code_oauth/prompt_handler.py +63 -0
  182. code_muse/plugins/claude_code_oauth/register_callbacks.py +547 -0
  183. code_muse/plugins/claude_code_oauth/test_fast_mode.py +165 -0
  184. code_muse/plugins/claude_code_oauth/test_plugin.py +283 -0
  185. code_muse/plugins/claude_code_oauth/token_refresh_heartbeat.py +237 -0
  186. code_muse/plugins/claude_code_oauth/utils.py +664 -0
  187. code_muse/plugins/copilot_auth/__init__.py +11 -0
  188. code_muse/plugins/copilot_auth/config.py +91 -0
  189. code_muse/plugins/copilot_auth/reasoning_client.py +409 -0
  190. code_muse/plugins/copilot_auth/register_callbacks.py +461 -0
  191. code_muse/plugins/copilot_auth/utils.py +584 -0
  192. code_muse/plugins/custom_commands/__init__.py +14 -0
  193. code_muse/plugins/custom_commands/args_injection.py +82 -0
  194. code_muse/plugins/custom_commands/command_discovery.py +89 -0
  195. code_muse/plugins/custom_commands/command_toml_schema.py +71 -0
  196. code_muse/plugins/custom_commands/register_callbacks.py +176 -0
  197. code_muse/plugins/customizable_commands/__init__.py +0 -0
  198. code_muse/plugins/customizable_commands/register_callbacks.py +136 -0
  199. code_muse/plugins/destructive_command_guard/__init__.py +14 -0
  200. code_muse/plugins/destructive_command_guard/detector.py +375 -0
  201. code_muse/plugins/destructive_command_guard/register_callbacks.py +148 -0
  202. code_muse/plugins/example_custom_command/README.md +280 -0
  203. code_muse/plugins/example_custom_command/register_callbacks.py +51 -0
  204. code_muse/plugins/file_permission_handler/__init__.py +4 -0
  205. code_muse/plugins/file_permission_handler/register_callbacks.py +441 -0
  206. code_muse/plugins/filter_engine/__init__.py +30 -0
  207. code_muse/plugins/filter_engine/classifier.py +153 -0
  208. code_muse/plugins/filter_engine/content_detector.py +184 -0
  209. code_muse/plugins/filter_engine/dispatcher.py +244 -0
  210. code_muse/plugins/filter_engine/register_callbacks.py +188 -0
  211. code_muse/plugins/filter_engine/registry.py +279 -0
  212. code_muse/plugins/filter_engine/strategies/__init__.py +8 -0
  213. code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-darwin.so +0 -0
  214. code_muse/plugins/filter_engine/strategies/ast_compressor.cpython-314-x86_64-linux-gnu.so +0 -0
  215. code_muse/plugins/filter_engine/strategies/ast_compressor.pyx +348 -0
  216. code_muse/plugins/filter_engine/strategies/ast_parser.py +167 -0
  217. code_muse/plugins/filter_engine/strategies/code.cpython-314-darwin.so +0 -0
  218. code_muse/plugins/filter_engine/strategies/code.cpython-314-x86_64-linux-gnu.so +0 -0
  219. code_muse/plugins/filter_engine/strategies/code.pyx +584 -0
  220. code_muse/plugins/filter_engine/strategies/git.cpython-314-darwin.so +0 -0
  221. code_muse/plugins/filter_engine/strategies/git.cpython-314-x86_64-linux-gnu.so +0 -0
  222. code_muse/plugins/filter_engine/strategies/git.pyx +438 -0
  223. code_muse/plugins/filter_engine/strategies/json_compressor.cpython-314-darwin.so +0 -0
  224. code_muse/plugins/filter_engine/strategies/json_compressor.pyx +253 -0
  225. code_muse/plugins/filter_engine/strategies/json_patterns.cpython-314-darwin.so +0 -0
  226. code_muse/plugins/filter_engine/strategies/json_patterns.pyx +178 -0
  227. code_muse/plugins/filter_engine/strategies/lint.cpython-314-darwin.so +0 -0
  228. code_muse/plugins/filter_engine/strategies/lint.cpython-314-x86_64-linux-gnu.so +0 -0
  229. code_muse/plugins/filter_engine/strategies/lint.pyx +626 -0
  230. code_muse/plugins/filter_engine/strategies/test.cpython-314-darwin.so +0 -0
  231. code_muse/plugins/filter_engine/strategies/test.cpython-314-x86_64-linux-gnu.so +0 -0
  232. code_muse/plugins/filter_engine/strategies/test.pyx +431 -0
  233. code_muse/plugins/filter_engine/verbosity.py +63 -0
  234. code_muse/plugins/force_push_guard/__init__.py +5 -0
  235. code_muse/plugins/force_push_guard/detector.py +96 -0
  236. code_muse/plugins/force_push_guard/register_callbacks.py +144 -0
  237. code_muse/plugins/force_push_guard/test_detector.py +143 -0
  238. code_muse/plugins/frontend_emitter/__init__.py +25 -0
  239. code_muse/plugins/frontend_emitter/emitter.py +121 -0
  240. code_muse/plugins/frontend_emitter/register_callbacks.py +259 -0
  241. code_muse/plugins/gac/__init__.py +4 -0
  242. code_muse/plugins/gac/git_ops.py +136 -0
  243. code_muse/plugins/gac/prompt.py +191 -0
  244. code_muse/plugins/gac/register_callbacks.py +82 -0
  245. code_muse/plugins/hook_creator/__init__.py +1 -0
  246. code_muse/plugins/hook_creator/register_callbacks.py +34 -0
  247. code_muse/plugins/hook_manager/__init__.py +1 -0
  248. code_muse/plugins/hook_manager/config.py +289 -0
  249. code_muse/plugins/hook_manager/hooks_menu.py +563 -0
  250. code_muse/plugins/hook_manager/register_callbacks.py +227 -0
  251. code_muse/plugins/hook_monitor/register_callbacks.py +36 -0
  252. code_muse/plugins/mindpack/__init__.py +0 -0
  253. code_muse/plugins/mindpack/factory.py +930 -0
  254. code_muse/plugins/mindpack/judge.py +573 -0
  255. code_muse/plugins/mindpack/memory.py +100 -0
  256. code_muse/plugins/mindpack/mindpack_menu.py +1552 -0
  257. code_muse/plugins/mindpack/orchestration.py +605 -0
  258. code_muse/plugins/mindpack/register_callbacks.py +175 -0
  259. code_muse/plugins/mindpack/schemas.py +358 -0
  260. code_muse/plugins/mindpack/tools.py +387 -0
  261. code_muse/plugins/oauth_muse_html.py +226 -0
  262. code_muse/plugins/ollama_setup/__init__.py +5 -0
  263. code_muse/plugins/ollama_setup/completer.py +36 -0
  264. code_muse/plugins/ollama_setup/register_callbacks.py +410 -0
  265. code_muse/plugins/plan_command/__init__.py +0 -0
  266. code_muse/plugins/plan_command/register_callbacks.py +206 -0
  267. code_muse/plugins/plan_mode/__init__.py +37 -0
  268. code_muse/plugins/plan_mode/mode_cycling.py +40 -0
  269. code_muse/plugins/plan_mode/plan_generation.py +68 -0
  270. code_muse/plugins/plan_mode/plan_hooks.py +74 -0
  271. code_muse/plugins/plan_mode/plan_mode_tools.py +138 -0
  272. code_muse/plugins/plan_mode/register_callbacks.py +121 -0
  273. code_muse/plugins/plugin_trust/register_callbacks.py +140 -0
  274. code_muse/plugins/policy_engine/__init__.py +46 -0
  275. code_muse/plugins/policy_engine/approval_flow_integration.py +59 -0
  276. code_muse/plugins/policy_engine/policy_evaluator.py +75 -0
  277. code_muse/plugins/policy_engine/policy_file_discovery.py +90 -0
  278. code_muse/plugins/policy_engine/policy_toml_schema.py +115 -0
  279. code_muse/plugins/policy_engine/register_callbacks.py +112 -0
  280. code_muse/plugins/pop_command/__init__.py +1 -0
  281. code_muse/plugins/pop_command/register_callbacks.py +189 -0
  282. code_muse/plugins/prompt_newline/__init__.py +13 -0
  283. code_muse/plugins/prompt_newline/config.py +19 -0
  284. code_muse/plugins/prompt_newline/register_callbacks.py +159 -0
  285. code_muse/plugins/safety_status/__init__.py +0 -0
  286. code_muse/plugins/safety_status/register_callbacks.py +113 -0
  287. code_muse/plugins/semantic_compression/__init__.py +6 -0
  288. code_muse/plugins/semantic_compression/compressor.py +295 -0
  289. code_muse/plugins/semantic_compression/config.py +123 -0
  290. code_muse/plugins/semantic_compression/register_callbacks.py +320 -0
  291. code_muse/plugins/shell_minimizer/__init__.py +50 -0
  292. code_muse/plugins/shell_minimizer/builtin_filters.toml +393 -0
  293. code_muse/plugins/shell_minimizer/pipeline.py +556 -0
  294. code_muse/plugins/shell_minimizer/primitives.py +482 -0
  295. code_muse/plugins/shell_minimizer/register_callbacks.py +276 -0
  296. code_muse/plugins/shell_safety/__init__.py +6 -0
  297. code_muse/plugins/shell_safety/agent_shell_safety.py +69 -0
  298. code_muse/plugins/shell_safety/command_cache.py +149 -0
  299. code_muse/plugins/shell_safety/register_callbacks.py +202 -0
  300. code_muse/plugins/synthetic_status/__init__.py +1 -0
  301. code_muse/plugins/synthetic_status/register_callbacks.py +128 -0
  302. code_muse/plugins/synthetic_status/status_api.py +145 -0
  303. code_muse/plugins/token_caching/__init__.py +21 -0
  304. code_muse/plugins/token_caching/cache_hit_tracking.py +128 -0
  305. code_muse/plugins/token_caching/cacheable_prefix_detection.py +28 -0
  306. code_muse/plugins/token_caching/register_callbacks.py +54 -0
  307. code_muse/plugins/token_caching/stats_display.py +35 -0
  308. code_muse/plugins/token_tracking/__init__.py +26 -0
  309. code_muse/plugins/token_tracking/database.py +381 -0
  310. code_muse/plugins/token_tracking/edit_analyzer.py +97 -0
  311. code_muse/plugins/token_tracking/record.py +55 -0
  312. code_muse/plugins/token_tracking/register_callbacks.py +277 -0
  313. code_muse/plugins/token_tracking/reports.py +329 -0
  314. code_muse/plugins/universal_constructor/__init__.py +13 -0
  315. code_muse/plugins/universal_constructor/models.py +136 -0
  316. code_muse/plugins/universal_constructor/register_callbacks.py +47 -0
  317. code_muse/plugins/universal_constructor/registry.py +390 -0
  318. code_muse/plugins/universal_constructor/runner.py +474 -0
  319. code_muse/plugins/universal_constructor/safety.py +440 -0
  320. code_muse/plugins/universal_constructor/sandbox.py +584 -0
  321. code_muse/provider_identity.py +105 -0
  322. code_muse/pydantic_patches.py +410 -0
  323. code_muse/reopenable_async_client.py +233 -0
  324. code_muse/round_robin_model.py +151 -0
  325. code_muse/secret_storage.py +74 -0
  326. code_muse/security/__init__.py +1 -0
  327. code_muse/security/redaction.cpython-314-darwin.so +0 -0
  328. code_muse/security/redaction.cpython-314-x86_64-linux-gnu.so +0 -0
  329. code_muse/security/redaction.pyx +135 -0
  330. code_muse/session_storage.py +565 -0
  331. code_muse/status_display.py +261 -0
  332. code_muse/stream_parser/__init__.py +76 -0
  333. code_muse/stream_parser/assistant_text_parser.py +90 -0
  334. code_muse/stream_parser/citation_parser.py +76 -0
  335. code_muse/stream_parser/inline_hidden_tag_parser.py +236 -0
  336. code_muse/stream_parser/proposed_plan_parser.py +158 -0
  337. code_muse/stream_parser/stream_text_chunk.py +23 -0
  338. code_muse/stream_parser/stream_text_parser.py +27 -0
  339. code_muse/stream_parser/tagged_line_parser.cpython-314-darwin.so +0 -0
  340. code_muse/stream_parser/tagged_line_parser.pyx +251 -0
  341. code_muse/stream_parser/utf8_stream_parser.cpython-314-darwin.so +0 -0
  342. code_muse/stream_parser/utf8_stream_parser.pyx +206 -0
  343. code_muse/summarization_agent.py +308 -0
  344. code_muse/terminal_utils.cpython-314-darwin.so +0 -0
  345. code_muse/terminal_utils.cpython-314-x86_64-linux-gnu.so +0 -0
  346. code_muse/terminal_utils.pyx +483 -0
  347. code_muse/tools/__init__.py +459 -0
  348. code_muse/tools/agent_tools.py +613 -0
  349. code_muse/tools/ask_user_question/__init__.py +26 -0
  350. code_muse/tools/ask_user_question/constants.py +73 -0
  351. code_muse/tools/ask_user_question/demo_tui.py +55 -0
  352. code_muse/tools/ask_user_question/handler.py +232 -0
  353. code_muse/tools/ask_user_question/models.py +302 -0
  354. code_muse/tools/ask_user_question/registration.py +37 -0
  355. code_muse/tools/ask_user_question/renderers.py +336 -0
  356. code_muse/tools/ask_user_question/terminal_ui.py +327 -0
  357. code_muse/tools/ask_user_question/theme.py +156 -0
  358. code_muse/tools/ask_user_question/tui_loop.py +422 -0
  359. code_muse/tools/background_jobs.py +99 -0
  360. code_muse/tools/browser/__init__.py +37 -0
  361. code_muse/tools/browser/browser_control.py +289 -0
  362. code_muse/tools/browser/browser_interactions.py +545 -0
  363. code_muse/tools/browser/browser_locators.py +640 -0
  364. code_muse/tools/browser/browser_manager.py +376 -0
  365. code_muse/tools/browser/browser_navigation.py +251 -0
  366. code_muse/tools/browser/browser_screenshot.py +180 -0
  367. code_muse/tools/browser/browser_scripts.py +462 -0
  368. code_muse/tools/browser/browser_workflows.py +222 -0
  369. code_muse/tools/chrome_cdp/__init__.py +1070 -0
  370. code_muse/tools/chrome_cdp/register_callbacks.py +61 -0
  371. code_muse/tools/command_runner.py +1401 -0
  372. code_muse/tools/common.py +1407 -0
  373. code_muse/tools/display.py +87 -0
  374. code_muse/tools/file_modifications.py +1099 -0
  375. code_muse/tools/file_operations.py +860 -0
  376. code_muse/tools/image_tools.py +185 -0
  377. code_muse/tools/meetin_proxy/__init__.py +243 -0
  378. code_muse/tools/meetin_proxy/capture_addon.py +82 -0
  379. code_muse/tools/meetin_proxy/proxy_manager.py +326 -0
  380. code_muse/tools/meetin_proxy/register_callbacks.py +45 -0
  381. code_muse/tools/path_policy.py +219 -0
  382. code_muse/tools/skills_tools.py +586 -0
  383. code_muse/tools/subagent_context.py +158 -0
  384. code_muse/tools/tools_content.py +50 -0
  385. code_muse/tools/universal_constructor.py +965 -0
  386. code_muse/uvx_detection.py +241 -0
  387. code_muse/version_checker.py +86 -0
  388. code_muse-0.0.1.data/data/code_muse/models.json +66 -0
  389. code_muse-0.0.1.data/data/code_muse/models_dev_api.json +1 -0
  390. code_muse-0.0.1.dist-info/METADATA +845 -0
  391. code_muse-0.0.1.dist-info/RECORD +394 -0
  392. code_muse-0.0.1.dist-info/WHEEL +4 -0
  393. code_muse-0.0.1.dist-info/entry_points.txt +2 -0
  394. code_muse-0.0.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,590 @@
1
+ """
2
+ Models development API parser for Muse.
3
+
4
+ This module provides functionality to parse and work with the models.dev API,
5
+ including provider and model information, search capabilities, and conversion to Muse
6
+ configuration format.
7
+
8
+ The parser fetches data from the live models.dev API first, falling back to a bundled
9
+ JSON file if the API is unavailable.
10
+
11
+ The parser supports filtering by cost, context length, capabilities, and provides
12
+ comprehensive type safety throughout the implementation.
13
+ """
14
+
15
+ import json
16
+ from dataclasses import dataclass, field
17
+ from pathlib import Path
18
+ from typing import Any
19
+
20
+ import httpx
21
+
22
+ from code_muse.messaging import emit_error, emit_info, emit_warning
23
+
24
+ # Live API endpoint for models.dev
25
+ MODELS_DEV_API_URL = "https://models.dev/api.json"
26
+
27
+ # Bundled fallback JSON file (relative to this module)
28
+ BUNDLED_JSON_FILENAME = "models_dev_api.json"
29
+
30
+
31
+ @dataclass(slots=True)
32
+ class ProviderInfo:
33
+ """Information about a model provider."""
34
+
35
+ id: str
36
+ name: str
37
+ env: list[str]
38
+ api: str
39
+ npm: str | None = None
40
+ doc: str | None = None
41
+ models: dict[str, dict[str, Any]] = field(default_factory=dict)
42
+
43
+ def __post_init__(self) -> None:
44
+ """Validate provider data after initialization."""
45
+ if not self.id:
46
+ raise ValueError("Provider ID cannot be empty")
47
+ if not self.name:
48
+ raise ValueError("Provider name cannot be empty")
49
+
50
+ @property
51
+ def model_count(self) -> int:
52
+ """Get the number of models for this provider."""
53
+ return len(self.models)
54
+
55
+
56
+ @dataclass(slots=True)
57
+ class ModelInfo:
58
+ """Information about a specific model."""
59
+
60
+ provider_id: str
61
+ model_id: str
62
+ name: str
63
+ attachment: bool = False
64
+ reasoning: bool = False
65
+ tool_call: bool = False
66
+ temperature: bool = False
67
+ structured_output: bool = False
68
+ cost_input: float | None = None
69
+ cost_output: float | None = None
70
+ cost_cache_read: float | None = None
71
+ context_length: int = 0
72
+ max_output: int = 0
73
+ input_modalities: list[str] = field(default_factory=list)
74
+ output_modalities: list[str] = field(default_factory=list)
75
+ knowledge: str | None = None
76
+ release_date: str | None = None
77
+ last_updated: str | None = None
78
+ open_weights: bool = False
79
+
80
+ def __post_init__(self) -> None:
81
+ """Validate model data after initialization."""
82
+ if not self.provider_id:
83
+ raise ValueError("Provider ID cannot be empty")
84
+ if not self.model_id:
85
+ raise ValueError("Model ID cannot be empty")
86
+ if not self.name:
87
+ raise ValueError("Model name cannot be empty")
88
+ if self.context_length < 0:
89
+ raise ValueError("Context length cannot be negative")
90
+ if self.max_output < 0:
91
+ raise ValueError("Max output cannot be negative")
92
+
93
+ @property
94
+ def full_id(self) -> str:
95
+ """Get the full identifier: provider_id::model_id."""
96
+ return f"{self.provider_id}::{self.model_id}"
97
+
98
+ @property
99
+ def has_vision(self) -> bool:
100
+ """Check if the model supports vision capabilities."""
101
+ return "image" in self.input_modalities
102
+
103
+ @property
104
+ def is_multimodal(self) -> bool:
105
+ """Check if the model supports multiple modalities."""
106
+ return len(self.input_modalities) > 1 or len(self.output_modalities) > 1
107
+
108
+ def supports_capability(self, capability: str) -> bool:
109
+ """Check if model supports a specific capability."""
110
+ return getattr(self, capability, False) is True
111
+
112
+
113
+ class ModelsDevRegistry:
114
+ """Registry for managing models and providers from models.dev API.
115
+
116
+ Fetches data from the live models.dev API first, falling back to a bundled
117
+ JSON file if the API is unavailable.
118
+ """
119
+
120
+ def __init__(self, json_path: str | Path | None = None) -> None:
121
+ """
122
+ Initialize the registry by fetching from models.dev API or loading bundled JSON.
123
+
124
+ Args:
125
+ json_path: Optional path to a local JSON file (for testing/offline use).
126
+ If None, will try live API first, then bundled fallback.
127
+
128
+ Raises:
129
+ FileNotFoundError: If no data source is available
130
+ json.JSONDecodeError: If the data contains invalid JSON
131
+ ValueError: If required fields are missing or malformed
132
+ """
133
+ self.json_path = Path(json_path) if json_path else None
134
+ self.providers: dict[str, ProviderInfo] = {}
135
+ self.models: dict[str, ModelInfo] = {}
136
+ self.provider_models: dict[
137
+ str, list[str]
138
+ ] = {} # Maps provider_id to list of model IDs
139
+ self.data_source: str = "unknown" # Track where data came from
140
+ self._load_data()
141
+
142
+ def _fetch_from_api(self) -> dict[str, Any | None]:
143
+ """Fetch data from the live models.dev API.
144
+
145
+ Returns:
146
+ Parsed JSON data if successful, None otherwise.
147
+ """
148
+ try:
149
+ with httpx.Client(timeout=10.0) as client:
150
+ response = client.get(MODELS_DEV_API_URL)
151
+ response.raise_for_status()
152
+ data = response.json()
153
+ if isinstance(data, dict) and len(data) > 0:
154
+ return data
155
+ return None
156
+ except httpx.TimeoutException:
157
+ emit_warning("models.dev API timed out, using bundled fallback")
158
+ return None
159
+ except httpx.HTTPStatusError as e:
160
+ emit_warning(
161
+ f"models.dev API returned {e.response.status_code}, using bundled fallback"
162
+ )
163
+ return None
164
+ except Exception as e:
165
+ emit_warning(
166
+ f"Failed to fetch from models.dev API: {e}, using bundled fallback"
167
+ )
168
+ return None
169
+
170
+ def _get_bundled_json_path(self) -> Path:
171
+ """Get the path to the bundled JSON file."""
172
+ return Path(__file__).parent / BUNDLED_JSON_FILENAME
173
+
174
+ def _load_data(self) -> None:
175
+ """Load data from API or fallback sources, populating internal data structures."""
176
+ data: dict[str, Any | None] = None
177
+
178
+ # If explicit json_path provided, use that directly (for testing)
179
+ if self.json_path:
180
+ if not self.json_path.exists():
181
+ raise FileNotFoundError(f"Models API file not found: {self.json_path}")
182
+ try:
183
+ with open(self.json_path, encoding="utf-8") as f:
184
+ data = json.load(f)
185
+ self.data_source = f"file:{self.json_path}"
186
+ except json.JSONDecodeError as e:
187
+ emit_error(f"Invalid JSON in {self.json_path}: {e}")
188
+ raise
189
+ else:
190
+ # Try live API first
191
+ data = self._fetch_from_api()
192
+ if data:
193
+ self.data_source = "live:models.dev"
194
+ emit_info("📡 Fetched latest models from models.dev")
195
+ else:
196
+ # Fall back to bundled JSON
197
+ bundled_path = self._get_bundled_json_path()
198
+ if bundled_path.exists():
199
+ try:
200
+ with open(bundled_path, encoding="utf-8") as f:
201
+ data = json.load(f)
202
+ self.data_source = f"bundled:{bundled_path.name}"
203
+ emit_info(
204
+ "📦 Using bundled models database (models.dev unavailable)"
205
+ )
206
+ except json.JSONDecodeError as e:
207
+ emit_error(f"Invalid JSON in bundled file {bundled_path}: {e}")
208
+ raise
209
+ else:
210
+ raise FileNotFoundError(
211
+ f"No data source available: models.dev API failed and bundled file not found at {bundled_path}"
212
+ )
213
+
214
+ if not isinstance(data, dict):
215
+ raise ValueError("Top-level JSON must be an object")
216
+
217
+ # Parse flat structure: {provider_id: {id, name, env, api, npm, doc, models: {model_id: {...}}}}
218
+ for provider_id, provider_data in data.items():
219
+ try:
220
+ provider = self._parse_provider(provider_id, provider_data)
221
+ self.providers[provider_id] = provider
222
+ self.provider_models[provider_id] = []
223
+
224
+ # Parse models nested under the provider
225
+ models_data = provider_data.get("models", {})
226
+ if isinstance(models_data, dict):
227
+ for model_id, model_data in models_data.items():
228
+ try:
229
+ model = self._parse_model(provider_id, model_id, model_data)
230
+ model_key = model.full_id
231
+ self.models[model_key] = model
232
+ self.provider_models[provider_id].append(model_id)
233
+ except Exception as e:
234
+ emit_warning(
235
+ f"Skipping malformed model {provider_id}::{model_id}: {e}"
236
+ )
237
+ continue
238
+
239
+ except Exception as e:
240
+ emit_warning(f"Skipping malformed provider {provider_id}: {e}")
241
+ continue
242
+
243
+ emit_info(
244
+ f"Loaded {len(self.providers)} providers and {len(self.models)} models"
245
+ )
246
+
247
+ def _parse_provider(self, provider_id: str, data: dict[str, Any]) -> ProviderInfo:
248
+ """Parse provider data from JSON."""
249
+ # Only name and env are truly required - api is optional for SDK-based providers
250
+ # like Anthropic, OpenAI, Azure that don't need a custom API URL
251
+ required_fields = ["name", "env"]
252
+ missing_fields = [f for f in required_fields if f not in data]
253
+ if missing_fields:
254
+ raise ValueError(f"Missing required fields: {missing_fields}")
255
+
256
+ return ProviderInfo(
257
+ id=provider_id,
258
+ name=data["name"],
259
+ env=data["env"],
260
+ api=data.get("api", ""), # Optional - empty string for SDK-based providers
261
+ npm=data.get("npm"),
262
+ doc=data.get("doc"),
263
+ models=data.get("models", {}),
264
+ )
265
+
266
+ def _parse_model(
267
+ self, provider_id: str, model_id: str, data: dict[str, Any]
268
+ ) -> ModelInfo:
269
+ """Parse model data from JSON."""
270
+ if not data.get("name"):
271
+ raise ValueError("Missing required field: name")
272
+
273
+ # Extract cost data from nested dict
274
+ cost_data = data.get("cost", {})
275
+ cost_input = cost_data.get("input")
276
+ cost_output = cost_data.get("output")
277
+ cost_cache_read = cost_data.get("cache_read")
278
+
279
+ # Extract limit data from nested dict
280
+ limit_data = data.get("limit", {})
281
+ context_length = limit_data.get("context", 0)
282
+ max_output = limit_data.get("output", 0)
283
+
284
+ # Extract modalities from nested dict
285
+ modalities = data.get("modalities", {})
286
+ input_mods = modalities.get("input", [])
287
+ output_mods = modalities.get("output", [])
288
+
289
+ return ModelInfo(
290
+ provider_id=provider_id,
291
+ model_id=model_id,
292
+ name=data["name"],
293
+ attachment=data.get("attachment", False),
294
+ reasoning=data.get("reasoning", False),
295
+ tool_call=data.get("tool_call", False),
296
+ temperature=data.get("temperature", True),
297
+ structured_output=data.get("structured_output", False),
298
+ cost_input=cost_input,
299
+ cost_output=cost_output,
300
+ cost_cache_read=cost_cache_read,
301
+ context_length=context_length,
302
+ max_output=max_output,
303
+ input_modalities=input_mods,
304
+ output_modalities=output_mods,
305
+ knowledge=data.get("knowledge"),
306
+ release_date=data.get("release_date"),
307
+ last_updated=data.get("last_updated"),
308
+ open_weights=data.get("open_weights", False),
309
+ )
310
+
311
+ def get_providers(self) -> list[ProviderInfo]:
312
+ """
313
+ Get all providers, sorted by name.
314
+
315
+ Returns:
316
+ List of ProviderInfo objects sorted by name
317
+ """
318
+ return sorted(self.providers.values(), key=lambda p: p.name.lower())
319
+
320
+ def get_provider(self, provider_id: str) -> ProviderInfo | None:
321
+ """
322
+ Get a specific provider by ID.
323
+
324
+ Args:
325
+ provider_id: The provider identifier
326
+
327
+ Returns:
328
+ ProviderInfo if found, None otherwise
329
+ """
330
+ return self.providers.get(provider_id)
331
+
332
+ def get_models(self, provider_id: str | None = None) -> list[ModelInfo]:
333
+ """
334
+ Get models, optionally filtered by provider.
335
+
336
+ Args:
337
+ provider_id: Optional provider ID to filter by
338
+
339
+ Returns:
340
+ List of ModelInfo objects sorted by name
341
+ """
342
+ if provider_id:
343
+ model_ids = self.provider_models.get(provider_id, [])
344
+ models = [
345
+ self.models[f"{provider_id}::{model_id}"]
346
+ for model_id in model_ids
347
+ if f"{provider_id}::{model_id}" in self.models
348
+ ]
349
+ else:
350
+ models = list(self.models.values())
351
+
352
+ return sorted(models, key=lambda m: m.name.lower())
353
+
354
+ def get_model(self, provider_id: str, model_id: str) -> ModelInfo | None:
355
+ """
356
+ Get a specific model.
357
+
358
+ Args:
359
+ provider_id: The provider identifier
360
+ model_id: The model identifier
361
+
362
+ Returns:
363
+ ModelInfo if found, None otherwise
364
+ """
365
+ full_id = f"{provider_id}::{model_id}"
366
+ return self.models.get(full_id)
367
+
368
+ def search_models(
369
+ self,
370
+ query: str | None = None,
371
+ capability_filters: dict[str, Any | None] = None,
372
+ ) -> list[ModelInfo]:
373
+ """
374
+ Search models by name/query and filter by capabilities.
375
+
376
+ Args:
377
+ query: Optional search string (case-insensitive)
378
+ capability_filters: Optional capability filters (e.g., {"vision": True})
379
+
380
+ Returns:
381
+ List of matching ModelInfo objects
382
+ """
383
+ models = list(self.models.values())
384
+
385
+ # Filter by query
386
+ if query:
387
+ query_lower = query.lower()
388
+ models = [
389
+ m
390
+ for m in models
391
+ if query_lower in m.name.lower() or query_lower in m.model_id.lower()
392
+ ]
393
+
394
+ # Filter by capabilities
395
+ if capability_filters:
396
+ for capability, required in capability_filters.items():
397
+ if isinstance(required, bool):
398
+ models = [
399
+ m
400
+ for m in models
401
+ if m.supports_capability(capability) == required
402
+ ]
403
+ else:
404
+ # Handle other capability filter types if needed
405
+ models = [
406
+ m for m in models if getattr(m, capability, None) == required
407
+ ]
408
+
409
+ return sorted(models, key=lambda m: m.name.lower())
410
+
411
+ def filter_by_cost(
412
+ self,
413
+ models: list[ModelInfo],
414
+ max_input_cost: float | None = None,
415
+ max_output_cost: float | None = None,
416
+ ) -> list[ModelInfo]:
417
+ """
418
+ Filter models by cost constraints.
419
+
420
+ Args:
421
+ models: List of models to filter
422
+ max_input_cost: Maximum input cost per token (optional)
423
+ max_output_cost: Maximum output cost per token (optional)
424
+
425
+ Returns:
426
+ Filtered list of models within cost constraints
427
+ """
428
+ filtered_models = models
429
+
430
+ if max_input_cost is not None:
431
+ filtered_models = [
432
+ m
433
+ for m in filtered_models
434
+ if m.cost_input is not None and m.cost_input <= max_input_cost
435
+ ]
436
+
437
+ if max_output_cost is not None:
438
+ filtered_models = [
439
+ m
440
+ for m in filtered_models
441
+ if m.cost_output is not None and m.cost_output <= max_output_cost
442
+ ]
443
+
444
+ return filtered_models
445
+
446
+ def filter_by_context(
447
+ self, models: list[ModelInfo], min_context_length: int
448
+ ) -> list[ModelInfo]:
449
+ """
450
+ Filter models by minimum context length.
451
+
452
+ Args:
453
+ models: List of models to filter
454
+ min_context_length: Minimum context length requirement
455
+
456
+ Returns:
457
+ Filtered list of models meeting context requirement
458
+ """
459
+ return [m for m in models if m.context_length >= min_context_length]
460
+
461
+
462
+ # Provider type mapping for Muse configuration
463
+ PROVIDER_TYPE_MAP = {
464
+ "anthropic": "anthropic",
465
+ "openai": "openai",
466
+ "google": "gemini",
467
+ "deepseek": "deepseek",
468
+ "ollama": "ollama",
469
+ "groq": "groq",
470
+ "cohere": "cohere",
471
+ "mistral": "mistral",
472
+ }
473
+
474
+
475
+ def convert_to_muse_config(
476
+ model: ModelInfo, provider: ProviderInfo
477
+ ) -> dict[str, Any]:
478
+ """
479
+ Convert a model and provider to Muse configuration format.
480
+
481
+ Args:
482
+ model: ModelInfo object
483
+ provider: ProviderInfo object
484
+
485
+ Returns:
486
+ Dictionary in Muse configuration format
487
+
488
+ Raises:
489
+ ValueError: If required configuration fields are missing
490
+ """
491
+ # Determine provider type
492
+ provider_type = PROVIDER_TYPE_MAP.get(provider.id, provider.id)
493
+
494
+ # Basic configuration
495
+ config = {
496
+ "type": provider_type,
497
+ "model": model.model_id,
498
+ "enabled": True,
499
+ "provider_id": provider.id,
500
+ "env_vars": provider.env,
501
+ }
502
+
503
+ # Add optional fields if available
504
+ if provider.api:
505
+ config["api_url"] = provider.api
506
+ if provider.npm:
507
+ config["npm_package"] = provider.npm
508
+
509
+ # Add cost information
510
+ if model.cost_input is not None:
511
+ config["input_cost_per_token"] = model.cost_input
512
+ if model.cost_output is not None:
513
+ config["output_cost_per_token"] = model.cost_output
514
+ if model.cost_cache_read is not None:
515
+ config["cache_read_cost_per_token"] = model.cost_cache_read
516
+
517
+ # Add limits
518
+ if model.context_length > 0:
519
+ config["max_tokens"] = model.context_length
520
+ if model.max_output > 0:
521
+ config["max_output_tokens"] = model.max_output
522
+
523
+ # Add capabilities
524
+ capabilities = {
525
+ "attachment": model.attachment,
526
+ "reasoning": model.reasoning,
527
+ "tool_call": model.tool_call,
528
+ "temperature": model.temperature,
529
+ "structured_output": model.structured_output,
530
+ }
531
+ config["capabilities"] = capabilities
532
+
533
+ # Add modalities
534
+ if model.input_modalities:
535
+ config["input_modalities"] = model.input_modalities
536
+ if model.output_modalities:
537
+ config["output_modalities"] = model.output_modalities
538
+
539
+ # Add metadata
540
+ metadata = {}
541
+ if model.knowledge:
542
+ metadata["knowledge"] = model.knowledge
543
+ if model.release_date:
544
+ metadata["release_date"] = model.release_date
545
+ if model.last_updated:
546
+ metadata["last_updated"] = model.last_updated
547
+ metadata["open_weights"] = model.open_weights
548
+
549
+ if metadata:
550
+ config["metadata"] = metadata
551
+
552
+ return config
553
+
554
+
555
+ # Example usage
556
+ if __name__ == "__main__":
557
+ # This is for testing purposes
558
+ try:
559
+ registry = ModelsDevRegistry()
560
+
561
+ # Example: Get all providers
562
+ providers = registry.get_providers()
563
+ emit_info(f"Loaded {len(providers)} providers")
564
+
565
+ # Example: Search for vision models
566
+ vision_models = registry.search_models()
567
+ vision_models = [m for m in vision_models if m.has_vision]
568
+ emit_info(f"Found {len(vision_models)} vision models")
569
+
570
+ # Example: Filter by cost
571
+ affordable_models = registry.filter_by_cost(
572
+ registry.get_models(), max_input_cost=0.001
573
+ )
574
+ emit_info(f"Found {len(affordable_models)} affordable models")
575
+
576
+ # Example: Convert to Muse config
577
+ if providers and registry.get_models():
578
+ provider = providers[0]
579
+ models = registry.get_models(provider.id)
580
+ if models:
581
+ config = convert_to_muse_config(models[0], provider)
582
+ emit_info(f"Example config created for {models[0].name}")
583
+
584
+ # Show data source
585
+ emit_info(f"Data source: {registry.data_source}")
586
+
587
+ except FileNotFoundError as e:
588
+ emit_error(f"No data source available: {e}")
589
+ except Exception as e:
590
+ emit_error(f"Error loading models: {e}")