Skip to content

inkling: serve mode + openai_server gateway support - #539

Merged
JustVugg merged 2 commits into
JustVugg:devfrom
nbeerbower:feat/inkling-serve-upstream
Jul 23, 2026
Merged

inkling: serve mode + openai_server gateway support#539
JustVugg merged 2 commits into
JustVugg:devfrom
nbeerbower:feat/inkling-serve-upstream

Conversation

@nbeerbower

Copy link
Copy Markdown
Contributor

What

#312 landed the Inkling engine, but inkling.c only has -p streaming and the oracle harness β€” the shared openai_server.py gateway has nothing to drive. This adds the missing serve loop and the gateway support to actually serve it, both strictly additive.

Engine (inkling.c, +246): a SERVE=1 loop byte-identical to colibri.c's protocol, so the existing gateway drives it unchanged:

  • READY sentinel + STAT handshake, then per request SUBMIT <id> <slot> <len> <max_tok> <temp> <top_p> β†’ DATA frames β†’ DONE <id> STAT … + PROF (per-turn phase timings). CANCEL honored between tokens; v1 runs one request at a time.
  • temperature + top-p nucleus sampling (sample_logits; temp<=0 = greedy, so the oracle path is untouched) + a light REP_PEN repeat guard.
  • HWINFO / TIERS / EMAP dashboard lines (same as colibri.c) for the web Brain/Profiling pages.
  • prompt_reject bounds the served context (CTX_MAX, default 8192).

Gateway (openai_server.py, +193): teach it to speak inkling β€” the glm path is byte-unchanged (ARCH defaults to glm):

  • --arch {auto,glm,inkling}; auto reads model_type from the model's config.json, then picks the chat-template renderer and model-id.
  • inkling's thinking is reasoning, not answer: split the <|content_thinking|> / <|content_text|> channels into reasoning_content on both the streaming (InklingStreamSplit) and non-streaming chat paths.
  • response_format grammars are refused for inkling (its serve loop speaks the 6-field SUBMIT header only) with a clear 400.

Validation

  • Oracle unchanged: make_tiny_inkling.py + ./inkling 8 0 ref_inkling.json still 36/36 teacher-forced argmax + 24/24 greedy. Serve mode is additive; -Wall -Wextra clean.
  • End-to-end serve smoke against a tiny model: SUBMIT β†’ 8 DATA frames β†’ DONE req1 STAT 8 … 2 1 β†’ 9-field PROF. Sampling (temp/top_p) works; the DONE/STAT/PROF layout matches the gateway's _stats parser exactly.
  • 51 openai_server tests pass (glm default path intact).

Follow-up worth doing: a serve-mode smoke wired into the inkling-oracle CI job (needs the tiny fixture to also emit a tokenizer). Happy to add it here or separately.

πŸ€– Generated with Claude Code

https://claude.ai/code/session_016KLDCYJSyHxd39ChTr4T27

nbeerbower and others added 2 commits July 22, 2026 22:06
Stage-A inkling.c only had greedy -p / oracle modes, so the shared
openai_server.py gateway had nothing to drive. Add the serve loop it
speaks, byte-identical to colibri.c's protocol:

- SERVE=1 -> serve_loop: READY sentinel, STAT handshake, then per request
  SUBMIT <id> <slot> <len> <max_tok> <temp> <top_p> -> DATA frames ->
  DONE <id> STAT ... + PROF (per-turn phase timings). CANCEL honored
  between tokens; requests run one at a time (v1).
- temperature + top-p nucleus sampling (sample_logits; temp<=0 = greedy,
  so the oracle path is unchanged) + a light REP_PEN repeat guard.
- HWINFO / TIERS / EMAP dashboard lines (same as colibri.c) so the web
  Brain/Profiling pages render live expert-tier state.
- prompt_reject bounds the served context (CTX_MAX, default 8192).

Additive: the oracle still matches 36/36 teacher-forced + 24/24 greedy,
0 warnings. POSIX serve loop (inkling targets Linux/CUDA); the select()
include is guarded like colibri.c's.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016KLDCYJSyHxd39ChTr4T27
…nel)

With inkling.c now speaking the serve protocol, teach the gateway to
drive it. Additive β€” the glm path is byte-unchanged (ARCH defaults to
"glm"):

- --arch {auto,glm,inkling}; auto reads model_type from the model's
  config.json. Picks the chat-template renderer (render_chat_inkling)
  and the model-id.
- inkling's thinking is reasoning, not answer: split the <|content_thinking|>
  / <|content_text|> channels (split_inkling / strip_inkling_markers) into
  reasoning_content on both the streaming (InklingStreamSplit) and
  non-streaming chat paths.
- response_format grammars are refused for inkling (its serve loop speaks
  the 6-field SUBMIT header only) with a clear 400.

51 openai_server tests pass; end-to-end serve smoke against a tiny model
returns DATA/DONE/PROF and coherent reasoning/text split.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016KLDCYJSyHxd39ChTr4T27
@JustVugg
JustVugg merged commit 5fefde0 into JustVugg:dev Jul 23, 2026
10 checks passed
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.

2 participants