feat(phase9): LlmEngine::extract_content_tags + smoke test
Added as a method on LlmEngine alongside cleanup_text and extract_tasks; same render_chat_prompt -> generate -> parse pattern. Truncates the transcript to its trailing 2000 chars on a UTF-8 char boundary, runs at temperature 0.0 with the CONTENT_TAGS_GRAMMAR GBNF, and re-validates intent against INTENT_CLOSED_SET to catch the unlikely grammar bypass case. max_tokens 96 is enough for the JSON envelope. Smoke test gated on KON_LLM_TEST_MODEL like the existing smoke.rs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
48
crates/llm/tests/content_tags_smoke.rs
Normal file
48
crates/llm/tests/content_tags_smoke.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
//! Smoke test for Phase 9 LlmEngine::extract_content_tags.
|
||||
//!
|
||||
//! Gated behind the same `KON_LLM_TEST_MODEL` env var as the existing
|
||||
//! smoke.rs test so neither runs in default `cargo test` runs (model
|
||||
//! load is heavy). Run explicitly with:
|
||||
//!
|
||||
//! KON_LLM_TEST_MODEL=/path/to/model.gguf cargo test -p kon-llm \
|
||||
//! --test content_tags_smoke -- --nocapture
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use kon_llm::{is_valid_intent, LlmEngine, LlmModelId};
|
||||
|
||||
#[test]
|
||||
fn extract_content_tags_returns_valid_pair() {
|
||||
let model_path = match env::var("KON_LLM_TEST_MODEL") {
|
||||
Ok(path) => PathBuf::from(path),
|
||||
Err(_) => {
|
||||
eprintln!("KON_LLM_TEST_MODEL not set — skipping");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let engine = LlmEngine::new();
|
||||
engine
|
||||
.load_model(LlmModelId::Qwen3_1_7B_Q4, &model_path, true)
|
||||
.expect("load model");
|
||||
|
||||
let transcript = "Tomorrow I need to run through the grant application one more time \
|
||||
and make sure the figures add up. I also need to book a slot with \
|
||||
Rachmann for the Mac test and email Andrew about the meeting window.";
|
||||
let tags = engine
|
||||
.extract_content_tags(transcript)
|
||||
.expect("extract_content_tags");
|
||||
|
||||
assert!(tags.topic.len() >= 3, "topic present: {tags:?}");
|
||||
assert!(
|
||||
tags.topic
|
||||
.chars()
|
||||
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-'),
|
||||
"topic lowercase + slugged: {tags:?}",
|
||||
);
|
||||
assert!(
|
||||
is_valid_intent(&tags.intent),
|
||||
"intent in closed set: {tags:?}",
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user