Synced from monorepo
Synced from monorepo Changes: - Refresh tool search when the managed MCP catalog is re-fetched - Prevent duplicate leader process spawn and startup hang from stale leaders - Document marketplaces, plugins, and organization controls - Stamp session ID on image generation direct-to-API requests - Fix auto mode blocked documentation - Auto mode considers recent user intent - Expose deploy archive, taken-down, limit, and in-progress reasons on the chat API - Fail-closed auth refresh contract for shell clients - Emit a chat-supplied per-session turn index in turn hooks - Show bash mode chrome in minimal mode - Add metrics for true-noop and stationarity stops - Include voice interim text on prompt submit - Silently end turn on true-noop thrash - Quiet copy toast when clipboard delivery is confirmed - Fix session fork truncating at the wrong prompt in rewound sessions - Make the idle "still running" watcher cue clickable to open the tasks pane - Default web search model to grok-4.5 - Let plugin subagents inherit parent MCP servers - Gate no-op end-turn reminder on system reminders - Add gateway bridge lifecycle telemetry - Allow editing finalized text while voice is open - Relocate token carrier to turn-commit events and plumb per-turn origin context - Raise workflow scratch quotas and make failed runs resumable - Workflows overlay: auto-progress phases, live agent status, and drop budget meter Source-Revision: 9b8d35b46d959c042ea9aa31cbbebbd1f0c5c527
This commit is contained in:
parent
69f0ba880a
commit
6e38642082
103 changed files with 4964 additions and 1261 deletions
|
|
@ -467,6 +467,79 @@ mod inner {
|
|||
pub(crate) fn admission_wait_observe(secs: f64) {
|
||||
ADMISSION_WAIT_SECONDS.observe(secs);
|
||||
}
|
||||
|
||||
// ── OIDC refresh (auth.current path) ────────────────────────────
|
||||
|
||||
/// Closed-set outcomes for `AuthProvider::current` (metric labels).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum OidcRefreshOutcome {
|
||||
SkippedNotExpired,
|
||||
Ok,
|
||||
FailedUsedStale,
|
||||
}
|
||||
|
||||
impl OidcRefreshOutcome {
|
||||
pub const fn as_str(self) -> &'static str {
|
||||
match self {
|
||||
Self::SkippedNotExpired => "skipped_not_expired",
|
||||
Self::Ok => "ok",
|
||||
Self::FailedUsedStale => "failed_used_stale",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static OIDC_REFRESH_TOTAL: LazyLock<IntCounterVec> = LazyLock::new(|| {
|
||||
register_int_counter_vec!(
|
||||
"computer_hub_oidc_refresh_total",
|
||||
"OIDC AuthProvider::current outcomes: skipped_not_expired (no network), \
|
||||
ok (refresh succeeded), failed_used_stale (refresh failed, stale token returned).",
|
||||
&["outcome"]
|
||||
)
|
||||
.expect("computer_hub_oidc_refresh_total must register once")
|
||||
});
|
||||
|
||||
static OIDC_REFRESH_DURATION_SECONDS: LazyLock<Histogram> = LazyLock::new(|| {
|
||||
register_histogram!(
|
||||
"computer_hub_oidc_refresh_duration_seconds",
|
||||
"Wall-clock time of an attempted OIDC refresh (discovery + token exchange). \
|
||||
Not sampled for skipped_not_expired.",
|
||||
exponential_buckets(0.01, 2.0, 14).expect("valid bucket params")
|
||||
)
|
||||
.expect("computer_hub_oidc_refresh_duration_seconds must register once")
|
||||
});
|
||||
|
||||
/// Duration observed only for attempted refreshes (`Ok` / `FailedUsedStale`).
|
||||
pub(crate) fn oidc_refresh_observe(outcome: OidcRefreshOutcome, secs: Option<f64>) {
|
||||
OIDC_REFRESH_TOTAL
|
||||
.with_label_values(&[outcome.as_str()])
|
||||
.inc();
|
||||
if let Some(secs) = secs {
|
||||
OIDC_REFRESH_DURATION_SECONDS.observe(secs);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn oidc_refresh_count(outcome: OidcRefreshOutcome) -> u64 {
|
||||
OIDC_REFRESH_TOTAL
|
||||
.with_label_values(&[outcome.as_str()])
|
||||
.get()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn oidc_refresh_duration_sample_count() -> u64 {
|
||||
OIDC_REFRESH_DURATION_SECONDS.get_sample_count()
|
||||
}
|
||||
|
||||
/// Serializes OIDC metric delta assertions under parallel `cargo test`.
|
||||
#[cfg(test)]
|
||||
static OIDC_METRICS_TEST_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn lock_oidc_metrics_test() -> std::sync::MutexGuard<'static, ()> {
|
||||
OIDC_METRICS_TEST_LOCK
|
||||
.lock()
|
||||
.unwrap_or_else(|poisoned| poisoned.into_inner())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "metrics"))]
|
||||
|
|
@ -507,8 +580,16 @@ mod inner {
|
|||
pub(crate) fn tool_call_inflight_inc(_scope: &str) {}
|
||||
pub(crate) fn tool_call_inflight_dec(_scope: &str) {}
|
||||
pub(crate) fn admission_wait_observe(_secs: f64) {}
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum OidcRefreshOutcome {
|
||||
SkippedNotExpired,
|
||||
Ok,
|
||||
FailedUsedStale,
|
||||
}
|
||||
pub(crate) fn oidc_refresh_observe(_outcome: OidcRefreshOutcome, _secs: Option<f64>) {}
|
||||
}
|
||||
|
||||
pub(crate) use inner::OidcRefreshOutcome;
|
||||
pub(crate) use inner::admission_wait_observe;
|
||||
pub(crate) use inner::call_dispatch_observe;
|
||||
pub(crate) use inner::call_id_collision;
|
||||
|
|
@ -524,8 +605,15 @@ pub(crate) use inner::inbox_full_notification_dropped;
|
|||
pub(crate) use inner::inbox_full_reject_send_failed;
|
||||
pub(crate) use inner::inbox_full_request_rejected;
|
||||
pub(crate) use inner::liveness_deadline_expired;
|
||||
#[cfg(all(test, feature = "metrics"))]
|
||||
pub(crate) use inner::lock_oidc_metrics_test;
|
||||
pub(crate) use inner::no_handler;
|
||||
pub(crate) use inner::notif_lagged_recovered;
|
||||
#[cfg(all(test, feature = "metrics"))]
|
||||
pub(crate) use inner::oidc_refresh_count;
|
||||
#[cfg(all(test, feature = "metrics"))]
|
||||
pub(crate) use inner::oidc_refresh_duration_sample_count;
|
||||
pub(crate) use inner::oidc_refresh_observe;
|
||||
pub(crate) use inner::pool_connections_dec;
|
||||
pub(crate) use inner::pool_connections_inc;
|
||||
pub(crate) use inner::pool_evictions_inc;
|
||||
|
|
|
|||
Loading…
Reference in a new issue