Files
goclaw/internal/store/provider_store.go
T
Goon 5e2fa395c7 feat(providers): add ACP provider for external coding agents (#190)
* feat(providers): add ACP provider for orchestrating external coding agents (#189)

Implement native Go ACP (Agent Client Protocol) client as a new Provider.
Enables GoClaw to orchestrate any ACP-compatible agent (Claude Code, Codex
CLI, Gemini CLI) as a subprocess via JSON-RPC 2.0 over stdio.

- Add bidirectional JSON-RPC 2.0 transport over stdio pipes
- Add subprocess process pool with idle TTL reaping and crash recovery
- Add ACP session lifecycle (initialize, session/new, session/prompt)
- Add tool bridge for agent-initiated fs/terminal/permission requests
- Add workspace sandboxing, shell deny patterns, and env var filtering
- Wire config-based and DB-based provider registration paths
- Export DefaultDenyPatterns from tools package for reuse

* feat(providers): add changelog entry for ACP provider integration

* fix(tools): prevent workspace traversal bypass via /tmp/ fallback in resolveMediaPath

Reject paths containing ".." in the isInTempDir fallback to prevent
workspace escape where traversal path still resolves inside /tmp/.

* fix(tools): block workspace-sibling paths in resolveMediaPath /tmp/ fallback

When workspace is inside /tmp/, traversal paths like workspace/../X
resolve to /tmp/ siblings that pass isInTempDir. Reject paths inside
the workspace parent directory to prevent this escape.

* feat(providers): add ACP provider web UI and live reload via pubsub

Web UI for creating/editing ACP providers with dedicated form fields
(binary, args, idle TTL, permission mode, work directory). ACP providers
now update immediately without gateway restart via cache invalidation
pubsub pattern.

Frontend:
- New ACPSection form component with i18n (en/vi/zh)
- Provider form dialog integration with ACP state management
- ACP type badge on providers list page
- Settings field added to provider TypeScript types

Backend:
- ACP models handler (claude/codex/gemini) without API key requirement
- Binary path validation + LookPath verification in verify handler
- Provider CRUD emits cache.invalidate events via msgBus
- Subscriber in gateway_managed.go re-registers ACP providers from DB
- ACP core improvements from code review (helpers, jsonrpc, process,
  terminal, tool_bridge)

---------

Co-authored-by: viettranx <viettranx@gmail.com>
2026-03-14 16:16:08 +07:00

83 lines
2.8 KiB
Go

package store
import (
"context"
"encoding/json"
"github.com/google/uuid"
)
// Provider type constants.
const (
ProviderAnthropicNative = "anthropic_native"
ProviderOpenAICompat = "openai_compat"
ProviderGeminiNative = "gemini_native"
ProviderOpenRouter = "openrouter"
ProviderGroq = "groq"
ProviderDeepSeek = "deepseek"
ProviderMistral = "mistral"
ProviderXAI = "xai"
ProviderMiniMax = "minimax_native"
ProviderCohere = "cohere"
ProviderPerplexity = "perplexity"
ProviderDashScope = "dashscope"
ProviderBailian = "bailian"
ProviderChatGPTOAuth = "chatgpt_oauth"
ProviderClaudeCLI = "claude_cli"
ProviderSuno = "suno"
ProviderYesScale = "yescale"
ProviderZai = "zai"
ProviderZaiCoding = "zai_coding"
ProviderOllama = "ollama" // local or self-hosted Ollama (no API key)
ProviderOllamaCloud = "ollama_cloud" // Ollama Cloud (Bearer token required)
ProviderACP = "acp" // ACP (Agent Client Protocol) agent subprocess
)
// ValidProviderTypes lists all accepted provider_type values.
var ValidProviderTypes = map[string]bool{
ProviderAnthropicNative: true,
ProviderOpenAICompat: true,
ProviderGeminiNative: true,
ProviderOpenRouter: true,
ProviderGroq: true,
ProviderDeepSeek: true,
ProviderMistral: true,
ProviderXAI: true,
ProviderMiniMax: true,
ProviderCohere: true,
ProviderPerplexity: true,
ProviderDashScope: true,
ProviderBailian: true,
ProviderChatGPTOAuth: true,
ProviderClaudeCLI: true,
ProviderSuno: true,
ProviderYesScale: true,
ProviderZai: true,
ProviderZaiCoding: true,
ProviderOllama: true,
ProviderOllamaCloud: true,
ProviderACP: true,
}
// LLMProviderData represents an LLM provider configuration.
type LLMProviderData struct {
BaseModel
Name string `json:"name"`
DisplayName string `json:"display_name,omitempty"`
ProviderType string `json:"provider_type"`
APIBase string `json:"api_base,omitempty"`
APIKey string `json:"api_key,omitempty"`
Enabled bool `json:"enabled"`
Settings json.RawMessage `json:"settings,omitempty"`
}
// ProviderStore manages LLM providers.
type ProviderStore interface {
CreateProvider(ctx context.Context, p *LLMProviderData) error
GetProvider(ctx context.Context, id uuid.UUID) (*LLMProviderData, error)
GetProviderByName(ctx context.Context, name string) (*LLMProviderData, error)
ListProviders(ctx context.Context) ([]LLMProviderData, error)
UpdateProvider(ctx context.Context, id uuid.UUID, updates map[string]any) error
DeleteProvider(ctx context.Context, id uuid.UUID) error
}