darkfoo-code 0.4.0 → 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 +165 -105
- 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",
|
|
@@ -2234,7 +2234,7 @@ import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
|
2234
2234
|
var Messages = memo2(function Messages2({ messages }) {
|
|
2235
2235
|
return /* @__PURE__ */ jsx3(Box2, { flexDirection: "column", children: messages.map((msg) => /* @__PURE__ */ jsx3(MessageRow, { message: msg }, msg.id)) });
|
|
2236
2236
|
});
|
|
2237
|
-
|
|
2237
|
+
var MessageRow = memo2(function MessageRow2({ message }) {
|
|
2238
2238
|
switch (message.role) {
|
|
2239
2239
|
case "user":
|
|
2240
2240
|
return /* @__PURE__ */ jsxs2(Box2, { marginTop: 1, marginBottom: 1, children: [
|
|
@@ -2262,46 +2262,98 @@ function MessageRow({ message }) {
|
|
|
2262
2262
|
default:
|
|
2263
2263
|
return null;
|
|
2264
2264
|
}
|
|
2265
|
-
}
|
|
2265
|
+
});
|
|
2266
2266
|
|
|
2267
|
-
// src/components/
|
|
2267
|
+
// src/components/StreamingDisplay.tsx
|
|
2268
2268
|
init_theme();
|
|
2269
|
-
|
|
2269
|
+
import { useState, useRef, useEffect, useImperativeHandle, forwardRef, memo as memo3 } from "react";
|
|
2270
2270
|
import { Box as Box3, Text as Text3 } from "ink";
|
|
2271
2271
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
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: [
|
|
2276
2328
|
" ",
|
|
2277
2329
|
toolName
|
|
2278
2330
|
] }),
|
|
2279
|
-
args ? /* @__PURE__ */
|
|
2331
|
+
args ? /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2280
2332
|
" ",
|
|
2281
2333
|
formatToolArgs(args)
|
|
2282
2334
|
] }) : null
|
|
2283
2335
|
] });
|
|
2284
|
-
}
|
|
2285
|
-
|
|
2336
|
+
});
|
|
2337
|
+
var ToolResultDisplay = memo4(function ToolResultDisplay2({ toolName, output, isError }) {
|
|
2286
2338
|
const icon = isError ? "\u2718" : "\u2714";
|
|
2287
2339
|
const iconColor = isError ? theme.pink : theme.green;
|
|
2288
2340
|
const lines = output.split("\n");
|
|
2289
2341
|
const preview = lines.length > 6 ? lines.slice(0, 6).join("\n") + `
|
|
2290
2342
|
... (${lines.length - 6} more lines)` : output;
|
|
2291
|
-
return /* @__PURE__ */
|
|
2292
|
-
/* @__PURE__ */
|
|
2293
|
-
/* @__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: [
|
|
2294
2346
|
icon,
|
|
2295
2347
|
" "
|
|
2296
2348
|
] }),
|
|
2297
|
-
/* @__PURE__ */
|
|
2349
|
+
/* @__PURE__ */ jsx5(Text4, { bold: true, color: theme.yellow, children: toolName })
|
|
2298
2350
|
] }),
|
|
2299
|
-
/* @__PURE__ */
|
|
2351
|
+
/* @__PURE__ */ jsx5(Box4, { marginLeft: 2, children: /* @__PURE__ */ jsxs4(Text4, { color: theme.dim, children: [
|
|
2300
2352
|
"\u23BF ",
|
|
2301
2353
|
truncate(preview, 1200)
|
|
2302
2354
|
] }) })
|
|
2303
2355
|
] });
|
|
2304
|
-
}
|
|
2356
|
+
});
|
|
2305
2357
|
function formatToolArgs(args) {
|
|
2306
2358
|
const entries = Object.entries(args);
|
|
2307
2359
|
if (entries.length === 0) return "";
|
|
@@ -2317,9 +2369,9 @@ function formatToolArgs(args) {
|
|
|
2317
2369
|
// src/components/StatusLine.tsx
|
|
2318
2370
|
init_theme();
|
|
2319
2371
|
init_state();
|
|
2320
|
-
import { memo as
|
|
2321
|
-
import { Box as
|
|
2322
|
-
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";
|
|
2323
2375
|
function getContextLimit(model) {
|
|
2324
2376
|
const lower = model.toLowerCase();
|
|
2325
2377
|
if (lower.includes("llama3.1")) return 131072;
|
|
@@ -2330,47 +2382,47 @@ function getContextLimit(model) {
|
|
|
2330
2382
|
if (lower.includes("deepseek")) return 32768;
|
|
2331
2383
|
return 8192;
|
|
2332
2384
|
}
|
|
2333
|
-
var StatusLine =
|
|
2385
|
+
var StatusLine = memo5(function StatusLine2({ model, messageCount, tokenEstimate, isStreaming }) {
|
|
2334
2386
|
const state2 = getAppState();
|
|
2335
2387
|
const contextLimit = getContextLimit(model);
|
|
2336
2388
|
const usage = Math.min(tokenEstimate / contextLimit, 1);
|
|
2337
2389
|
const pct = (usage * 100).toFixed(0);
|
|
2338
2390
|
const usageColor = usage > 0.8 ? theme.pink : usage > 0.5 ? theme.yellow : theme.cyan;
|
|
2339
2391
|
const activeTasks = state2.tasks.filter((t) => t.status === "in_progress").length;
|
|
2340
|
-
return /* @__PURE__ */
|
|
2341
|
-
/* @__PURE__ */
|
|
2392
|
+
return /* @__PURE__ */ jsxs5(Box5, { marginTop: 1, children: [
|
|
2393
|
+
/* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
|
|
2342
2394
|
"\u2500".repeat(2),
|
|
2343
2395
|
" "
|
|
2344
2396
|
] }),
|
|
2345
|
-
/* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2347
|
-
/* @__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: [
|
|
2348
2400
|
messageCount,
|
|
2349
2401
|
" msgs"
|
|
2350
2402
|
] }),
|
|
2351
|
-
/* @__PURE__ */
|
|
2352
|
-
/* @__PURE__ */
|
|
2403
|
+
/* @__PURE__ */ jsx6(Text5, { color: theme.dim, children: " \u2502 " }),
|
|
2404
|
+
/* @__PURE__ */ jsxs5(Text5, { color: usageColor, children: [
|
|
2353
2405
|
"ctx ",
|
|
2354
2406
|
pct,
|
|
2355
2407
|
"%"
|
|
2356
2408
|
] }),
|
|
2357
|
-
state2.planMode ? /* @__PURE__ */
|
|
2358
|
-
/* @__PURE__ */
|
|
2359
|
-
/* @__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" })
|
|
2360
2412
|
] }) : null,
|
|
2361
|
-
activeTasks > 0 ? /* @__PURE__ */
|
|
2362
|
-
/* @__PURE__ */
|
|
2363
|
-
/* @__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: [
|
|
2364
2416
|
activeTasks,
|
|
2365
2417
|
" task",
|
|
2366
2418
|
activeTasks > 1 ? "s" : ""
|
|
2367
2419
|
] })
|
|
2368
2420
|
] }) : null,
|
|
2369
|
-
isStreaming ? /* @__PURE__ */
|
|
2370
|
-
/* @__PURE__ */
|
|
2371
|
-
/* @__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" })
|
|
2372
2424
|
] }) : null,
|
|
2373
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ jsxs5(Text5, { color: theme.dim, children: [
|
|
2374
2426
|
" ",
|
|
2375
2427
|
"\u2500".repeat(2)
|
|
2376
2428
|
] })
|
|
@@ -2379,8 +2431,8 @@ var StatusLine = memo3(function StatusLine2({ model, messageCount, tokenEstimate
|
|
|
2379
2431
|
|
|
2380
2432
|
// src/components/UserInput.tsx
|
|
2381
2433
|
init_theme();
|
|
2382
|
-
import { useState, useCallback, memo as
|
|
2383
|
-
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";
|
|
2384
2436
|
import TextInput from "ink-text-input";
|
|
2385
2437
|
|
|
2386
2438
|
// src/commands/help.ts
|
|
@@ -3416,10 +3468,10 @@ function getCommandNames() {
|
|
|
3416
3468
|
}
|
|
3417
3469
|
|
|
3418
3470
|
// src/components/UserInput.tsx
|
|
3419
|
-
import { Fragment as Fragment2, jsx as
|
|
3420
|
-
var UserInput =
|
|
3421
|
-
const [historyIdx, setHistoryIdx] =
|
|
3422
|
-
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("");
|
|
3423
3475
|
useInput((_input, key) => {
|
|
3424
3476
|
if (disabled || !history || history.length === 0) return;
|
|
3425
3477
|
if (key.upArrow) {
|
|
@@ -3465,20 +3517,20 @@ var UserInput = memo4(function UserInput2({ value, onChange, onSubmit, disabled,
|
|
|
3465
3517
|
const borderColor = disabled ? theme.dim : isBash ? theme.yellow : isCommand ? theme.purple : theme.cyan;
|
|
3466
3518
|
const promptChar = isBash ? "!" : "\u276F";
|
|
3467
3519
|
const promptColor = isBash ? theme.yellow : theme.cyan;
|
|
3468
|
-
return /* @__PURE__ */
|
|
3469
|
-
|
|
3520
|
+
return /* @__PURE__ */ jsxs6(
|
|
3521
|
+
Box6,
|
|
3470
3522
|
{
|
|
3471
3523
|
borderStyle: "round",
|
|
3472
3524
|
borderColor,
|
|
3473
3525
|
paddingLeft: 1,
|
|
3474
3526
|
paddingRight: 1,
|
|
3475
3527
|
children: [
|
|
3476
|
-
/* @__PURE__ */
|
|
3528
|
+
/* @__PURE__ */ jsxs6(Text6, { color: disabled ? theme.dim : promptColor, bold: true, children: [
|
|
3477
3529
|
promptChar,
|
|
3478
3530
|
" "
|
|
3479
3531
|
] }),
|
|
3480
|
-
disabled ? /* @__PURE__ */
|
|
3481
|
-
/* @__PURE__ */
|
|
3532
|
+
disabled ? /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: "..." }) : /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
3533
|
+
/* @__PURE__ */ jsx7(
|
|
3482
3534
|
TextInput,
|
|
3483
3535
|
{
|
|
3484
3536
|
value,
|
|
@@ -3492,7 +3544,7 @@ var UserInput = memo4(function UserInput2({ value, onChange, onSubmit, disabled,
|
|
|
3492
3544
|
}
|
|
3493
3545
|
}
|
|
3494
3546
|
),
|
|
3495
|
-
suggestion ? /* @__PURE__ */
|
|
3547
|
+
suggestion ? /* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: suggestion }) : null
|
|
3496
3548
|
] })
|
|
3497
3549
|
]
|
|
3498
3550
|
}
|
|
@@ -3508,7 +3560,7 @@ init_tools();
|
|
|
3508
3560
|
init_bash();
|
|
3509
3561
|
init_hooks();
|
|
3510
3562
|
init_theme();
|
|
3511
|
-
import { jsx as
|
|
3563
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3512
3564
|
function getContextLimit3(model) {
|
|
3513
3565
|
const lower = model.toLowerCase();
|
|
3514
3566
|
if (lower.includes("llama3.1")) return 131072;
|
|
@@ -3522,42 +3574,44 @@ function getContextLimit3(model) {
|
|
|
3522
3574
|
function REPL({ initialPrompt }) {
|
|
3523
3575
|
const { model: initialModel, systemPromptOverride, maxTurns, initialMessages, initialSessionId } = useDarkfooContext();
|
|
3524
3576
|
const { exit } = useApp();
|
|
3525
|
-
const [model, setModel] =
|
|
3526
|
-
const [messages, setMessages] =
|
|
3527
|
-
const [inputValue, setInputValue] =
|
|
3528
|
-
const [isStreaming, setIsStreaming] =
|
|
3529
|
-
const [
|
|
3530
|
-
const [activeTool, setActiveTool] =
|
|
3531
|
-
const [toolResults, setToolResults] =
|
|
3532
|
-
const [commandOutput, setCommandOutput] =
|
|
3533
|
-
const [inputHistory, setInputHistory] =
|
|
3534
|
-
const [tokenCounts, setTokenCounts] =
|
|
3535
|
-
const [systemPrompt, setSystemPrompt] =
|
|
3536
|
-
const [mascotMood, setMascotMood] =
|
|
3537
|
-
const [providerOnline, setProviderOnline] =
|
|
3538
|
-
const abortRef =
|
|
3539
|
-
const hasRun =
|
|
3540
|
-
const sessionId =
|
|
3541
|
-
const
|
|
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);
|
|
3542
3595
|
messagesRef.current = messages;
|
|
3543
|
-
const modelRef =
|
|
3596
|
+
const modelRef = useRef2(model);
|
|
3544
3597
|
modelRef.current = model;
|
|
3545
|
-
const systemPromptRef =
|
|
3598
|
+
const systemPromptRef = useRef2(systemPrompt);
|
|
3546
3599
|
systemPromptRef.current = systemPrompt;
|
|
3547
3600
|
const tools = getTools();
|
|
3548
3601
|
const cwd = process.cwd();
|
|
3549
|
-
|
|
3602
|
+
const providerName = useMemo(() => getActiveProviderName(), [model, providerOnline]);
|
|
3603
|
+
useEffect2(() => {
|
|
3550
3604
|
if (systemPromptOverride) {
|
|
3551
3605
|
setSystemPrompt(systemPromptOverride);
|
|
3552
3606
|
} else {
|
|
3553
3607
|
buildSystemPrompt(tools, cwd).then(setSystemPrompt);
|
|
3554
3608
|
}
|
|
3555
3609
|
}, []);
|
|
3556
|
-
|
|
3610
|
+
useEffect2(() => {
|
|
3557
3611
|
executeHooks("session_start", { cwd }).catch(() => {
|
|
3558
3612
|
});
|
|
3559
3613
|
}, []);
|
|
3560
|
-
|
|
3614
|
+
useEffect2(() => {
|
|
3561
3615
|
const provider = getProvider();
|
|
3562
3616
|
provider.healthCheck().then((ok) => {
|
|
3563
3617
|
setProviderOnline(ok);
|
|
@@ -3590,7 +3644,7 @@ function REPL({ initialPrompt }) {
|
|
|
3590
3644
|
});
|
|
3591
3645
|
}, []);
|
|
3592
3646
|
const clearMessages = useCallback2(() => setMessages([]), []);
|
|
3593
|
-
const commandContextRef =
|
|
3647
|
+
const commandContextRef = useRef2({
|
|
3594
3648
|
messages,
|
|
3595
3649
|
model,
|
|
3596
3650
|
cwd,
|
|
@@ -3618,15 +3672,17 @@ function REPL({ initialPrompt }) {
|
|
|
3618
3672
|
};
|
|
3619
3673
|
setMessages((prev) => [...prev, userMsg]);
|
|
3620
3674
|
setIsStreaming(true);
|
|
3621
|
-
|
|
3675
|
+
setReceivedText(false);
|
|
3622
3676
|
setToolResults([]);
|
|
3623
3677
|
setCommandOutput(null);
|
|
3624
3678
|
setMascotMood("thinking");
|
|
3679
|
+
streamingRef.current?.clear();
|
|
3625
3680
|
const controller = new AbortController();
|
|
3626
3681
|
abortRef.current = controller;
|
|
3627
3682
|
const allMessages = [...messagesRef.current, userMsg];
|
|
3628
3683
|
const currentModel = modelRef.current;
|
|
3629
3684
|
const currentSystemPrompt = systemPromptRef.current;
|
|
3685
|
+
let gotFirstText = false;
|
|
3630
3686
|
try {
|
|
3631
3687
|
for await (const event of query({
|
|
3632
3688
|
model: currentModel,
|
|
@@ -3639,8 +3695,12 @@ function REPL({ initialPrompt }) {
|
|
|
3639
3695
|
if (controller.signal.aborted) break;
|
|
3640
3696
|
switch (event.type) {
|
|
3641
3697
|
case "text_delta":
|
|
3642
|
-
|
|
3643
|
-
|
|
3698
|
+
streamingRef.current?.append(event.text);
|
|
3699
|
+
if (!gotFirstText) {
|
|
3700
|
+
gotFirstText = true;
|
|
3701
|
+
setReceivedText(true);
|
|
3702
|
+
setMascotMood("idle");
|
|
3703
|
+
}
|
|
3644
3704
|
break;
|
|
3645
3705
|
case "tool_call":
|
|
3646
3706
|
setActiveTool({ name: event.toolCall.function.name, args: event.toolCall.function.arguments });
|
|
@@ -3661,15 +3721,18 @@ function REPL({ initialPrompt }) {
|
|
|
3661
3721
|
}));
|
|
3662
3722
|
break;
|
|
3663
3723
|
case "assistant_message":
|
|
3724
|
+
streamingRef.current?.clear();
|
|
3725
|
+
setReceivedText(false);
|
|
3726
|
+
gotFirstText = false;
|
|
3664
3727
|
setMessages((prev) => {
|
|
3665
3728
|
const updated = [...prev, event.message];
|
|
3666
3729
|
saveSession(sessionId.current, updated, currentModel, cwd).catch(() => {
|
|
3667
3730
|
});
|
|
3668
3731
|
return updated;
|
|
3669
3732
|
});
|
|
3670
|
-
setStreamingText("");
|
|
3671
3733
|
break;
|
|
3672
3734
|
case "error":
|
|
3735
|
+
streamingRef.current?.clear();
|
|
3673
3736
|
setMascotMood("error");
|
|
3674
3737
|
setMessages((prev) => [
|
|
3675
3738
|
...prev,
|
|
@@ -3687,8 +3750,9 @@ function REPL({ initialPrompt }) {
|
|
|
3687
3750
|
]);
|
|
3688
3751
|
}
|
|
3689
3752
|
} finally {
|
|
3753
|
+
streamingRef.current?.clear();
|
|
3690
3754
|
setIsStreaming(false);
|
|
3691
|
-
|
|
3755
|
+
setReceivedText(false);
|
|
3692
3756
|
setActiveTool(null);
|
|
3693
3757
|
setToolResults([]);
|
|
3694
3758
|
setMascotMood((prev) => prev === "error" ? "error" : "success");
|
|
@@ -3752,14 +3816,14 @@ function REPL({ initialPrompt }) {
|
|
|
3752
3816
|
},
|
|
3753
3817
|
[addToHistory, exit, cwd, runQuery]
|
|
3754
3818
|
);
|
|
3755
|
-
|
|
3819
|
+
useEffect2(() => {
|
|
3756
3820
|
if (initialPrompt && !hasRun.current) {
|
|
3757
3821
|
hasRun.current = true;
|
|
3758
3822
|
runQuery(initialPrompt);
|
|
3759
3823
|
}
|
|
3760
3824
|
}, [initialPrompt, runQuery]);
|
|
3761
|
-
const autoCompactRef =
|
|
3762
|
-
|
|
3825
|
+
const autoCompactRef = useRef2(false);
|
|
3826
|
+
useEffect2(() => {
|
|
3763
3827
|
if (isStreaming || autoCompactRef.current || messages.length < 6) return;
|
|
3764
3828
|
const totalChars = messages.reduce((sum, m) => sum + m.content.length, 0);
|
|
3765
3829
|
const estTokens = Math.ceil(totalChars / 4) + 2e3;
|
|
@@ -3802,22 +3866,18 @@ ${result.content}
|
|
|
3802
3866
|
}
|
|
3803
3867
|
}
|
|
3804
3868
|
});
|
|
3805
|
-
return /* @__PURE__ */
|
|
3806
|
-
/* @__PURE__ */
|
|
3807
|
-
/* @__PURE__ */
|
|
3808
|
-
commandOutput ? /* @__PURE__ */
|
|
3809
|
-
toolResults.map((tr) => /* @__PURE__ */
|
|
3810
|
-
activeTool ? /* @__PURE__ */
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
/* @__PURE__ */
|
|
3814
|
-
/* @__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" })
|
|
3815
3879
|
] }) : null,
|
|
3816
|
-
|
|
3817
|
-
/* @__PURE__ */ jsx7(Text6, { color: theme.cyan, children: "..." }),
|
|
3818
|
-
/* @__PURE__ */ jsx7(Text6, { color: theme.dim, children: " Thinking" })
|
|
3819
|
-
] }) : null,
|
|
3820
|
-
/* @__PURE__ */ jsx7(
|
|
3880
|
+
/* @__PURE__ */ jsx8(
|
|
3821
3881
|
UserInput,
|
|
3822
3882
|
{
|
|
3823
3883
|
value: inputValue,
|
|
@@ -3827,7 +3887,7 @@ ${result.content}
|
|
|
3827
3887
|
history: inputHistory
|
|
3828
3888
|
}
|
|
3829
3889
|
),
|
|
3830
|
-
/* @__PURE__ */
|
|
3890
|
+
/* @__PURE__ */ jsx8(
|
|
3831
3891
|
StatusLine,
|
|
3832
3892
|
{
|
|
3833
3893
|
model,
|
|
@@ -3841,9 +3901,9 @@ ${result.content}
|
|
|
3841
3901
|
|
|
3842
3902
|
// src/main.tsx
|
|
3843
3903
|
init_providers();
|
|
3844
|
-
import { jsx as
|
|
3904
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
3845
3905
|
var program = new Command();
|
|
3846
|
-
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) => {
|
|
3847
3907
|
const { model, prompt, provider, systemPrompt } = options;
|
|
3848
3908
|
if (options.debug) {
|
|
3849
3909
|
const { setDebugMode: setDebugMode2 } = await Promise.resolve().then(() => (init_debug(), debug_exports));
|
|
@@ -3978,7 +4038,7 @@ Error: ${event.error}
|
|
|
3978
4038
|
}
|
|
3979
4039
|
}
|
|
3980
4040
|
const { waitUntilExit } = render(
|
|
3981
|
-
/* @__PURE__ */
|
|
4041
|
+
/* @__PURE__ */ jsx9(
|
|
3982
4042
|
App,
|
|
3983
4043
|
{
|
|
3984
4044
|
model: resolvedModel,
|
|
@@ -3986,7 +4046,7 @@ Error: ${event.error}
|
|
|
3986
4046
|
maxTurns,
|
|
3987
4047
|
initialMessages,
|
|
3988
4048
|
initialSessionId,
|
|
3989
|
-
children: /* @__PURE__ */
|
|
4049
|
+
children: /* @__PURE__ */ jsx9(REPL, {})
|
|
3990
4050
|
}
|
|
3991
4051
|
)
|
|
3992
4052
|
);
|