@gaberrb/polypus 0.4.3 → 0.4.4
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 +85 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -109,6 +109,7 @@ var en = {
|
|
|
109
109
|
"cli.opt.agent": "which configured agent to use",
|
|
110
110
|
"cli.opt.mode": "plan | review | bypass (overrides config)",
|
|
111
111
|
"cli.opt.maxSteps": "maximum agent steps",
|
|
112
|
+
"cli.opt.json": "headless mode: emit a single JSON object (steps, tool calls, files changed, usage) instead of the TUI \u2014 use with --mode bypass",
|
|
112
113
|
"cli.arg.swarmTask": "high-level task to split across agents",
|
|
113
114
|
"cli.opt.agents": "comma-separated agent names (default: all configured)",
|
|
114
115
|
"cli.opt.maxSubtasks": "maximum number of parallel subtasks",
|
|
@@ -135,6 +136,7 @@ var en = {
|
|
|
135
136
|
"run.reprompt": "\u21BB no tool call \u2014 reinforcing instructions (attempt {attempt})",
|
|
136
137
|
"run.autocorrect": "\u21BB tool failed \u2014 auto-correcting with extra context",
|
|
137
138
|
"run.cancelled": "\u25A0 cancelled",
|
|
139
|
+
"run.jsonNeedsTask": "--json requires a task argument (headless mode has no interactive REPL).",
|
|
138
140
|
// repl
|
|
139
141
|
"repl.welcome": "Polypus interactive session.",
|
|
140
142
|
"repl.welcomeHint": " Type /help for commands, /exit to quit.",
|
|
@@ -334,6 +336,7 @@ var ptBR = {
|
|
|
334
336
|
"cli.opt.agent": "qual agente configurado usar",
|
|
335
337
|
"cli.opt.mode": "plan | review | bypass (sobrescreve a config)",
|
|
336
338
|
"cli.opt.maxSteps": "n\xFAmero m\xE1ximo de passos do agente",
|
|
339
|
+
"cli.opt.json": "modo headless: emite um \xFAnico objeto JSON (passos, tool calls, arquivos alterados, uso) em vez da TUI \u2014 use com --mode bypass",
|
|
337
340
|
"cli.arg.swarmTask": "tarefa de alto n\xEDvel para dividir entre os agentes",
|
|
338
341
|
"cli.opt.agents": "nomes de agentes separados por v\xEDrgula (padr\xE3o: todos)",
|
|
339
342
|
"cli.opt.maxSubtasks": "n\xFAmero m\xE1ximo de subtarefas paralelas",
|
|
@@ -358,6 +361,7 @@ var ptBR = {
|
|
|
358
361
|
"run.reprompt": "\u21BB nenhuma chamada de tool \u2014 refor\xE7ando instru\xE7\xF5es (tentativa {attempt})",
|
|
359
362
|
"run.autocorrect": "\u21BB tool falhou \u2014 autocorrigindo com contexto extra",
|
|
360
363
|
"run.cancelled": "\u25A0 cancelado",
|
|
364
|
+
"run.jsonNeedsTask": "--json exige um argumento de tarefa (o modo headless n\xE3o tem REPL interativo).",
|
|
361
365
|
"repl.welcome": "Sess\xE3o interativa do Polypus.",
|
|
362
366
|
"repl.welcomeHint": " Digite /help para comandos, /exit para sair.",
|
|
363
367
|
"repl.modeChanged": "modo \u2192 {mode}",
|
|
@@ -2032,6 +2036,60 @@ ${blocks.join("\n\n")}`;
|
|
|
2032
2036
|
return { task: augmented, injected };
|
|
2033
2037
|
}
|
|
2034
2038
|
|
|
2039
|
+
// src/cli/commands/json-output.ts
|
|
2040
|
+
var OUTPUT_PREVIEW = 500;
|
|
2041
|
+
function createJsonCollector() {
|
|
2042
|
+
const log = [];
|
|
2043
|
+
const filesChanged = /* @__PURE__ */ new Set();
|
|
2044
|
+
const events = {
|
|
2045
|
+
onStep(step) {
|
|
2046
|
+
log.push({ type: "step", step });
|
|
2047
|
+
},
|
|
2048
|
+
onAssistantText(text2) {
|
|
2049
|
+
if (text2.trim()) log.push({ type: "assistant", text: text2 });
|
|
2050
|
+
},
|
|
2051
|
+
onToolCall(call) {
|
|
2052
|
+
log.push({ type: "tool_call", name: call.name, arguments: call.arguments });
|
|
2053
|
+
},
|
|
2054
|
+
onToolResult(call, result) {
|
|
2055
|
+
log.push({
|
|
2056
|
+
type: "tool_result",
|
|
2057
|
+
name: call.name,
|
|
2058
|
+
ok: result.ok,
|
|
2059
|
+
output: result.output.slice(0, OUTPUT_PREVIEW)
|
|
2060
|
+
});
|
|
2061
|
+
if (result.ok && (call.name === "write_file" || call.name === "edit_file")) {
|
|
2062
|
+
const path = call.arguments.path;
|
|
2063
|
+
if (typeof path === "string") filesChanged.add(path);
|
|
2064
|
+
}
|
|
2065
|
+
},
|
|
2066
|
+
onCorrection(call) {
|
|
2067
|
+
log.push({ type: "correction", name: call.name });
|
|
2068
|
+
},
|
|
2069
|
+
onReprompt(attempt) {
|
|
2070
|
+
log.push({ type: "reprompt", attempt });
|
|
2071
|
+
},
|
|
2072
|
+
onUsage() {
|
|
2073
|
+
}
|
|
2074
|
+
};
|
|
2075
|
+
return {
|
|
2076
|
+
events,
|
|
2077
|
+
build(result) {
|
|
2078
|
+
return {
|
|
2079
|
+
result: {
|
|
2080
|
+
reason: result.reason,
|
|
2081
|
+
finished: result.finished,
|
|
2082
|
+
steps: result.steps,
|
|
2083
|
+
summary: result.summary,
|
|
2084
|
+
filesChanged: [...filesChanged],
|
|
2085
|
+
usage: result.usage
|
|
2086
|
+
},
|
|
2087
|
+
events: log
|
|
2088
|
+
};
|
|
2089
|
+
}
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2035
2093
|
// src/ui/repl.ts
|
|
2036
2094
|
import pc6 from "picocolors";
|
|
2037
2095
|
|
|
@@ -3285,20 +3343,23 @@ async function run(task, opts) {
|
|
|
3285
3343
|
const resolved2 = createProvider(active);
|
|
3286
3344
|
await executeTask(taskText, resolved2, workspace, session);
|
|
3287
3345
|
};
|
|
3346
|
+
if (opts.json && !task) throw new Error(t("run.jsonNeedsTask"));
|
|
3288
3347
|
if (task) {
|
|
3289
3348
|
const resolved2 = createProvider(agentConfig);
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3349
|
+
if (!opts.json) {
|
|
3350
|
+
console.log(
|
|
3351
|
+
pc8.dim(
|
|
3352
|
+
t("run.status", {
|
|
3353
|
+
name: resolved2.config.name,
|
|
3354
|
+
provider: resolved2.config.provider,
|
|
3355
|
+
model: resolved2.config.model,
|
|
3356
|
+
toolMode: resolved2.toolMode,
|
|
3357
|
+
mode: session.mode
|
|
3358
|
+
})
|
|
3359
|
+
)
|
|
3360
|
+
);
|
|
3361
|
+
}
|
|
3362
|
+
await executeTask(task, resolved2, workspace, session, opts.json ?? false);
|
|
3302
3363
|
return;
|
|
3303
3364
|
}
|
|
3304
3365
|
const resolved = createProvider(agentConfig);
|
|
@@ -3321,7 +3382,7 @@ async function run(task, opts) {
|
|
|
3321
3382
|
};
|
|
3322
3383
|
await startRepl(ctx);
|
|
3323
3384
|
}
|
|
3324
|
-
async function executeTask(task, resolved, workspace, session) {
|
|
3385
|
+
async function executeTask(task, resolved, workspace, session, json = false) {
|
|
3325
3386
|
const mention = await resolveMentions(task, {
|
|
3326
3387
|
workspace,
|
|
3327
3388
|
allow: session.allow,
|
|
@@ -3329,16 +3390,18 @@ async function executeTask(task, resolved, workspace, session) {
|
|
|
3329
3390
|
});
|
|
3330
3391
|
if (mention.injected.length > 0) {
|
|
3331
3392
|
task = mention.task;
|
|
3332
|
-
console.log(pc8.dim(`\u21B3 @ ${mention.injected.join(", ")}`));
|
|
3393
|
+
if (!json) console.log(pc8.dim(`\u21B3 @ ${mention.injected.join(", ")}`));
|
|
3333
3394
|
}
|
|
3334
3395
|
const spinner3 = new Spinner();
|
|
3335
3396
|
const controller = new AbortController();
|
|
3336
3397
|
const cancel2 = listenForCancel(controller);
|
|
3398
|
+
const collector = json ? createJsonCollector() : void 0;
|
|
3337
3399
|
const permissions = new PermissionEngine({
|
|
3338
3400
|
mode: session.mode,
|
|
3339
3401
|
policy: { workspace, allow: session.allow, deny: session.deny },
|
|
3340
3402
|
allowedCommands: session.allowedCommands,
|
|
3341
|
-
|
|
3403
|
+
// Headless runs have no TTY for confirmations — use --mode bypass instead.
|
|
3404
|
+
confirm: json ? async () => false : async (req) => {
|
|
3342
3405
|
spinner3.stop();
|
|
3343
3406
|
cancel2.pause();
|
|
3344
3407
|
const ok = await confirmAction(req);
|
|
@@ -3346,7 +3409,7 @@ async function executeTask(task, resolved, workspace, session) {
|
|
|
3346
3409
|
return ok;
|
|
3347
3410
|
}
|
|
3348
3411
|
});
|
|
3349
|
-
spinner3.start(t("ui.thinking"));
|
|
3412
|
+
if (!json) spinner3.start(t("ui.thinking"));
|
|
3350
3413
|
let result;
|
|
3351
3414
|
try {
|
|
3352
3415
|
result = await runAgent({
|
|
@@ -3358,13 +3421,17 @@ async function executeTask(task, resolved, workspace, session) {
|
|
|
3358
3421
|
history: session.history,
|
|
3359
3422
|
maxSteps: session.maxSteps,
|
|
3360
3423
|
signal: controller.signal,
|
|
3361
|
-
events: renderEvents(spinner3)
|
|
3424
|
+
events: collector ? collector.events : renderEvents(spinner3)
|
|
3362
3425
|
});
|
|
3363
3426
|
} finally {
|
|
3364
3427
|
spinner3.stop();
|
|
3365
3428
|
cancel2.dispose();
|
|
3366
3429
|
}
|
|
3367
3430
|
session.history = result.messages;
|
|
3431
|
+
if (collector) {
|
|
3432
|
+
process.stdout.write(JSON.stringify(collector.build(result)) + "\n");
|
|
3433
|
+
return;
|
|
3434
|
+
}
|
|
3368
3435
|
if (result.reason === "finished") {
|
|
3369
3436
|
console.log(pc8.green("\n" + t("run.done", { steps: result.steps })) + (result.summary ? ` ${result.summary}` : ""));
|
|
3370
3437
|
} else if (result.reason === "cancelled") {
|
|
@@ -4115,7 +4182,7 @@ function buildProgram() {
|
|
|
4115
4182
|
program.command("add-agent").argument("<name>", t("cli.arg.addAgentName")).requiredOption("--provider <provider>", t("cli.opt.provider")).requiredOption("--model <model>", t("cli.opt.model")).option("--api-key <key>", t("cli.opt.apiKey")).option("--base-url <url>", t("cli.opt.baseUrl")).option("--tool-mode <mode>", t("cli.opt.toolMode"), "auto").option("--set-default", t("cli.opt.setDefault")).description(t("cli.cmd.addAgent")).action((name, opts) => addAgent(name, opts));
|
|
4116
4183
|
program.command("remove-agent").argument("<name>", t("cli.arg.removeAgentName")).description(t("cli.cmd.removeAgent")).action((name) => removeAgent(name));
|
|
4117
4184
|
program.command("list-agents").alias("agents").description(t("cli.cmd.listAgents")).action(() => listAgents());
|
|
4118
|
-
program.command("run").argument("[task]", t("cli.arg.runTask")).option("--agent <name>", t("cli.opt.agent")).option("--mode <mode>", t("cli.opt.mode")).option("--max-steps <n>", t("cli.opt.maxSteps")).description(t("cli.cmd.run")).action((task, opts) => run(task, opts));
|
|
4185
|
+
program.command("run").argument("[task]", t("cli.arg.runTask")).option("--agent <name>", t("cli.opt.agent")).option("--mode <mode>", t("cli.opt.mode")).option("--max-steps <n>", t("cli.opt.maxSteps")).option("--json", t("cli.opt.json")).description(t("cli.cmd.run")).action((task, opts) => run(task, opts));
|
|
4119
4186
|
program.command("swarm").argument("<task>", t("cli.arg.swarmTask")).option("--agents <names>", t("cli.opt.agents")).option("--max-subtasks <n>", t("cli.opt.maxSubtasks")).description(t("cli.cmd.swarm")).action((task, opts) => swarm(task, opts));
|
|
4120
4187
|
program.command("models").option("--search <text>", t("cli.opt.search")).option("--tools", t("cli.opt.toolsOnly")).option("--free", t("cli.opt.free")).option("--max-price <usd>", t("cli.opt.maxPrice")).option("--sort <order>", t("cli.opt.sort")).option("--limit <n>", t("cli.opt.limit")).description(t("cli.cmd.models")).action((opts) => models(opts));
|
|
4121
4188
|
program.command("prd").argument("<issue>", t("cli.arg.prdIssue")).option("--out <file>", t("cli.opt.out")).option("--model <model>", t("cli.opt.model")).option("--input <file>", t("cli.opt.input")).description(t("cli.cmd.prd")).action((issue, opts) => prd(issue, opts));
|