@@ -25,44 +25,40 @@ func (DebuggerTool) Description() string {
2525Prefer this over adding print statements when you need to understand runtime state.`
2626}
2727
28- func (DebuggerTool ) Parameters () map [string ]interface {} {
29- return map [string ]interface {}{
30- "type" : "object" ,
31- "properties" : map [string ]interface {}{
32- "action" : map [string ]interface {}{
33- "type" : "string" ,
34- "description" : "Action: breakpoint, run, inspect, step, continue, stack" ,
35- "enum" : []string {"breakpoint" , "run" , "inspect" , "step" , "continue" , "stack" },
36- },
37- "file" : map [string ]interface {}{
38- "type" : "string" ,
39- "description" : "File path (for breakpoint action)" ,
40- },
41- "line" : map [string ]interface {}{
42- "type" : "integer" ,
43- "description" : "Line number (for breakpoint action)" ,
44- },
45- "expression" : map [string ]interface {}{
46- "type" : "string" ,
47- "description" : "Expression to evaluate (for inspect action)" ,
48- },
28+ // Schema returns the typed input schema. Parameters() delegates to it so the
29+ // two cannot diverge.
30+ func (DebuggerTool ) Schema () ToolSchema {
31+ return ToolSchema {
32+ Type : "object" ,
33+ Properties : map [string ]SchemaProperty {
34+ "action" : {Type : "string" , Enum : []interface {}{"breakpoint" , "run" , "inspect" , "step" , "continue" , "stack" }, Description : "Action: breakpoint, run, inspect, step, continue, stack" },
35+ "file" : {Type : "string" , Description : "File path (for breakpoint action)" },
36+ "line" : {Type : "integer" , Description : "Line number (for breakpoint action)" },
37+ "expression" : {Type : "string" , Description : "Expression to evaluate (for inspect action)" },
4938 },
50- "required" : []string {"action" },
39+ Required : []string {"action" },
5140 }
5241}
5342
54- // debugParams holds the parsed input parameters.
55- type debugParams struct {
43+ func (DebuggerTool ) Parameters () map [string ]interface {} {
44+ return debuggerSchema .ToJSONSchema ()
45+ }
46+
47+ // debuggerSchema is the single source of truth for Debugger's input schema.
48+ var debuggerSchema = DebuggerTool {}.Schema ()
49+
50+ // DebuggerInput is the typed input for DebuggerTool.
51+ type DebuggerInput struct {
5652 Action string `json:"action"`
5753 File string `json:"file"`
5854 Line int `json:"line"`
5955 Expression string `json:"expression"`
6056}
6157
6258func (DebuggerTool ) Execute (ctx context.Context , input json.RawMessage ) (string , error ) {
63- var p debugParams
64- if err := json . Unmarshal ( input , & p ); err != nil {
65- return "" , fmt . Errorf ( "invalid input: %w" , err )
59+ p , err := DecodeInput [ DebuggerInput ]( "Debug" , input )
60+ if err != nil {
61+ return "" , err
6662 }
6763
6864 if err := validateDebugParams (p ); err != nil {
@@ -88,7 +84,7 @@ func (DebuggerTool) Execute(ctx context.Context, input json.RawMessage) (string,
8884}
8985
9086// validateDebugParams ensures required fields are present for each action.
91- func validateDebugParams (p debugParams ) error {
87+ func validateDebugParams (p DebuggerInput ) error {
9288 switch p .Action {
9389 case "" :
9490 return fmt .Errorf ("action is required" )
@@ -126,7 +122,7 @@ func detectDebugLanguage(file string) string {
126122 }
127123}
128124
129- func debugBreakpoint (ctx context.Context , p debugParams ) (string , error ) {
125+ func debugBreakpoint (ctx context.Context , p DebuggerInput ) (string , error ) {
130126 lang := detectDebugLanguage (p .File )
131127 switch lang {
132128 case "go" :
@@ -148,7 +144,7 @@ func debugBreakpoint(ctx context.Context, p debugParams) (string, error) {
148144 }
149145}
150146
151- func debugRun (ctx context.Context , p debugParams ) (string , error ) {
147+ func debugRun (ctx context.Context , p DebuggerInput ) (string , error ) {
152148 file := p .File
153149 if file == "" {
154150 file = "."
@@ -184,7 +180,7 @@ func debugRun(ctx context.Context, p debugParams) (string, error) {
184180 }
185181}
186182
187- func debugInspect (ctx context.Context , p debugParams ) (string , error ) {
183+ func debugInspect (ctx context.Context , p DebuggerInput ) (string , error ) {
188184 // For Go, use dlv eval.
189185 cmd := exec .CommandContext (ctx , "dlv" , "eval" , p .Expression ) // #nosec G204 -- debugger/interpreter invocation with file path or expression from tool params
190186 out , err := cmd .CombinedOutput ()
0 commit comments