@elisym/sdk 0.17.0 → 0.19.0
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 +107 -2
- package/dist/agent-store.cjs.map +1 -1
- package/dist/agent-store.d.cts +35 -1
- package/dist/agent-store.d.ts +35 -1
- package/dist/agent-store.js +107 -4
- package/dist/agent-store.js.map +1 -1
- package/dist/index.cjs +223 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +111 -1
- package/dist/index.d.ts +111 -1
- package/dist/index.js +218 -2
- package/dist/index.js.map +1 -1
- package/dist/llm-health.cjs +121 -1
- package/dist/llm-health.cjs.map +1 -1
- package/dist/llm-health.d.cts +70 -2
- package/dist/llm-health.d.ts +70 -2
- package/dist/llm-health.js +121 -1
- package/dist/llm-health.js.map +1 -1
- package/dist/skills.cjs.map +1 -1
- package/dist/skills.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -41,10 +41,14 @@ var RELAYS = [
|
|
|
41
41
|
"wss://relay.snort.social"
|
|
42
42
|
];
|
|
43
43
|
var KIND_APP_HANDLER = 31990;
|
|
44
|
+
var KIND_LONG_FORM_ARTICLE = 30023;
|
|
44
45
|
var KIND_JOB_REQUEST_BASE = 5e3;
|
|
45
46
|
var KIND_JOB_RESULT_BASE = 6e3;
|
|
46
47
|
var KIND_JOB_FEEDBACK = 7e3;
|
|
47
48
|
var DEFAULT_KIND_OFFSET = 100;
|
|
49
|
+
var POLICY_T_TAG = "elisym-policy";
|
|
50
|
+
var POLICY_D_TAG_PREFIX = "elisym-policy-";
|
|
51
|
+
var POLICY_TYPE_REGEX = /^[a-z0-9](?:[a-z0-9-]{0,30}[a-z0-9])?$/;
|
|
48
52
|
var KIND_JOB_REQUEST = KIND_JOB_REQUEST_BASE + DEFAULT_KIND_OFFSET;
|
|
49
53
|
var KIND_JOB_RESULT = KIND_JOB_RESULT_BASE + DEFAULT_KIND_OFFSET;
|
|
50
54
|
function jobRequestKind(offset) {
|
|
@@ -97,7 +101,13 @@ var LIMITS = {
|
|
|
97
101
|
MAX_CAPABILITIES: 20,
|
|
98
102
|
MAX_DESCRIPTION_LENGTH: 500,
|
|
99
103
|
MAX_AGENT_NAME_LENGTH: 64,
|
|
100
|
-
MAX_CAPABILITY_LENGTH: 64
|
|
104
|
+
MAX_CAPABILITY_LENGTH: 64,
|
|
105
|
+
MAX_POLICY_CONTENT_LENGTH: 5e4,
|
|
106
|
+
MAX_POLICIES_PER_AGENT: 12,
|
|
107
|
+
MAX_POLICY_TYPE_LENGTH: 32,
|
|
108
|
+
MAX_POLICY_TITLE_LENGTH: 120,
|
|
109
|
+
MAX_POLICY_SUMMARY_LENGTH: 280,
|
|
110
|
+
MAX_POLICY_VERSION_LENGTH: 32
|
|
101
111
|
};
|
|
102
112
|
function getConfigDecoder() {
|
|
103
113
|
return kit.getStructDecoder([
|
|
@@ -2725,6 +2735,184 @@ var PingService = class _PingService {
|
|
|
2725
2735
|
await this.pool.publishAll(pongEvent);
|
|
2726
2736
|
}
|
|
2727
2737
|
};
|
|
2738
|
+
function dTagFor(type) {
|
|
2739
|
+
return `${POLICY_D_TAG_PREFIX}${type}`;
|
|
2740
|
+
}
|
|
2741
|
+
function validatePolicyInput(input) {
|
|
2742
|
+
if (!POLICY_TYPE_REGEX.test(input.type)) {
|
|
2743
|
+
throw new Error(
|
|
2744
|
+
`Invalid policy type "${input.type}". Must be lowercase ASCII + hyphen, 1-${LIMITS.MAX_POLICY_TYPE_LENGTH} chars, no leading/trailing hyphen.`
|
|
2745
|
+
);
|
|
2746
|
+
}
|
|
2747
|
+
if (input.version.length === 0 || input.version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {
|
|
2748
|
+
throw new Error(
|
|
2749
|
+
`Policy version must be 1-${LIMITS.MAX_POLICY_VERSION_LENGTH} chars (got ${input.version.length}).`
|
|
2750
|
+
);
|
|
2751
|
+
}
|
|
2752
|
+
if (input.title.length === 0 || input.title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {
|
|
2753
|
+
throw new Error(
|
|
2754
|
+
`Policy title must be 1-${LIMITS.MAX_POLICY_TITLE_LENGTH} chars (got ${input.title.length}).`
|
|
2755
|
+
);
|
|
2756
|
+
}
|
|
2757
|
+
if (input.summary !== void 0 && input.summary.length > LIMITS.MAX_POLICY_SUMMARY_LENGTH) {
|
|
2758
|
+
throw new Error(
|
|
2759
|
+
`Policy summary too long: ${input.summary.length} chars (max ${LIMITS.MAX_POLICY_SUMMARY_LENGTH}).`
|
|
2760
|
+
);
|
|
2761
|
+
}
|
|
2762
|
+
if (input.content.length === 0) {
|
|
2763
|
+
throw new Error("Policy content cannot be empty.");
|
|
2764
|
+
}
|
|
2765
|
+
if (input.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {
|
|
2766
|
+
throw new Error(
|
|
2767
|
+
`Policy content too long: ${input.content.length} chars (max ${LIMITS.MAX_POLICY_CONTENT_LENGTH}).`
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
function parsePolicyEvent(event) {
|
|
2772
|
+
if (!nostrTools.verifyEvent(event)) {
|
|
2773
|
+
return null;
|
|
2774
|
+
}
|
|
2775
|
+
if (event.kind !== KIND_LONG_FORM_ARTICLE) {
|
|
2776
|
+
return null;
|
|
2777
|
+
}
|
|
2778
|
+
if (!event.content || event.content.length > LIMITS.MAX_POLICY_CONTENT_LENGTH) {
|
|
2779
|
+
return null;
|
|
2780
|
+
}
|
|
2781
|
+
const dTag = event.tags.find((tag) => tag[0] === "d")?.[1];
|
|
2782
|
+
if (!dTag || !dTag.startsWith(POLICY_D_TAG_PREFIX)) {
|
|
2783
|
+
return null;
|
|
2784
|
+
}
|
|
2785
|
+
const type = event.tags.find((tag) => tag[0] === "policy_type")?.[1];
|
|
2786
|
+
if (!type || !POLICY_TYPE_REGEX.test(type)) {
|
|
2787
|
+
return null;
|
|
2788
|
+
}
|
|
2789
|
+
const version = event.tags.find((tag) => tag[0] === "policy_version")?.[1];
|
|
2790
|
+
if (!version || version.length > LIMITS.MAX_POLICY_VERSION_LENGTH) {
|
|
2791
|
+
return null;
|
|
2792
|
+
}
|
|
2793
|
+
const title = event.tags.find((tag) => tag[0] === "title")?.[1];
|
|
2794
|
+
if (!title || title.length > LIMITS.MAX_POLICY_TITLE_LENGTH) {
|
|
2795
|
+
return null;
|
|
2796
|
+
}
|
|
2797
|
+
const summaryTag = event.tags.find((tag) => tag[0] === "summary")?.[1];
|
|
2798
|
+
const summary = summaryTag !== void 0 && summaryTag.length <= LIMITS.MAX_POLICY_SUMMARY_LENGTH ? summaryTag : void 0;
|
|
2799
|
+
const naddr = nostrTools.nip19.naddrEncode({
|
|
2800
|
+
kind: KIND_LONG_FORM_ARTICLE,
|
|
2801
|
+
pubkey: event.pubkey,
|
|
2802
|
+
identifier: dTag,
|
|
2803
|
+
relays: []
|
|
2804
|
+
});
|
|
2805
|
+
return {
|
|
2806
|
+
type,
|
|
2807
|
+
version,
|
|
2808
|
+
title,
|
|
2809
|
+
summary,
|
|
2810
|
+
content: event.content,
|
|
2811
|
+
naddr,
|
|
2812
|
+
dTag,
|
|
2813
|
+
publishedAt: event.created_at,
|
|
2814
|
+
eventId: event.id,
|
|
2815
|
+
authorPubkey: event.pubkey
|
|
2816
|
+
};
|
|
2817
|
+
}
|
|
2818
|
+
var PoliciesService = class {
|
|
2819
|
+
constructor(pool) {
|
|
2820
|
+
this.pool = pool;
|
|
2821
|
+
}
|
|
2822
|
+
/**
|
|
2823
|
+
* Fetch all elisym policies published by `pubkey`. Verifies signatures,
|
|
2824
|
+
* dedupes by d-tag (latest `created_at` wins), and returns sorted by `type`
|
|
2825
|
+
* for deterministic UI rendering.
|
|
2826
|
+
*
|
|
2827
|
+
* Returns `[]` on empty result. Network errors propagate to the caller.
|
|
2828
|
+
*/
|
|
2829
|
+
async fetchPolicies(pubkey) {
|
|
2830
|
+
const filter = {
|
|
2831
|
+
kinds: [KIND_LONG_FORM_ARTICLE],
|
|
2832
|
+
authors: [pubkey],
|
|
2833
|
+
"#t": [POLICY_T_TAG]
|
|
2834
|
+
};
|
|
2835
|
+
const events = await this.pool.querySync(filter);
|
|
2836
|
+
const latestByDTag = /* @__PURE__ */ new Map();
|
|
2837
|
+
for (const event of events) {
|
|
2838
|
+
const dTag = event.tags.find((tag) => tag[0] === "d")?.[1] ?? "";
|
|
2839
|
+
const prev = latestByDTag.get(dTag);
|
|
2840
|
+
if (!prev || event.created_at > prev.created_at) {
|
|
2841
|
+
latestByDTag.set(dTag, event);
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
const policies = [];
|
|
2845
|
+
for (const event of latestByDTag.values()) {
|
|
2846
|
+
const parsed = parsePolicyEvent(event);
|
|
2847
|
+
if (parsed) {
|
|
2848
|
+
policies.push(parsed);
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
policies.sort((a, b) => a.type.localeCompare(b.type));
|
|
2852
|
+
return policies;
|
|
2853
|
+
}
|
|
2854
|
+
/**
|
|
2855
|
+
* Publish a policy as a NIP-23 long-form article (kind 30023). Replaces any
|
|
2856
|
+
* existing policy of the same `type` for this pubkey via the addressable
|
|
2857
|
+
* `(kind, pubkey, d-tag)` slot.
|
|
2858
|
+
*/
|
|
2859
|
+
async publishPolicy(identity, input) {
|
|
2860
|
+
validatePolicyInput(input);
|
|
2861
|
+
const dTag = dTagFor(input.type);
|
|
2862
|
+
const tags = [
|
|
2863
|
+
["d", dTag],
|
|
2864
|
+
["t", POLICY_T_TAG],
|
|
2865
|
+
["title", input.title],
|
|
2866
|
+
["policy_type", input.type],
|
|
2867
|
+
["policy_version", input.version]
|
|
2868
|
+
];
|
|
2869
|
+
if (input.summary) {
|
|
2870
|
+
tags.push(["summary", input.summary]);
|
|
2871
|
+
}
|
|
2872
|
+
const event = nostrTools.finalizeEvent(
|
|
2873
|
+
{
|
|
2874
|
+
kind: KIND_LONG_FORM_ARTICLE,
|
|
2875
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
2876
|
+
tags,
|
|
2877
|
+
content: input.content
|
|
2878
|
+
},
|
|
2879
|
+
identity.secretKey
|
|
2880
|
+
);
|
|
2881
|
+
await this.pool.publishAll(event);
|
|
2882
|
+
const naddr = nostrTools.nip19.naddrEncode({
|
|
2883
|
+
kind: KIND_LONG_FORM_ARTICLE,
|
|
2884
|
+
pubkey: event.pubkey,
|
|
2885
|
+
identifier: dTag,
|
|
2886
|
+
relays: []
|
|
2887
|
+
});
|
|
2888
|
+
return { eventId: event.id, naddr };
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* Tombstone a policy by publishing an empty replacement under the same
|
|
2892
|
+
* `(kind, pubkey, d-tag)` slot. Readers skip events with empty content.
|
|
2893
|
+
*/
|
|
2894
|
+
async deletePolicy(identity, type) {
|
|
2895
|
+
if (!POLICY_TYPE_REGEX.test(type)) {
|
|
2896
|
+
throw new Error(`Invalid policy type "${type}".`);
|
|
2897
|
+
}
|
|
2898
|
+
const dTag = dTagFor(type);
|
|
2899
|
+
const event = nostrTools.finalizeEvent(
|
|
2900
|
+
{
|
|
2901
|
+
kind: KIND_LONG_FORM_ARTICLE,
|
|
2902
|
+
created_at: Math.floor(Date.now() / 1e3),
|
|
2903
|
+
tags: [
|
|
2904
|
+
["d", dTag],
|
|
2905
|
+
["t", POLICY_T_TAG],
|
|
2906
|
+
["policy_type", type]
|
|
2907
|
+
],
|
|
2908
|
+
content: ""
|
|
2909
|
+
},
|
|
2910
|
+
identity.secretKey
|
|
2911
|
+
);
|
|
2912
|
+
await this.pool.publishAll(event);
|
|
2913
|
+
return event.id;
|
|
2914
|
+
}
|
|
2915
|
+
};
|
|
2728
2916
|
|
|
2729
2917
|
// src/primitives/bounded-set.ts
|
|
2730
2918
|
var BoundedSet = class {
|
|
@@ -3033,6 +3221,7 @@ var ElisymClient = class {
|
|
|
3033
3221
|
marketplace;
|
|
3034
3222
|
ping;
|
|
3035
3223
|
media;
|
|
3224
|
+
policies;
|
|
3036
3225
|
payment;
|
|
3037
3226
|
constructor(config = {}) {
|
|
3038
3227
|
this.pool = new NostrPool(config.relays ?? RELAYS);
|
|
@@ -3040,12 +3229,39 @@ var ElisymClient = class {
|
|
|
3040
3229
|
this.marketplace = new MarketplaceService(this.pool);
|
|
3041
3230
|
this.ping = new PingService(this.pool);
|
|
3042
3231
|
this.media = new MediaService(config.uploadUrl);
|
|
3232
|
+
this.policies = new PoliciesService(this.pool);
|
|
3043
3233
|
this.payment = config.payment ?? new SolanaPaymentStrategy();
|
|
3044
3234
|
}
|
|
3045
3235
|
close() {
|
|
3046
3236
|
this.pool.close();
|
|
3047
3237
|
}
|
|
3048
3238
|
};
|
|
3239
|
+
|
|
3240
|
+
// src/services/jobErrors.ts
|
|
3241
|
+
var AGENT_UNAVAILABLE_MARKERS = [
|
|
3242
|
+
"agent temporarily unavailable",
|
|
3243
|
+
"internal processing error",
|
|
3244
|
+
"invalid x-api-key",
|
|
3245
|
+
"invalid api key",
|
|
3246
|
+
"invalid_api_key",
|
|
3247
|
+
"x-api-key",
|
|
3248
|
+
"credit balance",
|
|
3249
|
+
"billing",
|
|
3250
|
+
"insufficient",
|
|
3251
|
+
"insufficient_quota",
|
|
3252
|
+
"authentication_error",
|
|
3253
|
+
"unauthorized",
|
|
3254
|
+
"unauthenticated"
|
|
3255
|
+
];
|
|
3256
|
+
function classifyJobError(message) {
|
|
3257
|
+
const lower = message.toLowerCase();
|
|
3258
|
+
for (const marker of AGENT_UNAVAILABLE_MARKERS) {
|
|
3259
|
+
if (lower.includes(marker)) {
|
|
3260
|
+
return "agent-unavailable";
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
return "unknown";
|
|
3264
|
+
}
|
|
3049
3265
|
var DEFAULT_COMPUTE_UNIT_LIMIT2 = 2e5;
|
|
3050
3266
|
var DEFAULT_PRIORITY_FEE_PERCENTILE2 = 75;
|
|
3051
3267
|
var BASE_FEE_LAMPORTS_PER_SIGNATURE = 5000n;
|
|
@@ -3587,6 +3803,7 @@ exports.KIND_JOB_REQUEST = KIND_JOB_REQUEST;
|
|
|
3587
3803
|
exports.KIND_JOB_REQUEST_BASE = KIND_JOB_REQUEST_BASE;
|
|
3588
3804
|
exports.KIND_JOB_RESULT = KIND_JOB_RESULT;
|
|
3589
3805
|
exports.KIND_JOB_RESULT_BASE = KIND_JOB_RESULT_BASE;
|
|
3806
|
+
exports.KIND_LONG_FORM_ARTICLE = KIND_LONG_FORM_ARTICLE;
|
|
3590
3807
|
exports.KIND_PING = KIND_PING;
|
|
3591
3808
|
exports.KIND_PONG = KIND_PONG;
|
|
3592
3809
|
exports.KNOWN_ASSETS = KNOWN_ASSETS;
|
|
@@ -3596,9 +3813,13 @@ exports.MarketplaceService = MarketplaceService;
|
|
|
3596
3813
|
exports.MediaService = MediaService;
|
|
3597
3814
|
exports.NATIVE_SOL = NATIVE_SOL;
|
|
3598
3815
|
exports.NostrPool = NostrPool;
|
|
3816
|
+
exports.POLICY_D_TAG_PREFIX = POLICY_D_TAG_PREFIX;
|
|
3817
|
+
exports.POLICY_TYPE_REGEX = POLICY_TYPE_REGEX;
|
|
3818
|
+
exports.POLICY_T_TAG = POLICY_T_TAG;
|
|
3599
3819
|
exports.PROTOCOL_PROGRAM_ID_DEVNET = PROTOCOL_PROGRAM_ID_DEVNET;
|
|
3600
3820
|
exports.PaymentRequestSchema = PaymentRequestSchema;
|
|
3601
3821
|
exports.PingService = PingService;
|
|
3822
|
+
exports.PoliciesService = PoliciesService;
|
|
3602
3823
|
exports.RELAYS = RELAYS;
|
|
3603
3824
|
exports.SECRET_REDACT_PATHS = SECRET_REDACT_PATHS;
|
|
3604
3825
|
exports.SessionSpendLimitEntrySchema = SessionSpendLimitEntrySchema;
|
|
@@ -3611,6 +3832,7 @@ exports.assetByKey = assetByKey;
|
|
|
3611
3832
|
exports.assetKey = assetKey;
|
|
3612
3833
|
exports.buildPaymentInstructions = buildPaymentInstructions;
|
|
3613
3834
|
exports.calculateProtocolFee = calculateProtocolFee;
|
|
3835
|
+
exports.classifyJobError = classifyJobError;
|
|
3614
3836
|
exports.clearPriorityFeeCache = clearPriorityFeeCache;
|
|
3615
3837
|
exports.clearProtocolConfigCache = clearProtocolConfigCache;
|
|
3616
3838
|
exports.clearQuickVerifyCache = clearQuickVerifyCache;
|