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.
Files changed (145) hide show
  1. {utim_cli-2.3.1 → utim_cli-2.3.2}/CHANGELOG.md +5 -0
  2. {utim_cli-2.3.1/utim_cli.egg-info → utim_cli-2.3.2}/PKG-INFO +1 -1
  3. {utim_cli-2.3.1 → utim_cli-2.3.2}/pyproject.toml +1 -1
  4. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/__init__.py +1 -1
  5. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/_version.py +1 -1
  6. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/context_pruner.py +19 -32
  7. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/orchestrator.py +169 -247
  8. utim_cli-2.3.2/utim_cli/plugins/__init__.py +10 -0
  9. utim_cli-2.3.2/utim_cli/plugins/manager.py +465 -0
  10. utim_cli-2.3.2/utim_cli/plugins/registry.py +120 -0
  11. utim_cli-2.3.2/utim_cli/plugins/schema.py +230 -0
  12. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/auth.py +11 -47
  13. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/db.py +0 -47
  14. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/micro_batcher.py +12 -18
  15. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/rate_limit.py +9 -5
  16. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/router.py +3 -1
  17. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/__init__.py +3 -1
  18. utim_cli-2.3.2/utim_cli/server/routes/admin_db_routes.py +507 -0
  19. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/completion_routes.py +52 -40
  20. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/quota_routes.py +76 -12
  21. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/share.py +99 -99
  22. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/state.py +0 -1
  23. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/task_dispatcher.py +62 -20
  24. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tools.py +0 -12
  25. utim_cli-2.3.2/utim_cli/tui/plugins_dialog.py +351 -0
  26. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/utim.py +20 -38
  27. {utim_cli-2.3.1 → utim_cli-2.3.2/utim_cli.egg-info}/PKG-INFO +1 -1
  28. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/SOURCES.txt +6 -6
  29. utim_cli-2.3.1/utim_cli/_check_obj.py +0 -9
  30. utim_cli-2.3.1/utim_cli/_find_mcp.py +0 -9
  31. utim_cli-2.3.1/utim_cli/_find_plan.py +0 -12
  32. utim_cli-2.3.1/utim_cli/_find_tool.py +0 -10
  33. utim_cli-2.3.1/utim_cli/_patch_multimodal.py +0 -125
  34. utim_cli-2.3.1/utim_cli/_test_regex.py +0 -22
  35. {utim_cli-2.3.1 → utim_cli-2.3.2}/LICENSE +0 -0
  36. {utim_cli-2.3.1 → utim_cli-2.3.2}/MANIFEST.in +0 -0
  37. {utim_cli-2.3.1 → utim_cli-2.3.2}/README.md +0 -0
  38. {utim_cli-2.3.1 → utim_cli-2.3.2}/setup.cfg +0 -0
  39. {utim_cli-2.3.1 → utim_cli-2.3.2}/setup.py +0 -0
  40. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim/__init__.py +0 -0
  41. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/agent.py +0 -0
  42. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/ask_helper.py +0 -0
  43. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/auth.py +0 -0
  44. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/backup.py +0 -0
  45. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/billing.py +0 -0
  46. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/blender_agent.py +0 -0
  47. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/bootstrap.py +0 -0
  48. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/brain.py +0 -0
  49. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/client_utils.py +0 -0
  50. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/config.py +0 -0
  51. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/constants.py +0 -0
  52. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/doctor.py +0 -0
  53. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/harbor.py +0 -0
  54. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/knowledge_graph.py +0 -0
  55. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/local_db.py +0 -0
  56. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/logger.py +0 -0
  57. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/mcp_clean_wrapper.py +0 -0
  58. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/mcp_client.py +0 -0
  59. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/mcp_registry.json +0 -0
  60. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/models.txt +0 -0
  61. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/reflection.py +0 -0
  62. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/report.py +0 -0
  63. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/scrapy_search.py +0 -0
  64. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/__init__.py +0 -0
  65. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/config.py +0 -0
  66. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/context.py +0 -0
  67. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/events.py +0 -0
  68. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/handlers.py +0 -0
  69. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/session.py +0 -0
  70. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/sdk/sidecar.py +0 -0
  71. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/__init__.py +0 -0
  72. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/admin_auth.py +0 -0
  73. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/attribution.py +0 -0
  74. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/audit_log.py +0 -0
  75. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/batch_processor.py +0 -0
  76. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/captcha.py +0 -0
  77. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/cli_auth.py +0 -0
  78. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/SECRET_PROVISIONING.md +0 -0
  79. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/about.md +0 -0
  80. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/changelog.md +0 -0
  81. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/docs.md +0 -0
  82. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/features.md +0 -0
  83. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/license.md +0 -0
  84. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/pricing.md +0 -0
  85. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/privacy.md +0 -0
  86. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/refund.md +0 -0
  87. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/support.md +0 -0
  88. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/docs_md/terms.md +0 -0
  89. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/email_utils.py +0 -0
  90. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/exchange_rate.py +0 -0
  91. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/firebase.py +0 -0
  92. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/fix_duplicate_users.py +0 -0
  93. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/history.py +0 -0
  94. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/local_llm.py +0 -0
  95. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/logging_config.py +0 -0
  96. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/model_agent.py +0 -0
  97. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/models.py +0 -0
  98. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/pricing_updater.py +0 -0
  99. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/provision_build.py +0 -0
  100. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/rewards_engine.py +0 -0
  101. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/auth_routes.py +0 -0
  102. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/billing_routes.py +0 -0
  103. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/credit_routes.py +0 -0
  104. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/feedback_routes.py +0 -0
  105. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/marketplace_routes.py +0 -0
  106. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/quota_share_routes.py +0 -0
  107. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/referral_routes.py +0 -0
  108. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/rewards_routes.py +0 -0
  109. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/security_routes.py +0 -0
  110. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/session_routes.py +0 -0
  111. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/routes/share_routes.py +0 -0
  112. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/server.py +0 -0
  113. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/server/storage_nodes.py +0 -0
  114. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/share_tui.py +0 -0
  115. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/situational_scoring.py +0 -0
  116. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/subagent_manager.py +0 -0
  117. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/__init__.py +0 -0
  118. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/feedback_dialog.py +0 -0
  119. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/history_dialog.py +0 -0
  120. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/marketplace_app_state.py +0 -0
  121. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/marketplace_dialog.py +0 -0
  122. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/marketplace_layout_engine.py +0 -0
  123. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/mcp_dialog.py +0 -0
  124. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/miniagents_dialog.py +0 -0
  125. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/model_dialog.py +0 -0
  126. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/publish_dialog.py +0 -0
  127. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/quota_dialog.py +0 -0
  128. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/quota_redeem_dialog.py +0 -0
  129. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/quota_share_dialog.py +0 -0
  130. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/resume_dialog.py +0 -0
  131. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/rewards_tui.py +0 -0
  132. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/skills_dialog.py +0 -0
  133. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/subagents_dialog.py +0 -0
  134. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/thinking_display.py +0 -0
  135. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/tools_dialog.py +0 -0
  136. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/tui/update_dialog.py +0 -0
  137. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/utilities.py +0 -0
  138. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/utimmodel.txt +0 -0
  139. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/vector_memory.py +0 -0
  140. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/wheel.py +0 -0
  141. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli/workspace.py +0 -0
  142. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/dependency_links.txt +0 -0
  143. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/entry_points.txt +0 -0
  144. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/requires.txt +0 -0
  145. {utim_cli-2.3.1 → utim_cli-2.3.2}/utim_cli.egg-info/top_level.txt +0 -0
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.3.2] - 2026-08-20
4
+
5
+ ### 🚀 Performance & Fixes
6
+ - Token usage optimization and bug fixes
7
+
3
8
  ## [2.3.1] - 2026-08-19
4
9
 
5
10
  ### 🛠️ Fixes & Enhancements
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: utim-cli
3
- Version: 2.3.1
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "utim-cli"
7
- version = "2.3.1"
7
+ version = "2.3.2"
8
8
 
9
9
  description = "UTIM – Universal Terminal Intelligence Manager. A powerful agentic AI coding assistant for your terminal."
10
10
  readme = "README.md"
@@ -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.1"
8
+ __version__ = "2.3.2"
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.1"
14
+ VERSION = "2.3.2"
15
15
 
16
16
 
@@ -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], keep_last_tools: int = 5) -> 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
- The last 5 tool outputs must NEVER be deduplicated, truncated, or stubbed out,
110
- even if they are duplicates of earlier reads, because the model requires the exact
111
- code lines and context to execute precise file edits and tool actions.
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
- # Identify indices of all tool messages
114
- tool_msg_indices = [i for i, m in enumerate(messages) if m.get("role") == "tool"]
115
- exempt_indices = set(tool_msg_indices[-keep_last_tools:]) if len(tool_msg_indices) >= 1 else set()
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 i, msg in enumerate(messages):
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 older duplicate with stub
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], keep_last_tools: int = 5) -> 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 older repeated identical tool outputs (strictly preserving the last 5 tool calls verbatim).
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 older duplicate tool outputs while protecting last 5 tool calls
351
- messages = _deduplicate_tool_outputs(messages, keep_last_tools=keep_last_tools)
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 = 5,
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` (at least 5) tool results & their assistant calls are kept 100% verbatim.
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, keep_last_tools=keep_last_tools)
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, keep_last_tools=keep_last_tools)
526
+ return sanitize_message_sequence(result_messages)
540
527
 
541
528
 
542
529
  def score_message_importance(message: Dict, llm_key: str = None) -> float: