@jcode.labs/ragmir 2.0.0 → 2.2.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/dist/access-log.d.ts.map +1 -1
- package/dist/access-log.js +32 -1
- package/dist/access-log.js.map +1 -1
- package/dist/cli-options.d.ts +48 -0
- package/dist/cli-options.d.ts.map +1 -0
- package/dist/cli-options.js +92 -0
- package/dist/cli-options.js.map +1 -0
- package/dist/cli.js +1 -68
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +28 -6
- package/dist/config.js.map +1 -1
- package/dist/defaults.d.ts +0 -1
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +0 -7
- package/dist/defaults.js.map +1 -1
- package/dist/destroy.d.ts.map +1 -1
- package/dist/destroy.js +4 -0
- package/dist/destroy.js.map +1 -1
- package/dist/embeddings.d.ts +6 -0
- package/dist/embeddings.d.ts.map +1 -1
- package/dist/embeddings.js +31 -0
- package/dist/embeddings.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +57 -29
- package/dist/query.js.map +1 -1
- package/dist/redaction.d.ts.map +1 -1
- package/dist/redaction.js +48 -2
- package/dist/redaction.js.map +1 -1
- package/dist/sources.d.ts +13 -0
- package/dist/sources.d.ts.map +1 -1
- package/dist/sources.js +70 -21
- package/dist/sources.js.map +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +46 -1
- package/dist/store.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/examples/library-api-demo/README.md +2 -1
- package/package.json +4 -4
- package/skills/ragmir-audio-summary/SKILL.md +107 -25
- package/skills/ragmir-audio-summary/listening-style.md +91 -0
- package/skills/ragmir-audio-summary/narration-templates.md +162 -0
package/dist/sources.js
CHANGED
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
import { existsSync } from "node:fs";
|
|
2
2
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { loadConfig } from "./config.js";
|
|
5
|
-
|
|
4
|
+
import { findProjectConfig, loadConfig } from "./config.js";
|
|
5
|
+
/**
|
|
6
|
+
* List the configured source entries. Sources live in the `sources` array of
|
|
7
|
+
* `.ragmir/config.json` (the primary mechanism). A legacy `.ragmir/sources.txt`
|
|
8
|
+
* is still read and merged when present so existing projects keep working, but
|
|
9
|
+
* it is never created or written by these functions anymore.
|
|
10
|
+
*/
|
|
6
11
|
export async function listSourceEntries(cwd = process.cwd()) {
|
|
7
12
|
const config = await loadConfig(cwd);
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
+
const projectConfig = findProjectConfig(cwd);
|
|
14
|
+
const configEntries = await readConfigSources(projectConfig);
|
|
15
|
+
const legacyEntries = await readLegacySourcesTxt(config.sourcesFile);
|
|
16
|
+
const seen = new Set();
|
|
17
|
+
const entries = [];
|
|
18
|
+
for (const entry of [...configEntries, ...legacyEntries]) {
|
|
19
|
+
if (!seen.has(entry)) {
|
|
20
|
+
seen.add(entry);
|
|
21
|
+
entries.push(entry);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return { sourcesFile: projectConfig.configPath, entries };
|
|
13
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* Add source entries to the `sources` array of `.ragmir/config.json`. Does not
|
|
28
|
+
* touch the legacy `sources.txt` file anymore; entries already present there
|
|
29
|
+
* are treated as existing (skipped) to avoid duplicates.
|
|
30
|
+
*/
|
|
14
31
|
export async function addSourceEntries(options) {
|
|
15
|
-
const
|
|
16
|
-
if (
|
|
32
|
+
const requested = normalizeRequestedEntries(options.entries);
|
|
33
|
+
if (requested.length === 0) {
|
|
17
34
|
throw new Error("At least one source path or glob is required.");
|
|
18
35
|
}
|
|
19
36
|
const config = await loadConfig(options.cwd);
|
|
20
|
-
const
|
|
21
|
-
const
|
|
37
|
+
const projectConfig = findProjectConfig(options.cwd ?? process.cwd());
|
|
38
|
+
const configEntries = await readConfigSources(projectConfig);
|
|
39
|
+
const existingEntries = new Set([
|
|
40
|
+
...configEntries,
|
|
41
|
+
...(await readLegacySourcesTxt(config.sourcesFile)),
|
|
42
|
+
]);
|
|
22
43
|
const added = [];
|
|
23
44
|
const skipped = [];
|
|
24
|
-
for (const entry of
|
|
45
|
+
for (const entry of requested) {
|
|
25
46
|
if (existingEntries.has(entry)) {
|
|
26
47
|
skipped.push(entry);
|
|
27
48
|
continue;
|
|
@@ -30,20 +51,49 @@ export async function addSourceEntries(options) {
|
|
|
30
51
|
added.push(entry);
|
|
31
52
|
}
|
|
32
53
|
if (added.length > 0) {
|
|
33
|
-
await
|
|
34
|
-
await writeFile(config.sourcesFile, nextSourcesFileContent(content, added), "utf8");
|
|
54
|
+
await writeConfigSources(projectConfig, [...configEntries, ...added]);
|
|
35
55
|
}
|
|
36
56
|
return {
|
|
37
|
-
sourcesFile:
|
|
57
|
+
sourcesFile: projectConfig.configPath,
|
|
38
58
|
added,
|
|
39
59
|
skipped,
|
|
40
60
|
};
|
|
41
61
|
}
|
|
42
|
-
|
|
62
|
+
/** Read the raw `sources` array from config.json without resolving paths. */
|
|
63
|
+
async function readConfigSources(projectConfig) {
|
|
64
|
+
if (!existsSync(projectConfig.configPath)) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
try {
|
|
68
|
+
const raw = JSON.parse(await readFile(projectConfig.configPath, "utf8"));
|
|
69
|
+
if (isRecord(raw) && Array.isArray(raw.sources)) {
|
|
70
|
+
return raw.sources.filter((entry) => typeof entry === "string");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Fall back to empty if the config is unreadable; loadConfig surfaces real errors elsewhere.
|
|
75
|
+
}
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
/** Write the `sources` array back into config.json, preserving other fields. */
|
|
79
|
+
async function writeConfigSources(projectConfig, entries) {
|
|
80
|
+
await mkdir(path.dirname(projectConfig.configPath), { recursive: true });
|
|
81
|
+
const raw = existsSync(projectConfig.configPath)
|
|
82
|
+
? JSON.parse(await readFile(projectConfig.configPath, "utf8"))
|
|
83
|
+
: {};
|
|
84
|
+
if (!isRecord(raw)) {
|
|
85
|
+
throw new Error(`${path.relative(projectConfig.projectRoot, projectConfig.configPath)} must contain a JSON object.`);
|
|
86
|
+
}
|
|
87
|
+
raw.sources = [...entries];
|
|
88
|
+
await writeFile(projectConfig.configPath, `${JSON.stringify(raw, null, 2)}\n`, "utf8");
|
|
89
|
+
}
|
|
90
|
+
/** Read the legacy sources.txt read-only for backward compatibility. */
|
|
91
|
+
async function readLegacySourcesTxt(sourcesFile) {
|
|
43
92
|
if (!existsSync(sourcesFile)) {
|
|
44
|
-
return
|
|
93
|
+
return [];
|
|
45
94
|
}
|
|
46
|
-
|
|
95
|
+
const content = await readFile(sourcesFile, "utf8");
|
|
96
|
+
return parseSourceEntries(content);
|
|
47
97
|
}
|
|
48
98
|
function parseSourceEntries(content) {
|
|
49
99
|
return content
|
|
@@ -64,8 +114,7 @@ function normalizeRequestedEntries(entries) {
|
|
|
64
114
|
}
|
|
65
115
|
return normalized;
|
|
66
116
|
}
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
return `${base ? `${base}\n` : ""}${added.join("\n")}\n`;
|
|
117
|
+
function isRecord(value) {
|
|
118
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
70
119
|
}
|
|
71
120
|
//# sourceMappingURL=sources.js.map
|
package/dist/sources.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../src/sources.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAiBnD,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBhF;AA6BD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,EAAE,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAevF;AAED,wBAAsB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,CAOjF;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CASnE;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAG/D"}
|
package/dist/store.js
CHANGED
|
@@ -3,6 +3,19 @@ import path from "node:path";
|
|
|
3
3
|
import * as lancedb from "@lancedb/lancedb";
|
|
4
4
|
import { isRecord } from "./guards.js";
|
|
5
5
|
const EMPTY_TEXT_FILES_MANIFEST = "empty-text-files.json";
|
|
6
|
+
/**
|
|
7
|
+
* LanceDB requires a minimum number of rows to train an IVF_PQ vector index.
|
|
8
|
+
* Below this threshold, brute-force (flat) scan is used instead, which is
|
|
9
|
+
* optimal for small corpora and avoids wasted index-training work.
|
|
10
|
+
*/
|
|
11
|
+
const MIN_INDEX_ROWS = 256;
|
|
12
|
+
/**
|
|
13
|
+
* IVF partition count heuristic: roughly sqrt(row_count), bounded to keep both
|
|
14
|
+
* small corpora (too many empty partitions) and very large corpora (training
|
|
15
|
+
* cost) well-behaved. See LanceDB production guidance.
|
|
16
|
+
*/
|
|
17
|
+
const MIN_IVF_PARTITIONS = 8;
|
|
18
|
+
const MAX_IVF_PARTITIONS = 1024;
|
|
6
19
|
export async function writeRows(rows, config) {
|
|
7
20
|
await mkdir(config.storageDir, { recursive: true });
|
|
8
21
|
const db = await lancedb.connect(config.storageDir);
|
|
@@ -14,9 +27,41 @@ export async function writeRows(rows, config) {
|
|
|
14
27
|
return;
|
|
15
28
|
}
|
|
16
29
|
const records = rows.map((row) => ({ ...row }));
|
|
17
|
-
await db.createTable(config.tableName, records, {
|
|
30
|
+
const table = await db.createTable(config.tableName, records, {
|
|
18
31
|
mode: "overwrite",
|
|
19
32
|
});
|
|
33
|
+
// Train an IVF_PQ vector index once the corpus is large enough to benefit
|
|
34
|
+
// from approximate nearest-neighbour search. Below the threshold, LanceDB
|
|
35
|
+
// falls back to an exact flat scan, which is faster for small corpora and
|
|
36
|
+
// avoids wasting work training an index on too few vectors.
|
|
37
|
+
if (rows.length >= MIN_INDEX_ROWS) {
|
|
38
|
+
await ensureVectorIndex(table, rows.length);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function ensureVectorIndex(table, rowCount) {
|
|
42
|
+
const existing = await table.listIndices();
|
|
43
|
+
const hasVectorIndex = existing.some((index) => index.name === "vector_idx");
|
|
44
|
+
if (hasVectorIndex) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
// numSubVectors must divide the vector dimension evenly. 16 is a safe default
|
|
48
|
+
// for the 384-dim local-hash and mxbai-xsmall models; LanceDB validates and
|
|
49
|
+
// will reject a value that does not divide evenly, so larger models still
|
|
50
|
+
// fall back to flat scan rather than corrupting the index.
|
|
51
|
+
const numSubVectors = 16;
|
|
52
|
+
const numPartitions = clampIvfPartitions(Math.round(Math.sqrt(rowCount)));
|
|
53
|
+
try {
|
|
54
|
+
await table.createIndex("vector", {
|
|
55
|
+
config: lancedb.Index.ivfPq({ numPartitions, numSubVectors }),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Index training can fail on edge-case dimensionality or tiny effective
|
|
60
|
+
// corpora; the table remains usable via flat scan. Do not fail the ingest.
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function clampIvfPartitions(value) {
|
|
64
|
+
return Math.min(MAX_IVF_PARTITIONS, Math.max(MIN_IVF_PARTITIONS, value));
|
|
20
65
|
}
|
|
21
66
|
export async function writeEmptyTextFiles(records, config) {
|
|
22
67
|
const manifestPath = path.join(config.storageDir, EMPTY_TEXT_FILES_MANIFEST);
|
package/dist/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,KAAK,OAAO,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGtC,MAAM,yBAAyB,GAAG,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -56,6 +56,8 @@ export interface RedactionPattern {
|
|
|
56
56
|
pattern: string;
|
|
57
57
|
flags?: string | undefined;
|
|
58
58
|
replacement?: string | undefined;
|
|
59
|
+
/** Optional post-match verification for patterns prone to false positives. */
|
|
60
|
+
verify?: "luhn" | undefined;
|
|
59
61
|
}
|
|
60
62
|
export interface RedactionCount {
|
|
61
63
|
name: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAE1D,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,cAAc,EAAE,MAAM,CAAA;IACtB,6BAA6B,EAAE,OAAO,CAAA;IACtC,SAAS,EAAE,eAAe,CAAA;IAC1B,SAAS,EAAE,OAAO,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;IACvB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,EAAE,CAAA;IAC3B,mBAAmB,EAAE,MAAM,CAAA;CAC5B;AAED,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,QAAQ,GACR,KAAK,GACL,UAAU,GACV,UAAU,GACV,eAAe,CAAA;AAEnB,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,QAAQ,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,OAAO,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,CAAA;IAC/C,iBAAiB,EAAE,MAAM,CAAA;IACzB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,cAAc,CAAA;AAE7D,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,gBAAgB,EAAE,CAAA;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.2.0";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = "2.
|
|
1
|
+
export const VERSION = "2.2.0";
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -25,7 +25,8 @@ That builds Ragmir Core, then runs the demo. It reuses the committed synthetic c
|
|
|
25
25
|
`sovereign-rag-demo`, so it needs no private documents and writes only to that example's gitignored
|
|
26
26
|
`.ragmir/storage`.
|
|
27
27
|
|
|
28
|
-
To run it directly against the already-built `dist/` without rebuilding
|
|
28
|
+
To run it directly against the already-built `dist/` without rebuilding (run `pnpm build` first;
|
|
29
|
+
`dist/` is gitignored, so a clean clone has none):
|
|
29
30
|
|
|
30
31
|
```bash
|
|
31
32
|
node packages/ragmir-core/examples/library-api-demo/run.mjs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jcode.labs/ragmir",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Ragmir Core: open-source sovereign local RAG for confidential datasets and AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"unpdf": "^1.4.0",
|
|
69
69
|
"yaml": "^2.9.0",
|
|
70
70
|
"zod": "^4.1.13",
|
|
71
|
-
"@jcode.labs/ragmir-tts": "2.
|
|
71
|
+
"@jcode.labs/ragmir-tts": "2.2.0"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@types/html-to-text": "^9.0.4",
|
|
@@ -79,9 +79,9 @@
|
|
|
79
79
|
},
|
|
80
80
|
"scripts": {
|
|
81
81
|
"build": "tsc -p tsconfig.json",
|
|
82
|
-
"check": "tsc -p tsconfig.json --noEmit",
|
|
82
|
+
"check": "pnpm --filter @jcode.labs/ragmir-tts build && tsc -p tsconfig.json --noEmit",
|
|
83
83
|
"mcp:smoke": "pnpm build && node scripts/mcp-smoke.mjs",
|
|
84
84
|
"package:check": "publint",
|
|
85
|
-
"test": "vitest run"
|
|
85
|
+
"test": "pnpm --filter @jcode.labs/ragmir-tts build && vitest run"
|
|
86
86
|
}
|
|
87
87
|
}
|
|
@@ -1,17 +1,35 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ragmir-audio-summary
|
|
3
3
|
description: >-
|
|
4
|
-
Create an
|
|
5
|
-
for an audio, TTS, spoken brief, briefing, narration, or listenable summary
|
|
6
|
-
repository documents indexed by Ragmir. The skill is confidentiality-first:
|
|
7
|
-
|
|
8
|
-
audio under ignored local Ragmir state unless the user
|
|
4
|
+
Create an intention-driven, memorable spoken audio summary from a Ragmir local knowledge base. Use
|
|
5
|
+
when the user asks for an audio, TTS, spoken brief, briefing, narration, or listenable summary
|
|
6
|
+
based on private repository documents indexed by Ragmir. The skill is confidentiality-first: it
|
|
7
|
+
filters everything against the user's intent, writes only a temporary narration text file outside
|
|
8
|
+
the repository, and renders the final audio under ignored local Ragmir state unless the user
|
|
9
|
+
explicitly chooses another output path.
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
# Ragmir Audio Summary
|
|
12
13
|
|
|
13
|
-
Use this skill to turn a confidential local Ragmir knowledge base into
|
|
14
|
-
|
|
14
|
+
Use this skill to turn a confidential local Ragmir knowledge base into a spoken summary that
|
|
15
|
+
respects the listener: only what serves their intent, structured to be intelligible in one pass, and
|
|
16
|
+
designed to be retained.
|
|
17
|
+
|
|
18
|
+
The knowledge base stays local. The final audio is a generated artifact and must not be committed.
|
|
19
|
+
|
|
20
|
+
The goal is not a "basic summary read aloud". It is a deliberate narration built from five
|
|
21
|
+
techniques:
|
|
22
|
+
|
|
23
|
+
1. **Intent-first filtering** — drop everything that does not serve what the user actually needs.
|
|
24
|
+
2. **Density-driven duration** — short for a small topic, long for a large one. Never pad.
|
|
25
|
+
3. **Pyramid structure** — answer first, then the supporting points, then a recap.
|
|
26
|
+
4. **Writing for the ear** — short sentences, spoken signposting, deliberate TTS punctuation.
|
|
27
|
+
5. **Active recall** — two-to-three self-check questions that force retrieval and anchor memory.
|
|
28
|
+
|
|
29
|
+
Two reference files sit next to this skill and are read while drafting:
|
|
30
|
+
|
|
31
|
+
- `listening-style.md` — how to write prose a TTS engine can pronounce and a listener can follow.
|
|
32
|
+
- `narration-templates.md` — skeletons per format, plus signposting and active-recall catalogues.
|
|
15
33
|
|
|
16
34
|
## Confidentiality Rules
|
|
17
35
|
|
|
@@ -25,7 +43,22 @@ The knowledge base stays local; the final audio is a generated artifact and must
|
|
|
25
43
|
- Render audio under `.ragmir/audio/` by default. This directory is ignored by Git when Ragmir is installed.
|
|
26
44
|
- Never stage or commit generated audio, temporary text, WAV, AIFF, or intermediate files.
|
|
27
45
|
|
|
28
|
-
## 1.
|
|
46
|
+
## 1. Capture The Intent Before Searching
|
|
47
|
+
|
|
48
|
+
Do not run any search yet. First make the intent explicit so every later step filters by it. Confirm
|
|
49
|
+
with the user when it is ambiguous, or infer it from their request and state your assumption.
|
|
50
|
+
|
|
51
|
+
Capture four things:
|
|
52
|
+
|
|
53
|
+
- **Purpose** — what the listener will do with this: decide, learn, monitor, compare, or plan.
|
|
54
|
+
- **Subject** — the precise question or topic, narrower than "summarize everything".
|
|
55
|
+
- **Depth** — a quick scan or a deep dossier. Let the user steer, but default from the material.
|
|
56
|
+
- **Language** — the spoken language, passed later to `--lang` (`fr` default, `en`, `es`).
|
|
57
|
+
|
|
58
|
+
This is the guardrail against superfluous data: anything that does not advance the captured intent
|
|
59
|
+
gets dropped at the drafting step, not added because it was "also in the documents".
|
|
60
|
+
|
|
61
|
+
## 2. Verify The Knowledge Base
|
|
29
62
|
|
|
30
63
|
From the repository root, run:
|
|
31
64
|
|
|
@@ -48,9 +81,10 @@ pnpm exec ragmir audit --unsupported
|
|
|
48
81
|
has no warnings. Do not create an audio summary from stale or incomplete evidence unless the user
|
|
49
82
|
explicitly accepts that limitation.
|
|
50
83
|
|
|
51
|
-
##
|
|
84
|
+
## 3. Search Deeply, Guided By The Intent
|
|
52
85
|
|
|
53
|
-
Use Ragmir search or MCP tools to gather evidence
|
|
86
|
+
Use Ragmir search or MCP tools to gather evidence, and derive the queries from the intent captured
|
|
87
|
+
in step 1 — not from the subject alone.
|
|
54
88
|
|
|
55
89
|
For a broad summary, run multiple searches:
|
|
56
90
|
|
|
@@ -63,26 +97,72 @@ pnpm exec ragmir ask "<specific synthesis question>" --top-k 8
|
|
|
63
97
|
When MCP is available, prefer `ragmir_search`, `ragmir_ask`, `ragmir_audit`, and
|
|
64
98
|
`ragmir_security_audit` over shell commands.
|
|
65
99
|
|
|
66
|
-
Keep citations in your working notes, but do not read long raw passages aloud. The audio
|
|
67
|
-
|
|
100
|
+
Keep citations in your working notes, but do not read long raw passages aloud. The audio is a clear
|
|
101
|
+
synthesis, not a dump of source text.
|
|
102
|
+
|
|
103
|
+
While searching, also gauge the **density of relevant material** for step 4:
|
|
104
|
+
|
|
105
|
+
- How many passages directly serve the intent?
|
|
106
|
+
- Do they overlap, reinforce, or contradict each other?
|
|
107
|
+
- Are there clear facets (chapters) or one tight question?
|
|
108
|
+
|
|
109
|
+
## 4. Choose The Format From The Density
|
|
110
|
+
|
|
111
|
+
Pick the format from the relevant material found, not from a fixed default. Length follows material;
|
|
112
|
+
never pad.
|
|
113
|
+
|
|
114
|
+
| Format | Use when | Word budget | Duration |
|
|
115
|
+
| --- | --- | --- | --- |
|
|
116
|
+
| **Micro-brief** | One clear question or little relevant material | 150-220 words | ~60-90 s |
|
|
117
|
+
| **Brief standard** | Moderate material, a few angles worth keeping | 450-750 words | ~3-5 min |
|
|
118
|
+
| **Dossier long** | Dense, multi-faceted material needing chapters | 1500-3000 words | ~10-20 min |
|
|
119
|
+
|
|
120
|
+
If two formats plausibly fit, prefer the shorter one unless the user asked for depth. A short,
|
|
121
|
+
dense summary respects the listener more than a padded one.
|
|
122
|
+
|
|
123
|
+
If the user explicitly asks for a long audio on a thin topic, say so in the final report and keep
|
|
124
|
+
the narration tight rather than inflated.
|
|
125
|
+
|
|
126
|
+
## 5. Write For Listening
|
|
127
|
+
|
|
128
|
+
Write one flowing narration in the chosen language. No markdown, headings, bullets, tables, SSML, or
|
|
129
|
+
XML tags in the spoken text. Open `listening-style.md` for the full rules; the cardinal ones:
|
|
130
|
+
|
|
131
|
+
- **Pyramid first.** State the key message (one-to-four points to retain) up front, then develop it,
|
|
132
|
+
then recap it. This exploits primacy and recency.
|
|
133
|
+
- **Signpost, do not list.** Use spoken transitions ("D'abord…, Ensuite…, Enfin…") instead of
|
|
134
|
+
enumerated lists. See `narration-templates.md` for the catalogue.
|
|
135
|
+
- **Short sentences.** One idea per sentence, twenty words or fewer. Split long ones.
|
|
136
|
+
- **Deliberate punctuation.** Periods for full pauses, commas for micro-pauses, `…` for the
|
|
137
|
+
deliberate beat before an active-recall answer. Avoid semicolons and exclamation marks.
|
|
138
|
+
- **Pronounceable.** Expand acronyms on first use, write numbers and symbols in words, never read
|
|
139
|
+
URLs, paths, or code aloud.
|
|
140
|
+
|
|
141
|
+
Read the draft aloud once at a normal pace. If you stumble or run out of breath, the sentence is too
|
|
142
|
+
long or too dense — fix it.
|
|
68
143
|
|
|
69
|
-
##
|
|
144
|
+
## 6. Anchor Memorability
|
|
70
145
|
|
|
71
|
-
|
|
72
|
-
tables, SSML, XML tags, or stage directions in the spoken text.
|
|
146
|
+
Build two devices into every narration, systematically:
|
|
73
147
|
|
|
74
|
-
|
|
148
|
+
1. **Recap the key points twice** — once right after the opening message, once at the very end.
|
|
149
|
+
Same points, compressed, in different words the second time.
|
|
150
|
+
2. **Active recall** — end with self-check questions that force retrieval, not recognition:
|
|
151
|
+
- One question for a micro-brief, two-to-three for a standard brief, three-to-five for a dossier.
|
|
152
|
+
- Each question targets a key point from the recap, not a peripheral detail.
|
|
153
|
+
- Phrase so the answer is not leaked: "Quelle est la durée du préavis?" beats "Le préavis est-il
|
|
154
|
+
de trente jours?".
|
|
155
|
+
- After each question mark, insert `…` so the TTS pause gives the listener a beat to answer
|
|
156
|
+
silently, then state the answer in the fewest words possible.
|
|
75
157
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
3. Separate proven facts from uncertainty.
|
|
79
|
-
4. Highlight decisions, risks, deadlines, and missing documents.
|
|
80
|
-
5. End with a concise recap and two or three self-check questions.
|
|
158
|
+
For the full skeleton per format and the active-recall catalogue by intent, see
|
|
159
|
+
`narration-templates.md`.
|
|
81
160
|
|
|
82
|
-
|
|
83
|
-
|
|
161
|
+
Respect the Ragmir evidence separation in spoken form using language cues rather than formatting:
|
|
162
|
+
state proven facts plainly, mark inferences ("Cela suggère que…"), mark uncertainty ("Reste à
|
|
163
|
+
confirmer…"), and name missing documents.
|
|
84
164
|
|
|
85
|
-
##
|
|
165
|
+
## 7. Render The Audio
|
|
86
166
|
|
|
87
167
|
Create the output directory and write the narration to a temp file outside the repo:
|
|
88
168
|
|
|
@@ -140,11 +220,13 @@ Helper engine selection:
|
|
|
140
220
|
|
|
141
221
|
Voice can be selected with `TTS_VOICE`. Speed for Edge can be selected with `TTS_RATE`.
|
|
142
222
|
|
|
143
|
-
##
|
|
223
|
+
## 8. Report The Result
|
|
144
224
|
|
|
145
225
|
After rendering, report:
|
|
146
226
|
|
|
147
227
|
- the audio path;
|
|
228
|
+
- the **format chosen** (micro-brief, brief standard, dossier long) and the **intention served**;
|
|
229
|
+
- the **estimated duration** (`word count / 140`) versus the target budget;
|
|
148
230
|
- which renderer/model was used or requested;
|
|
149
231
|
- whether remote model downloads or online TTS were allowed;
|
|
150
232
|
- any evidence limitation, such as stale index, missing documents, or weak search results.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Listening Style Guide
|
|
2
|
+
|
|
3
|
+
Reference for the narration-writing step of `ragmir-audio-summary`. This file defines how to turn
|
|
4
|
+
retrieved evidence into spoken text that a TTS engine can pronounce and a listener can follow and
|
|
5
|
+
remember in one pass. There is no second chance to re-read audio.
|
|
6
|
+
|
|
7
|
+
## Pacing And Duration
|
|
8
|
+
|
|
9
|
+
- Conversational narration lands around **130-150 words per minute**. Plan on **140 words/minute**
|
|
10
|
+
as the working estimate.
|
|
11
|
+
- Estimated duration = `word count / 140`. Keep a short narration under the target; never pad to
|
|
12
|
+
reach a target.
|
|
13
|
+
- Per-format word budgets (use them as ceilings, not goals):
|
|
14
|
+
|
|
15
|
+
| Format | Target duration | Word budget |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Micro-brief | ~60-90 s | 150-220 words |
|
|
18
|
+
| Brief standard | ~3-5 min | 450-750 words |
|
|
19
|
+
| Dossier long | ~10-20 min | 1500-3000 words |
|
|
20
|
+
|
|
21
|
+
If the relevant material does not fill the budget, stop earlier. Padding makes audio undrinkable.
|
|
22
|
+
|
|
23
|
+
## Sentence Shape
|
|
24
|
+
|
|
25
|
+
- One idea per sentence. If you need "and" twice, split the sentence.
|
|
26
|
+
- Aim for **20 words or fewer** per sentence. A few longer sentences are fine for rhythm; never chain
|
|
27
|
+
three long ones in a row.
|
|
28
|
+
- Prefer subject-verb-object order. TTS engines and the human ear both handle it best.
|
|
29
|
+
- Avoid stacked subordinate clauses and parentheticals. They trip the reader and the listener.
|
|
30
|
+
|
|
31
|
+
Before: "Le contrat, qui avait été signé, malgré des réserves émises tardivement, par les deux
|
|
32
|
+
parties, prévoit une rupture."
|
|
33
|
+
|
|
34
|
+
After: "Les deux parties ont signé le contrat, avec des réserves de dernière minute. Il prévoit
|
|
35
|
+
une rupture."
|
|
36
|
+
|
|
37
|
+
## Punctuation For TTS
|
|
38
|
+
|
|
39
|
+
Punctuation is the only cue a TTS engine has for pausing. Use it deliberately.
|
|
40
|
+
|
|
41
|
+
- **Comma** `,` — short micro-pause. Use it to separate clauses and ease breathing points.
|
|
42
|
+
- **Period** `.` — full pause. End sentences here. Favour periods over commas when in doubt.
|
|
43
|
+
- **Ellipsis** `…` — deliberate longer pause. Use it before the answer in an active-recall question,
|
|
44
|
+
so the listener gets a beat to think (about three seconds).
|
|
45
|
+
- **Colon** `:` — read as a mild pause; acceptable when introducing a short enumeration spoken as
|
|
46
|
+
prose, but prefer rephrasing into a plain sentence.
|
|
47
|
+
- **Semicolon** `;` — avoid. Engines hesitate inconsistently. Split into two sentences.
|
|
48
|
+
- **Exclamation** `!` — avoid for TTS. It can trigger an unnatural spike in pitch.
|
|
49
|
+
- **Question mark** `?` — use it for the active-recall questions; the engine raises intonation
|
|
50
|
+
naturally.
|
|
51
|
+
|
|
52
|
+
## Pronounceability
|
|
53
|
+
|
|
54
|
+
Anything the engine might misread must be rewritten for the ear.
|
|
55
|
+
|
|
56
|
+
- **Acronyms**: expand on first use, then use the short form if it is pronounceable. "Le RGPD, le
|
|
57
|
+
Règlement Général sur la Protection des Données, ..."
|
|
58
|
+
- **Numbers**: write them the way they should be read. "1500" can read as "mille cinq cents" or
|
|
59
|
+
"quinze cents" — write the intended form. For money, spell the currency: "douze mille euros".
|
|
60
|
+
- **Symbols**: rewrite in words. `&` becomes "et", `%` becomes "pour cent", `->` becomes "mène à".
|
|
61
|
+
- **Dates and times**: write them fully. "Le quinze mars deux mille vingt-cinq", not "2025-03-15".
|
|
62
|
+
- **URLs, paths, code**: never read them aloud. Paraphrase: "le fichier de configuration du
|
|
63
|
+
projet" instead of `ragmir/config.json`.
|
|
64
|
+
- **Foreign terms**: if the term has no clean translation, introduce it once and keep it.
|
|
65
|
+
|
|
66
|
+
## Anti-Patterns
|
|
67
|
+
|
|
68
|
+
Avoid these — they are the main causes of "imbuvable" audio.
|
|
69
|
+
|
|
70
|
+
- **Jargon without setup.** If a technical term is needed, define it in one short clause first.
|
|
71
|
+
- **Spoken bullet lists.** Enumerations read aloud are exhausting. Convert lists into flowing
|
|
72
|
+
sentences with signposting ("D'abord…, Ensuite…, Pour finir…"). See `narration-templates.md`.
|
|
73
|
+
- **Meta-commentary.** Drop "Dans ce résumé, nous allons parler de…". Open on the substance.
|
|
74
|
+
- **Padding to reach a duration.** Restating the same idea in more words lowers density and respect
|
|
75
|
+
for the listener. Shorter is better than watered down.
|
|
76
|
+
- **Reading raw source passages.** The audio is a synthesis, not a quote dump. Reformulate in plain
|
|
77
|
+
speech and keep the citation in your working notes, not in the narration.
|
|
78
|
+
- **Overload.** More than ~4 new ideas in a brief is too many to retain. Group, merge, or defer.
|
|
79
|
+
|
|
80
|
+
## Language
|
|
81
|
+
|
|
82
|
+
- Write the narration in the same language passed to `--lang` (`fr` default, `en`, `es`).
|
|
83
|
+
- Match the working language the user used when asking for the summary when it is one of the three
|
|
84
|
+
supported languages.
|
|
85
|
+
- Keep numerals, units, and proper nouns pronounceable in the target language.
|
|
86
|
+
|
|
87
|
+
## Self-Check Before Rendering
|
|
88
|
+
|
|
89
|
+
Read the draft aloud once at a normal pace. If you stumble or run out of breath on a sentence, it is
|
|
90
|
+
too long or too dense. Fix it, then estimate the duration with `word count / 140` and confirm it
|
|
91
|
+
matches the chosen format's budget.
|