Documentation
¶
Overview ¶
Package codexacp exposes the Codex CLI as an Agent Client Protocol agent.
Most hosts run the agent over a pair of JSON-RPC streams using Serve. Serve starts one `codex app-server` for the agent, opens one Codex thread per ACP session on it, maps ACP requests onto the app-server protocol, and streams ACP session updates back to the client. Codex inherits the adapter's environment and keeps its rollouts in its own home, so a session started over ACP can be continued natively with `codex resume` after the adapter closes.
Hosts that need durable remote resume provide WithSessionStore. The store is the durability boundary for session/list, session/load and session/resume; Codex's own rollout is the native copy an operator can continue outside ACP.
Hosts that need adapter telemetry provide OpenTelemetry providers with WithTracerProvider and WithMeterProvider; the package never configures global providers.
Index ¶
- Constants
- func Serve(ctx context.Context, input io.Reader, output io.Writer, opts ...Option) (returnErr error)
- func SetModelRequest(sessionID acp.SessionId, model string) acp.SetSessionConfigOptionRequest
- func ValidateCodexSessionMeta(meta map[string]any) error
- func WithSessionCodexOptions(options CodexOptions) wire.SessionRequestOption
- func WithSessionOutputSchema(schema map[string]any) wire.SessionRequestOption
- func WithSessionRawEvents(enabled bool) wire.SessionRequestOption
- type Agent
- func (a *Agent) Authenticate(_ context.Context, params acp.AuthenticateRequest) (acp.AuthenticateResponse, error)
- func (a *Agent) Cancel(ctx context.Context, params acp.CancelNotification) (err error)
- func (a *Agent) Close() error
- func (a *Agent) CloseSession(ctx context.Context, params acp.CloseSessionRequest) (resp acp.CloseSessionResponse, err error)
- func (a *Agent) HandleExtensionMethod(ctx context.Context, method string, params json.RawMessage) (any, error)
- func (a *Agent) Initialize(ctx context.Context, params acp.InitializeRequest) (resp acp.InitializeResponse, err error)
- func (a *Agent) ListSessions(ctx context.Context, params acp.ListSessionsRequest) (resp acp.ListSessionsResponse, err error)
- func (a *Agent) LoadSession(ctx context.Context, params acp.LoadSessionRequest) (resp acp.LoadSessionResponse, err error)
- func (a *Agent) Logout(_ context.Context, params acp.LogoutRequest) (acp.LogoutResponse, error)
- func (a *Agent) NewSession(ctx context.Context, params acp.NewSessionRequest) (resp acp.NewSessionResponse, err error)
- func (a *Agent) Prompt(ctx context.Context, params acp.PromptRequest) (resp acp.PromptResponse, err error)
- func (a *Agent) ResumeSession(ctx context.Context, params acp.ResumeSessionRequest) (resp acp.ResumeSessionResponse, err error)
- func (a *Agent) SetSessionConfigOption(ctx context.Context, params acp.SetSessionConfigOptionRequest) (resp acp.SetSessionConfigOptionResponse, err error)
- func (a *Agent) SetSessionMode(_ context.Context, params acp.SetSessionModeRequest) (acp.SetSessionModeResponse, error)
- func (a *Agent) UnstableDeleteSession(ctx context.Context, params acp.UnstableDeleteSessionRequest) (resp acp.UnstableDeleteSessionResponse, err error)
- type CodexOption
- func WithCodexApprovalPolicy(policy any) CodexOption
- func WithCodexEffort(effort string) CodexOption
- func WithCodexEnv(env map[string]string) CodexOption
- func WithCodexExtraPathDirs(dirs ...string) CodexOption
- func WithCodexModel(model string) CodexOption
- func WithCodexOutputSchema(schema map[string]any) CodexOption
- func WithCodexPersonality(personality string) CodexOption
- func WithCodexSandboxPolicy(policy any) CodexOption
- func WithCodexServiceTier(tier string) CodexOption
- type CodexOptions
- type ConcurrencyLimits
- type ImageLimits
- type Option
- func WithAgentName(name string) Option
- func WithAgentTitle(title string) Option
- func WithAgentVersion(version string) Option
- func WithCodexConfigOverrides(overrides map[string]any) Option
- func WithConcurrencyLimits(limits ConcurrencyLimits) Option
- func WithConfiguredModels(ids []string) Option
- func WithDefaultModel(model string) Option
- func WithEnv(env map[string]string) Option
- func WithExecutablePath(path string) Option
- func WithHome(path string) Option
- func WithImageLimits(limits ImageLimits) Option
- func WithInputHandoffRoot(dir string) Option
- func WithLogger(logger *slog.Logger) Option
- func WithMeterProvider(provider metric.MeterProvider) Option
- func WithScratchDir(dir string) Option
- func WithSeedFiles(files map[string]string) Option
- func WithSessionStore(store acpcore.SessionStore) Option
- func WithTextMapPropagator(propagator propagation.TextMapPropagator) Option
- func WithTracerProvider(provider trace.TracerProvider) Option
- type Options
Examples ¶
Constants ¶
const ( // RawEventMethod is the notification carrying one raw app-server event // when a session opted in through _meta.codex.rawEvent.enabled. RawEventMethod = "_codex/rawEvent" // AccountUsageMethod is the request reading the logged-in account's // rate-limit windows through the shared app-server. AccountUsageMethod = "_codex/accountUsage" // SessionStoreFormat identifies the store layout this package writes: raw // Codex rollout rows under the main subpath plus the adapter's session // record under the config subpath. SessionStoreFormat = "codex-rollout-jsonl-v1" )
Variables ¶
This section is empty.
Functions ¶
func Serve ¶
func Serve(ctx context.Context, input io.Reader, output io.Writer, opts ...Option) (returnErr error)
Serve runs an ACP agent over the provided streams. It blocks until the context is cancelled or the peer closes the connection, then closes the agent.
Example (Initialize) ¶
ExampleServe_initialize embeds the agent over a pair of pipes, the same wiring a host uses for stdio, and reads the capabilities the handshake advertises.
package main
import (
"bufio"
"context"
"encoding/json"
"fmt"
"io"
codexacp "github.com/savid/acp-go-codex"
)
func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
clientToAgentReader, clientToAgentWriter := io.Pipe()
agentToClientReader, agentToClientWriter := io.Pipe()
done := make(chan error, 1)
go func() {
done <- codexacp.Serve(ctx, clientToAgentReader, agentToClientWriter)
}()
_, _ = fmt.Fprintln(clientToAgentWriter,
`{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}`)
line, _ := bufio.NewReader(agentToClientReader).ReadString('\n')
cancel()
_ = clientToAgentWriter.Close()
<-done
var response struct {
Result struct {
AuthMethods []any `json:"authMethods"`
AgentCapabilities struct {
LoadSession bool `json:"loadSession"`
SessionCapabilities map[string]any `json:"sessionCapabilities"`
} `json:"agentCapabilities"`
} `json:"result"`
}
_ = json.Unmarshal([]byte(line), &response)
fmt.Println(len(response.Result.AuthMethods))
fmt.Println(response.Result.AgentCapabilities.LoadSession)
fmt.Println(len(response.Result.AgentCapabilities.SessionCapabilities))
}
Output: 0 true 5
func SetModelRequest ¶
func SetModelRequest(sessionID acp.SessionId, model string) acp.SetSessionConfigOptionRequest
SetModelRequest constructs a model selector update.
func ValidateCodexSessionMeta ¶
ValidateCodexSessionMeta runs the owned-namespace parsing of a session lifecycle request's _meta without an Agent and returns the same refusal.
func WithSessionCodexOptions ¶
func WithSessionCodexOptions(options CodexOptions) wire.SessionRequestOption
WithSessionCodexOptions merges codex-specific options into _meta.codex.options.
func WithSessionOutputSchema ¶
func WithSessionOutputSchema(schema map[string]any) wire.SessionRequestOption
WithSessionOutputSchema sets the JSON schema the turn's final answer must satisfy; it rides outputSchema on turn/start.
func WithSessionRawEvents ¶
func WithSessionRawEvents(enabled bool) wire.SessionRequestOption
WithSessionRawEvents toggles raw codex event emission for the session.
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent exposes the Codex app-server through ACP. One app-server serves every session; each session owns one thread on it.
func NewAgent ¶
NewAgent creates an ACP agent for the Codex CLI. Construction never fails; a refused option is reported by Initialize and every session-establishing method as codex_invalid_options.
func (*Agent) Authenticate ¶
func (a *Agent) Authenticate(_ context.Context, params acp.AuthenticateRequest) (acp.AuthenticateResponse, error)
Authenticate exists because the SDK interface requires it. The harness authenticates itself in its own home, outside ACP.
func (*Agent) Cancel ¶
Cancel interrupts the session's in-flight turn. It is wire-silent on an unknown session or with no turn in flight.
func (*Agent) Close ¶
Close runs the shutdown ladder for every session, stops the shared app-server, and refuses every later request.
func (*Agent) CloseSession ¶
func (a *Agent) CloseSession(ctx context.Context, params acp.CloseSessionRequest) (resp acp.CloseSessionResponse, err error)
CloseSession runs the shutdown ladder for one session.
func (*Agent) HandleExtensionMethod ¶
func (a *Agent) HandleExtensionMethod(ctx context.Context, method string, params json.RawMessage) (any, error)
HandleExtensionMethod serves the account-usage read; every other extension method is method-not-found.
func (*Agent) Initialize ¶
func (a *Agent) Initialize(ctx context.Context, params acp.InitializeRequest) (resp acp.InitializeResponse, err error)
Initialize implements ACP initialize.
func (*Agent) ListSessions ¶
func (a *Agent) ListSessions(ctx context.Context, params acp.ListSessionsRequest) (resp acp.ListSessionsResponse, err error)
ListSessions lists live sessions and stored sessions, newest first.
func (*Agent) LoadSession ¶
func (a *Agent) LoadSession(ctx context.Context, params acp.LoadSessionRequest) (resp acp.LoadSessionResponse, err error)
LoadSession restores a session and replays its history.
func (*Agent) Logout ¶
func (a *Agent) Logout(_ context.Context, params acp.LogoutRequest) (acp.LogoutResponse, error)
Logout exists because the SDK interface requires it.
func (*Agent) NewSession ¶
func (a *Agent) NewSession(ctx context.Context, params acp.NewSessionRequest) (resp acp.NewSessionResponse, err error)
NewSession starts a thread on the shared app-server.
func (*Agent) Prompt ¶
func (a *Agent) Prompt(ctx context.Context, params acp.PromptRequest) (resp acp.PromptResponse, err error)
Prompt sends one turn to the thread and streams updates until it settles.
func (*Agent) ResumeSession ¶
func (a *Agent) ResumeSession(ctx context.Context, params acp.ResumeSessionRequest) (resp acp.ResumeSessionResponse, err error)
ResumeSession restores a session without replaying its history.
func (*Agent) SetSessionConfigOption ¶
func (a *Agent) SetSessionConfigOption(ctx context.Context, params acp.SetSessionConfigOptionRequest) (resp acp.SetSessionConfigOptionResponse, err error)
SetSessionConfigOption applies one select value.
func (*Agent) SetSessionMode ¶
func (a *Agent) SetSessionMode(_ context.Context, params acp.SetSessionModeRequest) (acp.SetSessionModeResponse, error)
SetSessionMode exists because the SDK interface requires it. Native modes are config options, never ACP session modes.
func (*Agent) UnstableDeleteSession ¶
func (a *Agent) UnstableDeleteSession(ctx context.Context, params acp.UnstableDeleteSessionRequest) (resp acp.UnstableDeleteSessionResponse, err error)
UnstableDeleteSession tombstones the session first, then closes any live session with the same id. The rollout stays in Codex's home.
type CodexOption ¶
type CodexOption func(*CodexOptions)
CodexOption configures CodexOptions values.
func WithCodexApprovalPolicy ¶
func WithCodexApprovalPolicy(policy any) CodexOption
WithCodexApprovalPolicy configures Codex's approval policy.
func WithCodexEffort ¶
func WithCodexEffort(effort string) CodexOption
WithCodexEffort configures the reasoning effort.
func WithCodexEnv ¶
func WithCodexEnv(env map[string]string) CodexOption
WithCodexEnv configures the session environment overlay.
func WithCodexExtraPathDirs ¶
func WithCodexExtraPathDirs(dirs ...string) CodexOption
WithCodexExtraPathDirs configures the directories prepended to the session PATH.
func WithCodexModel ¶
func WithCodexModel(model string) CodexOption
WithCodexModel configures the session model.
func WithCodexOutputSchema ¶
func WithCodexOutputSchema(schema map[string]any) CodexOption
WithCodexOutputSchema configures structured output for every turn.
func WithCodexPersonality ¶
func WithCodexPersonality(personality string) CodexOption
WithCodexPersonality configures the personality.
func WithCodexSandboxPolicy ¶
func WithCodexSandboxPolicy(policy any) CodexOption
WithCodexSandboxPolicy configures Codex's sandbox policy.
func WithCodexServiceTier ¶
func WithCodexServiceTier(tier string) CodexOption
WithCodexServiceTier configures the service tier.
type CodexOptions ¶
type CodexOptions struct {
// Model selects the Codex model for this session.
Model string `json:"model,omitempty"`
// Env overlays the session's thread environment.
Env map[string]string `json:"env,omitempty"`
// ExtraPathDirs are absolute directories prepended, in order, to the PATH
// of this session's thread.
ExtraPathDirs []string `json:"extraPathDirs,omitempty"`
// OutputSchema is the JSON schema every turn's final answer must satisfy.
OutputSchema map[string]any `json:"outputSchema,omitempty"`
// Effort is the reasoning effort passed to Codex.
Effort string `json:"effort,omitempty"`
// ServiceTier is the service tier passed to Codex.
ServiceTier string `json:"serviceTier,omitempty"`
// Personality is the personality passed to Codex.
Personality string `json:"personality,omitempty"`
// ApprovalPolicy is Codex's own approval policy, forwarded unchanged.
ApprovalPolicy any `json:"approvalPolicy,omitempty"`
// SandboxPolicy is Codex's own sandbox policy, forwarded unchanged.
SandboxPolicy any `json:"sandboxPolicy,omitempty"`
}
CodexOptions is the per-session options struct carried at _meta.codex.options.
func NewCodexOptions ¶
func NewCodexOptions(opts ...CodexOption) CodexOptions
NewCodexOptions constructs CodexOptions from functional options.
Example ¶
package main
import (
"fmt"
codexacp "github.com/savid/acp-go-codex"
)
func main() {
options := codexacp.NewCodexOptions(
codexacp.WithCodexModel("gpt-5.5"),
codexacp.WithCodexEffort("high"),
codexacp.WithCodexApprovalPolicy("on-request"),
)
fmt.Println(options.Model)
fmt.Println(options.Effort)
fmt.Println(options.ApprovalPolicy)
}
Output: gpt-5.5 high on-request
func (CodexOptions) Meta ¶
func (options CodexOptions) Meta() map[string]any
Meta returns exactly {"codex": {"options": {...}}} with the non-zero fields.
type ConcurrencyLimits ¶
ConcurrencyLimits controls per-agent backpressure. Zero fields use defaults.
type ImageLimits ¶
type ImageLimits struct {
MaxInputBytesPerImage int64
MaxInputBytesPerPrompt int64
MaxOutputBytesPerImage int64
MaxOutputBytesPerToolCall int64
}
ImageLimits bounds decoded image bytes. A zero field disables that policy limit; the frame clamp still applies.
type Option ¶
type Option func(*Options)
Option configures the Codex ACP agent.
func WithAgentName ¶
WithAgentName sets the protocol identifier advertised during ACP initialize.
func WithAgentTitle ¶
WithAgentTitle sets the human-readable agent name advertised during ACP initialize.
func WithAgentVersion ¶
WithAgentVersion sets the agent version advertised during ACP initialize.
func WithCodexConfigOverrides ¶
WithCodexConfigOverrides passes config values to the app-server as -c key=value. Nothing is written to disk.
func WithConcurrencyLimits ¶
func WithConcurrencyLimits(limits ConcurrencyLimits) Option
WithConcurrencyLimits sets process-local backpressure limits.
func WithConfiguredModels ¶
WithConfiguredModels names the models the host lists explicitly.
func WithDefaultModel ¶
WithDefaultModel selects the model for new sessions.
func WithEnv ¶
WithEnv sets the static agent-scoped environment overlay applied to the app-server after the inherited environment.
func WithExecutablePath ¶
WithExecutablePath selects the codex executable.
func WithImageLimits ¶
func WithImageLimits(limits ImageLimits) Option
WithImageLimits bounds decoded image bytes. A zero field disables that policy limit; a negative field fails construction.
func WithInputHandoffRoot ¶
WithInputHandoffRoot sets the absolute directory under which handoff-form prompt images are read. The adapter never writes there.
func WithLogger ¶
WithLogger configures structured diagnostic logging.
func WithMeterProvider ¶
func WithMeterProvider(provider metric.MeterProvider) Option
WithMeterProvider configures the OpenTelemetry meter provider.
func WithScratchDir ¶
WithScratchDir adds a root image output may be read from.
func WithSeedFiles ¶
WithSeedFiles registers files written into Codex's home before the app-server launches. Keys are paths relative to that home.
func WithSessionStore ¶
func WithSessionStore(store acpcore.SessionStore) Option
WithSessionStore configures the session store.
func WithTextMapPropagator ¶
func WithTextMapPropagator(propagator propagation.TextMapPropagator) Option
WithTextMapPropagator configures trace-context extraction from ACP _meta.
func WithTracerProvider ¶
func WithTracerProvider(provider trace.TracerProvider) Option
WithTracerProvider configures the OpenTelemetry tracer provider.
type Options ¶
type Options struct {
// AgentName is the protocol identifier advertised during ACP initialize.
AgentName string
// AgentTitle is the human-readable agent name advertised during ACP initialize.
AgentTitle string
// AgentVersion is the agent version advertised during ACP initialize.
AgentVersion string
// ExecutablePath selects the codex executable. A bare name is searched on
// the base PATH; a path containing a separator is used as given. Empty
// means "codex".
ExecutablePath string
// Home is Codex's native config, auth, and session root, passed to the
// app-server as CODEX_HOME. Empty leaves Codex to resolve its home from the
// inherited environment exactly as it would from a shell.
Home string
// ScratchDir is an additional root image output may be read from. The
// adapter writes no ephemeral files of its own.
ScratchDir string
// InputHandoffRoot is the absolute directory under which handoff-form
// prompt images are read. Empty rejects the handoff form.
InputHandoffRoot string
// DefaultModel selects the model for new sessions.
DefaultModel string
// ConfiguredModels are the model ids the host lists explicitly.
ConfiguredModels []string
// Env is the static agent-scoped overlay on the inherited process
// environment the app-server runs with.
Env map[string]string
// CodexConfigOverrides are passed to the app-server as -c key=value.
CodexConfigOverrides map[string]any
// Logger receives structured diagnostic logs. If nil, the default logger is used.
Logger *slog.Logger
// TracerProvider records adapter spans. If nil, tracing is a no-op.
TracerProvider trace.TracerProvider
// MeterProvider records adapter metrics. If nil, metrics are no-ops.
MeterProvider metric.MeterProvider
// TextMapPropagator extracts trace context from ACP _meta. If nil, W3C
// trace context plus baggage propagation is used.
TextMapPropagator propagation.TextMapPropagator
// SessionStore is the durability boundary for session rows. Nil installs a
// fresh in-memory store.
SessionStore acpcore.SessionStore
// ConcurrencyLimits controls process-local backpressure.
ConcurrencyLimits ConcurrencyLimits
// SeedFiles maps paths relative to Codex's home to file contents written
// there before the app-server launches.
SeedFiles map[string]string
// ImageLimits bounds decoded image bytes on prompt input and emitted
// output. Every field defaults to 6 MiB when the option is omitted.
ImageLimits ImageLimits
// contains filtered or unexported fields
}
Options configures the ACP agent process and the shared app-server it starts.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
acp-go-codex
command
|
|
|
Package integration holds the tests that run against an installed Codex.
|
Package integration holds the tests that run against an installed Codex. |
|
internal
|
|