From 67e950a2009e81df1b8c91b0a2ade0596e83f168 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Mon, 3 Jul 2023 14:21:13 +0200
Subject: [PATCH 001/192] wip
---
vending-machine.md | 163 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 163 insertions(+)
create mode 100644 vending-machine.md
diff --git a/vending-machine.md b/vending-machine.md
new file mode 100644
index 00000000..273aa28f
--- /dev/null
+++ b/vending-machine.md
@@ -0,0 +1,163 @@
+# NIP-XX: Data Vending Machine
+Money in, data out.
+
+## Rationale
+Nostr can act as a marketplace for data processing, where users request jobs to be processed in certain ways (e.g. "speech-to-text", "summarization"), but where they don't necessarily care about "who" processes the data.
+
+This NIP is not to be confused with a 1:1 marketplace; but rather, a flow where user announces a desired output, willigness to pay, and service providers compete to fulfill the job requirement in the best way possible.
+
+### Actors
+There are two actors to the workflow described in this NIP:
+* Customers (npubs who request a job)
+* Service providers (npubs who fulfill jobs)
+
+## User flow
+* User publishes a job request
+`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
+
+* Service providers listen for the type of jobs they can perform
+`{"kinds":[68001], "#j": ["speech-to-text", "image-generation", ... ]}`
+
+* When a job comes in, the service providers who opt to attempt to fulfill the request begin processing it
+* Upon completion, the service provider publishes the result of the job with a `job-result` event.
+* Upon acceptance, the user zaps the service provider, tagging the job request
+
+## Kinds
+
+This NIP introduces two new kinds:
+
+* `kind:68001`: Job request -- a request to have a job be processed
+* `kind:68002`: Job result -- a proposal of the resulting job
+
+### Job request
+A request to have data processed -- published by a user
+
+```json
+{
+ "kind": 68001,
+ "content": "",
+ "tags": [
+ // The type data processing the user wants to be performed
+ // on the
+ [ "j", "", "" ],
+ [ "input", "", "", "" ],
+ [ "relays", "wss://..."],
+
+ // stringified sat amount that the user is offering to pay
+ // for this request
+ // should this include an optional max price or is it too
+ // ambiguous?
+ [ "bid", "", [""] ],
+
+ // max timestamp at which the job is no longer to be processed
+ [ "expiration", "" ]
+
+ // p tags
+ [ "p", "service-provider-1" ],
+ [ "p", "service-provider-2" ],
+
+ // NIP-33 d-tag
+ [ "d", ""]
+ ]
+}
+```
+
+#### `content` field
+An optional, human-readable description of what this job is for.
+
+#### `j` tag
+Specifies the job to be executed. A job request MUST have exactly one `j` tag.
+
+A `j` tag MIGHT name a specific model to be used for the computed with.
+
+#### `input` tag
+Specified the input that the job should be executed with.
+
+* ``: The argument for the input
+* ``: The way this argument should be interpreted
+ * Possible values:
+ * `url`: a URL to be fetched
+ * `event`: a different event ID
+ * `job`: the output of a previous job
+* ``:
+
+#### `relays` tag
+A list of relays the service provider should publish its job result to.
+
+#### `p` tags (optional)
+A user might want to explicitly request this job to be processed by specific service provider(s). Other service providers might still choose to compete for this job.
+
+#### `expiration` (optional)
+A user might specify that they will not be interested in results past a certain time (e.g. a time-sensitive job whos value is no longer relevant after some time, like a live transcription service)
+
+### Job result
+The output of processing the data -- published by the
+```json
+{
+ "pubkey": "service-provider",
+
+ // result
+ "content": "",
+ "tags" [
+ // stringified JSON request event
+ [ "request", "<2xxx1-event>" ],
+ [ "e", ],
+ [ "p", "" ],
+ [ "status", "success", ""],
+ [ "payment", "requested-payment-amount" ]
+ ]
+}
+```
+
+### `status` tag
+The service provider might want to return an error to the user in case the job could not be processed correctly
+
+### `payment`
+
+## Job types
+
+This NIP defines some job types, clients SHOULD specify these types for maximum compatibility with service providers. Other job types might be added to this NIP.
+
+### `speech-to-text`
+#### params
+| param | req? | description
+|--------------------------------|------|--------
+| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
+
+### `summarization`
+| param | req? | description
+|--------------------------------|------|--------
+| `length` | opt | desired length
+
+### `translation` -- Translate text to a specific language
+#### params
+| param | req? | description
+|--------------------------------|------|--------
+| `language` | req | desired language in BCP 47 format.
+
+## Job chaining
+A customer CAN request multiple jobs to be chained, 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.
+
+Service providers might opt to start processing a subsequent job the moment they see the prior job's result, or they might choose to wait for a zap to have been published. This introduces the 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.
+
+## Job feedback
+> **Warning**
+> Is this hijacking/modifying the meaning of NIP-25 reactions too much?
+
+A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
+The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result, either
+in the form of
+
+
+## Explicitly not addressed in this NIP
+
+### Reputation system
+Service 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).
+
+It's out of scope (and undesirable) to have this NIP address this issue; the market should.
+
+## Notes
+
+### Multitple job acceptance
+* Nothing prevents a user from accepting multiple job results.
+
From 71803c21a6bdd2413244a47752c129e3c64eaec6 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Mon, 3 Jul 2023 14:33:17 +0200
Subject: [PATCH 002/192] Add examples
---
vending-machine.md | 84 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 82 insertions(+), 2 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 273aa28f..a94cd332 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -77,8 +77,8 @@ Specified the input that the job should be executed with.
* ``: The way this argument should be interpreted
* Possible values:
* `url`: a URL to be fetched
- * `event`: a different event ID
- * `job`: the output of a previous job
+ * `event`: a nostr event ID
+ * `job`: the output of a previous job with the specified event ID
* ``:
#### `relays` tag
@@ -161,3 +161,83 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
### Multitple job acceptance
* Nothing prevents a user from accepting multiple job results.
+# Appendix 1: Examples
+
+## Customer wants to get a transcript of a podcast from second 900 to 930.
+
+### `kind:68001`: Job Request
+```json
+{
+ "id": "12345",
+ "pubkey": "abcdef",
+ "content": "I need a transcript of Bitcoin.review",
+ "tags": [
+ [ "j", "speech-to-text" ],
+ [ "params", "range", "900", "930" ],
+ [ "input", "https://bitcoin.review/episode1.mp3", "url" ],
+ [ "bid", "5000", "9000" ]
+ ]
+}
+```
+
+### `kind:1021`: Job fulfillment
+```json
+{
+ "content": "Person 1: blah blah blah",
+ "tags": [
+ ["e", "12345"],
+ ["p", "abcdef"],
+ ["status", "success"]
+ ]
+}
+```
+
+## Customer wants to get a summarization of a podcast
+
+User publishes two job requests at the same time in the order they should be executed.
+
+### `kind:68001`: Job Request #1
+```json
+{
+ "id": "12345",
+ "pubkey": "abcdef",
+ "content": "I need a transcript of Bitcoin.review from second 900 to 930",
+ "tags": [
+ [ "j", "speech-to-text" ],
+ [ "params", "range", "900", "930" ],
+ [ "input", "https://bitcoin.review/episode1.mp3", "url" ],
+ [ "bid", "5000", "9000" ]
+ ]
+}
+```
+
+### `kind:68001`: Job Request #2
+```json
+{
+ "id": "12346",
+ "pubkey": "abcdef",
+ "content": "I need a summarization",
+ "tags": [
+ [ "j", "summarization" ],
+ [ "params", "length", "3 paragraphs" ],
+ [ "input", "12346", "job" ],
+ [ "bid", "300", "900" ]
+ ]
+}
+```
+
+## Customer wants a translation of a note
+### `kind:68001`: Job Request #1
+```json
+{
+ "id": "12346",
+ "pubkey": "abcdef",
+ "content": "",
+ "tags": [
+ [ "j", "translation" ],
+ [ "input", "", "event" ]
+ [ "params", "language", "es_AR" ],
+ [ "bid", "100", "500" ]
+ ]
+}
+```
\ No newline at end of file
From b5a7b67d78ad2b8ea52d81704be6b71a9cc80dac Mon Sep 17 00:00:00 2001
From: Semisol <45574030+Semisol@users.noreply.github.com>
Date: Mon, 3 Jul 2023 18:02:15 +0300
Subject: [PATCH 003/192] Clarify JSON serialization for the `id` field
---
01.md | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/01.md b/01.md
index 2ff81ebf..9258d2f7 100644
--- a/01.md
+++ b/01.md
@@ -30,7 +30,7 @@ The only object type that exists is the `event`, which has the following format
}
```
-To obtain the `event.id`, we `sha256` the serialized event. The serialization is done over the UTF-8 JSON-serialized string (with no white space or line breaks) of the following structure:
+To obtain the `event.id`, we `sha256` the serialized event. The serialization is done over the UTF-8 JSON-serialized string (which is described below) of the following structure:
```json
[
@@ -43,6 +43,14 @@ To obtain the `event.id`, we `sha256` the serialized event. The serialization is
]
```
+To prevent implementation differences from creating a different event ID for the same event, the following rules MUST be followed while serializing:
+- No whitespace, line breaks or other unnecessary formatting should be included in the output JSON.
+- No characters except the following should be escaped, and instead should be included verbatim:
+ - The line break, `0x0A`, as `\n`
+ - A double quote, `0x22`, as `\"`
+ - A backspace, `0x5C`, as `\\`
+- UTF-8 should be used for encoding.
+
## Communication between clients and relays
Relays expose a websocket endpoint to which clients can connect.
From 3f8658ecc11e593f85a6a8d7de109d0b8f3254df Mon Sep 17 00:00:00 2001
From: Semisol <45574030+Semisol@users.noreply.github.com>
Date: Tue, 4 Jul 2023 13:49:52 +0300
Subject: [PATCH 004/192] Fix typo
---
01.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/01.md b/01.md
index 9258d2f7..70aae443 100644
--- a/01.md
+++ b/01.md
@@ -48,7 +48,7 @@ To prevent implementation differences from creating a different event ID for the
- No characters except the following should be escaped, and instead should be included verbatim:
- The line break, `0x0A`, as `\n`
- A double quote, `0x22`, as `\"`
- - A backspace, `0x5C`, as `\\`
+ - A backslash, `0x5C`, as `\\`
- UTF-8 should be used for encoding.
## Communication between clients and relays
From 21d71791c89f41fb93f84b69d6db253bb7b403c4 Mon Sep 17 00:00:00 2001
From: Semisol <45574030+Semisol@users.noreply.github.com>
Date: Tue, 4 Jul 2023 13:55:15 +0300
Subject: [PATCH 005/192] Add carriage returns and tab characters since those
may be in some events
---
01.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/01.md b/01.md
index 70aae443..f5673b38 100644
--- a/01.md
+++ b/01.md
@@ -49,6 +49,8 @@ To prevent implementation differences from creating a different event ID for the
- The line break, `0x0A`, as `\n`
- A double quote, `0x22`, as `\"`
- A backslash, `0x5C`, as `\\`
+ - A carriage return, `0x0D`, as `\r`
+ - A tab character, `0x09`, as `\t`
- UTF-8 should be used for encoding.
## Communication between clients and relays
From ce552554a08bb5b9878621abfdde3207d54cae62 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Wed, 5 Jul 2023 11:14:50 +0200
Subject: [PATCH 006/192] wip, part 2
---
vending-machine.md | 208 ++++++++++++++++++++++++++++++---------------
1 file changed, 139 insertions(+), 69 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index a94cd332..eb26688d 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -1,8 +1,15 @@
-# NIP-XX: Data Vending Machine
-Money in, data out.
+NIP-XX
+======
+
+Data Vending Machine
+--------------------
+
+`draft` `optional` `author:pablof7z`
+
+This NIP defines the interaction between customers and Service Providers to perform on-demand computation.
## Rationale
-Nostr can act as a marketplace for data processing, where users request jobs to be processed in certain ways (e.g. "speech-to-text", "summarization"), but where they don't necessarily care about "who" processes the data.
+Nostr 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.
This NIP is not to be confused with a 1:1 marketplace; but rather, a flow where user announces a desired output, willigness to pay, and service providers compete to fulfill the job requirement in the best way possible.
@@ -11,26 +18,9 @@ There are two actors to the workflow described in this NIP:
* Customers (npubs who request a job)
* Service providers (npubs who fulfill jobs)
-## User flow
-* User publishes a job request
-`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
-
-* Service providers listen for the type of jobs they can perform
-`{"kinds":[68001], "#j": ["speech-to-text", "image-generation", ... ]}`
-
-* When a job comes in, the service providers who opt to attempt to fulfill the request begin processing it
-* Upon completion, the service provider publishes the result of the job with a `job-result` event.
-* Upon acceptance, the user zaps the service provider, tagging the job request
-
-## Kinds
-
-This NIP introduces two new kinds:
-
-* `kind:68001`: Job request -- a request to have a job be processed
-* `kind:68002`: Job result -- a proposal of the resulting job
-
-### Job request
-A request to have data processed -- published by a user
+# Event Kinds
+## Job request
+A request to have data processed -- published by a customer
```json
{
@@ -38,40 +28,35 @@ A request to have data processed -- published by a user
"content": "",
"tags": [
// The type data processing the user wants to be performed
- // on the
- [ "j", "", "" ],
- [ "input", "", "", "" ],
+ [ "j", "", "" ],
+
+ // input(s) for the job request
+ [ "i", "", "", "" ],
+
+ // relays where the job result should be published
[ "relays", "wss://..."],
- // stringified sat amount that the user is offering to pay
- // for this request
- // should this include an optional max price or is it too
- // ambiguous?
- [ "bid", "", [""] ],
-
- // max timestamp at which the job is no longer to be processed
- [ "expiration", "" ]
-
- // p tags
+ // millisats amount that the user is offering to pay
+ [ "bid", "", "" ],
+ [ "exp", "" ],
[ "p", "service-provider-1" ],
[ "p", "service-provider-2" ],
-
- // NIP-33 d-tag
- [ "d", ""]
]
}
```
-#### `content` field
+### `content` field
An optional, human-readable description of what this job is for.
-#### `j` tag
+### `j` tag
Specifies the job to be executed. A job request MUST have exactly one `j` tag.
-A `j` tag MIGHT name a specific model to be used for the computed with.
+A `j` tag MIGHT name a specific model to be used for the computed with as the second value.
-#### `input` tag
-Specified the input that the job should be executed with.
+### `i` (input) tag
+Specifies the input that the job should be executed with. The input is relay-indexable so that clients interested in the exact same job can find it it's result if it's already fulfilled.
+
+A job request CAN have zero or more inputs.
* ``: The argument for the input
* ``: The way this argument should be interpreted
@@ -81,17 +66,20 @@ Specified the input that the job should be executed with.
* `job`: the output of a previous job with the specified event ID
* ``:
-#### `relays` tag
+### `bid` tag
+The user MIGHT specify an amount of millisats they are willing to pay for the job to be processed. The user MIGHT also specify a maximum amount of millisats they are willing to pay.
+
+### `relays` tag
A list of relays the service provider should publish its job result to.
-#### `p` tags (optional)
-A user might want to explicitly request this job to be processed by specific service provider(s). Other service providers might still choose to compete for this job.
+### `p` tags
+A user MIGHT want to explicitly request this job to be processed by specific service provider(s). Other service providers might still choose to compete for this job.
-#### `expiration` (optional)
+### `exp`
A user might specify that they will not be interested in results past a certain time (e.g. a time-sensitive job whos value is no longer relevant after some time, like a live transcription service)
-### Job result
-The output of processing the data -- published by the
+## Job result
+The output of processing the data -- published by the service provider.
```json
{
"pubkey": "service-provider",
@@ -100,19 +88,22 @@ The output of processing the data -- published by the
"content": "",
"tags" [
// stringified JSON request event
- [ "request", "<2xxx1-event>" ],
- [ "e", ],
+ [ "request", "<68001-event>" ],
+ [ "e", ],
[ "p", "" ],
[ "status", "success", ""],
- [ "payment", "requested-payment-amount" ]
+ [ "amount", "requested-payment-amount" ]
]
}
```
-### `status` tag
+The result of the job should be in the `content`. If the output is not text, the `content` field should be empty and an `output` tag should be used instead as described below.
+
+#### `status` tag
The service provider might want to return an error to the user in case the job could not be processed correctly
-### `payment`
+#### `amount`
+The amount of millisats the service provider is requesting to be paid. This amount MIGHT be different than the amount specified by the user in the `bid` tag. The amount SHOULD be less than the maximum amount specified by the user in the `bid` tag.
## Job types
@@ -133,21 +124,52 @@ This NIP defines some job types, clients SHOULD specify these types for maximum
#### params
| param | req? | description
|--------------------------------|------|--------
-| `language` | req | desired language in BCP 47 format.
+| `language` | req | requested language in BCP 47 format.
-## Job chaining
+# Protocol Flow
+* User publishes a job request
+`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
+
+* Service providers listen for the type of jobs they can perform
+`{"kinds":[68001], "#j": ["speech-to-text", "image-generation", ... ]}`
+
+* When a job comes in, the service providers who opt to attempt to fulfill the request begin processing it, or they can react to it with feedback for the user (e.g. _payment required_, _unprocessable entity_, etc.)
+* Upon completion, the service provider publishes the result of the job with a `job-result` event.
+* Upon acceptance, the user zaps the service provider, tagging the job result event.
+
+# Payment
+Customers SHOULD pay service providers whose job results they accept. Users should zap the service provider, tagging the `kind:68002` job result.
+
+
+# Job chaining
A customer CAN request multiple jobs to be chained, 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.
Service providers might opt to start processing a subsequent job the moment they see the prior job's result, or they might choose to wait for a zap to have been published. This introduces the 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.
-## Job feedback
+# Reactions
> **Warning**
> Is this hijacking/modifying the meaning of NIP-25 reactions too much?
-A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
-The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result, either
-in the form of
+## Job request reactions
+Service Providers might opt to give feedback about a job.
+### E.g. Payment required
+```json
+{
+ "kind": 7,
+ "content": "Please pay 7 sats for job xxxx",
+ "tags": [
+ [ "e", ],
+ [ "status", "payment-required" ],
+ [ "amount", "7000" ],
+ ]
+}
+```
+
+## Job feedback
+
+A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
+The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result.
## Explicitly not addressed in this NIP
@@ -163,7 +185,7 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
# Appendix 1: Examples
-## Customer wants to get a transcript of a podcast from second 900 to 930.
+## Transcript of a podcast from second `900` to `930`.
### `kind:68001`: Job Request
```json
@@ -174,7 +196,7 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
"tags": [
[ "j", "speech-to-text" ],
[ "params", "range", "900", "930" ],
- [ "input", "https://bitcoin.review/episode1.mp3", "url" ],
+ [ "i", "https://bitcoin.review/episode1.mp3", "url" ],
[ "bid", "5000", "9000" ]
]
}
@@ -192,7 +214,7 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
}
```
-## Customer wants to get a summarization of a podcast
+## Summarization of a podcast
User publishes two job requests at the same time in the order they should be executed.
@@ -205,7 +227,7 @@ User publishes two job requests at the same time in the order they should be exe
"tags": [
[ "j", "speech-to-text" ],
[ "params", "range", "900", "930" ],
- [ "input", "https://bitcoin.review/episode1.mp3", "url" ],
+ [ "i", "https://bitcoin.review/episode1.mp3", "url" ],
[ "bid", "5000", "9000" ]
]
}
@@ -220,13 +242,13 @@ User publishes two job requests at the same time in the order they should be exe
"tags": [
[ "j", "summarization" ],
[ "params", "length", "3 paragraphs" ],
- [ "input", "12346", "job" ],
+ [ "i", "12346", "job" ],
[ "bid", "300", "900" ]
]
}
```
-## Customer wants a translation of a note
+## Translation of a note
### `kind:68001`: Job Request #1
```json
{
@@ -235,9 +257,57 @@ User publishes two job requests at the same time in the order they should be exe
"content": "",
"tags": [
[ "j", "translation" ],
- [ "input", "", "event" ]
+ [ "i", "", "event" ]
[ "params", "language", "es_AR" ],
[ "bid", "100", "500" ]
]
}
-```
\ No newline at end of file
+```
+
+## AI-image of the summarization of 2 podcasts
+
+### `kind:68001`: Job request #1 (transcribe podcast #1)
+```json
+{
+ "id": "123",
+ "tags": [
+ [ "j", "speech-to-text" ],
+ [ "i", "https://example.com/episode1.mp3", "url" ],
+ [ "bid", "100", "500" ]
+ ]
+}
+```
+
+### `kind:68001`: Job request #2 (transcribe podcast #2)
+```json
+{
+ "id": "124",
+ "tags": [
+ [ "j", "speech-to-text" ],
+ [ "i", "https://example.com/episode2.mp3", "url" ],
+ [ "bid", "100", "500" ]
+ ]
+}
+```
+
+### `kind:68001`: Job request #3 (summarize both podcasts into one podcast)
+```json
+{
+ "id": "125",
+ "tags": [
+ [ "j", "summarize" ],
+ [ "param", "length", "1 paragraph" ],
+ [ "i", "123", "job" ],
+ [ "i", "124", "job" ],
+ [ "bid", "100", "500" ]
+ ]
+}
+```
+
+# Notes
+
+* Should there be a possibility of getting the job result delivered encrypted? I don't like it but maybe it should be supported.
+
+* Ambiguity on job acceptance, particularly for job-chaining circumstances is deliberately ambiguous: 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.
+
+That'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).
From 667c700c1cab5106655df2de528e960b4875db0d Mon Sep 17 00:00:00 2001
From: gsovereignty
Date: Sat, 8 Jul 2023 18:51:30 +0800
Subject: [PATCH 007/192] Problem: some of the language is inconsistent
---
vending-machine.md | 53 +++++++++++++++++++++++-----------------------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index eb26688d..2f9c0649 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -27,7 +27,7 @@ A request to have data processed -- published by a customer
"kind": 68001,
"content": "",
"tags": [
- // The type data processing the user wants to be performed
+ // The type of data processing the user wants to be performed
[ "j", "", "" ],
// input(s) for the job request
@@ -49,12 +49,12 @@ A request to have data processed -- published by a customer
An optional, human-readable description of what this job is for.
### `j` tag
-Specifies the job to be executed. A job request MUST have exactly one `j` tag.
+Specifies the job to be executed. A job request MUST have exactly one (1) `j` tag.
-A `j` tag MIGHT name a specific model to be used for the computed with as the second value.
+A `j` tag MAY include a second value specifying the name of a model to be used when computing the result.
### `i` (input) tag
-Specifies the input that the job should be executed with. The input is relay-indexable so that clients interested in the exact same job can find it it's result if it's already fulfilled.
+Specifies the input data that the job is to be executed against. The input is relay-indexable so that clients interested in the exact same job can find the input data and the result result (if it's already fulfilled).
A job request CAN have zero or more inputs.
@@ -64,50 +64,51 @@ A job request CAN have zero or more inputs.
* `url`: a URL to be fetched
* `event`: a nostr event ID
* `job`: the output of a previous job with the specified event ID
-* ``:
+* ``: an optional field indicating where the data can be found if it is a subset of the provided values, for example the name of the key(s) in a key/value set, or the start and end positions of the data if it's a bytestream.
### `bid` tag
-The user MIGHT specify an amount of millisats they are willing to pay for the job to be processed. The user MIGHT also specify a maximum amount of millisats they are willing to pay.
+The Customer MAY specify a maximum amount (in millisats) they are willing to pay for the job to be processed.
### `relays` tag
-A list of relays the service provider should publish its job result to.
+The Service Provider SHOULD publish job results to the relays specified in this this tag.
### `p` tags
-A user MIGHT want to explicitly request this job to be processed by specific service provider(s). Other service providers might still choose to compete for this job.
+If a Customer has a preference for specific Service Provider(s) to process this job, they SHOULD indicate this by including the Service Provider(s) pubkey in a `p` tag. This is NOT intended to exclude other Service Providers and they MAY still choose to compete for jobs that have not tagged them.
### `exp`
-A user might specify that they will not be interested in results past a certain time (e.g. a time-sensitive job whos value is no longer relevant after some time, like a live transcription service)
+A Customer MAY indicate that they will not pay for results produced after a specific Block height or Unix Timestamp. This is intended for time-sensitive jobs where the result is not relevant unless produced within a certain timeframe, e.g. a live transcription service.
## Job result
-The output of processing the data -- published by the service provider.
+The output of processing the data -- published by the Service Provider.
```json
{
- "pubkey": "service-provider",
+ "pubkey": "service-provider pubkey in hex",
// result
- "content": "",
+ "content": "string: ",
+ "kind": 68002,
"tags" [
// stringified JSON request event
- [ "request", "<68001-event>" ],
- [ "e", ],
- [ "p", "" ],
- [ "status", "success", ""],
+ [ "request", "" ],
+ [ "e", "" ],
+ [ "p", "" ],
+ [ "status", "success", "" ],
[ "amount", "requested-payment-amount" ]
]
}
```
-The result of the job should be in the `content`. If the output is not text, the `content` field should be empty and an `output` tag should be used instead as described below.
+The result of the job SHOULD be included in the `content` field. If the output is not text, the `content` field SHOULD be empty and an `output` tag should be used instead as described below.
#### `status` tag
-The service provider might want to return an error to the user in case the job could not be processed correctly
+The Service Provider MAY indicate errors during processing by including them in the `status` tag, these errors are intended to be consumed by the Customer.
#### `amount`
-The amount of millisats the service provider is requesting to be paid. This amount MIGHT be different than the amount specified by the user in the `bid` tag. The amount SHOULD be less than the maximum amount specified by the user in the `bid` tag.
+The amount (in millisats) that the Service Provider is requesting to be paid. This amount MAY differ to the amount specified by the Customer in the `bid` tag. The amount SHOULD be less than the maximum amount specified by the user in the `bid` tag.
## Job types
-This NIP defines some job types, clients SHOULD specify these types for maximum compatibility with service providers. Other job types might be added to this NIP.
+This NIP defines some example job types, Customers SHOULD specify these types for maximum compatibility with Service Providers. Other job types MAY be added to this NIP after being observed in the wild.
### `speech-to-text`
#### params
@@ -127,24 +128,24 @@ This NIP defines some job types, clients SHOULD specify these types for maximum
| `language` | req | requested language in BCP 47 format.
# Protocol Flow
-* User publishes a job request
+* Customer publishes a job request
`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
-* Service providers listen for the type of jobs they can perform
+* Service Providers subsribe to the type of jobs they can perform
`{"kinds":[68001], "#j": ["speech-to-text", "image-generation", ... ]}`
-* When a job comes in, the service providers who opt to attempt to fulfill the request begin processing it, or they can react to it with feedback for the user (e.g. _payment required_, _unprocessable entity_, etc.)
+* When a job comes in, the Service Providers who opt to attempt to fulfill the request begin processing it, or they can react to it with feedback for the user (e.g. _payment required_, _unprocessable entity_, etc.)
* Upon completion, the service provider publishes the result of the job with a `job-result` event.
* Upon acceptance, the user zaps the service provider, tagging the job result event.
# Payment
-Customers SHOULD pay service providers whose job results they accept. Users should zap the service provider, tagging the `kind:68002` job result.
+Customers SHOULD pay service providers whose job results they accept by zapping the Service Provider and tagging the `kind:68002` job result.
# Job chaining
-A customer CAN request multiple jobs to be chained, 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.
+A 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.
-Service providers might opt to start processing a subsequent job the moment they see the prior job's result, or they might choose to wait for a zap to have been published. This introduces the 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.
+Service 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.
# Reactions
> **Warning**
From 5f27121c98efe01f756ee8d316051913277b33c5 Mon Sep 17 00:00:00 2001
From: Believethehype
Date: Sun, 9 Jul 2023 12:08:28 +0200
Subject: [PATCH 008/192] Update vending-machine.md
---
vending-machine.md | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/vending-machine.md b/vending-machine.md
index 2f9c0649..e64a667c 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -89,7 +89,7 @@ The output of processing the data -- published by the Service Provider.
"kind": 68002,
"tags" [
// stringified JSON request event
- [ "request", "" ],
+ [ "request", "<68001-event-as-stringified JSON>" ],
[ "e", "" ],
[ "p", "" ],
[ "status", "success", "" ],
@@ -115,6 +115,7 @@ This NIP defines some example job types, Customers SHOULD specify these types fo
| param | req? | description
|--------------------------------|------|--------
| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
+| `alignment` | opt | word, segment, raw : word-level, segment-level or raw outputs
### `summarization`
| param | req? | description
From a9dd5574531229df065eb9df2212bb7510db1f61 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Tue, 11 Jul 2023 15:22:30 +0200
Subject: [PATCH 009/192] get rid of the kind:7 stuff
---
vending-machine.md | 131 +++++++++++++++++++++------------------------
1 file changed, 61 insertions(+), 70 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index e64a667c..0f0b0031 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -33,6 +33,9 @@ A request to have data processed -- published by a customer
// input(s) for the job request
[ "i", "", "", "" ],
+ // expected output format
+ [ "output", "mimetype" ],
+
// relays where the job result should be published
[ "relays", "wss://..."],
@@ -45,51 +48,36 @@ A request to have data processed -- published by a customer
}
```
-### `content` field
-An optional, human-readable description of what this job is for.
+* `content` field: An optional, human-readable description of what this job is for.
+* `j` tag: Job-type to be executed.
+ * A job request MUST have exactly one `j` tag.
+ * It MAY include a second value specifying the name of a model to be used when computing the result.
-### `j` tag
-Specifies the job to be executed. A job request MUST have exactly one (1) `j` tag.
-
-A `j` tag MAY include a second value specifying the name of a model to be used when computing the result.
-
-### `i` (input) tag
-Specifies the input data that the job is to be executed against. The input is relay-indexable so that clients interested in the exact same job can find the input data and the result result (if it's already fulfilled).
-
-A job request CAN have zero or more inputs.
-
-* ``: The argument for the input
-* ``: The way this argument should be interpreted
- * Possible values:
+* `i` tag: Input data for the job.
+ * A job request CAN have zero or more inputs.
+ * Positional arguments: `["i", "", "", "", ""]`
+ * ``: The argument for the input
+ * ``: The way this argument should be interpreted, one of:
* `url`: a URL to be fetched
- * `event`: a nostr event ID
+ * `event`: a nostr event ID, include an optional relay-url extra param
* `job`: the output of a previous job with the specified event ID
-* ``: an optional field indicating where the data can be found if it is a subset of the provided values, for example the name of the key(s) in a key/value set, or the start and end positions of the data if it's a bytestream.
-
-### `bid` tag
-The Customer MAY specify a maximum amount (in millisats) they are willing to pay for the job to be processed.
-
-### `relays` tag
-The Service Provider SHOULD publish job results to the relays specified in this this tag.
-
-### `p` tags
-If a Customer has a preference for specific Service Provider(s) to process this job, they SHOULD indicate this by including the Service Provider(s) pubkey in a `p` tag. This is NOT intended to exclude other Service Providers and they MAY still choose to compete for jobs that have not tagged them.
-
-### `exp`
-A Customer MAY indicate that they will not pay for results produced after a specific Block height or Unix Timestamp. This is intended for time-sensitive jobs where the result is not relevant unless produced within a certain timeframe, e.g. a live transcription service.
+ * ``: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string.
+ * ``: an optional field indicating how this input should be used.
+* `output` tag: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format.
+* `bid` tag: Customer MAY specify a maximum amount (in millisats) they are willing to pay.
+* `relays` tag: relays where Service Providers SHOULD publish responses to.
+* `p` tags: Service Providers the customer is interested in having process this job. Other SP MIGHT still choose to process the job.
+* `exp`: Optional expiration timestamp. Service Providers SHOULD not send results after this timestamp.
## Job result
The output of processing the data -- published by the Service Provider.
```json
{
"pubkey": "service-provider pubkey in hex",
-
- // result
- "content": "string: ",
+ "content": "",
"kind": 68002,
"tags" [
- // stringified JSON request event
- [ "request", "<68001-event-as-stringified JSON>" ],
+ [ "request", "<68001-event>" ],
[ "e", "" ],
[ "p", "" ],
[ "status", "success", "" ],
@@ -98,36 +86,15 @@ The output of processing the data -- published by the Service Provider.
}
```
+## Job feedback
+Both customers and service providers can give feedback about a job.
+
The result of the job SHOULD be included in the `content` field. If the output is not text, the `content` field SHOULD be empty and an `output` tag should be used instead as described below.
-#### `status` tag
-The Service Provider MAY indicate errors during processing by including them in the `status` tag, these errors are intended to be consumed by the Customer.
-
-#### `amount`
-The amount (in millisats) that the Service Provider is requesting to be paid. This amount MAY differ to the amount specified by the Customer in the `bid` tag. The amount SHOULD be less than the maximum amount specified by the user in the `bid` tag.
-
-## Job types
-
-This NIP defines some example job types, Customers SHOULD specify these types for maximum compatibility with Service Providers. Other job types MAY be added to this NIP after being observed in the wild.
-
-### `speech-to-text`
-#### params
-| param | req? | description
-|--------------------------------|------|--------
-| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
-| `alignment` | opt | word, segment, raw : word-level, segment-level or raw outputs
-
-### `summarization`
-| param | req? | description
-|--------------------------------|------|--------
-| `length` | opt | desired length
-
-### `translation` -- Translate text to a specific language
-#### params
-| param | req? | description
-|--------------------------------|------|--------
-| `language` | req | requested language in BCP 47 format.
+* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag.
+* `amount`: millisats that the Service Provider is requesting to be paid.
+##
# Protocol Flow
* Customer publishes a job request
`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
@@ -142,15 +109,17 @@ This NIP defines some example job types, Customers SHOULD specify these types fo
# Payment
Customers SHOULD pay service providers whose job results they accept by zapping the Service Provider and tagging the `kind:68002` job result.
+Additionally, if a service provider requests full or partial prepayment via a `kind:68003` job-feedback event, the customer SHOULD zap that event to pay the service provider.
+
+# Cancellation
+A `kind:68001` job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event.
# Job chaining
A 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.
Service 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.
-# Reactions
-> **Warning**
-> Is this hijacking/modifying the meaning of NIP-25 reactions too much?
+# Job Feedback
## Job request reactions
Service Providers might opt to give feedback about a job.
@@ -169,7 +138,6 @@ Service Providers might opt to give feedback about a job.
```
## Job feedback
-
A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result.
@@ -197,21 +165,21 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
"content": "I need a transcript of Bitcoin.review",
"tags": [
[ "j", "speech-to-text" ],
- [ "params", "range", "900", "930" ],
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
- [ "bid", "5000", "9000" ]
+ [ "params", "range", "900", "930" ],
+ [ "bid", "5000", "9000" ],
+ [ "output", "text/plain" ]
]
}
```
-### `kind:1021`: Job fulfillment
+### `kind:68002`: Job fulfillment
```json
{
- "content": "Person 1: blah blah blah",
+ "content": "blah blah blah",
"tags": [
["e", "12345"],
["p", "abcdef"],
- ["status", "success"]
]
}
```
@@ -306,6 +274,29 @@ User publishes two job requests at the same time in the order they should be exe
}
```
+# Appendix 2: Job types
+
+This NIP defines some example job types, Customers SHOULD specify these types for maximum compatibility with Service Providers. Other job types MAY be added to this NIP after being observed in the wild.
+
+### `speech-to-text`
+#### params
+| param | req? | description
+|--------------------------------|------|--------
+| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
+| `alignment` | opt | word, segment, raw : word-level, segment-level or raw outputs
+
+### `summarization`
+| param | req? | description
+|--------------------------------|------|--------
+| `length` | opt | desired length
+
+### `translation` -- Translate text to a specific language
+#### params
+| param | req? | description
+|--------------------------------|------|--------
+| `language` | req | requested language in BCP 47 format.
+
+
# Notes
* Should there be a possibility of getting the job result delivered encrypted? I don't like it but maybe it should be supported.
From def620e1ce4417a4e78b5012c3a43adbe105f43e Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Tue, 11 Jul 2023 22:25:54 +0200
Subject: [PATCH 010/192] more cleanup
---
vending-machine.md | 57 +++++++++++++++++++++++++++++-----------------
1 file changed, 36 insertions(+), 21 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 0f0b0031..8121ffc0 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -27,19 +27,10 @@ A request to have data processed -- published by a customer
"kind": 68001,
"content": "",
"tags": [
- // The type of data processing the user wants to be performed
[ "j", "", "" ],
-
- // input(s) for the job request
[ "i", "", "", "" ],
-
- // expected output format
- [ "output", "mimetype" ],
-
- // relays where the job result should be published
+ [ "output", "" ],
[ "relays", "wss://..."],
-
- // millisats amount that the user is offering to pay
[ "bid", "", "" ],
[ "exp", "" ],
[ "p", "service-provider-1" ],
@@ -94,7 +85,6 @@ The result of the job SHOULD be included in the `content` field. If the output i
* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag.
* `amount`: millisats that the Service Provider is requesting to be paid.
-##
# Protocol Flow
* Customer publishes a job request
`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
@@ -127,7 +117,7 @@ Service Providers might opt to give feedback about a job.
### E.g. Payment required
```json
{
- "kind": 7,
+ "kind": 68003,
"content": "Please pay 7 sats for job xxxx",
"tags": [
[ "e", ],
@@ -148,11 +138,6 @@ Service providers are at obvious risk of having their results not compensated. M
It's out of scope (and undesirable) to have this NIP address this issue; the market should.
-## Notes
-
-### Multitple job acceptance
-* Nothing prevents a user from accepting multiple job results.
-
# Appendix 1: Examples
## Transcript of a podcast from second `900` to `930`.
@@ -162,7 +147,7 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
{
"id": "12345",
"pubkey": "abcdef",
- "content": "I need a transcript of Bitcoin.review",
+ "content": "",
"tags": [
[ "j", "speech-to-text" ],
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
@@ -173,13 +158,30 @@ It's out of scope (and undesirable) to have this NIP address this issue; the mar
}
```
-### `kind:68002`: Job fulfillment
+### `kind:68003`: Job Feedback: request for (partial) payment
+```json
+{
+ "kind": 68003,
+ "content": "",
+ "tags": [
+ ["e", "12345"],
+ ["p", "abcdef"],
+ ["status", "payment-required"],
+ ["amount", "1000"]
+ ]
+}
+```
+
+* User zaps 1000 sats to event kind:68003.
+
+### `kind:68002`: Job fulfillment + request for remaining payment
```json
{
"content": "blah blah blah",
"tags": [
["e", "12345"],
["p", "abcdef"],
+ ["amount", "6000"]
]
}
```
@@ -208,7 +210,7 @@ User publishes two job requests at the same time in the order they should be exe
{
"id": "12346",
"pubkey": "abcdef",
- "content": "I need a summarization",
+ "content": "",
"tags": [
[ "j", "summarization" ],
[ "params", "length", "3 paragraphs" ],
@@ -227,13 +229,26 @@ User publishes two job requests at the same time in the order they should be exe
"content": "",
"tags": [
[ "j", "translation" ],
- [ "i", "", "event" ]
+ [ "i", "", "event", "wss://relay.nostr.com" ]
[ "params", "language", "es_AR" ],
[ "bid", "100", "500" ]
]
}
```
+### `kind:68003`: Job respomse
+```json
+{
+ "kind": 68003,
+ "content": "Che, que copado, boludo!",
+ "tags": [
+ ["e", "12346"],
+ ["p", "abcdef"],
+ ["amount", "1000"]
+ ]
+}
+```
+
## AI-image of the summarization of 2 podcasts
### `kind:68001`: Job request #1 (transcribe podcast #1)
From e9924bdcde2dc516a891c027bd023f487b73a674 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Sat, 15 Jul 2023 12:24:32 +0200
Subject: [PATCH 011/192] add optional bolt11
---
vending-machine.md | 24 +++++++++++++++---------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 8121ffc0..1d08bd23 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -72,7 +72,7 @@ The output of processing the data -- published by the Service Provider.
[ "e", "" ],
[ "p", "" ],
[ "status", "success", "" ],
- [ "amount", "requested-payment-amount" ]
+ [ "amount", "requested-payment-amount", "" ]
]
}
```
@@ -80,21 +80,27 @@ The output of processing the data -- published by the Service Provider.
## Job feedback
Both customers and service providers can give feedback about a job.
-The result of the job SHOULD be included in the `content` field. If the output is not text, the `content` field SHOULD be empty and an `output` tag should be used instead as described below.
+The result of the job SHOULD be included in the `content` field.
* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag.
-* `amount`: millisats that the Service Provider is requesting to be paid.
+* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice.
# Protocol Flow
* Customer publishes a job request
`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
+* Service Prpvoders can submit `kind:68003` job-feedback events (e.g. `payment-required`, `processing`, `unprocessable-entity`, etc.).
+* Upon completion, the service provider publishes the result of the job with a `kind:68002` job-result event.
+* Upon acceptance, the user zaps the service provider, tagging the job result event with a `kind:7` π reaction.
-* Service Providers subsribe to the type of jobs they can perform
-`{"kinds":[68001], "#j": ["speech-to-text", "image-generation", ... ]}`
+`kind:68002` and `kind:68003` 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 must be done before moving on to the next step.
-* When a job comes in, the Service Providers who opt to attempt to fulfill the request begin processing it, or they can react to it with feedback for the user (e.g. _payment required_, _unprocessable entity_, etc.)
-* Upon completion, the service provider publishes the result of the job with a `job-result` event.
-* Upon acceptance, the user zaps the service provider, tagging the job result event.
+## Notes about the protocol flow
+The flow is deliverately left 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:68002` 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.
# Payment
Customers SHOULD pay service providers whose job results they accept by zapping the Service Provider and tagging the `kind:68002` job result.
@@ -131,7 +137,7 @@ Service Providers might opt to give feedback about a job.
A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result.
-## Explicitly not addressed in this NIP
+## Not addressed in this NIP
### Reputation system
Service 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).
From 53bd97373b5442445f5c387945cf5685ac39ab80 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Sun, 23 Jul 2023 21:28:59 +0200
Subject: [PATCH 012/192] use different kinds per job request type
---
vending-machine.md | 217 ++++++++++++++++++++++++++-------------------
1 file changed, 127 insertions(+), 90 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 1d08bd23..4dbc5a3a 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -8,10 +8,19 @@ Data Vending Machine
This NIP defines the interaction between customers and Service Providers to perform on-demand computation.
+## Kinds
+This NIP reserves the range `65000-69999` for data vending machine use.
+
+| Kind | Description |
+| ---- | ----------- |
+| 65000 | Job feedback |
+| 65001 | Job result |
+| 65002-69999 | Job request kinds |
+
## Rationale
Nostr 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.
-This NIP is not to be confused with a 1:1 marketplace; but rather, a flow where user announces a desired output, willigness to pay, and service providers compete to fulfill the job requirement in the best way possible.
+This 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.
### Actors
There are two actors to the workflow described in this NIP:
@@ -24,52 +33,44 @@ A request to have data processed -- published by a customer
```json
{
- "kind": 68001,
+ "kind": 6xxxx,
"content": "",
"tags": [
- [ "j", "", "" ],
- [ "i", "", "", "" ],
+ [ "i", "", "", "", "" ],
[ "output", "" ],
[ "relays", "wss://..."],
- [ "bid", "", "" ],
+ [ "bid", "" ],
[ "exp", "" ],
- [ "p", "service-provider-1" ],
- [ "p", "service-provider-2" ],
+ [ "t", "bitcoin" ]
]
}
```
-* `content` field: An optional, human-readable description of what this job is for.
-* `j` tag: Job-type to be executed.
- * A job request MUST have exactly one `j` tag.
- * It MAY include a second value specifying the name of a model to be used when computing the result.
-
-* `i` tag: Input data for the job.
- * A job request CAN have zero or more inputs.
- * Positional arguments: `["i", "", "", "", ""]`
+* `i` tag: Input data for the job, (zero or more inputs may exist)
* ``: The argument for the input
- * ``: The way this argument should be interpreted, one of:
+ * ``: The way this argument should be interpreted, MUST be one of:
* `url`: a URL to be fetched
* `event`: a nostr event ID, include an optional relay-url extra param
* `job`: the output of a previous job with the specified event ID
- * ``: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string.
+ * `content`:
* ``: an optional field indicating how this input should be used.
-* `output` tag: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format.
-* `bid` tag: Customer MAY specify a maximum amount (in millisats) they are willing to pay.
+ * ``: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string.
+* `output` tag (opt): MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified.
+* `bid` tag (opt): Customer MAY specify a maximum amount (in millisats) they are willing to pay.
* `relays` tag: relays where Service Providers SHOULD publish responses to.
-* `p` tags: Service Providers the customer is interested in having process this job. Other SP MIGHT still choose to process the job.
-* `exp`: Optional expiration timestamp. Service Providers SHOULD not send results after this timestamp.
+* `p` tags (opt): Service Providers the customer is interested in having process this job. Other SP MIGHT still choose to process the job.
+* `exp` (opt): expiration timestamp. Service Providers SHOULD not send results after this timestamp.
## Job result
The output of processing the data -- published by the Service Provider.
```json
{
- "pubkey": "service-provider pubkey in hex",
+ "pubkey": "",
"content": "",
- "kind": 68002,
+ "kind": 65001,
"tags" [
- [ "request", "<68001-event>" ],
- [ "e", "" ],
+ [ "request", "" ],
+ [ "e", "", "" ],
[ "p", "" ],
[ "status", "success", "" ],
[ "amount", "requested-payment-amount", "" ]
@@ -77,6 +78,9 @@ The output of processing the data -- published by the Service Provider.
}
```
+* `request` tag: The job request event ID.
+* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice.
+
## Job feedback
Both customers and service providers can give feedback about a job.
@@ -86,29 +90,25 @@ The result of the job SHOULD be included in the `content` field.
* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice.
# Protocol Flow
-* Customer publishes a job request
-`{ "kind": 68001, "tags": [ [ "j", "speech-to-text" ], ... ] }`
-* Service Prpvoders can submit `kind:68003` job-feedback events (e.g. `payment-required`, `processing`, `unprocessable-entity`, etc.).
-* Upon completion, the service provider publishes the result of the job with a `kind:68002` job-result event.
-* Upon acceptance, the user zaps the service provider, tagging the job result event with a `kind:7` π reaction.
+* Customer publishes a job request (e.g. `kind:65002`).
+* Service Prpvoders can submit `kind:65000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.).
+* Upon completion, the service provider publishes the result of the job with a `kind:65001` job-result event.
+* At any point, the user can pay the included `bolt11` or zap any of the events the service provider has sent to the user.
-`kind:68002` and `kind:68003` 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 must be done before moving on to the next step.
+`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. Custeroms 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.
## Notes about the protocol flow
-The flow is deliverately left 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:68002` 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.
+The 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.
+
+It's not up to this NIP to define how individual vending machines should choose to run their business.
# Payment
-Customers SHOULD pay service providers whose job results they accept by zapping the Service Provider and tagging the `kind:68002` job result.
+Customers 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.
-Additionally, if a service provider requests full or partial prepayment via a `kind:68003` job-feedback event, the customer SHOULD zap that event to pay the service provider.
+Additionally, 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.
# Cancellation
-A `kind:68001` job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event.
+A job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event.
# Job chaining
A 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.
@@ -116,17 +116,31 @@ A Customer MAY request multiple jobs to be processed in a chained form, so that
Service 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.
# Job Feedback
+The 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.
-## Job request reactions
-Service Providers might opt to give feedback about a job.
+Any 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.
-### E.g. Payment required
+| status | description |
+|--------|-------------|
+| `payment-required` | Service Provider requires payment before continuing. |
+| `processing` | Service Provider is processing the job. |
+| `error` | Service Provider was unable to process the job. |
+| `success` | Service Provider successfully processed the job. |
+| `failure` | Service Provider failed to process the job. |
+| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
+
+Any job feedback event MIGHT include an `amount` tag, as described in the [Job Result](#job-result) section.
+
+Any job feedback event MIGHT include results in the `.content` field, as described in the [Job Result](#job-result) section.
+
+### E.g. Payment required (with sample content)
```json
{
- "kind": 68003,
- "content": "Please pay 7 sats for job xxxx",
+ "kind": 65000,
+ "content": "This is the transcription service that you",
"tags": [
- [ "e", ],
+ [ "e", , ],
+ [ "p", ],
[ "status", "payment-required" ],
[ "amount", "7000" ],
]
@@ -144,153 +158,160 @@ Service providers are at obvious risk of having their results not compensated. M
It's out of scope (and undesirable) to have this NIP address this issue; the market should.
+### Encrypted job requests
+Not to be included in the first draft of this NIP, but encrypted job requests should be added. A few ways:
+* 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.
+
# Appendix 1: Examples
## Transcript of a podcast from second `900` to `930`.
-### `kind:68001`: Job Request
+### `kind:65002`: Speech-to-text job request
```json
{
"id": "12345",
"pubkey": "abcdef",
"content": "",
+ "kind": 65002,
"tags": [
- [ "j", "speech-to-text" ],
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
[ "params", "range", "900", "930" ],
- [ "bid", "5000", "9000" ],
+ [ "output", "text/vtt" ],
+ [ "bid", "50000" ],
[ "output", "text/plain" ]
]
}
```
-### `kind:68003`: Job Feedback: request for (partial) payment
+### `kind:65001`: Job Feedback: request for (partial) payment
+* The SP is signaling here that it won't start processing until 100 sats are paid
```json
{
- "kind": 68003,
+ "kind": 65000,
"content": "",
"tags": [
["e", "12345"],
["p", "abcdef"],
["status", "payment-required"],
- ["amount", "1000"]
+ ["amount", "100000"]
]
}
```
-* User zaps 1000 sats to event kind:68003.
+* User zaps 100 sats to the `kind:65000` job-feedback
-### `kind:68002`: Job fulfillment + request for remaining payment
+### `kind:65001`: Job result + request for remaining payment
```json
{
"content": "blah blah blah",
"tags": [
["e", "12345"],
["p", "abcdef"],
- ["amount", "6000"]
+ ["amount", "400000"]
]
}
```
## Summarization of a podcast
+User publishes two job requests at the same time.
-User publishes two job requests at the same time in the order they should be executed.
-
-### `kind:68001`: Job Request #1
+### `kind:65002`: Job Request #1: speech-to-text
```json
{
"id": "12345",
"pubkey": "abcdef",
+ "kinds" 65002,
"content": "I need a transcript of Bitcoin.review from second 900 to 930",
"tags": [
- [ "j", "speech-to-text" ],
- [ "params", "range", "900", "930" ],
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
- [ "bid", "5000", "9000" ]
+ [ "output", "text/plain" ],
+ [ "params", "range", "900", "930" ],
+ [ "bid", "100000" ]
]
}
```
-### `kind:68001`: Job Request #2
+### `kind:65003`: Job Request #2: summarization of job #1's result
```json
{
"id": "12346",
"pubkey": "abcdef",
+ "kinds": 65003,
"content": "",
"tags": [
- [ "j", "summarization" ],
- [ "params", "length", "3 paragraphs" ],
[ "i", "12346", "job" ],
- [ "bid", "300", "900" ]
+ [ "output", "text/plain" ],
+ [ "params", "length", "3 paragraphs" ],
+ [ "bid", "10000" ]
]
}
```
## Translation of a note
-### `kind:68001`: Job Request #1
+### `kind:65004`: Job Request #1: translation of an existing note
```json
{
"id": "12346",
"pubkey": "abcdef",
"content": "",
+ "kinds": 65004,
"tags": [
- [ "j", "translation" ],
[ "i", "", "event", "wss://relay.nostr.com" ]
- [ "params", "language", "es_AR" ],
- [ "bid", "100", "500" ]
+ [ "params", "lang", "es_AR" ],
+ [ "bid", "5000" ]
]
}
```
-### `kind:68003`: Job respomse
+### `kind:65001`: Job respomse
```json
{
- "kind": 68003,
+ "kind": 65001,
"content": "Che, que copado, boludo!",
"tags": [
["e", "12346"],
["p", "abcdef"],
- ["amount", "1000"]
+ ["amount", "4000"]
]
}
```
## AI-image of the summarization of 2 podcasts
-### `kind:68001`: Job request #1 (transcribe podcast #1)
+### `kind:65002`: Job request #1 (transcribe podcast #1)
```json
{
"id": "123",
+ "kind" 65002,
"tags": [
- [ "j", "speech-to-text" ],
[ "i", "https://example.com/episode1.mp3", "url" ],
- [ "bid", "100", "500" ]
+ [ "bid", "100000" ]
]
}
```
-### `kind:68001`: Job request #2 (transcribe podcast #2)
+### `kind:65002`: Job request #2 (transcribe podcast #2)
```json
{
"id": "124",
+ "kind" 65002,
"tags": [
- [ "j", "speech-to-text" ],
[ "i", "https://example.com/episode2.mp3", "url" ],
- [ "bid", "100", "500" ]
+ [ "bid", "100000" ]
]
}
```
-### `kind:68001`: Job request #3 (summarize both podcasts into one podcast)
+### `kind:65003`: Job request #3 (summarize both podcasts into one paragraph)
```json
{
"id": "125",
+ "kind": 65003,
"tags": [
- [ "j", "summarize" ],
[ "param", "length", "1 paragraph" ],
[ "i", "123", "job" ],
[ "i", "124", "job" ],
- [ "bid", "100", "500" ]
+ [ "bid", "100000" ]
]
}
```
@@ -299,29 +320,45 @@ User publishes two job requests at the same time in the order they should be exe
This NIP defines some example job types, Customers SHOULD specify these types for maximum compatibility with Service Providers. Other job types MAY be added to this NIP after being observed in the wild.
-### `speech-to-text`
+### speech-to-text: `kind:65002`
#### params
| param | req? | description
|--------------------------------|------|--------
| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
-| `alignment` | opt | word, segment, raw : word-level, segment-level or raw outputs
+| `alignment` | opt | word, segment, raw: word-level, segment-level or raw outputs
-### `summarization`
+### summarization: `kind:65003`
| param | req? | description
|--------------------------------|------|--------
| `length` | opt | desired length
-### `translation` -- Translate text to a specific language
-#### params
+### translation: `kind:65004`
| param | req? | description
|--------------------------------|------|--------
-| `language` | req | requested language in BCP 47 format.
+| `lang` | req | desired language in BCP 47 format.
+### image generation: `kind:65005`
+* `input`
# Notes
-* Should there be a possibility of getting the job result delivered encrypted? I don't like it but maybe it should be supported.
-
-* Ambiguity on job acceptance, particularly for job-chaining circumstances is deliberately ambiguous: 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.
+* 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.
That'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).
+
+# Appendix 3: Service provider discoverability
+
+Service Providers can use NIP-89 announcements to advertise their support for job kinds:
+
+```json
+{
+ "kind": 31990,
+ "pubkey": ,
+ "tags": [
+ [ "k", 65002 ], // e.g. speech-to-text
+ [ "t", "bitcoin" ] // e.g. optionally advertises it specializes in bitcoin audio transcription that won't confuse "Drivechains" with "Ridechains"
+ ]
+}
+```
+
+Customers can use NIP-89 to see what service providers their follows use.
\ No newline at end of file
From d8b0e7d757206098f65b8ff868e8c59a9ac92ea6 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Sun, 23 Jul 2023 23:37:20 +0300
Subject: [PATCH 013/192] wip
---
vending-machine.md | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 4dbc5a3a..4934d4c3 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -9,13 +9,13 @@ Data Vending Machine
This NIP defines the interaction between customers and Service Providers to perform on-demand computation.
## Kinds
-This NIP reserves the range `65000-69999` for data vending machine use.
+This NIP reserves the range `65000-66000` for data vending machine use.
| Kind | Description |
| ---- | ----------- |
| 65000 | Job feedback |
| 65001 | Job result |
-| 65002-69999 | Job request kinds |
+| 65002-66000 | Job request kinds |
## Rationale
Nostr 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.
@@ -33,7 +33,7 @@ A request to have data processed -- published by a customer
```json
{
- "kind": 6xxxx,
+ "kind": <65002-66000>,
"content": "",
"tags": [
[ "i", "", "", "", "" ],
@@ -46,6 +46,8 @@ A request to have data processed -- published by a customer
}
```
+All tags are optional.
+
* `i` tag: Input data for the job, (zero or more inputs may exist)
* ``: The argument for the input
* ``: The way this argument should be interpreted, MUST be one of:
@@ -55,11 +57,11 @@ A request to have data processed -- published by a customer
* `content`:
* ``: an optional field indicating how this input should be used.
* ``: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string.
-* `output` tag (opt): MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified.
-* `bid` tag (opt): Customer MAY specify a maximum amount (in millisats) they are willing to pay.
-* `relays` tag: relays where Service Providers SHOULD publish responses to.
-* `p` tags (opt): Service Providers the customer is interested in having process this job. Other SP MIGHT still choose to process the job.
-* `exp` (opt): expiration timestamp. Service Providers SHOULD not send results after this timestamp.
+* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified.
+* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay.
+* `relays`: relays where Service Providers SHOULD publish responses to.
+* `p`: Service Providers the customer is interested in. Other SP MIGHT still choose to process the job.
+* `exp`: expiration timestamp. Service Providers SHOULD not send results after this timestamp.
## Job result
The output of processing the data -- published by the Service Provider.
From 280483adc5b2299886e1e15e369557001e8807af Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Sun, 23 Jul 2023 23:58:12 +0300
Subject: [PATCH 014/192] more clarifications
---
vending-machine.md | 68 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 52 insertions(+), 16 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 4934d4c3..c4fdc18c 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -17,6 +17,8 @@ This NIP reserves the range `65000-66000` for data vending machine use.
| 65001 | Job result |
| 65002-66000 | Job request kinds |
+[Appendix 2](#appendix-2-job-types) defines the job types.
+
## Rationale
Nostr 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.
@@ -33,7 +35,7 @@ A request to have data processed -- published by a customer
```json
{
- "kind": <65002-66000>,
+ "kind": xxx, // kind in 65002-66000 range
"content": "",
"tags": [
[ "i", "", "", "", "" ],
@@ -54,8 +56,8 @@ All tags are optional.
* `url`: a URL to be fetched
* `event`: a nostr event ID, include an optional relay-url extra param
* `job`: the output of a previous job with the specified event ID
- * `content`:
- * ``: an optional field indicating how this input should be used.
+ * `text`: `` is the value of the input, no resolution is needed
+ * ``: an optional field indicating how this input should be used within the context of the job.
* ``: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string.
* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified.
* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay.
@@ -97,7 +99,7 @@ The result of the job SHOULD be included in the `content` field.
* Upon completion, the service provider publishes the result of the job with a `kind:65001` job-result event.
* At any point, the user can pay the included `bolt11` or zap any of the events the service provider has sent to the user.
-`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. Custeroms 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.
+`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.
## Notes about the protocol flow
The 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.
@@ -117,6 +119,8 @@ A Customer MAY request multiple jobs to be processed in a chained form, so that
Service 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.
+Consult [Appendix 1: Example](#appendix-1-examples)'s [Summarization of a podcast](#summarization-of-a-podcast)
+
# Job Feedback
The 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.
@@ -215,7 +219,9 @@ Not to be included in the first draft of this NIP, but encrypted job requests sh
```
## Summarization of a podcast
-User publishes two job requests at the same time.
+User publishes two job requests at the same time. A job that transcribes an audio and a job that summarizes the transcription (output of job #1).
+
+User publishes event #1 and #2 together.
### `kind:65002`: Job Request #1: speech-to-text
```json
@@ -223,7 +229,7 @@ User publishes two job requests at the same time.
"id": "12345",
"pubkey": "abcdef",
"kinds" 65002,
- "content": "I need a transcript of Bitcoin.review from second 900 to 930",
+ "content": "",
"tags": [
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
[ "output", "text/plain" ],
@@ -233,7 +239,7 @@ User publishes two job requests at the same time.
}
```
-### `kind:65003`: Job Request #2: summarization of job #1's result
+### `kind:65002`: Job Request #2: summarization of job #1's result
```json
{
"id": "12346",
@@ -241,7 +247,7 @@ User publishes two job requests at the same time.
"kinds": 65003,
"content": "",
"tags": [
- [ "i", "12346", "job" ],
+ [ "i", "12345", "job" ], // input is the output of job with id 12345
[ "output", "text/plain" ],
[ "params", "length", "3 paragraphs" ],
[ "bid", "10000" ]
@@ -317,30 +323,60 @@ User publishes two job requests at the same time.
]
}
```
+## AI-image of embedded input
+
+### `kind:65005`: Job request
+```json
+{
+ "kind": 65004,
+ "tags": [
+ [ "i", "Millions of vending machines, interconnected with tubes with eah other", "text" ],
+ [ "param", "prompt", "photorealistic" ],
+ [ "bid", "500000" ]
+ ]
+}
+```
+
+### `kind:65006`: Job request #4 (generate image based on the summary)
+```json
+{
+ "id": "126",
+ "kind": 65004,
+ "tags": [
+ [ "i", "125", "job" ],
+ [ "param", "prompt", "photorealistic" ],
+ [ "param", "size", "4000x4000" ],
+ [ "bid", "500000" ]
+ ]
+}
+```
# Appendix 2: Job types
-This NIP defines some example job types, Customers SHOULD specify these types for maximum compatibility with Service Providers. Other job types MAY be added to this NIP after being observed in the wild.
-
-### speech-to-text: `kind:65002`
-#### params
+This is a list of all the supported job requests
+.
+## speech-to-text: `kind:65002`
+### params
| param | req? | description
|--------------------------------|------|--------
| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
| `alignment` | opt | word, segment, raw: word-level, segment-level or raw outputs
-### summarization: `kind:65003`
+## summarization: `kind:65003`
| param | req? | description
|--------------------------------|------|--------
| `length` | opt | desired length
-### translation: `kind:65004`
+## translation: `kind:65004`
| param | req? | description
|--------------------------------|------|--------
| `lang` | req | desired language in BCP 47 format.
-### image generation: `kind:65005`
-* `input`
+## image generation: `kind:65005`
+| param | req? | description
+|--------------------------------|------|--------
+| `prompt` | opt | extra prompt to be used for the image generation
+| `size` | opt | desired size of the image
# Notes
From 4cb3ac871f1c54d2e845ec8655bf564072377a46 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Mon, 24 Jul 2023 00:38:47 +0300
Subject: [PATCH 015/192] clarifications, hopefully
---
vending-machine.md | 192 ++++++++++++++++++++++-----------------------
1 file changed, 93 insertions(+), 99 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index c4fdc18c..276132df 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -1,4 +1,4 @@
-NIP-XX
+NIP-90
======
Data Vending Machine
@@ -6,7 +6,9 @@ Data Vending Machine
`draft` `optional` `author:pablof7z`
-This NIP defines the interaction between customers and Service Providers to perform on-demand computation.
+This NIP defines the interaction between customers and Service Providers for performing on-demand computation.
+
+Money in, data out.
## Kinds
This 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.
[Appendix 2](#appendix-2-job-types) defines the job types.
## Rationale
-Nostr 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.
+Nostr 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.
-This 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.
+This 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.
### Actors
-There are two actors to the workflow described in this NIP:
+There are two actors in the workflow described in this NIP:
* Customers (npubs who request a job)
* Service providers (npubs who fulfill jobs)
# Event Kinds
## Job request
-A request to have data processed -- published by a customer
+A request to have data processed, published by a customer
```json
{
@@ -50,33 +52,34 @@ A request to have data processed -- published by a customer
All tags are optional.
-* `i` tag: Input data for the job, (zero or more inputs may exist)
+* `i` tag: Input data for the job (zero or more inputs may exist)
* ``: The argument for the input
* ``: The way this argument should be interpreted, MUST be one of:
- * `url`: a URL to be fetched
- * `event`: a nostr event ID, include an optional relay-url extra param
- * `job`: the output of a previous job with the specified event ID
+ * `url`: A URL to be fetched
+ * `event`: A Nostr event ID, include an optional relay-url extra param
+ * `job`: The output of a previous job with the specified event ID
* `text`: `` is the value of the input, no resolution is needed
- * ``: an optional field indicating how this input should be used within the context of the job.
- * ``: if `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string.
-* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified.
-* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay.
-* `relays`: relays where Service Providers SHOULD publish responses to.
-* `p`: Service Providers the customer is interested in. Other SP MIGHT still choose to process the job.
-* `exp`: expiration timestamp. Service Providers SHOULD not send results after this timestamp.
+ * ``: An optional field indicating how this input should be used within the context of the job
+ * ``: If `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string
+* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified
+* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay
+* `relays`: Relays where Service Providers SHOULD publish responses to
+* `p`: Service Providers the customer is interested in. Other SPs MIGHT still choose to process the job
+* `exp`: Expiration timestamp. Service Providers SHOULD not send results after this timestamp
## Job result
+
The output of processing the data -- published by the Service Provider.
+
```json
{
"pubkey": "",
"content": "",
"kind": 65001,
- "tags" [
+ "tags": [
[ "request", "" ],
[ "e", "", "" ],
[ "p", "" ],
- [ "status", "success", "" ],
[ "amount", "requested-payment-amount", "" ]
]
}
@@ -91,54 +94,35 @@ Both customers and service providers can give feedback about a job.
The result of the job SHOULD be included in the `content` field.
* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag.
-* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice.
+* `amount`: as defined in the [Job Result](#job-result) section.
# Protocol Flow
* Customer publishes a job request (e.g. `kind:65002`).
-* Service Prpvoders can submit `kind:65000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.).
+* Service Providers can submit `kind:65000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.).
* Upon completion, the service provider publishes the result of the job with a `kind:65001` job-result event.
* At any point, the user can pay the included `bolt11` or zap any of the events the service provider has sent to the user.
-`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.
+`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.
## Notes about the protocol flow
-The 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.
+The 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.
+
+Some 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.
It's not up to this NIP to define how individual vending machines should choose to run their business.
-# Payment
-Customers 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.
-
-Additionally, 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.
-
# Cancellation
A job request might be cancelled by publishing a `kind:5` delete request event tagging the job request event.
# Job chaining
-A 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.
+A 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.
-Service 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.
+Service 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.
+
+This gives a higher level of flexibility to service providers (which sophisticated service providers would take anyway).
Consult [Appendix 1: Example](#appendix-1-examples)'s [Summarization of a podcast](#summarization-of-a-podcast)
-# Job Feedback
-The 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.
-
-Any 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.
-
-| status | description |
-|--------|-------------|
-| `payment-required` | Service Provider requires payment before continuing. |
-| `processing` | Service Provider is processing the job. |
-| `error` | Service Provider was unable to process the job. |
-| `success` | Service Provider successfully processed the job. |
-| `failure` | Service Provider failed to process the job. |
-| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
-
-Any job feedback event MIGHT include an `amount` tag, as described in the [Job Result](#job-result) section.
-
-Any job feedback event MIGHT include results in the `.content` field, as described in the [Job Result](#job-result) section.
-
### E.g. Payment required (with sample content)
```json
{
@@ -153,20 +137,15 @@ Any job feedback event MIGHT include results in the `.content` field, as describ
}
```
-## Job feedback
-A user might choose to not accept a job result for any reason. A user can provide feedback via NIP-25 reactions.
-The `content` of the `kind:7` event SHOULD include a description of how the user reacted to the job result.
-
## Not addressed in this NIP
### Reputation system
-Service 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).
-
-It's out of scope (and undesirable) to have this NIP address this issue; the market should.
+Service 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.
### Encrypted job requests
Not to be included in the first draft of this NIP, but encrypted job requests should be added. A few ways:
-* 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.
+ * 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.
+
# Appendix 1: Examples
@@ -189,7 +168,7 @@ Not to be included in the first draft of this NIP, but encrypted job requests sh
}
```
-### `kind:65001`: Job Feedback: request for (partial) payment
+### `kind:65000`: Job Feedback: request for (partial) payment
* The SP is signaling here that it won't start processing until 100 sats are paid
```json
{
@@ -228,7 +207,7 @@ User publishes event #1 and #2 together.
{
"id": "12345",
"pubkey": "abcdef",
- "kinds" 65002,
+ "kind": 65002,
"content": "",
"tags": [
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
@@ -244,7 +223,7 @@ User publishes event #1 and #2 together.
{
"id": "12346",
"pubkey": "abcdef",
- "kinds": 65003,
+ "kind": 65003,
"content": "",
"tags": [
[ "i", "12345", "job" ], // input is the output of job with id 12345
@@ -262,16 +241,17 @@ User publishes event #1 and #2 together.
"id": "12346",
"pubkey": "abcdef",
"content": "",
- "kinds": 65004,
+ "kind": 65004,
"tags": [
[ "i", "", "event", "wss://relay.nostr.com" ]
+ [ "output", "text/plain" ],
[ "params", "lang", "es_AR" ],
[ "bid", "5000" ]
]
}
```
-### `kind:65001`: Job respomse
+### `kind:65001`: Job result
```json
{
"kind": 65001,
@@ -290,7 +270,7 @@ User publishes event #1 and #2 together.
```json
{
"id": "123",
- "kind" 65002,
+ "kind": 65002,
"tags": [
[ "i", "https://example.com/episode1.mp3", "url" ],
[ "bid", "100000" ]
@@ -302,7 +282,7 @@ User publishes event #1 and #2 together.
```json
{
"id": "124",
- "kind" 65002,
+ "kind": 65002,
"tags": [
[ "i", "https://example.com/episode2.mp3", "url" ],
[ "bid", "100000" ]
@@ -310,7 +290,7 @@ User publishes event #1 and #2 together.
}
```
-### `kind:65003`: Job request #3 (summarize both podcasts into one paragraph)
+### `kind:65003`: Job request #3 (summarize the two job's outputs into one paragraph)
```json
{
"id": "125",
@@ -323,6 +303,21 @@ User publishes event #1 and #2 together.
]
}
```
+
+### `kind:65005`: Job request #4 (generate image based on the summary)
+```json
+{
+ "id": "126",
+ "kind": 65004,
+ "tags": [
+ [ "i", "125", "job" ],
+ [ "param", "prompt", "photorealistic" ],
+ [ "param", "size", "4000x4000" ],
+ [ "bid", "500000" ]
+ ]
+}
+``
+
## AI-image of embedded input
### `kind:65005`: Job request
@@ -337,61 +332,60 @@ User publishes event #1 and #2 together.
}
```
-### `kind:65006`: Job request #4 (generate image based on the summary)
-```json
-{
- "id": "126",
- "kind": 65004,
- "tags": [
- [ "i", "125", "job" ],
- [ "param", "prompt", "photorealistic" ],
- [ "param", "size", "4000x4000" ],
- [ "bid", "500000" ]
- ]
-}
-```
-
# Appendix 2: Job types
-This is a list of all the supported job requests
-.
+This is a list of all the supported job requests.
+
## speech-to-text: `kind:65002`
+
### params
-| param | req? | description
-|--------------------------------|------|--------
-| `range` | opt | timestamp range (in seconds) of desired text to be transcribed
-| `alignment` | opt | word, segment, raw: word-level, segment-level or raw outputs
+
+| param | req? | description |
+|------------|------|-----------------------------------------------------------|
+| `range` | opt | timestamp range (in seconds) of desired text to be transcribed |
+| `alignment`| opt | word, segment, raw: word-level, segment-level, or raw outputs |
## summarization: `kind:65003`
-| param | req? | description
-|--------------------------------|------|--------
-| `length` | opt | desired length
+
+| param | req? | description |
+|-----------|------|---------------|
+| `length` | opt | desired length |
## translation: `kind:65004`
-| param | req? | description
-|--------------------------------|------|--------
-| `lang` | req | desired language in BCP 47 format.
+
+| param | req? | description |
+|-----------|------|--------------------------------------------|
+| `lang` | req | desired language in BCP 47 format. |
## image generation: `kind:65005`
-| param | req? | description
-|--------------------------------|------|--------
-| `prompt` | opt | extra prompt to be used for the image generation
-| `size` | opt | desired size of the image
-# Notes
+| param | req? | description |
+|-----------|------|-------------------------------------------------------|
+| `prompt` | opt | extra prompt to be used for the image generation |
+| `size` | opt | desired size of the image |
-* 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.
-That'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).
+# Appendix 3: Job feedback status
-# Appendix 3: Service provider discoverability
+| status | description |
+|--------|-------------|
+| `payment-required` | Service Provider requires payment before continuing. |
+| `processing` | Service Provider is processing the job. |
+| `error` | Service Provider was unable to process the job. |
+| `success` | Service Provider successfully processed the job. |
+| `failure` | Service Provider failed to process the job. |
+| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
+
+Any 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.
+
+# Appendix 4: Service provider discoverability
Service Providers can use NIP-89 announcements to advertise their support for job kinds:
```json
{
"kind": 31990,
- "pubkey": ,
+ "pubkey": "",
"tags": [
[ "k", 65002 ], // e.g. speech-to-text
[ "t", "bitcoin" ] // e.g. optionally advertises it specializes in bitcoin audio transcription that won't confuse "Drivechains" with "Ridechains"
From 723103506030749fc2bba9d5b4ddaf607dd24da3 Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Tue, 25 Jul 2023 01:29:02 +0300
Subject: [PATCH 016/192] feed-generation kind and some more stuff
---
vending-machine.md | 104 ++++++++++++++++++++++++++++++++-------------
1 file changed, 74 insertions(+), 30 deletions(-)
diff --git a/vending-machine.md b/vending-machine.md
index 276132df..c41ccceb 100644
--- a/vending-machine.md
+++ b/vending-machine.md
@@ -19,7 +19,7 @@ This NIP reserves the range `65000-66000` for data vending machine use.
| 65001 | Job result |
| 65002-66000 | Job request kinds |
-[Appendix 2](#appendix-2-job-types) defines the job types.
+[Appendix 2](#appendix-2-job-types) defines the job request types.
## Rationale
Nostr 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.
@@ -32,19 +32,23 @@ There are two actors in the workflow described in this NIP:
* Service providers (npubs who fulfill jobs)
# Event Kinds
+
+* `kind:65000`: job feedback
+* `kind:65001`: job result
+* `kind:65002`-`kind:66000`: job requests
+
## Job request
-A request to have data processed, published by a customer
+A request to have data processed, published by a customer. This event signals that an npub is interested in receiving the result of some kind of compute.
```json
{
- "kind": xxx, // kind in 65002-66000 range
+ "kind": 65xxx, // kind in 65002-66000 range
"content": "",
"tags": [
[ "i", "", "", "", "" ],
[ "output", "" ],
[ "relays", "wss://..."],
[ "bid", "" ],
- [ "exp", "" ],
[ "t", "bitcoin" ]
]
}
@@ -52,24 +56,25 @@ A request to have data processed, published by a customer
All tags are optional.
-* `i` tag: Input data for the job (zero or more inputs may exist)
+* `i` tag: Input data for the job (zero or more inputs)
* ``: The argument for the input
- * ``: The way this argument should be interpreted, MUST be one of:
+ * ``: The way this argument should be interpreted. MUST be one of:
* `url`: A URL to be fetched
- * `event`: A Nostr event ID, include an optional relay-url extra param
+ * `event`: A Nostr event ID.
* `job`: The output of a previous job with the specified event ID
* `text`: `` is the value of the input, no resolution is needed
* ``: An optional field indicating how this input should be used within the context of the job
* ``: If `event` or `job` input-type, the relay where the event/job was published, otherwise optional or empty string
-* `output`: MIME type. Expected output format. Service Providers SHOULD publish the result of the job in this format if it has been specified
+* `output`: Expected output format. (e.g. MIME type)
+ * Service Providers MUST publish the result of the job in this format if it has been specified.
+ * Each job-type ([Appendix 2](#appendix-2-job-types)) might define the output format more narrowly.
* `bid`: Customer MAY specify a maximum amount (in millisats) they are willing to pay
-* `relays`: Relays where Service Providers SHOULD publish responses to
+* `relays`: List of relays where Service Providers SHOULD publish responses to
* `p`: Service Providers the customer is interested in. Other SPs MIGHT still choose to process the job
-* `exp`: Expiration timestamp. Service Providers SHOULD not send results after this timestamp
## Job result
-The output of processing the data -- published by the Service Provider.
+Service providers publish job results, providing the output of the job result. They should tag the original job request event id as well as the customer's pubkey.
```json
{
@@ -79,28 +84,40 @@ The output of processing the data -- published by the Service Provider.
"tags": [
[ "request", "" ],
[ "e", "", "" ],
- [ "p", "" ],
+ [ "p", "" ],
[ "amount", "requested-payment-amount", "" ]
]
}
```
-* `request` tag: The job request event ID.
+* `request`: The job request event stringified-JSON.
* `amount`: millisats that the Service Provider is requesting to be paid. An optional third value can be a bolt11 invoice.
## Job feedback
-Both customers and service providers can give feedback about a job.
+Service providers can give feedback about a job back to the customer.
-The result of the job SHOULD be included in the `content` field.
+```json
+{
+ "kind": 65000,
+ "content": "",
+ "tags": [
+ [ "status", "", "" ],
+ [ "amount", "requested-payment-amount", "" ],
+ [ "e", "", "" ],
+ [ "p", "" ],
+ ]
+}
+```
-* `status` tag: Service Providers MAY indicate errors or extra info about the results by including them in the `status` tag.
-* `amount`: as defined in the [Job Result](#job-result) section.
+* `content`: Either empty or a job-result (e.g. for partial-result samples)
+* `status` tag: Service Providers SHOULD indicate what this feedback status refers to. [Appendix 3](#appendix-3-job-feedback-status) defines status. Extra human-readable information can be added as an extra argument.
+* `amount` tag: as defined in the [Job Result](#job-result) section.
# Protocol Flow
-* Customer publishes a job request (e.g. `kind:65002`).
+* Customer publishes a job request (e.g. `kind:65002` speech-to-text).
* Service Providers can submit `kind:65000` job-feedback events (e.g. `payment-required`, `processing`, `error`, etc.).
* Upon completion, the service provider publishes the result of the job with a `kind:65001` job-result event.
-* At any point, the user can pay the included `bolt11` or zap any of the events the service provider has sent to the user.
+* At any point, if there is an `amount` pending to be paid as instructed by the service provider, the user can pay the included `bolt11` or zap the job result event the service provider has sent to the user
`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.
@@ -137,16 +154,6 @@ Consult [Appendix 1: Example](#appendix-1-examples)'s [Summarization of a podcas
}
```
-## Not addressed in this NIP
-
-### Reputation system
-Service 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.
-
-### Encrypted job requests
-Not to be included in the first draft of this NIP, but encrypted job requests should be added. A few ways:
- * 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.
-
-
# Appendix 1: Examples
## Transcript of a podcast from second `900` to `930`.
@@ -316,7 +323,7 @@ User publishes event #1 and #2 together.
[ "bid", "500000" ]
]
}
-``
+```
## AI-image of embedded input
@@ -364,6 +371,43 @@ This is a list of all the supported job requests.
| `prompt` | opt | extra prompt to be used for the image generation |
| `size` | opt | desired size of the image |
+## event list generation: `kind:65006`
+
+Generates a list of event ids, (e.g. algorithmic feeds, spam-free notifications, trending topics)
+
+Output should be a stringified array of elements usually find in a nostr event' `tags`, e.g.:
+
+```json
+{ "content": "[
+ [\"e\", \"\"],
+ [\"a\", \"30023:pubkey:id\"],
+ [\"t\", \"tag\"],
+ [\"p\", \"pubkey\"],
+]" }
+```
+
+| param | req? | description |
+|-----------|------|-------------------------------------------------------|
+| `filter` | opt | JSON-stringified `REQ`-like filter
+| `prompt` | opt | A human-readable description of the desired results. Which might be used with e.g. an LLM to tune the results.
+| `p` | opt | Array of pubkeys to generate a feed from someone else's point-of-view. This param allows for a client to choose to generate the feeds and incur the costs of its users.
+
+### example job-request
+
+Generate an algorithmic feed of the most interesting `kind:1`s related to the topic "bitcoin", tagging service providers specializing in safe-for-work content
+that would interest pubkey `pubkey1`.
+
+```json
+{
+ "kind": 65006,
+ "tags": [
+ [ "param", "filter", "{ \"kinds\": [1], \"#t\": [\"bitcoin\"] }" ],
+ [ "param", "p", "[\"pubkey1\"]"]
+ [ "bid", "5000" ],
+ [ "t", "sfw" ]
+ ]
+}
+```
# Appendix 3: Job feedback status
From 948ee24775fe89e779efe7680ca6a27dc5a6207f Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Tue, 25 Jul 2023 17:20:24 +0300
Subject: [PATCH 017/192] rename file
---
vending-machine.md => 90.md | 1 -
README.md | 4 ++++
2 files changed, 4 insertions(+), 1 deletion(-)
rename vending-machine.md => 90.md (99%)
diff --git a/vending-machine.md b/90.md
similarity index 99%
rename from vending-machine.md
rename to 90.md
index c41ccceb..99f313d4 100644
--- a/vending-machine.md
+++ b/90.md
@@ -417,7 +417,6 @@ that would interest pubkey `pubkey1`.
| `processing` | Service Provider is processing the job. |
| `error` | Service Provider was unable to process the job. |
| `success` | Service Provider successfully processed the job. |
-| `failure` | Service Provider failed to process the job. |
| `partial` | Service Provider partially processed the job. The `.content` might include a sample of the partial results. |
Any 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.
diff --git a/README.md b/README.md
index 9893ffcf..ebfd3596 100644
--- a/README.md
+++ b/README.md
@@ -64,6 +64,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
- [NIP-65: Relay List Metadata](65.md)
- [NIP-78: Application-specific data](78.md)
- [NIP-89: Recommended Application Handlers](89.md)
+- [NIP-90: Data Vending Machines](90.md)
- [NIP-94: File Metadata](94.md)
- [NIP-98: HTTP Auth](98.md)
@@ -110,6 +111,8 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `30078` | Application-specific Data | [78](78.md) |
| `31989` | Handler recommendation | [89](89.md) |
| `31990` | Handler information | [89](89.md) |
+| `65000` | Job Feedback | [90](90.md) |
+| `65001` | Job Result | [90](90.md) |
### Event Kind Ranges
@@ -119,6 +122,7 @@ They exist to document what may be implemented by [Nostr](https://github.com/nos
| `10000`--`19999` | Replaceable Events | [16](16.md) |
| `20000`--`29999` | Ephemeral Events | [16](16.md) |
| `30000`--`39999` | Parameterized Replaceable Events | [33](33.md) |
+| `65002`--`66000` | Job Requests | [90](90.md) |
## Message types
From 9fa9045d19b93f4cbac231bff39558108a6e82ae Mon Sep 17 00:00:00 2001
From: pablof7z
Date: Tue, 25 Jul 2023 17:31:31 +0300
Subject: [PATCH 018/192] remove duplicated output
---
90.md | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/90.md b/90.md
index 99f313d4..51c49cf2 100644
--- a/90.md
+++ b/90.md
@@ -168,9 +168,8 @@ Consult [Appendix 1: Example](#appendix-1-examples)'s [Summarization of a podcas
"tags": [
[ "i", "https://bitcoin.review/episode1.mp3", "url" ],
[ "params", "range", "900", "930" ],
- [ "output", "text/vtt" ],
+ [ "output", "text/plain" ],
[ "bid", "50000" ],
- [ "output", "text/plain" ]
]
}
```
@@ -388,7 +387,7 @@ Output should be a stringified array of elements usually find in a nostr event'
| param | req? | description |
|-----------|------|-------------------------------------------------------|
-| `filter` | opt | JSON-stringified `REQ`-like filter
+| `filter` | opt | Stringified JSON `REQ` filter. Used to scope the desired results (e.g. specify the desired kinds)
| `prompt` | opt | A human-readable description of the desired results. Which might be used with e.g. an LLM to tune the results.
| `p` | opt | Array of pubkeys to generate a feed from someone else's point-of-view. This param allows for a client to choose to generate the feeds and incur the costs of its users.
From acafcc774d571867bde615423c758c51dba64fca Mon Sep 17 00:00:00 2001
From: Yasuhiro Matsumoto
Date: Mon, 28 Aug 2023 16:25:43 +0900
Subject: [PATCH 019/192] NIP-38: description for content
---
38.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/38.md b/38.md
index 378da1c5..010c14c3 100644
--- a/38.md
+++ b/38.md
@@ -57,3 +57,5 @@ Clients MAY display this next to the username on posts or profiles to provide li
* Nostr music streaming services that update your music status when you're listening
* Podcasting apps that update your music status when you're listening to a podcast, with a link for others to listen as well
* Clients can use the system media player to update playing music status
+
+The `content` MAY be an emoji, or [NIP-30](30.md) custom emoji. If the `content` is an empty string then the client should clear the status.
From 1aa9301a4a993cf7122ebb7761945d94dc4eadba Mon Sep 17 00:00:00 2001
From: Yasuhiro Matsumoto
Date: Mon, 28 Aug 2023 21:10:07 +0900
Subject: [PATCH 020/192] update 38.md
---
38.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/38.md b/38.md
index 010c14c3..f1eddcd8 100644
--- a/38.md
+++ b/38.md
@@ -58,4 +58,4 @@ Clients MAY display this next to the username on posts or profiles to provide li
* Podcasting apps that update your music status when you're listening to a podcast, with a link for others to listen as well
* Clients can use the system media player to update playing music status
-The `content` MAY be an emoji, or [NIP-30](30.md) custom emoji. If the `content` is an empty string then the client should clear the status.
+The `content` MAY include emoji(s), or [NIP-30](30.md) custom emoji(s). If the `content` is an empty string then the client should clear the status.
From 8aa89367cd66e160b2bc2320362e87b3a4e71eac Mon Sep 17 00:00:00 2001
From: Luis Miguel
Date: Tue, 5 Sep 2023 18:15:14 +0200
Subject: [PATCH 021/192] Micro-typo nip-58
---
58.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/58.md b/58.md
index d6bb27d6..ccabc7b6 100644
--- a/58.md
+++ b/58.md
@@ -11,7 +11,7 @@ user profiles:
1. A "Badge Definition" event is defined as a parameterized replaceable event with kind `30009` having a `d` tag with a value that uniquely identifies the badge (e.g. `bravery`) published by the badge issuer. Badge definitions can be updated.
-2. A "Badge Award" event is a kind `8` event with a single `a` tag referencing a "Define Badge" event and one or more `p` tags, one for each pubkey the badge issuer wishes to award. Awarded badges are immutable and non-transferrable.
+2. A "Badge Award" event is a kind `8` event with a single `a` tag referencing a "Badge Definition" event and one or more `p` tags, one for each pubkey the badge issuer wishes to award. Awarded badges are immutable and non-transferrable.
3. A "Profile Badges" event is defined as a parameterized replaceable event
with kind `30008` with a `d` tag with the value `profile_badges`.
From 74611d2580004e8384b77048a346c2e0b2a47890 Mon Sep 17 00:00:00 2001
From: gsovereignty
Date: Fri, 8 Sep 2023 16:09:02 +0800
Subject: [PATCH 022/192] Spelling and clarifcations
---
98.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/98.md b/98.md
index ecbebc08..c8cba0f5 100644
--- a/98.md
+++ b/98.md
@@ -6,9 +6,9 @@ HTTP Auth
`draft` `optional` `author:kieran` `author:melvincarvalho`
-This NIP defines an ephemerial event used to authorize requests to HTTP servers using nostr events.
+This NIP defines an ephemeral event used to authorize requests to HTTP servers using nostr events.
-This is useful for HTTP services which are build for Nostr and deal with Nostr user accounts.
+This is useful for HTTP services which are built for Nostr and deal with Nostr user accounts.
## Nostr event
@@ -16,7 +16,7 @@ A `kind 27235` (In reference to [RFC 7235](https://www.rfc-editor.org/rfc/rfc723
The `content` SHOULD be empty.
-The following tags are defined as REQUIRED.
+The following tags MUST be included.
* `u` - absolute URL
* `method` - HTTP Request Method
@@ -45,7 +45,7 @@ Example event:
Servers MUST perform the following checks in order to validate the event:
1. The `kind` MUST be `27235`.
-2. The `created_at` MUST be within a reasonable time window (suggestion 60 seconds).
+2. The `created_at` timestamp MUST be within a reasonable time window (suggestion 60 seconds).
3. The `u` tag MUST be exactly the same as the absolute request URL (including query parameters).
4. The `method` tag MUST be the same HTTP method used for the requested resource.
@@ -53,11 +53,11 @@ When the request contains a body (as in POST/PUT/PATCH methods) clients SHOULD i
If one of the checks was to fail the server SHOULD respond with a 401 Unauthorized response code.
-All other checks which server MAY do are OPTIONAL, and implementation specific.
+Servers MAY perform additional implementation-specific validation checks.
## Request Flow
-Using the `Authorization` header, the `kind 27235` event MUST be `base64` encoded and use the Authorization scheme `Nostr`
+Using the `Authorization` HTTP header, the `kind 27235` event MUST be `base64` encoded and use the Authorization scheme `Nostr`
Example HTTP Authorization header:
```
@@ -65,4 +65,4 @@ Authorization: Nostr eyJpZCI6ImZlOTY0ZTc1ODkwMzM2MGYyOGQ4NDI0ZDA5MmRhODQ5NGVkMjA
```
## Reference Implementations
-- C# ASP.NET `AuthenticationHandler` [NostrAuth.cs](https://gist.github.com/v0l/74346ae530896115bfe2504c8cd018d3)
\ No newline at end of file
+- C# ASP.NET `AuthenticationHandler` [NostrAuth.cs](https://gist.github.com/v0l/74346ae530896115bfe2504c8cd018d3)
From c567f2e4d6fa4e79585e83b6e6d9313217295582 Mon Sep 17 00:00:00 2001
From: Tiago Vasconcelos
Date: Fri, 8 Sep 2023 13:10:59 +0100
Subject: [PATCH 023/192] Add description to event 30019 (#768)
---
15.md | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/15.md b/15.md
index 01ef05bf..edece818 100644
--- a/15.md
+++ b/15.md
@@ -220,6 +220,28 @@ The below json goes in `content` of [NIP04](https://github.com/nostr-protocol/ni
"shipped": ,
}
```
+## Customize Marketplace
+Create a customized user experience using the `naddr` from [NIP-19](https://github.com/nostr-protocol/nips/blob/master/19.md#shareable-identifiers-with-extra-metadata). The use of `naddr` enables easy sharing of marketplace events while incorporating a rich set of metadata. This metadata can include relays, merchant profiles, and more. Subsequently, it allows merchants to be grouped into a market, empowering the market creator to configure the marketplace's user interface and user experience, and share that marketplace. This customization can encompass elements such as market name, description, logo, banner, themes, and even color schemes, offering a tailored and unique marketplace experience.
+
+### Event `30019`: Create or update marketplace UI/UX
+
+**Event Content**:
+```json
+{
+ "name": ,
+ "about": ,
+ "ui": {
+ "picture": ,
+ "banner": ,
+ "theme": ,
+ "darkMode":
+ },
+ "merchants": <[String] (optional), array of pubkeys>,
+ ...
+}
+```
+
+This event leverages naddr to enable comprehensive customization and sharing of marketplace configurations, fostering a unique and engaging marketplace environment.
## Customer support events
From e3504024a279ae896394254f08c56a64d6722d97 Mon Sep 17 00:00:00 2001
From: Asai Toshiya
Date: Fri, 8 Sep 2023 21:11:38 +0900
Subject: [PATCH 024/192] Clarify character case of m tag value (#767)
---
94.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/94.md b/94.md
index 24dd346f..c1b322a2 100644
--- a/94.md
+++ b/94.md
@@ -13,7 +13,7 @@ The purpose of this NIP is to allow an organization and classification of shared
This NIP specifies the use of the `1063` event type, having in `content` a description of the file content, and a list of tags described below:
* `url` the url to download the file
-* `m` a string indicating the data type of the file. The MIME types format must be used (https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)
+* `m` a string indicating the data type of the file. The [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) format must be used,Β and they should be lowercase.
* `"aes-256-gcm"` (optional) key and nonce for AES-GCM encryption with tagSize always 128bits
* `x` containing the SHA-256 hexencoded string of the file.
* `size` (optional) size of file in bytes
From 12238ebe2b234b7438864b521c0886471aa351a8 Mon Sep 17 00:00:00 2001
From: Asai Toshiya
Date: Mon, 11 Sep 2023 13:03:32 +0900
Subject: [PATCH 025/192] Remove description about NIP-12
---
52.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/52.md b/52.md
index 846fbf43..f5bd0adb 100644
--- a/52.md
+++ b/52.md
@@ -30,7 +30,7 @@ The list of tags are as follows:
* `start` (required) inclusive start date in ISO 8601 format (YYYY-MM-DD). Must be less than `end`, if it exists.
* `end` (optional) exclusive end date in ISO 8601 format (YYYY-MM-DD). If omitted, the calendar event ends on the same date as `start`.
* `location` (optional) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call
-* `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location as suggested as an example by [NIP-12](12.md)
+* `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location
* `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting
* `t` (optional, repeated) hashtag to categorize calendar event
* `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc.
@@ -88,7 +88,7 @@ The list of tags are as follows:
* `start_tzid` (optional) time zone of the start timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`
* `end_tzid` (optional) time zone of the end timestamp, as defined by the IANA Time Zone Database. e.g., `America/Costa_Rica`. If omitted and `start_tzid` is provided, the time zone of the end timestamp is the same as the start timestamp.
* `location` (optional) location of the calendar event. e.g. address, GPS coordinates, meeting room name, link to video call
-* `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location as suggested as an example by [NIP-12](12.md)
+* `g` (optional) [geohash](https://en.wikipedia.org/wiki/Geohash) to associate calendar event with a searchable physical location
* `p` (optional, repeated) 32-bytes hex pubkey of a participant, optional recommended relay URL, and participant's role in the meeting
* `t` (optional, repeated) hashtag to categorize calendar event
* `r` (optional, repeated) references / links to web pages, documents, video calls, recorded videos, etc.
From 67cf855c8448c78010cd0d3ed8f19ddfeb1d2606 Mon Sep 17 00:00:00 2001
From: arthurfranca
Date: Tue, 12 Sep 2023 09:50:25 -0300
Subject: [PATCH 026/192] Add tags to nip94
---
94.md | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/94.md b/94.md
index c1b322a2..e34a576d 100644
--- a/94.md
+++ b/94.md
@@ -21,6 +21,8 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
* `magnet` (optional) URI to magnet file
* `i` (optional) torrent infohash
* `blurhash`(optional) the [blurhash](https://github.com/woltapp/blurhash) to show while the file is being loaded by the client
+* `preview` (optional) shorter file variant such as thumbnail, blurred image or text excerpt
+* `caption` (optional) loose description not meant for accessibility
```json
{
@@ -37,7 +39,9 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
["dim", ],
["magnet", ],
["i",],
- ["blurhash", ]
+ ["blurhash", ],
+ ["preview", , ],
+ ["caption", ]
],
"content": ,
"sig": <64-bytes hex of the signature of the sha256 hash of the serialized event data, which is the same as the "id" field>
From de15edb04a7b6dc36bc6d5eaba26fb49e54b300e Mon Sep 17 00:00:00 2001
From: arthurfranca
Date: Tue, 12 Sep 2023 10:49:21 -0300
Subject: [PATCH 027/192] Invert caption and alt
---
94.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/94.md b/94.md
index e34a576d..8e47c27d 100644
--- a/94.md
+++ b/94.md
@@ -22,7 +22,7 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
* `i` (optional) torrent infohash
* `blurhash`(optional) the [blurhash](https://github.com/woltapp/blurhash) to show while the file is being loaded by the client
* `preview` (optional) shorter file variant such as thumbnail, blurred image or text excerpt
-* `caption` (optional) loose description not meant for accessibility
+* `alt` (optional) description for accessibility
```json
{
@@ -41,9 +41,9 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
["i",],
["blurhash", ],
["preview", , ],
- ["caption", ]
+ ["alt", ]
],
- "content": ,
+ "content": ,
"sig": <64-bytes hex of the signature of the sha256 hash of the serialized event data, which is the same as the "id" field>
}
```
From 30c799b00148c687b693331cd169c9ed20b93515 Mon Sep 17 00:00:00 2001
From: arthurfranca
Date: Tue, 12 Sep 2023 11:58:34 -0300
Subject: [PATCH 028/192] Expand preview into other tags
---
94.md | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/94.md b/94.md
index 8e47c27d..c5e0f182 100644
--- a/94.md
+++ b/94.md
@@ -21,7 +21,9 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
* `magnet` (optional) URI to magnet file
* `i` (optional) torrent infohash
* `blurhash`(optional) the [blurhash](https://github.com/woltapp/blurhash) to show while the file is being loaded by the client
-* `preview` (optional) shorter file variant such as thumbnail, blurred image or text excerpt
+* `thumb` (optional) url of thumbnail with same aspect ratio
+* `image` (optional) url of preview image with same dimensions
+* `summary` (optional) text excerpt
* `alt` (optional) description for accessibility
```json
@@ -40,7 +42,9 @@ This NIP specifies the use of the `1063` event type, having in `content` a descr
["magnet", ],
["i",],
["blurhash", ],
- ["preview", , ],
+ ["thumb", ],
+ ["image",