mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
IPC command for sending messages to the current task (#9149)
This commit is contained in:
parent
62636add14
commit
b09d0a7640
4 changed files with 175 additions and 0 deletions
|
|
@ -9,6 +9,7 @@ import {
|
|||
type IpcMessage,
|
||||
IpcOrigin,
|
||||
IpcMessageType,
|
||||
TaskCommandName,
|
||||
ipcMessageSchema,
|
||||
} from "@roo-code/types"
|
||||
|
||||
|
|
@ -98,6 +99,13 @@ export class IpcClient extends EventEmitter<IpcClientEvents> {
|
|||
this.sendMessage(message)
|
||||
}
|
||||
|
||||
public sendTaskMessage(text?: string, images?: string[]) {
|
||||
this.sendCommand({
|
||||
commandName: TaskCommandName.SendMessage,
|
||||
data: { text, images },
|
||||
})
|
||||
}
|
||||
|
||||
public sendMessage(message: IpcMessage) {
|
||||
ipc.of[this._id]?.emit("message", message)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ export enum TaskCommandName {
|
|||
CancelTask = "CancelTask",
|
||||
CloseTask = "CloseTask",
|
||||
ResumeTask = "ResumeTask",
|
||||
SendMessage = "SendMessage",
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,6 +74,13 @@ export const taskCommandSchema = z.discriminatedUnion("commandName", [
|
|||
commandName: z.literal(TaskCommandName.ResumeTask),
|
||||
data: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
commandName: z.literal(TaskCommandName.SendMessage),
|
||||
data: z.object({
|
||||
text: z.string().optional(),
|
||||
images: z.array(z.string()).optional(),
|
||||
}),
|
||||
}),
|
||||
])
|
||||
|
||||
export type TaskCommand = z.infer<typeof taskCommandSchema>
|
||||
|
|
|
|||
155
src/extension/__tests__/api-send-message.spec.ts
Normal file
155
src/extension/__tests__/api-send-message.spec.ts
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import { describe, it, expect, vi, beforeEach } from "vitest"
|
||||
import * as vscode from "vscode"
|
||||
|
||||
import { API } from "../api"
|
||||
import { ClineProvider } from "../../core/webview/ClineProvider"
|
||||
import { TaskCommandName } from "@roo-code/types"
|
||||
|
||||
vi.mock("vscode")
|
||||
vi.mock("../../core/webview/ClineProvider")
|
||||
|
||||
describe("API - SendMessage Command", () => {
|
||||
let api: API
|
||||
let mockOutputChannel: vscode.OutputChannel
|
||||
let mockProvider: ClineProvider
|
||||
let mockPostMessageToWebview: ReturnType<typeof vi.fn>
|
||||
let mockLog: ReturnType<typeof vi.fn>
|
||||
|
||||
beforeEach(() => {
|
||||
// Setup mocks
|
||||
mockOutputChannel = {
|
||||
appendLine: vi.fn(),
|
||||
} as unknown as vscode.OutputChannel
|
||||
|
||||
mockPostMessageToWebview = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
mockProvider = {
|
||||
context: {} as vscode.ExtensionContext,
|
||||
postMessageToWebview: mockPostMessageToWebview,
|
||||
on: vi.fn(),
|
||||
getCurrentTaskStack: vi.fn().mockReturnValue([]),
|
||||
viewLaunched: true,
|
||||
} as unknown as ClineProvider
|
||||
|
||||
mockLog = vi.fn()
|
||||
|
||||
// Create API instance with logging enabled for testing
|
||||
api = new API(mockOutputChannel, mockProvider, undefined, true)
|
||||
// Override the log method to use our mock
|
||||
;(api as any).log = mockLog
|
||||
})
|
||||
|
||||
it("should handle SendMessage command with text only", async () => {
|
||||
// Arrange
|
||||
const messageText = "Hello, this is a test message"
|
||||
|
||||
// Act
|
||||
await api.sendMessage(messageText)
|
||||
|
||||
// Assert
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: messageText,
|
||||
images: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle SendMessage command with text and images", async () => {
|
||||
// Arrange
|
||||
const messageText = "Analyze this image"
|
||||
const images = [
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
|
||||
]
|
||||
|
||||
// Act
|
||||
await api.sendMessage(messageText, images)
|
||||
|
||||
// Assert
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: messageText,
|
||||
images,
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle SendMessage command with images only", async () => {
|
||||
// Arrange
|
||||
const images = [
|
||||
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
|
||||
]
|
||||
|
||||
// Act
|
||||
await api.sendMessage(undefined, images)
|
||||
|
||||
// Assert
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: undefined,
|
||||
images,
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle SendMessage command with empty parameters", async () => {
|
||||
// Act
|
||||
await api.sendMessage()
|
||||
|
||||
// Assert
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: undefined,
|
||||
images: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("should log SendMessage command when processed via IPC", async () => {
|
||||
// This test verifies the logging behavior when the command comes through IPC
|
||||
// We need to simulate the IPC handler directly since we can't easily test the full IPC flow
|
||||
|
||||
const messageText = "Test message from IPC"
|
||||
const commandData = {
|
||||
text: messageText,
|
||||
images: undefined,
|
||||
}
|
||||
|
||||
// Simulate the IPC command handler calling sendMessage
|
||||
mockLog(`[API] SendMessage -> ${commandData.text}`)
|
||||
await api.sendMessage(commandData.text, commandData.images)
|
||||
|
||||
// Assert that logging occurred
|
||||
expect(mockLog).toHaveBeenCalledWith(`[API] SendMessage -> ${messageText}`)
|
||||
|
||||
// Assert that the message was sent
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: messageText,
|
||||
images: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle SendMessage with multiple images", async () => {
|
||||
// Arrange
|
||||
const messageText = "Compare these images"
|
||||
const images = [
|
||||
"data:image/png;base64,image1data",
|
||||
"data:image/png;base64,image2data",
|
||||
"data:image/png;base64,image3data",
|
||||
]
|
||||
|
||||
// Act
|
||||
await api.sendMessage(messageText, images)
|
||||
|
||||
// Assert
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: messageText,
|
||||
images,
|
||||
})
|
||||
expect(mockPostMessageToWebview).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
@ -91,6 +91,10 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
// The error is logged for debugging purposes
|
||||
}
|
||||
break
|
||||
case TaskCommandName.SendMessage:
|
||||
this.log(`[API] SendMessage -> ${data.text}`)
|
||||
await this.sendMessage(data.text, data.images)
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue