gestalt-mobile 0.35.3 → 0.35.4
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.
|
@@ -588,7 +588,7 @@ export async function composeRelayApp(options) {
|
|
|
588
588
|
if (rawInteraction.kind === 'autopilotWaitLease') {
|
|
589
589
|
const lease = rawInteraction.payload;
|
|
590
590
|
const rootOwned = origin.kind === 'root' && origin.physicalTurnId === session.activeTurnId;
|
|
591
|
-
const
|
|
591
|
+
const registration = rootOwned &&
|
|
592
592
|
(lease.version === 2
|
|
593
593
|
? autopilot.registerProactiveWait(sessionId, {
|
|
594
594
|
id: lease.reportId,
|
|
@@ -602,10 +602,12 @@ export async function composeRelayApp(options) {
|
|
|
602
602
|
leaseId: lease.leaseId,
|
|
603
603
|
wakeConditions: lease.wakeConditions,
|
|
604
604
|
}));
|
|
605
|
-
if (
|
|
606
|
-
if (rootOwned)
|
|
605
|
+
if (registration !== true) {
|
|
606
|
+
if (rootOwned && registration === false)
|
|
607
607
|
autopilot.rejectProbe(sessionId);
|
|
608
|
-
return (runtime?.resolveServerRequest(sessionId, rawInteraction.requestId, autopilotWaitLeaseToolResponse(false
|
|
608
|
+
return (runtime?.resolveServerRequest(sessionId, rawInteraction.requestId, autopilotWaitLeaseToolResponse(false, registration === 'wakeAlreadySatisfied'
|
|
609
|
+
? 'wakeAlreadySatisfied'
|
|
610
|
+
: 'automaticContinuationUnavailable')) === true);
|
|
609
611
|
}
|
|
610
612
|
return (runtime?.resolveServerRequest(sessionId, rawInteraction.requestId, autopilotWaitLeaseToolResponse()) === true);
|
|
611
613
|
}
|
|
@@ -162,6 +162,24 @@ export class AutopilotCoordinator {
|
|
|
162
162
|
report.maxWaitMs > AUTOPILOT_WAIT_MAX_MS)
|
|
163
163
|
return false;
|
|
164
164
|
const now = this.deps.now();
|
|
165
|
+
if (this.executorWakeAlreadySatisfied(sessionId, state, report.wakeConditions)) {
|
|
166
|
+
// The executor edge is already visible. Fence every pending automatic
|
|
167
|
+
// callback before returning control to the still-active root; otherwise
|
|
168
|
+
// a scheduled executor resume could race same-turn supervision.
|
|
169
|
+
const cancelled = this.cancelScheduledControl(state, now);
|
|
170
|
+
this.persist({
|
|
171
|
+
...state,
|
|
172
|
+
generation: state.generation + 1,
|
|
173
|
+
...(cancelled ? { lastControlId: null } : {}),
|
|
174
|
+
nextEvaluationAt: null,
|
|
175
|
+
updatedAt: now,
|
|
176
|
+
}, cancelled);
|
|
177
|
+
this.timers.get(sessionId)?.();
|
|
178
|
+
this.timers.delete(sessionId);
|
|
179
|
+
this.completionTimers.get(sessionId)?.();
|
|
180
|
+
this.completionTimers.delete(sessionId);
|
|
181
|
+
return 'wakeAlreadySatisfied';
|
|
182
|
+
}
|
|
165
183
|
const resumeAt = new Date(Date.parse(now) + report.maxWaitMs).toISOString();
|
|
166
184
|
const protocol = state.supervision ?? startSupervisionProtocol(this.progressKey(sessionId));
|
|
167
185
|
const nextProtocol = registerProtocolWait(protocol, { ...report, resumeAt });
|
|
@@ -185,6 +203,19 @@ export class AutopilotCoordinator {
|
|
|
185
203
|
this.armWaitDeadline(sessionId, report.leaseId, resumeAt);
|
|
186
204
|
return true;
|
|
187
205
|
}
|
|
206
|
+
/** Prevents an edge-triggered executor lease from parking after its edge. */
|
|
207
|
+
executorWakeAlreadySatisfied(sessionId, state, wakeConditions) {
|
|
208
|
+
if (!wakeConditions.includes('executorChanged'))
|
|
209
|
+
return false;
|
|
210
|
+
if (this.completionTimers.has(sessionId))
|
|
211
|
+
return true;
|
|
212
|
+
const retained = this.deps.plan(sessionId);
|
|
213
|
+
const activity = this.deps.activity(sessionId);
|
|
214
|
+
if (!retained || activity?.confidence !== 'fresh')
|
|
215
|
+
return false;
|
|
216
|
+
const executor = this.currentExecutor(sessionId, retained.plan, state.consecutiveNoProgress, state.executor);
|
|
217
|
+
return Boolean(executor && !this.authoritativeExecutorActive(state, retained.plan, activity));
|
|
218
|
+
}
|
|
188
219
|
/** Fails closed only for the currently active bounded probe. */
|
|
189
220
|
rejectProbe(sessionId) {
|
|
190
221
|
const state = this.deps.store.find(sessionId);
|
|
@@ -1074,6 +1105,10 @@ export class AutopilotCoordinator {
|
|
|
1074
1105
|
this.completionTimers.delete(sessionId);
|
|
1075
1106
|
this.executorTimers.get(sessionId)?.();
|
|
1076
1107
|
this.executorTimers.delete(sessionId);
|
|
1108
|
+
this.cancelScheduledExecutorCommands(sessionId);
|
|
1109
|
+
}
|
|
1110
|
+
/** Cancels executor authority while allowing a delivered stale callback to audit itself. */
|
|
1111
|
+
cancelScheduledExecutorCommands(sessionId) {
|
|
1077
1112
|
const state = this.deps.store.find(sessionId);
|
|
1078
1113
|
const executor = state?.executor;
|
|
1079
1114
|
if (state && executor?.commands?.some((command) => command.status === 'scheduled'))
|
|
@@ -74,7 +74,7 @@ export function parseAutopilotWaitLease(value) {
|
|
|
74
74
|
maxWaitMs: value.maxWaitMs,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
export function autopilotWaitLeaseToolResponse(accepted = true) {
|
|
77
|
+
export function autopilotWaitLeaseToolResponse(accepted = true, reason = 'automaticContinuationUnavailable') {
|
|
78
78
|
return {
|
|
79
79
|
success: true,
|
|
80
80
|
contentItems: [
|
|
@@ -82,7 +82,7 @@ export function autopilotWaitLeaseToolResponse(accepted = true) {
|
|
|
82
82
|
type: 'inputText',
|
|
83
83
|
text: accepted
|
|
84
84
|
? '{"accepted":true}'
|
|
85
|
-
:
|
|
85
|
+
: JSON.stringify({ accepted: false, reason, next: 'continueSameTurn' }),
|
|
86
86
|
},
|
|
87
87
|
],
|
|
88
88
|
};
|