feat: add session stream event trace flag

This commit is contained in:
2026-05-26 19:57:47 +09:00
parent 5ccfdea7c8
commit 372a99bc0b
4 changed files with 100 additions and 3 deletions
+38 -1
View File
@@ -17,7 +17,8 @@ use crate::defaults;
use crate::model::{AuthRef, ModelManifest, ReasoningControl};
use crate::{
CompactionConfig, FileUploadLimits, MemoryConfig, PodManifest, PodMeta, ScopeConfig,
SkillsConfig, ToolOutputLimits, ToolPermissionConfig, ToolPermissionRule, WorkerManifest,
SessionConfig, SkillsConfig, ToolOutputLimits, ToolPermissionConfig, ToolPermissionRule,
WorkerManifest,
};
/// Partial-form Pod manifest. Every field is optional; one or more
@@ -37,6 +38,8 @@ pub struct PodManifestConfig {
pub worker: WorkerManifestConfig,
#[serde(default)]
pub scope: ScopeConfig,
#[serde(default)]
pub session: Option<SessionConfigPartial>,
/// Optional `[permissions]` section. `None` means the permission layer
/// is disabled; `Some` requires `default_action` during final resolve.
#[serde(default)]
@@ -102,6 +105,12 @@ pub struct FileUploadLimitsPartial {
pub max_bytes: Option<usize>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct SessionConfigPartial {
#[serde(default)]
pub record_event_trace: Option<bool>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct PermissionConfigPartial {
#[serde(default)]
@@ -260,6 +269,7 @@ impl PodManifestConfig {
model: self.model.merge(upper.model),
worker: self.worker.merge(upper.worker),
scope: merge_scope(self.scope, upper.scope),
session: merge_option(self.session, upper.session, SessionConfigPartial::merge),
permissions: merge_option(
self.permissions,
upper.permissions,
@@ -353,6 +363,14 @@ impl FileUploadLimitsPartial {
}
}
impl SessionConfigPartial {
fn merge(self, upper: Self) -> Self {
Self {
record_event_trace: upper.record_event_trace.or(self.record_event_trace),
}
}
}
impl PermissionConfigPartial {
fn merge(mut self, upper: Self) -> Self {
self.rules.extend(upper.rules);
@@ -496,6 +514,12 @@ impl TryFrom<PodManifestConfig> for PodManifest {
for rule in &cfg.scope.deny {
ensure_absolute("scope.deny.target", &rule.target)?;
}
let session = SessionConfig {
record_event_trace: cfg
.session
.and_then(|s| s.record_event_trace)
.unwrap_or(false),
};
let permissions = cfg
.permissions
@@ -550,6 +574,7 @@ impl TryFrom<PodManifestConfig> for PodManifest {
model: cfg.model,
worker,
scope: cfg.scope,
session,
permissions,
compaction,
memory: cfg.memory,
@@ -596,6 +621,7 @@ mod tests {
deny: Vec::new(),
},
permissions: None,
session: None,
compaction: None,
memory: None,
skills: None,
@@ -610,6 +636,17 @@ mod tests {
assert!(manifest.permissions.is_none());
}
#[test]
fn resolve_session_record_event_trace() {
let mut cfg = minimal_valid();
cfg.session = Some(SessionConfigPartial {
record_event_trace: Some(true),
});
let manifest: PodManifest = cfg.try_into().unwrap();
assert!(manifest.session.record_event_trace);
}
#[test]
fn resolve_permissions_requires_default_action_when_present() {
let mut cfg = minimal_valid();
+12
View File
@@ -37,6 +37,9 @@ pub struct PodManifest {
pub model: ModelManifest,
pub worker: WorkerManifest,
pub scope: ScopeConfig,
/// Session/debug persistence settings. Defaults keep extra traces off.
#[serde(default)]
pub session: SessionConfig,
/// Optional manifest-level tool permission policy. Absent means the
/// permission layer is disabled and tool calls run as before.
#[serde(default)]
@@ -300,6 +303,15 @@ pub struct ScopeConfig {
pub deny: Vec<ScopeRule>,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq, Eq)]
pub struct SessionConfig {
/// Persist every provider stream event directly to `trace.jsonl` next to the
/// segment log. Intended for debugging stalls between stream requests; off
/// by default because it can be verbose.
#[serde(default)]
pub record_event_trace: bool,
}
/// Manifest-level pattern-based tool permission policy.
///
/// Presence of `[permissions]` enables this layer. Rules are evaluated