Loading...
Loading...
Compare original and translation side by side
reference.mdtroubleshooting.mdexamples/reference.mdtroubleshooting.mdexamples/DISABLE_TUNNELDISABLE_TUNNEL=truerun()FORCE_TUNNELFORCE_TUNNEL=trueendpointUrl/healthDISABLE_TUNNELDISABLE_TUNNEL=truerun()FORCE_TUNNELFORCE_TUNNEL=trueendpointUrl/healthrun()agents-proxy.openserv.aiendpointUrlprovision()provision()agent.instancesetCredentials()run()agents-proxy.openserv.aiprovision()endpointUrlprovision()agent.instancesetCredentials()npm install @openserv-labs/sdk @openserv-labs/client zod openaiNote: The SDK requiresas a peer dependency.openai@^5.x
npm install @openserv-labs/sdk @openserv-labs/client zod openai注意: SDK需要作为对等依赖。openai@^5.x
examples/basic-agent.tsAgentagent.addCapability()provision()agent.instancerun(agent)examples/basic-agent.tsAgentagent.addCapability()provision()agent.instancerun(agent)my-agent/
├── src/agent.ts
├── .env
├── .gitignore
├── package.json
└── tsconfig.jsonmy-agent/
├── src/agent.ts
├── .env
├── .gitignore
├── package.json
└── tsconfig.jsonnpm init -y && npm pkg set type=module
npm i @openserv-labs/sdk @openserv-labs/client dotenv openai zod
npm i -D @types/node tsx typescriptNote: The project must usein"type": "module". Add apackage.jsonscript for local development."dev": "tsx src/agent.ts"
npm init -y && npm pkg set type=module
npm i @openserv-labs/sdk @openserv-labs/client dotenv openai zod
npm i -D @types/node tsx typescript注意: 项目必须在中设置package.json。添加"type": "module"脚本用于本地开发。"dev": "tsx src/agent.ts"
OPENAI_API_KEY=your-openai-keyOPENAI_API_KEY=your-openai-key
---
---namedescriptionschemarunexamples/capability-example.tsnamedescriptionschemarunexamples/capability-example.tsthisaddLogToTask()uploadFile()examples/capability-with-agent-methods.tsthisaddLogToTask()uploadFile()examples/capability-with-agent-methods.tsawait agent.createTask({ workspaceId, assignee, description, body, input, dependencies })
await agent.updateTaskStatus({ workspaceId, taskId, status: 'in-progress' })
await agent.addLogToTask({ workspaceId, taskId, severity: 'info', type: 'text', body: '...' })
await agent.markTaskAsErrored({ workspaceId, taskId, error: 'Something went wrong' })
const task = await agent.getTaskDetail({ workspaceId, taskId })
const tasks = await agent.getTasks({ workspaceId })await agent.createTask({ workspaceId, assignee, description, body, input, dependencies })
await agent.updateTaskStatus({ workspaceId, taskId, status: 'in-progress' })
await agent.addLogToTask({ workspaceId, taskId, severity: 'info', type: 'text', body: '...' })
await agent.markTaskAsErrored({ workspaceId, taskId, error: 'Something went wrong' })
const task = await agent.getTaskDetail({ workspaceId, taskId })
const tasks = await agent.getTasks({ workspaceId })const files = await agent.getFiles({ workspaceId })
await agent.uploadFile({ workspaceId, path: 'output.txt', file: 'content', taskIds: [taskId] })
await agent.deleteFile({ workspaceId, fileId })const files = await agent.getFiles({ workspaceId })
await agent.uploadFile({ workspaceId, path: 'output.txt', file: 'content', taskIds: [taskId] })
await agent.deleteFile({ workspaceId, fileId })actiontask'do-task'action.taskasync run({ args, action }) {
// action.task does NOT exist on all action types — you must narrow first
if (action?.type === 'do-task' && action.task) {
const { workspace, task } = action
workspace.id // Workspace ID
workspace.goal // Workspace goal
task.id // Task ID
task.description // Task description
task.input // Task input
action.me.id // Current agent ID
}
}action?.task?.idProperty 'task' does not exist on type 'ActionSchema'action'do-task'taskaction.taskasync run({ args, action }) {
// action.task并非所有action类型都存在 — 必须先进行类型收窄
if (action?.type === 'do-task' && action.task) {
const { workspace, task } = action
workspace.id // 工作区ID
workspace.goal // 工作区目标
task.id // 任务ID
task.description // 任务描述
task.input // 任务输入
action.me.id // 当前Agent ID
}
}action?.task?.idProperty 'task' does not exist on type 'ActionSchema'workflowprovision()name'Crypto Alpha Scanner''AI Video Studio''Instant Blog Machine'goalworkflow: {
name: 'Haiku Poetry Generator', // Polished display name — the ERC-8004 agent name users see
goal: 'Transform any theme or emotion into a beautiful traditional 5-7-5 haiku poem using AI',
trigger: triggers.x402({ ... }),
task: { description: 'Generate a haiku about the given topic' }
}provision()workflowname'Crypto Alpha Scanner''AI Video Studio''Instant Blog Machine'goalworkflow: {
name: 'Haiku Poetry Generator', // 经过打磨的显示名称 — 用户在ERC-8004中看到的Agent名称
goal: 'Transform any theme or emotion into a beautiful traditional 5-7-5 haiku poem using AI',
trigger: triggers.x402({ ... }),
task: { description: 'Generate a haiku about the given topic' }
}import { triggers } from '@openserv-labs/client'
triggers.webhook({ waitForCompletion: true, timeout: 600 })
triggers.x402({ name: '...', description: '...', price: '0.01', timeout: 600 })
triggers.cron({ schedule: '0 9 * * *' })
triggers.manual()Important: Always setto at least 600 seconds (10 minutes) for webhook and x402 triggers. Agents often take significant time to process requests — especially when performing research, content generation, or other complex tasks. A low timeout will cause premature failures. For multi-agent pipelines with many sequential steps, consider 900 seconds or more.timeout
import { triggers } from '@openserv-labs/client'
triggers.webhook({ waitForCompletion: true, timeout: 600 })
triggers.x402({ name: '...', description: '...', price: '0.01', timeout: 600 })
triggers.cron({ schedule: '0 9 * * *' })
triggers.manual()重要提示: Webhook和x402触发器的请至少设置为600秒(10分钟)。Agent处理请求通常需要较长时间 — 尤其是在执行研究、内容生成或其他复杂任务时。过短的超时会导致任务提前失败。对于包含多个连续步骤的多Agent流水线,建议设置为900秒或更长时间。timeout
npm run devrun()agents-proxy.openserv.airun()run(agent)npm run devrun()agents-proxy.openserv.airun()run(agent)DISABLE_TUNNEL=truerun()await provision({
agent: {
name: 'my-agent',
description: '...',
endpointUrl: 'https://my-agent.example.com' // Required for production
},
workflow: {
name: 'Lightning Service Pro',
goal: 'Describe in detail what this workflow does — be thorough, vague goals cause failures',
trigger: triggers.webhook({ waitForCompletion: true, timeout: 600 }),
task: { description: 'Process incoming requests' }
}
})
// With DISABLE_TUNNEL=true, run() starts only the HTTP server (no tunnel)
await run(agent)DISABLE_TUNNEL=truerun()await provision({
agent: {
name: 'my-agent',
description: '...',
endpointUrl: 'https://my-agent.example.com' // 生产环境必填
},
workflow: {
name: 'Lightning Service Pro',
goal: 'Describe in detail what this workflow does — be thorough, vague goals cause failures',
trigger: triggers.webhook({ waitForCompletion: true, timeout: 600 }),
task: { description: 'Process incoming requests' }
}
})
// 当设置DISABLE_TUNNEL=true时,run()仅启动HTTP服务器(无隧道)
await run(agent)Requires ETH on Base. Registration callson the ERC-8004 contract on Base mainnet (chain 8453), which costs gas. The wallet created byregister()starts with a zero balance. Fund it with a small amount of ETH on Base before the first registration attempt. The wallet address is logged during provisioning (provision()).Created new wallet: 0x...
Always wrap in try/catch so a registration failure (e.g. unfunded wallet) doesn't preventfrom starting.run(agent)
dotenvimport 'dotenv/config'.envprovision()WALLET_PRIVATE_KEYdotenv.config({ override: true })provision()import dotenv from 'dotenv'
dotenv.config()
import { Agent, run } from '@openserv-labs/sdk'
import { provision, triggers, PlatformClient } from '@openserv-labs/client'
// ... define agent and capabilities ...
const result = await provision({
agent: { instance: agent, name: 'my-agent', description: '...' },
workflow: {
name: 'My Service',
goal: 'Detailed description of what the workflow does',
trigger: triggers.x402({ name: 'My Service', description: '...', price: '0.01', timeout: 600 }),
task: { description: 'Process requests' },
},
})
// Reload .env to pick up WALLET_PRIVATE_KEY written by provision()
dotenv.config({ override: true })
// Register on-chain (non-blocking — requires funded wallet on Base)
try {
const client = new PlatformClient()
await client.authenticate(process.env.WALLET_PRIVATE_KEY)
const erc8004 = await client.erc8004.registerOnChain({
workflowId: result.workflowId,
privateKey: process.env.WALLET_PRIVATE_KEY!,
name: 'My Service',
description: 'What this agent does',
})
console.log(`Agent ID: ${erc8004.agentId}`) // "8453:42"
console.log(`TX: ${erc8004.blockExplorerUrl}`)
console.log(`Scan: ${erc8004.scanUrl}`) // "https://www.8004scan.io/agents/base/42"
} catch (error) {
console.warn('ERC-8004 registration skipped:', error instanceof Error ? error.message : error)
}
await run(agent)chainIdrpcUrl需要Base网络的ETH。 注册会调用Base主网(链ID 8453)上ERC-8004合约的方法,需要支付Gas费。register()创建的钱包初始余额为0。首次注册前,请为该钱包充值少量Base网络的ETH。钱包地址会在注册过程中日志输出(provision())。Created new wallet: 0x...
请始终用try/catch包裹,避免注册失败(如钱包未充值)导致无法启动。run(agent)
dotenvimport 'dotenv/config'provision()WALLET_PRIVATE_KEY.envprovision()dotenv.config({ override: true })import dotenv from 'dotenv'
dotenv.config()
import { Agent, run } from '@openserv-labs/sdk'
import { provision, triggers, PlatformClient } from '@openserv-labs/client'
// ... 定义Agent和功能模块 ...
const result = await provision({
agent: { instance: agent, name: 'my-agent', description: '...' },
workflow: {
name: 'My Service',
goal: 'Detailed description of what the workflow does',
trigger: triggers.x402({ name: 'My Service', description: '...', price: '0.01', timeout: 600 }),
task: { description: 'Process requests' },
},
})
// 重新加载.env以获取provision()写入的WALLET_PRIVATE_KEY
dotenv.config({ override: true })
// 链上注册(非阻塞 — 需要Base网络的已充值钱包)
try {
const client = new PlatformClient()
await client.authenticate(process.env.WALLET_PRIVATE_KEY)
const erc8004 = await client.erc8004.registerOnChain({
workflowId: result.workflowId,
privateKey: process.env.WALLET_PRIVATE_KEY!,
name: 'My Service',
description: 'What this agent does',
})
console.log(`Agent ID: ${erc8004.agentId}`) // "8453:42"
console.log(`TX: ${erc8004.blockExplorerUrl}`)
console.log(`Scan: ${erc8004.scanUrl}`) // "https://www.8004scan.io/agents/base/42"
} catch (error) {
console.warn('ERC-8004 registration skipped:', error instanceof Error ? error.message : error)
}
await run(agent)chainIdrpcUrlthis.process()doTaskthis.completeTask()this.process()doTaskthis.completeTask()undefinedundefined
Or reinstall the OpenServ skills directly:
```bash
npx skills add openserv-labs/skills
或直接重新安装OpenServ技能:
```bash
npx skills add openserv-labs/skills