Documentation
¶
Overview ¶
Package protocol defines the WebSocket message protocol between Runner and Flashduty.
Index ¶
- type AuthErrorMeta
- type BashArgs
- type BashResult
- type DeleteKnowledgeFilesArgs
- type DeleteKnowledgeFilesResult
- type EnvironmentInfo
- type GlobArgs
- type GlobResult
- type GrepArgs
- type GrepMatch
- type GrepResult
- type HeartbeatMetrics
- type HeartbeatPayload
- type KnowledgeFile
- type KnowledgeFileStatus
- type KnowledgeManifestEntry
- type ListArgs
- type ListEntry
- type ListResult
- type MCPCallArgs
- type MCPCallPayload
- type MCPCallResult
- type MCPListToolsArgs
- type MCPListToolsResult
- type MCPResultPayload
- type MCPServerConfig
- type MCPToolInfo
- type Message
- type MessageType
- type PackFolderArgs
- type PackFolderResult
- type ReadArgs
- type ReadResult
- type ReconcileKnowledgeManifestArgs
- type ReconcileKnowledgeManifestResult
- type StageKnowledgeFilesArgs
- type StageKnowledgeFilesResult
- type SyncSkillArgs
- type SyncSkillResult
- type TaskCancelPayload
- type TaskOperation
- type TaskOutputPayload
- type TaskRequestPayload
- type TaskResultPayload
- type WebFetchArgs
- type WebFetchResult
- type WelcomePayload
- type WriteArgs
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthErrorMeta ¶ added in v0.0.12
type AuthErrorMeta struct {
StatusCode int `json:"status_code,omitempty"`
WWWAuthenticate string `json:"www_authenticate,omitempty"`
ResourceMetadataURL string `json:"resource_metadata_url,omitempty"`
}
AuthErrorMeta carries the 401 challenge details so fc-safari can initiate the per-user OAuth flow without re-parsing opaque error strings.
type BashArgs ¶
type BashArgs struct {
Command string `json:"command"`
Workdir string `json:"workdir,omitempty"`
Timeout int `json:"timeout,omitempty"` // seconds
Env map[string]string `json:"env,omitempty"`
}
BashArgs are the arguments for bash operation.
Env carries per-call environment variables the caller wants merged on top of the runner process's own environment. Values may be secrets (auth tokens, per-tenant API keys), so the runner MUST NOT log them — only the keys are safe to surface. The bash command itself should reference these as `$VAR_NAME` so the secret expands inside the shell and never appears in transport-layer logs that mirror Command.
type BashResult ¶
type BashResult struct {
Stdout string `json:"stdout"`
Stderr string `json:"stderr"`
ExitCode int `json:"exit_code"`
// Per-stream truncation metadata. A stream is "truncated" when either
// processLargeOutput trimmed it OR the underlying LimitedWriter hit its
// hard cap mid-execution (the captured buffer carries an inline marker).
TruncatedStdout bool `json:"truncated_stdout,omitempty"`
TruncatedStderr bool `json:"truncated_stderr,omitempty"`
StdoutFilePath string `json:"stdout_file_path,omitempty"`
StderrFilePath string `json:"stderr_file_path,omitempty"`
StdoutTotalSize int64 `json:"stdout_total_size,omitempty"`
StderrTotalSize int64 `json:"stderr_total_size,omitempty"`
// Legacy stdout-only mirrors. Kept so older safari clients that only
// parse these still see truncation. New code should read the stream-
// specific fields instead.
Truncated bool `json:"truncated,omitempty"`
FilePath string `json:"file_path,omitempty"`
TotalSize int64 `json:"total_size,omitempty"`
}
BashResult is the result of a bash operation.
Stdout and stderr are tracked independently — either stream may be truncated and spilled to a separate file. The legacy fields (`Truncated`, `FilePath`, `TotalSize`) mirror the stdout-side fields for backward compatibility with older safari builds; new callers should prefer the stream-specific fields.
type DeleteKnowledgeFilesArgs ¶ added in v0.0.6
type DeleteKnowledgeFilesArgs struct {
RelPaths []string `json:"rel_paths"`
}
DeleteKnowledgeFilesArgs are the arguments for delete_knowledge_files operation.
type DeleteKnowledgeFilesResult ¶ added in v0.0.6
type DeleteKnowledgeFilesResult struct {
Success bool `json:"success"`
}
DeleteKnowledgeFilesResult is the result of a delete_knowledge_files operation.
type EnvironmentInfo ¶
type EnvironmentInfo struct {
OS string `json:"os"` // e.g., "darwin", "linux", "windows"
OSVersion string `json:"os_version"` // e.g., "24.6.0" for macOS
Arch string `json:"arch"` // e.g., "amd64", "arm64"
Hostname string `json:"hostname"` // Machine hostname
Shell string `json:"shell"` // Default shell, e.g., "/bin/zsh"
HomeDir string `json:"home_dir"` // User home directory
WorkspaceRoot string `json:"workspace_root"` // Configured workspace root
Username string `json:"username"` // Current user
NumCPU int `json:"num_cpu"` // Number of CPUs
TotalMemoryMB int64 `json:"total_memory_mb,omitempty"` // Total memory in MB
Timezone string `json:"timezone"` // Timezone name, e.g., "Asia/Shanghai"
UTCOffset string `json:"utc_offset"` // UTC offset, e.g., "+08:00"
}
EnvironmentInfo contains detailed environment information for LLM context. This is similar to Cursor's system reminder format.
type GlobArgs ¶
type GlobArgs struct {
Pattern string `json:"pattern"`
}
GlobArgs are the arguments for glob operation.
type GlobResult ¶
type GlobResult struct {
Matches []string `json:"matches"`
}
GlobResult is the result of a glob operation.
type GrepArgs ¶
type GrepArgs struct {
Pattern string `json:"pattern"`
Include []string `json:"include,omitempty"`
// OutputMode controls the shape of the result: "content" (default — file:line:text rows),
// "files_with_matches" (one path per match), or "count" (one path:count per file).
OutputMode string `json:"output_mode,omitempty"`
// ContextBefore (-B) and ContextAfter (-A) request N lines of context around each match.
// Honored by ripgrep only when OutputMode is "content".
ContextBefore int `json:"context_before,omitempty"`
ContextAfter int `json:"context_after,omitempty"`
// HeadLimit caps the number of result rows returned (post-format). 0 = unlimited.
HeadLimit int `json:"head_limit,omitempty"`
// FileType maps to ripgrep's --type (e.g., "go", "py", "js"). Ignored by the Go fallback.
FileType string `json:"file_type,omitempty"`
// CaseSensitive overrides ripgrep's default --smart-case.
// nil = smart-case; true = case-sensitive; false = case-insensitive.
CaseSensitive *bool `json:"case_sensitive,omitempty"`
}
GrepArgs are the arguments for grep operation.
type GrepMatch ¶
type GrepMatch struct {
Path string `json:"path"`
LineNumber int `json:"line_number"`
Content string `json:"content"`
}
GrepMatch is a single match in a grep result.
type GrepResult ¶
type GrepResult struct {
Matches []GrepMatch `json:"matches"`
Content string `json:"content"` // Formatted content (may be truncated)
Truncated bool `json:"truncated,omitempty"` // Whether content was truncated
FilePath string `json:"file_path,omitempty"` // Path to full content if truncated
TotalSize int64 `json:"total_size,omitempty"` // Original content size
// RegexCompileError surfaces a non-fatal fallback path: the requested pattern failed
// to compile as a Go regexp, so the Go fallback walked files matching it as a literal.
// Empty when ripgrep handled the request or compilation succeeded.
RegexCompileError string `json:"regex_compile_error,omitempty"`
}
GrepResult is the result of a grep operation.
type HeartbeatMetrics ¶
type HeartbeatMetrics struct {
CPUPercent float64 `json:"cpu_percent,omitempty"`
MemoryPercent float64 `json:"memory_percent,omitempty"`
DiskPercent float64 `json:"disk_percent,omitempty"`
}
HeartbeatMetrics contains system metrics.
type HeartbeatPayload ¶
type HeartbeatPayload struct {
EnvironmentID string `json:"environment_id"`
Name string `json:"name"`
Labels []string `json:"labels"`
Version string `json:"version"`
Environment *EnvironmentInfo `json:"environment,omitempty"`
Metrics *HeartbeatMetrics `json:"metrics,omitempty"`
}
HeartbeatPayload is the payload for heartbeat messages.
type KnowledgeFile ¶ added in v0.0.6
type KnowledgeFile struct {
RelPath string `json:"rel_path"`
Checksum string `json:"checksum"`
ContentB64 string `json:"content_b64"`
}
KnowledgeFile is a single file entry in a stage_knowledge_files request.
type KnowledgeFileStatus ¶ added in v0.0.6
type KnowledgeFileStatus struct {
RelPath string `json:"rel_path"`
Success bool `json:"success"`
Error string `json:"error,omitempty"`
}
KnowledgeFileStatus is the per-file result entry in the stage ack.
type KnowledgeManifestEntry ¶ added in v0.0.7
type KnowledgeManifestEntry struct {
RelPath string `json:"rel_path"`
Checksum string `json:"checksum"`
}
KnowledgeManifestEntry is one (rel_path, checksum) pair in a reconcile manifest. rel_path uses the same `knowledge/<scope>/<leaf>` shape as StageKnowledgeFiles so the runner-side validator is shared.
type ListArgs ¶
type ListArgs struct {
Path string `json:"path"`
Recursive bool `json:"recursive,omitempty"`
Ignore []string `json:"ignore,omitempty"`
}
ListArgs are the arguments for list operation.
type ListEntry ¶
type ListEntry struct {
Path string `json:"path"`
IsDir bool `json:"is_dir"`
Size int64 `json:"size"`
}
ListEntry is a single entry in a list result.
type ListResult ¶
type ListResult struct {
Entries []ListEntry `json:"entries"`
}
ListResult is the result of a list operation.
type MCPCallArgs ¶
type MCPCallArgs struct {
Server MCPServerConfig `json:"server"`
ToolName string `json:"tool_name"`
Args json.RawMessage `json:"args"`
Timeout int `json:"timeout,omitempty"` // seconds
}
MCPCallArgs are the arguments for mcp_call operation.
type MCPCallPayload ¶
type MCPCallPayload struct {
CallID string `json:"call_id"`
Server MCPServerConfig `json:"server"`
ToolName string `json:"tool_name"`
Arguments json.RawMessage `json:"arguments"`
}
MCPCallPayload is the payload for MCP tool calls. Server configuration is passed from cloud (stored in database).
type MCPCallResult ¶
type MCPCallResult struct {
Content string `json:"content"`
IsError bool `json:"is_error,omitempty"` // Whether the tool returned an error
Truncated bool `json:"truncated,omitempty"` // Whether content was truncated
FilePath string `json:"file_path,omitempty"` // Path to full content if truncated
TotalSize int64 `json:"total_size,omitempty"` // Original content size
}
MCPCallResult is the result of an mcp_call operation.
type MCPListToolsArgs ¶
type MCPListToolsArgs struct {
Server MCPServerConfig `json:"server"`
}
MCPListToolsArgs are the arguments for mcp_list_tools operation.
type MCPListToolsResult ¶
type MCPListToolsResult struct {
Tools []MCPToolInfo `json:"tools"`
}
MCPListToolsResult is the result of an mcp_list_tools operation.
type MCPResultPayload ¶
type MCPResultPayload struct {
CallID string `json:"call_id"`
Success bool `json:"success"`
Result json.RawMessage `json:"result,omitempty"`
Error string `json:"error,omitempty"`
// P1: structured auth-error metadata (additive; old senders omit).
ErrorType string `json:"error_type,omitempty"` // "auth_error" | ""
AuthMetadata *AuthErrorMeta `json:"auth_metadata,omitempty"` // non-nil iff ErrorType=="auth_error"
}
MCPResultPayload is the payload for MCP call results.
type MCPServerConfig ¶
type MCPServerConfig struct {
Name string `json:"name"`
Transport string `json:"transport"` // stdio, sse
Command string `json:"command,omitempty"`
Args []string `json:"args,omitempty"`
Env map[string]string `json:"env,omitempty"`
URL string `json:"url,omitempty"`
Headers map[string]string `json:"headers,omitempty"`
DynamicHeaders map[string]string `json:"dynamic_headers,omitempty"`
}
MCPServerConfig is the MCP server configuration passed from cloud.
type MCPToolInfo ¶
type MCPToolInfo struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema any `json:"input_schema,omitempty"`
}
MCPToolInfo represents metadata for an MCP tool.
type Message ¶
type Message struct {
ID string `json:"id"`
Type MessageType `json:"type"`
Payload json.RawMessage `json:"payload"`
Timestamp int64 `json:"timestamp"`
}
Message is the base WebSocket message structure.
func NewMessage ¶
func NewMessage(msgType MessageType, payload any) (*Message, error)
NewMessage creates a new message with the given type and payload.
type MessageType ¶
type MessageType string
MessageType defines the type of WebSocket message.
const ( // Flashduty -> Runner (initial) MessageTypeWelcome MessageType = "welcome" // Runner -> Flashduty MessageTypeHeartbeat MessageType = "heartbeat" MessageTypeTaskOutput MessageType = "task.output" MessageTypeTaskResult MessageType = "task.result" MessageTypeMCPResult MessageType = "mcp.result" // Flashduty -> Runner MessageTypeTaskRequest MessageType = "task.request" MessageTypeTaskCancel MessageType = "task.cancel" MessageTypeMCPCall MessageType = "mcp.call" // Shutdown is Safari telling the runner to drop everything and exit — // used when CloudManager tears down a cloud sandbox so the runner's // WebSocket closes immediately instead of waiting for the 5s force // unregister timeout. MessageTypeShutdown MessageType = "shutdown" )
type PackFolderArgs ¶ added in v0.0.8
type PackFolderArgs struct {
Path string `json:"path"` // absolute path inside workspace
SkillRoot bool `json:"skill_root"` // when true, also exclude evals/ at the root
MaxBytes int64 `json:"max_bytes"` // 0 = no cap; >0 = error if zip exceeds
}
PackFolderArgs walks a directory inside the workspace and returns a zip archive of its contents. Used by Safari's sync_files(type="skill") path so the agent never has to package skills by hand.
type PackFolderResult ¶ added in v0.0.8
type PackFolderResult struct {
ZipB64 string `json:"zip_b64"` // base64-encoded zip bytes
SizeBytes int64 `json:"size_bytes"`
FileCount int `json:"file_count"`
}
PackFolderResult carries the produced archive back to Safari.
type ReadArgs ¶
type ReadArgs struct {
Path string `json:"path"`
Offset int64 `json:"offset,omitempty"`
Limit int64 `json:"limit,omitempty"`
}
ReadArgs are the arguments for read operation.
type ReadResult ¶
type ReadResult struct {
Content string `json:"content"` // base64 encoded
TotalSize int64 `json:"total_size"`
}
ReadResult is the result of a read operation.
type ReconcileKnowledgeManifestArgs ¶ added in v0.0.7
type ReconcileKnowledgeManifestArgs struct {
Files []KnowledgeManifestEntry `json:"files"`
}
ReconcileKnowledgeManifestArgs supplies the canonical view of which knowledge files should exist on disk and at what checksum. The runner deletes anything not in the manifest (orphan prune) and anything whose on-disk checksum disagrees (stale prune); the result's NeedsStage field tells the caller which manifest entries the runner does NOT have cached so the caller can bulk-stage them in one follow-up batch (skills-style eager materialization).
type ReconcileKnowledgeManifestResult ¶ added in v0.0.7
type ReconcileKnowledgeManifestResult struct {
Pruned []string `json:"pruned,omitempty"`
KeptCount int `json:"kept_count"`
StaleCount int `json:"stale_count"`
NeedsStage []string `json:"needs_stage,omitempty"`
}
ReconcileKnowledgeManifestResult reports the diff outcome plus the list of entries the caller still needs to push.
Pruned lists every rel_path the runner removed (orphans + stale together). StaleCount is the subset of Pruned whose rel_path was in the manifest but had a divergent checksum — useful for spotting upstream edits. KeptCount counts files left untouched because their checksum already matched. NeedsStage enumerates every manifest entry the runner does NOT have on disk after the prune step. The caller (Safari) materializes these by fetching from S3 and calling StageKnowledgeFiles. Empty when the runner is already in sync with the manifest.
type StageKnowledgeFilesArgs ¶ added in v0.0.6
type StageKnowledgeFilesArgs struct {
Files []KnowledgeFile `json:"files"`
}
StageKnowledgeFilesArgs are the arguments for stage_knowledge_files operation.
type StageKnowledgeFilesResult ¶ added in v0.0.6
type StageKnowledgeFilesResult struct {
Files []KnowledgeFileStatus `json:"files"`
}
StageKnowledgeFilesResult is the result of a stage_knowledge_files operation.
type SyncSkillArgs ¶
type SyncSkillArgs struct {
SkillName string `json:"skill_name"`
SkillDir string `json:"skill_dir"`
ZipData string `json:"zip_data"` // base64 encoded zip
Checksum string `json:"checksum"`
}
SyncSkillArgs are the arguments for sync_skill operation.
type SyncSkillResult ¶
type SyncSkillResult struct {
Success bool `json:"success"`
Path string `json:"path"` // Local path where skill is materialized
Cached bool `json:"cached,omitempty"` // True iff cache hit
}
SyncSkillResult is the result of a sync_skill operation.
Probe semantics: when SyncSkillArgs.ZipData is empty, the runner checks its local cache and returns either {Success:true, Cached:true, Path} on hit or {Success:true, Cached:false, Path:""} on miss (cloud must retry with zip). When ZipData is non-empty, the runner installs unconditionally and returns {Success:true, Cached:false, Path}.
type TaskCancelPayload ¶
type TaskCancelPayload struct {
TaskID string `json:"task_id"`
}
TaskCancelPayload is the payload for task cancellation.
type TaskOperation ¶
type TaskOperation string
TaskOperation defines the type of workspace operation.
const ( TaskOpRead TaskOperation = "read" TaskOpWrite TaskOperation = "write" TaskOpList TaskOperation = "list" TaskOpGlob TaskOperation = "glob" TaskOpGrep TaskOperation = "grep" TaskOpBash TaskOperation = "bash" TaskOpWebFetch TaskOperation = "webfetch" TaskOpMCPCall TaskOperation = "mcp_call" TaskOpMCPListTools TaskOperation = "mcp_list_tools" TaskOpSyncSkill TaskOperation = "sync_skill" TaskOpPackFolder TaskOperation = "pack_folder" TaskOpStageKnowledgeFiles TaskOperation = "stage_knowledge_files" TaskOpDeleteKnowledgeFiles TaskOperation = "delete_knowledge_files" TaskOpReconcileKnowledgeManifest TaskOperation = "reconcile_knowledge_manifest" )
type TaskOutputPayload ¶
type TaskOutputPayload struct {
TaskID string `json:"task_id"`
Stream string `json:"stream"` // stdout, stderr
Data string `json:"data"`
}
TaskOutputPayload is the payload for streaming task output.
type TaskRequestPayload ¶
type TaskRequestPayload struct {
TaskID string `json:"task_id"`
TraceID string `json:"trace_id,omitempty"`
SourceInstanceID string `json:"source_instance_id,omitempty"` // Safari instance ID
Operation TaskOperation `json:"operation"`
Args json.RawMessage `json:"args"`
}
TaskRequestPayload is the payload for task request messages.
type TaskResultPayload ¶
type TaskResultPayload struct {
TaskID string `json:"task_id"`
SourceInstanceID string `json:"source_instance_id,omitempty"` // Safari instance ID
Success bool `json:"success"`
Result json.RawMessage `json:"result,omitempty"`
Error string `json:"error,omitempty"`
ExitCode int `json:"exit_code,omitempty"`
}
TaskResultPayload is the payload for task completion.
type WebFetchArgs ¶
type WebFetchArgs struct {
URL string `json:"url"`
Format string `json:"format,omitempty"` // markdown, text, html (default: markdown)
Timeout int `json:"timeout,omitempty"` // seconds (default: 30, max: 120)
}
WebFetchArgs are the arguments for webfetch operation.
type WebFetchResult ¶
type WebFetchResult struct {
Content string `json:"content"`
URL string `json:"url"` // Final URL after redirects
Truncated bool `json:"truncated,omitempty"` // Whether content was truncated
FilePath string `json:"file_path,omitempty"` // Path to full content if truncated
TotalSize int64 `json:"total_size,omitempty"` // Original content size
}
WebFetchResult is the result of a webfetch operation.
type WelcomePayload ¶
type WelcomePayload struct {
EnvironmentID string `json:"environment_id"`
Name string `json:"name"`
Labels []string `json:"labels"`
}
WelcomePayload is the payload for the welcome message sent by server after connection. Contains environment info (name, labels) managed via Web UI.