(task?: string, images?: string[])
| 1877 | } |
| 1878 | |
| 1879 | private async startTask(task?: string, images?: string[]): Promise<void> { |
| 1880 | try { |
| 1881 | // `conversationHistory` (for API) and `clineMessages` (for webview) |
| 1882 | // need to be in sync. |
| 1883 | // If the extension process were killed, then on restart the |
| 1884 | // `clineMessages` might not be empty, so we need to set it to [] when |
| 1885 | // we create a new Cline client (otherwise webview would show stale |
| 1886 | // messages from previous session). |
| 1887 | this.clineMessages = [] |
| 1888 | this.apiConversationHistory = [] |
| 1889 | |
| 1890 | // The todo list is already set in the constructor if initialTodos were provided |
| 1891 | // No need to add any messages - the todoList property is already set |
| 1892 | |
| 1893 | await this.providerRef.deref()?.postStateToWebviewWithoutTaskHistory() |
| 1894 | |
| 1895 | await this.say("text", task, images) |
| 1896 | |
| 1897 | // Check for too many MCP tools and warn the user |
| 1898 | const { enabledToolCount, enabledServerCount } = await this.getEnabledMcpToolsCount() |
| 1899 | if (enabledToolCount > MAX_MCP_TOOLS_THRESHOLD) { |
| 1900 | await this.say( |
| 1901 | "too_many_tools_warning", |
| 1902 | JSON.stringify({ |
| 1903 | toolCount: enabledToolCount, |
| 1904 | serverCount: enabledServerCount, |
| 1905 | threshold: MAX_MCP_TOOLS_THRESHOLD, |
| 1906 | }), |
| 1907 | undefined, |
| 1908 | undefined, |
| 1909 | undefined, |
| 1910 | undefined, |
| 1911 | { isNonInteractive: true }, |
| 1912 | ) |
| 1913 | } |
| 1914 | this.isInitialized = true |
| 1915 | |
| 1916 | const imageBlocks: Anthropic.ImageBlockParam[] = formatResponse.imageBlocks(images) |
| 1917 | |
| 1918 | // Task starting |
| 1919 | await this.initiateTaskLoop([ |
| 1920 | { |
| 1921 | type: "text", |
| 1922 | text: `<user_message>\n${task}\n</user_message>`, |
| 1923 | }, |
| 1924 | ...imageBlocks, |
| 1925 | ]).catch((error) => { |
| 1926 | // Swallow loop rejection when the task was intentionally abandoned/aborted |
| 1927 | // during delegation or user cancellation to prevent unhandled rejections. |
| 1928 | if (this.abandoned === true || this.abortReason === "user_cancelled") { |
| 1929 | return |
| 1930 | } |
| 1931 | throw error |
| 1932 | }) |
| 1933 | } catch (error) { |
| 1934 | // In tests and some UX flows, tasks can be aborted while `startTask` is still |
| 1935 | // initializing. Treat abort/abandon as expected and avoid unhandled rejections. |
| 1936 | if (this.abandoned === true || this.abort === true || this.abortReason === "user_cancelled") { |
no test coverage detected