Streaming generation via httpx with retry on connection failure.
(prompt: str, model_id: int, think_mode: int, file_refs: list = None, extra_fields: dict = None)
| 220 | |
| 221 | |
| 222 | def generate_stream(prompt: str, model_id: int, think_mode: int, file_refs: list = None, extra_fields: dict = None): |
| 223 | """Streaming generation via httpx with retry on connection failure.""" |
| 224 | if not HAS_HTTPX: |
| 225 | text = generate(prompt, model_id, think_mode, file_refs, extra_fields) |
| 226 | if text: |
| 227 | yield text |
| 228 | return |
| 229 | |
| 230 | body = _build_payload(prompt, model_id, think_mode, file_refs, extra_fields) |
| 231 | url = _get_url() |
| 232 | headers = _build_headers() |
| 233 | client = _get_httpx_client() |
| 234 | |
| 235 | last_err = None |
| 236 | for attempt in range(CONFIG["retry_attempts"]): |
| 237 | try: |
| 238 | prev_text = "" |
| 239 | with client.stream("POST", url, content=body, headers=headers) as resp: |
| 240 | buf = "" |
| 241 | for chunk in resp.iter_text(): |
| 242 | buf += chunk |
| 243 | while "\n" in buf: |
| 244 | line, buf = buf.split("\n", 1) |
| 245 | for t in _extract_texts_from_line(line): |
| 246 | if len(t) > len(prev_text): |
| 247 | delta = clean_text(t[len(prev_text):]) |
| 248 | if delta: |
| 249 | yield delta |
| 250 | prev_text = t |
| 251 | return |
| 252 | except Exception as e: |
| 253 | last_err = e |
| 254 | if attempt < CONFIG["retry_attempts"] - 1: |
| 255 | log(f"Stream retry {attempt+1}/{CONFIG['retry_attempts']}: {e}") |
| 256 | time.sleep(CONFIG["retry_delay_sec"]) |
| 257 | raise last_err |
no test coverage detected