main
 1# frozen_string_literal: true
 2
 3require "base64"
 4require "date"
 5require "digest"
 6require "erb"
 7require "fileutils"
 8require "json"
 9require "json_schemer"
10require "logger"
11require "net/hippie"
12require "open3"
13require "optparse"
14require "pathname"
15require "reline"
16require "securerandom"
17require "shellwords"
18require "stringio"
19require "tempfile"
20require "uri"
21require "webrick"
22
23require_relative "elelem/agent"
24require_relative "elelem/commands"
25require_relative "elelem/conversation"
26require_relative "elelem/mcp"
27require_relative "elelem/net"
28require_relative "elelem/permissions"
29require_relative "elelem/plugins"
30require_relative "elelem/providers"
31require_relative "elelem/server"
32require_relative "elelem/system_prompt"
33require_relative "elelem/terminal"
34require_relative "elelem/tool"
35require_relative "elelem/toolbox"
36require_relative "elelem/version"
37require_relative "elelem/web_terminal"
38
39module Elelem
40  def self.sh(cmd, args: [], cwd: Dir.pwd, env: {})
41    output = StringIO.new
42
43    Open3.popen2e(env, cmd, *args, chdir: cwd) do |stdin, out, wait_thr|
44      stdin.close
45      out.each_line do |line|
46        yield line if block_given?
47        output.write(line)
48      end
49
50      { exit_status: wait_thr.value.exitstatus, content: output.string }
51    end
52  end
53
54  def self.start(provider: "ollama", toolbox: Toolbox.new)
55    client = Providers.build(provider)
56    agent = Agent.new(client, toolbox: toolbox)
57    Plugins.setup!(agent)
58    agent.terminal = Terminal.new(commands: agent.commands)
59    agent.repl
60  end
61
62  def self.serve(provider: "ollama", port: 4567, toolbox: Toolbox.new)
63    client = Providers.build(provider)
64    agent = Agent.new(client, toolbox: toolbox, terminal: WebTerminal.new)
65    Plugins.setup!(agent)
66    Server.new(agent, port: port).start
67  end
68
69  def self.ask(prompt, provider: "ollama", toolbox: Toolbox.new)
70    client = Providers.build(provider)
71    agent = Agent.new(client, toolbox: toolbox, terminal: Terminal.new(quiet: true))
72    Plugins.setup!(agent)
73    agent.turn(prompt)
74    agent.conversation.last[:content]
75  end
76end