@bitbaum/chatkit 0.2.1
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.md +132 -0
- package/dist/attachments.d.ts +72 -0
- package/dist/attachments.d.ts.map +1 -0
- package/dist/attachments.js +64 -0
- package/dist/attachments.js.map +1 -0
- package/dist/composer.d.ts +34 -0
- package/dist/composer.d.ts.map +1 -0
- package/dist/composer.js +41 -0
- package/dist/composer.js.map +1 -0
- package/dist/dictation.d.ts +60 -0
- package/dist/dictation.d.ts.map +1 -0
- package/dist/dictation.js +93 -0
- package/dist/dictation.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +64 -0
- package/dist/markdown.d.ts.map +1 -0
- package/dist/markdown.js +129 -0
- package/dist/markdown.js.map +1 -0
- package/dist/react/Composer.d.ts +85 -0
- package/dist/react/Composer.d.ts.map +1 -0
- package/dist/react/Composer.js +132 -0
- package/dist/react/Composer.js.map +1 -0
- package/dist/react/Markdown.d.ts +27 -0
- package/dist/react/Markdown.d.ts.map +1 -0
- package/dist/react/Markdown.js +62 -0
- package/dist/react/Markdown.js.map +1 -0
- package/dist/react/Thread.d.ts +90 -0
- package/dist/react/Thread.d.ts.map +1 -0
- package/dist/react/Thread.js +64 -0
- package/dist/react/Thread.js.map +1 -0
- package/dist/react/hooks.d.ts +40 -0
- package/dist/react/hooks.d.ts.map +1 -0
- package/dist/react/hooks.js +99 -0
- package/dist/react/hooks.js.map +1 -0
- package/dist/react/icons.d.ts +12 -0
- package/dist/react/icons.d.ts.map +1 -0
- package/dist/react/icons.js +21 -0
- package/dist/react/icons.js.map +1 -0
- package/dist/react/index.d.ts +21 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +16 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/use-attachments.d.ts +26 -0
- package/dist/react/use-attachments.d.ts.map +1 -0
- package/dist/react/use-attachments.js +202 -0
- package/dist/react/use-attachments.js.map +1 -0
- package/dist/react/use-dictation.d.ts +49 -0
- package/dist/react/use-dictation.d.ts.map +1 -0
- package/dist/react/use-dictation.js +365 -0
- package/dist/react/use-dictation.js.map +1 -0
- package/dist/scroll.d.ts +13 -0
- package/dist/scroll.d.ts.map +1 -0
- package/dist/scroll.js +11 -0
- package/dist/scroll.js.map +1 -0
- package/package.json +83 -0
- package/styles.css +689 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAkDzD;AAED,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAI9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAKpC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,CA2BtD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYpD;AAED,0EAA0E;AAC1E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEpD"}
|
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The markdown an LLM actually writes, parsed into blocks and inline spans —
|
|
3
|
+
* no dependency, no HTML string, nothing to sanitise because nothing is ever
|
|
4
|
+
* rendered as HTML.
|
|
5
|
+
*
|
|
6
|
+
* From loki's `MarkdownText`, the one renderer in the fleet that four repos
|
|
7
|
+
* did NOT have: those rendered model output with the literal `**` still in it.
|
|
8
|
+
* Supports what answers use — paragraphs, bullet and numbered lists, headings,
|
|
9
|
+
* **bold**, *italic*, `code`, fenced code, [links](url) and `[F1]` citation
|
|
10
|
+
* handles — and deliberately nothing else.
|
|
11
|
+
*/
|
|
12
|
+
export function parseBlocks(text) {
|
|
13
|
+
const blocks = [];
|
|
14
|
+
let list = null;
|
|
15
|
+
const lines = text.split(/\r?\n/);
|
|
16
|
+
for (let i = 0; i < lines.length; i++) {
|
|
17
|
+
const raw = lines[i] ?? "";
|
|
18
|
+
const line = raw.trim();
|
|
19
|
+
// ``` fenced code — verbatim until the closing fence (or the end, while
|
|
20
|
+
// it is still streaming in).
|
|
21
|
+
if (line.startsWith("```")) {
|
|
22
|
+
list = null;
|
|
23
|
+
const lang = line.slice(3).trim();
|
|
24
|
+
const code = [];
|
|
25
|
+
i++;
|
|
26
|
+
while (i < lines.length && !(lines[i] ?? "").trim().startsWith("```")) {
|
|
27
|
+
code.push(lines[i] ?? "");
|
|
28
|
+
i++;
|
|
29
|
+
}
|
|
30
|
+
blocks.push({ kind: "code", lang, code: code.join("\n") });
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!line) {
|
|
34
|
+
list = null;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const bullet = /^[-*•]\s+(.*)$/.exec(line);
|
|
38
|
+
const numbered = /^\d+[.)]\s+(.*)$/.exec(line);
|
|
39
|
+
if (bullet || numbered) {
|
|
40
|
+
const kind = bullet ? "ul" : "ol";
|
|
41
|
+
if (!list || list.kind !== kind) {
|
|
42
|
+
list = { kind, items: [] };
|
|
43
|
+
blocks.push(list);
|
|
44
|
+
}
|
|
45
|
+
list.items.push((bullet ?? numbered)[1] ?? "");
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
list = null;
|
|
49
|
+
if (/^#{1,6}\s/.test(line)) {
|
|
50
|
+
blocks.push({ kind: "h", text: line.replace(/^#+\s+/, "") });
|
|
51
|
+
}
|
|
52
|
+
else if (line.startsWith(">")) {
|
|
53
|
+
// A model's `>` leaked into prose was one of orangecat's fixed bugs.
|
|
54
|
+
blocks.push({ kind: "quote", text: line.replace(/^>\s?/, "") });
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const prev = blocks[blocks.length - 1];
|
|
58
|
+
// A soft line break inside a paragraph continues it.
|
|
59
|
+
if (prev && prev.kind === "p" && (lines[i - 1] ?? "").trim())
|
|
60
|
+
prev.text += `\n${line}`;
|
|
61
|
+
else
|
|
62
|
+
blocks.push({ kind: "p", text: line });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return blocks;
|
|
66
|
+
}
|
|
67
|
+
const INLINE_RE = /(`[^`]+`|\*\*[^*]+\*\*|\*[^*\s][^*]*\*|\[[^\]]+\]\([^)\s]+\)|\[[FD]\d+(?:,\s*[FD]\d+)*\]|https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/g;
|
|
68
|
+
export function parseInline(text) {
|
|
69
|
+
const out = [];
|
|
70
|
+
for (const part of text.split(INLINE_RE)) {
|
|
71
|
+
if (!part)
|
|
72
|
+
continue;
|
|
73
|
+
if (/^\[[FD]\d+(?:,\s*[FD]\d+)*\]$/.test(part)) {
|
|
74
|
+
out.push({ kind: "cite", ids: part.slice(1, -1).split(/,\s*/) });
|
|
75
|
+
}
|
|
76
|
+
else if (part.startsWith("`") && part.endsWith("`") && part.length > 1) {
|
|
77
|
+
out.push({ kind: "code", text: part.slice(1, -1) });
|
|
78
|
+
}
|
|
79
|
+
else if (part.startsWith("**") && part.endsWith("**") && part.length > 4) {
|
|
80
|
+
const inner = part.slice(2, -2);
|
|
81
|
+
out.push({ kind: "strong", text: inner, children: parseInline(inner) });
|
|
82
|
+
}
|
|
83
|
+
else if (/^\*[^*\s][^*]*\*$/.test(part)) {
|
|
84
|
+
const inner = part.slice(1, -1);
|
|
85
|
+
out.push({ kind: "em", text: inner, children: parseInline(inner) });
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const link = /^\[([^\]]+)\]\(([^)\s]+)\)$/.exec(part);
|
|
89
|
+
const href = link
|
|
90
|
+
? safeHref(link[2] ?? "")
|
|
91
|
+
: /^https?:\/\//.test(part)
|
|
92
|
+
? safeHref(part)
|
|
93
|
+
: null;
|
|
94
|
+
if (link && href)
|
|
95
|
+
out.push({ kind: "link", text: link[1] ?? href, href });
|
|
96
|
+
else if (!link && href)
|
|
97
|
+
out.push({ kind: "link", text: part, href });
|
|
98
|
+
else
|
|
99
|
+
out.push({ kind: "text", text: link ? (link[1] ?? part) : part });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return out;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Only http(s), mailto and same-site paths become links. A `javascript:` URL in
|
|
106
|
+
* model output is text, never a link — the answer is written by a model that
|
|
107
|
+
* may have read a hostile page.
|
|
108
|
+
*/
|
|
109
|
+
export function safeHref(href) {
|
|
110
|
+
const h = href.trim();
|
|
111
|
+
if (h.startsWith("/") && !h.startsWith("//"))
|
|
112
|
+
return h;
|
|
113
|
+
if (h.startsWith("#"))
|
|
114
|
+
return h;
|
|
115
|
+
try {
|
|
116
|
+
const u = new URL(h);
|
|
117
|
+
return u.protocol === "https:" || u.protocol === "http:" || u.protocol === "mailto:"
|
|
118
|
+
? u.href
|
|
119
|
+
: null;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/** A same-site path navigates in place; anything else opens a new tab. */
|
|
126
|
+
export function isInternalHref(href) {
|
|
127
|
+
return href.startsWith("/") || href.startsWith("#");
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,MAAM,GAAoB,EAAE,CAAC;IACnC,IAAI,IAAI,GAAkD,IAAI,CAAC;IAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,wEAAwE;QACxE,6BAA6B;QAC7B,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,GAAG,IAAI,CAAC;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAClC,MAAM,IAAI,GAAa,EAAE,CAAC;YAC1B,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;gBACtE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;gBAC1B,CAAC,EAAE,CAAC;YACN,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS;QACX,CAAC;QACD,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,MAAM,IAAI,QAAQ,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;YAClC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;gBAChC,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,QAAQ,CAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAChD,SAAS;QACX,CAAC;QACD,IAAI,GAAG,IAAI,CAAC;QACZ,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChC,qEAAqE;YACrE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACvC,qDAAqD;YACrD,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;gBAAE,IAAI,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;;gBAClF,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAaD,MAAM,SAAS,GACb,mIAAmI,CAAC;AAEtI,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,IAAI,+BAA+B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/C,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC1E,CAAC;aAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,GAAG,6BAA6B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,IAAI,GAAG,IAAI;gBACf,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;gBACzB,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;oBACzB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAChB,CAAC,CAAC,IAAI,CAAC;YACX,IAAI,IAAI,IAAI,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;iBACrE,IAAI,CAAC,IAAI,IAAI,IAAI;gBAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;;gBAChE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACvD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;QACrB,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;YAClF,CAAC,CAAC,CAAC,CAAC,IAAI;YACR,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type ReactNode, type RefObject } from "react";
|
|
2
|
+
import { type ComposerMode, type ComposerSendResult } from "../composer.js";
|
|
3
|
+
import { type DictationProblem } from "../dictation.js";
|
|
4
|
+
import { type Attachment, type AttachmentLimits, type AttachmentNotes } from "../attachments.js";
|
|
5
|
+
import { type UseDictationOptions } from "./use-dictation.js";
|
|
6
|
+
export type ComposerLabels = {
|
|
7
|
+
send: string;
|
|
8
|
+
stop: string;
|
|
9
|
+
voice: string;
|
|
10
|
+
voiceStop: string;
|
|
11
|
+
cancelRecording: string;
|
|
12
|
+
confirmRecording: string;
|
|
13
|
+
listening: string;
|
|
14
|
+
transcribing: string;
|
|
15
|
+
attach: string;
|
|
16
|
+
remove: (name: string) => string;
|
|
17
|
+
dismiss: string;
|
|
18
|
+
dictation: Record<DictationProblem, string>;
|
|
19
|
+
/** Why a file did not attach. */
|
|
20
|
+
attachNotes: AttachmentNotes;
|
|
21
|
+
};
|
|
22
|
+
export declare const DEFAULT_COMPOSER_LABELS: ComposerLabels;
|
|
23
|
+
export type ComposerVoice = Omit<UseDictationOptions, "onText">;
|
|
24
|
+
/** Overrides: every label is optional, including each dictation and attachment note. */
|
|
25
|
+
export type ComposerLabelOverrides = Partial<Omit<ComposerLabels, "dictation" | "attachNotes">> & {
|
|
26
|
+
dictation?: Partial<ComposerLabels["dictation"]>;
|
|
27
|
+
attachNotes?: Partial<AttachmentNotes>;
|
|
28
|
+
};
|
|
29
|
+
export type ComposerProps = {
|
|
30
|
+
/** Deliver what was written. Return `false` (or resolve to it) to keep the
|
|
31
|
+
* draft — a failed send is retried from the same box, not retyped. */
|
|
32
|
+
onSend: (text: string, attachments: Attachment[]) => ComposerSendResult | Promise<ComposerSendResult>;
|
|
33
|
+
placeholder: string;
|
|
34
|
+
ariaLabel?: string;
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/** Typing is fine, sending is not — shown as the send button's title. */
|
|
37
|
+
sendBlockedReason?: string | null;
|
|
38
|
+
sending?: boolean;
|
|
39
|
+
/** Given, the send slot becomes Stop while `sending`: a turn you cannot
|
|
40
|
+
* cancel is what makes a slow answer feel broken. */
|
|
41
|
+
onStop?: () => void;
|
|
42
|
+
/** What an attachments-only send says. Omit and empty text cannot send. */
|
|
43
|
+
attachmentOnlyText?: string;
|
|
44
|
+
/** Attachments on, optionally with the app's own limits. Off by default:
|
|
45
|
+
* only offer what the app's API accepts. */
|
|
46
|
+
attach?: boolean | Partial<AttachmentLimits>;
|
|
47
|
+
/** The microphone. On by default. Pass `transcribeUrl` (or `transcribe`) so
|
|
48
|
+
* it still works where the browser recogniser does not — that fallback is
|
|
49
|
+
* what makes the mic never a dead button. `false` only for a surface that
|
|
50
|
+
* truly cannot take speech. */
|
|
51
|
+
voice?: ComposerVoice | false;
|
|
52
|
+
modes?: readonly ComposerMode[];
|
|
53
|
+
mode?: string;
|
|
54
|
+
onModeChange?: (id: string) => void;
|
|
55
|
+
/** "/" typed into an empty composer — open a library instead of typing. */
|
|
56
|
+
onEmptySlash?: () => void;
|
|
57
|
+
value?: string;
|
|
58
|
+
onValueChange?: (text: string) => void;
|
|
59
|
+
defaultValue?: string;
|
|
60
|
+
inputRef?: RefObject<HTMLTextAreaElement | null>;
|
|
61
|
+
density?: "comfortable" | "compact";
|
|
62
|
+
/** Outside the box, above it (suggestion chips). */
|
|
63
|
+
above?: ReactNode;
|
|
64
|
+
/** Inside the box, above the text (scope pills, an error). */
|
|
65
|
+
header?: ReactNode;
|
|
66
|
+
/** Extra tools after attach and voice (a model picker, a library). */
|
|
67
|
+
tools?: ReactNode;
|
|
68
|
+
/** Just before the send button. */
|
|
69
|
+
trailing?: ReactNode;
|
|
70
|
+
/** Inside the box, under the controls. */
|
|
71
|
+
footer?: ReactNode;
|
|
72
|
+
hint?: string;
|
|
73
|
+
labels?: ComposerLabelOverrides;
|
|
74
|
+
autoFocus?: boolean;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* THE composer: write words — or say them, or paste a screenshot — and send
|
|
78
|
+
* them. Enter sends, Shift+Enter breaks the line, an IME composition never
|
|
79
|
+
* sends half a word. 16px text, so iOS never zooms the page on focus.
|
|
80
|
+
*
|
|
81
|
+
* Extracted from loki `components/composer/Composer.tsx` (itself the merge of
|
|
82
|
+
* four composers in one app), with heidi's microphone and orangecat's lessons.
|
|
83
|
+
*/
|
|
84
|
+
export declare function Composer({ onSend, placeholder, ariaLabel, disabled, sendBlockedReason, sending, onStop, attachmentOnlyText, attach, voice, modes, mode, onModeChange, onEmptySlash, value, onValueChange, defaultValue, inputRef, density, above, header, tools, trailing, footer, hint, labels: labelOverrides, autoFocus, }: ComposerProps): import("react").JSX.Element;
|
|
85
|
+
//# sourceMappingURL=Composer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composer.d.ts","sourceRoot":"","sources":["../../src/react/Composer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { appendTranscript, composerCanSend, composerOutgoingText, formatElapsed, shouldClearDraft, } from "../composer.js";
|
|
5
|
+
import { DEFAULT_DICTATION_MESSAGES } from "../dictation.js";
|
|
6
|
+
import { DEFAULT_ATTACHMENT_NOTES, } from "../attachments.js";
|
|
7
|
+
import { useDictation } from "./use-dictation.js";
|
|
8
|
+
import { useAttachments } from "./use-attachments.js";
|
|
9
|
+
import { useAutoGrow } from "./hooks.js";
|
|
10
|
+
import { IconArrowUp, IconCheck, IconFile, IconMic, IconPaperclip, IconSpinner, IconStop, IconX, } from "./icons.js";
|
|
11
|
+
export const DEFAULT_COMPOSER_LABELS = {
|
|
12
|
+
send: "Send",
|
|
13
|
+
stop: "Stop generating",
|
|
14
|
+
voice: "Speak instead of typing",
|
|
15
|
+
voiceStop: "Stop recording",
|
|
16
|
+
cancelRecording: "Cancel recording",
|
|
17
|
+
confirmRecording: "Done — use what I said",
|
|
18
|
+
listening: "Listening…",
|
|
19
|
+
transcribing: "Transcribing…",
|
|
20
|
+
attach: "Attach a screenshot or file",
|
|
21
|
+
remove: (name) => `Remove ${name}`,
|
|
22
|
+
dismiss: "Dismiss",
|
|
23
|
+
dictation: DEFAULT_DICTATION_MESSAGES,
|
|
24
|
+
attachNotes: DEFAULT_ATTACHMENT_NOTES,
|
|
25
|
+
};
|
|
26
|
+
function AttachmentStrip({ attachments, labels, }) {
|
|
27
|
+
if (attachments.attachments.length === 0 && !attachments.note)
|
|
28
|
+
return null;
|
|
29
|
+
return (_jsxs("div", { className: "ck-attach-strip", children: [attachments.attachments.map((a) => {
|
|
30
|
+
const key = attachments.keyOf(a);
|
|
31
|
+
return (_jsxs("div", { className: "ck-attach-item", children: [a.kind === "image" && a.previewUrl ? (_jsx("img", { src: a.previewUrl, alt: a.name, className: "ck-attach-thumb" })) : (_jsxs("span", { className: "ck-attach-file", children: [_jsx(IconFile, {}), _jsx("span", { className: "ck-truncate", children: a.name })] })), _jsx("button", { type: "button", className: "ck-attach-remove", onClick: () => attachments.remove(key), "aria-label": labels.remove(a.name), title: labels.remove(a.name), children: _jsx(IconX, {}) })] }, key));
|
|
32
|
+
}), attachments.note && (_jsx("button", { type: "button", className: "ck-note", onClick: attachments.clearNote, children: attachments.note }))] }));
|
|
33
|
+
}
|
|
34
|
+
function Elapsed({ since }) {
|
|
35
|
+
const [now, setNow] = useState(() => Date.now());
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (since === null)
|
|
38
|
+
return;
|
|
39
|
+
const t = setInterval(() => setNow(Date.now()), 250);
|
|
40
|
+
return () => clearInterval(t);
|
|
41
|
+
}, [since]);
|
|
42
|
+
return (_jsx("span", { className: "ck-voice-timer", children: formatElapsed(since === null ? 0 : (now - since) / 1000) }));
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* THE composer: write words — or say them, or paste a screenshot — and send
|
|
46
|
+
* them. Enter sends, Shift+Enter breaks the line, an IME composition never
|
|
47
|
+
* sends half a word. 16px text, so iOS never zooms the page on focus.
|
|
48
|
+
*
|
|
49
|
+
* Extracted from loki `components/composer/Composer.tsx` (itself the merge of
|
|
50
|
+
* four composers in one app), with heidi's microphone and orangecat's lessons.
|
|
51
|
+
*/
|
|
52
|
+
export function Composer({ onSend, placeholder, ariaLabel, disabled = false, sendBlockedReason = null, sending = false, onStop, attachmentOnlyText, attach = false, voice = {}, modes, mode, onModeChange, onEmptySlash, value, onValueChange, defaultValue = "", inputRef, density = "comfortable", above, header, tools, trailing, footer, hint, labels: labelOverrides, autoFocus, }) {
|
|
53
|
+
const labels = {
|
|
54
|
+
...DEFAULT_COMPOSER_LABELS,
|
|
55
|
+
...labelOverrides,
|
|
56
|
+
dictation: { ...DEFAULT_COMPOSER_LABELS.dictation, ...labelOverrides?.dictation },
|
|
57
|
+
attachNotes: { ...DEFAULT_COMPOSER_LABELS.attachNotes, ...labelOverrides?.attachNotes },
|
|
58
|
+
};
|
|
59
|
+
const [ownText, setOwnText] = useState(defaultValue);
|
|
60
|
+
const controlled = value !== undefined;
|
|
61
|
+
const text = controlled ? value : ownText;
|
|
62
|
+
// Mirrored so an async send compares against the CURRENT draft, not the one
|
|
63
|
+
// its closure captured. Written in an effect, never during render.
|
|
64
|
+
const textRef = useRef(text);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
textRef.current = text;
|
|
67
|
+
});
|
|
68
|
+
const setText = (next) => {
|
|
69
|
+
const resolved = typeof next === "function" ? next(textRef.current) : next;
|
|
70
|
+
textRef.current = resolved;
|
|
71
|
+
if (!controlled)
|
|
72
|
+
setOwnText(resolved);
|
|
73
|
+
onValueChange?.(resolved);
|
|
74
|
+
};
|
|
75
|
+
const localRef = useRef(null);
|
|
76
|
+
const textareaRef = inputRef ?? localRef;
|
|
77
|
+
useAutoGrow(textareaRef, text);
|
|
78
|
+
const attachOn = attach !== false;
|
|
79
|
+
const attachments = useAttachments(typeof attach === "object" ? attach : {}, labels.attachNotes);
|
|
80
|
+
const dictation = useDictation({
|
|
81
|
+
...(voice || {}),
|
|
82
|
+
onText: (said) => setText((prev) => appendTranscript(prev, said)),
|
|
83
|
+
});
|
|
84
|
+
const voiceOn = voice !== false && dictation.supported;
|
|
85
|
+
const listening = dictation.status === "listening";
|
|
86
|
+
const transcribing = dictation.status === "transcribing";
|
|
87
|
+
const attachCount = attachOn ? attachments.attachments.length : 0;
|
|
88
|
+
const canSend = composerCanSend({
|
|
89
|
+
text,
|
|
90
|
+
attachmentCount: attachCount,
|
|
91
|
+
attachmentOnlyText,
|
|
92
|
+
sending,
|
|
93
|
+
disabled,
|
|
94
|
+
blocked: Boolean(sendBlockedReason),
|
|
95
|
+
});
|
|
96
|
+
const submit = async () => {
|
|
97
|
+
if (!canSend)
|
|
98
|
+
return;
|
|
99
|
+
const sent = text;
|
|
100
|
+
const outgoing = composerOutgoingText(sent, attachCount, attachmentOnlyText);
|
|
101
|
+
const result = await onSend(outgoing, attachOn ? attachments.toWire() : []);
|
|
102
|
+
if (!shouldClearDraft(result))
|
|
103
|
+
return;
|
|
104
|
+
// Only clear what was sent: words typed while a slow send was in flight
|
|
105
|
+
// are the next message.
|
|
106
|
+
if (textRef.current === sent)
|
|
107
|
+
setText("");
|
|
108
|
+
attachments.clear();
|
|
109
|
+
};
|
|
110
|
+
const fileInput = useRef(null);
|
|
111
|
+
const showModes = Boolean(modes && modes.length > 1);
|
|
112
|
+
return (_jsxs("div", { className: "ck-composer-wrap", children: [above, _jsxs("div", { className: "ck-composer-frame", children: [(listening || transcribing) && (_jsx("div", { className: "ck-voice-bar", role: "status", "aria-live": "polite", children: listening ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "ck-voice-dot", "aria-hidden": true }), _jsx("span", { className: "ck-voice-wave", "aria-hidden": true, children: Array.from({ length: 9 }).map((_, i) => (_jsx("span", {}, i))) }), _jsx(Elapsed, { since: dictation.startedAt }), _jsx("button", { type: "button", className: "ck-icon-btn", onClick: dictation.cancel, "aria-label": labels.cancelRecording, title: labels.cancelRecording, children: _jsx(IconX, {}) }), _jsx("button", { type: "button", className: "ck-voice-confirm", onClick: dictation.stop, "aria-label": labels.confirmRecording, title: labels.confirmRecording, children: _jsx(IconCheck, {}) })] })) : (_jsxs(_Fragment, { children: [_jsx(IconSpinner, {}), _jsx("span", { className: "ck-voice-timer", children: labels.transcribing })] })) })), _jsxs("div", { className: density === "compact" ? "ck-composer ck-composer-compact" : "ck-composer", children: [showModes && (_jsx("div", { className: "ck-modes", role: "group", children: modes.map((m) => (_jsx("button", { type: "button", className: "ck-mode", "aria-pressed": m.id === mode, title: m.hint, onClick: () => onModeChange?.(m.id), children: m.label }, m.id))) })), header, _jsx("textarea", { ref: textareaRef, className: "ck-input", rows: 1, value: text, autoFocus: autoFocus, disabled: disabled || transcribing, placeholder: listening ? labels.listening : placeholder, "aria-label": ariaLabel ?? placeholder, enterKeyHint: "send", onChange: (e) => {
|
|
113
|
+
const next = e.target.value;
|
|
114
|
+
if (onEmptySlash && next === "/" && text === "") {
|
|
115
|
+
onEmptySlash();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
setText(next);
|
|
119
|
+
}, onPaste: (e) => {
|
|
120
|
+
if (attachOn && attachments.addFromPaste(e))
|
|
121
|
+
e.preventDefault();
|
|
122
|
+
}, onKeyDown: (e) => {
|
|
123
|
+
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
void submit();
|
|
126
|
+
}
|
|
127
|
+
} }), attachOn && _jsx(AttachmentStrip, { attachments: attachments, labels: labels }), _jsxs("div", { className: "ck-actions", children: [_jsxs("div", { className: "ck-tools", children: [attachOn && (_jsxs(_Fragment, { children: [_jsx("input", { ref: fileInput, type: "file", multiple: true, hidden: true, accept: "image/*,text/*,.md,.txt,.json,.csv,.log", onChange: (e) => {
|
|
128
|
+
attachments.addFiles(e.target.files);
|
|
129
|
+
e.target.value = "";
|
|
130
|
+
} }), _jsx("button", { type: "button", className: "ck-icon-btn", onClick: () => fileInput.current?.click(), disabled: disabled || attachments.full, "aria-label": labels.attach, title: labels.attach, children: _jsx(IconPaperclip, {}) })] })), voiceOn && (_jsx("button", { type: "button", className: listening ? "ck-icon-btn ck-mic ck-mic-on" : "ck-icon-btn ck-mic", onClick: dictation.toggle, disabled: disabled || transcribing, "aria-label": listening ? labels.voiceStop : labels.voice, "aria-pressed": listening, title: listening ? labels.voiceStop : labels.voice, children: transcribing ? _jsx(IconSpinner, {}) : _jsx(IconMic, {}) })), tools, hint && _jsx("span", { className: "ck-hint", children: hint })] }), _jsxs("div", { className: "ck-submit", children: [trailing, sending && onStop ? (_jsx("button", { type: "button", className: "ck-send ck-send-stop", onClick: onStop, "aria-label": labels.stop, title: labels.stop, children: _jsx(IconStop, {}) })) : (!listening && (_jsx("button", { type: "button", className: "ck-send", disabled: !canSend, onClick: () => void submit(), "aria-label": labels.send, title: sendBlockedReason ?? labels.send, children: sending ? _jsx(IconSpinner, {}) : _jsx(IconArrowUp, {}) })))] })] }), footer] })] }), dictation.problem && (_jsxs("p", { className: "ck-problem", role: "status", children: [_jsx("span", { children: labels.dictation[dictation.problem] }), _jsx("button", { type: "button", className: "ck-problem-x", onClick: dictation.clearProblem, "aria-label": labels.dismiss, children: _jsx(IconX, {}) })] }))] }));
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=Composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composer.js","sourceRoot":"","sources":["../../src/react/Composer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/** What a grounded answer's `[F8]` / `[D1]` handle refers to. Unknown handles
|
|
3
|
+
* are dropped rather than shown bare: a dangling `[F8]` implies a source the
|
|
4
|
+
* reader cannot reach. */
|
|
5
|
+
export type CitationMap = Record<string, {
|
|
6
|
+
label: string;
|
|
7
|
+
detail: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type RenderLink = (link: {
|
|
10
|
+
href: string;
|
|
11
|
+
internal: boolean;
|
|
12
|
+
className: string;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}) => ReactNode;
|
|
15
|
+
/** A plain anchor: same-site paths in place, everything else in a new tab. */
|
|
16
|
+
export declare const defaultRenderLink: RenderLink;
|
|
17
|
+
/**
|
|
18
|
+
* Model output as readable text: paragraphs, lists, headings, bold, italic,
|
|
19
|
+
* code, links and citations. Never HTML — nothing here can inject markup.
|
|
20
|
+
*/
|
|
21
|
+
export declare function Markdown({ text, citations, renderLink, className, }: {
|
|
22
|
+
text: string;
|
|
23
|
+
citations?: CitationMap;
|
|
24
|
+
renderLink?: RenderLink;
|
|
25
|
+
className?: string;
|
|
26
|
+
}): import("react").JSX.Element;
|
|
27
|
+
//# sourceMappingURL=Markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Markdown.d.ts","sourceRoot":"","sources":["../../src/react/Markdown.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC;;2BAE2B;AAC3B,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAE5E,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;CACrB,KAAK,SAAS,CAAC;AAEhB,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,EAAE,UAS7B,CAAC;AAuEJ;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,SAAS,EACT,UAA8B,EAC9B,SAAS,GACV,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAuCA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { isInternalHref, parseBlocks, parseInline } from "../markdown.js";
|
|
3
|
+
/** A plain anchor: same-site paths in place, everything else in a new tab. */
|
|
4
|
+
export const defaultRenderLink = ({ href, internal, className, children }) => internal ? (_jsx("a", { href: href, className: className, children: children })) : (_jsx("a", { href: href, className: className, target: "_blank", rel: "noopener noreferrer", children: children }));
|
|
5
|
+
function Inline({ spans, citations, renderLink, }) {
|
|
6
|
+
return (_jsx(_Fragment, { children: spans.map((s, i) => {
|
|
7
|
+
switch (s.kind) {
|
|
8
|
+
case "code":
|
|
9
|
+
return (_jsx("code", { className: "ck-code", children: s.text }, i));
|
|
10
|
+
case "strong":
|
|
11
|
+
case "em": {
|
|
12
|
+
// Plain emphasis stays plain markup; only what holds a link, code
|
|
13
|
+
// or a citation is rendered as nested spans.
|
|
14
|
+
const plain = s.children.every((c) => c.kind === "text");
|
|
15
|
+
const inner = plain ? (s.text) : (_jsx(Inline, { spans: s.children, citations: citations, renderLink: renderLink }));
|
|
16
|
+
return s.kind === "strong" ? (_jsx("strong", { children: inner }, i)) : (_jsx("em", { children: inner }, i));
|
|
17
|
+
}
|
|
18
|
+
case "link":
|
|
19
|
+
return (_jsx("span", { children: renderLink({
|
|
20
|
+
href: s.href,
|
|
21
|
+
internal: isInternalHref(s.href),
|
|
22
|
+
className: "ck-link",
|
|
23
|
+
children: s.text,
|
|
24
|
+
}) }, i));
|
|
25
|
+
case "cite": {
|
|
26
|
+
const known = s.ids.filter((id) => citations?.[id]);
|
|
27
|
+
if (known.length === 0)
|
|
28
|
+
return null;
|
|
29
|
+
return (_jsx("sup", { className: "ck-cite", title: known
|
|
30
|
+
.map((id) => `${id} — ${citations[id].label}\n${citations[id].detail}`)
|
|
31
|
+
.join("\n\n"), children: known.join(" ") }, i));
|
|
32
|
+
}
|
|
33
|
+
default:
|
|
34
|
+
return _jsx("span", { children: s.text }, i);
|
|
35
|
+
}
|
|
36
|
+
}) }));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Model output as readable text: paragraphs, lists, headings, bold, italic,
|
|
40
|
+
* code, links and citations. Never HTML — nothing here can inject markup.
|
|
41
|
+
*/
|
|
42
|
+
export function Markdown({ text, citations, renderLink = defaultRenderLink, className, }) {
|
|
43
|
+
const inline = (t) => (_jsx(Inline, { spans: parseInline(t), citations: citations, renderLink: renderLink }));
|
|
44
|
+
return (_jsx("div", { className: className ? `ck-md ${className}` : "ck-md", children: parseBlocks(text).map((b, i) => {
|
|
45
|
+
switch (b.kind) {
|
|
46
|
+
case "code":
|
|
47
|
+
return (_jsx("pre", { className: "ck-pre", "data-lang": b.lang || undefined, children: _jsx("code", { children: b.code }) }, i));
|
|
48
|
+
case "ul":
|
|
49
|
+
case "ol": {
|
|
50
|
+
const List = b.kind;
|
|
51
|
+
return (_jsx(List, { children: b.items.map((item, j) => (_jsx("li", { children: inline(item) }, j))) }, i));
|
|
52
|
+
}
|
|
53
|
+
case "h":
|
|
54
|
+
return (_jsx("p", { className: "ck-md-h", children: inline(b.text) }, i));
|
|
55
|
+
case "quote":
|
|
56
|
+
return _jsx("blockquote", { children: inline(b.text) }, i);
|
|
57
|
+
default:
|
|
58
|
+
return _jsx("p", { children: inline(b.text) }, i);
|
|
59
|
+
}
|
|
60
|
+
}) }));
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=Markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Markdown.js","sourceRoot":"","sources":["../../src/react/Markdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
import { type CitationMap, type RenderLink } from "./Markdown.js";
|
|
3
|
+
export type ChatSpeaker = {
|
|
4
|
+
/** Shown above the message when more than one agent can answer. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Stable id for styling (`ck-from-<id>`), e.g. "cat" or "loki". */
|
|
7
|
+
id?: string;
|
|
8
|
+
};
|
|
9
|
+
export type ChatMessageData = {
|
|
10
|
+
id: string;
|
|
11
|
+
role: "user" | "assistant";
|
|
12
|
+
content: string;
|
|
13
|
+
speaker?: ChatSpeaker;
|
|
14
|
+
citations?: CitationMap;
|
|
15
|
+
/** The turn failed: shown as a failure with Retry, never as silence. */
|
|
16
|
+
failed?: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type ThreadLabels = {
|
|
19
|
+
copy: string;
|
|
20
|
+
copied: string;
|
|
21
|
+
retry: string;
|
|
22
|
+
stop: string;
|
|
23
|
+
working: string;
|
|
24
|
+
stopped: string;
|
|
25
|
+
jump: string;
|
|
26
|
+
failed: string;
|
|
27
|
+
loading: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const DEFAULT_THREAD_LABELS: ThreadLabels;
|
|
30
|
+
/**
|
|
31
|
+
* One turn. The asymmetry is deliberate: the person's own words get a pill —
|
|
32
|
+
* a short aside they already know — and the answer gets the full column with
|
|
33
|
+
* no box, because it is the thing being READ. Copy is on every answer; Retry
|
|
34
|
+
* only on the last one (retrying an older turn would fork the thread).
|
|
35
|
+
*/
|
|
36
|
+
export declare function ChatMessage({ message, onRetry, renderLink, showSpeaker, footer, last, labels, }: {
|
|
37
|
+
message: ChatMessageData;
|
|
38
|
+
/** The latest answer: its actions stay visible (they are what you want next). */
|
|
39
|
+
last?: boolean;
|
|
40
|
+
onRetry?: () => void;
|
|
41
|
+
renderLink?: RenderLink;
|
|
42
|
+
/** Hide the name when only one agent ever speaks. */
|
|
43
|
+
showSpeaker?: boolean;
|
|
44
|
+
/** Under the answer: provenance, sources, an action card. */
|
|
45
|
+
footer?: ReactNode;
|
|
46
|
+
labels?: ThreadLabels;
|
|
47
|
+
}): import("react").JSX.Element;
|
|
48
|
+
export type LiveTurn = {
|
|
49
|
+
/** What has streamed in so far. */
|
|
50
|
+
text?: string;
|
|
51
|
+
/** What it is doing before the first word ("Reading the fleet map"). */
|
|
52
|
+
status?: string;
|
|
53
|
+
speaker?: ChatSpeaker;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* The conversation. Follows new tokens only while the reader is at the
|
|
57
|
+
* bottom, with a button back down once they are not; a turn in flight can be
|
|
58
|
+
* stopped from where it is being written.
|
|
59
|
+
*/
|
|
60
|
+
export declare function ChatThread({ messages, live, loading, stopped, onStop, onRetry, renderLink, renderFooter, showSpeakers, empty, children, labels: labelOverrides, }: {
|
|
61
|
+
messages: ChatMessageData[];
|
|
62
|
+
live?: LiveTurn | null;
|
|
63
|
+
loading?: boolean;
|
|
64
|
+
/** The person stopped the last turn themselves. */
|
|
65
|
+
stopped?: boolean;
|
|
66
|
+
onStop?: () => void;
|
|
67
|
+
/** Retry the last answer (offered on it, and on a failed one). */
|
|
68
|
+
onRetry?: () => void;
|
|
69
|
+
renderLink?: RenderLink;
|
|
70
|
+
/** App-specific content under an answer (sources, an action card). */
|
|
71
|
+
renderFooter?: (m: ChatMessageData) => ReactNode;
|
|
72
|
+
/** Default: shown when more than one speaker appears in the thread. */
|
|
73
|
+
showSpeakers?: boolean;
|
|
74
|
+
/** Shown instead of the thread before the first message (starters). */
|
|
75
|
+
empty?: ReactNode;
|
|
76
|
+
/** After the last turn (a note, a picker). */
|
|
77
|
+
children?: ReactNode;
|
|
78
|
+
labels?: Partial<ThreadLabels>;
|
|
79
|
+
}): import("react").JSX.Element;
|
|
80
|
+
export type Starter = string | {
|
|
81
|
+
label: string;
|
|
82
|
+
prompt?: string;
|
|
83
|
+
};
|
|
84
|
+
/** The empty state that starts a conversation. It disappears once one has. */
|
|
85
|
+
export declare function ChatStarters({ starters, onPick, title, }: {
|
|
86
|
+
starters: readonly Starter[];
|
|
87
|
+
onPick: (prompt: string) => void;
|
|
88
|
+
title?: ReactNode;
|
|
89
|
+
}): import("react").JSX.Element;
|
|
90
|
+
//# sourceMappingURL=Thread.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Thread.d.ts","sourceRoot":"","sources":["../../src/react/Thread.tsx"],"names":[],"mappings":"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"}
|