SStar Developers
同步响应、SSE 与会话管理查看 Markdown

Chat integration#

Chat is a synchronous or streaming Star Task capability. It does not use the asynchronous POST /v1/tasks creation contract, even though each completed turn is recorded as a task for billing and audit.

Route by task type#

Runtime task_typeSubmit endpointCompletion contract
chatPOST /v1/ai/chatImmediate JSON or SSE stream
Image, video, audio, musicPOST /v1/tasks202 plus poll_url
Reusable AI toolPOST /v1/tools/:tool_id/tasksTool-specific task result

Use GET /v1/models?view=chat-picker&site_id=<SITE_ID> for a chat-only picker. Submit the selected mode's exact task_model as model; never derive an alias from product_id.

Quote a chat turn#

http
POST https://task.starhk.uk/v1/ai/chat/quote
Authorization: Bearer <access_token>
Content-Type: application/json

The quote endpoint accepts the same body as the send endpoint. Its JSON response contains top-level cost_points; there is no data wrapper.

Send a non-streaming message#

js
const body = {
  site_id: SITE_ID,
  model: selectedMode.task_model,
  task_type: 'chat',
  input: {
    messages: [
      { role: 'system', content: 'Answer clearly and concisely.' },
      { role: 'user', content: '你好' },
    ],
  },
  options: {
    stream: false,
    web_search: false,
    thinking: false,
    max_tokens: 4096,
  },
  idempotency_key: crypto.randomUUID(),
};

const response = await fetch('https://task.starhk.uk/v1/ai/chat', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${accessToken}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});

const result = await response.json();
if (!response.ok || result.ok !== true) throw new Error(result.error?.message ?? 'Chat failed');

const reply = result.output?.choices?.[0]?.message?.content ?? result.output?.text ?? '';

The native non-streaming response is:

json
{
  "ok": true,
  "task_id": "t_xxx",
  "conversation_id": "c_xxx",
  "model": "deepseek-v4-flash",
  "output": {
    "choices": [{ "message": { "role": "assistant", "content": "你好" } }]
  },
  "cost_points": 1
}

output is the provider-compatible completion object. A site backend may normalize it to a reply string, but reply is not a native Star Task response field.

For a follow-up turn, pass the returned ID as options.conversation_id. Keep the relevant prior messages in input.messages; do not put messages at the request top level.

Stream a response#

Set options.stream=true and send the same request to POST /v1/ai/chat. The response content type is text/event-stream, with OpenAI-compatible data: frames and a final [DONE] marker. Read these response headers before consuming the stream:

  • X-Conversation-Id
  • X-Task-Id

Accumulate choices[0].delta.content from each JSON frame. Do not try to parse the stream as one JSON document and do not poll /v1/tasks for the assistant text.

Upload and reference documents#

The browser integrates one Star Task attachment API. It must not choose or call a RokoAPI parser; Star Task selects the text, office, or presentation parser from the verified file type.

Read the runtime limits before rendering the file picker:

http
GET https://task.starhk.uk/v1/chat/attachments/capabilities?site_id=<SITE_ID>
Authorization: Bearer <access_token>

The response contains max_file_bytes, max_files_per_message, image_extensions, document_extensions, and all_extensions. Build the input accept value from all_extensions; do not keep a separate site-specific extension list.

Current server limits are 10 MiB per file and six attachments per chat request. Supported document types are:

  • Office and PDF: pdf, docx, xlsx, xls, pptx.
  • OpenDocument: odt, ods.
  • Text and data: txt, md, markdown, csv, tsv, json, yaml, yml, xml, html,
  • htm, log, toml, ini.

  • Images accepted by the same chat attachment flow: jpg, jpeg, png, webp.

Text files must be valid UTF-8. Legacy .doc and .ppt, macro-enabled Office documents, archives, encrypted documents, and executable files are not supported. PDF OCR, image text recognition, PowerPoint visual layout, charts, and animations are not guaranteed.

Upload one file as multipart form data:

http
POST https://task.starhk.uk/v1/chat/attachments
Authorization: Bearer <access_token>
Content-Type: multipart/form-data

file=<binary>
site_id=<SITE_ID>
conversation_id=<optional existing conversation ID>

Images return ready; documents normally return parsing. Poll GET /v1/chat/attachments/:id?site_id=<SITE_ID> until ready or failed. A failed document can be retried with POST /v1/chat/attachments/:id/retry. Delete unused private files with DELETE /v1/chat/attachments/:id?site_id=<SITE_ID>.

Reference only a ready attachment in a user message:

json
{
  "role": "user",
  "content": [
    { "type": "text", "text": "Summarize the attached document" },
    { "type": "attachment", "attachment_id": "att_xxx" }
  ]
}

Attachments are private to the authenticated user_id, site_id, and bound conversation. Never store or expose a RokoAPI token in frontend code.

For one model request, Star Task currently supplies at most 80,000 parsed characters from one document and 120,000 characters across all documents. If a document is larger, the beginning and end are retained with an explicit omission marker so the model cannot mistake a partial document for complete content. These values are returned by the capabilities endpoint and may change; the browser must not use them to reject otherwise valid uploads.

Request and response rules#

  • input must be an object and input.messages must be a non-empty array.
  • Message roles are system, user, or assistant; content may be text or supported content
  • parts returned by the runtime capabilities.

  • Put stream, web_search, thinking, conversation_id, and max_tokens in options.
  • The successful JSON response is top-level `{ ok, task_id, conversation_id, model, output,
  • cost_points }; do not assume { data: ... }`.

  • Generate one UUID v4 per user-initiated turn and reuse it only when retrying that same turn.
  • Surface structured { ok:false, error:{code,message,details?} } failures to the user.

Common integration failures#

FailureCauseFix
Chat type rejected by /v1/tasksChat was sent to the async media endpointUse /v1/ai/chat
input must be an objectmessages was placed at the request top levelWrap it as input.messages
Empty displayed replyClient expected a top-level reply fieldRead output.choices[0].message.content or normalize it in the site backend
Endless pollingChat was modeled as an async taskHandle JSON/SSE directly