Compare commits

...
2 Commits
Author SHA1 Message Date
infosave2007 5d8455b4a0 v0.2.35
Docker / publish (push) Canceled after 0s
Release / crates-io (push) Canceled after 0s
Release / release (macos-14, aarch64-apple-darwin) (push) Canceled after 0s
Release / release (ubuntu-latest, x86_64-unknown-linux-gnu) (push) Canceled after 0s
Release / release (windows-latest, x86_64-pc-windows-msvc) (push) Canceled after 0s
2026-07-23 21:25:45 +03:00
infosave2007 b255c60b0b chore: update lockfile 2026-07-23 16:41:58 +03:00
6 changed files with 50 additions and 4 deletions
+7 -1
View File
@@ -3,7 +3,13 @@
All notable changes to this project are documented here.
The format is based on [Keep a Changelog](https://keepachangelog.com/).
## [0.2.32] - 2026-07-22
## [0.2.35] - 2026-07-23
### Fixed
- **Streaming Pipeline System Prompt Merging**: Fixed system prompt injection in `run_stream` so configured model system prompts and reasoning suppression directives are properly passed into streaming requests.
- **CMF Reasoning Mode Compatibility**: Fully integrated with `cortiq-engine` v0.5.17 for sampler-level logit bias reasoning token suppression and zero-token thinking bypass.
## [0.2.34] - 2026-07-23
### Added
- **Responsive mobile admin console**: Added a hamburger navigation drawer, touch-friendly controls, phone-sized forms and cards, scrollable tables, compact toolbars, safe-area support, and mobile bottom-sheet dialogs across the admin interface.
Generated
+1 -1
View File
@@ -285,7 +285,7 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
[[package]]
name = "cortiq-gateway"
version = "0.2.33"
version = "0.2.34"
dependencies = [
"anyhow",
"arc-swap",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "cortiq-gateway"
version = "0.2.34"
version = "0.2.35"
edition = "2021"
rust-version = "1.75"
license = "Apache-2.0"
+7 -1
View File
@@ -99,6 +99,7 @@ async fn main() -> anyhow::Result<()> {
let mut app = Router::new()
.route("/healthz", get(|| async { "ok" }))
.route("/health", get(|| async { "ok" }))
.route("/readyz", get(|| async { "ready" }))
.route("/metrics", get(admin::metrics))
.merge(protocols::build_router());
@@ -109,7 +110,12 @@ async fn main() -> anyhow::Result<()> {
.fallback(admin::assets::fallback);
}
let app = app.with_state(state);
let cors = tower_http::cors::CorsLayer::new()
.allow_origin(tower_http::cors::Any)
.allow_methods(tower_http::cors::Any)
.allow_headers(tower_http::cors::Any);
let app = app.with_state(state).layer(cors);
let listener = tokio::net::TcpListener::bind(&listen).await?;
tracing::info!("cortiq-gateway listening on {listen}");
+28
View File
@@ -487,6 +487,20 @@ impl Pipeline {
if req_call.params.think_budget.is_none() {
req_call.params.think_budget = m_cfg.think_budget;
}
if let Some(sys) = &m_cfg.system_prompt {
if !sys.trim().is_empty()
&& !req_call.messages.iter().any(|m| m.role == "system")
{
req_call.messages.insert(
0,
Message {
role: "system".into(),
content: sys.clone(),
tool_calls: Vec::new(),
},
);
}
}
} else if let Some(s_cfg) = live.cfg.cmf.servers.iter().find(|s| s.id == model_id) {
if req_call.params.temperature.is_none() {
req_call.params.temperature = s_cfg.temperature;
@@ -500,6 +514,20 @@ impl Pipeline {
if req_call.params.think_budget.is_none() {
req_call.params.think_budget = s_cfg.think_budget;
}
if let Some(sys) = &s_cfg.system_prompt {
if !sys.trim().is_empty()
&& !req_call.messages.iter().any(|m| m.role == "system")
{
req_call.messages.insert(
0,
Message {
role: "system".into(),
content: sys.clone(),
tool_calls: Vec::new(),
},
);
}
}
}
match provider.chat_stream(req_call).await {
+6
View File
@@ -48,11 +48,13 @@ impl OpenAiProvider {
if let Some(m) = req.params.max_tokens {
body["max_tokens"] = m.into();
}
eprintln!("[to_wire] think_budget={:?}", req.params.think_budget);
if let Some(tb) = req.params.think_budget {
body["think_budget"] = tb.into();
body["reasoning_effort"] = tb.into();
// cortiq serve uses enable_thinking (bool): 0 = off, >0 = on
body["enable_thinking"] = (tb > 0).into();
eprintln!("[to_wire] SET enable_thinking={}", tb > 0);
}
if !req.tools.is_empty() {
body["tools"] = serde_json::Value::Array(req.tools.clone());
@@ -61,6 +63,10 @@ impl OpenAiProvider {
for (k, v) in &req.params.passthrough {
body[k] = v.clone();
}
eprintln!(
"[to_wire] enable_thinking={:?}",
body.get("enable_thinking")
);
body
}
}