@xtalpi/science-algorithm-client
v0.2.5
Published
Library + CLI to call the XtalPi Science algorithm service API (contract 0.8.0)
Downloads
1,315
Keywords
Readme
@xtalpi/science-algorithm-client
Node.js + TypeScript 库,封装 XtalPi Science 算法服务 HTTP API(契约 0.8.0)。用 AlgorithmClient 提交计算、查任务、下结果;内置鉴权、重试、幂等、流式传文件与 sha256 校验。
命令行
algo为薄封装,见 CLI.md。
安装
npm install @xtalpi/science-algorithm-client- Node ≥ 18(原生
fetch/ Web Streams) - 依赖:
ajv、ajv-formats
import { AlgorithmClient } from '@xtalpi/science-algorithm-client';
const client = new AlgorithmClient({
baseUrl: 'https://<algorithm-service-host>',
token: process.env.ALGORITHM_TOKEN!,
// 可选:httpTimeoutMs、uploadDownloadTimeoutMs、httpMaxRetries、maxUploadBytes
});
// token 过期:client.setToken(newToken)API
| 方法 | 说明 |
|---|---|
| submit(input) | 提交。异步算法返回 { taskId, status };同步 vast_search 返回 { response }(无 task) |
| getTask(taskId) / getTasks(taskIds) | 查任务 |
| downloadResultFile({ taskId, destDir }) | 下载该任务全部结果文件到 destDir,校验 sha256 |
| listAlgorithms() / getAlgorithm(name) | 能力发现 |
| setToken(token) | 重置 token |
SubmitInput 按 algorithm 区分 params(见 SynthesisAssessmentParams 等)与允许的 files.field:
import type {
SubmitInput,
SynthesisAssessmentParams,
VastSearchParams,
} from '@xtalpi/science-algorithm-client';
const assessment: SubmitInput = {
algorithm: 'synthesis_assessment',
params: { enable_condition_prediction: false },
files: [{ field: 'reactions_files', path: './reactions.csv' }],
};
const search: SubmitInput = {
algorithm: 'vast_search',
params: { search_type: 'similarity', smiles: 'c1ccccc1', limit: 20 },
};完整字段以包内导出类型 / schemas/*.schema.json 为准。动态算法名可用 UntypedSubmitInput。
文件字段分配
files[].field 可传可不传:
- 传
field:按指定 multipart 字段上传(如{ field: 'scaffolds_file', path })。 - 省略
field:SDK 按算法 multipart 字段的声明顺序依次分配,并跳过已在params中内联/OSS 引用占用的字段。因此多文件必须按声明顺序提供(展库:scaffolds 在前、 building_blocks 在后)。顺序错误 SDK 无法从文件内容纠正;文件数超出可用字段会抛ValidationError。reactions_files这类可重复字段会吸收其余所有无 field 文件。
// 省略 field:两个文件按声明顺序落到 scaffolds_file、building_blocks_file
const enum1: SubmitInput = {
algorithm: 'library_enumeration',
params: { reaction_names: ['amide_coupling-1'] },
files: [{ path: './scaffolds.csv' }, { path: './building_blocks.csv' }],
};异步:提交 → 轮询 → 下载
const { taskId } = await client.submit({
algorithm: 'synthesis_assessment',
params: { enable_condition_prediction: false },
files: [{ field: 'reactions_files', path: './reactions.csv' }],
});
let task = await client.getTask(taskId!);
while (!['succeeded', 'partially_succeeded', 'failed'].includes(task.status)) {
await new Promise((r) => setTimeout(r, 20_000));
task = await client.getTask(taskId!);
}
const isSuccessful =
task.status === 'succeeded' || task.status === 'partially_succeeded';
const hasResultFiles = (task.result?.files?.length ?? 0) > 0;
if (isSuccessful) {
// 成功态可能只有 result.summary / result.data,files 为空属正常,勿当失败
// console.log(task.result?.summary, task.result?.data);
if (hasResultFiles) {
const { files } = await client.downloadResultFile({
taskId: taskId!,
destDir: './out',
});
}
}终态:succeeded / partially_succeeded(部分成功,勿当全部成功)/ failed。非终态:submitted / running。downloadResultFile 在 result.files 为空时会抛错,须先判断长度;无文件但有结构化结果仍应视为任务成功。
同步:vast_search
const { response } = await client.submit({
algorithm: 'vast_search',
params: { search_type: 'similarity', smiles: 'CC(=O)NC1=CC=CC=C1', limit: 20 },
});
// response: success / search_type / results / pagination / metadata支持的算法
| algorithm | 模式 | multipart 字段 | 说明 |
|---|---|---|---|
| synthesis_assessment | 异步 | reactions_files(1–16) | AI 合成评估 |
| library_enumeration | 异步 | scaffolds_file(必填)、building_blocks_file(可选) | 展库 |
| vast_synthesis_quote | 异步 | items_file | VAST 合成报价 |
| vast_search | 同步 | 无 | 属性/相似性/子结构检索 |
互斥输入(submit 本地校验):合成评估 reactions / reactions_files / source_task_id 三选一;展库 scaffolds / scaffolds_file 二选一;报价 items / items_file 二选一。机器可读清单见 capabilities.json。
错误与上限
import { ValidationError, ApiError, NetworkError } from '@xtalpi/science-algorithm-client';ValidationError:本地校验未过,未发请求ApiError:服务端非 2xx(status/code/message/details)NetworkError:网络/超时,重试耗尽后抛出
上传合计 ≤ 32 MiB、记录合计 ≤ 10 万。档位:vast_search limit ≤ 1000;synthesis_assessment reactions ≤ 10 万;library_enumeration scaffolds ≤ 1 万、building_blocks ≤ 1 千。重试与终态细节见 ERRORS.md。
本地测试
npm test # 单元(校验层等,无网络)
cp .env.example .env # ALGORITHM_API_URL / ALGORITHM_TOKEN
npm run test:e2e # 真实服务 e2e;无 token 时跳过e2e 报告在 reports/,实现见 scripts/lib-e2e/。
