1jehuang / 1jehuang/jcode

Custom OpenAI-compatible providers: add per-model display_name, reasoning, max_output_tokens, cost, and provider display_name (opencode parity)

Open
#571 7 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement from-pr priority: medium triage: needs-decision
Dominant language
Rust
Stars
19.9k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
30

Description

Summary

Custom OpenAI-compatible providers configured via [providers.<name>] in ~/.jcode/config.toml were missing several fields that opencode supports for its custom OpenAI-compatible provider spec. This made it harder to get a clean model picker experience and correct cost display for self-hosted or third-party gateways.

Gaps identified

Feature opencode jcode (before) Status
Provider display name (name) ❌ (raw profile key) Fixed
Per-model display name (name) ❌ (raw model id) Fixed
Per-model cost (cost.input/output/cache_read/cache_write) Fixed
Per-model max output tokens (limit.output) Fixed
Per-model reasoning bool (reasoning) provider-level only Fixed
Per-model context_window Already present
Per-model image input (input) Already present

Changes

Config schema (jcode-config-types)
  • New ModelCostConfig struct: input, output, cache_read, cache_write (USD per million tokens)
  • New fields on NamedProviderModelConfig: display_name (alias name), max_output_tokens (alias output_limit), reasoning (bool), cost (ModelCostConfig)
  • New field on NamedProviderConfig: display_name (provider-level)
Runtime wiring (jcode-provider-openrouter-runtime)
  • available_models_display(): applies per-model display name aliases in the picker
  • runtime_display_name() + direct_openai_compatible_route_parts(): use provider display_name
  • supports_deepseek_reasoning_effort() / supports_openai_reasoning_effort(): check per-model reasoning override first
  • complete(): per-model max_output_tokens overrides runtime default in the request body
  • fork(): carries all new fields
Picker routes (jcode-base/provider/catalog_routes.rs)
  • named_provider_profile_routes(): uses provider display_name as route label, per-model display_name as route model field, and converts cost config into RouteCheapnessEstimate for the picker cost overlay
  • New cost_to_route_cheapness() helper
Tests
  • 7 new tests in openrouter_tests.rs covering display name, reasoning, max_output_tokens, and cost
  • 2 new tests in catalog_routes.rs covering route display name + cost cheapness conversion
Docs
  • README updated with new config field descriptions and enriched config.toml example

Config example

[providers.my-api]
type = "openai-compatible"
base_url = "https://llm.example.com/v1"
api_key_env = "JCODE_PROVIDER_MY_API_API_KEY"
default_model = "my-model-id"
display_name = "My Custom API"

[[providers.my-api.models]]
id = "my-model-id"
context_window = 128000
display_name = "My Model"
max_output_tokens = 8192
reasoning = true
cost = { input = 0.15, output = 0.60, cache_read = 0.015 }

Branch

fix/custom_openai_compatible

Verification

  • Full workspace cargo check passes cleanly
  • 99 jcode-provider-openrouter-runtime lib tests pass (7 new)
  • 2 jcode-base catalog_routes tests pass (2 new)
  • All existing tests unaffected

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the config types in jcode-config-types, then trace provider handling through jcode-provider-openrouter-runtime and jcode-base/provider/catalog_routes.rs. Run the named openrouter_tests.rs and catalog_routes.rs tests; done means the documented provider and model fields are represented in runtime requests and picker routes, with the README example consistent.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
api, cli
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.