Skip to content

progress 1 #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions creatormodetask.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Creator Mode Task Description

## Overview

This project is an **agentic AI extension** for VSCode, forked from **RooCode**, which itself is a fork of **Cline**. Our fork is called **PearAI-Roo-Code**.

## Goal

We are implementing a **new view called Creator Mode** into this extension. The objective is to introduce a **separate GUI file structure** to minimize merge conflicts when pulling upstream. However, separation is not a strict requirement—if it makes more sense to integrate changes within the existing structure, we will do so.

## Guidelines

- **Maintain Separation:** GUI files should be kept separate to minimize merge conflicts when pulling upstream.
- **Flexible Code Organization:** While separation is preferred, prioritize maintainability and efficiency over strict separation.
- **Keep This Document Updated:** Ensure this file always reflects the latest task status for continuity.
- **Clear and Concise Development:** No unnecessary complexity—keep solutions to the point and functional.
- no bs.
- dont hallucinate.

## Creator Mode Details

- Creator Mode will feature a **text input box** at the center, allowing users to enter prompts.
- The design will differ from the existing **ChatView** (`chatview.tsx`), but function similarly in terms of input handling.
- When the user enters a prompt, it will be sent to the **selected AI model**.
- The response will generate a **new file containing an action plan**, which the user can edit directly.
- A new **mode identifier** (`Creator Mode`) will be introduced, similar to the existing **Ask Mode** and **Architect Mode**.

## Development Plan (Step-by-Step)

[COMPLETED] - add completed tasks here

[NEXT STEPS]

1. **Initial Input Box Implementation**

- Create a simple input box that sends user input to the selected model.
- Ensure basic communication between the UI and backend.
- Validate that the model receives and processes input correctly.

2. **Introduce Creator Mode**

- Understand how existing "ask" mode and "architect" mode are implemented.
- Add `Creator Mode` to the list of available modes.
- Ensure the UI adapts accordingly when this mode is selected.

3. **Implement File Edit Functionality**
- Modify the response handling to generate an editable file.
- Provide a smooth user experience for modifying action plans.

- Proceed step-by-step, ensuring each milestone is functional before progressing, so begin with step **1: Implementing the input box** and verifying AI model communication, once stable, move on to **step 2: introducing Creator Mode**.

This file should be regularly updated to reflect the project's current state and objectives.
50 changes: 41 additions & 9 deletions src/activate/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,38 @@ const getCommandsMap = ({ context, outputChannel, provider }: RegisterCommandOpt
"roo-cline.helpButtonClicked": () => {
vscode.env.openExternal(vscode.Uri.parse("https://docs.roocode.com"))
},
"roo-cline.executeCreatorPlan": async (args: any) => {
const sidebarProvider = ClineProvider.getSidebarInstance()
if (sidebarProvider) {
// Start a new chat in the sidebar
vscode.commands.executeCommand("pearai-roo-cline.SidebarProvider.focus")
await sidebarProvider.clearTask()
await sidebarProvider.handleModeSwitch("code")
await sidebarProvider.postStateToWebview()
await sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" })

// Create the template message using the args
let executePlanTemplate = `This file contains detailed plan to my task. please read it and Execute the plan accordingly.
File: ${args.filePath || "No file specified"}`

if (args.code) {
executePlanTemplate += `Code: \`\`\`
${args.code}
\`\`\`
`
}

if (args.context) {
executePlanTemplate += `Additional context: ${args.context}`
}

await sidebarProvider.postMessageToWebview({
type: "invoke",
invoke: "sendMessage",
text: executePlanTemplate,
})
}
},
}
}

Expand All @@ -51,21 +83,21 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterComman
// deserialize cached webview, but since we use retainContextWhenHidden, we
// don't need to use that event).
// https://github.com/microsoft/vscode-extension-samples/blob/main/webview-sample/src/extension.ts
const tabProvider = new ClineProvider(context, outputChannel)
const tabProvider = new ClineProvider(context, outputChannel, true)
// const column = vscode.window.activeTextEditor ? vscode.window.activeTextEditor.viewColumn : undefined
const lastCol = Math.max(...vscode.window.visibleTextEditors.map((editor) => editor.viewColumn || 0))
// const lastCol = Math.max(...vscode.window.visibleTextEditors.map((editor) => editor.viewColumn || 0))

// Check if there are any visible text editors, otherwise open a new group
// to the right.
const hasVisibleEditors = vscode.window.visibleTextEditors.length > 0
// const hasVisibleEditors = vscode.window.visibleTextEditors.length > 0

if (!hasVisibleEditors) {
await vscode.commands.executeCommand("workbench.action.newGroupRight")
}
// if (!hasVisibleEditors) {
// await vscode.commands.executeCommand("workbench.action.newGroupRight")
// }

const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two
// const targetCol = hasVisibleEditors ? Math.max(lastCol + 1, 1) : vscode.ViewColumn.Two

const panel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Roo Code", targetCol, {
const panel = vscode.window.createWebviewPanel(ClineProvider.tabPanelId, "Roo Code", vscode.ViewColumn.One, {
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [context.extensionUri],
Expand All @@ -82,5 +114,5 @@ const openClineInNewTab = async ({ context, outputChannel }: Omit<RegisterComman

// Lock the editor group so clicking on files doesn't open them over the panel
await delay(100)
await vscode.commands.executeCommand("workbench.action.lockEditorGroup")
// await vscode.commands.executeCommand("workbench.action.lockEditorGroup")
}
30 changes: 25 additions & 5 deletions src/api/providers/anthropic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,31 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
// prompt caching: https://x.com/alexalbert__/status/1823751995901272068
// https://github.com/anthropics/anthropic-sdk-typescript?tab=readme-ov-file#default-headers
// https://github.com/anthropics/anthropic-sdk-typescript/commit/c920b77fc67bd839bfeb6716ceab9d7c9bbe7393
return {
headers: {
"anthropic-beta": "prompt-caching-2024-07-31",
authorization: `Bearer ${this.options.apiKey}`,
},

const betas = []

// Check for the thinking-128k variant first
// if (virtualId === "claude-3-7-sonnet-20250219:thinking") {
// betas.push("output-128k-2025-02-19")
// }

// Then check for models that support prompt caching
switch (modelId) {
case "claude-3-7-sonnet-20250219":
case "claude-3-5-sonnet-20241022":
case "claude-3-5-haiku-20241022":
case "claude-3-opus-20240229":
case "claude-3-haiku-20240307":
betas.push("prompt-caching-2024-07-31")
return {
headers: {
"anthropic-beta": betas.join(","),
authorization: `Bearer ${this.options.apiKey}`,
"creator-mode": String(this.options.creatorMode),
},
}
default:
return undefined
}
})(),
)
Expand Down
2 changes: 2 additions & 0 deletions src/api/providers/deepseek.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export class DeepSeekHandler implements ApiHandler, SingleCompletionHandler {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.options.deepSeekApiKey}`,
"creator-mode": String(this.options.creatorMode),
},
body: JSON.stringify({
model: modelId,
Expand Down Expand Up @@ -139,6 +140,7 @@ export class DeepSeekHandler implements ApiHandler, SingleCompletionHandler {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${this.options.deepSeekApiKey}`,
"creator-mode": String(this.options.creatorMode),
},
body: JSON.stringify({
model: this.getModel().id,
Expand Down
4 changes: 4 additions & 0 deletions src/api/providers/pearai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export class PearAiHandler {
apiKey: options.pearaiApiKey,
anthropicBaseUrl: PEARAI_URL,
apiModelId: "claude-3-5-sonnet-20241022",
creatorMode: options.creatorMode,
})

// Then try to initialize the correct handler asynchronously
Expand All @@ -64,6 +65,7 @@ export class PearAiHandler {
deepSeekApiKey: options.pearaiApiKey,
deepSeekBaseUrl: PEARAI_URL,
apiModelId: underlyingModel,
creatorMode: options.creatorMode,
})
} else {
// Default to Claude
Expand All @@ -72,6 +74,7 @@ export class PearAiHandler {
apiKey: options.pearaiApiKey,
anthropicBaseUrl: PEARAI_URL,
apiModelId: underlyingModel,
creatorMode: options.creatorMode,
})
}
} catch (error) {
Expand All @@ -82,6 +85,7 @@ export class PearAiHandler {
apiKey: options.pearaiApiKey,
anthropicBaseUrl: PEARAI_URL,
apiModelId: "claude-3-5-sonnet-20241022",
creatorMode: options.creatorMode,
})
}
} else if (modelId.startsWith("claude")) {
Expand Down
23 changes: 2 additions & 21 deletions src/core/Cline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1106,7 +1106,7 @@ export class Cline {
// (have to do this for partial and complete since sending content in thinking tags to markdown renderer will automatically be removed)
// Remove end substrings of <thinking or </thinking (below xml parsing is only for opening tags)
// (this is done with the xml parsing below now, but keeping here for reference)
// content = content.replace(/<\/?t(?:h(?:i(?:n(?:k(?:i(?:n(?:g)?)?)?$/, "")
// content = content.replace(/<\/?t(?:h(?:i(?:n(?:k(?:i(?:n(?:g)?)?)?)?$/, "")
// Remove all instances of <thinking> (with optional line break after) and </thinking> (with optional line break before)
// - Needs to be separate since we dont want to remove the line break before the first tag
// - Needs to happen before the xml parsing below
Expand Down Expand Up @@ -1184,6 +1184,7 @@ export class Cline {
return `[${block.name} in ${modeName} mode: '${message}']`
}
}
return `[${block.name}]`
}

if (this.didRejectTool) {
Expand Down Expand Up @@ -2618,26 +2619,6 @@ export class Cline {
}

case "attempt_completion": {
/*
this.consecutiveMistakeCount = 0
let resultToSend = result
if (command) {
await this.say("completion_result", resultToSend)
// TODO: currently we don't handle if this command fails, it could be useful to let cline know and retry
const [didUserReject, commandResult] = await this.executeCommand(command, true)
// if we received non-empty string, the command was rejected or failed
if (commandResult) {
return [didUserReject, commandResult]
}
resultToSend = ""
}
const { response, text, images } = await this.ask("completion_result", resultToSend) // this prompts webview to show 'new task' button, and enable text input (which would be the 'text' here)
if (response === "yesButtonClicked") {
return [false, ""] // signals to recursive loop to stop (for now this never happens since yesButtonClicked will trigger a new task)
}
await this.say("user_feedback", text ?? "", images)
return [
*/
const result: string | undefined = block.params.result
const command: string | undefined = block.params.command
try {
Expand Down
Loading