BYOK custom model Agent: byok-connect-routed empty interactionUpdate:turnEnded marked success (no assistant/tools)

Where does the bug appear (feature/product)?

Cursor IDE

Describe the Bug

With a custom OpenAI-compatible BYOK model (e.g. lazy/task), Agent Host always selects runtime=connect disposition=fallback reason=byok-connect-routed and logs “Local loop fell back to the backend loop”. On follow-up user messages, the NAL stream often ends in ~6-8s with last_inbound_message_type=interactionUpdate:turnEnded and Turn terminal blob reads count=0. Local transcript shows user → turn_ended status=success with NO assistant text and NO tool_use. UI looks idle/“not working” while the turn is marked successful. Distinct from mid-stream drops (Stream ended without turnEnded / PING timed out), which we also saw on the same path.

Steps to Reproduce

  1. Enable OpenAI API Key + Override Base URL (OpenAI-compatible).
  2. Open Agent chat; select custom model id lazy/task (or equivalent BYOK custom model).
  3. Send a long Agent task that uses many Shell/Read tools. First turn may run tools.
  4. After first turn ends, send short follow-ups such as progress / ? / why aren’t you working.
  5. Observe: turn completes in ~6-8s with no assistant output; transcript shows empty turn_ended success.

Logs show: Selected Agent Host turn runtime reason=byok-connect-routed; Local loop fell back to the backend loop; last_inbound_message_type=interactionUpdate:turnEnded; Turn terminal blob reads count=0.

Expected Behavior

Either continue the Agent loop with model tokens/tools, OR surface a visible failed/error turn if the backend cannot continue. Do NOT mark an empty turn as success when there is no assistant content and no tools.

Operating System

MacOS

Version Information

Cursor 3.29.15 (stable) / macOS arm64 / glass layout / Pro membership active

For AI issues: which model did you use?

lazy/task (custom OpenAI-compatible BYOK route)

For AI issues: add Request ID with privacy disabled

conversationId 2c949ebf-d437-4046-9640-49f153ad2e27; generationUUIDs: f8f065eb-b776-4f7f-9487-716b1f9b5e13, 40b4377e-a582-4a83-9cac-0c6b32396933, 40d0a01b-a73e-475c-8168-f0878c5cbd87; also 34da7504-7093-4eb7-93be-4ae7c3be6fda / d7d0235d-9c1a-4905-b422-fa543f8106dd

Additional Information

Key log signatures: reason=byok-connect-routed; Local loop fell back to the backend loop; interactionUpdate:turnEnded; Turn terminal blob reads count=0; transcript turn_ended status=success with zero assistant/tool output. Also observed on same path: Stream ended without turnEnded / PING timed out (transport), but empty-success is the main UX failure. Related forum themes: BYOK early stopping / turn ends before write tool_use. Ask: empty turnEnded should not be success; or keep Local Loop available for BYOK Agent.

Does this stop you from using Cursor

Sometimes - I can sometimes use Cursor

Hi @lcw, the empty turns come from what your endpoint returned, not from the routing.

On the requests you listed, the response was a 200 stream whose only event was an upstream error object (402 You're out of credits, billing_error), with no choices and no finish_reason. Cursor retried once, got the same thing, and ended the turn with nothing to show.

Thanks Colin — that matches what we can act on. We’ll check the upstream gateway billing/credits for those request IDs.

The confusing part on our side was the empty turnEnded/success with no visible 402 in the Agent UI; clearer surfacing of billing_error would help a lot.

We’ll follow up if empty turns continue after credits are restored.