@bendyline/docblocks-react 2.7.5 → 2.7.7

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.
Files changed (29) hide show
  1. package/THIRD_PARTY_NOTICES.txt +26 -26
  2. package/dist/{AiDiagrams-5P657GFC.js → AiDiagrams-7KBAOXPB.js} +4 -2
  3. package/dist/{AiEditorAssistant-V4MZRC6Q.js → AiEditorAssistant-4B2PFFOT.js} +128 -12
  4. package/dist/{AiStudyDialog-GSCFTG3G.js → AiStudyDialog-JPVFFZBB.js} +14 -4
  5. package/dist/{AudioExportDialog-IOYIEAER.js → AudioExportDialog-EICCBSSE.js} +1 -1
  6. package/dist/{ExportDialog-LGWBXIWN.js → ExportDialog-EYDGTJ3S.js} +1 -1
  7. package/dist/{ExportToolbarControls-HOV424TO.js → ExportToolbarControls-2XY2CKGH.js} +45 -4
  8. package/dist/{PresentationMaker-H5B44Q7P.js → PresentationMaker-VYQKNL3L.js} +2 -2
  9. package/dist/{SpeechToolbarControl-KNI2C4JJ.js → SpeechToolbarControl-E6OSJGHL.js} +217 -71
  10. package/dist/{TextFromNarration-EYOMW2IW.js → TextFromNarration-ME6FAYWO.js} +1 -1
  11. package/dist/{WorkspaceSearchPanel-J6BKEZQJ.js → WorkspaceSearchPanel-MEBBTK7F.js} +3 -3
  12. package/dist/{chunk-I44HKDQX.js → chunk-3TSJQESW.js} +16 -3
  13. package/dist/chunk-5OIHB3SR.js +1162 -0
  14. package/dist/chunk-6QHZNL6C.js +208 -0
  15. package/dist/{chunk-FBPCURCS.js → chunk-7HBKKXRV.js} +291 -82
  16. package/dist/{chunk-KBDZDFPU.js → chunk-BNKIPCXO.js} +4 -1
  17. package/dist/{chunk-2IYBBFQX.js → chunk-BZRYQENB.js} +59 -16
  18. package/dist/{chunk-GFK4TCKN.js → chunk-G63YXKBC.js} +8 -5
  19. package/dist/{chunk-DICE7VBJ.js → chunk-KHQ44ZFA.js} +16 -1
  20. package/dist/{chunk-CUCWCZRO.js → chunk-N7AKLJPY.js} +143 -98
  21. package/dist/{chunk-USKX66SA.js → chunk-T2PA7QEF.js} +1 -1
  22. package/dist/editor.js +2 -2
  23. package/dist/export/index.js +1 -1
  24. package/dist/index.js +232 -134
  25. package/dist/settings/index.js +2 -1
  26. package/package.json +8 -8
  27. package/src/styles/docblocks.css +547 -11
  28. package/dist/chunk-I4JURPYS.js +0 -812
  29. package/dist/{QuickOpenDialog-ENVFGIHS.js → QuickOpenDialog-3QEX7RZG.js} +3 -3
@@ -0,0 +1,208 @@
1
+ import {
2
+ KnowledgeIcon,
3
+ SourcedFactsIcon,
4
+ UnsourcedFactsIcon
5
+ } from "./chunk-KHQ44ZFA.js";
6
+
7
+ // src/Ai/AiKnowledgeIndicator.tsx
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ var QUIET_NOTES = {
10
+ none: "Your knowledge catalogs were searched, and nothing in them matched this request.",
11
+ skipped: "Your knowledge catalogs could not be searched for this request. A long document can leave no room for reference passages."
12
+ };
13
+ function AiKnowledgeIndicator({ knowledge }) {
14
+ if (!knowledge) return null;
15
+ if (knowledge.outcome !== "used") {
16
+ return /* @__PURE__ */ jsxs("details", { className: "db-ai-knowledge db-ai-knowledge--quiet", children: [
17
+ /* @__PURE__ */ jsxs("summary", { children: [
18
+ /* @__PURE__ */ jsx(KnowledgeIcon, {}),
19
+ knowledge.outcome === "none" ? "No matching knowledge" : "Knowledge not searched"
20
+ ] }),
21
+ /* @__PURE__ */ jsx("p", { children: QUIET_NOTES[knowledge.outcome] })
22
+ ] });
23
+ }
24
+ const several = knowledge.sources.length > 1;
25
+ const count = knowledge.sources.reduce((sum, source) => sum + source.titles.length, 0);
26
+ return /* @__PURE__ */ jsxs("details", { className: "db-ai-knowledge db-ai-knowledge--used", children: [
27
+ /* @__PURE__ */ jsxs("summary", { children: [
28
+ /* @__PURE__ */ jsx(KnowledgeIcon, {}),
29
+ /* @__PURE__ */ jsxs("span", { className: "db-ai-knowledge-names", children: [
30
+ "Knowledge: ",
31
+ knowledge.sources.map((source) => source.name).join(", ")
32
+ ] }),
33
+ count > 0 && /* @__PURE__ */ jsxs("span", { className: "db-ai-knowledge-count", children: [
34
+ " ",
35
+ "\xB7 ",
36
+ count,
37
+ " ",
38
+ count === 1 ? "article" : "articles"
39
+ ] })
40
+ ] }),
41
+ /* @__PURE__ */ jsx("p", { children: "Passages from these articles were given to the model as reference material:" }),
42
+ knowledge.sources.map((source) => /* @__PURE__ */ jsxs("div", { className: "db-ai-knowledge-source", children: [
43
+ several && /* @__PURE__ */ jsx("p", { className: "db-ai-knowledge-catalog", children: source.name }),
44
+ /* @__PURE__ */ jsx("ul", { children: source.titles.map((title) => /* @__PURE__ */ jsx("li", { children: title }, title)) })
45
+ ] }, source.catalogId))
46
+ ] });
47
+ }
48
+ function markDetails(text, details) {
49
+ const terms = details.map((detail) => detail.replace(/ next to .+$/u, "")).filter(Boolean).map((detail) => detail.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&")).sort((a, b) => b.length - a.length);
50
+ if (terms.length === 0) return [text];
51
+ const pattern = new RegExp(
52
+ `(?<![\\p{L}\\p{N}])(${terms.join("|")})(?=(?:st|nd|rd|th)?(?![\\p{L}\\p{N}]))`,
53
+ "giu"
54
+ );
55
+ return text.split(pattern).map((part, index) => index % 2 === 1 ? /* @__PURE__ */ jsx("mark", { children: part }, index) : part);
56
+ }
57
+ function AiFactsIndicator({ check }) {
58
+ if (!check || check.checked === 0) return null;
59
+ if (check.unsourced.length === 0) {
60
+ return /* @__PURE__ */ jsxs("details", { className: "db-ai-knowledge db-ai-knowledge--quiet db-ai-facts--sourced", children: [
61
+ /* @__PURE__ */ jsxs("summary", { children: [
62
+ /* @__PURE__ */ jsx(SourcedFactsIcon, {}),
63
+ "Details found in sources"
64
+ ] }),
65
+ /* @__PURE__ */ jsx("p", { children: "Every name, date, number and quotation in the draft appears in your document, your instructions or the reference passages. The check cannot tell whether a source is right." })
66
+ ] });
67
+ }
68
+ const count = check.unsourced.length;
69
+ return /* @__PURE__ */ jsxs("details", { className: "db-ai-knowledge db-ai-facts", children: [
70
+ /* @__PURE__ */ jsxs("summary", { children: [
71
+ /* @__PURE__ */ jsx(UnsourcedFactsIcon, {}),
72
+ count,
73
+ " ",
74
+ count === 1 ? "statement" : "statements",
75
+ " to check"
76
+ ] }),
77
+ /* @__PURE__ */ jsx("p", { children: "Neither your document, your instructions nor the reference passages show the marked details. The model may have written them from memory." }),
78
+ /* @__PURE__ */ jsx("ul", { children: check.unsourced.map((sentence, index) => /* @__PURE__ */ jsx("li", { children: sentence.problem === "bad-citation" ? /* @__PURE__ */ jsxs(Fragment, { children: [
79
+ sentence.text,
80
+ " ",
81
+ /* @__PURE__ */ jsxs("span", { className: "db-ai-facts-note", children: [
82
+ "It cites ",
83
+ sentence.missing.join(", "),
84
+ ", which is not one of the reference passages."
85
+ ] })
86
+ ] }) : markDetails(sentence.text, sentence.missing) }, index)) })
87
+ ] });
88
+ }
89
+
90
+ // src/Ai/ai-knowledge.ts
91
+ import { useEffect, useMemo, useRef, useState } from "react";
92
+ import { AI_WIRE_LIMITS } from "@bendyline/docblocks/host";
93
+ function mergeAiKnowledge(current, next) {
94
+ if (!current) return next;
95
+ if (current.outcome !== "used" || next.outcome !== "used") {
96
+ if (current.outcome === "used") return current;
97
+ if (next.outcome === "used") return next;
98
+ return current.outcome === "none" ? current : next;
99
+ }
100
+ const sources = current.sources.map((source) => ({ ...source, titles: [...source.titles] }));
101
+ for (const source of next.sources) {
102
+ const existing = sources.find((entry) => entry.catalogId === source.catalogId);
103
+ if (!existing) {
104
+ sources.push({ ...source, titles: [...source.titles] });
105
+ continue;
106
+ }
107
+ for (const title of source.titles) {
108
+ if (!existing.titles.includes(title)) existing.titles.push(title);
109
+ }
110
+ }
111
+ const evidence = [...current.evidence];
112
+ for (const passage of next.evidence) {
113
+ if (!evidence.some((known) => known.text === passage.text)) evidence.push(passage);
114
+ }
115
+ return { outcome: "used", sources, evidence };
116
+ }
117
+ function sameEvidence(a, b) {
118
+ return a.length === b.length && a.every((passage, index) => passage.text === b[index]?.text);
119
+ }
120
+ function numberingHolds(current, next) {
121
+ return current?.outcome !== "used" || next.outcome !== "used" || sameEvidence(current.evidence, next.evidence);
122
+ }
123
+ function useAiKnowledge(ai) {
124
+ const [run, setRun] = useState({
125
+ knowledge: null,
126
+ citable: true
127
+ });
128
+ const runRef = useRef(0);
129
+ const helpers = useMemo(() => {
130
+ const tapped = {
131
+ chat(request, onEvent) {
132
+ const started = runRef.current;
133
+ return ai.chat(request, (event) => {
134
+ if (event.kind === "knowledge" && started === runRef.current) {
135
+ setRun((current) => ({
136
+ knowledge: mergeAiKnowledge(current.knowledge, event.knowledge),
137
+ citable: current.citable && numberingHolds(current.knowledge, event.knowledge)
138
+ }));
139
+ }
140
+ onEvent(event);
141
+ });
142
+ }
143
+ };
144
+ const reset = () => {
145
+ runRef.current += 1;
146
+ setRun({ knowledge: null, citable: true });
147
+ };
148
+ return { ai: tapped, reset };
149
+ }, [ai]);
150
+ return { knowledge: run.knowledge, citable: run.citable, ...helpers };
151
+ }
152
+ function factCheckRequest(text, knowledge, given, citable) {
153
+ if (text.length > AI_WIRE_LIMITS.factCheckTextCharacters) return null;
154
+ const evidence = [];
155
+ let total = 0;
156
+ for (const passage of knowledge?.outcome === "used" ? knowledge.evidence : []) {
157
+ total += passage.text.length;
158
+ if (evidence.length >= AI_WIRE_LIMITS.factCheckEvidence || total > AI_WIRE_LIMITS.factCheckEvidenceCharacters) {
159
+ break;
160
+ }
161
+ evidence.push(passage.text);
162
+ }
163
+ return {
164
+ text,
165
+ evidence,
166
+ given: given.slice(0, AI_WIRE_LIMITS.factCheckGivenCharacters),
167
+ // Passages were numbered for citing only when there were passages.
168
+ citations: citable && evidence.length > 0
169
+ };
170
+ }
171
+ function factsNeedReview(check) {
172
+ return check.unsourced.some((sentence) => sentence.strong) || check.unsourced.length >= 3;
173
+ }
174
+ function useFactCheck(ai, text, knowledge, given, citable) {
175
+ const [result, setResult] = useState(null);
176
+ useEffect(() => {
177
+ const request = text?.trim() && ai.checkFacts ? factCheckRequest(text, knowledge, given, citable) : null;
178
+ if (!request) {
179
+ setResult(null);
180
+ return;
181
+ }
182
+ let live = true;
183
+ const timer = setTimeout(() => {
184
+ ai.checkFacts?.(request).then(
185
+ (checked) => {
186
+ if (live) setResult(checked.ok ? checked.value : null);
187
+ },
188
+ () => {
189
+ if (live) setResult(null);
190
+ }
191
+ );
192
+ }, 400);
193
+ return () => {
194
+ live = false;
195
+ clearTimeout(timer);
196
+ };
197
+ }, [ai, text, knowledge, given, citable]);
198
+ return result;
199
+ }
200
+
201
+ export {
202
+ AiKnowledgeIndicator,
203
+ AiFactsIndicator,
204
+ useAiKnowledge,
205
+ factCheckRequest,
206
+ factsNeedReview,
207
+ useFactCheck
208
+ };