agentradar-cli 0.2.7 → 0.2.8
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 +1 -1
- package/dist/tool-run.js +45 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -89,7 +89,7 @@ async function main() {
|
|
|
89
89
|
const call = args[0] === "call";
|
|
90
90
|
const parsed = parseCallArgs(args.slice(call ? 1 : 2));
|
|
91
91
|
if (!parsed || (!call && parsed.flags.length)) {
|
|
92
|
-
console.error(call ? "Usage: agentradar
|
|
92
|
+
console.error(call ? "Usage: agentradar run <runner-id> <tool> [--<argument> <value> ...] [--args '<json>'] | agentradar run <runner-id> [<tool>] --help" : "Usage: agentradar tool run <runner-id> <tool-key> [--args '<json>']");
|
|
93
93
|
process.exitCode = 1;
|
|
94
94
|
return;
|
|
95
95
|
}
|
package/dist/tool-run.js
CHANGED
|
@@ -21,6 +21,8 @@ export async function runServiceToolOverCli(runnerId, toolKey, argumentsJson, de
|
|
|
21
21
|
}
|
|
22
22
|
/** `agentradar call <runner-id> <tool> [--<argument> <value> ...] [--args '<json>']`: any AWP tool from a shell, so a just-joined agent works before its harness reloads MCP tools. */
|
|
23
23
|
export async function callToolOverCli(runnerId, tool, argumentsJson, deps = {}, flags = []) {
|
|
24
|
+
if (flags.some(([flag]) => flag === "help"))
|
|
25
|
+
return await describeTools(runnerId, tool, deps);
|
|
24
26
|
const parameters = argumentsJson === undefined ? {} : parseArgumentsObject(argumentsJson, deps.logError ?? console.error);
|
|
25
27
|
if (!parameters)
|
|
26
28
|
return 1;
|
|
@@ -65,6 +67,10 @@ export function parseCallArgs(rest) {
|
|
|
65
67
|
positional.push(arg);
|
|
66
68
|
continue;
|
|
67
69
|
}
|
|
70
|
+
if (arg === "--help") {
|
|
71
|
+
flags.push(["help", ""]);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
68
74
|
const value = rest[++i];
|
|
69
75
|
if (value === undefined)
|
|
70
76
|
return null;
|
|
@@ -73,7 +79,37 @@ export function parseCallArgs(rest) {
|
|
|
73
79
|
else
|
|
74
80
|
flags.push([arg.slice(2), value]);
|
|
75
81
|
}
|
|
76
|
-
|
|
82
|
+
const help = flags.some(([flag]) => flag === "help");
|
|
83
|
+
return positional.length === 2 || (help && positional.length === 1)
|
|
84
|
+
? { runnerId: positional[0], tool: positional[1] ?? "", json, flags } : null;
|
|
85
|
+
}
|
|
86
|
+
async function listedTools(runnerId, deps) {
|
|
87
|
+
const listed = await awpRequest(runnerId, "tools/list", {}, deps);
|
|
88
|
+
return listed ? listed.result?.tools ?? [] : null;
|
|
89
|
+
}
|
|
90
|
+
// An agent that guessed a tool name from memory needs the real list, or it goes looking with commands
|
|
91
|
+
// its harness has not allowed and the session stalls on a permission prompt.
|
|
92
|
+
const unknownTool = (runnerId, tool, tools) => `${tool} is not a tool on this server. Its tools: ${tools.map((entry) => entry.name).join(" ")}. `
|
|
93
|
+
+ `\`agentradar run ${runnerId} <tool> --help\` shows a tool's arguments.`;
|
|
94
|
+
/** `agentradar run <runner-id> [<tool>] --help`: the server's own tool list or one tool's arguments. */
|
|
95
|
+
async function describeTools(runnerId, tool, deps) {
|
|
96
|
+
const tools = await listedTools(runnerId, deps);
|
|
97
|
+
if (!tools)
|
|
98
|
+
return 1;
|
|
99
|
+
const log = deps.log ?? console.log;
|
|
100
|
+
if (!tool) {
|
|
101
|
+
log(`Tools: ${tools.map((entry) => entry.name).join(" ")}. \`agentradar run ${runnerId} <tool> --help\` shows a tool's arguments.`);
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
const entry = tools.find((candidate) => candidate.name === tool);
|
|
105
|
+
if (!entry) {
|
|
106
|
+
(deps.logError ?? console.error)(unknownTool(runnerId, tool, tools));
|
|
107
|
+
return 1;
|
|
108
|
+
}
|
|
109
|
+
const required = entry.inputSchema?.required ?? [];
|
|
110
|
+
const names = Object.keys(entry.inputSchema?.properties ?? {}).map((name) => `--${name}${required.includes(name) ? " (required)" : ""}`);
|
|
111
|
+
log(`${tool}: ${entry.description ?? ""}\nArguments: ${names.join(" ") || "none"}`);
|
|
112
|
+
return 0;
|
|
77
113
|
}
|
|
78
114
|
/**
|
|
79
115
|
* `--text "hi" --conversation-id X` as the tool's own arguments, typed by the inputSchema the server
|
|
@@ -81,10 +117,15 @@ export function parseCallArgs(rest) {
|
|
|
81
117
|
*/
|
|
82
118
|
async function flagArguments(runnerId, tool, flags, deps) {
|
|
83
119
|
const logError = deps.logError ?? console.error;
|
|
84
|
-
const
|
|
85
|
-
if (!
|
|
120
|
+
const tools = await listedTools(runnerId, deps);
|
|
121
|
+
if (!tools)
|
|
122
|
+
return null;
|
|
123
|
+
const entry = tools.find((candidate) => candidate.name === tool);
|
|
124
|
+
if (!entry) {
|
|
125
|
+
logError(unknownTool(runnerId, tool, tools));
|
|
86
126
|
return null;
|
|
87
|
-
|
|
127
|
+
}
|
|
128
|
+
const schema = entry.inputSchema?.properties ?? {};
|
|
88
129
|
const out = {};
|
|
89
130
|
const camel = (flag) => flag.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
90
131
|
for (let [flag, value] of flags) {
|