robot_lab 0.0.1 → 0.0.6

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 (187) 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 +140 -0
  5. data/README.md +263 -48
  6. data/Rakefile +71 -1
  7. data/docs/api/core/index.md +53 -46
  8. data/docs/api/core/memory.md +200 -154
  9. data/docs/api/core/network.md +13 -3
  10. data/docs/api/core/robot.md +490 -130
  11. data/docs/api/core/state.md +55 -73
  12. data/docs/api/core/tool.md +205 -209
  13. data/docs/api/index.md +7 -28
  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/messages/index.md +35 -20
  19. data/docs/api/messages/text-message.md +67 -21
  20. data/docs/api/messages/tool-call-message.md +80 -41
  21. data/docs/api/messages/tool-result-message.md +119 -50
  22. data/docs/api/messages/user-message.md +48 -24
  23. data/docs/api/streaming/context.md +157 -74
  24. data/docs/api/streaming/events.md +114 -166
  25. data/docs/api/streaming/index.md +74 -72
  26. data/docs/architecture/core-concepts.md +360 -116
  27. data/docs/architecture/index.md +97 -59
  28. data/docs/architecture/message-flow.md +138 -129
  29. data/docs/architecture/network-orchestration.md +197 -50
  30. data/docs/architecture/robot-execution.md +199 -146
  31. data/docs/architecture/state-management.md +255 -187
  32. data/docs/concepts.md +311 -49
  33. data/docs/examples/basic-chat.md +89 -77
  34. data/docs/examples/index.md +222 -47
  35. data/docs/examples/mcp-server.md +207 -203
  36. data/docs/examples/multi-robot-network.md +129 -35
  37. data/docs/examples/rails-application.md +159 -160
  38. data/docs/examples/tool-usage.md +295 -204
  39. data/docs/getting-started/configuration.md +347 -154
  40. data/docs/getting-started/index.md +1 -1
  41. data/docs/getting-started/installation.md +22 -13
  42. data/docs/getting-started/quick-start.md +166 -121
  43. data/docs/guides/building-robots.md +418 -212
  44. data/docs/guides/creating-networks.md +143 -24
  45. data/docs/guides/index.md +0 -5
  46. data/docs/guides/mcp-integration.md +152 -113
  47. data/docs/guides/memory.md +220 -164
  48. data/docs/guides/rails-integration.md +244 -162
  49. data/docs/guides/streaming.md +137 -187
  50. data/docs/guides/using-tools.md +259 -212
  51. data/docs/index.md +46 -41
  52. data/examples/01_simple_robot.rb +6 -9
  53. data/examples/02_tools.rb +6 -9
  54. data/examples/03_network.rb +19 -17
  55. data/examples/04_mcp.rb +5 -8
  56. data/examples/05_streaming.rb +5 -8
  57. data/examples/06_prompt_templates.rb +42 -37
  58. data/examples/07_network_memory.rb +13 -14
  59. data/examples/08_llm_config.rb +169 -0
  60. data/examples/09_chaining.rb +262 -0
  61. data/examples/10_memory.rb +331 -0
  62. data/examples/11_network_introspection.rb +253 -0
  63. data/examples/12_message_bus.rb +74 -0
  64. data/examples/13_spawn.rb +90 -0
  65. data/examples/14_rusty_circuit/comic.rb +143 -0
  66. data/examples/14_rusty_circuit/display.rb +203 -0
  67. data/examples/14_rusty_circuit/heckler.rb +63 -0
  68. data/examples/14_rusty_circuit/open_mic.rb +123 -0
  69. data/examples/14_rusty_circuit/prompts/open_mic_comic.md +20 -0
  70. data/examples/14_rusty_circuit/prompts/open_mic_heckler.md +23 -0
  71. data/examples/14_rusty_circuit/prompts/open_mic_scout.md +20 -0
  72. data/examples/14_rusty_circuit/scout.rb +156 -0
  73. data/examples/14_rusty_circuit/scout_notes.md +89 -0
  74. data/examples/14_rusty_circuit/show.log +234 -0
  75. data/examples/15_memory_network_and_bus/editor_in_chief.rb +24 -0
  76. data/examples/15_memory_network_and_bus/editorial_pipeline.rb +206 -0
  77. data/examples/15_memory_network_and_bus/linux_writer.rb +80 -0
  78. data/examples/15_memory_network_and_bus/os_editor.rb +46 -0
  79. data/examples/15_memory_network_and_bus/os_writer.rb +46 -0
  80. data/examples/15_memory_network_and_bus/output/combined_article.md +13 -0
  81. data/examples/15_memory_network_and_bus/output/final_article.md +15 -0
  82. data/examples/15_memory_network_and_bus/output/linux_draft.md +5 -0
  83. data/examples/15_memory_network_and_bus/output/mac_draft.md +7 -0
  84. data/examples/15_memory_network_and_bus/output/memory.json +13 -0
  85. data/examples/15_memory_network_and_bus/output/revision_1.md +19 -0
  86. data/examples/15_memory_network_and_bus/output/revision_2.md +15 -0
  87. data/examples/15_memory_network_and_bus/output/windows_draft.md +7 -0
  88. data/examples/15_memory_network_and_bus/prompts/os_advocate.md +13 -0
  89. data/examples/15_memory_network_and_bus/prompts/os_chief.md +13 -0
  90. data/examples/15_memory_network_and_bus/prompts/os_editor.md +13 -0
  91. data/examples/16_writers_room/display.rb +158 -0
  92. data/examples/16_writers_room/output/.gitignore +2 -0
  93. data/examples/16_writers_room/output/opus_001.md +263 -0
  94. data/examples/16_writers_room/output/opus_001_notes.log +470 -0
  95. data/examples/16_writers_room/prompts/writer.md +37 -0
  96. data/examples/16_writers_room/room.rb +150 -0
  97. data/examples/16_writers_room/tools.rb +162 -0
  98. data/examples/16_writers_room/writer.rb +121 -0
  99. data/examples/16_writers_room/writers_room.rb +162 -0
  100. data/examples/README.md +197 -0
  101. data/examples/prompts/{assistant/system.txt.erb → assistant.md} +3 -0
  102. data/examples/prompts/{billing/system.txt.erb → billing.md} +3 -0
  103. data/examples/prompts/{classifier/system.txt.erb → classifier.md} +3 -0
  104. data/examples/prompts/comedian.md +6 -0
  105. data/examples/prompts/comedy_critic.md +10 -0
  106. data/examples/prompts/configurable.md +9 -0
  107. data/examples/prompts/dispatcher.md +12 -0
  108. data/examples/prompts/{entity_extractor/system.txt.erb → entity_extractor.md} +3 -0
  109. data/examples/prompts/{escalation/system.txt.erb → escalation.md} +7 -0
  110. data/examples/prompts/frontmatter_mcp_test.md +9 -0
  111. data/examples/prompts/frontmatter_named_test.md +5 -0
  112. data/examples/prompts/frontmatter_tools_test.md +6 -0
  113. data/examples/prompts/{general/system.txt.erb → general.md} +3 -0
  114. data/examples/prompts/{github_assistant/system.txt.erb → github_assistant.md} +8 -0
  115. data/examples/prompts/{helper/system.txt.erb → helper.md} +3 -0
  116. data/examples/prompts/{keyword_extractor/system.txt.erb → keyword_extractor.md} +3 -0
  117. data/examples/prompts/llm_config_demo.md +20 -0
  118. data/examples/prompts/{order_support/system.txt.erb → order_support.md} +8 -0
  119. data/examples/prompts/os_advocate.md +13 -0
  120. data/examples/prompts/os_chief.md +13 -0
  121. data/examples/prompts/os_editor.md +13 -0
  122. data/examples/prompts/{product_support/system.txt.erb → product_support.md} +7 -0
  123. data/examples/prompts/{sentiment_analyzer/system.txt.erb → sentiment_analyzer.md} +3 -0
  124. data/examples/prompts/{synthesizer/system.txt.erb → synthesizer.md} +3 -0
  125. data/examples/prompts/{technical/system.txt.erb → technical.md} +3 -0
  126. data/examples/prompts/{triage/system.txt.erb → triage.md} +6 -0
  127. data/lib/generators/robot_lab/templates/initializer.rb.tt +0 -13
  128. data/lib/robot_lab/ask_user.rb +75 -0
  129. data/lib/robot_lab/config/defaults.yml +121 -0
  130. data/lib/robot_lab/config.rb +183 -0
  131. data/lib/robot_lab/error.rb +6 -0
  132. data/lib/robot_lab/mcp/client.rb +1 -1
  133. data/lib/robot_lab/memory.rb +10 -34
  134. data/lib/robot_lab/network.rb +13 -20
  135. data/lib/robot_lab/robot/bus_messaging.rb +239 -0
  136. data/lib/robot_lab/robot/mcp_management.rb +88 -0
  137. data/lib/robot_lab/robot/template_rendering.rb +130 -0
  138. data/lib/robot_lab/robot.rb +240 -330
  139. data/lib/robot_lab/robot_message.rb +44 -0
  140. data/lib/robot_lab/robot_result.rb +1 -0
  141. data/lib/robot_lab/run_config.rb +184 -0
  142. data/lib/robot_lab/state_proxy.rb +2 -12
  143. data/lib/robot_lab/streaming/context.rb +1 -1
  144. data/lib/robot_lab/task.rb +8 -1
  145. data/lib/robot_lab/tool.rb +108 -172
  146. data/lib/robot_lab/tool_config.rb +1 -1
  147. data/lib/robot_lab/tool_manifest.rb +2 -18
  148. data/lib/robot_lab/utils.rb +39 -0
  149. data/lib/robot_lab/version.rb +1 -1
  150. data/lib/robot_lab.rb +89 -57
  151. data/mkdocs.yml +0 -11
  152. metadata +121 -135
  153. data/docs/api/adapters/anthropic.md +0 -121
  154. data/docs/api/adapters/gemini.md +0 -133
  155. data/docs/api/adapters/index.md +0 -104
  156. data/docs/api/adapters/openai.md +0 -134
  157. data/docs/api/history/active-record-adapter.md +0 -195
  158. data/docs/api/history/config.md +0 -191
  159. data/docs/api/history/index.md +0 -132
  160. data/docs/api/history/thread-manager.md +0 -144
  161. data/docs/guides/history.md +0 -359
  162. data/examples/prompts/assistant/user.txt.erb +0 -1
  163. data/examples/prompts/billing/user.txt.erb +0 -1
  164. data/examples/prompts/classifier/user.txt.erb +0 -1
  165. data/examples/prompts/entity_extractor/user.txt.erb +0 -3
  166. data/examples/prompts/escalation/user.txt.erb +0 -34
  167. data/examples/prompts/general/user.txt.erb +0 -1
  168. data/examples/prompts/github_assistant/user.txt.erb +0 -1
  169. data/examples/prompts/helper/user.txt.erb +0 -1
  170. data/examples/prompts/keyword_extractor/user.txt.erb +0 -3
  171. data/examples/prompts/order_support/user.txt.erb +0 -22
  172. data/examples/prompts/product_support/user.txt.erb +0 -32
  173. data/examples/prompts/sentiment_analyzer/user.txt.erb +0 -3
  174. data/examples/prompts/synthesizer/user.txt.erb +0 -15
  175. data/examples/prompts/technical/user.txt.erb +0 -1
  176. data/examples/prompts/triage/user.txt.erb +0 -17
  177. data/lib/robot_lab/adapters/anthropic.rb +0 -163
  178. data/lib/robot_lab/adapters/base.rb +0 -85
  179. data/lib/robot_lab/adapters/gemini.rb +0 -193
  180. data/lib/robot_lab/adapters/openai.rb +0 -159
  181. data/lib/robot_lab/adapters/registry.rb +0 -81
  182. data/lib/robot_lab/configuration.rb +0 -143
  183. data/lib/robot_lab/errors.rb +0 -70
  184. data/lib/robot_lab/history/active_record_adapter.rb +0 -146
  185. data/lib/robot_lab/history/config.rb +0 -115
  186. data/lib/robot_lab/history/thread_manager.rb +0 -93
  187. data/lib/robot_lab/robotic_model.rb +0 -324
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RobotLab
4
+ # Shared utility methods used across multiple classes.
5
+ #
6
+ # Include this module to get `dispatch_async` and `deep_dup`
7
+ # as private instance methods.
8
+ module Utils
9
+ private
10
+
11
+ # Dispatch a block asynchronously using Async fibers.
12
+ #
13
+ # When already inside an Async reactor, creates a child task.
14
+ # Otherwise, creates a temporary reactor that runs the block
15
+ # and cleans up automatically.
16
+ def dispatch_async(&block)
17
+ Async do
18
+ block.call
19
+ rescue => e
20
+ RobotLab.config.logger.error("dispatch_async error: #{e.class}: #{e.message}")
21
+ end
22
+ end
23
+
24
+ # Deep-duplicate a nested Hash/Array structure.
25
+ #
26
+ # @param obj [Object] the object to duplicate
27
+ # @return [Object] the deep copy
28
+ def deep_dup(obj)
29
+ case obj
30
+ when Hash
31
+ obj.transform_values { |v| deep_dup(v) }
32
+ when Array
33
+ obj.map { |v| deep_dup(v) }
34
+ else
35
+ obj.dup rescue obj
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RobotLab
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.6"
5
5
  end
data/lib/robot_lab.rb CHANGED
@@ -1,13 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "zeitwerk"
4
- require "json"
5
- require "securerandom"
6
- require "digest"
3
+ require 'zeitwerk'
4
+ require 'json'
5
+ require 'securerandom'
6
+ require 'digest'
7
7
 
8
8
  # Core dependencies
9
- require "ruby_llm"
10
- require "async"
9
+ # ActiveSupport delegation is required by ruby_llm (RubyLLM::Agent uses delegate)
10
+ # but not declared in ruby_llm's gemspec. Load it before ruby_llm.
11
+ require 'active_support/core_ext/module/delegation'
12
+ require 'ruby_llm'
13
+ require 'prompt_manager'
14
+ require 'async'
15
+ require 'typed_bus'
11
16
 
12
17
  # Define the module first so Zeitwerk can populate it
13
18
  #
@@ -29,10 +34,16 @@ require "async"
29
34
  # result = network.run(message: "Process this document")
30
35
  #
31
36
  # @example Configuration
32
- # RobotLab.configure do |config|
33
- # config.anthropic_api_key = ENV["ANTHROPIC_API_KEY"]
34
- # config.template_path = "app/templates"
35
- # end
37
+ # # Via environment variables (ROBOT_LAB_* prefix)
38
+ # # ROBOT_LAB_DEFAULT_MODEL=gpt-4
39
+ # # ROBOT_LAB_RUBY_LLM__ANTHROPIC_API_KEY=sk-ant-...
40
+ #
41
+ # # Or via config files (~/.config/robot_lab/config.yml or ./config/robot_lab.yml)
42
+ # # See lib/robot_lab/config/defaults.yml for all options
43
+ #
44
+ # # Access configuration values:
45
+ # RobotLab.config.ruby_llm.model #=> "claude-sonnet-4"
46
+ # RobotLab.config.ruby_llm.request_timeout #=> 120
36
47
  #
37
48
  module RobotLab
38
49
  end
@@ -40,63 +51,94 @@ end
40
51
  loader = Zeitwerk::Loader.for_gem(warn_on_extra_files: false)
41
52
  loader.ignore("#{__dir__}/generators")
42
53
  loader.ignore("#{__dir__}/robot_lab/rails")
54
+ loader.ignore("#{__dir__}/robot_lab/robot")
43
55
 
44
56
  # Custom inflections for classes that don't follow Zeitwerk naming conventions
45
57
  loader.inflector.inflect(
46
- "robot_lab" => "RobotLab",
47
- "robotic_model" => "RoboticModel",
48
- "mcp" => "MCP",
49
- "openai" => "OpenAI",
50
- "sse" => "SSE",
51
- "streamable_http" => "StreamableHTTP",
52
- "websocket" => "WebSocket"
58
+ 'robot_lab' => 'RobotLab',
59
+ 'mcp' => 'MCP',
60
+ 'openai' => 'OpenAI',
61
+ 'sse' => 'SSE',
62
+ 'streamable_http' => 'StreamableHTTP',
63
+ 'websocket' => 'WebSocket'
53
64
  )
54
65
 
55
- # Note: adapters/ is NOT collapsed since files define RobotLab::Adapters::* classes
56
-
57
66
  loader.setup
58
67
 
59
- # Eager load for proper constant resolution
60
- loader.eager_load
68
+ # These files define multiple classes that Zeitwerk cannot autoload
69
+ # individually (e.g. TextMessage lives in message.rb, not text_message.rb).
70
+ # Require them explicitly so their constants are available without eager loading.
71
+ require_relative 'robot_lab/error'
72
+ require_relative 'robot_lab/message'
73
+ require_relative 'robot_lab/memory'
74
+
75
+ # Eager load everything in Rails or when explicitly requested.
76
+ # Otherwise Zeitwerk's lazy autoloading keeps boot fast.
77
+ loader.eager_load if defined?(Rails::Engine) || ENV["ROBOT_LAB_EAGER_LOAD"]
61
78
 
62
79
  module RobotLab
63
80
  # Error classes are defined in lib/robot_lab/error.rb
64
81
 
65
82
  class << self
66
- # @!attribute [w] configuration
67
- # @return [Configuration] the configuration object
68
- attr_writer :configuration
69
-
70
- # Returns the current configuration object.
83
+ # Returns the Config object (MywayConfig-based).
84
+ #
85
+ # Configuration is automatically loaded from:
86
+ # - Bundled defaults (lib/robot_lab/config/defaults.yml)
87
+ # - Environment-specific overrides (development, test, production)
88
+ # - XDG config files (~/.config/robot_lab/config.yml)
89
+ # - Project config (./config/robot_lab.yml)
90
+ # - Environment variables (ROBOT_LAB_*)
71
91
  #
72
- # @return [Configuration] the configuration instance
73
- def configuration
74
- @configuration ||= Configuration.new
92
+ # @return [Config] the config instance
93
+ #
94
+ # @example
95
+ # RobotLab.config.ruby_llm.model #=> "claude-sonnet-4"
96
+ # RobotLab.config.ruby_llm.request_timeout #=> 120
97
+ # RobotLab.config.development? #=> true
98
+ def config
99
+ @config ||= Config.new.tap(&:after_load)
75
100
  end
76
101
 
77
- # Yields the configuration object for modification.
102
+
103
+ # Yields the Config object for block-style configuration.
78
104
  #
79
- # @yield [Configuration] the configuration object
80
- # @return [void]
105
+ # @yield [Config] the config instance
106
+ # @return [Config] the config instance
81
107
  #
82
108
  # @example
83
- # RobotLab.configure do |config|
84
- # config.anthropic_api_key = "sk-..."
109
+ # RobotLab.configure do |c|
110
+ # c.default_model = "claude-sonnet-4"
85
111
  # end
86
112
  def configure
87
- yield(configuration)
113
+ yield config
88
114
  end
89
115
 
116
+
117
+ # Reload configuration from all sources.
118
+ #
119
+ # Clears the cached Config instance, forcing it to be
120
+ # reloaded on next access.
121
+ #
122
+ # @return [Config] the new config instance
123
+ def reload_config!
124
+ @config = nil
125
+ config
126
+ end
127
+
128
+
90
129
  # Factory method to create a new Robot instance.
91
130
  #
92
- # @param name [String] the unique identifier for the robot
93
- # @param template [Symbol, nil] the ERB template for the robot's prompt
131
+ # @param name [String, nil] the unique identifier for the robot (auto-generated if nil)
132
+ # @param template [Symbol, nil] the prompt_manager template for the robot's prompt
94
133
  # @param system_prompt [String, nil] inline system prompt (can be used alone or with template)
95
134
  # @param context [Hash] variables to pass to the template
96
135
  # @param enable_cache [Boolean] whether to enable semantic caching (default: true)
97
136
  # @param options [Hash] additional options passed to Robot.new
98
137
  # @return [Robot] a new Robot instance
99
- # @raise [ArgumentError] if neither template nor system_prompt is provided
138
+ #
139
+ # @example Bare robot (no template or prompt)
140
+ # robot = RobotLab.build
141
+ # robot.with_instructions("You are helpful.").run("Hello!")
100
142
  #
101
143
  # @example Robot with template
102
144
  # robot = RobotLab.build(
@@ -110,31 +152,20 @@ module RobotLab
110
152
  # name: "helper",
111
153
  # system_prompt: "You are a helpful assistant."
112
154
  # )
113
- #
114
- # @example Robot with both template and system prompt
115
- # robot = RobotLab.build(
116
- # name: "support",
117
- # template: :support_agent,
118
- # system_prompt: "Today's date is #{Date.today}."
119
- # )
120
- #
121
- # @example Robot with caching disabled
122
- # robot = RobotLab.build(
123
- # name: "simple",
124
- # system_prompt: "You are helpful.",
125
- # enable_cache: false
126
- # )
127
- def build(name:, template: nil, system_prompt: nil, context: {}, enable_cache: true, **options)
155
+ def build(name: "robot", template: nil, system_prompt: nil, context: {}, enable_cache: true, bus: nil, config: nil, **options)
128
156
  Robot.new(
129
157
  name: name,
130
158
  template: template,
131
159
  system_prompt: system_prompt,
132
160
  context: context,
133
161
  enable_cache: enable_cache,
162
+ bus: bus,
163
+ config: config,
134
164
  **options
135
165
  )
136
166
  end
137
167
 
168
+
138
169
  # Factory method to create a new Network of robots.
139
170
  #
140
171
  # @param name [String] the unique identifier for the network
@@ -162,10 +193,11 @@ module RobotLab
162
193
  # step :entities, entity_bot, depends_on: [:fetch]
163
194
  # step :merge, merger, depends_on: [:sentiment, :entities]
164
195
  # end
165
- def create_network(name:, concurrency: :auto, &block)
166
- Network.new(name: name, concurrency: concurrency, &block)
196
+ def create_network(name:, concurrency: :auto, config: nil, &block)
197
+ Network.new(name: name, concurrency: concurrency, config: config, &block)
167
198
  end
168
199
 
200
+
169
201
  # Factory method to create a new Memory object.
170
202
  #
171
203
  # @param data [Hash] initial runtime data
@@ -190,6 +222,6 @@ end
190
222
 
191
223
  # Load Rails integration if Rails is defined
192
224
  if defined?(Rails::Engine)
193
- require "robot_lab/rails/engine"
194
- require "robot_lab/rails/railtie"
225
+ require 'robot_lab/rails/engine'
226
+ require 'robot_lab/rails/railtie'
195
227
  end
data/mkdocs.yml CHANGED
@@ -168,7 +168,6 @@ nav:
168
168
  - Using Tools: guides/using-tools.md
169
169
  - MCP Integration: guides/mcp-integration.md
170
170
  - Streaming Responses: guides/streaming.md
171
- - Conversation History: guides/history.md
172
171
  - Memory System: guides/memory.md
173
172
  - Rails Integration: guides/rails-integration.md
174
173
  - API Reference:
@@ -186,11 +185,6 @@ nav:
186
185
  - TextMessage: api/messages/text-message.md
187
186
  - ToolCallMessage: api/messages/tool-call-message.md
188
187
  - ToolResultMessage: api/messages/tool-result-message.md
189
- - Adapters:
190
- - api/adapters/index.md
191
- - Anthropic: api/adapters/anthropic.md
192
- - OpenAI: api/adapters/openai.md
193
- - Gemini: api/adapters/gemini.md
194
188
  - MCP:
195
189
  - api/mcp/index.md
196
190
  - Client: api/mcp/client.md
@@ -200,11 +194,6 @@ nav:
200
194
  - api/streaming/index.md
201
195
  - Context: api/streaming/context.md
202
196
  - Events: api/streaming/events.md
203
- - History:
204
- - api/history/index.md
205
- - Config: api/history/config.md
206
- - ThreadManager: api/history/thread-manager.md
207
- - ActiveRecordAdapter: api/history/active-record-adapter.md
208
197
  - Examples:
209
198
  - examples/index.md
210
199
  - Basic Chat: examples/basic-chat.md