@smarter.sh/ui-chat 0.3.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +126 -173
- package/dist/smarter-chat-library.es.js +44286 -12088
- package/dist/smarter-chat-library.es.js.map +1 -1
- package/dist/smarter-chat-library.umd.js +340 -121
- package/dist/smarter-chat-library.umd.js.map +1 -1
- package/dist/types/src/components/AppTitle/Component.d.ts +13 -0
- package/dist/types/src/components/AppTitle/index.d.ts +2 -0
- package/dist/types/src/components/Console/Component.d.ts +17 -0
- package/dist/types/src/components/Console/ServerLogs.d.ts +8 -0
- package/dist/types/src/components/Console/data.d.ts +7 -0
- package/dist/types/src/components/Console/enums.d.ts +9 -0
- package/dist/types/src/components/Console/index.d.ts +2 -0
- package/dist/types/src/components/ErrorBoundary/Component.d.ts +17 -0
- package/dist/types/src/components/ErrorBoundary/index.d.ts +2 -0
- package/dist/types/src/components/SmarterChat/Component.d.ts +26 -0
- package/dist/types/src/components/SmarterChat/icons.d.ts +17 -0
- package/dist/types/src/components/SmarterChat/index.d.ts +2 -0
- package/dist/types/src/const.d.ts +5 -0
- package/dist/types/src/index.d.ts +12 -0
- package/dist/types/src/lib/ansi.d.ts +33 -0
- package/dist/types/src/lib/api.d.ts +73 -0
- package/dist/types/src/lib/code.d.ts +32 -0
- package/dist/types/src/lib/cookie.d.ts +17 -0
- package/dist/types/src/lib/enums.d.ts +26 -0
- package/dist/types/src/lib/layout.d.ts +42 -0
- package/dist/types/src/lib/logStream.d.ts +30 -0
- package/dist/types/src/lib/math.d.ts +18 -0
- package/dist/types/src/lib/mermaid.d.ts +27 -0
- package/dist/types/src/lib/messages.d.ts +52 -0
- package/dist/types/src/types.d.ts +143 -0
- package/dist/ui-chat.css +2 -1
- package/package.json +87 -59
- package/src/components/Console/Component.css +0 -47
- package/src/components/Console/Component.jsx +0 -186
- package/src/components/Console/HeadStyles.jsx +0 -20
- package/src/components/Console/enums.js +0 -7
- package/src/components/Console/index.js +0 -2
- package/src/components/ErrorModal/ErrorModal.css +0 -35
- package/src/components/ErrorModal/ErrorModal.jsx +0 -56
- package/src/components/ErrorModal/index.js +0 -3
- package/src/components/SmarterChat/Component.jsx +0 -431
- package/src/components/SmarterChat/ErrorBoundary.jsx +0 -32
- package/src/components/SmarterChat/Layout.js +0 -47
- package/src/components/SmarterChat/api.js +0 -200
- package/src/components/SmarterChat/enums.js +0 -17
- package/src/components/SmarterChat/index.js +0 -3
- package/src/components/SmarterChat/styles.css +0 -152
- package/src/components/SmarterChat/utils.jsx +0 -148
- package/src/components/enums.js +0 -1
- package/src/components/index.js +0 -3
- package/src/components/shared/cookie.js +0 -51
- package/src/constants.js +0 -2
- package/src/index.js +0 -4
- package/src/types/index.js +0 -2
- package/src/types/propTypes.js +0 -154
- package/src/version.js +0 -2
- package/types/index.d.ts +0 -17
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat's title: the LLMClient's app name and version, with icons for whether it is valid, and
|
|
3
|
+
* whether it is deployed or is still in the sandbox.
|
|
4
|
+
*/
|
|
5
|
+
import "@/components/AppTitle/styles.css";
|
|
6
|
+
interface AppTitleProps {
|
|
7
|
+
title: string;
|
|
8
|
+
isReady: boolean;
|
|
9
|
+
isValid: boolean;
|
|
10
|
+
isDeployed: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare function AppTitle({ title, isReady, isValid, isDeployed }: AppTitleProps): import("react").JSX.Element;
|
|
13
|
+
export default AppTitle;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ConsoleConfig } from "@/components/Console/data";
|
|
2
|
+
import "@/components/Console/styles.css";
|
|
3
|
+
interface ConsoleProps {
|
|
4
|
+
/** The LLMClient's configuration, from its config api. Empty until it loads. */
|
|
5
|
+
config: ConsoleConfig;
|
|
6
|
+
/** The url of the user's server log stream. Without it, there is no "Server Logs" tab. */
|
|
7
|
+
logStreamUrl?: string | null;
|
|
8
|
+
/**
|
|
9
|
+
* The minimum log level of the server logs, e.g. "DEBUG" in sandbox mode. Without it, the server's
|
|
10
|
+
* own log level. A change reconnects the stream, which replays the history at the new level.
|
|
11
|
+
*/
|
|
12
|
+
logLevel?: string | null;
|
|
13
|
+
/** Changes when a new chat session starts, which clears the server logs. */
|
|
14
|
+
resetKey?: number | string;
|
|
15
|
+
}
|
|
16
|
+
declare function Console({ config, logStreamUrl, logLevel, resetKey }: ConsoleProps): import("react").JSX.Element;
|
|
17
|
+
export default Console;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** The data that the Console displays for each of its menu items. */
|
|
2
|
+
import type { ChatConfig } from "../../types";
|
|
3
|
+
import { type MenuItem } from "./enums";
|
|
4
|
+
/** The LLMClient's configuration, from its config api. Empty until it loads. */
|
|
5
|
+
export type ConsoleConfig = ChatConfig | Record<string, never> | null;
|
|
6
|
+
/** The JSON objects to display for a menu item. */
|
|
7
|
+
export declare function consoleData(config: ConsoleConfig, item: MenuItem): object[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** The Console's menu items: the configuration, the chat session's histories, and the server logs. */
|
|
2
|
+
export declare const MenuItems: {
|
|
3
|
+
readonly CHAT_CONFIG: "chat_config";
|
|
4
|
+
readonly LLMCLIENT_REQUEST_HISTORY: "llmclient_request_history";
|
|
5
|
+
readonly CHAT_TOOL_CALL_HISTORY: "chat_tool_call_history";
|
|
6
|
+
readonly CHAT_PLUGIN_USAGE_HISTORY: "chat_plugin_usage_history";
|
|
7
|
+
readonly SERVER_LOGS: "server_logs";
|
|
8
|
+
};
|
|
9
|
+
export type MenuItem = (typeof MenuItems)[keyof typeof MenuItems];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Catches a rendering error in its children, and displays a message instead of an empty page.
|
|
3
|
+
*/
|
|
4
|
+
import { Component, type ErrorInfo, type ReactNode } from "react";
|
|
5
|
+
interface ErrorBoundaryProps {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
interface ErrorBoundaryState {
|
|
9
|
+
error: Error | null;
|
|
10
|
+
}
|
|
11
|
+
declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
12
|
+
state: ErrorBoundaryState;
|
|
13
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
14
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
15
|
+
render(): string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
16
|
+
}
|
|
17
|
+
export default ErrorBoundary;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SmarterChat: a chat with a Smarter LLMClient, with an optional Console beside it.
|
|
3
|
+
*
|
|
4
|
+
* It fetches the LLMClient's configuration, which includes the chat session's history, then sends
|
|
5
|
+
* the chat thread to the LLMClient's prompt api with each new message, and adds the response's
|
|
6
|
+
* messages to the thread. Failed prompts are displayed in the thread, as "smarter_error" messages.
|
|
7
|
+
* While a prompt runs, its progress (e.g. its tool calls and MCP server requests) is displayed in
|
|
8
|
+
* the thread, with a spinner beside its current step, and is replaced by the response's messages
|
|
9
|
+
* when it finishes. Code blocks in messages
|
|
10
|
+
* are syntax highlighted, and have a copy button.
|
|
11
|
+
*
|
|
12
|
+
* The user can resize the chat and the Console by dragging the separator between them, and can
|
|
13
|
+
* hide the Console, which slides out to the right. In sandbox mode, the thread also displays
|
|
14
|
+
* Smarter's system, tool and meta data messages. In production mode, it displays only the
|
|
15
|
+
* conversation, as the LLMClient's users see it. The Console's server logs follow the mode: DEBUG
|
|
16
|
+
* and above in sandbox mode, and the server's own log level in production mode. A new chat also
|
|
17
|
+
* clears the Console's server logs.
|
|
18
|
+
*
|
|
19
|
+
* This is the component that the @smarter.sh/ui-chat npm package exports, and that the Smarter web
|
|
20
|
+
* console's LLMClient prompt workbench renders. See main.tsx.
|
|
21
|
+
*/
|
|
22
|
+
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
|
|
23
|
+
import type { SmarterChatProps } from "@/types";
|
|
24
|
+
import "@/components/SmarterChat/styles.css";
|
|
25
|
+
declare function SmarterChat({ apiUrl, apiKey, toggleMetadata, csrfCookieName, csrftoken, debugCookieName, debugCookieExpiration, debugMode, sessionCookieName, sessionCookieExpiration, showConsole, cookieDomain, smarterRequestId, logStreamUrl, streamProgress, }: SmarterChatProps): import("react").JSX.Element;
|
|
26
|
+
export default SmarterChat;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The chat toolbar's icons, from Bootstrap Icons (MIT license, https://icons.getbootstrap.com),
|
|
3
|
+
* inline so that the package needs neither its font nor its css.
|
|
4
|
+
*/
|
|
5
|
+
/** A blank sheet of paper: a new chat. (bi-file-earmark) */
|
|
6
|
+
export declare function NewChatIcon(): import("react").JSX.Element;
|
|
7
|
+
/**
|
|
8
|
+
* A window with a panel on its right, as the Console is: filled while the Console is visible
|
|
9
|
+
* (bi-layout-sidebar-inset-reverse), and empty while it is hidden (bi-layout-sidebar-reverse).
|
|
10
|
+
*/
|
|
11
|
+
export declare function ConsoleIcon({ visible }: {
|
|
12
|
+
visible: boolean;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
/** Tools: sandbox mode, which displays Smarter's system, tool and meta data messages. (bi-tools) */
|
|
15
|
+
export declare function SandboxIcon(): import("react").JSX.Element;
|
|
16
|
+
/** A shield: production mode, which displays the conversation only, as its users see it. (bi-shield-check) */
|
|
17
|
+
export declare function ProductionIcon(): import("react").JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const projectName: string;
|
|
2
|
+
export declare const projectVersion: string;
|
|
3
|
+
export declare const loggerPrefix: string;
|
|
4
|
+
/** The default lifetime of the chat session and debug cookies: one day, in milliseconds. */
|
|
5
|
+
export declare const DEFAULT_COOKIE_EXPIRATION: number;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @smarter.sh/ui-chat: the public api of the npm package. See vite.config.ts (--mode lib).
|
|
3
|
+
*
|
|
4
|
+
* The Smarter web console builds this package as an app instead. See main.tsx.
|
|
5
|
+
*/
|
|
6
|
+
export { default as SmarterChat } from "./components/SmarterChat";
|
|
7
|
+
export { default as Console } from "./components/Console";
|
|
8
|
+
export { MenuItems } from "./components/Console/enums";
|
|
9
|
+
export { MessageDirectionEnum, SenderRoleEnum, ValidMessageRolesEnum } from "./lib/enums";
|
|
10
|
+
export { projectVersion as version } from "./const";
|
|
11
|
+
export type { PromptProgressEvent } from "./lib/api";
|
|
12
|
+
export type { ApiMessage, ChatConfig, ChatHistory, ChatMessage, ChatMetaData, ChatbotConfig, SmarterChatProps, } from "./types";
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ANSI escape codes, as the server's log records have them, e.g. "\x1b[1;34m...\x1b[0m".
|
|
3
|
+
*
|
|
4
|
+
* The text of a log record is split into segments, each with the color and the emphasis that its
|
|
5
|
+
* SGR (Select Graphic Rendition) codes give it, so that the Console displays the records as the
|
|
6
|
+
* Smarter web console's log viewer (smarter-terminal-emulator, an xterm.js terminal) does. Other
|
|
7
|
+
* escape sequences, e.g. cursor movements, are removed.
|
|
8
|
+
*/
|
|
9
|
+
import type { CSSProperties } from "react";
|
|
10
|
+
/** The xterm.js theme of smarter-terminal-emulator, by ANSI color number: 0-7, then bright 8-15. */
|
|
11
|
+
export declare const ANSI_PALETTE: string[];
|
|
12
|
+
/** The text style that SGR codes set. */
|
|
13
|
+
export interface AnsiStyle {
|
|
14
|
+
color?: string;
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
bold?: boolean;
|
|
17
|
+
dim?: boolean;
|
|
18
|
+
italic?: boolean;
|
|
19
|
+
underline?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** A run of text, with its style. */
|
|
22
|
+
export interface AnsiSegment {
|
|
23
|
+
text: string;
|
|
24
|
+
style: AnsiStyle;
|
|
25
|
+
}
|
|
26
|
+
/** The style after the given SGR codes. An empty list of codes is a reset. */
|
|
27
|
+
export declare function applySgr(style: AnsiStyle, codes: number[]): AnsiStyle;
|
|
28
|
+
/** The text's segments, each with its style, without the escape sequences. */
|
|
29
|
+
export declare function parseAnsi(text: string): AnsiSegment[];
|
|
30
|
+
/** The text without its escape sequences. */
|
|
31
|
+
export declare function stripAnsi(text: string): string;
|
|
32
|
+
/** The css of a style. */
|
|
33
|
+
export declare function ansiCss(style: AnsiStyle): CSSProperties;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Smarter api calls of Smarter Chat: the LLMClient's configuration, and its prompts.
|
|
3
|
+
*
|
|
4
|
+
* Both are POSTs, with Django's CSRF token, and with the browser's cookies, so that the Smarter web
|
|
5
|
+
* console's session authenticates them. Each response wraps its payload in "data". See:
|
|
6
|
+
*
|
|
7
|
+
* - smarter.apps.prompt.views.detailviews.prompt_config_view.PromptConfigView: <apiUrl>config/
|
|
8
|
+
* - smarter.apps.llmclient.api.v1.views.base: the LLMClient's prompt api, chatbot.url_chatbot. Its
|
|
9
|
+
* payload is an AWS Lambda style response, whose body is a JSON string of the completion, with
|
|
10
|
+
* Smarter's own messages in body.smarter.messages. A failed prompt has the LLM provider's status,
|
|
11
|
+
* and its body is {error: {status, message}, response: <the completion>}, whose messages include a
|
|
12
|
+
* "smarter_error" message.
|
|
13
|
+
*
|
|
14
|
+
* A prompt can stream its progress, e.g. its tool calls and MCP server requests, as Server-Sent
|
|
15
|
+
* Events: the request accepts text/event-stream, and the response is "progress" events, then a
|
|
16
|
+
* "result" event with the same JSON as a non-streaming response. Servers that don't stream answer
|
|
17
|
+
* with JSON, as before. See smarter.apps.prompt.progress.
|
|
18
|
+
*/
|
|
19
|
+
import type { ApiMessage, ChatConfig, ChatCookies, ClientContext } from "../types";
|
|
20
|
+
export declare class SmarterApiError extends Error {
|
|
21
|
+
status: number;
|
|
22
|
+
constructor(message: string, status: number);
|
|
23
|
+
}
|
|
24
|
+
/** The result of a prompt: the messages to add to the thread, and the error, if it failed. */
|
|
25
|
+
export interface PromptResult {
|
|
26
|
+
messages: ApiMessage[];
|
|
27
|
+
error: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** A step of a prompt that is still running, e.g. a tool call. */
|
|
30
|
+
export interface PromptProgressEvent {
|
|
31
|
+
/** e.g. llm_request, tool_requested, tool_responded, plugin_called, mcp_tool_called */
|
|
32
|
+
type: string;
|
|
33
|
+
/** A short, human-readable description of the step. */
|
|
34
|
+
message: string;
|
|
35
|
+
[key: string]: unknown;
|
|
36
|
+
}
|
|
37
|
+
/** The http status of a response, as errorMessage() reads it. */
|
|
38
|
+
type ResponseStatus = Pick<Response, "status" | "statusText">;
|
|
39
|
+
/** The url of an api endpoint, relative to apiUrl, with the chat session's key. */
|
|
40
|
+
export declare function urlFactory(apiUrl: string, endpoint: string | null, sessionKey: string | null): string;
|
|
41
|
+
/**
|
|
42
|
+
* The request headers. Any custom header must also be in Django's CORS_ALLOW_HEADERS, in
|
|
43
|
+
* smarter.settings.base, for pages on other domains.
|
|
44
|
+
*/
|
|
45
|
+
export declare function requestHeadersFactory(cookies: ChatCookies, context: ClientContext): Record<string, string>;
|
|
46
|
+
/** The error message of an api error response, whatever its shape. */
|
|
47
|
+
export declare function errorMessage(json: Record<string, unknown>, response: ResponseStatus): string;
|
|
48
|
+
/**
|
|
49
|
+
* The LLMClient's configuration. A new chat session's key, and the debug mode, are saved in their
|
|
50
|
+
* cookies, for the next page load.
|
|
51
|
+
*/
|
|
52
|
+
export declare function fetchConfig(apiUrl: string, cookies: ChatCookies, context: ClientContext): Promise<ChatConfig>;
|
|
53
|
+
/**
|
|
54
|
+
* Reads a Server-Sent Events stream, and calls onEvent with each event's name and data. Comments
|
|
55
|
+
* (e.g. keepalives) and retry hints are ignored.
|
|
56
|
+
*/
|
|
57
|
+
export declare function readEventStream(body: ReadableStream<Uint8Array>, onEvent: (event: string, data: string) => void): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* A "smarter" message that explains a completion that the LLM stopped because it reached the
|
|
60
|
+
* LLMClient's max tokens, i.e. whose finish_reason is "length", or null. A reasoning model can
|
|
61
|
+
* spend all of its tokens reasoning, and then return an empty response, which is otherwise
|
|
62
|
+
* displayed as nothing at all.
|
|
63
|
+
*/
|
|
64
|
+
export declare function maxTokensMessage(completion: Record<string, unknown> | null | undefined): ApiMessage | null;
|
|
65
|
+
/**
|
|
66
|
+
* Sends the thread to the LLMClient's prompt api. Resolves to the messages to add to the thread.
|
|
67
|
+
* A failed prompt resolves too, with its error, and with a "smarter_error" message to display.
|
|
68
|
+
*
|
|
69
|
+
* With onProgress, the prompt's progress is requested as Server-Sent Events, and each step is
|
|
70
|
+
* passed to onProgress while the prompt runs.
|
|
71
|
+
*/
|
|
72
|
+
export declare function fetchPrompt(config: ChatConfig, messages: ApiMessage[], cookies: ChatCookies, context: ClientContext, onProgress?: (event: PromptProgressEvent) => void): Promise<PromptResult>;
|
|
73
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const CODE_BLOCK_CLASS = "smarter-chat-code";
|
|
2
|
+
export declare const COPY_BUTTON_CLASS = "smarter-chat-code-copy";
|
|
3
|
+
export declare const MERMAID_BLOCK_CLASS = "smarter-chat-mermaid";
|
|
4
|
+
/**
|
|
5
|
+
* The language of a code block, from its fence's info string, e.g. "python" from
|
|
6
|
+
* "```python title=asgi.py", or "" when it has none.
|
|
7
|
+
*/
|
|
8
|
+
export declare function codeLanguage(info: string | undefined): string;
|
|
9
|
+
/**
|
|
10
|
+
* A code block's text, without a closing fence that is at the end of its last line rather than on
|
|
11
|
+
* a line of its own, e.g. " )```", which LLMs sometimes write. Markdown does not close the block
|
|
12
|
+
* there, so the block ends with the message, and the fence would otherwise be displayed as code.
|
|
13
|
+
*/
|
|
14
|
+
export declare function stripTrailingFence(text: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Html for a code block's code: highlighted if its language is one that highlight.js knows, by
|
|
17
|
+
* name or alias (e.g. "py", "js", "sh", "yml"), and otherwise escaped, as GitHub does.
|
|
18
|
+
*/
|
|
19
|
+
export declare function highlightCode(text: string, language: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Html for a fenced or indented code block: a header with its language and a copy button, and its
|
|
22
|
+
* highlighted code. A mermaid block is also marked, so that it can be displayed as a diagram. See
|
|
23
|
+
* mermaid.ts.
|
|
24
|
+
*/
|
|
25
|
+
export declare function codeBlockHtml(text: string, info?: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Copies a code block's code to the clipboard when its copy button is clicked, and shows that it
|
|
28
|
+
* did on the button for a moment. Clicks on anything else are ignored.
|
|
29
|
+
*
|
|
30
|
+
* :returns: whether the click was on a copy button.
|
|
31
|
+
*/
|
|
32
|
+
export declare function copyCodeBlock(target: EventTarget | null): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookie management for Smarter Chat: the Django CSRF cookie, which it reads, and the chat
|
|
3
|
+
* session and debug cookies, which it sets for the page's path, so that each LLMClient's
|
|
4
|
+
* workbench has its own chat session.
|
|
5
|
+
*/
|
|
6
|
+
import type { CookieMeta } from "../types";
|
|
7
|
+
/**
|
|
8
|
+
* Whether the page's hostname is in a cookie's domain. Django's cookie domain settings may
|
|
9
|
+
* include a port (localhost:9357) or a leading dot (.smarter.sh), and may be empty or "None",
|
|
10
|
+
* which means the page's own domain.
|
|
11
|
+
*/
|
|
12
|
+
export declare function inCookieDomain(hostname: string, domain: string | null | undefined): boolean;
|
|
13
|
+
/** The cookie's value: its preset value, else the browser's cookie, else defaultValue. */
|
|
14
|
+
export declare function getCookie(cookie: CookieMeta, defaultValue?: string | null): string | null;
|
|
15
|
+
/** Sets the cookie for the page's path, or deletes it when value is empty. */
|
|
16
|
+
export declare function setCookie(cookie: CookieMeta, value: string | boolean | null | undefined): void;
|
|
17
|
+
export declare function cookieMetaFactory(name: string, expiration: number | null, domain: string | undefined, value?: string | null): CookieMeta;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The direction and the sender of a chat message.
|
|
3
|
+
*
|
|
4
|
+
* The roles are those of the OpenAI chat completion api, plus Smarter's own: "smarter" messages
|
|
5
|
+
* describe what the Smarter backend did, e.g. which plugins it selected, and "smarter_error"
|
|
6
|
+
* messages describe a failed prompt. See OpenAIMessageKeys in
|
|
7
|
+
* smarter.apps.provider.services.text_completion.const.
|
|
8
|
+
*/
|
|
9
|
+
export declare const MessageDirectionEnum: {
|
|
10
|
+
readonly INCOMING: "incoming";
|
|
11
|
+
readonly OUTGOING: "outgoing";
|
|
12
|
+
};
|
|
13
|
+
export type MessageDirection = (typeof MessageDirectionEnum)[keyof typeof MessageDirectionEnum];
|
|
14
|
+
export declare const SenderRoleEnum: {
|
|
15
|
+
readonly SYSTEM: "system";
|
|
16
|
+
readonly ASSISTANT: "assistant";
|
|
17
|
+
readonly USER: "user";
|
|
18
|
+
readonly TOOL: "tool";
|
|
19
|
+
readonly SMARTER: "smarter";
|
|
20
|
+
readonly SMARTER_ERROR: "smarter_error";
|
|
21
|
+
};
|
|
22
|
+
export type SenderRole = (typeof SenderRoleEnum)[keyof typeof SenderRoleEnum];
|
|
23
|
+
/** The roles that the LLM provider accepts. Smarter's own messages are only displayed. */
|
|
24
|
+
export declare const ValidMessageRolesEnum: SenderRole[];
|
|
25
|
+
/** The roles of the backend's messages, which the metadata toggle shows and hides. */
|
|
26
|
+
export declare const MetadataRolesEnum: SenderRole[];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout of the chat and the Console: the width of the chat, which the user changes by dragging
|
|
3
|
+
* the separator between them, whether the Console is visible, and whether its server logs' long
|
|
4
|
+
* lines wrap. They are remembered in the browser's localStorage, which may be unavailable, e.g. in a private window, so they have defaults.
|
|
5
|
+
*/
|
|
6
|
+
import { type KeyboardEvent, type PointerEvent, type RefObject, type SetStateAction } from "react";
|
|
7
|
+
/** The chat's width, as a percentage of the component's width. */
|
|
8
|
+
export declare const DEFAULT_CHAT_WIDTH = 33.33;
|
|
9
|
+
export declare const MIN_CHAT_WIDTH = 20;
|
|
10
|
+
export declare const MAX_CHAT_WIDTH = 80;
|
|
11
|
+
/** The change in the chat's width, in percent, for each arrow key press on the separator. */
|
|
12
|
+
export declare const KEYBOARD_STEP = 5;
|
|
13
|
+
export declare const CHAT_WIDTH_STORAGE_KEY = "smarter-chat.chat-width";
|
|
14
|
+
export declare const CONSOLE_VISIBLE_STORAGE_KEY = "smarter-chat.console-visible";
|
|
15
|
+
export declare const LOG_WRAP_STORAGE_KEY = "smarter-chat.log-wrap";
|
|
16
|
+
export declare function clampChatWidth(width: number): number;
|
|
17
|
+
/** Whether the Console is visible. It is, until the user hides it. */
|
|
18
|
+
export declare function useConsoleVisible(): readonly [boolean, (action: SetStateAction<boolean>) => void];
|
|
19
|
+
/** Whether the server logs' long lines wrap. They don't, until the user wraps them: they scroll. */
|
|
20
|
+
export declare function useLogWrap(): readonly [boolean, (action: SetStateAction<boolean>) => void];
|
|
21
|
+
/**
|
|
22
|
+
* The chat's width, and the props of the separator that resizes it. The separator is a focusable
|
|
23
|
+
* "separator", whose value is the chat's width: drag it, or use the arrow, Home and End keys.
|
|
24
|
+
* Double-click it to restore the default width.
|
|
25
|
+
*/
|
|
26
|
+
export declare function useChatWidth(containerRef: RefObject<HTMLElement | null>): {
|
|
27
|
+
chatWidth: number;
|
|
28
|
+
separatorProps: {
|
|
29
|
+
role: string;
|
|
30
|
+
tabIndex: number;
|
|
31
|
+
"aria-orientation": "vertical";
|
|
32
|
+
"aria-label": string;
|
|
33
|
+
"aria-valuenow": number;
|
|
34
|
+
"aria-valuemin": number;
|
|
35
|
+
"aria-valuemax": number;
|
|
36
|
+
onPointerDown: (event: PointerEvent<HTMLElement>) => void;
|
|
37
|
+
onPointerMove: (event: PointerEvent<HTMLElement>) => void;
|
|
38
|
+
onPointerUp: (event: PointerEvent<HTMLElement>) => void;
|
|
39
|
+
onDoubleClick: () => void;
|
|
40
|
+
onKeyDown: (event: KeyboardEvent<HTMLElement>) => void;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** A log record. Records that aren't JSON are displayed as their message. */
|
|
2
|
+
export interface LogEvent {
|
|
3
|
+
message: string;
|
|
4
|
+
level?: string;
|
|
5
|
+
levelname?: string;
|
|
6
|
+
timestamp?: number | string;
|
|
7
|
+
logger?: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
/** The most records to keep. Older records are dropped. */
|
|
11
|
+
export declare const MAX_LOG_EVENTS = 2000;
|
|
12
|
+
/** The log level of the stream in sandbox mode. Production mode uses the server's log level. */
|
|
13
|
+
export declare const SANDBOX_LOG_LEVEL = "DEBUG";
|
|
14
|
+
/**
|
|
15
|
+
* The log stream's url, for the records at or above the given log level, e.g. "DEBUG". Without a
|
|
16
|
+
* level, the url is unchanged, and the stream sends the records at or above the server's log level.
|
|
17
|
+
*/
|
|
18
|
+
export declare function logStreamUrlForLevel(streamUrl: string | null, level?: string | null): string | null;
|
|
19
|
+
/**
|
|
20
|
+
* The log stream's records, and its connection state. Connects only while streamUrl is set.
|
|
21
|
+
*
|
|
22
|
+
* clear() removes the records, e.g. for a new chat session. The records that were logged before
|
|
23
|
+
* then are not displayed again, even when a reconnection replays the history.
|
|
24
|
+
*/
|
|
25
|
+
export declare function useLogStream(streamUrl: string | null): {
|
|
26
|
+
logs: LogEvent[];
|
|
27
|
+
connected: boolean;
|
|
28
|
+
error: string | null;
|
|
29
|
+
clear: () => void;
|
|
30
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import "katex/dist/katex.min.css";
|
|
2
|
+
import type { MarkedExtension } from "marked";
|
|
3
|
+
import "./math.css";
|
|
4
|
+
/**
|
|
5
|
+
* Html for a LaTeX expression, inline or displayed, or for its source if it is not valid LaTeX. A
|
|
6
|
+
* dollar sign, which is not valid in math, e.g. a price in \($1.20\), is a dollar sign.
|
|
7
|
+
*/
|
|
8
|
+
export declare function mathHtml(tex: string, displayMode: boolean): string;
|
|
9
|
+
/**
|
|
10
|
+
* The marked extension that tokenizes and renders math. See convertMarkdownToHTML in messages.ts.
|
|
11
|
+
*
|
|
12
|
+
* A display equation that follows a line of text, without a blank line between them, would be read
|
|
13
|
+
* as part of that paragraph, and a line of its own that is "=" or "-", e.g. between the two sides of
|
|
14
|
+
* an equation, would make the paragraph a setext heading, which splits the equation. So a setext
|
|
15
|
+
* heading that contains a display equation is not a heading: the paragraph then ends where the
|
|
16
|
+
* equation begins, and blockMath tokenizes it.
|
|
17
|
+
*/
|
|
18
|
+
export declare const mathExtension: MarkedExtension;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import "./mermaid.css";
|
|
2
|
+
export declare const DIAGRAM_CLASS = "smarter-chat-mermaid-diagram";
|
|
3
|
+
export declare const TOGGLE_BUTTON_CLASS = "smarter-chat-mermaid-toggle";
|
|
4
|
+
/** A diagram's svg, without anything that could run a script, but with its own styles. */
|
|
5
|
+
export declare function sanitizeSvg(svg: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* A diagram's source, with the ">" of its quoted labels written as mermaid's "#gt;". With svg text
|
|
8
|
+
* labels, mermaid drops ">" from quoted flowchart labels, e.g. "a >= b > 0" is drawn as "a = b 0".
|
|
9
|
+
* Other diagrams display "#gt;" as ">" too.
|
|
10
|
+
*/
|
|
11
|
+
export declare function escapeQuotedLabels(source: string): string;
|
|
12
|
+
/** A diagram's sanitized svg, rendered once for each source, or null if it can't be rendered. */
|
|
13
|
+
export declare function diagramSvg(source: string): Promise<string | null>;
|
|
14
|
+
/**
|
|
15
|
+
* Displays the mermaid code blocks within root as their diagrams. Blocks that are already
|
|
16
|
+
* displayed, or are being rendered, are left as they are. A block that leaves the page while its
|
|
17
|
+
* diagram renders, e.g. because its message was displayed again, is skipped: its new block finds
|
|
18
|
+
* the diagram in the cache.
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderMermaidDiagrams(root: ParentNode | null | undefined): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Shows a diagram's code instead of the diagram, or the diagram again, when its button is clicked.
|
|
23
|
+
* Clicks on anything else are ignored.
|
|
24
|
+
*
|
|
25
|
+
* :returns: whether the click was on a diagram's button.
|
|
26
|
+
*/
|
|
27
|
+
export declare function toggleMermaidDiagram(target: EventTarget | null): boolean;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ApiMessage, ChatMessage } from "../types";
|
|
2
|
+
import { type MessageDirection } from "./enums";
|
|
3
|
+
export declare function escapeHtml(text: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Html for a message's text: escaped, with markdown images and links as html.
|
|
6
|
+
*
|
|
7
|
+
* - ```` is an image, which opens at full size in a new tab, unless it's a data url,
|
|
8
|
+
* which browsers don't open.
|
|
9
|
+
* - ``[](href)`` is an image that links to href.
|
|
10
|
+
* - ``[text](href)`` is a link, which opens in a new tab.
|
|
11
|
+
*
|
|
12
|
+
* Urls are http(s) or relative to the page. Images may also be base64 png, jpeg, gif or webp data
|
|
13
|
+
* urls. Anything else, e.g. a javascript: url, stays as text.
|
|
14
|
+
*/
|
|
15
|
+
export declare function convertMarkdownLinksToHTML(text: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Html for a markdown message, e.g. an LLM's response: GitHub flavored markdown, i.e. headings,
|
|
18
|
+
* emphasis, lists, tables, block quotes, code, links and images, and math. Line breaks are kept. Code
|
|
19
|
+
* blocks are syntax highlighted, as GitHub's are. See code.ts. Math, in LaTeX, is typeset by KaTeX.
|
|
20
|
+
* See math.ts.
|
|
21
|
+
*
|
|
22
|
+
* Raw html is displayed as text, and links and images follow the rules of
|
|
23
|
+
* convertMarkdownLinksToHTML. A message that is a single paragraph is not wrapped in one,
|
|
24
|
+
* so that its chat bubble stays as compact as the text.
|
|
25
|
+
*/
|
|
26
|
+
export declare function convertMarkdownToHTML(text: string): string;
|
|
27
|
+
/** The direction of a message from the given sender. */
|
|
28
|
+
export declare function directionOf(sender: string): MessageDirection;
|
|
29
|
+
/** Html for a message's text: the user's as they typed it, and the others as markdown. */
|
|
30
|
+
export declare function messageHtml(content: string, sender: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* A new chat message. Messages without text, e.g. an assistant's tool calls, stay in the thread,
|
|
33
|
+
* so that they are sent back to the api, but are not displayed.
|
|
34
|
+
*/
|
|
35
|
+
export declare function messageFactory(content: string | null | undefined, sender: string, originalMessage?: ApiMessage, direction?: MessageDirection): ChatMessage;
|
|
36
|
+
/** The thread of a chat session, from the messages that the backend saved. */
|
|
37
|
+
export declare function chatRestoreFromBackend(chatHistory: ApiMessage[] | null | undefined): ChatMessage[];
|
|
38
|
+
/** Example prompts, which help the user to get started, as a markdown list. */
|
|
39
|
+
export declare function examplePrompts(prompts: string[] | null | undefined): string;
|
|
40
|
+
/** The thread of a new chat session: the system role, the welcome message, and example prompts. */
|
|
41
|
+
export declare function chatIntro(welcomeMessage: string, systemRole: string, prompts: string[] | null | undefined): ChatMessage[];
|
|
42
|
+
/** The thread of a chat session: its saved history, or the introduction to a new one. */
|
|
43
|
+
export declare function chatInit(welcomeMessage: string, systemRole: string, prompts: string[] | null | undefined, chatHistory: ApiMessage[] | null | undefined): ChatMessage[];
|
|
44
|
+
/**
|
|
45
|
+
* The thread as the api's messages: those the LLM accepts, without Smarter's own. The api's
|
|
46
|
+
* original messages keep their other fields, e.g. an assistant's tool_calls.
|
|
47
|
+
*/
|
|
48
|
+
export declare function chatMessages2RequestMessages(messages: ChatMessage[]): ApiMessage[];
|
|
49
|
+
/** Shows or hides the backend's messages (smarter, system and tool), and always shows the rest. */
|
|
50
|
+
export declare function toggleMetadataMessages(messages: ChatMessage[], show: boolean, metadataRoles: string[]): ChatMessage[];
|
|
51
|
+
/** Removes html tags, which pasting text into the message input tends to add. */
|
|
52
|
+
export declare function sanitizeInput(text: string): string;
|