Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions crates/openfang-kernel/src/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6895,8 +6895,12 @@ fn infer_provider_from_model(model: &str) -> Option<String> {
"minimax" | "gemini" | "anthropic" | "openai" | "groq" | "deepseek" | "mistral"
| "cohere" | "xai" | "ollama" | "together" | "fireworks" | "perplexity"
| "cerebras" | "sambanova" | "replicate" | "huggingface" | "ai21" | "codex"
| "claude-code" | "copilot" | "github-copilot" | "qwen" | "zhipu" | "zai"
| "moonshot" | "openrouter" | "volcengine" | "doubao" | "dashscope" => {
| "codex_app_server" | "codex-app-server" | "claude-code" | "copilot"
| "github-copilot" | "qwen" | "zhipu" | "zai" | "moonshot" | "openrouter"
| "volcengine" | "doubao" | "dashscope" => {
if prefix == "codex-app-server" {
return Some("codex_app_server".to_string());
}
return Some(prefix.to_string());
}
// "kimi" is a brand alias for moonshot
Expand Down Expand Up @@ -9062,7 +9066,14 @@ mod tests {

// The local providers the user did NOT configure must NOT show up.
// This is what makes the issue #1031 probe noise go away.
for unwanted in &["vllm", "lmstudio", "lemonade", "claude-code", "qwen-code"] {
for unwanted in &[
"vllm",
"lmstudio",
"lemonade",
"claude-code",
"codex_app_server",
"qwen-code",
] {
assert!(
!referenced.contains(*unwanted),
"unconfigured local provider {unwanted:?} must NOT be in the referenced set ({referenced:?})"
Expand Down
15 changes: 15 additions & 0 deletions crates/openfang-kernel/src/metering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,21 @@ pub struct BudgetStatus {
/// Order matters: more specific patterns must come before generic ones
/// (e.g. "gpt-4o-mini" before "gpt-4o", "gpt-4.1-mini" before "gpt-4.1").
fn estimate_cost_rates(model: &str) -> (f64, f64) {
// Codex app-server uses ChatGPT subscription auth via the Codex CLI. Keep
// usage events visible while leaving per-token cost at zero for flat-rate
// subscription billing.
//
// Match only the canonical provider id forms (with optional model suffix
// separated by '/'). Substring `.contains` would zero-cost a user-named
// model like `my-codex_app_server-eval`.
if model == "codex_app_server"
|| model == "codex-app-server"
|| model.starts_with("codex_app_server/")
|| model.starts_with("codex-app-server/")
{
return (0.0, 0.0);
}

// ── Requesty (issue #995) ──────────────────────────────────
// Router-style gateway. IDs are `requesty/<upstream>/<model>` and
// resolve via substring match on the upstream model name below
Expand Down
Loading