Documentation
¶
Overview ¶
Package desktop implements the BuildMax desktop app (Wails) and is used by cmd/buildmax-desktop.
Index ¶
- func Run(assets fs.FS) error
- type App
- func (a *App) CancelRun(projectID string) error
- func (a *App) ClearProjectSessions(projectID string) ([]string, error)
- func (a *App) DeleteProject(id string, deleteSessions bool) error
- func (a *App) DeleteSession(sessionID string) error
- func (a *App) DeliverNextJobEvent(projectID, sessionID string) (bool, error)
- func (a *App) DoLogin(serverURL, email, otp string) (*AuthStatus, error)
- func (a *App) DoLoginWithPassword(serverURL, email, password string) (*AuthStatus, error)
- func (a *App) ForkSession(projectID, sessionID, itemID string) (HistoryMoveResult, error)
- func (a *App) GetAuthStatus() (*AuthStatus, error)
- func (a *App) GetDefaultServerURL() string
- func (a *App) GetGitBranch(projectID string) (string, error)
- func (a *App) GetHistoryPoints(sessionID string) (HistoryPointsResult, error)
- func (a *App) GetJobOutput(projectID, jobID, stream string, cursor uint64) (JobOutputPayload, error)
- func (a *App) GetPlugins(projectID string) (PluginsResult, error)
- func (a *App) GetRunStatus(projectID, sessionID string) (RunStatusPayload, error)
- func (a *App) GetSession(sessionID string) (SessionDetail, error)
- func (a *App) GetSlashAgents(projectID string) (SlashAgentsResult, error)
- func (a *App) GetSlashMCP(projectID string) (SlashMCPResult, error)
- func (a *App) GetSlashModels(projectID string) (SlashModelsResult, error)
- func (a *App) GetSlashSkills(projectID string) (SlashSkillsResult, error)
- func (a *App) GetWorkspaceDiff(projectID string) (git.WorkspaceDiff, error)
- func (a *App) InstallPlugin(name, version string, update bool) (InstallPluginPlan, error)
- func (a *App) ListJobs(projectID string) ([]JobPayload, error)
- func (a *App) ListProjects() ([]localproject.Summary, error)
- func (a *App) ListSessions() ([]session.ItemSummary, error)
- func (a *App) Logout() error
- func (a *App) OpenFolderDialog() (string, error)
- func (a *App) OpenProject(folderPath, name string) (*localproject.Summary, error)
- func (a *App) PendingJobDeliveries(projectID, sessionID string) int
- func (a *App) PlanPluginInstall(name, version string, update bool) (InstallPluginPlan, error)
- func (a *App) ProjectMemory(projectID string) (ProjectMemoryPayload, error)
- func (a *App) ProjectNotices(projectID string) ([]string, error)
- func (a *App) QueuedMessages(projectID string) []string
- func (a *App) RenameProject(id, newName string) error
- func (a *App) RenameSession(sessionID, title string) error
- func (a *App) RequestOTP(serverURL, email, intent string) error
- func (a *App) RespondApproval(projectID string, decision string)
- func (a *App) RewindSession(projectID, sessionID, itemID string) (HistoryMoveResult, error)
- func (a *App) SendMessageStream(projectID, sessionID, prompt string) (int, error)
- func (a *App) SetPluginDisabled(name string, disabled bool) error
- func (a *App) SetProjectModel(projectID, modelName string) error
- func (a *App) SetSessionPinned(sessionID string, pinned bool) error
- func (a *App) Shutdown(_ context.Context)
- func (a *App) Startup(ctx context.Context)
- func (a *App) StopJob(projectID, jobID string) error
- func (a *App) UninstallPlugin(name string, force bool) error
- type ApprovalRequestPayload
- type AuthStatus
- type DesktopApprovalHandler
- type HistoryMoveResult
- type HistoryPoint
- type HistoryPointsResult
- type HistoryToolEffect
- type InstallPluginPlan
- type JobDeliveryPayload
- type JobDeliveryPendingPayload
- type JobOutputPayload
- type JobPayload
- type MemoryEntry
- type MemorySkipped
- type MessageBlockedPayload
- type MessageDequeuedPayload
- type PluginEntry
- type PluginEnvVar
- type PluginsResult
- type ProjectMemoryPayload
- type ReplyPayload
- type RunStatusPayload
- type SessionDetail
- type SlashAgentEntry
- type SlashAgentsResult
- type SlashMCPResult
- type SlashMCPServer
- type SlashModelEntry
- type SlashModelsResult
- type SlashSkillEntry
- type SlashSkillsResult
- type StreamErrorPayload
- type ToolEndPayload
- type ToolStartPayload
- type TurnDigestPayload
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App holds desktop application state and implements Wails lifecycle hooks. Each project gets its own AgentApp and ApprovalHandler instance, created lazily on first use.
func (*App) CancelRun ¶
CancelRun cancels the in-flight run for the given project, if any. Cancellation is cooperative: the agent loop returns the partial assistant reply produced so far and emits desktop/stream-done as a normal completion. Calling CancelRun when no run is in flight is a no-op.
Stopping also discards anything queued behind the run. Those prompts were written for work the user has just called off; delivering them afterwards would restart it in their name.
func (*App) ClearProjectSessions ¶
func (*App) DeleteProject ¶
DeleteProject removes a Project. Its sessions go only when deleteSessions says so.
A Project and its sessions are separate things to destroy, so removing one never silently takes the other: a Project that still has sessions is refused with the count, and the caller comes back having told the user what will be lost. See docs/design/local-project-memory.md §15.
func (*App) DeleteSession ¶
func (*App) DeliverNextJobEvent ¶
DeliverNextJobEvent runs one parked background event for the given session as its own streaming turn, mirroring SendMessageStream's serialization. It returns false when nothing was started: no parked event, or a run already in flight — the parked event then simply waits for the next trigger. The frontend calls it when the session is on screen and idle.
func (*App) DoLogin ¶
func (a *App) DoLogin(serverURL, email, otp string) (*AuthStatus, error)
DoLogin authenticates with a single-use login code and saves credentials on success. It is the recovery path: claiming a new account, or getting back in after a forgotten password.
func (*App) DoLoginWithPassword ¶
func (a *App) DoLoginWithPassword(serverURL, email, password string) (*AuthStatus, error)
DoLoginWithPassword authenticates with a password and saves credentials on success. This is the everyday path.
func (*App) ForkSession ¶
func (a *App) ForkSession(projectID, sessionID, itemID string) (HistoryMoveResult, error)
ForkSession copies this session's history through itemID into a new session and returns it, leaving the original exactly as it was.
func (*App) GetAuthStatus ¶
func (a *App) GetAuthStatus() (*AuthStatus, error)
GetAuthStatus reports the stored login, if there is one, and whether it still works. The check runs here rather than on the first prompt so the answer arrives while the user is still deciding what to do.
func (*App) GetDefaultServerURL ¶
GetDefaultServerURL is what the sign-in form starts with. It reads the same settings.yaml key `buildmax login` does, so the two entry points offer the same address instead of the Desktop insisting on a local server someone has already configured away from.
func (*App) GetGitBranch ¶
GetGitBranch returns the current git branch for the given project's folder, or an empty string if the folder is not a git repository.
func (*App) GetHistoryPoints ¶
func (a *App) GetHistoryPoints(sessionID string) (HistoryPointsResult, error)
GetHistoryPoints lists what this session can be rewound to and forked from, each newest first.
It reads without the writer lock, so the picker still opens while a run is in flight. Only the move itself is refused then.
func (*App) GetJobOutput ¶
func (a *App) GetJobOutput(projectID, jobID, stream string, cursor uint64) (JobOutputPayload, error)
GetJobOutput reads one job's captured output incrementally. stream is "stdout" (default) or "stderr"; pass the previous next_cursor to continue.
func (*App) GetPlugins ¶
func (a *App) GetPlugins(projectID string) (PluginsResult, error)
GetPlugins returns what this project's runtime loaded.
It reads the runtime's snapshot rather than scanning again, so what is shown is what the running agent has — an install completed a moment ago appears once the runtime is rebuilt, which is the same rule every other surface has.
func (*App) GetRunStatus ¶
func (a *App) GetRunStatus(projectID, sessionID string) (RunStatusPayload, error)
func (*App) GetSession ¶
func (a *App) GetSession(sessionID string) (SessionDetail, error)
GetSession loads one session by ID and returns it for display.
func (*App) GetSlashAgents ¶
func (a *App) GetSlashAgents(projectID string) (SlashAgentsResult, error)
GetSlashAgents returns all agent types (builtin + user-defined) for the project.
func (*App) GetSlashMCP ¶
func (a *App) GetSlashMCP(projectID string) (SlashMCPResult, error)
GetSlashMCP returns the MCP server status for the given project.
func (*App) GetSlashModels ¶
func (a *App) GetSlashModels(projectID string) (SlashModelsResult, error)
GetSlashModels returns configured models and the active model for a project.
func (*App) GetSlashSkills ¶
func (a *App) GetSlashSkills(projectID string) (SlashSkillsResult, error)
GetSlashSkills returns all skills discovered for the given project.
func (*App) GetWorkspaceDiff ¶
func (a *App) GetWorkspaceDiff(projectID string) (git.WorkspaceDiff, error)
GetWorkspaceDiff returns the current git-backed changed-file view for a project.
func (*App) InstallPlugin ¶
func (a *App) InstallPlugin(name, version string, update bool) (InstallPluginPlan, error)
InstallPlugin downloads and installs a release.
It resolves again rather than taking the plan the app was shown: a release published between the two is a different install, and acting on a stale plan would put bytes on disk that nobody was shown.
func (*App) ListJobs ¶
func (a *App) ListJobs(projectID string) ([]JobPayload, error)
ListJobs returns the project's background jobs in creation order.
func (*App) ListProjects ¶
func (a *App) ListProjects() ([]localproject.Summary, error)
ListProjects returns the local Projects, most recently used first.
func (*App) ListSessions ¶
func (a *App) ListSessions() ([]session.ItemSummary, error)
ListSessions returns all sessions across all projects.
func (*App) Logout ¶
Logout clears stored credentials and revokes the session on the server.
A server that cannot be reached is not a failed logout: the credentials are gone from this machine either way, and returning an error would leave the UI showing someone as signed in when they are not. Signing out is what returns the app to local mode: the credentials are the mode, so removing them is the whole switch.
func (*App) OpenFolderDialog ¶
OpenFolderDialog opens a native directory picker and returns the selected path.
func (*App) OpenProject ¶
func (a *App) OpenProject(folderPath, name string) (*localproject.Summary, error)
OpenProject resolves a folder to its local Project, registering one the first time that folder is opened.
It replaces a create binding because adding a folder is no longer how a Project comes to exist: a worktree of a repository Desktop already knows opens that repository's Project rather than a second one beside it. A name is applied when given, so opening a folder and calling it something reads the way it looks.
func (*App) PendingJobDeliveries ¶
PendingJobDeliveries reports how many parked deliveries wait for a session.
func (*App) PlanPluginInstall ¶
func (a *App) PlanPluginInstall(name, version string, update bool) (InstallPluginPlan, error)
PlanPluginInstall resolves which release an install would take.
func (*App) ProjectMemory ¶
func (a *App) ProjectMemory(projectID string) (ProjectMemoryPayload, error)
ProjectMemory returns what this project remembers.
Read-only. Editing a memory from the desktop is the phase 3 surface in docs/design/local-project-memory.md §11.5, and needs the refusal path a digest-checked write can take; the files are editable in the meantime and the directory is returned so a person can open them.
func (*App) ProjectNotices ¶
ProjectNotices are the things the runtime wants said once when a project is opened: a project registered for a directory that may be a moved repository, and memory files that will be silently absent from every run until repaired.
A source missing for a whole session without anyone being told is the failure this prevents, and a desktop user never runs `buildmax doctor`. Building the runtime is what produces them, so this is also what warms it.
func (*App) QueuedMessages ¶
QueuedMessages returns the prompts waiting behind the project's in-flight run, oldest first. The frontend reads it when it switches back to a project whose queue events it was not mounted for.
func (*App) RenameProject ¶
RenameProject updates the name of a project.
func (*App) RenameSession ¶
func (*App) RequestOTP ¶
RequestOTP calls the server's OTP endpoint.
func (*App) RespondApproval ¶
RespondApproval is called by the frontend when the user answers a tool approval prompt. projectID must match the project that triggered the desktop/approval-request event. decision is "once", "session", or "deny"; anything else denies, so a frontend that falls out of step fails closed.
func (*App) RewindSession ¶
func (a *App) RewindSession(projectID, sessionID, itemID string) (HistoryMoveResult, error)
RewindSession removes itemID and everything after it, and returns the prompt for the composer to take back.
No session lifecycle hook fires. Nothing is starting or ending here — the user is editing history — and the transient open this needs is an artifact of Desktop not holding sessions, not an event a hook should be told about. The TUI, which rewinds a session it already has open, fires none either.
func (*App) SendMessageStream ¶
SendMessageStream runs a prompt in the given project and session with streaming. It returns immediately and emits desktop/stream-delta, then desktop/stream-done or desktop/stream-error. sessionID may be empty to start a new session.
At most one run per project may be in flight. A prompt submitted while one is active is queued and runs as its own turn once the current one finishes; the return value is that prompt's 1-based position in the queue, and 0 when the prompt started a run of its own. The position comes back as a return value rather than an event because it answers the caller's own call.
func (*App) SetPluginDisabled ¶
SetPluginDisabled stops a plugin loading, or lets it load again.
func (*App) SetProjectModel ¶
SetProjectModel switches the active model for a project's agent.
func (*App) Shutdown ¶
Shutdown closes all per-project AgentApp instances and cancels any in-flight runs.
func (*App) Startup ¶
Startup is called by Wails when the app is starting. AgentApp instances are created lazily on first use per project.
type ApprovalRequestPayload ¶
type ApprovalRequestPayload struct {
ProjectID string `json:"project_id"`
ToolName string `json:"tool_name"`
Args map[string]any `json:"args"`
}
ApprovalRequestPayload is emitted to the frontend when a tool call needs approval.
type AuthStatus ¶
type AuthStatus struct {
LoggedIn bool `json:"logged_in"`
ServerURL string `json:"server_url,omitempty"`
UserID string `json:"user_id,omitempty"`
Email string `json:"email,omitempty"`
Name string `json:"name,omitempty"`
// Expired means the stored login no longer works. The app stays in managed
// mode and refuses to run rather than quietly using local models, which
// would send prompts somewhere the user did not choose. Signing in again or
// signing out are the two ways out — see docs/design/client-modes.md
// section 8.
Expired bool `json:"expired,omitempty"`
// ExpiredDetail is what to tell the user, set only when Expired.
ExpiredDetail string `json:"expired_detail,omitempty"`
}
AuthStatus is who is signed in, and therefore which mode the app is in.
There is no mode field. A login is the mode: with one the app is managed and its models come from that server, without one it is local and they come from settings.yaml. Anything remembered alongside the credentials would be a second source of truth for one fact. See docs/design/client-modes.md section 3.
type DesktopApprovalHandler ¶
type DesktopApprovalHandler struct {
// contains filtered or unexported fields
}
DesktopApprovalHandler implements agent.ApprovalHandler for the Wails desktop app. It emits a Wails event to the frontend and blocks until RespondApproval is called.
func (*DesktopApprovalHandler) RequestApproval ¶
func (h *DesktopApprovalHandler) RequestApproval(ctx context.Context, name string, args map[string]any) agent.ApprovalDecision
RequestApproval emits an approval-request event to the frontend and blocks until the user responds via RespondApproval. Denies if the app context is not ready.
type HistoryMoveResult ¶
type HistoryMoveResult struct {
// SessionID is the session to display next: the same one after a rewind,
// the new child after a fork.
SessionID string `json:"session_id"`
Messages int `json:"messages"`
Tools []HistoryToolEffect `json:"tools,omitempty"`
// Prompt is the rewound message, for the composer to take back. Empty
// after a fork, which removes nothing.
Prompt string `json:"prompt,omitempty"`
// Attachments counts images the rewound message carried and the composer
// cannot restore.
Attachments int `json:"attachments,omitempty"`
}
HistoryMoveResult is what happened, for the report shown afterwards.
type HistoryPoint ¶
type HistoryPoint struct {
ItemID string `json:"item_id"`
Role string `json:"role"`
Content string `json:"content"`
Messages int `json:"messages"`
Tools []HistoryToolEffect `json:"tools,omitempty"`
}
HistoryPoint is one message a picker offers.
Messages and Tools describe the span choosing it affects, and the two operations mean opposite things by it. A rewind removes that span from this conversation and leaves the tools' effects on disk; a fork removes nothing — the original keeps all of it — but the copy begins without knowing that work happened. The surface chooses the reading; the binding reports the span once.
type HistoryPointsResult ¶
type HistoryPointsResult struct {
SessionID string `json:"session_id"`
Rewind []HistoryPoint `json:"rewind"`
Fork []HistoryPoint `json:"fork"`
}
HistoryPointsResult is the picker's whole input, consequences included.
The two lists are computed here rather than filtered in the frontend, because which messages an operation may be pointed at is a rule about the journal, not a presentation choice: rewind offers the prompts it can hand back, fork offers every message a turn ended on, and the head is a fork point but never a rewind one. Every point carries what choosing it would affect, rather than the surface asking again each time the selection moves: the computation is in-memory over a branch that is already loaded, and a round trip per keystroke would be the expensive half of an otherwise free question.
type HistoryToolEffect ¶
type HistoryToolEffect struct {
Name string `json:"name"`
// Interrupted marks a call that entered its tool and never reported back.
// It is the worse of the two: it may have changed as much as one that
// finished, and nothing recorded what.
Interrupted bool `json:"interrupted"`
}
HistoryToolEffect is one tool call on the far side of a chosen point.
type InstallPluginPlan ¶
type InstallPluginPlan struct {
Name string `json:"name"`
Version string `json:"version"`
Digest string `json:"digest"`
SizeBytes int64 `json:"size_bytes"`
PublishedBy string `json:"published_by,omitempty"`
AlreadyInstalled bool `json:"already_installed"`
Skills []string `json:"skills,omitempty"`
Subagents []string `json:"subagents,omitempty"`
MCP []string `json:"mcp,omitempty"`
Hooks []string `json:"hooks,omitempty"`
// MissingEnv names the variables this release reads that are not set here,
// which is the usual reason a plugin looks installed and does nothing.
MissingEnv []string `json:"missing_env,omitempty"`
// DirtySource says the release was packed from a working tree that was not
// the commit it names.
DirtySource bool `json:"dirty_source,omitempty"`
}
InstallPluginPlan is what an install would do, resolved before anything is downloaded so the app can show it while the decision is still open.
type JobDeliveryPayload ¶
type JobDeliveryPayload struct {
ProjectID string `json:"project_id"`
SessionID string `json:"session_id"`
JobID string `json:"job_id"`
Source string `json:"source"`
Title string `json:"title"`
}
JobDeliveryPayload describes the delivery turn that just started.
type JobDeliveryPendingPayload ¶
type JobDeliveryPendingPayload struct {
ProjectID string `json:"project_id"`
SessionID string `json:"session_id"`
Pending int `json:"pending"`
}
JobDeliveryPendingPayload reports parked deliveries for one session.
type JobOutputPayload ¶
type JobOutputPayload struct {
Data string `json:"data"`
NextCursor uint64 `json:"next_cursor"`
Dropped uint64 `json:"dropped,omitempty"`
Running bool `json:"running"`
State string `json:"state"`
}
JobOutputPayload is one incremental output read.
type JobPayload ¶
type JobPayload struct {
ProjectID string `json:"project_id"`
ID string `json:"id"`
Kind string `json:"kind"`
State string `json:"state"`
StopReason string `json:"stop_reason,omitempty"`
ExitCode int `json:"exit_code,omitempty"`
Error string `json:"error,omitempty"`
Command string `json:"command"`
SessionID string `json:"session_id,omitempty"`
Running bool `json:"running"`
CreatedAt string `json:"created_at"`
EndedAt string `json:"ended_at,omitempty"`
}
JobPayload is one background job as the frontend sees it.
type MemoryEntry ¶
type MemoryEntry struct {
Name string `json:"name"`
Type string `json:"type"`
Description string `json:"description"`
Body string `json:"body"`
UpdatedAt string `json:"updated_at,omitempty"`
VerifiedAt string `json:"verified_at,omitempty"`
}
MemoryEntry is one of a project's memories as the desktop shows it.
It carries the body, unlike the index a model is given: a person opening their own memories is not paying a per-call context cost, and the body is where the reason lives. The frontend still shows one at a time, because a list of twenty bodies is not a list.
type MemorySkipped ¶
MemorySkipped is a memory file that could not be used. It is reported rather than omitted: such a memory is silently absent from every run until someone repairs it.
type MessageBlockedPayload ¶
type MessageBlockedPayload struct {
Prompt string `json:"prompt"`
Reason string `json:"reason"`
Queued []string `json:"queued"`
}
MessageBlockedPayload is emitted when a hook refuses a queued prompt (event desktop/message-blocked). It reports one message, not the end of the run — the run carries on with what it already had.
type MessageDequeuedPayload ¶
type MessageDequeuedPayload struct {
Prompt string `json:"prompt"`
Queued []string `json:"queued"`
}
MessageDequeuedPayload is emitted just before a queued prompt starts its own turn (event desktop/message-dequeued), so the transcript can show it as sent.
type PluginEntry ¶
type PluginEntry struct {
Name string `json:"name"`
DisplayName string `json:"display_name"`
Description string `json:"description,omitempty"`
Path string `json:"path"`
Source string `json:"source"`
// State is active, disabled, refused, or error — a decision and a defect
// are different things and a reader should not have to tell them apart
// from a message.
State string `json:"state"`
Version string `json:"version,omitempty"`
Digest string `json:"digest,omitempty"`
RemoteURL string `json:"remote_url,omitempty"`
Branch string `json:"branch,omitempty"`
Commit string `json:"commit,omitempty"`
Dirty bool `json:"dirty,omitempty"`
Skills []string `json:"skills,omitempty"`
Subagents []string `json:"subagents,omitempty"`
MCP []string `json:"mcp,omitempty"`
Hooks []string `json:"hooks,omitempty"`
Env []PluginEnvVar `json:"env,omitempty"`
// Shadowed names what a higher layer overrode, so a plugin does not read
// as fully active while part of it never loads.
Shadowed []string `json:"shadowed,omitempty"`
Problems []string `json:"problems,omitempty"`
}
PluginEntry is one installed plugin as the app shows it.
type PluginEnvVar ¶
type PluginEnvVar struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
Required bool `json:"required"`
Set bool `json:"set"`
}
PluginEnvVar is one declared environment variable and whether it is set here.
type PluginsResult ¶
type PluginsResult struct {
Dir string `json:"dir"`
Plugins []PluginEntry `json:"plugins"`
// AllowedSources is the operator's restriction, empty when there is none.
AllowedSources []string `json:"allowed_sources,omitempty"`
// Notes are directory-level findings: a stray directory, unreadable state.
Notes []string `json:"notes,omitempty"`
}
PluginsResult is the project's plugin inventory.
type ProjectMemoryPayload ¶
type ProjectMemoryPayload struct {
ProjectName string `json:"project_name"`
Directory string `json:"directory"`
// IndexChars is what the index costs on every model call and IndexBudget
// what it may cost. That pair is what a person prunes against, not the
// count.
IndexChars int `json:"index_chars"`
IndexBudget int `json:"index_budget"`
// Unavailable distinguishes a store that could not be read from one with
// nothing in it.
Memories []MemoryEntry `json:"memories"`
Skipped []MemorySkipped `json:"skipped,omitempty"`
}
ProjectMemoryPayload is what a project remembers, for the memory drawer.
type ReplyPayload ¶
type ReplyPayload struct {
Reply string `json:"reply"`
SessionID string `json:"session_id"`
ContextTokens int `json:"context_tokens"`
ContextWindow int `json:"context_window"`
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalPromptTokens int `json:"total_prompt_tokens"`
TotalCompletionTokens int `json:"total_completion_tokens"`
// Cache counts are the cached parts of the prompt counts above, not extra
// tokens to add to them.
CacheReadTokens int `json:"cache_read_tokens"`
CacheWriteTokens int `json:"cache_write_tokens"`
TotalCacheReadTokens int `json:"total_cache_read_tokens"`
TotalCacheWriteTokens int `json:"total_cache_write_tokens"`
}
ReplyPayload is returned when a desktop prompt completes successfully.
type RunStatusPayload ¶
type RunStatusPayload struct {
ContextTokens int `json:"context_tokens"`
ContextWindow int `json:"context_window"`
PromptTokens int `json:"prompt_tokens"`
CompletionTokens int `json:"completion_tokens"`
TotalPromptTokens int `json:"total_prompt_tokens"`
TotalCompletionTokens int `json:"total_completion_tokens"`
CacheReadTokens int `json:"cache_read_tokens"`
CacheWriteTokens int `json:"cache_write_tokens"`
TotalCacheReadTokens int `json:"total_cache_read_tokens"`
TotalCacheWriteTokens int `json:"total_cache_write_tokens"`
}
type SessionDetail ¶
type SessionDetail struct {
ID string `json:"id"`
Title string `json:"title,omitempty"`
CreatedAt string `json:"created_at"`
Messages []llm.Message `json:"messages,omitempty"`
}
SessionDetail is the session payload returned to the frontend for display.
type SlashAgentEntry ¶
type SlashAgentsResult ¶
type SlashAgentsResult struct {
Agents []SlashAgentEntry `json:"agents"`
}
type SlashMCPResult ¶
type SlashMCPResult struct {
LoadError string `json:"load_error,omitempty"`
Servers []SlashMCPServer `json:"servers"`
}
type SlashMCPServer ¶
type SlashModelEntry ¶
type SlashModelEntry struct {
Name string `json:"name"`
ProviderModel string `json:"provider_model,omitempty"`
IsCurrent bool `json:"is_current"`
// Destination is the provider endpoint a local model is called at. Empty in
// managed mode, where the deployment on the result says where every prompt
// goes and no model has an endpoint of its own.
Destination string `json:"destination,omitempty"`
}
type SlashModelsResult ¶
type SlashModelsResult struct {
Current string `json:"current"`
// Managed and ServerURL say where every prompt in this session goes. It is
// the app's mode, not a property of one model, so the picker states it once
// above the list. See docs/design/client-modes.md.
Managed bool `json:"managed"`
ServerURL string `json:"server_url,omitempty"`
Models []SlashModelEntry `json:"models"`
}
type SlashSkillEntry ¶
type SlashSkillsResult ¶
type SlashSkillsResult struct {
Skills []SlashSkillEntry `json:"skills"`
}
type StreamErrorPayload ¶
type StreamErrorPayload struct {
Message string `json:"message"`
}
StreamErrorPayload is emitted when streaming fails (event desktop/stream-error).
type ToolEndPayload ¶
type ToolEndPayload struct {
ToolCallID string `json:"tool_call_id"`
ToolName string `json:"tool_name"`
DurationMs int64 `json:"duration_ms,omitempty"`
IsError bool `json:"is_error,omitempty"`
Denied bool `json:"denied,omitempty"`
Reason string `json:"reason,omitempty"`
}
ToolEndPayload is emitted when a tool call finishes or is denied.
type ToolStartPayload ¶
type ToolStartPayload struct {
ToolCallID string `json:"tool_call_id"`
ToolName string `json:"tool_name"`
Args string `json:"args"`
}
ToolStartPayload is emitted when a tool call begins executing.
type TurnDigestPayload ¶
type TurnDigestPayload struct {
// Recap is a short account of what the turn did, or "" when it earned none.
Recap string `json:"recap"`
// Suggestion is the answer the user is likely about to give, or "" when the
// turn did not end by asking them anything.
Suggestion string `json:"suggestion"`
}
TurnDigestPayload is what the finished turn is worth telling the user, and nothing the model will read again (event desktop/turn-digest). It is emitted once per turn rather than with stream-done, because a run that drains a queue runs several turns and each one's recap describes only itself.
It deliberately does not travel in the message list: stream-done reloads the thread from the session, and neither of these is in the session.