Skip to content

Add gpt-oss-120b, qwen3-30b-a3b-fp8, and the domain IAB classifier - #3

Merged
amaan-ai20 merged 1 commit into
mainfrom
feat/new-models
Jul 27, 2026
Merged

Add gpt-oss-120b, qwen3-30b-a3b-fp8, and the domain IAB classifier#3
amaan-ai20 merged 1 commit into
mainfrom
feat/new-models

Conversation

@amaan-ai20

@amaan-ai20 amaan-ai20 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Brings the CLI in line with the models published in the API reference. Three models were live in the docs with no CLI path to them, and one was renamed underneath us.

New models

Model Surface
gpt-oss-120b zerogpu chat -m gpt-oss-120b
qwen3-30b-a3b-fp8 zerogpu chat -m qwen3-30b-a3b-fp8
zlm-v1-iab-domain-classifier zerogpu classify_domain <domain>

chat gains --model

Rather than a command per model, chat takes -m, --model and keeps LFM2.5-1.2B-Instruct as the default, so every existing invocation behaves exactly as before. -r, --reasoning prints the trace that the reasoning models return alongside their answer.

zerogpu chat "Why is my p99 latency spiking?" -m gpt-oss-120b -r

qwen3-30b-a3b-fp8 is the one model the platform serves only through Chat Completions, so the CLI posts it to /v1/chat/completions instead of /v1/responses, maps --instructions to a system message, and normalizes prompt_tokens/completion_tokens back to Responses token names for savings tracking. The routing is invisible to the caller.

classify_domain

Classifies a bare hostname — no crawl, no page body — for bidstream enrichment and inventory-level targeting.

zerogpu classify_domain nytimes.com

Fixes carried along

  • Enriched IAB model was renamed. The docs moved zlm-v1-iab-classify-edge-enrichedzlm-v2-iab-classify-edge-enriched; classify_iab_enriched was still sending the v1 id.
  • Reasoning items broke the output[0] assumption. gpt-oss-120b returns a reasoning item before the assistant message, so the old extraction would have printed the reasoning as the answer. Response parsing now selects the message item.
  • Stale pricing in savings.ts. The table carried $0.05/$0.40 per 1M for the edge models; the published catalog says $0.02/$0.05. Savings figures were understated. The unknown-model fallback is now the priciest published rate so it can never overstate savings.

Verification

npm run build, npm run lint, and npm test (37 tests, incl. new coverage for reasoning-item extraction and usage mapping) all pass. All four model paths were also exercised against the live API — gpt-oss-120b (answer correctly separated from its reasoning trace), qwen3-30b-a3b-fp8 via Chat Completions, classify_domain, and classify_iab_enriched on the v2 id.

No version bump here — that is npm run release's job per RELEASING.md.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added classify_domain to classify domains against the IAB taxonomy without fetching page content.
    • Expanded chat with multiple model options, multilingual and reasoning-capable models, and an optional reasoning trace.
    • Added support for model-specific response handling and improved formatted output.
  • Updates

    • Updated classify_iab_enriched to use the enriched v2 model.
    • Refined usage and savings reporting across supported models.
  • Documentation

    • Added command references, examples, supported models, options, and API behavior details.

…IAB classifier

Brings the CLI in line with the models published in the API reference.

- `chat` gains `-m, --model` (default `LFM2.5-1.2B-Instruct`) covering
  `gpt-oss-120b`, `qwen3-30b-a3b-fp8`, and `LFM2.5-1.2B-Thinking`, plus
  `-r, --reasoning` to print the trace reasoning models return.
  `qwen3-30b-a3b-fp8` has no Responses endpoint, so it is routed to
  `/v1/chat/completions` transparently.
- New `classify_domain` command for `zlm-v1-iab-domain-classifier`,
  which classifies a bare hostname with no page fetch.
- `classify_iab_enriched` now sends `zlm-v2-iab-classify-edge-enriched`;
  the docs renamed the model from `zlm-v1-...`.
- Reasoning models emit a `reasoning` output item ahead of the assistant
  message, so response parsing now selects the `message` item instead of
  assuming `output[0]`.
- Refresh `ZGPU_PRICING` against the published catalog — the edge models
  are $0.02/$0.05 per 1M, not the $0.05/$0.40 the table still carried.

Verified against the live API: all four model paths return expected
output, and the reasoning trace is separated from the answer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The CLI adds classify_domain, expands chat to support multiple models and API formats with optional reasoning output, updates response parsing and pricing, changes the enriched IAB model, and documents the new commands and contracts.

Changes

CLI AI commands

Layer / File(s) Summary
Response contracts and parsing
src/lib/responses.ts, src/lib/chatCompletions.ts, tests/responses.test.ts, docs/ADDING_COMMANDS.md, docs/DOCUMENTATION.md
Adds typed response helpers, reasoning extraction, Chat Completions usage normalization, and tests for output and token parsing.
Multi-model chat routing
src/commands/chat.ts, src/lib/savings.ts, tests/savings.test.ts, README.md, docs/DOCUMENTATION.md
Adds model selection, endpoint-specific request and response handling, optional reasoning output, and updated model pricing.
Domain classification command
src/commands/classifyDomain.ts, src/cli.ts, src/commands/classifyIabEnriched.ts, README.md, docs/DOCUMENTATION.md
Registers classify_domain, sends domains to the IAB classifier, records usage, updates the enriched classifier model, and documents the command.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Poem

I’m a rabbit with a CLI in flight,
Hopping through models day and night.
Domains get sorted, traces shine,
Tokens and prices fall in line.
New routes bloom where old ones ran—
classify_domain joins the plan!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main additions: new chat models and the domain IAB classifier.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/new-models

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/DOCUMENTATION.md`:
- Around line 705-713: Update the “Common output behavior” documentation section
to describe selecting the assistant message from output and extracting its
output_text content, rather than assuming output[0]. Ensure it reflects
reasoning-first payloads and the existing fallback/pretty-print behavior used by
the parser.
- Line 191: Label the fenced code block at docs/DOCUMENTATION.md lines 191-191
as bash, label the fenced code block at lines 637-637 as bash, and label the
endpoint-contract fence at lines 685-685 as http or text to satisfy markdownlint
MD040.

In `@src/lib/responses.ts`:
- Around line 32-35: Update the response extraction logic around the message
selection in responses.ts so it only falls back to an untyped output item, never
a typed reasoning item. When no message or untyped output item exists, return
undefined so the existing missing-content error path is preserved; keep
output_text and legacy text extraction unchanged for valid items.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d7f45871-ad3e-4790-bdbc-7d0f98616a18

📥 Commits

Reviewing files that changed from the base of the PR and between 6a3f230 and 095652a.

📒 Files selected for processing (12)
  • README.md
  • docs/ADDING_COMMANDS.md
  • docs/DOCUMENTATION.md
  • src/cli.ts
  • src/commands/chat.ts
  • src/commands/classifyDomain.ts
  • src/commands/classifyIabEnriched.ts
  • src/lib/chatCompletions.ts
  • src/lib/responses.ts
  • src/lib/savings.ts
  • tests/responses.test.ts
  • tests/savings.test.ts

Comment thread docs/DOCUMENTATION.md
Chat with a ZeroGPU text-generation model. Defaults to `LFM2.5-1.2B-Instruct`.

**Synopsis**
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add languages to the fenced code blocks. These fences fail markdownlint MD040.

  • docs/DOCUMENTATION.md#L191-L191: label the CLI synopsis fence as bash.
  • docs/DOCUMENTATION.md#L637-L637: label the CLI synopsis fence as bash.
  • docs/DOCUMENTATION.md#L685-L685: label the endpoint-contract fence as http or text.
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 191-191: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

📍 Affects 1 file
  • docs/DOCUMENTATION.md#L191-L191 (this comment)
  • docs/DOCUMENTATION.md#L637-L637
  • docs/DOCUMENTATION.md#L685-L685
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/DOCUMENTATION.md` at line 191, Label the fenced code block at
docs/DOCUMENTATION.md lines 191-191 as bash, label the fenced code block at
lines 637-637 as bash, and label the endpoint-contract fence at lines 685-685 as
http or text to satisfy markdownlint MD040.

Source: Linters/SAST tools

Comment thread docs/DOCUMENTATION.md
Comment on lines +705 to +713
type?: string;
content?: Array<{ type?: string; text?: string }>;
}>;
}
```
It picks the first `content` entry whose `type === "output_text"` (falling back to `content[0]`), then prints `text` — pretty-printed if it parses as JSON, otherwise as a raw string.

Reasoning models emit a `reasoning` output item **ahead of** the assistant message, so `chat` selects the item whose `type === "message"` rather than assuming `output[0]`, and reads the trace from the `reasoning` item when `--reasoning` is passed. On the Chat Completions path the answer is `choices[0].message.content` and the trace is `choices[0].message.reasoning`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the common output contract with the new parser.

The earlier “Common output behavior” section still says every inference command reads output[0], which contradicts this message-item selection rule. Update that section to describe output_text extraction from the assistant message so integrations do not assume reasoning-first payloads are unsupported.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/DOCUMENTATION.md` around lines 705 - 713, Update the “Common output
behavior” documentation section to describe selecting the assistant message from
output and extracting its output_text content, rather than assuming output[0].
Ensure it reflects reasoning-first payloads and the existing
fallback/pretty-print behavior used by the parser.

Comment thread src/lib/responses.ts
Comment on lines +32 to +35
const items = data.output ?? [];
const message = items.find((item) => item.type === "message") ?? items[0];
const parts = message?.content ?? [];
return parts.find((p) => p.type === "output_text")?.text ?? parts[0]?.text;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Do not treat a typed reasoning item as assistant output.

If a response contains only a reasoning item, items[0] is returned and its trace is printed as chat content even without --reasoning. Only fall back to an untyped output item for backward compatibility; otherwise return undefined and preserve the missing-content error path.

Proposed fix
-  const message = items.find((item) => item.type === "message") ?? items[0];
+  const message =
+    items.find((item) => item.type === "message") ??
+    items.find((item) => item.type === undefined);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const items = data.output ?? [];
const message = items.find((item) => item.type === "message") ?? items[0];
const parts = message?.content ?? [];
return parts.find((p) => p.type === "output_text")?.text ?? parts[0]?.text;
const items = data.output ?? [];
const message =
items.find((item) => item.type === "message") ??
items.find((item) => item.type === undefined);
const parts = message?.content ?? [];
return parts.find((p) => p.type === "output_text")?.text ?? parts[0]?.text;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/responses.ts` around lines 32 - 35, Update the response extraction
logic around the message selection in responses.ts so it only falls back to an
untyped output item, never a typed reasoning item. When no message or untyped
output item exists, return undefined so the existing missing-content error path
is preserved; keep output_text and legacy text extraction unchanged for valid
items.

@amaan-ai20
amaan-ai20 merged commit ec02528 into main Jul 27, 2026
2 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.

1 participant