mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
fix(backend): Use raw content from the LLM as conversation history (#9551)
### Changes 🏗️ Instead of parsing an LlmMessage by ourselves, we use raw content from the LLM as conversation history and accept any format it introduces. Example output: ``` [ { "role": "system", "content": "Thinking carefully step by step decide which function to call. Always choose a function call from the list of function signatures. The test graph is basically an all knowing answer machine you can use it to get an answer" }, { "role": "user", "content": "Hey how's the weather today" }, { "role": "assistant", "audio": null, "content": null, "refusal": null, "tool_calls": [ { "id": "call_Z7CKKIkldylmfWJdE6ZnDxjr", "type": "function", "function": { "name": "storevalueblock", "arguments": "{\"input\":\"I don't have context for your location. Could you provide one?\"}" } } ], "function_call": null } ] ``` ### Checklist 📋 #### For code changes: - [ ] I have clearly listed my changes in the PR description - [ ] I have made a test plan - [ ] I have tested my changes according to the test plan: <!-- Put your test plan here: --> - [ ] ... <details> <summary>Example test plan</summary> - [ ] Create from scratch and execute an agent with at least 3 blocks - [ ] Import an agent from file upload, and confirm it executes correctly - [ ] Upload agent to marketplace - [ ] Import an agent from marketplace and confirm it executes correctly - [ ] Edit an agent from monitor, and confirm it executes correctly </details> #### For configuration changes: - [ ] `.env.example` is updated or already compatible with my changes - [ ] `docker-compose.yml` is updated or already compatible with my changes - [ ] I have included a list of my configuration changes in the PR description (under **Changes**) <details> <summary>Examples of configuration changes</summary> - Changing ports - Adding new services that need to communicate with each other - Secrets or environment variable changes - New or infrastructure changes such as databases </details>
This commit is contained in:
@@ -229,17 +229,6 @@ for model in LlmModel:
|
||||
raise ValueError(f"Missing MODEL_METADATA metadata for model: {model}")
|
||||
|
||||
|
||||
class MessageRole(str, Enum):
|
||||
SYSTEM = "system"
|
||||
USER = "user"
|
||||
ASSISTANT = "assistant"
|
||||
|
||||
|
||||
class Message(BlockSchema):
|
||||
role: MessageRole
|
||||
content: str
|
||||
|
||||
|
||||
class ToolCall(BaseModel):
|
||||
name: str
|
||||
arguments: str
|
||||
@@ -252,7 +241,8 @@ class ToolContentBlock(BaseModel):
|
||||
|
||||
|
||||
class LLMResponse(BaseModel):
|
||||
prompt: str
|
||||
raw_response: Any
|
||||
prompt: List[Any]
|
||||
response: str
|
||||
tool_calls: Optional[List[ToolContentBlock]] | None
|
||||
prompt_tokens: int
|
||||
@@ -362,7 +352,8 @@ def llm_call(
|
||||
tool_calls = None
|
||||
|
||||
return LLMResponse(
|
||||
prompt=json.dumps(prompt),
|
||||
raw_response=response.choices[0].message,
|
||||
prompt=prompt,
|
||||
response=response.choices[0].message.content or "",
|
||||
tool_calls=tool_calls,
|
||||
prompt_tokens=response.usage.prompt_tokens if response.usage else 0,
|
||||
@@ -423,7 +414,8 @@ def llm_call(
|
||||
)
|
||||
|
||||
return LLMResponse(
|
||||
prompt=json.dumps(prompt),
|
||||
raw_response=resp.content[0],
|
||||
prompt=prompt,
|
||||
response=(
|
||||
resp.content[0].name
|
||||
if isinstance(resp.content[0], anthropic.types.ToolUseBlock)
|
||||
@@ -450,7 +442,8 @@ def llm_call(
|
||||
max_tokens=max_tokens,
|
||||
)
|
||||
return LLMResponse(
|
||||
prompt=json.dumps(prompt),
|
||||
raw_response=response.choices[0].message,
|
||||
prompt=prompt,
|
||||
response=response.choices[0].message.content or "",
|
||||
tool_calls=None,
|
||||
prompt_tokens=response.usage.prompt_tokens if response.usage else 0,
|
||||
@@ -469,7 +462,8 @@ def llm_call(
|
||||
stream=False,
|
||||
)
|
||||
return LLMResponse(
|
||||
prompt=json.dumps(prompt),
|
||||
raw_response=response.get("response") or "",
|
||||
prompt=prompt,
|
||||
response=response.get("response") or "",
|
||||
tool_calls=None,
|
||||
prompt_tokens=response.get("prompt_eval_count") or 0,
|
||||
@@ -515,7 +509,8 @@ def llm_call(
|
||||
tool_calls = None
|
||||
|
||||
return LLMResponse(
|
||||
prompt=json.dumps(prompt),
|
||||
raw_response=response.choices[0].message,
|
||||
prompt=prompt,
|
||||
response=response.choices[0].message.content or "",
|
||||
tool_calls=tool_calls,
|
||||
prompt_tokens=response.usage.prompt_tokens if response.usage else 0,
|
||||
@@ -557,7 +552,7 @@ class AIStructuredResponseGeneratorBlock(AIBlockBase):
|
||||
default="",
|
||||
description="The system prompt to provide additional context to the model.",
|
||||
)
|
||||
conversation_history: list[Message] = SchemaField(
|
||||
conversation_history: list[Any] = SchemaField(
|
||||
default=[],
|
||||
description="The conversation history to provide context for the prompt.",
|
||||
)
|
||||
@@ -613,7 +608,8 @@ class AIStructuredResponseGeneratorBlock(AIBlockBase):
|
||||
],
|
||||
test_mock={
|
||||
"llm_call": lambda *args, **kwargs: LLMResponse(
|
||||
prompt="",
|
||||
raw_response="",
|
||||
prompt=[""],
|
||||
response=json.dumps(
|
||||
{
|
||||
"key1": "key1Value",
|
||||
@@ -1032,7 +1028,7 @@ class AITextSummarizerBlock(AIBlockBase):
|
||||
|
||||
class AIConversationBlock(AIBlockBase):
|
||||
class Input(BlockSchema):
|
||||
messages: List[Message] = SchemaField(
|
||||
messages: List[Any] = SchemaField(
|
||||
description="List of messages in the conversation.", min_length=1
|
||||
)
|
||||
model: LlmModel = SchemaField(
|
||||
|
||||
@@ -53,7 +53,7 @@ class SmartDecisionMakerBlock(Block):
|
||||
default="Thinking carefully step by step decide which function to call. Always choose a function call from the list of function signatures.",
|
||||
description="The system prompt to provide additional context to the model.",
|
||||
)
|
||||
conversation_history: list[llm.Message] = SchemaField(
|
||||
conversation_history: list[Any] = SchemaField(
|
||||
default=[],
|
||||
description="The conversation history to provide context for the prompt.",
|
||||
)
|
||||
@@ -84,7 +84,7 @@ class SmartDecisionMakerBlock(Block):
|
||||
finished: str = SchemaField(
|
||||
description="The finished message to display to the user."
|
||||
)
|
||||
conversations: list[llm.Message] = SchemaField(
|
||||
conversations: list[Any] = SchemaField(
|
||||
description="The conversation history to provide context for the prompt."
|
||||
)
|
||||
|
||||
@@ -312,7 +312,6 @@ class SmartDecisionMakerBlock(Block):
|
||||
|
||||
if not response.tool_calls:
|
||||
yield "finished", f"No Decision Made finishing task: {response.response}"
|
||||
assistant_response = response.response
|
||||
else:
|
||||
for tool_call in response.tool_calls:
|
||||
tool_name = tool_call.function.name
|
||||
@@ -321,15 +320,6 @@ class SmartDecisionMakerBlock(Block):
|
||||
for arg_name, arg_value in tool_args.items():
|
||||
yield f"tools_^_{tool_name}_{arg_name}".lower(), arg_value
|
||||
|
||||
assistant_response = "\n".join(
|
||||
f"[{c.function.name}] called with arguments: {c.function.arguments}"
|
||||
for c in response.tool_calls
|
||||
)
|
||||
|
||||
input_data.conversation_history.append(
|
||||
llm.Message(role=llm.MessageRole.USER, content=response.prompt)
|
||||
)
|
||||
input_data.conversation_history.append(
|
||||
llm.Message(role=llm.MessageRole.ASSISTANT, content=assistant_response)
|
||||
)
|
||||
input_data.conversation_history.extend(response.prompt)
|
||||
input_data.conversation_history.append(response.raw_response)
|
||||
yield "conversations", input_data.conversation_history
|
||||
|
||||
Reference in New Issue
Block a user