@kernelonpanic/kitcode 1.2.8 → 1.2.9
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/index.js +58 -12
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1430,6 +1430,10 @@ async function runTurn(cfg, history, hooks, signal) {
|
|
|
1430
1430
|
let pauses = 0;
|
|
1431
1431
|
let steps = 0;
|
|
1432
1432
|
for (; ; ) {
|
|
1433
|
+
if (signal.aborted) {
|
|
1434
|
+
hooks.onEvent({ type: "turn_end", stopReason: "aborted" });
|
|
1435
|
+
return sanitizeHistory(messages);
|
|
1436
|
+
}
|
|
1433
1437
|
if (++steps > MAX_TURN_STEPS) {
|
|
1434
1438
|
hooks.onEvent({
|
|
1435
1439
|
type: "notice",
|
|
@@ -1516,12 +1520,16 @@ async function consumeStream(cfg, messages, hooks, signal, maxTokens) {
|
|
|
1516
1520
|
signal
|
|
1517
1521
|
};
|
|
1518
1522
|
let outcome;
|
|
1523
|
+
let text = "";
|
|
1524
|
+
let thinking = "";
|
|
1519
1525
|
for await (const event of streamWithRetry(cfg.provider, request, cfg.modelRef, signal)) {
|
|
1520
1526
|
switch (event.type) {
|
|
1521
1527
|
case "text_delta":
|
|
1528
|
+
text += event.text;
|
|
1522
1529
|
hooks.onEvent({ type: "text_delta", text: event.text });
|
|
1523
1530
|
break;
|
|
1524
1531
|
case "thinking_delta":
|
|
1532
|
+
thinking += event.text;
|
|
1525
1533
|
hooks.onEvent({ type: "thinking_delta", text: event.text });
|
|
1526
1534
|
break;
|
|
1527
1535
|
case "usage":
|
|
@@ -1540,7 +1548,12 @@ async function consumeStream(cfg, messages, hooks, signal, maxTokens) {
|
|
|
1540
1548
|
}
|
|
1541
1549
|
}
|
|
1542
1550
|
if (outcome) return outcome;
|
|
1543
|
-
if (signal.aborted)
|
|
1551
|
+
if (signal.aborted) {
|
|
1552
|
+
const content = [];
|
|
1553
|
+
if (thinking) content.push({ type: "thinking", text: thinking });
|
|
1554
|
+
if (text) content.push({ type: "text", text });
|
|
1555
|
+
return { content, stopReason: "aborted" };
|
|
1556
|
+
}
|
|
1544
1557
|
throw new Error(
|
|
1545
1558
|
`"${cfg.provider.id}" ended the stream without completing the turn \u2014 nothing was generated. The endpoint answered, but not with a usable ${cfg.provider.kind} response.`
|
|
1546
1559
|
);
|
|
@@ -1550,8 +1563,29 @@ async function* streamWithRetry(provider, request, modelRef, signal) {
|
|
|
1550
1563
|
for (let attempt = 0; attempt <= MAX_RETRIES2; attempt++) {
|
|
1551
1564
|
if (signal.aborted) return;
|
|
1552
1565
|
try {
|
|
1553
|
-
|
|
1554
|
-
|
|
1566
|
+
const stream = provider.stream(request)[Symbol.asyncIterator]();
|
|
1567
|
+
let cancel;
|
|
1568
|
+
let cancelTimer;
|
|
1569
|
+
const cancelled = new Promise((resolve3) => {
|
|
1570
|
+
cancel = () => {
|
|
1571
|
+
cancelTimer ??= setTimeout(() => resolve3({ done: true, value: void 0 }), 100);
|
|
1572
|
+
};
|
|
1573
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
1574
|
+
if (signal.aborted) cancel();
|
|
1575
|
+
});
|
|
1576
|
+
try {
|
|
1577
|
+
for (; ; ) {
|
|
1578
|
+
const next = await Promise.race([stream.next(), cancelled]);
|
|
1579
|
+
if (next.done) break;
|
|
1580
|
+
if (!signal.aborted || next.value.type === "usage" || next.value.type === "done") {
|
|
1581
|
+
yield next.value;
|
|
1582
|
+
}
|
|
1583
|
+
if (next.value.type === "done") break;
|
|
1584
|
+
}
|
|
1585
|
+
} finally {
|
|
1586
|
+
signal.removeEventListener("abort", cancel);
|
|
1587
|
+
if (cancelTimer !== void 0) clearTimeout(cancelTimer);
|
|
1588
|
+
void stream.return?.().catch(() => void 0);
|
|
1555
1589
|
}
|
|
1556
1590
|
return;
|
|
1557
1591
|
} catch (error) {
|
|
@@ -3499,7 +3533,7 @@ function clip(value) {
|
|
|
3499
3533
|
// package.json
|
|
3500
3534
|
var package_default = {
|
|
3501
3535
|
name: "@kernelonpanic/kitcode",
|
|
3502
|
-
version: "1.2.
|
|
3536
|
+
version: "1.2.9",
|
|
3503
3537
|
description: "Terminal coding agent with a config you never have to write by hand",
|
|
3504
3538
|
type: "module",
|
|
3505
3539
|
license: "MIT",
|
|
@@ -3567,7 +3601,7 @@ var package_default = {
|
|
|
3567
3601
|
|
|
3568
3602
|
// src/version.ts
|
|
3569
3603
|
var KITCODE_VERSION = package_default.version;
|
|
3570
|
-
var KITCODE_COMMIT = true ? "
|
|
3604
|
+
var KITCODE_COMMIT = true ? "cc499fc443e73408f49b928f204b77c48e9d2d05" : "development";
|
|
3571
3605
|
|
|
3572
3606
|
// src/mcp/client.ts
|
|
3573
3607
|
var clientInfo = { name: "kitcode", version: KITCODE_VERSION };
|
|
@@ -7067,6 +7101,10 @@ function validateKey(value) {
|
|
|
7067
7101
|
// src/app/tui.tsx
|
|
7068
7102
|
import { render } from "ink";
|
|
7069
7103
|
|
|
7104
|
+
// src/ui/App.tsx
|
|
7105
|
+
import { Box as Box13, Text as Text12, useApp, useInput as useInput2, useStdout as useStdout2 } from "ink";
|
|
7106
|
+
import { useCallback, useEffect as useEffect2, useMemo as useMemo5, useRef as useRef4, useState as useState5 } from "react";
|
|
7107
|
+
|
|
7070
7108
|
// src/ui/terminal-size.ts
|
|
7071
7109
|
import { useStdout } from "ink";
|
|
7072
7110
|
import { useMemo, useSyncExternalStore } from "react";
|
|
@@ -7107,10 +7145,6 @@ function useTerminalSize() {
|
|
|
7107
7145
|
return useSyncExternalStore(store.subscribe, store.getSnapshot, store.getSnapshot);
|
|
7108
7146
|
}
|
|
7109
7147
|
|
|
7110
|
-
// src/ui/App.tsx
|
|
7111
|
-
import { Box as Box13, Text as Text12, useApp, useInput as useInput2 } from "ink";
|
|
7112
|
-
import { useCallback, useEffect as useEffect2, useMemo as useMemo5, useRef as useRef4, useState as useState5 } from "react";
|
|
7113
|
-
|
|
7114
7148
|
// src/mcp/add.ts
|
|
7115
7149
|
var SERVER_NAME = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/;
|
|
7116
7150
|
function parseMcpAddArgs(args) {
|
|
@@ -9598,7 +9632,8 @@ function App({
|
|
|
9598
9632
|
initialHistory,
|
|
9599
9633
|
warnings = []
|
|
9600
9634
|
}) {
|
|
9601
|
-
const { exit } = useApp();
|
|
9635
|
+
const { exit, suspendTerminal } = useApp();
|
|
9636
|
+
const { stdout } = useStdout2();
|
|
9602
9637
|
const { rows } = useTerminalSize();
|
|
9603
9638
|
const [transcript, setTranscript] = useState5(
|
|
9604
9639
|
() => warnings.reduce((state, text) => pushNotice(state, "warn", text), fromHistory(initialHistory))
|
|
@@ -9634,6 +9669,9 @@ function App({
|
|
|
9634
9669
|
const [context, setContext] = useState5(() => runtime.modelContext());
|
|
9635
9670
|
const transcriptEvents = useRef4([]);
|
|
9636
9671
|
const transcriptTimer = useRef4(null);
|
|
9672
|
+
const clearScreen = useCallback(() => {
|
|
9673
|
+
if (stdout.isTTY) stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
9674
|
+
}, [stdout]);
|
|
9637
9675
|
const replaceAttachments = useCallback((next) => {
|
|
9638
9676
|
attachmentsRef.current = next;
|
|
9639
9677
|
setAttachments(next);
|
|
@@ -9801,12 +9839,20 @@ function App({
|
|
|
9801
9839
|
exit();
|
|
9802
9840
|
return;
|
|
9803
9841
|
case "clear":
|
|
9842
|
+
if (busyRef.current && abort.current) {
|
|
9843
|
+
abort.current.abort();
|
|
9844
|
+
}
|
|
9845
|
+
queueRef.current = [];
|
|
9846
|
+
setPendingCount(0);
|
|
9804
9847
|
await runtime.newSession();
|
|
9805
9848
|
history.current = [];
|
|
9806
9849
|
replaceAttachments([]);
|
|
9807
9850
|
setPromptHistory([]);
|
|
9808
|
-
|
|
9809
|
-
|
|
9851
|
+
await suspendTerminal(async () => {
|
|
9852
|
+
setTranscript(emptyTranscript());
|
|
9853
|
+
setTranscriptRevision((revision) => revision + 1);
|
|
9854
|
+
clearScreen();
|
|
9855
|
+
});
|
|
9810
9856
|
sessionStart.current = Date.now();
|
|
9811
9857
|
turns.current = 0;
|
|
9812
9858
|
void runtime.persist([]).catch(
|