@robota-sdk/agent-cli 3.0.0-beta.17 → 3.0.0-beta.19
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 +353 -290
- package/dist/node/bin.js +1 -1
- package/dist/node/{chunk-4WB3L3RU.js → chunk-RE4JCNEA.js} +342 -279
- package/dist/node/index.cjs +353 -290
- package/dist/node/index.js +1 -1
- package/package.json +3 -3
package/dist/node/bin.cjs
CHANGED
|
@@ -161,11 +161,126 @@ var PrintTerminal = class {
|
|
|
161
161
|
};
|
|
162
162
|
|
|
163
163
|
// src/ui/render.tsx
|
|
164
|
-
var
|
|
164
|
+
var import_ink11 = require("ink");
|
|
165
165
|
|
|
166
166
|
// src/ui/App.tsx
|
|
167
|
-
var
|
|
168
|
-
var
|
|
167
|
+
var import_react11 = require("react");
|
|
168
|
+
var import_ink10 = require("ink");
|
|
169
|
+
var import_agent_core3 = require("@robota-sdk/agent-core");
|
|
170
|
+
|
|
171
|
+
// src/ui/hooks/useSession.ts
|
|
172
|
+
var import_react = require("react");
|
|
173
|
+
var import_agent_sdk = require("@robota-sdk/agent-sdk");
|
|
174
|
+
var TOOL_ARG_DISPLAY_MAX = 80;
|
|
175
|
+
var TOOL_ARG_TRUNCATE_AT = 77;
|
|
176
|
+
var NOOP_TERMINAL = {
|
|
177
|
+
write: () => {
|
|
178
|
+
},
|
|
179
|
+
writeLine: () => {
|
|
180
|
+
},
|
|
181
|
+
writeMarkdown: () => {
|
|
182
|
+
},
|
|
183
|
+
writeError: () => {
|
|
184
|
+
},
|
|
185
|
+
prompt: () => Promise.resolve(""),
|
|
186
|
+
select: () => Promise.resolve(0),
|
|
187
|
+
spinner: () => ({ stop: () => {
|
|
188
|
+
}, update: () => {
|
|
189
|
+
} })
|
|
190
|
+
};
|
|
191
|
+
function useSession(props) {
|
|
192
|
+
const [permissionRequest, setPermissionRequest] = (0, import_react.useState)(null);
|
|
193
|
+
const [streamingText, setStreamingText] = (0, import_react.useState)("");
|
|
194
|
+
const [activeTools, setActiveTools] = (0, import_react.useState)([]);
|
|
195
|
+
const permissionQueueRef = (0, import_react.useRef)([]);
|
|
196
|
+
const processingRef = (0, import_react.useRef)(false);
|
|
197
|
+
const processNextPermission = (0, import_react.useCallback)(() => {
|
|
198
|
+
if (processingRef.current) return;
|
|
199
|
+
const next = permissionQueueRef.current[0];
|
|
200
|
+
if (!next) {
|
|
201
|
+
setPermissionRequest(null);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
processingRef.current = true;
|
|
205
|
+
setPermissionRequest({
|
|
206
|
+
toolName: next.toolName,
|
|
207
|
+
toolArgs: next.toolArgs,
|
|
208
|
+
resolve: (result) => {
|
|
209
|
+
permissionQueueRef.current.shift();
|
|
210
|
+
processingRef.current = false;
|
|
211
|
+
setPermissionRequest(null);
|
|
212
|
+
next.resolve(result);
|
|
213
|
+
setTimeout(() => processNextPermission(), 0);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}, []);
|
|
217
|
+
const sessionRef = (0, import_react.useRef)(null);
|
|
218
|
+
if (sessionRef.current === null) {
|
|
219
|
+
const permissionHandler = (toolName, toolArgs) => {
|
|
220
|
+
return new Promise((resolve) => {
|
|
221
|
+
permissionQueueRef.current.push({ toolName, toolArgs, resolve });
|
|
222
|
+
processNextPermission();
|
|
223
|
+
});
|
|
224
|
+
};
|
|
225
|
+
const onTextDelta = (delta) => {
|
|
226
|
+
setStreamingText((prev) => prev + delta);
|
|
227
|
+
};
|
|
228
|
+
const onToolExecution = (event) => {
|
|
229
|
+
if (event.type === "start") {
|
|
230
|
+
let firstArg = "";
|
|
231
|
+
if (event.toolArgs) {
|
|
232
|
+
const firstVal = Object.values(event.toolArgs)[0];
|
|
233
|
+
const raw = typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal ?? "");
|
|
234
|
+
firstArg = raw.length > TOOL_ARG_DISPLAY_MAX ? raw.slice(0, TOOL_ARG_TRUNCATE_AT) + "..." : raw;
|
|
235
|
+
}
|
|
236
|
+
setActiveTools((prev) => [...prev, { toolName: event.toolName, firstArg, isRunning: true }]);
|
|
237
|
+
} else {
|
|
238
|
+
setActiveTools(
|
|
239
|
+
(prev) => prev.map(
|
|
240
|
+
(t) => t.toolName === event.toolName && t.isRunning ? { ...t, isRunning: false } : t
|
|
241
|
+
)
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
const paths = (0, import_agent_sdk.projectPaths)(props.cwd ?? process.cwd());
|
|
246
|
+
sessionRef.current = (0, import_agent_sdk.createSession)({
|
|
247
|
+
config: props.config,
|
|
248
|
+
context: props.context,
|
|
249
|
+
terminal: NOOP_TERMINAL,
|
|
250
|
+
sessionLogger: new import_agent_sdk.FileSessionLogger(paths.logs),
|
|
251
|
+
projectInfo: props.projectInfo,
|
|
252
|
+
sessionStore: props.sessionStore,
|
|
253
|
+
permissionMode: props.permissionMode,
|
|
254
|
+
maxTurns: props.maxTurns,
|
|
255
|
+
permissionHandler,
|
|
256
|
+
onTextDelta,
|
|
257
|
+
onToolExecution
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
const clearStreamingText = (0, import_react.useCallback)(() => {
|
|
261
|
+
setStreamingText("");
|
|
262
|
+
setActiveTools([]);
|
|
263
|
+
}, []);
|
|
264
|
+
return { session: sessionRef.current, permissionRequest, streamingText, clearStreamingText, activeTools };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/ui/hooks/useMessages.ts
|
|
268
|
+
var import_react2 = require("react");
|
|
269
|
+
var msgIdCounter = 0;
|
|
270
|
+
function nextId() {
|
|
271
|
+
msgIdCounter += 1;
|
|
272
|
+
return `msg_${msgIdCounter}`;
|
|
273
|
+
}
|
|
274
|
+
function useMessages() {
|
|
275
|
+
const [messages, setMessages] = (0, import_react2.useState)([]);
|
|
276
|
+
const addMessage = (0, import_react2.useCallback)((msg) => {
|
|
277
|
+
setMessages((prev) => [...prev, { ...msg, id: nextId(), timestamp: /* @__PURE__ */ new Date() }]);
|
|
278
|
+
}, []);
|
|
279
|
+
return { messages, setMessages, addMessage };
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// src/ui/hooks/useSlashCommands.ts
|
|
283
|
+
var import_react3 = require("react");
|
|
169
284
|
|
|
170
285
|
// src/commands/slash-executor.ts
|
|
171
286
|
var VALID_MODES2 = ["plan", "default", "acceptEdits", "bypassPermissions"];
|
|
@@ -290,9 +405,133 @@ async function executeSlashCommand(cmd, args, session, addMessage, clearMessages
|
|
|
290
405
|
}
|
|
291
406
|
}
|
|
292
407
|
|
|
293
|
-
// src/ui/
|
|
294
|
-
var
|
|
295
|
-
|
|
408
|
+
// src/ui/hooks/useSlashCommands.ts
|
|
409
|
+
var EXIT_DELAY_MS = 500;
|
|
410
|
+
function useSlashCommands(session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId) {
|
|
411
|
+
return (0, import_react3.useCallback)(
|
|
412
|
+
async (input) => {
|
|
413
|
+
const parts = input.slice(1).split(/\s+/);
|
|
414
|
+
const cmd = parts[0]?.toLowerCase() ?? "";
|
|
415
|
+
const args = parts.slice(1).join(" ");
|
|
416
|
+
const clearMessages = () => setMessages([]);
|
|
417
|
+
const result = await executeSlashCommand(cmd, args, session, addMessage, clearMessages, registry);
|
|
418
|
+
if (result.pendingModelId) {
|
|
419
|
+
pendingModelChangeRef.current = result.pendingModelId;
|
|
420
|
+
setPendingModelId(result.pendingModelId);
|
|
421
|
+
}
|
|
422
|
+
if (result.exitRequested) {
|
|
423
|
+
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
424
|
+
}
|
|
425
|
+
return result.handled;
|
|
426
|
+
},
|
|
427
|
+
[session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId]
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// src/ui/hooks/useSubmitHandler.ts
|
|
432
|
+
var import_react4 = require("react");
|
|
433
|
+
|
|
434
|
+
// src/utils/tool-call-extractor.ts
|
|
435
|
+
var TOOL_ARG_MAX_LENGTH = 80;
|
|
436
|
+
var TOOL_ARG_TRUNCATE_LENGTH = 77;
|
|
437
|
+
function extractToolCalls(history, startIndex) {
|
|
438
|
+
const lines = [];
|
|
439
|
+
for (let i = startIndex; i < history.length; i++) {
|
|
440
|
+
const msg = history[i];
|
|
441
|
+
if (msg.role === "assistant" && msg.toolCalls) {
|
|
442
|
+
for (const tc of msg.toolCalls) {
|
|
443
|
+
const value = parseFirstArgValue(tc.function.arguments);
|
|
444
|
+
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_TRUNCATE_LENGTH) + "..." : value;
|
|
445
|
+
lines.push(`${tc.function.name}(${truncated})`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return lines;
|
|
450
|
+
}
|
|
451
|
+
function parseFirstArgValue(argsJson) {
|
|
452
|
+
try {
|
|
453
|
+
const parsed = JSON.parse(argsJson);
|
|
454
|
+
const firstVal = Object.values(parsed)[0];
|
|
455
|
+
return typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
|
|
456
|
+
} catch {
|
|
457
|
+
return argsJson;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// src/utils/skill-prompt.ts
|
|
462
|
+
function buildSkillPrompt(input, registry) {
|
|
463
|
+
const parts = input.slice(1).split(/\s+/);
|
|
464
|
+
const cmd = parts[0]?.toLowerCase() ?? "";
|
|
465
|
+
const skillCmd = registry.getCommands().find((c) => c.name === cmd && c.source === "skill");
|
|
466
|
+
if (!skillCmd) return null;
|
|
467
|
+
const args = parts.slice(1).join(" ").trim();
|
|
468
|
+
const userInstruction = args || skillCmd.description;
|
|
469
|
+
if (skillCmd.skillContent) {
|
|
470
|
+
return `<skill name="${cmd}">
|
|
471
|
+
${skillCmd.skillContent}
|
|
472
|
+
</skill>
|
|
473
|
+
|
|
474
|
+
Execute the "${cmd}" skill: ${userInstruction}`;
|
|
475
|
+
}
|
|
476
|
+
return `Use the "${cmd}" skill: ${userInstruction}`;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// src/ui/hooks/useSubmitHandler.ts
|
|
480
|
+
function syncContextState(session, setter) {
|
|
481
|
+
const ctx = session.getContextState();
|
|
482
|
+
setter({ percentage: ctx.usedPercentage, usedTokens: ctx.usedTokens, maxTokens: ctx.maxTokens });
|
|
483
|
+
}
|
|
484
|
+
async function runSessionPrompt(prompt, session, addMessage, clearStreamingText, setIsThinking, setContextState) {
|
|
485
|
+
setIsThinking(true);
|
|
486
|
+
clearStreamingText();
|
|
487
|
+
const historyBefore = session.getHistory().length;
|
|
488
|
+
try {
|
|
489
|
+
const response = await session.run(prompt);
|
|
490
|
+
clearStreamingText();
|
|
491
|
+
const history = session.getHistory();
|
|
492
|
+
const toolLines = extractToolCalls(
|
|
493
|
+
history,
|
|
494
|
+
historyBefore
|
|
495
|
+
);
|
|
496
|
+
if (toolLines.length > 0) {
|
|
497
|
+
addMessage({ role: "tool", content: toolLines.join("\n"), toolName: `${toolLines.length} tools` });
|
|
498
|
+
}
|
|
499
|
+
addMessage({ role: "assistant", content: response || "(empty response)" });
|
|
500
|
+
syncContextState(session, setContextState);
|
|
501
|
+
} catch (err) {
|
|
502
|
+
clearStreamingText();
|
|
503
|
+
if (err instanceof DOMException && err.name === "AbortError") {
|
|
504
|
+
addMessage({ role: "system", content: "Cancelled." });
|
|
505
|
+
} else {
|
|
506
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
507
|
+
addMessage({ role: "system", content: `Error: ${errMsg}` });
|
|
508
|
+
}
|
|
509
|
+
} finally {
|
|
510
|
+
setIsThinking(false);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamingText, setIsThinking, setContextState, registry) {
|
|
514
|
+
return (0, import_react4.useCallback)(
|
|
515
|
+
async (input) => {
|
|
516
|
+
if (input.startsWith("/")) {
|
|
517
|
+
const handled = await handleSlashCommand(input);
|
|
518
|
+
if (handled) {
|
|
519
|
+
syncContextState(session, setContextState);
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
const prompt = buildSkillPrompt(input, registry);
|
|
523
|
+
if (!prompt) return;
|
|
524
|
+
return runSessionPrompt(prompt, session, addMessage, clearStreamingText, setIsThinking, setContextState);
|
|
525
|
+
}
|
|
526
|
+
addMessage({ role: "user", content: input });
|
|
527
|
+
return runSessionPrompt(input, session, addMessage, clearStreamingText, setIsThinking, setContextState);
|
|
528
|
+
},
|
|
529
|
+
[session, addMessage, handleSlashCommand, clearStreamingText, setIsThinking, setContextState, registry]
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// src/ui/hooks/useCommandRegistry.ts
|
|
534
|
+
var import_react5 = require("react");
|
|
296
535
|
|
|
297
536
|
// src/commands/command-registry.ts
|
|
298
537
|
var CommandRegistry = class {
|
|
@@ -446,6 +685,18 @@ var SkillCommandSource = class {
|
|
|
446
685
|
}
|
|
447
686
|
};
|
|
448
687
|
|
|
688
|
+
// src/ui/hooks/useCommandRegistry.ts
|
|
689
|
+
function useCommandRegistry(cwd) {
|
|
690
|
+
const registryRef = (0, import_react5.useRef)(null);
|
|
691
|
+
if (registryRef.current === null) {
|
|
692
|
+
const registry = new CommandRegistry();
|
|
693
|
+
registry.addSource(new BuiltinCommandSource());
|
|
694
|
+
registry.addSource(new SkillCommandSource(cwd));
|
|
695
|
+
registryRef.current = registry;
|
|
696
|
+
}
|
|
697
|
+
return registryRef.current;
|
|
698
|
+
}
|
|
699
|
+
|
|
449
700
|
// src/ui/MessageList.tsx
|
|
450
701
|
var import_ink = require("ink");
|
|
451
702
|
|
|
@@ -566,11 +817,11 @@ function StatusBar({
|
|
|
566
817
|
}
|
|
567
818
|
|
|
568
819
|
// src/ui/InputArea.tsx
|
|
569
|
-
var
|
|
820
|
+
var import_react8 = __toESM(require("react"), 1);
|
|
570
821
|
var import_ink6 = require("ink");
|
|
571
822
|
|
|
572
823
|
// src/ui/CjkTextInput.tsx
|
|
573
|
-
var
|
|
824
|
+
var import_react6 = require("react");
|
|
574
825
|
var import_ink3 = require("ink");
|
|
575
826
|
var import_chalk = __toESM(require("chalk"), 1);
|
|
576
827
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
@@ -590,9 +841,9 @@ function CjkTextInput({
|
|
|
590
841
|
focus = true,
|
|
591
842
|
showCursor = true
|
|
592
843
|
}) {
|
|
593
|
-
const valueRef = (0,
|
|
594
|
-
const cursorRef = (0,
|
|
595
|
-
const [, forceRender] = (0,
|
|
844
|
+
const valueRef = (0, import_react6.useRef)(value);
|
|
845
|
+
const cursorRef = (0, import_react6.useRef)(value.length);
|
|
846
|
+
const [, forceRender] = (0, import_react6.useState)(0);
|
|
596
847
|
if (value !== valueRef.current) {
|
|
597
848
|
valueRef.current = value;
|
|
598
849
|
if (cursorRef.current > value.length) {
|
|
@@ -669,15 +920,15 @@ function renderWithCursor(value, cursorOffset, placeholder, showCursor) {
|
|
|
669
920
|
}
|
|
670
921
|
|
|
671
922
|
// src/ui/WaveText.tsx
|
|
672
|
-
var
|
|
923
|
+
var import_react7 = require("react");
|
|
673
924
|
var import_ink4 = require("ink");
|
|
674
925
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
675
926
|
var WAVE_COLORS = ["#666666", "#888888", "#aaaaaa", "#888888"];
|
|
676
927
|
var INTERVAL_MS = 400;
|
|
677
928
|
var CHARS_PER_GROUP = 4;
|
|
678
929
|
function WaveText({ text }) {
|
|
679
|
-
const [tick, setTick] = (0,
|
|
680
|
-
(0,
|
|
930
|
+
const [tick, setTick] = (0, import_react7.useState)(0);
|
|
931
|
+
(0, import_react7.useEffect)(() => {
|
|
681
932
|
const timer = setInterval(() => {
|
|
682
933
|
setTick((prev) => prev + 1);
|
|
683
934
|
}, INTERVAL_MS);
|
|
@@ -743,16 +994,16 @@ function parseSlashInput(value) {
|
|
|
743
994
|
return { isSlash: true, parentCommand: parent, filter: rest };
|
|
744
995
|
}
|
|
745
996
|
function useAutocomplete(value, registry) {
|
|
746
|
-
const [selectedIndex, setSelectedIndex] = (0,
|
|
747
|
-
const [dismissed, setDismissed] = (0,
|
|
748
|
-
const prevValueRef =
|
|
997
|
+
const [selectedIndex, setSelectedIndex] = (0, import_react8.useState)(0);
|
|
998
|
+
const [dismissed, setDismissed] = (0, import_react8.useState)(false);
|
|
999
|
+
const prevValueRef = import_react8.default.useRef(value);
|
|
749
1000
|
if (prevValueRef.current !== value) {
|
|
750
1001
|
prevValueRef.current = value;
|
|
751
1002
|
if (dismissed) setDismissed(false);
|
|
752
1003
|
}
|
|
753
1004
|
const parsed = parseSlashInput(value);
|
|
754
1005
|
const isSubcommandMode = parsed.isSlash && parsed.parentCommand.length > 0;
|
|
755
|
-
const filteredCommands = (0,
|
|
1006
|
+
const filteredCommands = (0, import_react8.useMemo)(() => {
|
|
756
1007
|
if (!registry || !parsed.isSlash || dismissed) return [];
|
|
757
1008
|
if (isSubcommandMode) {
|
|
758
1009
|
const subs = registry.getSubcommands(parsed.parentCommand);
|
|
@@ -786,7 +1037,7 @@ function useAutocomplete(value, registry) {
|
|
|
786
1037
|
};
|
|
787
1038
|
}
|
|
788
1039
|
function InputArea({ onSubmit, isDisabled, registry }) {
|
|
789
|
-
const [value, setValue] = (0,
|
|
1040
|
+
const [value, setValue] = (0, import_react8.useState)("");
|
|
790
1041
|
const {
|
|
791
1042
|
showPopup,
|
|
792
1043
|
filteredCommands,
|
|
@@ -795,7 +1046,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
795
1046
|
isSubcommandMode,
|
|
796
1047
|
setShowPopup
|
|
797
1048
|
} = useAutocomplete(value, registry);
|
|
798
|
-
const handleSubmit = (0,
|
|
1049
|
+
const handleSubmit = (0, import_react8.useCallback)(
|
|
799
1050
|
(text) => {
|
|
800
1051
|
const trimmed = text.trim();
|
|
801
1052
|
if (trimmed.length === 0) return;
|
|
@@ -808,7 +1059,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
808
1059
|
},
|
|
809
1060
|
[showPopup, filteredCommands, selectedIndex, onSubmit]
|
|
810
1061
|
);
|
|
811
|
-
const selectCommand = (0,
|
|
1062
|
+
const selectCommand = (0, import_react8.useCallback)(
|
|
812
1063
|
(cmd) => {
|
|
813
1064
|
const parsed = parseSlashInput(value);
|
|
814
1065
|
if (parsed.parentCommand) {
|
|
@@ -869,7 +1120,7 @@ function InputArea({ onSubmit, isDisabled, registry }) {
|
|
|
869
1120
|
}
|
|
870
1121
|
|
|
871
1122
|
// src/ui/ConfirmPrompt.tsx
|
|
872
|
-
var
|
|
1123
|
+
var import_react9 = require("react");
|
|
873
1124
|
var import_ink7 = require("ink");
|
|
874
1125
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
875
1126
|
function ConfirmPrompt({
|
|
@@ -877,9 +1128,9 @@ function ConfirmPrompt({
|
|
|
877
1128
|
options = ["Yes", "No"],
|
|
878
1129
|
onSelect
|
|
879
1130
|
}) {
|
|
880
|
-
const [selected, setSelected] = (0,
|
|
881
|
-
const resolvedRef = (0,
|
|
882
|
-
const doSelect = (0,
|
|
1131
|
+
const [selected, setSelected] = (0, import_react9.useState)(0);
|
|
1132
|
+
const resolvedRef = (0, import_react9.useRef)(false);
|
|
1133
|
+
const doSelect = (0, import_react9.useCallback)(
|
|
883
1134
|
(index) => {
|
|
884
1135
|
if (resolvedRef.current) return;
|
|
885
1136
|
resolvedRef.current = true;
|
|
@@ -912,7 +1163,7 @@ function ConfirmPrompt({
|
|
|
912
1163
|
}
|
|
913
1164
|
|
|
914
1165
|
// src/ui/PermissionPrompt.tsx
|
|
915
|
-
var
|
|
1166
|
+
var import_react10 = __toESM(require("react"), 1);
|
|
916
1167
|
var import_ink8 = require("ink");
|
|
917
1168
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
918
1169
|
var OPTIONS = ["Allow", "Allow always (this session)", "Deny"];
|
|
@@ -922,15 +1173,15 @@ function formatArgs(args) {
|
|
|
922
1173
|
return entries.map(([k, v]) => `${k}: ${typeof v === "string" ? v : JSON.stringify(v)}`).join(", ");
|
|
923
1174
|
}
|
|
924
1175
|
function PermissionPrompt({ request }) {
|
|
925
|
-
const [selected, setSelected] =
|
|
926
|
-
const resolvedRef =
|
|
927
|
-
const prevRequestRef =
|
|
1176
|
+
const [selected, setSelected] = import_react10.default.useState(0);
|
|
1177
|
+
const resolvedRef = import_react10.default.useRef(false);
|
|
1178
|
+
const prevRequestRef = import_react10.default.useRef(request);
|
|
928
1179
|
if (prevRequestRef.current !== request) {
|
|
929
1180
|
prevRequestRef.current = request;
|
|
930
1181
|
resolvedRef.current = false;
|
|
931
1182
|
setSelected(0);
|
|
932
1183
|
}
|
|
933
|
-
const doResolve =
|
|
1184
|
+
const doResolve = import_react10.default.useCallback(
|
|
934
1185
|
(index) => {
|
|
935
1186
|
if (resolvedRef.current) return;
|
|
936
1187
|
resolvedRef.current = true;
|
|
@@ -975,254 +1226,54 @@ function PermissionPrompt({ request }) {
|
|
|
975
1226
|
] });
|
|
976
1227
|
}
|
|
977
1228
|
|
|
978
|
-
// src/
|
|
979
|
-
var
|
|
980
|
-
var TOOL_ARG_TRUNCATE_LENGTH = 77;
|
|
981
|
-
function extractToolCalls(history, startIndex) {
|
|
982
|
-
const lines = [];
|
|
983
|
-
for (let i = startIndex; i < history.length; i++) {
|
|
984
|
-
const msg = history[i];
|
|
985
|
-
if (msg.role === "assistant" && msg.toolCalls) {
|
|
986
|
-
for (const tc of msg.toolCalls) {
|
|
987
|
-
const value = parseFirstArgValue(tc.function.arguments);
|
|
988
|
-
const truncated = value.length > TOOL_ARG_MAX_LENGTH ? value.slice(0, TOOL_ARG_TRUNCATE_LENGTH) + "..." : value;
|
|
989
|
-
lines.push(`${tc.function.name}(${truncated})`);
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
}
|
|
993
|
-
return lines;
|
|
994
|
-
}
|
|
995
|
-
function parseFirstArgValue(argsJson) {
|
|
996
|
-
try {
|
|
997
|
-
const parsed = JSON.parse(argsJson);
|
|
998
|
-
const firstVal = Object.values(parsed)[0];
|
|
999
|
-
return typeof firstVal === "string" ? firstVal : JSON.stringify(firstVal);
|
|
1000
|
-
} catch {
|
|
1001
|
-
return argsJson;
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
// src/ui/App.tsx
|
|
1229
|
+
// src/ui/StreamingIndicator.tsx
|
|
1230
|
+
var import_ink9 = require("ink");
|
|
1006
1231
|
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
}
|
|
1012
|
-
var NOOP_TERMINAL = {
|
|
1013
|
-
write: () => {
|
|
1014
|
-
},
|
|
1015
|
-
writeLine: () => {
|
|
1016
|
-
},
|
|
1017
|
-
writeMarkdown: () => {
|
|
1018
|
-
},
|
|
1019
|
-
writeError: () => {
|
|
1020
|
-
},
|
|
1021
|
-
prompt: () => Promise.resolve(""),
|
|
1022
|
-
select: () => Promise.resolve(0),
|
|
1023
|
-
spinner: () => ({ stop: () => {
|
|
1024
|
-
}, update: () => {
|
|
1025
|
-
} })
|
|
1026
|
-
};
|
|
1027
|
-
function useSession(props) {
|
|
1028
|
-
const [permissionRequest, setPermissionRequest] = (0, import_react6.useState)(null);
|
|
1029
|
-
const [streamingText, setStreamingText] = (0, import_react6.useState)("");
|
|
1030
|
-
const permissionQueueRef = (0, import_react6.useRef)([]);
|
|
1031
|
-
const processingRef = (0, import_react6.useRef)(false);
|
|
1032
|
-
const processNextPermission = (0, import_react6.useCallback)(() => {
|
|
1033
|
-
if (processingRef.current) return;
|
|
1034
|
-
const next = permissionQueueRef.current[0];
|
|
1035
|
-
if (!next) {
|
|
1036
|
-
setPermissionRequest(null);
|
|
1037
|
-
return;
|
|
1038
|
-
}
|
|
1039
|
-
processingRef.current = true;
|
|
1040
|
-
setPermissionRequest({
|
|
1041
|
-
toolName: next.toolName,
|
|
1042
|
-
toolArgs: next.toolArgs,
|
|
1043
|
-
resolve: (result) => {
|
|
1044
|
-
permissionQueueRef.current.shift();
|
|
1045
|
-
processingRef.current = false;
|
|
1046
|
-
setPermissionRequest(null);
|
|
1047
|
-
next.resolve(result);
|
|
1048
|
-
setTimeout(() => processNextPermission(), 0);
|
|
1049
|
-
}
|
|
1050
|
-
});
|
|
1051
|
-
}, []);
|
|
1052
|
-
const sessionRef = (0, import_react6.useRef)(null);
|
|
1053
|
-
if (sessionRef.current === null) {
|
|
1054
|
-
const permissionHandler = (toolName, toolArgs) => {
|
|
1055
|
-
return new Promise((resolve) => {
|
|
1056
|
-
permissionQueueRef.current.push({ toolName, toolArgs, resolve });
|
|
1057
|
-
processNextPermission();
|
|
1058
|
-
});
|
|
1059
|
-
};
|
|
1060
|
-
const onTextDelta = (delta) => {
|
|
1061
|
-
setStreamingText((prev) => prev + delta);
|
|
1062
|
-
};
|
|
1063
|
-
const paths = (0, import_agent_sdk.projectPaths)(props.cwd ?? process.cwd());
|
|
1064
|
-
sessionRef.current = (0, import_agent_sdk.createSession)({
|
|
1065
|
-
config: props.config,
|
|
1066
|
-
context: props.context,
|
|
1067
|
-
terminal: NOOP_TERMINAL,
|
|
1068
|
-
sessionLogger: new import_agent_sdk.FileSessionLogger(paths.logs),
|
|
1069
|
-
projectInfo: props.projectInfo,
|
|
1070
|
-
sessionStore: props.sessionStore,
|
|
1071
|
-
permissionMode: props.permissionMode,
|
|
1072
|
-
maxTurns: props.maxTurns,
|
|
1073
|
-
permissionHandler,
|
|
1074
|
-
onTextDelta
|
|
1075
|
-
});
|
|
1232
|
+
function StreamingIndicator({ text, activeTools }) {
|
|
1233
|
+
const hasTools = activeTools.length > 0;
|
|
1234
|
+
const hasText = text.length > 0;
|
|
1235
|
+
if (!hasTools && !hasText) {
|
|
1236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "yellow", children: "Thinking..." });
|
|
1076
1237
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
}
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
const args = parts.slice(1).join(" ");
|
|
1094
|
-
const clearMessages = () => setMessages([]);
|
|
1095
|
-
const result = await executeSlashCommand(cmd, args, session, addMessage, clearMessages, registry);
|
|
1096
|
-
if (result.pendingModelId) {
|
|
1097
|
-
pendingModelChangeRef.current = result.pendingModelId;
|
|
1098
|
-
setPendingModelId(result.pendingModelId);
|
|
1099
|
-
}
|
|
1100
|
-
if (result.exitRequested) {
|
|
1101
|
-
setTimeout(() => exit(), EXIT_DELAY_MS);
|
|
1102
|
-
}
|
|
1103
|
-
return result.handled;
|
|
1104
|
-
},
|
|
1105
|
-
[session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId]
|
|
1106
|
-
);
|
|
1107
|
-
}
|
|
1108
|
-
function StreamingIndicator({ text }) {
|
|
1109
|
-
if (text) {
|
|
1110
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", children: [
|
|
1111
|
-
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Text, { color: "cyan", bold: true, children: [
|
|
1112
|
-
"Robota:",
|
|
1113
|
-
" "
|
|
1114
|
-
] }),
|
|
1238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", children: [
|
|
1239
|
+
hasTools && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1240
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "gray", bold: true, children: "Tools:" }),
|
|
1241
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { children: " " }),
|
|
1242
|
+
activeTools.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Text, { color: t.isRunning ? "yellow" : "green", children: [
|
|
1243
|
+
" ",
|
|
1244
|
+
t.isRunning ? "\u27F3" : "\u2713",
|
|
1245
|
+
" ",
|
|
1246
|
+
t.toolName,
|
|
1247
|
+
"(",
|
|
1248
|
+
t.firstArg,
|
|
1249
|
+
")"
|
|
1250
|
+
] }, `${t.toolName}-${i}`))
|
|
1251
|
+
] }),
|
|
1252
|
+
hasText && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_ink9.Box, { flexDirection: "column", marginBottom: 1, children: [
|
|
1253
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "cyan", bold: true, children: "Robota:" }),
|
|
1115
1254
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { children: " " }),
|
|
1116
1255
|
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Box, { marginLeft: 2, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { wrap: "wrap", children: renderMarkdown(text) }) })
|
|
1117
|
-
] })
|
|
1118
|
-
}
|
|
1119
|
-
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_ink9.Text, { color: "yellow", children: "Thinking..." });
|
|
1120
|
-
}
|
|
1121
|
-
async function runSessionPrompt(prompt, session, addMessage, clearStreamingText, setIsThinking, setContextPercentage) {
|
|
1122
|
-
setIsThinking(true);
|
|
1123
|
-
clearStreamingText();
|
|
1124
|
-
const historyBefore = session.getHistory().length;
|
|
1125
|
-
try {
|
|
1126
|
-
const response = await session.run(prompt);
|
|
1127
|
-
clearStreamingText();
|
|
1128
|
-
const history = session.getHistory();
|
|
1129
|
-
const toolLines = extractToolCalls(
|
|
1130
|
-
history,
|
|
1131
|
-
historyBefore
|
|
1132
|
-
);
|
|
1133
|
-
if (toolLines.length > 0) {
|
|
1134
|
-
addMessage({ role: "tool", content: toolLines.join("\n"), toolName: `${toolLines.length} tools` });
|
|
1135
|
-
}
|
|
1136
|
-
addMessage({ role: "assistant", content: response || "(empty response)" });
|
|
1137
|
-
setContextPercentage(session.getContextState().usedPercentage);
|
|
1138
|
-
} catch (err) {
|
|
1139
|
-
clearStreamingText();
|
|
1140
|
-
if (err instanceof DOMException && err.name === "AbortError") {
|
|
1141
|
-
addMessage({ role: "system", content: "Cancelled." });
|
|
1142
|
-
} else {
|
|
1143
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
1144
|
-
addMessage({ role: "system", content: `Error: ${errMsg}` });
|
|
1145
|
-
}
|
|
1146
|
-
} finally {
|
|
1147
|
-
setIsThinking(false);
|
|
1148
|
-
}
|
|
1256
|
+
] })
|
|
1257
|
+
] });
|
|
1149
1258
|
}
|
|
1150
|
-
function buildSkillPrompt(input, registry) {
|
|
1151
|
-
const parts = input.slice(1).split(/\s+/);
|
|
1152
|
-
const cmd = parts[0]?.toLowerCase() ?? "";
|
|
1153
|
-
const skillCmd = registry.getCommands().find((c) => c.name === cmd && c.source === "skill");
|
|
1154
|
-
if (!skillCmd) return null;
|
|
1155
|
-
const args = parts.slice(1).join(" ").trim();
|
|
1156
|
-
const userInstruction = args || skillCmd.description;
|
|
1157
|
-
if (skillCmd.skillContent) {
|
|
1158
|
-
return `<skill name="${cmd}">
|
|
1159
|
-
${skillCmd.skillContent}
|
|
1160
|
-
</skill>
|
|
1161
1259
|
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
}
|
|
1166
|
-
function useSubmitHandler(session, addMessage, handleSlashCommand, clearStreamingText, setIsThinking, setContextPercentage, registry) {
|
|
1167
|
-
return (0, import_react6.useCallback)(
|
|
1168
|
-
async (input) => {
|
|
1169
|
-
if (input.startsWith("/")) {
|
|
1170
|
-
const handled = await handleSlashCommand(input);
|
|
1171
|
-
if (handled) {
|
|
1172
|
-
setContextPercentage(session.getContextState().usedPercentage);
|
|
1173
|
-
return;
|
|
1174
|
-
}
|
|
1175
|
-
const prompt = buildSkillPrompt(input, registry);
|
|
1176
|
-
if (!prompt) return;
|
|
1177
|
-
return runSessionPrompt(
|
|
1178
|
-
prompt,
|
|
1179
|
-
session,
|
|
1180
|
-
addMessage,
|
|
1181
|
-
clearStreamingText,
|
|
1182
|
-
setIsThinking,
|
|
1183
|
-
setContextPercentage
|
|
1184
|
-
);
|
|
1185
|
-
}
|
|
1186
|
-
addMessage({ role: "user", content: input });
|
|
1187
|
-
return runSessionPrompt(
|
|
1188
|
-
input,
|
|
1189
|
-
session,
|
|
1190
|
-
addMessage,
|
|
1191
|
-
clearStreamingText,
|
|
1192
|
-
setIsThinking,
|
|
1193
|
-
setContextPercentage
|
|
1194
|
-
);
|
|
1195
|
-
},
|
|
1196
|
-
[
|
|
1197
|
-
session,
|
|
1198
|
-
addMessage,
|
|
1199
|
-
handleSlashCommand,
|
|
1200
|
-
clearStreamingText,
|
|
1201
|
-
setIsThinking,
|
|
1202
|
-
setContextPercentage,
|
|
1203
|
-
registry
|
|
1204
|
-
]
|
|
1205
|
-
);
|
|
1206
|
-
}
|
|
1207
|
-
function useCommandRegistry(cwd) {
|
|
1208
|
-
const registryRef = (0, import_react6.useRef)(null);
|
|
1209
|
-
if (registryRef.current === null) {
|
|
1210
|
-
const registry = new CommandRegistry();
|
|
1211
|
-
registry.addSource(new BuiltinCommandSource());
|
|
1212
|
-
registry.addSource(new SkillCommandSource(cwd));
|
|
1213
|
-
registryRef.current = registry;
|
|
1214
|
-
}
|
|
1215
|
-
return registryRef.current;
|
|
1216
|
-
}
|
|
1260
|
+
// src/ui/App.tsx
|
|
1261
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1262
|
+
var EXIT_DELAY_MS2 = 500;
|
|
1217
1263
|
function App(props) {
|
|
1218
|
-
const { exit } = (0,
|
|
1219
|
-
const { session, permissionRequest, streamingText, clearStreamingText } = useSession(props);
|
|
1264
|
+
const { exit } = (0, import_ink10.useApp)();
|
|
1265
|
+
const { session, permissionRequest, streamingText, clearStreamingText, activeTools } = useSession(props);
|
|
1220
1266
|
const { messages, setMessages, addMessage } = useMessages();
|
|
1221
|
-
const [isThinking, setIsThinking] = (0,
|
|
1222
|
-
const
|
|
1267
|
+
const [isThinking, setIsThinking] = (0, import_react11.useState)(false);
|
|
1268
|
+
const initialCtx = session.getContextState();
|
|
1269
|
+
const [contextState, setContextState] = (0, import_react11.useState)({
|
|
1270
|
+
percentage: initialCtx.usedPercentage,
|
|
1271
|
+
usedTokens: initialCtx.usedTokens,
|
|
1272
|
+
maxTokens: initialCtx.maxTokens
|
|
1273
|
+
});
|
|
1223
1274
|
const registry = useCommandRegistry(props.cwd ?? process.cwd());
|
|
1224
|
-
const pendingModelChangeRef = (0,
|
|
1225
|
-
const [pendingModelId, setPendingModelId] = (0,
|
|
1275
|
+
const pendingModelChangeRef = (0, import_react11.useRef)(null);
|
|
1276
|
+
const [pendingModelId, setPendingModelId] = (0, import_react11.useState)(null);
|
|
1226
1277
|
const handleSlashCommand = useSlashCommands(session, addMessage, setMessages, exit, registry, pendingModelChangeRef, setPendingModelId);
|
|
1227
1278
|
const handleSubmit = useSubmitHandler(
|
|
1228
1279
|
session,
|
|
@@ -1230,36 +1281,36 @@ function App(props) {
|
|
|
1230
1281
|
handleSlashCommand,
|
|
1231
1282
|
clearStreamingText,
|
|
1232
1283
|
setIsThinking,
|
|
1233
|
-
|
|
1284
|
+
setContextState,
|
|
1234
1285
|
registry
|
|
1235
1286
|
);
|
|
1236
|
-
(0,
|
|
1287
|
+
(0, import_ink10.useInput)(
|
|
1237
1288
|
(_input, key) => {
|
|
1238
1289
|
if (key.ctrl && _input === "c") exit();
|
|
1239
1290
|
if (key.escape && isThinking) session.abort();
|
|
1240
1291
|
},
|
|
1241
1292
|
{ isActive: !permissionRequest }
|
|
1242
1293
|
);
|
|
1243
|
-
return /* @__PURE__ */ (0,
|
|
1244
|
-
/* @__PURE__ */ (0,
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1294
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink10.Box, { flexDirection: "column", children: [
|
|
1295
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink10.Box, { flexDirection: "column", paddingX: 1, marginBottom: 1, children: [
|
|
1296
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink10.Text, { color: "cyan", bold: true, children: `
|
|
1246
1297
|
____ ___ ____ ___ _____ _
|
|
1247
1298
|
| _ \\ / _ \\| __ ) / _ \\_ _|/ \\
|
|
1248
1299
|
| |_) | | | | _ \\| | | || | / _ \\
|
|
1249
1300
|
| _ <| |_| | |_) | |_| || |/ ___ \\
|
|
1250
1301
|
|_| \\_\\\\___/|____/ \\___/ |_/_/ \\_\\
|
|
1251
1302
|
` }),
|
|
1252
|
-
/* @__PURE__ */ (0,
|
|
1303
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink10.Text, { dimColor: true, children: [
|
|
1253
1304
|
" v",
|
|
1254
1305
|
props.version ?? "0.0.0"
|
|
1255
1306
|
] })
|
|
1256
1307
|
] }),
|
|
1257
|
-
/* @__PURE__ */ (0,
|
|
1258
|
-
/* @__PURE__ */ (0,
|
|
1259
|
-
isThinking && /* @__PURE__ */ (0,
|
|
1308
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_ink10.Box, { flexDirection: "column", paddingX: 1, flexGrow: 1, children: [
|
|
1309
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MessageList, { messages }),
|
|
1310
|
+
isThinking && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink10.Box, { flexDirection: "column", marginBottom: 1, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(StreamingIndicator, { text: streamingText, activeTools }) })
|
|
1260
1311
|
] }),
|
|
1261
|
-
permissionRequest && /* @__PURE__ */ (0,
|
|
1262
|
-
pendingModelId && /* @__PURE__ */ (0,
|
|
1312
|
+
permissionRequest && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(PermissionPrompt, { request: permissionRequest }),
|
|
1313
|
+
pendingModelId && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1263
1314
|
ConfirmPrompt,
|
|
1264
1315
|
{
|
|
1265
1316
|
message: `Change model to ${(0, import_agent_core3.getModelName)(pendingModelId)}? This will restart the session.`,
|
|
@@ -1271,7 +1322,7 @@ function App(props) {
|
|
|
1271
1322
|
const settingsPath = getUserSettingsPath();
|
|
1272
1323
|
updateModelInSettings(settingsPath, pendingModelId);
|
|
1273
1324
|
addMessage({ role: "system", content: `Model changed to ${(0, import_agent_core3.getModelName)(pendingModelId)}. Restarting...` });
|
|
1274
|
-
setTimeout(() => exit(),
|
|
1325
|
+
setTimeout(() => exit(), EXIT_DELAY_MS2);
|
|
1275
1326
|
} catch (err) {
|
|
1276
1327
|
addMessage({ role: "system", content: `Failed: ${err instanceof Error ? err.message : String(err)}` });
|
|
1277
1328
|
}
|
|
@@ -1281,7 +1332,7 @@ function App(props) {
|
|
|
1281
1332
|
}
|
|
1282
1333
|
}
|
|
1283
1334
|
),
|
|
1284
|
-
/* @__PURE__ */ (0,
|
|
1335
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1285
1336
|
StatusBar,
|
|
1286
1337
|
{
|
|
1287
1338
|
permissionMode: session.getPermissionMode(),
|
|
@@ -1289,12 +1340,12 @@ function App(props) {
|
|
|
1289
1340
|
sessionId: session.getSessionId(),
|
|
1290
1341
|
messageCount: messages.length,
|
|
1291
1342
|
isThinking,
|
|
1292
|
-
contextPercentage,
|
|
1293
|
-
contextUsedTokens:
|
|
1294
|
-
contextMaxTokens:
|
|
1343
|
+
contextPercentage: contextState.percentage,
|
|
1344
|
+
contextUsedTokens: contextState.usedTokens,
|
|
1345
|
+
contextMaxTokens: contextState.maxTokens
|
|
1295
1346
|
}
|
|
1296
1347
|
),
|
|
1297
|
-
/* @__PURE__ */ (0,
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1298
1349
|
InputArea,
|
|
1299
1350
|
{
|
|
1300
1351
|
onSubmit: handleSubmit,
|
|
@@ -1302,12 +1353,12 @@ function App(props) {
|
|
|
1302
1353
|
registry
|
|
1303
1354
|
}
|
|
1304
1355
|
),
|
|
1305
|
-
/* @__PURE__ */ (0,
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_ink10.Text, { children: " " })
|
|
1306
1357
|
] });
|
|
1307
1358
|
}
|
|
1308
1359
|
|
|
1309
1360
|
// src/ui/render.tsx
|
|
1310
|
-
var
|
|
1361
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1311
1362
|
function renderApp(options) {
|
|
1312
1363
|
process.on("unhandledRejection", (reason) => {
|
|
1313
1364
|
process.stderr.write(`
|
|
@@ -1318,7 +1369,7 @@ function renderApp(options) {
|
|
|
1318
1369
|
`);
|
|
1319
1370
|
}
|
|
1320
1371
|
});
|
|
1321
|
-
const instance = (0,
|
|
1372
|
+
const instance = (0, import_ink11.render)(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(App, { ...options }), {
|
|
1322
1373
|
exitOnCtrlC: true
|
|
1323
1374
|
});
|
|
1324
1375
|
instance.waitUntilExit().catch((err) => {
|
|
@@ -1332,6 +1383,18 @@ function renderApp(options) {
|
|
|
1332
1383
|
|
|
1333
1384
|
// src/cli.ts
|
|
1334
1385
|
var import_meta = {};
|
|
1386
|
+
function hasValidSettingsFile(filePath) {
|
|
1387
|
+
if (!(0, import_node_fs3.existsSync)(filePath)) return false;
|
|
1388
|
+
try {
|
|
1389
|
+
const raw = (0, import_node_fs3.readFileSync)(filePath, "utf8").trim();
|
|
1390
|
+
if (raw.length === 0) return false;
|
|
1391
|
+
const parsed = JSON.parse(raw);
|
|
1392
|
+
const provider = parsed.provider;
|
|
1393
|
+
return !!provider?.apiKey;
|
|
1394
|
+
} catch {
|
|
1395
|
+
return false;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1335
1398
|
function readVersion() {
|
|
1336
1399
|
try {
|
|
1337
1400
|
const thisFile = (0, import_node_url.fileURLToPath)(import_meta.url);
|
|
@@ -1356,7 +1419,7 @@ async function ensureConfig(cwd) {
|
|
|
1356
1419
|
const userPath = getUserSettingsPath();
|
|
1357
1420
|
const projectPath = (0, import_node_path3.join)(cwd, ".robota", "settings.json");
|
|
1358
1421
|
const localPath = (0, import_node_path3.join)(cwd, ".robota", "settings.local.json");
|
|
1359
|
-
if ((
|
|
1422
|
+
if (hasValidSettingsFile(userPath) || hasValidSettingsFile(projectPath) || hasValidSettingsFile(localPath)) {
|
|
1360
1423
|
return;
|
|
1361
1424
|
}
|
|
1362
1425
|
process.stdout.write("\n");
|