ORBIT API

客户 SDK(JavaScript / Python)

两个零依赖的薄客户端,封装四个公开模拟接口:读取模型、提交调用、按 requestId 核对、流式调用。当前只连接固定模拟接口,不会产生真实模型回答或真实扣款。

获取与安装

SDK 位于代码仓库的 sdk/ 目录:JavaScript 需要 Node.js 22 及以上,Python 需要 3.9 及以上,均只用标准库。把 sdk/js 或 sdk/python 目录复制到你的服务端项目中即可。

SDK 不在 npm 或 PyPI 上发布,请不要从公共包仓库安装同名包。

服务端从环境变量 ORBIT_SIM_BASE_URL(服务 Origin,须为 https)和 ORBIT_SIM_API_KEY(专用模拟密钥)读取配置。密钥只放在你自己的服务端,不要写进网页代码、日志或代码仓库;SDK 不会在输出或错误信息里打印密钥。

快速上手

读取模型、提交一次调用,再用同一个 requestId 核对。requestId 是幂等键,发送前先保存。

sdk/examples/quickstart.mjs

// Node.js 22+. Run from the repository root: node sdk/examples/quickstart.mjs
// Reads ORBIT_SIM_BASE_URL and ORBIT_SIM_API_KEY. Keep the key on your server; never log it.
import { OrbitClient, OrbitError } from '../js/orbit-sim.mjs';

const orbit = new OrbitClient({ baseUrl: process.env.ORBIT_SIM_BASE_URL, apiKey: process.env.ORBIT_SIM_API_KEY });

const { models } = await orbit.models();
console.log('models:', models.map(m => m.id).join(', '));

// requestId is the idempotency key. Save it before sending.
const requestId = process.env.ORBIT_SIM_REQUEST_ID || crypto.randomUUID();
try {
  const { replayed, record } = await orbit.generate({ model: 'sim-general', message: 'hello', maxOutputTokens: 64, requestId });
  console.log('generate:', record.state, 'cost', record.cost, 'replayed', replayed);
} catch (error) {
  if (!(error instanceof OrbitError) || !error.outcomeUnknown) throw error;
  // The SDK never re-sends a POST whose outcome is unknown. Check the same requestId instead.
  const check = await orbit.lookup(error.requestId);
  console.log('unknown outcome:', error.code ?? error.name, 'lookup', check.state);
}

const check = await orbit.lookup(requestId);
console.log('lookup:', check.state);

运行方式

export ORBIT_SIM_BASE_URL=... ORBIT_SIM_API_KEY=...
node sdk/examples/quickstart.mjs

流式调用

onFrame 会依次收到 start、delta、fault 帧,文字只是临时内容。只有 stream() 正常返回时,返回的记录才是最终结果;同一 requestId 再次调用会返回原记录(replayed 为 true)。

sdk/examples/stream.mjs

// Node.js 22+. Run from the repository root: node sdk/examples/stream.mjs
// Reads ORBIT_SIM_BASE_URL and ORBIT_SIM_API_KEY. Keep the key on your server; never log it.
import { OrbitClient } from '../js/orbit-sim.mjs';

const orbit = new OrbitClient({ baseUrl: process.env.ORBIT_SIM_BASE_URL, apiKey: process.env.ORBIT_SIM_API_KEY });
const requestId = process.env.ORBIT_SIM_REQUEST_ID || crypto.randomUUID();

// Delta text is provisional. The record is final only when stream() resolves.
const result = await orbit.stream(
  { model: 'sim-general', message: 'hello', maxOutputTokens: 64, requestId },
  { onFrame: frame => { if (frame.type === 'delta') process.stdout.write(frame.text); } },
);
console.log();
console.log('stream:', result.record.state, 'cost', result.record.cost, 'replayed', result.replayed);

重试与超时

默认最多自动重试 2 次;单次请求超时 20 秒,流式调用整体超时 60 秒,均可调整。

错误类型

所有错误都继承 OrbitError,带有 code、status、execution 和 requestId。outcomeUnknown(Python 为 outcome_unknown)为真时,表示服务端可能已经执行或计费。

错误类错误码(HTTP 状态)
OrbitInvalidRequestError
PUBLIC_SIMULATION_INVALID (400, 405, 413, 415)
SIMULATION_INVALID (400)
OrbitAuthenticationError
PUBLIC_SIMULATION_UNAUTHENTICATED (401)
OrbitPermissionError
PUBLIC_SIMULATION_FORBIDDEN (403)
SIMULATION_KEY_INVALID (403)
SIMULATION_KEY_FORBIDDEN (403)
SIMULATION_MODEL_NOT_ALLOWED (403)
OrbitNotFoundError
PUBLIC_SIMULATION_NOT_FOUND (404)
SIMULATION_NOT_FOUND (404)
OrbitConflictError
SIMULATION_INSUFFICIENT_BALANCE (409)
SIMULATION_ACCOUNT_FROZEN (409)
SIMULATION_KEY_BUDGET (409)
SIMULATION_CAPACITY (409)
OrbitIdempotencyConflictError
SIMULATION_IDEMPOTENCY_CONFLICT (409)
OrbitRateLimitError
PUBLIC_SIMULATION_RATE_LIMITED (429)
SIMULATION_QUOTA (429)
OrbitUnavailableError
PUBLIC_SIMULATION_UNAVAILABLE (502, 503)
OrbitTimeoutError没有拿到可用响应,结果未知。
OrbitConnectionError没有拿到可用响应,结果未知。
OrbitProtocolError没有拿到可用响应,结果未知。
OrbitConfigError参数或客户端配置有误,请求未发出。

结果未知时怎么办

保留原 requestId,调用 lookup 核对。用同一 requestId 和完全相同的参数再次提交,会得到原记录(replayed 为 true);参数不同会收到 OrbitIdempotencyConflictError。lookup 返回 not_found 不能证明此前没有执行;cost 或 actual 为 null 表示待核对,不是零费用。

当前范围

SDK 版本 0.1.0,只覆盖固定模拟接口(sim-general / sim-reasoning)。OpenAI 兼容端点、工具调用和真实路由开放后会同步更新。