diff --git a/README.md b/README.md index 6bfb02a..e96e420 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # AgentAPI -Control [Claude Code](https://github.com/anthropics/claude-code), [Goose](https://github.com/block/goose), [Aider](https://github.com/Aider-AI/aider), [Gemini](https://github.com/google-gemini/gemini-cli), [Sourcegraph Amp](https://github.com/sourcegraph/amp-cli), [Codex](https://github.com/openai/codex), [Auggie](https://docs.augmentcode.com/cli/overview), and [Cursor CLI](https://cursor.com/en/cli) with an HTTP API. +Control [Claude Code](https://github.com/anthropics/claude-code), [AmazonQ](https://aws.amazon.com/developer/learning/q-developer-cli/), [Goose](https://github.com/block/goose), [Aider](https://github.com/Aider-AI/aider), [Gemini](https://github.com/google-gemini/gemini-cli), [Sourcegraph Amp](https://github.com/sourcegraph/amp-cli), [Codex](https://github.com/openai/codex), [Auggie](https://docs.augmentcode.com/cli/overview), and [Cursor CLI](https://cursor.com/en/cli) with an HTTP API. ![agentapi-chat](https://github.com/user-attachments/assets/57032c9f-4146-4b66-b219-09e38ab7690d) diff --git a/cmd/server/server.go b/cmd/server/server.go index 912ab66..8541e76 100644 --- a/cmd/server/server.go +++ b/cmd/server/server.go @@ -32,6 +32,8 @@ const ( AgentTypeCursorAgent AgentType = msgfmt.AgentTypeCursorAgent AgentTypeCursor AgentType = msgfmt.AgentTypeCursor AgentTypeAuggie AgentType = msgfmt.AgentTypeAuggie + AgentTypeAmazonQ AgentType = msgfmt.AgentTypeAmazonQ + AgentTypeQ AgentType = msgfmt.AgentTypeQ AgentTypeCustom AgentType = msgfmt.AgentTypeCustom ) @@ -46,6 +48,8 @@ var agentTypeMap = map[AgentType]bool{ AgentTypeCursorAgent: true, AgentTypeCursor: true, AgentTypeAuggie: true, + AgentTypeAmazonQ: true, + AgentTypeQ: true, AgentTypeCustom: true, } diff --git a/cmd/server/server_test.go b/cmd/server/server_test.go index f61d2c0..75b2417 100644 --- a/cmd/server/server_test.go +++ b/cmd/server/server_test.go @@ -57,6 +57,16 @@ func TestParseAgentType(t *testing.T) { agentTypeVar: "", want: AgentTypeCursor, }, + { + firstArg: "amazonq", + agentTypeVar: "", + want: AgentTypeAmazonQ, + }, + { + firstArg: "q", + agentTypeVar: "", + want: AgentTypeQ, + }, { firstArg: "auggie", agentTypeVar: "", @@ -97,6 +107,16 @@ func TestParseAgentType(t *testing.T) { agentTypeVar: "gemini", want: AgentTypeGemini, }, + { + firstArg: "claude", + agentTypeVar: "amazonq", + want: AgentTypeAmazonQ, + }, + { + firstArg: "claude", + agentTypeVar: "q", + want: AgentTypeQ, + }, { firstArg: "claude", agentTypeVar: "cursor-agent", diff --git a/lib/msgfmt/msgfmt.go b/lib/msgfmt/msgfmt.go index 3c88200..cca29ac 100644 --- a/lib/msgfmt/msgfmt.go +++ b/lib/msgfmt/msgfmt.go @@ -234,6 +234,8 @@ const ( AgentTypeCursorAgent AgentType = "cursor-agent" AgentTypeCursor AgentType = "cursor" AgentTypeAuggie AgentType = "auggie" + AgentTypeAmazonQ AgentType = "amazonq" + AgentTypeQ AgentType = "q" AgentTypeCustom AgentType = "custom" ) @@ -271,6 +273,10 @@ func FormatAgentMessage(agentType AgentType, message string, userInput string) s return formatGenericMessage(message, userInput, agentType) case AgentTypeAuggie: return formatGenericMessage(message, userInput, agentType) + case AgentTypeAmazonQ: + return formatGenericMessage(message, userInput, agentType) + case AgentTypeQ: + return formatGenericMessage(message, userInput, agentType) case AgentTypeCustom: return formatGenericMessage(message, userInput, agentType) default: diff --git a/lib/msgfmt/msgfmt_test.go b/lib/msgfmt/msgfmt_test.go index c29d6b9..ebf1bc8 100644 --- a/lib/msgfmt/msgfmt_test.go +++ b/lib/msgfmt/msgfmt_test.go @@ -218,7 +218,7 @@ func TestTrimEmptyLines(t *testing.T) { func TestFormatAgentMessage(t *testing.T) { dir := "testdata/format" - agentTypes := []AgentType{AgentTypeClaude, AgentTypeGoose, AgentTypeAider, AgentTypeGemini, AgentTypeAmp, AgentTypeCodex, AgentTypeCursorAgent, AgentTypeCursor, AgentTypeAuggie, AgentTypeCustom} + agentTypes := []AgentType{AgentTypeClaude, AgentTypeGoose, AgentTypeAider, AgentTypeGemini, AgentTypeAmp, AgentTypeCodex, AgentTypeCursorAgent, AgentTypeCursor, AgentTypeAuggie, AgentTypeQ, AgentTypeCustom} for _, agentType := range agentTypes { t.Run(string(agentType), func(t *testing.T) { cases, err := testdataDir.ReadDir(path.Join(dir, string(agentType))) diff --git a/lib/msgfmt/testdata/format/q/confirmation_box/expected.txt b/lib/msgfmt/testdata/format/q/confirmation_box/expected.txt new file mode 100644 index 0000000..be32e1d --- /dev/null +++ b/lib/msgfmt/testdata/format/q/confirmation_box/expected.txt @@ -0,0 +1,13 @@ +🛠️ Using tool: coder_report_task from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "summary": "Checking current directory to identify repository", + ⋮ "link": "", + ⋮ "state": "working" + ⋮ } + ⋮ } + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/confirmation_box/msg.txt b/lib/msgfmt/testdata/format/q/confirmation_box/msg.txt new file mode 100644 index 0000000..71cda2c --- /dev/null +++ b/lib/msgfmt/testdata/format/q/confirmation_box/msg.txt @@ -0,0 +1,20 @@ +> what repo is this ? + + + + +🛠️ Using tool: coder_report_task from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "summary": "Checking current directory to identify repository", + ⋮ "link": "", + ⋮ "state": "working" + ⋮ } + ⋮ } + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/confirmation_box/user.txt b/lib/msgfmt/testdata/format/q/confirmation_box/user.txt new file mode 100644 index 0000000..4cce2f7 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/confirmation_box/user.txt @@ -0,0 +1 @@ +what repo is this ? \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/first_message/expected.txt b/lib/msgfmt/testdata/format/q/first_message/expected.txt new file mode 100644 index 0000000..464886e --- /dev/null +++ b/lib/msgfmt/testdata/format/q/first_message/expected.txt @@ -0,0 +1,12 @@ +✓ coder loaded in 0.03 s + +Welcome to Amazon Q! + +💡 Run /prompts to learn how to build & run repeatable workflows + +/help all commands +ctrl + j new lines +ctrl + s fuzzy search + + +🤖 You are chatting with claude-sonnet-4 \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/first_message/msg.txt b/lib/msgfmt/testdata/format/q/first_message/msg.txt new file mode 100644 index 0000000..4f43700 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/first_message/msg.txt @@ -0,0 +1,14 @@ +✓ coder loaded in 0.03 s + +Welcome to Amazon Q! + +💡 Run /prompts to learn how to build & run repeatable workflows + +/help all commands +ctrl + j new lines +ctrl + s fuzzy search + + +🤖 You are chatting with claude-sonnet-4 + +> \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/first_message/user.txt b/lib/msgfmt/testdata/format/q/first_message/user.txt new file mode 100644 index 0000000..e69de29 diff --git a/lib/msgfmt/testdata/format/q/multi-line-input/expected.txt b/lib/msgfmt/testdata/format/q/multi-line-input/expected.txt new file mode 100644 index 0000000..112f6f9 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/multi-line-input/expected.txt @@ -0,0 +1,62 @@ +🛠️ Using tool: coder_report_task from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "summary": "Searching for the formatCodexMessage function in the codebase", + ⋮ "link": "", + ⋮ "state": "working" + ⋮ } + ⋮ } + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> y + + + ⋮ + ● Completed in 0.0s + + + + + +Tool validation failed: +Failed to validate tool parameters: Path is not a file: + + + +🛠️ Using tool: fs_read (trusted) + ⋮ + ● Reading directory: /Users/jkmr/Documents/work/agentapi with maximum depth of 0 + ✓ Successfully read directory /Users/jkmr/Documents/work/agentapi (29 entries) + + ⋮ + ● Completed in 0.1s + + + + + +🛠️ Using tool: execute_bash + ⋮ + ● I will run the following shell command: +find /Users/jkmr/Documents/work/agentapi -name "*.go" -exec grep -l "formatCodexMessage" {} \; + ⋮ + ↳ Purpose: Search for Go files containing formatCodexMessage function + + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> y + +/Users/jkmr/Documents/work/agentapi/lib/msgfmt/msgfmt.go + + ⋮ + ● Completed in 0.449s + + +> The formatCodexMessage function is located in the file: + +/Users/jkmr/Documents/work/agentapi/lib/msgfmt/msgfmt.go \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/multi-line-input/msg.txt b/lib/msgfmt/testdata/format/q/multi-line-input/msg.txt new file mode 100644 index 0000000..a004f51 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/multi-line-input/msg.txt @@ -0,0 +1,75 @@ +> Which file has this snippet +func formatCodexMessage(message string, userInput string) string { + message = RemoveUserInput(message, userInput) + message = removeCodexInputBox(message) + message = trimEmptyLines(message) + return message +} + + + + +🛠️ Using tool: coder_report_task from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "summary": "Searching for the formatCodexMessage function in the codebase", + ⋮ "link": "", + ⋮ "state": "working" + ⋮ } + ⋮ } + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> y + + + ⋮ + ● Completed in 0.0s + + + + + +Tool validation failed: +Failed to validate tool parameters: Path is not a file: + + + +🛠️ Using tool: fs_read (trusted) + ⋮ + ● Reading directory: /Users/jkmr/Documents/work/agentapi with maximum depth of 0 + ✓ Successfully read directory /Users/jkmr/Documents/work/agentapi (29 entries) + + ⋮ + ● Completed in 0.1s + + + + + +🛠️ Using tool: execute_bash + ⋮ + ● I will run the following shell command: +find /Users/jkmr/Documents/work/agentapi -name "*.go" -exec grep -l "formatCodexMessage" {} \; + ⋮ + ↳ Purpose: Search for Go files containing formatCodexMessage function + + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> y + +/Users/jkmr/Documents/work/agentapi/lib/msgfmt/msgfmt.go + + ⋮ + ● Completed in 0.449s + + +> The formatCodexMessage function is located in the file: + +/Users/jkmr/Documents/work/agentapi/lib/msgfmt/msgfmt.go + +> \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/multi-line-input/user.txt b/lib/msgfmt/testdata/format/q/multi-line-input/user.txt new file mode 100644 index 0000000..e85fa2a --- /dev/null +++ b/lib/msgfmt/testdata/format/q/multi-line-input/user.txt @@ -0,0 +1,7 @@ +Which file has this snippet +func formatCodexMessage(message string, userInput string) string { + message = RemoveUserInput(message, userInput) + message = removeCodexInputBox(message) + message = trimEmptyLines(message) + return message +} \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/second_message/expected.txt b/lib/msgfmt/testdata/format/q/second_message/expected.txt new file mode 100644 index 0000000..57def31 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/second_message/expected.txt @@ -0,0 +1,59 @@ +🛠️ Using tool: coder_report_task from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "summary": "Checking for untracked files in the repository", + ⋮ "link": "/Users/jkmr/Documents/work/agentapi", + ⋮ "state": "working" + ⋮ } + ⋮ } + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> t + + + ⋮ + ● Completed in 0.0s + + + + + +🛠️ Using tool: execute_bash + ⋮ + ● I will run the following shell command: +git status --porcelain | grep '^??' | wc -l + ⋮ + ↳ Purpose: Count untracked files using git status + + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> t + + 8 + + ⋮ + ● Completed in 0.24s + + +> There are 8 untracked files in the repository. + + +🛠️ Using tool: coder_report_task (trusted) from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "link": "/Users/jkmr/Documents/work/agentapi", + ⋮ "summary": "Found 8 untracked files in the repository", + ⋮ "state": "idle" + ⋮ } + ⋮ } + + ⋮ + ● Completed in 0.0s \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/second_message/msg.txt b/lib/msgfmt/testdata/format/q/second_message/msg.txt new file mode 100644 index 0000000..e02a08b --- /dev/null +++ b/lib/msgfmt/testdata/format/q/second_message/msg.txt @@ -0,0 +1,69 @@ +> How many untracked files are there? + + + + +🛠️ Using tool: coder_report_task from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "summary": "Checking for untracked files in the repository", + ⋮ "link": "/Users/jkmr/Documents/work/agentapi", + ⋮ "state": "working" + ⋮ } + ⋮ } + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> t + + + ⋮ + ● Completed in 0.0s + + + + + +🛠️ Using tool: execute_bash + ⋮ + ● I will run the following shell command: +git status --porcelain | grep '^??' | wc -l + ⋮ + ↳ Purpose: Count untracked files using git status + + +Allow this action? Use 't' to trust (always allow) this tool for the session. [y/n/t]: + +> t + + 8 + + ⋮ + ● Completed in 0.24s + + +> There are 8 untracked files in the repository. + + +🛠️ Using tool: coder_report_task (trusted) from mcp server coder + ⋮ + ● Running coder_report_task with the param: + ⋮ { + ⋮ "name": "coder_report_task", + ⋮ "arguments": { + ⋮ "link": "/Users/jkmr/Documents/work/agentapi", + ⋮ "summary": "Found 8 untracked files in the repository", + ⋮ "state": "idle" + ⋮ } + ⋮ } + + ⋮ + ● Completed in 0.0s + + + + +> \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/second_message/user.txt b/lib/msgfmt/testdata/format/q/second_message/user.txt new file mode 100644 index 0000000..f739c91 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/second_message/user.txt @@ -0,0 +1 @@ +How many untracked files are there? \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/thinking/expected.txt b/lib/msgfmt/testdata/format/q/thinking/expected.txt new file mode 100644 index 0000000..64c5b8a --- /dev/null +++ b/lib/msgfmt/testdata/format/q/thinking/expected.txt @@ -0,0 +1 @@ +⠋ Thinking... \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/thinking/msg.txt b/lib/msgfmt/testdata/format/q/thinking/msg.txt new file mode 100644 index 0000000..71b55de --- /dev/null +++ b/lib/msgfmt/testdata/format/q/thinking/msg.txt @@ -0,0 +1,3 @@ +> How many untracked files are there? + +⠋ Thinking... \ No newline at end of file diff --git a/lib/msgfmt/testdata/format/q/thinking/user.txt b/lib/msgfmt/testdata/format/q/thinking/user.txt new file mode 100644 index 0000000..f739c91 --- /dev/null +++ b/lib/msgfmt/testdata/format/q/thinking/user.txt @@ -0,0 +1 @@ +How many untracked files are there? \ No newline at end of file