@robota-sdk/agent-cli 3.0.0-beta.27 → 3.0.0-beta.29
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 +62 -38
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-QTZS5QXJ.js → chunk-74GXDZY7.js} +40 -16
- package/dist/node/index.cjs +62 -38
- package/dist/node/index.js +1 -1
- package/package.json +3 -3
package/dist/node/bin.cjs
CHANGED
|
@@ -166,7 +166,7 @@ var PrintTerminal = class {
|
|
|
166
166
|
var import_ink11 = require("ink");
|
|
167
167
|
|
|
168
168
|
// src/ui/App.tsx
|
|
169
|
-
var
|
|
169
|
+
var import_react13 = require("react");
|
|
170
170
|
var import_ink10 = require("ink");
|
|
171
171
|
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
172
172
|
|
|
@@ -175,6 +175,7 @@ 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
177
|
var TAIL_KEEP = 30;
|
|
178
|
+
var MAX_COMPLETED_TOOLS = 50;
|
|
178
179
|
var NOOP_TERMINAL = {
|
|
179
180
|
write: () => {
|
|
180
181
|
},
|
|
@@ -240,12 +241,25 @@ function useSession(props) {
|
|
|
240
241
|
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
241
242
|
]);
|
|
242
243
|
} else {
|
|
243
|
-
const
|
|
244
|
-
setActiveTools(
|
|
245
|
-
|
|
246
|
-
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result } : t
|
|
247
|
-
)
|
|
248
|
-
|
|
244
|
+
const toolResult = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
245
|
+
setActiveTools((prev) => {
|
|
246
|
+
const updated = prev.map(
|
|
247
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result: toolResult } : t
|
|
248
|
+
);
|
|
249
|
+
const completed = updated.filter((t) => !t.isRunning);
|
|
250
|
+
if (completed.length > MAX_COMPLETED_TOOLS) {
|
|
251
|
+
const excess = completed.length - MAX_COMPLETED_TOOLS;
|
|
252
|
+
let removed = 0;
|
|
253
|
+
return updated.filter((t) => {
|
|
254
|
+
if (!t.isRunning && removed < excess) {
|
|
255
|
+
removed++;
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
return true;
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
return updated;
|
|
262
|
+
});
|
|
249
263
|
}
|
|
250
264
|
};
|
|
251
265
|
const paths = (0, import_agent_sdk.projectPaths)(props.cwd ?? process.cwd());
|
|
@@ -278,6 +292,7 @@ function useSession(props) {
|
|
|
278
292
|
|
|
279
293
|
// src/ui/hooks/useMessages.ts
|
|
280
294
|
var import_react2 = require("react");
|
|
295
|
+
var MAX_RENDERED_MESSAGES = 100;
|
|
281
296
|
var msgIdCounter = 0;
|
|
282
297
|
function nextId() {
|
|
283
298
|
msgIdCounter += 1;
|
|
@@ -286,7 +301,13 @@ function nextId() {
|
|
|
286
301
|
function useMessages() {
|
|
287
302
|
const [messages, setMessages] = (0, import_react2.useState)([]);
|
|
288
303
|
const addMessage = (0, import_react2.useCallback)((msg) => {
|
|
289
|
-
setMessages((prev) =>
|
|
304
|
+
setMessages((prev) => {
|
|
305
|
+
const updated = [...prev, { ...msg, id: nextId(), timestamp: /* @__PURE__ */ new Date() }];
|
|
306
|
+
if (updated.length > MAX_RENDERED_MESSAGES) {
|
|
307
|
+
return updated.slice(-MAX_RENDERED_MESSAGES);
|
|
308
|
+
}
|
|
309
|
+
return updated;
|
|
310
|
+
});
|
|
290
311
|
}, []);
|
|
291
312
|
return { messages, setMessages, addMessage };
|
|
292
313
|
}
|
|
@@ -1205,6 +1226,7 @@ function usePluginCallbacks(cwd) {
|
|
|
1205
1226
|
}
|
|
1206
1227
|
|
|
1207
1228
|
// src/ui/MessageList.tsx
|
|
1229
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
1208
1230
|
var import_ink = require("ink");
|
|
1209
1231
|
|
|
1210
1232
|
// src/ui/render-markdown.ts
|
|
@@ -1267,7 +1289,9 @@ function ToolMessage({ message }) {
|
|
|
1267
1289
|
] }, i))
|
|
1268
1290
|
] });
|
|
1269
1291
|
}
|
|
1270
|
-
|
|
1292
|
+
var MessageItem = import_react7.default.memo(function MessageItem2({
|
|
1293
|
+
message
|
|
1294
|
+
}) {
|
|
1271
1295
|
if (message.role === "tool") {
|
|
1272
1296
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolMessage, { message });
|
|
1273
1297
|
}
|
|
@@ -1284,7 +1308,7 @@ function MessageItem({ message }) {
|
|
|
1284
1308
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }),
|
|
1285
1309
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { wrap: "wrap", children: message.role === "assistant" ? renderMarkdown(message.content) : message.content }) })
|
|
1286
1310
|
] });
|
|
1287
|
-
}
|
|
1311
|
+
});
|
|
1288
1312
|
function MessageList({ messages }) {
|
|
1289
1313
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { flexDirection: "column", children: messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageItem, { message: msg }, msg.id)) });
|
|
1290
1314
|
}
|
|
@@ -1350,11 +1374,11 @@ function StatusBar({
|
|
|
1350
1374
|
}
|
|
1351
1375
|
|
|
1352
1376
|
// src/ui/InputArea.tsx
|
|
1353
|
-
var
|
|
1377
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
1354
1378
|
var import_ink6 = require("ink");
|
|
1355
1379
|
|
|
1356
1380
|
// src/ui/CjkTextInput.tsx
|
|
1357
|
-
var
|
|
1381
|
+
var import_react8 = require("react");
|
|
1358
1382
|
var import_ink3 = require("ink");
|
|
1359
1383
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
1360
1384
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -1374,9 +1398,9 @@ function CjkTextInput({
|
|
|
1374
1398
|
focus = true,
|
|
1375
1399
|
showCursor = true
|
|
1376
1400
|
}) {
|
|
1377
|
-
const valueRef = (0,
|
|
1378
|
-
const cursorRef = (0,
|
|
1379
|
-
const [, forceRender] = (0,
|
|
1401
|
+
const valueRef = (0, import_react8.useRef)(value);
|
|
1402
|
+
const cursorRef = (0, import_react8.useRef)(value.length);
|
|
1403
|
+
const [, forceRender] = (0, import_react8.useState)(0);
|
|
1380
1404
|
if (value !== valueRef.current) {
|
|
1381
1405
|
valueRef.current = value;
|
|
1382
1406
|
if (cursorRef.current > value.length) {
|
|
@@ -1453,15 +1477,15 @@ function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
|
1453
1477
|
}
|
|
1454
1478
|
|
|
1455
1479
|
// src/ui/WaveText.tsx
|
|
1456
|
-
var
|
|
1480
|
+
var import_react9 = require("react");
|
|
1457
1481
|
var import_ink4 = require("ink");
|
|
1458
1482
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1459
1483
|
var WAVE_COLORS = ["#666666", "#888888", "#aaaaaa", "#888888"];
|
|
1460
1484
|
var INTERVAL_MS = 400;
|
|
1461
1485
|
var CHARS_PER_GROUP = 4;
|
|
1462
1486
|
function WaveText({ text }) {
|
|
1463
|
-
const [tick, setTick] = (0,
|
|
1464
|
-
(0,
|
|
1487
|
+
const [tick, setTick] = (0, import_react9.useState)(0);
|
|
1488
|
+
(0, import_react9.useEffect)(() => {
|
|
1465
1489
|
const timer = setInterval(() => {
|
|
1466
1490
|
setTick((prev) => prev + 1);
|
|
1467
1491
|
}, INTERVAL_MS);
|
|
@@ -1527,16 +1551,16 @@ function parseSlashInput(value) {
|
|
|
1527
1551
|
return { isSlash: true, parentCommand: parent, filter: rest };
|
|
1528
1552
|
}
|
|
1529
1553
|
function useAutocomplete(value, registry) {
|
|
1530
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
1531
|
-
const [dismissed, setDismissed] = (0,
|
|
1532
|
-
const prevValueRef =
|
|
1554
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react10.useState)(0);
|
|
1555
|
+
const [dismissed, setDismissed] = (0, import_react10.useState)(false);
|
|
1556
|
+
const prevValueRef = import_react10.default.useRef(value);
|
|
1533
1557
|
if (prevValueRef.current !== value) {
|
|
1534
1558
|
prevValueRef.current = value;
|
|
1535
1559
|
if (dismissed) setDismissed(false);
|
|
1536
1560
|
}
|
|
1537
1561
|
const parsed = parseSlashInput(value);
|
|
1538
1562
|
const isSubcommandMode = parsed.isSlash && parsed.parentCommand.length > 0;
|
|
1539
|
-
const filteredCommands = (0,
|
|
1563
|
+
const filteredCommands = (0, import_react10.useMemo)(() => {
|
|
1540
1564
|
if (!registry || !parsed.isSlash || dismissed) return [];
|
|
1541
1565
|
if (isSubcommandMode) {
|
|
1542
1566
|
const subs = registry.getSubcommands(parsed.parentCommand);
|
|
@@ -1570,7 +1594,7 @@ function useAutocomplete(value, registry) {
|
|
|
1570
1594
|
};
|
|
1571
1595
|
}
|
|
1572
1596
|
function InputArea({ onSubmit, isDisabled, registry }) {
|
|
1573
|
-
const [value, setValue] = (0,
|
|
1597
|
+
const [value, setValue] = (0, import_react10.useState)("");
|
|
1574
1598
|
const {
|
|
1575
1599
|
showPopup,
|
|
1576
1600
|
filteredCommands,
|
|
@@ -1579,7 +1603,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1579
1603
|
isSubcommandMode,
|
|
1580
1604
|
setShowPopup
|
|
1581
1605
|
} = useAutocomplete(value, registry);
|
|
1582
|
-
const handleSubmit = (0,
|
|
1606
|
+
const handleSubmit = (0, import_react10.useCallback)(
|
|
1583
1607
|
(text) => {
|
|
1584
1608
|
const trimmed = text.trim();
|
|
1585
1609
|
if (trimmed.length === 0) return;
|
|
@@ -1592,7 +1616,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1592
1616
|
},
|
|
1593
1617
|
[showPopup, filteredCommands, selectedIndex, onSubmit]
|
|
1594
1618
|
);
|
|
1595
|
-
const selectCommand = (0,
|
|
1619
|
+
const selectCommand = (0, import_react10.useCallback)(
|
|
1596
1620
|
(cmd) => {
|
|
1597
1621
|
const parsed = parseSlashInput(value);
|
|
1598
1622
|
if (parsed.parentCommand) {
|
|
@@ -1653,7 +1677,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1653
1677
|
}
|
|
1654
1678
|
|
|
1655
1679
|
// src/ui/ConfirmPrompt.tsx
|
|
1656
|
-
var
|
|
1680
|
+
var import_react11 = require("react");
|
|
1657
1681
|
var import_ink7 = require("ink");
|
|
1658
1682
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1659
1683
|
function ConfirmPrompt({
|
|
@@ -1661,9 +1685,9 @@ function ConfirmPrompt({
|
|
|
1661
1685
|
options = ["Yes", "No"],
|
|
1662
1686
|
onSelect
|
|
1663
1687
|
}) {
|
|
1664
|
-
const [selected, setSelected] = (0,
|
|
1665
|
-
const resolvedRef = (0,
|
|
1666
|
-
const doSelect = (0,
|
|
1688
|
+
const [selected, setSelected] = (0, import_react11.useState)(0);
|
|
1689
|
+
const resolvedRef = (0, import_react11.useRef)(false);
|
|
1690
|
+
const doSelect = (0, import_react11.useCallback)(
|
|
1667
1691
|
(index) => {
|
|
1668
1692
|
if (resolvedRef.current) return;
|
|
1669
1693
|
resolvedRef.current = true;
|
|
@@ -1696,7 +1720,7 @@ function ConfirmPrompt({
|
|
|
1696
1720
|
}
|
|
1697
1721
|
|
|
1698
1722
|
// src/ui/PermissionPrompt.tsx
|
|
1699
|
-
var
|
|
1723
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
1700
1724
|
var import_ink8 = require("ink");
|
|
1701
1725
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1702
1726
|
var OPTIONS = ["Allow", "Allow always (this session)", "Deny"];
|
|
@@ -1706,15 +1730,15 @@ function formatArgs(args) {
|
|
|
1706
1730
|
return entries.map(([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`).join(", ");
|
|
1707
1731
|
}
|
|
1708
1732
|
function PermissionPrompt({ request }) {
|
|
1709
|
-
const [selected, setSelected] =
|
|
1710
|
-
const resolvedRef =
|
|
1711
|
-
const prevRequestRef =
|
|
1733
|
+
const [selected, setSelected] = import_react12.default.useState(0);
|
|
1734
|
+
const resolvedRef = import_react12.default.useRef(false);
|
|
1735
|
+
const prevRequestRef = import_react12.default.useRef(request);
|
|
1712
1736
|
if (prevRequestRef.current !== request) {
|
|
1713
1737
|
prevRequestRef.current = request;
|
|
1714
1738
|
resolvedRef.current = false;
|
|
1715
1739
|
setSelected(0);
|
|
1716
1740
|
}
|
|
1717
|
-
const doResolve =
|
|
1741
|
+
const doResolve = import_react12.default.useCallback(
|
|
1718
1742
|
(index) => {
|
|
1719
1743
|
if (resolvedRef.current) return;
|
|
1720
1744
|
resolvedRef.current = true;
|
|
@@ -1832,15 +1856,15 @@ function App(props) {
|
|
|
1832
1856
|
{ ...props, config: configWithPluginHooks }
|
|
1833
1857
|
);
|
|
1834
1858
|
const { messages, setMessages, addMessage } = useMessages();
|
|
1835
|
-
const [isThinking, setIsThinking] = (0,
|
|
1859
|
+
const [isThinking, setIsThinking] = (0, import_react13.useState)(false);
|
|
1836
1860
|
const initialCtx = session.getContextState();
|
|
1837
|
-
const [contextState, setContextState] = (0,
|
|
1861
|
+
const [contextState, setContextState] = (0, import_react13.useState)({
|
|
1838
1862
|
percentage: initialCtx.usedPercentage,
|
|
1839
1863
|
usedTokens: initialCtx.usedTokens,
|
|
1840
1864
|
maxTokens: initialCtx.maxTokens
|
|
1841
1865
|
});
|
|
1842
|
-
const pendingModelChangeRef = (0,
|
|
1843
|
-
const [pendingModelId, setPendingModelId] = (0,
|
|
1866
|
+
const pendingModelChangeRef = (0, import_react13.useRef)(null);
|
|
1867
|
+
const [pendingModelId, setPendingModelId] = (0, import_react13.useState)(null);
|
|
1844
1868
|
const pluginCallbacks = usePluginCallbacks(props.cwd ?? process.cwd());
|
|
1845
1869
|
const handleSlashCommand = useSlashCommands(
|
|
1846
1870
|
session,
|
package/dist/node/bin.js
CHANGED
|
@@ -158,6 +158,7 @@ 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
160
|
var TAIL_KEEP = 30;
|
|
161
|
+
var MAX_COMPLETED_TOOLS = 50;
|
|
161
162
|
var NOOP_TERMINAL = {
|
|
162
163
|
write: () => {
|
|
163
164
|
},
|
|
@@ -223,12 +224,25 @@ function useSession(props) {
|
|
|
223
224
|
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
224
225
|
]);
|
|
225
226
|
} else {
|
|
226
|
-
const
|
|
227
|
-
setActiveTools(
|
|
228
|
-
|
|
229
|
-
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result } : t
|
|
230
|
-
)
|
|
231
|
-
|
|
227
|
+
const toolResult = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
228
|
+
setActiveTools((prev) => {
|
|
229
|
+
const updated = prev.map(
|
|
230
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result: toolResult } : t
|
|
231
|
+
);
|
|
232
|
+
const completed = updated.filter((t) => !t.isRunning);
|
|
233
|
+
if (completed.length > MAX_COMPLETED_TOOLS) {
|
|
234
|
+
const excess = completed.length - MAX_COMPLETED_TOOLS;
|
|
235
|
+
let removed = 0;
|
|
236
|
+
return updated.filter((t) => {
|
|
237
|
+
if (!t.isRunning && removed < excess) {
|
|
238
|
+
removed++;
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
return updated;
|
|
245
|
+
});
|
|
232
246
|
}
|
|
233
247
|
};
|
|
234
248
|
const paths = projectPaths(props.cwd ?? process.cwd());
|
|
@@ -261,6 +275,7 @@ function useSession(props) {
|
|
|
261
275
|
|
|
262
276
|
// src/ui/hooks/useMessages.ts
|
|
263
277
|
import { useState as useState2, useCallback as useCallback2 } from "react";
|
|
278
|
+
var MAX_RENDERED_MESSAGES = 100;
|
|
264
279
|
var msgIdCounter = 0;
|
|
265
280
|
function nextId() {
|
|
266
281
|
msgIdCounter += 1;
|
|
@@ -269,7 +284,13 @@ function nextId() {
|
|
|
269
284
|
function useMessages() {
|
|
270
285
|
const [messages, setMessages] = useState2([]);
|
|
271
286
|
const addMessage = useCallback2((msg) => {
|
|
272
|
-
setMessages((prev) =>
|
|
287
|
+
setMessages((prev) => {
|
|
288
|
+
const updated = [...prev, { ...msg, id: nextId(), timestamp: /* @__PURE__ */ new Date() }];
|
|
289
|
+
if (updated.length > MAX_RENDERED_MESSAGES) {
|
|
290
|
+
return updated.slice(-MAX_RENDERED_MESSAGES);
|
|
291
|
+
}
|
|
292
|
+
return updated;
|
|
293
|
+
});
|
|
273
294
|
}, []);
|
|
274
295
|
return { messages, setMessages, addMessage };
|
|
275
296
|
}
|
|
@@ -1193,6 +1214,7 @@ function usePluginCallbacks(cwd) {
|
|
|
1193
1214
|
}
|
|
1194
1215
|
|
|
1195
1216
|
// src/ui/MessageList.tsx
|
|
1217
|
+
import React2 from "react";
|
|
1196
1218
|
import { Box, Text } from "ink";
|
|
1197
1219
|
|
|
1198
1220
|
// src/ui/render-markdown.ts
|
|
@@ -1255,7 +1277,9 @@ function ToolMessage({ message }) {
|
|
|
1255
1277
|
] }, i))
|
|
1256
1278
|
] });
|
|
1257
1279
|
}
|
|
1258
|
-
|
|
1280
|
+
var MessageItem = React2.memo(function MessageItem2({
|
|
1281
|
+
message
|
|
1282
|
+
}) {
|
|
1259
1283
|
if (message.role === "tool") {
|
|
1260
1284
|
return /* @__PURE__ */ jsx(ToolMessage, { message });
|
|
1261
1285
|
}
|
|
@@ -1272,7 +1296,7 @@ function MessageItem({ message }) {
|
|
|
1272
1296
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
1273
1297
|
/* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsx(Text, { wrap: "wrap", children: message.role === "assistant" ? renderMarkdown(message.content) : message.content }) })
|
|
1274
1298
|
] });
|
|
1275
|
-
}
|
|
1299
|
+
});
|
|
1276
1300
|
function MessageList({ messages }) {
|
|
1277
1301
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: messages.map((msg) => /* @__PURE__ */ jsx(MessageItem, { message: msg }, msg.id)) });
|
|
1278
1302
|
}
|
|
@@ -1338,7 +1362,7 @@ function StatusBar({
|
|
|
1338
1362
|
}
|
|
1339
1363
|
|
|
1340
1364
|
// src/ui/InputArea.tsx
|
|
1341
|
-
import
|
|
1365
|
+
import React5, { useState as useState5, useCallback as useCallback5, useMemo as useMemo2 } from "react";
|
|
1342
1366
|
import { Box as Box4, Text as Text6, useInput as useInput2 } from "ink";
|
|
1343
1367
|
|
|
1344
1368
|
// src/ui/CjkTextInput.tsx
|
|
@@ -1517,7 +1541,7 @@ function parseSlashInput(value) {
|
|
|
1517
1541
|
function useAutocomplete(value, registry) {
|
|
1518
1542
|
const [selectedIndex, setSelectedIndex] = useState5(0);
|
|
1519
1543
|
const [dismissed, setDismissed] = useState5(false);
|
|
1520
|
-
const prevValueRef =
|
|
1544
|
+
const prevValueRef = React5.useRef(value);
|
|
1521
1545
|
if (prevValueRef.current !== value) {
|
|
1522
1546
|
prevValueRef.current = value;
|
|
1523
1547
|
if (dismissed) setDismissed(false);
|
|
@@ -1684,7 +1708,7 @@ function ConfirmPrompt({
|
|
|
1684
1708
|
}
|
|
1685
1709
|
|
|
1686
1710
|
// src/ui/PermissionPrompt.tsx
|
|
1687
|
-
import
|
|
1711
|
+
import React7 from "react";
|
|
1688
1712
|
import { Box as Box6, Text as Text8, useInput as useInput4 } from "ink";
|
|
1689
1713
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1690
1714
|
var OPTIONS = ["Allow", "Allow always (this session)", "Deny"];
|
|
@@ -1694,15 +1718,15 @@ function formatArgs(args) {
|
|
|
1694
1718
|
return entries.map(([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`).join(", ");
|
|
1695
1719
|
}
|
|
1696
1720
|
function PermissionPrompt({ request }) {
|
|
1697
|
-
const [selected, setSelected] =
|
|
1698
|
-
const resolvedRef =
|
|
1699
|
-
const prevRequestRef =
|
|
1721
|
+
const [selected, setSelected] = React7.useState(0);
|
|
1722
|
+
const resolvedRef = React7.useRef(false);
|
|
1723
|
+
const prevRequestRef = React7.useRef(request);
|
|
1700
1724
|
if (prevRequestRef.current !== request) {
|
|
1701
1725
|
prevRequestRef.current = request;
|
|
1702
1726
|
resolvedRef.current = false;
|
|
1703
1727
|
setSelected(0);
|
|
1704
1728
|
}
|
|
1705
|
-
const doResolve =
|
|
1729
|
+
const doResolve = React7.useCallback(
|
|
1706
1730
|
(index) => {
|
|
1707
1731
|
if (resolvedRef.current) return;
|
|
1708
1732
|
resolvedRef.current = true;
|
package/dist/node/index.cjs
CHANGED
|
@@ -182,7 +182,7 @@ var PrintTerminal = class {
|
|
|
182
182
|
var import_ink11 = require("ink");
|
|
183
183
|
|
|
184
184
|
// src/ui/App.tsx
|
|
185
|
-
var
|
|
185
|
+
var import_react13 = require("react");
|
|
186
186
|
var import_ink10 = require("ink");
|
|
187
187
|
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
188
188
|
|
|
@@ -191,6 +191,7 @@ 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
193
|
var TAIL_KEEP = 30;
|
|
194
|
+
var MAX_COMPLETED_TOOLS = 50;
|
|
194
195
|
var NOOP_TERMINAL = {
|
|
195
196
|
write: () => {
|
|
196
197
|
},
|
|
@@ -256,12 +257,25 @@ function useSession(props) {
|
|
|
256
257
|
{ toolName: event.toolName, firstArg, isRunning: true }
|
|
257
258
|
]);
|
|
258
259
|
} else {
|
|
259
|
-
const
|
|
260
|
-
setActiveTools(
|
|
261
|
-
|
|
262
|
-
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result } : t
|
|
263
|
-
)
|
|
264
|
-
|
|
260
|
+
const toolResult = event.denied ? "denied" : event.success === false ? "error" : "success";
|
|
261
|
+
setActiveTools((prev) => {
|
|
262
|
+
const updated = prev.map(
|
|
263
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false, result: toolResult } : t
|
|
264
|
+
);
|
|
265
|
+
const completed = updated.filter((t) => !t.isRunning);
|
|
266
|
+
if (completed.length > MAX_COMPLETED_TOOLS) {
|
|
267
|
+
const excess = completed.length - MAX_COMPLETED_TOOLS;
|
|
268
|
+
let removed = 0;
|
|
269
|
+
return updated.filter((t) => {
|
|
270
|
+
if (!t.isRunning && removed < excess) {
|
|
271
|
+
removed++;
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
return true;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
return updated;
|
|
278
|
+
});
|
|
265
279
|
}
|
|
266
280
|
};
|
|
267
281
|
const paths = (0, import_agent_sdk.projectPaths)(props.cwd ?? process.cwd());
|
|
@@ -294,6 +308,7 @@ function useSession(props) {
|
|
|
294
308
|
|
|
295
309
|
// src/ui/hooks/useMessages.ts
|
|
296
310
|
var import_react2 = require("react");
|
|
311
|
+
var MAX_RENDERED_MESSAGES = 100;
|
|
297
312
|
var msgIdCounter = 0;
|
|
298
313
|
function nextId() {
|
|
299
314
|
msgIdCounter += 1;
|
|
@@ -302,7 +317,13 @@ function nextId() {
|
|
|
302
317
|
function useMessages() {
|
|
303
318
|
const [messages, setMessages] = (0, import_react2.useState)([]);
|
|
304
319
|
const addMessage = (0, import_react2.useCallback)((msg) => {
|
|
305
|
-
setMessages((prev) =>
|
|
320
|
+
setMessages((prev) => {
|
|
321
|
+
const updated = [...prev, { ...msg, id: nextId(), timestamp: /* @__PURE__ */ new Date() }];
|
|
322
|
+
if (updated.length > MAX_RENDERED_MESSAGES) {
|
|
323
|
+
return updated.slice(-MAX_RENDERED_MESSAGES);
|
|
324
|
+
}
|
|
325
|
+
return updated;
|
|
326
|
+
});
|
|
306
327
|
}, []);
|
|
307
328
|
return { messages, setMessages, addMessage };
|
|
308
329
|
}
|
|
@@ -1221,6 +1242,7 @@ function usePluginCallbacks(cwd) {
|
|
|
1221
1242
|
}
|
|
1222
1243
|
|
|
1223
1244
|
// src/ui/MessageList.tsx
|
|
1245
|
+
var import_react7 = __toESM(require("react"), 1);
|
|
1224
1246
|
var import_ink = require("ink");
|
|
1225
1247
|
|
|
1226
1248
|
// src/ui/render-markdown.ts
|
|
@@ -1283,7 +1305,9 @@ function ToolMessage({ message }) {
|
|
|
1283
1305
|
] }, i))
|
|
1284
1306
|
] });
|
|
1285
1307
|
}
|
|
1286
|
-
|
|
1308
|
+
var MessageItem = import_react7.default.memo(function MessageItem2({
|
|
1309
|
+
message
|
|
1310
|
+
}) {
|
|
1287
1311
|
if (message.role === "tool") {
|
|
1288
1312
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ToolMessage, { message });
|
|
1289
1313
|
}
|
|
@@ -1300,7 +1324,7 @@ function MessageItem({ message }) {
|
|
|
1300
1324
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { children: " " }),
|
|
1301
1325
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Text, { wrap: "wrap", children: message.role === "assistant" ? renderMarkdown(message.content) : message.content }) })
|
|
1302
1326
|
] });
|
|
1303
|
-
}
|
|
1327
|
+
});
|
|
1304
1328
|
function MessageList({ messages }) {
|
|
1305
1329
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { flexDirection: "column", children: messages.map((msg) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(MessageItem, { message: msg }, msg.id)) });
|
|
1306
1330
|
}
|
|
@@ -1366,11 +1390,11 @@ function StatusBar({
|
|
|
1366
1390
|
}
|
|
1367
1391
|
|
|
1368
1392
|
// src/ui/InputArea.tsx
|
|
1369
|
-
var
|
|
1393
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
1370
1394
|
var import_ink6 = require("ink");
|
|
1371
1395
|
|
|
1372
1396
|
// src/ui/CjkTextInput.tsx
|
|
1373
|
-
var
|
|
1397
|
+
var import_react8 = require("react");
|
|
1374
1398
|
var import_ink3 = require("ink");
|
|
1375
1399
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
1376
1400
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -1390,9 +1414,9 @@ function CjkTextInput({
|
|
|
1390
1414
|
focus = true,
|
|
1391
1415
|
showCursor = true
|
|
1392
1416
|
}) {
|
|
1393
|
-
const valueRef = (0,
|
|
1394
|
-
const cursorRef = (0,
|
|
1395
|
-
const [, forceRender] = (0,
|
|
1417
|
+
const valueRef = (0, import_react8.useRef)(value);
|
|
1418
|
+
const cursorRef = (0, import_react8.useRef)(value.length);
|
|
1419
|
+
const [, forceRender] = (0, import_react8.useState)(0);
|
|
1396
1420
|
if (value !== valueRef.current) {
|
|
1397
1421
|
valueRef.current = value;
|
|
1398
1422
|
if (cursorRef.current > value.length) {
|
|
@@ -1469,15 +1493,15 @@ function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
|
1469
1493
|
}
|
|
1470
1494
|
|
|
1471
1495
|
// src/ui/WaveText.tsx
|
|
1472
|
-
var
|
|
1496
|
+
var import_react9 = require("react");
|
|
1473
1497
|
var import_ink4 = require("ink");
|
|
1474
1498
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1475
1499
|
var WAVE_COLORS = ["#666666", "#888888", "#aaaaaa", "#888888"];
|
|
1476
1500
|
var INTERVAL_MS = 400;
|
|
1477
1501
|
var CHARS_PER_GROUP = 4;
|
|
1478
1502
|
function WaveText({ text }) {
|
|
1479
|
-
const [tick, setTick] = (0,
|
|
1480
|
-
(0,
|
|
1503
|
+
const [tick, setTick] = (0, import_react9.useState)(0);
|
|
1504
|
+
(0, import_react9.useEffect)(() => {
|
|
1481
1505
|
const timer = setInterval(() => {
|
|
1482
1506
|
setTick((prev) => prev + 1);
|
|
1483
1507
|
}, INTERVAL_MS);
|
|
@@ -1543,16 +1567,16 @@ function parseSlashInput(value) {
|
|
|
1543
1567
|
return { isSlash: true, parentCommand: parent, filter: rest };
|
|
1544
1568
|
}
|
|
1545
1569
|
function useAutocomplete(value, registry) {
|
|
1546
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
1547
|
-
const [dismissed, setDismissed] = (0,
|
|
1548
|
-
const prevValueRef =
|
|
1570
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react10.useState)(0);
|
|
1571
|
+
const [dismissed, setDismissed] = (0, import_react10.useState)(false);
|
|
1572
|
+
const prevValueRef = import_react10.default.useRef(value);
|
|
1549
1573
|
if (prevValueRef.current !== value) {
|
|
1550
1574
|
prevValueRef.current = value;
|
|
1551
1575
|
if (dismissed) setDismissed(false);
|
|
1552
1576
|
}
|
|
1553
1577
|
const parsed = parseSlashInput(value);
|
|
1554
1578
|
const isSubcommandMode = parsed.isSlash && parsed.parentCommand.length > 0;
|
|
1555
|
-
const filteredCommands = (0,
|
|
1579
|
+
const filteredCommands = (0, import_react10.useMemo)(() => {
|
|
1556
1580
|
if (!registry || !parsed.isSlash || dismissed) return [];
|
|
1557
1581
|
if (isSubcommandMode) {
|
|
1558
1582
|
const subs = registry.getSubcommands(parsed.parentCommand);
|
|
@@ -1586,7 +1610,7 @@ function useAutocomplete(value, registry) {
|
|
|
1586
1610
|
};
|
|
1587
1611
|
}
|
|
1588
1612
|
function InputArea({ onSubmit, isDisabled, registry }) {
|
|
1589
|
-
const [value, setValue] = (0,
|
|
1613
|
+
const [value, setValue] = (0, import_react10.useState)("");
|
|
1590
1614
|
const {
|
|
1591
1615
|
showPopup,
|
|
1592
1616
|
filteredCommands,
|
|
@@ -1595,7 +1619,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1595
1619
|
isSubcommandMode,
|
|
1596
1620
|
setShowPopup
|
|
1597
1621
|
} = useAutocomplete(value, registry);
|
|
1598
|
-
const handleSubmit = (0,
|
|
1622
|
+
const handleSubmit = (0, import_react10.useCallback)(
|
|
1599
1623
|
(text) => {
|
|
1600
1624
|
const trimmed = text.trim();
|
|
1601
1625
|
if (trimmed.length === 0) return;
|
|
@@ -1608,7 +1632,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1608
1632
|
},
|
|
1609
1633
|
[showPopup, filteredCommands, selectedIndex, onSubmit]
|
|
1610
1634
|
);
|
|
1611
|
-
const selectCommand = (0,
|
|
1635
|
+
const selectCommand = (0, import_react10.useCallback)(
|
|
1612
1636
|
(cmd) => {
|
|
1613
1637
|
const parsed = parseSlashInput(value);
|
|
1614
1638
|
if (parsed.parentCommand) {
|
|
@@ -1669,7 +1693,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
1669
1693
|
}
|
|
1670
1694
|
|
|
1671
1695
|
// src/ui/ConfirmPrompt.tsx
|
|
1672
|
-
var
|
|
1696
|
+
var import_react11 = require("react");
|
|
1673
1697
|
var import_ink7 = require("ink");
|
|
1674
1698
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1675
1699
|
function ConfirmPrompt({
|
|
@@ -1677,9 +1701,9 @@ function ConfirmPrompt({
|
|
|
1677
1701
|
options = ["Yes", "No"],
|
|
1678
1702
|
onSelect
|
|
1679
1703
|
}) {
|
|
1680
|
-
const [selected, setSelected] = (0,
|
|
1681
|
-
const resolvedRef = (0,
|
|
1682
|
-
const doSelect = (0,
|
|
1704
|
+
const [selected, setSelected] = (0, import_react11.useState)(0);
|
|
1705
|
+
const resolvedRef = (0, import_react11.useRef)(false);
|
|
1706
|
+
const doSelect = (0, import_react11.useCallback)(
|
|
1683
1707
|
(index) => {
|
|
1684
1708
|
if (resolvedRef.current) return;
|
|
1685
1709
|
resolvedRef.current = true;
|
|
@@ -1712,7 +1736,7 @@ function ConfirmPrompt({
|
|
|
1712
1736
|
}
|
|
1713
1737
|
|
|
1714
1738
|
// src/ui/PermissionPrompt.tsx
|
|
1715
|
-
var
|
|
1739
|
+
var import_react12 = __toESM(require("react"), 1);
|
|
1716
1740
|
var import_ink8 = require("ink");
|
|
1717
1741
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1718
1742
|
var OPTIONS = ["Allow", "Allow always (this session)", "Deny"];
|
|
@@ -1722,15 +1746,15 @@ function formatArgs(args) {
|
|
|
1722
1746
|
return entries.map(([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`).join(", ");
|
|
1723
1747
|
}
|
|
1724
1748
|
function PermissionPrompt({ request }) {
|
|
1725
|
-
const [selected, setSelected] =
|
|
1726
|
-
const resolvedRef =
|
|
1727
|
-
const prevRequestRef =
|
|
1749
|
+
const [selected, setSelected] = import_react12.default.useState(0);
|
|
1750
|
+
const resolvedRef = import_react12.default.useRef(false);
|
|
1751
|
+
const prevRequestRef = import_react12.default.useRef(request);
|
|
1728
1752
|
if (prevRequestRef.current !== request) {
|
|
1729
1753
|
prevRequestRef.current = request;
|
|
1730
1754
|
resolvedRef.current = false;
|
|
1731
1755
|
setSelected(0);
|
|
1732
1756
|
}
|
|
1733
|
-
const doResolve =
|
|
1757
|
+
const doResolve = import_react12.default.useCallback(
|
|
1734
1758
|
(index) => {
|
|
1735
1759
|
if (resolvedRef.current) return;
|
|
1736
1760
|
resolvedRef.current = true;
|
|
@@ -1848,15 +1872,15 @@ function App(props) {
|
|
|
1848
1872
|
{ ...props, config: configWithPluginHooks }
|
|
1849
1873
|
);
|
|
1850
1874
|
const { messages, setMessages, addMessage } = useMessages();
|
|
1851
|
-
const [isThinking, setIsThinking] = (0,
|
|
1875
|
+
const [isThinking, setIsThinking] = (0, import_react13.useState)(false);
|
|
1852
1876
|
const initialCtx = session.getContextState();
|
|
1853
|
-
const [contextState, setContextState] = (0,
|
|
1877
|
+
const [contextState, setContextState] = (0, import_react13.useState)({
|
|
1854
1878
|
percentage: initialCtx.usedPercentage,
|
|
1855
1879
|
usedTokens: initialCtx.usedTokens,
|
|
1856
1880
|
maxTokens: initialCtx.maxTokens
|
|
1857
1881
|
});
|
|
1858
|
-
const pendingModelChangeRef = (0,
|
|
1859
|
-
const [pendingModelId, setPendingModelId] = (0,
|
|
1882
|
+
const pendingModelChangeRef = (0, import_react13.useRef)(null);
|
|
1883
|
+
const [pendingModelId, setPendingModelId] = (0, import_react13.useState)(null);
|
|
1860
1884
|
const pluginCallbacks = usePluginCallbacks(props.cwd ?? process.cwd());
|
|
1861
1885
|
const handleSlashCommand = useSlashCommands(
|
|
1862
1886
|
session,
|
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.29",
|
|
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-
|
|
39
|
-
"@robota-sdk/agent-
|
|
38
|
+
"@robota-sdk/agent-core": "3.0.0-beta.29",
|
|
39
|
+
"@robota-sdk/agent-sdk": "3.0.0-beta.29"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/marked": "^6.0.0",
|