10#include "absl/strings/ascii.h"
11#include "absl/strings/str_cat.h"
23 const std::map<std::string, std::string>& args) {
24 std::vector<std::string> result;
26 for (
const auto& [key, value] : args) {
28 result.push_back(absl::StrCat(
"--", key,
"=", value));
32 bool has_format =
false;
33 for (
const auto& arg : result) {
34 if (arg.find(
"--format=") == 0) {
40 result.push_back(
"--format=json");
73 return absl::InvalidArgumentError(
74 absl::StrCat(
"Unknown tool: ", call.
tool_name));
79 return absl::FailedPreconditionError(absl::StrCat(
80 "Tool '", call.
tool_name,
"' disabled by current agent configuration"));
85 if (!handler_or.ok()) {
86 return handler_or.status();
88 auto handler = std::move(handler_or.value());
96 std::vector<std::string> args = ConvertArgsToVector(call.
args);
100 return absl::FailedPreconditionError(
102 "' requires ROM context but none is available"));
107 return absl::FailedPreconditionError(
109 "' requires Project context but none is available"));
113 std::stringstream output_buffer;
114 std::streambuf* old_cout = std::cout.rdbuf(output_buffer.rdbuf());
118 std::cout.rdbuf(old_cout);
124 std::string output = output_buffer.str();
125 if (output.empty()) {
126 return absl::InternalError(
127 absl::StrCat(
"Tool '", call.
tool_name,
"' produced no output"));
134 std::vector<ToolInfo> tools;
137 for (
const auto& def : all_defs) {
139 tools.push_back({def.name, def.category, def.description, def.usage, def.examples, def.requires_rom, def.requires_project});
146 const std::string& tool_name)
const {
149 return ToolInfo{def->
name, def->category, def->description, def->usage, def->examples, def->requires_rom, def->requires_project};
155 const std::string& query)
const {
156 std::vector<ToolInfo> matches;
157 std::string lower_query = absl::AsciiStrToLower(query);
160 for (
const auto& tool : all_tools) {
161 std::string lower_name = absl::AsciiStrToLower(tool.name);
162 std::string lower_desc = absl::AsciiStrToLower(tool.description);
163 std::string lower_category = absl::AsciiStrToLower(tool.category);
165 if (lower_name.find(lower_query) != std::string::npos ||
166 lower_desc.find(lower_query) != std::string::npos ||
167 lower_category.find(lower_query) != std::string::npos) {
168 matches.push_back(tool);
181 auto start_time = std::chrono::high_resolution_clock::now();
185 std::vector<std::future<absl::StatusOr<std::string>>> futures;
186 futures.reserve(batch.
calls.size());
188 for (
const auto& call : batch.
calls) {
189 futures.push_back(std::async(std::launch::async, [
this, &call]() {
195 for (
size_t i = 0; i < futures.size(); ++i) {
196 auto status_or = futures[i].get();
197 if (status_or.ok()) {
198 result.
results[i] = std::move(status_or.value());
199 result.
statuses[i] = absl::OkStatus();
203 result.
statuses[i] = status_or.status();
209 for (
size_t i = 0; i < batch.
calls.size(); ++i) {
211 if (status_or.ok()) {
212 result.
results[i] = std::move(status_or.value());
213 result.
statuses[i] = absl::OkStatus();
217 result.
statuses[i] = status_or.status();
223 auto end_time = std::chrono::high_resolution_clock::now();
225 std::chrono::duration<double, std::milli>(end_time - start_time).count();