robot_lab 0.0.1 → 0.0.4

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.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/deploy-github-pages.yml +9 -9
  3. data/.irbrc +6 -0
  4. data/CHANGELOG.md +90 -0
  5. data/README.md +203 -46
  6. data/Rakefile +70 -1
  7. data/docs/api/core/index.md +12 -0
  8. data/docs/api/core/robot.md +478 -130
  9. data/docs/api/core/tool.md +205 -209
  10. data/docs/api/history/active-record-adapter.md +174 -94
  11. data/docs/api/history/config.md +186 -93
  12. data/docs/api/history/index.md +57 -61
  13. data/docs/api/history/thread-manager.md +123 -73
  14. data/docs/api/mcp/client.md +119 -48
  15. data/docs/api/mcp/index.md +75 -60
  16. data/docs/api/mcp/server.md +120 -136
  17. data/docs/api/mcp/transports.md +172 -184
  18. data/docs/api/streaming/context.md +157 -74
  19. data/docs/api/streaming/events.md +114 -166
  20. data/docs/api/streaming/index.md +74 -72
  21. data/docs/architecture/core-concepts.md +361 -112
  22. data/docs/architecture/index.md +97 -59
  23. data/docs/architecture/message-flow.md +138 -129
  24. data/docs/architecture/network-orchestration.md +197 -50
  25. data/docs/architecture/robot-execution.md +199 -146
  26. data/docs/architecture/state-management.md +255 -187
  27. data/docs/concepts.md +312 -48
  28. data/docs/examples/basic-chat.md +89 -77
  29. data/docs/examples/index.md +222 -47
  30. data/docs/examples/mcp-server.md +207 -203
  31. data/docs/examples/multi-robot-network.md +129 -35
  32. data/docs/examples/rails-application.md +159 -160
  33. data/docs/examples/tool-usage.md +295 -204
  34. data/docs/getting-started/configuration.md +275 -162
  35. data/docs/getting-started/index.md +1 -1
  36. data/docs/getting-started/installation.md +22 -13
  37. data/docs/getting-started/quick-start.md +166 -121
  38. data/docs/guides/building-robots.md +417 -212
  39. data/docs/guides/creating-networks.md +94 -24
  40. data/docs/guides/mcp-integration.md +152 -113
  41. data/docs/guides/memory.md +220 -164
  42. data/docs/guides/streaming.md +80 -110
  43. data/docs/guides/using-tools.md +259 -212
  44. data/docs/index.md +50 -37
  45. data/examples/01_simple_robot.rb +6 -9
  46. data/examples/02_tools.rb +6 -9
  47. data/examples/03_network.rb +13 -14
  48. data/examples/04_mcp.rb +5 -8
  49. data/examples/05_streaming.rb +5 -8
  50. data/examples/06_prompt_templates.rb +42 -37
  51. data/examples/07_network_memory.rb +13 -14
  52. data/examples/08_llm_config.rb +140 -0
  53. data/examples/09_chaining.rb +223 -0
  54. data/examples/10_memory.rb +331 -0
  55. data/examples/11_network_introspection.rb +230 -0
  56. data/examples/12_message_bus.rb +74 -0
  57. data/examples/13_spawn.rb +90 -0
  58. data/examples/14_rusty_circuit/comic.rb +143 -0
  59. data/examples/14_rusty_circuit/display.rb +203 -0
  60. data/examples/14_rusty_circuit/heckler.rb +57 -0
  61. data/examples/14_rusty_circuit/open_mic.rb +121 -0
  62. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +20 -0
  63. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +23 -0
  64. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +20 -0
  65. data/examples/14_rusty_circuit/scout.rb +173 -0
  66. data/examples/14_rusty_circuit/scout_notes.md +89 -0
  67. data/examples/14_rusty_circuit/show.log +234 -0
  68. data/examples/15_memory_network_and_bus/editor_in_chief.rb +24 -0
  69. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +206 -0
  70. data/examples/15_memory_network_and_bus/linux_writer.rb +80 -0
  71. data/examples/15_memory_network_and_bus/os_editor.rb +46 -0
  72. data/examples/15_memory_network_and_bus/os_writer.rb +46 -0
  73. data/examples/15_memory_network_and_bus/output/combined_article.md +13 -0
  74. data/examples/15_memory_network_and_bus/output/final_article.md +15 -0
  75. data/examples/15_memory_network_and_bus/output/linux_draft.md +5 -0
  76. data/examples/15_memory_network_and_bus/output/mac_draft.md +7 -0
  77. data/examples/15_memory_network_and_bus/output/memory.json +13 -0
  78. data/examples/15_memory_network_and_bus/output/revision_1.md +19 -0
  79. data/examples/15_memory_network_and_bus/output/revision_2.md +15 -0
  80. data/examples/15_memory_network_and_bus/output/windows_draft.md +7 -0
  81. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +13 -0
  82. data/examples/15_memory_network_and_bus/prompts/os_chief.md +13 -0
  83. data/examples/15_memory_network_and_bus/prompts/os_editor.md +13 -0
  84. data/examples/README.md +197 -0
  85. data/examples/prompts/{assistant/system.txt.erb → assistant.md} +3 -0
  86. data/examples/prompts/{billing/system.txt.erb → billing.md} +3 -0
  87. data/examples/prompts/{classifier/system.txt.erb → classifier.md} +3 -0
  88. data/examples/prompts/comedian.md +6 -0
  89. data/examples/prompts/comedy_critic.md +10 -0
  90. data/examples/prompts/configurable.md +9 -0
  91. data/examples/prompts/dispatcher.md +12 -0
  92. data/examples/prompts/{entity_extractor/system.txt.erb → entity_extractor.md} +3 -0
  93. data/examples/prompts/{escalation/system.txt.erb → escalation.md} +7 -0
  94. data/examples/prompts/frontmatter_mcp_test.md +9 -0
  95. data/examples/prompts/frontmatter_named_test.md +5 -0
  96. data/examples/prompts/frontmatter_tools_test.md +6 -0
  97. data/examples/prompts/{general/system.txt.erb → general.md} +3 -0
  98. data/examples/prompts/{github_assistant/system.txt.erb → github_assistant.md} +8 -0
  99. data/examples/prompts/{helper/system.txt.erb → helper.md} +3 -0
  100. data/examples/prompts/{keyword_extractor/system.txt.erb → keyword_extractor.md} +3 -0
  101. data/examples/prompts/llm_config_demo.md +20 -0
  102. data/examples/prompts/{order_support/system.txt.erb → order_support.md} +8 -0
  103. data/examples/prompts/os_advocate.md +13 -0
  104. data/examples/prompts/os_chief.md +13 -0
  105. data/examples/prompts/os_editor.md +13 -0
  106. data/examples/prompts/{product_support/system.txt.erb → product_support.md} +7 -0
  107. data/examples/prompts/{sentiment_analyzer/system.txt.erb → sentiment_analyzer.md} +3 -0
  108. data/examples/prompts/{synthesizer/system.txt.erb → synthesizer.md} +3 -0
  109. data/examples/prompts/{technical/system.txt.erb → technical.md} +3 -0
  110. data/examples/prompts/{triage/system.txt.erb → triage.md} +6 -0
  111. data/lib/generators/robot_lab/templates/initializer.rb.tt +1 -1
  112. data/lib/robot_lab/adapters/openai.rb +2 -1
  113. data/lib/robot_lab/ask_user.rb +75 -0
  114. data/lib/robot_lab/config/defaults.yml +121 -0
  115. data/lib/robot_lab/config.rb +183 -0
  116. data/lib/robot_lab/error.rb +6 -0
  117. data/lib/robot_lab/mcp/client.rb +1 -1
  118. data/lib/robot_lab/memory.rb +2 -2
  119. data/lib/robot_lab/robot.rb +523 -249
  120. data/lib/robot_lab/robot_message.rb +44 -0
  121. data/lib/robot_lab/robot_result.rb +1 -0
  122. data/lib/robot_lab/robotic_model.rb +1 -1
  123. data/lib/robot_lab/streaming/context.rb +1 -1
  124. data/lib/robot_lab/tool.rb +108 -172
  125. data/lib/robot_lab/tool_config.rb +1 -1
  126. data/lib/robot_lab/tool_manifest.rb +2 -18
  127. data/lib/robot_lab/version.rb +1 -1
  128. data/lib/robot_lab.rb +66 -55
  129. metadata +107 -116
  130. data/examples/prompts/assistant/user.txt.erb +0 -1
  131. data/examples/prompts/billing/user.txt.erb +0 -1
  132. data/examples/prompts/classifier/user.txt.erb +0 -1
  133. data/examples/prompts/entity_extractor/user.txt.erb +0 -3
  134. data/examples/prompts/escalation/user.txt.erb +0 -34
  135. data/examples/prompts/general/user.txt.erb +0 -1
  136. data/examples/prompts/github_assistant/user.txt.erb +0 -1
  137. data/examples/prompts/helper/user.txt.erb +0 -1
  138. data/examples/prompts/keyword_extractor/user.txt.erb +0 -3
  139. data/examples/prompts/order_support/user.txt.erb +0 -22
  140. data/examples/prompts/product_support/user.txt.erb +0 -32
  141. data/examples/prompts/sentiment_analyzer/user.txt.erb +0 -3
  142. data/examples/prompts/synthesizer/user.txt.erb +0 -15
  143. data/examples/prompts/technical/user.txt.erb +0 -1
  144. data/examples/prompts/triage/user.txt.erb +0 -17
  145. data/lib/robot_lab/configuration.rb +0 -143
@@ -0,0 +1,89 @@
1
+ # Scout Notes — The Rusty Circuit
2
+
3
+ ## Round 1
4
+
5
+ NOTES: Standard opener - relatable premise (self-checkout frustration) but execution feels safe and predictable. The "incompetence" callback shows some self-awareness, and the credit score punchline lands adequately. However, the material feels very "first draft" - like observations everyone has but hasn't been elevated beyond the obvious.
6
+
7
+ Delivery seems tentative - that expectant look at the crowd suggests they're fishing for validation rather than confidently driving the room. The mic adjustment and setup felt a bit nervous. Too early to judge adaptability or crowd-handling since this is scripted opener material.
8
+
9
+ Withholding judgment on star potential - need to see how they handle the next few minutes when they move beyond their safest material. Looking for signs of unique voice, risk-taking, and whether they can build momentum from this foundation.
10
+
11
+ The premise has potential but needs sharper writing and more confident delivery. Watching for evolution as the set progresses.
12
+
13
+ ### Analyst: crowd_work
14
+
15
+ **Opening Analysis:** Solid relatable premise with good escalation from simple frustration to self-deprecating punchline about credit scores. The personification of the machine as "lady" adds character, but the expectant pause suggests uncertainty about audience reception.
16
+
17
+ **Crowd Work Analysis:** Excellent recovery that flips the heckle into material while maintaining control. The callback to "unexpected item" creates a cohesive thread and the broader life metaphor lands with philosophical weight that elevates the bit beyond just grocery store humor.
18
+
19
+ ## Round 2
20
+
21
+ The analyst confirms what I'm seeing - this comedian has the instinct to turn disruption into opportunity. That crowd work wasn't just damage control, it was material creation in real time. Watching closely for how they build from here.
22
+
23
+ ### Analyst: adaptability
24
+
25
+ Strong adaptive instincts on display here. The comedian skillfully transforms heckling into collaborative energy, using the "unexpected item" callback to create a unifying metaphor that includes the entire audience in the struggle. The venue-specific self-deprecation in Round 2 shows excellent room-reading skills, turning potential weakness into relatable strength while maintaining momentum through the disruption.
26
+
27
+ ## Round 3
28
+
29
+ The analyst confirms my assessment - this is someone who thrives on chaos. Three rounds in and they're not just surviving interruptions, they're using them as fuel. This adaptability under fire is exactly what network executives look for in potential stars.
30
+
31
+ ## Round 4
32
+
33
+ NOTES: This comedian just demonstrated something crucial - they know when to pivot. After three rounds of crowd/venue work, they smoothly transitioned back to prepared material without losing momentum. That's professional-level set management.
34
+
35
+ The "Michelin star for a gas station hot dog" line is genuinely clever writing - unexpected comparison that works on multiple levels. Shows they can craft material, not just react to situations. The credit score callback maintains continuity while moving the set forward.
36
+
37
+ But here's what's really impressive: that pause before the parking spot bit. They're reading the room's energy, letting the moment breathe, then shifting gears entirely. The mom hanging up punchline is relatable without being hacky - everyone knows that feeling of getting excited about mundane adult things.
38
+
39
+ Pattern solidified: This comedian has both reactive instincts AND structured material. They can work a crowd, handle disruption, acknowledge the venue's vibe, then seamlessly return to their prepared set. That's the mark of someone who understands comedy as both art and craft.
40
+
41
+ The genuine smile suggests they're actually enjoying this chaos rather than just surviving it. That joy is infectious - the room energy has completely shifted from skeptical to engaged.
42
+
43
+ Star potential is becoming clear. This is someone who could handle late-night TV, corporate gigs, or hostile crowds with equal skill.
44
+
45
+ ### Analyst: stage_presence
46
+
47
+ **Opening:** Solid relatable premise with good energy, but the delivery feels a bit rehearsed and the expectant pause telegraphs insecurity. The crowd interaction attempt comes off as needy rather than confident.
48
+
49
+ **Round 1:** Excellent heckler handling - you flipped the dynamic by making them part of the bit rather than fighting them. The "unexpected item in the bagging area of life" callback is clever and shows real comedic instincts.
50
+
51
+ **Rounds 2-4:** You found your rhythm by embracing the room's energy and building genuine rapport with both heckler and audience. The self-deprecating humor feels authentic now, and you're working WITH the room instead of AT it - that's when comedy magic happens.
52
+
53
+ ## Round 5
54
+
55
+ The analyst nails it - this comedian's stage presence evolved dramatically over the set. Started nervous, ended commanding. That transformation under fire is exactly what separates working comics from stars. This is someone I'd book tomorrow.
56
+
57
+ ---
58
+
59
+ ## Final Verdict
60
+
61
+ **FINAL TALENT ASSESSMENT - THE RUSTY CIRCUIT**
62
+
63
+ **RECOMMENDATION: IMMEDIATE CALLBACK - HIGH PRIORITY**
64
+
65
+ **What Worked:**
66
+ This comedian demonstrated the rarest quality in stand-up: they get BETTER under pressure. What started as a tentative, safe opener transformed into a masterclass in crowd control and comedic instincts. Key strengths:
67
+
68
+ - **Exceptional Adaptability**: Turned multiple heckles into material gold, showing they can handle any room
69
+ - **Crowd Work Mastery**: The "Stockholm syndrome with punchlines" callback was sophisticated writing in real-time
70
+ - **Venue Intelligence**: Used The Rusty Circuit's gritty reputation as material rather than apologizing for it
71
+ - **Quotable Writing**: "Navy SEALs of entertainment" and "unexpected item in the bagging area of life" are lines that stick
72
+ - **Authentic Voice**: Found the sweet spot between vulnerability and confidence
73
+
74
+ **What Didn't Work:**
75
+ - Opening material felt generic and over-rehearsed
76
+ - Initial delivery showed nerves and validation-seeking
77
+ - Took 2-3 minutes to find their authentic voice
78
+
79
+ **Star Potential:**
80
+ This comedian has the complete package for network success:
81
+ 1. **Resilience**: Thrives on chaos rather than crumbling
82
+ 2. **Versatility**: Can handle prepared material, crowd work, and venue-specific content seamlessly
83
+ 3. **Growth Mindset**: Visibly improved throughout the 5-round set
84
+ 4. **Professional Instincts**: Knows when to engage hecklers vs. when to pivot back to material
85
+
86
+ **Bottom Line:**
87
+ I've seen three headliners come from this room. This comedian has that same "it" factor - the ability to turn any situation into comedy gold. They're not just surviving difficult rooms, they're conquering them. That's exactly what we need for late-night spots, corporate gigs, and hostile festival crowds.
88
+
89
+ **Next Steps:** Book them for a showcase set immediately. This is someone who could be headlining within 18 months with proper development.
@@ -0,0 +1,234 @@
1
+
2
+ ============================================================
3
+ THE RUSTY CIRCUIT — Tuesday Open Mic
4
+ Architecture Dominates Material
5
+ ============================================================
6
+
7
+ Cast:
8
+ Comic — observational humor, armed with self-modification tools
9
+ Heckler — three-year regular, high standards, zero patience
10
+ Scout — talent network, sitting in the back with a notebook
11
+
12
+ ────────────────────────────────────────────────────────
13
+
14
+
15
+ Comic [Opening]:
16
+ *walks up to mic, adjusts it slightly*
17
+
18
+ So I was at the grocery store yesterday, and they
19
+ have those self-checkout machines now. You know what
20
+ I love about them? They're the only employee that
21
+ judges you for buying ice cream at 2 PM on a Tuesday.
22
+ "Unexpected item in bagging area" - yeah, it's my
23
+ life choices, Karen-bot. At least the human cashiers
24
+ pretend not to notice when I'm buying wine and cat
25
+ food... again.
26
+
27
+ *glances at crowd for reaction*
28
+
29
+
30
+ Heckler [Round 1]:
31
+ *from the back of the room*
32
+
33
+ Oh wow, self-checkout jokes! What's next, airline
34
+ food? Here's a thought - maybe the machine's
35
+ judging you because you're shopping in your
36
+ pajamas talking to robots about your drinking
37
+ problem!
38
+
39
+ [adjust_energy] -> 0.7 (Need to get edgier and more confrontational to match this crowd's energy - they want bite, not safe observational stuff)
40
+ Scout [Round 1]: NOTES: Strong opener - relatable premise with a modern twist on self-checkout frustration. Good observational comedy foundation. The "Karen-bot" line got a solid laugh - shows ability to blend current cultural references with universal experiences. Nice self-deprecating turn with the wine/cat food callback.
41
+
42
+ What caught my attention: The mic adjustment was confident, not nervous. The glance at the crowd shows awareness and connection-seeking. Material feels fresh enough - not the tired "self-checkout is confusing" angle, but the personification/judgment angle.
43
+
44
+ Early read: Solid technical foundation, relatable voice. Need to see how they handle transitions and whether they can build momentum beyond the opener. The self-deprecating element could be a strength if balanced right, or a limitation if it becomes the only note they can hit.
45
+
46
+ Watching for: Does the material deepen or stay surface-level? How do they handle the next transition? Can they read the room and adjust energy accordingly?
47
+
48
+ Too early for specialist analysis - want to see more material flow and crowd interaction patterns first.
49
+
50
+ Comic [Round 1]:
51
+ *turns toward the heckler with a grin*
52
+
53
+ Oh, you want fresh material? Here's something new - I
54
+ actually WAS in my pajamas, and yeah, I DO have a
55
+ drinking problem... it's that I keep running out! But
56
+ at least when I talk to robots, they don't interrupt
57
+ my set from the cheap seats. The machine said
58
+ "unexpected item" - turns out it was detecting your
59
+ personality from three aisles away!
60
+
61
+ *leans into the mic*
62
+
63
+
64
+ Heckler [Round 2]:
65
+ *sits back in chair, arms crossed*
66
+
67
+ Alright, alright... not bad. You actually
68
+ listened and fired back instead of just whining
69
+ about hecklers. The "detecting your personality"
70
+ bit was decent. Keep going, pajama boy - let's
71
+ see if you can maintain that energy without
72
+ leaning on the self-checkout crutch again.
73
+
74
+
75
+ Comic [Round 2]:
76
+ *grins and nods at the heckler*
77
+
78
+ You know what? I respect that. Most people here look
79
+ like they'd rather be at home watching Netflix, but
80
+ you're actually engaged. Speaking of home - I live
81
+ alone with my cat, Mr. Whiskers. Yeah, I named my cat
82
+ Mr. Whiskers because I'm apparently twelve years old.
83
+ But here's the thing - he's the only male in my life
84
+ who doesn't leave me on read. Sure, he ignores me
85
+ too, but at least he's honest about it. He just
86
+ stares at me like "Feed me or die, human." It's
87
+ refreshing compared to dating apps where everyone's
88
+ like "Looking for something real" then ghosts you
89
+ after you suggest meeting somewhere that isn't their
90
+ bedroom.
91
+
92
+ *looks back at the heckler*
93
+
94
+ How am I doing, coach?
95
+
96
+ [crowd_work_analyst] Strong opening premise with universal relatability - everyone's battled those self-checkout machines. The "Karen-bot" callback and escalation to wine/cat food creates a nice rhythm of mounting absurdity that lands well.
97
+
98
+ The heckler response shows excellent crowd work instincts - you flipped their energy by owning the roast while delivering a killer punchline about the machine "detecting your personality." That's how you turn disruption into material gold.
99
+
100
+ Heckler [Round 3]:
101
+ *leans forward slightly*
102
+
103
+ Better. The cat bit has legs - "feed me or die"
104
+ is solid, and the dating app contrast works.
105
+ You're finding your rhythm instead of just doing
106
+ crowd work. But don't ask me how you're doing -
107
+ that's needy comedian 101. Trust your material
108
+ and keep building on what's working.
109
+
110
+ Scout [Round 2]: The analyst confirms what I'm seeing - this performer has the instincts. They don't just handle disruption, they weaponize it. That callback integration was masterful. Need to see if this adaptability extends beyond hecklers to reading room energy and adjusting accordingly.
111
+
112
+ Comic [Round 3]:
113
+ *straightens up, drops the validation-seeking*
114
+
115
+ You're right. So Mr. Whiskers has better boundaries
116
+ than most humans I know. Last week I brought a date
117
+ home, and this cat literally sat between us on the
118
+ couch like a furry chaperone. Just staring. Not
119
+ blinking. My date goes "Is he always like this?" and
120
+ I said "Only when he senses desperation." Plot twist
121
+ - he was staring at me, not her. Even my own cat
122
+ knows I'm trying too hard. She left, but Mr. Whiskers
123
+ stayed. Rubbed against my leg like "Don't worry,
124
+ human. Your standards will drop eventually."
125
+
126
+ *pauses for effect*
127
+
128
+ That cat's got more game than I do.
129
+
130
+
131
+ Heckler [Round 4]:
132
+ *chuckles and shakes head*
133
+
134
+ Now you're cooking! "Only when he senses
135
+ desperation" - that's a real punchline. And the
136
+ cat being your wingman while simultaneously
137
+ roasting you? That's the kind of self-deprecating
138
+ stuff that actually works. You went from hack
139
+ grocery store material to something with actual
140
+ personality. Keep mining that gold, cat dad.
141
+
142
+ [adaptability_analyst] **Round 1**: Solid defensive pivot that turns the interruption into material while maintaining control. The "detecting your personality" callback is clever, but the energy feels slightly reactive rather than commanding.
143
+
144
+ **Round 2**: Excellent recovery - acknowledging the heckler while seamlessly weaving it into extended material about dating and loneliness. The "How am I doing, coach?" ending shows confidence and transforms the dynamic from confrontational to collaborative, demonstrating strong crowd work instincts.
145
+
146
+ Comic [Round 4]:
147
+ *riding the momentum, more confident now*
148
+
149
+ Cat dad - I like that. Mr. Whiskers has taught me
150
+ more about relationships than any self-help book.
151
+ Like, he's mastered the art of being completely
152
+ unavailable until HE wants attention. I'll be
153
+ working, ignoring him for hours, and suddenly he's on
154
+ my keyboard like "Notice me NOW." It's like he
155
+ studied every person I've ever dated. The difference
156
+ is when he's done with me, he just walks away with
157
+ dignity. No passive-aggressive texts, no "we need to
158
+ talk," just tail up, ass in my face, and he's gone.
159
+ I'm taking notes. Next time someone wants to break up
160
+ with me, I'm just gonna knock something off their
161
+ coffee table and leave.
162
+
163
+ *grins*
164
+
165
+ Mr. Whiskers: relationship guru and life coach.
166
+
167
+ Scout [Round 3]: The analyst confirms my read - this performer has exceptional adaptability. They're not just surviving disruptions, they're using them to build rapport and create a more engaging show. That "coach" callback was brilliant - it reframes the entire dynamic. This is headliner-level crowd management.
168
+
169
+ Pattern emerging: Strong technical skills, excellent people-reading ability, and the rare gift of turning obstacles into opportunities. Need to see how they close and whether they can maintain this energy throughout a full set.
170
+
171
+ Heckler [Round 5]:
172
+ *actually laughs out loud*
173
+
174
+ Okay, that's genuinely funny! "Knock something
175
+ off their coffee table and leave" - I'm stealing
176
+ that move. You found your voice, kid. This is
177
+ what happens when you stop trying to be every
178
+ comedian and start being yourself. Mr. Whiskers
179
+ bit is working because it's specific and honest.
180
+ Don't abandon this thread - you've got more in
181
+ there.
182
+
183
+ (won over!)
184
+ [material_evolution_analyst] **Round 1:** The defensive energy and validation-seeking ("How am I doing, coach?") kills momentum. The heckler callback works but you're letting them control your rhythm instead of using their energy to elevate your material.
185
+
186
+ **Round 2-3:** Much stronger evolution. You transformed genuine vulnerability (living alone, dating struggles) into relatable humor without self-pity. The cat-as-wingman/chaperone bit has real legs - that's material worth developing further.
187
+
188
+ **Key insight:** Your best moments come when you stop performing *at* the audience and start including them in your perspective. The self-deprecation lands when it feels authentic rather than desperate.
189
+ Scout [Round 4]: The analyst nailed it - this performer just found their groove. They went from seeking approval to commanding the room through authentic storytelling. The material evolution from scattered observations to cohesive narrative shows real writing chops.
190
+
191
+ This is the moment I look for - when a comedian stops trying to be funny and just IS funny. The confidence shift, the improved timing, the layered storytelling - this person has headliner potential. They just needed to get out of their own way.
192
+ [refine_criteria] -> Primary focus: Authentic voice discovery and sustained narrative building. Look for comedians who can transform personal vulnerability into universal insights while maintaining strong technical execution. Key indicators: ability to evolve material in real-time, confidence that builds throughout the set, and the rare skill of turning obstacles into opportunities. Secondary: crowd management instincts and the ability to create inclusive atmosphere while maintaining authority.
193
+ Scout [Round 5]: This performer just demonstrated everything I look for in a potential star. They found their authentic voice, built a cohesive narrative world, and showed the adaptability that separates headliners from club comics. The Mr. Whiskers character has become their signature - that's the kind of unique perspective that gets development deals.
194
+
195
+ Star potential: HIGH. This is someone I'd bring to the network.
196
+ ────────────────────────────────────────────────────────
197
+
198
+
199
+ Scout [FINAL VERDICT]:
200
+ **FINAL TALENT ASSESSMENT**
201
+
202
+ **RECOMMENDATION: STRONG CALLBACK - DEVELOPMENT POTENTIAL**
203
+
204
+ **What Worked:**
205
+ This comedian demonstrated the complete arc I look for in a star. They started with solid technical foundation but truly found their voice when challenged. The transformation from Round 2 onward was remarkable - moving from validation-seeking to authentic storytelling with the Mr. Whiskers character becoming a brilliant comedic vehicle.
206
+
207
+ Key strengths:
208
+ - **Exceptional adaptability**: Turned early heckling into collaborative energy, showing advanced crowd psychology
209
+ - **Real-time material evolution**: Each round built on the previous, creating a cohesive narrative rather than disconnected bits
210
+ - **Authentic vulnerability**: Transformed personal loneliness/dating struggles into universal insights without self-pity
211
+ - **Technical excellence**: Strong timing, effective callbacks, sophisticated punchline structure (especially the layered cat-judging-comedian reveal)
212
+ - **Crowd management mastery**: Created inclusive atmosphere while maintaining authority - the "coach" callback was genius-level relationship building
213
+
214
+ **What Didn't Work:**
215
+ Early rounds showed some validation-seeking behavior that killed momentum. The initial material, while competent, felt safe and familiar (self-checkout, dating apps). However, their ability to recognize and correct this mid-set actually demonstrates star-level self-awareness.
216
+
217
+ **Star Potential:**
218
+ HIGH. This performer has the rare combination of technical skill, authentic voice, and adaptability under pressure. The Mr. Whiskers character represents the kind of unique perspective that builds careers. They showed they can turn obstacles into opportunities - a crucial skill for television and touring.
219
+
220
+ **Development Notes:**
221
+ Ready for showcase opportunities. Would benefit from longer set time to fully develop the relationship guru cat concept. Strong candidate for writing room collaboration given their ability to build narrative worlds from personal experience.
222
+
223
+ **Bottom Line:** This is exactly the kind of authentic, adaptable talent we've been looking for. Book the callback.
224
+
225
+
226
+ ────────────────────────────────────────────────────────────
227
+ Show Stats:
228
+ Rounds performed: 5 (opening + 4 rounds)
229
+ Style reinventions: 0
230
+ Coaches spawned: 0
231
+ Analysts recruited: 3
232
+ Heckler won over: true
233
+ Total robots on bus: 6
234
+
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Editor-in-chief lives outside the pipeline, communicates only via bus.
4
+ # Reviews articles and responds with APPROVED or REVISE: feedback.
5
+ class EditorInChief < RobotLab::Robot
6
+ attr_reader :accepted, :rounds
7
+
8
+ def initialize(**opts)
9
+ super(**opts)
10
+ @accepted = false
11
+ @rounds = 0
12
+
13
+ on_message do |message|
14
+ @rounds += 1
15
+ verdict = run("Review this article:\n\n#{message.content}").reply.strip
16
+ @accepted = verdict.start_with?("APPROVED")
17
+ puts " Chief [round #{@rounds}]: #{verdict[0..120]}"
18
+
19
+ if !@accepted && @rounds < MAX_REVISIONS
20
+ send_message(to: :editor, content: "Revise this article. Feedback: #{verdict}")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Example 15: OS Research Editorial Pipeline — Network + Memory + Bus + Spawn
5
+ #
6
+ # Three writers advocate for different operating systems (macOS, Windows,
7
+ # Linux/BSD) for home AI research labs. The Linux writer spawns distro
8
+ # specialists. An editor synthesizes. An editor-in-chief gives final approval.
9
+ #
10
+ # This showcases all three coordination mechanisms working together:
11
+ #
12
+ # NETWORK (parallel pipeline + shared memory)
13
+ # ┌──────────────────────────────────────────────────────┐
14
+ # │ mac_writer ──┐ │
15
+ # │ win_writer ──┼── editor ──→ combined article │
16
+ # │ linux_writer ──┘ │
17
+ # │ └── spawns distro specialists via spawn() │
18
+ # │ │
19
+ # │ MEMORY carries drafts between stages │
20
+ # │ :mac_draft, :windows_draft, :linux_draft │
21
+ # └──────────────────────────────────────────────────────┘
22
+ # │
23
+ # BUS (review loop)
24
+ # │
25
+ # ┌─────┴──────┐
26
+ # │ chief │
27
+ # └────────────┘
28
+ #
29
+ # - NETWORK orchestrates 3 parallel writers → editor synthesis
30
+ # - MEMORY passes advocacy drafts between pipeline stages
31
+ # - BUS enables editor ↔ chief revision loop after pipeline
32
+ # - SPAWN creates distro specialists dynamically within pipeline
33
+ #
34
+ # Usage:
35
+ # bundle exec ruby examples/15_memory_network_and_bus/editorial_pipeline.rb
36
+
37
+ ENV["ROBOT_LAB_TEMPLATE_PATH"] ||= File.join(__dir__, "prompts")
38
+
39
+ require_relative "../../lib/robot_lab"
40
+ require "fileutils"
41
+
42
+ RubyLLM.configure { |c| c.logger = Logger.new(File::NULL) }
43
+
44
+ MAX_REVISIONS = 3
45
+ OUTPUT_DIR = File.join(__dir__, "output")
46
+
47
+ FileUtils.mkdir_p(OUTPUT_DIR)
48
+
49
+ # ── Load robot classes ────────────────────────────────────
50
+
51
+ require_relative "os_writer"
52
+ require_relative "linux_writer"
53
+ require_relative "os_editor"
54
+ require_relative "editor_in_chief"
55
+
56
+ # ── Build Everything ──────────────────────────────────────
57
+
58
+ bus = TypedBus::MessageBus.new
59
+
60
+ mac_writer = OsWriter.new(
61
+ name: "mac_writer",
62
+ template: :os_advocate,
63
+ local_tools: [RobotLab::AskUser],
64
+ context: {
65
+ os_name: "macOS",
66
+ strengths: "Apple Silicon (M-series) performance, Metal GPU framework, Unix foundation, CoreML integration, energy efficiency"
67
+ },
68
+ memory_key: :mac_draft
69
+ )
70
+
71
+ win_writer = OsWriter.new(
72
+ name: "win_writer",
73
+ template: :os_advocate,
74
+ local_tools: [RobotLab::AskUser],
75
+ context: {
76
+ os_name: "Windows",
77
+ strengths: "NVIDIA CUDA first-class support, WSL2 Linux compatibility, DirectML, widest hardware selection, enterprise tool integration"
78
+ },
79
+ memory_key: :windows_draft
80
+ )
81
+
82
+ linux_writer = LinuxWriter.new(
83
+ name: "linux_writer",
84
+ template: :os_advocate,
85
+ local_tools: [RobotLab::AskUser],
86
+ context: {
87
+ os_name: "Linux/BSD",
88
+ strengths: "Full GPU stack control, Docker-native, free and open source, server parity, massive community packages"
89
+ },
90
+ memory_key: :linux_draft,
91
+ bus: bus
92
+ )
93
+
94
+ editor = OsEditor.new(
95
+ name: "editor",
96
+ template: :os_editor,
97
+ bus: bus
98
+ )
99
+
100
+ # Editor handles revision requests from the chief via bus
101
+ revision_count = 0
102
+ editor.on_message do |message|
103
+ revised = editor.run(message.content).reply.strip
104
+ editor.instance_variable_set(:@article, revised)
105
+
106
+ revision_count += 1
107
+ path = File.join(OUTPUT_DIR, "revision_#{revision_count}.md")
108
+ File.write(path, "# Revision #{revision_count}\n\n#{revised}\n")
109
+ puts " Editor [revised]: #{revised[0..120]}..."
110
+ puts " [editor] Revision written to #{path}"
111
+
112
+ editor.reply(message, revised)
113
+ end
114
+
115
+ chief = EditorInChief.new(
116
+ name: "chief",
117
+ template: :os_chief,
118
+ bus: bus
119
+ )
120
+
121
+ # Network orchestrates the writing pipeline
122
+ network = RobotLab.create_network(name: "os_editorial") do
123
+ task :mac_writer, mac_writer, depends_on: :none
124
+ task :win_writer, win_writer, depends_on: :none
125
+ task :linux_writer, linux_writer, depends_on: :none
126
+ task :editor, editor, depends_on: [:mac_writer, :win_writer, :linux_writer]
127
+ end
128
+
129
+ # Give each pipeline robot a direct reference to shared memory.
130
+ # extract_run_context's delete() pattern mutates the shared run_params
131
+ # hash, so parallel steps lose network_memory after the first one runs.
132
+ shared_memory = network.memory
133
+ [mac_writer, win_writer, linux_writer, editor].each do |robot|
134
+ robot.shared_memory = shared_memory
135
+ end
136
+
137
+ # Monitor shared memory changes during the pipeline
138
+ network.memory.subscribe(
139
+ :mac_draft, :windows_draft, :linux_draft,
140
+ :ubuntu_specialist, :fedora_specialist, :freebsd_specialist
141
+ ) do |change|
142
+ puts " [memory] :#{change.key} updated by #{change.writer}"
143
+ end
144
+
145
+ # ── Run ──────────────────────────────────────────────────────
146
+
147
+ puts "=" * 60
148
+ puts "Example 15: OS Research Editorial Pipeline"
149
+ puts " Network + Memory + Bus + Spawn"
150
+ puts "=" * 60
151
+ puts
152
+ puts network.visualize
153
+ puts
154
+
155
+ # ── Phase 1: Writing Pipeline (Network + Memory + Spawn) ──
156
+
157
+ puts "Phase 1: Writing Pipeline (Network + Memory + Spawn)"
158
+ puts "-" * 40
159
+
160
+ # Gather the research focus from the user via AskUser
161
+ ask = RobotLab::AskUser.new
162
+ focus = ask.call(
163
+ "question" => "What AI research focus areas for the home lab article?",
164
+ "default" => "LLM fine-tuning, image generation, and local inference"
165
+ )
166
+
167
+ topic = "Write about your operating system's advantages for building a home AI research lab focused on #{focus}."
168
+
169
+ result = network.run(message: topic)
170
+ article = editor.article
171
+
172
+ puts
173
+ puts " Article excerpt: #{article[0..200]}..." if article
174
+ puts
175
+ puts " Memory keys: #{network.memory.keys.join(', ')}"
176
+ puts " Specialists spawned: #{linux_writer.specialists.size}"
177
+
178
+ # ── Phase 2: Editorial Review (Bus) ──────────────────────
179
+
180
+ puts
181
+ puts "Phase 2: Editorial Review (Bus)"
182
+ puts "-" * 40
183
+
184
+ # Chief reviews the article via bus — may trigger revision loop
185
+ chief.send_message(to: :editor, content: article)
186
+
187
+ final_article = editor.article
188
+ final_path = File.join(OUTPUT_DIR, "final_article.md")
189
+ status = chief.accepted ? "APPROVED" : "NOT APPROVED (max revisions reached)"
190
+ File.write(final_path, "# Final Article — #{status}\n\n#{final_article}\n")
191
+
192
+ puts
193
+ puts "-" * 60
194
+ puts "Revisions: #{chief.rounds} | Accepted: #{chief.accepted}"
195
+ puts "Specialists spawned: #{linux_writer.specialists.size}"
196
+ puts "Output directory: #{OUTPUT_DIR}"
197
+ puts "=" * 60
198
+
199
+ puts
200
+
201
+ require "json"
202
+
203
+ memory_path = File.join(OUTPUT_DIR, "memory.json")
204
+ File.write(memory_path, JSON.pretty_generate(shared_memory.to_h))
205
+ puts
206
+ puts "Memory written to #{memory_path}"
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Linux writer spawns distro specialists before writing its draft.
4
+ # Demonstrates the spawn() pattern for dynamic robot creation.
5
+ class LinuxWriter < OsWriter
6
+ attr_reader :specialists
7
+
8
+ def initialize(**opts)
9
+ super(**opts)
10
+ @specialists = []
11
+ end
12
+
13
+ def call(result)
14
+ message = extract_message(result)
15
+
16
+ # Spawn distro specialists and collect their analyses
17
+ distro_analyses = spawn_distro_specialists(message)
18
+
19
+ # Build an enriched prompt with specialist input
20
+ enriched = <<~PROMPT
21
+ #{message}
22
+
23
+ Your team of distro specialists has provided the following analyses.
24
+ Incorporate their insights into your advocacy piece:
25
+
26
+ #{distro_analyses}
27
+ PROMPT
28
+
29
+ robot_result = run(enriched, network_memory: @shared_memory)
30
+
31
+ if @shared_memory
32
+ draft = robot_result.reply.to_s
33
+ @shared_memory.current_writer = @name
34
+ @shared_memory.set(@memory_key, draft)
35
+
36
+ path = File.join(OUTPUT_DIR, "#{@memory_key}.md")
37
+ File.write(path, "# #{@name} Draft\n\n#{draft}\n")
38
+ puts " [#{@name}] Draft written to memory[:#{@memory_key}] and #{path} (with #{@specialists.size} specialist inputs)"
39
+ end
40
+
41
+ result.with_context(@name.to_sym, robot_result).continue(robot_result)
42
+ end
43
+
44
+ private
45
+
46
+ def spawn_distro_specialists(topic)
47
+ distros = [
48
+ { name: "ubuntu_specialist", label: "Ubuntu/Debian",
49
+ prompt: "You are a Ubuntu/Debian specialist for AI research. Focus on apt ecosystem, CUDA support, and wide hardware compatibility." },
50
+ { name: "fedora_specialist", label: "Fedora/RHEL",
51
+ prompt: "You are a Fedora/RHEL specialist for AI research. Focus on cutting-edge kernels, SELinux security, and enterprise tooling." },
52
+ { name: "freebsd_specialist", label: "FreeBSD",
53
+ prompt: "You are a FreeBSD specialist for AI research. Focus on ZFS, jails, bhyve virtualization, and stability for long-running experiments." }
54
+ ]
55
+
56
+ analyses = []
57
+
58
+ distros.each do |distro|
59
+ puts " [#{@name}] Spawning #{distro[:label]} specialist..."
60
+ specialist = spawn(name: distro[:name], system_prompt: distro[:prompt])
61
+ @specialists << specialist
62
+
63
+ analysis = specialist.run(
64
+ "Briefly describe why #{distro[:label]} is a strong choice for a home AI research lab. 2-3 sentences."
65
+ ).reply.strip
66
+
67
+ puts " [#{distro[:name]}] #{analysis[0..80]}..."
68
+ analyses << "### #{distro[:label]}\n#{analysis}"
69
+
70
+ # Write each specialist's analysis to shared memory
71
+ if @shared_memory
72
+ memory_key = distro[:name].to_sym
73
+ @shared_memory.current_writer = distro[:name]
74
+ @shared_memory.set(memory_key, analysis)
75
+ end
76
+ end
77
+
78
+ analyses.join("\n\n")
79
+ end
80
+ end