Chat completions endpoint
Super Decider also answers through the OpenAI-compatible chat completions endpoint, so you can call it from an existing OpenAI client. It makes the same decisions as /v1/systemone; only the request shape differs.
POST https://inference.asicloud.cudos.org/v1/chat/completions
Messages​
Send exactly two messages:
| Role | Content |
|---|---|
system | The question schema, as a JSON string. |
user | The state, as a JSON string. A plain string must be JSON-encoded too, for example with json.dumps. Raw text returns 400. For images, see below. |
Question schema​
{"questions": [
{"id": "next_step", "type": "choice", "instructions": "What should support do next?",
"options": [{"name": "refund_now", "description": "Refund without a return"},
{"name": "start_return", "description": "Start a return"},
{"name": "escalate", "description": "Hand over to a human"}]},
{"id": "allowed", "type": "noul", "instructions": "Is cancelling this order allowed by the policy?"},
{"id": "urgency", "type": "score", "instructions": "How urgent is this ticket?",
"levels": ["low", "medium", "high"]}
]}
Compared with /v1/systemone:
questionsis an array, and each question carries its ownid.- A choice lists its options in
options, each with anameand an optionaldescription. - A score lists its levels in
levels. - A span puts
max_tokensandmax_itemsdirectly on the question. - The request's
thinkingfield is ignored. Control thinking with schema keys:"adaptive": falsefor no thought, or"think": 512for a thought of up to 512 tokens on every question. See Thinking.
{"think": 512, "questions": [...]}
Example​
- Python
- cURL
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://inference.asicloud.cudos.org/v1",
api_key=os.environ["ASI_API_KEY"],
)
schema = {"questions": [
{"id": "next_step", "type": "choice", "instructions": "What should support do next?",
"options": [{"name": "refund_now", "description": "Refund without a return"},
{"name": "start_return", "description": "Start a return"},
{"name": "escalate", "description": "Hand over to a human"}]},
{"id": "allowed", "type": "noul", "instructions": "Is cancelling this order allowed by the policy?"},
{"id": "urgency", "type": "score", "instructions": "How urgent is this ticket?",
"levels": ["low", "medium", "high"]},
]}
state = (
"Order 8812 shipped on Oct 1. The customer writes: "
'"I want to cancel and get my money back." '
"Policy: shipped orders cannot be cancelled; they can be returned "
"within 30 days of delivery for a full refund."
)
r = client.chat.completions.create(
model="super-decider",
messages=[
{"role": "system", "content": json.dumps(schema)},
{"role": "user", "content": json.dumps(state)},
],
)
answers = json.loads(r.choices[0].message.content)["answers"]
curl https://inference.asicloud.cudos.org/v1/chat/completions \
-H "Authorization: Bearer $ASI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "super-decider",
"messages": [
{"role": "system", "content": "{\"questions\": [{\"id\": \"allowed\", \"type\": \"noul\", \"instructions\": \"Is cancelling this order allowed by the policy?\"}]}"},
{"role": "user", "content": "\"Order 8812 shipped on Oct 1. Policy: shipped orders cannot be cancelled.\""}
]
}'
Note the escaped quotes: both message contents are JSON strings, and the state is a JSON-encoded string inside them.
Response​
choices[0].message.content is compact JSON with the answers only. Each answer has the same fields as on /v1/systemone, plus a ready label:
{"answers": {
"next_step": {"type": "choice", "choice": "start_return", "probabilities": {...}, "confidence": 0.96, "label": "start_return"},
"allowed": {"type": "noul", "noul": 0.04, "label": "no", "confidence": 0.96, "probabilities": {"yes": 0.04, "no": 0.96}},
"urgency": {"type": "score", "score": 0.66, "legend": {...}, "probabilities": {...}, "confidence": 0.61, "label": "medium"}
}}
probabilities and legend are shortened to {...} here; they have the same shape as on /v1/systemone.
| Type | label |
|---|---|
choice | The chosen option. |
score | The most likely level. |
noul | yes when noul is at least 0.5, otherwise no. Noul answers also carry confidence and probabilities here. |
The response's usage has the token counts. completion_tokens includes the thought when the request thinks.
Images​
Put images in the user message as a list of image_url parts, with an optional text part for context:
{"role": "user", "content": [
{"type": "image_url", "image_url": {"url": f"data:image/png;base64,{img}"}},
{"type": "text", "text": "Scanned document from the accounts payable inbox."},
]}
See Images for limits and a full example.