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.
- checksums.yaml +7 -0
- data/README.md +144 -0
- data/lib/debug_agent/chat_page.rb +575 -0
- data/lib/debug_agent/chat_session.rb +47 -0
- data/lib/debug_agent/config.rb +34 -0
- data/lib/debug_agent/context_compressor.rb +159 -0
- data/lib/debug_agent/engine.rb +162 -0
- data/lib/debug_agent/inspectors/gc.rb +90 -0
- data/lib/debug_agent/inspectors/http_tracker.rb +70 -0
- data/lib/debug_agent/inspectors/object_space.rb +74 -0
- data/lib/debug_agent/inspectors/process_info.rb +61 -0
- data/lib/debug_agent/inspectors/routes.rb +114 -0
- data/lib/debug_agent/inspectors/runtime.rb +81 -0
- data/lib/debug_agent/inspectors/system.rb +61 -0
- data/lib/debug_agent/inspectors/threads.rb +67 -0
- data/lib/debug_agent/llm_client.rb +221 -0
- data/lib/debug_agent/middleware.rb +127 -0
- data/lib/debug_agent/system_prompt_builder.rb +97 -0
- data/lib/debug_agent/tool_registry.rb +97 -0
- data/lib/debug_agent/version.rb +3 -0
- data/lib/debug_agent.rb +34 -0
- metadata +106 -0
|
@@ -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
|
data/lib/debug_agent.rb
ADDED
|
@@ -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: []
|