luo 0.2.4 → 0.2.5
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/Gemfile.lock +1 -1
- data/lib/luo/agent_runner_base.rb +25 -2
- data/lib/luo/agent_runner_context.rb +2 -2
- data/lib/luo/llm_func/cain.rb +30 -0
- data/lib/luo/llm_func/cain_builder.rb +65 -0
- data/lib/luo/llm_func.rb +12 -0
- data/lib/luo/memory_history.rb +24 -3
- data/lib/luo/messages.rb +6 -2
- data/lib/luo/middleware/base.rb +61 -0
- data/lib/luo/middleware/env.rb +56 -0
- data/lib/luo/middleware/logger.rb +19 -0
- data/lib/luo/middleware/memory_history.rb +28 -0
- data/lib/luo/middleware.rb +6 -0
- data/lib/luo/open_ai.rb +10 -0
- data/lib/luo/open_ai_agent_runner.rb +7 -11
- data/lib/luo/version.rb +1 -1
- data/lib/luo/xinghuo.rb +9 -0
- data/lib/luo/xinghuo_agent_runner.rb +10 -14
- data/lib/luo.rb +3 -0
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4078773adb559f48cefc4e2bf43e64c0476bd4eb6f4e9ccfa215558c93c2d346
|
4
|
+
data.tar.gz: 4732dba7c93e21066cc828bc8042617ad29c93a6b50c799c518b8d96332cd640
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 521b30ee3642e76b70ff2ddd6d906b0394e7ad3ecee9ff4e69eb4155482c385947ab3051aafd1c38083c9e7e8aca90ca28b1edf8144d662ef76c8e9659be70a3
|
7
|
+
data.tar.gz: 325450266621354fcda412c1b40c4df88079c2eb985690e43f1b6fae4d7f87a5bf6de7a04ea077c5426a61e5e76c9d93df3908aa560189135228218382e9619e
|
data/Gemfile.lock
CHANGED
@@ -6,6 +6,8 @@ module Luo
|
|
6
6
|
include Configurable
|
7
7
|
|
8
8
|
setting :language, default: "en"
|
9
|
+
setting :client, default: nil
|
10
|
+
setting :context_adapter, default: -> { Luo::AgentRunnerContext.new }
|
9
11
|
|
10
12
|
def initialize(histories: nil)
|
11
13
|
context.histories = histories unless histories.nil?
|
@@ -15,13 +17,18 @@ module Luo
|
|
15
17
|
def on_init
|
16
18
|
end
|
17
19
|
|
20
|
+
def client
|
21
|
+
raise Luo::ClientNotSetError, "client not set" if self.class.config.client.nil?
|
22
|
+
self.class.config.client
|
23
|
+
end
|
24
|
+
|
18
25
|
def context
|
19
|
-
@context ||=
|
26
|
+
@context ||= config.context_adapter.call
|
20
27
|
end
|
21
28
|
|
22
29
|
def reset_context
|
23
30
|
histories = context.histories
|
24
|
-
@context =
|
31
|
+
@context = config.context_adapter.call
|
25
32
|
@context.histories = histories
|
26
33
|
@context
|
27
34
|
end
|
@@ -59,6 +66,16 @@ module Luo
|
|
59
66
|
context.have_running_agents << agent
|
60
67
|
end
|
61
68
|
|
69
|
+
def save_history
|
70
|
+
context.histories.save(context.user_input, context.final_result) if save_history?
|
71
|
+
end
|
72
|
+
|
73
|
+
# @private
|
74
|
+
private
|
75
|
+
def save_history?
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
62
79
|
class << self
|
63
80
|
|
64
81
|
def agents
|
@@ -85,6 +102,12 @@ module Luo
|
|
85
102
|
end
|
86
103
|
end
|
87
104
|
|
105
|
+
def disable_history
|
106
|
+
define_method(:save_history?) do
|
107
|
+
false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
88
111
|
end
|
89
112
|
end
|
90
113
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Luo
|
4
4
|
class AgentRunnerContext
|
5
5
|
include Configurable
|
6
|
-
setting :history_adapter, default: MemoryHistory
|
6
|
+
setting :history_adapter, default: ->(context) { MemoryHistory.new(context) }
|
7
7
|
|
8
8
|
attr_accessor :user_input, :action_input, :response, :agent_results, :final_result, :messages, :retries
|
9
9
|
|
@@ -13,7 +13,7 @@ module Luo
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def histories
|
16
|
-
@histories ||= config.history_adapter.
|
16
|
+
@histories ||= config.history_adapter.call(self)
|
17
17
|
end
|
18
18
|
|
19
19
|
def histories=(histories)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Luo
|
4
|
+
module LLMFunc
|
5
|
+
class Cain
|
6
|
+
include Dry::Configurable
|
7
|
+
|
8
|
+
setting :system, default: nil
|
9
|
+
setting :prompt
|
10
|
+
setting :adapter, default: Luo::OpenAI.llm_func_adapter
|
11
|
+
setting :temperature, default: 0
|
12
|
+
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
temperature = env.fetch(:temperature, nil)
|
16
|
+
history = env.fetch(:history, nil)
|
17
|
+
messages = Messages.create(history: history).user(prompt: config.prompt, context: env.to_h)
|
18
|
+
|
19
|
+
if config.system
|
20
|
+
messages = messages.system(text: config.system)
|
21
|
+
end
|
22
|
+
|
23
|
+
output = config.adapter.call(messages, temperature || config.temperature)
|
24
|
+
env.set(:output, output)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Luo
|
4
|
+
module LLMFunc
|
5
|
+
class CainBuilder
|
6
|
+
def initialize
|
7
|
+
@system = nil
|
8
|
+
@prompt = nil
|
9
|
+
@adapter = Luo::OpenAI.llm_func_adapter
|
10
|
+
@temperature = 0
|
11
|
+
|
12
|
+
@middlewares = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def system(text=nil)
|
16
|
+
@system = text
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def prompt(prompt=nil)
|
21
|
+
@prompt = prompt
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def adapter(adapter=nil)
|
26
|
+
@adapter = adapter
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def temperature(temperature=nil)
|
31
|
+
@temperature = temperature
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def use(middleware)
|
36
|
+
@middlewares << middleware
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def build
|
41
|
+
cain = Cain.new.configure do |c|
|
42
|
+
c.system = @system
|
43
|
+
c.prompt = @prompt
|
44
|
+
c.adapter = @adapter
|
45
|
+
c.temperature = @temperature
|
46
|
+
end
|
47
|
+
|
48
|
+
_next_ = cain
|
49
|
+
@middlewares.reverse_each do |middleware|
|
50
|
+
_next_ = middleware.new(_next_)
|
51
|
+
end
|
52
|
+
|
53
|
+
Proc.new do |**input|
|
54
|
+
env = Luo::Middleware::Env.new(**input)
|
55
|
+
_next_.call(env)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def call(**input)
|
60
|
+
build.call(**input)
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/lib/luo/llm_func.rb
ADDED
data/lib/luo/memory_history.rb
CHANGED
@@ -7,12 +7,14 @@ module Luo
|
|
7
7
|
class MemoryHistory
|
8
8
|
include Configurable
|
9
9
|
|
10
|
-
setting :max_size, default:
|
10
|
+
setting :max_size, default: 6
|
11
11
|
|
12
|
+
attr_reader :context
|
12
13
|
##
|
13
14
|
# 初始化一个队列
|
14
15
|
# @param [Integer] max_size 队列的最大长度
|
15
|
-
def initialize(
|
16
|
+
def initialize(context = nil, max_size: config.max_size)
|
17
|
+
@context = context
|
16
18
|
@queue = []
|
17
19
|
@max_size = max_size
|
18
20
|
end
|
@@ -30,6 +32,15 @@ module Luo
|
|
30
32
|
Marshal.load(Marshal.dump(self))
|
31
33
|
end
|
32
34
|
|
35
|
+
def save(input, output)
|
36
|
+
@context_model ||= true
|
37
|
+
enqueue({input: input, output: output})
|
38
|
+
end
|
39
|
+
|
40
|
+
def context_model
|
41
|
+
@context_model
|
42
|
+
end
|
43
|
+
|
33
44
|
def user(content)
|
34
45
|
enqueue({role: "user", content: content})
|
35
46
|
end
|
@@ -49,7 +60,17 @@ module Luo
|
|
49
60
|
end
|
50
61
|
|
51
62
|
def to_a
|
52
|
-
@queue
|
63
|
+
return @queue unless context_model
|
64
|
+
|
65
|
+
@queue.reduce([]) do |rt, node|
|
66
|
+
rt << {role: "user", content: node[:input]}
|
67
|
+
rt << {role: "assistant", content: node[:output]}
|
68
|
+
rt
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def search(_input)
|
73
|
+
to_a
|
53
74
|
end
|
54
75
|
|
55
76
|
def to_json
|
data/lib/luo/messages.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Luo
|
4
|
+
module Middleware
|
5
|
+
class Base
|
6
|
+
extend Dry::Configurable
|
7
|
+
def initialize(app)
|
8
|
+
raise ArgumentError, "app must respond to `call`" unless app.respond_to? :call
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
env = Env.validate_env!(env)
|
14
|
+
env = Env.validate_env! _before_call_(env)
|
15
|
+
env = Env.validate_env! _call_(env)
|
16
|
+
env = Env.validate_env! @app.call(env)
|
17
|
+
Env.validate_env! _after_call_(env)
|
18
|
+
end
|
19
|
+
|
20
|
+
def _before_call_(env)
|
21
|
+
env
|
22
|
+
end
|
23
|
+
|
24
|
+
def _after_call_(env)
|
25
|
+
env
|
26
|
+
end
|
27
|
+
|
28
|
+
def _call_(env)
|
29
|
+
env
|
30
|
+
end
|
31
|
+
|
32
|
+
class << self
|
33
|
+
|
34
|
+
def create_method(name, &block)
|
35
|
+
define_method name do |env|
|
36
|
+
_env_ = block.call(env)
|
37
|
+
if _env_.is_a? Env
|
38
|
+
_env_
|
39
|
+
else
|
40
|
+
env
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def before(&block)
|
46
|
+
create_method :_before_call_, &block
|
47
|
+
end
|
48
|
+
|
49
|
+
def after(&block)
|
50
|
+
create_method :_after_call_, &block
|
51
|
+
end
|
52
|
+
|
53
|
+
def call(&block)
|
54
|
+
create_method :_call_, &block
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Luo
|
4
|
+
module Middleware
|
5
|
+
class Env
|
6
|
+
attr_accessor :meta
|
7
|
+
def initialize(**meta)
|
8
|
+
@meta = meta
|
9
|
+
end
|
10
|
+
|
11
|
+
def set(key, value)
|
12
|
+
@meta[key] = value
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def get(key)
|
17
|
+
@meta[key]
|
18
|
+
end
|
19
|
+
|
20
|
+
def input
|
21
|
+
@meta[:input]
|
22
|
+
end
|
23
|
+
|
24
|
+
def output
|
25
|
+
@meta[:output]
|
26
|
+
end
|
27
|
+
|
28
|
+
def fetch(key, default=nil)
|
29
|
+
@meta.fetch(key, default)
|
30
|
+
end
|
31
|
+
|
32
|
+
def fetch_and_delete!(key, default=nil)
|
33
|
+
@meta.fetch(key, default).tap do
|
34
|
+
@meta.delete(key)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
@meta.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_h
|
43
|
+
@meta
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_method(name, &block)
|
47
|
+
self.class.send(:define_method, name, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.validate_env!(env)
|
51
|
+
raise ArgumentError, "env must be a Luo::Middleware::Env" unless env.is_a? Luo::Middleware::Env
|
52
|
+
env
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Luo
|
3
|
+
module Middleware
|
4
|
+
class Logger < Base
|
5
|
+
|
6
|
+
setting :level, default: ::Logger::INFO
|
7
|
+
setting :logger, default: ::Logger.new(STDOUT)
|
8
|
+
|
9
|
+
call do |env|
|
10
|
+
logger = config.logger
|
11
|
+
logger.level = config.level
|
12
|
+
env.create_method(:logger) do
|
13
|
+
logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Luo
|
4
|
+
module Middleware
|
5
|
+
module MemoryHistory
|
6
|
+
extend self
|
7
|
+
|
8
|
+
def create(history)
|
9
|
+
Class.new(Base) do
|
10
|
+
@history = history
|
11
|
+
def initialize(app)
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
before do |env|
|
16
|
+
env.set(:history, @history)
|
17
|
+
end
|
18
|
+
|
19
|
+
after do |env|
|
20
|
+
@history.user env.fetch(:input)
|
21
|
+
@history.assistant env.fetch(:output)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/luo/open_ai.rb
CHANGED
@@ -62,6 +62,16 @@ module Luo
|
|
62
62
|
chat_completions(params).body.dig("choices", 0, "message", "content")
|
63
63
|
end
|
64
64
|
|
65
|
+
class << self
|
66
|
+
def llm_func_adapter
|
67
|
+
client = self.new
|
68
|
+
Proc.new do |messages, temperature|
|
69
|
+
client.chat(messages, temperature: temperature)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
|
65
75
|
end
|
66
76
|
|
67
77
|
end
|
@@ -12,19 +12,15 @@ module Luo
|
|
12
12
|
setting :tool_input, default: Luo::Prompts.agent_tool_input
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
@openai = OpenAI.new
|
17
|
-
end
|
15
|
+
setting :client, default: Luo::OpenAI.new
|
18
16
|
|
19
17
|
on_request do
|
20
|
-
context.messages = Messages.create(history: context.histories)
|
18
|
+
context.messages = Messages.create(history: context.histories.search(context.user_input))
|
21
19
|
.system(prompt: config.prompts.system)
|
22
20
|
.user(prompt: config.prompts.input, context: {agents: self.class.agents, last_user_input: context.user_input})
|
23
|
-
context.response =
|
21
|
+
context.response = client.chat(context.messages)
|
24
22
|
end
|
25
23
|
|
26
|
-
##
|
27
|
-
# TODO: 用markdown解析库来解析response
|
28
24
|
on_result do
|
29
25
|
begin
|
30
26
|
actions = JSON.parse(context.response)
|
@@ -36,13 +32,13 @@ module Luo
|
|
36
32
|
agent = self.class.agents[action['action']]&.new(
|
37
33
|
context: context,
|
38
34
|
action_input: action['action_input'],
|
39
|
-
client:
|
35
|
+
client: client
|
40
36
|
)
|
41
37
|
add_agent(agent) if agent
|
42
38
|
if action['action'] == "Final Answer"
|
43
39
|
context.final_result = action['action_input']
|
44
|
-
|
45
|
-
|
40
|
+
|
41
|
+
save_history
|
46
42
|
end
|
47
43
|
end
|
48
44
|
end
|
@@ -55,7 +51,7 @@ module Luo
|
|
55
51
|
tools_response: context.agent_results
|
56
52
|
}
|
57
53
|
)
|
58
|
-
context.response =
|
54
|
+
context.response = client.chat(context.messages)
|
59
55
|
context.retries += 1
|
60
56
|
on_result
|
61
57
|
on_run
|
data/lib/luo/version.rb
CHANGED
data/lib/luo/xinghuo.rb
CHANGED
@@ -47,5 +47,14 @@ module Luo
|
|
47
47
|
request_chat(params).body.dig('choices', 0, 'message', 'content')
|
48
48
|
end
|
49
49
|
|
50
|
+
class << self
|
51
|
+
def llm_func_adapter
|
52
|
+
client = self.new
|
53
|
+
Proc.new do |messages, temperature|
|
54
|
+
client.chat(messages, random_threshold: temperature)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
50
59
|
end
|
51
60
|
end
|
@@ -9,21 +9,18 @@ module Luo
|
|
9
9
|
setting :input, default: Luo::Prompts.xinghuo_agent_input
|
10
10
|
setting :response_error, default: Luo::Prompts.xinghuo_response_error
|
11
11
|
end
|
12
|
-
|
13
|
-
on_init do
|
14
|
-
@xinghuo = Xinghuo.new
|
15
|
-
end
|
12
|
+
setting :client, default: Luo::Xinghuo.new
|
16
13
|
|
17
14
|
on_request do
|
18
|
-
context.messages = Messages.create(history: context.histories)
|
15
|
+
context.messages = Messages.create(history: context.histories.search(context.user_input))
|
19
16
|
.user(prompt: config.prompts.input, context: {agents: self.class.agents, last_user_input: context.user_input})
|
20
|
-
response =
|
17
|
+
response = client.chat(context.messages)
|
21
18
|
if response.split("\n").select { |line| line.size >1 }.size > 1
|
22
|
-
message = Messages.create(history: context.histories)
|
19
|
+
message = Messages.create(history: context.histories.search(context.user_input))
|
23
20
|
.user(prompt: config.prompts.input, context: {agents: self.class.agents, last_user_input: context.user_input})
|
24
21
|
.assistant(text: response)
|
25
22
|
.user(prompt: config.prompts.response_error, context: {agents: self.class.agents, last_user_input: context.user_input})
|
26
|
-
context.response =
|
23
|
+
context.response = client.chat(message)
|
27
24
|
else
|
28
25
|
context.response = response
|
29
26
|
end
|
@@ -35,12 +32,12 @@ module Luo
|
|
35
32
|
agent = self.class.agents[agent_name]&.new(
|
36
33
|
context: context,
|
37
34
|
action_input: context.user_input,
|
38
|
-
client:
|
35
|
+
client: client
|
39
36
|
)
|
40
37
|
add_agent(agent)
|
41
38
|
else
|
42
|
-
messages = Messages.create(history: context.histories).user(text: context.user_input)
|
43
|
-
context.final_result =
|
39
|
+
messages = Messages.create(history: context.histories.search(context.user_input)).user(text: context.user_input)
|
40
|
+
context.final_result = client.chat(messages)
|
44
41
|
end
|
45
42
|
end
|
46
43
|
|
@@ -50,8 +47,7 @@ module Luo
|
|
50
47
|
context.final_result = answer if answer
|
51
48
|
end
|
52
49
|
|
53
|
-
|
54
|
-
context.histories.assistant(context.final_result)
|
50
|
+
save_history
|
55
51
|
end
|
56
52
|
end
|
57
53
|
|
@@ -60,7 +56,7 @@ module Luo
|
|
60
56
|
agent_desc '你可以问我任何问题,我都会尽力回答你'
|
61
57
|
|
62
58
|
on_call_with_final_result do
|
63
|
-
messages = Messages.create(history: context.histories).user(text: context.user_input)
|
59
|
+
messages = Messages.create(history: context.histories.search(context.user_input)).user(text: context.user_input)
|
64
60
|
client.chat(messages)
|
65
61
|
end
|
66
62
|
|
data/lib/luo.rb
CHANGED
@@ -16,6 +16,7 @@ require 'dry-initializer'
|
|
16
16
|
require 'uri'
|
17
17
|
require 'redcarpet'
|
18
18
|
require 'thor'
|
19
|
+
require 'logger'
|
19
20
|
|
20
21
|
require "zeitwerk"
|
21
22
|
loader = Zeitwerk::Loader.for_gem
|
@@ -23,10 +24,12 @@ loader.inflector.inflect("open_ai" => "OpenAI")
|
|
23
24
|
loader.inflector.inflect("aiui" => "AIUI")
|
24
25
|
loader.inflector.inflect("cli" => "CLI")
|
25
26
|
loader.inflector.inflect("open_ai_agent_runner" => "OpenAIAgentRunner")
|
27
|
+
loader.inflector.inflect('llm_func' => 'LLMFunc')
|
26
28
|
loader.setup
|
27
29
|
|
28
30
|
module Luo
|
29
31
|
class Error < StandardError; end
|
32
|
+
class ClientNotSetError < StandardError; end
|
30
33
|
# Your code goes here...
|
31
34
|
|
32
35
|
module_eval do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: luo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- MJ
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|
@@ -236,10 +236,18 @@ files:
|
|
236
236
|
- lib/luo/error_handle.rb
|
237
237
|
- lib/luo/helpers.rb
|
238
238
|
- lib/luo/http_client.rb
|
239
|
+
- lib/luo/llm_func.rb
|
240
|
+
- lib/luo/llm_func/cain.rb
|
241
|
+
- lib/luo/llm_func/cain_builder.rb
|
239
242
|
- lib/luo/loader.rb
|
240
243
|
- lib/luo/marqo.rb
|
241
244
|
- lib/luo/memory_history.rb
|
242
245
|
- lib/luo/messages.rb
|
246
|
+
- lib/luo/middleware.rb
|
247
|
+
- lib/luo/middleware/base.rb
|
248
|
+
- lib/luo/middleware/env.rb
|
249
|
+
- lib/luo/middleware/logger.rb
|
250
|
+
- lib/luo/middleware/memory_history.rb
|
243
251
|
- lib/luo/open_ai.rb
|
244
252
|
- lib/luo/open_ai_agent_runner.rb
|
245
253
|
- lib/luo/parser_markdown.rb
|