types.go
1 package daemon 2 3 import "encoding/json" 4 5 // Server -> Daemon message types 6 const ( 7 MsgTypeConnected = "connected" 8 MsgTypeMessage = "message" 9 MsgTypeClaimAck = "claim_ack" 10 MsgTypeSystem = "system" 11 ) 12 13 // Daemon -> Server message types 14 const ( 15 MsgTypeClaim = "claim" 16 MsgTypeReply = "reply" 17 MsgTypeProgress = "progress" 18 MsgTypeDisconnect = "disconnect" 19 MsgTypeEvent = "event" 20 MsgTypeProactive = "proactive" 21 ) 22 23 // Approval protocol (bidirectional relay via Cloud) 24 const ( 25 MsgTypeApprovalRequest = "approval_request" 26 MsgTypeApprovalResponse = "approval_response" 27 MsgTypeApprovalResolved = "approval_resolved" 28 ) 29 30 // ApprovalRequest is sent by daemon when a tool needs user approval. 31 type ApprovalRequest struct { 32 Channel string `json:"channel"` 33 ThreadID string `json:"thread_id"` 34 RequestID string `json:"request_id"` 35 Tool string `json:"tool"` 36 Args string `json:"args"` 37 Agent string `json:"agent"` 38 } 39 40 // ApprovalResponse is received from the client (via Cloud relay). 41 type ApprovalResponse struct { 42 RequestID string `json:"request_id"` 43 Decision ApprovalDecision `json:"decision"` // "allow", "deny", "always_allow" 44 ResolvedBy string `json:"resolved_by,omitempty"` // populated by Cloud 45 } 46 47 // ApprovalResolvedPayload is sent daemon→Cloud when Ptfrog resolves first. 48 type ApprovalResolvedPayload struct { 49 RequestID string `json:"request_id"` 50 Decision ApprovalDecision `json:"decision"` 51 ResolvedBy string `json:"resolved_by"` // "ptfrog", "slack", "line" 52 } 53 54 // Channel types 55 const ( 56 ChannelSlack = "slack" 57 ChannelLINE = "line" 58 ChannelTeams = "teams" 59 ChannelWeChat = "wechat" 60 ChannelWeb = "web" 61 ChannelFeishu = "feishu" 62 ChannelLark = "lark" 63 ChannelDiscord = "discord" 64 ChannelSchedule = "schedule" 65 ChannelSystem = "system" 66 ) 67 68 // Reply format types 69 const ( 70 FormatText = "text" 71 FormatMarkdown = "markdown" 72 ) 73 74 // ServerMessage is the envelope for all server-to-daemon messages. 75 type ServerMessage struct { 76 Type string `json:"type"` 77 MessageID string `json:"message_id,omitempty"` 78 Payload json.RawMessage `json:"payload,omitempty"` 79 } 80 81 // DaemonMessage is the envelope for all daemon-to-server messages. 82 type DaemonMessage struct { 83 Type string `json:"type"` 84 MessageID string `json:"message_id,omitempty"` 85 Payload json.RawMessage `json:"payload,omitempty"` 86 } 87 88 // MessagePayload is what the daemon's agent loop processes. 89 type MessagePayload struct { 90 Channel string `json:"channel"` 91 ThreadID string `json:"thread_id"` 92 Sender string `json:"sender"` 93 Text string `json:"text"` 94 Content []RequestContentBlock `json:"content,omitempty"` // multimodal content blocks (reserved for Cloud) 95 AgentName string `json:"agent_name,omitempty"` 96 MessageID string `json:"-"` // set locally from envelope, not from JSON 97 Timestamp string `json:"timestamp"` 98 Source string `json:"source,omitempty"` // populated by Cloud; "slack", "line", "webhook" 99 CWD string `json:"cwd,omitempty"` // project path override from Cloud/Desktop 100 Files []RemoteFile `json:"files,omitempty"` // file attachments from messaging platforms 101 } 102 103 // RemoteFile describes a file attachment forwarded by Cloud from a messaging platform. 104 type RemoteFile struct { 105 Name string `json:"name"` 106 MimeType string `json:"mimetype,omitempty"` 107 Size int64 `json:"size,omitempty"` 108 URL string `json:"url"` 109 AuthHeader string `json:"auth_header,omitempty"` 110 } 111 112 // ReplyPayload is sent back after agent completes. 113 type ReplyPayload struct { 114 Channel string `json:"channel"` 115 ThreadID string `json:"thread_id"` 116 Text string `json:"text"` 117 Format string `json:"format,omitempty"` 118 } 119 120 // ProactivePayload is sent by the daemon to push an unsolicited message 121 // to all channels mapped to the named agent. 122 type ProactivePayload struct { 123 AgentName string `json:"agent_name"` 124 Text string `json:"text"` 125 Format string `json:"format,omitempty"` // "text" (default) or "markdown" 126 SessionID string `json:"session_id,omitempty"` 127 } 128 129 // DaemonEventPayload carries a single agent loop event to Cloud. 130 type DaemonEventPayload struct { 131 EventType string `json:"event_type"` 132 Message string `json:"message"` 133 Data map[string]interface{} `json:"data,omitempty"` 134 Seq int64 `json:"seq"` 135 Timestamp string `json:"ts"` 136 } 137 138 // ClaimAckPayload is sent to confirm or deny a claim. 139 type ClaimAckPayload struct { 140 Granted bool `json:"granted"` 141 } 142 143 // IsSystemChannel returns true for channels that don't expect agent processing. 144 func IsSystemChannel(channel string) bool { 145 return channel == ChannelSystem 146 }