worktree-bold-oak-fgv1
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