soka 0.0.1.beta2
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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +365 -0
- data/CHANGELOG.md +31 -0
- data/CLAUDE.md +213 -0
- data/LICENSE +21 -0
- data/README.md +650 -0
- data/Rakefile +10 -0
- data/examples/1_basic.rb +94 -0
- data/examples/2_event_handling.rb +120 -0
- data/examples/3_memory.rb +182 -0
- data/examples/4_hooks.rb +140 -0
- data/examples/5_error_handling.rb +85 -0
- data/examples/6_retry.rb +164 -0
- data/examples/7_tool_conditional.rb +180 -0
- data/examples/8_multi_provider.rb +112 -0
- data/lib/soka/agent.rb +130 -0
- data/lib/soka/agent_tool.rb +146 -0
- data/lib/soka/agent_tools/params_validator.rb +139 -0
- data/lib/soka/agents/dsl_methods.rb +140 -0
- data/lib/soka/agents/hook_manager.rb +68 -0
- data/lib/soka/agents/llm_builder.rb +32 -0
- data/lib/soka/agents/retry_handler.rb +74 -0
- data/lib/soka/agents/tool_builder.rb +78 -0
- data/lib/soka/configuration.rb +60 -0
- data/lib/soka/engines/base.rb +67 -0
- data/lib/soka/engines/concerns/prompt_template.rb +130 -0
- data/lib/soka/engines/concerns/response_processor.rb +103 -0
- data/lib/soka/engines/react.rb +136 -0
- data/lib/soka/engines/reasoning_context.rb +92 -0
- data/lib/soka/llm.rb +85 -0
- data/lib/soka/llms/anthropic.rb +124 -0
- data/lib/soka/llms/base.rb +114 -0
- data/lib/soka/llms/concerns/response_parser.rb +47 -0
- data/lib/soka/llms/concerns/streaming_handler.rb +78 -0
- data/lib/soka/llms/gemini.rb +106 -0
- data/lib/soka/llms/openai.rb +97 -0
- data/lib/soka/memory.rb +83 -0
- data/lib/soka/result.rb +136 -0
- data/lib/soka/test_helpers.rb +162 -0
- data/lib/soka/thoughts_memory.rb +112 -0
- data/lib/soka/version.rb +5 -0
- data/lib/soka.rb +49 -0
- data/sig/soka.rbs +4 -0
- metadata +158 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 78ad837d61ec2a941c9e10af5aca993ef92b47db056e60be35a37b01a79e1e73
|
4
|
+
data.tar.gz: 6c0c38931ad663decc2e18cad777a3decb1dc0bb32815db4289e2d5e60eec747
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 0babc9b4e2d5cd704e14c31bb955dea922133f844e78596f9fff25a0cd8c4ad5601248c276342d8adc0faaaf1e061129cad12283830878dfb72165df248efca1
|
7
|
+
data.tar.gz: e6b33ed72f5258dd19a1b62dadb7ec683141e12d64193753e619c94cb2816e16963cfb80322717c161c8bdef0dbd1854cbe82ed2f1e5f956bfc272fa345e0cbf
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,365 @@
|
|
1
|
+
# Omakase Ruby styling for Rails
|
2
|
+
# inherit_gem: { rubocop-rails-omakase: rubocop.yml }
|
3
|
+
|
4
|
+
# Overwrite or add rules to create your own house style
|
5
|
+
#
|
6
|
+
# # Use `[a, [b, c]]` not `[ a, [ b, c ] ]`
|
7
|
+
# Layout/SpaceInsideArrayLiteralBrackets:
|
8
|
+
# Enabled: false
|
9
|
+
plugins:
|
10
|
+
- rubocop-rspec
|
11
|
+
|
12
|
+
AllCops:
|
13
|
+
TargetRubyVersion: 3.4
|
14
|
+
SuggestExtensions: false
|
15
|
+
|
16
|
+
Exclude:
|
17
|
+
- 'examples/**/*'
|
18
|
+
- 'vendor/**/*'
|
19
|
+
|
20
|
+
Gemspec/AddRuntimeDependency: # new in 1.65
|
21
|
+
Enabled: true
|
22
|
+
Gemspec/DeprecatedAttributeAssignment: # new in 1.30
|
23
|
+
Enabled: true
|
24
|
+
Gemspec/DevelopmentDependencies: # new in 1.44
|
25
|
+
Enabled: true
|
26
|
+
Gemspec/RequireMFA: # new in 1.23
|
27
|
+
Enabled: true
|
28
|
+
Layout/LineContinuationLeadingSpace: # new in 1.31
|
29
|
+
Enabled: true
|
30
|
+
Layout/LineContinuationSpacing: # new in 1.31
|
31
|
+
Enabled: true
|
32
|
+
Layout/LineEndStringConcatenationIndentation: # new in 1.18
|
33
|
+
Enabled: true
|
34
|
+
Layout/SpaceBeforeBrackets: # new in 1.7
|
35
|
+
Enabled: true
|
36
|
+
Lint/AmbiguousAssignment: # new in 1.7
|
37
|
+
Enabled: true
|
38
|
+
Lint/AmbiguousOperatorPrecedence: # new in 1.21
|
39
|
+
Enabled: true
|
40
|
+
Lint/AmbiguousRange: # new in 1.19
|
41
|
+
Enabled: true
|
42
|
+
Lint/ConstantOverwrittenInRescue: # new in 1.31
|
43
|
+
Enabled: true
|
44
|
+
Lint/DeprecatedConstants: # new in 1.8
|
45
|
+
Enabled: true
|
46
|
+
Lint/DuplicateBranch: # new in 1.3
|
47
|
+
Enabled: true
|
48
|
+
Lint/DuplicateMagicComment: # new in 1.37
|
49
|
+
Enabled: true
|
50
|
+
Lint/DuplicateMatchPattern: # new in 1.50
|
51
|
+
Enabled: true
|
52
|
+
Lint/DuplicateRegexpCharacterClassElement: # new in 1.1
|
53
|
+
Enabled: true
|
54
|
+
Lint/EmptyBlock: # new in 1.1
|
55
|
+
Enabled: true
|
56
|
+
Lint/EmptyClass: # new in 1.3
|
57
|
+
Enabled: true
|
58
|
+
Lint/EmptyInPattern: # new in 1.16
|
59
|
+
Enabled: true
|
60
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
61
|
+
Enabled: true
|
62
|
+
Lint/ItWithoutArgumentsInBlock: # new in 1.59
|
63
|
+
Enabled: true
|
64
|
+
Lint/LambdaWithoutLiteralBlock: # new in 1.8
|
65
|
+
Enabled: true
|
66
|
+
Lint/LiteralAssignmentInCondition: # new in 1.58
|
67
|
+
Enabled: true
|
68
|
+
Lint/MixedCaseRange: # new in 1.53
|
69
|
+
Enabled: true
|
70
|
+
Lint/NoReturnInBeginEndBlocks: # new in 1.2
|
71
|
+
Enabled: true
|
72
|
+
Lint/NonAtomicFileOperation: # new in 1.31
|
73
|
+
Enabled: true
|
74
|
+
Lint/NumberedParameterAssignment: # new in 1.9
|
75
|
+
Enabled: true
|
76
|
+
Lint/OrAssignmentToConstant: # new in 1.9
|
77
|
+
Enabled: true
|
78
|
+
Lint/RedundantDirGlobSort: # new in 1.8
|
79
|
+
Enabled: true
|
80
|
+
Lint/RedundantRegexpQuantifiers: # new in 1.53
|
81
|
+
Enabled: true
|
82
|
+
Lint/RefinementImportMethods: # new in 1.27
|
83
|
+
Enabled: true
|
84
|
+
Lint/RequireRangeParentheses: # new in 1.32
|
85
|
+
Enabled: true
|
86
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
87
|
+
Enabled: true
|
88
|
+
Lint/SymbolConversion: # new in 1.9
|
89
|
+
Enabled: true
|
90
|
+
Lint/ToEnumArguments: # new in 1.1
|
91
|
+
Enabled: true
|
92
|
+
Lint/TripleQuotes: # new in 1.9
|
93
|
+
Enabled: true
|
94
|
+
Lint/UnexpectedBlockArity: # new in 1.5
|
95
|
+
Enabled: true
|
96
|
+
Lint/UnmodifiedReduceAccumulator: # new in 1.1
|
97
|
+
Enabled: true
|
98
|
+
Lint/UselessNumericOperation: # new in 1.66
|
99
|
+
Enabled: true
|
100
|
+
Lint/UselessRescue: # new in 1.43
|
101
|
+
Enabled: true
|
102
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
103
|
+
Enabled: true
|
104
|
+
Metrics/CollectionLiteralLength: # new in 1.47
|
105
|
+
Enabled: true
|
106
|
+
Naming/BlockForwarding: # new in 1.24
|
107
|
+
Enabled: true
|
108
|
+
Security/CompoundHash: # new in 1.28
|
109
|
+
Enabled: true
|
110
|
+
Security/IoMethods: # new in 1.22
|
111
|
+
Enabled: true
|
112
|
+
Style/ArgumentsForwarding: # new in 1.1
|
113
|
+
Enabled: true
|
114
|
+
Style/ArrayIntersect: # new in 1.40
|
115
|
+
Enabled: true
|
116
|
+
Style/CollectionCompact: # new in 1.2
|
117
|
+
Enabled: true
|
118
|
+
Style/ComparableClamp: # new in 1.44
|
119
|
+
Enabled: true
|
120
|
+
Style/ConcatArrayLiterals: # new in 1.41
|
121
|
+
Enabled: true
|
122
|
+
Style/DataInheritance: # new in 1.49
|
123
|
+
Enabled: true
|
124
|
+
Style/DirEmpty: # new in 1.48
|
125
|
+
Enabled: true
|
126
|
+
Style/DocumentDynamicEvalDefinition: # new in 1.1
|
127
|
+
Enabled: true
|
128
|
+
Style/EmptyHeredoc: # new in 1.32
|
129
|
+
Enabled: true
|
130
|
+
Style/EndlessMethod: # new in 1.8
|
131
|
+
Enabled: true
|
132
|
+
Style/EnvHome: # new in 1.29
|
133
|
+
Enabled: true
|
134
|
+
Style/ExactRegexpMatch: # new in 1.51
|
135
|
+
Enabled: true
|
136
|
+
Style/FetchEnvVar: # new in 1.28
|
137
|
+
Enabled: true
|
138
|
+
Style/FileEmpty: # new in 1.48
|
139
|
+
Enabled: true
|
140
|
+
Style/FileRead: # new in 1.24
|
141
|
+
Enabled: true
|
142
|
+
Style/FileWrite: # new in 1.24
|
143
|
+
Enabled: true
|
144
|
+
Style/HashConversion: # new in 1.10
|
145
|
+
Enabled: true
|
146
|
+
Style/HashExcept: # new in 1.7
|
147
|
+
Enabled: true
|
148
|
+
Style/IfWithBooleanLiteralBranches: # new in 1.9
|
149
|
+
Enabled: true
|
150
|
+
Style/InPatternThen: # new in 1.16
|
151
|
+
Enabled: true
|
152
|
+
Style/MagicCommentFormat: # new in 1.35
|
153
|
+
Enabled: true
|
154
|
+
Style/MapCompactWithConditionalBlock: # new in 1.30
|
155
|
+
Enabled: true
|
156
|
+
Style/MapIntoArray: # new in 1.63
|
157
|
+
Enabled: true
|
158
|
+
Style/MapToHash: # new in 1.24
|
159
|
+
Enabled: true
|
160
|
+
Style/MapToSet: # new in 1.42
|
161
|
+
Enabled: true
|
162
|
+
Style/MinMaxComparison: # new in 1.42
|
163
|
+
Enabled: true
|
164
|
+
Style/MultilineInPatternThen: # new in 1.16
|
165
|
+
Enabled: true
|
166
|
+
Style/NegatedIfElseCondition: # new in 1.2
|
167
|
+
Enabled: true
|
168
|
+
Style/NestedFileDirname: # new in 1.26
|
169
|
+
Enabled: true
|
170
|
+
Style/NilLambda: # new in 1.3
|
171
|
+
Enabled: true
|
172
|
+
Style/NumberedParameters: # new in 1.22
|
173
|
+
Enabled: true
|
174
|
+
Style/NumberedParametersLimit: # new in 1.22
|
175
|
+
Enabled: true
|
176
|
+
Style/ObjectThen: # new in 1.28
|
177
|
+
Enabled: true
|
178
|
+
Style/OperatorMethodCall: # new in 1.37
|
179
|
+
Enabled: true
|
180
|
+
Style/QuotedSymbols: # new in 1.16
|
181
|
+
Enabled: true
|
182
|
+
Style/RedundantArgument: # new in 1.4
|
183
|
+
Enabled: true
|
184
|
+
Style/RedundantArrayConstructor: # new in 1.52
|
185
|
+
Enabled: true
|
186
|
+
Style/RedundantConstantBase: # new in 1.40
|
187
|
+
Enabled: true
|
188
|
+
Style/RedundantCurrentDirectoryInPath: # new in 1.53
|
189
|
+
Enabled: true
|
190
|
+
Style/RedundantDoubleSplatHashBraces: # new in 1.41
|
191
|
+
Enabled: true
|
192
|
+
Style/RedundantEach: # new in 1.38
|
193
|
+
Enabled: true
|
194
|
+
Style/RedundantFilterChain: # new in 1.52
|
195
|
+
Enabled: true
|
196
|
+
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
|
197
|
+
Enabled: true
|
198
|
+
Style/RedundantInitialize: # new in 1.27
|
199
|
+
Enabled: true
|
200
|
+
Style/RedundantInterpolationUnfreeze: # new in 1.66
|
201
|
+
Enabled: true
|
202
|
+
Style/RedundantLineContinuation: # new in 1.49
|
203
|
+
Enabled: true
|
204
|
+
Style/RedundantRegexpArgument: # new in 1.53
|
205
|
+
Enabled: true
|
206
|
+
Style/RedundantRegexpConstructor: # new in 1.52
|
207
|
+
Enabled: true
|
208
|
+
Style/RedundantSelfAssignmentBranch: # new in 1.19
|
209
|
+
Enabled: true
|
210
|
+
Style/RedundantStringEscape: # new in 1.37
|
211
|
+
Enabled: true
|
212
|
+
Style/ReturnNilInPredicateMethodDefinition: # new in 1.53
|
213
|
+
Enabled: true
|
214
|
+
Style/SelectByRegexp: # new in 1.22
|
215
|
+
Enabled: true
|
216
|
+
Style/SendWithLiteralMethodName: # new in 1.64
|
217
|
+
Enabled: true
|
218
|
+
Style/SingleLineDoEndBlock: # new in 1.57
|
219
|
+
Enabled: true
|
220
|
+
Style/StringChars: # new in 1.12
|
221
|
+
Enabled: true
|
222
|
+
Style/SuperArguments: # new in 1.64
|
223
|
+
Enabled: true
|
224
|
+
Style/SuperWithArgsParentheses: # new in 1.58
|
225
|
+
Enabled: true
|
226
|
+
Style/SwapValues: # new in 1.1
|
227
|
+
Enabled: true
|
228
|
+
Style/YAMLFileRead: # new in 1.53
|
229
|
+
Enabled: true
|
230
|
+
Lint/DuplicateSetElement: # new in 1.67
|
231
|
+
Enabled: true
|
232
|
+
Lint/UnescapedBracketInRegexp: # new in 1.68
|
233
|
+
Enabled: true
|
234
|
+
Style/AmbiguousEndlessMethodDefinition: # new in 1.68
|
235
|
+
Enabled: true
|
236
|
+
Style/BitwisePredicate: # new in 1.68
|
237
|
+
Enabled: true
|
238
|
+
Style/CombinableDefined: # new in 1.68
|
239
|
+
Enabled: true
|
240
|
+
Style/KeywordArgumentsMerging: # new in 1.68
|
241
|
+
Enabled: true
|
242
|
+
Style/SafeNavigationChainLength: # new in 1.68
|
243
|
+
Enabled: true
|
244
|
+
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
|
245
|
+
Enabled: true
|
246
|
+
Lint/NumericOperationWithConstantResult: # new in 1.69
|
247
|
+
Enabled: true
|
248
|
+
Lint/UselessDefined: # new in 1.69
|
249
|
+
Enabled: true
|
250
|
+
Style/DigChain: # new in 1.69
|
251
|
+
Enabled: true
|
252
|
+
Style/FileNull: # new in 1.69
|
253
|
+
Enabled: true
|
254
|
+
Style/FileTouch: # new in 1.69
|
255
|
+
Enabled: true
|
256
|
+
Lint/ConstantReassignment: # new in 1.70
|
257
|
+
Enabled: true
|
258
|
+
Lint/SharedMutableDefault: # new in 1.70
|
259
|
+
Enabled: true
|
260
|
+
Style/ItAssignment: # new in 1.70
|
261
|
+
Enabled: true
|
262
|
+
Lint/ArrayLiteralInRegexp: # new in 1.71
|
263
|
+
Enabled: true
|
264
|
+
Style/HashSlice: # new in 1.71
|
265
|
+
Enabled: true
|
266
|
+
Lint/CopDirectiveSyntax: # new in 1.72
|
267
|
+
Enabled: true
|
268
|
+
Lint/RedundantTypeConversion: # new in 1.72
|
269
|
+
Enabled: true
|
270
|
+
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
|
271
|
+
Enabled: true
|
272
|
+
Lint/UselessConstantScoping: # new in 1.72
|
273
|
+
Enabled: true
|
274
|
+
Style/RedundantFormat: # new in 1.72
|
275
|
+
Enabled: true
|
276
|
+
Style/ComparableBetween: # new in 1.74
|
277
|
+
Enabled: true
|
278
|
+
Style/HashFetchChain: # new in 1.75
|
279
|
+
Enabled: true
|
280
|
+
Style/ItBlockParameter: # new in 1.75
|
281
|
+
Enabled: true
|
282
|
+
Lint/UselessDefaultValueArgument: # new in 1.76
|
283
|
+
Enabled: true
|
284
|
+
Lint/UselessOr: # new in 1.76
|
285
|
+
Enabled: true
|
286
|
+
Naming/PredicateMethod: # new in 1.76
|
287
|
+
Enabled: true
|
288
|
+
Style/EmptyStringInsideInterpolation: # new in 1.76
|
289
|
+
Enabled: true
|
290
|
+
Style/RedundantArrayFlatten: # new in 1.76
|
291
|
+
Enabled: true
|
292
|
+
Gemspec/AttributeAssignment: # new in 1.77
|
293
|
+
Enabled: true
|
294
|
+
Style/CollectionQuerying: # new in 1.77
|
295
|
+
Enabled: true
|
296
|
+
Layout/EmptyLinesAfterModuleInclusion: # new in 1.79
|
297
|
+
Enabled: true
|
298
|
+
Style/OpenStructUse: # new in 1.23
|
299
|
+
Enabled: true
|
300
|
+
# RSpecRails cops have been moved to a separate gem
|
301
|
+
# If you need Rails-specific RSpec cops, add rubocop-rspec_rails to your Gemfile
|
302
|
+
RSpec/BeEmpty: # new in 2.20
|
303
|
+
Enabled: true
|
304
|
+
RSpec/BeEq: # new in 2.9.0
|
305
|
+
Enabled: true
|
306
|
+
RSpec/BeNil: # new in 2.9.0
|
307
|
+
Enabled: true
|
308
|
+
RSpec/ChangeByZero: # new in 2.11
|
309
|
+
Enabled: true
|
310
|
+
RSpec/ContainExactly: # new in 2.19
|
311
|
+
Enabled: true
|
312
|
+
RSpec/DuplicatedMetadata: # new in 2.16
|
313
|
+
Enabled: true
|
314
|
+
RSpec/EmptyMetadata: # new in 2.24
|
315
|
+
Enabled: true
|
316
|
+
RSpec/EmptyOutput: # new in 2.29
|
317
|
+
Enabled: true
|
318
|
+
RSpec/Eq: # new in 2.24
|
319
|
+
Enabled: true
|
320
|
+
RSpec/ExcessiveDocstringSpacing: # new in 2.5
|
321
|
+
Enabled: true
|
322
|
+
RSpec/ExpectInLet: # new in 2.30
|
323
|
+
Enabled: true
|
324
|
+
RSpec/IdenticalEqualityAssertion: # new in 2.4
|
325
|
+
Enabled: true
|
326
|
+
RSpec/IndexedLet: # new in 2.20
|
327
|
+
Enabled: true
|
328
|
+
RSpec/IsExpectedSpecify: # new in 2.27
|
329
|
+
Enabled: true
|
330
|
+
RSpec/MatchArray: # new in 2.19
|
331
|
+
Enabled: true
|
332
|
+
RSpec/MetadataStyle: # new in 2.24
|
333
|
+
Enabled: true
|
334
|
+
RSpec/NoExpectationExample: # new in 2.13
|
335
|
+
Enabled: true
|
336
|
+
RSpec/PendingWithoutReason: # new in 2.16
|
337
|
+
Enabled: true
|
338
|
+
RSpec/ReceiveMessages: # new in 2.23
|
339
|
+
Enabled: true
|
340
|
+
RSpec/RedundantAround: # new in 2.19
|
341
|
+
Enabled: true
|
342
|
+
RSpec/RedundantPredicateMatcher: # new in 2.26
|
343
|
+
Enabled: true
|
344
|
+
RSpec/RemoveConst: # new in 2.26
|
345
|
+
Enabled: true
|
346
|
+
RSpec/RepeatedSubjectCall: # new in 2.27
|
347
|
+
Enabled: true
|
348
|
+
RSpec/SkipBlockInsideExample: # new in 2.19
|
349
|
+
Enabled: true
|
350
|
+
RSpec/SortMetadata: # new in 2.14
|
351
|
+
Enabled: true
|
352
|
+
RSpec/SpecFilePathFormat: # new in 2.24
|
353
|
+
Enabled: false
|
354
|
+
RSpec/SpecFilePathSuffix: # new in 2.24
|
355
|
+
Enabled: true
|
356
|
+
RSpec/SubjectDeclaration: # new in 2.5
|
357
|
+
Enabled: true
|
358
|
+
RSpec/UndescriptiveLiteralsDescription: # new in 2.29
|
359
|
+
Enabled: true
|
360
|
+
RSpec/VerifiedDoubleReference: # new in 2.10.0
|
361
|
+
Enabled: true
|
362
|
+
# Capybara and FactoryBot cops have been moved to separate gems
|
363
|
+
# If you need them, add rubocop-capybara and rubocop-factory_bot to your Gemfile
|
364
|
+
RSpec/IncludeExamples: # new in 3.6
|
365
|
+
Enabled: true
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
|
+
|
8
|
+
## [Unreleased]
|
9
|
+
|
10
|
+
## [0.0.1.beta2] - 2025-07-29
|
11
|
+
|
12
|
+
### Chores
|
13
|
+
- chore: update .gitignore to include new documentation files (e122098)
|
14
|
+
|
15
|
+
### Added
|
16
|
+
- Initial release of Soka gem
|
17
|
+
- Multi-LLM provider support (Gemini Studio, OpenAI, Anthropic)
|
18
|
+
- Object-oriented tool system with parameter validation
|
19
|
+
- ReAct (Reasoning and Acting) engine implementation
|
20
|
+
- Memory and ThoughtsMemory systems for conversation tracking
|
21
|
+
- Global and instance-level configuration system
|
22
|
+
- Retry mechanism with exponential backoff
|
23
|
+
- Test helper utilities
|
24
|
+
- Comprehensive documentation and examples
|
25
|
+
|
26
|
+
### Features
|
27
|
+
- Agent base class with DSL for easy customization
|
28
|
+
- Tool registration with conditional loading
|
29
|
+
- Before/after action hooks and error handlers
|
30
|
+
- Real-time event streaming during agent execution
|
31
|
+
- Result objects with detailed execution information
|
data/CLAUDE.md
ADDED
@@ -0,0 +1,213 @@
|
|
1
|
+
# Soka - Ruby ReAct Agent Framework
|
2
|
+
|
3
|
+
## Project Overview
|
4
|
+
|
5
|
+
Soka is a Ruby AI Agent framework based on the ReAct (Reasoning and Acting) pattern. It supports multiple AI providers (Gemini Studio, OpenAI, Anthropic) and provides an object-oriented tool system and intelligent memory management.
|
6
|
+
|
7
|
+
## Core Architecture
|
8
|
+
|
9
|
+
### Directory Structure
|
10
|
+
```
|
11
|
+
soka/
|
12
|
+
├── lib/
|
13
|
+
│ ├── soka.rb # Main entry point with Zeitwerk autoloading
|
14
|
+
│ └── soka/
|
15
|
+
│ ├── agent.rb # Agent base class with DSL and execution logic
|
16
|
+
│ ├── agent_tool.rb # Tool base class with parameter validation
|
17
|
+
│ ├── agent_tools/
|
18
|
+
│ │ └── params_validator.rb # Parameter validation module
|
19
|
+
│ ├── agents/ # Agent feature modules
|
20
|
+
│ │ ├── dsl_methods.rb # DSL method definitions
|
21
|
+
│ │ ├── hook_manager.rb # Lifecycle hook management
|
22
|
+
│ │ ├── llm_builder.rb # LLM instance construction
|
23
|
+
│ │ ├── retry_handler.rb # Retry mechanism
|
24
|
+
│ │ └── tool_builder.rb # Tool construction and management
|
25
|
+
│ ├── configuration.rb # Global configuration system
|
26
|
+
│ ├── llm.rb # LLM unified interface layer
|
27
|
+
│ ├── llms/ # LLM provider implementations
|
28
|
+
│ │ ├── base.rb # LLM base class
|
29
|
+
│ │ ├── concerns/ # Shared functionality modules
|
30
|
+
│ │ │ ├── response_parser.rb # Response parsing
|
31
|
+
│ │ │ └── streaming_handler.rb # Stream processing
|
32
|
+
│ │ ├── gemini.rb # Google Gemini implementation
|
33
|
+
│ │ ├── openai.rb # OpenAI implementation
|
34
|
+
│ │ └── anthropic.rb # Anthropic implementation
|
35
|
+
│ ├── engines/ # Reasoning engines
|
36
|
+
│ │ ├── base.rb # Engine base class
|
37
|
+
│ │ ├── concerns/ # Engine shared modules
|
38
|
+
│ │ │ ├── prompt_template.rb # Prompt templates
|
39
|
+
│ │ │ └── response_processor.rb # Response processing
|
40
|
+
│ │ ├── react.rb # ReAct reasoning engine
|
41
|
+
│ │ └── reasoning_context.rb # Reasoning context management
|
42
|
+
│ ├── memory.rb # Conversation memory management
|
43
|
+
│ ├── thoughts_memory.rb # Thought process memory
|
44
|
+
│ ├── result.rb # Result object encapsulation
|
45
|
+
│ ├── test_helpers.rb # RSpec test helpers
|
46
|
+
│ └── version.rb # Version definition
|
47
|
+
├── examples/
|
48
|
+
│ ├── 1_basic.rb # Basic usage example
|
49
|
+
│ ├── 2_event_handling.rb # Event handling example
|
50
|
+
│ ├── 3_memory.rb # Memory usage example
|
51
|
+
│ ├── 4_hooks.rb # Lifecycle hooks example
|
52
|
+
│ ├── 5_error_handling.rb # Error handling example
|
53
|
+
│ ├── 6_retry.rb # Retry mechanism example
|
54
|
+
│ ├── 7_tool_conditional.rb # Conditional tools example
|
55
|
+
│ └── 8_multi_provider.rb # Multi-provider example
|
56
|
+
├── spec/ # RSpec tests
|
57
|
+
└── test_soka.rb # Quick test script
|
58
|
+
```
|
59
|
+
|
60
|
+
## Core Component Descriptions
|
61
|
+
|
62
|
+
### 1. Agent System (`agent.rb`)
|
63
|
+
- Provides DSL for defining AI settings, tool registration, and retry mechanisms
|
64
|
+
- Supports conditional tool loading (`if:` option)
|
65
|
+
- Built-in lifecycle hooks (before_action, after_action, on_error)
|
66
|
+
- Uses `times` loop instead of `loop` for iteration control
|
67
|
+
- Modular design: functionality separated into concern modules
|
68
|
+
- `DSLMethods`: DSL method definitions
|
69
|
+
- `HookManager`: Lifecycle hook management
|
70
|
+
- `LLMBuilder`: LLM instance construction
|
71
|
+
- `RetryHandler`: Retry handling
|
72
|
+
- `ToolBuilder`: Tool construction and management
|
73
|
+
|
74
|
+
### 2. Tool System (`agent_tool.rb`)
|
75
|
+
- Grape API-like parameter definition system
|
76
|
+
- Built-in parameter validation (presence, length, inclusion, format)
|
77
|
+
- Supports required and optional parameters
|
78
|
+
- Auto-generates tool description schemas
|
79
|
+
|
80
|
+
### 3. ReAct Engine (`engines/react.rb`)
|
81
|
+
- Implements tagged ReAct flow: `<Thought>`, `<Action>`, `<Observation>`, `<Final_Answer>`
|
82
|
+
- Uses Struct instead of OpenStruct (Rubocop compliant)
|
83
|
+
- Automatically manages conversation context and tool execution
|
84
|
+
- Calculates confidence scores (based on iteration count)
|
85
|
+
- Uses `ReasoningContext` to manage reasoning state
|
86
|
+
- Shared modules:
|
87
|
+
- `PromptTemplate`: Prompt template management
|
88
|
+
- `ResponseProcessor`: Response processing logic
|
89
|
+
|
90
|
+
### 4. LLM Integration
|
91
|
+
- **LLM Unified Interface Layer (`llm.rb`)**
|
92
|
+
- Provides unified API interface
|
93
|
+
- Supports streaming and non-streaming modes
|
94
|
+
- Auto-routes to corresponding provider implementation
|
95
|
+
- **LLM Provider Implementations (`llms/`)**
|
96
|
+
- Gemini: Uses Google Generative AI API, defaults to `gemini-2.5-flash-lite`
|
97
|
+
- OpenAI: Supports GPT-4 series, includes streaming capabilities
|
98
|
+
- Anthropic: Supports Claude 3 series, handles system prompts
|
99
|
+
- Shared modules:
|
100
|
+
- `ResponseParser`: Unified response parsing
|
101
|
+
- `StreamingHandler`: Stream response handling
|
102
|
+
- Built-in error handling and retry mechanisms
|
103
|
+
|
104
|
+
### 5. Memory System
|
105
|
+
- `Memory`: Manages conversation history
|
106
|
+
- `ThoughtsMemory`: Records complete ReAct thought processes
|
107
|
+
- Supports initial memory loading
|
108
|
+
|
109
|
+
## Design Decisions
|
110
|
+
|
111
|
+
### 1. Using Zeitwerk Autoloading
|
112
|
+
- Simplifies require management
|
113
|
+
- Supports hot reloading (development environment)
|
114
|
+
- Automatically handles namespaces
|
115
|
+
|
116
|
+
### 2. Dry-rb Ecosystem Integration
|
117
|
+
- `dry-validation`: Powerful parameter validation
|
118
|
+
- `dry-struct`: Type-safe data structures
|
119
|
+
- `dry-types`: Type definitions and coercion
|
120
|
+
|
121
|
+
### 3. Configuration System Design
|
122
|
+
- Supports global configuration and instance-level overrides
|
123
|
+
- Block-style DSL provides intuitive configuration
|
124
|
+
- Fallback mechanism ensures service availability
|
125
|
+
- Configuration includes AI providers and performance settings
|
126
|
+
|
127
|
+
### 4. Error Handling Strategy
|
128
|
+
- Layered error class inheritance
|
129
|
+
- Tool execution errors don't interrupt entire flow
|
130
|
+
- Configurable retry mechanism (exponential backoff)
|
131
|
+
|
132
|
+
## Testing Strategy
|
133
|
+
|
134
|
+
### Unit Tests
|
135
|
+
- Using RSpec 3
|
136
|
+
- Provides `TestHelpers` module for mocking AI responses
|
137
|
+
- Supports tool mocking and error simulation
|
138
|
+
|
139
|
+
### Integration Tests
|
140
|
+
- `test_soka.rb`: Quick test without real API keys
|
141
|
+
- `examples/1_basic.rb`: Actual API integration test
|
142
|
+
|
143
|
+
## Development Guide
|
144
|
+
|
145
|
+
### Adding New AI Provider
|
146
|
+
1. Create new file in `lib/soka/llms/`
|
147
|
+
2. Inherit from `Soka::LLMs::Base`
|
148
|
+
3. Implement required methods:
|
149
|
+
- `default_model`
|
150
|
+
- `base_url`
|
151
|
+
- `chat(messages, **params)`
|
152
|
+
- `parse_response(response)`
|
153
|
+
4. Add new provider to `LLM#create_provider` method
|
154
|
+
|
155
|
+
### Adding New Tools
|
156
|
+
1. Inherit from `Soka::AgentTool`
|
157
|
+
2. Use `desc` to define description
|
158
|
+
3. Use `params` block to define parameters
|
159
|
+
4. Implement `call` method
|
160
|
+
|
161
|
+
### Custom Engines
|
162
|
+
1. Inherit from `Soka::Engines::Base`
|
163
|
+
2. Implement `reason(task, &block)` method
|
164
|
+
3. Use `emit_event` to send events
|
165
|
+
4. Return result object inheriting from Struct
|
166
|
+
5. Can use concerns modules to share functionality
|
167
|
+
|
168
|
+
## Rubocop Compatibility
|
169
|
+
- Complies with Ruby 3.0+ standards
|
170
|
+
- Major issues fixed:
|
171
|
+
- Using `Struct` instead of `OpenStruct`
|
172
|
+
- Using `format` instead of `String#%`
|
173
|
+
- Using `times` instead of `loop`
|
174
|
+
- Removed unused MODELS constants
|
175
|
+
|
176
|
+
## Performance Considerations
|
177
|
+
- Maximum iteration limit (default 10)
|
178
|
+
- Request timeout settings (default 30 seconds)
|
179
|
+
- Memory usage optimization (lazy loading)
|
180
|
+
|
181
|
+
## Security
|
182
|
+
- API keys managed through environment variables
|
183
|
+
- Input parameter validation
|
184
|
+
- Error messages don't leak sensitive information
|
185
|
+
- Supports `.env` files (not version controlled)
|
186
|
+
- Unified error handling hierarchy
|
187
|
+
|
188
|
+
## Future Extensions
|
189
|
+
- [ ] Support more LLM providers (Cohere, Hugging Face)
|
190
|
+
- [ ] Implement caching mechanism
|
191
|
+
- [ ] Support vector database integration
|
192
|
+
- [ ] Add more built-in tools
|
193
|
+
- [ ] WebSocket support for real-time conversations
|
194
|
+
- [ ] Support functional tools (use methods directly as tools)
|
195
|
+
|
196
|
+
## Development Standards
|
197
|
+
|
198
|
+
### Code Quality Checks
|
199
|
+
- **When adjusting code, the final step is to run Rubocop to check if the code complies with rules**
|
200
|
+
- **When Rubocop has any issues, fix them until all rules are satisfied**
|
201
|
+
- **When adjusting code, the final step is to perform a code review to avoid redundant design and ensure code conciseness**
|
202
|
+
- Check for unnecessary intermediate layers or methods
|
203
|
+
- Confirm parameter passing is direct and clear
|
204
|
+
- Remove duplicate code
|
205
|
+
- Avoid over-abstraction
|
206
|
+
|
207
|
+
### Code Documentation
|
208
|
+
- **When adjusting code, add comments and documentation to methods**
|
209
|
+
- Use YARD format comments
|
210
|
+
- Include method purpose descriptions
|
211
|
+
- Explain parameter types and purposes
|
212
|
+
- Explain return value types and meanings
|
213
|
+
- For complex logic, add implementation detail explanations
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 陳均均 (jiunjiun)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|