工具接入接口文档
工具接入接口文档
适用范围
这份文档面向 2026-04-17 已落地的工具插件架构。适合平台管理员、外部工具开发者和站内工具开发者按统一协议接入 tripai / NextDevTpl。
后台导入
先在 /admin/tool-config 导入工具定义,再补管理员默认配置
统一能力
用户、积分、AI、存储、审计统一复用平台能力
外部工具协议
外部服务使用 launch_ticket、runtime token 和 platform API
接入模式
适合只想复用平台账号体系、后台配置和入口管理的工具。
推荐做法:
- 导入工具定义
- 配好字段
- 入口指向外部地址或内部页面
适合主要依赖统一 AI 网关的工具。
推荐做法:
- 导入工具定义
- 配置
features - 在
/admin/ai绑定模型和 provider
适合前后端独立部署的产品。
推荐做法:
authMode = launch_ticket- 平台生成启动票据
- 外部服务端用
runtime token换用户身份并读取配置
适合像 RedInk 这样有专属页面、专属流程和专属适配层的工具。
推荐做法:
- 工具业务逻辑放工具模块
- 用户、AI、积分、存储仍走平台统一能力
接入前提
平台侧
平台已部署,数据库迁移完成,/admin/tool-config、/admin/ai、/admin/storage 可正常访问
工具侧
明确 toolKey、入口类型、是否要用户配置、积分、AI、存储、外部票据
外部工具额外要求
必须有自己的服务端,用来安全保存 runtime token,不能把 token 暴露给浏览器
命名约定
Prop
Type
标准接入流程
管理员进入 /zh/admin/tool-config,导入工具定义 JSON
在 /zh/admin/tool-config 填管理员默认配置、密钥和 JSON 字段
如果工具需要 AI,去 /zh/admin/ai 给 feature 绑定模型和 provider
如果工具要上传资源,去 /zh/admin/storage 检查对象存储和前缀规则
如果工具允许用户个人覆盖配置,到 /zh/dashboard/settings 验证字段是否按预期暴露
如果工具是外部服务,再串联 launch_ticket、session/exchange、runtime、runtime-save
手机号认证(AutoLive 等工具)
平台已支持手机号 + 密码登录;注册与改密使用短信验证码。外部工具不要在客户端直连 TripAI /api/auth/*,应由工具服务端 Relay:
- 登录:
POST /v1/auth/platform/exchangebody{ phone, password, device, licenseKey? } - 注册发码:
POST /v1/auth/phone/send-otp→ 平台phone-number/send-otp - 注册:
POST /v1/auth/phone/registerbody{ phone, code, password, name?, licenseKey?, device }— 无licenseKey时仍可完成平台注册并返回 token,响应含requiresLicenseActivation: true,客户端再调POST /v1/license/activate - 忘记密码:
POST /v1/auth/phone/password-reset/request→POST /v1/auth/phone/password-reset/confirm
平台侧对应:sign-in/phone-number、/api/platform/auth/phone/register、phone-number/request-password-reset、reset-password。
详见 docs/phone-auth-integration-plan-2026-05-22.html(2026-05-23 修订)。
工具定义结构
后台导入和接口导入使用同一结构
你在 /admin/tool-config 页面顶部粘贴的 JSON,和 POST /api/platform/tools/import 接口请求体中的 definition 完全一致。
{
"toolKey": "notes-ai",
"name": "Notes AI",
"description": "会议纪要和知识整理工具",
"entry": {
"type": "external_url",
"url": "https://notes.tripai.icu"
},
"runtimeMode": "platform_api",
"authMode": "launch_ticket",
"billingMode": "ai_gateway",
"storageMode": "platform_storage",
"capabilities": {
"adminConfig": true,
"userConfig": true,
"credits": true,
"ai": true,
"storage": true
},
"enabled": true,
"sortOrder": 60,
"fields": [
{
"fieldKey": "config1",
"label": "notes.defaultTone",
"description": "默认输出风格",
"group": "config",
"type": "select",
"adminOnly": true,
"userOverridable": false,
"defaultValueJson": "formal",
"optionsJson": ["formal", "concise", "friendly"]
},
{
"fieldKey": "secret1",
"label": "notes.webhookSecret",
"description": "外部回调签名密钥",
"group": "secret",
"type": "secret",
"adminOnly": true,
"userOverridable": false
},
{
"fieldKey": "json1",
"label": "notes.templateCatalog",
"description": "模板目录",
"group": "json",
"type": "json",
"adminOnly": true,
"userOverridable": false,
"defaultValueJson": {
"summary": "会议总结",
"todo": "待办提取"
}
}
],
"features": [
{
"featureKey": "meeting_summary",
"name": "会议总结",
"description": "生成会议纪要",
"requestType": "chat",
"defaultOperation": "text.generate",
"requiredCapabilities": ["text"],
"enabled": true,
"sortOrder": 10,
"pricing": {
"billingMode": "token_based",
"minimumCredits": 1,
"inputTokensPerCredit": 1000,
"outputTokensPerCredit": 500
}
}
],
"storage": {
"prefixRules": [
{
"prefix": "notes-ai/attachments/",
"purpose": "attachment",
"retentionClass": "temporary",
"ttlHours": 72,
"enabled": true,
"maxSizeBytes": 10485760,
"contentTypes": ["application/pdf", "image/png", "image/jpeg"]
}
]
}
}关键字段说明
元数据字段
Prop
Type
字段定义
Prop
Type
功能定义
Prop
Type
常用平台接口
1. 会话与账户
GET /api/platform/session
返回当前登录用户、套餐和积分余额。
{
"success": true,
"user": {
"id": "user_xxx",
"name": "Alice",
"email": "alice@example.com",
"phoneNumber": "+8613812345678",
"primaryContact": "+8613812345678",
"primaryContactType": "phone",
"emailIsPlaceholder": false,
"canReceiveEmail": true,
"image": null,
"role": "user"
},
"plan": {
"code": "pro",
"name": "Pro",
"hasActiveSubscription": true
},
"credits": {
"balance": 520,
"status": "active"
}
}2. 积分
POST /api/platform/credits/check
{
"amount": 3
}POST /api/platform/credits/consume
{
"amount": 3,
"serviceName": "notes_ai_summary",
"description": "生成会议纪要",
"metadata": {
"tool": "notes-ai",
"feature": "meeting_summary"
}
}POST /api/platform/credits/delegated/check
外部工具服务端用 runtime token 代表指定平台用户检查积分。请求头必须带:
Authorization: Bearer <runtime-token>该 token 必须属于请求里的 projectKey + tool,并拥有 credits:read scope。
{
"projectKey": "nextdevtpl",
"tool": "autolive",
"userId": "user_xxx",
"amount": 3
}POST /api/platform/credits/delegated/consume
外部工具服务端用 runtime token 代表指定平台用户消费积分。请求头必须带:
Authorization: Bearer <runtime-token>该 token 必须属于请求里的 projectKey + tool,并拥有 credits:consume scope。
{
"projectKey": "nextdevtpl",
"tool": "autolive",
"userId": "user_xxx",
"amount": 3,
"serviceName": "autolive:reply",
"description": "直播回复扣费",
"metadata": {
"sessionId": "live_xxx",
"replyId": "reply_xxx"
}
}2.1 autolive-server 当前配置
autolive-server 是外部 Go 服务,NextDevTpl 侧按数据库工具配置接入。
当前约定:
- project key:
nextdevtpl - tool key:
autolive - 显示名:
autolive-server - 入口类型:
external_url - 本地入口:
http://127.0.0.1:8080 - 认证方式:
launch_ticket - AI feature:
live-reply(直播互动)、script-draft(AI 帮写) - TTS feature:
live-tts - AI provider:
geekai - 默认模型:
gemini-2.5-flash - TTS provider:
bailian-tts或fishaudio - TTS 默认模型:
cosyvoice-v3-flash或对应 Fish Audio TTS model - 计费方式:固定
1积分 / 次
autolive-server 需要的环境变量:
$env:TRIPAI_BASE_URL="http://127.0.0.1:3000"
$env:TRIPAI_PROJECT_KEY="nextdevtpl"
$env:TRIPAI_TOOL_KEY="autolive"
$env:TRIPAI_RUNTIME_TOKEN="<tool_runtime_token>"
$env:TRIPAI_AI_API_KEY="<api_key>"
$env:TRIPAI_AI_TOOL_KEY="autolive"
$env:TRIPAI_AI_FEATURE_KEY="live-reply"
$env:TRIPAI_SCRIPT_DRAFT_FEATURE_KEY="script-draft"
$env:TRIPAI_TTS_FEATURE_KEY="live-tts"TRIPAI_RUNTIME_TOKEN 至少需要:
runtime:readruntime:writesession:exchangecredits:readcredits:consume
TRIPAI_AI_API_KEY 建议限制:
- allowed tools:
["autolive"] - allowed models:
["gemini-2.5-flash"]
密钥保存
明文 runtime token 和 API key 只在生成时可见,不要写入仓库文档、提交记录或前端代码。
3. AI 网关
POST /api/platform/ai/chat
{
"tool": "notes-ai",
"feature": "meeting_summary",
"input": "请整理这段会议记录"
}{
"tool": "notes-ai",
"feature": "meeting_summary",
"messages": [
{
"role": "system",
"content": "你是会议纪要助手"
},
{
"role": "user",
"content": "请总结下面内容"
}
],
"model": "gpt-4o-mini",
"operation": "text.generate"
}支持的常见 operation:
text.generateimage.understandimage.generateimage.editvideo.understandvideo.generateaudio.understandaudio.generatefile.understand
GET /api/platform/ai/chat/result?requestId=...
用于查询任务型 AI 结果。
POST /api/platform/ai/tts
用于真正的 TTS/语音合成请求。当前网关会按 provider 分流到真实上游:
- Fish Audio:
POST https://api.fish.audio/v1/tts - 阿里百炼 CosyVoice:
POST https://dashscope.aliyuncs.com/api/v1/services/audio/tts/SpeechSynthesizer
最小请求:
{
"tool": "autolive",
"feature": "live-tts",
"input": "欢迎来到直播间",
"model": "cosyvoice-v3-flash",
"voice": "longxiaochun",
"format": "mp3",
"sampleRate": 44100
}POST /api/platform/ai/voice-enrollment/ensure
幂等确保 CosyVoice 复刻音色已注册(多部署共享 enrollmentKey)。首次调用需 reference.referenceUrl;已存在且上游仍有效时只校验并返回已有 providerVoiceId。
{
"tool": "autolive",
"feature": "voice-clone",
"enrollmentKey": "tripai:nextdevtpl:autolive:preset:zxlive_5262",
"targetModel": "cosyvoice-v3-flash",
"reference": { "referenceUrl": "https://cdn.example.com/ref.wav" },
"prefix": "autolive",
"metadata": { "presetId": "zxlive_5262", "kind": "cloned_preset" }
}POST /api/platform/ai/voice-clone
百炼 CosyVoice 声音复刻必须走独立入口,不再复用 /api/platform/ai/chat。
{
"tool": "autolive",
"feature": "voice-clone",
"action": "create",
"targetModel": "cosyvoice-v3-flash",
"prefix": "autolive",
"reference": {
"referenceUrl": "https://cdn.example.com/autolive/voices/user_1/ref/demo.wav"
},
"languageHints": ["zh"]
}成功响应示例:
{
"success": true,
"requestId": "air_vc_001",
"providerVoiceId": "cosyvoice-v3-flash-autolive-xxx",
"status": "ready",
"demoUrl": null,
"billing": {
"chargedCredits": 10,
"remainingBalance": 90
}
}成功响应会统一返回 output.audio:
- 百炼 / CosyVoice 通常返回
output.audio.url - Fish Audio 通常返回
output.audio.data(Base64)和output.audio.mimeType sampleRate当前仅对百炼 / CosyVoice 生效;传给其他 TTS provider 会直接返回 4xx,而不会再被静默忽略
4. 用户配置
GET /api/platform/tool-config/editor?projectKey=nextdevtpl&tool=notes-ai
读取用户侧可见配置表单。
POST /api/platform/tool-config/user
{
"projectKey": "nextdevtpl",
"tool": "notes-ai",
"values": {
"config2": "friendly"
},
"clearSecrets": []
}5. 对象存储
POST /api/platform/storage/presigned-image
{
"filename": "cover.png",
"contentType": "image/png",
"toolKey": "notes-ai",
"purpose": "attachment",
"retentionClass": "temporary",
"requestId": "req_xxx"
}6. 结果归档
POST /api/platform/results/save
{
"tool": "notes-ai",
"type": "meeting_summary",
"payload": {
"title": "周会纪要",
"content": "..."
},
"requestId": "req_xxx"
}外部工具接入协议
外部工具的核心原则
浏览器不应该直接持有 runtime token。正确做法是:平台前端拿一次性 ticket,外部工具服务端持有 runtime token 去换用户身份和读写配置。
启动时序
平台前端调用 GET /api/platform/tools/{toolKey}/launch
平台拿到 ticket 和 launchUrl 后跳转到外部工具
外部工具服务端用 POST /api/platform/tools/session/exchange 换到当前用户
外部工具服务端再调用 runtime / runtime-save 读取和写回工具配置
GET /api/platform/tools/{toolKey}/launch
成功响应示例:
{
"success": true,
"tool": "notes-ai",
"ticket": "ticket_xxx",
"launchUrl": "https://notes.tripai.icu?ticket=ticket_xxx&projectKey=nextdevtpl",
"expiresAt": "2026-04-17T10:30:00.000Z"
}POST /api/platform/tools/session/exchange
请求头:
Authorization: Bearer <runtime-token>请求体:
{
"projectKey": "nextdevtpl",
"tool": "notes-ai",
"ticket": "ticket_xxx"
}成功响应:
{
"success": true,
"toolKey": "notes-ai",
"user": {
"id": "user_xxx",
"name": "Alice",
"email": "alice@example.com"
},
"expiresAt": "2026-04-17T10:35:00.000Z"
}POST /api/platform/tool-config/runtime
请求头:
Authorization: Bearer <runtime-token>请求体:
{
"projectKey": "nextdevtpl",
"tool": "notes-ai",
"userId": "user_xxx",
"knownRevision": 12
}POST /api/platform/tool-config/runtime-save
请求头:
Authorization: Bearer <runtime-token>请求体:
{
"projectKey": "nextdevtpl",
"tool": "notes-ai",
"userId": "user_xxx",
"values": {
"config2": "friendly"
},
"clearSecrets": []
}GET /api/platform/tool-config/revision?projectKey=nextdevtpl&tool=notes-ai
请求头:
Authorization: Bearer <runtime-token>用途:
- 只读取版本号
- 适合检测配置是否变化
管理后台接口
GET /api/platform/tools
读取工具状态列表、最近导入、最近 AI 请求和运行时访问情况
POST /api/platform/tools/import
导入一份新的工具定义
POST /api/platform/tools/{toolKey}/disable
停用工具但保留历史记录
POST /api/platform/tools/{toolKey}/rollback
回滚最近一次工具定义变更
推荐联调顺序
先完成工具定义导入,不要先写接口调用
先把后台默认配置、密钥和 JSON 字段填完整
再绑定 AI provider 和模型
再验证上传和对象存储前缀
再打通外部票据和运行时配置
最后串联完整业务流:AI、积分、归档、错误处理
常见失败原因
- 只导入了工具定义,没有补后台默认配置
- AI 功能没有在
/admin/ai绑定模型 - 工具被停用
- 字段被设置成
adminOnly = true - 没开
userOverridable = true
authMode不是launch_ticketruntime token没有session:exchange权限- 外部工具扣积分时,
runtime token没有credits:read或credits:consume权限 - 启动票据过期或已被消费
toolKey传错purpose传错- 后台没有对应的工具存储规则
一句话结论
推荐做法
新工具接入时,先导入工具定义,再补管理员配置,再绑定 AI 和存储,最后按是否为外部服务决定是否接 launch_ticket 和运行时接口。不要反过来做。
