debug-agent 0.2.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.
@@ -0,0 +1,97 @@
1
+ module DebugAgent
2
+ CATEGORY_MAP = {
3
+ 'gc' => 'Memory & GC',
4
+ 'object_space' => 'Memory & GC',
5
+ 'memory' => 'Memory & GC',
6
+ 'object_count' => 'Memory & GC',
7
+ 'allocations' => 'Memory & GC',
8
+ 'force_gc' => 'Memory & GC',
9
+ 'trigger_gc' => 'Memory & GC',
10
+ 'process' => 'Process Info',
11
+ 'cpu' => 'Process Info',
12
+ 'uptime' => 'Process Info',
13
+ 'thread' => 'Threads',
14
+ 'system' => 'System Info',
15
+ 'disk' => 'System Info',
16
+ 'environment' => 'System Info',
17
+ 'routes' => 'Framework & Routes',
18
+ 'middleware' => 'Framework & Routes',
19
+ 'runtime' => 'Runtime Info',
20
+ 'recent' => 'HTTP Requests',
21
+ 'slow' => 'HTTP Requests',
22
+ 'error' => 'HTTP Requests',
23
+ 'request' => 'HTTP Requests',
24
+ 'gem' => 'Dependencies',
25
+ 'module' => 'Module Info',
26
+ }.freeze
27
+
28
+ class SystemPromptBuilder
29
+ def initialize(tool_registry = REGISTRY)
30
+ @registry = tool_registry
31
+ end
32
+
33
+ def build
34
+ categories = categorize_tools
35
+
36
+ sb = +''
37
+ sb << "You are an expert Ruby runtime debugging assistant.\n"
38
+ sb << "You are running INSIDE the developer's Ruby application and have direct access\n"
39
+ sb << "to its runtime state through diagnostic tools.\n\n"
40
+ sb << "## Your Capabilities\n"
41
+ sb << "You can call tools to inspect the live application. Here are ALL available tools,\n"
42
+ sb << "grouped by category:\n\n"
43
+
44
+ categories.keys.sort.each do |category|
45
+ sb << "**#{category}\n"
46
+ categories[category].each do |t|
47
+ sb << "- `#{t[:name]}`: #{truncate(t[:desc])}\n"
48
+ end
49
+ sb << "\n"
50
+ end
51
+
52
+ sb << "## Workflow\n"
53
+ sb << "1. Understand the developer's problem description\n"
54
+ sb << "2. Proactively call the most relevant tools to gather diagnostic data\n"
55
+ sb << "3. Analyze the collected data to identify root causes\n"
56
+ sb << "4. Provide clear, actionable solutions with data evidence\n\n"
57
+ sb << "## Guidelines\n"
58
+ sb << "- Be proactive: gather data with tools before answering\n"
59
+ sb << "- Always present data in a readable format (tables, bullet points)\n"
60
+ sb << "- Respond in the same language the developer uses\n"
61
+ sb << "- When you find a problem, explain the root cause and give concrete fix suggestions\n"
62
+ sb << "- You can call multiple tools in parallel if they are independent\n"
63
+
64
+ sb.freeze
65
+ end
66
+
67
+ private
68
+
69
+ def categorize_tools
70
+ categories = Hash.new { |h, k| h[k] = [] }
71
+ @registry.all_schemas.each do |schema|
72
+ fn = schema['function']
73
+ name = fn['name']
74
+ desc = fn['description']
75
+ category = extract_category(name)
76
+ categories[category] << { name: name, desc: desc }
77
+ end
78
+ categories
79
+ end
80
+
81
+ def extract_category(tool_name)
82
+ name_lower = tool_name.downcase
83
+ CATEGORY_MAP.each do |keyword, category|
84
+ return category if name_lower.include?(keyword)
85
+ end
86
+ 'Other Tools'
87
+ end
88
+
89
+ def truncate(desc)
90
+ return '' if desc.nil? || desc.empty?
91
+ period = desc.index('.')
92
+ return desc[0..period] if period && period > 0 && period < 150
93
+ return desc[0..116] + '...' if desc.length > 120
94
+ desc
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,97 @@
1
+ require 'json'
2
+
3
+ module DebugAgent
4
+ ToolParam = Struct.new(:description, :required, keyword_init: true) do
5
+ def initialize(description:, required: true)
6
+ super
7
+ end
8
+ end
9
+
10
+ ToolDefinition = Struct.new(:name, :description, :func, :params, keyword_init: true)
11
+
12
+ class ToolRegistry
13
+ def initialize
14
+ @tools = {}
15
+ end
16
+
17
+ def register(tool)
18
+ @tools[tool.name] = tool
19
+ end
20
+
21
+ def get(name)
22
+ @tools[name]
23
+ end
24
+
25
+ def all_schemas
26
+ @tools.values.map(&:to_schema)
27
+ end
28
+
29
+ def execute(name, args)
30
+ tool = @tools[name]
31
+ return { error: "Unknown tool: #{name}" } unless tool
32
+
33
+ begin
34
+ result = tool.func.call(**args)
35
+ result
36
+ rescue => e
37
+ { error: e.message }
38
+ end
39
+ end
40
+
41
+ def names
42
+ @tools.keys
43
+ end
44
+ end
45
+
46
+ module ToolDefinitionExt
47
+ def to_schema
48
+ properties = {}
49
+ required = []
50
+
51
+ (params || {}).each do |pname, pmeta|
52
+ properties[pname.to_s] = {
53
+ 'type' => pmeta[:type] || 'string',
54
+ 'description' => pmeta[:description] || ''
55
+ }
56
+ required << pname.to_s if pmeta[:required] != false
57
+ end
58
+
59
+ {
60
+ 'type' => 'function',
61
+ 'function' => {
62
+ 'name' => name,
63
+ 'description' => description,
64
+ 'parameters' => {
65
+ 'type' => 'object',
66
+ 'properties' => properties,
67
+ 'required' => required
68
+ }
69
+ }
70
+ }
71
+ end
72
+ end
73
+
74
+ # Patch Struct to include schema method
75
+ ToolDefinition.prepend(ToolDefinitionExt)
76
+
77
+ # Global registry singleton
78
+ REGISTRY = ToolRegistry.new
79
+
80
+ module ClassMethods
81
+ def registry
82
+ REGISTRY
83
+ end
84
+
85
+ def register_tool(name, description, params = {}, &block)
86
+ tool = ToolDefinition.new(
87
+ name: name,
88
+ description: description,
89
+ func: block,
90
+ params: params
91
+ )
92
+ REGISTRY.register(tool)
93
+ end
94
+ end
95
+
96
+ extend ClassMethods
97
+ end
@@ -0,0 +1,3 @@
1
+ module DebugAgent
2
+ VERSION = '0.2.6'.freeze
3
+ end
@@ -0,0 +1,34 @@
1
+ require_relative 'debug_agent/version'
2
+ require_relative 'debug_agent/config'
3
+ require_relative 'debug_agent/tool_registry'
4
+ require_relative 'debug_agent/llm_client'
5
+ require_relative 'debug_agent/chat_session'
6
+ require_relative 'debug_agent/system_prompt_builder'
7
+ require_relative 'debug_agent/context_compressor'
8
+ require_relative 'debug_agent/engine'
9
+ require_relative 'debug_agent/chat_page'
10
+ require_relative 'debug_agent/middleware'
11
+
12
+ # Auto-register built-in inspectors
13
+ require_relative 'debug_agent/inspectors/runtime'
14
+ require_relative 'debug_agent/inspectors/http_tracker'
15
+ require_relative 'debug_agent/inspectors/system'
16
+ require_relative 'debug_agent/inspectors/gc'
17
+ require_relative 'debug_agent/inspectors/object_space'
18
+ require_relative 'debug_agent/inspectors/threads'
19
+ require_relative 'debug_agent/inspectors/routes'
20
+ require_relative 'debug_agent/inspectors/process_info'
21
+
22
+ module DebugAgent
23
+ class Error < StandardError; end
24
+
25
+ # Process start time for uptime tracking
26
+ PROCESS_START_TIME = Time.now
27
+
28
+ # Reference to the wrapped Rack/Sinatra app for route/middleware inspection
29
+ @app = nil
30
+
31
+ class << self
32
+ attr_accessor :app
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: debug-agent
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ platform: ruby
6
+ authors:
7
+ - ggcode
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: json
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '2.6'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '2.6'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '3.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '3.0'
54
+ description: Embed an AI debugging assistant into your Ruby web app. Inspect GC, threads,
55
+ memory, ObjectSpace, routes, HTTP requests, and more.
56
+ email:
57
+ - noreply@ggcode.dev
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - README.md
63
+ - lib/debug_agent.rb
64
+ - lib/debug_agent/chat_page.rb
65
+ - lib/debug_agent/chat_session.rb
66
+ - lib/debug_agent/config.rb
67
+ - lib/debug_agent/context_compressor.rb
68
+ - lib/debug_agent/engine.rb
69
+ - lib/debug_agent/inspectors/gc.rb
70
+ - lib/debug_agent/inspectors/http_tracker.rb
71
+ - lib/debug_agent/inspectors/object_space.rb
72
+ - lib/debug_agent/inspectors/process_info.rb
73
+ - lib/debug_agent/inspectors/routes.rb
74
+ - lib/debug_agent/inspectors/runtime.rb
75
+ - lib/debug_agent/inspectors/system.rb
76
+ - lib/debug_agent/inspectors/threads.rb
77
+ - lib/debug_agent/llm_client.rb
78
+ - lib/debug_agent/middleware.rb
79
+ - lib/debug_agent/system_prompt_builder.rb
80
+ - lib/debug_agent/tool_registry.rb
81
+ - lib/debug_agent/version.rb
82
+ homepage: https://github.com/topcheer/ruby-debug-agent
83
+ licenses:
84
+ - MIT
85
+ metadata:
86
+ homepage_uri: https://github.com/topcheer/ruby-debug-agent
87
+ source_code_uri: https://github.com/topcheer/ruby-debug-agent
88
+ bug_tracker_uri: https://github.com/topcheer/ruby-debug-agent/issues
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '2.7'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 4.0.10
104
+ specification_version: 4
105
+ summary: AI-powered runtime debugging agent for Ruby applications
106
+ test_files: []