codex-autorunner 0.1.2__py3-none-any.whl → 1.0.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 (189) hide show
  1. codex_autorunner/__main__.py +4 -0
  2. codex_autorunner/agents/opencode/client.py +68 -35
  3. codex_autorunner/agents/opencode/logging.py +21 -5
  4. codex_autorunner/agents/opencode/run_prompt.py +1 -0
  5. codex_autorunner/agents/opencode/runtime.py +118 -30
  6. codex_autorunner/agents/opencode/supervisor.py +36 -48
  7. codex_autorunner/agents/registry.py +136 -8
  8. codex_autorunner/api.py +25 -0
  9. codex_autorunner/bootstrap.py +16 -35
  10. codex_autorunner/cli.py +157 -139
  11. codex_autorunner/core/about_car.py +44 -32
  12. codex_autorunner/core/adapter_utils.py +21 -0
  13. codex_autorunner/core/app_server_logging.py +7 -3
  14. codex_autorunner/core/app_server_prompts.py +27 -260
  15. codex_autorunner/core/app_server_threads.py +15 -26
  16. codex_autorunner/core/codex_runner.py +6 -0
  17. codex_autorunner/core/config.py +390 -100
  18. codex_autorunner/core/docs.py +10 -2
  19. codex_autorunner/core/drafts.py +82 -0
  20. codex_autorunner/core/engine.py +278 -262
  21. codex_autorunner/core/flows/__init__.py +25 -0
  22. codex_autorunner/core/flows/controller.py +178 -0
  23. codex_autorunner/core/flows/definition.py +82 -0
  24. codex_autorunner/core/flows/models.py +75 -0
  25. codex_autorunner/core/flows/runtime.py +351 -0
  26. codex_autorunner/core/flows/store.py +485 -0
  27. codex_autorunner/core/flows/transition.py +133 -0
  28. codex_autorunner/core/flows/worker_process.py +242 -0
  29. codex_autorunner/core/hub.py +15 -9
  30. codex_autorunner/core/locks.py +4 -0
  31. codex_autorunner/core/prompt.py +15 -7
  32. codex_autorunner/core/redaction.py +29 -0
  33. codex_autorunner/core/review_context.py +5 -8
  34. codex_autorunner/core/run_index.py +6 -0
  35. codex_autorunner/core/runner_process.py +5 -2
  36. codex_autorunner/core/state.py +0 -88
  37. codex_autorunner/core/static_assets.py +55 -0
  38. codex_autorunner/core/supervisor_utils.py +67 -0
  39. codex_autorunner/core/update.py +20 -11
  40. codex_autorunner/core/update_runner.py +2 -0
  41. codex_autorunner/core/utils.py +29 -2
  42. codex_autorunner/discovery.py +2 -4
  43. codex_autorunner/flows/ticket_flow/__init__.py +3 -0
  44. codex_autorunner/flows/ticket_flow/definition.py +91 -0
  45. codex_autorunner/integrations/agents/__init__.py +27 -0
  46. codex_autorunner/integrations/agents/agent_backend.py +142 -0
  47. codex_autorunner/integrations/agents/codex_backend.py +307 -0
  48. codex_autorunner/integrations/agents/opencode_backend.py +325 -0
  49. codex_autorunner/integrations/agents/run_event.py +71 -0
  50. codex_autorunner/integrations/app_server/client.py +576 -92
  51. codex_autorunner/integrations/app_server/supervisor.py +59 -33
  52. codex_autorunner/integrations/telegram/adapter.py +141 -167
  53. codex_autorunner/integrations/telegram/api_schemas.py +120 -0
  54. codex_autorunner/integrations/telegram/config.py +175 -0
  55. codex_autorunner/integrations/telegram/constants.py +16 -1
  56. codex_autorunner/integrations/telegram/dispatch.py +17 -0
  57. codex_autorunner/integrations/telegram/doctor.py +47 -0
  58. codex_autorunner/integrations/telegram/handlers/callbacks.py +0 -4
  59. codex_autorunner/integrations/telegram/handlers/commands/__init__.py +2 -0
  60. codex_autorunner/integrations/telegram/handlers/commands/execution.py +53 -57
  61. codex_autorunner/integrations/telegram/handlers/commands/files.py +2 -6
  62. codex_autorunner/integrations/telegram/handlers/commands/flows.py +227 -0
  63. codex_autorunner/integrations/telegram/handlers/commands/formatting.py +1 -1
  64. codex_autorunner/integrations/telegram/handlers/commands/github.py +41 -582
  65. codex_autorunner/integrations/telegram/handlers/commands/workspace.py +8 -8
  66. codex_autorunner/integrations/telegram/handlers/commands_runtime.py +133 -475
  67. codex_autorunner/integrations/telegram/handlers/commands_spec.py +11 -4
  68. codex_autorunner/integrations/telegram/handlers/messages.py +120 -9
  69. codex_autorunner/integrations/telegram/helpers.py +88 -16
  70. codex_autorunner/integrations/telegram/outbox.py +208 -37
  71. codex_autorunner/integrations/telegram/progress_stream.py +3 -10
  72. codex_autorunner/integrations/telegram/service.py +214 -40
  73. codex_autorunner/integrations/telegram/state.py +100 -2
  74. codex_autorunner/integrations/telegram/ticket_flow_bridge.py +322 -0
  75. codex_autorunner/integrations/telegram/transport.py +36 -3
  76. codex_autorunner/integrations/telegram/trigger_mode.py +53 -0
  77. codex_autorunner/manifest.py +2 -0
  78. codex_autorunner/plugin_api.py +22 -0
  79. codex_autorunner/routes/__init__.py +23 -14
  80. codex_autorunner/routes/analytics.py +239 -0
  81. codex_autorunner/routes/base.py +81 -109
  82. codex_autorunner/routes/file_chat.py +836 -0
  83. codex_autorunner/routes/flows.py +980 -0
  84. codex_autorunner/routes/messages.py +459 -0
  85. codex_autorunner/routes/system.py +6 -1
  86. codex_autorunner/routes/usage.py +87 -0
  87. codex_autorunner/routes/workspace.py +271 -0
  88. codex_autorunner/server.py +2 -1
  89. codex_autorunner/static/agentControls.js +1 -0
  90. codex_autorunner/static/agentEvents.js +248 -0
  91. codex_autorunner/static/app.js +25 -22
  92. codex_autorunner/static/autoRefresh.js +29 -1
  93. codex_autorunner/static/bootstrap.js +1 -0
  94. codex_autorunner/static/bus.js +1 -0
  95. codex_autorunner/static/cache.js +1 -0
  96. codex_autorunner/static/constants.js +20 -4
  97. codex_autorunner/static/dashboard.js +162 -196
  98. codex_autorunner/static/diffRenderer.js +37 -0
  99. codex_autorunner/static/docChatCore.js +324 -0
  100. codex_autorunner/static/docChatStorage.js +65 -0
  101. codex_autorunner/static/docChatVoice.js +65 -0
  102. codex_autorunner/static/docEditor.js +133 -0
  103. codex_autorunner/static/env.js +1 -0
  104. codex_autorunner/static/eventSummarizer.js +166 -0
  105. codex_autorunner/static/fileChat.js +182 -0
  106. codex_autorunner/static/health.js +155 -0
  107. codex_autorunner/static/hub.js +41 -118
  108. codex_autorunner/static/index.html +787 -858
  109. codex_autorunner/static/liveUpdates.js +1 -0
  110. codex_autorunner/static/loader.js +1 -0
  111. codex_autorunner/static/messages.js +470 -0
  112. codex_autorunner/static/mobileCompact.js +2 -1
  113. codex_autorunner/static/settings.js +24 -211
  114. codex_autorunner/static/styles.css +7567 -3865
  115. codex_autorunner/static/tabs.js +28 -5
  116. codex_autorunner/static/terminal.js +14 -0
  117. codex_autorunner/static/terminalManager.js +34 -59
  118. codex_autorunner/static/ticketChatActions.js +333 -0
  119. codex_autorunner/static/ticketChatEvents.js +16 -0
  120. codex_autorunner/static/ticketChatStorage.js +16 -0
  121. codex_autorunner/static/ticketChatStream.js +264 -0
  122. codex_autorunner/static/ticketEditor.js +750 -0
  123. codex_autorunner/static/ticketVoice.js +9 -0
  124. codex_autorunner/static/tickets.js +1315 -0
  125. codex_autorunner/static/utils.js +32 -3
  126. codex_autorunner/static/voice.js +1 -0
  127. codex_autorunner/static/workspace.js +672 -0
  128. codex_autorunner/static/workspaceApi.js +53 -0
  129. codex_autorunner/static/workspaceFileBrowser.js +504 -0
  130. codex_autorunner/tickets/__init__.py +20 -0
  131. codex_autorunner/tickets/agent_pool.py +377 -0
  132. codex_autorunner/tickets/files.py +85 -0
  133. codex_autorunner/tickets/frontmatter.py +55 -0
  134. codex_autorunner/tickets/lint.py +102 -0
  135. codex_autorunner/tickets/models.py +95 -0
  136. codex_autorunner/tickets/outbox.py +232 -0
  137. codex_autorunner/tickets/replies.py +179 -0
  138. codex_autorunner/tickets/runner.py +823 -0
  139. codex_autorunner/tickets/spec_ingest.py +77 -0
  140. codex_autorunner/web/app.py +269 -91
  141. codex_autorunner/web/middleware.py +3 -4
  142. codex_autorunner/web/schemas.py +89 -109
  143. codex_autorunner/web/static_assets.py +1 -44
  144. codex_autorunner/workspace/__init__.py +40 -0
  145. codex_autorunner/workspace/paths.py +319 -0
  146. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.0.0.dist-info}/METADATA +18 -21
  147. codex_autorunner-1.0.0.dist-info/RECORD +251 -0
  148. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.0.0.dist-info}/WHEEL +1 -1
  149. codex_autorunner/agents/execution/policy.py +0 -292
  150. codex_autorunner/agents/factory.py +0 -52
  151. codex_autorunner/agents/orchestrator.py +0 -358
  152. codex_autorunner/core/doc_chat.py +0 -1446
  153. codex_autorunner/core/snapshot.py +0 -580
  154. codex_autorunner/integrations/github/chatops.py +0 -268
  155. codex_autorunner/integrations/github/pr_flow.py +0 -1314
  156. codex_autorunner/routes/docs.py +0 -381
  157. codex_autorunner/routes/github.py +0 -327
  158. codex_autorunner/routes/runs.py +0 -250
  159. codex_autorunner/spec_ingest.py +0 -812
  160. codex_autorunner/static/docChatActions.js +0 -287
  161. codex_autorunner/static/docChatEvents.js +0 -300
  162. codex_autorunner/static/docChatRender.js +0 -205
  163. codex_autorunner/static/docChatStream.js +0 -361
  164. codex_autorunner/static/docs.js +0 -20
  165. codex_autorunner/static/docsClipboard.js +0 -69
  166. codex_autorunner/static/docsCrud.js +0 -257
  167. codex_autorunner/static/docsDocUpdates.js +0 -62
  168. codex_autorunner/static/docsDrafts.js +0 -16
  169. codex_autorunner/static/docsElements.js +0 -69
  170. codex_autorunner/static/docsInit.js +0 -285
  171. codex_autorunner/static/docsParse.js +0 -160
  172. codex_autorunner/static/docsSnapshot.js +0 -87
  173. codex_autorunner/static/docsSpecIngest.js +0 -263
  174. codex_autorunner/static/docsState.js +0 -127
  175. codex_autorunner/static/docsThreadRegistry.js +0 -44
  176. codex_autorunner/static/docsUi.js +0 -153
  177. codex_autorunner/static/docsVoice.js +0 -56
  178. codex_autorunner/static/github.js +0 -504
  179. codex_autorunner/static/logs.js +0 -678
  180. codex_autorunner/static/review.js +0 -157
  181. codex_autorunner/static/runs.js +0 -418
  182. codex_autorunner/static/snapshot.js +0 -124
  183. codex_autorunner/static/state.js +0 -94
  184. codex_autorunner/static/todoPreview.js +0 -27
  185. codex_autorunner/workspace.py +0 -16
  186. codex_autorunner-0.1.2.dist-info/RECORD +0 -222
  187. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.0.0.dist-info}/entry_points.txt +0 -0
  188. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.0.0.dist-info}/licenses/LICENSE +0 -0
  189. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,264 @@
1
+ // GENERATED FILE - do not edit directly. Source: static_src/
2
+ /**
3
+ * Ticket Chat Stream - handles SSE streaming for ticket chat
4
+ */
5
+ import { resolvePath, getAuthToken } from "./utils.js";
6
+ import { ticketChatState, renderTicketChat, clearTicketEvents, addUserMessage, addAssistantMessage, } from "./ticketChatActions.js";
7
+ import { applyTicketEvent, renderTicketEvents, renderTicketMessages } from "./ticketChatEvents.js";
8
+ const decoder = new TextDecoder();
9
+ function parseMaybeJson(data) {
10
+ try {
11
+ return JSON.parse(data);
12
+ }
13
+ catch {
14
+ return data;
15
+ }
16
+ }
17
+ export async function performTicketChatRequest(ticketIndex, message, signal, options = {}) {
18
+ // Clear events from previous request and add user message to history
19
+ clearTicketEvents();
20
+ addUserMessage(message);
21
+ // Render both chat (for container visibility) and messages
22
+ renderTicketChat();
23
+ renderTicketMessages();
24
+ const endpoint = resolvePath(`/api/tickets/${ticketIndex}/chat`);
25
+ const headers = {
26
+ "Content-Type": "application/json",
27
+ };
28
+ const token = getAuthToken();
29
+ if (token) {
30
+ headers.Authorization = `Bearer ${token}`;
31
+ }
32
+ const payload = {
33
+ message,
34
+ stream: true,
35
+ };
36
+ if (options.agent)
37
+ payload.agent = options.agent;
38
+ if (options.model)
39
+ payload.model = options.model;
40
+ if (options.reasoning)
41
+ payload.reasoning = options.reasoning;
42
+ const res = await fetch(endpoint, {
43
+ method: "POST",
44
+ headers,
45
+ body: JSON.stringify(payload),
46
+ signal,
47
+ });
48
+ if (!res.ok) {
49
+ const text = await res.text();
50
+ let detail = text;
51
+ try {
52
+ const parsed = JSON.parse(text);
53
+ detail = parsed.detail || parsed.error || text;
54
+ }
55
+ catch {
56
+ // ignore parse errors
57
+ }
58
+ throw new Error(detail || `Request failed (${res.status})`);
59
+ }
60
+ const contentType = res.headers.get("content-type") || "";
61
+ if (contentType.includes("text/event-stream")) {
62
+ await readTicketChatStream(res);
63
+ }
64
+ else {
65
+ // Non-streaming response
66
+ const responsePayload = contentType.includes("application/json")
67
+ ? await res.json()
68
+ : await res.text();
69
+ applyTicketChatResult(responsePayload);
70
+ }
71
+ }
72
+ async function readTicketChatStream(res) {
73
+ if (!res.body)
74
+ throw new Error("Streaming not supported in this browser");
75
+ const reader = res.body.getReader();
76
+ let buffer = "";
77
+ let escapedNewlines = false;
78
+ for (;;) {
79
+ const { value, done } = await reader.read();
80
+ if (done)
81
+ break;
82
+ const decoded = decoder.decode(value, { stream: true });
83
+ // Handle escaped newlines
84
+ if (!escapedNewlines) {
85
+ const combined = buffer + decoded;
86
+ if (!combined.includes("\n") && combined.includes("\\n")) {
87
+ escapedNewlines = true;
88
+ buffer = buffer.replace(/\\n(?=event:|data:|\\n)/g, "\n");
89
+ }
90
+ }
91
+ buffer += escapedNewlines
92
+ ? decoded.replace(/\\n(?=event:|data:|\\n)/g, "\n")
93
+ : decoded;
94
+ // Split on double newlines (SSE message delimiter)
95
+ const chunks = buffer.split("\n\n");
96
+ buffer = chunks.pop() || "";
97
+ for (const chunk of chunks) {
98
+ if (!chunk.trim())
99
+ continue;
100
+ let event = "message";
101
+ const dataLines = [];
102
+ chunk.split("\n").forEach((line) => {
103
+ if (line.startsWith("event:")) {
104
+ event = line.slice(6).trim();
105
+ }
106
+ else if (line.startsWith("data:")) {
107
+ dataLines.push(line.slice(5).trimStart());
108
+ }
109
+ else if (line.trim()) {
110
+ dataLines.push(line);
111
+ }
112
+ });
113
+ if (dataLines.length === 0)
114
+ continue;
115
+ const data = dataLines.join("\n");
116
+ handleTicketStreamEvent(event, data);
117
+ }
118
+ }
119
+ }
120
+ function handleTicketStreamEvent(event, rawData) {
121
+ const parsed = parseMaybeJson(rawData);
122
+ switch (event) {
123
+ case "status": {
124
+ const status = typeof parsed === "string"
125
+ ? parsed
126
+ : parsed.status || "";
127
+ ticketChatState.statusText = status;
128
+ renderTicketChat();
129
+ renderTicketEvents();
130
+ break;
131
+ }
132
+ case "token": {
133
+ const token = typeof parsed === "string"
134
+ ? parsed
135
+ : parsed.token ||
136
+ parsed.text ||
137
+ rawData ||
138
+ "";
139
+ ticketChatState.streamText = (ticketChatState.streamText || "") + token;
140
+ if (!ticketChatState.statusText || ticketChatState.statusText === "queued") {
141
+ ticketChatState.statusText = "responding";
142
+ }
143
+ renderTicketChat();
144
+ break;
145
+ }
146
+ case "update": {
147
+ applyTicketChatResult(parsed);
148
+ break;
149
+ }
150
+ case "event":
151
+ case "app-server": {
152
+ // App-server events (thinking, tool calls, etc.)
153
+ applyTicketEvent(parsed);
154
+ renderTicketEvents();
155
+ break;
156
+ }
157
+ case "error": {
158
+ const message = typeof parsed === "object" && parsed !== null
159
+ ? parsed.detail ||
160
+ parsed.error ||
161
+ rawData
162
+ : rawData || "Ticket chat failed";
163
+ ticketChatState.status = "error";
164
+ ticketChatState.error = String(message);
165
+ // Add error as assistant message
166
+ addAssistantMessage(`Error: ${message}`, true);
167
+ renderTicketChat();
168
+ renderTicketMessages();
169
+ throw new Error(String(message));
170
+ }
171
+ case "interrupted": {
172
+ const message = typeof parsed === "object" && parsed !== null
173
+ ? parsed.detail || rawData
174
+ : rawData || "Ticket chat interrupted";
175
+ ticketChatState.status = "interrupted";
176
+ ticketChatState.error = "";
177
+ ticketChatState.statusText = String(message);
178
+ // Add interrupted message
179
+ addAssistantMessage("Request interrupted", true);
180
+ renderTicketChat();
181
+ renderTicketMessages();
182
+ break;
183
+ }
184
+ case "done":
185
+ case "finish": {
186
+ ticketChatState.status = "done";
187
+ // Final render to ensure UI is up to date
188
+ renderTicketChat();
189
+ renderTicketMessages();
190
+ renderTicketEvents();
191
+ break;
192
+ }
193
+ default:
194
+ // Unknown event - try to parse as app-server event
195
+ if (typeof parsed === "object" && parsed !== null) {
196
+ const messageObj = parsed;
197
+ if (messageObj.method || messageObj.message) {
198
+ applyTicketEvent(parsed);
199
+ renderTicketEvents();
200
+ }
201
+ }
202
+ break;
203
+ }
204
+ }
205
+ function applyTicketChatResult(payload) {
206
+ if (!payload || typeof payload !== "object")
207
+ return;
208
+ const result = payload;
209
+ if (result.status === "interrupted") {
210
+ ticketChatState.status = "interrupted";
211
+ ticketChatState.error = "";
212
+ addAssistantMessage("Request interrupted", true);
213
+ renderTicketChat();
214
+ renderTicketMessages();
215
+ return;
216
+ }
217
+ if (result.status === "error" || result.error) {
218
+ ticketChatState.status = "error";
219
+ ticketChatState.error =
220
+ result.detail || result.error || "Chat failed";
221
+ addAssistantMessage(`Error: ${ticketChatState.error}`, true);
222
+ renderTicketChat();
223
+ renderTicketMessages();
224
+ return;
225
+ }
226
+ // Success
227
+ ticketChatState.status = "done";
228
+ if (result.message) {
229
+ ticketChatState.streamText = result.message;
230
+ }
231
+ if (result.agent_message || result.agentMessage) {
232
+ ticketChatState.statusText =
233
+ result.agent_message || result.agentMessage || "";
234
+ }
235
+ // Check for draft/patch in response
236
+ const hasDraft = result.has_draft ?? result.hasDraft;
237
+ if (hasDraft === false) {
238
+ ticketChatState.draft = null;
239
+ }
240
+ else if (hasDraft === true || result.draft || result.patch || result.content) {
241
+ ticketChatState.draft = {
242
+ content: result.content || "",
243
+ patch: result.patch || "",
244
+ agentMessage: result.agent_message || result.agentMessage || "",
245
+ createdAt: result.created_at || result.createdAt || "",
246
+ baseHash: result.base_hash || result.baseHash || "",
247
+ };
248
+ }
249
+ // Add assistant message from response
250
+ const responseText = ticketChatState.streamText ||
251
+ ticketChatState.statusText ||
252
+ (ticketChatState.draft ? "Changes ready to apply" : "Done");
253
+ if (responseText && ticketChatState.messages.length > 0) {
254
+ // Only add if we have messages (i.e., a user message was sent)
255
+ const lastMessage = ticketChatState.messages[ticketChatState.messages.length - 1];
256
+ // Avoid duplicate assistant messages
257
+ if (lastMessage.role === "user") {
258
+ addAssistantMessage(responseText, true);
259
+ }
260
+ }
261
+ renderTicketChat();
262
+ renderTicketMessages();
263
+ renderTicketEvents();
264
+ }