upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpablof7z <p@f7z.io>2023-07-24 00:38:47 +0300
committerpablof7z <p@f7z.io>2023-07-24 00:38:47 +0300
commit4cb3ac871f1c54d2e845ec8655bf564072377a46 (patch)
tree5a00210d6137f759a84e6310660c1d2d1a5aa730
parent280483adc5b2299886e1e15e369557001e8807af (diff)
clarifications, hopefully
-rw-r--r--vending-machine.md180
1 files changed, 87 insertions, 93 deletions
diff --git a/vending-machine.md b/vending-machine.md
index c4fdc18..276132d 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -1,4 +1,4 @@
1NIP-XX 1NIP-90
2====== 2======
3 3
4Data Vending Machine 4Data Vending Machine
@@ -6,7 +6,9 @@ Data Vending Machine
6 6
7`draft` `optional` `author:pablof7z` 7`draft` `optional` `author:pablof7z`
8 8
9This NIP defines the interaction between customers and Service Providers to perform on-demand computation. 9This NIP defines the interaction between customers and Service Providers for performing on-demand computation.
10
11Money in, data out.
10 12
11## Kinds 13## Kinds
12This NIP reserves the range `65000-66000` for data vending machine use. 14This NIP reserves the range `65000-66000` for data vending machine use.
@@ -20,18 +22,18 @@ This NIP reserves the range `65000-66000` for data vending machine use.
20[Appendix 2](#appendix-2-job-types) defines the job types. 22[Appendix 2](#appendix-2-job-types) defines the job types.
21 23
22## Rationale 24## Rationale
23Nostr can act as a marketplace for data processing, where users request jobs to be processed in certain ways (e.g. "speech-to-text", "summarization", etc.), but where they don't necessarily care about "who" processes the data. 25Nostr can act as a marketplace for data processing, where users request jobs to be processed in certain ways (e.g., "speech-to-text", "summarization", etc.), but they don't necessarily care about "who" processes the data.
24 26
25This NIP is not to be confused with a 1:1 marketplace; but rather, a flow where user announces a desired output, willingness to pay, and service providers compete to fulfill the job requirement in the best way possible. 27This NIP is not to be confused with a 1:1 marketplace; instead, it describes a flow where a user announces a desired output, willingness to pay, and service providers compete to fulfill the job requirement in the best way possible.
26 28
27### Actors 29### Actors
28There are two actors to the workflow described in this NIP: 30There are two actors in the workflow described in this NIP:
29* Customers (npubs who request a job) 31* Customers (npubs who request a job)
30* Service providers (npubs who fulfill jobs) 32* Service providers (npubs who fulfill jobs)
31 33
32# Event Kinds 34# Event Kinds
33## Job request 35## Job request
34A request to have data processed -- published by a customer 36A request to have data processed, published by a customer
35 37
36```json 38```json
37{ 39{
@@ -50,33 +52,34 @@ A request to have data processed -- published by a customer
50 52
51All tags are optional. 53All tags are optional.
52 54
53* `i` tag: Input data for the job, (zero or more inputs may exist) 55* `i` tag: Input data for the job (zero or more inputs may exist)
54 * `<data>`: The argument for the input 56 * `<data>`: The argument for the input
55 * `<input-type>`: The way this argument should be interpreted, MUST be one of: 57 * `<input-type>`: The way this argument should be interpreted, MUST be one of:
56 * `url`: a URL to be fetched 58 * `url`: A URL to be fetched
57 * `event`: a nostr event ID, include an optional relay-url extra param 59 * `event`: A Nostr event ID, include an optional relay-url extra param
58 * `job`: the output of a previous job with the specified event ID 60 * `job`: The output of a previous job with the specified event ID
59 * `text`: `<data>` is the value of the input, no resolution is needed 61 * `text`: `<data>` is the value of the input, no resolution is needed
60 * `<marker>`: an optional field indicating how this input should be used within the context of the job. 62 * `<marker>`: An optional field indicating how this input should be used within the context of the job
61 * `<relay>`: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string. 63 * `<relay>`: If `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string
62* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified. 64* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified
63* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay. 65* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay
64* `relays`: relays where Service Providers SHOULD publish responses to. 66* `relays`: Relays where Service Providers SHOULD publish responses to
65* `p`: Service Providers the customer is interested in. Other SP MIGHT still choose to process the job. 67* `p`: Service Providers the customer is interested in. Other SPs MIGHT still choose to process the job
66* `exp`: expiration timestamp. Service Providers SHOULD not send results after this timestamp. 68* `exp`: Expiration timestamp. Service Providers SHOULD not send results after this timestamp
67 69
68## Job result 70## Job result
71
69The output of processing the data -- published by the Service Provider. 72The output of processing the data -- published by the Service Provider.
73
70```json 74```json
71{ 75{
72 "pubkey": "<service-provider pubkey>", 76 "pubkey": "<service-provider pubkey>",
73 "content": "<payload>", 77 "content": "<payload>",
74 "kind": 65001, 78 "kind": 65001,
75 "tags" [ 79 "tags": [
76 [ "request", "<job-request>" ], 80 [ "request", "<job-request>" ],
77 [ "e", "<job-request-id>", "<relay-hint>" ], 81 [ "e", "<job-request-id>", "<relay-hint>" ],
78 [ "p", "<Customer's pubkey>" ], 82 [ "p", "<Customer's pubkey>" ],
79 [ "status", "success", "<more-info>" ],
80 [ "amount", "requested-payment-amount", "<optional-bolt11>" ] 83 [ "amount", "requested-payment-amount", "<optional-bolt11>" ]
81 ] 84 ]
82} 85}
@@ -91,53 +94,34 @@ Both customers and service providers can give feedback about a job.
91The result of the job SHOULD be included in the `content` field. 94The result of the job SHOULD be included in the `content` field.
92 95
93* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag. 96* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag.
94* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice. 97* `amount`: as defined in the [Job Result](#job-result) section.
95 98
96# Protocol Flow 99# Protocol Flow
97* Customer publishes a job request (e.g. `kind:65002`). 100* Customer publishes a job request (e.g. `kind:65002`).
98* Service Prpvoders can submit `kind:65000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.). 101* Service Providers can submit `kind:65000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.).
99* Upon completion, the service provider publishes the result of the job with a `kind:65001` job-result event. 102* Upon completion, the service provider publishes the result of the job with a `kind:65001` job-result event.
100* At any point, the user can pay the included `bolt11` or zap any of the events the service provider has sent to the user. 103* At any point, the user can pay the included `bolt11` or zap any of the events the service provider has sent to the user.
101 104
102`kind:65000` and `kind:65001` events MAY include an `amount` tag, this can be interpreted as a suggestion to pay. Service Providers SHOULD use the `payment-required` feedback event to signal that a payment is required and no further actions will be performed until the payment is sent. Customers are can always either pay the included `bolt11` invoice or zap the event requesting the payment and service providers should monitor for both if they choose to include a bolt11 invoice. 105`kind:65000` and `kind:65001` events MAY include an `amount` tag, this can be interpreted as a suggestion to pay. Service Providers SHOULD use the `payment-required` feedback event to signal that a payment is required and no further actions will be performed until the payment is sent. Customers can always either pay the included `bolt11` invoice or zap the event requesting the payment and service providers should monitor for both if they choose to include a bolt11 invoice.
103 106
104## Notes about the protocol flow 107## Notes about the protocol flow
105The flow is deliverately ambiguos, allowing vast flexibility for the interaction between customers and service providers so that service providers can model their behavior based on their own decisions. Some service providers might choose to submit a `payment-required` as the first reaction before sending an `processing` or before delivering `kind:65001` results, some might choose to serve partial results for the job (e.g. as a sample), send a `payment-required`to deliver the rest of the results, and some service providers might choose to assess likelyhood of payment based on an npub's past behavior and thus serve the job results before requesting payment for the best possible UX. 108The flow is deliberately ambiguous, allowing vast flexibility for the interaction between customers and service providers so that service providers can model their behavior based on their own decisions/perceptions of risk.
106
107It's not up to this NIP to define how individual vending machines should choose to run their business.
108 109
109# Payment 110Some service providers might choose to submit a `payment-required` as the first reaction before sending a `processing` or before delivering `kind:65001` results, some might choose to serve partial results for the job (e.g. as a sample), send a `payment-required` to deliver the rest of the results, and some service providers might choose to assess likelihood of payment based on an npub's past behavior and thus serve the job results before requesting payment for the best possible UX.
110Customers SHOULD pay service providers whose job results they accept by either zapping the Service Provider and tagging the `kind:65001` job result or, if included, paying the bolt11 invoice.
111 111
112Additionally, if a service provider requests full or partial prepayment via a `kind:65000` job-feedback event, the customer SHOULD zap that event to pay the service provider. 112It's not up to this NIP to define how individual vending machines should choose to run their business.
113 113
114# Cancellation 114# Cancellation
115A job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event. 115A job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event.
116 116
117# Job chaining 117# Job chaining
118A Customer MAY request multiple jobs to be processed in a chained form, so that the output of a job can be the input of the next job. (e.g. summarization of a podcast's transcription). This is done by specifying as `input` an eventID of a different job with the `job` marker. 118A Customer MAY request multiple jobs to be processed as a chain, where the output of a job can be the input of another job. (e.g. podcast transcription -> summarization of the transcription). This is done by specifying as input an event id of a different job with the `job` type.
119 119
120Service Providers MAY begin processing a subsequent job the moment they see the prior job's result, but they will likely wait for a zap to be published first. This introduces a risk that Service Provider of job #1 might delay publishing the zap event in order to have an advantage. This risk is up to Service Providers to mitigate or to decide whether the service provider of job #1 tends to have good-enough results so as to not wait for a explicit zap to assume the job was accepted. 120Service Providers MAY begin processing a subsequent job the moment they see the prior job's result, but they will likely wait for a zap to be published first. This introduces a risk that Service Provider of job #1 might delay publishing the zap event in order to have an advantage. This risk is up to Service Providers to mitigate or to decide whether the service provider of job #1 tends to have good-enough results so as to not wait for an explicit zap to assume the job was accepted.
121 121
122Consult [Appendix 1: Example](#appendix-1-examples)'s [Summarization of a podcast](#summarization-of-a-podcast) 122This gives a higher level of flexibility to service providers (which sophisticated service providers would take anyway).
123
124# Job Feedback
125The parties to a job request can use `kind:65000` to provide feedback about the job, using a `status` tag to indicate the type of feedback.
126 123
127Any job feedback event MIGHT include an `amount` tag, indicating the amount of millisats the party is requesting to be paid. An optional third value can be a bolt11 invoice. 124Consult [Appendix 1: Example](#appendix-1-examples)'s [Summarization of a podcast](#summarization-of-a-podcast)
128
129| status | description |
130|--------|-------------|
131| `payment-required` | Service Provider requires payment before continuing. |
132| `processing` | Service Provider is processing the job. |
133| `error` | Service Provider was unable to process the job. |
134| `success` | Service Provider successfully processed the job. |
135| `failure` | Service Provider failed to process the job. |
136| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
137
138Any job feedback event MIGHT include an `amount` tag, as described in the [Job Result](#job-result) section.
139
140Any job feedback event MIGHT include results in the `.content` field, as described in the [Job Result](#job-result) section.
141 125
142### E.g. Payment required (with sample content) 126### E.g. Payment required (with sample content)
143```json 127```json
@@ -153,20 +137,15 @@ Any job feedback event MIGHT include results in the `.content` field, as describ
153} 137}
154``` 138```
155 139
156## Job feedback
157A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
158The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result.
159
160## Not addressed in this NIP 140## Not addressed in this NIP
161 141
162### Reputation system 142### Reputation system
163Service providers are at obvious risk of having their results not compensated. Mitigation of this risk is up to service providers to figure out (i.e. building reputation systems, requiring npub "balances", etc, etc). 143Service providers are at an obvious risk of having their results not compensated. Mitigation of this risk is up to service providers to figure out (i.e., building reputation systems, requiring npub "balances", etc.). It's out of scope (and undesirable) to have this NIP address this issue; the market should.
164
165It's out of scope (and undesirable) to have this NIP address this issue; the market should.
166 144
167### Encrypted job requests 145### Encrypted job requests
168Not to be included in the first draft of this NIP, but encrypted job requests should be added. A few ways: 146Not to be included in the first draft of this NIP, but encrypted job requests should be added. A few ways:
169* publish job requests with some useful metadata of the job "e.g. length of audio to be transcribed", service providers offer to do the job, the customer replies with a NIP-04-like encrypted job requested encrypted with the service provider's pubkey. 147 * publish job requests with some useful metadata of the job "e.g., length of audio to be transcribed", service providers offer to do the job, the customer replies with a NIP-04-like encrypted job requested encrypted with the service provider's pubkey.
148
170 149
171# Appendix 1: Examples 150# Appendix 1: Examples
172 151
@@ -189,7 +168,7 @@ Not to be included in the first draft of this NIP, but encrypted job requests sh
189} 168}
190``` 169```
191 170
192### `kind:65001`: Job Feedback: request for (partial) payment 171### `kind:65000`: Job Feedback: request for (partial) payment
193* The SP is signaling here that it won't start processing until 100 sats are paid 172* The SP is signaling here that it won't start processing until 100 sats are paid
194```json 173```json
195{ 174{
@@ -228,7 +207,7 @@ User publishes event #1 and #2 together.
228{ 207{
229 "id": "12345", 208 "id": "12345",
230 "pubkey": "abcdef", 209 "pubkey": "abcdef",
231 "kinds" 65002, 210 "kind": 65002,
232 "content": "", 211 "content": "",
233 "tags": [ 212 "tags": [
234 [ "i", "https://bitcoin.review/episode1.mp3", "url" ], 213 [ "i", "https://bitcoin.review/episode1.mp3", "url" ],
@@ -244,7 +223,7 @@ User publishes event #1 and #2 together.
244{ 223{
245 "id": "12346", 224 "id": "12346",
246 "pubkey": "abcdef", 225 "pubkey": "abcdef",
247 "kinds": 65003, 226 "kind": 65003,
248 "content": "", 227 "content": "",
249 "tags": [ 228 "tags": [
250 [ "i", "12345", "job" ], // input is the output of job with id 12345 229 [ "i", "12345", "job" ], // input is the output of job with id 12345
@@ -262,16 +241,17 @@ User publishes event #1 and #2 together.
262 "id": "12346", 241 "id": "12346",
263 "pubkey": "abcdef", 242 "pubkey": "abcdef",
264 "content": "", 243 "content": "",
265 "kinds": 65004, 244 "kind": 65004,
266 "tags": [ 245 "tags": [
267 [ "i", "<hexid>", "event", "wss://relay.nostr.com" ] 246 [ "i", "<hexid>", "event", "wss://relay.nostr.com" ]
247 [ "output", "text/plain" ],
268 [ "params", "lang", "es_AR" ], 248 [ "params", "lang", "es_AR" ],
269 [ "bid", "5000" ] 249 [ "bid", "5000" ]
270 ] 250 ]
271} 251}
272``` 252```
273 253
274### `kind:65001`: Job respomse 254### `kind:65001`: Job result
275```json 255```json
276{ 256{
277 "kind": 65001, 257 "kind": 65001,
@@ -290,7 +270,7 @@ User publishes event #1 and #2 together.
290```json 270```json
291{ 271{
292 "id": "123", 272 "id": "123",
293 "kind" 65002, 273 "kind": 65002,
294 "tags": [ 274 "tags": [
295 [ "i", "https://example.com/episode1.mp3", "url" ], 275 [ "i", "https://example.com/episode1.mp3", "url" ],
296 [ "bid", "100000" ] 276 [ "bid", "100000" ]
@@ -302,7 +282,7 @@ User publishes event #1 and #2 together.
302```json 282```json
303{ 283{
304 "id": "124", 284 "id": "124",
305 "kind" 65002, 285 "kind": 65002,
306 "tags": [ 286 "tags": [
307 [ "i", "https://example.com/episode2.mp3", "url" ], 287 [ "i", "https://example.com/episode2.mp3", "url" ],
308 [ "bid", "100000" ] 288 [ "bid", "100000" ]
@@ -310,7 +290,7 @@ User publishes event #1 and #2 together.
310} 290}
311``` 291```
312 292
313### `kind:65003`: Job request #3 (summarize both podcasts into one paragraph) 293### `kind:65003`: Job request #3 (summarize the two job's outputs into one paragraph)
314```json 294```json
315{ 295{
316 "id": "125", 296 "id": "125",
@@ -323,29 +303,30 @@ User publishes event #1 and #2 together.
323 ] 303 ]
324} 304}
325``` 305```
326## AI-image of embedded input
327 306
328### `kind:65005`: Job request 307### `kind:65005`: Job request #4 (generate image based on the summary)
329```json 308```json
330{ 309{
310 "id": "126",
331 "kind": 65004, 311 "kind": 65004,
332 "tags": [ 312 "tags": [
333 [ "i", "Millions of vending machines, interconnected with tubes with eah other", "text" ], 313 [ "i", "125", "job" ],
334 [ "param", "prompt", "photorealistic" ], 314 [ "param", "prompt", "photorealistic" ],
315 [ "param", "size", "4000x4000" ],
335 [ "bid", "500000" ] 316 [ "bid", "500000" ]
336 ] 317 ]
337} 318}
338``` 319``
339 320
340### `kind:65006`: Job request #4 (generate image based on the summary) 321## AI-image of embedded input
322
323### `kind:65005`: Job request
341```json 324```json
342{ 325{
343 "id": "126",
344 "kind": 65004, 326 "kind": 65004,
345 "tags": [ 327 "tags": [
346 [ "i", "125", "job" ], 328 [ "i", "Millions of vending machines, interconnected with tubes with eah other", "text" ],
347 [ "param", "prompt", "photorealistic" ], 329 [ "param", "prompt", "photorealistic" ],
348 [ "param", "size", "4000x4000" ],
349 [ "bid", "500000" ] 330 [ "bid", "500000" ]
350 ] 331 ]
351} 332}
@@ -353,45 +334,58 @@ User publishes event #1 and #2 together.
353 334
354# Appendix 2: Job types 335# Appendix 2: Job types
355 336
356This is a list of all the supported job requests 337This is a list of all the supported job requests.
357. 338
358## speech-to-text: `kind:65002` 339## speech-to-text: `kind:65002`
340
359### params 341### params
360| param | req? | description 342
361|--------------------------------|------|-------- 343| param | req? | description |
362| `range` | opt | timestamp range (in seconds) of desired text to be transcribed 344|------------|------|-----------------------------------------------------------|
363| `alignment` | opt | word, segment, raw: word-level, segment-level or raw outputs 345| `range` | opt | timestamp range (in seconds) of desired text to be transcribed |
346| `alignment`| opt | word, segment, raw: word-level, segment-level, or raw outputs |
364 347
365## summarization: `kind:65003` 348## summarization: `kind:65003`
366| param | req? | description 349
367|--------------------------------|------|-------- 350| param | req? | description |
368| `length` | opt | desired length 351|-----------|------|---------------|
352| `length` | opt | desired length |
369 353
370## translation: `kind:65004` 354## translation: `kind:65004`
371| param | req? | description 355
372|--------------------------------|------|-------- 356| param | req? | description |
373| `lang` | req | desired language in BCP 47 format. 357|-----------|------|--------------------------------------------|
358| `lang` | req | desired language in BCP 47 format. |
374 359
375## image generation: `kind:65005` 360## image generation: `kind:65005`
376| param | req? | description
377|--------------------------------|------|--------
378| `prompt` | opt | extra prompt to be used for the image generation
379| `size` | opt | desired size of the image
380 361
381# Notes 362| param | req? | description |
363|-----------|------|-------------------------------------------------------|
364| `prompt` | opt | extra prompt to be used for the image generation |
365| `size` | opt | desired size of the image |
366
382 367
383* Job acceptance ambiguity, particularly for job-chaining circumstances is deliberate: service providers could wait until explicit job result acceptance / payment to start working on the next item on the chain, or they could start working as soon as they see a result of the previous job computed. 368# Appendix 3: Job feedback status
369
370| status | description |
371|--------|-------------|
372| `payment-required` | Service Provider requires payment before continuing. |
373| `processing` | Service Provider is processing the job. |
374| `error` | Service Provider was unable to process the job. |
375| `success` | Service Provider successfully processed the job. |
376| `failure` | Service Provider failed to process the job. |
377| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
384 378
385That's up to each service provider to choose how to behave depending on the circumstances. This gives a higher level of flexibility to service providers (which sophisticated service providers would take anyway). 379Any job feedback event MIGHT include results in the `.content` field, as described in the [Job Result](#job-result) section. This is useful for service providers to provide a sample of the results that have been processed so far.
386 380
387# Appendix 3: Service provider discoverability 381# Appendix 4: Service provider discoverability
388 382
389Service Providers can use NIP-89 announcements to advertise their support for job kinds: 383Service Providers can use NIP-89 announcements to advertise their support for job kinds:
390 384
391```json 385```json
392{ 386{
393 "kind": 31990, 387 "kind": 31990,
394 "pubkey": <pubkey>, 388 "pubkey": "<pubkey>",
395 "tags": [ 389 "tags": [
396 [ "k", 65002 ], // e.g. speech-to-text 390 [ "k", 65002 ], // e.g. speech-to-text
397 [ "t", "bitcoin" ] // e.g. optionally advertises it specializes in bitcoin audio transcription that won't confuse "Drivechains" with "Ridechains" 391 [ "t", "bitcoin" ] // e.g. optionally advertises it specializes in bitcoin audio transcription that won't confuse "Drivechains" with "Ridechains"