chore(ci/triage): add detailed safety debug (request-id, error body excerpt, key presence mask); set Accept+originator headers; keep Responses v1

This commit is contained in:
James Peter
2025-09-13 01:09:12 +10:00
parent 7d4601a2f1
commit 12262a92e4
2 changed files with 47 additions and 16 deletions
+32 -8
View File
@@ -303,6 +303,13 @@ jobs:
'Output must strictly match the JSON schema provided via text.format.'
].join(' ');
function mask(s) {
if (!s) return '';
const t = String(s);
if (t.length <= 8) return '<len='+t.length+"/>";
return t.slice(0,3) + '…' + t.slice(-4) + ` <len=${t.length}>`;
}
async function callResponses(model) {
const input = [
{
@@ -346,13 +353,25 @@ jobs:
parallel_tool_calls: false
};
return fetch(base + '/responses', {
const url = base + '/responses';
const headers = {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': `Bearer ${apiKey}`,
'OpenAI-Beta': 'responses=v1',
'originator': 'codex_ci_triage',
'version': '0.0.0'
};
// Minimal debug context (no secrets)
try {
core.notice(`Safety: calling ${model} at /responses (payload bytes=${Buffer.from(JSON.stringify(payload)).length})`);
const keyInfo = apiKey ? `present (${mask(apiKey)})` : 'missing';
core.notice(`Safety: OPENAI_API_KEY=${keyInfo}`);
} catch {}
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`,
'OpenAI-Beta': 'responses=v1'
},
headers,
body: JSON.stringify(payload)
});
}
@@ -364,9 +383,14 @@ jobs:
res = await callResponses('gpt-4o-mini');
}
if (!res.ok) {
let body = '';
try { body = await res.text(); } catch {}
const rid = res.headers.get('x-request-id') || '-';
const excerpt = body && body.length > 800 ? body.slice(0,800) + '…' : body;
core.setOutput('decision', 'comment_only');
core.setOutput('reason', `Safety API error: ${res.status} ${res.statusText}`);
core.notice(`Safety: comment_only (API ${res.status} ${res.statusText})`);
core.setOutput('reason', `Safety API error: ${res.status} ${res.statusText} (request-id: ${rid})`);
core.notice(`Safety: comment_only (API ${res.status} ${res.statusText}; request-id: ${rid})`);
if (excerpt) core.notice(`Safety: error body: ${excerpt}`);
} else {
const data = await res.json();
let json = {};
@@ -309,11 +309,12 @@ impl ThemeSelectionView {
std::sync::Arc::new(cfg.clone()),
Some(auth_mgr),
cfg.model_provider.clone(),
codex_core::config_types::ReasoningEffort::Medium,
codex_core::config_types::ReasoningEffort::Low,
cfg.model_reasoning_summary,
cfg.model_text_verbosity,
uuid::Uuid::new_v4(),
std::sync::Arc::new(std::sync::Mutex::new(codex_core::debug_logger::DebugLogger::new(false).unwrap_or_else(|_| codex_core::debug_logger::DebugLogger::new(false).expect("debug logger")))),
// Enable debug logs for targeted triage of stream issues
std::sync::Arc::new(std::sync::Mutex::new(codex_core::debug_logger::DebugLogger::new(true).unwrap_or_else(|_| codex_core::debug_logger::DebugLogger::new(false).expect("debug logger")))),
);
// Build developer guidance and input
@@ -382,12 +383,18 @@ impl ThemeSelectionView {
// If we received no content at all, surface the transport error explicitly
if out.trim().is_empty() {
let err = last_err
.map(|e| format!("model stream error: {}", e))
.unwrap_or_else(|| "model stream returned no content".to_string());
let _ = progress_tx.send(ProgressMsg::CompletedErr {
error: err,
_raw_snippet: String::new(),
});
.map(|e| format!(
"model stream error: {} | raw_out_len={} think_len={}",
e,
out.len(),
think_sum.len()
))
.unwrap_or_else(|| format!(
"model stream returned no content | raw_out_len={} think_len={}",
out.len(),
think_sum.len()
));
let _ = progress_tx.send(ProgressMsg::CompletedErr { error: err, _raw_snippet: String::new() });
return;
}