ideacode 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/context.js +3 -0
- package/dist/repl.js +20 -14
- package/dist/tools/index.js +1 -1
- package/dist/ui/format.js +11 -0
- package/dist/ui/index.js +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/context.js
CHANGED
|
@@ -11,6 +11,9 @@ export function estimateTokens(messages, systemPrompt) {
|
|
|
11
11
|
chars += systemPrompt.length;
|
|
12
12
|
return Math.round(chars / 4);
|
|
13
13
|
}
|
|
14
|
+
export function estimateTokensForString(str) {
|
|
15
|
+
return Math.round(str.length / 4);
|
|
16
|
+
}
|
|
14
17
|
export async function compressState(apiKey, state, systemPrompt, model, options) {
|
|
15
18
|
const { keepLast } = options;
|
|
16
19
|
if (state.length <= keepLast)
|
package/dist/repl.js
CHANGED
|
@@ -13,10 +13,10 @@ import { getModel, saveModel, saveBraveSearchApiKey, getBraveSearchApiKey } from
|
|
|
13
13
|
import { loadConversation, saveConversation } from "./conversation.js";
|
|
14
14
|
import { callApi, fetchModels } from "./api.js";
|
|
15
15
|
import { getVersion, checkForUpdate } from "./version.js";
|
|
16
|
-
import { estimateTokens, ensureUnderBudget } from "./context.js";
|
|
16
|
+
import { estimateTokens, estimateTokensForString, ensureUnderBudget } from "./context.js";
|
|
17
17
|
import { runTool } from "./tools/index.js";
|
|
18
18
|
import { COMMANDS, matchCommand, resolveCommand } from "./commands.js";
|
|
19
|
-
import { colors, icons, separator, agentMessage, toolCallBox, toolResultLine, userPromptBox, inkColors, } from "./ui/index.js";
|
|
19
|
+
import { colors, icons, separator, agentMessage, toolCallBox, toolResultLine, toolResultTokenLine, userPromptBox, inkColors, } from "./ui/index.js";
|
|
20
20
|
function wordStartBackward(value, cursor) {
|
|
21
21
|
let i = cursor - 1;
|
|
22
22
|
while (i >= 0 && /\s/.test(value[i]))
|
|
@@ -103,11 +103,14 @@ function replayMessagesToLogLines(messages) {
|
|
|
103
103
|
const block = toolUses.find((b) => b.id === tr.tool_use_id);
|
|
104
104
|
if (block?.name) {
|
|
105
105
|
const firstVal = block.input && typeof block.input === "object" ? Object.values(block.input)[0] : undefined;
|
|
106
|
-
const argPreview = String(firstVal ?? "").slice(0, 50);
|
|
107
|
-
const
|
|
106
|
+
const argPreview = String(firstVal ?? "").slice(0, 50) || "—";
|
|
107
|
+
const content = tr.content ?? "";
|
|
108
|
+
const ok = !content.startsWith("error:");
|
|
108
109
|
lines.push(toolCallBox(block.name, argPreview, ok));
|
|
109
|
-
const preview =
|
|
110
|
+
const preview = content.split("\n")[0]?.slice(0, 60) ?? "";
|
|
110
111
|
lines.push(toolResultLine(preview, ok));
|
|
112
|
+
const tokens = estimateTokensForString(content);
|
|
113
|
+
lines.push(toolResultTokenLine(tokens, ok));
|
|
111
114
|
}
|
|
112
115
|
}
|
|
113
116
|
}
|
|
@@ -116,7 +119,7 @@ function replayMessagesToLogLines(messages) {
|
|
|
116
119
|
else if (msg.role === "assistant" && Array.isArray(msg.content)) {
|
|
117
120
|
const blocks = msg.content;
|
|
118
121
|
for (const block of blocks) {
|
|
119
|
-
if (block.type === "text" && block.text) {
|
|
122
|
+
if (block.type === "text" && block.text?.trim()) {
|
|
120
123
|
lines.push("");
|
|
121
124
|
lines.push(...agentMessage(block.text).trimEnd().split("\n"));
|
|
122
125
|
}
|
|
@@ -174,7 +177,8 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
174
177
|
messagesRef.current = messages;
|
|
175
178
|
}, [messages]);
|
|
176
179
|
useEffect(() => {
|
|
177
|
-
|
|
180
|
+
const loaded = loadConversation(cwd);
|
|
181
|
+
if (loaded.length > 0 && !hasRestoredLogRef.current) {
|
|
178
182
|
hasRestoredLogRef.current = true;
|
|
179
183
|
const model = getModel();
|
|
180
184
|
const version = getVersion();
|
|
@@ -185,9 +189,9 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
185
189
|
colors.mutedDark(" / commands ! shell @ files · Ctrl+P palette · Ctrl+C or /q to quit"),
|
|
186
190
|
"",
|
|
187
191
|
];
|
|
188
|
-
setLogLines([...banner, ...replayMessagesToLogLines(
|
|
192
|
+
setLogLines([...banner, ...replayMessagesToLogLines(loaded)]);
|
|
189
193
|
}
|
|
190
|
-
}, [
|
|
194
|
+
}, [cwd]);
|
|
191
195
|
const saveDebounceRef = useRef(null);
|
|
192
196
|
useEffect(() => {
|
|
193
197
|
if (saveDebounceRef.current)
|
|
@@ -413,7 +417,7 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
413
417
|
const toolResults = [];
|
|
414
418
|
for (let bi = 0; bi < contentBlocks.length; bi++) {
|
|
415
419
|
const block = contentBlocks[bi];
|
|
416
|
-
if (block.type === "text" && block.text) {
|
|
420
|
+
if (block.type === "text" && block.text?.trim()) {
|
|
417
421
|
appendLog("");
|
|
418
422
|
appendLog(agentMessage(block.text).trimEnd());
|
|
419
423
|
}
|
|
@@ -421,19 +425,21 @@ export function Repl({ apiKey, cwd, onQuit }) {
|
|
|
421
425
|
const toolName = block.name;
|
|
422
426
|
const toolArgs = block.input;
|
|
423
427
|
const firstVal = Object.values(toolArgs)[0];
|
|
424
|
-
const argPreview = String(firstVal ?? "").slice(0,
|
|
428
|
+
const argPreview = String(firstVal ?? "").slice(0, 100) || "—";
|
|
425
429
|
const result = await runTool(toolName, toolArgs);
|
|
426
430
|
const ok = !result.startsWith("error:");
|
|
427
431
|
appendLog(toolCallBox(toolName, argPreview, ok));
|
|
428
432
|
const resultLines = result.split("\n");
|
|
429
|
-
let preview = resultLines[0]?.slice(0,
|
|
433
|
+
let preview = resultLines[0]?.slice(0, 80) ?? "";
|
|
430
434
|
if (resultLines.length > 1)
|
|
431
435
|
preview += ` ... +${resultLines.length - 1} lines`;
|
|
432
|
-
else if (preview.length >
|
|
436
|
+
else if (preview.length > 80)
|
|
433
437
|
preview += "...";
|
|
434
438
|
appendLog(toolResultLine(preview, ok));
|
|
439
|
+
const contentForApi = truncateToolResult(result);
|
|
440
|
+
const tokens = estimateTokensForString(contentForApi);
|
|
441
|
+
appendLog(toolResultTokenLine(tokens, ok));
|
|
435
442
|
if (block.id) {
|
|
436
|
-
const contentForApi = truncateToolResult(result);
|
|
437
443
|
toolResults.push({ type: "tool_result", tool_use_id: block.id, content: contentForApi });
|
|
438
444
|
}
|
|
439
445
|
}
|
package/dist/tools/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export const TOOLS = {
|
|
|
26
26
|
grepFiles,
|
|
27
27
|
],
|
|
28
28
|
bash: [
|
|
29
|
-
"Run shell command.
|
|
29
|
+
"Run shell command. Use for things the other tools don't cover (e.g. running tests, installs, one-off commands, ephemeral << PY scripts, etc.). Always avoid dump outputs. Prefer read/grep/glob for file content and search; use targeted commands and avoid dumping huge output.",
|
|
30
30
|
{ cmd: "string" },
|
|
31
31
|
runBash,
|
|
32
32
|
],
|
package/dist/ui/format.js
CHANGED
|
@@ -90,6 +90,17 @@ export function toolResultLine(preview, success = true) {
|
|
|
90
90
|
const textColor = success ? toolSubdued : colors.toolFail;
|
|
91
91
|
return `${TOOL_INDENT}${TOOL_INDENT}${pipeColor(icons.pipe + " ")}${textColor(preview)}`;
|
|
92
92
|
}
|
|
93
|
+
function formatTokenCount(n) {
|
|
94
|
+
if (n >= 1000)
|
|
95
|
+
return (n / 1000).toFixed(1).replace(/\.0$/, "") + "K";
|
|
96
|
+
return String(n);
|
|
97
|
+
}
|
|
98
|
+
export function toolResultTokenLine(tokens, success = true) {
|
|
99
|
+
const pipeColor = success ? toolSubdued : colors.toolFail;
|
|
100
|
+
const textColor = success ? toolSubdued : colors.toolFail;
|
|
101
|
+
const tokenStr = `+${formatTokenCount(tokens)} tokens`;
|
|
102
|
+
return `${TOOL_INDENT}${TOOL_INDENT}${pipeColor(icons.pipe + " ")}${textColor(tokenStr)}`;
|
|
103
|
+
}
|
|
93
104
|
export function agentMessage(text) {
|
|
94
105
|
const rendered = renderMarkdown(text.trim());
|
|
95
106
|
return `${colors.accentPale(icons.agent)} ${rendered}`;
|
package/dist/ui/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { colors, icons, theme, inkColors, separator, agentMessage, toolCallBox, toolResultLine, userPromptBox, bashOutputLine, renderMarkdown, header, } from "./format.js";
|
|
1
|
+
export { colors, icons, theme, inkColors, separator, agentMessage, toolCallBox, toolResultLine, toolResultTokenLine, userPromptBox, bashOutputLine, renderMarkdown, header, } from "./format.js";
|
package/dist/version.js
CHANGED
|
@@ -32,7 +32,7 @@ function isNewer(latest, current) {
|
|
|
32
32
|
return false;
|
|
33
33
|
}
|
|
34
34
|
const UPDATE_CHECK_FILE = "last-update-check.json";
|
|
35
|
-
const CHECK_INTERVAL_MS =
|
|
35
|
+
const CHECK_INTERVAL_MS = 60 * 60 * 1000;
|
|
36
36
|
function shouldSkipCheck() {
|
|
37
37
|
try {
|
|
38
38
|
const file = path.join(getConfigDir(), UPDATE_CHECK_FILE);
|