()
| 60 | |
| 61 | |
| 62 | async def main() -> None: |
| 63 | agent = Agent( |
| 64 | name="Codex Agent (same thread)", |
| 65 | instructions=( |
| 66 | "Always use the Codex tool to inspect the local workspace and answer the user's " |
| 67 | "question. Treat the workspace as read-only and answer concisely." |
| 68 | ), |
| 69 | tools=[ |
| 70 | codex_tool( |
| 71 | # Give each Codex tool a unique `codex_` name when you run multiple tools in one agent. |
| 72 | # Name-based defaults keep their run-context thread IDs separated. |
| 73 | name="codex_engineer", |
| 74 | sandbox_mode="read-only", |
| 75 | default_thread_options=ThreadOptions( |
| 76 | model="gpt-5.5", |
| 77 | model_reasoning_effort="low", |
| 78 | network_access_enabled=True, |
| 79 | web_search_enabled=False, |
| 80 | approval_policy="never", |
| 81 | ), |
| 82 | on_stream=on_codex_stream, |
| 83 | # Reuse the same Codex thread across runs that share this context object. |
| 84 | use_run_context_thread_id=True, |
| 85 | ) |
| 86 | ], |
| 87 | model_settings=ModelSettings(tool_choice="required"), |
| 88 | ) |
| 89 | |
| 90 | class MyContext(BaseModel): |
| 91 | something: str | None = None |
| 92 | # the default is "codex_thread_id"; missing this works as well |
| 93 | codex_thread_id_engineer: str | None = None # aligns with run_context_thread_id_key |
| 94 | |
| 95 | context = MyContext() |
| 96 | |
| 97 | # Simple dict object works as well: |
| 98 | # context: dict[str, str] = {} |
| 99 | |
| 100 | trace_id = gen_trace_id() |
| 101 | log(f"View trace: https://platform.openai.com/traces/trace?trace_id={trace_id}") |
| 102 | |
| 103 | with trace("Codex same thread example", trace_id=trace_id): |
| 104 | log("Turn 1: inspect AGENTS.md with the Codex tool.") |
| 105 | first_prompt = ( |
| 106 | "Use the Codex tool to inspect AGENTS.md in this repository and list the mandatory " |
| 107 | "local verification commands. Do not modify any files." |
| 108 | ) |
| 109 | first_result = await Runner.run(agent, first_prompt, context=context) |
| 110 | first_thread_id = read_context_value(context, THREAD_ID_KEY) |
| 111 | log(first_result.final_output) |
| 112 | log(f"thread id after turn 1: {first_thread_id}") |
| 113 | if first_thread_id is None: |
| 114 | log("thread id after turn 1 is unavailable; turn 2 may start a new Codex thread.") |
| 115 | |
| 116 | log("Turn 2: continue with the same Codex thread.") |
| 117 | second_prompt = ( |
| 118 | "Continue from the same Codex thread. Rewrite that verification workflow as a single " |
| 119 | "short sentence. Do not modify any files." |
no test coverage detected