@straiffi/archon 1.10.7 → 1.10.9
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/dist/client/assets/{ActivityView-CZdw9ypU.js → ActivityView-CKvbDXeA.js} +1 -1
- package/dist/client/assets/{GitHubActionsDialog-C4xENL_U.js → GitHubActionsDialog-Dzo0vtak.js} +1 -1
- package/dist/client/assets/{VerificationDialog-Bl63STnx.js → VerificationDialog-BJnOitrJ.js} +1 -1
- package/dist/client/assets/{architectureDiagram-3BPJPVTR-B-Dbav9P.js → architectureDiagram-3BPJPVTR-BAIGV9Mj.js} +1 -1
- package/dist/client/assets/{blockDiagram-GPEHLZMM-V8QgIP4y.js → blockDiagram-GPEHLZMM-B-5v5jSZ.js} +1 -1
- package/dist/client/assets/{c4Diagram-AAUBKEIU-CK1CFah9.js → c4Diagram-AAUBKEIU-C6wU415o.js} +1 -1
- package/dist/client/assets/channel-5mIy7nm1.js +1 -0
- package/dist/client/assets/{chunk-2J33WTMH-DebzCgcQ.js → chunk-2J33WTMH-COmvX2tP.js} +1 -1
- package/dist/client/assets/{chunk-3OPIFGDE-iAUuccWS.js → chunk-3OPIFGDE-BlANptdY.js} +1 -1
- package/dist/client/assets/{chunk-5ZQYHXKU-DeuVJv0c.js → chunk-5ZQYHXKU-ETyA2_GU.js} +1 -1
- package/dist/client/assets/{chunk-727SXJPM-C6mHzmPL.js → chunk-727SXJPM-D5-DudwF.js} +1 -1
- package/dist/client/assets/{chunk-AQP2D5EJ-D_qASYNv.js → chunk-AQP2D5EJ-k1AJ4sA3.js} +1 -1
- package/dist/client/assets/{chunk-CSCIHK7Q-rSaGnDPo.js → chunk-CSCIHK7Q-jfksXwY9.js} +1 -1
- package/dist/client/assets/{chunk-KSCS5N6A-CFmDkyBp.js → chunk-KSCS5N6A-CHj0FDj9.js} +1 -1
- package/dist/client/assets/{chunk-L5ZTLDWV-Bxoonz0d.js → chunk-L5ZTLDWV-1ODGxXhG.js} +1 -1
- package/dist/client/assets/{chunk-LZXEDZCA-DVwYlvwm.js → chunk-LZXEDZCA-Bgh9X2W0.js} +2 -2
- package/dist/client/assets/{chunk-ND2GUHAM-CrYlkN7l.js → chunk-ND2GUHAM-DDkb3sp4.js} +1 -1
- package/dist/client/assets/{chunk-NZK2D7GU-B3F5DD0o.js → chunk-NZK2D7GU-B6B8PZ_-.js} +1 -1
- package/dist/client/assets/{chunk-O5CBEL6O-6Yr7XpqV.js → chunk-O5CBEL6O-DhiUIFgj.js} +1 -1
- package/dist/client/assets/{chunk-WU5MYG2G-CXpOzbd6.js → chunk-WU5MYG2G-Dzd0fbP3.js} +1 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-BiQ-X2Sg.js +1 -0
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CF-wCYW-.js +1 -0
- package/dist/client/assets/{dagre-BM42HDAG-B5BJffrd.js → dagre-BM42HDAG-DoNDMCXI.js} +1 -1
- package/dist/client/assets/{diagram-2AECGRRQ-C4DOfy9O.js → diagram-2AECGRRQ-ETDXSa5q.js} +1 -1
- package/dist/client/assets/{diagram-5GNKFQAL-CC0n3BGG.js → diagram-5GNKFQAL-CgTUep7e.js} +1 -1
- package/dist/client/assets/{diagram-KO2AKTUF-CRzcdj4F.js → diagram-KO2AKTUF-BKTx2iRe.js} +1 -1
- package/dist/client/assets/{diagram-LMA3HP47-DsJtR4ne.js → diagram-LMA3HP47-9iEiScHT.js} +1 -1
- package/dist/client/assets/{diagram-OG6HWLK6-DrY7fZ_a.js → diagram-OG6HWLK6-UIZRh7Qa.js} +1 -1
- package/dist/client/assets/{erDiagram-TEJ5UH35-qYLRrYyX.js → erDiagram-TEJ5UH35-BpNJmJva.js} +1 -1
- package/dist/client/assets/{flowDiagram-I6XJVG4X-DZwnzJns.js → flowDiagram-I6XJVG4X-C-rK0XZ1.js} +1 -1
- package/dist/client/assets/{ganttDiagram-6RSMTGT7-f4AoXkmX.js → ganttDiagram-6RSMTGT7-DWyfPvv_.js} +1 -1
- package/dist/client/assets/{gitGraphDiagram-PVQCEYII-_CHXhrED.js → gitGraphDiagram-PVQCEYII-x71bzdc_.js} +1 -1
- package/dist/client/assets/index-CIAO5aE_.css +2 -0
- package/dist/client/assets/index-nCGyalrn.js +276 -0
- package/dist/client/assets/{infoDiagram-5YYISTIA-DPN-bmpB.js → infoDiagram-5YYISTIA-CbRus0Xu.js} +1 -1
- package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-D4y7nv2X.js → ishikawaDiagram-YF4QCWOH-DvaMHrgN.js} +1 -1
- package/dist/client/assets/{journeyDiagram-JHISSGLW-BqU9b2Ls.js → journeyDiagram-JHISSGLW-BQBu4YGn.js} +1 -1
- package/dist/client/assets/{kanban-definition-UN3LZRKU-B3Ff_dpA.js → kanban-definition-UN3LZRKU-8rU-U7L1.js} +1 -1
- package/dist/client/assets/{line-Jpug3yeg.js → line-CSZnwjLA.js} +1 -1
- package/dist/client/assets/{mermaid-parser.core-BIMhUApg.js → mermaid-parser.core-CTOl2slE.js} +1 -1
- package/dist/client/assets/{mermaid.core-Bksciss2.js → mermaid.core-B9gr0Vqf.js} +3 -3
- package/dist/client/assets/{mindmap-definition-RKZ34NQL-D4jePVLd.js → mindmap-definition-RKZ34NQL-But1_PWQ.js} +1 -1
- package/dist/client/assets/{pieDiagram-4H26LBE5-DVizXBtA.js → pieDiagram-4H26LBE5-CnlVmfSG.js} +1 -1
- package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Daakxhvx.js → quadrantDiagram-W4KKPZXB-Dww1ZGuR.js} +1 -1
- package/dist/client/assets/{requirementDiagram-4Y6WPE33-CLcCdr6S.js → requirementDiagram-4Y6WPE33-CNf_loe8.js} +1 -1
- package/dist/client/assets/{sankeyDiagram-5OEKKPKP-DNrYDsXq.js → sankeyDiagram-5OEKKPKP-DBhi37Jj.js} +1 -1
- package/dist/client/assets/{sequenceDiagram-3UESZ5HK-B09pYUTV.js → sequenceDiagram-3UESZ5HK-B64hb4E4.js} +1 -1
- package/dist/client/assets/{stateDiagram-AJRCARHV-B8xFgv9d.js → stateDiagram-AJRCARHV-DcS6oB-S.js} +1 -1
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-PWeeL0tR.js +1 -0
- package/dist/client/assets/{timeline-definition-PNZ67QCA-BheFMJuC.js → timeline-definition-PNZ67QCA-Dq-4tXfh.js} +1 -1
- package/dist/client/assets/{vennDiagram-CIIHVFJN-wEvykl0Z.js → vennDiagram-CIIHVFJN-CeDklSE_.js} +1 -1
- package/dist/client/assets/{wardleyDiagram-YWT4CUSO-GXXHVTTa.js → wardleyDiagram-YWT4CUSO-D2cJISMm.js} +1 -1
- package/dist/client/assets/{xychartDiagram-2RQKCTM6-BIR4svhm.js → xychartDiagram-2RQKCTM6-CBF-tTpF.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/server/db.js +12 -2
- package/dist/server/db.js.map +1 -1
- package/dist/server/index.js +94 -23
- package/dist/server/index.js.map +1 -1
- package/dist/server/lib/agent.js +35 -6
- package/dist/server/lib/agent.js.map +1 -1
- package/dist/server/lib/agentRuns.js +15 -0
- package/dist/server/lib/agentRuns.js.map +1 -1
- package/dist/server/lib/automationDeliveryDecision.js +34 -0
- package/dist/server/lib/automationDeliveryDecision.js.map +1 -0
- package/dist/server/lib/automationProgression.js +5 -2
- package/dist/server/lib/automationProgression.js.map +1 -1
- package/dist/server/lib/boundedProcess.js +129 -0
- package/dist/server/lib/boundedProcess.js.map +1 -0
- package/dist/server/lib/bundleReviewOperations.js +7 -0
- package/dist/server/lib/bundleReviewOperations.js.map +1 -1
- package/dist/server/lib/chatOperations.js +140 -1
- package/dist/server/lib/chatOperations.js.map +1 -1
- package/dist/server/lib/chats.js +34 -2
- package/dist/server/lib/chats.js.map +1 -1
- package/dist/server/lib/conversationResume.js +152 -0
- package/dist/server/lib/conversationResume.js.map +1 -0
- package/dist/server/lib/git.js +89 -48
- package/dist/server/lib/git.js.map +1 -1
- package/dist/server/lib/integrations/github.js +49 -105
- package/dist/server/lib/integrations/github.js.map +1 -1
- package/dist/server/lib/mobileAccess.js +18 -2
- package/dist/server/lib/mobileAccess.js.map +1 -1
- package/dist/server/lib/reviewFindings.js +31 -2
- package/dist/server/lib/reviewFindings.js.map +1 -1
- package/dist/server/lib/reviewRepairCompletion.js +9 -1
- package/dist/server/lib/reviewRepairCompletion.js.map +1 -1
- package/dist/server/lib/reviewRepairReconciliation.js +8 -13
- package/dist/server/lib/reviewRepairReconciliation.js.map +1 -1
- package/dist/server/lib/specOperations.js +135 -2
- package/dist/server/lib/specOperations.js.map +1 -1
- package/dist/server/lib/specs.js +36 -8
- package/dist/server/lib/specs.js.map +1 -1
- package/dist/server/lib/ticketAutomation.js +27 -4
- package/dist/server/lib/ticketAutomation.js.map +1 -1
- package/dist/server/lib/tickets.js +72 -20
- package/dist/server/lib/tickets.js.map +1 -1
- package/dist/server/lib/types.js.map +1 -1
- package/dist/server/workers/chat.js +102 -42
- package/dist/server/workers/chat.js.map +1 -1
- package/dist/server/workers/review.js +14 -26
- package/dist/server/workers/review.js.map +1 -1
- package/dist/server/workers/specSession.js +199 -92
- package/dist/server/workers/specSession.js.map +1 -1
- package/package.json +1 -1
- package/dist/client/assets/channel-CGJSY1zl.js +0 -1
- package/dist/client/assets/classDiagram-4FO5ZUOK-C8R3tolL.js +0 -1
- package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BQyANHoJ.js +0 -1
- package/dist/client/assets/index-BXsDja_y.css +0 -2
- package/dist/client/assets/index-Go0iENKj.js +0 -276
- package/dist/client/assets/stateDiagram-v2-BHNVJYJU-CanC5-kF.js +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { formatAgentErrorForTranscript, getAgentErrorTranscriptRuns, registerSpecProcessPlaceholder, runSpecAgent, untrackSpecProcessById } from '../lib/agent.js';
|
|
2
|
-
import { createAgentRun, emitAgentRunsUpdated, finalizeAgentRun, getNextAgentRunIndex, terminalizeAgentRunsForExecutionRun } from '../lib/agentRuns.js';
|
|
1
|
+
import { formatAgentErrorForTranscript, getAgentErrorTranscriptRuns, isAgentContinuationRejectedError, registerSpecProcessPlaceholder, runSpecAgent, untrackSpecProcessById } from '../lib/agent.js';
|
|
2
|
+
import { createAgentRun, emitAgentRunsUpdated, finalizeAgentRun, getNextAgentRunIndex, resolveHistoricalProviderSession, setAgentRunContinuationResponse, terminalizeAgentRunsForExecutionRun } from '../lib/agentRuns.js';
|
|
3
3
|
import { deleteStagedSpecAttachments, linkSpecAttachmentsToMessage, stageSpecAttachmentsForAgent } from '../lib/attachments.js';
|
|
4
4
|
import { createSpecMessage, listSpecMessages } from '../lib/specMessages.js';
|
|
5
5
|
import { beginSpecSessionThinkingRun, bindSpecSessionThinkingMessage } from '../lib/thinkingState.js';
|
|
6
|
-
import { createSpecSnapshot, deriveSpecSessionTitle, getDefaultSpecSessionTitle, getSpecSession, getSpecSnapshot, resolveSpecModeValue, updateSpecSessionMode, updateSpecSessionRunConfig, updateSpecSessionStatus, updateSpecSessionTitle, updateSpecSessionUsageSnapshot, } from '../lib/specs.js';
|
|
6
|
+
import { createSpecSnapshot, deriveSpecSessionTitle, getDefaultSpecSessionTitle, getSpecSession, getSpecSnapshot, resolveSpecModeValue, updateSpecSessionMode, updateSpecSessionRunConfig, updateSpecSessionResumeSourceRunId, updateSpecSessionStatus, updateSpecSessionTitle, updateSpecSessionUsageSnapshot, } from '../lib/specs.js';
|
|
7
7
|
import { normalizeClaudeModelId, normalizeModelId } from '../lib/models.js';
|
|
8
8
|
import { HttpError } from '../lib/httpError.js';
|
|
9
9
|
import { appendPlanModeQuestionPromptRules, PLAN_MODE_RUNTIME_PROMPT_RULES } from '../lib/planModeQuestions.js';
|
|
@@ -13,7 +13,7 @@ import { persistSpecSessionProjectMemorySuggestions } from '../lib/projectMemory
|
|
|
13
13
|
import { extractProjectMemorySuggestionsFromOutput, getProjectMemorySuggestionPromptRules, } from '../lib/projectMemorySuggestions.js';
|
|
14
14
|
import { enqueue, isRunning } from '../lib/queue.js';
|
|
15
15
|
import { getProjectById } from '../lib/projects.js';
|
|
16
|
-
import { addExecutionRunLink, transitionExecutionRun } from '../lib/executionRuns.js';
|
|
16
|
+
import { addExecutionRunLink, appendLifecycleEvent, getExecutionRun, transitionExecutionRun, withExecutionRunTransaction } from '../lib/executionRuns.js';
|
|
17
17
|
import { TurnStartError } from '../lib/turnExecutionErrors.js';
|
|
18
18
|
import { buildLinkedResearchContext, prepareLinkedPlanningResearch } from './plan.js';
|
|
19
19
|
import { extractGrillQuestionFromOutput, extractSpecArtifactFromOutput, projectPlannerOwnedLikelyFiles, resolveCarriedForwardArtifacts, resolveCarriedForwardStructuredFields, stripFileRelationGraphBlocks, stripMermaidBlocks } from '../lib/specArtifact.js';
|
|
@@ -23,7 +23,7 @@ import { collectSpecResourceUrls } from '../lib/specResources.js';
|
|
|
23
23
|
import { resolveImportedSpecBundleName } from '../lib/specBundleGroups.js';
|
|
24
24
|
import { resolveSessionExecutionTarget, resolveSessionTargetForExecution } from '../lib/sessionTargets.js';
|
|
25
25
|
import { resolveWorkloadExecutionEnvironment } from '../lib/workloadExecutionEnvironment.js';
|
|
26
|
-
import { assertProviderSessionAuthorityMatches } from '../lib/executionRunAuthority.js';
|
|
26
|
+
import { assertProviderSessionAuthorityMatches, getExecutionRunAuthority } from '../lib/executionRunAuthority.js';
|
|
27
27
|
import { getModelProvider } from '../lib/models.js';
|
|
28
28
|
import { unavailableSpecSnapshotRepositoryEvidence } from '../lib/specSnapshotEvidenceSerialization.js';
|
|
29
29
|
import { SPEC_REPOSITORY_GRAPH_DISABLED_REASON } from '../lib/specGraphFeature.js';
|
|
@@ -414,7 +414,7 @@ const emitUpdatedSpecSession = (specSessionId, io, skipTargetResolution = false)
|
|
|
414
414
|
io.emit('spec-session:updated', specSession);
|
|
415
415
|
}
|
|
416
416
|
};
|
|
417
|
-
const failSpecTurn = ({ specSessionId, executionContext, existingTriggerMessageId, providerContinuation, conversationContext, priorSnapshotId, turnMode, mainRunId, error, io, skipTargetResolution = false, }) => {
|
|
417
|
+
const failSpecTurn = ({ specSessionId, executionContext, existingTriggerMessageId, providerContinuation, conversationContext, priorSnapshotId, turnMode, providerSessionId, internalContinuation, mainRunId, error, io, skipTargetResolution = false, }) => {
|
|
418
418
|
const failureMessage = getErrorMessage(error);
|
|
419
419
|
untrackSpecProcessById(specSessionId);
|
|
420
420
|
try {
|
|
@@ -427,7 +427,7 @@ const failSpecTurn = ({ specSessionId, executionContext, existingTriggerMessageI
|
|
|
427
427
|
// Preserve the top-level execution even if detail finalization fails.
|
|
428
428
|
}
|
|
429
429
|
try {
|
|
430
|
-
const errorContent = formatAgentErrorForTranscript(error);
|
|
430
|
+
const errorContent = internalContinuation ? null : formatAgentErrorForTranscript(error);
|
|
431
431
|
if (errorContent) {
|
|
432
432
|
const errorMessageId = createSpecMessage({
|
|
433
433
|
specSessionId,
|
|
@@ -464,12 +464,19 @@ const failSpecTurn = ({ specSessionId, executionContext, existingTriggerMessageI
|
|
|
464
464
|
runId: executionContext.runId,
|
|
465
465
|
status: 'failed',
|
|
466
466
|
domainStatus: 'error',
|
|
467
|
-
failure: {
|
|
468
|
-
|
|
467
|
+
failure: {
|
|
468
|
+
code: internalContinuation
|
|
469
|
+
? isAgentContinuationRejectedError(error)
|
|
470
|
+
? 'resume_provider_continuation_rejected'
|
|
471
|
+
: 'resume_continuation_failed'
|
|
472
|
+
: 'spec_turn_failed',
|
|
473
|
+
message: failureMessage,
|
|
474
|
+
},
|
|
475
|
+
eventType: internalContinuation ? 'resume_failed' : 'spec_turn_failed',
|
|
469
476
|
}, io);
|
|
470
477
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
471
478
|
};
|
|
472
|
-
export const startSpecSessionTurn = ({ specSessionId, instruction, attachments = [], tool, model, variant, skills = [], io, executionContext, existingTriggerMessageId, providerContinuation, conversationContext, priorSnapshotId, turnMode, }) => {
|
|
479
|
+
export const startSpecSessionTurn = ({ specSessionId, instruction, attachments = [], tool, model, variant, skills = [], io, executionContext, existingTriggerMessageId, providerContinuation, conversationContext, priorSnapshotId, turnMode, providerSessionId, internalContinuation, }) => {
|
|
473
480
|
const specSession = getSpecSession(specSessionId, { includeMessages: true });
|
|
474
481
|
if (!specSession) {
|
|
475
482
|
return false;
|
|
@@ -488,13 +495,13 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
488
495
|
if (specSession.agent_status === 'running' || isRunning(jobKey)) {
|
|
489
496
|
return false;
|
|
490
497
|
}
|
|
491
|
-
const userMessageId = existingTriggerMessageId ?? createSpecMessage({
|
|
498
|
+
const userMessageId = existingTriggerMessageId ?? (internalContinuation ? null : createSpecMessage({
|
|
492
499
|
specSessionId,
|
|
493
500
|
role: 'user',
|
|
494
501
|
kind: 'prompt',
|
|
495
502
|
content: trimmedInstruction,
|
|
496
|
-
});
|
|
497
|
-
if (!existingTriggerMessageId) {
|
|
503
|
+
}));
|
|
504
|
+
if (!existingTriggerMessageId && userMessageId) {
|
|
498
505
|
addExecutionRunLink({
|
|
499
506
|
projectId: executionContext.projectId,
|
|
500
507
|
runId: executionContext.runId,
|
|
@@ -506,7 +513,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
506
513
|
},
|
|
507
514
|
});
|
|
508
515
|
}
|
|
509
|
-
if (!existingTriggerMessageId && attachments.length > 0) {
|
|
516
|
+
if (!existingTriggerMessageId && userMessageId && attachments.length > 0) {
|
|
510
517
|
linkSpecAttachmentsToMessage({
|
|
511
518
|
specMessageId: userMessageId,
|
|
512
519
|
attachments,
|
|
@@ -520,14 +527,16 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
520
527
|
: null;
|
|
521
528
|
const resolvedVariant = resolvedTool === 'opencode' && resolvedModel ? variant ?? null : null;
|
|
522
529
|
const resolvedSkills = skills;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
530
|
+
if (!internalContinuation) {
|
|
531
|
+
updateSpecSessionRunConfig({
|
|
532
|
+
specSessionId,
|
|
533
|
+
tool: resolvedTool,
|
|
534
|
+
model: resolvedModel,
|
|
535
|
+
variant: resolvedVariant,
|
|
536
|
+
skills: resolvedSkills,
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
if (!internalContinuation && resolvedTool !== 'opencode' && specSession.title === getDefaultSpecSessionTitle()) {
|
|
531
540
|
updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
|
|
532
541
|
}
|
|
533
542
|
beginSpecSessionThinkingRun(specSessionId);
|
|
@@ -578,6 +587,12 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
578
587
|
workspacePath: canonicalTarget.target.workspacePath,
|
|
579
588
|
workspaceEvidence: canonicalTarget.target.workspaceEvidence,
|
|
580
589
|
};
|
|
590
|
+
const sourceAuthority = internalContinuation
|
|
591
|
+
? getExecutionRunAuthority(latestProject.id, internalContinuation.sourceRunId)
|
|
592
|
+
: null;
|
|
593
|
+
if (internalContinuation && !sourceAuthority) {
|
|
594
|
+
throw new Error('The exact Resume execution authority is unavailable.');
|
|
595
|
+
}
|
|
581
596
|
workloadEnvironment = await resolveWorkloadExecutionEnvironment({
|
|
582
597
|
project: latestProject,
|
|
583
598
|
executionRunId: executionContext.runId,
|
|
@@ -586,17 +601,26 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
586
601
|
skills: resolvedSkills,
|
|
587
602
|
target: executionTarget,
|
|
588
603
|
workload: 'spec',
|
|
604
|
+
pinnedProvider: sourceAuthority?.effective.provider,
|
|
605
|
+
pinnedEnvironmentId: sourceAuthority?.effective.environment_id ?? undefined,
|
|
606
|
+
pinnedEnvironmentRevision: sourceAuthority?.effective.environment_revision ?? undefined,
|
|
607
|
+
pinnedEnvironmentValidationFingerprint: sourceAuthority?.effective.environment_validation_fingerprint ?? undefined,
|
|
589
608
|
signal: specCancellation.abortController?.signal,
|
|
590
609
|
onLeaseAcquired: release => {
|
|
591
610
|
leasedEnvironmentRelease = release;
|
|
592
611
|
},
|
|
593
612
|
});
|
|
594
613
|
leasedEnvironmentRelease = null;
|
|
595
|
-
const resumeSessionId =
|
|
596
|
-
?
|
|
597
|
-
:
|
|
598
|
-
?
|
|
599
|
-
:
|
|
614
|
+
const resumeSessionId = providerSessionId !== undefined
|
|
615
|
+
? providerSessionId
|
|
616
|
+
: providerContinuation === 'fresh'
|
|
617
|
+
? null
|
|
618
|
+
: resolvedTool === 'claude'
|
|
619
|
+
? latestSession.claude_session_id
|
|
620
|
+
: latestSession.opencode_session_id;
|
|
621
|
+
if (internalContinuation && resumeSessionId !== internalContinuation.providerSessionId) {
|
|
622
|
+
throw new Error('The exact Resume provider session is unavailable.');
|
|
623
|
+
}
|
|
600
624
|
if (resumeSessionId) {
|
|
601
625
|
assertProviderSessionAuthorityMatches({
|
|
602
626
|
projectId: latestProject.id,
|
|
@@ -648,7 +672,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
648
672
|
currentInstruction: trimmedInstruction,
|
|
649
673
|
invocation: { parentType: 'spec', parentId: specSessionId, agentRunId: mainRunId },
|
|
650
674
|
});
|
|
651
|
-
const preResponseContext = await raceAgainstSpecCancellation(trimmedInstruction
|
|
675
|
+
const preResponseContext = await raceAgainstSpecCancellation(trimmedInstruction && !internalContinuation
|
|
652
676
|
? prepareLinkedPlanningResearch(trimmedInstruction, {
|
|
653
677
|
projectId: latestProject.id,
|
|
654
678
|
cwd,
|
|
@@ -671,16 +695,18 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
671
695
|
// to 'stopped' (worker-owned, mirroring how Chat finalizes after a stop).
|
|
672
696
|
if (specCancellation.stopRequested) {
|
|
673
697
|
untrackSpecProcessById(specSessionId);
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
698
|
+
withExecutionRunTransaction(transaction => {
|
|
699
|
+
finalizeAgentRun(mainRunId, 'stopped', null);
|
|
700
|
+
updateSpecSessionStatus(specSessionId, 'stopped', null, null);
|
|
701
|
+
transaction.transitionExecutionRun({
|
|
702
|
+
projectId: executionContext.projectId,
|
|
703
|
+
runId: executionContext.runId,
|
|
704
|
+
status: 'cancelled',
|
|
705
|
+
domainStatus: 'stopped',
|
|
706
|
+
eventType: internalContinuation ? 'resume_interrupted' : 'spec_turn_cancelled',
|
|
707
|
+
});
|
|
683
708
|
}, io);
|
|
709
|
+
emitUpdatedSpecSession(specSessionId, io);
|
|
684
710
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
685
711
|
return;
|
|
686
712
|
}
|
|
@@ -709,30 +735,64 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
709
735
|
targetBundleName: latestSession.target_branch_snapshot,
|
|
710
736
|
externalKey: latestSession.external_source?.external_key ?? null,
|
|
711
737
|
});
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
738
|
+
if (internalContinuation) {
|
|
739
|
+
appendLifecycleEvent({
|
|
740
|
+
projectId: executionContext.projectId,
|
|
741
|
+
runId: executionContext.runId,
|
|
742
|
+
domainStatus: 'running',
|
|
743
|
+
eventType: 'provider_continuation_requested',
|
|
744
|
+
metadata: { source_run_id: internalContinuation.sourceRunId },
|
|
745
|
+
}, io);
|
|
746
|
+
}
|
|
747
|
+
let specRunResult;
|
|
748
|
+
try {
|
|
749
|
+
specRunResult = await runSpecAgent({
|
|
750
|
+
specSessionId,
|
|
751
|
+
tool: resolvedTool,
|
|
752
|
+
prompt: specPrompt,
|
|
753
|
+
cwd,
|
|
754
|
+
files: stagedAgentAttachments.files,
|
|
755
|
+
io,
|
|
756
|
+
model: resolvedModel,
|
|
757
|
+
variant: resolvedVariant,
|
|
758
|
+
resumeSessionId,
|
|
759
|
+
executionContext,
|
|
760
|
+
mainRun: { id: mainRunId, label: 'Main agent', role: 'main', runIndex: mainRunIndex },
|
|
761
|
+
executionProvider: workloadEnvironment.provider,
|
|
762
|
+
executionTarget,
|
|
763
|
+
executionLauncherEnvironment: workloadEnvironment.launcherEnvironment,
|
|
764
|
+
executionRuntimeEnvironment: workloadEnvironment.runtimeEnvironment,
|
|
765
|
+
});
|
|
766
|
+
if (internalContinuation) {
|
|
767
|
+
appendLifecycleEvent({
|
|
768
|
+
projectId: executionContext.projectId,
|
|
769
|
+
runId: executionContext.runId,
|
|
770
|
+
domainStatus: 'running',
|
|
771
|
+
eventType: 'provider_continuation_resumed',
|
|
772
|
+
}, io);
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
catch (error) {
|
|
776
|
+
if (internalContinuation) {
|
|
777
|
+
appendLifecycleEvent({
|
|
778
|
+
projectId: executionContext.projectId,
|
|
779
|
+
runId: executionContext.runId,
|
|
780
|
+
domainStatus: isAgentContinuationRejectedError(error) ? 'continuation_rejected_before_execution' : 'continuation_failed',
|
|
781
|
+
eventType: isAgentContinuationRejectedError(error) ? 'provider_continuation_rejected_before_execution' : 'provider_continuation_unsafe_failure',
|
|
782
|
+
}, io);
|
|
783
|
+
}
|
|
784
|
+
throw error;
|
|
785
|
+
}
|
|
729
786
|
if (specRunResult.completionStatus === 'stopped') {
|
|
730
787
|
const interruptedSession = getSpecSession(specSessionId);
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
788
|
+
const rawInterruptedResponse = specRunResult.finalResponse?.trim()
|
|
789
|
+
? specRunResult.finalResponse
|
|
790
|
+
: interruptedSession?.streaming_response?.trim()
|
|
791
|
+
? interruptedSession.streaming_response
|
|
792
|
+
: getTranscriptContentFallback(specRunResult.transcriptRuns);
|
|
793
|
+
const interruptedResponse = stripSpecFileGraph(rawInterruptedResponse ?? '')
|
|
734
794
|
|| '';
|
|
735
|
-
if (resolvedTool === 'opencode' && interruptedSession?.title === getDefaultSpecSessionTitle()) {
|
|
795
|
+
if (!internalContinuation && resolvedTool === 'opencode' && interruptedSession?.title === getDefaultSpecSessionTitle()) {
|
|
736
796
|
updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
|
|
737
797
|
}
|
|
738
798
|
if (interruptedResponse) {
|
|
@@ -759,16 +819,29 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
759
819
|
}
|
|
760
820
|
}
|
|
761
821
|
updateSpecSessionUsageSnapshot(specSessionId, specRunResult.usageSnapshot);
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
822
|
+
withExecutionRunTransaction(transaction => {
|
|
823
|
+
updateSpecSessionStatus(specSessionId, 'stopped', interruptedSession?.agent_log ?? null, null);
|
|
824
|
+
setAgentRunContinuationResponse(mainRunId, rawInterruptedResponse ?? '');
|
|
825
|
+
finalizeAgentRun(mainRunId, 'stopped', rawInterruptedResponse || null);
|
|
826
|
+
transaction.transitionExecutionRun({
|
|
827
|
+
projectId: executionContext.projectId,
|
|
828
|
+
runId: executionContext.runId,
|
|
829
|
+
status: 'cancelled',
|
|
830
|
+
domainStatus: 'stopped',
|
|
831
|
+
eventType: internalContinuation ? 'resume_interrupted' : 'spec_turn_cancelled',
|
|
832
|
+
});
|
|
833
|
+
if (getExecutionRun(executionContext.projectId, executionContext.runId)?.initiated_by === 'user') {
|
|
834
|
+
try {
|
|
835
|
+
if (resolveHistoricalProviderSession(executionContext.runId).sessionId) {
|
|
836
|
+
updateSpecSessionResumeSourceRunId(specSessionId, executionContext.runId);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
catch {
|
|
840
|
+
updateSpecSessionResumeSourceRunId(specSessionId, null);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
771
843
|
}, io);
|
|
844
|
+
emitUpdatedSpecSession(specSessionId, io);
|
|
772
845
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
773
846
|
return;
|
|
774
847
|
}
|
|
@@ -781,7 +854,14 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
781
854
|
streamingResponse: streamedAssistantMessage,
|
|
782
855
|
transcriptRuns: specRunResult.transcriptRuns,
|
|
783
856
|
};
|
|
784
|
-
const
|
|
857
|
+
const completedOutput = resolveCompletedAssistantOutput(completedOutputOptions);
|
|
858
|
+
const currentRawResponse = specRunResult.finalResponse?.trim()
|
|
859
|
+
? specRunResult.finalResponse
|
|
860
|
+
: completedOutput;
|
|
861
|
+
const rawResponse = `${internalContinuation?.priorResponseText ?? ''}${currentRawResponse}`;
|
|
862
|
+
const parsingOutputOptions = internalContinuation
|
|
863
|
+
? { finalResponse: rawResponse }
|
|
864
|
+
: completedOutputOptions;
|
|
785
865
|
// Resolve the session mode at the moment the turn completed. NULL/legacy
|
|
786
866
|
// values normalize to 'standard'. The worker's per-mode output branch is
|
|
787
867
|
// decided here, not from a re-read after the artifact path, so an
|
|
@@ -798,7 +878,8 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
798
878
|
throw new Error(`Invalid Grill question envelope: ${grillResult.error}`);
|
|
799
879
|
}
|
|
800
880
|
if (grillResult.grillQuestion) {
|
|
801
|
-
const
|
|
881
|
+
const currentGrillResult = internalContinuation ? extractGrillQuestionFromOutput(currentRawResponse) : grillResult;
|
|
882
|
+
const cleanedGrillText = stripSpecFileGraph(currentGrillResult.error ? '' : currentGrillResult.cleanedOutput)
|
|
802
883
|
|| grillResult.grillQuestion.question
|
|
803
884
|
|| stripSpecFileGraph(streamedAssistantMessage);
|
|
804
885
|
const grillMessageId = createSpecMessage({
|
|
@@ -823,7 +904,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
823
904
|
},
|
|
824
905
|
});
|
|
825
906
|
}
|
|
826
|
-
if (resolvedTool === 'opencode' && latestCompletedSession?.title === getDefaultSpecSessionTitle()) {
|
|
907
|
+
if (!internalContinuation && resolvedTool === 'opencode' && latestCompletedSession?.title === getDefaultSpecSessionTitle()) {
|
|
827
908
|
updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
|
|
828
909
|
}
|
|
829
910
|
updateSpecSessionUsageSnapshot(specSessionId, specRunResult.usageSnapshot);
|
|
@@ -835,14 +916,14 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
835
916
|
runId: executionContext.runId,
|
|
836
917
|
status: 'completed',
|
|
837
918
|
domainStatus: 'done',
|
|
838
|
-
eventType: 'spec_turn_completed',
|
|
919
|
+
eventType: internalContinuation ? 'resume_completed' : 'spec_turn_completed',
|
|
839
920
|
}, io);
|
|
840
921
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
841
922
|
return;
|
|
842
923
|
}
|
|
843
924
|
}
|
|
844
925
|
const completedQuestionOutput = sessionMode !== 'grill'
|
|
845
|
-
? resolveCompletedQuestionOutput(
|
|
926
|
+
? resolveCompletedQuestionOutput(parsingOutputOptions)
|
|
846
927
|
: null;
|
|
847
928
|
const askQuestionResult = completedQuestionOutput
|
|
848
929
|
? completedQuestionOutput.extraction
|
|
@@ -851,7 +932,11 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
851
932
|
throw new Error(`Invalid question envelope: ${askQuestionResult.error}`);
|
|
852
933
|
}
|
|
853
934
|
if (askQuestionResult.questionSet) {
|
|
854
|
-
const
|
|
935
|
+
const currentQuestionResult = internalContinuation
|
|
936
|
+
? resolveCompletedQuestionOutput(completedOutputOptions).extraction
|
|
937
|
+
: askQuestionResult;
|
|
938
|
+
const questionMessage = stripSpecFileGraph(currentQuestionResult.error ? '' : currentQuestionResult.cleanedOutput)
|
|
939
|
+
|| formatAskQuestionMessage(askQuestionResult.questionSet);
|
|
855
940
|
const messageId = createSpecMessage({
|
|
856
941
|
specSessionId,
|
|
857
942
|
role: 'assistant',
|
|
@@ -872,7 +957,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
872
957
|
expectedParent: { entityType: 'spec_session', entityId: specSessionId },
|
|
873
958
|
},
|
|
874
959
|
});
|
|
875
|
-
if (resolvedTool === 'opencode' && latestCompletedSession?.title === getDefaultSpecSessionTitle()) {
|
|
960
|
+
if (!internalContinuation && resolvedTool === 'opencode' && latestCompletedSession?.title === getDefaultSpecSessionTitle()) {
|
|
876
961
|
updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
|
|
877
962
|
}
|
|
878
963
|
updateSpecSessionUsageSnapshot(specSessionId, specRunResult.usageSnapshot);
|
|
@@ -883,7 +968,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
883
968
|
runId: executionContext.runId,
|
|
884
969
|
status: 'completed',
|
|
885
970
|
domainStatus: 'done',
|
|
886
|
-
eventType: 'spec_turn_completed',
|
|
971
|
+
eventType: internalContinuation ? 'resume_completed' : 'spec_turn_completed',
|
|
887
972
|
}, io);
|
|
888
973
|
emitUpdatedSpecSession(specSessionId, io);
|
|
889
974
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
@@ -917,7 +1002,17 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
917
1002
|
const cleanPlannerResponse = (value) => stripSpecFileGraph(stripMermaidBlocks(value));
|
|
918
1003
|
const cleanedPlanText = cleanPlannerResponse(parsedResponse.cleanedOutput)
|
|
919
1004
|
|| cleanPlannerResponse(streamedAssistantMessage);
|
|
920
|
-
|
|
1005
|
+
const currentQuestionResult = internalContinuation
|
|
1006
|
+
? resolveCompletedQuestionOutput(completedOutputOptions).extraction
|
|
1007
|
+
: askQuestionResult;
|
|
1008
|
+
const currentArtifactResult = internalContinuation
|
|
1009
|
+
? extractSpecArtifactFromOutput(currentQuestionResult.error ? currentRawResponse : currentQuestionResult.cleanedOutput)
|
|
1010
|
+
: artifactResult;
|
|
1011
|
+
const currentParsedResponse = internalContinuation
|
|
1012
|
+
? extractProjectMemorySuggestionsFromOutput(currentArtifactResult.cleanedOutput)
|
|
1013
|
+
: parsedResponse;
|
|
1014
|
+
let assistantMessage = cleanPlannerResponse(currentParsedResponse.cleanedOutput)
|
|
1015
|
+
|| (internalContinuation ? cleanPlannerResponse(currentRawResponse) : '')
|
|
921
1016
|
|| stripSpecFileGraph(getTranscriptContentFallback(specRunResult.transcriptRuns))
|
|
922
1017
|
|| (attachments.length > 0 ? ATTACHMENT_ONLY_EMPTY_RESPONSE_FALLBACK : '');
|
|
923
1018
|
let artifactValidationError = artifactResult.error;
|
|
@@ -1030,7 +1125,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
1030
1125
|
});
|
|
1031
1126
|
}
|
|
1032
1127
|
}
|
|
1033
|
-
if (resolvedTool === 'opencode' && latestCompletedSession?.title === getDefaultSpecSessionTitle()) {
|
|
1128
|
+
if (!internalContinuation && resolvedTool === 'opencode' && latestCompletedSession?.title === getDefaultSpecSessionTitle()) {
|
|
1034
1129
|
updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
|
|
1035
1130
|
}
|
|
1036
1131
|
updateSpecSessionUsageSnapshot(specSessionId, specRunResult.usageSnapshot);
|
|
@@ -1045,33 +1140,45 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
1045
1140
|
runId: executionContext.runId,
|
|
1046
1141
|
status: 'completed',
|
|
1047
1142
|
domainStatus: 'done',
|
|
1048
|
-
eventType: 'spec_turn_completed',
|
|
1143
|
+
eventType: internalContinuation ? 'resume_completed' : 'spec_turn_completed',
|
|
1049
1144
|
}, io);
|
|
1050
1145
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
1051
1146
|
}
|
|
1052
1147
|
catch (error) {
|
|
1053
1148
|
if (specCancellation.stopRequested) {
|
|
1054
1149
|
untrackSpecProcessById(specSessionId);
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1150
|
+
withExecutionRunTransaction(transaction => {
|
|
1151
|
+
if (mainRunId) {
|
|
1152
|
+
finalizeAgentRun(mainRunId, 'stopped', null);
|
|
1153
|
+
}
|
|
1154
|
+
updateSpecSessionStatus(specSessionId, 'stopped', null, null);
|
|
1155
|
+
transaction.transitionExecutionRun({
|
|
1156
|
+
projectId: executionContext.projectId,
|
|
1157
|
+
runId: executionContext.runId,
|
|
1158
|
+
status: 'cancelled',
|
|
1159
|
+
domainStatus: 'stopped',
|
|
1160
|
+
eventType: internalContinuation ? 'resume_interrupted' : 'spec_turn_cancelled',
|
|
1161
|
+
});
|
|
1162
|
+
if (getExecutionRun(executionContext.projectId, executionContext.runId)?.initiated_by === 'user') {
|
|
1163
|
+
try {
|
|
1164
|
+
if (resolveHistoricalProviderSession(executionContext.runId).sessionId) {
|
|
1165
|
+
updateSpecSessionResumeSourceRunId(specSessionId, executionContext.runId);
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
catch {
|
|
1169
|
+
updateSpecSessionResumeSourceRunId(specSessionId, null);
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1066
1172
|
}, io);
|
|
1173
|
+
emitUpdatedSpecSession(specSessionId, io);
|
|
1067
1174
|
emitAgentRunsUpdated(io, 'spec', specSessionId);
|
|
1068
1175
|
return;
|
|
1069
1176
|
}
|
|
1070
1177
|
const latestSession = getSpecSession(specSessionId, hasValidatedTarget ? {} : { skipTargetResolution: true });
|
|
1071
|
-
if (resolvedTool === 'opencode' && latestSession?.title === getDefaultSpecSessionTitle()) {
|
|
1178
|
+
if (!internalContinuation && resolvedTool === 'opencode' && latestSession?.title === getDefaultSpecSessionTitle()) {
|
|
1072
1179
|
updateSpecSessionTitle(specSessionId, deriveSpecSessionTitle(trimmedInstruction));
|
|
1073
1180
|
}
|
|
1074
|
-
failSpecTurn({ specSessionId, executionContext, mainRunId, error, io, skipTargetResolution: !hasValidatedTarget });
|
|
1181
|
+
failSpecTurn({ specSessionId, executionContext, mainRunId, error, io, skipTargetResolution: !hasValidatedTarget, internalContinuation });
|
|
1075
1182
|
}
|
|
1076
1183
|
finally {
|
|
1077
1184
|
try {
|
|
@@ -1097,7 +1204,7 @@ export const startSpecSessionTurn = ({ specSessionId, instruction, attachments =
|
|
|
1097
1204
|
}
|
|
1098
1205
|
queuedJob.catch(error => {
|
|
1099
1206
|
try {
|
|
1100
|
-
failSpecTurn({ specSessionId, executionContext, mainRunId: null, error, io });
|
|
1207
|
+
failSpecTurn({ specSessionId, executionContext, mainRunId: null, error, io, internalContinuation });
|
|
1101
1208
|
}
|
|
1102
1209
|
catch {
|
|
1103
1210
|
// Startup reconciliation remains the final repair boundary for database failures.
|