@zq-silk/yui 0.10.0 → 0.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 +53 -0
- package/dist/cli/commandCatalog.js +28 -7
- package/dist/cli.js +50 -47
- package/dist/commands/projectCommands.js +69 -6
- package/dist/commands/taskCommands.js +639 -89
- package/dist/commands/taskContextCommand.js +78 -27
- package/dist/commands/taskNextActionCommand.js +13 -2
- package/dist/commands/taskOverviewCommand.js +21 -5
- package/dist/commands/taskUpstreamCommands.js +136 -0
- package/dist/context/runContextPack.js +184 -17
- package/dist/controller/agentRuntimeObserver.js +31 -20
- package/dist/controller/fileSchedulerStoreAdapter.js +7 -13
- package/dist/execution/candidateConvergence.js +623 -0
- package/dist/execution/executionGroup.js +255 -13
- package/dist/execution/executionHealth.js +324 -0
- package/dist/execution/resourceBroker.js +425 -0
- package/dist/executor/fileRoleLaunchPlanner.js +6 -9
- package/dist/executor/workspacePreflightClassification.js +117 -0
- package/dist/lifecycle/exactRunTerminalization.js +13 -2
- package/dist/lifecycle/taskRoleSessionReset.js +4 -2
- package/dist/repository/taskBaseFreshness.js +26 -1
- package/dist/repository/taskWorkspacePreparer.js +17 -1
- package/dist/review/reviewRound.js +27 -6
- package/dist/run/agentRun.js +2 -2
- package/dist/run/recoveryProjection.js +15 -0
- package/dist/runtime/runtimeContinuationProjection.js +7 -0
- package/dist/runtime/tmuxAdapters.js +8 -2
- package/dist/scheduler/actionability.js +169 -3
- package/dist/scheduler/activeTaskProgress.js +15 -10
- package/dist/scheduler/leaderWakeupProcessor.js +17 -1
- package/dist/scheduler/taskExecutionProjection.js +105 -8
- package/dist/scheduler/taskObservabilityProjection.js +282 -0
- package/dist/storage/migration/productionRegistry.js +14 -0
- package/dist/storage/sqliteStore.js +12 -0
- package/dist/storage/taskStore.js +1 -1
- package/dist/task/completionReadiness.js +1 -1
- package/dist/task/nextAction.js +314 -2
- package/dist/web/assets/client/components.js +116 -0
- package/dist/web/assets/client/i18n.js +66 -0
- package/dist/web/assets/client/view.js +15 -0
- package/dist/web/assets/styles/cards.js +23 -0
- package/dist/web/assets/styles/responsive.js +2 -0
- package/dist/web/webSnapshot.js +8 -2
- package/dist/workItem/workItem.js +262 -5
- package/i18n/README.zh-CN.md +42 -0
- package/package.json +1 -1
|
@@ -6,7 +6,47 @@ export const RUN_CONTEXT_PACK_SCHEMA_VERSION = 1;
|
|
|
6
6
|
export const RUN_CONTEXT_PACK_MAX_REFS = 256;
|
|
7
7
|
export const RUN_CONTEXT_PACK_MAX_BYTES = 8 * 1024 * 1024;
|
|
8
8
|
export const RUN_CONTEXT_EXPAND_MAX_BYTES = 4 * 1024 * 1024;
|
|
9
|
-
export function freezeRunContextSnapshot(store, run, now, frozenBy = "controller") {
|
|
9
|
+
export function freezeRunContextSnapshot(store, run, now, frozenBy = "controller", baselineRef) {
|
|
10
|
+
if (baselineRef !== undefined) {
|
|
11
|
+
const baseline = store.getContextSnapshot(run.taskId, baselineRef.id);
|
|
12
|
+
if (baseline === null
|
|
13
|
+
|| baseline.taskId !== run.taskId
|
|
14
|
+
|| baselineRef.taskId !== run.taskId
|
|
15
|
+
|| baseline.digest !== baselineRef.digest
|
|
16
|
+
|| baseline.sequence !== baselineRef.sequence
|
|
17
|
+
|| baseline.scope !== "stage"
|
|
18
|
+
|| baselineRef.scope !== baseline.scope
|
|
19
|
+
|| baseline.scopeRef !== baselineRef.scopeRef) {
|
|
20
|
+
throw new Error(`Run Context baseline is missing or drifted: ${baselineRef.id}.`);
|
|
21
|
+
}
|
|
22
|
+
validateContextSnapshot(baseline);
|
|
23
|
+
const overlays = collectRunContextOverlays(store, run);
|
|
24
|
+
const resources = [...new Map([...baseline.resources, ...overlays].map((entry) => [
|
|
25
|
+
contextRefIdentity(entry.ref),
|
|
26
|
+
entry
|
|
27
|
+
])).values()].sort((left, right) => (contextRefIdentity(left.ref).localeCompare(contextRefIdentity(right.ref))));
|
|
28
|
+
const previous = store.listContextSnapshots(run.taskId)
|
|
29
|
+
.filter((candidate) => candidate.scope === baseline.scope
|
|
30
|
+
&& candidate.scopeRef === baseline.scopeRef)
|
|
31
|
+
.sort((left, right) => left.sequence - right.sequence)
|
|
32
|
+
.at(-1);
|
|
33
|
+
const snapshot = createContextSnapshot({
|
|
34
|
+
id: store.nextContextSnapshotId(run.taskId),
|
|
35
|
+
taskId: run.taskId,
|
|
36
|
+
scope: baseline.scope,
|
|
37
|
+
scopeRef: baseline.scopeRef,
|
|
38
|
+
sequence: (previous?.sequence ?? baseline.sequence) + 1,
|
|
39
|
+
refs: resources.map(({ ref }) => ref),
|
|
40
|
+
resources,
|
|
41
|
+
...(baseline.repoCommit === undefined ? {} : { repoCommit: baseline.repoCommit }),
|
|
42
|
+
acceptRefs: baseline.acceptRefs,
|
|
43
|
+
parentRef: contextSnapshotRef(baseline),
|
|
44
|
+
frozenAt: now,
|
|
45
|
+
frozenBy
|
|
46
|
+
});
|
|
47
|
+
store.saveContextSnapshot(snapshot);
|
|
48
|
+
return snapshot;
|
|
49
|
+
}
|
|
10
50
|
const scope = run.reviewRoundId !== undefined
|
|
11
51
|
? "stage"
|
|
12
52
|
: run.workItemId !== undefined
|
|
@@ -34,6 +74,127 @@ export function freezeRunContextSnapshot(store, run, now, frozenBy = "controller
|
|
|
34
74
|
store.saveContextSnapshot(snapshot);
|
|
35
75
|
return snapshot;
|
|
36
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Freeze the shared, role-neutral ContextSnapshot anchored by one WorkItem
|
|
79
|
+
* exploration stage Group. AgentRun snapshots remain role-specific; this
|
|
80
|
+
* record is the durable stage baseline and derives from a fresh WorkItem
|
|
81
|
+
* snapshot so the Group never depends on ambient latest state.
|
|
82
|
+
*/
|
|
83
|
+
export function freezeExecutionStageContextSnapshot(store, input, now) {
|
|
84
|
+
const task = store.getTask(input.taskId);
|
|
85
|
+
if (task === null)
|
|
86
|
+
throw new Error(`Task not found: ${input.taskId}.`);
|
|
87
|
+
const workItem = store.getWorkItem(input.taskId, input.workItemId);
|
|
88
|
+
if (workItem === null)
|
|
89
|
+
throw new Error(`WorkItem not found: ${input.workItemId}.`);
|
|
90
|
+
const materialized = [
|
|
91
|
+
materialize("L2", "task", task.id, task),
|
|
92
|
+
materialize("L3", "work-item", workItem.id, workItem)
|
|
93
|
+
];
|
|
94
|
+
for (const dependencyId of workItem.dependsOn) {
|
|
95
|
+
const dependency = store.getWorkItem(task.id, dependencyId);
|
|
96
|
+
if (dependency === null || dependency.status !== "completed") {
|
|
97
|
+
throw new Error(`Exploration stage dependency is not accepted: ${dependencyId}.`);
|
|
98
|
+
}
|
|
99
|
+
materialized.push(materialize("L3", "accepted-work-item", dependency.id, dependency));
|
|
100
|
+
}
|
|
101
|
+
for (const binding of task.projectBindings) {
|
|
102
|
+
const project = store.getProject(binding.projectId);
|
|
103
|
+
if (project === null)
|
|
104
|
+
throw new Error(`Run Project not found: ${binding.projectId}.`);
|
|
105
|
+
const { knowledge, ...projectPolicy } = project;
|
|
106
|
+
materialized.push(materialize("L1", "project-policy", project.id, projectPolicy));
|
|
107
|
+
for (const entry of knowledge.filter(({ status }) => status === "active")) {
|
|
108
|
+
materialized.push(materialize("L1", "project-knowledge", `${project.id}:${entry.id}`, { projectId: project.id, ...entry }));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
const resources = [...new Map(materialized.map((entry) => [
|
|
112
|
+
contextRefIdentity(entry.ref),
|
|
113
|
+
entry
|
|
114
|
+
])).values()].sort((left, right) => (contextRefIdentity(left.ref).localeCompare(contextRefIdentity(right.ref))));
|
|
115
|
+
const previousWorkItem = store.listContextSnapshots(task.id)
|
|
116
|
+
.filter((candidate) => candidate.scope === "workitem"
|
|
117
|
+
&& candidate.scopeRef === workItem.id)
|
|
118
|
+
.sort((left, right) => left.sequence - right.sequence)
|
|
119
|
+
.at(-1);
|
|
120
|
+
const workItemSnapshot = createContextSnapshot({
|
|
121
|
+
id: store.nextContextSnapshotId(task.id),
|
|
122
|
+
taskId: task.id,
|
|
123
|
+
scope: "workitem",
|
|
124
|
+
scopeRef: workItem.id,
|
|
125
|
+
sequence: (previousWorkItem?.sequence ?? 0) + 1,
|
|
126
|
+
refs: resources.map(({ ref }) => ref),
|
|
127
|
+
resources,
|
|
128
|
+
acceptRefs: [`work-item:${workItem.id}:acceptance`],
|
|
129
|
+
...(previousWorkItem === undefined
|
|
130
|
+
? {}
|
|
131
|
+
: { parentRef: contextSnapshotRef(previousWorkItem) }),
|
|
132
|
+
frozenAt: now,
|
|
133
|
+
frozenBy: "controller"
|
|
134
|
+
});
|
|
135
|
+
store.saveContextSnapshot(workItemSnapshot);
|
|
136
|
+
const stageSnapshot = createContextSnapshot({
|
|
137
|
+
id: store.nextContextSnapshotId(task.id),
|
|
138
|
+
taskId: task.id,
|
|
139
|
+
scope: "stage",
|
|
140
|
+
scopeRef: input.executionGroupId,
|
|
141
|
+
sequence: workItemSnapshot.sequence + 1,
|
|
142
|
+
refs: resources.map(({ ref }) => ref),
|
|
143
|
+
resources,
|
|
144
|
+
acceptRefs: [`work-item:${workItem.id}:acceptance`],
|
|
145
|
+
parentRef: contextSnapshotRef(workItemSnapshot),
|
|
146
|
+
frozenAt: now,
|
|
147
|
+
frozenBy: "controller"
|
|
148
|
+
});
|
|
149
|
+
store.saveContextSnapshot(stageSnapshot);
|
|
150
|
+
return stageSnapshot;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Freeze the role-neutral baseline for one Reviewer ExecutionGroup before
|
|
154
|
+
* admission. Delayed or retried sibling Lanes reuse the same immutable
|
|
155
|
+
* ReviewRound/Task/Project values and add only their Role overlay.
|
|
156
|
+
*/
|
|
157
|
+
export function freezeReviewStageContextSnapshot(store, input, now) {
|
|
158
|
+
const existing = store.listContextSnapshots(input.taskId)
|
|
159
|
+
.filter((candidate) => candidate.scope === "stage"
|
|
160
|
+
&& candidate.scopeRef === input.executionGroupId
|
|
161
|
+
&& candidate.parentRef === undefined)
|
|
162
|
+
.sort((left, right) => left.sequence - right.sequence)
|
|
163
|
+
.at(0);
|
|
164
|
+
if (existing !== undefined)
|
|
165
|
+
return validateContextSnapshot(existing);
|
|
166
|
+
const round = store.getReviewRound(input.taskId, input.reviewRoundId);
|
|
167
|
+
if (round === null)
|
|
168
|
+
throw new Error(`ReviewRound not found: ${input.reviewRoundId}.`);
|
|
169
|
+
const materialized = collectAuthorizedContext(store, {
|
|
170
|
+
taskId: input.taskId,
|
|
171
|
+
roleName: round.reviewerRoleName,
|
|
172
|
+
purpose: "review",
|
|
173
|
+
...(round.workItemId === undefined ? {} : { workItemId: round.workItemId }),
|
|
174
|
+
reviewRoundId: round.id
|
|
175
|
+
}).filter(({ ref }) => (ref.store !== "role-profile" && ref.store !== "managed-workspace"));
|
|
176
|
+
if (!materialized.some(({ ref }) => (ref.store === "review-round" && ref.refId === round.id))) {
|
|
177
|
+
throw new Error(`ReviewRound Context baseline is unavailable: ${round.id}.`);
|
|
178
|
+
}
|
|
179
|
+
const resources = [...new Map(materialized.map((entry) => [
|
|
180
|
+
contextRefIdentity(entry.ref),
|
|
181
|
+
entry
|
|
182
|
+
])).values()].sort((left, right) => (contextRefIdentity(left.ref).localeCompare(contextRefIdentity(right.ref))));
|
|
183
|
+
const snapshot = createContextSnapshot({
|
|
184
|
+
id: store.nextContextSnapshotId(input.taskId),
|
|
185
|
+
taskId: input.taskId,
|
|
186
|
+
scope: "stage",
|
|
187
|
+
scopeRef: input.executionGroupId,
|
|
188
|
+
sequence: 1,
|
|
189
|
+
refs: resources.map(({ ref }) => ref),
|
|
190
|
+
resources,
|
|
191
|
+
acceptRefs: round.workItemId === undefined ? [] : [`work-item:${round.workItemId}:acceptance`],
|
|
192
|
+
frozenAt: now,
|
|
193
|
+
frozenBy: "controller"
|
|
194
|
+
});
|
|
195
|
+
store.saveContextSnapshot(snapshot);
|
|
196
|
+
return snapshot;
|
|
197
|
+
}
|
|
37
198
|
/** Bounded changed-ref hint between one frozen Snapshot and its exact parent. */
|
|
38
199
|
export function contextSnapshotDeltaRefIds(store, snapshot) {
|
|
39
200
|
validateContextSnapshot(snapshot);
|
|
@@ -190,22 +351,7 @@ function collectAuthorizedContext(store, run) {
|
|
|
190
351
|
if (brief !== null && view === "leader") {
|
|
191
352
|
result.push(materialize("L2", "task-brief", task.id, brief));
|
|
192
353
|
}
|
|
193
|
-
|
|
194
|
-
if (role === null)
|
|
195
|
-
throw new Error(`Run Role not found: ${task.id}/${run.roleName}.`);
|
|
196
|
-
result.push(materialize("L1", "role-profile", role.name, {
|
|
197
|
-
name: role.name,
|
|
198
|
-
defaultAccess: role.defaultAccess,
|
|
199
|
-
description: role.description,
|
|
200
|
-
responsibilities: role.responsibilities ?? [],
|
|
201
|
-
constraints: role.constraints ?? [],
|
|
202
|
-
expectedOutput: role.expectedOutput,
|
|
203
|
-
skills: role.skills ?? [],
|
|
204
|
-
launchRevision: role.launchRevision
|
|
205
|
-
}));
|
|
206
|
-
if ("workspace" in run && run.workspace !== undefined) {
|
|
207
|
-
result.push(materialize("L3", "managed-workspace", `${run.taskId}/${run.roleName}`, run.workspace));
|
|
208
|
-
}
|
|
354
|
+
result.push(...collectRunContextOverlays(store, run));
|
|
209
355
|
if (run.workItemId !== undefined) {
|
|
210
356
|
const item = store.getWorkItem(task.id, run.workItemId);
|
|
211
357
|
if (item === null)
|
|
@@ -287,6 +433,27 @@ function collectAuthorizedContext(store, run) {
|
|
|
287
433
|
const unique = new Map(result.map((entry) => [contextRefIdentity(entry.ref), entry]));
|
|
288
434
|
return [...unique.values()].sort((left, right) => (contextRefIdentity(left.ref).localeCompare(contextRefIdentity(right.ref))));
|
|
289
435
|
}
|
|
436
|
+
/** Lane-specific context that may be layered over an immutable stage base. */
|
|
437
|
+
function collectRunContextOverlays(store, run) {
|
|
438
|
+
const role = store.getRole(run.taskId, run.roleName);
|
|
439
|
+
if (role === null)
|
|
440
|
+
throw new Error(`Run Role not found: ${run.taskId}/${run.roleName}.`);
|
|
441
|
+
return [
|
|
442
|
+
materialize("L1", "role-profile", role.name, {
|
|
443
|
+
name: role.name,
|
|
444
|
+
defaultAccess: role.defaultAccess,
|
|
445
|
+
description: role.description,
|
|
446
|
+
responsibilities: role.responsibilities ?? [],
|
|
447
|
+
constraints: role.constraints ?? [],
|
|
448
|
+
expectedOutput: role.expectedOutput,
|
|
449
|
+
skills: role.skills ?? [],
|
|
450
|
+
launchRevision: role.launchRevision
|
|
451
|
+
}),
|
|
452
|
+
...("workspace" in run && run.workspace !== undefined
|
|
453
|
+
? [materialize("L3", "managed-workspace", `${run.taskId}/${run.roleName}`, run.workspace)]
|
|
454
|
+
: [])
|
|
455
|
+
];
|
|
456
|
+
}
|
|
290
457
|
function materialize(layer, store, refId, value) {
|
|
291
458
|
const digest = contextContentDigest(value);
|
|
292
459
|
const record = value;
|
|
@@ -59,26 +59,37 @@ export class AgentRuntimeObserver {
|
|
|
59
59
|
// latency can change completion order without changing observation
|
|
60
60
|
// identity or the canonical sequence assigned to a source.
|
|
61
61
|
const sequence = sequenceBase + index;
|
|
62
|
-
if (existingState === undefined &&
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
62
|
+
if (existingState === undefined && state.usage === undefined) {
|
|
63
|
+
// A fresh native Session begins at zero. A resumed Session instead
|
|
64
|
+
// freezes its first cumulative sample as this Run's lower-bound
|
|
65
|
+
// baseline so later samples can prove spend without charging usage
|
|
66
|
+
// that belongs to an earlier Run in the same native conversation.
|
|
67
|
+
const baseline = freshSession
|
|
68
|
+
? Object.freeze({
|
|
69
|
+
semantics: "cumulative-session",
|
|
70
|
+
inputTokens: 0,
|
|
71
|
+
outputTokens: 0
|
|
72
|
+
})
|
|
73
|
+
: sample.usage?.semantics === "cumulative-session"
|
|
74
|
+
? sample.usage
|
|
75
|
+
: undefined;
|
|
76
|
+
if (baseline !== undefined) {
|
|
77
|
+
const baselineKey = freshSession ? "zero" : JSON.stringify(baseline);
|
|
78
|
+
this.inbox.enqueueObservation(createRuntimeObservation({
|
|
79
|
+
schemaVersion: 2,
|
|
80
|
+
eventId: observationId("baseline", fence, source.sourceId, baselineKey),
|
|
81
|
+
semanticKey: observationId("baseline", fence, source.sourceId, baselineKey),
|
|
82
|
+
kind: "activity.observed",
|
|
83
|
+
authority: freshSession ? "controller" : "driver-inferred",
|
|
84
|
+
receivedAt: at,
|
|
85
|
+
sequence,
|
|
86
|
+
ordinal: 1,
|
|
87
|
+
fence,
|
|
88
|
+
payload: { activity: "model", usage: baseline }
|
|
89
|
+
}));
|
|
90
|
+
state.usage = baseline;
|
|
91
|
+
dirty.add(`role:${fence.taskId}/${fence.roleName}`);
|
|
92
|
+
}
|
|
82
93
|
}
|
|
83
94
|
const health = JSON.stringify([sample.status, sample.detail ?? null]);
|
|
84
95
|
if (state.health !== health) {
|
|
@@ -30,7 +30,7 @@ import { wakeReason } from "../scheduler/wakeReason.js";
|
|
|
30
30
|
import { foldRunProgressFacts, latestRunDurableProgressAt, latestRunEventTime, latestStallEvidenceKey, clearMatchingLeaderStallAttention, RUN_PROGRESS_EVENT, RUN_RECOVERED_EVENT, RUN_STALLED_EVENT } from "../scheduler/roleRunStall.js";
|
|
31
31
|
import { projectProviderContinuations } from "../runtime/runtimeContinuationProjection.js";
|
|
32
32
|
import { providerContinuationKey } from "../runtime/providerContinuation.js";
|
|
33
|
-
import { currentWorkItemExecutionGroup, updateWorkItemExecutionGroup, updateWorkItemStatus } from "../workItem/workItem.js";
|
|
33
|
+
import { currentWorkItemExecutionGroup, updateWorkItemExecutionGroup, updateWorkItemStatus, workItemOwnsUnresolvedExecutionLane } from "../workItem/workItem.js";
|
|
34
34
|
import { recordExecutionLaneResult } from "../execution/executionGroup.js";
|
|
35
35
|
import { formatAgentRunReceiptId, formatTaskRecordReference } from "../task/taskRecordReference.js";
|
|
36
36
|
import { bindExecution, claimPending, claimInputDelivery as claimMailboxInputDelivery, completeInputDelivery as completeMailboxInputDelivery, completeProcessing, mailboxHasPending, mailboxHasWork, pendingLane, markInputDeliveryPushed as markMailboxInputDeliveryPushed, markInputDeliveryUnknown as markMailboxInputDeliveryUnknown, releaseInputDelivery as releaseMailboxInputDelivery, resolveInputDeliveryNotAccepted as resolveMailboxInputDeliveryNotAccepted, releaseProcessing } from "../coordination/workMailbox.js";
|
|
@@ -1547,11 +1547,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1547
1547
|
if (item !== null && ![
|
|
1548
1548
|
"completed", "failed", "retired"
|
|
1549
1549
|
].includes(item.status)) {
|
|
1550
|
-
|
|
1551
|
-
const groupedPanel = group !== undefined
|
|
1552
|
-
&& (group.lanes.length > 1 || group.strategy.mode === "adaptive")
|
|
1553
|
-
&& group.resolution === undefined;
|
|
1554
|
-
if (!groupedPanel) {
|
|
1550
|
+
if (!workItemOwnsUnresolvedExecutionLane(item, terminal.executionGroupId, terminal.executionLaneId)) {
|
|
1555
1551
|
store.saveWorkItem(input.taskId, updateWorkItemStatus(item, "failed", input.now, summary));
|
|
1556
1552
|
}
|
|
1557
1553
|
}
|
|
@@ -1705,11 +1701,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
1705
1701
|
store.saveWorkItem(task.id, updateWorkItemExecutionGroup(workItem, recordExecutionLaneResult(group, currentRun.executionLaneId, { summary: input.summary }, "failed", input.now), input.now));
|
|
1706
1702
|
}
|
|
1707
1703
|
const laneUpdated = store.getWorkItem(task.id, currentRun.workItemId);
|
|
1708
|
-
|
|
1709
|
-
const groupedPanel = laneGroup !== undefined
|
|
1710
|
-
&& (laneGroup.lanes.length > 1 || laneGroup.strategy.mode === "adaptive")
|
|
1711
|
-
&& laneGroup.resolution === undefined;
|
|
1712
|
-
if (!groupedPanel) {
|
|
1704
|
+
if (!workItemOwnsUnresolvedExecutionLane(laneUpdated, currentRun.executionGroupId, currentRun.executionLaneId)) {
|
|
1713
1705
|
store.saveWorkItem(task.id, updateWorkItemStatus(laneUpdated, "failed", input.now, input.summary));
|
|
1714
1706
|
}
|
|
1715
1707
|
}
|
|
@@ -2109,7 +2101,7 @@ export class FileSchedulerStoreAdapter {
|
|
|
2109
2101
|
const item = store.getWorkItem(input.taskId, before.workItemId);
|
|
2110
2102
|
if (item !== null && ![
|
|
2111
2103
|
"completed", "failed", "retired"
|
|
2112
|
-
].includes(item.status)) {
|
|
2104
|
+
].includes(item.status) && !workItemOwnsUnresolvedExecutionLane(item, before.executionGroupId, before.executionLaneId)) {
|
|
2113
2105
|
store.saveWorkItem(input.taskId, updateWorkItemStatus(item, "failed", now, summary));
|
|
2114
2106
|
}
|
|
2115
2107
|
}
|
|
@@ -3388,7 +3380,9 @@ function finalizeProviderRetryDeadline(store, run, summary, reason, now) {
|
|
|
3388
3380
|
}, now));
|
|
3389
3381
|
if (terminal.purpose === "execution" && terminal.workItemId !== undefined) {
|
|
3390
3382
|
const item = store.getWorkItem(run.taskId, terminal.workItemId);
|
|
3391
|
-
if (item !== null
|
|
3383
|
+
if (item !== null
|
|
3384
|
+
&& !["completed", "failed", "retired"].includes(item.status)
|
|
3385
|
+
&& !workItemOwnsUnresolvedExecutionLane(item, terminal.executionGroupId, terminal.executionLaneId)) {
|
|
3392
3386
|
store.saveWorkItem(run.taskId, updateWorkItemStatus(item, "failed", now, summary));
|
|
3393
3387
|
}
|
|
3394
3388
|
}
|