Register agent tasks behind use_agent_identity (#17387)

## Summary

Stack PR3 for feature-gated agent identity support.

This PR adds per-thread agent task registration behind
`features.use_agent_identity`. Tasks are minted on the first real user
turn and cached in thread runtime state for later turns.

## Stack

- PR1: https://github.com/openai/codex/pull/17385 - add
`features.use_agent_identity`
- PR2: https://github.com/openai/codex/pull/17386 - register agent
identities when enabled
- PR3: https://github.com/openai/codex/pull/17387 - this PR, original
task registration slice
- PR3.1: https://github.com/openai/codex/pull/17978 - persist and
prewarm registered tasks per thread
- PR4: https://github.com/openai/codex/pull/17980 - use `AgentAssertion`
downstream when enabled

## Validation

Covered as part of the local stack validation pass:

- `just fmt`
- `cargo test -p codex-core --lib agent_identity`
- `cargo test -p codex-core --lib agent_assertion`
- `cargo test -p codex-core --lib websocket_agent_task`
- `cargo test -p codex-api api_bridge`
- `cargo build -p codex-cli --bin codex`

## Notes

The full local app-server E2E path is still being debugged after PR
creation. The current branch stack is directionally ready for review
while that follow-up continues.
This commit is contained in:
Adrian
2026-04-16 14:30:02 -07:00
committed by GitHub
parent 0708cc78cb
commit 55c3de75cb
14 changed files with 804 additions and 43 deletions

View File

@@ -351,6 +351,8 @@ async fn get_auth_status_omits_token_after_proactive_refresh_failure() -> Result
)?;
let server = MockServer::start().await;
// App-server startup may proactively read stale auth before this test sends
// getAuthStatus; require the refresh path without depending on that race.
Mock::given(method("POST"))
.and(path("/oauth/token"))
.respond_with(ResponseTemplate::new(401).set_body_json(serde_json::json!({
@@ -358,7 +360,7 @@ async fn get_auth_status_omits_token_after_proactive_refresh_failure() -> Result
"code": "refresh_token_reused"
}
})))
.expect(2)
.expect(1..=2)
.mount(&server)
.await;
@@ -418,6 +420,8 @@ async fn get_auth_status_returns_token_after_proactive_refresh_recovery() -> Res
)?;
let server = MockServer::start().await;
// App-server startup may proactively read stale auth before this test sends
// getAuthStatus; require the refresh path without depending on that race.
Mock::given(method("POST"))
.and(path("/oauth/token"))
.respond_with(ResponseTemplate::new(401).set_body_json(serde_json::json!({
@@ -425,7 +429,7 @@ async fn get_auth_status_returns_token_after_proactive_refresh_recovery() -> Res
"code": "refresh_token_reused"
}
})))
.expect(2)
.expect(1..=2)
.mount(&server)
.await;

View File

@@ -30,7 +30,8 @@ use wiremock::matchers::method;
use wiremock::matchers::path;
use wiremock::matchers::query_param;
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
// These tests start full app-server processes and can also run plugin startup warmers.
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
const TEST_CURATED_PLUGIN_SHA: &str = "0123456789abcdef0123456789abcdef01234567";
const STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE: &str = ".tmp/app-server-remote-plugin-sync-v1";

View File

@@ -72,6 +72,7 @@ use wiremock::matchers::path;
use wiremock::matchers::path_regex;
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
const DELEGATED_SHELL_TOOL_TIMEOUT_MS: u64 = 30_000;
const STARTUP_CONTEXT_HEADER: &str = "Startup context from Codex.";
const V2_STEERING_ACKNOWLEDGEMENT: &str =
"This was sent to steer the previous background agent task.";
@@ -1717,7 +1718,9 @@ async fn webrtc_v2_tool_call_delegated_turn_can_execute_shell_tool() -> Result<(
create_shell_command_sse_response(
realtime_tool_ok_command(),
/*workdir*/ None,
Some(5000),
// Windows CI can spend several seconds starting the nested PowerShell command. This
// test verifies delegated shell-tool plumbing, not timeout enforcement.
Some(DELEGATED_SHELL_TOOL_TIMEOUT_MS),
"shell_call",
)?,
create_final_assistant_message_sse_response("shell tool finished")?,