conversation

package
v0.6.2 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2026 License: MIT Imports: 25 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MaxTitleRunes = 120
	ScopeChat     = "chat"
	ScopeProject  = "project"
	KindScratch   = "scratch"
	KindFolder    = "folder"
)

Variables

View Source
var ErrApprovalPending = errors.New("session: approval is pending")

ErrApprovalPending rejects new queued work while a tool permission decision is still waiting for the viewer.

View Source
var ErrImagesUnsupported = errors.New("session: selected model does not support images")

ErrImagesUnsupported rejects image attachments before a run is reserved when the session's selected model accepts text only.

View Source
var ErrInvalidPermissionMode = errors.New("session: invalid permission mode")

ErrInvalidPermissionMode reports a mode outside the product's supported session permission presets.

View Source
var ErrInvalidSessionScope = errors.New("session: invalid session scope")

ErrInvalidSessionScope reports a create request that is neither a standalone chat nor a project-backed conversation.

View Source
var ErrManagerClosed = errors.New("session: conversation manager is closed")

ErrManagerClosed rejects new work after product shutdown has started.

View Source
var ErrQuestionPending = errors.New("session: a question is pending")

ErrQuestionPending rejects new queued work while the agent's question is still waiting for the viewer to answer it.

View Source
var ErrQueuedMessageInFlight = errors.New("session: queued message is already being processed")

ErrQueuedMessageInFlight reports a message that already left the agent queue and can no longer be withdrawn.

View Source
var ErrQueuedMessageNotFound = errors.New("session: queued message not found")

ErrQueuedMessageNotFound reports an unknown browser-facing queue ID.

View Source
var ErrSessionActive = errors.New("session: session is running or waiting for approval")

ErrSessionActive prevents deleting a conversation while its run or approval gate still owns live resources.

View Source
var ErrSessionNotRunning = errors.New("session: session is not running")

ErrSessionNotRunning rejects a queued message after its run has ended.

Functions

func NewID

func NewID() string

NewID returns an identifier for a session or a queued message.

Types

type Delivery

type Delivery string
const (
	DeliverySteer    Delivery = "steer"
	DeliveryFollowUp Delivery = "followup"
)

type Event

type Event interface{ Event() }

Session state changes are described here as plain facts — a message was queued, a title changed — with no knowledge of how they reach a viewer. Projecting them onto a wire format belongs to whoever is delivering them.

type Manager

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

Manager owns every conversation across the registered workspaces. Metadata is kept in indexes while each transcript and details sidecar stays separate. Lock ordering: mu is always taken before the workspace registry's own lock. The registry never calls back into this package, so that ordering holds simply by never taking mu inside a registry call.

func NewManager

func NewManager(ctx context.Context, opts Options) (*Manager, error)

NewManager restores and validates the session index. Restored transcripts, transports, and engine sessions stay unloaded until the conversation is first opened. The ledger and registry are passed in because the HTTP layer also serves them directly.

func (*Manager) Abort

func (m *Manager) Abort(id string) error

Abort cancels the active run, if any.

func (*Manager) Close

func (m *Manager) Close()

Close stops accepting new work, cancels active runs and title generation, then releases every session-owned process. It is safe to call repeatedly.

func (*Manager) Compact

func (m *Manager) Compact(
	ctx context.Context,
	id string,
	instructions string,
) (engine.CompactionResult, error)

Compact reserves an idle session and performs one explicit context compaction. It blocks until the summary is durable.

func (*Manager) Create

func (m *Manager) Create(
	title, workspacePath, scope string,
	model llm.Model,
	thinking llm.ModelThinkingLevel,
	permissionMode permission.Mode,
) (Summary, error)

Create adds an empty, independently persisted conversation. Chat sessions receive an isolated, manager-owned workspace; project sessions use the caller-selected folder and never fall back to the process working directory.

func (*Manager) Delete

func (m *Manager) Delete(id string) error

Delete permanently removes one idle conversation and its persisted files. Files are staged under temporary names before the index is changed, so an index write failure can restore the conversation without data loss.

func (*Manager) DequeueMessage

func (m *Manager) DequeueMessage(sessionID, messageID string) error

DequeueMessage withdraws one queued message by its browser-facing ID.

func (*Manager) EnsureLoaded added in v0.6.2

func (m *Manager) EnsureLoaded(id string) error

EnsureLoaded opens one restored conversation on first use. Loading is serialized by the manager lock so concurrent history and SSE requests share one engine session and transport.

func (*Manager) List

func (m *Manager) List() []Summary

List returns newest-active first and samples each session's live state.

func (*Manager) QueueMessage

func (m *Manager) QueueMessage(id string, message QueuedMessage) error

QueueMessage submits one steer or follow-up to a running conversation.

func (*Manager) Rename

func (m *Manager) Rename(id, customTitle string) (Summary, error)

Rename sets a user-defined custom title on the session. An empty title clears the custom title so the display falls back to the AI or prompt-derived title.

func (*Manager) Snapshot

func (m *Manager) Snapshot(id string) (Snapshot, error)

Snapshot returns the current client-readable state without exposing the runtime that owns the engine session.

func (*Manager) StartPrompt

func (m *Manager) StartPrompt(id, prompt string, images ...llm.ImageContent) error

StartPrompt reserves a session and runs the prompt in the background. The manager owns the complete lifecycle so callers cannot forget to release the reservation or clean up queued messages.

func (*Manager) StartPromptWithFiles

func (m *Manager) StartPromptWithFiles(
	id string,
	prompt string,
	files []engine.AttachedFile,
	images ...llm.ImageContent,
) error

StartPromptWithFiles starts a prompt with validated text-file attachments.

func (*Manager) StopTask

func (m *Manager) StopTask(sessionID, taskID string) error

StopTask terminates one background task owned by the conversation.

func (*Manager) TaskOutput

func (m *Manager) TaskOutput(sessionID, taskID string) (engine.TaskOutput, error)

TaskOutput returns a bounded tail of one conversation task's logs.

func (*Manager) UpdatePermissionMode

func (m *Manager) UpdatePermissionMode(id string, mode permission.Mode) (Summary, error)

UpdatePermissionMode changes the baseline tool policy used by subsequent calls and persists it with the conversation.

func (*Manager) UpdateSettings

func (m *Manager) UpdateSettings(
	id string,
	model llm.Model,
	thinking llm.ModelThinkingLevel,
) (Summary, error)

UpdateSettings changes the model and reasoning effort used by the session's next prompt and persists the choice with that conversation.

func (*Manager) UsesProvider

func (m *Manager) UsesProvider(provider string) bool

UsesProvider reports whether any restored session currently references the provider.

func (*Manager) WorkspacePath

func (m *Manager) WorkspacePath(id string) (string, error)

WorkspacePath returns the tool root owned by one conversation.

type MessageAccepted

type MessageAccepted struct {
	ID       string
	Text     string
	Images   []llm.ImageContent
	Files    []engine.File
	Delivery Delivery
	Queued   bool
}

MessageAccepted reports a user message the server has taken responsibility for. Queued distinguishes one waiting behind a running turn from one the run has already picked up.

func (MessageAccepted) Event

func (MessageAccepted) Event()

type MessageCancelled

type MessageCancelled struct{ ID string }

MessageCancelled reports a queued message dropped because its run ended.

func (MessageCancelled) Event

func (MessageCancelled) Event()

type MessageDequeued

type MessageDequeued struct{ ID string }

MessageDequeued reports a queued message the user withdrew before it ran.

func (MessageDequeued) Event

func (MessageDequeued) Event()

type NewTransport

type NewTransport func(sessionID string) Transport

NewTransport builds the delivery link for one opened session. Manager calls it once when the session runtime loads and owns closing the returned transport.

type Options

type Options struct {
	DataDir        string
	Usage          *usage.Store
	Workspaces     *workspace.Registry
	NewTransport   NewTransport
	TitleGenerator titlegen.Generator
}

Options supplies the product services and storage root owned by a Manager.

type QueuedMessage

type QueuedMessage struct {
	ID       string
	Delivery Delivery
	Text     string
	Images   []llm.ImageContent
	Files    []engine.AttachedFile
}

type RunFailed

type RunFailed struct{ Text string }

RunFailed reports an asynchronous prompt failure to the viewer.

func (RunFailed) Event

func (RunFailed) Event()

type Snapshot

type Snapshot struct {
	History         []engine.HistoryItem
	Queue           []Event
	ContextUsage    engine.ContextUsage
	Tasks           []engine.BackgroundTask
	Running         bool
	Title           string
	AITitle         string
	CustomTitle     string
	TitleGeneration TitleGeneration
}

Snapshot is the complete client-readable state of one conversation.

type Summary

type Summary struct {
	ID              string                 `json:"id"`
	Title           string                 `json:"title"`
	AITitle         string                 `json:"aiTitle,omitempty"`
	CustomTitle     string                 `json:"customTitle,omitempty"`
	TitleGeneration TitleGeneration        `json:"titleGeneration"`
	WorkspacePath   string                 `json:"workspacePath"`
	WorkspaceName   string                 `json:"workspaceName"`
	Scope           string                 `json:"scope"`
	WorkspaceKind   string                 `json:"workspaceKind"`
	CreatedAt       time.Time              `json:"createdAt"`
	UpdatedAt       time.Time              `json:"updatedAt"`
	Running         bool                   `json:"running"`
	HasApproval     bool                   `json:"hasApproval"`
	HasQuestion     bool                   `json:"hasQuestion"`
	ModelProvider   string                 `json:"modelProvider"`
	ModelID         string                 `json:"modelId"`
	ModelName       string                 `json:"modelName"`
	ThinkingLevel   llm.ModelThinkingLevel `json:"thinkingLevel"`
	PermissionMode  permission.Mode        `json:"permissionMode"`
}

Summary is the browser-facing metadata for one independent coding conversation. Live state is sampled when the list is requested.

type TitleChanged

type TitleChanged struct {
	Title       string
	AITitle     string
	CustomTitle string
}

TitleChanged reports the session's display title and the two sources it is derived from, so a client can tell a user-set name from a generated one.

func (TitleChanged) Event

func (TitleChanged) Event()

type TitleGeneration

type TitleGeneration struct {
	Status      TitleGenerationStatus `json:"status"`
	Provider    string                `json:"provider,omitempty"`
	Model       string                `json:"model,omitempty"`
	ErrorCode   string                `json:"errorCode,omitempty"`
	Error       string                `json:"error,omitempty"`
	AttemptedAt string                `json:"attemptedAt,omitempty"`
}

TitleGeneration is runtime diagnostics for the background title request. Error is sanitized before it reaches this state and never contains secrets.

type TitleGenerationChanged

type TitleGenerationChanged struct{ Generation TitleGeneration }

func (TitleGenerationChanged) Event

func (TitleGenerationChanged) Event()

type TitleGenerationStatus

type TitleGenerationStatus string
const (
	TitleGenerationIdle        TitleGenerationStatus = "idle"
	TitleGenerationGenerating  TitleGenerationStatus = "generating"
	TitleGenerationSucceeded   TitleGenerationStatus = "succeeded"
	TitleGenerationFailed      TitleGenerationStatus = "failed"
	TitleGenerationUnavailable TitleGenerationStatus = "unavailable"
)

type Transport

type Transport interface {
	// Publish delivers a state change this session raised.
	Publish(Event)
	// PublishAgent delivers an event raised by the agent underneath.
	PublishAgent(engine.Event)
	// Decide gates one tool call, blocking until answered or cancelled.
	Decide(context.Context, permission.ApprovalRequest) (permission.ApprovalResponse, error)
	// HasPendingApproval reports a gate still waiting on a viewer.
	HasPendingApproval() bool
	// OpenBrowser delivers one validated agent navigation and waits for the
	// viewer's product shell to report its terminal result.
	OpenBrowser(context.Context, tools.BrowserRequest) (tools.BrowserResult, error)
	// Ask puts the agent's multiple-choice questions to the viewer and blocks
	// until they answer or the run is cancelled.
	Ask(context.Context, []tools.Question) ([]tools.Answer, error)
	// HasPendingQuestion reports a question still waiting on a viewer.
	HasPendingQuestion() bool
	// Close releases the delivery link after its session is removed.
	Close()
}

Transport is one session's link to whatever is watching it. The delivery layer supplies an implementation per session; this package never learns how an event is encoded or who receives it.

Decide and HasPendingApproval are here rather than on a separate type because a permission gate is a conversation with the same viewer: the session cannot know whether one is answerable without asking its transport.

Jump to

Keyboard shortcuts

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