npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

runninghub-sdk-node

v0.1.0

Published

RunningHub Node.js and TypeScript SDK

Readme

runninghub-sdk-node

RunningHub 的 Node.js / TypeScript SDK,适用于 Node.js 18 及以上环境。

适合这些场景:

  • 调用 AI App
  • 调用 Workflow / Comfy 工作流
  • 轮询任务状态并获取结果
  • 上传文件、下载结果、查询资源和账户信息

安装

npm install runninghub-sdk-node

要求:

  • Node.js >=18

准备 API Key

推荐使用环境变量:

RUNNINGHUB_API_KEY=your_runninghub_api_key

如果不使用 .env 加载工具,也可以直接在命令前传入:

RUNNINGHUB_API_KEY=your_runninghub_api_key node your-script.js

快速开始

下面这个例子会直接调用一个工作流并等待结果返回:

import { modifyNodes, RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '');

const result = await client.runWorkflowAndWait(
  '2044675520398368770',
  modifyNodes()
    .text('6', 'a quiet seaside road at sunrise, painterly illustration')
    .seed('10', 123456)
    .steps('10', 12)
    .cfg('10', 1)
    .size('11', 1024, 1024),
  { pollIntervalMs: 2_000 },
);

console.log(result.status);
console.log(result.results[0]?.url);

选哪个接口

AI App

适合已经发布好的应用接口。

  • runAIApp()
  • runAIAppWithModifier()
  • runAIAppAndWait()

Workflow / Comfy 工作流

适合直接调用某个 workflow ID,并按节点修改参数。

  • runWorkflow()
  • runWorkflowWithModifier()
  • runWorkflowAndWait()
  • run()
  • runWithModifier()
  • asyncRun()
  • asyncRunWithModifier()

说明:

  • runWorkflow*()/openapi/v2/run/workflow/{id}
  • run*()/task/openapi/create
  • 两种方式都能提交工作流任务;如果更想贴近 RunningHub 的通用建任务接口,优先用 run() / runWithModifier()

标准模型接口

适合直接调用平台暴露的标准模型,例如文生图模型接口。

  • runStandardModel()
  • pricePreview()

初始化客户端

import { RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '', {
  baseURL: 'https://www.runninghub.cn',
  hostOverride: 'www.runninghub.cn',
  userAgent: 'my-app/1.0.0',
  timeoutMs: 60_000,
  maxBodyBytes: 10 << 20,
});

支持的配置项:

  • baseURL: API 基础地址
  • hostOverride: 自定义请求 Host
  • userAgent: 自定义 User-Agent
  • timeoutMs: 单次请求超时时间,单位毫秒
  • maxBodyBytes: 响应体最大读取字节数
  • fetch: 自定义 fetch 实现
  • headers: 默认附加请求头

Workflow 教程

推荐流程是:先找出工作流里可改的节点参数,再用 modifyNodes() 提交。

1. 查看工作流参数

import { RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '');

const params = await client.getWorkflowParams('2044675520398368770');
console.log(params);

返回结果包含:

  • nodeId
  • nodeType
  • nodeTitle
  • fieldName
  • fieldType
  • value

如果还想看节点之间的连接关系:

const inspection = await client.inspectWorkflow('2044675520398368770');
console.log(inspection.nodes.find((node) => node.nodeId === '10'));

inspectWorkflow() 会额外返回 linkedInputs,比如 positive 连接到哪个节点、model 来自哪个节点。

2. 提交工作流任务

import { modifyNodes, RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '');

const modifier = modifyNodes()
  .text('6', 'a cinematic seaside road at sunrise')
  .seed('10', 601240929502329)
  .steps('10', 8)
  .cfg('10', 1)
  .sizeWithBatch('11', 1024, 1024, 1);

const task = await client.runWithModifier('2044675520398368770', modifier, {
  instanceType: 'default',
  addMetadata: true,
});

const result = await client.waitForCompletion(task, {
  pollIntervalMs: 2_000,
  timeoutMs: 600_000,
  onStatusChange: (status) => console.log('status:', status),
});

console.log(result.results[0]?.url);

3. async 风格别名

如果你想在命名上区分“提交任务”和“等待完成”,可以使用这组别名:

const task = await client.asyncRunWithModifier('2044675520398368770', modifier);
const result = await client.asyncWaitForCompletion(task, { pollIntervalMs: 2_000 });

这些 async* 方法是对现有稳定实现的别名,不会引入另一套执行逻辑。

AI App 教程

import { RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '');

const task = await client.runAIApp('2050082405557514242', {
  nodeInfoList: [
    {
      nodeId: '2',
      fieldName: 'resolution',
      fieldValue: '2k',
      description: '选择分辨率',
    },
  ],
  instanceType: 'default',
  usePersonalQueue: false,
});

const result = await client.waitForTask(task.taskId);
console.log(JSON.stringify(result, null, 2));

如果也想用链式写法:

import { modifyNodes, RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '');

const result = await client.runAIAppAndWait(
  '2050082405557514242',
  modifyNodes().set('2', 'resolution', '2k'),
  { pollIntervalMs: 2_000 },
);

console.log(result.status);

标准模型接口

import { RunningHubClient } from 'runninghub-sdk-node';

const client = new RunningHubClient(process.env.RUNNINGHUB_API_KEY ?? '');

const task = await client.runStandardModel('/openapi/v2/seedream-v4/text-to-image', {
  prompt: '一只戴着护目镜的柯基犬在月球上驾驶复古摩托车,电影感光影,超细节,4k',
  negativePrompt: 'blurry, low quality, distorted, extra fingers',
  width: 1024,
  height: 1024,
  numImages: 1,
});

const result = await client.waitForTask(task.taskId);
console.log(result.results);

价格预估:

const preview = await client.pricePreview('/openapi/v2/seedream-v4/text-to-image', {
  prompt: 'a cat astronaut',
  width: 1024,
  height: 1024,
  numImages: 1,
});

console.log(preview.priceText);

NodeModifier

modifyNodes() 用来构建 nodeInfoList

通用写法:

const modifier = modifyNodes()
  .set('6', 'text', 'hello world')
  .set('10', 'steps', 8)
  .set('11', 'width', 1024);

常用快捷方法:

  • text(nodeId, value)
  • negativeText(nodeId, value)
  • image(nodeId, value)
  • video(nodeId, value)
  • audio(nodeId, value)
  • seed(nodeId, value)
  • steps(nodeId, value)
  • cfg(nodeId, value)
  • denoise(nodeId, value)
  • sampler(nodeId, value)
  • scheduler(nodeId, value)
  • width(nodeId, value)
  • height(nodeId, value)
  • size(nodeId, width, height)
  • sizeWithBatch(nodeId, width, height, batchSize)
  • batchSize(nodeId, value)
  • lora(nodeId, value)
  • loraStrength(nodeId, value)
  • checkpoint(nodeId, value)

批量操作:

const modifier = modifyNodes()
  .append({ nodeId: '6', fieldName: 'text', fieldValue: 'prompt' })
  .addMany([
    { nodeId: '10', fieldName: 'steps', fieldValue: 8 },
    { nodeId: '11', fieldName: 'width', fieldValue: 1024 },
  ]);

console.log(modifier.length);
console.log(modifier.toList());

任务状态与结果

等待完成:

const result = await client.waitForTask(taskId, {
  pollIntervalMs: 2_000,
  timeoutMs: 600_000,
  onStatusChange: (status, response) => {
    console.log('status:', status, 'task:', response.taskId);
  },
});

查询状态:

const status = await client.getStatus('task_id');
console.log(status);

获取输出:

const outputs = await client.getOutputs('task_id');
console.log(outputs);

查询完整任务信息:

const detail = await client.queryTaskV2('task_id');
console.log(detail);

常见状态值:

  • CREATE
  • QUEUED
  • RUNNING
  • SUCCESS
  • FAILED
  • CANCELLED

文件上传与结果下载

上传二进制内容:

const uploaded = await client.uploadBinary(fileBuffer, 'input.png');
console.log(uploaded.download_url);

这些方法是等价别名:

  • uploadBinary(input, filename)
  • uploadBinaryReader(input, filename)
  • uploadFile(input, filename)
  • uploadImage(input, filename)

上传本地文件:

const uploaded = await client.uploadFilePath('/tmp/input.png');
console.log(uploaded.download_url);

也可以使用:

  • uploadBinaryFile(filePath)
  • uploadImageFile(filePath)

下载任务结果:

const result = await client.waitForTask(taskId);
const files = await client.downloadTaskResults(result, './outputs');
console.log(files);

账户与资源

const account = await client.accountStatus();
const keys = await client.apiKeyList();
const queue = await client.queueStatus();

const resources = await client.listPublicResources({
  resourceType: 'LORA',
  current: 1,
  size: 20,
});

Comfy 兼容接口

这些接口主要用于兼容旧调用方式,或者需要直接操作工作流 JSON 的场景:

  • createComfyTaskSimple(workflowId, options)
  • cancel(taskId)
  • cancelComfyTask(taskId)
  • getTaskStatusDeprecated(taskId)
  • getTaskOutputsDeprecated(taskId)
  • getWorkflowJSONPrompt(workflowId)
  • getWorkflowJSON(workflowId)

说明:

  • getWorkflowJSONPrompt() 返回原始 JSON 字符串
  • getWorkflowJSON() 返回解析后的对象
  • inspectWorkflow() / getWorkflowParams() 是在 getWorkflowJSON() 基础上做的高层封装

子路径导入

import { RunningHubClient } from 'runninghub-sdk-node/client';
import type { RunAIAppRequest } from 'runninghub-sdk-node/types';
import { RunningHubAPIError } from 'runninghub-sdk-node/errors';

可用导出:

  • runninghub-sdk-node
  • runninghub-sdk-node/client
  • runninghub-sdk-node/types
  • runninghub-sdk-node/errors

错误处理

SDK 会抛出以下错误类型:

  • RunningHubAPIError: 接口返回业务错误
  • RunningHubHTTPError: HTTP 状态码异常
  • RunningHubConfigError: 参数或本地配置错误
  • RunningHubTimeoutError: 等待任务超时
import {
  RunningHubAPIError,
  RunningHubConfigError,
  RunningHubHTTPError,
  RunningHubTimeoutError,
} from 'runninghub-sdk-node/errors';

try {
  const result = await client.queryTaskV2('task_id');
  console.log(result.status);
} catch (error) {
  if (error instanceof RunningHubAPIError) {
    console.error(error.code, error.message, error.details);
  } else if (error instanceof RunningHubHTTPError) {
    console.error(error.statusCode, error.body);
  } else if (error instanceof RunningHubTimeoutError) {
    console.error(error.taskId, error.timeoutMs);
  } else if (error instanceof RunningHubConfigError) {
    console.error(error.message);
  } else {
    console.error(error);
  }
}

示例

示例代码位于 examples/ 目录:

  • examples/ai-app.ts: AI App 调用示例
  • examples/text-to-image.ts: 标准模型文生图示例
  • examples/workflow.ts: 基础 workflow 调用示例
  • examples/workflow-from-template.ts: 推荐的工作流调用示例,直接基于 workflowId + nodeInfoList 运行,不依赖本地 JSON 模板参与提交

进入 examples/ 目录后,可以直接运行:

cd examples
npm run ai-app
npm run text-to-image
npm run workflow
npm run workflow-from-template

workflow-from-template.ts 支持以下环境变量覆盖默认参数:

  • RUNNINGHUB_WORKFLOW_ID
  • RUNNINGHUB_NODE_6_TEXT
  • RUNNINGHUB_NODE_10_SEED
  • RUNNINGHUB_NODE_10_STEPS
  • RUNNINGHUB_NODE_10_CFG
  • RUNNINGHUB_NODE_11_WIDTH
  • RUNNINGHUB_NODE_11_HEIGHT

例如:

cd examples
RUNNINGHUB_NODE_6_TEXT='a futuristic city at dawn' npm run workflow-from-template

API 总表

提交任务:

  • asyncRun(workflowId, modifierOrNodeInfoList?, options?)
  • asyncRunWithModifier(workflowId, modifier, options?)
  • run(workflowId, modifierOrNodeInfoList?, options?)
  • runWithModifier(workflowId, modifier, options?)
  • runAIApp(appIdOrPath, request)
  • runAIAppWithModifier(appIdOrPath, modifier, options)
  • runAIAppAndWait(appIdOrPath, requestOrModifier, waitOptions)
  • runWorkflow(workflowIdOrPath, request)
  • runWorkflowWithModifier(workflowIdOrPath, modifier, options)
  • runWorkflowAndWait(workflowIdOrPath, requestOrModifier, waitOptions)
  • runStandardModel(modelPath, request)
  • pricePreview(modelPath, request)

查询任务和工作流:

  • asyncWaitForCompletion(taskOrTaskId, options)
  • getWorkflowParams(workflowId)
  • inspectWorkflow(workflowId)
  • getStatus(taskId)
  • getOutputs(taskId)
  • queryTaskV2(taskId)
  • waitForTask(taskId, options)
  • waitForCompletion(taskOrTaskId, options)

文件与资源:

  • uploadFile(input, filename)
  • uploadImage(input, filename)
  • uploadBinary(input, filename)
  • uploadBinaryReader(input, filename)
  • uploadBinaryFile(filePath)
  • uploadFilePath(filePath)
  • uploadImageFile(filePath)
  • downloadFile(fileURL, destPath)
  • downloadTaskResults(task, outputDir)
  • accountStatus()
  • apiKeyList()
  • queueStatus()
  • listPublicResources(request)

构建

npm run check
npm run build