llm.rb 12.3.0 → 12.4.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 +175 -0
- data/README.md +72 -15
- data/data/bedrock.json +159 -0
- data/data/deepinfra.json +5 -5
- data/data/google.json +1 -1
- data/data/openai.json +4 -4
- data/lib/llm/agent.rb +9 -6
- data/lib/llm/context/deserializer.rb +2 -5
- data/lib/llm/repl/command.rb +85 -0
- data/lib/llm/repl/commands/exit.rb +19 -0
- data/lib/llm/repl/input.rb +115 -35
- data/lib/llm/repl/stream.rb +42 -2
- data/lib/llm/repl/transcript.rb +6 -0
- data/lib/llm/repl/window.rb +34 -7
- data/lib/llm/repl.rb +77 -25
- data/lib/llm/tools/ls.rb +30 -0
- data/lib/llm/tools/which.rb +38 -0
- data/lib/llm/version.rb +1 -1
- data/resources/deepdive.md +66 -0
- metadata +5 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class LLM::Tool
|
|
4
|
+
##
|
|
5
|
+
# The {LLM::Tool::Which LLM::Tool::Which} class implements
|
|
6
|
+
# a tool that locates an executable on the system PATH.
|
|
7
|
+
#
|
|
8
|
+
# This lets an agent discover whether a command it intends
|
|
9
|
+
# to use is actually available before attempting to run it.
|
|
10
|
+
# For example, checking `which("rg")` before a search, or
|
|
11
|
+
# `which("git")` before a version control operation, avoids
|
|
12
|
+
# a failed subprocess and lets the agent adapt its strategy
|
|
13
|
+
# when a tool is missing.
|
|
14
|
+
class Which < self
|
|
15
|
+
name "which"
|
|
16
|
+
description "locate an executable on the system PATH"
|
|
17
|
+
parameter :name, String, "the name of the executable to find"
|
|
18
|
+
required %i[name]
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# @param [String] name
|
|
22
|
+
# @return [Hash]
|
|
23
|
+
def call(name:)
|
|
24
|
+
path = paths.find { File.executable? File.join(_1, name) }
|
|
25
|
+
{ok: !!path, path:}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# @return [Array<String>]
|
|
32
|
+
def paths
|
|
33
|
+
ENV["PATH"]
|
|
34
|
+
.to_s
|
|
35
|
+
.split(File::PATH_SEPARATOR)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/llm/version.rb
CHANGED
data/resources/deepdive.md
CHANGED
|
@@ -92,9 +92,12 @@ features that didn't make it into the homepage documentation.
|
|
|
92
92
|
<summary>REPL</summary>
|
|
93
93
|
|
|
94
94
|
- [LLM::Agent](#llmagent)
|
|
95
|
+
- [State](#state)
|
|
95
96
|
- [Tools](#tools)
|
|
96
97
|
- [Skills](#skills-1)
|
|
97
98
|
- [Tracer](#tracer-1)
|
|
99
|
+
- [Input](#input)
|
|
100
|
+
- [Commands](#commands)
|
|
98
101
|
</details>
|
|
99
102
|
|
|
100
103
|
**Persistence**
|
|
@@ -894,6 +897,12 @@ you a way to confirm the work was successful, inspect
|
|
|
894
897
|
anything that went wrong, and keep talking to the same
|
|
895
898
|
agent while its state is still intact.
|
|
896
899
|
|
|
900
|
+
The REPL is a curses-based TUI with a status line showing
|
|
901
|
+
a context-usage bar and cost counter, a scrollable transcript
|
|
902
|
+
that renders markdown, and a multi-line input area. The UI
|
|
903
|
+
thread stays responsive while a second thread communicates
|
|
904
|
+
with the model.
|
|
905
|
+
|
|
897
906
|
#### LLM::Agent
|
|
898
907
|
|
|
899
908
|
The [LLM::Agent#repl](https://r.uby.dev/api-docs/llm.rb/LLM/Agent.html#repl-instance_method)
|
|
@@ -915,6 +924,20 @@ agent = LLM::Agent.new(llm)
|
|
|
915
924
|
agent.repl
|
|
916
925
|
```
|
|
917
926
|
|
|
927
|
+
#### State
|
|
928
|
+
|
|
929
|
+
The `path:` option accepts a file path where runtime state
|
|
930
|
+
is read from and written to. This lets you resume a
|
|
931
|
+
conversation across REPL sessions. When the file does not
|
|
932
|
+
exist the agent starts fresh; when it does, the agent
|
|
933
|
+
restores its previous state.
|
|
934
|
+
|
|
935
|
+
```ruby
|
|
936
|
+
llm = LLM.deepseek(key: ENV["KEY"])
|
|
937
|
+
agent = LLM::Agent.new(llm)
|
|
938
|
+
agent.repl(path: "session.json")
|
|
939
|
+
```
|
|
940
|
+
|
|
918
941
|
#### Tools
|
|
919
942
|
|
|
920
943
|
The read-eval-print loop accepts a `tools` option that lets
|
|
@@ -952,6 +975,49 @@ agent = LLM::Agent.new(llm, tracer: LLM.logger(llm, path: "agent.log"))
|
|
|
952
975
|
agent.repl(tracer: true, tools: [Debugger])
|
|
953
976
|
```
|
|
954
977
|
|
|
978
|
+
#### Input
|
|
979
|
+
|
|
980
|
+
The input area supports several keyboard shortcuts:
|
|
981
|
+
|
|
982
|
+
| Key | Action |
|
|
983
|
+
|---|---|
|
|
984
|
+
| `Enter` | Submit the current prompt |
|
|
985
|
+
| `Ctrl+A` | Jump to the start of the line |
|
|
986
|
+
| `Ctrl+E` | Jump to the end of the line |
|
|
987
|
+
| `Ctrl+F` | Move the cursor forward |
|
|
988
|
+
| `Ctrl+K` | Erase from cursor to the end of the line |
|
|
989
|
+
| `Ctrl+Y` | Paste previously killed text |
|
|
990
|
+
| `Ctrl+D` | Delete the character at the cursor |
|
|
991
|
+
| `Left / Right` | Move the cursor |
|
|
992
|
+
| `Up / Down` | Scroll the transcript |
|
|
993
|
+
|
|
994
|
+
When characters arrive faster than a threshold the REPL
|
|
995
|
+
detects that text is being pasted rather than typed. In
|
|
996
|
+
paste mode pressing `Enter` inserts a newline instead of
|
|
997
|
+
submitting, allowing multi-line prompts.
|
|
998
|
+
|
|
999
|
+
#### Commands
|
|
1000
|
+
|
|
1001
|
+
Commands are recognized by a `/` prefix on the input line.
|
|
1002
|
+
The built-in command is `/exit`, which leaves the REPL.
|
|
1003
|
+
The [`LLM::Repl::Command`](https://r.uby.dev/api-docs/llm.rb/LLM/Repl/Command.html)
|
|
1004
|
+
class can be subclassed to add custom commands –
|
|
1005
|
+
any subclass that defines a `name`, `description`, and
|
|
1006
|
+
`call` method is automatically registered and available.
|
|
1007
|
+
|
|
1008
|
+
```ruby
|
|
1009
|
+
class LLM::Repl::Command
|
|
1010
|
+
class Clear < self
|
|
1011
|
+
name "clear"
|
|
1012
|
+
description "clears the transcript"
|
|
1013
|
+
|
|
1014
|
+
def call
|
|
1015
|
+
system("clear") || system("cls")
|
|
1016
|
+
end
|
|
1017
|
+
end
|
|
1018
|
+
end
|
|
1019
|
+
```
|
|
1020
|
+
|
|
955
1021
|
[Back to top](#table-of-contents)
|
|
956
1022
|
|
|
957
1023
|
## Images
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: llm.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 12.
|
|
4
|
+
version: 12.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- robert
|
|
@@ -468,6 +468,8 @@ files:
|
|
|
468
468
|
- lib/llm/registry.rb
|
|
469
469
|
- lib/llm/repl.rb
|
|
470
470
|
- lib/llm/repl/bar.rb
|
|
471
|
+
- lib/llm/repl/command.rb
|
|
472
|
+
- lib/llm/repl/commands/exit.rb
|
|
471
473
|
- lib/llm/repl/input.rb
|
|
472
474
|
- lib/llm/repl/markdown.rb
|
|
473
475
|
- lib/llm/repl/status.rb
|
|
@@ -505,12 +507,14 @@ files:
|
|
|
505
507
|
- lib/llm/tools.rb
|
|
506
508
|
- lib/llm/tools/chdir.rb
|
|
507
509
|
- lib/llm/tools/git.rb
|
|
510
|
+
- lib/llm/tools/ls.rb
|
|
508
511
|
- lib/llm/tools/mkdir.rb
|
|
509
512
|
- lib/llm/tools/pwd.rb
|
|
510
513
|
- lib/llm/tools/read_file.rb
|
|
511
514
|
- lib/llm/tools/rg.rb
|
|
512
515
|
- lib/llm/tools/shell.rb
|
|
513
516
|
- lib/llm/tools/swap_text.rb
|
|
517
|
+
- lib/llm/tools/which.rb
|
|
514
518
|
- lib/llm/tools/write_file.rb
|
|
515
519
|
- lib/llm/tracer.rb
|
|
516
520
|
- lib/llm/tracer/logger.rb
|