@byollm/protocol 0.1.0-alpha.84 → 0.1.0-alpha.86
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/README.md +1 -1
- package/dist/index.d.ts +66 -1
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -845,6 +845,38 @@ declare function updateOfferFor(input: {
|
|
|
845
845
|
}): {
|
|
846
846
|
readonly updateTo?: string;
|
|
847
847
|
};
|
|
848
|
+
/**
|
|
849
|
+
* Source with its comments removed, for the checks below.
|
|
850
|
+
*
|
|
851
|
+
* Comments go first because a rule about a field has to be explainable in
|
|
852
|
+
* prose beside the code it governs — and the first version of the relay's
|
|
853
|
+
* fence test flagged its own explanation, which was written to say there
|
|
854
|
+
* must be no such write anywhere.
|
|
855
|
+
*/
|
|
856
|
+
declare function withoutComments(source: string): string;
|
|
857
|
+
/**
|
|
858
|
+
* Does this source mention a wire field at all?
|
|
859
|
+
*
|
|
860
|
+
* **A word, not a spelling.** The relay's fence test shipped scanning for
|
|
861
|
+
* `/\bupdateTo\s*:/`, which is one syntax of one way to set a property —
|
|
862
|
+
* `"updateTo": offer`, `res.updateTo = offer`, `res["updateTo"] = offer` and
|
|
863
|
+
* shorthand in a spread all walk straight past it. The check's claim was
|
|
864
|
+
* "there is nowhere else to call from"; what it enforced was a spelling.
|
|
865
|
+
* That is our own recurring law, and this is its sixth instance — the first
|
|
866
|
+
* inside a test written to be structural rather than remembered.
|
|
867
|
+
*
|
|
868
|
+
* So the question this asks is deliberately blunter than the rule it serves.
|
|
869
|
+
* A mention is not a write, and the false positives are the point: anything
|
|
870
|
+
* that names the field in code has to be looked at by a person, because the
|
|
871
|
+
* cost of the miss is every daemon that predates the field rejecting every
|
|
872
|
+
* heartbeat.
|
|
873
|
+
*
|
|
874
|
+
* Lives here, beside {@link updateOfferFor}, so the hub and the relay run one
|
|
875
|
+
* copy rather than two that drift — the field's hazard is fleet-wide and it
|
|
876
|
+
* crosses a repository boundary, which is exactly where a duplicated rule
|
|
877
|
+
* stops being the same rule.
|
|
878
|
+
*/
|
|
879
|
+
declare function mentionsWireField(source: string, field: string): boolean;
|
|
848
880
|
|
|
849
881
|
/** The full description — five sections, plus why it matters. */
|
|
850
882
|
declare const ABOUT = "# About BYOLLM\n\n**What BYOLLM is**\n\nBYOLLM lets you use your own AI on websites. You install one small program on\nyour computer. Then, websites that support BYOLLM can use the AI you already\nhave \u2014 a free model running on your machine, or an AI service you already pay\nfor \u2014 instead of the website paying for AI and passing the cost to you.\n\n**Why it matters**\n\nFor you:\n\n- Your favorite model, everywhere you go.\n- New models the moment you get them \u2013 not when a site gets around to adding\n them.\n- Encrypted end-to-end. Your prompts go to your own device; byollm.cloud can't\n read them.\n- Sites never learn which model you use, and your subscriptions are never\n shared.\n- Pay less. Sites that don't pay for AI can charge you less \u2013 or nothing.\n\nFor sites and developers:\n\n- Zero AI bills. Your users bring their own compute.\n- No floating money \u2013 you don't pay LLM bills up front and hope to collect\n later, and you never ask people to prepay just to try you.\n- Free trials that cost you nothing to offer.\n- Ship the AI features you kept private for fear of the API bill.\n- One small integration. Your users choose the models.\n\n**Your device**\n\nThe `byollm` program runs on your computer. It knows which AI services you have\nset up: free open-source models on your machine, metered services you pay per\nuse, or your own subscriptions like Claude Pro/Max. When a website you have\nenabled sends work, your device runs it with the service you chose. Your\nprompts are encrypted end-to-end to your own device. byollm.cloud passes them\nalong and cannot read them.\n\n**Sites**\n\nA website that wants to use BYOLLM says what it needs \u2014 \"writing help,\" \"chat,\"\nand so on. When you connect the site, you pick which of your services answers\neach one. The site never learns which model you use. You can turn a site off at\nany time, and it stops getting your work.\n\n**Teams (optional)**\n\nA team lets you share what runs on your devices with people you name \u2014 the free\nopen-source models on your machine, or a metered service with a spending limit\nyou set. Your subscription accounts (like Claude Pro/Max) are never shared with\nanyone. That is a rule, not a setting.\n\n**byollm.cloud (or your own relay)**\n\nMany sites, many devices, many people. byollm.cloud keeps track of who has\nallowed what and sends each job to the right device. It never sees your\nprompts. If you would rather run this part yourself, the relay is open source \u2014\nyou can run your own instead of using byollm.cloud.";
|
|
@@ -1796,6 +1828,39 @@ declare const MAX_ENVELOPE_BYTES: number;
|
|
|
1796
1828
|
* this function is that one number answers both questions.
|
|
1797
1829
|
*/
|
|
1798
1830
|
declare function envelopeBytes(envelope: unknown): number;
|
|
1831
|
+
/**
|
|
1832
|
+
* A size somebody can act on, rounded **up** and only ever up.
|
|
1833
|
+
*
|
|
1834
|
+
* The rounding rule, in one place, because it has now been got wrong twice —
|
|
1835
|
+
* B072. `toFixed` rounds to nearest, so a message one byte over the line
|
|
1836
|
+
* printed "this message is 10.5 MB and the limit is 10.5 MB": a refusal that
|
|
1837
|
+
* reads as a contradiction, given to somebody who now has no idea what to
|
|
1838
|
+
* change.
|
|
1839
|
+
*
|
|
1840
|
+
* The relay found that, fixed it, and wrote the reasoning down beside the
|
|
1841
|
+
* fix. The SDK's refusal then rediscovered the identical bug, because it
|
|
1842
|
+
* copied the SENTENCE rather than the function — which is the same shape as
|
|
1843
|
+
* `MAX_BODY_BYTES` diverging from `MAX_ENVELOPE_BYTES`, and the same answer:
|
|
1844
|
+
* neither side holds the rule.
|
|
1845
|
+
*
|
|
1846
|
+
* Up is also the honest direction. Understating how far over a message is
|
|
1847
|
+
* sends somebody to trim a hundred bytes off something that needs to lose a
|
|
1848
|
+
* megabyte; overstating by a tenth costs them nothing.
|
|
1849
|
+
*/
|
|
1850
|
+
declare function describeBytes(bytes: number): string;
|
|
1851
|
+
/**
|
|
1852
|
+
* What a message that is too big is told, minus anything about pricing.
|
|
1853
|
+
*
|
|
1854
|
+
* Shared because both planes refuse the same thing for the same reason. What
|
|
1855
|
+
* is NOT shared is the relay's "every plan has the same ceiling" — a hosted
|
|
1856
|
+
* sentence, and meaningless to somebody self-hosting the direct lane, where
|
|
1857
|
+
* there are no plans. One rule, two audiences: the rule travels, the words
|
|
1858
|
+
* about our billing do not.
|
|
1859
|
+
*/
|
|
1860
|
+
declare function tooLargeMessage(input: {
|
|
1861
|
+
readonly bytes: number;
|
|
1862
|
+
readonly limit: number;
|
|
1863
|
+
}): string;
|
|
1799
1864
|
/** Where the bucket boundaries sit, in characters of payload text. */
|
|
1800
1865
|
declare const SIZE_CLASS_LIMITS: Readonly<{
|
|
1801
1866
|
small: 4000;
|
|
@@ -2810,4 +2875,4 @@ declare const MUST_IDS: readonly ("PAIR_ONE_USER" | "PAIR_INTERACTIVE" | "PAIR_C
|
|
|
2810
2875
|
/** Every MUST verified a particular way. */
|
|
2811
2876
|
declare function mustsVerifiedBy(kind: MustVerification): MustId[];
|
|
2812
2877
|
|
|
2813
|
-
export { ABOUT, ABOUT_SHORT, ABOUT_SHORT_LEDE, ABOUT_SHORT_TAIL, AUDIENCES, Audience, BACKENDS, BACKEND_CLASSES, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, CLOCK_ATTRIBUTION_MS, CLOCK_SKEW_WARN_MS, Capability, CapabilityMatrix, ChatMessage, ChatPayload, ClaimRequest, ClaimResponse, ClaimedJob, ClaimedStub, DeliveredResult, ENCRYPTION_KEY_CONTEXT, ENDPOINTS, ENVELOPE_MAX_AGE_MS, ERROR_STATUS, type Endpoint, type EnvelopeContext, EnvelopeDirection, type EnvelopeFailure, FetchRequest, FetchResponse, type FloorRefusal, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, GrantRef, type GrantRefusal, HeartbeatRequest, HeartbeatResponse, JOB_KINDS, JobKind, JobOutcome, JobPayload, JobRefused, JobResultCanceled, JobResultError, JobResultOk, JobState, JobStub, KindedPayload, Lease, MAX_CLOCK_SKEW_MS, MAX_ENVELOPE_BYTES, MAX_PURPOSES, MAX_SUCCESSION_CHAIN, MIN_PROTOCOL_VERSION, MUSTS, MUST_IDS, Manifest, type MatchDaemon, type MatchJob, MatchRefusal, type MatchResult, type Must, type MustEnforcer, type MustId, type MustVerification, type MustVerifiedBy, OFFER_SCOPES, OfferScope, type OpenResult, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, REFUSAL_MESSAGES, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASSES, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedEnvelope, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, StoredKeys, Succession, type SuccessionFailure, type SuccessionWalk, TERMINAL_STATES, UPDATE_OFFER_SINCE, UPGRADE_COMMAND, type VersionRefusal, WireError, WireErrorCode, WithheldKind, backendDescriptor, backendName, canTransition, canonicalRequest, checkDaemonFloor, checkProtocolVersion, classifyCost, compareVersions, cryptoReady, declaredVersion, effectiveOfferScope, envelopeBytes, fingerprint, generateKeys, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, keyId, kindsOf, matchAudience, mayOfferUpdate, mustsVerifiedBy, open, payloadTextLength, provenanceFor, publicIdentityOf, resolveCost, seal, signGrant, signRequest, signSiteRequest, signSuccession, signWith, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, updateOfferFor, verifyGrant, verifyLink, verifyPublicIdentity, verifyRequest, verifySiteRequest, verifyWith, walkSuccession };
|
|
2878
|
+
export { ABOUT, ABOUT_SHORT, ABOUT_SHORT_LEDE, ABOUT_SHORT_TAIL, AUDIENCES, Audience, BACKENDS, BACKEND_CLASSES, BACKEND_IDS, BackendClass, BackendCost, type BackendDescriptor, type BackendId, BackendIdSchema, CLOCK_ATTRIBUTION_MS, CLOCK_SKEW_WARN_MS, Capability, CapabilityMatrix, ChatMessage, ChatPayload, ClaimRequest, ClaimResponse, ClaimedJob, ClaimedStub, DeliveredResult, ENCRYPTION_KEY_CONTEXT, ENDPOINTS, ENVELOPE_MAX_AGE_MS, ERROR_STATUS, type Endpoint, type EnvelopeContext, EnvelopeDirection, type EnvelopeFailure, FetchRequest, FetchResponse, type FloorRefusal, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, GrantRef, type GrantRefusal, HeartbeatRequest, HeartbeatResponse, JOB_KINDS, JobKind, JobOutcome, JobPayload, JobRefused, JobResultCanceled, JobResultError, JobResultOk, JobState, JobStub, KindedPayload, Lease, MAX_CLOCK_SKEW_MS, MAX_ENVELOPE_BYTES, MAX_PURPOSES, MAX_SUCCESSION_CHAIN, MIN_PROTOCOL_VERSION, MUSTS, MUST_IDS, Manifest, type MatchDaemon, type MatchJob, MatchRefusal, type MatchResult, type Must, type MustEnforcer, type MustId, type MustVerification, type MustVerifiedBy, OFFER_SCOPES, OfferScope, type OpenResult, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, REFUSAL_MESSAGES, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASSES, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedEnvelope, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, StoredKeys, Succession, type SuccessionFailure, type SuccessionWalk, TERMINAL_STATES, UPDATE_OFFER_SINCE, UPGRADE_COMMAND, type VersionRefusal, WireError, WireErrorCode, WithheldKind, backendDescriptor, backendName, canTransition, canonicalRequest, checkDaemonFloor, checkProtocolVersion, classifyCost, compareVersions, cryptoReady, declaredVersion, describeBytes, effectiveOfferScope, envelopeBytes, fingerprint, generateKeys, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, keyId, kindsOf, matchAudience, mayOfferUpdate, mentionsWireField, mustsVerifiedBy, open, payloadTextLength, provenanceFor, publicIdentityOf, resolveCost, seal, signGrant, signRequest, signSiteRequest, signSuccession, signWith, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, tooLargeMessage, updateOfferFor, verifyGrant, verifyLink, verifyPublicIdentity, verifyRequest, verifySiteRequest, verifyWith, walkSuccession, withoutComments };
|
package/dist/index.js
CHANGED
|
@@ -905,6 +905,12 @@ function envelopeBytes(envelope) {
|
|
|
905
905
|
const serialised = JSON.stringify(envelope);
|
|
906
906
|
return serialised === void 0 ? 0 : serialised.length;
|
|
907
907
|
}
|
|
908
|
+
function describeBytes(bytes) {
|
|
909
|
+
return `${(Math.ceil(bytes / (1024 * 1024) * 10) / 10).toFixed(1)} MB`;
|
|
910
|
+
}
|
|
911
|
+
function tooLargeMessage(input) {
|
|
912
|
+
return `this message is ${describeBytes(input.bytes)} and the limit is ${describeBytes(input.limit)} \u2014 it is a limit on one message rather than on how many you send. Split the work into smaller jobs and send them separately.`;
|
|
913
|
+
}
|
|
908
914
|
var SIZE_CLASS_LIMITS = Object.freeze({
|
|
909
915
|
small: 4e3,
|
|
910
916
|
medium: 64e3,
|
|
@@ -1896,6 +1902,12 @@ function updateOfferFor(input) {
|
|
|
1896
1902
|
function exactOffer(value) {
|
|
1897
1903
|
return /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(value) ? value : void 0;
|
|
1898
1904
|
}
|
|
1905
|
+
function withoutComments(source) {
|
|
1906
|
+
return source.replace(/\/\*[\s\S]*?\*\//g, " ").replace(/^[ \t]*\/\/.*$/gm, " ");
|
|
1907
|
+
}
|
|
1908
|
+
function mentionsWireField(source, field) {
|
|
1909
|
+
return new RegExp(`\\b${field}\\b`).test(withoutComments(source));
|
|
1910
|
+
}
|
|
1899
1911
|
|
|
1900
1912
|
// src/about.ts
|
|
1901
1913
|
var ABOUT = `# About BYOLLM
|
|
@@ -2621,6 +2633,7 @@ export {
|
|
|
2621
2633
|
compareVersions,
|
|
2622
2634
|
cryptoReady,
|
|
2623
2635
|
declaredVersion,
|
|
2636
|
+
describeBytes,
|
|
2624
2637
|
effectiveOfferScope,
|
|
2625
2638
|
envelopeBytes,
|
|
2626
2639
|
fingerprint,
|
|
@@ -2635,6 +2648,7 @@ export {
|
|
|
2635
2648
|
kindsOf,
|
|
2636
2649
|
matchAudience,
|
|
2637
2650
|
mayOfferUpdate,
|
|
2651
|
+
mentionsWireField,
|
|
2638
2652
|
mustsVerifiedBy,
|
|
2639
2653
|
open,
|
|
2640
2654
|
payloadTextLength,
|
|
@@ -2651,6 +2665,7 @@ export {
|
|
|
2651
2665
|
sizeClassCeiling,
|
|
2652
2666
|
sizeClassOf,
|
|
2653
2667
|
successionStatement,
|
|
2668
|
+
tooLargeMessage,
|
|
2654
2669
|
updateOfferFor,
|
|
2655
2670
|
verifyGrant,
|
|
2656
2671
|
verifyLink,
|
|
@@ -2658,6 +2673,7 @@ export {
|
|
|
2658
2673
|
verifyRequest,
|
|
2659
2674
|
verifySiteRequest,
|
|
2660
2675
|
verifyWith,
|
|
2661
|
-
walkSuccession
|
|
2676
|
+
walkSuccession,
|
|
2677
|
+
withoutComments
|
|
2662
2678
|
};
|
|
2663
2679
|
//# sourceMappingURL=index.js.map
|