llm.rb 11.3.1 → 12.1.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 +354 -2
- data/LICENSE +93 -17
- data/README.md +226 -616
- data/data/anthropic.json +322 -426
- data/data/bedrock.json +2634 -1144
- data/data/deepinfra.json +1513 -0
- data/data/deepseek.json +57 -28
- data/data/google.json +411 -771
- data/data/openai.json +1104 -771
- data/data/xai.json +141 -292
- data/data/zai.json +263 -141
- data/lib/llm/active_record/acts_as_agent.rb +3 -41
- data/lib/llm/active_record/acts_as_llm.rb +18 -0
- data/lib/llm/active_record.rb +3 -3
- data/lib/llm/agent.rb +25 -1
- data/lib/llm/context.rb +17 -5
- data/lib/llm/contract/completion.rb +2 -2
- data/lib/llm/json_adapter.rb +29 -3
- data/lib/llm/provider.rb +3 -3
- data/lib/llm/providers/deepinfra/audio.rb +66 -0
- data/lib/llm/providers/deepinfra/images.rb +90 -0
- data/lib/llm/providers/deepinfra/response_adapter.rb +36 -0
- data/lib/llm/providers/deepinfra.rb +100 -0
- data/lib/llm/providers/deepseek/images.rb +109 -0
- data/lib/llm/providers/deepseek/request_adapter.rb +32 -0
- data/lib/llm/providers/deepseek/response_adapter/image.rb +9 -0
- data/lib/llm/providers/deepseek/response_adapter.rb +29 -0
- data/lib/llm/providers/deepseek.rb +4 -2
- data/lib/llm/providers/google/request_adapter.rb +22 -5
- data/lib/llm/providers/google.rb +4 -4
- data/lib/llm/providers/llamacpp.rb +5 -5
- data/lib/llm/providers/openai/audio.rb +6 -2
- data/lib/llm/providers/openai/images.rb +9 -50
- data/lib/llm/providers/openai/request_adapter/respond.rb +38 -4
- data/lib/llm/providers/openai/response_adapter/audio.rb +5 -1
- data/lib/llm/providers/openai/response_adapter/completion.rb +1 -1
- data/lib/llm/providers/openai/response_adapter/image.rb +0 -4
- data/lib/llm/providers/openai/responses.rb +1 -0
- data/lib/llm/providers/openai/stream_parser.rb +5 -6
- data/lib/llm/providers/openai.rb +2 -2
- data/lib/llm/providers/xai/images.rb +49 -26
- data/lib/llm/providers/xai.rb +2 -2
- data/lib/llm/repl/input.rb +64 -0
- data/lib/llm/repl/status.rb +30 -0
- data/lib/llm/repl/stream.rb +46 -0
- data/lib/llm/repl/transcript.rb +61 -0
- data/lib/llm/repl/window.rb +107 -0
- data/lib/llm/repl.rb +78 -0
- data/lib/llm/response.rb +10 -0
- data/lib/llm/schema/leaf.rb +7 -1
- data/lib/llm/schema/renderer.rb +121 -0
- data/lib/llm/schema.rb +30 -0
- data/lib/llm/sequel/agent.rb +2 -43
- data/lib/llm/sequel/plugin.rb +25 -7
- data/lib/llm/tools/chdir.rb +23 -0
- data/lib/llm/tools/git.rb +41 -0
- data/lib/llm/tools/mkdir.rb +32 -0
- data/lib/llm/tools/pwd.rb +20 -0
- data/lib/llm/tools/read_file.rb +40 -0
- data/lib/llm/tools/rg.rb +46 -0
- data/lib/llm/tools/shell.rb +48 -0
- data/lib/llm/tools/swap_text.rb +25 -0
- data/lib/llm/tools/write_file.rb +24 -0
- data/lib/llm/tools.rb +5 -0
- data/lib/llm/tracer/telemetry.rb +4 -6
- data/lib/llm/tracer.rb +9 -21
- data/lib/llm/transport/execution.rb +16 -1
- data/lib/llm/transport/net_http_adapter.rb +1 -1
- data/lib/llm/uridata.rb +16 -0
- data/lib/llm/version.rb +1 -1
- data/lib/llm.rb +9 -0
- data/llm.gemspec +5 -18
- data/resources/deepdive.md +829 -263
- metadata +31 -18
- data/lib/llm/tracer/langsmith.rb +0 -144
metadata
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: llm.rb
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 12.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- bsdrobert
|
|
8
8
|
- Antar Azri
|
|
9
9
|
- Rodrigo Serrano
|
|
10
10
|
bindir: bin
|
|
@@ -277,20 +277,8 @@ dependencies:
|
|
|
277
277
|
- - "~>"
|
|
278
278
|
- !ruby/object:Gem::Version
|
|
279
279
|
version: '1.18'
|
|
280
|
-
description:
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
It runs on Ruby's standard library by default. loads optional pieces
|
|
284
|
-
only when needed, and offers a single runtime for providers, agents,
|
|
285
|
-
tools, skills, MCP, A2A (Agent2Agent), RAG (vector stores & embeddings),
|
|
286
|
-
streaming, files, and persisted state. As a bonus, llm.rb is also available
|
|
287
|
-
for mruby.
|
|
288
|
-
|
|
289
|
-
It supports OpenAI, OpenAI-compatible endpoints, Anthropic, Google
|
|
290
|
-
Gemini, DeepSeek, xAI, Z.ai, AWS Bedrock, Ollama, and llama.cpp. It
|
|
291
|
-
also includes built-in ActiveRecord and Sequel support, plus concurrent
|
|
292
|
-
tool execution through threads, tasks (via async gem), fibers, ractors,
|
|
293
|
-
and fork (via xchan.rb gem).
|
|
280
|
+
description: llm.rb is not a library, framework or toolkit but an advanced runtime
|
|
281
|
+
for building highly capable AI applications on CRuby.
|
|
294
282
|
email:
|
|
295
283
|
- robert@r.uby.dev
|
|
296
284
|
executables: []
|
|
@@ -302,6 +290,7 @@ files:
|
|
|
302
290
|
- README.md
|
|
303
291
|
- data/anthropic.json
|
|
304
292
|
- data/bedrock.json
|
|
293
|
+
- data/deepinfra.json
|
|
305
294
|
- data/deepseek.json
|
|
306
295
|
- data/google.json
|
|
307
296
|
- data/openai.json
|
|
@@ -401,9 +390,16 @@ files:
|
|
|
401
390
|
- lib/llm/providers/bedrock/signature.rb
|
|
402
391
|
- lib/llm/providers/bedrock/stream_decoder.rb
|
|
403
392
|
- lib/llm/providers/bedrock/stream_parser.rb
|
|
393
|
+
- lib/llm/providers/deepinfra.rb
|
|
394
|
+
- lib/llm/providers/deepinfra/audio.rb
|
|
395
|
+
- lib/llm/providers/deepinfra/images.rb
|
|
396
|
+
- lib/llm/providers/deepinfra/response_adapter.rb
|
|
404
397
|
- lib/llm/providers/deepseek.rb
|
|
398
|
+
- lib/llm/providers/deepseek/images.rb
|
|
405
399
|
- lib/llm/providers/deepseek/request_adapter.rb
|
|
406
400
|
- lib/llm/providers/deepseek/request_adapter/completion.rb
|
|
401
|
+
- lib/llm/providers/deepseek/response_adapter.rb
|
|
402
|
+
- lib/llm/providers/deepseek/response_adapter/image.rb
|
|
407
403
|
- lib/llm/providers/google.rb
|
|
408
404
|
- lib/llm/providers/google/audio.rb
|
|
409
405
|
- lib/llm/providers/google/error_handler.rb
|
|
@@ -463,6 +459,12 @@ files:
|
|
|
463
459
|
- lib/llm/providers/xai/images.rb
|
|
464
460
|
- lib/llm/providers/zai.rb
|
|
465
461
|
- lib/llm/registry.rb
|
|
462
|
+
- lib/llm/repl.rb
|
|
463
|
+
- lib/llm/repl/input.rb
|
|
464
|
+
- lib/llm/repl/status.rb
|
|
465
|
+
- lib/llm/repl/stream.rb
|
|
466
|
+
- lib/llm/repl/transcript.rb
|
|
467
|
+
- lib/llm/repl/window.rb
|
|
466
468
|
- lib/llm/response.rb
|
|
467
469
|
- lib/llm/schema.rb
|
|
468
470
|
- lib/llm/schema/all_of.rb
|
|
@@ -477,6 +479,7 @@ files:
|
|
|
477
479
|
- lib/llm/schema/object.rb
|
|
478
480
|
- lib/llm/schema/one_of.rb
|
|
479
481
|
- lib/llm/schema/parser.rb
|
|
482
|
+
- lib/llm/schema/renderer.rb
|
|
480
483
|
- lib/llm/schema/string.rb
|
|
481
484
|
- lib/llm/schema/version.rb
|
|
482
485
|
- lib/llm/sequel/agent.rb
|
|
@@ -488,8 +491,17 @@ files:
|
|
|
488
491
|
- lib/llm/stream/queue.rb
|
|
489
492
|
- lib/llm/tool.rb
|
|
490
493
|
- lib/llm/tool/param.rb
|
|
494
|
+
- lib/llm/tools.rb
|
|
495
|
+
- lib/llm/tools/chdir.rb
|
|
496
|
+
- lib/llm/tools/git.rb
|
|
497
|
+
- lib/llm/tools/mkdir.rb
|
|
498
|
+
- lib/llm/tools/pwd.rb
|
|
499
|
+
- lib/llm/tools/read_file.rb
|
|
500
|
+
- lib/llm/tools/rg.rb
|
|
501
|
+
- lib/llm/tools/shell.rb
|
|
502
|
+
- lib/llm/tools/swap_text.rb
|
|
503
|
+
- lib/llm/tools/write_file.rb
|
|
491
504
|
- lib/llm/tracer.rb
|
|
492
|
-
- lib/llm/tracer/langsmith.rb
|
|
493
505
|
- lib/llm/tracer/logger.rb
|
|
494
506
|
- lib/llm/tracer/null.rb
|
|
495
507
|
- lib/llm/tracer/telemetry.rb
|
|
@@ -505,6 +517,7 @@ files:
|
|
|
505
517
|
- lib/llm/transport/response/http.rb
|
|
506
518
|
- lib/llm/transport/stream_decoder.rb
|
|
507
519
|
- lib/llm/transport/utils.rb
|
|
520
|
+
- lib/llm/uridata.rb
|
|
508
521
|
- lib/llm/usage.rb
|
|
509
522
|
- lib/llm/utils.rb
|
|
510
523
|
- lib/llm/version.rb
|
|
@@ -514,7 +527,7 @@ files:
|
|
|
514
527
|
- resources/deepdive.md
|
|
515
528
|
homepage: https://r.uby.dev/llm/
|
|
516
529
|
licenses:
|
|
517
|
-
-
|
|
530
|
+
- BUSL-1.1
|
|
518
531
|
metadata:
|
|
519
532
|
homepage_uri: https://r.uby.dev/llm/
|
|
520
533
|
source_code_uri: https://github.com/r-uby-dev/llm.rb
|
data/lib/llm/tracer/langsmith.rb
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module LLM
|
|
4
|
-
##
|
|
5
|
-
# LangSmith-specific tracer built on top of Telemetry. Supports extra
|
|
6
|
-
# inputs/outputs and metadata on traces and spans via {#merge_extra} and
|
|
7
|
-
# {#start_trace}(metadata:).
|
|
8
|
-
#
|
|
9
|
-
# @example Constructor metadata and tags
|
|
10
|
-
# llm.tracer = LLM::Tracer::Langsmith.new(
|
|
11
|
-
# llm,
|
|
12
|
-
# session_id: "123e4567-e89b-12d3-a456-426614174000",
|
|
13
|
-
# metadata: {env: "dev"},
|
|
14
|
-
# tags: ["changelog"]
|
|
15
|
-
# )
|
|
16
|
-
#
|
|
17
|
-
# @example Per-request extra metadata and inputs (e.g. from chatbot)
|
|
18
|
-
# tracer.merge_extra(
|
|
19
|
-
# metadata: { turn_id: turn.id, component: "chatbot_message_stream" },
|
|
20
|
-
# inputs: { "gen_ai.input.messages" => messages_json }
|
|
21
|
-
# )
|
|
22
|
-
# bot.chat(prompt)
|
|
23
|
-
#
|
|
24
|
-
# @example Trace-level metadata via start_trace
|
|
25
|
-
# tracer.start_trace(trace_group_id: turn.id, name: "chatbot.turn", metadata: { turn_id: turn.id })
|
|
26
|
-
class Tracer::Langsmith < Tracer::Telemetry
|
|
27
|
-
THREAD_EXTRA_KEY = :llm_langsmith_extra
|
|
28
|
-
|
|
29
|
-
UUID = /\A
|
|
30
|
-
[0-9a-f]{8}-
|
|
31
|
-
[0-9a-f]{4}-
|
|
32
|
-
[1-5][0-9a-f]{3}-
|
|
33
|
-
[89ab][0-9a-f]{3}-
|
|
34
|
-
[0-9a-f]{12}
|
|
35
|
-
\z/ix
|
|
36
|
-
|
|
37
|
-
def initialize(provider, options = {})
|
|
38
|
-
super
|
|
39
|
-
setup_langsmith!(options)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def start_trace(trace_group_id: nil, name: "llm", attributes: {}, metadata: nil)
|
|
43
|
-
merge_extra(metadata: metadata) if metadata && !metadata.empty?
|
|
44
|
-
super
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def stop_trace
|
|
48
|
-
clear_thread_extra!
|
|
49
|
-
super
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def merge_extra(metadata: nil, inputs: nil, outputs: nil)
|
|
53
|
-
store = thread_extra
|
|
54
|
-
store[:metadata].merge!(metadata) if metadata && !metadata.empty?
|
|
55
|
-
store[:inputs].merge!(inputs) if inputs && !inputs.empty?
|
|
56
|
-
store[:outputs].merge!(outputs) if outputs && !outputs.empty?
|
|
57
|
-
self
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def current_extra
|
|
61
|
-
store = thread_extra
|
|
62
|
-
{
|
|
63
|
-
metadata: store[:metadata].dup,
|
|
64
|
-
inputs: store[:inputs].dup,
|
|
65
|
-
outputs: store[:outputs].dup
|
|
66
|
-
}
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def consume_extra_inputs
|
|
70
|
-
thread_extra[:inputs].tap { thread_extra[:inputs] = {} }
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def consume_extra_outputs
|
|
74
|
-
thread_extra[:outputs].tap { thread_extra[:outputs] = {} }
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
private
|
|
78
|
-
|
|
79
|
-
def trace_attributes(span_kind:)
|
|
80
|
-
attributes = {}
|
|
81
|
-
unless @langsmith_session_id.to_s.empty?
|
|
82
|
-
attributes["langsmith.trace.session_id"] = @langsmith_session_id
|
|
83
|
-
end
|
|
84
|
-
merged_metadata = @langsmith_metadata.merge(thread_extra[:metadata])
|
|
85
|
-
merged_metadata.each do |key, value|
|
|
86
|
-
next if value.nil?
|
|
87
|
-
|
|
88
|
-
attr_key = key.to_s.start_with?("langsmith.metadata.") ? key.to_s : "langsmith.metadata.#{key}"
|
|
89
|
-
attributes[attr_key] = serialize_langsmith_value(value)
|
|
90
|
-
end
|
|
91
|
-
unless @langsmith_tags.empty?
|
|
92
|
-
attributes["langsmith.span.tags"] = @langsmith_tags.map(&:to_s).join(",")
|
|
93
|
-
end
|
|
94
|
-
attributes["langsmith.span.kind"] = span_kind
|
|
95
|
-
attributes
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def thread_extra
|
|
99
|
-
Thread.current[THREAD_EXTRA_KEY] ||= {
|
|
100
|
-
metadata: {},
|
|
101
|
-
inputs: {},
|
|
102
|
-
outputs: {}
|
|
103
|
-
}
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def clear_thread_extra!
|
|
107
|
-
Thread.current[THREAD_EXTRA_KEY] = nil
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def setup_langsmith!(options)
|
|
111
|
-
options ||= {}
|
|
112
|
-
@langsmith_metadata = options[:metadata] || {}
|
|
113
|
-
@langsmith_session_id = normalize_langsmith_session_id(
|
|
114
|
-
options[:session_id],
|
|
115
|
-
metadata: @langsmith_metadata
|
|
116
|
-
)
|
|
117
|
-
@langsmith_tags = options[:tags] || []
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def serialize_langsmith_value(value)
|
|
121
|
-
case value
|
|
122
|
-
when String, Numeric, TrueClass, FalseClass
|
|
123
|
-
value
|
|
124
|
-
else
|
|
125
|
-
LLM.json.dump(value)
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def normalize_langsmith_session_id(session_id, metadata:)
|
|
130
|
-
raw = session_id&.to_s
|
|
131
|
-
return nil if raw.to_s.empty?
|
|
132
|
-
return raw if uuid?(raw)
|
|
133
|
-
|
|
134
|
-
# Keep arbitrary identifiers in metadata instead of forcing
|
|
135
|
-
# them into langsmith.trace.session_id, which expects a UUID.
|
|
136
|
-
metadata[:session_id] ||= raw
|
|
137
|
-
nil
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def uuid?(value)
|
|
141
|
-
value.match?(UUID)
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
end
|