openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
67 lines (66 loc) • 3.63 kB
JavaScript
import { g as projectWorkerSessionTurnClaim, h as placementTurnOwner, x as serializeWorkerSessionTurnClaim } from "./placement-record-BOfTzlFO.js";
import { r as getWorkerTurnExecutionIdentityCapability } from "./placement-turn-claim-events-Baq1Tn78.js";
//#region src/gateway/worker-environments/placement-worker-gate.ts
function claimForBinding(record, binding) {
const claim = record ? projectWorkerSessionTurnClaim(record) : void 0;
return claim?.sessionId === binding.sessionId && claim.owner.environmentId === binding.environmentId && claim.owner.ownerEpoch === binding.ownerEpoch ? claim : void 0;
}
function claimForOwnerRevocation(record, binding) {
if (record?.state !== "active" && record?.state !== "draining" || record.environmentId !== binding.environmentId || record.activeOwnerEpoch !== binding.ownerEpoch || !record.turnClaim) return;
return {
sessionId: record.sessionId,
claimId: record.turnClaim.claimId,
runId: record.turnClaim.runId,
placementGeneration: record.turnClaim.generation,
owner: placementTurnOwner(record)
};
}
function createWorkerSessionPlacementGate(store, options = {}) {
const recoveryOnlyClaims = new Set(options.rejectExistingWorkerClaims ? store.list().flatMap((record) => {
const claim = projectWorkerSessionTurnClaim(record);
return claim ? [serializeWorkerSessionTurnClaim(claim)] : [];
}) : []);
const isOperational = (claim) => !recoveryOnlyClaims.has(serializeWorkerSessionTurnClaim(claim)) && store.validateTurnClaim(claim);
const readWorkerTurnClaim = (binding) => {
const claim = claimForBinding(store.get(binding.sessionId), binding);
return claim && store.validateTurnClaim(claim) ? claim : void 0;
};
const validateWorkerTurn = (claim) => isOperational(claim);
return {
readWorkerTurnClaim,
getExecutionIdentityCapability: (claim) => getWorkerTurnExecutionIdentityCapability(store, claim),
validateWorkerTurn,
readWorkerTurnLiveAckCursor(claim) {
if (!validateWorkerTurn(claim)) throw new Error(`Cannot read ACK cursor for stale worker turn ${claim.sessionId}`);
const placement = store.get(claim.sessionId);
if (!placement) throw new Error(`Worker placement disappeared for session ${claim.sessionId}`);
return placement.lastLiveEventAckCursor ?? 0;
},
isWorkerTurnToolAuthorized(claim, toolName) {
return validateWorkerTurn(claim) && store.isWorkerTurnToolAuthorized(claim, toolName);
},
updateAckCursors(input) {
if (!validateWorkerTurn(input.claim)) throw new Error(`Cannot ACK stale worker turn for session ${input.claim.sessionId}`);
store.updateAckCursors({
claim: input.claim,
...input.transcriptSeq === void 0 ? {} : { transcript: input.transcriptSeq },
...input.liveSeq === void 0 ? {} : { liveEvent: input.liveSeq }
});
},
prepareWorkspaceResultOwnerRevocation(binding, error) {
const claim = claimForOwnerRevocation(store.get(binding.sessionId), binding);
if (!claim) return;
const pending = store.listPendingWorkspaceResults().find((candidate) => candidate.sessionId === claim.sessionId && candidate.claimId === claim.claimId && candidate.runId === claim.runId);
if (!pending) return;
if (pending.gatewayInstanceId !== store.workspaceResultInstanceId()) return;
if (claim.owner.kind === "local" && pending.stagedResultRef === null && pending.workspaceAcceptedAtMs === null) {
store.failWorkspaceResultAndReleaseTurn(pending, error);
return;
}
store.handoffWorkspaceResultRecovery(claim);
},
registerTurnClaimClosedHandler: (handler) => store.registerTurnClaimClosedHandler(handler)
};
}
//#endregion
export { createWorkerSessionPlacementGate };