autoflux 0.2.0 → 0.3.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/README.md +64 -34
- data/lib/autoflux/memory.rb +3 -3
- data/lib/autoflux/stdio.rb +3 -5
- data/lib/autoflux/step/assistant.rb +10 -6
- data/lib/autoflux/step/command.rb +7 -2
- data/lib/autoflux/step/start.rb +2 -1
- data/lib/autoflux/step/stop.rb +2 -1
- data/lib/autoflux/step/tool.rb +18 -11
- data/lib/autoflux/step.rb +0 -1
- data/lib/autoflux/version.rb +1 -1
- data/lib/autoflux/workflow.rb +21 -4
- data/lib/autoflux.rb +5 -3
- data/sig/autoflux/agent.rbs +1 -9
- data/sig/autoflux/event.rbs +27 -0
- data/sig/autoflux/io.rbs +2 -7
- data/sig/autoflux/memory.rbs +5 -5
- data/sig/autoflux/stdio.rbs +7 -14
- data/sig/autoflux/step.rbs +12 -12
- data/sig/autoflux/tool.rbs +1 -16
- data/sig/autoflux/workflow.rbs +4 -17
- data/sig/autoflux.rbs +5 -0
- metadata +3 -6
- data/lib/autoflux/agent.rb +0 -26
- data/lib/autoflux/io.rb +0 -15
- data/lib/autoflux/step/base.rb +0 -17
- data/lib/autoflux/tool.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bfba17b715db371a3388379b0d894f1cd7e02e5ddec7dc9e30545b009037195e
|
4
|
+
data.tar.gz: 768d96e08f58eac4516c03b6fb1ae13a6c4939ffa47702fa57de3c45cff8a831
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe2ee26a057d023a378eee32fead552d45312724a1a59b4dcf1a6681cef889ffda78030fcafac5b98ee41ae2c4a4d3b24d859fa1682aac86595ed82e58759226
|
7
|
+
data.tar.gz: dd3461bdffb1f07be326962f43b3ee661e901881eaea3a71c0225bb55047c559e13a5e62743e4426751a36af3447fdcf4084cddd238f155ce4529060f619802a
|
data/README.md
CHANGED
@@ -57,82 +57,110 @@ When receive "exit" from the user, the workflow transition to the stop state.
|
|
57
57
|
|
58
58
|
### Agent
|
59
59
|
|
60
|
-
The agent is an adapter to the LLM model.
|
60
|
+
The agent is an adapter to the LLM model.
|
61
61
|
|
62
62
|
```ruby
|
63
63
|
# :nodoc:
|
64
|
-
class OpenAIAgent
|
64
|
+
class OpenAIAgent
|
65
65
|
attr_reader :client, :model
|
66
66
|
|
67
|
-
def initialize(client:,
|
67
|
+
def initialize(client:, model: 'gpt-4o-mini')
|
68
68
|
super(tools: tools)
|
69
69
|
@client = client
|
70
70
|
@model = model
|
71
71
|
end
|
72
72
|
|
73
73
|
def call(memory:)
|
74
|
-
client.chat(
|
74
|
+
msg = client.chat(
|
75
75
|
parameters: {
|
76
76
|
model: model,
|
77
|
-
messages: memory.data,
|
78
|
-
tools: tools
|
77
|
+
messages: memory.data.map { |event| convert_message(event) },
|
79
78
|
}
|
80
79
|
).dig('choices', 0, 'message')
|
80
|
+
|
81
|
+
convert_event(msg)
|
81
82
|
end
|
82
83
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
84
|
+
# If allow to use the tool, return tool object implements `Autoflux::_Tool` interface
|
85
|
+
def tools?(name) = false
|
86
|
+
def tool(name) = nil
|
87
|
+
|
88
|
+
# Autoflux use a generic event object to represent the message, you have to convert it to the model's format
|
89
|
+
def convert_message(event)
|
90
|
+
{
|
91
|
+
role: event[:role],
|
92
|
+
content: event[:content]
|
93
|
+
}.tap do |evt|
|
94
|
+
evt[:tool_calls] = event[:invocations]&.map { |invocation| convert_tool_call(invocation) }
|
95
|
+
evt[:tool_call_id] = event[:invocation_id] if event[:invocation_id]
|
93
96
|
end
|
94
97
|
end
|
98
|
+
|
99
|
+
def convert_tool_call(invocation)
|
100
|
+
{
|
101
|
+
type: :function,
|
102
|
+
id: invocation[:id],
|
103
|
+
function: {
|
104
|
+
name: invocation[:name],
|
105
|
+
arguments: invocation[:args]
|
106
|
+
}
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def convert_event(msg) # rubocop:disable Metrics/MethodLength
|
111
|
+
{
|
112
|
+
role: msg['role'],
|
113
|
+
content: msg['content'],
|
114
|
+
invocations: msg['tool_calls']&.map do |call|
|
115
|
+
{
|
116
|
+
id: call['id'],
|
117
|
+
name: call.dig('function', 'name'),
|
118
|
+
args: call.dig('function', 'arguments')
|
119
|
+
}
|
120
|
+
end
|
121
|
+
}
|
122
|
+
end
|
95
123
|
end
|
96
124
|
```
|
97
125
|
|
98
|
-
The memory is
|
126
|
+
The memory is history which keep in the workflow. You can decide to use it or not.
|
99
127
|
|
100
128
|
### Tool
|
101
129
|
|
102
|
-
The tool is a function that can be used in the agent's response.
|
130
|
+
The tool is a function that can be used in the agent's response.
|
103
131
|
|
104
132
|
```ruby
|
105
133
|
# :nodoc:
|
106
|
-
class AddToCartTool
|
134
|
+
class AddToCartTool
|
135
|
+
attr_reader :name, :description, :parameters
|
136
|
+
|
107
137
|
def initialize # rubocop:disable Metrics/MethodLength
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
quantity: { type: 'number', description: 'The quantity of the product' }
|
116
|
-
}
|
138
|
+
@name = 'add_to_cart'
|
139
|
+
@description = 'Add the product to the cart'
|
140
|
+
@parameters = {
|
141
|
+
type: 'object',
|
142
|
+
properties: {
|
143
|
+
name: { type: 'string', description: 'The name of the product' },
|
144
|
+
quantity: { type: 'number', description: 'The quantity of the product' }
|
117
145
|
}
|
118
|
-
|
146
|
+
}
|
119
147
|
end
|
120
148
|
|
121
|
-
def call(
|
122
|
-
{ success: true, content: "Added #{quantity} #{name} to the cart" }
|
149
|
+
def call(workflow:, params:)
|
150
|
+
{ success: true, content: "Added #{params[:quantity]} #{params[:name]} to the cart" }
|
123
151
|
end
|
124
152
|
end
|
125
153
|
```
|
126
154
|
|
127
|
-
|
155
|
+
> You can define how to tell the agent to use the tool by adding `name` and `description` to the tool.
|
128
156
|
|
129
157
|
### IO
|
130
158
|
|
131
|
-
The IO is an adapter to the input and output.
|
159
|
+
The IO is an adapter to the input and output.
|
132
160
|
|
133
161
|
```ruby
|
134
162
|
# :nodoc:
|
135
|
-
class ConsoleIO
|
163
|
+
class ConsoleIO
|
136
164
|
def read
|
137
165
|
print 'User: '
|
138
166
|
gets.chomp
|
@@ -147,6 +175,8 @@ end
|
|
147
175
|
The default `Autoflux::Stdio` implement the minimal Standard I/O support.
|
148
176
|
|
149
177
|
```ruby
|
178
|
+
require 'autoflux/stdio'
|
179
|
+
|
150
180
|
workflow = Autoflux::Workflow.new(
|
151
181
|
agent: agent,
|
152
182
|
io: Autoflux::Stdio.new(prompt: '> ')
|
data/lib/autoflux/memory.rb
CHANGED
@@ -15,9 +15,9 @@ module Autoflux
|
|
15
15
|
# Push the data to the memory.
|
16
16
|
#
|
17
17
|
# @rbs data: Hash
|
18
|
-
def push(
|
19
|
-
puts JSON.pretty_generate(
|
20
|
-
@data.push(
|
18
|
+
def push(event)
|
19
|
+
puts JSON.pretty_generate(event) if verbose
|
20
|
+
@data.push(event)
|
21
21
|
end
|
22
22
|
|
23
23
|
# Get the last data from the memory.
|
data/lib/autoflux/stdio.rb
CHANGED
@@ -2,14 +2,12 @@
|
|
2
2
|
|
3
3
|
module Autoflux
|
4
4
|
# The Stdio is a class to represent the standard input/output.
|
5
|
-
class Stdio
|
5
|
+
class Stdio
|
6
6
|
attr_accessor :prompt
|
7
7
|
|
8
8
|
# @rbs input: IO
|
9
9
|
# @rbs output: IO
|
10
10
|
def initialize(input: $stdin, output: $stdout, prompt: nil)
|
11
|
-
super()
|
12
|
-
|
13
11
|
@input = input
|
14
12
|
@output = output
|
15
13
|
@prompt = prompt
|
@@ -18,12 +16,12 @@ module Autoflux
|
|
18
16
|
|
19
17
|
def read
|
20
18
|
print prompt if prompt
|
21
|
-
@input.gets
|
19
|
+
@input.gets&.chomp
|
22
20
|
end
|
23
21
|
|
24
22
|
# @rbs data: String
|
25
23
|
def write(data)
|
26
|
-
@output.puts(data)
|
24
|
+
@output.puts(data) if data
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -3,15 +3,19 @@
|
|
3
3
|
module Autoflux
|
4
4
|
module Step
|
5
5
|
# The Assistant state is used to call the agent.
|
6
|
-
class Assistant
|
7
|
-
|
6
|
+
class Assistant
|
7
|
+
def to_s = self.class.name || "Assistant"
|
8
8
|
|
9
9
|
def call(workflow:)
|
10
|
-
|
11
|
-
workflow.memory.push(
|
12
|
-
return Tool.new if res["tool_calls"]&.any?
|
10
|
+
event = workflow.agent.call(memory: workflow.memory)
|
11
|
+
workflow.memory.push(event)
|
13
12
|
|
14
|
-
|
13
|
+
# @type var invocation_event: Autoflux::invocationEvent
|
14
|
+
invocation_event = event
|
15
|
+
return Tool.new if invocation_event[:invocations]&.any?
|
16
|
+
|
17
|
+
# @type var event: Autoflux::textEvent
|
18
|
+
workflow.io.write(event[:content]) if event[:role] == ROLE_ASSISTANT
|
15
19
|
|
16
20
|
Command.new
|
17
21
|
end
|
@@ -3,14 +3,19 @@
|
|
3
3
|
module Autoflux
|
4
4
|
module Step
|
5
5
|
# The Command step is used to get the user input.
|
6
|
-
class Command
|
6
|
+
class Command
|
7
7
|
EXIT_COMMAND = "exit"
|
8
8
|
|
9
|
+
def to_s = self.class.name || "Command"
|
10
|
+
|
9
11
|
def call(workflow:)
|
10
12
|
input = workflow.io.read
|
13
|
+
return Stop.new if input.nil?
|
11
14
|
return Stop.new if input == EXIT_COMMAND
|
12
15
|
|
13
|
-
|
16
|
+
# @type var event: Autoflux::event
|
17
|
+
event = { role: ROLE_USER, content: input }
|
18
|
+
workflow.memory.push(event)
|
14
19
|
Assistant.new
|
15
20
|
end
|
16
21
|
end
|
data/lib/autoflux/step/start.rb
CHANGED
data/lib/autoflux/step/stop.rb
CHANGED
data/lib/autoflux/step/tool.rb
CHANGED
@@ -3,14 +3,21 @@
|
|
3
3
|
module Autoflux
|
4
4
|
module Step
|
5
5
|
# The Tool state is used to call the tools provided by the agent.
|
6
|
-
class Tool
|
6
|
+
class Tool
|
7
|
+
def to_s = self.class.name || "Tool"
|
8
|
+
|
7
9
|
def call(workflow:)
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
# @type var event: Autoflux::invocationEvent
|
11
|
+
event = workflow.memory.last
|
12
|
+
event[:invocations]&.each do |invocation|
|
13
|
+
# @type: var invocation: Autoflux::invocation
|
14
|
+
# @type: var event: Autoflux::invocationResultEvent
|
15
|
+
event = {
|
16
|
+
role: ROLE_TOOL,
|
17
|
+
content: run(workflow: workflow, invocation: invocation).to_json,
|
18
|
+
invocation_id: invocation[:id]
|
19
|
+
}
|
20
|
+
workflow.memory.push(event)
|
14
21
|
end
|
15
22
|
|
16
23
|
Assistant.new
|
@@ -18,12 +25,12 @@ module Autoflux
|
|
18
25
|
|
19
26
|
protected
|
20
27
|
|
21
|
-
def run(workflow:,
|
22
|
-
name =
|
23
|
-
params = JSON.parse(
|
28
|
+
def run(workflow:, invocation:)
|
29
|
+
name = invocation[:name]
|
30
|
+
params = JSON.parse(invocation[:args], symbolize_names: true)
|
24
31
|
return { status: "error", message: "Tool not found" } unless workflow.agent.tool?(name)
|
25
32
|
|
26
|
-
workflow.agent.tool(name)
|
33
|
+
workflow.agent.tool(name)&.call(workflow: workflow, params: params)
|
27
34
|
rescue JSON::ParserError
|
28
35
|
{ status: "error", message: "Invalid arguments" }
|
29
36
|
end
|
data/lib/autoflux/step.rb
CHANGED
data/lib/autoflux/version.rb
CHANGED
data/lib/autoflux/workflow.rb
CHANGED
@@ -16,6 +16,8 @@ module Autoflux
|
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
|
+
include Enumerable
|
20
|
+
|
19
21
|
attr_reader :id, :agent, :memory, :io
|
20
22
|
|
21
23
|
# @rbs state: State
|
@@ -27,12 +29,27 @@ module Autoflux
|
|
27
29
|
@memory = memory
|
28
30
|
end
|
29
31
|
|
32
|
+
def each
|
33
|
+
return to_enum(:each) unless block_given?
|
34
|
+
|
35
|
+
yield self
|
36
|
+
while @step
|
37
|
+
@step = step.call(workflow: self)
|
38
|
+
yield self if @step
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
30
42
|
# Run the workflow.
|
31
43
|
#
|
32
44
|
# @rbs system_prompt: String?
|
33
|
-
def run(system_prompt: nil)
|
34
|
-
|
35
|
-
|
45
|
+
def run(system_prompt: nil, &block)
|
46
|
+
if system_prompt
|
47
|
+
# @type var event: Autoflux::event
|
48
|
+
event = { role: ROLE_SYSTEM, content: system_prompt }
|
49
|
+
memory.push(event)
|
50
|
+
end
|
51
|
+
|
52
|
+
each(&block || ->(_workflow) {})
|
36
53
|
end
|
37
54
|
|
38
55
|
# Stop the workflow.
|
@@ -51,7 +68,7 @@ module Autoflux
|
|
51
68
|
def to_h
|
52
69
|
{
|
53
70
|
id: id,
|
54
|
-
step: step.
|
71
|
+
step: step.to_s
|
55
72
|
}
|
56
73
|
end
|
57
74
|
end
|
data/lib/autoflux.rb
CHANGED
@@ -6,9 +6,11 @@ require_relative "autoflux/version"
|
|
6
6
|
module Autoflux
|
7
7
|
class Error < StandardError; end
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ROLE_SYSTEM = "system"
|
10
|
+
ROLE_ASSISTANT = "assistant"
|
11
|
+
ROLE_TOOL = "tool"
|
12
|
+
ROLE_USER = "user"
|
13
|
+
|
12
14
|
require_relative "autoflux/memory"
|
13
15
|
require_relative "autoflux/step"
|
14
16
|
require_relative "autoflux/workflow"
|
data/sig/autoflux/agent.rbs
CHANGED
@@ -3,14 +3,6 @@ module Autoflux
|
|
3
3
|
interface _Agent
|
4
4
|
def tool?: (String name) -> bool
|
5
5
|
def tool: (String name) -> _Tool?
|
6
|
-
def call: (memory: _Memory) ->
|
7
|
-
end
|
8
|
-
|
9
|
-
# The Agent is a abstract class to represent the adapter of the Language Model.
|
10
|
-
class Agent
|
11
|
-
include _Agent
|
12
|
-
|
13
|
-
@_tools: Array[_Tool]
|
14
|
-
def initialize: (?tools: Array[_Tool]?) -> void
|
6
|
+
def call: (memory: _Memory) -> event
|
15
7
|
end
|
16
8
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Autoflux
|
2
|
+
type jsonString = String
|
3
|
+
|
4
|
+
type invocation = {
|
5
|
+
id: String,
|
6
|
+
name: String,
|
7
|
+
args: jsonString
|
8
|
+
}
|
9
|
+
|
10
|
+
type eventRole = "assistant" | "system" | "user" | "tool" | String
|
11
|
+
type baseEvent = {
|
12
|
+
role: eventRole,
|
13
|
+
agent_id?: String,
|
14
|
+
raw?: Hash[untyped, untyped]
|
15
|
+
}
|
16
|
+
type textEvent = baseEvent & {
|
17
|
+
content: String
|
18
|
+
}
|
19
|
+
type invocationEvent = baseEvent & {
|
20
|
+
invocations: Array[invocation]
|
21
|
+
}
|
22
|
+
type invocationResultEvent = textEvent & {
|
23
|
+
invocation_id: String
|
24
|
+
}
|
25
|
+
|
26
|
+
type event = textEvent | invocationEvent | invocationResultEvent
|
27
|
+
end
|
data/sig/autoflux/io.rbs
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
module Autoflux
|
2
2
|
interface _IO
|
3
|
-
def read: () -> String
|
4
|
-
def write: (String data) ->
|
5
|
-
end
|
6
|
-
|
7
|
-
# The IO is abstract class to represent the interface of the IO
|
8
|
-
class IO
|
9
|
-
include _IO
|
3
|
+
def read: () -> String?
|
4
|
+
def write: (String? data) -> untyped
|
10
5
|
end
|
11
6
|
end
|
data/sig/autoflux/memory.rbs
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
module Autoflux
|
2
2
|
interface _Memory
|
3
|
-
def data: () -> Array[
|
4
|
-
def push: (
|
5
|
-
def last: () ->
|
3
|
+
def data: () -> Array[event]
|
4
|
+
def push: (event event) -> void
|
5
|
+
def last: () -> event
|
6
6
|
end
|
7
7
|
|
8
8
|
# The Memory is a class to store the memory of the workflow.
|
9
9
|
class Memory
|
10
10
|
include _Memory
|
11
11
|
|
12
|
-
@data: Array[
|
12
|
+
@data: Array[event]
|
13
13
|
@verbose: bool
|
14
14
|
|
15
15
|
attr_reader verbose: bool
|
16
16
|
|
17
17
|
# @rbs data: Array[Hash]
|
18
|
-
def initialize: (?data: Array[
|
18
|
+
def initialize: (?data: Array[event], ?verbose: bool) -> void
|
19
19
|
end
|
20
20
|
end
|
data/sig/autoflux/stdio.rbs
CHANGED
@@ -1,21 +1,14 @@
|
|
1
1
|
module Autoflux
|
2
2
|
# The Stdio is a class to represent the standard input/output.
|
3
|
-
class Stdio
|
4
|
-
|
3
|
+
class Stdio
|
4
|
+
include _IO
|
5
5
|
|
6
|
-
@
|
6
|
+
@input: ::IO
|
7
|
+
@output: ::IO
|
8
|
+
@prompt: String?
|
7
9
|
|
8
|
-
|
10
|
+
attr_accessor prompt: String?
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
# @rbs input: IO
|
13
|
-
# @rbs output: IO
|
14
|
-
def initialize: (?input: untyped, ?output: untyped, ?prompt: untyped?) -> void
|
15
|
-
|
16
|
-
def read: () -> untyped
|
17
|
-
|
18
|
-
# @rbs data: String
|
19
|
-
def write: (untyped data) -> untyped
|
12
|
+
def initialize: (?input: IO, ?output: IO, ?prompt: String?) -> void
|
20
13
|
end
|
21
14
|
end
|
data/sig/autoflux/step.rbs
CHANGED
@@ -1,35 +1,35 @@
|
|
1
1
|
module Autoflux
|
2
2
|
interface _Step
|
3
|
-
def
|
3
|
+
def to_s: () -> String
|
4
4
|
def call: (workflow: Workflow) -> untyped
|
5
5
|
end
|
6
6
|
|
7
7
|
module Step
|
8
|
-
# The Step::Base is abstract class to represent the interface of the state
|
9
|
-
class Base
|
10
|
-
include Autoflux::_Step
|
11
|
-
end
|
12
|
-
|
13
8
|
# The Start step is used to start the workflow.
|
14
|
-
class Start
|
9
|
+
class Start
|
10
|
+
include Autoflux::_Step
|
15
11
|
end
|
16
12
|
|
17
13
|
# The Stop step is used to stop the workflow.
|
18
|
-
class Stop
|
14
|
+
class Stop
|
15
|
+
include Autoflux::_Step
|
19
16
|
end
|
20
17
|
|
21
18
|
# The Assistant state is used to call the agent.
|
22
|
-
class Assistant
|
19
|
+
class Assistant
|
20
|
+
include Autoflux::_Step
|
23
21
|
OUTPUT_ROLE_NAME: "assistant"
|
24
22
|
end
|
25
23
|
|
26
24
|
# The Tool state is used to call the tools provided by the agent.
|
27
|
-
class Tool
|
28
|
-
|
25
|
+
class Tool
|
26
|
+
include Autoflux::_Step
|
27
|
+
def run: (workflow: Workflow, invocation: invocation) -> ::_ToJson
|
29
28
|
end
|
30
29
|
|
31
30
|
# The Command step is used to get the user input.
|
32
|
-
class Command
|
31
|
+
class Command
|
32
|
+
include Autoflux::_Step
|
33
33
|
EXIT_COMMAND: "exit"
|
34
34
|
end
|
35
35
|
end
|
data/sig/autoflux/tool.rbs
CHANGED
@@ -1,20 +1,5 @@
|
|
1
1
|
module Autoflux
|
2
2
|
interface _Tool
|
3
|
-
def
|
4
|
-
def description: () -> String
|
5
|
-
def parameters: () -> untyped
|
6
|
-
|
7
|
-
def call: (**untyped) -> untyped
|
8
|
-
end
|
9
|
-
|
10
|
-
# The Tool is a abstract class to represent the adapter of tools which can be used by the Language Model.
|
11
|
-
class Tool
|
12
|
-
include _Tool
|
13
|
-
|
14
|
-
@name: String
|
15
|
-
@description: String
|
16
|
-
@parameters: untyped
|
17
|
-
|
18
|
-
def initialize: (name: String, description: String, ?parameters: untyped?) -> void
|
3
|
+
def call: (workflow: Workflow, params: untyped) -> untyped
|
19
4
|
end
|
20
5
|
end
|
data/sig/autoflux/workflow.rbs
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
module Autoflux
|
2
2
|
# The workflow is a state machine to manage the flow of agentic AI.
|
3
3
|
class Workflow
|
4
|
+
include Enumerable[Workflow]
|
5
|
+
|
4
6
|
@id: String
|
5
7
|
@agent: _Agent
|
6
8
|
@io: _IO
|
7
9
|
@step: _Step
|
8
10
|
@memory: _Memory
|
9
11
|
|
10
|
-
# Generate a random UUID.
|
11
|
-
#
|
12
|
-
# @return [String]
|
13
12
|
def self.next_id: () -> String
|
14
13
|
|
15
14
|
attr_reader id: String
|
@@ -17,23 +16,11 @@ module Autoflux
|
|
17
16
|
attr_reader memory: _Memory
|
18
17
|
attr_reader io: _IO
|
19
18
|
|
20
|
-
# @rbs state: State
|
21
19
|
def initialize: (agent: _Agent, io: _IO, ?id: String?, ?step: _Step, ?memory: _Memory) -> void
|
22
|
-
|
23
|
-
|
24
|
-
#
|
25
|
-
# @rbs system_prompt: String?
|
26
|
-
def run: (?system_prompt: String?) -> void
|
27
|
-
|
28
|
-
# Stop the workflow.
|
20
|
+
def each: { (Workflow) -> void } -> void
|
21
|
+
def run: (?system_prompt: String?) ?{ (Workflow) -> void } -> void
|
29
22
|
def stop: () -> void
|
30
|
-
|
31
|
-
# Get the current step. If the step is nil, return a Stop step.
|
32
23
|
def step: () -> _Step
|
33
|
-
|
34
|
-
# Get the hash representation of the workflow.
|
35
|
-
#
|
36
|
-
# @return [Hash]
|
37
24
|
def to_h: () -> { id: String, step: String }
|
38
25
|
end
|
39
26
|
end
|
data/sig/autoflux.rbs
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: autoflux
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aotokitsuruya
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-01-
|
11
|
+
date: 2025-01-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A lightweight AI agent framework for Ruby
|
14
14
|
email:
|
@@ -27,24 +27,21 @@ files:
|
|
27
27
|
- Steepfile
|
28
28
|
- commitlint.config.js
|
29
29
|
- lib/autoflux.rb
|
30
|
-
- lib/autoflux/agent.rb
|
31
|
-
- lib/autoflux/io.rb
|
32
30
|
- lib/autoflux/memory.rb
|
33
31
|
- lib/autoflux/stdio.rb
|
34
32
|
- lib/autoflux/step.rb
|
35
33
|
- lib/autoflux/step/assistant.rb
|
36
|
-
- lib/autoflux/step/base.rb
|
37
34
|
- lib/autoflux/step/command.rb
|
38
35
|
- lib/autoflux/step/start.rb
|
39
36
|
- lib/autoflux/step/stop.rb
|
40
37
|
- lib/autoflux/step/tool.rb
|
41
|
-
- lib/autoflux/tool.rb
|
42
38
|
- lib/autoflux/version.rb
|
43
39
|
- lib/autoflux/workflow.rb
|
44
40
|
- package-lock.json
|
45
41
|
- package.json
|
46
42
|
- sig/autoflux.rbs
|
47
43
|
- sig/autoflux/agent.rbs
|
44
|
+
- sig/autoflux/event.rbs
|
48
45
|
- sig/autoflux/io.rbs
|
49
46
|
- sig/autoflux/memory.rbs
|
50
47
|
- sig/autoflux/stdio.rbs
|
data/lib/autoflux/agent.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Autoflux
|
4
|
-
# The Agent is a abstract class to represent the adapter of the Language Model.
|
5
|
-
class Agent
|
6
|
-
# @rbs tools: Array<Tool>
|
7
|
-
def initialize(tools: [])
|
8
|
-
@_tools = tools
|
9
|
-
end
|
10
|
-
|
11
|
-
# @rbs name: String
|
12
|
-
def tool?(name)
|
13
|
-
@_tools.any? { |tool| tool.name == name }
|
14
|
-
end
|
15
|
-
|
16
|
-
# @rbs name: String
|
17
|
-
def tool(name)
|
18
|
-
@_tools.find { |tool| tool.name == name }
|
19
|
-
end
|
20
|
-
|
21
|
-
# @rbs memory: Memory?
|
22
|
-
def call(**)
|
23
|
-
raise NotImplementedError
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
data/lib/autoflux/io.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Autoflux
|
4
|
-
# The IO is abstract class to represent the interface of the IO
|
5
|
-
class IO
|
6
|
-
def read
|
7
|
-
raise NotImplementedError
|
8
|
-
end
|
9
|
-
|
10
|
-
# @rbs data: String
|
11
|
-
def write(_)
|
12
|
-
raise NotImplementedError
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/lib/autoflux/step/base.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Autoflux
|
4
|
-
module Step
|
5
|
-
# The Step::Base is abstract class to represent the interface of the state
|
6
|
-
class Base
|
7
|
-
# @rbs workflow: Workflow
|
8
|
-
def call(**)
|
9
|
-
raise NotImplementedError
|
10
|
-
end
|
11
|
-
|
12
|
-
def name
|
13
|
-
self.class.name || "Step"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
data/lib/autoflux/tool.rb
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Autoflux
|
4
|
-
# The Tool is a abstract class to represent the adapter of tools which can be used by the Language Model.
|
5
|
-
class Tool
|
6
|
-
attr_reader :name, :description, :parameters
|
7
|
-
|
8
|
-
def initialize(name:, description:, parameters: nil)
|
9
|
-
@name = name
|
10
|
-
@description = description
|
11
|
-
@parameters = parameters
|
12
|
-
freeze
|
13
|
-
end
|
14
|
-
|
15
|
-
def call(**)
|
16
|
-
raise NotImplementedError
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|