daemonclient

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Aug 28, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package daemonclient is the CLI's HTTP client for a running kram-daemon: creating sessions and sending messages. The CLI itself never persists anything or talks to an LLM provider — it's purely a view over what the daemon already owns.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type BackgroundProcess added in v0.2.8

type BackgroundProcess struct {
	ID            string     `json:"id"`
	Command       string     `json:"command"`
	PID           int        `json:"pid"`
	Running       bool       `json:"running"`
	ExitCode      int        `json:"exit_code"`
	ExitError     string     `json:"exit_error,omitempty"`
	StartedAt     time.Time  `json:"started_at"`
	EndedAt       *time.Time `json:"ended_at,omitempty"`
	OutputBytes   int64      `json:"output_bytes"`
	RetainedBytes int        `json:"retained_bytes"`
	Truncated     bool       `json:"truncated"`
}

BackgroundProcess mirrors the daemon's read-only process metadata.

type BackgroundProcessOutput added in v0.2.8

type BackgroundProcessOutput struct {
	ID        string `json:"id"`
	Output    string `json:"output"`
	Cursor    int64  `json:"cursor"`
	Reset     bool   `json:"reset"`
	Running   bool   `json:"running"`
	ExitCode  int    `json:"exit_code"`
	ExitError string `json:"exit_error,omitempty"`
	Truncated bool   `json:"truncated"`
}

type Client

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

Client talks to a kram-daemon instance.

func New

func New(baseURL, authToken string) *Client

New builds a client pointed at a running daemon (e.g. http://127.0.0.1:20130). authToken is the per-process bearer token the daemon requires on every request (may be "" when talking to a daemon started without auth, e.g. an old build — the header is simply omitted then). The single-binary cmd/kram threads the same token it hands the daemon; a standalone CLI passes the token the daemon wrote to its daemon.token file.

func (*Client) AnswerApproval

func (c *Client) AnswerApproval(ctx context.Context, sessionID, approvalID, decision string) error

AnswerApproval delivers a decision ("once", "always", or "deny") to a pending permission-policy approval — same blocking shape as AnswerQuestion, but a distinct endpoint/id space (see server.go).

func (*Client) AnswerQuestion

func (c *Client) AnswerQuestion(ctx context.Context, sessionID, questionID, answer string) error

AnswerQuestion delivers an answer to a pending ask_question call — the SSE stream that produced the "question" event stays open and blocked server-side the whole time; this is a separate HTTP request that unblocks it, not a message sent over the stream itself.

func (*Client) AttachTurn added in v0.6.0

func (c *Client) AttachTurn(ctx context.Context, sessionID string) (*MessageStream, error)

AttachTurn reattaches to a session's running (or just-finished) turn: the daemon replays every event published so far and then streams live until the turn ends. A "no active turn" daemon error means there is nothing to attach to — the session's persisted history is the record.

func (*Client) CreateSession

func (c *Client) CreateSession(ctx context.Context, title string) (Session, error)

CreateSession starts a new session with the given title.

func (*Client) GetBackgroundProcessOutput added in v0.2.8

func (c *Client) GetBackgroundProcessOutput(ctx context.Context, id string, cursor *int64) (BackgroundProcessOutput, error)

func (*Client) GetContext

func (c *Client) GetContext(ctx context.Context, sessionID string) (ContextUsage, error)

GetContext fetches a session's current context-window usage breakdown.

func (*Client) GetSession

func (c *Client) GetSession(ctx context.Context, id string) (Session, []Message, error)

GetSession returns a session and its full message history.

func (*Client) Interrupt added in v0.6.0

func (c *Client) Interrupt(ctx context.Context, sessionID string) error

Interrupt cancels the session's active turn server-side. Closing the SSE stream alone no longer cancels anything (a detached turn keeps running — see the daemon's turn registry); this is the explicit stop.

func (*Client) ListBackgroundProcesses added in v0.2.8

func (c *Client) ListBackgroundProcesses(ctx context.Context) ([]BackgroundProcess, error)

func (*Client) ListSessions

func (c *Client) ListSessions(ctx context.Context) ([]Session, error)

ListSessions returns every known session, most recently active first.

func (*Client) ListTools

func (c *Client) ListTools(ctx context.Context) ([]ToolInfo, []Skill, error)

ListTools fetches every registered tool and discovered skill from the daemon, enabled or not — the source of truth the toggle screen renders from, rather than a hardcoded duplicate list in the CLI.

func (*Client) Rewind added in v0.6.0

func (c *Client) Rewind(ctx context.Context, id string) (RewindResult, error)

Rewind restores the workspace to the given checkpoint id (from RewindInfo — passing the id pins the confirmation to exactly what the user was shown).

func (*Client) RewindInfo added in v0.6.0

func (c *Client) RewindInfo(ctx context.Context) (RewindCheckpoint, error)

RewindInfo fetches the newest automatic checkpoint — what Rewind would restore to — for a confirm-before-destroy flow.

func (*Client) SendMessageStream

func (c *Client) SendMessageStream(ctx context.Context, sessionID, content string, images []string) (*MessageStream, error)

SendMessageStream posts a user message (with optional image data: URLs) and returns a live stream of what the agent loop does to answer it — text deltas as they're generated, tool activity, notices, ending in one "done" (or "error") event.

func (*Client) SetCombo added in v0.5.0

func (c *Client) SetCombo(ctx context.Context, combo string) error

SetCombo switches the daemon's active combo — the combo ID future messages route to. Takes effect on the next message; an in-flight turn keeps the combo it started with.

func (*Client) Steer added in v0.6.0

func (c *Client) Steer(ctx context.Context, sessionID, content string) error

Steer queues a user message for the session's running turn — picked up at the agent's next model-call boundary. Errors (including "no turn running") mean nothing was queued; send a normal message instead.

func (*Client) UpdateToolSettings added in v0.2.5

func (c *Client) UpdateToolSettings(ctx context.Context, disabled []string) error

UpdateToolSettings applies the already-persisted disabled set to the live daemon. This keeps the settings UI and the registry used by the next model call coherent without requiring a process restart.

type ContextCategory

type ContextCategory struct {
	Name   string `json:"name"`
	Tokens int    `json:"tokens"`
}

ContextCategory is one real contributor to a session's context-window usage.

type ContextUsage

type ContextUsage struct {
	Budget     int               `json:"budget"`
	Used       int               `json:"used"`
	Free       int               `json:"free"`
	Categories []ContextCategory `json:"categories"`
}

ContextUsage is a session's current context-window breakdown.

type Message

type Message struct {
	ID        int64  `json:"id"`
	SessionID string `json:"session_id"`
	Role      string `json:"role"`
	Content   string `json:"content"`
	Provider  string `json:"provider,omitempty"`
	CreatedAt int64  `json:"created_at"`
}

Message mirrors the daemon's persisted message shape.

type MessageStream

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

MessageStream is an open connection to a running agent turn — read it with Next until it reports done, then Close it.

func (*MessageStream) Close

func (s *MessageStream) Close() error

Close releases the underlying HTTP connection. Safe to call on a zero-value or already-closed stream (nil resp) — the CLI's interrupt path closes whatever stream it holds without first proving it was ever opened.

func (*MessageStream) Next

func (s *MessageStream) Next() (evt StreamEvent, done bool, err error)

Next blocks until the next SSE event arrives. done is true once the stream has logically ended (a "done"/"error" event, EOF, or a read error) — the caller should stop calling Next at that point, though it remains safe to call again (it will just report done with a zero event).

type RewindCheckpoint added in v0.6.0

type RewindCheckpoint struct {
	ID        string    `json:"id"`
	Message   string    `json:"message"`
	CreatedAt time.Time `json:"created_at"`
}

RewindCheckpoint mirrors the daemon's snapshot metadata for the automatic pre-mutation checkpoint a one-key rewind would restore to.

func (RewindCheckpoint) ShortID added in v0.6.0

func (c RewindCheckpoint) ShortID() string

ShortID mirrors snapshot.Snapshot.ShortID for display.

type RewindResult added in v0.6.0

type RewindResult struct {
	Restored struct {
		SnapshotID string `json:"snapshot_id"`
		Changes    []struct {
			Path   string `json:"path"`
			Status string `json:"status"`
		} `json:"changes"`
	} `json:"restored"`
	Snapshot RewindCheckpoint `json:"snapshot"`
}

RewindResult is what a rewind actually changed.

type RouteCall

type RouteCall struct {
	Index    int                         `json:"index"`
	Combo    string                      `json:"combo"`
	Strategy string                      `json:"strategy"`
	Attempts []openai.AttemptInfo        `json:"attempts"`
	Ranking  []openai.RankedProviderInfo `json:"ranking,omitempty"`
	Winner   string                      `json:"winner,omitempty"`
}

RouteCall mirrors agent.RouteCall — one model call's full routing story within a run.

type RouteTrace

type RouteTrace struct {
	Combo    string      `json:"combo"`
	Strategy string      `json:"strategy"`
	Calls    []RouteCall `json:"calls"`
}

RouteTrace mirrors agent.RouteTrace — every model call a run made, in order, each with its own complete fallback trail. Distinct from StreamEvent.Attempts (the last call's trail only, kept for the simple footer view): RouteTrace is what a full route-trace UI (Ctrl+R) needs.

type Session

type Session struct {
	ID        string `json:"id"`
	Title     string `json:"title"`
	CreatedAt int64  `json:"created_at"`
	UpdatedAt int64  `json:"updated_at"`
}

Session mirrors the daemon's persisted session shape.

type Skill

type Skill struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	Scope       string `json:"scope"`
	Disabled    bool   `json:"disabled"`
}

Skill mirrors the daemon's tools.Skill.

type StreamEvent

type StreamEvent struct {
	Type         string               `json:"type"`
	Content      string               `json:"content,omitempty"`
	Name         string               `json:"name,omitempty"`
	Args         string               `json:"args,omitempty"`
	Result       string               `json:"result,omitempty"`
	OK           bool                 `json:"ok,omitempty"`
	ProcessID    string               `json:"process_id,omitempty"`
	Segment      int                  `json:"segment,omitempty"`
	Segments     int                  `json:"segments,omitempty"`
	Text         string               `json:"text,omitempty"`
	QuestionID   string               `json:"question_id,omitempty"`
	Question     string               `json:"question,omitempty"`
	Options      []string             `json:"options,omitempty"`
	ApprovalID   string               `json:"approval_id,omitempty"`
	Tool         string               `json:"tool,omitempty"`
	Subject      string               `json:"subject,omitempty"`
	Diff         string               `json:"diff,omitempty"` // approval: unified diff for edit_file/write_file
	RouteCall    *RouteCall           `json:"route_call,omitempty"`
	Message      Message              `json:"message,omitempty"`
	Attempts     []openai.AttemptInfo `json:"attempts,omitempty"`
	RouteTrace   RouteTrace           `json:"route_trace,omitempty"`
	Usage        openai.Usage         `json:"usage,omitempty"`
	ToolActivity []ToolActivity       `json:"tool_activity,omitempty"`
	Compactions  int                  `json:"compactions,omitempty"`
	ImageNotice  string               `json:"image_notice,omitempty"`
	Error        string               `json:"error,omitempty"`
}

StreamEvent is one event from a message stream. Type selects which other fields are meaningful: "delta" (Content), "reasoning" (Content — a reasoning-capable model's chain-of-thought fragment, best-effort and never the model's actual answer; see agent.EventReasoning), "tool_start" (Name, Args), "tool_result" (Name, Result, OK), "notice" (Text), "question" (QuestionID, Question, Options), "approval" (ApprovalID, Tool, Subject, Options), "route_start" (none), "route_done" (RouteCall), "heartbeat", "segment" (Segment/Segments), "done" (Message, Attempts, RouteTrace, Usage, ToolActivity, Compactions, ImageNotice), or "error" (Error).

type ToolActivity

type ToolActivity struct {
	Name      string `json:"name"`
	Args      string `json:"args"`
	Result    string `json:"result"`
	OK        bool   `json:"ok"`
	ProcessID string `json:"process_id,omitempty"`
	Running   bool   `json:"-"`
}

ToolActivity mirrors one tool call the daemon's agent loop made while producing this reply. Running is CLI-only UI state (never sent over the wire) — true from the moment a tool_start event arrives until its matching tool_result lands.

type ToolInfo

type ToolInfo struct {
	Name        string `json:"Name"`
	Description string `json:"Description"`
	Disabled    bool   `json:"Disabled"`
}

ToolInfo mirrors the daemon's tools.ToolInfo — one registered tool, enabled or not, for the tools/skills toggle screen.

Jump to

Keyboard shortcuts

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