mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Updates to enter interactive mode from the extension settings instead of parsing the prompt
This commit is contained in:
parent
4d53bd2104
commit
f049fb4577
9 changed files with 118 additions and 32 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -11,4 +11,4 @@ roo-cline-*.vsix
|
|||
|
||||
# Prompts
|
||||
prompts
|
||||
|
||||
.clinerules
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ export class Cline {
|
|||
apiConfiguration: ApiConfiguration,
|
||||
customInstructions?: string,
|
||||
diffEnabled?: boolean,
|
||||
isInteractiveMode?: boolean,
|
||||
browserPort?: string,
|
||||
task?: string,
|
||||
images?: string[],
|
||||
historyItem?: HistoryItem,
|
||||
|
|
@ -108,6 +110,8 @@ export class Cline {
|
|||
this.urlContentFetcher = new UrlContentFetcher(provider.context)
|
||||
this.browserSession = new BrowserSession(provider.context)
|
||||
this.diffViewProvider = new DiffViewProvider(cwd)
|
||||
this.isInteractiveMode = isInteractiveMode ?? false
|
||||
this.browserPort = browserPort ?? "7333"
|
||||
this.customInstructions = customInstructions
|
||||
if (diffEnabled && this.api.getModel().id) {
|
||||
this.diffStrategy = getDiffStrategy(this.api.getModel().id)
|
||||
|
|
@ -633,48 +637,29 @@ export class Cline {
|
|||
if (responseImages && responseImages.length > 0) {
|
||||
newUserContent.push(...formatResponse.imageBlocks(responseImages))
|
||||
}
|
||||
const wasInteractiveBrowser = (lastRelevantMessageIndex > 0) ? modifiedClineMessages[lastRelevantMessageIndex - 1].text?.includes("interactive mode") : false
|
||||
const state = await this.providerRef.deref()?.getState()
|
||||
const wasInteractiveBrowser = state?.isInteractiveMode
|
||||
let hadBrowserPort = '';
|
||||
if ( wasInteractiveBrowser ) {
|
||||
const match = modifiedClineMessages[lastRelevantMessageIndex - 1].text?.match(/\(browserPort\s*=\s*(\d+)\)/)
|
||||
if (match) {
|
||||
hadBrowserPort = match[1] ?? this.browserPort;
|
||||
this.providerRef.deref()?.outputChannel.appendLine(`resumeTaskFromHistory :: browserPort :: ${hadBrowserPort}`)
|
||||
}
|
||||
hadBrowserPort = state?.browserPort;
|
||||
this.providerRef.deref()?.outputChannel.appendLine(`resumeTaskFromHistory :: browserPort :: ${hadBrowserPort}`)
|
||||
}
|
||||
await this.overwriteApiConversationHistory(modifiedApiConversationHistory)
|
||||
await this.initiateTaskLoop(newUserContent, wasInteractiveBrowser, hadBrowserPort)
|
||||
}
|
||||
|
||||
private async initiateTaskLoop(userContent: UserContent, wasInteractiveBrowser: boolean = false, hadBrowserPort: string = ''): Promise<void> {
|
||||
// Check if any text block contains "interactive mode"
|
||||
const hasInteractiveMode = userContent.some((block) => {
|
||||
if (block.type === "text" && typeof block.text === "string") {
|
||||
return (block.type === "text" &&
|
||||
typeof block.text === "string" &&
|
||||
block.text.toLowerCase().includes("interactive mode"))
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
) || wasInteractiveBrowser;
|
||||
const state = await this.providerRef.deref()?.getState()
|
||||
const hasInteractiveMode = state?.isInteractiveMode ?? wasInteractiveBrowser
|
||||
|
||||
|
||||
this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: hasInteractiveMode :: ${hasInteractiveMode}`)
|
||||
|
||||
// Set interactive mode flag if found in text
|
||||
if (hasInteractiveMode) {
|
||||
this.isInteractiveMode = true;
|
||||
|
||||
// Parse browserPort if specified in text blocks
|
||||
userContent.forEach((block) => {
|
||||
if (block.type === "text" && typeof block.text === "string") {
|
||||
const match = block.text.match(/\(browserPort\s*=\s*(\d+)\)/)
|
||||
if (match) {
|
||||
this.browserPort = match[1] ?? hadBrowserPort;
|
||||
this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: browserPort :: ${this.browserPort}`)
|
||||
}
|
||||
}
|
||||
})
|
||||
this.browserPort = state?.browserPort ?? hadBrowserPort
|
||||
this.providerRef.deref()?.outputChannel.appendLine(`initiateTaskLoop :: browserPort :: ${this.browserPort}`)
|
||||
}
|
||||
|
||||
let nextUserContent = userContent;
|
||||
|
|
@ -1863,12 +1848,25 @@ export class Cline {
|
|||
userContent: UserContent,
|
||||
includeFileDetails: boolean = false,
|
||||
isInteractiveMode: boolean = false,
|
||||
browserPort: string = '7333'
|
||||
browserPort?: string
|
||||
): Promise<boolean> {
|
||||
if (this.presentAssistantMessageHasPendingUpdates) {
|
||||
this.presentAssistantMessage()
|
||||
}
|
||||
|
||||
const state = await this.providerRef.deref()?.getState()
|
||||
// Use optional chaining and provide defaults
|
||||
this.isInteractiveMode = isInteractiveMode ?? state?.isInteractiveMode ?? false
|
||||
this.browserPort = browserPort ?? state?.browserPort ?? "7333"
|
||||
|
||||
// Store interactive mode state
|
||||
if (state?.isInteractiveMode !== undefined) {
|
||||
this.isInteractiveMode = state.isInteractiveMode
|
||||
}
|
||||
|
||||
if (this.abort) {
|
||||
throw new Error("Cline instance aborted")
|
||||
}
|
||||
|
||||
// Store interactive mode state
|
||||
this.isInteractiveMode = isInteractiveMode;
|
||||
|
||||
|
|
|
|||
|
|
@ -237,6 +237,8 @@ describe('Cline', () => {
|
|||
mockApiConfig,
|
||||
'custom instructions',
|
||||
false,
|
||||
true, // isInteractiveMode
|
||||
'7333', // browserPort
|
||||
'test task'
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,8 @@ type GlobalStateKey =
|
|||
| "allowedCommands"
|
||||
| "soundEnabled"
|
||||
| "diffEnabled"
|
||||
| "isInteractiveMode"
|
||||
| "browserPort"
|
||||
|
||||
export const GlobalFileNames = {
|
||||
apiConversationHistory: "api_conversation_history.json",
|
||||
|
|
@ -203,13 +205,17 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
isInteractiveMode,
|
||||
browserPort,
|
||||
} = await this.getState()
|
||||
|
||||
|
||||
this.cline = new Cline(
|
||||
this,
|
||||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
isInteractiveMode,
|
||||
browserPort,
|
||||
task,
|
||||
images
|
||||
)
|
||||
|
|
@ -221,6 +227,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
isInteractiveMode,
|
||||
browserPort,
|
||||
} = await this.getState()
|
||||
|
||||
this.cline = new Cline(
|
||||
|
|
@ -228,6 +236,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
apiConfiguration,
|
||||
customInstructions,
|
||||
diffEnabled,
|
||||
isInteractiveMode,
|
||||
browserPort,
|
||||
undefined,
|
||||
undefined,
|
||||
historyItem,
|
||||
|
|
@ -547,6 +557,14 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
await this.updateGlobalState("diffEnabled", diffEnabled)
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
case "isInteractiveMode":
|
||||
await this.updateGlobalState("isInteractiveMode", message.bool ?? false)
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
case "browserPort":
|
||||
await this.updateGlobalState("browserPort", message.text ?? "7333")
|
||||
await this.postStateToWebview()
|
||||
break
|
||||
}
|
||||
},
|
||||
null,
|
||||
|
|
@ -855,6 +873,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
soundEnabled,
|
||||
diffEnabled,
|
||||
taskHistory,
|
||||
isInteractiveMode,
|
||||
browserPort,
|
||||
} = await this.getState()
|
||||
|
||||
const allowedCommands = vscode.workspace
|
||||
|
|
@ -878,6 +898,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
diffEnabled: diffEnabled ?? false,
|
||||
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
|
||||
allowedCommands,
|
||||
isInteractiveMode: isInteractiveMode ?? false,
|
||||
browserPort: browserPort ?? "7333",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -969,6 +991,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
allowedCommands,
|
||||
soundEnabled,
|
||||
diffEnabled,
|
||||
isInteractiveMode,
|
||||
browserPort,
|
||||
] = await Promise.all([
|
||||
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
|
||||
this.getGlobalState("apiModelId") as Promise<string | undefined>,
|
||||
|
|
@ -1005,6 +1029,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
this.getGlobalState("allowedCommands") as Promise<string[] | undefined>,
|
||||
this.getGlobalState("soundEnabled") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("diffEnabled") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("isInteractiveMode") as Promise<boolean | undefined>,
|
||||
this.getGlobalState("browserPort") as Promise<string | undefined>
|
||||
])
|
||||
|
||||
let apiProvider: ApiProvider
|
||||
|
|
@ -1059,6 +1085,8 @@ export class ClineProvider implements vscode.WebviewViewProvider {
|
|||
allowedCommands,
|
||||
soundEnabled,
|
||||
diffEnabled,
|
||||
isInteractiveMode: isInteractiveMode ?? false,
|
||||
browserPort: browserPort ?? "7333"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ export class BrowserSession {
|
|||
async launchBrowser(interactive: boolean = false, port?: string) {
|
||||
console.log("launch browser called")
|
||||
this.isInteractive = interactive
|
||||
this.browserPort = port ?? this.browserPort
|
||||
|
||||
// Set browserPort if provided, otherwise use default
|
||||
if (port) {
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ export interface ExtensionState {
|
|||
allowedCommands?: string[]
|
||||
soundEnabled?: boolean
|
||||
diffEnabled?: boolean
|
||||
isInteractiveMode?: boolean
|
||||
browserPort?: string
|
||||
}
|
||||
|
||||
export interface ClineMessage {
|
||||
|
|
@ -99,6 +101,8 @@ export interface ClineSayTool {
|
|||
content?: string
|
||||
regex?: string
|
||||
filePattern?: string
|
||||
isInteractiveMode?: boolean
|
||||
browserPort?: string
|
||||
}
|
||||
|
||||
// must keep in sync with system prompt
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ export interface WebviewMessage {
|
|||
| "playSound"
|
||||
| "soundEnabled"
|
||||
| "diffEnabled"
|
||||
| "isInteractiveMode"
|
||||
| "browserPort"
|
||||
text?: string
|
||||
askResponse?: ClineAskResponse
|
||||
apiConfiguration?: ApiConfiguration
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
|
|||
openRouterModels,
|
||||
setAllowedCommands,
|
||||
allowedCommands,
|
||||
isInteractiveMode,
|
||||
setInteractiveBrowserMode,
|
||||
browserPort,
|
||||
setBrowserPort,
|
||||
} = useExtensionState()
|
||||
const [apiErrorMessage, setApiErrorMessage] = useState<string | undefined>(undefined)
|
||||
const [modelIdErrorMessage, setModelIdErrorMessage] = useState<string | undefined>(undefined)
|
||||
|
|
@ -53,6 +57,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
|
|||
vscode.postMessage({ type: "allowedCommands", commands: allowedCommands ?? [] })
|
||||
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
|
||||
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
|
||||
vscode.postMessage({ type: "isInteractiveMode", bool: isInteractiveMode })
|
||||
vscode.postMessage({ type: "browserPort", text: browserPort })
|
||||
onDone()
|
||||
}
|
||||
}
|
||||
|
|
@ -323,6 +329,45 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{ marginBottom: 5 }}>
|
||||
<h4 style={{ fontWeight: 500, marginBottom: 10 }}>Browser Settings</h4>
|
||||
|
||||
<div style={{ marginBottom: 5 }}>
|
||||
<VSCodeCheckbox
|
||||
checked={isInteractiveMode}
|
||||
onChange={(e: any) => setInteractiveBrowserMode(e.target.checked)}
|
||||
>
|
||||
<span style={{ fontWeight: "500" }}>Interactive Browser Mode</span>
|
||||
</VSCodeCheckbox>
|
||||
<p style={{
|
||||
fontSize: "12px",
|
||||
marginTop: "5px",
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
}}>
|
||||
When enabled, connects to an existing Chrome instance instead of launching a new browser.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{isInteractiveMode && (
|
||||
<div style={{ marginBottom: 5 }}>
|
||||
<VSCodeTextField
|
||||
value={browserPort}
|
||||
onInput={(e: any) => setBrowserPort(e.target.value)}
|
||||
placeholder="Browser debugging port (default: 7333)"
|
||||
>
|
||||
<span style={{ fontWeight: "500" }}>Browser Port</span>
|
||||
</VSCodeTextField>
|
||||
<p style={{
|
||||
fontSize: "12px",
|
||||
marginTop: "5px",
|
||||
color: "var(--vscode-descriptionForeground)",
|
||||
}}>
|
||||
Port number for Chrome's remote debugging. Launch Chrome with --remote-debugging-port=PORT
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{IS_DEV && (
|
||||
<>
|
||||
<div style={{ marginTop: "10px", marginBottom: "4px" }}>Debug</div>
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ export interface ExtensionStateContextType extends ExtensionState {
|
|||
setAllowedCommands: (value: string[]) => void
|
||||
setSoundEnabled: (value: boolean) => void
|
||||
setDiffEnabled: (value: boolean) => void
|
||||
setInteractiveBrowserMode: (value: boolean) => void
|
||||
setBrowserPort: (value: string) => void
|
||||
}
|
||||
|
||||
const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
|
||||
|
|
@ -40,6 +42,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
allowedCommands: [],
|
||||
soundEnabled: false,
|
||||
diffEnabled: false,
|
||||
isInteractiveMode: false,
|
||||
browserPort: "7333",
|
||||
})
|
||||
const [didHydrateState, setDidHydrateState] = useState(false)
|
||||
const [showWelcome, setShowWelcome] = useState(false)
|
||||
|
|
@ -130,6 +134,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
|
|||
setAllowedCommands: (value) => setState((prevState) => ({ ...prevState, allowedCommands: value })),
|
||||
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),
|
||||
setDiffEnabled: (value) => setState((prevState) => ({ ...prevState, diffEnabled: value })),
|
||||
setInteractiveBrowserMode: (value) => setState((prevState) => ({ ...prevState, isInteractiveMode: value })),
|
||||
setBrowserPort: (value) => setState((prevState) => ({ ...prevState, browserPort: value })),
|
||||
}
|
||||
|
||||
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue