@gresmcp/mcp 1.0.0
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/LICENSE +18 -0
- package/README.md +219 -0
- package/dist/cli.js +1103 -0
- package/dist/cli.js.map +1 -0
- package/dist/mcp.js +515 -0
- package/dist/mcp.js.map +1 -0
- package/package.json +56 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/db.ts","../src/cli.ts","../src/ollama.ts","../src/ingest.ts","../src/chunk.ts","../src/html.ts","../src/check.ts","../src/version.ts"],"sourcesContent":["export const DEFAULT_DATABASE_URL = \"postgresql://gres:gres@localhost/gres\";\r\nexport const DEFAULT_OLLAMA_URL = \"http://localhost:11434\";\r\n\r\nexport function databaseUrl(): string {\r\n return process.env.GRESMCP_DATABASE_URL || DEFAULT_DATABASE_URL;\r\n}\r\n\r\nexport function normalizeUrl(url: string): string {\r\n return url.replace(/\\/+$/, \"\");\r\n}\r\n\r\nexport function ollamaUrl(override?: string): string {\r\n const raw = override || process.env.GRESMCP_OLLAMA_URL || DEFAULT_OLLAMA_URL;\r\n return normalizeUrl(raw);\r\n}\r\n","import { Pool } from \"pg\";\r\nimport { toSql } from \"pgvector\";\r\nimport { createHash } from \"node:crypto\";\r\nimport { databaseUrl, DEFAULT_OLLAMA_URL } from \"./config.js\";\r\n\r\nlet pool: Pool | undefined;\r\n\r\nexport function getPool(): Pool {\r\n if (!pool) {\r\n pool = new Pool({ connectionString: databaseUrl(), max: 5 });\r\n }\r\n return pool;\r\n}\r\n\r\nexport async function closePool(): Promise<void> {\r\n if (pool) {\r\n await pool.end();\r\n pool = undefined;\r\n }\r\n}\r\n\r\nexport interface KnowledgeSource {\r\n id: string;\r\n name: string;\r\n description: string;\r\n embedding_model: string;\r\n embedding_dim: number;\r\n ollama_url: string;\r\n created_at: Date;\r\n updated_at: Date;\r\n}\r\n\r\nexport interface EntryRow {\r\n id: string | number;\r\n source: string;\r\n title: string;\r\n chunk_index: number;\r\n content: string;\r\n content_hash: string;\r\n metadata: Record<string, unknown>;\r\n created_at: Date;\r\n}\r\n\r\nexport function entryTableName(ks: Pick<KnowledgeSource, \"id\">): string {\r\n const name = `entry_${ks.id.replace(/-/g, \"\")}`;\r\n assertTableName(name);\r\n return name;\r\n}\r\n\r\nexport function assertTableName(name: string): void {\r\n if (!/^entry_[0-9a-f]{32}$/.test(name)) {\r\n throw new Error(`Refusing to use unsafe table name: ${name}`);\r\n }\r\n}\r\n\r\nexport function contentHash(content: string): string {\r\n return createHash(\"sha256\").update(content).digest(\"hex\");\r\n}\r\n\r\nexport async function initDb(): Promise<void> {\r\n const p = getPool();\r\n await p.query(`CREATE EXTENSION IF NOT EXISTS vector`);\r\n await p.query(`\r\n CREATE TABLE IF NOT EXISTS ks (\r\n id uuid PRIMARY KEY DEFAULT gen_random_uuid(),\r\n name text NOT NULL UNIQUE,\r\n description text NOT NULL DEFAULT '',\r\n embedding_model text NOT NULL,\r\n embedding_dim integer NOT NULL,\r\n ollama_url text NOT NULL DEFAULT '${DEFAULT_OLLAMA_URL}',\r\n created_at timestamptz NOT NULL DEFAULT now(),\r\n updated_at timestamptz NOT NULL DEFAULT now()\r\n )\r\n `);\r\n}\r\n\r\nexport async function createKs(input: {\r\n name: string;\r\n description?: string;\r\n model: string;\r\n dim: number;\r\n url: string;\r\n}): Promise<KnowledgeSource> {\r\n const res = await getPool().query(\r\n `INSERT INTO ks (name, description, embedding_model, embedding_dim, ollama_url)\r\n VALUES ($1, $2, $3, $4, $5)\r\n RETURNING *`,\r\n [input.name, input.description ?? \"\", input.model, input.dim, input.url],\r\n );\r\n const ks = res.rows[0] as KnowledgeSource;\r\n await ensureEntryTable(ks);\r\n return ks;\r\n}\r\n\r\nexport async function listKs(): Promise<KnowledgeSource[]> {\r\n const res = await getPool().query(`SELECT * FROM ks ORDER BY name`);\r\n return res.rows as KnowledgeSource[];\r\n}\r\n\r\nexport async function getKs(name: string): Promise<KnowledgeSource | undefined> {\r\n const res = await getPool().query(`SELECT * FROM ks WHERE name = $1`, [name]);\r\n return res.rows[0] as KnowledgeSource | undefined;\r\n}\r\n\r\nexport async function updateKs(\r\n id: string,\r\n fields: { name?: string; description?: string; ollama_url?: string },\r\n): Promise<KnowledgeSource> {\r\n const sets: string[] = [];\r\n const params: unknown[] = [];\r\n if (fields.name !== undefined) {\r\n params.push(fields.name);\r\n sets.push(`name = $${params.length}`);\r\n }\r\n if (fields.description !== undefined) {\r\n params.push(fields.description);\r\n sets.push(`description = $${params.length}`);\r\n }\r\n if (fields.ollama_url !== undefined) {\r\n params.push(fields.ollama_url);\r\n sets.push(`ollama_url = $${params.length}`);\r\n }\r\n if (sets.length === 0) {\r\n const res = await getPool().query(`SELECT * FROM ks WHERE id = $1`, [id]);\r\n return res.rows[0] as KnowledgeSource;\r\n }\r\n sets.push(`updated_at = now()`);\r\n params.push(id);\r\n const res = await getPool().query(\r\n `UPDATE ks SET ${sets.join(\", \")} WHERE id = $${params.length} RETURNING *`,\r\n params,\r\n );\r\n return res.rows[0] as KnowledgeSource;\r\n}\r\n\r\nexport async function deleteKs(ks: KnowledgeSource): Promise<void> {\r\n const tbl = entryTableName(ks);\r\n await getPool().query(`DROP TABLE IF EXISTS ${tbl}`);\r\n await getPool().query(`DELETE FROM ks WHERE id = $1`, [ks.id]);\r\n}\r\n\r\nexport async function ensureEntryTable(ks: KnowledgeSource): Promise<void> {\r\n const tbl = entryTableName(ks);\r\n const p = getPool();\r\n await p.query(`\r\n CREATE TABLE IF NOT EXISTS ${tbl} (\r\n id bigserial PRIMARY KEY,\r\n source text NOT NULL,\r\n title text NOT NULL DEFAULT '',\r\n chunk_index integer NOT NULL DEFAULT 0,\r\n content text NOT NULL,\r\n content_hash text NOT NULL,\r\n metadata jsonb NOT NULL DEFAULT '{}',\r\n tsv tsvector GENERATED ALWAYS AS (to_tsvector('english', content)) STORED,\r\n embedding vector(${ks.embedding_dim}) NOT NULL,\r\n created_at timestamptz NOT NULL DEFAULT now()\r\n )\r\n `);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_tsv_idx ON ${tbl} USING gin (tsv)`);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_emb_idx ON ${tbl} USING hnsw (embedding vector_cosine_ops)`);\r\n await p.query(`CREATE INDEX IF NOT EXISTS ${tbl}_source_idx ON ${tbl} (source)`);\r\n}\r\n\r\nexport interface ChunkInsert {\r\n source: string;\r\n title: string;\r\n chunk_index: number;\r\n content: string;\r\n metadata: Record<string, unknown>;\r\n embedding: number[];\r\n}\r\n\r\nexport async function insertChunks(ks: KnowledgeSource, rows: ChunkInsert[]): Promise<number> {\r\n if (rows.length === 0) return 0;\r\n const tbl = entryTableName(ks);\r\n const p = getPool();\r\n const BATCH = 25;\r\n let inserted = 0;\r\n for (let i = 0; i < rows.length; i += BATCH) {\r\n const batch = rows.slice(i, i + BATCH);\r\n const values: string[] = [];\r\n const params: unknown[] = [];\r\n batch.forEach((r, j) => {\r\n const b = j * 7;\r\n values.push(`($${b + 1}, $${b + 2}, $${b + 3}, $${b + 4}, $${b + 5}, $${b + 6}, $${b + 7}::vector)`);\r\n params.push(r.source, r.title, r.chunk_index, r.content, contentHash(r.content), JSON.stringify(r.metadata), toSql(r.embedding));\r\n });\r\n const res = await p.query(\r\n `INSERT INTO ${tbl} (source, title, chunk_index, content, content_hash, metadata, embedding)\r\n VALUES ${values.join(\", \")}`,\r\n params,\r\n );\r\n inserted += res.rowCount ?? 0;\r\n }\r\n return inserted;\r\n}\r\n\r\nexport async function deleteBySource(ks: KnowledgeSource, source: string): Promise<number> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(`DELETE FROM ${tbl} WHERE source = $1`, [source]);\r\n return res.rowCount ?? 0;\r\n}\r\n\r\nexport async function sourceChunkHashes(\r\n ks: KnowledgeSource,\r\n source: string,\r\n): Promise<Map<number, string>> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(\r\n `SELECT chunk_index, content_hash FROM ${tbl} WHERE source = $1`,\r\n [source],\r\n );\r\n const map = new Map<number, string>();\r\n for (const row of res.rows) {\r\n map.set(Number(row.chunk_index), String(row.content_hash));\r\n }\r\n return map;\r\n}\r\n\r\nexport async function countEntries(ks: KnowledgeSource): Promise<number> {\r\n const tbl = entryTableName(ks);\r\n const res = await getPool().query(`SELECT count(*)::int AS n FROM ${tbl}`);\r\n return Number(res.rows[0]?.n ?? 0);\r\n}\r\n","import { Command } from \"commander\";\r\nimport { createInterface } from \"node:readline/promises\";\r\nimport { stdin, stdout } from \"node:process\";\r\nimport {\r\n initDb,\r\n closePool,\r\n createKs,\r\n listKs,\r\n getKs,\r\n updateKs,\r\n deleteKs,\r\n countEntries,\r\n type KnowledgeSource,\r\n} from \"./db.js\";\r\nimport { probeModel } from \"./ollama.js\";\r\nimport { ollamaUrl } from \"./config.js\";\r\nimport { feedTarget, feedText } from \"./ingest.js\";\r\nimport { runChecks, type CheckStatus } from \"./check.js\";\r\nimport { VERSION } from \"./version.js\";\r\n\r\nasync function run(fn: () => Promise<void>): Promise<void> {\r\n try {\r\n await fn();\r\n } catch (err) {\r\n console.error(`error: ${err instanceof Error ? err.message : err}`);\r\n process.exitCode = 1;\r\n } finally {\r\n await closePool().catch(() => {});\r\n }\r\n}\r\n\r\nasync function confirm(question: string): Promise<boolean> {\r\n const rl = createInterface({ input: stdin, output: stdout });\r\n try {\r\n const answer = (await rl.question(`${question} [y/N] `)).trim().toLowerCase();\r\n return answer === \"y\" || answer === \"yes\";\r\n } finally {\r\n rl.close();\r\n }\r\n}\r\n\r\nfunction requireKs(ks: KnowledgeSource | undefined, name: string): KnowledgeSource {\r\n if (!ks) throw new Error(`knowledge source '${name}' not found`);\r\n return ks;\r\n}\r\n\r\nfunction parseKeyValue(pairs: string[]): Record<string, unknown> {\r\n const out: Record<string, unknown> = {};\r\n for (const pair of pairs) {\r\n const idx = pair.indexOf(\"=\");\r\n if (idx <= 0) throw new Error(`invalid metadata entry '${pair}', expected key=value`);\r\n out[pair.slice(0, idx)] = pair.slice(idx + 1);\r\n }\r\n return out;\r\n}\r\n\r\nfunction parseTags(tags?: string): string[] | undefined {\r\n if (!tags) return undefined;\r\n const list = tags.split(\",\").map((t) => t.trim()).filter(Boolean);\r\n return list.length > 0 ? list : undefined;\r\n}\r\n\r\nconst program = new Command();\r\n\r\nprogram\r\n .name(\"gresmcp\")\r\n .description(\"Manage Postgres-backed knowledge sources for the gresmcp MCP server\")\r\n .version(VERSION);\r\n\r\nprogram\r\n .command(\"init\")\r\n .description(\"Initialize the database schema (extension, ks table; repairs entry tables)\")\r\n .action(() =>\r\n run(async () => {\r\n await initDb();\r\n for (const ks of await listKs()) {\r\n const { ensureEntryTable } = await import(\"./db.js\");\r\n await ensureEntryTable(ks);\r\n }\r\n console.log(\"database ready\");\r\n }),\r\n );\r\n\r\nprogram\r\n .command(\"check\")\r\n .description(\"Verify environment requirements (Node, Postgres, pgvector, schema, Ollama models)\")\r\n .option(\"--model <model>\", \"Verify this Ollama model is available (e.g. nomic-embed-text)\")\r\n .option(\"--url <url>\", \"Ollama base URL (default http://localhost:11434)\")\r\n .option(\"--probe\", \"Embed a test string with each model to verify dimensions (slower)\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((opts: { model?: string; url?: string; probe?: boolean; json?: boolean }) =>\r\n run(async () => {\r\n const results = await runChecks({ model: opts.model, url: opts.url, probe: opts.probe });\r\n if (opts.json) {\r\n console.log(JSON.stringify(results, null, 2));\r\n } else {\r\n const symbols: Record<CheckStatus, string> = { ok: \"✔\", warn: \"⚠\", fail: \"✘\", skip: \"-\" };\r\n for (const r of results) console.log(`${symbols[r.status]} ${r.detail}`);\r\n const failed = results.filter((r) => r.status === \"fail\").length;\r\n const warned = results.filter((r) => r.status === \"warn\").length;\r\n if (failed > 0) {\r\n console.log(`${failed} check(s) failed${warned > 0 ? `, ${warned} warning(s)` : \"\"}`);\r\n } else if (warned > 0) {\r\n console.log(`all checks passed with ${warned} warning(s)`);\r\n } else {\r\n console.log(\"all checks passed\");\r\n }\r\n }\r\n if (results.some((r) => r.status === \"fail\")) process.exitCode = 1;\r\n }),\r\n );\r\n\r\nconst ksCmd = program.command(\"ks\").description(\"Manage knowledge sources\");\r\n\r\nksCmd\r\n .command(\"create <name>\")\r\n .description(\"Create a knowledge source (probes Ollama to validate the model and detect dimensions)\")\r\n .requiredOption(\"--model <model>\", \"Ollama embedding model, e.g. nomic-embed-text\")\r\n .option(\"--url <url>\", \"Ollama base URL (default http://localhost:11434)\")\r\n .option(\"--description <description>\", \"Human-readable description\")\r\n .option(\"--dim <n>\", \"Skip the Ollama probe and set the embedding dimension explicitly\", parseInt)\r\n .action((name: string, opts: { model: string; url?: string; description?: string; dim?: number }) =>\r\n run(async () => {\r\n await initDb();\r\n if (await getKs(name)) throw new Error(`knowledge source '${name}' already exists`);\r\n const url = ollamaUrl(opts.url);\r\n let dim = opts.dim;\r\n if (dim === undefined || !Number.isFinite(dim) || dim <= 0) {\r\n console.log(`Probing model ${opts.model} at ${url} ...`);\r\n dim = (await probeModel(url, opts.model)).dim;\r\n console.log(`Model OK, embedding dimension: ${dim}`);\r\n }\r\n const ks = await createKs({\r\n name,\r\n description: opts.description,\r\n model: opts.model,\r\n dim,\r\n url,\r\n });\r\n console.log(`Created knowledge source '${ks.name}' (dim=${ks.embedding_dim}, model=${ks.embedding_model}, url=${ks.ollama_url})`);\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"edit <name>\")\r\n .description(\"Edit a knowledge source (the embedding model is immutable)\")\r\n .option(\"--url <url>\", \"New Ollama base URL\")\r\n .option(\"--rename <new-name>\", \"Rename the knowledge source\")\r\n .option(\"--description <description>\", \"New description\")\r\n .action((name: string, opts: { url?: string; rename?: string; description?: string }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n if (opts.rename && opts.rename !== name && (await getKs(opts.rename))) {\r\n throw new Error(`knowledge source '${opts.rename}' already exists`);\r\n }\r\n const updated = await updateKs(ks.id, {\r\n name: opts.rename,\r\n description: opts.description,\r\n ollama_url: opts.url ? ollamaUrl(opts.url) : undefined,\r\n });\r\n console.log(`Updated '${updated.name}' (model=${updated.embedding_model}, url=${updated.ollama_url}, dim=${updated.embedding_dim})`);\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"list\")\r\n .description(\"List knowledge sources\")\r\n .option(\"--json\", \"Output as JSON\")\r\n .action((opts: { json?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const all = await listKs();\r\n if (opts.json) {\r\n console.log(JSON.stringify(all, null, 2));\r\n return;\r\n }\r\n if (all.length === 0) {\r\n console.log(\"no knowledge sources yet; create one with: gresmcp ks create <name> --model <model>\");\r\n return;\r\n }\r\n for (const ks of all) {\r\n const n = await countEntries(ks);\r\n console.log(\r\n `${ks.name.padEnd(20)} ${`${ks.embedding_model}@${ks.ollama_url}`.padEnd(50)} dim=${String(ks.embedding_dim).padEnd(6)} entries=${String(n).padEnd(8)} ${ks.description}`,\r\n );\r\n }\r\n }),\r\n );\r\n\r\nksCmd\r\n .command(\"delete <name>\")\r\n .description(\"Delete a knowledge source and all of its entries\")\r\n .option(\"--yes\", \"Do not ask for confirmation\")\r\n .action((name: string, opts: { yes?: boolean }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n if (!opts.yes) {\r\n const n = await countEntries(ks);\r\n const ok = await confirm(`Delete knowledge source '${name}' and its ${n} entry chunk(s)?`);\r\n if (!ok) {\r\n console.log(\"aborted\");\r\n return;\r\n }\r\n }\r\n await deleteKs(ks);\r\n console.log(`Deleted knowledge source '${name}'`);\r\n }),\r\n );\r\n\r\nprogram\r\n .command(\"feed <ks>\")\r\n .description(\"Feed data into a knowledge source (from a file/folder via --path, or inline via --text/--stdin)\")\r\n .option(\"--path <path>\", \"File or folder to ingest (text, markdown, code, html)\")\r\n .option(\"--text <text>\", \"Inline text entry\")\r\n .option(\"--stdin\", \"Read entry text from stdin\")\r\n .option(\"--title <title>\", \"Title for manual entries\")\r\n .option(\"--source-name <name>\", \"Source name for manual entries (default 'manual')\")\r\n .option(\"--tags <tags>\", \"Comma-separated tags\")\r\n .option(\"--metadata <key=value...>\", \"Custom metadata entries\", ((v: string, prev: string[]) => [...prev, v]) as never, [] as string[])\r\n .option(\"--url <url>\", \"Ollama base URL override for this run\")\r\n .option(\"--replace\", \"Replace existing chunks of the same source instead of deduplicating\")\r\n .option(\"--dry-run\", \"Parse and chunk only; do not embed or write\")\r\n .option(\"--chunk-size <n>\", \"Max chunk length in characters\", parseInt)\r\n .option(\"--overlap <n>\", \"Chunk overlap in characters\", parseInt)\r\n .action((name: string, opts: {\r\n path?: string;\r\n text?: string;\r\n stdin?: boolean;\r\n title?: string;\r\n sourceName?: string;\r\n tags?: string;\r\n metadata?: string[];\r\n url?: string;\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n chunkSize?: number;\r\n overlap?: number;\r\n }) =>\r\n run(async () => {\r\n await initDb();\r\n const ks = requireKs(await getKs(name), name);\r\n const modes = [opts.path, opts.text, opts.stdin].filter(Boolean).length;\r\n if (modes !== 1) throw new Error(\"provide exactly one of --path, --text or --stdin\");\r\n const common = {\r\n title: opts.title,\r\n url: opts.url,\r\n replace: opts.replace,\r\n dryRun: opts.dryRun,\r\n batchSize: 32,\r\n maxLen: opts.chunkSize && opts.chunkSize > 0 ? opts.chunkSize : undefined,\r\n overlap: opts.overlap,\r\n tags: parseTags(opts.tags),\r\n metadata: parseKeyValue(opts.metadata ?? []),\r\n };\r\n let summary;\r\n if (opts.path) {\r\n summary = await feedTarget(ks, opts.path, common);\r\n } else {\r\n const text = opts.stdin ? await readStdin() : opts.text!;\r\n if (!text.trim()) throw new Error(\"empty input text\");\r\n summary = await feedText(ks, text, { ...common, sourceName: opts.sourceName });\r\n }\r\n if (summary.dryRun) {\r\n console.log(`dry run: ${summary.documents} document(s), ${summary.chunks} chunk(s), ${summary.skippedFiles.length} file(s) skipped`);\r\n } else {\r\n console.log(\r\n `fed '${ks.name}': ${summary.inserted} chunk(s) inserted` +\r\n (summary.skippedExisting ? `, ${summary.skippedExisting} unchanged chunk(s) skipped` : \"\") +\r\n (summary.deletedForReplace ? `, ${summary.deletedForReplace} old chunk(s) replaced` : \"\") +\r\n `, ${summary.skippedFiles.length} file(s) skipped`,\r\n );\r\n }\r\n }),\r\n );\r\n\r\nasync function readStdin(): Promise<string> {\r\n const chunks: Buffer[] = [];\r\n for await (const chunk of stdin) chunks.push(chunk as Buffer);\r\n return Buffer.concat(chunks).toString(\"utf8\");\r\n}\r\n\r\nprogram.parseAsync(process.argv);\r\n","import { normalizeUrl } from \"./config.js\";\r\n\r\nexport class OllamaError extends Error {\r\n constructor(\r\n message: string,\r\n public readonly status?: number,\r\n ) {\r\n super(message);\r\n this.name = \"OllamaError\";\r\n }\r\n}\r\n\r\nexport async function embed(\r\n baseUrl: string,\r\n model: string,\r\n inputs: string[],\r\n timeoutMs = 120_000,\r\n): Promise<number[][]> {\r\n const url = `${normalizeUrl(baseUrl)}/api/embed`;\r\n let res: Response;\r\n try {\r\n res = await fetch(url, {\r\n method: \"POST\",\r\n headers: { \"content-type\": \"application/json\" },\r\n body: JSON.stringify({ model, input: inputs }),\r\n signal: AbortSignal.timeout(timeoutMs),\r\n });\r\n } catch (err) {\r\n throw new OllamaError(\r\n `Cannot reach Ollama at ${normalizeUrl(baseUrl)} (${err instanceof Error ? err.message : err})`,\r\n );\r\n }\r\n if (!res.ok) {\r\n const body = await res.text().catch(() => \"\");\r\n throw new OllamaError(`Ollama returned ${res.status} for ${url}: ${body.slice(0, 300)}`, res.status);\r\n }\r\n const data = (await res.json()) as { embeddings?: number[][]; error?: string };\r\n if (data.error) {\r\n throw new OllamaError(`Ollama error: ${data.error}`);\r\n }\r\n if (!Array.isArray(data.embeddings) || data.embeddings.length !== inputs.length) {\r\n throw new OllamaError(`Unexpected response shape from ${url}`);\r\n }\r\n return data.embeddings;\r\n}\r\n\r\nexport async function embedBatch(\r\n baseUrl: string,\r\n model: string,\r\n inputs: string[],\r\n batchSize = 32,\r\n onProgress?: (done: number, total: number) => void,\r\n): Promise<number[][]> {\r\n const out: number[][] = [];\r\n let done = 0;\r\n for (let i = 0; i < inputs.length; i += batchSize) {\r\n const batch = inputs.slice(i, i + batchSize);\r\n const embs = await embed(baseUrl, model, batch);\r\n out.push(...embs);\r\n done += batch.length;\r\n onProgress?.(done, inputs.length);\r\n }\r\n return out;\r\n}\r\n\r\nexport async function probeModel(\r\n baseUrl: string,\r\n model: string,\r\n): Promise<{ dim: number }> {\r\n const embs = await embed(baseUrl, model, [\"gresmcp dimension probe\"], 30_000);\r\n const first = embs[0];\r\n if (!first || first.length === 0) {\r\n throw new OllamaError(`Ollama returned an empty embedding for model ${model}`);\r\n }\r\n return { dim: first.length };\r\n}\r\n","import { promises as fs } from \"node:fs\";\r\nimport path from \"node:path\";\r\nimport { chunkMarkdown, chunkPlain, mdTitle, type Chunk } from \"./chunk.js\";\r\nimport { htmlToMarkdown } from \"./html.js\";\r\nimport {\r\n deleteBySource,\r\n insertChunks,\r\n sourceChunkHashes,\r\n contentHash,\r\n type ChunkInsert,\r\n type KnowledgeSource,\r\n} from \"./db.js\";\r\nimport { embedBatch } from \"./ollama.js\";\r\nimport { ollamaUrl } from \"./config.js\";\r\n\r\nexport const MD_EXT = new Set([\".md\", \".markdown\", \".mdx\"]);\r\nexport const HTML_EXT = new Set([\".html\", \".htm\", \".xhtml\"]);\r\nexport const TEXT_EXT = new Set([\r\n \".txt\", \".text\", \".log\", \".csv\", \".tsv\", \".json\", \".jsonl\", \".yaml\", \".yml\",\r\n \".toml\", \".ini\", \".cfg\", \".conf\", \".xml\", \".rst\", \".adoc\",\r\n]);\r\nexport const CODE_EXT = new Set([\r\n \".js\", \".mjs\", \".cjs\", \".ts\", \".tsx\", \".jsx\", \".py\", \".go\", \".rs\", \".java\",\r\n \".kt\", \".kts\", \".rb\", \".php\", \".c\", \".h\", \".cpp\", \".hpp\", \".cc\", \".cs\",\r\n \".sh\", \".bash\", \".zsh\", \".ps1\", \".psm1\", \".bat\", \".cmd\", \".sql\", \".css\",\r\n \".scss\", \".less\", \".vue\", \".svelte\", \".astro\", \".swift\", \".scala\", \".pl\",\r\n \".lua\", \".r\", \".dart\", \".gradle\", \".cmake\", \".dockerfile\", \".makefile\", \".proto\", \".graphql\",\r\n]);\r\n\r\nconst SKIP_DIRS = new Set([\r\n \"node_modules\", \".git\", \".hg\", \".svn\", \"dist\", \"build\", \"out\", \".next\",\r\n \".nuxt\", \".venv\", \"venv\", \"__pycache__\", \".idea\", \".vscode\", \"target\",\r\n \"coverage\", \".turbo\", \".cache\",\r\n]);\r\n\r\nexport interface LoadedDoc {\r\n source: string;\r\n title: string;\r\n chunks: Chunk[];\r\n}\r\n\r\nexport interface SkippedFile {\r\n path: string;\r\n reason: string;\r\n}\r\n\r\nexport interface LoadResult {\r\n docs: LoadedDoc[];\r\n fileCount: number;\r\n skipped: SkippedFile[];\r\n}\r\n\r\nfunction isAllowed(ext: string): boolean {\r\n return MD_EXT.has(ext) || HTML_EXT.has(ext) || TEXT_EXT.has(ext) || CODE_EXT.has(ext);\r\n}\r\n\r\nasync function walk(root: string): Promise<string[]> {\r\n const out: string[] = [];\r\n const entries = await fs.readdir(root, { withFileTypes: true });\r\n for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {\r\n const full = path.join(root, entry.name);\r\n if (entry.isDirectory()) {\r\n if (SKIP_DIRS.has(entry.name)) continue;\r\n out.push(...(await walk(full)));\r\n } else if (entry.isFile()) {\r\n out.push(full);\r\n }\r\n }\r\n return out;\r\n}\r\n\r\nexport async function loadTarget(target: string, opts: { maxLen: number; overlap: number }): Promise<LoadResult> {\r\n const stat = await fs.stat(target);\r\n const files = stat.isDirectory() ? await walk(target) : [target];\r\n const docs: LoadedDoc[] = [];\r\n const skipped: SkippedFile[] = [];\r\n\r\n for (const file of files) {\r\n const ext = path.extname(file).toLowerCase();\r\n if (!isAllowed(ext)) {\r\n skipped.push({ path: file, reason: `unsupported extension '${ext || \"(none)\"}'` });\r\n continue;\r\n }\r\n let raw: string;\r\n try {\r\n raw = await fs.readFile(file, \"utf8\");\r\n } catch {\r\n skipped.push({ path: file, reason: \"unreadable\" });\r\n continue;\r\n }\r\n if (raw.includes(\"\\u0000\")) {\r\n skipped.push({ path: file, reason: \"binary content\" });\r\n continue;\r\n }\r\n let text = raw;\r\n let title = \"\";\r\n if (HTML_EXT.has(ext)) {\r\n const conv = htmlToMarkdown(raw);\r\n text = conv.markdown;\r\n title = conv.title ?? \"\";\r\n } else if (MD_EXT.has(ext)) {\r\n title = mdTitle(raw) ?? \"\";\r\n }\r\n if (!text.trim()) {\r\n skipped.push({ path: file, reason: \"empty\" });\r\n continue;\r\n }\r\n if (!title) title = path.basename(file);\r\n const chunks = HTML_EXT.has(ext) || MD_EXT.has(ext)\r\n ? chunkMarkdown(text, opts)\r\n : chunkPlain(text, opts);\r\n if (chunks.length === 0) {\r\n skipped.push({ path: file, reason: \"no chunks produced\" });\r\n continue;\r\n }\r\n docs.push({ source: path.resolve(file), title, chunks });\r\n }\r\n return { docs, fileCount: files.length, skipped };\r\n}\r\n\r\nexport interface FeedSummary {\r\n documents: number;\r\n chunks: number;\r\n inserted: number;\r\n skippedExisting: number;\r\n deletedForReplace: number;\r\n skippedFiles: SkippedFile[];\r\n dryRun: boolean;\r\n}\r\n\r\ninterface PendingRow {\r\n doc: LoadedDoc;\r\n chunk: Chunk;\r\n metadata: Record<string, unknown>;\r\n}\r\n\r\nasync function embedAndInsert(\r\n ks: KnowledgeSource,\r\n pending: PendingRow[],\r\n opts: { url: string; dryRun: boolean; batchSize: number; log?: (msg: string) => void },\r\n): Promise<{ inserted: number }> {\r\n if (pending.length === 0 || opts.dryRun) return { inserted: 0 };\r\n const contents = pending.map((p) => p.chunk.content);\r\n opts.log?.(`Embedding ${contents.length} chunk(s) with ${ks.embedding_model} at ${opts.url} ...`);\r\n const embeddings = await embedBatch(opts.url, ks.embedding_model, contents, opts.batchSize, (done, total) => {\r\n opts.log?.(` embedded ${done}/${total}`);\r\n });\r\n const byDoc = new Map<LoadedDoc, ChunkInsert[]>();\r\n pending.forEach((p, i) => {\r\n const list = byDoc.get(p.doc) ?? [];\r\n list.push({\r\n source: p.doc.source,\r\n title: p.doc.title,\r\n chunk_index: p.chunk.index,\r\n content: p.chunk.content,\r\n metadata: p.metadata,\r\n embedding: embeddings[i]!,\r\n });\r\n byDoc.set(p.doc, list);\r\n });\r\n let inserted = 0;\r\n for (const [, rows] of byDoc) {\r\n inserted += await insertChunks(ks, rows);\r\n }\r\n return { inserted };\r\n}\r\n\r\nexport async function feedTarget(\r\n ks: KnowledgeSource,\r\n target: string,\r\n opts: {\r\n url?: string;\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n maxLen?: number;\r\n overlap?: number;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n } = {},\r\n): Promise<FeedSummary> {\r\n const loadOpts = { maxLen: opts.maxLen ?? 1200, overlap: opts.overlap ?? 180 };\r\n const { docs, fileCount, skipped } = await loadTarget(target, loadOpts);\r\n const log = opts.log ?? ((m: string) => console.log(m));\r\n\r\n for (const doc of docs) {\r\n log(`${doc.source}: ${doc.chunks.length} chunk(s)`);\r\n }\r\n for (const s of skipped) {\r\n log(`skipped ${s.path}: ${s.reason}`);\r\n }\r\n\r\n const meta: Record<string, unknown> = { ...opts.metadata };\r\n if (opts.tags && opts.tags.length > 0) meta.tags = opts.tags;\r\n\r\n let deletedForReplace = 0;\r\n const pending: PendingRow[] = [];\r\n let skippedExisting = 0;\r\n\r\n for (const doc of docs) {\r\n if (opts.replace) {\r\n deletedForReplace += await deleteBySource(ks, doc.source);\r\n }\r\n const existing = await sourceChunkHashes(ks, doc.source);\r\n for (const chunk of doc.chunks) {\r\n if (!opts.replace && existing.get(chunk.index) === contentHash(chunk.content)) {\r\n skippedExisting++;\r\n continue;\r\n }\r\n pending.push({ doc, chunk, metadata: meta });\r\n }\r\n }\r\n\r\n const { inserted } = await embedAndInsert(ks, pending, {\r\n url: ollamaUrl(opts.url),\r\n dryRun: opts.dryRun ?? false,\r\n batchSize: opts.batchSize ?? 32,\r\n log,\r\n });\r\n\r\n return {\r\n documents: docs.length,\r\n chunks: docs.reduce((n, d) => n + d.chunks.length, 0),\r\n inserted,\r\n skippedExisting,\r\n deletedForReplace,\r\n skippedFiles: skipped,\r\n dryRun: opts.dryRun ?? false,\r\n };\r\n}\r\n\r\nexport async function feedText(\r\n ks: KnowledgeSource,\r\n text: string,\r\n opts: {\r\n title?: string;\r\n sourceName?: string;\r\n url?: string;\r\n replace?: boolean;\r\n dryRun?: boolean;\r\n batchSize?: number;\r\n maxLen?: number;\r\n overlap?: number;\r\n tags?: string[];\r\n metadata?: Record<string, unknown>;\r\n log?: (msg: string) => void;\r\n } = {},\r\n): Promise<FeedSummary> {\r\n const log = opts.log ?? ((m: string) => console.log(m));\r\n const source = opts.sourceName?.trim() || \"manual\";\r\n const title = opts.title?.trim() || source;\r\n const chunks = chunkMarkdown(text, { maxLen: opts.maxLen ?? 1200, overlap: opts.overlap ?? 180 });\r\n const doc: LoadedDoc = { source, title, chunks };\r\n log(`${source}: ${chunks.length} chunk(s)`);\r\n\r\n const meta: Record<string, unknown> = { ...opts.metadata };\r\n if (opts.tags && opts.tags.length > 0) meta.tags = opts.tags;\r\n\r\n let deletedForReplace = 0;\r\n const pending: PendingRow[] = [];\r\n let skippedExisting = 0;\r\n\r\n if (opts.replace) {\r\n deletedForReplace += await deleteBySource(ks, source);\r\n }\r\n const existing = await sourceChunkHashes(ks, source);\r\n for (const chunk of chunks) {\r\n if (!opts.replace && existing.get(chunk.index) === contentHash(chunk.content)) {\r\n skippedExisting++;\r\n continue;\r\n }\r\n pending.push({ doc, chunk, metadata: meta });\r\n }\r\n\r\n const { inserted } = await embedAndInsert(ks, pending, {\r\n url: ollamaUrl(opts.url),\r\n dryRun: opts.dryRun ?? false,\r\n batchSize: opts.batchSize ?? 32,\r\n log,\r\n });\r\n\r\n return {\r\n documents: 1,\r\n chunks: chunks.length,\r\n inserted,\r\n skippedExisting,\r\n deletedForReplace,\r\n skippedFiles: [],\r\n dryRun: opts.dryRun ?? false,\r\n };\r\n}\r\n","export interface Chunk {\r\n index: number;\r\n content: string;\r\n}\r\n\r\nexport interface ChunkOptions {\r\n maxLen?: number;\r\n overlap?: number;\r\n}\r\n\r\nconst HEADING_RE = /^(#{1,6})\\s+(.+)$/;\r\n\r\nfunction splitBlocks(text: string): string[] {\r\n return text\r\n .split(/\\n{2,}/)\r\n .map((b) => b.trim())\r\n .filter((b) => b.length > 0);\r\n}\r\n\r\nfunction cutPoint(slice: string): number {\r\n const nl = slice.lastIndexOf(\"\\n\");\r\n if (nl > slice.length * 0.5) return nl + 1;\r\n const dot = slice.lastIndexOf(\". \");\r\n if (dot > slice.length * 0.5) return dot + 1;\r\n const sp = slice.lastIndexOf(\" \");\r\n if (sp > slice.length * 0.5) return sp + 1;\r\n return slice.length;\r\n}\r\n\r\nfunction hardSplit(block: string, maxLen: number, overlap: number): string[] {\r\n const parts: string[] = [];\r\n let pos = 0;\r\n while (pos < block.length) {\r\n const end = Math.min(pos + maxLen, block.length);\r\n let slice = block.slice(pos, end);\r\n if (end < block.length) {\r\n const cut = cutPoint(slice);\r\n slice = slice.slice(0, cut);\r\n }\r\n parts.push(slice.trim());\r\n if (end >= block.length) break;\r\n const advanced = Math.max(slice.length - overlap, 1);\r\n pos += advanced;\r\n }\r\n return parts.filter((p) => p.length > 0);\r\n}\r\n\r\nfunction packBlocks(blocks: string[], maxLen: number, overlap: number): string[] {\r\n const pieces: string[] = [];\r\n let current = \"\";\r\n for (const block of blocks) {\r\n const expanded =\r\n block.length > maxLen ? hardSplit(block, maxLen, overlap) : [block];\r\n for (const part of expanded) {\r\n if (!current) {\r\n current = part;\r\n } else if (current.length + 2 + part.length <= maxLen) {\r\n current += \"\\n\\n\" + part;\r\n } else {\r\n pieces.push(current);\r\n const tail =\r\n overlap > 0 && current.length > overlap\r\n ? current.slice(current.length - overlap).replace(/^\\S+\\s+/, \"\")\r\n : \"\";\r\n current = tail ? tail + \"\\n\\n\" + part : part;\r\n }\r\n }\r\n }\r\n if (current) pieces.push(current);\r\n return pieces;\r\n}\r\n\r\nexport function chunkMarkdown(text: string, opts: ChunkOptions = {}): Chunk[] {\r\n const maxLen = opts.maxLen ?? 1200;\r\n const overlap = Math.min(opts.overlap ?? 180, Math.floor(maxLen / 4));\r\n const norm = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n if (!norm) return [];\r\n\r\n const lines = norm.split(\"\\n\");\r\n const sections: { path: string[]; body: string[] }[] = [{ path: [], body: [] }];\r\n for (const line of lines) {\r\n const m = HEADING_RE.exec(line);\r\n if (m) {\r\n const level = m[1]!.length;\r\n const path = sections[sections.length - 1]!.path;\r\n const parent = path.slice(0, level - 1);\r\n sections.push({ path: [...parent, m[2]!.trim()], body: [line] });\r\n } else {\r\n sections[sections.length - 1]!.body.push(line);\r\n }\r\n }\r\n\r\n const pieces: string[] = [];\r\n for (const s of sections) {\r\n const body = s.body.join(\"\\n\").trim();\r\n if (!body) continue;\r\n const context = s.path.length > 0 ? s.path.join(\" > \") + \"\\n\" : \"\";\r\n const packed = packBlocks(splitBlocks(body), maxLen, overlap);\r\n packed.forEach((piece, i) => {\r\n pieces.push(i === 0 || !context ? piece : context + piece);\r\n });\r\n }\r\n return pieces.map((content, index) => ({ index, content }));\r\n}\r\n\r\nexport function chunkPlain(text: string, opts: ChunkOptions = {}): Chunk[] {\r\n const maxLen = opts.maxLen ?? 1200;\r\n const overlap = Math.min(opts.overlap ?? 180, Math.floor(maxLen / 4));\r\n const norm = text.replace(/\\r\\n?/g, \"\\n\").replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n if (!norm) return [];\r\n const pieces = packBlocks(splitBlocks(norm), maxLen, overlap);\r\n return pieces.map((content, index) => ({ index, content }));\r\n}\r\n\r\nexport function mdTitle(text: string): string | undefined {\r\n const m = /^#\\s+(.+)\\s*$/m.exec(text);\r\n return m ? m[1]!.trim() : undefined;\r\n}\r\n","import { JSDOM } from \"jsdom\";\r\nimport TurndownService from \"turndown\";\r\nimport gfmModule from \"turndown-plugin-gfm\";\r\n\r\nconst gfm: (service: TurndownService) => void =\r\n typeof gfmModule === \"function\"\r\n ? (gfmModule as unknown as (service: TurndownService) => void)\r\n : ((gfmModule as { gfm?: (service: TurndownService) => void }).gfm as (service: TurndownService) => void);\r\n\r\nconst REMOVE_SELECTORS =\r\n \"script, style, noscript, template, iframe, svg, nav, footer, aside, form, button\";\r\n\r\nlet service: TurndownService | undefined;\r\n\r\nfunction turndown(): TurndownService {\r\n if (!service) {\r\n service = new TurndownService({\r\n headingStyle: \"atx\",\r\n codeBlockStyle: \"fenced\",\r\n bulletListMarker: \"-\",\r\n });\r\n if (typeof gfm === \"function\") {\r\n service.use(gfm);\r\n }\r\n service.remove([\"button\"]);\r\n }\r\n return service;\r\n}\r\n\r\nexport function htmlToMarkdown(html: string): { markdown: string; title?: string } {\r\n const dom = new JSDOM(html);\r\n const doc = dom.window.document;\r\n doc.querySelectorAll(REMOVE_SELECTORS).forEach((el) => el.remove());\r\n\r\n const title =\r\n doc.title?.trim() || doc.querySelector(\"h1\")?.textContent?.trim() || undefined;\r\n\r\n const root = doc.body ?? doc.documentElement;\r\n let markdown = \"\";\r\n try {\r\n markdown = turndown().turndown(root.innerHTML);\r\n } catch {\r\n markdown = root.textContent ?? \"\";\r\n }\r\n markdown = markdown.replace(/\\n{3,}/g, \"\\n\\n\").trim();\r\n return { markdown, title: title || undefined };\r\n}\r\n","import pg from \"pg\";\r\nimport { databaseUrl, normalizeUrl, ollamaUrl } from \"./config.js\";\r\nimport { entryTableName } from \"./db.js\";\r\nimport { probeModel } from \"./ollama.js\";\r\n\r\nexport const MIN_NODE_MAJOR = 20;\r\nexport const MIN_PGVECTOR_VERSION = \"0.5.0\";\r\nconst DB_CONNECT_TIMEOUT_MS = 5_000;\r\nconst OLLAMA_TIMEOUT_MS = 10_000;\r\n\r\nexport type CheckStatus = \"ok\" | \"warn\" | \"fail\" | \"skip\";\r\n\r\nexport interface CheckResult {\r\n id: string;\r\n status: CheckStatus;\r\n detail: string;\r\n}\r\n\r\nexport interface KsInfo {\r\n id: string;\r\n name: string;\r\n embedding_model: string;\r\n embedding_dim: number;\r\n ollama_url: string;\r\n}\r\n\r\nexport interface CheckOptions {\r\n model?: string;\r\n url?: string;\r\n probe?: boolean;\r\n}\r\n\r\nexport function compareVersions(a: string, b: string): number {\r\n const pa = a.split(/[.-]/).map((s) => parseInt(s, 10) || 0);\r\n const pb = b.split(/[.-]/).map((s) => parseInt(s, 10) || 0);\r\n const len = Math.max(pa.length, pb.length);\r\n for (let i = 0; i < len; i++) {\r\n const d = (pa[i] ?? 0) - (pb[i] ?? 0);\r\n if (d !== 0) return d < 0 ? -1 : 1;\r\n }\r\n return 0;\r\n}\r\n\r\nexport function modelMatches(tag: string, wanted: string): boolean {\r\n if (tag === wanted) return true;\r\n if (wanted.includes(\":\")) return false;\r\n return tag === `${wanted}:latest`;\r\n}\r\n\r\nfunction errMsg(err: unknown): string {\r\n return err instanceof Error ? err.message : String(err);\r\n}\r\n\r\nfunction shortVersion(v: string): string {\r\n return v.split(/\\s+/).slice(0, 2).join(\" \") || v;\r\n}\r\n\r\ntype TagResult = { names: string[] } | { error: string };\r\n\r\nasync function fetchTags(baseUrl: string): Promise<TagResult> {\r\n try {\r\n const res = await fetch(`${normalizeUrl(baseUrl)}/api/tags`, {\r\n headers: { accept: \"application/json\" },\r\n signal: AbortSignal.timeout(OLLAMA_TIMEOUT_MS),\r\n });\r\n if (!res.ok) return { error: `HTTP ${res.status}` };\r\n const data = (await res.json()) as { models?: { name?: string; model?: string }[] };\r\n const names = (data.models ?? [])\r\n .map((m) => m.name ?? m.model ?? \"\")\r\n .filter(Boolean);\r\n return { names };\r\n } catch (err) {\r\n return { error: errMsg(err) };\r\n }\r\n}\r\n\r\nasync function checkOneModel(\r\n id: string,\r\n model: string,\r\n baseUrl: string,\r\n names: string[],\r\n ks: KsInfo | undefined,\r\n probe: boolean,\r\n): Promise<CheckResult> {\r\n const scope = ks ? ` (ks '${ks.name}')` : \"\";\r\n if (!names.some((n) => modelMatches(n, model))) {\r\n return {\r\n id,\r\n status: \"fail\",\r\n detail: `model '${model}' not found at ${baseUrl}${scope} — run: ollama pull ${model}`,\r\n };\r\n }\r\n if (probe) {\r\n try {\r\n const { dim } = await probeModel(baseUrl, model);\r\n if (ks && dim !== ks.embedding_dim) {\r\n return {\r\n id,\r\n status: \"fail\",\r\n detail: `model '${model}' serves dim=${dim} but ks '${ks.name}' expects dim=${ks.embedding_dim}`,\r\n };\r\n }\r\n return { id, status: \"ok\", detail: `model '${model}' available at ${baseUrl}${scope} (dim=${dim})` };\r\n } catch (err) {\r\n return { id, status: \"fail\", detail: `probe of model '${model}' failed — ${errMsg(err)}${scope}` };\r\n }\r\n }\r\n return { id, status: \"ok\", detail: `model '${model}' available at ${baseUrl}${scope}` };\r\n}\r\n\r\nexport async function runChecks(opts: CheckOptions = {}): Promise<CheckResult[]> {\r\n const results: CheckResult[] = [];\r\n\r\n const major = Number(process.versions.node.split(\".\")[0]);\r\n results.push({\r\n id: \"node\",\r\n status: Number.isFinite(major) && major >= MIN_NODE_MAJOR ? \"ok\" : \"fail\",\r\n detail: `Node ${process.versions.node} (>= ${MIN_NODE_MAJOR} required)`,\r\n });\r\n\r\n let client: pg.Client | undefined;\r\n let dbUp = false;\r\n let kss: KsInfo[] = [];\r\n try {\r\n try {\r\n client = new pg.Client({\r\n connectionString: databaseUrl(),\r\n connectionTimeoutMillis: DB_CONNECT_TIMEOUT_MS,\r\n });\r\n client.on(\"error\", () => {});\r\n await client.connect();\r\n const v = await client.query(\"SELECT version() AS v\");\r\n dbUp = true;\r\n results.push({\r\n id: \"postgres\",\r\n status: \"ok\",\r\n detail: `PostgreSQL reachable at ${databaseUrl()} (${shortVersion(String(v.rows[0]?.v ?? \"\"))})`,\r\n });\r\n } catch (err) {\r\n results.push({\r\n id: \"postgres\",\r\n status: \"fail\",\r\n detail: `PostgreSQL not reachable at ${databaseUrl()} — ${errMsg(err)}`,\r\n });\r\n }\r\n\r\n if (dbUp && client) {\r\n try {\r\n await client.query(`CREATE EXTENSION IF NOT EXISTS vector`);\r\n const res = await client.query(\"SELECT extversion AS v FROM pg_extension WHERE extname = 'vector'\");\r\n const ver = res.rows[0]?.v as string | undefined;\r\n if (!ver) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"fail\",\r\n detail: \"pgvector extension not installed — install it on the PostgreSQL server (https://github.com/pgvector/pgvector)\",\r\n });\r\n } else if (compareVersions(ver, MIN_PGVECTOR_VERSION) < 0) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"warn\",\r\n detail: `pgvector ${ver} installed (>= ${MIN_PGVECTOR_VERSION} required for HNSW indexes; older versions fall back to sequential scans)`,\r\n });\r\n } else {\r\n results.push({ id: \"pgvector\", status: \"ok\", detail: `pgvector ${ver} installed` });\r\n }\r\n } catch (err) {\r\n results.push({\r\n id: \"pgvector\",\r\n status: \"fail\",\r\n detail: `pgvector unavailable — ${errMsg(err)}`,\r\n });\r\n }\r\n } else {\r\n results.push({ id: \"pgvector\", status: \"skip\", detail: \"pgvector check skipped — PostgreSQL unreachable\" });\r\n }\r\n\r\n if (dbUp && client) {\r\n try {\r\n const hasKs = await client.query(\"SELECT to_regclass('ks') IS NOT NULL AS present\");\r\n if (!hasKs.rows[0]?.present) {\r\n results.push({ id: \"schema\", status: \"fail\", detail: \"schema missing — run: gresmcp init\" });\r\n } else {\r\n const ksRes = await client.query(\r\n \"SELECT id, name, embedding_model, embedding_dim, ollama_url FROM ks ORDER BY name\",\r\n );\r\n kss = ksRes.rows as KsInfo[];\r\n const missing: string[] = [];\r\n for (const ks of kss) {\r\n const r = await client.query(\"SELECT to_regclass($1) IS NOT NULL AS present\", [entryTableName(ks)]);\r\n if (!r.rows[0]?.present) missing.push(ks.name);\r\n }\r\n if (missing.length > 0) {\r\n results.push({\r\n id: \"schema\",\r\n status: \"fail\",\r\n detail: `entry table missing for: ${missing.join(\", \")} — run: gresmcp init`,\r\n });\r\n } else {\r\n results.push({\r\n id: \"schema\",\r\n status: \"ok\",\r\n detail: `schema ready (${kss.length} knowledge source(s))`,\r\n });\r\n }\r\n }\r\n } catch (err) {\r\n results.push({ id: \"schema\", status: \"fail\", detail: `schema check failed — ${errMsg(err)}` });\r\n }\r\n } else {\r\n results.push({ id: \"schema\", status: \"skip\", detail: \"schema check skipped — PostgreSQL unreachable\" });\r\n }\r\n } finally {\r\n if (client) {\r\n try {\r\n await client.end();\r\n } catch {}\r\n }\r\n }\r\n\r\n const defaultUrl = ollamaUrl(opts.url);\r\n const tagCache = new Map<string, Promise<TagResult>>();\r\n const getTags = (baseUrl: string): Promise<TagResult> => {\r\n const key = normalizeUrl(baseUrl);\r\n let entry = tagCache.get(key);\r\n if (!entry) {\r\n entry = fetchTags(key);\r\n tagCache.set(key, entry);\r\n }\r\n return entry;\r\n };\r\n\r\n const defaultTags = await getTags(defaultUrl);\r\n results.push(\r\n \"error\" in defaultTags\r\n ? { id: \"ollama\", status: \"fail\", detail: `Ollama not reachable at ${defaultUrl} — ${defaultTags.error}` }\r\n : { id: \"ollama\", status: \"ok\", detail: `Ollama reachable at ${defaultUrl} (${defaultTags.names.length} model(s))` },\r\n );\r\n\r\n if (opts.model) {\r\n const tags = await getTags(defaultUrl);\r\n if (\"error\" in tags) {\r\n results.push({\r\n id: \"model\",\r\n status: \"skip\",\r\n detail: `Ollama unreachable at ${defaultUrl} — cannot verify model '${opts.model}'`,\r\n });\r\n } else {\r\n results.push(await checkOneModel(\"model\", opts.model, defaultUrl, tags.names, undefined, opts.probe ?? false));\r\n }\r\n }\r\n\r\n for (const ks of kss) {\r\n const tags = await getTags(ks.ollama_url);\r\n if (\"error\" in tags) {\r\n results.push({\r\n id: `model:${ks.name}`,\r\n status: \"fail\",\r\n detail: `Ollama not reachable at ${ks.ollama_url} (required by ks '${ks.name}') — ${tags.error}`,\r\n });\r\n continue;\r\n }\r\n results.push(\r\n await checkOneModel(`model:${ks.name}`, ks.embedding_model, ks.ollama_url, tags.names, ks, opts.probe ?? false),\r\n );\r\n }\r\n\r\n if (!opts.model && kss.length === 0) {\r\n results.push({\r\n id: \"model\",\r\n status: \"warn\",\r\n detail: \"no embedding model to verify — pass --model <model> or create a knowledge source\",\r\n });\r\n }\r\n\r\n return results;\r\n}\r\n","export const VERSION = \"1.0.0\";\r\n"],"mappings":"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","names":["res","path","ensureEntryTable"]}
|