@elisym/mcp 0.15.8 → 0.16.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/index.js CHANGED
@@ -2228,6 +2228,9 @@ var SubmitAndPayJobFromFileSchema = z.object({
2228
2228
  input_path: z.string().min(1).max(4096).describe(
2229
2229
  "Path to a regular file whose contents become the job input. Absolute or relative to the MCP server's working directory."
2230
2230
  ),
2231
+ prompt: z.string().max(MAX_INPUT_LEN).default("").describe(
2232
+ 'Optional text instruction sent alongside the file (e.g. how to edit an image: "make it night", "add a hat"). It rides inline (NIP-44 encrypted) in the job event while the file travels peer-to-peer via iroh. The single attachment slot holds the file, so the prompt cannot spill to a second transfer - keep it short.'
2233
+ ),
2231
2234
  provider_npub: z.string(),
2232
2235
  capability: z.string().min(1).max(64).default("general"),
2233
2236
  kind_offset: z.number().int().min(0).max(999).default(DEFAULT_KIND_OFFSET),
@@ -2257,7 +2260,8 @@ function paymentCardForCapability(provider, dTag) {
2257
2260
  const candidates = dTag ? cards.filter(
2258
2261
  (card) => toDTag(card.name) === dTag || card.capabilities?.some((capability) => toDTag(capability) === dTag)
2259
2262
  ) : cards;
2260
- for (const card of candidates.length > 0 ? candidates : cards) {
2263
+ const pool = dTag !== void 0 ? candidates : cards;
2264
+ for (const card of pool) {
2261
2265
  if (card.payment?.chain === "solana" && card.payment?.address) {
2262
2266
  return card;
2263
2267
  }
@@ -3088,11 +3092,18 @@ ${wrapped}`);
3088
3092
  }),
3089
3093
  defineTool({
3090
3094
  name: "submit_and_pay_job_from_file",
3091
- description: "Same as submit_and_pay_job, but the job input is read from a file on disk by the MCP server instead of being passed inline by the LLM. Use this when the input is large or binary (images, logs, captured output) and the LLM only needs to forward it - the file content never enters the model's output tokens. input_path may be absolute or relative to the MCP server's working directory. The file is ALWAYS transferred peer-to-peer via iroh, so this needs: a persistent agent, a PAID provider skill (free skills reject file inputs), and the iroh addon. Text files reach the skill on stdin; binary files via ELISYM_INPUT_FILE.",
3095
+ description: "Same as submit_and_pay_job, but the job input is read from a file on disk by the MCP server instead of being passed inline by the LLM. Use this when the input is large or binary (images, logs, captured output) and the LLM only needs to forward it - the file content never enters the model's output tokens. input_path may be absolute or relative to the MCP server's working directory. The file is ALWAYS transferred peer-to-peer via iroh, so this needs: a persistent agent, a PAID provider skill (free skills reject file inputs), and the iroh addon. Text files reach the skill on stdin; binary files via ELISYM_INPUT_FILE. Pass an optional `prompt` to send a text instruction alongside the file (e.g. how to edit an image); it rides inline (encrypted) while the file rides P2P.",
3092
3096
  schema: SubmitAndPayJobFromFileSchema,
3093
3097
  async handler(ctx, input) {
3094
3098
  ctx.toolRateLimiter.check();
3095
3099
  checkLen("provider_npub", input.provider_npub, MAX_NPUB_LEN);
3100
+ const PROMPT_INLINE_CAP = 55e3;
3101
+ const trimmedPrompt = input.prompt.trim();
3102
+ if (utf8ByteLength(trimmedPrompt) > PROMPT_INLINE_CAP) {
3103
+ return errorResult(
3104
+ `Prompt is too long to ride inline (max ${PROMPT_INLINE_CAP} bytes); the file occupies the only attachment slot, so shorten the prompt.`
3105
+ );
3106
+ }
3096
3107
  let prepared;
3097
3108
  try {
3098
3109
  prepared = await prepareFileInput(input.input_path, {
@@ -3126,7 +3137,7 @@ ${wrapped}`);
3126
3137
  return errorResult(`Failed to seed file for transfer: ${msg}`);
3127
3138
  }
3128
3139
  return executeSubmitAndPay(ctx, agent, {
3129
- input: "",
3140
+ input: trimmedPrompt,
3130
3141
  attachment,
3131
3142
  providerNpub: input.provider_npub,
3132
3143
  providerPubkey: decodeNpub(input.provider_npub),
@@ -3527,6 +3538,7 @@ async function removeContact(agentDir, pubkey) {
3527
3538
 
3528
3539
  // src/tools/discovery.ts
3529
3540
  var SEARCH_PING_TIMEOUT_MS = 3e3;
3541
+ var MAX_SEARCH_CANDIDATES = 100;
3530
3542
  var STOP_WORDS = /* @__PURE__ */ new Set([
3531
3543
  "a",
3532
3544
  "an",
@@ -3657,7 +3669,7 @@ var STOP_WORDS = /* @__PURE__ */ new Set([
3657
3669
  "provides"
3658
3670
  ]);
3659
3671
  var SearchAgentsSchema = z.object({
3660
- capabilities: z.array(z.string()).min(1).describe("OR-matched substring filter on agent names, descriptions, and capability tags."),
3672
+ capabilities: z.array(z.string().min(1)).min(1).describe("OR-matched substring filter on agent names, descriptions, and capability tags."),
3661
3673
  query: z.string().optional().describe("Optional secondary scoring for re-ranking. Omit when you have precise tokens."),
3662
3674
  max_price_lamports: z.number().int().optional(),
3663
3675
  include_offline: z.boolean().default(false).describe(
@@ -3715,6 +3727,11 @@ var discoveryTools = [
3715
3727
  )
3716
3728
  );
3717
3729
  }
3730
+ const matchedCount = filtered.length;
3731
+ const truncated = matchedCount > MAX_SEARCH_CANDIDATES;
3732
+ if (truncated) {
3733
+ filtered = filtered.slice(0, MAX_SEARCH_CANDIDATES);
3734
+ }
3718
3735
  if (!include_offline && filtered.length > 0) {
3719
3736
  const probes = await Promise.allSettled(
3720
3737
  filtered.map(
@@ -3834,6 +3851,13 @@ var discoveryTools = [
3834
3851
  };
3835
3852
  });
3836
3853
  const { text } = sanitizeUntrusted(JSON.stringify(results, null, 2), "structured");
3854
+ if (truncated) {
3855
+ return textResult(
3856
+ `Matched ${matchedCount} agents; only the first ${MAX_SEARCH_CANDIDATES} were probed for availability (online-ping cap). Use more specific \`capabilities\` tokens for full coverage.
3857
+
3858
+ ` + text
3859
+ );
3860
+ }
3837
3861
  return textResult(text);
3838
3862
  }
3839
3863
  }),