ikie-cli 0.1.16 → 0.1.18
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/agent.d.ts +5 -0
- package/dist/agent.js +20 -2
- package/dist/repl.js +24 -7
- package/dist/theme.d.ts +1 -1
- package/dist/theme.js +1 -1
- package/package.json +1 -1
package/dist/agent.d.ts
CHANGED
|
@@ -15,6 +15,11 @@ export interface AgentTurnStats {
|
|
|
15
15
|
filesChanged: number;
|
|
16
16
|
}
|
|
17
17
|
export declare function estimateTokens(chars: number): number;
|
|
18
|
+
/**
|
|
19
|
+
* Extract the most useful upstream error message from an OpenAI SDK error.
|
|
20
|
+
* The SDK wraps provider responses; we prefer the nested error.message if it exists.
|
|
21
|
+
*/
|
|
22
|
+
export declare function extractUpstreamError(err: unknown): string;
|
|
18
23
|
/**
|
|
19
24
|
* Safely restore previously-saved stdin listeners after a raw-mode interaction
|
|
20
25
|
* (permission prompt, ask_user, theme picker, agent turn).
|
package/dist/agent.js
CHANGED
|
@@ -6,6 +6,20 @@ import { c, toolLine, permissionPrompt, toolSuccessLine, toolErrorLine, toolOutp
|
|
|
6
6
|
export function estimateTokens(chars) {
|
|
7
7
|
return Math.max(1, Math.round(chars / 4));
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Extract the most useful upstream error message from an OpenAI SDK error.
|
|
11
|
+
* The SDK wraps provider responses; we prefer the nested error.message if it exists.
|
|
12
|
+
*/
|
|
13
|
+
export function extractUpstreamError(err) {
|
|
14
|
+
if (!(err instanceof Error))
|
|
15
|
+
return String(err);
|
|
16
|
+
// OpenAI SDK v4 error shape: error.error?.message or error.message
|
|
17
|
+
const e = err;
|
|
18
|
+
const upstream = e.error?.message ||
|
|
19
|
+
e.response?.data?.error?.message ||
|
|
20
|
+
e.message;
|
|
21
|
+
return upstream || 'Unknown error';
|
|
22
|
+
}
|
|
9
23
|
/**
|
|
10
24
|
* Safely restore previously-saved stdin listeners after a raw-mode interaction
|
|
11
25
|
* (permission prompt, ask_user, theme picker, agent turn).
|
|
@@ -380,7 +394,7 @@ export class Agent {
|
|
|
380
394
|
}
|
|
381
395
|
catch (err) {
|
|
382
396
|
spinner.stop();
|
|
383
|
-
throw err;
|
|
397
|
+
throw new Error(extractUpstreamError(err));
|
|
384
398
|
}
|
|
385
399
|
let textContent = '';
|
|
386
400
|
let thinkingContent = '';
|
|
@@ -446,7 +460,7 @@ export class Agent {
|
|
|
446
460
|
// user cancelled — swallow
|
|
447
461
|
}
|
|
448
462
|
else {
|
|
449
|
-
throw err;
|
|
463
|
+
throw new Error(extractUpstreamError(err));
|
|
450
464
|
}
|
|
451
465
|
}
|
|
452
466
|
finally {
|
|
@@ -482,6 +496,10 @@ export class Agent {
|
|
|
482
496
|
...this.buildParams(),
|
|
483
497
|
}, requestOpts);
|
|
484
498
|
}
|
|
499
|
+
catch (err) {
|
|
500
|
+
spinner.stop();
|
|
501
|
+
throw new Error(extractUpstreamError(err));
|
|
502
|
+
}
|
|
485
503
|
finally {
|
|
486
504
|
spinner.stop();
|
|
487
505
|
}
|
package/dist/repl.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as readline from 'node:readline';
|
|
2
2
|
import { execSync, exec } from 'child_process';
|
|
3
|
-
import { restoreStdinListeners } from './agent.js';
|
|
3
|
+
import { restoreStdinListeners, extractUpstreamError } from './agent.js';
|
|
4
4
|
import { c, PROMPT, CONTINUE_PROMPT, PROMPT_ARROW, printPromptHeader, modeTag, drawBanner, infoLine, successLine, errorLine, THEMES, setTheme, stripAnsi, contextRing, renderSlashMenu, } from './theme.js';
|
|
5
5
|
import { renderMarkdown } from './renderer.js';
|
|
6
6
|
import { loadAllMemory } from './memory.js';
|
|
@@ -615,6 +615,19 @@ async function handleSlashCommand(input, agent, config, projectContext, rl, sess
|
|
|
615
615
|
return true;
|
|
616
616
|
}
|
|
617
617
|
}
|
|
618
|
+
function fmtReset(resetAt) {
|
|
619
|
+
if (!resetAt)
|
|
620
|
+
return 'not started';
|
|
621
|
+
const ms = resetAt - Date.now();
|
|
622
|
+
if (ms <= 0)
|
|
623
|
+
return 'now';
|
|
624
|
+
const mins = Math.ceil(ms / 60000);
|
|
625
|
+
const h = Math.floor(mins / 60);
|
|
626
|
+
const m = mins % 60;
|
|
627
|
+
if (h >= 24)
|
|
628
|
+
return `${Math.floor(h / 24)}d ${h % 24}h`;
|
|
629
|
+
return h > 0 ? `${h}h ${m}m` : `${m}m`;
|
|
630
|
+
}
|
|
618
631
|
function fmtUsd(n) {
|
|
619
632
|
if (n === 0)
|
|
620
633
|
return '$0.00';
|
|
@@ -633,7 +646,11 @@ function printUsage(data) {
|
|
|
633
646
|
const s = data.stats;
|
|
634
647
|
const row = (label, value) => console.log(` ${c.secondary(label.padEnd(18))} ${c.white(value)}`);
|
|
635
648
|
console.log(`\n${c.primary.bold('Account Usage')}\n`);
|
|
636
|
-
|
|
649
|
+
const w5 = data.limits.fiveHour;
|
|
650
|
+
const wk = data.limits.weekly;
|
|
651
|
+
const limitColor = (rem, lim) => rem <= 0 ? c.error : rem / lim <= 0.3 ? c.warning : c.success;
|
|
652
|
+
row('5-hour limit', `${limitColor(w5.remaining, w5.limit).bold(fmtUsd(w5.remaining))} left ${c.muted(`of ${fmtUsd(w5.limit)} · resets ${fmtReset(w5.resetAt)}`)}`);
|
|
653
|
+
row('Weekly limit', `${limitColor(wk.remaining, wk.limit).bold(fmtUsd(wk.remaining))} left ${c.muted(`of ${fmtUsd(wk.limit)} · resets ${fmtReset(wk.resetAt)}`)}`);
|
|
637
654
|
row('Total spent', fmtUsd(s.totalCost));
|
|
638
655
|
console.log();
|
|
639
656
|
row('Requests · 30d', s.requests30d.toLocaleString());
|
|
@@ -1051,10 +1068,11 @@ export async function startREPL(agent, config, projectContext, oneShot) {
|
|
|
1051
1068
|
forwardToReadline(data);
|
|
1052
1069
|
return;
|
|
1053
1070
|
}
|
|
1071
|
+
// Multi-line paste without bracketed-paste markers: treat the whole chunk
|
|
1072
|
+
// as a pasted block so it doesn't submit immediately.
|
|
1054
1073
|
if (!pasteMode && !text.includes('\x1b[200~') && /[\r\n]/.test(text.trim()) && text.length > 3) {
|
|
1055
1074
|
closeMenu();
|
|
1056
|
-
|
|
1057
|
-
rl.write(normalized);
|
|
1075
|
+
insertPasteBlock(text);
|
|
1058
1076
|
return;
|
|
1059
1077
|
}
|
|
1060
1078
|
let rest = text;
|
|
@@ -1066,8 +1084,7 @@ export async function startREPL(agent, config, projectContext, oneShot) {
|
|
|
1066
1084
|
return;
|
|
1067
1085
|
}
|
|
1068
1086
|
pasteBuffer += rest.slice(0, end);
|
|
1069
|
-
|
|
1070
|
-
rl.write(normalized);
|
|
1087
|
+
insertPasteBlock(pasteBuffer);
|
|
1071
1088
|
pasteBuffer = '';
|
|
1072
1089
|
pasteMode = false;
|
|
1073
1090
|
rest = rest.slice(end + '\x1b[201~'.length);
|
|
@@ -1278,7 +1295,7 @@ export async function startREPL(agent, config, projectContext, oneShot) {
|
|
|
1278
1295
|
restoredImages = true;
|
|
1279
1296
|
}
|
|
1280
1297
|
const e = err;
|
|
1281
|
-
console.error(`\n${errorLine(`Error: ${
|
|
1298
|
+
console.error(`\n${errorLine(`Error: ${extractUpstreamError(err)}`)}`);
|
|
1282
1299
|
}
|
|
1283
1300
|
}
|
|
1284
1301
|
finally {
|
package/dist/theme.d.ts
CHANGED
package/dist/theme.js
CHANGED
|
@@ -3,7 +3,7 @@ import os from 'os';
|
|
|
3
3
|
import { join as pathJoin, basename } from 'path';
|
|
4
4
|
import { existsSync, readFileSync } from 'fs';
|
|
5
5
|
import { loadConfig, saveConfig } from './config.js';
|
|
6
|
-
export const VERSION = '0.1.
|
|
6
|
+
export const VERSION = '0.1.18';
|
|
7
7
|
const IKIE_BANNER = [
|
|
8
8
|
' ██╗██╗ ██╗██╗███████╗',
|
|
9
9
|
' ██║██║ ██╔╝██║██╔════╝',
|