codexapi 0.6.8__tar.gz → 0.7.1__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.6.8/src/codexapi.egg-info → codexapi-0.7.1}/PKG-INFO +36 -14
- {codexapi-0.6.8 → codexapi-0.7.1}/README.md +35 -13
- {codexapi-0.6.8 → codexapi-0.7.1}/pyproject.toml +1 -1
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/__init__.py +3 -3
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/agent.py +15 -6
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/cli.py +62 -19
- codexapi-0.7.1/src/codexapi/lead.py +477 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/pushover.py +1 -1
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/ralph.py +17 -2
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/science.py +1 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/task.py +1 -1
- {codexapi-0.6.8 → codexapi-0.7.1/src/codexapi.egg-info}/PKG-INFO +36 -14
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/SOURCES.txt +1 -1
- codexapi-0.6.8/src/codexapi/watch.py +0 -302
- {codexapi-0.6.8 → codexapi-0.7.1}/LICENSE +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/setup.cfg +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/__main__.py +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/foreach.py +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/gh_integration.py +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/rate_limits.py +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/taskfile.py +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi/welfare.py +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/dependency_links.txt +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/entry_points.txt +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/requires.txt +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/src/codexapi.egg-info/top_level.txt +0 -0
- {codexapi-0.6.8 → codexapi-0.7.1}/tests/test_task_progress.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codexapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Minimal Python API for running the Codex CLI.
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: codex,agent,cli,openai
|
|
@@ -130,17 +130,32 @@ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off
|
|
|
130
130
|
```
|
|
131
131
|
|
|
132
132
|
Use `--no-yolo` to run Codex with `--full-auto` instead.
|
|
133
|
+
Use `--include-thinking` to return all agent messages joined together for `codexapi run`.
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
and prints JSON status updates. The agent controls the loop by
|
|
136
|
-
`continue` to true/false in its JSON response. Each
|
|
135
|
+
Lead mode periodically checks in on a long-running agent session with the
|
|
136
|
+
current time and prints JSON status updates. The agent controls the loop by
|
|
137
|
+
setting `continue` to true/false in its JSON response. Each check-in expects
|
|
138
|
+
JSON keys:
|
|
137
139
|
`status` (one line), `continue` (bool), and optional `comments` (string). If the
|
|
138
|
-
JSON is invalid,
|
|
139
|
-
error. When `~/.pushover` is configured,
|
|
140
|
+
JSON is invalid, lead asks the agent once to retry before stopping with an
|
|
141
|
+
error. When `~/.pushover` is configured, lead sends a notification when it
|
|
140
142
|
stops.
|
|
141
143
|
|
|
144
|
+
Lead mode also uses a leadbook file as the agent's working page. By default this
|
|
145
|
+
is `LEADBOOK.md` in the working directory. The leadbook content is injected into
|
|
146
|
+
each check-in prompt and must be updated before the agent responds. Use
|
|
147
|
+
`--leadbook PATH` to point at a different file, or `--no-leadbook` to disable.
|
|
148
|
+
Use `-f/--prompt-file` to read the prompt from a file.
|
|
149
|
+
If the leadbook does not exist, lead creates it with a template.
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
codexapi lead 5 "Run the benchmark and wait for results."
|
|
153
|
+
|
|
154
|
+
Run without waiting between check-ins:
|
|
155
|
+
|
|
142
156
|
```bash
|
|
143
|
-
codexapi
|
|
157
|
+
codexapi lead 0 "Do a rapid triage pass and report."
|
|
158
|
+
```
|
|
144
159
|
```
|
|
145
160
|
|
|
146
161
|
Ralph loop mode repeats the same prompt until a completion promise or a max
|
|
@@ -171,7 +186,7 @@ Optional Pushover notifications: create `~/.pushover` with two non-empty lines.
|
|
|
171
186
|
Line 1 is your user or group key, line 2 is the app API token. When this file
|
|
172
187
|
exists, Science will send a notification whenever it detects a new best result,
|
|
173
188
|
including the metric values and percent improvement. Task runs will also send a
|
|
174
|
-
✅/❌ notification with the task summary.
|
|
189
|
+
✅/❌ notification with the task summary. Lead runs send a notification when the
|
|
175
190
|
loop stops.
|
|
176
191
|
|
|
177
192
|
Run a task file across a list file:
|
|
@@ -185,7 +200,7 @@ codexapi foreach list.txt task.yaml --retry-all
|
|
|
185
200
|
|
|
186
201
|
## API
|
|
187
202
|
|
|
188
|
-
### `agent(prompt, cwd=None, yolo=True, flags=None) -> str`
|
|
203
|
+
### `agent(prompt, cwd=None, yolo=True, flags=None, include_thinking=False) -> str`
|
|
189
204
|
|
|
190
205
|
Runs a single Codex turn and returns only the agent's message. Any reasoning
|
|
191
206
|
items are filtered out.
|
|
@@ -194,8 +209,9 @@ items are filtered out.
|
|
|
194
209
|
- `cwd` (str | PathLike | None): working directory for the Codex session.
|
|
195
210
|
- `yolo` (bool): pass `--yolo` to Codex when true (defaults to true).
|
|
196
211
|
- `flags` (str | None): extra CLI flags to pass to Codex.
|
|
212
|
+
- `include_thinking` (bool): when true, return all agent messages joined.
|
|
197
213
|
|
|
198
|
-
### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False)`
|
|
214
|
+
### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False, include_thinking=False)`
|
|
199
215
|
|
|
200
216
|
Creates a stateful session wrapper. Calling the instance sends the prompt into
|
|
201
217
|
the same conversation and returns only the agent's message.
|
|
@@ -206,15 +222,20 @@ the same conversation and returns only the agent's message.
|
|
|
206
222
|
- `flags` (str | None): extra CLI flags to pass to Codex.
|
|
207
223
|
- `welfare` (bool): when true, append welfare stop instructions to each prompt
|
|
208
224
|
and raise `WelfareStop` if the agent outputs `MAKE IT STOP`.
|
|
225
|
+
- `include_thinking` (bool): when true, return all agent messages joined.
|
|
209
226
|
|
|
210
|
-
### `
|
|
227
|
+
### `lead(minutes, prompt, cwd=None, yolo=True, flags=None, leadbook=None) -> dict`
|
|
211
228
|
|
|
212
|
-
Runs a long-lived agent session and periodically
|
|
213
|
-
local time and a reminder of `prompt`. Each
|
|
229
|
+
Runs a long-lived agent session and periodically checks in with the current
|
|
230
|
+
local time and a reminder of `prompt`. Each check-in expects JSON with keys:
|
|
214
231
|
`status` (one line), `continue` (bool), and optional `comments` (string). If the
|
|
215
|
-
JSON is invalid,
|
|
232
|
+
JSON is invalid, lead asks the agent once to retry. The loop stops when
|
|
216
233
|
`continue` is false and sends a Pushover notification (when configured).
|
|
217
234
|
|
|
235
|
+
Lead also injects the leadbook content into each prompt. By default it uses
|
|
236
|
+
`LEADBOOK.md` in the working directory. Pass `leadbook=False` to disable or a
|
|
237
|
+
path string to override the location.
|
|
238
|
+
|
|
218
239
|
### `task(prompt, check=None, max_iterations=10, cwd=None, yolo=True, flags=None, progress=False, set_up=None, tear_down=None, on_success=None, on_failure=None) -> str`
|
|
219
240
|
|
|
220
241
|
Runs a task with checker-driven retries and returns the success summary.
|
|
@@ -287,6 +308,7 @@ Simple result object returned by `foreach()`.
|
|
|
287
308
|
## Behavior notes
|
|
288
309
|
|
|
289
310
|
- Uses `codex exec --json` and parses JSONL events for `agent_message` items.
|
|
311
|
+
- Returns the last `agent_message` by default; set `include_thinking=True` to join all messages.
|
|
290
312
|
- Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
|
|
291
313
|
- Passes `--yolo` by default (use `--no-yolo` or `yolo=False` for `--full-auto`).
|
|
292
314
|
- Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
|
|
@@ -115,17 +115,32 @@ codexapi run --thread-id THREAD_ID --print-thread-id "Continue where we left off
|
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
Use `--no-yolo` to run Codex with `--full-auto` instead.
|
|
118
|
+
Use `--include-thinking` to return all agent messages joined together for `codexapi run`.
|
|
118
119
|
|
|
119
|
-
|
|
120
|
-
and prints JSON status updates. The agent controls the loop by
|
|
121
|
-
`continue` to true/false in its JSON response. Each
|
|
120
|
+
Lead mode periodically checks in on a long-running agent session with the
|
|
121
|
+
current time and prints JSON status updates. The agent controls the loop by
|
|
122
|
+
setting `continue` to true/false in its JSON response. Each check-in expects
|
|
123
|
+
JSON keys:
|
|
122
124
|
`status` (one line), `continue` (bool), and optional `comments` (string). If the
|
|
123
|
-
JSON is invalid,
|
|
124
|
-
error. When `~/.pushover` is configured,
|
|
125
|
+
JSON is invalid, lead asks the agent once to retry before stopping with an
|
|
126
|
+
error. When `~/.pushover` is configured, lead sends a notification when it
|
|
125
127
|
stops.
|
|
126
128
|
|
|
129
|
+
Lead mode also uses a leadbook file as the agent's working page. By default this
|
|
130
|
+
is `LEADBOOK.md` in the working directory. The leadbook content is injected into
|
|
131
|
+
each check-in prompt and must be updated before the agent responds. Use
|
|
132
|
+
`--leadbook PATH` to point at a different file, or `--no-leadbook` to disable.
|
|
133
|
+
Use `-f/--prompt-file` to read the prompt from a file.
|
|
134
|
+
If the leadbook does not exist, lead creates it with a template.
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
codexapi lead 5 "Run the benchmark and wait for results."
|
|
138
|
+
|
|
139
|
+
Run without waiting between check-ins:
|
|
140
|
+
|
|
127
141
|
```bash
|
|
128
|
-
codexapi
|
|
142
|
+
codexapi lead 0 "Do a rapid triage pass and report."
|
|
143
|
+
```
|
|
129
144
|
```
|
|
130
145
|
|
|
131
146
|
Ralph loop mode repeats the same prompt until a completion promise or a max
|
|
@@ -156,7 +171,7 @@ Optional Pushover notifications: create `~/.pushover` with two non-empty lines.
|
|
|
156
171
|
Line 1 is your user or group key, line 2 is the app API token. When this file
|
|
157
172
|
exists, Science will send a notification whenever it detects a new best result,
|
|
158
173
|
including the metric values and percent improvement. Task runs will also send a
|
|
159
|
-
✅/❌ notification with the task summary.
|
|
174
|
+
✅/❌ notification with the task summary. Lead runs send a notification when the
|
|
160
175
|
loop stops.
|
|
161
176
|
|
|
162
177
|
Run a task file across a list file:
|
|
@@ -170,7 +185,7 @@ codexapi foreach list.txt task.yaml --retry-all
|
|
|
170
185
|
|
|
171
186
|
## API
|
|
172
187
|
|
|
173
|
-
### `agent(prompt, cwd=None, yolo=True, flags=None) -> str`
|
|
188
|
+
### `agent(prompt, cwd=None, yolo=True, flags=None, include_thinking=False) -> str`
|
|
174
189
|
|
|
175
190
|
Runs a single Codex turn and returns only the agent's message. Any reasoning
|
|
176
191
|
items are filtered out.
|
|
@@ -179,8 +194,9 @@ items are filtered out.
|
|
|
179
194
|
- `cwd` (str | PathLike | None): working directory for the Codex session.
|
|
180
195
|
- `yolo` (bool): pass `--yolo` to Codex when true (defaults to true).
|
|
181
196
|
- `flags` (str | None): extra CLI flags to pass to Codex.
|
|
197
|
+
- `include_thinking` (bool): when true, return all agent messages joined.
|
|
182
198
|
|
|
183
|
-
### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False)`
|
|
199
|
+
### `Agent(cwd=None, yolo=True, thread_id=None, flags=None, welfare=False, include_thinking=False)`
|
|
184
200
|
|
|
185
201
|
Creates a stateful session wrapper. Calling the instance sends the prompt into
|
|
186
202
|
the same conversation and returns only the agent's message.
|
|
@@ -191,15 +207,20 @@ the same conversation and returns only the agent's message.
|
|
|
191
207
|
- `flags` (str | None): extra CLI flags to pass to Codex.
|
|
192
208
|
- `welfare` (bool): when true, append welfare stop instructions to each prompt
|
|
193
209
|
and raise `WelfareStop` if the agent outputs `MAKE IT STOP`.
|
|
210
|
+
- `include_thinking` (bool): when true, return all agent messages joined.
|
|
194
211
|
|
|
195
|
-
### `
|
|
212
|
+
### `lead(minutes, prompt, cwd=None, yolo=True, flags=None, leadbook=None) -> dict`
|
|
196
213
|
|
|
197
|
-
Runs a long-lived agent session and periodically
|
|
198
|
-
local time and a reminder of `prompt`. Each
|
|
214
|
+
Runs a long-lived agent session and periodically checks in with the current
|
|
215
|
+
local time and a reminder of `prompt`. Each check-in expects JSON with keys:
|
|
199
216
|
`status` (one line), `continue` (bool), and optional `comments` (string). If the
|
|
200
|
-
JSON is invalid,
|
|
217
|
+
JSON is invalid, lead asks the agent once to retry. The loop stops when
|
|
201
218
|
`continue` is false and sends a Pushover notification (when configured).
|
|
202
219
|
|
|
220
|
+
Lead also injects the leadbook content into each prompt. By default it uses
|
|
221
|
+
`LEADBOOK.md` in the working directory. Pass `leadbook=False` to disable or a
|
|
222
|
+
path string to override the location.
|
|
223
|
+
|
|
203
224
|
### `task(prompt, check=None, max_iterations=10, cwd=None, yolo=True, flags=None, progress=False, set_up=None, tear_down=None, on_success=None, on_failure=None) -> str`
|
|
204
225
|
|
|
205
226
|
Runs a task with checker-driven retries and returns the success summary.
|
|
@@ -272,6 +293,7 @@ Simple result object returned by `foreach()`.
|
|
|
272
293
|
## Behavior notes
|
|
273
294
|
|
|
274
295
|
- Uses `codex exec --json` and parses JSONL events for `agent_message` items.
|
|
296
|
+
- Returns the last `agent_message` by default; set `include_thinking=True` to join all messages.
|
|
275
297
|
- Automatically passes `--skip-git-repo-check` so it can run outside a git repo.
|
|
276
298
|
- Passes `--yolo` by default (use `--no-yolo` or `yolo=False` for `--full-auto`).
|
|
277
299
|
- Raises `RuntimeError` if Codex exits non-zero or returns no agent message.
|
|
@@ -7,7 +7,7 @@ from .rate_limits import quota_line, rate_limits
|
|
|
7
7
|
from .ralph import Ralph
|
|
8
8
|
from .science import Science
|
|
9
9
|
from .task import Task, TaskFailed, TaskResult, task, task_result
|
|
10
|
-
from .
|
|
10
|
+
from .lead import lead
|
|
11
11
|
|
|
12
12
|
__all__ = [
|
|
13
13
|
"Agent",
|
|
@@ -25,6 +25,6 @@ __all__ = [
|
|
|
25
25
|
"foreach",
|
|
26
26
|
"task",
|
|
27
27
|
"task_result",
|
|
28
|
-
"
|
|
28
|
+
"lead",
|
|
29
29
|
]
|
|
30
|
-
__version__ = "0.
|
|
30
|
+
__version__ = "0.7.1"
|
|
@@ -10,7 +10,7 @@ from . import welfare
|
|
|
10
10
|
_CODEX_BIN = os.environ.get("CODEX_BIN", "codex")
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
def agent(prompt, cwd=None, yolo=True, flags=None):
|
|
13
|
+
def agent(prompt, cwd=None, yolo=True, flags=None, include_thinking=False):
|
|
14
14
|
"""Run a single Codex turn and return only the agent's message.
|
|
15
15
|
|
|
16
16
|
Args:
|
|
@@ -18,11 +18,14 @@ def agent(prompt, cwd=None, yolo=True, flags=None):
|
|
|
18
18
|
cwd: Optional working directory for the Codex session.
|
|
19
19
|
yolo: Whether to pass --yolo to Codex.
|
|
20
20
|
flags: Additional raw CLI flags to pass to Codex.
|
|
21
|
+
include_thinking: When true, return all agent messages joined together.
|
|
21
22
|
|
|
22
23
|
Returns:
|
|
23
24
|
The agent's visible response text with reasoning traces removed.
|
|
24
25
|
"""
|
|
25
|
-
message, _thread_id = _run_codex(
|
|
26
|
+
message, _thread_id = _run_codex(
|
|
27
|
+
prompt, cwd, None, yolo, flags, include_thinking
|
|
28
|
+
)
|
|
26
29
|
return message
|
|
27
30
|
|
|
28
31
|
|
|
@@ -51,6 +54,7 @@ class Agent:
|
|
|
51
54
|
thread_id=None,
|
|
52
55
|
flags=None,
|
|
53
56
|
welfare=False,
|
|
57
|
+
include_thinking=False,
|
|
54
58
|
):
|
|
55
59
|
"""Create a new session wrapper.
|
|
56
60
|
|
|
@@ -62,11 +66,13 @@ class Agent:
|
|
|
62
66
|
flags: Additional raw CLI flags to pass to Codex.
|
|
63
67
|
welfare: When true, append welfare stop instructions to each prompt
|
|
64
68
|
and raise WelfareStop if the agent outputs MAKE IT STOP.
|
|
69
|
+
include_thinking: When true, return all agent messages joined together.
|
|
65
70
|
"""
|
|
66
71
|
self.cwd = cwd
|
|
67
72
|
self._yolo = yolo
|
|
68
73
|
self._flags = flags
|
|
69
74
|
self._welfare = welfare
|
|
75
|
+
self._include_thinking = include_thinking
|
|
70
76
|
self.thread_id = thread_id
|
|
71
77
|
|
|
72
78
|
def __call__(self, prompt):
|
|
@@ -79,6 +85,7 @@ class Agent:
|
|
|
79
85
|
self.thread_id,
|
|
80
86
|
self._yolo,
|
|
81
87
|
self._flags,
|
|
88
|
+
self._include_thinking,
|
|
82
89
|
)
|
|
83
90
|
if thread_id:
|
|
84
91
|
self.thread_id = thread_id
|
|
@@ -87,7 +94,7 @@ class Agent:
|
|
|
87
94
|
return message
|
|
88
95
|
|
|
89
96
|
|
|
90
|
-
def _run_codex(prompt, cwd, thread_id, yolo, flags):
|
|
97
|
+
def _run_codex(prompt, cwd, thread_id, yolo, flags, include_thinking):
|
|
91
98
|
"""Invoke the Codex CLI and return the message plus thread id (if any)."""
|
|
92
99
|
command = [
|
|
93
100
|
_CODEX_BIN,
|
|
@@ -124,10 +131,10 @@ def _run_codex(prompt, cwd, thread_id, yolo, flags):
|
|
|
124
131
|
msg = f"{msg}\n{stderr}"
|
|
125
132
|
raise RuntimeError(msg)
|
|
126
133
|
|
|
127
|
-
return _parse_jsonl(result.stdout)
|
|
134
|
+
return _parse_jsonl(result.stdout, include_thinking)
|
|
128
135
|
|
|
129
136
|
|
|
130
|
-
def _parse_jsonl(output):
|
|
137
|
+
def _parse_jsonl(output, include_thinking):
|
|
131
138
|
"""Extract agent messages and the latest thread id from Codex JSONL output."""
|
|
132
139
|
thread_id = None
|
|
133
140
|
messages = []
|
|
@@ -161,4 +168,6 @@ def _parse_jsonl(output):
|
|
|
161
168
|
"Codex returned no agent message. Raw output:\n" + fallback
|
|
162
169
|
)
|
|
163
170
|
|
|
164
|
-
|
|
171
|
+
if include_thinking:
|
|
172
|
+
return "\n\n".join(messages), thread_id
|
|
173
|
+
return messages[-1], thread_id
|
|
@@ -19,7 +19,7 @@ from .science import Science
|
|
|
19
19
|
from .task import DEFAULT_MAX_ITERATIONS, TaskFailed, task
|
|
20
20
|
from .taskfile import TaskFile, load_task_file, task_def_uses_item
|
|
21
21
|
from .rate_limits import quota_line
|
|
22
|
-
from .
|
|
22
|
+
from .lead import lead
|
|
23
23
|
|
|
24
24
|
_SESSION_ID_RE = re.compile(
|
|
25
25
|
r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
|
|
@@ -92,6 +92,19 @@ def _read_prompt(prompt):
|
|
|
92
92
|
return data
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
def _read_prompt_file(path):
|
|
96
|
+
if not path or not str(path).strip():
|
|
97
|
+
raise SystemExit("Prompt file path is empty.")
|
|
98
|
+
try:
|
|
99
|
+
with open(path, "r", encoding="utf-8") as handle:
|
|
100
|
+
data = handle.read()
|
|
101
|
+
except FileNotFoundError:
|
|
102
|
+
raise SystemExit(f"Prompt file not found: {path}") from None
|
|
103
|
+
if not data.strip():
|
|
104
|
+
raise SystemExit(f"Prompt file is empty: {path}")
|
|
105
|
+
return data
|
|
106
|
+
|
|
107
|
+
|
|
95
108
|
def _single_line(text):
|
|
96
109
|
if not text:
|
|
97
110
|
return ""
|
|
@@ -1040,29 +1053,48 @@ def main(argv=None):
|
|
|
1040
1053
|
"--flags",
|
|
1041
1054
|
help="Additional raw CLI flags to pass to Codex (quoted as needed).",
|
|
1042
1055
|
)
|
|
1056
|
+
run_parser.add_argument(
|
|
1057
|
+
"--include-thinking",
|
|
1058
|
+
action="store_true",
|
|
1059
|
+
help="Return all agent messages joined together.",
|
|
1060
|
+
)
|
|
1043
1061
|
|
|
1044
|
-
|
|
1045
|
-
"
|
|
1046
|
-
help="Periodically
|
|
1062
|
+
lead_parser = subparsers.add_parser(
|
|
1063
|
+
"lead",
|
|
1064
|
+
help="Periodically check in to lead long-running work.",
|
|
1047
1065
|
)
|
|
1048
|
-
|
|
1066
|
+
lead_parser.add_argument(
|
|
1049
1067
|
"minutes",
|
|
1050
1068
|
type=int,
|
|
1051
|
-
help="
|
|
1069
|
+
help="Check-in interval in minutes (integer, >= 0).",
|
|
1052
1070
|
)
|
|
1053
|
-
|
|
1071
|
+
lead_parser.add_argument(
|
|
1054
1072
|
"prompt",
|
|
1055
1073
|
nargs="?",
|
|
1056
1074
|
help="Prompt to send. Use '-' or omit to read from stdin.",
|
|
1057
1075
|
)
|
|
1058
|
-
|
|
1059
|
-
|
|
1076
|
+
lead_parser.add_argument(
|
|
1077
|
+
"-f",
|
|
1078
|
+
"--prompt-file",
|
|
1079
|
+
help="Read the lead prompt from a file.",
|
|
1080
|
+
)
|
|
1081
|
+
lead_parser.add_argument("--cwd", help="Working directory for the Codex session.")
|
|
1082
|
+
lead_parser.add_argument(
|
|
1083
|
+
"--leadbook",
|
|
1084
|
+
help="Path to the leadbook file (default: LEADBOOK.md in cwd).",
|
|
1085
|
+
)
|
|
1086
|
+
lead_parser.add_argument(
|
|
1087
|
+
"--no-leadbook",
|
|
1088
|
+
action="store_true",
|
|
1089
|
+
help="Disable leadbook injection and checks.",
|
|
1090
|
+
)
|
|
1091
|
+
lead_parser.add_argument(
|
|
1060
1092
|
"--no-yolo",
|
|
1061
1093
|
action="store_false",
|
|
1062
1094
|
dest="yolo",
|
|
1063
1095
|
help="Disable --yolo and use --full-auto.",
|
|
1064
1096
|
)
|
|
1065
|
-
|
|
1097
|
+
lead_parser.add_argument(
|
|
1066
1098
|
"--flags",
|
|
1067
1099
|
help="Additional raw CLI flags to pass to Codex (quoted as needed).",
|
|
1068
1100
|
)
|
|
@@ -1517,11 +1549,16 @@ def main(argv=None):
|
|
|
1517
1549
|
|
|
1518
1550
|
prompt_source = None
|
|
1519
1551
|
prompt = None
|
|
1520
|
-
if args.command in ("run", "ralph", "
|
|
1521
|
-
|
|
1552
|
+
if args.command in ("run", "ralph", "lead"):
|
|
1553
|
+
if args.command == "lead" and args.prompt_file:
|
|
1554
|
+
if args.prompt is not None:
|
|
1555
|
+
raise SystemExit("lead --prompt-file cannot be used with a prompt arg.")
|
|
1556
|
+
prompt = _read_prompt_file(args.prompt_file)
|
|
1557
|
+
else:
|
|
1558
|
+
prompt_source = args.prompt
|
|
1522
1559
|
elif args.command == "science":
|
|
1523
1560
|
prompt_source = args.task
|
|
1524
|
-
if args.command != "task":
|
|
1561
|
+
if args.command != "task" and prompt is None:
|
|
1525
1562
|
prompt = _read_prompt(prompt_source)
|
|
1526
1563
|
exit_code = 0
|
|
1527
1564
|
message = None
|
|
@@ -1552,15 +1589,18 @@ def main(argv=None):
|
|
|
1552
1589
|
args.ralph_fresh,
|
|
1553
1590
|
)()
|
|
1554
1591
|
return
|
|
1555
|
-
if args.command == "
|
|
1556
|
-
if args.minutes <
|
|
1557
|
-
raise SystemExit("
|
|
1592
|
+
if args.command == "lead":
|
|
1593
|
+
if args.minutes < 0:
|
|
1594
|
+
raise SystemExit("lead minutes must be >= 0.")
|
|
1558
1595
|
try:
|
|
1559
|
-
|
|
1596
|
+
if args.no_leadbook and args.leadbook:
|
|
1597
|
+
raise SystemExit("--leadbook and --no-leadbook are mutually exclusive.")
|
|
1598
|
+
leadbook = False if args.no_leadbook else args.leadbook
|
|
1599
|
+
lead(args.minutes, prompt, args.cwd, args.yolo, args.flags, leadbook)
|
|
1560
1600
|
except KeyboardInterrupt:
|
|
1561
1601
|
raise SystemExit(130)
|
|
1562
1602
|
except Exception as exc:
|
|
1563
|
-
raise SystemExit(str(exc) or "
|
|
1603
|
+
raise SystemExit(str(exc) or "lead failed") from None
|
|
1564
1604
|
return
|
|
1565
1605
|
if args.command == "task":
|
|
1566
1606
|
if args.project:
|
|
@@ -1602,12 +1642,15 @@ def main(argv=None):
|
|
|
1602
1642
|
args.yolo,
|
|
1603
1643
|
args.thread_id,
|
|
1604
1644
|
args.flags,
|
|
1645
|
+
include_thinking=args.include_thinking,
|
|
1605
1646
|
)
|
|
1606
1647
|
message = session(prompt)
|
|
1607
1648
|
if args.print_thread_id:
|
|
1608
1649
|
print(f"thread_id={session.thread_id}", file=sys.stderr)
|
|
1609
1650
|
else:
|
|
1610
|
-
message = agent(
|
|
1651
|
+
message = agent(
|
|
1652
|
+
prompt, args.cwd, args.yolo, args.flags, args.include_thinking
|
|
1653
|
+
)
|
|
1611
1654
|
|
|
1612
1655
|
if message is not None:
|
|
1613
1656
|
print(message)
|