quassel 0.1.1 → 0.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/ChatInputToolbar.d.ts +35 -6
- package/ChatMessages.d.ts +19 -15
- package/ChatPanel.d.ts +4 -2
- package/ChatSendContext.d.ts +7 -12
- package/DetailModeSwitch.d.ts +1 -1
- package/Markdown.d.ts +4 -11
- package/MessageActions.d.ts +1 -10
- package/PendingActionCard.d.ts +13 -0
- package/QuasselProvider.d.ts +76 -0
- package/README.md +39 -38
- package/StepPopover.d.ts +1 -1
- package/TimestampSwitch.d.ts +2 -2
- package/WorkingScenes.d.ts +3 -1
- package/attachments.d.ts +24 -0
- package/chat-attachments.d.ts +6 -0
- package/chat-scroll.d.ts +12 -0
- package/chat.css +2051 -0
- package/chunk-IGCFQJZB.js +183 -0
- package/chunk-IGCFQJZB.js.map +7 -0
- package/events.d.ts +74 -17
- package/events.js +11 -1
- package/index.d.ts +17 -10
- package/index.js +1615 -988
- package/index.js.map +4 -4
- package/options.d.ts +1 -1
- package/package.json +12 -10
- package/texts.d.ts +38 -11
- package/timestamps.d.ts +6 -4
- package/types.d.ts +6 -6
- package/ui/button.d.ts +8 -0
- package/ui/card.d.ts +5 -0
- package/ui/cn.d.ts +2 -0
- package/ui/popover.d.ts +4 -0
- package/ui/spinner.d.ts +2 -0
- package/ui/stop-button.d.ts +10 -0
- package/ui/toggle.d.ts +8 -0
- package/ui/useFileInput.d.ts +20 -0
- package/useChatAction.d.ts +6 -0
- package/QuestionCard.d.ts +0 -12
- package/chunk-DOLTANTM.js +0 -84
- package/chunk-DOLTANTM.js.map +0 -7
- package/css/chat.css +0 -927
- package/css/foundation/base.css +0 -24
- package/css/foundation/index.css +0 -3
- package/css/foundation/panel.css +0 -111
- package/css/foundation/tokens.css +0 -68
- package/css/foundation/wash.css +0 -26
- package/css/question.css +0 -149
- package/icons.d.ts +0 -15
- package/server/http.d.ts +0 -17
- package/server/index.d.ts +0 -6
- package/server/index.js +0 -478
- package/server/index.js.map +0 -7
- package/server/manager.d.ts +0 -12
- package/server/openai.d.ts +0 -16
- package/server/session.d.ts +0 -27
- package/server/store.d.ts +0 -18
- package/server/types.d.ts +0 -62
- package/useChat.d.ts +0 -14
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// packages/quassel/src/chat-attachments.ts
|
|
2
|
+
var MAX_CHAT_ATTACHMENTS = 8;
|
|
3
|
+
var MAX_CHAT_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
4
|
+
var MAX_CHAT_REQUEST_BYTES = 29 * 1024 * 1024;
|
|
5
|
+
var chatAttachmentMediaType = (name, mediaType) => {
|
|
6
|
+
const explicit = mediaType.trim().toLowerCase();
|
|
7
|
+
if (explicit) return explicit === "video/quicktime" ? "video/mov" : explicit;
|
|
8
|
+
const types = {
|
|
9
|
+
png: "image/png",
|
|
10
|
+
jpg: "image/jpeg",
|
|
11
|
+
jpeg: "image/jpeg",
|
|
12
|
+
gif: "image/gif",
|
|
13
|
+
webp: "image/webp",
|
|
14
|
+
avif: "image/avif",
|
|
15
|
+
svg: "image/svg+xml",
|
|
16
|
+
pdf: "application/pdf",
|
|
17
|
+
mp4: "video/mp4",
|
|
18
|
+
webm: "video/webm",
|
|
19
|
+
mov: "video/mov",
|
|
20
|
+
mpeg: "video/mpeg",
|
|
21
|
+
mpg: "video/mpeg",
|
|
22
|
+
txt: "text/plain",
|
|
23
|
+
md: "text/markdown",
|
|
24
|
+
csv: "text/csv",
|
|
25
|
+
tsv: "text/tab-separated-values",
|
|
26
|
+
json: "application/json",
|
|
27
|
+
jsonl: "application/x-ndjson",
|
|
28
|
+
xml: "application/xml",
|
|
29
|
+
yaml: "application/yaml",
|
|
30
|
+
yml: "application/yaml",
|
|
31
|
+
ts: "text/plain",
|
|
32
|
+
tsx: "text/plain",
|
|
33
|
+
js: "application/javascript",
|
|
34
|
+
py: "text/plain",
|
|
35
|
+
cs: "text/plain",
|
|
36
|
+
fs: "text/plain",
|
|
37
|
+
html: "text/html",
|
|
38
|
+
css: "text/css",
|
|
39
|
+
log: "text/plain"
|
|
40
|
+
};
|
|
41
|
+
return types[name.split(".").at(-1)?.toLowerCase() ?? ""] ?? "application/octet-stream";
|
|
42
|
+
};
|
|
43
|
+
var parseChatAttachments = (value) => {
|
|
44
|
+
if (value === void 0) return [];
|
|
45
|
+
if (!Array.isArray(value) || value.length > MAX_CHAT_ATTACHMENTS) {
|
|
46
|
+
throw new Error(`Anh\xE4nge m\xFCssen eine Liste mit h\xF6chstens ${MAX_CHAT_ATTACHMENTS} Dateien sein.`);
|
|
47
|
+
}
|
|
48
|
+
let total = 0;
|
|
49
|
+
return value.map((entry, index) => {
|
|
50
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) throw new Error(`Anhang ${index + 1} ist ung\xFCltig.`);
|
|
51
|
+
const { name, mediaType, data } = entry;
|
|
52
|
+
if (typeof name !== "string" || !name.trim() || name.length > 255 || /[/\\\u0000-\u001f\u007f]/.test(name) || name === "." || name === "..") throw new Error(`Anhang ${index + 1} ben\xF6tigt einen g\xFCltigen Dateinamen ohne Pfad.`);
|
|
53
|
+
const normalizedType = typeof mediaType === "string" ? chatAttachmentMediaType(name, mediaType) : "";
|
|
54
|
+
if (!/^[a-z0-9!#$&^_.+-]+\/[a-z0-9!#$&^_.+-]+$/i.test(normalizedType)) {
|
|
55
|
+
throw new Error(`Anhang ${name} ben\xF6tigt einen g\xFCltigen MIME-Typ.`);
|
|
56
|
+
}
|
|
57
|
+
if (typeof data === "string" && data.length > Math.ceil(MAX_CHAT_ATTACHMENT_BYTES / 3) * 4)
|
|
58
|
+
throw new Error("Anh\xE4nge d\xFCrfen zusammen h\xF6chstens 20 MiB gro\xDF sein.");
|
|
59
|
+
if (typeof data !== "string" || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(data)) {
|
|
60
|
+
throw new Error(`Anhang ${name} enth\xE4lt ung\xFCltiges Base64.`);
|
|
61
|
+
}
|
|
62
|
+
const padding = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
|
|
63
|
+
const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
64
|
+
if (padding && (alphabet.indexOf(data[data.length - padding - 1]) & (padding === 2 ? 15 : 3)) !== 0) {
|
|
65
|
+
throw new Error(`Anhang ${name} enth\xE4lt nichtkanonisches Base64.`);
|
|
66
|
+
}
|
|
67
|
+
total += data.length / 4 * 3 - padding;
|
|
68
|
+
if (total > MAX_CHAT_ATTACHMENT_BYTES) throw new Error("Anh\xE4nge d\xFCrfen zusammen h\xF6chstens 20 MiB gro\xDF sein.");
|
|
69
|
+
return { name, mediaType: normalizedType, data };
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// packages/quassel/src/events.ts
|
|
74
|
+
var keyCounter = 0;
|
|
75
|
+
var newKey = () => typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : `qsl-${Date.now().toString(36)}-${(keyCounter += 1).toString(36)}`;
|
|
76
|
+
function openMessageIndex(messages) {
|
|
77
|
+
for (let index = messages.length - 1; index >= 0; index--) {
|
|
78
|
+
const message = messages[index];
|
|
79
|
+
if (!message.closed && (message.role === "assistant" || message.role === "thinking")) return index;
|
|
80
|
+
}
|
|
81
|
+
return -1;
|
|
82
|
+
}
|
|
83
|
+
function closeOpen(messages) {
|
|
84
|
+
const index = openMessageIndex(messages);
|
|
85
|
+
if (index === -1) {
|
|
86
|
+
return messages;
|
|
87
|
+
}
|
|
88
|
+
return messages.map((message, position) => position === index ? { ...message, closed: true } : message);
|
|
89
|
+
}
|
|
90
|
+
function appendDelta(messages, role, delta, at, textCursor) {
|
|
91
|
+
const index = openMessageIndex(messages);
|
|
92
|
+
const current = messages[index];
|
|
93
|
+
if (current && current.role === role && current.textCursor?.conversationId === textCursor?.conversationId && current.textCursor?.sequence === textCursor?.sequence) {
|
|
94
|
+
return messages.map((message, position) => position === index ? { ...message, text: message.text + delta, ...textCursor ? { textCursor } : {} } : message);
|
|
95
|
+
}
|
|
96
|
+
return [...closeOpen(messages), { key: newKey(), role, text: delta, at, ...textCursor ? { textCursor } : {} }];
|
|
97
|
+
}
|
|
98
|
+
function applyEvent(messages, event) {
|
|
99
|
+
switch (event.kind) {
|
|
100
|
+
case "reset":
|
|
101
|
+
return [];
|
|
102
|
+
case "user":
|
|
103
|
+
return [...messages, {
|
|
104
|
+
key: newKey(),
|
|
105
|
+
role: "user",
|
|
106
|
+
text: event.text,
|
|
107
|
+
closed: true,
|
|
108
|
+
at: event.at,
|
|
109
|
+
...event.inputId ? { inputId: event.inputId } : {},
|
|
110
|
+
...event.attachments?.length ? { attachments: event.attachments } : {}
|
|
111
|
+
}];
|
|
112
|
+
case "steered":
|
|
113
|
+
return messages.map((message) => message.inputId === event.inputId ? { ...message, steered: true } : message);
|
|
114
|
+
case "text":
|
|
115
|
+
return appendDelta(messages, "assistant", event.delta, event.at, event.cursor);
|
|
116
|
+
case "thinking":
|
|
117
|
+
return appendDelta(messages, "thinking", event.delta, event.at);
|
|
118
|
+
case "tool":
|
|
119
|
+
return [
|
|
120
|
+
...closeOpen(messages),
|
|
121
|
+
{
|
|
122
|
+
key: newKey(),
|
|
123
|
+
role: "tool",
|
|
124
|
+
text: event.label ?? event.name,
|
|
125
|
+
closed: true,
|
|
126
|
+
tool: { id: event.id, name: event.name, arguments: event.arguments },
|
|
127
|
+
at: event.at
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
case "tool-result": {
|
|
131
|
+
const index = messages.map((message) => message.tool?.id).lastIndexOf(event.id);
|
|
132
|
+
return messages.map(
|
|
133
|
+
(message, position) => position === index && message.tool ? { ...message, tool: { ...message.tool, result: event.result, isError: event.isError } } : message
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
case "action":
|
|
137
|
+
return [
|
|
138
|
+
...closeOpen(messages),
|
|
139
|
+
{
|
|
140
|
+
key: newKey(),
|
|
141
|
+
role: "action",
|
|
142
|
+
text: event.text,
|
|
143
|
+
closed: true,
|
|
144
|
+
action: { actionId: event.actionId, owner: event.owner, payload: event.payload },
|
|
145
|
+
at: event.at
|
|
146
|
+
}
|
|
147
|
+
];
|
|
148
|
+
case "action-resolved":
|
|
149
|
+
return messages.map(
|
|
150
|
+
(message) => message.action?.actionId === event.actionId ? { ...message, action: { ...message.action, status: event.status, result: event.result } } : message
|
|
151
|
+
);
|
|
152
|
+
case "system":
|
|
153
|
+
return [...closeOpen(messages), { key: newKey(), role: "system", text: event.text, closed: true, at: event.at }];
|
|
154
|
+
case "turn-done":
|
|
155
|
+
return closeOpen(messages);
|
|
156
|
+
default:
|
|
157
|
+
return messages;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function prettyJson(value) {
|
|
161
|
+
try {
|
|
162
|
+
return JSON.stringify(JSON.parse(value), null, 2);
|
|
163
|
+
} catch {
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function compactToolLine(tool) {
|
|
168
|
+
const args = tool.arguments.replace(/\s+/g, " ").trim();
|
|
169
|
+
const line = args && args !== "{}" ? `${tool.name} ${args}` : tool.name;
|
|
170
|
+
return line.length > 160 ? `${line.slice(0, 160)} ...` : line;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
MAX_CHAT_ATTACHMENTS,
|
|
175
|
+
MAX_CHAT_ATTACHMENT_BYTES,
|
|
176
|
+
MAX_CHAT_REQUEST_BYTES,
|
|
177
|
+
chatAttachmentMediaType,
|
|
178
|
+
parseChatAttachments,
|
|
179
|
+
applyEvent,
|
|
180
|
+
prettyJson,
|
|
181
|
+
compactToolLine
|
|
182
|
+
};
|
|
183
|
+
//# sourceMappingURL=chunk-IGCFQJZB.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/chat-attachments.ts", "../src/events.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ChatAttachmentInput } from \"./events\";\n\nexport const MAX_CHAT_ATTACHMENTS = 8;\nexport const MAX_CHAT_ATTACHMENT_BYTES = 20 * 1024 * 1024;\nexport const MAX_CHAT_REQUEST_BYTES = 29 * 1024 * 1024;\n\nexport const chatAttachmentMediaType = (name: string, mediaType: string): string => {\n const explicit = mediaType.trim().toLowerCase();\n if (explicit) return explicit === \"video/quicktime\" ? \"video/mov\" : explicit;\n const types: Record<string, string> = {\n png: \"image/png\", jpg: \"image/jpeg\", jpeg: \"image/jpeg\", gif: \"image/gif\", webp: \"image/webp\",\n avif: \"image/avif\", svg: \"image/svg+xml\", pdf: \"application/pdf\",\n mp4: \"video/mp4\", webm: \"video/webm\", mov: \"video/mov\", mpeg: \"video/mpeg\", mpg: \"video/mpeg\",\n txt: \"text/plain\", md: \"text/markdown\", csv: \"text/csv\", tsv: \"text/tab-separated-values\",\n json: \"application/json\", jsonl: \"application/x-ndjson\", xml: \"application/xml\",\n yaml: \"application/yaml\", yml: \"application/yaml\", ts: \"text/plain\", tsx: \"text/plain\",\n js: \"application/javascript\", py: \"text/plain\", cs: \"text/plain\", fs: \"text/plain\",\n html: \"text/html\", css: \"text/css\", log: \"text/plain\",\n };\n return types[name.split(\".\").at(-1)?.toLowerCase() ?? \"\"] ?? \"application/octet-stream\";\n};\n\nexport const parseChatAttachments = (value: unknown): ChatAttachmentInput[] => {\n if (value === undefined) return [];\n if (!Array.isArray(value) || value.length > MAX_CHAT_ATTACHMENTS) {\n throw new Error(`Anh\u00E4nge m\u00FCssen eine Liste mit h\u00F6chstens ${MAX_CHAT_ATTACHMENTS} Dateien sein.`);\n }\n let total = 0;\n return value.map((entry, index) => {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) throw new Error(`Anhang ${index + 1} ist ung\u00FCltig.`);\n const { name, mediaType, data } = entry as Record<string, unknown>;\n if (typeof name !== \"string\" || !name.trim() || name.length > 255 || /[/\\\\\\u0000-\\u001f\\u007f]/.test(name)\n || name === \".\" || name === \"..\") throw new Error(`Anhang ${index + 1} ben\u00F6tigt einen g\u00FCltigen Dateinamen ohne Pfad.`);\n const normalizedType = typeof mediaType === \"string\" ? chatAttachmentMediaType(name, mediaType) : \"\";\n if (!/^[a-z0-9!#$&^_.+-]+\\/[a-z0-9!#$&^_.+-]+$/i.test(normalizedType)) {\n throw new Error(`Anhang ${name} ben\u00F6tigt einen g\u00FCltigen MIME-Typ.`);\n }\n if (typeof data === \"string\" && data.length > Math.ceil(MAX_CHAT_ATTACHMENT_BYTES / 3) * 4)\n throw new Error(\"Anh\u00E4nge d\u00FCrfen zusammen h\u00F6chstens 20 MiB gro\u00DF sein.\");\n if (typeof data !== \"string\" || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(data)) {\n throw new Error(`Anhang ${name} enth\u00E4lt ung\u00FCltiges Base64.`);\n }\n const padding = data.endsWith(\"==\") ? 2 : data.endsWith(\"=\") ? 1 : 0;\n const alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n if (padding && (alphabet.indexOf(data[data.length - padding - 1]) & (padding === 2 ? 15 : 3)) !== 0) {\n throw new Error(`Anhang ${name} enth\u00E4lt nichtkanonisches Base64.`);\n }\n total += data.length / 4 * 3 - padding;\n if (total > MAX_CHAT_ATTACHMENT_BYTES) throw new Error(\"Anh\u00E4nge d\u00FCrfen zusammen h\u00F6chstens 20 MiB gro\u00DF sein.\");\n return { name, mediaType: normalizedType, data };\n });\n};\n", "export type Role = \"user\" | \"assistant\" | \"thinking\" | \"tool\" | \"system\" | \"action\";\n\nexport interface ChatAttachmentInput {\n name: string;\n mediaType: string;\n data: string;\n}\n\nexport interface ChatAttachment {\n name: string;\n mediaType: string;\n size: number;\n url: string;\n}\n\nexport interface ChatAttachmentCapabilities {\n input: readonly string[];\n model: string;\n}\n\nexport interface ToolInfo {\n id: string;\n name: string;\n arguments: string;\n result?: string;\n isError?: boolean;\n}\n\nexport interface ChatTextCursor {\n conversationId: string;\n sequence: number;\n /** Accumulated non-whitespace UTF-16 units in the turn anchored by sequence. */\n offset: number;\n}\n\nexport interface ChatJournalCursor {\n conversationId: string;\n eventId: string;\n sequence: number;\n}\n\n/**\n * Eine Aktion, die auf eine Eingabe des Benutzers wartet. Form und Inhalt von `payload` und\n * `result` geh\u00F6ren dem Plugin in `owner`; `status` gesetzt hei\u00DFt: erledigt, die Karte ist Beleg.\n */\nexport interface PendingAction {\n actionId: string;\n owner: string | null;\n payload: unknown;\n status?: \"approved\" | \"dismissed\";\n result?: unknown;\n}\n\nexport interface Message {\n key: string;\n role: Role;\n /** Absenderkennung f\u00FCr die Darstellung; unabh\u00E4ngig von Rolle und Sprechblasenlabel. */\n sender?: string;\n text: string;\n textCursor?: ChatTextCursor;\n closed?: boolean;\n attachments?: ChatAttachment[];\n tool?: ToolInfo;\n action?: PendingAction;\n /** ISO-Zeitpunkt der Nachricht; Anzeige optional (ChatMessages showTimestamps). */\n at?: string;\n /** Der ActorInput hinter einer eingehenden Nachricht; an ihm h\u00E4ngt die Steering-Markierung. */\n inputId?: string;\n /** Die Nachricht ist in einen schon laufenden Turn eingespeist worden, statt einen eigenen zu beginnen. */\n steered?: boolean;\n /** Farbige Sprechblase statt Fliesstext, z.B. fuer Mehrparteien-Gespraeche. */\n bubble?: { color: string; side: \"start\" | \"end\"; label?: string };\n}\n\nexport interface ChatStartupStatus {\n status: \"preparing\" | \"failed\";\n message: string;\n}\n\nexport type ChatEvent =\n | { kind: \"reset\"; reason?: \"conversation-reset\"; conversationId: string | null }\n | { kind: \"replay-end\"; conversationId: string | null }\n | { kind: \"user\"; text: string; inputId?: string; at?: string; attachments?: ChatAttachment[] }\n | { kind: \"steered\"; inputId: string }\n | { kind: \"text\"; delta: string; at?: string; cursor: ChatTextCursor }\n | { kind: \"thinking\"; delta: string; at?: string }\n | { kind: \"tool\"; id: string; name: string; arguments: string; label?: string; at?: string }\n | { kind: \"tool-result\"; id: string; result: string; isError?: boolean }\n | { kind: \"action\"; actionId: string; owner: string | null; text: string; payload: unknown; at?: string }\n | { kind: \"action-resolved\"; actionId: string; status: \"approved\" | \"dismissed\"; result: unknown }\n | { kind: \"system\"; text: string; at?: string }\n | { kind: \"status\"; running: boolean; startup?: ChatStartupStatus }\n | { kind: \"turn-done\" }\n | { kind: \"plugin\"; pluginId: string; type: string; payload?: unknown; at?: string; journal?: ChatJournalCursor };\n\nlet keyCounter = 0;\n\n// crypto.randomUUID fehlt ausserhalb sicherer Kontexte, etwa bei einem Host unter http.\nconst newKey = (): string => typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n ? crypto.randomUUID()\n : `qsl-${Date.now().toString(36)}-${(keyCounter += 1).toString(36)}`;\n\nfunction openMessageIndex(messages: Message[]): number {\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (!message.closed && (message.role === \"assistant\" || message.role === \"thinking\")) return index;\n }\n return -1;\n}\n\nfunction closeOpen(messages: Message[]): Message[] {\n const index = openMessageIndex(messages);\n if (index === -1) {\n return messages;\n }\n return messages.map((message, position) => position === index ? { ...message, closed: true } : message);\n}\n\nfunction appendDelta(messages: Message[], role: Role, delta: string, at?: string, textCursor?: ChatTextCursor): Message[] {\n const index = openMessageIndex(messages);\n const current = messages[index];\n if (current && current.role === role\n && current.textCursor?.conversationId === textCursor?.conversationId\n && current.textCursor?.sequence === textCursor?.sequence) {\n return messages.map((message, position) => position === index\n ? { ...message, text: message.text + delta, ...(textCursor ? { textCursor } : {}) }\n : message);\n }\n return [...closeOpen(messages), { key: newKey(), role, text: delta, at, ...(textCursor ? { textCursor } : {}) }];\n}\n\n/** Eingehende Nachrichten lassen den laufenden Ausgabeblock offen. */\nexport function applyEvent(messages: Message[], event: ChatEvent): Message[] {\n switch (event.kind) {\n case \"reset\":\n return [];\n case \"user\":\n return [...messages, { key: newKey(), role: \"user\", text: event.text, closed: true, at: event.at,\n ...(event.inputId ? { inputId: event.inputId } : {}),\n ...(event.attachments?.length ? { attachments: event.attachments } : {}) }];\n case \"steered\":\n return messages.map((message) => message.inputId === event.inputId ? { ...message, steered: true } : message);\n case \"text\":\n return appendDelta(messages, \"assistant\", event.delta, event.at, event.cursor);\n case \"thinking\":\n return appendDelta(messages, \"thinking\", event.delta, event.at);\n case \"tool\":\n return [\n ...closeOpen(messages),\n {\n key: newKey(),\n role: \"tool\",\n text: event.label ?? event.name,\n closed: true,\n tool: { id: event.id, name: event.name, arguments: event.arguments },\n at: event.at,\n },\n ];\n case \"tool-result\": {\n const index = messages.map((message) => message.tool?.id).lastIndexOf(event.id);\n return messages.map((message, position) =>\n position === index && message.tool\n ? { ...message, tool: { ...message.tool, result: event.result, isError: event.isError } }\n : message,\n );\n }\n case \"action\":\n return [\n ...closeOpen(messages),\n {\n key: newKey(),\n role: \"action\",\n text: event.text,\n closed: true,\n action: { actionId: event.actionId, owner: event.owner, payload: event.payload },\n at: event.at,\n },\n ];\n case \"action-resolved\":\n return messages.map((message) =>\n message.action?.actionId === event.actionId\n ? { ...message, action: { ...message.action, status: event.status, result: event.result } }\n : message,\n );\n case \"system\":\n return [...closeOpen(messages), { key: newKey(), role: \"system\", text: event.text, closed: true, at: event.at }];\n case \"turn-done\":\n return closeOpen(messages);\n default:\n return messages;\n }\n}\n\nexport function prettyJson(value: string): string {\n try {\n return JSON.stringify(JSON.parse(value), null, 2);\n } catch {\n return value;\n }\n}\n\nexport function compactToolLine(tool: ToolInfo): string {\n const args = tool.arguments.replace(/\\s+/g, \" \").trim();\n const line = args && args !== \"{}\" ? `${tool.name} ${args}` : tool.name;\n return line.length > 160 ? `${line.slice(0, 160)} ...` : line;\n}\n\nexport { MAX_CHAT_ATTACHMENTS, MAX_CHAT_ATTACHMENT_BYTES, MAX_CHAT_REQUEST_BYTES, chatAttachmentMediaType, parseChatAttachments } from \"./chat-attachments\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/events.d.ts
CHANGED
|
@@ -1,4 +1,19 @@
|
|
|
1
|
-
export type Role = "user" | "assistant" | "thinking" | "tool" | "system" | "
|
|
1
|
+
export type Role = "user" | "assistant" | "thinking" | "tool" | "system" | "action";
|
|
2
|
+
export interface ChatAttachmentInput {
|
|
3
|
+
name: string;
|
|
4
|
+
mediaType: string;
|
|
5
|
+
data: string;
|
|
6
|
+
}
|
|
7
|
+
export interface ChatAttachment {
|
|
8
|
+
name: string;
|
|
9
|
+
mediaType: string;
|
|
10
|
+
size: number;
|
|
11
|
+
url: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ChatAttachmentCapabilities {
|
|
14
|
+
input: readonly string[];
|
|
15
|
+
model: string;
|
|
16
|
+
}
|
|
2
17
|
export interface ToolInfo {
|
|
3
18
|
id: string;
|
|
4
19
|
name: string;
|
|
@@ -6,22 +21,45 @@ export interface ToolInfo {
|
|
|
6
21
|
result?: string;
|
|
7
22
|
isError?: boolean;
|
|
8
23
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
24
|
+
export interface ChatTextCursor {
|
|
25
|
+
conversationId: string;
|
|
26
|
+
sequence: number;
|
|
27
|
+
/** Accumulated non-whitespace UTF-16 units in the turn anchored by sequence. */
|
|
28
|
+
offset: number;
|
|
29
|
+
}
|
|
30
|
+
export interface ChatJournalCursor {
|
|
31
|
+
conversationId: string;
|
|
32
|
+
eventId: string;
|
|
33
|
+
sequence: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Eine Aktion, die auf eine Eingabe des Benutzers wartet. Form und Inhalt von `payload` und
|
|
37
|
+
* `result` gehören dem Plugin in `owner`; `status` gesetzt heißt: erledigt, die Karte ist Beleg.
|
|
38
|
+
*/
|
|
39
|
+
export interface PendingAction {
|
|
40
|
+
actionId: string;
|
|
41
|
+
owner: string | null;
|
|
42
|
+
payload: unknown;
|
|
43
|
+
status?: "approved" | "dismissed";
|
|
44
|
+
result?: unknown;
|
|
15
45
|
}
|
|
16
46
|
export interface Message {
|
|
17
47
|
key: string;
|
|
18
48
|
role: Role;
|
|
49
|
+
/** Absenderkennung für die Darstellung; unabhängig von Rolle und Sprechblasenlabel. */
|
|
50
|
+
sender?: string;
|
|
19
51
|
text: string;
|
|
52
|
+
textCursor?: ChatTextCursor;
|
|
20
53
|
closed?: boolean;
|
|
54
|
+
attachments?: ChatAttachment[];
|
|
21
55
|
tool?: ToolInfo;
|
|
22
|
-
|
|
56
|
+
action?: PendingAction;
|
|
23
57
|
/** ISO-Zeitpunkt der Nachricht; Anzeige optional (ChatMessages showTimestamps). */
|
|
24
58
|
at?: string;
|
|
59
|
+
/** Der ActorInput hinter einer eingehenden Nachricht; an ihm hängt die Steering-Markierung. */
|
|
60
|
+
inputId?: string;
|
|
61
|
+
/** Die Nachricht ist in einen schon laufenden Turn eingespeist worden, statt einen eigenen zu beginnen. */
|
|
62
|
+
steered?: boolean;
|
|
25
63
|
/** Farbige Sprechblase statt Fliesstext, z.B. fuer Mehrparteien-Gespraeche. */
|
|
26
64
|
bubble?: {
|
|
27
65
|
color: string;
|
|
@@ -29,16 +67,31 @@ export interface Message {
|
|
|
29
67
|
label?: string;
|
|
30
68
|
};
|
|
31
69
|
}
|
|
70
|
+
export interface ChatStartupStatus {
|
|
71
|
+
status: "preparing" | "failed";
|
|
72
|
+
message: string;
|
|
73
|
+
}
|
|
32
74
|
export type ChatEvent = {
|
|
33
75
|
kind: "reset";
|
|
76
|
+
reason?: "conversation-reset";
|
|
77
|
+
conversationId: string | null;
|
|
78
|
+
} | {
|
|
79
|
+
kind: "replay-end";
|
|
80
|
+
conversationId: string | null;
|
|
34
81
|
} | {
|
|
35
82
|
kind: "user";
|
|
36
83
|
text: string;
|
|
84
|
+
inputId?: string;
|
|
37
85
|
at?: string;
|
|
86
|
+
attachments?: ChatAttachment[];
|
|
87
|
+
} | {
|
|
88
|
+
kind: "steered";
|
|
89
|
+
inputId: string;
|
|
38
90
|
} | {
|
|
39
91
|
kind: "text";
|
|
40
92
|
delta: string;
|
|
41
93
|
at?: string;
|
|
94
|
+
cursor: ChatTextCursor;
|
|
42
95
|
} | {
|
|
43
96
|
kind: "thinking";
|
|
44
97
|
delta: string;
|
|
@@ -56,16 +109,17 @@ export type ChatEvent = {
|
|
|
56
109
|
result: string;
|
|
57
110
|
isError?: boolean;
|
|
58
111
|
} | {
|
|
59
|
-
kind: "
|
|
60
|
-
|
|
112
|
+
kind: "action";
|
|
113
|
+
actionId: string;
|
|
114
|
+
owner: string | null;
|
|
61
115
|
text: string;
|
|
62
|
-
|
|
63
|
-
multi?: boolean;
|
|
116
|
+
payload: unknown;
|
|
64
117
|
at?: string;
|
|
65
118
|
} | {
|
|
66
|
-
kind: "
|
|
67
|
-
|
|
68
|
-
|
|
119
|
+
kind: "action-resolved";
|
|
120
|
+
actionId: string;
|
|
121
|
+
status: "approved" | "dismissed";
|
|
122
|
+
result: unknown;
|
|
69
123
|
} | {
|
|
70
124
|
kind: "system";
|
|
71
125
|
text: string;
|
|
@@ -73,16 +127,19 @@ export type ChatEvent = {
|
|
|
73
127
|
} | {
|
|
74
128
|
kind: "status";
|
|
75
129
|
running: boolean;
|
|
130
|
+
startup?: ChatStartupStatus;
|
|
76
131
|
} | {
|
|
77
132
|
kind: "turn-done";
|
|
78
133
|
} | {
|
|
79
|
-
kind: "
|
|
134
|
+
kind: "plugin";
|
|
80
135
|
pluginId: string;
|
|
81
136
|
type: string;
|
|
82
137
|
payload?: unknown;
|
|
83
138
|
at?: string;
|
|
139
|
+
journal?: ChatJournalCursor;
|
|
84
140
|
};
|
|
85
|
-
/**
|
|
141
|
+
/** Eingehende Nachrichten lassen den laufenden Ausgabeblock offen. */
|
|
86
142
|
export declare function applyEvent(messages: Message[], event: ChatEvent): Message[];
|
|
87
143
|
export declare function prettyJson(value: string): string;
|
|
88
144
|
export declare function compactToolLine(tool: ToolInfo): string;
|
|
145
|
+
export { MAX_CHAT_ATTACHMENTS, MAX_CHAT_ATTACHMENT_BYTES, MAX_CHAT_REQUEST_BYTES, chatAttachmentMediaType, parseChatAttachments } from "./chat-attachments";
|
package/events.js
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
|
+
MAX_CHAT_ATTACHMENTS,
|
|
3
|
+
MAX_CHAT_ATTACHMENT_BYTES,
|
|
4
|
+
MAX_CHAT_REQUEST_BYTES,
|
|
2
5
|
applyEvent,
|
|
6
|
+
chatAttachmentMediaType,
|
|
3
7
|
compactToolLine,
|
|
8
|
+
parseChatAttachments,
|
|
4
9
|
prettyJson
|
|
5
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-IGCFQJZB.js";
|
|
6
11
|
export {
|
|
12
|
+
MAX_CHAT_ATTACHMENTS,
|
|
13
|
+
MAX_CHAT_ATTACHMENT_BYTES,
|
|
14
|
+
MAX_CHAT_REQUEST_BYTES,
|
|
7
15
|
applyEvent,
|
|
16
|
+
chatAttachmentMediaType,
|
|
8
17
|
compactToolLine,
|
|
18
|
+
parseChatAttachments,
|
|
9
19
|
prettyJson
|
|
10
20
|
};
|
|
11
21
|
//# sourceMappingURL=events.js.map
|
package/index.d.ts
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
export type { Role, ToolInfo,
|
|
1
|
+
export type { Role, ToolInfo, PendingAction, Message, ChatEvent, ChatTextCursor, ChatJournalCursor, ChatAttachment, ChatAttachmentInput, ChatAttachmentCapabilities, ChatStartupStatus, DetailMode, StepState, ChatAnnouncement, } from "./types";
|
|
2
2
|
export { applyEvent, prettyJson, compactToolLine, stepState } from "./types";
|
|
3
3
|
export type { ChatTexts } from "./texts";
|
|
4
|
-
export { defaultTexts } from "./texts";
|
|
5
|
-
export { useChat } from "./useChat";
|
|
4
|
+
export { defaultTexts, fillText } from "./texts";
|
|
6
5
|
export { ChatMessages } from "./ChatMessages";
|
|
7
6
|
export { ChatPanel } from "./ChatPanel";
|
|
7
|
+
export { ChatInputToolbar, type ChatInputHandle, type ToolbarAction } from "./ChatInputToolbar";
|
|
8
|
+
export { DetailModeSwitch, DETAIL_MODES, detailModeLabel } from "./DetailModeSwitch";
|
|
8
9
|
export { TimestampSwitch } from "./TimestampSwitch";
|
|
9
|
-
export {
|
|
10
|
-
export
|
|
11
|
-
export {
|
|
10
|
+
export { Markdown, MarkdownCodeBlocks, MarkdownLinks, markdownPlainText, type LinkClickHandler } from "./Markdown";
|
|
11
|
+
export { MessageActions } from "./MessageActions";
|
|
12
|
+
export { PendingActionCard } from "./PendingActionCard";
|
|
13
|
+
export { StepPopover } from "./StepPopover";
|
|
14
|
+
export { WorkingScenes, type WorkingScenesProps } from "./WorkingScenes";
|
|
12
15
|
export { announce } from "./announce";
|
|
13
|
-
export
|
|
14
|
-
export
|
|
15
|
-
export {
|
|
16
|
-
export {
|
|
16
|
+
export { useChatAction, copyChatText } from "./useChatAction";
|
|
17
|
+
export { createChatScroll } from "./chat-scroll";
|
|
18
|
+
export { ChatSendContext, createChatSendScope, type ChatSendScope } from "./ChatSendContext";
|
|
19
|
+
export { messageDate, timestampDay, timestampLabel } from "./timestamps";
|
|
20
|
+
export { attachmentCapabilityError, attachmentDownloadUrl, attachmentMediaType, encodeAttachment, formatAttachmentSize, validateAttachmentSelection, MAX_CHAT_ATTACHMENTS, MAX_CHAT_ATTACHMENT_BYTES, } from "./attachments";
|
|
21
|
+
export type { ChatAppearance, TimestampOptions, CodeBlockOptions, BubbleOptions, MessageAction, MessageActionsOptions, SendShortcut, } from "./options";
|
|
22
|
+
export { appearanceStyle } from "./options";
|
|
23
|
+
export { QuasselProvider, defaultComponents, useQuasselComponents, type QuasselComponents, type QuasselButtonProps, type QuasselButtonVariant, type QuasselButtonSize, type QuasselToggleProps, type QuasselCardProps, type QuasselStopButtonProps, type QuasselPopoverProps, type QuasselPopoverContentProps, type QuasselPopoverAnchor, } from "./QuasselProvider";
|