feat: add Codex CLI provider for subprocess integration (#80)
* feat: add Codex CLI provider for OpenAI subprocess integration Add CodexCliProvider that wraps `codex exec --json` as a subprocess, analogous to the existing ClaudeCliProvider pattern. This enables using OpenAI's Codex CLI tool as a local LLM backend. - CodexCliProvider: subprocess wrapper parsing JSONL event stream - Credential reader for ~/.codex/auth.json with token expiry detection - Factory integration: provider "codex-cli" and auth_method "codex-cli" - Fix tilde expansion in workspace path for CLI providers - 37 unit tests covering parsing, prompt building, credentials, and mocks * fix: add tool call extraction to Codex CLI provider - Extract shared tool call parsing into tool_call_extract.go (extractToolCallsFromText, stripToolCallsFromText, findMatchingBrace) - Both ClaudeCliProvider and CodexCliProvider now share the same tool call extraction logic for PicoClaw-specific tools - Fix cache token accounting: include cached_input_tokens in total - Add 2 new tests for tool call extraction from JSONL events - Update existing tests for corrected token calculations * fix(docker): update Go version to match go.mod requirement Dockerfile used golang:1.24-alpine but go.mod requires go >= 1.25.7. This caused Docker builds to fail on all branches with: "go: go.mod requires go >= 1.25.7 (running go 1.24.13)" Update to golang:1.25-alpine to match the project requirement. * fix: handle codex CLI stderr noise without losing valid stdout Codex writes diagnostic messages to stderr (e.g. rollout errors) which cause non-zero exit codes even when valid JSONL output exists on stdout. Parse stdout first before checking exit code to avoid false errors. * style: fix gofmt formatting and update web search API in tests - Remove trailing whitespace in web.go and base_test.go - Update config_test.go and web_test.go for WebSearchToolOptions API
This commit is contained in:
@@ -240,6 +240,9 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
|
||||
}
|
||||
case "openai", "gpt":
|
||||
if cfg.Providers.OpenAI.APIKey != "" || cfg.Providers.OpenAI.AuthMethod != "" {
|
||||
if cfg.Providers.OpenAI.AuthMethod == "codex-cli" {
|
||||
return NewCodexProviderWithTokenSource("", "", CreateCodexCliTokenSource()), nil
|
||||
}
|
||||
if cfg.Providers.OpenAI.AuthMethod == "oauth" || cfg.Providers.OpenAI.AuthMethod == "token" {
|
||||
return createCodexAuthProvider()
|
||||
}
|
||||
@@ -299,11 +302,17 @@ func CreateProvider(cfg *config.Config) (LLMProvider, error) {
|
||||
}
|
||||
}
|
||||
case "claude-cli", "claudecode", "claude-code":
|
||||
workspace := cfg.Agents.Defaults.Workspace
|
||||
workspace := cfg.WorkspacePath()
|
||||
if workspace == "" {
|
||||
workspace = "."
|
||||
}
|
||||
return NewClaudeCliProvider(workspace), nil
|
||||
case "codex-cli", "codex-code":
|
||||
workspace := cfg.WorkspacePath()
|
||||
if workspace == "" {
|
||||
workspace = "."
|
||||
}
|
||||
return NewCodexCliProvider(workspace), nil
|
||||
case "deepseek":
|
||||
if cfg.Providers.DeepSeek.APIKey != "" {
|
||||
apiKey = cfg.Providers.DeepSeek.APIKey
|
||||
|
||||
Reference in New Issue
Block a user