MCPcopy Create free account
hub / github.com/OpenRaiser/PaperFlow / answer_question_stream

Function answer_question_stream

agents/wiki-agent/retrieve/answer.py:256–318  ·  view source on GitHub ↗

Yield answer events with local citations and provider-native chunks.

(
    user_id: str,
    question: str,
    *,
    limit: int = 8,
    pinned_nodes: Optional[List[Dict[str, Any]]] = None,
    allowed_node_ids: Optional[Iterable[str]] = None,
    response_language: str = "zh",
)

Source from the content-addressed store, hash-verified

254
255
256def answer_question_stream(
257 user_id: str,
258 question: str,
259 *,
260 limit: int = 8,
261 pinned_nodes: Optional[List[Dict[str, Any]]] = None,
262 allowed_node_ids: Optional[Iterable[str]] = None,
263 response_language: str = "zh",
264) -> Iterator[Dict[str, Any]]:
265 """Yield answer events with local citations and provider-native chunks."""
266 language = _normalize_response_language(response_language)
267 started = time.time()
268 hits, embedding_error = _prepare_hits(user_id, question, limit, pinned_nodes, allowed_node_ids=allowed_node_ids)
269 if not hits:
270 result = _empty_answer(started, response_language=language)
271 yield {"event": "meta", "data": {key: value for key, value in result.items() if key != "text"}}
272 yield {"event": "chunk", "data": {"text": result["text"]}}
273 yield {"event": "done", "data": result}
274 return
275
276 citations = _build_citations(user_id, hits)
277 llm = build_llm_provider()
278 prompt = _build_prompt(question, hits)
279 llm_error = None
280 text_parts: List[str] = []
281 meta = {
282 "citations": citations,
283 "elapsed_ms": 0,
284 "response_language": language,
285 "token_usage": _token_usage(llm, None, embedding_error, None),
286 "streaming": {"provider": True, "transport": "sse"},
287 }
288 yield {"event": "meta", "data": meta}
289 try:
290 for chunk in llm.stream_generate(prompt, system=_system_prompt(language), temperature=0.0, max_tokens=_answer_max_tokens()):
291 if not chunk:
292 continue
293 text_parts.append(chunk)
294 yield {"event": "chunk", "data": {"text": chunk}}
295 except Exception as exc:
296 llm_error = str(exc)
297 fallback = _extractive_fallback(hits, llm_error, response_language=language)
298 text_parts = [fallback]
299 yield {"event": "chunk", "data": {"text": fallback}}
300
301 answer_text = "".join(text_parts)
302 response = None
303 if llm_error is None and _looks_incomplete_answer(answer_text):
304 try:
305 response = llm.generate(prompt, system=_system_prompt(language), temperature=0.0, max_tokens=_answer_max_tokens())
306 if response.text and len(response.text.strip()) > len(answer_text.strip()):
307 answer_text = response.text
308 except Exception as exc:
309 llm_error = f"incomplete stream fallback failed: {exc}"
310
311 result = {
312 "text": answer_text,
313 "citations": citations,

Callers

nothing calls this directly

Calls 13

build_llm_providerFunction · 0.90
_prepare_hitsFunction · 0.85
_empty_answerFunction · 0.85
_build_citationsFunction · 0.85
_build_promptFunction · 0.85
_token_usageFunction · 0.85
_system_promptFunction · 0.85
_answer_max_tokensFunction · 0.85
_extractive_fallbackFunction · 0.85
_looks_incomplete_answerFunction · 0.85
stream_generateMethod · 0.45

Tested by

no test coverage detected