@elisym/sdk 0.25.1 → 0.25.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/agent-store.cjs.map +1 -1
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +90 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +145 -16
- package/dist/index.d.ts +145 -16
- package/dist/index.js +89 -14
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +83 -22
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +66 -0
- package/dist/node.d.ts +66 -0
- package/dist/node.js +83 -22
- package/dist/node.js.map +1 -1
- package/dist/skills.cjs +57 -1
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +23 -3
- package/dist/skills.d.ts +23 -3
- package/dist/skills.js +58 -2
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -73,6 +73,11 @@ var DEFAULTS = {
|
|
|
73
73
|
// default, not a protocol constant - the transfer is resumable and its own
|
|
74
74
|
// budget, decoupled from the result-wait window.
|
|
75
75
|
IROH_FETCH_TIMEOUT_MS: 3e5,
|
|
76
|
+
// Ceiling for a single iroh SEED (addFromPath/addBytes/share). Seeding is local
|
|
77
|
+
// (hash + store-copy + ticket mint), so this is a generous backstop: it bounds
|
|
78
|
+
// the JS await so a wedged native call surfaces as a thrown error (and triggers a
|
|
79
|
+
// node reset) instead of an indefinite hang that stalls file delivery.
|
|
80
|
+
IROH_SEED_TIMEOUT_MS: 12e4,
|
|
76
81
|
// Ceiling for a single Blossom blob upload (PUT /upload). Large blobs (up to
|
|
77
82
|
// LIMITS.MAX_FILE_SIZE) need far more than the 30s used for small media images.
|
|
78
83
|
BLOSSOM_UPLOAD_TIMEOUT_MS: 3e5,
|
|
@@ -1194,6 +1199,17 @@ var BlossomService = class {
|
|
|
1194
1199
|
this.serverUrl = serverUrl;
|
|
1195
1200
|
this.fallback = fallback;
|
|
1196
1201
|
}
|
|
1202
|
+
/**
|
|
1203
|
+
* The content-addressed GET URL for a blob, derivable from its sha256 BEFORE
|
|
1204
|
+
* upload (BUD-01: `<serverUrl>/<sha256>`, no extension for our octet-stream
|
|
1205
|
+
* ciphertext uploads - same form `delete` addresses by). Lets a caller build a
|
|
1206
|
+
* complete attachment descriptor and defer the actual byte upload (the descriptor
|
|
1207
|
+
* is submitted first, the bytes PUT later). `upload()` re-verifies the server
|
|
1208
|
+
* returns this exact url.
|
|
1209
|
+
*/
|
|
1210
|
+
contentUrl(sha256) {
|
|
1211
|
+
return `${this.serverUrl}/${sha256}`;
|
|
1212
|
+
}
|
|
1197
1213
|
/**
|
|
1198
1214
|
* Upload a file to the Blossom server, returning its descriptor. On any failure, falls
|
|
1199
1215
|
* back to the configured uploader (if any) and returns a normalized descriptor with
|
|
@@ -1432,6 +1448,9 @@ function parseCapabilityEvent(event, network) {
|
|
|
1432
1448
|
if (card.inputMime !== void 0 && (typeof card.inputMime !== "string" || card.inputMime.length > 255) || card.outputMime !== void 0 && (typeof card.outputMime !== "string" || card.outputMime.length > 255)) {
|
|
1433
1449
|
return null;
|
|
1434
1450
|
}
|
|
1451
|
+
if (card.inputText !== void 0 && !["required", "optional", "none"].includes(card.inputText)) {
|
|
1452
|
+
card.inputText = void 0;
|
|
1453
|
+
}
|
|
1435
1454
|
if (card.payment?.job_price !== null && card.payment?.job_price !== void 0 && (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)) {
|
|
1436
1455
|
return null;
|
|
1437
1456
|
}
|
|
@@ -2062,7 +2081,11 @@ var FileAttachmentSchema = z.object({
|
|
|
2062
2081
|
var JobPayloadEnvelopeSchema = z.object({
|
|
2063
2082
|
v: z.literal(ENVELOPE_VERSION),
|
|
2064
2083
|
text: z.string().optional(),
|
|
2065
|
-
attachment
|
|
2084
|
+
// Legacy single attachment - kept (and mirrored from `attachments[0]`) so an old
|
|
2085
|
+
// decoder that doesn't know `attachments` still gets the first file.
|
|
2086
|
+
attachment: FileAttachmentSchema.optional(),
|
|
2087
|
+
// Multiple result/input files. Additive; old decoders strip this unknown key.
|
|
2088
|
+
attachments: z.array(FileAttachmentSchema).optional()
|
|
2066
2089
|
});
|
|
2067
2090
|
var ACCEPT_TRANSPORTS_TAG = "accept";
|
|
2068
2091
|
var KNOWN_TRANSPORT_KINDS = ["iroh", "blossom"];
|
|
@@ -2095,12 +2118,21 @@ function readAcceptedTransports(tags) {
|
|
|
2095
2118
|
}
|
|
2096
2119
|
return out.length > 0 ? out : void 0;
|
|
2097
2120
|
}
|
|
2121
|
+
function attachmentsOf(decoded) {
|
|
2122
|
+
if (decoded.attachments !== void 0 && decoded.attachments.length > 0) {
|
|
2123
|
+
return decoded.attachments;
|
|
2124
|
+
}
|
|
2125
|
+
return decoded.attachment !== void 0 ? [decoded.attachment] : [];
|
|
2126
|
+
}
|
|
2098
2127
|
function encodeJobPayload(payload) {
|
|
2099
2128
|
const envelope = { v: ENVELOPE_VERSION };
|
|
2100
2129
|
if (payload.text !== void 0) {
|
|
2101
2130
|
envelope.text = payload.text;
|
|
2102
2131
|
}
|
|
2103
|
-
if (payload.
|
|
2132
|
+
if (payload.attachments !== void 0 && payload.attachments.length > 0) {
|
|
2133
|
+
envelope.attachments = payload.attachments;
|
|
2134
|
+
envelope.attachment = payload.attachments[0];
|
|
2135
|
+
} else if (payload.attachment !== void 0) {
|
|
2104
2136
|
envelope.attachment = payload.attachment;
|
|
2105
2137
|
}
|
|
2106
2138
|
return JSON.stringify(envelope);
|
|
@@ -2128,7 +2160,11 @@ function decodeJobPayload(content) {
|
|
|
2128
2160
|
`Invalid elisym job payload (v=${JSON.stringify(version)}): ${result.error.message}`
|
|
2129
2161
|
);
|
|
2130
2162
|
}
|
|
2131
|
-
return {
|
|
2163
|
+
return {
|
|
2164
|
+
text: result.data.text,
|
|
2165
|
+
attachment: result.data.attachment,
|
|
2166
|
+
attachments: result.data.attachments
|
|
2167
|
+
};
|
|
2132
2168
|
}
|
|
2133
2169
|
|
|
2134
2170
|
// src/services/marketplace.ts
|
|
@@ -2293,7 +2329,7 @@ var MarketplaceService = class {
|
|
|
2293
2329
|
}
|
|
2294
2330
|
resultDelivered = true;
|
|
2295
2331
|
try {
|
|
2296
|
-
cb.onResult?.(decoded.text ?? "", ev.id, decoded.attachment);
|
|
2332
|
+
cb.onResult?.(decoded.text ?? "", ev.id, decoded.attachment, attachmentsOf(decoded));
|
|
2297
2333
|
} catch {
|
|
2298
2334
|
} finally {
|
|
2299
2335
|
done();
|
|
@@ -2457,8 +2493,8 @@ var MarketplaceService = class {
|
|
|
2457
2493
|
);
|
|
2458
2494
|
}
|
|
2459
2495
|
/** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */
|
|
2460
|
-
async submitJobResult(identity, requestEvent, content, amount,
|
|
2461
|
-
const hasAttachment =
|
|
2496
|
+
async submitJobResult(identity, requestEvent, content, amount, attachments) {
|
|
2497
|
+
const hasAttachment = attachments !== void 0 && attachments.length > 0;
|
|
2462
2498
|
if (!content && !hasAttachment) {
|
|
2463
2499
|
throw new Error("Job result content must not be empty.");
|
|
2464
2500
|
}
|
|
@@ -2472,7 +2508,7 @@ var MarketplaceService = class {
|
|
|
2472
2508
|
);
|
|
2473
2509
|
}
|
|
2474
2510
|
const shouldEncrypt = isEncrypted(requestEvent);
|
|
2475
|
-
const payload = hasAttachment ? encodeJobPayload({ text: content || void 0,
|
|
2511
|
+
const payload = hasAttachment ? encodeJobPayload({ text: content || void 0, attachments }) : content;
|
|
2476
2512
|
if (shouldEncrypt) {
|
|
2477
2513
|
const payloadBytes = utf8ByteLength(payload);
|
|
2478
2514
|
if (payloadBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {
|
|
@@ -2513,11 +2549,11 @@ var MarketplaceService = class {
|
|
|
2513
2549
|
* With maxAttempts=3: try, ~1s, try, ~2s, try, throw.
|
|
2514
2550
|
* Jitter: 0.5x-1.0x of calculated delay.
|
|
2515
2551
|
*/
|
|
2516
|
-
async submitJobResultWithRetry(identity, requestEvent, content, amount, maxAttempts = DEFAULTS.RESULT_RETRY_COUNT, baseDelayMs = DEFAULTS.RESULT_RETRY_BASE_MS,
|
|
2552
|
+
async submitJobResultWithRetry(identity, requestEvent, content, amount, maxAttempts = DEFAULTS.RESULT_RETRY_COUNT, baseDelayMs = DEFAULTS.RESULT_RETRY_BASE_MS, attachments) {
|
|
2517
2553
|
const attempts = Math.max(1, maxAttempts);
|
|
2518
2554
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
2519
2555
|
try {
|
|
2520
|
-
return await this.submitJobResult(identity, requestEvent, content, amount,
|
|
2556
|
+
return await this.submitJobResult(identity, requestEvent, content, amount, attachments);
|
|
2521
2557
|
} catch (e) {
|
|
2522
2558
|
if (attempt >= attempts - 1) {
|
|
2523
2559
|
throw e;
|
|
@@ -3694,6 +3730,10 @@ function createBlossomTransport(opts) {
|
|
|
3694
3730
|
}
|
|
3695
3731
|
|
|
3696
3732
|
// src/transport/file-jobs.ts
|
|
3733
|
+
async function sha256Hex(bytes) {
|
|
3734
|
+
const digest = await crypto.subtle.digest("SHA-256", bytes);
|
|
3735
|
+
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
3736
|
+
}
|
|
3697
3737
|
var EXECUTABLE_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
3698
3738
|
".exe",
|
|
3699
3739
|
".dll",
|
|
@@ -3719,21 +3759,56 @@ function looksExecutable(name, type) {
|
|
|
3719
3759
|
const ext = dot >= 0 ? name.slice(dot).toLowerCase() : "";
|
|
3720
3760
|
return EXECUTABLE_EXTENSIONS.has(ext) || EXECUTABLE_MIMES.has(type);
|
|
3721
3761
|
}
|
|
3722
|
-
async function
|
|
3762
|
+
async function prepareEncryptedFileInput(args) {
|
|
3723
3763
|
const { file, providerPubkey, identity, blossom } = args;
|
|
3724
3764
|
const name = file.name ?? "upload";
|
|
3725
3765
|
if (looksExecutable(name, file.type)) {
|
|
3726
3766
|
throw new Error("Refusing to upload an executable file.");
|
|
3727
3767
|
}
|
|
3728
|
-
const transport = createBlossomTransport({ blossom, identity });
|
|
3729
3768
|
const bytes = new Uint8Array(await file.arrayBuffer());
|
|
3730
|
-
|
|
3731
|
-
|
|
3769
|
+
if (bytes.byteLength > LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES) {
|
|
3770
|
+
throw new Error(
|
|
3771
|
+
`File too large for the encrypted-Blossom transport: ${bytes.byteLength} bytes (max ${LIMITS.MAX_BLOSSOM_ENCRYPTED_BYTES}).`
|
|
3772
|
+
);
|
|
3773
|
+
}
|
|
3774
|
+
const { ciphertext, wrappedKey, iv } = await encryptBytesForRecipient(
|
|
3775
|
+
bytes,
|
|
3776
|
+
identity.secretKey,
|
|
3777
|
+
providerPubkey
|
|
3778
|
+
);
|
|
3779
|
+
const sha256 = await sha256Hex(ciphertext);
|
|
3780
|
+
const member = {
|
|
3781
|
+
kind: "blossom",
|
|
3782
|
+
url: blossom.contentUrl(sha256),
|
|
3783
|
+
sha256,
|
|
3784
|
+
enc: { alg: "AES-256-GCM", iv, key: wrappedKey }
|
|
3785
|
+
};
|
|
3786
|
+
const attachment = {
|
|
3732
3787
|
name,
|
|
3733
3788
|
size: bytes.byteLength,
|
|
3734
3789
|
mime: file.type || "application/octet-stream",
|
|
3735
3790
|
transports: [member]
|
|
3736
3791
|
};
|
|
3792
|
+
const upload = async () => {
|
|
3793
|
+
const descriptor = await blossom.upload(
|
|
3794
|
+
identity,
|
|
3795
|
+
new Blob([ciphertext], { type: "application/octet-stream" })
|
|
3796
|
+
);
|
|
3797
|
+
if (descriptor.provider !== "blossom") {
|
|
3798
|
+
throw new Error("Blossom upload fell back to a non-content-addressed provider.");
|
|
3799
|
+
}
|
|
3800
|
+
if (descriptor.sha256 !== sha256 || descriptor.url !== member.url) {
|
|
3801
|
+
throw new Error(
|
|
3802
|
+
`Blossom upload descriptor mismatch (expected ${member.url} / ${sha256}, got ${descriptor.url} / ${descriptor.sha256}).`
|
|
3803
|
+
);
|
|
3804
|
+
}
|
|
3805
|
+
};
|
|
3806
|
+
return { attachment, upload };
|
|
3807
|
+
}
|
|
3808
|
+
async function buildEncryptedFileInput(args) {
|
|
3809
|
+
const prepared = await prepareEncryptedFileInput(args);
|
|
3810
|
+
await prepared.upload();
|
|
3811
|
+
return prepared.attachment;
|
|
3737
3812
|
}
|
|
3738
3813
|
async function fetchEncryptedFileOutput(args) {
|
|
3739
3814
|
const { attachment, providerPubkey, identity, blossom, maxBytes } = args;
|
|
@@ -4323,6 +4398,6 @@ function makeCensor() {
|
|
|
4323
4398
|
};
|
|
4324
4399
|
}
|
|
4325
4400
|
|
|
4326
|
-
export { ACCEPT_TRANSPORTS_TAG, BlossomService, BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ENVELOPE_VERSION, ElisymClient, ElisymIdentity, GlobalConfigSchema, INPUT_REDACT_PATHS, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, PaymentRequestSchema, PingService, PoliciesService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, buildAcceptTransportsTag, buildEncryptedFileInput, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createBlossomTransport, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, decodeJobPayload, decryptBytesFromSender, encodeJobPayload, encryptBytesForRecipient, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, fetchEncryptedFileOutput, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, readAcceptedTransports, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, utf8ByteLength, validateAgentName, validateExpiry, verifyJobPaymentQuick };
|
|
4401
|
+
export { ACCEPT_TRANSPORTS_TAG, BlossomService, BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, ENVELOPE_VERSION, ElisymClient, ElisymIdentity, GlobalConfigSchema, INPUT_REDACT_PATHS, JobWaitTimeoutError, KIND_APP_HANDLER, KIND_JOB_FEEDBACK, KIND_JOB_REQUEST, KIND_JOB_REQUEST_BASE, KIND_JOB_RESULT, KIND_JOB_RESULT_BASE, KIND_LONG_FORM_ARTICLE, KIND_PING, KIND_PONG, KNOWN_ASSETS, LAMPORTS_PER_SOL, LIMITS, MarketplaceService, MediaService, NATIVE_SOL, NostrPool, POLICY_D_TAG_PREFIX, POLICY_TYPE_REGEX, POLICY_T_TAG, PROTOCOL_PROGRAM_ID_DEVNET, PaymentRequestSchema, PingService, PoliciesService, RELAYS, SECRET_REDACT_PATHS, SessionSpendLimitEntrySchema, SolanaPaymentStrategy, USDC_SOLANA_DEVNET, aggregateNetworkStats, assertExpiry, assertLamports, assetByKey, assetKey, attachmentsOf, buildAcceptTransportsTag, buildEncryptedFileInput, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createBlossomTransport, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, decodeJobPayload, decryptBytesFromSender, encodeJobPayload, encryptBytesForRecipient, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, fetchEncryptedFileOutput, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, prepareEncryptedFileInput, readAcceptedTransports, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, utf8ByteLength, validateAgentName, validateExpiry, verifyJobPaymentQuick };
|
|
4327
4402
|
//# sourceMappingURL=index.js.map
|
|
4328
4403
|
//# sourceMappingURL=index.js.map
|