mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Add submitUserMessage to Task (#6895)
This commit is contained in:
parent
3ee607202e
commit
f53fd39014
4 changed files with 148 additions and 1 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@roo-code/types",
|
||||
"version": "1.44.0",
|
||||
"version": "1.45.0",
|
||||
"description": "TypeScript type definitions for Roo Code.",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ export interface TaskLike {
|
|||
off<K extends keyof TaskEvents>(event: K, listener: (...args: TaskEvents[K]) => void | Promise<void>): this
|
||||
|
||||
setMessageResponse(text: string, images?: string[]): void
|
||||
submitUserMessage(text: string, images?: string[]): void
|
||||
}
|
||||
|
||||
export type TaskEvents = {
|
||||
|
|
|
|||
|
|
@ -740,6 +740,32 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
this.askResponseImages = images
|
||||
}
|
||||
|
||||
public submitUserMessage(text: string, images?: string[]): void {
|
||||
try {
|
||||
const trimmed = (text ?? "").trim()
|
||||
const imgs = images ?? []
|
||||
|
||||
if (!trimmed && imgs.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const provider = this.providerRef.deref()
|
||||
if (!provider) {
|
||||
console.error("[Task#submitUserMessage] Provider reference lost")
|
||||
return
|
||||
}
|
||||
|
||||
void provider.postMessageToWebview({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: trimmed,
|
||||
images: imgs,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("[Task#submitUserMessage] Failed to submit user message:", error)
|
||||
}
|
||||
}
|
||||
|
||||
async handleTerminalOperation(terminalOperation: "continue" | "abort") {
|
||||
if (terminalOperation === "continue") {
|
||||
this.terminalProcess?.continue()
|
||||
|
|
|
|||
|
|
@ -1493,5 +1493,125 @@ describe("Cline", () => {
|
|||
expect(noModelTask.apiConfiguration.apiProvider).toBe("openai")
|
||||
})
|
||||
})
|
||||
|
||||
describe("submitUserMessage", () => {
|
||||
it("should always route through webview sendMessage invoke", async () => {
|
||||
const task = new Task({
|
||||
provider: mockProvider,
|
||||
apiConfiguration: mockApiConfig,
|
||||
task: "initial task",
|
||||
startTask: false,
|
||||
})
|
||||
|
||||
// Set up some existing messages to simulate an ongoing conversation
|
||||
task.clineMessages = [
|
||||
{
|
||||
ts: Date.now(),
|
||||
type: "say",
|
||||
say: "text",
|
||||
text: "Initial message",
|
||||
},
|
||||
]
|
||||
|
||||
// Call submitUserMessage
|
||||
task.submitUserMessage("test message", ["image1.png"])
|
||||
|
||||
// Verify postMessageToWebview was called with sendMessage invoke
|
||||
expect(mockProvider.postMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: "test message",
|
||||
images: ["image1.png"],
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle empty messages gracefully", async () => {
|
||||
const task = new Task({
|
||||
provider: mockProvider,
|
||||
apiConfiguration: mockApiConfig,
|
||||
task: "initial task",
|
||||
startTask: false,
|
||||
})
|
||||
|
||||
// Call with empty text and no images
|
||||
task.submitUserMessage("", [])
|
||||
|
||||
// Should not call postMessageToWebview for empty messages
|
||||
expect(mockProvider.postMessageToWebview).not.toHaveBeenCalled()
|
||||
|
||||
// Call with whitespace only
|
||||
task.submitUserMessage(" ", [])
|
||||
expect(mockProvider.postMessageToWebview).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should route through webview for both new and existing tasks", async () => {
|
||||
const task = new Task({
|
||||
provider: mockProvider,
|
||||
apiConfiguration: mockApiConfig,
|
||||
task: "initial task",
|
||||
startTask: false,
|
||||
})
|
||||
|
||||
// Test with no messages (new task scenario)
|
||||
task.clineMessages = []
|
||||
task.submitUserMessage("new task", ["image1.png"])
|
||||
|
||||
expect(mockProvider.postMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: "new task",
|
||||
images: ["image1.png"],
|
||||
})
|
||||
|
||||
// Clear mock
|
||||
mockProvider.postMessageToWebview.mockClear()
|
||||
|
||||
// Test with existing messages (ongoing task scenario)
|
||||
task.clineMessages = [
|
||||
{
|
||||
ts: Date.now(),
|
||||
type: "say",
|
||||
say: "text",
|
||||
text: "Initial message",
|
||||
},
|
||||
]
|
||||
task.submitUserMessage("follow-up message", ["image2.png"])
|
||||
|
||||
expect(mockProvider.postMessageToWebview).toHaveBeenCalledWith({
|
||||
type: "invoke",
|
||||
invoke: "sendMessage",
|
||||
text: "follow-up message",
|
||||
images: ["image2.png"],
|
||||
})
|
||||
})
|
||||
|
||||
it("should handle undefined provider gracefully", async () => {
|
||||
const task = new Task({
|
||||
provider: mockProvider,
|
||||
apiConfiguration: mockApiConfig,
|
||||
task: "initial task",
|
||||
startTask: false,
|
||||
})
|
||||
|
||||
// Simulate weakref returning undefined
|
||||
Object.defineProperty(task, "providerRef", {
|
||||
value: { deref: () => undefined },
|
||||
writable: false,
|
||||
configurable: true,
|
||||
})
|
||||
|
||||
// Spy on console.error to verify error is logged
|
||||
const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {})
|
||||
|
||||
// Should log error but not throw
|
||||
task.submitUserMessage("test message")
|
||||
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("[Task#submitUserMessage] Provider reference lost")
|
||||
expect(mockProvider.postMessageToWebview).not.toHaveBeenCalled()
|
||||
|
||||
// Restore console.error
|
||||
consoleErrorSpy.mockRestore()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue