@elisym/mcp 0.8.12 → 0.8.14
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 +63 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1167,6 +1167,7 @@ function sanitizeField(input, maxLen) {
|
|
|
1167
1167
|
}
|
|
1168
1168
|
var CUSTOMER_HISTORY_FILENAME = ".customer-history.json";
|
|
1169
1169
|
var MAX_HISTORY_ENTRIES = 500;
|
|
1170
|
+
var RESULT_PREVIEW_MAX_LEN = 1e4;
|
|
1170
1171
|
var StatusSchema = z.enum(["completed", "failed", "timeout"]);
|
|
1171
1172
|
var FeedbackSchema = z.enum(["positive", "negative"]);
|
|
1172
1173
|
var CustomerJobEntrySchema = z.object({
|
|
@@ -1179,7 +1180,7 @@ var CustomerJobEntrySchema = z.object({
|
|
|
1179
1180
|
status: StatusSchema,
|
|
1180
1181
|
submittedAt: z.number().int().nonnegative(),
|
|
1181
1182
|
completedAt: z.number().int().nonnegative(),
|
|
1182
|
-
resultPreview: z.string().max(
|
|
1183
|
+
resultPreview: z.string().max(RESULT_PREVIEW_MAX_LEN).optional(),
|
|
1183
1184
|
paymentSig: z.string().max(128).optional(),
|
|
1184
1185
|
customerFeedback: FeedbackSchema.optional()
|
|
1185
1186
|
}).strict();
|
|
@@ -1856,7 +1857,7 @@ ${sanitized.text}`);
|
|
|
1856
1857
|
status: "completed",
|
|
1857
1858
|
submittedAt,
|
|
1858
1859
|
completedAt: Date.now(),
|
|
1859
|
-
resultPreview: result.slice(0,
|
|
1860
|
+
resultPreview: result.slice(0, RESULT_PREVIEW_MAX_LEN),
|
|
1860
1861
|
paymentSig
|
|
1861
1862
|
});
|
|
1862
1863
|
const warningBlock = paymentWarnings.length > 0 ? `${paymentWarnings.join("\n")}
|
|
@@ -2015,7 +2016,7 @@ ${sanitized.text}`
|
|
|
2015
2016
|
status: "completed",
|
|
2016
2017
|
submittedAt,
|
|
2017
2018
|
completedAt: Date.now(),
|
|
2018
|
-
resultPreview: result.slice(0,
|
|
2019
|
+
resultPreview: result.slice(0, RESULT_PREVIEW_MAX_LEN),
|
|
2019
2020
|
paymentSig
|
|
2020
2021
|
});
|
|
2021
2022
|
const warningBlock = paymentWarnings.length > 0 ? `${paymentWarnings.join("\n")}
|
|
@@ -2336,7 +2337,7 @@ var GetIdentitySchema = z.object({});
|
|
|
2336
2337
|
var discoveryTools = [
|
|
2337
2338
|
defineTool({
|
|
2338
2339
|
name: "search_agents",
|
|
2339
|
-
description: "Search AI agents currently online on elisym. `capabilities` is a hard OR-filter of substring tokens from the user's request (never invent synonyms). `query` is optional re-ranking; omit if not needed. Offline agents are excluded by default - pass include_offline=true only when debugging.",
|
|
2340
|
+
description: "Search AI agents currently online on elisym. `capabilities` is a hard OR-filter of substring tokens from the user's request (never invent synonyms). `query` is optional re-ranking; omit if not needed. Offline agents are excluded by default - pass include_offline=true only when debugging. Results that match a saved contact are sorted to the top and annotated with `is_contact`, `last_worked_at`, `last_capability`, and `contact_note` - surface this to the user (e.g. \"already in your contacts, last used <date>\") so they can prefer providers they've worked with before.",
|
|
2340
2341
|
schema: SearchAgentsSchema,
|
|
2341
2342
|
async handler(ctx, input) {
|
|
2342
2343
|
const { capabilities, query, max_price_lamports, include_offline, contacts_only } = input;
|
|
@@ -2344,25 +2345,27 @@ var discoveryTools = [
|
|
|
2344
2345
|
return errorResult(`Too many capabilities (max ${MAX_CAPABILITIES})`);
|
|
2345
2346
|
}
|
|
2346
2347
|
const agent = ctx.active();
|
|
2347
|
-
|
|
2348
|
+
const contactByPubkey = /* @__PURE__ */ new Map();
|
|
2349
|
+
if (agent.agentDir) {
|
|
2350
|
+
const data = await readContacts(agent.agentDir);
|
|
2351
|
+
for (const contact of data.contacts) {
|
|
2352
|
+
contactByPubkey.set(contact.pubkey, contact);
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
2348
2355
|
if (contacts_only) {
|
|
2349
2356
|
if (!agent.agentDir) {
|
|
2350
2357
|
return textResult(
|
|
2351
2358
|
"contacts_only=true requires a persistent agent (no on-disk directory for the active agent)."
|
|
2352
2359
|
);
|
|
2353
2360
|
}
|
|
2354
|
-
|
|
2355
|
-
if (data.contacts.length === 0) {
|
|
2361
|
+
if (contactByPubkey.size === 0) {
|
|
2356
2362
|
return textResult(
|
|
2357
2363
|
"No contacts saved yet. Use add_contact (or rate a job positively with submit_feedback and then add_contact) before searching with contacts_only=true."
|
|
2358
2364
|
);
|
|
2359
2365
|
}
|
|
2360
|
-
lastWorkedAtByPubkey = new Map(
|
|
2361
|
-
data.contacts.map((contact) => [contact.pubkey, contact.lastJobAt ?? contact.addedAt])
|
|
2362
|
-
);
|
|
2363
2366
|
}
|
|
2364
2367
|
const agents = await agent.client.discovery.fetchAgents(agent.network);
|
|
2365
|
-
let filtered = contacts_only ? agents.filter((a) =>
|
|
2368
|
+
let filtered = contacts_only ? agents.filter((a) => contactByPubkey.has(a.pubkey)) : agents;
|
|
2366
2369
|
filtered = filtered.filter(
|
|
2367
2370
|
(a) => a.cards.some(
|
|
2368
2371
|
(card) => capabilities.some(
|
|
@@ -2405,10 +2408,28 @@ var discoveryTools = [
|
|
|
2405
2408
|
hits++;
|
|
2406
2409
|
}
|
|
2407
2410
|
}
|
|
2408
|
-
|
|
2411
|
+
const contactBoost = contactByPubkey.has(a.pubkey) ? 0.5 : 0;
|
|
2412
|
+
return { agent: a, score: hits + contactBoost };
|
|
2409
2413
|
});
|
|
2410
2414
|
filtered = scored.filter((s) => s.score > 0).sort((a, b) => b.score - a.score).map((s) => s.agent);
|
|
2411
2415
|
}
|
|
2416
|
+
} else if (contactByPubkey.size > 0) {
|
|
2417
|
+
filtered = [...filtered].sort((left, right) => {
|
|
2418
|
+
const leftContact = contactByPubkey.get(left.pubkey);
|
|
2419
|
+
const rightContact = contactByPubkey.get(right.pubkey);
|
|
2420
|
+
if (leftContact && !rightContact) {
|
|
2421
|
+
return -1;
|
|
2422
|
+
}
|
|
2423
|
+
if (rightContact && !leftContact) {
|
|
2424
|
+
return 1;
|
|
2425
|
+
}
|
|
2426
|
+
if (leftContact && rightContact) {
|
|
2427
|
+
const leftTs = leftContact.lastJobAt ?? leftContact.addedAt;
|
|
2428
|
+
const rightTs = rightContact.lastJobAt ?? rightContact.addedAt;
|
|
2429
|
+
return rightTs - leftTs;
|
|
2430
|
+
}
|
|
2431
|
+
return 0;
|
|
2432
|
+
});
|
|
2412
2433
|
}
|
|
2413
2434
|
if (filtered.length === 0) {
|
|
2414
2435
|
return textResult(
|
|
@@ -2440,30 +2461,36 @@ var discoveryTools = [
|
|
|
2440
2461
|
} catch {
|
|
2441
2462
|
}
|
|
2442
2463
|
}
|
|
2443
|
-
const results = filtered.map((a) =>
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2464
|
+
const results = filtered.map((a) => {
|
|
2465
|
+
const contact = contactByPubkey.get(a.pubkey);
|
|
2466
|
+
return {
|
|
2467
|
+
npub: a.npub,
|
|
2468
|
+
name: sanitizeField(a.name || "", 200),
|
|
2469
|
+
cards: a.cards.map((card) => {
|
|
2470
|
+
const asset = assetFromCardPayment(card.payment);
|
|
2471
|
+
const price = card.payment?.job_price;
|
|
2472
|
+
const gasEstimate = price ? gasByAtaNeed.get(asset.mint !== void 0) : void 0;
|
|
2473
|
+
return {
|
|
2474
|
+
name: sanitizeField(card.name || "", 200),
|
|
2475
|
+
description: sanitizeField(card.description || "", 500),
|
|
2476
|
+
capabilities: card.capabilities,
|
|
2477
|
+
job_price_subunits: price,
|
|
2478
|
+
price_display: price ? formatAssetAmount(asset, BigInt(price)) : "free",
|
|
2479
|
+
asset_token: asset.token,
|
|
2480
|
+
asset_symbol: asset.symbol,
|
|
2481
|
+
asset_mint: asset.mint,
|
|
2482
|
+
chain: card.payment?.chain,
|
|
2483
|
+
network: card.payment?.network,
|
|
2484
|
+
network_fee_estimate_sol: gasEstimate
|
|
2485
|
+
};
|
|
2486
|
+
}),
|
|
2487
|
+
supported_kinds: a.supportedKinds,
|
|
2488
|
+
is_contact: contact ? true : void 0,
|
|
2489
|
+
last_worked_at: contact ? contact.lastJobAt ?? contact.addedAt : void 0,
|
|
2490
|
+
last_capability: contact?.lastCapability,
|
|
2491
|
+
contact_note: contact?.note ? sanitizeField(contact.note, 500) : void 0
|
|
2492
|
+
};
|
|
2493
|
+
});
|
|
2467
2494
|
const { text } = sanitizeUntrusted(JSON.stringify(results, null, 2), "structured");
|
|
2468
2495
|
return textResult(text);
|
|
2469
2496
|
}
|