utim-cli 2.3.26__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.
- {utim_cli-2.3.26 → utim_cli-2.4.0}/CHANGELOG.md +14 -0
- {utim_cli-2.3.26/utim_cli.egg-info → utim_cli-2.4.0}/PKG-INFO +1 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/pyproject.toml +1 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim/__init__.py +1 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/__init__.py +1 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/_version.py +1 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/agent.py +34 -6
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/bootstrap.py +617 -580
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/client_utils.py +324 -41
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/constants.py +2 -6
- utim_cli-2.4.0/utim_cli/context_inspector.py +341 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/context_pruner.py +644 -327
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/crawler/engine.py +3 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/orchestrator.py +139 -50
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/orchestrator_helpers.py +76 -20
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/orchestrator_llm_transport.py +126 -27
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/orchestrator_tool_exec.py +155 -3
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/orchestrator_turn_history.py +409 -250
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/auth.py +93 -50
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/db.py +189 -24
- utim_cli-2.4.0/utim_cli/server/docs_md/pricing.md +24 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/key_rotator.py +16 -91
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/models.py +42 -20
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/plan_integrity.py +9 -7
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/router.py +17 -165
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/completion_routes.py +127 -123
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/quota_routes.py +134 -56
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/utils.py +198 -65
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tools.py +686 -54
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/compression_dialog.py +11 -11
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/model_dialog.py +165 -3
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/plugins_dialog.py +11 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/tools_dialog.py +291 -273
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/utim.py +265 -64
- {utim_cli-2.3.26 → utim_cli-2.4.0/utim_cli.egg-info}/PKG-INFO +1 -1
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli.egg-info/SOURCES.txt +1 -0
- utim_cli-2.3.26/utim_cli/server/docs_md/pricing.md +0 -19
- {utim_cli-2.3.26 → utim_cli-2.4.0}/LICENSE +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/MANIFEST.in +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/README.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/setup.cfg +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/setup.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/_chip_test.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/_verify_repro.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/_verify_syntax.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/_wizard_smoke_test.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/ask_helper.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/auth.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/backup.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/billing.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/blender_agent.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/brain.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/builtin/skills/utim-guide/SKILL.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/config.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/crawler/__init__.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/crawler/markdown_distiller.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/dependency_manager.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/doctor.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/evidence_registry.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/harbor.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/knowledge_graph.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/local_db.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/logger.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/mcp_clean_wrapper.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/mcp_client.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/mcp_registry.json +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/models.txt +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/personalities.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/platform_installer.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/__init__.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/hooks.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/loader.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/manager.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/registry.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/runtime.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/schema.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/plugins/tool_loader.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/reflection.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/report.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/scrapy_search.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/__init__.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/config.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/context.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/events.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/handlers.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/session.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/sdk/sidecar.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/__init__.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/admin_auth.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/attribution.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/audit_log.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/batch_processor.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/captcha.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/cli_auth.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/concurrency.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/SECRET_PROVISIONING.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/about.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/changelog.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/docs.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/features.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/license.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/privacy.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/refund.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/support.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/docs_md/terms.md +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/email_utils.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/exchange_rate.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/firebase.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/fix_duplicate_users.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/history.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/local_llm.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/logging_config.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/micro_batcher.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/model_agent.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/pricing_updater.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/provision_build.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/rate_limit.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/rewards_engine.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/__init__.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/admin_bonus_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/admin_db_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/auth_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/billing_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/credit_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/feedback_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/marketplace_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/quota_share_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/referral_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/rewards_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/security_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/session_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/share_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/routes/webhook_routes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/security_alerts.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/server.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/server/storage_nodes.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/share.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/share_tui.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/situational_scoring.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/state.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/subagent_manager.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/task_dispatcher.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/task_logger.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tools_grep.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/__init__.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/feedback_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/history_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/marketplace_app_state.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/marketplace_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/marketplace_layout_engine.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/mcp_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/miniagents_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/personality_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/publish_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/quota_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/quota_redeem_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/quota_share_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/resume_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/rewards_tui.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/skills_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/subagents_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/tasks_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/thinking_display.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/tui/update_dialog.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/update_checker.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/utilities.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/utimmodel.txt +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/vector_memory.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/wheel.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli/workspace.py +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli.egg-info/dependency_links.txt +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli.egg-info/entry_points.txt +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli.egg-info/requires.txt +0 -0
- {utim_cli-2.3.26 → utim_cli-2.4.0}/utim_cli.egg-info/top_level.txt +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
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
|
+
|
|
3
17
|
## [2.3.26] - 2026-09-08
|
|
4
18
|
|
|
5
19
|
### 🛡️ Zero Rate-Limit Failover & Low-Latency Key Rotation
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: utim-cli
|
|
3
|
-
Version: 2.
|
|
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
|
|
@@ -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.
|
|
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
|
|
@@ -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
|
-
|
|
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=
|
|
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":
|
|
451
|
+
"tool_call_id": tc_id,
|
|
424
452
|
"content": result,
|
|
425
453
|
})
|
|
426
454
|
else:
|