lupacode 1.0.0 → 1.0.1
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 +459 -123
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -85693,6 +85693,12 @@ var toolInputSchemas = {
|
|
|
85693
85693
|
command: exports_external.string().describe("Shell command to run"),
|
|
85694
85694
|
description: exports_external.string().optional().describe("Short description of the command"),
|
|
85695
85695
|
timeout: exports_external.number().optional().describe("Timeout in milliseconds")
|
|
85696
|
+
}),
|
|
85697
|
+
deleteFile: exports_external.object({
|
|
85698
|
+
path: exports_external.string().describe("Relative path to the file to delete")
|
|
85699
|
+
}),
|
|
85700
|
+
webSearch: exports_external.object({
|
|
85701
|
+
query: exports_external.string().describe("Search query for web search")
|
|
85696
85702
|
})
|
|
85697
85703
|
};
|
|
85698
85704
|
// node_modules/ai/node_modules/@ai-sdk/provider/dist/index.js
|
|
@@ -93401,10 +93407,18 @@ var readOnlyToolContracts = {
|
|
|
93401
93407
|
grep: tool({
|
|
93402
93408
|
description: "Search file contents with a regular expression under the current project directory.",
|
|
93403
93409
|
inputSchema: toolInputSchemas.grep
|
|
93410
|
+
}),
|
|
93411
|
+
webSearch: tool({
|
|
93412
|
+
description: "Search the web for up-to-date information on any topic.",
|
|
93413
|
+
inputSchema: toolInputSchemas.webSearch
|
|
93404
93414
|
})
|
|
93405
93415
|
};
|
|
93406
93416
|
var buildToolContracts = {
|
|
93407
93417
|
...readOnlyToolContracts,
|
|
93418
|
+
deleteFile: tool({
|
|
93419
|
+
description: "Delete a file under the current project directory.",
|
|
93420
|
+
inputSchema: toolInputSchemas.deleteFile
|
|
93421
|
+
}),
|
|
93408
93422
|
writeFile: tool({
|
|
93409
93423
|
description: "Create or overwrite a file under the current project directory.",
|
|
93410
93424
|
inputSchema: toolInputSchemas.writeFile
|
|
@@ -93421,7 +93435,7 @@ var buildToolContracts = {
|
|
|
93421
93435
|
// src/lib/shared/models.ts
|
|
93422
93436
|
var SUPPORTED_CHAT_MODELS = [
|
|
93423
93437
|
{
|
|
93424
|
-
id: "claude-sonnet-
|
|
93438
|
+
id: "claude-sonnet-5",
|
|
93425
93439
|
provider: "anthropic",
|
|
93426
93440
|
pricing: {
|
|
93427
93441
|
inputUsdPerMillionTokens: 3,
|
|
@@ -93429,7 +93443,7 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93429
93443
|
}
|
|
93430
93444
|
},
|
|
93431
93445
|
{
|
|
93432
|
-
id: "claude-
|
|
93446
|
+
id: "claude-haiku-4-5",
|
|
93433
93447
|
provider: "anthropic",
|
|
93434
93448
|
pricing: {
|
|
93435
93449
|
inputUsdPerMillionTokens: 1,
|
|
@@ -93437,7 +93451,7 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93437
93451
|
}
|
|
93438
93452
|
},
|
|
93439
93453
|
{
|
|
93440
|
-
id: "claude-opus-4-
|
|
93454
|
+
id: "claude-opus-4-8",
|
|
93441
93455
|
provider: "anthropic",
|
|
93442
93456
|
pricing: {
|
|
93443
93457
|
inputUsdPerMillionTokens: 5,
|
|
@@ -93445,7 +93459,7 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93445
93459
|
}
|
|
93446
93460
|
},
|
|
93447
93461
|
{
|
|
93448
|
-
id: "gpt-
|
|
93462
|
+
id: "gpt-5.5",
|
|
93449
93463
|
provider: "openai",
|
|
93450
93464
|
pricing: {
|
|
93451
93465
|
inputUsdPerMillionTokens: 2.5,
|
|
@@ -93453,7 +93467,7 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93453
93467
|
}
|
|
93454
93468
|
},
|
|
93455
93469
|
{
|
|
93456
|
-
id: "gpt-4
|
|
93470
|
+
id: "gpt-5.4-mini",
|
|
93457
93471
|
provider: "openai",
|
|
93458
93472
|
pricing: {
|
|
93459
93473
|
inputUsdPerMillionTokens: 0.75,
|
|
@@ -93461,7 +93475,7 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93461
93475
|
}
|
|
93462
93476
|
},
|
|
93463
93477
|
{
|
|
93464
|
-
id: "gpt-4
|
|
93478
|
+
id: "gpt-5.4-nano",
|
|
93465
93479
|
provider: "openai",
|
|
93466
93480
|
pricing: {
|
|
93467
93481
|
inputUsdPerMillionTokens: 0.2,
|
|
@@ -93469,19 +93483,19 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93469
93483
|
}
|
|
93470
93484
|
},
|
|
93471
93485
|
{
|
|
93472
|
-
id: "
|
|
93486
|
+
id: "cohere/north-mini-code:free",
|
|
93473
93487
|
provider: "openrouter",
|
|
93474
93488
|
pricing: {
|
|
93475
|
-
inputUsdPerMillionTokens: 0
|
|
93476
|
-
outputUsdPerMillionTokens:
|
|
93489
|
+
inputUsdPerMillionTokens: 0,
|
|
93490
|
+
outputUsdPerMillionTokens: 0
|
|
93477
93491
|
}
|
|
93478
93492
|
},
|
|
93479
93493
|
{
|
|
93480
|
-
id: "
|
|
93481
|
-
provider: "
|
|
93494
|
+
id: "deepseek/deepseek-chat-v3",
|
|
93495
|
+
provider: "openrouter",
|
|
93482
93496
|
pricing: {
|
|
93483
|
-
inputUsdPerMillionTokens: 0.
|
|
93484
|
-
outputUsdPerMillionTokens:
|
|
93497
|
+
inputUsdPerMillionTokens: 0.27,
|
|
93498
|
+
outputUsdPerMillionTokens: 1.1
|
|
93485
93499
|
}
|
|
93486
93500
|
},
|
|
93487
93501
|
{
|
|
@@ -93493,11 +93507,67 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93493
93507
|
}
|
|
93494
93508
|
},
|
|
93495
93509
|
{
|
|
93496
|
-
id: "deepseek/deepseek-
|
|
93510
|
+
id: "deepseek/deepseek-v3.2",
|
|
93497
93511
|
provider: "openrouter",
|
|
93498
93512
|
pricing: {
|
|
93499
|
-
inputUsdPerMillionTokens: 0.
|
|
93500
|
-
outputUsdPerMillionTokens:
|
|
93513
|
+
inputUsdPerMillionTokens: 0.2288,
|
|
93514
|
+
outputUsdPerMillionTokens: 0.3432
|
|
93515
|
+
}
|
|
93516
|
+
},
|
|
93517
|
+
{
|
|
93518
|
+
id: "deepseek/deepseek-v4-flash",
|
|
93519
|
+
provider: "openrouter",
|
|
93520
|
+
pricing: {
|
|
93521
|
+
inputUsdPerMillionTokens: 0.1,
|
|
93522
|
+
outputUsdPerMillionTokens: 0.2
|
|
93523
|
+
}
|
|
93524
|
+
},
|
|
93525
|
+
{
|
|
93526
|
+
id: "deepseek/deepseek-v4-pro",
|
|
93527
|
+
provider: "openrouter",
|
|
93528
|
+
pricing: {
|
|
93529
|
+
inputUsdPerMillionTokens: 0.435,
|
|
93530
|
+
outputUsdPerMillionTokens: 0.87
|
|
93531
|
+
}
|
|
93532
|
+
},
|
|
93533
|
+
{
|
|
93534
|
+
id: "nvidia/nemotron-3-super-120b-a12b:free",
|
|
93535
|
+
provider: "openrouter",
|
|
93536
|
+
pricing: {
|
|
93537
|
+
inputUsdPerMillionTokens: 0,
|
|
93538
|
+
outputUsdPerMillionTokens: 0
|
|
93539
|
+
}
|
|
93540
|
+
},
|
|
93541
|
+
{
|
|
93542
|
+
id: "nvidia/nemotron-3-ultra-550b-a55b:free",
|
|
93543
|
+
provider: "openrouter",
|
|
93544
|
+
pricing: {
|
|
93545
|
+
inputUsdPerMillionTokens: 0,
|
|
93546
|
+
outputUsdPerMillionTokens: 0
|
|
93547
|
+
}
|
|
93548
|
+
},
|
|
93549
|
+
{
|
|
93550
|
+
id: "poolside/laguna-m.1:free",
|
|
93551
|
+
provider: "openrouter",
|
|
93552
|
+
pricing: {
|
|
93553
|
+
inputUsdPerMillionTokens: 0,
|
|
93554
|
+
outputUsdPerMillionTokens: 0
|
|
93555
|
+
}
|
|
93556
|
+
},
|
|
93557
|
+
{
|
|
93558
|
+
id: "qwen/qwen3-coder",
|
|
93559
|
+
provider: "openrouter",
|
|
93560
|
+
pricing: {
|
|
93561
|
+
inputUsdPerMillionTokens: 0.3,
|
|
93562
|
+
outputUsdPerMillionTokens: 1.2
|
|
93563
|
+
}
|
|
93564
|
+
},
|
|
93565
|
+
{
|
|
93566
|
+
id: "qwen/qwen3-coder-next",
|
|
93567
|
+
provider: "openrouter",
|
|
93568
|
+
pricing: {
|
|
93569
|
+
inputUsdPerMillionTokens: 0.11,
|
|
93570
|
+
outputUsdPerMillionTokens: 0.8
|
|
93501
93571
|
}
|
|
93502
93572
|
},
|
|
93503
93573
|
{
|
|
@@ -93508,6 +93578,22 @@ var SUPPORTED_CHAT_MODELS = [
|
|
|
93508
93578
|
outputUsdPerMillionTokens: 0
|
|
93509
93579
|
}
|
|
93510
93580
|
},
|
|
93581
|
+
{
|
|
93582
|
+
id: "gemini-3-flash-lite",
|
|
93583
|
+
provider: "google",
|
|
93584
|
+
pricing: {
|
|
93585
|
+
inputUsdPerMillionTokens: 0.25,
|
|
93586
|
+
outputUsdPerMillionTokens: 1.5
|
|
93587
|
+
}
|
|
93588
|
+
},
|
|
93589
|
+
{
|
|
93590
|
+
id: "gemini-3-flash-preview",
|
|
93591
|
+
provider: "google",
|
|
93592
|
+
pricing: {
|
|
93593
|
+
inputUsdPerMillionTokens: 0.5,
|
|
93594
|
+
outputUsdPerMillionTokens: 3
|
|
93595
|
+
}
|
|
93596
|
+
},
|
|
93511
93597
|
{
|
|
93512
93598
|
id: "llama-3.3-70b-versatile",
|
|
93513
93599
|
provider: "groq",
|
|
@@ -93555,7 +93641,7 @@ function findSupportedChatModel(modelId) {
|
|
|
93555
93641
|
function isFreeModel(model) {
|
|
93556
93642
|
return model.pricing.inputUsdPerMillionTokens === 0 && model.pricing.outputUsdPerMillionTokens === 0;
|
|
93557
93643
|
}
|
|
93558
|
-
var DEFAULT_CHAT_MODEL_ID = "
|
|
93644
|
+
var DEFAULT_CHAT_MODEL_ID = "deepseek/deepseek-v4-flash";
|
|
93559
93645
|
// src/lib/shared/domains.ts
|
|
93560
93646
|
var DOMAINS = [
|
|
93561
93647
|
{
|
|
@@ -93823,11 +93909,8 @@ function DialogProvider({ children }) {
|
|
|
93823
93909
|
const [dialogStack, setDialogStack] = import_react24.useState([]);
|
|
93824
93910
|
const { push, pop } = useKeyboardLayer();
|
|
93825
93911
|
const close = import_react24.useCallback(() => {
|
|
93826
|
-
setDialogStack((prev) =>
|
|
93827
|
-
|
|
93828
|
-
pop("dialog");
|
|
93829
|
-
return next;
|
|
93830
|
-
});
|
|
93912
|
+
setDialogStack((prev) => prev.slice(0, -1));
|
|
93913
|
+
pop("dialog");
|
|
93831
93914
|
}, [pop]);
|
|
93832
93915
|
const open = import_react24.useCallback((config2) => {
|
|
93833
93916
|
setDialogStack((prev) => [...prev, config2]);
|
|
@@ -93994,7 +94077,7 @@ function RootLayout() {
|
|
|
93994
94077
|
}
|
|
93995
94078
|
|
|
93996
94079
|
// src/screens/home.tsx
|
|
93997
|
-
var
|
|
94080
|
+
var import_react42 = __toESM(require_react(), 1);
|
|
93998
94081
|
|
|
93999
94082
|
// src/components/header.tsx
|
|
94000
94083
|
function Header() {
|
|
@@ -94022,7 +94105,7 @@ function Header() {
|
|
|
94022
94105
|
}
|
|
94023
94106
|
|
|
94024
94107
|
// src/components/input-bar.tsx
|
|
94025
|
-
var
|
|
94108
|
+
var import_react40 = __toESM(require_react(), 1);
|
|
94026
94109
|
import { readdir } from "fs/promises";
|
|
94027
94110
|
import { isAbsolute as isAbsolute3, relative, resolve as resolve5 } from "path";
|
|
94028
94111
|
|
|
@@ -96333,7 +96416,7 @@ var import_react35 = __toESM(require_react(), 1);
|
|
|
96333
96416
|
// package.json
|
|
96334
96417
|
var package_default2 = {
|
|
96335
96418
|
name: "lupacode",
|
|
96336
|
-
version: "1.0.
|
|
96419
|
+
version: "1.0.1",
|
|
96337
96420
|
description: "AI-powered terminal coding assistant",
|
|
96338
96421
|
type: "module",
|
|
96339
96422
|
bin: {
|
|
@@ -96415,7 +96498,7 @@ async function checkForUpdate(currentVersion) {
|
|
|
96415
96498
|
const cache = readCache();
|
|
96416
96499
|
if (cache && Date.now() - cache.checkedAt < CHECK_INTERVAL_MS) {
|
|
96417
96500
|
cachedLatest = cache.latest;
|
|
96418
|
-
return cache.latest
|
|
96501
|
+
return isNewer(cache.latest, currentVersion) ? cache.latest : null;
|
|
96419
96502
|
}
|
|
96420
96503
|
try {
|
|
96421
96504
|
const res = await fetch("https://registry.npmjs.org/lupacode/latest");
|
|
@@ -96426,13 +96509,32 @@ async function checkForUpdate(currentVersion) {
|
|
|
96426
96509
|
const result = { latest, checkedAt: Date.now() };
|
|
96427
96510
|
writeCache(result);
|
|
96428
96511
|
cachedLatest = latest;
|
|
96429
|
-
return latest
|
|
96512
|
+
return isNewer(latest, currentVersion) ? latest : null;
|
|
96430
96513
|
} catch {
|
|
96431
96514
|
return null;
|
|
96432
96515
|
}
|
|
96433
96516
|
}
|
|
96517
|
+
function isNewer(latest, current) {
|
|
96518
|
+
if (!latest)
|
|
96519
|
+
return false;
|
|
96520
|
+
const a = parseSemver(latest);
|
|
96521
|
+
const b2 = parseSemver(current);
|
|
96522
|
+
if (!a || !b2)
|
|
96523
|
+
return false;
|
|
96524
|
+
if (a.major !== b2.major)
|
|
96525
|
+
return a.major > b2.major;
|
|
96526
|
+
if (a.minor !== b2.minor)
|
|
96527
|
+
return a.minor > b2.minor;
|
|
96528
|
+
return a.patch > b2.patch;
|
|
96529
|
+
}
|
|
96530
|
+
function parseSemver(v2) {
|
|
96531
|
+
const m2 = /^v?(\d+)\.(\d+)\.(\d+)/.exec(v2.trim());
|
|
96532
|
+
if (!m2 || m2[1] == null || m2[2] == null || m2[3] == null)
|
|
96533
|
+
return null;
|
|
96534
|
+
return { major: Number(m2[1]), minor: Number(m2[2]), patch: Number(m2[3]) };
|
|
96535
|
+
}
|
|
96434
96536
|
function hasUpdate() {
|
|
96435
|
-
return cachedLatest
|
|
96537
|
+
return isNewer(cachedLatest, cachedCurrent);
|
|
96436
96538
|
}
|
|
96437
96539
|
|
|
96438
96540
|
// src/components/dialogs/settings-dialog.tsx
|
|
@@ -96460,7 +96562,7 @@ var SettingsDialogContent = () => {
|
|
|
96460
96562
|
break;
|
|
96461
96563
|
case "model":
|
|
96462
96564
|
dialog.open({ title: "Select Model", children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ModelsDialogContent, {
|
|
96463
|
-
models: SUPPORTED_CHAT_MODELS,
|
|
96565
|
+
models: [...SUPPORTED_CHAT_MODELS],
|
|
96464
96566
|
onSelectModel: setModel
|
|
96465
96567
|
}, undefined, false, undefined, this) });
|
|
96466
96568
|
break;
|
|
@@ -96549,7 +96651,7 @@ var shortcuts = [
|
|
|
96549
96651
|
{ key: "ctrl+d", description: "Switch domain" },
|
|
96550
96652
|
{ key: "ctrl+s", description: "Open settings" },
|
|
96551
96653
|
{ key: "ctrl+r", description: "Regenerate last assistant response" },
|
|
96552
|
-
{ key: "e", description: "Edit last user message" },
|
|
96654
|
+
{ key: "ctrl+e", description: "Edit last user message" },
|
|
96553
96655
|
{ key: "escape", description: "Interrupt response / Cancel / Close dialog" }
|
|
96554
96656
|
];
|
|
96555
96657
|
var KeyboardHelpDialogContent = () => {
|
|
@@ -96616,6 +96718,9 @@ function StatusBar() {
|
|
|
96616
96718
|
}, undefined, true, undefined, this);
|
|
96617
96719
|
}
|
|
96618
96720
|
|
|
96721
|
+
// src/components/command-menu/commands.tsx
|
|
96722
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
96723
|
+
|
|
96619
96724
|
// ../../node_modules/open/index.js
|
|
96620
96725
|
import process9 from "process";
|
|
96621
96726
|
import path4 from "path";
|
|
@@ -97440,6 +97545,85 @@ var COMMANDS = [
|
|
|
97440
97545
|
}
|
|
97441
97546
|
}
|
|
97442
97547
|
},
|
|
97548
|
+
{
|
|
97549
|
+
name: "rename",
|
|
97550
|
+
description: "Rename the current session",
|
|
97551
|
+
value: "/rename",
|
|
97552
|
+
action: (ctx) => {
|
|
97553
|
+
if (!ctx.sessionId) {
|
|
97554
|
+
ctx.toast.show({ variant: "error", message: "No active session" });
|
|
97555
|
+
return;
|
|
97556
|
+
}
|
|
97557
|
+
const RenameDialog = () => {
|
|
97558
|
+
const [text2, setText] = import_react37.useState("");
|
|
97559
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
97560
|
+
flexDirection: "column",
|
|
97561
|
+
gap: 1,
|
|
97562
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("input", {
|
|
97563
|
+
focused: true,
|
|
97564
|
+
placeholder: "New session name",
|
|
97565
|
+
onContentChange: (event) => setText(String(event.value ?? event)),
|
|
97566
|
+
onSubmit: () => {
|
|
97567
|
+
const name23 = text2.trim();
|
|
97568
|
+
if (!name23)
|
|
97569
|
+
return;
|
|
97570
|
+
const baseUrl = process.env.API_URL ?? "https://lupacodeserver-production.up.railway.app";
|
|
97571
|
+
const token = getAuth()?.token ?? "";
|
|
97572
|
+
fetch(`${baseUrl}/sessions/${ctx.sessionId}`, {
|
|
97573
|
+
method: "PATCH",
|
|
97574
|
+
headers: {
|
|
97575
|
+
"Content-Type": "application/json",
|
|
97576
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
97577
|
+
},
|
|
97578
|
+
body: JSON.stringify({ title: name23 })
|
|
97579
|
+
}).then((res) => {
|
|
97580
|
+
if (!res.ok)
|
|
97581
|
+
throw new Error("Failed to rename");
|
|
97582
|
+
ctx.toast.show({ variant: "success", message: `Renamed to "${name23}"` });
|
|
97583
|
+
}).catch(() => {
|
|
97584
|
+
ctx.toast.show({ variant: "error", message: "Failed to rename session" });
|
|
97585
|
+
});
|
|
97586
|
+
ctx.dialog.close();
|
|
97587
|
+
}
|
|
97588
|
+
}, undefined, false, undefined, this)
|
|
97589
|
+
}, undefined, false, undefined, this);
|
|
97590
|
+
};
|
|
97591
|
+
ctx.dialog.open({ title: "Rename Session", children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(RenameDialog, {}, undefined, false, undefined, this) });
|
|
97592
|
+
}
|
|
97593
|
+
},
|
|
97594
|
+
{
|
|
97595
|
+
name: "export",
|
|
97596
|
+
description: "Export conversation as markdown",
|
|
97597
|
+
value: "/export",
|
|
97598
|
+
action: (ctx) => {
|
|
97599
|
+
if (!ctx.messages || ctx.messages.length === 0) {
|
|
97600
|
+
ctx.toast.show({ variant: "error", message: "No messages to export" });
|
|
97601
|
+
return;
|
|
97602
|
+
}
|
|
97603
|
+
const lines = [];
|
|
97604
|
+
lines.push("# Chat Export");
|
|
97605
|
+
lines.push("");
|
|
97606
|
+
for (const msg of ctx.messages) {
|
|
97607
|
+
const role = msg.role === "user" ? "User" : "Assistant";
|
|
97608
|
+
const text2 = msg.parts.filter((p) => p.type === "text").map((p) => p.text).join("");
|
|
97609
|
+
if (!text2)
|
|
97610
|
+
continue;
|
|
97611
|
+
lines.push(`**${role}:**`);
|
|
97612
|
+
lines.push("");
|
|
97613
|
+
lines.push(text2);
|
|
97614
|
+
lines.push("");
|
|
97615
|
+
}
|
|
97616
|
+
const content = lines.join(`
|
|
97617
|
+
`);
|
|
97618
|
+
const filename = `chat-export-${Date.now()}.md`;
|
|
97619
|
+
try {
|
|
97620
|
+
Bun.write(filename, content);
|
|
97621
|
+
ctx.toast.show({ variant: "success", message: `Exported to ${filename}` });
|
|
97622
|
+
} catch {
|
|
97623
|
+
ctx.toast.show({ variant: "error", message: "Failed to write export file" });
|
|
97624
|
+
}
|
|
97625
|
+
}
|
|
97626
|
+
},
|
|
97443
97627
|
{
|
|
97444
97628
|
name: "exit",
|
|
97445
97629
|
description: "Quit the application",
|
|
@@ -97520,15 +97704,15 @@ function CommandMenu({
|
|
|
97520
97704
|
}
|
|
97521
97705
|
|
|
97522
97706
|
// src/components/command-menu/use-command-menu.ts
|
|
97523
|
-
var
|
|
97707
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
97524
97708
|
function useCommandMenu() {
|
|
97525
|
-
const [textValue, setTextValue] =
|
|
97526
|
-
const [selectedIndex, setSelectedIndex] =
|
|
97527
|
-
const [showCommandMenu, setShowCommandMenu] =
|
|
97528
|
-
const scrollRef =
|
|
97709
|
+
const [textValue, setTextValue] = import_react38.useState("");
|
|
97710
|
+
const [selectedIndex, setSelectedIndex] = import_react38.useState(0);
|
|
97711
|
+
const [showCommandMenu, setShowCommandMenu] = import_react38.useState(false);
|
|
97712
|
+
const scrollRef = import_react38.useRef(null);
|
|
97529
97713
|
const { push, pop, isTopLayer } = useKeyboardLayer();
|
|
97530
97714
|
const commandQuery = showCommandMenu && textValue.startsWith("/") ? textValue.slice(1) : "";
|
|
97531
|
-
const filteredCommands =
|
|
97715
|
+
const filteredCommands = import_react38.useMemo(() => getFilteredCommands(commandQuery), [commandQuery]);
|
|
97532
97716
|
const close = () => {
|
|
97533
97717
|
setShowCommandMenu(false);
|
|
97534
97718
|
pop("command");
|
|
@@ -97785,21 +97969,21 @@ var TEXTAREA_KEY_BINDINGS = [
|
|
|
97785
97969
|
{ name: "return", shift: true, action: "newline" },
|
|
97786
97970
|
{ name: "enter", shift: true, action: "newline" }
|
|
97787
97971
|
];
|
|
97788
|
-
function InputBar({ onSubmit, disabled = false }) {
|
|
97972
|
+
function InputBar({ onSubmit, disabled = false, sessionId, messages }) {
|
|
97789
97973
|
const { mode, toggleMode, setMode, setModel, domain: domain2, setDomain } = usePromptConfig();
|
|
97790
|
-
const textareaRef =
|
|
97791
|
-
const onSubmitRef =
|
|
97792
|
-
const activeMentionRef =
|
|
97793
|
-
const mentionScrollRef =
|
|
97974
|
+
const textareaRef = import_react40.useRef(null);
|
|
97975
|
+
const onSubmitRef = import_react40.useRef(() => {});
|
|
97976
|
+
const activeMentionRef = import_react40.useRef(null);
|
|
97977
|
+
const mentionScrollRef = import_react40.useRef(null);
|
|
97794
97978
|
const renderer = useRenderer();
|
|
97795
97979
|
const toast = useToast();
|
|
97796
97980
|
const navigate = useNavigate();
|
|
97797
97981
|
const dialog = useDialog();
|
|
97798
97982
|
const { colors } = useTheme();
|
|
97799
97983
|
const { isTopLayer, setResponder, push, pop } = useKeyboardLayer();
|
|
97800
|
-
const [activeMention, setActiveMention] =
|
|
97801
|
-
const [mentionCandidates, setMentionCandidates] =
|
|
97802
|
-
const [mentionSelectedIndex, setMentionSelectedIndex] =
|
|
97984
|
+
const [activeMention, setActiveMention] = import_react40.useState(null);
|
|
97985
|
+
const [mentionCandidates, setMentionCandidates] = import_react40.useState([]);
|
|
97986
|
+
const [mentionSelectedIndex, setMentionSelectedIndex] = import_react40.useState(0);
|
|
97803
97987
|
const {
|
|
97804
97988
|
showCommandMenu,
|
|
97805
97989
|
commandQuery,
|
|
@@ -97810,13 +97994,13 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97810
97994
|
setSelectedIndex
|
|
97811
97995
|
} = useCommandMenu();
|
|
97812
97996
|
const showMentionMenu = activeMention !== null;
|
|
97813
|
-
const closeMentionMenu =
|
|
97997
|
+
const closeMentionMenu = import_react40.useCallback(() => {
|
|
97814
97998
|
activeMentionRef.current = null;
|
|
97815
97999
|
setActiveMention(null);
|
|
97816
98000
|
setMentionCandidates([]);
|
|
97817
98001
|
pop("mention");
|
|
97818
98002
|
}, [pop]);
|
|
97819
|
-
const syncMentionMenu =
|
|
98003
|
+
const syncMentionMenu = import_react40.useCallback((text2, cursorOffset) => {
|
|
97820
98004
|
const nextMention = findActiveMention(text2, cursorOffset);
|
|
97821
98005
|
const previousMention = activeMentionRef.current;
|
|
97822
98006
|
const mentionChanged = previousMention?.start !== nextMention?.start || previousMention?.end !== nextMention?.end || previousMention?.query !== nextMention?.query;
|
|
@@ -97839,7 +98023,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97839
98023
|
mentionScrollRef.current?.scrollTo(0);
|
|
97840
98024
|
}
|
|
97841
98025
|
}, [closeMentionMenu, push]);
|
|
97842
|
-
const handleTextareaContentChange =
|
|
98026
|
+
const handleTextareaContentChange = import_react40.useCallback(() => {
|
|
97843
98027
|
const textarea = textareaRef.current;
|
|
97844
98028
|
if (!textarea)
|
|
97845
98029
|
return;
|
|
@@ -97847,7 +98031,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97847
98031
|
handleContentChange(textarea.plainText);
|
|
97848
98032
|
syncMentionMenu(text2, textarea.cursorOffset);
|
|
97849
98033
|
}, [handleContentChange, syncMentionMenu]);
|
|
97850
|
-
const handleSubmit =
|
|
98034
|
+
const handleSubmit = import_react40.useCallback(() => {
|
|
97851
98035
|
if (disabled)
|
|
97852
98036
|
return;
|
|
97853
98037
|
const textarea = textareaRef.current;
|
|
@@ -97859,7 +98043,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97859
98043
|
onSubmit(text2);
|
|
97860
98044
|
textarea.setText("");
|
|
97861
98045
|
}, [disabled, onSubmit]);
|
|
97862
|
-
const handleMentionExecute =
|
|
98046
|
+
const handleMentionExecute = import_react40.useCallback((index) => {
|
|
97863
98047
|
const textarea = textareaRef.current;
|
|
97864
98048
|
const mention = activeMentionRef.current;
|
|
97865
98049
|
const candidate = mentionCandidates[index];
|
|
@@ -97871,13 +98055,13 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97871
98055
|
textarea.cursorOffset = mention.start + insertion.length + 1;
|
|
97872
98056
|
syncMentionMenu(nextText, textarea.cursorOffset);
|
|
97873
98057
|
}, [mentionCandidates, syncMentionMenu]);
|
|
97874
|
-
const handleTextareaCursorChange =
|
|
98058
|
+
const handleTextareaCursorChange = import_react40.useCallback(() => {
|
|
97875
98059
|
const textarea = textareaRef.current;
|
|
97876
98060
|
if (!textarea)
|
|
97877
98061
|
return;
|
|
97878
98062
|
syncMentionMenu(textarea.plainText, textarea.cursorOffset);
|
|
97879
98063
|
}, [syncMentionMenu]);
|
|
97880
|
-
const handleCommand =
|
|
98064
|
+
const handleCommand = import_react40.useCallback((command) => {
|
|
97881
98065
|
const textarea = textareaRef.current;
|
|
97882
98066
|
if (!textarea || !command)
|
|
97883
98067
|
return;
|
|
@@ -97891,17 +98075,19 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97891
98075
|
mode,
|
|
97892
98076
|
setMode,
|
|
97893
98077
|
setModel,
|
|
97894
|
-
setDomain
|
|
98078
|
+
setDomain,
|
|
98079
|
+
sessionId,
|
|
98080
|
+
messages
|
|
97895
98081
|
});
|
|
97896
98082
|
} else {
|
|
97897
98083
|
textarea.insertText(command.value + " ");
|
|
97898
98084
|
}
|
|
97899
98085
|
}, [renderer, toast, dialog, navigate, mode, setMode, setModel, setDomain]);
|
|
97900
|
-
const handleCommandExecute =
|
|
98086
|
+
const handleCommandExecute = import_react40.useCallback((index) => {
|
|
97901
98087
|
const command = resolveCommand(index);
|
|
97902
98088
|
handleCommand(command);
|
|
97903
98089
|
}, [resolveCommand, handleCommand]);
|
|
97904
|
-
|
|
98090
|
+
import_react40.useEffect(() => {
|
|
97905
98091
|
if (!activeMention) {
|
|
97906
98092
|
setMentionCandidates([]);
|
|
97907
98093
|
return;
|
|
@@ -97924,7 +98110,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97924
98110
|
ignore = true;
|
|
97925
98111
|
};
|
|
97926
98112
|
}, [activeMention]);
|
|
97927
|
-
|
|
98113
|
+
import_react40.useEffect(() => {
|
|
97928
98114
|
const textare = textareaRef.current;
|
|
97929
98115
|
if (!textare)
|
|
97930
98116
|
return;
|
|
@@ -97982,7 +98168,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
97982
98168
|
});
|
|
97983
98169
|
}
|
|
97984
98170
|
});
|
|
97985
|
-
|
|
98171
|
+
import_react40.useEffect(() => {
|
|
97986
98172
|
setResponder("base", () => {
|
|
97987
98173
|
if (disabled)
|
|
97988
98174
|
return false;
|
|
@@ -98100,7 +98286,7 @@ function InputBar({ onSubmit, disabled = false }) {
|
|
|
98100
98286
|
function Home() {
|
|
98101
98287
|
const navigate = useNavigate();
|
|
98102
98288
|
const { mode, model, domain: domain2 } = usePromptConfig();
|
|
98103
|
-
const handleSubmit =
|
|
98289
|
+
const handleSubmit = import_react42.useCallback((text2) => {
|
|
98104
98290
|
navigate("/sessions/new", { state: { message: text2, mode, model, domain: domain2 } });
|
|
98105
98291
|
}, [navigate, mode, model, domain2]);
|
|
98106
98292
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -98178,7 +98364,7 @@ function Home() {
|
|
|
98178
98364
|
}
|
|
98179
98365
|
|
|
98180
98366
|
// src/screens/new-session.tsx
|
|
98181
|
-
var
|
|
98367
|
+
var import_react45 = __toESM(require_react(), 1);
|
|
98182
98368
|
|
|
98183
98369
|
// src/components/messages/error-message.tsx
|
|
98184
98370
|
function ErrorMessage({ message: message2 }) {
|
|
@@ -98369,7 +98555,45 @@ function prettyMilliseconds(milliseconds, options) {
|
|
|
98369
98555
|
}
|
|
98370
98556
|
|
|
98371
98557
|
// src/components/messages/bot-message.tsx
|
|
98372
|
-
var globalSyntaxStyle = SyntaxStyle.
|
|
98558
|
+
var globalSyntaxStyle = SyntaxStyle.fromStyles({
|
|
98559
|
+
default: { fg: "#D4D4D4" },
|
|
98560
|
+
keyword: { fg: "#569CD6" },
|
|
98561
|
+
"keyword.control": { fg: "#C586C0" },
|
|
98562
|
+
"keyword.import": { fg: "#C586C0" },
|
|
98563
|
+
"keyword.function": { fg: "#DCDCAA" },
|
|
98564
|
+
string: { fg: "#CE9178" },
|
|
98565
|
+
"string.special": { fg: "#CE9178" },
|
|
98566
|
+
number: { fg: "#B5CEA8" },
|
|
98567
|
+
"number.float": { fg: "#B5CEA8" },
|
|
98568
|
+
comment: { fg: "#6A9955", italic: true },
|
|
98569
|
+
function: { fg: "#DCDCAA" },
|
|
98570
|
+
"function.call": { fg: "#DCDCAA" },
|
|
98571
|
+
"function.method": { fg: "#DCDCAA" },
|
|
98572
|
+
type: { fg: "#4EC9B0" },
|
|
98573
|
+
"type.builtin": { fg: "#4EC9B0" },
|
|
98574
|
+
variable: { fg: "#9CDCFE" },
|
|
98575
|
+
"variable.parameter": { fg: "#9CDCFE" },
|
|
98576
|
+
"variable.builtin": { fg: "#9CDCFE" },
|
|
98577
|
+
constant: { fg: "#4FC1FF" },
|
|
98578
|
+
"constant.builtin": { fg: "#569CD6" },
|
|
98579
|
+
property: { fg: "#9CDCFE" },
|
|
98580
|
+
operator: { fg: "#D4D4D4" },
|
|
98581
|
+
"punctuation.delimiter": { fg: "#D4D4D4" },
|
|
98582
|
+
"punctuation.bracket": { fg: "#D4D4D4" },
|
|
98583
|
+
boolean: { fg: "#569CD6" },
|
|
98584
|
+
label: { fg: "#DCDCAA" },
|
|
98585
|
+
"markup.heading": { fg: "#569CD6", bold: true },
|
|
98586
|
+
"markup.italic": { italic: true },
|
|
98587
|
+
"markup.strong": { fg: "#DCDCAA", bold: true },
|
|
98588
|
+
"markup.strikethrough": { fg: "#888888", italic: true, dim: true },
|
|
98589
|
+
"markup.raw": { fg: "#CE9178" },
|
|
98590
|
+
"markup.link": { fg: "#569CD6", underline: true },
|
|
98591
|
+
"markup.link.label": { fg: "#569CD6", underline: true },
|
|
98592
|
+
"markup.link.url": { fg: "#4FC1FF" },
|
|
98593
|
+
"markup.list": { fg: "#569CD6" },
|
|
98594
|
+
"markup.quote": { fg: "#6A9955", italic: true },
|
|
98595
|
+
conceal: { fg: "#555555" }
|
|
98596
|
+
});
|
|
98373
98597
|
function formatToolName(name23) {
|
|
98374
98598
|
return name23.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/^./, (c) => c.toUpperCase());
|
|
98375
98599
|
}
|
|
@@ -98383,6 +98607,79 @@ function formatToolArgs(tc) {
|
|
|
98383
98607
|
return String(tc.input);
|
|
98384
98608
|
return Object.values(tc.input).map(String).join(" ");
|
|
98385
98609
|
}
|
|
98610
|
+
function isBashTool(tc) {
|
|
98611
|
+
const name23 = tc.type === "dynamic-tool" ? tc.toolName : tc.type.slice("tool-".length);
|
|
98612
|
+
return name23 === "bash";
|
|
98613
|
+
}
|
|
98614
|
+
function isToolRunning(tc) {
|
|
98615
|
+
return tc.state !== "output-available" && tc.state !== "output-error";
|
|
98616
|
+
}
|
|
98617
|
+
function renderToolCall(tc, colors, j2, renderKey) {
|
|
98618
|
+
const toolName = tc.type === "dynamic-tool" ? tc.toolName : tc.type.slice("tool-".length);
|
|
98619
|
+
const running = isToolRunning(tc);
|
|
98620
|
+
const done = tc.state === "output-available";
|
|
98621
|
+
if (isBashTool(tc)) {
|
|
98622
|
+
const command = typeof tc.input === "object" && tc.input != null ? String(tc.input.command ?? "") : "";
|
|
98623
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
98624
|
+
width: "100%",
|
|
98625
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98626
|
+
attributes: TextAttributes.DIM,
|
|
98627
|
+
children: [
|
|
98628
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
|
|
98629
|
+
fg: colors.success,
|
|
98630
|
+
attributes: TextAttributes.BOLD,
|
|
98631
|
+
children: "$"
|
|
98632
|
+
}, undefined, false, undefined, this),
|
|
98633
|
+
" ",
|
|
98634
|
+
command,
|
|
98635
|
+
running ? "" : "",
|
|
98636
|
+
tc.state === "output-error" ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
|
|
98637
|
+
fg: colors.error,
|
|
98638
|
+
children: [
|
|
98639
|
+
" ",
|
|
98640
|
+
"\u2716",
|
|
98641
|
+
" ",
|
|
98642
|
+
tc.errorText
|
|
98643
|
+
]
|
|
98644
|
+
}, undefined, true, undefined, this) : null
|
|
98645
|
+
]
|
|
98646
|
+
}, undefined, true, undefined, this)
|
|
98647
|
+
}, renderKey, false, undefined, this);
|
|
98648
|
+
}
|
|
98649
|
+
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
98650
|
+
width: "100%",
|
|
98651
|
+
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98652
|
+
attributes: TextAttributes.DIM,
|
|
98653
|
+
children: [
|
|
98654
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
|
|
98655
|
+
fg: colors.info,
|
|
98656
|
+
children: [
|
|
98657
|
+
formatToolName(toolName),
|
|
98658
|
+
":"
|
|
98659
|
+
]
|
|
98660
|
+
}, undefined, true, undefined, this),
|
|
98661
|
+
" ",
|
|
98662
|
+
formatToolArgs(tc),
|
|
98663
|
+
running ? "..." : done ? " \u2713" : "",
|
|
98664
|
+
tc.state === "output-error" ? /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
|
|
98665
|
+
fg: colors.error,
|
|
98666
|
+
children: [
|
|
98667
|
+
" ",
|
|
98668
|
+
"\u2716",
|
|
98669
|
+
" ",
|
|
98670
|
+
tc.errorText
|
|
98671
|
+
]
|
|
98672
|
+
}, undefined, true, undefined, this) : null
|
|
98673
|
+
]
|
|
98674
|
+
}, undefined, true, undefined, this)
|
|
98675
|
+
}, renderKey, false, undefined, this);
|
|
98676
|
+
}
|
|
98677
|
+
function formatTokens(usage) {
|
|
98678
|
+
const total = usage.totalTokens ?? usage.inputTokens ?? usage.outputTokens;
|
|
98679
|
+
if (total == null)
|
|
98680
|
+
return "";
|
|
98681
|
+
return `${total.toLocaleString()} tok`;
|
|
98682
|
+
}
|
|
98386
98683
|
function mergeReasoningParts(parts) {
|
|
98387
98684
|
const reasoningParts = parts.filter((p) => p.type === "reasoning");
|
|
98388
98685
|
if (reasoningParts.length <= 1)
|
|
@@ -98420,6 +98717,7 @@ function BotMessage({
|
|
|
98420
98717
|
model,
|
|
98421
98718
|
mode,
|
|
98422
98719
|
durationMs,
|
|
98720
|
+
usage,
|
|
98423
98721
|
streaming = false
|
|
98424
98722
|
}) {
|
|
98425
98723
|
const { colors } = useTheme();
|
|
@@ -98445,22 +98743,7 @@ function BotMessage({
|
|
|
98445
98743
|
flexDirection: "column",
|
|
98446
98744
|
children: group.parts.map((part, j2) => {
|
|
98447
98745
|
const tc = part;
|
|
98448
|
-
|
|
98449
|
-
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98450
|
-
attributes: TextAttributes.DIM,
|
|
98451
|
-
children: [
|
|
98452
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
|
|
98453
|
-
fg: colors.info,
|
|
98454
|
-
children: [
|
|
98455
|
-
formatToolName(toolName),
|
|
98456
|
-
":"
|
|
98457
|
-
]
|
|
98458
|
-
}, undefined, true, undefined, this),
|
|
98459
|
-
formatToolArgs(tc),
|
|
98460
|
-
tc.state !== "output-available" && tc.state !== "output-error" ? "..." : "",
|
|
98461
|
-
tc.state === "output-error" ? ` ${tc.errorText}` : ""
|
|
98462
|
-
]
|
|
98463
|
-
}, tc.toolCallId, true, undefined, this);
|
|
98746
|
+
return renderToolCall(tc, colors, j2, tc.toolCallId);
|
|
98464
98747
|
})
|
|
98465
98748
|
}, undefined, false, undefined, this)
|
|
98466
98749
|
}, group.key, false, undefined, this);
|
|
@@ -98493,7 +98776,6 @@ function BotMessage({
|
|
|
98493
98776
|
}, `reasoning-${j2}`, false, undefined, this);
|
|
98494
98777
|
}
|
|
98495
98778
|
if (isToolPart(part)) {
|
|
98496
|
-
const toolName = part.type === "dynamic-tool" ? part.toolName : part.type.slice("tool-".length);
|
|
98497
98779
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
98498
98780
|
border: ["left"],
|
|
98499
98781
|
borderColor: colors.thinkingBorder,
|
|
@@ -98503,21 +98785,7 @@ function BotMessage({
|
|
|
98503
98785
|
},
|
|
98504
98786
|
width: "100%",
|
|
98505
98787
|
paddingX: 2,
|
|
98506
|
-
children:
|
|
98507
|
-
attributes: TextAttributes.DIM,
|
|
98508
|
-
children: [
|
|
98509
|
-
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("em", {
|
|
98510
|
-
fg: colors.info,
|
|
98511
|
-
children: [
|
|
98512
|
-
formatToolName(toolName),
|
|
98513
|
-
":"
|
|
98514
|
-
]
|
|
98515
|
-
}, undefined, true, undefined, this),
|
|
98516
|
-
formatToolArgs(part),
|
|
98517
|
-
part.state !== "output-available" && part.state !== "output-error" ? "..." : "",
|
|
98518
|
-
part.state === "output-error" ? ` ${part.errorText}` : ""
|
|
98519
|
-
]
|
|
98520
|
-
}, undefined, true, undefined, this)
|
|
98788
|
+
children: renderToolCall(part, colors, j2, part.toolCallId)
|
|
98521
98789
|
}, part.toolCallId, false, undefined, this);
|
|
98522
98790
|
}
|
|
98523
98791
|
if (part.type === "text") {
|
|
@@ -98527,7 +98795,17 @@ function BotMessage({
|
|
|
98527
98795
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("markdown", {
|
|
98528
98796
|
content: part.text,
|
|
98529
98797
|
syntaxStyle: globalSyntaxStyle,
|
|
98530
|
-
conceal: true
|
|
98798
|
+
conceal: true,
|
|
98799
|
+
concealCode: true,
|
|
98800
|
+
streaming,
|
|
98801
|
+
tableOptions: {
|
|
98802
|
+
style: "grid",
|
|
98803
|
+
borders: true,
|
|
98804
|
+
outerBorder: true,
|
|
98805
|
+
borderStyle: "rounded",
|
|
98806
|
+
cellPadding: 1,
|
|
98807
|
+
borderColor: "#555555"
|
|
98808
|
+
}
|
|
98531
98809
|
}, undefined, false, undefined, this)
|
|
98532
98810
|
}, `text-${j2}`, false, undefined, this);
|
|
98533
98811
|
}
|
|
@@ -98576,6 +98854,19 @@ function BotMessage({
|
|
|
98576
98854
|
children: prettyMilliseconds(durationMs)
|
|
98577
98855
|
}, undefined, false, undefined, this)
|
|
98578
98856
|
]
|
|
98857
|
+
}, undefined, true, undefined, this),
|
|
98858
|
+
usage && formatTokens(usage) && /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(import_jsx_dev_runtime2.Fragment, {
|
|
98859
|
+
children: [
|
|
98860
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98861
|
+
attributes: TextAttributes.DIM,
|
|
98862
|
+
fg: colors.dimSeparator,
|
|
98863
|
+
children: ">"
|
|
98864
|
+
}, undefined, false, undefined, this),
|
|
98865
|
+
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("text", {
|
|
98866
|
+
attributes: TextAttributes.DIM,
|
|
98867
|
+
children: formatTokens(usage)
|
|
98868
|
+
}, undefined, false, undefined, this)
|
|
98869
|
+
]
|
|
98579
98870
|
}, undefined, true, undefined, this)
|
|
98580
98871
|
]
|
|
98581
98872
|
}, undefined, true, undefined, this)
|
|
@@ -100570,7 +100861,9 @@ function SessionShell({
|
|
|
100570
100861
|
onSubmit,
|
|
100571
100862
|
inputDisabled = false,
|
|
100572
100863
|
loading = false,
|
|
100573
|
-
interruptible = false
|
|
100864
|
+
interruptible = false,
|
|
100865
|
+
sessionId,
|
|
100866
|
+
messages
|
|
100574
100867
|
}) {
|
|
100575
100868
|
const { mode } = usePromptConfig();
|
|
100576
100869
|
return /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -100595,7 +100888,9 @@ function SessionShell({
|
|
|
100595
100888
|
flexShrink: 0,
|
|
100596
100889
|
children: /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(InputBar, {
|
|
100597
100890
|
onSubmit,
|
|
100598
|
-
disabled: inputDisabled
|
|
100891
|
+
disabled: inputDisabled,
|
|
100892
|
+
sessionId,
|
|
100893
|
+
messages
|
|
100599
100894
|
}, undefined, false, undefined, this)
|
|
100600
100895
|
}, undefined, false, undefined, this),
|
|
100601
100896
|
/* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV("box", {
|
|
@@ -100684,17 +100979,17 @@ function NewSession() {
|
|
|
100684
100979
|
const navigate = useNavigate();
|
|
100685
100980
|
const location = useLocation();
|
|
100686
100981
|
const toast = useToast();
|
|
100687
|
-
const hasStartedRef =
|
|
100688
|
-
const state =
|
|
100982
|
+
const hasStartedRef = import_react45.useRef(false);
|
|
100983
|
+
const state = import_react45.useMemo(() => {
|
|
100689
100984
|
const parsed = newSessionStateSchema.safeParse(location.state);
|
|
100690
100985
|
return parsed.success ? parsed.data : null;
|
|
100691
100986
|
}, [location.state]);
|
|
100692
|
-
|
|
100987
|
+
import_react45.useEffect(() => {
|
|
100693
100988
|
if (!state?.message) {
|
|
100694
100989
|
navigate("/", { replace: true });
|
|
100695
100990
|
}
|
|
100696
100991
|
}, [state, navigate]);
|
|
100697
|
-
|
|
100992
|
+
import_react45.useEffect(() => {
|
|
100698
100993
|
if (!state || hasStartedRef.current)
|
|
100699
100994
|
return;
|
|
100700
100995
|
hasStartedRef.current = true;
|
|
@@ -100742,13 +101037,13 @@ function NewSession() {
|
|
|
100742
101037
|
}
|
|
100743
101038
|
|
|
100744
101039
|
// src/screens/sessions.tsx
|
|
100745
|
-
var
|
|
101040
|
+
var import_react54 = __toESM(require_react(), 1);
|
|
100746
101041
|
|
|
100747
101042
|
// src/hooks/use-chat.ts
|
|
100748
|
-
var
|
|
101043
|
+
var import_react52 = __toESM(require_react(), 1);
|
|
100749
101044
|
|
|
100750
101045
|
// ../../node_modules/@ai-sdk/react/dist/index.js
|
|
100751
|
-
var
|
|
101046
|
+
var import_react46 = __toESM(require_react(), 1);
|
|
100752
101047
|
|
|
100753
101048
|
// ../../node_modules/@ai-sdk/react/node_modules/@ai-sdk/provider/dist/index.js
|
|
100754
101049
|
var marker23 = "vercel.ai.error";
|
|
@@ -105501,11 +105796,11 @@ var AbstractChat = class {
|
|
|
105501
105796
|
|
|
105502
105797
|
// ../../node_modules/@ai-sdk/react/dist/index.js
|
|
105503
105798
|
var import_throttleit = __toESM(require_throttleit(), 1);
|
|
105504
|
-
var import_react46 = __toESM(require_react(), 1);
|
|
105505
105799
|
var import_react47 = __toESM(require_react(), 1);
|
|
105506
105800
|
var import_react48 = __toESM(require_react(), 1);
|
|
105507
105801
|
var import_react49 = __toESM(require_react(), 1);
|
|
105508
105802
|
var import_react50 = __toESM(require_react(), 1);
|
|
105803
|
+
var import_react51 = __toESM(require_react(), 1);
|
|
105509
105804
|
var import_jsx_runtime = __toESM(require_jsx_runtime(), 1);
|
|
105510
105805
|
var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1);
|
|
105511
105806
|
var __accessCheck = (obj, member, msg) => {
|
|
@@ -105642,7 +105937,7 @@ function useChat({
|
|
|
105642
105937
|
resume = false,
|
|
105643
105938
|
...options
|
|
105644
105939
|
} = {}) {
|
|
105645
|
-
const callbacksRef =
|
|
105940
|
+
const callbacksRef = import_react46.useRef(!("chat" in options) ? {
|
|
105646
105941
|
onToolCall: options.onToolCall,
|
|
105647
105942
|
onData: options.onData,
|
|
105648
105943
|
onFinish: options.onFinish,
|
|
@@ -105681,22 +105976,22 @@ function useChat({
|
|
|
105681
105976
|
return (_c = (_b17 = (_a29 = callbacksRef.current).sendAutomaticallyWhen) == null ? undefined : _b17.call(_a29, arg)) != null ? _c : false;
|
|
105682
105977
|
}
|
|
105683
105978
|
};
|
|
105684
|
-
const chatRef =
|
|
105979
|
+
const chatRef = import_react46.useRef("chat" in options ? options.chat : new Chat(optionsWithCallbacks));
|
|
105685
105980
|
const shouldRecreateChat = "chat" in options && options.chat !== chatRef.current || "id" in options && chatRef.current.id !== options.id;
|
|
105686
105981
|
if (shouldRecreateChat) {
|
|
105687
105982
|
chatRef.current = "chat" in options ? options.chat : new Chat(optionsWithCallbacks);
|
|
105688
105983
|
}
|
|
105689
|
-
const subscribeToMessages =
|
|
105690
|
-
const messages =
|
|
105691
|
-
const status =
|
|
105692
|
-
const error51 =
|
|
105693
|
-
const setMessages =
|
|
105984
|
+
const subscribeToMessages = import_react46.useCallback((update) => chatRef.current["~registerMessagesCallback"](update, throttleWaitMs), [throttleWaitMs, chatRef.current.id]);
|
|
105985
|
+
const messages = import_react46.useSyncExternalStore(subscribeToMessages, () => chatRef.current.messages, () => chatRef.current.messages);
|
|
105986
|
+
const status = import_react46.useSyncExternalStore(chatRef.current["~registerStatusCallback"], () => chatRef.current.status, () => chatRef.current.status);
|
|
105987
|
+
const error51 = import_react46.useSyncExternalStore(chatRef.current["~registerErrorCallback"], () => chatRef.current.error, () => chatRef.current.error);
|
|
105988
|
+
const setMessages = import_react46.useCallback((messagesParam) => {
|
|
105694
105989
|
if (typeof messagesParam === "function") {
|
|
105695
105990
|
messagesParam = messagesParam(chatRef.current.messages);
|
|
105696
105991
|
}
|
|
105697
105992
|
chatRef.current.messages = messagesParam;
|
|
105698
105993
|
}, [chatRef]);
|
|
105699
|
-
|
|
105994
|
+
import_react46.useEffect(() => {
|
|
105700
105995
|
if (resume) {
|
|
105701
105996
|
chatRef.current.resumeStream();
|
|
105702
105997
|
}
|
|
@@ -105719,7 +106014,7 @@ function useChat({
|
|
|
105719
106014
|
}
|
|
105720
106015
|
|
|
105721
106016
|
// src/lib/local-tools.ts
|
|
105722
|
-
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir2, stat, writeFile as writeFile2 } from "fs/promises";
|
|
106017
|
+
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir2, stat, writeFile as writeFile2, unlink as unlink2 } from "fs/promises";
|
|
105723
106018
|
import { dirname as dirname2, isAbsolute as isAbsolute5, join as join5, relative as relative2, resolve as resolve7 } from "path";
|
|
105724
106019
|
var MAX_FILE_SIZE = 1e4;
|
|
105725
106020
|
var MAX_RESULTS = 200;
|
|
@@ -105739,7 +106034,7 @@ function truncate(value, limit) {
|
|
|
105739
106034
|
return value.length > limit ? `${value.slice(0, limit)}n... (truncated, ${value.length} total chars)` : value;
|
|
105740
106035
|
}
|
|
105741
106036
|
async function executeLocalTool(toolName, input, mode) {
|
|
105742
|
-
if (mode === Mode.PLAN && !["readFile", "listDirectory", "glob", "grep"].includes(toolName)) {
|
|
106037
|
+
if (mode === Mode.PLAN && !["readFile", "listDirectory", "glob", "grep", "webSearch"].includes(toolName)) {
|
|
105743
106038
|
throw new Error(`Tool ${toolName} is not available in PLAN mode`);
|
|
105744
106039
|
}
|
|
105745
106040
|
switch (toolName) {
|
|
@@ -105849,11 +106144,15 @@ async function executeLocalTool(toolName, input, mode) {
|
|
|
105849
106144
|
}
|
|
105850
106145
|
case "bash": {
|
|
105851
106146
|
const { command, timeout = DEFAULT_TIMEOUT } = toolInputSchemas.bash.parse(input);
|
|
105852
|
-
const
|
|
106147
|
+
const isWindows = process.platform === "win32";
|
|
106148
|
+
const shell = isWindows ? "cmd.exe" : "bash";
|
|
106149
|
+
const shellFlag = isWindows ? "/c" : "-c";
|
|
106150
|
+
const env2 = isWindows ? { ...process.env } : { ...process.env, TERM: "dumb" };
|
|
106151
|
+
const proc = Bun.spawn([shell, shellFlag, command], {
|
|
105853
106152
|
cwd: resolveInsideCwd(".").resolved,
|
|
105854
106153
|
stdout: "pipe",
|
|
105855
106154
|
stderr: "pipe",
|
|
105856
|
-
env:
|
|
106155
|
+
env: env2
|
|
105857
106156
|
});
|
|
105858
106157
|
const timer = setTimeout(() => proc.kill(), timeout);
|
|
105859
106158
|
const [stdout, stderr] = await Promise.all([
|
|
@@ -105868,6 +106167,40 @@ async function executeLocalTool(toolName, input, mode) {
|
|
|
105868
106167
|
exitCode
|
|
105869
106168
|
};
|
|
105870
106169
|
}
|
|
106170
|
+
case "deleteFile": {
|
|
106171
|
+
const { path: path5 } = toolInputSchemas.deleteFile.parse(input);
|
|
106172
|
+
const { cwd, resolved } = resolveInsideCwd(path5);
|
|
106173
|
+
await unlink2(resolved);
|
|
106174
|
+
return { success: true, path: relative2(cwd, resolved) };
|
|
106175
|
+
}
|
|
106176
|
+
case "webSearch": {
|
|
106177
|
+
const { query } = toolInputSchemas.webSearch.parse(input);
|
|
106178
|
+
const apiKey = process.env.TAVILY_API_KEY;
|
|
106179
|
+
if (!apiKey)
|
|
106180
|
+
throw new Error("TAVILY_API_KEY is not set");
|
|
106181
|
+
const res = await fetch("https://api.tavily.com/search", {
|
|
106182
|
+
method: "POST",
|
|
106183
|
+
headers: { "Content-Type": "application/json" },
|
|
106184
|
+
body: JSON.stringify({
|
|
106185
|
+
api_key: apiKey,
|
|
106186
|
+
query,
|
|
106187
|
+
search_depth: "advanced",
|
|
106188
|
+
include_answer: true,
|
|
106189
|
+
max_results: 5
|
|
106190
|
+
})
|
|
106191
|
+
});
|
|
106192
|
+
if (!res.ok)
|
|
106193
|
+
throw new Error(`Web search failed: ${res.status} ${res.statusText}`);
|
|
106194
|
+
const data2 = await res.json();
|
|
106195
|
+
return {
|
|
106196
|
+
results: data2.results.map((r) => ({
|
|
106197
|
+
title: r.title,
|
|
106198
|
+
url: r.url,
|
|
106199
|
+
content: r.content
|
|
106200
|
+
})),
|
|
106201
|
+
answer: data2.answer
|
|
106202
|
+
};
|
|
106203
|
+
}
|
|
105871
106204
|
default:
|
|
105872
106205
|
throw new Error(`Unknown tool ${toolName}`);
|
|
105873
106206
|
}
|
|
@@ -105875,7 +106208,7 @@ async function executeLocalTool(toolName, input, mode) {
|
|
|
105875
106208
|
|
|
105876
106209
|
// src/hooks/use-chat.ts
|
|
105877
106210
|
function useChat2(sessionId, initialMessages) {
|
|
105878
|
-
const transport =
|
|
106211
|
+
const transport = import_react52.useMemo(() => {
|
|
105879
106212
|
return new DefaultChatTransport({
|
|
105880
106213
|
api: apiClient.chat.$url().toString(),
|
|
105881
106214
|
headers() {
|
|
@@ -105963,6 +106296,7 @@ function ChatMessage({ msg }) {
|
|
|
105963
106296
|
model: msg.metadata?.model ?? "unknown",
|
|
105964
106297
|
mode: msg.metadata?.mode ?? "BUILD",
|
|
105965
106298
|
durationMs: msg.metadata?.durationMs,
|
|
106299
|
+
usage: msg.metadata?.usage,
|
|
105966
106300
|
streaming: false
|
|
105967
106301
|
}, undefined, false, undefined, this);
|
|
105968
106302
|
}
|
|
@@ -105986,14 +106320,14 @@ function SessionChat({
|
|
|
105986
106320
|
session,
|
|
105987
106321
|
initialPrompt
|
|
105988
106322
|
}) {
|
|
105989
|
-
const [initialMessages] =
|
|
106323
|
+
const [initialMessages] = import_react54.useState(() => session.messages);
|
|
105990
106324
|
const { mode, model, domain: domain2 } = usePromptConfig();
|
|
105991
106325
|
const { isTopLayer } = useKeyboardLayer();
|
|
105992
106326
|
const { messages, status, submit, setMessages, reload, abort, interrupt, error: error51 } = useChat2(session.id, initialMessages);
|
|
105993
|
-
const hasSubmittedInitialPromptRef =
|
|
106327
|
+
const hasSubmittedInitialPromptRef = import_react54.useRef(false);
|
|
105994
106328
|
const toast = useToast();
|
|
105995
106329
|
const dialog = useDialog();
|
|
105996
|
-
|
|
106330
|
+
import_react54.useEffect(() => {
|
|
105997
106331
|
return () => {
|
|
105998
106332
|
abort();
|
|
105999
106333
|
};
|
|
@@ -106014,7 +106348,7 @@ function SessionChat({
|
|
|
106014
106348
|
}
|
|
106015
106349
|
});
|
|
106016
106350
|
useKeyboard((key) => {
|
|
106017
|
-
if (key.name === "e" &&
|
|
106351
|
+
if (key.name === "e" && key.ctrl && isTopLayer("base") && status !== "streaming" && status !== "submitted") {
|
|
106018
106352
|
const lastUserMsg = messages.findLast((m2) => m2.role === "user");
|
|
106019
106353
|
if (!lastUserMsg)
|
|
106020
106354
|
return;
|
|
@@ -106052,7 +106386,7 @@ function SessionChat({
|
|
|
106052
106386
|
});
|
|
106053
106387
|
}
|
|
106054
106388
|
});
|
|
106055
|
-
|
|
106389
|
+
import_react54.useEffect(() => {
|
|
106056
106390
|
if (!initialPrompt || hasSubmittedInitialPromptRef.current)
|
|
106057
106391
|
return;
|
|
106058
106392
|
hasSubmittedInitialPromptRef.current = true;
|
|
@@ -106066,6 +106400,8 @@ function SessionChat({
|
|
|
106066
106400
|
onSubmit: (text3) => submit({ userText: text3, mode, model, domain: domain2 }),
|
|
106067
106401
|
loading: status === "submitted" || status === "streaming",
|
|
106068
106402
|
interruptible: status === "submitted" || status === "streaming",
|
|
106403
|
+
sessionId: session.id,
|
|
106404
|
+
messages,
|
|
106069
106405
|
children: [
|
|
106070
106406
|
messages.map((msg) => /* @__PURE__ */ import_jsx_dev_runtime2.jsxDEV(ChatMessage, {
|
|
106071
106407
|
msg
|
|
@@ -106081,12 +106417,12 @@ function Session() {
|
|
|
106081
106417
|
const location = useLocation();
|
|
106082
106418
|
const navigate = useNavigate();
|
|
106083
106419
|
const toast = useToast();
|
|
106084
|
-
const prefetched =
|
|
106420
|
+
const prefetched = import_react54.useMemo(() => {
|
|
106085
106421
|
const parsed = sessionLocationSchema.safeParse(location.state);
|
|
106086
106422
|
return parsed.success ? parsed.data : null;
|
|
106087
106423
|
}, [location.state]);
|
|
106088
|
-
const [session, setSession] =
|
|
106089
|
-
|
|
106424
|
+
const [session, setSession] = import_react54.useState(prefetched?.session ?? null);
|
|
106425
|
+
import_react54.useEffect(() => {
|
|
106090
106426
|
if (prefetched?.session)
|
|
106091
106427
|
return;
|
|
106092
106428
|
setSession(null);
|