@byollm/protocol 0.1.2 → 0.1.4

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 CHANGED
@@ -1,5 +1,5 @@
1
1
  <!-- release-note 0.1.1 -->
2
- > **`0.1.2` is documentation only — nothing to upgrade.** `PROTOCOL_VERSION`
2
+ > **`0.1.4` is documentation only — nothing to upgrade.** `PROTOCOL_VERSION`
3
3
  > is still `2`, so a 0.1.0 party and a 0.1.1 party talk to each other in both
4
4
  > directions. No dependency, schema, wire field or on-disk shape moved.
5
5
  >
package/dist/index.d.ts CHANGED
@@ -45,7 +45,16 @@ export { C as CONSOLE_FRAME_VERSION, a as CONSOLE_MAX_DATA_BYTES, b as ConsoleBy
45
45
  * unchanged by the move.
46
46
  */
47
47
  /**
48
- * The hub fence, verbatim — ruled by Todd, 2026-09-04.
48
+ * The hub fence, verbatim — ruled by Todd, 2026-10-22 (#4058), replacing the
49
+ * 2026-09-04 wording.
50
+ *
51
+ * It says what the hub sees and stops there. The old sentence opened "sees
52
+ * only what routing and metering need", and that opening is why the sentence
53
+ * was ruled three times: a justification fails every new fact that serves
54
+ * neither — the device that did each job is kept for the team card, not for
55
+ * routing (which has it in Valkey) or billing (unchanged). Without it, the
56
+ * fence is the mapping below: a column that fits a clause is a release, and
57
+ * one that fits none is a ruling.
49
58
  *
50
59
  * Asserted whole rather than by keyword wherever it is checked: "close
51
60
  * enough" is not a standard a page about what we can see gets to use, and a
@@ -976,6 +985,55 @@ declare const ABOUT_SHORT_LEDE = "BYOLLM \u2013 Bring Your Own LLM \u2013 lets y
976
985
  declare const ABOUT_SHORT_TAIL = "Sites can charge you less because you bring your own \u2013 see why that matters \u2192. Teams can optionally share the free or metered services on their devices with people they name. Personal subscriptions are never shared.";
977
986
  /** Both halves, for a surface that wants the paragraph entire. */
978
987
  declare const ABOUT_SHORT = "BYOLLM \u2013 Bring Your Own LLM \u2013 lets you use your own AI on websites you authorize. A small program installed on your machine lets you use your own models and subscriptions on any BYOLLM-integrated site, including new models the moment you get access \u2013 no site updates required. BYOLLM Cloud connects sites to your devices with end-to-end encryption, so no one, including us, can see your data.\n\nSites can charge you less because you bring your own \u2013 see why that matters \u2192. Teams can optionally share the free or metered services on their devices with people they name. Personal subscriptions are never shared.";
988
+ /** Who a prompt is for, which is also which path it sets up. */
989
+ type AgentPromptAudience = "user" | "developer" | "operator";
990
+ /** One "paste this into your agent" prompt. */
991
+ interface AgentPrompt {
992
+ /** Stable, for anchors: `agent-<id>` on byo-llm.com. */
993
+ readonly id: string;
994
+ readonly title: string;
995
+ readonly audience: AgentPromptAudience;
996
+ /** Verbatim, line breaks included — what the copy button copies. */
997
+ readonly prompt: string;
998
+ }
999
+ /** The heading every surface shows above the prompts. */
1000
+ declare const AGENT_PROMPTS_HEADING = "You already have an AI. Hand it this.";
1001
+ /** The one line under it. */
1002
+ declare const AGENT_PROMPTS_LEDE = "Paste the prompt into whatever you use \u2014 Claude, ChatGPT, Codex, Cursor, a local model \u2014 and it does the setup, stopping where a step needs you.";
1003
+ /** Set up my computer, add BYOLLM to my site, run my own relay — in that order. */
1004
+ declare const AGENT_PROMPTS: readonly AgentPrompt[];
1005
+
1006
+ /**
1007
+ * What BYOLLM does not do yet — one list, rendered on every surface.
1008
+ *
1009
+ * Todd, 2026-10-06: the sites did not call out the limits the way the
1010
+ * open-sourcing post did. The post's sentence is the source of the words; this
1011
+ * is the source of the list. The README's "Not yet", byo-llm.com's "What it
1012
+ * doesn't do yet" and byollm.cloud render from here, and a test on each
1013
+ * surface fails when its copy and this disagree.
1014
+ *
1015
+ * Hand-written beside `about.ts` rather than inside it, because that file is
1016
+ * generated from the ABOUT markdown and this one derives from code.
1017
+ */
1018
+ interface NotYet {
1019
+ /** The missing thing, phrased so "no …" reads as a sentence. */
1020
+ readonly what: string;
1021
+ /** What that means for you, when the name alone does not say. */
1022
+ readonly detail?: string;
1023
+ }
1024
+ /** What BYOLLM does not do yet, in the post's order. */
1025
+ declare const NOT_YET: readonly NotYet[];
1026
+ declare const NOT_YET_LEDE = "Things we know are limiting right now:";
1027
+ declare const NOT_YET_TAIL = "We have plans for every one of these, and we are building in public.";
1028
+ /** The list as one paragraph — the post's sentence, from the list. */
1029
+ declare function notYetSentence(list?: readonly NotYet[]): string;
1030
+ /**
1031
+ * One entry as a list line: "Streaming — a result comes back whole".
1032
+ *
1033
+ * Every list surface renders this, so the README, byo-llm.com and
1034
+ * byollm.cloud cannot each phrase an entry their own way.
1035
+ */
1036
+ declare function notYetLine({ what, detail }: NotYet): string;
979
1037
 
980
1038
  /**
981
1039
  * Its members, for anything that has to report what it accepts.
@@ -2984,4 +3042,4 @@ declare const MUST_IDS: readonly ("PAIR_ONE_USER" | "PAIR_INTERACTIVE" | "PAIR_C
2984
3042
  /** Every MUST verified a particular way. */
2985
3043
  declare function mustsVerifiedBy(kind: MustVerification): MustId[];
2986
3044
 
2987
- 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, DEFAULT_ROUTING, DeliveredResult, ENDPOINTS, ERROR_STATUS, type Endpoint, type FenceClause, FetchRequest, FetchResponse, type FloorRefusal, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, GrantRef, type GrantRefusal, HUB_FENCE, HUB_FENCE_CLAUSES, 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, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, PurposeRouting, REFUSAL_MESSAGES, REFUSAL_TEXT, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASSES, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, type StopReason, StopReasonSchema, 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, declaredVersion, describeBytes, effectiveOfferScope, envelopeBytes, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, kindsOf, matchAudience, mayOfferUpdate, mentionsWireField, mustsVerifiedBy, payloadTextLength, provenanceFor, resolveCost, routingOf, signGrant, signRequest, signSiteRequest, signSuccession, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, tooLargeMessage, updateOfferFor, verifyGrant, verifyLink, verifyRequest, verifySiteRequest, walkSuccession, withoutComments };
3045
+ export { ABOUT, ABOUT_SHORT, ABOUT_SHORT_LEDE, ABOUT_SHORT_TAIL, AGENT_PROMPTS, AGENT_PROMPTS_HEADING, AGENT_PROMPTS_LEDE, AUDIENCES, type AgentPrompt, type AgentPromptAudience, 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, DEFAULT_ROUTING, DeliveredResult, ENDPOINTS, ERROR_STATUS, type Endpoint, type FenceClause, FetchRequest, FetchResponse, type FloorRefusal, GRANT_CONTEXT, GRANT_MAX_AGE_MS, GRANT_SIGNED_FIELDS, GeneratePayload, type GrantClaims, GrantRef, type GrantRefusal, HUB_FENCE, HUB_FENCE_CLAUSES, 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, NOT_YET, NOT_YET_LEDE, NOT_YET_TAIL, type NotYet, OFFER_SCOPES, OfferScope, PAYLOAD_LIMITS, PROTOCOL_PREFIX, PROTOCOL_VERSION, PairPollRequest, PairPollResponse, PairRequest, PairStartRequest, PairStartResponse, type PayloadFor, PublicIdentity, Purpose, PurposeRouting, REFUSAL_MESSAGES, REFUSAL_TEXT, RESERVED_PURPOSE, RETIREMENT_WINDOW_MS, RefusalReason, ReleaseRequest, ReleaseResponse, RequestSignature, ResultDisposition, ResultProvenance, ResultRequest, ResultResponse, RunMetadata, SIZE_CLASSES, SIZE_CLASS_LIMITS, SUCCESSION_CONTEXT, SUPPORTED_PROTOCOL_VERSIONS, SealedOutcome, type SignatureFailure, SignedGrant, SizeClass, type SpendConsent, type StopReason, StopReasonSchema, 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, declaredVersion, describeBytes, effectiveOfferScope, envelopeBytes, grantStatement, isBackendId, isCloudTaggedModel, isJobKind, isLocalHost, isTerminal, kindsOf, matchAudience, mayOfferUpdate, mentionsWireField, mustsVerifiedBy, notYetLine, notYetSentence, payloadTextLength, provenanceFor, resolveCost, routingOf, signGrant, signRequest, signSiteRequest, signSuccession, singlePurposeManifest, sizeClassCeiling, sizeClassOf, successionStatement, tooLargeMessage, updateOfferFor, verifyGrant, verifyLink, verifyRequest, verifySiteRequest, walkSuccession, withoutComments };
package/dist/index.js CHANGED
@@ -22,18 +22,29 @@ import {
22
22
  } from "./chunk-J3HTAGMX.js";
23
23
 
24
24
  // src/hub-fence.ts
25
- var HUB_FENCE = "byollm.cloud sees only what routing and metering need: which devices and sites are connected, each job's kind, size, and outcome, and timestamps. Never prompts, never answers, never credentials.";
25
+ var HUB_FENCE = "byollm.cloud sees who asked, which devices and sites are connected, which device did each job, and each job's kind, size, outcome and time. Never prompts, never answers, never credentials.";
26
26
  var HUB_FENCE_CLAUSES = Object.freeze([
27
27
  {
28
- says: "which devices and sites are connected",
29
- covers: Object.freeze(["owner_id", "site_id", "member_id"])
28
+ says: "who asked",
29
+ covers: Object.freeze(["owner_id", "member_id"])
30
30
  },
31
+ /*
32
+ * The pair row's device owner — the hub's one row per (requester, device
33
+ * owner), #4058's shape (c). Ruled into "devices and sites"; the clause runs
34
+ * on through "which device did each job" because that is the phrase the
35
+ * column makes true, and a clause that stopped short would map the column
36
+ * to words that do not mention it.
37
+ */
31
38
  {
32
- says: "each job's kind, size, and outcome",
39
+ says: "which devices and sites are connected, which device did each job",
40
+ covers: Object.freeze(["site_id", "served_by_owner_id"])
41
+ },
42
+ {
43
+ says: "each job's kind, size, outcome",
33
44
  covers: Object.freeze(["kind", "size_class", "disposition", "bytes"])
34
45
  },
35
46
  {
36
- says: "and timestamps",
47
+ says: "and time",
37
48
  covers: Object.freeze(["at", "month", "updated_at"])
38
49
  },
39
50
  /*
@@ -2157,6 +2168,59 @@ var ABOUT_SHORT_TAIL = "Sites can charge you less because you bring your own \u2
2157
2168
  var ABOUT_SHORT = `${ABOUT_SHORT_LEDE}
2158
2169
 
2159
2170
  ${ABOUT_SHORT_TAIL}`;
2171
+ var AGENT_PROMPTS_HEADING = "You already have an AI. Hand it this.";
2172
+ var AGENT_PROMPTS_LEDE = "Paste the prompt into whatever you use \u2014 Claude, ChatGPT, Codex, Cursor, a local model \u2014 and it does the setup, stopping where a step needs you.";
2173
+ var AGENT_PROMPTS = [
2174
+ {
2175
+ "id": "computer",
2176
+ "title": "Set up my computer",
2177
+ "audience": "user",
2178
+ "prompt": "Set up BYOLLM on my computer so websites I approve can use the AI I already\nhave. Some steps need me at the keyboard: tell me exactly what to type, then\nwait. First I open Terminal (Mac) or PowerShell (Windows). Run\n`node --version`; if it fails or is below 22.14, I install the LTS version\nof Node.js \u2014 the free program BYOLLM runs on \u2014 from https://nodejs.org and\nreopen the window. Then run `npm install -g byollm@latest`. Then I run\n`byollm setup` myself, because it asks questions: it finds what I have\n(Ollama, MLX or llama.cpp here, or my Claude Pro/Max or Codex sign-in \u2014\nsubscriptions stay mine, never shared) and pairs with byollm.cloud. When it\nprints a pairing code and fingerprint, STOP: I approve it at\nhttps://dashboard.byollm.cloud/devices and check the fingerprint matches.\nThen run `byollm status` and `byollm services`, fix anything they name, and\n`byollm start` if it is not running. Finish by having me press Connect at\nhttps://test.byollm.cloud. Reference:\nhttps://docs.byollm.cloud/#what-is-byollm and\nhttps://docs.byollm.cloud/#keep-daemon-running. Don't guess commands:\n`byollm --help` is the authority."
2179
+ },
2180
+ {
2181
+ "id": "site",
2182
+ "title": "Add BYOLLM to my site",
2183
+ "audience": "developer",
2184
+ "prompt": 'Add BYOLLM to this project so my users bring their own AI. Install\n`@byollm/server`, generate site keys once with\n`npx --package @byollm/server keygen` and put them in env (never in the\nrepo), mount the handler at `/byollm` (not under `/api` \u2014 the daemon pairs\nwith an origin), and add one `enqueue` with a timeout and a no-runner path \u2014\nnever a bare await. Then register the site at https://dashboard.byollm.cloud\nand add the Connect button exactly as https://docs.byollm.cloud/#embed says:\nthe iframe gets `site`, `state` and `return`, the page posts\n`{ byollm: "hello" }` first, and the return page posts\n`{ byollm: "connected" }` and closes. Job states and why an answer stopped:\nhttps://docs.byollm.cloud/#job-states and\nhttps://docs.byollm.cloud/#stop-reason. Test against\nhttps://test.byollm.cloud\'s flow before you tell me it works. STOP and ask\nme for anything that needs my dashboard login.'
2185
+ },
2186
+ {
2187
+ "id": "relay",
2188
+ "title": "Run my own relay",
2189
+ "audience": "operator",
2190
+ "prompt": "Stand up my own BYOLLM relay instead of byollm.cloud. Use `@byollm/relay`\nand `@byollm/control-plane` from npm \u2014 one replica on the built-in memory\nstore, or give the relay a shared `RoutingStore` to run more \u2014 and prove it\nwith `@byollm/conformance`\n(`npx --package @byollm/conformance byollm-certify <target>`) before\npointing any daemon at it: a server is byollm-compatible when the kit\npasses. Then pair a daemon with `byollm connect <my relay origin>`. The\nrelay never sees prompts (https://docs.byollm.cloud/#what-we-see) and that\nmust stay true in my deployment. Reference:\nhttps://github.com/oftomorrowinc/byollm#packages. STOP and ask me before\nanything that costs money or opens a port to the internet."
2191
+ }
2192
+ ];
2193
+
2194
+ // src/not-yet.ts
2195
+ var and = (items) => items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.slice(-1).join("")}`;
2196
+ function notYetFor(kinds) {
2197
+ return Object.freeze([
2198
+ { what: "tool use" },
2199
+ { what: "access to your local files" },
2200
+ { what: "streaming", detail: "a result comes back whole" },
2201
+ {
2202
+ what: `job kinds beyond ${and(kinds)}`,
2203
+ detail: "no embeddings or images yet"
2204
+ },
2205
+ {
2206
+ what: "jobs while your device is offline",
2207
+ detail: "your device has to be online for your jobs to run"
2208
+ }
2209
+ ]);
2210
+ }
2211
+ var NOT_YET = notYetFor(JobKind.options);
2212
+ var NOT_YET_LEDE = "Things we know are limiting right now:";
2213
+ var NOT_YET_TAIL = "We have plans for every one of these, and we are building in public.";
2214
+ function notYetSentence(list = NOT_YET) {
2215
+ const items = list.map(
2216
+ ({ what, detail }) => `no ${what}${detail ? ` (${detail})` : ""}`
2217
+ );
2218
+ return `${NOT_YET_LEDE} ${and(items)}. ${NOT_YET_TAIL}`;
2219
+ }
2220
+ function notYetLine({ what, detail }) {
2221
+ const head = what.charAt(0).toUpperCase() + what.slice(1);
2222
+ return detail ? `${head} \u2014 ${detail}` : head;
2223
+ }
2160
2224
 
2161
2225
  // src/signing.ts
2162
2226
  import { createHash as createHash2 } from "crypto";
@@ -2729,6 +2793,9 @@ export {
2729
2793
  ABOUT_SHORT,
2730
2794
  ABOUT_SHORT_LEDE,
2731
2795
  ABOUT_SHORT_TAIL,
2796
+ AGENT_PROMPTS,
2797
+ AGENT_PROMPTS_HEADING,
2798
+ AGENT_PROMPTS_LEDE,
2732
2799
  AUDIENCES,
2733
2800
  Audience,
2734
2801
  BACKENDS,
@@ -2795,6 +2862,9 @@ export {
2795
2862
  MUST_IDS,
2796
2863
  Manifest,
2797
2864
  MatchRefusal,
2865
+ NOT_YET,
2866
+ NOT_YET_LEDE,
2867
+ NOT_YET_TAIL,
2798
2868
  OFFER_SCOPES,
2799
2869
  OfferScope,
2800
2870
  PAYLOAD_LIMITS,
@@ -2874,6 +2944,8 @@ export {
2874
2944
  mayOfferUpdate,
2875
2945
  mentionsWireField,
2876
2946
  mustsVerifiedBy,
2947
+ notYetLine,
2948
+ notYetSentence,
2877
2949
  open,
2878
2950
  payloadTextLength,
2879
2951
  provenanceFor,