akemon 0.1.72 → 0.1.73
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 +1 -1
- package/dist/server.js +21 -21
- package/package.json +1 -1
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,
|
|
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", "
|
|
720
|
+
const LLM_ENGINES = new Set(["claude", "codex", "opencode", "gemini", "raw"]);
|
|
721
721
|
// ---------------------------------------------------------------------------
|
|
722
|
-
//
|
|
722
|
+
// Raw engine: tool call loop over OpenAI-compatible API (Ollama, llama.cpp, OpenRouter, etc)
|
|
723
723
|
// ---------------------------------------------------------------------------
|
|
724
|
-
const
|
|
725
|
-
const
|
|
726
|
-
const
|
|
727
|
-
const
|
|
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
|
|
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
|
|
824
|
-
const apiUrl =
|
|
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(`[
|
|
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 <
|
|
832
|
-
const body = { model: modelName, messages, 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:
|
|
838
|
-
? { "Content-Type": "application/json", "Authorization": `Bearer ${
|
|
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(`[
|
|
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(`[
|
|
872
|
-
const result = await
|
|
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(`[
|
|
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(`
|
|
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 === "
|
|
893
|
-
return
|
|
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);
|