codex-autorunner 1.2.0__py3-none-any.whl → 1.3.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.
- codex_autorunner/bootstrap.py +26 -5
- codex_autorunner/core/about_car.py +12 -12
- codex_autorunner/core/config.py +178 -61
- codex_autorunner/core/context_awareness.py +1 -0
- codex_autorunner/core/filesystem.py +24 -0
- codex_autorunner/core/flows/controller.py +50 -12
- codex_autorunner/core/flows/runtime.py +8 -3
- codex_autorunner/core/hub.py +293 -16
- codex_autorunner/core/lifecycle_events.py +44 -5
- codex_autorunner/core/pma_context.py +188 -1
- codex_autorunner/core/pma_delivery.py +81 -0
- codex_autorunner/core/pma_dispatches.py +224 -0
- codex_autorunner/core/pma_lane_worker.py +122 -0
- codex_autorunner/core/pma_queue.py +167 -18
- codex_autorunner/core/pma_reactive.py +91 -0
- codex_autorunner/core/pma_safety.py +58 -0
- codex_autorunner/core/pma_sink.py +104 -0
- codex_autorunner/core/pma_transcripts.py +183 -0
- codex_autorunner/core/safe_paths.py +117 -0
- codex_autorunner/housekeeping.py +77 -23
- codex_autorunner/integrations/agents/codex_backend.py +18 -12
- codex_autorunner/integrations/agents/wiring.py +2 -0
- codex_autorunner/integrations/app_server/client.py +31 -0
- codex_autorunner/integrations/app_server/supervisor.py +3 -0
- codex_autorunner/integrations/telegram/adapter.py +1 -1
- codex_autorunner/integrations/telegram/config.py +1 -1
- codex_autorunner/integrations/telegram/constants.py +1 -1
- codex_autorunner/integrations/telegram/handlers/commands/execution.py +16 -15
- codex_autorunner/integrations/telegram/handlers/commands/files.py +5 -8
- codex_autorunner/integrations/telegram/handlers/commands/github.py +10 -6
- codex_autorunner/integrations/telegram/handlers/commands/shared.py +9 -8
- codex_autorunner/integrations/telegram/handlers/commands/workspace.py +85 -2
- codex_autorunner/integrations/telegram/handlers/commands_runtime.py +29 -8
- codex_autorunner/integrations/telegram/handlers/messages.py +8 -2
- codex_autorunner/integrations/telegram/helpers.py +30 -2
- codex_autorunner/integrations/telegram/ticket_flow_bridge.py +54 -3
- codex_autorunner/static/archive.js +274 -81
- codex_autorunner/static/archiveApi.js +21 -0
- codex_autorunner/static/constants.js +1 -1
- codex_autorunner/static/docChatCore.js +2 -0
- codex_autorunner/static/hub.js +59 -0
- codex_autorunner/static/index.html +70 -54
- codex_autorunner/static/notificationBell.js +173 -0
- codex_autorunner/static/notifications.js +187 -36
- codex_autorunner/static/pma.js +96 -35
- codex_autorunner/static/styles.css +431 -4
- codex_autorunner/static/terminalManager.js +22 -3
- codex_autorunner/static/utils.js +5 -1
- codex_autorunner/surfaces/cli/cli.py +206 -129
- codex_autorunner/surfaces/cli/template_repos.py +157 -0
- codex_autorunner/surfaces/web/app.py +193 -5
- codex_autorunner/surfaces/web/routes/archive.py +197 -0
- codex_autorunner/surfaces/web/routes/file_chat.py +115 -87
- codex_autorunner/surfaces/web/routes/flows.py +125 -67
- codex_autorunner/surfaces/web/routes/pma.py +638 -57
- codex_autorunner/surfaces/web/schemas.py +11 -0
- codex_autorunner/tickets/agent_pool.py +6 -1
- codex_autorunner/tickets/outbox.py +27 -14
- codex_autorunner/tickets/replies.py +4 -10
- codex_autorunner/tickets/runner.py +1 -0
- codex_autorunner/workspace/paths.py +8 -3
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.3.0.dist-info}/METADATA +1 -1
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.3.0.dist-info}/RECORD +67 -57
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.3.0.dist-info}/WHEEL +0 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.3.0.dist-info}/entry_points.txt +0 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.3.0.dist-info}/licenses/LICENSE +0 -0
- {codex_autorunner-1.2.0.dist-info → codex_autorunner-1.3.0.dist-info}/top_level.txt +0 -0
|
@@ -18,6 +18,7 @@ from ...manifest import load_manifest
|
|
|
18
18
|
from ...tickets import AgentPool
|
|
19
19
|
from .adapter import chunk_message
|
|
20
20
|
from .constants import TELEGRAM_MAX_MESSAGE_LENGTH
|
|
21
|
+
from .helpers import format_public_error
|
|
21
22
|
from .state import parse_topic_key
|
|
22
23
|
|
|
23
24
|
|
|
@@ -163,7 +164,7 @@ class TelegramTicketFlowBridge:
|
|
|
163
164
|
key, self._set_ticket_dispatch_marker(marker)
|
|
164
165
|
)
|
|
165
166
|
|
|
166
|
-
primary_key,
|
|
167
|
+
primary_key, primary_record = primary
|
|
167
168
|
try:
|
|
168
169
|
chat_id, thread_id, _scope = parse_topic_key(primary_key)
|
|
169
170
|
except Exception as exc:
|
|
@@ -182,6 +183,8 @@ class TelegramTicketFlowBridge:
|
|
|
182
183
|
seq=seq,
|
|
183
184
|
content=content,
|
|
184
185
|
archived_dir=archived_dir,
|
|
186
|
+
workspace_root=workspace_root,
|
|
187
|
+
repo_id=getattr(primary_record, "repo_id", None),
|
|
185
188
|
)
|
|
186
189
|
self._pause_targets[str(workspace_root)] = run_id
|
|
187
190
|
except Exception as exc:
|
|
@@ -296,9 +299,14 @@ class TelegramTicketFlowBridge:
|
|
|
296
299
|
def _format_ticket_flow_pause_reason(record: FlowRunRecord) -> str:
|
|
297
300
|
state = record.state or {}
|
|
298
301
|
engine = state.get("ticket_engine") or {}
|
|
299
|
-
|
|
302
|
+
reason_raw = (
|
|
300
303
|
engine.get("reason") or record.error_message or "Paused without details."
|
|
301
304
|
)
|
|
305
|
+
reason = (
|
|
306
|
+
format_public_error(str(reason_raw))
|
|
307
|
+
if reason_raw
|
|
308
|
+
else "Paused without details."
|
|
309
|
+
)
|
|
302
310
|
return f"Reason: {reason}"
|
|
303
311
|
|
|
304
312
|
def get_paused_ticket_flow(
|
|
@@ -373,6 +381,7 @@ class TelegramTicketFlowBridge:
|
|
|
373
381
|
seq=seq,
|
|
374
382
|
content=content,
|
|
375
383
|
archived_dir=archived_dir,
|
|
384
|
+
workspace_root=workspace_root,
|
|
376
385
|
)
|
|
377
386
|
self._last_default_notification[workspace_root] = marker
|
|
378
387
|
self._pause_targets[str(workspace_root)] = run_id
|
|
@@ -396,6 +405,8 @@ class TelegramTicketFlowBridge:
|
|
|
396
405
|
seq: str,
|
|
397
406
|
content: str,
|
|
398
407
|
archived_dir: Optional[Path],
|
|
408
|
+
workspace_root: Optional[Path],
|
|
409
|
+
repo_id: Optional[str] = None,
|
|
399
410
|
) -> None:
|
|
400
411
|
await self._send_dispatch_text(
|
|
401
412
|
chat_id,
|
|
@@ -403,6 +414,8 @@ class TelegramTicketFlowBridge:
|
|
|
403
414
|
run_id=run_id,
|
|
404
415
|
seq=seq,
|
|
405
416
|
content=content,
|
|
417
|
+
workspace_root=workspace_root,
|
|
418
|
+
repo_id=repo_id,
|
|
406
419
|
)
|
|
407
420
|
if self._pause_config.send_attachments and archived_dir:
|
|
408
421
|
await self._send_dispatch_attachments(
|
|
@@ -421,9 +434,15 @@ class TelegramTicketFlowBridge:
|
|
|
421
434
|
run_id: str,
|
|
422
435
|
seq: str,
|
|
423
436
|
content: str,
|
|
437
|
+
workspace_root: Optional[Path],
|
|
438
|
+
repo_id: Optional[str] = None,
|
|
424
439
|
) -> None:
|
|
425
440
|
body = content.strip() or "(no dispatch message)"
|
|
426
|
-
|
|
441
|
+
source = self._format_dispatch_source(workspace_root, repo_id)
|
|
442
|
+
header = (
|
|
443
|
+
f"Ticket flow paused (run {run_id}). Latest dispatch #{seq}:\n"
|
|
444
|
+
f"Source: {source}\n\n"
|
|
445
|
+
)
|
|
427
446
|
footer = "\n\nUse /flow resume to continue."
|
|
428
447
|
full_text = f"{header}{body}{footer}"
|
|
429
448
|
|
|
@@ -446,6 +465,38 @@ class TelegramTicketFlowBridge:
|
|
|
446
465
|
if idx == 0:
|
|
447
466
|
await asyncio.sleep(0)
|
|
448
467
|
|
|
468
|
+
def _format_dispatch_source(
|
|
469
|
+
self, workspace_root: Optional[Path], repo_id: Optional[str]
|
|
470
|
+
) -> str:
|
|
471
|
+
workspace_label = None
|
|
472
|
+
if isinstance(workspace_root, Path):
|
|
473
|
+
workspace_label = str(workspace_root)
|
|
474
|
+
repo_label = repo_id.strip() if isinstance(repo_id, str) else ""
|
|
475
|
+
if self._hub_root and self._manifest_path and self._manifest_path.exists():
|
|
476
|
+
try:
|
|
477
|
+
manifest = load_manifest(self._manifest_path, self._hub_root)
|
|
478
|
+
if workspace_root:
|
|
479
|
+
entry = manifest.get_by_path(self._hub_root, workspace_root)
|
|
480
|
+
else:
|
|
481
|
+
entry = None
|
|
482
|
+
if entry:
|
|
483
|
+
repo_label = entry.id or repo_label
|
|
484
|
+
if entry.display_name and entry.display_name != repo_label:
|
|
485
|
+
repo_label = f"{repo_label} ({entry.display_name})"
|
|
486
|
+
if entry.kind == "worktree" and entry.worktree_of:
|
|
487
|
+
repo_label = f"{repo_label} [worktree of {entry.worktree_of}]"
|
|
488
|
+
except Exception as exc:
|
|
489
|
+
self._logger.debug(
|
|
490
|
+
"telegram.ticket_flow.manifest_label_failed", exc_info=exc
|
|
491
|
+
)
|
|
492
|
+
if repo_label and workspace_label:
|
|
493
|
+
return f"{repo_label} @ {workspace_label}"
|
|
494
|
+
if repo_label:
|
|
495
|
+
return repo_label
|
|
496
|
+
if workspace_label:
|
|
497
|
+
return workspace_label
|
|
498
|
+
return "unknown workspace"
|
|
499
|
+
|
|
449
500
|
async def _send_dispatch_attachments(
|
|
450
501
|
self,
|
|
451
502
|
chat_id: int,
|