Fix build errors
This commit is contained in:
committed by
Vignesh
parent
3a57106c1e
commit
e12184661e
@@ -109,6 +109,13 @@ out to QMD for retrieval. Key points:
|
||||
a release) and make sure the `qmd` binary is on the gateway’s `PATH`.
|
||||
- QMD needs an SQLite build that allows extensions (`brew install sqlite` on
|
||||
macOS). The gateway sets `INDEX_PATH`/`QMD_CONFIG_DIR` automatically.
|
||||
- QMD shells out to its CLI, which depends on an Ollama daemon listening on
|
||||
`http://localhost:11434` to load the bundled models (`embeddinggemma`,
|
||||
`ExpedientFalcon/qwen3-reranker:0.6b-q8_0`, `qwen3:0.6b`). Install/run Ollama
|
||||
separately before enabling the backend.
|
||||
- OS support: macOS and Linux work out of the box once Bun + SQLite + Ollama are
|
||||
installed. Windows requires WSL2 (or building the experimental Ollama port)
|
||||
until Ollama ships native binaries.
|
||||
|
||||
**How the sidecar runs**
|
||||
- The gateway writes a self-contained QMD home under
|
||||
|
||||
@@ -257,13 +257,16 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
onMissing: (error) => defaultRuntime.log(error ?? "Memory search disabled."),
|
||||
onCloseError: (err) =>
|
||||
defaultRuntime.error(`Memory manager close failed: ${formatErrorMessage(err)}`),
|
||||
close: (manager) => manager.close(),
|
||||
close: async (manager) => {
|
||||
await manager.close?.();
|
||||
},
|
||||
run: async (manager) => {
|
||||
const deep = Boolean(opts.deep || opts.index);
|
||||
let embeddingProbe:
|
||||
| Awaited<ReturnType<typeof manager.probeEmbeddingAvailability>>
|
||||
| undefined;
|
||||
let indexError: string | undefined;
|
||||
const syncFn = manager.sync;
|
||||
if (deep) {
|
||||
await withProgress({ label: "Checking memory…", total: 2 }, async (progress) => {
|
||||
progress.setLabel("Probing vector…");
|
||||
@@ -273,7 +276,7 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
embeddingProbe = await manager.probeEmbeddingAvailability();
|
||||
progress.tick();
|
||||
});
|
||||
if (opts.index) {
|
||||
if (opts.index && syncFn) {
|
||||
await withProgressTotals(
|
||||
{
|
||||
label: "Indexing memory…",
|
||||
@@ -282,7 +285,7 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
},
|
||||
async (update, progress) => {
|
||||
try {
|
||||
await manager.sync({
|
||||
await syncFn({
|
||||
reason: "cli",
|
||||
force: true,
|
||||
progress: (syncUpdate) => {
|
||||
@@ -303,6 +306,8 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
}
|
||||
},
|
||||
);
|
||||
} else if (opts.index && !syncFn) {
|
||||
defaultRuntime.log("Memory backend does not support manual reindex.");
|
||||
}
|
||||
} else {
|
||||
await manager.probeVectorAvailability();
|
||||
@@ -311,12 +316,10 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
const sources = (
|
||||
status.sources?.length ? status.sources : ["memory"]
|
||||
) as MemorySourceName[];
|
||||
const scan = await scanMemorySources({
|
||||
workspaceDir: status.workspaceDir,
|
||||
agentId,
|
||||
sources,
|
||||
extraPaths: status.extraPaths,
|
||||
});
|
||||
const workspaceDir = status.workspaceDir;
|
||||
const scan = workspaceDir
|
||||
? await scanMemorySources({ workspaceDir, agentId, sources, extraPaths: status.extraPaths })
|
||||
: undefined;
|
||||
allResults.push({ agentId, status, embeddingProbe, indexError, scan });
|
||||
},
|
||||
});
|
||||
@@ -338,28 +341,35 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
|
||||
for (const result of allResults) {
|
||||
const { agentId, status, embeddingProbe, indexError, scan } = result;
|
||||
const filesIndexed = status.files ?? 0;
|
||||
const chunksIndexed = status.chunks ?? 0;
|
||||
const totalFiles = scan?.totalFiles ?? null;
|
||||
const indexedLabel =
|
||||
totalFiles === null
|
||||
? `${status.files}/? files · ${status.chunks} chunks`
|
||||
: `${status.files}/${totalFiles} files · ${status.chunks} chunks`;
|
||||
? `${filesIndexed}/? files · ${chunksIndexed} chunks`
|
||||
: `${filesIndexed}/${totalFiles} files · ${chunksIndexed} chunks`;
|
||||
if (opts.index) {
|
||||
const line = indexError ? `Memory index failed: ${indexError}` : "Memory index complete.";
|
||||
defaultRuntime.log(line);
|
||||
}
|
||||
const extraPaths = formatExtraPaths(status.workspaceDir, status.extraPaths ?? []);
|
||||
const requestedProvider = status.requestedProvider ?? status.provider;
|
||||
const modelLabel = status.model ?? status.provider;
|
||||
const storePath = status.dbPath ? shortenHomePath(status.dbPath) : "<unknown>";
|
||||
const workspacePath = status.workspaceDir ? shortenHomePath(status.workspaceDir) : "<unknown>";
|
||||
const sourceList = status.sources?.length ? status.sources.join(", ") : null;
|
||||
const extraPaths = status.workspaceDir
|
||||
? formatExtraPaths(status.workspaceDir, status.extraPaths ?? [])
|
||||
: [];
|
||||
const lines = [
|
||||
`${heading("Memory Search")} ${muted(`(${agentId})`)}`,
|
||||
`${label("Provider")} ${info(status.provider)} ${muted(
|
||||
`(requested: ${status.requestedProvider})`,
|
||||
)}`,
|
||||
`${label("Model")} ${info(status.model)}`,
|
||||
status.sources?.length ? `${label("Sources")} ${info(status.sources.join(", "))}` : null,
|
||||
`${label("Provider")} ${info(status.provider)} ${muted(`(requested: ${requestedProvider})`)}`,
|
||||
`${label("Model")} ${info(modelLabel)}`,
|
||||
sourceList ? `${label("Sources")} ${info(sourceList)}` : null,
|
||||
extraPaths.length ? `${label("Extra paths")} ${info(extraPaths.join(", "))}` : null,
|
||||
`${label("Indexed")} ${success(indexedLabel)}`,
|
||||
`${label("Dirty")} ${status.dirty ? warn("yes") : muted("no")}`,
|
||||
`${label("Store")} ${info(shortenHomePath(status.dbPath))}`,
|
||||
`${label("Workspace")} ${info(shortenHomePath(status.workspaceDir))}`,
|
||||
`${label("Store")} ${info(storePath)}`,
|
||||
`${label("Workspace")} ${info(workspacePath)}`,
|
||||
].filter(Boolean) as string[];
|
||||
if (embeddingProbe) {
|
||||
const state = embeddingProbe.ok ? "ready" : "unavailable";
|
||||
@@ -372,7 +382,7 @@ export async function runMemoryStatus(opts: MemoryCommandOptions) {
|
||||
if (status.sourceCounts?.length) {
|
||||
lines.push(label("By source"));
|
||||
for (const entry of status.sourceCounts) {
|
||||
const total = scan?.sources.find(
|
||||
const total = scan?.sources?.find(
|
||||
(scanEntry) => scanEntry.source === entry.source,
|
||||
)?.totalFiles;
|
||||
const counts =
|
||||
@@ -504,9 +514,12 @@ export function registerMemoryCli(program: Command) {
|
||||
onMissing: (error) => defaultRuntime.log(error ?? "Memory search disabled."),
|
||||
onCloseError: (err) =>
|
||||
defaultRuntime.error(`Memory manager close failed: ${formatErrorMessage(err)}`),
|
||||
close: (manager) => manager.close(),
|
||||
close: async (manager) => {
|
||||
await manager.close?.();
|
||||
},
|
||||
run: async (manager) => {
|
||||
try {
|
||||
const syncFn = manager.sync;
|
||||
if (opts.verbose) {
|
||||
const status = manager.status();
|
||||
const rich = isRich();
|
||||
@@ -515,16 +528,20 @@ export function registerMemoryCli(program: Command) {
|
||||
const info = (text: string) => colorize(rich, theme.info, text);
|
||||
const warn = (text: string) => colorize(rich, theme.warn, text);
|
||||
const label = (text: string) => muted(`${text}:`);
|
||||
const sourceLabels = status.sources.map((source) =>
|
||||
formatSourceLabel(source, status.workspaceDir, agentId),
|
||||
const sourceLabels = (status.sources ?? []).map((source) =>
|
||||
formatSourceLabel(source, status.workspaceDir ?? "", agentId),
|
||||
);
|
||||
const extraPaths = formatExtraPaths(status.workspaceDir, status.extraPaths ?? []);
|
||||
const extraPaths = status.workspaceDir
|
||||
? formatExtraPaths(status.workspaceDir, status.extraPaths ?? [])
|
||||
: [];
|
||||
const requestedProvider = status.requestedProvider ?? status.provider;
|
||||
const modelLabel = status.model ?? status.provider;
|
||||
const lines = [
|
||||
`${heading("Memory Index")} ${muted(`(${agentId})`)}`,
|
||||
`${label("Provider")} ${info(status.provider)} ${muted(
|
||||
`(requested: ${status.requestedProvider})`,
|
||||
`(requested: ${requestedProvider})`,
|
||||
)}`,
|
||||
`${label("Model")} ${info(status.model)}`,
|
||||
`${label("Model")} ${info(modelLabel)}`,
|
||||
sourceLabels.length
|
||||
? `${label("Sources")} ${info(sourceLabels.join(", "))}`
|
||||
: null,
|
||||
@@ -571,6 +588,10 @@ export function registerMemoryCli(program: Command) {
|
||||
? `${lastLabel} · elapsed ${elapsed} · eta ${eta}`
|
||||
: `${lastLabel} · elapsed ${elapsed}`;
|
||||
};
|
||||
if (!syncFn) {
|
||||
defaultRuntime.log("Memory backend does not support manual reindex.");
|
||||
return;
|
||||
}
|
||||
await withProgressTotals(
|
||||
{
|
||||
label: "Indexing memory…",
|
||||
@@ -582,7 +603,7 @@ export function registerMemoryCli(program: Command) {
|
||||
progress.setLabel(buildLabel());
|
||||
}, 1000);
|
||||
try {
|
||||
await manager.sync({
|
||||
await syncFn({
|
||||
reason: "cli",
|
||||
force: true,
|
||||
progress: (syncUpdate) => {
|
||||
@@ -638,7 +659,9 @@ export function registerMemoryCli(program: Command) {
|
||||
onMissing: (error) => defaultRuntime.log(error ?? "Memory search disabled."),
|
||||
onCloseError: (err) =>
|
||||
defaultRuntime.error(`Memory manager close failed: ${formatErrorMessage(err)}`),
|
||||
close: (manager) => manager.close(),
|
||||
close: async (manager) => {
|
||||
await manager.close?.();
|
||||
},
|
||||
run: async (manager) => {
|
||||
let results: Awaited<ReturnType<typeof manager.search>>;
|
||||
try {
|
||||
|
||||
@@ -86,10 +86,14 @@ export async function resolveDiscordTarget(
|
||||
|
||||
const likelyUsername = isLikelyUsername(trimmed);
|
||||
const shouldLookup = isExplicitUserLookup(trimmed, parseOptions) || likelyUsername;
|
||||
|
||||
// Parse directly if it's already a known format. Use a safe parse so ambiguous
|
||||
// numeric targets don't throw when we still want to attempt username lookup.
|
||||
const directParse = safeParseDiscordTarget(trimmed, parseOptions);
|
||||
if (directParse && directParse.kind !== "channel" && !likelyUsername) {
|
||||
return directParse;
|
||||
}
|
||||
|
||||
if (!shouldLookup) {
|
||||
return directParse ?? parseDiscordTarget(trimmed, parseOptions);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import type {
|
||||
MemorySource,
|
||||
MemorySyncProgressUpdate,
|
||||
} from "./types.js";
|
||||
|
||||
type SqliteDatabase = import("node:sqlite").DatabaseSync;
|
||||
import type { ResolvedMemoryBackendConfig, ResolvedQmdConfig } from "./backend-config.js";
|
||||
|
||||
const log = createSubsystemLogger("memory");
|
||||
@@ -85,7 +87,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
private updateTimer: NodeJS.Timeout | null = null;
|
||||
private pendingUpdate: Promise<void> | null = null;
|
||||
private closed = false;
|
||||
private db: import("node:sqlite").DatabaseSync | null = null;
|
||||
private db: SqliteDatabase | null = null;
|
||||
private lastUpdateAt: number | null = null;
|
||||
|
||||
private constructor(params: {
|
||||
@@ -379,10 +381,10 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
});
|
||||
}
|
||||
|
||||
private ensureDb() {
|
||||
private ensureDb(): SqliteDatabase {
|
||||
if (this.db) return this.db;
|
||||
const sqlite = requireNodeSqlite();
|
||||
this.db = sqlite.open(this.indexPath, { readonly: true });
|
||||
const { DatabaseSync } = requireNodeSqlite();
|
||||
this.db = new DatabaseSync(this.indexPath, { readOnly: true });
|
||||
return this.db;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user