utim-cli 2.3.25__tar.gz → 2.4.0__tar.gz

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 (174) hide show
  1. {utim_cli-2.3.25 → utim_cli-2.4.0}/CHANGELOG.md +21 -0
  2. {utim_cli-2.3.25/utim_cli.egg-info → utim_cli-2.4.0}/PKG-INFO +1 -1
  3. {utim_cli-2.3.25 → utim_cli-2.4.0}/pyproject.toml +1 -1
  4. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim/__init__.py +1 -1
  5. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/__init__.py +1 -1
  6. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/_version.py +1 -1
  7. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/agent.py +34 -6
  8. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/bootstrap.py +617 -580
  9. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/client_utils.py +324 -41
  10. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/constants.py +8 -1
  11. utim_cli-2.4.0/utim_cli/context_inspector.py +341 -0
  12. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/context_pruner.py +644 -327
  13. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/crawler/engine.py +3 -1
  14. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/orchestrator.py +172 -79
  15. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/orchestrator_helpers.py +87 -31
  16. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/orchestrator_llm_transport.py +158 -62
  17. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/orchestrator_tool_exec.py +172 -8
  18. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/orchestrator_turn_history.py +409 -250
  19. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/auth.py +93 -50
  20. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/db.py +189 -24
  21. utim_cli-2.4.0/utim_cli/server/docs_md/pricing.md +24 -0
  22. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/key_rotator.py +98 -150
  23. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/models.py +123 -15
  24. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/plan_integrity.py +9 -7
  25. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/router.py +23 -177
  26. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/completion_routes.py +654 -359
  27. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/quota_routes.py +134 -56
  28. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/utils.py +198 -65
  29. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tools.py +776 -64
  30. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/compression_dialog.py +11 -11
  31. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/model_dialog.py +165 -3
  32. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/plugins_dialog.py +11 -0
  33. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/tools_dialog.py +291 -273
  34. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/utim.py +268 -65
  35. {utim_cli-2.3.25 → utim_cli-2.4.0/utim_cli.egg-info}/PKG-INFO +1 -1
  36. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli.egg-info/SOURCES.txt +1 -0
  37. utim_cli-2.3.25/utim_cli/server/docs_md/pricing.md +0 -19
  38. {utim_cli-2.3.25 → utim_cli-2.4.0}/LICENSE +0 -0
  39. {utim_cli-2.3.25 → utim_cli-2.4.0}/MANIFEST.in +0 -0
  40. {utim_cli-2.3.25 → utim_cli-2.4.0}/README.md +0 -0
  41. {utim_cli-2.3.25 → utim_cli-2.4.0}/setup.cfg +0 -0
  42. {utim_cli-2.3.25 → utim_cli-2.4.0}/setup.py +0 -0
  43. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/_chip_test.py +0 -0
  44. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/_verify_repro.py +0 -0
  45. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/_verify_syntax.py +0 -0
  46. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/_wizard_smoke_test.py +0 -0
  47. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/ask_helper.py +0 -0
  48. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/auth.py +0 -0
  49. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/backup.py +0 -0
  50. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/billing.py +0 -0
  51. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/blender_agent.py +0 -0
  52. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/brain.py +0 -0
  53. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/builtin/skills/utim-guide/SKILL.md +0 -0
  54. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/config.py +0 -0
  55. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/crawler/__init__.py +0 -0
  56. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/crawler/markdown_distiller.py +0 -0
  57. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/dependency_manager.py +0 -0
  58. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/doctor.py +0 -0
  59. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/evidence_registry.py +0 -0
  60. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/harbor.py +0 -0
  61. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/knowledge_graph.py +0 -0
  62. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/local_db.py +0 -0
  63. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/logger.py +0 -0
  64. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/mcp_clean_wrapper.py +0 -0
  65. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/mcp_client.py +0 -0
  66. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/mcp_registry.json +0 -0
  67. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/models.txt +0 -0
  68. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/personalities.py +0 -0
  69. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/platform_installer.py +0 -0
  70. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/__init__.py +0 -0
  71. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/hooks.py +0 -0
  72. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/loader.py +0 -0
  73. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/manager.py +0 -0
  74. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/registry.py +0 -0
  75. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/runtime.py +0 -0
  76. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/schema.py +0 -0
  77. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/plugins/tool_loader.py +0 -0
  78. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/reflection.py +0 -0
  79. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/report.py +0 -0
  80. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/scrapy_search.py +0 -0
  81. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/__init__.py +0 -0
  82. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/config.py +0 -0
  83. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/context.py +0 -0
  84. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/events.py +0 -0
  85. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/handlers.py +0 -0
  86. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/session.py +0 -0
  87. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/sdk/sidecar.py +0 -0
  88. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/__init__.py +0 -0
  89. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/admin_auth.py +0 -0
  90. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/attribution.py +0 -0
  91. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/audit_log.py +0 -0
  92. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/batch_processor.py +0 -0
  93. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/captcha.py +0 -0
  94. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/cli_auth.py +0 -0
  95. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/concurrency.py +0 -0
  96. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/SECRET_PROVISIONING.md +0 -0
  97. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/about.md +0 -0
  98. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/changelog.md +0 -0
  99. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/docs.md +0 -0
  100. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/features.md +0 -0
  101. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/license.md +0 -0
  102. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/privacy.md +0 -0
  103. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/refund.md +0 -0
  104. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/support.md +0 -0
  105. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/docs_md/terms.md +0 -0
  106. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/email_utils.py +0 -0
  107. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/exchange_rate.py +0 -0
  108. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/firebase.py +0 -0
  109. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/fix_duplicate_users.py +0 -0
  110. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/history.py +0 -0
  111. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/local_llm.py +0 -0
  112. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/logging_config.py +0 -0
  113. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/micro_batcher.py +0 -0
  114. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/model_agent.py +0 -0
  115. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/pricing_updater.py +0 -0
  116. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/provision_build.py +0 -0
  117. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/rate_limit.py +0 -0
  118. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/rewards_engine.py +0 -0
  119. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/__init__.py +0 -0
  120. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/admin_bonus_routes.py +0 -0
  121. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/admin_db_routes.py +0 -0
  122. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/auth_routes.py +0 -0
  123. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/billing_routes.py +0 -0
  124. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/credit_routes.py +0 -0
  125. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/feedback_routes.py +0 -0
  126. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/marketplace_routes.py +0 -0
  127. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/quota_share_routes.py +0 -0
  128. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/referral_routes.py +0 -0
  129. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/rewards_routes.py +0 -0
  130. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/security_routes.py +0 -0
  131. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/session_routes.py +0 -0
  132. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/share_routes.py +0 -0
  133. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/routes/webhook_routes.py +0 -0
  134. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/security_alerts.py +0 -0
  135. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/server.py +0 -0
  136. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/server/storage_nodes.py +0 -0
  137. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/share.py +0 -0
  138. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/share_tui.py +0 -0
  139. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/situational_scoring.py +0 -0
  140. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/state.py +0 -0
  141. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/subagent_manager.py +0 -0
  142. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/task_dispatcher.py +0 -0
  143. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/task_logger.py +0 -0
  144. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tools_grep.py +0 -0
  145. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/__init__.py +0 -0
  146. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/feedback_dialog.py +0 -0
  147. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/history_dialog.py +0 -0
  148. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/marketplace_app_state.py +0 -0
  149. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/marketplace_dialog.py +0 -0
  150. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/marketplace_layout_engine.py +0 -0
  151. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/mcp_dialog.py +0 -0
  152. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/miniagents_dialog.py +0 -0
  153. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/personality_dialog.py +0 -0
  154. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/publish_dialog.py +0 -0
  155. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/quota_dialog.py +0 -0
  156. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/quota_redeem_dialog.py +0 -0
  157. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/quota_share_dialog.py +0 -0
  158. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/resume_dialog.py +0 -0
  159. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/rewards_tui.py +0 -0
  160. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/skills_dialog.py +0 -0
  161. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/subagents_dialog.py +0 -0
  162. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/tasks_dialog.py +0 -0
  163. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/thinking_display.py +0 -0
  164. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/tui/update_dialog.py +0 -0
  165. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/update_checker.py +0 -0
  166. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/utilities.py +0 -0
  167. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/utimmodel.txt +0 -0
  168. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/vector_memory.py +0 -0
  169. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/wheel.py +0 -0
  170. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli/workspace.py +0 -0
  171. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli.egg-info/dependency_links.txt +0 -0
  172. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli.egg-info/entry_points.txt +0 -0
  173. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli.egg-info/requires.txt +0 -0
  174. {utim_cli-2.3.25 → utim_cli-2.4.0}/utim_cli.egg-info/top_level.txt +0 -0
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.4.0] - 2026-09-14
4
+
5
+ ### ✨ New Features & Enhancements
6
+ - Added native file tools for binary documents (Excel/`.xlsx`, Word/`.docx`, PDF/`.pdf`).
7
+ - Implemented `@mcp` sticky tags for automated daemon-like MCP server configuration without background processes.
8
+ - Eliminated typing input latency and UI lag by migrating `os.path.exists` checks to async background threads.
9
+ - Refactored Context Monitor with retro-active gap logic to instantly handle dynamic interval thresholds and sudden context bloat.
10
+
11
+ ### 🐛 Bug Fixes
12
+ - Fixed the CSV sniffer crashing when writing markdown tables to binary files.
13
+ - Fixed Windows path spacing errors during inline Python execution.
14
+ - Fixed UI rendering bugs where multi-line markdown boxes wouldn't flush to screen until refreshed.
15
+
16
+
17
+ ## [2.3.26] - 2026-09-08
18
+
19
+ ### 🛡️ Zero Rate-Limit Failover & Low-Latency Key Rotation
20
+ - **Deterministic APINEX Failover Chain**: Upstream APINEX failures (429/402/exhaustion) seamlessly cascade through `openrouter/free` -> `upstage/solar-pro4` -> `qwen/qwen3.7-flash` -> `deepseek/deepseek-v4-flash-0731` with zero wait latency and direct key pool acquisition.
21
+ - **Silent Rate-Limit Recovery**: Completely eliminated user-facing rate-limit interruptions, warnings, and 24-hour key lockout bans on transient provider 429s.
22
+ - **Zero-Latency Paid 402/429 Key Rotation**: OpenRouter keys returning 402 or 429 immediately rotate across candidate keys and seamlessly fail over to backup chain models without aborting active turns.
23
+
3
24
  ## [2.3.25] - 2026-09-07
4
25
 
5
26
  ### 🛠️ Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: utim-cli
3
- Version: 2.3.25
3
+ Version: 2.4.0
4
4
  Summary: UTIM – Universal Terminal Intelligence Manager. A powerful agentic AI coding assistant for your terminal.
5
5
  License: Emend AI Proprietary EULA
6
6
  Project-URL: Homepage, https://utim.dev
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "utim-cli"
7
- version = "2.3.25"
7
+ version = "2.4.0"
8
8
 
9
9
  description = "UTIM – Universal Terminal Intelligence Manager. A powerful agentic AI coding assistant for your terminal."
10
10
  readme = "README.md"
@@ -14,7 +14,7 @@ Quickstart:
14
14
  try:
15
15
  from utim_cli._version import VERSION as __version__
16
16
  except ImportError:
17
- __version__ = "2.3.25"
17
+ __version__ = "2.4.0"
18
18
 
19
19
  # Developer-friendly core classes (similar to `import genai` / `import openai`)
20
20
  from utim_cli.sdk.session import UtimSession as Session
@@ -5,7 +5,7 @@ try:
5
5
  from utim_cli._version import VERSION as __version__
6
6
  except ImportError:
7
7
  # Fallback during first-install / editable-install edge cases
8
- __version__ = "2.3.25"
8
+ __version__ = "2.4.0"
9
9
 
10
10
 
11
11
  import builtins, os, pathlib, urllib.parse, re
@@ -11,6 +11,6 @@
11
11
  # from here so every surface stays in sync automatically.
12
12
  # ─────────────────────────────────────────────────────────────────────────────
13
13
 
14
- VERSION = "2.3.25"
14
+ VERSION = "2.4.0"
15
15
 
16
16
 
@@ -182,6 +182,25 @@ class ReActAgent:
182
182
  "cmd": "run_command",
183
183
  "execute_command": "run_command",
184
184
  "view_file": "read_file",
185
+ "write_to_file": "write_file",
186
+ "create_file": "write_file",
187
+ "save_file": "write_file",
188
+ "str_replace_editor": "edit_file",
189
+ "replace_file_content": "edit_file",
190
+ "modify_file": "edit_file",
191
+ "update_file": "edit_file",
192
+ "edit": "edit_file",
193
+ "list_dir": "list_directory",
194
+ "dir": "list_directory",
195
+ "ls": "list_directory",
196
+ "search": "grep_search",
197
+ "search_codebase": "grep_search",
198
+ "grep": "grep_search",
199
+ "find_files": "find_by_name",
200
+ "find_file": "find_by_name",
201
+ "websearch": "web_search",
202
+ "search_web": "web_search",
203
+ "crawl": "crawl_web",
185
204
  }
186
205
  if tool_name in _TOOL_NAME_ALIASES:
187
206
  tool_name = _TOOL_NAME_ALIASES[tool_name]
@@ -249,7 +268,11 @@ class ReActAgent:
249
268
  return f"Error: Tool '{tool_name}' not found."
250
269
 
251
270
  try:
252
- result = tool_functions[tool_name](**arguments)
271
+ import inspect
272
+ sig = inspect.signature(tool_functions[tool_name])
273
+ has_var_kw = any(p.kind == inspect.Parameter.VAR_KEYWORD for p in sig.parameters.values())
274
+ filtered_args = dict(arguments) if has_var_kw else {k: v for k, v in arguments.items() if k in sig.parameters}
275
+ result = tool_functions[tool_name](**filtered_args)
253
276
  # Erase the running line first
254
277
  try:
255
278
  width = self.console.size.width
@@ -282,6 +305,7 @@ class ReActAgent:
282
305
  tool_calls = []
283
306
  current_tool_call = None
284
307
 
308
+ from utim_cli.client_utils import sanitize_tools_for_api, sanitize_messages_for_api, repair_and_normalize_tool_call
285
309
  utim_tools, tool_functions = get_tools()
286
310
  all_tools = utim_tools
287
311
 
@@ -291,11 +315,11 @@ class ReActAgent:
291
315
  "stream": True,
292
316
  }
293
317
  if all_tools:
294
- kwargs["tools"] = all_tools
318
+ kwargs["tools"] = sanitize_tools_for_api(all_tools, model_id=self.model_id)
295
319
 
296
320
  # Provider-safety pass: drop null/empty `tool_calls` keys from
297
321
  # history (strict providers 400 on `messages.N.tool_calls: null`).
298
- kwargs["messages"] = sanitize_messages_for_api(kwargs.get("messages") or [], model_id=getattr(self, "model", None))
322
+ kwargs["messages"] = sanitize_messages_for_api(kwargs.get("messages") or [], model_id=self.model_id)
299
323
 
300
324
  # Call the LLM with streaming (retry once on transport errors so a
301
325
  # mid-stream failure doesn't silently kill the whole run)
@@ -365,6 +389,9 @@ class ReActAgent:
365
389
  assistant_content = parsed_content or ""
366
390
  tool_calls.extend(parsed_tool_calls)
367
391
 
392
+ # Repair and normalize all tool calls (names, IDs, types, arguments)
393
+ tool_calls = [repair_and_normalize_tool_call(tc) for tc in tool_calls if tc]
394
+
368
395
  # Print any text content generated by the assistant
369
396
  if assistant_content.strip():
370
397
  self.console.print()
@@ -414,13 +441,14 @@ class ReActAgent:
414
441
  })
415
442
 
416
443
  # Execute each tool call
417
- for tc in tool_calls:
444
+ for i, tc in enumerate(tool_calls):
418
445
  result = self._execute_tool_call(tc)
419
446
 
420
- # Add tool result to messages
447
+ # Add tool result to messages with guaranteed matching tool_call_id
448
+ tc_id = tc.get("id") or f"call_{i}_{int(time.time()*1000)}"
421
449
  self.messages.append({
422
450
  "role": "tool",
423
- "tool_call_id": tc.get("id", ""),
451
+ "tool_call_id": tc_id,
424
452
  "content": result,
425
453
  })
426
454
  else: