@robota-sdk/agent-cli 3.0.0-beta.25 → 3.0.0-beta.26
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/node/bin.cjs +76 -20
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-GJ3LG37H.js → chunk-QTZS5QXJ.js} +76 -20
- package/dist/node/index.cjs +76 -20
- package/dist/node/index.js +1 -1
- package/package.json +3 -3
package/dist/node/bin.cjs
CHANGED
|
@@ -174,7 +174,7 @@ var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
|
174
174
|
var import_react = require("react");
|
|
175
175
|
var import_agent_sdk = require("@robota-sdk/agent-sdk");
|
|
176
176
|
var TOOL_ARG_DISPLAY_MAX = 80;
|
|
177
|
-
var
|
|
177
|
+
var TAIL_KEEP = 30;
|
|
178
178
|
var NOOP_TERMINAL = {
|
|
179
179
|
write: () => {
|
|
180
180
|
},
|
|
@@ -233,13 +233,17 @@ function useSession(props) {
|
|
|
233
233
|
if (event.toolArgs) {
|
|
234
234
|
const firstVal = Object.values(event.toolArgs)[0];
|
|
235
235
|
const raw = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal ?? "");
|
|
236
|
-
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0,
|
|
236
|
+
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0, TOOL_ARG_DISPLAY_MAX - TAIL_KEEP - 3) + "..." + raw.slice(-TAIL_KEEP) : raw;
|
|
237
237
|
}
|
|
238
|
-
setActiveTools((prev) => [
|
|
238
|
+
setActiveTools((prev) => [
|
|
239
|
+
...prev,
|
|
240
|
+
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
241
|
+
]);
|
|
239
242
|
} else {
|
|
243
|
+
const result = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
240
244
|
setActiveTools(
|
|
241
245
|
(prev) => prev.map(
|
|
242
|
-
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false } : t
|
|
246
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result } : t
|
|
243
247
|
)
|
|
244
248
|
);
|
|
245
249
|
}
|
|
@@ -263,7 +267,13 @@ function useSession(props) {
|
|
|
263
267
|
setStreamingText("");
|
|
264
268
|
setActiveTools([]);
|
|
265
269
|
}, []);
|
|
266
|
-
return {
|
|
270
|
+
return {
|
|
271
|
+
session: sessionRef.current,
|
|
272
|
+
permissionRequest,
|
|
273
|
+
streamingText,
|
|
274
|
+
clearStreamingText,
|
|
275
|
+
activeTools
|
|
276
|
+
};
|
|
267
277
|
}
|
|
268
278
|
|
|
269
279
|
// src/ui/hooks/useMessages.ts
|
|
@@ -594,7 +604,7 @@ var import_react4 = require("react");
|
|
|
594
604
|
|
|
595
605
|
// src/utils/tool-call-extractor.ts
|
|
596
606
|
var TOOL_ARG_MAX_LENGTH = 80;
|
|
597
|
-
var
|
|
607
|
+
var TAIL_KEEP2 = 30;
|
|
598
608
|
function extractToolCalls(history, startIndex) {
|
|
599
609
|
const lines = [];
|
|
600
610
|
for (let i = startIndex; i < history.length; i++) {
|
|
@@ -602,7 +612,7 @@ function extractToolCalls(history, startIndex) {
|
|
|
602
612
|
if (msg.role === "assistant" && msg.toolCalls) {
|
|
603
613
|
for (const tc of msg.toolCalls) {
|
|
604
614
|
const value = parseFirstArgValue(tc.function.arguments);
|
|
605
|
-
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0,
|
|
615
|
+
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_MAX_LENGTH - TAIL_KEEP2 - 3) + "..." + value.slice(-TAIL_KEEP2) : value;
|
|
606
616
|
lines.push(`${tc.function.name}(${truncated})`);
|
|
607
617
|
}
|
|
608
618
|
}
|
|
@@ -730,6 +740,9 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
|
|
|
730
740
|
}
|
|
731
741
|
const prompt = await buildSkillPrompt(input, registry);
|
|
732
742
|
if (!prompt) return;
|
|
743
|
+
const cmdName = input.slice(1).split(/\s+/)[0]?.toLowerCase() ?? "";
|
|
744
|
+
const qualifiedName = registry.resolveQualifiedName(cmdName);
|
|
745
|
+
const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmdName.length)}` : input;
|
|
733
746
|
return runSessionPrompt(
|
|
734
747
|
prompt,
|
|
735
748
|
session,
|
|
@@ -737,7 +750,7 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
|
|
|
737
750
|
clearStreamingText,
|
|
738
751
|
setIsThinking,
|
|
739
752
|
setContextState,
|
|
740
|
-
|
|
753
|
+
hookInput
|
|
741
754
|
);
|
|
742
755
|
}
|
|
743
756
|
addMessage({ role: "user", content: input });
|
|
@@ -784,6 +797,14 @@ var CommandRegistry = class {
|
|
|
784
797
|
const lower = filter.toLowerCase();
|
|
785
798
|
return all.filter((cmd) => cmd.name.toLowerCase().startsWith(lower));
|
|
786
799
|
}
|
|
800
|
+
/** Resolve a short name to its fully qualified plugin:name form */
|
|
801
|
+
resolveQualifiedName(shortName) {
|
|
802
|
+
const matches = this.getCommands().filter(
|
|
803
|
+
(c) => c.source === "plugin" && c.name.includes(":") && c.name.endsWith(`:${shortName}`)
|
|
804
|
+
);
|
|
805
|
+
if (matches.length !== 1) return null;
|
|
806
|
+
return matches[0].name;
|
|
807
|
+
}
|
|
787
808
|
/** Get subcommands for a specific command */
|
|
788
809
|
getSubcommands(commandName) {
|
|
789
810
|
const lower = commandName.toLowerCase();
|
|
@@ -1017,7 +1038,7 @@ var PluginCommandSource = class {
|
|
|
1017
1038
|
const baseName = skill.name.includes("@") ? skill.name.split("@")[0] : skill.name;
|
|
1018
1039
|
commands.push({
|
|
1019
1040
|
name: baseName,
|
|
1020
|
-
description:
|
|
1041
|
+
description: `(${plugin.manifest.name}) ${skill.description}`,
|
|
1021
1042
|
source: "plugin",
|
|
1022
1043
|
skillContent: skill.skillContent,
|
|
1023
1044
|
pluginDir: plugin.pluginDir
|
|
@@ -1217,13 +1238,39 @@ function RoleLabel({ role }) {
|
|
|
1217
1238
|
" "
|
|
1218
1239
|
] });
|
|
1219
1240
|
case "tool":
|
|
1220
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "
|
|
1241
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "white", bold: true, children: [
|
|
1221
1242
|
"Tool:",
|
|
1222
1243
|
" "
|
|
1223
1244
|
] });
|
|
1224
1245
|
}
|
|
1225
1246
|
}
|
|
1247
|
+
function ToolMessage({ message }) {
|
|
1248
|
+
const lines = message.content.split("\n").filter((l) => l.trim());
|
|
1249
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1250
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { children: [
|
|
1251
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "white", bold: true, children: [
|
|
1252
|
+
"Tool:",
|
|
1253
|
+
" "
|
|
1254
|
+
] }),
|
|
1255
|
+
message.toolName && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "white", dimColor: true, children: [
|
|
1256
|
+
"[",
|
|
1257
|
+
message.toolName,
|
|
1258
|
+
"]"
|
|
1259
|
+
] })
|
|
1260
|
+
] }),
|
|
1261
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }),
|
|
1262
|
+
lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "green", children: [
|
|
1263
|
+
" ",
|
|
1264
|
+
"\u2713",
|
|
1265
|
+
" ",
|
|
1266
|
+
line
|
|
1267
|
+
] }, i))
|
|
1268
|
+
] });
|
|
1269
|
+
}
|
|
1226
1270
|
function MessageItem({ message }) {
|
|
1271
|
+
if (message.role === "tool") {
|
|
1272
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolMessage, { message });
|
|
1273
|
+
}
|
|
1227
1274
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1228
1275
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { children: [
|
|
1229
1276
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleLabel, { role: message.role }),
|
|
@@ -1715,6 +1762,12 @@ function PermissionPrompt({ request }) {
|
|
|
1715
1762
|
// src/ui/StreamingIndicator.tsx
|
|
1716
1763
|
var import_ink9 = require("ink");
|
|
1717
1764
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1765
|
+
function getToolStyle(t) {
|
|
1766
|
+
if (t.isRunning) return { color: "yellow", icon: "\u27F3", strikethrough: false };
|
|
1767
|
+
if (t.result === "error") return { color: "red", icon: "\u2717", strikethrough: true };
|
|
1768
|
+
if (t.result === "denied") return { color: "yellowBright", icon: "\u2298", strikethrough: true };
|
|
1769
|
+
return { color: "green", icon: "\u2713", strikethrough: false };
|
|
1770
|
+
}
|
|
1718
1771
|
function StreamingIndicator({ text, activeTools }) {
|
|
1719
1772
|
const hasTools = activeTools.length > 0;
|
|
1720
1773
|
const hasText = text.length > 0;
|
|
@@ -1723,17 +1776,20 @@ function StreamingIndicator({ text, activeTools }) {
|
|
|
1723
1776
|
}
|
|
1724
1777
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", children: [
|
|
1725
1778
|
hasTools && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1726
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "
|
|
1779
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "white", bold: true, children: "Tools:" }),
|
|
1727
1780
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { children: " " }),
|
|
1728
|
-
activeTools.map((t, i) =>
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1781
|
+
activeTools.map((t, i) => {
|
|
1782
|
+
const { color, icon, strikethrough } = getToolStyle(t);
|
|
1783
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Text, { color, strikethrough, children: [
|
|
1784
|
+
" ",
|
|
1785
|
+
icon,
|
|
1786
|
+
" ",
|
|
1787
|
+
t.toolName,
|
|
1788
|
+
"(",
|
|
1789
|
+
t.firstArg,
|
|
1790
|
+
")"
|
|
1791
|
+
] }, `${t.toolName}-${i}`);
|
|
1792
|
+
})
|
|
1737
1793
|
] }),
|
|
1738
1794
|
hasText && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1739
1795
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "cyan", bold: true, children: "Robota:" }),
|
package/dist/node/bin.js
CHANGED
|
@@ -157,7 +157,7 @@ import { getModelName } from "@robota-sdk/agent-core";
|
|
|
157
157
|
import { useState, useCallback, useRef } from "react";
|
|
158
158
|
import { createSession, FileSessionLogger, projectPaths } from "@robota-sdk/agent-sdk";
|
|
159
159
|
var TOOL_ARG_DISPLAY_MAX = 80;
|
|
160
|
-
var
|
|
160
|
+
var TAIL_KEEP = 30;
|
|
161
161
|
var NOOP_TERMINAL = {
|
|
162
162
|
write: () => {
|
|
163
163
|
},
|
|
@@ -216,13 +216,17 @@ function useSession(props) {
|
|
|
216
216
|
if (event.toolArgs) {
|
|
217
217
|
const firstVal = Object.values(event.toolArgs)[0];
|
|
218
218
|
const raw = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal ?? "");
|
|
219
|
-
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0,
|
|
219
|
+
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0, TOOL_ARG_DISPLAY_MAX - TAIL_KEEP - 3) + "..." + raw.slice(-TAIL_KEEP) : raw;
|
|
220
220
|
}
|
|
221
|
-
setActiveTools((prev) => [
|
|
221
|
+
setActiveTools((prev) => [
|
|
222
|
+
...prev,
|
|
223
|
+
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
224
|
+
]);
|
|
222
225
|
} else {
|
|
226
|
+
const result = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
223
227
|
setActiveTools(
|
|
224
228
|
(prev) => prev.map(
|
|
225
|
-
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false } : t
|
|
229
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result } : t
|
|
226
230
|
)
|
|
227
231
|
);
|
|
228
232
|
}
|
|
@@ -246,7 +250,13 @@ function useSession(props) {
|
|
|
246
250
|
setStreamingText("");
|
|
247
251
|
setActiveTools([]);
|
|
248
252
|
}, []);
|
|
249
|
-
return {
|
|
253
|
+
return {
|
|
254
|
+
session: sessionRef.current,
|
|
255
|
+
permissionRequest,
|
|
256
|
+
streamingText,
|
|
257
|
+
clearStreamingText,
|
|
258
|
+
activeTools
|
|
259
|
+
};
|
|
250
260
|
}
|
|
251
261
|
|
|
252
262
|
// src/ui/hooks/useMessages.ts
|
|
@@ -577,7 +587,7 @@ import { useCallback as useCallback4 } from "react";
|
|
|
577
587
|
|
|
578
588
|
// src/utils/tool-call-extractor.ts
|
|
579
589
|
var TOOL_ARG_MAX_LENGTH = 80;
|
|
580
|
-
var
|
|
590
|
+
var TAIL_KEEP2 = 30;
|
|
581
591
|
function extractToolCalls(history, startIndex) {
|
|
582
592
|
const lines = [];
|
|
583
593
|
for (let i = startIndex; i < history.length; i++) {
|
|
@@ -585,7 +595,7 @@ function extractToolCalls(history, startIndex) {
|
|
|
585
595
|
if (msg.role === "assistant" && msg.toolCalls) {
|
|
586
596
|
for (const tc of msg.toolCalls) {
|
|
587
597
|
const value = parseFirstArgValue(tc.function.arguments);
|
|
588
|
-
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0,
|
|
598
|
+
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_MAX_LENGTH - TAIL_KEEP2 - 3) + "..." + value.slice(-TAIL_KEEP2) : value;
|
|
589
599
|
lines.push(`${tc.function.name}(${truncated})`);
|
|
590
600
|
}
|
|
591
601
|
}
|
|
@@ -713,6 +723,9 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
|
|
|
713
723
|
}
|
|
714
724
|
const prompt = await buildSkillPrompt(input, registry);
|
|
715
725
|
if (!prompt) return;
|
|
726
|
+
const cmdName = input.slice(1).split(/\s+/)[0]?.toLowerCase() ?? "";
|
|
727
|
+
const qualifiedName = registry.resolveQualifiedName(cmdName);
|
|
728
|
+
const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmdName.length)}` : input;
|
|
716
729
|
return runSessionPrompt(
|
|
717
730
|
prompt,
|
|
718
731
|
session,
|
|
@@ -720,7 +733,7 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
|
|
|
720
733
|
clearStreamingText,
|
|
721
734
|
setIsThinking,
|
|
722
735
|
setContextState,
|
|
723
|
-
|
|
736
|
+
hookInput
|
|
724
737
|
);
|
|
725
738
|
}
|
|
726
739
|
addMessage({ role: "user", content: input });
|
|
@@ -767,6 +780,14 @@ var CommandRegistry = class {
|
|
|
767
780
|
const lower = filter.toLowerCase();
|
|
768
781
|
return all.filter((cmd) => cmd.name.toLowerCase().startsWith(lower));
|
|
769
782
|
}
|
|
783
|
+
/** Resolve a short name to its fully qualified plugin:name form */
|
|
784
|
+
resolveQualifiedName(shortName) {
|
|
785
|
+
const matches = this.getCommands().filter(
|
|
786
|
+
(c) => c.source === "plugin" && c.name.includes(":") && c.name.endsWith(`:${shortName}`)
|
|
787
|
+
);
|
|
788
|
+
if (matches.length !== 1) return null;
|
|
789
|
+
return matches[0].name;
|
|
790
|
+
}
|
|
770
791
|
/** Get subcommands for a specific command */
|
|
771
792
|
getSubcommands(commandName) {
|
|
772
793
|
const lower = commandName.toLowerCase();
|
|
@@ -1000,7 +1021,7 @@ var PluginCommandSource = class {
|
|
|
1000
1021
|
const baseName = skill.name.includes("@") ? skill.name.split("@")[0] : skill.name;
|
|
1001
1022
|
commands.push({
|
|
1002
1023
|
name: baseName,
|
|
1003
|
-
description:
|
|
1024
|
+
description: `(${plugin.manifest.name}) ${skill.description}`,
|
|
1004
1025
|
source: "plugin",
|
|
1005
1026
|
skillContent: skill.skillContent,
|
|
1006
1027
|
pluginDir: plugin.pluginDir
|
|
@@ -1205,13 +1226,39 @@ function RoleLabel({ role }) {
|
|
|
1205
1226
|
" "
|
|
1206
1227
|
] });
|
|
1207
1228
|
case "tool":
|
|
1208
|
-
return /* @__PURE__ */ jsxs(Text, { color: "
|
|
1229
|
+
return /* @__PURE__ */ jsxs(Text, { color: "white", bold: true, children: [
|
|
1209
1230
|
"Tool:",
|
|
1210
1231
|
" "
|
|
1211
1232
|
] });
|
|
1212
1233
|
}
|
|
1213
1234
|
}
|
|
1235
|
+
function ToolMessage({ message }) {
|
|
1236
|
+
const lines = message.content.split("\n").filter((l) => l.trim());
|
|
1237
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1238
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1239
|
+
/* @__PURE__ */ jsxs(Text, { color: "white", bold: true, children: [
|
|
1240
|
+
"Tool:",
|
|
1241
|
+
" "
|
|
1242
|
+
] }),
|
|
1243
|
+
message.toolName && /* @__PURE__ */ jsxs(Text, { color: "white", dimColor: true, children: [
|
|
1244
|
+
"[",
|
|
1245
|
+
message.toolName,
|
|
1246
|
+
"]"
|
|
1247
|
+
] })
|
|
1248
|
+
] }),
|
|
1249
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1250
|
+
lines.map((line, i) => /* @__PURE__ */ jsxs(Text, { color: "green", children: [
|
|
1251
|
+
" ",
|
|
1252
|
+
"\u2713",
|
|
1253
|
+
" ",
|
|
1254
|
+
line
|
|
1255
|
+
] }, i))
|
|
1256
|
+
] });
|
|
1257
|
+
}
|
|
1214
1258
|
function MessageItem({ message }) {
|
|
1259
|
+
if (message.role === "tool") {
|
|
1260
|
+
return /* @__PURE__ */ jsx(ToolMessage, { message });
|
|
1261
|
+
}
|
|
1215
1262
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1216
1263
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
1217
1264
|
/* @__PURE__ */ jsx(RoleLabel, { role: message.role }),
|
|
@@ -1703,6 +1750,12 @@ function PermissionPrompt({ request }) {
|
|
|
1703
1750
|
// src/ui/StreamingIndicator.tsx
|
|
1704
1751
|
import { Box as Box7, Text as Text9 } from "ink";
|
|
1705
1752
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1753
|
+
function getToolStyle(t) {
|
|
1754
|
+
if (t.isRunning) return { color: "yellow", icon: "\u27F3", strikethrough: false };
|
|
1755
|
+
if (t.result === "error") return { color: "red", icon: "\u2717", strikethrough: true };
|
|
1756
|
+
if (t.result === "denied") return { color: "yellowBright", icon: "\u2298", strikethrough: true };
|
|
1757
|
+
return { color: "green", icon: "\u2713", strikethrough: false };
|
|
1758
|
+
}
|
|
1706
1759
|
function StreamingIndicator({ text, activeTools }) {
|
|
1707
1760
|
const hasTools = activeTools.length > 0;
|
|
1708
1761
|
const hasText = text.length > 0;
|
|
@@ -1711,17 +1764,20 @@ function StreamingIndicator({ text, activeTools }) {
|
|
|
1711
1764
|
}
|
|
1712
1765
|
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
1713
1766
|
hasTools && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginBottom: 1, children: [
|
|
1714
|
-
/* @__PURE__ */ jsx9(Text9, { color: "
|
|
1767
|
+
/* @__PURE__ */ jsx9(Text9, { color: "white", bold: true, children: "Tools:" }),
|
|
1715
1768
|
/* @__PURE__ */ jsx9(Text9, { children: " " }),
|
|
1716
|
-
activeTools.map((t, i) =>
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1769
|
+
activeTools.map((t, i) => {
|
|
1770
|
+
const { color, icon, strikethrough } = getToolStyle(t);
|
|
1771
|
+
return /* @__PURE__ */ jsxs7(Text9, { color, strikethrough, children: [
|
|
1772
|
+
" ",
|
|
1773
|
+
icon,
|
|
1774
|
+
" ",
|
|
1775
|
+
t.toolName,
|
|
1776
|
+
"(",
|
|
1777
|
+
t.firstArg,
|
|
1778
|
+
")"
|
|
1779
|
+
] }, `${t.toolName}-${i}`);
|
|
1780
|
+
})
|
|
1725
1781
|
] }),
|
|
1726
1782
|
hasText && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", marginBottom: 1, children: [
|
|
1727
1783
|
/* @__PURE__ */ jsx9(Text9, { color: "cyan", bold: true, children: "Robota:" }),
|
package/dist/node/index.cjs
CHANGED
|
@@ -190,7 +190,7 @@ var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
|
190
190
|
var import_react = require("react");
|
|
191
191
|
var import_agent_sdk = require("@robota-sdk/agent-sdk");
|
|
192
192
|
var TOOL_ARG_DISPLAY_MAX = 80;
|
|
193
|
-
var
|
|
193
|
+
var TAIL_KEEP = 30;
|
|
194
194
|
var NOOP_TERMINAL = {
|
|
195
195
|
write: () => {
|
|
196
196
|
},
|
|
@@ -249,13 +249,17 @@ function useSession(props) {
|
|
|
249
249
|
if (event.toolArgs) {
|
|
250
250
|
const firstVal = Object.values(event.toolArgs)[0];
|
|
251
251
|
const raw = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal ?? "");
|
|
252
|
-
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0,
|
|
252
|
+
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0, TOOL_ARG_DISPLAY_MAX - TAIL_KEEP - 3) + "..." + raw.slice(-TAIL_KEEP) : raw;
|
|
253
253
|
}
|
|
254
|
-
setActiveTools((prev) => [
|
|
254
|
+
setActiveTools((prev) => [
|
|
255
|
+
...prev,
|
|
256
|
+
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
257
|
+
]);
|
|
255
258
|
} else {
|
|
259
|
+
const result = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
256
260
|
setActiveTools(
|
|
257
261
|
(prev) => prev.map(
|
|
258
|
-
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false } : t
|
|
262
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result } : t
|
|
259
263
|
)
|
|
260
264
|
);
|
|
261
265
|
}
|
|
@@ -279,7 +283,13 @@ function useSession(props) {
|
|
|
279
283
|
setStreamingText("");
|
|
280
284
|
setActiveTools([]);
|
|
281
285
|
}, []);
|
|
282
|
-
return {
|
|
286
|
+
return {
|
|
287
|
+
session: sessionRef.current,
|
|
288
|
+
permissionRequest,
|
|
289
|
+
streamingText,
|
|
290
|
+
clearStreamingText,
|
|
291
|
+
activeTools
|
|
292
|
+
};
|
|
283
293
|
}
|
|
284
294
|
|
|
285
295
|
// src/ui/hooks/useMessages.ts
|
|
@@ -610,7 +620,7 @@ var import_react4 = require("react");
|
|
|
610
620
|
|
|
611
621
|
// src/utils/tool-call-extractor.ts
|
|
612
622
|
var TOOL_ARG_MAX_LENGTH = 80;
|
|
613
|
-
var
|
|
623
|
+
var TAIL_KEEP2 = 30;
|
|
614
624
|
function extractToolCalls(history, startIndex) {
|
|
615
625
|
const lines = [];
|
|
616
626
|
for (let i = startIndex; i < history.length; i++) {
|
|
@@ -618,7 +628,7 @@ function extractToolCalls(history, startIndex) {
|
|
|
618
628
|
if (msg.role === "assistant" && msg.toolCalls) {
|
|
619
629
|
for (const tc of msg.toolCalls) {
|
|
620
630
|
const value = parseFirstArgValue(tc.function.arguments);
|
|
621
|
-
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0,
|
|
631
|
+
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_MAX_LENGTH - TAIL_KEEP2 - 3) + "..." + value.slice(-TAIL_KEEP2) : value;
|
|
622
632
|
lines.push(`${tc.function.name}(${truncated})`);
|
|
623
633
|
}
|
|
624
634
|
}
|
|
@@ -746,6 +756,9 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
|
|
|
746
756
|
}
|
|
747
757
|
const prompt = await buildSkillPrompt(input, registry);
|
|
748
758
|
if (!prompt) return;
|
|
759
|
+
const cmdName = input.slice(1).split(/\s+/)[0]?.toLowerCase() ?? "";
|
|
760
|
+
const qualifiedName = registry.resolveQualifiedName(cmdName);
|
|
761
|
+
const hookInput = qualifiedName ? `/${qualifiedName}${input.slice(1 + cmdName.length)}` : input;
|
|
749
762
|
return runSessionPrompt(
|
|
750
763
|
prompt,
|
|
751
764
|
session,
|
|
@@ -753,7 +766,7 @@ function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamin
|
|
|
753
766
|
clearStreamingText,
|
|
754
767
|
setIsThinking,
|
|
755
768
|
setContextState,
|
|
756
|
-
|
|
769
|
+
hookInput
|
|
757
770
|
);
|
|
758
771
|
}
|
|
759
772
|
addMessage({ role: "user", content: input });
|
|
@@ -800,6 +813,14 @@ var CommandRegistry = class {
|
|
|
800
813
|
const lower = filter.toLowerCase();
|
|
801
814
|
return all.filter((cmd) => cmd.name.toLowerCase().startsWith(lower));
|
|
802
815
|
}
|
|
816
|
+
/** Resolve a short name to its fully qualified plugin:name form */
|
|
817
|
+
resolveQualifiedName(shortName) {
|
|
818
|
+
const matches = this.getCommands().filter(
|
|
819
|
+
(c) => c.source === "plugin" && c.name.includes(":") && c.name.endsWith(`:${shortName}`)
|
|
820
|
+
);
|
|
821
|
+
if (matches.length !== 1) return null;
|
|
822
|
+
return matches[0].name;
|
|
823
|
+
}
|
|
803
824
|
/** Get subcommands for a specific command */
|
|
804
825
|
getSubcommands(commandName) {
|
|
805
826
|
const lower = commandName.toLowerCase();
|
|
@@ -1033,7 +1054,7 @@ var PluginCommandSource = class {
|
|
|
1033
1054
|
const baseName = skill.name.includes("@") ? skill.name.split("@")[0] : skill.name;
|
|
1034
1055
|
commands.push({
|
|
1035
1056
|
name: baseName,
|
|
1036
|
-
description:
|
|
1057
|
+
description: `(${plugin.manifest.name}) ${skill.description}`,
|
|
1037
1058
|
source: "plugin",
|
|
1038
1059
|
skillContent: skill.skillContent,
|
|
1039
1060
|
pluginDir: plugin.pluginDir
|
|
@@ -1233,13 +1254,39 @@ function RoleLabel({ role }) {
|
|
|
1233
1254
|
" "
|
|
1234
1255
|
] });
|
|
1235
1256
|
case "tool":
|
|
1236
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "
|
|
1257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "white", bold: true, children: [
|
|
1237
1258
|
"Tool:",
|
|
1238
1259
|
" "
|
|
1239
1260
|
] });
|
|
1240
1261
|
}
|
|
1241
1262
|
}
|
|
1263
|
+
function ToolMessage({ message }) {
|
|
1264
|
+
const lines = message.content.split("\n").filter((l) => l.trim());
|
|
1265
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1266
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { children: [
|
|
1267
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "white", bold: true, children: [
|
|
1268
|
+
"Tool:",
|
|
1269
|
+
" "
|
|
1270
|
+
] }),
|
|
1271
|
+
message.toolName && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "white", dimColor: true, children: [
|
|
1272
|
+
"[",
|
|
1273
|
+
message.toolName,
|
|
1274
|
+
"]"
|
|
1275
|
+
] })
|
|
1276
|
+
] }),
|
|
1277
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }),
|
|
1278
|
+
lines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Text, { color: "green", children: [
|
|
1279
|
+
" ",
|
|
1280
|
+
"\u2713",
|
|
1281
|
+
" ",
|
|
1282
|
+
line
|
|
1283
|
+
] }, i))
|
|
1284
|
+
] });
|
|
1285
|
+
}
|
|
1242
1286
|
function MessageItem({ message }) {
|
|
1287
|
+
if (message.role === "tool") {
|
|
1288
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolMessage, { message });
|
|
1289
|
+
}
|
|
1243
1290
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1244
1291
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_ink.Box, { children: [
|
|
1245
1292
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(RoleLabel, { role: message.role }),
|
|
@@ -1731,6 +1778,12 @@ function PermissionPrompt({ request }) {
|
|
|
1731
1778
|
// src/ui/StreamingIndicator.tsx
|
|
1732
1779
|
var import_ink9 = require("ink");
|
|
1733
1780
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1781
|
+
function getToolStyle(t) {
|
|
1782
|
+
if (t.isRunning) return { color: "yellow", icon: "\u27F3", strikethrough: false };
|
|
1783
|
+
if (t.result === "error") return { color: "red", icon: "\u2717", strikethrough: true };
|
|
1784
|
+
if (t.result === "denied") return { color: "yellowBright", icon: "\u2298", strikethrough: true };
|
|
1785
|
+
return { color: "green", icon: "\u2713", strikethrough: false };
|
|
1786
|
+
}
|
|
1734
1787
|
function StreamingIndicator({ text, activeTools }) {
|
|
1735
1788
|
const hasTools = activeTools.length > 0;
|
|
1736
1789
|
const hasText = text.length > 0;
|
|
@@ -1739,17 +1792,20 @@ function StreamingIndicator({ text, activeTools }) {
|
|
|
1739
1792
|
}
|
|
1740
1793
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", children: [
|
|
1741
1794
|
hasTools && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1742
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "
|
|
1795
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "white", bold: true, children: "Tools:" }),
|
|
1743
1796
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { children: " " }),
|
|
1744
|
-
activeTools.map((t, i) =>
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1797
|
+
activeTools.map((t, i) => {
|
|
1798
|
+
const { color, icon, strikethrough } = getToolStyle(t);
|
|
1799
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Text, { color, strikethrough, children: [
|
|
1800
|
+
" ",
|
|
1801
|
+
icon,
|
|
1802
|
+
" ",
|
|
1803
|
+
t.toolName,
|
|
1804
|
+
"(",
|
|
1805
|
+
t.firstArg,
|
|
1806
|
+
")"
|
|
1807
|
+
] }, `${t.toolName}-${i}`);
|
|
1808
|
+
})
|
|
1753
1809
|
] }),
|
|
1754
1810
|
hasText && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1755
1811
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "cyan", bold: true, children: "Robota:" }),
|
package/dist/node/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@robota-sdk/agent-cli",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.26",
|
|
4
4
|
"description": "AI coding assistant CLI built on Robota SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"marked-terminal": "^7.3.0",
|
|
36
36
|
"react": "19.2.4",
|
|
37
37
|
"string-width": "^8.2.0",
|
|
38
|
-
"@robota-sdk/agent-core": "3.0.0-beta.
|
|
39
|
-
"@robota-sdk/agent-sdk": "3.0.0-beta.
|
|
38
|
+
"@robota-sdk/agent-core": "3.0.0-beta.26",
|
|
39
|
+
"@robota-sdk/agent-sdk": "3.0.0-beta.26"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/marked": "^6.0.0",
|