Skip to content

[Other] add legacy /v1/completions for raw-prompt clients (#2277) - #2278

Closed
kossum wants to merge 2 commits into
Niko1221:mainfrom
kossum:serve-completions
Closed

kossum wants to merge 2 commits into
Niko1221:mainfrom
kossum:serve-completions

Conversation

@kossum

@kossum kossum commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Problem and result

Clients that apply their own chat template need to send a raw prompt to /v1/completions. Strata currently has no endpoint for that.

This adds the legacy OpenAI endpoint with streaming and non-streaming responses, text_completion objects, and token usage. The server doesn't apply the chat template again.

Related discussion

#2277

Approach

The handler uses the existing generation path and accepts one string prompt. max_tokens: 0 or a negative value uses the remaining context.

Explicit thinking-disable flags append the template's no-thinking tail. Without those flags, the prompt passes through unchanged.

Streaming sends each piece of text once. With echo: true, it sends the prompt once at the start; the finish chunk has empty text.

This also keeps the structured-output error handler in the chat endpoint, so a failed streamed response sends an SSE error and [DONE], not another HTTP response inside the stream. Engine errors after streaming starts are handled as SSE errors too.

Validation

Rebased onto main e88ee39d (0.2.0-beta). These local checks ran on 7e08755f.

Passed:

Windows, Python 3.13.2, with jsonschema installed:

uv run --no-project --with regex --with jinja2 --with jsonschema python -m unittest serve.test_server serve.test_structured serve.test_monitor

368 tests, OK, 3 skipped.

Linux, Python 3.11 in Docker, using a dedicated venv with only the pinned requirements.txt packages:

python tools/minimal_server_smoke.py --report /tmp/minimal-server-smoke.json

Reported "passed": true.

git diff --check upstream/main also passed.

Failed:

The full suite in the same Linux venv:

python -m unittest discover -s serve -p 'test_*.py'

888 tests, 2 failures, 18 skipped:

  • test_lifeline.Lifeline.test_the_portable_watcher_ends_the_child_when_the_server_is_killed
  • test_server.VisionTempFiles.test_work_dir_has_no_space_when_temp_has_one

I reran both tests on clean main e88ee39d with the same container and dependencies. Both fail there with the same assertions. I haven't changed either behavior in this PR.

Not run:

  • Live-model testing on this rebased revision. The earlier live checks were on an older revision.
  • CUDA, HIP, SYCL or Metal builds. This PR changes Python serving code, not native backend code.
  • A byte-for-byte comparison of all existing endpoints against the release.

Limits

Only a string prompt and n=1 / best_of=1 are supported. Suffix and logprobs are rejected.

stream_options accepts only include_usage, and only with streaming. Usage still comes on the finish chunk, not a separate choices: [] chunk, so this doesn't yet implement the full OpenAI streaming-usage format.

DamirLukina88 pushed a commit to DamirLukina88/D.L.-AI---Strata that referenced this pull request Oct 13, 2026
…s endpoint for raw-prompt clients (Niko1221#2277)

Source: Niko1221#2278

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DamirLukina88 pushed a commit to DamirLukina88/D.L.-AI---Strata that referenced this pull request Oct 13, 2026
…up robustness, conversation cache memory)

Serve: Niko1221#2290 Niko1221#2284 Niko1221#2285 Niko1221#2170 Niko1221#2140 Niko1221#2278. Setup: Niko1221#2161 Niko1221#2287. Engine: Niko1221#2253 Niko1221#2265 Niko1221#2247 Niko1221#2217 Niko1221#2243.
New opt-in engine flags: --session-state-codec (enabled in the local configs), --conversation-cache-park-gain and --drop-file-cache (left off: no measured benefit on the RX 7600 XT box). Bench: bench/results/upstream-prs-2026-10-13.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@qiuzan2001

Copy link
Copy Markdown

Two findings (Linux, Python 3.14; serve.test_server.MaxTokens passes):

  1. serve/test_structured.py fails on this branch once jsonschema is installed (it is skipped without it): test_invalid_generation_is_an_error_and_never_streams_content gets a raw HTTP/1.0 502 Bad Gateway ... {"error": {"type": "structured_output_failed", ...}} block written into the SSE stream instead of data: {"error": ...} followed by data: [DONE], for all three invalid scripts. On main 296b59d the same file passes (10 OK). The except StructuredOutputError that the streamed chat path relied on now sits in _completions, so a streamed /v1/chat/completions with response_format reaches do_POST's generic handler after the 200 headers are out.
  2. In _completions' chunks(), every token is already streamed as a delta, and the final chunk again carries "text": (prompt if echo else "") + text, the whole completion. A client that concatenates the streamed text fields gets the answer twice; OpenAI's final chunk has an empty text with the finish_reason. The new tests check only usage and [DONE] on the stream.

@kossum

kossum commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor Author

Thanks for catching both. Fixed in the latest push.

I accidentally moved the StructuredOutputError handler out of _openai when adding _completions. It's back now, so a failed streamed response sends an SSE error followed by [DONE] instead of writing another HTTP response into the stream.

The final completion chunk now has empty text. With echo: true, the prompt goes out once at the start. Added tests that concatenate the streamed text and compare it with the non-stream response, with echo on and off.

You were also right about jsonschema: I didn't have it installed, so that test was being skipped. Reran with it installed and checked both fixes against the live model too. I also added a streaming failure check to the dependency-absent test so this doesn't slip through again.

@kossum
kossum force-pushed the serve-completions branch 2 times, most recently from 43916b0 to ac6aeed Compare October 19, 2026 14:22
@kossum kossum changed the title serve: add the legacy /v1/completions endpoint for raw-prompt clients (#2277) [Other] add legacy /v1/completions for raw-prompt clients (#2277) Oct 19, 2026
@Niko1221

Copy link
Copy Markdown
Owner

Thanks for the pull request.

We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to review properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected.

To reopen it takes about two minutes:

  1. Rebase on main if it no longer applies, and re-run your checks on 0.2.0-beta.
  2. Start the title with its area: [Engine], [GUI], [TUI], [Benchmark], [Docs] or [Other].
  3. Fill in the pull request template: the problem and result, and the validation (what you ran, on which revision, what you saw).
  4. Comment /reopen. A check runs and either reopens the pull request or lists what is still missing.

The rules are in CONTRIBUTING.md.

@Niko1221 Niko1221 closed this Oct 19, 2026
@kossum

kossum commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

/reopen

@github-actions

Copy link
Copy Markdown

The check passed, but GitHub would not reopen it (Validation Failed: ). If the branch was deleted, restore it or open a new pull request and link this one.

@kossum

kossum commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

/reopen

@github-actions

Copy link
Copy Markdown

The check passed, but GitHub would not reopen it (Validation Failed: ). If the branch was deleted, restore it or open a new pull request and link this one.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants