@prampta/sdk 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +14 -3
- package/dist/index.mjs +14 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -147,8 +147,11 @@ const decision = await pg.assertLicensed(subjectCode, {
|
|
|
147
147
|
- asks fresh for **every subject in the output** and generates only if
|
|
148
148
|
**all** of them return a licence-backed `allow`;
|
|
149
149
|
- re-checks every allow **immediately before** your `generate` runs;
|
|
150
|
-
-
|
|
151
|
-
|
|
150
|
+
- takes its own copy of the request before doing anything, so changing your
|
|
151
|
+
object afterwards cannot change the job;
|
|
152
|
+
- stores the output hash and the **exact receipts** (signed, if you sign)
|
|
153
|
+
before sending them, and after a failure resends those receipts byte for
|
|
154
|
+
byte — receipt options passed on a later call do not replace them;
|
|
152
155
|
- a receipt counts as filed only when the registry accepted exactly it:
|
|
153
156
|
`unreported` lists receipts to resend (call again with the same id and
|
|
154
157
|
request), `conflicts` lists decisions for which the registry holds a
|
package/dist/index.d.mts
CHANGED
|
@@ -398,8 +398,10 @@ interface GenerationJournalEntry {
|
|
|
398
398
|
stage: "claimed" | "authorized" | "generated" | "reported" | "released";
|
|
399
399
|
decisions: SignedDecision[];
|
|
400
400
|
outputHash?: string;
|
|
401
|
-
/** Kept so a resent receipt is byte-identical to the first. */
|
|
402
401
|
generatedAt?: number;
|
|
402
|
+
/** The exact receipt bodies (signed, if a key was given), stored before the
|
|
403
|
+
* first send and resent unchanged. No private key is stored. */
|
|
404
|
+
receipts?: Record<string, Record<string, unknown>>;
|
|
403
405
|
}
|
|
404
406
|
interface GenerationJournal {
|
|
405
407
|
/** ATOMIC across every worker: store `entry` if no entry exists for its
|
|
@@ -666,6 +668,8 @@ declare class Prampta {
|
|
|
666
668
|
/** 32-byte Ed25519 private key, hex; keep server-side. Never sent to PRAMPTA. */
|
|
667
669
|
providerSigningKeyHex?: string;
|
|
668
670
|
}): Promise<Record<string, unknown>>;
|
|
671
|
+
/** The exact receipt body submitReceipt() would send, signed if a key is given. */
|
|
672
|
+
buildReceipt(decision: SignedDecision, result?: NonNullable<Parameters<Prampta["submitReceipt"]>[1]>): Promise<Record<string, unknown>>;
|
|
669
673
|
/**
|
|
670
674
|
* Get (issuing if needed) the signed `pg.assertion.v1` for a decision this
|
|
671
675
|
* provider/licensee pair already submitted a receipt for — embed it in
|
package/dist/index.d.ts
CHANGED
|
@@ -398,8 +398,10 @@ interface GenerationJournalEntry {
|
|
|
398
398
|
stage: "claimed" | "authorized" | "generated" | "reported" | "released";
|
|
399
399
|
decisions: SignedDecision[];
|
|
400
400
|
outputHash?: string;
|
|
401
|
-
/** Kept so a resent receipt is byte-identical to the first. */
|
|
402
401
|
generatedAt?: number;
|
|
402
|
+
/** The exact receipt bodies (signed, if a key was given), stored before the
|
|
403
|
+
* first send and resent unchanged. No private key is stored. */
|
|
404
|
+
receipts?: Record<string, Record<string, unknown>>;
|
|
403
405
|
}
|
|
404
406
|
interface GenerationJournal {
|
|
405
407
|
/** ATOMIC across every worker: store `entry` if no entry exists for its
|
|
@@ -666,6 +668,8 @@ declare class Prampta {
|
|
|
666
668
|
/** 32-byte Ed25519 private key, hex; keep server-side. Never sent to PRAMPTA. */
|
|
667
669
|
providerSigningKeyHex?: string;
|
|
668
670
|
}): Promise<Record<string, unknown>>;
|
|
671
|
+
/** The exact receipt body submitReceipt() would send, signed if a key is given. */
|
|
672
|
+
buildReceipt(decision: SignedDecision, result?: NonNullable<Parameters<Prampta["submitReceipt"]>[1]>): Promise<Record<string, unknown>>;
|
|
669
673
|
/**
|
|
670
674
|
* Get (issuing if needed) the signed `pg.assertion.v1` for a decision this
|
|
671
675
|
* provider/licensee pair already submitted a receipt for — embed it in
|
package/dist/index.js
CHANGED
|
@@ -1143,6 +1143,7 @@ var Prampta = class _Prampta {
|
|
|
1143
1143
|
* `generate` must throw only when nothing was produced.
|
|
1144
1144
|
*/
|
|
1145
1145
|
async generateAuthorized(request, generate, options) {
|
|
1146
|
+
request = structuredClone(request);
|
|
1146
1147
|
const id = request.generationId;
|
|
1147
1148
|
if (!id) throw new PramptaSchemaError("generateAuthorized requires a generationId");
|
|
1148
1149
|
if (!options?.journal) throw new PramptaSchemaError("generateAuthorized requires a journal (singleProcessJournal() for one process)");
|
|
@@ -1203,12 +1204,18 @@ var Prampta = class _Prampta {
|
|
|
1203
1204
|
}
|
|
1204
1205
|
const bytes = typeof result.outputBytes === "string" ? new TextEncoder().encode(result.outputBytes) : result.outputBytes;
|
|
1205
1206
|
const outputHash = result.outputHash ?? (bytes ? await sha256Bytes(bytes) : "");
|
|
1206
|
-
const
|
|
1207
|
+
const generatedAt = Math.floor(Date.now() / 1e3);
|
|
1208
|
+
const receipts = {};
|
|
1209
|
+
for (const d of decisions) receipts[d.decisionId] = await this.buildReceipt(d, { ...receipt, outputHash, generatedAt });
|
|
1210
|
+
const generated = { ...entry, stage: "generated", outputHash, generatedAt, receipts };
|
|
1207
1211
|
await journal.put(generated);
|
|
1208
1212
|
return this.report(journal, generated, "generated", result.output, receipt);
|
|
1209
1213
|
}
|
|
1210
1214
|
async report(journal, entry, status, output, receipt) {
|
|
1211
|
-
const results = await Promise.allSettled(entry.decisions.map((d) => this.
|
|
1215
|
+
const results = await Promise.allSettled(entry.decisions.map(async (d) => this.post(
|
|
1216
|
+
"/v1/receipts/",
|
|
1217
|
+
entry.receipts?.[d.decisionId] ?? await this.buildReceipt(d, { ...receipt, outputHash: entry.outputHash ?? "", generatedAt: entry.generatedAt })
|
|
1218
|
+
)));
|
|
1212
1219
|
const unreported = [], conflicts = [];
|
|
1213
1220
|
results.forEach((r, i) => {
|
|
1214
1221
|
if (r.status === "fulfilled") return;
|
|
@@ -1275,6 +1282,10 @@ var Prampta = class _Prampta {
|
|
|
1275
1282
|
* provider attestation, not proof of complete reporting or actual execution.
|
|
1276
1283
|
*/
|
|
1277
1284
|
async submitReceipt(decision, result = {}) {
|
|
1285
|
+
return this.post("/v1/receipts/", await this.buildReceipt(decision, result));
|
|
1286
|
+
}
|
|
1287
|
+
/** The exact receipt body submitReceipt() would send, signed if a key is given. */
|
|
1288
|
+
async buildReceipt(decision, result = {}) {
|
|
1278
1289
|
const payload = {
|
|
1279
1290
|
decision_id: decision.decisionId,
|
|
1280
1291
|
prompt_hash: decision.promptHash,
|
|
@@ -1317,7 +1328,7 @@ var Prampta = class _Prampta {
|
|
|
1317
1328
|
} else if (result.eventType && result.eventType !== "output_accepted") {
|
|
1318
1329
|
throw new PramptaError("A non-default eventType requires a provider signing key and pg.receipt.v3");
|
|
1319
1330
|
}
|
|
1320
|
-
return
|
|
1331
|
+
return payload;
|
|
1321
1332
|
}
|
|
1322
1333
|
// ── C2PA bridge (PRE-GEN v1.1 addendum §11) ─────────────────────────────
|
|
1323
1334
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1086,6 +1086,7 @@ var Prampta = class _Prampta {
|
|
|
1086
1086
|
* `generate` must throw only when nothing was produced.
|
|
1087
1087
|
*/
|
|
1088
1088
|
async generateAuthorized(request, generate, options) {
|
|
1089
|
+
request = structuredClone(request);
|
|
1089
1090
|
const id = request.generationId;
|
|
1090
1091
|
if (!id) throw new PramptaSchemaError("generateAuthorized requires a generationId");
|
|
1091
1092
|
if (!options?.journal) throw new PramptaSchemaError("generateAuthorized requires a journal (singleProcessJournal() for one process)");
|
|
@@ -1146,12 +1147,18 @@ var Prampta = class _Prampta {
|
|
|
1146
1147
|
}
|
|
1147
1148
|
const bytes = typeof result.outputBytes === "string" ? new TextEncoder().encode(result.outputBytes) : result.outputBytes;
|
|
1148
1149
|
const outputHash = result.outputHash ?? (bytes ? await sha256Bytes(bytes) : "");
|
|
1149
|
-
const
|
|
1150
|
+
const generatedAt = Math.floor(Date.now() / 1e3);
|
|
1151
|
+
const receipts = {};
|
|
1152
|
+
for (const d of decisions) receipts[d.decisionId] = await this.buildReceipt(d, { ...receipt, outputHash, generatedAt });
|
|
1153
|
+
const generated = { ...entry, stage: "generated", outputHash, generatedAt, receipts };
|
|
1150
1154
|
await journal.put(generated);
|
|
1151
1155
|
return this.report(journal, generated, "generated", result.output, receipt);
|
|
1152
1156
|
}
|
|
1153
1157
|
async report(journal, entry, status, output, receipt) {
|
|
1154
|
-
const results = await Promise.allSettled(entry.decisions.map((d) => this.
|
|
1158
|
+
const results = await Promise.allSettled(entry.decisions.map(async (d) => this.post(
|
|
1159
|
+
"/v1/receipts/",
|
|
1160
|
+
entry.receipts?.[d.decisionId] ?? await this.buildReceipt(d, { ...receipt, outputHash: entry.outputHash ?? "", generatedAt: entry.generatedAt })
|
|
1161
|
+
)));
|
|
1155
1162
|
const unreported = [], conflicts = [];
|
|
1156
1163
|
results.forEach((r, i) => {
|
|
1157
1164
|
if (r.status === "fulfilled") return;
|
|
@@ -1218,6 +1225,10 @@ var Prampta = class _Prampta {
|
|
|
1218
1225
|
* provider attestation, not proof of complete reporting or actual execution.
|
|
1219
1226
|
*/
|
|
1220
1227
|
async submitReceipt(decision, result = {}) {
|
|
1228
|
+
return this.post("/v1/receipts/", await this.buildReceipt(decision, result));
|
|
1229
|
+
}
|
|
1230
|
+
/** The exact receipt body submitReceipt() would send, signed if a key is given. */
|
|
1231
|
+
async buildReceipt(decision, result = {}) {
|
|
1221
1232
|
const payload = {
|
|
1222
1233
|
decision_id: decision.decisionId,
|
|
1223
1234
|
prompt_hash: decision.promptHash,
|
|
@@ -1260,7 +1271,7 @@ var Prampta = class _Prampta {
|
|
|
1260
1271
|
} else if (result.eventType && result.eventType !== "output_accepted") {
|
|
1261
1272
|
throw new PramptaError("A non-default eventType requires a provider signing key and pg.receipt.v3");
|
|
1262
1273
|
}
|
|
1263
|
-
return
|
|
1274
|
+
return payload;
|
|
1264
1275
|
}
|
|
1265
1276
|
// ── C2PA bridge (PRE-GEN v1.1 addendum §11) ─────────────────────────────
|
|
1266
1277
|
/**
|