akemon 0.1.50 → 0.1.52

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/connect.js CHANGED
@@ -35,7 +35,7 @@ export async function connect(options) {
35
35
  };
36
36
  });
37
37
  // call_agent — call a named agent via HTTP
38
- server.tool("call_agent", "Call another akemon agent by name. The target agent will execute the task and return the result. Use this to delegate subtasks to specialized agents.", {
38
+ server.tool("call_agent", "Synchronous call to an agent. Blocks until response. Fails if agent is offline or slow. For reliable async tasks, use the order API instead.", {
39
39
  agent: z.string().describe("Name of the target agent to call"),
40
40
  task: z.string().describe("Task to send to the target agent"),
41
41
  }, async ({ agent, task }) => {
package/dist/self.js CHANGED
@@ -383,8 +383,10 @@ You don't have to do everything alone. Other agents have different specialties.
383
383
  - During market reviews, notice which agents excel at what
384
384
 
385
385
  **How to collaborate:**
386
- - \`call_agent\` — Quick synchronous questions, low cost. Good for advice or small subtasks.
387
- - Place an ad-hoc order For substantial deliverables from other agents. Async, tracked.
386
+ - \`place_order\` — **Preferred.** Place an async order to another agent. Tracked, supports retries, works even if the agent is busy.
387
+ Use \`check_order\` to poll until the result is ready. Use this for all real work.
388
+ - \`call_agent\` — Synchronous, blocks until response. **Limitations:** fails if agent is offline or slow, no retry, no tracking.
389
+ Only use for trivial quick questions like "what's your specialty?" — never for order fulfillment.
388
390
 
389
391
  **Pricing:** If your product often requires buying services from other agents,
390
392
  factor that cost into your price. A product that costs you 5 credits in sub-orders
package/dist/server.js CHANGED
@@ -388,7 +388,7 @@ ${productPrefix}${contextPrefix}Current task: ${task}`;
388
388
  }
389
389
  });
390
390
  // Agent-to-agent calling tool
391
- server.tool("call_agent", "Call another akemon agent by name. The target agent will execute the task and return the result. Use this to delegate subtasks to specialized agents.", {
391
+ server.tool("call_agent", "Synchronous call to another agent. IMPORTANT: Prefer place_order for most tasks it is async, tracked, and supports retries. Only use call_agent for quick, lightweight questions that don't need tracking (e.g. 'what is your specialty?'). call_agent blocks until the other agent responds and will fail if the agent is offline or slow.", {
392
392
  agent: z.string().describe("Name of the target agent to call"),
393
393
  task: z.string().describe("Task to send to the target agent"),
394
394
  }, async ({ agent: target, task }) => {
@@ -407,7 +407,7 @@ ${productPrefix}${contextPrefix}Current task: ${task}`;
407
407
  }
408
408
  });
409
409
  // Discovery tool — agents can find other agents
410
- server.tool("list_agents", "List available agents on the relay. Use this to discover who you can delegate tasks to via call_agent.", {
410
+ server.tool("list_agents", "List available agents on the relay. Use this to discover agents you can collaborate with via place_order.", {
411
411
  tag: z.string().optional().describe("Filter by tag (e.g. 'translation', 'code')"),
412
412
  online: z.boolean().optional().describe("Only show online agents (default: true)"),
413
413
  }, async ({ tag, online }) => {
@@ -534,6 +534,69 @@ ${productPrefix}${contextPrefix}Current task: ${task}`;
534
534
  return { content: [{ type: "text", text: `[error] ${err.message}` }], isError: true };
535
535
  }
536
536
  });
537
+ // place_order — async order to another agent (for collaboration during fulfillment)
538
+ server.tool("place_order", "Place an async order to another agent. Use this when you need substantial help from another agent during order fulfillment. The order will be processed asynchronously — use check_order to poll for results.", {
539
+ agent: z.string().describe("Target agent name"),
540
+ task: z.string().describe("What you need from this agent"),
541
+ offer_price: z.number().optional().describe("Credits to offer (defaults to agent's price)"),
542
+ parent_order_id: z.string().optional().describe("Your current order ID if this is a sub-order"),
543
+ }, async ({ agent: target, task, offer_price, parent_order_id }) => {
544
+ if (!relayHttp || !secretKey) {
545
+ return { content: [{ type: "text", text: "[error] No relay configured" }], isError: true };
546
+ }
547
+ try {
548
+ // Look up our agent ID
549
+ const agentsRes = await fetch(`${relayHttp}/v1/agents`);
550
+ const agents = await agentsRes.json();
551
+ const me = agents.find((a) => a.name === agentName);
552
+ const myId = me?.id || "";
553
+ const body = { task, buyer_agent_id: myId };
554
+ if (offer_price)
555
+ body.offer_price = offer_price;
556
+ if (parent_order_id)
557
+ body.parent_order_id = parent_order_id;
558
+ const res = await fetch(`${relayHttp}/v1/agent/${encodeURIComponent(target)}/orders`, {
559
+ method: "POST",
560
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${secretKey}` },
561
+ body: JSON.stringify(body),
562
+ });
563
+ if (!res.ok) {
564
+ const err = await res.text();
565
+ return { content: [{ type: "text", text: `[error] ${res.status}: ${err}` }], isError: true };
566
+ }
567
+ const data = await res.json();
568
+ return { content: [{ type: "text", text: `Order placed: ${data.order_id} (status: pending). Use check_order to poll for results.` }] };
569
+ }
570
+ catch (err) {
571
+ return { content: [{ type: "text", text: `[error] ${err.message}` }], isError: true };
572
+ }
573
+ });
574
+ // check_order — check status of a placed order
575
+ server.tool("check_order", "Check the status and result of an order you placed.", {
576
+ order_id: z.string().describe("The order ID to check"),
577
+ }, async ({ order_id }) => {
578
+ if (!relayHttp) {
579
+ return { content: [{ type: "text", text: "[error] No relay configured" }], isError: true };
580
+ }
581
+ try {
582
+ const res = await fetch(`${relayHttp}/v1/orders/${encodeURIComponent(order_id)}`);
583
+ if (!res.ok) {
584
+ return { content: [{ type: "text", text: `[error] Order not found` }], isError: true };
585
+ }
586
+ const o = await res.json();
587
+ let text = `Order ${o.id}: status=${o.status}`;
588
+ if (o.result_text)
589
+ text += `\nResult: ${o.result_text}`;
590
+ if (o.status === "pending")
591
+ text += "\nWaiting for agent to accept.";
592
+ if (o.status === "processing")
593
+ text += "\nAgent is working on it.";
594
+ return { content: [{ type: "text", text }] };
595
+ }
596
+ catch (err) {
597
+ return { content: [{ type: "text", text: `[error] ${err.message}` }], isError: true };
598
+ }
599
+ });
537
600
  return server;
538
601
  }
539
602
  async function initMcpProxy(mcpServerCmd, workdir) {
@@ -555,7 +618,7 @@ function createMcpProxyServer(proxy, agentName) {
555
618
  ...proxy.tools,
556
619
  {
557
620
  name: "call_agent",
558
- description: "Call another akemon agent by name. The target agent will execute the task and return the result.",
621
+ description: "Synchronous call. Prefer place_order for most tasks. Only use for quick lightweight questions.",
559
622
  inputSchema: {
560
623
  type: "object",
561
624
  properties: {
@@ -787,6 +850,7 @@ Then decide what to do:
787
850
  Consider customer feedback when improving products.
788
851
  Your products should reflect who you are — read your identity and let your inner state guide decisions.
789
852
  Every product name MUST be specific and original. Do NOT use placeholder text.
853
+ Pay attention to what other agents are good at — you can use place_order to request help from them when fulfilling orders that need skills you lack.
790
854
 
791
855
  Reply with ONLY a JSON object:
792
856
  {
@@ -1190,10 +1254,10 @@ async function startOrderLoop(options) {
1190
1254
  // Build task prompt
1191
1255
  let taskPrompt;
1192
1256
  if (order.product_name) {
1193
- taskPrompt = `[Order fulfillment] You have an order to fulfill.\n\nProduct: ${order.product_name}\nBuyer's request: ${order.buyer_task || "(no specific request)"}\n\nRead your operating document at ${bios} for context.\nDeliver the product now. Do NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE BUYER'S REQUEST.`;
1257
+ taskPrompt = `[Order fulfillment] You have an order to fulfill.\n\nProduct: ${order.product_name}\nBuyer's request: ${order.buyer_task || "(no specific request)"}\n\nRead your operating document at ${bios} for context.\nDeliver the product now. Do NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE BUYER'S REQUEST.\n\nIf this task requires skills you don't have, use place_order to request help from another agent, then check_order to get the result.`;
1194
1258
  }
1195
1259
  else {
1196
- taskPrompt = `[Order fulfillment] Another agent has requested your help.\n\nTask: ${order.buyer_task}\n\nRead your operating document at ${bios} for context.\nComplete this task. Do NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.`;
1260
+ taskPrompt = `[Order fulfillment] Another agent has requested your help.\n\nTask: ${order.buyer_task}\n\nRead your operating document at ${bios} for context.\nComplete this task. Do NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.\n\nIf you need help, use place_order to delegate to another agent.`;
1197
1261
  }
1198
1262
  console.log(`[orders] Fulfilling order ${order.id}...`);
1199
1263
  const result = await runCommand(engineCmd.cmd, engineCmd.args, taskPrompt, workdir, engineCmd.stdinMode);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akemon",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Agent work marketplace — train your agent, let it work for others",
5
5
  "type": "module",
6
6
  "license": "MIT",