mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Add an API for resuming tasks by ID (#7122)
This commit is contained in:
parent
44086e4a86
commit
9a734d0cab
5 changed files with 182 additions and 1 deletions
90
packages/ipc/README.md
Normal file
90
packages/ipc/README.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# IPC (Inter-Process Communication)
|
||||
|
||||
This package provides IPC functionality for Roo Code, allowing external applications to communicate with the extension through a socket-based interface.
|
||||
|
||||
## Available Commands
|
||||
|
||||
The IPC interface supports the following task commands:
|
||||
|
||||
### StartNewTask
|
||||
|
||||
Starts a new task with optional configuration and initial message.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `configuration`: RooCode settings object
|
||||
- `text`: Initial task message (string)
|
||||
- `images`: Array of image data URIs (optional)
|
||||
- `newTab`: Whether to open in a new tab (boolean, optional)
|
||||
|
||||
### CancelTask
|
||||
|
||||
Cancels a running task.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `data`: Task ID to cancel (string)
|
||||
|
||||
### CloseTask
|
||||
|
||||
Closes a task and performs cleanup.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `data`: Task ID to close (string)
|
||||
|
||||
### ResumeTask
|
||||
|
||||
Resumes a task from history.
|
||||
|
||||
**Parameters:**
|
||||
|
||||
- `data`: Task ID to resume (string)
|
||||
|
||||
**Error Handling:**
|
||||
|
||||
- If the task ID is not found in history, the command will fail gracefully without crashing the IPC server
|
||||
- Errors are logged for debugging purposes but do not propagate to the client
|
||||
|
||||
## Usage Example
|
||||
|
||||
```typescript
|
||||
import { IpcClient } from "@roo-code/ipc"
|
||||
|
||||
const client = new IpcClient("/path/to/socket")
|
||||
|
||||
// Resume a task
|
||||
client.sendCommand({
|
||||
commandName: "ResumeTask",
|
||||
data: "task-123",
|
||||
})
|
||||
|
||||
// Start a new task
|
||||
client.sendCommand({
|
||||
commandName: "StartNewTask",
|
||||
data: {
|
||||
configuration: {
|
||||
/* RooCode settings */
|
||||
},
|
||||
text: "Hello, world!",
|
||||
images: [],
|
||||
newTab: false,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
The IPC interface also emits task events that clients can listen to:
|
||||
|
||||
- `TaskStarted`: When a task begins
|
||||
- `TaskCompleted`: When a task finishes
|
||||
- `TaskAborted`: When a task is cancelled
|
||||
- `Message`: When a task sends a message
|
||||
|
||||
## Socket Path
|
||||
|
||||
The socket path is typically located in the system's temporary directory and follows the pattern:
|
||||
|
||||
- Unix/Linux/macOS: `/tmp/roo-code-{id}.sock`
|
||||
- Windows: `\\.\pipe\roo-code-{id}`
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@roo-code/types",
|
||||
"version": "1.49.0",
|
||||
"version": "1.50.0",
|
||||
"description": "TypeScript type definitions for Roo Code.",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
|
|
|
|||
75
packages/types/src/__tests__/ipc.test.ts
Normal file
75
packages/types/src/__tests__/ipc.test.ts
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { describe, it, expect } from "vitest"
|
||||
import { TaskCommandName, taskCommandSchema } from "../ipc.js"
|
||||
|
||||
describe("IPC Types", () => {
|
||||
describe("TaskCommandName", () => {
|
||||
it("should include ResumeTask command", () => {
|
||||
expect(TaskCommandName.ResumeTask).toBe("ResumeTask")
|
||||
})
|
||||
|
||||
it("should have all expected task commands", () => {
|
||||
const expectedCommands = ["StartNewTask", "CancelTask", "CloseTask", "ResumeTask"]
|
||||
const actualCommands = Object.values(TaskCommandName)
|
||||
|
||||
expectedCommands.forEach((command) => {
|
||||
expect(actualCommands).toContain(command)
|
||||
})
|
||||
})
|
||||
|
||||
describe("Error Handling", () => {
|
||||
it("should handle ResumeTask command gracefully when task not found", () => {
|
||||
// This test verifies the schema validation - the actual error handling
|
||||
// for invalid task IDs is tested at the API level, not the schema level
|
||||
const resumeTaskCommand = {
|
||||
commandName: TaskCommandName.ResumeTask,
|
||||
data: "non-existent-task-id",
|
||||
}
|
||||
|
||||
const result = taskCommandSchema.safeParse(resumeTaskCommand)
|
||||
expect(result.success).toBe(true)
|
||||
|
||||
if (result.success) {
|
||||
expect(result.data.commandName).toBe("ResumeTask")
|
||||
expect(result.data.data).toBe("non-existent-task-id")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("taskCommandSchema", () => {
|
||||
it("should validate ResumeTask command with taskId", () => {
|
||||
const resumeTaskCommand = {
|
||||
commandName: TaskCommandName.ResumeTask,
|
||||
data: "task-123",
|
||||
}
|
||||
|
||||
const result = taskCommandSchema.safeParse(resumeTaskCommand)
|
||||
expect(result.success).toBe(true)
|
||||
|
||||
if (result.success) {
|
||||
expect(result.data.commandName).toBe("ResumeTask")
|
||||
expect(result.data.data).toBe("task-123")
|
||||
}
|
||||
})
|
||||
|
||||
it("should reject ResumeTask command with invalid data", () => {
|
||||
const invalidCommand = {
|
||||
commandName: TaskCommandName.ResumeTask,
|
||||
data: 123, // Should be string
|
||||
}
|
||||
|
||||
const result = taskCommandSchema.safeParse(invalidCommand)
|
||||
expect(result.success).toBe(false)
|
||||
})
|
||||
|
||||
it("should reject ResumeTask command without data", () => {
|
||||
const invalidCommand = {
|
||||
commandName: TaskCommandName.ResumeTask,
|
||||
// Missing data field
|
||||
}
|
||||
|
||||
const result = taskCommandSchema.safeParse(invalidCommand)
|
||||
expect(result.success).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -44,6 +44,7 @@ export enum TaskCommandName {
|
|||
StartNewTask = "StartNewTask",
|
||||
CancelTask = "CancelTask",
|
||||
CloseTask = "CloseTask",
|
||||
ResumeTask = "ResumeTask",
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,6 +69,10 @@ export const taskCommandSchema = z.discriminatedUnion("commandName", [
|
|||
commandName: z.literal(TaskCommandName.CloseTask),
|
||||
data: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
commandName: z.literal(TaskCommandName.ResumeTask),
|
||||
data: z.string(),
|
||||
}),
|
||||
])
|
||||
|
||||
export type TaskCommand = z.infer<typeof taskCommandSchema>
|
||||
|
|
|
|||
|
|
@ -78,6 +78,17 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
|
|||
await vscode.commands.executeCommand("workbench.action.files.saveFiles")
|
||||
await vscode.commands.executeCommand("workbench.action.closeWindow")
|
||||
break
|
||||
case TaskCommandName.ResumeTask:
|
||||
this.log(`[API] ResumeTask -> ${data}`)
|
||||
try {
|
||||
await this.resumeTask(data)
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error)
|
||||
this.log(`[API] ResumeTask failed for taskId ${data}: ${errorMessage}`)
|
||||
// Don't rethrow - we want to prevent IPC server crashes
|
||||
// The error is logged for debugging purposes
|
||||
}
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue