darkfoo-code 0.4.1 → 0.4.2
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/main.js +159 -140
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2068,8 +2068,8 @@ function App({ model, systemPromptOverride, maxTurns, initialMessages, initialSe
|
|
|
2068
2068
|
}
|
|
2069
2069
|
|
|
2070
2070
|
// src/repl.tsx
|
|
2071
|
-
import { useState as
|
|
2072
|
-
import { Box as
|
|
2071
|
+
import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useMemo } from "react";
|
|
2072
|
+
import { Box as Box7, Text as Text7, useApp, useInput as useInput2 } from "ink";
|
|
2073
2073
|
import { nanoid as nanoid6 } from "nanoid";
|
|
2074
2074
|
|
|
2075
2075
|
// src/components/Banner.tsx
|
|
@@ -2077,7 +2077,7 @@ init_theme();
|
|
|
2077
2077
|
import { memo } from "react";
|
|
2078
2078
|
import { Box, Text } from "ink";
|
|
2079
2079
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
2080
|
-
var version = "0.4.
|
|
2080
|
+
var version = "0.4.2";
|
|
2081
2081
|
var LOGO_LINES = [
|
|
2082
2082
|
" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
|
|
2083
2083
|
" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2554\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557",
|
|
@@ -2264,40 +2264,91 @@ var MessageRow = memo2(function MessageRow2({ message }) {
|
|
|
2264
2264
|
}
|
|
2265
2265
|
});
|
|
2266
2266
|
|
|
2267
|
-
// src/components/
|
|
2267
|
+
// src/components/StreamingDisplay.tsx
|
|
2268
2268
|
init_theme();
|
|
2269
|
-
|
|
2270
|
-
import { memo as memo3 } from "react";
|
|
2269
|
+
import { useState, useRef, useEffect, useImperativeHandle, forwardRef, memo as memo3 } from "react";
|
|
2271
2270
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
2272
2271
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2273
|
-
var
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2272
|
+
var FLUSH_INTERVAL_MS = 150;
|
|
2273
|
+
var StreamingDisplay = memo3(forwardRef(function StreamingDisplay2(_, ref) {
|
|
2274
|
+
const bufferRef = useRef("");
|
|
2275
|
+
const [displayText, setDisplayText] = useState("");
|
|
2276
|
+
const timerRef = useRef(null);
|
|
2277
|
+
function startTimer() {
|
|
2278
|
+
if (timerRef.current) return;
|
|
2279
|
+
timerRef.current = setInterval(() => {
|
|
2280
|
+
const buf = bufferRef.current;
|
|
2281
|
+
if (!buf) return;
|
|
2282
|
+
const lastNL = buf.lastIndexOf("\n");
|
|
2283
|
+
setDisplayText(lastNL >= 0 ? buf.substring(0, lastNL + 1) : buf);
|
|
2284
|
+
}, FLUSH_INTERVAL_MS);
|
|
2285
|
+
}
|
|
2286
|
+
function stopTimer() {
|
|
2287
|
+
if (timerRef.current) {
|
|
2288
|
+
clearInterval(timerRef.current);
|
|
2289
|
+
timerRef.current = null;
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
2292
|
+
useImperativeHandle(ref, () => ({
|
|
2293
|
+
append(text) {
|
|
2294
|
+
bufferRef.current += text;
|
|
2295
|
+
startTimer();
|
|
2296
|
+
},
|
|
2297
|
+
clear() {
|
|
2298
|
+
stopTimer();
|
|
2299
|
+
if (bufferRef.current) {
|
|
2300
|
+
setDisplayText("");
|
|
2301
|
+
}
|
|
2302
|
+
bufferRef.current = "";
|
|
2303
|
+
},
|
|
2304
|
+
getText() {
|
|
2305
|
+
return bufferRef.current;
|
|
2306
|
+
}
|
|
2307
|
+
}));
|
|
2308
|
+
useEffect(() => {
|
|
2309
|
+
return () => stopTimer();
|
|
2310
|
+
}, []);
|
|
2311
|
+
if (!displayText) return null;
|
|
2312
|
+
return /* @__PURE__ */ jsxs3(Box3, { marginBottom: 1, children: [
|
|
2313
|
+
/* @__PURE__ */ jsx4(Text3, { color: theme.cyan, children: "\u23BF " }),
|
|
2314
|
+
/* @__PURE__ */ jsx4(Text3, { color: theme.text, wrap: "wrap", children: displayText })
|
|
2315
|
+
] });
|
|
2316
|
+
}));
|
|
2317
|
+
|
|
2318
|
+
// src/components/ToolCall.tsx
|
|
2319
|
+
init_theme();
|
|
2320
|
+
init_format();
|
|
2321
|
+
import { memo as memo4 } from "react";
|
|
2322
|
+
import { Box as Box4, Text as Text4 } from "ink";
|
|
2323
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2324
|
+
var ActiveToolCall = memo4(function ActiveToolCall2({ toolName, args }) {
|
|
2325
|
+
return /* @__PURE__ */ jsxs4(Box4, { marginLeft: 2, children: [
|
|
2326
|
+
/* @__PURE__ */ jsx5(Text4, { color: theme.cyan, children: "..." }),
|
|
2327
|
+
/* @__PURE__ */ jsxs4(Text4, { bold: true, color: theme.yellow, children: [
|
|
2277
2328
|
" ",
|
|
2278
2329
|
toolName
|
|
2279
2330
|
] }),
|
|
2280
|
-
args ? /* @__PURE__ */
|
|
2331
|
+
args ? /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2281
2332
|
" ",
|
|
2282
2333
|
formatToolArgs(args)
|
|
2283
2334
|
] }) : null
|
|
2284
2335
|
] });
|
|
2285
2336
|
});
|
|
2286
|
-
var ToolResultDisplay =
|
|
2337
|
+
var ToolResultDisplay = memo4(function ToolResultDisplay2({ toolName, output, isError }) {
|
|
2287
2338
|
const icon = isError ? "\u2718" : "\u2714";
|
|
2288
2339
|
const iconColor = isError ? theme.pink : theme.green;
|
|
2289
2340
|
const lines = output.split("\n");
|
|
2290
2341
|
const preview = lines.length > 6 ? lines.slice(0, 6).join("\n") + `
|
|
2291
2342
|
... (${lines.length - 6} more lines)` : output;
|
|
2292
|
-
return /* @__PURE__ */
|
|
2293
|
-
/* @__PURE__ */
|
|
2294
|
-
/* @__PURE__ */
|
|
2343
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginLeft: 2, marginBottom: 1, children: [
|
|
2344
|
+
/* @__PURE__ */ jsxs4(Box4, { children: [
|
|
2345
|
+
/* @__PURE__ */ jsxs4(Text4, { color: iconColor, children: [
|
|
2295
2346
|
icon,
|
|
2296
2347
|
" "
|
|
2297
2348
|
] }),
|
|
2298
|
-
/* @__PURE__ */
|
|
2349
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: theme.yellow, children: toolName })
|
|
2299
2350
|
] }),
|
|
2300
|
-
/* @__PURE__ */
|
|
2351
|
+
/* @__PURE__ */ jsx5(Box4, { marginLeft: 2, children: /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2301
2352
|
"\u23BF ",
|
|
2302
2353
|
truncate(preview, 1200)
|
|
2303
2354
|
] }) })
|
|
@@ -2318,9 +2369,9 @@ function formatToolArgs(args) {
|
|
|
2318
2369
|
// src/components/StatusLine.tsx
|
|
2319
2370
|
init_theme();
|
|
2320
2371
|
init_state();
|
|
2321
|
-
import { memo as
|
|
2322
|
-
import { Box as
|
|
2323
|
-
import { Fragment, jsx as
|
|
2372
|
+
import { memo as memo5 } from "react";
|
|
2373
|
+
import { Box as Box5, Text as Text5 } from "ink";
|
|
2374
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2324
2375
|
function getContextLimit(model) {
|
|
2325
2376
|
const lower = model.toLowerCase();
|
|
2326
2377
|
if (lower.includes("llama3.1")) return 131072;
|
|
@@ -2331,47 +2382,47 @@ function getContextLimit(model) {
|
|
|
2331
2382
|
if (lower.includes("deepseek")) return 32768;
|
|
2332
2383
|
return 8192;
|
|
2333
2384
|
}
|
|
2334
|
-
var StatusLine =
|
|
2385
|
+
var StatusLine = memo5(function StatusLine2({ model, messageCount, tokenEstimate, isStreaming }) {
|
|
2335
2386
|
const state2 = getAppState();
|
|
2336
2387
|
const contextLimit = getContextLimit(model);
|
|
2337
2388
|
const usage = Math.min(tokenEstimate / contextLimit, 1);
|
|
2338
2389
|
const pct = (usage * 100).toFixed(0);
|
|
2339
2390
|
const usageColor = usage > 0.8 ? theme.pink : usage > 0.5 ? theme.yellow : theme.cyan;
|
|
2340
2391
|
const activeTasks = state2.tasks.filter((t) => t.status === "in_progress").length;
|
|
2341
|
-
return /* @__PURE__ */
|
|
2342
|
-
/* @__PURE__ */
|
|
2392
|
+
return /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, children: [
|
|
2393
|
+
/* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
|
|
2343
2394
|
"\u2500".repeat(2),
|
|
2344
2395
|
" "
|
|
2345
2396
|
] }),
|
|
2346
|
-
/* @__PURE__ */
|
|
2347
|
-
/* @__PURE__ */
|
|
2348
|
-
/* @__PURE__ */
|
|
2397
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.cyan, bold: true, children: model ? model.split(":")[0] : "--" }),
|
|
2398
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
|
|
2399
|
+
/* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
|
|
2349
2400
|
messageCount,
|
|
2350
2401
|
" msgs"
|
|
2351
2402
|
] }),
|
|
2352
|
-
/* @__PURE__ */
|
|
2353
|
-
/* @__PURE__ */
|
|
2403
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
|
|
2404
|
+
/* @__PURE__ */ jsxs5(Text5, { color: usageColor, children: [
|
|
2354
2405
|
"ctx ",
|
|
2355
2406
|
pct,
|
|
2356
2407
|
"%"
|
|
2357
2408
|
] }),
|
|
2358
|
-
state2.planMode ? /* @__PURE__ */
|
|
2359
|
-
/* @__PURE__ */
|
|
2360
|
-
/* @__PURE__ */
|
|
2409
|
+
state2.planMode ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
2410
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
|
|
2411
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.yellow, bold: true, children: "PLAN" })
|
|
2361
2412
|
] }) : null,
|
|
2362
|
-
activeTasks > 0 ? /* @__PURE__ */
|
|
2363
|
-
/* @__PURE__ */
|
|
2364
|
-
/* @__PURE__ */
|
|
2413
|
+
activeTasks > 0 ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
2414
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
|
|
2415
|
+
/* @__PURE__ */ jsxs5(Text5, { color: theme.green, children: [
|
|
2365
2416
|
activeTasks,
|
|
2366
2417
|
" task",
|
|
2367
2418
|
activeTasks > 1 ? "s" : ""
|
|
2368
2419
|
] })
|
|
2369
2420
|
] }) : null,
|
|
2370
|
-
isStreaming ? /* @__PURE__ */
|
|
2371
|
-
/* @__PURE__ */
|
|
2372
|
-
/* @__PURE__ */
|
|
2421
|
+
isStreaming ? /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
2422
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
|
|
2423
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.cyan, children: "streaming" })
|
|
2373
2424
|
] }) : null,
|
|
2374
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
|
|
2375
2426
|
" ",
|
|
2376
2427
|
"\u2500".repeat(2)
|
|
2377
2428
|
] })
|
|
@@ -2380,8 +2431,8 @@ var StatusLine = memo4(function StatusLine2({ model, messageCount, tokenEstimate
|
|
|
2380
2431
|
|
|
2381
2432
|
// src/components/UserInput.tsx
|
|
2382
2433
|
init_theme();
|
|
2383
|
-
import { useState, useCallback, memo as
|
|
2384
|
-
import { Box as
|
|
2434
|
+
import { useState as useState2, useCallback, memo as memo6 } from "react";
|
|
2435
|
+
import { Box as Box6, Text as Text6, useInput } from "ink";
|
|
2385
2436
|
import TextInput from "ink-text-input";
|
|
2386
2437
|
|
|
2387
2438
|
// src/commands/help.ts
|
|
@@ -3417,10 +3468,10 @@ function getCommandNames() {
|
|
|
3417
3468
|
}
|
|
3418
3469
|
|
|
3419
3470
|
// src/components/UserInput.tsx
|
|
3420
|
-
import { Fragment as Fragment2, jsx as
|
|
3421
|
-
var UserInput =
|
|
3422
|
-
const [historyIdx, setHistoryIdx] =
|
|
3423
|
-
const [suggestion, setSuggestion] =
|
|
3471
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
3472
|
+
var UserInput = memo6(function UserInput2({ value, onChange, onSubmit, disabled, history }) {
|
|
3473
|
+
const [historyIdx, setHistoryIdx] = useState2(-1);
|
|
3474
|
+
const [suggestion, setSuggestion] = useState2("");
|
|
3424
3475
|
useInput((_input, key) => {
|
|
3425
3476
|
if (disabled || !history || history.length === 0) return;
|
|
3426
3477
|
if (key.upArrow) {
|
|
@@ -3466,20 +3517,20 @@ var UserInput = memo5(function UserInput2({ value, onChange, onSubmit, disabled,
|
|
|
3466
3517
|
const borderColor = disabled ? theme.dim : isBash ? theme.yellow : isCommand ? theme.purple : theme.cyan;
|
|
3467
3518
|
const promptChar = isBash ? "!" : "\u276F";
|
|
3468
3519
|
const promptColor = isBash ? theme.yellow : theme.cyan;
|
|
3469
|
-
return /* @__PURE__ */
|
|
3470
|
-
|
|
3520
|
+
return /* @__PURE__ */ jsxs6(
|
|
3521
|
+
Box6,
|
|
3471
3522
|
{
|
|
3472
3523
|
borderStyle: "round",
|
|
3473
3524
|
borderColor,
|
|
3474
3525
|
paddingLeft: 1,
|
|
3475
3526
|
paddingRight: 1,
|
|
3476
3527
|
children: [
|
|
3477
|
-
/* @__PURE__ */
|
|
3528
|
+
/* @__PURE__ */ jsxs6(Text6, { color: disabled ? theme.dim : promptColor, bold: true, children: [
|
|
3478
3529
|
promptChar,
|
|
3479
3530
|
" "
|
|
3480
3531
|
] }),
|
|
3481
|
-
disabled ? /* @__PURE__ */
|
|
3482
|
-
/* @__PURE__ */
|
|
3532
|
+
disabled ? /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: "..." }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
3533
|
+
/* @__PURE__ */ jsx7(
|
|
3483
3534
|
TextInput,
|
|
3484
3535
|
{
|
|
3485
3536
|
value,
|
|
@@ -3493,7 +3544,7 @@ var UserInput = memo5(function UserInput2({ value, onChange, onSubmit, disabled,
|
|
|
3493
3544
|
}
|
|
3494
3545
|
}
|
|
3495
3546
|
),
|
|
3496
|
-
suggestion ? /* @__PURE__ */
|
|
3547
|
+
suggestion ? /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: suggestion }) : null
|
|
3497
3548
|
] })
|
|
3498
3549
|
]
|
|
3499
3550
|
}
|
|
@@ -3509,7 +3560,7 @@ init_tools();
|
|
|
3509
3560
|
init_bash();
|
|
3510
3561
|
init_hooks();
|
|
3511
3562
|
init_theme();
|
|
3512
|
-
import { jsx as
|
|
3563
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3513
3564
|
function getContextLimit3(model) {
|
|
3514
3565
|
const lower = model.toLowerCase();
|
|
3515
3566
|
if (lower.includes("llama3.1")) return 131072;
|
|
@@ -3520,72 +3571,47 @@ function getContextLimit3(model) {
|
|
|
3520
3571
|
if (lower.includes("deepseek")) return 32768;
|
|
3521
3572
|
return 8192;
|
|
3522
3573
|
}
|
|
3523
|
-
var STREAM_THROTTLE_MS = 80;
|
|
3524
3574
|
function REPL({ initialPrompt }) {
|
|
3525
3575
|
const { model: initialModel, systemPromptOverride, maxTurns, initialMessages, initialSessionId } = useDarkfooContext();
|
|
3526
3576
|
const { exit } = useApp();
|
|
3527
|
-
const [model, setModel] =
|
|
3528
|
-
const [messages, setMessages] =
|
|
3529
|
-
const [inputValue, setInputValue] =
|
|
3530
|
-
const [isStreaming, setIsStreaming] =
|
|
3531
|
-
const [
|
|
3532
|
-
const [activeTool, setActiveTool] =
|
|
3533
|
-
const [toolResults, setToolResults] =
|
|
3534
|
-
const [commandOutput, setCommandOutput] =
|
|
3535
|
-
const [inputHistory, setInputHistory] =
|
|
3536
|
-
const [tokenCounts, setTokenCounts] =
|
|
3537
|
-
const [systemPrompt, setSystemPrompt] =
|
|
3538
|
-
const [mascotMood, setMascotMood] =
|
|
3539
|
-
const [providerOnline, setProviderOnline] =
|
|
3540
|
-
const abortRef =
|
|
3541
|
-
const hasRun =
|
|
3542
|
-
const sessionId =
|
|
3543
|
-
const
|
|
3544
|
-
const
|
|
3545
|
-
const startStreamFlush = useCallback2(() => {
|
|
3546
|
-
if (streamFlushTimer.current) return;
|
|
3547
|
-
streamFlushTimer.current = setInterval(() => {
|
|
3548
|
-
const buf = streamBufferRef.current;
|
|
3549
|
-
if (buf) {
|
|
3550
|
-
setStreamingText(buf);
|
|
3551
|
-
}
|
|
3552
|
-
}, STREAM_THROTTLE_MS);
|
|
3553
|
-
}, []);
|
|
3554
|
-
const stopStreamFlush = useCallback2(() => {
|
|
3555
|
-
if (streamFlushTimer.current) {
|
|
3556
|
-
clearInterval(streamFlushTimer.current);
|
|
3557
|
-
streamFlushTimer.current = null;
|
|
3558
|
-
}
|
|
3559
|
-
if (streamBufferRef.current) {
|
|
3560
|
-
setStreamingText(streamBufferRef.current);
|
|
3561
|
-
}
|
|
3562
|
-
}, []);
|
|
3563
|
-
useEffect(() => {
|
|
3564
|
-
return () => {
|
|
3565
|
-
if (streamFlushTimer.current) clearInterval(streamFlushTimer.current);
|
|
3566
|
-
};
|
|
3567
|
-
}, []);
|
|
3568
|
-
const messagesRef = useRef(messages);
|
|
3577
|
+
const [model, setModel] = useState3(initialModel);
|
|
3578
|
+
const [messages, setMessages] = useState3(initialMessages ?? []);
|
|
3579
|
+
const [inputValue, setInputValue] = useState3("");
|
|
3580
|
+
const [isStreaming, setIsStreaming] = useState3(false);
|
|
3581
|
+
const [receivedText, setReceivedText] = useState3(false);
|
|
3582
|
+
const [activeTool, setActiveTool] = useState3(null);
|
|
3583
|
+
const [toolResults, setToolResults] = useState3([]);
|
|
3584
|
+
const [commandOutput, setCommandOutput] = useState3(null);
|
|
3585
|
+
const [inputHistory, setInputHistory] = useState3([]);
|
|
3586
|
+
const [tokenCounts, setTokenCounts] = useState3({ input: 0, output: 0 });
|
|
3587
|
+
const [systemPrompt, setSystemPrompt] = useState3("");
|
|
3588
|
+
const [mascotMood, setMascotMood] = useState3("idle");
|
|
3589
|
+
const [providerOnline, setProviderOnline] = useState3(true);
|
|
3590
|
+
const abortRef = useRef2(null);
|
|
3591
|
+
const hasRun = useRef2(false);
|
|
3592
|
+
const sessionId = useRef2(initialSessionId ?? createSessionId());
|
|
3593
|
+
const streamingRef = useRef2(null);
|
|
3594
|
+
const messagesRef = useRef2(messages);
|
|
3569
3595
|
messagesRef.current = messages;
|
|
3570
|
-
const modelRef =
|
|
3596
|
+
const modelRef = useRef2(model);
|
|
3571
3597
|
modelRef.current = model;
|
|
3572
|
-
const systemPromptRef =
|
|
3598
|
+
const systemPromptRef = useRef2(systemPrompt);
|
|
3573
3599
|
systemPromptRef.current = systemPrompt;
|
|
3574
3600
|
const tools = getTools();
|
|
3575
3601
|
const cwd = process.cwd();
|
|
3576
3602
|
const providerName = useMemo(() => getActiveProviderName(), [model, providerOnline]);
|
|
3577
|
-
|
|
3603
|
+
useEffect2(() => {
|
|
3578
3604
|
if (systemPromptOverride) {
|
|
3579
3605
|
setSystemPrompt(systemPromptOverride);
|
|
3580
3606
|
} else {
|
|
3581
3607
|
buildSystemPrompt(tools, cwd).then(setSystemPrompt);
|
|
3582
3608
|
}
|
|
3583
3609
|
}, []);
|
|
3584
|
-
|
|
3610
|
+
useEffect2(() => {
|
|
3585
3611
|
executeHooks("session_start", { cwd }).catch(() => {
|
|
3586
3612
|
});
|
|
3587
3613
|
}, []);
|
|
3588
|
-
|
|
3614
|
+
useEffect2(() => {
|
|
3589
3615
|
const provider = getProvider();
|
|
3590
3616
|
provider.healthCheck().then((ok) => {
|
|
3591
3617
|
setProviderOnline(ok);
|
|
@@ -3618,7 +3644,7 @@ function REPL({ initialPrompt }) {
|
|
|
3618
3644
|
});
|
|
3619
3645
|
}, []);
|
|
3620
3646
|
const clearMessages = useCallback2(() => setMessages([]), []);
|
|
3621
|
-
const commandContextRef =
|
|
3647
|
+
const commandContextRef = useRef2({
|
|
3622
3648
|
messages,
|
|
3623
3649
|
model,
|
|
3624
3650
|
cwd,
|
|
@@ -3646,18 +3672,17 @@ function REPL({ initialPrompt }) {
|
|
|
3646
3672
|
};
|
|
3647
3673
|
setMessages((prev) => [...prev, userMsg]);
|
|
3648
3674
|
setIsStreaming(true);
|
|
3649
|
-
|
|
3650
|
-
setStreamingText("");
|
|
3675
|
+
setReceivedText(false);
|
|
3651
3676
|
setToolResults([]);
|
|
3652
3677
|
setCommandOutput(null);
|
|
3653
3678
|
setMascotMood("thinking");
|
|
3679
|
+
streamingRef.current?.clear();
|
|
3654
3680
|
const controller = new AbortController();
|
|
3655
3681
|
abortRef.current = controller;
|
|
3656
3682
|
const allMessages = [...messagesRef.current, userMsg];
|
|
3657
3683
|
const currentModel = modelRef.current;
|
|
3658
3684
|
const currentSystemPrompt = systemPromptRef.current;
|
|
3659
|
-
let
|
|
3660
|
-
startStreamFlush();
|
|
3685
|
+
let gotFirstText = false;
|
|
3661
3686
|
try {
|
|
3662
3687
|
for await (const event of query({
|
|
3663
3688
|
model: currentModel,
|
|
@@ -3670,14 +3695,14 @@ function REPL({ initialPrompt }) {
|
|
|
3670
3695
|
if (controller.signal.aborted) break;
|
|
3671
3696
|
switch (event.type) {
|
|
3672
3697
|
case "text_delta":
|
|
3673
|
-
|
|
3674
|
-
if (!
|
|
3675
|
-
|
|
3698
|
+
streamingRef.current?.append(event.text);
|
|
3699
|
+
if (!gotFirstText) {
|
|
3700
|
+
gotFirstText = true;
|
|
3701
|
+
setReceivedText(true);
|
|
3676
3702
|
setMascotMood("idle");
|
|
3677
3703
|
}
|
|
3678
3704
|
break;
|
|
3679
3705
|
case "tool_call":
|
|
3680
|
-
stopStreamFlush();
|
|
3681
3706
|
setActiveTool({ name: event.toolCall.function.name, args: event.toolCall.function.arguments });
|
|
3682
3707
|
setMascotMood("working");
|
|
3683
3708
|
break;
|
|
@@ -3696,20 +3721,18 @@ function REPL({ initialPrompt }) {
|
|
|
3696
3721
|
}));
|
|
3697
3722
|
break;
|
|
3698
3723
|
case "assistant_message":
|
|
3699
|
-
|
|
3724
|
+
streamingRef.current?.clear();
|
|
3725
|
+
setReceivedText(false);
|
|
3726
|
+
gotFirstText = false;
|
|
3700
3727
|
setMessages((prev) => {
|
|
3701
3728
|
const updated = [...prev, event.message];
|
|
3702
3729
|
saveSession(sessionId.current, updated, currentModel, cwd).catch(() => {
|
|
3703
3730
|
});
|
|
3704
3731
|
return updated;
|
|
3705
3732
|
});
|
|
3706
|
-
streamBufferRef.current = "";
|
|
3707
|
-
setStreamingText("");
|
|
3708
|
-
receivedFirstText = false;
|
|
3709
|
-
startStreamFlush();
|
|
3710
3733
|
break;
|
|
3711
3734
|
case "error":
|
|
3712
|
-
|
|
3735
|
+
streamingRef.current?.clear();
|
|
3713
3736
|
setMascotMood("error");
|
|
3714
3737
|
setMessages((prev) => [
|
|
3715
3738
|
...prev,
|
|
@@ -3727,10 +3750,9 @@ function REPL({ initialPrompt }) {
|
|
|
3727
3750
|
]);
|
|
3728
3751
|
}
|
|
3729
3752
|
} finally {
|
|
3730
|
-
|
|
3731
|
-
streamBufferRef.current = "";
|
|
3753
|
+
streamingRef.current?.clear();
|
|
3732
3754
|
setIsStreaming(false);
|
|
3733
|
-
|
|
3755
|
+
setReceivedText(false);
|
|
3734
3756
|
setActiveTool(null);
|
|
3735
3757
|
setToolResults([]);
|
|
3736
3758
|
setMascotMood((prev) => prev === "error" ? "error" : "success");
|
|
@@ -3738,7 +3760,7 @@ function REPL({ initialPrompt }) {
|
|
|
3738
3760
|
abortRef.current = null;
|
|
3739
3761
|
}
|
|
3740
3762
|
},
|
|
3741
|
-
[tools, cwd
|
|
3763
|
+
[tools, cwd]
|
|
3742
3764
|
);
|
|
3743
3765
|
const handleSubmit = useCallback2(
|
|
3744
3766
|
async (value) => {
|
|
@@ -3794,14 +3816,14 @@ function REPL({ initialPrompt }) {
|
|
|
3794
3816
|
},
|
|
3795
3817
|
[addToHistory, exit, cwd, runQuery]
|
|
3796
3818
|
);
|
|
3797
|
-
|
|
3819
|
+
useEffect2(() => {
|
|
3798
3820
|
if (initialPrompt && !hasRun.current) {
|
|
3799
3821
|
hasRun.current = true;
|
|
3800
3822
|
runQuery(initialPrompt);
|
|
3801
3823
|
}
|
|
3802
3824
|
}, [initialPrompt, runQuery]);
|
|
3803
|
-
const autoCompactRef =
|
|
3804
|
-
|
|
3825
|
+
const autoCompactRef = useRef2(false);
|
|
3826
|
+
useEffect2(() => {
|
|
3805
3827
|
if (isStreaming || autoCompactRef.current || messages.length < 6) return;
|
|
3806
3828
|
const totalChars = messages.reduce((sum, m) => sum + m.content.length, 0);
|
|
3807
3829
|
const estTokens = Math.ceil(totalChars / 4) + 2e3;
|
|
@@ -3844,21 +3866,18 @@ ${result.content}
|
|
|
3844
3866
|
}
|
|
3845
3867
|
}
|
|
3846
3868
|
});
|
|
3847
|
-
return /* @__PURE__ */
|
|
3848
|
-
/* @__PURE__ */
|
|
3849
|
-
/* @__PURE__ */
|
|
3850
|
-
commandOutput ? /* @__PURE__ */
|
|
3851
|
-
toolResults.map((tr) => /* @__PURE__ */
|
|
3852
|
-
activeTool ? /* @__PURE__ */
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
/* @__PURE__ */
|
|
3869
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", padding: 1, children: [
|
|
3870
|
+
/* @__PURE__ */ jsx8(Banner, { model, cwd, providerName, providerOnline, mood: mascotMood }),
|
|
3871
|
+
/* @__PURE__ */ jsx8(Messages, { messages }),
|
|
3872
|
+
commandOutput ? /* @__PURE__ */ jsx8(Box7, { marginBottom: 1, marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx8(Text7, { children: commandOutput }) }) : null,
|
|
3873
|
+
toolResults.map((tr) => /* @__PURE__ */ jsx8(ToolResultDisplay, { toolName: tr.toolName, output: tr.output, isError: tr.isError }, tr.id)),
|
|
3874
|
+
activeTool ? /* @__PURE__ */ jsx8(ActiveToolCall, { toolName: activeTool.name, args: activeTool.args }) : null,
|
|
3875
|
+
/* @__PURE__ */ jsx8(StreamingDisplay, { ref: streamingRef }),
|
|
3876
|
+
isStreaming && !receivedText && !activeTool ? /* @__PURE__ */ jsxs7(Box7, { marginLeft: 2, children: [
|
|
3877
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.cyan, children: "..." }),
|
|
3878
|
+
/* @__PURE__ */ jsx8(Text7, { color: theme.dim, children: " Thinking" })
|
|
3856
3879
|
] }) : null,
|
|
3857
|
-
|
|
3858
|
-
/* @__PURE__ */ jsx7(Text6, { color: theme.cyan, children: "..." }),
|
|
3859
|
-
/* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: " Thinking" })
|
|
3860
|
-
] }) : null,
|
|
3861
|
-
/* @__PURE__ */ jsx7(
|
|
3880
|
+
/* @__PURE__ */ jsx8(
|
|
3862
3881
|
UserInput,
|
|
3863
3882
|
{
|
|
3864
3883
|
value: inputValue,
|
|
@@ -3868,7 +3887,7 @@ ${result.content}
|
|
|
3868
3887
|
history: inputHistory
|
|
3869
3888
|
}
|
|
3870
3889
|
),
|
|
3871
|
-
/* @__PURE__ */
|
|
3890
|
+
/* @__PURE__ */ jsx8(
|
|
3872
3891
|
StatusLine,
|
|
3873
3892
|
{
|
|
3874
3893
|
model,
|
|
@@ -3882,9 +3901,9 @@ ${result.content}
|
|
|
3882
3901
|
|
|
3883
3902
|
// src/main.tsx
|
|
3884
3903
|
init_providers();
|
|
3885
|
-
import { jsx as
|
|
3904
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
3886
3905
|
var program = new Command();
|
|
3887
|
-
program.name("darkfoo").description("Darkfoo Code \u2014 local AI coding assistant powered by local LLM providers").version("0.4.
|
|
3906
|
+
program.name("darkfoo").description("Darkfoo Code \u2014 local AI coding assistant powered by local LLM providers").version("0.4.2").option("-m, --model <model>", "Model to use", "llama3.1:8b").option("-p, --prompt <prompt>", "Run a single prompt (non-interactive)").option("-c, --continue", "Resume the most recent session").option("--resume <id>", "Resume a specific session by ID").option("--max-turns <n>", "Maximum tool-use turns per query", "30").option("--debug", "Enable debug logging to stderr").option("--output-format <format>", "Output format for non-interactive mode (text, json)").option("--provider <name>", "LLM provider backend (ollama, llama-cpp, vllm, tgi, etc.)").option("--system-prompt <prompt>", "Override the system prompt").action(async (options) => {
|
|
3888
3907
|
const { model, prompt, provider, systemPrompt } = options;
|
|
3889
3908
|
if (options.debug) {
|
|
3890
3909
|
const { setDebugMode: setDebugMode2 } = await Promise.resolve().then(() => (init_debug(), debug_exports));
|
|
@@ -4019,7 +4038,7 @@ Error: ${event.error}
|
|
|
4019
4038
|
}
|
|
4020
4039
|
}
|
|
4021
4040
|
const { waitUntilExit } = render(
|
|
4022
|
-
/* @__PURE__ */
|
|
4041
|
+
/* @__PURE__ */ jsx9(
|
|
4023
4042
|
App,
|
|
4024
4043
|
{
|
|
4025
4044
|
model: resolvedModel,
|
|
@@ -4027,7 +4046,7 @@ Error: ${event.error}
|
|
|
4027
4046
|
maxTurns,
|
|
4028
4047
|
initialMessages,
|
|
4029
4048
|
initialSessionId,
|
|
4030
|
-
children: /* @__PURE__ */
|
|
4049
|
+
children: /* @__PURE__ */ jsx9(REPL, {})
|
|
4031
4050
|
}
|
|
4032
4051
|
)
|
|
4033
4052
|
);
|