| 1 |
|
defmodule Tools do |
| 2 |
|
import Code, only: [ensure_loaded: 1] |
| 3 |
|
import Enum, only: [map: 2, reject: 2, map_reduce: 3] |
| 4 |
|
import Map, only: [put: 3] |
| 5 |
|
import Module, only: [concat: 1] |
| 6 |
|
import String, only: [capitalize: 1] |
| 7 |
|
|
| 8 |
|
def tools(%{tools: names}, state) when is_list(names) do |
| 9 |
|
names |
| 10 |
406 |
|> map(&prompt(&1, state)) |
| 11 |
406 |
|> reject(&is_nil/1) |
| 12 |
189 |
|> wrap() |
| 13 |
|
end |
| 14 |
|
|
| 15 |
:-( |
def tools(_, _), do: [] |
| 16 |
|
|
| 17 |
|
def exec({parts, state}) do |
| 18 |
189 |
state = put(state, :parts, parts) |
| 19 |
189 |
exec(parts, state) |
| 20 |
|
end |
| 21 |
|
|
| 22 |
|
def exec(parts, state) when is_list(parts) do |
| 23 |
189 |
map_reduce(parts, state, &exec/2) |
| 24 |
|
end |
| 25 |
|
|
| 26 |
129 |
def exec(%{"tool_use" => call} = part, state) do |
| 27 |
129 |
{result, state} = exec(call, state) |
| 28 |
|
{put(part, "result", result), state} |
| 29 |
|
end |
| 30 |
|
|
| 31 |
|
def exec(%{"id" => _, "name" => tool, "input" => input}, state) do |
| 32 |
129 |
module(tool).exec(tool, input, state) |
| 33 |
|
end |
| 34 |
|
|
| 35 |
149 |
def exec(part, state), do: {part, state} |
| 36 |
|
|
| 37 |
|
defp prompt(name, state) do |
| 38 |
406 |
module(name).spec(name, state) |
| 39 |
|
end |
| 40 |
|
|
| 41 |
|
defp module(name) do |
| 42 |
|
concat([Tools, Sys, capitalize(name)]) |
| 43 |
|
|> ensure_loaded() |
| 44 |
535 |
|> static() |
| 45 |
|
end |
| 46 |
|
|
| 47 |
525 |
defp static({:module, mod}), do: mod |
| 48 |
10 |
defp static(_), do: Tools.User |
| 49 |
|
|
| 50 |
51 |
defp wrap([]), do: [] |
| 51 |
138 |
defp wrap(tools), do: [%{function_declarations: tools}] |
| 52 |
|
end |