quassel 0.1.0 → 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.
Files changed (59) hide show
  1. package/ChatInputToolbar.d.ts +35 -6
  2. package/ChatMessages.d.ts +19 -15
  3. package/ChatPanel.d.ts +4 -2
  4. package/ChatSendContext.d.ts +7 -12
  5. package/DetailModeSwitch.d.ts +1 -1
  6. package/Markdown.d.ts +4 -11
  7. package/MessageActions.d.ts +1 -10
  8. package/PendingActionCard.d.ts +13 -0
  9. package/QuasselProvider.d.ts +76 -0
  10. package/README.md +39 -38
  11. package/StepPopover.d.ts +1 -1
  12. package/TimestampSwitch.d.ts +2 -2
  13. package/WorkingScenes.d.ts +3 -1
  14. package/attachments.d.ts +24 -0
  15. package/chat-attachments.d.ts +6 -0
  16. package/chat-scroll.d.ts +12 -0
  17. package/chat.css +2051 -0
  18. package/chunk-IGCFQJZB.js +183 -0
  19. package/chunk-IGCFQJZB.js.map +7 -0
  20. package/events.d.ts +74 -17
  21. package/events.js +11 -1
  22. package/index.d.ts +17 -10
  23. package/index.js +1615 -980
  24. package/index.js.map +4 -4
  25. package/options.d.ts +1 -1
  26. package/package.json +12 -10
  27. package/texts.d.ts +38 -11
  28. package/timestamps.d.ts +6 -4
  29. package/types.d.ts +6 -6
  30. package/ui/button.d.ts +8 -0
  31. package/ui/card.d.ts +5 -0
  32. package/ui/cn.d.ts +2 -0
  33. package/ui/popover.d.ts +4 -0
  34. package/ui/spinner.d.ts +2 -0
  35. package/ui/stop-button.d.ts +10 -0
  36. package/ui/toggle.d.ts +8 -0
  37. package/ui/useFileInput.d.ts +20 -0
  38. package/useChatAction.d.ts +6 -0
  39. package/QuestionCard.d.ts +0 -12
  40. package/chunk-DOLTANTM.js +0 -84
  41. package/chunk-DOLTANTM.js.map +0 -7
  42. package/css/chat.css +0 -927
  43. package/css/foundation/base.css +0 -24
  44. package/css/foundation/index.css +0 -3
  45. package/css/foundation/panel.css +0 -111
  46. package/css/foundation/tokens.css +0 -68
  47. package/css/foundation/wash.css +0 -26
  48. package/css/question.css +0 -149
  49. package/icons.d.ts +0 -15
  50. package/server/http.d.ts +0 -17
  51. package/server/index.d.ts +0 -6
  52. package/server/index.js +0 -478
  53. package/server/index.js.map +0 -7
  54. package/server/manager.d.ts +0 -12
  55. package/server/openai.d.ts +0 -16
  56. package/server/session.d.ts +0 -27
  57. package/server/store.d.ts +0 -18
  58. package/server/types.d.ts +0 -62
  59. package/useChat.d.ts +0 -14
package/options.d.ts CHANGED
@@ -39,4 +39,4 @@ export interface MessageActionsOptions {
39
39
  custom?: (message: Message) => readonly MessageAction[];
40
40
  }
41
41
  export type SendShortcut = "enter" | "mod-enter";
42
- export declare function appearanceStyle(appearance?: ChatAppearance): CSSProperties;
42
+ export declare const appearanceStyle: (appearance?: ChatAppearance) => CSSProperties;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "quassel",
3
- "version": "0.1.0",
4
- "description": "Composable chat building blocks for React: streaming transcript, steps, questions, inputs, CSS foundation and event contract",
3
+ "version": "0.2.0",
4
+ "description": "Chat building blocks for React: streaming transcript with thinking and tool steps, input card, themable Tailwind styles and an event contract",
5
5
  "license": "MIT",
6
6
  "author": "Ronald Schlenker",
7
7
  "repository": {
@@ -15,7 +15,8 @@
15
15
  "llm",
16
16
  "agent",
17
17
  "streaming",
18
- "ui"
18
+ "ui",
19
+ "tailwind"
19
20
  ],
20
21
  "type": "module",
21
22
  "sideEffects": [
@@ -30,13 +31,14 @@
30
31
  "types": "./events.d.ts",
31
32
  "default": "./events.js"
32
33
  },
33
- "./server": {
34
- "types": "./server/index.d.ts",
35
- "default": "./server/index.js"
36
- },
37
- "./chat.css": "./css/chat.css",
38
- "./foundation.css": "./css/foundation/index.css",
39
- "./base.css": "./css/foundation/base.css"
34
+ "./chat.css": "./chat.css"
35
+ },
36
+ "dependencies": {
37
+ "@base-ui/react": "^1.8.0",
38
+ "class-variance-authority": "^0.7.1",
39
+ "cn": "^0.3.0",
40
+ "lucide-react": "^1.46.0",
41
+ "streamdown": "^2.6.0"
40
42
  },
41
43
  "peerDependencies": {
42
44
  "react": "^18 || ^19",
package/texts.d.ts CHANGED
@@ -2,7 +2,9 @@ export interface ChatTexts {
2
2
  working: string;
3
3
  toolRunning: string;
4
4
  toolStillRunning: string;
5
+ currentTool: string;
5
6
  thinkingChip: string;
7
+ toolChip: string;
6
8
  stepGroupOne: string;
7
9
  stepGroupMany: string;
8
10
  stepGroupCollapse: string;
@@ -17,23 +19,48 @@ export interface ChatTexts {
17
19
  stop: string;
18
20
  placeholder: string;
19
21
  steeringPlaceholder: string;
20
- timestamps: string;
21
- messageActions: string;
22
- questionSubmit: string;
23
- questionPlaceholder: string;
24
- questionAnswer: string;
25
- copyMessage: string;
26
- copyCode: string;
27
- copied: string;
28
- copyFailed: string;
29
- editMessage: string;
30
- retryMessage: string;
22
+ steered: string;
23
+ inputHint: string;
31
24
  detailModeTitle: string;
32
25
  detailModeOff: string;
26
+ detailModeCurrent: string;
33
27
  detailModeIcons: string;
34
28
  detailModeChips: string;
35
29
  detailModeGrouped: string;
36
30
  detailModeCompact: string;
37
31
  detailModeFull: string;
32
+ timestamps: string;
33
+ showTimestamps: string;
34
+ hideTimestamps: string;
35
+ copyMessage: string;
36
+ editMessage: string;
37
+ retryMessage: string;
38
+ copyCode: string;
39
+ copied: string;
40
+ pendingAction: string;
41
+ dismissAction: string;
42
+ actionDismissed: string;
43
+ actionFailed: string;
44
+ clipboardUnavailable: string;
45
+ transcript: string;
46
+ attachments: string;
47
+ attachFiles: string;
48
+ attachFilesHint: string;
49
+ removeAttachment: string;
50
+ attachmentPreparing: string;
51
+ attachmentsPreparing: string;
52
+ attachmentReadFailed: string;
53
+ attachmentsWhileBusy: string;
54
+ tooManyAttachments: string;
55
+ attachmentsTooLarge: string;
56
+ attachmentUnsupported: string;
57
+ attachmentUnsupportedByModel: string;
58
+ attachmentKindImage: string;
59
+ attachmentKindVideo: string;
60
+ attachmentKindPdf: string;
61
+ notSent: string;
62
+ notSentAttachments: string;
63
+ insertUnsent: string;
38
64
  }
65
+ export declare const fillText: (text: string, values: Record<string, string | number>) => string;
39
66
  export declare const defaultTexts: ChatTexts;
package/timestamps.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import type { TimestampOptions } from "./options";
2
- export declare function timestampDate(at?: string): Date | undefined;
3
- export declare function formatTimestamp(date: Date, options?: TimestampOptions, now?: number): string;
4
- export declare function timestampDay(date: Date, timeZone?: string): string;
5
- export declare function formatDay(date: Date, options?: TimestampOptions): string;
2
+ export declare function messageDate(at: string | undefined): Date | undefined;
3
+ export declare function timestampLabel(date: Date, options?: TimestampOptions, now?: number): string;
4
+ export declare function timestampDay(date: Date, options?: TimestampOptions): {
5
+ key: string;
6
+ label: string;
7
+ };
package/types.d.ts CHANGED
@@ -1,22 +1,22 @@
1
1
  import type { Message } from "./events";
2
- export type { Role, ToolInfo, Question, Message, ChatEvent } from "./events";
2
+ export type { Role, ToolInfo, PendingAction, Message, ChatEvent, ChatTextCursor, ChatJournalCursor, ChatAttachment, ChatAttachmentInput, ChatAttachmentCapabilities, ChatStartupStatus } from "./events";
3
3
  export { applyEvent, prettyJson, compactToolLine } from "./events";
4
4
  /**
5
- * off = nur Antworten, icons = Schritte als reine Symbole nebeneinander,
5
+ * current = nur der laufende Schritt, off = nur Antworten, icons = Schritte als reine Symbole nebeneinander,
6
6
  * chips = Schritte als Symbol + Kurztext nebeneinander (mit Umbruch),
7
- * grouped = aufeinanderfolgende Schritte hinter einer aufklappbaren Kopfzeile, darin einzeilig,
7
+ * grouped = aufeinanderfolgende Schritte als eine aufklappbare Zeile, dahinter einzeilig,
8
8
  * compact = Denken und Werkzeuge einzeilig, full = alles ausgeklappt.
9
9
  */
10
- export type DetailMode = "off" | "icons" | "chips" | "grouped" | "compact" | "full";
10
+ export type DetailMode = "off" | "current" | "icons" | "chips" | "grouped" | "compact" | "full";
11
11
  /** running = call still open, thinking = thought block still open, done = finished, error = failed. */
12
12
  export type StepState = "running" | "thinking" | "done" | "error";
13
13
  /** The single derivation of a step state, so chips, hosts and tests read the same signal. */
14
14
  export declare function stepState(message: Message): StepState;
15
- /** A moment worth one screen reader announcement: a finished reply or a new open question. */
15
+ /** A moment worth one screen reader announcement: a finished reply or a new pending action. */
16
16
  export type ChatAnnouncement = {
17
17
  kind: "reply";
18
18
  message: Message;
19
19
  } | {
20
- kind: "question";
20
+ kind: "action";
21
21
  message: Message;
22
22
  };
package/ui/button.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { Button as ButtonPrimitive } from "@base-ui/react/button";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const buttonVariants: (props?: ({
4
+ variant?: "link" | "default" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
5
+ size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ declare function Button({ className, variant, size, ...props }: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>): import("react").JSX.Element;
8
+ export { Button, buttonVariants };
package/ui/card.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import * as React from "react";
2
+ declare function Card({ className, size, ...props }: React.ComponentProps<"div"> & {
3
+ size?: "default" | "sm";
4
+ }): React.JSX.Element;
5
+ export { Card };
package/ui/cn.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { CnFunction } from "cn";
2
+ export declare const cn: CnFunction;
@@ -0,0 +1,4 @@
1
+ import { Popover as PopoverPrimitive } from "@base-ui/react/popover";
2
+ declare function Popover({ ...props }: PopoverPrimitive.Root.Props): import("react").JSX.Element;
3
+ declare function PopoverContent({ className, align, alignOffset, side, sideOffset, anchor, collisionPadding, keepMounted, ...props }: PopoverPrimitive.Popup.Props & Pick<PopoverPrimitive.Positioner.Props, "align" | "alignOffset" | "side" | "sideOffset" | "anchor" | "collisionPadding"> & Pick<PopoverPrimitive.Portal.Props, "keepMounted">): import("react").JSX.Element;
4
+ export { Popover, PopoverContent };
@@ -0,0 +1,2 @@
1
+ declare function Spinner({ className, ...props }: React.ComponentProps<"svg">): import("react").JSX.Element;
2
+ export { Spinner };
@@ -0,0 +1,10 @@
1
+ import { SquareIcon } from "lucide-react";
2
+ import type { ComponentProps } from "react";
3
+ import { Button } from "./button";
4
+ /** Die eine Stopp-Glyphe: ein gefülltes rotes Quadrat; ein Zustandssymbol trägt sie nie. */
5
+ export declare function StopGlyph({ className, ...props }: Omit<ComponentProps<typeof SquareIcon>, "fill">): import("react").JSX.Element;
6
+ /** Jeder Stopp-Knopf sieht gleich aus: die Glyphe als Symbol, das Wort im Tooltip, rot in Ruhe und beim Hover. */
7
+ export declare function StopButton({ label, busy, className, title, ...props }: Omit<ComponentProps<typeof Button>, "children" | "variant"> & {
8
+ label: string;
9
+ busy?: boolean;
10
+ }): import("react").JSX.Element;
package/ui/toggle.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import { Toggle as TogglePrimitive } from "@base-ui/react/toggle";
2
+ import { type VariantProps } from "class-variance-authority";
3
+ declare const toggleVariants: (props?: ({
4
+ variant?: "default" | "outline" | null | undefined;
5
+ size?: "default" | "sm" | "lg" | null | undefined;
6
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
+ declare function Toggle({ className, variant, size, ...props }: TogglePrimitive.Props & VariantProps<typeof toggleVariants>): import("react").JSX.Element;
8
+ export { Toggle, toggleVariants };
@@ -0,0 +1,20 @@
1
+ import { type ChangeEvent, type ClipboardEvent, type DragEvent } from "react";
2
+ export declare function useFileInput({ disabled, onFiles, onPasteText }: {
3
+ disabled?: boolean;
4
+ onFiles: (files: File[]) => void | Promise<void>;
5
+ onPasteText?: (text: string) => void;
6
+ }): {
7
+ inputRef: import("react").RefObject<HTMLInputElement | null>;
8
+ dragging: boolean;
9
+ clearDragging: () => void;
10
+ inputProps: {
11
+ ref: import("react").RefObject<HTMLInputElement | null>;
12
+ onChange: (event: ChangeEvent<HTMLInputElement>) => void;
13
+ };
14
+ dropProps: {
15
+ onDragOver: (event: DragEvent<HTMLElement>) => void;
16
+ onDragLeave: (event: DragEvent<HTMLElement>) => void;
17
+ onDrop: (event: DragEvent<HTMLElement>) => void;
18
+ onPaste: (event: ClipboardEvent<HTMLElement>) => void;
19
+ };
20
+ };
@@ -0,0 +1,6 @@
1
+ export declare function useChatAction(): {
2
+ status: "done" | "idle" | "pending";
3
+ error: string | undefined;
4
+ invoke: (action: () => void | Promise<void>, failureLabel: string) => Promise<void>;
5
+ };
6
+ export declare function copyChatText(text: string, unavailable: string): Promise<void>;
package/QuestionCard.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import { Question } from "./types";
2
- import type { ChatTexts } from "./texts";
3
- /**
4
- * Rückfrage-Karte: Optionen untereinander, wahlweise Einzel- oder Mehrfachauswahl
5
- * (question.multi), dazu immer eine freie Antwortzeile. Nach der Antwort nur noch Beleg.
6
- */
7
- export declare function QuestionCard({ text, question, texts, onAnswer, }: {
8
- text: string;
9
- question: Question;
10
- texts: ChatTexts;
11
- onAnswer: (text: string) => void;
12
- }): import("react").JSX.Element;
package/chunk-DOLTANTM.js DELETED
@@ -1,84 +0,0 @@
1
- // packages/quassel/src/events.ts
2
- function closeLast(messages) {
3
- const last = messages[messages.length - 1];
4
- if (!last || last.closed) {
5
- return messages;
6
- }
7
- return [...messages.slice(0, -1), { ...last, closed: true }];
8
- }
9
- function appendDelta(messages, role, delta, at) {
10
- const last = messages[messages.length - 1];
11
- if (last && last.role === role && !last.closed) {
12
- return [...messages.slice(0, -1), { ...last, text: last.text + delta }];
13
- }
14
- return [...closeLast(messages), { key: crypto.randomUUID(), role, text: delta, at }];
15
- }
16
- function applyEvent(messages, event) {
17
- switch (event.kind) {
18
- case "reset":
19
- return [];
20
- case "user":
21
- return [...closeLast(messages), { key: crypto.randomUUID(), role: "user", text: event.text, at: event.at }];
22
- case "text":
23
- return appendDelta(messages, "assistant", event.delta, event.at);
24
- case "thinking":
25
- return appendDelta(messages, "thinking", event.delta, event.at);
26
- case "tool":
27
- return [
28
- ...closeLast(messages),
29
- {
30
- key: crypto.randomUUID(),
31
- role: "tool",
32
- text: event.label ?? event.name,
33
- closed: true,
34
- tool: { id: event.id, name: event.name, arguments: event.arguments },
35
- at: event.at
36
- }
37
- ];
38
- case "tool-result":
39
- return messages.map(
40
- (message) => message.tool?.id === event.id ? { ...message, tool: { ...message.tool, result: event.result, isError: event.isError } } : message
41
- );
42
- case "question":
43
- return [
44
- ...closeLast(messages),
45
- {
46
- key: crypto.randomUUID(),
47
- role: "question",
48
- text: event.text,
49
- closed: true,
50
- question: { callId: event.callId, options: event.options, multi: event.multi },
51
- at: event.at
52
- }
53
- ];
54
- case "question-answered":
55
- return messages.map(
56
- (message) => message.question?.callId === event.callId ? { ...message, question: { ...message.question, answer: event.answer } } : message
57
- );
58
- case "system":
59
- return [...closeLast(messages), { key: crypto.randomUUID(), role: "system", text: event.text, closed: true, at: event.at }];
60
- case "turn-done":
61
- return closeLast(messages);
62
- default:
63
- return messages;
64
- }
65
- }
66
- function prettyJson(value) {
67
- try {
68
- return JSON.stringify(JSON.parse(value), null, 2);
69
- } catch {
70
- return value;
71
- }
72
- }
73
- function compactToolLine(tool) {
74
- const args = tool.arguments.replace(/\s+/g, " ").trim();
75
- const line = args && args !== "{}" ? `${tool.name} ${args}` : tool.name;
76
- return line.length > 160 ? `${line.slice(0, 160)} ...` : line;
77
- }
78
-
79
- export {
80
- applyEvent,
81
- prettyJson,
82
- compactToolLine
83
- };
84
- //# sourceMappingURL=chunk-DOLTANTM.js.map
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../src/events.ts"],
4
- "sourcesContent": ["export type Role = \"user\" | \"assistant\" | \"thinking\" | \"tool\" | \"system\" | \"question\";\n\nexport interface ToolInfo {\n id: string;\n name: string;\n arguments: string;\n result?: string;\n isError?: boolean;\n}\n\n/** Eine R\u00FCckfrage des Assistenten. `answer` gesetzt hei\u00DFt: beantwortet, die Karte ist nur noch Beleg. */\nexport interface Question {\n callId: string;\n options: string[];\n multi?: boolean;\n answer?: string;\n}\n\nexport interface Message {\n key: string;\n role: Role;\n text: string;\n closed?: boolean;\n tool?: ToolInfo;\n question?: Question;\n /** ISO-Zeitpunkt der Nachricht; Anzeige optional (ChatMessages showTimestamps). */\n at?: string;\n /** Farbige Sprechblase statt Fliesstext, z.B. fuer Mehrparteien-Gespraeche. */\n bubble?: { color: string; side: \"start\" | \"end\"; label?: string };\n}\n\nexport type ChatEvent =\n | { kind: \"reset\" }\n | { kind: \"user\"; text: string; at?: string }\n | { kind: \"text\"; delta: string; at?: string }\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: \"question\"; callId: string; text: string; options: string[]; multi?: boolean; at?: string }\n | { kind: \"question-answered\"; callId: string; answer: string }\n | { kind: \"system\"; text: string; at?: string }\n | { kind: \"status\"; running: boolean }\n | { kind: \"turn-done\" }\n | { kind: \"extension\"; pluginId: string; type: string; payload?: unknown; at?: string };\n\nfunction closeLast(messages: Message[]): Message[] {\n const last = messages[messages.length - 1];\n if (!last || last.closed) {\n return messages;\n }\n return [...messages.slice(0, -1), { ...last, closed: true }];\n}\n\nfunction appendDelta(messages: Message[], role: Role, delta: string, at?: string): Message[] {\n const last = messages[messages.length - 1];\n if (last && last.role === role && !last.closed) {\n return [...messages.slice(0, -1), { ...last, text: last.text + delta }];\n }\n return [...closeLast(messages), { key: crypto.randomUUID(), role, text: delta, at }];\n}\n\n/** Der Streaming-Kern: Deltas verschmelzen mit dem letzten offenen Block, alles andere schlie\u00DFt ihn. */\nexport function applyEvent(messages: Message[], event: ChatEvent): Message[] {\n switch (event.kind) {\n case \"reset\":\n return [];\n case \"user\":\n return [...closeLast(messages), { key: crypto.randomUUID(), role: \"user\", text: event.text, at: event.at }];\n case \"text\":\n return appendDelta(messages, \"assistant\", event.delta, event.at);\n case \"thinking\":\n return appendDelta(messages, \"thinking\", event.delta, event.at);\n case \"tool\":\n return [\n ...closeLast(messages),\n {\n key: crypto.randomUUID(),\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 return messages.map((message) =>\n message.tool?.id === event.id\n ? { ...message, tool: { ...message.tool, result: event.result, isError: event.isError } }\n : message,\n );\n case \"question\":\n return [\n ...closeLast(messages),\n {\n key: crypto.randomUUID(),\n role: \"question\",\n text: event.text,\n closed: true,\n question: { callId: event.callId, options: event.options, multi: event.multi },\n at: event.at,\n },\n ];\n case \"question-answered\":\n return messages.map((message) =>\n message.question?.callId === event.callId\n ? { ...message, question: { ...message.question, answer: event.answer } }\n : message,\n );\n case \"system\":\n return [...closeLast(messages), { key: crypto.randomUUID(), role: \"system\", text: event.text, closed: true, at: event.at }];\n case \"turn-done\":\n return closeLast(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"],
5
- "mappings": "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",
6
- "names": []
7
- }