# @computesdk/provider 中文文档

规范地址：https://npmcn.com/package/%40computesdk/provider/

版本：2\.1\.22
npm 元数据更新时间：2026-11-06T13:54:47.041Z
中文译文更新时间：2026-11-10T14:23:10.889Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40computesdk/provider
原文对照：https://npmcn.com/package/%40computesdk/provider/?lang=original
项目主页：https://www.computesdk.com/
源码仓库：https://github.com/computesdk/computesdk

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：758 kB，9 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- 运行依赖：3 个
- 首次发布：2025-12-31T19:03:04.709Z
- 最新版本发布：2026-11-06T13:54:46.642Z
- 近 30 天下载量：48359（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：59（近 12 个月 59 个）

## 中文简介

计算SDK的提供方框架 - 定义自定义的沙盒提供者

## 安装

```sh
npm install @computesdk/provider
```

也可以使用：`pnpm add @computesdk/provider`、`yarn add @computesdk/provider`、`bun add @computesdk/provider`

## README

# @ computesdk/ 提供者

构建自定义计算提供者的提供者框架.

## 概览

这个软件包为计算SDK生态系统提供了自定义沙盒提供商的工具和类型. 使用它来添加对新计算平台,云提供商,或沙盒环境的支持.

## 安装

```bash
npm install @computesdk/provider
```

## 快速启动

```typescript
import { defineProvider } from '@computesdk/provider';
import type { ProviderConfig } from '@computesdk/provider';

interface MyProviderConfig extends ProviderConfig {
  apiKey: string;
  region?: string;
}

export const myProvider = defineProvider<any, MyProviderConfig>({
  name: 'my-provider',
  defaultMode: 'direct',
  methods: {
    instances: {
      create: async (config, options) => {
        // Create sandbox via your provider's API
        const response = await fetch(`https://api.example.com/sandboxes`, {
          method: 'POST',
          headers: { 'Authorization': `Bearer ${config.apiKey}` },
          body: JSON.stringify(options)
        });
        
        const data = await response.json();
        
        return {
          instance: data, // Your provider's sandbox object
          instanceId: data.id
        };
      },
      
      getById: async (config, instanceId) => {
        const response = await fetch(
          `https://api.example.com/sandboxes/${instanceId}`,
          { headers: { 'Authorization': `Bearer ${config.apiKey}` } }
        );
        
        if (!response.ok) return null;
        
        const data = await response.json();
        return { instance: data, instanceId: data.id };
      },
      
      list: async (config) => {
        const response = await fetch(
          `https://api.example.com/sandboxes`,
          { headers: { 'Authorization': `Bearer ${config.apiKey}` } }
        );
        
        const data = await response.json();
        return data.map((s: any) => ({ instance: s, instanceId: s.id }));
      },
      
      destroy: async (config, instanceId) => {
        await fetch(
          `https://api.example.com/sandboxes/${instanceId}`,
          {
            method: 'DELETE',
            headers: { 'Authorization': `Bearer ${config.apiKey}` }
          }
        );
      },
      
      runCommand: async (sandbox, command, args) => {
        // Run shell command
        const response = await fetch(
          `https://api.example.com/sandboxes/${sandbox.id}/command`,
          {
            method: 'POST',
            body: JSON.stringify({ command, args })
          }
        );
        
        const result = await response.json();
        return {
          stdout: result.stdout,
          stderr: result.stderr,
          exitCode: result.exitCode
        };
      },
      
      getInfo: async (sandbox) => {
        return {
          id: sandbox.id,
          status: sandbox.status,
          createdAt: new Date(sandbox.created_at)
        };
      },
      
      getUrl: async (sandbox, options) => {
        return `https://${sandbox.id}.example.com:${options.port}`;
      }
    }
  }
});
```

## API 参考

### `defineProvider(config)`

定义具有沙盒生命周期方法的新供应商.

**参数:**

```typescript
interface ProviderConfig<TInstance, TConfig> {
  name: string;
  defaultMode?: 'direct' | 'gateway';
  methods: {
    instances: InstanceMethods<TInstance, TConfig>;
    template?: TemplateMethods<TTemplate, TConfig>;
    snapshot?: SnapshotMethods<TSnapshot, TConfig>;
  };
}
```

`methods.sandbox` 仍为 `methods.instances` ——使用 `instances` 在新供应商.

**回返情况:** 工厂功能 `(config: TConfig) => Provider`

### 必要实例方法

#### 收集操作

这些方法管理收集层面的沙盒:

##### `create(config, options?)`

创建新沙盒 .

```typescript
create: async (config, options) => {
  // Return: { instance: YourSandboxObject, instanceId: string }
  return { instance: myInstance, instanceId: 'sandbox-123'
  };
}
```

##### `getById(config, instanceId)`

以身份证获取已有的沙盒 .

```typescript
getById: async (config, instanceId) => {
  // Return: { instance, instanceId } or null if not found
  return { instance: myInstance, instanceId };
}
```

##### `list(config)`

列出所有沙盒 .

```typescript
list: async (config) => {
  // Return: Array of { instance, instanceId }
  return [
    { instance: sandbox1, instanceId: 'id1' },
    { instance: sandbox2, instanceId: 'id2' }
  ];
}
```

##### `destroy(config, instanceId)`

毁一沙盒.

```typescript
destroy: async (config, instanceId) => {
  await yourApi.deleteSandbox(instanceId);
}
```

#### 实例操作

这些方法适用于单个沙盒实例:

##### `runCommand(sandbox, command, args?, options?)`

运行 shell 命令 .

```typescript
runCommand: async (sandbox, command, args) => {
  const result = await yourApi.runCommand(sandbox.id, command, args);
  return {
    stdout: result.stdout,
    stderr: result.errors,
    exitCode: result.code
  };
}
```

##### `getInfo(sandbox)`

获取沙盒信息.

```typescript
getInfo: async (sandbox) => {
  return {
    id: sandbox.id,
    status: 'running', // 'running' | 'stopped' | 'error'
    createdAt: new Date(sandbox.created_at)
  };
}
```

##### `getUrl(sandbox, options)`

访问沙盒服务时获取 URL .

```typescript
getUrl: async (sandbox, options) => {
  return `https://${sandbox.id}.example.com:${options.port}`;
}
```

### 可选文件系统方法

通过执行 `filesystem` 方法。 。 。 导入 `escapeShellArg` 从 `@computesdk/provider` 并且总是插入 双引号——帮助者逃脱 `\`, (中文(简体) ), `"`, (中文(简体) ), `$`,并反向缩写,但不包括空格或外壳元体,例如 `;` 财务报告和审定财务报表 `|`,因此未引用的用法会在有空格的路径上断开,对于用户控制的输入来说是不安全的.

```typescript
import { defineProvider, escapeShellArg } from '@computesdk/provider';

// ...

methods: {
  instances: {
    // ... required methods
    
    filesystem: {
      readFile: async (sandbox, path, runCommand) => {
        const result = await runCommand(sandbox, `cat "${escapeShellArg(path)}"`);
        return result.stdout;
      },
      
      writeFile: async (sandbox, path, content, runCommand) => {
        await runCommand(sandbox, `cat > "${escapeShellArg(path)}" << 'EOF'\n${content}\nEOF`);
      },
      
      mkdir: async (sandbox, path, runCommand) => {
        await runCommand(sandbox, `mkdir -p "${escapeShellArg(path)}"`);
      },
      
      readdir: async (sandbox, path, runCommand) => {
        const result = await runCommand(sandbox, `ls -la "${escapeShellArg(path)}"`);
        // Parse ls output and return FileEntry[]
        return parseFileList(result.stdout);
      },
      
      exists: async (sandbox, path, runCommand) => {
        const result = await runCommand(sandbox, `test -e "${escapeShellArg(path)}"`);
        return result.exitCode === 0;
      },
      
      remove: async (sandbox, path, runCommand) => {
        await runCommand(sandbox, `rm -rf "${escapeShellArg(path)}"`);
      }
    }
  }
}
```

**说明:** 如果你不执行 `filesystem`,沙盒仍然会工作,但文件系统操作会抛出有用的"不支持"错误.

## 背景进程和流程

`instance.startProcess(...)` 财务报告和审定财务报表 `runCommand(cmd, { onStdout, onStderr })` 每个供应商的工作。 框架按此顺序选择运行时间:

1.  **土著** - 供应商自己 `streamCommand` 编号 : `startProcess` 钩上 `methods.instances`。 。 。 .
2.  **外壳分级( 默认)** —— POSIX- shell 进程记录只建立在提供者平原上 `runCommand`。节点、守护进程或下載等实例,因此它可以工作在任何图像上 `sh`包括高山和繁忙的盒子.
3.  **守护进程( opt- in)** ——箱式守护进程,仅在提供者配置时 `processRuntime: 'daemond'`数字 :

```typescript
const provider = e2b({ apiKey, processRuntime: 'daemond' });
```

`instance.processRuntime` (b) 报告为每一能力服务的级别,例如:. `{ streaming: 'native', processes: 'shell' }`。 。 。 .

### 贝壳级

每个工作都是目录 `${TMPDIR:-/tmp}/.computesdk/jobs/<jobId>/` (英语:Mode 0700). 一个执行官写工作文件 并派出一名主管 `nohup setsid`;主管通过 FIFOs 将命令在自己的流程组中运行并进行 stdout/stder 运行到被设定的日志中(`out.log`,记录 `O<len>\n…` 编号 : `E<len>\n…` ,然后写 `pid` 财务报告和审定财务报表 `exit`。 。 。 .

-   **读取** (单位:千美元)`status`, (中文(简体) ), `wait`, streaming)是每个执行器一个,取一个字节光标并只返回新输出,每执行器最多为16个日志的KiB(约22个KB Base64,在SSM的24000个字符内置封顶下). `wait` 每名执行官最多25分.
-   **静态** (单位:千美元)`stdin: true`\- 持单人程序保持的FIFO; `write` 是一个执事者, `closeStdin` 杀死持有者.
-   **杀死** 表示整个进程组。 流线 `runCommand`是因为 `timeout` 由监督员在盒子中执行,监督员是SIGKILLL 组(出局码为124),因此,当客户端消失时,最后期限就到了。 无 `timeout` 没有任何东西可以杀死指挥部.
-   **重装**数字 : `instance.attachProcess(jobId)` 在新客户端中重建一个手柄.
-   **保留**:退出后10分钟(杀后60分),工作目录被移除.
-   **执行者共享无状态的实例** (每个命令有一个新鲜的容器,例如Archil磁盘Exec):一个实例上的第一次发射会维持这个命令,直到第二个执行确认工作目录幸存,所以在任何东西运行之前都会发现这个. 在这种情况下,流出 `runCommand` 回到一个简单的执行器,其输出在出口交付 `startProcess` 掷出 `ShellStateNotPersistentError`。 。 。 .
-   **所需资源**数字 : `sh`, (中文(简体) ), `setsid`, (中文(简体) ), `mkfifo`, (中文(简体) ), `kill`, (中文(简体) ), `cat`, (中文(简体) ), `dd`, (中文(简体) ), `wc`, (中文(简体) ), `tail`, (中文(简体) ), `head`, (中文(简体) ), `base64`, (中文(简体) ), `mkdir`, (中文(简体) ), `rm`, (中文(简体) ), `mv`, (中文(简体) ), `sleep`。一个缺失的失败 `ShellProcessUnsupportedError` 点名.

进取路由器( :`CreateInstanceOptions.egress`)留在守护进程上:它的shim是一个节点程序,守护进程靴子是将节点安装在图像上而没有它的东西.

## 类型定义

### 核心类型

```typescript
import type {
  // Provider types
  Provider,
  ProviderConfig,
  ProviderInstance,
  
  // Method definitions
  InstanceMethods,
  TemplateMethods,
  SnapshotMethods,
  
  // Result types
  CodeResult,
  CommandResult,
  InstanceInfo,
  
  // Options
  CreateInstanceOptions,
  RunCommandOptions,
  
  // Filesystem
  FileEntry,
  InstanceFileSystem
} from '@computesdk/provider';
```

### 提供者模式

供应商可以以不同方式运作:

-   **`direct`** - 供应商具有本地沙盒能力(例如E2B、Modal)
-   **`gateway`** - 供应商只有基础设施 -- -- 通过网关的路线

在提供者配置中设置默认模式 :

```typescript
export const myProvider = defineProvider({
  name: 'my-provider',
  defaultMode: 'direct', // or 'gateway'
  methods: { /* ... */ }
});
```

## 完整示例

这里有一个完整的最小提供者执行:

```typescript
import { defineProvider } from '@computesdk/provider';

interface MinimalConfig {
  apiKey: string;
}

export const minimal = defineProvider<any, MinimalConfig>({
  name: 'minimal',
  defaultMode: 'direct',
  methods: {
    instances: {
      create: async (config, options) => {
        const id = `sandbox-${Date.now()}`;
        return {
          instance: { id, status: 'running' },
          instanceId: id
        };
      },
      
      getById: async (config, id) => {
        return {
          instance: { id, status: 'running' },
          instanceId: id
        };
      },
      
      list: async (config) => {
        return [];
      },
      
      destroy: async (config, id) => {
        // Clean up sandbox
      },
      
      runCommand: async (sandbox, command, args) => {
        return {
          stdout: `Ran: ${command} ${args?.join(' ')}`,
          stderr: '',
          exitCode: 0
        };
      },
      
      getInfo: async (sandbox) => {
        return {
          id: sandbox.id,
          status: 'running',
          createdAt: new Date()
        };
      },
      
      getUrl: async (sandbox, options) => {
        return `http://localhost:${options.port}`;
      }
    }
  }
});

// Export factory function
export function createMinimal(config: MinimalConfig) {
  return minimal(config);
}
```

## 供应商包中的使用

一旦您定义了您的供应商, 从您的软件包中导出 :

```typescript
// In @computesdk/my-provider/src/index.ts
import { defineProvider } from '@computesdk/provider';

export const myProvider = defineProvider({ /* ... */ });

// Users can then use it directly
import { myProvider } from '@computesdk/my-provider';

const compute = myProvider({ apiKey: 'xxx' });
const sandbox = await compute.instances.create();
```

## 最佳做法

### 1\. 提前验证配置

```typescript
create: async (config, options) => {
  if (!config.apiKey) {
    throw new Error(
      'Missing API key for my-provider.\n\n' +
      'Setup instructions:\n' +
      '1. Get your API key from https://example.com/keys\n' +
      '2. Set environment variable: export MY_PROVIDER_API_KEY=your_key\n' +
      '3. Or pass it directly: myProvider({ apiKey: "your_key" })'
    );
  }
  
  if (!config.apiKey.startsWith('mp_')) {
    throw new Error(
      'Invalid API key format for my-provider.\n' +
      'API keys should start with "mp_"'
    );
  }
  
  // Continue with creation
}
```

### 2\. 提供帮助错误消息

```typescript
runCommand: async (sandbox, command, args) => {
  try {
    return await yourApi.runCommand(sandbox.id, command, args);
  } catch (error) {
    if (error.code === 'QUOTA_EXCEEDED') {
      throw new Error(
        'API quota exceeded for my-provider.\n' +
        'Upgrade your plan at https://example.com/pricing'
      );
    }
    throw error;
  }
}
```

### 3\. 慷慨地处理缺失的地物

如果您的提供者不支持某些特性:

```typescript
// Don't implement filesystem methods - ComputeSDK will auto-generate
// helpful error messages for users
```

### 4\. 文件提供者 -- -- 具体特点

```typescript
/**
 * My Provider - Fast cloud sandboxes
 * 
 * Features:
 * - Python and Node.js runtimes
 * - Full filesystem support
 * - GPU acceleration (premium plans)
 * - No terminal support
 */
export const myProvider = defineProvider({ /* ... */ });
```

## 测试您的提供者

创建测试以验证您的提供者执行 :

```typescript
import { describe, it, expect } from 'vitest';
import { myProvider } from './index';

describe('MyProvider', () => {
  it('creates and destroys sandboxes', async () => {
    const compute = myProvider({ apiKey: process.env.MY_PROVIDER_API_KEY! });
    
    const sandbox = await compute.instances.create();
    expect(sandbox.instanceId).toBeDefined();
    
    const info = await sandbox.getInfo();
    expect(info.status).toBe('running');
    
    await sandbox.destroy();
  });
  
  it('executes code', async () => {
    const compute = myProvider({ apiKey: process.env.MY_PROVIDER_API_KEY! });
    const sandbox = await compute.instances.create();
    
    const result = await sandbox.runCommand('python -c "print(\"Hello\")"');
    expect(result.stdout).toContain('Hello');
    expect(result.exitCode).toBe(0);
    
    await sandbox.destroy();
  });
});
```

## 实例

参见这些提供者的实施参考:

-   **[@ computesdk/e2b](https://npmcn.com/package/%40computesdk/e2b)** - 拥有文件系统操作的全能提供者
-   **[@ computesdk/ 模式](https://npmcn.com/package/%40computesdk/modal)** - GPU加速Python供应商
-   **[@ computesdk/ daytona (帮助)](https://npmcn.com/package/%40computesdk/daytona)** - 基于工作空间的发展沙盒

## 相关软件包

-   **[计算](https://npmcn.com/package/%40computesdk/computesdk)** - 面向用户的网关SDK
-   **[@ computesdk/e2b](https://npmcn.com/package/%40computesdk/e2b)** - E2B供应商的实施
-   **[@ computesdk/ 模式](https://npmcn.com/package/%40computesdk/modal)** - 模块提供者的落实

## 许可证

麻省理工学院

## 纯标准大小的能力钩

`defineProvider` 接受可选同步 `sizes(config, profile, options)` 钩. 遗产习惯 `Provider` 执行不需要添加此字段。 工厂 供应商暴露出不可改变的 `provider.sizes.list(context?)` 编号 : `resolve(class, context?)` 管理器; 没有钩子报告的适配器 `unknown` 并且否认明白的 `sizeClass` 请求而不是忽略它们。 背景可以包括模式或 平台选择器,但不得合并标准大小控件和本地大小控件.

```ts
sizes: (_config, profile, options) => {
  if (options?.snapshotId) {
    return { status: 'unsupported', reason: 'Restores inherit resource sizing.' };
  }
  // Declare supported only after verifying exact CPU + RAM bounds and semantics.
  return {
    status: 'supported',
    nativeOptions: { vcpus: profile.vcpus, memoryMiB: profile.memoryMiB },
  };
},
```

工厂应用平地并合并已知的命名空间 `instanceOptions.shape` 资源路径 创建选项的副本,条 `sizeClass`,并记录不可更改的请求 元数据为 `instance.sizing`. 虎克必须只返回资源绘图场, 永远不要复制呼叫器 env/metadata/ 授权/通过机构进入补丁 . 这种被捆绑的合并保留了无关的嵌入地,没有被冻结的呼叫器 对象; 它不会递归正态任意创建选项。 标准 资源背景和释放的补丁拒绝不安全的密钥/存取器; 普通和 接受无效原型数据对象。 没有阶级的要求是没有改变的. 业务 `resolution.nativeOptions` 与 `instance.sizing`,哪个 只包含已请求/已解决的CPU/RAM/类和出处. 它们必须是纯的: 没有客户端构建, 证书检查,模板列表, 网络接入、构建或提供。 支持的映射是适配器声明 \* 请求、未计量资源或账户/区域可用性担保. 返回时 `unconfigured`, (中文(简体) ), `unavailable`, (中文(简体) ), `requires-build`, (中文(简体) ), `unknown`,或 `unsupported` 当精确的映射无法宣告时, 没有后退或自动 建设发生。 发现结果被复制并被冻结(包括巢原生地) 选项);调用输入不被冻结或变异.

`createCompute` 保护传统定制供应商 缺乏规模合同. `defineInfraProvider` 目前拒绝标准大小请求为 `unknown`; 其编号 传统本地创建路径不变。 直接调用到手写习惯 提供者仍然是提供者作者的责任.

一个 `InstanceSizeManager` 携带 `contract: 'computesdk.instance-sizes.v1'` 将制作 明确和区分不相关的遗产 `sizes` 属性。 手写 宣布该合同的供应商对实际消费负有责任 `sizeClass` (b) 框架保证: `defineProvider` 适应器. 核心拒绝不兼容/有缺陷的声明.

标准选项、限定的本地资源背景以及释放的补丁使用 假设自己的字符串键数据描述符。 符号/不可假设/接入域 在钩/复制/创建之前拒绝; 带有定义的函数 `sizeClass` 无法 选择退出验证。 失踪/未定义 `sizeClass` 保留遗产通过.

关于源相容性, 基础 `Provider.sizes` 编号 : `DirectProvider.sizes` 是一个 选项 `unknown` 扩展槽:遗留数组、函数或无关对象 即使没有标准要求,仍然可以转让。 使用 `isInstanceSizeManager` 在发现前缩小这个位置. `defineProvider` sDK适配器工厂 仍然返回需要的, 强烈键入 `sizes` 管理器; 缺失/不兼容 运行时合同在创建前仍然拒绝定义的标准请求 .

仅由编译器保存的相容性覆盖包含在本包中 `tsconfig.json` (单位:千美元)`src/**/*`,包括: `src/__tests__/legacy-size-types.ts`) (中文(简体) ). 运行 它明确来自没有网络/安装的工作空间根:

```sh
pnpm exec tsc --noEmit --strict --target es2020 --moduleResolution node --esModuleInterop --skipLibCheck packages/provider/src/__tests__/legacy-size-types.ts
```

一般的模拟套房也运行 `legacy-size-types.test.ts`,引用 已安装此固定线上的 TypeScript 编译器(`--noEmit`; 计 数 fixture 的只类型实例调用从未执行 。 没有安装/ 网络步骤 需要,所以结构后退失败 `pnpm test` 我也一样.

## 常见问题

### @computesdk/provider 是什么？

计算SDK的提供方框架 - 定义自定义的沙盒提供者

### 如何安装 @computesdk/provider？

在项目目录运行 npm install @computesdk/provider，或使用 pnpm add / yarn add / bun add。

### @computesdk/provider 支持 TypeScript 吗？

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

### @computesdk/provider 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @computesdk/provider 可以商用吗？

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

### @computesdk/provider 的下载量有多少？

根据 npm 官方下载统计，@computesdk/provider 在 2026/10/11 – 2026/11/09 这 30 天内被下载 48,359 次，日均约 1,612 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @computesdk/provider 还在维护吗？

最新版本 2\.1\.22 发布于 2026/11/06（4 天前）；至今共发布 59 个版本，其中过去 12 个月发布了 59 个；首次发布于 2026/01/01。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

