| 1 |
|
defmodule Agent.Watch do |
| 2 |
|
import String, only: [trim: 1] |
| 3 |
|
import System, only: [monotonic_time: 1] |
| 4 |
|
import Agent.Jsonl, only: [find: 3] |
| 5 |
|
import Agent.Puppet, only: [cwd: 0] |
| 6 |
|
import Process, only: [sleep: 1] |
| 7 |
|
import Log, only: [trace: 1] |
| 8 |
|
import Task.Supervisor, only: [start_child: 2] |
| 9 |
|
|
| 10 |
:-( |
def start(agent, question, folder \\ nil) do |
| 11 |
:-( |
start_child(Elita.Tasks, fn -> init(agent, question, folder) end) |
| 12 |
|
end |
| 13 |
|
|
| 14 |
:-( |
defp init(agent, question, folder) do |
| 15 |
:-( |
boot(agent, question, resolve(folder)) |
| 16 |
|
rescue |
| 17 |
:-( |
e -> reraise e, __STACKTRACE__ |
| 18 |
|
end |
| 19 |
|
|
| 20 |
:-( |
defp resolve(nil), do: cwd() |
| 21 |
:-( |
defp resolve(folder), do: folder |
| 22 |
|
|
| 23 |
|
defp boot(agent, question, folder) do |
| 24 |
:-( |
trace("WATCHER START #{agent} #{question}\n") |
| 25 |
:-( |
trace("watcher:folder=#{inspect(folder)}\n") |
| 26 |
:-( |
{agent, question, folder, monotonic_time(:millisecond), 0} |> loop() |
| 27 |
|
end |
| 28 |
|
|
| 29 |
|
defp loop({_, _, _, start, _pos} = state) do |
| 30 |
:-( |
elapsed = monotonic_time(:millisecond) - start |
| 31 |
:-( |
proceed(state, elapsed) |
| 32 |
|
end |
| 33 |
|
|
| 34 |
:-( |
defp proceed(_, elapsed) when elapsed > 90000, do: :ok |
| 35 |
|
|
| 36 |
|
defp proceed({agent, question, folder, start, pos}, _) do |
| 37 |
:-( |
{agent, question, folder, start, pos} |> fetch() |
| 38 |
|
end |
| 39 |
|
|
| 40 |
|
defp fetch({_agent, question, folder, _start, pos} = state) do |
| 41 |
:-( |
check(scan(question, folder, pos), state) |
| 42 |
|
end |
| 43 |
|
|
| 44 |
|
defp check({:found, text}, {agent, _, _, _, _}) do |
| 45 |
:-( |
answer(agent, trim(text)) |
| 46 |
|
end |
| 47 |
|
|
| 48 |
|
defp check({:continue, newpos}, {agent, q, f, s, _}) do |
| 49 |
:-( |
wait(agent, q, f, s, newpos) |
| 50 |
|
end |
| 51 |
|
|
| 52 |
|
defp check(:wait, {agent, q, f, s, p}) do |
| 53 |
:-( |
wait(agent, q, f, s, p) |
| 54 |
|
end |
| 55 |
|
|
| 56 |
|
defp wait(agent, question, folder, start, pos) do |
| 57 |
:-( |
sleep(100) |
| 58 |
:-( |
loop({agent, question, folder, start, pos}) |
| 59 |
|
end |
| 60 |
|
|
| 61 |
|
defp scan(question, folder, pos) do |
| 62 |
:-( |
find(question, folder, pos) |
| 63 |
|
end |
| 64 |
|
|
| 65 |
|
defp answer(agent, text) do |
| 66 |
:-( |
:erlang.apply(:"Elixir.Tools.Sys.Ask", :answer, [agent, text]) |
| 67 |
|
end |
| 68 |
|
end |