claudecode

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package claudecode wraps the claude CLI binary as a provider.

Index

Constants

View Source
const (
	DefaultBackgroundGrace = 2 * time.Second
	DefaultBackgroundWait  = 30 * time.Minute
	DefaultTerminateGrace  = 5 * time.Second
)

Background-policy defaults.

The wait is generous on purpose. Its job is to cover the case this feature exists for — a build, a test suite or a training run that the agent started and should have waited for — and those finish in minutes, not seconds. The cost of waiting too long is a slow task; the cost of waiting too briefly is a task marked incomplete and retried when it would have succeeded, which is both more expensive and more confusing.

View Source
const ProviderName = "claudecode"

Variables

View Source
var ErrAuthFailure = errors.New("claude CLI authentication failure")

ErrAuthFailure marks a CLI invocation the API rejected for credential reasons (HTTP 401 / authentication_error). Callers use errors.Is to tell it apart from the other fatal CLI failures — 403, 429, 5xx, HTML error pages — which a credential refresh cannot fix and which must therefore not be retried here.

Functions

func CredentialRefresherWired

func CredentialRefresherWired() bool

CredentialRefresherWired reports whether a refresher has been installed. Exists so a test can assert the cmd/providers.go wiring is still present: losing it degrades the retry silently — it would still fire, but could only recover races a peer process happened to win, not a credential this process must rotate itself.

func SetCredentialRefresher

func SetCredentialRefresher(fn func() string)

SetCredentialRefresher installs the OAuth refresh used before an authentication retry. Called once from cmd/providers.go; also used by tests to substitute a stub for the real credentials and network.

Types

type BackgroundPolicy

type BackgroundPolicy struct {
	// Disabled turns detection off, restoring the previous behaviour of
	// trusting a harness that reports success while its work is still
	// running. An escape hatch for a deployment where the tradeoff is wrong,
	// not a default.
	Disabled bool
	// Grace is how long a surviving process may live before it counts as
	// background work rather than ordinary teardown. Zero selects
	// DefaultBackgroundGrace.
	Grace time.Duration
	// Wait bounds how long cloop blocks for that work to finish. Zero selects
	// DefaultBackgroundWait; negative means report it without waiting.
	Wait time.Duration
	// TerminateGrace is how long a terminated group has to exit on SIGTERM
	// before SIGKILL. Zero selects DefaultTerminateGrace.
	TerminateGrace time.Duration
	// KeepOrphans leaves work that outlived the budget running instead of
	// terminating it. The task is still reported incomplete either way.
	KeepOrphans bool
}

BackgroundPolicy governs what happens to work the harness leaves running in its process group after it exits. The zero value is the recommended behaviour: detect it, wait for it, and terminate whatever outlives the wait.

type Provider

type Provider struct {
	// Background governs the handling of work the CLI leaves running after it
	// exits. The zero value detects, waits and terminates; see
	// BackgroundPolicy.
	Background BackgroundPolicy
}

func New

func New() *Provider

func NewWithBackground

func NewWithBackground(policy BackgroundPolicy) *Provider

NewWithBackground builds a provider with an explicit policy for work the CLI leaves running. Zero-valued fields resolve to the documented defaults, so a caller that configures nothing still gets detection, the wait, and cleanup.

func (*Provider) Complete

func (p *Provider) Complete(ctx context.Context, prompt string, opts provider.Options) (*provider.Result, error)

Complete runs the CLI once and, if the API rejected our credentials, refreshes the OAuth token and retries exactly once.

Why a retry belongs here (Task 20204): a 401 from this provider is usually not a dead credential but a *lost race* for one. The CLI subprocesses refresh OAuth independently of each other and of cloop, and Claude.ai refresh tokens are single-use — so when a parallel round of tasks straddles the token's expiry, several CLI processes exchange the same refresh token at once. One wins; the losers get invalid_grant and surface "API Error: 401". The task after them succeeds because the winner has meanwhile written a fresh credential to disk, which is precisely the reported symptom: an isolated 401 with a healthy task on either side. A transient 401 from the edge (observed: a Cloudflare 502 body delivered under a 401 status) has the same shape and the same remedy.

Retrying is therefore scoped strictly to authentication failures. 429 and 5xx are deliberately excluded: an immediate retry cannot help a rate limit and would feed the loop that keeps it alive, and the orchestrator's MaxFailures gate already handles sustained upstream outages.

func (*Provider) DefaultModel

func (p *Provider) DefaultModel() string

func (*Provider) Name

func (p *Provider) Name() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL