Files
kandev/backend/pkg/acp/protocol/message.go
T
jcfs aebb0c0c76 Implement bidirectional ACP communication with agents
- Add ACP session manager for JSON-RPC 2.0 over stdin/stdout
- Create jsonrpc package with Client for bidirectional communication
- Update agent.sh to run auggie --acp mode
- Add Docker client methods for container stdin/stdout attachment
- Update lifecycle manager to use ACP instead of log streaming
- Add new API endpoints: POST /prompt, POST /cancel, GET /session
- Update AGENTS.md with ACP protocol documentation
- Update OpenAPI spec with new endpoints and schemas

This enables:
- Sending prompts to running agents
- Cancelling agent operations
- Session management (create, load, resume)
- Real-time progress updates via session/update notifications
2026-01-10 10:51:11 +00:00

82 lines
2.2 KiB
Go

package protocol
import (
"encoding/json"
"time"
)
// MessageType represents the type of ACP message
type MessageType string
const (
// Agent → Backend message types
MessageTypeProgress MessageType = "progress"
MessageTypeLog MessageType = "log"
MessageTypeResult MessageType = "result"
MessageTypeError MessageType = "error"
MessageTypeStatus MessageType = "status"
MessageTypeHeartbeat MessageType = "heartbeat"
MessageTypeInputRequired MessageType = "input_required" // Agent requests input from user
MessageTypeSessionInfo MessageType = "session_info" // Agent reports session information
// Backend → Agent message types
MessageTypeControl MessageType = "control" // Control commands (pause, resume, stop)
MessageTypeInputResponse MessageType = "input_response" // Response to input_required
)
// Message represents an ACP protocol message
type Message struct {
Type MessageType `json:"type"`
Timestamp time.Time `json:"timestamp"`
AgentID string `json:"agent_id"`
TaskID string `json:"task_id"`
Data map[string]interface{} `json:"data"`
}
// NewMessage creates a new ACP message with the current timestamp
func NewMessage(msgType MessageType, agentID, taskID string, data map[string]interface{}) *Message {
return &Message{
Type: msgType,
Timestamp: time.Now().UTC(),
AgentID: agentID,
TaskID: taskID,
Data: data,
}
}
// MarshalJSON implements custom JSON marshaling
func (m *Message) MarshalJSON() ([]byte, error) {
type Alias Message
return json.Marshal(&struct {
*Alias
Timestamp string `json:"timestamp"`
}{
Alias: (*Alias)(m),
Timestamp: m.Timestamp.Format(time.RFC3339Nano),
})
}
// Parse parses a JSON string into an ACP message
func Parse(data []byte) (*Message, error) {
var msg Message
if err := json.Unmarshal(data, &msg); err != nil {
return nil, err
}
return &msg, nil
}
// IsValid checks if the message has required fields
func (m *Message) IsValid() bool {
if m.Type == "" {
return false
}
if m.AgentID == "" {
return false
}
if m.TaskID == "" {
return false
}
return true
}