[codex-analytics] add extensible feature thread sources (#27063)

## Why
- `ThreadSource` currently defines a closed set of core-owned values
- Product features also create threads for background or scheduled work
- Adding every product-specific value to the core enum would require
repeated `codex-rs` protocol changes
- Feature-backed values let product callers provide precise attribution
while preserving the existing core classifications

## What Changed
- Adds `ThreadSource::Feature(String)` for app-owned thread source
values
- Represents all app-server v2 thread sources as scalar strings, so a
feature source is supplied as `"automation"`
- Persists and emits the feature's plain string label, so `"automation"`
produces `thread_source="automation"` in analytics
- Keeps `user`, `subagent`, and `memory_consolidation` as explicit
core-owned values and regenerates the app-server schemas and TypeScript
bindings

## Verification
- `just write-app-server-schema`
- `cargo check --workspace`
- `just test -p codex-protocol
feature_thread_source_serializes_as_its_app_owned_label`
- `just test -p codex-app-server-protocol
thread_sources_round_trip_as_scalar_labels`
- `cargo test -p codex-analytics
thread_initialized_event_serializes_expected_shape`
- `just fmt`
This commit is contained in:
marksteinbrick-oai
2026-06-09 12:27:10 -07:00
committed by GitHub
Unverified
parent 99da697e4c
commit a71e040df5
32 changed files with 123 additions and 113 deletions
+2 -2
View File
@@ -91,7 +91,7 @@ pub(super) async fn spawn_review_thread(
forked_from_thread_id,
parent_turn_context.parent_thread_id,
&session_source,
parent_turn_context.thread_source,
parent_turn_context.thread_source.clone(),
review_turn_id.clone(),
#[allow(deprecated)]
parent_turn_context.cwd.clone(),
@@ -121,7 +121,7 @@ pub(super) async fn spawn_review_thread(
reasoning_summary,
session_source,
parent_thread_id: parent_turn_context.parent_thread_id,
thread_source: parent_turn_context.thread_source,
thread_source: parent_turn_context.thread_source.clone(),
environments: parent_turn_context.environments.clone(),
available_models,
unified_exec_shell_mode,
+3 -3
View File
@@ -193,7 +193,7 @@ impl SessionConfiguration {
session_source: self.session_source.clone(),
forked_from_thread_id: self.forked_from_thread_id,
parent_thread_id: self.parent_thread_id,
thread_source: self.thread_source,
thread_source: self.thread_source.clone(),
}
}
@@ -549,7 +549,7 @@ impl Session {
forked_from_id,
parent_thread_id,
source: session_source,
thread_source: session_configuration.thread_source,
thread_source: session_configuration.thread_source.clone(),
base_instructions: BaseInstructions {
text: session_configuration.base_instructions.clone(),
},
@@ -1089,7 +1089,7 @@ impl Session {
thread_id,
forked_from_id,
parent_thread_id,
thread_source: session_configuration.thread_source,
thread_source: session_configuration.thread_source.clone(),
thread_name: session_configuration.thread_name.clone(),
model: session_configuration.collaboration_mode.model().to_string(),
model_provider_id: config.model_provider_id.clone(),
+3 -3
View File
@@ -239,7 +239,7 @@ impl TurnContext {
reasoning_summary: self.reasoning_summary,
session_source: self.session_source.clone(),
parent_thread_id: self.parent_thread_id,
thread_source: self.thread_source,
thread_source: self.thread_source.clone(),
environments: self.environments.clone(),
#[allow(deprecated)]
cwd: self.cwd.clone(),
@@ -514,7 +514,7 @@ impl Session {
session_configuration.forked_from_thread_id,
session_configuration.parent_thread_id,
&session_configuration.session_source,
session_configuration.thread_source,
session_configuration.thread_source.clone(),
sub_id.clone(),
cwd.clone(),
&session_configuration.permission_profile(),
@@ -538,7 +538,7 @@ impl Session {
reasoning_summary,
session_source,
parent_thread_id: session_configuration.parent_thread_id,
thread_source: session_configuration.thread_source,
thread_source: session_configuration.thread_source.clone(),
environments,
#[allow(deprecated)]
cwd,