-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathprotocol.go
More file actions
312 lines (265 loc) · 8.63 KB
/
Copy pathprotocol.go
File metadata and controls
312 lines (265 loc) · 8.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
package main
import (
"encoding/json"
"time"
)
// --- JSON-RPC 2.0 ---
type JSONRPCMessage struct {
JSONRPC string `json:"jsonrpc"`
ID *json.RawMessage `json:"id,omitempty"`
Method string `json:"method,omitempty"`
Params json.RawMessage `json:"params,omitempty"`
Result json.RawMessage `json:"result,omitempty"`
Error *JSONRPCError `json:"error,omitempty"`
}
type JSONRPCError struct {
Code int `json:"code"`
Message string `json:"message"`
Data json.RawMessage `json:"data,omitempty"`
}
func newRequest(id int, method string, params any) ([]byte, error) {
raw, err := json.Marshal(id)
if err != nil {
return nil, err
}
idRaw := json.RawMessage(raw)
p, err := json.Marshal(params)
if err != nil {
return nil, err
}
return json.Marshal(JSONRPCMessage{
JSONRPC: "2.0",
ID: &idRaw,
Method: method,
Params: p,
})
}
func newResponse(id *json.RawMessage, result any) ([]byte, error) {
r, err := json.Marshal(result)
if err != nil {
return nil, err
}
return json.Marshal(JSONRPCMessage{
JSONRPC: "2.0",
ID: id,
Result: r,
})
}
func newErrorResponse(id *json.RawMessage, code int, message string) ([]byte, error) {
return json.Marshal(JSONRPCMessage{
JSONRPC: "2.0",
ID: id,
Error: &JSONRPCError{Code: code, Message: message},
})
}
// --- ACP Types ---
type InitializeParams struct {
ProtocolVersion int `json:"protocolVersion"`
ClientCapabilities ClientCapabilities `json:"clientCapabilities"`
ClientInfo ClientInfo `json:"clientInfo"`
}
type ClientCapabilities struct {
FS *FSCapabilities `json:"fs,omitempty"`
Terminal bool `json:"terminal,omitempty"`
}
type FSCapabilities struct {
ReadTextFile bool `json:"readTextFile"`
WriteTextFile bool `json:"writeTextFile"`
}
type ClientInfo struct {
Name string `json:"name"`
Title string `json:"title"`
Version string `json:"version"`
}
type InitializeResult struct {
ProtocolVersion int `json:"protocolVersion"`
AgentCapabilities json.RawMessage `json:"agentCapabilities,omitempty"`
AgentInfo json.RawMessage `json:"agentInfo,omitempty"`
AuthMethods json.RawMessage `json:"authMethods,omitempty"`
}
type SessionNewParams struct {
CWD string `json:"cwd"`
MCPServers []any `json:"mcpServers"`
}
type SessionNewResult struct {
SessionID string `json:"sessionId"`
}
type PromptContent struct {
Type string `json:"type"`
Text string `json:"text,omitempty"`
}
type SessionPromptParams struct {
SessionID string `json:"sessionId"`
Prompt []PromptContent `json:"prompt"`
}
type SessionPromptResult struct {
StopReason string `json:"stopReason"`
}
type SessionUpdateParams struct {
SessionID string `json:"sessionId"`
Update json.RawMessage `json:"update"`
}
type SessionUpdate struct {
SessionUpdate string `json:"sessionUpdate"`
}
type AgentMessageChunk struct {
SessionUpdate string `json:"sessionUpdate"`
Content PromptContent `json:"content"`
}
// ToolCallFlat is the flat structure sent by ACP for both "tool_call" and
// "tool_call_update" session updates. All fields live at the top level.
type ToolCallFlat struct {
SessionUpdate string `json:"sessionUpdate"`
ToolCallID string `json:"toolCallId"`
Title string `json:"title,omitempty"`
Kind string `json:"kind,omitempty"`
Status string `json:"status,omitempty"`
Content json.RawMessage `json:"content,omitempty"`
RawInput json.RawMessage `json:"rawInput,omitempty"`
RawOutput json.RawMessage `json:"rawOutput,omitempty"`
}
type ToolCallResultUpdate struct {
SessionUpdate string `json:"sessionUpdate"`
ToolCallID string `json:"toolCallId"`
Result json.RawMessage `json:"result,omitempty"`
}
// toolCallMeta extracts the _meta.claudeCode fields embedded in tool_call_update
// events. Claude Code embeds the original file content in toolResponse when a
// file-writing tool (Edit, Write) completes.
type toolCallMeta struct {
Meta *struct {
ClaudeCode *struct {
ToolResponse *struct {
FilePath string `json:"filePath"`
OriginalFile string `json:"originalFile"`
} `json:"toolResponse,omitempty"`
} `json:"claudeCode,omitempty"`
} `json:"_meta,omitempty"`
}
type PermissionRequestParams struct {
SessionID string `json:"sessionId"`
ToolCall PermissionToolCall `json:"toolCall"`
Options []PermissionOption `json:"options"`
}
type PermissionToolCall struct {
ToolCallID string `json:"toolCallId"`
Title string `json:"title,omitempty"`
Kind string `json:"kind,omitempty"`
Status string `json:"status,omitempty"`
RawInput json.RawMessage `json:"rawInput,omitempty"`
}
type PermissionOption struct {
OptionID string `json:"optionId"`
Name string `json:"name"`
Kind string `json:"kind"`
}
type PermissionOutcome struct {
Outcome struct {
Outcome string `json:"outcome"`
OptionID string `json:"optionId,omitempty"`
} `json:"outcome"`
}
type FSReadParams struct {
SessionID string `json:"sessionId"`
Path string `json:"path"`
Line int `json:"line,omitempty"`
Limit int `json:"limit,omitempty"`
}
type FSWriteParams struct {
SessionID string `json:"sessionId"`
Path string `json:"path"`
Content string `json:"content"`
}
type TerminalCreateParams struct {
SessionID string `json:"sessionId"`
Command string `json:"command"`
Args []string `json:"args,omitempty"`
CWD string `json:"cwd,omitempty"`
}
type TerminalOutputParams struct {
SessionID string `json:"sessionId"`
TerminalID string `json:"terminalId"`
}
type TerminalWaitParams struct {
SessionID string `json:"sessionId"`
TerminalID string `json:"terminalId"`
}
type TerminalKillParams struct {
SessionID string `json:"sessionId"`
TerminalID string `json:"terminalId"`
}
type TerminalReleaseParams struct {
SessionID string `json:"sessionId"`
TerminalID string `json:"terminalId"`
}
// --- WebSocket Protocol ---
type WSMessage struct {
Type string `json:"type"`
Data json.RawMessage `json:"data,omitempty"`
}
type WSHistoryMessage struct {
Type string `json:"type"`
Messages []WSMessage `json:"messages"`
}
type WSPrompt struct {
Type string `json:"type"`
Text string `json:"text"`
}
type WSPermissionResponse struct {
Type string `json:"type"`
RequestID string `json:"requestId"`
OptionID string `json:"optionId"`
}
type WSAgentText struct {
Text string `json:"text"`
}
type WSToolCall struct {
ToolCallID string `json:"toolCallId"`
Title string `json:"title"`
Kind string `json:"kind"`
Status string `json:"status"`
Content string `json:"content,omitempty"`
}
type WSToolResult struct {
ToolCallID string `json:"toolCallId"`
Content string `json:"content"`
}
type WSPermissionRequest struct {
RequestID string `json:"requestId"`
Title string `json:"title"`
Kind string `json:"kind"`
Command string `json:"command,omitempty"` // extracted from rawInput for shell commands
Options []PermissionOption `json:"options"`
}
type WSError struct {
Message string `json:"message"`
}
// SubAgentInfo tracks a sub-agent tool call (e.g. Task or dispatch_agent)
// spawned within a session.
type SubAgentInfo struct {
ToolCallID string `json:"toolCallId"`
Title string `json:"title"`
Status string `json:"status"` // "running", "completed", "failed"
StartedAt time.Time `json:"startedAt"`
}
type WSSessionInfo struct {
ID string `json:"id"`
WorkingDir string `json:"workingDir"`
ACPSession string `json:"acpSessionId"`
Status string `json:"status"`
Backend string `json:"backend"`
Model string `json:"model,omitempty"`
SkipPermissions bool `json:"skipPermissions"`
PlanMode bool `json:"planMode"`
LastMessage string `json:"lastMessage,omitempty"`
CurrentTool string `json:"currentTool,omitempty"`
CurrentPrompt string `json:"currentPrompt,omitempty"`
IsRunning bool `json:"isRunning"`
QueueDepth int `json:"queueDepth"`
PendingPermission bool `json:"pendingPermission"`
Title string `json:"title,omitempty"`
Summary string `json:"summary,omitempty"`
PRURL string `json:"prUrl,omitempty"`
CreatedAt time.Time `json:"createdAt"`
SubAgents []SubAgentInfo `json:"subAgents,omitempty"`
}