mirror of
https://github.com/openai/codex.git
synced 2026-09-10 20:26:47 +00:00
Add untrusted external messages to the Python SDK (#44086)
## Why Applications need to deliver content from other agents, tools, or services with tool-level authority, without treating it as user input or granting authorization. ## What changed - Export `ExternalMessage` for sync and async `run(...)` and `turn(...)`, accepting text or structured content with a tool name and optional namespace. Send it through `toolOutput` and require CLI 0.151.0 or newer. - Support starting a turn or joining an active regular turn while preserving external content as function output in history. Keep external messages separate from user-input lists and `steer(...)`. - Give turn handles independent subscriptions, replaying completed items and latest usage to joining handles. Release consumed transient events and clean up subscriptions on closure, failure, or cancellation. - Document the authority boundary and add sync and async examples. ## Testing Add coverage for wire representations, input validation, runtime compatibility, tool authority across resume, active-turn joins, and tool-output truncation. Add subscription tests for replay, concurrent consumers, early completion, cancellation, and cleanup. GitOrigin-RevId: 6106327085fd9c4bd11b71e20b3d8e74738b8bb5
This commit is contained in:
@@ -1259,7 +1259,8 @@ def _render_thread_block(turn_fields: list[PublicFieldSpec], *, is_async: bool =
|
||||
" ) -> TurnResult:",
|
||||
' """Run a complete turn and collect its final result.',
|
||||
"",
|
||||
" Accepts the same input and options as turn().",
|
||||
" Accepts the same input and options as turn(), including ExternalMessage",
|
||||
" for untrusted external content with tool-level authority.",
|
||||
' """',
|
||||
f" turn = {await_prefix}self.turn(",
|
||||
" input,",
|
||||
@@ -1275,18 +1276,21 @@ def _render_thread_block(turn_fields: list[PublicFieldSpec], *, is_async: bool =
|
||||
*_approval_mode_override_signature_lines(),
|
||||
*_kw_signature_lines(turn_fields),
|
||||
f" ) -> {handle_type}:",
|
||||
' """Start a turn and return a handle for streaming or control.',
|
||||
' """Start a turn or join an active regular turn and return its handle.',
|
||||
"",
|
||||
" ExternalMessage supplies untrusted content with tool-level authority;",
|
||||
" it does not establish user authorization or approval.",
|
||||
" turn_service_tier applies only to this new turn; service_tier updates",
|
||||
" the thread default. source labels what initiated a new turn and grants",
|
||||
" no authority. Both turn_service_tier and source are ignored when joining.",
|
||||
' """',
|
||||
" wire_input = _to_wire_input(_normalize_run_input(input))",
|
||||
" wire_input, tool_output = _to_wire_turn_input(input)",
|
||||
*([" await self._codex._ensure_initialized()"] if is_async else []),
|
||||
_approval_mode_assignment_line("_approval_mode_override_settings"),
|
||||
" params = TurnStartParams(",
|
||||
" thread_id=self.id,",
|
||||
" input=wire_input,",
|
||||
" tool_output=tool_output,",
|
||||
*_approval_mode_model_arg_lines(),
|
||||
*_model_arg_lines(turn_fields),
|
||||
" )",
|
||||
|
||||
Reference in New Issue
Block a user