feat: add skill injected counter metric (#9575)

This commit is contained in:
alexsong-oai 2026-01-20 19:05:37 -08:00 committed by GitHub
parent 0523a259c8
commit fabc2bcc32
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 1 deletions

View file

@ -2812,10 +2812,11 @@ pub(crate) async fn run_turn(
.await,
);
let otel_manager = turn_context.client.get_otel_manager();
let SkillInjections {
items: skill_items,
warnings: skill_warnings,
} = build_skill_injections(&input, skills_outcome.as_ref()).await;
} = build_skill_injections(&input, skills_outcome.as_ref(), Some(&otel_manager)).await;
for message in skill_warnings {
sess.send_event(&turn_context, EventMsg::Warning(WarningEvent { message }))

View file

@ -4,6 +4,7 @@ use std::path::PathBuf;
use crate::instructions::SkillInstructions;
use crate::skills::SkillLoadOutcome;
use crate::skills::SkillMetadata;
use codex_otel::OtelManager;
use codex_protocol::models::ResponseItem;
use codex_protocol::user_input::UserInput;
use tokio::fs;
@ -17,6 +18,7 @@ pub(crate) struct SkillInjections {
pub(crate) async fn build_skill_injections(
inputs: &[UserInput],
skills: Option<&SkillLoadOutcome>,
otel: Option<&OtelManager>,
) -> SkillInjections {
if inputs.is_empty() {
return SkillInjections::default();
@ -40,6 +42,7 @@ pub(crate) async fn build_skill_injections(
for skill in mentioned_skills {
match fs::read_to_string(&skill.path).await {
Ok(contents) => {
emit_skill_injected_metric(otel, &skill, "ok");
result.items.push(ResponseItem::from(SkillInstructions {
name: skill.name,
path: skill.path.to_string_lossy().into_owned(),
@ -47,6 +50,7 @@ pub(crate) async fn build_skill_injections(
}));
}
Err(err) => {
emit_skill_injected_metric(otel, &skill, "error");
let message = format!(
"Failed to load skill {name} at {path}: {err:#}",
name = skill.name,
@ -60,6 +64,18 @@ pub(crate) async fn build_skill_injections(
result
}
fn emit_skill_injected_metric(otel: Option<&OtelManager>, skill: &SkillMetadata, status: &str) {
let Some(otel) = otel else {
return;
};
otel.counter(
"codex.skill.injected",
1,
&[("status", status), ("skill", skill.name.as_str())],
);
}
fn collect_explicit_skill_mentions(
inputs: &[UserInput],
skills: &[SkillMetadata],