Refactor to use Content for tool calls

This commit is contained in:
2026-06-15 16:53:42 -05:00
parent 3fc1a2b286
commit 79218deb2f
5 changed files with 21 additions and 12 deletions
+3 -1
View File
@@ -400,9 +400,11 @@ struct ContentPart {
DRH_DEFINE_TYPE_OPTIONAL(ContentPart, type, text, image_url)
using Content = std::variant<std::string, std::vector<ContentPart>>;
struct Message {
std::string role = "";
std::variant<std::string, std::vector<ContentPart>> content = "";
Content content = "";
std::string reasoning = "";
std::string reasoning_content = "";
std::string tool_call_id = "";
+4 -4
View File
@@ -7,9 +7,9 @@
// Template function that wraps a typed lambda for tool execution
// Handles JSON deserialization internally, eliminating std::any
template<typename ParamsType>
std::function<std::string(const nlohmann::json&)> create_tool_execute(
std::function<std::string(const ParamsType&)> fn
template<typename ParamsType, typename F>
std::function<Content(const nlohmann::json&)> create_tool_execute(
F const& fn
) {
return [fn = std::move(fn)](const nlohmann::json& json) -> std::string {
auto result = json_to<ParamsType>(json);
@@ -24,7 +24,7 @@ struct Tool {
std::string name;
std::string description;
nlohmann::json parameters_schema;
std::function<std::string(const nlohmann::json&)> execute;
std::function<Content(const nlohmann::json&)> execute;
nlohmann::json to_api_json() const {
return {
+1 -1
View File
@@ -11,7 +11,7 @@ public:
std::expected<void, std::string> register_tool(Tool tool);
std::optional<const Tool*> find(const std::string& name) const;
std::vector<Tool> tools() const;
std::string invoke(const std::string& name, const nlohmann::json& args) const;
Content invoke(const std::string& name, const nlohmann::json& args) const;
std::expected<ToolRegistry, std::string> create_subregistry(std::vector<std::string> const& names) const;
std::vector<std::string> const& tool_names() const;
+11 -4
View File
@@ -114,7 +114,7 @@ std::expected<std::string, std::string> Harness::chat(const Message& user_messag
if (config_.verbose)
std::cerr << prefix << "[tool call] " << tool_name << "(" << args_str << ")\n";
std::string result;
Content result = "";
auto args_json = parse_json_safely(args_str);
if (args_json.is_discarded()) {
result = "Error: invalid JSON in tool arguments";
@@ -123,9 +123,16 @@ std::expected<std::string, std::string> Harness::chat(const Message& user_messag
}
if (config_.verbose)
std::cerr << prefix << "[tool result] "
<< result.substr(0, 300)
<< (result.size() > 300 ? "..." : "") << "\n";
{
std::cerr << prefix << "[tool result] ";
if (std::holds_alternative<std::string>(result))
{
std::string str = std::get<std::string>(result);
std::cerr
<< str.substr(0, 300)
<< (str.size() > 300 ? "..." : "") << "\n";
}
}
Message tool_result{};
tool_result.tool_call_id = tc.id;
+2 -2
View File
@@ -24,8 +24,8 @@ std::vector<Tool> ToolRegistry::tools() const {
return ret;
}
std::string ToolRegistry::invoke(const std::string& name,
const nlohmann::json& args) const {
Content ToolRegistry::invoke(const std::string& name,
const nlohmann::json& args) const {
auto it = tools_.find(name);
if (it == tools_.end())
return "Error: unknown tool: " + name;