|
32 | 32 |
|
33 | 33 | import httpx |
34 | 34 | from litellm import experimental_mcp_client |
35 | | -from litellm.types.utils import ChatCompletionMessageToolCall, Function, ModelResponse |
| 35 | +from litellm.types.utils import ModelResponse |
36 | 36 | from prompt_toolkit.patch_stdout import patch_stdout |
37 | 37 | from rich.console import Console |
38 | 38 |
|
39 | 39 | import cecli.prompts.utils.system as prompts |
40 | 40 | from cecli import __version__, models, urls, utils |
41 | 41 | from cecli.commands import Commands, SwitchCoderSignal |
42 | 42 | from cecli.exceptions import LiteLLMExceptions |
43 | | -from cecli.helpers import command_parser, coroutines, nested |
| 43 | +from cecli.helpers import command_parser, coroutines, nested, responses |
44 | 44 | from cecli.helpers.conversation import ( |
45 | 45 | ConversationChunks, |
46 | 46 | ConversationManager, |
@@ -1581,8 +1581,8 @@ async def run_one(self, user_message, preproc): |
1581 | 1581 | self.reflected_message = None |
1582 | 1582 | self.tool_reflection = False |
1583 | 1583 |
|
1584 | | - if float(self.total_cost) > self.cost_multiplier * nested.getter( |
1585 | | - self.args, "cost_limit", float("inf") |
| 1584 | + if float(self.total_cost) > self.cost_multiplier * ( |
| 1585 | + nested.getter(self.args, "cost_limit", float("inf")) or float("inf") |
1586 | 1586 | ): |
1587 | 1587 | if await self.io.confirm_ask( |
1588 | 1588 | "You have reached your configured cost limit. Continue?", |
@@ -3311,66 +3311,16 @@ def consolidate_chunks(self): |
3311 | 3311 | # If no native tool calls, check if the content contains JSON tool calls |
3312 | 3312 | # This handles models that write JSON in text instead of using native calling |
3313 | 3313 | if not self.partial_response_tool_calls and self.partial_response_content: |
3314 | | - try: |
3315 | | - # Simple extraction of JSON-like structures that look like tool calls |
3316 | | - # Only look for tool calls if it looks like JSON |
3317 | | - if "{" in self.partial_response_content or "[" in self.partial_response_content: |
3318 | | - json_chunks = utils.split_concatenated_json(self.partial_response_content) |
3319 | | - extracted_calls = [] |
3320 | | - chunk_index = 0 |
3321 | | - |
3322 | | - for chunk in json_chunks: |
3323 | | - chunk_index += 1 |
3324 | | - try: |
3325 | | - json_obj = json.loads(chunk) |
3326 | | - if ( |
3327 | | - isinstance(json_obj, dict) |
3328 | | - and "name" in json_obj |
3329 | | - and "arguments" in json_obj |
3330 | | - ): |
3331 | | - # Create a Pydantic model for the tool call |
3332 | | - function_obj = Function( |
3333 | | - name=json_obj["name"], |
3334 | | - arguments=( |
3335 | | - json.dumps(json_obj["arguments"]) |
3336 | | - if isinstance(json_obj["arguments"], (dict, list)) |
3337 | | - else str(json_obj["arguments"]) |
3338 | | - ), |
3339 | | - ) |
3340 | | - tool_call_obj = ChatCompletionMessageToolCall( |
3341 | | - type="function", |
3342 | | - function=function_obj, |
3343 | | - id=f"call_{len(extracted_calls)}_{int(time.time())}_{chunk_index}", |
3344 | | - ) |
3345 | | - extracted_calls.append(tool_call_obj) |
3346 | | - elif isinstance(json_obj, list): |
3347 | | - for item in json_obj: |
3348 | | - if ( |
3349 | | - isinstance(item, dict) |
3350 | | - and "name" in item |
3351 | | - and "arguments" in item |
3352 | | - ): |
3353 | | - function_obj = Function( |
3354 | | - name=item["name"], |
3355 | | - arguments=( |
3356 | | - json.dumps(item["arguments"]) |
3357 | | - if isinstance(item["arguments"], (dict, list)) |
3358 | | - else str(item["arguments"]) |
3359 | | - ), |
3360 | | - ) |
3361 | | - tool_call_obj = ChatCompletionMessageToolCall( |
3362 | | - type="function", |
3363 | | - function=function_obj, |
3364 | | - id=f"call_{len(extracted_calls)}_{int(time.time())}_{chunk_index}", |
3365 | | - ) |
3366 | | - extracted_calls.append(tool_call_obj) |
3367 | | - except json.JSONDecodeError: |
3368 | | - continue |
3369 | | - |
3370 | | - if extracted_calls: |
3371 | | - self.partial_response_tool_calls = extracted_calls |
3372 | | - except Exception: |
3373 | | - pass |
| 3314 | + extracted_calls = responses.extract_tools_from_content_json( |
| 3315 | + self.partial_response_content |
| 3316 | + ) |
| 3317 | + if not extracted_calls: |
| 3318 | + extracted_calls = responses.extract_tools_from_content_xml( |
| 3319 | + self.partial_response_content |
| 3320 | + ) |
| 3321 | + |
| 3322 | + if extracted_calls: |
| 3323 | + self.partial_response_tool_calls = extracted_calls |
3374 | 3324 |
|
3375 | 3325 | return response, func_err, content_err |
3376 | 3326 |
|
|
0 commit comments