Fluens
Pone stream ad true et responsio ut server-sent events advenit dum modellum eam scribit: primum ratiocinatio, deinde responsio, deinde ultimus chunk cum causa finis et usage. Utere eo quotiens persona textum exspectat, et pro responsionibus longis.
POST https://api.shannon-ai.com/v1/chat/completions
SDK OpenAI chunks singulos tibi dant. Lege quemque chunk per id quod fert: partem ratiocinationis, partem responsionis, vocationem tool, aut finem responsionis.
from openai import OpenAI, APIError
client = OpenAI(
api_key="YOUR_API_KEY",
base_url="https://api.shannon-ai.com/v1",
)
stream = client.chat.completions.create(
model="shannon-3",
messages=[{"role": "user", "content": "Explain server-sent events in three sentences."}],
stream=True,
)
answer, reasoning, tool_calls = [], [], []
finish_reason = usage = None
try:
for chunk in stream:
if chunk.usage:
usage = chunk.usage
if not chunk.choices:
continue
choice = chunk.choices[0]
delta = choice.delta
thought = getattr(delta, "reasoning_content", None)
if thought:
reasoning.append(thought)
if delta.content:
answer.append(delta.content)
print(delta.content, end="", flush=True)
for call in delta.tool_calls or []:
tool_calls.append((call.id, call.function.name, call.function.arguments))
if choice.finish_reason:
finish_reason = choice.finish_reason
except APIError as error:
# A failure after the stream started arrives as an error chunk.
print(f"\nstream failed: {error}")
print(f"\n{finish_reason} {usage}") import OpenAI from "openai";
const client = new OpenAI({
apiKey: "YOUR_API_KEY",
baseURL: "https://api.shannon-ai.com/v1",
});
const stream = await client.chat.completions.create({
model: "shannon-3",
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
stream: true,
});
let answer = "";
let reasoning = "";
const toolCalls = [];
let finishReason = null;
let usage = null;
try {
for await (const chunk of stream) {
if (chunk.usage) usage = chunk.usage;
const choice = chunk.choices?.[0];
if (!choice) continue;
const delta = choice.delta;
if (delta.reasoning_content) reasoning += delta.reasoning_content;
if (delta.content) {
answer += delta.content;
process.stdout.write(delta.content);
}
for (const call of delta.tool_calls ?? []) {
toolCalls.push({ id: call.id, name: call.function.name, arguments: call.function.arguments });
}
if (choice.finish_reason) finishReason = choice.finish_reason;
}
} catch (error) {
// A failure after the stream started arrives as an error chunk.
console.error("\nstream failed:", error.message);
}
console.log("\n", finishReason, usage); curl -N https://api.shannon-ai.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "shannon-3",
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}],
"stream": true
}' Quomodo stream formetur
- Responsio statum
200et headerscontent-type: text/event-streametcache-control: no-cachehabet. - Quisque eventus est una linea quae cum
data:incipit et quam linea vacua sequitur. Textus postdata:est unus chunk JSON. Nullae lineaeevent:velid:sunt. - Linea quae a colon incipit, ut
: ping, est commentarium quod connexionem apertam servat. Praetere eam. - Stream cum
data: [DONE]finit. Stream qui sine eo desinit incompletus est.
Chunks ordine
Quisque chunk est objectum chat.completion.chunk:
{
"id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "chat.completion.chunk",
"created": 1791625200,
"model": "shannon-3",
"choices": [
{
"index": 0,
"delta": {
"content": "Server-sent"
},
"finish_reason": null
}
]
} Omnes chunks unius streami eadem id, created et model ferunt. choices semper unam inscriptionem tenet. Eius delta quod novum est tenet, et finish_reason est null usque ad ultimum chunk.
| Clavis in delta | Genus | Descriptio | Missum a |
|---|---|---|---|
role | string | Semper assistant. Semel advenit, in initio streami. | Modelli open-weight hosted, shannon-2-lite, shannon-2-pro |
reasoning_content | string | Pars ratiocinationis modelli. Partes ordine iunge. | Modelli open-weight hosted, familia Shannon 3, shannon-1.6-pro, shannon-coder-1 |
content | string | Pars responsionis. Partes ordine iunge. | Omnia modelli |
tool_calls | array | Una vocatio tool completa. Vide Tool call deltas. | Omnia modelli |
Ratiocinatio primum venit, deinde responsio, deinde vocationes tool. Lege chunk per claves in eius delta, non per locum eius in stream: delta role una cum prima parte textus tenere potest, et ultimum vacuum est.
Totus stream ut it. Ut lineae breves maneant, id, object, created et model hic ex quoque chunk omittuntur.
data: {"choices":[{"index":0,"delta":{"reasoning_content":"Three sentences:"},"finish_reason":null}]}
data: {"choices":[{"index":0,"delta":{"reasoning_content":" what it is, how it is framed, why it is used."},"finish_reason":null}]}
: ping
data: {"choices":[{"index":0,"delta":{"content":"Server-sent"},"finish_reason":null}]}
data: {"choices":[{"index":0,"delta":{"content":" events let a server push text to a client over one HTTP reply."},"finish_reason":null}]}
data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":1190,"completion_tokens":84,"total_tokens":1274}}
data: [DONE] Deltas ratiocinationis
Modellum quod ratiocinatur ratiocinationem suam in delta.reasoning_content ante responsionem mittit. Duos textus separatos serva: ostende ratiocinationem ut partem separatam et plicabilem, aut omitte eam.
Modelli open-weight hosted nullam ratiocinationem mittunt cum reasoning_effort est off, et nullam cum petitio response_format habet.
shannon-2-lite et shannon-2-pro etiam ratiocinantur antequam respondent. In hoc endpoint lineas commentarii : thinking mittunt dum id faciunt, deinde responsionem.
reasoning_content in modellis typatis SDK OpenAI non est. In Python lege eum cum getattr(delta, "reasoning_content", None); in JavaScript delta.reasoning_content ut est operatur.
Tool call deltas
Vocatio tool tota advenit: unus chunk per vocationem, cuius delta vocationem cum toto string arguments tenet. index vocationes responsionis a 0 numerat. Codex qui arguments frustatim iungit sine mutatione operatur, quia unam partem iungit.
{
"tool_calls": [
{
"index": 0,
"id": "call_3d9a7c1e5b2f4a60c8e1d7f09b24a6c5",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\":\"Paris\"}"
}
}
]
} Post vocationes, ultimus chunk finish_reason tool_calls habet.
Cum petitio tools habet, shannon-1.6-lite, shannon-1.6-pro et shannon-coder-1 textum responsionis ut unum delta in fine responsionis mittunt.
Ultimus chunk
Ultimus chunk ante data: [DONE] delta vacuum, finish_reason et usage petitionis habet, omnia in eodem chunk. Omnis stream eum habet; stream_options non requiris.
{
"id": "chatcmpl-5f0c1e7a9b3d4c62a8e1f07d2b46c9a3",
"object": "chat.completion.chunk",
"created": 1791625200,
"model": "shannon-3",
"choices": [
{
"index": 0,
"delta": {},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 1190,
"completion_tokens": 84,
"total_tokens": 1274
}
} In modellis open-weight hosted usage etiam prompt_tokens_details.cached_tokens et completion_tokens_details.reasoning_tokens habet.
Post petitionem cum web_search: true cuius quaestus aliquid invenit, ultimus chunk etiam sources fert, et unus chunk ante eum notas citationum ut delta.annotations fert. Quaestus interretialis
| finish_reason | Descriptio | Missum a |
|---|---|---|
stop | Modellum responsionem suam finivit, aut string stop apparuit. | Omnia modelli |
tool_calls | Responsio unam vel plures vocationes tool tenet. | Omnia modelli |
length | Responsio ad limitem outputi abscisa est. | Familia Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 |
Campi usage cum endpoint describuntur. Chat Completions
Lineae keep-alive
Dum modellum laborat et nihil adhuc mittendum habet, stream lineas commentarii fert. Nulla data tenent. Parser SSE eas per se praeterit; codex qui lineas crudas legit omnem lineam quae a colon incipit praeterire debet.
| Linea | Missum a | Quando |
|---|---|---|
: ping | Familia Shannon 3, shannon-1.6-lite, shannon-1.6-pro, shannon-coder-1 | Omnibus 15 secundis. |
: keepalive | Modelli open-weight hosted | Omnibus 15 secundis dum modellum laborat. |
: thinking | shannon-2-lite, shannon-2-pro | Dum modellum ratiocinatur. |
Errores intra stream
Postquam stream incepit, status eius est 200, itaque defectus intra stream advenit: chunk cum membro error ubi choices esset.
data: {"error":{"message":"The model backend failed to answer. Please retry.","type":"api_error","code":null,"param":null}}
data: {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":1190,"completion_tokens":12,"total_tokens":1202}}
data: [DONE] Post chunk erroris ultimus chunk, cum finish_reason et usage, et data: [DONE] adhuc sequuntur. Inspice omnem chunk pro error. Sine hac inspectione responsio quae in medio defecit completa videtur.
| Type | Code | Nuntius | Quando |
|---|---|---|---|
api_error | The model backend failed to answer. Please retry. | Modellum defecit, aut nihil scripsit. Mitte petitionem iterum. | |
rate_limit_error | Shannon routes are temporarily busy. Please retry. | Modellum hoc momento occupatum est. Exspecta paucas secundas et mitte petitionem iterum. | |
invalid_request_error | context_length_exceeded | Conversatio longior est quam context window modelli. Eam contrahe antequam iterum mittis. Textus nuntii variat. |
Modelli open-weight hosted membrum error cum type et message tantum mittunt.
SDK OpenAI Python et JavaScript chunk erroris ut errorem API excitant dum iteras, itaque circulum in tractatione errorum tua solita involve.
Codices status, corpus erroris et quid iterandum sit paginam propriam habent. Tractatio errorum
Connexionem claudere
Connexionem claudere traditionem sistit, non petitionem. Modellum responsionem ad finem scribit et petitio computatur ac si totam legisses. Ut minus solvas, minus pete: pone max_tokens inferiorem in modello quod eum applicat.
Stream etiam in via ad te mature finire potest, exempli gratia in ruptura retis aut dum servientis renovatur. Tunc sine ultimo chunk et sine data: [DONE] desinit. Illam responsionem ut incompletam tracta et mitte petitionem iterum.
Stream sine SDK legere
Lector rectus quinque facit: errores qui ante stream adveniunt ad tractationem errorum suam mittit, corpus in lineas dividit, lineas commentarii praeterit, ad data: [DONE] sistit, et quemque chunk pro error inspicit.
import json
import requests
response = requests.post(
"https://api.shannon-ai.com/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "shannon-3",
"messages": [{"role": "user", "content": "Explain server-sent events in three sentences."}],
"stream": True,
},
stream=True,
)
# 1. Errors before the stream are plain JSON with their own status.
if response.status_code != 200:
raise RuntimeError(f"{response.status_code}: {response.text}")
answer, done = [], False
for raw in response.iter_lines(): # 2. one line at a time
line = raw.decode("utf-8")
if not line.startswith("data: "): # 3. empty lines and ": ping" comments
continue
data = line[len("data: "):]
if data == "[DONE]": # 4. the end of the stream
done = True
break
chunk = json.loads(data)
if "error" in chunk: # 5. a failure inside the stream
raise RuntimeError(chunk["error"]["message"])
delta = chunk["choices"][0]["delta"]
if delta.get("content"):
answer.append(delta["content"])
if chunk.get("usage"):
print(chunk["choices"][0]["finish_reason"], chunk["usage"])
if not done:
raise RuntimeError("the stream ended before [DONE]")
print("".join(answer)) const response = await fetch("https://api.shannon-ai.com/v1/chat/completions", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "shannon-3",
messages: [{ role: "user", content: "Explain server-sent events in three sentences." }],
stream: true,
}),
});
// 1. Errors before the stream are plain JSON with their own status.
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
const decoder = new TextDecoder();
let buffer = "";
let answer = "";
let done = false;
read: for await (const bytes of response.body) {
buffer += decoder.decode(bytes, { stream: true });
const lines = buffer.split("\n"); // 2. one line at a time
buffer = lines.pop(); // keep the unfinished line
for (const line of lines) {
if (!line.startsWith("data: ")) continue; // 3. empty lines and ": ping" comments
const data = line.slice(6);
if (data === "[DONE]") { // 4. the end of the stream
done = true;
break read;
}
const chunk = JSON.parse(data);
if (chunk.error) throw new Error(chunk.error.message); // 5. a failure inside the stream
const choice = chunk.choices[0];
if (choice.delta.content) answer += choice.delta.content;
if (chunk.usage) console.log(choice.finish_reason, chunk.usage);
}
}
if (!done) throw new Error("the stream ended before [DONE]");
console.log(answer); Exemplum Python bibliotheca requests utitur. Exemplum JavaScript in Node.js 18 vel recentiore currit.
Streams aliarum formarum
Endpoints Responses et Messages etiam streamantur. Frames eorum lineam event: cum nomine eventus et lineam data: cum JSON eius ferunt. Quaeque pagina eventus suos ordine enumerat.
| In stream | Chat Completions | Responses | Messages |
|---|---|---|---|
| Frames | Lineae data: | Lineae event: et data: | Lineae event: et data: |
| Ratiocinatio advenit in | delta.reasoning_content | response.reasoning_summary_text.delta | thinking_delta |
| Textus responsionis advenit in | delta.content | response.output_text.delta | text_delta |
| Usage advenit in | Ultimus chunk | response.completed | message_delta |
| Stream finit cum | Ultimus chunk, deinde data: [DONE] | response.completed | message_stop |