python-codex 0.1.13__py3-none-any.whl → 0.2.0__py3-none-any.whl
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.
- pycodex/agent.py +71 -11
- pycodex/cli.py +16 -356
- pycodex/context.py +12 -0
- pycodex/feishu_card.py +76 -30
- pycodex/feishu_link.py +131 -11
- pycodex/interactive_session.py +397 -0
- pycodex/model.py +11 -22
- pycodex/protocol.py +0 -5
- pycodex/runtime.py +23 -0
- pycodex/runtime_services.py +2 -2
- pycodex/tools/agent_tool_schemas.py +1 -1
- pycodex/tools/apply_patch_tool.py +1 -1
- pycodex/tools/base_tool.py +1 -27
- pycodex/tools/close_agent_tool.py +11 -4
- pycodex/tools/code_mode_manager.py +1 -1
- pycodex/tools/exec_command_tool.py +40 -16
- pycodex/tools/exec_tool.py +18 -2
- pycodex/tools/grep_files_tool.py +19 -6
- pycodex/tools/ipython_tool.py +3 -2
- pycodex/tools/list_dir_tool.py +19 -6
- pycodex/tools/read_file_tool.py +39 -9
- pycodex/tools/request_permissions_tool.py +12 -1
- pycodex/tools/request_user_input_tool.py +28 -1
- pycodex/tools/send_input_tool.py +4 -2
- pycodex/tools/shell_command_tool.py +23 -6
- pycodex/tools/shell_tool.py +13 -4
- pycodex/tools/spawn_agent_tool.py +31 -8
- pycodex/tools/unified_exec_manager.py +49 -93
- pycodex/tools/update_plan_tool.py +14 -6
- pycodex/tools/view_image_tool.py +17 -16
- pycodex/tools/wait_agent_tool.py +15 -3
- pycodex/tools/wait_tool.py +18 -4
- pycodex/tools/web_search_tool.py +2 -1
- pycodex/tools/write_stdin_tool.py +42 -10
- pycodex/utils/compactor.py +7 -1
- pycodex/utils/session_persist.py +42 -1
- pycodex/utils/truncation.py +206 -0
- pycodex/utils/visualize.py +34 -15
- {python_codex-0.1.13.dist-info → python_codex-0.2.0.dist-info}/METADATA +4 -1
- python_codex-0.2.0.dist-info/RECORD +88 -0
- {python_codex-0.1.13.dist-info → python_codex-0.2.0.dist-info}/entry_points.txt +1 -0
- workspace_server/__init__.py +23 -0
- workspace_server/__main__.py +5 -0
- workspace_server/app.py +1347 -0
- workspace_server/workspace.html +866 -0
- pycodex/prompts/exec_tools.json +0 -411
- pycodex/prompts/subagent_tools.json +0 -163
- python_codex-0.1.13.dist-info/RECORD +0 -84
- {python_codex-0.1.13.dist-info → python_codex-0.2.0.dist-info}/WHEEL +0 -0
- {python_codex-0.1.13.dist-info → python_codex-0.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
"""Shared truncation helpers for model-visible tool output."""
|
|
2
|
+
|
|
3
|
+
import math
|
|
4
|
+
|
|
5
|
+
from ..protocol import JSONValue, ToolResult
|
|
6
|
+
import typing
|
|
7
|
+
|
|
8
|
+
DEFAULT_MAX_OUTPUT_TOKENS = 10_000
|
|
9
|
+
TRUNCATION_SERIALIZATION_BUDGET_MULTIPLIER = 1.2
|
|
10
|
+
HISTORY_TOOL_OUTPUT_TOKENS = int(
|
|
11
|
+
math.ceil(DEFAULT_MAX_OUTPUT_TOKENS * TRUNCATION_SERIALIZATION_BUDGET_MULTIPLIER)
|
|
12
|
+
)
|
|
13
|
+
APPROX_BYTES_PER_TOKEN = 4
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def approx_token_count(text: 'str') -> 'int':
|
|
17
|
+
"""Estimate token count using the upstream Codex 4-bytes-per-token rule."""
|
|
18
|
+
if not text:
|
|
19
|
+
return 0
|
|
20
|
+
byte_length = len(text.encode("utf-8"))
|
|
21
|
+
return max(
|
|
22
|
+
1,
|
|
23
|
+
(byte_length + APPROX_BYTES_PER_TOKEN - 1) // APPROX_BYTES_PER_TOKEN,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def formatted_truncate_text(text: 'str', max_tokens: 'int') -> 'str':
|
|
28
|
+
"""Format a direct tool response with line count plus middle truncation."""
|
|
29
|
+
byte_budget = _approx_bytes_for_tokens(max_tokens)
|
|
30
|
+
if len(text.encode("utf-8")) <= byte_budget:
|
|
31
|
+
return text
|
|
32
|
+
|
|
33
|
+
total_lines = len(text.splitlines())
|
|
34
|
+
return f"Total output lines: {total_lines}\n\n{_truncate_text(text, max_tokens)}"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def truncate_tool_result_for_history(
|
|
38
|
+
result: 'ToolResult',
|
|
39
|
+
) -> 'ToolResult':
|
|
40
|
+
"""Truncate model-visible ToolResult content before storing it in history."""
|
|
41
|
+
if result.content_items is not None:
|
|
42
|
+
truncated_content_items = _truncate_content_items(
|
|
43
|
+
result.content_items,
|
|
44
|
+
HISTORY_TOOL_OUTPUT_TOKENS,
|
|
45
|
+
)
|
|
46
|
+
if truncated_content_items == result.content_items:
|
|
47
|
+
return result
|
|
48
|
+
return ToolResult(
|
|
49
|
+
call_id=result.call_id,
|
|
50
|
+
name=result.name,
|
|
51
|
+
output=result.output,
|
|
52
|
+
content_items=truncated_content_items,
|
|
53
|
+
success=result.success,
|
|
54
|
+
is_error=result.is_error,
|
|
55
|
+
tool_type=result.tool_type,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
output_text = _tool_output_text(result.output)
|
|
59
|
+
truncated_output = _truncate_text(output_text, HISTORY_TOOL_OUTPUT_TOKENS)
|
|
60
|
+
if truncated_output == output_text:
|
|
61
|
+
return result
|
|
62
|
+
return ToolResult(
|
|
63
|
+
call_id=result.call_id,
|
|
64
|
+
name=result.name,
|
|
65
|
+
output=truncated_output,
|
|
66
|
+
success=result.success,
|
|
67
|
+
is_error=result.is_error,
|
|
68
|
+
tool_type=result.tool_type,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def truncate_tool_results_for_history(
|
|
73
|
+
results: 'typing.Iterable[ToolResult]',
|
|
74
|
+
) -> 'typing.List[ToolResult]':
|
|
75
|
+
"""Apply history-layer truncation to a batch of completed tool results."""
|
|
76
|
+
return [
|
|
77
|
+
truncate_tool_result_for_history(result)
|
|
78
|
+
for result in results
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _tool_output_text(output: 'JSONValue') -> 'str':
|
|
83
|
+
if isinstance(output, str):
|
|
84
|
+
return output
|
|
85
|
+
|
|
86
|
+
import json
|
|
87
|
+
|
|
88
|
+
return json.dumps(
|
|
89
|
+
output,
|
|
90
|
+
ensure_ascii=False,
|
|
91
|
+
separators=(",", ":"),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _truncate_content_items(
|
|
96
|
+
content_items: 'typing.Tuple[typing.Dict[str, typing.Any], ...]',
|
|
97
|
+
token_limit: 'int',
|
|
98
|
+
) -> 'typing.Tuple[typing.Dict[str, typing.Any], ...]':
|
|
99
|
+
output: 'typing.List[typing.Dict[str, typing.Any]]' = []
|
|
100
|
+
remaining_budget = token_limit
|
|
101
|
+
omitted_text_items = 0
|
|
102
|
+
|
|
103
|
+
for item in content_items:
|
|
104
|
+
if item.get("type") != "input_text":
|
|
105
|
+
output.append(dict(item))
|
|
106
|
+
continue
|
|
107
|
+
|
|
108
|
+
text = str(item.get("text", ""))
|
|
109
|
+
if remaining_budget <= 0:
|
|
110
|
+
omitted_text_items += 1
|
|
111
|
+
continue
|
|
112
|
+
|
|
113
|
+
cost = approx_token_count(text)
|
|
114
|
+
if cost <= remaining_budget:
|
|
115
|
+
output.append(dict(item))
|
|
116
|
+
remaining_budget -= cost
|
|
117
|
+
continue
|
|
118
|
+
|
|
119
|
+
truncated_text = _truncate_text(text, remaining_budget)
|
|
120
|
+
if truncated_text:
|
|
121
|
+
next_item = dict(item)
|
|
122
|
+
next_item["text"] = truncated_text
|
|
123
|
+
output.append(next_item)
|
|
124
|
+
else:
|
|
125
|
+
omitted_text_items += 1
|
|
126
|
+
remaining_budget = 0
|
|
127
|
+
|
|
128
|
+
if omitted_text_items > 0:
|
|
129
|
+
output.append(
|
|
130
|
+
{
|
|
131
|
+
"type": "input_text",
|
|
132
|
+
"text": f"[omitted {omitted_text_items} text items ...]",
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
return tuple(output)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _approx_tokens_from_byte_count(byte_count: 'int') -> 'int':
|
|
139
|
+
if byte_count <= 0:
|
|
140
|
+
return 0
|
|
141
|
+
return (byte_count + APPROX_BYTES_PER_TOKEN - 1) // APPROX_BYTES_PER_TOKEN
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def _approx_bytes_for_tokens(token_count: 'int') -> 'int':
|
|
145
|
+
return max(token_count, 0) * APPROX_BYTES_PER_TOKEN
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def _split_budget(byte_budget: 'int') -> 'typing.Tuple[int, int]':
|
|
149
|
+
left_budget = byte_budget // 2
|
|
150
|
+
return left_budget, byte_budget - left_budget
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _split_string(
|
|
154
|
+
text: 'str',
|
|
155
|
+
beginning_bytes: 'int',
|
|
156
|
+
end_bytes: 'int',
|
|
157
|
+
) -> 'typing.Tuple[str, str]':
|
|
158
|
+
if not text:
|
|
159
|
+
return "", ""
|
|
160
|
+
|
|
161
|
+
total_bytes = len(text.encode("utf-8"))
|
|
162
|
+
tail_start_target = max(total_bytes - end_bytes, 0)
|
|
163
|
+
prefix_end = 0
|
|
164
|
+
suffix_start = len(text)
|
|
165
|
+
suffix_started = False
|
|
166
|
+
current_byte = 0
|
|
167
|
+
|
|
168
|
+
for index, char in enumerate(text):
|
|
169
|
+
char_bytes = len(char.encode("utf-8"))
|
|
170
|
+
char_start = current_byte
|
|
171
|
+
char_end = current_byte + char_bytes
|
|
172
|
+
if char_end <= beginning_bytes:
|
|
173
|
+
prefix_end = index + 1
|
|
174
|
+
current_byte = char_end
|
|
175
|
+
continue
|
|
176
|
+
if char_start >= tail_start_target:
|
|
177
|
+
if not suffix_started:
|
|
178
|
+
suffix_start = index
|
|
179
|
+
suffix_started = True
|
|
180
|
+
current_byte = char_end
|
|
181
|
+
continue
|
|
182
|
+
current_byte = char_end
|
|
183
|
+
|
|
184
|
+
if suffix_start < prefix_end:
|
|
185
|
+
suffix_start = prefix_end
|
|
186
|
+
|
|
187
|
+
return text[:prefix_end], text[suffix_start:]
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _truncate_text(text: 'str', max_tokens: 'int') -> 'str':
|
|
191
|
+
if not text:
|
|
192
|
+
return ""
|
|
193
|
+
|
|
194
|
+
max_bytes = _approx_bytes_for_tokens(max_tokens)
|
|
195
|
+
total_bytes = len(text.encode("utf-8"))
|
|
196
|
+
if total_bytes <= max_bytes:
|
|
197
|
+
return text
|
|
198
|
+
|
|
199
|
+
removed_tokens = _approx_tokens_from_byte_count(total_bytes - max_bytes)
|
|
200
|
+
marker = f"\u2026{removed_tokens} tokens truncated\u2026"
|
|
201
|
+
if max_bytes == 0:
|
|
202
|
+
return marker
|
|
203
|
+
|
|
204
|
+
left_budget, right_budget = _split_budget(max_bytes)
|
|
205
|
+
prefix, suffix = _split_string(text, left_budget, right_budget)
|
|
206
|
+
return f"{prefix}{marker}{suffix}"
|
pycodex/utils/visualize.py
CHANGED
|
@@ -17,6 +17,7 @@ import typing
|
|
|
17
17
|
STATUS_FRAMES = ("⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏")
|
|
18
18
|
PROMPT_CONTEXT_BASELINE_TOKENS = 12_000
|
|
19
19
|
DEFAULT_MAIN_PROMPT = "pycodex> "
|
|
20
|
+
IDLE_LISTENING_STATUS = "idle: listening"
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
def shorten_title(text: "str", limit: "int" = 48) -> "str":
|
|
@@ -235,8 +236,22 @@ class CliSessionView:
|
|
|
235
236
|
pending_prompt = self._pending_user_prompts.pop(submission_id, None)
|
|
236
237
|
if pending_prompt is not None:
|
|
237
238
|
self._history.append((pending_prompt, final_text))
|
|
238
|
-
self.
|
|
239
|
+
self._set_idle_status(event)
|
|
240
|
+
return
|
|
241
|
+
|
|
242
|
+
if event.kind == "stream_error":
|
|
243
|
+
self._stream_buffer = ""
|
|
244
|
+
message = str(event.payload.get("message", "")).strip() or "Reconnecting..."
|
|
245
|
+
self._print_line(
|
|
246
|
+
colorize_cli_message(
|
|
247
|
+
f"[status] {message}",
|
|
248
|
+
"status",
|
|
249
|
+
self._color_enabled,
|
|
250
|
+
)
|
|
251
|
+
)
|
|
252
|
+
self.prompter.set_status("reconnecting")
|
|
239
253
|
return
|
|
254
|
+
|
|
240
255
|
self.finish_stream()
|
|
241
256
|
|
|
242
257
|
if event.kind == "turn_started":
|
|
@@ -285,18 +300,6 @@ class CliSessionView:
|
|
|
285
300
|
# self.prompter.set_status("thinking")
|
|
286
301
|
return
|
|
287
302
|
|
|
288
|
-
if event.kind == "stream_error":
|
|
289
|
-
message = str(event.payload.get("message", "")).strip() or "Reconnecting..."
|
|
290
|
-
self._print_line(
|
|
291
|
-
colorize_cli_message(
|
|
292
|
-
f"[status] {message}",
|
|
293
|
-
"status",
|
|
294
|
-
self._color_enabled,
|
|
295
|
-
)
|
|
296
|
-
)
|
|
297
|
-
self.prompter.set_status("reconnecting")
|
|
298
|
-
return
|
|
299
|
-
|
|
300
303
|
if event.kind == "auto_compact_started":
|
|
301
304
|
total_tokens = event.payload.get("total_tokens")
|
|
302
305
|
token_limit = event.payload.get("token_limit")
|
|
@@ -377,7 +380,7 @@ class CliSessionView:
|
|
|
377
380
|
event.payload.get("submission_id", event.turn_id)
|
|
378
381
|
).strip()
|
|
379
382
|
self._pending_user_prompts.pop(submission_id, None)
|
|
380
|
-
self.
|
|
383
|
+
self._set_idle_status(event)
|
|
381
384
|
return
|
|
382
385
|
|
|
383
386
|
if event.kind == "turn_interrupted":
|
|
@@ -388,7 +391,7 @@ class CliSessionView:
|
|
|
388
391
|
pending_prompt = self._pending_user_prompts.pop(submission_id, None)
|
|
389
392
|
if pending_prompt is not None and final_text:
|
|
390
393
|
self._history.append((pending_prompt, final_text))
|
|
391
|
-
self.
|
|
394
|
+
self._set_idle_status(event)
|
|
392
395
|
return
|
|
393
396
|
|
|
394
397
|
def show_history(self) -> "None":
|
|
@@ -406,6 +409,15 @@ class CliSessionView:
|
|
|
406
409
|
self.finish_stream()
|
|
407
410
|
self._print_line(f"Session: {self._title or 'untitled'}")
|
|
408
411
|
|
|
412
|
+
def set_session_title(self, title: "str") -> "None":
|
|
413
|
+
self.finish_stream()
|
|
414
|
+
self._title = title or None
|
|
415
|
+
self._print_line(f"Session: {self._title or 'untitled'}")
|
|
416
|
+
|
|
417
|
+
def show_resumed_session(self, title: "str") -> "None":
|
|
418
|
+
self.write_line(f"Resumed session: {title}")
|
|
419
|
+
self.show_history()
|
|
420
|
+
|
|
409
421
|
def load_session_history(
|
|
410
422
|
self,
|
|
411
423
|
title: "typing.Union[str, None]",
|
|
@@ -454,6 +466,13 @@ class CliSessionView:
|
|
|
454
466
|
return prompt
|
|
455
467
|
return f"pyco({self._context_remaining_percent}%)> "
|
|
456
468
|
|
|
469
|
+
def _set_idle_status(self, event: "AgentEvent") -> "None":
|
|
470
|
+
background_work_count = event.payload.get("background_exec_count", 0)
|
|
471
|
+
if background_work_count > 0:
|
|
472
|
+
self.prompter.set_status(IDLE_LISTENING_STATUS)
|
|
473
|
+
else:
|
|
474
|
+
self.prompter.set_status(active=False)
|
|
475
|
+
|
|
457
476
|
def show_steer_queued(self, turn_id: "str", prompt: "str") -> "None":
|
|
458
477
|
preview = shorten_title(prompt, limit=72)
|
|
459
478
|
self._queued_steer_prompts.setdefault(turn_id, []).append(preview)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: python-codex
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
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
|
|
@@ -165,12 +165,15 @@ pycodex --put @127.0.0.1:5577
|
|
|
165
165
|
pycodex --put /data/.codex/@127.0.0.1:5577
|
|
166
166
|
pycodex --call SECRET-CALLID@127.0.0.1:5577 "Reply with exactly OK."
|
|
167
167
|
pycodex doctor
|
|
168
|
+
pycodex-ws --listen 0.0.0.0:6007 --board ./board.html
|
|
168
169
|
```
|
|
169
170
|
|
|
170
171
|
Current behavior:
|
|
171
172
|
|
|
172
173
|
- with no argv prompt and a TTY stdin, enter interactive mode
|
|
173
174
|
- with an argv prompt or piped stdin, run a single turn
|
|
175
|
+
- `pycodex-ws` starts the standalone browser workspace with a board pane and a
|
|
176
|
+
pycodex session pane
|
|
174
177
|
- interactive mode supports `/exit` and `/quit`
|
|
175
178
|
- interactive mode shows a compact event stream for user-visible phases such as
|
|
176
179
|
tool execution and model follow-up after tool results
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
pycodex/__init__.py,sha256=I1P7OHkabjHP7g32A31o-L9NMd3lKYJ2xhV8AHLPYXA,3196
|
|
2
|
+
pycodex/agent.py,sha256=HKzWVFRag_Le8LVR1qqfdfVzk23bRsXkykZV8Zq2hLE,21659
|
|
3
|
+
pycodex/cli.py,sha256=6URw4uSV-GPevu8NiqoraWIa180QmSUFOHScCZHO2Mc,20616
|
|
4
|
+
pycodex/collaboration.py,sha256=yQ6pBD-R3ZWR4_FAYQFoS7KF0m4LLD42otXIbPqw2ys,641
|
|
5
|
+
pycodex/compat.py,sha256=l35JE0vGAOCn9NWbWbqwGURGk83HXddXQ5wJIfcG41o,3254
|
|
6
|
+
pycodex/context.py,sha256=Hwh3vU-qSvaleUDdOWuWiGyNmbULVAZmboxiu9iiHt8,26549
|
|
7
|
+
pycodex/doctor.py,sha256=De3M4hRBJq8ZeqsUJgHz0vitqrH18YugrEnz7oHhTdQ,10572
|
|
8
|
+
pycodex/feishu_card.py,sha256=De6pM--3MfhgGo-WcWfhm-fop5UtzjwKrZ4gI2Lls3w,26198
|
|
9
|
+
pycodex/feishu_link.py,sha256=XGV93CIorcc03pNgBnXay9SkivnDL4i2GkLR5NjBjq0,15588
|
|
10
|
+
pycodex/interactive_session.py,sha256=VmQ4xLk5b9QrI4LvgrdyhXTvIk0K65loKxh2XbfV2FA,15617
|
|
11
|
+
pycodex/model.py,sha256=O5Gf35qCMAGrqvr_5d1ZQNk3vHmNRD5Uv-8k7-zbpXg,36679
|
|
12
|
+
pycodex/portable.py,sha256=gxl2E2h5uZJbasMEPPs-nyALFPIvX79T2ZYsu6vXZrg,15656
|
|
13
|
+
pycodex/portable_server.py,sha256=6I3pQkWj3e_SFlDXY2mGdCPns1w_3PSxByBV9wv5epI,7331
|
|
14
|
+
pycodex/protocol.py,sha256=4qiEcBQc3d3RZqsIKBjwORsHsQa78cqwvNljtnIuNbM,10795
|
|
15
|
+
pycodex/runtime.py,sha256=dXxLkcsjufBZ8F7o4QKFXF--mkgq3cpxhyUbPPaBYy4,8684
|
|
16
|
+
pycodex/runtime_services.py,sha256=6PQMI4MM8F9imijaVKBIz_0ADtoKDcdYs6vQ-c4frtQ,13931
|
|
17
|
+
pycodex/prompts/collaboration_default.md,sha256=MBTmPuMubeWfZgIeFVj49wwnwD4n_o3fVYAbgWKwu6Q,955
|
|
18
|
+
pycodex/prompts/collaboration_plan.md,sha256=IzjQAA5oHJz-3FmJdOjsJ4LHq6LW1tlEYMoy09n0HKk,8777
|
|
19
|
+
pycodex/prompts/default_base_instructions.md,sha256=D65mcj6bo4CDvVom-D9cbJRJVNquo0NghKt164_fRsg,20923
|
|
20
|
+
pycodex/prompts/models.json,sha256=D9AdqWpvxkhN6y4k3G6tJsjQFj99ATb4mjwGRcggWa8,349617
|
|
21
|
+
pycodex/prompts/permissions/approval_policy/never.md,sha256=QceTG6wjkaJARjYr0HYV1aPnPcpGcrkRUW-smWRr6MQ,120
|
|
22
|
+
pycodex/prompts/permissions/approval_policy/on_failure.md,sha256=dfJjpXkpO6_ANdCKxbVJ8o4vyLxevrJWfKsGHTqtbkc,289
|
|
23
|
+
pycodex/prompts/permissions/approval_policy/on_request.md,sha256=hVQalzh0FAdkKzw5u-N4H7-LtC9ijVDlYsh3OKsZKzo,3661
|
|
24
|
+
pycodex/prompts/permissions/approval_policy/on_request_rule_request_permission.md,sha256=mOinishp1k-wlPsaEuIOMn5GoVm_dAIsWIuEMmv2r7o,1725
|
|
25
|
+
pycodex/prompts/permissions/approval_policy/unless_trusted.md,sha256=XHpi1Lfx1iIXFbbQ_ho_kGstA3JN-RLho291HM30UNw,247
|
|
26
|
+
pycodex/prompts/permissions/sandbox_mode/danger_full_access.md,sha256=nZ7YHacBd3cAHKRZc9XClOOOnXJPXPh0WFBueh5C2D0,197
|
|
27
|
+
pycodex/prompts/permissions/sandbox_mode/read_only.md,sha256=2rAPEXsBYCcuttI5j3euS-3uv_v97catIsnhxlSQSIM,173
|
|
28
|
+
pycodex/prompts/permissions/sandbox_mode/workspace_write.md,sha256=lVN-LwrBbHqlv5yVjcd_mU8tzZW8jfKpTatJKIZu9HI,277
|
|
29
|
+
pycodex/tools/__init__.py,sha256=aSLXrr_31KGQgDfRow5zVIc-2-KdXlHaCE6qUnE4HWI,1772
|
|
30
|
+
pycodex/tools/agent_tool_schemas.py,sha256=8cL9ml4So0H6IIeK0ZzjAo9bk3VeprDOSYPpIamOqEU,2048
|
|
31
|
+
pycodex/tools/apply_patch_tool.py,sha256=wLHk5sl_UkR7iv0yqMJBMLHbGkZlMmCuX9a0yTevzps,13802
|
|
32
|
+
pycodex/tools/base_tool.py,sha256=0aQ69ygvSYKtDq1wHXr_j7EF3NtKIfmj0A9AbB-pD4Q,5431
|
|
33
|
+
pycodex/tools/close_agent_tool.py,sha256=79qr4ljPTvjnpH-Oe83yFTUGZdgNNnGoLZbpdqp4eOY,2031
|
|
34
|
+
pycodex/tools/code_mode_manager.py,sha256=T8RHM8tyJvHWwS6AD2g9hsaOmvApMmlWuSCRfmDVMDE,19053
|
|
35
|
+
pycodex/tools/exec_command_tool.py,sha256=KIt-pni7b2I41EMXGa1NW9YWJ1AoiWlPW_Ljlu7kLpk,4082
|
|
36
|
+
pycodex/tools/exec_runtime.js,sha256=DR1uocKailTqNWAcJNFJuQgFFMSUzTpT_uQsRaneg2s,3643
|
|
37
|
+
pycodex/tools/exec_tool.py,sha256=6uACLanhMxa5_5dZGO8CPztnM20O2ACANbaf9AUBS8M,2278
|
|
38
|
+
pycodex/tools/grep_files_tool.py,sha256=7M5xLQX6RJ_45korFmwBic97zDToiuojcmi1t9s-cko,5279
|
|
39
|
+
pycodex/tools/ipython_tool.py,sha256=7kn04RmR7GxSX3vDvFPhniEsChsoWl7_lVHyUCxouO4,4576
|
|
40
|
+
pycodex/tools/list_dir_tool.py,sha256=XMo1_hqDKX1004OfkyTcHz_8Shz9-4ikXd05z71U2gA,5283
|
|
41
|
+
pycodex/tools/read_file_tool.py,sha256=csClKG5Ldc38NKa2Enc3thBGxS8CU9lLAuMjmRKPgNw,9549
|
|
42
|
+
pycodex/tools/request_permissions_tool.py,sha256=Px0gvuYp5nPMCK-NotVmURRcwHG_0C0d44_s5tEaKPo,3787
|
|
43
|
+
pycodex/tools/request_user_input_tool.py,sha256=AF_EYdIrm-z8irHiJJzh7ubhEnDxaBdGtCprmvoh9m4,7201
|
|
44
|
+
pycodex/tools/resume_agent_tool.py,sha256=o62xdrsRxGFdRLxEhKEny-YEcaBOeqIneImrkME35II,1614
|
|
45
|
+
pycodex/tools/send_input_tool.py,sha256=vRg-f7LI2Sr01j1LeCPKeXto_ROQZ7bcUC5GIjx9NcI,3747
|
|
46
|
+
pycodex/tools/shell_command_tool.py,sha256=wUw4lw8VLGIQ-7BIgyEsI0oqjj-Yr-MZn-_VDrnimAw,4202
|
|
47
|
+
pycodex/tools/shell_tool.py,sha256=1m-Tcbn3His4ggyK5ec8Mkg6ihopqTvBd9F6fJlm6m4,4054
|
|
48
|
+
pycodex/tools/spawn_agent_tool.py,sha256=7Me4Frjz7_fTpjMMFCvNmDHPOK2G1qTfXUr2Ugs61bU,6194
|
|
49
|
+
pycodex/tools/unified_exec_manager.py,sha256=cKW_YNjSweVlGt8xNdeK_7gVwsGXxumCqjr-OlW5Xe0,12868
|
|
50
|
+
pycodex/tools/update_plan_tool.py,sha256=UsChtCBqI1RnVnPQbByPmD2LMZXMoCwfe6NpGqP8qu0,3174
|
|
51
|
+
pycodex/tools/view_image_tool.py,sha256=2Xu5Vx7djVpz7-IV-LKrDKJjvVJc9AND-MFXp3CWplg,3892
|
|
52
|
+
pycodex/tools/wait_agent_tool.py,sha256=0Uj9-IrXe2dSvOtOMq-RAc0XzaidwFH5q7Mri3BXWyM,3135
|
|
53
|
+
pycodex/tools/wait_tool.py,sha256=N6IrwzMp-fr1EohF-bxSwUlVs7KvZO2vV2csm3xCmS0,3205
|
|
54
|
+
pycodex/tools/web_search_tool.py,sha256=mhiK_G6VC6K6-01KctmIpsr-BURDF8L4ZJyY6IFGlNA,964
|
|
55
|
+
pycodex/tools/write_stdin_tool.py,sha256=K--XMp-AyEdp8yQ9EseYHsK3QrGrK4AgzOyvUk4swmw,3608
|
|
56
|
+
pycodex/utils/__init__.py,sha256=p3jaERPxkimNDhmMIsm4glvKiazf3UMv1X-qoH5Zl3U,963
|
|
57
|
+
pycodex/utils/async_bridge.py,sha256=d21Pjim-nsQbSG5pJddd0WaQ03CzA3w3TINWDmmjWbg,1815
|
|
58
|
+
pycodex/utils/compactor.py,sha256=zny3xhbc68FzpIlUJ1o0eEw0Cr9_rjBO_CyWDuoL74E,9013
|
|
59
|
+
pycodex/utils/debug.py,sha256=JeEB5JfzYfbdG0fXlrWFmXyR1ts86fKsI_97IqgF6R0,296
|
|
60
|
+
pycodex/utils/dotenv.py,sha256=rGKmurHjm7GdP4giyjHBPpSPv2Oi45qBqDB6HG3CnfA,1866
|
|
61
|
+
pycodex/utils/get_env.py,sha256=5fNhcNhujOakWV6AS66rGW3jEA68WGpuE4YVXJZFE6U,7427
|
|
62
|
+
pycodex/utils/random_ids.py,sha256=zBphjVGc7OXk9ZNExAbxRi_bk7ipyLG491qTv7hi8jM,380
|
|
63
|
+
pycodex/utils/session_persist.py,sha256=LnyKbQQ2SyONXhZ_XF_5pUUz_ZqhWsA7dOL5pCcKsCg,18491
|
|
64
|
+
pycodex/utils/toolcall_visualize.py,sha256=zIqmdsOfyYaLy_P4jpKnRxDsfTgYLRBx55R8m1P_lBE,24708
|
|
65
|
+
pycodex/utils/truncation.py,sha256=B_RvfXC2-M1oKz--eQIqDLqMD0g7_J-MSQd3WD6Rh08,6110
|
|
66
|
+
pycodex/utils/visualize.py,sha256=oTl1vqYW3nFBrdLcDyzwYfkNaPEW4OhVahJMHFSVkEg,20591
|
|
67
|
+
responses_server/__init__.py,sha256=3yPv_zeGT7P11tTnmj5kXktISLNsNW-02MUnnbiZcb0,394
|
|
68
|
+
responses_server/__main__.py,sha256=9SRp-Yw7ShGxc6DhSIXcDLKgGEdAVm3oBZ59rBOPjT0,62
|
|
69
|
+
responses_server/app.py,sha256=ack2a0otiBwq_DpsFURqLMlQzcf9oJPwo8o6iJ1fuig,7885
|
|
70
|
+
responses_server/config.py,sha256=leb3_uPrCyYdUIkyRyVPX4luGF88dQ62OkhRLPe7uxw,2718
|
|
71
|
+
responses_server/messages_api.py,sha256=WgO6J1jz2pOJkI79rLXp-pS1yxtLARcwX8T6JX5Vkcc,16971
|
|
72
|
+
responses_server/payload_processors.py,sha256=cbXGW8Xi-mliaWRg0_Af41X0vXV2W6R9VBzTE6DXfe4,3483
|
|
73
|
+
responses_server/server.py,sha256=Ko-Cqz_kW-uve091itucMklsPhEei77v-YcTjtjEdqU,2286
|
|
74
|
+
responses_server/session_store.py,sha256=ZD3cH2aEOkWaQsu5qTzcal2mThTSFQPAhAhPUN9srgI,1115
|
|
75
|
+
responses_server/stream_router.py,sha256=UiP-T4IKgJubD1L0AY93N3DqUh4K41fNcdONmC3Z-0A,37161
|
|
76
|
+
responses_server/trajectory_dump.py,sha256=XCwYaZZmlAxSsSXOfhk3zRvyfDpOHX5R8KzspScNFUM,3435
|
|
77
|
+
responses_server/tools/__init__.py,sha256=ivsBSEy0SBUhY-Uea5v1XMLXShkwHdCVl0id-1FwdZg,150
|
|
78
|
+
responses_server/tools/custom_adapter.py,sha256=LxO7ldydvR-GWachDz8GKC0Q8KGGFoFPbZxM0QvxuZ0,8350
|
|
79
|
+
responses_server/tools/web_search.py,sha256=pm4ZUiHUfxc0bGY1kEvt-BCzDrZIyP24xzPUcga2ul0,8908
|
|
80
|
+
workspace_server/__init__.py,sha256=XbSU6aAeYBMsBTVi9Ug6ZW9sxcwefqPS7T_7wpt_VMo,462
|
|
81
|
+
workspace_server/__main__.py,sha256=9SRp-Yw7ShGxc6DhSIXcDLKgGEdAVm3oBZ59rBOPjT0,62
|
|
82
|
+
workspace_server/app.py,sha256=aDfUqIwyMsndavSTP47rfcBKIwgo37F8U_lkCgUfUc0,49260
|
|
83
|
+
workspace_server/workspace.html,sha256=7d1eTxQ_4Hl-8YbMFHMTmRPpMRXE-a0KSJn1224JpXw,25563
|
|
84
|
+
python_codex-0.2.0.dist-info/METADATA,sha256=oCzNpTEbt1eODGxsJeHJE-gjTf53He7UDvcs-bovqAc,16812
|
|
85
|
+
python_codex-0.2.0.dist-info/WHEEL,sha256=KGYbc1zXlYddvwxnNty23BeaKzh7YuoSIvIMO4jEhvw,87
|
|
86
|
+
python_codex-0.2.0.dist-info/entry_points.txt,sha256=vkV2UWCtEKvQNMJuPNjt8HyBKiwp83JyqBatrBNGDp8,80
|
|
87
|
+
python_codex-0.2.0.dist-info/licenses/LICENSE,sha256=0X8ifk312hYAORM4hlzg8wVSEXYKNmiPgWlB1YIy2Nw,10926
|
|
88
|
+
python_codex-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from .app import (
|
|
2
|
+
ThreadedWorkspaceInteractiveSession,
|
|
3
|
+
WebSessionView,
|
|
4
|
+
WorkspaceInteractiveSession,
|
|
5
|
+
WorkspaceSessionManager,
|
|
6
|
+
build_parser,
|
|
7
|
+
create_app,
|
|
8
|
+
main,
|
|
9
|
+
parse_target,
|
|
10
|
+
run_serve_cli,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"ThreadedWorkspaceInteractiveSession",
|
|
15
|
+
"WebSessionView",
|
|
16
|
+
"WorkspaceInteractiveSession",
|
|
17
|
+
"WorkspaceSessionManager",
|
|
18
|
+
"build_parser",
|
|
19
|
+
"create_app",
|
|
20
|
+
"main",
|
|
21
|
+
"parse_target",
|
|
22
|
+
"run_serve_cli",
|
|
23
|
+
]
|