unrag 0.2.9 → 0.2.11
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/cli/index.js +227 -29
- package/dist/debug-tui/index.js +145 -0
- package/package.json +7 -3
- package/registry/connectors/google-drive/_api-types.ts +4 -0
- package/registry/connectors/google-drive/client.ts +2 -2
- package/registry/connectors/google-drive/index.ts +4 -4
- package/registry/connectors/google-drive/mime.ts +1 -1
- package/registry/connectors/google-drive/sync.ts +7 -7
- package/registry/connectors/google-drive/types.ts +3 -3
- package/registry/connectors/notion/index.ts +13 -5
- package/registry/connectors/notion/render.ts +1 -1
- package/registry/connectors/notion/sync.ts +5 -5
- package/registry/connectors/notion/types.ts +3 -4
- package/registry/core/assets.ts +2 -2
- package/registry/core/chunking.ts +1 -1
- package/registry/core/config.ts +4 -3
- package/registry/core/context-engine.ts +96 -18
- package/registry/core/debug-emitter.ts +162 -0
- package/registry/core/debug-events.ts +222 -0
- package/registry/core/deep-merge.ts +1 -1
- package/registry/core/delete.ts +41 -1
- package/registry/core/index.ts +10 -10
- package/registry/core/ingest.ts +106 -5
- package/registry/core/rerank.ts +37 -1
- package/registry/core/retrieve.ts +62 -2
- package/registry/core/types.ts +11 -6
- package/registry/debug/client.ts +332 -0
- package/registry/debug/commands.ts +699 -0
- package/registry/debug/index.ts +93 -0
- package/registry/debug/runtime.ts +63 -0
- package/registry/debug/server.ts +554 -0
- package/registry/debug/tui/App.tsx +193 -0
- package/registry/debug/tui/assets/unragLogo.ts +36 -0
- package/registry/debug/tui/components/Dashboard.tsx +192 -0
- package/registry/debug/tui/components/Docs.tsx +563 -0
- package/registry/debug/tui/components/Doctor.tsx +290 -0
- package/registry/debug/tui/components/Eval.tsx +377 -0
- package/registry/debug/tui/components/EventDetail.tsx +237 -0
- package/registry/debug/tui/components/EventList.tsx +202 -0
- package/registry/debug/tui/components/EventRow.tsx +104 -0
- package/registry/debug/tui/components/Header.tsx +58 -0
- package/registry/debug/tui/components/HelpOverlay.tsx +101 -0
- package/registry/debug/tui/components/Ingest.tsx +351 -0
- package/registry/debug/tui/components/Logo.tsx +138 -0
- package/registry/debug/tui/components/MetricCard.tsx +59 -0
- package/registry/debug/tui/components/QueryRunner.tsx +327 -0
- package/registry/debug/tui/components/ScrollableText.tsx +120 -0
- package/registry/debug/tui/components/Sparkline.tsx +71 -0
- package/registry/debug/tui/components/StatusBar.tsx +63 -0
- package/registry/debug/tui/components/TabBar.tsx +45 -0
- package/registry/debug/tui/components/Traces.tsx +294 -0
- package/registry/debug/tui/context/HotkeysLock.tsx +68 -0
- package/registry/debug/tui/hooks/useConnection.ts +155 -0
- package/registry/debug/tui/hooks/useEvents.ts +68 -0
- package/registry/debug/tui/hooks/useScrollWindow.ts +58 -0
- package/registry/debug/tui/hooks/useTerminalSize.ts +45 -0
- package/registry/debug/tui/theme.ts +175 -0
- package/registry/debug/types.ts +593 -0
- package/registry/debug/unrag-json.ts +40 -0
- package/registry/embedding/ai.ts +1 -1
- package/registry/embedding/azure.ts +3 -3
- package/registry/embedding/bedrock.ts +3 -3
- package/registry/embedding/cohere.ts +3 -3
- package/registry/embedding/google.ts +3 -3
- package/registry/embedding/mistral.ts +3 -3
- package/registry/embedding/ollama.ts +3 -3
- package/registry/embedding/openai.ts +3 -3
- package/registry/embedding/openrouter.ts +2 -2
- package/registry/embedding/together.ts +8 -4
- package/registry/embedding/vertex.ts +3 -3
- package/registry/embedding/voyage.ts +141 -101
- package/registry/eval/index.ts +8 -8
- package/registry/eval/report.ts +2 -2
- package/registry/eval/runner.ts +10 -6
- package/registry/extractors/_shared/fetch.ts +1 -1
- package/registry/extractors/audio-transcribe/index.ts +2 -2
- package/registry/extractors/file-docx/index.ts +6 -8
- package/registry/extractors/file-pptx/index.ts +4 -4
- package/registry/extractors/file-text/index.ts +4 -4
- package/registry/extractors/file-xlsx/index.ts +4 -4
- package/registry/extractors/image-caption-llm/index.ts +4 -4
- package/registry/extractors/image-ocr/index.ts +4 -4
- package/registry/extractors/pdf-llm/index.ts +4 -4
- package/registry/extractors/pdf-ocr/index.ts +3 -3
- package/registry/extractors/pdf-text-layer/index.ts +3 -3
- package/registry/extractors/video-frames/index.ts +3 -3
- package/registry/extractors/video-transcribe/index.ts +2 -2
- package/registry/manifest.json +9 -0
- package/registry/rerank/cohere.ts +7 -7
- package/registry/rerank/custom.ts +2 -2
- package/registry/rerank/index.ts +3 -3
- package/registry/rerank/types.ts +1 -1
- package/registry/shims.d.ts +60 -0
- package/registry/store/drizzle/index.ts +9 -0
- package/registry/store/drizzle/store.ts +386 -0
- package/registry/store/prisma/index.ts +3 -0
- package/registry/store/prisma/store.ts +330 -0
- package/registry/store/raw-sql/index.ts +3 -0
- package/registry/store/raw-sql/store.ts +369 -0
- package/registry/store/drizzle-postgres-pgvector/index.ts +0 -4
- package/registry/store/drizzle-postgres-pgvector/store.ts +0 -176
- package/registry/store/prisma-postgres-pgvector/index.ts +0 -3
- package/registry/store/prisma-postgres-pgvector/store.ts +0 -155
- package/registry/store/raw-sql-postgres-pgvector/index.ts +0 -3
- package/registry/store/raw-sql-postgres-pgvector/store.ts +0 -177
- /package/registry/store/{drizzle-postgres-pgvector → drizzle}/schema.ts +0 -0
package/dist/cli/index.js
CHANGED
|
@@ -19,7 +19,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
21
|
// cli/run.ts
|
|
22
|
-
import { intro, outro as
|
|
22
|
+
import { intro, outro as outro6 } from "@clack/prompts";
|
|
23
23
|
|
|
24
24
|
// cli/commands/init.ts
|
|
25
25
|
import {
|
|
@@ -97,6 +97,11 @@ var writeText = async (filePath, content) => {
|
|
|
97
97
|
await ensureDir(path2.dirname(filePath));
|
|
98
98
|
await writeFile(filePath, content, "utf8");
|
|
99
99
|
};
|
|
100
|
+
var rewriteRegistryAliasImports = (content, aliasBase) => {
|
|
101
|
+
if (!content.includes("@registry"))
|
|
102
|
+
return content;
|
|
103
|
+
return content.replaceAll("@registry/", `${aliasBase}/`);
|
|
104
|
+
};
|
|
100
105
|
var EXTRACTOR_FACTORY = {
|
|
101
106
|
"pdf-llm": "createPdfLlmExtractor",
|
|
102
107
|
"pdf-text-layer": "createPdfTextLayerExtractor",
|
|
@@ -400,6 +405,26 @@ async function copyRegistryFiles(selection) {
|
|
|
400
405
|
src: path2.join(selection.registryRoot, "core/rerank.ts"),
|
|
401
406
|
dest: path2.join(installBaseAbs, "core/rerank.ts")
|
|
402
407
|
},
|
|
408
|
+
{
|
|
409
|
+
src: path2.join(selection.registryRoot, "core/debug-emitter.ts"),
|
|
410
|
+
dest: path2.join(installBaseAbs, "core/debug-emitter.ts")
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
src: path2.join(selection.registryRoot, "core/debug-events.ts"),
|
|
414
|
+
dest: path2.join(installBaseAbs, "core/debug-events.ts")
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
src: path2.join(selection.registryRoot, "extractors/_shared/fetch.ts"),
|
|
418
|
+
dest: path2.join(installBaseAbs, "extractors/_shared/fetch.ts")
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
src: path2.join(selection.registryRoot, "extractors/_shared/media.ts"),
|
|
422
|
+
dest: path2.join(installBaseAbs, "extractors/_shared/media.ts")
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
src: path2.join(selection.registryRoot, "extractors/_shared/text.ts"),
|
|
426
|
+
dest: path2.join(installBaseAbs, "extractors/_shared/text.ts")
|
|
427
|
+
},
|
|
403
428
|
{
|
|
404
429
|
src: path2.join(selection.registryRoot, "embedding/_shared.ts"),
|
|
405
430
|
dest: path2.join(installBaseAbs, "embedding/_shared.ts")
|
|
@@ -455,29 +480,29 @@ async function copyRegistryFiles(selection) {
|
|
|
455
480
|
];
|
|
456
481
|
if (selection.storeAdapter === "drizzle") {
|
|
457
482
|
fileMappings.push({
|
|
458
|
-
src: path2.join(selection.registryRoot, "store/drizzle
|
|
483
|
+
src: path2.join(selection.registryRoot, "store/drizzle/index.ts"),
|
|
459
484
|
dest: path2.join(installBaseAbs, "store/drizzle/index.ts")
|
|
460
485
|
}, {
|
|
461
|
-
src: path2.join(selection.registryRoot, "store/drizzle
|
|
486
|
+
src: path2.join(selection.registryRoot, "store/drizzle/schema.ts"),
|
|
462
487
|
dest: path2.join(installBaseAbs, "store/drizzle/schema.ts")
|
|
463
488
|
}, {
|
|
464
|
-
src: path2.join(selection.registryRoot, "store/drizzle
|
|
489
|
+
src: path2.join(selection.registryRoot, "store/drizzle/store.ts"),
|
|
465
490
|
dest: path2.join(installBaseAbs, "store/drizzle/store.ts")
|
|
466
491
|
});
|
|
467
492
|
} else if (selection.storeAdapter === "raw-sql") {
|
|
468
493
|
fileMappings.push({
|
|
469
|
-
src: path2.join(selection.registryRoot, "store/raw-sql
|
|
494
|
+
src: path2.join(selection.registryRoot, "store/raw-sql/index.ts"),
|
|
470
495
|
dest: path2.join(installBaseAbs, "store/raw-sql/index.ts")
|
|
471
496
|
}, {
|
|
472
|
-
src: path2.join(selection.registryRoot, "store/raw-sql
|
|
497
|
+
src: path2.join(selection.registryRoot, "store/raw-sql/store.ts"),
|
|
473
498
|
dest: path2.join(installBaseAbs, "store/raw-sql/store.ts")
|
|
474
499
|
});
|
|
475
500
|
} else {
|
|
476
501
|
fileMappings.push({
|
|
477
|
-
src: path2.join(selection.registryRoot, "store/prisma
|
|
502
|
+
src: path2.join(selection.registryRoot, "store/prisma/index.ts"),
|
|
478
503
|
dest: path2.join(installBaseAbs, "store/prisma/index.ts")
|
|
479
504
|
}, {
|
|
480
|
-
src: path2.join(selection.registryRoot, "store/prisma
|
|
505
|
+
src: path2.join(selection.registryRoot, "store/prisma/store.ts"),
|
|
481
506
|
dest: path2.join(installBaseAbs, "store/prisma/store.ts")
|
|
482
507
|
});
|
|
483
508
|
}
|
|
@@ -505,7 +530,8 @@ async function copyRegistryFiles(selection) {
|
|
|
505
530
|
}
|
|
506
531
|
}
|
|
507
532
|
const raw = await readText(mapping.src);
|
|
508
|
-
const
|
|
533
|
+
const transformed = mapping.transform ? mapping.transform(raw) : raw;
|
|
534
|
+
const content = rewriteRegistryAliasImports(transformed, selection.aliasBase);
|
|
509
535
|
await writeText(mapping.dest, content);
|
|
510
536
|
}
|
|
511
537
|
}
|
|
@@ -543,7 +569,8 @@ async function copyConnectorFiles(selection) {
|
|
|
543
569
|
}
|
|
544
570
|
}
|
|
545
571
|
const raw = await readText(src);
|
|
546
|
-
|
|
572
|
+
const content = rewriteRegistryAliasImports(raw, selection.aliasBase);
|
|
573
|
+
await writeText(dest, content);
|
|
547
574
|
}
|
|
548
575
|
}
|
|
549
576
|
async function copyExtractorFiles(selection) {
|
|
@@ -569,7 +596,8 @@ async function copyExtractorFiles(selection) {
|
|
|
569
596
|
return false;
|
|
570
597
|
try {
|
|
571
598
|
const [srcRaw, destRaw] = await Promise.all([readText(src), readText(dest)]);
|
|
572
|
-
|
|
599
|
+
const nextSrc = rewriteRegistryAliasImports(srcRaw, selection.aliasBase);
|
|
600
|
+
if (nextSrc === destRaw)
|
|
573
601
|
return false;
|
|
574
602
|
} catch {}
|
|
575
603
|
const answer = await confirm({
|
|
@@ -591,7 +619,8 @@ async function copyExtractorFiles(selection) {
|
|
|
591
619
|
if (!await shouldWrite(src, dest))
|
|
592
620
|
continue;
|
|
593
621
|
const raw = await readText(src);
|
|
594
|
-
|
|
622
|
+
const content = rewriteRegistryAliasImports(raw, selection.aliasBase);
|
|
623
|
+
await writeText(dest, content);
|
|
595
624
|
}
|
|
596
625
|
for (const src of sharedFiles) {
|
|
597
626
|
if (!await exists(src)) {
|
|
@@ -602,7 +631,8 @@ async function copyExtractorFiles(selection) {
|
|
|
602
631
|
if (!await shouldWrite(src, dest))
|
|
603
632
|
continue;
|
|
604
633
|
const raw = await readText(src);
|
|
605
|
-
|
|
634
|
+
const content = rewriteRegistryAliasImports(raw, selection.aliasBase);
|
|
635
|
+
await writeText(dest, content);
|
|
606
636
|
}
|
|
607
637
|
}
|
|
608
638
|
async function copyBatteryFiles(selection) {
|
|
@@ -614,6 +644,14 @@ async function copyBatteryFiles(selection) {
|
|
|
614
644
|
throw new Error(`Unknown battery registry: ${path2.relative(selection.registryRoot, batteryRegistryAbs)}`);
|
|
615
645
|
}
|
|
616
646
|
const batteryFiles = await listFilesRecursive(batteryRegistryAbs);
|
|
647
|
+
const filteredBatteryFiles = batteryFiles.filter((abs) => {
|
|
648
|
+
if (batteryRegistryDir === "debug") {
|
|
649
|
+
const rel = path2.relative(batteryRegistryAbs, abs).replace(/\\/g, "/");
|
|
650
|
+
if (rel === "tui" || rel.startsWith("tui/"))
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
return true;
|
|
654
|
+
});
|
|
617
655
|
const destRootAbs = path2.join(installBaseAbs, batteryRegistryDir);
|
|
618
656
|
const nonInteractive = Boolean(selection.yes) || !process.stdin.isTTY;
|
|
619
657
|
const overwritePolicy = selection.overwrite ?? "skip";
|
|
@@ -626,7 +664,8 @@ async function copyBatteryFiles(selection) {
|
|
|
626
664
|
return false;
|
|
627
665
|
try {
|
|
628
666
|
const [srcRaw, destRaw] = await Promise.all([readText(src), readText(dest)]);
|
|
629
|
-
|
|
667
|
+
const nextSrc = rewriteRegistryAliasImports(srcRaw, selection.aliasBase);
|
|
668
|
+
if (nextSrc === destRaw)
|
|
630
669
|
return false;
|
|
631
670
|
} catch {}
|
|
632
671
|
const answer = await confirm({
|
|
@@ -639,7 +678,7 @@ async function copyBatteryFiles(selection) {
|
|
|
639
678
|
}
|
|
640
679
|
return Boolean(answer);
|
|
641
680
|
};
|
|
642
|
-
for (const src of
|
|
681
|
+
for (const src of filteredBatteryFiles) {
|
|
643
682
|
if (!await exists(src)) {
|
|
644
683
|
throw new Error(`Registry file missing: ${src}`);
|
|
645
684
|
}
|
|
@@ -648,7 +687,8 @@ async function copyBatteryFiles(selection) {
|
|
|
648
687
|
if (!await shouldWrite(src, dest))
|
|
649
688
|
continue;
|
|
650
689
|
const raw = await readText(src);
|
|
651
|
-
|
|
690
|
+
const content = rewriteRegistryAliasImports(raw, selection.aliasBase);
|
|
691
|
+
await writeText(dest, content);
|
|
652
692
|
}
|
|
653
693
|
}
|
|
654
694
|
|
|
@@ -887,6 +927,9 @@ function depsForBattery(battery) {
|
|
|
887
927
|
deps["@ai-sdk/cohere"] = "^3.0.1";
|
|
888
928
|
}
|
|
889
929
|
if (battery === "eval") {}
|
|
930
|
+
if (battery === "debug") {
|
|
931
|
+
deps["ws"] = "^8.18.0";
|
|
932
|
+
}
|
|
890
933
|
return { deps, devDeps };
|
|
891
934
|
}
|
|
892
935
|
function installCmd(pm) {
|
|
@@ -1038,7 +1081,7 @@ var EVAL_PACKAGE_JSON_SCRIPTS = {
|
|
|
1038
1081
|
"unrag:eval:ci": `bun run scripts/unrag-eval.ts -- --dataset .unrag/eval/datasets/sample.json --ci`
|
|
1039
1082
|
};
|
|
1040
1083
|
function renderEvalRunnerScript(opts) {
|
|
1041
|
-
const
|
|
1084
|
+
const aliasBase = String(opts.aliasBase ?? "").trim() || "@unrag";
|
|
1042
1085
|
return `/**
|
|
1043
1086
|
* Unrag eval runner entrypoint (generated).
|
|
1044
1087
|
*
|
|
@@ -1048,7 +1091,7 @@ function renderEvalRunnerScript(opts) {
|
|
|
1048
1091
|
import path from "node:path";
|
|
1049
1092
|
import { access, readFile } from "node:fs/promises";
|
|
1050
1093
|
|
|
1051
|
-
import { createUnragEngine } from "
|
|
1094
|
+
import { createUnragEngine } from "${aliasBase}/config";
|
|
1052
1095
|
import {
|
|
1053
1096
|
runEval,
|
|
1054
1097
|
readEvalReportFromFile,
|
|
@@ -1060,7 +1103,7 @@ import {
|
|
|
1060
1103
|
type EvalMode,
|
|
1061
1104
|
type EvalThresholds,
|
|
1062
1105
|
type EvalCleanupPolicy,
|
|
1063
|
-
} from "${
|
|
1106
|
+
} from "${aliasBase}/eval";
|
|
1064
1107
|
|
|
1065
1108
|
type CliArgs = {
|
|
1066
1109
|
dataset?: string;
|
|
@@ -1565,6 +1608,7 @@ async function initCommand(args) {
|
|
|
1565
1608
|
projectRoot: root,
|
|
1566
1609
|
registryRoot,
|
|
1567
1610
|
installDir,
|
|
1611
|
+
aliasBase,
|
|
1568
1612
|
extractor,
|
|
1569
1613
|
yes: nonInteractive,
|
|
1570
1614
|
overwrite: overwritePolicy
|
|
@@ -1595,6 +1639,7 @@ async function initCommand(args) {
|
|
|
1595
1639
|
projectRoot: root,
|
|
1596
1640
|
registryRoot,
|
|
1597
1641
|
installDir,
|
|
1642
|
+
aliasBase,
|
|
1598
1643
|
connector,
|
|
1599
1644
|
yes: nonInteractive,
|
|
1600
1645
|
overwrite: overwritePolicy
|
|
@@ -1622,6 +1667,7 @@ async function initCommand(args) {
|
|
|
1622
1667
|
projectRoot: root,
|
|
1623
1668
|
registryRoot,
|
|
1624
1669
|
installDir,
|
|
1670
|
+
aliasBase,
|
|
1625
1671
|
battery,
|
|
1626
1672
|
yes: nonInteractive,
|
|
1627
1673
|
overwrite: overwritePolicy
|
|
@@ -1674,7 +1720,7 @@ async function initCommand(args) {
|
|
|
1674
1720
|
`);
|
|
1675
1721
|
await writeIfMissing(evalConfigAbs, JSON.stringify(EVAL_CONFIG_DEFAULT, null, 2) + `
|
|
1676
1722
|
`);
|
|
1677
|
-
await writeIfMissing(scriptAbs, renderEvalRunnerScript({
|
|
1723
|
+
await writeIfMissing(scriptAbs, renderEvalRunnerScript({ aliasBase }));
|
|
1678
1724
|
const pkg2 = await readPackageJson(root);
|
|
1679
1725
|
const existingScripts = pkg2.scripts ?? {};
|
|
1680
1726
|
const toAdd = {};
|
|
@@ -1690,8 +1736,11 @@ async function initCommand(args) {
|
|
|
1690
1736
|
}
|
|
1691
1737
|
const pm = await detectPackageManager(root);
|
|
1692
1738
|
const installLine = merged.changes.length === 0 ? "Dependencies already satisfied." : noInstall ? `Next: run \`${installCmd(pm)}\`` : "Dependencies installed.";
|
|
1693
|
-
const
|
|
1694
|
-
|
|
1739
|
+
const tsconfigResult = await patchTsconfigPaths({
|
|
1740
|
+
projectRoot: root,
|
|
1741
|
+
installDir,
|
|
1742
|
+
aliasBase
|
|
1743
|
+
});
|
|
1695
1744
|
const envHint = (() => {
|
|
1696
1745
|
if (embeddingProvider === "ai") {
|
|
1697
1746
|
return [
|
|
@@ -1801,7 +1850,7 @@ async function initCommand(args) {
|
|
|
1801
1850
|
`- Embedding provider: ${embeddingProvider}`,
|
|
1802
1851
|
richMediaEnabled ? `- Extractors: ${selectedExtractors.length > 0 ? selectedExtractors.join(", ") : "none"}` : "",
|
|
1803
1852
|
richMediaEnabled ? ` Tip: you can tweak extractors + assetProcessing flags in unrag.config.ts later.` : ` Tip: re-run \`unrag init --rich-media\` (or edit unrag.config.ts) to enable rich media later.`,
|
|
1804
|
-
|
|
1853
|
+
tsconfigResult.changed ? `- TypeScript: updated ${tsconfigResult.file} (added aliases)` : `- TypeScript: no tsconfig changes needed`,
|
|
1805
1854
|
"",
|
|
1806
1855
|
merged.changes.length > 0 ? `Added deps: ${merged.changes.map((c) => c.name).join(", ")}` : "Added deps: none",
|
|
1807
1856
|
installLine,
|
|
@@ -1983,6 +2032,7 @@ Available batteries: ${Array.from(availableBatteries).join(", ")}`);
|
|
|
1983
2032
|
projectRoot: root,
|
|
1984
2033
|
registryRoot,
|
|
1985
2034
|
installDir: config.installDir,
|
|
2035
|
+
aliasBase: config.aliasBase ?? "@unrag",
|
|
1986
2036
|
battery,
|
|
1987
2037
|
yes: nonInteractive
|
|
1988
2038
|
});
|
|
@@ -2038,7 +2088,7 @@ Available batteries: ${Array.from(availableBatteries).join(", ")}`);
|
|
|
2038
2088
|
cleanup: "none",
|
|
2039
2089
|
ingest: true
|
|
2040
2090
|
};
|
|
2041
|
-
const
|
|
2091
|
+
const aliasBase = String(config.aliasBase ?? "").trim() || "@unrag";
|
|
2042
2092
|
const script = `/**
|
|
2043
2093
|
* Unrag eval runner entrypoint (generated).
|
|
2044
2094
|
*
|
|
@@ -2048,7 +2098,7 @@ Available batteries: ${Array.from(availableBatteries).join(", ")}`);
|
|
|
2048
2098
|
import path from "node:path";
|
|
2049
2099
|
import { access, readFile } from "node:fs/promises";
|
|
2050
2100
|
|
|
2051
|
-
import { createUnragEngine } from "
|
|
2101
|
+
import { createUnragEngine } from "${aliasBase}/config";
|
|
2052
2102
|
import {
|
|
2053
2103
|
runEval,
|
|
2054
2104
|
readEvalReportFromFile,
|
|
@@ -2060,7 +2110,7 @@ import {
|
|
|
2060
2110
|
type EvalMode,
|
|
2061
2111
|
type EvalThresholds,
|
|
2062
2112
|
type EvalCleanupPolicy,
|
|
2063
|
-
} from "${
|
|
2113
|
+
} from "${aliasBase}/eval";
|
|
2064
2114
|
|
|
2065
2115
|
type CliArgs = {
|
|
2066
2116
|
dataset?: string;
|
|
@@ -2326,6 +2376,50 @@ main().catch((err) => {
|
|
|
2326
2376
|
" bun run unrag:eval",
|
|
2327
2377
|
" bun run unrag:eval:ci"
|
|
2328
2378
|
].filter(Boolean).join(`
|
|
2379
|
+
`));
|
|
2380
|
+
return;
|
|
2381
|
+
}
|
|
2382
|
+
if (battery === "debug") {
|
|
2383
|
+
const configAbs = path7.join(root, ".unrag/debug/config.json");
|
|
2384
|
+
const debugConfig = {
|
|
2385
|
+
port: 3847,
|
|
2386
|
+
host: "localhost"
|
|
2387
|
+
};
|
|
2388
|
+
if (await shouldWriteFile(configAbs, root, nonInteractive)) {
|
|
2389
|
+
await writeTextFile(configAbs, JSON.stringify(debugConfig, null, 2) + `
|
|
2390
|
+
`);
|
|
2391
|
+
}
|
|
2392
|
+
const scriptsToAdd = {
|
|
2393
|
+
"unrag:debug": "bunx unrag debug"
|
|
2394
|
+
};
|
|
2395
|
+
const scriptsResult = await addPackageJsonScripts({
|
|
2396
|
+
projectRoot: root,
|
|
2397
|
+
pkg,
|
|
2398
|
+
scripts: scriptsToAdd,
|
|
2399
|
+
nonInteractive
|
|
2400
|
+
});
|
|
2401
|
+
outro2([
|
|
2402
|
+
`Installed battery: ${battery}.`,
|
|
2403
|
+
"",
|
|
2404
|
+
`- Code: ${path7.join(config.installDir, "debug")}`,
|
|
2405
|
+
`- Config: .unrag/debug/config.json`,
|
|
2406
|
+
"",
|
|
2407
|
+
merged2.changes.length > 0 ? `Added deps: ${merged2.changes.map((c) => c.name).join(", ")}` : "Added deps: none",
|
|
2408
|
+
merged2.changes.length > 0 && !noInstall ? "Dependencies installed." : merged2.changes.length > 0 && noInstall ? "Dependencies not installed (skipped)." : "",
|
|
2409
|
+
scriptsResult.added.length > 0 ? `Added scripts: ${scriptsResult.added.join(", ")}` : "Added scripts: none",
|
|
2410
|
+
scriptsResult.kept.length > 0 ? `Kept existing scripts: ${scriptsResult.kept.join(", ")}` : "",
|
|
2411
|
+
"",
|
|
2412
|
+
"Usage:",
|
|
2413
|
+
" 1. Set UNRAG_DEBUG=true in your app's environment",
|
|
2414
|
+
" 2. Run your app (debug server auto-starts on port 3847)",
|
|
2415
|
+
" 3. In another terminal: bun run unrag:debug",
|
|
2416
|
+
"",
|
|
2417
|
+
"The debug panel will connect to your app and show live events for:",
|
|
2418
|
+
" - Ingest operations (chunking, embedding, storage)",
|
|
2419
|
+
" - Retrieve operations (embedding, database queries)",
|
|
2420
|
+
" - Rerank operations (scoring, reordering)",
|
|
2421
|
+
" - Delete operations"
|
|
2422
|
+
].filter(Boolean).join(`
|
|
2329
2423
|
`));
|
|
2330
2424
|
return;
|
|
2331
2425
|
}
|
|
@@ -2369,6 +2463,7 @@ Available connectors: ${Array.from(availableConnectors).join(", ")}`);
|
|
|
2369
2463
|
projectRoot: root,
|
|
2370
2464
|
registryRoot,
|
|
2371
2465
|
installDir: config.installDir,
|
|
2466
|
+
aliasBase: config.aliasBase ?? "@unrag",
|
|
2372
2467
|
connector,
|
|
2373
2468
|
yes: nonInteractive
|
|
2374
2469
|
});
|
|
@@ -2406,6 +2501,7 @@ Available extractors: ${Array.from(availableExtractors).join(", ")}`);
|
|
|
2406
2501
|
projectRoot: root,
|
|
2407
2502
|
registryRoot,
|
|
2408
2503
|
installDir: config.installDir,
|
|
2504
|
+
aliasBase: config.aliasBase ?? "@unrag",
|
|
2409
2505
|
extractor,
|
|
2410
2506
|
yes: nonInteractive
|
|
2411
2507
|
});
|
|
@@ -5042,6 +5138,103 @@ async function doctorCommand(args) {
|
|
|
5042
5138
|
}
|
|
5043
5139
|
}
|
|
5044
5140
|
|
|
5141
|
+
// cli/commands/debug.ts
|
|
5142
|
+
import { outro as outro5 } from "@clack/prompts";
|
|
5143
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
5144
|
+
import { dirname, join } from "node:path";
|
|
5145
|
+
import { existsSync } from "node:fs";
|
|
5146
|
+
function parseDebugArgs(args) {
|
|
5147
|
+
const out = {};
|
|
5148
|
+
for (let i = 0;i < args.length; i++) {
|
|
5149
|
+
const arg = args[i];
|
|
5150
|
+
if (arg === "--url") {
|
|
5151
|
+
out.url = args[++i];
|
|
5152
|
+
} else if (arg === "--port" || arg === "-p") {
|
|
5153
|
+
const portStr = args[++i] ?? "";
|
|
5154
|
+
out.port = parseInt(portStr, 10);
|
|
5155
|
+
if (isNaN(out.port)) {
|
|
5156
|
+
throw new Error(`Invalid port: ${portStr}`);
|
|
5157
|
+
}
|
|
5158
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
5159
|
+
out.help = true;
|
|
5160
|
+
}
|
|
5161
|
+
}
|
|
5162
|
+
return out;
|
|
5163
|
+
}
|
|
5164
|
+
function renderDebugHelp() {
|
|
5165
|
+
return [
|
|
5166
|
+
"unrag debug — Real-time TUI debugger for RAG operations",
|
|
5167
|
+
"",
|
|
5168
|
+
"Usage:",
|
|
5169
|
+
" bunx unrag debug [options]",
|
|
5170
|
+
"",
|
|
5171
|
+
"Options:",
|
|
5172
|
+
" --url <ws://...> WebSocket URL (default: ws://localhost:3847)",
|
|
5173
|
+
" --port, -p <num> Port to connect to (default: 3847)",
|
|
5174
|
+
" -h, --help Show this help",
|
|
5175
|
+
"",
|
|
5176
|
+
"Setup:",
|
|
5177
|
+
" 1. Set UNRAG_DEBUG=true in your app's environment",
|
|
5178
|
+
" 2. Start your app (debug server auto-starts on port 3847)",
|
|
5179
|
+
" 3. Run: bunx unrag debug",
|
|
5180
|
+
"",
|
|
5181
|
+
"Keyboard shortcuts (in TUI):",
|
|
5182
|
+
" Shift+Tab Cycle tabs",
|
|
5183
|
+
" 1-8 Jump to specific tab",
|
|
5184
|
+
" j/k or arrows Navigate event list",
|
|
5185
|
+
" Enter/e View event details",
|
|
5186
|
+
" a/i/r/k/d Filter events by type",
|
|
5187
|
+
" ?/h Show help",
|
|
5188
|
+
" q Quit",
|
|
5189
|
+
"",
|
|
5190
|
+
"Environment variables (in your app):",
|
|
5191
|
+
" UNRAG_DEBUG=true Enable debug mode",
|
|
5192
|
+
" UNRAG_DEBUG_PORT=3847 Debug server port (optional)",
|
|
5193
|
+
""
|
|
5194
|
+
].join(`
|
|
5195
|
+
`);
|
|
5196
|
+
}
|
|
5197
|
+
function getTuiModulePath() {
|
|
5198
|
+
const __filename4 = fileURLToPath3(import.meta.url);
|
|
5199
|
+
const __dirname4 = dirname(__filename4);
|
|
5200
|
+
const dev = process.env.UNRAG_DEBUG_TUI_DEV === "1";
|
|
5201
|
+
const devPath = join(__dirname4, "..", "debug-tui", "index.dev.js");
|
|
5202
|
+
const prodPath = join(__dirname4, "..", "debug-tui", "index.js");
|
|
5203
|
+
if (dev) {
|
|
5204
|
+
if (existsSync(devPath))
|
|
5205
|
+
return devPath;
|
|
5206
|
+
throw new Error("UNRAG_DEBUG_TUI_DEV=1 was set but dev TUI bundle was not found. Rebuild unrag with: `bun run build:debug-tui:dev`");
|
|
5207
|
+
}
|
|
5208
|
+
return prodPath;
|
|
5209
|
+
}
|
|
5210
|
+
async function debugCommand(args) {
|
|
5211
|
+
try {
|
|
5212
|
+
const parsed = parseDebugArgs(args);
|
|
5213
|
+
if (parsed.help) {
|
|
5214
|
+
outro5(renderDebugHelp());
|
|
5215
|
+
return;
|
|
5216
|
+
}
|
|
5217
|
+
let url = parsed.url;
|
|
5218
|
+
if (!url && parsed.port) {
|
|
5219
|
+
url = `ws://localhost:${parsed.port}`;
|
|
5220
|
+
}
|
|
5221
|
+
url = url ?? "ws://localhost:3847";
|
|
5222
|
+
console.log(`Connecting to debug server at ${url}...`);
|
|
5223
|
+
console.log(`Press ? for help, q to quit
|
|
5224
|
+
`);
|
|
5225
|
+
const tuiPath = getTuiModulePath();
|
|
5226
|
+
const { runDebugTui } = await import(tuiPath);
|
|
5227
|
+
await runDebugTui({ url });
|
|
5228
|
+
} catch (error) {
|
|
5229
|
+
if (error instanceof Error) {
|
|
5230
|
+
outro5(`Error: ${error.message}`);
|
|
5231
|
+
} else {
|
|
5232
|
+
outro5(`Error: ${String(error)}`);
|
|
5233
|
+
}
|
|
5234
|
+
process.exitCode = 1;
|
|
5235
|
+
}
|
|
5236
|
+
}
|
|
5237
|
+
|
|
5045
5238
|
// cli/run.ts
|
|
5046
5239
|
function renderHelp() {
|
|
5047
5240
|
return [
|
|
@@ -5055,9 +5248,10 @@ function renderHelp() {
|
|
|
5055
5248
|
" init Install core files (config + store adapter templates)",
|
|
5056
5249
|
" add <connector> Install a connector (notion, google-drive)",
|
|
5057
5250
|
" add extractor <n> Install an extractor (pdf-llm, image-ocr, etc.)",
|
|
5058
|
-
" add battery <name> Install a battery module (reranker,
|
|
5251
|
+
" add battery <name> Install a battery module (reranker, eval, debug)",
|
|
5059
5252
|
" doctor Validate installation and configuration",
|
|
5060
5253
|
" doctor setup Generate project-specific doctor config and scripts",
|
|
5254
|
+
" debug Open real-time debug TUI (requires UNRAG_DEBUG=true in app)",
|
|
5061
5255
|
" help Show this help",
|
|
5062
5256
|
"",
|
|
5063
5257
|
"Global options:",
|
|
@@ -5113,7 +5307,7 @@ async function run(argv) {
|
|
|
5113
5307
|
const [, , command, ...rest] = argv;
|
|
5114
5308
|
intro("unrag");
|
|
5115
5309
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
5116
|
-
|
|
5310
|
+
outro6(renderHelp());
|
|
5117
5311
|
return;
|
|
5118
5312
|
}
|
|
5119
5313
|
if (command === "init") {
|
|
@@ -5128,7 +5322,11 @@ async function run(argv) {
|
|
|
5128
5322
|
await doctorCommand(rest);
|
|
5129
5323
|
return;
|
|
5130
5324
|
}
|
|
5131
|
-
|
|
5325
|
+
if (command === "debug") {
|
|
5326
|
+
await debugCommand(rest);
|
|
5327
|
+
return;
|
|
5328
|
+
}
|
|
5329
|
+
outro6([`Unknown command: ${command}`, "", renderHelp()].join(`
|
|
5132
5330
|
`));
|
|
5133
5331
|
process.exitCode = 1;
|
|
5134
5332
|
}
|