SDK Reference(@eazo/anima)
官方 SDK 为 Node.js / TypeScript(@eazo/anima)。其他语言直接使用 HTTP API。
域名与端点里为什么还有 eak
SDK 符号已统一为 Anima 前缀(Qoni、AnimaScopes、Anima*Error)。api.eak.eazo.ai、/api/v3/eak/... 这类域名与端点仍沿用历史标识 eak——它们指的都是 Qoni 这一套基础设施。
本页与发布版 @eazo/anima v0.2.1 的类型定义逐项核对。升级 SDK 后以对应版本的类型定义为准。
安装与初始化
npm install @eazo/animaimport { Qoni } from "@eazo/anima";
const anima = new Qoni({
host: "https://api.eak.eazo.ai",
accessKey: process.env.ANIMA_ACCESS_KEY!,
secretKey: process.env.ANIMA_SECRET_KEY!,
});AnimaOptions 常用项:
| 选项 | 类型 | 说明 |
|---|---|---|
host | string | 网关地址。SDK 会通过 runtime-config 自动发现各服务地址 |
accessKey / secretKey | string | 工作空间访问密钥。只在服务端使用,绝不进浏览器/客户端(见 安全考量) |
timeoutMs | number | 请求超时 |
sseMaxRetries | number | SSE 流断线自动重连次数(默认 5,按 last-event-id 续传;0 关闭) |
fetch | typeof fetch | 自定义 fetch 实现 |
已弃用的初始化项
accessKeyId / accessKeySecret 已 @deprecated,改用 accessKey / secretKey;eakBaseUrl / genauthBaseUrl 等直连地址项已 @deprecated,改用 host 走运行时发现。
delegateToken —— 发起委托
两种模式,两种返回。签名(重载):
delegateToken(input: DelegateTokenInteractiveInput): Promise<AnimaResponse<InteractiveDelegationResponse>>;
delegateToken(input: DelegateTokenSilentInput): Promise<AnimaResponse<DelegateTokenSilentResponse>>;interactive(用户级授权确认,文档主线)
import { AnimaScopes } from "@eazo/anima";
const { data } = await anima.delegateToken({
mode: "interactive",
agent: "report-agent",
scopes: [AnimaScopes.WEB_SEARCH_RUN, AnimaScopes.WEB_SEARCH_READ],
redirectUri: "https://yourapp.example.com/eak/callback",
state: "opaque-business-state",
user: { id: "usr_demo_0001" },
});
// data: InteractiveDelegationResponse
// { mode: "interactive", authorizationUrl, grantId, grantState, state, requestedScopes? }把用户引导到 authorizationUrl 完成授权确认,回调后用 completeDelegateToken 换取令牌。
silent(组织级授权确认,受信服务端路径)
const { data } = await anima.delegateToken({
agent: "report-agent",
scopes: [AnimaScopes.WEB_SEARCH_RUN],
user: { id: "usr_demo_0001" },
expiresIn: 7200, // 秒,60–86400
});
// data: DelegateTokenSilentResponse(即刻含 token)silent 的边界
silent 模式等同于以组织名义替用户完成授权确认,只适用于已加固的受信服务端集成,使用前必读 安全考量 的硬约束清单与 Consent 与审批 的定位说明。
输入字段(DelegateTokenInput)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
agent | string | ✓ | Agent 标识 |
scopes | string[] | ✓ | 请求的 scope(用 AnimaScopes 常量) |
user | { id: string, ... } | silent ✓ / interactive 可选 | 被授权用户 |
mode | "silent" | "interactive" | 默认 silent | 授权模式 |
redirectUri / state | string | interactive ✓ | 授权完成回跳地址与业务 state |
expiresIn | number | string | 可选 | 令牌有效期(秒,60–86400) |
idempotencyKey | string | 可选 | 幂等键 |
已弃用:顶层 userId(改用 user: { id })、delegateAgent() 别名(改用 delegateToken())。迁移映射见 术语表与迁移;服务端兼容期风险见 安全考量。
completeDelegateToken —— 完成交互式授权
const { data } = await anima.completeDelegateToken({ grantId, code, state });
// data: DelegateTokenResponseDelegateTokenResponse 字段:
| 字段 | 类型 | 说明 |
|---|---|---|
token | string | 委托令牌。这是 SDK 重命名后的字段名——HTTP 响应里叫 delegationToken(详见下方对照表)。SDK 同时保留 delegateAgentToken / delegationToken 两个 @deprecated 别名 |
tokenType | "Bearer" | 令牌类型 |
expiresIn | number | 有效期(秒) |
grantId / auditId | string | 授权记录 ID / 审计链 ID |
grantedScopes | string[]? | 实际授予的 scope |
mode | "silent" | "interactive" | 签发模式 |
SDK 字段名 ≠ HTTP 字段名
SDK 对后端响应做了重命名与增强。混用会取到 undefined:
| HTTP 响应(API Reference) | SDK 响应(本页) | |
|---|---|---|
| 委托令牌 | delegationToken(+ delegateAgentToken 同值别名) | token |
| 已授 scope | 无此字段 | grantedScopes? |
| 错误码 | eak.* 点分码(如 eak.delegation.agent_not_allowed) | 归并码 + 类型化错误类(见下) |
用 SDK 就按本页写,直连 HTTP 就按 API Reference 写。
命名空间
anima.genauth:introspectDelegationToken({ token })(委托令牌在线验证)、userInfo({ accessToken })、jwks()、discovery()、users.list / get / getBatch / create / createBatch / update / deleteBatch(管理面,需管理员令牌)。anima.eak:workspaces.list / get / create / update、credentials.list / create / rotate / update(工作空间与访问密钥管理,对应 API Reference 的工作空间端点)。- 产品命名空间:
anima.gumem、anima.webSearch、anima.doAnything、anima.track、anima.deepResearch——各产品能力调用,接受token(委托令牌/运行时令牌)参数;详见各产品文档。
其他实用方法
| 方法 | 用途 |
|---|---|
anima.currentUser({ accessToken }) | 用用户的 access token 解析当前登录用户——应用代码里应据此确定"代表谁" |
anima.resolveAnyBoundUser() | 从绑定用户池中取任一用户 ID。仅供 demo 与冒烟测试;生产代码请用 currentUser |
anima.request({ method, path, body?, query?, headers?, token? }) | 原始请求通道:调用尚未包装为具名方法的端点(如令牌兑换 POST /api/v3/eak/token-exchange),自动带签名 |
anima.unstableRequest(...) | 同上,用于不稳定/实验性端点 |
Scope 常量
AnimaScopes(格式 服务.能力:动作)与 AnimaScopeBundles(常用组合包):
AnimaScopes.WEB_SEARCH_RUN // "webagent.web_search:run"
AnimaScopes.DO_ANYTHING_RUN // "webagent.do_anything:run"
AnimaScopes.GUMEM_MEMORY_READ // "gumem.memory:read"
AnimaScopeBundles.WEB_SEARCH // run + read
AnimaScopeBundles.AGENT_DO_ANYTHING_BASIC // run + read + stop + control
AnimaScopeBundles.GUMEM_READONLY // memory:read + profile:read按最小权限选择:能用单个 scope 不用 bundle,能用 read 不申请 run。
错误处理
所有错误继承 AnimaError(含 code / status / meta.requestId):
| 错误类 | 典型 code | 何时发生 |
|---|---|---|
AnimaAuthError | auth.failed | 签名/密钥错误 |
AnimaDelegationRequiredError | delegation.required | 缺少委托令牌 |
AnimaPermissionDeniedError | permission_denied | scope 不足 / 白名单拒绝 |
AnimaTokenExpiredError | token.expired | 令牌过期 |
AnimaValidationError | validation.failed | 参数校验失败 |
AnimaRateLimitError | rate_limit.exceeded | 触发限流 |
AnimaUpstreamError | upstream.failed、eak.token_exchange.upstream_failed | 上游服务失败 |
AnimaTimeoutError | timeout | 超时 |
import { AnimaTokenExpiredError } from "@eazo/anima";
try {
await anima.genauth.introspectDelegationToken({ token });
} catch (err) {
if (err instanceof AnimaTokenExpiredError) {
// 重新发起委托
}
throw err;
}