@elisym/sdk 0.23.0 → 0.24.1
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 +22 -0
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.d.cts +9 -1
- package/dist/agent-store.d.ts +9 -1
- package/dist/agent-store.js +23 -2
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +134 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +206 -6
- package/dist/index.d.ts +206 -6
- package/dist/index.js +131 -10
- package/dist/index.js.map +1 -1
- package/dist/llm-health.cjs.map +1 -1
- package/dist/llm-health.d.cts +2 -2
- package/dist/llm-health.d.ts +2 -2
- package/dist/llm-health.js.map +1 -1
- package/dist/node.cjs +175 -0
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +46 -1
- package/dist/node.d.ts +46 -1
- package/dist/node.js +175 -1
- package/dist/node.js.map +1 -1
- package/dist/skills.cjs +128 -28
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.d.cts +49 -1
- package/dist/skills.d.ts +49 -1
- package/dist/skills.js +130 -30
- package/dist/skills.js.map +1 -1
- package/dist/{types-Cdscy9kY.d.cts → types-CqN9kFTn.d.cts} +6 -1
- package/dist/{types-Cdscy9kY.d.ts → types-CqN9kFTn.d.ts} +6 -1
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -68,10 +68,35 @@ var DEFAULTS = {
|
|
|
68
68
|
RESULT_RETRY_COUNT: 3,
|
|
69
69
|
RESULT_RETRY_BASE_MS: 1e3,
|
|
70
70
|
QUERY_MAX_CONCURRENCY: 6,
|
|
71
|
-
VERIFY_SIGNATURE_LIMIT: 25
|
|
71
|
+
VERIFY_SIGNATURE_LIMIT: 25,
|
|
72
|
+
// Default ceiling for a single iroh file transfer (seed/fetch). A tunable
|
|
73
|
+
// default, not a protocol constant - the transfer is resumable and its own
|
|
74
|
+
// budget, decoupled from the result-wait window.
|
|
75
|
+
IROH_FETCH_TIMEOUT_MS: 3e5
|
|
72
76
|
};
|
|
73
77
|
var LIMITS = {
|
|
74
78
|
MAX_INPUT_LENGTH: 1e5,
|
|
79
|
+
// NIP-44 v2 hard cap on encrypted plaintext: the pad() length prefix is a u16,
|
|
80
|
+
// so the plaintext can be at most 65_535 BYTES (not chars). Encrypting anything
|
|
81
|
+
// larger throws `invalid plaintext size` inside nip44Encrypt. This is the binding
|
|
82
|
+
// limit for TARGETED (encrypted) jobs - lower than every relay's NIP-11 cap.
|
|
83
|
+
NIP44_MAX_PLAINTEXT_BYTES: 65535,
|
|
84
|
+
// Spill threshold for encrypted content: above this many UTF-8 bytes, callers
|
|
85
|
+
// route the text through iroh out-of-band instead of inlining it. A non-spilled
|
|
86
|
+
// job is encrypted RAW (no envelope - see marketplace.submitJobRequest), so a
|
|
87
|
+
// 60_000-byte input is a 60_000-byte plaintext; the ~5.5KB gap under the hard cap
|
|
88
|
+
// is plain slack, and NIP44_MAX_PLAINTEXT_BYTES is the SDK backstop.
|
|
89
|
+
MAX_ENCRYPTED_INLINE_BYTES: 6e4,
|
|
90
|
+
// Ceiling above which a text/* attachment is NOT materialized back into a string
|
|
91
|
+
// (re-inlined into SkillInput.data) - the consumer gets a filePath / explicit
|
|
92
|
+
// fetch instead. Also bounds the in-memory git-diff buffer (memory-DoS guard).
|
|
93
|
+
MAX_REINLINE_TEXT_BYTES: 4194304,
|
|
94
|
+
// 4 MiB
|
|
95
|
+
// Hard safety cap on a single file transferred via iroh, enforced on the
|
|
96
|
+
// actual streamed bytes (never the sender-declared `size`). A tunable default;
|
|
97
|
+
// providers may lower it per deployment.
|
|
98
|
+
MAX_FILE_SIZE: 1073741824,
|
|
99
|
+
// 1 GiB
|
|
75
100
|
MAX_TIMEOUT_SECS: 600,
|
|
76
101
|
// Upper bound for execution budgets (`max_execution_secs` / `execution_timeout_secs`).
|
|
77
102
|
// Distinct from MAX_TIMEOUT_SECS (the result-wait cap): execution budgets may be
|
|
@@ -89,6 +114,10 @@ var LIMITS = {
|
|
|
89
114
|
MAX_POLICY_SUMMARY_LENGTH: 280,
|
|
90
115
|
MAX_POLICY_VERSION_LENGTH: 32
|
|
91
116
|
};
|
|
117
|
+
var UTF8_ENCODER = new TextEncoder();
|
|
118
|
+
function utf8ByteLength(value) {
|
|
119
|
+
return UTF8_ENCODER.encode(value).length;
|
|
120
|
+
}
|
|
92
121
|
function getConfigDecoder() {
|
|
93
122
|
return getStructDecoder([
|
|
94
123
|
["discriminator", fixDecoderSize(getBytesDecoder(), 8)],
|
|
@@ -1212,6 +1241,12 @@ function parseCapabilityEvent(event, network) {
|
|
|
1212
1241
|
if (card.payment && (typeof card.payment.chain !== "string" || typeof card.payment.network !== "string" || typeof card.payment.address !== "string")) {
|
|
1213
1242
|
return null;
|
|
1214
1243
|
}
|
|
1244
|
+
if (card.payment && (card.payment.token !== void 0 && typeof card.payment.token !== "string" || card.payment.symbol !== void 0 && typeof card.payment.symbol !== "string" || card.payment.mint !== void 0 && typeof card.payment.mint !== "string")) {
|
|
1245
|
+
return null;
|
|
1246
|
+
}
|
|
1247
|
+
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)) {
|
|
1248
|
+
return null;
|
|
1249
|
+
}
|
|
1215
1250
|
if (card.payment?.job_price !== null && card.payment?.job_price !== void 0 && (!Number.isInteger(card.payment.job_price) || card.payment.job_price < 0)) {
|
|
1216
1251
|
return null;
|
|
1217
1252
|
}
|
|
@@ -1788,6 +1823,67 @@ function nip44Decrypt(ciphertext, receiverSk, senderPubkey) {
|
|
|
1788
1823
|
const conversationKey = nip44.v2.utils.getConversationKey(receiverSk, senderPubkey);
|
|
1789
1824
|
return nip44.v2.decrypt(ciphertext, conversationKey);
|
|
1790
1825
|
}
|
|
1826
|
+
var ENVELOPE_VERSION = "elisym-job/1";
|
|
1827
|
+
var ENVELOPE_NAMESPACE_PREFIX = "elisym-job/";
|
|
1828
|
+
var MAX_TICKET_LENGTH = 4096;
|
|
1829
|
+
var FileTransportSchema = z.discriminatedUnion("kind", [
|
|
1830
|
+
z.object({
|
|
1831
|
+
kind: z.literal("iroh"),
|
|
1832
|
+
/** Opaque iroh `BlobTicket` string. Parsed into a real ticket only at fetch time. */
|
|
1833
|
+
ticket: z.string().min(1).max(MAX_TICKET_LENGTH)
|
|
1834
|
+
})
|
|
1835
|
+
]);
|
|
1836
|
+
var FileAttachmentSchema = z.object({
|
|
1837
|
+
/** Display name only. Never used to derive a filesystem path (callers sanitize). */
|
|
1838
|
+
name: z.string().min(1).max(255),
|
|
1839
|
+
/** Declared size in bytes (display/hint only; enforcement is on actual streamed bytes). */
|
|
1840
|
+
size: z.number().int().nonnegative(),
|
|
1841
|
+
mime: z.string().min(1).max(255),
|
|
1842
|
+
/** Ordered by sender preference; at least one. */
|
|
1843
|
+
transports: z.array(FileTransportSchema).min(1),
|
|
1844
|
+
/** Optional provider hint (unix seconds) for when seeding may stop. */
|
|
1845
|
+
seedingExpiresAt: z.number().int().nonnegative().optional()
|
|
1846
|
+
});
|
|
1847
|
+
var JobPayloadEnvelopeSchema = z.object({
|
|
1848
|
+
v: z.literal(ENVELOPE_VERSION),
|
|
1849
|
+
text: z.string().optional(),
|
|
1850
|
+
attachment: FileAttachmentSchema.optional()
|
|
1851
|
+
});
|
|
1852
|
+
function encodeJobPayload(payload) {
|
|
1853
|
+
const envelope = { v: ENVELOPE_VERSION };
|
|
1854
|
+
if (payload.text !== void 0) {
|
|
1855
|
+
envelope.text = payload.text;
|
|
1856
|
+
}
|
|
1857
|
+
if (payload.attachment !== void 0) {
|
|
1858
|
+
envelope.attachment = payload.attachment;
|
|
1859
|
+
}
|
|
1860
|
+
return JSON.stringify(envelope);
|
|
1861
|
+
}
|
|
1862
|
+
function decodeJobPayload(content) {
|
|
1863
|
+
if (content.length > LIMITS.MAX_INPUT_LENGTH) {
|
|
1864
|
+
return { text: content };
|
|
1865
|
+
}
|
|
1866
|
+
let parsed;
|
|
1867
|
+
try {
|
|
1868
|
+
parsed = JSON.parse(content);
|
|
1869
|
+
} catch {
|
|
1870
|
+
return { text: content };
|
|
1871
|
+
}
|
|
1872
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
1873
|
+
return { text: content };
|
|
1874
|
+
}
|
|
1875
|
+
const version = parsed.v;
|
|
1876
|
+
if (typeof version !== "string" || !version.startsWith(ENVELOPE_NAMESPACE_PREFIX)) {
|
|
1877
|
+
return { text: content };
|
|
1878
|
+
}
|
|
1879
|
+
const result = JobPayloadEnvelopeSchema.safeParse(parsed);
|
|
1880
|
+
if (!result.success) {
|
|
1881
|
+
throw new Error(
|
|
1882
|
+
`Invalid elisym job payload (v=${JSON.stringify(version)}): ${result.error.message}`
|
|
1883
|
+
);
|
|
1884
|
+
}
|
|
1885
|
+
return { text: result.data.text, attachment: result.data.attachment };
|
|
1886
|
+
}
|
|
1791
1887
|
|
|
1792
1888
|
// src/services/marketplace.ts
|
|
1793
1889
|
function isEncrypted(event) {
|
|
@@ -1820,7 +1916,8 @@ var MarketplaceService = class {
|
|
|
1820
1916
|
}
|
|
1821
1917
|
/** Submit a job request with NIP-44 encrypted input. Returns the event ID. */
|
|
1822
1918
|
async submitJobRequest(identity, options) {
|
|
1823
|
-
|
|
1919
|
+
const hasAttachment = options.attachment !== void 0;
|
|
1920
|
+
if (!options.input && !hasAttachment) {
|
|
1824
1921
|
throw new Error("Job input must not be empty.");
|
|
1825
1922
|
}
|
|
1826
1923
|
if (options.input.length > LIMITS.MAX_INPUT_LENGTH) {
|
|
@@ -1834,7 +1931,15 @@ var MarketplaceService = class {
|
|
|
1834
1931
|
if (options.providerPubkey && !/^[0-9a-f]{64}$/.test(options.providerPubkey)) {
|
|
1835
1932
|
throw new Error("Invalid provider pubkey: expected 64 hex characters.");
|
|
1836
1933
|
}
|
|
1837
|
-
const plaintext = options.input;
|
|
1934
|
+
const plaintext = hasAttachment ? encodeJobPayload({ text: options.input || void 0, attachment: options.attachment }) : options.input;
|
|
1935
|
+
if (options.providerPubkey) {
|
|
1936
|
+
const plaintextBytes = utf8ByteLength(plaintext);
|
|
1937
|
+
if (plaintextBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {
|
|
1938
|
+
throw new Error(
|
|
1939
|
+
`Encrypted job input too large: ${plaintextBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Send large input as a file/iroh attachment instead.`
|
|
1940
|
+
);
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1838
1943
|
const encrypted = options.providerPubkey ? nip44Encrypt(plaintext, identity.secretKey, options.providerPubkey) : plaintext;
|
|
1839
1944
|
const tags = [
|
|
1840
1945
|
["i", options.providerPubkey ? "encrypted" : "text", "text"],
|
|
@@ -1928,9 +2033,15 @@ var MarketplaceService = class {
|
|
|
1928
2033
|
if (content === null) {
|
|
1929
2034
|
return;
|
|
1930
2035
|
}
|
|
2036
|
+
let decoded;
|
|
2037
|
+
try {
|
|
2038
|
+
decoded = decodeJobPayload(content);
|
|
2039
|
+
} catch {
|
|
2040
|
+
return;
|
|
2041
|
+
}
|
|
1931
2042
|
resultDelivered = true;
|
|
1932
2043
|
try {
|
|
1933
|
-
cb.onResult?.(
|
|
2044
|
+
cb.onResult?.(decoded.text ?? "", ev.id, decoded.attachment);
|
|
1934
2045
|
} catch {
|
|
1935
2046
|
} finally {
|
|
1936
2047
|
done();
|
|
@@ -2094,8 +2205,9 @@ var MarketplaceService = class {
|
|
|
2094
2205
|
);
|
|
2095
2206
|
}
|
|
2096
2207
|
/** Submit a job result with NIP-44 encrypted content. Result kind is derived from the request kind. */
|
|
2097
|
-
async submitJobResult(identity, requestEvent, content, amount) {
|
|
2098
|
-
|
|
2208
|
+
async submitJobResult(identity, requestEvent, content, amount, attachment) {
|
|
2209
|
+
const hasAttachment = attachment !== void 0;
|
|
2210
|
+
if (!content && !hasAttachment) {
|
|
2099
2211
|
throw new Error("Job result content must not be empty.");
|
|
2100
2212
|
}
|
|
2101
2213
|
if (!Number.isInteger(requestEvent.kind)) {
|
|
@@ -2108,7 +2220,16 @@ var MarketplaceService = class {
|
|
|
2108
2220
|
);
|
|
2109
2221
|
}
|
|
2110
2222
|
const shouldEncrypt = isEncrypted(requestEvent);
|
|
2111
|
-
const
|
|
2223
|
+
const payload = hasAttachment ? encodeJobPayload({ text: content || void 0, attachment }) : content;
|
|
2224
|
+
if (shouldEncrypt) {
|
|
2225
|
+
const payloadBytes = utf8ByteLength(payload);
|
|
2226
|
+
if (payloadBytes > LIMITS.NIP44_MAX_PLAINTEXT_BYTES) {
|
|
2227
|
+
throw new Error(
|
|
2228
|
+
`Encrypted job result too large: ${payloadBytes} bytes (max ${LIMITS.NIP44_MAX_PLAINTEXT_BYTES}). Deliver large results as a file/iroh attachment instead.`
|
|
2229
|
+
);
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
const resultContent = shouldEncrypt ? nip44Encrypt(payload, identity.secretKey, requestEvent.pubkey) : payload;
|
|
2112
2233
|
const resultKind = KIND_JOB_RESULT_BASE + offset;
|
|
2113
2234
|
const tags = [
|
|
2114
2235
|
["e", requestEvent.id],
|
|
@@ -2140,11 +2261,11 @@ var MarketplaceService = class {
|
|
|
2140
2261
|
* With maxAttempts=3: try, ~1s, try, ~2s, try, throw.
|
|
2141
2262
|
* Jitter: 0.5x-1.0x of calculated delay.
|
|
2142
2263
|
*/
|
|
2143
|
-
async submitJobResultWithRetry(identity, requestEvent, content, amount, maxAttempts = DEFAULTS.RESULT_RETRY_COUNT, baseDelayMs = DEFAULTS.RESULT_RETRY_BASE_MS) {
|
|
2264
|
+
async submitJobResultWithRetry(identity, requestEvent, content, amount, maxAttempts = DEFAULTS.RESULT_RETRY_COUNT, baseDelayMs = DEFAULTS.RESULT_RETRY_BASE_MS, attachment) {
|
|
2144
2265
|
const attempts = Math.max(1, maxAttempts);
|
|
2145
2266
|
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
2146
2267
|
try {
|
|
2147
|
-
return await this.submitJobResult(identity, requestEvent, content, amount);
|
|
2268
|
+
return await this.submitJobResult(identity, requestEvent, content, amount, attachment);
|
|
2148
2269
|
} catch (e) {
|
|
2149
2270
|
if (attempt >= attempts - 1) {
|
|
2150
2271
|
throw e;
|
|
@@ -3804,6 +3925,6 @@ function makeCensor() {
|
|
|
3804
3925
|
};
|
|
3805
3926
|
}
|
|
3806
3927
|
|
|
3807
|
-
export { BoundedSet, DEFAULTS, DEFAULT_KIND_OFFSET, DEFAULT_REDACT_PATHS, DiscoveryService, ELISYM_PROTOCOL_TAG, 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, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, validateAgentName, validateExpiry, verifyJobPaymentQuick };
|
|
3928
|
+
export { 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, buildPaymentInstructions, calculateProtocolFee, classifyJobError, clearPriorityFeeCache, clearProtocolConfigCache, clearQuickVerifyCache, compareAgentsByRank, computeRankKey, createPaymentRequestWithOnchainConfig, createSlidingWindowLimiter, decodeJobPayload, encodeJobPayload, estimateNetworkBaseline, estimatePriorityFeeMicroLamports, estimateSolFeeLamports, formatAssetAmount, formatFeeBreakdown, formatNetworkBaseline, formatSol, getNetworkStats, getProtocolConfig, getProtocolProgramId, jobRequestKind, jobResultKind, makeCensor, nip44Decrypt, nip44Encrypt, parseAssetAmount, parsePaymentRequest, pickPercentileFee, resolveAssetFromPaymentRequest, resolveKnownAsset, timeAgo, toDTag, truncateKey, utf8ByteLength, validateAgentName, validateExpiry, verifyJobPaymentQuick };
|
|
3808
3929
|
//# sourceMappingURL=index.js.map
|
|
3809
3930
|
//# sourceMappingURL=index.js.map
|