跳到主要内容

TypeScript SDK

Aholo OpenAPI 官方 TypeScript / Node.js SDK。

安装

按需安装,只装你用到的包:

npm install @manycore/aholo-sdk-asset # 文件上传
npm install @manycore/aholo-sdk-world@^1.3.0 # 世界重建与生成(v1.3.0+ 支持 insv)
npm install @manycore/aholo-sdk-lux3d # Lux3D 3D 生成

鉴权

推荐: 通过环境变量设置,SDK 自动读取 AHOLO_API_KEY

export AHOLO_API_KEY=your_api_key_here

也可在代码中显式传入:

import { createWorldClient } from '@manycore/aholo-sdk-world';

const world = createWorldClient({ apiKey: 'your_api_key_here', region: 'cn' });
安全提示

请勿将 API Key 硬编码到源代码、安装包或公开仓库中。

区域

说明API 接入点
cn中国区https://api.aholo3d.cn
com海外区https://api.aholo3d.com

通用上传(Asset)

import { createAssetClient } from '@manycore/aholo-sdk-asset';

const asset = createAssetClient({ region: 'cn' });

上传文件

const result = await asset.uploadFile('./video.mp4');
console.log(result.url); // 公开访问 URL

上传 Buffer

import { readFileSync } from 'node:fs';

const data = readFileSync('./image.jpg');
const result = await asset.uploadBuffer(data, { filename: 'image.jpg' });

带进度回调

const result = await asset.uploadFile('./video.mp4', {
onProgress: (uploaded, total) => {
const pct = Math.round((uploaded / total) * 100);
process.stdout.write(`\r上传进度: ${pct}%`);
},
});

UploadOptions 参数

参数类型说明
filenamestring覆盖文件名(默认取路径 basename)
onProgress(uploaded: number, total: number) => void进度回调(字节)
partTimeoutMsnumber每个分块上传超时(默认 120,000 ms)
signalAbortSignal取消信号

UploadResult 返回值

字段类型说明
urlstring文件公开访问 URL
md5string文件 MD5

世界(World)

import { createWorldClient, type WorldResourceItem, type WorldResourceType } from '@manycore/aholo-sdk-world';

const world = createWorldClient({ region: 'cn' });

重建 resources 使用 WorldResourceItemtypeWorldResourceTypeimage | video | insv)。生成 resources 使用 GenerateWorldResourceItem(仅 image,至多 1 条)。v1.3.0 起支持 Insta360 全景 type: 'insv'

3DGS 重建(从视频 / 图像)

const { worldId } = await world.reconstructions.create({
name: '客厅',
resources: [{ url: 'https://cdn.example.com/room.mp4', type: 'video' }], // type: 'video' | 'image' | 'insv'
taskQuality: 'normal', // 'low' | 'normal' | 'high'
scene: 'model', // 'model' | 'space'
useMask: false, // optional: segment uploaded resources when true
});

const detail = await world.waitFor(worldId);
console.log(detail.assets?.splats?.urls?.plyPath); // PLY 下载 URL
图片重建要求

使用图片重建时,resources 中图片类资源须 ≥ 20 条type: 'image' 或省略,.jpg/.jpeg/.png/.webp)。普通视频用 type: 'video'.mp4/.mov);Insta360 全景用 type: 'insv'.insv)。URL 扩展名须与 type 一致。

Insta360 示例:

const { worldId } = await world.reconstructions.create({
name: '全景客厅',
resources: [{ url: 'https://cdn.example.com/room.insv', type: 'insv' }],
taskQuality: 'high',
scene: 'space',
});

3DGS 生成(从文字描述)

生成接口 resources 仅支持图片type: 'image',至多 1 张,扩展名 .jpg/.jpeg/.png/.webp),不支持 video / insv

const { worldId } = await world.generations.create({
name: '森林小屋',
prompt: '森林中的现代风格小木屋',
// resources: [{ url: 'https://cdn.example.com/ref.jpg', type: 'image' }], // 可选,至多 1 张
});

const detail = await world.waitFor(worldId);

查询世界详情

const detail = await world.retrieve(worldId);
console.log(detail.status);

任务状态与轮询

阶段状态值说明
进行中PENDING排队中
进行中PREPROCESSING预处理中
进行中RUNNING执行中
成功终态SUCCEEDED成功
失败终态FAILED失败
失败终态CANCELED已取消
失败终态TIMEOUT超时
失败终态REJECTED被拒绝

world.waitFor(worldId) 轮询直至 SUCCEEDED 并返回 WorldDetail;若进入 FAILED / CANCELED / TIMEOUT / REJECTED,抛出 PollingFailedError

查询世界列表

const list = await world.list({ pageNum: 1, pageSize: 20 });
list.result?.forEach((w) => console.log(w.worldId, w.status));

WorldDetail 返回值

字段类型说明
worldIdstring世界 ID
namestring?名称
statusstring见上方「任务状态与轮询」
assets.splats.urls.plyPathstring?PLY 下载 URL
assets.splats.urls.spzPathstring?SPZ 下载 URL
assets.splats.urls.lodMetaPathstring?LOD 元数据 URL(若已生成)
assets.imagery.panoUrlstring?AI 生成全景图 URL(仅 Spatial Gen,全景子任务成功后)
assets.semanticsMetadata.upAxis"Y" | "Z"?世界上轴(Y = glTF/USD;Z = 3DGS 约定)
createTimenumber?创建时间(Unix 毫秒)
updateTimenumber?更新时间(Unix 毫秒)

Lux3D

import { createLux3dClient } from '@manycore/aholo-sdk-lux3d';

const lux3d = createLux3dClient({ region: 'cn' });

图像转 3D

// 从 URL(省略 version 即默认 v3.0-standard)
const taskId = await lux3d.imgTo3d.create({
img: 'https://example.com/object.jpg',
});

// v3.0 可选:面数与导出格式
const taskIdV3 = await lux3d.imgTo3d.create({
img: 'https://example.com/object.jpg',
faceCount: 80_000,
outputFormat: ['zip', 'glb', 'usdz', 'obj_zip'],
});

// G1 多视角(本地文件)
const taskIdG1 = await lux3d.imgTo3d.createFromFiles(
['./view1.png', './view2.png'],
{ version: 'G1', outputFormat: ['glb'], enablePbr: true },
);

// 从本地文件
const taskId2 = await lux3d.imgTo3d.createFromFile('./object.jpg');

const result = await lux3d.tasks.waitFor(taskId);
console.log(result.outputs[0]?.content); // 默认 zip 下载 URL

文字转 3D

const taskId = await lux3d.textTo3d.create({
prompt: '带雕花腿的木椅',
// style: 'photorealistic', // 见下方风格列表
});
const result = await lux3d.tasks.waitFor(taskId);

文字转 3D 风格: photorealistic(写实,默认)| cartoon(卡通)| anime(动漫)| hand_painted(手绘)| cyberpunk(赛博朋克)| fantasy(奇幻)| glass(玻璃)

材质迁移

const taskId = await lux3d.materialTransfer.create({
img: 'https://example.com/material.jpg',
meshUrl: 'https://example.com/model.glb',
});
const result = await lux3d.tasks.waitFor(taskId);

版本差异

版本默认输出说明
v3.0-standard五槽位 zip / glb / usdz / obj_zip / fbx_zipoutputFormat 选择导出;未请求槽位可能为 NOT_REQUESTED
v2.0-preview同 v3 五槽位2.0 架构
v1.0-pro单个 ZIP完整 PBR,支持透明材质
G1zip / glb / plybeta;enablePbr / textureSize;多视角 imgs

faceCount(10_000–500_000)对 v2 / v3 / G1 生效(v2/v3 默认 60_000,G1 默认 200_000);v1.0-pro 忽略。

Lux3dTaskResult 返回值

字段类型说明
taskIdnumber任务 ID
status0 | 1 | 3 | 40 初始化;1 进行中;3 成功;4 失败
outputsTaskOutput[]输出文件列表(outputs[n].content 为下载 URL,成功后约 2 小时内有效)

lux3d.tasks.waitFor(taskId)status === 3 时返回;status === 4 时抛出 PollingFailedError。建议每 10–15 秒轮询一次。


错误处理

import {
AuthenticationError,
RateLimitError,
BusinessError,
PollingTimeoutError,
PollingFailedError,
} from '@manycore/aholo-sdk-core';

try {
const detail = await world.waitFor(worldId);
} catch (e) {
if (e instanceof AuthenticationError) {
console.error('API Key 无效或未设置');
} else if (e instanceof RateLimitError) {
console.error('请求频率超限,稍后重试');
} else if (e instanceof BusinessError) {
console.error('业务错误:', e.code, e.message);
} else if (e instanceof PollingTimeoutError) {
console.error('任务轮询超时');
} else if (e instanceof PollingFailedError) {
console.error('任务执行失败:', e.message);
}
}
错误类型说明
AuthenticationErrorAPI Key 无效或未设置
RateLimitError请求频率超限
BusinessError业务错误(含 code 字段)
PollingTimeoutError轮询等待超时
PollingFailedError任务执行失败

更多示例

完整示例见 GitHub examples 目录

  • upload-file.mts — 上传本地文件
  • world-reconstruct.mts — 3DGS 重建完整流程(支持 .mp4 / .mov / .insv
  • lux3d-img-to-3d.mts — 图像转 3D

GitHub README 仅作安装说明。若与本文冲突,以本文为准。源码与可运行示例见 GitHub