@inferencesh/sdk

中文文档
0.38.4发布于 2026/11/01MITTypeScriptES Module构建来源已验证

用于inference.sh的官方JavaScript/TypeScript SDK -使用简单的API运行AI模型

中文使用文档
文档目录40 节
  1. 安装
  2. 获取API密钥
  3. 快速入门
  4. 使用
  5. 基本用法
  6. 使用设置参数
  7. 火灾和遗忘
  8. 实时状态更新
  9. 流媒体vs轮询
  10. 批处理
  11. 文件上传
  12. 取消任务
  13. 流函数(Live Sockets)
  14. 会话(有状态执行)
  15. 代理聊天
  16. 使用模板代理
  17. 创建Ad-Hoc代理
  18. 工具构建器
  19. 生命周期的钩子
  20. 消息排队
  21. 文件附件
  22. 结构化输出
  23. 剂的方法
  24. API参考
  25. inference(config)
  26. client.tasks.run(params, options?)
  27. client.tasks.get(taskId)
  28. client.tasks.cancel(taskId)
  29. client.files.upload(data, options?)
  30. client.agents.create(templateOrConfig) / client.agent(...)
  31. client.sessions
  32. client.sockets
  33. 任务状态常量
  34. 凭据常量
  35. 实例状态常量
  36. 工具参数类型
  37. 打印稿的支持
  38. 要求
  39. 资源
  40. 许可证

用于javascript和typescript的ai推理API

npm version npm downloads License: MIT TypeScript

官方javascript/typescript SDK inference.sh -无服务器ai推理的ai代理运行时。

运行ai模型,构建ai代理,并使用简单的api部署生成ai应用程序。访问模型包括通量,稳定扩散,LLMS (claude, gpt, gemini),视频生成(veo, seedance)等。

安装

npm install @inferencesh/sdk
# or
yarn add @inferencesh/sdk
# or
pnpm add @inferencesh/sdk

获取API密钥

获取API密钥 inference.sh仪表板.

快速入门

import { inference, TaskStatusCompleted } from '@inferencesh/sdk';

const client = inference({ apiKey: 'your-api-key' });

// Run a task and wait for the result
const result = await client.tasks.run({
  app: 'your-app',
  input: {
    prompt: 'Hello, world!'
  }
});

if (result.status === TaskStatusCompleted) {
  console.log(result.output);
}

使用

基本用法

import { inference, TaskStatusCompleted } from '@inferencesh/sdk';

const client = inference({ apiKey: 'your-api-key' });

// Wait for result (default behavior)
const result = await client.tasks.run({
  app: 'my-app',
  input: { prompt: 'Generate something amazing' }
});

if (result.status === TaskStatusCompleted) {
  console.log('Output:', result.output);
}

使用设置参数

设置参数配置应用实例(例如,模型选择)。具有匹配设置的工人是“温暖”和跳过设置:

const result = await client.tasks.run({
  app: 'my-app',
  setup: { model: 'schnell' },  // Setup parameters
  input: { prompt: 'hello' }
});

火灾和遗忘

// Get task info immediately without waiting
const task = await client.tasks.run(
  { app: 'my-app', input: { prompt: 'hello' } },
  { wait: false }
);

console.log('Task ID:', task.id);
console.log('Status:', task.status);

实时状态更新

默认情况下,客户端通过NDJSON (/tasks/{id}/stream)并调用 onUpdate 随着任务的变化。使用 onPartialUpdate 当你只需要部分流负载中的特定字段时:

const result = await client.run(
  { app: 'my-app', input: { prompt: 'hello' } },
  {
    onUpdate: (update) => {
      console.log('Status:', update.status);
      console.log('Progress:', update.logs);
    },
    onPartialUpdate: (update, fields) => {
      console.log('Changed fields:', fields, update.status);
    },
  }
);

流媒体vs轮询

SSE/NDJSON流是默认的。对于不能保持长时间连接打开的边缘运行时(凸动作,Cloudflare Workers等),禁用流并使用轻量级状态轮询:

const client = inference({
  apiKey: 'your-api-key',
  stream: false,           // poll /tasks/{id}/status instead of streaming
  pollIntervalMs: 2000,    // default: 2000
});

// Per-call override
const result = await client.run(
  { app: 'my-app', input: { prompt: 'hello' } },
  { stream: false, onUpdate: (u) => console.log(u.status) }
);

轮询模式下,由SDK进行检查 /tasks/{id}/status 并在状态改变时获取完整的任务。如果状态转换后取回失败, run() 拒绝使用基础错误。

批处理

async function processImages(images: string[]) {
  const results = [];

  for (const image of images) {
    const result = await client.tasks.run({
      app: 'image-processor',
      input: { image }
    }, {
      onUpdate: (update) => console.log(`Processing: ${update.status}`)
    });

    results.push(result);
  }

  return results;
}

文件上传

// Upload from base64
const file = await client.files.upload('data:image/png;base64,...', {
  filename: 'image.png',
  contentType: 'image/png'
});

// Use the uploaded file in a task
const result = await client.tasks.run({
  app: 'image-app',
  input: { image: file.uri }
});

取消任务

const task = await client.tasks.run(
  { app: 'long-running-app', input: {} },
  { wait: false }
);

// Cancel if needed
await client.tasks.cancel(task.id);

流函数(Live Sockets)

流函数在任务的生命周期内保持套接字与其调用者打开:帧在调用者关闭或应用程序返回之前都是双向的。 client.live 启动任务并拨打其套接字;run响应携带要拨号的地方(task.socket)。

const { task, session } = await client.live(
  { app: 'infsh/voice-loop', function: 'stream', input: { effect: 'robot' } },
  {
    onState: (state) => console.log(state), // connecting → waiting → live → ended
    onBinary: (pcm) => speaker.write(new Int16Array(pcm)),
    onPatch: (patch) => console.log(patch), // e.g. { frames: 120 }
  }
);

session.sendBinary(micFrame);          // one item of the input's binary live field
session.sendPatch({ effect: 'echo' }); // change an ordinary input while it runs
session.close();                       // the function returns and the task completes
await session.ended;

会议是 waiting 直到应用程序的第一帧(冷启动可能需要一分钟),如果任务在此之前结束,则放弃。当它下面的中继重新启动时,它使用一个新的凭据再次拨号。 client.sockets.open(taskOrId, handlers) 重新连接到正在运行的任务的套接字,例如在页面重新加载后。

函数的套接字所携带的内容在其模式中:活字段是 {"type": "array", "format": "stream", "items": ...}. splitLiveSchema(schema) 将普通字段(请求体)与活动字段分开,并且 pcmFormat(field.media) 读取PCM音频场的采样率。

在Node 18-21上没有全局变量 WebSocket:从 ws 包作为 { webSocket: WebSocket }.

会话(有状态执行)

会话允许您跨多个任务调用维护状态。worker在调用之间保持温暖,保留已加载的模型和内存状态。

// Start a new session
const result = await client.tasks.run({
  app: 'my-stateful-app',
  input: { prompt: 'hello' },
  session: 'new'
});

const sessionId = result.session_id;
console.log('Session ID:', sessionId);

// Continue the session with another call
const result2 = await client.tasks.run({
  app: 'my-stateful-app',
  input: { prompt: 'remember what I said?' },
  session: sessionId
});

自定义会话超时时间

缺省情况下,会话在60秒后失效。您可以使用 session_timeout (1 - 3600秒):

// Create a session with 5-minute idle timeout
const result = await client.tasks.run({
  app: 'my-stateful-app',
  input: { prompt: 'hello' },
  session: 'new',
  session_timeout: 300  // 5 minutes
});

// Session stays alive for 5 minutes after each call

注:

  • session_timeout 仅在以下情况下有效 session: 'new'
  • 最小超时时间:1秒
  • 最大超时时间:3600秒(1小时)
  • 每次呼叫成功都会重置空闲计时器

会话管理API

不运行任务直接管理会话:

// Inspect a session
const info = await client.sessions.get(sessionId);
console.log(info.status, info.expires_at, info.call_count);

// List active sessions
const sessions = await client.sessions.list();

// Extend idle timeout without a task call (sliding window)
await client.sessions.keepalive(sessionId);

// Release the worker immediately
await client.sessions.end(sessionId);

会话的错误

import {
  SessionNotFoundError,
  SessionExpiredError,
  SessionEndedError,
} from '@inferencesh/sdk';

try {
  await client.tasks.run({
    app: 'my-stateful-app',
    input: { prompt: 'hello' },
    session: sessionId,
  });
} catch (error) {
  if (
    error instanceof SessionNotFoundError ||
    error instanceof SessionExpiredError ||
    error instanceof SessionEndedError
  ) {
    // Start a new session and retry
    const result = await client.tasks.run({
      app: 'my-stateful-app',
      input: { prompt: 'hello' },
      session: 'new',
    });
  } else {
    throw error;
  }
}

有关完整的会话文档,包括错误处理、最佳实践和高级模式,请参阅 会议开发者指南.

代理聊天

聊天与人工智能代理使用 client.agents.create().

使用模板代理

使用工作区中的现有代理 namespace/name@shortid:

import { inference } from '@inferencesh/sdk';

const client = inference({ apiKey: 'your-api-key' });

// Create agent from template
const agent = client.agents.create('my-org/assistant@abc123');

// Send a message with streaming
await agent.sendMessage('Hello!', {
  onMessage: (msg) => {
    if (msg.content) {
      for (const c of msg.content) {
        if (c.type === 'text' && c.text) {
          process.stdout.write(c.text);
        }
      }
    }
  }
});

// Clean up
agent.disconnect();

创建Ad-Hoc代理

即时创建代理,无需保存到工作区:

import { inference, tool, string } from '@inferencesh/sdk';

const client = inference({ apiKey: 'your-api-key' });

// Create ad-hoc agent (config uses API field names: core_app, system_prompt)
const weatherTool = tool('get_weather')
  .describe('Get current weather')
  .param('city', string('City name'))
  .build();

const agent = client.agents.create({
  core_app: { ref: 'infsh/claude-sonnet-4@abc123' },
  system_prompt: 'You are a helpful assistant.',
  tools: [weatherTool], // only schemas are sent to the API; handlers stay client-side
});

await agent.sendMessage('What is the weather in Paris?', {
  onMessage: (msg) => console.log(msg),
  onToolCall: async (call) => {
    const result = await runMyClientTool(call.name, call.args);
    await agent.submitToolResult(call.id, result);
  },
});

对于多回合聊天,SDK在发送下一条消息之前打开聊天流,因此不会错过更新。使用 stopChat() 取消机上发电(POST /chats/{id}/stop), reset() 清除当前聊天并重新开始。

工具构建器

使用流畅构建器来定义 AgentTool 模式。客户端工具(tool)运行在你的应用程序通过 onToolCall;服务器端工具在inference.sh上运行。

建设者运行在描述
tool(name)客户端当地处理程序;只有模式被发送到API
appTool(name, appRef)服务器调用另一个推理应用程序
agentTool(name, agentRef)服务器委托给子代理
httpTool(name, url) / callTool(name, url)服务器带凭据注入的HTTP请求(优先于 webhookTool)
webhookTool(name, url)服务器Unsigned webhook (legacy httpTool 对于新工具)
mcpTool(name, { server, toolName })服务器调用MCP服务器上的工具(通过段塞),使用运行者自己与服务器提供程序的连接进行登录
internalTools()服务器内置工具:计划、记忆、小部件、完成、技能、元、远程、知识、工件、代理
import {
  inference,
  tool,
  appTool,
  httpTool,
  mcpTool,
  internalTools,
  string,
  CredentialProviderGoogle,
} from '@inferencesh/sdk';

const clientTool = tool('get_weather')
  .describe('Get current weather')
  .param('city', string('City name'))
  .build();

// HTTP tool authenticated with a connected account (token injected server-side)
const gmailSend = httpTool('gmail_send', 'https://gmail.googleapis.com/gmail/v1/users/me/messages/send')
  .describe('Send an email via Gmail')
  .method('POST')
  .auth({ credential: CredentialProviderGoogle })
  .build();

// API key or bearer auth
const fetchData = httpTool('fetch', 'https://api.example.com/data')
  .method('GET')
  .auth({ apiKey: 'YOUR_KEY', header: 'X-API-Key' }) // default header: X-API-Key
  .header('Accept', 'application/json')
  .build();

const bearerFetch = httpTool('bearer_fetch', 'https://api.example.com')
  .auth({ bearer: 'YOUR_TOKEN' })
  .build();

const imageGen = appTool('generate_image', 'infsh/flux-schnell@abc123')
  .param('prompt', string('Image description'))
  .requireApproval()
  .build();

// MCP server by slug; the runner's connection to its provider signs the call
const mcpSearch = mcpTool('notion_search', { server: 'notion', toolName: 'search' })
  .describe('Search Notion pages')
  .param('query', string('Search query'))
  .build();

const agent = client.agents.create({
  core_app: { ref: 'infsh/claude-sonnet-4@latest' },
  system_prompt: 'You are helpful.',
  tools: [clientTool, gmailSend, imageGen, mcpSearch],
  internal_tools: internalTools().memory().build(),
});

callTool 的别名 httpTool。运行 npx tsx examples/tool-builder.ts 查看更多模式示例(不需要API键)。

生命周期的钩子

使用 lifecycleHook() 将钩子附加到代理事件。Hooks可以调用webhook或作为任务委托给另一个代理:

import { inference, lifecycleHook, HookEventTurnStart, HookEventToolCall } from '@inferencesh/sdk';

const client = inference({ apiKey: 'your-api-key' });

const agent = client.agents.create({
  core_app: { ref: 'openrouter/claude-sonnet-4@abc' },
  hooks: [
    lifecycleHook(HookEventTurnStart)
      .webhook('https://example.com/on-turn')
      .timeout(10)
      .build(),
    lifecycleHook(HookEventToolCall)
      .task('my-org/approval-agent')
      .async(true)
      .build(),
  ],
});

消息排队

sendMessage 当代理忙于处理上一条消息时自动排队。队列消息显示时带有 queued 状态,直到座席接机。

要在处理队列消息之前取消该消息,请使用 cancelMessage 在React提供程序或 chats.cancelMessage 在API客户端上:

// Via the API client
await client.chats.cancelMessage(messageId);

文件附件

传入文件 sendMessage 选项。 Blob 首先上传值;带有 uri (已上载至 client.files.upload)按原样附上:

const uploaded = await client.files.upload(imageBlob, {
  filename: 'photo.png',
  contentType: 'image/png',
});

await agent.sendMessage('Describe this image', {
  files: [imageBlob, uploaded], // Blob uploads; FileDTO reuses uri
  onMessage: (msg) => console.log(msg),
});

结构化输出

使用 output_schema 获取结构化JSON响应:

const agent = client.agents.create({
  core_app: { ref: 'infsh/claude-sonnet-4@latest' },
  output_schema: {
    type: 'object',
    properties: {
      summary: { type: 'string' },
      sentiment: { type: 'string', enum: ['positive', 'negative', 'neutral'] },
      confidence: { type: 'number' },
    },
    required: ['summary', 'sentiment', 'confidence'],
  },
  internal_tools: { finish: true },
});

const output = await agent.run('Analyze: Great product!');

agent.run() 发送带有轮询的消息(没有SSE),等待聊天空闲,然后返回 chat.output (解析后的成品-工具结果,或 null 如果没有)。

剂的方法

方法描述
sendMessage(text, options?)发送消息;流或轮询,直到空闲时回调或 stream: false
run(text, options?)结构化发送和返回 chat.output (总是使用轮询)
getChat(chatId?)获取当前或指定的聊天记录(chat_messages 在返回的聊天中)
stopChat()停止当前聊天的生成(如果没有活动聊天,则不进行操作)
submitToolResult(toolId, resultOrAction)提交客户端工具的结果(字符串或 {action, form_data})
startStreaming(options?)手动连接到 /chats/{id}/stream 对于当前聊天
disconnect()停止活动流/轮询连接
reset()断开并清除聊天状态,以便下一条消息开始新的聊天

通过渠道整合(Slack、Telegram、可穿戴设备)到达的信息可以携带 channel_context 因此,回复以同样的方式发送回来。API在它第一次看到它的时候记录在聊天中,所以以后的turn继承它:

await agent.sendMessage(text, {
  channel_context: { channel_type: 'slack', channel_metadata: { channel: 'C123', thread_ts: '1700000000.000100' } },
});

API参考

inference(config)

创建一个新的推断客户端。

参数类型要求描述
config.apiKeystring是您的inference.sh API密钥
config.baseUrlstring否自定义API URL(默认: https://api.inference.sh)
config.streamboolean否使用NDJSON流(true,默认)或状态轮询(false)
config.pollIntervalMsnumber否轮询间隔 stream: false (默认值: 2000)
config.proxyUrlstring否前端应用的代理基础URL(将API密钥保存在服务器端)

client.tasks.run(params, options?)

在inference.sh上运行任务。

参数:

参数类型要求描述
params.appstring是App标识符(例如: 'username/app-name')
params.inputobject是输入应用程序的参数
params.setupobject否设置参数(影响工人热情/调度)
params.infrastring否基础设施: 'cloud' 或者 'private'
params.sessionstring否会话ID或 'new' 开始一个新的会话
params.session_timeoutnumber否会话超时时间,单位为秒(1-3600) session: 'new')

选项:

选项类型默认的描述
waitbooleantrue等待任务完成
streamboolean客户端默认使用NDJSON流或状态轮询
pollIntervalMsnumber客户端默认轮询间隔 stream: false
onUpdatefunction-回调任务更新(在轮询时对状态更改进行完整获取)
onPartialUpdatefunction-部分NDJSON流更新的回调 (task, fields)
maxReconnectsnumber5最大轮询重试时 stream: false

client.tasks.get(taskId)

按ID获取任务。

client.tasks.cancel(taskId)

取消正在运行的任务。

client.files.upload(data, options?)

上传文件到inference.sh。

参数:

参数类型描述
datastring | BlobBase64字符串、数据URI或Blob
options.filenamestring文件名
options.contentTypestringMIME类型
options.publicboolean使文件可公开访问

client.agents.create(templateOrConfig) / client.agent(...)

从模板或临时配置创建代理实例。 client.agent(...) 的别名 client.agents.create(...).

sendMessage 选项: onMessage, onChat, onToolCall, files, stream, pollIntervalMs。带有状态的客户端工具 awaiting_input 每个调用ID通过 onToolCall.

模板模式:

const agent = client.agents.create('namespace/name@version');

特别的模式:

const agent = client.agents.create({
  core_app: { ref: 'infsh/claude-sonnet-4@abc123' },
  system_prompt: 'You are helpful.',
  tools: [...],
});

client.sessions

方法HTTP描述
get(sessionId)GET /sessions/{id}会话元数据(status, expires_at, call_count,……)
list()GET /sessions所有会话(如果没有则为空数组)
keepalive(sessionId)POST /sessions/{id}/keepalive重置空闲过期
end(sessionId)DELETE /sessions/{id}结束会话并释放工作人员

client.sockets

方法HTTP描述
open(taskOrId, handlers?, options?)- - - - - -调用流任务的套接字;返回一个 LiveSession
get(socketId)GET /sockets/{id}插座和它的寿命
forTask(taskId)POST /sockets/list任务的套接字,或null
access(socketId)POST /sockets/{id}/access呼叫方的新凭证
delete(socketId)DELETE /sockets/{id}删除记录

client.live(params, handlers?, options?) 是 tasks.run(params, { wait: false }) 紧随其后的是 sockets.open.

任务状态常量

import {
  TaskStatusQueued,
  TaskStatusRunning,
  TaskStatusCompleted,
  TaskStatusFailed,
  TaskStatusCancelled
} from '@inferencesh/sdk';

if (task.status === TaskStatusCompleted) {
  console.log('Done!');
}

凭据常量

CredentialDTO 字段(provider, type, status)使用导出为常量的类型化字符串联合:

import type { CredentialDTO } from '@inferencesh/sdk';
import {
  CredentialProviderGoogle,
  CredentialTypeOAuth,
  CredentialStatusConnected,
  CredentialStatusDisconnected,
  CredentialStatusExpired,
  CredentialStatusError,
  RequirementTypeCredential,
  isRequirementsNotMetException,
} from '@inferencesh/sdk';

function isGoogleConnected(credential: CredentialDTO): boolean {
  return (
    credential.provider === CredentialProviderGoogle &&
    credential.status === CredentialStatusConnected
  );
}

// HTTP 412 when an app requires a missing secret, credential, or scope
try {
  await client.run({ app: 'my-app', input: {} });
} catch (error) {
  if (isRequirementsNotMetException(error)) {
    for (const req of error.errors) {
      if (req.type === RequirementTypeCredential && req.action?.provider === CredentialProviderGoogle) {
        // User must connect Google — see https://inference.sh/docs/extend/credentials
      }
    }
  }
}
恒集团值
CredentialProvider*google, google-sa, slack, notion, github, x, microsoft, salesforce, discord, gcp, reddit
CredentialType*service_account, oauth, api_key, wif
CredentialStatus*connected, disconnected, expired, error

实例状态常量

使用引擎实例api时使用(InstanceDTO.status):

import {
  InstanceStatusCreating,
  InstanceStatusPendingProvider,
  InstanceStatusPending,
  InstanceStatusActive,
  InstanceStatusError,
  InstanceStatusDeleting,
  InstanceStatusDeleted,
} from '@inferencesh/sdk';

工具参数类型

在构建 AgentTool 模式手动(在工具构建器之外),使用 ToolParamType* 用于JSON模式 type 字段:

import {
  ToolParamTypeObject,
  ToolParamTypeString,
  ToolParamTypeInteger,
  ToolParamTypeNumber,
  ToolParamTypeBoolean,
  ToolParamTypeArray,
  ToolParamTypeNull,
} from '@inferencesh/sdk';

const schema = {
  type: ToolParamTypeObject,
  properties: {
    city: { type: ToolParamTypeString, description: 'City name' },
  },
  required: ['city'],
};

流畅的工具构建器(string(), number(), object())自动推断这些类型。

打印稿的支持

这个SDK是用TypeScript编写的,包含完整的类型定义。导出所有类型:

import type {
  Task,
  ApiAppRunRequest,
  RunOptions,
  CredentialDTO,
  AgentTool,
} from '@inferencesh/sdk';

要求

  • Node.js 18.0.0或更高版本
  • 现代浏览器 fetch 支持

资源

许可证

麻省理工学院© inference.sh

版本与发布记录

@inferencesh/sdk 共发布 122 个版本,首次发布于 2025/12/01;过去 12 个月发布了 122 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.38.4latest2026/11/012 天前
0.38.32026/11/012 天前
0.38.22026/11/012 天前
0.38.12026/10/312 天前
0.38.02026/10/295 天前
0.37.02026/10/295 天前

关于 @inferencesh/sdk 的常见问题

@inferencesh/sdk 是什么?

用于inference.sh的官方JavaScript/TypeScript SDK -使用简单的API运行AI模型

如何安装 @inferencesh/sdk?

在项目目录运行 npm install @inferencesh/sdk,或使用 pnpm add / yarn add / bun add。

@inferencesh/sdk 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@inferencesh/sdk 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@inferencesh/sdk 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22.12.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@inferencesh/sdk 可以商用吗?

@inferencesh/sdk 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@inferencesh/sdk 还在维护吗?

最新版本 0.38.4 发布于 2026/11/01(2 天前);至今共发布 122 个版本,其中过去 12 个月发布了 122 个;首次发布于 2025/12/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。