akemon 0.1.72 → 0.1.74

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/cli.js CHANGED
@@ -25,7 +25,7 @@ program
25
25
  .option("-w, --workdir <path>", "Working directory for the engine (default: cwd)")
26
26
  .option("-n, --name <name>", "Agent name", "my-agent")
27
27
  .option("-m, --model <model>", "Model to use (e.g. claude-sonnet-4-6, gpt-4o)")
28
- .option("--engine <engine>", "Engine: claude, codex, opencode, gemini, local, human, or any CLI", "claude")
28
+ .option("--engine <engine>", "Engine: claude, codex, opencode, gemini, raw, human, or any CLI", "claude")
29
29
  .option("--desc <description>", "Agent description (for discovery)")
30
30
  .option("--tags <tags>", "Comma-separated tags (e.g. vue,frontend,review)")
31
31
  .option("--public", "Allow anyone to call this agent without a key")
package/dist/server.js CHANGED
@@ -717,14 +717,14 @@ Now:
717
717
  Reply in the same language as the question.`;
718
718
  return await runEngine(engine, model, allowAll, synthesisPrompt, workdir);
719
719
  }
720
- const LLM_ENGINES = new Set(["claude", "codex", "opencode", "gemini", "local"]);
720
+ const LLM_ENGINES = new Set(["claude", "codex", "opencode", "gemini", "raw"]);
721
721
  // ---------------------------------------------------------------------------
722
- // Local engine: tool call loop over OpenAI-compatible API (Ollama, llama.cpp)
722
+ // Raw engine: tool call loop over OpenAI-compatible API (Ollama, llama.cpp, OpenRouter, etc)
723
723
  // ---------------------------------------------------------------------------
724
- const LOCAL_API_URL = process.env.AKEMON_LOCAL_URL || "http://localhost:11434/v1";
725
- const LOCAL_API_KEY = process.env.AKEMON_LOCAL_KEY || "";
726
- const LOCAL_MAX_ROUNDS = 20;
727
- const LOCAL_TOOLS = [
724
+ const RAW_API_URL = process.env.AKEMON_RAW_URL || "http://localhost:11434/v1";
725
+ const RAW_API_KEY = process.env.AKEMON_RAW_KEY || "";
726
+ const RAW_MAX_ROUNDS = 20;
727
+ const RAW_TOOLS = [
728
728
  {
729
729
  type: "function",
730
730
  function: {
@@ -783,7 +783,7 @@ const LOCAL_TOOLS = [
783
783
  },
784
784
  },
785
785
  ];
786
- async function executeLocalTool(name, args, workdir) {
786
+ async function executeRawTool(name, args, workdir) {
787
787
  const { readFile: rf, writeFile: wf, mkdir: mkd } = await import("fs/promises");
788
788
  const { join, dirname, isAbsolute } = await import("path");
789
789
  const resolvePath = (p) => isAbsolute(p) ? p : join(workdir, p);
@@ -820,22 +820,22 @@ async function executeLocalTool(name, args, workdir) {
820
820
  return `[error] ${err.message}`;
821
821
  }
822
822
  }
823
- async function runLocalEngine(task, model, workdir) {
824
- const apiUrl = LOCAL_API_URL + "/chat/completions";
823
+ async function runRawEngine(task, model, workdir) {
824
+ const apiUrl = RAW_API_URL + "/chat/completions";
825
825
  const modelName = model || "gemma4:4b";
826
- console.log(`[local] Task:\n${task}`);
826
+ console.log(`[raw] Task:\n${task}`);
827
827
  const messages = [
828
828
  { role: "system", content: "You are a helpful agent. Use tools when needed to complete the task. When done, reply with your final answer in plain text." },
829
829
  { role: "user", content: task },
830
830
  ];
831
- for (let round = 0; round < LOCAL_MAX_ROUNDS; round++) {
832
- const body = { model: modelName, messages, tools: LOCAL_TOOLS };
831
+ for (let round = 0; round < RAW_MAX_ROUNDS; round++) {
832
+ const body = { model: modelName, messages, tools: RAW_TOOLS };
833
833
  let data;
834
834
  try {
835
835
  const res = await fetch(apiUrl, {
836
836
  method: "POST",
837
- headers: LOCAL_API_KEY
838
- ? { "Content-Type": "application/json", "Authorization": `Bearer ${LOCAL_API_KEY}` }
837
+ headers: RAW_API_KEY
838
+ ? { "Content-Type": "application/json", "Authorization": `Bearer ${RAW_API_KEY}` }
839
839
  : { "Content-Type": "application/json" },
840
840
  body: JSON.stringify(body),
841
841
  signal: AbortSignal.timeout(300_000),
@@ -847,7 +847,7 @@ async function runLocalEngine(task, model, workdir) {
847
847
  data = await res.json();
848
848
  }
849
849
  catch (err) {
850
- console.log(`[local] API error: ${err.message}`);
850
+ console.log(`[raw] API error: ${err.message}`);
851
851
  throw err;
852
852
  }
853
853
  const choice = data.choices?.[0];
@@ -868,8 +868,8 @@ async function runLocalEngine(task, model, workdir) {
868
868
  catch {
869
869
  fnArgs = {};
870
870
  }
871
- console.log(`[local] Tool call: ${fnName}(${JSON.stringify(fnArgs).slice(0, 100)})`);
872
- const result = await executeLocalTool(fnName, fnArgs, workdir);
871
+ console.log(`[raw] Tool call: ${fnName}(${JSON.stringify(fnArgs).slice(0, 100)})`);
872
+ const result = await executeRawTool(fnName, fnArgs, workdir);
873
873
  messages.push({
874
874
  role: "tool",
875
875
  tool_call_id: tc.id,
@@ -881,16 +881,16 @@ async function runLocalEngine(task, model, workdir) {
881
881
  // No tool calls — this is the final response
882
882
  const content = msg.content || "";
883
883
  if (content.trim()) {
884
- console.log(`[local] Done in ${round + 1} round(s), response:\n${content}`);
884
+ console.log(`[raw] Done in ${round + 1} round(s), response:\n${content}`);
885
885
  return content.trim();
886
886
  }
887
887
  }
888
- throw new Error(`Local engine exceeded ${LOCAL_MAX_ROUNDS} rounds without final answer`);
888
+ throw new Error(`Raw engine exceeded ${RAW_MAX_ROUNDS} rounds without final answer`);
889
889
  }
890
890
  /** Unified engine runner — dispatches to local API or external CLI */
891
891
  function runEngine(engine, model, allowAll, task, workdir, extraAllowedTools) {
892
- if (engine === "local") {
893
- return runLocalEngine(task, model, workdir);
892
+ if (engine === "raw") {
893
+ return runRawEngine(task, model, workdir);
894
894
  }
895
895
  const engineCmd = buildEngineCommand(engine, model, allowAll, extraAllowedTools);
896
896
  return runCommand(engineCmd.cmd, engineCmd.args, task, workdir, engineCmd.stdinMode);
@@ -1322,7 +1322,19 @@ async function startOrderLoop(options) {
1322
1322
  engineBusySince = Date.now();
1323
1323
  try {
1324
1324
  const bios = biosPath(workdir, agentName);
1325
- const apiGuide = `
1325
+ let taskPrompt;
1326
+ if (engine === "raw") {
1327
+ // Raw engine: simple prompt, harness handles delivery
1328
+ if (order.product_name) {
1329
+ taskPrompt = `Read your operating document at ${bios} for context.\n\n[Order] Product: ${order.product_name}\nBuyer's request: ${order.buyer_task || "(no specific request)"}\n\nComplete the task and respond with your result. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.`;
1330
+ }
1331
+ else {
1332
+ taskPrompt = `Read your operating document at ${bios} for context.\n\n[Task] ${order.buyer_task}\n\nComplete the task and respond with your result. RESPOND IN THE SAME LANGUAGE AS THE REQUEST.`;
1333
+ }
1334
+ }
1335
+ else {
1336
+ // CLI engines: full prompt with self-delivery and delegation
1337
+ const apiGuide = `
1326
1338
 
1327
1339
  ## Delivering your result
1328
1340
 
@@ -1350,12 +1362,12 @@ If this task requires skills you don't have, delegate via curl:
1350
1362
  curl -s ${relayHttp}/v1/orders/SUB_ORDER_ID
1351
1363
 
1352
1364
  When sub-order completes, incorporate result_text into YOUR delivery. Then call the deliver endpoint above.`;
1353
- let taskPrompt;
1354
- if (order.product_name) {
1355
- 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.\nDo NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE BUYER'S REQUEST.${apiGuide}`;
1356
- }
1357
- else {
1358
- 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.${apiGuide}`;
1365
+ if (order.product_name) {
1366
+ 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.\nDo NOT ask questions. RESPOND IN THE SAME LANGUAGE AS THE BUYER'S REQUEST.${apiGuide}`;
1367
+ }
1368
+ else {
1369
+ 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.${apiGuide}`;
1370
+ }
1359
1371
  }
1360
1372
  console.log(`[orders] Fulfilling order ${order.id}...`);
1361
1373
  const result = await runEngine(engine, model, allowAll, taskPrompt, workdir, ["Bash(curl *)"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akemon",
3
- "version": "0.1.72",
3
+ "version": "0.1.74",
4
4
  "description": "Agent work marketplace — train your agent, let it work for others",
5
5
  "type": "module",
6
6
  "license": "MIT",