Refactor Client::chat to return Message instead of ChatResponse
- Changed Client::chat return type from ChatResponse to Message - Updated OllamaClient and DebugClient to extract message from response - Simplified Harness to work directly with Message - ChatResponse is still parsed internally for Usage info logging
This commit is contained in:
+1
-1
@@ -9,7 +9,7 @@
|
||||
class Client {
|
||||
public:
|
||||
virtual ~Client() = default;
|
||||
virtual std::expected<ChatResponse, std::string> chat(const std::vector<Message>& messages,
|
||||
virtual std::expected<Message, std::string> chat(const std::vector<Message>& messages,
|
||||
const std::vector<Tool>& tools) const = 0;
|
||||
virtual std::expected<std::vector<std::string>, std::string> list_models() const = 0;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
class DebugClient : public Client {
|
||||
public:
|
||||
std::expected<ChatResponse, std::string> chat(const std::vector<Message>& messages,
|
||||
std::expected<Message, std::string> chat(const std::vector<Message>& messages,
|
||||
const std::vector<Tool>& tools) const override;
|
||||
|
||||
std::expected<std::vector<std::string>, std::string> list_models() const override;
|
||||
|
||||
@@ -17,7 +17,7 @@ public:
|
||||
explicit OllamaClient(OllamaConfig config = {});
|
||||
~OllamaClient() override;
|
||||
|
||||
std::expected<ChatResponse, std::string> chat(const std::vector<Message>& messages,
|
||||
std::expected<Message, std::string> chat(const std::vector<Message>& messages,
|
||||
const std::vector<Tool>& tools) const override;
|
||||
|
||||
std::expected<std::vector<std::string>, std::string> list_models() const override;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <iostream>
|
||||
#include <expected>
|
||||
|
||||
std::expected<ChatResponse, std::string> DebugClient::chat(const std::vector<Message>& /* messages */,
|
||||
std::expected<Message, std::string> DebugClient::chat(const std::vector<Message>& /* messages */,
|
||||
const std::vector<Tool>& /* tools */) const {
|
||||
std::string input;
|
||||
// Read the JSON blob from stdin.
|
||||
@@ -20,7 +20,10 @@ std::expected<ChatResponse, std::string> DebugClient::chat(const std::vector<Mes
|
||||
if (!result) {
|
||||
return std::unexpected(std::string("DebugClient invalid JSON input: ") + result.error());
|
||||
}
|
||||
return result.value();
|
||||
if (result.value().choices.empty())
|
||||
return std::unexpected(std::string("0 choices in return"));
|
||||
|
||||
return result.value().choices[0].message;
|
||||
}
|
||||
|
||||
std::expected<std::vector<std::string>, std::string> DebugClient::list_models() const {
|
||||
|
||||
+7
-14
@@ -47,7 +47,7 @@ std::expected<std::string, std::string> Harness::chat(const std::string& user_me
|
||||
push_message(message);
|
||||
|
||||
for (size_t i = 0; i < config_.max_tool_iterations; ++i) {
|
||||
ChatResponse response;
|
||||
Message response;
|
||||
bool done = false;
|
||||
size_t retries = 20;
|
||||
while (!done)
|
||||
@@ -65,21 +65,16 @@ std::expected<std::string, std::string> Harness::chat(const std::string& user_me
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
auto& choice = response.choices[0];
|
||||
auto message = choice.message;
|
||||
std::string finish = choice.finish_reason.empty() ? "stop" : choice.finish_reason;
|
||||
|
||||
push_message(message);
|
||||
push_message(response);
|
||||
|
||||
if (finish == "stop") {
|
||||
if (!message.content.empty())
|
||||
return message.content;
|
||||
if (response.content.empty() && response.tool_calls.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (finish == "tool_calls") {
|
||||
if (!response.tool_calls.empty()) {
|
||||
std::string prefix = std::string(config_.depth, '>') + (config_.depth ? " " : "");
|
||||
for (const auto& tc : message.tool_calls) {
|
||||
for (const auto& tc : response.tool_calls) {
|
||||
std::string tool_name = tc.function.name;
|
||||
std::string args_str = tc.function.arguments;
|
||||
|
||||
@@ -108,10 +103,8 @@ std::expected<std::string, std::string> Harness::chat(const std::string& user_me
|
||||
continue;
|
||||
}
|
||||
|
||||
// Unexpected finish_reason — return whatever content we have
|
||||
if (!message.content.empty())
|
||||
return message.content;
|
||||
return "[no content]";
|
||||
// No tool calls — return content
|
||||
return response.content;
|
||||
}
|
||||
|
||||
return std::unexpected("max tool iterations exceeded");
|
||||
|
||||
@@ -87,7 +87,7 @@ nlohmann::json OllamaClient::build_body(const std::vector<Message>& messages,
|
||||
return body;
|
||||
}
|
||||
|
||||
std::expected<ChatResponse, std::string> OllamaClient::chat(const std::vector<Message>& messages,
|
||||
std::expected<Message, std::string> OllamaClient::chat(const std::vector<Message>& messages,
|
||||
const std::vector<Tool>& tools) const {
|
||||
nlohmann::json body = build_body(messages, tools);
|
||||
std::string body_str = body.dump();
|
||||
@@ -111,7 +111,11 @@ std::expected<ChatResponse, std::string> OllamaClient::chat(const std::vector<Me
|
||||
std::cerr << "Total Tokens: " << ret.usage.total_tokens << std::endl;
|
||||
std::cerr << "Input Tokens: " << ret.usage.prompt_tokens << std::endl;
|
||||
std::cerr << "Generated Tokens: " << ret.usage.completion_tokens << std::endl;
|
||||
return ret;
|
||||
|
||||
if (ret.choices.empty())
|
||||
return std::unexpected(std::string("No choices returned"));
|
||||
|
||||
return ret.choices[0].message;
|
||||
}
|
||||
|
||||
std::expected<std::vector<std::string>, std::string> OllamaClient::list_models() const {
|
||||
|
||||
Reference in New Issue
Block a user