@yeshwanthyk/coding-agent 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +40 -0
- package/README.md +372 -0
- package/package.json +42 -0
- package/src/adapters/acp/index.ts +305 -0
- package/src/adapters/acp/protocol.ts +191 -0
- package/src/adapters/acp/session.ts +289 -0
- package/src/adapters/acp/updates.ts +96 -0
- package/src/adapters/cli/headless.ts +112 -0
- package/src/adapters/cli/validate.ts +50 -0
- package/src/adapters/tui/app.tsx +39 -0
- package/src/agent-events.ts +671 -0
- package/src/args.ts +102 -0
- package/src/autocomplete-commands.ts +102 -0
- package/src/commands.ts +23 -0
- package/src/compact-handler.ts +272 -0
- package/src/components/Footer.tsx +49 -0
- package/src/components/Header.tsx +218 -0
- package/src/components/MessageList.tsx +380 -0
- package/src/config.ts +1 -0
- package/src/domain/commands/builtin/clear.ts +14 -0
- package/src/domain/commands/builtin/compact.ts +96 -0
- package/src/domain/commands/builtin/conceal.ts +9 -0
- package/src/domain/commands/builtin/diffwrap.ts +9 -0
- package/src/domain/commands/builtin/editor.ts +24 -0
- package/src/domain/commands/builtin/exit.ts +14 -0
- package/src/domain/commands/builtin/followup.ts +24 -0
- package/src/domain/commands/builtin/index.ts +29 -0
- package/src/domain/commands/builtin/login.ts +118 -0
- package/src/domain/commands/builtin/model.ts +66 -0
- package/src/domain/commands/builtin/status.ts +32 -0
- package/src/domain/commands/builtin/steer.ts +24 -0
- package/src/domain/commands/builtin/theme.ts +23 -0
- package/src/domain/commands/builtin/thinking.ts +16 -0
- package/src/domain/commands/helpers.ts +41 -0
- package/src/domain/commands/registry.ts +42 -0
- package/src/domain/commands/types.ts +69 -0
- package/src/domain/messaging/content.ts +117 -0
- package/src/editor.ts +103 -0
- package/src/extensibility/schema.ts +1 -0
- package/src/extensibility/validation.ts +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useAgentEvents.ts +28 -0
- package/src/hooks/useEditorBridge.ts +101 -0
- package/src/hooks/useGitStatus.ts +28 -0
- package/src/hooks/usePromptQueue.ts +7 -0
- package/src/hooks/useSessionController.ts +5 -0
- package/src/hooks/useSpinner.ts +28 -0
- package/src/hooks/useToastManager.ts +26 -0
- package/src/index.ts +188 -0
- package/src/keyboard-handler.ts +134 -0
- package/src/profiler.ts +40 -0
- package/src/runtime/context.tsx +16 -0
- package/src/runtime/factory.ts +63 -0
- package/src/runtime/git/git-info.ts +25 -0
- package/src/runtime/session/session-controller.ts +208 -0
- package/src/session-manager.ts +1 -0
- package/src/session-picker.tsx +134 -0
- package/src/shell-runner.ts +134 -0
- package/src/syntax-highlighting.ts +114 -0
- package/src/theme-names.ts +37 -0
- package/src/tool-ui-contracts.ts +77 -0
- package/src/tui-open-rendering.tsx +565 -0
- package/src/types.ts +89 -0
- package/src/ui/app-shell/TuiApp.tsx +586 -0
- package/src/ui/clipboard/osc52.ts +18 -0
- package/src/ui/components/modals/ConfirmModal.tsx +52 -0
- package/src/ui/components/modals/EditorModal.tsx +39 -0
- package/src/ui/components/modals/InputModal.tsx +30 -0
- package/src/ui/components/modals/ModalContainer.tsx +67 -0
- package/src/ui/components/modals/SelectModal.tsx +48 -0
- package/src/ui/components/modals/index.ts +4 -0
- package/src/ui/features/composer/Composer.tsx +73 -0
- package/src/ui/features/composer/SlashCommandHandler.ts +58 -0
- package/src/ui/features/composer/keyboard.ts +3 -0
- package/src/ui/features/main-view/MainView.tsx +367 -0
- package/src/ui/features/message-pane/MessagePane.tsx +34 -0
- package/src/ui/hooks/useModals.ts +74 -0
- package/src/ui/state/app-store.ts +67 -0
- package/src/utils.ts +14 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP (Agent Client Protocol) server mode for Zed integration
|
|
3
|
+
* JSON-RPC 2.0 over stdio
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Agent } from "@yeshwanthyk/agent-core"
|
|
7
|
+
import { getModels, type KnownProvider, type Model, type Api } from "@yeshwanthyk/ai"
|
|
8
|
+
import { createRuntime } from "@runtime/factory.js"
|
|
9
|
+
import { Effect } from "effect"
|
|
10
|
+
import {
|
|
11
|
+
type JsonRpcRequest,
|
|
12
|
+
type JsonRpcNotification,
|
|
13
|
+
type InitializeParams,
|
|
14
|
+
type InitializeResult,
|
|
15
|
+
type NewSessionParams,
|
|
16
|
+
type NewSessionResult,
|
|
17
|
+
type PromptParams,
|
|
18
|
+
type PromptResult,
|
|
19
|
+
type CancelParams,
|
|
20
|
+
type SetModelParams,
|
|
21
|
+
type SetModelResult,
|
|
22
|
+
type ModelOption,
|
|
23
|
+
makeResponse,
|
|
24
|
+
makeError,
|
|
25
|
+
ErrorCodes,
|
|
26
|
+
} from "./protocol.js"
|
|
27
|
+
import { createUpdateEmitter } from "./updates.js"
|
|
28
|
+
import { createAcpSession, type AcpSession } from "./session.js"
|
|
29
|
+
import pkg from "../../../package.json"
|
|
30
|
+
|
|
31
|
+
// Fixed model list for Zed picker
|
|
32
|
+
const MODEL_OPTIONS: ModelOption[] = [
|
|
33
|
+
{ modelId: "claude-opus-4-5", name: "Claude Opus 4.5" },
|
|
34
|
+
{ modelId: "codex/gpt-5.2-codex", name: "GPT 5.2 Codex" },
|
|
35
|
+
{ modelId: "opencode/glm-4.7-free", name: "GLM 4.7 Free" },
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
interface AcpServerState {
|
|
39
|
+
initialized: boolean
|
|
40
|
+
session: AcpSession | null
|
|
41
|
+
agent: Agent | null
|
|
42
|
+
currentModelId: string
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function parseModelSpec(spec: string): { provider: KnownProvider; modelId: string } {
|
|
46
|
+
if (spec.includes("/")) {
|
|
47
|
+
const [provider, ...rest] = spec.split("/")
|
|
48
|
+
return { provider: provider as KnownProvider, modelId: rest.join("/") }
|
|
49
|
+
}
|
|
50
|
+
// Default to anthropic for models without provider prefix
|
|
51
|
+
return { provider: "anthropic", modelId: spec }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function findModel(provider: KnownProvider, modelId: string): Model<Api> | undefined {
|
|
55
|
+
const models = getModels(provider)
|
|
56
|
+
return models.find((m) => m.id === modelId) as Model<Api> | undefined
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function runAcp(args: { configDir?: string; configPath?: string; model?: string }) {
|
|
60
|
+
const runtime = await createRuntime(
|
|
61
|
+
{
|
|
62
|
+
configDir: args.configDir,
|
|
63
|
+
configPath: args.configPath,
|
|
64
|
+
model: args.model,
|
|
65
|
+
},
|
|
66
|
+
"acp",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
// Initialize hooks with no-op handlers for ACP mode (no interactive UI)
|
|
70
|
+
runtime.hookRunner.initialize({
|
|
71
|
+
sendHandler: () => {},
|
|
72
|
+
sendMessageHandler: () => {},
|
|
73
|
+
sendUserMessageHandler: async () => {},
|
|
74
|
+
steerHandler: async () => {},
|
|
75
|
+
followUpHandler: async () => {},
|
|
76
|
+
isIdleHandler: () => true,
|
|
77
|
+
appendEntryHandler: (customType, data) => runtime.sessionManager.appendEntry(customType, data),
|
|
78
|
+
getSessionId: () => runtime.sessionManager.sessionId,
|
|
79
|
+
getModel: () => runtime.agent.state.model,
|
|
80
|
+
hasUI: false,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
// Determine initial model from args or first in MODEL_OPTIONS
|
|
84
|
+
const initialModelId = args.model?.split(",")[0] ?? MODEL_OPTIONS[0]?.modelId ?? "claude-opus-4-5"
|
|
85
|
+
|
|
86
|
+
const state: AcpServerState = {
|
|
87
|
+
initialized: false,
|
|
88
|
+
session: null,
|
|
89
|
+
agent: null,
|
|
90
|
+
currentModelId: initialModelId,
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Write JSON-RPC message to stdout
|
|
94
|
+
const writeMessage = (msg: object) => {
|
|
95
|
+
const json = JSON.stringify(msg)
|
|
96
|
+
process.stdout.write(json + "\n")
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Handle initialize request
|
|
100
|
+
const handleInitialize = (_params: InitializeParams): InitializeResult => {
|
|
101
|
+
state.initialized = true
|
|
102
|
+
return {
|
|
103
|
+
protocolVersion: 1,
|
|
104
|
+
agentInfo: {
|
|
105
|
+
name: "Marvin",
|
|
106
|
+
version: pkg.version,
|
|
107
|
+
},
|
|
108
|
+
agentCapabilities: {
|
|
109
|
+
promptCapabilities: {
|
|
110
|
+
image: true,
|
|
111
|
+
embeddedContext: false,
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
authMethods: [],
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Handle session/new request
|
|
119
|
+
const handleNewSession = async (params: NewSessionParams): Promise<NewSessionResult> => {
|
|
120
|
+
const sessionId = crypto.randomUUID()
|
|
121
|
+
const cwd = params.cwd || process.cwd()
|
|
122
|
+
|
|
123
|
+
// Parse current model
|
|
124
|
+
const { provider, modelId } = parseModelSpec(state.currentModelId)
|
|
125
|
+
const model = findModel(provider, modelId)
|
|
126
|
+
if (!model) {
|
|
127
|
+
throw new Error(`Model not found: ${state.currentModelId}`)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Prepare runtime agent
|
|
131
|
+
const agent = runtime.agent
|
|
132
|
+
agent.abort()
|
|
133
|
+
agent.reset()
|
|
134
|
+
agent.setModel(model)
|
|
135
|
+
agent.setThinkingLevel(runtime.config.thinking)
|
|
136
|
+
state.agent = agent
|
|
137
|
+
runtime.config.provider = provider
|
|
138
|
+
runtime.config.modelId = model.id
|
|
139
|
+
runtime.config.model = model
|
|
140
|
+
|
|
141
|
+
await Effect.runPromise(runtime.sessionOrchestrator.queue.clear)
|
|
142
|
+
|
|
143
|
+
// Create update emitter
|
|
144
|
+
const emitter = createUpdateEmitter(sessionId, writeMessage)
|
|
145
|
+
|
|
146
|
+
// Model setter
|
|
147
|
+
const setModelFn = (newModelId: string): boolean => {
|
|
148
|
+
const option = MODEL_OPTIONS.find((m) => m.modelId === newModelId)
|
|
149
|
+
if (!option) return false
|
|
150
|
+
|
|
151
|
+
const { provider: p, modelId: m } = parseModelSpec(newModelId)
|
|
152
|
+
const newModel = findModel(p, m)
|
|
153
|
+
if (!newModel) return false
|
|
154
|
+
const activeAgent = state.agent ?? runtime.agent
|
|
155
|
+
activeAgent.setModel(newModel)
|
|
156
|
+
state.currentModelId = newModelId
|
|
157
|
+
runtime.config.provider = p
|
|
158
|
+
runtime.config.modelId = newModel.id
|
|
159
|
+
runtime.config.model = newModel
|
|
160
|
+
return true
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Create session
|
|
164
|
+
state.session = createAcpSession({
|
|
165
|
+
sessionId,
|
|
166
|
+
cwd,
|
|
167
|
+
agent,
|
|
168
|
+
sessionOrchestrator: runtime.sessionOrchestrator,
|
|
169
|
+
emitter,
|
|
170
|
+
models: MODEL_OPTIONS,
|
|
171
|
+
currentModelId: state.currentModelId,
|
|
172
|
+
contextWindow: model.contextWindow,
|
|
173
|
+
thinkingLevel: runtime.config.thinking,
|
|
174
|
+
setModel: setModelFn,
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
return {
|
|
178
|
+
sessionId,
|
|
179
|
+
models: {
|
|
180
|
+
availableModels: MODEL_OPTIONS,
|
|
181
|
+
currentModelId: state.currentModelId,
|
|
182
|
+
},
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Emit post-session notifications (called after response is sent)
|
|
187
|
+
const emitSessionNotifications = () => {
|
|
188
|
+
if (!state.session) return
|
|
189
|
+
const emitter = createUpdateEmitter(state.session.id, writeMessage)
|
|
190
|
+
emitter.emitCommands(state.session.getAvailableCommands())
|
|
191
|
+
emitter.emitModels(MODEL_OPTIONS, state.currentModelId)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Handle session/prompt request
|
|
195
|
+
const handlePrompt = async (params: PromptParams): Promise<PromptResult> => {
|
|
196
|
+
if (!state.session) {
|
|
197
|
+
throw new Error("No active session")
|
|
198
|
+
}
|
|
199
|
+
if (params.sessionId !== state.session.id) {
|
|
200
|
+
throw new Error("Invalid session ID")
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const stopReason = await state.session.prompt(params.prompt)
|
|
204
|
+
return { stopReason }
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// Handle session/cancel notification
|
|
208
|
+
const handleCancel = (params: CancelParams): void => {
|
|
209
|
+
if (state.session && params.sessionId === state.session.id) {
|
|
210
|
+
state.session.cancel()
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Handle session/set_model request
|
|
215
|
+
const handleSetModel = (params: SetModelParams): SetModelResult => {
|
|
216
|
+
if (!state.session) {
|
|
217
|
+
throw new Error("No active session")
|
|
218
|
+
}
|
|
219
|
+
if (params.sessionId !== state.session.id) {
|
|
220
|
+
throw new Error("Invalid session ID")
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const success = state.session.setModel(params.modelId)
|
|
224
|
+
if (!success) {
|
|
225
|
+
throw new Error(`Unknown model: ${params.modelId}`)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return { modelId: params.modelId }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Process a JSON-RPC request
|
|
232
|
+
const processRequest = async (req: JsonRpcRequest): Promise<void> => {
|
|
233
|
+
try {
|
|
234
|
+
let result: unknown
|
|
235
|
+
|
|
236
|
+
switch (req.method) {
|
|
237
|
+
case "initialize":
|
|
238
|
+
result = handleInitialize(req.params as InitializeParams)
|
|
239
|
+
break
|
|
240
|
+
case "session/new":
|
|
241
|
+
result = await handleNewSession(req.params as NewSessionParams)
|
|
242
|
+
break
|
|
243
|
+
case "session/prompt":
|
|
244
|
+
result = await handlePrompt(req.params as PromptParams)
|
|
245
|
+
break
|
|
246
|
+
case "session/set_model":
|
|
247
|
+
result = handleSetModel(req.params as SetModelParams)
|
|
248
|
+
break
|
|
249
|
+
default:
|
|
250
|
+
writeMessage(makeError(req.id, ErrorCodes.MethodNotFound, `Unknown method: ${req.method}`))
|
|
251
|
+
return
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
writeMessage(makeResponse(req.id, result))
|
|
255
|
+
|
|
256
|
+
// Emit notifications after session/new response
|
|
257
|
+
if (req.method === "session/new") {
|
|
258
|
+
emitSessionNotifications()
|
|
259
|
+
}
|
|
260
|
+
} catch (err) {
|
|
261
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
262
|
+
writeMessage(makeError(req.id, ErrorCodes.InternalError, message))
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Process a JSON-RPC notification
|
|
267
|
+
const processNotification = (notif: JsonRpcNotification): void => {
|
|
268
|
+
switch (notif.method) {
|
|
269
|
+
case "session/cancel":
|
|
270
|
+
handleCancel(notif.params as CancelParams)
|
|
271
|
+
break
|
|
272
|
+
// Ignore unknown notifications
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Read and process stdin line by line
|
|
277
|
+
const readline = await import("node:readline")
|
|
278
|
+
const rl = readline.createInterface({
|
|
279
|
+
input: process.stdin,
|
|
280
|
+
terminal: false,
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
for await (const line of rl) {
|
|
284
|
+
if (!line.trim()) continue
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
const msg = JSON.parse(line)
|
|
288
|
+
|
|
289
|
+
if (msg.jsonrpc !== "2.0") {
|
|
290
|
+
writeMessage(makeError(msg.id ?? null, ErrorCodes.InvalidRequest, "Invalid JSON-RPC version"))
|
|
291
|
+
continue
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (msg.id !== undefined) {
|
|
295
|
+
// Request
|
|
296
|
+
await processRequest(msg as JsonRpcRequest)
|
|
297
|
+
} else {
|
|
298
|
+
// Notification
|
|
299
|
+
processNotification(msg as JsonRpcNotification)
|
|
300
|
+
}
|
|
301
|
+
} catch {
|
|
302
|
+
writeMessage(makeError(0, ErrorCodes.ParseError, "Parse error"))
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ACP (Agent Client Protocol) JSON-RPC 2.0 types
|
|
3
|
+
* Spec: https://agentclientprotocol.com
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================================================
|
|
7
|
+
// JSON-RPC 2.0 Base Types
|
|
8
|
+
// ============================================================================
|
|
9
|
+
|
|
10
|
+
export interface JsonRpcRequest {
|
|
11
|
+
jsonrpc: "2.0"
|
|
12
|
+
id: number | string
|
|
13
|
+
method: string
|
|
14
|
+
params?: unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface JsonRpcResponse {
|
|
18
|
+
jsonrpc: "2.0"
|
|
19
|
+
id: number | string
|
|
20
|
+
result?: unknown
|
|
21
|
+
error?: JsonRpcError
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface JsonRpcNotification {
|
|
25
|
+
jsonrpc: "2.0"
|
|
26
|
+
method: string
|
|
27
|
+
params: unknown
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface JsonRpcError {
|
|
31
|
+
code: number
|
|
32
|
+
message: string
|
|
33
|
+
data?: unknown
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Standard JSON-RPC error codes
|
|
37
|
+
export const ErrorCodes = {
|
|
38
|
+
ParseError: -32700,
|
|
39
|
+
InvalidRequest: -32600,
|
|
40
|
+
MethodNotFound: -32601,
|
|
41
|
+
InvalidParams: -32602,
|
|
42
|
+
InternalError: -32603,
|
|
43
|
+
} as const
|
|
44
|
+
|
|
45
|
+
// ============================================================================
|
|
46
|
+
// Initialize
|
|
47
|
+
// ============================================================================
|
|
48
|
+
|
|
49
|
+
export interface InitializeParams {
|
|
50
|
+
protocolVersion: number
|
|
51
|
+
clientInfo?: { name: string; version: string }
|
|
52
|
+
clientCapabilities?: {
|
|
53
|
+
fs?: { readTextFile?: boolean; writeTextFile?: boolean }
|
|
54
|
+
terminal?: boolean
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface InitializeResult {
|
|
59
|
+
protocolVersion: number
|
|
60
|
+
agentInfo: { name: string; version: string }
|
|
61
|
+
agentCapabilities: {
|
|
62
|
+
promptCapabilities: { image: boolean; embeddedContext: boolean }
|
|
63
|
+
}
|
|
64
|
+
authMethods: Array<{ id: string; name: string; description: string }>
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Session
|
|
69
|
+
// ============================================================================
|
|
70
|
+
|
|
71
|
+
export interface NewSessionParams {
|
|
72
|
+
cwd: string
|
|
73
|
+
mcpServers?: unknown[]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface SlashCommand {
|
|
77
|
+
name: string
|
|
78
|
+
description: string
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface ModelOption {
|
|
82
|
+
modelId: string
|
|
83
|
+
name: string
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface NewSessionResult {
|
|
87
|
+
sessionId: string
|
|
88
|
+
models?: {
|
|
89
|
+
availableModels: ModelOption[]
|
|
90
|
+
currentModelId: string
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface PromptParams {
|
|
95
|
+
sessionId: string
|
|
96
|
+
prompt: ContentBlock[]
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface ContentBlock {
|
|
100
|
+
type: "text" | "image" | "resource" | "resource_link"
|
|
101
|
+
text?: string
|
|
102
|
+
data?: string // base64 for images
|
|
103
|
+
mimeType?: string
|
|
104
|
+
uri?: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export type StopReason = "end_turn" | "cancelled" | "max_turn_requests"
|
|
108
|
+
|
|
109
|
+
export interface PromptResult {
|
|
110
|
+
stopReason: StopReason
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export interface CancelParams {
|
|
114
|
+
sessionId: string
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface SetModeParams {
|
|
118
|
+
sessionId: string
|
|
119
|
+
mode: "default" | "acceptEdits" | "bypassPermissions" | "dontAsk" | "plan"
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface SetModelParams {
|
|
123
|
+
sessionId: string
|
|
124
|
+
modelId: string
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export interface SetModelResult {
|
|
128
|
+
modelId: string
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ============================================================================
|
|
132
|
+
// Session Update (Agent → Client notifications)
|
|
133
|
+
// ============================================================================
|
|
134
|
+
|
|
135
|
+
export type SessionUpdateType =
|
|
136
|
+
| "agent_message_chunk"
|
|
137
|
+
| "user_message_chunk"
|
|
138
|
+
| "agent_thought_chunk"
|
|
139
|
+
| "tool_call"
|
|
140
|
+
| "tool_call_update"
|
|
141
|
+
| "plan"
|
|
142
|
+
| "available_commands_update"
|
|
143
|
+
| "current_mode_update"
|
|
144
|
+
| "models_update"
|
|
145
|
+
|
|
146
|
+
export type ToolCallStatus = "pending" | "in_progress" | "completed" | "failed"
|
|
147
|
+
export type ToolCallKind = "read" | "write" | "edit" | "command" | "other"
|
|
148
|
+
|
|
149
|
+
export interface SessionUpdateParams {
|
|
150
|
+
sessionId: string
|
|
151
|
+
update: SessionUpdate
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
export type SessionUpdate =
|
|
155
|
+
| { sessionUpdate: "agent_message_chunk"; content: { type: "text"; text: string } }
|
|
156
|
+
| { sessionUpdate: "user_message_chunk"; content: { type: "text"; text: string } }
|
|
157
|
+
| { sessionUpdate: "agent_thought_chunk"; content: { type: "text"; text: string } }
|
|
158
|
+
| {
|
|
159
|
+
sessionUpdate: "tool_call"
|
|
160
|
+
toolCallId: string
|
|
161
|
+
title: string
|
|
162
|
+
kind: ToolCallKind
|
|
163
|
+
status: ToolCallStatus
|
|
164
|
+
rawInput?: unknown
|
|
165
|
+
}
|
|
166
|
+
| {
|
|
167
|
+
sessionUpdate: "tool_call_update"
|
|
168
|
+
toolCallId: string
|
|
169
|
+
status: ToolCallStatus
|
|
170
|
+
title?: string
|
|
171
|
+
content?: Array<{ type: "text"; text: string }>
|
|
172
|
+
}
|
|
173
|
+
| { sessionUpdate: "available_commands_update"; availableCommands: SlashCommand[] }
|
|
174
|
+
| { sessionUpdate: "models_update"; models: { availableModels: ModelOption[]; currentModelId: string } }
|
|
175
|
+
| { sessionUpdate: "current_mode_update"; currentModeId: string }
|
|
176
|
+
|
|
177
|
+
// ============================================================================
|
|
178
|
+
// Helpers
|
|
179
|
+
// ============================================================================
|
|
180
|
+
|
|
181
|
+
export function makeResponse(id: number | string, result: unknown): JsonRpcResponse {
|
|
182
|
+
return { jsonrpc: "2.0", id, result }
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function makeError(id: number | string, code: number, message: string): JsonRpcResponse {
|
|
186
|
+
return { jsonrpc: "2.0", id, error: { code, message } }
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function makeNotification(method: string, params: unknown): JsonRpcNotification {
|
|
190
|
+
return { jsonrpc: "2.0", method, params }
|
|
191
|
+
}
|