3 Commits
Author SHA1 Message Date
Matteo Pietro DazziandGitHub 862154541a feat: add MiniMax quota fetcher and brand icon (#1662)
* feat(server): add MiniMax quota fetcher

Mirror the live multi-provider quota panel (#1278) for MiniMax. Resolves the
bearer token from $MINIMAX_API_KEY or the MiniMax CLI config at
~/.mmx/config.json (api_key, oauth.access_token) and credentials at
~/.mmx/credentials.json, then queries the /v1/token_plan/remains endpoint on
the configured region (global by default, cn when region='cn'). The response
is normalized into ProviderUsage windows per model_remains entry, surfacing
the interval and weekly limits with their reset times and a danger tone when
the server reports status=2.

* feat(app): add MiniMax brand icon for usage page

The quota panel resolves the icon via resolveProviderIconName, which falls
back to a generic Bot for any provider not in BUILTIN_PROVIDER_ICON_NAMES.
Register 'minimax' as a built-in icon and vendor the official 24×24 brand
mark (single Path, currentColor) as MiniMaxIcon so the usage card stops
showing the generic robot.

* refactor(server): flatten nested ternaries in MiniMax quota fetcher

Greptile review on #1662 called out two nested ternaries in toIntervalWindow
and toWeeklyWindow. Extract a toneForStatus helper that uses an explicit
if/else chain so the same status-to-tone mapping is shared between the
interval and weekly windows, and add the missing trailing newline.

* fix: format
2026-06-26 14:14:29 +08:00
Matteo Pietro DazziandGitHub 1377adbece fix(claude): respect profile models for built-in claude provider (#1311)
* fix(claude): respect profile models for built-in claude provider

The built-in Claude provider was the only one in the registry whose
profile `models` array was treated as additive on top of the hardcoded
first-party catalog. Every other built-in provider (and every custom
provider) replaces the runtime model list when `models` is set, which
matches the documented behavior in docs/custom-providers.md.

For users pointing Claude Code at a third-party Anthropic-compatible
gateway (Z.AI, Alibaba/Qwen, MiniMax, custom proxies, …) and curating
the picker with `agents.providers.claude.models`, the old behavior
leaked the nine first-party Claude models into the dropdown, making it
impossible to ship a curated list. This is issue #1299.

The fix flips the built-in Claude entry in `provider-registry.ts` to
match the other providers, so `models` replaces the runtime catalog
(including the settings.json-discovered entries surfaced by
getClaudeModelsWithSettings). The existing `additionalModels` field
keeps its additive semantics for anyone who still wants to append
entries on top of the first-party list.

- provider-registry.ts: drop the claude-only `profileModelsAreAdditive`
  branch and align with the rest of the registry.
- provider-registry.test.ts: update the "append to runtime models"
  expectation for built-in Claude to "replace runtime models" and add a
  regression test that mirrors the issue scenario (hardcoded catalog +
  configured profile models, expect only the profile models).
- agent.test.ts: make the "returns hardcoded claude models" hermetic by
  pointing CLAUDE_CONFIG_DIR at an empty temp dir; the test was reading
  the host's real ~/.claude/settings.json (which now contains MiniMax
  env vars from the issue report) and leaking that into the assertion.
- custom-providers.md: correct the note about Claude profile models
  being additive and document the new replace semantics alongside
  additionalModels.

Closes #1299

* test(claude): drop explanatory comments from new tests

* refactor(claude): inject configDir into ClaudeAgentClient for test hermeticity

Greptile flagged the previous hermeticity fix on agent.test.ts: mutating
process.env.CLAUDE_CONFIG_DIR inside a test leaks the redirection into
any concurrent test in the same process for the duration of the try
block.

Thread a `configDir` option through ClaudeAgentClient ->
getClaudeModelsWithSettings -> readClaudeSettingsModels ->
resolveClaudeConfigDir instead. The constructor follows the same
injection pattern as `resolveBinary`, so the test passes an empty temp
dir via the option and no shared global state is touched.

- models.ts: add an optional `configDir` to
  getClaudeModelsWithSettings, readClaudeSettingsModels, and
  resolveClaudeConfigDir. Env var remains the fallback for production
  callers.
- agent.ts: add `configDir?` to ClaudeAgentClientOptions, store it on
  the instance, and forward it to getClaudeModelsWithSettings from
  listModels.
- agent.test.ts: drop the process.env save/mutate/restore dance and
  pass `configDir: emptyConfigDir` to the constructor instead.

Refs #1311
2026-06-05 20:58:38 +08:00
Matteo Pietro DazziandGitHub e58ea31d6d chore: upgrade vitest (#1091)
* chore: upgrade vitest

* chore: sync lock
2026-05-20 12:14:13 +00:00