mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-09 22:31:41 +00:00
feat(advisor): add replace_with_text param to strip_advisor_blocks_from_messages
This commit is contained in:
parent
23e20facb6
commit
a89b0672c7
1 changed files with 70 additions and 21 deletions
|
|
@ -639,15 +639,23 @@ class AnthropicModelInfo(BaseLLMModelInfo):
|
|||
return AnthropicTokenCounter()
|
||||
|
||||
|
||||
def strip_advisor_blocks_from_messages(messages: List[Any]) -> List[Any]:
|
||||
def strip_advisor_blocks_from_messages(
|
||||
messages: List[Any], replace_with_text: bool = False
|
||||
) -> List[Any]:
|
||||
"""
|
||||
Remove server_tool_use (name='advisor') and advisor_tool_result blocks from
|
||||
assistant message content when the advisor tool is absent from the request.
|
||||
Remove (or replace) server_tool_use (name='advisor') and advisor_tool_result blocks
|
||||
from assistant message content.
|
||||
|
||||
Prevents Anthropic 400 invalid_request_error: if advisor_tool_result blocks
|
||||
exist in history but the advisor tool is not in the tools array, the API rejects
|
||||
the request. This happens when the user has removed the advisor tool for cost
|
||||
control or on a follow-up turn.
|
||||
|
||||
Args:
|
||||
messages: Conversation history to process (mutated in-place).
|
||||
replace_with_text: When True, replace the advisor exchange with an
|
||||
<advisor_feedback> text block so the executor retains the semantic
|
||||
context of what the advisor said. When False (default), strip silently.
|
||||
"""
|
||||
for message in messages:
|
||||
if not isinstance(message, dict) or message.get("role") != "assistant":
|
||||
|
|
@ -655,7 +663,9 @@ def strip_advisor_blocks_from_messages(messages: List[Any]) -> List[Any]:
|
|||
content = message.get("content")
|
||||
if not isinstance(content, list):
|
||||
continue
|
||||
advisor_ids: set = set()
|
||||
|
||||
# Collect advisor server_tool_use ids and their advice text (for replace mode).
|
||||
advisor_id_to_text: dict = {}
|
||||
for block in content:
|
||||
if (
|
||||
isinstance(block, dict)
|
||||
|
|
@ -664,26 +674,65 @@ def strip_advisor_blocks_from_messages(messages: List[Any]) -> List[Any]:
|
|||
):
|
||||
bid = block.get("id")
|
||||
if bid:
|
||||
advisor_ids.add(bid)
|
||||
if not advisor_ids:
|
||||
advisor_id_to_text[bid] = None # text filled in below
|
||||
|
||||
if not advisor_id_to_text:
|
||||
continue
|
||||
message["content"] = [
|
||||
block
|
||||
for block in content
|
||||
if not (
|
||||
isinstance(block, dict)
|
||||
and (
|
||||
(
|
||||
block.get("type") == "server_tool_use"
|
||||
and block.get("name") == "advisor"
|
||||
|
||||
# If replacing, collect the advisor response text from advisor_tool_result blocks.
|
||||
if replace_with_text:
|
||||
for block in content:
|
||||
if (
|
||||
isinstance(block, dict)
|
||||
and block.get("type") == "advisor_tool_result"
|
||||
and block.get("tool_use_id") in advisor_id_to_text
|
||||
):
|
||||
raw = block.get("content") or ""
|
||||
text = (
|
||||
raw
|
||||
if isinstance(raw, str)
|
||||
else next(
|
||||
(
|
||||
b.get("text", "")
|
||||
for b in raw
|
||||
if isinstance(b, dict) and b.get("type") == "text"
|
||||
),
|
||||
"",
|
||||
)
|
||||
)
|
||||
or (
|
||||
block.get("type") == "advisor_tool_result"
|
||||
and block.get("tool_use_id") in advisor_ids
|
||||
)
|
||||
)
|
||||
advisor_id_to_text[block["tool_use_id"]] = text
|
||||
|
||||
new_content = []
|
||||
for block in content:
|
||||
if not isinstance(block, dict):
|
||||
new_content.append(block)
|
||||
continue
|
||||
is_advisor_use = (
|
||||
block.get("type") == "server_tool_use"
|
||||
and block.get("name") == "advisor"
|
||||
and block.get("id") in advisor_id_to_text
|
||||
)
|
||||
]
|
||||
is_advisor_result = (
|
||||
block.get("type") == "advisor_tool_result"
|
||||
and block.get("tool_use_id") in advisor_id_to_text
|
||||
)
|
||||
if is_advisor_use:
|
||||
if replace_with_text:
|
||||
advice = advisor_id_to_text.get(block.get("id")) or ""
|
||||
if advice:
|
||||
new_content.append(
|
||||
{
|
||||
"type": "text",
|
||||
"text": f"<advisor_feedback>\n{advice}\n</advisor_feedback>",
|
||||
}
|
||||
)
|
||||
# else: drop silently
|
||||
elif is_advisor_result:
|
||||
pass # always drop — replaced above (or stripped)
|
||||
else:
|
||||
new_content.append(block)
|
||||
|
||||
message["content"] = new_content
|
||||
return messages
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue