扩展技能(ExtSkill)示例 · iOS

扩展技能(ExtSkill)示例 · iOS

⚠️ 尚未上线:本能力为 v1.5.0-SNAPSHOT 开发中特性,接口与协议可能调整,正式发布前请勿用于生产环境。

v1.5.0 新增。iOS 端最小示例,展示 query(拉取清单)与 invoke(触发执行,三段回调:ack → state → result)全流程。iOS SDK 暂无独立的 ExtSkill 示例源文件,以下为内联完整代码。

最小示例

swift
import Foundation
import LinksoulAgentSDK

// ExtSkill: query → invoke (onInvokeAck + onInvokeResult)

let url = "wss://open.agibot.com/api/V1/open-portal/app/wss/agent-sdk"
let appId = "您通过灵心开放平台创建的应用获取的appId"
let appKey = "您通过灵心开放平台创建的应用获取的appKey"
let appSecret = "您通过灵心开放平台创建的应用获取的appSecret"
let agentId = "您通过灵心平台创建的二开智能体获取的agentId"

// 第一步:创建 SDK 实例
let agentSdk = AgentSdk.create(url: url, appId: appId, appKey: appKey, appSecret: appSecret)

// 第二步:注册验签回调
final class AuthCallback: AgentAuthCallback {
    func onAuthState(appId: String, code: Int, msg: String) {
        print("onAuthState => appId: \(appId), code: \(code), msg: \(msg)")
    }
}
agentSdk.registerAuth(AuthCallback())
agentSdk.initialize()

Thread.sleep(forTimeInterval: 2.0)

// 第三步:注册扩展技能请求实例
let requestId = IdGenerator.generateExtSkillRequestId()
let extSkillRequest = ExtSkillRequest(agentSdk: agentSdk, agentId: agentId, requestId: requestId)
agentSdk.registerExtSkill(extSkillRequest)

// 3.1 查询可用扩展技能清单
final class QueryCallback: ExtSkillQueryCallback {
    override func onQueryResult(agentId: String, requestId: String, eventId: String,
                                code: Int, msg: String?, result: AgentParam?) {
        print("onQueryResult => agentId \(agentId), requestId \(requestId), "
            + "eventId \(eventId), code \(code), msg \(msg ?? ""), result \(String(describing: result))")
    }
}
let queryEventId = extSkillRequest.query(queryCallback: QueryCallback(), timeout: 2000)
print("query queryEventId \(queryEventId)")

// 3.2 触发某个扩展技能执行
let extSkillId = "test_ext_skill_id_001"           // 扩展技能 ID
let input = AgentParam.create()                    // 扩展技能入参
    .setString("role", "male")
    .setInt("threshold", 0)

final class InvokeCallback: ExtSkillInvokeCallback {
    override func onInvokeAck(agentId: String, requestId: String, eventId: String,
                              code: Int, msg: String?) {
        // 第一段:网关已受理
        print("onInvokeAck => agentId \(agentId), requestId \(requestId), "
            + "eventId \(eventId), code \(code), msg \(msg ?? "")")
    }

    override func onState(agentId: String, requestId: String, eventId: String,
                          stateName: String?, stateValue: String?) {
        // 第二段:执行期间状态上报(0 到多次)
        print("onState => agentId \(agentId), requestId \(requestId), "
            + "eventId \(eventId), stateName \(stateName ?? ""), stateValue \(stateValue ?? "")")
    }

    override func onInvokeResult(agentId: String, requestId: String, eventId: String,
                                 code: Int, msg: String?, param: AgentParam?) {
        // 第三段:技能执行输出
        print("onInvokeResult => agentId \(agentId), requestId \(requestId), "
            + "eventId \(eventId), code \(code), msg \(msg ?? ""), param \(String(describing: param))")
    }
}
let invokeEventId = extSkillRequest.invoke(
    extSkillId: extSkillId, input: input,
    invokeCallback: InvokeCallback(), timeout: 2000)
print("invoke invokeEventId \(invokeEventId)")

Thread.sleep(forTimeInterval: 5.0)

// 第四步:反注册释放
agentSdk.unregisterExtSkill(requestId: requestId)
// agentSdk.release()

RunLoop.main.run()

常见改写要点

想做改哪里
只拉清单不触发只调 query(...),拿到 onQueryResult 的 result 即可;invoke 可省略
触发不同技能换 invoke 的 extSkillId 参数;input 按目标技能定义填 AgentParam
传结构化入参AgentParam.create().setString(...).setInt(...);wire 上以扁平键值下发
只关心最终结果onInvokeAck 可只记日志;真正输出在 onInvokeResult 的 param(code == 0 时非空)
感知 SDK 鉴权 / 断连query / invoke 回调收到 code == 1000 表示本地连接已关闭,应重连后重试
多智能体并行每个 agentId 建一个 ExtSkillRequest(各自独立 requestId);SDK 按 requestId 索引,互不冲突

关于 RunLoop.main.run()

命令行 target 需要显式保活主线程,否则进程会在最后一行代码执行完之后立刻退出。iOS App target 由 UIApplication 自带 runloop,无需此调用;SwiftUI / UIKit 页面直接把回调 UI 更新切到 DispatchQueue.main.async 即可。