116 lines
5.5 KiB
Markdown
116 lines
5.5 KiB
Markdown
# Troubleshooting
|
|
|
|
Diagnose configuration, protocol events, execution and playback separately.
|
|
Use [architecture](architecture.md), [tool calling](tool-calling.md) and
|
|
[context injection](context-injection.md) to identify which path is active.
|
|
|
|
## Check configuration and connection first
|
|
|
|
Inspect the server configuration without printing secret environment files:
|
|
|
|
```bash
|
|
curl -fsS http://localhost:8420/api/config | jq
|
|
```
|
|
|
|
Confirm `s2sUrl`, `lb`, `reasoningType`, `injectProfile`, `apipilot`, `theme`
|
|
and `startSessionMode`. A direct WebSocket URL bypasses the local relay's
|
|
server-side context injection and marker execution. For a local proxy, confirm
|
|
the server can resolve and reach `S2S_PROXY_TARGET`.
|
|
|
|
In browser DevTools, inspect the WebSocket handshake and `session.created`,
|
|
`session.update` and error events. Check that instructions and native tools are
|
|
inside `session`. A cached browser module can disagree with current server
|
|
code; inspect served asset versions and reload with cache disabled when needed.
|
|
|
|
## The assistant promises a tool but nothing happens
|
|
|
|
Follow the actual execution mechanism:
|
|
|
|
1. For a native tool, confirm it appears in the outbound `session.tools` array.
|
|
2. Find `response.function_call_arguments.done` with a tool name, `call_id`, and
|
|
JSON-string arguments.
|
|
3. Confirm the browser dispatched `toolcall` and the executor sent its request.
|
|
4. Confirm `function_call_output` and any required `response.create` were sent.
|
|
5. For ApiPilot, inspect discovery, marker detection, authorization/schema
|
|
validation, execution, and second-pass result injection instead.
|
|
|
|
A spoken sentence such as “Voy a buscar el reporte” does not satisfy step 2.
|
|
If the function-call event is absent, inspect model/backend tool generation
|
|
before debugging a browser executor that has not been invoked.
|
|
|
|
Earlier local debug notes recorded a reproduction where tools and required
|
|
tool policy were sent but the model produced only spoken text. Those notes
|
|
refer to the retired MCP ranking path; they do not establish a current ApiPilot
|
|
failure. Both local investigation notes remain marked `OPEN`. Their useful
|
|
lesson is to collect evidence at each boundary and reproduce against current
|
|
code before claiming a root cause is resolved.
|
|
|
|
## The assistant misses caller or report context
|
|
|
|
- Verify the page has an encoded `phoneNumber` or the intended `episode_id`.
|
|
- Inspect `/api/user/phone` and context-fetch logs for HTTP/JSON failures.
|
|
- Confirm profile injection is enabled; a visible profile alone does not prove
|
|
realtime instructions contain it.
|
|
- Reports need `S2S_INJECT_REPORTS=true`; `minimal` sends only labels and dates.
|
|
A historical script will not be in the prompt in that mode.
|
|
- Static summary text overrides the HTTP summary endpoint.
|
|
- Inspect the final `session.update` rather than only its browser base prompt.
|
|
The proxy can append and deduplicate context after the browser sends it.
|
|
|
|
`S2S_DEBUG_PROMPT=true` enables complete prompt logs, including caller information
|
|
and conversation text. Use summaries when full payloads are unnecessary. The
|
|
browser's application functions are module-scoped; do not assume names such as
|
|
`effectiveInstructions()` are available directly on `window` in DevTools.
|
|
|
|
## Short gaps or clipped words around tool results
|
|
|
|
The retained audio investigation found very low local serialization/render
|
|
times for one large tool result, while still observing audio interruptions.
|
|
That evidence ruled out a UI-render bottleneck for that reproduction; it does
|
|
not rule out rendering costs for all future payloads.
|
|
|
|
Useful checks are:
|
|
|
|
- Measure tool-result size, prompt length, serialization time and UI render time.
|
|
- Inspect whether result injection overlaps an active or pending response.
|
|
- Check whether a speculative response starts before its `response.created`
|
|
reaches the browser. Cancellation based only on an existing response ID can
|
|
miss that window.
|
|
- Inspect deferred text/response queues and whether they flush after
|
|
`response.done` rather than interrupting the active turn.
|
|
- Inspect playback prebuffering and queue underflow, especially when the first
|
|
words of every sentence are affected.
|
|
- Confirm oversized tool results are summarized or capped on the relevant
|
|
path rather than assuming every tool payload gets the same treatment.
|
|
|
|
The historical investigation introduced a 90ms playback prebuffer and reduced
|
|
MCP prompt reinjection. The old 150ms MCP fallback timer is historical, not a
|
|
current ApiPilot configuration knob. Verify the live worklet and current relay
|
|
before changing audio timing based on those observations.
|
|
|
|
## External reasoning and startup
|
|
|
|
`/api/reasoning` returning 409 is expected in `PROXY` mode. In `NODE_RED`, check
|
|
that `S2S_REASONING_NODE_RED_URL` is reachable from the server and whether the
|
|
response is `log_only=true`. An empty answer is valid only in log-only mode.
|
|
In `OPENAI`, check the configured endpoint/model/key and provider logs; HTTP
|
|
reasoning does not use the native session's tool array.
|
|
|
|
For `TALK`/`TALKFIRST`, the two-second warmup does not override browser
|
|
microphone/audio permissions. If automatic startup fails, use the unlocker
|
|
gesture and inspect the permission error rather than increasing the timer
|
|
without evidence.
|
|
|
|
## Read-only source checks
|
|
|
|
From the repository root, useful syntax checks are:
|
|
|
|
```bash
|
|
node --check s2s-client/main.js
|
|
node --check s2s-client/ws/s2s-ws-client.js
|
|
python -m py_compile s2s-client/server.py
|
|
```
|
|
|
|
Syntax checks do not validate microphone access, network services, model output,
|
|
or audio quality. Collect a fresh browser/backend reproduction for those paths.
|