llm.rb 12.6.0 → 13.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +387 -0
- data/LICENSE +21 -93
- data/README.md +46 -155
- data/data/deepinfra.json +3 -0
- data/data/xai.json +1 -1
- data/lib/llm/a2a.rb +1 -1
- data/lib/llm/active_record/acts_as_llm.rb +6 -6
- data/lib/llm/agent.rb +62 -23
- data/lib/llm/buffer.rb +85 -3
- data/lib/llm/compactor/null.rb +19 -0
- data/lib/llm/compactor/truncate.rb +80 -0
- data/lib/llm/compactor.rb +42 -124
- data/lib/llm/context.rb +31 -37
- data/lib/llm/contract.rb +4 -25
- data/lib/llm/function/array.rb +15 -14
- data/lib/llm/function/async/group.rb +54 -0
- data/lib/llm/function/async/reactor.rb +48 -0
- data/lib/llm/function/async/task.rb +83 -0
- data/lib/llm/function/fiber/group.rb +46 -0
- data/lib/llm/function/fiber/task.rb +62 -0
- data/lib/llm/function/{fork_group.rb → fork/group.rb} +14 -5
- data/lib/llm/function/fork/job.rb +2 -2
- data/lib/llm/function/fork/task.rb +19 -10
- data/lib/llm/function/group.rb +40 -0
- data/lib/llm/function/{ractor_group.rb → ractor/group.rb} +13 -5
- data/lib/llm/function/ractor/job.rb +9 -3
- data/lib/llm/function/ractor/mailbox.rb +2 -0
- data/lib/llm/function/ractor/task.rb +23 -15
- data/lib/llm/function/{call_group.rb → sequential/group.rb} +12 -8
- data/lib/llm/function/sequential/task.rb +49 -0
- data/lib/llm/function/task.rb +25 -48
- data/lib/llm/function/thread/group.rb +46 -0
- data/lib/llm/function/thread/task.rb +60 -0
- data/lib/llm/function.rb +54 -64
- data/lib/llm/loop_guard.rb +1 -2
- data/lib/llm/mcp.rb +22 -0
- data/lib/llm/object.rb +2 -1
- data/lib/llm/provider.rb +6 -3
- data/lib/llm/providers/google.rb +2 -2
- data/lib/llm/repl/command.rb +35 -8
- data/lib/llm/repl/commands/compact.rb +33 -0
- data/lib/llm/repl/input.rb +80 -15
- data/lib/llm/repl/markdown/table.rb +76 -0
- data/lib/llm/repl/markdown.rb +31 -1
- data/lib/llm/repl/status.rb +1 -1
- data/lib/llm/repl/stream.rb +10 -3
- data/lib/llm/repl/transcript.rb +1 -1
- data/lib/llm/repl/walker.rb +46 -0
- data/lib/llm/repl.rb +18 -12
- data/lib/llm/response.rb +10 -0
- data/lib/llm/schema/leaf.rb +5 -0
- data/lib/llm/schema/object.rb +11 -5
- data/lib/llm/sequel/plugin.rb +6 -6
- data/lib/llm/stream.rb +24 -17
- data/lib/llm/tool.rb +20 -4
- data/lib/llm/tools/chdir.rb +0 -2
- data/lib/llm/tools/git.rb +8 -4
- data/lib/llm/tools/mkdir.rb +1 -1
- data/lib/llm/tools/pwd.rb +0 -2
- data/lib/llm/tools/read_file.rb +0 -2
- data/lib/llm/tools/rg.rb +8 -4
- data/lib/llm/tools/shell.rb +8 -4
- data/lib/llm/tools/utils.rb +31 -0
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +25 -5
- data/llm.gemspec +3 -3
- data/resources/deepdive.md +645 -58
- metadata +24 -13
- data/lib/llm/function/call_task.rb +0 -46
- data/lib/llm/function/fiber_group.rb +0 -105
- data/lib/llm/function/task_group.rb +0 -97
- data/lib/llm/function/thread_group.rb +0 -102
data/lib/llm/tools/shell.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# frozen_string_literal
|
|
4
|
-
|
|
5
3
|
class LLM::Tool
|
|
6
4
|
##
|
|
7
5
|
# The {LLM::Tool::Shell} class implements a tool that can
|
|
@@ -12,11 +10,16 @@ class LLM::Tool
|
|
|
12
10
|
# by managing the tool loop manually through
|
|
13
11
|
# {LLM::Context LLM::Context}.
|
|
14
12
|
class Shell < self
|
|
13
|
+
require_relative "utils"
|
|
14
|
+
include Utils
|
|
15
|
+
|
|
15
16
|
name "shell"
|
|
16
17
|
description "run a shell command"
|
|
17
18
|
parameter :name, String, "the command name"
|
|
18
19
|
parameter :arguments, Array[String], "one or more command arguments"
|
|
20
|
+
parameter :timeout, Integer, "the maximum allowed time for the command to run (in seconds)"
|
|
19
21
|
required %i[name]
|
|
22
|
+
defaults arguments: [], timeout: 60
|
|
20
23
|
|
|
21
24
|
##
|
|
22
25
|
# @param [String] name
|
|
@@ -24,8 +27,9 @@ class LLM::Tool
|
|
|
24
27
|
# @param [Array<String>] arguments
|
|
25
28
|
# One or more command-line arguments
|
|
26
29
|
# @return [Hash]
|
|
27
|
-
def call(name:, arguments:
|
|
30
|
+
def call(name:, arguments: [], timeout: 60)
|
|
28
31
|
command = spawn(name:, arguments:)
|
|
32
|
+
wait(command:, timeout:)
|
|
29
33
|
{ok: command.success?, stdout: command.stdout, stderr: command.stderr}
|
|
30
34
|
end
|
|
31
35
|
|
|
@@ -42,7 +46,7 @@ class LLM::Tool
|
|
|
42
46
|
.spawn
|
|
43
47
|
end
|
|
44
48
|
|
|
45
|
-
LLM.require "test-cmd.rb"
|
|
49
|
+
LLM.require "test-cmd.rb", "~> 1.1"
|
|
46
50
|
Command = Test::Cmd
|
|
47
51
|
end
|
|
48
52
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class LLM::Tool
|
|
4
|
+
##
|
|
5
|
+
# Shared utilities for tool implementations.
|
|
6
|
+
module Utils
|
|
7
|
+
##
|
|
8
|
+
# Wait for a command to finish, or abort
|
|
9
|
+
# with an error when it exceeds the
|
|
10
|
+
# specified timeout.
|
|
11
|
+
# @param [Test::Cmd] command
|
|
12
|
+
# @param [Integer] timeout
|
|
13
|
+
# @return [void]
|
|
14
|
+
def wait(command:, timeout:)
|
|
15
|
+
start = now
|
|
16
|
+
while command.running?
|
|
17
|
+
if now - start > timeout
|
|
18
|
+
command.kill!
|
|
19
|
+
raise "command timed out after #{timeout}s"
|
|
20
|
+
end
|
|
21
|
+
sleep 0.01
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# @return [Numeric]
|
|
27
|
+
def now
|
|
28
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/llm/version.rb
CHANGED
data/lib/llm.rb
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
##
|
|
4
|
+
# llm.rb is a zero-dependency AI runtime for Ruby. Twelve providers, six
|
|
5
|
+
# concurrency strategies, MCP and A2A, streaming tool calls with
|
|
6
|
+
# cancellation, context compaction, and ORM persistence.
|
|
7
|
+
#
|
|
8
|
+
# @example The three-step workflow
|
|
9
|
+
# require "llm"
|
|
10
|
+
# llm = LLM.deepseek(key: ENV["KEY"]) # 1. pick a provider
|
|
11
|
+
# agent = LLM::Agent.new(llm, stream: $stdout) # 2. create an agent
|
|
12
|
+
# agent.talk "Hello world" # 3. talk to it
|
|
13
|
+
#
|
|
14
|
+
# @see LLM::Agent The recommended high-level interface
|
|
15
|
+
# @see LLM::Context The low-level stateful runtime (advanced)
|
|
3
16
|
module LLM
|
|
4
17
|
require "stringio"
|
|
5
18
|
require "securerandom"
|
|
19
|
+
require_relative "llm/compactor"
|
|
6
20
|
require_relative "llm/json_adapter"
|
|
7
21
|
require_relative "llm/tracer"
|
|
8
22
|
require_relative "llm/error"
|
|
@@ -49,15 +63,21 @@ module LLM
|
|
|
49
63
|
|
|
50
64
|
##
|
|
51
65
|
# Requires an optional runtime dependency
|
|
52
|
-
# @
|
|
66
|
+
# @param [String] name
|
|
67
|
+
# The name of a gem
|
|
68
|
+
# @param [String, nil] version
|
|
69
|
+
# Optional gem version
|
|
70
|
+
# @raise [LLM::LoadError]
|
|
53
71
|
# When the dependency cannot be loaded
|
|
54
|
-
def self.require(name)
|
|
55
|
-
super
|
|
56
|
-
rescue ::LoadError
|
|
72
|
+
def self.require(name, version = nil)
|
|
57
73
|
names = {"xchan" => "xchan.rb", "net/http/persistent" => "net-http-persistent"}
|
|
74
|
+
gem(names[name] || name, version) if version
|
|
75
|
+
super(name)
|
|
76
|
+
rescue ::LoadError
|
|
58
77
|
name = names[name] || name
|
|
59
78
|
raise LLM::LoadError,
|
|
60
|
-
"#{name}
|
|
79
|
+
"#{name}#{version ? " #{version}" : ""} is an optional " \
|
|
80
|
+
"runtime dependency but it does not appear to be installed. " \
|
|
61
81
|
"Consider 'gem install #{name}', adding '#{name}' to your Gemfile or " \
|
|
62
82
|
"opting out of the functionality provided by '#{name}'"
|
|
63
83
|
end
|
data/llm.gemspec
CHANGED
|
@@ -16,7 +16,7 @@ functionality – such as ActiveRecord support – require
|
|
|
16
16
|
optional dependencies that are opt-in.
|
|
17
17
|
DESCRIPTION
|
|
18
18
|
|
|
19
|
-
spec.license = "
|
|
19
|
+
spec.license = "MIT"
|
|
20
20
|
spec.required_ruby_version = ">= 3.3.0"
|
|
21
21
|
|
|
22
22
|
spec.homepage = "https://r.uby.dev/llm/"
|
|
@@ -38,7 +38,7 @@ DESCRIPTION
|
|
|
38
38
|
spec.add_development_dependency "yard", "~> 0.9.37"
|
|
39
39
|
spec.add_development_dependency "redcarpet", "~> 3.6"
|
|
40
40
|
spec.add_development_dependency "webrick", "~> 1.8"
|
|
41
|
-
spec.add_development_dependency "test-cmd.rb", "~>
|
|
41
|
+
spec.add_development_dependency "test-cmd.rb", "~> 1.1.0"
|
|
42
42
|
spec.add_development_dependency "rake", "~> 13.0"
|
|
43
43
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
44
44
|
spec.add_development_dependency "standard", "~> 1.50"
|
|
@@ -50,7 +50,7 @@ DESCRIPTION
|
|
|
50
50
|
spec.add_development_dependency "activerecord", "~> 8.0"
|
|
51
51
|
spec.add_development_dependency "sequel", "~> 5.0"
|
|
52
52
|
spec.add_development_dependency "sqlite3", "~> 2.0"
|
|
53
|
-
spec.add_development_dependency "xchan.rb", "~> 0.
|
|
53
|
+
spec.add_development_dependency "xchan.rb", "~> 0.22"
|
|
54
54
|
spec.add_development_dependency "pg", "~> 1.5"
|
|
55
55
|
spec.add_development_dependency "irb", "~> 1.18"
|
|
56
56
|
end
|