Troubleshooting & FAQ (Java v1.4.0)
Troubleshooting & FAQ (Java v1.4.0)
This document grows over time. Add new pitfalls or common questions as they surface. It has two parts:
- Troubleshooting manual — organised as symptom → diagnosis → fix, for locating and resolving concrete failures.
- FAQ (Q&A) — organised as question → answer, for concept, usage, and boundary questions.
1. Troubleshooting manual
When adding new entries, follow the four-part shape symptom / possible cause / how to diagnose / fix so problems can be located quickly.
1.1 WebSocket connection is closed by the server immediately
- Symptom: the connection drops right after
AgentSdk.create(...)returns; no callbacks fire. - Possible causes:
- You are still pointing at the pre-v1.4.0 gateway
wss://agentsdk.agibot.com/v1/agentsdk, which no longer accepts traffic in v1.4.0. - You are still calling the pre-v1.4.0 three-arg
AgentSdk.create(url, appId, appSecret)(missingappKey).
- You are still pointing at the pre-v1.4.0 gateway
- Diagnose: verify the
urlargument and thecreate()overload used are the v1.4.0 versions. - Fix:
- Switch the gateway to
wss://open.agibot.com/api/V1/open-portal/app/wss/agent-sdk. - Switch the call to
AgentSdk.create(url, appId, appKey, appSecret). - See the CHANGELOG for the full migration checklist.
- Switch the gateway to
1.2 Auth failure / 401 or 403 at handshake
- Symptom: the WebSocket handshake returns 401 / 403, or logs show a signature check failure.
- Possible causes:
appId/appKey/appSecretare not from the same application (e.g. legacy custom-agent template credentials mixed in).- Client-side clock drift is too large, so
X-Timestampfails the server-side window check. - A custom proxy or gateway strips or drops the five v1.4.0 auth headers (
X-App-Id/X-App-Key/X-Timestamp/X-Nonce/X-Signature).
- Diagnose:
- Verify all three values come from the same LinkSoul open-platform application.
- Run
date -uand compare against network time. - Capture the outbound request and confirm all five
X-*headers are present.
- Fix: reissue credentials from the same application, sync the clock, and repair proxy header forwarding.
1.3 X-Callback-Types header rejected / callbacks silent
- Symptom: the handshake succeeds, but subscribed passive callbacks (e.g.
Audio2Llm) never fire. - Possible causes:
- In v1.4.0
callbackTypesmoved out of the JWT payload into a standaloneX-Callback-Typesrequest header, and its value must be a JSON array string (e.g.["AUDIO_2_LLM"]). - A custom proxy is dropping this header.
- In v1.4.0
- Diagnose: capture the request and confirm
X-Callback-Typesis present and well-formed. - Fix: correct the header value or the proxy forwarding. See Enums Reference for the valid callback-type identifiers.
1.4 AgentSdk.registerXxx(...) no longer compiles
- Symptom: the compiler reports missing symbols for
registerStateListen/registerPushListen/querySkill/queryState/registerPullStream. - Possible cause: these methods were removed or merged in v1.4.0.
- Fix:
- State updates are now delivered through the shared
PassiveCallback.onState(...)— no separate registration needed. - The only public active surface is task flow (
registerTaskFlow/unregisterTaskFlow). - See the CHANGELOG and the Active Operations Guide for the migration path.
- State updates are now delivered through the shared
For error codes and reconnect strategy see Error Handling.
2. FAQ (Q&A)
When adding new entries, start with Q / A, keep the answer short and link out when a deeper reference exists — this keeps the FAQ from drifting into a full guide.
Q1. Are pre-v1.4.0 credentials or gateway URLs compatible?
A: No. v1.4.0 moved to LinkSoul open-platform application credentials, a new gateway, and an HMAC-SHA256 signing scheme with five signed headers — none of that is backward compatible. Upgrading requires reissuing credentials, switching the gateway URL, updating the create() call, and rewriting custom auth-header handling. Full checklist in the CHANGELOG.
Q2. Where do I get appId / appKey / appSecret?
A: Log in to the LinkSoul open platform, create an application, and all three values are issued together. They must be used as a set — legacy custom-agent template credentials are no longer accepted in v1.4.0.
Q3. Do I need to sign requests myself?
A: No. AgentSdk.create(url, appId, appKey, appSecret) builds the signature and headers internally. Hand-rolling the signature only matters if a custom proxy needs to replay it; the signing recipe is in the breaking-change table of the CHANGELOG.
Q4. Can a single SDK instance subscribe to multiple passive callback types?
A: Yes. v1.4.0 narrows the public passive-callback set to eight types (Audio2Llm / Audio2Tts / Asr2Llm / Asr2Tts / AsrVideo2Vlm / AsrVideo2Tts / AudioVideo2Vlm / AudioVideo2Tts); register as many as you need. See Enums Reference for the identifiers and Passive Examples for usage.
Q5. Why is the whole interaction pipeline streaming? What's the difference between streaming and non-streaming?
A: AgentSDK's device-side pipeline is streaming end-to-end:
- ASR audio input flows up frame by frame from the robot into the SDK;
- ASR / LLM / TTS results flow down incrementally as
onXxxDelta(partial chunk) +onXxxDone(end marker) events, rather than being returned in one shot after the entire result is ready.
The win is produce-and-consume in parallel: the robot can start speaking or move on to the next step before recognition / generation / synthesis has fully finished, which visibly shortens end-to-end latency and improves the response speed and interaction experience. A non-streaming design would have to wait for the whole result before returning, so the user-perceived wait time grows accordingly.
Q6. How does the 二开-series AgentSDK differ from a traditional HTTP API?
A: Different goals. A traditional API (e.g. HTTP REST) is a stateless, one-shot request/response call — single-frame request, single-frame response, synchronous, self-contained context. AgentSDK is built for device-side multimodal robot interaction and is a long-lived (WebSocket, full-duplex) + fully-time-series model. Four core differences:
- Shape: an interaction is not "one request in, one response out" but two time series — audio frames flow up (ASR input is itself a stream), and ASR / LLM / VLM / TTS results plus robot-state updates flow down as incremental
onXxxDelta+onXxxDoneevents. - Timing: request and response are fully asynchronous. Frames within the same
eventIdare ordered (guaranteed by the SDK's per-agent thread pool); upstream stages still have a fixed order — LLM only starts producing deltas after ASR emits itsonXxxDone— but as soon as LLM streams out its first chunk of text, TTS begins synthesising that chunk and flushing audio frames in parallel with LLM's subsequent deltas. - Direction: bidirectional. The robot pushes upstream (8 passive callbacks: ASR / LLM / VLM / TTS results, robot state, face / voiceprint, greetings…) and the SDK also pushes downstream (task flow) — no longer a single client → server direction.
- Control: interruption is first-class (
response.onInterrupt(eventId, interruptType, interruptTips)) — you can cancel or replace the current response while it is still streaming, which has no direct analogue in a synchronous API.
In one line: a traditional API is a point-to-point one-shot Q&A; AgentSDK is a bidirectional, asynchronous, eventId-anchored temporal dialogue. The integrator's mental model shifts accordingly — from "build a request / parse a response" to "subscribe to callbacks, stitch the time series, decide when to interrupt or move on". For threading and reconnection see Architecture; for the two interaction modes see the Passive Callbacks Guide and Active Operations Guide.