Skip to content

feat(providers): add Moonshot API compatibility + fix Z.AI baseURL - #1

Closed
gHashTag wants to merge 1 commit into
devfrom
feat/moonshot-zai-model-support
Closed

gHashTag wants to merge 1 commit into
devfrom
feat/moonshot-zai-model-support

Conversation

@gHashTag

Copy link
Copy Markdown
Owner

Summary

Adds support for Moonshot AI models (kimi-k2.5, kimi-k2.6) and fixes Z.AI connectivity via Anthropic-compatible API.

Moonshot API Compatibility

The Vercel AI SDK sends fields that Moonshot does not support, causing 400 errors:

  • parallel_tool_calls
  • response_format.json_schema without name
  • response_format.strict
  • max_tokens > 98304 or max_tokens = 0
  • frequency_penalty / presence_penalty (Moonshot only supports 0)

Changes:

  • moonshot-fetch.ts: new fetch wrapper that intercepts and sanitizes request bodies
  • provider-factory.ts: wires createMoonshotFetch() into the Moonshot factory
  • provider.ts (llm): wires createMoonshotFetch() into the Moonshot model
  • moonshot-fetch.test.ts: unit tests for all filtering logic

Z.AI BaseURL Fix

Z.AI uses an Anthropic-compatible API at https://z.ai/api/anthropic/v1, but the built-in Anthropic factories were ignoring custom baseUrl, sending requests to api.anthropic.com. This caused "invalid x-api-key" errors.

Changes:

  • provider-factory.ts: pass baseURL to createAnthropic() when set
  • provider.ts (llm): pass baseURL to createAnthropic() when set
  • urls.ts: fix ZAI_API from broken https://api.z.ai to https://z.ai

Tested With

Provider Model Endpoint
NVIDIA NIM (OpenAI compatible) moonshotai/kimi-k2.6 https://integrate.api.nvidia.com/v1
Z.AI (Anthropic compatible) glm-5.1 https://z.ai/api/anthropic/v1

Closes browseros-ai#657

Add support for Moonshot AI models (kimi-k2.5, kimi-k2.6) via NVIDIA NIM
and direct Moonshot API. The Vercel AI SDK sends fields that Moonshot
does not support (parallel_tool_calls, strict response_format,
frequency/presence penalties, unlimited max_tokens), causing 400 errors.

Changes:
- moonshot-fetch.ts: intercept and filter unsupported request fields
  * Remove parallel_tool_calls
  * Remove json_schema response_format without name
  * Remove strict flag from response_format
  * Clamp max_tokens > 98304 to 32768, remove if 0
  * Force frequency_penalty and presence_penalty to 0
- provider-factory.ts: wire createMoonshotFetch() into Moonshot factory
- provider.ts (llm): wire createMoonshotFetch() into Moonshot model
- provider-factory.ts + provider.ts: pass baseURL for Anthropic provider
  to support Z.AI custom endpoints (https://z.ai/api/anthropic/v1)
- urls.ts: fix ZAI_API from broken https://api.z.ai to https://z.ai
- moonshot-fetch.test.ts: unit tests for all filtering logic

Tested with:
- NVIDIA NIM: moonshotai/kimi-k2.6 via integrate.api.nvidia.com
- Z.AI: glm-5.1 via z.ai/api/anthropic/v1
@gHashTag

Copy link
Copy Markdown
Owner Author

Closing to split into focused PRs

@gHashTag gHashTag closed this May 20, 2026
@github-actions
github-actions Bot deleted the feat/moonshot-zai-model-support branch May 24, 2026 01:07
gHashTag added a commit that referenced this pull request May 24, 2026
 #1)

- queen-browseros.md: BrowserOS Agent for Trinity A2A
- skills: tri, doctor, god-mode, bridge
- cron-queen.sh: 15-min autonomous lifecycle
- launchd: com.trinity.queen-cron running
- .trinity/experience.md: knowledge base
- Full MCP access: fs_read, fs_write, shell_execute
gHashTag added a commit that referenced this pull request Aug 1, 2026
The supervisor surface was opened and looked at for the first time tonight, and
it works. In the narrow panel: an OPEN DASHBOARD control at the top, a compact
line reading "1 needs you - 0/4 working", and the bee board below it with a
WAITING ON YOU section and a card carrying the state, the worker, the branch and
an Accept button. Widened, the same plus the full swarm strip with the issue,
the branch, awaitingReview and Review. gHashTag/trios#1118 closed on its last
criterion, which was readability and could only ever be answered this way.

Looking found a defect no test had: the issue number printed as `#1,124`. A
SwiftUI `Text` interpolating an Int formats it as a quantity, and an issue number
is an identifier - you cannot search for `#1,124` or paste it anywhere. Fixed on
both screens that print one.

The bee's own assertion for it could not pass: it compared lengths and claimed
the identifier was shorter, while `browseros-ai#1129` and `1,129` are both five characters.
A test that is false by construction fails the same way a real defect does, and
it was caught only because the gate went red. It asserts the shape now - the
rendered identifier carries no group separator.

Also this cycle: an empty diff no longer sends the reviewer the first 500 lines
of a file, and a verdict is bound to the tree state it was judged against.

Ratchet 552 -> 559.

Closes gHashTag/trios#1129
Refs gHashTag/trios#1118, gHashTag/trios#1124
gHashTag added a commit that referenced this pull request Aug 19, 2026
Bee work for browseros-ai#1129, landed as she wrote it. She introduced `IssueBadgeForm`
with the rule stated in one place - an issue number is an identifier that
happens to be written in digits, so routing it through a value formatter
returns `#1,124`, by which rendering the issue cannot be found on GitHub
and the number cannot be copied out of the card.

Her edit sat uncommitted in the shared tree: her task predates worktrees,
so she worked where every bee used to.

The e2e check called this a regression. It searched for the literal
`Text(verbatim: "#\(task.issue.number)")` - the first fix's exact spelling
- while she had replaced it with `Text(verbatim: IssueBadgeForm.badge(...))`,
a named form with its own assertions. The requirement is that the number
reaches the screen verbatim; the check had pinned one way of writing that,
and so failed the day someone wrote it better. It now accepts either.
dmitrii-f-t27 added a commit that referenced this pull request Oct 2, 2026
… the next number

A key added without a name was stored as an empty label and shown as the
bare provider, so the owner's 25th NVIDIA key read "nvidia" above
"nvidia #1".."#24". Environment keys are now named by their place in their
pool (Z.ai's pool-2 keys become zai #1..#10 instead of #10001..#10010), a key
added unnamed or named only after its provider takes the next free number
under the add lock, and a managed key saved before numbering is numbered
once, compare-and-set, the first time the owner's keys are listed.
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.

Kimi built-in assistant consumes credits but gives "HTTP 422: Unprocessable Entity"

1 participant