Skip to content

OpenCode Go: gpt-5.6-luna stream degradation (repeats, mid-stream cuts, junk tails); Codex path clean #39881

Closed as not planned

Description

@kirocop

Description

gpt-5.6-luna on OpenCode Go is reachable and returns completions, but the stream/output quality is degraded compared to the same model via OpenAI Codex.

Observed symptoms on OpenCode Go (opencode-go / gpt-5.6-luna):

  1. Repeated final answers — exact phrase echoed multiple times in one completion
  2. Mid-stream cut / continue loops — client sees network-cut continuation behavior (previous response was cut off by a network error mid-stream) even on short prompts
  3. Garbage / wrong identity tails — after a finished answer, extra junk text appears (e.g. model claiming to be a different model, trailing “Fine.” / completion noise)
  4. Control/count tasks get polluted — e.g. “count 1..5” returns the numbers plus an unnecessary trailing remark

Same model ID via OpenAI Codex (openai-codex / gpt-5.6-luna) on the same machine/day is clean: single exact answer, no repetition, no junk tail.

This looks like a Go relay / Responses streaming issue for Luna, not a general Luna model failure.

Related (not identical):

Docs reference

Per https://opencode.ai/docs/go , GPT 5.6 Luna is served on:

  • Model ID: gpt-5.6-luna
  • Endpoint: https://opencode.ai/zen/go/v1/responses
  • Package: @ai-sdk/openai

Plugins

N/A (reproduced via OpenAI-compatible client / Hermes Agent using OpenCode Go API key against the public Go endpoint). Not using OpenCode TUI plugins.

OpenCode version

N/A for TUI — reproduced against the public Go API:

  • Base URL: https://opencode.ai/zen/go/v1
  • Provider label: OpenCode Go
  • Model: gpt-5.6-luna

Client side: Hermes Agent using the OpenCode Go key / Responses path for Luna.

Steps to reproduce

  1. Authenticate with a valid OpenCode Go API key.
  2. Call Luna on Go (Responses path as documented):
    • POST https://opencode.ai/zen/go/v1/responses
    • model: gpt-5.6-luna
  3. Minimal prompts that reproduced degradation today (2026-07-31, Europe/Rome):
Reply with exactly: LUNA_OK_OPENCODE

Observed: answer repeated multiple times (LUNA_OK_OPENCODE × N), plus mid-stream continue behavior in the client session log.

In Italian, one line only: say who you are and your model id if known. No repetitions.

Observed on Go: wrong/noisy identity text (including claiming another model) and trailing junk.

Count from 1 to 5, one number per line, nothing else.

Observed on Go:

1
2
3
4
5(The count was already complete.)
  1. Control comparison on the same day, same machine, same model ID via OpenAI Codex:
    • Prompt: Reply with exactly: LUNA_OK_CODEX
    • Result: clean single-line LUNA_OK_CODEX
    • Natural one-line identity prompt: clean, correct, no junk

Expected behavior

  • Single clean final answer
  • No repeated completion text
  • No mid-stream cut/continue loops on short prompts
  • No trailing garbage after a finished response
  • Behavior parity with Codex for the same model ID on simple deterministic prompts

Actual behavior

On OpenCode Go, Luna often returns usable tokens but with degraded stream/finalization quality (repetitions, cut/continue, junk tails, wrong identity noise). Codex path remains clean.

Screenshot and/or share link

No TUI screenshot. Session evidence from 2026-07-31 CEST:

  • Go smoke: repeated LUNA_OK_OPENCODE
  • Go natural prompt: polluted/wrong identity + trailing noise
  • Go count prompt: numbers + trailing remark after completion
  • Codex control: clean exact responses

Happy to provide redacted request/response traces (no API keys) if useful.

Operating System

Linux (server-side client against public Go API), Europe/Rome

Terminal

Headless API client (Hermes Agent CLI), not OpenCode TUI

Additional notes

  • UI label (2x) on GPT 5.6 Luna in some clients appears to be the temporary 2× usage limits promo, not a separate model SKU. This report is about quality/stream integrity of gpt-5.6-luna on Go, not quota labeling.
  • Antigravity/OpenCode TUI usage of Luna may appear “fine” depending on transport/path; the degradation was consistently reproducible through the Go API Responses path from an external agent client.
  • Please advise if Go Luna currently requires a specific Responses contract (stream flags, previous_response_id, WS vs SSE, etc.) that third-party clients must mirror.

Activity

  1. awesomekyle commented on Jul 31, 2026

    @awesomekyle

    Is your stream cut off mid-stream, or is it just missing a stop reason? When using pi, it tells me this: Error: Retry failed after 3 attempts: Stream ended without finish_reason. Looking at the raw stream it looks like it actually is done, it has token usage, but no [DONE] and no finish_reason. These are the last events in the SSE stream:

    data: {
      "id": "",
      "object": "chat.completion.chunk",
      "created": 1785505662,
      "model": "",
      "choices": []
    }
    
    data: {
      "id": "gen-1785505659-LGLXKuuNN02hNGje8MN8",
      "object": "chat.completion.chunk",
      "created": 1785505662,
      "model": "gpt-5.6-luna",
      "choices": [],
      "usage": {
        "prompt_tokens": 1228,
        "completion_tokens": 144,
        "total_tokens": 1372
      }
    }
    
    data: {
      "choices": [],
      "cost": "0"
    }
    
  2. kirocop commented on Jul 31, 2026

    @kirocop
    Author

    @awesomekyle Good catch — this matches what we see.

    Short answer: it looks more like a missing/nonstandard stream termination than a clean mid-generation cut.

    We just rechecked both Go endpoints with the same minimal prompt:

    Reply with exactly: LUNA_SSE_TEST

    1) Documented path: POST /zen/go/v1/responses (stream=true)

    This path looks healthier:

    • proper Responses SSE event sequence
    • text deltas assemble correctly to LUNA_SSE_TEST
    • ends with response.output_text.done → response.output_item.done → response.completed
    • includes usage
    • status: "completed"

    No classic chat-completions finish_reason / [DONE] here (expected for Responses API).

    2) Compatibility path: POST /zen/go/v1/chat/completions (stream=true)

    This is the broken-looking one, and it matches your raw trace closely:

    • content deltas arrive (L UNA _S SE _TEST)
    • many chunks have empty choices: []
    • final usage chunk arrives
    • final cost chunk arrives
    • no data: [DONE]
    • no terminal chunk with finish_reason: "stop"
    • the only finish_reason values seen on content deltas are null

    Last events look like:

    data: {"id":"...","object":"chat.completion.chunk","model":"gpt-5.6-luna","choices":[],"usage":{...}}
    
    data: {"choices":[],"cost":"0"}
    

    So: stream has tokens + usage, but clients that require either [DONE] or a non-null finish_reason will treat it as incomplete and retry (Stream ended without finish_reason).

    How this maps to our original report

    Our agent client hits the incomplete-stream recovery path (“previous response was cut off… continue”), which then produces:

    • exact-phrase repetitions
    • junk tails after an already-complete answer
    • “already complete” style noise

    So the user-visible degradation is likely a client retry/continue reaction to malformed chat-completions SSE termination on Go Luna, not only model quality.

    Ask for maintainers

    Is Go’s /chat/completions stream for gpt-5.6-luna intentionally nonstandard, or should it emit a normal OpenAI-compatible terminator (finish_reason: "stop" and/or data: [DONE])?

    If /responses is the supported path for Luna, it would help to call that out more strongly for third-party clients — docs already list Responses for Luna, but many agents still default to chat-completions.

    Happy to provide additional redacted SSE captures if useful.

  3. kirocop commented on Jul 31, 2026

    @kirocop
    Author

    Additional data point: the missing termination is not limited to SSE streaming — it reproduces in plain non-stream requests too.

    Tested both endpoints with the same minimal prompt (Reply with exactly: LUNA_OK), non-stream:

    1) POST /zen/go/v1/responses

    • HTTP 200
    • status: "completed"
    • output text exactly LUNA_OK
    • clean completion, usage present

    2) POST /zen/go/v1/chat/completions

    • HTTP 200
    • content: "LUNA_OK"
    • finish_reason: null (no stop even on a fully completed response)

    So on the compatibility path the model produces the full answer but never emits a terminal finish_reason, which forces clients to treat every response as incomplete and retry. This aligns with the streaming trace above (no [DONE], final usage chunk only) and confirms the issue is in the chat/completions transport itself, not in stream handling.

  4. jcmpgit commented on Aug 7, 2026

    @jcmpgit

    Adding two data points from a downstream consumer (Hermes Agent), since this
    directly affects every strict SSE client that refuses to fabricate terminal
    markers:

    1. The defect is model-specific, not path-wide. Same tiny probe
    (Reply with exactly: X), same POST /zen/go/v1/chat/completions endpoint,
    streaming + non-streaming:

    Model finish_reason (non-stream) Terminal [DONE]/finish_reason (stream) Verdict
    gpt-5.6-luna null missing — final chunk {"choices":[],"cost":"0"} 🔴 broken
    kimi-k3 null missing — same shape 🔴 broken
    kimi-k2.7-code stop present + [DONE] 🟢 ok
    glm-5.2 stop present + [DONE] 🟢 ok
    deepseek-v4-flash stop present + [DONE] 🟢 ok
    deepseek-v4-pro stop present + [DONE] 🟢 ok
    minimax-m3 stop present + [DONE] 🟢 ok

    So the missing termination is confined to the 5.6-family (and kimi-k3) on
    the chat/completions compatibility path, not a global behavior of that
    endpoint.

    2. Downstream impact + current workaround. Hermes deliberately refuses
    to stamp finish_reason="stop" on streams that end without one (it guards a
    real truncation class — see NousResearch/hermes-agent#32086), so every luna /
    kimi-k3 response was treated as a mid-stream drop and every turn failed with
    "Response remained truncated after 4 continuation attempts". The fallback
    chain never engaged because the transport succeeds (HTTP 200, full content
    delivered) — the defect is semantic, not a connection error.

    Until this is fixed upstream, affected clients can either avoid the model on
    this path (use /zen/go/v1/responses where the termination is correct, or
    route to another model) or apply a narrow model-scoped bypass. We published
    a small patch script for the Hermes-side guard as a stopgap:
    https://gist.github.com/jcmpgit/60087ac45da47c58ffe654781bada8fc

    Happy to run any additional probes if it helps isolate where the terminal
    marker is being dropped on the gateway side.

  5. github-actions commented on Oct 8, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions