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,113 @@
|
|
|
1
|
+
/** One prepared model, reusable across requests until explicitly retired. */
|
|
2
|
+
import { createPreparationProgressObserver } from '../../../shared/vendor/reploid/mesh/preparation-progress.js';
|
|
3
|
+
import { openWorkProvider } from './work-provider.js';
|
|
4
|
+
import { retainModelStorage } from '../infrastructure/model-storage-lock.js';
|
|
5
|
+
import { withWorkDevice } from './work-device.js';
|
|
6
|
+
|
|
7
|
+
export function createWorkResidentProvider({ service, model, generation, maxOutcomeCharacters,
|
|
8
|
+
onChange = () => {}, onComplete = () => {}, scope = 'work-resident:' + crypto.randomUUID(), resolveAdapter, resolveSource, source, loadOptions }) {
|
|
9
|
+
model = structuredClone(model);
|
|
10
|
+
generation = structuredClone(generation);
|
|
11
|
+
const lifetime = new AbortController(), operations = new Set();
|
|
12
|
+
let adapter = null, identity = null, preparing = null, closing = null, cleanup = null, releaseStorage = null;
|
|
13
|
+
let closed = false, phase = 'idle', error = null, progress = null, completed = 0;
|
|
14
|
+
const production = { outputTokens: 0, missingTokenCounts: 0 };
|
|
15
|
+
let adapterIdentities = [];
|
|
16
|
+
const getState = () => ({ phase, error, progress: structuredClone(progress), completed, production: { ...production },
|
|
17
|
+
modelId: model.id, modelIdentity: identity?.modelIdentity || null,
|
|
18
|
+
adapterIdentities: [...adapterIdentities],
|
|
19
|
+
hardware: adapter?.getHardware() || null,
|
|
20
|
+
contextCache: adapter?.getContextCacheStats?.() || null,
|
|
21
|
+
ready: !closed && !!adapter && adapter.isReady() && ['ready', 'executing'].includes(phase) });
|
|
22
|
+
const notify = () => {
|
|
23
|
+
try { onChange(getState()); } catch (cause) { console.error('[Resident] state observer failed', cause); }
|
|
24
|
+
};
|
|
25
|
+
const dispose = () => {
|
|
26
|
+
adapter?.close();
|
|
27
|
+
adapter = null;
|
|
28
|
+
cleanup ||= Promise.resolve().then(() => service.close(scope)).then(async () => { await releaseStorage?.(); releaseStorage = null; }).catch(cause => { cleanup = null; throw cause; });
|
|
29
|
+
return cleanup;
|
|
30
|
+
};
|
|
31
|
+
const fail = async cause => {
|
|
32
|
+
error = cause?.message || String(cause); phase = 'failed';
|
|
33
|
+
try { await dispose(); }
|
|
34
|
+
catch (cleanupError) { error = new AggregateError([cause, cleanupError], 'Execution and cleanup failed').message; }
|
|
35
|
+
notify();
|
|
36
|
+
};
|
|
37
|
+
const prepare = () => {
|
|
38
|
+
if (closed) return Promise.reject(new Error('Contribution stopped'));
|
|
39
|
+
if (preparing) return preparing;
|
|
40
|
+
if (adapter) return Promise.resolve(getState());
|
|
41
|
+
if (error) return Promise.reject(new Error(error));
|
|
42
|
+
phase = 'loading';
|
|
43
|
+
const observeProgress = createPreparationProgressObserver();
|
|
44
|
+
let observingPreparation = true;
|
|
45
|
+
preparing = Promise.resolve().then(() => withWorkDevice(service, lifetime.signal, async () => {
|
|
46
|
+
const reportProgress = value => { if (observingPreparation) { progress = observeProgress(structuredClone(value)); notify(); } };
|
|
47
|
+
releaseStorage = await retainModelStorage({ signal: lifetime.signal });
|
|
48
|
+
const resolvedSource = resolveSource ? await resolveSource(model, { signal: lifetime.signal, onProgress: reportProgress }) : source;
|
|
49
|
+
const loaded = await openWorkProvider({ model, service, scope, signal: lifetime.signal,
|
|
50
|
+
generation, maxOutcomeCharacters, resolveAdapter, source: resolvedSource, loadOptions, onProgress: reportProgress });
|
|
51
|
+
lifetime.signal.throwIfAborted();
|
|
52
|
+
await loaded.reset();
|
|
53
|
+
if (model.adapters?.length) adapterIdentities = await loaded.prepareAdapters(model.adapters);
|
|
54
|
+
lifetime.signal.throwIfAborted();
|
|
55
|
+
identity = loaded.getIdentity(); adapter = loaded; phase = 'ready'; notify();
|
|
56
|
+
return getState();
|
|
57
|
+
})).catch(async cause => {
|
|
58
|
+
await fail(cause); throw cause;
|
|
59
|
+
}).finally(() => { observingPreparation = false; preparing = null; });
|
|
60
|
+
notify();
|
|
61
|
+
return preparing;
|
|
62
|
+
};
|
|
63
|
+
const generate = (messages, onUpdate, { signal, adapters = [], maxOutputTokens, contextOwner, contextId }) => {
|
|
64
|
+
if (!getState().ready) return Promise.reject(new Error('Contributor model is not ready'));
|
|
65
|
+
const input = structuredClone(messages);
|
|
66
|
+
const selectedAdapters = structuredClone(adapters);
|
|
67
|
+
const current = adapter, combined = AbortSignal.any([lifetime.signal, signal]);
|
|
68
|
+
const operation = withWorkDevice(service, combined, async () => {
|
|
69
|
+
combined.throwIfAborted();
|
|
70
|
+
if (adapter !== current || error) throw new Error('Resident session was retired before execution');
|
|
71
|
+
phase = 'executing'; notify();
|
|
72
|
+
try {
|
|
73
|
+
const result = await current.generate(input, onUpdate, { signal: combined, adapters: selectedAdapters,
|
|
74
|
+
maxOutputTokens, contextOwner, contextId });
|
|
75
|
+
combined.throwIfAborted(); completed++;
|
|
76
|
+
// Count runtime-reported tokens, never text deltas or estimated words.
|
|
77
|
+
const tokens = result.completion?.generatedTokenCount ?? result.timing?.generatedTokenCount;
|
|
78
|
+
if (Number.isSafeInteger(tokens) && tokens >= 0) production.outputTokens += tokens;
|
|
79
|
+
else production.missingTokenCounts++;
|
|
80
|
+
// Retain only completed, identity-checked execution metadata. Reporting
|
|
81
|
+
// failure must not turn a completed answer into an inference failure.
|
|
82
|
+
try { onComplete({ modelId: model.id, modelIdentity: identity.modelIdentity,
|
|
83
|
+
outputTokens: Number.isSafeInteger(tokens) && tokens >= 0 ? tokens : null }); }
|
|
84
|
+
catch (cause) { console.error('[Resident] completion observer failed', cause); }
|
|
85
|
+
return result;
|
|
86
|
+
} catch (cause) {
|
|
87
|
+
// Cancellation or pre-execution admission rejection may reuse a clean session; runtime or reset failures may not.
|
|
88
|
+
if ((!combined.aborted && cause?.recoverableSession !== true) || !current.isReady()) await fail(cause);
|
|
89
|
+
throw cause;
|
|
90
|
+
} finally {
|
|
91
|
+
if (!closed && adapter) phase = 'ready';
|
|
92
|
+
notify();
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
operations.add(operation);
|
|
96
|
+
operation.finally(() => operations.delete(operation)).catch(() => {});
|
|
97
|
+
return operation;
|
|
98
|
+
};
|
|
99
|
+
const close = () => {
|
|
100
|
+
if (closing) return closing;
|
|
101
|
+
closed = true; phase = 'stopping'; lifetime.abort(new Error('Contribution stopped'));
|
|
102
|
+
closing = (async () => {
|
|
103
|
+
await preparing?.catch(() => {});
|
|
104
|
+
await Promise.allSettled([...operations]);
|
|
105
|
+
try { await dispose(); phase = 'idle'; }
|
|
106
|
+
catch (cause) { phase = 'failed'; error = cause?.message || String(cause); throw cause; }
|
|
107
|
+
finally { notify(); }
|
|
108
|
+
})().catch(cause => { closing = null; throw cause; });
|
|
109
|
+
notify();
|
|
110
|
+
return closing;
|
|
111
|
+
};
|
|
112
|
+
return Object.freeze({ getState, prepare, generate, close });
|
|
113
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Native fleet service
|
|
2
|
+
|
|
3
|
+
`server/fleet/` adds enrolled computer identities, non-cash service credits and
|
|
4
|
+
placement to the existing native participant. It uses the existing WebRTC,
|
|
5
|
+
whole-model and ordered-partition execution paths. It does not change Doppler's
|
|
6
|
+
model arithmetic or qualification rules.
|
|
7
|
+
|
|
8
|
+
This is an operator-configured private fleet. A paired browser can use it from the
|
|
9
|
+
normal chat workspace; unpaired public-network chats do not use this coordinator.
|
|
10
|
+
Purchased credits and payouts are separate.
|
|
11
|
+
|
|
12
|
+
## Computer identity
|
|
13
|
+
|
|
14
|
+
An owner-only `identityFile` retains an Ed25519 signing identity across launches.
|
|
15
|
+
The coordinator enrollment maps its public key to the computer ID, display name
|
|
16
|
+
and owner. Several provider keys may belong to one computer account. Generate
|
|
17
|
+
enrollment from the workspace fleet registry; do not maintain another static
|
|
18
|
+
machine inventory in this repository.
|
|
19
|
+
|
|
20
|
+
GPU adapter information, buffer limits and live memory observations describe
|
|
21
|
+
capacity. They are not unique hardware identifiers or remote attestation. A
|
|
22
|
+
copied signing key can impersonate its enrolled computer.
|
|
23
|
+
|
|
24
|
+
## Credits
|
|
25
|
+
|
|
26
|
+
Before sending a prompt, the requester reserves its maximum charge and records
|
|
27
|
+
dispatch. Providers independently check that admission before executing. The
|
|
28
|
+
credit policy explicitly sets the integer rate, debt limit, output limit,
|
|
29
|
+
pending-request limit and whether computers belonging to one owner may trade.
|
|
30
|
+
Negative balances are permitted within the configured debt limit.
|
|
31
|
+
|
|
32
|
+
Completed whole-model work requires a provider-signed, requester-countersigned
|
|
33
|
+
receipt. Partitioned work requires the ordered stages' signed closing receipts
|
|
34
|
+
and the requester's signed output acknowledgment. Exact model, adapter, route,
|
|
35
|
+
request and participant identities must match. Duplicate settlement has one
|
|
36
|
+
economic effect. Every credit has an equal debit. A requester's own partition
|
|
37
|
+
share is unbilled; there is no reward for paying itself.
|
|
38
|
+
|
|
39
|
+
SQLite retains balances, reservations, the complete signed evidence, provider
|
|
40
|
+
admissions, and the journal. Requester and provider outboxes retry proofs after
|
|
41
|
+
process restart without generating another answer. Partition acknowledgments
|
|
42
|
+
are retained before they return to the coordinator; each contributor independently
|
|
43
|
+
submits its signed closing receipt. Invalid proof is retained as a rejected record
|
|
44
|
+
rather than retried forever.
|
|
45
|
+
|
|
46
|
+
Cancellation can settle an acknowledged prefix. All admitted stages must prove
|
|
47
|
+
cleanup, and a signed final-stage receipt must match that prefix's output chain.
|
|
48
|
+
Unacknowledged work is not billed. A signed `failed` receipt proves cleanup only
|
|
49
|
+
with its closing timestamp; it does not turn a failed answer into a completed one.
|
|
50
|
+
Equivalent verified re-signatures retain the original economic outcome.
|
|
51
|
+
|
|
52
|
+
For whole-model cancellation or failure, the provider retains and submits
|
|
53
|
+
`reploid.generation-terminal/v1` only after its execution owner confirms cleanup.
|
|
54
|
+
Usage remains unknown. Setting `creditPolicy.wholeModelTerminalCharge` to `0`
|
|
55
|
+
accepts zero non-cash terminal charge, frozen into each reservation; omission
|
|
56
|
+
keeps the hold pending. This does not change purchased-credit accounting.
|
|
57
|
+
`acceptFleetTerminalPolicy` in `server/fleet/terminal-policy.js` records an
|
|
58
|
+
operator-approved zero-charge policy migration and an explicit list of unresolved
|
|
59
|
+
whole-model reservations to which it applies. It cannot change metered rates,
|
|
60
|
+
completed balances, or release work without verified cleanup.
|
|
61
|
+
|
|
62
|
+
Admission closes atomically before recovery. A never-dispatched reservation can
|
|
63
|
+
expire. A dispatched request with no admitted providers can release after that
|
|
64
|
+
fence; one with admitted providers still needs their signed closing receipts.
|
|
65
|
+
Deadline expiry closes admission but never proves remote cleanup. Old reservations
|
|
66
|
+
without the admission journal cannot use the zero-admission release rule.
|
|
67
|
+
A request whose dispatch or completion is uncertain retains its hold. Cancellation
|
|
68
|
+
alone does not establish that work was never performed. There is no automatic
|
|
69
|
+
hold forgiveness or cash conversion. Enrollment or policy changes require an
|
|
70
|
+
explicit migration; editing a JSON file cannot reinterpret existing balances.
|
|
71
|
+
|
|
72
|
+
## Placement
|
|
73
|
+
|
|
74
|
+
Each computer submits owner preferences and measured execution envelopes. The
|
|
75
|
+
planner checks the exact model, installed delivery digest, measurement age,
|
|
76
|
+
observation age, input/output limits, GPU/host budgets and single-buffer binding
|
|
77
|
+
limit before ranking a candidate. Costs use measured loading, prefill and decode
|
|
78
|
+
rates. They are scheduling estimates, not throughput guarantees or billing meters.
|
|
79
|
+
|
|
80
|
+
It prefers feasible whole-model capacity, retains warm residents, and adds replicas
|
|
81
|
+
when queue demand warrants them. Otherwise it requires a complete ordered
|
|
82
|
+
partition route across distinct computers and measured links. Search is bounded.
|
|
83
|
+
Missing measurements produce an unavailable result, never an invented estimate.
|
|
84
|
+
Owner opt-out stops idle contribution; active work drains before replacement.
|
|
85
|
+
An opted-out provider cannot admit new credited work.
|
|
86
|
+
|
|
87
|
+
The host reads an operator observation file, refreshes live memory and hardware
|
|
88
|
+
limits, binds it to `native-delivery.json`, and applies plans at idle boundaries.
|
|
89
|
+
`followPlacement` publishes bounded demand while a request waits for an exact
|
|
90
|
+
ready model. Its UTF-8-byte input estimate is labeled as such and is not a token
|
|
91
|
+
charge. Conservative estimates can reject capacity outside the measured envelope.
|
|
92
|
+
|
|
93
|
+
## Running
|
|
94
|
+
|
|
95
|
+
Use Node 22.13 or newer and the packaged native delivery, with its locked Doppler,
|
|
96
|
+
WebRTC and GPU dependencies. The package must retain `native-delivery.json`.
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
npm run package:native
|
|
100
|
+
node server/fleet/service.js /absolute/operator/service.json
|
|
101
|
+
node server/fleet/native-host.js /absolute/operator/host.json
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The service configuration uses schema `reploid.fleet-service/v1` and declares
|
|
105
|
+
`enrollmentFile`, `modelsFile`, `databaseFile`, `creditPolicy`, `placementPolicy`,
|
|
106
|
+
`listenHost`, `port`, and optional `tls: {keyFile, certFile}`. Non-loopback binding
|
|
107
|
+
requires TLS. Pin a private CA for the service processes rather than disabling
|
|
108
|
+
certificate checks. Requests are authenticated with enrolled signing keys.
|
|
109
|
+
|
|
110
|
+
Host configuration uses schema `reploid.fleet-native/v1`, explicit `computerId`,
|
|
111
|
+
`name`, `identityFile`, private `roomId`, `roomTokenFile`, `signalingUrl`,
|
|
112
|
+
`serviceUrl`, `maxOutputTokens` and `models`. Each model entry supplies the exact
|
|
113
|
+
catalog `model`, local artifact `directory`, `mode`, and, for ordered shards,
|
|
114
|
+
`ordered` stage configuration. Doppler's public partition API owns the layer plan.
|
|
115
|
+
The model manifest digest is checked before preparation.
|
|
116
|
+
|
|
117
|
+
`observationFile`, `auto: true` and `pollMs` enable reconciliation. `daemon: true`
|
|
118
|
+
keeps the host running after standard input closes. `initialModel` and
|
|
119
|
+
`initialContribution` explicitly choose startup behavior. A requester using
|
|
120
|
+
`followPlacement: true` must supply a bounded `capacityWaitMs`.
|
|
121
|
+
|
|
122
|
+
The JSON-lines control interface accepts `select`, `state`, `reconcile`,
|
|
123
|
+
`balances`, `generate` and `cancel`. Every command has an `id`; generation emits
|
|
124
|
+
`delta` events followed by the result. `state` includes computer identity,
|
|
125
|
+
execution state, adapter information and owned GPU-buffer accounting. The
|
|
126
|
+
identity file, private room token, database and operator configuration stay out
|
|
127
|
+
of source control.
|
|
128
|
+
|
|
129
|
+
## Evidence
|
|
130
|
+
|
|
131
|
+
Focused tests cover admission, credit conservation, restart/replay, missing or
|
|
132
|
+
forged evidence, cancellation/completion races, partial settlement, remote retirement,
|
|
133
|
+
requester/provider restarts, token caps, admission fencing, local-stage exclusion, placement bounds,
|
|
134
|
+
clock skew and owner opt-out. The opt-in physical fixture is
|
|
135
|
+
`tests/fixtures/fleet-native-physical.js`; it consumes private operator paths and
|
|
136
|
+
an installed package receipt, verifies the remote delivery digest, runs real
|
|
137
|
+
WebRTC requests and retains settlement and cleanup results.
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
REPLOID_FLEET_PHYSICAL=1 node tests/fixtures/fleet-native-physical.js /absolute/operator/physical.json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Physical receipts establish only the recorded devices, prompts, package and
|
|
144
|
+
route. They do not establish general model quality, a speed advantage for
|
|
145
|
+
sharding, Flash-Next readiness, or public-site deployment.
|
|
146
|
+
|
|
147
|
+
## Browser workspace
|
|
148
|
+
|
|
149
|
+
The existing Computers panel can pair with a native requester on the same computer.
|
|
150
|
+
Add `browserBridge` to its private `reploid.fleet-native/v1` configuration:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"browserBridge": {
|
|
155
|
+
"port": 18784,
|
|
156
|
+
"tokenFile": "/absolute/owner-only/browser-pairing-secret",
|
|
157
|
+
"origins": ["https://replo.id", "http://localhost:8000"]
|
|
158
|
+
},
|
|
159
|
+
"daemon": true
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Use at least 32 random bytes encoded as text for the pairing secret, with an
|
|
164
|
+
owner-only file. Run the existing `server/fleet/native-host.js` entry point with
|
|
165
|
+
that configuration. The bridge binds only 127.0.0.1. Every request checks the exact
|
|
166
|
+
browser origin and bearer secret. A browser may separately request permission to
|
|
167
|
+
access the local network. No signing key, private room token or model-file path
|
|
168
|
+
is returned to the browser.
|
|
169
|
+
|
|
170
|
+
In Computers, choose **Connect a native host**, enter its local address and secret,
|
|
171
|
+
and review the enrolled computer names. The pairing is stored only in that tab's
|
|
172
|
+
session storage. Choose a model under **Your private computers**. This authorizes
|
|
173
|
+
your native requester to serve the exact model through its reviewed private pool;
|
|
174
|
+
its existing per-provider disclosure, admission, spending limits and settlement
|
|
175
|
+
remain mandatory. It is delegation to the paired host, not browser-side hardware
|
|
176
|
+
attestation. A changed enrollment requires reconnection. Private selections never
|
|
177
|
+
fall back to public capacity or a local weight download.
|
|
178
|
+
|
|
179
|
+
The answer retains actual whole-model or ordered-stage execution and service-credit
|
|
180
|
+
records. Computers shows fresh observed capacity separately from execution receipts;
|
|
181
|
+
expired observations are offline, not ready. Service credits and receipt export are
|
|
182
|
+
on demand. Stop requests cancellation; a lost stream leaves a pending outcome until
|
|
183
|
+
the native owners reconcile. There is no automatic resend after interruption.
|
|
184
|
+
Browser history, drafts and reload use the existing conversation store; the bridge
|
|
185
|
+
does not retain prompt text. Signing keys and durable accounting remain native.
|
|
186
|
+
|
|
187
|
+
Local model downloads remain a separate reviewed action. Send does not acquire
|
|
188
|
+
weights, even if an older automatic-download preference was stored.
|
|
189
|
+
|
|
190
|
+
## Authenticated HTTP text API
|
|
191
|
+
|
|
192
|
+
An enrolled native requester can also serve `/v1/models`, `/v1/chat/completions`
|
|
193
|
+
and `/v1/responses` over its private pool by adding `textApi` to its
|
|
194
|
+
`reploid.fleet-native/v1` configuration:
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"textApi": {
|
|
199
|
+
"listenHost": "127.0.0.1",
|
|
200
|
+
"port": 18785,
|
|
201
|
+
"tokenFile": "/absolute/owner-only/fleet-api-secret",
|
|
202
|
+
"allowedRecipients": ["peer:5c0ecd2fd5fd8a105a4f8068"]
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Use at least 32 random bytes encoded as text for `tokenFile` with mode `0600`.
|
|
208
|
+
Non-loopback `listenHost` values require `tls: { "keyFile": "...", "certFile": "..." }`.
|
|
209
|
+
Every request checks the bearer secret in constant time, verifies that the
|
|
210
|
+
requester remains in `private-pool` scope, checks disclosed provider signing
|
|
211
|
+
identities against the coordinator's enrolled computers (and optional
|
|
212
|
+
`allowedRecipients`), and reserves and settles non-cash service credits before
|
|
213
|
+
publishing `reploid.http-execution/v1`. Signing keys and room tokens remain on
|
|
214
|
+
the native host.
|