* Stream a final text response (no tools, just summarize).
(ctx)
| 96 | * Stream a final text response (no tools, just summarize). |
| 97 | */ |
| 98 | async function streamFinalResponse(ctx) { |
| 99 | const { config, earlyStop, _fullscreenRef } = ctx; |
| 100 | const target = config.activeModelTarget || getModelTarget(config, 'default'); |
| 101 | const requestConfig = withModelTarget(config, target); |
| 102 | const baseUrl = target.baseUrl; |
| 103 | |
| 104 | const systemMsg = { role: 'system', content: 'You are SmallCode, a coding assistant. Summarize what you just did in 1-2 sentences. Be concise.' }; |
| 105 | |
| 106 | try { |
| 107 | const headers = buildAuthHeaders(requestConfig); |
| 108 | const messages = ctx.conversationHistory; |
| 109 | |
| 110 | const response = await fetch(`${baseUrl}/chat/completions`, { |
| 111 | method: 'POST', |
| 112 | headers, |
| 113 | body: JSON.stringify({ |
| 114 | model: target.model, |
| 115 | messages: [systemMsg, ...messages.slice(-6)], |
| 116 | stream: true, |
| 117 | temperature: 0.1, |
| 118 | max_tokens: 256, |
| 119 | }), |
| 120 | }); |
| 121 | |
| 122 | if (!response.ok) return null; |
| 123 | |
| 124 | const reader = response.body.getReader(); |
| 125 | const decoder = new TextDecoder(); |
| 126 | let buffer = ''; |
| 127 | let fullContent = ''; |
| 128 | |
| 129 | if (_fullscreenRef) _fullscreenRef.setStreaming(true); |
| 130 | |
| 131 | while (true) { |
| 132 | const { done, value } = await reader.read(); |
| 133 | if (done) break; |
| 134 | |
| 135 | buffer += decoder.decode(value, { stream: true }); |
| 136 | const lines = buffer.split('\n'); |
| 137 | buffer = lines.pop() || ''; |
| 138 | |
| 139 | for (const line of lines) { |
| 140 | if (!line.trim() || !line.startsWith('data: ')) continue; |
| 141 | const data = line.slice(6); |
| 142 | if (data === '[DONE]') { |
| 143 | if (_fullscreenRef) { _fullscreenRef.endStream(); _fullscreenRef.setStreaming(false); } |
| 144 | else console.log(''); |
| 145 | return fullContent; |
| 146 | } |
| 147 | try { |
| 148 | const chunk = JSON.parse(data); |
| 149 | const delta = chunk.choices?.[0]?.delta; |
| 150 | if (delta?.content) { |
| 151 | if (_fullscreenRef) _fullscreenRef.streamToken(delta.content); |
| 152 | else process.stdout.write(delta.content); |
| 153 | fullContent += delta.content; |
| 154 | |
| 155 | if (earlyStop) { |
nothing calls this directly
no test coverage detected