@prampta/sdk 0.3.1 → 0.4.0
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/LICENSE +202 -0
- package/README.md +91 -229
- package/dist/index.d.mts +316 -0
- package/dist/index.d.ts +316 -3
- package/dist/index.js +707 -2
- package/dist/index.mjs +657 -0
- package/package.json +28 -46
- package/dist/client.d.ts +0 -75
- package/dist/client.d.ts.map +0 -1
- package/dist/client.js +0 -221
- package/dist/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/mcp.d.ts +0 -3
- package/dist/mcp.d.ts.map +0 -1
- package/dist/mcp.js +0 -324
- package/dist/mcp.js.map +0 -1
- package/dist/types.d.ts +0 -60
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PRAMPTA SDK for TypeScript / Node.js
|
|
3
|
+
*
|
|
4
|
+
* Pre-generation authorization for AI content.
|
|
5
|
+
* Verifies operator Ed25519 signatures on decisions — not a blind HTTP wrapper.
|
|
6
|
+
*
|
|
7
|
+
* @example Basic verification
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Prampta } from "@prampta/sdk";
|
|
10
|
+
*
|
|
11
|
+
* const pg = new Prampta({
|
|
12
|
+
* baseUrl: "https://api2.prampta.com",
|
|
13
|
+
* providerId: "my-ai-service",
|
|
14
|
+
* licenseeId: "acme-corp",
|
|
15
|
+
* token: "pair-token",
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Throws if denied — fail-closed by default
|
|
19
|
+
* await pg.assertAllowed("leonardo-da-vinci", {
|
|
20
|
+
* prompt: "Da Vinci in a documentary",
|
|
21
|
+
* modality: "image",
|
|
22
|
+
* model: "gpt-image-1",
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
interface PramptaConfig {
|
|
27
|
+
/** The PRAMPTA registry URL. Falls back to PRAMPTA_BASE_URL env var. */
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
/** Your provider ID. Falls back to PRAMPTA_PROVIDER_ID env var. */
|
|
30
|
+
providerId?: string;
|
|
31
|
+
/** The licensee ID. Falls back to PRAMPTA_LICENSEE_ID env var. */
|
|
32
|
+
licenseeId?: string;
|
|
33
|
+
/** The pair authentication token. Falls back to PRAMPTA_TOKEN env var. */
|
|
34
|
+
token?: string;
|
|
35
|
+
/** Request timeout in milliseconds (default 3000). */
|
|
36
|
+
timeoutMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Max retry attempts for transient failures (network errors, timeouts,
|
|
39
|
+
* HTTP 429, and 5xx). Default 2 (so up to 3 total attempts). Set 0 to disable.
|
|
40
|
+
* Retries use exponential backoff. Non-transient errors (4xx other than 429,
|
|
41
|
+
* refusals, signature/schema errors) are never retried.
|
|
42
|
+
*/
|
|
43
|
+
maxRetries?: number;
|
|
44
|
+
/** Base backoff in ms between retries; doubles each attempt. Default 200. */
|
|
45
|
+
retryBackoffMs?: number;
|
|
46
|
+
/** If true (default), deny on backend errors/timeouts. */
|
|
47
|
+
failClosed?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Pinned operator public key(s), hex — the trust anchor for signature
|
|
50
|
+
* verification. Obtain out of band (PRAMPTA docs), not from the API that
|
|
51
|
+
* serves decisions. Pass one, or several (comma/space separated) to pin the
|
|
52
|
+
* current + next key and rotate with zero downtime. Falls back to
|
|
53
|
+
* PRAMPTA_OPERATOR_PUBLIC_KEY. If omitted, verification runs in
|
|
54
|
+
* trust-on-first-use mode (a warning is emitted) — do not do this in prod.
|
|
55
|
+
*/
|
|
56
|
+
operatorPublicKeyHex?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Monitor mode: when false, refusals do NOT block generation — the SDK still
|
|
59
|
+
* verifies and records a signed decision, but assertAllowed / withAuthorization
|
|
60
|
+
* proceed instead of throwing. Use for a pilot rollout. Default true.
|
|
61
|
+
*/
|
|
62
|
+
enforce?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* If true (default), verify operator signature on every decision.
|
|
65
|
+
* Set to false ONLY for local development — never in production.
|
|
66
|
+
*/
|
|
67
|
+
verifyDecisionSignature?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface VerifyRequest {
|
|
70
|
+
/** Subject to verify authorization for. */
|
|
71
|
+
subjectId: string;
|
|
72
|
+
/** Raw prompt text — will be hashed, never sent to PRAMPTA. */
|
|
73
|
+
prompt?: string;
|
|
74
|
+
/** Pre-computed SHA-256 hash. Use instead of prompt if you've already hashed. */
|
|
75
|
+
promptHash?: string;
|
|
76
|
+
/** Generation modality: "image", "video", "audio", "text", "3d". */
|
|
77
|
+
modality?: string;
|
|
78
|
+
/** The AI model being used. */
|
|
79
|
+
model?: string;
|
|
80
|
+
/** Intended use metadata. */
|
|
81
|
+
intendedUse?: {
|
|
82
|
+
channel?: string;
|
|
83
|
+
productName?: string;
|
|
84
|
+
projectName?: string;
|
|
85
|
+
categories?: string[];
|
|
86
|
+
territory?: string;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Options for the flat `pg.verify(subjectId, options)` convenience call. */
|
|
90
|
+
interface VerifyOptions extends Omit<VerifyRequest, "subjectId"> {
|
|
91
|
+
categories?: string[];
|
|
92
|
+
channel?: string;
|
|
93
|
+
productName?: string;
|
|
94
|
+
projectName?: string;
|
|
95
|
+
territory?: string;
|
|
96
|
+
}
|
|
97
|
+
interface SignedDecision {
|
|
98
|
+
schemaVersion: string;
|
|
99
|
+
decisionId: string;
|
|
100
|
+
allowed: boolean;
|
|
101
|
+
reason: string | null;
|
|
102
|
+
subjectId: string;
|
|
103
|
+
licenseeId: string;
|
|
104
|
+
providerId: string;
|
|
105
|
+
licenseId: string | null;
|
|
106
|
+
promptHash: string;
|
|
107
|
+
model: string;
|
|
108
|
+
modality: string;
|
|
109
|
+
intendedUse: Record<string, unknown>;
|
|
110
|
+
obligations: Record<string, unknown>;
|
|
111
|
+
rulesText: string;
|
|
112
|
+
rulesTextHash: string;
|
|
113
|
+
watermarkPayload: string | null;
|
|
114
|
+
isHardRefusal: boolean;
|
|
115
|
+
issuedAt: number;
|
|
116
|
+
expiresAt: number;
|
|
117
|
+
operatorKeyId: string;
|
|
118
|
+
operatorSignature: string;
|
|
119
|
+
/** Strongest authority backing the subject: self | agency_asserted |
|
|
120
|
+
* consented | verified. "self" is only the registrant's own claim. */
|
|
121
|
+
subjectAuthority: string;
|
|
122
|
+
denied: boolean;
|
|
123
|
+
}
|
|
124
|
+
interface SubjectInfo {
|
|
125
|
+
subjectId: string;
|
|
126
|
+
status: string;
|
|
127
|
+
visibility: string;
|
|
128
|
+
rulesText: string;
|
|
129
|
+
aliases: string[];
|
|
130
|
+
publicKeyHex?: string;
|
|
131
|
+
publicKeyFingerprint?: string;
|
|
132
|
+
registeredAt: string;
|
|
133
|
+
}
|
|
134
|
+
interface LicenseRequestInput {
|
|
135
|
+
subjectId: string;
|
|
136
|
+
useCase: "commercial" | "editorial" | "personal" | "educational" | "research";
|
|
137
|
+
purpose?: string;
|
|
138
|
+
durationDays?: number;
|
|
139
|
+
message?: string;
|
|
140
|
+
}
|
|
141
|
+
interface LicenseRequestResult {
|
|
142
|
+
requestId: string;
|
|
143
|
+
status: string;
|
|
144
|
+
}
|
|
145
|
+
interface OutputMetadata {
|
|
146
|
+
prampta_decision_id: string;
|
|
147
|
+
prampta_license_id: string | null;
|
|
148
|
+
prampta_watermark: string | null;
|
|
149
|
+
prampta_obligations: Record<string, unknown>;
|
|
150
|
+
prampta_issued_at: number;
|
|
151
|
+
}
|
|
152
|
+
declare class PramptaError extends Error {
|
|
153
|
+
constructor(message: string);
|
|
154
|
+
}
|
|
155
|
+
declare class PramptaNetworkError extends PramptaError {
|
|
156
|
+
readonly cause_: unknown;
|
|
157
|
+
constructor(cause_: unknown);
|
|
158
|
+
}
|
|
159
|
+
declare class PramptaTimeoutError extends PramptaError {
|
|
160
|
+
readonly timeoutMs: number;
|
|
161
|
+
constructor(timeoutMs: number);
|
|
162
|
+
}
|
|
163
|
+
declare class PramptaApiError extends PramptaError {
|
|
164
|
+
readonly status: number;
|
|
165
|
+
readonly detail: string;
|
|
166
|
+
constructor(status: number, detail: string);
|
|
167
|
+
}
|
|
168
|
+
declare class PramptaSchemaError extends PramptaError {
|
|
169
|
+
constructor(message: string);
|
|
170
|
+
}
|
|
171
|
+
/** Operator signature verification failed — decision cannot be trusted. */
|
|
172
|
+
declare class PramptaSignatureError extends PramptaError {
|
|
173
|
+
constructor(message: string);
|
|
174
|
+
}
|
|
175
|
+
declare class PramptaRefusalError extends PramptaError {
|
|
176
|
+
readonly decision: SignedDecision;
|
|
177
|
+
constructor(decision: SignedDecision);
|
|
178
|
+
get reason(): string;
|
|
179
|
+
get isHardRefusal(): boolean;
|
|
180
|
+
get decisionId(): string;
|
|
181
|
+
get licenseId(): string | null;
|
|
182
|
+
}
|
|
183
|
+
declare class PramptaFailClosedError extends PramptaError {
|
|
184
|
+
readonly cause_: unknown;
|
|
185
|
+
constructor(cause_: unknown);
|
|
186
|
+
}
|
|
187
|
+
declare const REFUSAL_DESCRIPTIONS: Record<string, string>;
|
|
188
|
+
declare const HARD_REFUSAL_CODES: Set<string>;
|
|
189
|
+
declare const SOFT_REFUSAL_CODES: Set<string>;
|
|
190
|
+
/** SHA-256 of a prompt — what a decision gets bound to. Standalone twin of
|
|
191
|
+
* `Prampta.hashPrompt` so it can be imported directly. */
|
|
192
|
+
declare function hashPrompt(prompt: string): Promise<string>;
|
|
193
|
+
/**
|
|
194
|
+
* Canonical JSON — deterministic serialization matching Python's
|
|
195
|
+
* `json.dumps(obj, sort_keys=True, separators=(",",":"), ensure_ascii=False)`.
|
|
196
|
+
* Required for signature verification across languages.
|
|
197
|
+
*
|
|
198
|
+
* Exported so external verifiers can rebuild signed bodies and so the
|
|
199
|
+
* cross-implementation spec test vectors (spec/test-vectors) can pin it.
|
|
200
|
+
* Field names in signed protocol bodies are ASCII by construction — key
|
|
201
|
+
* sorting is identical to Python's code-point sort in that range.
|
|
202
|
+
*/
|
|
203
|
+
declare function canonicalJson(obj: unknown): string;
|
|
204
|
+
/** One entry of the /v1/subjects/index detection index. */
|
|
205
|
+
interface SubjectIndexEntry {
|
|
206
|
+
subject_id: string;
|
|
207
|
+
aliases: string[];
|
|
208
|
+
status: string;
|
|
209
|
+
visibility: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Canonical normalization for subject matching: lowercase, strip Latin
|
|
213
|
+
* diacritics, de-leet, -/_ → space, strip punctuation, collapse whitespace.
|
|
214
|
+
* Must stay behaviorally identical to the Python SDK's normalize_for_match.
|
|
215
|
+
*/
|
|
216
|
+
declare function normalizeForMatch(text: string): string;
|
|
217
|
+
/**
|
|
218
|
+
* Detect which index entries are mentioned in `text`. Whole-word phrase
|
|
219
|
+
* containment, plus a squeezed-substring fallback (min length) that defeats
|
|
220
|
+
* letter-spacing ("a d a") and concatenation ("AdaLovelace"). Baseline layer —
|
|
221
|
+
* text only; image/voice detection is provider-side perceptual work.
|
|
222
|
+
*/
|
|
223
|
+
declare function matchSubjects(text: string, entries: SubjectIndexEntry[]): SubjectIndexEntry[];
|
|
224
|
+
declare class Prampta {
|
|
225
|
+
private readonly baseUrl;
|
|
226
|
+
private readonly providerId;
|
|
227
|
+
private readonly licenseeId;
|
|
228
|
+
private readonly token;
|
|
229
|
+
private readonly timeoutMs;
|
|
230
|
+
private readonly maxRetries;
|
|
231
|
+
private readonly retryBackoffMs;
|
|
232
|
+
private readonly failClosed;
|
|
233
|
+
private readonly verifySignature;
|
|
234
|
+
private readonly enforce;
|
|
235
|
+
private pinnedKeys;
|
|
236
|
+
private keySetCache;
|
|
237
|
+
private keySetPromise;
|
|
238
|
+
private tofuWarned;
|
|
239
|
+
constructor(config?: PramptaConfig);
|
|
240
|
+
/** Fetch /keys and check it is self-signed by its current key. Cached. */
|
|
241
|
+
private fetchVerifiedKeySet;
|
|
242
|
+
/**
|
|
243
|
+
* Public key hex to verify a decision signed by `keyId`, enforcing the
|
|
244
|
+
* pinning trust model. A pinned match returns immediately (no network); an
|
|
245
|
+
* unpinned key id fails closed in pinned mode; unpinned/TOFU mode resolves
|
|
246
|
+
* from the self-consistent /keys set with a warning.
|
|
247
|
+
*/
|
|
248
|
+
private resolveOperatorKey;
|
|
249
|
+
private subjectIndexEntries;
|
|
250
|
+
private subjectIndexFetchedAt;
|
|
251
|
+
private static readonly SUBJECT_INDEX_TTL_MS;
|
|
252
|
+
/** Fetch the raw subject detection index (/v1/subjects/index). */
|
|
253
|
+
fetchSubjectIndex(): Promise<{
|
|
254
|
+
version: number;
|
|
255
|
+
count: number;
|
|
256
|
+
subjects: SubjectIndexEntry[];
|
|
257
|
+
}>;
|
|
258
|
+
/**
|
|
259
|
+
* Detect registered subjects mentioned in `text`, using a TTL-cached
|
|
260
|
+
* copy of the subject index. Call verify()/assertAllowed() per hit.
|
|
261
|
+
*/
|
|
262
|
+
matchSubjects(text: string, opts?: {
|
|
263
|
+
forceRefresh?: boolean;
|
|
264
|
+
}): Promise<SubjectIndexEntry[]>;
|
|
265
|
+
/**
|
|
266
|
+
* Verify operator Ed25519 signature over decision body.
|
|
267
|
+
* Fails closed on any error.
|
|
268
|
+
*/
|
|
269
|
+
private verifyDecision;
|
|
270
|
+
/**
|
|
271
|
+
* Verify that the signed decision is bound to the correct request context.
|
|
272
|
+
* Prevents replay attacks where a valid decision for one context is used in another.
|
|
273
|
+
*/
|
|
274
|
+
private verifyContextBinding;
|
|
275
|
+
verifyGeneration(request: VerifyRequest): Promise<SignedDecision>;
|
|
276
|
+
/** Flat convenience API mirroring the Python SDK: intended-use fields
|
|
277
|
+
* (categories, channel, productName, …) are accepted at the top level.
|
|
278
|
+
* Either `prompt` or `promptHash` is REQUIRED — decisions are bound to
|
|
279
|
+
* the prompt hash and the SDK refuses to request unbound ones. */
|
|
280
|
+
verify(subjectId: string, options?: VerifyOptions): Promise<SignedDecision>;
|
|
281
|
+
assertAllowed(subjectId: string, options?: Omit<VerifyRequest, "subjectId">): Promise<SignedDecision>;
|
|
282
|
+
withAuthorization<T>(request: VerifyRequest, generateFn: (decision: SignedDecision) => Promise<T>): Promise<{
|
|
283
|
+
output: T;
|
|
284
|
+
decision: SignedDecision;
|
|
285
|
+
metadata: OutputMetadata;
|
|
286
|
+
}>;
|
|
287
|
+
getSubject(subjectId: string): Promise<SubjectInfo | null>;
|
|
288
|
+
requestLicense(input: LicenseRequestInput): Promise<LicenseRequestResult>;
|
|
289
|
+
createOutputMetadata(decision: SignedDecision): OutputMetadata;
|
|
290
|
+
/**
|
|
291
|
+
* Submit a generation receipt AFTER generating — the provider's enforcement
|
|
292
|
+
* proof, bound to the decision it acted on. Records that this generation was
|
|
293
|
+
* authorized and executed under the decision's terms (verifiable post-hoc).
|
|
294
|
+
*/
|
|
295
|
+
submitReceipt(decision: SignedDecision, result?: {
|
|
296
|
+
outputHash?: string;
|
|
297
|
+
model?: string;
|
|
298
|
+
watermarkEmbedded?: boolean;
|
|
299
|
+
obligationsApplied?: Record<string, unknown>;
|
|
300
|
+
generatedAt?: number;
|
|
301
|
+
}): Promise<Record<string, unknown>>;
|
|
302
|
+
health(): Promise<boolean>;
|
|
303
|
+
version(): Promise<Record<string, unknown>>;
|
|
304
|
+
static hashPrompt(prompt: string): Promise<string>;
|
|
305
|
+
private parseDecision;
|
|
306
|
+
private headers;
|
|
307
|
+
/** Transient errors worth retrying: connectivity, timeout, 429, and 5xx. */
|
|
308
|
+
private isRetryable;
|
|
309
|
+
private withRetry;
|
|
310
|
+
private post;
|
|
311
|
+
private postOnce;
|
|
312
|
+
private get;
|
|
313
|
+
private getOnce;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export { HARD_REFUSAL_CODES, type LicenseRequestInput, type LicenseRequestResult, type OutputMetadata, Prampta, PramptaApiError, type PramptaConfig, PramptaError, PramptaFailClosedError, PramptaNetworkError, PramptaRefusalError, PramptaSchemaError, PramptaSignatureError, PramptaTimeoutError, REFUSAL_DESCRIPTIONS, SOFT_REFUSAL_CODES, type SignedDecision, type SubjectIndexEntry, type SubjectInfo, type VerifyOptions, type VerifyRequest, canonicalJson, hashPrompt, matchSubjects, normalizeForMatch };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,316 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* PRAMPTA SDK for TypeScript / Node.js
|
|
3
|
+
*
|
|
4
|
+
* Pre-generation authorization for AI content.
|
|
5
|
+
* Verifies operator Ed25519 signatures on decisions — not a blind HTTP wrapper.
|
|
6
|
+
*
|
|
7
|
+
* @example Basic verification
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Prampta } from "@prampta/sdk";
|
|
10
|
+
*
|
|
11
|
+
* const pg = new Prampta({
|
|
12
|
+
* baseUrl: "https://api2.prampta.com",
|
|
13
|
+
* providerId: "my-ai-service",
|
|
14
|
+
* licenseeId: "acme-corp",
|
|
15
|
+
* token: "pair-token",
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* // Throws if denied — fail-closed by default
|
|
19
|
+
* await pg.assertAllowed("leonardo-da-vinci", {
|
|
20
|
+
* prompt: "Da Vinci in a documentary",
|
|
21
|
+
* modality: "image",
|
|
22
|
+
* model: "gpt-image-1",
|
|
23
|
+
* });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
interface PramptaConfig {
|
|
27
|
+
/** The PRAMPTA registry URL. Falls back to PRAMPTA_BASE_URL env var. */
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
/** Your provider ID. Falls back to PRAMPTA_PROVIDER_ID env var. */
|
|
30
|
+
providerId?: string;
|
|
31
|
+
/** The licensee ID. Falls back to PRAMPTA_LICENSEE_ID env var. */
|
|
32
|
+
licenseeId?: string;
|
|
33
|
+
/** The pair authentication token. Falls back to PRAMPTA_TOKEN env var. */
|
|
34
|
+
token?: string;
|
|
35
|
+
/** Request timeout in milliseconds (default 3000). */
|
|
36
|
+
timeoutMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Max retry attempts for transient failures (network errors, timeouts,
|
|
39
|
+
* HTTP 429, and 5xx). Default 2 (so up to 3 total attempts). Set 0 to disable.
|
|
40
|
+
* Retries use exponential backoff. Non-transient errors (4xx other than 429,
|
|
41
|
+
* refusals, signature/schema errors) are never retried.
|
|
42
|
+
*/
|
|
43
|
+
maxRetries?: number;
|
|
44
|
+
/** Base backoff in ms between retries; doubles each attempt. Default 200. */
|
|
45
|
+
retryBackoffMs?: number;
|
|
46
|
+
/** If true (default), deny on backend errors/timeouts. */
|
|
47
|
+
failClosed?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Pinned operator public key(s), hex — the trust anchor for signature
|
|
50
|
+
* verification. Obtain out of band (PRAMPTA docs), not from the API that
|
|
51
|
+
* serves decisions. Pass one, or several (comma/space separated) to pin the
|
|
52
|
+
* current + next key and rotate with zero downtime. Falls back to
|
|
53
|
+
* PRAMPTA_OPERATOR_PUBLIC_KEY. If omitted, verification runs in
|
|
54
|
+
* trust-on-first-use mode (a warning is emitted) — do not do this in prod.
|
|
55
|
+
*/
|
|
56
|
+
operatorPublicKeyHex?: string;
|
|
57
|
+
/**
|
|
58
|
+
* Monitor mode: when false, refusals do NOT block generation — the SDK still
|
|
59
|
+
* verifies and records a signed decision, but assertAllowed / withAuthorization
|
|
60
|
+
* proceed instead of throwing. Use for a pilot rollout. Default true.
|
|
61
|
+
*/
|
|
62
|
+
enforce?: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* If true (default), verify operator signature on every decision.
|
|
65
|
+
* Set to false ONLY for local development — never in production.
|
|
66
|
+
*/
|
|
67
|
+
verifyDecisionSignature?: boolean;
|
|
68
|
+
}
|
|
69
|
+
interface VerifyRequest {
|
|
70
|
+
/** Subject to verify authorization for. */
|
|
71
|
+
subjectId: string;
|
|
72
|
+
/** Raw prompt text — will be hashed, never sent to PRAMPTA. */
|
|
73
|
+
prompt?: string;
|
|
74
|
+
/** Pre-computed SHA-256 hash. Use instead of prompt if you've already hashed. */
|
|
75
|
+
promptHash?: string;
|
|
76
|
+
/** Generation modality: "image", "video", "audio", "text", "3d". */
|
|
77
|
+
modality?: string;
|
|
78
|
+
/** The AI model being used. */
|
|
79
|
+
model?: string;
|
|
80
|
+
/** Intended use metadata. */
|
|
81
|
+
intendedUse?: {
|
|
82
|
+
channel?: string;
|
|
83
|
+
productName?: string;
|
|
84
|
+
projectName?: string;
|
|
85
|
+
categories?: string[];
|
|
86
|
+
territory?: string;
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** Options for the flat `pg.verify(subjectId, options)` convenience call. */
|
|
90
|
+
interface VerifyOptions extends Omit<VerifyRequest, "subjectId"> {
|
|
91
|
+
categories?: string[];
|
|
92
|
+
channel?: string;
|
|
93
|
+
productName?: string;
|
|
94
|
+
projectName?: string;
|
|
95
|
+
territory?: string;
|
|
96
|
+
}
|
|
97
|
+
interface SignedDecision {
|
|
98
|
+
schemaVersion: string;
|
|
99
|
+
decisionId: string;
|
|
100
|
+
allowed: boolean;
|
|
101
|
+
reason: string | null;
|
|
102
|
+
subjectId: string;
|
|
103
|
+
licenseeId: string;
|
|
104
|
+
providerId: string;
|
|
105
|
+
licenseId: string | null;
|
|
106
|
+
promptHash: string;
|
|
107
|
+
model: string;
|
|
108
|
+
modality: string;
|
|
109
|
+
intendedUse: Record<string, unknown>;
|
|
110
|
+
obligations: Record<string, unknown>;
|
|
111
|
+
rulesText: string;
|
|
112
|
+
rulesTextHash: string;
|
|
113
|
+
watermarkPayload: string | null;
|
|
114
|
+
isHardRefusal: boolean;
|
|
115
|
+
issuedAt: number;
|
|
116
|
+
expiresAt: number;
|
|
117
|
+
operatorKeyId: string;
|
|
118
|
+
operatorSignature: string;
|
|
119
|
+
/** Strongest authority backing the subject: self | agency_asserted |
|
|
120
|
+
* consented | verified. "self" is only the registrant's own claim. */
|
|
121
|
+
subjectAuthority: string;
|
|
122
|
+
denied: boolean;
|
|
123
|
+
}
|
|
124
|
+
interface SubjectInfo {
|
|
125
|
+
subjectId: string;
|
|
126
|
+
status: string;
|
|
127
|
+
visibility: string;
|
|
128
|
+
rulesText: string;
|
|
129
|
+
aliases: string[];
|
|
130
|
+
publicKeyHex?: string;
|
|
131
|
+
publicKeyFingerprint?: string;
|
|
132
|
+
registeredAt: string;
|
|
133
|
+
}
|
|
134
|
+
interface LicenseRequestInput {
|
|
135
|
+
subjectId: string;
|
|
136
|
+
useCase: "commercial" | "editorial" | "personal" | "educational" | "research";
|
|
137
|
+
purpose?: string;
|
|
138
|
+
durationDays?: number;
|
|
139
|
+
message?: string;
|
|
140
|
+
}
|
|
141
|
+
interface LicenseRequestResult {
|
|
142
|
+
requestId: string;
|
|
143
|
+
status: string;
|
|
144
|
+
}
|
|
145
|
+
interface OutputMetadata {
|
|
146
|
+
prampta_decision_id: string;
|
|
147
|
+
prampta_license_id: string | null;
|
|
148
|
+
prampta_watermark: string | null;
|
|
149
|
+
prampta_obligations: Record<string, unknown>;
|
|
150
|
+
prampta_issued_at: number;
|
|
151
|
+
}
|
|
152
|
+
declare class PramptaError extends Error {
|
|
153
|
+
constructor(message: string);
|
|
154
|
+
}
|
|
155
|
+
declare class PramptaNetworkError extends PramptaError {
|
|
156
|
+
readonly cause_: unknown;
|
|
157
|
+
constructor(cause_: unknown);
|
|
158
|
+
}
|
|
159
|
+
declare class PramptaTimeoutError extends PramptaError {
|
|
160
|
+
readonly timeoutMs: number;
|
|
161
|
+
constructor(timeoutMs: number);
|
|
162
|
+
}
|
|
163
|
+
declare class PramptaApiError extends PramptaError {
|
|
164
|
+
readonly status: number;
|
|
165
|
+
readonly detail: string;
|
|
166
|
+
constructor(status: number, detail: string);
|
|
167
|
+
}
|
|
168
|
+
declare class PramptaSchemaError extends PramptaError {
|
|
169
|
+
constructor(message: string);
|
|
170
|
+
}
|
|
171
|
+
/** Operator signature verification failed — decision cannot be trusted. */
|
|
172
|
+
declare class PramptaSignatureError extends PramptaError {
|
|
173
|
+
constructor(message: string);
|
|
174
|
+
}
|
|
175
|
+
declare class PramptaRefusalError extends PramptaError {
|
|
176
|
+
readonly decision: SignedDecision;
|
|
177
|
+
constructor(decision: SignedDecision);
|
|
178
|
+
get reason(): string;
|
|
179
|
+
get isHardRefusal(): boolean;
|
|
180
|
+
get decisionId(): string;
|
|
181
|
+
get licenseId(): string | null;
|
|
182
|
+
}
|
|
183
|
+
declare class PramptaFailClosedError extends PramptaError {
|
|
184
|
+
readonly cause_: unknown;
|
|
185
|
+
constructor(cause_: unknown);
|
|
186
|
+
}
|
|
187
|
+
declare const REFUSAL_DESCRIPTIONS: Record<string, string>;
|
|
188
|
+
declare const HARD_REFUSAL_CODES: Set<string>;
|
|
189
|
+
declare const SOFT_REFUSAL_CODES: Set<string>;
|
|
190
|
+
/** SHA-256 of a prompt — what a decision gets bound to. Standalone twin of
|
|
191
|
+
* `Prampta.hashPrompt` so it can be imported directly. */
|
|
192
|
+
declare function hashPrompt(prompt: string): Promise<string>;
|
|
193
|
+
/**
|
|
194
|
+
* Canonical JSON — deterministic serialization matching Python's
|
|
195
|
+
* `json.dumps(obj, sort_keys=True, separators=(",",":"), ensure_ascii=False)`.
|
|
196
|
+
* Required for signature verification across languages.
|
|
197
|
+
*
|
|
198
|
+
* Exported so external verifiers can rebuild signed bodies and so the
|
|
199
|
+
* cross-implementation spec test vectors (spec/test-vectors) can pin it.
|
|
200
|
+
* Field names in signed protocol bodies are ASCII by construction — key
|
|
201
|
+
* sorting is identical to Python's code-point sort in that range.
|
|
202
|
+
*/
|
|
203
|
+
declare function canonicalJson(obj: unknown): string;
|
|
204
|
+
/** One entry of the /v1/subjects/index detection index. */
|
|
205
|
+
interface SubjectIndexEntry {
|
|
206
|
+
subject_id: string;
|
|
207
|
+
aliases: string[];
|
|
208
|
+
status: string;
|
|
209
|
+
visibility: string;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Canonical normalization for subject matching: lowercase, strip Latin
|
|
213
|
+
* diacritics, de-leet, -/_ → space, strip punctuation, collapse whitespace.
|
|
214
|
+
* Must stay behaviorally identical to the Python SDK's normalize_for_match.
|
|
215
|
+
*/
|
|
216
|
+
declare function normalizeForMatch(text: string): string;
|
|
217
|
+
/**
|
|
218
|
+
* Detect which index entries are mentioned in `text`. Whole-word phrase
|
|
219
|
+
* containment, plus a squeezed-substring fallback (min length) that defeats
|
|
220
|
+
* letter-spacing ("a d a") and concatenation ("AdaLovelace"). Baseline layer —
|
|
221
|
+
* text only; image/voice detection is provider-side perceptual work.
|
|
222
|
+
*/
|
|
223
|
+
declare function matchSubjects(text: string, entries: SubjectIndexEntry[]): SubjectIndexEntry[];
|
|
224
|
+
declare class Prampta {
|
|
225
|
+
private readonly baseUrl;
|
|
226
|
+
private readonly providerId;
|
|
227
|
+
private readonly licenseeId;
|
|
228
|
+
private readonly token;
|
|
229
|
+
private readonly timeoutMs;
|
|
230
|
+
private readonly maxRetries;
|
|
231
|
+
private readonly retryBackoffMs;
|
|
232
|
+
private readonly failClosed;
|
|
233
|
+
private readonly verifySignature;
|
|
234
|
+
private readonly enforce;
|
|
235
|
+
private pinnedKeys;
|
|
236
|
+
private keySetCache;
|
|
237
|
+
private keySetPromise;
|
|
238
|
+
private tofuWarned;
|
|
239
|
+
constructor(config?: PramptaConfig);
|
|
240
|
+
/** Fetch /keys and check it is self-signed by its current key. Cached. */
|
|
241
|
+
private fetchVerifiedKeySet;
|
|
242
|
+
/**
|
|
243
|
+
* Public key hex to verify a decision signed by `keyId`, enforcing the
|
|
244
|
+
* pinning trust model. A pinned match returns immediately (no network); an
|
|
245
|
+
* unpinned key id fails closed in pinned mode; unpinned/TOFU mode resolves
|
|
246
|
+
* from the self-consistent /keys set with a warning.
|
|
247
|
+
*/
|
|
248
|
+
private resolveOperatorKey;
|
|
249
|
+
private subjectIndexEntries;
|
|
250
|
+
private subjectIndexFetchedAt;
|
|
251
|
+
private static readonly SUBJECT_INDEX_TTL_MS;
|
|
252
|
+
/** Fetch the raw subject detection index (/v1/subjects/index). */
|
|
253
|
+
fetchSubjectIndex(): Promise<{
|
|
254
|
+
version: number;
|
|
255
|
+
count: number;
|
|
256
|
+
subjects: SubjectIndexEntry[];
|
|
257
|
+
}>;
|
|
258
|
+
/**
|
|
259
|
+
* Detect registered subjects mentioned in `text`, using a TTL-cached
|
|
260
|
+
* copy of the subject index. Call verify()/assertAllowed() per hit.
|
|
261
|
+
*/
|
|
262
|
+
matchSubjects(text: string, opts?: {
|
|
263
|
+
forceRefresh?: boolean;
|
|
264
|
+
}): Promise<SubjectIndexEntry[]>;
|
|
265
|
+
/**
|
|
266
|
+
* Verify operator Ed25519 signature over decision body.
|
|
267
|
+
* Fails closed on any error.
|
|
268
|
+
*/
|
|
269
|
+
private verifyDecision;
|
|
270
|
+
/**
|
|
271
|
+
* Verify that the signed decision is bound to the correct request context.
|
|
272
|
+
* Prevents replay attacks where a valid decision for one context is used in another.
|
|
273
|
+
*/
|
|
274
|
+
private verifyContextBinding;
|
|
275
|
+
verifyGeneration(request: VerifyRequest): Promise<SignedDecision>;
|
|
276
|
+
/** Flat convenience API mirroring the Python SDK: intended-use fields
|
|
277
|
+
* (categories, channel, productName, …) are accepted at the top level.
|
|
278
|
+
* Either `prompt` or `promptHash` is REQUIRED — decisions are bound to
|
|
279
|
+
* the prompt hash and the SDK refuses to request unbound ones. */
|
|
280
|
+
verify(subjectId: string, options?: VerifyOptions): Promise<SignedDecision>;
|
|
281
|
+
assertAllowed(subjectId: string, options?: Omit<VerifyRequest, "subjectId">): Promise<SignedDecision>;
|
|
282
|
+
withAuthorization<T>(request: VerifyRequest, generateFn: (decision: SignedDecision) => Promise<T>): Promise<{
|
|
283
|
+
output: T;
|
|
284
|
+
decision: SignedDecision;
|
|
285
|
+
metadata: OutputMetadata;
|
|
286
|
+
}>;
|
|
287
|
+
getSubject(subjectId: string): Promise<SubjectInfo | null>;
|
|
288
|
+
requestLicense(input: LicenseRequestInput): Promise<LicenseRequestResult>;
|
|
289
|
+
createOutputMetadata(decision: SignedDecision): OutputMetadata;
|
|
290
|
+
/**
|
|
291
|
+
* Submit a generation receipt AFTER generating — the provider's enforcement
|
|
292
|
+
* proof, bound to the decision it acted on. Records that this generation was
|
|
293
|
+
* authorized and executed under the decision's terms (verifiable post-hoc).
|
|
294
|
+
*/
|
|
295
|
+
submitReceipt(decision: SignedDecision, result?: {
|
|
296
|
+
outputHash?: string;
|
|
297
|
+
model?: string;
|
|
298
|
+
watermarkEmbedded?: boolean;
|
|
299
|
+
obligationsApplied?: Record<string, unknown>;
|
|
300
|
+
generatedAt?: number;
|
|
301
|
+
}): Promise<Record<string, unknown>>;
|
|
302
|
+
health(): Promise<boolean>;
|
|
303
|
+
version(): Promise<Record<string, unknown>>;
|
|
304
|
+
static hashPrompt(prompt: string): Promise<string>;
|
|
305
|
+
private parseDecision;
|
|
306
|
+
private headers;
|
|
307
|
+
/** Transient errors worth retrying: connectivity, timeout, 429, and 5xx. */
|
|
308
|
+
private isRetryable;
|
|
309
|
+
private withRetry;
|
|
310
|
+
private post;
|
|
311
|
+
private postOnce;
|
|
312
|
+
private get;
|
|
313
|
+
private getOnce;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export { HARD_REFUSAL_CODES, type LicenseRequestInput, type LicenseRequestResult, type OutputMetadata, Prampta, PramptaApiError, type PramptaConfig, PramptaError, PramptaFailClosedError, PramptaNetworkError, PramptaRefusalError, PramptaSchemaError, PramptaSignatureError, PramptaTimeoutError, REFUSAL_DESCRIPTIONS, SOFT_REFUSAL_CODES, type SignedDecision, type SubjectIndexEntry, type SubjectInfo, type VerifyOptions, type VerifyRequest, canonicalJson, hashPrompt, matchSubjects, normalizeForMatch };
|