robot_lab 0.2.6 → 0.2.7
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 +124 -64
- data/docs/api/core/index.md +41 -15
- data/docs/api/core/memory.md +247 -29
- data/docs/api/core/network.md +255 -33
- data/docs/api/core/result.md +120 -32
- data/docs/api/core/robot.md +551 -61
- data/docs/api/core/state.md +87 -197
- data/docs/api/core/tool.md +165 -20
- data/docs/api/errors.md +110 -17
- data/docs/api/hooks.md +469 -0
- data/docs/api/index.md +80 -7
- data/docs/api/mcp/client.md +129 -35
- data/docs/api/mcp/index.md +164 -23
- data/docs/api/mcp/server.md +27 -3
- data/docs/api/mcp/transports.md +94 -22
- data/docs/api/messages/index.md +26 -3
- data/docs/api/messages/text-message.md +33 -11
- data/docs/api/messages/tool-call-message.md +27 -4
- data/docs/api/messages/tool-result-message.md +23 -4
- data/docs/api/messages/user-message.md +45 -8
- data/docs/api/skills.md +519 -0
- data/docs/api/streaming/context.md +28 -5
- data/docs/api/streaming/index.md +57 -11
- data/docs/api/support.md +846 -0
- data/docs/architecture/core-concepts.md +79 -31
- data/docs/architecture/index.md +86 -11
- data/docs/architecture/message-flow.md +66 -29
- data/docs/architecture/network-orchestration.md +145 -38
- data/docs/architecture/robot-execution.md +172 -90
- data/docs/architecture/state-management.md +31 -12
- data/docs/concepts.md +176 -21
- data/docs/examples/basic-chat.md +72 -19
- data/docs/examples/index.md +117 -31
- data/docs/examples/mcp-server.md +154 -45
- data/docs/examples/multi-robot-network.md +91 -21
- data/docs/examples/tool-usage.md +104 -37
- data/docs/getting-started/configuration.md +284 -97
- data/docs/getting-started/installation.md +53 -41
- data/docs/getting-started/quick-start.md +51 -6
- data/docs/guides/building-robots.md +258 -50
- data/docs/guides/creating-networks.md +214 -30
- data/docs/guides/hooks.md +141 -54
- data/docs/guides/knowledge.md +35 -4
- data/docs/guides/mcp-integration.md +211 -44
- data/docs/guides/memory.md +103 -12
- data/docs/guides/observability.md +95 -47
- data/docs/guides/streaming.md +184 -125
- data/docs/guides/using-tools.md +237 -17
- data/docs/index.md +36 -4
- data/examples/01_simple_robot.rb +2 -2
- data/examples/02_tools.rb +14 -4
- data/examples/03_network.rb +12 -7
- data/examples/04_mcp.rb +11 -4
- data/examples/05_streaming.rb +8 -5
- data/examples/06_prompt_templates.rb +13 -9
- data/examples/07_network_memory.rb +5 -5
- data/examples/08_llm_config.rb +20 -15
- data/examples/09_chaining.rb +4 -4
- data/examples/11_network_introspection.rb +4 -4
- data/examples/12_message_bus.rb +2 -2
- data/examples/13_spawn.rb +2 -2
- data/examples/14_rusty_circuit/README.md +1 -0
- data/examples/14_rusty_circuit/comic.rb +7 -3
- data/examples/14_rusty_circuit/display.rb +14 -0
- data/examples/14_rusty_circuit/heckler.rb +8 -6
- data/examples/14_rusty_circuit/open_mic.rb +17 -6
- data/examples/14_rusty_circuit/scout.rb +17 -10
- data/examples/15_memory_network_and_bus/editorial_pipeline.rb +14 -10
- data/examples/15_memory_network_and_bus/linux_writer.rb +2 -2
- data/examples/15_memory_network_and_bus/os_editor.rb +3 -1
- data/examples/15_memory_network_and_bus/os_writer.rb +4 -1
- data/examples/16_writers_room/writer.rb +22 -22
- data/examples/16_writers_room/writers_room.rb +2 -0
- data/examples/17_skills.rb +14 -13
- data/examples/18_rails/README.md +20 -1
- data/examples/18_rails/app/controllers/chat_controller.rb +5 -1
- data/examples/18_rails/app/jobs/robot_run_job.rb +11 -5
- data/examples/18_rails/app/robots/chat_robot.rb +11 -0
- data/examples/18_rails/config/initializers/robot_lab.rb +8 -0
- data/examples/19_token_tracking.rb +25 -9
- data/examples/20_circuit_breaker.rb +10 -7
- data/examples/21_learning_loop.rb +42 -16
- data/examples/22_context_compression.rb +23 -23
- data/examples/23_convergence.rb +24 -17
- data/examples/24_structured_delegation.rb +13 -8
- data/examples/25_history_search.rb +12 -8
- data/examples/27_incident_response/incident_response.rb +31 -13
- data/examples/28_mcp_discovery.rb +17 -13
- data/examples/29_ractor_tools.rb +4 -2
- data/examples/30_ractor_network.rb +22 -17
- data/examples/31_launch_assessment.rb +20 -9
- data/examples/32_newsletter_reader.rb +7 -2
- data/examples/33_stock_predictor.rb +34 -13
- data/examples/34_agentskills.rb +7 -3
- data/examples/35_hooks.rb +18 -8
- data/examples/README.md +199 -45
- data/examples/common.rb +79 -11
- data/examples/xyzzy.rb +8 -1
- data/lib/robot_lab/config.rb +10 -5
- data/lib/robot_lab/names.rb +402 -0
- data/lib/robot_lab/robot/agent_skill_matching.rb +1 -3
- data/lib/robot_lab/robot/bus_messaging.rb +16 -8
- data/lib/robot_lab/robot/template_rendering.rb +16 -3
- data/lib/robot_lab/robot.rb +23 -2
- data/lib/robot_lab/version.rb +1 -1
- data/lib/robot_lab.rb +21 -15
- data/mkdocs.yml +6 -1
- metadata +7 -2
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
# lib/robot_lab/names.rb
|
|
2
|
+
|
|
3
|
+
# A large curated word list, not application logic — kept as one inline
|
|
4
|
+
# module for lookup speed, so the size/length cops below are false positives.
|
|
5
|
+
# rubocop:disable Metrics/ModuleLength
|
|
6
|
+
module RobotLab
|
|
7
|
+
# Fictional robot names
|
|
8
|
+
# rubocop:disable Metrics/CollectionLiteralLength
|
|
9
|
+
NAMES = %w[
|
|
10
|
+
R_7723
|
|
11
|
+
R_790
|
|
12
|
+
AXL
|
|
13
|
+
Adam
|
|
14
|
+
Adam_Link
|
|
15
|
+
Alfie
|
|
16
|
+
Alojzy_Kukuryk
|
|
17
|
+
Alpha_5
|
|
18
|
+
Alpha_6
|
|
19
|
+
Alsatia_Zevo
|
|
20
|
+
AMEE
|
|
21
|
+
Ancient_Ore_Crusher
|
|
22
|
+
Andrew
|
|
23
|
+
Andrew_Martin
|
|
24
|
+
Andromon
|
|
25
|
+
Aniel
|
|
26
|
+
Aqua
|
|
27
|
+
Arbeitsmaschine
|
|
28
|
+
Arthur
|
|
29
|
+
Artificial_Friend
|
|
30
|
+
Ash
|
|
31
|
+
Astor
|
|
32
|
+
Astro_Boy
|
|
33
|
+
Athena
|
|
34
|
+
Atmophytes
|
|
35
|
+
AUTO
|
|
36
|
+
Ava
|
|
37
|
+
B_4
|
|
38
|
+
BATs
|
|
39
|
+
BEN
|
|
40
|
+
BOB
|
|
41
|
+
B166ER
|
|
42
|
+
Baymax
|
|
43
|
+
BB
|
|
44
|
+
BB_8
|
|
45
|
+
Becker
|
|
46
|
+
Bender
|
|
47
|
+
Bénédict_Masson
|
|
48
|
+
Bennie
|
|
49
|
+
Beta
|
|
50
|
+
Beta_Machine
|
|
51
|
+
Billybot
|
|
52
|
+
Bishop
|
|
53
|
+
Black_Beauty
|
|
54
|
+
Blue_Senturion
|
|
55
|
+
Boilerplate
|
|
56
|
+
Boppers
|
|
57
|
+
Bors
|
|
58
|
+
Box
|
|
59
|
+
Brackenridge
|
|
60
|
+
Brainbots
|
|
61
|
+
BRL_A
|
|
62
|
+
Bruno
|
|
63
|
+
Bubo
|
|
64
|
+
Buffybot
|
|
65
|
+
BURN_E
|
|
66
|
+
Byron
|
|
67
|
+
C_3PO
|
|
68
|
+
CHOMPS
|
|
69
|
+
Calculon
|
|
70
|
+
Caliban
|
|
71
|
+
Call
|
|
72
|
+
Cambot
|
|
73
|
+
Candy_Droober
|
|
74
|
+
Carl
|
|
75
|
+
Casandra_Kresnov
|
|
76
|
+
CASE
|
|
77
|
+
Cassandra_One
|
|
78
|
+
Chani
|
|
79
|
+
CHAPPiE
|
|
80
|
+
Charlie
|
|
81
|
+
Cherry_2000
|
|
82
|
+
Chip
|
|
83
|
+
CHIP
|
|
84
|
+
Chitti
|
|
85
|
+
Chuck_the_Robot
|
|
86
|
+
Chucky
|
|
87
|
+
Chumblies
|
|
88
|
+
Claire
|
|
89
|
+
Clamps
|
|
90
|
+
Clunk
|
|
91
|
+
Coconuts
|
|
92
|
+
Coldfire
|
|
93
|
+
Coldstone
|
|
94
|
+
Colossus
|
|
95
|
+
Conky_2000
|
|
96
|
+
Coppélia
|
|
97
|
+
Coyote
|
|
98
|
+
Crimson
|
|
99
|
+
Crow_T_Robot
|
|
100
|
+
Cutie
|
|
101
|
+
Cybots
|
|
102
|
+
Cylons
|
|
103
|
+
D_FIB
|
|
104
|
+
DARYL
|
|
105
|
+
Damon
|
|
106
|
+
Data
|
|
107
|
+
David
|
|
108
|
+
David_8
|
|
109
|
+
Dee_Model
|
|
110
|
+
Dewey
|
|
111
|
+
DOR_15
|
|
112
|
+
Dorfl
|
|
113
|
+
Dot_Matrix
|
|
114
|
+
DV_8
|
|
115
|
+
ED_209
|
|
116
|
+
EDI
|
|
117
|
+
Elio
|
|
118
|
+
Elle
|
|
119
|
+
Emma_2
|
|
120
|
+
Enforcer_Drone
|
|
121
|
+
Engimals
|
|
122
|
+
EVAs
|
|
123
|
+
Eve
|
|
124
|
+
EVE
|
|
125
|
+
Evolver
|
|
126
|
+
Ez_27
|
|
127
|
+
false_Maria
|
|
128
|
+
Fembots
|
|
129
|
+
Flexo
|
|
130
|
+
Frank_Saunders
|
|
131
|
+
Franklin_Droober
|
|
132
|
+
Freya
|
|
133
|
+
Freysa
|
|
134
|
+
Frost
|
|
135
|
+
G2
|
|
136
|
+
Galaxina
|
|
137
|
+
GERTY_3000
|
|
138
|
+
Giant_Robot
|
|
139
|
+
Giddy
|
|
140
|
+
Gigantor
|
|
141
|
+
Gnut
|
|
142
|
+
GO_4
|
|
143
|
+
Goddard
|
|
144
|
+
Gog
|
|
145
|
+
Gort
|
|
146
|
+
Gort
|
|
147
|
+
Gris
|
|
148
|
+
Grounder
|
|
149
|
+
Guardromon
|
|
150
|
+
Gypsy
|
|
151
|
+
Hadaly
|
|
152
|
+
HAN_S
|
|
153
|
+
Haro
|
|
154
|
+
HCR_328
|
|
155
|
+
Hector
|
|
156
|
+
Helen_OLoy
|
|
157
|
+
Helena
|
|
158
|
+
Hermes
|
|
159
|
+
Huey
|
|
160
|
+
Hymie
|
|
161
|
+
Ilia
|
|
162
|
+
Intergalactic_Advocate_Bob
|
|
163
|
+
Jaegers
|
|
164
|
+
Janice_Em
|
|
165
|
+
Jay_Score
|
|
166
|
+
Jay_Dub
|
|
167
|
+
Jenkins
|
|
168
|
+
Jenny_Wakeman
|
|
169
|
+
Jessica
|
|
170
|
+
Jet
|
|
171
|
+
Jet_Jaguar
|
|
172
|
+
Jinx
|
|
173
|
+
Johnny_5
|
|
174
|
+
Johnny_Cab
|
|
175
|
+
Juliana_Tainer
|
|
176
|
+
K
|
|
177
|
+
K_2SO
|
|
178
|
+
K9
|
|
179
|
+
Kampfmaschin
|
|
180
|
+
KARR
|
|
181
|
+
Kay_Em_14
|
|
182
|
+
Kei
|
|
183
|
+
Kikaider
|
|
184
|
+
Killbots
|
|
185
|
+
Kirby
|
|
186
|
+
Kit
|
|
187
|
+
KITT
|
|
188
|
+
Klapaucius
|
|
189
|
+
Kronos
|
|
190
|
+
Kryten
|
|
191
|
+
Kwanzaa_Bot
|
|
192
|
+
Kyoko
|
|
193
|
+
L_76
|
|
194
|
+
L3_37
|
|
195
|
+
Lal
|
|
196
|
+
Lenny
|
|
197
|
+
Leon_Kowalski
|
|
198
|
+
Lomax
|
|
199
|
+
Lore
|
|
200
|
+
Louie
|
|
201
|
+
Luv
|
|
202
|
+
M_O
|
|
203
|
+
M3GAN
|
|
204
|
+
Mac
|
|
205
|
+
Magog
|
|
206
|
+
Mami
|
|
207
|
+
Manders
|
|
208
|
+
Mandroid
|
|
209
|
+
Marcus_Wright
|
|
210
|
+
Maria
|
|
211
|
+
Mariette
|
|
212
|
+
Marius
|
|
213
|
+
Mark_1
|
|
214
|
+
MARK13
|
|
215
|
+
Marvin
|
|
216
|
+
Mary_25
|
|
217
|
+
Maschinenmensch
|
|
218
|
+
Mata_Nui
|
|
219
|
+
Maureen_Droober
|
|
220
|
+
MAX
|
|
221
|
+
Max_404
|
|
222
|
+
Maximillian
|
|
223
|
+
May
|
|
224
|
+
MD_63
|
|
225
|
+
Mech_Eagles
|
|
226
|
+
Mecha_King_Ghidorah
|
|
227
|
+
Mechagodzilla
|
|
228
|
+
Mechagodzilla
|
|
229
|
+
Mechani_Kong
|
|
230
|
+
Mechano
|
|
231
|
+
Mechonoids
|
|
232
|
+
Mec_Willy
|
|
233
|
+
Melfina
|
|
234
|
+
Merlin_Athrawes
|
|
235
|
+
Micro_Managers
|
|
236
|
+
MM7
|
|
237
|
+
Moguera
|
|
238
|
+
MOOSE
|
|
239
|
+
Moravecs
|
|
240
|
+
Mordel
|
|
241
|
+
Morgan
|
|
242
|
+
Mr_Split
|
|
243
|
+
Mr_Static
|
|
244
|
+
Muranian
|
|
245
|
+
Necron_99
|
|
246
|
+
Neotnia
|
|
247
|
+
Newman
|
|
248
|
+
Nimani
|
|
249
|
+
Nimue_Alban
|
|
250
|
+
Norby
|
|
251
|
+
NS4
|
|
252
|
+
Okra
|
|
253
|
+
Olimpia
|
|
254
|
+
Oliver
|
|
255
|
+
Olympia
|
|
256
|
+
Omega
|
|
257
|
+
Omnidroid
|
|
258
|
+
Otis
|
|
259
|
+
POPS
|
|
260
|
+
Paws
|
|
261
|
+
Peace
|
|
262
|
+
Phatasaur
|
|
263
|
+
Phil
|
|
264
|
+
Pino_Petto
|
|
265
|
+
PR_T
|
|
266
|
+
Primus
|
|
267
|
+
Pris
|
|
268
|
+
Project_2501
|
|
269
|
+
Proteus_IV
|
|
270
|
+
Quinn
|
|
271
|
+
R_Daneel_Olivaw
|
|
272
|
+
R_Giskard_Reventlov
|
|
273
|
+
RALF
|
|
274
|
+
ROTOR
|
|
275
|
+
R2_D2
|
|
276
|
+
R4_P17
|
|
277
|
+
Rabbot
|
|
278
|
+
Rachael
|
|
279
|
+
Radius
|
|
280
|
+
Rena
|
|
281
|
+
Replicators
|
|
282
|
+
Rex
|
|
283
|
+
RIA
|
|
284
|
+
Richard_Daniel
|
|
285
|
+
Rick_Deckard
|
|
286
|
+
Ro_Man_Extension_XJ_2
|
|
287
|
+
Rob_Monkey
|
|
288
|
+
Robbie
|
|
289
|
+
Robby
|
|
290
|
+
Robo
|
|
291
|
+
Robo_Clowns
|
|
292
|
+
RoboDoc
|
|
293
|
+
RoboGadget
|
|
294
|
+
Robot_7
|
|
295
|
+
Robot_B_9
|
|
296
|
+
Robot_Devil
|
|
297
|
+
Robot_Santa
|
|
298
|
+
Robot_ZX29B
|
|
299
|
+
Robotoid
|
|
300
|
+
Roderick
|
|
301
|
+
Rosie
|
|
302
|
+
Roy_Batty
|
|
303
|
+
Roz
|
|
304
|
+
ROZZUM_unit_7134
|
|
305
|
+
SAR_003
|
|
306
|
+
S1MONE
|
|
307
|
+
Samantha
|
|
308
|
+
Sapper_Morton
|
|
309
|
+
Sara
|
|
310
|
+
Scratch
|
|
311
|
+
Sentinels
|
|
312
|
+
Setaur
|
|
313
|
+
Sheen
|
|
314
|
+
Sheriff_Not_a_Robot
|
|
315
|
+
SHROUD
|
|
316
|
+
SI_9
|
|
317
|
+
Sico
|
|
318
|
+
SID_67
|
|
319
|
+
SIMON
|
|
320
|
+
Skutters
|
|
321
|
+
Solo
|
|
322
|
+
Sonny
|
|
323
|
+
Sox
|
|
324
|
+
Sparks
|
|
325
|
+
Speedy
|
|
326
|
+
Spofforth
|
|
327
|
+
Spot
|
|
328
|
+
Stitchpunks
|
|
329
|
+
Sulla
|
|
330
|
+
T_1000
|
|
331
|
+
T_600
|
|
332
|
+
T_800
|
|
333
|
+
T_850
|
|
334
|
+
T_Bob
|
|
335
|
+
T_X
|
|
336
|
+
Talkie_Toaster
|
|
337
|
+
TARS
|
|
338
|
+
Terminus
|
|
339
|
+
Tet
|
|
340
|
+
The_Automaton
|
|
341
|
+
The_Cast_Iron_Man
|
|
342
|
+
The_Electric_Grandmother
|
|
343
|
+
The_Fury
|
|
344
|
+
The_Golden_Army
|
|
345
|
+
The_Gunslinger
|
|
346
|
+
The_Hangman
|
|
347
|
+
The_Iron_Giant
|
|
348
|
+
The_Iron_Man
|
|
349
|
+
The_Juggernaut
|
|
350
|
+
The_Mechanical_Cow
|
|
351
|
+
The_Mechanical_Dummy
|
|
352
|
+
The_Mechanical_Horse
|
|
353
|
+
The_Mechanical_Hound
|
|
354
|
+
The_One_Who_Waits
|
|
355
|
+
Tin_Man
|
|
356
|
+
Tik_Tok
|
|
357
|
+
Tilk
|
|
358
|
+
Tilly
|
|
359
|
+
Tima
|
|
360
|
+
Toaster
|
|
361
|
+
Tobor
|
|
362
|
+
Tom
|
|
363
|
+
Tom_Servo
|
|
364
|
+
Tony
|
|
365
|
+
Torg
|
|
366
|
+
Trace_Mayter
|
|
367
|
+
Trurl
|
|
368
|
+
Twonky
|
|
369
|
+
Ultron
|
|
370
|
+
Ulyssses
|
|
371
|
+
UniBlab
|
|
372
|
+
US_47
|
|
373
|
+
VINCENT
|
|
374
|
+
Vahki
|
|
375
|
+
Val
|
|
376
|
+
Valerie_23
|
|
377
|
+
Vanessa_Kensington
|
|
378
|
+
VAQ_M
|
|
379
|
+
Victor
|
|
380
|
+
Vision
|
|
381
|
+
VN_GO
|
|
382
|
+
Voltron
|
|
383
|
+
WALL_E
|
|
384
|
+
Walter_One
|
|
385
|
+
Weebo
|
|
386
|
+
Wilmer
|
|
387
|
+
XJ_9
|
|
388
|
+
Yod
|
|
389
|
+
Z_1
|
|
390
|
+
Z_2
|
|
391
|
+
Z_3
|
|
392
|
+
Zane_Gort
|
|
393
|
+
Zat
|
|
394
|
+
Zhora
|
|
395
|
+
Zoromes
|
|
396
|
+
].freeze
|
|
397
|
+
# rubocop:enable Metrics/CollectionLiteralLength
|
|
398
|
+
|
|
399
|
+
def self.name = names.first
|
|
400
|
+
def self.names(how_many = 1) = NAMES.sample(how_many).sort
|
|
401
|
+
end
|
|
402
|
+
# rubocop:enable Metrics/ModuleLength
|
|
@@ -90,9 +90,7 @@ module RobotLab
|
|
|
90
90
|
#
|
|
91
91
|
# @return [String, nil]
|
|
92
92
|
def current_agent_skill_instructions
|
|
93
|
-
|
|
94
|
-
sys = messages&.find { |m| m.role.to_s == "system" }
|
|
95
|
-
sys&.content
|
|
93
|
+
current_system_instructions
|
|
96
94
|
end
|
|
97
95
|
end
|
|
98
96
|
end
|
|
@@ -12,9 +12,15 @@ module RobotLab
|
|
|
12
12
|
# == Delivery Serialization
|
|
13
13
|
#
|
|
14
14
|
# TypedBus delivers messages in concurrent Async fibers. Robots
|
|
15
|
-
# enqueue deliveries into a BusPoller rather than
|
|
16
|
-
#
|
|
17
|
-
#
|
|
15
|
+
# enqueue deliveries into a shared BusPoller rather than dispatching
|
|
16
|
+
# them straight to the handler. Despite the name, BusPoller runs no
|
|
17
|
+
# background thread: `enqueue` processes the delivery inline in the
|
|
18
|
+
# caller's own execution context (Async fiber or OS thread) when the
|
|
19
|
+
# robot is idle, and otherwise queues it behind the delivery already
|
|
20
|
+
# in flight and drains it once that one returns. A mutex therefore
|
|
21
|
+
# serializes deliveries per robot, so a robot's run() calls never
|
|
22
|
+
# interleave — but nothing makes progress while the calling fiber is
|
|
23
|
+
# parked.
|
|
18
24
|
#
|
|
19
25
|
# Owns: @bus, @bus_poller, @private_bus_poller, @bus_poller_group, @bus_subscriber_id, @message_counter, @outbox, @message_handler
|
|
20
26
|
# Reads: @name
|
|
@@ -78,8 +84,9 @@ module RobotLab
|
|
|
78
84
|
# counterpart to how a Cyborg answers its human — one call makes any bus
|
|
79
85
|
# member a first-class responder instead of hand-wiring {#on_message}.
|
|
80
86
|
#
|
|
81
|
-
# The responder runs
|
|
82
|
-
#
|
|
87
|
+
# The responder runs inline in the caller's execution context (BusPoller has
|
|
88
|
+
# no drain thread), and deliveries to this member are serialized, so a long
|
|
89
|
+
# turn blocks both the sender and the next inbound message.
|
|
83
90
|
#
|
|
84
91
|
# @param auto_reply [Boolean] send the responder's result back to the sender
|
|
85
92
|
# @yield [message] the inbound task; return the reply content (nil => no reply)
|
|
@@ -165,8 +172,9 @@ module RobotLab
|
|
|
165
172
|
|
|
166
173
|
# Assign a shared BusPoller from a Network.
|
|
167
174
|
#
|
|
168
|
-
#
|
|
169
|
-
# the network's shared poller for the given group.
|
|
175
|
+
# Drops any private poller this robot auto-created, then adopts
|
|
176
|
+
# the network's shared poller for the given group. Called by
|
|
177
|
+
# Network#task; groups are informational labels only.
|
|
170
178
|
#
|
|
171
179
|
# @param poller [BusPoller] the network's shared poller
|
|
172
180
|
# @param group [Symbol] poller group for this robot (default: :default)
|
|
@@ -223,7 +231,7 @@ module RobotLab
|
|
|
223
231
|
@bus_poller.enqueue(robot: self, delivery: delivery, group: @bus_poller_group)
|
|
224
232
|
end
|
|
225
233
|
|
|
226
|
-
# Process a single delivery (called by BusPoller drain
|
|
234
|
+
# Process a single delivery (called by BusPoller during its inline drain).
|
|
227
235
|
def process_delivery(delivery)
|
|
228
236
|
message = delivery.message
|
|
229
237
|
correlate_reply(message) if message.reply?
|
|
@@ -64,6 +64,10 @@ module RobotLab
|
|
|
64
64
|
|
|
65
65
|
# Re-render the template with run-time context merged into build-time context.
|
|
66
66
|
# prompt_manager parameters may be required (null) and only available at run time.
|
|
67
|
+
#
|
|
68
|
+
# Re-rendering replaces the system message, so the inline system_prompt must be
|
|
69
|
+
# re-appended here exactly as apply_system_prompt does at construction --
|
|
70
|
+
# otherwise it would be silently dropped on any run that supplies context.
|
|
67
71
|
def rerender_template(run_context)
|
|
68
72
|
merged = (@build_context || {}).merge(run_context)
|
|
69
73
|
resolved_ctx = resolve_context(merged, network: nil)
|
|
@@ -81,15 +85,24 @@ module RobotLab
|
|
|
81
85
|
bodies << body if body
|
|
82
86
|
end
|
|
83
87
|
|
|
84
|
-
|
|
85
|
-
@chat.with_instructions(combined)
|
|
88
|
+
@chat.with_instructions(with_system_prompt_appended(bodies.join("\n\n")))
|
|
86
89
|
else
|
|
87
90
|
parsed = PM.parse(@template)
|
|
88
91
|
rendered = parsed.to_s(**resolved_ctx)
|
|
89
|
-
@chat.with_instructions(rendered)
|
|
92
|
+
@chat.with_instructions(with_system_prompt_appended(rendered))
|
|
90
93
|
end
|
|
91
94
|
end
|
|
92
95
|
|
|
96
|
+
# Append the inline system_prompt to freshly rendered template text.
|
|
97
|
+
#
|
|
98
|
+
# @param rendered [String] newly rendered template body
|
|
99
|
+
# @return [String] rendered text with system_prompt appended, if one is set
|
|
100
|
+
def with_system_prompt_appended(rendered)
|
|
101
|
+
return rendered unless @system_prompt
|
|
102
|
+
|
|
103
|
+
[rendered, @system_prompt].reject { |s| s.to_s.empty? }.join("\n\n")
|
|
104
|
+
end
|
|
105
|
+
|
|
93
106
|
# Orchestrate skill expansion and template application.
|
|
94
107
|
#
|
|
95
108
|
# @param skill_ids [Array<Symbol>] skill IDs from constructor + front matter
|
data/lib/robot_lab/robot.rb
CHANGED
|
@@ -666,8 +666,27 @@ module RobotLab
|
|
|
666
666
|
end
|
|
667
667
|
end
|
|
668
668
|
|
|
669
|
+
# Append the inline system prompt to whatever apply_template already set.
|
|
670
|
+
#
|
|
671
|
+
# The template renders first and establishes the base instructions; the
|
|
672
|
+
# inline system_prompt is appended so both survive. Combining into a single
|
|
673
|
+
# system message (rather than using with_instructions(append: true), which
|
|
674
|
+
# adds a second one) keeps readers that look at only the first system
|
|
675
|
+
# message -- notably AgentSkillMatching's snapshot/restore -- correct.
|
|
669
676
|
def apply_system_prompt
|
|
670
|
-
|
|
677
|
+
return unless @system_prompt
|
|
678
|
+
|
|
679
|
+
base = current_system_instructions.to_s
|
|
680
|
+
combined = [base, @system_prompt].reject(&:empty?).join("\n\n")
|
|
681
|
+
@chat.with_instructions(combined)
|
|
682
|
+
end
|
|
683
|
+
|
|
684
|
+
# Content of the chat's system message, or nil when none is set.
|
|
685
|
+
#
|
|
686
|
+
# @return [String, nil]
|
|
687
|
+
def current_system_instructions
|
|
688
|
+
messages = @chat.instance_variable_get(:@messages)
|
|
689
|
+
messages&.find { |m| m.role.to_s == "system" }&.content
|
|
671
690
|
end
|
|
672
691
|
|
|
673
692
|
def apply_chat_params
|
|
@@ -757,7 +776,9 @@ module RobotLab
|
|
|
757
776
|
# is the definitive choke point: tools are fully resolved (MCP connected)
|
|
758
777
|
# and about to be handed to the chat, so the cap holds no matter how the
|
|
759
778
|
# tools were configured, filtered, or connected. Cap value comes from
|
|
760
|
-
# RunConfig#max_tools, defaulting to DEFAULT_MAX_TOOLS; nil
|
|
779
|
+
# RunConfig#max_tools, defaulting to DEFAULT_MAX_TOOLS; a nil, zero, or
|
|
780
|
+
# negative max_tools falls back to that default, so the cap cannot be
|
|
781
|
+
# disabled from configuration.
|
|
761
782
|
#
|
|
762
783
|
# @param tools [Array<Tool>] the resolved tools
|
|
763
784
|
# @return [Array<Tool>] at most `max_tools` tools
|
data/lib/robot_lab/version.rb
CHANGED
data/lib/robot_lab.rb
CHANGED
|
@@ -24,9 +24,9 @@ require 'typed_bus'
|
|
|
24
24
|
#
|
|
25
25
|
# @example Creating a network of robots
|
|
26
26
|
# network = RobotLab.create_network(name: "pipeline") do
|
|
27
|
-
#
|
|
28
|
-
#
|
|
29
|
-
#
|
|
27
|
+
# task :analyzer, analyzer, depends_on: :none
|
|
28
|
+
# task :writer, writer, depends_on: [:analyzer]
|
|
29
|
+
# task :reviewer, reviewer, depends_on: [:writer]
|
|
30
30
|
# end
|
|
31
31
|
# result = network.run(message: "Process this document")
|
|
32
32
|
#
|
|
@@ -35,7 +35,7 @@ require 'typed_bus'
|
|
|
35
35
|
# # ROBOT_LAB_DEFAULT_MODEL=gpt-4
|
|
36
36
|
# # ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY=sk-ant-...
|
|
37
37
|
#
|
|
38
|
-
# # Or via config files (~/.config/robot_lab/
|
|
38
|
+
# # Or via config files (~/.config/robot_lab/robot_lab.yml or ./config/robot_lab.yml)
|
|
39
39
|
# # See lib/robot_lab/config/defaults.yml for all options
|
|
40
40
|
#
|
|
41
41
|
# # Access configuration values:
|
|
@@ -47,6 +47,7 @@ end
|
|
|
47
47
|
|
|
48
48
|
loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
|
|
49
49
|
loader.ignore("#{__dir__}/robot_lab/robot")
|
|
50
|
+
loader.ignore("#{__dir__}/robot_lab/names.rb")
|
|
50
51
|
|
|
51
52
|
# Custom inflections for classes that don't follow Zeitwerk naming conventions
|
|
52
53
|
loader.inflector.inflect(
|
|
@@ -71,6 +72,11 @@ require_relative 'robot_lab/hooks'
|
|
|
71
72
|
require_relative 'robot_lab/message'
|
|
72
73
|
require_relative 'robot_lab/memory'
|
|
73
74
|
|
|
75
|
+
# names.rb defines the NAMES data constant plus helper methods directly on
|
|
76
|
+
# RobotLab, not a RobotLab::Names class/module, so Zeitwerk can't autoload it
|
|
77
|
+
# by convention — ignored above and required explicitly instead.
|
|
78
|
+
require_relative 'robot_lab/names'
|
|
79
|
+
|
|
74
80
|
# Eager load everything in Rails or when explicitly requested.
|
|
75
81
|
# Otherwise Zeitwerk's lazy autoloading keeps boot fast.
|
|
76
82
|
loader.eager_load if defined?(Rails::Engine) || ENV["ROBOT_LAB_EAGER_LOAD"]
|
|
@@ -145,7 +151,7 @@ module RobotLab
|
|
|
145
151
|
# Configuration is automatically loaded from:
|
|
146
152
|
# - Bundled defaults (lib/robot_lab/config/defaults.yml)
|
|
147
153
|
# - Environment-specific overrides (development, test, production)
|
|
148
|
-
# - XDG config
|
|
154
|
+
# - XDG config file (~/.config/robot_lab/robot_lab.yml)
|
|
149
155
|
# - Project config (./config/robot_lab.yml)
|
|
150
156
|
# - Environment variables (ROBOT_LAB_*)
|
|
151
157
|
#
|
|
@@ -246,28 +252,28 @@ module RobotLab
|
|
|
246
252
|
#
|
|
247
253
|
# @param name [String] the unique identifier for the network
|
|
248
254
|
# @param concurrency [Symbol] concurrency model (:auto, :threads, :async)
|
|
249
|
-
# @yield Block for defining pipeline
|
|
255
|
+
# @yield Block for defining pipeline tasks (the DSL method is `task`)
|
|
250
256
|
# @return [Network] a new Network instance
|
|
251
257
|
#
|
|
252
258
|
# @example Sequential pipeline
|
|
253
259
|
# network = RobotLab.create_network(name: "pipeline") do
|
|
254
|
-
#
|
|
255
|
-
#
|
|
260
|
+
# task :first, robot1, depends_on: :none
|
|
261
|
+
# task :second, robot2, depends_on: [:first]
|
|
256
262
|
# end
|
|
257
263
|
#
|
|
258
264
|
# @example With optional routing
|
|
259
265
|
# network = RobotLab.create_network(name: "support") do
|
|
260
|
-
#
|
|
261
|
-
#
|
|
262
|
-
#
|
|
266
|
+
# task :classifier, classifier, depends_on: :none
|
|
267
|
+
# task :billing, billing_robot, depends_on: :optional
|
|
268
|
+
# task :technical, technical_robot, depends_on: :optional
|
|
263
269
|
# end
|
|
264
270
|
#
|
|
265
271
|
# @example Parallel execution
|
|
266
272
|
# network = RobotLab.create_network(name: "analysis") do
|
|
267
|
-
#
|
|
268
|
-
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
273
|
+
# task :fetch, fetcher, depends_on: :none
|
|
274
|
+
# task :sentiment, sentiment_bot, depends_on: [:fetch]
|
|
275
|
+
# task :entities, entity_bot, depends_on: [:fetch]
|
|
276
|
+
# task :merge, merger, depends_on: [:sentiment, :entities]
|
|
271
277
|
# end
|
|
272
278
|
def create_network(name:, concurrency: :auto, config: nil, &)
|
|
273
279
|
Network.new(name: name, concurrency: concurrency, config: config, &)
|
data/mkdocs.yml
CHANGED
|
@@ -177,10 +177,15 @@ nav:
|
|
|
177
177
|
- Core Classes:
|
|
178
178
|
- api/core/index.md
|
|
179
179
|
- Robot: api/core/robot.md
|
|
180
|
+
- RobotResult: api/core/result.md
|
|
180
181
|
- Network: api/core/network.md
|
|
181
|
-
- State: api/core/state.md
|
|
182
182
|
- Tool: api/core/tool.md
|
|
183
183
|
- Memory: api/core/memory.md
|
|
184
|
+
- StateProxy: api/core/state.md
|
|
185
|
+
- Hooks: api/hooks.md
|
|
186
|
+
- Skills: api/skills.md
|
|
187
|
+
- Support Classes: api/support.md
|
|
188
|
+
- Errors: api/errors.md
|
|
184
189
|
- Messages:
|
|
185
190
|
- api/messages/index.md
|
|
186
191
|
- UserMessage: api/messages/user-message.md
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: robot_lab
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dewayne VanHoozer
|
|
@@ -235,6 +235,7 @@ files:
|
|
|
235
235
|
- docs/api/core/state.md
|
|
236
236
|
- docs/api/core/tool.md
|
|
237
237
|
- docs/api/errors.md
|
|
238
|
+
- docs/api/hooks.md
|
|
238
239
|
- docs/api/index.md
|
|
239
240
|
- docs/api/mcp/client.md
|
|
240
241
|
- docs/api/mcp/index.md
|
|
@@ -245,9 +246,11 @@ files:
|
|
|
245
246
|
- docs/api/messages/tool-call-message.md
|
|
246
247
|
- docs/api/messages/tool-result-message.md
|
|
247
248
|
- docs/api/messages/user-message.md
|
|
249
|
+
- docs/api/skills.md
|
|
248
250
|
- docs/api/streaming/context.md
|
|
249
251
|
- docs/api/streaming/events.md
|
|
250
252
|
- docs/api/streaming/index.md
|
|
253
|
+
- docs/api/support.md
|
|
251
254
|
- docs/architecture/core-concepts.md
|
|
252
255
|
- docs/architecture/index.md
|
|
253
256
|
- docs/architecture/message-flow.md
|
|
@@ -295,6 +298,7 @@ files:
|
|
|
295
298
|
- examples/13_spawn.rb
|
|
296
299
|
- examples/14_rusty_circuit/.envrc
|
|
297
300
|
- examples/14_rusty_circuit/.gitignore
|
|
301
|
+
- examples/14_rusty_circuit/README.md
|
|
298
302
|
- examples/14_rusty_circuit/comic.rb
|
|
299
303
|
- examples/14_rusty_circuit/display.rb
|
|
300
304
|
- examples/14_rusty_circuit/heckler.rb
|
|
@@ -473,6 +477,7 @@ files:
|
|
|
473
477
|
- lib/robot_lab/memory.rb
|
|
474
478
|
- lib/robot_lab/memory_change.rb
|
|
475
479
|
- lib/robot_lab/message.rb
|
|
480
|
+
- lib/robot_lab/names.rb
|
|
476
481
|
- lib/robot_lab/narrator.rb
|
|
477
482
|
- lib/robot_lab/network.rb
|
|
478
483
|
- lib/robot_lab/robot.rb
|
|
@@ -536,7 +541,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
536
541
|
- !ruby/object:Gem::Version
|
|
537
542
|
version: '0'
|
|
538
543
|
requirements: []
|
|
539
|
-
rubygems_version: 4.0.
|
|
544
|
+
rubygems_version: 4.0.19
|
|
540
545
|
specification_version: 4
|
|
541
546
|
summary: Ruby framework for building and orchestrating multi-robot LLM workflows
|
|
542
547
|
test_files: []
|