utim-cli 2.3.1__tar.gz → 2.3.2__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.1 → utim_cli-2.3.2}/CHANGELOG.md +5 -0
- {utim_cli-2.3.1/utim_cli.egg-info → utim_cli-2.3.2}/PKG-INFO +1 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/pyproject.toml +1 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/__init__.py +1 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/_version.py +1 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/context_pruner.py +19 -32
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/orchestrator.py +169 -247
- utim_cli-2.3.2/utim_cli/plugins/__init__.py +10 -0
- utim_cli-2.3.2/utim_cli/plugins/manager.py +465 -0
- utim_cli-2.3.2/utim_cli/plugins/registry.py +120 -0
- utim_cli-2.3.2/utim_cli/plugins/schema.py +230 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/auth.py +11 -47
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/db.py +0 -47
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/micro_batcher.py +12 -18
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/rate_limit.py +9 -5
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/router.py +3 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/__init__.py +3 -1
- utim_cli-2.3.2/utim_cli/server/routes/admin_db_routes.py +507 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/completion_routes.py +52 -40
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/quota_routes.py +76 -12
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/share.py +99 -99
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/state.py +0 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/task_dispatcher.py +62 -20
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tools.py +0 -12
- utim_cli-2.3.2/utim_cli/tui/plugins_dialog.py +351 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/utim.py +20 -38
- {utim_cli-2.3.1 → utim_cli-2.3.2/utim_cli.egg-info}/PKG-INFO +1 -1
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/SOURCES.txt +6 -6
- utim_cli-2.3.1/utim_cli/_check_obj.py +0 -9
- utim_cli-2.3.1/utim_cli/_find_mcp.py +0 -9
- utim_cli-2.3.1/utim_cli/_find_plan.py +0 -12
- utim_cli-2.3.1/utim_cli/_find_tool.py +0 -10
- utim_cli-2.3.1/utim_cli/_patch_multimodal.py +0 -125
- utim_cli-2.3.1/utim_cli/_test_regex.py +0 -22
- {utim_cli-2.3.1 → utim_cli-2.3.2}/LICENSE +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/MANIFEST.in +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/README.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/setup.cfg +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/setup.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim/__init__.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/agent.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/ask_helper.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/auth.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/backup.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/billing.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/blender_agent.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/bootstrap.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/brain.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/client_utils.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/config.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/constants.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/doctor.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/harbor.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/knowledge_graph.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/local_db.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/logger.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/mcp_clean_wrapper.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/mcp_client.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/mcp_registry.json +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/models.txt +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/reflection.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/report.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/scrapy_search.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/__init__.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/config.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/context.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/events.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/handlers.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/session.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/sidecar.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/__init__.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/admin_auth.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/attribution.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/audit_log.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/batch_processor.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/captcha.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/cli_auth.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/SECRET_PROVISIONING.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/about.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/changelog.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/docs.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/features.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/license.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/pricing.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/privacy.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/refund.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/support.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/terms.md +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/email_utils.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/exchange_rate.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/firebase.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/fix_duplicate_users.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/history.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/local_llm.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/logging_config.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/model_agent.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/models.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/pricing_updater.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/provision_build.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/rewards_engine.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/auth_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/billing_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/credit_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/feedback_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/marketplace_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/quota_share_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/referral_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/rewards_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/security_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/session_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/share_routes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/server.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/storage_nodes.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/share_tui.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/situational_scoring.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/subagent_manager.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/__init__.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/feedback_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/history_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/marketplace_app_state.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/marketplace_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/marketplace_layout_engine.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/mcp_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/miniagents_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/model_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/publish_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/quota_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/quota_redeem_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/quota_share_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/resume_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/rewards_tui.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/skills_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/subagents_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/thinking_display.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/tools_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/update_dialog.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/utilities.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/utimmodel.txt +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/vector_memory.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/wheel.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/workspace.py +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/dependency_links.txt +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/entry_points.txt +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/requires.txt +0 -0
- {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: utim-cli
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.2
|
|
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
|
|
@@ -102,40 +102,27 @@ def _strip_thinking_blocks(messages: List[Dict], keep_last: int = 1) -> List[Dic
|
|
|
102
102
|
return result
|
|
103
103
|
|
|
104
104
|
|
|
105
|
-
def _deduplicate_tool_outputs(messages: List[Dict]
|
|
106
|
-
"""Compress repeated identical tool responses to a one-liner stub
|
|
107
|
-
WHILE STRICTLY PRESERVING the most recent `keep_last_tools` tool outputs 100% verbatim.
|
|
105
|
+
def _deduplicate_tool_outputs(messages: List[Dict]) -> List[Dict]:
|
|
106
|
+
"""Compress repeated identical tool responses to a one-liner stub.
|
|
108
107
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
When the agent calls the same tool with the same arguments repeatedly and gets
|
|
109
|
+
the same output (e.g. re-reading an unchanged file multiple times), only the
|
|
110
|
+
first occurrence is kept verbatim. Subsequent duplicates are replaced with:
|
|
111
|
+
[Duplicate tool output — identical to earlier result, omitted to save tokens]
|
|
112
112
|
"""
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
seen: dict = {} # (tool_name, content_hash) -> True
|
|
113
|
+
# Map: (tool_call_id_of_preceding_assistant_call -> output_hash)
|
|
114
|
+
# We key on (tool_name, args_hash) -> first_output_hash seen
|
|
115
|
+
seen: dict = {} # (tool_name_or_id, content_hash) -> True
|
|
118
116
|
result = []
|
|
119
117
|
|
|
120
|
-
for
|
|
118
|
+
for msg in messages:
|
|
121
119
|
if msg.get("role") == "tool":
|
|
122
120
|
content = msg.get("content") or ""
|
|
123
121
|
tool_name = msg.get("name", "")
|
|
124
|
-
|
|
125
|
-
# CRITICAL: Never deduplicate or stub any of the last 5 tool calls!
|
|
126
|
-
if i in exempt_indices:
|
|
127
|
-
result.append(msg)
|
|
128
|
-
continue
|
|
129
|
-
|
|
130
|
-
# Never deduplicate tool error messages
|
|
131
|
-
if isinstance(content, str) and any(err in content.lower() for err in ["error", "exception", "failed", "failure", "traceback", "syntaxerror", "not found"]):
|
|
132
|
-
result.append(msg)
|
|
133
|
-
continue
|
|
134
|
-
|
|
135
122
|
# Use first 300 chars of content for the hash to avoid hashing huge outputs
|
|
136
123
|
content_key = (tool_name, hashlib.md5(content[:300].encode(errors="replace")).hexdigest())
|
|
137
124
|
if content_key in seen and len(content) > 200:
|
|
138
|
-
# Replace
|
|
125
|
+
# Replace with stub
|
|
139
126
|
msg = dict(msg)
|
|
140
127
|
msg["content"] = (
|
|
141
128
|
f"[Duplicate {tool_name!r} output — identical to earlier result, "
|
|
@@ -333,13 +320,13 @@ def resolve_model_context_envelope(model_id: str, raw_context_window: int = 0) -
|
|
|
333
320
|
}
|
|
334
321
|
|
|
335
322
|
|
|
336
|
-
def sanitize_message_sequence(messages: List[Dict]
|
|
323
|
+
def sanitize_message_sequence(messages: List[Dict]) -> List[Dict]:
|
|
337
324
|
"""
|
|
338
325
|
Ensure the messages list is valid for LLM API calls.
|
|
339
326
|
- Each tool message must have a preceding assistant message with the matching tool_call_id.
|
|
340
327
|
- Each assistant message with tool_calls must have corresponding tool messages.
|
|
341
328
|
- Strips <think> blocks from non-current assistant messages to save tokens.
|
|
342
|
-
- Deduplicates
|
|
329
|
+
- Deduplicates repeated identical tool outputs.
|
|
343
330
|
"""
|
|
344
331
|
if not messages:
|
|
345
332
|
return messages
|
|
@@ -347,8 +334,8 @@ def sanitize_message_sequence(messages: List[Dict], keep_last_tools: int = 5) ->
|
|
|
347
334
|
# Strip thinking blocks from older assistant messages
|
|
348
335
|
messages = _strip_thinking_blocks(messages)
|
|
349
336
|
|
|
350
|
-
# Compress
|
|
351
|
-
messages = _deduplicate_tool_outputs(messages
|
|
337
|
+
# Compress duplicate tool outputs
|
|
338
|
+
messages = _deduplicate_tool_outputs(messages)
|
|
352
339
|
|
|
353
340
|
# Step 1: Identify all tool call IDs present in tool messages
|
|
354
341
|
present_tool_ids = {
|
|
@@ -400,7 +387,7 @@ def sanitize_message_sequence(messages: List[Dict], keep_last_tools: int = 5) ->
|
|
|
400
387
|
def soft_prune_messages(
|
|
401
388
|
messages: List[Dict],
|
|
402
389
|
turn_msg_start: int = 1,
|
|
403
|
-
keep_last_tools: int =
|
|
390
|
+
keep_last_tools: int = 4,
|
|
404
391
|
max_char_threshold: int = 1200,
|
|
405
392
|
) -> List[Dict]:
|
|
406
393
|
"""
|
|
@@ -408,7 +395,7 @@ def soft_prune_messages(
|
|
|
408
395
|
|
|
409
396
|
Balanced policy ('not too aggressive, not too light'):
|
|
410
397
|
- Anchors: System prompt (idx 0) and the root User prompt (turn_msg_start) are strictly preserved.
|
|
411
|
-
- Active Working Tail: The most recent `keep_last_tools`
|
|
398
|
+
- Active Working Tail: The most recent `keep_last_tools` tool results & their assistant calls are kept 100% verbatim.
|
|
412
399
|
- Errors / Failures: Any tool output containing error keywords (e.g. 'error', 'exception', 'failed', 'traceback', 'syntaxerror') is preserved verbatim to prevent debugging amnesia.
|
|
413
400
|
- Read / Search Outputs (older than tail): If longer than `max_char_threshold`, softly truncates the middle (keeps head 350 chars + tail 200 chars) with a clean diagnostic placeholder.
|
|
414
401
|
- Successful Mutation / Command Outputs: If verbose, compacted to clean status indicators without losing file targets.
|
|
@@ -430,7 +417,7 @@ def soft_prune_messages(
|
|
|
430
417
|
|
|
431
418
|
# If not enough tool messages have accumulated in this turn, just sanitize and return
|
|
432
419
|
if len(tool_indices) <= keep_last_tools:
|
|
433
|
-
return sanitize_message_sequence(cleaned_messages
|
|
420
|
+
return sanitize_message_sequence(cleaned_messages)
|
|
434
421
|
|
|
435
422
|
# Older tool message indices that are eligible for soft pruning
|
|
436
423
|
eligible_tool_indices = set(tool_indices[:-keep_last_tools])
|
|
@@ -536,7 +523,7 @@ def soft_prune_messages(
|
|
|
536
523
|
|
|
537
524
|
result_messages.append(msg)
|
|
538
525
|
|
|
539
|
-
return sanitize_message_sequence(result_messages
|
|
526
|
+
return sanitize_message_sequence(result_messages)
|
|
540
527
|
|
|
541
528
|
|
|
542
529
|
def score_message_importance(message: Dict, llm_key: str = None) -> float:
|