feat: add iFlytek Spark and Astron MaaS providers - #9837
Conversation
Add declarative OpenAI-compatible providers for iFlytek Spark (讯飞星火) and iFlytek Astron MaaS (讯飞星辰): - iflytek.json: Spark HTTP API (spark-api-open.xf-yun.com/v1) with 4.0Ultra, generalv3.5, max-32k, generalv3, pro-128k and lite, using SPARK_API_PASSWORD for auth. - iflytek_astron.json: Astron MaaS, defaulting to the Token Plan endpoint with ASTRON_BASE_URL to switch to the Coding Plan; ships Spark X2, DeepSeek, GLM, Kimi, MiniMax, Qwen and astron-code-latest. Both use static model lists and skip canonical filtering since the model ids are provider-specific. Adds deserialization tests and documents the providers in the supported providers table. Signed-off-by: FenjuFu <fufenjupku@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d3f4940da
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| {"name": "generalv3", "context_limit": 8192}, | ||
| {"name": "pro-128k", "context_limit": 131072}, | ||
| {"name": "lite", "context_limit": 4096} |
There was a problem hiding this comment.
Remove Spark models without system/tool support
The official Spark HTTP docs note that only Spark 4.0Ultra and Max support system messages and Function Call (https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html). When a goose session selects these Pro/Pro-128K/Lite entries, the OpenAI provider can send the normal system prompt and tools, so those requests are liable to be rejected even though the models are advertised as supported; please omit these entries or otherwise prevent tool/system-using sessions from selecting them.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Done in d03354d — dropped the Pro/Pro-128K/Lite entries and kept only 4.0Ultra and the Max family (generalv3.5, max-32k), which the Spark HTTP docs list as supporting system messages and Function Call.
|
Thanks for the contribution! A couple of things before this can land:
(Also for context: the earlier "closing, external repo" comment doesn't apply to this PR — it looks like it was posted in error.) I'll snooze this for a few days to give you a chance to respond. |
…t all bundled providers parse Per the Spark HTTP docs only the 4.0Ultra and Max families accept system messages and Function Call, so drop the Pro/Pro-128K/Lite entries that would reject goose's system-prompt + tools requests. Replace the per-file iflytek deserialization tests with a single test that asserts every bundled declarative provider parses through the same path load_fixed_providers uses, which otherwise silently skips invalid files.
|
Thanks for the review — both addressed in d03354d:
(And understood re: the earlier "closing, external repo" comment — thanks for clarifying.) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d03354d81b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "name": "iflytek", | ||
| "engine": "openai", | ||
| "display_name": "iFlytek Spark", | ||
| "description": "iFlytek Spark (讯飞星火) models via the OpenAI-compatible HTTP API. Authenticate with your Spark HTTP API password (APIPassword). Only the 4.0Ultra and Max model families are listed, since per the Spark HTTP docs they are the versions that accept system messages and Function Call (tools) — which goose always sends.", |
There was a problem hiding this comment.
Set Spark's tool_calls switch before enabling tools
For sessions with tools, selecting only Max/Ultra is not enough for Spark to behave like OpenAI: the Spark HTTP docs say tool_calls_switch defaults off and must be true to return function calls in the tool_calls array, while goose's OpenAI formatter only drives tool execution from tool_calls. This declarative config has no provider-level request param to add that switch, so Spark function calls can come back as JSON content and goose will not execute the requested tools; please add support for sending tool_calls_switch: true (or don't advertise Spark as tool-capable until it can be sent).
Useful? React with 👍 / 👎.
|
Thanks for the quick turnaround on the model list and the consolidated test — that's a nice improvement. Two things still open before this can land:
Snoozing for a few days to give you a chance to reply. |
Spark only returns OpenAI-style tool_calls when the request body sets tool_calls_switch=true, which the declarative config cannot inject, so the iflytek provider is best used for chat. Note this in the provider description and the providers table, and drop the stale 'lite' mention (lite was removed from iflytek.json earlier). Signed-off-by: FenjuFu <fufenjupku@gmail.com>
|
Thanks — you're right, and the codex point checks out against the Spark HTTP docs. On tool calling (1): Spark's chat-completions endpoint gates OpenAI-style tool calls behind a request-body flag: So I've framed this provider as chat-oriented rather than claiming tool support:
On the docs (2): good catch — dropped the stale Both in If you'd be open to it, I'm happy to follow up with a separate PR adding an optional request-body-params field to declarative providers (e.g. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8b0b02e5a7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| {"name": "xopdeepseekv4flash", "context_limit": 131072}, | ||
| {"name": "xopdeepseekv32", "context_limit": 131072}, | ||
| {"name": "xopkimik26", "context_limit": 262144}, | ||
| {"name": "xminimaxm25", "context_limit": 204800}, |
There was a problem hiding this comment.
Lower MiniMax context limit to the Token Plan cap
When xminimaxm25 is used with the default Astron Token Plan endpoint, this advertises a 204800-token window, but the official Token Plan table lists MiniMax-M2.5 as 128K (https://www.xfyun.cn/doc/spark/TokenPlan.html). The registry copies this value into ModelConfig and context management uses it for compaction decisions, so goose can keep sending more than the provider accepts and hit 10907/10910 token-limit errors instead of compacting earlier; please cap this entry to the documented 128K limit.
Useful? React with 👍 / 👎.
The xminimaxm25 model was listed with a 204800 context limit, but the Astron Token Plan documents a 128K (131072) cap for this model. Lower it to match.
|
Pushed a fix for the last codex comment: lowered Thanks for the iterations here — the consolidated |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c80f20f81d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| "dynamic_models": false, | ||
| "skip_canonical_filtering": true, | ||
| "models": [ | ||
| {"name": "4.0Ultra", "context_limit": 8192}, |
There was a problem hiding this comment.
Raise Spark Ultra's context limit
For 4.0Ultra, the Spark HTTP docs list Ultra's maximum input length as 32K (https://www.xfyun.cn/doc/spark/HTTP%E8%B0%83%E7%94%A8%E6%96%87%E6%A1%A3.html), but this config advertises only 8192. ProviderEntry::normalize_model_config backfills ModelConfig.context_limit from these JSON ModelInfo entries, so 4.0Ultra sessions will compact and drop context around 8K even though the provider accepts much more; please set this entry to the documented window.
Useful? React with 👍 / 👎.
| {"name": "xopdeepseekv4pro", "context_limit": 131072}, | ||
| {"name": "xopdeepseekv4flash", "context_limit": 131072}, |
There was a problem hiding this comment.
Raise Astron V4 context limits
The Astron Token Plan model table documents DeepSeek-V4-Pro and DeepSeek-V4-Flash with 1M context windows (https://www.xfyun.cn/doc/spark/TokenPlan.html), but both entries here are capped at 131072. Because these static limits are copied into the session model config before compaction decisions, users of either V4 model will unnecessarily lose most of the usable context instead of running near the provider's advertised 1M window.
Useful? React with 👍 / 👎.
DOsinga
left a comment
There was a problem hiding this comment.
LGTM. Two clean OpenAI-compatible declarative providers, the test consolidation is a real improvement, and the last codex comment on the MiniMax context limit is now addressed. Thanks for the thoughtful iterations!
* main: (26 commits) Fix MCP app sandbox bridge lifecycle (#10064) fix(bedrock): send inference config (max_tokens, temperature) on Converse (#9889) feat(providers): support OpenRouter request parameters (#9276) Migrate local inference model management to ACP (#10124) (attempt to) fix disk space errors in linux release builds (#10024) feat: add --edit session flag to edit conversation before forking (#9799) feat: add iFlytek Spark and Astron MaaS providers (#9837) fix(desktop): dedupe Nostr session deep link imports (#9918) [codex] Add SessionStart hook parity outside CLI (#9970) feat(providers): add Fireworks AI declarative provider (#9990) fix(providers): don't retry deterministically-permanent 400s (thinking-block immutability) (#10005) fix(deps): downgrade pkcs8 to v0.10 to match sec1/pkcs1 v0.7 (#10119) chore(deps): bump actions/cache from 5.0.2 to 6.0.0 (#10051) Make OpenAI Responses API store param configurable (#10040) remove unsupported model (#10121) chore(release): bump version to 1.40.0 (minor) (#10099) move ollama provider into goose-providers (#9986) UI acp migratoin: Decouple desktop UI types from generated OpenAPI types (#10109) fix(otel): use async reqwest client so OTLP export works in `goose serve` mode (#10100) feat (acp): exposed available tools in acp schema (#10097) ...
* main: (42 commits) Fix MCP app sandbox bridge lifecycle (#10064) fix(bedrock): send inference config (max_tokens, temperature) on Converse (#9889) feat(providers): support OpenRouter request parameters (#9276) Migrate local inference model management to ACP (#10124) (attempt to) fix disk space errors in linux release builds (#10024) feat: add --edit session flag to edit conversation before forking (#9799) feat: add iFlytek Spark and Astron MaaS providers (#9837) fix(desktop): dedupe Nostr session deep link imports (#9918) [codex] Add SessionStart hook parity outside CLI (#9970) feat(providers): add Fireworks AI declarative provider (#9990) fix(providers): don't retry deterministically-permanent 400s (thinking-block immutability) (#10005) fix(deps): downgrade pkcs8 to v0.10 to match sec1/pkcs1 v0.7 (#10119) chore(deps): bump actions/cache from 5.0.2 to 6.0.0 (#10051) Make OpenAI Responses API store param configurable (#10040) remove unsupported model (#10121) chore(release): bump version to 1.40.0 (minor) (#10099) move ollama provider into goose-providers (#9986) UI acp migratoin: Decouple desktop UI types from generated OpenAPI types (#10109) fix(otel): use async reqwest client so OTLP export works in `goose serve` mode (#10100) feat (acp): exposed available tools in acp schema (#10097) ...
* main: (31 commits) test: generic validator for declarative providers (#10010) UI acp migratoin: Decouple desktop UI types from generated OpenAPI types (Part 2) (#10149) Remove MCP sampling support (#10087) Support TLS for ACP serve (#10088) feat (ui): Migrate dictation local model manager to ACP (#10131) Fix MCP app sandbox bridge lifecycle (#10064) fix(bedrock): send inference config (max_tokens, temperature) on Converse (#9889) feat(providers): support OpenRouter request parameters (#9276) Migrate local inference model management to ACP (#10124) (attempt to) fix disk space errors in linux release builds (#10024) feat: add --edit session flag to edit conversation before forking (#9799) feat: add iFlytek Spark and Astron MaaS providers (#9837) fix(desktop): dedupe Nostr session deep link imports (#9918) [codex] Add SessionStart hook parity outside CLI (#9970) feat(providers): add Fireworks AI declarative provider (#9990) fix(providers): don't retry deterministically-permanent 400s (thinking-block immutability) (#10005) fix(deps): downgrade pkcs8 to v0.10 to match sec1/pkcs1 v0.7 (#10119) chore(deps): bump actions/cache from 5.0.2 to 6.0.0 (#10051) Make OpenAI Responses API store param configurable (#10040) remove unsupported model (#10121) ...
What
Adds two declarative OpenAI-compatible providers for iFlytek:
iflytek.json) — 讯飞星火 via the Spark HTTP API(
https://spark-api-open.xf-yun.com/v1). Ships4.0Ultra,generalv3.5,max-32k,generalv3,pro-128kandlite. Auth uses the Spark HTTP APIpassword (
SPARK_API_PASSWORD).iflytek_astron.json) — 讯飞星辰 MaaS. Defaults to theToken Plan endpoint (
https://maas-token-api.cn-huabei-1.xf-yun.com/v2) andexposes
ASTRON_BASE_URLso users can switch to the Coding Plan(
https://maas-coding-api.cn-huabei-1.xf-yun.com/v2, e.g.astron-code-latest).Ships Spark X2, DeepSeek, GLM, Kimi, MiniMax, Qwen and the Astron coding model.
Auth uses
ASTRON_API_KEY.Both follow the existing declarative-provider pattern (cf.
zhipu.json,moonshot.json,alibaba.json).Why
iFlytek Spark and Astron MaaS are widely used in China and both expose
OpenAI-compatible endpoints, so shipping them as built-in declarative providers
lets users select them directly from the provider list instead of hand-rolling a
custom provider.
Notes
base_urluses only the/vNpath segment;derive_base_pathresolves it to…/vN/chat/completions, which both endpoints expect.skip_canonical_filtering: trueis set because the model ids areprovider-specific (
4.0Ultra,xsparkx2, …) and are not in the canonicalcatalog; without it the inventory filter would drop every model. Each model
ships an explicit
context_limitinstead.dynamic_models: falsekeeps the static lists authoritative and avoids aruntime dependency on a
/modelsendpoint.Testing
test_iflytek_json_deserializesandtest_iflytek_astron_json_deserializesalongside the existing per-provider deserialization tests.
References