Simplify chat tool round flow
This commit is contained in:
1
AUDIT.md
1
AUDIT.md
@@ -29,6 +29,7 @@ after each item.
|
|||||||
- [x] `mcp/tools.ex`
|
- [x] `mcp/tools.ex`
|
||||||
- [x] `mcp/server.ex`
|
- [x] `mcp/server.ex`
|
||||||
- [x] `ai/chat_tools.ex`
|
- [x] `ai/chat_tools.ex`
|
||||||
|
- [x] `ai/chat.ex`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -578,47 +578,22 @@ defmodule BDS.AI.Chat do
|
|||||||
runtime.generate(Runtime.endpoint_with_model(endpoint, model), request, generate_opts),
|
runtime.generate(Runtime.endpoint_with_model(endpoint, model), request, generate_opts),
|
||||||
{:ok, assistant_message} <- persist_assistant_response(conversation.id, response),
|
{:ok, assistant_message} <- persist_assistant_response(conversation.id, response),
|
||||||
:ok <- touch_conversation(conversation.id) do
|
:ok <- touch_conversation(conversation.id) do
|
||||||
if is_binary(Map.get(response, :content)) and String.trim(Map.get(response, :content)) != "" do
|
notify_assistant_content(response, conversation.id, opts)
|
||||||
notify_chat_event(
|
|
||||||
opts,
|
|
||||||
{:chat_streaming_content, conversation.id, Map.get(response, :content)}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
tool_calls = decode_tool_calls(Map.get(response, :tool_calls))
|
response
|
||||||
|
|> Map.get(:tool_calls)
|
||||||
Enum.each(tool_calls, fn tool_call ->
|
|> decode_tool_calls()
|
||||||
notify_chat_event(opts, {:chat_tool_call, conversation.id, tool_call})
|
|> continue_chat_round(
|
||||||
end)
|
conversation.id,
|
||||||
|
assistant_message,
|
||||||
cond do
|
|
||||||
tool_calls != [] and tools != [] ->
|
|
||||||
with {:ok, tool_messages} <-
|
|
||||||
execute_tool_calls(conversation.id, tool_calls, project_id, opts),
|
|
||||||
updated_messages <- load_chat_messages(conversation.id),
|
|
||||||
{:ok, reply} <-
|
|
||||||
chat_round(
|
|
||||||
Repo.get!(ChatConversation, conversation.id),
|
|
||||||
updated_messages,
|
|
||||||
endpoint,
|
endpoint,
|
||||||
model,
|
model,
|
||||||
project_id,
|
project_id,
|
||||||
tools,
|
tools,
|
||||||
runtime,
|
runtime,
|
||||||
opts,
|
opts,
|
||||||
rounds_left - 1
|
rounds_left
|
||||||
) do
|
)
|
||||||
{:ok, Map.put(reply, :tool_messages, tool_messages)}
|
|
||||||
end
|
|
||||||
|
|
||||||
true ->
|
|
||||||
{:ok,
|
|
||||||
%{
|
|
||||||
conversation: format_conversation(Repo.get!(ChatConversation, conversation.id)),
|
|
||||||
assistant_message: format_chat_message(assistant_message),
|
|
||||||
tool_messages: []
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -673,6 +648,63 @@ defmodule BDS.AI.Chat do
|
|||||||
{:ok, tool_messages}
|
{:ok, tool_messages}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp continue_chat_round(
|
||||||
|
tool_calls,
|
||||||
|
conversation_id,
|
||||||
|
assistant_message,
|
||||||
|
endpoint,
|
||||||
|
model,
|
||||||
|
project_id,
|
||||||
|
tools,
|
||||||
|
runtime,
|
||||||
|
opts,
|
||||||
|
rounds_left
|
||||||
|
) do
|
||||||
|
Enum.each(tool_calls, fn tool_call ->
|
||||||
|
notify_chat_event(opts, {:chat_tool_call, conversation_id, tool_call})
|
||||||
|
end)
|
||||||
|
|
||||||
|
if tool_calls != [] and tools != [] do
|
||||||
|
with {:ok, tool_messages} <- execute_tool_calls(conversation_id, tool_calls, project_id, opts),
|
||||||
|
updated_messages <- load_chat_messages(conversation_id),
|
||||||
|
{:ok, reply} <-
|
||||||
|
chat_round(
|
||||||
|
Repo.get!(ChatConversation, conversation_id),
|
||||||
|
updated_messages,
|
||||||
|
endpoint,
|
||||||
|
model,
|
||||||
|
project_id,
|
||||||
|
tools,
|
||||||
|
runtime,
|
||||||
|
opts,
|
||||||
|
rounds_left - 1
|
||||||
|
) do
|
||||||
|
{:ok, Map.put(reply, :tool_messages, tool_messages)}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
final_chat_reply(conversation_id, assistant_message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp final_chat_reply(conversation_id, assistant_message) do
|
||||||
|
{:ok,
|
||||||
|
%{
|
||||||
|
conversation: format_conversation(Repo.get!(ChatConversation, conversation_id)),
|
||||||
|
assistant_message: format_chat_message(assistant_message),
|
||||||
|
tool_messages: []
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp notify_assistant_content(response, conversation_id, opts) do
|
||||||
|
content = Map.get(response, :content)
|
||||||
|
|
||||||
|
if is_binary(content) and String.trim(content) != "" do
|
||||||
|
notify_chat_event(opts, {:chat_streaming_content, conversation_id, content})
|
||||||
|
end
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
defp build_chat_request(conversation, messages, model, project_id, tools) do
|
defp build_chat_request(conversation, messages, model, project_id, tools) do
|
||||||
system_message = %{"role" => "system", "content" => chat_system_prompt(project_id, tools)}
|
system_message = %{"role" => "system", "content" => chat_system_prompt(project_id, tools)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user