codex-autorunner 1.0.0__py3-none-any.whl → 1.1.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.
Files changed (170) hide show
  1. codex_autorunner/__init__.py +12 -1
  2. codex_autorunner/agents/codex/harness.py +1 -1
  3. codex_autorunner/agents/opencode/constants.py +3 -0
  4. codex_autorunner/agents/opencode/harness.py +6 -1
  5. codex_autorunner/agents/opencode/runtime.py +59 -18
  6. codex_autorunner/agents/registry.py +22 -3
  7. codex_autorunner/bootstrap.py +7 -3
  8. codex_autorunner/cli.py +5 -1174
  9. codex_autorunner/codex_cli.py +20 -84
  10. codex_autorunner/core/__init__.py +4 -0
  11. codex_autorunner/core/about_car.py +6 -1
  12. codex_autorunner/core/app_server_ids.py +59 -0
  13. codex_autorunner/core/app_server_threads.py +11 -2
  14. codex_autorunner/core/app_server_utils.py +165 -0
  15. codex_autorunner/core/archive.py +349 -0
  16. codex_autorunner/core/codex_runner.py +6 -2
  17. codex_autorunner/core/config.py +197 -3
  18. codex_autorunner/core/drafts.py +58 -4
  19. codex_autorunner/core/engine.py +1329 -680
  20. codex_autorunner/core/exceptions.py +4 -0
  21. codex_autorunner/core/flows/controller.py +25 -1
  22. codex_autorunner/core/flows/models.py +13 -0
  23. codex_autorunner/core/flows/reasons.py +52 -0
  24. codex_autorunner/core/flows/reconciler.py +131 -0
  25. codex_autorunner/core/flows/runtime.py +35 -4
  26. codex_autorunner/core/flows/store.py +83 -0
  27. codex_autorunner/core/flows/transition.py +5 -0
  28. codex_autorunner/core/flows/ux_helpers.py +257 -0
  29. codex_autorunner/core/git_utils.py +62 -0
  30. codex_autorunner/core/hub.py +121 -7
  31. codex_autorunner/core/notifications.py +14 -2
  32. codex_autorunner/core/ports/__init__.py +28 -0
  33. codex_autorunner/{integrations/agents → core/ports}/agent_backend.py +11 -3
  34. codex_autorunner/core/ports/backend_orchestrator.py +41 -0
  35. codex_autorunner/{integrations/agents → core/ports}/run_event.py +22 -2
  36. codex_autorunner/core/state_roots.py +57 -0
  37. codex_autorunner/core/supervisor_protocol.py +15 -0
  38. codex_autorunner/core/text_delta_coalescer.py +54 -0
  39. codex_autorunner/core/ticket_linter_cli.py +201 -0
  40. codex_autorunner/core/ticket_manager_cli.py +432 -0
  41. codex_autorunner/core/update.py +4 -5
  42. codex_autorunner/core/update_paths.py +28 -0
  43. codex_autorunner/core/usage.py +164 -12
  44. codex_autorunner/core/utils.py +91 -9
  45. codex_autorunner/flows/review/__init__.py +17 -0
  46. codex_autorunner/{core/review.py → flows/review/service.py} +15 -10
  47. codex_autorunner/flows/ticket_flow/definition.py +9 -2
  48. codex_autorunner/integrations/agents/__init__.py +9 -19
  49. codex_autorunner/integrations/agents/backend_orchestrator.py +284 -0
  50. codex_autorunner/integrations/agents/codex_adapter.py +90 -0
  51. codex_autorunner/integrations/agents/codex_backend.py +158 -17
  52. codex_autorunner/integrations/agents/opencode_adapter.py +108 -0
  53. codex_autorunner/integrations/agents/opencode_backend.py +305 -32
  54. codex_autorunner/integrations/agents/runner.py +91 -0
  55. codex_autorunner/integrations/agents/wiring.py +271 -0
  56. codex_autorunner/integrations/app_server/client.py +7 -60
  57. codex_autorunner/integrations/app_server/env.py +2 -107
  58. codex_autorunner/{core/app_server_events.py → integrations/app_server/event_buffer.py} +15 -8
  59. codex_autorunner/integrations/telegram/adapter.py +65 -0
  60. codex_autorunner/integrations/telegram/config.py +46 -0
  61. codex_autorunner/integrations/telegram/constants.py +1 -1
  62. codex_autorunner/integrations/telegram/handlers/callbacks.py +7 -0
  63. codex_autorunner/integrations/telegram/handlers/commands/flows.py +1203 -66
  64. codex_autorunner/integrations/telegram/handlers/commands_runtime.py +4 -3
  65. codex_autorunner/integrations/telegram/handlers/commands_spec.py +8 -2
  66. codex_autorunner/integrations/telegram/handlers/messages.py +1 -0
  67. codex_autorunner/integrations/telegram/handlers/selections.py +61 -1
  68. codex_autorunner/integrations/telegram/helpers.py +24 -1
  69. codex_autorunner/integrations/telegram/service.py +15 -10
  70. codex_autorunner/integrations/telegram/ticket_flow_bridge.py +329 -40
  71. codex_autorunner/integrations/telegram/transport.py +3 -1
  72. codex_autorunner/routes/__init__.py +37 -76
  73. codex_autorunner/routes/agents.py +2 -137
  74. codex_autorunner/routes/analytics.py +2 -238
  75. codex_autorunner/routes/app_server.py +2 -131
  76. codex_autorunner/routes/base.py +2 -596
  77. codex_autorunner/routes/file_chat.py +4 -833
  78. codex_autorunner/routes/flows.py +4 -977
  79. codex_autorunner/routes/messages.py +4 -456
  80. codex_autorunner/routes/repos.py +2 -196
  81. codex_autorunner/routes/review.py +2 -147
  82. codex_autorunner/routes/sessions.py +2 -175
  83. codex_autorunner/routes/settings.py +2 -168
  84. codex_autorunner/routes/shared.py +2 -275
  85. codex_autorunner/routes/system.py +4 -193
  86. codex_autorunner/routes/usage.py +2 -86
  87. codex_autorunner/routes/voice.py +2 -119
  88. codex_autorunner/routes/workspace.py +2 -270
  89. codex_autorunner/server.py +2 -2
  90. codex_autorunner/static/agentControls.js +40 -11
  91. codex_autorunner/static/app.js +11 -3
  92. codex_autorunner/static/archive.js +826 -0
  93. codex_autorunner/static/archiveApi.js +37 -0
  94. codex_autorunner/static/autoRefresh.js +7 -7
  95. codex_autorunner/static/dashboard.js +224 -171
  96. codex_autorunner/static/hub.js +112 -94
  97. codex_autorunner/static/index.html +80 -33
  98. codex_autorunner/static/messages.js +486 -83
  99. codex_autorunner/static/preserve.js +17 -0
  100. codex_autorunner/static/settings.js +125 -6
  101. codex_autorunner/static/smartRefresh.js +52 -0
  102. codex_autorunner/static/styles.css +1373 -101
  103. codex_autorunner/static/tabs.js +152 -11
  104. codex_autorunner/static/terminal.js +18 -0
  105. codex_autorunner/static/ticketEditor.js +99 -5
  106. codex_autorunner/static/tickets.js +760 -87
  107. codex_autorunner/static/utils.js +11 -0
  108. codex_autorunner/static/workspace.js +133 -40
  109. codex_autorunner/static/workspaceFileBrowser.js +9 -9
  110. codex_autorunner/surfaces/__init__.py +5 -0
  111. codex_autorunner/surfaces/cli/__init__.py +6 -0
  112. codex_autorunner/surfaces/cli/cli.py +1224 -0
  113. codex_autorunner/surfaces/cli/codex_cli.py +20 -0
  114. codex_autorunner/surfaces/telegram/__init__.py +3 -0
  115. codex_autorunner/surfaces/web/__init__.py +1 -0
  116. codex_autorunner/surfaces/web/app.py +2019 -0
  117. codex_autorunner/surfaces/web/hub_jobs.py +192 -0
  118. codex_autorunner/surfaces/web/middleware.py +587 -0
  119. codex_autorunner/surfaces/web/pty_session.py +370 -0
  120. codex_autorunner/surfaces/web/review.py +6 -0
  121. codex_autorunner/surfaces/web/routes/__init__.py +78 -0
  122. codex_autorunner/surfaces/web/routes/agents.py +138 -0
  123. codex_autorunner/surfaces/web/routes/analytics.py +277 -0
  124. codex_autorunner/surfaces/web/routes/app_server.py +132 -0
  125. codex_autorunner/surfaces/web/routes/archive.py +357 -0
  126. codex_autorunner/surfaces/web/routes/base.py +615 -0
  127. codex_autorunner/surfaces/web/routes/file_chat.py +836 -0
  128. codex_autorunner/surfaces/web/routes/flows.py +1164 -0
  129. codex_autorunner/surfaces/web/routes/messages.py +459 -0
  130. codex_autorunner/surfaces/web/routes/repos.py +197 -0
  131. codex_autorunner/surfaces/web/routes/review.py +148 -0
  132. codex_autorunner/surfaces/web/routes/sessions.py +176 -0
  133. codex_autorunner/surfaces/web/routes/settings.py +169 -0
  134. codex_autorunner/surfaces/web/routes/shared.py +280 -0
  135. codex_autorunner/surfaces/web/routes/system.py +196 -0
  136. codex_autorunner/surfaces/web/routes/usage.py +89 -0
  137. codex_autorunner/surfaces/web/routes/voice.py +120 -0
  138. codex_autorunner/surfaces/web/routes/workspace.py +271 -0
  139. codex_autorunner/surfaces/web/runner_manager.py +25 -0
  140. codex_autorunner/surfaces/web/schemas.py +417 -0
  141. codex_autorunner/surfaces/web/static_assets.py +490 -0
  142. codex_autorunner/surfaces/web/static_refresh.py +86 -0
  143. codex_autorunner/surfaces/web/terminal_sessions.py +78 -0
  144. codex_autorunner/tickets/__init__.py +8 -1
  145. codex_autorunner/tickets/agent_pool.py +26 -4
  146. codex_autorunner/tickets/files.py +6 -2
  147. codex_autorunner/tickets/models.py +3 -1
  148. codex_autorunner/tickets/outbox.py +12 -0
  149. codex_autorunner/tickets/runner.py +63 -5
  150. codex_autorunner/web/__init__.py +5 -1
  151. codex_autorunner/web/app.py +2 -1949
  152. codex_autorunner/web/hub_jobs.py +2 -191
  153. codex_autorunner/web/middleware.py +2 -586
  154. codex_autorunner/web/pty_session.py +2 -369
  155. codex_autorunner/web/runner_manager.py +2 -24
  156. codex_autorunner/web/schemas.py +2 -376
  157. codex_autorunner/web/static_assets.py +4 -441
  158. codex_autorunner/web/static_refresh.py +2 -85
  159. codex_autorunner/web/terminal_sessions.py +2 -77
  160. codex_autorunner/workspace/paths.py +49 -33
  161. codex_autorunner-1.1.0.dist-info/METADATA +154 -0
  162. codex_autorunner-1.1.0.dist-info/RECORD +308 -0
  163. codex_autorunner/core/static_assets.py +0 -55
  164. codex_autorunner-1.0.0.dist-info/METADATA +0 -246
  165. codex_autorunner-1.0.0.dist-info/RECORD +0 -251
  166. /codex_autorunner/{routes → surfaces/web/routes}/terminal_images.py +0 -0
  167. {codex_autorunner-1.0.0.dist-info → codex_autorunner-1.1.0.dist-info}/WHEEL +0 -0
  168. {codex_autorunner-1.0.0.dist-info → codex_autorunner-1.1.0.dist-info}/entry_points.txt +0 -0
  169. {codex_autorunner-1.0.0.dist-info → codex_autorunner-1.1.0.dist-info}/licenses/LICENSE +0 -0
  170. {codex_autorunner-1.0.0.dist-info → codex_autorunner-1.1.0.dist-info}/top_level.txt +0 -0
@@ -62,6 +62,7 @@ DEFAULT_MESSAGE_OVERFLOW = "document"
62
62
  MESSAGE_OVERFLOW_OPTIONS = {"document", "split", "trim"}
63
63
  DEFAULT_METRICS_MODE = "separate"
64
64
  METRICS_MODE_OPTIONS = {"separate", "append_to_response", "append_to_progress"}
65
+ DEFAULT_PAUSE_DISPATCH_MAX_FILE_BYTES = 50 * 1024 * 1024
65
66
 
66
67
  PARSE_MODE_ALIASES = {
67
68
  "html": "HTML",
@@ -160,6 +161,14 @@ class TelegramBotProgressStreamConfig:
160
161
  min_edit_interval_seconds: float
161
162
 
162
163
 
164
+ @dataclass(frozen=True)
165
+ class PauseDispatchNotifications:
166
+ enabled: bool
167
+ send_attachments: bool
168
+ max_file_size_bytes: int
169
+ chunk_long_messages: bool
170
+
171
+
163
172
  @dataclass(frozen=True)
164
173
  class TelegramMediaCandidate:
165
174
  kind: str
@@ -209,6 +218,8 @@ class TelegramBotConfig:
209
218
  coalesce_window_seconds: float
210
219
  agent_binaries: dict[str, str]
211
220
  ticket_flow_auto_resume: bool
221
+ pause_dispatch_notifications: PauseDispatchNotifications
222
+ default_notification_chat_id: Optional[int]
212
223
 
213
224
  @classmethod
214
225
  def from_raw(
@@ -506,6 +517,39 @@ class TelegramBotConfig:
506
517
  )
507
518
  ticket_flow_auto_resume = bool(ticket_flow_raw.get("auto_resume", False))
508
519
 
520
+ pause_raw_value = cfg.get("pause_dispatch_notifications")
521
+ pause_raw: dict[str, Any] = (
522
+ pause_raw_value if isinstance(pause_raw_value, dict) else {}
523
+ )
524
+ pause_enabled = bool(pause_raw.get("enabled", enabled))
525
+ pause_send_attachments = bool(pause_raw.get("send_attachments", True))
526
+ pause_max_file_size_bytes = int(
527
+ pause_raw.get("max_file_size_bytes", DEFAULT_PAUSE_DISPATCH_MAX_FILE_BYTES)
528
+ )
529
+ if pause_max_file_size_bytes <= 0:
530
+ pause_max_file_size_bytes = DEFAULT_PAUSE_DISPATCH_MAX_FILE_BYTES
531
+ pause_chunk_long_messages = bool(pause_raw.get("chunk_long_messages", True))
532
+ pause_dispatch_notifications = PauseDispatchNotifications(
533
+ enabled=pause_enabled,
534
+ send_attachments=pause_send_attachments,
535
+ max_file_size_bytes=pause_max_file_size_bytes,
536
+ chunk_long_messages=pause_chunk_long_messages,
537
+ )
538
+
539
+ default_notification_chat_raw = cfg.get("default_notification_chat_id")
540
+ default_notification_chat_id: Optional[int] = None
541
+ env_chat_candidates = _parse_int_list(env.get(chat_id_env))
542
+ if default_notification_chat_raw is not None:
543
+ try:
544
+ default_notification_chat_id = int(default_notification_chat_raw)
545
+ except (TypeError, ValueError):
546
+ default_notification_chat_id = None
547
+ if default_notification_chat_id is None:
548
+ if env_chat_candidates:
549
+ default_notification_chat_id = env_chat_candidates[0]
550
+ elif allowed_chat_ids:
551
+ default_notification_chat_id = min(allowed_chat_ids)
552
+
509
553
  agent_binaries = dict(agent_binaries or {})
510
554
  command_reg_raw_value = cfg.get("command_registration")
511
555
  command_reg_raw: dict[str, Any] = (
@@ -666,6 +710,8 @@ class TelegramBotConfig:
666
710
  coalesce_window_seconds=coalesce_window_seconds,
667
711
  agent_binaries=agent_binaries,
668
712
  ticket_flow_auto_resume=ticket_flow_auto_resume,
713
+ pause_dispatch_notifications=pause_dispatch_notifications,
714
+ default_notification_chat_id=default_notification_chat_id,
669
715
  )
670
716
 
671
717
  def validate(self) -> None:
@@ -24,7 +24,6 @@ DEFAULT_AGENT_TURN_TIMEOUT_SECONDS = {
24
24
  "codex": 28800.0,
25
25
  "opencode": 28800.0,
26
26
  }
27
- DEFAULT_WORKSPACE_STATE_ROOT = "~/.codex-autorunner/workspaces"
28
27
  DEFAULT_AGENT = "codex"
29
28
  APP_SERVER_START_BACKOFF_INITIAL_SECONDS = 1.0
30
29
  APP_SERVER_START_BACKOFF_MAX_SECONDS = 30.0
@@ -66,6 +65,7 @@ UPDATE_PICKER_PROMPT = "Select update target (buttons below)."
66
65
  REVIEW_COMMIT_PICKER_PROMPT = (
67
66
  "Select a commit to review (buttons below or reply with number)."
68
67
  )
68
+ FLOW_RUNS_PICKER_PROMPT = "Select a ticket flow run (buttons below)."
69
69
  REVIEW_COMMIT_BUTTON_LABEL_LIMIT = 80
70
70
  UPDATE_TARGET_OPTIONS = (
71
71
  ("both", "Both (web + Telegram)"),
@@ -9,6 +9,8 @@ from ..adapter import (
9
9
  CancelCallback,
10
10
  CompactCallback,
11
11
  EffortCallback,
12
+ FlowCallback,
13
+ FlowRunCallback,
12
14
  ModelCallback,
13
15
  PageCallback,
14
16
  QuestionCancelCallback,
@@ -91,3 +93,8 @@ async def handle_callback(handlers: Any, callback: TelegramCallbackQuery) -> Non
91
93
  elif isinstance(parsed, PageCallback):
92
94
  if key:
93
95
  await handlers._handle_selection_page(key, parsed, callback)
96
+ elif isinstance(parsed, FlowCallback):
97
+ await handlers._handle_flow_callback(callback, parsed)
98
+ elif isinstance(parsed, FlowRunCallback):
99
+ if key:
100
+ await handlers._handle_flow_run_callback(key, callback, parsed)