From 1d85120a6fc0a483835d38e250b2f6a5b1a3b595 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Sun, 5 Oct 2025 13:56:40 +0000 Subject: [PATCH 1/9] feat(cli): Add YAML and JSON output format support - Add global --output/-o flag with yaml (default) and json options - Implement structured output for all major commands (tasks list/get/history, config list, agent-card, connect, version, submit) - Use standard libraries: gopkg.in/yaml.v3 and encoding/json - Add comprehensive tests for output formatting functions - Update documentation with examples and usage instructions - Remove deprecated displayPart function - YAML is now the default output format as requested Resolves #14 Co-authored-by: Eden Reich --- README.md | 58 ++++++++ cli/cli.go | 297 +++++++++++------------------------------ cli/cli_output_test.go | 192 ++++++++++++++++++++++++++ 3 files changed, 329 insertions(+), 218 deletions(-) create mode 100644 cli/cli_output_test.go diff --git a/README.md b/README.md index 3ac4dcb..15fb5a7 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ A powerful command-line utility for debugging, monitoring, and inspecting A2A se - **Flexible Configuration**: Support for configuration files and environment variables - **Debug Logging**: Comprehensive logging with configurable verbosity levels - **Namespace Commands**: Organized command structure with `config` and `tasks` namespaces +- **Multiple Output Formats**: Support for YAML (default) and JSON output formats for structured data ## šŸ“¦ Installation @@ -148,6 +149,7 @@ server-url: http://localhost:8080 timeout: 30s debug: false insecure: false +output: yaml # or json ``` ### Command Options @@ -159,6 +161,7 @@ insecure: false - `--debug`: Enable debug logging - `--insecure`: Skip TLS verification - `--config`: Config file path +- `--output, -o`: Output format (yaml|json) (default: yaml) #### Task List Options @@ -268,6 +271,61 @@ Task: task-abc123 (Status: completed) 1: Hello! How can I help you today? ``` +#### Output Formats + +By default, all commands output structured data in YAML format. You can switch to JSON using the `-o` flag: + +```bash +# YAML output (default) +$ a2a tasks list --limit 2 +tasks: + - id: task-abc123 + context_id: ctx-xyz789 + kind: task + status: + state: completed + message: + message_id: msg-456 + role: assistant + artifacts: [] + metadata: {} + - id: task-def456 + context_id: ctx-uvw123 + kind: task + status: + state: working + message: + message_id: msg-789 + role: user + artifacts: [] + metadata: {} +total: 23 +showing: 2 + +# JSON output +$ a2a tasks list --limit 2 -o json +{ + "tasks": [ + { + "id": "task-abc123", + "context_id": "ctx-xyz789", + "kind": "task", + "status": { + "state": "completed", + "message": { + "message_id": "msg-456", + "role": "assistant" + } + }, + "artifacts": [], + "metadata": {} + } + ], + "total": 23, + "showing": 2 +} +``` + ## šŸ› ļø Development ### Prerequisites diff --git a/cli/cli.go b/cli/cli.go index 59432dc..e4c8942 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -15,6 +15,7 @@ import ( cobra "github.com/spf13/cobra" viper "github.com/spf13/viper" zap "go.uber.org/zap" + yaml "gopkg.in/yaml.v3" ) var ( @@ -65,6 +66,7 @@ func init() { rootCmd.PersistentFlags().Duration("timeout", 30*time.Second, "Request timeout") rootCmd.PersistentFlags().Bool("debug", false, "Enable debug logging") rootCmd.PersistentFlags().Bool("insecure", false, "Skip TLS verification") + rootCmd.PersistentFlags().StringP("output", "o", "yaml", "Output format (yaml|json)") err := viper.BindPFlag("server-url", rootCmd.PersistentFlags().Lookup("server-url")) if err != nil { @@ -86,6 +88,11 @@ func init() { log.Fatalf("bind error: %v", err) } + err = viper.BindPFlag("output", rootCmd.PersistentFlags().Lookup("output")) + if err != nil { + log.Fatalf("bind error: %v", err) + } + configCmd.AddCommand(configSetCmd) configCmd.AddCommand(configGetCmd) configCmd.AddCommand(configListCmd) @@ -196,79 +203,51 @@ func handleA2AError(err error, method string) error { return err } -// displayPart displays a message part with proper formatting based on its type -func displayPart(part interface{}, partIndex int, prefix string) { - if partMap, ok := part.(map[string]interface{}); ok { - kind, kindExists := partMap["kind"] - if !kindExists { - fmt.Printf("%s%d. Unknown part (no kind field)\n", prefix, partIndex) - return - } +// OutputFormat represents supported output formats +type OutputFormat string - switch kind { - case "text": - if text, exists := partMap["text"]; exists { - fmt.Printf("%s%d. [Text] %v\n", prefix, partIndex, text) - } else { - fmt.Printf("%s%d. [Text] (no text content)\n", prefix, partIndex) - } +const ( + OutputFormatYAML OutputFormat = "yaml" + OutputFormatJSON OutputFormat = "json" +) - case "data": - fmt.Printf("%s%d. [Data] ", prefix, partIndex) - if data, exists := partMap["data"]; exists { - // Pretty print the data content - if dataJSON, err := json.MarshalIndent(data, "", " "); err == nil { - fmt.Printf("\n%s %s\n", prefix, strings.ReplaceAll(string(dataJSON), "\n", "\n"+prefix+" ")) - } else { - fmt.Printf("%v\n", data) - } - } else { - fmt.Printf("(no data content)\n") - } +// getOutputFormat returns the configured output format +func getOutputFormat() OutputFormat { + format := viper.GetString("output") + switch strings.ToLower(format) { + case "json": + return OutputFormatJSON + case "yaml": + return OutputFormatYAML + default: + return OutputFormatYAML // Default to YAML + } +} - case "file": - fmt.Printf("%s%d. [File] ", prefix, partIndex) - if file, exists := partMap["file"]; exists { - if fileMap, ok := file.(map[string]interface{}); ok { - if name, exists := fileMap["name"]; exists { - fmt.Printf("Name: %v", name) - } - if mimeType, exists := fileMap["mimeType"]; exists { - fmt.Printf(" Type: %v", mimeType) - } - if uri, exists := fileMap["uri"]; exists { - fmt.Printf(" URI: %v", uri) - } else if bytes, exists := fileMap["bytes"]; exists { - if bytesStr, ok := bytes.(string); ok { - fmt.Printf(" Size: %d bytes", len(bytesStr)) - } - } - } - fmt.Printf("\n") - } else { - fmt.Printf("(no file content)\n") - } +// formatOutput formats the given data according to the specified format +func formatOutput(data interface{}) ([]byte, error) { + format := getOutputFormat() + switch format { + case OutputFormatJSON: + return json.MarshalIndent(data, "", " ") + case OutputFormatYAML: + return yaml.Marshal(data) + default: + return yaml.Marshal(data) + } +} - default: - fmt.Printf("%s%d. [%v] ", prefix, partIndex, kind) - // Try to display any content we can find - if text, exists := partMap["text"]; exists { - fmt.Printf("Text: %v\n", text) - } else if data, exists := partMap["data"]; exists { - if dataJSON, err := json.MarshalIndent(data, "", " "); err == nil { - fmt.Printf("Data:\n%s %s\n", prefix, strings.ReplaceAll(string(dataJSON), "\n", "\n"+prefix+" ")) - } else { - fmt.Printf("Data: %v\n", data) - } - } else { - fmt.Printf("(unknown content)\n") - } - } - } else { - fmt.Printf("%s%d. Invalid part format\n", prefix, partIndex) +// printFormatted outputs the data in the configured format +func printFormatted(data interface{}) error { + output, err := formatOutput(data) + if err != nil { + return fmt.Errorf("failed to format output: %w", err) } + fmt.Print(string(output)) + return nil } + // Config namespace command var configCmd = &cobra.Command{ Use: "config", @@ -325,18 +304,7 @@ var configListCmd = &cobra.Command{ Long: "List all configuration values from the A2A debugger config file.", RunE: func(cmd *cobra.Command, args []string) error { settings := viper.AllSettings() - - if len(settings) == 0 { - fmt.Printf("No configuration found\n") - return nil - } - - fmt.Printf("šŸ“‹ Configuration:\n\n") - for key, value := range settings { - fmt.Printf(" %s = %v\n", key, value) - } - - return nil + return printFormatted(settings) }, } @@ -362,25 +330,13 @@ var connectCmd = &cobra.Command{ return fmt.Errorf("failed to connect to A2A server: %w", err) } - fmt.Printf("āœ… Successfully connected to A2A server!\n\n") - fmt.Printf("Agent Information:\n") - fmt.Printf(" Name: %s\n", agentCard.Name) - fmt.Printf(" Description: %s\n", agentCard.Description) - fmt.Printf(" Version: %s\n", agentCard.Version) - fmt.Printf(" URL: %s\n", agentCard.URL) - - fmt.Printf("\nCapabilities:\n") - if agentCard.Capabilities.Streaming != nil { - fmt.Printf(" Streaming: %t\n", *agentCard.Capabilities.Streaming) - } - if agentCard.Capabilities.PushNotifications != nil { - fmt.Printf(" Push Notifications: %t\n", *agentCard.Capabilities.PushNotifications) - } - if agentCard.Capabilities.StateTransitionHistory != nil { - fmt.Printf(" State Transition History: %t\n", *agentCard.Capabilities.StateTransitionHistory) + // Create structured output with connection status + output := map[string]interface{}{ + "connected": true, + "agent": agentCard, } - return nil + return printFormatted(output) }, } @@ -428,56 +384,14 @@ var listTasksCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task list: %w", err) } - fmt.Printf("šŸ“‹ Tasks (Total: %d, Showing: %d)\n\n", taskList.Total, len(taskList.Tasks)) - - if len(taskList.Tasks) == 0 { - fmt.Printf("No tasks found.\n") - return nil - } - - for i, task := range taskList.Tasks { - fmt.Printf("%d. Task ID: %s\n", i+1, task.ID) - fmt.Printf(" Context ID: %s\n", task.ContextID) - fmt.Printf(" Kind: %s\n", task.Kind) - fmt.Printf(" Status: %s\n", task.Status.State) - if task.Status.Message != nil { - fmt.Printf(" Message ID: %s\n", task.Status.Message.MessageID) - fmt.Printf(" Role: %s\n", task.Status.Message.Role) - } - if task.Status.Timestamp != nil { - fmt.Printf(" Timestamp: %s\n", *task.Status.Timestamp) - } - - if len(task.Artifacts) > 0 { - fmt.Printf(" Artifacts (%d):\n", len(task.Artifacts)) - for j, artifact := range task.Artifacts { - fmt.Printf(" %d. ID: %s", j+1, artifact.ArtifactID) - if artifact.Name != nil { - fmt.Printf(" | Name: %s", *artifact.Name) - } - if artifact.Description != nil { - fmt.Printf(" | Description: %s", *artifact.Description) - } - fmt.Printf(" | Parts: %d", len(artifact.Parts)) - fmt.Printf("\n") - } - } else { - fmt.Printf(" Artifacts: None\n") - } - - if len(task.Metadata) > 0 { - fmt.Printf(" Metadata:\n") - for key, value := range task.Metadata { - fmt.Printf(" %s: %v\n", key, value) - } - } else { - fmt.Printf(" Metadata: None\n") - } - - fmt.Printf("\n") + // Create structured output + output := map[string]interface{}{ + "tasks": taskList.Tasks, + "total": taskList.Total, + "showing": len(taskList.Tasks), } - return nil + return printFormatted(output) }, } @@ -519,33 +433,7 @@ var getTaskCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task: %w", err) } - fmt.Printf("šŸ” Task Details\n\n") - fmt.Printf("ID: %s\n", task.ID) - fmt.Printf("Context ID: %s\n", task.ContextID) - fmt.Printf("Status: %s\n", task.Status.State) - - if task.Status.Message != nil { - fmt.Printf("\nCurrent Message:\n") - fmt.Printf(" Message ID: %s\n", task.Status.Message.MessageID) - fmt.Printf(" Role: %s\n", task.Status.Message.Role) - fmt.Printf(" Parts: %d\n", len(task.Status.Message.Parts)) - - for i, part := range task.Status.Message.Parts { - displayPart(part, i+1, " ") - } - } - - if len(task.History) > 0 { - fmt.Printf("\nConversation History (%d messages):\n", len(task.History)) - for i, msg := range task.History { - fmt.Printf(" %d. [%s] %s\n", i+1, msg.Role, msg.MessageID) - for j, part := range msg.Parts { - displayPart(part, j+1, " ") - } - } - } - - return nil + return printFormatted(task) }, } @@ -581,35 +469,13 @@ var historyCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task list: %w", err) } - if len(taskList.Tasks) == 0 { - fmt.Printf("No conversation history found for context: %s\n", contextID) - return nil - } - - fmt.Printf("šŸ’¬ Conversation History for Context: %s\n\n", contextID) - - for _, task := range taskList.Tasks { - fmt.Printf("Task: %s (Status: %s)\n", task.ID, task.Status.State) - - if len(task.History) > 0 { - for i, msg := range task.History { - fmt.Printf(" %d. [%s] %s\n", i+1, msg.Role, msg.MessageID) - for j, part := range msg.Parts { - displayPart(part, j+1, " ") - } - } - } - - if task.Status.Message != nil { - fmt.Printf(" Current: [%s] %s\n", task.Status.Message.Role, task.Status.Message.MessageID) - for j, part := range task.Status.Message.Parts { - displayPart(part, j+1, " ") - } - } - fmt.Printf("\n") + // Create structured output + output := map[string]interface{}{ + "context_id": contextID, + "tasks": taskList.Tasks, } - return nil + return printFormatted(output) }, } @@ -628,15 +494,7 @@ var agentCardCmd = &cobra.Command{ return handleA2AError(err, "agent-card") } - agentCardJSON, err := json.MarshalIndent(agentCard, "", " ") - if err != nil { - return fmt.Errorf("failed to marshal agent card: %w", err) - } - - fmt.Printf("šŸ¤– Agent Card\n\n") - fmt.Printf("%s\n", agentCardJSON) - - return nil + return printFormatted(agentCard) }, } @@ -644,11 +502,14 @@ var versionCmd = &cobra.Command{ Use: "version", Short: "Print version information", Long: "Display version information including version number, commit hash, and build date.", - Run: func(cmd *cobra.Command, args []string) { - fmt.Printf("A2A Debugger\n") - fmt.Printf("Version: %s\n", appVersion) - fmt.Printf("Commit: %s\n", buildCommit) - fmt.Printf("Built: %s\n", buildDate) + RunE: func(cmd *cobra.Command, args []string) error { + version := map[string]interface{}{ + "name": "A2A Debugger", + "version": appVersion, + "commit": buildCommit, + "built": buildDate, + } + return printFormatted(version) }, } @@ -706,14 +567,14 @@ var submitTaskCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task: %w", err) } - fmt.Printf("āœ… Task submitted successfully!\n\n") - fmt.Printf("Task Details:\n") - fmt.Printf(" Task ID: %s\n", task.ID) - fmt.Printf(" Context ID: %s\n", task.ContextID) - fmt.Printf(" Status: %s\n", task.Status.State) - fmt.Printf(" Message ID: %s\n", messageID) + // Create structured output + output := map[string]interface{}{ + "submitted": true, + "message_id": messageID, + "task": task, + } - return nil + return printFormatted(output) }, } diff --git a/cli/cli_output_test.go b/cli/cli_output_test.go new file mode 100644 index 0000000..51fd361 --- /dev/null +++ b/cli/cli_output_test.go @@ -0,0 +1,192 @@ +package cli + +import ( + "bytes" + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/spf13/viper" + "gopkg.in/yaml.v3" +) + +func TestGetOutputFormat(t *testing.T) { + tests := []struct { + name string + configValue string + expectedFormat OutputFormat + }{ + { + name: "Default YAML format", + configValue: "", + expectedFormat: OutputFormatYAML, + }, + { + name: "Explicit YAML format", + configValue: "yaml", + expectedFormat: OutputFormatYAML, + }, + { + name: "JSON format", + configValue: "json", + expectedFormat: OutputFormatJSON, + }, + { + name: "Case insensitive JSON", + configValue: "JSON", + expectedFormat: OutputFormatJSON, + }, + { + name: "Invalid format defaults to YAML", + configValue: "invalid", + expectedFormat: OutputFormatYAML, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Set up viper configuration + if tt.configValue != "" { + viper.Set("output", tt.configValue) + } else { + viper.Set("output", "yaml") // Set default + } + + format := getOutputFormat() + if format != tt.expectedFormat { + t.Errorf("Expected format %v, got %v", tt.expectedFormat, format) + } + }) + } +} + +func TestFormatOutput(t *testing.T) { + testData := map[string]interface{}{ + "name": "test", + "version": "1.0.0", + "active": true, + } + + tests := []struct { + name string + outputFormat string + data interface{} + validate func([]byte) error + }{ + { + name: "YAML output", + outputFormat: "yaml", + data: testData, + validate: func(output []byte) error { + var result map[string]interface{} + if err := yaml.Unmarshal(output, &result); err != nil { + return fmt.Errorf("failed to parse YAML: %w", err) + } + if result["name"] != "test" { + return fmt.Errorf("expected name 'test', got %v", result["name"]) + } + return nil + }, + }, + { + name: "JSON output", + outputFormat: "json", + data: testData, + validate: func(output []byte) error { + var result map[string]interface{} + if err := json.Unmarshal(output, &result); err != nil { + return fmt.Errorf("failed to parse JSON: %w", err) + } + if result["name"] != "test" { + return fmt.Errorf("expected name 'test', got %v", result["name"]) + } + return nil + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + viper.Set("output", tt.outputFormat) + + output, err := formatOutput(tt.data) + if err != nil { + t.Fatalf("formatOutput failed: %v", err) + } + + if err := tt.validate(output); err != nil { + t.Errorf("Validation failed: %v", err) + } + }) + } +} + +func TestPrintFormatted(t *testing.T) { + testData := map[string]interface{}{ + "message": "hello world", + "status": "success", + } + + tests := []struct { + name string + outputFormat string + expectError bool + }{ + { + name: "YAML print success", + outputFormat: "yaml", + expectError: false, + }, + { + name: "JSON print success", + outputFormat: "json", + expectError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + viper.Set("output", tt.outputFormat) + + // Capture stdout + oldStdout := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + err := printFormatted(testData) + + _ = w.Close() + os.Stdout = oldStdout + var buf bytes.Buffer + _, _ = buf.ReadFrom(r) + output := buf.String() + + if tt.expectError && err == nil { + t.Error("Expected error but got none") + } + if !tt.expectError && err != nil { + t.Errorf("Unexpected error: %v", err) + } + + if !tt.expectError { + if len(output) == 0 { + t.Error("Expected output but got none") + } + + // Verify the output can be parsed back + if tt.outputFormat == "json" { + var result map[string]interface{} + if err := json.Unmarshal([]byte(output), &result); err != nil { + t.Errorf("Failed to parse JSON output: %v", err) + } + } else { + var result map[string]interface{} + if err := yaml.Unmarshal([]byte(output), &result); err != nil { + t.Errorf("Failed to parse YAML output: %v", err) + } + } + } + }) + } +} \ No newline at end of file From f2ffa5ae62c4edd701c1584333bb4bdf1a15d615 Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:22:26 +0200 Subject: [PATCH 2/9] chore(cli): Remove unnecessary blank lines and ensure consistent formatting Signed-off-by: Eden Reich --- cli/cli.go | 39 +++++++++++++++++---------------------- cli/cli_output_test.go | 2 +- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/cli/cli.go b/cli/cli.go index e4c8942..534dc49 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -247,7 +247,6 @@ func printFormatted(data interface{}) error { return nil } - // Config namespace command var configCmd = &cobra.Command{ Use: "config", @@ -330,10 +329,9 @@ var connectCmd = &cobra.Command{ return fmt.Errorf("failed to connect to A2A server: %w", err) } - // Create structured output with connection status output := map[string]interface{}{ "connected": true, - "agent": agentCard, + "agent": agentCard, } return printFormatted(output) @@ -384,10 +382,9 @@ var listTasksCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task list: %w", err) } - // Create structured output output := map[string]interface{}{ - "tasks": taskList.Tasks, - "total": taskList.Total, + "tasks": taskList.Tasks, + "total": taskList.Total, "showing": len(taskList.Tasks), } @@ -469,10 +466,9 @@ var historyCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task list: %w", err) } - // Create structured output output := map[string]interface{}{ "context_id": contextID, - "tasks": taskList.Tasks, + "tasks": taskList.Tasks, } return printFormatted(output) @@ -504,10 +500,10 @@ var versionCmd = &cobra.Command{ Long: "Display version information including version number, commit hash, and build date.", RunE: func(cmd *cobra.Command, args []string) error { version := map[string]interface{}{ - "name": "A2A Debugger", + "name": "A2A Debugger", "version": appVersion, - "commit": buildCommit, - "built": buildDate, + "commit": buildCommit, + "built": buildDate, } return printFormatted(version) }, @@ -567,11 +563,10 @@ var submitTaskCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task: %w", err) } - // Create structured output output := map[string]interface{}{ - "submitted": true, + "submitted": true, "message_id": messageID, - "task": task, + "task": task, } return printFormatted(output) @@ -637,13 +632,13 @@ var submitStreamingTaskCmd = &cobra.Command{ fmt.Printf("\nšŸ”„ Streaming responses:\n\n") var streamingSummary struct { - TaskID string - ContextID string - FinalStatus string - StatusUpdates int - ArtifactUpdates int - TotalEvents int - FinalMessage *adk.Message + TaskID string + ContextID string + FinalStatus string + StatusUpdates int + ArtifactUpdates int + TotalEvents int + FinalMessage *adk.Message } for event := range eventChan { @@ -680,7 +675,7 @@ var submitStreamingTaskCmd = &cobra.Command{ for i, part := range statusEvent.Status.Message.Parts { adkParts[i] = adk.Part(part) } - + adkMessage := &adk.Message{ Kind: statusEvent.Status.Message.Kind, MessageID: statusEvent.Status.Message.MessageID, diff --git a/cli/cli_output_test.go b/cli/cli_output_test.go index 51fd361..99a493e 100644 --- a/cli/cli_output_test.go +++ b/cli/cli_output_test.go @@ -189,4 +189,4 @@ func TestPrintFormatted(t *testing.T) { } }) } -} \ No newline at end of file +} From 19baa4ec968ec45bd134ddd96d6d5301fb44d4b2 Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:27:51 +0200 Subject: [PATCH 3/9] refactor: Make the code less confusing by leveraging modern golang - refactor output handling to use 'any' type instead of 'interface{}' Also regenerate the types from the latest schema. - Updated function signatures in cli.go to replace 'interface{}' with 'any' for better type safety. - Modified output maps in various commands to use 'any' for consistency. - Adjusted test cases in cli_output_test.go and cli_test.go to reflect the changes in type. - Ensured compatibility with existing functionality while improving code readability. Signed-off-by: Eden Reich --- Taskfile.yaml | 2 +- a2a/generated_types.go | 570 +++++++++++++---------- a2a/schema.yaml | 1007 ++++++++++++++++++++++++---------------- cli/cli.go | 26 +- cli/cli_output_test.go | 15 +- cli/cli_test.go | 22 +- 6 files changed, 944 insertions(+), 698 deletions(-) diff --git a/Taskfile.yaml b/Taskfile.yaml index 65d60fc..59ed9f8 100644 --- a/Taskfile.yaml +++ b/Taskfile.yaml @@ -16,7 +16,7 @@ tasks: generate: desc: 'Generate Go code from the official A2A JSON RPC Schema' cmds: - - go run github.com/inference-gateway/tools/cmd/generator@v0.1.1 -generator jsonrpc -package a2a a2a/schema.yaml a2a/generated_types.go + - go run github.com/inference-gateway/tools/cmd/generator@v0.1.2 -generator jsonrpc -package a2a a2a/schema.yaml a2a/generated_types.go tidy: desc: 'Run go mod tidy to clean up dependencies' diff --git a/a2a/generated_types.go b/a2a/generated_types.go index a0e7420..3818cdb 100644 --- a/a2a/generated_types.go +++ b/a2a/generated_types.go @@ -1,7 +1,7 @@ // Code generated from JSON schema. DO NOT EDIT. package a2a -// Represents the possible states of a Task. +// Defines the lifecycle states of a Task. type TaskState string // TaskState enum values @@ -17,12 +17,23 @@ const ( TaskStateWorking TaskState = "working" ) -type A2AError interface{} +// Supported A2A transport protocols. +type TransportProtocol string -// A2A supported request types -type A2ARequest interface{} +// TransportProtocol enum values +const ( + TransportProtocolGrpc TransportProtocol = "GRPC" + TransportProtocolHttpjson TransportProtocol = "HTTP+JSON" + TransportProtocolJSONRPC TransportProtocol = "JSONRPC" +) + +// A discriminated union of all standard JSON-RPC and A2A-specific error types. +type A2AError any -// API Key security scheme. +// A discriminated union representing all possible JSON-RPC 2.0 requests supported by the A2A specification. +type A2ARequest any + +// Defines a security scheme using an API key. type APIKeySecurityScheme struct { Description *string `json:"description,omitempty"` In string `json:"in"` @@ -38,11 +49,9 @@ type AgentCapabilities struct { Streaming *bool `json:"streaming,omitempty"` } -// An AgentCard conveys key information: -// - Overall details (version, name, description, uses) -// - Skills: A set of capabilities the agent can perform -// - Default modalities/content types supported by the agent. -// - Authentication requirements +// The AgentCard is a self-describing manifest for an agent. It provides essential +// metadata including the agent's identity, capabilities, skills, supported +// communication methods, and security requirements. type AgentCard struct { AdditionalInterfaces []AgentInterface `json:"additionalInterfaces,omitempty"` Capabilities AgentCapabilities `json:"capabilities"` @@ -52,26 +61,36 @@ type AgentCard struct { DocumentationURL *string `json:"documentationUrl,omitempty"` IconURL *string `json:"iconUrl,omitempty"` Name string `json:"name"` - PreferredTransport *string `json:"preferredTransport,omitempty"` + PreferredTransport string `json:"preferredTransport,omitempty"` + ProtocolVersion string `json:"protocolVersion"` Provider *AgentProvider `json:"provider,omitempty"` Security []map[string][]string `json:"security,omitempty"` SecuritySchemes map[string]SecurityScheme `json:"securitySchemes,omitempty"` + Signatures []AgentCardSignature `json:"signatures,omitempty"` Skills []AgentSkill `json:"skills"` SupportsAuthenticatedExtendedCard *bool `json:"supportsAuthenticatedExtendedCard,omitempty"` URL string `json:"url"` Version string `json:"version"` } -// A declaration of an extension supported by an Agent. +// AgentCardSignature represents a JWS signature of an AgentCard. +// This follows the JSON format of an RFC 7515 JSON Web Signature (JWS). +type AgentCardSignature struct { + Header map[string]any `json:"header,omitempty"` + Protected string `json:"protected"` + Signature string `json:"signature"` +} + +// A declaration of a protocol extension supported by an Agent. type AgentExtension struct { - Description *string `json:"description,omitempty"` - Params map[string]interface{} `json:"params,omitempty"` - Required *bool `json:"required,omitempty"` - URI string `json:"uri"` + Description *string `json:"description,omitempty"` + Params map[string]any `json:"params,omitempty"` + Required *bool `json:"required,omitempty"` + URI string `json:"uri"` } -// AgentInterface provides a declaration of a combination of the -// target url and the supported transport to interact with the agent. +// Declares a combination of a target URL and a transport protocol for interacting with the agent. +// This allows agents to expose the same functionality over multiple transport mechanisms. type AgentInterface struct { Transport string `json:"transport"` URL string `json:"url"` @@ -83,28 +102,36 @@ type AgentProvider struct { URL string `json:"url"` } -// Represents a unit of capability that an agent can perform. +// Represents a distinct capability or function that an agent can perform. type AgentSkill struct { - Description string `json:"description"` - Examples []string `json:"examples,omitempty"` - ID string `json:"id"` - InputModes []string `json:"inputModes,omitempty"` - Name string `json:"name"` - OutputModes []string `json:"outputModes,omitempty"` - Tags []string `json:"tags"` + Description string `json:"description"` + Examples []string `json:"examples,omitempty"` + ID string `json:"id"` + InputModes []string `json:"inputModes,omitempty"` + Name string `json:"name"` + OutputModes []string `json:"outputModes,omitempty"` + Security []map[string][]string `json:"security,omitempty"` + Tags []string `json:"tags"` } -// Represents an artifact generated for a task. +// Represents a file, data structure, or other resource generated by an agent during a task. type Artifact struct { - ArtifactID string `json:"artifactId"` - Description *string `json:"description,omitempty"` - Extensions []string `json:"extensions,omitempty"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - Name *string `json:"name,omitempty"` - Parts []Part `json:"parts"` + ArtifactID string `json:"artifactId"` + Description *string `json:"description,omitempty"` + Extensions []string `json:"extensions,omitempty"` + Metadata map[string]any `json:"metadata,omitempty"` + Name *string `json:"name,omitempty"` + Parts []Part `json:"parts"` +} + +// An A2A-specific error indicating that the agent does not have an Authenticated Extended Card configured +type AuthenticatedExtendedCardNotConfiguredError struct { + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// Configuration details for a supported OAuth Flow +// Defines configuration details for the OAuth 2.0 Authorization Code flow. type AuthorizationCodeOAuthFlow struct { AuthorizationURL string `json:"authorizationUrl"` RefreshURL *string `json:"refreshUrl,omitempty"` @@ -112,141 +139,160 @@ type AuthorizationCodeOAuthFlow struct { TokenURL string `json:"tokenUrl"` } -// JSON-RPC request model for the 'tasks/cancel' method. +// Represents a JSON-RPC request for the `tasks/cancel` method. type CancelTaskRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params TaskIdParams `json:"params"` } -// JSON-RPC response for the 'tasks/cancel' method. -type CancelTaskResponse interface{} +// Represents a JSON-RPC response for the `tasks/cancel` method. +type CancelTaskResponse any -// JSON-RPC success response model for the 'tasks/cancel' method. +// Represents a successful JSON-RPC response for the `tasks/cancel` method. type CancelTaskSuccessResponse struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Result Task `json:"result"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result Task `json:"result"` } -// Configuration details for a supported OAuth Flow +// Defines configuration details for the OAuth 2.0 Client Credentials flow. type ClientCredentialsOAuthFlow struct { RefreshURL *string `json:"refreshUrl,omitempty"` Scopes map[string]string `json:"scopes"` TokenURL string `json:"tokenUrl"` } -// A2A specific error indicating incompatible content types between request and agent capabilities. +// An A2A-specific error indicating an incompatibility between the requested +// content types and the agent's capabilities. type ContentTypeNotSupportedError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// Represents a structured data segment within a message part. +// Represents a structured data segment (e.g., JSON) within a message or artifact. type DataPart struct { - Data map[string]interface{} `json:"data"` - Kind string `json:"kind"` - Metadata map[string]interface{} `json:"metadata,omitempty"` + Data map[string]any `json:"data"` + Kind string `json:"kind"` + Metadata map[string]any `json:"metadata,omitempty"` } -// Parameters for removing pushNotificationConfiguration associated with a Task +// Defines parameters for deleting a specific push notification configuration for a task. type DeleteTaskPushNotificationConfigParams struct { - ID string `json:"id"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - PushNotificationConfigID string `json:"pushNotificationConfigId"` + ID string `json:"id"` + Metadata map[string]any `json:"metadata,omitempty"` + PushNotificationConfigID string `json:"pushNotificationConfigId"` } -// JSON-RPC request model for the 'tasks/pushNotificationConfig/delete' method. +// Represents a JSON-RPC request for the `tasks/pushNotificationConfig/delete` method. type DeleteTaskPushNotificationConfigRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params DeleteTaskPushNotificationConfigParams `json:"params"` } -// JSON-RPC response for the 'tasks/pushNotificationConfig/delete' method. -type DeleteTaskPushNotificationConfigResponse interface{} +// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/delete` method. +type DeleteTaskPushNotificationConfigResponse any -// JSON-RPC success response model for the 'tasks/pushNotificationConfig/delete' method. +// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/delete` method. type DeleteTaskPushNotificationConfigSuccessResponse struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Result interface{} `json:"result"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result any `json:"result"` } -// Represents the base entity for FileParts +// Defines base properties for a file. type FileBase struct { MIMEType *string `json:"mimeType,omitempty"` Name *string `json:"name,omitempty"` } -// Represents a File segment within parts. +// Represents a file segment within a message or artifact. The file content can be +// provided either directly as bytes or as a URI. type FilePart struct { - File interface{} `json:"file"` - Kind string `json:"kind"` - Metadata map[string]interface{} `json:"metadata,omitempty"` + File any `json:"file"` + Kind string `json:"kind"` + Metadata map[string]any `json:"metadata,omitempty"` } -// Define the variant where 'bytes' is present and 'uri' is absent +// Represents a file with its content provided directly as a base64-encoded string. type FileWithBytes struct { Bytes string `json:"bytes"` MIMEType *string `json:"mimeType,omitempty"` Name *string `json:"name,omitempty"` } -// Define the variant where 'uri' is present and 'bytes' is absent +// Represents a file with its content located at a specific URI. type FileWithUri struct { MIMEType *string `json:"mimeType,omitempty"` Name *string `json:"name,omitempty"` URI string `json:"uri"` } -// Parameters for fetching a pushNotificationConfiguration associated with a Task +// Represents a JSON-RPC request for the `agent/getAuthenticatedExtendedCard` method. +type GetAuthenticatedExtendedCardRequest struct { + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Method string `json:"method"` +} + +// Represents a JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method. +type GetAuthenticatedExtendedCardResponse any + +// Represents a successful JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method. +type GetAuthenticatedExtendedCardSuccessResponse struct { + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result AgentCard `json:"result"` +} + +// Defines parameters for fetching a specific push notification configuration for a task. type GetTaskPushNotificationConfigParams struct { - ID string `json:"id"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - PushNotificationConfigID *string `json:"pushNotificationConfigId,omitempty"` + ID string `json:"id"` + Metadata map[string]any `json:"metadata,omitempty"` + PushNotificationConfigID *string `json:"pushNotificationConfigId,omitempty"` } -// JSON-RPC request model for the 'tasks/pushNotificationConfig/get' method. +// Represents a JSON-RPC request for the `tasks/pushNotificationConfig/get` method. type GetTaskPushNotificationConfigRequest struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Method string `json:"method"` - Params interface{} `json:"params"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Method string `json:"method"` + Params any `json:"params"` } -// JSON-RPC response for the 'tasks/pushNotificationConfig/set' method. -type GetTaskPushNotificationConfigResponse interface{} +// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/get` method. +type GetTaskPushNotificationConfigResponse any -// JSON-RPC success response model for the 'tasks/pushNotificationConfig/get' method. +// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/get` method. type GetTaskPushNotificationConfigSuccessResponse struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Result TaskPushNotificationConfig `json:"result"` } -// JSON-RPC request model for the 'tasks/get' method. +// Represents a JSON-RPC request for the `tasks/get` method. type GetTaskRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params TaskQueryParams `json:"params"` } -// JSON-RPC response for the 'tasks/get' method. -type GetTaskResponse interface{} +// Represents a JSON-RPC response for the `tasks/get` method. +type GetTaskResponse any -// JSON-RPC success response for the 'tasks/get' method. +// Represents a successful JSON-RPC response for the `tasks/get` method. type GetTaskSuccessResponse struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Result Task `json:"result"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result Task `json:"result"` } -// HTTP Authentication security scheme. +// Defines a security scheme using HTTP authentication. type HTTPAuthSecurityScheme struct { BearerFormat *string `json:"bearerFormat,omitempty"` Description *string `json:"description,omitempty"` @@ -254,154 +300,163 @@ type HTTPAuthSecurityScheme struct { Type string `json:"type"` } -// Configuration details for a supported OAuth Flow +// Defines configuration details for the OAuth 2.0 Implicit flow. type ImplicitOAuthFlow struct { AuthorizationURL string `json:"authorizationUrl"` RefreshURL *string `json:"refreshUrl,omitempty"` Scopes map[string]string `json:"scopes"` } -// JSON-RPC error indicating an internal JSON-RPC error on the server. +// An error indicating an internal error on the server. type InternalError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// A2A specific error indicating agent returned invalid response for the current method +// An A2A-specific error indicating that the agent returned a response that +// does not conform to the specification for the current method. type InvalidAgentResponseError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// JSON-RPC error indicating invalid method parameter(s). +// An error indicating that the method parameters are invalid. type InvalidParamsError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// JSON-RPC error indicating the JSON sent is not a valid Request object. +// An error indicating that the JSON sent is not a valid Request object. type InvalidRequestError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// JSON-RPC error indicating invalid JSON was received by the server. +// An error indicating that the server received invalid JSON. type JSONParseError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// Represents a JSON-RPC 2.0 Error object. -// This is typically included in a JSONRPCErrorResponse when an error occurs. +// Represents a JSON-RPC 2.0 Error object, included in an error response. type JSONRPCError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } // Represents a JSON-RPC 2.0 Error Response object. type JSONRPCErrorResponse struct { - Error interface{} `json:"error"` - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` + Error any `json:"error"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` } -// Base interface for any JSON-RPC 2.0 request or response. +// Defines the base structure for any JSON-RPC 2.0 request, response, or notification. type JSONRPCMessage struct { - ID *interface{} `json:"id,omitempty"` - JSONRPC string `json:"jsonrpc"` + ID *any `json:"id,omitempty"` + JSONRPC string `json:"jsonrpc"` } // Represents a JSON-RPC 2.0 Request object. type JSONRPCRequest struct { - ID *interface{} `json:"id,omitempty"` - JSONRPC string `json:"jsonrpc"` - Method string `json:"method"` - Params map[string]interface{} `json:"params,omitempty"` + ID *any `json:"id,omitempty"` + JSONRPC string `json:"jsonrpc"` + Method string `json:"method"` + Params map[string]any `json:"params,omitempty"` } -// Represents a JSON-RPC 2.0 Response object. -type JSONRPCResponse interface{} +// A discriminated union representing all possible JSON-RPC 2.0 responses +// for the A2A specification methods. +type JSONRPCResponse any -// Represents a JSON-RPC 2.0 Success Response object. +// Represents a successful JSON-RPC 2.0 Response object. type JSONRPCSuccessResponse struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Result interface{} `json:"result"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result any `json:"result"` } -// Parameters for getting list of pushNotificationConfigurations associated with a Task +// Defines parameters for listing all push notification configurations associated with a task. type ListTaskPushNotificationConfigParams struct { - ID string `json:"id"` - Metadata map[string]interface{} `json:"metadata,omitempty"` + ID string `json:"id"` + Metadata map[string]any `json:"metadata,omitempty"` } -// JSON-RPC request model for the 'tasks/pushNotificationConfig/list' method. +// Represents a JSON-RPC request for the `tasks/pushNotificationConfig/list` method. type ListTaskPushNotificationConfigRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params ListTaskPushNotificationConfigParams `json:"params"` } -// JSON-RPC response for the 'tasks/pushNotificationConfig/list' method. -type ListTaskPushNotificationConfigResponse interface{} +// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/list` method. +type ListTaskPushNotificationConfigResponse any -// JSON-RPC success response model for the 'tasks/pushNotificationConfig/list' method. +// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/list` method. type ListTaskPushNotificationConfigSuccessResponse struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Result []TaskPushNotificationConfig `json:"result"` } -// Represents a single message exchanged between user and agent. +// Represents a single message in the conversation between a user and an agent. type Message struct { - ContextID *string `json:"contextId,omitempty"` - Extensions []string `json:"extensions,omitempty"` - Kind string `json:"kind"` - MessageID string `json:"messageId"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - Parts []Part `json:"parts"` - ReferenceTaskIds []string `json:"referenceTaskIds,omitempty"` - Role string `json:"role"` - TaskID *string `json:"taskId,omitempty"` -} - -// Configuration for the send message request. + ContextID *string `json:"contextId,omitempty"` + Extensions []string `json:"extensions,omitempty"` + Kind string `json:"kind"` + MessageID string `json:"messageId"` + Metadata map[string]any `json:"metadata,omitempty"` + Parts []Part `json:"parts"` + ReferenceTaskIds []string `json:"referenceTaskIds,omitempty"` + Role string `json:"role"` + TaskID *string `json:"taskId,omitempty"` +} + +// Defines configuration options for a `message/send` or `message/stream` request. type MessageSendConfiguration struct { - AcceptedOutputModes []string `json:"acceptedOutputModes"` + AcceptedOutputModes []string `json:"acceptedOutputModes,omitempty"` Blocking *bool `json:"blocking,omitempty"` HistoryLength *int `json:"historyLength,omitempty"` PushNotificationConfig *PushNotificationConfig `json:"pushNotificationConfig,omitempty"` } -// Sent by the client to the agent as a request. May create, continue or restart a task. +// Defines the parameters for a request to send a message to an agent. This can be used +// to create a new task, continue an existing one, or restart a task. type MessageSendParams struct { Configuration *MessageSendConfiguration `json:"configuration,omitempty"` Message Message `json:"message"` - Metadata map[string]interface{} `json:"metadata,omitempty"` + Metadata map[string]any `json:"metadata,omitempty"` } -// JSON-RPC error indicating the method does not exist or is not available. +// An error indicating that the requested method does not exist or is not available. type MethodNotFoundError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` +} + +// Defines a security scheme using mTLS authentication. +type MutualTLSSecurityScheme struct { + Description *string `json:"description,omitempty"` + Type string `json:"type"` } -// OAuth2.0 security scheme configuration. +// Defines a security scheme using OAuth 2.0. type OAuth2SecurityScheme struct { - Description *string `json:"description,omitempty"` - Flows OAuthFlows `json:"flows"` - Type string `json:"type"` + Description *string `json:"description,omitempty"` + Flows OAuthFlows `json:"flows"` + Oauth2metadataURL *string `json:"oauth2MetadataUrl,omitempty"` + Type string `json:"type"` } -// Allows configuration of the supported OAuth Flows +// Defines the configuration for the supported OAuth 2.0 flows. type OAuthFlows struct { AuthorizationCode *AuthorizationCodeOAuthFlow `json:"authorizationCode,omitempty"` ClientCredentials *ClientCredentialsOAuthFlow `json:"clientCredentials,omitempty"` @@ -409,35 +464,36 @@ type OAuthFlows struct { Password *PasswordOAuthFlow `json:"password,omitempty"` } -// OpenID Connect security scheme configuration. +// Defines a security scheme using OpenID Connect. type OpenIdConnectSecurityScheme struct { Description *string `json:"description,omitempty"` OpenIDConnectURL string `json:"openIdConnectUrl"` Type string `json:"type"` } -// Represents a part of a message, which can be text, a file, or structured data. -type Part interface{} +// A discriminated union representing a part of a message or artifact, which can +// be text, a file, or structured data. +type Part any -// Base properties common to all message parts. +// Defines base properties common to all message or artifact parts. type PartBase struct { - Metadata map[string]interface{} `json:"metadata,omitempty"` + Metadata map[string]any `json:"metadata,omitempty"` } -// Configuration details for a supported OAuth Flow +// Defines configuration details for the OAuth 2.0 Resource Owner Password flow. type PasswordOAuthFlow struct { RefreshURL *string `json:"refreshUrl,omitempty"` Scopes map[string]string `json:"scopes"` TokenURL string `json:"tokenUrl"` } -// Defines authentication details for push notifications. +// Defines authentication details for a push notification endpoint. type PushNotificationAuthenticationInfo struct { Credentials *string `json:"credentials,omitempty"` Schemes []string `json:"schemes"` } -// Configuration for setting up push notifications for task updates. +// Defines the configuration for setting up push notifications for task updates. type PushNotificationConfig struct { Authentication *PushNotificationAuthenticationInfo `json:"authentication,omitempty"` ID *string `json:"id,omitempty"` @@ -445,165 +501,169 @@ type PushNotificationConfig struct { URL string `json:"url"` } -// A2A specific error indicating the agent does not support push notifications. +// An A2A-specific error indicating that the agent does not support push notifications. type PushNotificationNotSupportedError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// Mirrors the OpenAPI Security Scheme Object -// (https://swagger.io/specification/#security-scheme-object) -type SecurityScheme interface{} +// Defines a security scheme that can be used to secure an agent's endpoints. +// This is a discriminated union type based on the OpenAPI 3.0 Security Scheme Object. +type SecurityScheme any -// Base properties shared by all security schemes. +// Defines base properties shared by all security scheme objects. type SecuritySchemeBase struct { Description *string `json:"description,omitempty"` } -// JSON-RPC request model for the 'message/send' method. +// Represents a JSON-RPC request for the `message/send` method. type SendMessageRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params MessageSendParams `json:"params"` } -// JSON-RPC response model for the 'message/send' method. -type SendMessageResponse interface{} +// Represents a JSON-RPC response for the `message/send` method. +type SendMessageResponse any -// JSON-RPC success response model for the 'message/send' method. +// Represents a successful JSON-RPC response for the `message/send` method. type SendMessageSuccessResponse struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Result interface{} `json:"result"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result any `json:"result"` } -// JSON-RPC request model for the 'message/stream' method. +// Represents a JSON-RPC request for the `message/stream` method. type SendStreamingMessageRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params MessageSendParams `json:"params"` } -// JSON-RPC response model for the 'message/stream' method. -type SendStreamingMessageResponse interface{} +// Represents a JSON-RPC response for the `message/stream` method. +type SendStreamingMessageResponse any -// JSON-RPC success response model for the 'message/stream' method. +// Represents a successful JSON-RPC response for the `message/stream` method. +// The server may send multiple response objects for a single request. type SendStreamingMessageSuccessResponse struct { - ID interface{} `json:"id"` - JSONRPC string `json:"jsonrpc"` - Result interface{} `json:"result"` + ID any `json:"id"` + JSONRPC string `json:"jsonrpc"` + Result any `json:"result"` } -// JSON-RPC request model for the 'tasks/pushNotificationConfig/set' method. +// Represents a JSON-RPC request for the `tasks/pushNotificationConfig/set` method. type SetTaskPushNotificationConfigRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params TaskPushNotificationConfig `json:"params"` } -// JSON-RPC response for the 'tasks/pushNotificationConfig/set' method. -type SetTaskPushNotificationConfigResponse interface{} +// Represents a JSON-RPC response for the `tasks/pushNotificationConfig/set` method. +type SetTaskPushNotificationConfigResponse any -// JSON-RPC success response model for the 'tasks/pushNotificationConfig/set' method. +// Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/set` method. type SetTaskPushNotificationConfigSuccessResponse struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Result TaskPushNotificationConfig `json:"result"` } +// Represents a single, stateful operation or conversation between a client and an agent. type Task struct { - Artifacts []Artifact `json:"artifacts,omitempty"` - ContextID string `json:"contextId"` - History []Message `json:"history,omitempty"` - ID string `json:"id"` - Kind string `json:"kind"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - Status TaskStatus `json:"status"` + Artifacts []Artifact `json:"artifacts,omitempty"` + ContextID string `json:"contextId"` + History []Message `json:"history,omitempty"` + ID string `json:"id"` + Kind string `json:"kind"` + Metadata map[string]any `json:"metadata,omitempty"` + Status TaskStatus `json:"status"` } -// Sent by server during sendStream or subscribe requests +// An event sent by the agent to notify the client that an artifact has been +// generated or updated. This is typically used in streaming models. type TaskArtifactUpdateEvent struct { - Append *bool `json:"append,omitempty"` - Artifact Artifact `json:"artifact"` - ContextID string `json:"contextId"` - Kind string `json:"kind"` - LastChunk *bool `json:"lastChunk,omitempty"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - TaskID string `json:"taskId"` + Append *bool `json:"append,omitempty"` + Artifact Artifact `json:"artifact"` + ContextID string `json:"contextId"` + Kind string `json:"kind"` + LastChunk *bool `json:"lastChunk,omitempty"` + Metadata map[string]any `json:"metadata,omitempty"` + TaskID string `json:"taskId"` } -// Parameters containing only a task ID, used for simple task operations. +// Defines parameters containing a task ID, used for simple task operations. type TaskIdParams struct { - ID string `json:"id"` - Metadata map[string]interface{} `json:"metadata,omitempty"` + ID string `json:"id"` + Metadata map[string]any `json:"metadata,omitempty"` } -// A2A specific error indicating the task is in a state where it cannot be canceled. +// An A2A-specific error indicating that the task is in a state where it cannot be canceled. type TaskNotCancelableError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// A2A specific error indicating the requested task ID was not found. +// An A2A-specific error indicating that the requested task ID was not found. type TaskNotFoundError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } -// Parameters for setting or getting push notification configuration for a task +// A container associating a push notification configuration with a specific task. type TaskPushNotificationConfig struct { PushNotificationConfig PushNotificationConfig `json:"pushNotificationConfig"` TaskID string `json:"taskId"` } -// Parameters for querying a task, including optional history length. +// Defines parameters for querying a task, with an option to limit history length. type TaskQueryParams struct { - HistoryLength *int `json:"historyLength,omitempty"` - ID string `json:"id"` - Metadata map[string]interface{} `json:"metadata,omitempty"` + HistoryLength *int `json:"historyLength,omitempty"` + ID string `json:"id"` + Metadata map[string]any `json:"metadata,omitempty"` } -// JSON-RPC request model for the 'tasks/resubscribe' method. +// Represents a JSON-RPC request for the `tasks/resubscribe` method, used to resume a streaming connection. type TaskResubscriptionRequest struct { - ID interface{} `json:"id"` + ID any `json:"id"` JSONRPC string `json:"jsonrpc"` Method string `json:"method"` Params TaskIdParams `json:"params"` } -// TaskState and accompanying message. +// Represents the status of a task at a specific point in time. type TaskStatus struct { Message *Message `json:"message,omitempty"` State TaskState `json:"state"` Timestamp *string `json:"timestamp,omitempty"` } -// Sent by server during sendStream or subscribe requests +// An event sent by the agent to notify the client of a change in a task's status. +// This is typically used in streaming or subscription models. type TaskStatusUpdateEvent struct { - ContextID string `json:"contextId"` - Final bool `json:"final"` - Kind string `json:"kind"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - Status TaskStatus `json:"status"` - TaskID string `json:"taskId"` + ContextID string `json:"contextId"` + Final bool `json:"final"` + Kind string `json:"kind"` + Metadata map[string]any `json:"metadata,omitempty"` + Status TaskStatus `json:"status"` + TaskID string `json:"taskId"` } -// Represents a text segment within parts. +// Represents a text segment within a message or artifact. type TextPart struct { - Kind string `json:"kind"` - Metadata map[string]interface{} `json:"metadata,omitempty"` - Text string `json:"text"` + Kind string `json:"kind"` + Metadata map[string]any `json:"metadata,omitempty"` + Text string `json:"text"` } -// A2A specific error indicating the requested operation is not supported by the agent. +// An A2A-specific error indicating that the requested operation is not supported by the agent. type UnsupportedOperationError struct { - Code int `json:"code"` - Data *interface{} `json:"data,omitempty"` - Message string `json:"message"` + Code int `json:"code"` + Data *any `json:"data,omitempty"` + Message string `json:"message"` } diff --git a/a2a/schema.yaml b/a2a/schema.yaml index 86f4cb4..7f51254 100644 --- a/a2a/schema.yaml +++ b/a2a/schema.yaml @@ -13,6 +13,8 @@ definitions: - $ref: '#/definitions/UnsupportedOperationError' - $ref: '#/definitions/ContentTypeNotSupportedError' - $ref: '#/definitions/InvalidAgentResponseError' + - $ref: '#/definitions/AuthenticatedExtendedCardNotConfiguredError' + description: A discriminated union of all standard JSON-RPC and A2A-specific error types. A2ARequest: anyOf: - $ref: '#/definitions/SendMessageRequest' @@ -24,25 +26,27 @@ definitions: - $ref: '#/definitions/TaskResubscriptionRequest' - $ref: '#/definitions/ListTaskPushNotificationConfigRequest' - $ref: '#/definitions/DeleteTaskPushNotificationConfigRequest' - description: A2A supported request types + - $ref: '#/definitions/GetAuthenticatedExtendedCardRequest' + description: A discriminated union representing all possible JSON-RPC 2.0 requests supported by the A2A specification. APIKeySecurityScheme: - description: API Key security scheme. + description: Defines a security scheme using an API key. properties: description: - description: Description of this security scheme. + description: An optional description for the security scheme. type: string in: - description: The location of the API key. Valid values are "query", "header", or "cookie". + description: The location of the API key. enum: - cookie - header - query type: string name: - description: The name of the header, query or cookie parameter to be used. + description: The name of the header, query, or cookie parameter to be used. type: string type: const: apiKey + description: The type of the security scheme. Must be 'apiKey'. type: string required: - in @@ -53,72 +57,110 @@ definitions: description: Defines optional capabilities supported by an agent. properties: extensions: - description: extensions supported by this agent. + description: A list of protocol extensions supported by the agent. items: $ref: '#/definitions/AgentExtension' type: array pushNotifications: - description: true if the agent can notify updates to client. + description: Indicates if the agent supports sending push notifications for asynchronous task updates. type: boolean stateTransitionHistory: - description: true if the agent exposes status change history for tasks. + description: Indicates if the agent provides a history of state transitions for a task. type: boolean streaming: - description: true if the agent supports SSE. + description: Indicates if the agent supports Server-Sent Events (SSE) for streaming responses. type: boolean type: object AgentCard: description: |- - An AgentCard conveys key information: - - Overall details (version, name, description, uses) - - Skills: A set of capabilities the agent can perform - - Default modalities/content types supported by the agent. - - Authentication requirements + The AgentCard is a self-describing manifest for an agent. It provides essential + metadata including the agent's identity, capabilities, skills, supported + communication methods, and security requirements. properties: additionalInterfaces: description: |- - Announcement of additional supported transports. Client can use any of - the supported transports. + A list of additional supported interfaces (transport and URL combinations). + This allows agents to expose multiple transports, potentially at different URLs. + + Best practices: + - SHOULD include all supported transports for completeness + - SHOULD include an entry matching the main 'url' and 'preferredTransport' + - MAY reuse URLs if multiple transports are available at the same endpoint + - MUST accurately declare the transport available at each URL + + Clients can select any interface from this list based on their transport capabilities + and preferences. This enables transport negotiation and fallback scenarios. items: $ref: '#/definitions/AgentInterface' type: array capabilities: $ref: '#/definitions/AgentCapabilities' - description: Optional capabilities supported by the agent. + description: A declaration of optional capabilities supported by the agent. defaultInputModes: description: |- - The set of interaction modes that the agent supports across all skills. This can be overridden per-skill. - Supported media types for input. + Default set of supported input MIME types for all skills, which can be + overridden on a per-skill basis. items: type: string type: array defaultOutputModes: - description: Supported media types for output. + description: |- + Default set of supported output MIME types for all skills, which can be + overridden on a per-skill basis. items: type: string type: array description: description: |- - A human-readable description of the agent. Used to assist users and - other agents in understanding what the agent can do. + A human-readable description of the agent, assisting users and other agents + in understanding its purpose. + examples: + - Agent that helps users with recipes and cooking. type: string documentationUrl: - description: A URL to documentation for the agent. + description: An optional URL to the agent's documentation. type: string iconUrl: - description: A URL to an icon for the agent. + description: An optional URL to an icon for the agent. type: string name: - description: Human readable name of the agent. + description: A human-readable name for the agent. + examples: + - Recipe Agent type: string preferredTransport: - description: The transport of the preferred endpoint. If empty, defaults to JSONRPC. + default: JSONRPC + description: |- + The transport protocol for the preferred endpoint (the main 'url' field). + If not specified, defaults to 'JSONRPC'. + + IMPORTANT: The transport specified here MUST be available at the main 'url'. + This creates a binding between the main URL and its supported transport protocol. + Clients should prefer this transport and URL combination when both are supported. + examples: + - JSONRPC + - GRPC + - HTTP+JSON + type: string + protocolVersion: + default: 0.3.0 + description: The version of the A2A protocol this agent supports. type: string provider: $ref: '#/definitions/AgentProvider' - description: The service provider of the agent + description: Information about the agent's service provider. security: - description: Security requirements for contacting the agent. + description: |- + A list of security requirement objects that apply to all agent interactions. Each object + lists security schemes that can be used. Follows the OpenAPI 3.0 Security Requirement Object. + This list can be seen as an OR of ANDs. Each object in the list describes one possible + set of security requirements that must be present on a request. This allows specifying, + for example, "callers must either use OAuth OR an API Key AND mTLS." + examples: + - - oauth: + - read + - api-key: [] + mtls: [] items: additionalProperties: items: @@ -129,25 +171,36 @@ definitions: securitySchemes: additionalProperties: $ref: '#/definitions/SecurityScheme' - description: Security scheme details used for authenticating with this agent. + description: |- + A declaration of the security schemes available to authorize requests. The key is the + scheme name. Follows the OpenAPI 3.0 Security Scheme Object. type: object + signatures: + description: JSON Web Signatures computed for this AgentCard. + items: + $ref: '#/definitions/AgentCardSignature' + type: array skills: - description: Skills are a unit of capability that an agent can perform. + description: The set of skills, or distinct capabilities, that the agent can perform. items: $ref: '#/definitions/AgentSkill' type: array supportsAuthenticatedExtendedCard: description: |- - true if the agent supports providing an extended agent card when the user is authenticated. - Defaults to false if not specified. + If true, the agent can provide an extended agent card with additional details + to authenticated users. Defaults to false. type: boolean url: description: |- - A URL to the address the agent is hosted at. This represents the - preferred endpoint as declared by the agent. + The preferred endpoint URL for interacting with the agent. + This URL MUST support the transport specified by 'preferredTransport'. + examples: + - https://api.example.com/a2a/v1 type: string version: - description: The version of the agent - format is up to the provider. + description: The agent's own version number. The format is defined by the provider. + examples: + - 1.0.0 type: string required: - capabilities @@ -155,41 +208,75 @@ definitions: - defaultOutputModes - description - name + - protocolVersion - skills - url - version type: object + AgentCardSignature: + description: |- + AgentCardSignature represents a JWS signature of an AgentCard. + This follows the JSON format of an RFC 7515 JSON Web Signature (JWS). + properties: + header: + additionalProperties: {} + description: The unprotected JWS header values. + type: object + protected: + description: |- + The protected JWS header for the signature. This is a Base64url-encoded + JSON object, as per RFC 7515. + type: string + signature: + description: The computed signature, Base64url-encoded. + type: string + required: + - protected + - signature + type: object AgentExtension: - description: A declaration of an extension supported by an Agent. + description: A declaration of a protocol extension supported by an Agent. + examples: + - description: Google OAuth 2.0 authentication + required: false + uri: https://developers.google.com/identity/protocols/oauth2 properties: description: - description: A description of how this agent uses this extension. + description: A human-readable description of how this agent uses the extension. type: string params: additionalProperties: {} - description: Optional configuration for the extension. + description: Optional, extension-specific configuration parameters. type: object required: - description: Whether the client must follow specific requirements of the extension. + description: |- + If true, the client must understand and comply with the extension's requirements + to interact with the agent. type: boolean uri: - description: The URI of the extension. + description: The unique URI identifying the extension. type: string required: - uri type: object AgentInterface: description: |- - AgentInterface provides a declaration of a combination of the - target url and the supported transport to interact with the agent. + Declares a combination of a target URL and a transport protocol for interacting with the agent. + This allows agents to expose the same functionality over multiple transport mechanisms. properties: transport: - description: |- - The transport supported this url. This is an open form string, to be - easily extended for many transport protocols. The core ones officially - supported are JSONRPC, GRPC and HTTP+JSON. + description: The transport protocol supported at this URL. + examples: + - JSONRPC + - GRPC + - HTTP+JSON type: string url: + description: The URL where this interface is available. Must be a valid absolute HTTPS URL in production. + examples: + - https://api.example.com/a2a/v1 + - https://grpc.example.com/a2a + - https://rest.example.com/v1 type: string required: - transport @@ -197,53 +284,75 @@ definitions: type: object AgentProvider: description: Represents the service provider of an agent. + examples: + - organization: Google + url: https://ai.google.dev properties: organization: - description: Agent provider's organization name. + description: The name of the agent provider's organization. type: string url: - description: Agent provider's URL. + description: A URL for the agent provider's website or relevant documentation. type: string required: - organization - url type: object AgentSkill: - description: Represents a unit of capability that an agent can perform. + description: Represents a distinct capability or function that an agent can perform. properties: description: description: |- - Description of the skill - will be used by the client or a human - as a hint to understand what the skill does. + A detailed description of the skill, intended to help clients or users + understand its purpose and functionality. type: string examples: description: |- - The set of example scenarios that the skill can perform. - Will be used by the client as a hint to understand how the skill can be used. + Example prompts or scenarios that this skill can handle. Provides a hint to + the client on how to use the skill. + examples: + - - I need a recipe for bread items: type: string type: array id: - description: Unique identifier for the agent's skill. + description: A unique identifier for the agent's skill. type: string inputModes: - description: |- - The set of interaction modes that the skill supports - (if different than the default). - Supported media types for input. + description: The set of supported input MIME types for this skill, overriding the agent's defaults. items: type: string type: array name: - description: Human readable name of the skill. + description: A human-readable name for the skill. type: string outputModes: - description: Supported media types for output. + description: The set of supported output MIME types for this skill, overriding the agent's defaults. items: type: string type: array + security: + description: |- + Security schemes necessary for the agent to leverage this skill. + As in the overall AgentCard.security, this list represents a logical OR of security + requirement objects. Each object is a set of security schemes that must be used together + (a logical AND). + examples: + - - google: + - oidc + items: + additionalProperties: + items: + type: string + type: array + type: object + type: array tags: - description: Set of tagwords describing classes of capabilities for this specific skill. + description: A set of keywords describing the skill's capabilities. + examples: + - - cooking + - customer support + - billing items: type: string type: array @@ -254,28 +363,28 @@ definitions: - tags type: object Artifact: - description: Represents an artifact generated for a task. + description: Represents a file, data structure, or other resource generated by an agent during a task. properties: artifactId: - description: Unique identifier for the artifact. + description: A unique identifier (e.g. UUID) for the artifact within the scope of the task. type: string description: - description: Optional description for the artifact. + description: An optional, human-readable description of the artifact. type: string extensions: - description: The URIs of extensions that are present or contributed to this Artifact. + description: The URIs of extensions that are relevant to this artifact. items: type: string type: array metadata: additionalProperties: {} - description: Extension metadata. + description: Optional metadata for extensions. The key is an extension-specific identifier. type: object name: - description: Optional name for the artifact. + description: An optional, human-readable name for the artifact. type: string parts: - description: Artifact parts. + description: An array of content parts that make up the artifact. items: $ref: '#/definitions/Part' type: array @@ -283,30 +392,49 @@ definitions: - artifactId - parts type: object + AuthenticatedExtendedCardNotConfiguredError: + description: An A2A-specific error indicating that the agent does not have an Authenticated Extended Card configured + properties: + code: + const: -32007 + description: The error code for when an authenticated extended card is not configured. + type: integer + data: + description: |- + A primitive or structured value containing additional information about the error. + This may be omitted. + message: + default: Authenticated Extended Card is not configured + description: The error message. + type: string + required: + - code + - message + type: object AuthorizationCodeOAuthFlow: - description: Configuration details for a supported OAuth Flow + description: Defines configuration details for the OAuth 2.0 Authorization Code flow. properties: authorizationUrl: description: |- - The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 - standard requires the use of TLS + The authorization URL to be used for this flow. + This MUST be a URL and use TLS. type: string refreshUrl: description: |- - The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 - standard requires the use of TLS. + The URL to be used for obtaining refresh tokens. + This MUST be a URL and use TLS. type: string scopes: additionalProperties: type: string description: |- - The available scopes for the OAuth2 security scheme. A map between the scope name and a short - description for it. The map MAY be empty. + The available scopes for the OAuth2 security scheme. A map between the scope + name and a short description for it. type: object tokenUrl: description: |- - The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard - requires the use of TLS. + The token URL to be used for this flow. + This MUST be a URL and use TLS. type: string required: - authorizationUrl @@ -314,26 +442,24 @@ definitions: - tokenUrl type: object CancelTaskRequest: - description: JSON-RPC request model for the 'tasks/cancel' method. + description: Represents a JSON-RPC request for the `tasks/cancel` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/cancel - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/cancel'. type: string params: $ref: '#/definitions/TaskIdParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters identifying the task to cancel. required: - id - jsonrpc @@ -344,128 +470,124 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/CancelTaskSuccessResponse' - description: JSON-RPC response for the 'tasks/cancel' method. + description: Represents a JSON-RPC response for the `tasks/cancel` method. CancelTaskSuccessResponse: - description: JSON-RPC success response model for the 'tasks/cancel' method. + description: Represents a successful JSON-RPC response for the `tasks/cancel` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: $ref: '#/definitions/Task' - description: The result object on success. + description: The result, containing the final state of the canceled Task object. required: - id - jsonrpc - result type: object ClientCredentialsOAuthFlow: - description: Configuration details for a supported OAuth Flow + description: Defines configuration details for the OAuth 2.0 Client Credentials flow. properties: refreshUrl: - description: |- - The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 - standard requires the use of TLS. + description: The URL to be used for obtaining refresh tokens. This MUST be a URL. type: string scopes: additionalProperties: type: string description: |- - The available scopes for the OAuth2 security scheme. A map between the scope name and a short - description for it. The map MAY be empty. + The available scopes for the OAuth2 security scheme. A map between the scope + name and a short description for it. type: object tokenUrl: - description: |- - The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard - requires the use of TLS. + description: The token URL to be used for this flow. This MUST be a URL. type: string required: - scopes - tokenUrl type: object ContentTypeNotSupportedError: - description: A2A specific error indicating incompatible content types between request and agent capabilities. + description: |- + An A2A-specific error indicating an incompatibility between the requested + content types and the agent's capabilities. properties: code: const: -32005 - description: A Number that indicates the error type that occurred. + description: The error code for an unsupported content type. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Incompatible content types - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object DataPart: - description: Represents a structured data segment within a message part. + description: Represents a structured data segment (e.g., JSON) within a message or artifact. properties: data: additionalProperties: {} - description: Structured data content + description: The structured data content. type: object kind: const: data - description: Part type - data for DataParts + description: The type of this part, used as a discriminator. Always 'data'. type: string metadata: additionalProperties: {} - description: Optional metadata associated with the part. + description: Optional metadata associated with this part. type: object required: - data - kind type: object DeleteTaskPushNotificationConfigParams: - description: Parameters for removing pushNotificationConfiguration associated with a Task + description: Defines parameters for deleting a specific push notification configuration for a task. properties: id: - description: Task id. + description: The unique identifier (e.g. UUID) of the task. type: string metadata: additionalProperties: {} + description: Optional metadata associated with the request. type: object pushNotificationConfigId: + description: The ID of the push notification configuration to delete. type: string required: - id - pushNotificationConfigId type: object DeleteTaskPushNotificationConfigRequest: - description: JSON-RPC request model for the 'tasks/pushNotificationConfig/delete' method. + description: Represents a JSON-RPC request for the `tasks/pushNotificationConfig/delete` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/pushNotificationConfig/delete - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/pushNotificationConfig/delete'. type: string params: $ref: '#/definitions/DeleteTaskPushNotificationConfigParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters identifying the push notification configuration to delete. required: - id - jsonrpc @@ -476,24 +598,22 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/DeleteTaskPushNotificationConfigSuccessResponse' - description: JSON-RPC response for the 'tasks/pushNotificationConfig/delete' method. + description: Represents a JSON-RPC response for the `tasks/pushNotificationConfig/delete` method. DeleteTaskPushNotificationConfigSuccessResponse: - description: JSON-RPC success response model for the 'tasks/pushNotificationConfig/delete' method. + description: Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/delete` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: - description: The result object on success. + description: The result is null on successful deletion. type: 'null' required: - id @@ -501,104 +621,151 @@ definitions: - result type: object FileBase: - description: Represents the base entity for FileParts + description: Defines base properties for a file. properties: mimeType: - description: Optional mimeType for the file + description: The MIME type of the file (e.g., "application/pdf"). type: string name: - description: Optional name for the file + description: An optional name for the file (e.g., "document.pdf"). type: string type: object FilePart: - description: Represents a File segment within parts. + description: |- + Represents a file segment within a message or artifact. The file content can be + provided either directly as bytes or as a URI. properties: file: anyOf: - $ref: '#/definitions/FileWithBytes' - $ref: '#/definitions/FileWithUri' - description: File content either as url or bytes + description: The file content, represented as either a URI or as base64-encoded bytes. kind: const: file - description: Part type - file for FileParts + description: The type of this part, used as a discriminator. Always 'file'. type: string metadata: additionalProperties: {} - description: Optional metadata associated with the part. + description: Optional metadata associated with this part. type: object required: - file - kind type: object FileWithBytes: - description: Define the variant where 'bytes' is present and 'uri' is absent + description: Represents a file with its content provided directly as a base64-encoded string. properties: bytes: - description: base64 encoded content of the file + description: The base64-encoded content of the file. type: string mimeType: - description: Optional mimeType for the file + description: The MIME type of the file (e.g., "application/pdf"). type: string name: - description: Optional name for the file + description: An optional name for the file (e.g., "document.pdf"). type: string required: - bytes type: object FileWithUri: - description: Define the variant where 'uri' is present and 'bytes' is absent + description: Represents a file with its content located at a specific URI. properties: mimeType: - description: Optional mimeType for the file + description: The MIME type of the file (e.g., "application/pdf"). type: string name: - description: Optional name for the file + description: An optional name for the file (e.g., "document.pdf"). type: string uri: - description: URL for the File content + description: A URL pointing to the file's content. type: string required: - uri type: object + GetAuthenticatedExtendedCardRequest: + description: Represents a JSON-RPC request for the `agent/getAuthenticatedExtendedCard` method. + properties: + id: + description: The identifier for this request. + type: + - string + - integer + jsonrpc: + const: '2.0' + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". + type: string + method: + const: agent/getAuthenticatedExtendedCard + description: The method name. Must be 'agent/getAuthenticatedExtendedCard'. + type: string + required: + - id + - jsonrpc + - method + type: object + GetAuthenticatedExtendedCardResponse: + anyOf: + - $ref: '#/definitions/JSONRPCErrorResponse' + - $ref: '#/definitions/GetAuthenticatedExtendedCardSuccessResponse' + description: Represents a JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method. + GetAuthenticatedExtendedCardSuccessResponse: + description: Represents a successful JSON-RPC response for the `agent/getAuthenticatedExtendedCard` method. + properties: + id: + description: The identifier established by the client. + type: + - string + - integer + - 'null' + jsonrpc: + const: '2.0' + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". + type: string + result: + $ref: '#/definitions/AgentCard' + description: The result is an Agent Card object. + required: + - id + - jsonrpc + - result + type: object GetTaskPushNotificationConfigParams: - description: Parameters for fetching a pushNotificationConfiguration associated with a Task + description: Defines parameters for fetching a specific push notification configuration for a task. properties: id: - description: Task id. + description: The unique identifier (e.g. UUID) of the task. type: string metadata: additionalProperties: {} + description: Optional metadata associated with the request. type: object pushNotificationConfigId: + description: The ID of the push notification configuration to retrieve. type: string required: - id type: object GetTaskPushNotificationConfigRequest: - description: JSON-RPC request model for the 'tasks/pushNotificationConfig/get' method. + description: Represents a JSON-RPC request for the `tasks/pushNotificationConfig/get` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/pushNotificationConfig/get - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/pushNotificationConfig/get'. type: string params: anyOf: - $ref: '#/definitions/TaskIdParams' - $ref: '#/definitions/GetTaskPushNotificationConfigParams' - description: |- - A Structured value that holds the parameter values to be used during the invocation of the method. - TaskIdParams type is deprecated for this method + description: The parameters for getting a push notification configuration. required: - id - jsonrpc @@ -609,51 +776,47 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/GetTaskPushNotificationConfigSuccessResponse' - description: JSON-RPC response for the 'tasks/pushNotificationConfig/set' method. + description: Represents a JSON-RPC response for the `tasks/pushNotificationConfig/get` method. GetTaskPushNotificationConfigSuccessResponse: - description: JSON-RPC success response model for the 'tasks/pushNotificationConfig/get' method. + description: Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/get` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: $ref: '#/definitions/TaskPushNotificationConfig' - description: The result object on success. + description: The result, containing the requested push notification configuration. required: - id - jsonrpc - result type: object GetTaskRequest: - description: JSON-RPC request model for the 'tasks/get' method. + description: Represents a JSON-RPC request for the `tasks/get` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/get - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/get'. type: string params: $ref: '#/definitions/TaskQueryParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters for querying a task. required: - id - jsonrpc @@ -664,188 +827,182 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/GetTaskSuccessResponse' - description: JSON-RPC response for the 'tasks/get' method. + description: Represents a JSON-RPC response for the `tasks/get` method. GetTaskSuccessResponse: - description: JSON-RPC success response for the 'tasks/get' method. + description: Represents a successful JSON-RPC response for the `tasks/get` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: $ref: '#/definitions/Task' - description: The result object on success. + description: The result, containing the requested Task object. required: - id - jsonrpc - result type: object HTTPAuthSecurityScheme: - description: HTTP Authentication security scheme. + description: Defines a security scheme using HTTP authentication. properties: bearerFormat: description: |- - A hint to the client to identify how the bearer token is formatted. Bearer tokens are usually - generated by an authorization server, so this information is primarily for documentation - purposes. + A hint to the client to identify how the bearer token is formatted (e.g., "JWT"). + This is primarily for documentation purposes. type: string description: - description: Description of this security scheme. + description: An optional description for the security scheme. type: string scheme: description: |- - The name of the HTTP Authentication scheme to be used in the Authorization header as defined - in RFC7235. The values used SHOULD be registered in the IANA Authentication Scheme registry. - The value is case-insensitive, as defined in RFC7235. + The name of the HTTP Authentication scheme to be used in the Authorization header, + as defined in RFC7235 (e.g., "Bearer"). + This value should be registered in the IANA Authentication Scheme registry. type: string type: const: http + description: The type of the security scheme. Must be 'http'. type: string required: - scheme - type type: object ImplicitOAuthFlow: - description: Configuration details for a supported OAuth Flow + description: Defines configuration details for the OAuth 2.0 Implicit flow. properties: authorizationUrl: - description: |- - The authorization URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 - standard requires the use of TLS + description: The authorization URL to be used for this flow. This MUST be a URL. type: string refreshUrl: - description: |- - The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 - standard requires the use of TLS. + description: The URL to be used for obtaining refresh tokens. This MUST be a URL. type: string scopes: additionalProperties: type: string description: |- - The available scopes for the OAuth2 security scheme. A map between the scope name and a short - description for it. The map MAY be empty. + The available scopes for the OAuth2 security scheme. A map between the scope + name and a short description for it. type: object required: - authorizationUrl - scopes type: object InternalError: - description: JSON-RPC error indicating an internal JSON-RPC error on the server. + description: An error indicating an internal error on the server. properties: code: const: -32603 - description: A Number that indicates the error type that occurred. + description: The error code for an internal server error. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Internal error - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object InvalidAgentResponseError: - description: A2A specific error indicating agent returned invalid response for the current method + description: |- + An A2A-specific error indicating that the agent returned a response that + does not conform to the specification for the current method. properties: code: const: -32006 - description: A Number that indicates the error type that occurred. + description: The error code for an invalid agent response. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Invalid agent response - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object InvalidParamsError: - description: JSON-RPC error indicating invalid method parameter(s). + description: An error indicating that the method parameters are invalid. properties: code: const: -32602 - description: A Number that indicates the error type that occurred. + description: The error code for an invalid parameters error. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Invalid parameters - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object InvalidRequestError: - description: JSON-RPC error indicating the JSON sent is not a valid Request object. + description: An error indicating that the JSON sent is not a valid Request object. properties: code: const: -32600 - description: A Number that indicates the error type that occurred. + description: The error code for an invalid request. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Request payload validation error - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object JSONParseError: - description: JSON-RPC error indicating invalid JSON was received by the server. + description: An error indicating that the server received invalid JSON. properties: code: const: -32700 - description: A Number that indicates the error type that occurred. + description: The error code for a JSON parse error. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Invalid JSON payload - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object JSONRPCError: - description: |- - Represents a JSON-RPC 2.0 Error object. - This is typically included in a JSONRPCErrorResponse when an error occurs. + description: Represents a JSON-RPC 2.0 Error object, included in an error response. properties: code: - description: A Number that indicates the error type that occurred. + description: A number that indicates the error type that occurred. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: - description: A String providing a short description of the error. + description: A string providing a short description of the error. type: string required: - code @@ -868,17 +1025,17 @@ definitions: - $ref: '#/definitions/UnsupportedOperationError' - $ref: '#/definitions/ContentTypeNotSupportedError' - $ref: '#/definitions/InvalidAgentResponseError' + - $ref: '#/definitions/AuthenticatedExtendedCardNotConfiguredError' + description: An object describing the error that occurred. id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string required: - error @@ -886,19 +1043,19 @@ definitions: - jsonrpc type: object JSONRPCMessage: - description: Base interface for any JSON-RPC 2.0 request or response. + description: Defines the base structure for any JSON-RPC 2.0 request, response, or notification. properties: id: description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + A unique identifier established by the client. It must be a String, a Number, or null. + The server must reply with the same value in the response. This property is omitted for notifications. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string required: - jsonrpc @@ -908,22 +1065,22 @@ definitions: properties: id: description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + A unique identifier established by the client. It must be a String, a Number, or null. + The server must reply with the same value in the response. This property is omitted for notifications. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: - description: A String containing the name of the method to be invoked. + description: A string containing the name of the method to be invoked. type: string params: additionalProperties: {} - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: A structured value holding the parameter values to be used during the method invocation. type: object required: - jsonrpc @@ -938,62 +1095,64 @@ definitions: - $ref: '#/definitions/CancelTaskSuccessResponse' - $ref: '#/definitions/SetTaskPushNotificationConfigSuccessResponse' - $ref: '#/definitions/GetTaskPushNotificationConfigSuccessResponse' - description: Represents a JSON-RPC 2.0 Response object. + - $ref: '#/definitions/ListTaskPushNotificationConfigSuccessResponse' + - $ref: '#/definitions/DeleteTaskPushNotificationConfigSuccessResponse' + - $ref: '#/definitions/GetAuthenticatedExtendedCardSuccessResponse' + description: |- + A discriminated union representing all possible JSON-RPC 2.0 responses + for the A2A specification methods. JSONRPCSuccessResponse: - description: Represents a JSON-RPC 2.0 Success Response object. + description: Represents a successful JSON-RPC 2.0 Response object. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: - description: The result object on success + description: The value of this member is determined by the method invoked on the Server. required: - id - jsonrpc - result type: object ListTaskPushNotificationConfigParams: - description: Parameters for getting list of pushNotificationConfigurations associated with a Task + description: Defines parameters for listing all push notification configurations associated with a task. properties: id: - description: Task id. + description: The unique identifier (e.g. UUID) of the task. type: string metadata: additionalProperties: {} + description: Optional metadata associated with the request. type: object required: - id type: object ListTaskPushNotificationConfigRequest: - description: JSON-RPC request model for the 'tasks/pushNotificationConfig/list' method. + description: Represents a JSON-RPC request for the `tasks/pushNotificationConfig/list` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/pushNotificationConfig/list - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/pushNotificationConfig/list'. type: string params: $ref: '#/definitions/ListTaskPushNotificationConfigParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters identifying the task whose configurations are to be listed. required: - id - jsonrpc @@ -1004,24 +1163,22 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/ListTaskPushNotificationConfigSuccessResponse' - description: JSON-RPC response for the 'tasks/pushNotificationConfig/list' method. + description: Represents a JSON-RPC response for the `tasks/pushNotificationConfig/list` method. ListTaskPushNotificationConfigSuccessResponse: - description: JSON-RPC success response model for the 'tasks/pushNotificationConfig/list' method. + description: Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/list` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: - description: The result object on success. + description: The result, containing an array of all push notification configurations for the task. items: $ref: '#/definitions/TaskPushNotificationConfig' type: array @@ -1031,45 +1188,47 @@ definitions: - result type: object Message: - description: Represents a single message exchanged between user and agent. + description: Represents a single message in the conversation between a user and an agent. properties: contextId: - description: The context the message is associated with + description: The context ID for this message, used to group related interactions. type: string extensions: - description: The URIs of extensions that are present or contributed to this Message. + description: The URIs of extensions that are relevant to this message. items: type: string type: array kind: const: message - description: Event type + description: The type of this object, used as a discriminator. Always 'message' for a Message. type: string messageId: - description: Identifier created by the message creator + description: A unique identifier for the message, typically a UUID, generated by the sender. type: string metadata: additionalProperties: {} - description: Extension metadata. + description: Optional metadata for extensions. The key is an extension-specific identifier. type: object parts: - description: Message content + description: |- + An array of content parts that form the message body. A message can be + composed of multiple parts of different types (e.g., text and files). items: $ref: '#/definitions/Part' type: array referenceTaskIds: - description: List of tasks referenced as context by this message. + description: A list of other task IDs that this message references for additional context. items: type: string type: array role: - description: Message sender's role + description: Identifies the sender of the message. `user` for the client, `agent` for the service. enum: - agent - user type: string taskId: - description: Identifier of task the message is related to + description: The ID of the task this message is part of. Can be omitted for the first message of a new task. type: string required: - kind @@ -1078,103 +1237,123 @@ definitions: - role type: object MessageSendConfiguration: - description: Configuration for the send message request. + description: Defines configuration options for a `message/send` or `message/stream` request. properties: acceptedOutputModes: - description: Accepted output modalities by the client. + description: A list of output MIME types the client is prepared to accept in the response. items: type: string type: array blocking: - description: If the server should treat the client as a blocking request. + description: If true, the client will wait for the task to complete. The server may reject this if the task is long-running. type: boolean historyLength: - description: Number of recent messages to be retrieved. + description: The number of most recent messages from the task's history to retrieve in the response. type: integer pushNotificationConfig: $ref: '#/definitions/PushNotificationConfig' - description: Where the server should send notifications when disconnected. - required: - - acceptedOutputModes + description: Configuration for the agent to send push notifications for updates after the initial response. type: object MessageSendParams: - description: Sent by the client to the agent as a request. May create, continue or restart a task. + description: |- + Defines the parameters for a request to send a message to an agent. This can be used + to create a new task, continue an existing one, or restart a task. properties: configuration: $ref: '#/definitions/MessageSendConfiguration' - description: Send message configuration. + description: Optional configuration for the send request. message: $ref: '#/definitions/Message' - description: The message being sent to the server. + description: The message object being sent to the agent. metadata: additionalProperties: {} - description: Extension metadata. + description: Optional metadata for extensions. type: object required: - message type: object MethodNotFoundError: - description: JSON-RPC error indicating the method does not exist or is not available. + description: An error indicating that the requested method does not exist or is not available. properties: code: const: -32601 - description: A Number that indicates the error type that occurred. + description: The error code for a method not found error. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Method not found - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object + MutualTLSSecurityScheme: + description: Defines a security scheme using mTLS authentication. + properties: + description: + description: An optional description for the security scheme. + type: string + type: + const: mutualTLS + description: The type of the security scheme. Must be 'mutualTLS'. + type: string + required: + - type + type: object OAuth2SecurityScheme: - description: OAuth2.0 security scheme configuration. + description: Defines a security scheme using OAuth 2.0. properties: description: - description: Description of this security scheme. + description: An optional description for the security scheme. type: string flows: $ref: '#/definitions/OAuthFlows' - description: An object containing configuration information for the flow types supported. + description: An object containing configuration information for the supported OAuth 2.0 flows. + oauth2MetadataUrl: + description: |- + URL to the oauth2 authorization server metadata + [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414). TLS is required. + type: string type: const: oauth2 + description: The type of the security scheme. Must be 'oauth2'. type: string required: - flows - type type: object OAuthFlows: - description: Allows configuration of the supported OAuth Flows + description: Defines the configuration for the supported OAuth 2.0 flows. properties: authorizationCode: $ref: '#/definitions/AuthorizationCodeOAuthFlow' description: Configuration for the OAuth Authorization Code flow. Previously called accessCode in OpenAPI 2.0. clientCredentials: $ref: '#/definitions/ClientCredentialsOAuthFlow' - description: Configuration for the OAuth Client Credentials flow. Previously called application in OpenAPI 2.0 + description: Configuration for the OAuth Client Credentials flow. Previously called application in OpenAPI 2.0. implicit: $ref: '#/definitions/ImplicitOAuthFlow' - description: Configuration for the OAuth Implicit flow + description: Configuration for the OAuth Implicit flow. password: $ref: '#/definitions/PasswordOAuthFlow' - description: Configuration for the OAuth Resource Owner Password flow + description: Configuration for the OAuth Resource Owner Password flow. type: object OpenIdConnectSecurityScheme: - description: OpenID Connect security scheme configuration. + description: Defines a security scheme using OpenID Connect. properties: description: - description: Description of this security scheme. + description: An optional description for the security scheme. type: string openIdConnectUrl: - description: Well-known URL to discover the [[OpenID-Connect-Discovery]] provider metadata. + description: The OpenID Connect Discovery URL for the OIDC provider's metadata. type: string type: const: openIdConnect + description: The type of the security scheme. Must be 'openIdConnect'. type: string required: - openIdConnectUrl @@ -1185,47 +1364,45 @@ definitions: - $ref: '#/definitions/TextPart' - $ref: '#/definitions/FilePart' - $ref: '#/definitions/DataPart' - description: Represents a part of a message, which can be text, a file, or structured data. + description: |- + A discriminated union representing a part of a message or artifact, which can + be text, a file, or structured data. PartBase: - description: Base properties common to all message parts. + description: Defines base properties common to all message or artifact parts. properties: metadata: additionalProperties: {} - description: Optional metadata associated with the part. + description: Optional metadata associated with this part. type: object type: object PasswordOAuthFlow: - description: Configuration details for a supported OAuth Flow + description: Defines configuration details for the OAuth 2.0 Resource Owner Password flow. properties: refreshUrl: - description: |- - The URL to be used for obtaining refresh tokens. This MUST be in the form of a URL. The OAuth2 - standard requires the use of TLS. + description: The URL to be used for obtaining refresh tokens. This MUST be a URL. type: string scopes: additionalProperties: type: string description: |- - The available scopes for the OAuth2 security scheme. A map between the scope name and a short - description for it. The map MAY be empty. + The available scopes for the OAuth2 security scheme. A map between the scope + name and a short description for it. type: object tokenUrl: - description: |- - The token URL to be used for this flow. This MUST be in the form of a URL. The OAuth2 standard - requires the use of TLS. + description: The token URL to be used for this flow. This MUST be a URL. type: string required: - scopes - tokenUrl type: object PushNotificationAuthenticationInfo: - description: Defines authentication details for push notifications. + description: Defines authentication details for a push notification endpoint. properties: credentials: - description: Optional credentials + description: Optional credentials required by the push notification endpoint. type: string schemes: - description: Supported authentication schemes - e.g. Basic, Bearer + description: A list of supported authentication schemes (e.g., 'Basic', 'Bearer'). items: type: string type: array @@ -1233,36 +1410,39 @@ definitions: - schemes type: object PushNotificationConfig: - description: Configuration for setting up push notifications for task updates. + description: Defines the configuration for setting up push notifications for task updates. properties: authentication: $ref: '#/definitions/PushNotificationAuthenticationInfo' + description: Optional authentication details for the agent to use when calling the notification URL. id: - description: Push Notification ID - created by server to support multiple callbacks + description: |- + A unique identifier (e.g. UUID) for the push notification configuration, set by the client + to support multiple notification callbacks. type: string token: - description: Token unique to this task/session. + description: A unique token for this task or session to validate incoming push notifications. type: string url: - description: URL for sending the push notifications. + description: The callback URL where the agent should send push notifications. type: string required: - url type: object PushNotificationNotSupportedError: - description: A2A specific error indicating the agent does not support push notifications. + description: An A2A-specific error indicating that the agent does not support push notifications. properties: code: const: -32003 - description: A Number that indicates the error type that occurred. + description: The error code for when push notifications are not supported. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Push Notification is not supported - description: A String providing a short description of the error. + description: The error message. type: string required: - code @@ -1274,37 +1454,36 @@ definitions: - $ref: '#/definitions/HTTPAuthSecurityScheme' - $ref: '#/definitions/OAuth2SecurityScheme' - $ref: '#/definitions/OpenIdConnectSecurityScheme' + - $ref: '#/definitions/MutualTLSSecurityScheme' description: |- - Mirrors the OpenAPI Security Scheme Object - (https://swagger.io/specification/#security-scheme-object) + Defines a security scheme that can be used to secure an agent's endpoints. + This is a discriminated union type based on the OpenAPI 3.0 Security Scheme Object. SecuritySchemeBase: - description: Base properties shared by all security schemes. + description: Defines base properties shared by all security scheme objects. properties: description: - description: Description of this security scheme. + description: An optional description for the security scheme. type: string type: object SendMessageRequest: - description: JSON-RPC request model for the 'message/send' method. + description: Represents a JSON-RPC request for the `message/send` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: message/send - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'message/send'. type: string params: $ref: '#/definitions/MessageSendParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters for sending a message. required: - id - jsonrpc @@ -1315,53 +1494,49 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/SendMessageSuccessResponse' - description: JSON-RPC response model for the 'message/send' method. + description: Represents a JSON-RPC response for the `message/send` method. SendMessageSuccessResponse: - description: JSON-RPC success response model for the 'message/send' method. + description: Represents a successful JSON-RPC response for the `message/send` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: anyOf: - $ref: '#/definitions/Task' - $ref: '#/definitions/Message' - description: The result object on success + description: The result, which can be a direct reply Message or the initial Task object. required: - id - jsonrpc - result type: object SendStreamingMessageRequest: - description: JSON-RPC request model for the 'message/stream' method. + description: Represents a JSON-RPC request for the `message/stream` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: message/stream - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'message/stream'. type: string params: $ref: '#/definitions/MessageSendParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters for sending a message. required: - id - jsonrpc @@ -1372,21 +1547,21 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/SendStreamingMessageSuccessResponse' - description: JSON-RPC response model for the 'message/stream' method. + description: Represents a JSON-RPC response for the `message/stream` method. SendStreamingMessageSuccessResponse: - description: JSON-RPC success response model for the 'message/stream' method. + description: |- + Represents a successful JSON-RPC response for the `message/stream` method. + The server may send multiple response objects for a single request. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: anyOf: @@ -1394,33 +1569,31 @@ definitions: - $ref: '#/definitions/Message' - $ref: '#/definitions/TaskStatusUpdateEvent' - $ref: '#/definitions/TaskArtifactUpdateEvent' - description: The result object on success + description: The result, which can be a Message, Task, or a streaming update event. required: - id - jsonrpc - result type: object SetTaskPushNotificationConfigRequest: - description: JSON-RPC request model for the 'tasks/pushNotificationConfig/set' method. + description: Represents a JSON-RPC request for the `tasks/pushNotificationConfig/set` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/pushNotificationConfig/set - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/pushNotificationConfig/set'. type: string params: $ref: '#/definitions/TaskPushNotificationConfig' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters for setting the push notification configuration. required: - id - jsonrpc @@ -1431,58 +1604,58 @@ definitions: anyOf: - $ref: '#/definitions/JSONRPCErrorResponse' - $ref: '#/definitions/SetTaskPushNotificationConfigSuccessResponse' - description: JSON-RPC response for the 'tasks/pushNotificationConfig/set' method. + description: Represents a JSON-RPC response for the `tasks/pushNotificationConfig/set` method. SetTaskPushNotificationConfigSuccessResponse: - description: JSON-RPC success response model for the 'tasks/pushNotificationConfig/set' method. + description: Represents a successful JSON-RPC response for the `tasks/pushNotificationConfig/set` method. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier established by the client. type: - string - integer - 'null' jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string result: $ref: '#/definitions/TaskPushNotificationConfig' - description: The result object on success. + description: The result, containing the configured push notification settings. required: - id - jsonrpc - result type: object Task: + description: Represents a single, stateful operation or conversation between a client and an agent. properties: artifacts: - description: Collection of artifacts created by the agent. + description: A collection of artifacts generated by the agent during the execution of the task. items: $ref: '#/definitions/Artifact' type: array contextId: - description: Server-generated id for contextual alignment across interactions + description: A server-generated unique identifier (e.g. UUID) for maintaining context across multiple related tasks or interactions. type: string history: + description: An array of messages exchanged during the task, representing the conversation history. items: $ref: '#/definitions/Message' type: array id: - description: Unique identifier for the task + description: A unique identifier (e.g. UUID) for the task, generated by the server for a new task. type: string kind: const: task - description: Event type + description: The type of this object, used as a discriminator. Always 'task' for a Task. type: string metadata: additionalProperties: {} - description: Extension metadata. + description: Optional metadata for extensions. The key is an extension-specific identifier. type: object status: $ref: '#/definitions/TaskStatus' - description: Current status of the task + description: The current status of the task, including its state and a descriptive message. required: - contextId - id @@ -1490,30 +1663,32 @@ definitions: - status type: object TaskArtifactUpdateEvent: - description: Sent by server during sendStream or subscribe requests + description: |- + An event sent by the agent to notify the client that an artifact has been + generated or updated. This is typically used in streaming models. properties: append: - description: Indicates if this artifact appends to a previous one + description: If true, the content of this artifact should be appended to a previously sent artifact with the same ID. type: boolean artifact: $ref: '#/definitions/Artifact' - description: Generated artifact + description: The artifact that was generated or updated. contextId: - description: The context the task is associated with + description: The context ID associated with the task. type: string kind: const: artifact-update - description: Event type + description: The type of this event, used as a discriminator. Always 'artifact-update'. type: string lastChunk: - description: Indicates if this is the last chunk of the artifact + description: If true, this is the final chunk of the artifact. type: boolean metadata: additionalProperties: {} - description: Extension metadata. + description: Optional metadata for extensions. type: object taskId: - description: Task id + description: The ID of the task this artifact belongs to. type: string required: - artifact @@ -1522,104 +1697,104 @@ definitions: - taskId type: object TaskIdParams: - description: Parameters containing only a task ID, used for simple task operations. + description: Defines parameters containing a task ID, used for simple task operations. properties: id: - description: Task id. + description: The unique identifier (e.g. UUID) of the task. type: string metadata: additionalProperties: {} + description: Optional metadata associated with the request. type: object required: - id type: object TaskNotCancelableError: - description: A2A specific error indicating the task is in a state where it cannot be canceled. + description: An A2A-specific error indicating that the task is in a state where it cannot be canceled. properties: code: const: -32002 - description: A Number that indicates the error type that occurred. + description: The error code for a task that cannot be canceled. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Task cannot be canceled - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object TaskNotFoundError: - description: A2A specific error indicating the requested task ID was not found. + description: An A2A-specific error indicating that the requested task ID was not found. properties: code: const: -32001 - description: A Number that indicates the error type that occurred. + description: The error code for a task not found error. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: Task not found - description: A String providing a short description of the error. + description: The error message. type: string required: - code - message type: object TaskPushNotificationConfig: - description: Parameters for setting or getting push notification configuration for a task + description: A container associating a push notification configuration with a specific task. properties: pushNotificationConfig: $ref: '#/definitions/PushNotificationConfig' - description: Push notification configuration. + description: The push notification configuration for this task. taskId: - description: Task id. + description: The unique identifier (e.g. UUID) of the task. type: string required: - pushNotificationConfig - taskId type: object TaskQueryParams: - description: Parameters for querying a task, including optional history length. + description: Defines parameters for querying a task, with an option to limit history length. properties: historyLength: - description: Number of recent messages to be retrieved. + description: The number of most recent messages from the task's history to retrieve. type: integer id: - description: Task id. + description: The unique identifier (e.g. UUID) of the task. type: string metadata: additionalProperties: {} + description: Optional metadata associated with the request. type: object required: - id type: object TaskResubscriptionRequest: - description: JSON-RPC request model for the 'tasks/resubscribe' method. + description: Represents a JSON-RPC request for the `tasks/resubscribe` method, used to resume a streaming connection. properties: id: - description: |- - An identifier established by the Client that MUST contain a String, Number. - Numbers SHOULD NOT contain fractional parts. + description: The identifier for this request. type: - string - integer jsonrpc: const: '2.0' - description: Specifies the version of the JSON-RPC protocol. MUST be exactly "2.0". + description: The version of the JSON-RPC protocol. MUST be exactly "2.0". type: string method: const: tasks/resubscribe - description: A String containing the name of the method to be invoked. + description: The method name. Must be 'tasks/resubscribe'. type: string params: $ref: '#/definitions/TaskIdParams' - description: A Structured value that holds the parameter values to be used during the invocation of the method. + description: The parameters identifying the task to resubscribe to. required: - id - jsonrpc @@ -1627,7 +1802,7 @@ definitions: - params type: object TaskState: - description: Represents the possible states of a Task. + description: Defines the lifecycle states of a Task. enum: - submitted - working @@ -1640,41 +1815,46 @@ definitions: - unknown type: string TaskStatus: - description: TaskState and accompanying message. + description: Represents the status of a task at a specific point in time. properties: message: $ref: '#/definitions/Message' - description: Additional status updates for client + description: An optional, human-readable message providing more details about the current status. state: $ref: '#/definitions/TaskState' + description: The current state of the task's lifecycle. timestamp: - description: ISO 8601 datetime string when the status was recorded. + description: An ISO 8601 datetime string indicating when this status was recorded. + examples: + - '2023-10-27T10:00:00Z' type: string required: - state type: object TaskStatusUpdateEvent: - description: Sent by server during sendStream or subscribe requests + description: |- + An event sent by the agent to notify the client of a change in a task's status. + This is typically used in streaming or subscription models. properties: contextId: - description: The context the task is associated with + description: The context ID associated with the task. type: string final: - description: Indicates the end of the event stream + description: If true, this is the final event in the stream for this interaction. type: boolean kind: const: status-update - description: Event type + description: The type of this event, used as a discriminator. Always 'status-update'. type: string metadata: additionalProperties: {} - description: Extension metadata. + description: Optional metadata for extensions. type: object status: $ref: '#/definitions/TaskStatus' - description: Current status of the task + description: The new status of the task. taskId: - description: Task id + description: The ID of the task that was updated. type: string required: - contextId @@ -1684,37 +1864,44 @@ definitions: - taskId type: object TextPart: - description: Represents a text segment within parts. + description: Represents a text segment within a message or artifact. properties: kind: const: text - description: Part type - text for TextParts + description: The type of this part, used as a discriminator. Always 'text'. type: string metadata: additionalProperties: {} - description: Optional metadata associated with the part. + description: Optional metadata associated with this part. type: object text: - description: Text content + description: The string content of the text part. type: string required: - kind - text type: object + TransportProtocol: + description: Supported A2A transport protocols. + enum: + - JSONRPC + - GRPC + - HTTP+JSON + type: string UnsupportedOperationError: - description: A2A specific error indicating the requested operation is not supported by the agent. + description: An A2A-specific error indicating that the requested operation is not supported by the agent. properties: code: const: -32004 - description: A Number that indicates the error type that occurred. + description: The error code for an unsupported operation. type: integer data: description: |- - A Primitive or Structured value that contains additional information about the error. + A primitive or structured value containing additional information about the error. This may be omitted. message: default: This operation is not supported - description: A String providing a short description of the error. + description: The error message. type: string required: - code diff --git a/cli/cli.go b/cli/cli.go index 534dc49..3e266ce 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -225,7 +225,7 @@ func getOutputFormat() OutputFormat { } // formatOutput formats the given data according to the specified format -func formatOutput(data interface{}) ([]byte, error) { +func formatOutput(data any) ([]byte, error) { format := getOutputFormat() switch format { case OutputFormatJSON: @@ -238,7 +238,7 @@ func formatOutput(data interface{}) ([]byte, error) { } // printFormatted outputs the data in the configured format -func printFormatted(data interface{}) error { +func printFormatted(data any) error { output, err := formatOutput(data) if err != nil { return fmt.Errorf("failed to format output: %w", err) @@ -329,7 +329,7 @@ var connectCmd = &cobra.Command{ return fmt.Errorf("failed to connect to A2A server: %w", err) } - output := map[string]interface{}{ + output := map[string]any{ "connected": true, "agent": agentCard, } @@ -382,7 +382,7 @@ var listTasksCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task list: %w", err) } - output := map[string]interface{}{ + output := map[string]any{ "tasks": taskList.Tasks, "total": taskList.Total, "showing": len(taskList.Tasks), @@ -466,7 +466,7 @@ var historyCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task list: %w", err) } - output := map[string]interface{}{ + output := map[string]any{ "context_id": contextID, "tasks": taskList.Tasks, } @@ -499,7 +499,7 @@ var versionCmd = &cobra.Command{ Short: "Print version information", Long: "Display version information including version number, commit hash, and build date.", RunE: func(cmd *cobra.Command, args []string) error { - version := map[string]interface{}{ + version := map[string]any{ "name": "A2A Debugger", "version": appVersion, "commit": buildCommit, @@ -530,7 +530,7 @@ var submitTaskCmd = &cobra.Command{ MessageID: messageID, Role: "user", Parts: []adk.Part{ - map[string]interface{}{ + map[string]any{ "kind": "text", "text": message, }, @@ -563,7 +563,7 @@ var submitTaskCmd = &cobra.Command{ return fmt.Errorf("failed to unmarshal task: %w", err) } - output := map[string]interface{}{ + output := map[string]any{ "submitted": true, "message_id": messageID, "task": task, @@ -596,7 +596,7 @@ var submitStreamingTaskCmd = &cobra.Command{ MessageID: messageID, Role: "user", Parts: []adk.Part{ - map[string]interface{}{ + map[string]any{ "kind": "text", "text": message, }, @@ -614,7 +614,7 @@ var submitStreamingTaskCmd = &cobra.Command{ logger.Debug("submitting new streaming task", zap.String("message", message), zap.String("context_id", contextID), zap.String("task_id", taskID)) - eventChan := make(chan interface{}, 100) + eventChan := make(chan any, 100) go func() { defer close(eventChan) @@ -650,7 +650,7 @@ var submitStreamingTaskCmd = &cobra.Command{ continue } - var genericEvent map[string]interface{} + var genericEvent map[string]any if err := json.Unmarshal(eventJSON, &genericEvent); err != nil { logger.Error("Failed to unmarshal generic event", zap.Error(err)) continue @@ -733,7 +733,7 @@ var submitStreamingTaskCmd = &cobra.Command{ if statusEvent.Status.Message != nil && len(statusEvent.Status.Message.Parts) > 0 { fmt.Printf("\nšŸ’¬ Agent Response:\n") for _, part := range statusEvent.Status.Message.Parts { - if partMap, ok := part.(map[string]interface{}); ok { + if partMap, ok := part.(map[string]any); ok { if kind, ok := partMap["kind"].(string); ok && kind == "text" { if text, ok := partMap["text"].(string); ok { fmt.Printf("%s\n", text) @@ -762,7 +762,7 @@ var submitStreamingTaskCmd = &cobra.Command{ if len(artifactEvent.Artifact.Parts) > 0 { fmt.Printf(" Parts:\n") for i, part := range artifactEvent.Artifact.Parts { - if partMap, ok := part.(map[string]interface{}); ok { + if partMap, ok := part.(map[string]any); ok { if kind, exists := partMap["kind"]; exists { fmt.Printf(" Part %d: [%v]", i+1, kind) if text, exists := partMap["text"]; exists { diff --git a/cli/cli_output_test.go b/cli/cli_output_test.go index 99a493e..5eaf0b4 100644 --- a/cli/cli_output_test.go +++ b/cli/cli_output_test.go @@ -62,7 +62,7 @@ func TestGetOutputFormat(t *testing.T) { } func TestFormatOutput(t *testing.T) { - testData := map[string]interface{}{ + testData := map[string]any{ "name": "test", "version": "1.0.0", "active": true, @@ -71,7 +71,7 @@ func TestFormatOutput(t *testing.T) { tests := []struct { name string outputFormat string - data interface{} + data any validate func([]byte) error }{ { @@ -79,7 +79,7 @@ func TestFormatOutput(t *testing.T) { outputFormat: "yaml", data: testData, validate: func(output []byte) error { - var result map[string]interface{} + var result map[string]any if err := yaml.Unmarshal(output, &result); err != nil { return fmt.Errorf("failed to parse YAML: %w", err) } @@ -94,7 +94,7 @@ func TestFormatOutput(t *testing.T) { outputFormat: "json", data: testData, validate: func(output []byte) error { - var result map[string]interface{} + var result map[string]any if err := json.Unmarshal(output, &result); err != nil { return fmt.Errorf("failed to parse JSON: %w", err) } @@ -123,7 +123,7 @@ func TestFormatOutput(t *testing.T) { } func TestPrintFormatted(t *testing.T) { - testData := map[string]interface{}{ + testData := map[string]any{ "message": "hello world", "status": "success", } @@ -174,14 +174,13 @@ func TestPrintFormatted(t *testing.T) { t.Error("Expected output but got none") } - // Verify the output can be parsed back if tt.outputFormat == "json" { - var result map[string]interface{} + var result map[string]any if err := json.Unmarshal([]byte(output), &result); err != nil { t.Errorf("Failed to parse JSON output: %v", err) } } else { - var result map[string]interface{} + var result map[string]any if err := yaml.Unmarshal([]byte(output), &result); err != nil { t.Errorf("Failed to parse YAML output: %v", err) } diff --git a/cli/cli_test.go b/cli/cli_test.go index 93ab738..9a919a5 100644 --- a/cli/cli_test.go +++ b/cli/cli_test.go @@ -19,7 +19,7 @@ import ( // mockA2AClient implements the A2AClient interface for testing type mockA2AClient struct { - sendTaskStreamingFunc func(ctx context.Context, params adk.MessageSendParams, eventChan chan<- interface{}) error + sendTaskStreamingFunc func(ctx context.Context, params adk.MessageSendParams, eventChan chan<- any) error } func (m *mockA2AClient) GetAgentCard(ctx context.Context) (*adk.AgentCard, error) { @@ -42,7 +42,7 @@ func (m *mockA2AClient) SendTask(ctx context.Context, params adk.MessageSendPara return nil, fmt.Errorf("not implemented") } -func (m *mockA2AClient) SendTaskStreaming(ctx context.Context, params adk.MessageSendParams, eventChan chan<- interface{}) error { +func (m *mockA2AClient) SendTaskStreaming(ctx context.Context, params adk.MessageSendParams, eventChan chan<- any) error { if m.sendTaskStreamingFunc != nil { return m.sendTaskStreamingFunc(ctx, params, eventChan) } @@ -75,7 +75,7 @@ func TestSubmitStreamingTaskCmd_StreamingSummary(t *testing.T) { logger = testLogger mockClient := &mockA2AClient{ - sendTaskStreamingFunc: func(ctx context.Context, params adk.MessageSendParams, eventChan chan<- interface{}) error { + sendTaskStreamingFunc: func(ctx context.Context, params adk.MessageSendParams, eventChan chan<- any) error { statusEvent := a2a.TaskStatusUpdateEvent{ Kind: "status-update", TaskID: "test-task-123", @@ -87,7 +87,7 @@ func TestSubmitStreamingTaskCmd_StreamingSummary(t *testing.T) { MessageID: "msg-123", Role: "assistant", Parts: []a2a.Part{ - map[string]interface{}{ + map[string]any{ "kind": "text", "text": "Test response", }, @@ -105,7 +105,7 @@ func TestSubmitStreamingTaskCmd_StreamingSummary(t *testing.T) { Artifact: a2a.Artifact{ ArtifactID: "artifact-123", Parts: []a2a.Part{ - map[string]interface{}{ + map[string]any{ "kind": "text", "text": "Test artifact content", }, @@ -125,7 +125,7 @@ func TestSubmitStreamingTaskCmd_StreamingSummary(t *testing.T) { MessageID: "msg-124", Role: "assistant", Parts: []a2a.Part{ - map[string]interface{}{ + map[string]any{ "kind": "text", "text": "Task completed", }, @@ -135,7 +135,7 @@ func TestSubmitStreamingTaskCmd_StreamingSummary(t *testing.T) { Final: true, } eventChan <- finalStatusEvent - + return nil }, } @@ -148,7 +148,7 @@ func TestSubmitStreamingTaskCmd_StreamingSummary(t *testing.T) { cmd := &cobra.Command{} cmd.Flags().String("context-id", "", "Context ID for the task") cmd.Flags().Bool("raw", false, "Show raw streaming event data") - + err := submitStreamingTaskCmd.RunE(cmd, []string{"test message"}) _ = w.Close() @@ -191,7 +191,7 @@ func TestSubmitStreamingTaskCmd_RawMode(t *testing.T) { logger = testLogger mockClient := &mockA2AClient{ - sendTaskStreamingFunc: func(ctx context.Context, params adk.MessageSendParams, eventChan chan<- interface{}) error { + sendTaskStreamingFunc: func(ctx context.Context, params adk.MessageSendParams, eventChan chan<- any) error { statusEvent := a2a.TaskStatusUpdateEvent{ Kind: "status-update", TaskID: "test-task-456", @@ -202,7 +202,7 @@ func TestSubmitStreamingTaskCmd_RawMode(t *testing.T) { Final: true, } eventChan <- statusEvent - + return nil }, } @@ -216,7 +216,7 @@ func TestSubmitStreamingTaskCmd_RawMode(t *testing.T) { cmd.Flags().String("context-id", "", "Context ID for the task") cmd.Flags().Bool("raw", true, "Show raw streaming event data") _ = cmd.Flag("raw").Value.Set("true") - + err := submitStreamingTaskCmd.RunE(cmd, []string{"test message"}) _ = w.Close() From 8cc975774034aa6ca6a15884bbf2af4b4f12e19d Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:40:38 +0200 Subject: [PATCH 4/9] chore(deps): Upgrade Go version to 1.25 and update dependencies in Dockerfile, go.mod, and CI workflows Signed-off-by: Eden Reich --- .devcontainer/Dockerfile | 12 +- .flox/env/manifest.lock | 202 ++++++++++++++++++----- .flox/env/manifest.toml | 5 +- .github/workflows/artifacts.yml | 22 +-- .github/workflows/ci.yml | 10 +- .github/workflows/claude-code-review.yml | 56 ------- .github/workflows/claude.yml | 6 +- .github/workflows/release.yml | 4 +- CLAUDE.md | 2 +- Dockerfile | 2 +- README.md | 2 +- go.mod | 4 +- 12 files changed, 201 insertions(+), 126 deletions(-) delete mode 100644 .github/workflows/claude-code-review.yml diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index ec33d26..e2e4de7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,11 +1,11 @@ -FROM mcr.microsoft.com/devcontainers/go:1-1.24-bookworm +FROM mcr.microsoft.com/devcontainers/go:2-1.25-bookworm -ENV TASK_VERSION=v3.44.0 \ - GORELEASER_VERSION=v2.9.0 \ - GOLANG_CI_LINT_VERSION=v2.1.6 \ - GITHUB_CLI_VERSION=2.68.1 \ +ENV TASK_VERSION=v3.45.4 \ + GORELEASER_VERSION=v2.12.0 \ + GOLANG_CI_LINT_VERSION=v2.5.0 \ + GITHUB_CLI_VERSION=2.81.0 \ NODE_VERSION=lts \ - SEMANTIC_RELEASE_VERSION=v24.2.5 + SEMANTIC_RELEASE_VERSION=v24.2.9 RUN apt-get update && \ # Determine architecture diff --git a/.flox/env/manifest.lock b/.flox/env/manifest.lock index f8df9cc..0213222 100644 --- a/.flox/env/manifest.lock +++ b/.flox/env/manifest.lock @@ -5,7 +5,11 @@ "install": { "go": { "pkg-path": "go", - "version": "^1.24" + "version": "^1.25" + }, + "go-task": { + "pkg-path": "go-task", + "version": "^3.45.4" } }, "hook": { @@ -17,27 +21,28 @@ { "attr_path": "go", "broken": false, - "derivation": "/nix/store/b4f7b08k5wnka70sax9qx3d2p1x2sfb9-go-1.24.6.drv", + "derivation": "/nix/store/4vsv792v76f1v0d3w0yd36fb54qbx40v-go-1.25.0.drv", "description": "Go Programming language", "install_id": "go", "license": "BSD-3-Clause", - "locked_url": "https://github.com/flox/nixpkgs?rev=8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "name": "go-1.24.6", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-1.25.0", "pname": "go", - "rev": "8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "rev_count": 852432, - "rev_date": "2025-08-27T03:49:43Z", - "scrape_date": "2025-08-28T03:26:01.562872Z", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T04:40:09.627704Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, - "version": "1.24.6", + "version": "1.25.0", "outputs_to_install": [ "out" ], "outputs": { - "out": "/nix/store/rgmygksbfyy75iappxpinv0y8lxfq35x-go-1.24.6" + "out": "/nix/store/cr196bvbbai01r0w11p1inkzkdrqdx6y-go-1.25.0" }, "system": "aarch64-darwin", "group": "toplevel", @@ -46,27 +51,28 @@ { "attr_path": "go", "broken": false, - "derivation": "/nix/store/x4i65glp99jc4a2cxkz1scx29s08dw05-go-1.24.6.drv", + "derivation": "/nix/store/l1ircnwvgwv6l1s6qzj0avfbyjp35ca8-go-1.25.0.drv", "description": "Go Programming language", "install_id": "go", "license": "BSD-3-Clause", - "locked_url": "https://github.com/flox/nixpkgs?rev=8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "name": "go-1.24.6", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-1.25.0", "pname": "go", - "rev": "8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "rev_count": 852432, - "rev_date": "2025-08-27T03:49:43Z", - "scrape_date": "2025-08-28T03:34:27.703146Z", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T04:56:40.000926Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, - "version": "1.24.6", + "version": "1.25.0", "outputs_to_install": [ "out" ], "outputs": { - "out": "/nix/store/w30rz1jlg360zk9d34ylhdvcdz19vyxh-go-1.24.6" + "out": "/nix/store/yhcdwwikp86p2cpq0qr7di91ji63460s-go-1.25.0" }, "system": "aarch64-linux", "group": "toplevel", @@ -75,27 +81,28 @@ { "attr_path": "go", "broken": false, - "derivation": "/nix/store/awngf5b7wwjyay1nlfjnk25a39f823c3-go-1.24.6.drv", + "derivation": "/nix/store/iqfbwa0qdhgrynay4i1c2lg988i98wz1-go-1.25.0.drv", "description": "Go Programming language", "install_id": "go", "license": "BSD-3-Clause", - "locked_url": "https://github.com/flox/nixpkgs?rev=8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "name": "go-1.24.6", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-1.25.0", "pname": "go", - "rev": "8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "rev_count": 852432, - "rev_date": "2025-08-27T03:49:43Z", - "scrape_date": "2025-08-28T03:43:53.573934Z", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T05:12:16.314162Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, - "version": "1.24.6", + "version": "1.25.0", "outputs_to_install": [ "out" ], "outputs": { - "out": "/nix/store/kcj6a7xghpcsg6by6kkc03s3rr2v34il-go-1.24.6" + "out": "/nix/store/hz7dfw13v8iff4vf6vbnqnlnd7wh7j5x-go-1.25.0" }, "system": "x86_64-darwin", "group": "toplevel", @@ -104,27 +111,148 @@ { "attr_path": "go", "broken": false, - "derivation": "/nix/store/lz6sgami9527f9s2sh8bd8y2imv8nqqb-go-1.24.6.drv", + "derivation": "/nix/store/q4lnc9dhphz8h133yz9cx2whfrmndifc-go-1.25.0.drv", "description": "Go Programming language", "install_id": "go", "license": "BSD-3-Clause", - "locked_url": "https://github.com/flox/nixpkgs?rev=8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "name": "go-1.24.6", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-1.25.0", "pname": "go", - "rev": "8a6d5427d99ec71c64f0b93d45778c889005d9c2", - "rev_count": 852432, - "rev_date": "2025-08-27T03:49:43Z", - "scrape_date": "2025-08-28T03:51:30.313652Z", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T05:27:33.651241Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "1.25.0", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/3fd683jfggglpshxprz9mi5sz8wd3c9p-go-1.25.0" + }, + "system": "x86_64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "go-task", + "broken": false, + "derivation": "/nix/store/7vy1xgwwf179n32yf1csqs7zvywx0w3g-go-task-3.45.4.drv", + "description": "Task runner / simpler Make alternative written in Go", + "install_id": "go-task", + "license": "MIT", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-task-3.45.4", + "pname": "go-task", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T04:40:09.646158Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.45.4", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/q6ln03442mj1lyckjssqvhjmamwv4shy-go-task-3.45.4" + }, + "system": "aarch64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "go-task", + "broken": false, + "derivation": "/nix/store/l14wvy2z9avqx70sp450p84ji1r6z3hk-go-task-3.45.4.drv", + "description": "Task runner / simpler Make alternative written in Go", + "install_id": "go-task", + "license": "MIT", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-task-3.45.4", + "pname": "go-task", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T04:56:40.027905Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.45.4", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/kc677152flyszzldgphlzlcnf2ap87c0-go-task-3.45.4" + }, + "system": "aarch64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "go-task", + "broken": false, + "derivation": "/nix/store/lrvqsavsn5746mdqhw6x638s6d51l53g-go-task-3.45.4.drv", + "description": "Task runner / simpler Make alternative written in Go", + "install_id": "go-task", + "license": "MIT", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-task-3.45.4", + "pname": "go-task", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T05:12:16.332841Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": false, + "version": "3.45.4", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/v4fpcid9nb9in5wi3f5bbz8m5yx880wb-go-task-3.45.4" + }, + "system": "x86_64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "go-task", + "broken": false, + "derivation": "/nix/store/6qqrxabc1m4irc8ckkpdih3q6m4mv5kr-go-task-3.45.4.drv", + "description": "Task runner / simpler Make alternative written in Go", + "install_id": "go-task", + "license": "MIT", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "go-task-3.45.4", + "pname": "go-task", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T05:27:33.681590Z", "stabilities": [ + "staging", "unstable" ], "unfree": false, - "version": "1.24.6", + "version": "3.45.4", "outputs_to_install": [ "out" ], "outputs": { - "out": "/nix/store/g026m2zmhiah7izdmmvgsq847z2sh1h1-go-1.24.6" + "out": "/nix/store/fyywhmm96sgz0jj60d9x7fb9ijc0h0pw-go-task-3.45.4" }, "system": "x86_64-linux", "group": "toplevel", diff --git a/.flox/env/manifest.toml b/.flox/env/manifest.toml index e10403a..71b8604 100644 --- a/.flox/env/manifest.toml +++ b/.flox/env/manifest.toml @@ -2,7 +2,10 @@ version = 1 [install] go.pkg-path = "go" -go.version = "^1.24" +go.version = "^1.25" + +go-task.pkg-path = "go-task" +go-task.version = "^3.45.4" [hook] on-activate = """ diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index 51236a4..0baa5fa 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -19,28 +19,28 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Checkout code - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v5 with: ref: ${{ github.ref }} fetch-depth: 0 - name: Set up Go - uses: actions/setup-go@v5.5.0 + uses: actions/setup-go@v6 with: - go-version: '1.24' + go-version-file: 'go.mod' cache: true - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.10.0 + uses: docker/setup-buildx-action@v3.11.1 with: version: latest - name: Install GoReleaser run: | - curl -sSL https://github.com/goreleaser/goreleaser/releases/download/v2.7.0/goreleaser_Linux_x86_64.tar.gz | tar -xzv -C /usr/local/bin goreleaser + curl -sSL https://github.com/goreleaser/goreleaser/releases/download/v2.12.0/goreleaser_Linux_x86_64.tar.gz | tar -xzv -C /usr/local/bin goreleaser - name: Login to GitHub Container Registry - uses: docker/login-action@v3.4.0 + uses: docker/login-action@v3.6.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -86,12 +86,12 @@ jobs: TAG: ${{ github.event.release.tag_name }} steps: - name: Checkout repository - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v5 with: ref: ${{ github.ref }} - name: Login to GitHub Container Registry - uses: docker/login-action@v3.4.0 + uses: docker/login-action@v3.6.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -125,12 +125,12 @@ jobs: TAG: ${{ github.event.release.tag_name }} steps: - name: Install cosign - uses: sigstore/cosign-installer@v3.8.2 + uses: sigstore/cosign-installer@v3.10.0 with: - cosign-release: 'v2.5.0' + cosign-release: 'v2.6.0' - name: Log in to GitHub Container Registry - uses: docker/login-action@v3.4.0 + uses: docker/login-action@v3.6.0 with: registry: ghcr.io username: ${{ github.actor }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 232be36..df2828b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,21 +12,21 @@ jobs: build: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@v4.2.2 + - uses: actions/checkout@v5 - name: Set up Go - uses: actions/setup-go@v5.5.0 + uses: actions/setup-go@v6 with: - go-version: '1.24' + go-version-file: 'go.mod' cache: true - name: Install Task run: | - curl -s https://taskfile.dev/install.sh | sh -s -- -b /usr/local/bin v3.44.1 + curl -s https://taskfile.dev/install.sh | sh -s -- -b /usr/local/bin v3.45.4 - name: Install golangci-lint run: | - curl -fsSL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v2.1.6 + curl -fsSL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v2.5.0 - name: Install Go tools run: | diff --git a/.github/workflows/claude-code-review.yml b/.github/workflows/claude-code-review.yml deleted file mode 100644 index da186c6..0000000 --- a/.github/workflows/claude-code-review.yml +++ /dev/null @@ -1,56 +0,0 @@ -name: Claude Code Review - -on: - issue_comment: - types: - - created - -jobs: - claude-review: - if: | - github.event_name == 'issue_comment' && - github.event.issue.pull_request && - contains(github.event.comment.body, '@claude /review') - runs-on: ubuntu-24.04 - permissions: - contents: write - pull-requests: write - issues: write - id-token: write - actions: read - - steps: - - name: Checkout repository - uses: actions/checkout@v4.2.2 - with: - fetch-depth: 1 - - - name: Run Claude Code Review - id: claude-review - uses: anthropics/claude-code-action@beta - with: - claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - additional_permissions: | - actions: read - use_commit_signing: true - base_branch: main - branch_prefix: 'claude/' - mcp_config: | - { - "mcpServers": { - "context7": { - "command": "npx", - "args": ["-y", "@upstash/context7-mcp@latest"], - "env": {} - } - } - } - direct_prompt: | - Please review this pull request and provide feedback on: - - Code quality and best practices - - Potential bugs or issues - - Performance considerations - - Security concerns - - Test coverage - - Be constructive and helpful in your feedback. diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index ab6881d..de292e3 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -31,17 +31,17 @@ jobs: actions: read steps: - name: Checkout repository - uses: actions/checkout@v4.2.2 + uses: actions/checkout@v5 with: fetch-depth: 1 - name: Install golangci-lint run: | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v2.1.6 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b /usr/local/bin v2.5.0 - name: Install task run: | - curl -s https://taskfile.dev/install.sh | sh -s -- -b /usr/local/bin v3.43.3 + curl -s https://taskfile.dev/install.sh | sh -s -- -b /usr/local/bin v3.45.4 - name: Run Claude Code id: claude diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e047f5c..70d139e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,13 +48,13 @@ jobs: token: ${{ steps.app-token.outputs.token }} - name: Set up Node.js - uses: actions/setup-node@v4.4.0 + uses: actions/setup-node@v5 with: node-version: "lts/*" - name: Install semantic release and plugins run: | - npm install -g semantic-release@v24.2.5 \ + npm install -g semantic-release@v24.2.9 \ conventional-changelog-cli \ conventional-changelog-conventionalcommits \ @semantic-release/changelog \ diff --git a/CLAUDE.md b/CLAUDE.md index 8be6e98..713be4f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -114,7 +114,7 @@ task build:docker - **CLI Framework**: `github.com/spf13/cobra` + `github.com/spf13/viper` - **A2A SDK**: `github.com/inference-gateway/a2a` - **Logging**: `go.uber.org/zap` -- **Go Version**: 1.24+ +- **Go Version**: 1.25+ ## Development Guidelines diff --git a/Dockerfile b/Dockerfile index 7d961fe..e9831dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.24-alpine AS builder +FROM golang:1.25-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download diff --git a/README.md b/README.md index 15fb5a7..74c2fbc 100644 --- a/README.md +++ b/README.md @@ -330,7 +330,7 @@ $ a2a tasks list --limit 2 -o json ### Prerequisites -- Go 1.24 or later +- Go 1.25 or later - [Task](https://taskfile.dev/) for build automation ### Available Tasks diff --git a/go.mod b/go.mod index 611142f..590a723 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,13 @@ module github.com/inference-gateway/a2a-debugger -go 1.24 +go 1.25 require ( github.com/inference-gateway/adk v0.7.4 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 go.uber.org/zap v1.27.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( @@ -31,5 +32,4 @@ require ( golang.org/x/text v0.26.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) From 3f02174d2f49ee9cc7942990304a21a783f28254 Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:44:43 +0200 Subject: [PATCH 5/9] chore: Update Trivy action version to 0.33.1 for vulnerability scanning Signed-off-by: Eden Reich --- .github/workflows/artifacts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/artifacts.yml b/.github/workflows/artifacts.yml index 0baa5fa..e6d5eec 100644 --- a/.github/workflows/artifacts.yml +++ b/.github/workflows/artifacts.yml @@ -101,7 +101,7 @@ jobs: run: echo "VERSION=${TAG#v}" >> $GITHUB_ENV - name: Run Vulnerability Scanning - uses: aquasecurity/trivy-action@0.31.0 + uses: aquasecurity/trivy-action@0.33.1 with: image-ref: 'ghcr.io/${{ github.repository }}:${{ env.VERSION }}' exit-code: '0' From 5bc024fdd9edb17f03efdd8242e2d738c7206f01 Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:45:37 +0200 Subject: [PATCH 6/9] chore: Remove outdated documentation files for Copilot and CLAUDE Signed-off-by: Eden Reich --- .github/copilot-instructions.md | 43 -------- CLAUDE.md | 173 -------------------------------- 2 files changed, 216 deletions(-) delete mode 100644 .github/copilot-instructions.md delete mode 100644 CLAUDE.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md deleted file mode 100644 index 59849c4..0000000 --- a/.github/copilot-instructions.md +++ /dev/null @@ -1,43 +0,0 @@ -# Custom Instructions for Copilot - -Today is June 17, 2025. - -- Never modify files with generated\_ prefix: These files are automatically generated and should not be edited manually. -- Always use context7 to check for the latest updates, features, or best practices of a library relevant to the task at hand. -- Always prefer Table-Driven Testing: When writing tests. -- Always use Early Returns: Favor early returns to simplify logic and avoid deep nesting with if-else structures. -- Always prefer switch statements over if-else chains: Use switch statements for cleaner and more readable code when checking multiple conditions. -- Always run `task generate` before committing code to ensure all generated files are up-to-date. -- Always run `task lint` before committing code to ensure it adheres to the project's linting rules. -- Always run `task build` to verify compilation after making changes. -- Always run `task test` before committing code to ensure all tests pass. -- Always search for the simplest solution first before considering more complex alternatives. -- Always prefer type safety over dynamic typing: Use strong typing and interfaces to ensure type safety and reduce runtime errors. -- When possible code to an interface so it's easier to mock in tests. -- When writing tests, each test case should have it's own isolated mock server mock dependecies so it's easier to understand and maintain. - -## Development Workflow - -### Configuration Changes - -When adding new configuration fields: - -2. Run `task generate` to regenerate all configuration-related files -3. Run `task lint` to ensure code quality -4. Run `task build` to verify successful compilation -5. Run `task test` to ensure all tests pass - -## Available Tools and MCPs - -- context7 - Helps by finding the latest updates, features, or best practices of a library relevant to the task at hand. - -## Related Repositories - -- [Inference Gateway](https://github.com/inference-gateway) - - [Inference Gateway UI](https://github.com/inference-gateway/ui) - - [Go SDK](https://github.com/inference-gateway/go-sdk) - - [Rust SDK](https://github.com/inference-gateway/rust-sdk) - - [TypeScript SDK](https://github.com/inference-gateway/typescript-sdk) - - [Python SDK](https://github.com/inference-gateway/python-sdk) - - [A2A ADK](https://github.com/inference-gateway/a2a) - - [Documentation](https://github.com/inference-gateway/docs) diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 713be4f..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,173 +0,0 @@ -# CLAUDE.md - -This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. - -## Project Overview - -A2A Debugger is a command-line debugging tool for A2A (Agent-to-Agent) servers. It's built in Go using the Cobra CLI framework and integrates with the Inference Gateway A2A ecosystem for testing connections, managing tasks, viewing conversation histories, and monitoring streaming responses. - -## Development Commands - -### Core Development Workflow - -```bash -# Generate Go code from A2A schema (always run before commit) -task generate - -# Run linting (required before commit) -task lint - -# Build the project -task build - -# Build for development (no version info) -task build:dev - -# Run tests -task test - -# Run tests with coverage -task test:coverage - -# Clean build artifacts -task clean -``` - -### Schema and Dependencies - -```bash -# Download latest A2A schema -task a2a:download:schema - -# Clean up Go module dependencies -task tidy -``` - -### Installation - -```bash -# Install locally -task install - -# Uninstall -task uninstall -``` - -### Docker - -```bash -# Build Docker image with version info -task build:docker -``` - -## Code Architecture - -### Project Structure - -- `main.go`: Entry point, passes version info to CLI -- `cli/cli.go`: Main CLI implementation using Cobra framework -- `a2a/`: A2A protocol types and schema - - `generated_types.go`: Auto-generated from A2A JSON-RPC schema - - `schema.yaml`: Official A2A schema (downloaded from inference-gateway/schemas) - -### Key Components - -#### CLI Architecture (cli/cli.go) - -- **Root Command**: Main `a2a` command with global flags -- **Namespace Commands**: - - `config`: Configuration management (set/get/list) - - `tasks`: Task operations (list/get/history/submit/submit-streaming) - - Standalone: `connect`, `agent-card`, `version` - -#### Configuration System - -- Uses Viper for configuration management -- Config file: `~/.a2a.yaml` -- Environment variable support with automatic binding -- Global flags: `--server-url`, `--timeout`, `--debug`, `--insecure`, `--config` - -#### A2A Client Integration - -- Uses `github.com/inference-gateway/a2a/adk/client` for server communication -- Lazy initialization via `ensureA2AClient()` -- Error handling with user-friendly messages for MethodNotFoundError (-32601) -- Structured logging with Zap - -#### Task Management - -- **List Tasks**: Filter by state, context-id, with pagination -- **Get Task**: Detailed task info with optional history -- **Submit Task**: Send messages to A2A server -- **Submit Streaming**: Real-time streaming with event processing -- **History**: Conversation history by context ID - -#### Streaming Support - -- Event channel-based streaming architecture -- Event types: `status-update`, `artifact-update` -- Raw mode for debugging protocol compliance -- Graceful handling of streaming responses - -### Dependencies - -- **CLI Framework**: `github.com/spf13/cobra` + `github.com/spf13/viper` -- **A2A SDK**: `github.com/inference-gateway/a2a` -- **Logging**: `go.uber.org/zap` -- **Go Version**: 1.25+ - -## Development Guidelines - -### Code Generation - -- Always run `task generate` before committing to update generated types -- Generated files have `generated_` prefix - never modify manually -- Schema updates require downloading latest from inference-gateway/schemas - -### Testing Strategy - -- Use table-driven testing patterns -- Each test case should have isolated mock servers -- Early returns over deep nesting -- Prefer switch statements over if-else chains - -### Error Handling - -- Custom error handling for A2A protocol errors -- User-friendly messages for common errors (e.g., MethodNotFoundError) -- Structured logging for debugging - -### Type Safety - -- Code to interfaces for easier mocking -- Strong typing over dynamic typing -- Use generated types from A2A schema - -### Pre-commit Workflow - -1. `task generate` - Update generated files -2. `task lint` - Code quality checks -3. `task build` - Verify compilation -4. `task test` - Ensure tests pass - -## Configuration - -### Default Configuration - -```yaml -server-url: http://localhost:8080 -timeout: 30s -debug: false -insecure: false -``` - -### Environment Variables - -All configuration keys can be set via environment variables (automatic Viper binding). - -## Related Repositories - -- [Inference Gateway](https://github.com/inference-gateway) -- [A2A ADK](https://github.com/inference-gateway/a2a) - Agent Development Kit -- [Go SDK](https://github.com/inference-gateway/go-sdk) -- [Schemas](https://github.com/inference-gateway/schemas) - A2A protocol schemas From 68380d9431de61957ef3772570e34cdb924d7f86 Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:47:55 +0200 Subject: [PATCH 7/9] chore: Add claude-code package details to manifest files Signed-off-by: Eden Reich --- .flox/env/manifest.lock | 124 ++++++++++++++++++++++++++++++++++++++++ .flox/env/manifest.toml | 3 + 2 files changed, 127 insertions(+) diff --git a/.flox/env/manifest.lock b/.flox/env/manifest.lock index 0213222..21f2a7c 100644 --- a/.flox/env/manifest.lock +++ b/.flox/env/manifest.lock @@ -3,6 +3,10 @@ "manifest": { "version": 1, "install": { + "claude-code": { + "pkg-path": "claude-code", + "version": "^2.0.1" + }, "go": { "pkg-path": "go", "version": "^1.25" @@ -18,6 +22,126 @@ "options": {} }, "packages": [ + { + "attr_path": "claude-code", + "broken": false, + "derivation": "/nix/store/f3yv1ga4r9hl67pn75a1l63i5g27670a-claude-code-2.0.1.drv", + "description": "Agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster", + "install_id": "claude-code", + "license": "Unfree", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "claude-code-2.0.1", + "pname": "claude-code", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T04:40:08.767056Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": true, + "version": "2.0.1", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/ipi2giva57qs24pcicrb1wp38lggbg72-claude-code-2.0.1" + }, + "system": "aarch64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "claude-code", + "broken": false, + "derivation": "/nix/store/x522nb7kzqgmjjghjdxif0s6r9m7fwki-claude-code-2.0.1.drv", + "description": "Agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster", + "install_id": "claude-code", + "license": "Unfree", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "claude-code-2.0.1", + "pname": "claude-code", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T04:56:38.363718Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": true, + "version": "2.0.1", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/fy9ngf85a96l7ljc2q1427ahc44qiw1g-claude-code-2.0.1" + }, + "system": "aarch64-linux", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "claude-code", + "broken": false, + "derivation": "/nix/store/csqwzfwqc1nwd770d63rv06b06sgmmbn-claude-code-2.0.1.drv", + "description": "Agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster", + "install_id": "claude-code", + "license": "Unfree", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "claude-code-2.0.1", + "pname": "claude-code", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T05:12:15.436552Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": true, + "version": "2.0.1", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/036ybyhzibr2mqw2ry1zc79qj1rjzjaj-claude-code-2.0.1" + }, + "system": "x86_64-darwin", + "group": "toplevel", + "priority": 5 + }, + { + "attr_path": "claude-code", + "broken": false, + "derivation": "/nix/store/i32jl01vvyvi7sd2x9lkzfc7q5xz1457-claude-code-2.0.1.drv", + "description": "Agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster", + "install_id": "claude-code", + "license": "Unfree", + "locked_url": "https://github.com/flox/nixpkgs?rev=7df7ff7d8e00218376575f0acdcc5d66741351ee", + "name": "claude-code-2.0.1", + "pname": "claude-code", + "rev": "7df7ff7d8e00218376575f0acdcc5d66741351ee", + "rev_count": 870157, + "rev_date": "2025-10-02T04:57:58Z", + "scrape_date": "2025-10-03T05:27:31.798081Z", + "stabilities": [ + "staging", + "unstable" + ], + "unfree": true, + "version": "2.0.1", + "outputs_to_install": [ + "out" + ], + "outputs": { + "out": "/nix/store/s7gl3s5wim61yyin8kv3chp3v3iak7dj-claude-code-2.0.1" + }, + "system": "x86_64-linux", + "group": "toplevel", + "priority": 5 + }, { "attr_path": "go", "broken": false, diff --git a/.flox/env/manifest.toml b/.flox/env/manifest.toml index 71b8604..f830d42 100644 --- a/.flox/env/manifest.toml +++ b/.flox/env/manifest.toml @@ -7,6 +7,9 @@ go.version = "^1.25" go-task.pkg-path = "go-task" go-task.version = "^3.45.4" +claude-code.pkg-path = "claude-code" +claude-code.version = "^2.0.1" + [hook] on-activate = """ export GOENV="$FLOX_ENV_CACHE/goenv" From b618745317178ed4725f3896bb479302e33f3930 Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:50:43 +0200 Subject: [PATCH 8/9] docs: Add CLAUDE.md for project guidance and CLI usage instructions Signed-off-by: Eden Reich --- CLAUDE.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..30a398d --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,141 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +A2A Debugger is a CLI tool for debugging and monitoring A2A (Agent-to-Agent) servers. It's built with Go and uses the Cobra framework for command-line interface, with Viper for configuration management. + +**Core Dependencies:** +- `github.com/inference-gateway/adk` - The A2A Agent Development Kit client library +- `github.com/spf13/cobra` - CLI framework +- `github.com/spf13/viper` - Configuration management +- `go.uber.org/zap` - Structured logging + +## Architecture + +### Code Generation + +The `a2a/generated_types.go` file is **auto-generated** from the A2A JSON-RPC schema and should **NEVER** be edited manually. To regenerate: + +1. Download latest schema: `task a2a:download:schema` +2. Generate types: `task generate` + +The generator reads `a2a/schema.yaml` and produces Go types for the A2A protocol. + +### CLI Command Structure + +All CLI commands are implemented in a **single file**: `cli/cli.go` (~806 lines). The command structure is namespace-based: + +- **Config namespace** (`a2a config`): Configuration management (set, get, list) +- **Tasks namespace** (`a2a tasks`): Task operations (list, get, history, submit, submit-streaming) +- **Server commands**: `connect`, `agent-card`, `version` + +Key architectural patterns: +- `ensureA2AClient()` - Lazy initialization of A2A client +- `handleA2AError()` - Centralized error handling for method-not-found errors +- `formatOutput()` / `printFormatted()` - Support for YAML (default) and JSON output formats + +### Entry Point + +`main.go` is minimal - it just passes version info to `cli.Execute()`. + +## Common Commands + +### Development Workflow + +```bash +# Generate code from schema (required after schema updates) +task generate + +# Run linting +task lint + +# Build with version info +task build + +# Quick dev build (no version info) +task build:dev + +# Run tests +task test + +# Run tests with coverage +task test:coverage + +# Clean build artifacts +task clean + +# Tidy dependencies +task tidy +``` + +### Testing the CLI + +```bash +# Run the built binary +./dist/a2a --help + +# Test with local A2A server (example environment) +cd example +docker compose up -d +docker compose run --rm a2a-debugger connect +``` + +### Installation + +```bash +# Install locally +task install + +# Uninstall +task uninstall +``` + +## Configuration + +- Default config location: `~/.a2a.yaml` +- Environment variables are auto-loaded via Viper +- All flags can be set in config file or via CLI flags + +Config file format: +```yaml +server-url: http://localhost:8080 +timeout: 30s +debug: false +insecure: false +output: yaml # or json +``` + +## CI/CD Pipeline + +The CI workflow (`task generate` → `task tidy` → dirty check → `task lint` → `task build` → `task test`) ensures: +1. Generated code is up-to-date +2. Dependencies are tidy +3. No uncommitted changes +4. Code passes linting +5. Build succeeds +6. Tests pass + +## Adding New Commands + +When adding commands to `cli/cli.go`: +1. Define the command with Cobra +2. Use `ensureA2AClient()` before making A2A calls +3. Use `handleA2AError()` for error handling +4. Use `printFormatted()` for structured output +5. Register the command in `init()` function +6. Add flags if needed (global flags are on `rootCmd`, command-specific on the command itself) + +## Running Tests + +Single test: `go test ./cli -run TestSpecificFunction` +All tests: `task test` +Coverage: `task test:coverage` + +## Docker Build + +```bash +# Build Docker image with version info +task build:docker +``` From b6b307649b771bf974dacf5437337b1d1575c1ee Mon Sep 17 00:00:00 2001 From: Eden Reich Date: Sun, 5 Oct 2025 16:52:42 +0200 Subject: [PATCH 9/9] docs: Add improved Copilot instructions for project setup and usage Signed-off-by: Eden Reich --- .github/copilot-instructions.md | 141 ++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 .github/copilot-instructions.md diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..9d951e6 --- /dev/null +++ b/.github/copilot-instructions.md @@ -0,0 +1,141 @@ +# copilot-instructions.md + +This file provides guidance to Copilot when working with code in this repository. + +## Project Overview + +A2A Debugger is a CLI tool for debugging and monitoring A2A (Agent-to-Agent) servers. It's built with Go and uses the Cobra framework for command-line interface, with Viper for configuration management. + +**Core Dependencies:** +- `github.com/inference-gateway/adk` - The A2A Agent Development Kit client library +- `github.com/spf13/cobra` - CLI framework +- `github.com/spf13/viper` - Configuration management +- `go.uber.org/zap` - Structured logging + +## Architecture + +### Code Generation + +The `a2a/generated_types.go` file is **auto-generated** from the A2A JSON-RPC schema and should **NEVER** be edited manually. To regenerate: + +1. Download latest schema: `task a2a:download:schema` +2. Generate types: `task generate` + +The generator reads `a2a/schema.yaml` and produces Go types for the A2A protocol. + +### CLI Command Structure + +All CLI commands are implemented in a **single file**: `cli/cli.go` (~806 lines). The command structure is namespace-based: + +- **Config namespace** (`a2a config`): Configuration management (set, get, list) +- **Tasks namespace** (`a2a tasks`): Task operations (list, get, history, submit, submit-streaming) +- **Server commands**: `connect`, `agent-card`, `version` + +Key architectural patterns: +- `ensureA2AClient()` - Lazy initialization of A2A client +- `handleA2AError()` - Centralized error handling for method-not-found errors +- `formatOutput()` / `printFormatted()` - Support for YAML (default) and JSON output formats + +### Entry Point + +`main.go` is minimal - it just passes version info to `cli.Execute()`. + +## Common Commands + +### Development Workflow + +```bash +# Generate code from schema (required after schema updates) +task generate + +# Run linting +task lint + +# Build with version info +task build + +# Quick dev build (no version info) +task build:dev + +# Run tests +task test + +# Run tests with coverage +task test:coverage + +# Clean build artifacts +task clean + +# Tidy dependencies +task tidy +``` + +### Testing the CLI + +```bash +# Run the built binary +./dist/a2a --help + +# Test with local A2A server (example environment) +cd example +docker compose up -d +docker compose run --rm a2a-debugger connect +``` + +### Installation + +```bash +# Install locally +task install + +# Uninstall +task uninstall +``` + +## Configuration + +- Default config location: `~/.a2a.yaml` +- Environment variables are auto-loaded via Viper +- All flags can be set in config file or via CLI flags + +Config file format: +```yaml +server-url: http://localhost:8080 +timeout: 30s +debug: false +insecure: false +output: yaml # or json +``` + +## CI/CD Pipeline + +The CI workflow (`task generate` → `task tidy` → dirty check → `task lint` → `task build` → `task test`) ensures: +1. Generated code is up-to-date +2. Dependencies are tidy +3. No uncommitted changes +4. Code passes linting +5. Build succeeds +6. Tests pass + +## Adding New Commands + +When adding commands to `cli/cli.go`: +1. Define the command with Cobra +2. Use `ensureA2AClient()` before making A2A calls +3. Use `handleA2AError()` for error handling +4. Use `printFormatted()` for structured output +5. Register the command in `init()` function +6. Add flags if needed (global flags are on `rootCmd`, command-specific on the command itself) + +## Running Tests + +Single test: `go test ./cli -run TestSpecificFunction` +All tests: `task test` +Coverage: `task test:coverage` + +## Docker Build + +```bash +# Build Docker image with version info +task build:docker +```