chat

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Apr 5, 2026 License: MIT Imports: 38 Imported by: 0

Documentation

Index

Constants

View Source
const (
	DefaultMaxTurns     = 10
	DefaultMaxBudgetUSD = 2.0
)
View Source
const (
	DefaultSkillRefinementMaxAttempts = 3
)

Variables

View Source
var (
	ErrConversationNotFound         = chatrepo.ErrNotFound
	ErrConversationConflict         = chatrepo.ErrConflict
	ErrConversationTurnActive       = chatrepo.ErrTurnAlreadyActive
	ErrConversationInterruptPending = domain.ErrInterruptPending
	ErrPendingInterruptNotFound     = chatrepo.ErrNotFound
	ErrConversationRuntimeAbsent    = fmt.Errorf("chat conversation runtime is unavailable")
)
View Source
var (
	ErrUnavailable             = errors.New("chat service unavailable")
	ErrSourceUnsupported       = errors.New("chat source is unsupported")
	ErrProviderNotFound        = errors.New("chat-capable provider not found for project")
	ErrProviderUnsupported     = errors.New("chat provider does not support ephemeral chat")
	ErrProviderUnavailable     = errors.New("chat provider is unavailable")
	ErrSessionNotFound         = errors.New("chat session not found")
	ErrSessionProviderMismatch = errors.New("chat session cannot resume across providers")
	ErrSessionTurnLimitReached = errors.New("chat session reached the turn limit; please create a ticket for further work")
	ErrSessionBudgetExceeded   = errors.New("chat session reached the budget cap; please create a ticket for further work")
)
View Source
var (
	ErrSkillRefinementUnavailable     = errors.New("skill refinement service unavailable")
	ErrSkillRefinementSessionNotFound = errors.New("skill refinement session not found")
)

Functions

This section is empty.

Types

type ClaudeRuntime

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

func NewClaudeRuntime

func NewClaudeRuntime(adapter provider.ClaudeCodeAdapter) *ClaudeRuntime

func (*ClaudeRuntime) CloseSession

func (r *ClaudeRuntime) CloseSession(sessionID SessionID) bool

func (*ClaudeRuntime) RespondInterrupt

func (r *ClaudeRuntime) RespondInterrupt(
	ctx context.Context,
	input RuntimeInterruptResponseInput,
) (TurnStream, error)

func (*ClaudeRuntime) SessionAnchor

func (r *ClaudeRuntime) SessionAnchor(sessionID SessionID) RuntimeSessionAnchor

func (*ClaudeRuntime) StartTurn

func (r *ClaudeRuntime) StartTurn(ctx context.Context, input RuntimeTurnInput) (TurnStream, error)

func (*ClaudeRuntime) Supports

func (r *ClaudeRuntime) Supports(providerItem catalogdomain.AgentProvider) bool

type CodexRuntime

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

func NewCodexRuntime

func NewCodexRuntime(adapter *codexadapter.Adapter) *CodexRuntime

func (*CodexRuntime) CloseSession

func (r *CodexRuntime) CloseSession(sessionID SessionID) bool

func (*CodexRuntime) EnsureSession

func (r *CodexRuntime) EnsureSession(ctx context.Context, input RuntimeTurnInput) error

func (*CodexRuntime) RespondInterrupt

func (r *CodexRuntime) RespondInterrupt(
	ctx context.Context,
	input RuntimeInterruptResponseInput,
) (TurnStream, error)

func (*CodexRuntime) SessionAnchor

func (r *CodexRuntime) SessionAnchor(sessionID SessionID) RuntimeSessionAnchor

func (*CodexRuntime) StartTurn

func (r *CodexRuntime) StartTurn(ctx context.Context, input RuntimeTurnInput) (TurnStream, error)

func (*CodexRuntime) Supports

func (r *CodexRuntime) Supports(providerItem catalogdomain.AgentProvider) bool

type Context

type Context struct {
	ProjectID      uuid.UUID
	WorkflowID     *uuid.UUID
	TicketID       *uuid.UUID
	HarnessDraft   *string
	SkillID        *uuid.UUID
	SkillFilePath  *string
	SkillFileDraft *string
	ProjectFocus   *ProjectConversationFocus
}

type GeminiRuntime

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

func NewGeminiRuntime

func NewGeminiRuntime(processManager provider.AgentCLIProcessManager) *GeminiRuntime

func (*GeminiRuntime) CloseSession

func (r *GeminiRuntime) CloseSession(sessionID SessionID) bool

func (*GeminiRuntime) StartTurn

func (r *GeminiRuntime) StartTurn(ctx context.Context, input RuntimeTurnInput) (TurnStream, error)

func (*GeminiRuntime) Supports

func (r *GeminiRuntime) Supports(providerItem catalogdomain.AgentProvider) bool

type ProjectConversationFocusKind

type ProjectConversationFocusKind string
const (
	ProjectConversationFocusWorkflow ProjectConversationFocusKind = "workflow"
	ProjectConversationFocusSkill    ProjectConversationFocusKind = "skill"
	ProjectConversationFocusTicket   ProjectConversationFocusKind = "ticket"
	ProjectConversationFocusMachine  ProjectConversationFocusKind = "machine"
)

type ProjectConversationMachineFocus

type ProjectConversationMachineFocus struct {
	ID            uuid.UUID
	Name          string
	Host          string
	Status        string
	SelectedArea  string
	HealthSummary string
}

type ProjectConversationMuxEvent

type ProjectConversationMuxEvent struct {
	Event          string
	ConversationID uuid.UUID
	Payload        any
	SentAt         time.Time
}

type ProjectConversationService

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

func NewProjectConversationService

func NewProjectConversationService(
	logger *slog.Logger,
	stores projectConversationStoreSource,
	catalog projectConversationCatalog,
	tickets ticketReader,
	workflows workflowReader,
	localProcessManager provider.AgentCLIProcessManager,
	sshPool *sshinfra.Pool,
) *ProjectConversationService

func (*ProjectConversationService) AppendActionExecutionResult

func (s *ProjectConversationService) AppendActionExecutionResult(
	ctx context.Context,
	userID UserID,
	conversationID uuid.UUID,
	turnID *uuid.UUID,
	payload map[string]any,
) (domain.Entry, error)

func (*ProjectConversationService) CloseRuntime

func (s *ProjectConversationService) CloseRuntime(ctx context.Context, userID UserID, conversationID uuid.UUID) error

func (*ProjectConversationService) ConfigureGitHubCredentials

func (s *ProjectConversationService) ConfigureGitHubCredentials(resolver githubauthservice.TokenResolver)

func (*ProjectConversationService) ConfigurePlatformEnvironment

func (s *ProjectConversationService) ConfigurePlatformEnvironment(
	apiURL string,
	platform projectConversationAgentPlatform,
)

func (*ProjectConversationService) CreateConversation

func (s *ProjectConversationService) CreateConversation(
	ctx context.Context,
	userID UserID,
	projectID uuid.UUID,
	providerID uuid.UUID,
) (domain.Conversation, error)

func (*ProjectConversationService) GetConversation

func (s *ProjectConversationService) GetConversation(ctx context.Context, userID UserID, conversationID uuid.UUID) (domain.Conversation, error)

func (*ProjectConversationService) GetPrincipal

func (s *ProjectConversationService) GetPrincipal(ctx context.Context, userID UserID, conversationID uuid.UUID) (domain.ProjectConversationPrincipal, error)

func (*ProjectConversationService) GetWorkspaceDiff

func (s *ProjectConversationService) GetWorkspaceDiff(
	ctx context.Context,
	userID UserID,
	conversationID uuid.UUID,
) (ProjectConversationWorkspaceDiff, error)

func (*ProjectConversationService) ListConversations

func (s *ProjectConversationService) ListConversations(
	ctx context.Context,
	userID UserID,
	projectID uuid.UUID,
	providerID *uuid.UUID,
) ([]domain.Conversation, error)

func (*ProjectConversationService) ListEntries

func (s *ProjectConversationService) ListEntries(ctx context.Context, userID UserID, conversationID uuid.UUID) ([]domain.Entry, error)

func (*ProjectConversationService) RespondInterrupt

func (s *ProjectConversationService) RespondInterrupt(
	ctx context.Context,
	userID UserID,
	conversationID uuid.UUID,
	interruptID uuid.UUID,
	response domain.InterruptResponse,
) (domain.PendingInterrupt, error)

func (*ProjectConversationService) StartTurn

func (s *ProjectConversationService) StartTurn(
	ctx context.Context,
	userID UserID,
	conversationID uuid.UUID,
	message string,
	focus *ProjectConversationFocus,
) (domain.Turn, error)

func (*ProjectConversationService) WatchConversation

func (s *ProjectConversationService) WatchConversation(
	ctx context.Context,
	conversationID uuid.UUID,
) (<-chan StreamEvent, func())

func (*ProjectConversationService) WatchProjectConversations

func (s *ProjectConversationService) WatchProjectConversations(
	ctx context.Context,
	userID UserID,
	projectID uuid.UUID,
) (<-chan ProjectConversationMuxEvent, func(), error)

type ProjectConversationSkillFocus

type ProjectConversationSkillFocus struct {
	ID                 uuid.UUID
	Name               string
	SelectedFilePath   string
	BoundWorkflowNames []string
	HasDirtyDraft      bool
}

type ProjectConversationTicketActivity

type ProjectConversationTicketActivity struct {
	EventType string
	Message   string
	CreatedAt string
}

type ProjectConversationTicketAssignedAgent

type ProjectConversationTicketAssignedAgent struct {
	ID                  string
	Name                string
	Provider            string
	RuntimeControlState string
	RuntimePhase        string
}

type ProjectConversationTicketDependency

type ProjectConversationTicketDependency struct {
	Identifier string
	Title      string
	Relation   string
	Status     string
}

type ProjectConversationTicketFocus

type ProjectConversationTicketFocus struct {
	ID             uuid.UUID
	Identifier     string
	Title          string
	Description    string
	Status         string
	Priority       string
	AttemptCount   int
	RetryPaused    bool
	PauseReason    string
	SelectedArea   string
	Dependencies   []ProjectConversationTicketDependency
	RepoScopes     []ProjectConversationTicketRepoScope
	RecentActivity []ProjectConversationTicketActivity
	HookHistory    []ProjectConversationTicketHook
	AssignedAgent  *ProjectConversationTicketAssignedAgent
	CurrentRun     *ProjectConversationTicketRun
	TargetMachine  *ProjectConversationTicketTargetMachine
}

type ProjectConversationTicketHook

type ProjectConversationTicketHook struct {
	HookName  string
	Status    string
	Output    string
	Timestamp string
}

type ProjectConversationTicketRepoScope

type ProjectConversationTicketRepoScope struct {
	RepoID         string
	RepoName       string
	BranchName     string
	PullRequestURL string
}

type ProjectConversationTicketRun

type ProjectConversationTicketRun struct {
	ID                 string
	AttemptNumber      int
	Status             string
	CurrentStepStatus  string
	CurrentStepSummary string
	LastError          string
}

type ProjectConversationTicketTargetMachine

type ProjectConversationTicketTargetMachine struct {
	ID   string
	Name string
	Host string
}

type ProjectConversationWorkflowFocus

type ProjectConversationWorkflowFocus struct {
	ID            uuid.UUID
	Name          string
	Type          string
	HarnessPath   string
	IsActive      bool
	SelectedArea  string
	HasDirtyDraft bool
}

type ProjectConversationWorkspaceDiff

type ProjectConversationWorkspaceDiff struct {
	ConversationID uuid.UUID
	WorkspacePath  string
	Dirty          bool
	ReposChanged   int
	FilesChanged   int
	Added          int
	Removed        int
	Repos          []ProjectConversationWorkspaceRepoDiff
}

type ProjectConversationWorkspaceFileDiff

type ProjectConversationWorkspaceFileDiff struct {
	Path    string
	Status  ProjectConversationWorkspaceFileStatus
	Added   int
	Removed int
}

type ProjectConversationWorkspaceFileStatus

type ProjectConversationWorkspaceFileStatus string
const (
	ProjectConversationWorkspaceFileStatusModified  ProjectConversationWorkspaceFileStatus = "modified"
	ProjectConversationWorkspaceFileStatusAdded     ProjectConversationWorkspaceFileStatus = "added"
	ProjectConversationWorkspaceFileStatusDeleted   ProjectConversationWorkspaceFileStatus = "deleted"
	ProjectConversationWorkspaceFileStatusRenamed   ProjectConversationWorkspaceFileStatus = "renamed"
	ProjectConversationWorkspaceFileStatusUntracked ProjectConversationWorkspaceFileStatus = "untracked"
)

type ProjectConversationWorkspaceRepoDiff

type ProjectConversationWorkspaceRepoDiff struct {
	Name         string
	Path         string
	Branch       string
	Dirty        bool
	FilesChanged int
	Added        int
	Removed      int
	Files        []ProjectConversationWorkspaceFileDiff
}

type RawChatContext

type RawChatContext struct {
	ProjectID      *string `json:"project_id"`
	WorkflowID     *string `json:"workflow_id"`
	TicketID       *string `json:"ticket_id"`
	HarnessDraft   *string `json:"harness_draft"`
	SkillID        *string `json:"skill_id"`
	SkillFilePath  *string `json:"skill_file_path"`
	SkillFileDraft *string `json:"skill_file_draft"`
}

type RawProjectConversationFocus

type RawProjectConversationFocus struct {
	Kind                 string                                     `json:"kind"`
	WorkflowID           *string                                    `json:"workflow_id"`
	WorkflowName         *string                                    `json:"workflow_name"`
	WorkflowType         *string                                    `json:"workflow_type"`
	HarnessPath          *string                                    `json:"harness_path"`
	IsActive             *bool                                      `json:"is_active"`
	SelectedArea         *string                                    `json:"selected_area"`
	HasDirtyDraft        *bool                                      `json:"has_dirty_draft"`
	SkillID              *string                                    `json:"skill_id"`
	SkillName            *string                                    `json:"skill_name"`
	SelectedFilePath     *string                                    `json:"selected_file_path"`
	BoundWorkflowNames   []string                                   `json:"bound_workflow_names"`
	TicketID             *string                                    `json:"ticket_id"`
	TicketIdentifier     *string                                    `json:"ticket_identifier"`
	TicketTitle          *string                                    `json:"ticket_title"`
	TicketDescription    *string                                    `json:"ticket_description"`
	TicketStatus         *string                                    `json:"ticket_status"`
	TicketPriority       *string                                    `json:"ticket_priority"`
	TicketAttemptCount   *int                                       `json:"ticket_attempt_count"`
	TicketRetryPaused    *bool                                      `json:"ticket_retry_paused"`
	TicketPauseReason    *string                                    `json:"ticket_pause_reason"`
	TicketDependencies   []RawProjectConversationTicketDependency   `json:"ticket_dependencies"`
	TicketRepoScopes     []RawProjectConversationTicketRepoScope    `json:"ticket_repo_scopes"`
	TicketRecentActivity []RawProjectConversationTicketActivity     `json:"ticket_recent_activity"`
	TicketHookHistory    []RawProjectConversationTicketHook         `json:"ticket_hook_history"`
	TicketAssignedAgent  *RawProjectConversationTicketAssignedAgent `json:"ticket_assigned_agent"`
	TicketCurrentRun     *RawProjectConversationTicketRun           `json:"ticket_current_run"`
	TicketTargetMachine  *RawProjectConversationTicketTargetMachine `json:"ticket_target_machine"`
	MachineID            *string                                    `json:"machine_id"`
	MachineName          *string                                    `json:"machine_name"`
	MachineHost          *string                                    `json:"machine_host"`
	MachineStatus        *string                                    `json:"machine_status"`
	HealthSummary        *string                                    `json:"health_summary"`
}

type RawProjectConversationTicketActivity

type RawProjectConversationTicketActivity struct {
	EventType *string `json:"event_type"`
	Message   *string `json:"message"`
	CreatedAt *string `json:"created_at"`
}

type RawProjectConversationTicketAssignedAgent

type RawProjectConversationTicketAssignedAgent struct {
	ID                  *string `json:"id"`
	Name                *string `json:"name"`
	Provider            *string `json:"provider"`
	RuntimeControlState *string `json:"runtime_control_state"`
	RuntimePhase        *string `json:"runtime_phase"`
}

type RawProjectConversationTicketDependency

type RawProjectConversationTicketDependency struct {
	Identifier *string `json:"identifier"`
	Title      *string `json:"title"`
	Relation   *string `json:"relation"`
	Status     *string `json:"status"`
}

type RawProjectConversationTicketHook

type RawProjectConversationTicketHook struct {
	HookName  *string `json:"hook_name"`
	Status    *string `json:"status"`
	Output    *string `json:"output"`
	Timestamp *string `json:"timestamp"`
}

type RawProjectConversationTicketRepoScope

type RawProjectConversationTicketRepoScope struct {
	RepoID         *string `json:"repo_id"`
	RepoName       *string `json:"repo_name"`
	BranchName     *string `json:"branch_name"`
	PullRequestURL *string `json:"pull_request_url"`
}

type RawProjectConversationTicketRun

type RawProjectConversationTicketRun struct {
	ID                 *string `json:"id"`
	AttemptNumber      *int    `json:"attempt_number"`
	Status             *string `json:"status"`
	CurrentStepStatus  *string `json:"current_step_status"`
	CurrentStepSummary *string `json:"current_step_summary"`
	LastError          *string `json:"last_error"`
}

type RawProjectConversationTicketTargetMachine

type RawProjectConversationTicketTargetMachine struct {
	ID   *string `json:"id"`
	Name *string `json:"name"`
	Host *string `json:"host"`
}

type RawStartInput

type RawStartInput struct {
	Message    string         `json:"message"`
	Source     string         `json:"source"`
	ProviderID *string        `json:"provider_id"`
	Context    RawChatContext `json:"context"`
	SessionID  *string        `json:"session_id"`
}

type Runtime

type Runtime interface {
	Supports(catalogdomain.AgentProvider) bool
	StartTurn(context.Context, RuntimeTurnInput) (TurnStream, error)
	CloseSession(SessionID) bool
}

func NewRuntime

func NewRuntime(runtimes ...Runtime) Runtime

type RuntimeInterruptDecision

type RuntimeInterruptDecision struct {
	ID    string `json:"id"`
	Label string `json:"label"`
}

type RuntimeInterruptEvent

type RuntimeInterruptEvent struct {
	RequestID string                     `json:"request_id"`
	Kind      string                     `json:"kind"`
	Options   []RuntimeInterruptDecision `json:"options,omitempty"`
	Payload   map[string]any             `json:"payload,omitempty"`
}

type RuntimeInterruptResponseInput

type RuntimeInterruptResponseInput struct {
	SessionID              SessionID
	Provider               catalogdomain.AgentProvider
	RequestID              string
	Kind                   string
	Decision               string
	Answer                 map[string]any
	Payload                map[string]any
	WorkingDirectory       provider.AbsolutePath
	Environment            []string
	ResumeProviderThreadID string
	ResumeProviderTurnID   string
	PersistentConversation bool
}

type RuntimeSessionAnchor

type RuntimeSessionAnchor struct {
	ProviderThreadID          string
	LastTurnID                string
	ProviderThreadStatus      string
	ProviderThreadActiveFlags []string
	ProviderAnchorID          string
	ProviderAnchorKind        string
	ProviderTurnSupported     bool
}

type RuntimeTurnInput

type RuntimeTurnInput struct {
	SessionID              SessionID
	Provider               catalogdomain.AgentProvider
	Message                string
	SystemPrompt           string
	WorkingDirectory       provider.AbsolutePath
	Environment            []string
	ResumeProviderThreadID string
	ResumeProviderTurnID   string
	MaxTurns               int
	MaxBudgetUSD           float64
	PersistentConversation bool
}

type Service

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

func NewService

func NewService(
	logger *slog.Logger,
	runtime Runtime,
	catalog catalogReader,
	tickets ticketReader,
	workflows workflowReader,
	statuses statusReader,
	workingDir provider.AbsolutePath,
) *Service

func (*Service) CloseSession

func (s *Service) CloseSession(userID UserID, sessionID SessionID) bool

func (*Service) EnableDurableSessions

func (s *Service) EnableDurableSessions(path string)

func (*Service) StartTurn

func (s *Service) StartTurn(ctx context.Context, userID UserID, input StartInput) (TurnStream, error)

type SessionID

type SessionID string

func ParseCloseSessionID

func ParseCloseSessionID(raw string) (SessionID, error)

func ParseSessionID

func ParseSessionID(raw string) (SessionID, error)

func (SessionID) String

func (s SessionID) String() string

type SkillRefinementInput

type SkillRefinementInput struct {
	ProjectID  uuid.UUID
	SkillID    uuid.UUID
	ProviderID *uuid.UUID
	Message    string
	DraftFiles []workflowservice.SkillBundleFileInput
}

type SkillRefinementResultPayload

type SkillRefinementResultPayload struct {
	SessionID            string                            `json:"session_id"`
	Status               string                            `json:"status"`
	WorkspacePath        string                            `json:"workspace_path"`
	ProviderID           string                            `json:"provider_id"`
	ProviderName         string                            `json:"provider_name"`
	ProviderThreadID     string                            `json:"provider_thread_id,omitempty"`
	ProviderTurnID       string                            `json:"provider_turn_id,omitempty"`
	Attempts             int                               `json:"attempts"`
	TranscriptSummary    string                            `json:"transcript_summary,omitempty"`
	CommandOutputSummary string                            `json:"command_output_summary,omitempty"`
	FailureReason        string                            `json:"failure_reason,omitempty"`
	CandidateFiles       []workflowservice.SkillBundleFile `json:"candidate_files,omitempty"`
	CandidateBundleHash  string                            `json:"candidate_bundle_hash,omitempty"`
}

type SkillRefinementService

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

func NewSkillRefinementService

func NewSkillRefinementService(
	logger *slog.Logger,
	runtime skillRefinementRuntime,
	catalog catalogReader,
	workflows workflowReader,
) *SkillRefinementService

func (*SkillRefinementService) CloseSession

func (s *SkillRefinementService) CloseSession(userID UserID, sessionID SessionID) bool

func (*SkillRefinementService) ResolveSessionScopeForUser

func (s *SkillRefinementService) ResolveSessionScopeForUser(
	userID UserID,
	sessionID SessionID,
) (uuid.UUID, uuid.UUID, bool)

func (*SkillRefinementService) Start

type SkillRefinementSessionPayload

type SkillRefinementSessionPayload struct {
	SessionID     string `json:"session_id"`
	WorkspacePath string `json:"workspace_path"`
}

type SkillRefinementStatusPayload

type SkillRefinementStatusPayload struct {
	SessionID string `json:"session_id"`
	Phase     string `json:"phase"`
	Attempt   int    `json:"attempt"`
	Message   string `json:"message"`
}

type Source

type Source string
const (
	SourceHarnessEditor  Source = "harness_editor"
	SourceSkillEditor    Source = "skill_editor"
	SourceProjectSidebar Source = "project_sidebar"
	SourceTicketDetail   Source = "ticket_detail"
)

type StartInput

type StartInput struct {
	Message    string
	Source     Source
	ProviderID *uuid.UUID
	Context    Context
	SessionID  *SessionID
}

func ParseStartInput

func ParseStartInput(raw RawStartInput) (StartInput, error)

type StreamEvent

type StreamEvent struct {
	Event   string
	Payload any
}

type TurnStream

type TurnStream struct {
	Events <-chan StreamEvent
}

type UserID

type UserID string
const AnonymousUserID UserID = "anonymous"

func ParseRequestUserID

func ParseRequestUserID(raw string) (UserID, error)

func ParseUserID

func ParseUserID(raw string) (UserID, error)

func (UserID) String

func (u UserID) String() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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