ExtSkill guide (extended skills)
ExtSkill guide (extended skills)
⚠️ Not yet released: in-development v1.5.0-SNAPSHOT capability; interface and protocol may change. Do not use in production before the official release.
New in v1.5.0. ExtSkill = extended skills: the application attaches custom skills to an agent, then at runtime first
querythe list of extended skills currently available on that agent, andinvokeone of them to run. It sits alongside passive / active / teleop, using its own event family and theAgentPolicy.EXT_SKILLpolicy (wire value"extskill").
When to use
- The application has configured extended skills for an agent on the LinkSoul platform (weather lookup, ticket creation, device control, etc.) and needs to discover the list at runtime and trigger them on demand.
- You need to bypass the dialogue chain and call a deterministic capability directly (structured input, structured output) instead of LLM free-form generation.
- One
invokereturns in three stages:onInvokeAckfirst (gateway accepted the request), thenonStatefor execution-time progress reports (optional), thenonInvokeResult(the skill's actual execution output).
Flow
After registerExtSkill, call query to fetch the list and invoke to trigger execution any number of times; unregisterExtSkill to release when done.
┌─────────────────────────────┐
│ ExtSkillRequest.query │ fetch available extended-skill list
│ (onQueryResult) │
└─────────────────────────────┘
┌─────────────────────────────┐
│ ExtSkillRequest.invoke │ trigger a skill to run
│ (onInvokeAck) │ ← stage 1: gateway accepted
│ (onState) │ ← stage 2: execution-time state report (0..n)
│ (onInvokeResult) │ ← stage 3: execution output
└─────────────────────────────┘
queryreturns once viaonQueryResult; whencode == 0,resultcarries the skill list and related content.invokereturns in three stages:onInvokeAck(accept), thenonState(execution-time progress reported viaagentsdk.ext_skill.report_state, zero or more times), thenonInvokeResult(output;paramcarries the result whencode == 0).- If the SDK connection is already closed at send time, the
query/invokecallback fires synchronously on the calling thread once withcode == 1000+msg == "Agentsdk connection is closed".
Event family & protocol
Event types live in com.agibot.aiem.sdk.enums.AgentEventType:
| Enum member | Event type string | Meaning |
|---|---|---|
AGENTSDK_EXT_SKILL_QUERY | agentsdk.ext_skill.query | Query available extended skills (SDK → gateway) |
AGENTSDK_EXT_SKILL_QUERY_RESULT | agentsdk.ext_skill.query_result | Query result (gateway → SDK) |
AGENTSDK_EXT_SKILL_INVOKE | agentsdk.ext_skill.invoke | Trigger a skill (SDK → gateway) |
AGENTSDK_EXT_SKILL_INVOKE_ACK | agentsdk.ext_skill.invoke_ack | Accept receipt (gateway → SDK) |
AGENTSDK_EXT_SKILL_REPORT_STATE | agentsdk.ext_skill.report_state | Execution-time state report (gateway → SDK) |
AGENTSDK_EXT_SKILL_INVOKE_RESULT | agentsdk.ext_skill.invoke_result | Execution result (gateway → SDK) |
Wire structure of every ExtSkill message:
{
"type": "<event type>",
"agentId": "<target agent agentId>",
"eventId": "event_xxxxxxxxxxxxxxxxxxxxx",
"agentMode": "extskill",
"requestId": "extskill_xxxxxxxxxxxxxxxxxxxxx"
}
- Unlike Teleop (which uses
sn), ExtSkill usesagentIdas the agent identity field. requestIdcomes fromIdGenerator.generateExtSkillRequestId(); it is the identity of one extended-skill session and is reused byquery/invoke.invokeadditionally carriesextSkillId(the skill to trigger) andinput(flat input key-values, matchinginput.getExtParam()).agentModeis always"extskill"(matchingAgentPolicy.EXT_SKILL).
invoke input
The input of invoke(extSkillId, input, callback, timeout) is an AgentParam carrying the skill's structured input; the exact keys are defined by the skill. Example:
AgentParam input = AgentParam.create()
.setString("city", "shanghai")
.setInteger("days", 3);
String eventId = extSkillRequest.invoke("skill_weather", input, invokeCallback, 2000);
It is sent as flat key-values on the wire (input.city / input.days), matching input.getExtParam().
Result codes
The code of query / invoke callbacks is uniform:
code | Meaning |
|---|---|
0 | Success (result / param carries returned content) |
-1 | Server returned failure; msg carries errorMsg |
1000 | Local failure: LinkskyClient was closed at send time; the SDK invokes this code synchronously on the calling thread |
When code != 0, both result (in onQueryResult) and param (in onInvokeResult) are null.
API at a glance
- Request class:
com.agibot.aiem.sdk.extskill.ExtSkillRequest - Callback base classes:
ExtSkillQueryCallback(onQueryResult) /ExtSkillInvokeCallback(onInvokeAck+onState+onInvokeResult) - Registration:
AgentSdk.registerExtSkill(ExtSkillRequest)/AgentSdk.unregisterExtSkill(requestId) - ID:
IdGenerator.generateExtSkillRequestId()
Full signatures in ExtSkill API. Runnable example in ExtSkill examples.
Lifecycle & cleanup
AgentSdkExtSkillMgrtracks active requests byrequestId; you mustregisterExtSkill(...)before callingquery/invoke.- Each request method call refreshes the internal
updateTs; a request idle for more than 7200s is reclaimed by the background cleanup thread. - When done, call
agentSdk.unregisterExtSkill(requestId)to release explicitly. AgentSdk.release()also clears all ExtSkill requests owned by that instance.
ExtSkill vs. Teleop
| Aspect | Teleop | ExtSkill |
|---|---|---|
| Policy | AgentPolicy.TELEOP ("teleop") | AgentPolicy.EXT_SKILL ("extskill") |
| Identity fields | sn + teleopId | agentId + requestId |
| Core actions | enter / audio / keepalive / exit | query / invoke |
| Result model | single ACK | query: single result; invoke: three stages (ack + state + result) |