@pulseai/sdk 0.1.1 → 0.1.3

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/dist/index.js CHANGED
@@ -41,8 +41,10 @@ var MAINNET_ADDRESSES = {
41
41
  feeDistributor: "0x51EdD8E4C4B423b952821fc9e2a7dad15a858B56",
42
42
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
43
43
  reputationRegistry: "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63",
44
- usdm: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7"
44
+ usdm: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7",
45
+ buyerRelay: "0x633054593db34c5aAe36F784faeAe51b9604e037"
45
46
  };
47
+ var PLATFORM_BUYER_AGENT_ID = 8154n;
46
48
  var DEFAULT_INDEXER_URLS = {
47
49
  testnet: "https://pulse-indexer.up.railway.app",
48
50
  mainnet: "https://pulse-indexer.up.railway.app"
@@ -2664,10 +2666,17 @@ async function deployJobTerms(client, agentId, params) {
2664
2666
  const { masterAddress } = await deployWarrenMaster(client, agentId, pageAddress, contentBytes.length, 0);
2665
2667
  return { masterAddress, pageAddress, hash, txHash };
2666
2668
  }
2669
+ function stripCodeFence(content) {
2670
+ let result = content.trim();
2671
+ result = result.replace(/^```\w*\n?/, "");
2672
+ result = result.replace(/\n?```\s*$/, "");
2673
+ return result;
2674
+ }
2667
2675
  async function deployDeliverable(client, agentId, jobId, params, indexerUrl) {
2668
2676
  const { json, hash } = createDeliverable(params);
2669
- const contentBytes = new TextEncoder().encode(json);
2670
- const { pageAddress, txHash } = await deployWarrenPage(client, json);
2677
+ const warrenContent = params.type === "inline" && params.content ? stripCodeFence(params.content) : json;
2678
+ const contentBytes = new TextEncoder().encode(warrenContent);
2679
+ const { pageAddress, txHash } = await deployWarrenPage(client, warrenContent);
2671
2680
  const { masterAddress } = await deployWarrenMaster(client, agentId, pageAddress, contentBytes.length, 1);
2672
2681
  await write(client, {
2673
2682
  address: client.addresses.jobEngine,
@@ -2886,7 +2895,9 @@ async function callOpenAI(params) {
2886
2895
  if (!content) {
2887
2896
  throw new Error("OpenAI returned an empty response");
2888
2897
  }
2889
- return { content, raw: payload };
2898
+ const truncated = payload?.choices?.[0]?.finish_reason === "length";
2899
+ const usage = payload?.usage ? { inputTokens: payload.usage.prompt_tokens ?? 0, outputTokens: payload.usage.completion_tokens ?? 0 } : void 0;
2900
+ return { content, truncated, raw: payload, usage };
2890
2901
  }
2891
2902
  async function callAnthropic(params) {
2892
2903
  const systemPrompt = params.messages.filter((message) => message.role === "system").map((message) => message.content).join("\n\n").trim();
@@ -2919,7 +2930,9 @@ async function callAnthropic(params) {
2919
2930
  if (!content) {
2920
2931
  throw new Error("Anthropic returned an empty response");
2921
2932
  }
2922
- return { content, raw: payload };
2933
+ const truncated = payload?.stop_reason === "max_tokens";
2934
+ const usage = payload?.usage ? { inputTokens: payload.usage.input_tokens ?? 0, outputTokens: payload.usage.output_tokens ?? 0 } : void 0;
2935
+ return { content, truncated, raw: payload, usage };
2923
2936
  }
2924
2937
  async function callGoogle(params) {
2925
2938
  const systemPrompt = params.messages.filter((message) => message.role === "system").map((message) => message.content).join("\n\n").trim();
@@ -2953,7 +2966,9 @@ async function callGoogle(params) {
2953
2966
  if (!content) {
2954
2967
  throw new Error("Google returned an empty response");
2955
2968
  }
2956
- return { content, raw: payload };
2969
+ const truncated = payload?.candidates?.[0]?.finishReason === "MAX_TOKENS";
2970
+ const usage = payload?.usageMetadata ? { inputTokens: payload.usageMetadata.promptTokenCount ?? 0, outputTokens: payload.usageMetadata.candidatesTokenCount ?? 0 } : void 0;
2971
+ return { content, truncated, raw: payload, usage };
2957
2972
  }
2958
2973
  async function callAI(params) {
2959
2974
  if (params.provider === "openai") {
@@ -2971,12 +2986,15 @@ async function callAI(params) {
2971
2986
  // src/handler/site-modifier.ts
2972
2987
  var FETCH_TIMEOUT_MS = 3e4;
2973
2988
  var MAX_HTML_BYTES = 500 * 1024;
2974
- var DEFAULT_MAX_TOKENS = 4096;
2989
+ var DEFAULT_MAX_TOKENS = 16384;
2990
+ var AI_MAX_RETRIES = 3;
2991
+ var RETRY_DELAY_MS = 2e3;
2992
+ var GOOGLE_FALLBACK_MODEL = "gemini-2.5-pro";
2975
2993
  var SUPPORTED_PROVIDERS = ["anthropic", "google", "openai"];
2976
2994
  var DEFAULT_MODELS = {
2977
- openai: "gpt-4o-mini",
2978
- anthropic: "claude-3-5-sonnet-latest",
2979
- google: "gemini-1.5-pro"
2995
+ openai: "gpt-5.2",
2996
+ anthropic: "claude-sonnet-4-6",
2997
+ google: "gemini-3.1-pro-preview"
2980
2998
  };
2981
2999
  var DEFAULT_SYSTEM_PROMPT = [
2982
3000
  "You are an expert frontend engineer modifying an existing HTML document.",
@@ -3029,6 +3047,10 @@ function isHtmlContentType(contentType) {
3029
3047
  const lower = contentType.toLowerCase();
3030
3048
  return lower.includes("text/html") || lower.includes("application/xhtml+xml");
3031
3049
  }
3050
+ function isJsonContentType(contentType) {
3051
+ const lower = contentType.toLowerCase();
3052
+ return lower.includes("application/json") || lower.includes("text/json");
3053
+ }
3032
3054
  function extractHtmlFromText(text) {
3033
3055
  const htmlFence = text.match(/```html\s*([\s\S]*?)```/i);
3034
3056
  if (htmlFence?.[1]) {
@@ -3042,18 +3064,101 @@ function extractHtmlFromText(text) {
3042
3064
  return fencedContent;
3043
3065
  }
3044
3066
  }
3067
+ const openFence = text.match(/```html?\s*\n?([\s\S]+)/i);
3068
+ if (openFence?.[1]) {
3069
+ const content = openFence[1].trim();
3070
+ if (/<html[\s>]|<!doctype html/i.test(content)) {
3071
+ return content;
3072
+ }
3073
+ }
3045
3074
  const trimmed = text.trim();
3046
3075
  if (/<html[\s>]|<!doctype html/i.test(trimmed)) {
3047
3076
  return trimmed;
3048
3077
  }
3049
3078
  return null;
3050
3079
  }
3080
+ function extractHtmlFromJson(jsonText) {
3081
+ try {
3082
+ const parsed = JSON.parse(jsonText);
3083
+ if (typeof parsed === "string") {
3084
+ if (/<html[\s>]|<!doctype html/i.test(parsed)) return parsed;
3085
+ return null;
3086
+ }
3087
+ if (typeof parsed !== "object" || parsed === null) return null;
3088
+ const obj = parsed;
3089
+ const nested = obj.data && typeof obj.data === "object" ? obj.data : null;
3090
+ const candidates = [
3091
+ obj.html,
3092
+ obj.content,
3093
+ obj.body,
3094
+ nested?.content,
3095
+ nested?.html,
3096
+ nested?.body
3097
+ ];
3098
+ for (const candidate of candidates) {
3099
+ if (typeof candidate === "string" && candidate.trim().length > 0) {
3100
+ if (/<html[\s>]|<!doctype html|<head[\s>]|<body[\s>]|<div[\s>]/i.test(candidate)) {
3101
+ return candidate.trim();
3102
+ }
3103
+ }
3104
+ }
3105
+ return null;
3106
+ } catch {
3107
+ return null;
3108
+ }
3109
+ }
3051
3110
  function getByteLength(content) {
3052
3111
  return new TextEncoder().encode(content).byteLength;
3053
3112
  }
3054
3113
  var SiteModifierHandler = class {
3055
3114
  offeringId;
3056
3115
  autoAccept;
3116
+ schema = {
3117
+ version: 1,
3118
+ serviceRequirements: {
3119
+ type: "object",
3120
+ properties: {
3121
+ siteUrl: {
3122
+ type: "string",
3123
+ description: "URL of the site to modify (http/https)"
3124
+ },
3125
+ modificationRequest: {
3126
+ type: "string",
3127
+ description: "What changes to make"
3128
+ },
3129
+ provider: {
3130
+ type: "string",
3131
+ description: "AI provider",
3132
+ enum: ["google", "anthropic", "openai"]
3133
+ },
3134
+ model: {
3135
+ type: "string",
3136
+ description: "Specific model override"
3137
+ }
3138
+ },
3139
+ required: ["siteUrl", "modificationRequest"]
3140
+ },
3141
+ deliverableRequirements: {
3142
+ type: "object",
3143
+ properties: {
3144
+ type: {
3145
+ type: "string",
3146
+ description: 'Delivery type, always "inline"',
3147
+ enum: ["inline"]
3148
+ },
3149
+ content: {
3150
+ type: "string",
3151
+ description: "Modified HTML content"
3152
+ },
3153
+ mimeType: {
3154
+ type: "string",
3155
+ description: 'Content type, always "text/html"',
3156
+ enum: ["text/html"]
3157
+ }
3158
+ },
3159
+ required: ["type", "content", "mimeType"]
3160
+ }
3161
+ };
3057
3162
  config;
3058
3163
  constructor(offeringId, config, options) {
3059
3164
  this.offeringId = offeringId;
@@ -3076,7 +3181,8 @@ var SiteModifierHandler = class {
3076
3181
  const targetUrl = parseAndValidateUrl(requirements.siteUrl);
3077
3182
  ensureAllowedUrl(targetUrl, this.config.allowedDomains);
3078
3183
  const provider = requirements.provider ?? this.config.defaultProvider ?? "openai";
3079
- const model = requirements.model?.trim() || this.config.defaultModel?.trim() || DEFAULT_MODELS[provider];
3184
+ const useConfigModel = provider === (this.config.defaultProvider ?? "openai");
3185
+ const model = requirements.model?.trim() || (useConfigModel ? this.config.defaultModel?.trim() : void 0) || DEFAULT_MODELS[provider];
3080
3186
  const maxTokens = this.config.maxTokens && this.config.maxTokens > 0 ? this.config.maxTokens : DEFAULT_MAX_TOKENS;
3081
3187
  if (!model) {
3082
3188
  throw new Error(
@@ -3102,17 +3208,71 @@ var SiteModifierHandler = class {
3102
3208
  originalHtml,
3103
3209
  "```"
3104
3210
  ].join("\n");
3105
- const aiResponse = await callAI({
3106
- provider,
3107
- model,
3108
- maxTokens,
3109
- apiKey,
3110
- signal: context.abortSignal,
3111
- messages: [
3112
- { role: "system", content: systemPrompt },
3113
- { role: "user", content: userPrompt }
3114
- ]
3115
- });
3211
+ let aiResponse = null;
3212
+ let lastError = null;
3213
+ const aiMessages = [
3214
+ { role: "system", content: systemPrompt },
3215
+ { role: "user", content: userPrompt }
3216
+ ];
3217
+ for (let attempt = 1; attempt <= AI_MAX_RETRIES; attempt++) {
3218
+ try {
3219
+ aiResponse = await callAI({
3220
+ provider,
3221
+ model,
3222
+ maxTokens,
3223
+ apiKey,
3224
+ signal: context.abortSignal,
3225
+ messages: aiMessages
3226
+ });
3227
+ if (aiResponse.truncated) {
3228
+ throw new Error(
3229
+ "AI output was truncated (hit token limit). The generated HTML is incomplete."
3230
+ );
3231
+ }
3232
+ break;
3233
+ } catch (err) {
3234
+ lastError = err instanceof Error ? err : new Error(String(err));
3235
+ console.error(
3236
+ `[site-modifier] ${model} failed (attempt ${attempt}/${AI_MAX_RETRIES}): ${lastError.message}`
3237
+ );
3238
+ if (provider === "google" && model !== GOOGLE_FALLBACK_MODEL) {
3239
+ try {
3240
+ console.log(
3241
+ `[site-modifier] falling back to ${GOOGLE_FALLBACK_MODEL} (attempt ${attempt}/${AI_MAX_RETRIES})`
3242
+ );
3243
+ aiResponse = await callAI({
3244
+ provider,
3245
+ model: GOOGLE_FALLBACK_MODEL,
3246
+ maxTokens,
3247
+ apiKey,
3248
+ signal: context.abortSignal,
3249
+ messages: aiMessages
3250
+ });
3251
+ if (aiResponse.truncated) {
3252
+ throw new Error(
3253
+ "AI output was truncated (hit token limit). The generated HTML is incomplete."
3254
+ );
3255
+ }
3256
+ break;
3257
+ } catch (fallbackErr) {
3258
+ lastError = fallbackErr instanceof Error ? fallbackErr : new Error(String(fallbackErr));
3259
+ console.error(
3260
+ `[site-modifier] ${GOOGLE_FALLBACK_MODEL} also failed (attempt ${attempt}/${AI_MAX_RETRIES}): ${lastError.message}`
3261
+ );
3262
+ }
3263
+ }
3264
+ }
3265
+ if (attempt < AI_MAX_RETRIES) {
3266
+ const delay = RETRY_DELAY_MS * attempt;
3267
+ console.log(`[site-modifier] retrying in ${delay}ms...`);
3268
+ await new Promise((r) => setTimeout(r, delay));
3269
+ }
3270
+ }
3271
+ if (!aiResponse) {
3272
+ throw new Error(
3273
+ `AI generation failed after ${AI_MAX_RETRIES} attempts. Please try again later. Last error: ${lastError?.message ?? "unknown"}`
3274
+ );
3275
+ }
3116
3276
  const modifiedHtml = extractHtmlFromText(aiResponse.content);
3117
3277
  if (!modifiedHtml) {
3118
3278
  throw new Error("AI response did not contain valid HTML output");
@@ -3125,7 +3285,8 @@ var SiteModifierHandler = class {
3125
3285
  return {
3126
3286
  type: "inline",
3127
3287
  content: modifiedHtml,
3128
- mimeType: "text/html"
3288
+ mimeType: "text/html",
3289
+ usage: aiResponse.usage ? { provider, inputTokens: aiResponse.usage.inputTokens, outputTokens: aiResponse.usage.outputTokens } : void 0
3129
3290
  };
3130
3291
  }
3131
3292
  parseRequirements(requirements) {
@@ -3164,7 +3325,9 @@ var SiteModifierHandler = class {
3164
3325
  async fetchHtmlWithTimeout(siteUrl, parentSignal) {
3165
3326
  const controller = new AbortController();
3166
3327
  const timeoutId = setTimeout(() => {
3167
- controller.abort(new Error(`Site fetch timed out after ${FETCH_TIMEOUT_MS}ms`));
3328
+ controller.abort(
3329
+ new Error(`Site fetch timed out after ${FETCH_TIMEOUT_MS}ms for ${siteUrl}`)
3330
+ );
3168
3331
  }, FETCH_TIMEOUT_MS);
3169
3332
  const parentAbort = () => controller.abort(parentSignal?.reason);
3170
3333
  if (parentSignal) {
@@ -3185,10 +3348,12 @@ var SiteModifierHandler = class {
3185
3348
  `Failed to fetch site HTML: ${response.status} ${response.statusText}`
3186
3349
  );
3187
3350
  }
3188
- const contentType = response.headers.get("content-type");
3189
- if (contentType && !isHtmlContentType(contentType)) {
3351
+ const contentType = response.headers.get("content-type") ?? "";
3352
+ const isHtml = !contentType || isHtmlContentType(contentType);
3353
+ const isJson = isJsonContentType(contentType);
3354
+ if (!isHtml && !isJson) {
3190
3355
  throw new Error(
3191
- `Fetched content is not HTML (content-type: ${contentType})`
3356
+ `Fetched content is not HTML or JSON (content-type: ${contentType}, url: ${siteUrl})`
3192
3357
  );
3193
3358
  }
3194
3359
  const contentLengthHeader = response.headers.get("content-length");
@@ -3206,9 +3371,18 @@ var SiteModifierHandler = class {
3206
3371
  `HTML too large (${htmlBuffer.byteLength} bytes). Limit is ${MAX_HTML_BYTES} bytes`
3207
3372
  );
3208
3373
  }
3209
- const html = new TextDecoder().decode(htmlBuffer).trim();
3374
+ let html = new TextDecoder().decode(htmlBuffer).trim();
3210
3375
  if (!html) {
3211
- throw new Error("Fetched HTML is empty");
3376
+ throw new Error("Fetched content is empty");
3377
+ }
3378
+ if (isJson) {
3379
+ const extracted = extractHtmlFromJson(html);
3380
+ if (!extracted) {
3381
+ throw new Error(
3382
+ `JSON response from ${siteUrl} does not contain extractable HTML content`
3383
+ );
3384
+ }
3385
+ html = extracted;
3212
3386
  }
3213
3387
  return html;
3214
3388
  } catch (error) {
@@ -3216,7 +3390,7 @@ var SiteModifierHandler = class {
3216
3390
  if (parentSignal?.aborted) {
3217
3391
  throw new Error("Site fetch aborted");
3218
3392
  }
3219
- throw new Error(`Site fetch timed out after ${FETCH_TIMEOUT_MS}ms`);
3393
+ throw new Error(`Site fetch timed out after ${FETCH_TIMEOUT_MS}ms for ${siteUrl}`);
3220
3394
  }
3221
3395
  throw error;
3222
3396
  } finally {
@@ -3228,6 +3402,189 @@ var SiteModifierHandler = class {
3228
3402
  }
3229
3403
  };
3230
3404
 
3405
+ // src/types.ts
3406
+ var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
3407
+ JobStatus2[JobStatus2["Created"] = 0] = "Created";
3408
+ JobStatus2[JobStatus2["Accepted"] = 1] = "Accepted";
3409
+ JobStatus2[JobStatus2["InProgress"] = 2] = "InProgress";
3410
+ JobStatus2[JobStatus2["Delivered"] = 3] = "Delivered";
3411
+ JobStatus2[JobStatus2["Evaluated"] = 4] = "Evaluated";
3412
+ JobStatus2[JobStatus2["Completed"] = 5] = "Completed";
3413
+ JobStatus2[JobStatus2["Disputed"] = 6] = "Disputed";
3414
+ JobStatus2[JobStatus2["Cancelled"] = 7] = "Cancelled";
3415
+ return JobStatus2;
3416
+ })(JobStatus || {});
3417
+ var ServiceType = /* @__PURE__ */ ((ServiceType2) => {
3418
+ ServiceType2[ServiceType2["TextGeneration"] = 0] = "TextGeneration";
3419
+ ServiceType2[ServiceType2["ImageGeneration"] = 1] = "ImageGeneration";
3420
+ ServiceType2[ServiceType2["DataAnalysis"] = 2] = "DataAnalysis";
3421
+ ServiceType2[ServiceType2["CodeGeneration"] = 3] = "CodeGeneration";
3422
+ ServiceType2[ServiceType2["Translation"] = 4] = "Translation";
3423
+ ServiceType2[ServiceType2["Custom"] = 5] = "Custom";
3424
+ return ServiceType2;
3425
+ })(ServiceType || {});
3426
+
3427
+ // src/handler/schema.ts
3428
+ var DEFAULT_SCHEMAS = {
3429
+ [0 /* TextGeneration */]: {
3430
+ version: 1,
3431
+ serviceRequirements: {
3432
+ type: "object",
3433
+ properties: {
3434
+ prompt: { type: "string", description: "Text prompt to generate from" },
3435
+ maxTokens: { type: "number", description: "Maximum output token count" }
3436
+ },
3437
+ required: ["prompt"]
3438
+ },
3439
+ deliverableRequirements: {
3440
+ type: "object",
3441
+ properties: {
3442
+ text: { type: "string", description: "Generated text output" },
3443
+ tokenCount: { type: "number", description: "Tokens used to produce output" }
3444
+ },
3445
+ required: ["text"]
3446
+ }
3447
+ },
3448
+ [1 /* ImageGeneration */]: {
3449
+ version: 1,
3450
+ serviceRequirements: {
3451
+ type: "object",
3452
+ properties: {
3453
+ prompt: { type: "string", description: "Image prompt to generate from" },
3454
+ size: { type: "string", description: "Output size (for example: 1024x1024)" },
3455
+ style: { type: "string", description: "Desired visual style" }
3456
+ },
3457
+ required: ["prompt"]
3458
+ },
3459
+ deliverableRequirements: {
3460
+ type: "object",
3461
+ properties: {
3462
+ imageUrl: { type: "string", description: "URL of the generated image" },
3463
+ mimeType: { type: "string", description: "Image MIME type" }
3464
+ },
3465
+ required: ["imageUrl"]
3466
+ }
3467
+ },
3468
+ [2 /* DataAnalysis */]: {
3469
+ version: 1,
3470
+ serviceRequirements: {
3471
+ type: "object",
3472
+ properties: {
3473
+ data: { type: "string", description: "Input data for analysis" },
3474
+ analysisRequest: { type: "string", description: "Question or analysis task" }
3475
+ },
3476
+ required: ["data", "analysisRequest"]
3477
+ },
3478
+ deliverableRequirements: {
3479
+ type: "object",
3480
+ properties: {
3481
+ summary: { type: "string", description: "Analysis summary" },
3482
+ findings: {
3483
+ type: "array",
3484
+ description: "Structured key findings",
3485
+ items: { type: "string" }
3486
+ }
3487
+ },
3488
+ required: ["summary"]
3489
+ }
3490
+ },
3491
+ [3 /* CodeGeneration */]: {
3492
+ version: 1,
3493
+ serviceRequirements: {
3494
+ type: "object",
3495
+ properties: {
3496
+ prompt: { type: "string", description: "Code generation request" },
3497
+ language: { type: "string", description: "Target programming language" }
3498
+ },
3499
+ required: ["prompt"]
3500
+ },
3501
+ deliverableRequirements: {
3502
+ type: "object",
3503
+ properties: {
3504
+ code: { type: "string", description: "Generated source code" },
3505
+ language: { type: "string", description: "Detected or requested language" }
3506
+ },
3507
+ required: ["code"]
3508
+ }
3509
+ },
3510
+ [4 /* Translation */]: {
3511
+ version: 1,
3512
+ serviceRequirements: {
3513
+ type: "object",
3514
+ properties: {
3515
+ text: { type: "string", description: "Text to translate" },
3516
+ targetLanguage: { type: "string", description: "Target language code or name" },
3517
+ sourceLanguage: { type: "string", description: "Optional source language code or name" }
3518
+ },
3519
+ required: ["text", "targetLanguage"]
3520
+ },
3521
+ deliverableRequirements: {
3522
+ type: "object",
3523
+ properties: {
3524
+ translatedText: { type: "string", description: "Translated text output" },
3525
+ sourceLanguage: { type: "string", description: "Detected or provided source language" }
3526
+ },
3527
+ required: ["translatedText"]
3528
+ }
3529
+ }
3530
+ };
3531
+ function isObjectRecord(value) {
3532
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3533
+ }
3534
+ function isTypeMatch(value, type) {
3535
+ switch (type) {
3536
+ case "string":
3537
+ return typeof value === "string";
3538
+ case "number":
3539
+ return typeof value === "number" && Number.isFinite(value);
3540
+ case "boolean":
3541
+ return typeof value === "boolean";
3542
+ case "object":
3543
+ return isObjectRecord(value);
3544
+ case "array":
3545
+ return Array.isArray(value);
3546
+ default:
3547
+ return false;
3548
+ }
3549
+ }
3550
+ function validateAgainstSchema(data, schema) {
3551
+ if (!data || !isObjectRecord(data)) {
3552
+ return { valid: false, reason: "Requirements must be a JSON object" };
3553
+ }
3554
+ for (const requiredField of schema.required ?? []) {
3555
+ if (!(requiredField in data)) {
3556
+ return { valid: false, reason: `Missing required field: ${requiredField}` };
3557
+ }
3558
+ }
3559
+ for (const [field, fieldSchema] of Object.entries(schema.properties)) {
3560
+ const value = data[field];
3561
+ if (value === void 0) continue;
3562
+ if (!isTypeMatch(value, fieldSchema.type)) {
3563
+ return {
3564
+ valid: false,
3565
+ reason: `Field "${field}" must be of type ${fieldSchema.type}`
3566
+ };
3567
+ }
3568
+ if (fieldSchema.enum && !fieldSchema.enum.some((enumValue) => Object.is(enumValue, value))) {
3569
+ return {
3570
+ valid: false,
3571
+ reason: `Field "${field}" must be one of: ${fieldSchema.enum.map((v) => JSON.stringify(v)).join(", ")}`
3572
+ };
3573
+ }
3574
+ if (fieldSchema.type === "array" && fieldSchema.items && Array.isArray(value)) {
3575
+ for (let i = 0; i < value.length; i += 1) {
3576
+ if (!isTypeMatch(value[i], fieldSchema.items.type)) {
3577
+ return {
3578
+ valid: false,
3579
+ reason: `Field "${field}[${i}]" must be of type ${fieldSchema.items.type}`
3580
+ };
3581
+ }
3582
+ }
3583
+ }
3584
+ }
3585
+ return { valid: true };
3586
+ }
3587
+
3231
3588
  // src/utils.ts
3232
3589
  var USDM_DECIMALS = 18;
3233
3590
  var USDM_SCALE = 10n ** BigInt(USDM_DECIMALS);
@@ -3264,28 +3621,6 @@ function formatUsdm(amount) {
3264
3621
  return `${whole}.${trimmedFraction.padEnd(2, "0")}`;
3265
3622
  }
3266
3623
 
3267
- // src/types.ts
3268
- var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
3269
- JobStatus2[JobStatus2["Created"] = 0] = "Created";
3270
- JobStatus2[JobStatus2["Accepted"] = 1] = "Accepted";
3271
- JobStatus2[JobStatus2["InProgress"] = 2] = "InProgress";
3272
- JobStatus2[JobStatus2["Delivered"] = 3] = "Delivered";
3273
- JobStatus2[JobStatus2["Evaluated"] = 4] = "Evaluated";
3274
- JobStatus2[JobStatus2["Completed"] = 5] = "Completed";
3275
- JobStatus2[JobStatus2["Disputed"] = 6] = "Disputed";
3276
- JobStatus2[JobStatus2["Cancelled"] = 7] = "Cancelled";
3277
- return JobStatus2;
3278
- })(JobStatus || {});
3279
- var ServiceType = /* @__PURE__ */ ((ServiceType2) => {
3280
- ServiceType2[ServiceType2["TextGeneration"] = 0] = "TextGeneration";
3281
- ServiceType2[ServiceType2["ImageGeneration"] = 1] = "ImageGeneration";
3282
- ServiceType2[ServiceType2["DataAnalysis"] = 2] = "DataAnalysis";
3283
- ServiceType2[ServiceType2["CodeGeneration"] = 3] = "CodeGeneration";
3284
- ServiceType2[ServiceType2["Translation"] = 4] = "Translation";
3285
- ServiceType2[ServiceType2["Custom"] = 5] = "Custom";
3286
- return ServiceType2;
3287
- })(ServiceType || {});
3288
-
3289
3624
  // src/indexer/client.ts
3290
3625
  var IndexerClientError = class extends Error {
3291
3626
  status;
@@ -3323,6 +3658,7 @@ function toIndexerOffering(raw) {
3323
3658
  priceUsdm: raw.price_usdm,
3324
3659
  slaMinutes: raw.sla_minutes,
3325
3660
  description: raw.description,
3661
+ requirementsSchemaUri: raw.requirements_schema_uri ?? void 0,
3326
3662
  active: raw.active === 1,
3327
3663
  blockNumber: raw.block_number,
3328
3664
  txHash: raw.tx_hash
@@ -3755,6 +4091,7 @@ var HandlerProviderRuntime = class {
3755
4091
  running = false;
3756
4092
  processedJobs = /* @__PURE__ */ new Set();
3757
4093
  failedJobs = /* @__PURE__ */ new Map();
4094
+ schemaCache = /* @__PURE__ */ new Map();
3758
4095
  maxRetries = 3;
3759
4096
  onError;
3760
4097
  constructor(client, agentId, options) {
@@ -3783,6 +4120,7 @@ var HandlerProviderRuntime = class {
3783
4120
  try {
3784
4121
  await this.checkNewJobs();
3785
4122
  await this.checkInProgressJobs();
4123
+ await this.checkEvaluatedJobs();
3786
4124
  } catch (e) {
3787
4125
  this.onError?.(e instanceof Error ? e : new Error(String(e)));
3788
4126
  }
@@ -3798,8 +4136,8 @@ var HandlerProviderRuntime = class {
3798
4136
  for (const job of jobs) {
3799
4137
  const newKey = `new:${job.jobId}`;
3800
4138
  if (!this.canProcess(newKey)) continue;
3801
- const matchesOffering = offerings.some((o) => o.offeringId === job.offeringId);
3802
- if (!matchesOffering) continue;
4139
+ const offering = offerings.find((o) => o.offeringId === job.offeringId);
4140
+ if (!offering) continue;
3803
4141
  const handler = this.handlers.get(job.offeringId);
3804
4142
  if (!handler) continue;
3805
4143
  try {
@@ -3822,6 +4160,10 @@ var HandlerProviderRuntime = class {
3822
4160
  if (reqData) {
3823
4161
  context.requirements = reqData.requirements;
3824
4162
  }
4163
+ const schemaValidation = await this.validateSchemaRequirements(context, handler, offering);
4164
+ if (!schemaValidation.valid) {
4165
+ throw new Error(`Schema validation failed for job ${job.jobId}: ${schemaValidation.reason}`);
4166
+ }
3825
4167
  if (handler.validateRequirements) {
3826
4168
  const validation = await handler.validateRequirements(context);
3827
4169
  if (!validation.valid) {
@@ -3842,6 +4184,10 @@ var HandlerProviderRuntime = class {
3842
4184
  }
3843
4185
  }
3844
4186
  async checkInProgressJobs() {
4187
+ const offerings = await this.indexer.getOfferings({ agentId: Number(this.agentId) });
4188
+ const offeringsById = new Map(
4189
+ offerings.map((offering) => [offering.offeringId, offering])
4190
+ );
3845
4191
  const inProgressJobs = await this.indexer.getJobs({
3846
4192
  status: 2,
3847
4193
  agentId: Number(this.agentId)
@@ -3851,6 +4197,7 @@ var HandlerProviderRuntime = class {
3851
4197
  if (!this.canProcess(deliverKey)) continue;
3852
4198
  const handler = this.handlers.get(job.offeringId);
3853
4199
  if (!handler) continue;
4200
+ const offering = offeringsById.get(job.offeringId);
3854
4201
  try {
3855
4202
  if (job.slaMinutes === null) {
3856
4203
  throw new Error(`Job ${job.jobId} is missing slaMinutes`);
@@ -3871,6 +4218,14 @@ var HandlerProviderRuntime = class {
3871
4218
  if (reqData) {
3872
4219
  context.requirements = reqData.requirements;
3873
4220
  }
4221
+ const schemaValidation = await this.validateSchemaRequirements(context, handler, offering);
4222
+ if (!schemaValidation.valid) {
4223
+ this.markFailed(
4224
+ deliverKey,
4225
+ new Error(`Schema validation failed for job ${job.jobId}: ${schemaValidation.reason}`)
4226
+ );
4227
+ continue;
4228
+ }
3874
4229
  if (handler.validateRequirements) {
3875
4230
  const validation = await handler.validateRequirements(context);
3876
4231
  if (!validation.valid) {
@@ -3930,6 +4285,23 @@ var HandlerProviderRuntime = class {
3930
4285
  }
3931
4286
  }
3932
4287
  }
4288
+ async checkEvaluatedJobs() {
4289
+ const evaluatedJobs = await this.indexer.getJobs({
4290
+ status: 4,
4291
+ agentId: Number(this.agentId)
4292
+ });
4293
+ for (const job of evaluatedJobs) {
4294
+ const settleKey = `settle:${job.jobId}`;
4295
+ if (!this.canProcess(settleKey)) continue;
4296
+ try {
4297
+ await settle(this.client, BigInt(job.jobId));
4298
+ console.log(`[handler-provider] auto-settled job ${job.jobId}`);
4299
+ this.markProcessed(settleKey);
4300
+ } catch (e) {
4301
+ this.markFailed(settleKey, e);
4302
+ }
4303
+ }
4304
+ }
3933
4305
  canProcess(key) {
3934
4306
  if (this.processedJobs.has(key)) return false;
3935
4307
  return (this.failedJobs.get(key) ?? 0) < this.maxRetries;
@@ -3947,6 +4319,75 @@ var HandlerProviderRuntime = class {
3947
4319
  this.onError?.(new Error(`Giving up on ${key} after ${retries} failed attempts`));
3948
4320
  }
3949
4321
  }
4322
+ async validateSchemaRequirements(context, handler, offering) {
4323
+ if (offering?.requirementsSchemaUri) {
4324
+ try {
4325
+ const offeringSchema = await this.resolveOfferingSchemaFromUri(offering.requirementsSchemaUri);
4326
+ if (!offeringSchema) {
4327
+ return {
4328
+ valid: false,
4329
+ reason: `Unsupported requirementsSchemaUri format: ${offering.requirementsSchemaUri}`
4330
+ };
4331
+ }
4332
+ return validateAgainstSchema(context.requirements, offeringSchema.serviceRequirements);
4333
+ } catch (error) {
4334
+ return {
4335
+ valid: false,
4336
+ reason: error instanceof Error ? error.message : String(error)
4337
+ };
4338
+ }
4339
+ }
4340
+ const defaultSchema = offering ? DEFAULT_SCHEMAS[offering.serviceType] : void 0;
4341
+ const schema = handler.schema ?? defaultSchema;
4342
+ if (!schema) return { valid: true };
4343
+ return validateAgainstSchema(context.requirements, schema.serviceRequirements);
4344
+ }
4345
+ async resolveOfferingSchemaFromUri(schemaUri) {
4346
+ const cached = this.schemaCache.get(schemaUri);
4347
+ if (cached !== void 0) {
4348
+ return cached;
4349
+ }
4350
+ let schemaPayload;
4351
+ if (schemaUri.startsWith("data:")) {
4352
+ schemaPayload = this.parseDataUriJson(schemaUri);
4353
+ } else if (schemaUri.startsWith("http://") || schemaUri.startsWith("https://")) {
4354
+ const response = await fetch(schemaUri);
4355
+ if (!response.ok) {
4356
+ throw new Error(`Failed to fetch requirements schema URI (${response.status} ${response.statusText})`);
4357
+ }
4358
+ schemaPayload = await response.json();
4359
+ } else if (schemaUri.trim().startsWith("{")) {
4360
+ schemaPayload = JSON.parse(schemaUri);
4361
+ } else {
4362
+ this.schemaCache.set(schemaUri, null);
4363
+ return null;
4364
+ }
4365
+ if (!this.isOfferingSchema(schemaPayload)) {
4366
+ throw new Error("requirementsSchemaUri did not resolve to a valid OfferingSchema document");
4367
+ }
4368
+ this.schemaCache.set(schemaUri, schemaPayload);
4369
+ return schemaPayload;
4370
+ }
4371
+ parseDataUriJson(dataUri) {
4372
+ const commaIndex = dataUri.indexOf(",");
4373
+ if (commaIndex < 0) {
4374
+ throw new Error("Invalid data URI schema format");
4375
+ }
4376
+ const metadata = dataUri.slice(5, commaIndex);
4377
+ const payload = dataUri.slice(commaIndex + 1);
4378
+ const decoded = metadata.includes(";base64") ? new TextDecoder().decode(Uint8Array.from(atob(payload), (char) => char.charCodeAt(0))) : decodeURIComponent(payload);
4379
+ return JSON.parse(decoded);
4380
+ }
4381
+ isOfferingSchema(value) {
4382
+ if (typeof value !== "object" || value === null) return false;
4383
+ const candidate = value;
4384
+ return typeof candidate.version === "number" && this.isJsonSchema(candidate.serviceRequirements) && this.isJsonSchema(candidate.deliverableRequirements);
4385
+ }
4386
+ isJsonSchema(value) {
4387
+ if (typeof value !== "object" || value === null) return false;
4388
+ const candidate = value;
4389
+ return candidate.type === "object" && typeof candidate.properties === "object" && candidate.properties !== null;
4390
+ }
3950
4391
  getRemainingSlaMs(createdAt, acceptedAt, slaMinutes) {
3951
4392
  const start = acceptedAt ?? createdAt;
3952
4393
  if (start === null) return null;
@@ -4802,11 +5243,534 @@ var erc8004ReputationAbi = [
4802
5243
  "anonymous": false
4803
5244
  }
4804
5245
  ];
5246
+
5247
+ // src/abis/BuyerRelay.ts
5248
+ var buyerRelayAbi = [
5249
+ {
5250
+ "type": "constructor",
5251
+ "inputs": [
5252
+ {
5253
+ "name": "owner_",
5254
+ "type": "address",
5255
+ "internalType": "address"
5256
+ },
5257
+ {
5258
+ "name": "identityRegistry_",
5259
+ "type": "address",
5260
+ "internalType": "address"
5261
+ },
5262
+ {
5263
+ "name": "pulseExtension_",
5264
+ "type": "address",
5265
+ "internalType": "address"
5266
+ },
5267
+ {
5268
+ "name": "jobEngine_",
5269
+ "type": "address",
5270
+ "internalType": "address"
5271
+ },
5272
+ {
5273
+ "name": "serviceMarketplace_",
5274
+ "type": "address",
5275
+ "internalType": "address"
5276
+ },
5277
+ {
5278
+ "name": "usdm_",
5279
+ "type": "address",
5280
+ "internalType": "address"
5281
+ }
5282
+ ],
5283
+ "stateMutability": "nonpayable"
5284
+ },
5285
+ {
5286
+ "type": "function",
5287
+ "name": "buyerAgentId",
5288
+ "inputs": [],
5289
+ "outputs": [
5290
+ {
5291
+ "name": "",
5292
+ "type": "uint256",
5293
+ "internalType": "uint256"
5294
+ }
5295
+ ],
5296
+ "stateMutability": "view"
5297
+ },
5298
+ {
5299
+ "type": "function",
5300
+ "name": "cancelFor",
5301
+ "inputs": [
5302
+ {
5303
+ "name": "jobId",
5304
+ "type": "uint256",
5305
+ "internalType": "uint256"
5306
+ }
5307
+ ],
5308
+ "outputs": [],
5309
+ "stateMutability": "nonpayable"
5310
+ },
5311
+ {
5312
+ "type": "function",
5313
+ "name": "claimRefund",
5314
+ "inputs": [
5315
+ {
5316
+ "name": "jobId",
5317
+ "type": "uint256",
5318
+ "internalType": "uint256"
5319
+ }
5320
+ ],
5321
+ "outputs": [],
5322
+ "stateMutability": "nonpayable"
5323
+ },
5324
+ {
5325
+ "type": "function",
5326
+ "name": "createJobFor",
5327
+ "inputs": [
5328
+ {
5329
+ "name": "offeringId",
5330
+ "type": "uint256",
5331
+ "internalType": "uint256"
5332
+ },
5333
+ {
5334
+ "name": "termsHash",
5335
+ "type": "bytes32",
5336
+ "internalType": "bytes32"
5337
+ },
5338
+ {
5339
+ "name": "maxPrice",
5340
+ "type": "uint256",
5341
+ "internalType": "uint256"
5342
+ }
5343
+ ],
5344
+ "outputs": [
5345
+ {
5346
+ "name": "jobId",
5347
+ "type": "uint256",
5348
+ "internalType": "uint256"
5349
+ }
5350
+ ],
5351
+ "stateMutability": "nonpayable"
5352
+ },
5353
+ {
5354
+ "type": "function",
5355
+ "name": "evaluateFor",
5356
+ "inputs": [
5357
+ {
5358
+ "name": "jobId",
5359
+ "type": "uint256",
5360
+ "internalType": "uint256"
5361
+ },
5362
+ {
5363
+ "name": "approved",
5364
+ "type": "bool",
5365
+ "internalType": "bool"
5366
+ },
5367
+ {
5368
+ "name": "feedback",
5369
+ "type": "string",
5370
+ "internalType": "string"
5371
+ }
5372
+ ],
5373
+ "outputs": [],
5374
+ "stateMutability": "nonpayable"
5375
+ },
5376
+ {
5377
+ "type": "function",
5378
+ "name": "identityRegistry",
5379
+ "inputs": [],
5380
+ "outputs": [
5381
+ {
5382
+ "name": "",
5383
+ "type": "address",
5384
+ "internalType": "contract IERC8004Identity"
5385
+ }
5386
+ ],
5387
+ "stateMutability": "view"
5388
+ },
5389
+ {
5390
+ "type": "function",
5391
+ "name": "jobDeposit",
5392
+ "inputs": [
5393
+ {
5394
+ "name": "",
5395
+ "type": "uint256",
5396
+ "internalType": "uint256"
5397
+ }
5398
+ ],
5399
+ "outputs": [
5400
+ {
5401
+ "name": "",
5402
+ "type": "uint256",
5403
+ "internalType": "uint256"
5404
+ }
5405
+ ],
5406
+ "stateMutability": "view"
5407
+ },
5408
+ {
5409
+ "type": "function",
5410
+ "name": "jobEngine",
5411
+ "inputs": [],
5412
+ "outputs": [
5413
+ {
5414
+ "name": "",
5415
+ "type": "address",
5416
+ "internalType": "contract IJobEngine"
5417
+ }
5418
+ ],
5419
+ "stateMutability": "view"
5420
+ },
5421
+ {
5422
+ "type": "function",
5423
+ "name": "jobPayer",
5424
+ "inputs": [
5425
+ {
5426
+ "name": "",
5427
+ "type": "uint256",
5428
+ "internalType": "uint256"
5429
+ }
5430
+ ],
5431
+ "outputs": [
5432
+ {
5433
+ "name": "",
5434
+ "type": "address",
5435
+ "internalType": "address"
5436
+ }
5437
+ ],
5438
+ "stateMutability": "view"
5439
+ },
5440
+ {
5441
+ "type": "function",
5442
+ "name": "jobRefundState",
5443
+ "inputs": [
5444
+ {
5445
+ "name": "",
5446
+ "type": "uint256",
5447
+ "internalType": "uint256"
5448
+ }
5449
+ ],
5450
+ "outputs": [
5451
+ {
5452
+ "name": "",
5453
+ "type": "uint8",
5454
+ "internalType": "enum IBuyerRelay.RefundState"
5455
+ }
5456
+ ],
5457
+ "stateMutability": "view"
5458
+ },
5459
+ {
5460
+ "type": "function",
5461
+ "name": "onERC721Received",
5462
+ "inputs": [
5463
+ {
5464
+ "name": "",
5465
+ "type": "address",
5466
+ "internalType": "address"
5467
+ },
5468
+ {
5469
+ "name": "",
5470
+ "type": "address",
5471
+ "internalType": "address"
5472
+ },
5473
+ {
5474
+ "name": "",
5475
+ "type": "uint256",
5476
+ "internalType": "uint256"
5477
+ },
5478
+ {
5479
+ "name": "",
5480
+ "type": "bytes",
5481
+ "internalType": "bytes"
5482
+ }
5483
+ ],
5484
+ "outputs": [
5485
+ {
5486
+ "name": "",
5487
+ "type": "bytes4",
5488
+ "internalType": "bytes4"
5489
+ }
5490
+ ],
5491
+ "stateMutability": "pure"
5492
+ },
5493
+ {
5494
+ "type": "function",
5495
+ "name": "owner",
5496
+ "inputs": [],
5497
+ "outputs": [
5498
+ {
5499
+ "name": "",
5500
+ "type": "address",
5501
+ "internalType": "address"
5502
+ }
5503
+ ],
5504
+ "stateMutability": "view"
5505
+ },
5506
+ {
5507
+ "type": "function",
5508
+ "name": "pulseExtension",
5509
+ "inputs": [],
5510
+ "outputs": [
5511
+ {
5512
+ "name": "",
5513
+ "type": "address",
5514
+ "internalType": "contract IPulseExtension"
5515
+ }
5516
+ ],
5517
+ "stateMutability": "view"
5518
+ },
5519
+ {
5520
+ "type": "function",
5521
+ "name": "renounceOwnership",
5522
+ "inputs": [],
5523
+ "outputs": [],
5524
+ "stateMutability": "nonpayable"
5525
+ },
5526
+ {
5527
+ "type": "function",
5528
+ "name": "serviceMarketplace",
5529
+ "inputs": [],
5530
+ "outputs": [
5531
+ {
5532
+ "name": "",
5533
+ "type": "address",
5534
+ "internalType": "contract IServiceMarketplace"
5535
+ }
5536
+ ],
5537
+ "stateMutability": "view"
5538
+ },
5539
+ {
5540
+ "type": "function",
5541
+ "name": "setup",
5542
+ "inputs": [
5543
+ {
5544
+ "name": "agentURI",
5545
+ "type": "string",
5546
+ "internalType": "string"
5547
+ }
5548
+ ],
5549
+ "outputs": [],
5550
+ "stateMutability": "nonpayable"
5551
+ },
5552
+ {
5553
+ "type": "function",
5554
+ "name": "transferOwnership",
5555
+ "inputs": [
5556
+ {
5557
+ "name": "newOwner",
5558
+ "type": "address",
5559
+ "internalType": "address"
5560
+ }
5561
+ ],
5562
+ "outputs": [],
5563
+ "stateMutability": "nonpayable"
5564
+ },
5565
+ {
5566
+ "type": "function",
5567
+ "name": "usdm",
5568
+ "inputs": [],
5569
+ "outputs": [
5570
+ {
5571
+ "name": "",
5572
+ "type": "address",
5573
+ "internalType": "address"
5574
+ }
5575
+ ],
5576
+ "stateMutability": "view"
5577
+ },
5578
+ {
5579
+ "type": "event",
5580
+ "name": "EvaluatedFor",
5581
+ "inputs": [
5582
+ {
5583
+ "name": "jobId",
5584
+ "type": "uint256",
5585
+ "indexed": true,
5586
+ "internalType": "uint256"
5587
+ },
5588
+ {
5589
+ "name": "payer",
5590
+ "type": "address",
5591
+ "indexed": true,
5592
+ "internalType": "address"
5593
+ },
5594
+ {
5595
+ "name": "approved",
5596
+ "type": "bool",
5597
+ "indexed": false,
5598
+ "internalType": "bool"
5599
+ }
5600
+ ],
5601
+ "anonymous": false
5602
+ },
5603
+ {
5604
+ "type": "event",
5605
+ "name": "JobCreatedFor",
5606
+ "inputs": [
5607
+ {
5608
+ "name": "jobId",
5609
+ "type": "uint256",
5610
+ "indexed": true,
5611
+ "internalType": "uint256"
5612
+ },
5613
+ {
5614
+ "name": "payer",
5615
+ "type": "address",
5616
+ "indexed": true,
5617
+ "internalType": "address"
5618
+ },
5619
+ {
5620
+ "name": "price",
5621
+ "type": "uint256",
5622
+ "indexed": false,
5623
+ "internalType": "uint256"
5624
+ }
5625
+ ],
5626
+ "anonymous": false
5627
+ },
5628
+ {
5629
+ "type": "event",
5630
+ "name": "OwnershipTransferred",
5631
+ "inputs": [
5632
+ {
5633
+ "name": "previousOwner",
5634
+ "type": "address",
5635
+ "indexed": true,
5636
+ "internalType": "address"
5637
+ },
5638
+ {
5639
+ "name": "newOwner",
5640
+ "type": "address",
5641
+ "indexed": true,
5642
+ "internalType": "address"
5643
+ }
5644
+ ],
5645
+ "anonymous": false
5646
+ },
5647
+ {
5648
+ "type": "event",
5649
+ "name": "RefundClaimed",
5650
+ "inputs": [
5651
+ {
5652
+ "name": "jobId",
5653
+ "type": "uint256",
5654
+ "indexed": true,
5655
+ "internalType": "uint256"
5656
+ },
5657
+ {
5658
+ "name": "payer",
5659
+ "type": "address",
5660
+ "indexed": true,
5661
+ "internalType": "address"
5662
+ },
5663
+ {
5664
+ "name": "amount",
5665
+ "type": "uint256",
5666
+ "indexed": false,
5667
+ "internalType": "uint256"
5668
+ }
5669
+ ],
5670
+ "anonymous": false
5671
+ },
5672
+ {
5673
+ "type": "error",
5674
+ "name": "AgentAlreadyInitialized",
5675
+ "inputs": []
5676
+ },
5677
+ {
5678
+ "type": "error",
5679
+ "name": "AgentNotActive",
5680
+ "inputs": []
5681
+ },
5682
+ {
5683
+ "type": "error",
5684
+ "name": "InsufficientPayment",
5685
+ "inputs": [
5686
+ {
5687
+ "name": "required",
5688
+ "type": "uint256",
5689
+ "internalType": "uint256"
5690
+ },
5691
+ {
5692
+ "name": "provided",
5693
+ "type": "uint256",
5694
+ "internalType": "uint256"
5695
+ }
5696
+ ]
5697
+ },
5698
+ {
5699
+ "type": "error",
5700
+ "name": "InvalidJobStatus",
5701
+ "inputs": [
5702
+ {
5703
+ "name": "current",
5704
+ "type": "uint8",
5705
+ "internalType": "enum DataTypes.JobStatus"
5706
+ },
5707
+ {
5708
+ "name": "expected",
5709
+ "type": "uint8",
5710
+ "internalType": "enum DataTypes.JobStatus"
5711
+ }
5712
+ ]
5713
+ },
5714
+ {
5715
+ "type": "error",
5716
+ "name": "InvalidRefundState",
5717
+ "inputs": [
5718
+ {
5719
+ "name": "current",
5720
+ "type": "uint8",
5721
+ "internalType": "enum IBuyerRelay.RefundState"
5722
+ },
5723
+ {
5724
+ "name": "expected",
5725
+ "type": "uint8",
5726
+ "internalType": "enum IBuyerRelay.RefundState"
5727
+ }
5728
+ ]
5729
+ },
5730
+ {
5731
+ "type": "error",
5732
+ "name": "OnlyBuyer",
5733
+ "inputs": []
5734
+ },
5735
+ {
5736
+ "type": "error",
5737
+ "name": "OwnableInvalidOwner",
5738
+ "inputs": [
5739
+ {
5740
+ "name": "owner",
5741
+ "type": "address",
5742
+ "internalType": "address"
5743
+ }
5744
+ ]
5745
+ },
5746
+ {
5747
+ "type": "error",
5748
+ "name": "OwnableUnauthorizedAccount",
5749
+ "inputs": [
5750
+ {
5751
+ "name": "account",
5752
+ "type": "address",
5753
+ "internalType": "address"
5754
+ }
5755
+ ]
5756
+ },
5757
+ {
5758
+ "type": "error",
5759
+ "name": "Reentrancy",
5760
+ "inputs": []
5761
+ },
5762
+ {
5763
+ "type": "error",
5764
+ "name": "ZeroAddress",
5765
+ "inputs": []
5766
+ }
5767
+ ];
4805
5768
  export {
4806
5769
  ACCEPT_TIMEOUT,
4807
5770
  BPS_DENOMINATOR,
4808
5771
  BuyerRuntime,
4809
5772
  DEFAULT_INDEXER_URLS,
5773
+ DEFAULT_SCHEMAS,
4810
5774
  EVALUATION_TIMEOUT,
4811
5775
  FEE_BPS,
4812
5776
  HandlerProviderRuntime,
@@ -4815,6 +5779,7 @@ export {
4815
5779
  JobStatus,
4816
5780
  MAINNET_ADDRESSES,
4817
5781
  MEMO_TYPES,
5782
+ PLATFORM_BUYER_AGENT_ID,
4818
5783
  PULSE_DOMAIN,
4819
5784
  ProviderRuntime,
4820
5785
  RISK_POOL_BPS,
@@ -4825,6 +5790,7 @@ export {
4825
5790
  USDM_MAINNET,
4826
5791
  acceptJob,
4827
5792
  activateOffering,
5793
+ buyerRelayAbi,
4828
5794
  callAI,
4829
5795
  cancelJob,
4830
5796
  createAgentCard,
@@ -4878,6 +5844,7 @@ export {
4878
5844
  submitDeliverable,
4879
5845
  testnetERC8004,
4880
5846
  updateOffering,
5847
+ validateAgainstSchema,
4881
5848
  verifyContentHash
4882
5849
  };
4883
5850
  //# sourceMappingURL=index.js.map