zeroclaw

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2026 License: Apache-2.0, MIT Imports: 18 Imported by: 0

README

Go gopher zeroclaw-api-client-go

Your ZeroClaw, from Go. Typed calls, live streams, resilient by default.

Build Status Go Reference Go Report Card Latest release License ZeroClaw 0.8.5

net/http coder/websocket encoding/json govulncheck

Docs · Quick start · Guides · Resilience · Endpoint map · Architecture · ZeroClaw


zeroclaw-api-client-go is a typed, resilient Go client for the ZeroClaw gateway: its HTTP API, its Server-Sent Events stream and its WebSocket chat.

An independent, community-maintained client. It is not affiliated with or endorsed by ZeroClaw Labs; ZeroClaw is a trademark of ZeroClaw Labs.

go get github.com/RustLangLatam/zeroclaw-api-client-go
package main

import (
	"context"
	"fmt"
	"log"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, err := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	status, _ := client.System().Status(ctx, "")
	channels, _ := client.Channels().List(ctx)
	client.Config().Set(ctx, "agents.helper.model", "gpt-5.4-mini", "")

	chat, err := client.Chat(ctx, "helper", zeroclaw.ChatOptions{})
	if err != nil {
		log.Fatal(err)
	}
	defer chat.Close()
	reply, err := chat.Ask(ctx, "How many orders are pending?")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(status.Version, len(channels), reply.FullResponse)
}

Why an SDK

ZeroClaw is a self-hosted AI agent runtime. Everything an operator can do with it (configure agents, models and channels, pair devices, run SOPs, schedule jobs, read sessions and costs, talk to an agent) is exposed by its gateway over HTTP and WebSockets. Calling that surface by hand from every application that embeds ZeroClaw means repeating, in each of them:

  • the contract: about 150 routes, a dozen response shapes for errors, a JSON Patch dialect for the configuration, an event stream whose frames have no names, a chat protocol with typed frames;
  • the edge cases: secrets that are never returned, paths that must be encoded segment by segment, a gateway that drops connections while it reloads, routes that only exist with some build features;
  • the resilience: timeouts that must not cut a stream, retries that must never repeat a write, back-pressure.

This module does it once, typed and tested, so applications talk to ZeroClaw in terms of channels, agents and sessions instead of URLs and JSON. When the gateway changes, one place changes.

It complements what ZeroClaw ships: the gateway's own OpenAPI document (/api/openapi.json, browsable at /api/docs) describes part of the router, and zerocode speaks ACP over /acp; this client covers the whole REST, event and chat surface from Go.

Features

  • The whole client surface of the gateway, one accessor per area:

    Accessor Covers
    Config() per-field reads and writes, atomic JSON Patch, map aliases (agents, providers, channels), drift, catalogs, setup sections
    Pairing() pairing codes, bearer tokens, paired devices
    Channels() channel state, sending, group chats and their members, identity binding, relinking
    Chat() agent chat over WebSocket: streamed replies, tool calls, tool approvals
    Sessions(), Events() transcripts, session state, the live Server-Sent Events stream
    Agent(), Files(), Skills() agent workspaces, personality files, shared files, image uploads, skill bundles
    Cron(), Memory(), Cost() scheduled jobs, long-term memory, usage and cost
    Sops(), Canvas(), Quickstart() SOP authoring, runs and approvals; canvases; the first-agent setup
    System() health, status, metrics, diagnostics, tools, logs, upgrades, reload
    Webhook(), WebAuthn() one-shot webhook and A2A messages; hardware-key ceremonies
  • Resilient by default, built as a stack of http.RoundTrippers: answer timeouts that never cut a stream, retries with jittered exponential backoff for idempotent calls only that honor Retry-After, and, opt-in, a circuit breaker (sony/gobreaker), a client-side rate limit (x/time/rate) and a shared concurrency limit; plus your own middleware (metrics, tracing, signing) around every request.

  • Typed errors: a gateway refusal is an *APIError that keeps its status, its explanation and its JSON body; IsNotFound, IsUnauthorized, IsRateLimited and IsTransient classify any error, and sentinels (ErrTimeout, ErrDecode, …) work with errors.Is.

  • Pull, not callbacks: the event feed is an EventStream and the canvas and SOP-run feeds a Feed you read with Next; a chat is a session you pull frames from (NextFrame). The client starts no background work of its own.

  • Context everywhere: every call takes a context.Context for cancellation and deadlines.

  • Safe by construction: every path segment is percent-encoded, the token never appears in formatted output (%v, %+v, %#v), nothing is printed or logged.

  • Few, proven dependencies: coder/websocket for the chat, golang.org/x/time/rate and sony/gobreaker for resilience; everything else is the standard library.

Technologies

Concern Choice
Language Go 1.23+
HTTP net/http (TLS from crypto/tls, no cgo)
Middleware http.RoundTripper stack: deadline, rate limit, retry (jitter, Retry-After), concurrency limit, circuit breaker, your own Middleware
Rate limiting golang.org/x/time/rate token bucket
Circuit breaking sony/gobreaker/v2
WebSockets coder/websocket (zeroclaw.v1 subprotocol)
Serialization encoding/json
Tests net/http/httptest mock gateway, an in-test WebSocket gateway, captured response vectors, table-driven tests, benchmarks
Docs Go doc comments on pkg.go.dev and an mdBook book
Supply chain govulncheck, go mod tidy -diff

Architecture

 your code
    │  client.Channels().List(ctx)
    ▼
 Client ── resource accessors (Config, Channels, Chat, …) ── typed requests/responses
    │
    ├─ HTTP ──► your middleware ─► circuit breaker ─► concurrency limit ─► retry ─► rate limit ─► deadline ─► http.Transport ─► gateway
    ├─ SSE ───► the same stack; the body is read as a stream of events
    └─ WebSocket ─► coder/websocket (chat, canvas and SOP-run feeds)

Each method's documentation names the route it calls; the endpoint map is generated from them. See Architecture and the decision records.

Resilience

client, err := zeroclaw.New("http://127.0.0.1:42617",
	zeroclaw.WithToken("zc_…"),
	zeroclaw.WithTimeout(10*time.Second), // wait for an answer at most 10 s
	zeroclaw.WithRetry(zeroclaw.RetryPolicy{MaxRetries: 5, BaseDelay: 250 * time.Millisecond, MaxDelay: 8 * time.Second}),
	zeroclaw.WithConcurrencyLimit(4),                // shared by every copy
	zeroclaw.WithRateLimit(rate.Limit(10), 20),      // 10 requests/s, bursts of 20
	zeroclaw.WithCircuitBreaker(gobreaker.Settings{}), // open after 5 failures in a row, for 30 s
	zeroclaw.WithMiddleware(func(next http.RoundTripper) http.RoundTripper { return next }),
)

Retries apply to GET, HEAD, OPTIONS, PUT and DELETE after a connection failure, a connection dropped before the answer, a timeout, or a 408, 429, 502, 503 or 504, with jittered backoff and the gateway's Retry-After honored. A POST or PATCH is never repeated. An open breaker fails calls at once with ErrCircuitOpen; the rate limit fails a wait past the deadline with ErrRateLimited. The timeout bounds the wait for the answer's headers, so the event stream stays open. See the resilience guide.

Examples

Runnable programs under examples/:

Example Shows
status version, model and channels
pairing exchanging a pairing code for a token
config reading fields, listing agents, an atomic patch
events following the live event stream, reconnecting
chat streaming an agent's reply over the WebSocket
announce posting on a channel through a one-off cron job
resilient timeouts, retries, rate limit, circuit breaker, concurrency limit and a custom middleware
ZEROCLAW_URL=http://127.0.0.1:42617 ZEROCLAW_TOKEN=zc_… go run ./examples/status

Testing

  • Table-driven unit tests for every piece of logic: error mapping, URL encoding, SSE parsing, chat frames, retry decisions, backoff, patch operations, schedules.
  • HTTP-boundary tests for every endpoint against a mock gateway: method, path, query, body and decoding; plus retry, timeout, concurrency and middleware behavior, all under the race detector.
  • Response vectors: answers captured from a real gateway (scripts/capture-vectors.py, anonymized) must decode into the SDK's types and re-encode without losing a field.
  • Benchmarks for the hot paths: go test -run x -bench .
  • Live tests against a running gateway: every read decodes real answers, and a write suite covers the rest of the surface (config, cron, memory, files, skills, canvas, pairing, SOPs, admin, A2A, chat, webhooks, events and WebAuthn with a software authenticator), cleaning up after itself. See Testing.
go test -race ./...

Compatibility

Targets the ZeroClaw 0.8.5 gateway; see Compatibility for the builds it is verified against and the routes that need a newer one.

Documentation

Other languages

The same client, with the same surface, behavior and tests:

Language Repository Install
Rust zeroclaw-api-client-rust cargo add zeroclaw-api-client
Python zeroclaw-api-client-python pip install zeroclaw-api-client

Contributing

Work happens on branches with pull requests to main; see CONTRIBUTING.md and AGENTS.md.

License

Licensed under either of Apache License, Version 2.0 or MIT license, at your option.

The Go gopher (docs/assets/gopher.svg) was designed by Renée French and is licensed under Creative Commons Attribution 4.0; the artwork comes from golang/website.

Documentation

Overview

Package zeroclaw is a typed, resilient client for the ZeroClaw gateway (https://github.com/zeroclaw-labs/zeroclaw): its HTTP API, its Server-Sent Events stream and its WebSocket chat.

A Client holds the gateway URL and the bearer token; each resource group is reached through an accessor:

client, err := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
if err != nil { … }
channels, err := client.Channels().List(ctx)
port, err := client.Config().Get(ctx, "gateway.port")

Every HTTP request goes through a transport stack: an answer timeout that never cuts a stream, retries with jittered backoff for idempotent calls that honor Retry-After, and, opt-in, a circuit breaker (WithCircuitBreaker), a client-side rate limit (WithRateLimit), a concurrency limit (WithConcurrencyLimit) and any Middleware of your own (WithMiddleware).

Errors are typed: a gateway refusal is an *APIError that keeps its status and the gateway's own message; IsNotFound, IsUnauthorized, IsRateLimited and IsTransient classify any error. Shapes the gateway builds dynamically (config sections, SOP definitions, log events) are encoding/json.RawMessage.

Each method's documentation starts with the route it calls. The SDK targets the ZeroClaw 0.8.5 gateway; see docs/ for the endpoint map and the builds it is verified against.

This is an independent, community-maintained client. It is not affiliated with or endorsed by ZeroClaw Labs.

Example
package main

import (
	"context"
	"fmt"
	"log"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, err := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
	if err != nil {
		log.Fatal(err)
	}
	ctx := context.Background()

	status, err := client.System().Status(ctx, "")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("ZeroClaw", status.Version)

	if _, err := client.Config().Set(ctx, "agents.helper.model", "gpt-5.4-mini", ""); err != nil {
		log.Fatal(err)
	}
	chat, err := client.Chat(ctx, "helper", zeroclaw.ChatOptions{})
	if err != nil {
		log.Fatal(err)
	}
	defer chat.Close()
	reply, err := chat.Ask(ctx, "How many orders are pending?")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(reply.FullResponse)
}

Index

Examples

Constants

View Source
const (
	FrameSessionStart    = "session_start"    // the session is open
	FrameConnected       = "connected"        // answer to a "connect" frame
	FrameChunk           = "chunk"            // a piece of the reply, in Content
	FrameThinking        = "thinking"         // a piece of the model's reasoning, in Content
	FrameToolCall        = "tool_call"        // the agent calls a tool
	FrameToolResult      = "tool_result"      // a tool's result
	FrameApprovalRequest = "approval_request" // the agent needs approval to run a tool
	FrameDone            = "done"             // the turn ended; see Done
	FrameAborted         = "aborted"          // the turn was cancelled
	FrameError           = "error"            // the turn (or the session) failed
)

Chat frame types. Frames of any other type ("plan", "history_trimmed", "cron_result", session events, …) keep their type and only Raw is set.

View Source
const DefaultTimeout = 60 * time.Second

DefaultTimeout is how long a request waits for the gateway's answer (its headers: a streamed body is not bounded) unless WithTimeout says otherwise. The gateway's own limit is 30 s; calls that do longer work set their own.

View Source
const Version = "0.2.0"

Version is the SDK version, sent in the User-Agent header.

Variables

View Source
var (
	// ErrInvalidURL means the gateway URL, or a URL built from it, is not
	// valid.
	ErrInvalidURL = errors.New("invalid gateway URL")

	// ErrTimeout means the gateway did not answer within the client's
	// timeout (after any retries). A deadline or cancellation of the
	// caller's own context is returned as the context's error instead.
	ErrTimeout = errors.New("the gateway did not answer in time")

	// ErrDecode means the gateway answered successfully but the body did
	// not have the expected shape.
	ErrDecode = errors.New("unexpected gateway response")

	// ErrWebSocket means a WebSocket connection to the gateway failed.
	ErrWebSocket = errors.New("websocket error")

	// ErrCircuitOpen means the circuit breaker ([WithCircuitBreaker])
	// refused the call because the gateway kept failing; it was not sent.
	ErrCircuitOpen = errors.New("circuit breaker is open")

	// ErrRateLimited means the client's own rate limit ([WithRateLimit])
	// could not let the call through before the caller's deadline; it was
	// not sent.
	ErrRateLimited = errors.New("client rate limit exceeded")
)

Sentinel errors. Match them with errors.Is.

Functions

func IsNotFound

func IsNotFound(err error) bool

IsNotFound reports whether the gateway answered 404 (the resource does not exist).

func IsRateLimited

func IsRateLimited(err error) bool

IsRateLimited reports whether the gateway rate-limited the call (429), or the client's own rate limit held it back (ErrRateLimited).

func IsTransient

func IsTransient(err error) bool

IsTransient reports whether the call may work if made again later: no connection, a connection dropped before the answer, a timeout, or a "try again" status (408, 429, 502, 503, 504). The client already retried idempotent calls before returning it.

Example
package main

import (
	"context"
	"errors"
	"fmt"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, _ := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
	_, err := client.Cron().List(context.Background())
	switch {
	case err == nil:
	case zeroclaw.IsUnauthorized(err):
		fmt.Println("pair again:", err)
	case zeroclaw.IsTransient(err):
		fmt.Println("try later:", err) // idempotent calls were already retried
	default:
		var api *zeroclaw.APIError
		if errors.As(err, &api) {
			fmt.Println(api.Status, api.Message, string(api.Body))
		}
	}
}

func IsUnauthorized

func IsUnauthorized(err error) bool

IsUnauthorized reports whether the gateway refused the credentials (401) or the action (403).

func StatusCode

func StatusCode(err error) int

StatusCode is the HTTP status of an *APIError in err's chain, or 0.

Types

type APIError

type APIError struct {
	// Status is the HTTP status code.
	Status int
	// Message is the human-readable reason given by the gateway.
	Message string
	// Body is the JSON error body, when the gateway sent one.
	Body json.RawMessage
}

APIError is a gateway answer with a non-success status.

Message is the gateway's own explanation (its "error" or "message" field) when the body carries one, otherwise the body text; Body keeps the JSON body when there was one, for fields beyond the message.

func (*APIError) Error

func (e *APIError) Error() string

type AdminResponse

type AdminResponse struct {
	// Success is whether it was accepted.
	Success bool `json:"success"`
	// Message says what happens next.
	Message string `json:"message"`
}

AdminResponse is the answer of the /admin actions.

type AgentAPI

type AgentAPI struct {
	// contains filtered or unexported fields
}

AgentAPI holds one agent's endpoints, from Client.Agent.

func (AgentAPI) ListFiles

func (a AgentAPI) ListFiles(ctx context.Context, path string) (*FileListing, error)

ListFiles returns a workspace directory, the root when path is empty (GET /api/agents/{alias}/workspace/list).

func (AgentAPI) MakeDir

func (a AgentAPI) MakeDir(ctx context.Context, path string) error

MakeDir creates a directory (POST /api/agents/{alias}/workspace/mkdir).

func (AgentAPI) MovePath

func (a AgentAPI) MovePath(ctx context.Context, from, to string) error

MovePath moves or renames a file or directory (POST /api/agents/{alias}/workspace/move).

func (AgentAPI) Personality

func (a AgentAPI) Personality(ctx context.Context, filename string) (*PersonalityFile, error)

Personality returns one personality file: SOUL.md, IDENTITY.md, USER.md, AGENTS.md, TOOLS.md, HEARTBEAT.md or MEMORY.md (GET /api/personality/{filename}).

func (AgentAPI) PersonalityFiles

func (a AgentAPI) PersonalityFiles(ctx context.Context) (*PersonalityFiles, error)

PersonalityFiles returns the agent's personality files and whether each exists (GET /api/personality).

func (AgentAPI) PersonalityTemplates

func (a AgentAPI) PersonalityTemplates(ctx context.Context, pc PersonalityContext) (*PersonalityTemplates, error)

PersonalityTemplates returns the default personality files rendered for this agent, without writing them (GET /api/personality/templates).

func (AgentAPI) ReadFile

func (a AgentAPI) ReadFile(ctx context.Context, path string) (*FileContent, error)

ReadFile returns a workspace file, up to 4 MiB; binary files come base64-encoded (GET /api/agents/{alias}/workspace/read).

func (AgentAPI) RemovePath

func (a AgentAPI) RemovePath(ctx context.Context, path string) error

RemovePath removes a file or directory (DELETE /api/agents/{alias}/workspace/path).

func (AgentAPI) Skills

func (a AgentAPI) Skills(ctx context.Context) (*AgentSkills, error)

Skills returns the skills the agent loads, where each comes from, and those dropped by the audit (GET /api/agents/{alias}/skills).

func (AgentAPI) WritePersonality

func (a AgentAPI) WritePersonality(ctx context.Context, filename, content string, expectedMtimeMs *int64) (*PersonalityWritten, error)

WritePersonality replaces a personality file, at most 20 000 characters (PUT /api/personality/{filename}). With a non-nil expectedMtimeMs, the write is refused (409) if the file changed since it was read.

type AgentCostStats

type AgentCostStats struct {
	// AgentAlias is the agent.
	AgentAlias string `json:"agent_alias"`
	// CostUSD is the cost, USD.
	CostUSD float64 `json:"cost_usd"`
	// TotalTokens is all tokens.
	TotalTokens uint64 `json:"total_tokens"`
	// InputTokens is the input tokens.
	InputTokens uint64 `json:"input_tokens"`
	// OutputTokens is the output tokens.
	OutputTokens uint64 `json:"output_tokens"`
	// CachedInputTokens is the cached input tokens.
	CachedInputTokens uint64 `json:"cached_input_tokens"`
	// RequestCount is the calls.
	RequestCount int `json:"request_count"`
}

AgentCostStats is one agent's usage.

type AgentOptions

type AgentOptions struct {
	// Channels, as type.alias.
	Channels []string `json:"channels"`
	// ChannelTypes are the channel types.
	ChannelTypes []string `json:"channel_types"`
	// ModelProviders, as type.alias.
	ModelProviders []string `json:"model_providers"`
	// RiskProfiles are the risk profiles.
	RiskProfiles []string `json:"risk_profiles"`
	// RuntimeProfiles are the runtime profiles.
	RuntimeProfiles []string `json:"runtime_profiles"`
	// SkillBundles are the skill bundles.
	SkillBundles []string `json:"skill_bundles"`
	// KnowledgeBundles are the knowledge bundles.
	KnowledgeBundles []string `json:"knowledge_bundles"`
	// MCPBundles are the MCP bundles.
	MCPBundles []string `json:"mcp_bundles"`
	// Agents are the agents.
	Agents []string `json:"agents"`
}

AgentOptions lists the aliases an agent can reference.

type AgentReply

type AgentReply struct {
	// Response is the reply.
	Response string `json:"response"`
	// Model is the model that answered.
	Model string `json:"model"`
}

AgentReply is an agent's reply to a webhook.

type AgentSkills

type AgentSkills struct {
	// Agent is the agent.
	Agent string `json:"agent"`
	// Skills are the loaded skills: name, description, origin (workspace,
	// open-skills, plugin, bundle), editable, …
	Skills []json.RawMessage `json:"skills"`
	// Dropped are the skills left out, with reason_kind and reason.
	Dropped []json.RawMessage `json:"dropped,omitempty"`
}

AgentSkills lists the skills an agent loads.

type AliasSource

type AliasSource string

AliasSource is an alias kind an alias-reference field can point to.

const (
	AliasModelProviders         AliasSource = "model_providers" // providers.models.*
	AliasTTSProviders           AliasSource = "tts_providers"
	AliasTranscriptionProviders AliasSource = "transcription_providers"
	AliasChannels               AliasSource = "channels" // channels.*
	AliasRiskProfiles           AliasSource = "risk_profiles"
	AliasRuntimeProfiles        AliasSource = "runtime_profiles"
	AliasAgents                 AliasSource = "agents" // agents.*
	AliasSkillBundles           AliasSource = "skill_bundles"
	AliasKnowledgeBundles       AliasSource = "knowledge_bundles"
	AliasMCPBundles             AliasSource = "mcp_bundles"
)

The alias kinds.

type Bound

type Bound struct {
	// Saved says whether the configuration was saved.
	Saved bool `json:"saved"`
	// AlreadyBound says whether the identity was already allowed.
	AlreadyBound bool `json:"already_bound"`
	// Group is the peer group it was added to.
	Group string `json:"group"`
	// Channel is the channel.
	Channel string `json:"channel"`
}

Bound is the result of ChannelsAPI.Bind.

type CLITool

type CLITool struct {
	// Name is the command name.
	Name string `json:"name"`
	// Path is the full path.
	Path string `json:"path"`
	// Version is the reported version.
	Version *string `json:"version,omitempty"`
	// Category is the kind of tool (VersionControl, Language, …).
	Category string `json:"category"`
}

CLITool is a command-line tool on the host.

type CanvasAPI

type CanvasAPI struct {
	// contains filtered or unexported fields
}

CanvasAPI holds the canvas endpoints, from Client.Canvas.

func (CanvasAPI) Clear

func (a CanvasAPI) Clear(ctx context.Context, id string) error

Clear clears a canvas (DELETE /api/canvas/{id}).

func (CanvasAPI) Current

func (a CanvasAPI) Current(ctx context.Context, id string) (*CanvasFrame, error)

Current returns the current frame (GET /api/canvas/{id}).

func (CanvasAPI) History

func (a CanvasAPI) History(ctx context.Context, id string) ([]CanvasFrame, error)

History returns past frames, oldest first (GET /api/canvas/{id}/history).

func (CanvasAPI) List

func (a CanvasAPI) List(ctx context.Context) ([]string, error)

List returns the canvas ids (GET /api/canvas).

func (CanvasAPI) Publish

func (a CanvasAPI) Publish(ctx context.Context, id, contentType, content string) (*CanvasFrame, error)

Publish publishes a frame, creating the canvas (POST /api/canvas/{id}). contentType is html, svg, markdown or text.

func (CanvasAPI) Watch

func (a CanvasAPI) Watch(ctx context.Context, id string) (*Feed, error)

Watch follows a canvas live (GET /ws/canvas/{id}). Frames are {"type": "connected" | "frame" | "lagged" | "error", …}; a frame carries the published frame.

type CanvasFrame

type CanvasFrame struct {
	// FrameID is the frame id.
	FrameID string `json:"frame_id"`
	// ContentType is html, svg, markdown or text.
	ContentType string `json:"content_type"`
	// Content is the content.
	Content string `json:"content"`
	// Timestamp is when it was published.
	Timestamp string `json:"timestamp"`
}

CanvasFrame is a canvas frame.

type CatalogModelProvider

type CatalogModelProvider struct {
	// Name is the provider family name.
	Name string `json:"name"`
	// DisplayName is shown to people.
	DisplayName string `json:"display_name"`
	// Local says whether it runs locally.
	Local bool `json:"local"`
}

CatalogModelProvider is a model provider the build knows.

type CatalogModels

type CatalogModels struct {
	// ModelProvider is the provider family name.
	ModelProvider string `json:"model_provider"`
	// Models are the model ids.
	Models []string `json:"models"`
	// Pricing holds the prices per model, when the provider publishes them.
	Pricing map[string]ModelPricing `json:"pricing,omitempty"`
	// Local says whether it runs locally.
	Local bool `json:"local"`
	// Live says whether the list came live from the provider.
	Live bool `json:"live"`
}

CatalogModels lists the models of a provider.

type Channel

type Channel struct {
	// Name is type.alias, the name the other calls take.
	Name string `json:"name"`
	// Type is the channel type (whatsapp, telegram, …).
	Type string `json:"type"`
	// Alias is the alias.
	Alias string `json:"alias"`
	// OwningAgent is the agent it belongs to.
	OwningAgent *string `json:"owning_agent,omitempty"`
	// Enabled says whether it is enabled.
	Enabled bool `json:"enabled"`
	// Compiled says whether this build includes its type.
	Compiled bool `json:"compiled"`
	// Status is active, inactive, error, unknown or not_compiled.
	Status string `json:"status"`
	// Health is healthy, degraded, down or unavailable.
	Health string `json:"health"`
	// Readiness says what it still needs (enabled, bound_to_agent,
	// authenticated, listening, each ready/missing/unknown, plus notes).
	Readiness json.RawMessage `json:"readiness,omitempty"`
	// MessageCount is the number of messages the channel has carried.
	MessageCount int `json:"message_count"`
	// LastMessageAt is when the last one went through (RFC 3339).
	LastMessageAt *string `json:"last_message_at,omitempty"`
}

Channel is a configured channel.

type ChannelsAPI

type ChannelsAPI struct {
	// contains filtered or unexported fields
}

ChannelsAPI holds the channel endpoints, from Client.Channels.

func (ChannelsAPI) Bind

func (a ChannelsAPI) Bind(ctx context.Context, channelType, alias, identity string) (*Bound, error)

Bind lets identity talk to the channel (Telegram, WeChat and LINE), adding it to the channel's peer group (POST /api/channels/bind).

func (ChannelsAPI) List

func (a ChannelsAPI) List(ctx context.Context) ([]Channel, error)

List returns every configured channel and its state (GET /api/channels).

func (a ChannelsAPI) Relink(ctx context.Context, channel string) (*Relinked, error)

Relink clears a QR-paired channel's saved login so it pairs again after a reload (SystemAPI.Reload): POST /api/channels/{channel}/relink.

type ChatFrame

type ChatFrame struct {
	// Type is the frame type, one of the Frame* constants or another.
	Type string

	// Content of a chunk or thinking frame.
	Content string

	// SessionID, Resumed (whether it existed), MessageCount (messages it
	// holds) and Name of a session_start frame.
	SessionID    string
	Resumed      bool
	MessageCount int
	// Name of the session (session_start) or of the tool (tool_call,
	// tool_result).
	Name string

	// ID of a tool_call or tool_result; Args of the call; Output of the
	// result.
	ID     string
	Args   json.RawMessage
	Output json.RawMessage

	// RequestID, Tool, ArgumentsSummary (what it would do) and TimeoutSecs
	// (seconds before it is denied) of an approval_request; answer it with
	// [ChatSession.AnswerApproval].
	RequestID        string
	Tool             string
	ArgumentsSummary string
	TimeoutSecs      uint64

	// Done is the end of the turn, for a done frame.
	Done *TurnResult

	// Message and Code (PROVIDER_ERROR, SESSION_QUEUE_FULL, …) of an error
	// frame.
	Message string
	Code    string

	// Raw is the frame as sent.
	Raw json.RawMessage
}

ChatFrame is a frame the gateway sends on the chat. Type says which fields are set.

type ChatOptions

type ChatOptions struct {
	// SessionID is the session to resume or create (a new one without it).
	SessionID string
	// Name names the session.
	Name string
	// Cwd is the working directory for the session (must exist on the host).
	Cwd string
}

ChatOptions says where a chat connects. Empty fields are left out.

type ChatSession

type ChatSession struct {
	// contains filtered or unexported fields
}

ChatSession is an open chat with an agent. Frames are read by one goroutine at a time; sending is safe from any.

func (*ChatSession) AnswerApproval

func (s *ChatSession) AnswerApproval(ctx context.Context, requestID, decision string) error

AnswerApproval answers an approval_request with decision "approve", "deny" or "always".

func (*ChatSession) Ask

func (s *ChatSession) Ask(ctx context.Context, content string) (*TurnResult, error)

Ask sends content and waits for the turn to end, ignoring the frames in between. An error frame becomes a *TurnError; an aborted turn too, with code "ABORTED". Tool approvals are not answered here: use ChatSession.NextFrame for agents that ask for them.

func (*ChatSession) Close

func (s *ChatSession) Close() error

Close closes the chat. Closing during a turn cancels it.

func (*ChatSession) MessageCount

func (s *ChatSession) MessageCount() int

MessageCount is the number of messages the session held when it was opened.

func (*ChatSession) NextFrame

func (s *ChatSession) NextFrame(ctx context.Context) (ChatFrame, error)

NextFrame returns the next frame from the gateway, or io.EOF once the socket closed. Cancelling ctx while it waits closes the chat (the WebSocket cannot resume a half-read message).

Example
package main

import (
	"context"
	"fmt"
	"log"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, _ := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
	ctx := context.Background()
	chat, err := client.Chat(ctx, "helper", zeroclaw.ChatOptions{})
	if err != nil {
		log.Fatal(err)
	}
	defer chat.Close()
	chat.Send(ctx, "Clean the tmp folder")
	for {
		frame, err := chat.NextFrame(ctx)
		if err != nil {
			log.Fatal(err)
		}
		switch frame.Type {
		case zeroclaw.FrameChunk:
			fmt.Print(frame.Content)
		case zeroclaw.FrameApprovalRequest:
			chat.AnswerApproval(ctx, frame.RequestID, "approve")
		case zeroclaw.FrameDone:
			return
		}
	}
}

func (*ChatSession) Resumed

func (s *ChatSession) Resumed() bool

Resumed reports whether an existing session was resumed.

func (*ChatSession) Send

func (s *ChatSession) Send(ctx context.Context, content string) error

Send sends a message: it starts a turn, or steers the running one.

func (*ChatSession) SessionID

func (s *ChatSession) SessionID() string

SessionID is the session id (its key is gw_<id>).

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a connection to one ZeroClaw gateway.

It is safe for concurrent use; copies made with Client.WithToken share the connection pool and the concurrency limit. Resource groups are reached through accessors such as Client.Cron or Client.Config.

func New

func New(baseURL string, opts ...Option) (*Client, error)

New returns a client for the gateway at baseURL (e.g. "http://127.0.0.1:42617"). It fails with ErrInvalidURL when baseURL is not an absolute http or https URL.

Example (Resilience)
package main

import (
	"log"
	"time"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, err := zeroclaw.New("http://127.0.0.1:42617",
		zeroclaw.WithToken("zc_…"),
		zeroclaw.WithTimeout(10*time.Second), // wait for an answer at most 10 s
		zeroclaw.WithRetry(zeroclaw.RetryPolicy{MaxRetries: 5, BaseDelay: 250 * time.Millisecond, MaxDelay: 8 * time.Second}),
		zeroclaw.WithConcurrencyLimit(4), // shared by every copy
	)
	if err != nil {
		log.Fatal(err)
	}
	_ = client
}

func (*Client) Agent

func (c *Client) Agent(alias string) AgentAPI

Agent returns the endpoints of agent alias.

func (*Client) BaseURL

func (c *Client) BaseURL() *url.URL

BaseURL is the gateway's base URL.

func (*Client) Canvas

func (c *Client) Canvas() CanvasAPI

Canvas returns the canvas endpoints (/api/canvas).

func (*Client) Channels

func (c *Client) Channels() ChannelsAPI

Channels returns the channels (/api/channels).

func (*Client) Chat

func (c *Client) Chat(ctx context.Context, alias string, opts ChatOptions) (*ChatSession, error)

Chat opens a chat with agent alias (GET /ws/chat, upgraded to a WebSocket) and waits for the gateway to confirm the session. ctx bounds the opening only; each later call takes its own.

func (*Client) Config

func (c *Client) Config() ConfigAPI

Config returns the configuration endpoints (/api/config/...).

func (*Client) Cost

func (c *Client) Cost() CostAPI

Cost returns the usage and cost endpoint (/api/cost).

func (*Client) Cron

func (c *Client) Cron() CronAPI

Cron returns the scheduled jobs endpoints (/api/cron).

func (*Client) Events

func (c *Client) Events() EventsAPI

Events returns the live event stream endpoints (/api/events).

func (*Client) Files

func (c *Client) Files() FilesAPI

Files returns the shared directory and uploads.

func (*Client) GoString

func (c *Client) GoString() string

GoString hides the token from %#v too.

func (*Client) Memory

func (c *Client) Memory() MemoryAPI

Memory returns the long-term memory endpoints (/api/memory).

func (*Client) Pairing

func (c *Client) Pairing() PairingAPI

Pairing returns the pairing and paired devices endpoints.

func (*Client) Quickstart

func (c *Client) Quickstart() QuickstartAPI

Quickstart returns the first-agent quickstart endpoints (/api/quickstart).

func (*Client) Sessions

func (c *Client) Sessions() SessionsAPI

Sessions returns the conversation sessions endpoints (/api/sessions).

func (*Client) Skills

func (c *Client) Skills() SkillsAPI

Skills returns the skill bundles and skills (/api/skills).

func (*Client) Sops

func (c *Client) Sops() SopsAPI

Sops returns the standard operating procedure endpoints (/api/sops).

func (*Client) String

func (c *Client) String() string

String describes the client without its token, so it never reaches logs.

func (*Client) System

func (c *Client) System() SystemAPI

System returns the health, status, diagnostics, logs, versions and administration endpoints.

func (*Client) WebAuthn

func (c *Client) WebAuthn() WebAuthnAPI

WebAuthn returns the hardware-key registration and assertion endpoints (/api/webauthn).

func (*Client) Webhook

func (c *Client) Webhook() WebhookAPI

Webhook returns the generic webhook and A2A endpoints.

func (*Client) WithToken

func (c *Client) WithToken(token string) *Client

WithToken returns a client for the same gateway and connection pool with another bearer token, e.g. the one a pairing just returned.

type ComponentHealth

type ComponentHealth struct {
	// Status is "ok", "error", …
	Status string `json:"status"`
	// UpdatedAt is the last update (RFC 3339).
	UpdatedAt string `json:"updated_at"`
	// LastOK is the last time it was healthy.
	LastOK *string `json:"last_ok,omitempty"`
	// LastError is the last error.
	LastError *string `json:"last_error,omitempty"`
	// RestartCount is how many times it was restarted.
	RestartCount uint64 `json:"restart_count"`
}

ComponentHealth is one component's health.

type ConfigAPI

type ConfigAPI struct {
	// contains filtered or unexported fields
}

ConfigAPI holds the configuration endpoints, from Client.Config.

func (ConfigAPI) AgentOptions

func (a ConfigAPI) AgentOptions(ctx context.Context) (*AgentOptions, error)

AgentOptions returns the aliases an agent can reference (GET /api/config/agent-options).

func (ConfigAPI) AliasValues

func (a ConfigAPI) AliasValues(ctx context.Context, source AliasSource) ([]string, error)

AliasValues returns the aliases an alias-reference field may point to; providers and channels as type.alias (GET /api/config/resolve-alias-source).

func (ConfigAPI) Catalog

func (a ConfigAPI) Catalog(ctx context.Context) ([]CatalogModelProvider, error)

Catalog returns the model providers this build knows (GET /api/config/catalog).

func (ConfigAPI) CatalogModels

func (a ConfigAPI) CatalogModels(ctx context.Context, modelProvider string) (*CatalogModels, error)

CatalogModels returns the models of a provider; it may call the provider with the configured credentials (GET /api/config/catalog/models).

func (ConfigAPI) CreateMapKey

func (a ConfigAPI) CreateMapKey(ctx context.Context, path, key string) (*MapKeyResponse, error)

CreateMapKey creates alias key under map path with defaults; Created is false when it already existed (POST /api/config/map-key).

func (ConfigAPI) DeleteMapKey

func (a ConfigAPI) DeleteMapKey(ctx context.Context, path, key string) (*MapKeyResponse, error)

DeleteMapKey removes alias key and the references to it (DELETE /api/config/map-key). Deleting an agent also archives its workspace and its memory, cron jobs and sessions; check ConfigAPI.DeletePlan first.

func (ConfigAPI) DeletePlan

func (a ConfigAPI) DeletePlan(ctx context.Context, path, key string) (*DeletePlan, error)

DeletePlan says what deleting alias key would block on or rewrite, without changing anything (GET /api/config/delete-plan).

func (ConfigAPI) Drift

func (a ConfigAPI) Drift(ctx context.Context) ([]DriftEntry, error)

Drift returns the fields whose value on disk differs from the gateway's (GET /api/config/drift).

func (ConfigAPI) Get

func (a ConfigAPI) Get(ctx context.Context, path string) (*PropValue, error)

Get reads one field (GET /api/config/prop).

func (ConfigAPI) Init

func (a ConfigAPI) Init(ctx context.Context, section string) ([]string, error)

Init fills unset nested sections under section (everywhere when empty) with defaults and returns the sections created (POST /api/config/init).

func (ConfigAPI) List

func (a ConfigAPI) List(ctx context.Context, prefix string) (*ConfigList, error)

List returns every field reachable under prefix (all fields when empty), with its kind, category and current value (GET /api/config/list).

func (ConfigAPI) MapKeys

func (a ConfigAPI) MapKeys(ctx context.Context, path string) ([]string, error)

MapKeys returns the aliases of a map section, e.g. "agents" or "channels.whatsapp" (GET /api/config/map-keys).

func (ConfigAPI) Migrate

func (a ConfigAPI) Migrate(ctx context.Context) (*MigrateResponse, error)

Migrate migrates config.toml to the current schema in place, keeping a backup (POST /api/config/migrate).

func (ConfigAPI) Patch

func (a ConfigAPI) Patch(ctx context.Context, ops []PatchOp, overrideDrift bool) (*PatchResponse, error)

Patch applies ops atomically, all or nothing (PATCH /api/config). With overrideDrift, paths edited on disk since the gateway loaded them are overwritten instead of refused with 409.

Example
package main

import (
	"context"
	"log"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, _ := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
	// All or nothing: the model only changes if it is still the one read.
	_, err := client.Config().Patch(context.Background(), []zeroclaw.PatchOp{
		zeroclaw.TestOp("agents.helper.model", "gpt-5.4-mini"),
		zeroclaw.ReplaceOp("agents.helper.model", "gpt-5.5"),
		zeroclaw.CommentOp("agents.helper.model", "upgraded"),
	}, false)
	if err != nil {
		log.Fatal(err)
	}
}

func (ConfigAPI) PendingReload

func (a ConfigAPI) PendingReload(ctx context.Context) (bool, error)

PendingReload reports whether saved changes wait for a daemon reload (SystemAPI.Reload): GET /api/config/reload-status.

func (ConfigAPI) PropSchema

func (a ConfigAPI) PropSchema(ctx context.Context, path string) (json.RawMessage, error)

PropSchema returns the schema plus the field's metadata under x-zeroclaw-prop (OPTIONS /api/config/prop). Public.

func (ConfigAPI) RefreshContextWindow

func (a ConfigAPI) RefreshContextWindow(ctx context.Context, providerType, alias string) (uint64, error)

RefreshContextWindow asks the provider for the model's context window and stores it (POST /api/config/model-providers/{type}/{alias}/refresh-context-window).

func (ConfigAPI) RenameMapKey

func (a ConfigAPI) RenameMapKey(ctx context.Context, path, from, to string) (*RenameResponse, error)

RenameMapKey renames alias from to to, and every reference to it (POST /api/config/rename-map-key).

func (ConfigAPI) Reset

func (a ConfigAPI) Reset(ctx context.Context, path string) (*PropValue, error)

Reset resets one field to its default (DELETE /api/config/prop).

func (ConfigAPI) Schema

func (a ConfigAPI) Schema(ctx context.Context) (json.RawMessage, error)

Schema returns the JSON Schema of the whole configuration, static per gateway build (OPTIONS /api/config). Public.

func (ConfigAPI) SectionItems

func (a ConfigAPI) SectionItems(ctx context.Context, section string) (*SectionItems, error)

SectionItems returns the items a picker section offers, e.g. the provider families of providers.models (GET /api/config/sections/{section}).

func (ConfigAPI) Sections

func (a ConfigAPI) Sections(ctx context.Context) ([]ConfigSection, error)

Sections returns the setup sections, in wizard order (GET /api/config/sections).

func (ConfigAPI) SelectSectionItem

func (a ConfigAPI) SelectSectionItem(ctx context.Context, section, key, alias string) (*SelectedItem, error)

SelectSectionItem picks an item, creating what it needs, and returns where its fields live (POST /api/config/sections/{section}/items/{key}). An empty alias lets the gateway use "default" where the section takes one.

func (ConfigAPI) Set

func (a ConfigAPI) Set(ctx context.Context, path string, value any, comment string) (*PropValue, error)

Set writes one field (PUT /api/config/prop). value is encoded as JSON (nil resets it); a non-empty comment is written above the key in the TOML. A map alias implied by the path is created.

func (ConfigAPI) Snapshot

func (a ConfigAPI) Snapshot(ctx context.Context) (json.RawMessage, error)

Snapshot returns the whole configuration with secrets masked as "***MASKED***" (GET /api/config). A compatibility snapshot; prefer ConfigAPI.List and ConfigAPI.Get, which carry field metadata.

func (ConfigAPI) Status

func (a ConfigAPI) Status(ctx context.Context) (*ConfigStatus, error)

Status reports whether the setup is complete (GET /api/config/status).

func (ConfigAPI) Templates

func (a ConfigAPI) Templates(ctx context.Context) ([]TemplateEntry, error)

Templates returns the map and list sections and the type of their entries (GET /api/config/templates).

type ConfigEntry

type ConfigEntry struct {
	// Path is the dotted path.
	Path string `json:"path"`
	// Category groups fields.
	Category string `json:"category"`
	// Kind is string, bool, integer, float, enum, alias-ref, string-array,
	// object-array or object.
	Kind string `json:"kind"`
	// TypeHint is the Rust type, e.g. Option<String>.
	TypeHint string `json:"type_hint"`
	// Value is the display value; absent for secrets.
	Value json.RawMessage `json:"value,omitempty"`
	// Populated says whether it has a value.
	Populated bool `json:"populated"`
	// IsSecret says whether it is a secret.
	IsSecret bool `json:"is_secret"`
	// IsEnvOverridden says whether an environment variable overrides it.
	IsEnvOverridden bool `json:"is_env_overridden"`
	// EnumVariants are the allowed values of an enum.
	EnumVariants []string `json:"enum_variants,omitempty"`
	// Section is the setup section it belongs to.
	Section *string `json:"section,omitempty"`
	// Tab is the dashboard tab.
	Tab string `json:"tab"`
	// Multiline says whether it is edited as multi-line text.
	Multiline bool `json:"multiline"`
}

ConfigEntry is one configuration field.

type ConfigList

type ConfigList struct {
	// Entries are the fields.
	Entries []ConfigEntry `json:"entries"`
	// Drifted lists the fields whose value on disk differs from the
	// gateway's.
	Drifted []DriftEntry `json:"drifted,omitempty"`
}

ConfigList is the result of ConfigAPI.List.

type ConfigSection

type ConfigSection struct {
	// Key is the section key, e.g. providers.models.
	Key string `json:"key"`
	// Label is shown to people.
	Label string `json:"label"`
	// Help is the help text.
	Help string `json:"help"`
	// HasPicker says whether it offers items to pick
	// ([ConfigAPI.SectionItems]).
	HasPicker bool `json:"has_picker"`
	// Completed says whether it is completed.
	Completed bool `json:"completed"`
	// Ready says whether it is ready to use.
	Ready bool `json:"ready"`
	// Group is the group it is shown under.
	Group string `json:"group"`
	// IsQuickstart says whether the quickstart includes it.
	IsQuickstart bool `json:"is_quickstart"`
	// Shape is direct_form, one_tier_alias_map, typed_family_map or
	// backend_picker.
	Shape *string `json:"shape,omitempty"`
	// CostCategory is the cost category.
	CostCategory string `json:"cost_category"`
}

ConfigSection is a setup section.

type ConfigStatus

type ConfigStatus struct {
	// NeedsQuickstart says whether the quickstart still has to run.
	NeedsQuickstart bool `json:"needs_quickstart"`
	// Reason is has_dispatchable_agent, incomplete_agent or fresh_install.
	Reason string `json:"reason"`
	// HasPartialState says whether part of the setup is done.
	HasPartialState bool `json:"has_partial_state"`
	// Missing lists the steps left, in words.
	Missing []string `json:"missing"`
}

ConfigStatus says whether the setup is complete.

type CostAPI

type CostAPI struct {
	// contains filtered or unexported fields
}

CostAPI holds the cost endpoint, from Client.Cost.

func (CostAPI) Agent

func (a CostAPI) Agent(ctx context.Context, agent string) (*CostSummary, error)

Agent returns one agent's session and daily figures (GET /api/cost?agent=); the gateway ignores a time window here.

func (CostAPI) Summary

func (a CostAPI) Summary(ctx context.Context, from, to string) (*CostSummary, error)

Summary returns the usage in [from, to) (RFC 3339; unbounded when empty), broken down by model and by agent (GET /api/cost).

type CostSummary

type CostSummary struct {
	// SessionCostUSD is the cost of the current session, USD.
	SessionCostUSD float64 `json:"session_cost_usd"`
	// DailyCostUSD is the cost today, USD.
	DailyCostUSD float64 `json:"daily_cost_usd"`
	// MonthlyCostUSD is the cost this month, USD.
	MonthlyCostUSD float64 `json:"monthly_cost_usd"`
	// TotalTokens is the tokens in the window.
	TotalTokens uint64 `json:"total_tokens"`
	// RequestCount is the model calls in the window.
	RequestCount int `json:"request_count"`
	// ByModel is the usage by model.
	ByModel map[string]ModelStats `json:"by_model,omitempty"`
	// ByAgent is the usage by agent.
	ByAgent map[string]AgentCostStats `json:"by_agent,omitempty"`
}

CostSummary holds usage totals.

type CronAPI

type CronAPI struct {
	// contains filtered or unexported fields
}

CronAPI holds the cron endpoints, from Client.Cron.

func (CronAPI) Create

func (a CronAPI) Create(ctx context.Context, job *NewCronJob) (*CronJob, error)

Create creates a job (POST /api/cron).

func (CronAPI) Delete

func (a CronAPI) Delete(ctx context.Context, id string) error

Delete deletes a job (DELETE /api/cron/{id}).

func (CronAPI) List

func (a CronAPI) List(ctx context.Context) ([]CronJob, error)

List returns every job (GET /api/cron).

func (CronAPI) Run

func (a CronAPI) Run(ctx context.Context, id string) (*CronRunResult, error)

Run runs a job now and waits for it (POST /api/cron/{id}/run); the gateway allows up to its long-running timeout, 600 s by default. A failed job still returns no error, with Success false.

func (CronAPI) Runs

func (a CronAPI) Runs(ctx context.Context, id string, limit int) ([]CronRun, error)

Runs returns the job's latest runs (GET /api/cron/{id}/runs): limit 1 to 100, or 0 for the gateway's default, 20.

func (CronAPI) Settings

func (a CronAPI) Settings(ctx context.Context) (*CronSettings, error)

Settings returns the scheduler settings (GET /api/cron/settings).

func (CronAPI) Update

func (a CronAPI) Update(ctx context.Context, id string, patch *CronJobPatch) (*CronJob, error)

Update changes a job; unset fields stay as they are (PATCH /api/cron/{id}).

func (CronAPI) UpdateSettings

func (a CronAPI) UpdateSettings(ctx context.Context, settings *CronSettingsPatch) (*CronSettings, error)

UpdateSettings changes the scheduler settings that are set in settings; saved to the configuration (PATCH /api/cron/settings).

type CronJob

type CronJob struct {
	// ID is the job id.
	ID string `json:"id"`
	// Expression is the schedule expression as written.
	Expression string `json:"expression"`
	// Schedule is the parsed schedule.
	Schedule Schedule `json:"schedule"`
	// Command is the shell command (shell jobs).
	Command string `json:"command"`
	// Prompt is the prompt (agent jobs).
	Prompt *string `json:"prompt,omitempty"`
	// Name is the name.
	Name *string `json:"name,omitempty"`
	// JobType is shell or agent.
	JobType string `json:"job_type"`
	// SessionTarget is isolated or main.
	SessionTarget string `json:"session_target"`
	// Model is the model override (agent jobs).
	Model *string `json:"model,omitempty"`
	// AgentAlias is the agent that owns it.
	AgentAlias string `json:"agent_alias"`
	// Enabled says whether it runs.
	Enabled bool `json:"enabled"`
	// Delivery is where its output goes.
	Delivery Delivery `json:"delivery"`
	// DeleteAfterRun says whether it is deleted after one run.
	DeleteAfterRun bool `json:"delete_after_run"`
	// AllowedTools lists the tools an agent job may use (nil: no
	// restriction).
	AllowedTools []string `json:"allowed_tools,omitempty"`
	// UsesMemory says whether an agent job uses memory.
	UsesMemory bool `json:"uses_memory"`
	// Source is imperative (API, CLI) or declarative (config file).
	Source string `json:"source"`
	// ShellOutputFormat is wrapped or raw (shell jobs).
	ShellOutputFormat *string `json:"shell_output_format,omitempty"`
	// CreatedAt is the creation time (RFC 3339).
	CreatedAt string `json:"created_at"`
	// NextRun is the next run (RFC 3339).
	NextRun string `json:"next_run"`
	// LastRun is the last run (RFC 3339).
	LastRun *string `json:"last_run,omitempty"`
	// LastStatus is the last status.
	LastStatus *string `json:"last_status,omitempty"`
	// LastOutput is the last output.
	LastOutput *string `json:"last_output,omitempty"`
}

CronJob is a scheduled job.

type CronJobPatch

type CronJobPatch struct {
	// Agent is the owning agent; required when changing a shell job's
	// command.
	Agent *string `json:"agent,omitempty"`
	// Name is the name.
	Name *string `json:"name,omitempty"`
	// Schedule is the cron expression.
	Schedule *string `json:"schedule,omitempty"`
	// Tz is the IANA time zone.
	Tz *string `json:"tz,omitempty"`
	// ClearTz removes the time zone.
	ClearTz *bool `json:"clear_tz,omitempty"`
	// Command is the shell command (or an agent job's prompt).
	Command *string `json:"command,omitempty"`
	// Prompt is the agent prompt.
	Prompt *string `json:"prompt,omitempty"`
	// Enabled pauses (false) or resumes the job.
	Enabled *bool `json:"enabled,omitempty"`
	// UsesMemory says whether an agent job uses memory.
	UsesMemory *bool `json:"uses_memory,omitempty"`
	// ShellOutputFormat is wrapped or raw.
	ShellOutputFormat *string `json:"shell_output_format,omitempty"`
}

CronJobPatch holds changes to a job; nil leaves a field as it is.

type CronRun

type CronRun struct {
	// ID is the run id.
	ID int64 `json:"id"`
	// JobID is the job id.
	JobID string `json:"job_id"`
	// StartedAt is the start (RFC 3339).
	StartedAt string `json:"started_at"`
	// FinishedAt is the end (RFC 3339).
	FinishedAt string `json:"finished_at"`
	// Status is the status.
	Status string `json:"status"`
	// Output is the output.
	Output *string `json:"output,omitempty"`
	// DurationMs is the duration.
	DurationMs *int64 `json:"duration_ms,omitempty"`
}

CronRun is a recorded run.

type CronRunResult

type CronRunResult struct {
	// Status is the run status.
	Status string `json:"status"`
	// JobID is the job id.
	JobID string `json:"job_id"`
	// Success says whether the job succeeded.
	Success bool `json:"success"`
	// Output is its output.
	Output string `json:"output"`
	// DurationMs is the duration.
	DurationMs int64 `json:"duration_ms"`
	// StartedAt is the start (RFC 3339).
	StartedAt string `json:"started_at"`
	// FinishedAt is the end (RFC 3339).
	FinishedAt string `json:"finished_at"`
}

CronRunResult is the result of CronAPI.Run.

type CronSettings

type CronSettings struct {
	// Enabled says whether the scheduler runs jobs.
	Enabled bool `json:"enabled"`
	// CatchUpOnStartup says whether missed runs run at startup.
	CatchUpOnStartup bool `json:"catch_up_on_startup"`
	// MaxRunHistory is the number of runs kept per job.
	MaxRunHistory uint32 `json:"max_run_history"`
}

CronSettings are the scheduler settings.

type CronSettingsPatch

type CronSettingsPatch struct {
	// Enabled says whether the scheduler runs jobs.
	Enabled *bool `json:"enabled,omitempty"`
	// CatchUpOnStartup says whether missed runs run at startup.
	CatchUpOnStartup *bool `json:"catch_up_on_startup,omitempty"`
	// MaxRunHistory is the number of runs kept per job.
	MaxRunHistory *uint32 `json:"max_run_history,omitempty"`
}

CronSettingsPatch holds changes to the scheduler settings; nil leaves a setting as it is.

type Decision

type Decision struct {
	// Kind is approve, deny, amend or revise.
	Kind string
	// Reason says why, for deny ("" for none).
	Reason string
	// Text is the checkpoint's new text, for amend.
	Text string
	// Guidance is how to redo the step, for revise.
	Guidance string
}

Decision is an answer to a waiting SOP run, built with ApproveDecision, DenyDecision, AmendDecision or ReviseDecision. It encodes externally tagged: "approve", {"deny": {"reason": …}}, {"amend": {"text": …}} or {"revise": {"guidance": …}}.

func AmendDecision

func AmendDecision(text string) Decision

AmendDecision changes the checkpoint's text and goes on.

func ApproveDecision

func ApproveDecision() Decision

ApproveDecision goes on.

func DenyDecision

func DenyDecision(reason string) Decision

DenyDecision stops the run; reason may be "".

func ReviseDecision

func ReviseDecision(guidance string) Decision

ReviseDecision redoes the step with guidance.

func (Decision) MarshalJSON

func (d Decision) MarshalJSON() ([]byte, error)

MarshalJSON encodes d externally tagged, as the gateway expects.

type DeletePlan

type DeletePlan struct {
	// Path is the map section.
	Path string `json:"path"`
	// Key is the alias.
	Key string `json:"key"`
	// Allowed says whether the delete would go through.
	Allowed bool `json:"allowed"`
	// Blockers are the references that block it.
	Blockers []ReferenceSite `json:"blockers"`
	// Scrubs are the references it would clear.
	Scrubs []ReferenceSite `json:"scrubs"`
	// LiveACPSessions counts, for agents, the live ACP sessions (they block
	// the delete).
	LiveACPSessions *int `json:"live_acp_sessions,omitempty"`
	// CascadesOwnedState says whether the agent's memory, cron jobs and
	// sessions go too.
	CascadesOwnedState bool `json:"cascades_owned_state"`
}

DeletePlan says what deleting an alias would do.

type Delivery

type Delivery struct {
	// Mode is none or announce (post it on a channel).
	Mode string `json:"mode"`
	// Channel is the channel, as type.alias.
	Channel *string `json:"channel,omitempty"`
	// To is the recipient on the channel.
	To *string `json:"to,omitempty"`
	// ThreadID is the thread to post in.
	ThreadID *string `json:"thread_id,omitempty"`
	// BestEffort says whether a delivery failure leaves the run successful
	// (true when absent from the JSON).
	BestEffort bool `json:"best_effort"`
}

Delivery is where a job's output goes.

func AnnounceDelivery

func AnnounceDelivery(channel, to string) Delivery

AnnounceDelivery posts the output to to on channel (type.alias).

func (*Delivery) UnmarshalJSON

func (d *Delivery) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a delivery, BestEffort defaulting to true.

type Device

type Device struct {
	// ID is the device id.
	ID string `json:"id"`
	// Name is the name given at pairing.
	Name *string `json:"name,omitempty"`
	// DeviceType is the type given at pairing (legacy for tokens older than
	// the registry).
	DeviceType *string `json:"device_type,omitempty"`
	// PairedAt is when it paired (RFC 3339).
	PairedAt string `json:"paired_at"`
	// LastSeen is when it was last seen (RFC 3339).
	LastSeen string `json:"last_seen"`
	// IPAddress is the address it paired from.
	IPAddress *string `json:"ip_address,omitempty"`
	// Capabilities are the advertised capabilities.
	Capabilities []string `json:"capabilities,omitempty"`
}

Device is a paired device.

type Diagnostic

type Diagnostic struct {
	// Severity is "ok", "warn" or "error".
	Severity string `json:"severity"`
	// Category is the area checked.
	Category string `json:"category"`
	// Message is the finding.
	Message string `json:"message"`
}

Diagnostic is one diagnostic.

type DoctorReport

type DoctorReport struct {
	// Results holds each check.
	Results []Diagnostic `json:"results"`
	// Summary counts the results by severity.
	Summary DoctorSummary `json:"summary"`
}

DoctorReport is the result of SystemAPI.Doctor.

type DoctorSummary

type DoctorSummary struct {
	// OK is the number of checks passed.
	OK int `json:"ok"`
	// Warnings is the number of warnings.
	Warnings int `json:"warnings"`
	// Errors is the number of errors.
	Errors int `json:"errors"`
}

DoctorSummary holds the counts of a doctor run.

type DriftEntry

type DriftEntry struct {
	// Path is the dotted path.
	Path string `json:"path"`
	// Secret says whether it is a secret (no values shown).
	Secret bool `json:"secret"`
	// Drifted is always true.
	Drifted bool `json:"drifted"`
	// InMemoryValue is the gateway's value.
	InMemoryValue json.RawMessage `json:"in_memory_value,omitempty"`
	// OnDiskValue is the value in config.toml.
	OnDiskValue json.RawMessage `json:"on_disk_value,omitempty"`
}

DriftEntry is a field whose value on disk differs from the gateway's.

type Event

type Event map[string]json.RawMessage

Event is one event, as the gateway sent it: its top-level fields, each kept as raw JSON.

func (Event) Decode

func (e Event) Decode(field string, out any) error

Decode decodes field into out; it fails when the field is absent.

func (Event) IsLog

func (e Event) IsLog() bool

IsLog reports whether it is a structured log event (@timestamp, event, service, zeroclaw attribution).

func (Event) Kind

func (e Event) Kind() string

Kind is the event's "type" (agent_end, cron_result, …); empty for log events.

type EventStream

type EventStream struct {
	// contains filtered or unexported fields
}

EventStream is the live stream of EventsAPI.Subscribe. Read it with EventStream.Next and close it when done.

func (*EventStream) Close

func (s *EventStream) Close() error

Close closes the stream.

func (*EventStream) Next

func (s *EventStream) Next() (Event, error)

Next returns the next event. It returns io.EOF once the gateway closed the stream. A frame that is not JSON is an error wrapping ErrDecode; the stream goes on after it. Any other error ends the stream.

type EventsAPI

type EventsAPI struct {
	// contains filtered or unexported fields
}

EventsAPI holds the event endpoints, from Client.Events.

func (EventsAPI) History

func (a EventsAPI) History(ctx context.Context) ([]Event, error)

History returns the latest observer events, oldest first (up to 500, kept in memory): GET /api/events/history.

func (EventsAPI) Subscribe

func (a EventsAPI) Subscribe(ctx context.Context) (*EventStream, error)

Subscribe opens the live stream (GET /api/events). The stream ends when the gateway closes the connection (e.g. on reload); subscribe again to resume. The client's timeout bounds only the wait for the stream to open, never the stream itself; ctx bounds the whole stream.

Example
package main

import (
	"context"
	"errors"
	"fmt"
	"io"
	"log"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	client, _ := zeroclaw.New("http://127.0.0.1:42617", zeroclaw.WithToken("zc_…"))
	events, err := client.Events().Subscribe(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	defer events.Close()
	for {
		event, err := events.Next()
		if errors.Is(err, io.EOF) {
			return // the gateway closed the stream; subscribe again to resume
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(event.Kind())
	}
}

type Feed

type Feed struct {
	// contains filtered or unexported fields
}

Feed is a live WebSocket feed of JSON frames the gateway pushes (canvas, SOP runs). Read it with Feed.Next and close it when done.

func (*Feed) Close

func (f *Feed) Close() error

Close closes the feed.

func (*Feed) Next

func (f *Feed) Next(ctx context.Context) (json.RawMessage, error)

Next returns the next frame, or io.EOF once the gateway closed the feed. A frame that is not JSON is an error wrapping ErrDecode; the feed goes on after it. Cancelling ctx while it waits closes the feed.

type FileContent

type FileContent struct {
	// Path is the file.
	Path string `json:"path"`
	// Size is its size in bytes.
	Size uint64 `json:"size"`
	// IsText says whether it is text.
	IsText bool `json:"is_text"`
	// Content is the content, in Encoding.
	Content string `json:"content"`
	// Encoding is utf8 or base64.
	Encoding string `json:"encoding"`
}

FileContent is a file's content.

type FileEntry

type FileEntry struct {
	// Name is the entry's name.
	Name string `json:"name"`
	// Kind is dir or file.
	Kind string `json:"kind"`
	// Size is the size of a file.
	Size *uint64 `json:"size,omitempty"`
	// Protected says whether it may not be changed.
	Protected bool `json:"protected"`
}

FileEntry is a directory entry.

type FileListing

type FileListing struct {
	// Path is the directory.
	Path string `json:"path"`
	// Entries are the directories first, then the files, alphabetically.
	Entries []FileEntry `json:"entries"`
}

FileListing is a directory's entries.

type FilesAPI

type FilesAPI struct {
	// contains filtered or unexported fields
}

FilesAPI holds the shared-directory and upload endpoints, from Client.Files.

func (FilesAPI) List

func (a FilesAPI) List(ctx context.Context, path string) (*FileListing, error)

List returns a directory of the shared area, its root when path is empty (GET /api/browse).

func (FilesAPI) MakeDir

func (a FilesAPI) MakeDir(ctx context.Context, path string) error

MakeDir creates a directory (POST /api/browse/mkdir).

func (FilesAPI) RemoveDir

func (a FilesAPI) RemoveDir(ctx context.Context, path string) error

RemoveDir removes a directory and its contents (DELETE /api/browse/rmdir).

func (FilesAPI) UploadImage

func (a FilesAPI) UploadImage(ctx context.Context, agent string, image []byte) (*Upload, error)

UploadImage stores an image (PNG, JPEG, GIF or WebP, told by its bytes) in agent's workspace and returns the marker that attaches it to a chat message (POST /api/upload).

type Health

type Health struct {
	// Status is always "ok" while the gateway answers.
	Status string `json:"status"`
	// Paired is whether at least one client is paired.
	Paired bool `json:"paired"`
	// RequirePairing is whether requests need a bearer token.
	RequirePairing bool `json:"require_pairing"`
	// Runtime is the component health (raw when the gateway could not
	// serialize it).
	Runtime json.RawMessage `json:"runtime"`
}

Health is the answer of GET /health.

type HealthSnapshot

type HealthSnapshot struct {
	// PID is the daemon process id.
	PID uint32 `json:"pid"`
	// UpdatedAt is when it was computed (RFC 3339).
	UpdatedAt string `json:"updated_at"`
	// UptimeSeconds is the time since the daemon started.
	UptimeSeconds uint64 `json:"uptime_seconds"`
	// Components is the health per component (gateway,
	// channel:whatsapp.x, …).
	Components map[string]ComponentHealth `json:"components"`
}

HealthSnapshot is the runtime's component health.

type Integration

type Integration struct {
	// Name is the integration's name.
	Name string `json:"name"`
	// Description says what it does.
	Description string `json:"description"`
	// Category is "Chat", "AiModel", "ToolsAutomation" or "Platform".
	Category string `json:"category"`
	// CategoryLabel is the category in words.
	CategoryLabel string `json:"category_label"`
	// Status is "Available" or "Active".
	Status string `json:"status"`
}

Integration is an integration.

type IntegrationSetting

type IntegrationSetting struct {
	// Enabled is whether it is active.
	Enabled bool `json:"enabled"`
	// Category is its category.
	Category string `json:"category"`
	// Status is its status.
	Status string `json:"status"`
}

IntegrationSetting is an integration's state.

type LogPage

type LogPage struct {
	// Events are the log events (OpenTelemetry-like JSON, see ZeroClaw's
	// LogEvent).
	Events []json.RawMessage `json:"events"`
	// NextCursorLineOffset is the cursor for the next (older) page.
	NextCursorLineOffset *uint64 `json:"next_cursor_line_offset,omitempty"`
	// AtEnd is whether this is the oldest page.
	AtEnd bool `json:"at_end"`
	// DaemonStartedAt is when the daemon started.
	DaemonStartedAt string `json:"daemon_started_at"`
	// AttributionKeys are the attribution fields that can be filtered on.
	AttributionKeys []string `json:"attribution_keys,omitempty"`
}

LogPage is a page of SystemAPI.Logs.

type LogQuery

type LogQuery struct {
	// SinceTS keeps events at or after (RFC 3339).
	SinceTS string
	// UntilTS keeps events before (RFC 3339).
	UntilTS string
	// UntilLineOffset is the paging cursor: the previous page's
	// NextCursorLineOffset.
	UntilLineOffset *uint64
	// Action is the event action.
	Action string
	// Category is the event category.
	Category string
	// Outcome is the event outcome.
	Outcome string
	// SeverityMin is the minimum severity number.
	SeverityMin int
	// TraceID is the trace id.
	TraceID string
	// Q is free text.
	Q string
	// HideInternal leaves out the daemon's internal events.
	HideInternal bool
	// Limit is the page size (gateway default 200).
	Limit int
	// Attributes are exact matches on attribution fields (agent_alias,
	// channel, session_key, tool, …).
	Attributes map[string]string
}

LogQuery holds the filters of SystemAPI.Logs. Empty strings, zero numbers and a nil UntilLineOffset are not sent.

type MapKeyResponse

type MapKeyResponse struct {
	// Path is the map section.
	Path string `json:"path"`
	// Key is the alias.
	Key string `json:"key"`
	// Created says whether a new alias was created.
	Created bool `json:"created"`
	// Warnings lists cleanup steps that failed after the change was saved.
	Warnings []string `json:"warnings,omitempty"`
}

MapKeyResponse is the result of creating or deleting a map alias.

type MemoryAPI

type MemoryAPI struct {
	// contains filtered or unexported fields
}

MemoryAPI holds the memory endpoints, from Client.Memory.

func (MemoryAPI) Forget

func (a MemoryAPI) Forget(ctx context.Context, key, agent string) (bool, error)

Forget forgets an entry of agent's memory (the shared one when agent is empty) and reports whether it existed (DELETE /api/memory/{key}).

func (MemoryAPI) Search

func (a MemoryAPI) Search(ctx context.Context, filter MemoryQuery) ([]MemoryEntry, error)

Search returns, with a text or time filter, the best matches (at most 50); otherwise every entry (of Category, when set) (GET /api/memory). Contents longer than 4096 characters come truncated.

func (MemoryAPI) Store

func (a MemoryAPI) Store(ctx context.Context, key, content, category, agent string) error

Store stores content under key (category core unless category is set), in agent's memory or, when agent is empty, the shared one (POST /api/memory).

type MemoryEntry

type MemoryEntry struct {
	// ID is the entry id.
	ID string `json:"id"`
	// Key is the key.
	Key string `json:"key"`
	// Content is the content.
	Content string `json:"content"`
	// Category is the category.
	Category string `json:"category"`
	// Timestamp is when it was stored.
	Timestamp string `json:"timestamp"`
	// SessionID is the session it came from.
	SessionID *string `json:"session_id,omitempty"`
	// Score is the relevance of a recall match.
	Score *float64 `json:"score,omitempty"`
	// Namespace is the namespace.
	Namespace *string `json:"namespace,omitempty"`
	// Importance is the importance.
	Importance *float64 `json:"importance,omitempty"`
	// SupersededBy is the entry that replaced it.
	SupersededBy *string `json:"superseded_by,omitempty"`
	// Kind is "episodic", "procedural" or {"semantic": "fact"|…}.
	Kind json.RawMessage `json:"kind,omitempty"`
	// Pinned says whether it is pinned.
	Pinned bool `json:"pinned"`
	// AgentAlias is the owning agent.
	AgentAlias *string `json:"agent_alias,omitempty"`
}

MemoryEntry is a memory entry.

type MemoryQuery

type MemoryQuery struct {
	// Query is the text to recall by.
	Query string
	// Category is an exact category (core, daily, conversation or custom).
	Category string
	// Since keeps entries at or after it (RFC 3339).
	Since string
	// Until keeps entries before it (RFC 3339).
	Until string
	// Agent searches an agent's memory instead of the shared one.
	Agent string
}

MemoryQuery holds the filters of MemoryAPI.Search; empty ones are not sent.

type Middleware

type Middleware func(next http.RoundTripper) http.RoundTripper

Middleware wraps the client's HTTP transport (metrics, tracing, request signing, a circuit breaker, …). See WithMiddleware.

type MigrateResponse

type MigrateResponse struct {
	// Migrated says whether the file changed.
	Migrated bool `json:"migrated"`
	// BackupPath is where the previous file was kept.
	BackupPath *string `json:"backup_path,omitempty"`
	// SchemaVersion is the schema version now on disk.
	SchemaVersion int `json:"schema_version"`
}

MigrateResponse is the result of ConfigAPI.Migrate.

type ModelPricing

type ModelPricing struct {
	// Prompt is the input price.
	Prompt *string `json:"prompt,omitempty"`
	// Completion is the output price.
	Completion *string `json:"completion,omitempty"`
	// InputCacheRead is the cached input read price.
	InputCacheRead *string `json:"input_cache_read,omitempty"`
	// InputCacheWrite is the cached input write price.
	InputCacheWrite *string `json:"input_cache_write,omitempty"`
}

ModelPricing is a model's prices as the provider states them.

type ModelStats

type ModelStats struct {
	// Model is the model.
	Model string `json:"model"`
	// CostUSD is the cost, USD.
	CostUSD float64 `json:"cost_usd"`
	// InputTokens is the input tokens.
	InputTokens uint64 `json:"input_tokens"`
	// CachedInputTokens is the cached input tokens.
	CachedInputTokens uint64 `json:"cached_input_tokens"`
	// OutputTokens is the output tokens.
	OutputTokens uint64 `json:"output_tokens"`
	// TotalTokens is all tokens.
	TotalTokens uint64 `json:"total_tokens"`
	// RequestCount is the calls.
	RequestCount int `json:"request_count"`
}

ModelStats is one model's usage.

type NewCronJob

type NewCronJob struct {
	// Agent is the owning agent (must be configured).
	Agent string `json:"agent"`
	// Schedule is the cron expression.
	Schedule string `json:"schedule"`
	// Name is the name.
	Name string `json:"name,omitempty"`
	// Tz is the IANA time zone of the schedule.
	Tz string `json:"tz,omitempty"`
	// Command is the shell command.
	Command string `json:"command,omitempty"`
	// JobType is shell or agent.
	JobType string `json:"job_type,omitempty"`
	// Prompt is the agent prompt.
	Prompt string `json:"prompt,omitempty"`
	// Delivery is where the output goes.
	Delivery *Delivery `json:"delivery,omitempty"`
	// SessionTarget is isolated (default) or main.
	SessionTarget string `json:"session_target,omitempty"`
	// Model is the model override.
	Model string `json:"model,omitempty"`
	// AllowedTools lists the tools an agent job may use (nil: no
	// restriction; a pointer to an empty list: none).
	AllowedTools *[]string `json:"allowed_tools,omitempty"`
	// DeleteAfterRun deletes the job after its first run.
	DeleteAfterRun *bool `json:"delete_after_run,omitempty"`
	// UsesMemory says whether an agent job uses memory (default true).
	UsesMemory *bool `json:"uses_memory,omitempty"`
	// ShellOutputFormat is wrapped (default) or raw: how a shell job's
	// output is announced.
	ShellOutputFormat string `json:"shell_output_format,omitempty"`
}

NewCronJob is a job to create. Shell jobs need Command; agent jobs Prompt (and JobType "agent", implied by a prompt).

type Option

type Option func(*settings)

Option configures a Client.

func WithCircuitBreaker

func WithCircuitBreaker(st gobreaker.Settings) Option

WithCircuitBreaker stops calling a gateway that keeps failing: once ReadyToTrip says so (by default after 5 failures in a row), calls fail at once with ErrCircuitOpen until Timeout (default 30 s) has passed and a trial call works. A transport error, a 5xx, 408 or 429 count as failures; the caller's own cancellations do not. The breaker is shared by every copy of the client, and sees one logical call (its retries included).

func WithConcurrencyLimit

func WithConcurrencyLimit(max int) Option

WithConcurrencyLimit lets at most max requests wait for the gateway's answer at once, shared by every copy of the client; the rest wait their turn. A request holds its slot until the answer's headers arrive, retries and their backoff included; reading a body (an open event stream) holds none.

func WithMiddleware

func WithMiddleware(m ...Middleware) Option

WithMiddleware wraps every HTTP request in middleware of your own (metrics, tracing, request signing, a circuit breaker, …). Middleware added first is outermost: it sees the request first and the response last, around the client's own retry and timeout. An error it returns is returned wrapped; errors.Is and errors.As reach it.

Example
package main

import (
	"log"
	"net/http"

	zeroclaw "github.com/RustLangLatam/zeroclaw-api-client-go"
)

func main() {
	caller := func(next http.RoundTripper) http.RoundTripper {
		return zeroclaw.RoundTripperFunc(func(r *http.Request) (*http.Response, error) {
			r = r.Clone(r.Context())
			r.Header.Set("X-Caller", "billing")
			return next.RoundTrip(r)
		})
	}
	client, err := zeroclaw.New("http://127.0.0.1:42617",
		zeroclaw.WithToken("zc_…"),
		zeroclaw.WithMiddleware(caller))
	if err != nil {
		log.Fatal(err)
	}
	_ = client
}

func WithRateLimit

func WithRateLimit(r rate.Limit, burst int) Option

WithRateLimit keeps the client under r requests per second with bursts of up to burst, shared by every copy of the client. Every attempt, retries included, waits for its turn; a wait that would outlast the caller's deadline fails at once with ErrRateLimited.

func WithRetry

func WithRetry(p RetryPolicy) Option

WithRetry sets how failed idempotent requests are retried (default DefaultRetryPolicy). NoRetries turns retries off.

func WithTimeout

func WithTimeout(d time.Duration) Option

WithTimeout sets how long a request waits for the gateway's answer (default DefaultTimeout). It bounds the headers only, so the event stream is not cut; long gateway calls (a manual cron run) use their own, longer limit. Zero or less waits without limit.

func WithToken

func WithToken(token string) Option

WithToken sets the bearer token sent with every request (obtained by pairing, see PairingAPI). Without one, only public endpoints answer.

func WithTransport

func WithTransport(rt http.RoundTripper) Option

WithTransport uses an existing transport (its proxy, TLS and connection settings apply); the client's timeout and retry still wrap it. It also carries the WebSocket handshakes, so it must support HTTP/1.1 upgrades (*http.Transport does).

type Paired

type Paired struct {
	// Paired is always true.
	Paired bool `json:"paired"`
	// Persisted says whether the token was saved in the gateway's
	// configuration.
	Persisted bool `json:"persisted,omitempty"`
	// Token is the bearer token. Keep it secret.
	Token string `json:"token"`
	// Message is the gateway's note.
	Message *string `json:"message,omitempty"`
}

Paired is a successful pairing. Its String and GoString hide the token.

func (Paired) GoString

func (p Paired) GoString() string

GoString hides the token from %#v too.

func (Paired) String

func (p Paired) String() string

String describes the pairing without its token, so it never reaches logs.

type PairingAPI

type PairingAPI struct {
	// contains filtered or unexported fields
}

PairingAPI holds the pairing endpoints, from Client.Pairing.

func (PairingAPI) AdminCode

func (a PairingAPI) AdminCode(ctx context.Context) (*PairingCode, error)

AdminCode returns the pending pairing code (GET /admin/paircode). Loopback only.

func (PairingAPI) AdminNewCode

func (a PairingAPI) AdminNewCode(ctx context.Context, rotate string) (*PairingCode, error)

AdminNewCode mints a pairing code (POST /admin/paircode/new). A non-empty rotate revokes first: "all" every token and device, otherwise the device with that id. Loopback only.

func (PairingAPI) Devices

func (a PairingAPI) Devices(ctx context.Context) ([]Device, error)

Devices returns the paired devices (GET /api/devices).

func (PairingAPI) InitialCode

func (a PairingAPI) InitialCode(ctx context.Context) (*PairingCode, error)

InitialCode returns the first-run pairing code, shown only while no client is paired yet (GET /pair/code). Public.

func (PairingAPI) NewCode

func (a PairingAPI) NewCode(ctx context.Context) (string, error)

NewCode mints a new pairing code (replacing a pending one) so another device can pair (POST /api/pairing/initiate).

func (PairingAPI) Pair

func (a PairingAPI) Pair(ctx context.Context, code, deviceName, deviceType string) (*Paired, error)

Pair exchanges a pairing code for a bearer token, registering this client as a device (POST /api/pair). Empty deviceName and deviceType are sent as null. Public.

func (PairingAPI) PairLegacy

func (a PairingAPI) PairLegacy(ctx context.Context, code string) (*Paired, error)

PairLegacy is the original pairing call, with the code in the X-Pairing-Code header (POST /pair). Public.

func (PairingAPI) RevokeDevice

func (a PairingAPI) RevokeDevice(ctx context.Context, id string) error

RevokeDevice revokes a device and its token; it may be this client's own (DELETE /api/devices/{id}).

func (PairingAPI) RotateDeviceToken

func (a PairingAPI) RotateDeviceToken(ctx context.Context, id string) (string, error)

RotateDeviceToken revokes a device's token and mints a pairing code for it to pair again; the code is empty when one was already pending or pairing is off (POST /api/devices/{id}/token/rotate).

func (PairingAPI) SetCapabilities

func (a PairingAPI) SetCapabilities(ctx context.Context, capabilities []string) ([]string, error)

SetCapabilities replaces the capabilities this client's device advertises and returns them (POST /api/devices/me/capabilities).

type PairingCode

type PairingCode struct {
	// Success says whether the request succeeded.
	Success bool `json:"success,omitempty"`
	// PairingRequired says whether the gateway requires pairing.
	PairingRequired bool `json:"pairing_required"`
	// PairingCode is the six-digit code, when one is pending and may be
	// shown.
	PairingCode *string `json:"pairing_code,omitempty"`
	// Message is the gateway's note.
	Message *string `json:"message,omitempty"`
}

PairingCode is a pairing code and whether pairing is required.

type PatchOp

type PatchOp struct {
	// Op is add, replace, remove, test or comment.
	Op string `json:"op"`
	// Path is dotted, or a JSON Pointer (/a/b).
	Path string `json:"path"`
	// Value is the value for add, replace and test, encoded as JSON.
	Value any `json:"value,omitempty"`
	// Comment is the TOML comment written above the key.
	Comment string `json:"comment,omitempty"`
}

PatchOp is one operation of a ConfigAPI.Patch: RFC 6902 add, replace, remove and test, plus ZeroClaw's comment.

func AddOp

func AddOp(path string, value any) PatchOp

AddOp sets path to value, creating the map alias it implies.

func CommentOp

func CommentOp(path, comment string) PatchOp

CommentOp writes comment above the key of path.

func RemoveOp

func RemoveOp(path string) PatchOp

RemoveOp resets path to its default.

func ReplaceOp

func ReplaceOp(path string, value any) PatchOp

ReplaceOp sets path to value.

func TestOp

func TestOp(path string, value any) PatchOp

TestOp fails the whole patch unless path currently displays as value.

type PatchOpResult

type PatchOpResult struct {
	// Op is the operation.
	Op string `json:"op"`
	// Path is the dotted path.
	Path string `json:"path"`
	// Value is the new display value (absent for secrets and comments).
	Value json.RawMessage `json:"value,omitempty"`
	// Populated says, for secrets, whether it now has a value.
	Populated *bool `json:"populated,omitempty"`
	// Comment is, for comment, the comment written.
	Comment *string `json:"comment,omitempty"`
}

PatchOpResult is what one patch operation left.

type PatchResponse

type PatchResponse struct {
	// Saved is always true on success: the patch was saved.
	Saved bool `json:"saved"`
	// Results holds one result per operation, in order.
	Results []PatchOpResult `json:"results"`
	// Warnings lists validation problems outside the patched paths.
	Warnings []ValidationWarning `json:"warnings,omitempty"`
}

PatchResponse is the result of a ConfigAPI.Patch.

type PendingApproval

type PendingApproval struct {
	// RunID is the run id.
	RunID string `json:"run_id"`
	// SopName is the SOP.
	SopName string `json:"sop_name"`
	// Step is the step waiting.
	Step uint32 `json:"step"`
	// TotalSteps is the number of steps in all.
	TotalSteps uint32 `json:"total_steps"`
	// WaitingSince is since when.
	WaitingSince *string `json:"waiting_since,omitempty"`
	// Kind is approval or checkpoint.
	Kind string `json:"kind"`
}

PendingApproval is a run waiting for an operator.

type PersonalityContext

type PersonalityContext struct {
	AgentName          string
	UserName           string
	Timezone           string
	CommunicationStyle string
	// IncludeMemory, when set, says whether to render MEMORY.md.
	IncludeMemory *bool
}

PersonalityContext fills the default personality files rendered by AgentAPI.PersonalityTemplates; empty fields are not sent.

type PersonalityFile

type PersonalityFile struct {
	// Filename is the file name.
	Filename string `json:"filename"`
	// Content is the content (absent when the file does not exist).
	Content *string `json:"content,omitempty"`
	// Exists says whether it exists.
	Exists bool `json:"exists"`
	// Truncated says whether the content was cut at the size limit.
	Truncated bool `json:"truncated"`
	// MtimeMs is its modification time, for [AgentAPI.WritePersonality].
	MtimeMs *int64 `json:"mtime_ms,omitempty"`
}

PersonalityFile is a personality file's content.

type PersonalityFileEntry

type PersonalityFileEntry struct {
	// Filename is the file name.
	Filename string `json:"filename"`
	// Exists says whether it exists.
	Exists bool `json:"exists"`
	// Size is its size in bytes.
	Size uint64 `json:"size"`
	// MtimeMs is its modification time, ms since the epoch.
	MtimeMs *int64 `json:"mtime_ms,omitempty"`
}

PersonalityFileEntry is a personality file's presence.

type PersonalityFiles

type PersonalityFiles struct {
	// Files holds each editable file.
	Files []PersonalityFileEntry `json:"files"`
	// MaxChars is the maximum characters per file.
	MaxChars int `json:"max_chars"`
}

PersonalityFiles lists the personality files of an agent.

type PersonalityTemplates

type PersonalityTemplates struct {
	// Preset is the preset used.
	Preset string `json:"preset"`
	// Files holds each file: {filename, content}.
	Files []json.RawMessage `json:"files"`
}

PersonalityTemplates are the rendered default personality files.

type PersonalityWritten

type PersonalityWritten struct {
	// BytesWritten is the number of bytes written.
	BytesWritten uint64 `json:"bytes_written"`
	// MtimeMs is the new modification time.
	MtimeMs *int64 `json:"mtime_ms,omitempty"`
}

PersonalityWritten is the result of AgentAPI.WritePersonality.

type ProcessStats

type ProcessStats struct {
	// RSSBytes is the resident memory.
	RSSBytes uint64 `json:"rss_bytes"`
	// SystemRAMTotalBytes is the host memory.
	SystemRAMTotalBytes uint64 `json:"system_ram_total_bytes"`
	// CPUPercent is the CPU use.
	CPUPercent *float64 `json:"cpu_percent,omitempty"`
	// NumCPUs is the number of host CPUs.
	NumCPUs uint32 `json:"num_cpus"`
}

ProcessStats is the daemon's resource use.

type PropValue

type PropValue struct {
	// Path is the dotted path.
	Path string `json:"path"`
	// Value is the gateway's display value (null after a reset); absent
	// for secrets.
	Value json.RawMessage `json:"value,omitempty"`
	// Warnings lists validation problems of the configuration.
	Warnings []ValidationWarning `json:"warnings,omitempty"`
	// Populated says, for a secret, whether it has a value.
	Populated *bool `json:"populated,omitempty"`
}

PropValue is a field as GET, PUT and DELETE /api/config/prop return it: a regular field carries Value, a secret only Populated.

func (*PropValue) IsSecret

func (p *PropValue) IsSecret() bool

IsSecret reports whether the field is a secret (only Populated is known).

type QuickstartAPI

type QuickstartAPI struct {
	// contains filtered or unexported fields
}

QuickstartAPI holds the quickstart endpoints, from Client.Quickstart.

func (QuickstartAPI) Apply

func (a QuickstartAPI) Apply(ctx context.Context, submission any) (json.RawMessage, error)

Apply saves a submission (POST /api/quickstart/apply). On {"kind": "applied", …, "daemon_restarted": true} the gateway drops connections briefly while it reloads.

func (QuickstartAPI) Dismiss

func (a QuickstartAPI) Dismiss(ctx context.Context, runID, surface, lastStep string) error

Dismiss records that the quickstart was closed (POST /api/quickstart/dismiss). surface is web, tui, cli or test; lastStep may be "".

func (QuickstartAPI) Fields

func (a QuickstartAPI) Fields(ctx context.Context, section, typeKey string) (json.RawMessage, error)

Fields returns the fields a section (model_provider, channel or peer_group) of type typeKey needs (POST /api/quickstart/fields).

func (QuickstartAPI) State

State returns what exists and what can be chosen: provider and channel types, presets, memory kinds, … (GET /api/quickstart/state).

func (QuickstartAPI) Validate

func (a QuickstartAPI) Validate(ctx context.Context, submission any) (json.RawMessage, error)

Validate checks a submission, encoded as JSON (POST /api/quickstart/validate): {"kind": "ok"} or {"kind": "errors", "errors": […]}.

type ReferenceSite

type ReferenceSite struct {
	// Path is the dotted path of the referencing field.
	Path string `json:"path"`
	// RawValue is its raw value.
	RawValue string `json:"raw_value"`
}

ReferenceSite is a field that references an alias.

type Relinked

type Relinked struct {
	// Channel is the channel.
	Channel string `json:"channel"`
	// Outcome is cleared or nothing_to_clear.
	Outcome string `json:"outcome"`
	// Removed lists the files removed.
	Removed []string `json:"removed,omitempty"`
	// RestartRequired says whether a reload is needed for the channel to
	// pair again.
	RestartRequired bool `json:"restart_required,omitempty"`
	// Note is the gateway's note.
	Note *string `json:"note,omitempty"`
}

Relinked is the result of ChannelsAPI.Relink.

type RenameResponse

type RenameResponse struct {
	// Path is the map section.
	Path string `json:"path"`
	// From is the old alias.
	From string `json:"from"`
	// To is the new alias.
	To string `json:"to"`
	// Renamed says whether it was renamed.
	Renamed bool `json:"renamed"`
	// Warnings lists follow-up steps that failed (re-sending the rename
	// finishes them).
	Warnings []string `json:"warnings,omitempty"`
}

RenameResponse is the result of ConfigAPI.RenameMapKey.

type RetryPolicy

type RetryPolicy struct {
	// MaxRetries is how many times a request is tried again at most.
	MaxRetries int
	// BaseDelay is the wait before the first retry.
	BaseDelay time.Duration
	// MaxDelay caps the wait between retries.
	MaxDelay time.Duration
	// Jitter randomizes each wait between half and all of its delay.
	Jitter bool
}

RetryPolicy says when and how often a failed idempotent request is tried again. The delay before retry n (0-based) is BaseDelay × 2ⁿ, capped at MaxDelay; with Jitter, the wait is a random point in its upper half, so clients that failed together do not retry together. The zero value makes no retries.

func DefaultRetryPolicy

func DefaultRetryPolicy() RetryPolicy

DefaultRetryPolicy is three retries, 200 ms then doubling, at most 5 s apart, with jitter.

func NoRetries

func NoRetries() RetryPolicy

NoRetries is a policy that never retries.

func (RetryPolicy) Delay

func (p RetryPolicy) Delay(attempt int) time.Duration

Delay is how long to wait before retry attempt (0-based).

type RoundTripperFunc

type RoundTripperFunc func(*http.Request) (*http.Response, error)

RoundTripperFunc adapts a function to http.RoundTripper, for writing a Middleware inline.

func (RoundTripperFunc) RoundTrip

func (f RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip calls f(r).

type Schedule

type Schedule struct {
	// Kind is cron, at or every.
	Kind string
	// Expr is the cron expression.
	Expr string
	// Tz is the time zone of a cron schedule (nil: UTC).
	Tz *string
	// At is the time of an at schedule (RFC 3339).
	At string
	// EveryMs is the interval of an every schedule.
	EveryMs uint64
}

Schedule is when a job runs. Kind says which fields are set: cron (Expr, in Tz, an IANA zone, or UTC), at (At, RFC 3339) or every (EveryMs milliseconds). Build one with CronSchedule, AtSchedule or EverySchedule.

func AtSchedule

func AtSchedule(at string) Schedule

AtSchedule runs once, at at (RFC 3339).

func CronSchedule

func CronSchedule(expr, tz string) Schedule

CronSchedule runs on the cron expression expr, in time zone tz (UTC when empty).

func EverySchedule

func EverySchedule(ms uint64) Schedule

EverySchedule runs every ms milliseconds.

func (Schedule) MarshalJSON

func (s Schedule) MarshalJSON() ([]byte, error)

MarshalJSON encodes the schedule as the gateway does: {"kind":"cron","expr":…,"tz":…}, {"kind":"at","at":…} or {"kind":"every","every_ms":…}.

func (*Schedule) UnmarshalJSON

func (s *Schedule) UnmarshalJSON(b []byte) error

UnmarshalJSON decodes a schedule, refusing unknown kinds and missing fields.

type SectionItem

type SectionItem struct {
	// Key is the item key.
	Key string `json:"key"`
	// Label is shown to people.
	Label string `json:"label"`
	// Description describes it.
	Description *string `json:"description,omitempty"`
	// Badge is configured, needs setup, active or created.
	Badge *string `json:"badge,omitempty"`
}

SectionItem is an item of a picker section.

type SectionItems

type SectionItems struct {
	// Section is the section key.
	Section string `json:"section"`
	// Items are the items.
	Items []SectionItem `json:"items"`
	// Help is the help text.
	Help string `json:"help"`
}

SectionItems lists the items of a picker section.

type SelectedItem

type SelectedItem struct {
	// FieldsPrefix is the prefix of the fields to fill ([ConfigAPI.List]).
	FieldsPrefix string `json:"fields_prefix"`
	// Created says whether something was created.
	Created bool `json:"created"`
}

SelectedItem is the result of ConfigAPI.SelectSectionItem.

type Session

type Session struct {
	// SessionID is the display id (gw_ removed).
	SessionID string `json:"session_id"`
	// SessionKey is the full key (gw_…, whatsapp_<channel>_<peer>…).
	SessionKey *string `json:"session_key,omitempty"`
	// CreatedAt is the creation time (RFC 3339).
	CreatedAt string `json:"created_at"`
	// LastActivity is the last activity (RFC 3339).
	LastActivity string `json:"last_activity"`
	// MessageCount is the number of messages in it.
	MessageCount int `json:"message_count"`
	// AgentAlias is the agent that answers it.
	AgentAlias *string `json:"agent_alias,omitempty"`
	// ChannelID is the channel it came through (whatsapp.alias).
	ChannelID *string `json:"channel_id,omitempty"`
	// Name is the name given to it.
	Name *string `json:"name,omitempty"`
}

Session is a stored session.

type SessionMessage

type SessionMessage struct {
	// Role is user, assistant, tool, …
	Role string `json:"role"`
	// Content is the content (tool calls and results are JSON text).
	Content string `json:"content"`
	// CreatedAt is when it was stored.
	CreatedAt *string `json:"created_at,omitempty"`
}

SessionMessage is a message of a transcript.

type SessionState

type SessionState struct {
	// SessionID is the session id as asked.
	SessionID string `json:"session_id"`
	// State is idle, running or error.
	State string `json:"state"`
	// TurnID is the running turn.
	TurnID *string `json:"turn_id,omitempty"`
	// TurnStartedAt is when it started.
	TurnStartedAt *string `json:"turn_started_at,omitempty"`
}

SessionState says whether a session is busy.

type SessionsAPI

type SessionsAPI struct {
	// contains filtered or unexported fields
}

SessionsAPI holds the session endpoints, from Client.Sessions.

func (SessionsAPI) Abort

func (a SessionsAPI) Abort(ctx context.Context, id string) (bool, error)

Abort cancels the running turn and reports whether there was one (POST /api/sessions/{id}/abort).

func (SessionsAPI) AddMessage

func (a SessionsAPI) AddMessage(ctx context.Context, id, content string) error

AddMessage appends an assistant message to the session, shown to chat clients; no agent turn runs (POST /api/sessions/{id}/messages).

func (SessionsAPI) Delete

func (a SessionsAPI) Delete(ctx context.Context, id string) error

Delete cancels its running turn and deletes it (DELETE /api/sessions/{id}).

func (SessionsAPI) List

func (a SessionsAPI) List(ctx context.Context) ([]Session, error)

List returns every stored session, empty when the gateway keeps none (GET /api/sessions).

func (SessionsAPI) Messages

func (a SessionsAPI) Messages(ctx context.Context, id string) ([]SessionMessage, error)

Messages returns the transcript, empty for an unknown session (GET /api/sessions/{id}/messages).

func (SessionsAPI) Rename

func (a SessionsAPI) Rename(ctx context.Context, id, name string) error

Rename renames a session (PUT /api/sessions/{id}).

func (SessionsAPI) Running

func (a SessionsAPI) Running(ctx context.Context) ([]Session, error)

Running returns the gateway (web chat) sessions (GET /api/sessions/running).

func (SessionsAPI) State

func (a SessionsAPI) State(ctx context.Context, id string) (*SessionState, error)

State reports whether a turn is running (GET /api/sessions/{id}/state).

type Skill

type Skill struct {
	// Bundle is the bundle.
	Bundle string `json:"bundle"`
	// Name is the skill's name.
	Name string `json:"name"`
	// Frontmatter is the front matter.
	Frontmatter json.RawMessage `json:"frontmatter"`
	// Body is the Markdown body.
	Body string `json:"body"`
}

Skill is a skill.

type SkillBundle

type SkillBundle struct {
	// Alias is the bundle's alias.
	Alias string `json:"alias"`
	// Directory is its directory.
	Directory string `json:"directory"`
	// Include lists the skills it includes.
	Include []string `json:"include,omitempty"`
	// Exclude lists the skills it leaves out.
	Exclude []string `json:"exclude,omitempty"`
}

SkillBundle is a skill bundle.

type SkillSummary

type SkillSummary struct {
	// Bundle is the bundle.
	Bundle string `json:"bundle"`
	// Name is the skill's name.
	Name string `json:"name"`
	// Directory is its directory.
	Directory string `json:"directory"`
	// Frontmatter is the front matter (name, description, tags,
	// slash_options, …).
	Frontmatter json.RawMessage `json:"frontmatter"`
}

SkillSummary is a skill in a listing.

type SkillsAPI

type SkillsAPI struct {
	// contains filtered or unexported fields
}

SkillsAPI holds the skill endpoints, from Client.Skills.

func (SkillsAPI) Bundles

func (a SkillsAPI) Bundles(ctx context.Context) ([]SkillBundle, error)

Bundles returns the skill bundles (GET /api/skills/bundles).

func (SkillsAPI) Create

func (a SkillsAPI) Create(ctx context.Context, bundle, name string, frontmatter any, body string, noScaffold bool) error

Create creates a skill, with scripts/, references/ and assets/ unless noScaffold (POST /api/skills/bundles/{bundle}/skills). frontmatter is encoded as JSON.

func (SkillsAPI) Delete

func (a SkillsAPI) Delete(ctx context.Context, bundle, name string, purge bool) error

Delete archives a skill, or deletes it for good with purge (DELETE /api/skills/bundles/{bundle}/skills/{name}).

func (SkillsAPI) List

func (a SkillsAPI) List(ctx context.Context, bundle string) ([]SkillSummary, error)

List returns the skills of a bundle (GET /api/skills/bundles/{bundle}/skills).

func (SkillsAPI) Read

func (a SkillsAPI) Read(ctx context.Context, bundle, name string) (*Skill, error)

Read returns a skill (GET /api/skills/bundles/{bundle}/skills/{name}).

func (SkillsAPI) SlashOptionKinds

func (a SkillsAPI) SlashOptionKinds(ctx context.Context) ([]json.RawMessage, error)

SlashOptionKinds returns the option types a skill's slash command may declare (GET /api/skills/slash-option-kinds).

func (SkillsAPI) Write

func (a SkillsAPI) Write(ctx context.Context, bundle, name string, frontmatter any, body string) error

Write replaces a skill's front matter (encoded as JSON) and body (PUT /api/skills/bundles/{bundle}/skills/{name}).

type SopRun

type SopRun struct {
	// RunID is the run id.
	RunID string `json:"run_id"`
	// SopName is the SOP.
	SopName string `json:"sop_name"`
	// Status is pending, running, cancel_requested, waiting_approval,
	// paused_checkpoint, completed, failed or cancelled.
	Status string `json:"status"`
	// CurrentStep is the current step.
	CurrentStep uint32 `json:"current_step"`
	// TotalSteps is the number of steps in all.
	TotalSteps uint32 `json:"total_steps"`
	// StartedAt is the start (RFC 3339).
	StartedAt string `json:"started_at"`
	// CompletedAt is the end.
	CompletedAt *string `json:"completed_at,omitempty"`
	// TriggerSource is what started it.
	TriggerSource string `json:"trigger_source"`
	// Active is whether it is still running.
	Active bool `json:"active"`
}

SopRun is a run in a listing.

type SopsAPI

type SopsAPI struct {
	// contains filtered or unexported fields
}

SopsAPI holds the SOP endpoints, from Client.Sops.

func (SopsAPI) Approve

func (a SopsAPI) Approve(ctx context.Context, runID string) (string, error)

Approve approves a waiting run (POST /admin/sop/approve). It returns the outcome (resumed, already_resolved, pending_quorum (…), …).

func (SopsAPI) Cancel

func (a SopsAPI) Cancel(ctx context.Context, name, runID, reason string) (json.RawMessage, error)

Cancel cancels a run at its next step boundary; reason may be "" (POST /api/sops/{name}/runs/{run_id}/cancel).

func (SopsAPI) Create

func (a SopsAPI) Create(ctx context.Context, sop any) error

Create creates an SOP, 409 when the name exists (POST /api/sops). sop is encoded as JSON.

func (SopsAPI) Decide

func (a SopsAPI) Decide(ctx context.Context, name, runID string, decision Decision) (json.RawMessage, error)

Decide answers a run waiting for approval or at a checkpoint and returns the run overlay (POST /api/sops/{name}/runs/{run_id}/decide).

func (SopsAPI) Delete

func (a SopsAPI) Delete(ctx context.Context, name string) error

Delete deletes an SOP (DELETE /api/sops/{name}).

func (SopsAPI) Deny

func (a SopsAPI) Deny(ctx context.Context, runID, reason string) (string, error)

Deny denies a waiting run; reason may be "" (POST /admin/sop/deny).

func (SopsAPI) Get

func (a SopsAPI) Get(ctx context.Context, name string) (json.RawMessage, error)

Get returns one SOP definition (GET /api/sops/{name}/full).

func (SopsAPI) Graph

func (a SopsAPI) Graph(ctx context.Context, name string) (json.RawMessage, error)

Graph returns the SOP as a node graph with layout and diagnostics (GET /api/sops/{name}/graph).

func (SopsAPI) GraphDraft

func (a SopsAPI) GraphDraft(ctx context.Context, sop any) (json.RawMessage, error)

GraphDraft returns the graph of an unsaved definition (POST /api/sops/graph-draft).

func (SopsAPI) GraphLegend

func (a SopsAPI) GraphLegend(ctx context.Context) (json.RawMessage, error)

GraphLegend says what the graph's roles, pins and run states mean (GET /api/sops/graph-legend).

func (SopsAPI) List

func (a SopsAPI) List(ctx context.Context) ([]json.RawMessage, error)

List returns every SOP definition that loads (GET /api/sops).

func (SopsAPI) Pending

func (a SopsAPI) Pending(ctx context.Context) ([]PendingApproval, error)

Pending returns the runs waiting for an approval or a checkpoint (GET /admin/sop/pending). Loopback, or remote admin with pairing.

func (SopsAPI) Run

func (a SopsAPI) Run(ctx context.Context, name, payload string) (string, error)

Run starts the SOP through its manual trigger (POST /api/sops/{name}/run); payload is JSON text handed to the run ("" for none). It returns the run id (an existing run's when the SOP coalesces).

func (SopsAPI) RunOverlay

func (a SopsAPI) RunOverlay(ctx context.Context, name, runID string) (json.RawMessage, error)

RunOverlay returns a run's state per step, with its tool calls (GET /api/sops/{name}/runs/{run_id}/overlay).

func (SopsAPI) Runs

func (a SopsAPI) Runs(ctx context.Context, sop string) ([]SopRun, error)

Runs returns active and recent runs, newest first, of one SOP when sop is not "" (GET /api/sops/runs).

func (SopsAPI) Save

func (a SopsAPI) Save(ctx context.Context, name string, sop any) error

Save saves an SOP; steps are renumbered 1..N (PUT /api/sops/{name}).

func (SopsAPI) TriggerSources

func (a SopsAPI) TriggerSources(ctx context.Context) (json.RawMessage, error)

TriggerSources returns the trigger sources, their fields and the channels that can start an SOP (GET /api/sops/trigger-sources).

func (SopsAPI) WatchRuns

func (a SopsAPI) WatchRuns(ctx context.Context) (*Feed, error)

WatchRuns follows SOP runs live (GET /ws/sops/runs): a {"type": "snapshot", "runs": […]} first, then {"type": "run", "run": …} on every change (lagged, disabled and error frames too).

func (SopsAPI) WireDraft

func (a SopsAPI) WireDraft(ctx context.Context, sop, edit any) (json.RawMessage, error)

WireDraft applies a wiring edit to an unsaved definition and returns {sop, graph} (POST /api/sops/wire-draft). edit is {op: "connect" | "disconnect", from, to, role, port?}.

type Status

type Status struct {
	// Version is the ZeroClaw version.
	Version string `json:"version"`
	// ModelProvider is the model provider in use, as type.alias.
	ModelProvider *string `json:"model_provider,omitempty"`
	// Model is the model in use.
	Model string `json:"model"`
	// Temperature is the sampling temperature.
	Temperature *float64 `json:"temperature,omitempty"`
	// UptimeSeconds is the time since the daemon started.
	UptimeSeconds uint64 `json:"uptime_seconds"`
	// DaemonStartedAt is when the daemon started (RFC 3339).
	DaemonStartedAt string `json:"daemon_started_at"`
	// GatewayPort is the gateway port.
	GatewayPort uint16 `json:"gateway_port"`
	// Locale is the UI locale.
	Locale string `json:"locale"`
	// MemoryBackend is the memory backend.
	MemoryBackend string `json:"memory_backend"`
	// Paired is whether a client is paired.
	Paired bool `json:"paired"`
	// Channels are the configured channels, as type.alias.
	Channels map[string]bool `json:"channels"`
	// Nodes are the connected nodes and peers found on the network.
	Nodes json.RawMessage `json:"nodes,omitempty"`
	// Health is the component health.
	Health HealthSnapshot `json:"health"`
	// AgentAlias is the agent asked about, if any.
	AgentAlias *string `json:"agent_alias,omitempty"`
	// Process holds the process figures.
	Process *ProcessStats `json:"process,omitempty"`
	// CheckUpdates is whether the daemon checks for updates.
	CheckUpdates bool `json:"check_updates"`
	// AllowSelfUpgrade is whether self-upgrade is allowed.
	AllowSelfUpgrade bool `json:"allow_self_upgrade"`
	// RestartMode is "supervised", "self_respawn" or "manual".
	RestartMode *string `json:"restart_mode,omitempty"`
	// RestartHint says how to restart the daemon.
	RestartHint *string `json:"restart_hint,omitempty"`
	// LiveChannelConfig is the configuration a running channel picks up
	// without a restart.
	LiveChannelConfig []string `json:"live_channel_config,omitempty"`
}

Status is the answer of GET /api/status.

type SystemAPI

type SystemAPI struct {
	// contains filtered or unexported fields
}

SystemAPI holds the gateway-wide endpoints, from Client.System.

func (SystemAPI) CLITools

func (a SystemAPI) CLITools(ctx context.Context) ([]CLITool, error)

CLITools returns the command-line tools found on the host's PATH (GET /api/cli-tools). Slow: the gateway runs each with --version.

func (SystemAPI) Doctor

func (a SystemAPI) Doctor(ctx context.Context) (*DoctorReport, error)

Doctor runs the configuration diagnostics (POST /api/doctor).

func (SystemAPI) Health

func (a SystemAPI) Health(ctx context.Context) (*Health, error)

Health returns liveness and component health (GET /health). Public.

func (SystemAPI) IntegrationSettings

func (a SystemAPI) IntegrationSettings(ctx context.Context) (map[string]IntegrationSetting, error)

IntegrationSettings returns each integration's state, by name (GET /api/integrations/settings).

func (SystemAPI) Integrations

func (a SystemAPI) Integrations(ctx context.Context) ([]Integration, error)

Integrations returns the integrations this build offers (GET /api/integrations).

func (SystemAPI) Logs

func (a SystemAPI) Logs(ctx context.Context, filter LogQuery) (*LogPage, error)

Logs returns a page of structured log events, newest first (GET /api/logs). Continue with LogQuery.UntilLineOffset set to the page's NextCursorLineOffset.

func (SystemAPI) Metrics

func (a SystemAPI) Metrics(ctx context.Context) (string, error)

Metrics returns the Prometheus text exposition (GET /metrics). Public.

func (SystemAPI) OpenAPI

func (a SystemAPI) OpenAPI(ctx context.Context) (json.RawMessage, error)

OpenAPI returns the gateway's OpenAPI document, which covers the configuration, version, SOP and skill routes (GET /api/openapi.json). Public.

func (SystemAPI) Reload

func (a SystemAPI) Reload(ctx context.Context) (*AdminResponse, error)

Reload restarts the daemon's subsystems from the configuration on disk (POST /admin/reload). The connection drops shortly after; reconnect. Allowed from loopback, or remotely with gateway.allow_remote_admin.

func (SystemAPI) RuntimeHealth

func (a SystemAPI) RuntimeHealth(ctx context.Context) (*HealthSnapshot, error)

RuntimeHealth returns the runtime's component health (GET /api/health).

func (SystemAPI) Shutdown

func (a SystemAPI) Shutdown(ctx context.Context) (*AdminResponse, error)

Shutdown stops the gateway (POST /admin/shutdown). Loopback only.

func (SystemAPI) Status

func (a SystemAPI) Status(ctx context.Context, agent string) (*Status, error)

Status returns the version, model, channels, nodes and process figures (GET /api/status); with a non-empty agent, that agent's model.

func (SystemAPI) ToolParamOptions

func (a SystemAPI) ToolParamOptions(ctx context.Context, domain, agent string, args json.RawMessage) ([]ToolOption, error)

ToolParamOptions returns the values a tool parameter of domain accepts (channel_refs, peer_targets, peer_groups, agent_aliases, tool_names, memory_categories): POST /api/tools/param-options. args holds the sibling arguments the options depend on (nil for none); an empty agent is sent as null.

func (SystemAPI) Tools

func (a SystemAPI) Tools(ctx context.Context, agent string) ([]ToolSpec, error)

Tools returns the tools an agent (all of them when agent is empty) can call (GET /api/tools).

func (SystemAPI) Tuis

func (a SystemAPI) Tuis(ctx context.Context) ([]Tui, error)

Tuis returns the terminal clients connected to the daemon (GET /api/tuis).

func (SystemAPI) Upgrade

func (a SystemAPI) Upgrade(ctx context.Context, version string, autoRestart bool) (string, error)

Upgrade starts a self-upgrade (the latest release when version is empty) and returns the handoff id to follow with SystemAPI.UpgradeStatus (POST /api/version/upgrade). Needs gateway.allow_self_upgrade.

func (SystemAPI) UpgradeStatus

func (a SystemAPI) UpgradeStatus(ctx context.Context, handoffID string) (*UpgradeStatus, error)

UpgradeStatus returns the progress of an upgrade, the latest when handoffID is empty (GET /api/version/upgrade/status).

func (SystemAPI) VersionCheck

func (a SystemAPI) VersionCheck(ctx context.Context, force bool, version string) (*VersionCheck, error)

VersionCheck reports whether a newer release exists (GET /api/version/check). force skips the gateway's one-hour cache; a non-empty version checks that one tag.

type TemplateEntry

type TemplateEntry struct {
	// Path is the dotted path.
	Path string `json:"path"`
	// Kind is map or list.
	Kind string `json:"kind"`
	// ValueType is the Rust type of an entry.
	ValueType string `json:"value_type"`
	// Description says what the section holds.
	Description string `json:"description"`
}

TemplateEntry is a map or list section and the type of its entries.

type ToolOption

type ToolOption struct {
	// Value is the value.
	Value string `json:"value"`
	// Label is the label to show.
	Label *string `json:"label,omitempty"`
	// Hint is an extra hint.
	Hint *string `json:"hint,omitempty"`
}

ToolOption is a value a tool parameter accepts.

type ToolSpec

type ToolSpec struct {
	// Name is the tool name.
	Name string `json:"name"`
	// Description says what it does.
	Description string `json:"description"`
	// Parameters is the JSON Schema of its arguments.
	Parameters json.RawMessage `json:"parameters"`
	// Output is the JSON Schema of its output, when declared.
	Output json.RawMessage `json:"output,omitempty"`
	// ParamDomains is the option domain of the parameters that take known
	// values.
	ParamDomains map[string]string `json:"param_domains,omitempty"`
}

ToolSpec is a tool an agent can call.

type Tui

type Tui struct {
	// TuiID is the client id.
	TuiID string `json:"tui_id"`
	// ConnectedAt is when it connected (RFC 3339).
	ConnectedAt string `json:"connected_at"`
	// PeerLabel says who it is.
	PeerLabel string `json:"peer_label"`
	// Transport is "unix" or "wss".
	Transport string `json:"transport"`
}

Tui is a terminal client connected to the daemon.

type TurnError

type TurnError struct {
	// Code is the stable code, e.g. "PROVIDER_ERROR" or "ABORTED"; empty
	// when the gateway sent none.
	Code string
	// Message says what went wrong.
	Message string
}

TurnError is an agent turn on the chat that ended in an "error" frame, or was aborted (Code "ABORTED").

func (*TurnError) Error

func (e *TurnError) Error() string

type TurnResult

type TurnResult struct {
	// FullResponse is the whole reply.
	FullResponse string `json:"full_response"`
	// InputTokens used.
	InputTokens *uint64 `json:"input_tokens,omitempty"`
	// OutputTokens used.
	OutputTokens *uint64 `json:"output_tokens,omitempty"`
	// TokensUsed in all.
	TokensUsed *uint64 `json:"tokens_used,omitempty"`
	// CostUSD of the turn.
	CostUSD *float64 `json:"cost_usd,omitempty"`
	// Model used.
	Model string `json:"model"`
	// Provider used.
	Provider string `json:"provider"`
	// MaxContextTokens is the model's context size.
	MaxContextTokens *uint64 `json:"max_context_tokens,omitempty"`
	// LastInputTokens is the input tokens of the last model call.
	LastInputTokens *uint64 `json:"last_input_tokens,omitempty"`
}

TurnResult is the end of a turn.

type UpgradeStatus

type UpgradeStatus struct {
	// State is "idle", "running", "done", "restarting" or "failed".
	State string `json:"state"`
	// HandoffID is the upgrade id.
	HandoffID *string `json:"handoff_id,omitempty"`
	// Phase is the step, 0 to 6.
	Phase *uint8 `json:"phase,omitempty"`
	// LogTail holds the last log lines.
	LogTail []string `json:"log_tail,omitempty"`
	// PreviousVersion is the version before.
	PreviousVersion *string `json:"previous_version,omitempty"`
	// TargetVersion is the version being installed.
	TargetVersion *string `json:"target_version,omitempty"`
	// RestartMode is how the daemon restarts.
	RestartMode *string `json:"restart_mode,omitempty"`
	// RestartHint says how to restart it by hand.
	RestartHint *string `json:"restart_hint,omitempty"`
	// Error says why it failed.
	Error *string `json:"error,omitempty"`
}

UpgradeStatus is the progress of a self-upgrade.

type Upload

type Upload struct {
	// Path is where it was stored.
	Path string `json:"path"`
	// Marker is [IMAGE:<path>], to put in a message.
	Marker string `json:"marker"`
}

Upload is a stored upload.

type ValidationWarning

type ValidationWarning struct {
	// Code is stable, e.g. pre_existing_validation_error.
	Code string `json:"code"`
	// Message explains it.
	Message string `json:"message"`
	// Path is the field concerned.
	Path string `json:"path"`
}

ValidationWarning is a validation problem the gateway reports without refusing the write.

type VersionCheck

type VersionCheck struct {
	// CurrentVersion is the running version.
	CurrentVersion string `json:"current_version"`
	// LatestVersion is the latest release (nil when the check failed).
	LatestVersion *string `json:"latest_version,omitempty"`
	// IsNewer is whether the latest is newer.
	IsNewer bool `json:"is_newer"`
	// ReleaseURL is the release page.
	ReleaseURL *string `json:"release_url,omitempty"`
	// ReleaseNotes are the release notes (Markdown).
	ReleaseNotes *string `json:"release_notes,omitempty"`
	// PublishedAt is the release date.
	PublishedAt *string `json:"published_at,omitempty"`
	// Error says why the check failed.
	Error *string `json:"error,omitempty"`
}

VersionCheck is the answer of SystemAPI.VersionCheck.

type WebAuthnAPI

type WebAuthnAPI struct {
	// contains filtered or unexported fields
}

WebAuthnAPI holds the WebAuthn endpoints, from Client.WebAuthn.

func (WebAuthnAPI) AuthFinish

func (a WebAuthnAPI) AuthFinish(ctx context.Context, assertion any) (json.RawMessage, error)

AuthFinish sends the authenticator's assertion (challenge, id, authenticator_data, client_data_json, signature), encoded as JSON (POST /api/webauthn/auth/finish). Refused with 401 when it does not verify.

func (WebAuthnAPI) AuthStart

func (a WebAuthnAPI) AuthStart(ctx context.Context, userID string) (json.RawMessage, error)

AuthStart returns the assertion challenge for userID (POST /api/webauthn/auth/start).

func (WebAuthnAPI) Credentials

func (a WebAuthnAPI) Credentials(ctx context.Context, userID string) (json.RawMessage, error)

Credentials returns the keys of userID (GET /api/webauthn/credentials).

func (WebAuthnAPI) DeleteCredential

func (a WebAuthnAPI) DeleteCredential(ctx context.Context, userID, credentialID string) error

DeleteCredential removes key credentialID of userID (DELETE /api/webauthn/credentials/{id}).

func (WebAuthnAPI) RegisterFinish

func (a WebAuthnAPI) RegisterFinish(ctx context.Context, credential any) (json.RawMessage, error)

RegisterFinish sends the authenticator's answer (challenge, id, attestation_object, client_data_json, label?), encoded as JSON, and returns {credential_id, label, registered_at} (POST /api/webauthn/register/finish).

func (WebAuthnAPI) RegisterStart

func (a WebAuthnAPI) RegisterStart(ctx context.Context, userID, userName string) (json.RawMessage, error)

RegisterStart returns the creation challenge for a new key of userID (POST /api/webauthn/register/start).

type WebhookAPI

type WebhookAPI struct {
	// contains filtered or unexported fields
}

WebhookAPI holds the webhook and A2A endpoints, from Client.Webhook.

func (WebhookAPI) A2ASend

func (a WebhookAPI) A2ASend(ctx context.Context, alias, text string) (string, error)

A2ASend sends text to a published agent with message/send and returns the text of its answer (POST /a2a/{alias}). A JSON-RPC error is returned as an *APIError with status 200. Needs the a2a feature and a2a.server.enabled on the gateway.

func (WebhookAPI) AgentCard

func (a WebhookAPI) AgentCard(ctx context.Context, alias string) (json.RawMessage, error)

AgentCard returns a published agent's A2A card (GET /a2a/{alias}/.well-known/agent-card.json). Public.

func (WebhookAPI) Send

func (a WebhookAPI) Send(ctx context.Context, message string, opts WebhookOptions) (*WebhookReply, error)

Send sends message and returns the agent's reply (POST /webhook). A duplicate idempotency key answers a WebhookReply with Duplicate set.

type WebhookOptions

type WebhookOptions struct {
	// Agent is the agent to answer (the default agent when empty).
	Agent string
	// Secret is sent as X-Webhook-Secret, when the gateway sets
	// webhook_secret.
	Secret string
	// IdempotencyKey is sent as X-Idempotency-Key: a repeat within the
	// gateway's window is not run again.
	IdempotencyKey string
	// SessionID is sent as X-Session-Id: it keeps calls in one conversation
	// ([A-Za-z0-9._-], at most 128 characters).
	SessionID string
}

WebhookOptions holds the optional parameters of WebhookAPI.Send; empty ones are not sent.

type WebhookReply

type WebhookReply struct {
	// Reply is the agent's reply; nil when Duplicate.
	Reply *AgentReply
	// Duplicate is whether the idempotency key was already used.
	Duplicate bool
}

WebhookReply is the answer of WebhookAPI.Send: the agent's reply, or Duplicate when the idempotency key was already used and nothing ran.

Directories

Path Synopsis
examples
announce command
Command announce posts a message on a channel through an agent's channel binding: a one-off shell cron job whose raw output is announced, run at once and deleted.
Command announce posts a message on a channel through an agent's channel binding: a one-off shell cron job whose raw output is announced, run at once and deleted.
chat command
Command chat asks an agent one question and streams its reply.
Command chat asks an agent one question and streams its reply.
config command
Command config reads configuration fields, lists the agents, and, with -set, changes an agent's model atomically: the patch only applies if the model is still the one read.
Command config reads configuration fields, lists the agents, and, with -set, changes an agent's model atomically: the patch only applies if the model is still the one read.
events command
Command events follows the gateway's live events and prints one line per event: agent turns with their tokens and cost, tool calls, cron results and log events.
Command events follows the gateway's live events and prints one line per event: agent turns with their tokens and cost, tool calls, cron results and log events.
pairing command
Command pairing exchanges a pairing code for a bearer token, then lists the paired devices with it.
Command pairing exchanges a pairing code for a bearer token, then lists the paired devices with it.
resilient command
Command resilient shows a client tuned for an unreliable network: a short answer timeout, five retries with jittered backoff, at most four requests in flight, ten requests per second, a circuit breaker that stops calling a gateway that keeps failing, and a middleware of its own that times every request.
Command resilient shows a client tuned for an unreliable network: a short answer timeout, five retries with jittered backoff, at most four requests in flight, ten requests per second, a circuit breaker that stops calling a gateway that keeps failing, and a middleware of its own that times every request.
status command
Command status prints the gateway's version, model and channels.
Command status prints the gateway's version, model and channels.

Jump to

Keyboard shortcuts

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