llm_chain 0.5.4 ā 0.6.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 +65 -4
- data/README.md +111 -20
- data/examples/composite_agent_example.rb +121 -0
- data/examples/planner_agent_example.rb +103 -0
- data/examples/quick_demo.rb +1 -7
- data/examples/react_agent_example.rb +64 -0
- data/examples/tools_example.rb +1 -163
- data/exe/llm-chain +1 -1
- data/lib/llm_chain/agents/agent_factory.rb +120 -0
- data/lib/llm_chain/agents/composite_agent.rb +341 -0
- data/lib/llm_chain/agents/planner_agent.rb +108 -0
- data/lib/llm_chain/agents/react_agent.rb +307 -0
- data/lib/llm_chain/agents.rb +19 -0
- data/lib/llm_chain/builders/memory_context.rb +24 -0
- data/lib/llm_chain/builders/prompt.rb +26 -0
- data/lib/llm_chain/builders/rag_documents.rb +25 -0
- data/lib/llm_chain/builders/retriever_context.rb +25 -0
- data/lib/llm_chain/builders/tool_responses.rb +27 -0
- data/lib/llm_chain/chain.rb +68 -81
- data/lib/llm_chain/clients/gemma3.rb +5 -3
- data/lib/llm_chain/clients/openai.rb +1 -1
- data/lib/llm_chain/clients/qwen.rb +27 -15
- data/lib/llm_chain/configuration_validator.rb +11 -7
- data/lib/llm_chain/embeddings/clients/local/ollama_client.rb +2 -0
- data/lib/llm_chain/embeddings/clients/local/weaviate_vector_store.rb +2 -2
- data/lib/llm_chain/interfaces/agent.rb +54 -0
- data/lib/llm_chain/interfaces/builders/memory_context_builder.rb +20 -0
- data/lib/llm_chain/interfaces/builders/prompt_builder.rb +23 -0
- data/lib/llm_chain/interfaces/builders/rag_documents_builder.rb +20 -0
- data/lib/llm_chain/interfaces/builders/retriever_context_builder.rb +22 -0
- data/lib/llm_chain/interfaces/builders/tool_responses_builder.rb +20 -0
- data/lib/llm_chain/interfaces/memory.rb +38 -0
- data/lib/llm_chain/interfaces/tool_manager.rb +87 -0
- data/lib/llm_chain/memory/array.rb +18 -1
- data/lib/llm_chain/memory/redis.rb +20 -3
- data/lib/llm_chain/system_diagnostics.rb +73 -0
- data/lib/llm_chain/tools/calculator.rb +117 -44
- data/lib/llm_chain/tools/code_interpreter.rb +10 -3
- data/lib/llm_chain/tools/date_time.rb +63 -7
- data/lib/llm_chain/tools/tool_manager.rb +32 -87
- data/lib/llm_chain/tools/tool_manager_factory.rb +44 -0
- data/lib/llm_chain/tools/web_search.rb +232 -339
- data/lib/llm_chain/version.rb +1 -1
- data/lib/llm_chain.rb +56 -55
- metadata +128 -24
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 59badf4884002e839c8cd2c429db8f49dd21ba160d48303d6cb6b82bb06ca530
|
|
4
|
+
data.tar.gz: e1e89a377cf916c7174347d1ec1db2008b751d42f6a92cbc1738144997d4e683
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67cc37814800ded158a5039532ab207c222fed04926ad2fbedb58f43a2c6558adb94c19dfbc338a0c4af59ff9cd019e6f2ef9996ff01b4fd88c140334be03c1e
|
|
7
|
+
data.tar.gz: 9d634723d69b612d59d3984fe3325cc5429aad6062e4f7a477ce15cfe70e61b2bdc6b016913c9fcb4d8a499963141d3fb39218853375a63227766b28613932c6
|
data/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [0.
|
|
10
|
+
## [0.6.0] - 2025-07-24
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
* **Smart CompositeAgent** - Intelligent planning and execution capabilities:
|
|
14
|
+
* Automatic detection of simple vs complex tasks (math, time queries vs multi-step tasks)
|
|
15
|
+
* Direct execution for simple tasks (no unnecessary planning overhead)
|
|
16
|
+
* Smart result validation and quality scoring (0-10 scale)
|
|
17
|
+
* Intelligent result aggregation with structured summaries
|
|
18
|
+
* Better error handling and graceful degradation
|
|
19
|
+
* Meaningful information extraction from tool responses
|
|
20
|
+
* **Enhanced DateTime Tool** - Improved timezone handling and parsing:
|
|
21
|
+
* Support for multi-word timezone names (e.g., "New York", "Europe/Moscow")
|
|
22
|
+
* IANA timezone mapping and validation
|
|
23
|
+
* Better JSON input parsing
|
|
24
|
+
* Improved timezone abbreviation display
|
|
25
|
+
* Fallback handling for invalid timezones
|
|
26
|
+
* **Improved ReActAgent** - Better tool usage and reasoning:
|
|
27
|
+
* Enhanced prompt instructions for DateTime tool integration
|
|
28
|
+
* Improved termination logic to prevent premature stopping
|
|
29
|
+
* Better guidance for current information queries (uses DateTime before WebSearch)
|
|
30
|
+
* Support for multiple timezone queries
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
* **CompositeAgent Architecture** - Major refactoring for better performance:
|
|
34
|
+
* Split execution into `run_with_planning` and `execute_directly` methods
|
|
35
|
+
* Introduced `should_use_planner?` for intelligent task classification
|
|
36
|
+
* Enhanced result processing with `validate_and_process_result`
|
|
37
|
+
* Improved success validation with `validate_overall_success`
|
|
38
|
+
* Better streaming support with proper step tracking
|
|
39
|
+
* **Example Files Cleanup** - Streamlined and improved examples:
|
|
40
|
+
* Removed redundant and temporary example files
|
|
41
|
+
* Cleaned up all comments for better readability
|
|
42
|
+
* Consolidated planner agent examples
|
|
43
|
+
* Improved composite agent demonstration
|
|
44
|
+
* **Test Suite Improvements** - Better test coverage and reliability:
|
|
45
|
+
* Updated CompositeAgent specs to match new behavior
|
|
46
|
+
* Fixed DateTime tool specs with proper mocking
|
|
47
|
+
* Improved test isolation and dependency handling
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
* **DateTime Tool Parsing** - Fixed "Invalid identifier" errors for multi-word timezones
|
|
51
|
+
* **ReActAgent Termination** - Prevented premature stopping after DateTime tool usage
|
|
52
|
+
* **CompositeAgent Streaming** - Fixed keyword argument passing for stream parameter
|
|
53
|
+
* **Test Reliability** - Resolved TZInfo dependency issues in test environment
|
|
54
|
+
|
|
55
|
+
## [0.5.5] - 2025-07-17
|
|
56
|
+
|
|
57
|
+
### Changed
|
|
58
|
+
* **Major refactor:**
|
|
59
|
+
* Core classes have been extensively refactored for improved modularity, clarity, and maintainability:
|
|
60
|
+
* Adopted SOLID principles throughout the codebase.
|
|
61
|
+
* Extracted interfaces for memory, tool management, and all builder components, now located in a dedicated `interfaces` namespace.
|
|
62
|
+
* Introduced a `builders` folder and builder pattern for prompt, memory context, tool responses, RAG documents, and retriever context.
|
|
63
|
+
* Improved dependency injection and separation of concerns, making the codebase easier to extend and test.
|
|
64
|
+
* Centralized error handling and configuration validation.
|
|
65
|
+
* Enhanced documentation and type signatures for all major classes.
|
|
66
|
+
* The public API remains minimal and idiomatic, with extensibility via interfaces and factories.
|
|
67
|
+
* `Chain#ask` method rewritten following Ruby best practices: now declarative, each pipeline stage is a private method, code is cleaner and easier to extend.
|
|
68
|
+
* All ToolManager creation and configuration is now done via a dedicated factory: `ToolManagerFactory`. Old calls (`ToolManager.create_default_toolset`, `ToolManager.from_config`) have been replaced with factory methods.
|
|
69
|
+
|
|
70
|
+
## [0.5.4] - 2025-07-08
|
|
11
71
|
|
|
12
72
|
### Added
|
|
13
73
|
* **Deepseek-Coder-V2 Client** - Support for Deepseek-Coder-V2 models via Ollama
|
|
@@ -95,9 +155,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
95
155
|
### Changed
|
|
96
156
|
- Initial stable release with core functionality
|
|
97
157
|
|
|
98
|
-
[Unreleased]: https://github.com/FuryCow/llm_chain/compare/v0.
|
|
99
|
-
[0.
|
|
158
|
+
[Unreleased]: https://github.com/FuryCow/llm_chain/compare/v0.6.0...HEAD
|
|
159
|
+
[0.6.0]: https://github.com/FuryCow/llm_chain/compare/v0.5.5...v0.6.0
|
|
160
|
+
[0.5.5]: https://github.com/FuryCow/llm_chain/compare/v0.5.4...v0.5.5
|
|
100
161
|
[0.5.3]: https://github.com/FuryCow/llm_chain/compare/v0.5.2...v0.5.3
|
|
101
162
|
[0.5.2]: https://github.com/FuryCow/llm_chain/compare/v0.5.1...v0.5.2
|
|
102
163
|
[0.5.1]: https://github.com/FuryCow/llm_chain/compare/v0.5.0...v0.5.1
|
|
103
|
-
[0.5.0]: https://github.com/FuryCow/llm_chain/releases/tag/v0.5.0
|
|
164
|
+
[0.5.0]: https://github.com/FuryCow/llm_chain/releases/tag/v0.5.0
|
data/README.md
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
# 𦾠LLMChain
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/rb/llm_chain)
|
|
4
|
-
[](https://github.com/FuryCow/llm_chain/actions/workflows/rspec.yml)
|
|
5
5
|
[](LICENSE.txt)
|
|
6
6
|
|
|
7
7
|
**A powerful Ruby library for working with Large Language Models (LLMs) with intelligent tool system**
|
|
8
8
|
|
|
9
|
-
LLMChain is a Ruby
|
|
9
|
+
**LLMChain** is a powerful Ruby library that brings the magic of Large Language Models to your applications. Think of it as your AI Swiss Army knife - whether you need to chat with models, execute code, search the web, or build intelligent agents, LLMChain has you covered.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Built with Ruby's elegance and designed for developers who want to harness AI capabilities without the complexity, LLMChain provides a unified interface for OpenAI, Ollama, Qwen, and other leading LLMs. It comes packed with intelligent tools, smart agents, and RAG capabilities out of the box.
|
|
12
12
|
|
|
13
|
-
* š„ļø **New CLI executable** `llm-chain`
|
|
14
|
-
* `chat` ā ask a one-off question from your shell
|
|
15
|
-
* `repl` ā interactive session with conversation memory and helper commands (`/help`, `/mem clear`, `/tools list`)
|
|
16
|
-
* `diagnose` ā run the built-in environment health-check
|
|
17
|
-
* `tools list` ā inspect available tools
|
|
18
13
|
* š **Bundler-aware loading** ā CLI detects if itās executed inside the gem repo and avoids version clashes with external Gemfiles.
|
|
19
14
|
|
|
20
15
|
Thatās all you need to start talking to LLMs straight from the terminal. See the **Command-line Interface** section below for usage examples.
|
|
@@ -22,8 +17,9 @@ Thatās all you need to start talking to LLMs straight from the terminal. See t
|
|
|
22
17
|
## ⨠Key Features
|
|
23
18
|
|
|
24
19
|
- š¤ **Unified API** for multiple LLMs (OpenAI, Ollama, Qwen, LLaMA2, Gemma)
|
|
20
|
+
- š§ **Smart Agents** - CompositeAgent, ReActAgent, PlannerAgent for complex reasoning
|
|
25
21
|
- š ļø **Intelligent tool system** with automatic selection
|
|
26
|
-
- š§® **Built-in tools**: Calculator, web search, code interpreter
|
|
22
|
+
- š§® **Built-in tools**: Calculator, web search, code interpreter, DateTime
|
|
27
23
|
- š **RAG-ready** with vector database integration
|
|
28
24
|
- š¾ **Flexible memory system** (Array, Redis)
|
|
29
25
|
- š **Streaming output** for real-time responses
|
|
@@ -159,7 +155,7 @@ chain = LLMChain.quick_chain(
|
|
|
159
155
|
# Manual validation
|
|
160
156
|
LLMChain::ConfigurationValidator.validate_chain_config!(
|
|
161
157
|
model: "qwen3:1.7b",
|
|
162
|
-
tools: LLMChain::Tools::
|
|
158
|
+
tools: LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
163
159
|
)
|
|
164
160
|
```
|
|
165
161
|
|
|
@@ -182,7 +178,7 @@ chain.ask("Execute code: puts (1..10).sum")
|
|
|
182
178
|
# š» Result: 55
|
|
183
179
|
|
|
184
180
|
# Traditional setup
|
|
185
|
-
tool_manager = LLMChain::Tools::
|
|
181
|
+
tool_manager = LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
186
182
|
chain = LLMChain::Chain.new(
|
|
187
183
|
model: "qwen3:1.7b",
|
|
188
184
|
tools: tool_manager
|
|
@@ -199,6 +195,31 @@ puts result[:formatted]
|
|
|
199
195
|
# Output: sqrt(144) = 12.0
|
|
200
196
|
```
|
|
201
197
|
|
|
198
|
+
#### š DateTime (Enhanced in v0.6.0)
|
|
199
|
+
```ruby
|
|
200
|
+
datetime = LLMChain::Tools::DateTime.new
|
|
201
|
+
|
|
202
|
+
# Current time
|
|
203
|
+
result = datetime.call("What time is it?")
|
|
204
|
+
puts result[:formatted]
|
|
205
|
+
# Output: 2025-07-24 15:30:45 UTC
|
|
206
|
+
|
|
207
|
+
# Time in specific timezone
|
|
208
|
+
result = datetime.call("What time is it in New York?")
|
|
209
|
+
puts result[:formatted]
|
|
210
|
+
# Output: 2025-07-24 11:30:45 EDT
|
|
211
|
+
|
|
212
|
+
# Time in Europe
|
|
213
|
+
result = datetime.call("What time is it in Europe/Moscow?")
|
|
214
|
+
puts result[:formatted]
|
|
215
|
+
# Output: 2025-07-24 18:30:45 MSK
|
|
216
|
+
|
|
217
|
+
# JSON input support
|
|
218
|
+
result = datetime.call('{"timezone": "Asia/Tokyo"}')
|
|
219
|
+
puts result[:formatted]
|
|
220
|
+
# Output: 2025-07-25 00:30:45 JST
|
|
221
|
+
```
|
|
222
|
+
|
|
202
223
|
#### š Web Search
|
|
203
224
|
```ruby
|
|
204
225
|
# Google search for accurate results (v0.5.1+)
|
|
@@ -342,6 +363,7 @@ end
|
|
|
342
363
|
|
|
343
364
|
# Usage
|
|
344
365
|
weather = WeatherTool.new(api_key: "your-key")
|
|
366
|
+
tool_manager = LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
345
367
|
tool_manager.register_tool(weather)
|
|
346
368
|
```
|
|
347
369
|
|
|
@@ -488,7 +510,7 @@ chain.ask("Tell me about Ruby history", stream: true) do |chunk|
|
|
|
488
510
|
end
|
|
489
511
|
|
|
490
512
|
# Streaming with tools
|
|
491
|
-
tool_manager = LLMChain::Tools::
|
|
513
|
+
tool_manager = LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
492
514
|
chain = LLMChain::Chain.new(
|
|
493
515
|
model: "qwen3:1.7b",
|
|
494
516
|
tools: tool_manager
|
|
@@ -543,7 +565,7 @@ tools_config = [
|
|
|
543
565
|
}
|
|
544
566
|
]
|
|
545
567
|
|
|
546
|
-
tool_manager = LLMChain::Tools::
|
|
568
|
+
tool_manager = LLMChain::Tools::ToolManagerFactory.from_config(tools_config)
|
|
547
569
|
```
|
|
548
570
|
|
|
549
571
|
### Client Settings
|
|
@@ -626,6 +648,68 @@ code_result = code_runner.call("puts 'Hello World!'")
|
|
|
626
648
|
|
|
627
649
|
## š Usage Examples
|
|
628
650
|
|
|
651
|
+
### Smart Agents (v0.6.0+)
|
|
652
|
+
|
|
653
|
+
#### CompositeAgent - Intelligent Planning and Execution
|
|
654
|
+
|
|
655
|
+
```ruby
|
|
656
|
+
require 'llm_chain'
|
|
657
|
+
|
|
658
|
+
# Create a smart composite agent
|
|
659
|
+
agent = LLMChain::Agents::AgentFactory.create(
|
|
660
|
+
type: :composite,
|
|
661
|
+
model: "qwen3:1.7b",
|
|
662
|
+
max_iterations: 3
|
|
663
|
+
)
|
|
664
|
+
|
|
665
|
+
# Simple task - direct execution (no planning overhead)
|
|
666
|
+
result = agent.run("Calculate 15 * 7 + 32")
|
|
667
|
+
puts result[:final_answer] # "137"
|
|
668
|
+
puts result[:approach] # "direct"
|
|
669
|
+
|
|
670
|
+
# Complex task - intelligent planning
|
|
671
|
+
result = agent.run("Find the current president of the United States and the capital of France", stream: true) do |step|
|
|
672
|
+
if step[:type] == "step_completion"
|
|
673
|
+
puts "Step #{step[:step]}/#{step[:total_steps]}: #{step[:current_step]}"
|
|
674
|
+
puts "Quality: #{step[:validated_answer][:quality_score]}/10"
|
|
675
|
+
end
|
|
676
|
+
end
|
|
677
|
+
|
|
678
|
+
puts result[:final_answer]
|
|
679
|
+
# "Joe Biden\n\nParis\n\nSummary: The current president of the United States is Joe Biden, and the capital of France is Paris."
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
#### ReActAgent - Reasoning and Acting
|
|
683
|
+
|
|
684
|
+
```ruby
|
|
685
|
+
# Create a ReAct agent for complex reasoning tasks
|
|
686
|
+
react_agent = LLMChain::Agents::AgentFactory.create(
|
|
687
|
+
type: :react,
|
|
688
|
+
model: "qwen3:1.7b",
|
|
689
|
+
max_iterations: 5
|
|
690
|
+
)
|
|
691
|
+
|
|
692
|
+
# Agent will use tools intelligently
|
|
693
|
+
result = react_agent.run("What time is it in New York and what's the weather like?")
|
|
694
|
+
puts result[:final_answer]
|
|
695
|
+
# Uses DateTime tool first, then WebSearch for weather
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
#### PlannerAgent - Task Decomposition
|
|
699
|
+
|
|
700
|
+
```ruby
|
|
701
|
+
# Create a planner agent for complex task breakdown
|
|
702
|
+
planner_agent = LLMChain::Agents::AgentFactory.create(
|
|
703
|
+
type: :planner,
|
|
704
|
+
model: "qwen3:1.7b"
|
|
705
|
+
)
|
|
706
|
+
|
|
707
|
+
# Decompose complex task into steps
|
|
708
|
+
result = planner_agent.run("Plan a vacation to Japan")
|
|
709
|
+
puts result[:planning_result][:steps]
|
|
710
|
+
# ["Research popular destinations in Japan", "Check visa requirements", "Find flights", "Book accommodations", "Plan itinerary"]
|
|
711
|
+
```
|
|
712
|
+
|
|
629
713
|
### Chatbot with Tools
|
|
630
714
|
|
|
631
715
|
```ruby
|
|
@@ -633,7 +717,7 @@ require 'llm_chain'
|
|
|
633
717
|
|
|
634
718
|
class ChatBot
|
|
635
719
|
def initialize
|
|
636
|
-
@tool_manager = LLMChain::Tools::
|
|
720
|
+
@tool_manager = LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
637
721
|
@memory = LLMChain::Memory::Array.new(max_size: 20)
|
|
638
722
|
@chain = LLMChain::Chain.new(
|
|
639
723
|
model: "qwen3:1.7b",
|
|
@@ -668,7 +752,7 @@ bot.chat_loop
|
|
|
668
752
|
```ruby
|
|
669
753
|
data_chain = LLMChain::Chain.new(
|
|
670
754
|
model: "qwen3:7b",
|
|
671
|
-
tools: LLMChain::Tools::
|
|
755
|
+
tools: LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
672
756
|
)
|
|
673
757
|
|
|
674
758
|
# Analyze CSV data
|
|
@@ -712,6 +796,10 @@ bundle exec bin/console
|
|
|
712
796
|
### Main Classes
|
|
713
797
|
|
|
714
798
|
- `LLMChain::Chain` - Main class for creating chains
|
|
799
|
+
- `LLMChain::Agents::AgentFactory` - Factory for creating smart agents
|
|
800
|
+
- `LLMChain::Agents::CompositeAgent` - Intelligent planning and execution
|
|
801
|
+
- `LLMChain::Agents::ReActAgent` - Reasoning and acting agent
|
|
802
|
+
- `LLMChain::Agents::PlannerAgent` - Task decomposition agent
|
|
715
803
|
- `LLMChain::Tools::ToolManager` - Tool management
|
|
716
804
|
- `LLMChain::Memory::Array/Redis` - Memory systems
|
|
717
805
|
- `LLMChain::Clients::*` - Clients for various LLMs
|
|
@@ -740,17 +828,20 @@ chain.ask(prompt, stream: false, rag_context: false, rag_options: {})
|
|
|
740
828
|
- [x] Enhanced error handling with retry logic
|
|
741
829
|
- [x] Improved code extraction and tool stability
|
|
742
830
|
|
|
743
|
-
### v0.6.0
|
|
744
|
-
- [
|
|
831
|
+
### v0.6.0 ā
Completed
|
|
832
|
+
- [x] Smart CompositeAgent with intelligent planning
|
|
833
|
+
- [x] Enhanced ReActAgent with better tool integration
|
|
834
|
+
- [x] Improved DateTime tool with timezone support
|
|
835
|
+
- [x] Better error handling and result validation
|
|
836
|
+
- [x] Streamlined examples and improved test coverage
|
|
837
|
+
|
|
838
|
+
### v0.7.0 (Next)
|
|
745
839
|
- [ ] More tools (file system, database queries)
|
|
746
840
|
- [ ] Claude integration
|
|
747
841
|
- [ ] Advanced logging and metrics
|
|
748
|
-
|
|
749
|
-
### v0.7.0
|
|
750
842
|
- [ ] Multi-agent systems
|
|
751
843
|
- [ ] Task planning and workflows
|
|
752
844
|
- [ ] Web interface for testing
|
|
753
|
-
- [ ] Metrics and monitoring
|
|
754
845
|
|
|
755
846
|
### v1.0.0
|
|
756
847
|
- [ ] Stable API with semantic versioning
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/llm_chain'
|
|
4
|
+
|
|
5
|
+
puts "š Improved CompositeAgent Final Demo"
|
|
6
|
+
puts "=" * 50
|
|
7
|
+
|
|
8
|
+
agent = LLMChain::Agents::AgentFactory.create(
|
|
9
|
+
type: :composite,
|
|
10
|
+
model: "qwen3:1.7b",
|
|
11
|
+
max_iterations: 3
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
puts "ā
Improved agent created successfully"
|
|
15
|
+
puts "Model: #{agent.model}"
|
|
16
|
+
puts "Description: #{agent.description}"
|
|
17
|
+
puts
|
|
18
|
+
|
|
19
|
+
puts "šÆ Test 1: Simple Math Task (Direct Execution)"
|
|
20
|
+
task1 = "Calculate 2 + 2"
|
|
21
|
+
puts "Task: #{task1}"
|
|
22
|
+
|
|
23
|
+
begin
|
|
24
|
+
result1 = agent.run(task1)
|
|
25
|
+
puts "ā
Result: #{result1[:final_answer]}"
|
|
26
|
+
puts "ā
Success: #{result1[:success]}"
|
|
27
|
+
puts "ā
Iterations: #{result1[:iterations]}"
|
|
28
|
+
puts "ā
Approach: #{result1[:approach]}"
|
|
29
|
+
rescue => e
|
|
30
|
+
puts "ā Error: #{e.message}"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
puts "\n" + "=" * 60
|
|
34
|
+
|
|
35
|
+
puts "šÆ Test 2: Simple Time Task (Direct Execution)"
|
|
36
|
+
task2 = "What time is it?"
|
|
37
|
+
puts "Task: #{task2}"
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
result2 = agent.run(task2)
|
|
41
|
+
puts "ā
Result: #{result2[:final_answer]}"
|
|
42
|
+
puts "ā
Success: #{result2[:success]}"
|
|
43
|
+
puts "ā
Iterations: #{result2[:iterations]}"
|
|
44
|
+
puts "ā
Approach: #{result2[:approach]}"
|
|
45
|
+
rescue => e
|
|
46
|
+
puts "ā Error: #{e.message}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
puts "\n" + "=" * 60
|
|
50
|
+
|
|
51
|
+
puts "šÆ Test 3: Complex Task (Planning)"
|
|
52
|
+
task3 = "Find the current president of the United States and the capital of France"
|
|
53
|
+
puts "Task: #{task3}"
|
|
54
|
+
|
|
55
|
+
begin
|
|
56
|
+
result3 = agent.run(task3, stream: true) do |step|
|
|
57
|
+
if step[:type] == "step_completion"
|
|
58
|
+
puts " š Step #{step[:step]}/#{step[:total_steps]}: #{step[:current_step]}"
|
|
59
|
+
if step[:validated_answer]
|
|
60
|
+
puts " ā
Validated: #{step[:validated_answer][:processed_answer][0..80]}..."
|
|
61
|
+
puts " š Quality Score: #{step[:validated_answer][:quality_score]}/10"
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
puts "\nš Final Result:"
|
|
67
|
+
puts "ā
Answer: #{result3[:final_answer][0..200]}..."
|
|
68
|
+
puts "ā
Success: #{result3[:success]}"
|
|
69
|
+
puts "ā
Total iterations: #{result3[:iterations]}"
|
|
70
|
+
puts "ā
Planning steps: #{result3[:planning_result][:steps].length}"
|
|
71
|
+
puts "ā
Validated answers: #{result3[:validated_answers]&.length || 0}"
|
|
72
|
+
|
|
73
|
+
rescue => e
|
|
74
|
+
puts "ā Error: #{e.message}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
puts "\n" + "=" * 60
|
|
78
|
+
|
|
79
|
+
puts "šÆ Test 4: Performance Comparison"
|
|
80
|
+
task4 = "Calculate 15 * 7 + 32"
|
|
81
|
+
|
|
82
|
+
react_agent = LLMChain::Agents::AgentFactory.create(
|
|
83
|
+
type: :react,
|
|
84
|
+
model: "qwen3:1.7b",
|
|
85
|
+
max_iterations: 3
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
puts "Task: #{task4}"
|
|
89
|
+
|
|
90
|
+
puts "\nš ReAct Agent:"
|
|
91
|
+
begin
|
|
92
|
+
react_result = react_agent.run(task4)
|
|
93
|
+
puts "ā
Result: #{react_result[:final_answer]}"
|
|
94
|
+
puts "ā
Success: #{react_result[:success]}"
|
|
95
|
+
puts "ā
Iterations: #{react_result[:iterations]}"
|
|
96
|
+
rescue => e
|
|
97
|
+
puts "ā Error: #{e.message}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
puts "\nš Improved Composite Agent:"
|
|
101
|
+
begin
|
|
102
|
+
composite_result = agent.run(task4)
|
|
103
|
+
puts "ā
Result: #{composite_result[:final_answer]}"
|
|
104
|
+
puts "ā
Success: #{composite_result[:success]}"
|
|
105
|
+
puts "ā
Iterations: #{composite_result[:iterations]}"
|
|
106
|
+
puts "ā
Approach: #{composite_result[:approach]}"
|
|
107
|
+
rescue => e
|
|
108
|
+
puts "ā Error: #{e.message}"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
puts "\nš Demo completed!"
|
|
112
|
+
puts
|
|
113
|
+
puts "š Key Improvements Achieved:"
|
|
114
|
+
puts "1. ā
Smart planning detection - simple tasks use direct execution"
|
|
115
|
+
puts "2. ā
Result validation - filters out error responses"
|
|
116
|
+
puts "3. ā
Quality scoring - rates answer quality (0-10)"
|
|
117
|
+
puts "4. ā
Smart aggregation - structures multi-part responses"
|
|
118
|
+
puts "5. ā
Better success validation - checks completeness of complex tasks"
|
|
119
|
+
puts "6. ā
Meaningful info extraction - extracts relevant data from responses"
|
|
120
|
+
puts "7. ā
Efficient execution - no unnecessary planning for simple tasks"
|
|
121
|
+
puts "8. ā
Better error handling - graceful handling of failed steps"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/llm_chain'
|
|
4
|
+
|
|
5
|
+
puts "š§ Simple PlannerAgent Example"
|
|
6
|
+
puts "=" * 40
|
|
7
|
+
|
|
8
|
+
planner = LLMChain::Agents::AgentFactory.create(
|
|
9
|
+
type: :planner,
|
|
10
|
+
model: "qwen3:1.7b"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
puts "ā
Planner agent created successfully"
|
|
14
|
+
puts "Model: #{planner.model}"
|
|
15
|
+
puts "Description: #{planner.description}"
|
|
16
|
+
puts
|
|
17
|
+
|
|
18
|
+
puts "šÆ Example 1: Simple Task"
|
|
19
|
+
task1 = "What is 2 + 2?"
|
|
20
|
+
puts "Task: #{task1}"
|
|
21
|
+
|
|
22
|
+
steps1 = planner.plan(task1)
|
|
23
|
+
puts "Steps:"
|
|
24
|
+
steps1.each_with_index do |step, index|
|
|
25
|
+
puts " #{index + 1}. #{step}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
puts
|
|
29
|
+
|
|
30
|
+
puts "šÆ Example 2: Multi-Part Task"
|
|
31
|
+
task2 = "Find the current president of the United States and the capital of France"
|
|
32
|
+
puts "Task: #{task2}"
|
|
33
|
+
|
|
34
|
+
steps2 = planner.plan(task2)
|
|
35
|
+
puts "Steps:"
|
|
36
|
+
steps2.each_with_index do |step, index|
|
|
37
|
+
puts " #{index + 1}. #{step}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
puts
|
|
41
|
+
|
|
42
|
+
puts "šÆ Example 3: Complex Task"
|
|
43
|
+
task3 = "Calculate 15 * 7 + 32, find the current time in Moscow, and get the population of Tokyo"
|
|
44
|
+
puts "Task: #{task3}"
|
|
45
|
+
|
|
46
|
+
steps3 = planner.plan(task3)
|
|
47
|
+
puts "Steps:"
|
|
48
|
+
steps3.each_with_index do |step, index|
|
|
49
|
+
puts " #{index + 1}. #{step}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
puts
|
|
53
|
+
|
|
54
|
+
puts "šÆ Example 4: Using run() method"
|
|
55
|
+
task4 = "What is the current time and what year is it?"
|
|
56
|
+
puts "Task: #{task4}"
|
|
57
|
+
|
|
58
|
+
result4 = planner.run(task4)
|
|
59
|
+
puts "Result:"
|
|
60
|
+
puts " Task: #{result4[:task]}"
|
|
61
|
+
puts " Steps: #{result4[:steps].length}"
|
|
62
|
+
result4[:steps].each_with_index do |step, index|
|
|
63
|
+
puts " #{index + 1}. #{step}"
|
|
64
|
+
end
|
|
65
|
+
puts " Full result: #{result4[:result]}"
|
|
66
|
+
|
|
67
|
+
puts
|
|
68
|
+
|
|
69
|
+
puts "šÆ Example 5: Comparison with ReAct Agent"
|
|
70
|
+
puts "Note: PlannerAgent only plans, ReActAgent executes"
|
|
71
|
+
|
|
72
|
+
react_agent = LLMChain::Agents::AgentFactory.create(
|
|
73
|
+
type: :react,
|
|
74
|
+
model: "qwen3:1.7b",
|
|
75
|
+
max_iterations: 3
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
comparison_task = "What is the current time?"
|
|
79
|
+
puts "Task: #{comparison_task}"
|
|
80
|
+
|
|
81
|
+
puts "\nPlannerAgent result:"
|
|
82
|
+
planner_steps = planner.plan(comparison_task)
|
|
83
|
+
planner_steps.each_with_index do |step, index|
|
|
84
|
+
puts " #{index + 1}. #{step}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
puts "\nReActAgent result:"
|
|
88
|
+
begin
|
|
89
|
+
react_result = react_agent.run(comparison_task)
|
|
90
|
+
puts " Final answer: #{react_result[:final_answer]}"
|
|
91
|
+
puts " Iterations: #{react_result[:iterations]}"
|
|
92
|
+
puts " Success: #{react_result[:success]}"
|
|
93
|
+
rescue => e
|
|
94
|
+
puts " Error: #{e.message}"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
puts "\nš Example completed!"
|
|
98
|
+
puts
|
|
99
|
+
puts "š Key Points:"
|
|
100
|
+
puts "1. PlannerAgent breaks down complex tasks into steps"
|
|
101
|
+
puts "2. It doesn't execute tasks, only plans them"
|
|
102
|
+
puts "3. Use plan() for just steps, run() for full result"
|
|
103
|
+
puts "4. Combine with ReActAgent for execution"
|
data/examples/quick_demo.rb
CHANGED
|
@@ -5,7 +5,6 @@ require_relative '../lib/llm_chain'
|
|
|
5
5
|
puts "𦾠LLMChain v#{LlmChain::VERSION} - Quick Demo"
|
|
6
6
|
puts "=" * 50
|
|
7
7
|
|
|
8
|
-
# 1. Simple chain without tools
|
|
9
8
|
puts "\n1. š¬ Simple conversation"
|
|
10
9
|
begin
|
|
11
10
|
simple_chain = LLMChain::Chain.new(
|
|
@@ -20,19 +19,16 @@ rescue => e
|
|
|
20
19
|
puts "š” Make sure Ollama is running and qwen3:1.7b model is downloaded"
|
|
21
20
|
end
|
|
22
21
|
|
|
23
|
-
# 2. Calculator
|
|
24
22
|
puts "\n2. š§® Built-in calculator"
|
|
25
23
|
calculator = LLMChain::Tools::Calculator.new
|
|
26
24
|
result = calculator.call("Calculate 25 * 8 + 15")
|
|
27
25
|
puts "š #{result[:formatted]}"
|
|
28
26
|
|
|
29
|
-
# 3. Code interpreter
|
|
30
27
|
puts "\n3. š» Code interpreter"
|
|
31
28
|
begin
|
|
32
29
|
interpreter = LLMChain::Tools::CodeInterpreter.new
|
|
33
30
|
ruby_code = <<~RUBY_CODE
|
|
34
31
|
```ruby
|
|
35
|
-
# Simple program
|
|
36
32
|
data = [1, 2, 3, 4, 5]
|
|
37
33
|
total = data.sum
|
|
38
34
|
puts "Sum of numbers: \#{total}"
|
|
@@ -54,7 +50,6 @@ rescue => e
|
|
|
54
50
|
puts "ā Interpreter error: #{e.message}"
|
|
55
51
|
end
|
|
56
52
|
|
|
57
|
-
# 4. Web search (may not work without internet)
|
|
58
53
|
puts "\n4. š Web search"
|
|
59
54
|
search = LLMChain::Tools::WebSearch.new
|
|
60
55
|
search_result = search.call("Ruby programming language")
|
|
@@ -68,10 +63,9 @@ else
|
|
|
68
63
|
puts "ā Search failed or no results found"
|
|
69
64
|
end
|
|
70
65
|
|
|
71
|
-
# 5. Chain with tools
|
|
72
66
|
puts "\n5. š ļø Chain with automatic tools"
|
|
73
67
|
begin
|
|
74
|
-
tool_manager = LLMChain::Tools::
|
|
68
|
+
tool_manager = LLMChain::Tools::ToolManagerFactory.create_default_toolset
|
|
75
69
|
smart_chain = LLMChain::Chain.new(
|
|
76
70
|
model: "qwen3:1.7b",
|
|
77
71
|
tools: tool_manager,
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require_relative '../lib/llm_chain'
|
|
4
|
+
|
|
5
|
+
puts "š¤ LLMChain ReAct Agent Example"
|
|
6
|
+
puts "=" * 50
|
|
7
|
+
|
|
8
|
+
agent = LLMChain::Agents::AgentFactory.create(
|
|
9
|
+
type: :react,
|
|
10
|
+
model: "deepseek-coder-v2:16b",
|
|
11
|
+
max_iterations: 10
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
puts "Agent created: #{agent.description}"
|
|
15
|
+
puts "Available tools: #{agent.tools.list_tools.map(&:name).join(', ')}"
|
|
16
|
+
puts
|
|
17
|
+
|
|
18
|
+
task = "Calculate 15 * 7 + 32"
|
|
19
|
+
puts "šÆ Task: #{task}"
|
|
20
|
+
puts "Processing..."
|
|
21
|
+
|
|
22
|
+
result = agent.run(task, stream: true) do |step|
|
|
23
|
+
puts " Step #{step[:iteration]}: #{step[:thought]}"
|
|
24
|
+
if step[:action]
|
|
25
|
+
puts " Action: #{step[:action]} (#{step[:action_input]})"
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
puts
|
|
30
|
+
puts "ā
Final Answer: #{result[:final_answer]}"
|
|
31
|
+
puts "š Iterations: #{result[:iterations]}"
|
|
32
|
+
puts "šÆ Success: #{result[:success]}"
|
|
33
|
+
puts
|
|
34
|
+
|
|
35
|
+
task2 = "Who is the president of the United States? and who was the president before him?"
|
|
36
|
+
puts "šÆ Complex Task: #{task2}"
|
|
37
|
+
puts "Processing..."
|
|
38
|
+
|
|
39
|
+
result2 = agent.run(task2, stream: true) do |step|
|
|
40
|
+
puts " Step #{step[:iteration]}: #{step[:thought][0..100]}..."
|
|
41
|
+
if step[:action]
|
|
42
|
+
puts " Action: #{step[:action]} (#{step[:action_input]})"
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
puts
|
|
47
|
+
puts "ā
Final Answer: #{result2[:final_answer]}"
|
|
48
|
+
puts "š Iterations: #{result2[:iterations]}"
|
|
49
|
+
puts "šÆ Success: #{result2[:success]}"
|
|
50
|
+
|
|
51
|
+
task3 = "Which tools are available to me?"
|
|
52
|
+
puts "šÆ Task: #{task3}"
|
|
53
|
+
puts "Processing..."
|
|
54
|
+
|
|
55
|
+
result3 = agent.run(task3, stream: true) do |step|
|
|
56
|
+
puts " Step #{step[:iteration]}: #{step[:thought]}"
|
|
57
|
+
if step[:action]
|
|
58
|
+
puts " Action: #{step[:action]} (#{step[:action_input]})"
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
puts "ā
Final Answer: #{result3[:final_answer]}"
|
|
63
|
+
puts "š Iterations: #{result3[:iterations]}"
|
|
64
|
+
puts "šÆ Success: #{result3[:success]}"
|