python-codex 0.4.3__tar.gz → 0.4.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. {python_codex-0.4.3 → python_codex-0.4.5}/PKG-INFO +4 -2
  2. {python_codex-0.4.3 → python_codex-0.4.5}/README.md +3 -1
  3. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/agent.py +4 -0
  4. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/runtime_services.py +27 -2
  5. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/wait_agent_tool.py +1 -24
  6. {python_codex-0.4.3 → python_codex-0.4.5}/pyproject.toml +2 -2
  7. {python_codex-0.4.3 → python_codex-0.4.5}/.gitignore +0 -0
  8. {python_codex-0.4.3 → python_codex-0.4.5}/LICENSE +0 -0
  9. {python_codex-0.4.3 → python_codex-0.4.5}/README_ZH.md +0 -0
  10. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/__init__.py +0 -0
  11. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/__main__.py +0 -0
  12. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/bootstrap.py +0 -0
  13. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/cli.py +0 -0
  14. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/context.py +0 -0
  15. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/events.py +0 -0
  16. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/model.py +0 -0
  17. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/portable/__init__.py +0 -0
  18. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/portable/client.py +0 -0
  19. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/portable/server.py +0 -0
  20. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/default_base_instructions.md +0 -0
  21. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/models.json +0 -0
  22. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
  23. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
  24. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
  25. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
  26. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
  27. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
  28. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
  29. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
  30. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/protocol.py +0 -0
  31. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/runtime.py +0 -0
  32. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/__init__.py +0 -0
  33. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/agent_tool_schemas.py +0 -0
  34. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/apply_patch_tool.py +0 -0
  35. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/base_tool.py +0 -0
  36. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/clock_tool.py +0 -0
  37. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/close_agent_tool.py +0 -0
  38. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/code_mode_manager.py +0 -0
  39. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/exec_command_tool.py +0 -0
  40. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/exec_runtime.js +0 -0
  41. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/exec_tool.py +0 -0
  42. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/grep_files_tool.py +0 -0
  43. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/list_dir_tool.py +0 -0
  44. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/read_file_tool.py +0 -0
  45. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/request_permissions_tool.py +0 -0
  46. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/request_user_input_tool.py +0 -0
  47. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/resume_agent_tool.py +0 -0
  48. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/send_input_tool.py +0 -0
  49. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/shell_command_tool.py +0 -0
  50. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/shell_tool.py +0 -0
  51. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/spawn_agent_tool.py +0 -0
  52. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/unified_exec_manager.py +0 -0
  53. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/update_plan_tool.py +0 -0
  54. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/view_image_tool.py +0 -0
  55. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/wait_tool.py +0 -0
  56. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/web_search_tool.py +0 -0
  57. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/tools/write_stdin_tool.py +0 -0
  58. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/__init__.py +0 -0
  59. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/_aes_gcm/LICENSE +0 -0
  60. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/_aes_gcm/README.md +0 -0
  61. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/_aes_gcm/__init__.py +0 -0
  62. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/_aes_gcm/aes.py +0 -0
  63. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/_aes_gcm/gcm.py +0 -0
  64. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/_aes_gcm/source-sha256.json +0 -0
  65. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/async_bridge.py +0 -0
  66. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/compactor.py +0 -0
  67. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/compat.py +0 -0
  68. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/crypto.py +0 -0
  69. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/debug.py +0 -0
  70. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/doctor.py +0 -0
  71. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/dotenv.py +0 -0
  72. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/event_helpers.py +0 -0
  73. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/get_env.py +0 -0
  74. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/image_utils.py +0 -0
  75. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/model_metadata.py +0 -0
  76. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/random_ids.py +0 -0
  77. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/session_persist.py +0 -0
  78. {python_codex-0.4.3 → python_codex-0.4.5}/pycodex/utils/truncation.py +0 -0
  79. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/__init__.py +0 -0
  80. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/__main__.py +0 -0
  81. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/app.py +0 -0
  82. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/config.py +0 -0
  83. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/messages_api.py +0 -0
  84. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/payload_processors.py +0 -0
  85. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/server.py +0 -0
  86. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/session_store.py +0 -0
  87. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/stream_router.py +0 -0
  88. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/tools/__init__.py +0 -0
  89. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/tools/custom_adapter.py +0 -0
  90. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/tools/web_search.py +0 -0
  91. {python_codex-0.4.3 → python_codex-0.4.5}/responses_server/trajectory_dump.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: python-codex
3
- Version: 0.4.3
3
+ Version: 0.4.5
4
4
  Summary: A minimal Python extraction of Codex's main agent loop
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.6.2
@@ -808,7 +808,9 @@ event JSON format.
808
808
  The global `get_agent_runtime_environment()` and
809
809
  separate `Agent(..., runtime_environment=...)` entry points are removed.
810
810
  - Each sub-agent gets its own context manager and runtime services. The sub-agent
811
- service retains terminal event status, rather than inspecting Task results.
811
+ service retains terminal event status and queues one notification per terminal
812
+ event. The parent consumes these notifications before its next normal model
813
+ request, without requiring `wait_agent`; an idle parent waits for its next turn.
812
814
  - Every Agent records its session, including direct and child Agents; external
813
815
  callers no longer construct or inject `SessionRolloutRecorder`. The outer queue
814
816
  remains optional and no worker starts implicitly. Empty initial history and a
@@ -788,7 +788,9 @@ event JSON format.
788
788
  The global `get_agent_runtime_environment()` and
789
789
  separate `Agent(..., runtime_environment=...)` entry points are removed.
790
790
  - Each sub-agent gets its own context manager and runtime services. The sub-agent
791
- service retains terminal event status, rather than inspecting Task results.
791
+ service retains terminal event status and queues one notification per terminal
792
+ event. The parent consumes these notifications before its next normal model
793
+ request, without requiring `wait_agent`; an idle parent waits for its next turn.
792
794
  - Every Agent records its session, including direct and child Agents; external
793
795
  callers no longer construct or inject `SessionRolloutRecorder`. The outer queue
794
796
  remains optional and no worker starts implicitly. Empty initial history and a
@@ -253,6 +253,10 @@ class Agent:
253
253
  while True:
254
254
  phase = "pre_turn" if turn.iteration == 0 else "mid_turn"
255
255
  await self._maybe_auto_compact(turn.turn_id, phase)
256
+ manager = self.tool_registry.runtime_environment.subagent_manager
257
+ notifications = manager.take_pending_notifications()
258
+ if notifications:
259
+ self._append_history(notifications)
256
260
  if turn.iteration == 0:
257
261
  self._append_history(UserMessage(text=text) for text in texts)
258
262
  response = await self._sample(turn)
@@ -15,7 +15,7 @@ from ..events import (
15
15
  TurnInterruptedEvent,
16
16
  TurnStartedEvent,
17
17
  )
18
- from ..protocol import ConversationItem, ToolCall, ToolResult
18
+ from ..protocol import ConversationItem, ToolCall, ToolResult, UserMessage
19
19
  from ..utils import uuid7_string
20
20
  from ..utils.compat import Literal
21
21
 
@@ -221,6 +221,7 @@ class SubAgentManager:
221
221
  def __init__(self) -> "None":
222
222
  self._runtime_builder: "typing.Union[AgentRuntimeBuilder, None]" = None
223
223
  self._agents: "typing.Dict[str, ManagedAgent]" = {}
224
+ self._pending_notifications: "typing.List[UserMessage]" = []
224
225
  self._condition = None
225
226
  self._available_nicknames: "typing.List[str]" = []
226
227
  self._nickname_random = random.Random()
@@ -235,6 +236,11 @@ class SubAgentManager:
235
236
  ) -> "None":
236
237
  self._runtime_builder = builder
237
238
 
239
+ def take_pending_notifications(self) -> "typing.Tuple[UserMessage, ...]":
240
+ messages = tuple(self._pending_notifications)
241
+ self._pending_notifications.clear()
242
+ return messages
243
+
238
244
  async def spawn_agent(
239
245
  self,
240
246
  message: "typing.Union[str, None]",
@@ -396,8 +402,27 @@ class SubAgentManager:
396
402
  }
397
403
  elif isinstance(event, TurnInterruptedEvent):
398
404
  managed.last_status = {"errored": "TurnInterrupted: turn interrupted"}
399
- elif not isinstance(event, (TurnStartedEvent, CompactStartedEvent)):
405
+ elif isinstance(event, (TurnStartedEvent, CompactStartedEvent)):
406
+ asyncio.create_task(self._notify_waiters())
407
+ return
408
+ else:
400
409
  return
410
+ self._pending_notifications.append(
411
+ UserMessage(
412
+ text=(
413
+ "<subagent_notification>\n"
414
+ + json.dumps(
415
+ {
416
+ "agent_id": managed.agent_id,
417
+ "status": managed.last_status,
418
+ },
419
+ ensure_ascii=False,
420
+ separators=(",", ":"),
421
+ )
422
+ + "\n</subagent_notification>"
423
+ )
424
+ )
425
+ )
401
426
  asyncio.create_task(self._notify_waiters())
402
427
 
403
428
  async def _notify_waiters(self) -> "None":
@@ -9,10 +9,7 @@ Expected behavior:
9
9
  wait times out.
10
10
  """
11
11
 
12
- import json
13
- import typing
14
-
15
- from ..protocol import JSONDict, JSONValue, UserMessage
12
+ from ..protocol import JSONDict, JSONValue
16
13
  from .agent_tool_schemas import AGENT_STATUS_SCHEMA
17
14
  from .base_tool import BaseTool, ToolContext
18
15
  from .runtime_services import SubAgentManager
@@ -80,26 +77,6 @@ class WaitAgentTool(BaseTool):
80
77
  timeout_ms = self._timeout_ms(args)
81
78
  return await self._subagent_manager.wait_agents(agent_ids, timeout_ms)
82
79
 
83
- def follow_up_messages(
84
- self, output: "JSONValue"
85
- ) -> "typing.Tuple[UserMessage, ...]":
86
- if not isinstance(output, dict):
87
- return ()
88
- return tuple(
89
- UserMessage(
90
- text=(
91
- "<subagent_notification>\n"
92
- + json.dumps(
93
- {"agent_id": agent_id, "status": status},
94
- ensure_ascii=False,
95
- separators=(",", ":"),
96
- )
97
- + "\n</subagent_notification>"
98
- )
99
- )
100
- for agent_id, status in output["status"].items()
101
- )
102
-
103
80
  def _timeout_ms(self, args: "JSONDict") -> "int":
104
81
  value = int(args.get("timeout_ms", DEFAULT_WAIT_AGENT_TIMEOUT_MS))
105
82
  return min(
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "python-codex"
7
- version = "0.4.3"
7
+ version = "0.4.5"
8
8
  description = "A minimal Python extraction of Codex's main agent loop"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.6.2"
@@ -40,7 +40,7 @@ test = [
40
40
  ]
41
41
  dev = [
42
42
  { include-group = "test" },
43
- "pycodex-ws==0.4.3",
43
+ "pycodex-ws==0.4.5",
44
44
  "black>=22.8.0",
45
45
  "debugpy>=1.8.20; python_version >= '3.8'",
46
46
  "isort>=5.10.1",
File without changes
File without changes
File without changes