Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ snapshot2-*.log
schema.yaml
**/.claude/settings.local.json
out


#IDEs
.idea
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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), and [Codex](https://github.com/openai/codex) with an HTTP API.
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) and [Codex](https://github.com/openai/codex) with an HTTP API.

![agentapi-chat](https://github.com/user-attachments/assets/57032c9f-4146-4b66-b219-09e38ab7690d)

Expand Down
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
var rootCmd = &cobra.Command{
Use: "agentapi",
Short: "AgentAPI CLI",
Long: `AgentAPI - HTTP API for Claude Code, Goose, Aider, and Codex`,
Long: `AgentAPI - HTTP API for Claude Code, Goose, Aider, Gemini and Codex`,
Version: "0.2.3",
}

Expand Down
7 changes: 6 additions & 1 deletion cmd/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
AgentTypeGoose AgentType = msgfmt.AgentTypeGoose
AgentTypeAider AgentType = msgfmt.AgentTypeAider
AgentTypeCodex AgentType = msgfmt.AgentTypeCodex
AgentTypeGemini AgentType = msgfmt.AgentTypeGemini
AgentTypeCustom AgentType = msgfmt.AgentTypeCustom
)

Expand All @@ -46,6 +47,8 @@ func parseAgentType(firstArg string, agentTypeVar string) (AgentType, error) {
agentType = AgentTypeGoose
case string(AgentTypeAider):
agentType = AgentTypeAider
case string(AgentTypeGemini):
agentType = AgentTypeGemini
case string(AgentTypeCustom):
agentType = AgentTypeCustom
case string(AgentTypeCodex):
Expand All @@ -68,6 +71,8 @@ func parseAgentType(firstArg string, agentTypeVar string) (AgentType, error) {
agentType = AgentTypeAider
case string(AgentTypeCodex):
agentType = AgentTypeCodex
case string(AgentTypeGemini):
agentType = AgentTypeGemini
default:
agentType = AgentTypeCustom
}
Expand Down Expand Up @@ -137,7 +142,7 @@ func runServer(ctx context.Context, logger *slog.Logger, argsToPass []string) er
var ServerCmd = &cobra.Command{
Use: "server [agent]",
Short: "Run the server",
Long: `Run the server with the specified agent (claude, goose, aider, codex)`,
Long: `Run the server with the specified agent (claude, goose, aider, gemini, codex)`,
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
Expand Down
10 changes: 10 additions & 0 deletions cmd/server/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ func TestParseAgentType(t *testing.T) {
agentTypeVar: "",
want: AgentTypeClaude,
},
{
firstArg: "gemini",
agentTypeVar: "",
want: AgentTypeGemini,
},
{
firstArg: "goose",
agentTypeVar: "",
Expand All @@ -48,6 +53,11 @@ func TestParseAgentType(t *testing.T) {
agentTypeVar: "claude",
want: AgentTypeClaude,
},
{
firstArg: "claude",
agentTypeVar: "gemini",
want: AgentTypeGemini,
},
{
firstArg: "aider",
agentTypeVar: "claude",
Expand Down
13 changes: 12 additions & 1 deletion lib/msgfmt/msgfmt.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package msgfmt

import "strings"
import (
"strings"
)

const WhiteSpaceChars = " \t\n\r\f\v"

Expand Down Expand Up @@ -166,6 +168,12 @@ func RemoveUserInput(msgRaw string, userInputRaw string) string {
// Return the original message starting with the first line
// that doesn't contain the echoed user input.
lastUserInputLineIdx := msgRuneLineLocations[userInputEndIdx]

// In case of Gemini, the user input echoed back is wrapped in a rounded box, so we remove it.
if lastUserInputLineIdx+1 < len(msgLines) && strings.Contains(msgLines[lastUserInputLineIdx+1], "╯") && strings.Contains(msgLines[lastUserInputLineIdx+1], "╰") {
lastUserInputLineIdx += 1
}

return strings.Join(msgLines[lastUserInputLineIdx+1:], "\n")
}

Expand Down Expand Up @@ -197,6 +205,7 @@ const (
AgentTypeGoose AgentType = "goose"
AgentTypeAider AgentType = "aider"
AgentTypeCodex AgentType = "codex"
AgentTypeGemini AgentType = "gemini"
AgentTypeCustom AgentType = "custom"
)

Expand All @@ -217,6 +226,8 @@ func FormatAgentMessage(agentType AgentType, message string, userInput string) s
return formatGenericMessage(message, userInput)
case AgentTypeCodex:
return formatGenericMessage(message, userInput)
case AgentTypeGemini:
return formatGenericMessage(message, userInput)
case AgentTypeCustom:
return formatGenericMessage(message, userInput)
default:
Expand Down