@alisio/plugin-semantic 0.0.0-stage → 0.1.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 +21 -0
- package/README.es.md +152 -0
- package/README.md +144 -2
- package/THIRD_PARTY_NOTICES.md +42 -0
- package/assets/architecture.svg +1 -0
- package/assets/ask-flow.svg +1 -0
- package/cover.svg +53 -0
- package/dist/apps.d.ts +26 -0
- package/dist/apps.d.ts.map +1 -0
- package/dist/apps.js +135 -0
- package/dist/apps.js.map +1 -0
- package/dist/embedded.html +2194 -0
- package/dist/engine/download.d.ts +77 -0
- package/dist/engine/download.d.ts.map +1 -0
- package/dist/engine/download.js +213 -0
- package/dist/engine/download.js.map +1 -0
- package/dist/engine/embedder.d.ts +55 -0
- package/dist/engine/embedder.d.ts.map +1 -0
- package/dist/engine/embedder.js +182 -0
- package/dist/engine/embedder.js.map +1 -0
- package/dist/engine/infer.d.ts +22 -0
- package/dist/engine/infer.d.ts.map +1 -0
- package/dist/engine/infer.js +53 -0
- package/dist/engine/infer.js.map +1 -0
- package/dist/engine/models.d.ts +45 -0
- package/dist/engine/models.d.ts.map +1 -0
- package/dist/engine/models.js +132 -0
- package/dist/engine/models.js.map +1 -0
- package/dist/engine/runtime.d.ts +46 -0
- package/dist/engine/runtime.d.ts.map +1 -0
- package/dist/engine/runtime.js +172 -0
- package/dist/engine/runtime.js.map +1 -0
- package/dist/engine/setup.d.ts +82 -0
- package/dist/engine/setup.d.ts.map +1 -0
- package/dist/engine/setup.js +183 -0
- package/dist/engine/setup.js.map +1 -0
- package/dist/engine/store.d.ts +46 -0
- package/dist/engine/store.d.ts.map +1 -0
- package/dist/engine/store.js +280 -0
- package/dist/engine/store.js.map +1 -0
- package/dist/engine/tar.d.ts +18 -0
- package/dist/engine/tar.d.ts.map +1 -0
- package/dist/engine/tar.js +198 -0
- package/dist/engine/tar.js.map +1 -0
- package/dist/engine/worker.d.ts +2 -0
- package/dist/engine/worker.d.ts.map +1 -0
- package/dist/engine/worker.js +64 -0
- package/dist/engine/worker.js.map +1 -0
- package/dist/errors.d.ts +15 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +58 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +258 -0
- package/dist/index.js.map +1 -0
- package/dist/messages.d.ts +53 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +118 -0
- package/dist/messages.js.map +1 -0
- package/dist/notebook/answer.d.ts +33 -0
- package/dist/notebook/answer.d.ts.map +1 -0
- package/dist/notebook/answer.js +77 -0
- package/dist/notebook/answer.js.map +1 -0
- package/dist/notebook/chunk.d.ts +23 -0
- package/dist/notebook/chunk.d.ts.map +1 -0
- package/dist/notebook/chunk.js +124 -0
- package/dist/notebook/chunk.js.map +1 -0
- package/dist/notebook/db.d.ts +98 -0
- package/dist/notebook/db.d.ts.map +1 -0
- package/dist/notebook/db.js +328 -0
- package/dist/notebook/db.js.map +1 -0
- package/dist/notebook/docx.d.ts +3 -0
- package/dist/notebook/docx.d.ts.map +1 -0
- package/dist/notebook/docx.js +16 -0
- package/dist/notebook/docx.js.map +1 -0
- package/dist/notebook/extract.d.ts +11 -0
- package/dist/notebook/extract.d.ts.map +1 -0
- package/dist/notebook/extract.js +99 -0
- package/dist/notebook/extract.js.map +1 -0
- package/dist/notebook/jobs.d.ts +31 -0
- package/dist/notebook/jobs.d.ts.map +1 -0
- package/dist/notebook/jobs.js +84 -0
- package/dist/notebook/jobs.js.map +1 -0
- package/dist/notebook/ooxml.d.ts +6 -0
- package/dist/notebook/ooxml.d.ts.map +1 -0
- package/dist/notebook/ooxml.js +131 -0
- package/dist/notebook/ooxml.js.map +1 -0
- package/dist/notebook/retrieve.d.ts +14 -0
- package/dist/notebook/retrieve.d.ts.map +1 -0
- package/dist/notebook/retrieve.js +37 -0
- package/dist/notebook/retrieve.js.map +1 -0
- package/dist/notebook/service.d.ts +72 -0
- package/dist/notebook/service.d.ts.map +1 -0
- package/dist/notebook/service.js +620 -0
- package/dist/notebook/service.js.map +1 -0
- package/dist/notebook/workspace.d.ts +17 -0
- package/dist/notebook/workspace.d.ts.map +1 -0
- package/dist/notebook/workspace.js +75 -0
- package/dist/notebook/workspace.js.map +1 -0
- package/dist/notebook/zip.d.ts +33 -0
- package/dist/notebook/zip.d.ts.map +1 -0
- package/dist/notebook/zip.js +154 -0
- package/dist/notebook/zip.js.map +1 -0
- package/dist/paths.d.ts +17 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +28 -0
- package/dist/paths.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +3 -0
- package/dist/version.js.map +1 -0
- package/icon.svg +16 -0
- package/package.json +62 -3
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// .pptx and .xlsx text (owner O10). Reads only XML parts reached through the package's own
|
|
2
|
+
// relationships; never formulas (cached values only), macros, external links or embedded objects.
|
|
3
|
+
import { SemanticPluginError } from "../errors.js";
|
|
4
|
+
import { attributes, decodeXml, OFFICE_LIMITS, relationships, resolvePart, ZipArchive, } from "./zip.js";
|
|
5
|
+
/** Same rule as any source (§7.2): more extracted text than this is `limit_exceeded`. */
|
|
6
|
+
const MAX_CHARS = 2_000_000;
|
|
7
|
+
const MAX_CELLS = 2_000_000;
|
|
8
|
+
const bad = () => {
|
|
9
|
+
throw new SemanticPluginError("zip_invalid");
|
|
10
|
+
};
|
|
11
|
+
const folderOf = (part) => part.slice(0, part.lastIndexOf("/") + 1);
|
|
12
|
+
const relsOf = (part) => `${folderOf(part)}_rels/${part.slice(part.lastIndexOf("/") + 1)}.rels`;
|
|
13
|
+
function budget() {
|
|
14
|
+
let used = 0;
|
|
15
|
+
return (text) => {
|
|
16
|
+
used += text.length;
|
|
17
|
+
if (used > MAX_CHARS)
|
|
18
|
+
throw new SemanticPluginError("limit_exceeded");
|
|
19
|
+
return text;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/** Text of `<a:p>` paragraphs (`<a:t>` runs, `<a:br/>` breaks); slide-number fields are skipped. */
|
|
23
|
+
function drawingParagraphs(xml) {
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const match of xml.matchAll(/<a:p[\s>][\s\S]*?<\/a:p>/g)) {
|
|
26
|
+
const body = match[0].replace(/<a:fld\b[^>]*type="slidenum"[\s\S]*?<\/a:fld>/g, "");
|
|
27
|
+
let text = "";
|
|
28
|
+
for (const token of body.matchAll(/<a:t(?:\s[^>]*)?>([\s\S]*?)<\/a:t>|<a:br\b[^>]*\/>/g))
|
|
29
|
+
text += token[1] !== undefined ? decodeXml(token[1]) : "\n";
|
|
30
|
+
if (text.trim())
|
|
31
|
+
out.push(text.trim());
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
/** One segment per slide, in presentation order; notes follow the slide text after a blank line. */
|
|
36
|
+
export function pptxSegments(bytes) {
|
|
37
|
+
const zip = new ZipArchive(bytes, OFFICE_LIMITS);
|
|
38
|
+
const presentation = zip.xml("ppt/presentation.xml");
|
|
39
|
+
const rels = relationships(zip.xml("ppt/_rels/presentation.xml.rels"));
|
|
40
|
+
const take = budget();
|
|
41
|
+
const segments = [];
|
|
42
|
+
for (const match of presentation.matchAll(/<p:sldId\b([^>]*)\/?>/g)) {
|
|
43
|
+
const id = attributes(match[1])["r:id"];
|
|
44
|
+
const rel = id ? rels.get(id) : undefined;
|
|
45
|
+
if (!rel || !/\/slide$/.test(rel.type))
|
|
46
|
+
continue;
|
|
47
|
+
const part = resolvePart("ppt/", rel.target);
|
|
48
|
+
if (!part.startsWith("ppt/"))
|
|
49
|
+
bad();
|
|
50
|
+
const slideXml = zip.xml(part);
|
|
51
|
+
const blocks = [drawingParagraphs(slideXml).join("\n")];
|
|
52
|
+
const slideRels = zip.has(relsOf(part)) ? relationships(zip.xml(relsOf(part))) : new Map();
|
|
53
|
+
for (const r of slideRels.values())
|
|
54
|
+
if (/\/notesSlide$/.test(r.type)) {
|
|
55
|
+
const notesPart = resolvePart(folderOf(part), r.target);
|
|
56
|
+
if (zip.has(notesPart))
|
|
57
|
+
blocks.push(drawingParagraphs(zip.xml(notesPart)).join("\n"));
|
|
58
|
+
}
|
|
59
|
+
segments.push({ text: take(blocks.filter(Boolean).join("\n\n")), page: segments.length + 1 });
|
|
60
|
+
}
|
|
61
|
+
if (segments.length === 0)
|
|
62
|
+
bad();
|
|
63
|
+
return segments;
|
|
64
|
+
}
|
|
65
|
+
const columnIndex = (ref) => {
|
|
66
|
+
const letters = /^[A-Z]+/.exec(ref)?.[0] ?? "";
|
|
67
|
+
let n = 0;
|
|
68
|
+
for (const c of letters)
|
|
69
|
+
n = n * 26 + (c.charCodeAt(0) - 64);
|
|
70
|
+
return n - 1;
|
|
71
|
+
};
|
|
72
|
+
/** Text of every `<t>` in a string item, without phonetic runs. */
|
|
73
|
+
const itemText = (xml) => [...xml.replace(/<rPh\b[\s\S]*?<\/rPh>/g, "").matchAll(/<t(?:\s[^>]*)?>([\s\S]*?)<\/t>/g)]
|
|
74
|
+
.map((m) => decodeXml(m[1]))
|
|
75
|
+
.join("");
|
|
76
|
+
/** One segment per sheet, in workbook order: "Sheet: <name>" then tab-separated rows. */
|
|
77
|
+
export function xlsxSegments(bytes) {
|
|
78
|
+
const zip = new ZipArchive(bytes, OFFICE_LIMITS);
|
|
79
|
+
const workbook = zip.xml("xl/workbook.xml");
|
|
80
|
+
const rels = relationships(zip.xml("xl/_rels/workbook.xml.rels"));
|
|
81
|
+
const shared = zip.has("xl/sharedStrings.xml")
|
|
82
|
+
? [...zip.xml("xl/sharedStrings.xml").matchAll(/<si>([\s\S]*?)<\/si>/g)].map((m) => itemText(m[1]))
|
|
83
|
+
: [];
|
|
84
|
+
const take = budget();
|
|
85
|
+
let cells = 0;
|
|
86
|
+
const segments = [];
|
|
87
|
+
for (const match of workbook.matchAll(/<sheet\b([^>]*)\/?>/g)) {
|
|
88
|
+
const attrs = attributes(match[1]);
|
|
89
|
+
const rel = attrs["r:id"] ? rels.get(attrs["r:id"]) : undefined;
|
|
90
|
+
if (!rel || !/\/worksheet$/.test(rel.type))
|
|
91
|
+
continue;
|
|
92
|
+
const part = resolvePart("xl/", rel.target);
|
|
93
|
+
if (!part.startsWith("xl/"))
|
|
94
|
+
bad();
|
|
95
|
+
const lines = [take(`Sheet: ${attrs.name ?? ""}`)];
|
|
96
|
+
for (const row of zip.xml(part).matchAll(/<row\b[^>]*>([\s\S]*?)<\/row>/g)) {
|
|
97
|
+
const values = [];
|
|
98
|
+
for (const cell of row[1].matchAll(/<c\b([^>]*?)(?:\/>|>([\s\S]*?)<\/c>)/g)) {
|
|
99
|
+
if (++cells > MAX_CELLS)
|
|
100
|
+
throw new SemanticPluginError("limit_exceeded");
|
|
101
|
+
const a = attributes(cell[1]);
|
|
102
|
+
const body = cell[2] ?? "";
|
|
103
|
+
const raw = /<v>([\s\S]*?)<\/v>/.exec(body)?.[1];
|
|
104
|
+
let value;
|
|
105
|
+
if (a.t === "inlineStr")
|
|
106
|
+
value = itemText(/<is>([\s\S]*?)<\/is>/.exec(body)?.[1] ?? "");
|
|
107
|
+
else if (raw === undefined)
|
|
108
|
+
value = undefined;
|
|
109
|
+
else if (a.t === "s")
|
|
110
|
+
value = shared[Number(raw)] ?? "";
|
|
111
|
+
else if (a.t === "b")
|
|
112
|
+
value = raw.trim() === "1" ? "TRUE" : "FALSE";
|
|
113
|
+
else
|
|
114
|
+
value = decodeXml(raw); // numbers as written, cached formula results, errors
|
|
115
|
+
if (value === undefined || value === "")
|
|
116
|
+
continue;
|
|
117
|
+
const col = a.r ? columnIndex(a.r) : values.length;
|
|
118
|
+
while (values.length < col)
|
|
119
|
+
values.push("");
|
|
120
|
+
values[col] = value.replace(/[\t\r\n]+/g, " ");
|
|
121
|
+
}
|
|
122
|
+
if (values.some((v) => v))
|
|
123
|
+
lines.push(take(values.join("\t")));
|
|
124
|
+
}
|
|
125
|
+
segments.push({ text: lines.join("\n"), page: segments.length + 1 });
|
|
126
|
+
}
|
|
127
|
+
if (segments.length === 0)
|
|
128
|
+
bad();
|
|
129
|
+
return segments;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=ooxml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ooxml.js","sourceRoot":"","sources":["../../src/notebook/ooxml.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const RRF_K = 60;
|
|
2
|
+
export declare const RETRIEVE_EACH = 20;
|
|
3
|
+
export declare const RETRIEVE_KEEP = 8;
|
|
4
|
+
/**
|
|
5
|
+
* Sum of `1 / (k + rank)` over the lists an id appears in (1-based rank, first occurrence per
|
|
6
|
+
* list). Ties keep first-seen order (list order, then rank), so the fusion is deterministic.
|
|
7
|
+
*/
|
|
8
|
+
export declare function reciprocalRankFusion(lists: string[][], options?: {
|
|
9
|
+
k?: number;
|
|
10
|
+
top?: number;
|
|
11
|
+
}): string[];
|
|
12
|
+
/** A safe FTS5 MATCH expression: every word quoted, joined by OR (operators become words). */
|
|
13
|
+
export declare function ftsQuery(text: string): string;
|
|
14
|
+
//# sourceMappingURL=retrieve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieve.d.ts","sourceRoot":"","sources":["../../src/notebook/retrieve.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,KAAK,KAAK,CAAC;AACxB,eAAO,MAAM,aAAa,KAAK,CAAC;AAChC,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,EAAE,EAAE,EACjB,OAAO,GAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GACzC,MAAM,EAAE,CAkBV;AAED,8FAA8F;AAC9F,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM7C"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Hybrid retrieval (D9): vector top 20 + FTS5 BM25 top 20, fused with Reciprocal Rank Fusion.
|
|
2
|
+
export const RRF_K = 60;
|
|
3
|
+
export const RETRIEVE_EACH = 20;
|
|
4
|
+
export const RETRIEVE_KEEP = 8;
|
|
5
|
+
/**
|
|
6
|
+
* Sum of `1 / (k + rank)` over the lists an id appears in (1-based rank, first occurrence per
|
|
7
|
+
* list). Ties keep first-seen order (list order, then rank), so the fusion is deterministic.
|
|
8
|
+
*/
|
|
9
|
+
export function reciprocalRankFusion(lists, options = {}) {
|
|
10
|
+
const k = options.k ?? RRF_K;
|
|
11
|
+
const scores = new Map();
|
|
12
|
+
let seen = 0;
|
|
13
|
+
for (const list of lists) {
|
|
14
|
+
const counted = new Set();
|
|
15
|
+
list.forEach((id, index) => {
|
|
16
|
+
if (counted.has(id))
|
|
17
|
+
return;
|
|
18
|
+
counted.add(id);
|
|
19
|
+
const entry = scores.get(id) ?? { score: 0, seen: seen++ };
|
|
20
|
+
entry.score += 1 / (k + index + 1);
|
|
21
|
+
scores.set(id, entry);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return [...scores.entries()]
|
|
25
|
+
.sort((a, b) => b[1].score - a[1].score || a[1].seen - b[1].seen)
|
|
26
|
+
.slice(0, options.top ?? RETRIEVE_KEEP)
|
|
27
|
+
.map(([id]) => id);
|
|
28
|
+
}
|
|
29
|
+
/** A safe FTS5 MATCH expression: every word quoted, joined by OR (operators become words). */
|
|
30
|
+
export function ftsQuery(text) {
|
|
31
|
+
const words = text.match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
32
|
+
return words
|
|
33
|
+
.slice(0, 64)
|
|
34
|
+
.map((word) => `"${word}"`)
|
|
35
|
+
.join(" OR ");
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=retrieve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retrieve.js","sourceRoot":"","sources":["../../src/notebook/retrieve.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F,MAAM,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;AACxB,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAC;AAChC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,KAAiB,EACjB,OAAO,GAAiC,EAAE;IAE1C,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC;IAC7B,MAAM,MAAM,GAAG,IAAI,GAAG,EAA2C,CAAC;IAClE,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAClC,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE;YACzB,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAAE,OAAO;YAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC;YAC3D,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;SACzB,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;SAChE,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI,aAAa,CAAC;SACtC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;AACvB,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;IAClD,OAAO,KAAK;SACT,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;SACZ,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC;SAC1B,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { CompletionRequest, ToolSemantic } from "@alisio/sdk";
|
|
2
|
+
import { type Passage } from "./answer.js";
|
|
3
|
+
import type { NotebookDb } from "./db.js";
|
|
4
|
+
export declare const LIMITS: {
|
|
5
|
+
readonly sourcesPerNotebook: 50;
|
|
6
|
+
readonly charsPerSource: 2000000;
|
|
7
|
+
readonly chunksPerNotebook: 20000;
|
|
8
|
+
readonly questionChars: 4000;
|
|
9
|
+
readonly titleChars: 200;
|
|
10
|
+
readonly fileBytes: number;
|
|
11
|
+
readonly historyMessages: 50;
|
|
12
|
+
readonly indexBatch: 64;
|
|
13
|
+
};
|
|
14
|
+
export interface ActionContext {
|
|
15
|
+
sessionId: string;
|
|
16
|
+
workspace: string;
|
|
17
|
+
signal: AbortSignal;
|
|
18
|
+
idempotencyKey?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ServiceDeps {
|
|
21
|
+
db: NotebookDb;
|
|
22
|
+
/** The consumer side of `api.semantic` (absent on an older host). */
|
|
23
|
+
semantic: () => ToolSemantic | undefined;
|
|
24
|
+
complete: (request: CompletionRequest) => Promise<string>;
|
|
25
|
+
}
|
|
26
|
+
/** 12 lowercase base32 characters (D16). */
|
|
27
|
+
export declare function newId(): string;
|
|
28
|
+
export declare const collectionOf: (notebookId: string) => string;
|
|
29
|
+
type Input = Record<string, unknown>;
|
|
30
|
+
/** The Notebook app's actions, testable without a host (§7.7). */
|
|
31
|
+
export declare class NotebookService {
|
|
32
|
+
readonly db: NotebookDb;
|
|
33
|
+
private readonly deps;
|
|
34
|
+
private readonly jobs;
|
|
35
|
+
private readonly idempotent;
|
|
36
|
+
constructor(deps: ServiceDeps);
|
|
37
|
+
busy(): boolean;
|
|
38
|
+
dispose(): void;
|
|
39
|
+
idle(): Promise<void>;
|
|
40
|
+
private semantic;
|
|
41
|
+
invoke(action: string, input: Input, ctx: ActionContext): Promise<unknown>;
|
|
42
|
+
private notebook;
|
|
43
|
+
private source;
|
|
44
|
+
private dispatch;
|
|
45
|
+
/** How the frame labels `page`: a PDF page, a slide, or a sheet with its name (O10). */
|
|
46
|
+
private pageLabel;
|
|
47
|
+
private checkSourceLimit;
|
|
48
|
+
private upload;
|
|
49
|
+
private addFromWorkspace;
|
|
50
|
+
private addSource;
|
|
51
|
+
/** Embeds a source's stored chunks (D10: text lives in SQLite, `keepText: false`). */
|
|
52
|
+
private indexSource;
|
|
53
|
+
private removeVectors;
|
|
54
|
+
private rebuild;
|
|
55
|
+
/** Hybrid retrieval (D9): vector + FTS5, RRF, top 8; keyword-only when vectors are unavailable. */
|
|
56
|
+
retrieve(notebookId: string, query: string, options: {
|
|
57
|
+
sourceIds?: string[] | undefined;
|
|
58
|
+
signal: AbortSignal;
|
|
59
|
+
keep?: number;
|
|
60
|
+
}): Promise<{
|
|
61
|
+
passages: Passage[];
|
|
62
|
+
keywordOnly: boolean;
|
|
63
|
+
}>;
|
|
64
|
+
private ask;
|
|
65
|
+
/** Round-robin first passages of each source: an overview needs breadth, not one query. */
|
|
66
|
+
private overviewPassages;
|
|
67
|
+
private completeWith;
|
|
68
|
+
private guide;
|
|
69
|
+
private summary;
|
|
70
|
+
}
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/notebook/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEnE,OAAO,EAAyC,KAAK,OAAO,EAAkB,MAAM,aAAa,CAAC;AAElG,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,SAAS,CAAC;AAMrD,eAAO,MAAM,MAAM;aACjB,kBAAkB,EAAE,EAAE;aACtB,cAAc,EAAE,OAAS;aACzB,iBAAiB,EAAE,KAAM;aACzB,aAAa,EAAE,IAAI;aACnB,UAAU,EAAE,GAAG;aACf,SAAS;aACT,eAAe,EAAE,EAAE;aACnB,UAAU,EAAE,EAAE;CACN,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,UAAU,CAAC;IACf,qEAAqE;IACrE,QAAQ,EAAE,MAAM,YAAY,GAAG,SAAS,CAAC;IACzC,QAAQ,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CAC3D;AAaD,4CAA4C;AAC5C,wBAAgB,KAAK,IAAI,MAAM,CAK9B;AACD,eAAO,MAAM,YAAY,eAAgB,MAAM,WAAuB,CAAC;AAMvE,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA4BrC,kEAAkE;AAClE,qBAAa,eAAe;IAC1B,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAc;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAY;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA8B;IAEzD,YAAY,IAAI,EAAE,WAAW,EAI5B;IAED,IAAI,YAEH;IAED,OAAO,SAEN;IAED,IAAI,kBAEH;IAED,OAAO,CAAC,QAAQ;IASV,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAa/E;IAED,OAAO,CAAC,QAAQ;IAMhB,OAAO,CAAC,MAAM;YAMA,QAAQ;IAqHtB,wFAAwF;IACxF,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,MAAM;YAkCA,gBAAgB;IAgB9B,OAAO,CAAC,SAAS;IA6DjB,sFAAsF;YACxE,WAAW;YAqCX,aAAa;IAQ3B,OAAO,CAAC,OAAO;IAqBf,mGAAmG;IAC7F,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAAC,MAAM,EAAE,WAAW,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAChF,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAAC,CA6CxD;IAED,OAAO,CAAC,GAAG;IAkDX,2FAA2F;IAC3F,OAAO,CAAC,gBAAgB;YA8BV,YAAY;IAqB1B,OAAO,CAAC,KAAK;IA6Bb,OAAO,CAAC,OAAO;CAmBhB"}
|