reploid 0.0.0-stage → 0.1.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/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 +534 -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 +83 -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,291 @@
|
|
|
1
|
+
import canonicalPolicy from './partition-receiver-policy.json' with { type: 'json' };
|
|
2
|
+
import { canonicalPartitionBinding, samePartitionIdentity, canonicalRouteAttemptBinding, sameRouteAttemptIdentity, canonicalPartitionJson } from './partition-contract.js';
|
|
3
|
+
|
|
4
|
+
/** Receiver-side ordering/idempotency. Execution and verified identity remain host ports. */
|
|
5
|
+
export function createPartitionStepReceiver({ executeStep, authorize, fingerprint, settleAttempt, limits, canonical, ordered }) {
|
|
6
|
+
for (const port of [executeStep, authorize, fingerprint, settleAttempt]) {
|
|
7
|
+
if (typeof port !== 'function') throw new Error('Partition receiver requires execution, authorization, digest and settlement ports');
|
|
8
|
+
}
|
|
9
|
+
if (!Number.isSafeInteger(limits?.maxAttempts) || limits.maxAttempts <= 0
|
|
10
|
+
|| !Number.isSafeInteger(limits?.maxSteps) || limits.maxSteps <= 0) {
|
|
11
|
+
throw new Error('Explicit receiver attempt and step limits required');
|
|
12
|
+
}
|
|
13
|
+
if (ordered && canonical) throw new Error('Ordered canonical receiver is unsupported');
|
|
14
|
+
const orderedStage = ordered ? structuredClone(ordered.stage) : null;
|
|
15
|
+
if (ordered && (!Number.isSafeInteger(orderedStage?.index) || orderedStage.index < 0
|
|
16
|
+
|| !['participantId', 'transportId', 'residentId', 'executionId'].every(key => typeof orderedStage[key] === 'string' && orderedStage[key]))) {
|
|
17
|
+
throw new Error('Explicit ordered receiver stage required');
|
|
18
|
+
}
|
|
19
|
+
const snapshotIdentity = value => {
|
|
20
|
+
if (!orderedStage) return canonicalPartitionBinding(value);
|
|
21
|
+
const binding = canonicalRouteAttemptBinding(value);
|
|
22
|
+
if (canonicalPartitionJson(binding.route.stages[orderedStage.index]) !== canonicalPartitionJson(orderedStage)) {
|
|
23
|
+
throw new Error('Ordered receiver stage differs from route');
|
|
24
|
+
}
|
|
25
|
+
return binding;
|
|
26
|
+
};
|
|
27
|
+
const sameIdentity = orderedStage ? sameRouteAttemptIdentity : samePartitionIdentity;
|
|
28
|
+
const { maxAttempts, maxSteps } = limits;
|
|
29
|
+
const attempts = new Map();
|
|
30
|
+
const operations = new Set();
|
|
31
|
+
let closed = false;
|
|
32
|
+
const canonicalAttempts = new Map();
|
|
33
|
+
const canonicalStage = canonical ? structuredClone(canonical.stage) : null;
|
|
34
|
+
const runtime = canonical?.runtime;
|
|
35
|
+
if (canonical && (typeof canonical.execute !== 'function' || typeof canonical.verifyPublication !== 'function' || typeof canonical.now !== 'function'
|
|
36
|
+
|| !['metadataDigest', 'validateResidentAttemptIdentity', 'residentAttemptDigest'].every(name => typeof runtime?.[name] === 'function')
|
|
37
|
+
|| canonicalStage?.partitionIndex !== 1)) throw new Error('Explicit canonical output-stage receiver ports required');
|
|
38
|
+
const canonicalError = (code, message) => Object.assign(new Error(message), { code });
|
|
39
|
+
const expired = () => canonicalError('RESULT_EXPIRED', 'Canonical result expired; never reexecute');
|
|
40
|
+
const controlBytes = value => {
|
|
41
|
+
runtime.metadataDigest('reploid.partition-control/v1', value);
|
|
42
|
+
const size = new TextEncoder().encode(JSON.stringify(value)).byteLength;
|
|
43
|
+
if (size > canonicalPolicy.maxControlBytes) throw new Error('Canonical control message budget exceeded');
|
|
44
|
+
return size;
|
|
45
|
+
};
|
|
46
|
+
const prune = state => {
|
|
47
|
+
const completed = [...state.completed.keys()];
|
|
48
|
+
while (completed.length) {
|
|
49
|
+
const sequence = completed[0];
|
|
50
|
+
if (completed.length <= canonicalPolicy.maxCompletedSequences
|
|
51
|
+
&& canonical.now() - state.completed.get(sequence) < canonicalPolicy.maxRetentionMs) break;
|
|
52
|
+
completed.shift(); state.completed.delete(sequence);
|
|
53
|
+
for (const [key, record] of state.records) if (record.sequence === sequence && !record.pending) {
|
|
54
|
+
state.bytes -= record.bytes; state.records.delete(key);
|
|
55
|
+
}
|
|
56
|
+
state.retiredThrough = Math.max(state.retiredThrough, sequence);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const registerCanonical = (identity, attempt, digest) => {
|
|
60
|
+
if (attempts.has(identity.attemptId) || canonicalAttempts.size + attempts.size >= maxAttempts) {
|
|
61
|
+
throw new Error('Partition receiver attempt budget exhausted or identity collision');
|
|
62
|
+
}
|
|
63
|
+
const state = { identity, attempt, digest, records: new Map(), completed: new Map(), nextSequence: 0,
|
|
64
|
+
nextPosition: 0, admitted: false, terminal: false, awaitingPublication: null, retired: false, retiredThrough: -1,
|
|
65
|
+
bytes: 0, controller: new AbortController(), pending: null, settlement: null, settled: false };
|
|
66
|
+
canonicalAttempts.set(identity.attemptId, state); return state;
|
|
67
|
+
};
|
|
68
|
+
async function receiveCanonical(input, { signal } = {}) {
|
|
69
|
+
if (!canonical || closed) throw new Error('Canonical receiver unavailable or closed');
|
|
70
|
+
signal?.throwIfAborted();
|
|
71
|
+
const { payload, ...metadata } = input;
|
|
72
|
+
controlBytes(metadata);
|
|
73
|
+
const request = structuredClone(input);
|
|
74
|
+
request.identity = canonicalPartitionBinding(request.identity);
|
|
75
|
+
const attempt = runtime.validateResidentAttemptIdentity(request.canonicalAttempt);
|
|
76
|
+
if (attempt.routeKind !== 'two-stage-layer' || attempt.attemptId !== request.identity.attemptId
|
|
77
|
+
|| attempt.stages[0].participantId !== request.identity.participantA || attempt.stages[1].participantId !== request.identity.participantB
|
|
78
|
+
|| runtime.metadataDigest('reploid.partition-stage/v1', attempt.stages[1]) !== runtime.metadataDigest('reploid.partition-stage/v1', canonicalStage)
|
|
79
|
+
|| request.generationId !== attempt.generationId || !['admit', 'step', 'published'].includes(request.phase)
|
|
80
|
+
|| !Number.isSafeInteger(request.sequence) || request.sequence < 0 || request.sequence >= maxSteps
|
|
81
|
+
|| request.step !== request.sequence || !Number.isSafeInteger(request.tokenPosition) || request.tokenPosition < 0
|
|
82
|
+
|| !Number.isSafeInteger(request.inputTokenCount) || request.inputTokenCount <= 0
|
|
83
|
+
|| request.phase === 'admit' && (request.sequence !== 0 || request.tokenPosition !== 0)) {
|
|
84
|
+
throw new Error('Invalid canonical receiver binding');
|
|
85
|
+
}
|
|
86
|
+
const attemptDigest = runtime.residentAttemptDigest(attempt);
|
|
87
|
+
const operation = (async () => {
|
|
88
|
+
await permit(request); signal?.throwIfAborted();
|
|
89
|
+
const digest = await fingerprint(structuredClone(request));
|
|
90
|
+
if (!/^sha256:[a-f0-9]{64}$/.test(digest)) throw new Error('Partition input fingerprint required');
|
|
91
|
+
signal?.throwIfAborted();
|
|
92
|
+
if (closed) throw new Error('Partition receiver closed');
|
|
93
|
+
let state = canonicalAttempts.get(attempt.attemptId);
|
|
94
|
+
if (!state) {
|
|
95
|
+
if (request.phase !== 'admit') throw new Error('Canonical attempt must start with admission');
|
|
96
|
+
state = registerCanonical(request.identity, attempt, attemptDigest);
|
|
97
|
+
}
|
|
98
|
+
if (state.digest !== attemptDigest || !samePartitionIdentity(state.identity, request.identity)) throw new Error('Canonical attempt identity collision');
|
|
99
|
+
if (state.retired) throw new Error('Canonical attempt retired');
|
|
100
|
+
prune(state);
|
|
101
|
+
if (request.sequence <= state.retiredThrough) throw expired();
|
|
102
|
+
const key = `${request.sequence}:${request.phase}`;
|
|
103
|
+
let record = state.records.get(key);
|
|
104
|
+
if (record) {
|
|
105
|
+
if (record.digest !== digest) throw new Error('Canonical phase payload collision');
|
|
106
|
+
} else {
|
|
107
|
+
const publication = request.phase === 'published';
|
|
108
|
+
if (!publication && (state.terminal || request.sequence < state.nextSequence)) throw expired();
|
|
109
|
+
if (state.pending || (publication ? state.awaitingPublication !== request.sequence
|
|
110
|
+
: state.awaitingPublication !== null || request.sequence !== state.nextSequence || request.tokenPosition !== state.nextPosition
|
|
111
|
+
|| request.phase === 'admit' && state.admitted || request.phase === 'step' && !state.admitted
|
|
112
|
+
|| request.sequence > 0 && request.inputTokenCount !== 1)) throw new Error('Out-of-order canonical phase');
|
|
113
|
+
record = { sequence: request.sequence, digest, pending: true, bytes: 0, result: null };
|
|
114
|
+
state.records.set(key, record);
|
|
115
|
+
const combined = signal ? AbortSignal.any([signal, state.controller.signal]) : state.controller.signal;
|
|
116
|
+
record.result = (async () => {
|
|
117
|
+
try {
|
|
118
|
+
await permit(request); combined.throwIfAborted();
|
|
119
|
+
let result;
|
|
120
|
+
if (publication) {
|
|
121
|
+
const retained = state.records.get(`${request.sequence}:${state.terminal && state.nextSequence === 0 ? 'admit' : 'step'}`);
|
|
122
|
+
const original = await retained.result;
|
|
123
|
+
if (await canonical.verifyPublication(structuredClone(request), structuredClone(original)) !== true) {
|
|
124
|
+
throw new Error('Canonical publication acknowledgment rejected');
|
|
125
|
+
}
|
|
126
|
+
result = structuredClone(request.receipt);
|
|
127
|
+
} else result = structuredClone(await canonical.execute(structuredClone(request), { signal: combined }));
|
|
128
|
+
combined.throwIfAborted(); record.bytes = controlBytes(result);
|
|
129
|
+
if (state.bytes + record.bytes > canonicalPolicy.maxRetainedBytes) throw new Error('Canonical retained control budget exceeded');
|
|
130
|
+
state.bytes += record.bytes;
|
|
131
|
+
if (publication) {
|
|
132
|
+
state.awaitingPublication = null; state.completed.set(request.sequence, canonical.now());
|
|
133
|
+
} else if (request.phase === 'admit') {
|
|
134
|
+
state.admitted = true; state.terminal = !Object.hasOwn(result, 'kind');
|
|
135
|
+
if (state.terminal) state.awaitingPublication = request.sequence;
|
|
136
|
+
} else {
|
|
137
|
+
state.nextSequence++; state.nextPosition += request.inputTokenCount;
|
|
138
|
+
state.terminal = result.transition?.successor?.terminal === true;
|
|
139
|
+
state.awaitingPublication = request.sequence;
|
|
140
|
+
}
|
|
141
|
+
return result;
|
|
142
|
+
} catch (error) { state.retired = true; throw error; }
|
|
143
|
+
finally { record.pending = false; state.pending = null; prune(state); }
|
|
144
|
+
})();
|
|
145
|
+
state.pending = record.result;
|
|
146
|
+
}
|
|
147
|
+
const result = await record.result;
|
|
148
|
+
signal?.throwIfAborted(); await permit(request);
|
|
149
|
+
if (state.retired) throw new Error('Canonical attempt retired');
|
|
150
|
+
prune(state);
|
|
151
|
+
if (!state.records.has(key)) throw expired();
|
|
152
|
+
return structuredClone(result);
|
|
153
|
+
})();
|
|
154
|
+
operations.add(operation);
|
|
155
|
+
try { return await operation; } finally { operations.delete(operation); }
|
|
156
|
+
}
|
|
157
|
+
function closeCanonical(state) {
|
|
158
|
+
if (state.settlement) return state.settlement;
|
|
159
|
+
if (state.settled) return Promise.resolve();
|
|
160
|
+
state.retired = true; state.controller.abort(new Error('Canonical attempt closed'));
|
|
161
|
+
const operation = (async () => {
|
|
162
|
+
await state.pending?.catch(() => {});
|
|
163
|
+
await settleAttempt(structuredClone(state.identity));
|
|
164
|
+
state.records.clear(); state.completed.clear(); state.bytes = 0; state.settled = true;
|
|
165
|
+
})();
|
|
166
|
+
state.settlement = operation;
|
|
167
|
+
operation.finally(() => { if (state.settlement === operation) state.settlement = null; }).catch(() => {});
|
|
168
|
+
return operation;
|
|
169
|
+
}
|
|
170
|
+
const registerAttempt = identity => {
|
|
171
|
+
if (canonicalAttempts.has(identity.attemptId) || attempts.size + canonicalAttempts.size >= maxAttempts) throw new Error('Partition receiver attempt budget exhausted');
|
|
172
|
+
const state = { identity: snapshotIdentity(identity), nextStep: 0, nextPosition: 0, maxTokens: null,
|
|
173
|
+
last: null, retired: false, controller: new AbortController(), settlement: null };
|
|
174
|
+
attempts.set(identity.attemptId, state);
|
|
175
|
+
return state;
|
|
176
|
+
};
|
|
177
|
+
const permit = async request => {
|
|
178
|
+
if (closed || await authorize(structuredClone(request)) !== true) throw new Error('Partition receiver authorization declined');
|
|
179
|
+
if (closed) throw new Error('Partition receiver closed');
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
async function receive(input, { signal } = {}) {
|
|
183
|
+
signal?.throwIfAborted();
|
|
184
|
+
if (closed) throw new Error('Partition receiver closed');
|
|
185
|
+
// Host ingress validates payload shape/byte budgets before this copy or hashing.
|
|
186
|
+
const request = structuredClone(input);
|
|
187
|
+
request.identity = snapshotIdentity(request.identity);
|
|
188
|
+
if (orderedStage && request.partitionIndex !== orderedStage.index) throw new Error('Ordered receiver stage mismatch');
|
|
189
|
+
if (!Number.isSafeInteger(request.step) || request.step < 0 || request.step >= maxSteps
|
|
190
|
+
|| !Number.isSafeInteger(request.maxTokens) || request.maxTokens <= 0 || request.step >= request.maxTokens
|
|
191
|
+
|| !Number.isSafeInteger(request.tokenPosition) || request.tokenPosition < 0
|
|
192
|
+
|| !Number.isSafeInteger(request.inputTokenCount) || request.inputTokenCount <= 0) {
|
|
193
|
+
throw new Error('Invalid partition step binding');
|
|
194
|
+
}
|
|
195
|
+
const operation = (async () => {
|
|
196
|
+
await permit(request);
|
|
197
|
+
signal?.throwIfAborted();
|
|
198
|
+
const digest = await fingerprint(structuredClone(request));
|
|
199
|
+
if (!/^sha256:[a-f0-9]{64}$/.test(digest)) throw new Error('Partition input fingerprint required');
|
|
200
|
+
signal?.throwIfAborted();
|
|
201
|
+
if (closed) throw new Error('Partition receiver closed');
|
|
202
|
+
const key = request.identity.attemptId;
|
|
203
|
+
let state = attempts.get(key);
|
|
204
|
+
if (!state) {
|
|
205
|
+
if (request.step !== 0 || request.tokenPosition !== 0) throw new Error('Partition attempt must start with prefill');
|
|
206
|
+
state = registerAttempt(request.identity);
|
|
207
|
+
state.maxTokens = request.maxTokens;
|
|
208
|
+
}
|
|
209
|
+
if (!sameIdentity(state.identity, request.identity)) throw new Error('Partition attempt identity collision');
|
|
210
|
+
if (state.retired) throw new Error('Partition attempt retired; start a new attempt');
|
|
211
|
+
if (state.maxTokens !== request.maxTokens) throw new Error('Partition request token limit changed');
|
|
212
|
+
if (state.last?.step === request.step) {
|
|
213
|
+
if (state.last.digest !== digest) throw new Error('Partition step payload collision');
|
|
214
|
+
} else {
|
|
215
|
+
if (state.last?.pending || request.step !== state.nextStep || request.tokenPosition !== state.nextPosition) {
|
|
216
|
+
throw new Error('Out-of-order partition step');
|
|
217
|
+
}
|
|
218
|
+
if (request.step > 0 && request.inputTokenCount !== 1) throw new Error('Decode consumes one token');
|
|
219
|
+
const current = { step: request.step, digest, pending: true, result: null };
|
|
220
|
+
state.last = current;
|
|
221
|
+
const combined = signal ? AbortSignal.any([signal, state.controller.signal]) : state.controller.signal;
|
|
222
|
+
current.result = (async () => {
|
|
223
|
+
try {
|
|
224
|
+
await permit(request);
|
|
225
|
+
combined.throwIfAborted();
|
|
226
|
+
const result = await executeStep(structuredClone(request), { signal: combined });
|
|
227
|
+
combined.throwIfAborted();
|
|
228
|
+
state.nextStep++;
|
|
229
|
+
state.nextPosition += request.inputTokenCount;
|
|
230
|
+
return structuredClone(result);
|
|
231
|
+
} catch (error) {
|
|
232
|
+
// A failed compute may already have mutated KV state. Never run it again.
|
|
233
|
+
state.retired = true;
|
|
234
|
+
throw error;
|
|
235
|
+
} finally { current.pending = false; }
|
|
236
|
+
})();
|
|
237
|
+
}
|
|
238
|
+
const result = await state.last.result;
|
|
239
|
+
signal?.throwIfAborted();
|
|
240
|
+
// A replay still requires current disclosure permission.
|
|
241
|
+
await permit(request);
|
|
242
|
+
if (state.retired) throw new Error('Partition attempt retired');
|
|
243
|
+
return structuredClone(result);
|
|
244
|
+
})();
|
|
245
|
+
operations.add(operation);
|
|
246
|
+
try { return await operation; } finally { operations.delete(operation); }
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function closeAttempt(identity) {
|
|
250
|
+
try { identity = snapshotIdentity(identity); }
|
|
251
|
+
catch (error) { return Promise.reject(error); }
|
|
252
|
+
const canonicalState = canonicalAttempts.get(identity.attemptId);
|
|
253
|
+
if (canonicalState) {
|
|
254
|
+
if (!samePartitionIdentity(canonicalState.identity, identity)) return Promise.reject(new Error('Partition settlement identity collision'));
|
|
255
|
+
return closeCanonical(canonicalState);
|
|
256
|
+
}
|
|
257
|
+
let state = attempts.get(identity.attemptId);
|
|
258
|
+
if (!state) {
|
|
259
|
+
if (closed) return Promise.resolve();
|
|
260
|
+
try { state = registerAttempt(identity); }
|
|
261
|
+
catch (error) { return Promise.reject(error); }
|
|
262
|
+
// Cancellation may overtake the first step's authorization or hashing.
|
|
263
|
+
// Keep a bounded tombstone so that delayed ingress cannot acquire state.
|
|
264
|
+
state.retired = true;
|
|
265
|
+
state.settlement = Promise.resolve();
|
|
266
|
+
return state.settlement;
|
|
267
|
+
}
|
|
268
|
+
if (!sameIdentity(state.identity, identity)) {
|
|
269
|
+
return Promise.reject(new Error('Partition settlement identity collision'));
|
|
270
|
+
}
|
|
271
|
+
if (state.settlement) return state.settlement;
|
|
272
|
+
state.retired = true;
|
|
273
|
+
state.controller.abort(new Error('Partition attempt closed'));
|
|
274
|
+
state.settlement = (async () => {
|
|
275
|
+
await state.last?.result?.catch(() => {});
|
|
276
|
+
try { await settleAttempt(structuredClone(state.identity)); }
|
|
277
|
+
finally { state.last = null; }
|
|
278
|
+
})().catch(error => { state.settlement = null; throw error; });
|
|
279
|
+
return state.settlement;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return Object.freeze({ receive, receiveCanonical, closeAttempt,
|
|
283
|
+
async close() {
|
|
284
|
+
closed = true;
|
|
285
|
+
const results = await Promise.allSettled([...attempts.values(), ...canonicalAttempts.values()].map(state => closeAttempt(state.identity)));
|
|
286
|
+
await Promise.allSettled([...operations]);
|
|
287
|
+
const failures = results.filter(result => result.status === 'rejected').map(result => result.reason);
|
|
288
|
+
if (failures.length) throw new AggregateError(failures, 'Partition receiver settlement failed');
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { canonicalRouteAttemptBinding, sameRouteAttemptIdentity } from './partition-contract.js';
|
|
2
|
+
|
|
3
|
+
// Doppler resident stage metrics (PartitionTiming plus execution, readback and
|
|
4
|
+
// sampling). Contributors report them; only finite non-negative numbers count.
|
|
5
|
+
const STAGE_RUNTIME_KEYS = Object.freeze(['executionMs', 'inputUploadMs', 'encodeMs', 'submitWaitMs',
|
|
6
|
+
'activationReadbackMs', 'logitsMs', 'gpuKernelsMs', 'logitsReadbackMs', 'samplingMs']);
|
|
7
|
+
const measuredMs = value => typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : null;
|
|
8
|
+
|
|
9
|
+
/** Step 0 carries the whole prompt (prefill and the first sampled token); later
|
|
10
|
+
* steps decode one token each. Keep them apart so prompt length, prefill and
|
|
11
|
+
* decode are never averaged together. */
|
|
12
|
+
function summarizeOrderedPhases(steps) {
|
|
13
|
+
const aggregate = () => ({ count: 0, total: 0, min: null, max: null });
|
|
14
|
+
const add = (row, value) => {
|
|
15
|
+
if (value === null) return;
|
|
16
|
+
row.count++; row.total += value;
|
|
17
|
+
row.min = row.min === null ? value : Math.min(row.min, value); row.max = row.max === null ? value : Math.max(row.max, value);
|
|
18
|
+
};
|
|
19
|
+
const first = steps[0];
|
|
20
|
+
const prompt = first ? { inputTokens: Number.isSafeInteger(first.inputTokenCount) ? first.inputTokenCount : null,
|
|
21
|
+
stages: (first.stages || []).map(stage => ({ partitionIndex: stage.partitionIndex, elapsedMs: measuredMs(stage.elapsedMs),
|
|
22
|
+
runtime: Object.fromEntries(STAGE_RUNTIME_KEYS.map(key => [key, measuredMs(stage.metrics?.[key])])) })) } : null;
|
|
23
|
+
const decodeStages = new Map();
|
|
24
|
+
for (const step of steps.slice(1)) for (const stage of step.stages || []) {
|
|
25
|
+
const row = decodeStages.get(stage.partitionIndex) || { partitionIndex: stage.partitionIndex, elapsedMs: aggregate(),
|
|
26
|
+
runtime: Object.fromEntries(STAGE_RUNTIME_KEYS.map(key => [key, aggregate()])) };
|
|
27
|
+
add(row.elapsedMs, measuredMs(stage.elapsedMs));
|
|
28
|
+
for (const key of STAGE_RUNTIME_KEYS) add(row.runtime[key], measuredMs(stage.metrics?.[key]));
|
|
29
|
+
decodeStages.set(stage.partitionIndex, row);
|
|
30
|
+
}
|
|
31
|
+
return { prompt, decode: { steps: Math.max(steps.length - 1, 0), stages: [...decodeStages.values()] } };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Fixed-size timing projection for a completed requester response. Detailed
|
|
35
|
+
* per-step observations belong to the executing runner, not its control frame. */
|
|
36
|
+
export function summarizePartitionExecution(execution) {
|
|
37
|
+
if (execution.schema === 'reploid.mesh.partition-execution/v3') {
|
|
38
|
+
const stages = new Map();
|
|
39
|
+
for (const step of execution.steps || []) for (const stage of step.stages || []) {
|
|
40
|
+
const row = stages.get(stage.partitionIndex) || { partitionIndex: stage.partitionIndex, steps: 0,
|
|
41
|
+
stepMs: { count: 0, total: 0 } };
|
|
42
|
+
if (Number.isFinite(stage.elapsedMs) && stage.elapsedMs >= 0) {
|
|
43
|
+
row.stepMs.count++; row.stepMs.total += stage.elapsedMs;
|
|
44
|
+
}
|
|
45
|
+
row.steps++; stages.set(stage.partitionIndex, row);
|
|
46
|
+
}
|
|
47
|
+
return structuredClone({ schema: 'reploid.mesh.partition-summary/v2', identity: execution.identity,
|
|
48
|
+
activationBytes: execution.activationBytes, stopReason: execution.stopReason, settlement: execution.settlement,
|
|
49
|
+
stepSummary: { count: execution.steps?.length || 0, stages: [...stages.values()],
|
|
50
|
+
phases: summarizeOrderedPhases(execution.steps || []), detail: 'aggregate; no per-step trace transferred' },
|
|
51
|
+
// A ranking coordinator's unsigned record of the decision that chose this attempt's route.
|
|
52
|
+
...(execution.routeSelection ? { routeSelection: execution.routeSelection } : {}),
|
|
53
|
+
// The coordinator's unsigned admission wait, kept apart from prefill and decode timing.
|
|
54
|
+
...(Number.isFinite(execution.admission?.queuedMs) ? { admission: { queuedMs: execution.admission.queuedMs } } : {}) });
|
|
55
|
+
}
|
|
56
|
+
if (execution.schema === 'reploid.mesh.canonical-partition-execution/v1') {
|
|
57
|
+
// Signed records are already retained by the requester transaction owner.
|
|
58
|
+
// Do not transfer the full history again in a bounded final control frame.
|
|
59
|
+
const { publications: _publications, ...summary } = execution;
|
|
60
|
+
execution = summary;
|
|
61
|
+
}
|
|
62
|
+
if (!Array.isArray(execution.steps)) return structuredClone(execution);
|
|
63
|
+
const { steps, transport, ...binding } = execution;
|
|
64
|
+
const metrics = {};
|
|
65
|
+
const add = (name, value) => {
|
|
66
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) return;
|
|
67
|
+
const row = metrics[name] ||= { count: 0, total: 0, min: value, max: value };
|
|
68
|
+
row.count++; row.total += value; row.min = Math.min(row.min, value); row.max = Math.max(row.max, value);
|
|
69
|
+
};
|
|
70
|
+
for (const step of steps) {
|
|
71
|
+
for (const key of ['leaseWaitMs', 'outputDeliveryMs', 'localStepMs', 'serializationMs',
|
|
72
|
+
'transferMs', 'remoteStepMs', 'elapsedMs']) add(key, step[key]);
|
|
73
|
+
for (const owner of ['computationA', 'computationB']) {
|
|
74
|
+
for (const key of ['inputUploadMs', 'encodeMs', 'submitWaitMs', 'activationReadbackMs', 'logitsMs',
|
|
75
|
+
'gpuKernelsMs', 'executionMs', 'logitsReadbackMs', 'samplingMs']) {
|
|
76
|
+
add(`${owner}.${key}`, step[owner]?.[key]);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const key of ['authorizationMs', 'readyWaitMs', 'payloadUploadMs', 'responseWaitMs', 'acceptanceMs', 'totalMs']) {
|
|
80
|
+
add(`transportTiming.${key}`, step.transportTiming?.[key]);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const { lastFailure: _localFailure, ...delivery } = transport || {};
|
|
84
|
+
const memoryAtLastStep = {};
|
|
85
|
+
const number = value => typeof value === 'number' && Number.isFinite(value) ? value : null;
|
|
86
|
+
for (const owner of ['computationA', 'computationB']) {
|
|
87
|
+
const memory = steps.at(-1)?.[owner]?.memory;
|
|
88
|
+
if (memory) memoryAtLastStep[owner] = {
|
|
89
|
+
maxBytes: number(memory.maxBytes), liveBytes: number(memory.liveBytes), peakBytes: number(memory.peakBytes),
|
|
90
|
+
categories: Object.fromEntries(['weights', 'attention', 'recurrent', 'other'].map(key => [key, number(memory.categories?.[key])]))
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
return { ...structuredClone(binding), schema: 'reploid.mesh.partition-summary/v1',
|
|
94
|
+
stepSummary: { count: steps.length, metrics, detail: 'aggregate; no per-step trace transferred' },
|
|
95
|
+
memoryAtLastStep, transport: delivery };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Bounded completed-token observations measured on the coordinator clock.
|
|
99
|
+
* These describe execution only; they are never text or publication records. */
|
|
100
|
+
export function partitionActivity(value, identity, previous = null, coalesced = false) {
|
|
101
|
+
const fail = () => { throw new Error('Invalid or out-of-order partition activity'); };
|
|
102
|
+
const expected = canonicalRouteAttemptBinding(identity);
|
|
103
|
+
if (!value || value.schema !== 'reploid.partition-activity/v1'
|
|
104
|
+
|| !sameRouteAttemptIdentity(value.identity, expected)
|
|
105
|
+
|| (coalesced ? value.sequence < (previous ? previous.sequence + 1 : 0)
|
|
106
|
+
: value.sequence !== (previous ? previous.sequence + 1 : 0))) fail();
|
|
107
|
+
const summary = value.stepSummary;
|
|
108
|
+
if (!Number.isSafeInteger(value.sequence) || value.sequence < 0
|
|
109
|
+
|| !Number.isSafeInteger(summary?.count) || summary.count !== value.sequence + 1 || !Array.isArray(summary.stages)
|
|
110
|
+
|| summary.stages.length !== expected.route.stages.length) fail();
|
|
111
|
+
let measuredTotal = 0;
|
|
112
|
+
const stages = summary.stages.map((row, index) => {
|
|
113
|
+
if (row.partitionIndex !== index || row.steps !== summary.count
|
|
114
|
+
|| row.stepMs?.count !== summary.count || !Number.isFinite(row.stepMs.total) || row.stepMs.total < 0
|
|
115
|
+
|| previous && row.stepMs.total < previous.stepSummary.stages[index].stepMs.total) fail();
|
|
116
|
+
measuredTotal += row.stepMs.total;
|
|
117
|
+
if (!Number.isFinite(measuredTotal)) fail();
|
|
118
|
+
return { partitionIndex: index, steps: row.steps, stepMs: { count: row.stepMs.count, total: row.stepMs.total } };
|
|
119
|
+
});
|
|
120
|
+
return { schema: 'reploid.partition-activity/v1', identity: expected, sequence: value.sequence,
|
|
121
|
+
stepSummary: { count: summary.count, stages } };
|
|
122
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Retain preparation resources until each close succeeds; failed closes remain retryable. */
|
|
2
|
+
export function createPartitionPreparationOwner({ source, registerCleanup, onSettled = () => {}, errorMessage = 'Partition preparation cleanup failed' }) {
|
|
3
|
+
let resident = null, release = null, commitAuthority = null, cleaning = null;
|
|
4
|
+
let sourceSettled = false, releaseSettled = false, residentSettled = false;
|
|
5
|
+
const sessions = new Set();
|
|
6
|
+
const closeSources = async failures => {
|
|
7
|
+
if (!sourceSettled) {
|
|
8
|
+
try { await source.storage.close(); sourceSettled = true; } catch (error) { failures.push(error); }
|
|
9
|
+
}
|
|
10
|
+
if (release && !releaseSettled) {
|
|
11
|
+
try { await release.close(); releaseSettled = true; } catch (error) { failures.push(error); }
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const owner = {
|
|
15
|
+
set resident(value) { resident = value; },
|
|
16
|
+
set release(value) { release = value; },
|
|
17
|
+
set commitAuthority(value) { commitAuthority = value; },
|
|
18
|
+
closeSources,
|
|
19
|
+
trackSession(session) { sessions.add(session); return () => sessions.delete(session); },
|
|
20
|
+
close() {
|
|
21
|
+
return cleaning ||= (async () => {
|
|
22
|
+
const failures = [];
|
|
23
|
+
try { await commitAuthority?.close(); } catch (error) { failures.push(error); }
|
|
24
|
+
if (!residentSettled) {
|
|
25
|
+
try { await resident?.close(); residentSettled = true; } catch (error) { failures.push(error); }
|
|
26
|
+
}
|
|
27
|
+
for (const session of sessions) {
|
|
28
|
+
try { await session.close(); sessions.delete(session); } catch (error) { failures.push(error); }
|
|
29
|
+
}
|
|
30
|
+
await closeSources(failures);
|
|
31
|
+
if (failures.length === 1) throw failures[0];
|
|
32
|
+
if (failures.length) throw new AggregateError(failures, errorMessage);
|
|
33
|
+
await onSettled();
|
|
34
|
+
releaseCleanup?.();
|
|
35
|
+
})().catch(error => { cleaning = null; throw error; });
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const releaseCleanup = registerCleanup?.(owner);
|
|
39
|
+
return owner;
|
|
40
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"codes": {
|
|
3
|
+
"DOPPLER_RESIDENT_OUTPUT_LIMIT": "OUTPUT_LIMIT_EXCEEDED",
|
|
4
|
+
"DOPPLER_GENERATION_OUTPUT_INVALID": "GENERATION_OUTPUT_INVALID",
|
|
5
|
+
"DOPPLER_GPU_OOM": "RESOURCE_EXHAUSTED"
|
|
6
|
+
},
|
|
7
|
+
"legacyMessages": {
|
|
8
|
+
"Resident output exceeds its character allocation.": "OUTPUT_LIMIT_EXCEEDED"
|
|
9
|
+
}
|
|
10
|
+
}
|