payload = {
"chat_session_id": chat_session_id,
"parent_message_id": None,
"message": "What is Onyx?",
"file_descriptors": [],
"search_doc_ids": [],
"retrieval_options": {}
}
# Consume the streamed packets fully and then print a summary
# NOTE: The first packet always contains message IDs:
# {"user_message_id": int, "reserved_assistant_message_id": int}
with requests.post(
f"{API_BASE_URL}/chat/send-message",
headers=headers,
json=payload,
stream=True,
) as resp:
resp.raise_for_status()
full_text = []
docs_raw = None
citations_map = {}
user_message_id = None
reserved_assistant_message_id = None
# Each line is a JSON Packet: { ind: int, obj: { type: "...", ... } }
for line in resp.iter_lines(decode_unicode=True):
if not line:
continue
try:
packet = json.loads(line)
except Exception:
continue
# First packet: message IDs
if "user_message_id" in packet and "reserved_assistant_message_id" in packet:
user_message_id = packet.get("user_message_id")
reserved_assistant_message_id = packet.get("reserved_assistant_message_id")
continue
obj = packet.get("obj", {})
ptype = obj.get("type")
if ptype == "message_start":
# Includes final search documents per API spec
docs_raw = obj.get("final_documents") or docs_raw
elif ptype == "message_delta":
delta = obj.get("content", "")
full_text.append(delta)
elif ptype == "citation_delta":
# Update citation map using citation_num -> document_id pairs
if isinstance(obj.get("citations"), list):
for c in obj["citations"]:
cnum = c.get("citation_num")
did = c.get("document_id")
if cnum is not None and did is not None:
citations_map[str(cnum)] = str(did)
elif ptype == "stop":
break
# Prepare documents (id/title/link) if present
top_documents = []
if isinstance(docs_raw, list):
for d in docs_raw:
top_documents.append(
{
"id": d.get("document_id") or d.get("id"),
"title": d.get("semantic_identifier") or d.get("title"),
"link": d.get("link") or d.get("url"),
}
)
print("Final Answer:\n" + "".join(full_text))
if user_message_id is not None:
print(f"\nUser message ID: {user_message_id}")
if reserved_assistant_message_id is not None:
print(f"Reserved assistant message ID: {reserved_assistant_message_id}")
print("\nTop Documents:")
print(json.dumps(top_documents, indent=2))
print("\nCitations map (citation_num -> document_id):")
print(json.dumps(citations_map, indent=2))