@zq-silk/yui 0.14.0 → 0.14.2
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/ARCHITECTURE.md +64 -35
- package/README.md +258 -125
- package/dist/agent/argumentPolicy.js +2 -1
- package/dist/agent/managedRuntimeEnvironment.js +5 -8
- package/dist/cli/commandCatalog.js +74 -109
- package/dist/cli/helpRenderer.js +1 -2
- package/dist/cli/interactionCandidates.js +10 -0
- package/dist/cli/interactionPolicy.js +76 -37
- package/dist/cli/roleWizard.js +5 -6
- package/dist/cli/updateOrchestrator.js +10 -8
- package/dist/cli/updatePorts.js +17 -13
- package/dist/cli/upgradeCommand.js +2 -5
- package/dist/cli.js +268 -231
- package/dist/commands/agentCommands.js +13 -0
- package/dist/commands/configCommands.js +7 -19
- package/dist/commands/configOverview.js +3 -2
- package/dist/commands/durableJobCommands.js +1 -1
- package/dist/commands/executionAuditCommands.js +4 -9
- package/dist/commands/globalRoleCommands.js +17 -0
- package/dist/commands/profileCommands.js +200 -30
- package/dist/commands/sessionCommands.js +1 -1
- package/dist/commands/taskActor.js +29 -127
- package/dist/commands/taskChangeSetCommands.js +1 -3
- package/dist/commands/taskCommands.js +1771 -2107
- package/dist/commands/taskCompletionGate.js +27 -103
- package/dist/commands/taskContextCommand.js +47 -80
- package/dist/commands/taskExecutionCommands.js +9 -27
- package/dist/commands/taskInputCommands.js +10 -10
- package/dist/commands/taskIntegrationCommands.js +69 -61
- package/dist/commands/taskIntegrationQueueCommands.js +1 -1
- package/dist/commands/taskNextActionCommand.js +8 -29
- package/dist/commands/taskOverviewCommand.js +25 -3
- package/dist/commands/taskPublicationCommands.js +151 -85
- package/dist/commands/taskPublicationVerifyCommand.js +181 -0
- package/dist/commands/taskRemoteDeliveryCommand.js +134 -0
- package/dist/commands/taskRoleRuntimeStatus.js +5 -6
- package/dist/commands/taskUpstreamCommands.js +79 -95
- package/dist/config/configCatalog.js +1 -1
- package/dist/context/contextSnapshot.js +17 -2
- package/dist/context/sessionBootstrapManifest.js +18 -1
- package/dist/context/sourceTurnContext.js +30 -0
- package/dist/context/turnContextPack.js +107 -48
- package/dist/context/turnInputContract.js +11 -4
- package/dist/context/wakeNotification.js +84 -22
- package/dist/controller/agentRuntimeObserver.js +9 -12
- package/dist/controller/clientRuntime.js +13 -13
- package/dist/controller/controller.js +11 -11
- package/dist/controller/fileSchedulerStoreAdapter.js +262 -219
- package/dist/controller/jobControl.js +11 -10
- package/dist/controller/resourceInventory.js +6 -6
- package/dist/controller/resourceInventoryLinux.js +2 -2
- package/dist/controller/runtime.js +18 -61
- package/dist/controller/runtimeEventInbox.js +57 -34
- package/dist/controller/runtimeEventProcessor.js +36 -96
- package/dist/controller/runtimeHookTurnFence.js +33 -57
- package/dist/controller/runtimeLaunchCoordinator.js +44 -40
- package/dist/controller/runtimeObservationHook.js +18 -12
- package/dist/controller/sessionNotify.js +43 -28
- package/dist/controller/sessionOwnerReconciliation.js +21 -21
- package/dist/controller/structuredProviderObservation.js +13 -16
- package/dist/coordination/workMailboxQueue.js +132 -0
- package/dist/core/controllerServer.js +1 -0
- package/dist/domain/agentResultTransport.js +60 -0
- package/dist/execution/executionHealth.js +111 -118
- package/dist/execution/reviewMainTurn.js +161 -0
- package/dist/execution/workItemExecution.js +454 -0
- package/dist/execution/workItemExecutionProjection.js +309 -0
- package/dist/execution/workItemMainTurn.js +164 -0
- package/dist/executor/agentExecutor.js +19 -19
- package/dist/executor/executorRegistry.js +7 -28
- package/dist/executor/fileRoleLaunchPlanner.js +51 -83
- package/dist/external/githubPublicationVerifier.js +114 -0
- package/dist/external/gitlabPublicationVerifier.js +158 -0
- package/dist/external/pinnedCommandRunner.js +73 -0
- package/dist/integration/changeSetManifest.js +0 -3
- package/dist/integration/deliveryObligation.js +43 -6
- package/dist/integration/gitIntegrationService.js +284 -101
- package/dist/integration/integrationAttempt.js +64 -14
- package/dist/integration/integrationQueueEntry.js +5 -35
- package/dist/integration/integrationQueueService.js +65 -194
- package/dist/lifecycle/canonicalLifecycleEvent.js +16 -15
- package/dist/lifecycle/exactTurnTerminalization.js +100 -97
- package/dist/message/message.js +16 -0
- package/dist/observability/executionAudit.js +4 -25
- package/dist/observability/faultClassification.js +58 -70
- package/dist/observability/orchestrationMetrics.js +8 -50
- package/dist/profile/agentProfile.js +60 -15
- package/dist/profile/agentProfileRuntime.js +100 -0
- package/dist/release/releaseWorkflowPorts.js +5 -68
- package/dist/repository/executionLaneGitSnapshot.js +80 -0
- package/dist/repository/gitWorkspace.js +9 -67
- package/dist/repository/taskBaseFreshness.js +3 -1
- package/dist/repository/taskWorkspaceCoordinator.js +32 -4
- package/dist/repository/taskWorkspacePreparer.js +252 -411
- package/dist/resources/liveReferences.js +6 -55
- package/dist/resources/resourceDiscovery.js +1 -30
- package/dist/resources/resourceRegistrar.js +0 -23
- package/dist/review/deltaRecheck.js +8 -65
- package/dist/review/reviewAcceptance.js +22 -19
- package/dist/review/reviewConfig.js +0 -10
- package/dist/review/reviewDecision.js +2 -2
- package/dist/review/reviewRound.js +147 -273
- package/dist/review/reviewerAvailability.js +13 -23
- package/dist/role/role.js +3 -0
- package/dist/runtime/agentDriverObservation.js +1 -1
- package/dist/runtime/agentHost.js +51 -51
- package/dist/runtime/builtinAgentDrivers.js +9 -2
- package/dist/runtime/codexAppServerRuntime.js +23 -5
- package/dist/runtime/exactControlPlane.js +2 -267
- package/dist/runtime/firstProgressAdvisory.js +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/launchBroker.js +11 -11
- package/dist/runtime/lifecycleReservation.js +2 -2
- package/dist/runtime/managedCaller.js +111 -0
- package/dist/runtime/ports.js +16 -3
- package/dist/runtime/preallocatedNativeSession.js +2 -2
- package/dist/runtime/processExitObservation.js +3 -2
- package/dist/runtime/providerContinuationReconciliationService.js +1 -1
- package/dist/runtime/runtimeBinding.js +1 -1
- package/dist/runtime/runtimeObservation.js +33 -16
- package/dist/runtime/runtimeSessionCandidate.js +2 -2
- package/dist/runtime/runtimeStopReceipt.js +11 -11
- package/dist/runtime/sessionLaunchRequest.js +2 -2
- package/dist/runtime/sessionOwnerIdentity.js +9 -9
- package/dist/runtime/sessionOwnerRegistry.js +13 -13
- package/dist/runtime/sessionReconciliation.js +4 -4
- package/dist/runtime/sessionTerminationGuard.js +9 -9
- package/dist/runtime/sessionTokenMetrics.js +5 -7
- package/dist/runtime/structuredProviderHost.js +5 -5
- package/dist/runtime/taskRuntimeIsolation.js +24 -24
- package/dist/runtime/tmuxAdapters.js +32 -30
- package/dist/scheduler/activeRoleTurnDelivery.js +37 -15
- package/dist/scheduler/leaderWakeupProcessor.js +78 -55
- package/dist/scheduler/roleTurnLiveness.js +6 -6
- package/dist/scheduler/roleTurnStall.js +8 -9
- package/dist/scheduler/taskExecutionProjection.js +19 -41
- package/dist/scheduler/taskObservabilityProjection.js +75 -122
- package/dist/storage/sqliteSchema.js +1 -21
- package/dist/storage/sqliteStore.js +62 -47
- package/dist/storage/storageSchema.js +1 -8
- package/dist/storage/storageVersions.js +7 -4
- package/dist/storage/taskStore.js +8 -8
- package/dist/storage/upgrade/upgradeOrchestrator.js +112 -83
- package/dist/task/completionReadiness.js +17 -98
- package/dist/task/deliveryGuard.js +9 -11
- package/dist/task/draftPlan.js +142 -0
- package/dist/task/nextAction.js +179 -477
- package/dist/task/publicationVerification.js +1 -0
- package/dist/task/remoteDelivery.js +233 -0
- package/dist/task/task.js +108 -4
- package/dist/task/taskRecordReference.js +0 -1
- package/dist/turn/turn.js +109 -16
- package/dist/verification/verificationGateService.js +0 -26
- package/dist/web/assets/client/components.js +99 -121
- package/dist/web/assets/client/i18n.js +136 -58
- package/dist/web/assets/client/view.js +44 -0
- package/dist/web/assets/styles/cards.js +3 -15
- package/dist/web/assets/styles/widgets.js +4 -0
- package/dist/web/webSnapshot.js +29 -14
- package/dist/workItem/dependencyGate.js +34 -0
- package/dist/workItem/workItem.js +99 -266
- package/dist/workspace/workItemChangeSetManager.js +15 -59
- package/docs/task-local-identity.md +1 -1
- package/i18n/README.zh-CN.md +165 -59
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +272 -782
- package/skills/yui-operator/SKILL.md +190 -365
- package/skills/yui-reviewer/SKILL.md +40 -33
- package/skills/yui-runtime/SKILL.md +27 -6
- package/skills/yui-worker/SKILL.md +19 -6
- package/dist/execution/candidateConvergence.js +0 -623
- package/dist/execution/executionGroup.js +0 -854
- package/dist/execution/resourceBroker.js +0 -426
- package/dist/executor/launchPlan.js +0 -16
- package/dist/review/reviewFinding.js +0 -240
- package/dist/review/reviewFindingLedger.js +0 -550
- package/dist/review/reviewOutcomeClassifier.js +0 -255
- package/dist/scheduler/resourceQueueProjection.js +0 -71
- package/dist/task/repairWave.js +0 -150
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { callController } from "../core/controllerClient.js";
|
|
3
3
|
import { builtinAgentDriverRegistry } from "../runtime/builtinAgentDrivers.js";
|
|
4
4
|
import { standardAgentError } from "../runtime/agentError.js";
|
|
5
|
+
import { transportAgentResult } from "../domain/agentResultTransport.js";
|
|
5
6
|
import { createRuntimeObservation, runtimeObservationSemanticKey } from "../runtime/runtimeObservation.js";
|
|
6
7
|
import { runtimeLifecycleSignalKey } from "../runtime/lifecycleReservation.js";
|
|
7
8
|
import { isForeignHandoverLockHeld } from "../release/runtimeRelease.js";
|
|
@@ -28,8 +29,7 @@ export async function publishStructuredProviderStarted(input) {
|
|
|
28
29
|
roleName: fence.roleName,
|
|
29
30
|
agentId: fence.agentId,
|
|
30
31
|
driverId: driver.id,
|
|
31
|
-
|
|
32
|
-
sessionGenerationId: fence.launchId,
|
|
32
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
33
33
|
conversationId: input.started.conversationId,
|
|
34
34
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
35
35
|
nativeSessionId: input.started.nativeSessionId,
|
|
@@ -56,8 +56,7 @@ export async function publishStructuredProviderAccepted(input) {
|
|
|
56
56
|
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
57
57
|
agentId: fence.agentId,
|
|
58
58
|
driverId: driver.id,
|
|
59
|
-
|
|
60
|
-
sessionGenerationId: fence.launchId,
|
|
59
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
61
60
|
conversationId: input.receipt.conversationId,
|
|
62
61
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
63
62
|
nativeSessionId: input.receipt.nativeSessionId,
|
|
@@ -107,8 +106,7 @@ export async function publishStructuredProviderOpened(input) {
|
|
|
107
106
|
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
108
107
|
agentId: fence.agentId,
|
|
109
108
|
driverId: driver.id,
|
|
110
|
-
|
|
111
|
-
sessionGenerationId: fence.launchId,
|
|
109
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
112
110
|
conversationId: input.conversationId,
|
|
113
111
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
114
112
|
nativeSessionId: input.nativeSessionId,
|
|
@@ -153,8 +151,7 @@ export async function publishStructuredProviderGoal(input) {
|
|
|
153
151
|
roleName: fence.roleName,
|
|
154
152
|
agentId: fence.agentId,
|
|
155
153
|
driverId: driver.id,
|
|
156
|
-
|
|
157
|
-
sessionGenerationId: fence.launchId,
|
|
154
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
158
155
|
conversationId: input.conversationId,
|
|
159
156
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
160
157
|
nativeSessionId: input.conversationId
|
|
@@ -180,8 +177,7 @@ export async function publishStructuredConversationRecoverability(input) {
|
|
|
180
177
|
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
181
178
|
agentId: fence.agentId,
|
|
182
179
|
driverId: driver.id,
|
|
183
|
-
|
|
184
|
-
sessionGenerationId: fence.launchId,
|
|
180
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
185
181
|
conversationId: input.conversationId,
|
|
186
182
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
187
183
|
nativeSessionId: input.conversationId,
|
|
@@ -224,10 +220,13 @@ export async function publishStructuredProviderTerminal(input) {
|
|
|
224
220
|
const kind = input.terminal.status === "completed"
|
|
225
221
|
? "turn.completed"
|
|
226
222
|
: input.terminal.status === "cancelled" ? "turn.cancelled" : "turn.failed";
|
|
223
|
+
const transported = transportAgentResult(input.terminal.output);
|
|
227
224
|
const payload = kind === "turn.completed"
|
|
228
225
|
? {
|
|
229
226
|
...(input.terminal.input === undefined ? {} : { input: input.terminal.input }),
|
|
230
|
-
...(
|
|
227
|
+
...(transported.status === "completed"
|
|
228
|
+
? { output: transported.output }
|
|
229
|
+
: { resultTransportDiagnostic: transported.diagnostic })
|
|
231
230
|
}
|
|
232
231
|
: kind === "turn.failed"
|
|
233
232
|
? {
|
|
@@ -263,8 +262,7 @@ export async function publishStructuredProviderTerminal(input) {
|
|
|
263
262
|
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
264
263
|
agentId: fence.agentId,
|
|
265
264
|
driverId: driver.id,
|
|
266
|
-
|
|
267
|
-
sessionGenerationId: fence.launchId,
|
|
265
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
268
266
|
conversationId: input.terminal.conversationId,
|
|
269
267
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
270
268
|
nativeSessionId: input.terminal.nativeSessionId,
|
|
@@ -290,8 +288,7 @@ export async function publishStructuredProviderActivationTerminal(input) {
|
|
|
290
288
|
...(fence.turnId === undefined ? {} : { turnId: fence.turnId }),
|
|
291
289
|
agentId: fence.agentId,
|
|
292
290
|
driverId: driver.id,
|
|
293
|
-
|
|
294
|
-
sessionGenerationId: fence.launchId,
|
|
291
|
+
runtimeGenerationId: fence.runtimeGenerationId,
|
|
295
292
|
conversationId: requireIdentity(input.conversationId, "Provider Conversation id"),
|
|
296
293
|
activationId: requireIdentity(input.activationId, "Provider Activation id"),
|
|
297
294
|
nativeSessionId: requireIdentity(input.nativeSessionId, "native Session id"),
|
|
@@ -311,7 +308,7 @@ function observation(input) {
|
|
|
311
308
|
payload: input.payload ?? {}
|
|
312
309
|
};
|
|
313
310
|
return createRuntimeObservation({
|
|
314
|
-
schemaVersion:
|
|
311
|
+
schemaVersion: 4,
|
|
315
312
|
eventId,
|
|
316
313
|
semanticKey: runtimeObservationSemanticKey(partial),
|
|
317
314
|
kind: input.kind,
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { completeProcessing, consumePendingBatch, createWorkMailbox, enqueueSignal, mailboxBatches, mailboxEntityRefKey } from "./workMailbox.js";
|
|
2
|
+
const LEGACY_ROLE_TURN_DISPATCH_REASONS = new Set([
|
|
3
|
+
"turn-dispatched",
|
|
4
|
+
"turn-retried",
|
|
5
|
+
"review-requested",
|
|
6
|
+
"workitem-synthesis-ready",
|
|
7
|
+
"review-synthesis-ready"
|
|
8
|
+
]);
|
|
2
9
|
/** Atomically useful when called inside the caller's TaskStore transaction. */
|
|
3
10
|
export function enqueueWork(store, target, reason, occurredAt, refs = [], metadata = {}) {
|
|
4
11
|
const mailbox = store.getWorkMailbox(target) ?? createWorkMailbox(target);
|
|
@@ -11,6 +18,106 @@ export function enqueueWork(store, target, reason, occurredAt, refs = [], metada
|
|
|
11
18
|
store.saveWorkMailbox(queued);
|
|
12
19
|
return queued;
|
|
13
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* The sole ordinary Role Turn wake shape. The Turn is durable execution
|
|
23
|
+
* authority; this signal only asks the Controller to deliver that exact Turn.
|
|
24
|
+
* Leader is deliberately excluded because its Role mailbox is reserved for
|
|
25
|
+
* semantic event wakes and force-steer batches. A Leader active Turn is
|
|
26
|
+
* selected directly from durable state by its targeted Controller pass.
|
|
27
|
+
*/
|
|
28
|
+
export function enqueueRoleTurnDispatch(store, input) {
|
|
29
|
+
if (input.roleName === "leader")
|
|
30
|
+
return null;
|
|
31
|
+
return enqueueWork(store, roleTurnTarget(input), input.reason, input.occurredAt, [roleTurnRef(input)], {
|
|
32
|
+
source: "turn-dispatch",
|
|
33
|
+
dedupeKey: roleTurnDispatchDedupeKey(input)
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Captures only the mailbox prefix that contains one exact Role Turn dispatch.
|
|
38
|
+
* A later signal may append while Provider delivery is in flight; its suffix
|
|
39
|
+
* remains pending when this token is settled.
|
|
40
|
+
*/
|
|
41
|
+
export function captureRoleTurnDispatch(mailbox, input) {
|
|
42
|
+
if (input.roleName === "leader"
|
|
43
|
+
|| mailbox === null
|
|
44
|
+
|| mailbox.target.kind !== "role"
|
|
45
|
+
|| mailbox.target.taskId !== input.taskId
|
|
46
|
+
|| mailbox.target.roleName !== input.roleName) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const exactRef = roleTurnRef(input);
|
|
50
|
+
if (mailbox.processing?.executionRef !== undefined
|
|
51
|
+
&& mailboxEntityRefKey(mailbox.processing.executionRef) === mailboxEntityRefKey(exactRef)) {
|
|
52
|
+
return {
|
|
53
|
+
kind: "processing",
|
|
54
|
+
batchId: mailbox.processing.batchId
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
const pending = mailbox.pending;
|
|
58
|
+
if (pending === null)
|
|
59
|
+
return null;
|
|
60
|
+
const dedupeKey = roleTurnDispatchDedupeKey(input);
|
|
61
|
+
if (mailbox.recentDedupeKeys.includes(dedupeKey))
|
|
62
|
+
return null;
|
|
63
|
+
const keyIndex = pending.dedupeKeys.indexOf(dedupeKey);
|
|
64
|
+
if (keyIndex >= 0 && pending.dedupeKeys.length === pending.requestCount) {
|
|
65
|
+
const turnSequence = pending.fromSequence + keyIndex;
|
|
66
|
+
if (turnSequence <= pending.toSequence) {
|
|
67
|
+
return {
|
|
68
|
+
kind: "pending",
|
|
69
|
+
fromSequence: pending.fromSequence,
|
|
70
|
+
toSequence: turnSequence
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Valid earlier dispatches used sequence-generated dedupe keys and could
|
|
75
|
+
// include a companion WorkItem ref. Consume that complete legacy batch once
|
|
76
|
+
// the exact Turn reaches an accepted or terminal boundary.
|
|
77
|
+
if (pending.requestCount === 1
|
|
78
|
+
&& pending.sources.length === 1
|
|
79
|
+
&& pending.sources[0] === "yui"
|
|
80
|
+
&& pending.reasons.some((reason) => LEGACY_ROLE_TURN_DISPATCH_REASONS.has(reason))
|
|
81
|
+
&& pending.refs.some((ref) => (mailboxEntityRefKey(ref) === mailboxEntityRefKey(exactRef)))) {
|
|
82
|
+
return {
|
|
83
|
+
kind: "pending",
|
|
84
|
+
fromSequence: pending.fromSequence,
|
|
85
|
+
toSequence: pending.toSequence
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Settles one exact ordinary Role Turn dispatch. Provider acceptance is the
|
|
92
|
+
* normal boundary; terminalization calls the same operation for conclusively
|
|
93
|
+
* unaccepted and valid earlier dispatches.
|
|
94
|
+
*/
|
|
95
|
+
export function settleRoleTurnDispatch(store, input, expected) {
|
|
96
|
+
if (expected === null)
|
|
97
|
+
return "absent";
|
|
98
|
+
const target = roleTurnTarget(input);
|
|
99
|
+
const mailbox = store.getWorkMailbox(target);
|
|
100
|
+
const current = captureRoleTurnDispatch(mailbox, input);
|
|
101
|
+
if (current === null || mailbox === null)
|
|
102
|
+
return "absent";
|
|
103
|
+
if (expected !== undefined && !sameRoleTurnDispatchToken(current, expected)) {
|
|
104
|
+
return "state-changed";
|
|
105
|
+
}
|
|
106
|
+
const token = expected ?? current;
|
|
107
|
+
if (token.kind === "processing") {
|
|
108
|
+
if (mailbox.processing?.batchId !== token.batchId)
|
|
109
|
+
return "state-changed";
|
|
110
|
+
store.saveWorkMailbox(completeProcessing(mailbox, token.batchId));
|
|
111
|
+
return "settled";
|
|
112
|
+
}
|
|
113
|
+
if (mailbox.pending === null
|
|
114
|
+
|| mailbox.pending.fromSequence !== token.fromSequence
|
|
115
|
+
|| mailbox.pending.toSequence < token.toSequence) {
|
|
116
|
+
return "state-changed";
|
|
117
|
+
}
|
|
118
|
+
store.saveWorkMailbox(consumePendingBatch(mailbox, token));
|
|
119
|
+
return "settled";
|
|
120
|
+
}
|
|
14
121
|
/** Completes only the batch owned by the matching durable execution. */
|
|
15
122
|
export function completeWorkExecution(store, target, executionRef) {
|
|
16
123
|
const mailbox = store.getWorkMailbox(target);
|
|
@@ -76,6 +183,31 @@ export function settleExactWorkExecution(store, target, executionRef) {
|
|
|
76
183
|
function timestamp(value) {
|
|
77
184
|
return value instanceof Date ? value.toISOString() : value;
|
|
78
185
|
}
|
|
186
|
+
function roleTurnTarget(input) {
|
|
187
|
+
return {
|
|
188
|
+
kind: "role",
|
|
189
|
+
taskId: input.taskId,
|
|
190
|
+
roleName: input.roleName
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function roleTurnRef(input) {
|
|
194
|
+
return {
|
|
195
|
+
type: "turn",
|
|
196
|
+
taskId: input.taskId,
|
|
197
|
+
id: input.turnId
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
function roleTurnDispatchDedupeKey(input) {
|
|
201
|
+
return `role-turn:${input.taskId}:${input.roleName}:${input.turnId}`;
|
|
202
|
+
}
|
|
203
|
+
function sameRoleTurnDispatchToken(left, right) {
|
|
204
|
+
return left.kind === right.kind
|
|
205
|
+
&& (left.kind === "pending"
|
|
206
|
+
? right.kind === "pending"
|
|
207
|
+
&& left.fromSequence === right.fromSequence
|
|
208
|
+
&& left.toSequence === right.toSequence
|
|
209
|
+
: right.kind === "processing" && left.batchId === right.batchId);
|
|
210
|
+
}
|
|
79
211
|
function targetLabel(target) {
|
|
80
212
|
switch (target.kind) {
|
|
81
213
|
case "operator": return "operator";
|
|
@@ -593,6 +593,7 @@ function parseBeginHandoverParams(value) {
|
|
|
593
593
|
}
|
|
594
594
|
const fromReleaseId = record.fromReleaseId;
|
|
595
595
|
if (fromReleaseId !== undefined
|
|
596
|
+
&& fromReleaseId !== null
|
|
596
597
|
&& (typeof fromReleaseId !== "string" || fromReleaseId.length > 256)) {
|
|
597
598
|
return null;
|
|
598
599
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export const MAX_TURN_RESULT_OUTPUT_BYTES = 512 * 1024;
|
|
2
|
+
export const MAX_TURN_FAILURE_DIAGNOSTIC_BYTES = 16 * 1024;
|
|
3
|
+
/**
|
|
4
|
+
* Validate only the transport envelope of an Agent result. The accepted text
|
|
5
|
+
* remains byte-for-byte unchanged; missing or untransportable text becomes a
|
|
6
|
+
* Core-owned failed outcome so the exact Turn can still terminalize.
|
|
7
|
+
*/
|
|
8
|
+
export function transportAgentResult(value) {
|
|
9
|
+
if (typeof value !== "string") {
|
|
10
|
+
return {
|
|
11
|
+
status: "failed",
|
|
12
|
+
diagnostic: "Provider terminal event did not include an Agent result.",
|
|
13
|
+
failureReason: "missing-result"
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (value.includes("\0")) {
|
|
17
|
+
return {
|
|
18
|
+
status: "failed",
|
|
19
|
+
diagnostic: "Provider terminal event included an Agent result with an invalid NUL byte.",
|
|
20
|
+
failureReason: "missing-result"
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
if (value.trim().length === 0) {
|
|
24
|
+
return {
|
|
25
|
+
status: "failed",
|
|
26
|
+
diagnostic: "Provider terminal event included an empty Agent result.",
|
|
27
|
+
failureReason: "missing-result"
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
const bytes = Buffer.byteLength(value, "utf8");
|
|
31
|
+
if (bytes > MAX_TURN_RESULT_OUTPUT_BYTES) {
|
|
32
|
+
return {
|
|
33
|
+
status: "failed",
|
|
34
|
+
diagnostic: `Provider Agent result is ${bytes} bytes and exceeds the ${MAX_TURN_RESULT_OUTPUT_BYTES}-byte durable result limit; the result was not stored.`,
|
|
35
|
+
failureReason: "missing-result"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return { status: "completed", output: value };
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Bound Core-owned failure diagnostics without rejecting a terminal event.
|
|
42
|
+
* This is intentionally separate from Agent result transport: successful
|
|
43
|
+
* Agent text is either retained exactly or rejected as a whole, never
|
|
44
|
+
* truncated. Provider/Core diagnostics may be clipped because they are only
|
|
45
|
+
* operational context for a failed Turn.
|
|
46
|
+
*/
|
|
47
|
+
export function boundedTurnFailureDiagnostic(value, fallback = "Provider reported a failed Agent Turn.") {
|
|
48
|
+
const candidate = typeof value === "string" && value.trim().length > 0
|
|
49
|
+
? value
|
|
50
|
+
: fallback;
|
|
51
|
+
const safe = candidate.replaceAll("\0", "\uFFFD");
|
|
52
|
+
if (Buffer.byteLength(safe, "utf8") <= MAX_TURN_FAILURE_DIAGNOSTIC_BYTES) {
|
|
53
|
+
return safe;
|
|
54
|
+
}
|
|
55
|
+
const prefix = Buffer
|
|
56
|
+
.from(safe, "utf8")
|
|
57
|
+
.subarray(0, MAX_TURN_FAILURE_DIAGNOSTIC_BYTES)
|
|
58
|
+
.toString("utf8");
|
|
59
|
+
return prefix.endsWith("\uFFFD") ? prefix.slice(0, -1) : prefix;
|
|
60
|
+
}
|