@straiffi/archon 1.10.12 → 1.11.0
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.
- package/README.md +9 -2
- package/dist/client/assets/{ActivityView-BFn_Nhj4.js → ActivityView-BvXSn9Jw.js} +1 -1
- package/dist/client/assets/{GitHubActionsDialog-iZD86Yju.js → GitHubActionsDialog-BPZg_Wy3.js} +1 -1
- package/dist/client/assets/{VerificationDialog-CqKE8t1d.js → VerificationDialog-D3mOY3z9.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-C8KefY67.js → architectureDiagram-3BPJPVTR-Bj7m5nzx.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-BO2Q_Osr.js → blockDiagram-GPEHLZMM-Dv4SrhZg.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-DGPkhbrK.js → c4Diagram-AAUBKEIU-BKGsMo_n.js} +1 -1
- package/dist/client/assets/channel-DmiHuOD2.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-Dtb7Xu8C.js → chunk-2J33WTMH-oppoEflV.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-Bnf4GbOF.js → chunk-3OPIFGDE-FoeHxEDL.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-BWGid3g7.js → chunk-5ZQYHXKU-DFo7Hn8f.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-ScA8IRGP.js → chunk-727SXJPM-BbM0ijwZ.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-Bygg04Ip.js → chunk-AQP2D5EJ-hGswj21x.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-CxdDDtfN.js → chunk-CSCIHK7Q-k3Y3HBPl.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-BgpZFsB5.js → chunk-KSCS5N6A-D-fMWFHX.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-CKSew0OL.js → chunk-L5ZTLDWV-Cp8034Xo.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-DVG9Rx0K.js → chunk-LZXEDZCA-DCmWwuZY.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-CHBqNmuF.js → chunk-ND2GUHAM-CPxoYLrb.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-DvZYWn7V.js → chunk-NZK2D7GU-B1xsQ-Ge.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-BL7lRTSe.js → chunk-O5CBEL6O-CP_QLulv.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-C-il2wHZ.js → chunk-WU5MYG2G-CqDmmASz.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-GuChK9KD.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-ezsQe4jc.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-B00l5tLi.js → dagre-BM42HDAG-I60HgRr5.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-Tum6g1_5.js → diagram-2AECGRRQ-DH7489lu.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BK1GX5jc.js → diagram-5GNKFQAL-UG5kJveS.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-BrzmD5NB.js → diagram-KO2AKTUF-DLPd9cl-.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-BhrlgXiJ.js → diagram-LMA3HP47-gfoMHIE-.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-K-fWsJ3a.js → diagram-OG6HWLK6-D7zejHzo.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Der6PjHE.js → erDiagram-TEJ5UH35-DB1R9rUd.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-BVWgGhXe.js → flowDiagram-I6XJVG4X-rSasRun9.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-DcoZ5ggj.js → ganttDiagram-6RSMTGT7-ickt48MT.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-BhhbMTBu.js → gitGraphDiagram-PVQCEYII-B2MWuej-.js} +1 -1
- package/dist/client/assets/index-4RQBXPuO.css +2 -0
- package/dist/client/assets/index-BN2UMUYo.js +276 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-Lwc-agyc.js → infoDiagram-5YYISTIA-ClB9-yBC.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-B95U1Xcl.js → ishikawaDiagram-YF4QCWOH-CyUX0IyE.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-xFpigy5D.js → journeyDiagram-JHISSGLW-CvZv1SZ7.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-D3mudQnR.js → kanban-definition-UN3LZRKU-C3MgzQMY.js} +1 -1
- package/dist/client/assets/{line-DtTL3ZI2.js → line-Dpj7mkeR.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-Dau7K6zV.js → mermaid-parser.core-Ezn4UHHp.js} +1 -1
- package/dist/client/assets/{mermaid.core-B8qtvATu.js → mermaid.core-GVI7XZqR.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-Cus04Yq3.js → mindmap-definition-RKZ34NQL-Bu2cgOo4.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-BCMGpBnn.js → pieDiagram-4H26LBE5-_WS41t2_.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CAmOr-PJ.js → quadrantDiagram-W4KKPZXB-Urvq-XqI.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-kisD3jc4.js → requirementDiagram-4Y6WPE33-bkmWG0rM.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CsCedmM0.js → sankeyDiagram-5OEKKPKP-DI0SArVz.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B-dAi954.js → sequenceDiagram-3UESZ5HK-n7PKrHd3.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-X0BnedIW.js → stateDiagram-AJRCARHV-CxnEzrQA.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DXTMu4iJ.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-DfFoSjhr.js → timeline-definition-PNZ67QCA-BFr88_A9.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-CKSCBwhG.js → vennDiagram-CIIHVFJN-BNYs6tfr.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DNIBQmHO.js → wardleyDiagram-YWT4CUSO-CaGZd3fe.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-FvB55TQN.js → xychartDiagram-2RQKCTM6-CMyDrx2a.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +153 -26
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +93 -36
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/activeTool.js +23 -0
- package/dist/server/lib/activeTool.js.map +1 -0
- package/dist/server/lib/agent.js +291 -67
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentCatalog.js +92 -4
- package/dist/server/lib/agentCatalog.js.map +1 -1
- package/dist/server/lib/agentProvider.js +8 -11
- package/dist/server/lib/agentProvider.js.map +1 -1
- package/dist/server/lib/agentRuns.js +26 -2
- package/dist/server/lib/agentRuns.js.map +1 -1
- package/dist/server/lib/automationCheckGate.js +6 -0
- package/dist/server/lib/automationCheckGate.js.map +1 -1
- package/dist/server/lib/buildExecutionEnvironment.js +82 -29
- package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/buildFlow.js +5 -4
- package/dist/server/lib/buildFlow.js.map +1 -1
- package/dist/server/lib/buildSequences.js +7 -29
- package/dist/server/lib/buildSequences.js.map +1 -1
- package/dist/server/lib/buildTicketCommit.js +82 -11
- package/dist/server/lib/buildTicketCommit.js.map +1 -1
- package/dist/server/lib/bundleReviewOperations.js +6 -0
- package/dist/server/lib/bundleReviewOperations.js.map +1 -1
- package/dist/server/lib/chatOperations.js +109 -93
- package/dist/server/lib/chatOperations.js.map +1 -1
- package/dist/server/lib/chatSessionTitle.js +66 -0
- package/dist/server/lib/chatSessionTitle.js.map +1 -0
- package/dist/server/lib/chats.js +20 -4
- package/dist/server/lib/chats.js.map +1 -1
- package/dist/server/lib/checkAutoFix.js +65 -61
- package/dist/server/lib/checkAutoFix.js.map +1 -1
- package/dist/server/lib/codexAgentProvider.js +320 -0
- package/dist/server/lib/codexAgentProvider.js.map +1 -0
- package/dist/server/lib/codexAppServer.js +678 -0
- package/dist/server/lib/codexAppServer.js.map +1 -0
- package/dist/server/lib/codexCatalogDiscoveryExecutionEnvironment.js +302 -0
- package/dist/server/lib/codexCatalogDiscoveryExecutionEnvironment.js.map +1 -0
- package/dist/server/lib/codexDiscovery.js +137 -0
- package/dist/server/lib/codexDiscovery.js.map +1 -0
- package/dist/server/lib/config.js.map +1 -1
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js +2 -2
- package/dist/server/lib/dockerSandboxEnvironmentOperations.js.map +1 -1
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js +39 -10
- package/dist/server/lib/dockerSandboxExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/dockerSandboxExecutionProvider.js +3 -1
- package/dist/server/lib/dockerSandboxExecutionProvider.js.map +1 -1
- package/dist/server/lib/dockerSandboxReleaseProfiles.js +8 -0
- package/dist/server/lib/dockerSandboxReleaseProfiles.js.map +1 -1
- package/dist/server/lib/executionCredentialCapabilities.js +39 -14
- package/dist/server/lib/executionCredentialCapabilities.js.map +1 -1
- package/dist/server/lib/executionEnvironment.js.map +1 -1
- package/dist/server/lib/executionEnvironmentContexts.js +1 -1
- package/dist/server/lib/executionEnvironmentContexts.js.map +1 -1
- package/dist/server/lib/executionEnvironmentLifecycle.js +1 -1
- package/dist/server/lib/executionEnvironmentLifecycle.js.map +1 -1
- package/dist/server/lib/executionEnvironmentReconciliation.js +7 -7
- package/dist/server/lib/executionEnvironmentReconciliation.js.map +1 -1
- package/dist/server/lib/executionEnvironmentRoutes.js +29 -25
- package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidation.js +205 -20
- package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidationOperations.js +34 -29
- package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
- package/dist/server/lib/executionEnvironments.js +59 -1
- package/dist/server/lib/executionEnvironments.js.map +1 -1
- package/dist/server/lib/executionProfiles.js +6 -3
- package/dist/server/lib/executionProfiles.js.map +1 -1
- package/dist/server/lib/executionRetryPredicates.js +2 -1
- package/dist/server/lib/executionRetryPredicates.js.map +1 -1
- package/dist/server/lib/executionRunAuthority.js +6 -1
- package/dist/server/lib/executionRunAuthority.js.map +1 -1
- package/dist/server/lib/genericToolCall.js +131 -9
- package/dist/server/lib/genericToolCall.js.map +1 -1
- package/dist/server/lib/hostExecutionEnvironment.js +5 -0
- package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/lightweightPrompt.js +258 -18
- package/dist/server/lib/lightweightPrompt.js.map +1 -1
- package/dist/server/lib/mobileAccess.js +21 -13
- package/dist/server/lib/mobileAccess.js.map +1 -1
- package/dist/server/lib/modelResolutionErrors.js +4 -2
- package/dist/server/lib/modelResolutionErrors.js.map +1 -1
- package/dist/server/lib/models.js +15 -2
- package/dist/server/lib/models.js.map +1 -1
- package/dist/server/lib/oneShotAgent.js +11 -0
- package/dist/server/lib/oneShotAgent.js.map +1 -0
- package/dist/server/lib/projectAutoConfig.js +11 -5
- package/dist/server/lib/projectAutoConfig.js.map +1 -1
- package/dist/server/lib/projectMemory.js +3 -1
- package/dist/server/lib/projectMemory.js.map +1 -1
- package/dist/server/lib/projectMemoryScan.js +13 -3
- package/dist/server/lib/projectMemoryScan.js.map +1 -1
- package/dist/server/lib/projectMemoryTransfer.js +5 -2
- package/dist/server/lib/projectMemoryTransfer.js.map +1 -1
- package/dist/server/lib/promptSkills.js +1 -1
- package/dist/server/lib/promptSkills.js.map +1 -1
- package/dist/server/lib/run.js +2 -0
- package/dist/server/lib/run.js.map +1 -1
- package/dist/server/lib/skills.js +21 -4
- package/dist/server/lib/skills.js.map +1 -1
- package/dist/server/lib/specOperations.js +14 -10
- package/dist/server/lib/specOperations.js.map +1 -1
- package/dist/server/lib/specReviewOperations.js +20 -11
- package/dist/server/lib/specReviewOperations.js.map +1 -1
- package/dist/server/lib/specs.js +14 -4
- package/dist/server/lib/specs.js.map +1 -1
- package/dist/server/lib/ticketAutomationCommit.js +23 -7
- package/dist/server/lib/ticketAutomationCommit.js.map +1 -1
- package/dist/server/lib/ticketFollowUpOperations.js +7 -0
- package/dist/server/lib/ticketFollowUpOperations.js.map +1 -1
- package/dist/server/lib/ticketRunOperations.js +11 -1
- package/dist/server/lib/ticketRunOperations.js.map +1 -1
- package/dist/server/lib/ticketSettingsOperations.js +4 -1
- package/dist/server/lib/ticketSettingsOperations.js.map +1 -1
- package/dist/server/lib/toolUpgrade.js +1 -0
- package/dist/server/lib/toolUpgrade.js.map +1 -1
- package/dist/server/lib/transcriptRuns.js +4 -1
- package/dist/server/lib/transcriptRuns.js.map +1 -1
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/workers/build.js +9 -4
- package/dist/server/workers/build.js.map +1 -1
- package/dist/server/workers/chat.js +55 -11
- package/dist/server/workers/chat.js.map +1 -1
- package/dist/server/workers/followUp.js +6 -1
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/plan.js +235 -68
- package/dist/server/workers/plan.js.map +1 -1
- package/dist/server/workers/planFollowUp.js +11 -4
- package/dist/server/workers/planFollowUp.js.map +1 -1
- package/dist/server/workers/review.js +15 -18
- package/dist/server/workers/review.js.map +1 -1
- package/dist/server/workers/specReview.js +7 -7
- package/dist/server/workers/specReview.js.map +1 -1
- package/dist/server/workers/specSession.js +8 -12
- package/dist/server/workers/specSession.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-DXKn3TOv.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-U0fU20hT.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-C6bQNSxL.js +0 -1
- package/dist/client/assets/index-B6BltHSr.css +0 -2
- package/dist/client/assets/index-CFOYm3j9.js +0 -276
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-6B8YH8Y2.js +0 -1
package/dist/server/lib/agent.js
CHANGED
|
@@ -3,15 +3,17 @@ import { randomUUID } from 'crypto';
|
|
|
3
3
|
import { isAbsolute, relative, resolve, sep } from 'path';
|
|
4
4
|
import db from '../db.js';
|
|
5
5
|
import { getChatSession, updateChatSessionUsageSnapshot } from './chats.js';
|
|
6
|
-
import {
|
|
6
|
+
import { normalizeAgentModelId, requireExecutableAgent } from './agentCatalog.js';
|
|
7
7
|
import { createOpencodeTaskSessionReader, parseOpencodeTaskEnvelope } from './opencodeTaskSessions.js';
|
|
8
8
|
import { hostOpencodeSessionOperations } from './opencodeSessionOperations.js';
|
|
9
9
|
import { hostExecutionEnvironment } from './hostExecutionEnvironment.js';
|
|
10
10
|
import { markRetryableOpenCodeDatabaseLock, RetryableOpenCodeDatabaseLockError, retryOpenCodeDatabaseLocks } from './opencodeExecutionReliability.js';
|
|
11
11
|
import { claudeAgentProvider } from './claudeAgentProvider.js';
|
|
12
|
+
import { codexAgentProvider } from './codexAgentProvider.js';
|
|
13
|
+
import { redactCodexDiagnostic } from './codexAppServer.js';
|
|
12
14
|
import { buildOpencodeSpecReviewInvocation, createOpencodeExitError, createOpencodeRecoveryTracker, interpretOpencodeRecoveryEvent, isSuccessfulOpencodeExit, opencodeAgentProvider, } from './opencodeAgentProvider.js';
|
|
13
15
|
import { appendClaudeHeadlessPlanPrompt, buildClaudeHeadlessPlanArgs } from './planModeQuestions.js';
|
|
14
|
-
import { formatGenericToolCall } from './genericToolCall.js';
|
|
16
|
+
import { formatCodexFileChange, formatCodexWebSearch, formatGenericToolCall } from './genericToolCall.js';
|
|
15
17
|
import { getSpecSession, updateSpecSessionResumeId, updateSpecSessionStatus, updateSpecSessionTitle, updateSpecSessionUsageSnapshot } from './specs.js';
|
|
16
18
|
import { updateSpecReviewRunStatus, updateSpecReviewRunStreaming, updateSpecReviewRunUsage } from './specReviews.js';
|
|
17
19
|
import { createAgentRun, emitAgentRunsUpdated, emitExecutionAgentRunsUpdated, finalizeAgentRun, getNextAgentRunIndex, listAgentRunsForExecutionRun, listAgentRunsForParent, updateAgentRunLabel, updateAgentRunSessionId, updateAgentRunStatus } from './agentRuns.js';
|
|
@@ -34,7 +36,7 @@ export class AgentContinuationRejectedError extends Error {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
export const isAgentContinuationRejectedError = (error) => (error instanceof AgentContinuationRejectedError);
|
|
37
|
-
const isTypedPreExecutionContinuationRejection = (message) => (/(?:session|conversation).*(?:not found|does not exist|invalid|expired)|(?:invalid|unknown).*(?:session|conversation)/i.test(message));
|
|
39
|
+
export const isTypedPreExecutionContinuationRejection = (message) => (/(?:session|conversation|thread).*(?:not found|does not exist|invalid|expired)|(?:invalid|unknown).*(?:session|conversation|thread)|no rollout found for thread id/i.test(message));
|
|
38
40
|
const attachTranscriptRunsToError = (error, transcriptRuns) => {
|
|
39
41
|
const resolvedError = (error instanceof Error ? error : new Error(String(error)));
|
|
40
42
|
if (transcriptRuns) {
|
|
@@ -53,10 +55,20 @@ const OPENCODE_SESSION_METADATA_LOOKUP_DELAY_MS = 1500;
|
|
|
53
55
|
const AGENT_PROGRESS_UPDATE_INTERVAL_MS = 100;
|
|
54
56
|
const OPENCODE_SUBAGENT_POLL_INTERVAL_MS = 750;
|
|
55
57
|
const resolveAgentModel = (tool, model) => {
|
|
58
|
+
return normalizeAgentModelId(tool, model) || null;
|
|
59
|
+
};
|
|
60
|
+
const getStreamingAgentProvider = (tool) => {
|
|
56
61
|
if (tool === 'claude') {
|
|
57
|
-
return
|
|
62
|
+
return claudeAgentProvider;
|
|
63
|
+
}
|
|
64
|
+
if (tool === 'codex') {
|
|
65
|
+
return codexAgentProvider;
|
|
58
66
|
}
|
|
59
|
-
return
|
|
67
|
+
return opencodeAgentProvider;
|
|
68
|
+
};
|
|
69
|
+
const getAgentStderr = (tool, chunks) => {
|
|
70
|
+
const stderr = Buffer.concat(chunks).toString();
|
|
71
|
+
return tool === 'codex' ? redactCodexDiagnostic(stderr) : stderr;
|
|
60
72
|
};
|
|
61
73
|
const writeClaudeStdin = (child, message) => {
|
|
62
74
|
const stdin = child.stdin;
|
|
@@ -358,7 +370,11 @@ const updateChatSessionStatus = (chatSessionId, status, log, io, streamingRespon
|
|
|
358
370
|
}
|
|
359
371
|
};
|
|
360
372
|
const updateChatSessionId = (chatSessionId, tool, sessionId, io) => {
|
|
361
|
-
const sessionField = tool === 'claude'
|
|
373
|
+
const sessionField = tool === 'claude'
|
|
374
|
+
? 'claude_session_id'
|
|
375
|
+
: tool === 'codex'
|
|
376
|
+
? 'codex_session_id'
|
|
377
|
+
: 'opencode_session_id';
|
|
362
378
|
db.prepare(`UPDATE chat_sessions SET ${sessionField} = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?`).run(sessionId, chatSessionId);
|
|
363
379
|
const chatSession = getChatSession(chatSessionId, { includeMessages: true });
|
|
364
380
|
if (chatSession) {
|
|
@@ -787,6 +803,16 @@ const formatToolCall = (name, input, cwd) => {
|
|
|
787
803
|
return formatApplyPatchToolCall(input, cwd);
|
|
788
804
|
}
|
|
789
805
|
const normalized = normalizeToolName(name);
|
|
806
|
+
if (normalized === 'filechange') {
|
|
807
|
+
const formatted = formatCodexFileChange(input, cwd);
|
|
808
|
+
if (formatted !== null) {
|
|
809
|
+
return formatted;
|
|
810
|
+
}
|
|
811
|
+
return formatGenericToolCall(name, input);
|
|
812
|
+
}
|
|
813
|
+
if (normalized === 'websearch') {
|
|
814
|
+
return formatCodexWebSearch(input);
|
|
815
|
+
}
|
|
790
816
|
if (normalized === 'edit') {
|
|
791
817
|
const formatted = formatEditToolCall(input, cwd);
|
|
792
818
|
if (formatted !== null) {
|
|
@@ -836,7 +862,10 @@ const stringifyToolResult = (content) => {
|
|
|
836
862
|
};
|
|
837
863
|
const getSubagentCompletionStatus = (state, isError = false) => {
|
|
838
864
|
const normalizedState = state?.toLowerCase();
|
|
839
|
-
|
|
865
|
+
if (isError || normalizedState === 'failed' || normalizedState === 'error') {
|
|
866
|
+
return 'error';
|
|
867
|
+
}
|
|
868
|
+
return normalizedState === 'stopped' ? 'stopped' : 'done';
|
|
840
869
|
};
|
|
841
870
|
const emptyParsedStreamLine = () => ({
|
|
842
871
|
logFragment: null,
|
|
@@ -961,8 +990,23 @@ const parseOpencodeJsonEvent = (event, cwd) => {
|
|
|
961
990
|
|| event.part?.sessionID?.trim()
|
|
962
991
|
|| event.part?.sessionId?.trim()
|
|
963
992
|
|| null;
|
|
993
|
+
if (event.type === 'plan' && event.part?.type === 'text' && event.part.text) {
|
|
994
|
+
return {
|
|
995
|
+
logFragment: event.part.text,
|
|
996
|
+
responseFragment: null,
|
|
997
|
+
subagentEvents: [],
|
|
998
|
+
providerSessionId,
|
|
999
|
+
modelResolutionError: false,
|
|
1000
|
+
concatenateFragments: event.part.metadata?.codex?.delta === true,
|
|
1001
|
+
replaceFragment: event.part.metadata?.codex?.snapshot === true,
|
|
1002
|
+
fragmentGroup: event.part.metadata?.codex?.fragmentGroup
|
|
1003
|
+
?? event.part.metadata?.codex?.itemId
|
|
1004
|
+
?? null,
|
|
1005
|
+
};
|
|
1006
|
+
}
|
|
964
1007
|
if (event.type === 'text' && event.part?.type === 'text' && event.part.text) {
|
|
965
|
-
const
|
|
1008
|
+
const concatenateFragments = event.part.metadata?.codex?.delta === true;
|
|
1009
|
+
const text = concatenateFragments ? event.part.text : event.part.text.trim();
|
|
966
1010
|
const phase = event.part.metadata?.openai?.phase;
|
|
967
1011
|
const recoveryEvent = interpretOpencodeRecoveryEvent(event.type, event.error, text, phase);
|
|
968
1012
|
return {
|
|
@@ -972,16 +1016,25 @@ const parseOpencodeJsonEvent = (event, cwd) => {
|
|
|
972
1016
|
providerSessionId,
|
|
973
1017
|
modelResolutionError: false,
|
|
974
1018
|
recoveryEvents: recoveryEvent ? [recoveryEvent] : [],
|
|
1019
|
+
concatenateFragments,
|
|
1020
|
+
fragmentGroup: event.part.metadata?.codex?.fragmentGroup
|
|
1021
|
+
?? event.part.metadata?.codex?.itemId
|
|
1022
|
+
?? null,
|
|
975
1023
|
};
|
|
976
1024
|
}
|
|
977
1025
|
if (event.type === 'reasoning' && event.part?.type === 'reasoning') {
|
|
978
|
-
const
|
|
1026
|
+
const concatenateFragments = event.part.metadata?.codex?.delta === true;
|
|
1027
|
+
const text = concatenateFragments ? event.part.text ?? '' : event.part.text?.trim() ?? '';
|
|
979
1028
|
return {
|
|
980
1029
|
logFragment: text || null,
|
|
981
1030
|
responseFragment: null,
|
|
982
1031
|
subagentEvents: [],
|
|
983
1032
|
providerSessionId,
|
|
984
1033
|
modelResolutionError: false,
|
|
1034
|
+
concatenateFragments,
|
|
1035
|
+
fragmentGroup: event.part.metadata?.codex?.fragmentGroup
|
|
1036
|
+
?? event.part.metadata?.codex?.itemId
|
|
1037
|
+
?? null,
|
|
985
1038
|
};
|
|
986
1039
|
}
|
|
987
1040
|
if (event.type === 'tool' || event.type === 'tool_use' || event.type === 'tool_result') {
|
|
@@ -993,8 +1046,9 @@ const parseOpencodeJsonEvent = (event, cwd) => {
|
|
|
993
1046
|
const envelope = parseOpencodeTaskEnvelope(rawOutput);
|
|
994
1047
|
const output = envelope ? envelope.result : rawOutput;
|
|
995
1048
|
const taskStatus = event.part?.state?.status?.toLowerCase() ?? envelope?.state?.toLowerCase();
|
|
996
|
-
const
|
|
997
|
-
const
|
|
1049
|
+
const isTerminal = Boolean(taskStatus && taskStatus !== 'running' && taskStatus !== 'pending');
|
|
1050
|
+
const outputKind = isTerminal ? 'complete' : 'fragment';
|
|
1051
|
+
const completionStatus = getSubagentCompletionStatus(taskStatus);
|
|
998
1052
|
const childSessionId = envelope?.childSessionId
|
|
999
1053
|
?? (typeof event.part?.state?.metadata?.sessionID === 'string' ? event.part.state.metadata.sessionID : null)
|
|
1000
1054
|
?? (typeof event.part?.state?.metadata?.sessionId === 'string' ? event.part.state.metadata.sessionId : null);
|
|
@@ -1010,11 +1064,11 @@ const parseOpencodeJsonEvent = (event, cwd) => {
|
|
|
1010
1064
|
sessionId: childSessionId,
|
|
1011
1065
|
}]
|
|
1012
1066
|
: []),
|
|
1013
|
-
...(output
|
|
1067
|
+
...(output || isTerminal
|
|
1014
1068
|
? [{
|
|
1015
1069
|
kind: outputKind,
|
|
1016
1070
|
callId: event.part?.callID ?? null,
|
|
1017
|
-
text: output,
|
|
1071
|
+
...(output ? { text: output } : {}),
|
|
1018
1072
|
sessionId: childSessionId,
|
|
1019
1073
|
status: completionStatus,
|
|
1020
1074
|
}]
|
|
@@ -1099,6 +1153,9 @@ const parseOpencodeJsonLine = (line, cwd) => {
|
|
|
1099
1153
|
const recoveryEvents = [];
|
|
1100
1154
|
let providerSessionId = null;
|
|
1101
1155
|
let modelResolutionError = false;
|
|
1156
|
+
let concatenateFragments;
|
|
1157
|
+
let replaceFragment;
|
|
1158
|
+
let fragmentGroup;
|
|
1102
1159
|
for (const jsonObject of jsonObjects) {
|
|
1103
1160
|
let event;
|
|
1104
1161
|
try {
|
|
@@ -1113,6 +1170,11 @@ const parseOpencodeJsonLine = (line, cwd) => {
|
|
|
1113
1170
|
recoveryEvents.push(...(parsedEvent.recoveryEvents ?? []));
|
|
1114
1171
|
modelResolutionError ||= Boolean(parsedEvent.modelResolutionError);
|
|
1115
1172
|
providerSessionId = providerSessionId ?? parsedEvent.providerSessionId;
|
|
1173
|
+
if (jsonObjects.length === 1) {
|
|
1174
|
+
concatenateFragments = parsedEvent.concatenateFragments;
|
|
1175
|
+
replaceFragment = parsedEvent.replaceFragment;
|
|
1176
|
+
fragmentGroup = parsedEvent.fragmentGroup;
|
|
1177
|
+
}
|
|
1116
1178
|
if (logFragment !== null) {
|
|
1117
1179
|
logFragments.push(logFragment);
|
|
1118
1180
|
}
|
|
@@ -1144,6 +1206,9 @@ const parseOpencodeJsonLine = (line, cwd) => {
|
|
|
1144
1206
|
providerSessionId,
|
|
1145
1207
|
modelResolutionError,
|
|
1146
1208
|
recoveryEvents,
|
|
1209
|
+
concatenateFragments,
|
|
1210
|
+
replaceFragment,
|
|
1211
|
+
fragmentGroup,
|
|
1147
1212
|
};
|
|
1148
1213
|
}
|
|
1149
1214
|
return emptyParsedStreamLine();
|
|
@@ -1155,16 +1220,49 @@ const appendTranscriptText = (current, fragment) => {
|
|
|
1155
1220
|
}
|
|
1156
1221
|
return current ? `${current}\n\n${trimmed}` : trimmed;
|
|
1157
1222
|
};
|
|
1223
|
+
const concatenatingLogLines = new WeakMap();
|
|
1224
|
+
const concatenatingResponseLines = new WeakMap();
|
|
1225
|
+
const groupedLogLineIndexes = new WeakMap();
|
|
1226
|
+
const groupedResponseLineIndexes = new WeakMap();
|
|
1227
|
+
const appendGroupedFragment = (lines, fragment, group, concatenate, replace, activeGroups, indexesByGroup) => {
|
|
1228
|
+
const groupKey = group ?? null;
|
|
1229
|
+
const indexes = indexesByGroup.get(lines) ?? new Map();
|
|
1230
|
+
if (replace && group) {
|
|
1231
|
+
const index = indexes.get(group);
|
|
1232
|
+
if (index !== undefined) {
|
|
1233
|
+
lines[index] = fragment;
|
|
1234
|
+
}
|
|
1235
|
+
else {
|
|
1236
|
+
indexes.set(group, lines.push(fragment) - 1);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
else if (concatenate && activeGroups.get(lines) === groupKey && lines.length > 0) {
|
|
1240
|
+
lines[lines.length - 1] += fragment;
|
|
1241
|
+
}
|
|
1242
|
+
else {
|
|
1243
|
+
const index = lines.push(fragment) - 1;
|
|
1244
|
+
if (group) {
|
|
1245
|
+
indexes.set(group, index);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
indexesByGroup.set(lines, indexes);
|
|
1249
|
+
if (concatenate) {
|
|
1250
|
+
activeGroups.set(lines, groupKey);
|
|
1251
|
+
}
|
|
1252
|
+
else {
|
|
1253
|
+
activeGroups.delete(lines);
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1158
1256
|
const appendOpencodeTranscriptLine = ({ parsed, logLines, responseLines, recoveryTracker, }) => {
|
|
1159
1257
|
const shouldResetResponse = recoveryTracker.consume(parsed.recoveryEvents);
|
|
1160
1258
|
if (shouldResetResponse) {
|
|
1161
1259
|
responseLines.length = 0;
|
|
1162
1260
|
}
|
|
1163
1261
|
if (parsed.logFragment !== null) {
|
|
1164
|
-
logLines.
|
|
1262
|
+
appendGroupedFragment(logLines, parsed.logFragment, parsed.fragmentGroup, parsed.concatenateFragments, parsed.replaceFragment, concatenatingLogLines, groupedLogLineIndexes);
|
|
1165
1263
|
}
|
|
1166
1264
|
if (parsed.responseFragment !== null) {
|
|
1167
|
-
responseLines.
|
|
1265
|
+
appendGroupedFragment(responseLines, parsed.responseFragment, parsed.fragmentGroup, parsed.concatenateFragments, parsed.replaceFragment, concatenatingResponseLines, groupedResponseLineIndexes);
|
|
1168
1266
|
}
|
|
1169
1267
|
return shouldResetResponse;
|
|
1170
1268
|
};
|
|
@@ -1360,6 +1458,9 @@ export const createSubagentRunTracker = ({ parentType, parentId, io, mainRun, ex
|
|
|
1360
1458
|
run_index: run.runIndex,
|
|
1361
1459
|
label: run.label,
|
|
1362
1460
|
role: 'subagent',
|
|
1461
|
+
tool: persistedRun?.tool,
|
|
1462
|
+
model: persistedRun?.model,
|
|
1463
|
+
variant: persistedRun?.variant,
|
|
1363
1464
|
agent_status: run.status,
|
|
1364
1465
|
agent_log: run.log || null,
|
|
1365
1466
|
streaming_response: null,
|
|
@@ -1388,6 +1489,9 @@ export const createSubagentRunTracker = ({ parentType, parentId, io, mainRun, ex
|
|
|
1388
1489
|
run_index: mainRun.runIndex,
|
|
1389
1490
|
label: mainRun.label,
|
|
1390
1491
|
role: mainRun.role,
|
|
1492
|
+
tool: persistedMainRun?.tool,
|
|
1493
|
+
model: persistedMainRun?.model,
|
|
1494
|
+
variant: persistedMainRun?.variant,
|
|
1391
1495
|
agent_status: status,
|
|
1392
1496
|
agent_log: parentLog,
|
|
1393
1497
|
streaming_response: null,
|
|
@@ -1935,7 +2039,7 @@ export const stopSpecReviewAgent = async (specReviewRunId) => {
|
|
|
1935
2039
|
}
|
|
1936
2040
|
return true;
|
|
1937
2041
|
};
|
|
1938
|
-
const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null, resumeSessionId = null, sessionField = 'session_id', trackBuildProcess = false, reviewProcessState, emitSuccessUpdate = true, opencodeAgentMode, runStream, executionContext, persistSessionIdToTicket = false, spawnPermitId, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
2042
|
+
const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null, skills = [], resumeSessionId = null, sessionField = 'session_id', trackBuildProcess = false, reviewProcessState, emitSuccessUpdate = true, opencodeAgentMode, runStream, executionContext, persistSessionIdToTicket = false, spawnPermitId, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
1939
2043
|
const resolvedModel = resolveAgentModel(tool, model);
|
|
1940
2044
|
const opencodeSessionOperations = executionProvider.sessionOperations?.opencode ?? null;
|
|
1941
2045
|
const subagentTracker = createSubagentRunTracker({
|
|
@@ -2067,18 +2171,18 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2067
2171
|
}
|
|
2068
2172
|
return hasResolvedOpencodeSessionId;
|
|
2069
2173
|
};
|
|
2070
|
-
const agentProvider = tool
|
|
2071
|
-
|
|
2072
|
-
: opencodeAgentProvider;
|
|
2073
|
-
const invocation = agentProvider.buildStreamingInvocation({
|
|
2174
|
+
const agentProvider = getStreamingAgentProvider(tool);
|
|
2175
|
+
const streamingRequest = {
|
|
2074
2176
|
cwd,
|
|
2177
|
+
skills,
|
|
2075
2178
|
prompt,
|
|
2076
2179
|
model: resolvedModel,
|
|
2077
2180
|
variant,
|
|
2078
2181
|
mode: opencodeAgentMode,
|
|
2079
2182
|
resumeSessionId,
|
|
2080
2183
|
sessionId: randomUUID(),
|
|
2081
|
-
}
|
|
2184
|
+
};
|
|
2185
|
+
const invocation = agentProvider.buildStreamingInvocation(streamingRequest);
|
|
2082
2186
|
sessionId = invocation.sessionId;
|
|
2083
2187
|
writeRunStatus('running', null);
|
|
2084
2188
|
if (tool === 'claude' && sessionId) {
|
|
@@ -2088,6 +2192,7 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2088
2192
|
spawnTimestamp = Date.now();
|
|
2089
2193
|
}
|
|
2090
2194
|
let child;
|
|
2195
|
+
let providerStdout = null;
|
|
2091
2196
|
let interrupt;
|
|
2092
2197
|
let placementFailure;
|
|
2093
2198
|
let placementCompletion = Promise.resolve(null);
|
|
@@ -2115,6 +2220,31 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2115
2220
|
if (handle.placementIdentity) {
|
|
2116
2221
|
placementCompletion = placementFailure;
|
|
2117
2222
|
}
|
|
2223
|
+
const connection = agentProvider.connectStreamingInvocation?.(child, streamingRequest, {
|
|
2224
|
+
runtimeEnvironmentKind: executionRuntimeEnvironment.kind,
|
|
2225
|
+
});
|
|
2226
|
+
if (connection) {
|
|
2227
|
+
providerStdout = connection.stdout;
|
|
2228
|
+
const placementInterrupt = interrupt;
|
|
2229
|
+
interrupt = async (signal) => {
|
|
2230
|
+
if (signal === 'SIGKILL') {
|
|
2231
|
+
await placementInterrupt(signal);
|
|
2232
|
+
return;
|
|
2233
|
+
}
|
|
2234
|
+
try {
|
|
2235
|
+
await connection.interrupt();
|
|
2236
|
+
}
|
|
2237
|
+
catch {
|
|
2238
|
+
await placementInterrupt(signal);
|
|
2239
|
+
}
|
|
2240
|
+
};
|
|
2241
|
+
void connection.sessionReady.then(providerThreadId => {
|
|
2242
|
+
if (!settled && providerThreadId) {
|
|
2243
|
+
sessionId = providerThreadId;
|
|
2244
|
+
writeRunSessionId(providerThreadId);
|
|
2245
|
+
}
|
|
2246
|
+
}).catch(() => { });
|
|
2247
|
+
}
|
|
2118
2248
|
}
|
|
2119
2249
|
catch (error) {
|
|
2120
2250
|
const resolvedError = agentProvider.classifyExecutionFailure(error);
|
|
@@ -2219,7 +2349,7 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2219
2349
|
responseLines.push(responseFragment);
|
|
2220
2350
|
}
|
|
2221
2351
|
}
|
|
2222
|
-
const errOutput =
|
|
2352
|
+
const errOutput = getAgentStderr(tool, stderrChunks);
|
|
2223
2353
|
const finalLog = logLines.join('\n\n') || errOutput;
|
|
2224
2354
|
const finalResponse = responseLines.join('\n\n') || errOutput;
|
|
2225
2355
|
const modelError = isLegacyModelResolutionError(errOutput);
|
|
@@ -2285,7 +2415,8 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2285
2415
|
},
|
|
2286
2416
|
});
|
|
2287
2417
|
}
|
|
2288
|
-
child.stdout
|
|
2418
|
+
const output = providerStdout ?? child.stdout;
|
|
2419
|
+
output?.on('data', (chunk) => {
|
|
2289
2420
|
lastOutputAt = Date.now();
|
|
2290
2421
|
const text = remainder + chunk.toString();
|
|
2291
2422
|
const lines = text.split('\n');
|
|
@@ -2395,7 +2526,7 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2395
2526
|
clearTimeout(sessionLookupTimer);
|
|
2396
2527
|
sessionLookupTimer = null;
|
|
2397
2528
|
}
|
|
2398
|
-
const stderrOutput =
|
|
2529
|
+
const stderrOutput = getAgentStderr(tool, stderrChunks);
|
|
2399
2530
|
const log = logLines.join('\n\n') || persistedTranscript?.log || stderrOutput;
|
|
2400
2531
|
const recoveredResponse = recoveryTracker.getRecoveredResponse();
|
|
2401
2532
|
const streamedResponse = recoveryTracker.hasRecoveredFinalAnswer()
|
|
@@ -2463,7 +2594,7 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2463
2594
|
subagentTracker.handle(parsed.subagentEvents);
|
|
2464
2595
|
appendOpencodeTranscriptLine({ parsed, logLines, responseLines, recoveryTracker });
|
|
2465
2596
|
}
|
|
2466
|
-
const stderrOutput =
|
|
2597
|
+
const stderrOutput = getAgentStderr(tool, stderrChunks);
|
|
2467
2598
|
const log = logLines.join('\n\n') || stderrOutput;
|
|
2468
2599
|
const response = recoveryTracker.hasRecoveredFinalAnswer()
|
|
2469
2600
|
? recoveryTracker.getRecoveredResponse()
|
|
@@ -2490,10 +2621,11 @@ const runAgentOnce = ({ ticketId, tool, prompt, cwd, io, model, variant = null,
|
|
|
2490
2621
|
});
|
|
2491
2622
|
};
|
|
2492
2623
|
export const runAgent = (options) => {
|
|
2624
|
+
requireExecutableAgent(options.tool);
|
|
2493
2625
|
const run = () => runAgentOnce(options);
|
|
2494
2626
|
return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
|
|
2495
2627
|
};
|
|
2496
|
-
const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, model, variant = null, resumeSessionId = null, opencodeAgentMode = 'build', executionContext, mainRun, spawnPermitId, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
2628
|
+
const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, model, variant = null, skills = [], resumeSessionId = null, opencodeAgentMode = 'build', executionContext, mainRun, spawnPermitId, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
2497
2629
|
const resolvedModel = resolveAgentModel(tool, model);
|
|
2498
2630
|
const opencodeSessionOperations = executionProvider.sessionOperations?.opencode ?? null;
|
|
2499
2631
|
const subagentTracker = createSubagentRunTracker({
|
|
@@ -2537,19 +2669,19 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2537
2669
|
}, transcriptRuns));
|
|
2538
2670
|
return;
|
|
2539
2671
|
}
|
|
2540
|
-
const agentProvider = tool
|
|
2541
|
-
|
|
2542
|
-
: opencodeAgentProvider;
|
|
2543
|
-
const invocation = agentProvider.buildStreamingInvocation({
|
|
2672
|
+
const agentProvider = getStreamingAgentProvider(tool);
|
|
2673
|
+
const streamingRequest = {
|
|
2544
2674
|
cwd,
|
|
2545
2675
|
files,
|
|
2676
|
+
skills,
|
|
2546
2677
|
prompt,
|
|
2547
2678
|
model: resolvedModel,
|
|
2548
2679
|
variant,
|
|
2549
2680
|
mode: opencodeAgentMode,
|
|
2550
2681
|
resumeSessionId,
|
|
2551
2682
|
sessionId: randomUUID(),
|
|
2552
|
-
}
|
|
2683
|
+
};
|
|
2684
|
+
const invocation = agentProvider.buildStreamingInvocation(streamingRequest);
|
|
2553
2685
|
sessionId = invocation.sessionId;
|
|
2554
2686
|
updateChatSessionStatus(chatSessionId, 'running', null, io);
|
|
2555
2687
|
subagentTracker.updateMain(null, null);
|
|
@@ -2580,6 +2712,7 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2580
2712
|
}
|
|
2581
2713
|
}
|
|
2582
2714
|
let child;
|
|
2715
|
+
let providerStdout = null;
|
|
2583
2716
|
let placementCompletion;
|
|
2584
2717
|
try {
|
|
2585
2718
|
if (chatState.stopRequested) {
|
|
@@ -2602,6 +2735,32 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2602
2735
|
child = handle.child;
|
|
2603
2736
|
chatState.interrupt = handle.interrupt;
|
|
2604
2737
|
placementCompletion = handle.placementFailure;
|
|
2738
|
+
const connection = agentProvider.connectStreamingInvocation?.(child, streamingRequest, {
|
|
2739
|
+
runtimeEnvironmentKind: executionRuntimeEnvironment.kind,
|
|
2740
|
+
});
|
|
2741
|
+
if (connection) {
|
|
2742
|
+
providerStdout = connection.stdout;
|
|
2743
|
+
const placementInterrupt = handle.interrupt;
|
|
2744
|
+
chatState.interrupt = async (signal) => {
|
|
2745
|
+
if (signal === 'SIGKILL') {
|
|
2746
|
+
await placementInterrupt(signal);
|
|
2747
|
+
return;
|
|
2748
|
+
}
|
|
2749
|
+
try {
|
|
2750
|
+
await connection.interrupt();
|
|
2751
|
+
}
|
|
2752
|
+
catch {
|
|
2753
|
+
await placementInterrupt(signal);
|
|
2754
|
+
}
|
|
2755
|
+
};
|
|
2756
|
+
void connection.sessionReady.then(providerThreadId => {
|
|
2757
|
+
if (!settled && providerThreadId) {
|
|
2758
|
+
sessionId = providerThreadId;
|
|
2759
|
+
updateChatSessionId(chatSessionId, 'codex', providerThreadId, io);
|
|
2760
|
+
subagentTracker.setMainSessionId(providerThreadId);
|
|
2761
|
+
}
|
|
2762
|
+
}).catch(() => { });
|
|
2763
|
+
}
|
|
2605
2764
|
}
|
|
2606
2765
|
catch (error) {
|
|
2607
2766
|
const resolvedError = agentProvider.classifyExecutionFailure(error);
|
|
@@ -2696,7 +2855,7 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2696
2855
|
responseLines.push(responseFragment);
|
|
2697
2856
|
}
|
|
2698
2857
|
}
|
|
2699
|
-
const errOutput =
|
|
2858
|
+
const errOutput = getAgentStderr(tool, stderrChunks);
|
|
2700
2859
|
const finalLog = logLines.join('\n\n') || errOutput;
|
|
2701
2860
|
const finalResponse = responseLines.join('\n\n') || errOutput;
|
|
2702
2861
|
if (chatState.stopRequested) {
|
|
@@ -2777,7 +2936,8 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2777
2936
|
updateChatSessionStatus(chatSessionId, 'running', log, io, response);
|
|
2778
2937
|
subagentTracker.updateMain(log, response);
|
|
2779
2938
|
});
|
|
2780
|
-
child.stdout
|
|
2939
|
+
const output = providerStdout ?? child.stdout;
|
|
2940
|
+
output?.on('data', (chunk) => {
|
|
2781
2941
|
const text = remainder + chunk.toString();
|
|
2782
2942
|
const lines = text.split('\n');
|
|
2783
2943
|
remainder = lines.pop() ?? '';
|
|
@@ -2836,7 +2996,7 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2836
2996
|
firstFinalAnswerTime = null;
|
|
2837
2997
|
}
|
|
2838
2998
|
}
|
|
2839
|
-
const stderrOutput =
|
|
2999
|
+
const stderrOutput = getAgentStderr(tool, stderrChunks);
|
|
2840
3000
|
const log = logLines.join('\n\n') || stderrOutput;
|
|
2841
3001
|
const recoveredResponse = recoveryTracker.getRecoveredResponse();
|
|
2842
3002
|
const finalResponse = recoveryTracker.hasRecoveredFinalAnswer()
|
|
@@ -2941,10 +3101,11 @@ const runChatAgentOnce = ({ chatSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2941
3101
|
});
|
|
2942
3102
|
};
|
|
2943
3103
|
export const runChatAgent = (options) => {
|
|
3104
|
+
requireExecutableAgent(options.tool);
|
|
2944
3105
|
const run = () => runChatAgentOnce(options);
|
|
2945
3106
|
return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
|
|
2946
3107
|
};
|
|
2947
|
-
const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, resumeSessionId = null, executionContext, mainRun, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
3108
|
+
const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, skills = [], resumeSessionId = null, executionContext, mainRun, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
2948
3109
|
const resolvedModel = resolveAgentModel(tool, model);
|
|
2949
3110
|
const subagentTracker = createSubagentRunTracker({
|
|
2950
3111
|
parentType: 'spec',
|
|
@@ -2987,15 +3148,20 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
2987
3148
|
}, transcriptRuns));
|
|
2988
3149
|
return;
|
|
2989
3150
|
}
|
|
2990
|
-
const
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
:
|
|
3151
|
+
const agentProvider = getStreamingAgentProvider(tool);
|
|
3152
|
+
const streamingRequest = {
|
|
3153
|
+
cwd,
|
|
3154
|
+
files,
|
|
3155
|
+
skills,
|
|
3156
|
+
prompt,
|
|
3157
|
+
model: resolvedModel,
|
|
3158
|
+
variant,
|
|
3159
|
+
mode: 'plan',
|
|
3160
|
+
resumeSessionId,
|
|
3161
|
+
sessionId: randomUUID(),
|
|
3162
|
+
};
|
|
3163
|
+
const invocation = agentProvider.buildStreamingInvocation(streamingRequest);
|
|
3164
|
+
sessionId = invocation.sessionId;
|
|
2999
3165
|
updateSpecSessionStatusLocal(specSessionId, 'running', null, io);
|
|
3000
3166
|
subagentTracker.updateMain(null, null);
|
|
3001
3167
|
if (tool === 'claude' && sessionId) {
|
|
@@ -3024,15 +3190,16 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
3024
3190
|
}
|
|
3025
3191
|
}
|
|
3026
3192
|
let child;
|
|
3193
|
+
let providerStdout = null;
|
|
3027
3194
|
let placementFailure = Promise.resolve(null);
|
|
3028
3195
|
try {
|
|
3029
3196
|
const handle = executionProvider.execute({
|
|
3030
3197
|
phase: 'agent',
|
|
3031
3198
|
target: executionTarget ?? null,
|
|
3032
|
-
command:
|
|
3033
|
-
args,
|
|
3199
|
+
command: invocation.command,
|
|
3200
|
+
args: invocation.args,
|
|
3034
3201
|
cwd,
|
|
3035
|
-
stdio:
|
|
3202
|
+
stdio: invocation.stdio,
|
|
3036
3203
|
launcherEnvironment: executionLauncherEnvironment,
|
|
3037
3204
|
runtimeEnvironment: executionRuntimeEnvironment,
|
|
3038
3205
|
detached: process.platform !== 'win32',
|
|
@@ -3040,6 +3207,32 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
3040
3207
|
child = handle.child;
|
|
3041
3208
|
specState.interrupt = handle.interrupt;
|
|
3042
3209
|
placementFailure = handle.placementFailure;
|
|
3210
|
+
const connection = agentProvider.connectStreamingInvocation?.(child, streamingRequest, {
|
|
3211
|
+
runtimeEnvironmentKind: executionRuntimeEnvironment.kind,
|
|
3212
|
+
});
|
|
3213
|
+
if (connection) {
|
|
3214
|
+
providerStdout = connection.stdout;
|
|
3215
|
+
const placementInterrupt = handle.interrupt;
|
|
3216
|
+
specState.interrupt = async (signal) => {
|
|
3217
|
+
if (signal === 'SIGKILL') {
|
|
3218
|
+
await placementInterrupt(signal);
|
|
3219
|
+
return;
|
|
3220
|
+
}
|
|
3221
|
+
try {
|
|
3222
|
+
await connection.interrupt();
|
|
3223
|
+
}
|
|
3224
|
+
catch {
|
|
3225
|
+
await placementInterrupt(signal);
|
|
3226
|
+
}
|
|
3227
|
+
};
|
|
3228
|
+
void connection.sessionReady.then(providerThreadId => {
|
|
3229
|
+
if (!settled && providerThreadId) {
|
|
3230
|
+
sessionId = providerThreadId;
|
|
3231
|
+
updateSpecSessionIdLocal(specSessionId, 'codex', providerThreadId, io);
|
|
3232
|
+
subagentTracker.setMainSessionId(providerThreadId);
|
|
3233
|
+
}
|
|
3234
|
+
}).catch(() => { });
|
|
3235
|
+
}
|
|
3043
3236
|
void placementFailure.then(failure => {
|
|
3044
3237
|
if (failure) {
|
|
3045
3238
|
rejectOnce(failure);
|
|
@@ -3129,7 +3322,7 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
3129
3322
|
responseLines.push(responseFragment);
|
|
3130
3323
|
}
|
|
3131
3324
|
}
|
|
3132
|
-
const errOutput =
|
|
3325
|
+
const errOutput = getAgentStderr(tool, stderrChunks);
|
|
3133
3326
|
const finalLog = logLines.join('\n\n') || errOutput;
|
|
3134
3327
|
const finalResponse = responseLines.join('\n\n') || errOutput;
|
|
3135
3328
|
if (specState.stopRequested) {
|
|
@@ -3210,7 +3403,8 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
3210
3403
|
updateSpecSessionStatusLocal(specSessionId, 'running', log, io, response);
|
|
3211
3404
|
subagentTracker.updateMain(log, response);
|
|
3212
3405
|
});
|
|
3213
|
-
child.stdout
|
|
3406
|
+
const output = providerStdout ?? child.stdout;
|
|
3407
|
+
output?.on('data', (chunk) => {
|
|
3214
3408
|
const text = remainder + chunk.toString();
|
|
3215
3409
|
const lines = text.split('\n');
|
|
3216
3410
|
remainder = lines.pop() ?? '';
|
|
@@ -3271,7 +3465,7 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
3271
3465
|
firstFinalAnswerTime = null;
|
|
3272
3466
|
}
|
|
3273
3467
|
}
|
|
3274
|
-
const stderrOutput =
|
|
3468
|
+
const stderrOutput = getAgentStderr(tool, stderrChunks);
|
|
3275
3469
|
const log = logLines.join('\n\n') || stderrOutput;
|
|
3276
3470
|
const recoveredResponse = recoveryTracker.getRecoveredResponse();
|
|
3277
3471
|
const finalResponse = recoveryTracker.hasRecoveredFinalAnswer()
|
|
@@ -3374,6 +3568,7 @@ const runSpecAgentOnce = ({ specSessionId, tool, prompt, files = [], cwd, io, mo
|
|
|
3374
3568
|
});
|
|
3375
3569
|
};
|
|
3376
3570
|
export const runSpecAgent = (options) => {
|
|
3571
|
+
requireExecutableAgent(options.tool);
|
|
3377
3572
|
const run = () => runSpecAgentOnce(options);
|
|
3378
3573
|
return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
|
|
3379
3574
|
};
|
|
@@ -3387,7 +3582,7 @@ export const runSpecAgent = (options) => {
|
|
|
3387
3582
|
* updateSpecReviewRunStatus / updateSpecReviewRunStreaming / updateSpecReviewRunUsage —
|
|
3388
3583
|
* the spec_sessions row is never touched by this path.
|
|
3389
3584
|
*/
|
|
3390
|
-
const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, executionContext, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
3585
|
+
const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt, files = [], cwd, io, model, variant = null, skills = [], executionContext, executionProvider = hostExecutionEnvironment, executionTarget, executionLauncherEnvironment = createHostLauncherEnvironment(), executionRuntimeEnvironment = createLegacyHostRuntimeEnvironment(cwd, { PWD: cwd }), }) => {
|
|
3391
3586
|
const registeredState = activeSpecReviewProcesses.get(specReviewRunId);
|
|
3392
3587
|
if (registeredState?.stopRequested) {
|
|
3393
3588
|
return Promise.resolve({
|
|
@@ -3431,20 +3626,25 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3431
3626
|
};
|
|
3432
3627
|
const resolveOnce = settle(resolve);
|
|
3433
3628
|
const rejectOnce = settle(reject);
|
|
3434
|
-
const [cmd, args] = [
|
|
3435
|
-
'claude',
|
|
3436
|
-
buildClaudeArgs('plan', resolvedModel, null, randomUUID()),
|
|
3437
|
-
];
|
|
3438
3629
|
updateSpecReviewRunStreaming(specReviewRunId, null);
|
|
3439
3630
|
let child;
|
|
3631
|
+
let providerStdout = null;
|
|
3440
3632
|
let placementFailure = Promise.resolve(null);
|
|
3633
|
+
const agentProvider = getStreamingAgentProvider(tool);
|
|
3634
|
+
const streamingRequest = {
|
|
3635
|
+
cwd,
|
|
3636
|
+
files,
|
|
3637
|
+
skills,
|
|
3638
|
+
prompt,
|
|
3639
|
+
model: resolvedModel,
|
|
3640
|
+
variant,
|
|
3641
|
+
mode: 'plan',
|
|
3642
|
+
resumeSessionId: null,
|
|
3643
|
+
sessionId: randomUUID(),
|
|
3644
|
+
};
|
|
3441
3645
|
const invocation = tool === 'opencode'
|
|
3442
3646
|
? buildOpencodeSpecReviewInvocation({ prompt, files, model: resolvedModel, variant })
|
|
3443
|
-
:
|
|
3444
|
-
command: cmd,
|
|
3445
|
-
args,
|
|
3446
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
3447
|
-
};
|
|
3647
|
+
: agentProvider.buildStreamingInvocation(streamingRequest);
|
|
3448
3648
|
try {
|
|
3449
3649
|
const handle = executionProvider.execute({
|
|
3450
3650
|
phase: 'agent',
|
|
@@ -3460,14 +3660,36 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3460
3660
|
child = handle.child;
|
|
3461
3661
|
reviewState.interrupt = handle.interrupt;
|
|
3462
3662
|
placementFailure = handle.placementFailure;
|
|
3663
|
+
const connection = agentProvider.connectStreamingInvocation?.(child, streamingRequest, {
|
|
3664
|
+
runtimeEnvironmentKind: executionRuntimeEnvironment.kind,
|
|
3665
|
+
});
|
|
3666
|
+
if (connection) {
|
|
3667
|
+
providerStdout = connection.stdout;
|
|
3668
|
+
const placementInterrupt = handle.interrupt;
|
|
3669
|
+
reviewState.interrupt = async (signal) => {
|
|
3670
|
+
if (signal === 'SIGKILL') {
|
|
3671
|
+
await placementInterrupt(signal);
|
|
3672
|
+
return;
|
|
3673
|
+
}
|
|
3674
|
+
try {
|
|
3675
|
+
await connection.interrupt();
|
|
3676
|
+
}
|
|
3677
|
+
catch {
|
|
3678
|
+
await placementInterrupt(signal);
|
|
3679
|
+
}
|
|
3680
|
+
};
|
|
3681
|
+
void connection.ready.catch(error => {
|
|
3682
|
+
rejectOnce(agentProvider.classifyExecutionFailure(error));
|
|
3683
|
+
});
|
|
3684
|
+
}
|
|
3463
3685
|
void placementFailure.then(failure => {
|
|
3464
3686
|
if (failure) {
|
|
3465
|
-
rejectOnce(
|
|
3687
|
+
rejectOnce(agentProvider.classifyExecutionFailure(failure));
|
|
3466
3688
|
}
|
|
3467
3689
|
});
|
|
3468
3690
|
}
|
|
3469
3691
|
catch (error) {
|
|
3470
|
-
rejectOnce(
|
|
3692
|
+
rejectOnce(agentProvider.classifyExecutionFailure(error));
|
|
3471
3693
|
return;
|
|
3472
3694
|
}
|
|
3473
3695
|
reviewState.child = child;
|
|
@@ -3536,7 +3758,7 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3536
3758
|
responseLines.push(responseFragment);
|
|
3537
3759
|
}
|
|
3538
3760
|
}
|
|
3539
|
-
const errOutput =
|
|
3761
|
+
const errOutput = getAgentStderr(tool, stderrChunks);
|
|
3540
3762
|
const finalLog = logLines.join('\n\n') || errOutput;
|
|
3541
3763
|
const finalResponse = responseLines.join('\n\n') || errOutput;
|
|
3542
3764
|
if (reviewState.stopRequested) {
|
|
@@ -3580,7 +3802,8 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3580
3802
|
const progressUpdater = createThrottledProgressUpdater(() => {
|
|
3581
3803
|
updateSpecReviewRunStreaming(specReviewRunId, responseLines.join('\n\n') || null);
|
|
3582
3804
|
});
|
|
3583
|
-
child.stdout
|
|
3805
|
+
const output = providerStdout ?? child.stdout;
|
|
3806
|
+
output?.on('data', (chunk) => {
|
|
3584
3807
|
const text = remainder + chunk.toString();
|
|
3585
3808
|
const lines = text.split('\n');
|
|
3586
3809
|
remainder = lines.pop() ?? '';
|
|
@@ -3619,7 +3842,7 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3619
3842
|
progressUpdater.cancel();
|
|
3620
3843
|
const placementError = await placementFailure;
|
|
3621
3844
|
if (placementError) {
|
|
3622
|
-
rejectOnce(
|
|
3845
|
+
rejectOnce(agentProvider.classifyExecutionFailure(placementError));
|
|
3623
3846
|
return;
|
|
3624
3847
|
}
|
|
3625
3848
|
await opencodeSubagentMonitor?.refresh();
|
|
@@ -3633,7 +3856,7 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3633
3856
|
firstFinalAnswerTime = null;
|
|
3634
3857
|
}
|
|
3635
3858
|
}
|
|
3636
|
-
const stderrOutput =
|
|
3859
|
+
const stderrOutput = getAgentStderr(tool, stderrChunks);
|
|
3637
3860
|
const log = logLines.join('\n\n') || stderrOutput;
|
|
3638
3861
|
const recoveredResponse = recoveryTracker.getRecoveredResponse();
|
|
3639
3862
|
const finalResponse = recoveryTracker.hasRecoveredFinalAnswer()
|
|
@@ -3699,13 +3922,14 @@ const runSpecReviewAgentOnce = ({ specReviewRunId, specSessionId, tool, prompt,
|
|
|
3699
3922
|
});
|
|
3700
3923
|
return;
|
|
3701
3924
|
}
|
|
3702
|
-
const failure =
|
|
3925
|
+
const failure = agentProvider.classifyExecutionFailure(err);
|
|
3703
3926
|
subagentTracker.finalize('error', failure.message, null);
|
|
3704
3927
|
rejectOnce(failure);
|
|
3705
3928
|
});
|
|
3706
3929
|
});
|
|
3707
3930
|
};
|
|
3708
3931
|
export const runSpecReviewAgent = (options) => {
|
|
3932
|
+
requireExecutableAgent(options.tool);
|
|
3709
3933
|
const run = () => runSpecReviewAgentOnce(options);
|
|
3710
3934
|
return options.tool === 'opencode' ? retryOpenCodeDatabaseLocks(run) : run();
|
|
3711
3935
|
};
|