openclaw-zero-token

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenClaw Zero Token

OpenClaw Zero Token

Skill by ara.so — Hermes Skills collection.
OpenClaw Zero Token is a TypeScript-based gateway that lets you use major AI models (Claude, ChatGPT, Gemini, DeepSeek, Qwen, Kimi, Doubao, Grok, GLM, Xiaomi MiMo, Manus) completely free by automating browser-based authentication instead of requiring paid API tokens. It drives official web UIs using Chrome DevTools Protocol (CDP) and Playwright to capture credentials, then proxies requests through a unified OpenAI-compatible API gateway.
ara.so开发的Skill — 属于Hermes Skills集合。
OpenClaw Zero Token是一个基于TypeScript的网关,它通过自动化浏览器身份验证替代付费API令牌,让你可以完全免费使用主流AI模型(Claude、ChatGPT、Gemini、DeepSeek、Qwen、Kimi、Doubao、Grok、GLM、小米MiMo、Manus)。它利用Chrome DevTools Protocol(CDP)和Playwright驱动官方Web UI以捕获凭证,随后通过统一的OpenAI兼容API网关代理请求。

What It Does

功能介绍

  • Zero-cost LLM access: Log in via browser once, reuse credentials for API calls
  • Unified gateway: OpenAI-compatible API endpoint on port 3001
  • 11 web models with tool calling:
    web_search
    ,
    web_fetch
    ,
    exec
    ,
    read
    ,
    write
    ,
    message
  • AskOnce multi-model queries: Broadcast one question to all configured providers
  • Web UI + CLI + Gateway: Multiple interaction modes (Lit 3.x UI, TUI, REST API)
  • 零成本大语言模型访问:通过浏览器登录一次,即可复用凭证进行API调用
  • 统一网关:在3001端口提供OpenAI兼容的API端点
  • 11个支持工具调用的Web模型:支持
    web_search
    web_fetch
    exec
    read
    write
    message
    工具
  • AskOnce多模型查询:将一个问题广播给所有已配置的服务商
  • Web UI + CLI + 网关:多种交互模式(Lit 3.x界面、TUI、REST API)

Supported Providers

支持的服务商

ProviderStatusAuth Method
DeepSeekBrowser login
Qwen (intl/cn)Browser login
KimiBrowser login
Claude WebBrowser login
ChatGPT WebBrowser login
Gemini WebBrowser login
Grok WebBrowser login
DoubaoBrowser login
GLM/GLM IntlBrowser login
Xiaomi MiMoBrowser login
Manus APIAPI key (free)
服务商状态认证方式
DeepSeek浏览器登录
Qwen (国际版/国内版)浏览器登录
Kimi浏览器登录
Claude Web浏览器登录
ChatGPT Web浏览器登录
Gemini Web浏览器登录
Grok Web浏览器登录
Doubao浏览器登录
GLM/GLM国际版浏览器登录
Xiaomi MiMo浏览器登录
Manus APIAPI密钥(免费)

Installation

安装步骤

Prerequisites

前提条件

bash
undefined
bash
undefined

Check versions

检查版本

node --version # >= 22.12.0 pnpm --version # >= 9.0.0
node --version # >= 22.12.0 pnpm --version # >= 9.0.0

Install Node.js 22+ if needed

如需安装Node.js 22+

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt-get install -y nodejs
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt-get install -y nodejs

Install pnpm

安装pnpm

npm install -g pnpm
undefined
npm install -g pnpm
undefined

Clone and Build

克隆并构建

bash
git clone https://github.com/linuxhsj/openclaw-zero-token.git
cd openclaw-zero-token
bash
git clone https://github.com/linuxhsj/openclaw-zero-token.git
cd openclaw-zero-token

Install dependencies

安装依赖

pnpm install
pnpm install

Build backend + frontend

构建后端+前端

pnpm build pnpm ui:build
undefined
pnpm build pnpm ui:build
undefined

Configuration

配置说明

Environment Setup

环境设置

Create
.env
file:
bash
undefined
创建
.env
文件:
bash
undefined

Gateway settings

网关设置

PORT=3001 NODE_ENV=production
PORT=3001 NODE_ENV=production

Browser debugging (DO NOT expose publicly)

浏览器调试(请勿公开暴露)

CHROME_DEBUG_PORT=9222
CHROME_DEBUG_PORT=9222

Optional: workspace for agent file access

可选:Agent文件访问工作区

AGENT_WORKSPACE=/home/user/agent-workspace
AGENT_WORKSPACE=/home/user/agent-workspace

Optional: logging

可选:日志级别

LOG_LEVEL=info
undefined
LOG_LEVEL=info
undefined

First-Time Authentication Flow

首次认证流程

OpenClaw uses a three-step process:
  1. Start debug Chrome → Opens browser on port 9222
  2. Login to web models → Manual browser login (scan QR / password)
  3. Run onboard wizard → Captures credentials automatically
bash
undefined
OpenClaw采用三步流程:
  1. 启动调试Chrome → 在9222端口打开浏览器
  2. 登录Web模型 → 手动在浏览器登录(扫码/密码)
  3. 运行引导向导 → 自动捕获凭证
bash
undefined

Terminal 1: Start Chrome in debug mode (keep running)

终端1:启动调试模式的Chrome(保持运行)

./start-chrome-debug.sh
./start-chrome-debug.sh

This opens Chrome with tabs for:

这会打开Chrome并加载以下标签页:

- Qwen intl: https://hf.co/chat

- Qwen国际版: https://hf.co/chat

etc.

LOG IN to each site manually in the browser

在浏览器中手动登录每个站点


```bash

```bash

Terminal 2: Run authentication wizard

终端2:运行认证向导

./onboard.sh webauth
./onboard.sh webauth

Interactive menu:

交互式菜单:

[1] deepseek-web

[1] deepseek-web

[2] qwen-web

[2] qwen-web

[3] qwen-cn

[3] qwen-cn

[4] kimi

[4] kimi

[5] claude-web

[5] claude-web

... etc

... 等

Select provider → wizard captures auth automatically

选择服务商 → 向导自动捕获认证信息

Saved to: data/auth/<provider>.json

保存至:data/auth/<provider>.json


The `onboard.sh` script uses Playwright CDP to intercept network requests and extract:
- Cookies
- Bearer tokens
- User-Agent headers

`onboard.sh`脚本使用Playwright CDP拦截网络请求并提取:
- Cookies
- Bearer令牌
- User-Agent请求头

Starting the Gateway

启动网关

bash
undefined
bash
undefined

Start server (daemon mode)

启动服务器(守护进程模式)

./server.sh start
./server.sh start

Other commands

其他命令

./server.sh stop ./server.sh restart ./server.sh status
./server.sh stop ./server.sh restart ./server.sh status

Manual start (foreground, for debugging)

手动启动(前台模式,用于调试)

pnpm start

Gateway runs on **http://localhost:3001** with OpenAI-compatible endpoints.
pnpm start

网关运行在**http://localhost:3001**,提供OpenAI兼容的端点。

Key Commands and Scripts

核心命令与脚本

Core Scripts

核心脚本

ScriptPurpose
./start-chrome-debug.sh
Launch Chrome on port 9222 for logins
./onboard.sh webauth
Run auth wizard to capture credentials
`./server.sh [startstop]`
pnpm build
Build TypeScript backend
pnpm ui:build
Build Lit 3.x frontend
pnpm test
Run test suite
脚本用途
./start-chrome-debug.sh
启动9222端口的Chrome用于登录
./onboard.sh webauth
运行认证向导捕获凭证
`./server.sh [startstop]`
pnpm build
构建TypeScript后端
pnpm ui:build
构建Lit 3.x前端
pnpm test
运行测试套件

pnpm Scripts (package.json)

pnpm脚本(package.json)

bash
undefined
bash
undefined

Build

构建

pnpm build # Compile TypeScript pnpm ui:build # Build frontend pnpm build:all # Both backend + UI
pnpm build # 编译TypeScript pnpm ui:build # 构建前端 pnpm build:all # 同时构建后端+UI

Development

开发

pnpm dev # Watch mode with hot reload pnpm start # Production server
pnpm dev # 热重载监听模式 pnpm start # 生产环境服务器

Testing

测试

pnpm test # Run tests pnpm lint # ESLint check pnpm format # Prettier format
undefined
pnpm test # 运行测试 pnpm lint # ESLint检查 pnpm format # Prettier格式化
undefined

API Usage

API使用方法

OpenAI-Compatible Endpoints

OpenAI兼容端点

OpenClaw exposes a standard OpenAI API format on port 3001:
bash
undefined
OpenClaw在3001端口暴露标准OpenAI API格式:
bash
undefined

List available models

列出可用模型

Chat completion (non-streaming)

聊天补全(非流式)

curl http://localhost:3001/v1/chat/completions
-H "Content-Type: application/json"
-d '{ "model": "deepseek-web/deepseek-chat", "messages": [{"role": "user", "content": "Hello!"}] }'
curl http://localhost:3001/v1/chat/completions
-H "Content-Type: application/json"
-d '{ "model": "deepseek-web/deepseek-chat", "messages": [{"role": "user", "content": "Hello!"}] }'

Streaming

流式响应

curl http://localhost:3001/v1/chat/completions
-H "Content-Type: application/json"
-d '{ "model": "qwen-web/qwen-turbo", "messages": [{"role": "user", "content": "Count to 5"}], "stream": true }'
undefined
curl http://localhost:3001/v1/chat/completions
-H "Content-Type: application/json"
-d '{ "model": "qwen-web/qwen-turbo", "messages": [{"role": "user", "content": "Count to 5"}], "stream": true }'
undefined

TypeScript Client Example

TypeScript客户端示例

typescript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:3001/v1',
  apiKey: 'not-needed', // Zero Token doesn't require keys
});

async function chat() {
  const response = await client.chat.completions.create({
    model: 'deepseek-web/deepseek-chat',
    messages: [
      { role: 'user', content: 'Explain TypeScript generics' }
    ],
  });

  console.log(response.choices[0].message.content);
}

chat();
typescript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'http://localhost:3001/v1',
  apiKey: 'not-needed', // Zero Token无需密钥
});

async function chat() {
  const response = await client.chat.completions.create({
    model: 'deepseek-web/deepseek-chat',
    messages: [
      { role: 'user', content: 'Explain TypeScript generics' }
    ],
  });

  console.log(response.choices[0].message.content);
}

chat();

Streaming Response

流式响应示例

typescript
async function streamChat() {
  const stream = await client.chat.completions.create({
    model: 'kimi/moonshot-v1-8k',
    messages: [{ role: 'user', content: 'Write a haiku' }],
    stream: true,
  });

  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '');
  }
}
typescript
async function streamChat() {
  const stream = await client.chat.completions.create({
    model: 'kimi/moonshot-v1-8k',
    messages: [{ role: 'user', content: 'Write a haiku' }],
    stream: true,
  });

  for await (const chunk of stream) {
    process.stdout.write(chunk.choices[0]?.delta?.content || '');
  }
}

Tool Calling (Web Models)

Web模型工具调用

OpenClaw injects tool definitions into prompts for 11/13 web models. Tools are only injected when user message contains keywords like "search", "read", "execute".
OpenClaw会为11/13个Web模型在提示词中注入工具定义。仅当用户消息包含"search"、"read"、"execute"等关键词时,才会注入工具。

Available Tools

可用工具

ToolFunctionProvider Support
web_search
DuckDuckGo search11/13 models
web_fetch
Fetch webpage content11/13 models
exec
Execute shell command11/13 models
read
Read file (workspace restricted)11/13 models
write
Write file (workspace restricted)11/13 models
message
Structured output11/13 models
工具功能服务商支持
web_search
DuckDuckGo搜索11/13个模型
web_fetch
获取网页内容11/13个模型
exec
执行Shell命令11/13个模型
read
读取文件(限制在工作区内)11/13个模型
write
写入文件(限制在工作区内)11/13个模型
message
结构化输出11/13个模型

Tool Calling Example

工具调用示例

typescript
const response = await client.chat.completions.create({
  model: 'deepseek-web/deepseek-chat',
  messages: [{
    role: 'user',
    content: 'Search for TypeScript 5.4 release notes and summarize'
  }],
});

// Model automatically:
// 1. Detects "search" keyword
// 2. Calls web_search tool
// 3. Fetches results
// 4. Summarizes content
typescript
const response = await client.chat.completions.create({
  model: 'deepseek-web/deepseek-chat',
  messages: [{
    role: 'user',
    content: 'Search for TypeScript 5.4 release notes and summarize'
  }],
});

// 模型会自动:
// 1. 检测到"search"关键词
// 2. 调用web_search工具
// 3. 获取搜索结果
// 4. 总结内容

Agent File Access Configuration

Agent文件访问配置

Tools like
read
/
write
are restricted to the configured workspace:
bash
undefined
read
/
write
等工具被限制在已配置的工作区内:
bash
undefined

In .env

在.env中设置

AGENT_WORKSPACE=/home/user/projects/safe-zone

```typescript
// Attempting to read outside workspace fails
const badRead = await client.chat.completions.create({
  model: 'kimi/moonshot-v1-32k',
  messages: [{
    role: 'user',
    content: 'Read /etc/passwd'  // ❌ Blocked
  }],
});

// Within workspace succeeds
const goodRead = await client.chat.completions.create({
  model: 'kimi/moonshot-v1-32k',
  messages: [{
    role: 'user',
    content: 'Read project-notes.md'  // ✅ Allowed if in workspace
  }],
});
AGENT_WORKSPACE=/home/user/projects/safe-zone

```typescript

AskOnce: Multi-Model Queries

尝试读取工作区外的文件会失败

Query all configured providers simultaneously:
bash
undefined
const badRead = await client.chat.completions.create({ model: 'kimi/moonshot-v1-32k', messages: [{ role: 'user', content: 'Read /etc/passwd' // ❌ 被阻止 }], });

CLI usage (if implemented)

在工作区内读取则成功

pnpm ask-once "What is the capital of France?"
const goodRead = await client.chat.completions.create({ model: 'kimi/moonshot-v1-32k', messages: [{ role: 'user', content: 'Read project-notes.md' // ✅ 若在工作区内则允许 }], });
undefined

Returns responses from:

AskOnce:多模型查询

- DeepSeek: "Paris..."

- Qwen: "The capital is Paris..."

- Kimi: "Paris, established in..."

etc.


```typescript
// Programmatic AskOnce
import { askOnce } from './src/zero-token/ask-once';

const results = await askOnce({
  query: 'Explain quantum entanglement in one sentence',
  providers: ['deepseek-web', 'qwen-web', 'kimi', 'claude-web'],
});

results.forEach(({ provider, response, duration }) => {
  console.log(`[${provider}] (${duration}ms): ${response}`);
});
同时向所有已配置的服务商发起查询:
bash
undefined

Common Patterns

CLI使用(若已实现)

1. Multi-Provider Failover

typescript
const providers = [
  'deepseek-web/deepseek-chat',
  'qwen-web/qwen-turbo',
  'kimi/moonshot-v1-8k',
];

async function chatWithFailover(message: string) {
  for (const model of providers) {
    try {
      const response = await client.chat.completions.create({
        model,
        messages: [{ role: 'user', content: message }],
      });
      return response.choices[0].message.content;
    } catch (error) {
      console.warn(`${model} failed, trying next...`);
    }
  }
  throw new Error('All providers failed');
}
pnpm ask-once "What is the capital of France?"

2. Model Routing by Task

返回以下服务商的响应:

- DeepSeek: "Paris..."

- Qwen: "The capital is Paris..."

- Kimi: "Paris, established in..."

typescript
function selectModel(task: string): string {
  if (task.includes('reasoning') || task.includes('logic')) {
    return 'deepseek-web/deepseek-reasoner';
  }
  if (task.includes('code')) {
    return 'qwen-web/qwen-plus';
  }
  return 'kimi/moonshot-v1-8k'; // default
}

const model = selectModel('Write a sorting algorithm');
const response = await client.chat.completions.create({
  model,
  messages: [{ role: 'user', content: 'Implement quicksort in Python' }],
});

```typescript

3. Workspace-Safe Agent

程序化调用AskOnce

typescript
import * as path from 'path';

const WORKSPACE = process.env.AGENT_WORKSPACE || '/tmp/agent-workspace';

async function safeAgentTask(instruction: string) {
  // Ensure workspace exists
  await fs.promises.mkdir(WORKSPACE, { recursive: true });

  const response = await client.chat.completions.create({
    model: 'kimi/moonshot-v1-32k',
    messages: [{
      role: 'system',
      content: `You are a helpful agent. All file operations must be within ${WORKSPACE}.`
    }, {
      role: 'user',
      content: instruction
    }],
  });

  return response.choices[0].message.content;
}

// Example: "Create a file notes.txt with today's date"
await safeAgentTask('Write the current timestamp to notes.txt');
import { askOnce } from './src/zero-token/ask-once';
const results = await askOnce({ query: 'Explain quantum entanglement in one sentence', providers: ['deepseek-web', 'qwen-web', 'kimi', 'claude-web'], });
results.forEach(({ provider, response, duration }) => { console.log(
[${provider}] (${duration}ms): ${response}
); });
undefined

4. Re-authentication Helper

常见使用模式

1. 多服务商故障转移

typescript
import { execSync } from 'child_process';

async function ensureAuth(provider: string) {
  const authPath = `data/auth/${provider}.json`;
  
  try {
    const authData = await fs.promises.readFile(authPath, 'utf-8');
    const parsed = JSON.parse(authData);
    
    // Check if token is expired (example logic)
    if (Date.now() > parsed.expiresAt) {
      console.log(`Auth expired for ${provider}, re-running onboard...`);
      execSync(`./onboard.sh webauth ${provider}`, { stdio: 'inherit' });
    }
  } catch (error) {
    console.log(`No auth found for ${provider}, running onboard...`);
    execSync(`./onboard.sh webauth ${provider}`, { stdio: 'inherit' });
  }
}

// Before making API calls
await ensureAuth('deepseek-web');
typescript
const providers = [
  'deepseek-web/deepseek-chat',
  'qwen-web/qwen-turbo',
  'kimi/moonshot-v1-8k',
];

async function chatWithFailover(message: string) {
  for (const model of providers) {
    try {
      const response = await client.chat.completions.create({
        model,
        messages: [{ role: 'user', content: message }],
      });
      return response.choices[0].message.content;
    } catch (error) {
      console.warn(`${model}调用失败,尝试下一个...`);
    }
  }
  throw new Error('所有服务商均调用失败');
}

Troubleshooting

2. 按任务路由模型

Chrome Debug Port Issues

Symptom:
onboard.sh
fails with "Cannot connect to CDP"
bash
undefined
typescript
function selectModel(task: string): string {
  if (task.includes('reasoning') || task.includes('logic')) {
    return 'deepseek-web/deepseek-reasoner';
  }
  if (task.includes('code')) {
    return 'qwen-web/qwen-plus';
  }
  return 'kimi/moonshot-v1-8k'; // 默认模型
}

const model = selectModel('Write a sorting algorithm');
const response = await client.chat.completions.create({
  model,
  messages: [{ role: 'user', content: 'Implement quicksort in Python' }],
});

Kill existing Chrome processes

3. 工作区安全Agent

pkill -f "chrome.*remote-debugging-port=9222"
typescript
import * as path from 'path';

const WORKSPACE = process.env.AGENT_WORKSPACE || '/tmp/agent-workspace';

async function safeAgentTask(instruction: string) {
  // 确保工作区存在
  await fs.promises.mkdir(WORKSPACE, { recursive: true });

  const response = await client.chat.completions.create({
    model: 'kimi/moonshot-v1-32k',
    messages: [{
      role: 'system',
      content: `你是一个乐于助人的Agent。所有文件操作必须在${WORKSPACE}目录内。`
    }, {
      role: 'user',
      content: instruction
    }],
  });

  return response.choices[0].message.content;
}

// 示例:"Create a file notes.txt with today's date"
await safeAgentTask('Write the current timestamp to notes.txt');

Restart debug Chrome

4. 重新认证助手

./start-chrome-debug.sh
typescript
import { execSync } from 'child_process';

async function ensureAuth(provider: string) {
  const authPath = `data/auth/${provider}.json`;
  
  try {
    const authData = await fs.promises.readFile(authPath, 'utf-8');
    const parsed = JSON.parse(authData);
    
    // 检查令牌是否过期(示例逻辑)
    if (Date.now() > parsed.expiresAt) {
      console.log(`${provider}的认证已过期,重新运行引导向导...`);
      execSync(`./onboard.sh webauth ${provider}`, { stdio: 'inherit' });
    }
  } catch (error) {
    console.log(`未找到${provider}的认证信息,运行引导向导...`);
    execSync(`./onboard.sh webauth ${provider}`, { stdio: 'inherit' });
  }
}

// 在发起API调用前执行
await ensureAuth('deepseek-web');

Verify port is open

故障排查

Chrome调试端口问题

lsof -i :9222 # Should show Chrome process
undefined
症状
onboard.sh
报错"Cannot connect to CDP"
bash
undefined

Authentication Expired

终止现有Chrome进程

Symptom: API calls return 401/403 after initial setup
bash
undefined
pkill -f "chrome.*remote-debugging-port=9222"

Re-run onboarding for specific provider

重启调试Chrome

./onboard.sh webauth
./start-chrome-debug.sh

Select the provider that's failing

验证端口是否开放

Example: [1] deepseek-web

Manually verify in browser:

1. Open http://localhost:9222 in another browser

2. Navigate to chat site

3. Check if logged in

undefined
lsof -i :9222 # 应显示Chrome进程
undefined

Stream Parsing Errors

认证过期

Symptom: "Cannot parse SSE stream" for Doubao or Gemini
typescript
// Use non-streaming for unstable providers
const response = await client.chat.completions.create({
  model: 'doubao/doubao-pro',
  messages: [{ role: 'user', content: 'Hello' }],
  stream: false,  // ← Disable streaming
});
症状:初始设置后API调用返回401/403
bash
undefined

Tool Calling Not Triggering

重新运行特定服务商的引导向导

Symptom: Model doesn't use tools despite keyword in message
typescript
// Ensure keywords are explicit
const response = await client.chat.completions.create({
  model: 'kimi/moonshot-v1-32k',
  messages: [{
    role: 'user',
    content: 'SEARCH for TypeScript 5.4 release notes'  // ← Explicit keyword
  }],
});

// Check middleware logs
// Tool injection only happens when keywords detected:
// "search", "fetch", "execute", "read file", "write file"
./onboard.sh webauth

Gateway Won't Start

选择出现故障的服务商

示例:[1] deepseek-web

在浏览器中手动验证:

1. 在另一个浏览器中打开http://localhost:9222

2. 导航至聊天站点

3. 检查是否已登录

bash
undefined
undefined

Check if port 3001 is already in use

流解析错误

lsof -i :3001
症状:Doubao或Gemini出现"Cannot parse SSE stream"
typescript
undefined

Kill existing process

对不稳定的服务商使用非流式响应

kill -9 $(lsof -t -i :3001)
const response = await client.chat.completions.create({ model: 'doubao/doubao-pro', messages: [{ role: 'user', content: 'Hello' }], stream: false, // ← 禁用流式响应 });
undefined

Check logs

工具调用未触发

tail -f logs/gateway.log
症状:尽管消息中有关键词,模型仍未使用工具
typescript
undefined

Verify build succeeded

确保关键词明确

pnpm build pnpm ui:build
undefined
const response = await client.chat.completions.create({ model: 'kimi/moonshot-v1-32k', messages: [{ role: 'user', content: 'SEARCH for TypeScript 5.4 release notes' // ← 明确关键词 }], });

Model Rate Limits

检查中间件日志

仅当检测到以下关键词时才会注入工具:

"search"、"fetch"、"execute"、"read file"、"write file"

Symptom: Web model returns "Too many requests"
typescript
// Implement exponential backoff
async function chatWithRetry(model: string, message: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      return await client.chat.completions.create({
        model,
        messages: [{ role: 'user', content: message }],
      });
    } catch (error: any) {
      if (error.status === 429 && i < retries - 1) {
        const delay = Math.pow(2, i) * 1000;
        console.log(`Rate limited, waiting ${delay}ms...`);
        await new Promise(resolve => setTimeout(resolve, delay));
      } else {
        throw error;
      }
    }
  }
}
undefined

Advanced Configuration

网关无法启动

Custom Provider Setup

typescript
// src/zero-token/providers/custom-provider.ts
import { BaseWebProvider } from './base-web-provider';

export class CustomProvider extends BaseWebProvider {
  constructor() {
    super({
      name: 'custom-web',
      chatUrl: 'https://custom-ai.example.com/chat',
      apiEndpoint: 'https://custom-ai.example.com/api/v1/chat',
    });
  }

  async authenticate(page: Page): Promise<AuthData> {
    // Custom auth logic
    const token = await page.evaluate(() => {
      return localStorage.getItem('auth_token');
    });
    
    return {
      token,
      cookies: await page.context().cookies(),
      userAgent: await page.evaluate(() => navigator.userAgent),
    };
  }
}
bash
undefined

Environment Variables Reference

检查3001端口是否已被占用

bash
undefined
lsof -i :3001

Core settings

终止现有进程

PORT=3001 # Gateway port NODE_ENV=production # production | development LOG_LEVEL=info # error | warn | info | debug
kill -9 $(lsof -t -i :3001)

Browser automation

查看日志

CHROME_DEBUG_PORT=9222 # CDP port HEADLESS=false # true for headless mode
tail -f logs/gateway.log

Agent configuration

验证构建是否成功

AGENT_WORKSPACE=/path/to/workspace # Tool file access restriction TOOL_TIMEOUT=30000 # Tool execution timeout (ms)
pnpm build pnpm ui:build
undefined

Provider-specific (optional)

模型速率限制

DEEPSEEK_CUSTOM_ENDPOINT=https://... # Override default endpoints QWEN_API_VERSION=v1 # API version
undefined
症状:Web模型返回"Too many requests"
typescript
undefined

File Structure

实现指数退避

openclaw-zero-token/
├── src/
│   ├── zero-token/
│   │   ├── providers/          # Web model implementations
│   │   │   ├── deepseek-web.ts
│   │   │   ├── qwen-web.ts
│   │   │   ├── kimi.ts
│   │   │   └── ...
│   │   ├── tool-calling/       # Tool injection middleware
│   │   │   ├── tools.ts        # Tool definitions
│   │   │   └── middleware.ts   # Prompt injection logic
│   │   ├── ask-once/           # Multi-model query system
│   │   └── auth/               # Authentication capture
│   ├── gateway/                # OpenAI-compatible API gateway
│   └── ui/                     # Lit 3.x web interface
├── data/
│   └── auth/                   # Stored credentials (gitignored)
│       ├── deepseek-web.json
│       ├── qwen-web.json
│       └── ...
├── scripts/
│   ├── start-chrome-debug.sh   # Chrome launcher
│   ├── onboard.sh              # Auth wizard
│   └── server.sh               # Gateway daemon manager
├── .env                        # Environment config
└── package.json
async function chatWithRetry(model: string, message: string, retries = 3) { for (let i = 0; i < retries; i++) { try { return await client.chat.completions.create({ model, messages: [{ role: 'user', content: message }], }); } catch (error: any) { if (error.status === 429 && i < retries - 1) { const delay = Math.pow(2, i) * 1000; console.log(
触发速率限制,等待${delay}ms...
); await new Promise(resolve => setTimeout(resolve, delay)); } else { throw error; } } } }
undefined

Security Notes

高级配置

自定义服务商设置

  1. Auth Data:
    data/auth/*.json
    contains sensitive credentials — never commit
  2. Chrome Debug Port: Port 9222 allows full browser control — DO NOT expose externally
  3. Workspace Restriction: Agent file tools are sandboxed to
    AGENT_WORKSPACE
  4. HTTPS Required: Use reverse proxy (nginx/Caddy) for production deployment
Example nginx config:
nginx
server {
  listen 443 ssl;
  server_name openclaw.example.com;
  
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  
  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
  }
}
typescript
// src/zero-token/providers/custom-provider.ts
import { BaseWebProvider } from './base-web-provider';

export class CustomProvider extends BaseWebProvider {
  constructor() {
    super({
      name: 'custom-web',
      chatUrl: 'https://custom-ai.example.com/chat',
      apiEndpoint: 'https://custom-ai.example.com/api/v1/chat',
    });
  }

  async authenticate(page: Page): Promise<AuthData> {
    // 自定义认证逻辑
    const token = await page.evaluate(() => {
      return localStorage.getItem('auth_token');
    });
    
    return {
      token,
      cookies: await page.context().cookies(),
      userAgent: await page.evaluate(() => navigator.userAgent),
    };
  }
}

References

环境变量参考

核心设置

PORT=3001 # 网关端口 NODE_ENV=production # production | development LOG_LEVEL=info # error | warn | info | debug

浏览器自动化

CHROME_DEBUG_PORT=9222 # CDP端口 HEADLESS=false # 无头模式设为true

Agent配置

AGENT_WORKSPACE=/path/to/workspace # 工具文件访问限制目录 TOOL_TIMEOUT=30000 # 工具执行超时时间(毫秒)

服务商特定配置(可选)

DEEPSEEK_CUSTOM_ENDPOINT=https://... # 覆盖默认端点 QWEN_API_VERSION=v1 # API版本
undefined

文件结构

openclaw-zero-token/
├── src/
│   ├── zero-token/
│   │   ├── providers/          # Web模型实现
│   │   │   ├── deepseek-web.ts
│   │   │   ├── qwen-web.ts
│   │   │   ├── kimi.ts
│   │   │   └── ...
│   │   ├── tool-calling/       # 工具注入中间件
│   │   │   ├── tools.ts        # 工具定义
│   │   │   └── middleware.ts   # 提示词注入逻辑
│   │   ├── ask-once/           # 多模型查询系统
│   │   └── auth/               # 认证捕获模块
│   ├── gateway/                # OpenAI兼容API网关
│   └── ui/                     # Lit 3.x Web界面
├── data/
│   └── auth/                   # 存储的凭证(已加入git忽略)
│       ├── deepseek-web.json
│       ├── qwen-web.json
│       └── ...
├── scripts/
│   ├── start-chrome-debug.sh   # Chrome启动脚本
│   ├── onboard.sh              # 认证向导脚本
│   └── server.sh               # 网关守护进程管理脚本
├── .env                        # 环境配置文件
└── package.json

安全注意事项

  1. 认证数据
    data/auth/*.json
    包含敏感凭证——切勿提交至代码仓库
  2. Chrome调试端口:9222端口允许完全控制浏览器——请勿对外暴露
  3. 工作区限制:Agent文件工具被沙箱限制在
    AGENT_WORKSPACE
    目录内
  4. 需使用HTTPS:生产部署时请使用反向代理(nginx/Caddy)
示例nginx配置:
nginx
server {
  listen 443 ssl;
  server_name openclaw.example.com;
  
  ssl_certificate /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;
  
  location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host $host;
  }
}

参考链接