python-codex 0.1.6__tar.gz → 0.1.7__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.
- {python_codex-0.1.6 → python_codex-0.1.7}/PKG-INFO +1 -1
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/cli.py +40 -4
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/base_tool.py +16 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/__init__.py +2 -0
- python_codex-0.1.7/pycodex/utils/debug.py +12 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pyproject.toml +1 -1
- {python_codex-0.1.6 → python_codex-0.1.7}/.github/workflows/publish.yml +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/.github/workflows/test.yml +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/.gitignore +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/AGENTS.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/LICENSE +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/README.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/README_ZH.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/docs/ALIGNMENT.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/docs/CONTEXT.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/docs/responses_server/README.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/__init__.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/agent.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/collaboration.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/compat.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/context.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/doctor.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/model.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/portable.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/portable_server.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/collaboration_default.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/collaboration_plan.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/default_base_instructions.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/exec_tools.json +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/models.json +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/never.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/on_failure.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/on_request.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/unless_trusted.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/sandbox_mode/danger_full_access.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/sandbox_mode/read_only.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/sandbox_mode/workspace_write.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/subagent_tools.json +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/protocol.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/runtime.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/runtime_services.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/__init__.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/agent_tool_schemas.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/apply_patch_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/close_agent_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/code_mode_manager.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/exec_command_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/exec_runtime.js +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/exec_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/grep_files_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/list_dir_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/read_file_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/request_permissions_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/request_user_input_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/resume_agent_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/send_input_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/shell_command_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/shell_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/spawn_agent_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/unified_exec_manager.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/update_plan_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/view_image_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/wait_agent_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/wait_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/web_search_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/tools/write_stdin_tool.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/compactor.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/dotenv.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/get_env.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/random_ids.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/session_persist.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/pycodex/utils/visualize.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/__init__.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/__main__.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/app.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/config.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/messages_api.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/payload_processors.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/server.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/session_store.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/stream_router.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/tools/__init__.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/tools/custom_adapter.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/responses_server/tools/web_search.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/TESTS.md +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/__init__.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/compare_request_user_input_roundtrip.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/compare_steer_request_bodies.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/compare_tool_schemas.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/fake_responses_server.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/fakes.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/responses_server/fake_chat_completions_server.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/responses_server/test_server.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_agent.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_builtin_tools.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_cli.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_compactor.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_context.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_doctor.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_fake_responses_server.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_model.py +0 -0
- {python_codex-0.1.6 → python_codex-0.1.7}/tests/test_portable.py +0 -0
|
@@ -7,6 +7,7 @@ import os
|
|
|
7
7
|
import shlex
|
|
8
8
|
import sys
|
|
9
9
|
import tempfile
|
|
10
|
+
import traceback
|
|
10
11
|
from dataclasses import asdict, replace
|
|
11
12
|
from pathlib import Path
|
|
12
13
|
from typing import Sequence
|
|
@@ -20,7 +21,7 @@ from .portable import bootstrap_called_home, upload_codex_home
|
|
|
20
21
|
from .protocol import AgentEvent
|
|
21
22
|
from .runtime import AgentRuntime
|
|
22
23
|
from .runtime_services import RuntimeEnvironment, create_runtime_environment
|
|
23
|
-
from .utils import CliSessionView, load_codex_dotenv, uuid7_string
|
|
24
|
+
from .utils import CliSessionView, get_debug_dir, load_codex_dotenv, uuid7_string
|
|
24
25
|
from .utils.compactor import compact_agent_loop
|
|
25
26
|
from .utils.session_persist import (
|
|
26
27
|
SessionRolloutRecorder,
|
|
@@ -57,9 +58,9 @@ def configure_loguru() -> 'None':
|
|
|
57
58
|
return
|
|
58
59
|
|
|
59
60
|
logger.remove()
|
|
60
|
-
|
|
61
|
-
if
|
|
62
|
-
logger.add(
|
|
61
|
+
debug_dir = get_debug_dir()
|
|
62
|
+
if debug_dir is not None:
|
|
63
|
+
logger.add(str(debug_dir / "loguru.log"), level="DEBUG")
|
|
63
64
|
return
|
|
64
65
|
|
|
65
66
|
if os.environ.get("PYCODEX_DEBUG_STDERR", "").strip().lower() in {
|
|
@@ -743,6 +744,8 @@ async def run_interactive_session(
|
|
|
743
744
|
async def run_cli(args: 'argparse.Namespace') -> 'int':
|
|
744
745
|
runtime = None
|
|
745
746
|
worker = None
|
|
747
|
+
debug_dir = get_debug_dir()
|
|
748
|
+
phase_handle = None if debug_dir is None else (debug_dir / "phase.log").open("a", encoding="utf-8")
|
|
746
749
|
try:
|
|
747
750
|
if args.put is not None and args.call:
|
|
748
751
|
raise ValueError("--put and --call cannot be combined")
|
|
@@ -762,9 +765,18 @@ async def run_cli(args: 'argparse.Namespace') -> 'int':
|
|
|
762
765
|
print(f"pycodex --call {shlex.quote(call_spec)}", flush=True)
|
|
763
766
|
return 0
|
|
764
767
|
if args.call:
|
|
768
|
+
if phase_handle is not None:
|
|
769
|
+
phase_handle.write("bootstrap_called_home:start\n")
|
|
770
|
+
phase_handle.flush()
|
|
765
771
|
config_path = bootstrap_called_home(args.call)
|
|
772
|
+
if phase_handle is not None:
|
|
773
|
+
phase_handle.write("bootstrap_called_home:done\n")
|
|
774
|
+
phase_handle.flush()
|
|
766
775
|
args.config = str(config_path)
|
|
767
776
|
os.environ["CODEX_HOME"] = str(config_path.parent)
|
|
777
|
+
if phase_handle is not None:
|
|
778
|
+
phase_handle.write("build_model_client:start\n")
|
|
779
|
+
phase_handle.flush()
|
|
768
780
|
client = _build_model_client(
|
|
769
781
|
args.config,
|
|
770
782
|
args.profile,
|
|
@@ -773,7 +785,13 @@ async def run_cli(args: 'argparse.Namespace') -> 'int':
|
|
|
773
785
|
use_chat_completion=args.use_chat_completion,
|
|
774
786
|
use_messages=args.use_messages,
|
|
775
787
|
)
|
|
788
|
+
if phase_handle is not None:
|
|
789
|
+
phase_handle.write("build_model_client:done\n")
|
|
790
|
+
phase_handle.flush()
|
|
776
791
|
|
|
792
|
+
if phase_handle is not None:
|
|
793
|
+
phase_handle.write("build_runtime:start\n")
|
|
794
|
+
phase_handle.flush()
|
|
777
795
|
runtime = build_runtime(
|
|
778
796
|
args.config,
|
|
779
797
|
args.profile,
|
|
@@ -781,6 +799,9 @@ async def run_cli(args: 'argparse.Namespace') -> 'int':
|
|
|
781
799
|
client,
|
|
782
800
|
session_mode="tui",
|
|
783
801
|
)
|
|
802
|
+
if phase_handle is not None:
|
|
803
|
+
phase_handle.write("build_runtime:done\n")
|
|
804
|
+
phase_handle.flush()
|
|
784
805
|
if should_run_interactive(args.prompt, sys.stdin.isatty()):
|
|
785
806
|
return await run_interactive_session(
|
|
786
807
|
runtime,
|
|
@@ -790,13 +811,28 @@ async def run_cli(args: 'argparse.Namespace') -> 'int':
|
|
|
790
811
|
else:
|
|
791
812
|
prompt_text = resolve_prompt_text(args.prompt)
|
|
792
813
|
worker = asyncio.create_task(runtime.run_forever())
|
|
814
|
+
if phase_handle is not None:
|
|
815
|
+
phase_handle.write("submit_user_turn:start\n")
|
|
816
|
+
phase_handle.flush()
|
|
793
817
|
result = await runtime.submit_user_turn(prompt_text)
|
|
818
|
+
if phase_handle is not None:
|
|
819
|
+
phase_handle.write("submit_user_turn:done\n")
|
|
820
|
+
phase_handle.flush()
|
|
794
821
|
print(format_turn_output(result, args.json))
|
|
795
822
|
return 0
|
|
796
823
|
except Exception as exc:
|
|
824
|
+
if phase_handle is not None:
|
|
825
|
+
phase_handle.write("fatal_exception\n")
|
|
826
|
+
phase_handle.flush()
|
|
827
|
+
if debug_dir is not None:
|
|
828
|
+
(debug_dir / "fatal_error.txt").write_text(
|
|
829
|
+
traceback.format_exc(), encoding="utf-8"
|
|
830
|
+
)
|
|
797
831
|
print(f"Error: {exc}", file=sys.stderr)
|
|
798
832
|
return 1
|
|
799
833
|
finally:
|
|
834
|
+
if phase_handle is not None:
|
|
835
|
+
phase_handle.close()
|
|
800
836
|
if runtime is not None and worker is not None:
|
|
801
837
|
await runtime.shutdown()
|
|
802
838
|
await worker
|
|
@@ -16,8 +16,10 @@ from dataclasses import dataclass
|
|
|
16
16
|
from functools import lru_cache
|
|
17
17
|
import json
|
|
18
18
|
from pathlib import Path
|
|
19
|
+
import traceback
|
|
19
20
|
|
|
20
21
|
from ..protocol import ConversationItem, JSONDict, JSONValue, ToolCall, ToolResult, ToolSpec
|
|
22
|
+
from ..utils import get_debug_dir
|
|
21
23
|
import typing
|
|
22
24
|
|
|
23
25
|
EXEC_TOOLS_SNAPSHOT_PATH = (
|
|
@@ -140,6 +142,20 @@ class ToolRegistry:
|
|
|
140
142
|
tool_type=call.tool_type,
|
|
141
143
|
)
|
|
142
144
|
except Exception as exc: # pragma: no cover - defensive wrapper
|
|
145
|
+
if (debug_dir := get_debug_dir()) is not None:
|
|
146
|
+
with (debug_dir / "tool_errors.jsonl").open("a", encoding="utf-8") as handle:
|
|
147
|
+
handle.write(
|
|
148
|
+
json.dumps(
|
|
149
|
+
{
|
|
150
|
+
"tool": call.name,
|
|
151
|
+
"call_id": call.call_id,
|
|
152
|
+
"error": f"{type(exc).__name__}: {exc}",
|
|
153
|
+
"traceback": traceback.format_exc(),
|
|
154
|
+
},
|
|
155
|
+
ensure_ascii=False,
|
|
156
|
+
)
|
|
157
|
+
)
|
|
158
|
+
handle.write("\n")
|
|
143
159
|
return ToolResult(
|
|
144
160
|
call_id=call.call_id,
|
|
145
161
|
name=call.name,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from .dotenv import DOTENV_FILENAME, load_codex_dotenv, parse_dotenv, parse_dotenv_value
|
|
2
|
+
from .debug import get_debug_dir
|
|
2
3
|
from .get_env import build_user_agent, get_shell_name, get_timezone_name
|
|
3
4
|
from .random_ids import uuid7_string
|
|
4
5
|
from .compactor import DEFAULT_COMPACT_PROMPT, SUMMARY_PREFIX, compact
|
|
@@ -31,6 +32,7 @@ __all__ = [
|
|
|
31
32
|
"format_cli_plan_messages",
|
|
32
33
|
"format_cli_tool_call_message",
|
|
33
34
|
"format_cli_tool_message",
|
|
35
|
+
"get_debug_dir",
|
|
34
36
|
"get_shell_name",
|
|
35
37
|
"get_timezone_name",
|
|
36
38
|
"load_codex_dotenv",
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import typing
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def get_debug_dir() -> 'typing.Union[Path, None]':
|
|
7
|
+
value = os.environ.get("PYCODEX_DEBUG_LOG", "").strip()
|
|
8
|
+
if not value:
|
|
9
|
+
return None
|
|
10
|
+
path = Path(value).expanduser()
|
|
11
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
12
|
+
return path
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/never.md
RENAMED
|
File without changes
|
{python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/on_failure.md
RENAMED
|
File without changes
|
{python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/approval_policy/on_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_codex-0.1.6 → python_codex-0.1.7}/pycodex/prompts/permissions/sandbox_mode/read_only.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_codex-0.1.6 → python_codex-0.1.7}/tests/responses_server/fake_chat_completions_server.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|