mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
feat: add IPC query handlers for commands, modes, and models (#11279)
Add GetCommands, GetModes, and GetModels to the IPC protocol so external clients can fetch slash commands, available modes, and Roo provider models without going through the internal webview message channel. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6d2459c7e8
commit
9b39d2242a
3 changed files with 106 additions and 3 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { z } from "zod"
|
||||
|
||||
import { clineMessageSchema, queuedMessageSchema, tokenUsageSchema } from "./message.js"
|
||||
import { modelInfoSchema } from "./model.js"
|
||||
import { toolNamesSchema, toolUsageSchema } from "./tool.js"
|
||||
|
||||
/**
|
||||
|
|
@ -45,6 +46,11 @@ export enum RooCodeEventName {
|
|||
ModeChanged = "modeChanged",
|
||||
ProviderProfileChanged = "providerProfileChanged",
|
||||
|
||||
// Query Responses
|
||||
CommandsResponse = "commandsResponse",
|
||||
ModesResponse = "modesResponse",
|
||||
ModelsResponse = "modelsResponse",
|
||||
|
||||
// Evals
|
||||
EvalPass = "evalPass",
|
||||
EvalFail = "evalFail",
|
||||
|
|
@ -108,6 +114,20 @@ export const rooCodeEventsSchema = z.object({
|
|||
|
||||
[RooCodeEventName.ModeChanged]: z.tuple([z.string()]),
|
||||
[RooCodeEventName.ProviderProfileChanged]: z.tuple([z.object({ name: z.string(), provider: z.string() })]),
|
||||
|
||||
[RooCodeEventName.CommandsResponse]: z.tuple([
|
||||
z.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
source: z.enum(["global", "project", "built-in"]),
|
||||
filePath: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
argumentHint: z.string().optional(),
|
||||
}),
|
||||
),
|
||||
]),
|
||||
[RooCodeEventName.ModesResponse]: z.tuple([z.array(z.object({ slug: z.string(), name: z.string() }))]),
|
||||
[RooCodeEventName.ModelsResponse]: z.tuple([z.record(z.string(), modelInfoSchema)]),
|
||||
})
|
||||
|
||||
export type RooCodeEvents = z.infer<typeof rooCodeEventsSchema>
|
||||
|
|
@ -237,6 +257,23 @@ export const taskEventSchema = z.discriminatedUnion("eventName", [
|
|||
taskId: z.number().optional(),
|
||||
}),
|
||||
|
||||
// Query Responses
|
||||
z.object({
|
||||
eventName: z.literal(RooCodeEventName.CommandsResponse),
|
||||
payload: rooCodeEventsSchema.shape[RooCodeEventName.CommandsResponse],
|
||||
taskId: z.number().optional(),
|
||||
}),
|
||||
z.object({
|
||||
eventName: z.literal(RooCodeEventName.ModesResponse),
|
||||
payload: rooCodeEventsSchema.shape[RooCodeEventName.ModesResponse],
|
||||
taskId: z.number().optional(),
|
||||
}),
|
||||
z.object({
|
||||
eventName: z.literal(RooCodeEventName.ModelsResponse),
|
||||
payload: rooCodeEventsSchema.shape[RooCodeEventName.ModelsResponse],
|
||||
taskId: z.number().optional(),
|
||||
}),
|
||||
|
||||
// Evals
|
||||
z.object({
|
||||
eventName: z.literal(RooCodeEventName.EvalPass),
|
||||
|
|
|
|||
|
|
@ -46,6 +46,9 @@ export enum TaskCommandName {
|
|||
CloseTask = "CloseTask",
|
||||
ResumeTask = "ResumeTask",
|
||||
SendMessage = "SendMessage",
|
||||
GetCommands = "GetCommands",
|
||||
GetModes = "GetModes",
|
||||
GetModels = "GetModels",
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -79,6 +82,15 @@ export const taskCommandSchema = z.discriminatedUnion("commandName", [
|
|||
images: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
z.object({
|
||||
commandName: z.literal(TaskCommandName.GetCommands),
|
||||
}),
|
||||
z.object({
|
||||
commandName: z.literal(TaskCommandName.GetModes),
|
||||
}),
|
||||
z.object({
|
||||
commandName: z.literal(TaskCommandName.GetModels),
|
||||
}),
|
||||
])
|
||||
|
||||
export type TaskCommand = z.infer<typeof taskCommandSchema>
|
||||
|
|
|
|||
|
|
@ -20,10 +20,13 @@ import {
|
|||
IpcMessageType,
|
||||
} from "@roo-code/types"
|
||||
import { IpcServer } from "@roo-code/ipc"
|
||||
import { CloudService } from "@roo-code/cloud"
|
||||
|
||||
import { Package } from "../shared/package"
|
||||
import { ClineProvider } from "../core/webview/ClineProvider"
|
||||
import { openClineInNewTab } from "../activate/registerCommands"
|
||||
import { getCommands } from "../services/command/commands"
|
||||
import { getModels } from "../api/providers/fetchers/modelCache"
|
||||
|
||||
export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
||||
private readonly outputChannel: vscode.OutputChannel
|
||||
|
|
@ -64,7 +67,15 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
ipc.listen()
|
||||
this.log(`[API] ipc server started: socketPath=${socketPath}, pid=${process.pid}, ppid=${process.ppid}`)
|
||||
|
||||
ipc.on(IpcMessageType.TaskCommand, async (_clientId, command) => {
|
||||
ipc.on(IpcMessageType.TaskCommand, async (clientId, command) => {
|
||||
const sendResponse = (eventName: RooCodeEventName, payload: unknown[]) => {
|
||||
ipc.send(clientId, {
|
||||
type: IpcMessageType.TaskEvent,
|
||||
origin: IpcOrigin.Server,
|
||||
data: { eventName, payload } as TaskEvent,
|
||||
})
|
||||
}
|
||||
|
||||
switch (command.commandName) {
|
||||
case TaskCommandName.StartNewTask:
|
||||
this.log(
|
||||
|
|
@ -88,13 +99,56 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
this.log(`[API] ResumeTask failed for taskId ${command.data}: ${errorMessage}`)
|
||||
// Don't rethrow - we want to prevent IPC server crashes
|
||||
// The error is logged for debugging purposes
|
||||
// Don't rethrow - we want to prevent IPC server crashes.
|
||||
// The error is logged for debugging purposes.
|
||||
}
|
||||
break
|
||||
case TaskCommandName.SendMessage:
|
||||
this.log(`[API] SendMessage -> ${command.data.text}`)
|
||||
await this.sendMessage(command.data.text, command.data.images)
|
||||
break
|
||||
case TaskCommandName.GetCommands:
|
||||
try {
|
||||
const commands = await getCommands(this.sidebarProvider.cwd)
|
||||
|
||||
sendResponse(RooCodeEventName.CommandsResponse, [
|
||||
commands.map((cmd) => ({
|
||||
name: cmd.name,
|
||||
source: cmd.source,
|
||||
filePath: cmd.filePath,
|
||||
description: cmd.description,
|
||||
argumentHint: cmd.argumentHint,
|
||||
})),
|
||||
])
|
||||
} catch (error) {
|
||||
sendResponse(RooCodeEventName.CommandsResponse, [[]])
|
||||
}
|
||||
|
||||
break
|
||||
case TaskCommandName.GetModes:
|
||||
try {
|
||||
const modes = await this.sidebarProvider.getModes()
|
||||
sendResponse(RooCodeEventName.ModesResponse, [modes])
|
||||
} catch (error) {
|
||||
sendResponse(RooCodeEventName.ModesResponse, [[]])
|
||||
}
|
||||
|
||||
break
|
||||
case TaskCommandName.GetModels:
|
||||
try {
|
||||
const models = await getModels({
|
||||
provider: "roo" as const,
|
||||
baseUrl: process.env.ROO_CODE_PROVIDER_URL ?? "https://api.roocode.com/proxy",
|
||||
apiKey: CloudService.hasInstance()
|
||||
? CloudService.instance.authService?.getSessionToken()
|
||||
: undefined,
|
||||
})
|
||||
|
||||
sendResponse(RooCodeEventName.ModelsResponse, [models])
|
||||
} catch (error) {
|
||||
sendResponse(RooCodeEventName.ModelsResponse, [{}])
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue