codexapi 0.1.9__tar.gz → 0.3.0__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.
- {codexapi-0.1.9/src/codexapi.egg-info → codexapi-0.3.0}/PKG-INFO +14 -10
- {codexapi-0.1.9 → codexapi-0.3.0}/README.md +13 -9
- {codexapi-0.1.9 → codexapi-0.3.0}/pyproject.toml +1 -1
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi/__init__.py +1 -1
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi/cli.py +103 -82
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi/ralph.py +2 -2
- {codexapi-0.1.9 → codexapi-0.3.0/src/codexapi.egg-info}/PKG-INFO +14 -10
- {codexapi-0.1.9 → codexapi-0.3.0}/LICENSE +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/setup.cfg +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi/__main__.py +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi/agent.py +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi/task.py +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi.egg-info/SOURCES.txt +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi.egg-info/dependency_links.txt +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi.egg-info/entry_points.txt +0 -0
- {codexapi-0.1.9 → codexapi-0.3.0}/src/codexapi.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codexapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Minimal Python API for running the Codex CLI.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: codex,agent,cli,openai
|
|
@@ -61,12 +61,16 @@ print(result.success, result.summary)
|
|
|
61
61
|
After installing, use the `codexapi` command:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
codexapi "Summarize this repo."
|
|
65
|
-
codexapi --cwd /path/to/project "Fix the failing tests."
|
|
66
|
-
echo "Say hello." | codexapi
|
|
64
|
+
codexapi run "Summarize this repo."
|
|
65
|
+
codexapi run --cwd /path/to/project "Fix the failing tests."
|
|
66
|
+
echo "Say hello." | codexapi run
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
`codexapi task` exits with code 0 on success and 1 on failure, printing the summary.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
codexapi task "Fix the failing tests." --max-iterations 5
|
|
73
|
+
```
|
|
70
74
|
|
|
71
75
|
Show running sessions and their latest activity:
|
|
72
76
|
|
|
@@ -78,17 +82,17 @@ Press `h` for keys.
|
|
|
78
82
|
Resume a session and print the thread id to stderr:
|
|
79
83
|
|
|
80
84
|
```bash
|
|
81
|
-
codexapi --thread-id THREAD_ID --print-thread-id "Continue where we left off."
|
|
85
|
+
codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off."
|
|
82
86
|
```
|
|
83
87
|
|
|
84
88
|
Ralph loop mode repeats the same prompt until a completion promise or a max
|
|
85
89
|
iteration cap is hit (0 means unlimited). Cancel by deleting
|
|
86
|
-
`.codexapi/ralph-loop.local.md` or running `codexapi --
|
|
90
|
+
`.codexapi/ralph-loop.local.md` or running `codexapi ralph --cancel`.
|
|
87
91
|
|
|
88
92
|
```bash
|
|
89
|
-
codexapi
|
|
90
|
-
codexapi
|
|
91
|
-
codexapi --
|
|
93
|
+
codexapi ralph "Fix the bug." --completion-promise DONE --max-iterations 5
|
|
94
|
+
codexapi ralph --ralph-fresh "Try again from scratch." --max-iterations 3
|
|
95
|
+
codexapi ralph --cancel --cwd /path/to/project
|
|
92
96
|
```
|
|
93
97
|
|
|
94
98
|
## API
|
|
@@ -49,12 +49,16 @@ print(result.success, result.summary)
|
|
|
49
49
|
After installing, use the `codexapi` command:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
|
-
codexapi "Summarize this repo."
|
|
53
|
-
codexapi --cwd /path/to/project "Fix the failing tests."
|
|
54
|
-
echo "Say hello." | codexapi
|
|
52
|
+
codexapi run "Summarize this repo."
|
|
53
|
+
codexapi run --cwd /path/to/project "Fix the failing tests."
|
|
54
|
+
echo "Say hello." | codexapi run
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
`codexapi task` exits with code 0 on success and 1 on failure, printing the summary.
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
codexapi task "Fix the failing tests." --max-iterations 5
|
|
61
|
+
```
|
|
58
62
|
|
|
59
63
|
Show running sessions and their latest activity:
|
|
60
64
|
|
|
@@ -66,17 +70,17 @@ Press `h` for keys.
|
|
|
66
70
|
Resume a session and print the thread id to stderr:
|
|
67
71
|
|
|
68
72
|
```bash
|
|
69
|
-
codexapi --thread-id THREAD_ID --print-thread-id "Continue where we left off."
|
|
73
|
+
codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off."
|
|
70
74
|
```
|
|
71
75
|
|
|
72
76
|
Ralph loop mode repeats the same prompt until a completion promise or a max
|
|
73
77
|
iteration cap is hit (0 means unlimited). Cancel by deleting
|
|
74
|
-
`.codexapi/ralph-loop.local.md` or running `codexapi --
|
|
78
|
+
`.codexapi/ralph-loop.local.md` or running `codexapi ralph --cancel`.
|
|
75
79
|
|
|
76
80
|
```bash
|
|
77
|
-
codexapi
|
|
78
|
-
codexapi
|
|
79
|
-
codexapi --
|
|
81
|
+
codexapi ralph "Fix the bug." --completion-promise DONE --max-iterations 5
|
|
82
|
+
codexapi ralph --ralph-fresh "Try again from scratch." --max-iterations 3
|
|
83
|
+
codexapi ralph --cancel --cwd /path/to/project
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
## API
|
|
@@ -87,9 +87,12 @@ def _parse_timestamp(value):
|
|
|
87
87
|
if value.endswith("Z"):
|
|
88
88
|
value = value[:-1] + "+00:00"
|
|
89
89
|
try:
|
|
90
|
-
|
|
90
|
+
parsed = datetime.fromisoformat(value)
|
|
91
91
|
except ValueError:
|
|
92
92
|
return None
|
|
93
|
+
if parsed.tzinfo is None:
|
|
94
|
+
return parsed
|
|
95
|
+
return parsed.astimezone().replace(tzinfo=None)
|
|
93
96
|
|
|
94
97
|
|
|
95
98
|
def _tail_lines(path):
|
|
@@ -867,146 +870,164 @@ def _run_top(argv):
|
|
|
867
870
|
|
|
868
871
|
def main(argv=None):
|
|
869
872
|
argv = sys.argv[1:] if argv is None else list(argv)
|
|
870
|
-
if argv and argv[0] == "top":
|
|
871
|
-
_run_top(argv[1:])
|
|
872
|
-
return
|
|
873
873
|
ralph_help = (
|
|
874
|
-
"Ralph loop mode (
|
|
874
|
+
"Ralph loop mode (ralph command):\n"
|
|
875
875
|
" Repeats the exact same prompt each iteration until a completion promise\n"
|
|
876
876
|
" is detected or --max-iterations is reached (0 means unlimited).\n"
|
|
877
877
|
" Completion promise: output <promise>TEXT</promise> where TEXT matches\n"
|
|
878
878
|
" --completion-promise after trimming/collapsing whitespace. CRITICAL RULE:\n"
|
|
879
879
|
" Only output the promise when it is completely and unequivocally TRUE.\n"
|
|
880
|
-
" Cancel by deleting .codexapi/ralph-loop.local.md or running --
|
|
880
|
+
" Cancel by deleting .codexapi/ralph-loop.local.md or running codexapi ralph --cancel.\n"
|
|
881
881
|
" Default reuses a single Codex thread; use --ralph-fresh for a new Agent\n"
|
|
882
882
|
" each iteration (no shared context).\n"
|
|
883
883
|
)
|
|
884
884
|
parser = argparse.ArgumentParser(
|
|
885
885
|
prog="codexapi",
|
|
886
886
|
description="Run Codex via the codexapi wrapper.",
|
|
887
|
-
epilog=ralph_help,
|
|
888
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
889
887
|
)
|
|
890
|
-
parser.
|
|
888
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
889
|
+
|
|
890
|
+
run_parser = subparsers.add_parser(
|
|
891
|
+
"run",
|
|
892
|
+
help="Run a Codex prompt.",
|
|
893
|
+
)
|
|
894
|
+
run_parser.add_argument(
|
|
891
895
|
"prompt",
|
|
892
896
|
nargs="?",
|
|
893
897
|
help="Prompt to send. Use '-' or omit to read from stdin.",
|
|
894
898
|
)
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
help="Run in task mode with verification retries.",
|
|
899
|
-
)
|
|
900
|
-
parser.add_argument(
|
|
901
|
-
"--check",
|
|
902
|
-
help="Optional check prompt for --task. Defaults to the task prompt.",
|
|
903
|
-
)
|
|
904
|
-
parser.add_argument("--cwd", help="Working directory for the Codex session.")
|
|
905
|
-
parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
|
|
906
|
-
parser.add_argument(
|
|
899
|
+
run_parser.add_argument("--cwd", help="Working directory for the Codex session.")
|
|
900
|
+
run_parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
|
|
901
|
+
run_parser.add_argument(
|
|
907
902
|
"--flags",
|
|
908
903
|
help="Additional raw CLI flags to pass to Codex (quoted as needed).",
|
|
909
904
|
)
|
|
910
|
-
|
|
905
|
+
run_parser.add_argument(
|
|
911
906
|
"--thread-id",
|
|
912
907
|
help="Resume an existing Codex thread id.",
|
|
913
908
|
)
|
|
914
|
-
|
|
909
|
+
run_parser.add_argument(
|
|
915
910
|
"--print-thread-id",
|
|
916
911
|
action="store_true",
|
|
917
912
|
help="Print the current thread id to stderr after running.",
|
|
918
913
|
)
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
help="Run a
|
|
914
|
+
|
|
915
|
+
task_parser = subparsers.add_parser(
|
|
916
|
+
"task",
|
|
917
|
+
help="Run a task with verification retries.",
|
|
918
|
+
)
|
|
919
|
+
task_parser.add_argument(
|
|
920
|
+
"prompt",
|
|
921
|
+
nargs="?",
|
|
922
|
+
help="Prompt to send. Use '-' or omit to read from stdin.",
|
|
923
|
+
)
|
|
924
|
+
task_parser.add_argument(
|
|
925
|
+
"--check",
|
|
926
|
+
help="Optional check prompt. Defaults to the task prompt.",
|
|
927
|
+
)
|
|
928
|
+
task_parser.add_argument(
|
|
929
|
+
"--max-iterations",
|
|
930
|
+
type=int,
|
|
931
|
+
default=10,
|
|
932
|
+
help="Max verification retries after a failed check (0 means no retries).",
|
|
933
|
+
)
|
|
934
|
+
task_parser.add_argument("--cwd", help="Working directory for the Codex session.")
|
|
935
|
+
task_parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
|
|
936
|
+
task_parser.add_argument(
|
|
937
|
+
"--flags",
|
|
938
|
+
help="Additional raw CLI flags to pass to Codex (quoted as needed).",
|
|
939
|
+
)
|
|
940
|
+
|
|
941
|
+
ralph_parser = subparsers.add_parser(
|
|
942
|
+
"ralph",
|
|
943
|
+
help="Run a Ralph loop.",
|
|
944
|
+
epilog=ralph_help,
|
|
945
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
946
|
+
)
|
|
947
|
+
ralph_parser.add_argument(
|
|
948
|
+
"prompt",
|
|
949
|
+
nargs="?",
|
|
950
|
+
help="Prompt to send. Use '-' or omit to read from stdin.",
|
|
923
951
|
)
|
|
924
|
-
|
|
952
|
+
ralph_parser.add_argument(
|
|
925
953
|
"--max-iterations",
|
|
926
954
|
type=int,
|
|
927
|
-
default=
|
|
928
|
-
help="Max iterations for
|
|
955
|
+
default=0,
|
|
956
|
+
help="Max iterations for the loop (0 means unlimited).",
|
|
957
|
+
)
|
|
958
|
+
ralph_parser.add_argument(
|
|
959
|
+
"--cancel",
|
|
960
|
+
action="store_true",
|
|
961
|
+
help="Cancel the Ralph loop state in the target cwd.",
|
|
929
962
|
)
|
|
930
|
-
|
|
963
|
+
ralph_parser.add_argument(
|
|
931
964
|
"--completion-promise",
|
|
932
|
-
help="Promise text
|
|
965
|
+
help="Promise text to match in <promise>...</promise>.",
|
|
933
966
|
)
|
|
934
|
-
|
|
967
|
+
ralph_parser.add_argument(
|
|
935
968
|
"--ralph-fresh",
|
|
936
969
|
action="store_true",
|
|
937
|
-
help="
|
|
970
|
+
help="Start each iteration with a fresh Agent context.",
|
|
938
971
|
)
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
972
|
+
ralph_parser.add_argument("--cwd", help="Working directory for the Codex session.")
|
|
973
|
+
ralph_parser.add_argument("--yolo", action="store_true", help="Pass --yolo to Codex.")
|
|
974
|
+
ralph_parser.add_argument(
|
|
975
|
+
"--flags",
|
|
976
|
+
help="Additional raw CLI flags to pass to Codex (quoted as needed).",
|
|
977
|
+
)
|
|
978
|
+
|
|
979
|
+
subparsers.add_parser(
|
|
980
|
+
"top",
|
|
981
|
+
help="Show running Codex sessions.",
|
|
946
982
|
)
|
|
947
983
|
|
|
948
984
|
args = parser.parse_args(argv)
|
|
949
|
-
if args.
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
or args.print_thread_id
|
|
955
|
-
or args.max_iterations is not None
|
|
956
|
-
or args.completion_promise is not None
|
|
957
|
-
or args.ralph_fresh
|
|
958
|
-
or args.check is not None
|
|
959
|
-
or args.prompt
|
|
960
|
-
):
|
|
961
|
-
raise SystemExit(
|
|
962
|
-
"--ralph-cancel cannot be combined with prompts or other modes."
|
|
963
|
-
)
|
|
964
|
-
print(cancel_ralph_loop(args.cwd))
|
|
985
|
+
if args.command is None:
|
|
986
|
+
parser.print_help()
|
|
987
|
+
raise SystemExit(2)
|
|
988
|
+
if args.command == "top":
|
|
989
|
+
_run_top([])
|
|
965
990
|
return
|
|
966
|
-
if args.check is not None and not args.task:
|
|
967
|
-
raise SystemExit("--check requires --task.")
|
|
968
|
-
if not args.ralph and (
|
|
969
|
-
args.max_iterations is not None
|
|
970
|
-
or args.completion_promise is not None
|
|
971
|
-
or args.ralph_fresh
|
|
972
|
-
):
|
|
973
|
-
raise SystemExit(
|
|
974
|
-
"--max-iterations/--completion-promise/--ralph-fresh require --ralph."
|
|
975
|
-
)
|
|
976
|
-
if args.ralph and (args.task or args.thread_id or args.print_thread_id):
|
|
977
|
-
raise SystemExit(
|
|
978
|
-
"--task/--thread-id/--print-thread-id are not supported with --ralph."
|
|
979
|
-
)
|
|
980
|
-
if args.task and (args.thread_id or args.print_thread_id):
|
|
981
|
-
raise SystemExit("--thread-id/--print-thread-id are not supported with --task.")
|
|
982
991
|
|
|
983
|
-
|
|
992
|
+
if args.command == "ralph":
|
|
993
|
+
if args.cancel:
|
|
994
|
+
if args.prompt:
|
|
995
|
+
raise SystemExit("ralph --cancel takes no prompt.")
|
|
996
|
+
if args.completion_promise or args.ralph_fresh:
|
|
997
|
+
raise SystemExit("--completion-promise/--ralph-fresh are not allowed with --cancel.")
|
|
998
|
+
if args.max_iterations != 0:
|
|
999
|
+
raise SystemExit("--max-iterations is not allowed with --cancel.")
|
|
1000
|
+
print(cancel_ralph_loop(args.cwd))
|
|
1001
|
+
return
|
|
984
1002
|
|
|
1003
|
+
prompt = _read_prompt(args.prompt)
|
|
985
1004
|
exit_code = 0
|
|
986
1005
|
|
|
987
|
-
if args.ralph:
|
|
988
|
-
|
|
989
|
-
if max_iterations < 0:
|
|
1006
|
+
if args.command == "ralph":
|
|
1007
|
+
if args.max_iterations < 0:
|
|
990
1008
|
raise SystemExit("--max-iterations must be >= 0.")
|
|
991
1009
|
run_ralph_loop(
|
|
992
1010
|
prompt,
|
|
993
1011
|
args.cwd,
|
|
994
1012
|
args.yolo,
|
|
995
1013
|
args.flags,
|
|
996
|
-
max_iterations,
|
|
1014
|
+
args.max_iterations,
|
|
997
1015
|
args.completion_promise,
|
|
998
1016
|
args.ralph_fresh,
|
|
999
1017
|
)
|
|
1000
1018
|
return
|
|
1001
|
-
if args.task:
|
|
1019
|
+
if args.command == "task":
|
|
1020
|
+
if args.max_iterations < 0:
|
|
1021
|
+
raise SystemExit("--max-iterations must be >= 0.")
|
|
1002
1022
|
check = args.check if args.check is not None else prompt
|
|
1003
1023
|
try:
|
|
1004
1024
|
message = task(
|
|
1005
1025
|
prompt,
|
|
1006
1026
|
check,
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1027
|
+
args.max_iterations,
|
|
1028
|
+
args.cwd,
|
|
1029
|
+
args.yolo,
|
|
1030
|
+
args.flags,
|
|
1010
1031
|
)
|
|
1011
1032
|
except TaskFailed as exc:
|
|
1012
1033
|
message = exc.summary
|
|
@@ -39,7 +39,7 @@ def run_ralph_loop(
|
|
|
39
39
|
|
|
40
40
|
By default a single Agent instance is reused for shared context. Set
|
|
41
41
|
`fresh=True` to create a new Agent each iteration for a clean context.
|
|
42
|
-
Cancel by deleting the state file or running `codexapi --
|
|
42
|
+
Cancel by deleting the state file or running `codexapi ralph --cancel`.
|
|
43
43
|
"""
|
|
44
44
|
if not isinstance(prompt, str) or not prompt.strip():
|
|
45
45
|
raise ValueError("prompt must be a non-empty string")
|
|
@@ -81,7 +81,7 @@ def run_ralph_loop(
|
|
|
81
81
|
"",
|
|
82
82
|
"The loop will resend the SAME PROMPT each iteration.",
|
|
83
83
|
"Cancel by deleting .codexapi/ralph-loop.local.md or running",
|
|
84
|
-
"codexapi --
|
|
84
|
+
"codexapi ralph --cancel.",
|
|
85
85
|
"No manual stop beyond max iterations or completion promise.",
|
|
86
86
|
"",
|
|
87
87
|
"To monitor: head -10 .codexapi/ralph-loop.local.md",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codexapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Minimal Python API for running the Codex CLI.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: codex,agent,cli,openai
|
|
@@ -61,12 +61,16 @@ print(result.success, result.summary)
|
|
|
61
61
|
After installing, use the `codexapi` command:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
-
codexapi "Summarize this repo."
|
|
65
|
-
codexapi --cwd /path/to/project "Fix the failing tests."
|
|
66
|
-
echo "Say hello." | codexapi
|
|
64
|
+
codexapi run "Summarize this repo."
|
|
65
|
+
codexapi run --cwd /path/to/project "Fix the failing tests."
|
|
66
|
+
echo "Say hello." | codexapi run
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
`codexapi task` exits with code 0 on success and 1 on failure, printing the summary.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
codexapi task "Fix the failing tests." --max-iterations 5
|
|
73
|
+
```
|
|
70
74
|
|
|
71
75
|
Show running sessions and their latest activity:
|
|
72
76
|
|
|
@@ -78,17 +82,17 @@ Press `h` for keys.
|
|
|
78
82
|
Resume a session and print the thread id to stderr:
|
|
79
83
|
|
|
80
84
|
```bash
|
|
81
|
-
codexapi --thread-id THREAD_ID --print-thread-id "Continue where we left off."
|
|
85
|
+
codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off."
|
|
82
86
|
```
|
|
83
87
|
|
|
84
88
|
Ralph loop mode repeats the same prompt until a completion promise or a max
|
|
85
89
|
iteration cap is hit (0 means unlimited). Cancel by deleting
|
|
86
|
-
`.codexapi/ralph-loop.local.md` or running `codexapi --
|
|
90
|
+
`.codexapi/ralph-loop.local.md` or running `codexapi ralph --cancel`.
|
|
87
91
|
|
|
88
92
|
```bash
|
|
89
|
-
codexapi
|
|
90
|
-
codexapi
|
|
91
|
-
codexapi --
|
|
93
|
+
codexapi ralph "Fix the bug." --completion-promise DONE --max-iterations 5
|
|
94
|
+
codexapi ralph --ralph-fresh "Try again from scratch." --max-iterations 3
|
|
95
|
+
codexapi ralph --cancel --cwd /path/to/project
|
|
92
96
|
```
|
|
93
97
|
|
|
94
98
|
## API
|
|
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
|