web

package
v0.0.0-nightly.20260628 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2026 License: AGPL-3.0 Imports: 20 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"
	ChatEventError        = "error"
)

Variables

This section is empty.

Functions

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"`
	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) 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

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

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

DispatchChatSession sends chat input to an agent and scopes the remote agent-side conversation state to the web chat session.

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

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) SetSessionLookup

func (p *AgentPool) SetSessionLookup(sl SessionLookup)

type BroadcastCallback

type BroadcastCallback func(id string, event HubEvent)

type ChatEvent

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"`
	Transient  bool           `json:"-"`
}

type ChatMessage

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

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"`
	ScanIDs   []string  `json:"scan_ids,omitempty"`
	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

type ConfigStatus

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"`
		VerifyTimeout int    `json:"verify_timeout"`
	} `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

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

ConfigStatusFromDistribute builds a masked ConfigStatus from raw config.

type ConfigStore

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

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, ioaHandler http.Handler, static http.Handler) *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) OnBroadcast

func (h *Hub) OnBroadcast(cb BroadcastCallback)

func (*Hub) Subscribe

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

type HubEvent

type HubEvent struct {
	Type string
	Data json.RawMessage
}

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 SQLiteStore

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

func NewSQLiteStore

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

func (*SQLiteStore) AddMessage

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

func (*SQLiteStore) Close

func (s *SQLiteStore) Close() error

func (*SQLiteStore) Create

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

func (*SQLiteStore) CreateSession

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) DeleteSession

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) GetSession

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

func (*SQLiteStore) LinkScanToSession

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

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

func (*SQLiteStore) ListSessions

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

func (*SQLiteStore) SessionScanIDs

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

func (s *SQLiteStore) UpdateSession(ctx context.Context, session *ChatSession) 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"`
	AI        bool           `json:"ai,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"`
	AI     bool   `json:"ai,omitempty"`
	Deep   bool   `json:"deep,omitempty"`
}

func (ScanRequest) AnalysisOptions

func (r ScanRequest) AnalysisOptions() (verify, sniper, deep bool)

type ScanStatus

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

type SendMessageRequest

type SendMessageRequest struct {
	Content string `json:"content"`
}

type Service

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

func NewService

func NewService(cfg ServiceConfig) *Service

func (*Service) BroadcastChatEvent

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

func (*Service) CancelScan

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

func (*Service) CancelSession

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

func (*Service) Close

func (s *Service) Close()

func (*Service) CreateSession

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

func (*Service) DeleteSession

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

func (*Service) GetConfigStatus

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

func (*Service) GetDistributeConfig

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

func (*Service) GetMessages

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

func (*Service) GetReport

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

func (*Service) GetScan

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

func (*Service) GetSession

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

func (*Service) HandleFileUpload

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

func (*Service) HandleUserMessage

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

func (*Service) Hub

func (s *Service) Hub() *Hub

func (*Service) ListScans

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

func (*Service) ListSessions

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

func (*Service) SaveConfig

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

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

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

type ServiceConfig

type ServiceConfig struct {
	Store         Store
	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 {
	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"`
}

type SessionLookup

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 Store

type Store interface {
	// Scan CRUD
	Create(ctx context.Context, job *ScanJob) error
	Get(ctx context.Context, id string) (*ScanJob, error)
	List(ctx context.Context, limit int) ([]*ScanJob, error)
	Update(ctx context.Context, job *ScanJob) error
	Delete(ctx context.Context, id string) error

	// Chat sessions
	CreateSession(ctx context.Context, session *ChatSession) error
	GetSession(ctx context.Context, id string) (*ChatSession, error)
	ListSessions(ctx context.Context, limit int) ([]*ChatSession, error)
	UpdateSession(ctx context.Context, session *ChatSession) error
	DeleteSession(ctx context.Context, id string) error

	// Chat messages
	AddMessage(ctx context.Context, msg *ChatMessage) error
	ListMessages(ctx context.Context, sessionID string, limit int) ([]*ChatMessage, error)

	// Session-scan association
	LinkScanToSession(ctx context.Context, sessionID, scanID string) error
	SessionScanIDs(ctx context.Context, sessionID string) ([]string, error)
}

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