|
7 | 7 | from typing import Any, Literal |
8 | 8 |
|
9 | 9 | import litellm |
10 | | -from jinja2 import StrictUndefined, Template |
11 | 10 | from pydantic import BaseModel |
12 | 11 |
|
13 | 12 | from minisweagent.exceptions import FormatError |
@@ -38,13 +37,6 @@ class LitellmModelConfig(BaseModel): |
38 | 37 | """Cost tracking mode for this model. Can be "default" or "ignore_errors" (ignore errors/missing cost info)""" |
39 | 38 | format_error_template: str = "{{ error }}" |
40 | 39 | """Template used when the LM's output is not in the expected format.""" |
41 | | - truncation_error_template: str = ( |
42 | | - "Your previous response reached the output token limit (finish_reason={{ finish_reason }}) " |
43 | | - "before you produced a tool call, so it was cut off. Respond more concisely and finish with " |
44 | | - "exactly one tool call. If you need to think more, do so briefly." |
45 | | - ) |
46 | | - """Template used when a response is truncated at max_tokens before a tool call is produced. |
47 | | - Distinct from format_error_template so the model is told it was cut off (not that it forgot).""" |
48 | 40 | observation_template: str = ( |
49 | 41 | "{% if output.exception_info %}<exception>{{output.exception_info}}</exception>\n{% endif %}" |
50 | 42 | "<returncode>{{output.returncode}}</returncode>\n<output>\n{{output.output}}</output>" |
@@ -102,20 +94,6 @@ def query(self, messages: list[dict[str, str]], **kwargs) -> dict: |
102 | 94 | # model_dump failed (e.g. unserializable object); fall back to repr |
103 | 95 | # so the spec contract ("response MUST be persisted") holds unconditionally. |
104 | 96 | e.messages[0]["extra"]["response"] = repr(response) |
105 | | - # If the response was cut off at the output token limit before a tool call (common with |
106 | | - # reasoning models whose thinking can consume the whole max_tokens budget), tell the |
107 | | - # model it was truncated instead of the misleading default "no tool call found" retry. |
108 | | - if self._is_truncated(response): |
109 | | - finish_reason = response.choices[0].finish_reason |
110 | | - e.messages[0]["content"] = Template( |
111 | | - self.config.truncation_error_template, undefined=StrictUndefined |
112 | | - ).render(finish_reason=finish_reason) |
113 | | - e.messages[0]["extra"]["truncated"] = True |
114 | | - logger.warning( |
115 | | - "Model response truncated at the output token limit (finish_reason=%s) " |
116 | | - "before a tool call -- consider raising max_tokens.", |
117 | | - finish_reason, |
118 | | - ) |
119 | 97 | raise |
120 | 98 | message = response.choices[0].message.model_dump() |
121 | 99 | message["extra"] = { |
@@ -151,22 +129,6 @@ def _parse_actions(self, response) -> list[dict]: |
151 | 129 | tool_calls = response.choices[0].message.tool_calls or [] |
152 | 130 | return parse_toolcall_actions(tool_calls, format_error_template=self.config.format_error_template) |
153 | 131 |
|
154 | | - @staticmethod |
155 | | - def _is_truncated(response) -> bool: |
156 | | - """Whether a no-tool-call response was cut off at the output token limit. |
157 | | -
|
158 | | - ``length`` means the completion was truncated mid-output; ``tool_calls`` with an empty |
159 | | - payload means it was cut right at the tool-call boundary. Both are budget truncations, |
160 | | - distinct from a model that simply ended its turn (``stop``/``end_turn``) without acting. |
161 | | - """ |
162 | | - try: |
163 | | - choice = response.choices[0] |
164 | | - finish_reason = choice.finish_reason |
165 | | - has_tool_calls = bool(choice.message.tool_calls) |
166 | | - except (AttributeError, IndexError): |
167 | | - return False |
168 | | - return finish_reason == "length" or (finish_reason == "tool_calls" and not has_tool_calls) |
169 | | - |
170 | 132 | def format_message(self, **kwargs) -> dict: |
171 | 133 | return expand_multimodal_content(kwargs, pattern=self.config.multimodal_regex) |
172 | 134 |
|
|
0 commit comments