web

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jul 18, 2026 License: AGPL-3.0 Imports: 31 Imported by: 0

Documentation

Index

Constants

View Source
const (
	SessionActive   = "active"
	SessionArchived = "archived"
)
View Source
const (
	ChatEventMessage        = "message"
	ChatEventMessageStart   = "message_start"
	ChatEventMessageDelta   = "message_delta"
	ChatEventMessageEnd     = "message_end"
	ChatEventToolCall       = "tool_call"
	ChatEventToolResult     = "tool_result"
	ChatEventThinking       = "thinking"
	ChatEventScanStarted    = "scan_started"
	ChatEventScanProgress   = "scan_progress"
	ChatEventScanComplete   = "scan_complete"
	ChatEventScanError      = "scan_error"
	ChatEventAgentJoined    = "agent_joined"
	ChatEventSessionCleared = "session_cleared"
	ChatEventEval           = "eval"
	ChatEventCompact        = "compact"
	ChatEventError          = "error"
)
View Source
const (
	SysNoRunningTask     = "no_running_task"
	SysPaused            = "paused"
	SysFileUploaded      = "file_uploaded" // params: filename, path
	SysNoAgentsConnected = "no_agents_connected"
	SysAgentsList        = "agents_list" // params: count, agents[]
	SysAgentNotConnected = "agent_not_connected"
)

System message codes. A backend-generated system message carries a stable Code (+ optional Params) so the client can localize it via i18n; Content holds an English fallback for non-i18n consumers, logs and tests. Keys are mirrored under `sys.*` in web/frontend/src/i18n/locales/*/chat.ts.

Variables

This section is empty.

Functions

func AccessKeyAuth added in v0.3.0

func AccessKeyAuth(key string) func(http.Handler) http.Handler

AccessKeyAuth returns middleware that gates requests behind a Bearer token. Requests without a valid token get a 401. An empty key disables auth (dev mode).

func ServeSSE

func ServeSSE(w http.ResponseWriter, r *http.Request, hub *Hub, id string, terminalEvents ...string)

func ValidateMode

func ValidateMode(mode string) (string, error)

func ValidateTarget

func ValidateTarget(raw string) (string, error)

Types

type AgentInfo

type AgentInfo struct {
	ID           string                 `json:"id"`
	Name         string                 `json:"name"`
	Commands     []string               `json:"commands,omitempty"`
	CommandsMenu []webproto.CommandSpec `json:"commands_menu,omitempty"`
	Busy         bool                   `json:"busy"`
	ConnectAt    time.Time              `json:"connected_at"`
	Identity     webproto.AgentIdentity `json:"identity,omitempty"`
	Stats        webproto.AgentStats    `json:"stats,omitempty"`
}

AgentInfo is the public view of a connected agent.

type AgentPool

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

AgentPool manages connected remote aiscan agents via WebSocket.

func NewAgentPool

func NewAgentPool(hub *Hub, allowedOrigins ...string) *AgentPool

func (*AgentPool) BroadcastConfigReload added in v0.3.0

func (p *AgentPool) BroadcastConfigReload() int

BroadcastConfigReload notifies every connected agent that the hub config changed so each re-fetches and hot-swaps its LLM provider without a restart. Best-effort: an agent whose send channel is full picks the change up on its next reconnect. Returns the number of agents notified.

func (*AgentPool) CancelPTY

func (p *AgentPool) CancelPTY(agentID, terminalID string)

func (*AgentPool) CancelTask

func (p *AgentPool) CancelTask(agentID, taskID string)

func (*AgentPool) CloseTerminal

func (p *AgentPool) CloseTerminal(agentID, terminalID string)

func (*AgentPool) Count

func (p *AgentPool) Count() int

func (*AgentPool) DispatchChat added in v0.2.8

func (p *AgentPool) DispatchChat(agentID, taskID, prompt string) (<-chan taskResult, error)

DispatchChat sends a natural-language prompt to an LLM-capable agent.

func (*AgentPool) DispatchChatSession added in v0.2.8

func (p *AgentPool) DispatchChatSession(agentID, taskID, sessionID, prompt string, opts webproto.ChatPayload) (<-chan taskResult, error)

DispatchChatSession sends chat input to an agent and scopes the remote agent-side conversation state to the web chat session. Goal-mode controls in opts (persist / eval criteria / turn caps) ride along so the agent can run the evaluator loop instead of a plain single-shot turn.

func (*AgentPool) DispatchCommand

func (p *AgentPool) DispatchCommand(agentID, taskID, command string) (<-chan taskResult, error)

DispatchCommand sends a command to an agent and returns a channel for the result.

func (*AgentPool) HandleTerminalWS

func (p *AgentPool) HandleTerminalWS(agentID string, w http.ResponseWriter, r *http.Request)

HandleTerminalWS bridges one browser terminal WebSocket to one remote agent. The browser sends pty.* messages; the pool assigns a stream_id and relays matching agent responses back.

func (*AgentPool) HandleWS

func (p *AgentPool) HandleWS(w http.ResponseWriter, r *http.Request)

HandleWS upgrades to WebSocket and manages the agent lifecycle. This single endpoint replaces register + stream + output + complete.

func (*AgentPool) List

func (p *AgentPool) List() []AgentInfo

func (*AgentPool) Pick

func (p *AgentPool) Pick() *remoteAgent

Pick selects an idle agent, or any agent if none idle.

func (*AgentPool) PickChat added in v0.2.8

func (p *AgentPool) PickChat() *remoteAgent

PickChat selects an idle LLM-capable agent, or any LLM-capable agent if all are busy.

func (*AgentPool) SendAgentMessage

func (p *AgentPool) SendAgentMessage(agentID string, msg WSMessage) error

func (*AgentPool) SetRecordStore added in v0.2.8

func (p *AgentPool) SetRecordStore(rs RecordStore)

func (*AgentPool) SetSessionLookup added in v0.2.8

func (p *AgentPool) SetSessionLookup(sl SessionLookup)

type ChatEvent added in v0.2.8

type ChatEvent struct {
	Type       string         `json:"type"`
	SessionID  string         `json:"session_id"`
	MessageID  string         `json:"message_id,omitempty"`
	Role       string         `json:"role,omitempty"`
	AgentID    string         `json:"agent_id,omitempty"`
	AgentName  string         `json:"agent_name,omitempty"`
	Turn       int            `json:"turn,omitempty"`
	Content    string         `json:"content,omitempty"`
	Delta      string         `json:"delta,omitempty"`
	ToolName   string         `json:"tool_name,omitempty"`
	ToolArgs   string         `json:"tool_args,omitempty"`
	ToolCallID string         `json:"tool_call_id,omitempty"`
	ScanID     string         `json:"scan_id,omitempty"`
	Result     *output.Result `json:"result,omitempty"`
	Data       string         `json:"data,omitempty"`
	Error      string         `json:"error,omitempty"`
	Code       string         `json:"code,omitempty"`
	Params     map[string]any `json:"params,omitempty"`
	// Goal-mode evaluator verdict, carried on ChatEventEval. EvalRound is
	// 0-indexed (the client renders round+1).
	EvalRound  int    `json:"eval_round,omitempty"`
	EvalPass   bool   `json:"eval_pass,omitempty"`
	EvalReason string `json:"eval_reason,omitempty"`

	CompactTokensBefore int `json:"compact_tokens_before,omitempty"`
	CompactTokensAfter  int `json:"compact_tokens_after,omitempty"`
	CompactKeptMessages int `json:"compact_kept_messages,omitempty"`

	Transient bool `json:"-"`
}

type ChatMessage added in v0.2.8

type ChatMessage struct {
	ID        string          `json:"id"`
	SessionID string          `json:"session_id"`
	Role      string          `json:"role"`
	AgentID   string          `json:"agent_id,omitempty"`
	AgentName string          `json:"agent_name,omitempty"`
	Content   string          `json:"content"`
	Metadata  json.RawMessage `json:"metadata,omitempty"`
	CreatedAt time.Time       `json:"created_at"`
}

type ChatSession added in v0.2.8

type ChatSession struct {
	ID        string    `json:"id"`
	AgentID   string    `json:"agent_id"`
	AgentName string    `json:"agent_name,omitempty"`
	Title     string    `json:"title"`
	Status    string    `json:"status"`
	TopicID   string    `json:"topic_id,omitempty"`
	ScanIDs   []string  `json:"scan_ids,omitempty"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

type ConfigStatus added in v0.2.8

type ConfigStatus struct {
	ConfigPath   string `json:"config_path,omitempty"`
	ConfigLoaded bool   `json:"config_loaded"`
	LLM          struct {
		Provider         string `json:"provider"`
		BaseURL          string `json:"base_url"`
		APIKeyConfigured bool   `json:"api_key_configured"`
		Model            string `json:"model"`
		Proxy            string `json:"proxy"`
	} `json:"llm"`
	Cyberhub struct {
		URL           string `json:"url"`
		KeyConfigured bool   `json:"key_configured"`
		Mode          string `json:"mode"`
		Proxy         string `json:"proxy"`
	} `json:"cyberhub"`
	Recon struct {
		FofaEmail              string `json:"fofa_email"`
		FofaKeyConfigured      bool   `json:"fofa_key_configured"`
		HunterTokenConfigured  bool   `json:"hunter_token_configured"`
		HunterAPIKeyConfigured bool   `json:"hunter_api_key_configured"`
		Proxy                  string `json:"proxy"`
		Limit                  *int   `json:"limit,omitempty"`
	} `json:"recon"`
	Scan struct {
		Verify string `json:"verify"`
	} `json:"scan"`
	Search struct {
		TavilyKeysConfigured bool `json:"tavily_keys_configured"`
	} `json:"search"`
	IOA struct {
		URL             string `json:"url"`
		TokenConfigured bool   `json:"token_configured"`
		NodeName        string `json:"node_name"`
		Space           string `json:"space"`
	} `json:"ioa"`
	Agent struct {
		Tools       []string `json:"tools,omitempty"`
		Timeout     int      `json:"timeout"`
		SaveSession bool     `json:"save_session"`
	} `json:"agent"`
}

ConfigStatus is the response for GET /api/config — secrets masked, *_configured booleans indicate whether a secret is set.

func ConfigStatusFromDistribute added in v0.2.8

func ConfigStatusFromDistribute(d *webproto.DistributeConfig, path string, loaded bool) ConfigStatus

ConfigStatusFromDistribute builds a masked ConfigStatus from raw config.

type ConfigStore added in v0.2.8

type ConfigStore interface {
	GetDistributeConfig(ctx context.Context) (path string, loaded bool, cfg webproto.DistributeConfig, err error)
	SaveDistributeConfig(ctx context.Context, cfg webproto.DistributeConfig) error
}

type CreateSessionRequest added in v0.2.8

type CreateSessionRequest struct {
	AgentID string `json:"agent_id"`
	Title   string `json:"title,omitempty"`
}

type Handler

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

func NewHandler

func NewHandler(service *Service, agents *AgentPool, local *LocalAgents, ioaHandler http.Handler, static http.Handler, accessKey string) *Handler

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

type Hub

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

func NewHub

func NewHub() *Hub

func (*Hub) Broadcast

func (h *Hub) Broadcast(id string, event HubEvent)

func (*Hub) Subscribe

func (h *Hub) Subscribe(id string) (<-chan HubEvent, func())

type HubEvent

type HubEvent struct {
	Type string
	Data json.RawMessage
	// Reliable marks a terminal event that Broadcast must not drop under
	// backpressure: on a full buffer it evicts the oldest queued event to seat
	// one, rather than shedding it like a token delta. See isTerminalChatEvent
	// for which events qualify and why a lost one strands the UI.
	Reliable bool
}

HubEvent is the unit broadcast through the SSE hub. Type is the SSE event name, Data is pre-serialized JSON written directly to the stream.

type LocalAgentView added in v0.3.0

type LocalAgentView struct {
	Name       string `json:"name"`
	PID        int    `json:"pid"`
	Registered bool   `json:"registered"` // has connected back to the hub pool
	Busy       bool   `json:"busy,omitempty"`
}

LocalAgentView is the API-facing view of a hub-hosted agent, cross-referenced with the live pool for connection state.

type LocalAgents added in v0.3.0

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

LocalAgents launches and tracks `aiscan agent` subprocesses on the hub host so they register in the pool and can be listed/stopped from the UI. Each child dials the hub's own loopback web + IOA endpoints, so it shows up in the pool like any node. The hub holds the only handle to these processes, so StopAll kills them on shutdown rather than leaving orphans.

func NewLocalAgents added in v0.3.0

func NewLocalAgents(hubURL, ioaToken string, pool *AgentPool) *LocalAgents

NewLocalAgents builds a launcher. hubURL is the loopback base the children dial (e.g. http://127.0.0.1:8080); ioaToken is embedded into the child's IOA URL. Children are launched from the current aiscan executable.

func (*LocalAgents) Launch added in v0.3.0

func (l *LocalAgents) Launch(ctx context.Context) (*LocalAgentView, error)

Launch spawns an `aiscan agent` on the hub host wired to the hub's loopback web + IOA endpoints, and tracks it. The LLM provider/model/key arrive via the hub's config push on registration, so nothing about the model is passed here.

func (*LocalAgents) List added in v0.3.0

func (l *LocalAgents) List() []LocalAgentView

List returns the tracked local agents (launch order), cross-referenced with the pool for connection state.

func (*LocalAgents) Stop added in v0.3.0

func (l *LocalAgents) Stop(name string) error

Stop kills a tracked local agent by name and drops it from the roster.

func (*LocalAgents) StopAll added in v0.3.0

func (l *LocalAgents) StopAll()

StopAll kills every tracked local agent (hub shutdown), so none are left orphaned once the hub — which holds the only handle to them — exits.

type RecordStore added in v0.2.8

type RecordStore interface {
	InsertRecord(ctx context.Context, rec *output.Record) error
	InsertRecords(ctx context.Context, recs []*output.Record) error
}

RecordStore is the subset of Store needed for record persistence.

type SQLiteStore

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

func NewSQLiteStore

func NewSQLiteStore(dbPath string) (*SQLiteStore, error)

func (*SQLiteStore) AddMessage added in v0.2.8

func (s *SQLiteStore) AddMessage(ctx context.Context, msg *ChatMessage) error

func (*SQLiteStore) ClearMessages added in v0.3.0

func (s *SQLiteStore) ClearMessages(ctx context.Context, sessionID string) error

ClearMessages deletes every message in a session without removing the session itself — the store half of web /clear ("clear conversation"). Messages are leaf rows (nothing references them), so a single delete suffices.

func (*SQLiteStore) Close

func (s *SQLiteStore) Close() error

func (*SQLiteStore) Create

func (s *SQLiteStore) Create(ctx context.Context, job *ScanJob) error

func (*SQLiteStore) CreateSession added in v0.2.8

func (s *SQLiteStore) CreateSession(ctx context.Context, session *ChatSession) error

func (*SQLiteStore) Delete

func (s *SQLiteStore) Delete(ctx context.Context, id string) error

func (*SQLiteStore) DeleteSCONodesByScan added in v0.3.0

func (s *SQLiteStore) DeleteSCONodesByScan(ctx context.Context, scanID string) error

func (*SQLiteStore) DeleteSession added in v0.2.8

func (s *SQLiteStore) DeleteSession(ctx context.Context, id string) error

func (*SQLiteStore) Get

func (s *SQLiteStore) Get(ctx context.Context, id string) (*ScanJob, error)

func (*SQLiteStore) GetSCONode added in v0.3.0

func (s *SQLiteStore) GetSCONode(ctx context.Context, cstxID string) (json.RawMessage, error)

func (*SQLiteStore) GetSession added in v0.2.8

func (s *SQLiteStore) GetSession(ctx context.Context, id string) (*ChatSession, error)

func (*SQLiteStore) InsertRecord added in v0.2.8

func (s *SQLiteStore) InsertRecord(ctx context.Context, rec *output.Record) error

func (*SQLiteStore) InsertRecords added in v0.2.8

func (s *SQLiteStore) InsertRecords(ctx context.Context, recs []*output.Record) error

func (*SQLiteStore) LinkScanToSession added in v0.2.8

func (s *SQLiteStore) LinkScanToSession(ctx context.Context, sessionID, scanID string) error

func (*SQLiteStore) List

func (s *SQLiteStore) List(ctx context.Context, limit int) ([]*ScanJob, error)

func (*SQLiteStore) ListMessages added in v0.2.8

func (s *SQLiteStore) ListMessages(ctx context.Context, sessionID string, limit int) ([]*ChatMessage, error)

func (*SQLiteStore) ListSCONodes added in v0.3.0

func (s *SQLiteStore) ListSCONodes(ctx context.Context, nodeType string, limit int) ([]json.RawMessage, error)

func (*SQLiteStore) ListSCONodesByScanID added in v0.3.0

func (s *SQLiteStore) ListSCONodesByScanID(ctx context.Context, scanID, nodeType string, limit int) ([]json.RawMessage, error)

func (*SQLiteStore) ListSessions added in v0.2.8

func (s *SQLiteStore) ListSessions(ctx context.Context, limit int) ([]*ChatSession, error)

func (*SQLiteStore) SCONodeStats added in v0.3.0

func (s *SQLiteStore) SCONodeStats(ctx context.Context) (map[string]int, error)

func (*SQLiteStore) SessionScanIDs added in v0.2.8

func (s *SQLiteStore) SessionScanIDs(ctx context.Context, sessionID string) ([]string, error)

func (*SQLiteStore) Update

func (s *SQLiteStore) Update(ctx context.Context, job *ScanJob) error

func (*SQLiteStore) UpdateSession added in v0.2.8

func (s *SQLiteStore) UpdateSession(ctx context.Context, session *ChatSession) error

func (*SQLiteStore) UpsertSCONodes added in v0.3.0

func (s *SQLiteStore) UpsertSCONodes(ctx context.Context, scanID string, nodes []json.RawMessage) error

type ScanJob

type ScanJob struct {
	ID        string         `json:"id"`
	Target    string         `json:"target"`
	Mode      string         `json:"mode"`
	Verify    bool           `json:"verify,omitempty"`
	Sniper    bool           `json:"sniper,omitempty"`
	Deep      bool           `json:"deep,omitempty"`
	Status    ScanStatus     `json:"status"`
	Progress  string         `json:"progress,omitempty"`
	Report    string         `json:"report,omitempty"`
	Result    *output.Result `json:"result,omitempty"`
	Error     string         `json:"error,omitempty"`
	CreatedAt time.Time      `json:"created_at"`
	UpdatedAt time.Time      `json:"updated_at"`
}

type ScanRequest

type ScanRequest struct {
	Target string `json:"target"`
	Mode   string `json:"mode"`
	Verify bool   `json:"verify,omitempty"`
	Sniper bool   `json:"sniper,omitempty"`
	Deep   bool   `json:"deep,omitempty"`
}

type ScanStatus

type ScanStatus string
const (
	StatusQueued    ScanStatus = "queued"
	StatusRunning   ScanStatus = "running"
	StatusCompleted ScanStatus = "completed"
	StatusFailed    ScanStatus = "failed"
	StatusCanceled  ScanStatus = "canceled"
)

type SendMessageRequest added in v0.2.8

type SendMessageRequest struct {
	Content string `json:"content"`
	// Goal-mode run controls (optional). The frontend sends these when the user
	// enables the Goal panel; a plain chat send leaves them zero.
	webproto.ChatPayload
}

type Service

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

func NewService

func NewService(cfg ServiceConfig) *Service

func (*Service) BroadcastChatEvent added in v0.2.8

func (s *Service) BroadcastChatEvent(sessionID string, event ChatEvent)

func (*Service) CancelScan

func (s *Service) CancelScan(id string) error

func (*Service) CancelSession added in v0.2.8

func (s *Service) CancelSession(ctx context.Context, sessionID string) error

func (*Service) Close

func (s *Service) Close()

func (*Service) CreateSession added in v0.2.8

func (s *Service) CreateSession(ctx context.Context, agentID, title string) (*ChatSession, error)

func (*Service) DeleteSession added in v0.2.8

func (s *Service) DeleteSession(ctx context.Context, id string) error

func (*Service) GetConfigStatus added in v0.2.8

func (s *Service) GetConfigStatus(ctx context.Context) (ConfigStatus, error)

func (*Service) GetDistributeConfig added in v0.2.8

func (s *Service) GetDistributeConfig(ctx context.Context) (webproto.DistributeConfig, error)

func (*Service) GetMessages added in v0.2.8

func (s *Service) GetMessages(ctx context.Context, sessionID string) ([]*ChatMessage, error)

func (*Service) GetReport

func (s *Service) GetReport(ctx context.Context, id, lang string) (string, error)

GetReport re-renders the report in the requested language from the stored structured result, so a zh user gets a zh report even though the scan ran once. It falls back to the report frozen at scan time when the structured result is no longer around.

func (*Service) GetScan

func (s *Service) GetScan(ctx context.Context, id string) (*ScanJob, error)

func (*Service) GetSession added in v0.2.8

func (s *Service) GetSession(ctx context.Context, id string) (*ChatSession, error)

func (*Service) HandleFileUpload added in v0.2.8

func (s *Service) HandleFileUpload(ctx context.Context, sessionID, filename string, data []byte) (*webproto.FileUploadResult, error)

func (*Service) HandleUserMessage added in v0.2.8

func (s *Service) HandleUserMessage(ctx context.Context, sessionID, content string, opts webproto.ChatPayload) (*ChatMessage, error)

func (*Service) Hub

func (s *Service) Hub() *Hub

func (*Service) ListLLMModels added in v0.3.0

func (s *Service) ListLLMModels(ctx context.Context, req probe.LLMProbeRequest) (probe.LLMModelsResult, error)

ListLLMModels enumerates the models the supplied LLM endpoint advertises, falling back to the stored API key when the request leaves it blank, then delegates to pkg/probe.

func (*Service) ListScans

func (s *Service) ListScans(ctx context.Context) ([]*ScanJob, error)

func (*Service) ListSessions added in v0.2.8

func (s *Service) ListSessions(ctx context.Context) ([]*ChatSession, error)

func (*Service) SaveConfig added in v0.2.8

func (s *Service) SaveConfig(ctx context.Context, cfg webproto.DistributeConfig) (ConfigStatus, error)

func (*Service) SessionMenu added in v0.3.0

func (s *Service) SessionMenu(sessionID string) []webproto.CommandSpec

SessionMenu is the web "/" command catalog for a session: the hub-scope commands plus the bound agent's reported agent-scope commands (its skills included). It falls back to the static agent-scope menu when no agent is bound, so the menu is populated even before an agent connects. This is the single source both the "/" menu (GET .../commands) and /help render from.

func (*Service) SetAgentPool

func (s *Service) SetAgentPool(pool *AgentPool)

func (*Service) Status

func (s *Service) Status() ServiceStatus

func (*Service) SubmitScan

func (s *Service) SubmitScan(ctx context.Context, target, mode string, verify, sniper, deep bool) (*ScanJob, error)

func (*Service) TaskSession added in v0.2.8

func (s *Service) TaskSession(taskID string) (string, bool)

func (*Service) TestConn added in v0.3.0

func (s *Service) TestConn(ctx context.Context, section string, in webproto.DistributeConfig) ([]probe.ConnCheck, error)

TestConn probes one settings section's external dependencies, resolving blank secrets against the stored config, then delegates to pkg/probe. Probe failures live inside the response; a returned error only signals an untestable section.

func (*Service) TestLLM added in v0.3.0

TestLLM probes the supplied LLM settings, falling back to the stored API key when the request leaves it blank, then delegates to pkg/probe.

type ServiceConfig

type ServiceConfig struct {
	Store         *SQLiteStore
	App           *runner.App
	ConfigStore   ConfigStore
	AppFactory    func(ctx context.Context) (*runner.App, error)
	AgentPool     *AgentPool
	MaxConcurrent int
	ScanTimeout   time.Duration
}

type ServiceStatus

type ServiceStatus struct {
	Version             string `json:"version"`
	LLMAvailable        bool   `json:"llm_available"`
	LLMProvider         string `json:"llm_provider,omitempty"`
	LLMModel            string `json:"llm_model,omitempty"`
	LLMAPIKeyConfigured bool   `json:"llm_api_key_configured,omitempty"`
	ConfigPath          string `json:"config_path,omitempty"`
	ConfigLoaded        bool   `json:"config_loaded"`
	Agents              int    `json:"agents"`
	IOAURL              string `json:"ioa_url,omitempty"`
}

type SessionLookup added in v0.2.8

type SessionLookup interface {
	TaskSession(taskID string) (sessionID string, ok bool)
	BroadcastChatEvent(sessionID string, event ChatEvent)
}

SessionLookup resolves a task ID to its owning chat session.

type WSMessage

type WSMessage = webproto.Message

WSMessage is the single message type for all agent↔web communication.

Jump to

Keyboard shortcuts

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