soka 0.0.1 → 0.0.3
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 +38 -0
- data/CLAUDE.md +347 -188
- data/README.md +137 -9
- data/examples/10_think_in_languages.rb +113 -0
- data/examples/2_event_handling.rb +5 -4
- data/examples/3_memory.rb +4 -2
- data/examples/4_hooks.rb +0 -1
- data/examples/9_custom_instructions.rb +190 -0
- data/lib/soka/agent.rb +22 -4
- data/lib/soka/agent_tool.rb +1 -1
- data/lib/soka/agents/dsl_methods.rb +14 -1
- data/lib/soka/engines/base.rb +6 -4
- data/lib/soka/engines/concerns/prompt_template.rb +44 -53
- data/lib/soka/engines/concerns/response_parser.rb +60 -0
- data/lib/soka/engines/concerns/response_processor.rb +5 -6
- data/lib/soka/engines/concerns/result_builder.rb +25 -0
- data/lib/soka/engines/react.rb +4 -26
- data/lib/soka/engines/reasoning_context.rb +4 -2
- data/lib/soka/result.rb +1 -5
- data/lib/soka/thoughts_memory.rb +0 -12
- data/lib/soka/version.rb +1 -1
- data/lib/soka.rb +0 -3
- metadata +7 -46
- data/lib/soka/test_helpers.rb +0 -162
data/lib/soka/engines/base.rb
CHANGED
@@ -4,13 +4,15 @@ module Soka
|
|
4
4
|
module Engines
|
5
5
|
# Base class for reasoning engines
|
6
6
|
class Base
|
7
|
-
attr_reader :agent, :llm, :tools, :max_iterations
|
7
|
+
attr_reader :agent, :llm, :tools, :max_iterations, :custom_instructions, :think_in
|
8
8
|
|
9
|
-
def initialize(agent,
|
9
|
+
def initialize(agent, tools, **options)
|
10
10
|
@agent = agent
|
11
|
-
@llm = llm
|
12
11
|
@tools = tools
|
13
|
-
@
|
12
|
+
@llm = options[:llm]
|
13
|
+
@max_iterations = options[:max_iterations] || 10
|
14
|
+
@custom_instructions = options[:custom_instructions]
|
15
|
+
@think_in = options[:think_in]
|
14
16
|
end
|
15
17
|
|
16
18
|
def reason(task)
|
@@ -8,6 +8,15 @@ module Soka
|
|
8
8
|
private
|
9
9
|
|
10
10
|
def system_prompt
|
11
|
+
# Use custom instructions if provided, otherwise use default ReAct prompt
|
12
|
+
if custom_instructions
|
13
|
+
combine_with_react_format(custom_instructions)
|
14
|
+
else
|
15
|
+
default_react_prompt
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_react_prompt
|
11
20
|
tools_description = format_tools_description(tools)
|
12
21
|
|
13
22
|
<<~PROMPT
|
@@ -20,16 +29,50 @@ module Soka
|
|
20
29
|
PROMPT
|
21
30
|
end
|
22
31
|
|
32
|
+
def combine_with_react_format(instructions)
|
33
|
+
tools_description = format_tools_description(tools)
|
34
|
+
|
35
|
+
<<~PROMPT
|
36
|
+
#{instructions}
|
37
|
+
|
38
|
+
You have access to the following tools:
|
39
|
+
#{tools_description}
|
40
|
+
|
41
|
+
#{format_instructions}
|
42
|
+
PROMPT
|
43
|
+
end
|
44
|
+
|
23
45
|
def format_instructions
|
46
|
+
thinking_instruction = build_thinking_instruction(think_in)
|
47
|
+
|
24
48
|
<<~INSTRUCTIONS
|
25
49
|
You must follow this exact format for each step:
|
26
50
|
|
51
|
+
#{thinking_instruction}
|
52
|
+
|
27
53
|
<Thought>Your reasoning about what to do next</Thought>
|
28
54
|
<Action>
|
29
55
|
Tool: tool_name
|
30
56
|
Parameters: {"param1": "value1", "param2": "value2"}
|
31
57
|
</Action>
|
32
58
|
|
59
|
+
#{action_format_rules}
|
60
|
+
INSTRUCTIONS
|
61
|
+
end
|
62
|
+
|
63
|
+
# Build thinking instruction based on language
|
64
|
+
# @param language [String, nil] The language to use for thinking
|
65
|
+
# @return [String] The thinking instruction
|
66
|
+
def build_thinking_instruction(language)
|
67
|
+
return '' unless language
|
68
|
+
|
69
|
+
"Use #{language} for your reasoning in <Thought> tags."
|
70
|
+
end
|
71
|
+
|
72
|
+
# Action format rules
|
73
|
+
# @return [String] The action format rules
|
74
|
+
def action_format_rules
|
75
|
+
<<~RULES
|
33
76
|
STOP HERE after each Action. Do NOT include <Observation> in your response.
|
34
77
|
The system will execute the tool and provide the observation.
|
35
78
|
|
@@ -45,7 +88,7 @@ module Soka
|
|
45
88
|
5. NEVER include <Observation> tags - wait for the system to provide them
|
46
89
|
6. Provide a clear and complete <Final_Answer> when done
|
47
90
|
7. If you cannot complete the task, explain why in the <Final_Answer>
|
48
|
-
|
91
|
+
RULES
|
49
92
|
end
|
50
93
|
|
51
94
|
def format_tools_description(tools)
|
@@ -72,58 +115,6 @@ module Soka
|
|
72
115
|
|
73
116
|
properties.join(', ')
|
74
117
|
end
|
75
|
-
|
76
|
-
def parse_response(text)
|
77
|
-
thoughts = extract_tagged_content(text, 'Thought')
|
78
|
-
actions = extract_actions(text)
|
79
|
-
final_answer = extract_tagged_content(text, 'Final_Answer').first
|
80
|
-
|
81
|
-
{
|
82
|
-
thoughts: thoughts,
|
83
|
-
actions: actions,
|
84
|
-
final_answer: final_answer
|
85
|
-
}
|
86
|
-
end
|
87
|
-
|
88
|
-
def extract_tagged_content(text, tag)
|
89
|
-
pattern = %r{<#{tag}>(.*?)</#{tag}>}m
|
90
|
-
text.scan(pattern).map { |match| match[0].strip }
|
91
|
-
end
|
92
|
-
|
93
|
-
def extract_actions(text)
|
94
|
-
action_blocks = text.scan(%r{<Action>(.*?)</Action>}m)
|
95
|
-
action_blocks.filter_map { |block| parse_action_block(block[0]) }
|
96
|
-
end
|
97
|
-
|
98
|
-
def parse_action_block(content)
|
99
|
-
content = content.strip
|
100
|
-
tool_match = content.match(/Tool:\s*(.+)/)
|
101
|
-
params_match = content.match(/Parameters:\s*(.+)/m)
|
102
|
-
|
103
|
-
return unless tool_match && params_match
|
104
|
-
|
105
|
-
tool_name = tool_match[1].strip
|
106
|
-
params_json = params_match[1].strip
|
107
|
-
params = parse_json_params(params_json)
|
108
|
-
|
109
|
-
{ tool: tool_name, params: params }
|
110
|
-
end
|
111
|
-
|
112
|
-
# Parse JSON parameters from action block
|
113
|
-
# @param params_json [String] The JSON string to parse
|
114
|
-
# @return [Hash] The parsed parameters as a hash with symbol keys
|
115
|
-
def parse_json_params(params_json)
|
116
|
-
# Clean up the JSON string - remove any trailing commas or whitespace
|
117
|
-
cleaned_json = params_json.strip.gsub(/,\s*}/, '}').gsub(/,\s*\]/, ']')
|
118
|
-
JSON.parse(cleaned_json, symbolize_names: true)
|
119
|
-
rescue JSON::ParserError
|
120
|
-
# Return empty hash to continue when JSON parsing fails
|
121
|
-
{}
|
122
|
-
end
|
123
|
-
|
124
|
-
def format_observation(observation)
|
125
|
-
"<Observation>#{observation}</Observation>"
|
126
|
-
end
|
127
118
|
end
|
128
119
|
end
|
129
120
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Engines
|
5
|
+
module Concerns
|
6
|
+
# Module for parsing LLM responses in ReAct format
|
7
|
+
module ResponseParser
|
8
|
+
private
|
9
|
+
|
10
|
+
def parse_response(text)
|
11
|
+
extract_response_parts(text)
|
12
|
+
end
|
13
|
+
|
14
|
+
def extract_response_parts(text)
|
15
|
+
{
|
16
|
+
thoughts: extract_tagged_content(text, 'Thought'),
|
17
|
+
actions: extract_actions(text),
|
18
|
+
final_answer: extract_tagged_content(text, 'Final_Answer').first
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def extract_tagged_content(text, tag)
|
23
|
+
pattern = %r{<#{tag}>(.*?)</#{tag}>}m
|
24
|
+
text.scan(pattern).map { |match| match[0].strip }
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract_actions(text)
|
28
|
+
action_blocks = text.scan(%r{<Action>(.*?)</Action>}m)
|
29
|
+
action_blocks.filter_map { |block| parse_action_block(block[0]) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_action_block(content)
|
33
|
+
content = content.strip
|
34
|
+
tool_match = content.match(/Tool:\s*(.+)/)
|
35
|
+
params_match = content.match(/Parameters:\s*(.+)/m)
|
36
|
+
|
37
|
+
return unless tool_match && params_match
|
38
|
+
|
39
|
+
tool_name = tool_match[1].strip
|
40
|
+
params_json = params_match[1].strip
|
41
|
+
params = parse_json_params(params_json)
|
42
|
+
|
43
|
+
{ tool: tool_name, params: params }
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parse JSON parameters from action block
|
47
|
+
# @param params_json [String] The JSON string to parse
|
48
|
+
# @return [Hash] The parsed parameters as a hash with symbol keys
|
49
|
+
def parse_json_params(params_json)
|
50
|
+
# Clean up the JSON string - remove any trailing commas or whitespace
|
51
|
+
cleaned_json = params_json.strip.gsub(/,\s*}/, '}').gsub(/,\s*\]/, ']')
|
52
|
+
JSON.parse(cleaned_json, symbolize_names: true)
|
53
|
+
rescue JSON::ParserError
|
54
|
+
# Return empty hash to continue when JSON parsing fails
|
55
|
+
{}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -5,8 +5,6 @@ module Soka
|
|
5
5
|
module Concerns
|
6
6
|
# Module for processing responses in ReAct engine
|
7
7
|
module ResponseProcessor
|
8
|
-
include Concerns::PromptTemplate
|
9
|
-
|
10
8
|
private
|
11
9
|
|
12
10
|
# Process thoughts from parsed response
|
@@ -75,10 +73,7 @@ module Soka
|
|
75
73
|
tool = tools.find { |t| t.class.tool_name == tool_name }
|
76
74
|
raise ToolError, "Tool '#{tool_name}' not found" unless tool
|
77
75
|
|
78
|
-
tool.
|
79
|
-
rescue StandardError => e
|
80
|
-
# Re-raise as ToolError to be caught by process_action
|
81
|
-
raise ToolError, "Error executing tool: #{e.message}"
|
76
|
+
tool.execute(**symbolize_keys(tool_input))
|
82
77
|
end
|
83
78
|
|
84
79
|
def symbolize_keys(hash)
|
@@ -97,6 +92,10 @@ module Soka
|
|
97
92
|
content: 'Please follow the exact format with <Thought>, <Action>, and <Final_Answer> tags.'
|
98
93
|
)
|
99
94
|
end
|
95
|
+
|
96
|
+
def format_observation(observation)
|
97
|
+
"<Observation>#{observation}</Observation>"
|
98
|
+
end
|
100
99
|
end
|
101
100
|
end
|
102
101
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Soka
|
4
|
+
module Engines
|
5
|
+
module Concerns
|
6
|
+
# Module for building ReAct reasoning results
|
7
|
+
module ResultBuilder
|
8
|
+
private
|
9
|
+
|
10
|
+
def build_result(input:, thoughts:, final_answer:, status:, error: nil)
|
11
|
+
result = {
|
12
|
+
input: input,
|
13
|
+
thoughts: thoughts,
|
14
|
+
final_answer: final_answer,
|
15
|
+
status: status
|
16
|
+
}
|
17
|
+
|
18
|
+
result[:error] = error if error
|
19
|
+
|
20
|
+
Soka::Engines::React::ReasonResult.new(**result)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/soka/engines/react.rb
CHANGED
@@ -8,6 +8,8 @@ module Soka
|
|
8
8
|
class React < Base
|
9
9
|
include Concerns::ResponseProcessor
|
10
10
|
include Concerns::PromptTemplate
|
11
|
+
include Concerns::ResponseParser
|
12
|
+
include Concerns::ResultBuilder
|
11
13
|
|
12
14
|
ReasonResult = Struct.new(:input, :thoughts, :final_answer, :status, :error, :confidence_score,
|
13
15
|
keyword_init: true) do
|
@@ -21,7 +23,8 @@ module Soka
|
|
21
23
|
# @yield [event] Optional block to handle events during execution
|
22
24
|
# @return [ReasonResult] The result of the reasoning process
|
23
25
|
def reason(task, &block)
|
24
|
-
context = ReasoningContext.new(task: task, event_handler: block, max_iterations: max_iterations
|
26
|
+
context = ReasoningContext.new(task: task, event_handler: block, max_iterations: max_iterations,
|
27
|
+
think_in: think_in)
|
25
28
|
context.messages = build_messages(task)
|
26
29
|
|
27
30
|
result = iterate_reasoning(context)
|
@@ -106,31 +109,6 @@ module Soka
|
|
106
109
|
status: :success
|
107
110
|
)
|
108
111
|
end
|
109
|
-
|
110
|
-
def build_result(input:, thoughts:, final_answer:, status:, error: nil)
|
111
|
-
result = {
|
112
|
-
input: input,
|
113
|
-
thoughts: thoughts,
|
114
|
-
final_answer: final_answer,
|
115
|
-
status: status
|
116
|
-
}
|
117
|
-
|
118
|
-
result[:error] = error if error
|
119
|
-
|
120
|
-
# Calculate confidence score based on iterations and status
|
121
|
-
result[:confidence_score] = calculate_confidence_score(thoughts, status)
|
122
|
-
|
123
|
-
ReasonResult.new(**result)
|
124
|
-
end
|
125
|
-
|
126
|
-
def calculate_confidence_score(thoughts, status)
|
127
|
-
return 0.0 if status != :success
|
128
|
-
|
129
|
-
base_score = 0.85
|
130
|
-
iteration_penalty = thoughts.length * 0.05
|
131
|
-
|
132
|
-
[base_score - iteration_penalty, 0.5].max
|
133
|
-
end
|
134
112
|
end
|
135
113
|
end
|
136
114
|
end
|
@@ -8,17 +8,19 @@ module Soka
|
|
8
8
|
# Event structure for emitting events
|
9
9
|
Event = Struct.new(:type, :content)
|
10
10
|
|
11
|
-
attr_accessor :messages, :thoughts, :task, :iteration, :parsed_response
|
11
|
+
attr_accessor :messages, :thoughts, :task, :iteration, :parsed_response, :think_in
|
12
12
|
attr_reader :event_handler, :max_iterations
|
13
13
|
|
14
14
|
# Initialize a new reasoning context
|
15
15
|
# @param task [String] The task to be processed
|
16
16
|
# @param event_handler [Proc, nil] Optional block to handle events
|
17
17
|
# @param max_iterations [Integer] Maximum number of reasoning iterations
|
18
|
-
|
18
|
+
# @param think_in [String, nil] The language to use for thinking
|
19
|
+
def initialize(task:, event_handler: nil, max_iterations: 10, think_in: nil)
|
19
20
|
@task = task
|
20
21
|
@event_handler = event_handler
|
21
22
|
@max_iterations = max_iterations
|
23
|
+
@think_in = think_in
|
22
24
|
@messages = []
|
23
25
|
@thoughts = []
|
24
26
|
@iteration = 0
|
data/lib/soka/result.rb
CHANGED
@@ -3,14 +3,13 @@
|
|
3
3
|
module Soka
|
4
4
|
# Represents the result of an agent's reasoning process
|
5
5
|
class Result
|
6
|
-
attr_reader :input, :thoughts, :final_answer, :
|
6
|
+
attr_reader :input, :thoughts, :final_answer, :status, :error, :execution_time
|
7
7
|
|
8
8
|
# Initialize a new Result instance
|
9
9
|
# @param attributes [Hash] Result attributes
|
10
10
|
# @option attributes [String] :input The original input
|
11
11
|
# @option attributes [Array] :thoughts Array of thought objects
|
12
12
|
# @option attributes [String] :final_answer The final answer
|
13
|
-
# @option attributes [Float] :confidence_score Confidence score (0.0-1.0)
|
14
13
|
# @option attributes [Symbol] :status The result status
|
15
14
|
# @option attributes [String] :error Error message if failed
|
16
15
|
# @option attributes [Float] :execution_time Time taken in seconds
|
@@ -18,7 +17,6 @@ module Soka
|
|
18
17
|
@input = attributes[:input]
|
19
18
|
@thoughts = attributes[:thoughts] || []
|
20
19
|
@final_answer = attributes[:final_answer]
|
21
|
-
@confidence_score = attributes[:confidence_score] || 0.0
|
22
20
|
@status = attributes[:status] || :pending
|
23
21
|
@error = attributes[:error]
|
24
22
|
@execution_time = attributes[:execution_time]
|
@@ -82,7 +80,6 @@ module Soka
|
|
82
80
|
def execution_details
|
83
81
|
{
|
84
82
|
iterations: iterations,
|
85
|
-
confidence: confidence_score ? format('%.1f%%', confidence_score * 100) : 'N/A',
|
86
83
|
time: execution_time ? "#{execution_time.round(2)}s" : 'N/A',
|
87
84
|
status: status
|
88
85
|
}
|
@@ -99,7 +96,6 @@ module Soka
|
|
99
96
|
input: input,
|
100
97
|
thoughts: thoughts,
|
101
98
|
final_answer: final_answer,
|
102
|
-
confidence_score: confidence_score,
|
103
99
|
status: status
|
104
100
|
}
|
105
101
|
end
|
data/lib/soka/thoughts_memory.rb
CHANGED
@@ -15,7 +15,6 @@ module Soka
|
|
15
15
|
thoughts: result.thoughts || [],
|
16
16
|
final_answer: result.final_answer,
|
17
17
|
status: result.status,
|
18
|
-
confidence_score: result.confidence_score,
|
19
18
|
timestamp: Time.now
|
20
19
|
}
|
21
20
|
|
@@ -52,14 +51,6 @@ module Soka
|
|
52
51
|
@sessions.select { |s| s[:status] == :failed }
|
53
52
|
end
|
54
53
|
|
55
|
-
def average_confidence_score
|
56
|
-
successful = successful_sessions
|
57
|
-
return 0.0 if successful.empty?
|
58
|
-
|
59
|
-
total = successful.sum { |s| s[:confidence_score] || 0.0 }
|
60
|
-
total / successful.size
|
61
|
-
end
|
62
|
-
|
63
54
|
def average_iterations
|
64
55
|
return 0 if @sessions.empty?
|
65
56
|
|
@@ -80,7 +71,6 @@ module Soka
|
|
80
71
|
total: size,
|
81
72
|
successful: successful_sessions.size,
|
82
73
|
failed: failed_sessions.size,
|
83
|
-
avg_confidence: format('%.2f', average_confidence_score),
|
84
74
|
avg_iterations: format('%.1f', average_iterations)
|
85
75
|
}
|
86
76
|
end
|
@@ -88,7 +78,6 @@ module Soka
|
|
88
78
|
def format_stats_string(stats)
|
89
79
|
"<Soka::ThoughtsMemory> (#{stats[:total]} sessions, " \
|
90
80
|
"#{stats[:successful]} successful, #{stats[:failed]} failed, " \
|
91
|
-
"avg confidence: #{stats[:avg_confidence]}, " \
|
92
81
|
"avg iterations: #{stats[:avg_iterations]})"
|
93
82
|
end
|
94
83
|
|
@@ -103,7 +92,6 @@ module Soka
|
|
103
92
|
total_sessions: size,
|
104
93
|
successful_sessions: successful_sessions.size,
|
105
94
|
failed_sessions: failed_sessions.size,
|
106
|
-
average_confidence_score: average_confidence_score,
|
107
95
|
average_iterations: average_iterations
|
108
96
|
}
|
109
97
|
}
|
data/lib/soka/version.rb
CHANGED
data/lib/soka.rb
CHANGED
metadata
CHANGED
@@ -1,56 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- jiunjiun
|
8
|
-
bindir:
|
8
|
+
bindir: bin
|
9
9
|
cert_chain: []
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
|
-
- !ruby/object:Gem::Dependency
|
13
|
-
name: dry-struct
|
14
|
-
requirement: !ruby/object:Gem::Requirement
|
15
|
-
requirements:
|
16
|
-
- - "~>"
|
17
|
-
- !ruby/object:Gem::Version
|
18
|
-
version: '1.6'
|
19
|
-
type: :runtime
|
20
|
-
prerelease: false
|
21
|
-
version_requirements: !ruby/object:Gem::Requirement
|
22
|
-
requirements:
|
23
|
-
- - "~>"
|
24
|
-
- !ruby/object:Gem::Version
|
25
|
-
version: '1.6'
|
26
|
-
- !ruby/object:Gem::Dependency
|
27
|
-
name: dry-types
|
28
|
-
requirement: !ruby/object:Gem::Requirement
|
29
|
-
requirements:
|
30
|
-
- - "~>"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '1.7'
|
33
|
-
type: :runtime
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '1.7'
|
40
|
-
- !ruby/object:Gem::Dependency
|
41
|
-
name: dry-validation
|
42
|
-
requirement: !ruby/object:Gem::Requirement
|
43
|
-
requirements:
|
44
|
-
- - "~>"
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: '1.10'
|
47
|
-
type: :runtime
|
48
|
-
prerelease: false
|
49
|
-
version_requirements: !ruby/object:Gem::Requirement
|
50
|
-
requirements:
|
51
|
-
- - "~>"
|
52
|
-
- !ruby/object:Gem::Version
|
53
|
-
version: '1.10'
|
54
12
|
- !ruby/object:Gem::Dependency
|
55
13
|
name: faraday
|
56
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,7 +38,7 @@ dependencies:
|
|
80
38
|
- !ruby/object:Gem::Version
|
81
39
|
version: '2.6'
|
82
40
|
description: Soka is a Ruby framework for building AI agents using the ReAct (Reasoning
|
83
|
-
and Acting) pattern. It supports multiple AI providers including Gemini Studio,
|
41
|
+
and Acting) pattern. It supports multiple AI providers including Gemini AI Studio,
|
84
42
|
OpenAI, and Anthropic.
|
85
43
|
email:
|
86
44
|
- imjiunjiun@gmail.com
|
@@ -95,6 +53,7 @@ files:
|
|
95
53
|
- LICENSE
|
96
54
|
- README.md
|
97
55
|
- Rakefile
|
56
|
+
- examples/10_think_in_languages.rb
|
98
57
|
- examples/1_basic.rb
|
99
58
|
- examples/2_event_handling.rb
|
100
59
|
- examples/3_memory.rb
|
@@ -103,6 +62,7 @@ files:
|
|
103
62
|
- examples/6_retry.rb
|
104
63
|
- examples/7_tool_conditional.rb
|
105
64
|
- examples/8_multi_provider.rb
|
65
|
+
- examples/9_custom_instructions.rb
|
106
66
|
- lib/soka.rb
|
107
67
|
- lib/soka/agent.rb
|
108
68
|
- lib/soka/agent_tool.rb
|
@@ -115,7 +75,9 @@ files:
|
|
115
75
|
- lib/soka/configuration.rb
|
116
76
|
- lib/soka/engines/base.rb
|
117
77
|
- lib/soka/engines/concerns/prompt_template.rb
|
78
|
+
- lib/soka/engines/concerns/response_parser.rb
|
118
79
|
- lib/soka/engines/concerns/response_processor.rb
|
80
|
+
- lib/soka/engines/concerns/result_builder.rb
|
119
81
|
- lib/soka/engines/react.rb
|
120
82
|
- lib/soka/engines/reasoning_context.rb
|
121
83
|
- lib/soka/llm.rb
|
@@ -125,7 +87,6 @@ files:
|
|
125
87
|
- lib/soka/llms/openai.rb
|
126
88
|
- lib/soka/memory.rb
|
127
89
|
- lib/soka/result.rb
|
128
|
-
- lib/soka/test_helpers.rb
|
129
90
|
- lib/soka/thoughts_memory.rb
|
130
91
|
- lib/soka/version.rb
|
131
92
|
- sig/soka.rbs
|