@pulseai/sdk 0.1.2 → 0.1.4

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
@@ -13,6 +13,9 @@ var megaethTestnet = defineChain({
13
13
  nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
14
14
  rpcUrls: {
15
15
  default: { http: ["https://carrot.megaeth.com/rpc"] }
16
+ },
17
+ blockExplorers: {
18
+ default: { name: "Blockscout", url: "https://megaeth-testnet-v2.blockscout.com" }
16
19
  }
17
20
  });
18
21
  var megaethMainnet = defineChain({
@@ -21,6 +24,9 @@ var megaethMainnet = defineChain({
21
24
  nativeCurrency: { name: "ETH", symbol: "ETH", decimals: 18 },
22
25
  rpcUrls: {
23
26
  default: { http: ["https://mainnet.megaeth.com/rpc"] }
27
+ },
28
+ blockExplorers: {
29
+ default: { name: "Blockscout", url: "https://megaeth.blockscout.com" }
24
30
  }
25
31
  });
26
32
 
@@ -36,15 +42,15 @@ var TESTNET_ADDRESSES = {
36
42
  };
37
43
  var MAINNET_ADDRESSES = {
38
44
  pulseExtension: "0xf1616D2008c4Ff5Ed7BDBd448DAE68615b7A71f0",
39
- serviceMarketplace: "0xfC180058FCB69531818B832C12473302811dfFF6",
45
+ serviceMarketplace: "0x0573C91396184323979F3f7b322C694932F91D44",
40
46
  jobEngine: "0xb5E56262b55aE453E8B16470228F0a5Ef617FF67",
41
47
  feeDistributor: "0x51EdD8E4C4B423b952821fc9e2a7dad15a858B56",
42
48
  identityRegistry: "0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
43
49
  reputationRegistry: "0x8004BAa17C55a88189AE136b182e5fdA19dE9b63",
44
50
  usdm: "0xFAfDdbb3FC7688494971a79cc65DCa3EF82079E7",
45
- buyerRelay: "0x633054593db34c5aAe36F784faeAe51b9604e037"
51
+ buyerRelay: "0x843B5B4AD44C174BAB8bBe11eb001aD7fE70647A"
46
52
  };
47
- var PLATFORM_BUYER_AGENT_ID = 8154n;
53
+ var PLATFORM_BUYER_AGENT_ID = 8155n;
48
54
  var DEFAULT_INDEXER_URLS = {
49
55
  testnet: "https://pulse-indexer.up.railway.app",
50
56
  mainnet: "https://pulse-indexer.up.railway.app"
@@ -1034,6 +1040,11 @@ var serviceMarketplaceAbi = [
1034
1040
  "type": "uint32",
1035
1041
  "internalType": "uint32"
1036
1042
  },
1043
+ {
1044
+ "name": "name",
1045
+ "type": "string",
1046
+ "internalType": "string"
1047
+ },
1037
1048
  {
1038
1049
  "name": "description",
1039
1050
  "type": "string",
@@ -1104,6 +1115,11 @@ var serviceMarketplaceAbi = [
1104
1115
  "type": "uint32",
1105
1116
  "internalType": "uint32"
1106
1117
  },
1118
+ {
1119
+ "name": "name",
1120
+ "type": "string",
1121
+ "internalType": "string"
1122
+ },
1107
1123
  {
1108
1124
  "name": "description",
1109
1125
  "type": "string",
@@ -1156,6 +1172,11 @@ var serviceMarketplaceAbi = [
1156
1172
  "type": "uint32",
1157
1173
  "internalType": "uint32"
1158
1174
  },
1175
+ {
1176
+ "name": "name",
1177
+ "type": "string",
1178
+ "internalType": "string"
1179
+ },
1159
1180
  {
1160
1181
  "name": "description",
1161
1182
  "type": "string",
@@ -1165,6 +1186,24 @@ var serviceMarketplaceAbi = [
1165
1186
  "outputs": [],
1166
1187
  "stateMutability": "nonpayable"
1167
1188
  },
1189
+ {
1190
+ "type": "function",
1191
+ "name": "updateOfferingSchema",
1192
+ "inputs": [
1193
+ {
1194
+ "name": "offeringId",
1195
+ "type": "uint256",
1196
+ "internalType": "uint256"
1197
+ },
1198
+ {
1199
+ "name": "requirementsSchemaURI",
1200
+ "type": "string",
1201
+ "internalType": "string"
1202
+ }
1203
+ ],
1204
+ "outputs": [],
1205
+ "stateMutability": "nonpayable"
1206
+ },
1168
1207
  {
1169
1208
  "type": "event",
1170
1209
  "name": "OfferingActivated",
@@ -1222,6 +1261,25 @@ var serviceMarketplaceAbi = [
1222
1261
  ],
1223
1262
  "anonymous": false
1224
1263
  },
1264
+ {
1265
+ "type": "event",
1266
+ "name": "OfferingSchemaUpdated",
1267
+ "inputs": [
1268
+ {
1269
+ "name": "offeringId",
1270
+ "type": "uint256",
1271
+ "indexed": true,
1272
+ "internalType": "uint256"
1273
+ },
1274
+ {
1275
+ "name": "requirementsSchemaURI",
1276
+ "type": "string",
1277
+ "indexed": false,
1278
+ "internalType": "string"
1279
+ }
1280
+ ],
1281
+ "anonymous": false
1282
+ },
1225
1283
  {
1226
1284
  "type": "event",
1227
1285
  "name": "OfferingUpdated",
@@ -1285,6 +1343,7 @@ async function listOffering(client, params) {
1285
1343
  params.serviceType,
1286
1344
  params.priceUSDm,
1287
1345
  params.slaMinutes,
1346
+ params.name,
1288
1347
  params.description,
1289
1348
  params.requirementsSchemaURI ?? ""
1290
1349
  ]
@@ -1296,12 +1355,20 @@ async function listOffering(client, params) {
1296
1355
  const offeringId = offeringLog?.topics[1] ? BigInt(offeringLog.topics[1]) : 0n;
1297
1356
  return { offeringId, txHash };
1298
1357
  }
1299
- async function updateOffering(client, offeringId, priceUSDm, slaMinutes, description) {
1358
+ async function updateOffering(client, offeringId, priceUSDm, slaMinutes, name, description) {
1300
1359
  return write(client, {
1301
1360
  address: client.addresses.serviceMarketplace,
1302
1361
  abi: serviceMarketplaceAbi,
1303
1362
  functionName: "updateOffering",
1304
- args: [offeringId, priceUSDm, slaMinutes, description]
1363
+ args: [offeringId, priceUSDm, slaMinutes, name, description]
1364
+ });
1365
+ }
1366
+ async function updateOfferingSchema(client, offeringId, requirementsSchemaURI) {
1367
+ return write(client, {
1368
+ address: client.addresses.serviceMarketplace,
1369
+ abi: serviceMarketplaceAbi,
1370
+ functionName: "updateOfferingSchema",
1371
+ args: [offeringId, requirementsSchemaURI]
1305
1372
  });
1306
1373
  }
1307
1374
  async function deactivateOffering(client, offeringId) {
@@ -1337,6 +1404,9 @@ async function getOfferingCount(client) {
1337
1404
  });
1338
1405
  }
1339
1406
 
1407
+ // src/jobs/index.ts
1408
+ import { maxUint256 } from "viem";
1409
+
1340
1410
  // src/abis/JobEngine.ts
1341
1411
  var jobEngineAbi = [
1342
1412
  {
@@ -1812,6 +1882,19 @@ var jobEngineAbi = [
1812
1882
  ],
1813
1883
  "stateMutability": "view"
1814
1884
  },
1885
+ {
1886
+ "type": "function",
1887
+ "name": "setServiceMarketplace",
1888
+ "inputs": [
1889
+ {
1890
+ "name": "newMarketplace",
1891
+ "type": "address",
1892
+ "internalType": "address"
1893
+ }
1894
+ ],
1895
+ "outputs": [],
1896
+ "stateMutability": "nonpayable"
1897
+ },
1815
1898
  {
1816
1899
  "type": "function",
1817
1900
  "name": "settle",
@@ -2088,6 +2171,25 @@ var jobEngineAbi = [
2088
2171
  ],
2089
2172
  "anonymous": false
2090
2173
  },
2174
+ {
2175
+ "type": "event",
2176
+ "name": "ServiceMarketplaceUpdated",
2177
+ "inputs": [
2178
+ {
2179
+ "name": "oldMarketplace",
2180
+ "type": "address",
2181
+ "indexed": true,
2182
+ "internalType": "address"
2183
+ },
2184
+ {
2185
+ "name": "newMarketplace",
2186
+ "type": "address",
2187
+ "indexed": true,
2188
+ "internalType": "address"
2189
+ }
2190
+ ],
2191
+ "anonymous": false
2192
+ },
2091
2193
  {
2092
2194
  "type": "event",
2093
2195
  "name": "Upgraded",
@@ -2339,6 +2441,7 @@ async function signMemo(walletClient, params) {
2339
2441
 
2340
2442
  // src/jobs/index.ts
2341
2443
  async function createJob(client, params) {
2444
+ const { account } = requireWallet(client);
2342
2445
  const offering = await client.publicClient.readContract({
2343
2446
  address: client.addresses.serviceMarketplace,
2344
2447
  abi: serviceMarketplaceAbi,
@@ -2346,13 +2449,21 @@ async function createJob(client, params) {
2346
2449
  args: [params.offeringId]
2347
2450
  });
2348
2451
  const price = offering.priceUSDm;
2349
- const approveTx = await write(client, {
2452
+ const allowance = await client.publicClient.readContract({
2350
2453
  address: client.addresses.usdm,
2351
2454
  abi: erc20Abi,
2352
- functionName: "approve",
2353
- args: [client.addresses.jobEngine, price]
2455
+ functionName: "allowance",
2456
+ args: [account.address, client.addresses.jobEngine]
2354
2457
  });
2355
- await client.publicClient.waitForTransactionReceipt({ hash: approveTx });
2458
+ if (allowance < price) {
2459
+ const approveTx = await write(client, {
2460
+ address: client.addresses.usdm,
2461
+ abi: erc20Abi,
2462
+ functionName: "approve",
2463
+ args: [client.addresses.jobEngine, maxUint256]
2464
+ });
2465
+ await client.publicClient.waitForTransactionReceipt({ hash: approveTx });
2466
+ }
2356
2467
  const txHash = await write(client, {
2357
2468
  address: client.addresses.jobEngine,
2358
2469
  abi: jobEngineAbi,
@@ -2666,39 +2777,14 @@ async function deployJobTerms(client, agentId, params) {
2666
2777
  const { masterAddress } = await deployWarrenMaster(client, agentId, pageAddress, contentBytes.length, 0);
2667
2778
  return { masterAddress, pageAddress, hash, txHash };
2668
2779
  }
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
- }
2675
- async function deployDeliverable(client, agentId, jobId, params, indexerUrl) {
2780
+ async function deployDeliverable(client, jobId, params, indexerUrl) {
2676
2781
  const { json, hash } = createDeliverable(params);
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);
2680
- const { masterAddress } = await deployWarrenMaster(client, agentId, pageAddress, contentBytes.length, 1);
2681
- await write(client, {
2782
+ const txHash = await write(client, {
2682
2783
  address: client.addresses.jobEngine,
2683
2784
  abi: jobEngineAbi,
2684
2785
  functionName: "submitDeliverable",
2685
2786
  args: [jobId, hash]
2686
2787
  });
2687
- if (indexerUrl) {
2688
- try {
2689
- await fetch(`${indexerUrl}/warren-links`, {
2690
- method: "POST",
2691
- headers: { "Content-Type": "application/json" },
2692
- body: JSON.stringify({
2693
- jobId: Number(jobId),
2694
- linkType: "deliverable",
2695
- masterAddress,
2696
- contentHash: hash
2697
- })
2698
- });
2699
- } catch {
2700
- }
2701
- }
2702
2788
  if (indexerUrl) {
2703
2789
  try {
2704
2790
  await fetch(`${indexerUrl.replace(/\/$/, "")}/deliverables`, {
@@ -2708,24 +2794,23 @@ async function deployDeliverable(client, agentId, jobId, params, indexerUrl) {
2708
2794
  jobId: Number(jobId),
2709
2795
  content: json,
2710
2796
  contentHash: hash,
2711
- storageType: "warren"
2797
+ storageType: "deliverable"
2712
2798
  })
2713
2799
  });
2714
2800
  } catch {
2715
2801
  }
2716
2802
  }
2717
- return { masterAddress, pageAddress, hash, txHash };
2803
+ return { hash, txHash };
2718
2804
  }
2719
- async function readDeliverable(client, jobId, indexerUrl) {
2720
- const res = await fetch(`${indexerUrl}/warren-links/${Number(jobId)}`);
2721
- if (!res.ok) throw new Error(`Failed to fetch warren link for job ${jobId}`);
2805
+ async function readDeliverable(jobId, indexerUrl) {
2806
+ const res = await fetch(`${indexerUrl.replace(/\/$/, "")}/deliverables/${Number(jobId)}`);
2807
+ if (!res.ok) throw new Error(`Failed to fetch deliverable for job ${jobId}`);
2722
2808
  const { data } = await res.json();
2723
- if (!data.deliverable) throw new Error(`No deliverable WARREN link for job ${jobId}`);
2724
- const content = await readWarrenMaster(client, data.deliverable.master_address);
2725
- if (!verifyContentHash(content, data.deliverable.content_hash)) {
2809
+ if (!data?.content) throw new Error(`No deliverable content for job ${jobId}`);
2810
+ if (!verifyContentHash(data.content, data.content_hash)) {
2726
2811
  throw new Error("Deliverable content hash mismatch");
2727
2812
  }
2728
- return JSON.parse(content);
2813
+ return JSON.parse(data.content);
2729
2814
  }
2730
2815
  async function deployRequirements(client, agentId, jobId, params, indexerUrl) {
2731
2816
  const { json, hash } = createRequirements(params);
@@ -2881,7 +2966,7 @@ async function callOpenAI(params) {
2881
2966
  role: message.role,
2882
2967
  content: message.content
2883
2968
  })),
2884
- max_tokens: params.maxTokens
2969
+ max_completion_tokens: params.maxTokens
2885
2970
  }),
2886
2971
  signal: params.signal
2887
2972
  });
@@ -2896,7 +2981,8 @@ async function callOpenAI(params) {
2896
2981
  throw new Error("OpenAI returned an empty response");
2897
2982
  }
2898
2983
  const truncated = payload?.choices?.[0]?.finish_reason === "length";
2899
- return { content, truncated, raw: payload };
2984
+ const usage = payload?.usage ? { inputTokens: payload.usage.prompt_tokens ?? 0, outputTokens: payload.usage.completion_tokens ?? 0 } : void 0;
2985
+ return { content, truncated, raw: payload, usage };
2900
2986
  }
2901
2987
  async function callAnthropic(params) {
2902
2988
  const systemPrompt = params.messages.filter((message) => message.role === "system").map((message) => message.content).join("\n\n").trim();
@@ -2930,7 +3016,8 @@ async function callAnthropic(params) {
2930
3016
  throw new Error("Anthropic returned an empty response");
2931
3017
  }
2932
3018
  const truncated = payload?.stop_reason === "max_tokens";
2933
- return { content, truncated, raw: payload };
3019
+ const usage = payload?.usage ? { inputTokens: payload.usage.input_tokens ?? 0, outputTokens: payload.usage.output_tokens ?? 0 } : void 0;
3020
+ return { content, truncated, raw: payload, usage };
2934
3021
  }
2935
3022
  async function callGoogle(params) {
2936
3023
  const systemPrompt = params.messages.filter((message) => message.role === "system").map((message) => message.content).join("\n\n").trim();
@@ -2965,7 +3052,8 @@ async function callGoogle(params) {
2965
3052
  throw new Error("Google returned an empty response");
2966
3053
  }
2967
3054
  const truncated = payload?.candidates?.[0]?.finishReason === "MAX_TOKENS";
2968
- return { content, truncated, raw: payload };
3055
+ const usage = payload?.usageMetadata ? { inputTokens: payload.usageMetadata.promptTokenCount ?? 0, outputTokens: payload.usageMetadata.candidatesTokenCount ?? 0 } : void 0;
3056
+ return { content, truncated, raw: payload, usage };
2969
3057
  }
2970
3058
  async function callAI(params) {
2971
3059
  if (params.provider === "openai") {
@@ -2989,8 +3077,8 @@ var RETRY_DELAY_MS = 2e3;
2989
3077
  var GOOGLE_FALLBACK_MODEL = "gemini-2.5-pro";
2990
3078
  var SUPPORTED_PROVIDERS = ["anthropic", "google", "openai"];
2991
3079
  var DEFAULT_MODELS = {
2992
- openai: "gpt-4o-mini",
2993
- anthropic: "claude-3-5-sonnet-latest",
3080
+ openai: "gpt-5.2",
3081
+ anthropic: "claude-sonnet-4-6",
2994
3082
  google: "gemini-3.1-pro-preview"
2995
3083
  };
2996
3084
  var DEFAULT_SYSTEM_PROMPT = [
@@ -3034,6 +3122,16 @@ function parseAndValidateUrl(urlString) {
3034
3122
  }
3035
3123
  return url;
3036
3124
  }
3125
+ function normalizeWarrenUrl(url) {
3126
+ const host = url.hostname.toLowerCase();
3127
+ if (host !== "thewarren.app" && !host.endsWith(".thewarren.app")) return url;
3128
+ const match = url.pathname.match(/^\/v\/site=(\d+)$/);
3129
+ if (!match) return url;
3130
+ const normalized = new URL(url.origin);
3131
+ normalized.pathname = "/api/source";
3132
+ normalized.searchParams.set("site", match[1]);
3133
+ return normalized;
3134
+ }
3037
3135
  function ensureAllowedUrl(url, allowedDomains) {
3038
3136
  if (!allowedDomains || allowedDomains.length === 0) return;
3039
3137
  if (!isAllowedDomain(url.hostname, allowedDomains)) {
@@ -3110,6 +3208,52 @@ function getByteLength(content) {
3110
3208
  var SiteModifierHandler = class {
3111
3209
  offeringId;
3112
3210
  autoAccept;
3211
+ schema = {
3212
+ version: 1,
3213
+ serviceRequirements: {
3214
+ type: "object",
3215
+ properties: {
3216
+ siteUrl: {
3217
+ type: "string",
3218
+ description: "URL of the site to modify (http/https)"
3219
+ },
3220
+ modificationRequest: {
3221
+ type: "string",
3222
+ description: "What changes to make"
3223
+ },
3224
+ provider: {
3225
+ type: "string",
3226
+ description: "AI provider",
3227
+ enum: ["google", "anthropic", "openai"]
3228
+ },
3229
+ model: {
3230
+ type: "string",
3231
+ description: "Specific model override"
3232
+ }
3233
+ },
3234
+ required: ["siteUrl", "modificationRequest"]
3235
+ },
3236
+ deliverableRequirements: {
3237
+ type: "object",
3238
+ properties: {
3239
+ type: {
3240
+ type: "string",
3241
+ description: 'Delivery type, always "inline"',
3242
+ enum: ["inline"]
3243
+ },
3244
+ content: {
3245
+ type: "string",
3246
+ description: "Modified HTML content"
3247
+ },
3248
+ mimeType: {
3249
+ type: "string",
3250
+ description: 'Content type, always "text/html"',
3251
+ enum: ["text/html"]
3252
+ }
3253
+ },
3254
+ required: ["type", "content", "mimeType"]
3255
+ }
3256
+ };
3113
3257
  config;
3114
3258
  constructor(offeringId, config, options) {
3115
3259
  this.offeringId = offeringId;
@@ -3132,7 +3276,8 @@ var SiteModifierHandler = class {
3132
3276
  const targetUrl = parseAndValidateUrl(requirements.siteUrl);
3133
3277
  ensureAllowedUrl(targetUrl, this.config.allowedDomains);
3134
3278
  const provider = requirements.provider ?? this.config.defaultProvider ?? "openai";
3135
- const model = requirements.model?.trim() || this.config.defaultModel?.trim() || DEFAULT_MODELS[provider];
3279
+ const useConfigModel = provider === (this.config.defaultProvider ?? "openai");
3280
+ const model = requirements.model?.trim() || (useConfigModel ? this.config.defaultModel?.trim() : void 0) || DEFAULT_MODELS[provider];
3136
3281
  const maxTokens = this.config.maxTokens && this.config.maxTokens > 0 ? this.config.maxTokens : DEFAULT_MAX_TOKENS;
3137
3282
  if (!model) {
3138
3283
  throw new Error(
@@ -3235,7 +3380,8 @@ var SiteModifierHandler = class {
3235
3380
  return {
3236
3381
  type: "inline",
3237
3382
  content: modifiedHtml,
3238
- mimeType: "text/html"
3383
+ mimeType: "text/html",
3384
+ usage: aiResponse.usage ? { provider, inputTokens: aiResponse.usage.inputTokens, outputTokens: aiResponse.usage.outputTokens } : void 0
3239
3385
  };
3240
3386
  }
3241
3387
  parseRequirements(requirements) {
@@ -3246,7 +3392,7 @@ var SiteModifierHandler = class {
3246
3392
  if (!isNonEmptyString(siteUrl)) {
3247
3393
  throw new Error("requirements.siteUrl must be a non-empty string");
3248
3394
  }
3249
- const parsedUrl = parseAndValidateUrl(siteUrl);
3395
+ const parsedUrl = normalizeWarrenUrl(parseAndValidateUrl(siteUrl));
3250
3396
  ensureAllowedUrl(parsedUrl, this.config.allowedDomains);
3251
3397
  const modificationRequest = requirements.modificationRequest;
3252
3398
  if (!isNonEmptyString(modificationRequest)) {
@@ -3265,7 +3411,7 @@ var SiteModifierHandler = class {
3265
3411
  throw new Error("requirements.model must be a non-empty string");
3266
3412
  }
3267
3413
  return {
3268
- siteUrl: siteUrl.trim(),
3414
+ siteUrl: parsedUrl.toString(),
3269
3415
  modificationRequest: modificationRequest.trim(),
3270
3416
  provider,
3271
3417
  model: typeof model === "string" ? model.trim() : void 0
@@ -3351,6 +3497,334 @@ var SiteModifierHandler = class {
3351
3497
  }
3352
3498
  };
3353
3499
 
3500
+ // src/handler/prompt-handler.ts
3501
+ var DEFAULT_MAX_TOKENS2 = 8192;
3502
+ var AI_MAX_RETRIES2 = 3;
3503
+ var RETRY_DELAY_MS2 = 2e3;
3504
+ var DEFAULT_MODELS2 = {
3505
+ openai: "gpt-5.2",
3506
+ anthropic: "claude-sonnet-4-6",
3507
+ google: "gemini-3.1-pro-preview"
3508
+ };
3509
+ function isRecord2(value) {
3510
+ return typeof value === "object" && value !== null;
3511
+ }
3512
+ function isNonEmptyString2(value) {
3513
+ return typeof value === "string" && value.trim().length > 0;
3514
+ }
3515
+ var PromptHandler = class {
3516
+ offeringId;
3517
+ autoAccept = true;
3518
+ schema = {
3519
+ version: 1,
3520
+ serviceRequirements: {
3521
+ type: "object",
3522
+ properties: {
3523
+ prompt: {
3524
+ type: "string",
3525
+ description: "Prompt to send to AI"
3526
+ },
3527
+ context: {
3528
+ type: "string",
3529
+ description: "Optional additional context"
3530
+ }
3531
+ },
3532
+ required: ["prompt"]
3533
+ },
3534
+ deliverableRequirements: {
3535
+ type: "object",
3536
+ properties: {
3537
+ type: {
3538
+ type: "string",
3539
+ description: 'Delivery type, always "inline"',
3540
+ enum: ["inline"]
3541
+ },
3542
+ content: {
3543
+ type: "string",
3544
+ description: "Generated markdown content"
3545
+ },
3546
+ mimeType: {
3547
+ type: "string",
3548
+ description: 'Content type, always "text/markdown"',
3549
+ enum: ["text/markdown"]
3550
+ }
3551
+ },
3552
+ required: ["type", "content", "mimeType"]
3553
+ }
3554
+ };
3555
+ config;
3556
+ constructor(offeringId, config) {
3557
+ this.offeringId = offeringId;
3558
+ this.config = config;
3559
+ }
3560
+ async validateRequirements(context) {
3561
+ try {
3562
+ this.parseRequirements(context.requirements);
3563
+ return { valid: true };
3564
+ } catch (error) {
3565
+ return {
3566
+ valid: false,
3567
+ reason: error instanceof Error ? error.message : String(error)
3568
+ };
3569
+ }
3570
+ }
3571
+ async executeJob(context) {
3572
+ const requirements = this.parseRequirements(context.requirements);
3573
+ const provider = this.config.aiProvider;
3574
+ const model = this.config.aiModel?.trim() || DEFAULT_MODELS2[provider];
3575
+ const maxTokens = this.config.maxTokens && this.config.maxTokens > 0 ? this.config.maxTokens : DEFAULT_MAX_TOKENS2;
3576
+ const apiKey = await this.config.getApiKey(provider);
3577
+ if (!isNonEmptyString2(apiKey)) {
3578
+ throw new Error(`Missing API key for provider "${provider}"`);
3579
+ }
3580
+ const userPrompt = requirements.context ? [requirements.prompt, requirements.context].join("\n\n") : requirements.prompt;
3581
+ const aiMessages = [
3582
+ { role: "system", content: this.config.systemPrompt },
3583
+ { role: "user", content: userPrompt }
3584
+ ];
3585
+ let aiResponse = null;
3586
+ let lastError = null;
3587
+ for (let attempt = 1; attempt <= AI_MAX_RETRIES2; attempt++) {
3588
+ try {
3589
+ aiResponse = await callAI({
3590
+ provider,
3591
+ model,
3592
+ maxTokens,
3593
+ apiKey,
3594
+ signal: context.abortSignal,
3595
+ messages: aiMessages
3596
+ });
3597
+ if (aiResponse.truncated) {
3598
+ throw new Error("AI output was truncated (hit token limit).");
3599
+ }
3600
+ break;
3601
+ } catch (err) {
3602
+ lastError = err instanceof Error ? err : new Error(String(err));
3603
+ console.error(
3604
+ `[prompt-handler] ${model} failed (attempt ${attempt}/${AI_MAX_RETRIES2}): ${lastError.message}`
3605
+ );
3606
+ }
3607
+ if (attempt < AI_MAX_RETRIES2) {
3608
+ const delay = RETRY_DELAY_MS2 * attempt;
3609
+ console.log(`[prompt-handler] retrying in ${delay}ms...`);
3610
+ await new Promise((r) => setTimeout(r, delay));
3611
+ }
3612
+ }
3613
+ if (!aiResponse) {
3614
+ throw new Error(
3615
+ `AI generation failed after ${AI_MAX_RETRIES2} attempts. Please try again later. Last error: ${lastError?.message ?? "unknown"}`
3616
+ );
3617
+ }
3618
+ return {
3619
+ type: "inline",
3620
+ content: aiResponse.content,
3621
+ mimeType: "text/markdown",
3622
+ usage: aiResponse.usage ? { provider, inputTokens: aiResponse.usage.inputTokens, outputTokens: aiResponse.usage.outputTokens } : void 0
3623
+ };
3624
+ }
3625
+ parseRequirements(requirements) {
3626
+ if (!isRecord2(requirements)) {
3627
+ throw new Error("Missing requirements object");
3628
+ }
3629
+ const prompt = requirements.prompt;
3630
+ if (!isNonEmptyString2(prompt)) {
3631
+ throw new Error("requirements.prompt must be a non-empty string");
3632
+ }
3633
+ const context = requirements.context;
3634
+ if (context !== void 0 && typeof context !== "string") {
3635
+ throw new Error("requirements.context must be a string when provided");
3636
+ }
3637
+ const normalizedContext = typeof context === "string" ? context.trim() : void 0;
3638
+ return {
3639
+ prompt: prompt.trim(),
3640
+ context: normalizedContext && normalizedContext.length > 0 ? normalizedContext : void 0
3641
+ };
3642
+ }
3643
+ };
3644
+
3645
+ // src/types.ts
3646
+ var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
3647
+ JobStatus2[JobStatus2["Created"] = 0] = "Created";
3648
+ JobStatus2[JobStatus2["Accepted"] = 1] = "Accepted";
3649
+ JobStatus2[JobStatus2["InProgress"] = 2] = "InProgress";
3650
+ JobStatus2[JobStatus2["Delivered"] = 3] = "Delivered";
3651
+ JobStatus2[JobStatus2["Evaluated"] = 4] = "Evaluated";
3652
+ JobStatus2[JobStatus2["Completed"] = 5] = "Completed";
3653
+ JobStatus2[JobStatus2["Disputed"] = 6] = "Disputed";
3654
+ JobStatus2[JobStatus2["Cancelled"] = 7] = "Cancelled";
3655
+ return JobStatus2;
3656
+ })(JobStatus || {});
3657
+ var ServiceType = /* @__PURE__ */ ((ServiceType2) => {
3658
+ ServiceType2[ServiceType2["TextGeneration"] = 0] = "TextGeneration";
3659
+ ServiceType2[ServiceType2["ImageGeneration"] = 1] = "ImageGeneration";
3660
+ ServiceType2[ServiceType2["DataAnalysis"] = 2] = "DataAnalysis";
3661
+ ServiceType2[ServiceType2["CodeGeneration"] = 3] = "CodeGeneration";
3662
+ ServiceType2[ServiceType2["Translation"] = 4] = "Translation";
3663
+ ServiceType2[ServiceType2["Custom"] = 5] = "Custom";
3664
+ return ServiceType2;
3665
+ })(ServiceType || {});
3666
+
3667
+ // src/handler/schema.ts
3668
+ var DEFAULT_SCHEMAS = {
3669
+ [0 /* TextGeneration */]: {
3670
+ version: 1,
3671
+ serviceRequirements: {
3672
+ type: "object",
3673
+ properties: {
3674
+ prompt: { type: "string", description: "Text prompt to generate from" },
3675
+ maxTokens: { type: "number", description: "Maximum output token count" }
3676
+ },
3677
+ required: ["prompt"]
3678
+ },
3679
+ deliverableRequirements: {
3680
+ type: "object",
3681
+ properties: {
3682
+ text: { type: "string", description: "Generated text output" },
3683
+ tokenCount: { type: "number", description: "Tokens used to produce output" }
3684
+ },
3685
+ required: ["text"]
3686
+ }
3687
+ },
3688
+ [1 /* ImageGeneration */]: {
3689
+ version: 1,
3690
+ serviceRequirements: {
3691
+ type: "object",
3692
+ properties: {
3693
+ prompt: { type: "string", description: "Image prompt to generate from" },
3694
+ size: { type: "string", description: "Output size (for example: 1024x1024)" },
3695
+ style: { type: "string", description: "Desired visual style" }
3696
+ },
3697
+ required: ["prompt"]
3698
+ },
3699
+ deliverableRequirements: {
3700
+ type: "object",
3701
+ properties: {
3702
+ imageUrl: { type: "string", description: "URL of the generated image" },
3703
+ mimeType: { type: "string", description: "Image MIME type" }
3704
+ },
3705
+ required: ["imageUrl"]
3706
+ }
3707
+ },
3708
+ [2 /* DataAnalysis */]: {
3709
+ version: 1,
3710
+ serviceRequirements: {
3711
+ type: "object",
3712
+ properties: {
3713
+ data: { type: "string", description: "Input data for analysis" },
3714
+ analysisRequest: { type: "string", description: "Question or analysis task" }
3715
+ },
3716
+ required: ["data", "analysisRequest"]
3717
+ },
3718
+ deliverableRequirements: {
3719
+ type: "object",
3720
+ properties: {
3721
+ summary: { type: "string", description: "Analysis summary" },
3722
+ findings: {
3723
+ type: "array",
3724
+ description: "Structured key findings",
3725
+ items: { type: "string" }
3726
+ }
3727
+ },
3728
+ required: ["summary"]
3729
+ }
3730
+ },
3731
+ [3 /* CodeGeneration */]: {
3732
+ version: 1,
3733
+ serviceRequirements: {
3734
+ type: "object",
3735
+ properties: {
3736
+ prompt: { type: "string", description: "Code generation request" },
3737
+ language: { type: "string", description: "Target programming language" }
3738
+ },
3739
+ required: ["prompt"]
3740
+ },
3741
+ deliverableRequirements: {
3742
+ type: "object",
3743
+ properties: {
3744
+ code: { type: "string", description: "Generated source code" },
3745
+ language: { type: "string", description: "Detected or requested language" }
3746
+ },
3747
+ required: ["code"]
3748
+ }
3749
+ },
3750
+ [4 /* Translation */]: {
3751
+ version: 1,
3752
+ serviceRequirements: {
3753
+ type: "object",
3754
+ properties: {
3755
+ text: { type: "string", description: "Text to translate" },
3756
+ targetLanguage: { type: "string", description: "Target language code or name" },
3757
+ sourceLanguage: { type: "string", description: "Optional source language code or name" }
3758
+ },
3759
+ required: ["text", "targetLanguage"]
3760
+ },
3761
+ deliverableRequirements: {
3762
+ type: "object",
3763
+ properties: {
3764
+ translatedText: { type: "string", description: "Translated text output" },
3765
+ sourceLanguage: { type: "string", description: "Detected or provided source language" }
3766
+ },
3767
+ required: ["translatedText"]
3768
+ }
3769
+ }
3770
+ };
3771
+ function isObjectRecord(value) {
3772
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3773
+ }
3774
+ function isTypeMatch(value, type) {
3775
+ switch (type) {
3776
+ case "string":
3777
+ return typeof value === "string";
3778
+ case "number":
3779
+ return typeof value === "number" && Number.isFinite(value);
3780
+ case "boolean":
3781
+ return typeof value === "boolean";
3782
+ case "object":
3783
+ return isObjectRecord(value);
3784
+ case "array":
3785
+ return Array.isArray(value);
3786
+ default:
3787
+ return false;
3788
+ }
3789
+ }
3790
+ function validateAgainstSchema(data, schema) {
3791
+ if (!data || !isObjectRecord(data)) {
3792
+ return { valid: false, reason: "Requirements must be a JSON object" };
3793
+ }
3794
+ for (const requiredField of schema.required ?? []) {
3795
+ if (!(requiredField in data)) {
3796
+ return { valid: false, reason: `Missing required field: ${requiredField}` };
3797
+ }
3798
+ }
3799
+ for (const [field, fieldSchema] of Object.entries(schema.properties)) {
3800
+ const value = data[field];
3801
+ if (value === void 0) continue;
3802
+ if (!isTypeMatch(value, fieldSchema.type)) {
3803
+ return {
3804
+ valid: false,
3805
+ reason: `Field "${field}" must be of type ${fieldSchema.type}`
3806
+ };
3807
+ }
3808
+ if (fieldSchema.enum && !fieldSchema.enum.some((enumValue) => Object.is(enumValue, value))) {
3809
+ return {
3810
+ valid: false,
3811
+ reason: `Field "${field}" must be one of: ${fieldSchema.enum.map((v) => JSON.stringify(v)).join(", ")}`
3812
+ };
3813
+ }
3814
+ if (fieldSchema.type === "array" && fieldSchema.items && Array.isArray(value)) {
3815
+ for (let i = 0; i < value.length; i += 1) {
3816
+ if (!isTypeMatch(value[i], fieldSchema.items.type)) {
3817
+ return {
3818
+ valid: false,
3819
+ reason: `Field "${field}[${i}]" must be of type ${fieldSchema.items.type}`
3820
+ };
3821
+ }
3822
+ }
3823
+ }
3824
+ }
3825
+ return { valid: true };
3826
+ }
3827
+
3354
3828
  // src/utils.ts
3355
3829
  var USDM_DECIMALS = 18;
3356
3830
  var USDM_SCALE = 10n ** BigInt(USDM_DECIMALS);
@@ -3387,28 +3861,6 @@ function formatUsdm(amount) {
3387
3861
  return `${whole}.${trimmedFraction.padEnd(2, "0")}`;
3388
3862
  }
3389
3863
 
3390
- // src/types.ts
3391
- var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
3392
- JobStatus2[JobStatus2["Created"] = 0] = "Created";
3393
- JobStatus2[JobStatus2["Accepted"] = 1] = "Accepted";
3394
- JobStatus2[JobStatus2["InProgress"] = 2] = "InProgress";
3395
- JobStatus2[JobStatus2["Delivered"] = 3] = "Delivered";
3396
- JobStatus2[JobStatus2["Evaluated"] = 4] = "Evaluated";
3397
- JobStatus2[JobStatus2["Completed"] = 5] = "Completed";
3398
- JobStatus2[JobStatus2["Disputed"] = 6] = "Disputed";
3399
- JobStatus2[JobStatus2["Cancelled"] = 7] = "Cancelled";
3400
- return JobStatus2;
3401
- })(JobStatus || {});
3402
- var ServiceType = /* @__PURE__ */ ((ServiceType2) => {
3403
- ServiceType2[ServiceType2["TextGeneration"] = 0] = "TextGeneration";
3404
- ServiceType2[ServiceType2["ImageGeneration"] = 1] = "ImageGeneration";
3405
- ServiceType2[ServiceType2["DataAnalysis"] = 2] = "DataAnalysis";
3406
- ServiceType2[ServiceType2["CodeGeneration"] = 3] = "CodeGeneration";
3407
- ServiceType2[ServiceType2["Translation"] = 4] = "Translation";
3408
- ServiceType2[ServiceType2["Custom"] = 5] = "Custom";
3409
- return ServiceType2;
3410
- })(ServiceType || {});
3411
-
3412
3864
  // src/indexer/client.ts
3413
3865
  var IndexerClientError = class extends Error {
3414
3866
  status;
@@ -3422,7 +3874,7 @@ var IndexerClientError = class extends Error {
3422
3874
  this.body = options.body;
3423
3875
  }
3424
3876
  };
3425
- function isRecord2(value) {
3877
+ function isRecord3(value) {
3426
3878
  return typeof value === "object" && value !== null;
3427
3879
  }
3428
3880
  function toIndexerAgent(raw) {
@@ -3446,6 +3898,7 @@ function toIndexerOffering(raw) {
3446
3898
  priceUsdm: raw.price_usdm,
3447
3899
  slaMinutes: raw.sla_minutes,
3448
3900
  description: raw.description,
3901
+ requirementsSchemaUri: raw.requirements_schema_uri ?? void 0,
3449
3902
  active: raw.active === 1,
3450
3903
  blockNumber: raw.block_number,
3451
3904
  txHash: raw.tx_hash
@@ -3610,7 +4063,7 @@ var IndexerClient = class {
3610
4063
  });
3611
4064
  }
3612
4065
  if (!response.ok) {
3613
- const apiError = isRecord2(payload) ? payload : void 0;
4066
+ const apiError = isRecord3(payload) ? payload : void 0;
3614
4067
  const message = response.status === 404 && notFoundMessage ? notFoundMessage : apiError?.error ?? apiError?.message ?? `Indexer request failed (${response.status})`;
3615
4068
  throw new IndexerClientError(message, {
3616
4069
  url,
@@ -3701,7 +4154,6 @@ var ProviderRuntime = class {
3701
4154
  this.processedJobs.add(deliverKey);
3702
4155
  await deployDeliverable(
3703
4156
  this.client,
3704
- this.agentId,
3705
4157
  BigInt(job.jobId),
3706
4158
  { ...params, jobId: BigInt(job.jobId) },
3707
4159
  this.indexer["baseUrl"]
@@ -3836,7 +4288,6 @@ var BuyerRuntime = class {
3836
4288
  this.processedJobs.add(deliveredKey);
3837
4289
  try {
3838
4290
  const deliverable = await readDeliverable(
3839
- this.client,
3840
4291
  BigInt(job.jobId),
3841
4292
  this.indexer["baseUrl"]
3842
4293
  );
@@ -3878,6 +4329,7 @@ var HandlerProviderRuntime = class {
3878
4329
  running = false;
3879
4330
  processedJobs = /* @__PURE__ */ new Set();
3880
4331
  failedJobs = /* @__PURE__ */ new Map();
4332
+ schemaCache = /* @__PURE__ */ new Map();
3881
4333
  maxRetries = 3;
3882
4334
  onError;
3883
4335
  constructor(client, agentId, options) {
@@ -3922,8 +4374,8 @@ var HandlerProviderRuntime = class {
3922
4374
  for (const job of jobs) {
3923
4375
  const newKey = `new:${job.jobId}`;
3924
4376
  if (!this.canProcess(newKey)) continue;
3925
- const matchesOffering = offerings.some((o) => o.offeringId === job.offeringId);
3926
- if (!matchesOffering) continue;
4377
+ const offering = offerings.find((o) => o.offeringId === job.offeringId);
4378
+ if (!offering) continue;
3927
4379
  const handler = this.handlers.get(job.offeringId);
3928
4380
  if (!handler) continue;
3929
4381
  try {
@@ -3946,6 +4398,10 @@ var HandlerProviderRuntime = class {
3946
4398
  if (reqData) {
3947
4399
  context.requirements = reqData.requirements;
3948
4400
  }
4401
+ const schemaValidation = await this.validateSchemaRequirements(context, handler, offering);
4402
+ if (!schemaValidation.valid) {
4403
+ throw new Error(`Schema validation failed for job ${job.jobId}: ${schemaValidation.reason}`);
4404
+ }
3949
4405
  if (handler.validateRequirements) {
3950
4406
  const validation = await handler.validateRequirements(context);
3951
4407
  if (!validation.valid) {
@@ -3966,6 +4422,10 @@ var HandlerProviderRuntime = class {
3966
4422
  }
3967
4423
  }
3968
4424
  async checkInProgressJobs() {
4425
+ const offerings = await this.indexer.getOfferings({ agentId: Number(this.agentId) });
4426
+ const offeringsById = new Map(
4427
+ offerings.map((offering) => [offering.offeringId, offering])
4428
+ );
3969
4429
  const inProgressJobs = await this.indexer.getJobs({
3970
4430
  status: 2,
3971
4431
  agentId: Number(this.agentId)
@@ -3975,6 +4435,7 @@ var HandlerProviderRuntime = class {
3975
4435
  if (!this.canProcess(deliverKey)) continue;
3976
4436
  const handler = this.handlers.get(job.offeringId);
3977
4437
  if (!handler) continue;
4438
+ const offering = offeringsById.get(job.offeringId);
3978
4439
  try {
3979
4440
  if (job.slaMinutes === null) {
3980
4441
  throw new Error(`Job ${job.jobId} is missing slaMinutes`);
@@ -3995,6 +4456,14 @@ var HandlerProviderRuntime = class {
3995
4456
  if (reqData) {
3996
4457
  context.requirements = reqData.requirements;
3997
4458
  }
4459
+ const schemaValidation = await this.validateSchemaRequirements(context, handler, offering);
4460
+ if (!schemaValidation.valid) {
4461
+ this.markFailed(
4462
+ deliverKey,
4463
+ new Error(`Schema validation failed for job ${job.jobId}: ${schemaValidation.reason}`)
4464
+ );
4465
+ continue;
4466
+ }
3998
4467
  if (handler.validateRequirements) {
3999
4468
  const validation = await handler.validateRequirements(context);
4000
4469
  if (!validation.valid) {
@@ -4040,7 +4509,6 @@ var HandlerProviderRuntime = class {
4040
4509
  };
4041
4510
  await deployDeliverable(
4042
4511
  this.client,
4043
- this.agentId,
4044
4512
  BigInt(job.jobId),
4045
4513
  deliverableParams,
4046
4514
  this.indexerUrl
@@ -4088,6 +4556,85 @@ var HandlerProviderRuntime = class {
4088
4556
  this.onError?.(new Error(`Giving up on ${key} after ${retries} failed attempts`));
4089
4557
  }
4090
4558
  }
4559
+ async validateSchemaRequirements(context, handler, offering) {
4560
+ if (offering?.requirementsSchemaUri) {
4561
+ try {
4562
+ const offeringSchema = await this.resolveOfferingSchemaFromUri(offering.requirementsSchemaUri);
4563
+ if (!offeringSchema) {
4564
+ return {
4565
+ valid: false,
4566
+ reason: `Unsupported requirementsSchemaUri format: ${offering.requirementsSchemaUri}`
4567
+ };
4568
+ }
4569
+ return validateAgainstSchema(context.requirements, offeringSchema.serviceRequirements);
4570
+ } catch (error) {
4571
+ return {
4572
+ valid: false,
4573
+ reason: error instanceof Error ? error.message : String(error)
4574
+ };
4575
+ }
4576
+ }
4577
+ const defaultSchema = offering ? DEFAULT_SCHEMAS[offering.serviceType] : void 0;
4578
+ const schema = handler.schema ?? defaultSchema;
4579
+ if (!schema) return { valid: true };
4580
+ return validateAgainstSchema(context.requirements, schema.serviceRequirements);
4581
+ }
4582
+ async resolveOfferingSchemaFromUri(schemaUri) {
4583
+ const cached = this.schemaCache.get(schemaUri);
4584
+ if (cached !== void 0) {
4585
+ return cached;
4586
+ }
4587
+ let schemaPayload;
4588
+ if (schemaUri.startsWith("data:")) {
4589
+ schemaPayload = this.parseDataUriJson(schemaUri);
4590
+ } else if (schemaUri.startsWith("http://") || schemaUri.startsWith("https://")) {
4591
+ const controller = new AbortController();
4592
+ const timeoutId = setTimeout(() => controller.abort(), 3e4);
4593
+ try {
4594
+ const response = await fetch(schemaUri, { signal: controller.signal });
4595
+ if (!response.ok) {
4596
+ throw new Error(`Failed to fetch requirements schema URI (${response.status} ${response.statusText})`);
4597
+ }
4598
+ const buf = await response.arrayBuffer();
4599
+ if (buf.byteLength > 1048576) {
4600
+ throw new Error(`Schema too large (${buf.byteLength} bytes). Limit is 1MB`);
4601
+ }
4602
+ schemaPayload = JSON.parse(new TextDecoder().decode(buf));
4603
+ } finally {
4604
+ clearTimeout(timeoutId);
4605
+ }
4606
+ } else if (schemaUri.trim().startsWith("{")) {
4607
+ schemaPayload = JSON.parse(schemaUri);
4608
+ } else {
4609
+ this.schemaCache.set(schemaUri, null);
4610
+ return null;
4611
+ }
4612
+ if (!this.isOfferingSchema(schemaPayload)) {
4613
+ throw new Error("requirementsSchemaUri did not resolve to a valid OfferingSchema document");
4614
+ }
4615
+ this.schemaCache.set(schemaUri, schemaPayload);
4616
+ return schemaPayload;
4617
+ }
4618
+ parseDataUriJson(dataUri) {
4619
+ const commaIndex = dataUri.indexOf(",");
4620
+ if (commaIndex < 0) {
4621
+ throw new Error("Invalid data URI schema format");
4622
+ }
4623
+ const metadata = dataUri.slice(5, commaIndex);
4624
+ const payload = dataUri.slice(commaIndex + 1);
4625
+ const decoded = metadata.includes(";base64") ? new TextDecoder().decode(Uint8Array.from(atob(payload), (char) => char.charCodeAt(0))) : decodeURIComponent(payload);
4626
+ return JSON.parse(decoded);
4627
+ }
4628
+ isOfferingSchema(value) {
4629
+ if (typeof value !== "object" || value === null) return false;
4630
+ const candidate = value;
4631
+ return typeof candidate.version === "number" && this.isJsonSchema(candidate.serviceRequirements) && this.isJsonSchema(candidate.deliverableRequirements);
4632
+ }
4633
+ isJsonSchema(value) {
4634
+ if (typeof value !== "object" || value === null) return false;
4635
+ const candidate = value;
4636
+ return candidate.type === "object" && typeof candidate.properties === "object" && candidate.properties !== null;
4637
+ }
4091
4638
  getRemainingSlaMs(createdAt, acceptedAt, slaMinutes) {
4092
4639
  const start = acceptedAt ?? createdAt;
4093
4640
  if (start === null) return null;
@@ -5470,6 +6017,7 @@ export {
5470
6017
  BPS_DENOMINATOR,
5471
6018
  BuyerRuntime,
5472
6019
  DEFAULT_INDEXER_URLS,
6020
+ DEFAULT_SCHEMAS,
5473
6021
  EVALUATION_TIMEOUT,
5474
6022
  FEE_BPS,
5475
6023
  HandlerProviderRuntime,
@@ -5480,6 +6028,7 @@ export {
5480
6028
  MEMO_TYPES,
5481
6029
  PLATFORM_BUYER_AGENT_ID,
5482
6030
  PULSE_DOMAIN,
6031
+ PromptHandler,
5483
6032
  ProviderRuntime,
5484
6033
  RISK_POOL_BPS,
5485
6034
  ServiceType,
@@ -5543,6 +6092,8 @@ export {
5543
6092
  submitDeliverable,
5544
6093
  testnetERC8004,
5545
6094
  updateOffering,
6095
+ updateOfferingSchema,
6096
+ validateAgainstSchema,
5546
6097
  verifyContentHash
5547
6098
  };
5548
6099
  //# sourceMappingURL=index.js.map