@opendatalabs/vana-sdk 3.18.1 → 3.19.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.
@@ -51,6 +51,7 @@ export { ScopeSchema, parseScope, scopeToPathSegments, scopeMatchesPattern, scop
51
51
  export { SCOPE_ACTIONS, InvalidScopeEntryError, parseScopeEntry, formatScopeEntry, grantPermissions, permissionsToScopes, tryGrantPermissions, hasAction, type ScopeAction, type ParsedScopeEntry, type GrantPermission, } from "./protocol/scope-actions.js";
52
52
  export { WRITE_SESSION_PATH, WRITE_SIGNATURE_HEADER, WRITE_METADATA_HEADER, WRITE_FILENAME_HEADER, WRITE_CONTENT_DISPOSITION_HEADER, WRITER_ATTRIBUTION_KEY, LINEAGE_KEY, LINEAGE_FIELD, MAX_LINEAGE_SOURCES, RESERVED_WRITE_KEYS, openWriteSession, writeData, writePersonalServerData, sessionCoversScope, binaryWriteSignedBytes, normalizeBinaryMimeType, parseWriteMetadataHeader, encodeWriteMetadataHeader, type WriteTransportRetryOptions, type WriteSession, type OpenWriteSessionParams, type WriteBinaryPayload, type LineageSource, type WriteJsonDataParams, type WriteBinaryDataParams, type WriteDataParams, type WriteDataResult, type WritePersonalServerDataParams, type WritePersonalServerDataResult, type BinaryWriteSignedBytesInput, } from "./protocol/personal-server-write.js";
53
53
  export { resolveWriteSigner, type WriteSigner, type WriteSignerSource, type ViemWriteAccount, type ViemWriteWalletClient, type ResolveWriteSignerOptions, } from "./protocol/write-signer.js";
54
+ export { DERIVATIVE_QUESTIONS_PATH, MAX_QUESTION_SOURCE_SCOPES, MAX_QUESTION_CHARS, MAX_QUESTION_MODEL_CHARS, DEFAULT_QUESTION_TIMEOUT_MS, DEFAULT_QUESTION_POLL_INTERVAL_MS, QUESTION_STATUSES, registerQuestion, getQuestion, listQuestions, recomputeQuestion, deleteQuestion, waitForQuestion, askPersonalServer, QuestionStatusSchema, QuestionRegisteredBySchema, DerivativeQuestionSchema, QuestionRecomputeResultSchema, QuestionDeleteResultSchema, type QuestionStatus, type QuestionRegisteredBy, type DerivativeQuestion, type QuestionRecomputeResult, type QuestionDeleteResult, type DerivativeQuestionAuthParams, type RegisterQuestionParams, type GetQuestionParams, type ListQuestionsParams, type RecomputeQuestionParams, type DeleteQuestionParams, type WaitForQuestionParams, type AskPersonalServerParams, type AskPersonalServerResult, } from "./protocol/derivative-questions.js";
54
55
  export { deriveDataPointId, isDataPointId, scopeNamespace, derivedScopeViolatesNaming, assertDerivedScopeNaming, isRedactedLineageNode, personalServerLineagePath, gatewayLineagePath, getLineage, getPersonalServerLineage, getGatewayLineage, LineageNodeSchema, RedactedLineageNodeSchema, LineageEntrySchema, LineageGraphSchema, type LineageNode, type RedactedLineageNode, type LineageEntry, type LineageGraph, type LineageReadResult, type PersonalServerLineageParams, type GatewayLineageParams, type GetLineageParams, } from "./protocol/lineage.js";
55
56
  export { DataFileEnvelopeSchema, createDataFileEnvelope, IngestResponseSchema, type DataFileEnvelope, type IngestResponse, } from "./protocol/data-file.js";
56
57
  export { createGatewayClient, type GatewayEnvelope, type GatewayProof, type Builder, type Schema, type ServerInfo, type OwnerServerRecord, type OwnerServersResult, type GatewayGrantFee, type GatewayGrantStatus, type GatewayGrantResponse, type GrantListItem, type DataPointRecord, type DataPointListResult, type ListDataPointsOptions, type RegisterServerParams, type RegisterServerResult, type RegisterBuilderParams, type RegisterBuilderResult, type RegisterDataPointParams, type RegisterDataPointResult, type GetDataPointOptions, type DeleteDataPointParams, type DeleteDataPointResult, type CreateGrantParams, type RevokeGrantParams, type AccessRecord, type PayForOperationParams, type PayForOperationResult, type SettleOpType, type SettleItem, type SettlePromoteResult, type SettleReconcileItem, type SettleParams, type SettleResult, type GatewayClient, } from "./protocol/gateway.js";
@@ -1358,6 +1358,46 @@ var LineageReadError = class extends VanaError {
1358
1358
  errorCode;
1359
1359
  details;
1360
1360
  };
1361
+ var DerivativeQuestionRejectedError = class extends PersonalServerWriteError {
1362
+ constructor(message, status, errorCode = null, details) {
1363
+ super(message, "DERIVATIVE_QUESTION_REJECTED", status, errorCode, details);
1364
+ }
1365
+ };
1366
+ var DerivativeQuestionInvalidError = class extends PersonalServerWriteError {
1367
+ constructor(message, status = 400, errorCode = null, details) {
1368
+ super(message, "DERIVATIVE_QUESTION_INVALID", status, errorCode, details);
1369
+ }
1370
+ };
1371
+ var DerivativeQuestionNotFoundError = class extends PersonalServerWriteError {
1372
+ constructor(message, errorCode = null, details) {
1373
+ super(message, "DERIVATIVE_QUESTION_NOT_FOUND", 404, errorCode, details);
1374
+ }
1375
+ };
1376
+ var DerivativeSourceNotGrantedError = class extends PersonalServerWriteError {
1377
+ constructor(message, errorCode = null, details) {
1378
+ super(message, "DERIVATIVE_SOURCE_NOT_GRANTED", 403, errorCode, details);
1379
+ }
1380
+ };
1381
+ var DerivativeCycleError = class extends PersonalServerWriteError {
1382
+ constructor(message, errorCode = null, details) {
1383
+ super(message, "DERIVATIVE_CYCLE", 409, errorCode, details);
1384
+ }
1385
+ };
1386
+ var DerivativeComputeUnavailableError = class extends PersonalServerWriteError {
1387
+ constructor(message, errorCode = null, details) {
1388
+ super(message, "DERIVATIVE_COMPUTE_UNAVAILABLE", 503, errorCode, details);
1389
+ }
1390
+ };
1391
+ var DerivativeQuestionTimeoutError = class extends PersonalServerWriteError {
1392
+ constructor(message, details) {
1393
+ super(message, "DERIVATIVE_QUESTION_TIMEOUT", void 0, null, details);
1394
+ }
1395
+ };
1396
+ var DerivativeQuestionFailedError = class extends PersonalServerWriteError {
1397
+ constructor(message, details) {
1398
+ super(message, "DERIVATIVE_QUESTION_FAILED", void 0, null, details);
1399
+ }
1400
+ };
1361
1401
  var DataPointDeletedError = class extends VanaError {
1362
1402
  constructor(message, details = {}) {
1363
1403
  super(message, "DATA_POINT_DELETED");
@@ -34391,32 +34431,13 @@ function tryGrantPermissions(scopes) {
34391
34431
  }
34392
34432
 
34393
34433
  // src/protocol/personal-server-write.ts
34394
- import { sha256 as sha2565 } from "@noble/hashes/sha2";
34395
- import { bytesToHex as bytesToHex2, isAddress as isAddress6 } from "viem";
34434
+ import { sha256 as sha2566 } from "@noble/hashes/sha2";
34435
+ import { bytesToHex as bytesToHex3, isAddress as isAddress6 } from "viem";
34396
34436
  import { z as z4 } from "zod";
34397
- var WRITE_SESSION_PATH = "/v1/write/session";
34398
- var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
34399
- var WRITE_METADATA_HEADER = "X-Vana-Metadata";
34400
- var LINEAGE_FIELD = "lineage";
34401
- var MAX_LINEAGE_SOURCES = 256;
34402
- var WRITE_FILENAME_HEADER = "X-Filename";
34403
- var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
34404
- var WRITER_ATTRIBUTION_KEY = "$writtenBy";
34405
- var LINEAGE_KEY = "$lineage";
34406
- var RESERVED_WRITE_KEYS = [
34407
- WRITER_ATTRIBUTION_KEY,
34408
- LINEAGE_KEY
34409
- ];
34410
- var WriteDataResultSchema = IngestResponseSchema.extend({
34411
- // Present when the write carried lineage: the validated, lowercased ids.
34412
- lineage: z4.object({ sources: z4.array(z4.string()) }).optional()
34413
- });
34414
- var WriteSessionResponseSchema = z4.object({
34415
- access_token: z4.string().min(1),
34416
- token_type: z4.string(),
34417
- expires_in: z4.number().nonnegative(),
34418
- scope: z4.string()
34419
- });
34437
+
34438
+ // src/protocol/write-request.ts
34439
+ import { sha256 as sha2565 } from "@noble/hashes/sha2";
34440
+ import { bytesToHex as bytesToHex2 } from "viem";
34420
34441
  function normalizeBaseUrl2(url) {
34421
34442
  return url.replace(/\/+$/, "");
34422
34443
  }
@@ -34427,9 +34448,6 @@ function resolveFetch2(fetchFn) {
34427
34448
  }
34428
34449
  return resolved;
34429
34450
  }
34430
- function dataPath(scope) {
34431
- return `/v1/data/${encodeURIComponent(scope)}`;
34432
- }
34433
34451
  function errorMessage(err) {
34434
34452
  return err instanceof Error ? err.message : String(err);
34435
34453
  }
@@ -34517,6 +34535,34 @@ async function sendWithFreshProof(label, fetchFn, options, proofKey, build) {
34517
34535
  lastError
34518
34536
  );
34519
34537
  }
34538
+
34539
+ // src/protocol/personal-server-write.ts
34540
+ var WRITE_SESSION_PATH = "/v1/write/session";
34541
+ var WRITE_SIGNATURE_HEADER = "X-Vana-Write-Signature";
34542
+ var WRITE_METADATA_HEADER = "X-Vana-Metadata";
34543
+ var LINEAGE_FIELD = "lineage";
34544
+ var MAX_LINEAGE_SOURCES = 256;
34545
+ var WRITE_FILENAME_HEADER = "X-Filename";
34546
+ var WRITE_CONTENT_DISPOSITION_HEADER = "Content-Disposition";
34547
+ var WRITER_ATTRIBUTION_KEY = "$writtenBy";
34548
+ var LINEAGE_KEY = "$lineage";
34549
+ var RESERVED_WRITE_KEYS = [
34550
+ WRITER_ATTRIBUTION_KEY,
34551
+ LINEAGE_KEY
34552
+ ];
34553
+ var WriteDataResultSchema = IngestResponseSchema.extend({
34554
+ // Present when the write carried lineage: the validated, lowercased ids.
34555
+ lineage: z4.object({ sources: z4.array(z4.string()) }).optional()
34556
+ });
34557
+ var WriteSessionResponseSchema = z4.object({
34558
+ access_token: z4.string().min(1),
34559
+ token_type: z4.string(),
34560
+ expires_in: z4.number().nonnegative(),
34561
+ scope: z4.string()
34562
+ });
34563
+ function dataPath(scope) {
34564
+ return `/v1/data/${encodeURIComponent(scope)}`;
34565
+ }
34520
34566
  async function openWriteSession(params) {
34521
34567
  const fetchFn = resolveFetch2(params.fetch);
34522
34568
  const personalServerUrl = normalizeBaseUrl2(params.personalServerUrl);
@@ -34648,7 +34694,7 @@ function binaryWriteSignedBytes(input) {
34648
34694
  mimeType: normalizeBinaryMimeType(input.contentType),
34649
34695
  ...input.filename ? { filename: input.filename } : {},
34650
34696
  sizeBytes: input.bytes.length,
34651
- contentHash: bytesToHex2(sha2565(input.bytes)),
34697
+ contentHash: bytesToHex3(sha2566(input.bytes)),
34652
34698
  encoding: "base64",
34653
34699
  content: toBase64(input.bytes),
34654
34700
  ...metadata !== void 0 ? { metadata } : {}
@@ -34945,6 +34991,437 @@ async function writePersonalServerData(params) {
34945
34991
  return { ...result, session };
34946
34992
  }
34947
34993
 
34994
+ // src/protocol/derivative-questions.ts
34995
+ import { z as z5 } from "zod";
34996
+ var DERIVATIVE_QUESTIONS_PATH = "/v1/derivatives/questions";
34997
+ var MAX_QUESTION_SOURCE_SCOPES = 16;
34998
+ var MAX_QUESTION_CHARS = 8e3;
34999
+ var MAX_QUESTION_MODEL_CHARS = 128;
35000
+ var MODEL_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:/-]*$/;
35001
+ var DEFAULT_QUESTION_TIMEOUT_MS = 12e4;
35002
+ var DEFAULT_QUESTION_POLL_INTERVAL_MS = 2e3;
35003
+ var SESSION_REFRESH_SKEW_MS = 3e4;
35004
+ var QUESTION_STATUSES = [
35005
+ "pending",
35006
+ "ready",
35007
+ "failed",
35008
+ "stale"
35009
+ ];
35010
+ var QuestionStatusSchema = z5.enum(QUESTION_STATUSES);
35011
+ var QuestionRegisteredBySchema = z5.union([
35012
+ z5.object({ kind: z5.literal("owner") }),
35013
+ z5.object({
35014
+ kind: z5.literal("builder"),
35015
+ builder: z5.string(),
35016
+ grantId: z5.string()
35017
+ })
35018
+ ]);
35019
+ var nullableString = z5.string().nullish().transform((value) => value ?? null);
35020
+ var DerivativeQuestionSchema = z5.object({
35021
+ questionId: z5.string().min(1),
35022
+ derivedScope: z5.string().min(1),
35023
+ sourceScopes: z5.array(z5.string()),
35024
+ question: z5.string(),
35025
+ /** The model override, or `null` for the server's default. */
35026
+ model: nullableString,
35027
+ registeredBy: QuestionRegisteredBySchema,
35028
+ status: QuestionStatusSchema,
35029
+ /** A short reason, set only while `status` is `failed`. */
35030
+ error: nullableString,
35031
+ createdAt: z5.string(),
35032
+ updatedAt: nullableString,
35033
+ /** When the last compute finished, or `null` while `pending`. */
35034
+ lastComputedAt: nullableString,
35035
+ /** Local version of the derived record the last compute wrote. */
35036
+ derivedVersion: z5.number().nullish().transform((value) => value ?? null),
35037
+ derivedCollectedAt: nullableString
35038
+ });
35039
+ var QuestionListSchema = z5.object({
35040
+ questions: z5.array(DerivativeQuestionSchema)
35041
+ });
35042
+ var QuestionRecomputeResultSchema = z5.object({
35043
+ questionId: z5.string().min(1),
35044
+ derivedScope: z5.string().min(1),
35045
+ /** `pending` when the question was never computed, else `stale`. */
35046
+ status: QuestionStatusSchema
35047
+ });
35048
+ var QuestionDeleteResultSchema = z5.object({
35049
+ questionId: z5.string().min(1),
35050
+ deleted: z5.literal(true)
35051
+ });
35052
+ var sessionsBySigner = /* @__PURE__ */ new WeakMap();
35053
+ function sessionCacheKey(personalServerUrl, audience, grantId, fetchFn) {
35054
+ return JSON.stringify([personalServerUrl, audience, grantId]) + fetchIdOf(fetchFn);
35055
+ }
35056
+ var fetchIds = /* @__PURE__ */ new WeakMap();
35057
+ var nextFetchId = 0;
35058
+ function fetchIdOf(fetchFn) {
35059
+ let id = fetchIds.get(fetchFn);
35060
+ if (id === void 0) {
35061
+ id = ++nextFetchId;
35062
+ fetchIds.set(fetchFn, id);
35063
+ }
35064
+ return `#${id}`;
35065
+ }
35066
+ function resolveRequest(params) {
35067
+ if (typeof params.personalServerUrl !== "string" || params.personalServerUrl.length === 0) {
35068
+ throw new WriteRequestError("personalServerUrl is required");
35069
+ }
35070
+ if (typeof params.grantId !== "string" || params.grantId.length === 0) {
35071
+ throw new WriteRequestError(
35072
+ "grantId is required; a question call runs under the grant carrying write:<derivedScope>"
35073
+ );
35074
+ }
35075
+ if (params.signer === null || typeof params.signer !== "object") {
35076
+ throw new WriteRequestError(
35077
+ "signer must be a viem LocalAccount, a viem WalletClient, or a { signMessage } object"
35078
+ );
35079
+ }
35080
+ const fetchFn = resolveFetch2(params.fetch);
35081
+ const baseUrl = normalizeBaseUrl2(params.personalServerUrl);
35082
+ const audience = params.audience ?? baseUrl;
35083
+ return {
35084
+ baseUrl,
35085
+ audience,
35086
+ fetchFn,
35087
+ cacheKey: sessionCacheKey(baseUrl, audience, params.grantId, fetchFn),
35088
+ signerKey: params.signer
35089
+ };
35090
+ }
35091
+ async function resolveSession(params, resolved, force) {
35092
+ let cache = sessionsBySigner.get(resolved.signerKey);
35093
+ if (cache === void 0) {
35094
+ cache = /* @__PURE__ */ new Map();
35095
+ sessionsBySigner.set(resolved.signerKey, cache);
35096
+ }
35097
+ const cached = cache.get(resolved.cacheKey);
35098
+ if (!force && cached !== void 0 && cached.expiresAt > Date.now() + SESSION_REFRESH_SKEW_MS) {
35099
+ return cached;
35100
+ }
35101
+ if (force) cache.delete(resolved.cacheKey);
35102
+ const session = await openWriteSession({
35103
+ personalServerUrl: resolved.baseUrl,
35104
+ signer: params.signer,
35105
+ grantId: params.grantId,
35106
+ account: params.account,
35107
+ audience: resolved.audience,
35108
+ fetch: resolved.fetchFn,
35109
+ headers: params.headers,
35110
+ retry: params.retry
35111
+ });
35112
+ cache.set(resolved.cacheKey, session);
35113
+ return session;
35114
+ }
35115
+ async function questionErrorFromResponse(response) {
35116
+ const { errorCode, message, details } = await readPersonalServerErrorBody(response);
35117
+ const text = message ?? `Derivative question request failed: ${response.status} ${response.statusText}`;
35118
+ switch (errorCode) {
35119
+ case "DERIVATIVE_SOURCE_NOT_GRANTED":
35120
+ return new DerivativeSourceNotGrantedError(text, errorCode, details);
35121
+ case "DERIVATIVE_CYCLE":
35122
+ return new DerivativeCycleError(text, errorCode, details);
35123
+ case "DERIVATIVE_COMPUTE_UNAVAILABLE":
35124
+ return new DerivativeComputeUnavailableError(text, errorCode, details);
35125
+ case "DERIVATIVE_QUESTION_INVALID":
35126
+ case "LINEAGE_SCOPE_UNDER_SOURCE_PREFIX":
35127
+ return new DerivativeQuestionInvalidError(
35128
+ text,
35129
+ response.status,
35130
+ errorCode,
35131
+ details
35132
+ );
35133
+ case "DERIVATIVE_QUESTION_NOT_FOUND":
35134
+ return new DerivativeQuestionNotFoundError(text, errorCode, details);
35135
+ default:
35136
+ break;
35137
+ }
35138
+ switch (response.status) {
35139
+ case 401:
35140
+ return new WriteUnauthorizedError(text, errorCode, details);
35141
+ case 403:
35142
+ return new WriteForbiddenError(text, errorCode, details);
35143
+ case 404:
35144
+ return new DerivativeQuestionNotFoundError(text, errorCode, details);
35145
+ case 409:
35146
+ return new WriteConflictError(text, errorCode, details);
35147
+ default:
35148
+ return new DerivativeQuestionRejectedError(
35149
+ text,
35150
+ response.status,
35151
+ errorCode,
35152
+ details
35153
+ );
35154
+ }
35155
+ }
35156
+ async function sendOnce(params, resolved, session, spec, bodyBytes) {
35157
+ return sendWithFreshProof(
35158
+ spec.label,
35159
+ resolved.fetchFn,
35160
+ params.retry,
35161
+ proofKeyFor({
35162
+ aud: session.audience,
35163
+ method: spec.method,
35164
+ uri: spec.path,
35165
+ grantId: session.grantId,
35166
+ signedBytes: bodyBytes
35167
+ }),
35168
+ async (iat) => {
35169
+ const headers = new Headers(params.headers);
35170
+ headers.set("Accept", "application/json");
35171
+ headers.set("Authorization", `Bearer ${session.accessToken}`);
35172
+ if (bodyBytes !== void 0) {
35173
+ headers.set("Content-Type", "application/json");
35174
+ }
35175
+ headers.set(
35176
+ WRITE_SIGNATURE_HEADER,
35177
+ await buildWeb3SignedHeader({
35178
+ signMessage: session.signer.signMessage,
35179
+ aud: session.audience,
35180
+ // The Personal Server verifies the proof against the request's
35181
+ // path only, so the signed `uri` must not carry the query string.
35182
+ uri: spec.path,
35183
+ method: spec.method,
35184
+ body: bodyBytes,
35185
+ grantId: session.grantId,
35186
+ iat
35187
+ })
35188
+ );
35189
+ return {
35190
+ url: `${resolved.baseUrl}${spec.path}${spec.query ?? ""}`,
35191
+ init: {
35192
+ method: spec.method,
35193
+ headers,
35194
+ ...bodyBytes === void 0 ? {} : { body: bodyBytes },
35195
+ ...params.signal ? { signal: params.signal } : {}
35196
+ }
35197
+ };
35198
+ }
35199
+ );
35200
+ }
35201
+ async function sendQuestionRequest(params, spec, schema) {
35202
+ const resolved = resolveRequest(params);
35203
+ const bodyBytes = spec.body === void 0 ? void 0 : new TextEncoder().encode(JSON.stringify(spec.body));
35204
+ let session = await resolveSession(params, resolved, false);
35205
+ let response = await sendOnce(params, resolved, session, spec, bodyBytes);
35206
+ if (response.status === 401) {
35207
+ session = await resolveSession(params, resolved, true);
35208
+ response = await sendOnce(params, resolved, session, spec, bodyBytes);
35209
+ }
35210
+ if (!response.ok) {
35211
+ throw await questionErrorFromResponse(response);
35212
+ }
35213
+ let body;
35214
+ try {
35215
+ body = await response.json();
35216
+ } catch (err) {
35217
+ throw new DerivativeQuestionRejectedError(
35218
+ `${spec.label} response is not JSON`,
35219
+ response.status,
35220
+ null,
35221
+ { cause: errorMessage(err) }
35222
+ );
35223
+ }
35224
+ const parsed = schema.safeParse(body);
35225
+ if (!parsed.success) {
35226
+ throw new DerivativeQuestionRejectedError(
35227
+ `${spec.label} response is not a derivative question answer`,
35228
+ response.status,
35229
+ null,
35230
+ { issues: parsed.error.issues }
35231
+ );
35232
+ }
35233
+ return parsed.data;
35234
+ }
35235
+ function assertQuestionId(questionId) {
35236
+ if (typeof questionId !== "string" || questionId.length === 0) {
35237
+ throw new WriteRequestError("questionId is required");
35238
+ }
35239
+ return `${DERIVATIVE_QUESTIONS_PATH}/${encodeURIComponent(questionId)}`;
35240
+ }
35241
+ function registrationBody(params) {
35242
+ const { derivedScope, question } = params;
35243
+ if (typeof derivedScope !== "string" || derivedScope.length === 0) {
35244
+ throw new WriteRequestError("derivedScope is required");
35245
+ }
35246
+ if (!Array.isArray(params.sourceScopes) || params.sourceScopes.length === 0) {
35247
+ throw new WriteRequestError(
35248
+ "sourceScopes must be a non-empty array of scopes"
35249
+ );
35250
+ }
35251
+ if (params.sourceScopes.length > MAX_QUESTION_SOURCE_SCOPES) {
35252
+ throw new WriteRequestError(
35253
+ `sourceScopes lists ${params.sourceScopes.length} scopes; the maximum is ${MAX_QUESTION_SOURCE_SCOPES}`,
35254
+ { max: MAX_QUESTION_SOURCE_SCOPES, count: params.sourceScopes.length }
35255
+ );
35256
+ }
35257
+ const sourceScopes = [];
35258
+ for (const scope of params.sourceScopes) {
35259
+ if (typeof scope !== "string" || scope.length === 0) {
35260
+ throw new WriteRequestError("sourceScopes entries must be scope strings");
35261
+ }
35262
+ if (sourceScopes.includes(scope)) {
35263
+ throw new WriteRequestError("sourceScopes must not repeat a scope", {
35264
+ duplicate: scope
35265
+ });
35266
+ }
35267
+ if (scope === derivedScope) {
35268
+ throw new WriteRequestError(
35269
+ "derivedScope cannot be one of its own sources",
35270
+ { scope }
35271
+ );
35272
+ }
35273
+ sourceScopes.push(scope);
35274
+ }
35275
+ if (typeof question !== "string" || question.trim() === "") {
35276
+ throw new WriteRequestError("question must be a non-empty string");
35277
+ }
35278
+ if (question.length > MAX_QUESTION_CHARS) {
35279
+ throw new WriteRequestError(
35280
+ `question is ${question.length} characters; the maximum is ${MAX_QUESTION_CHARS}`,
35281
+ { max: MAX_QUESTION_CHARS, length: question.length }
35282
+ );
35283
+ }
35284
+ if (params.model !== void 0) {
35285
+ if (typeof params.model !== "string" || params.model.length > MAX_QUESTION_MODEL_CHARS || !MODEL_ID_PATTERN.test(params.model)) {
35286
+ throw new WriteRequestError("model must be a provider model id", {
35287
+ model: params.model
35288
+ });
35289
+ }
35290
+ }
35291
+ assertDerivedScopeNaming(derivedScope, sourceScopes);
35292
+ return {
35293
+ derivedScope,
35294
+ sourceScopes,
35295
+ question,
35296
+ ...params.model === void 0 ? {} : { model: params.model }
35297
+ };
35298
+ }
35299
+ async function registerQuestion(params) {
35300
+ const body = registrationBody(params);
35301
+ return sendQuestionRequest(
35302
+ params,
35303
+ {
35304
+ method: "POST",
35305
+ path: DERIVATIVE_QUESTIONS_PATH,
35306
+ body,
35307
+ label: "Register derivative question"
35308
+ },
35309
+ DerivativeQuestionSchema
35310
+ );
35311
+ }
35312
+ async function getQuestion(params) {
35313
+ const path = assertQuestionId(params.questionId);
35314
+ return sendQuestionRequest(
35315
+ params,
35316
+ { method: "GET", path, label: "Read derivative question" },
35317
+ DerivativeQuestionSchema
35318
+ );
35319
+ }
35320
+ async function listQuestions(params) {
35321
+ if (typeof params.derivedScope !== "string" || params.derivedScope.length === 0) {
35322
+ throw new WriteRequestError(
35323
+ "derivedScope is required; a builder may only list its own questions on a scope it may write"
35324
+ );
35325
+ }
35326
+ const { questions } = await sendQuestionRequest(
35327
+ params,
35328
+ {
35329
+ method: "GET",
35330
+ path: DERIVATIVE_QUESTIONS_PATH,
35331
+ query: `?derivedScope=${encodeURIComponent(params.derivedScope)}`,
35332
+ label: "List derivative questions"
35333
+ },
35334
+ QuestionListSchema
35335
+ );
35336
+ return questions;
35337
+ }
35338
+ async function recomputeQuestion(params) {
35339
+ const path = `${assertQuestionId(params.questionId)}/recompute`;
35340
+ return sendQuestionRequest(
35341
+ params,
35342
+ { method: "POST", path, label: "Recompute derivative question" },
35343
+ QuestionRecomputeResultSchema
35344
+ );
35345
+ }
35346
+ async function deleteQuestion(params) {
35347
+ const path = assertQuestionId(params.questionId);
35348
+ return sendQuestionRequest(
35349
+ params,
35350
+ { method: "DELETE", path, label: "Delete derivative question" },
35351
+ QuestionDeleteResultSchema
35352
+ );
35353
+ }
35354
+ function isSettled(status) {
35355
+ return status === "ready" || status === "failed";
35356
+ }
35357
+ function abortError(signal) {
35358
+ const reason = signal.reason;
35359
+ if (reason instanceof Error) return reason;
35360
+ const error = new Error("The operation was aborted");
35361
+ error.name = "AbortError";
35362
+ return error;
35363
+ }
35364
+ async function waitForQuestion(params) {
35365
+ const timeoutMs = Math.max(
35366
+ 0,
35367
+ params.timeoutMs ?? DEFAULT_QUESTION_TIMEOUT_MS
35368
+ );
35369
+ const pollIntervalMs = Math.max(
35370
+ 0,
35371
+ params.pollIntervalMs ?? DEFAULT_QUESTION_POLL_INTERVAL_MS
35372
+ );
35373
+ const deadline = Date.now() + timeoutMs;
35374
+ for (; ; ) {
35375
+ if (params.signal?.aborted) throw abortError(params.signal);
35376
+ const latest = await getQuestion(params);
35377
+ if (isSettled(latest.status)) return latest;
35378
+ const remaining = deadline - Date.now();
35379
+ if (remaining <= 0) {
35380
+ throw new DerivativeQuestionTimeoutError(
35381
+ `Derivative question ${latest.questionId} was still ${latest.status} after ${timeoutMs}ms`,
35382
+ {
35383
+ questionId: latest.questionId,
35384
+ derivedScope: latest.derivedScope,
35385
+ status: latest.status,
35386
+ timeoutMs
35387
+ }
35388
+ );
35389
+ }
35390
+ await sleep2(Math.min(pollIntervalMs, remaining));
35391
+ }
35392
+ }
35393
+ async function askPersonalServer(params) {
35394
+ const registered = await registerQuestion(params);
35395
+ const registration = await waitForQuestion({
35396
+ ...params,
35397
+ questionId: registered.questionId
35398
+ });
35399
+ if (registration.status !== "ready") {
35400
+ throw new DerivativeQuestionFailedError(
35401
+ `Derivative question ${registration.questionId} failed: ${registration.error ?? "no reason given"}`,
35402
+ {
35403
+ questionId: registration.questionId,
35404
+ derivedScope: registration.derivedScope,
35405
+ error: registration.error
35406
+ }
35407
+ );
35408
+ }
35409
+ const signer = resolveWriteSigner(params.signer, {
35410
+ account: params.account
35411
+ });
35412
+ const readParams = {
35413
+ personalServerUrl: normalizeBaseUrl2(params.personalServerUrl),
35414
+ scope: params.derivedScope,
35415
+ grantId: params.grantId,
35416
+ signMessage: signer.signMessage,
35417
+ ...params.audience === void 0 ? {} : { audience: params.audience },
35418
+ ...params.headers === void 0 ? {} : { headers: params.headers },
35419
+ ...params.fetch === void 0 ? {} : { fetch: params.fetch }
35420
+ };
35421
+ const record = await readPersonalServerData(readParams);
35422
+ return { registration, record };
35423
+ }
35424
+
34948
35425
  // src/protocol/gateway.ts
34949
35426
  function withGrantPermissions(grant) {
34950
35427
  const stripped = { ...grant };
@@ -36025,11 +36502,23 @@ export {
36025
36502
  ContractNotFoundError,
36026
36503
  DATA_ACCESS_OP_TYPE,
36027
36504
  DATA_REGISTRY_STATUS_ABI,
36505
+ DEFAULT_QUESTION_POLL_INTERVAL_MS,
36506
+ DEFAULT_QUESTION_TIMEOUT_MS,
36507
+ DERIVATIVE_QUESTIONS_PATH,
36028
36508
  DataFileEnvelopeSchema,
36029
36509
  DataPointDeletedError,
36030
36510
  DataPointNotFoundError,
36031
36511
  DataPointStatus,
36032
36512
  DataPointVersionConflictError,
36513
+ DerivativeComputeUnavailableError,
36514
+ DerivativeCycleError,
36515
+ DerivativeQuestionFailedError,
36516
+ DerivativeQuestionInvalidError,
36517
+ DerivativeQuestionNotFoundError,
36518
+ DerivativeQuestionRejectedError,
36519
+ DerivativeQuestionSchema,
36520
+ DerivativeQuestionTimeoutError,
36521
+ DerivativeSourceNotGrantedError,
36033
36522
  DropboxStorage,
36034
36523
  ECIESError,
36035
36524
  ESCROW_DEPOSIT_ABI2 as ESCROW_DEPOSIT_ABI,
@@ -36054,6 +36543,9 @@ export {
36054
36543
  LineageReadError,
36055
36544
  MASTER_KEY_MESSAGE,
36056
36545
  MAX_LINEAGE_SOURCES,
36546
+ MAX_QUESTION_CHARS,
36547
+ MAX_QUESTION_MODEL_CHARS,
36548
+ MAX_QUESTION_SOURCE_SCOPES,
36057
36549
  MissingAuthError,
36058
36550
  NATIVE_ASSET_ADDRESS,
36059
36551
  NATIVE_VANA_ASSET,
@@ -36074,6 +36566,11 @@ export {
36074
36566
  PersonalServerError,
36075
36567
  PersonalServerWriteError,
36076
36568
  PinataStorage,
36569
+ QUESTION_STATUSES,
36570
+ QuestionDeleteResultSchema,
36571
+ QuestionRecomputeResultSchema,
36572
+ QuestionRegisteredBySchema,
36573
+ QuestionStatusSchema,
36077
36574
  R2Storage,
36078
36575
  RECORD_DATA_ACCESS_TYPES,
36079
36576
  REGISTRATION_KIND_FOR_OP,
@@ -36112,6 +36609,7 @@ export {
36112
36609
  WriteSessionExpiredError,
36113
36610
  WriteTransportError,
36114
36611
  WriteUnauthorizedError,
36612
+ askPersonalServer,
36115
36613
  assertDerivedScopeNaming,
36116
36614
  assertValidPkceVerifier,
36117
36615
  authorizeEscrowPayment,
@@ -36155,6 +36653,7 @@ export {
36155
36653
  dataRegistryDomain,
36156
36654
  decryptWithPassword,
36157
36655
  deleteDataPoint,
36656
+ deleteQuestion,
36158
36657
  deriveDataPointId,
36159
36658
  deriveMasterKey,
36160
36659
  deriveScopeKey,
@@ -36184,6 +36683,7 @@ export {
36184
36683
  getOpFee,
36185
36684
  getPersonalServerLineage,
36186
36685
  getPlatformCapabilities,
36686
+ getQuestion,
36187
36687
  getServiceEndpoints,
36188
36688
  grantPermissions,
36189
36689
  grantRegistrationDomain,
@@ -36196,6 +36696,7 @@ export {
36196
36696
  isPlatformSupported,
36197
36697
  isRedactedLineageNode,
36198
36698
  isTombstoneHashes,
36699
+ listQuestions,
36199
36700
  mainnetServices,
36200
36701
  moksha,
36201
36702
  mokshaServices,
@@ -36215,8 +36716,10 @@ export {
36215
36716
  personalServerLineagePath,
36216
36717
  personalServerRegistrationDomain,
36217
36718
  readPersonalServerData,
36719
+ recomputeQuestion,
36218
36720
  recoverServerOwner,
36219
36721
  registerPersonalServerSignature,
36722
+ registerQuestion,
36220
36723
  resolveWriteSigner,
36221
36724
  scopeCoveredByGrant,
36222
36725
  scopeMatchesPattern,
@@ -36236,6 +36739,7 @@ export {
36236
36739
  verifyGrantRegistration,
36237
36740
  verifyPkceChallenge,
36238
36741
  verifyWeb3Signed,
36742
+ waitForQuestion,
36239
36743
  writeData,
36240
36744
  writePersonalServerData
36241
36745
  };