ruboty-ai_agent 0.1.0 → 0.2.0

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +19 -0
  3. data/Gemfile +10 -3
  4. data/Rakefile +2 -0
  5. data/Steepfile +1 -0
  6. data/lib/ruboty/ai_agent/actions/add_ai_command.rb +16 -1
  7. data/lib/ruboty/ai_agent/actions/chat.rb +44 -16
  8. data/lib/ruboty/ai_agent/actions/list_ai_commands.rb +20 -4
  9. data/lib/ruboty/ai_agent/actions/remove_ai_command.rb +7 -1
  10. data/lib/ruboty/ai_agent/actions/show_system_prompt.rb +1 -1
  11. data/lib/ruboty/ai_agent/chat_message.rb +7 -2
  12. data/lib/ruboty/ai_agent/chat_thread_messages.rb +40 -0
  13. data/lib/ruboty/ai_agent/commands/base.rb +11 -14
  14. data/lib/ruboty/ai_agent/commands/builtin_base.rb +39 -0
  15. data/lib/ruboty/ai_agent/commands/clear.rb +2 -14
  16. data/lib/ruboty/ai_agent/commands/compact.rb +4 -47
  17. data/lib/ruboty/ai_agent/commands/prompt_command.rb +61 -0
  18. data/lib/ruboty/ai_agent/commands/usage.rb +2 -14
  19. data/lib/ruboty/ai_agent/commands.rb +3 -1
  20. data/lib/ruboty/ai_agent/database/query_methods.rb +31 -6
  21. data/lib/ruboty/ai_agent/database.rb +2 -1
  22. data/lib/ruboty/ai_agent/http_mcp_client.rb +5 -2
  23. data/lib/ruboty/ai_agent/llm/openai.rb +5 -5
  24. data/lib/ruboty/ai_agent/mcp_clients.rb +6 -0
  25. data/lib/ruboty/ai_agent/mcp_configuration.rb +3 -2
  26. data/lib/ruboty/ai_agent/prompt_command_definition.rb +17 -0
  27. data/lib/ruboty/ai_agent/record_set.rb +9 -5
  28. data/lib/ruboty/ai_agent/recordable.rb +11 -9
  29. data/lib/ruboty/ai_agent/token_usage.rb +10 -0
  30. data/lib/ruboty/ai_agent/user.rb +5 -0
  31. data/lib/ruboty/ai_agent/user_mcp_caches.rb +2 -2
  32. data/lib/ruboty/ai_agent/user_mcp_client.rb +2 -2
  33. data/lib/ruboty/ai_agent/user_prompt_command_definitions.rb +17 -0
  34. data/lib/ruboty/ai_agent/version.rb +1 -1
  35. data/lib/ruboty/ai_agent.rb +11 -0
  36. data/lib/ruboty/handlers/ai_agent.rb +27 -15
  37. data/rbs_collection.yaml +1 -0
  38. data/ruboty-ai_agent.gemspec +2 -6
  39. data/script/clean-orphaned-rbs.rb +105 -0
  40. data/script/generate-concern-rbs.rb +5 -5
  41. data/script/generate-data-rbs.rb +3 -5
  42. data/script/generate-memorized-ivar-rbs.rb +6 -11
  43. data/sig/generated/ruboty/ai_agent/actions/add_ai_command.rbs +4 -0
  44. data/sig/generated/ruboty/ai_agent/actions/chat.rbs +6 -0
  45. data/sig/generated/ruboty/ai_agent/chat_message.rbs +5 -2
  46. data/sig/generated/ruboty/ai_agent/chat_thread_messages.rbs +14 -0
  47. data/sig/generated/ruboty/ai_agent/commands/base.rbs +8 -20
  48. data/sig/generated/ruboty/ai_agent/commands/builtin_base.rbs +40 -0
  49. data/sig/generated/ruboty/ai_agent/commands/clear.rbs +2 -10
  50. data/sig/generated/ruboty/ai_agent/commands/compact.rbs +2 -20
  51. data/sig/generated/ruboty/ai_agent/commands/prompt_command.rbs +27 -0
  52. data/sig/generated/ruboty/ai_agent/commands/usage.rbs +2 -10
  53. data/sig/generated/ruboty/ai_agent/commands.rbs +2 -2
  54. data/sig/generated/ruboty/ai_agent/database/query_methods.rbs +18 -12
  55. data/sig/generated/ruboty/ai_agent/database.rbs +3 -1
  56. data/sig/generated/ruboty/ai_agent/llm/openai.rbs +3 -3
  57. data/sig/generated/ruboty/ai_agent/mcp_configuration.rbs +4 -2
  58. data/sig/generated/ruboty/ai_agent/prompt_command_definition.rbs +23 -0
  59. data/sig/generated/ruboty/ai_agent/record_set.rbs +11 -9
  60. data/sig/generated/ruboty/ai_agent/recordable.rbs +6 -6
  61. data/sig/generated/ruboty/ai_agent/token_usage.rbs +4 -0
  62. data/sig/generated/ruboty/ai_agent/user.rbs +4 -0
  63. data/sig/generated/ruboty/ai_agent/user_prompt_command_definitions.rbs +12 -0
  64. data/sig/generated/ruboty/handlers/ai_agent.rbs +12 -12
  65. data/sig/generated-by-scripts/concerns.rbs +5 -0
  66. data/sig/generated-by-scripts/memorized_ivars.rbs +9 -0
  67. metadata +11 -57
@@ -303,7 +303,7 @@ class ConcernRbsGenerator
303
303
 
304
304
  # Open namespaces
305
305
  namespace_parts.each do |part|
306
- content << (' ' * indent_level) + "module #{part}"
306
+ content << ((' ' * indent_level) + "module #{part}")
307
307
  indent_level += 1
308
308
  end
309
309
 
@@ -315,17 +315,17 @@ class ConcernRbsGenerator
315
315
  # Add type parameters if present
316
316
  if includer[:type_params] && !includer[:type_params].empty?
317
317
  type_params_str = "[#{includer[:type_params].join(', ')}]"
318
- content << (' ' * indent_level) + "#{keyword} #{simple_name}#{type_params_str}"
318
+ content << ((' ' * indent_level) + "#{keyword} #{simple_name}#{type_params_str}")
319
319
  else
320
- content << (' ' * indent_level) + "#{keyword} #{simple_name}"
320
+ content << ((' ' * indent_level) + "#{keyword} #{simple_name}")
321
321
  end
322
322
 
323
323
  concern = includer[:concern]
324
324
  concern_simple_name = concern[:name].sub(/^::/, '').split('::').last
325
325
 
326
- content << (' ' * (indent_level + 1)) + "extend #{concern_simple_name}::ClassMethods" if concern[:has_class_methods]
326
+ content << ((' ' * (indent_level + 1)) + "extend #{concern_simple_name}::ClassMethods") if concern[:has_class_methods]
327
327
 
328
- content << (' ' * (indent_level + 1)) + "prepend #{concern_simple_name}::PrependMethods" if concern[:has_prepend_methods]
328
+ content << ((' ' * (indent_level + 1)) + "prepend #{concern_simple_name}::PrependMethods") if concern[:has_prepend_methods]
329
329
 
330
330
  content << "#{' ' * indent_level}end"
331
331
  content << ''
@@ -31,7 +31,7 @@ class Processor
31
31
  puts "Scanning Ruby files in #{@lib_path}..."
32
32
 
33
33
  @lib_path.glob('**/*.rb').map do |file|
34
- puts "Processing #{file}..."
34
+ puts "Processing #{file}..." if ENV['DEBUG']
35
35
  content = file.read
36
36
 
37
37
  parsed = Prism.parse(content)
@@ -127,9 +127,7 @@ class DataClassRbsGenerator
127
127
 
128
128
  def extract_constant_name(constant_path)
129
129
  case constant_path
130
- when Prism::ConstantReadNode
131
- constant_path.name.to_s
132
- when Prism::ConstantPathNode
130
+ when Prism::ConstantReadNode, Prism::ConstantPathNode
133
131
  constant_path.name.to_s
134
132
  end
135
133
  end
@@ -242,7 +240,7 @@ class DataClassRbsGenerator
242
240
  end
243
241
 
244
242
  def indent(string, level:)
245
- ' ' * level + string
243
+ (' ' * level) + string
246
244
  end
247
245
  end
248
246
  end
@@ -101,15 +101,15 @@ class MemorizedIvarRbsGenerator
101
101
 
102
102
  # Open namespaces
103
103
  parts[0...-1].each do |part|
104
- content << (' ' * indent_level) + "module #{part}"
104
+ content << ((' ' * indent_level) + "module #{part}")
105
105
  indent_level += 1
106
106
  end
107
107
 
108
108
  # Class declaration with instance variables
109
- content << (' ' * indent_level) + "class #{parts.last}"
109
+ content << ((' ' * indent_level) + "class #{parts.last}")
110
110
 
111
111
  methods.each do |method|
112
- content << (' ' * (indent_level + 1)) + "@#{method.ivar_name}: #{method.return_type}"
112
+ content << ((' ' * (indent_level + 1)) + "@#{method.ivar_name}: #{method.return_type}")
113
113
  end
114
114
 
115
115
  content << "#{' ' * indent_level}end"
@@ -188,9 +188,7 @@ class MemorizedIvarRbsGenerator
188
188
 
189
189
  def extract_constant_name(constant_path)
190
190
  case constant_path
191
- when Prism::ConstantReadNode
192
- constant_path.name.to_s
193
- when Prism::ConstantPathNode
191
+ when Prism::ConstantReadNode, Prism::ConstantPathNode
194
192
  constant_path.name.to_s
195
193
  end
196
194
  end
@@ -248,11 +246,8 @@ class MemorizedIvarRbsGenerator
248
246
  return result if result
249
247
  end
250
248
  nil
251
- when Prism::InstanceVariableOperatorWriteNode, Prism::InstanceVariableOrWriteNode
252
- # This handles @ivar ||= ...
253
- node.name.to_s.delete('@')
254
- when Prism::InstanceVariableWriteNode
255
- # This handles @ivar = ...
249
+ when Prism::InstanceVariableOperatorWriteNode, Prism::InstanceVariableOrWriteNode, Prism::InstanceVariableWriteNode
250
+ # This handles @ivar ||= ... or @ivar = ...
256
251
  node.name.to_s.delete('@')
257
252
  else
258
253
  # Recursively search in child nodes
@@ -10,6 +10,10 @@ module Ruboty
10
10
  def name_param: () -> String
11
11
 
12
12
  def prompt_param: () -> String
13
+
14
+ # @rbs str: String
15
+ # @rbs return: String
16
+ def undump_string: (String str) -> String
13
17
  end
14
18
  end
15
19
  end
@@ -11,6 +11,12 @@ module Ruboty
11
11
  def call: ...
12
12
 
13
13
  def body_param: () -> String
14
+
15
+ private
16
+
17
+ # @rbs body: String
18
+ # @rbs return: void
19
+ def complete_chat: (String body) -> void
14
20
  end
15
21
  end
16
22
  end
@@ -18,16 +18,19 @@ module Ruboty
18
18
 
19
19
  attr_reader token_usage: TokenUsage?
20
20
 
21
- # @rbs role: Symbol
21
+ # @rbs role: Symbol | String
22
22
  # @rbs content: String
23
23
  # @rbs ?tool_call_id: String?
24
24
  # @rbs ?tool_name: String?
25
25
  # @rbs ?tool_arguments: Hash[Symbol | String, untyped]?
26
26
  # @rbs ?token_usage: TokenUsage?
27
- def initialize: (role: Symbol, content: String, ?tool_call_id: untyped, ?tool_name: untyped, ?tool_arguments: untyped, ?token_usage: untyped) -> untyped
27
+ def initialize: (role: Symbol | String, content: String, ?tool_call_id: untyped, ?tool_name: untyped, ?tool_arguments: untyped, ?token_usage: untyped) -> untyped
28
28
 
29
29
  def to_h: () -> Hash[Symbol, untyped]
30
30
 
31
+ # @rbs return: bool
32
+ def tool_call?: () -> bool
33
+
31
34
  def self.from_llm_response: (tool: untyped, tool_call_id: untyped, tool_arguments: untyped, tool_response: untyped) -> ChatMessage
32
35
  end
33
36
  end
@@ -8,6 +8,20 @@ module Ruboty
8
8
  def add: (ChatMessage message) -> void
9
9
 
10
10
  alias << add
11
+
12
+ # Check if any message's token usage exceeds auto compact threshold
13
+ # @rbs return: bool
14
+ def over_auto_compact_threshold?: () -> bool
15
+
16
+ # Compact chat messages by summarizing them
17
+ # @rbs llm: LLM::OpenAI
18
+ # @rbs return: void
19
+ def compact: (llm: LLM::OpenAI) -> void
20
+
21
+ # Generate summary of chat messages
22
+ # @rbs llm: LLM::OpenAI
23
+ # @rbs return: String
24
+ def summarize: (llm: LLM::OpenAI) -> String
11
25
  end
12
26
  end
13
27
  end
@@ -6,34 +6,22 @@ module Ruboty
6
6
  # Base class for commands.
7
7
  # @abstract
8
8
  class Base
9
- class Matcher < Data
10
- attr_reader pattern(): untyped
9
+ attr_reader message: Ruboty::Message
11
10
 
12
- attr_reader description(): untyped
11
+ attr_reader chat_thread: Ruboty::AiAgent::ChatThread
13
12
 
14
- attr_reader name(): untyped
15
-
16
- def self.new: (untyped pattern, untyped description, untyped name) -> instance
17
- | (pattern: untyped, description: untyped, name: untyped) -> instance
18
-
19
- def self.members: () -> [ :pattern, :description, :name ]
20
-
21
- def members: () -> [ :pattern, :description, :name ]
22
- end
23
-
24
- def self.matchers: () -> Array[Matcher]
25
-
26
- def self.on: (untyped pattern, name: untyped, description: untyped) -> untyped
13
+ # @rbs message: Ruboty::Message
14
+ # @rbs chat_thread: Ruboty::AiAgent::ChatThread
15
+ def initialize: (message: Ruboty::Message, chat_thread: Ruboty::AiAgent::ChatThread) -> untyped
27
16
 
28
17
  # @rbs *args: untyped
29
- # @rbs return: void
30
- def call: (*untyped args) -> void
18
+ # @rbs return: untyped
19
+ def call: (*untyped args) -> untyped
31
20
 
32
21
  # @rbs commandline: String
33
22
  # @rbs return: boolish
23
+ # @abstract
34
24
  def match?: (String commandline) -> boolish
35
-
36
- def matchers: () -> Array[Matcher]
37
25
  end
38
26
  end
39
27
  end
@@ -0,0 +1,40 @@
1
+ # Generated from lib/ruboty/ai_agent/commands/builtin_base.rb with RBS::Inline
2
+
3
+ module Ruboty
4
+ module AiAgent
5
+ module Commands
6
+ # Base class for commands.
7
+ # @abstract
8
+ class BuiltinBase < Base
9
+ class Matcher < Data
10
+ attr_reader pattern(): untyped
11
+
12
+ attr_reader description(): untyped
13
+
14
+ attr_reader name(): untyped
15
+
16
+ def self.new: (untyped pattern, untyped description, untyped name) -> instance
17
+ | (pattern: untyped, description: untyped, name: untyped) -> instance
18
+
19
+ def self.members: () -> [ :pattern, :description, :name ]
20
+
21
+ def members: () -> [ :pattern, :description, :name ]
22
+ end
23
+
24
+ def self.matchers: () -> Array[Matcher]
25
+
26
+ def self.on: (untyped pattern, name: untyped, description: untyped) -> untyped
27
+
28
+ # @rbs *args: untyped
29
+ # @rbs return: void
30
+ def call: (*untyped args) -> void
31
+
32
+ # @rbs commandline: String
33
+ # @rbs return: boolish
34
+ def match?: (String commandline) -> boolish
35
+
36
+ def matchers: () -> Array[Matcher]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -4,16 +4,8 @@ module Ruboty
4
4
  module AiAgent
5
5
  module Commands
6
6
  # Clear histories of the chat thread.
7
- class Clear < Base
8
- attr_reader message: Ruboty::Message
9
-
10
- attr_reader chat_thread: Ruboty::AiAgent::ChatThread
11
-
12
- # @rbs message: Ruboty::Message
13
- # @rbs chat_thread: Ruboty::AiAgent::ChatThread
14
- def initialize: (message: Ruboty::Message, chat_thread: Ruboty::AiAgent::ChatThread) -> untyped
15
-
16
- def call: () -> void
7
+ class Clear < BuiltinBase
8
+ def call: (*untyped) -> void
17
9
  end
18
10
  end
19
11
  end
@@ -4,26 +4,8 @@ module Ruboty
4
4
  module AiAgent
5
5
  module Commands
6
6
  # Compact chat history by summarizing it
7
- class Compact < Base
8
- attr_reader message: Ruboty::Message
9
-
10
- attr_reader chat_thread: Ruboty::AiAgent::ChatThread
11
-
12
- # @rbs message: Ruboty::Message
13
- # @rbs chat_thread: Ruboty::AiAgent::ChatThread
14
- def initialize: (message: Ruboty::Message, chat_thread: Ruboty::AiAgent::ChatThread) -> untyped
15
-
16
- def call: () -> void
17
-
18
- private
19
-
20
- # @rbs messages: Array[ChatMessage]
21
- # @rbs return: String
22
- def generate_summary: (Array[ChatMessage] messages) -> String
23
-
24
- # @rbs messages: Array[ChatMessage]
25
- # @rbs return: String
26
- def format_messages_for_summary: (Array[ChatMessage] messages) -> String
7
+ class Compact < BuiltinBase
8
+ def call: (*untyped) -> void
27
9
  end
28
10
  end
29
11
  end
@@ -0,0 +1,27 @@
1
+ # Generated from lib/ruboty/ai_agent/commands/prompt_command.rb with RBS::Inline
2
+
3
+ module Ruboty
4
+ module AiAgent
5
+ module Commands
6
+ # Compact chat history by summarizing it
7
+ class PromptCommand < Base
8
+ attr_reader definition: Ruboty::AiAgent::PromptCommandDefinition
9
+
10
+ # @rbs definition: Ruboty::AiAgent::PromptCommandDefinition
11
+ # @rbs message: Ruboty::Message
12
+ # @rbs chat_thread: Ruboty::AiAgent::ChatThread
13
+ def initialize: (definition: Ruboty::AiAgent::PromptCommandDefinition, message: Ruboty::Message, chat_thread: Ruboty::AiAgent::ChatThread) -> untyped
14
+
15
+ # @rbs commandline: String
16
+ # @rbs return: boolish
17
+ def match?: (String commandline) -> boolish
18
+
19
+ def pattern: () -> Regexp
20
+
21
+ # @rbs commandline: String
22
+ # @rbs return: String
23
+ def call: (commandline: String) -> String
24
+ end
25
+ end
26
+ end
27
+ end
@@ -4,16 +4,8 @@ module Ruboty
4
4
  module AiAgent
5
5
  module Commands
6
6
  # Show token usage information for the latest AI response
7
- class Usage < Base
8
- attr_reader message: Ruboty::Message
9
-
10
- attr_reader chat_thread: Ruboty::AiAgent::ChatThread
11
-
12
- # @rbs message: Ruboty::Message
13
- # @rbs chat_thread: Ruboty::AiAgent::ChatThread
14
- def initialize: (message: Ruboty::Message, chat_thread: Ruboty::AiAgent::ChatThread) -> untyped
15
-
16
- def call: () -> void
7
+ class Usage < BuiltinBase
8
+ def call: (*untyped) -> void
17
9
 
18
10
  private
19
11
 
@@ -6,8 +6,8 @@ module Ruboty
6
6
  module Commands
7
7
  # @rbs message: Ruboty::Message
8
8
  # @rbs chat_thread: ChatThread
9
- # @rbs return: Array[Commands::Base]
10
- def self.builtins: (message: Ruboty::Message, chat_thread: ChatThread) -> Array[Commands::Base]
9
+ # @rbs return: Array[Commands::BuiltinBase]
10
+ def self.builtins: (message: Ruboty::Message, chat_thread: ChatThread) -> Array[Commands::BuiltinBase]
11
11
  end
12
12
  end
13
13
  end
@@ -7,32 +7,38 @@ module Ruboty
7
7
  def data: () -> Hash[keynable, untyped]
8
8
  end
9
9
 
10
+ type query_key = keynable | Symbol | nil
11
+
10
12
  # @rbs module-self _WithData
11
13
  module QueryMethods : _WithData
12
- # @rbs *keys: keynable
14
+ # @rbs keys: Array[query_key]
15
+ # @rbs return: Array[keynable]
16
+ def self.keys_to_keynable: (Array[query_key] keys) -> Array[keynable]
17
+
18
+ # @rbs *keys: query_key
13
19
  # @rbs return: untyped
14
- def fetch: (*keynable keys) -> untyped
20
+ def fetch: (*query_key keys) -> untyped
15
21
 
16
- # @rbs *keys: keynable
22
+ # @rbs *keys: query_key
17
23
  # @rbs return: Integer
18
- def len: (*keynable keys) -> Integer
24
+ def len: (*query_key keys) -> Integer
19
25
 
20
- # @rbs *keys: keynable
26
+ # @rbs *keys: query_key
21
27
  # @rbs return: void
22
- def delete: (*keynable keys) -> void
28
+ def delete: (*query_key keys) -> void
23
29
 
24
- # @rbs *keys: keynable
30
+ # @rbs *keys: query_key
25
31
  # @rbs return: Array[keynable]
26
- def keys: (*keynable keys) -> Array[keynable]
32
+ def keys: (*query_key keys) -> Array[keynable]
27
33
 
28
- # @rbs *keys: keynable
34
+ # @rbs *keys: query_key
29
35
  # @rbs return: boolish
30
- def key?: (*keynable keys) -> boolish
36
+ def key?: (*query_key keys) -> boolish
31
37
 
32
- # @rbs at: Array[keynable]
38
+ # @rbs at: Array[query_key]
33
39
  # @rbs value: untyped
34
40
  # @rbs return: void
35
- def store: (untyped value, at: Array[keynable]) -> void
41
+ def store: (untyped value, at: Array[query_key]) -> void
36
42
  end
37
43
  end
38
44
  end
@@ -4,7 +4,7 @@ module Ruboty
4
4
  module AiAgent
5
5
  # Memorize and retrieve information using Ruboty's brain.
6
6
  class Database
7
- type keynable = Symbol | String | Integer
7
+ type keynable = String | Integer
8
8
 
9
9
  include QueryMethods
10
10
 
@@ -21,6 +21,8 @@ module Ruboty
21
21
 
22
22
  def chat_thread: (untyped id) -> ChatThread
23
23
 
24
+ # @rbs %a{memorized}
25
+ %a{memorized}
24
26
  def global_settings: () -> GlobalSettings
25
27
  end
26
28
  end
@@ -9,9 +9,9 @@ module Ruboty
9
9
 
10
10
  attr_reader model: String
11
11
 
12
- # @rbs client: OpenAI::Client
13
- # @rbs model: String
14
- def initialize: (client: OpenAI::Client, model: String) -> untyped
12
+ # @rbs ?client: OpenAI::Client
13
+ # @rbs ?model: String
14
+ def initialize: (?client: untyped, ?model: untyped) -> untyped
15
15
 
16
16
  # @rbs %a{memorized}
17
17
  %a{memorized}
@@ -4,6 +4,8 @@ module Ruboty
4
4
  module AiAgent
5
5
  type transports = :http | :websocket
6
6
 
7
+ type transports_str = "http" | "websocket"
8
+
7
9
  class McpConfiguration < Data
8
10
  attr_reader name(): String
9
11
 
@@ -26,10 +28,10 @@ module Ruboty
26
28
  include Recordable
27
29
 
28
30
  # @rbs name: String
29
- # @rbs transport: transports
31
+ # @rbs transport: transports | transports_str
30
32
  # @rbs url: String
31
33
  # @rbs headers: Hash[String, String]?
32
- def initialize: (name: String, transport: transports, url: String, ?headers: Hash[String, String]?) -> untyped
34
+ def initialize: (name: String, transport: transports | transports_str, url: String, ?headers: Hash[String, String]?) -> untyped
33
35
  end
34
36
  end
35
37
  end
@@ -0,0 +1,23 @@
1
+ # Generated from lib/ruboty/ai_agent/prompt_command_definition.rb with RBS::Inline
2
+
3
+ module Ruboty
4
+ module AiAgent
5
+ class PromptCommandDefinition < Data
6
+ attr_reader name(): String
7
+
8
+ attr_reader prompt(): String
9
+
10
+ def self.new: (String name, String prompt) -> instance
11
+ | (name: String, prompt: String) -> instance
12
+
13
+ def self.members: () -> [ :name, :prompt ]
14
+
15
+ def members: () -> [ :name, :prompt ]
16
+ end
17
+
18
+ # User-defined command model
19
+ class PromptCommandDefinition
20
+ include Recordable
21
+ end
22
+ end
23
+ end
@@ -9,7 +9,9 @@ module Ruboty
9
9
 
10
10
  def initialize: (database: untyped) -> untyped
11
11
 
12
- def namespace_keys: () -> Array[Database::keynable]
12
+ def namespace_keys: () -> Array[Database::query_key]
13
+
14
+ def empty?: () -> boolish
13
15
 
14
16
  def length: () -> Integer
15
17
 
@@ -19,22 +21,22 @@ module Ruboty
19
21
 
20
22
  def keys: () -> Array[Database::keynable]
21
23
 
22
- # @rbs key: Database::keynable
24
+ # @rbs key: Database::query_key
23
25
  # @rbs return: Record | nil
24
- def fetch: (Database::keynable key) -> (Record | nil)
26
+ def fetch: (Database::query_key key) -> (Record | nil)
25
27
 
26
- # @rbs key: Database::keynable
28
+ # @rbs key: Database::query_key
27
29
  # @rbs record: Record
28
30
  # @rbs return: void
29
- def store: (Record record, key: Database::keynable) -> void
31
+ def store: (Record record, key: Database::query_key) -> void
30
32
 
31
- # @rbs key: Database::keynable
33
+ # @rbs key: Database::query_key
32
34
  # @rbs return: void
33
- def remove: (Database::keynable key) -> void
35
+ def remove: (Database::query_key key) -> void
34
36
 
35
- # @rbs key: Database::keynable
37
+ # @rbs key: Database::query_key
36
38
  # @rbs return: boolish
37
- def key?: (Database::keynable key) -> boolish
39
+ def key?: (Database::query_key key) -> boolish
38
40
 
39
41
  def clear: () -> void
40
42
  end
@@ -3,7 +3,7 @@
3
3
  module Ruboty
4
4
  module AiAgent
5
5
  interface _WithToH
6
- def to_h: () -> Hash[Database::keynable, untyped]
6
+ def to_h: () -> Hash[Symbol, untyped]
7
7
  end
8
8
 
9
9
  # Convertable between Hash and Recordable bidirectionally.
@@ -15,9 +15,9 @@ module Ruboty
15
15
 
16
16
  def self.record_types: () -> Hash[Symbol, Class]
17
17
 
18
- # @rbs hash: Hash[Symbol, untyped]?
18
+ # @rbs hash: Hash[Symbol | String, untyped]?
19
19
  # @rbs return: bool
20
- def self.convertable?: (Hash[Symbol, untyped]? hash) -> bool
20
+ def self.convertable?: (Hash[Symbol | String, untyped]? hash) -> bool
21
21
 
22
22
  # @rbs value: untyped
23
23
  # @rbs return: untyped
@@ -31,9 +31,9 @@ module Ruboty
31
31
  # @rbs return: Hash[Database::keynable, untyped]
32
32
  def self.record_to_hash: (Recordable record) -> Hash[Database::keynable, untyped]
33
33
 
34
- # @rbs hash: Hash[Symbol, untyped]
34
+ # @rbs hash: Hash[Symbol | String, untyped]
35
35
  # @rbs return: Recordable
36
- def self.record_from_hash: (Hash[Symbol, untyped] hash) -> Recordable
36
+ def self.record_from_hash: (Hash[Symbol | String, untyped] hash) -> Recordable
37
37
 
38
38
  # @rbs module-self Class
39
39
  module ClassMethods : Class
@@ -45,7 +45,7 @@ module Ruboty
45
45
 
46
46
  # @rbs module-self Recordable::ClassMethods.instance
47
47
  module PrependMethods : Recordable::ClassMethods
48
- def to_h: () -> Hash[Database::keynable, untyped]
48
+ def to_h: () -> Hash[Symbol, untyped]
49
49
  end
50
50
 
51
51
  # @rbs %a{pure}
@@ -24,6 +24,10 @@ module Ruboty
24
24
  # @rbs return: (Float | nil)
25
25
  def usage_percentage: () -> (Float | nil)
26
26
 
27
+ # Check if usage percentage exceeds auto compact threshold
28
+ # @rbs return: bool
29
+ def over_auto_compact_threshold?: () -> bool
30
+
27
31
  def to_h: () -> Hash[Symbol, untyped]
28
32
  end
29
33
  end
@@ -30,6 +30,10 @@ module Ruboty
30
30
  # @rbs %a{memorized}
31
31
  %a{memorized}
32
32
  def mcp_tools_caches: () -> UserMcpToolsCaches
33
+
34
+ # @rbs %a{memorized}
35
+ %a{memorized}
36
+ def prompt_command_definitions: () -> UserPromptCommandDefinitions
33
37
  end
34
38
  end
35
39
  end
@@ -0,0 +1,12 @@
1
+ # Generated from lib/ruboty/ai_agent/user_prompt_command_definitions.rb with RBS::Inline
2
+
3
+ module Ruboty
4
+ module AiAgent
5
+ # User-defined commands record set
6
+ class UserPromptCommandDefinitions < UserAssociations[PromptCommandDefinition]
7
+ # @rbs command: PromptCommandDefinition
8
+ # @rbs return: PromptCommandDefinition
9
+ def add: (PromptCommandDefinition command) -> PromptCommandDefinition
10
+ end
11
+ end
12
+ end
@@ -4,29 +4,29 @@ module Ruboty
4
4
  module Handlers
5
5
  # Handler for AI agent commands
6
6
  class AiAgent < Base
7
- def chat: (untyped message) -> untyped
7
+ def chat: (untyped message) -> true
8
8
 
9
- def add_mcp: (untyped message) -> untyped
9
+ def add_mcp: (untyped message) -> true
10
10
 
11
- def remove_mcp: (untyped message) -> untyped
11
+ def remove_mcp: (untyped message) -> true
12
12
 
13
- def list_mcp: (untyped message) -> untyped
13
+ def list_mcp: (untyped message) -> true
14
14
 
15
- def set_system_prompt: (untyped message) -> untyped
15
+ def set_system_prompt: (untyped message) -> true
16
16
 
17
- def show_system_prompt: (untyped message) -> untyped
17
+ def show_system_prompt: (untyped message) -> true
18
18
 
19
- def add_ai_memory: (untyped message) -> untyped
19
+ def add_ai_memory: (untyped message) -> true
20
20
 
21
- def remove_ai_memory: (untyped message) -> untyped
21
+ def remove_ai_memory: (untyped message) -> true
22
22
 
23
- def list_ai_memories: (untyped message) -> untyped
23
+ def list_ai_memories: (untyped message) -> true
24
24
 
25
- def add_ai_command: (untyped message) -> untyped
25
+ def add_ai_command: (untyped message) -> true
26
26
 
27
- def remove_ai_command: (untyped message) -> untyped
27
+ def remove_ai_command: (untyped message) -> true
28
28
 
29
- def list_ai_commands: (untyped message) -> untyped
29
+ def list_ai_commands: (untyped message) -> true
30
30
  end
31
31
  end
32
32
  end