* Creates a streaming API request * @param apiConversationHistory - Conversation history * @param abortController - Optional abort signal for cancelling requests * @returns AsyncGenerator yielding SSE responses
(
apiConversationHistory: ApiHistoryItem[],
abortController: AbortController,
customSystemPrompt?: {
automaticReminders?: string
systemPrompt?: string | []
customInstructions?: string
useExistingSystemPrompt?: (systemPrompt: string[]) => string[]
},
skipProcessing = false,
postProcessConversationCallback?: (apiConversationHistory: ApiHistoryItem[]) => Promise<void>
)
| 104 | * @returns AsyncGenerator yielding SSE responses |
| 105 | */ |
| 106 | async *createApiStreamRequest( |
| 107 | apiConversationHistory: ApiHistoryItem[], |
| 108 | abortController: AbortController, |
| 109 | customSystemPrompt?: { |
| 110 | automaticReminders?: string |
| 111 | systemPrompt?: string | [] |
| 112 | customInstructions?: string |
| 113 | useExistingSystemPrompt?: (systemPrompt: string[]) => string[] |
| 114 | }, |
| 115 | skipProcessing = false, |
| 116 | postProcessConversationCallback?: (apiConversationHistory: ApiHistoryItem[]) => Promise<void> |
| 117 | ): AsyncGenerator<koduSSEResponse> { |
| 118 | const provider = this.providerRef.deref() |
| 119 | if (!provider || !provider.koduDev) { |
| 120 | throw new Error("Provider reference has been garbage collected") |
| 121 | } |
| 122 | // first pull latest api settings |
| 123 | await this.pullLatestApi() |
| 124 | |
| 125 | const executeRequest = async ({ shouldResetContext }: { shouldResetContext: boolean }) => { |
| 126 | let conversationHistory = |
| 127 | apiConversationHistory ?? |
| 128 | (await provider.koduDev?.getStateManager().apiHistoryManager.getSavedApiConversationHistory()) |
| 129 | |
| 130 | let baseSystem = [await this.getCurrentPrompts()] |
| 131 | if (customSystemPrompt?.systemPrompt) { |
| 132 | if (Array.isArray(customSystemPrompt.systemPrompt)) { |
| 133 | baseSystem = customSystemPrompt.systemPrompt |
| 134 | } else { |
| 135 | baseSystem = [customSystemPrompt.systemPrompt] |
| 136 | } |
| 137 | } |
| 138 | if (this.getModelId() === "claude-3-7-sonnet-20250219") { |
| 139 | const globalStateManager = GlobalStateManager.getInstance() |
| 140 | const thinking = globalStateManager.getGlobalState("thinking") |
| 141 | // we are going to add more critical instructions to the system prompt |
| 142 | if (thinking?.type === "enabled") { |
| 143 | baseSystem.push(`<critical_instructions> |
| 144 | In every message output you should document your current step, finalized reasoning and thoughts, your next steps, and any other relevant information. |
| 145 | This must be present in every message and should be concise and to the point. |
| 146 | You don't need to write <thinking> tags. instead you should write <thinking_summary> and <execution_plan> tags in every message. |
| 147 | so format every response as following: |
| 148 | <thinking_summary> |
| 149 | A summary of your current thoughts, reasoning, and next steps. |
| 150 | </thinking_summary> |
| 151 | <execution_plan> |
| 152 | Your plan of execution, what you are going to do next, and how you are going to do it. |
| 153 | </execution_plan> |
| 154 | <kodu_action>...the best tool call for this step...</kodu_action> |
| 155 | </critical_instructions>`) |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | let criticalMsg: string | undefined = mainPrompts.criticalMsg |
| 160 | if (customSystemPrompt) { |
| 161 | criticalMsg = customSystemPrompt.automaticReminders |
| 162 | } |
| 163 | // we want to replace {{task}} with the current task if it exists in the critical message |
no test coverage detected