reploid 0.0.0-stage → 0.1.1
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/apps/poolday/config/chat-files.json +27 -0
- package/apps/poolday/config/partition-generation.js +21 -0
- package/apps/poolday/config/partition-policy.json +74 -0
- package/apps/poolday/config/partition-releases.json +3 -0
- package/apps/poolday/config/work-profile.json +122 -0
- package/apps/poolday/host/chat-view.js +47 -0
- package/apps/poolday/host/earning/client.js +199 -0
- package/apps/poolday/host/earning/contribution.js +168 -0
- package/apps/poolday/host/partition-release.js +33 -0
- package/apps/poolday/host/work-partition-artifact-source.js +37 -0
- package/apps/poolday/host/work-partition-capsule.js +39 -0
- package/apps/poolday/host/work-partition-plan.js +167 -0
- package/apps/poolday/host/work-partition-tokenizer-guard.js +21 -0
- package/apps/poolday/infrastructure/model-storage-lock.js +22 -0
- package/apps/poolday/infrastructure/pack-release-storage.js +52 -0
- package/apps/poolday/pool/pack-operation.js +161 -0
- package/apps/poolday/pool/pack-release-policy.js +44 -0
- package/apps/poolday/pool/peer-pack-data-channel.js +217 -0
- package/apps/poolday/providers/work-adapter.js +67 -0
- package/apps/poolday/providers/work-device.js +33 -0
- package/apps/poolday/providers/work-generation-completion.js +55 -0
- package/apps/poolday/providers/work-provider.js +209 -0
- package/apps/poolday/providers/work-resident-provider.js +113 -0
- package/deploy/artifacts/doppler-gpu-0.7.1.tgz +0 -0
- package/docs/fleet-service.md +214 -0
- package/docs/native-participant.md +542 -0
- package/native-delivery.json +1174 -0
- package/package.json +29 -4
- package/packages/reploid/src/artifacts/binary.js +25 -0
- package/packages/reploid/src/artifacts/canonical-json.js +23 -0
- package/packages/reploid/src/artifacts/custody/exchange.js +402 -0
- package/packages/reploid/src/artifacts/custody/piece-acquisition.js +70 -0
- package/packages/reploid/src/artifacts/custody/runtime.js +404 -0
- package/packages/reploid/src/artifacts/custody/supply-budget.js +19 -0
- package/packages/reploid/src/artifacts/custody-certificate.js +123 -0
- package/packages/reploid/src/artifacts/delivery-attestation.js +64 -0
- package/packages/reploid/src/artifacts/generation-terminal.js +36 -0
- package/packages/reploid/src/artifacts/identity.js +91 -0
- package/packages/reploid/src/artifacts/participant-proofs.js +159 -0
- package/packages/reploid/src/artifacts/receipt.js +131 -0
- package/packages/reploid/src/artifacts/signatures.js +94 -0
- package/packages/reploid/src/artifacts/whole-model-receipt.js +42 -0
- package/packages/reploid/src/cancellation.js +44 -0
- package/packages/reploid/src/config/defaults.json +110 -0
- package/packages/reploid/src/config/index.js +209 -0
- package/packages/reploid/src/config/request-overrides.json +9 -0
- package/packages/reploid/src/config/transport-defaults.json +7 -0
- package/packages/reploid/src/hashing.js +30 -0
- package/packages/reploid/src/measurement/capacity-utilization.js +321 -0
- package/packages/reploid/src/measurement/index.js +5 -0
- package/packages/reploid/src/measurement/readiness-records.js +310 -0
- package/packages/reploid/src/mesh/computer-identity.js +50 -0
- package/packages/reploid/src/mesh/computer-identity.policy.json +8 -0
- package/packages/reploid/src/mesh/contribution.js +141 -0
- package/packages/reploid/src/mesh/generation-recovery.js +58 -0
- package/packages/reploid/src/mesh/gpu-signature-shader.js +27 -0
- package/packages/reploid/src/mesh/gpu-signature.js +136 -0
- package/packages/reploid/src/mesh/gpu-signature.policy.json +11 -0
- package/packages/reploid/src/mesh/index.js +66 -0
- package/packages/reploid/src/mesh/partitions/automatic-ordered-partitions.js +540 -0
- package/packages/reploid/src/mesh/partitions/automatic-partitions.js +298 -0
- package/packages/reploid/src/mesh/partitions/partition-attempt-evidence.js +282 -0
- package/packages/reploid/src/mesh/partitions/partition-attempt-queue-policy.json +6 -0
- package/packages/reploid/src/mesh/partitions/partition-attempt-queue.js +112 -0
- package/packages/reploid/src/mesh/partitions/partition-canonical-contract.js +167 -0
- package/packages/reploid/src/mesh/partitions/partition-canonical-execution.js +168 -0
- package/packages/reploid/src/mesh/partitions/partition-chat-canonical.js +49 -0
- package/packages/reploid/src/mesh/partitions/partition-chat.js +125 -0
- package/packages/reploid/src/mesh/partitions/partition-contract.js +192 -0
- package/packages/reploid/src/mesh/partitions/partition-device-admission.js +96 -0
- package/packages/reploid/src/mesh/partitions/partition-discovery.js +96 -0
- package/packages/reploid/src/mesh/partitions/partition-entry-publication.js +183 -0
- package/packages/reploid/src/mesh/partitions/partition-entry.js +434 -0
- package/packages/reploid/src/mesh/partitions/partition-generation-request.js +33 -0
- package/packages/reploid/src/mesh/partitions/partition-grants.js +277 -0
- package/packages/reploid/src/mesh/partitions/partition-link.js +103 -0
- package/packages/reploid/src/mesh/partitions/partition-network.js +109 -0
- package/packages/reploid/src/mesh/partitions/partition-ordered-chat.js +290 -0
- package/packages/reploid/src/mesh/partitions/partition-ordered-peer.js +415 -0
- package/packages/reploid/src/mesh/partitions/partition-ordered-publication.js +100 -0
- package/packages/reploid/src/mesh/partitions/partition-peer.js +314 -0
- package/packages/reploid/src/mesh/partitions/partition-placement.js +143 -0
- package/packages/reploid/src/mesh/partitions/partition-preparation-progress.js +25 -0
- package/packages/reploid/src/mesh/partitions/partition-receiver-policy.json +7 -0
- package/packages/reploid/src/mesh/partitions/partition-reservations.js +75 -0
- package/packages/reploid/src/mesh/partitions/partition-route-envelope-policy.json +16 -0
- package/packages/reploid/src/mesh/partitions/partition-route-envelope.js +74 -0
- package/packages/reploid/src/mesh/partitions/partition-route-execution.js +409 -0
- package/packages/reploid/src/mesh/partitions/partition-route-network.js +179 -0
- package/packages/reploid/src/mesh/partitions/partition-route-ranking.js +268 -0
- package/packages/reploid/src/mesh/partitions/partition-runner.js +319 -0
- package/packages/reploid/src/mesh/partitions/partition-stage-assignment.js +109 -0
- package/packages/reploid/src/mesh/partitions/partition-stage-commit.js +103 -0
- package/packages/reploid/src/mesh/partitions/partition-step-receiver.js +291 -0
- package/packages/reploid/src/mesh/partitions/partition-summary.js +122 -0
- package/packages/reploid/src/mesh/partitions/preparation-owner.js +40 -0
- package/packages/reploid/src/mesh/partitions/resident-error-codes.json +10 -0
- package/packages/reploid/src/mesh/partitions/resident-partition.js +333 -0
- package/packages/reploid/src/mesh/partitions/resident-route.js +46 -0
- package/packages/reploid/src/mesh/partitions/signed-resident-factory.js +59 -0
- package/packages/reploid/src/mesh/peer-generation.js +896 -0
- package/packages/reploid/src/mesh/peer-identity.js +87 -0
- package/packages/reploid/src/mesh/placement-beliefs.js +107 -0
- package/packages/reploid/src/mesh/preparation-progress.js +46 -0
- package/packages/reploid/src/mesh/provider-hardware.js +11 -0
- package/packages/reploid/src/mesh/remote-generation-requests.js +53 -0
- package/packages/reploid/src/mesh/swarm-coordination.js +140 -0
- package/packages/reploid/src/mesh/web-access-network.js +112 -0
- package/packages/reploid/src/mesh/web-access-policy.json +17 -0
- package/packages/reploid/src/retrieval/citations.js +156 -0
- package/packages/reploid/src/retrieval/claim-support.js +113 -0
- package/packages/reploid/src/retrieval/costs.js +101 -0
- package/packages/reploid/src/retrieval/fixed-provider.js +34 -0
- package/packages/reploid/src/retrieval/index.js +20 -0
- package/packages/reploid/src/retrieval/lexical-support.js +27 -0
- package/packages/reploid/src/retrieval/model-reviewer.js +67 -0
- package/packages/reploid/src/retrieval/page-fetch.json +10 -0
- package/packages/reploid/src/retrieval/page-text.js +182 -0
- package/packages/reploid/src/retrieval/passage.js +37 -0
- package/packages/reploid/src/retrieval/policy.json +14 -0
- package/packages/reploid/src/retrieval/retrieval.js +23 -0
- package/packages/reploid/src/retrieval/review-queue.js +76 -0
- package/packages/reploid/src/retrieval/sources.js +263 -0
- package/packages/reploid/src/retrieval/support-review.js +155 -0
- package/packages/reploid/src/retrieval/text.js +21 -0
- package/packages/reploid/src/rules/contribution.rules.json +8 -0
- package/packages/reploid/src/rules/routing.rules.json +24 -0
- package/packages/reploid/src/transport/assignment.js +571 -0
- package/packages/reploid/src/transport/bounded-channel-writer.js +46 -0
- package/packages/reploid/src/transport/index.js +11 -0
- package/packages/reploid/src/transport/introduction-admission.js +24 -0
- package/packages/reploid/src/transport/introduction-bootstrap.js +112 -0
- package/packages/reploid/src/transport/introduction-policy.json +12 -0
- package/packages/reploid/src/transport/introduction-records.js +90 -0
- package/packages/reploid/src/transport/introductions.js +209 -0
- package/packages/reploid/src/transport/partition-data-channel.js +421 -0
- package/packages/reploid/src/transport/partition-errors.json +16 -0
- package/packages/reploid/src/transport/retry-policy.js +36 -0
- package/packages/reploid/src/transport/room.js +502 -0
- package/packages/reploid/src/transport/sdp-fingerprint.js +5 -0
- package/packages/reploid/src/transport/signaling.js +571 -0
- package/packages/reploid/src/transport/swarm.js +1247 -0
- package/packages/reploid/src/transport/tool-offer-channel.js +137 -0
- package/server/browser-roots.js +42 -0
- package/server/browser-web-worker.js +94 -0
- package/server/chat-completions.js +45 -0
- package/server/fleet/browser-bridge.js +145 -0
- package/server/fleet/contract.js +42 -0
- package/server/fleet/credit-evidence.js +103 -0
- package/server/fleet/credit-recovery.js +175 -0
- package/server/fleet/credits.js +178 -0
- package/server/fleet/execution-admission.js +32 -0
- package/server/fleet/native-host.js +817 -0
- package/server/fleet/placement.js +132 -0
- package/server/fleet/requester.js +346 -0
- package/server/fleet/service.js +311 -0
- package/server/fleet/terminal-policy.js +83 -0
- package/server/fleet/text-api.js +94 -0
- package/server/hashing.js +35 -0
- package/server/http-request-owner.js +49 -0
- package/server/messages.js +57 -0
- package/server/native-canonical-epochs.js +90 -0
- package/server/native-change-log.js +40 -0
- package/server/native-earning.js +203 -0
- package/server/native-generation-journal.js +46 -0
- package/server/native-model-config.js +57 -0
- package/server/native-model-files.js +382 -0
- package/server/native-model-origin.js +54 -0
- package/server/native-model-origins.json +12 -0
- package/server/native-node.js +85 -0
- package/server/native-owner/controls.js +162 -0
- package/server/native-owner/monitor.js +251 -0
- package/server/native-owner/policy.js +273 -0
- package/server/native-owner/rate.js +92 -0
- package/server/native-participant.js +866 -0
- package/server/native-readiness-log.js +30 -0
- package/server/native-release-storage.js +64 -0
- package/server/native-shader-cache.js +369 -0
- package/server/native-supply-budget.js +66 -0
- package/server/native-whole-earning.js +67 -0
- package/server/native-whole-model-fill.js +182 -0
- package/server/native-whole-model.js +130 -0
- package/server/public-web-worker.js +66 -0
- package/server/responses.js +92 -0
- package/server/search/errors.js +47 -0
- package/server/search/page-fetch.js +185 -0
- package/server/text-api.js +83 -0
- package/server/text-recovery.js +45 -0
- package/server/text-request-options.js +23 -0
- package/server/text-requester.js +231 -0
- package/server/token-auth.js +9 -0
- package/server/whole-model-requester.js +99 -0
- package/shared/config/chat-models.json +4685 -0
- package/shared/config/doppler-execution-contracts.js +32 -0
- package/shared/config/doppler-execution-contracts.json +43 -0
- package/shared/config/doppler-generation-contract.js +223 -0
- package/shared/config/doppler-local-models.js +79 -0
- package/shared/config/doppler-package.json +7 -0
- package/shared/config/model-manifests/a0dc69e917133a82780823d17fc771c0f6b882d7c86c571deeaef45be2ff108b.json +6434 -0
- package/shared/config/model-manifests/e985e3cdad60d0cb57d84b436161e66ab5b3f6589a168de6f00b4610e5f1fb59.json +16534 -0
- package/shared/config/model-manifests/fa6eb7bbc3ba63571f8cede780b877d9272bde948697af93dd3d33837cb46137.json +7175 -0
- package/shared/config/model-pieces/qwen-0-8b-pieces.json +1506 -0
- package/shared/config/model-pieces/qwen-2b-pieces.json +4800 -0
- package/shared/config/model-pieces/qwen35b-q4_0-pieces.json +28880 -0
- package/shared/config/reploid-library.json +49 -0
- package/shared/config/swarm-bootstrap.json +21 -0
- package/shared/infrastructure/doppler-runtime-service.js +261 -0
- package/shared/pool/executable-pack.js +87 -0
- package/shared/pool/pack-operation-adapters.js +124 -0
- package/shared/pool/pack-operation-policy.js +75 -0
- package/shared/pool/pool-config.json +2280 -0
- package/shared/vendor/reploid/adapters/doppler-session.js +372 -0
- package/shared/vendor/reploid/artifacts/binary.js +25 -0
- package/shared/vendor/reploid/artifacts/canonical-json.js +23 -0
- package/shared/vendor/reploid/artifacts/delivery-attestation.js +64 -0
- package/shared/vendor/reploid/artifacts/identity.js +91 -0
- package/shared/vendor/reploid/artifacts/manifest-identity.js +17 -0
- package/shared/vendor/reploid/artifacts/participant-proofs.js +159 -0
- package/shared/vendor/reploid/artifacts/signatures.js +94 -0
- package/shared/vendor/reploid/config/defaults.json +110 -0
- package/shared/vendor/reploid/config/index.js +209 -0
- package/shared/vendor/reploid/config/request-overrides.json +9 -0
- package/shared/vendor/reploid/hashing.js +30 -0
- package/shared/vendor/reploid/mesh/generation-context-cache.js +97 -0
- package/shared/vendor/reploid/mesh/partitions/partition-attempt-evidence.js +282 -0
- package/shared/vendor/reploid/mesh/partitions/partition-contract.js +192 -0
- package/shared/vendor/reploid/mesh/partitions/partition-receiver-policy.json +7 -0
- package/shared/vendor/reploid/mesh/partitions/partition-route-ranking.js +268 -0
- package/shared/vendor/reploid/mesh/preparation-progress.js +46 -0
- package/shared/vendor/reploid/mesh/provider-hardware.js +11 -0
- package/shared/vendor/reploid/rules/routing.rules.json +24 -0
- package/shared/vendor/reploid/transport/partition-errors.json +16 -0
- package/README.md +0 -3
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { createPartitionDataChannel, partitionBinaryResult } from '../../transport/partition-data-channel.js';
|
|
2
|
+
import { createPartitionStepReceiver } from './partition-step-receiver.js';
|
|
3
|
+
import { assertPartition as assert, assertCapacity, partitionFailure, canonicalPartitionJson, canonicalRouteAttemptBinding,
|
|
4
|
+
sameRouteAttemptIdentity, validatePartitionRoute, partitionFingerprint, matchingPartitionActivation } from './partition-contract.js';
|
|
5
|
+
|
|
6
|
+
const SCHEMA = 'reploid.partition-stage-rpc/v2';
|
|
7
|
+
const GRANT_REFERENCE = 'reploid.partition-grant-reference/v1';
|
|
8
|
+
const GRANT_FIELDS = ['executionGrant', 'tokenContextGrant', 'incomingActivationGrant', 'outgoingActivationGrant', 'outputGrant'];
|
|
9
|
+
const equal = (a, b) => canonicalPartitionJson(a) === canonicalPartitionJson(b);
|
|
10
|
+
const unique = values => [...new Set(values)];
|
|
11
|
+
const grantDigest = grant => partitionFingerprint({ schema: GRANT_REFERENCE, grant });
|
|
12
|
+
const isReference = value => value?.schema === GRANT_REFERENCE && Object.keys(value).length === 2
|
|
13
|
+
&& /^sha256:[a-f0-9]{64}$/.test(value.digest);
|
|
14
|
+
/** Ordered mode of the existing peer. Binary outputs return to the explicitly disclosed coordinator
|
|
15
|
+
* on the reply to the step that produced them. A step names a signed grant already delivered for its
|
|
16
|
+
* attempt by digest; the stage resolves it only from grants it verified for that attempt. */
|
|
17
|
+
export function createOrderedPartitionPeer({ channel, localParticipantId, remoteParticipantId, runtime, plan,
|
|
18
|
+
planId, modelIdentity, authority, contributor, limits, receiverLimits, ordered, canonical }) {
|
|
19
|
+
assert(!canonical, 'Ordered canonical peer is unsupported');
|
|
20
|
+
plan = structuredClone(plan); ordered = structuredClone(ordered); receiverLimits = structuredClone(receiverLimits); limits = structuredClone(limits);
|
|
21
|
+
const { route, partitionIndex: index } = ordered, stage = route?.stages?.[index], coordinatorId = route?.stages?.[0]?.participantId;
|
|
22
|
+
assert(Number.isSafeInteger(index) && index > 0 && stage && authority?.verify
|
|
23
|
+
&& planId === route.planId && modelIdentity === route.modelIdentity, 'Explicit ordered peer binding required');
|
|
24
|
+
const serving = !!contributor;
|
|
25
|
+
assert(serving ? contributor.id === localParticipantId && contributor.index === index && remoteParticipantId === coordinatorId
|
|
26
|
+
&& localParticipantId === stage.participantId && ['transportId', 'residentId', 'executionId'].every(key => contributor[key] === stage[key])
|
|
27
|
+
: localParticipantId === coordinatorId && remoteParticipantId === stage.participantId, 'Ordered channel participant mismatch');
|
|
28
|
+
const ready = validatePartitionRoute(runtime, plan, route); ready.catch(() => {});
|
|
29
|
+
const confirmed = new Map(), retirementReceipts = new Map();
|
|
30
|
+
let undeliveredRetirements = 0;
|
|
31
|
+
const active = new Map(), reservations = new Map(), settlements = new Map(), inflight = new Set(), outputCharacters = new Map(), listeners = new Set();
|
|
32
|
+
// Per attempt: the grants a coordinator sent or a stage verified, by digest; and, on the coordinator,
|
|
33
|
+
// the digests its stage acknowledged receiving.
|
|
34
|
+
const delivered = new Map(), verifiedGrants = new Map();
|
|
35
|
+
let closed = false, retiring = false, remoteRetiring = false, closing = null, descriptor = null;
|
|
36
|
+
let channelClosed;
|
|
37
|
+
const remoteClose = new Promise(resolve => { channelClosed = resolve; });
|
|
38
|
+
const binding = request => {
|
|
39
|
+
const identity = canonicalRouteAttemptBinding(request.identity);
|
|
40
|
+
assert(equal(identity.route, route) && request.partitionIndex === index && request.coordinatorId === coordinatorId,
|
|
41
|
+
'Ordered peer route or stage mismatch');
|
|
42
|
+
return identity;
|
|
43
|
+
};
|
|
44
|
+
const protocol = request => {
|
|
45
|
+
assert(request?.schema === SCHEMA && ['reserve', 'step', 'settle', 'settle-accepted', 'retired'].includes(request.operation), 'Ordered peer message version mismatch');
|
|
46
|
+
return binding(request);
|
|
47
|
+
};
|
|
48
|
+
const scope = (request, action) => ({ identity: request.identity, coordinatorId, action,
|
|
49
|
+
partitionIndex: index, step: request.step, inputTokenCount: request.inputTokenCount,
|
|
50
|
+
generationDigest: request.generationDigest, activationBytes: request.frame?.byteLength });
|
|
51
|
+
const permit = async (request, action, grant, extra = {}, settlement = false) => {
|
|
52
|
+
const input = { ...scope(request, action), ...extra };
|
|
53
|
+
const { ok, reason } = authority.check ? await authority.check(grant, input, { settlement })
|
|
54
|
+
: { ok: await authority.verify(grant, input, { settlement }) === true, reason: null };
|
|
55
|
+
// The attempt's grant lifetime is its answer window: an expired grant reports the deadline.
|
|
56
|
+
if (reason === 'expired') throw partitionFailure('ANSWER_DEADLINE_EXCEEDED');
|
|
57
|
+
return ok;
|
|
58
|
+
};
|
|
59
|
+
const execution = (request, settlement = false) => permit(request, 'mesh.execute_partition_stage', request.executionGrant, {}, settlement);
|
|
60
|
+
const token = request => permit(request, 'mesh.transfer_token_context', request.tokenContextGrant,
|
|
61
|
+
{ recipients: unique([coordinatorId, stage.participantId]) });
|
|
62
|
+
const activation = (request, outgoing) => {
|
|
63
|
+
const fromStage = outgoing ? index : index - 1, toStage = fromStage + 1;
|
|
64
|
+
return permit(request, 'mesh.transfer_intermediate_activation', outgoing ? request.outgoingActivationGrant : request.incomingActivationGrant,
|
|
65
|
+
{ fromStage, toStage, recipients: unique([route.stages[fromStage].participantId, coordinatorId, route.stages[toStage]?.participantId]) });
|
|
66
|
+
};
|
|
67
|
+
const output = request => index === route.stages.length - 1
|
|
68
|
+
? permit(request, 'mesh.transfer_partition_output', request.outputGrant,
|
|
69
|
+
{ recipients: unique([stage.participantId, coordinatorId, request.identity.requesterId]) }) : activation(request, true);
|
|
70
|
+
const validStep = request => request.generation?.maxTokens === request.maxTokens && Number.isSafeInteger(request.step) && request.step >= 0
|
|
71
|
+
&& Number.isSafeInteger(request.maxTokens) && request.maxTokens > 0 && request.step < request.maxTokens
|
|
72
|
+
&& request.maxTokens <= request.executionGrant?.claim?.limits?.maxTokens
|
|
73
|
+
&& Number.isSafeInteger(request.tokenPosition) && request.tokenPosition >= 0
|
|
74
|
+
&& Number.isSafeInteger(request.inputTokenCount) && request.inputTokenCount > 0
|
|
75
|
+
&& Array.isArray(request.inputTokenIds) && request.inputTokenIds.length === request.inputTokenCount
|
|
76
|
+
&& request.inputTokenIds.every(id => Number.isSafeInteger(id) && id >= 0 && id < plan.vocabSize);
|
|
77
|
+
const validFrame = (request, byteLength, frame = request.frame) => {
|
|
78
|
+
const layout = route.activation;
|
|
79
|
+
return validStep(request) && frame?.schema === layout.schema && matchingPartitionActivation(frame, layout, true)
|
|
80
|
+
&& equal(frame.shape, [1, request.inputTokenCount, layout.hiddenSize]) && frame.step === request.step
|
|
81
|
+
&& frame.seqOffset === request.tokenPosition && frame.byteLength === byteLength && byteLength > 0
|
|
82
|
+
&& byteLength === request.inputTokenCount * layout.hiddenSize * layout.elementStrideBytes
|
|
83
|
+
&& byteLength <= request.executionGrant?.claim?.limits?.maxActivationBytes
|
|
84
|
+
&& sameRouteAttemptIdentity(frame.metadata?.identity, request.identity)
|
|
85
|
+
&& frame.metadata.partitionIndex === index && frame.metadata.step === request.step
|
|
86
|
+
&& frame.metadata.tokenPosition === request.tokenPosition && frame.metadata.generationDigest === request.generationDigest;
|
|
87
|
+
};
|
|
88
|
+
const frameMetadata = request => ({ identity: request.identity, partitionIndex: index, step: request.step,
|
|
89
|
+
tokenPosition: request.tokenPosition, generationDigest: request.generationDigest });
|
|
90
|
+
const snapshotRequest = request => { const { signal, ...data } = request; return { ...structuredClone(data), signal }; };
|
|
91
|
+
const activationBytes = request => request.inputTokenCount * route.activation.hiddenSize * route.activation.elementStrideBytes;
|
|
92
|
+
// A step's grant references resolve only to grants this stage verified (or this coordinator sent) for that same attempt.
|
|
93
|
+
const resolveGrants = metadata => {
|
|
94
|
+
if (metadata?.operation !== 'step') return metadata;
|
|
95
|
+
const known = verifiedGrants.get(metadata.identity?.attemptId);
|
|
96
|
+
for (const field of GRANT_FIELDS) {
|
|
97
|
+
if (!isReference(metadata[field])) continue;
|
|
98
|
+
const grant = known?.get(metadata[field].digest);
|
|
99
|
+
if (!grant) return null;
|
|
100
|
+
metadata[field] = structuredClone(grant);
|
|
101
|
+
}
|
|
102
|
+
return metadata;
|
|
103
|
+
};
|
|
104
|
+
const rememberGrants = async metadata => {
|
|
105
|
+
const attemptId = metadata.identity.attemptId;
|
|
106
|
+
if (!reservations.has(attemptId) && metadata.operation !== 'reserve') return;
|
|
107
|
+
const known = verifiedGrants.get(attemptId) ?? new Map();
|
|
108
|
+
for (const field of GRANT_FIELDS) {
|
|
109
|
+
if (metadata[field] && !isReference(metadata[field]) && known.size < GRANT_FIELDS.length) known.set(await grantDigest(metadata[field]), structuredClone(metadata[field]));
|
|
110
|
+
}
|
|
111
|
+
if (known.size) verifiedGrants.set(attemptId, known);
|
|
112
|
+
};
|
|
113
|
+
const control = (request, operation) => {
|
|
114
|
+
const { signal: _signal, activation: _activation, ...data } = request;
|
|
115
|
+
return { ...structuredClone(data), schema: SCHEMA, operation, coordinatorId, partitionIndex: index };
|
|
116
|
+
};
|
|
117
|
+
const receiver = createPartitionStepReceiver({ limits: receiverLimits, ordered: { stage },
|
|
118
|
+
authorize: async request => await execution(request) && await token(request) && await activation(request, false) && await output(request),
|
|
119
|
+
fingerprint: ({ payload, ...metadata }) => partitionFingerprint(metadata, payload),
|
|
120
|
+
executeStep: async (request, { signal }) => {
|
|
121
|
+
assert(serving && contributor.canAccept(request.identity), 'Ordered contributor unavailable');
|
|
122
|
+
const frame = { ...request.frame, buffer: request.payload.slice().buffer };
|
|
123
|
+
const decoded = runtime.validateActivationFrameForPlan(frame, plan);
|
|
124
|
+
const result = await contributor.executeStage({ ...request, activation: decoded, signal });
|
|
125
|
+
if (index === route.stages.length - 1) {
|
|
126
|
+
assert(typeof result.delta === 'string', 'Ordered final delta required');
|
|
127
|
+
const total = (outputCharacters.get(request.identity.attemptId) || 0) + result.delta.length;
|
|
128
|
+
assert(total <= request.executionGrant.claim.limits.maxOutputCharacters, 'Ordered output budget exhausted');
|
|
129
|
+
outputCharacters.set(request.identity.attemptId, total);
|
|
130
|
+
}
|
|
131
|
+
return result;
|
|
132
|
+
},
|
|
133
|
+
// The peer reservation owner closes the resident after receiver work settles,
|
|
134
|
+
// including reserve-before-first-step attempts unknown to this receiver.
|
|
135
|
+
settleAttempt: async () => {},
|
|
136
|
+
});
|
|
137
|
+
const settleLocal = (identity, acknowledged = null) => {
|
|
138
|
+
const previous = settlements.get(identity.attemptId);
|
|
139
|
+
if (previous) { assert(sameRouteAttemptIdentity(previous.identity, identity), 'Ordered settlement identity collision'); return previous.promise; }
|
|
140
|
+
const record = { identity: canonicalRouteAttemptBinding(identity), promise: null, completed: false, acknowledged: false, request: null };
|
|
141
|
+
settlements.set(identity.attemptId, record);
|
|
142
|
+
record.promise = (async () => {
|
|
143
|
+
const failures = [];
|
|
144
|
+
try { await receiver.closeAttempt(record.identity); } catch (error) { failures.push(error); }
|
|
145
|
+
try {
|
|
146
|
+
const closing = await contributor.closeAttempt({ identity: record.identity, partitionIndex: index, acknowledged });
|
|
147
|
+
record.signedReceipt = closing?.receipt ?? null;
|
|
148
|
+
} catch (error) { failures.push(error); }
|
|
149
|
+
if (failures.length) throw new AggregateError(failures, 'Ordered remote cleanup failed');
|
|
150
|
+
record.completed = true;
|
|
151
|
+
reservations.delete(identity.attemptId); outputCharacters.delete(identity.attemptId); verifiedGrants.delete(identity.attemptId);
|
|
152
|
+
})().catch(error => { settlements.delete(identity.attemptId); throw error; });
|
|
153
|
+
return record.promise;
|
|
154
|
+
};
|
|
155
|
+
const endpoint = createPartitionDataChannel({ channel, localParticipantId, remoteParticipantId, limits,
|
|
156
|
+
async authorize({ action, metadata, byteLength }) {
|
|
157
|
+
await ready;
|
|
158
|
+
if (closed || retiring && !['settle', 'settle-accepted', 'retired'].includes(metadata.operation)) {
|
|
159
|
+
// A retiring stage admits no new attempt: that is unavailable capacity, not a declined grant.
|
|
160
|
+
if (metadata.operation === 'reserve') throw partitionFailure('CAPACITY_UNAVAILABLE');
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
if (metadata.operation === 'describe') return byteLength === 0 && metadata.schema === SCHEMA;
|
|
164
|
+
try { protocol(metadata); } catch { return false; }
|
|
165
|
+
if (!resolveGrants(metadata)) return false;
|
|
166
|
+
const returningOutput = metadata.operation === 'retired';
|
|
167
|
+
const outbound = action === 'send' || action === 'accept';
|
|
168
|
+
if (returningOutput ? outbound !== serving : outbound === serving) return false;
|
|
169
|
+
if (metadata.operation === 'settle') return byteLength === 0 && execution(metadata, true);
|
|
170
|
+
if (metadata.operation === 'settle-accepted') {
|
|
171
|
+
const known = serving ? settlements.get(metadata.identity.attemptId)?.request : confirmed.get(metadata.identity.attemptId);
|
|
172
|
+
return byteLength === 0 && !!known && sameRouteAttemptIdentity(known.identity, metadata.identity)
|
|
173
|
+
&& known.generationDigest === metadata.generationDigest && await execution(metadata, true);
|
|
174
|
+
}
|
|
175
|
+
if (metadata.operation === 'retired') {
|
|
176
|
+
const known = serving ? retirementReceipts.get(metadata.identity.attemptId) : active.get(metadata.identity.attemptId) || confirmed.get(metadata.identity.attemptId);
|
|
177
|
+
return byteLength === 0 && !!known && sameRouteAttemptIdentity(known.identity, metadata.identity)
|
|
178
|
+
&& known.generationDigest === metadata.generationDigest && await execution(metadata, true);
|
|
179
|
+
}
|
|
180
|
+
if (!await execution(metadata) || await runtime.hashPartitionGeneration(metadata.generation) !== metadata.generationDigest) return false;
|
|
181
|
+
if (metadata.operation === 'reserve') {
|
|
182
|
+
const allowed = byteLength === 0
|
|
183
|
+
&& Number.isSafeInteger(metadata.maxTokens) && metadata.maxTokens > 0
|
|
184
|
+
&& metadata.maxTokens <= Math.min(receiverLimits.maxSteps, metadata.executionGrant.claim.limits.maxTokens)
|
|
185
|
+
&& metadata.generation?.maxTokens === metadata.maxTokens;
|
|
186
|
+
if (allowed && serving && action === 'receive') await rememberGrants(metadata);
|
|
187
|
+
return allowed;
|
|
188
|
+
}
|
|
189
|
+
if (!validFrame(metadata, byteLength)) return false;
|
|
190
|
+
const allowed = await token(metadata) && await activation(metadata, false) && await output(metadata)
|
|
191
|
+
&& (!serving || reservations.has(metadata.identity.attemptId));
|
|
192
|
+
if (allowed && serving && action === 'receive') await rememberGrants(metadata);
|
|
193
|
+
return allowed;
|
|
194
|
+
},
|
|
195
|
+
async serve(metadata, payload, { signal }) {
|
|
196
|
+
if (metadata.operation === 'describe') {
|
|
197
|
+
const state = contributor?.getState();
|
|
198
|
+
return { descriptor: state?.ready && typeof contributor.executeStage === 'function' ? state.descriptor : null,
|
|
199
|
+
stage: state?.ready ? stage : null, capability: state?.ready ? 'ordered-stage' : null };
|
|
200
|
+
}
|
|
201
|
+
if (metadata.operation === 'retired') {
|
|
202
|
+
assert(!serving, 'Only coordinator accepts remote retirement');
|
|
203
|
+
// This exact authenticated owner reports completed resident cleanup. A
|
|
204
|
+
// channel close or unrelated receipt never clears another reservation.
|
|
205
|
+
confirmed.set(metadata.identity.attemptId, { ...structuredClone(metadata), signedReceipt: metadata.receipt });
|
|
206
|
+
active.delete(metadata.identity.attemptId); retiring = true; remoteRetiring = true; descriptor = null;
|
|
207
|
+
// Do not notify a host that could close the channel before this reply.
|
|
208
|
+
// The retiring supplier closes it after receiving this acknowledgment.
|
|
209
|
+
return { settled: true, identity: metadata.identity, partitionIndex: index };
|
|
210
|
+
}
|
|
211
|
+
if (metadata.operation === 'reserve') {
|
|
212
|
+
assert(serving && !settlements.has(metadata.identity.attemptId), 'Ordered reservation already settled');
|
|
213
|
+
// A retiring stage or an exhausted receiver budget is unavailable capacity; the resident's own
|
|
214
|
+
// slot refusal below carries the same code across the channel.
|
|
215
|
+
assertCapacity(!closed && !retiring && (reservations.has(metadata.identity.attemptId)
|
|
216
|
+
|| reservations.size + settlements.size < receiverLimits.maxAttempts));
|
|
217
|
+
const previous = reservations.get(metadata.identity.attemptId);
|
|
218
|
+
assert(!previous || sameRouteAttemptIdentity(previous.identity, metadata.identity), 'Ordered reservation identity collision');
|
|
219
|
+
// May have been admitted even if the subsequent acknowledgment is lost.
|
|
220
|
+
reservations.set(metadata.identity.attemptId, structuredClone(metadata));
|
|
221
|
+
return contributor.reserve({ ...metadata, signal });
|
|
222
|
+
}
|
|
223
|
+
if (metadata.operation === 'settle-accepted') {
|
|
224
|
+
const record = settlements.get(metadata.identity.attemptId);
|
|
225
|
+
assert(serving && record?.completed, 'Ordered cleanup is not complete');
|
|
226
|
+
record.acknowledged = true;
|
|
227
|
+
if (!retiring) retirementReceipts.delete(metadata.identity.attemptId);
|
|
228
|
+
return { accepted: true };
|
|
229
|
+
}
|
|
230
|
+
if (metadata.operation === 'settle') {
|
|
231
|
+
const previous = reservations.get(metadata.identity.attemptId);
|
|
232
|
+
assert(!previous || sameRouteAttemptIdentity(previous.identity, metadata.identity), 'Ordered settlement identity collision');
|
|
233
|
+
const pending = settleLocal(metadata.identity, metadata.acknowledged ?? null), record = settlements.get(metadata.identity.attemptId);
|
|
234
|
+
record.request ||= structuredClone(metadata);
|
|
235
|
+
assert(record.request.generationDigest === metadata.generationDigest, 'Ordered settlement generation collision');
|
|
236
|
+
// Keep the request until its coordinator confirms receipt. Returning
|
|
237
|
+
// from serve does not establish delivery of the ordinary settle reply.
|
|
238
|
+
if (!record.acknowledged) retirementReceipts.set(metadata.identity.attemptId, record.request);
|
|
239
|
+
await pending; return { settled: true, ...(record.signedReceipt ? { receipt: record.signedReceipt } : {}) };
|
|
240
|
+
}
|
|
241
|
+
assert(resolveGrants(metadata), 'Ordered grant reference is not verified for this attempt');
|
|
242
|
+
const result = await receiver.receive({ ...metadata, payload }, { signal });
|
|
243
|
+
assert(sameRouteAttemptIdentity(result.identity, metadata.identity) && result.partitionIndex === index
|
|
244
|
+
&& result.step === metadata.step && result.tokenPosition === metadata.tokenPosition, 'Ordered output identity mismatch');
|
|
245
|
+
if (index === route.stages.length - 1) {
|
|
246
|
+
assert(!result.activationTensor && Number.isSafeInteger(result.tokenId) && result.tokenId >= 0 && result.tokenId < plan.vocabSize
|
|
247
|
+
&& typeof result.delta === 'string' && result.delta.length <= metadata.executionGrant.claim.limits.maxOutputCharacters
|
|
248
|
+
&& typeof result.done === 'boolean', 'Ordered final output mismatch');
|
|
249
|
+
const { logits: _logits, ...response } = result; return response;
|
|
250
|
+
}
|
|
251
|
+
assert(result.activationTensor && !('tokenId' in result) && !('delta' in result), 'Only final ordered stage may sample');
|
|
252
|
+
const frame = runtime.serializeActivationFrame({ ...result.activationTensor, metadata: frameMetadata(metadata) });
|
|
253
|
+
runtime.validateActivationFrameForPlan(frame, plan);
|
|
254
|
+
const { buffer, ...header } = frame;
|
|
255
|
+
const bytes = new Uint8Array(buffer);
|
|
256
|
+
assert(validFrame(metadata, bytes.byteLength, header), 'Ordered output frame mismatch');
|
|
257
|
+
const outputDigest = await partitionFingerprint(header, bytes);
|
|
258
|
+
const { activationTensor: _tensor, logits: _logits, ...rest } = result;
|
|
259
|
+
// The activation returns on this step's own reply, bound to its header by digest.
|
|
260
|
+
return partitionBinaryResult({ ...rest, frame: header, outputDigest }, bytes);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
const getState = () => ({ ready: !closed && !retiring && channel.readyState === 'open' && descriptor?.ready === true,
|
|
264
|
+
participantId: remoteParticipantId, descriptor: structuredClone(descriptor), receipt: endpoint.getReceipt(),
|
|
265
|
+
unsettled: serving ? new Set([...reservations.keys(), ...retirementReceipts.keys()]).size : active.size,
|
|
266
|
+
...(serving ? { undeliveredRetirements } : {}) });
|
|
267
|
+
const notify = () => { for (const listener of listeners) { try { listener(getState()); } catch {} } };
|
|
268
|
+
const closeAttempt = async ({ identity, acknowledged = null }) => {
|
|
269
|
+
identity = canonicalRouteAttemptBinding(identity);
|
|
270
|
+
await ready;
|
|
271
|
+
const previous = active.get(identity.attemptId);
|
|
272
|
+
if (!previous) {
|
|
273
|
+
const cached = confirmed.get(identity.attemptId);
|
|
274
|
+
assert(!cached || sameRouteAttemptIdentity(cached.identity, identity), 'Ordered settlement identity collision');
|
|
275
|
+
return cached?.signedReceipt ? { receipt: structuredClone(cached.signedReceipt) } : undefined;
|
|
276
|
+
}
|
|
277
|
+
assert(sameRouteAttemptIdentity(previous.identity, identity), 'Ordered settlement identity collision');
|
|
278
|
+
try {
|
|
279
|
+
if (!confirmed.has(identity.attemptId)) {
|
|
280
|
+
const result = await endpoint.request({ ...previous, operation: 'settle', ...(acknowledged ? { acknowledged } : {}) }, new Uint8Array());
|
|
281
|
+
assert(result.settled === true, 'Ordered settlement not acknowledged');
|
|
282
|
+
confirmed.set(identity.attemptId, { ...previous, signedReceipt: result.receipt ?? null });
|
|
283
|
+
}
|
|
284
|
+
const receipt = await endpoint.request({ ...previous, operation: 'settle-accepted' }, new Uint8Array());
|
|
285
|
+
assert(receipt.accepted === true, 'Ordered settlement receipt not acknowledged');
|
|
286
|
+
active.delete(identity.attemptId); delivered.delete(identity.attemptId); verifiedGrants.delete(identity.attemptId); notify();
|
|
287
|
+
} catch (error) {
|
|
288
|
+
// Only an already authenticated cleanup result can survive channel loss.
|
|
289
|
+
// Concurrent retirement also confirms this exact attempt; a closed
|
|
290
|
+
// channel by itself never supplies that evidence.
|
|
291
|
+
if ((!remoteRetiring && !closed) || !sameRouteAttemptIdentity(confirmed.get(identity.attemptId)?.identity, identity)) throw error;
|
|
292
|
+
active.delete(identity.attemptId);
|
|
293
|
+
}
|
|
294
|
+
const signedReceipt = confirmed.get(identity.attemptId)?.signedReceipt;
|
|
295
|
+
return signedReceipt ? { receipt: structuredClone(signedReceipt) } : undefined;
|
|
296
|
+
};
|
|
297
|
+
const close = () => {
|
|
298
|
+
if (closing) return closing;
|
|
299
|
+
retiring = true;
|
|
300
|
+
if (serving) for (const [id, request] of reservations) retirementReceipts.set(id, request);
|
|
301
|
+
closing = (async () => {
|
|
302
|
+
// Attempt known cleanup while the channel remains usable. Channel closure alone is not remote settlement.
|
|
303
|
+
const failures = [];
|
|
304
|
+
if (!serving) for (const request of active.values()) {
|
|
305
|
+
try { await closeAttempt({ identity: request.identity }); }
|
|
306
|
+
catch (error) {
|
|
307
|
+
// After channel loss no retry can confirm this owner. It stays counted in
|
|
308
|
+
// `unsettled` as unknown; it does not keep the dead port open forever.
|
|
309
|
+
if (!closed || error?.code !== 'CONNECTION_LOST') failures.push(error);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
descriptor = null;
|
|
313
|
+
try { await receiver.close(); } catch (error) { failures.push(error); }
|
|
314
|
+
if (serving) {
|
|
315
|
+
for (const [id, request] of retirementReceipts) {
|
|
316
|
+
let settled = false;
|
|
317
|
+
try {
|
|
318
|
+
await settleLocal(request.identity); settled = true;
|
|
319
|
+
const receipt = settlements.get(request.identity.attemptId)?.signedReceipt;
|
|
320
|
+
const result = await endpoint.request({ ...request, operation: 'retired', ...(receipt ? { receipt } : {}) }, new Uint8Array());
|
|
321
|
+
assert(result.settled === true && result.partitionIndex === index
|
|
322
|
+
&& sameRouteAttemptIdentity(result.identity, request.identity), 'Ordered retirement acknowledgment mismatch');
|
|
323
|
+
retirementReceipts.delete(id);
|
|
324
|
+
} catch (error) {
|
|
325
|
+
// This contributor released its own resident above. After its coordinator's channel is
|
|
326
|
+
// lost, no acknowledgment can ever be delivered on it, so it must not keep the route
|
|
327
|
+
// channel charged; the coordinator records that attempt's cleanup as unknown.
|
|
328
|
+
if (settled && closed && error?.code === 'CONNECTION_LOST') { retirementReceipts.delete(id); undeliveredRetirements++; }
|
|
329
|
+
else failures.push(error);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// A coordinator closing concurrently with a retirement response must not
|
|
334
|
+
// destroy the acknowledgment before the supplier receives it. The supplier
|
|
335
|
+
// owns channel closure once its exact receipts have all been acknowledged.
|
|
336
|
+
if (!serving && remoteRetiring && !closed && !failures.length) {
|
|
337
|
+
let timer;
|
|
338
|
+
try { await Promise.race([remoteClose, new Promise((_, reject) => {
|
|
339
|
+
timer = setTimeout(() => reject(Error('Ordered retirement acknowledgment remains unsettled')), limits.timeoutMs);
|
|
340
|
+
})]); } catch (error) { failures.push(error); } finally { clearTimeout(timer); }
|
|
341
|
+
}
|
|
342
|
+
if (failures.length) { notify(); throw new AggregateError(failures, 'Ordered peer cleanup remains unknown'); }
|
|
343
|
+
closed = true; endpoint.close(); delivered.clear(); verifiedGrants.clear(); notify();
|
|
344
|
+
})().catch(error => { closing = null; throw error; });
|
|
345
|
+
return closing;
|
|
346
|
+
};
|
|
347
|
+
channel.addEventListener('close', () => { closed = true; channelClosed(); descriptor = null; notify(); close().catch(() => {}); }, { once: true });
|
|
348
|
+
return Object.freeze({ id: remoteParticipantId, transportId: stage.transportId, residentId: stage.residentId, executionId: stage.executionId,
|
|
349
|
+
getState, subscribe(listener) { listeners.add(listener); listener(getState()); return () => listeners.delete(listener); }, close, closeAttempt,
|
|
350
|
+
async refresh({ signal } = {}) {
|
|
351
|
+
await ready;
|
|
352
|
+
const observed = await endpoint.request({ schema: SCHEMA, operation: 'describe' }, new Uint8Array(), { signal });
|
|
353
|
+
const value = observed.descriptor;
|
|
354
|
+
assert(!value || observed.capability === 'ordered-stage' && equal(observed.stage, stage)
|
|
355
|
+
&& value.schema === 'doppler.resident-partition/v2' && value.ready === true && value.index === index
|
|
356
|
+
&& value.stageCount === route.stages.length && value.modelId === route.modelId && value.modelIdentity === modelIdentity
|
|
357
|
+
&& value.planId === planId && equal(value.layerRange, plan.partitions[index].layerRange), 'Ordered remote descriptor mismatch');
|
|
358
|
+
descriptor = value; notify(); return getState();
|
|
359
|
+
},
|
|
360
|
+
async reserve(request) {
|
|
361
|
+
request = snapshotRequest(request);
|
|
362
|
+
await ready; assert(!serving, 'Only the coordinator reserves a remote stage');
|
|
363
|
+
assertCapacity(!closed && !retiring && active.size + confirmed.size < receiverLimits.maxAttempts);
|
|
364
|
+
const metadata = control({ ...request, step: 0 }, 'reserve'); protocol(metadata);
|
|
365
|
+
const previous = active.get(request.identity.attemptId);
|
|
366
|
+
assert(!previous || sameRouteAttemptIdentity(previous.identity, metadata.identity), 'Ordered reservation identity collision');
|
|
367
|
+
active.set(metadata.identity.attemptId, metadata);
|
|
368
|
+
const response = await endpoint.request(metadata, new Uint8Array(), { signal: request.signal });
|
|
369
|
+
assert(sameRouteAttemptIdentity(response.identity, metadata.identity) && response.partitionIndex === index
|
|
370
|
+
&& response.status === 'reserved', 'Ordered reservation acknowledgment mismatch');
|
|
371
|
+
delivered.set(metadata.identity.attemptId, new Set([await grantDigest(metadata.executionGrant)]));
|
|
372
|
+
return response;
|
|
373
|
+
},
|
|
374
|
+
async executeStage(request) {
|
|
375
|
+
request = snapshotRequest(request);
|
|
376
|
+
await ready; assert(!serving && !closed && !retiring, 'Ordered remote execution unavailable');
|
|
377
|
+
const previous = active.get(request.identity.attemptId);
|
|
378
|
+
assert(previous && sameRouteAttemptIdentity(previous.identity, request.identity), 'Ordered remote attempt not reserved');
|
|
379
|
+
const { tensorData, ...layout } = request.activation || {};
|
|
380
|
+
const frame = runtime.serializeActivationFrame({ ...layout, data: tensorData, metadata: frameMetadata(request) });
|
|
381
|
+
const { buffer, ...header } = frame;
|
|
382
|
+
const metadata = control({ ...request, frame: header }, 'step'); protocol(metadata);
|
|
383
|
+
const attemptId = metadata.identity.attemptId, final = index === route.stages.length - 1;
|
|
384
|
+
assert(inflight.size < receiverLimits.maxAttempts && !inflight.has(attemptId), 'Ordered remote step already in flight');
|
|
385
|
+
inflight.add(attemptId);
|
|
386
|
+
try {
|
|
387
|
+
// Grants this stage already holds for the attempt travel as digests; new ones travel once.
|
|
388
|
+
const known = delivered.get(attemptId) ?? new Set(), sent = [], wire = { ...metadata };
|
|
389
|
+
const own = verifiedGrants.get(attemptId) ?? new Map();
|
|
390
|
+
for (const field of GRANT_FIELDS) {
|
|
391
|
+
if (!metadata[field]) continue;
|
|
392
|
+
const digest = await grantDigest(metadata[field]);
|
|
393
|
+
if (own.size < GRANT_FIELDS.length || own.has(digest)) own.set(digest, metadata[field]);
|
|
394
|
+
if (known.has(digest)) wire[field] = { schema: GRANT_REFERENCE, digest };
|
|
395
|
+
else sent.push(digest);
|
|
396
|
+
}
|
|
397
|
+
if (active.has(attemptId)) verifiedGrants.set(attemptId, own);
|
|
398
|
+
const reply = await endpoint.request(wire, new Uint8Array(buffer), { signal: request.signal,
|
|
399
|
+
...(final ? {} : { maxResponseBytes: activationBytes(metadata) }) });
|
|
400
|
+
const response = final ? reply : reply.result;
|
|
401
|
+
assert(sameRouteAttemptIdentity(response.identity, metadata.identity) && response.partitionIndex === index
|
|
402
|
+
&& response.step === metadata.step && response.tokenPosition === metadata.tokenPosition, 'Ordered response binding mismatch');
|
|
403
|
+
for (const digest of sent) known.add(digest);
|
|
404
|
+
if (active.has(attemptId)) delivered.set(attemptId, known);
|
|
405
|
+
if (final) return response;
|
|
406
|
+
const { frame: output, outputDigest, ...rest } = response;
|
|
407
|
+
assert(validFrame(metadata, reply.bytes.byteLength, output)
|
|
408
|
+
&& await partitionFingerprint(output, reply.bytes) === outputDigest, 'Ordered binary output missing or altered');
|
|
409
|
+
const decoded = runtime.validateActivationFrameForPlan({ ...output, buffer: reply.bytes.slice().buffer }, plan);
|
|
410
|
+
const { tensorData: data, ...geometry } = decoded;
|
|
411
|
+
return { ...rest, outputDigest, activationTensor: { ...geometry, data } };
|
|
412
|
+
} finally { inflight.delete(attemptId); }
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { assertPartition as assert, canonicalPartitionJson, canonicalRouteAttemptBinding } from './partition-contract.js';
|
|
2
|
+
|
|
3
|
+
/** Requester-owned publication of ordinary ordered decoding. Doppler executes
|
|
4
|
+
* every stage and decides each token and stopping reason; these records only
|
|
5
|
+
* bind what the final stage returned to its route attempt and durable order.
|
|
6
|
+
* Ordinary ordered stages sign no commitments: records carry zero stage
|
|
7
|
+
* acknowledgments, and the digest port is the injected Doppler metadataDigest. */
|
|
8
|
+
export const ORDERED_PUBLICATION_SCHEMA = 'reploid.ordered-publication/v1';
|
|
9
|
+
export const ORDERED_PUBLICATION_ATTEMPT_SCHEMA = 'reploid.ordered-publication-attempt/v1';
|
|
10
|
+
export const ORDERED_PUBLICATION_CONTEXT_SCHEMA = 'reploid.ordered-publication-context/v1';
|
|
11
|
+
/** The durable writer's receipt for one accepted publication (chat/workspace-publication.js writes it). */
|
|
12
|
+
export const PUBLICATION_RECEIPT_SCHEMA = 'reploid.publication-receipt/v1';
|
|
13
|
+
const BOUNDS_SCHEMA = 'reploid.ordered-generation-bounds/v1';
|
|
14
|
+
const CURSOR_SCHEMA = 'reploid.ordered-cursor/v1';
|
|
15
|
+
const epoch = value => typeof value === 'string' && /^[a-f0-9]{32}$/.test(value);
|
|
16
|
+
const digest = value => typeof value === 'string' && /^sha256:[a-f0-9]{64}$/.test(value);
|
|
17
|
+
const count = value => Number.isSafeInteger(value) && value >= 0;
|
|
18
|
+
const positive = value => Number.isSafeInteger(value) && value > 0;
|
|
19
|
+
const exact = (value, keys) => !!value && typeof value === 'object' && !Array.isArray(value)
|
|
20
|
+
&& Object.keys(value).length === keys.length && keys.every(key => Object.hasOwn(value, key));
|
|
21
|
+
const attemptKeys = ['schema', 'attemptId', 'threadId', 'requesterId', 'placementGeneration', 'route',
|
|
22
|
+
'coordinatorEpoch', 'publisherEpoch', 'generationDigest'];
|
|
23
|
+
const recordKeys = ['schema', 'publicationDigest', 'attemptId', 'coordinatorEpoch', 'attemptDigest', 'sequence',
|
|
24
|
+
'previousPublicationDigest', 'tokenPosition', 'inputTokenCount', 'tokenId', 'delta', 'successor', 'acknowledgments'];
|
|
25
|
+
const cursorKeys = ['schema', 'revision', 'generatedTokenCount', 'nextTokenPosition', 'pendingTokenId',
|
|
26
|
+
'outputCharacters', 'terminal', 'stopReason'];
|
|
27
|
+
|
|
28
|
+
export function validateOrderedPublicationContext(value) {
|
|
29
|
+
assert(exact(value, ['schema', 'publisherEpoch', 'deadlineAt']) && value.schema === ORDERED_PUBLICATION_CONTEXT_SCHEMA
|
|
30
|
+
&& epoch(value.publisherEpoch) && positive(value.deadlineAt), 'Invalid ordered publication context');
|
|
31
|
+
return structuredClone(value);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function validateOrderedPublicationAttempt(value) {
|
|
35
|
+
assert(exact(value, attemptKeys) && value.schema === ORDERED_PUBLICATION_ATTEMPT_SCHEMA
|
|
36
|
+
&& epoch(value.coordinatorEpoch) && epoch(value.publisherEpoch) && digest(value.generationDigest),
|
|
37
|
+
'Invalid ordered publication attempt');
|
|
38
|
+
const binding = canonicalRouteAttemptBinding({ schema: 'reploid.partition-attempt/v2', route: value.route,
|
|
39
|
+
threadId: value.threadId, attemptId: value.attemptId, requesterId: value.requesterId, placementGeneration: value.placementGeneration });
|
|
40
|
+
assert(canonicalPartitionJson(binding.route) === canonicalPartitionJson(value.route), 'Ordered publication route is not canonical');
|
|
41
|
+
return structuredClone(value);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function orderedPublicationAttempt({ binding, coordinatorEpoch, publisherEpoch, generationDigest }) {
|
|
45
|
+
const identity = canonicalRouteAttemptBinding(binding);
|
|
46
|
+
return validateOrderedPublicationAttempt({ schema: ORDERED_PUBLICATION_ATTEMPT_SCHEMA, attemptId: identity.attemptId,
|
|
47
|
+
threadId: identity.threadId, requesterId: identity.requesterId, placementGeneration: identity.placementGeneration,
|
|
48
|
+
route: structuredClone(identity.route), coordinatorEpoch, publisherEpoch, generationDigest });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function validateOrderedGenerationBounds(value) {
|
|
52
|
+
assert(exact(value, ['schema', 'maxTokens', 'maxOutputCharacters']) && value.schema === BOUNDS_SCHEMA
|
|
53
|
+
&& positive(value.maxTokens) && positive(value.maxOutputCharacters), 'Invalid ordered generation bounds');
|
|
54
|
+
return structuredClone(value);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function orderedGenerationBounds({ maxTokens, maxOutputCharacters }) {
|
|
58
|
+
return validateOrderedGenerationBounds({ schema: BOUNDS_SCHEMA, maxTokens, maxOutputCharacters });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** One durable record per final-stage step, chained to the conversation head. */
|
|
62
|
+
export function orderedPublicationRecord({ attempt, bounds, vocabSize, base, previousPublicationDigest, metadataDigest, step }) {
|
|
63
|
+
const { sequence, tokenPosition, inputTokenCount, tokenId, delta, done, stopReason } = step;
|
|
64
|
+
const body = { schema: ORDERED_PUBLICATION_SCHEMA, attemptId: attempt.attemptId, coordinatorEpoch: attempt.coordinatorEpoch,
|
|
65
|
+
attemptDigest: metadataDigest(attempt.schema, attempt), sequence, previousPublicationDigest, tokenPosition, inputTokenCount,
|
|
66
|
+
tokenId, delta: { text: delta }, successor: { schema: CURSOR_SCHEMA, revision: sequence, generatedTokenCount: sequence + 1,
|
|
67
|
+
nextTokenPosition: tokenPosition + inputTokenCount, pendingTokenId: tokenId,
|
|
68
|
+
outputCharacters: (base?.outputCharacters ?? 0) + delta.length, terminal: done === true, stopReason: done === true ? stopReason : null },
|
|
69
|
+
acknowledgments: [] };
|
|
70
|
+
const record = { ...body, publicationDigest: metadataDigest(body.schema, body) };
|
|
71
|
+
return validateOrderedPublication(record, attempt, bounds, vocabSize, base, metadataDigest);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Validates against the admitted attempt and the prior record's successor cursor. */
|
|
75
|
+
export function validateOrderedPublication(input, attempt, bounds, vocabSize, base, metadataDigest) {
|
|
76
|
+
assert(exact(input, recordKeys) && input.schema === ORDERED_PUBLICATION_SCHEMA, 'Invalid ordered publication fields');
|
|
77
|
+
const value = structuredClone(input), { successor: next, delta } = value;
|
|
78
|
+
assert(value.attemptId === attempt.attemptId && value.coordinatorEpoch === attempt.coordinatorEpoch
|
|
79
|
+
&& value.attemptDigest === metadataDigest(attempt.schema, attempt), 'Ordered publication attempt binding mismatch');
|
|
80
|
+
assert(count(value.sequence) && value.sequence < bounds.maxTokens
|
|
81
|
+
&& (value.previousPublicationDigest === null || digest(value.previousPublicationDigest))
|
|
82
|
+
&& count(value.tokenPosition) && positive(value.inputTokenCount)
|
|
83
|
+
&& Number.isSafeInteger(value.tokenId) && value.tokenId >= 0 && value.tokenId < vocabSize
|
|
84
|
+
&& exact(delta, ['text']) && typeof delta.text === 'string'
|
|
85
|
+
&& Array.isArray(value.acknowledgments) && value.acknowledgments.length === 0, 'Invalid ordered publication step');
|
|
86
|
+
assert(exact(next, cursorKeys) && next.schema === CURSOR_SCHEMA && next.revision === value.sequence
|
|
87
|
+
&& next.generatedTokenCount === value.sequence + 1 && next.pendingTokenId === value.tokenId
|
|
88
|
+
&& next.nextTokenPosition === value.tokenPosition + value.inputTokenCount
|
|
89
|
+
&& next.outputCharacters === (base?.outputCharacters ?? 0) + delta.text.length
|
|
90
|
+
&& next.outputCharacters <= bounds.maxOutputCharacters && typeof next.terminal === 'boolean'
|
|
91
|
+
&& (next.terminal ? typeof next.stopReason === 'string' && next.stopReason.length > 0 && next.stopReason.length <= 64
|
|
92
|
+
: next.stopReason === null)
|
|
93
|
+
&& (next.terminal || value.sequence + 1 < bounds.maxTokens), 'Ordered publication cursor mismatch');
|
|
94
|
+
if (base == null) assert(value.sequence === 0 && value.tokenPosition === 0, 'Ordered publication bootstrap mismatch');
|
|
95
|
+
else assert(exact(base, cursorKeys) && base.schema === CURSOR_SCHEMA && !base.terminal && value.sequence === base.revision + 1
|
|
96
|
+
&& value.tokenPosition === base.nextTokenPosition && value.inputTokenCount === 1, 'Ordered publication does not extend its base cursor');
|
|
97
|
+
const { publicationDigest, ...body } = value;
|
|
98
|
+
assert(publicationDigest === metadataDigest(body.schema, body), 'Ordered publication digest mismatch');
|
|
99
|
+
return value;
|
|
100
|
+
}
|