@straiffi/archon 1.11.5 → 1.11.7
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 +8 -0
- package/dist/client/assets/{ActivityView-Dw7Bl18C.js → ActivityView-gwq90xuC.js} +1 -1
- package/dist/client/assets/{GitHubActionsDialog-9w5XtP5x.js → GitHubActionsDialog-CddU5mmQ.js} +1 -1
- package/dist/client/assets/{VerificationDialog-dOSv05QS.js → VerificationDialog-DZXmgf-Q.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-BU-dnVWz.js → architectureDiagram-3BPJPVTR-B7h4gUId.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-D1fhZ9K3.js → blockDiagram-GPEHLZMM-CKcqgkiW.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-C5cs67FJ.js → c4Diagram-AAUBKEIU-b0N8QAOw.js} +1 -1
- package/dist/client/assets/channel-DFqGOc-J.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-BuofkrUv.js → chunk-2J33WTMH-DuMyezuW.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-BSLbHStu.js → chunk-3OPIFGDE-Dgtz4ReD.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-CV_reqn5.js → chunk-5ZQYHXKU-By3w6rbd.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-DuL4OL6p.js → chunk-727SXJPM-BHTPfHY2.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-B7ebIXsD.js → chunk-AQP2D5EJ-W2Rgle6H.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-CfvfKS81.js → chunk-CSCIHK7Q-C0zW-M44.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-B8yAPh8_.js → chunk-KSCS5N6A-NLszOClX.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-CLAA9PrV.js → chunk-L5ZTLDWV-Djdu-TFq.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-BWDUNHyY.js → chunk-LZXEDZCA-BBMjUaM6.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-DDtkY0aA.js → chunk-ND2GUHAM-BMGxL6oq.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-Cqw_WclD.js → chunk-NZK2D7GU-BmBtYVzv.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-yk76d2Ne.js → chunk-O5CBEL6O-fNzTMe1t.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-C9RL4ic0.js → chunk-WU5MYG2G-DtWDtH9D.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-zJrDS8pp.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Bk6pmr_F.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-D1R8Uoz3.js → dagre-BM42HDAG-zpl4bunJ.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-CUwS3hk7.js → diagram-2AECGRRQ-XiIQ6yDZ.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-BQGwWZ5M.js → diagram-5GNKFQAL-EwX79EhM.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-C7ErzACC.js → diagram-KO2AKTUF-pTTl20VK.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-z4blMZQD.js → diagram-LMA3HP47-CAADMP3T.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-DTdMXNXF.js → diagram-OG6HWLK6-DSw-z9AU.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-Dzq40m7g.js → erDiagram-TEJ5UH35-CYVpzKnx.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-DZee4-lQ.js → flowDiagram-I6XJVG4X-YfUgs6Y9.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-BrvahLDI.js → ganttDiagram-6RSMTGT7-CBZcM6fa.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-DFl7NFyp.js → gitGraphDiagram-PVQCEYII-B-cnyCdP.js} +1 -1
- package/dist/client/assets/index-CbYT3N3U.css +2 -0
- package/dist/client/assets/index-DXJSLf4W.js +287 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-DcbIRnzw.js → infoDiagram-5YYISTIA-hg-hixwz.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CCLSDPWU.js → ishikawaDiagram-YF4QCWOH-CP30YmvW.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-DBybnxZb.js → journeyDiagram-JHISSGLW-MPwOtkOb.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-0vXnDc2p.js → kanban-definition-UN3LZRKU-dzx8hATQ.js} +1 -1
- package/dist/client/assets/{line-CmuG_mnn.js → line-C2wfs9Qd.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-2bcA4BZv.js → mermaid-parser.core-j3pT6MDr.js} +1 -1
- package/dist/client/assets/{mermaid.core-BtCKaSS-.js → mermaid.core-BwkWqkNy.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-BS3GYH1w.js → mindmap-definition-RKZ34NQL-CZ3iES81.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-DnSf3dLi.js → pieDiagram-4H26LBE5-DCY6gx4q.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CvU26PT6.js → quadrantDiagram-W4KKPZXB-Bs-SuHD0.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-9BKyfU_D.js → requirementDiagram-4Y6WPE33-DaHZPYWb.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-9EYmPhr5.js → sankeyDiagram-5OEKKPKP-CAABGeQw.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-BcBk_wZZ.js → sequenceDiagram-3UESZ5HK-BiFFDmHd.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-2m55Kpig.js → stateDiagram-AJRCARHV-DKXUKIex.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DyEfP-lL.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-J3NEOuRz.js → timeline-definition-PNZ67QCA-CNWuUe9M.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-D_3D_Pp4.js → vennDiagram-CIIHVFJN-Melay8l5.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-Wln2PbKU.js → wardleyDiagram-YWT4CUSO-pWa26XVf.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-DfvF03Zn.js → xychartDiagram-2RQKCTM6-BaAwLxVv.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +71 -4
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +29 -5
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent.js +277 -299
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentOutputLanguage.js +11 -0
- package/dist/server/lib/agentOutputLanguage.js.map +1 -0
- package/dist/server/lib/agentProvider.js.map +1 -1
- package/dist/server/lib/agentRuns.js +68 -4
- package/dist/server/lib/agentRuns.js.map +1 -1
- package/dist/server/lib/appLocale.js +19 -0
- package/dist/server/lib/appLocale.js.map +1 -0
- package/dist/server/lib/buildExecutionEnvironment.js +92 -1
- package/dist/server/lib/buildExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/chatDraftTargets.js +81 -0
- package/dist/server/lib/chatDraftTargets.js.map +1 -0
- package/dist/server/lib/chatOperations.js +26 -3
- package/dist/server/lib/chatOperations.js.map +1 -1
- package/dist/server/lib/chatTargets.js +57 -2
- package/dist/server/lib/chatTargets.js.map +1 -1
- package/dist/server/lib/chats.js +10 -6
- package/dist/server/lib/chats.js.map +1 -1
- package/dist/server/lib/conversationResume.js +56 -3
- package/dist/server/lib/conversationResume.js.map +1 -1
- package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js +81 -25
- package/dist/server/lib/dockerSandboxOpencodeSessionOperations.js.map +1 -1
- package/dist/server/lib/dockerSandboxReleaseProfiles.js +36 -7
- package/dist/server/lib/dockerSandboxReleaseProfiles.js.map +1 -1
- package/dist/server/lib/executionEnvironmentRoutes.js +71 -4
- package/dist/server/lib/executionEnvironmentRoutes.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidation.js +199 -19
- package/dist/server/lib/executionEnvironmentValidation.js.map +1 -1
- package/dist/server/lib/executionEnvironmentValidationEvidence.js +140 -0
- package/dist/server/lib/executionEnvironmentValidationEvidence.js.map +1 -0
- package/dist/server/lib/executionEnvironmentValidationOperations.js +13 -0
- package/dist/server/lib/executionEnvironmentValidationOperations.js.map +1 -1
- package/dist/server/lib/executionRetry.js.map +1 -1
- package/dist/server/lib/executionRetryContext.js +55 -11
- package/dist/server/lib/executionRetryContext.js.map +1 -1
- package/dist/server/lib/executionTargets.js +5 -2
- package/dist/server/lib/executionTargets.js.map +1 -1
- package/dist/server/lib/hostExecutionEnvironment.js +14 -2
- package/dist/server/lib/hostExecutionEnvironment.js.map +1 -1
- package/dist/server/lib/i18n/index.js +3 -2
- package/dist/server/lib/i18n/index.js.map +1 -1
- package/dist/server/lib/i18n/resources.js +0 -1
- package/dist/server/lib/i18n/resources.js.map +1 -1
- package/dist/server/lib/lightweightPrompt.js +4 -0
- package/dist/server/lib/lightweightPrompt.js.map +1 -1
- package/dist/server/lib/models.js +58 -18
- package/dist/server/lib/models.js.map +1 -1
- package/dist/server/lib/opencodeAgentProvider.js +54 -48
- package/dist/server/lib/opencodeAgentProvider.js.map +1 -1
- package/dist/server/lib/opencodeCli.js +244 -0
- package/dist/server/lib/opencodeCli.js.map +1 -0
- package/dist/server/lib/opencodePromptOutput.js +11 -65
- package/dist/server/lib/opencodePromptOutput.js.map +1 -1
- package/dist/server/lib/opencodeSessionOperations.js +44 -28
- package/dist/server/lib/opencodeSessionOperations.js.map +1 -1
- package/dist/server/lib/opencodeSessionProvenance.js +23 -0
- package/dist/server/lib/opencodeSessionProvenance.js.map +1 -0
- package/dist/server/lib/opencodeStream.js +263 -0
- package/dist/server/lib/opencodeStream.js.map +1 -0
- package/dist/server/lib/opencodeTaskSessions.js +3 -4
- package/dist/server/lib/opencodeTaskSessions.js.map +1 -1
- package/dist/server/lib/opencodeV2SessionOperations.js +453 -0
- package/dist/server/lib/opencodeV2SessionOperations.js.map +1 -0
- package/dist/server/lib/postBuildChecks.js +1 -1
- package/dist/server/lib/postBuildChecks.js.map +1 -1
- package/dist/server/lib/run.js +32 -41
- package/dist/server/lib/run.js.map +1 -1
- package/dist/server/lib/runProcessIdentity.js +10 -2
- package/dist/server/lib/runProcessIdentity.js.map +1 -1
- package/dist/server/lib/runProcesses.js +52 -19
- package/dist/server/lib/runProcesses.js.map +1 -1
- package/dist/server/lib/runServiceStop.js +62 -0
- package/dist/server/lib/runServiceStop.js.map +1 -0
- package/dist/server/lib/runServices.js +63 -4
- package/dist/server/lib/runServices.js.map +1 -1
- package/dist/server/lib/runSessionLifecycle.js +25 -0
- package/dist/server/lib/runSessionLifecycle.js.map +1 -1
- package/dist/server/lib/runtimePaths.js +7 -4
- package/dist/server/lib/runtimePaths.js.map +1 -1
- package/dist/server/lib/serviceRunLogs.js +180 -0
- package/dist/server/lib/serviceRunLogs.js.map +1 -0
- package/dist/server/lib/sessionTargets.js +35 -2
- package/dist/server/lib/sessionTargets.js.map +1 -1
- package/dist/server/lib/specOperations.js +7 -2
- package/dist/server/lib/specOperations.js.map +1 -1
- package/dist/server/lib/specReviewContext.js +3 -2
- package/dist/server/lib/specReviewContext.js.map +1 -1
- package/dist/server/lib/toolUpgrade.js +54 -5
- package/dist/server/lib/toolUpgrade.js.map +1 -1
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/workers/build.js +47 -9
- package/dist/server/workers/build.js.map +1 -1
- package/dist/server/workers/chat.js +89 -21
- package/dist/server/workers/chat.js.map +1 -1
- package/dist/server/workers/followUp.js +59 -22
- package/dist/server/workers/followUp.js.map +1 -1
- package/dist/server/workers/plan.js +109 -169
- package/dist/server/workers/plan.js.map +1 -1
- package/dist/server/workers/planFollowUp.js +27 -7
- package/dist/server/workers/planFollowUp.js.map +1 -1
- package/dist/server/workers/review.js +43 -10
- package/dist/server/workers/review.js.map +1 -1
- package/dist/server/workers/specReview.js +1 -0
- package/dist/server/workers/specReview.js.map +1 -1
- package/dist/server/workers/specSession.js +42 -5
- package/dist/server/workers/specSession.js.map +1 -1
- package/dist/shared/i18n/locales.js +12 -0
- package/dist/shared/i18n/locales.js.map +1 -0
- package/package.json +1 -1
- package/dist/client/assets/channel-DUX4Nl-Q.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-_vWY0Wm5.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-Boom-t3w.js +0 -1
- package/dist/client/assets/index-D8_nS8Kw.js +0 -287
- package/dist/client/assets/index-RM0FaS4q.css +0 -2
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-DuYuP5AB.js +0 -1
|
@@ -10,9 +10,14 @@ import { resolveExistingWorktreePath } from '../lib/git.js';
|
|
|
10
10
|
import { getModelProvider, normalizeModelId } from '../lib/models.js';
|
|
11
11
|
import { getAgentModelProvider, normalizeAgentModelId, requireExecutableAgent } from '../lib/agentCatalog.js';
|
|
12
12
|
import { codexAgentProvider } from '../lib/codexAgentProvider.js';
|
|
13
|
+
import { opencodeAgentProvider } from '../lib/opencodeAgentProvider.js';
|
|
13
14
|
import { createOpencodeTaskSessionReader, parseOpencodeTaskEnvelope } from '../lib/opencodeTaskSessions.js';
|
|
15
|
+
import { parseOpencodeStreamLine } from '../lib/opencodeStream.js';
|
|
16
|
+
import { parseOpencodeError } from '../lib/opencodeErrors.js';
|
|
14
17
|
import { hostOpencodeSessionOperations } from '../lib/opencodeSessionOperations.js';
|
|
18
|
+
import { getOpencodeCliCompatibility, inspectOpencodeRelease, requireSupportedOpencodeCompatibility } from '../lib/opencodeCli.js';
|
|
15
19
|
import { markRetryableOpenCodeDatabaseLock, RetryableOpenCodeDatabaseLockError, retryOpenCodeDatabaseLocks } from '../lib/opencodeExecutionReliability.js';
|
|
20
|
+
import { appendAgentOutputLanguagePrompt } from '../lib/agentOutputLanguage.js';
|
|
16
21
|
import { appendClaudeHeadlessPlanPrompt, appendPlanModeQuestionPromptRules, buildClaudeHeadlessPlanArgs } from '../lib/planModeQuestions.js';
|
|
17
22
|
import { persistProjectMemorySuggestions } from '../lib/projectMemory.js';
|
|
18
23
|
import { getProjectMemoryPromptBlock } from '../lib/projectMemoryPrompt.js';
|
|
@@ -27,7 +32,8 @@ import { createTicketMessage, upsertTicketDescriptionMessage } from '../lib/tick
|
|
|
27
32
|
import { createAskQuestionMetadata, extractAskQuestionFromOutput, formatAskQuestionMessage } from '../lib/planQuestions.js';
|
|
28
33
|
import { getTicket, resolveTicketBranch, resolveTicketTool, resolveTicketWorkerKey } from '../lib/tickets.js';
|
|
29
34
|
import { createOpencodeSubagentMonitor, createSubagentRunTracker, formatAgentErrorForTranscript, getAgentErrorTranscriptRuns, readOpencodeSessionTranscript, storeTicketUsageSnapshot, storeTicketUsageSnapshotDirect, mergeUsageFromJsonLine, EMPTY_CHAT_USAGE_SNAPSHOT } from '../lib/agent.js';
|
|
30
|
-
import { createAgentRun, emitAgentRunsUpdated, finalizeAgentRun, getAgentRun, getNextAgentRunIndex, terminalizeAgentRunsForExecutionRun, updateAgentRunSessionId } from '../lib/agentRuns.js';
|
|
35
|
+
import { createAgentRun, emitAgentRunsUpdated, finalizeAgentRun, getAgentRun, getNextAgentRunIndex, resolveHistoricalProviderSessionForParent, terminalizeAgentRunsForExecutionRun, updateAgentRunSessionId } from '../lib/agentRuns.js';
|
|
36
|
+
import { shouldStartFreshProviderSession } from '../lib/opencodeSessionProvenance.js';
|
|
31
37
|
import { addExecutionRunLink, createExecutionRun, transitionExecutionRun } from '../lib/executionRuns.js';
|
|
32
38
|
import { assertProviderSessionAuthorityMatches, createExecutionProfileSelectionMetadata } from '../lib/executionRunAuthority.js';
|
|
33
39
|
import { classifyTicketExecutionTarget, resolveExecutionTarget, resolveProjectRootExecutionTarget } from '../lib/executionTargets.js';
|
|
@@ -50,6 +56,7 @@ const plannerExecutionOptions = (options) => ({
|
|
|
50
56
|
executionTarget: options.executionTarget,
|
|
51
57
|
executionLauncherEnvironment: options.executionLauncherEnvironment,
|
|
52
58
|
executionRuntimeEnvironment: options.executionRuntimeEnvironment,
|
|
59
|
+
opencodeRuntimeIdentity: options.opencodeRuntimeIdentity,
|
|
53
60
|
});
|
|
54
61
|
const createPlanningInvocation = (options, label, role) => {
|
|
55
62
|
const parentType = options.agentRunParent?.parentType ?? (options.ticketId ? 'ticket' : options.projectId ? 'planning' : null);
|
|
@@ -116,59 +123,6 @@ const createPlannerRecoveryTracker = () => {
|
|
|
116
123
|
getRecoveredResponse: () => finalAnswerFragments.join('\n\n'),
|
|
117
124
|
};
|
|
118
125
|
};
|
|
119
|
-
const extractLeadingJsonObject = (line) => {
|
|
120
|
-
if (!line.startsWith('{')) {
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
123
|
-
let depth = 0;
|
|
124
|
-
let inString = false;
|
|
125
|
-
let escaping = false;
|
|
126
|
-
for (let index = 0; index < line.length; index += 1) {
|
|
127
|
-
const char = line[index];
|
|
128
|
-
if (inString) {
|
|
129
|
-
if (escaping) {
|
|
130
|
-
escaping = false;
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
if (char === '\\') {
|
|
134
|
-
escaping = true;
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
if (char === '"') {
|
|
138
|
-
inString = false;
|
|
139
|
-
}
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
if (char === '"') {
|
|
143
|
-
inString = true;
|
|
144
|
-
continue;
|
|
145
|
-
}
|
|
146
|
-
if (char === '{') {
|
|
147
|
-
depth += 1;
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
if (char === '}') {
|
|
151
|
-
depth -= 1;
|
|
152
|
-
if (depth === 0) {
|
|
153
|
-
return line.slice(0, index + 1);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return null;
|
|
158
|
-
};
|
|
159
|
-
const extractLeadingJsonObjects = (line) => {
|
|
160
|
-
const jsonObjects = [];
|
|
161
|
-
let remainder = line.trim();
|
|
162
|
-
while (remainder.startsWith('{')) {
|
|
163
|
-
const jsonObject = extractLeadingJsonObject(remainder);
|
|
164
|
-
if (!jsonObject) {
|
|
165
|
-
break;
|
|
166
|
-
}
|
|
167
|
-
jsonObjects.push(jsonObject);
|
|
168
|
-
remainder = remainder.slice(jsonObject.length).trim();
|
|
169
|
-
}
|
|
170
|
-
return { jsonObjects, remainder };
|
|
171
|
-
};
|
|
172
126
|
const normalizeToolName = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
173
127
|
const isPlannerSubagentTool = (name) => {
|
|
174
128
|
const normalized = normalizeToolName(name);
|
|
@@ -384,61 +338,41 @@ const parseClaudePlannerStreamJsonLine = (line) => {
|
|
|
384
338
|
}
|
|
385
339
|
return emptyParsedPlannerStreamLine();
|
|
386
340
|
};
|
|
387
|
-
const formatPlannerOpencodeToolUse = (event, cwd) => {
|
|
388
|
-
const toolName = event.part?.tool;
|
|
389
|
-
if (!toolName) {
|
|
390
|
-
return null;
|
|
391
|
-
}
|
|
392
|
-
return formatPlannerToolCall(toolName, event.part?.state?.input, cwd);
|
|
393
|
-
};
|
|
394
|
-
const formatPlannerStepTitle = (event) => {
|
|
395
|
-
const title = event.part?.title?.trim();
|
|
396
|
-
return title || null;
|
|
397
|
-
};
|
|
398
341
|
const parseOpencodePlannerJsonEvent = (event, cwd) => {
|
|
399
|
-
const providerSessionId = event.
|
|
400
|
-
|| event.sessionId?.trim()
|
|
401
|
-
|| event.part?.sessionID?.trim()
|
|
402
|
-
|| event.part?.sessionId?.trim()
|
|
403
|
-
|| null;
|
|
342
|
+
const providerSessionId = event.sessionId;
|
|
404
343
|
if (event.type === 'subagent_snapshot') {
|
|
405
|
-
const
|
|
406
|
-
? event.part.state.metadata.sessionId
|
|
407
|
-
: null;
|
|
408
|
-
const status = event.part?.state?.status;
|
|
344
|
+
const status = event.tool.status;
|
|
409
345
|
return {
|
|
410
346
|
...emptyParsedPlannerStreamLine(),
|
|
411
347
|
providerSessionId,
|
|
412
348
|
subagentEvents: [{
|
|
413
349
|
kind: 'snapshot',
|
|
414
|
-
callId: event.
|
|
415
|
-
label: event.
|
|
416
|
-
sessionId,
|
|
350
|
+
callId: event.tool.callId,
|
|
351
|
+
label: event.tool.title || 'Subagent',
|
|
352
|
+
sessionId: event.tool.childSessionId,
|
|
417
353
|
status: status === 'error' || status === 'failed'
|
|
418
354
|
? 'error'
|
|
419
355
|
: status === 'stopped' || status === 'interrupted' ? 'stopped' : status === 'running' ? 'running' : 'done',
|
|
420
|
-
log: event.
|
|
421
|
-
response: event.
|
|
356
|
+
log: event.tool.log,
|
|
357
|
+
response: event.tool.response,
|
|
422
358
|
}],
|
|
423
359
|
};
|
|
424
360
|
}
|
|
425
|
-
if (event.type === 'plan' && event.
|
|
361
|
+
if (event.type === 'plan' && event.text) {
|
|
426
362
|
return {
|
|
427
|
-
logFragment: event.
|
|
363
|
+
logFragment: event.text,
|
|
428
364
|
responseFragment: null,
|
|
429
365
|
subagentEvents: [],
|
|
430
366
|
providerSessionId,
|
|
431
|
-
concatenateFragments: event.
|
|
432
|
-
replaceFragment: event.
|
|
433
|
-
fragmentGroup: event.
|
|
434
|
-
?? event.part.metadata?.codex?.itemId
|
|
435
|
-
?? null,
|
|
367
|
+
concatenateFragments: event.metadata.delta,
|
|
368
|
+
replaceFragment: event.metadata.snapshot,
|
|
369
|
+
fragmentGroup: event.metadata.fragmentGroup ?? event.metadata.itemId,
|
|
436
370
|
};
|
|
437
371
|
}
|
|
438
|
-
if (event.type === 'text' && event.
|
|
439
|
-
const concatenateFragments = event.
|
|
440
|
-
const text = concatenateFragments ? event.
|
|
441
|
-
const phase = event.
|
|
372
|
+
if (event.type === 'text' && event.text) {
|
|
373
|
+
const concatenateFragments = event.metadata.delta;
|
|
374
|
+
const text = concatenateFragments ? event.text : event.text.trim();
|
|
375
|
+
const phase = event.metadata.phase;
|
|
442
376
|
return {
|
|
443
377
|
logFragment: text || null,
|
|
444
378
|
responseFragment: text && (!phase || phase === 'final_answer') ? text : null,
|
|
@@ -449,38 +383,32 @@ const parseOpencodePlannerJsonEvent = (event, cwd) => {
|
|
|
449
383
|
? [{ type: 'final_answer', text }]
|
|
450
384
|
: [],
|
|
451
385
|
concatenateFragments,
|
|
452
|
-
fragmentGroup: event.
|
|
453
|
-
?? event.part.metadata?.codex?.itemId
|
|
454
|
-
?? null,
|
|
386
|
+
fragmentGroup: event.metadata.fragmentGroup ?? event.metadata.itemId,
|
|
455
387
|
};
|
|
456
388
|
}
|
|
457
|
-
if (event.type === 'reasoning'
|
|
458
|
-
const concatenateFragments = event.
|
|
459
|
-
const text = concatenateFragments ? event.
|
|
389
|
+
if (event.type === 'reasoning') {
|
|
390
|
+
const concatenateFragments = event.metadata.delta;
|
|
391
|
+
const text = concatenateFragments ? event.text : event.text.trim();
|
|
460
392
|
return {
|
|
461
393
|
logFragment: text || null,
|
|
462
394
|
responseFragment: null,
|
|
463
395
|
subagentEvents: [],
|
|
464
396
|
providerSessionId,
|
|
465
397
|
concatenateFragments,
|
|
466
|
-
fragmentGroup: event.
|
|
467
|
-
?? event.part.metadata?.codex?.itemId
|
|
468
|
-
?? null,
|
|
398
|
+
fragmentGroup: event.metadata.fragmentGroup ?? event.metadata.itemId,
|
|
469
399
|
};
|
|
470
400
|
}
|
|
471
|
-
if (event.type === '
|
|
472
|
-
const isToolInvocation = event.type === '
|
|
473
|
-
const toolName = event.
|
|
401
|
+
if (event.type === 'tool_use' || event.type === 'tool_result') {
|
|
402
|
+
const isToolInvocation = event.type === 'tool_use';
|
|
403
|
+
const toolName = event.tool.name;
|
|
474
404
|
if (toolName && isPlannerSubagentTool(toolName)) {
|
|
475
|
-
const description = getPlannerSubagentDescription(event.
|
|
476
|
-
const rawOutput = event.
|
|
405
|
+
const description = getPlannerSubagentDescription(event.tool.input, toolName);
|
|
406
|
+
const rawOutput = event.tool.output?.trim();
|
|
477
407
|
const envelope = parseOpencodeTaskEnvelope(rawOutput);
|
|
478
408
|
const output = envelope?.result ?? rawOutput;
|
|
479
|
-
const taskStatus = event.
|
|
409
|
+
const taskStatus = event.tool.status?.toLowerCase() ?? envelope?.state?.toLowerCase();
|
|
480
410
|
const isTerminal = Boolean(taskStatus && taskStatus !== 'running' && taskStatus !== 'pending');
|
|
481
|
-
const childSessionId = envelope?.childSessionId
|
|
482
|
-
?? (typeof event.part?.state?.metadata?.sessionID === 'string' ? event.part.state.metadata.sessionID : null)
|
|
483
|
-
?? (typeof event.part?.state?.metadata?.sessionId === 'string' ? event.part.state.metadata.sessionId : null);
|
|
411
|
+
const childSessionId = envelope?.childSessionId ?? event.tool.childSessionId;
|
|
484
412
|
return {
|
|
485
413
|
logFragment: isToolInvocation ? `Subagent: ${description}` : null,
|
|
486
414
|
responseFragment: null,
|
|
@@ -488,7 +416,7 @@ const parseOpencodePlannerJsonEvent = (event, cwd) => {
|
|
|
488
416
|
...(isToolInvocation
|
|
489
417
|
? [{
|
|
490
418
|
kind: 'start',
|
|
491
|
-
callId: event.
|
|
419
|
+
callId: event.tool.callId,
|
|
492
420
|
label: `Subagent: ${description}`,
|
|
493
421
|
sessionId: childSessionId,
|
|
494
422
|
}]
|
|
@@ -496,7 +424,7 @@ const parseOpencodePlannerJsonEvent = (event, cwd) => {
|
|
|
496
424
|
...(output || isTerminal
|
|
497
425
|
? [{
|
|
498
426
|
kind: isTerminal ? 'complete' : 'fragment',
|
|
499
|
-
callId: event.
|
|
427
|
+
callId: event.tool.callId,
|
|
500
428
|
label: `Subagent: ${description}`,
|
|
501
429
|
...(output ? { text: output } : {}),
|
|
502
430
|
sessionId: childSessionId,
|
|
@@ -513,7 +441,7 @@ const parseOpencodePlannerJsonEvent = (event, cwd) => {
|
|
|
513
441
|
return { ...emptyParsedPlannerStreamLine(), providerSessionId };
|
|
514
442
|
}
|
|
515
443
|
return {
|
|
516
|
-
logFragment:
|
|
444
|
+
logFragment: formatPlannerToolCall(toolName, event.tool.input, cwd),
|
|
517
445
|
responseFragment: null,
|
|
518
446
|
subagentEvents: [],
|
|
519
447
|
providerSessionId,
|
|
@@ -521,19 +449,14 @@ const parseOpencodePlannerJsonEvent = (event, cwd) => {
|
|
|
521
449
|
}
|
|
522
450
|
if (event.type === 'step_start') {
|
|
523
451
|
return {
|
|
524
|
-
logFragment:
|
|
452
|
+
logFragment: event.title,
|
|
525
453
|
responseFragment: null,
|
|
526
454
|
subagentEvents: [],
|
|
527
455
|
providerSessionId,
|
|
528
456
|
};
|
|
529
457
|
}
|
|
530
458
|
if (event.type === 'error') {
|
|
531
|
-
const
|
|
532
|
-
? event.error.trim()
|
|
533
|
-
: event.error?.data?.message?.trim()
|
|
534
|
-
|| event.error?.message?.trim()
|
|
535
|
-
|| (event.error ? JSON.stringify(event.error) : '');
|
|
536
|
-
const text = event.part?.text?.trim() || errorText;
|
|
459
|
+
const text = parseOpencodeError(event.error, event.fallbackText ?? undefined)?.message ?? '';
|
|
537
460
|
return {
|
|
538
461
|
logFragment: text ? `**Error:** ${text}` : null,
|
|
539
462
|
responseFragment: null,
|
|
@@ -549,8 +472,9 @@ const parseOpencodePlannerJsonLine = (line, cwd) => {
|
|
|
549
472
|
if (!trimmedLine) {
|
|
550
473
|
return emptyParsedPlannerStreamLine();
|
|
551
474
|
}
|
|
552
|
-
const
|
|
553
|
-
|
|
475
|
+
const normalizedLine = parseOpencodeStreamLine(trimmedLine);
|
|
476
|
+
const { events, remainder } = normalizedLine;
|
|
477
|
+
if (!normalizedLine.structured) {
|
|
554
478
|
if (trimmedLine.startsWith('{')) {
|
|
555
479
|
return emptyParsedPlannerStreamLine();
|
|
556
480
|
}
|
|
@@ -578,14 +502,7 @@ const parseOpencodePlannerJsonLine = (line, cwd) => {
|
|
|
578
502
|
let concatenateFragments;
|
|
579
503
|
let replaceFragment;
|
|
580
504
|
let fragmentGroup;
|
|
581
|
-
for (const
|
|
582
|
-
let event;
|
|
583
|
-
try {
|
|
584
|
-
event = JSON.parse(jsonObject);
|
|
585
|
-
}
|
|
586
|
-
catch {
|
|
587
|
-
continue;
|
|
588
|
-
}
|
|
505
|
+
for (const event of events) {
|
|
589
506
|
const parsedEvent = parseOpencodePlannerJsonEvent(event, cwd);
|
|
590
507
|
const eventRecoveryEvents = parsedEvent.recoveryEvents ?? [];
|
|
591
508
|
if (eventRecoveryEvents.some(recoveryEvent => recoveryEvent.type === 'error')) {
|
|
@@ -601,7 +518,7 @@ const parseOpencodePlannerJsonLine = (line, cwd) => {
|
|
|
601
518
|
recoveryEvents.push(...eventRecoveryEvents);
|
|
602
519
|
providerSessionId = providerSessionId ?? parsedEvent.providerSessionId;
|
|
603
520
|
hasFinalAnswer ||= parsedEvent.hasFinalAnswer === true;
|
|
604
|
-
if (
|
|
521
|
+
if (events.length === 1) {
|
|
605
522
|
concatenateFragments = parsedEvent.concatenateFragments;
|
|
606
523
|
replaceFragment = parsedEvent.replaceFragment;
|
|
607
524
|
fragmentGroup = parsedEvent.fragmentGroup;
|
|
@@ -672,10 +589,6 @@ const MEMORY_SUGGESTION_RULES = [
|
|
|
672
589
|
const getPlanningMemorySuggestionRules = (memoryEnabled) => {
|
|
673
590
|
return memoryEnabled ? MEMORY_SUGGESTION_RULES : '';
|
|
674
591
|
};
|
|
675
|
-
const ENGLISH_OUTPUT_RULES = [
|
|
676
|
-
'- Always write the output in English regardless of the language used in the source description, ticket, or linked materials.',
|
|
677
|
-
'- Translate or restate non-English input into clear natural English for titles, summaries, descriptions, constraints, acceptance criteria, implementation steps, and open questions.',
|
|
678
|
-
].join('\n');
|
|
679
592
|
const EXPANDED_TICKET_EXAMPLE = [
|
|
680
593
|
'{',
|
|
681
594
|
' "key": "header-hello-world",',
|
|
@@ -810,7 +723,7 @@ Primary implementation scope:
|
|
|
810
723
|
Linked project findings:
|
|
811
724
|
${researchBlocks}`;
|
|
812
725
|
};
|
|
813
|
-
const buildPlanPrompt = (title, description, linkedResearchContext = '') => `You are helping plan a software development ticket. Based on the title and brief description below, write a detailed ticket description that is specific enough for a separate AI agent to implement the feature end-to-end without needing any further context or clarification.
|
|
726
|
+
const buildPlanPrompt = (title, description, linkedResearchContext = '') => appendAgentOutputLanguagePrompt(`You are helping plan a software development ticket. Based on the title and brief description below, write a detailed ticket description that is specific enough for a separate AI agent to implement the feature end-to-end without needing any further context or clarification.
|
|
814
727
|
|
|
815
728
|
Include:
|
|
816
729
|
${IMPLEMENTATION_READY_DESCRIPTION_REQUIREMENTS}
|
|
@@ -822,15 +735,13 @@ Brief description: ${description}
|
|
|
822
735
|
${linkedResearchContext}
|
|
823
736
|
|
|
824
737
|
Additional rules:
|
|
825
|
-
- Language rules:
|
|
826
|
-
${ENGLISH_OUTPUT_RULES}
|
|
827
738
|
- The downstream build agent will only work in the active project repo.
|
|
828
739
|
- If linked-project findings are relevant, embed the required external contract details directly in the ticket.
|
|
829
740
|
- Do not instruct the implementer to inspect linked projects or linked files.
|
|
830
741
|
- Preserve any user-provided URLs, Figma links, docs, tickets, or other external resources that are needed during implementation.
|
|
831
742
|
- Include those resources verbatim in the final ticket description instead of replacing them with vague summaries.
|
|
832
743
|
|
|
833
|
-
Write only the expanded description in markdown, formatted to be readable by both humans and agents. No preamble or meta-commentary
|
|
744
|
+
Write only the expanded description in markdown, formatted to be readable by both humans and agents. No preamble or meta-commentary.`);
|
|
834
745
|
const buildSingleTicketPrompt = (title, description, linkedResearchContext = '', projectMemoryBlock = '', memoryEnabled = false, interactiveQuestions = false) => {
|
|
835
746
|
const prompt = `You are helping plan a single software development ticket.
|
|
836
747
|
|
|
@@ -858,8 +769,6 @@ Rules:
|
|
|
858
769
|
- Use the key \`main-ticket\`.
|
|
859
770
|
- Use the provided title exactly.
|
|
860
771
|
- Return an empty dependencies array.
|
|
861
|
-
- Language rules:
|
|
862
|
-
${ENGLISH_OUTPUT_RULES}
|
|
863
772
|
- The description must be valid markdown and include:
|
|
864
773
|
${IMPLEMENTATION_READY_DESCRIPTION_REQUIREMENTS}
|
|
865
774
|
${INDENTED_IMPLEMENTATION_READY_DESCRIPTION_SECTION_TEMPLATE}
|
|
@@ -877,7 +786,6 @@ ${IMPLEMENTATION_BODY_DEDUPLICATION_RULES}
|
|
|
877
786
|
${PLANNING_QUESTIONS_RULES}
|
|
878
787
|
- Memory suggestion rules:${getPlanningMemorySuggestionRules(memoryEnabled) ? `
|
|
879
788
|
${getPlanningMemorySuggestionRules(memoryEnabled)}` : ' Omit memory suggestions entirely when project memory is disabled.'}
|
|
880
|
-
- Write the natural-language update in English.
|
|
881
789
|
- Keep the natural-language update to 1-3 short sentences focused on what changed in the plan.
|
|
882
790
|
- Wrap the JSON object in <archon-plan-output>...</archon-plan-output> tags after the natural-language update.
|
|
883
791
|
- Do not wrap the JSON in markdown fences.
|
|
@@ -889,9 +797,10 @@ ${projectMemoryBlock ? `${projectMemoryBlock}
|
|
|
889
797
|
|
|
890
798
|
` : ''}
|
|
891
799
|
${linkedResearchContext}`;
|
|
892
|
-
|
|
800
|
+
const languagePrompt = appendAgentOutputLanguagePrompt(prompt);
|
|
801
|
+
return interactiveQuestions ? appendPlanModeQuestionPromptRules(languagePrompt) : languagePrompt;
|
|
893
802
|
};
|
|
894
|
-
const buildPlanningAgentOutlinePrompt = (description, linkedResearchContext = '', projectMemoryBlock = '') => `You are helping break down a software development initiative into implementation tickets for a kanban board.
|
|
803
|
+
const buildPlanningAgentOutlinePrompt = (description, linkedResearchContext = '', projectMemoryBlock = '') => appendAgentOutputLanguagePrompt(`You are helping break down a software development initiative into implementation tickets for a kanban board.
|
|
895
804
|
|
|
896
805
|
This is pass 1 of 2. Your job is to decide the best ticket split and dependency graph, not to fully expand implementation details yet.
|
|
897
806
|
|
|
@@ -928,8 +837,6 @@ Rules:
|
|
|
928
837
|
- Each ticket should be independently actionable and belong in the plan column.
|
|
929
838
|
- Prefer the smallest useful number of tickets that still separates major implementation concerns cleanly.
|
|
930
839
|
- Do not write full implementation-ready descriptions yet.
|
|
931
|
-
- Language rules:
|
|
932
|
-
${ENGLISH_OUTPUT_RULES}
|
|
933
840
|
- For each ticket, include:
|
|
934
841
|
${OUTLINE_DETAIL_REQUIREMENTS}
|
|
935
842
|
- Use stable unique keys in kebab-case.
|
|
@@ -948,8 +855,8 @@ ${description}
|
|
|
948
855
|
${projectMemoryBlock ? `${projectMemoryBlock}
|
|
949
856
|
|
|
950
857
|
` : ''}
|
|
951
|
-
${linkedResearchContext}
|
|
952
|
-
const buildPlanningAgentExpansionPrompt = (description, outline, linkedResearchContext = '', projectMemoryBlock = '') => `You are helping expand a previously decomposed software development initiative into implementation-ready tickets for a kanban board.
|
|
858
|
+
${linkedResearchContext}`);
|
|
859
|
+
const buildPlanningAgentExpansionPrompt = (description, outline, linkedResearchContext = '', projectMemoryBlock = '') => appendAgentOutputLanguagePrompt(`You are helping expand a previously decomposed software development initiative into implementation-ready tickets for a kanban board.
|
|
953
860
|
|
|
954
861
|
Each generated ticket will later be implemented by a separate AI agent, so every ticket description must be self-contained and implementation-ready without needing any further context or clarification.
|
|
955
862
|
|
|
@@ -987,8 +894,6 @@ Rules:
|
|
|
987
894
|
- Preserve every ticket key exactly as provided.
|
|
988
895
|
- Preserve every ticket title exactly as provided.
|
|
989
896
|
- Preserve the dependency list exactly as provided.
|
|
990
|
-
- Language rules:
|
|
991
|
-
${ENGLISH_OUTPUT_RULES}
|
|
992
897
|
- Each description must be valid markdown and include:
|
|
993
898
|
${IMPLEMENTATION_READY_DESCRIPTION_REQUIREMENTS}
|
|
994
899
|
${INDENTED_IMPLEMENTATION_READY_DESCRIPTION_SECTION_TEMPLATE}
|
|
@@ -1016,7 +921,7 @@ ${description}
|
|
|
1016
921
|
${linkedResearchContext}
|
|
1017
922
|
|
|
1018
923
|
Outline to expand:
|
|
1019
|
-
${JSON.stringify(outline, null, 2)}
|
|
924
|
+
${JSON.stringify(outline, null, 2)}`);
|
|
1020
925
|
const resolvePlannerCwd = (project, branch) => {
|
|
1021
926
|
if (!project) {
|
|
1022
927
|
return undefined;
|
|
@@ -1098,9 +1003,23 @@ const runPlannerPromptOnce = (tool, model, variant, prompt, cwd, options = {}) =
|
|
|
1098
1003
|
? appendClaudeHeadlessPlanPrompt(prompt)
|
|
1099
1004
|
: prompt;
|
|
1100
1005
|
const sessionTracking = options.sessionTracking;
|
|
1006
|
+
const sessionDirectory = cwd ?? process.cwd();
|
|
1101
1007
|
const opencodeSessionOperations = options.executionProvider
|
|
1102
1008
|
? options.executionProvider.sessionOperations.opencode
|
|
1103
1009
|
: hostOpencodeSessionOperations;
|
|
1010
|
+
const resolvedOpencodeCompatibility = (() => {
|
|
1011
|
+
if (tool !== 'opencode') {
|
|
1012
|
+
return null;
|
|
1013
|
+
}
|
|
1014
|
+
if (options.executionProvider?.kind === 'docker_sandbox') {
|
|
1015
|
+
if (!options.opencodeRuntimeIdentity) {
|
|
1016
|
+
throw new Error('The selected OpenCode execution environment has no validated runtime compatibility.');
|
|
1017
|
+
}
|
|
1018
|
+
return requireSupportedOpencodeCompatibility(inspectOpencodeRelease(options.opencodeRuntimeIdentity.version));
|
|
1019
|
+
}
|
|
1020
|
+
return requireSupportedOpencodeCompatibility(getOpencodeCliCompatibility({ force: true }));
|
|
1021
|
+
})();
|
|
1022
|
+
const resolvedOpencodeRuntimeIdentity = resolvedOpencodeCompatibility?.runtimeIdentity ?? null;
|
|
1104
1023
|
let sessionId = null;
|
|
1105
1024
|
let spawnTimestamp = null;
|
|
1106
1025
|
let sessionLookupTimer = null;
|
|
@@ -1140,21 +1059,21 @@ const runPlannerPromptOnce = (tool, model, variant, prompt, cwd, options = {}) =
|
|
|
1140
1059
|
});
|
|
1141
1060
|
return [invocation.command, [...invocation.args], invocation.stdio];
|
|
1142
1061
|
})()
|
|
1143
|
-
:
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
'
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
[
|
|
1157
|
-
|
|
1062
|
+
: (() => {
|
|
1063
|
+
const invocation = opencodeAgentProvider.buildStreamingInvocation({
|
|
1064
|
+
cwd: cwd ?? process.cwd(),
|
|
1065
|
+
prompt: finalPrompt,
|
|
1066
|
+
model: resolvedModel || null,
|
|
1067
|
+
variant,
|
|
1068
|
+
skills: options.skills,
|
|
1069
|
+
mode: 'plan',
|
|
1070
|
+
resumeSessionId: sessionTracking?.resumeSessionId ?? null,
|
|
1071
|
+
sessionId: randomUUID(),
|
|
1072
|
+
opencodeRuntimeIdentity: resolvedOpencodeRuntimeIdentity,
|
|
1073
|
+
opencodeCompatibility: resolvedOpencodeCompatibility,
|
|
1074
|
+
});
|
|
1075
|
+
return [invocation.command, [...invocation.args], invocation.stdio];
|
|
1076
|
+
})();
|
|
1158
1077
|
return new Promise((resolve, reject) => {
|
|
1159
1078
|
let settled = false;
|
|
1160
1079
|
let completionForced = false;
|
|
@@ -1169,6 +1088,7 @@ const runPlannerPromptOnce = (tool, model, variant, prompt, cwd, options = {}) =
|
|
|
1169
1088
|
executionContext: options.executionContext,
|
|
1170
1089
|
mainRun: options.mainRun,
|
|
1171
1090
|
deferMainFinalization: Boolean(options.mainRun),
|
|
1091
|
+
opencodeRuntimeIdentity: resolvedOpencodeRuntimeIdentity,
|
|
1172
1092
|
})
|
|
1173
1093
|
: null;
|
|
1174
1094
|
let opencodeSubagentMonitor = null;
|
|
@@ -1207,12 +1127,13 @@ const runPlannerPromptOnce = (tool, model, variant, prompt, cwd, options = {}) =
|
|
|
1207
1127
|
if (!normalized) {
|
|
1208
1128
|
return;
|
|
1209
1129
|
}
|
|
1130
|
+
const sessionChanged = resolvedSessionId !== normalized;
|
|
1210
1131
|
resolvedSessionId = normalized;
|
|
1211
1132
|
opencodeSubagentMonitor?.setParentSessionId(normalized);
|
|
1212
1133
|
if (options.mainRun) {
|
|
1213
|
-
updateAgentRunSessionId(options.mainRun.id, normalized);
|
|
1134
|
+
updateAgentRunSessionId(options.mainRun.id, normalized, resolvedOpencodeRuntimeIdentity);
|
|
1214
1135
|
}
|
|
1215
|
-
if (sessionTracking && !hasResolvedSessionId) {
|
|
1136
|
+
if (sessionTracking && (!hasResolvedSessionId || sessionChanged)) {
|
|
1216
1137
|
hasResolvedSessionId = true;
|
|
1217
1138
|
updatePlanningSessionId(sessionTracking.ticketId, normalized, tool, sessionTracking.io, opencodeSessionOperations ?? undefined);
|
|
1218
1139
|
}
|
|
@@ -1222,7 +1143,7 @@ const runPlannerPromptOnce = (tool, model, variant, prompt, cwd, options = {}) =
|
|
|
1222
1143
|
return false;
|
|
1223
1144
|
}
|
|
1224
1145
|
try {
|
|
1225
|
-
const session = await opencodeSessionOperations.findLatestSessionAfter(spawnTimestamp ?? 0,
|
|
1146
|
+
const session = await opencodeSessionOperations.findLatestSessionAfter(spawnTimestamp ?? 0, { directory: sessionDirectory });
|
|
1226
1147
|
if (!hasResolvedSessionId && session?.id) {
|
|
1227
1148
|
bindResolvedProviderSession(session.id);
|
|
1228
1149
|
}
|
|
@@ -1330,7 +1251,7 @@ const runPlannerPromptOnce = (tool, model, variant, prompt, cwd, options = {}) =
|
|
|
1330
1251
|
bindResolvedProviderSession(discoveredSessionId);
|
|
1331
1252
|
},
|
|
1332
1253
|
taskSessionReader: opencodeSessionOperations
|
|
1333
|
-
? createOpencodeTaskSessionReader(opencodeSessionOperations)
|
|
1254
|
+
? createOpencodeTaskSessionReader(opencodeSessionOperations, { directory: sessionDirectory })
|
|
1334
1255
|
: null,
|
|
1335
1256
|
});
|
|
1336
1257
|
opencodeSubagentMonitor.start();
|
|
@@ -2021,6 +1942,7 @@ export const prepareLinkedPlanningResearch = async (taskDescription, options = {
|
|
|
2021
1942
|
executionTarget,
|
|
2022
1943
|
executionLauncherEnvironment: childEnvironment.launcherEnvironment,
|
|
2023
1944
|
executionRuntimeEnvironment: childEnvironment.runtimeEnvironment,
|
|
1945
|
+
opencodeRuntimeIdentity: childEnvironment.opencodeRuntimeIdentity ?? null,
|
|
2024
1946
|
...(invocation ? { mainRun: invocation } : {}),
|
|
2025
1947
|
});
|
|
2026
1948
|
const result = normalizeLinkedResearchResponse(extractFirstJsonObject(output), linkedProject, request);
|
|
@@ -2353,7 +2275,24 @@ export const startPlan = (ticket, io, options = {}) => {
|
|
|
2353
2275
|
workload: 'plan',
|
|
2354
2276
|
signal: cancellationState.abortController?.signal,
|
|
2355
2277
|
});
|
|
2356
|
-
|
|
2278
|
+
let planningSessionId = options.providerContinuation === 'fresh' ? null : ticket.planning_session_id;
|
|
2279
|
+
const historicalProviderSession = planningSessionId
|
|
2280
|
+
? resolveHistoricalProviderSessionForParent({
|
|
2281
|
+
projectId: project.id,
|
|
2282
|
+
currentExecutionRunId: executionContext.runId,
|
|
2283
|
+
parentType: 'ticket',
|
|
2284
|
+
parentId: ticket.id,
|
|
2285
|
+
sessionId: planningSessionId,
|
|
2286
|
+
})
|
|
2287
|
+
: null;
|
|
2288
|
+
if (shouldStartFreshProviderSession({
|
|
2289
|
+
tool: runTool,
|
|
2290
|
+
sessionId: planningSessionId,
|
|
2291
|
+
historicalRuntimeIdentity: historicalProviderSession?.runtimeIdentity ?? null,
|
|
2292
|
+
currentRuntimeIdentity: workloadEnvironment.opencodeRuntimeIdentity ?? null,
|
|
2293
|
+
})) {
|
|
2294
|
+
planningSessionId = null;
|
|
2295
|
+
}
|
|
2357
2296
|
if (planningSessionId) {
|
|
2358
2297
|
assertProviderSessionAuthorityMatches({
|
|
2359
2298
|
projectId: project.id,
|
|
@@ -2383,6 +2322,7 @@ export const startPlan = (ticket, io, options = {}) => {
|
|
|
2383
2322
|
executionTarget,
|
|
2384
2323
|
executionLauncherEnvironment: workloadEnvironment.launcherEnvironment,
|
|
2385
2324
|
executionRuntimeEnvironment: workloadEnvironment.runtimeEnvironment,
|
|
2325
|
+
opencodeRuntimeIdentity: workloadEnvironment.opencodeRuntimeIdentity ?? null,
|
|
2386
2326
|
onProgress: progress => {
|
|
2387
2327
|
updatePlanningProgress(ticket.id, progress.log, progress.response, io);
|
|
2388
2328
|
},
|