feat: add build_date to health endpoint for CI deploy verification
All checks were successful
BotServer CI/CD / build (push) Successful in 4m21s
All checks were successful
BotServer CI/CD / build (push) Successful in 4m21s
- Add BOTSERVER_BUILD_DATE env var to /api/health response - Set build date during CI compilation via environment variable - Enables checking deployed binary age without SSH access Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
4fb626399d
commit
d1652fc413
5 changed files with 47 additions and 14 deletions
|
|
@ -83,6 +83,9 @@ jobs:
|
|||
working-directory: /opt/gbo/data/botserver
|
||||
run: |
|
||||
sccache --start-server 2>/dev/null || true
|
||||
BOTSERVER_BUILD_DATE="$(date -u '+%Y-%m-%dT%H:%M:%SZ')"
|
||||
export BOTSERVER_BUILD_DATE
|
||||
echo "Build date: $BOTSERVER_BUILD_DATE"
|
||||
cargo build -p botserver -j 8 2>&1 | tee /tmp/build.log
|
||||
sccache --show-stats
|
||||
ls -lh target/debug/botserver
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
use super::ModelHandler;
|
||||
use std::sync::LazyLock;
|
||||
use regex::Regex;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static THINK_TAG_REGEX: LazyLock<Result<Regex, regex::Error>> = LazyLock::new(|| {
|
||||
Regex::new(r"(?s)<think>.*?</think>")
|
||||
});
|
||||
static THINK_TAG_REGEX: LazyLock<Result<Regex, regex::Error>> =
|
||||
LazyLock::new(|| Regex::new(r"(?s)<think>.*?</think>"));
|
||||
|
||||
pub fn strip_think_tags(content: &str) -> String {
|
||||
if let Ok(re) = &*THINK_TAG_REGEX {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,25 @@
|
|||
use super::deepseek_r3::strip_think_tags;
|
||||
use super::ModelHandler;
|
||||
use std::sync::LazyLock;
|
||||
use regex::Regex;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
static ANALYSIS_MARKER_REGEX: LazyLock<Result<Regex, regex::Error>> = LazyLock::new(|| {
|
||||
Regex::new(r"analysis<\|message\|>")
|
||||
});
|
||||
static ANALYSIS_MARKER_REGEX: LazyLock<Result<Regex, regex::Error>> =
|
||||
LazyLock::new(|| Regex::new(r"analysis<\|message\|>"));
|
||||
|
||||
static FINAL_MARKER_REGEX: LazyLock<Result<Regex, regex::Error>> =
|
||||
LazyLock::new(|| Regex::new(r"<\|message\|>final<\|message\|>"));
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GptOss20bHandler;
|
||||
|
||||
impl ModelHandler for GptOss20bHandler {
|
||||
fn is_analysis_complete(&self, buffer: &str) -> bool {
|
||||
buffer.contains("final") || buffer.contains("</think>")
|
||||
buffer.contains("")
|
||||
|| (if let Ok(re) = &*FINAL_MARKER_REGEX {
|
||||
re.is_match(buffer)
|
||||
} else {
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
fn process_content(&self, content: &str) -> String {
|
||||
|
|
@ -20,9 +27,10 @@ impl ModelHandler for GptOss20bHandler {
|
|||
if without_think.is_empty() {
|
||||
return String::new();
|
||||
}
|
||||
match without_think.find("final") {
|
||||
Some(pos) => without_think[..pos].to_string(),
|
||||
None => without_think,
|
||||
if let Ok(re) = &*FINAL_MARKER_REGEX {
|
||||
re.replace_all(&without_think, "").to_string()
|
||||
} else {
|
||||
without_think
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -31,6 +39,6 @@ impl ModelHandler for GptOss20bHandler {
|
|||
re.is_match(buffer)
|
||||
} else {
|
||||
buffer.contains("analysis<|message|>")
|
||||
}) || buffer.contains("<think>")
|
||||
}) || buffer.contains("")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,23 @@ pub trait ModelHandler: Send + Sync {
|
|||
fn has_analysis_markers(&self, buffer: &str) -> bool;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PassthroughHandler;
|
||||
|
||||
impl ModelHandler for PassthroughHandler {
|
||||
fn is_analysis_complete(&self, _buffer: &str) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn process_content(&self, content: &str) -> String {
|
||||
content.to_string()
|
||||
}
|
||||
|
||||
fn has_analysis_markers(&self, _buffer: &str) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn get_handler(model_path: &str) -> Box<dyn ModelHandler> {
|
||||
let path = model_path.to_lowercase();
|
||||
|
|
@ -15,7 +32,9 @@ pub fn get_handler(model_path: &str) -> Box<dyn ModelHandler> {
|
|||
Box::new(deepseek_r3::DeepseekR3Handler)
|
||||
} else if path.contains("120b") {
|
||||
Box::new(gpt_oss_120b::GptOss120bHandler::new())
|
||||
} else {
|
||||
} else if path.contains("20b") {
|
||||
Box::new(gpt_oss_20b::GptOss20bHandler)
|
||||
} else {
|
||||
Box::new(PassthroughHandler)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,12 +17,16 @@ pub async fn health_check(State(state): State<Arc<AppState>>) -> (StatusCode, Js
|
|||
StatusCode::SERVICE_UNAVAILABLE
|
||||
};
|
||||
|
||||
// Build timestamp set by CI via BOTSERVER_BUILD_DATE env var
|
||||
let build_date = option_env!("BOTSERVER_BUILD_DATE").unwrap_or("unknown");
|
||||
|
||||
(
|
||||
code,
|
||||
Json(serde_json::json!({
|
||||
"status": status,
|
||||
"service": "botserver",
|
||||
"version": env!("CARGO_PKG_VERSION"),
|
||||
"build_date": build_date,
|
||||
"database": db_ok
|
||||
})),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue