@pulseai/sdk 0.1.3 → 0.1.5
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.d.ts +115 -33
- package/dist/index.js +316 -57
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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: "
|
|
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: "
|
|
51
|
+
buyerRelay: "0x843B5B4AD44C174BAB8bBe11eb001aD7fE70647A"
|
|
46
52
|
};
|
|
47
|
-
var PLATFORM_BUYER_AGENT_ID =
|
|
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
|
|
2452
|
+
const allowance = await client.publicClient.readContract({
|
|
2350
2453
|
address: client.addresses.usdm,
|
|
2351
2454
|
abi: erc20Abi,
|
|
2352
|
-
functionName: "
|
|
2353
|
-
args: [client.addresses.jobEngine
|
|
2455
|
+
functionName: "allowance",
|
|
2456
|
+
args: [account.address, client.addresses.jobEngine]
|
|
2354
2457
|
});
|
|
2355
|
-
|
|
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
|
|
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
|
|
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: "
|
|
2797
|
+
storageType: "deliverable"
|
|
2712
2798
|
})
|
|
2713
2799
|
});
|
|
2714
2800
|
} catch {
|
|
2715
2801
|
}
|
|
2716
2802
|
}
|
|
2717
|
-
return {
|
|
2803
|
+
return { hash, txHash };
|
|
2718
2804
|
}
|
|
2719
|
-
async function readDeliverable(
|
|
2720
|
-
const res = await fetch(`${indexerUrl}/
|
|
2721
|
-
if (!res.ok) throw new Error(`Failed to fetch
|
|
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
|
|
2724
|
-
|
|
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
|
-
|
|
2969
|
+
max_completion_tokens: params.maxTokens
|
|
2885
2970
|
}),
|
|
2886
2971
|
signal: params.signal
|
|
2887
2972
|
});
|
|
@@ -3037,6 +3122,16 @@ function parseAndValidateUrl(urlString) {
|
|
|
3037
3122
|
}
|
|
3038
3123
|
return url;
|
|
3039
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
|
+
}
|
|
3040
3135
|
function ensureAllowedUrl(url, allowedDomains) {
|
|
3041
3136
|
if (!allowedDomains || allowedDomains.length === 0) return;
|
|
3042
3137
|
if (!isAllowedDomain(url.hostname, allowedDomains)) {
|
|
@@ -3297,7 +3392,7 @@ var SiteModifierHandler = class {
|
|
|
3297
3392
|
if (!isNonEmptyString(siteUrl)) {
|
|
3298
3393
|
throw new Error("requirements.siteUrl must be a non-empty string");
|
|
3299
3394
|
}
|
|
3300
|
-
const parsedUrl = parseAndValidateUrl(siteUrl);
|
|
3395
|
+
const parsedUrl = normalizeWarrenUrl(parseAndValidateUrl(siteUrl));
|
|
3301
3396
|
ensureAllowedUrl(parsedUrl, this.config.allowedDomains);
|
|
3302
3397
|
const modificationRequest = requirements.modificationRequest;
|
|
3303
3398
|
if (!isNonEmptyString(modificationRequest)) {
|
|
@@ -3316,7 +3411,7 @@ var SiteModifierHandler = class {
|
|
|
3316
3411
|
throw new Error("requirements.model must be a non-empty string");
|
|
3317
3412
|
}
|
|
3318
3413
|
return {
|
|
3319
|
-
siteUrl:
|
|
3414
|
+
siteUrl: parsedUrl.toString(),
|
|
3320
3415
|
modificationRequest: modificationRequest.trim(),
|
|
3321
3416
|
provider,
|
|
3322
3417
|
model: typeof model === "string" ? model.trim() : void 0
|
|
@@ -3402,6 +3497,151 @@ var SiteModifierHandler = class {
|
|
|
3402
3497
|
}
|
|
3403
3498
|
};
|
|
3404
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
|
+
|
|
3405
3645
|
// src/types.ts
|
|
3406
3646
|
var JobStatus = /* @__PURE__ */ ((JobStatus2) => {
|
|
3407
3647
|
JobStatus2[JobStatus2["Created"] = 0] = "Created";
|
|
@@ -3634,7 +3874,7 @@ var IndexerClientError = class extends Error {
|
|
|
3634
3874
|
this.body = options.body;
|
|
3635
3875
|
}
|
|
3636
3876
|
};
|
|
3637
|
-
function
|
|
3877
|
+
function isRecord3(value) {
|
|
3638
3878
|
return typeof value === "object" && value !== null;
|
|
3639
3879
|
}
|
|
3640
3880
|
function toIndexerAgent(raw) {
|
|
@@ -3775,6 +4015,16 @@ var IndexerClient = class {
|
|
|
3775
4015
|
})
|
|
3776
4016
|
});
|
|
3777
4017
|
}
|
|
4018
|
+
async updateOfferingMetadata(offeringId, params) {
|
|
4019
|
+
await this.requestJson(
|
|
4020
|
+
`/offerings/${offeringId}/metadata`,
|
|
4021
|
+
{
|
|
4022
|
+
method: "PUT",
|
|
4023
|
+
headers: { "Content-Type": "application/json" },
|
|
4024
|
+
body: JSON.stringify(params)
|
|
4025
|
+
}
|
|
4026
|
+
);
|
|
4027
|
+
}
|
|
3778
4028
|
async getDeliverable(jobId) {
|
|
3779
4029
|
try {
|
|
3780
4030
|
const response = await this.request(`/deliverables/${jobId}`);
|
|
@@ -3823,7 +4073,7 @@ var IndexerClient = class {
|
|
|
3823
4073
|
});
|
|
3824
4074
|
}
|
|
3825
4075
|
if (!response.ok) {
|
|
3826
|
-
const apiError =
|
|
4076
|
+
const apiError = isRecord3(payload) ? payload : void 0;
|
|
3827
4077
|
const message = response.status === 404 && notFoundMessage ? notFoundMessage : apiError?.error ?? apiError?.message ?? `Indexer request failed (${response.status})`;
|
|
3828
4078
|
throw new IndexerClientError(message, {
|
|
3829
4079
|
url,
|
|
@@ -3914,7 +4164,6 @@ var ProviderRuntime = class {
|
|
|
3914
4164
|
this.processedJobs.add(deliverKey);
|
|
3915
4165
|
await deployDeliverable(
|
|
3916
4166
|
this.client,
|
|
3917
|
-
this.agentId,
|
|
3918
4167
|
BigInt(job.jobId),
|
|
3919
4168
|
{ ...params, jobId: BigInt(job.jobId) },
|
|
3920
4169
|
this.indexer["baseUrl"]
|
|
@@ -4049,7 +4298,6 @@ var BuyerRuntime = class {
|
|
|
4049
4298
|
this.processedJobs.add(deliveredKey);
|
|
4050
4299
|
try {
|
|
4051
4300
|
const deliverable = await readDeliverable(
|
|
4052
|
-
this.client,
|
|
4053
4301
|
BigInt(job.jobId),
|
|
4054
4302
|
this.indexer["baseUrl"]
|
|
4055
4303
|
);
|
|
@@ -4271,7 +4519,6 @@ var HandlerProviderRuntime = class {
|
|
|
4271
4519
|
};
|
|
4272
4520
|
await deployDeliverable(
|
|
4273
4521
|
this.client,
|
|
4274
|
-
this.agentId,
|
|
4275
4522
|
BigInt(job.jobId),
|
|
4276
4523
|
deliverableParams,
|
|
4277
4524
|
this.indexerUrl
|
|
@@ -4351,11 +4598,21 @@ var HandlerProviderRuntime = class {
|
|
|
4351
4598
|
if (schemaUri.startsWith("data:")) {
|
|
4352
4599
|
schemaPayload = this.parseDataUriJson(schemaUri);
|
|
4353
4600
|
} else if (schemaUri.startsWith("http://") || schemaUri.startsWith("https://")) {
|
|
4354
|
-
const
|
|
4355
|
-
|
|
4356
|
-
|
|
4601
|
+
const controller = new AbortController();
|
|
4602
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
4603
|
+
try {
|
|
4604
|
+
const response = await fetch(schemaUri, { signal: controller.signal });
|
|
4605
|
+
if (!response.ok) {
|
|
4606
|
+
throw new Error(`Failed to fetch requirements schema URI (${response.status} ${response.statusText})`);
|
|
4607
|
+
}
|
|
4608
|
+
const buf = await response.arrayBuffer();
|
|
4609
|
+
if (buf.byteLength > 1048576) {
|
|
4610
|
+
throw new Error(`Schema too large (${buf.byteLength} bytes). Limit is 1MB`);
|
|
4611
|
+
}
|
|
4612
|
+
schemaPayload = JSON.parse(new TextDecoder().decode(buf));
|
|
4613
|
+
} finally {
|
|
4614
|
+
clearTimeout(timeoutId);
|
|
4357
4615
|
}
|
|
4358
|
-
schemaPayload = await response.json();
|
|
4359
4616
|
} else if (schemaUri.trim().startsWith("{")) {
|
|
4360
4617
|
schemaPayload = JSON.parse(schemaUri);
|
|
4361
4618
|
} else {
|
|
@@ -5781,6 +6038,7 @@ export {
|
|
|
5781
6038
|
MEMO_TYPES,
|
|
5782
6039
|
PLATFORM_BUYER_AGENT_ID,
|
|
5783
6040
|
PULSE_DOMAIN,
|
|
6041
|
+
PromptHandler,
|
|
5784
6042
|
ProviderRuntime,
|
|
5785
6043
|
RISK_POOL_BPS,
|
|
5786
6044
|
ServiceType,
|
|
@@ -5844,6 +6102,7 @@ export {
|
|
|
5844
6102
|
submitDeliverable,
|
|
5845
6103
|
testnetERC8004,
|
|
5846
6104
|
updateOffering,
|
|
6105
|
+
updateOfferingSchema,
|
|
5847
6106
|
validateAgainstSchema,
|
|
5848
6107
|
verifyContentHash
|
|
5849
6108
|
};
|