diff --git a/src/core/webview/messageHandlers/handleClearTask.ts b/src/core/webview/messageHandlers/handleClearTask.ts new file mode 100644 index 0000000000..9cd7b5c3d6 --- /dev/null +++ b/src/core/webview/messageHandlers/handleClearTask.ts @@ -0,0 +1,12 @@ +import { ClineProvider } from "../ClineProvider" +import { WebviewMessage } from "../../../shared/WebviewMessage" +import { t } from "../../../i18n" + +export async function handleClearTask( + provider: ClineProvider, + _message: WebviewMessage & { type: "clearTask" }, +): Promise { + // clear task resets the current session and allows for a new task to be started, if this session is a subtask - it allows the parent task to be resumed + await provider.finishSubTask(t("common:tasks.canceled")) + await provider.postStateToWebview() +} diff --git a/src/core/webview/messageHandlers/handleCustomInstructions.ts b/src/core/webview/messageHandlers/handleCustomInstructions.ts new file mode 100644 index 0000000000..1198c16099 --- /dev/null +++ b/src/core/webview/messageHandlers/handleCustomInstructions.ts @@ -0,0 +1,9 @@ +import { ClineProvider } from "../ClineProvider" +import { WebviewMessage } from "../../../shared/WebviewMessage" + +export async function handleCustomInstructions( + provider: ClineProvider, + message: WebviewMessage & { type: "customInstructions" }, +): Promise { + await provider.updateCustomInstructions(message.text) +} diff --git a/src/core/webview/messageHandlers/handleNewTask.ts b/src/core/webview/messageHandlers/handleNewTask.ts new file mode 100644 index 0000000000..2881cc0bc2 --- /dev/null +++ b/src/core/webview/messageHandlers/handleNewTask.ts @@ -0,0 +1,12 @@ +import { ClineProvider } from "../ClineProvider" +import { WebviewMessage } from "../../../shared/WebviewMessage" + +export async function handleNewTask( + provider: ClineProvider, + message: WebviewMessage & { type: "newTask" }, +): Promise { + // Initializing new instance of Cline will make sure that any + // agentically running promises in old instance don't affect our new + // task. This essentially creates a fresh slate for the new task. + await provider.initClineWithTask(message.text, message.images) +} diff --git a/src/core/webview/messageHandlers/handleSelectImages.ts b/src/core/webview/messageHandlers/handleSelectImages.ts new file mode 100644 index 0000000000..f4f9c383ab --- /dev/null +++ b/src/core/webview/messageHandlers/handleSelectImages.ts @@ -0,0 +1,11 @@ +import { ClineProvider } from "../ClineProvider" +import { WebviewMessage } from "../../../shared/WebviewMessage" +import { selectImages } from "../../../integrations/misc/process-images" + +export async function handleSelectImages( + provider: ClineProvider, + _message: WebviewMessage & { type: "selectImages" }, +): Promise { + const images = await selectImages() + await provider.postMessageToWebview({ type: "selectedImages", images }) +} diff --git a/src/core/webview/messageHandlers/requestProviderModelsHandler.ts b/src/core/webview/messageHandlers/requestProviderModelsHandler.ts new file mode 100644 index 0000000000..3508666b4a --- /dev/null +++ b/src/core/webview/messageHandlers/requestProviderModelsHandler.ts @@ -0,0 +1,52 @@ +import { ClineProvider } from "../ClineProvider" +import { WebviewMessage } from "../../../shared/WebviewMessage" +import { GetModelsOptions, ModelRecord, RouterName } from "../../../shared/api" +import { flushModels, getModels } from "../../../api/providers/fetchers/modelCache" + +export async function handleRequestProviderModels( + provider: ClineProvider, + message: WebviewMessage & { type: "requestProviderModels" }, +): Promise { + const optionsFromPayload = message.payload as any // Check payload structure first + + if ( + typeof optionsFromPayload !== "object" || + optionsFromPayload === null || + typeof optionsFromPayload.provider !== "string" || + !optionsFromPayload.provider + ) { + const providerNameForError = + typeof optionsFromPayload?.provider === "string" && optionsFromPayload.provider + ? (optionsFromPayload.provider as RouterName) + : ("unknown" as RouterName) + + provider.postMessageToWebview({ + type: "providerModelsResponse", + payload: { + provider: providerNameForError, + error: "Invalid payload for requestProviderModels: payload must be an object with a valid 'provider' string property.", + }, + }) + return + } + + const options = optionsFromPayload as GetModelsOptions // Now cast to GetModelsOptions + + let models: ModelRecord = {} + let error: string | undefined + + try { + await flushModels(options.provider) + models = await getModels(options) + } catch (e: any) { + error = + e.message || + `Failed to fetch models in webviewMessageHandler requestProviderModels for ${options.provider}. Check console for details.` + models = {} + } + + provider.postMessageToWebview({ + type: "providerModelsResponse", + payload: { provider: options.provider, models, error }, + }) +} diff --git a/src/core/webview/webviewMessageHandler.ts b/src/core/webview/webviewMessageHandler.ts index e2259b5866..3e7249d376 100644 --- a/src/core/webview/webviewMessageHandler.ts +++ b/src/core/webview/webviewMessageHandler.ts @@ -37,6 +37,7 @@ import { GlobalState } from "../../schemas" import { flushModels, getModels } from "../../api/providers/fetchers/modelCache" import { GetModelsOptions } from "../../shared/api" import { generateSystemPrompt } from "./generateSystemPrompt" +import { handleRequestProviderModels } from "./messageHandlers/requestProviderModelsHandler" const ALLOWED_VSCODE_SETTINGS = new Set(["terminal.integrated.inheritEnv"]) @@ -278,48 +279,7 @@ export const webviewMessageHandler = async (provider: ClineProvider, message: We await flushModels(routerNameFlush) break case "requestProviderModels": { - const optionsFromPayload = message.payload as any // Check payload structure first - - if ( - typeof optionsFromPayload !== "object" || - optionsFromPayload === null || - typeof optionsFromPayload.provider !== "string" || - !optionsFromPayload.provider - ) { - const providerNameForError = - typeof optionsFromPayload?.provider === "string" && optionsFromPayload.provider - ? (optionsFromPayload.provider as RouterName) - : ("unknown" as RouterName) - - provider.postMessageToWebview({ - type: "providerModelsResponse", - payload: { - provider: providerNameForError, - error: "Invalid payload for requestProviderModels: payload must be an object with a valid 'provider' string property.", - }, - }) - break - } - - const options = optionsFromPayload as GetModelsOptions // Now cast to GetModelsOptions - - let models: ModelRecord = {} - let error: string | undefined - - try { - await flushModels(options.provider) - models = await getModels(options) - } catch (e: any) { - error = - e.message || - `Failed to fetch models in webviewMessageHandler requestProviderModels for ${options.provider}. Check console for details.` - models = {} - } - - provider.postMessageToWebview({ - type: "providerModelsResponse", - payload: { provider: options.provider, models, error }, - }) + await handleRequestProviderModels(provider, message as WebviewMessage & { type: "requestProviderModels" }) break } case "requestRouterModels":