MCPcopy Create free account
hub / github.com/InferCore/InferCore / invokeStream

Method invokeStream

internal/adapters/gemini/gemini.go:195–342  ·  view source on GitHub ↗
(ctx context.Context, text, model string)

Source from the content-addressed store, hash-verified

193}
194
195func (a *Adapter) invokeStream(ctx context.Context, text, model string) (types.BackendResponse, error) {
196 t0 := time.Now()
197 payload := map[string]any{
198 "contents": []map[string]any{
199 {
200 "role": "user",
201 "parts": []map[string]string{{"text": text}},
202 },
203 },
204 }
205 raw, err := json.Marshal(payload)
206 if err != nil {
207 return types.BackendResponse{}, err
208 }
209 url := a.baseURL + a.actionPath(model, "streamGenerateContent") + "?alt=sse"
210 httpReq, err := http.NewRequestWithContext(ctx, http.MethodPost, url, bytes.NewReader(raw))
211 if err != nil {
212 return types.BackendResponse{}, err
213 }
214 httpReq.Header.Set("Content-Type", "application/json")
215 a.applyAPIKey(httpReq)
216 a.applyExtraHeaders(httpReq)
217
218 resp, err := a.httpClient.Do(httpReq)
219 if err != nil {
220 if errors.Is(err, context.DeadlineExceeded) {
221 return types.BackendResponse{}, upstream.New(upstream.KindTimeout, err.Error())
222 }
223 return types.BackendResponse{}, err
224 }
225 defer resp.Body.Close()
226 if resp.StatusCode < 200 || resp.StatusCode >= 300 {
227 if resp.StatusCode >= 500 {
228 return types.BackendResponse{}, upstream.New(upstream.KindUpstream5xx, fmt.Sprintf("gemini stream failed status=%d", resp.StatusCode))
229 }
230 return types.BackendResponse{}, upstream.New(upstream.KindUpstream4xx, fmt.Sprintf("gemini stream failed status=%d", resp.StatusCode))
231 }
232
233 ct := strings.ToLower(resp.Header.Get("Content-Type"))
234 if !strings.Contains(ct, "event-stream") && !strings.Contains(ct, "text/plain") {
235 // Fall back to single JSON body (non-SSE).
236 var parsed geminiGenerateResponse
237 if err := json.NewDecoder(resp.Body).Decode(&parsed); err != nil {
238 return types.BackendResponse{}, upstream.New(upstream.KindBackendError, err.Error())
239 }
240 out := geminiCandidatesText(parsed.Candidates)
241 t1 := time.Now()
242 lat := t1.Sub(t0).Milliseconds()
243 return types.BackendResponse{
244 Output: map[string]any{
245 "text": out,
246 "backend": a.cfg.Name,
247 "stream_requested": true,
248 "stream_degraded": true,
249 },
250 Timing: &types.BackendTiming{
251 TTFTMs: lat,
252 CompletionLatencyMs: lat,

Callers 1

InvokeMethod · 0.95

Calls 7

actionPathMethod · 0.95
applyAPIKeyMethod · 0.95
applyExtraHeadersMethod · 0.95
NewFunction · 0.92
geminiCandidatesTextFunction · 0.85
CloseMethod · 0.65
ErrorMethod · 0.45

Tested by

no test coverage detected