adapter

package
v0.1.0-alpha Latest Latest
Warning

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

Go to latest
Published: Mar 29, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ProbeProvider

func ProbeProvider(ctx context.Context, provider string) string

ProbeProvider checks whether the LLM provider is reachable by hitting its /v1/models endpoint. It understands "custom:<url>" format and well-known provider names. Returns "ok", "error", or "" if the URL can't be determined.

Types

type ActivityEvent

type ActivityEvent struct {
	Timestamp   time.Time      `json:"timestamp"`
	Type        string         `json:"type"` // "agent_start", "agent_end", "tool_call", "tool_call_start", "llm_request", "error", "chat", "separator"
	Summary     string         `json:"summary"`
	FullContent string         `json:"full_content,omitempty"`
	Fields      map[string]any `json:"fields,omitempty"`
}

type Agent

type Agent interface {
	// Identity
	ID() string
	Name() string
	Framework() string // "zeroclaw", "openclaw", "picoclaw", "hermes"

	// Gateway connection info
	BaseURL() string

	// Probing
	Health(ctx context.Context) (*HealthStatus, error)
	Status(ctx context.Context) (*AgentStatus, error)
	Config(ctx context.Context) (*AgentConfig, error)

	// Lifecycle (delegated to framework CLI)
	Start(ctx context.Context) error
	Stop(ctx context.Context) error
	Restart(ctx context.Context) error

	// Streaming
	TailLogs(ctx context.Context) (<-chan LogEntry, error)
	TailActivity(ctx context.Context) (<-chan ActivityEvent, error)

	// Conversation history (framework-dependent; may return nil, nil if unsupported)
	Sessions(ctx context.Context) ([]Session, error)
	ChatHistory(ctx context.Context, sessionKey string, limit int) ([]ChatMessage, error)

	// Chat: send a message and get the assistant's reply.
	// sessionKey identifies the conversation (e.g. "agent:main:main"); empty means default.
	SendMessage(ctx context.Context, message, sessionKey string) (*ChatMessage, error)

	// StreamMessage sends a message and streams the response as ChatEvent values.
	// The channel is closed when the response is complete (after a "done" or "error" event).
	StreamMessage(ctx context.Context, message, sessionKey string) (<-chan ChatEvent, error)

	// CreateSession creates a new conversation session with the given name. Returns the new session.
	CreateSession(ctx context.Context, name string) (*Session, error)

	// ResetSession archives the current transcript and starts a fresh session.
	ResetSession(ctx context.Context, sessionKey string) error

	// DeleteSession permanently removes a session from disk.
	DeleteSession(ctx context.Context, sessionKey string) error

	// Personality
	Personality(ctx context.Context) (*Personality, error)

	// Capabilities reports what roles this agent can fill in the hierarchy.
	Capabilities() AgentCapabilities
}

Agent is the common interface that every Claw framework adapter implements. Eyrie's CLI, web server, and discovery system all work through this interface.

type AgentCapabilities

type AgentCapabilities struct {
	CommanderCapable bool `json:"commander_capable"` // Can serve as Commander (requires tool execution, session context, API access)
}

type AgentConfig

type AgentConfig struct {
	Raw    string `json:"raw"`
	Format string `json:"format"` // "toml" or "json"
}

type AgentStatus

type AgentStatus struct {
	Provider       string     `json:"provider"`
	Model          string     `json:"model"`
	Channels       []string   `json:"channels"`
	Skills         int        `json:"skills"`
	LastTask       *time.Time `json:"last_task,omitempty"`
	Errors24h      int        `json:"errors_24h"`
	GatewayPort    int        `json:"gateway_port"`
	ProviderStatus string     `json:"provider_status,omitempty"` // "ok", "error", or "" (unknown/not checked)
	BusyState      string     `json:"busy_state,omitempty"`      // "idle", "busy", "error"
	CurrentTask    string     `json:"current_task,omitempty"`    // description of current activity
}

func (*AgentStatus) InferBusyState

func (s *AgentStatus) InferBusyState()

InferBusyState populates BusyState based on LastTask timestamp. Call after Status() to enrich the response.

type ChatEvent

type ChatEvent struct {
	Type    string         `json:"type"` // "delta", "tool_start", "tool_result", "done", "error"
	Content string         `json:"content,omitempty"`
	Tool    string         `json:"tool,omitempty"`
	ToolID  string         `json:"tool_id,omitempty"`
	Args    map[string]any `json:"args,omitempty"`
	Output  string         `json:"output,omitempty"`
	Success *bool          `json:"success,omitempty"`
	Error   string         `json:"error,omitempty"`
}

type ChatMessage

type ChatMessage struct {
	Timestamp time.Time  `json:"timestamp"`
	Role      string     `json:"role"` // "user", "assistant"
	Content   string     `json:"content"`
	Channel   string     `json:"channel,omitempty"`
	Parts     []ChatPart `json:"parts,omitempty"`
}

type ChatPart

type ChatPart struct {
	Type   string         `json:"type"`
	Text   string         `json:"text,omitempty"`
	ID     string         `json:"id,omitempty"`
	Name   string         `json:"name,omitempty"`
	Args   map[string]any `json:"args,omitempty"`
	Output string         `json:"output,omitempty"`
	Error  bool           `json:"error,omitempty"`
}

ChatPart is an ordered content element within a message. Type is "text" or "tool_call".

type ComponentHealth

type ComponentHealth struct {
	Status       string     `json:"status"`
	LastOK       *time.Time `json:"last_ok,omitempty"`
	LastError    string     `json:"last_error,omitempty"`
	RestartCount int        `json:"restart_count"`
}

type DiscoveredAgent

type DiscoveredAgent struct {
	Name        string `json:"name"`
	DisplayName string `json:"display_name,omitempty"`
	Framework   string `json:"framework"`
	Host        string `json:"host"`
	Port        int    `json:"port"`
	ConfigPath  string `json:"config_path"`
	Token       string `json:"-"`
	InstanceID  string `json:"instance_id,omitempty"`
}

DiscoveredAgent holds the result of auto-discovery before a full adapter is created.

func (*DiscoveredAgent) URL

func (d *DiscoveredAgent) URL() string

type HealthStatus

type HealthStatus struct {
	Alive      bool                       `json:"alive"`
	Uptime     time.Duration              `json:"uptime"`
	RAM        uint64                     `json:"ram_bytes"`
	CPU        float64                    `json:"cpu_percent"`
	PID        int                        `json:"pid,omitempty"`
	Components map[string]ComponentHealth `json:"components,omitempty"`
}

type HermesAdapter

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

HermesAdapter implements the Agent interface for Hermes (Python-based agent) using CLI invocation and file-based status checks.

func NewHermesAdapter

func NewHermesAdapter(id, name, configPath, binaryPath string) *HermesAdapter

NewHermesAdapter creates a new Hermes adapter

func (*HermesAdapter) BaseURL

func (h *HermesAdapter) BaseURL() string

BaseURL returns empty string (no HTTP API)

func (*HermesAdapter) Capabilities

func (h *HermesAdapter) Capabilities() AgentCapabilities

func (*HermesAdapter) ChatHistory

func (h *HermesAdapter) ChatHistory(ctx context.Context, sessionKey string, limit int) ([]ChatMessage, error)

ChatHistory returns chat messages for a session

func (*HermesAdapter) Config

func (h *HermesAdapter) Config(ctx context.Context) (*AgentConfig, error)

Config returns the agent configuration

func (*HermesAdapter) CreateSession

func (h *HermesAdapter) CreateSession(ctx context.Context, name string) (*Session, error)

CreateSession creates a new conversation session

func (*HermesAdapter) DeleteSession

func (h *HermesAdapter) DeleteSession(ctx context.Context, sessionKey string) error

DeleteSession permanently removes a session

func (*HermesAdapter) Framework

func (h *HermesAdapter) Framework() string

Framework returns "hermes"

func (*HermesAdapter) Health

func (h *HermesAdapter) Health(ctx context.Context) (*HealthStatus, error)

Health checks if the Hermes gateway is running by reading PID file and state file

func (*HermesAdapter) ID

func (h *HermesAdapter) ID() string

ID returns the unique identifier

func (*HermesAdapter) Name

func (h *HermesAdapter) Name() string

Name returns the agent name

func (*HermesAdapter) Personality

func (h *HermesAdapter) Personality(ctx context.Context) (*Personality, error)

Personality returns the agent's personality

func (*HermesAdapter) ResetSession

func (h *HermesAdapter) ResetSession(ctx context.Context, sessionKey string) error

ResetSession deletes a conversation session

func (*HermesAdapter) Restart

func (h *HermesAdapter) Restart(ctx context.Context) error

Restart restarts the Hermes gateway

func (*HermesAdapter) SendMessage

func (h *HermesAdapter) SendMessage(ctx context.Context, message, sessionKey string) (*ChatMessage, error)

SendMessage sends a message and waits for the response

func (*HermesAdapter) Sessions

func (h *HermesAdapter) Sessions(ctx context.Context) ([]Session, error)

Sessions returns conversation sessions

func (*HermesAdapter) Start

func (h *HermesAdapter) Start(ctx context.Context) error

Start starts the Hermes gateway

func (*HermesAdapter) Status

func (h *HermesAdapter) Status(ctx context.Context) (*AgentStatus, error)

Status returns agent status by parsing config file

func (*HermesAdapter) Stop

func (h *HermesAdapter) Stop(ctx context.Context) error

Stop stops the Hermes gateway by killing the process

func (*HermesAdapter) StreamMessage

func (h *HermesAdapter) StreamMessage(ctx context.Context, message, sessionKey string) (<-chan ChatEvent, error)

StreamMessage sends a message and streams the response

func (*HermesAdapter) TailActivity

func (h *HermesAdapter) TailActivity(ctx context.Context) (<-chan ActivityEvent, error)

TailActivity tails the Hermes log file and extracts activity events

func (*HermesAdapter) TailLogs

func (h *HermesAdapter) TailLogs(ctx context.Context) (<-chan LogEntry, error)

TailLogs tails the Hermes log file

type LogEntry

type LogEntry struct {
	Timestamp time.Time      `json:"timestamp"`
	Level     string         `json:"level"`
	Message   string         `json:"message"`
	Fields    map[string]any `json:"fields,omitempty"`
}

type OpenClawAdapter

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

OpenClawAdapter communicates with an OpenClaw instance via its WebSocket RPC gateway. OpenClaw exposes a single WebSocket endpoint at ws://host:port with RPC methods.

func NewOpenClawAdapter

func NewOpenClawAdapter(id, name, host string, port int, token, configPath string) *OpenClawAdapter

func (*OpenClawAdapter) BaseURL

func (o *OpenClawAdapter) BaseURL() string

func (*OpenClawAdapter) Capabilities

func (o *OpenClawAdapter) Capabilities() AgentCapabilities

func (*OpenClawAdapter) ChatHistory

func (o *OpenClawAdapter) ChatHistory(_ context.Context, sessionKey string, limit int) ([]ChatMessage, error)

ChatHistory reads the JSONL transcript file for a given session key directly from disk. It extracts user and assistant messages, handling OpenClaw's content format (array of {type, text} objects).

func (*OpenClawAdapter) Config

func (o *OpenClawAdapter) Config(ctx context.Context) (*AgentConfig, error)

func (*OpenClawAdapter) CreateSession

func (o *OpenClawAdapter) CreateSession(_ context.Context, name string) (*Session, error)

func (*OpenClawAdapter) DeleteSession

func (o *OpenClawAdapter) DeleteSession(_ context.Context, sessionKey string) error

func (*OpenClawAdapter) DestroySession

func (o *OpenClawAdapter) DestroySession(ctx context.Context, sessionKey string) error

DestroySession completely removes a session — deletes the JSONL transcript and removes the entry from sessions.json. Works for both active and archived sessions.

For active sessions this delegates to OpenClaw's sessions.delete RPC, which handles its own locking and transcript cleanup. Previous versions did file surgery on sessions.json from Eyrie, which was racy (TOCTOU) when OpenClaw wrote to the same file concurrently.

func (*OpenClawAdapter) Framework

func (o *OpenClawAdapter) Framework() string

func (*OpenClawAdapter) Health

func (o *OpenClawAdapter) Health(ctx context.Context) (*HealthStatus, error)

func (*OpenClawAdapter) ID

func (o *OpenClawAdapter) ID() string

func (*OpenClawAdapter) Name

func (o *OpenClawAdapter) Name() string

func (*OpenClawAdapter) Personality

func (o *OpenClawAdapter) Personality(ctx context.Context) (*Personality, error)

func (*OpenClawAdapter) QuickHealthCheck

func (o *OpenClawAdapter) QuickHealthCheck(ctx context.Context) bool

QuickHealthCheck does a fast WebSocket connect + handshake probe.

func (*OpenClawAdapter) ResetSession

func (o *OpenClawAdapter) ResetSession(ctx context.Context, sessionKey string) error

func (*OpenClawAdapter) Restart

func (o *OpenClawAdapter) Restart(ctx context.Context) error

func (*OpenClawAdapter) SendMessage

func (o *OpenClawAdapter) SendMessage(ctx context.Context, message, sessionKey string) (*ChatMessage, error)

func (*OpenClawAdapter) Sessions

func (o *OpenClawAdapter) Sessions(_ context.Context) ([]Session, error)

Sessions reads session metadata directly from OpenClaw's on-disk session store rather than using the WebSocket RPC (which requires a full device-auth handshake that Eyrie does not implement).

func (*OpenClawAdapter) Start

func (o *OpenClawAdapter) Start(ctx context.Context) error

func (*OpenClawAdapter) Status

func (o *OpenClawAdapter) Status(ctx context.Context) (*AgentStatus, error)

func (*OpenClawAdapter) Stop

func (o *OpenClawAdapter) Stop(ctx context.Context) error

func (*OpenClawAdapter) StreamMessage

func (o *OpenClawAdapter) StreamMessage(ctx context.Context, message, sessionKey string) (<-chan ChatEvent, error)

func (*OpenClawAdapter) TailActivity

func (o *OpenClawAdapter) TailActivity(ctx context.Context) (<-chan ActivityEvent, error)

TailActivity emits recent conversation history as activity events, then subscribes to the OpenClaw WebSocket event stream for live events.

func (*OpenClawAdapter) TailLogs

func (o *OpenClawAdapter) TailLogs(ctx context.Context) (<-chan LogEntry, error)

TailLogs subscribes to the OpenClaw logs.tail RPC stream. If the agent is not running, historical logs are still returned before closing.

type Personality

type Personality struct {
	Name         string            `json:"name"`
	SystemPrompt string            `json:"system_prompt,omitempty"`
	Traits       map[string]string `json:"traits,omitempty"`
	// Raw workspace identity files (IDENTITY.md, SOUL.md, etc.)
	IdentityFiles map[string]string `json:"identity_files,omitempty"`
}

type PicoClawAdapter

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

PicoClawAdapter communicates with a PicoClaw instance via the web backend's REST API (sessions, config, lifecycle) and the gateway's health endpoint. Chat streaming uses the Pico Protocol WebSocket with delta diffing.

Architecture: PicoClaw has a two-tier design — a gateway (agent runtime, default port 18790) and a web backend (launcher + API proxy, default port 18800 = gatewayPort + 10). Eyrie stores the gateway port in DiscoveredAgent for health probing (consistent with all adapters) and derives the web port.

func NewPicoClawAdapter

func NewPicoClawAdapter(id, name, host string, gatewayPort int, token, configPath string) *PicoClawAdapter

func (*PicoClawAdapter) BaseURL

func (p *PicoClawAdapter) BaseURL() string

func (*PicoClawAdapter) Capabilities

func (p *PicoClawAdapter) Capabilities() AgentCapabilities

Capabilities reports that PicoClaw is commander-capable.

func (*PicoClawAdapter) ChatHistory

func (p *PicoClawAdapter) ChatHistory(ctx context.Context, sessionKey string, limit int) ([]ChatMessage, error)

ChatHistory reads message history for a session from the web backend. Falls back to reading JSONL from disk if the API is unavailable.

func (*PicoClawAdapter) Config

func (p *PicoClawAdapter) Config(ctx context.Context) (*AgentConfig, error)

Config reads the config.json from disk. Returns the raw JSON content.

func (*PicoClawAdapter) CreateSession

func (p *PicoClawAdapter) CreateSession(_ context.Context, name string) (*Session, error)

CreateSession generates a new session UUID. PicoClaw creates sessions implicitly when a message is sent with a new session_id.

func (*PicoClawAdapter) DeleteSession

func (p *PicoClawAdapter) DeleteSession(ctx context.Context, sessionKey string) error

DeleteSession permanently removes a session via the web backend API.

func (*PicoClawAdapter) Framework

func (p *PicoClawAdapter) Framework() string

func (*PicoClawAdapter) Health

func (p *PicoClawAdapter) Health(ctx context.Context) (*HealthStatus, error)

Health probes the gateway's /health endpoint for status, uptime, and PID, then enriches with process-level stats from ps.

func (*PicoClawAdapter) ID

func (p *PicoClawAdapter) ID() string

func (*PicoClawAdapter) Name

func (p *PicoClawAdapter) Name() string

func (*PicoClawAdapter) Personality

func (p *PicoClawAdapter) Personality(ctx context.Context) (*Personality, error)

Personality reads SOUL.md and IDENTITY.md from the workspace directory, and returns config.json as an identity file.

func (*PicoClawAdapter) ResetSession

func (p *PicoClawAdapter) ResetSession(ctx context.Context, sessionKey string) error

ResetSession archives/deletes a session via the web backend API.

func (*PicoClawAdapter) Restart

func (p *PicoClawAdapter) Restart(ctx context.Context) error

Restart sends a POST to the web backend to restart the gateway.

func (*PicoClawAdapter) SendMessage

func (p *PicoClawAdapter) SendMessage(ctx context.Context, message, sessionKey string) (*ChatMessage, error)

SendMessage sends a message and collects the full response. Delegates to StreamMessage and reads until done, following the ZeroClaw pattern.

func (*PicoClawAdapter) Sessions

func (p *PicoClawAdapter) Sessions(ctx context.Context) ([]Session, error)

Sessions lists active sessions from the web backend.

func (*PicoClawAdapter) Start

func (p *PicoClawAdapter) Start(ctx context.Context) error

Start sends a POST to the web backend to start the gateway.

func (*PicoClawAdapter) Status

func (p *PicoClawAdapter) Status(ctx context.Context) (*AgentStatus, error)

Status queries the web backend for gateway status when online, falling back to parsing the config file for model/provider/channels when offline.

func (*PicoClawAdapter) Stop

func (p *PicoClawAdapter) Stop(ctx context.Context) error

Stop sends a POST to the web backend to stop the gateway.

func (*PicoClawAdapter) StreamMessage

func (p *PicoClawAdapter) StreamMessage(ctx context.Context, message, sessionKey string) (<-chan ChatEvent, error)

StreamMessage connects to the Pico Protocol WebSocket and streams the response.

Protocol:

  • Send: {type: "message.send", session_id, timestamp, payload: {content}}
  • Receive: message.update (streaming delta via full-content diffing) message.create (final complete response) error (error event)
  • Ignored: typing.start, typing.stop, pong

message.update delivers full-content replacements. The adapter diffs successive updates to emit append-only deltas for Eyrie's ChatEvent model.

func (*PicoClawAdapter) TailActivity

func (p *PicoClawAdapter) TailActivity(ctx context.Context) (<-chan ActivityEvent, error)

TailActivity reads historical log entries and classifies them as activity events, then polls for live updates.

func (*PicoClawAdapter) TailLogs

func (p *PicoClawAdapter) TailLogs(ctx context.Context) (<-chan LogEntry, error)

TailLogs reads historical log entries from the gateway log file (zerolog JSON), then polls the web backend's /api/gateway/logs endpoint every 2 seconds for live updates.

type Session

type Session struct {
	Key      string     `json:"key"`
	Title    string     `json:"title"`
	LastMsg  *time.Time `json:"last_message,omitempty"`
	Channel  string     `json:"channel,omitempty"`
	ReadOnly bool       `json:"readonly,omitempty"`
}

type ZeroClawAdapter

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

ZeroClawAdapter communicates with a ZeroClaw instance via its HTTP REST gateway and WebSocket chat endpoint. ZeroClaw exposes: GET /health, GET /api/status, GET /api/config, GET /api/events (SSE).

func NewZeroClawAdapter

func NewZeroClawAdapter(id, name, baseURL, token, configPath string) *ZeroClawAdapter

func (*ZeroClawAdapter) ActivateSession

func (z *ZeroClawAdapter) ActivateSession(_ context.Context, _ string) error

ActivateSession is a no-op for upstream ZeroClaw (0.5.7+) since sessions are selected per-connection via the ?session_id query param on the WS endpoint. Kept for interface compatibility with the hierarchy briefing handler.

func (*ZeroClawAdapter) BaseURL

func (z *ZeroClawAdapter) BaseURL() string

func (*ZeroClawAdapter) Capabilities

func (z *ZeroClawAdapter) Capabilities() AgentCapabilities

func (*ZeroClawAdapter) ChatHistory

func (z *ZeroClawAdapter) ChatHistory(ctx context.Context, sessionKey string, limit int) ([]ChatMessage, error)

ChatHistory returns conversation messages for a session. It reads from ZeroClaw's SQLite session database as the source of truth, then enriches messages with tool call parts from Eyrie's JSONL store where available. Falls back to the legacy memory API if neither is available.

func (*ZeroClawAdapter) Config

func (z *ZeroClawAdapter) Config(ctx context.Context) (*AgentConfig, error)

func (*ZeroClawAdapter) CreateSession

func (z *ZeroClawAdapter) CreateSession(_ context.Context, name string) (*Session, error)

CreateSession generates a new session ID for ZeroClaw. Upstream creates sessions implicitly on first WS message, so we just return the ID. The session will be created in the backend when StreamMessage connects.

func (*ZeroClawAdapter) DeleteSession

func (z *ZeroClawAdapter) DeleteSession(ctx context.Context, sessionKey string) error

func (*ZeroClawAdapter) DestroySession

func (z *ZeroClawAdapter) DestroySession(ctx context.Context, sessionKey string) error

func (*ZeroClawAdapter) Framework

func (z *ZeroClawAdapter) Framework() string

func (*ZeroClawAdapter) Health

func (z *ZeroClawAdapter) Health(ctx context.Context) (*HealthStatus, error)

func (*ZeroClawAdapter) ID

func (z *ZeroClawAdapter) ID() string

func (*ZeroClawAdapter) Name

func (z *ZeroClawAdapter) Name() string

func (*ZeroClawAdapter) Personality

func (z *ZeroClawAdapter) Personality(ctx context.Context) (*Personality, error)

func (*ZeroClawAdapter) ResetSession

func (z *ZeroClawAdapter) ResetSession(ctx context.Context, sessionKey string) error

func (*ZeroClawAdapter) Restart

func (z *ZeroClawAdapter) Restart(ctx context.Context) error

func (*ZeroClawAdapter) SendMessage

func (z *ZeroClawAdapter) SendMessage(ctx context.Context, message, sessionKey string) (*ChatMessage, error)

func (*ZeroClawAdapter) Sessions

func (z *ZeroClawAdapter) Sessions(ctx context.Context) ([]Session, error)

Sessions returns sessions from ZeroClaw's session backend (0.5.7+). Upstream uses UUID-based session_ids with a gw_ prefix internally. Falls back to a synthetic "memory" session for older versions.

func (*ZeroClawAdapter) Start

func (z *ZeroClawAdapter) Start(ctx context.Context) error

func (*ZeroClawAdapter) Status

func (z *ZeroClawAdapter) Status(ctx context.Context) (*AgentStatus, error)

func (*ZeroClawAdapter) Stop

func (z *ZeroClawAdapter) Stop(ctx context.Context) error

func (*ZeroClawAdapter) StreamMessage

func (z *ZeroClawAdapter) StreamMessage(ctx context.Context, message, sessionKey string) (<-chan ChatEvent, error)

StreamMessage connects to ZeroClaw's WebSocket chat endpoint with session support. The upstream WS handler (0.5.7+) creates a persistent Agent per connection, hydrates it from the session backend, and runs multi-turn chat with full tool execution.

func (*ZeroClawAdapter) TailActivity

func (z *ZeroClawAdapter) TailActivity(ctx context.Context) (<-chan ActivityEvent, error)

TailActivity emits historical activity from the daemon log, then connects to the ZeroClaw SSE event stream for live events.

func (*ZeroClawAdapter) TailLogs

func (z *ZeroClawAdapter) TailLogs(ctx context.Context) (<-chan LogEntry, error)

TailLogs emits historical log entries from the daemon log file, then connects to the ZeroClaw SSE event stream for live entries. If the agent is not running, historical logs are still returned before closing.

Jump to

Keyboard shortcuts

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