扩展技能(ExtSkill)示例 · JS / 浏览器
扩展技能(ExtSkill)示例 · JS / 浏览器
⚠️ 尚未上线:本能力为 v1.5.0-SNAPSHOT 开发中特性,接口与协议可能调整,正式发布前请勿用于生产环境。
v1.5.0 新增。本页给出浏览器端扩展技能的最小可读 TypeScript 示例,展示
query(拉取清单)与invoke(触发执行,两段回执)全流程。
最小示例:查询 + 触发
ts
import { createAgentSdk, AgentEventType } from 'linksoul-agentsdk';
const appId = '您通过灵心开放平台创建的应用获取的appId';
const agentId = '您通过灵心平台创建的二开智能体获取的agentId';
const upstreamUrl = 'wss://open.agibot.com/api/V1/open-portal/app/wss/agent-sdk';
let sdk = createAgentSdk(appId, {
authProvider: async () => {
const res = await fetch('/api/ws-auth', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ url: upstreamUrl, appId }),
});
return { url: (await res.json()).url };
},
reconnect: true,
});
// 监听下行结果
sdk.on('message', ({ data }) => {
let msg;
try { msg = JSON.parse(typeof data === 'string' ? data : ''); } catch { return; }
switch (msg.type) {
case AgentEventType.ExtSkillQueryResult:
if (msg.code === 0) {
console.log('可用技能清单:', msg.output);
// 拿到清单后触发某个技能
doInvoke();
} else {
console.error('query 失败:', msg.code, msg.message);
}
break;
case AgentEventType.ExtSkillInvokeAck:
console.log('invoke 已受理, code =', msg.code, ', eventId =', msg.eventId);
break;
case AgentEventType.ExtSkillInvokeResult:
if (msg.code === 0) {
console.log('技能执行结果:', msg.output);
} else {
console.error('invoke 执行失败:', msg.code, msg.message);
}
break;
}
});
await sdk.connect();
// 创建 ExtSkill 会话
const session = sdk.createExtSkillSession({ agentId });
console.log('requestId =', session.requestId);
// 查询可用技能清单
const queryEventId = session.query();
console.log('query eventId =', queryEventId);
// 触发技能执行
function doInvoke() {
const invokeEventId = session.invoke('skill_weather', {
city: 'shanghai',
days: 3,
});
console.log('invoke eventId =', invokeEventId);
}
带错误处理的完整示例
ts
import { createAgentSdk, AgentEventType } from 'linksoul-agentsdk';
import type { ExtSkillQueryResult, ExtSkillInvokeAck } from 'linksoul-agentsdk';
const appId = '<appId>';
const agentId = '<agentId>';
const upstreamUrl = 'wss://open.agibot.com/api/V1/open-portal/app/wss/agent-sdk';
const sdk = createAgentSdk(appId, {
authProvider: async () => {
const res = await fetch('/api/ws-auth', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ url: upstreamUrl, appId }),
});
if (!res.ok) throw new Error(`auth failed: ${res.status}`);
return { url: (await res.json()).url };
},
reconnect: true,
});
sdk.on('connected', () => {
console.log('SDK 已连接,可以发送请求');
});
sdk.on('disconnected', ({ willReconnect }) => {
console.log('SDK 断开, willReconnect =', willReconnect);
});
sdk.on('message', ({ data }) => {
let msg: Record<string, unknown>;
try { msg = JSON.parse(typeof data === 'string' ? data : ''); } catch { return; }
switch (msg.type) {
case AgentEventType.ExtSkillQueryResult: {
const result = msg as unknown as ExtSkillQueryResult;
if (result.code === 0) {
console.log('技能清单:', result.output);
} else {
console.error(`query 失败 [code=${result.code}]:`, result.message);
}
break;
}
case AgentEventType.ExtSkillInvokeAck: {
const ack = msg as unknown as ExtSkillInvokeAck;
if (ack.code !== 0) {
console.error(`invoke 受理失败 [code=${ack.code}]:`, ack.message);
}
break;
}
case AgentEventType.ExtSkillInvokeResult: {
const result = msg as unknown as ExtSkillQueryResult; // 形状相同
if (result.code === 0) {
console.log('执行输出:', result.output);
} else {
console.error(`invoke 执行失败 [code=${result.code}]:`, result.message);
}
break;
}
}
});
await sdk.connect();
const session = sdk.createExtSkillSession({ agentId });
// 安全调用:确保连接后再发送
try {
session.query();
} catch (err) {
console.error('发送失败(可能未连接):', err);
}
常见改写要点
| 想做 | 改哪里 |
|---|---|
| 只拉清单不触发 | 只调 session.query(),在 message 里处理 ExtSkillQueryResult 即可 |
| 触发不同技能 | 换 invoke 的第一个参数 extSkillId |
| 传结构化入参 | invoke('skill_id', { key: value });wire 上以 input 对象原样下发 |
| 只关心最终结果 | ExtSkillInvokeAck 只记日志;真正输出在 ExtSkillInvokeResult 的 output(code === 0 时) |
| 感知 SDK 断连 | sdk.on('disconnected') / sdk.on('connected');未连接时 send 抛错,不会静默丢失 |
| 多智能体并行 | 每个 agentId 建一个 ExtSkillSession(各自独立 requestId);复用同一 AgentSdk 连接 |
| 区分同一智能体的多次会话 | 手动传入 requestId:sdk.createExtSkillSession({ agentId, requestId: 'my_session_1' }) |