ui: Constants refactor (#26908)
* refactor: Constants * refactor: Constants/Enums cleanup * refactor: Constant objects instead of multiple single value constants * refactor: Cleanup constants
This commit is contained in:
+4
-12
@@ -5,22 +5,14 @@ export const ATTACHMENT_SAVED_REGEX = /\[Attachment saved: ([^\]]+)\]/;
|
||||
// JSON detection: trimmed content opens with an object or array literal.
|
||||
export const TOOL_RESULT_JSON_OPEN_REGEX = /^[[{]/;
|
||||
|
||||
// Markdown structural markers used by `looksLikeMarkdown`. Inline / line-level.
|
||||
export const MARKDOWN_CODE_FENCE_REGEX = /^(```|~~~)/m;
|
||||
export const MARKDOWN_ATX_HEADING_REGEX = /^#{1,6}\s+\S/;
|
||||
export const MARKDOWN_BLOCKQUOTE_REGEX = /^>\s+\S/;
|
||||
export const MARKDOWN_LIST_BULLET_REGEX = /^\s*[-*+]\s+\S/;
|
||||
export const MARKDOWN_LIST_NUMBERED_REGEX = /^\s*\d+[.)]\s+\S/;
|
||||
export const MARKDOWN_LINK_REGEX = /\[[^\]\n]+\]\([^)\s]+\)/;
|
||||
export const MARKDOWN_BOLD_REGEX = /\*\*[^*\n]+\*\*|__[^_\n]+__/;
|
||||
export const MARKDOWN_TABLE_SEPARATOR_REGEX = /^\s*\|?[\s:|-]+\|?\s*$/;
|
||||
|
||||
// Search-summary wire format used by file-glob and grep tools:
|
||||
// <matches>
|
||||
// ---
|
||||
// Total matches: N
|
||||
export const SEARCH_SUMMARY_SEPARATOR = '---\n';
|
||||
export const SEARCH_SUMMARY_TOTAL_REGEX = /Total matches:\s*(\d+)/;
|
||||
export const SEARCH_SUMMARY = {
|
||||
SEPARATOR: '---\n',
|
||||
TOTAL_REGEX: /Total matches:\s*(\d+)/
|
||||
} as const;
|
||||
|
||||
// Separator rendered between stats in the tool-result footer (e.g. between a
|
||||
// result message and the byte/edit count). Plain ASCII spaces bracket a hyphen
|
||||
@@ -1,4 +0,0 @@
|
||||
export const ATTACHMENT_LABEL_FILE = 'File';
|
||||
export const ATTACHMENT_LABEL_PDF_FILE = 'PDF File';
|
||||
export const ATTACHMENT_LABEL_MCP_PROMPT = 'MCP Prompt';
|
||||
export const ATTACHMENT_LABEL_MCP_RESOURCE = 'MCP Resource';
|
||||
+2
-23
@@ -1,33 +1,12 @@
|
||||
import { FolderOpen, MessageSquare, Zap } from '@lucide/svelte';
|
||||
import { FILE_TYPE_ICONS } from '$lib/constants/icons';
|
||||
import { FILE_TYPE_ICONS } from '$lib/constants';
|
||||
import {
|
||||
AttachmentAction,
|
||||
AttachmentItemEnabledWhen,
|
||||
AttachmentItemVisibleWhen,
|
||||
AttachmentMenuItemId
|
||||
} from '$lib/enums';
|
||||
import type { Component } from 'svelte';
|
||||
|
||||
export interface AttachmentMenuItem {
|
||||
/** Unique identifier for the item */
|
||||
id: AttachmentMenuItemId;
|
||||
/** Display label */
|
||||
label: string;
|
||||
/** Lucide icon component */
|
||||
icon: Component;
|
||||
/** Extra CSS class applied to the item (e.g. for test selectors) */
|
||||
class?: string;
|
||||
/** Whether the item requires a specific modality to be enabled */
|
||||
enabledWhen?: AttachmentItemEnabledWhen;
|
||||
/** Tooltip shown when the item is disabled */
|
||||
disabledTooltip?: string;
|
||||
/** Callback key on the Props interface to invoke when clicked */
|
||||
action: AttachmentAction;
|
||||
/** Whether the item is only shown when a specific capability is present */
|
||||
visibleWhen?: AttachmentItemVisibleWhen;
|
||||
/** Whether this item has a tooltip even when enabled (uses dynamic text) */
|
||||
hasEnabledTooltip?: boolean;
|
||||
}
|
||||
import type { AttachmentMenuItem } from '$lib/types';
|
||||
|
||||
/**
|
||||
* File attachment menu items shown in both the desktop dropdown and mobile sheet.
|
||||
+1
-13
@@ -20,13 +20,7 @@ import {
|
||||
Terminal
|
||||
} from '@lucide/svelte';
|
||||
import { BuiltInTool, ToolSource } from '$lib/enums';
|
||||
import type { Component } from 'svelte';
|
||||
|
||||
export interface BuiltinToolUiEntry {
|
||||
icon: Component;
|
||||
label: string;
|
||||
source: ToolSource.BUILTIN | ToolSource.FRONTEND;
|
||||
}
|
||||
import type { BuiltinToolUiEntry } from '$lib/types';
|
||||
|
||||
export const BUILTIN_TOOL_UI: Readonly<Record<BuiltInTool, BuiltinToolUiEntry>> = {
|
||||
[BuiltInTool.EDIT_FILE]: { icon: FilePen, label: 'Edit file', source: ToolSource.BUILTIN },
|
||||
@@ -56,9 +50,3 @@ export const BUILTIN_TOOL_UI: Readonly<Record<BuiltInTool, BuiltinToolUiEntry>>
|
||||
},
|
||||
[BuiltInTool.WRITE_FILE]: { icon: FilePlus, label: 'Write file', source: ToolSource.BUILTIN }
|
||||
} as const;
|
||||
|
||||
export function getBuiltinToolUi(toolName: string | undefined): BuiltinToolUiEntry | null {
|
||||
if (!toolName) return null;
|
||||
|
||||
return (BUILTIN_TOOL_UI as Record<string, BuiltinToolUiEntry>)[toolName] ?? null;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Cache configuration constants
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default cache limits when no per-cache overrides are given.
|
||||
*/
|
||||
export const CACHE = {
|
||||
/** Default maximum number of entries in a cache */
|
||||
DEFAULT_MAX_ENTRIES: 100,
|
||||
/** Default TTL (Time-To-Live) for cache entries in milliseconds (5 minutes) */
|
||||
DEFAULT_TTL_MS: 5 * 60 * 1000
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* TTL and size for the model props cache.
|
||||
* Props don't change frequently, so we can cache them longer.
|
||||
*/
|
||||
export const MODEL_PROPS_CACHE = {
|
||||
/** Maximum number of model props to cache */
|
||||
MAX_ENTRIES: 50,
|
||||
/** TTL for model props cache entries in milliseconds (10 minutes) */
|
||||
TTL_MS: 10 * 60 * 1000
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* TTL and size for the MCP resource cache.
|
||||
*/
|
||||
export const MCP_RESOURCE_CACHE = {
|
||||
/** Maximum number of MCP resources to cache */
|
||||
MAX_ENTRIES: 50,
|
||||
/** TTL for MCP resource cache entries in milliseconds (5 minutes) */
|
||||
TTL_MS: 5 * 60 * 1000
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Limits for pruning inactive conversation states held in memory.
|
||||
*/
|
||||
export const INACTIVE_CONVERSATION = {
|
||||
/** Maximum age (in ms) for inactive conversation states before cleanup (30 minutes) */
|
||||
MAX_AGE_MS: 30 * 60 * 1000,
|
||||
/** Maximum number of inactive conversation states to keep in memory */
|
||||
MAX_STATES: 10
|
||||
} as const;
|
||||
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* Cache configuration constants
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default TTL (Time-To-Live) for cache entries in milliseconds
|
||||
* @default 5 minutes
|
||||
*/
|
||||
export const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Default maximum number of entries in a cache
|
||||
* @default 100
|
||||
*/
|
||||
export const DEFAULT_CACHE_MAX_ENTRIES = 100;
|
||||
|
||||
/**
|
||||
* TTL for model props cache in milliseconds
|
||||
* Props don't change frequently, so we can cache them longer
|
||||
* @default 10 minutes
|
||||
*/
|
||||
export const MODEL_PROPS_CACHE_TTL_MS = 10 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Maximum number of model props to cache
|
||||
* @default 50
|
||||
*/
|
||||
export const MODEL_PROPS_CACHE_MAX_ENTRIES = 50;
|
||||
|
||||
/**
|
||||
* Maximum number of MCP resources to cache
|
||||
* @default 50
|
||||
*/
|
||||
export const MCP_RESOURCE_CACHE_MAX_ENTRIES = 50;
|
||||
|
||||
/**
|
||||
* TTL for MCP resource cache entries in milliseconds
|
||||
* @default 5 minutes
|
||||
*/
|
||||
export const MCP_RESOURCE_CACHE_TTL_MS = 5 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Maximum number of inactive conversation states to keep in memory
|
||||
* States for conversations beyond this limit will be cleaned up
|
||||
* @default 10
|
||||
*/
|
||||
export const MAX_INACTIVE_CONVERSATION_STATES = 10;
|
||||
|
||||
/**
|
||||
* Maximum age (in ms) for inactive conversation states before cleanup
|
||||
* States older than this will be removed during cleanup
|
||||
* @default 30 minutes
|
||||
*/
|
||||
export const INACTIVE_CONVERSATION_STATE_MAX_AGE_MS = 30 * 60 * 1000;
|
||||
@@ -1,44 +0,0 @@
|
||||
import { SET_WORKING_DIRECTORY_LABEL } from '$lib/constants/working-directory';
|
||||
import { ChatFormCommandAction } from '$lib/enums';
|
||||
import type { ChatFormCommand } from '$lib/types';
|
||||
|
||||
interface ChatCommandsOptions {
|
||||
/** Gates `/model`. */
|
||||
showModelSelector: boolean;
|
||||
/** Gates `/prompt`. */
|
||||
hasPrompts: () => boolean;
|
||||
/** Gates `/cwd`. */
|
||||
hasCwdTools: () => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* The slash commands surfaced by the `/` command picker, in display order.
|
||||
*
|
||||
* Availability is supplied as predicates rather than store imports: this
|
||||
* module is re-exported through the `$lib/constants` barrel, and importing
|
||||
* stores at module load would create a circular dependency (the stores
|
||||
* themselves import from `$lib/constants`).
|
||||
*/
|
||||
export function getChatCommands(options: ChatCommandsOptions): ChatFormCommand[] {
|
||||
return [
|
||||
{
|
||||
action: ChatFormCommandAction.PROMPT,
|
||||
description: 'Insert an MCP prompt',
|
||||
disabled: !options.hasPrompts(),
|
||||
name: 'prompt'
|
||||
},
|
||||
{
|
||||
action: ChatFormCommandAction.CWD,
|
||||
description: SET_WORKING_DIRECTORY_LABEL,
|
||||
disabled: !options.hasCwdTools(),
|
||||
keywords: ['current working directory'],
|
||||
name: 'cwd'
|
||||
},
|
||||
{
|
||||
action: ChatFormCommandAction.MODEL,
|
||||
description: 'Select model',
|
||||
disabled: !options.showModelSelector,
|
||||
name: 'model'
|
||||
}
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Constants for the markdown code-block renderer: language/fence handling and CSS classes.
|
||||
|
||||
/** Parsing and escaping helpers for the markdown code-block renderer. */
|
||||
export const CODE_BLOCK = {
|
||||
AMPERSAND_REGEX: /&/g,
|
||||
/** Language fallback used when no language is specified. */
|
||||
DEFAULT_LANGUAGE: 'text',
|
||||
/** Matches opening/closing markdown code fences. */
|
||||
FENCE_PATTERN: /^```|\n```/g,
|
||||
GT_REGEX: />/g,
|
||||
/** Matches the language specifier at the start of a code fence. */
|
||||
LANG_PATTERN: /^(\w*)\n?/,
|
||||
LT_REGEX: /</g,
|
||||
|
||||
// Matches the `text:` prefix that file-type identifiers use to denote a
|
||||
// plain-text language (e.g. `text:typescript`). Used by tool-call renderers
|
||||
// to recover the underlying highlight.js language.
|
||||
TEXT_LANGUAGE_PREFIX_REGEX: /^text:/,
|
||||
// Whitespace-only empty lines (between start of string and first non-empty line).
|
||||
// Used by trimCodePadding to drop leading/trailing phantom blank rows from LLM
|
||||
// payload wrappers without touching internal blank lines.
|
||||
TRIM_LEADING_PADDING_REGEX: /^(?:[ \t]*\n)+/,
|
||||
|
||||
TRIM_TRAILING_PADDING_REGEX: /(?:\n[ \t]*)+$/
|
||||
} as const;
|
||||
|
||||
// Matches either Unix or Windows path separators so `String.split(REGEX)` can
|
||||
// recover the trailing file-name segment from either `/foo/bar.txt` or
|
||||
// `C:\foo\bar.txt`. Used wherever a parameter accepts a user-supplied path.
|
||||
export const FILE_PATH_SEPARATOR_REGEX = /[\\/]/;
|
||||
|
||||
// Separates a file name from its extension, e.g. the '.' in `cover.png`.
|
||||
export const FILE_EXTENSION_SEPARATOR = '.';
|
||||
|
||||
// Matches the `text:` prefix that file-type identifiers use to denote a
|
||||
// plain-text language (e.g. `text:typescript`). Used by tool-call renderers
|
||||
// to recover the underlying highlight.js language.
|
||||
export const TEXT_LANGUAGE_PREFIX_REGEX = /^text:/;
|
||||
|
||||
/** CSS classes applied by the markdown code-block renderer. */
|
||||
export const CODE_BLOCK_CLASS = {
|
||||
ACTIONS: 'code-block-actions',
|
||||
COPY_BTN: 'copy-code-btn',
|
||||
HEADER: 'code-block-header',
|
||||
LANGUAGE: 'code-language',
|
||||
PREVIEW_BTN: 'preview-code-btn',
|
||||
RELATIVE: 'relative',
|
||||
SCROLL_CONTAINER: 'code-block-scroll-container',
|
||||
WRAPPER: 'code-block-wrapper'
|
||||
} as const;
|
||||
@@ -1,8 +0,0 @@
|
||||
export const CODE_BLOCK_SCROLL_CONTAINER_CLASS = 'code-block-scroll-container';
|
||||
export const CODE_BLOCK_WRAPPER_CLASS = 'code-block-wrapper';
|
||||
export const CODE_BLOCK_HEADER_CLASS = 'code-block-header';
|
||||
export const CODE_BLOCK_ACTIONS_CLASS = 'code-block-actions';
|
||||
export const CODE_LANGUAGE_CLASS = 'code-language';
|
||||
export const COPY_CODE_BTN_CLASS = 'copy-code-btn';
|
||||
export const PREVIEW_CODE_BTN_CLASS = 'preview-code-btn';
|
||||
export const RELATIVE_CLASS = 'relative';
|
||||
@@ -1,27 +0,0 @@
|
||||
export const NEWLINE = '\n';
|
||||
export const TAB = '\t';
|
||||
export const DEFAULT_LANGUAGE = 'text';
|
||||
export const LANG_PATTERN = /^(\w*)\n?/;
|
||||
export const AMPERSAND_REGEX = /&/g;
|
||||
export const LT_REGEX = /</g;
|
||||
export const GT_REGEX = />/g;
|
||||
export const FENCE_PATTERN = /^```|\n```/g;
|
||||
|
||||
// Whitespace-only empty lines (between start of string and first non-empty line).
|
||||
// Used by trimCodePadding to drop leading/trailing phantom blank rows from LLM
|
||||
// payload wrappers without touching internal blank lines.
|
||||
export const TRIM_LEADING_PADDING_REGEX = /^(?:[ \t]*\n)+/;
|
||||
export const TRIM_TRAILING_PADDING_REGEX = /(?:\n[ \t]*)+$/;
|
||||
|
||||
// Matches either Unix or Windows path separators so `String.split(REGEX)` can
|
||||
// recover the trailing file-name segment from either `/foo/bar.txt` or
|
||||
// `C:\foo\bar.txt`. Used wherever a parameter accepts a user-supplied path.
|
||||
export const FILE_PATH_SEPARATOR_REGEX = /[\\/]/;
|
||||
|
||||
// Separates a file name from its extension, e.g. the '.' in `cover.png`.
|
||||
export const FILE_EXTENSION_SEPARATOR = '.';
|
||||
|
||||
// Matches the `text:` prefix that file-type identifiers use to denote a
|
||||
// plain-text language (e.g. `text:typescript`). Used by tool-call renderers
|
||||
// to recover the underlying highlight.js language.
|
||||
export const TEXT_LANGUAGE_PREFIX_REGEX = /^text:/;
|
||||
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* String patterns for detecting content kind from MIME types and URIs.
|
||||
* Used with startsWith/includes checks, not as discriminated values.
|
||||
*/
|
||||
|
||||
export const MIME_TYPE_PREFIXES = {
|
||||
IMAGE: 'image/',
|
||||
TEXT: 'text'
|
||||
} as const;
|
||||
|
||||
export const MIME_TYPE_SUBSTRINGS = {
|
||||
JAVASCRIPT: 'javascript',
|
||||
JSON: 'json',
|
||||
TYPESCRIPT: 'typescript'
|
||||
} as const;
|
||||
|
||||
export const URI_PATTERNS = {
|
||||
DATABASE_KEYWORD: 'database',
|
||||
DATABASE_SCHEME: 'db://'
|
||||
} as const;
|
||||
-2
@@ -3,5 +3,3 @@
|
||||
export const CONTROL_ACTION = {
|
||||
END_REASONING: 'reasoning_end'
|
||||
} as const;
|
||||
|
||||
export type ControlAction = (typeof CONTROL_ACTION)[keyof typeof CONTROL_ACTION];
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
* naming changes.
|
||||
*/
|
||||
|
||||
import { STORAGE_APP_NAME } from './storage';
|
||||
import { STORAGE_APP_NAME } from './storage.constants';
|
||||
|
||||
/** IndexedDB database name */
|
||||
export const DB_NAME = STORAGE_APP_NAME;
|
||||
@@ -1,2 +0,0 @@
|
||||
export const VIEWPORT_GUTTER = 8;
|
||||
export const MENU_OFFSET = 6;
|
||||
@@ -0,0 +1,35 @@
|
||||
/** HTTP header handling for API and MCP requests. */
|
||||
export const HEADERS = {
|
||||
/** Canonical casing for the Authorization header (RFC 7235) */
|
||||
AUTHORIZATION: 'Authorization',
|
||||
/** Bearer scheme prefix used for Authorization headers (RFC 6750) */
|
||||
BEARER: 'Bearer ',
|
||||
/** Content-Type HTTP header name */
|
||||
CONTENT_TYPE: 'Content-Type',
|
||||
/** Partial-redaction rules for MCP headers: header name -> visible trailing chars */
|
||||
PARTIAL_REDACT: new Map<string, number>([['mcp-session-id', 5]]),
|
||||
|
||||
/** Header names whose values should be redacted in diagnostic logs */
|
||||
REDACTED: new Set([
|
||||
'authorization',
|
||||
'api-key',
|
||||
'cookie',
|
||||
'mcp-session-id',
|
||||
'proxy-authorization',
|
||||
'set-cookie',
|
||||
'x-auth-token',
|
||||
'x-api-key'
|
||||
]),
|
||||
|
||||
/** Header carrying the stream-session identity (conversation id, optionally with a model suffix) */
|
||||
X_CONVERSATION_ID_HEADER: 'X-Conversation-Id',
|
||||
|
||||
/** Header asking the server to encode a tool's output differently, e.g. read_file returning base64. */
|
||||
X_RESP_TYPE_HEADER: 'x-resp-type',
|
||||
|
||||
/** Header carrying the working directory a tool call runs in; the model cannot override it */
|
||||
X_TOOL_CWD_HEADER: 'x-tool-cwd'
|
||||
};
|
||||
|
||||
/** `X_RESP_TYPE_HEADER` value that makes read_file return raw bytes as base64 instead of text. */
|
||||
export const RESP_TYPE_BASE64 = 'base64';
|
||||
@@ -1,3 +0,0 @@
|
||||
export const MEGAPIXELS_TO_PIXELS = 1_000_000;
|
||||
|
||||
export const HEIC_JPEG_QUALITY = 0.85;
|
||||
@@ -0,0 +1,32 @@
|
||||
/** Image handling constants */
|
||||
|
||||
export const IMAGE = {
|
||||
/** JPEG quality used when transcoding HEIC images. */
|
||||
HEIC_JPEG_QUALITY: 0.85,
|
||||
/** Unit conversion: pixels per megapixel. */
|
||||
MEGAPIXELS_TO_PIXELS: 1_000_000
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* JPEG and EXIF binary format constants for orientation parsing.
|
||||
*/
|
||||
export const EXIF = {
|
||||
/** APP1 segment marker byte, carries the EXIF payload */
|
||||
APP1_MARKER: 0xe1,
|
||||
/** "Exif" signature opening the APP1 payload, big endian uint32 */
|
||||
EXIF_SIGNATURE: 0x45786966,
|
||||
/** Size in bytes of one IFD directory entry */
|
||||
IFD_ENTRY_SIZE: 12,
|
||||
/** JPEG start of image marker */
|
||||
JPEG_SOI_MARKER: 0xffd8,
|
||||
/** EXIF tag id holding the orientation value */
|
||||
ORIENTATION_TAG: 0x0112,
|
||||
/** Bytes of file prefix to scan, the APP1 EXIF segment sits near the start */
|
||||
SCAN_BYTE_LIMIT: 128 * 1024,
|
||||
/** Start of scan marker byte, compressed data begins and no EXIF follows */
|
||||
SOS_MARKER: 0xda,
|
||||
/** TIFF byte order mark for little endian ("II") */
|
||||
TIFF_LITTLE_ENDIAN: 0x4949,
|
||||
/** TIFF magic number following the byte order mark */
|
||||
TIFF_MAGIC: 42
|
||||
} as const;
|
||||
@@ -1,67 +1,61 @@
|
||||
// Central constants export file
|
||||
// All constants should be imported from '$lib/constants'
|
||||
|
||||
export * from './agentic';
|
||||
export * from './api-endpoints';
|
||||
export * from './app';
|
||||
export * from './attachment-labels';
|
||||
export * from './database';
|
||||
export * from './reasoning-effort';
|
||||
export * from './reasoning-effort-tokens';
|
||||
export * from './recommended-mcp-servers';
|
||||
export * from './storage';
|
||||
export * from './attachment-menu';
|
||||
export * from './auto-scroll';
|
||||
export * from './context-gauge-popup';
|
||||
export * from './conversation-import';
|
||||
export * from './binary-detection';
|
||||
export * from './built-in-tools';
|
||||
export * from './cache';
|
||||
export * from './chat-form';
|
||||
export * from './chat-commands';
|
||||
export * from './cli-flags';
|
||||
export * from './code-blocks';
|
||||
export * from './icons';
|
||||
export * from './code';
|
||||
export * from './context-keys';
|
||||
export * from './control-actions';
|
||||
export * from './css-classes';
|
||||
export * from './floating-ui-constraints';
|
||||
export * from './formatters';
|
||||
export * from './key-value-pairs';
|
||||
export * from './icons';
|
||||
export * from './latex-protection';
|
||||
export * from './literal-html';
|
||||
export * from './markdown';
|
||||
export * from './mermaid-blocks';
|
||||
export * from './svg-blocks';
|
||||
export * from './diagram-blocks';
|
||||
export * from './max-bundle-size';
|
||||
export * from './mcp';
|
||||
export * from './mcp-form';
|
||||
export * from './mcp-resource';
|
||||
export * from './mention-badge';
|
||||
export * from './message-export';
|
||||
export * from './path-display';
|
||||
export * from './model-id';
|
||||
export * from './model-loading';
|
||||
export * from './sse';
|
||||
export * from './precision';
|
||||
export * from './processing-info';
|
||||
export * from './pwa';
|
||||
export * from './agentic.constants';
|
||||
export * from './api-endpoints.constants';
|
||||
export * from './app.constants';
|
||||
export * from './database.constants';
|
||||
export * from './reasoning-effort.constants';
|
||||
export * from './recommended-mcp-servers.constants';
|
||||
export * from './storage.constants';
|
||||
export * from './icons.constants';
|
||||
export * from './attachment-menu.constants';
|
||||
export * from './auto-scroll.constants';
|
||||
export * from './context-gauge-popup.constants';
|
||||
export * from './conversation-import.constants';
|
||||
export * from './binary-detection.constants';
|
||||
export * from './content-detection.constants';
|
||||
export * from './built-in-tools.constants';
|
||||
export * from './cache.constants';
|
||||
export * from './chat-form.constants';
|
||||
export * from './cli-flags.constants';
|
||||
export * from './code-block.constants';
|
||||
export * from './context-keys.constants';
|
||||
export * from './control-actions.constants';
|
||||
export * from './css-classes.constants';
|
||||
export * from './formatters.constants';
|
||||
export * from './headers.constants';
|
||||
export * from './key-value-pairs.constants';
|
||||
export * from './latex-protection.constants';
|
||||
export * from './literal-html.constants';
|
||||
export * from './markdown.constants';
|
||||
export * from './mermaid-blocks.constants';
|
||||
export * from './svg-blocks.constants';
|
||||
export * from './diagram-blocks.constants';
|
||||
export * from './max-bundle-size.constants';
|
||||
export * from './error.constants';
|
||||
export * from './image.constants';
|
||||
export * from './mcp.constants';
|
||||
export * from './mcp-form.constants';
|
||||
export * from './mcp-resource.constants';
|
||||
export * from './mention-badge.constants';
|
||||
export * from './message-export.constants';
|
||||
export * from './path-display.constants';
|
||||
export * from './model-id.constants';
|
||||
export * from './model-loading.constants';
|
||||
export * from './precision.constants';
|
||||
export * from './pwa.constants';
|
||||
export * from './routes.constants';
|
||||
export * from './sandbox.constants';
|
||||
export * from './settings-keys.constants';
|
||||
export * from './settings-registry.constants';
|
||||
export * from './special-characters.constants';
|
||||
export * from './stream.constants';
|
||||
export * from './supported-file-types.constants';
|
||||
export * from './table-html-restorer.constants';
|
||||
export * from './title-generation.constants';
|
||||
export * from './ui.constants';
|
||||
export * from './uri-template.constants';
|
||||
export * from './url.constants';
|
||||
export * from './working-directory.constants';
|
||||
export * from './read-media';
|
||||
export * from './routes';
|
||||
export * from './sandbox';
|
||||
export * from './settings-keys';
|
||||
export * from './settings-registry';
|
||||
export * from './stream';
|
||||
export * from './supported-file-types';
|
||||
export * from './table-html-restorer';
|
||||
export * from './title-generation';
|
||||
export * from './tools';
|
||||
export * from './tooltip-config';
|
||||
export * from './ui';
|
||||
export * from './uri-template';
|
||||
export * from './url';
|
||||
export * from './viewport';
|
||||
export * from './working-directory';
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/**
|
||||
* JPEG and EXIF binary format constants for orientation parsing.
|
||||
*/
|
||||
|
||||
/** Bytes of file prefix to scan, the APP1 EXIF segment sits near the start */
|
||||
export const EXIF_SCAN_BYTE_LIMIT = 128 * 1024;
|
||||
|
||||
/** JPEG start of image marker */
|
||||
export const JPEG_SOI_MARKER = 0xffd8;
|
||||
|
||||
/** APP1 segment marker byte, carries the EXIF payload */
|
||||
export const APP1_MARKER = 0xe1;
|
||||
|
||||
/** Start of scan marker byte, compressed data begins and no EXIF follows */
|
||||
export const SOS_MARKER = 0xda;
|
||||
|
||||
/** "Exif" signature opening the APP1 payload, big endian uint32 */
|
||||
export const EXIF_SIGNATURE = 0x45786966;
|
||||
|
||||
/** TIFF byte order mark for little endian ("II") */
|
||||
export const TIFF_LITTLE_ENDIAN = 0x4949;
|
||||
|
||||
/** TIFF magic number following the byte order mark */
|
||||
export const TIFF_MAGIC = 42;
|
||||
|
||||
/** EXIF tag id holding the orientation value */
|
||||
export const EXIF_ORIENTATION_TAG = 0x0112;
|
||||
|
||||
/** Size in bytes of one IFD directory entry */
|
||||
export const IFD_ENTRY_SIZE = 12;
|
||||
-5
@@ -1,5 +1,3 @@
|
||||
export const LINE_BREAK = /\r?\n/;
|
||||
|
||||
export const PHRASE_PARENTS = new Set([
|
||||
'paragraph',
|
||||
'heading',
|
||||
@@ -10,6 +8,3 @@ export const PHRASE_PARENTS = new Set([
|
||||
'linkReference',
|
||||
'tableCell'
|
||||
]);
|
||||
|
||||
export const NBSP = '\u00a0';
|
||||
export const TAB_AS_SPACES = NBSP.repeat(4);
|
||||
@@ -0,0 +1,17 @@
|
||||
export const IMAGE_NOT_ERROR_BOUND_SELECTOR = 'img:not([data-error-bound])';
|
||||
export const DATA_ERROR_BOUND_ATTR = 'errorBound';
|
||||
export const DATA_ERROR_HANDLED_ATTR = 'errorHandled';
|
||||
export const BOOL_TRUE_STRING = 'true';
|
||||
export const BOOL_FALSE_STRING = 'false';
|
||||
|
||||
/** Markdown structural markers used by `looksLikeMarkdown`. Inline / line-level. */
|
||||
export const MARKDOWN = {
|
||||
ATX_HEADING_REGEX: /^#{1,6}\s+\S/,
|
||||
BLOCKQUOTE_REGEX: /^>\s+\S/,
|
||||
BOLD_REGEX: /\*\*[^*\n]+\*\*|__[^_\n]+__/,
|
||||
CODE_FENCE_REGEX: /^(```|~~~)/m,
|
||||
LINK_REGEX: /\[[^\]\n]+\]\([^)\s]+\)/,
|
||||
LIST_BULLET_REGEX: /^\s*[-*+]\s+\S/,
|
||||
LIST_NUMBERED_REGEX: /^\s*\d+[.)]\s+\S/,
|
||||
TABLE_SEPARATOR_REGEX: /^\s*\|?[\s:|-]+\|?\s*$/
|
||||
} as const;
|
||||
@@ -1,5 +0,0 @@
|
||||
export const IMAGE_NOT_ERROR_BOUND_SELECTOR = 'img:not([data-error-bound])';
|
||||
export const DATA_ERROR_BOUND_ATTR = 'errorBound';
|
||||
export const DATA_ERROR_HANDLED_ATTR = 'errorHandled';
|
||||
export const BOOL_TRUE_STRING = 'true';
|
||||
export const BOOL_FALSE_STRING = 'false';
|
||||
@@ -36,11 +36,14 @@ export const DEFAULT_MCP_CONFIG = {
|
||||
|
||||
export const MCP_SERVER_ID_PREFIX = 'LlamaUI-MCP-Server';
|
||||
|
||||
export const MCP_RECONNECT_INITIAL_DELAY = 1000;
|
||||
export const MCP_RECONNECT_BACKOFF_MULTIPLIER = 2;
|
||||
export const MCP_RECONNECT_MAX_DELAY = 30000;
|
||||
/** Per-attempt timeout for a single reconnection attempt before giving up and backing off. */
|
||||
export const MCP_RECONNECT_ATTEMPT_TIMEOUT_MS = 15_000;
|
||||
/** Backoff policy for reconnecting to a dropped MCP server. */
|
||||
export const MCP_RECONNECT = {
|
||||
/** Per-attempt timeout for a single reconnection attempt before giving up and backing off. */
|
||||
ATTEMPT_TIMEOUT_MS: 15_000,
|
||||
BACKOFF_MULTIPLIER: 2,
|
||||
INITIAL_DELAY: 1000,
|
||||
MAX_DELAY: 30000
|
||||
};
|
||||
|
||||
/** Maximum number of MCP server avatars to display in the chat form */
|
||||
export const MAX_DISPLAYED_MCP_AVATARS = 4;
|
||||
@@ -48,40 +51,20 @@ export const MAX_DISPLAYED_MCP_AVATARS = 4;
|
||||
/** Expected count when two theme-less icons represent a light/dark pair */
|
||||
export const EXPECTED_THEMED_ICON_PAIR_COUNT = 2;
|
||||
|
||||
/** CORS proxy URL query parameter name */
|
||||
export const CORS_PROXY_URL_PARAM = 'url';
|
||||
/** CORS proxy connection settings */
|
||||
export const CORS_PROXY = {
|
||||
/** Header prefix for headers that should be forwarded by the CORS proxy */
|
||||
HEADER_PREFIX: 'x-llama-server-proxy-header-',
|
||||
/** CORS proxy URL query parameter name */
|
||||
URL_PARAM: 'url'
|
||||
} as const;
|
||||
|
||||
/** Header prefix for headers that should be forwarded by the CORS proxy */
|
||||
export const CORS_PROXY_HEADER_PREFIX = 'x-llama-server-proxy-header-';
|
||||
|
||||
/** Number of trailing characters to keep visible when partially redacting mcp-session-id */
|
||||
export const MCP_SESSION_ID_VISIBLE_CHARS = 5;
|
||||
|
||||
/** Partial-redaction rules for MCP headers: header name -> visible trailing chars */
|
||||
export const MCP_PARTIAL_REDACT_HEADERS = new Map<string, number>([
|
||||
['mcp-session-id', MCP_SESSION_ID_VISIBLE_CHARS]
|
||||
]);
|
||||
|
||||
/** Bearer scheme prefix used for Authorization headers (RFC 6750) */
|
||||
export const BEARER_PREFIX = 'Bearer ';
|
||||
|
||||
/** Canonical casing for the Authorization header (RFC 7235) */
|
||||
export const AUTHORIZATION_HEADER = 'Authorization';
|
||||
|
||||
/** Content-Type HTTP header name */
|
||||
export const CONTENT_TYPE_HEADER = 'Content-Type';
|
||||
|
||||
/** Header names whose values should be redacted in diagnostic logs */
|
||||
export const REDACTED_HEADERS = new Set([
|
||||
'authorization',
|
||||
'api-key',
|
||||
'cookie',
|
||||
'mcp-session-id',
|
||||
'proxy-authorization',
|
||||
'set-cookie',
|
||||
'x-auth-token',
|
||||
'x-api-key'
|
||||
]);
|
||||
/** Standard SSE endpoint path indicators */
|
||||
export const MCP_SSE = {
|
||||
ENDPOINT: '/sse',
|
||||
ENDPOINT_QUERY: '/sse?',
|
||||
ENDPOINT_SLASH: '/sse/'
|
||||
} as const;
|
||||
|
||||
/** Human-readable labels for MCP transport types */
|
||||
export const MCP_TRANSPORT_LABELS: Record<MCPTransportType, string> = {
|
||||
@@ -96,8 +79,3 @@ export const MCP_TRANSPORT_ICONS: Record<MCPTransportType, Component> = {
|
||||
[MCPTransportType.STREAMABLE_HTTP]: Globe,
|
||||
[MCPTransportType.WEBSOCKET]: Zap
|
||||
};
|
||||
|
||||
/** Standard SSE endpoint path indicators */
|
||||
export const MCP_SSE_ENDPOINT = '/sse';
|
||||
export const MCP_SSE_ENDPOINT_SLASH = '/sse/';
|
||||
export const MCP_SSE_ENDPOINT_QUERY = '/sse?';
|
||||
@@ -0,0 +1,24 @@
|
||||
// Conversation exporter / filename constants
|
||||
|
||||
export const EXPORT_CONV = {
|
||||
// Producer marker carried by the session record of a JSONL export
|
||||
HARNESS: 'llama.app',
|
||||
// Length of the trimmed conversation ID in the filename
|
||||
ID_TRIM_LENGTH: 8,
|
||||
// Replacements to the ISO date for use in the export filename
|
||||
ISO_DATE_TIME_SEPARATOR: 'T',
|
||||
|
||||
ISO_DATE_TIME_SEPARATOR_REPLACEMENT: '_',
|
||||
|
||||
ISO_TIME_SEPARATOR: ':',
|
||||
ISO_TIME_SEPARATOR_REPLACEMENT: '-',
|
||||
// Characters to keep in the ISO timestamp. 19 keeps 2026-01-01T00:00:00
|
||||
ISO_TIMESTAMP_SLICE: 19,
|
||||
|
||||
MULTIPLE_UNDERSCORE_REGEX: /_+/g,
|
||||
// Maximum length of the sanitized conversation name snippet
|
||||
NAME_SUFFIX_MAX_LENGTH: 20,
|
||||
// Replacements for making the conversation title filename-friendly
|
||||
NON_ALPHANUMERIC_REGEX: /[^a-z0-9]/gi,
|
||||
NONALNUM_REPLACEMENT: '_'
|
||||
} as const;
|
||||
@@ -1,23 +0,0 @@
|
||||
// Conversation filename constants
|
||||
|
||||
// Length of the trimmed conversation ID in the filename
|
||||
export const EXPORT_CONV_ID_TRIM_LENGTH = 8;
|
||||
// Maximum length of the sanitized conversation name snippet
|
||||
export const EXPORT_CONV_NAME_SUFFIX_MAX_LENGTH = 20;
|
||||
// Characters to keep in the ISO timestamp. 19 keeps 2026-01-01T00:00:00
|
||||
export const ISO_TIMESTAMP_SLICE_LENGTH = 19;
|
||||
|
||||
// Producer marker carried by the session record of a JSONL export
|
||||
export const SESSION_HARNESS = 'llama.app';
|
||||
|
||||
// Replacements for making the conversation title filename-friendly
|
||||
export const NON_ALPHANUMERIC_REGEX = /[^a-z0-9]/gi;
|
||||
export const EXPORT_CONV_NONALNUM_REPLACEMENT = '_';
|
||||
export const MULTIPLE_UNDERSCORE_REGEX = /_+/g;
|
||||
|
||||
// Replacements to the ISO date for use in the export filename
|
||||
export const ISO_DATE_TIME_SEPARATOR = 'T';
|
||||
export const ISO_DATE_TIME_SEPARATOR_REPLACEMENT = '_';
|
||||
|
||||
export const ISO_TIME_SEPARATOR = ':';
|
||||
export const ISO_TIME_SEPARATOR_REPLACEMENT = '-';
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Parsing of `org/ModelName[-tag][:quant]` style model IDs.
|
||||
*/
|
||||
|
||||
export const MODEL_ID = {
|
||||
/**
|
||||
* Matches an activated-parameter-count segment, e.g. `A10B`, `a2.4b`.
|
||||
* The leading `A`/`a` distinguishes it from a regular params segment.
|
||||
*/
|
||||
ACTIVATED_PARAMS_RE: /^[Aa]\d+(\.\d+)?[BbMmKkTt]$/,
|
||||
|
||||
/** Matches prefix for custom quantization types, e.g. `UD-Q8_K_XL`. */
|
||||
CUSTOM_QUANTIZATION_PREFIX_RE: /^UD$/i,
|
||||
/** Container format segments to exclude from tags (every model uses these). */
|
||||
IGNORED_SEGMENTS: new Set(['GGUF', 'GGML']),
|
||||
/** Sentinel value returned by `indexOf` when a substring is not found. */
|
||||
NOT_FOUND: -1,
|
||||
|
||||
/** Separates `<org>` from `<model>` in a model ID, e.g. `org/ModelName`. */
|
||||
ORG_SEPARATOR: '/',
|
||||
|
||||
/**
|
||||
* Matches a parameter-count segment, e.g. `7B`, `1.5b`, `120M`.
|
||||
* The optional leading `E` covers effective-parameter sizes, e.g. Gemma's
|
||||
* `E2B`/`E4B` (MatFormer models sized by resident params).
|
||||
*/
|
||||
PARAMS_RE: /^[Ee]?\d+(\.\d+)?[BbMmKkTt]$/,
|
||||
|
||||
/**
|
||||
* Matches a quantization/precision segment, e.g. `Q4_K_M`, `IQ4_XS`, `F16`, `BF16`, `MXFP4`.
|
||||
* Case-insensitive to handle both uppercase and lowercase inputs.
|
||||
*/
|
||||
QUANTIZATION_SEGMENT_RE: /^(I?Q\d+(_[A-Z0-9]+)*|F\d+|BF\d+|MXFP\d+(_[A-Z0-9]+)*)$/i,
|
||||
|
||||
/** Separates the model path from the quantization tag, e.g. `model:Q4_K_M`. */
|
||||
QUANTIZATION_SEPARATOR: ':',
|
||||
|
||||
/** Separates named segments within the model path, e.g. `ModelName-7B-GGUF`. */
|
||||
SEGMENT_SEPARATOR: '-',
|
||||
|
||||
/** Matches a trailing weight file extension, e.g. `model.gguf` -> `model`. */
|
||||
WEIGHT_EXTENSION_RE: /\.(gguf|ggml)$/i
|
||||
};
|
||||
@@ -1,46 +0,0 @@
|
||||
/** Sentinel value returned by `indexOf` when a substring is not found. */
|
||||
export const MODEL_ID_NOT_FOUND = -1;
|
||||
|
||||
/** Separates `<org>` from `<model>` in a model ID, e.g. `org/ModelName`. */
|
||||
export const MODEL_ID_ORG_SEPARATOR = '/';
|
||||
|
||||
/** Separates named segments within the model path, e.g. `ModelName-7B-GGUF`. */
|
||||
export const MODEL_ID_SEGMENT_SEPARATOR = '-';
|
||||
|
||||
/** Separates the model path from the quantization tag, e.g. `model:Q4_K_M`. */
|
||||
export const MODEL_ID_QUANTIZATION_SEPARATOR = ':';
|
||||
|
||||
/**
|
||||
* Matches a quantization/precision segment, e.g. `Q4_K_M`, `IQ4_XS`, `F16`, `BF16`, `MXFP4`.
|
||||
* Case-insensitive to handle both uppercase and lowercase inputs.
|
||||
*/
|
||||
export const MODEL_QUANTIZATION_SEGMENT_RE =
|
||||
/^(I?Q\d+(_[A-Z0-9]+)*|F\d+|BF\d+|MXFP\d+(_[A-Z0-9]+)*)$/i;
|
||||
|
||||
/**
|
||||
* Matches prefix for custom quantization types, e.g. `UD-Q8_K_XL`.
|
||||
*/
|
||||
export const MODEL_CUSTOM_QUANTIZATION_PREFIX_RE = /^UD$/i;
|
||||
|
||||
/**
|
||||
* Matches a parameter-count segment, e.g. `7B`, `1.5b`, `120M`.
|
||||
* The optional leading `E` covers effective-parameter sizes, e.g. Gemma's
|
||||
* `E2B`/`E4B` (MatFormer models sized by resident params).
|
||||
*/
|
||||
export const MODEL_PARAMS_RE = /^[Ee]?\d+(\.\d+)?[BbMmKkTt]$/;
|
||||
|
||||
/**
|
||||
* Matches an activated-parameter-count segment, e.g. `A10B`, `a2.4b`.
|
||||
* The leading `A`/`a` distinguishes it from a regular params segment.
|
||||
*/
|
||||
export const MODEL_ACTIVATED_PARAMS_RE = /^[Aa]\d+(\.\d+)?[BbMmKkTt]$/;
|
||||
|
||||
/**
|
||||
* Container format segments to exclude from tags (every model uses these).
|
||||
*/
|
||||
export const MODEL_IGNORED_SEGMENTS = new Set(['GGUF', 'GGML']);
|
||||
|
||||
/**
|
||||
* Matches a trailing weight file extension, e.g. `model.gguf` -> `model`.
|
||||
*/
|
||||
export const MODEL_WEIGHT_EXTENSION_RE = /\.(gguf|ggml)$/i;
|
||||
@@ -1,8 +0,0 @@
|
||||
export const PROCESSING_INFO_TIMEOUT = 2000;
|
||||
|
||||
/**
|
||||
* Statistics units labels
|
||||
*/
|
||||
export const STATS_UNITS = {
|
||||
TOKENS_PER_SECOND: 't/s'
|
||||
} as const;
|
||||
@@ -3,7 +3,7 @@
|
||||
* definitions across the codebase.
|
||||
*/
|
||||
|
||||
import { APP_NAME } from './app';
|
||||
import { APP_NAME } from './app.constants';
|
||||
|
||||
export const MEDIA_QUERIES = {
|
||||
DISPLAY_MODE_STANDALONE: '(display-mode: standalone)',
|
||||
@@ -1,12 +0,0 @@
|
||||
import { ReasoningEffort } from '$lib/enums';
|
||||
|
||||
/**
|
||||
* Reasoning effort to token budget mapping.
|
||||
* Maps the ReasoningEffort enum values to concrete token counts for the server.
|
||||
*/
|
||||
export const REASONING_EFFORT_TOKENS: Record<string, number> = {
|
||||
[ReasoningEffort.HIGH]: 8192,
|
||||
[ReasoningEffort.LOW]: 512,
|
||||
[ReasoningEffort.MAX]: -1, // unlimited
|
||||
[ReasoningEffort.MEDIUM]: 2048
|
||||
};
|
||||
+11
@@ -22,3 +22,14 @@ export const REASONING_EFFORT_LEVELS: ReasoningEffortLevel[] = [
|
||||
{ label: 'High', value: ReasoningEffort.HIGH },
|
||||
{ hasInfo: true, label: 'Max', value: ReasoningEffort.MAX }
|
||||
];
|
||||
|
||||
/**
|
||||
* Reasoning effort to token budget mapping.
|
||||
* Maps the ReasoningEffort enum values to concrete token counts for the server.
|
||||
*/
|
||||
export const REASONING_EFFORT_TOKENS: Record<string, number> = {
|
||||
[ReasoningEffort.HIGH]: 8192,
|
||||
[ReasoningEffort.LOW]: 512,
|
||||
[ReasoningEffort.MAX]: -1, // unlimited
|
||||
[ReasoningEffort.MEDIUM]: 2048
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
import { BuiltInTool } from '$lib/enums';
|
||||
|
||||
export const SANDBOX_TOOL_NAME = BuiltInTool.RUN_JAVASCRIPT;
|
||||
|
||||
export const SANDBOX_TIMEOUT_MS_DEFAULT = 10000;
|
||||
|
||||
export const SANDBOX_TIMEOUT_MS_MAX = 30000;
|
||||
|
||||
export const SANDBOX_OUTPUT_MAX_CHARS = 8192;
|
||||
|
||||
export const SANDBOX_EMPTY_OUTPUT = '(no output)';
|
||||
|
||||
export const SANDBOX_TRUNCATION_NOTICE = '[output truncated]';
|
||||
@@ -1,59 +0,0 @@
|
||||
import { BuiltInTool, JsonSchemaType, ToolCallType } from '$lib/enums';
|
||||
import type { OpenAIToolDefinition } from '$lib/types';
|
||||
|
||||
export const SANDBOX_TOOL_NAME = BuiltInTool.RUN_JAVASCRIPT;
|
||||
|
||||
export const SANDBOX_TIMEOUT_MS_DEFAULT = 10000;
|
||||
|
||||
export const SANDBOX_TIMEOUT_MS_MAX = 30000;
|
||||
|
||||
export const SANDBOX_OUTPUT_MAX_CHARS = 8192;
|
||||
|
||||
export const SANDBOX_EMPTY_OUTPUT = '(no output)';
|
||||
|
||||
export const SANDBOX_TRUNCATION_NOTICE = '[output truncated]';
|
||||
|
||||
const NERDAMER_DESCRIPTION = `
|
||||
Symbolic/numeric math via \`nerdamer\`
|
||||
nerdamer(expr,subs?,opts?)/nerdamer.func(...)→Expression Format via .text(fmt?) (fmt: 'decimals'|'fractions'|'scientific') eval via .evaluate(subs?)
|
||||
nerdamer(expr,{x:2}) substitutes numeric via opts 'numer' or .evaluate()
|
||||
simplify/expand/factor(expr) div/gcd/lcm(...) coeffs/partfrac(expr,var)
|
||||
diff/integrate(expr,var) defint(expr,lo,hi,var?) sum/product(expr,var,lo,hi) limit(expr,var,pt)
|
||||
solve(expr,var) solveEquations([eq1,eq2],[var1,var2])
|
||||
polarform/rectform/arg/realpart/imagpart(z)
|
||||
set/get Var/Constant(name,val?) setFunction(name,[params],body)
|
||||
IMPORTANT:Identifier 'nerdamer' has already been declared, use it directly`;
|
||||
|
||||
/**
|
||||
* Build the sandbox tool definition. When `includeSymbolicMath` is true,
|
||||
* the description includes nerdamer API documentation; otherwise it
|
||||
* describes a plain JavaScript sandbox.
|
||||
*/
|
||||
export function buildSandboxToolDefinition(includeSymbolicMath: boolean): OpenAIToolDefinition {
|
||||
return {
|
||||
function: {
|
||||
description: includeSymbolicMath
|
||||
? `Execute JS in a sandboxed browser worker (no DOM/page access). Top-level await ok; console.log for intermediates; top-level return is captured as result.${NERDAMER_DESCRIPTION}`
|
||||
: 'Execute JS in a sandboxed browser worker (no DOM/page access). Top-level await ok; console.log for intermediates; top-level return is captured as result.',
|
||||
name: SANDBOX_TOOL_NAME,
|
||||
parameters: {
|
||||
properties: {
|
||||
code: {
|
||||
description: 'JavaScript source to execute',
|
||||
type: JsonSchemaType.STRING
|
||||
},
|
||||
timeout_ms: {
|
||||
description: `Execution timeout in milliseconds, default ${SANDBOX_TIMEOUT_MS_DEFAULT}, max ${SANDBOX_TIMEOUT_MS_MAX}`,
|
||||
type: JsonSchemaType.NUMBER
|
||||
}
|
||||
},
|
||||
required: ['code'],
|
||||
type: JsonSchemaType.OBJECT
|
||||
}
|
||||
},
|
||||
type: ToolCallType.FUNCTION
|
||||
};
|
||||
}
|
||||
|
||||
/** @deprecated Use {@link buildSandboxToolDefinition} instead. Kept for backward compatibility. */
|
||||
export const SANDBOX_TOOL_DEFINITION = buildSandboxToolDefinition(true);
|
||||
+10
-14
@@ -1,12 +1,9 @@
|
||||
import { CLI_FLAGS } from './cli-flags';
|
||||
import { DEFAULT_MCP_CONFIG } from './mcp';
|
||||
import { ROUTES, SETTINGS_SECTION_SLUGS } from './routes';
|
||||
import { SETTINGS_KEYS } from './settings-keys';
|
||||
import { TITLE_GENERATION } from './title-generation';
|
||||
import {
|
||||
FILE_GLOB_SEARCH_PICKERS_DEFAULT_SEARCH_DEPTH,
|
||||
FILE_GLOB_SEARCH_PICKERS_MAX_SEARCH_DEPTH
|
||||
} from './working-directory';
|
||||
import { CLI_FLAGS } from './cli-flags.constants';
|
||||
import { DEFAULT_MCP_CONFIG } from './mcp.constants';
|
||||
import { ROUTES, SETTINGS_SECTION_SLUGS } from './routes.constants';
|
||||
import { SETTINGS_KEYS } from './settings-keys.constants';
|
||||
import { TITLE_GENERATION } from './title-generation.constants';
|
||||
import { FILE_GLOB_SEARCH_PICKERS } from './working-directory.constants';
|
||||
import {
|
||||
AlertTriangle,
|
||||
Code,
|
||||
@@ -14,7 +11,6 @@ import {
|
||||
Funnel,
|
||||
ListRestart,
|
||||
Monitor,
|
||||
Monitor as MonitorIcon,
|
||||
Moon,
|
||||
PencilRuler,
|
||||
Sliders,
|
||||
@@ -53,7 +49,7 @@ const STANDALONE_SECTIONS: { title: SettingsSectionTitle; slug: string; icon: Co
|
||||
}
|
||||
];
|
||||
const COLOR_MODE_OPTIONS: Array<{ value: string; label: string; icon: Component }> = [
|
||||
{ icon: MonitorIcon, label: 'System', value: ColorMode.SYSTEM },
|
||||
{ icon: Monitor, label: 'System', value: ColorMode.SYSTEM },
|
||||
{ icon: Sun, label: 'Light', value: ColorMode.LIGHT },
|
||||
{ icon: Moon, label: 'Dark', value: ColorMode.DARK }
|
||||
];
|
||||
@@ -106,14 +102,14 @@ const SETTINGS_REGISTRY: Record<string, SettingsSectionEntry> = {
|
||||
type: SettingsFieldType.INPUT
|
||||
},
|
||||
{
|
||||
defaultValue: FILE_GLOB_SEARCH_PICKERS_DEFAULT_SEARCH_DEPTH,
|
||||
defaultValue: FILE_GLOB_SEARCH_PICKERS.DEFAULT_SEARCH_DEPTH,
|
||||
help: 'How many directory levels below the working directory the @-mention file search descends. Larger values surface deeply nested files but take longer on large trees.',
|
||||
isPositiveInteger: true,
|
||||
key: SETTINGS_KEYS.MENTION_SEARCH_MAX_DEPTH,
|
||||
label: 'Mention search depth',
|
||||
max: FILE_GLOB_SEARCH_PICKERS_MAX_SEARCH_DEPTH,
|
||||
max: FILE_GLOB_SEARCH_PICKERS.MAX_SEARCH_DEPTH,
|
||||
min: 1,
|
||||
placeholder: `${FILE_GLOB_SEARCH_PICKERS_DEFAULT_SEARCH_DEPTH}`,
|
||||
placeholder: `${FILE_GLOB_SEARCH_PICKERS.DEFAULT_SEARCH_DEPTH}`,
|
||||
section: SETTINGS_SECTION_SLUGS.AGENTIC,
|
||||
type: SettingsFieldType.INPUT
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Control / whitespace / formatting characters that appear literally inside rendered text.
|
||||
|
||||
/** Line feed. */
|
||||
export const NEWLINE = '\n';
|
||||
|
||||
/** Horizontal tab. */
|
||||
export const TAB = '\t';
|
||||
|
||||
/** Non-breaking space. */
|
||||
export const NBSP = '\u00a0';
|
||||
|
||||
/** Non-breaking spaces used to render a tab stop that whitespace collapsing would otherwise squash. */
|
||||
export const TAB_AS_SPACES = NBSP.repeat(4);
|
||||
|
||||
/** Matches a CR-terminated or bare LF line break. */
|
||||
export const LINE_BREAK = /\r?\n/;
|
||||
@@ -1,3 +1,11 @@
|
||||
// grace window after a visibilitychange before we kick a reader whose socket likely died
|
||||
// while the tab was hidden. covers brief background pauses without thrashing live streams
|
||||
export const STREAM_VISIBILITY_KICK_MS = 3000;
|
||||
|
||||
// separator joining a conversation id and its per-model stream identity
|
||||
// suffix (conv::model) used by the server side replay buffer
|
||||
export const CONVERSATION_ID_SEPARATOR = '::';
|
||||
|
||||
/**
|
||||
* Server-sent events wire format, shared by the chat stream and the
|
||||
* /models/sse status feed (text/event-stream).
|
||||
@@ -1,3 +0,0 @@
|
||||
// grace window after a visibilitychange before we kick a reader whose socket likely died
|
||||
// while the tab was hidden. covers brief background pauses without thrashing live streams
|
||||
export const STREAM_VISIBILITY_KICK_MS = 3000;
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Constants for rendering svg code blocks inline.
|
||||
*/
|
||||
export const SVG = {
|
||||
// CSS classes applied to the inline svg block and its chrome.
|
||||
BLOCK_CLASS: 'svg-block',
|
||||
/**
|
||||
* Shadow root style for the zoom dialog svg. Lets the svg grow past its
|
||||
* intrinsic size so pan and zoom have room to work.
|
||||
*/
|
||||
DIALOG_SHADOW_STYLE:
|
||||
':host{display:inline-block}svg{min-height:min(50vh,12rem);min-width:min(80vw,20rem);max-width:none;max-height:none;height:auto;width:auto;display:block}',
|
||||
ID_ATTR: 'data-svg-id',
|
||||
|
||||
/**
|
||||
* Shadow root style for an inline svg block. Mirrors the centered, padded
|
||||
* sizing the light dom used before the svg moved behind a shadow boundary.
|
||||
*/
|
||||
INLINE_SHADOW_STYLE:
|
||||
':host{display:block;width:100%;text-align:center}svg{display:block;margin:0 auto;width:auto;height:auto;max-width:100%;max-height:70vh;min-height:8rem;padding:3rem 1rem}',
|
||||
// Languages that mark a code block as svg content.
|
||||
LANGUAGE: 'svg',
|
||||
/**
|
||||
* Hard size ceiling for a single inline svg block.
|
||||
* Above this the source is left as raw text instead of being rendered.
|
||||
*/
|
||||
MAX_BYTES: 256 * 1024,
|
||||
|
||||
RENDERED_ATTR: 'data-svg-rendered',
|
||||
/**
|
||||
* DOMPurify config for untrusted svg coming from model output.
|
||||
*
|
||||
* foreignObject and script stay forbidden unconditionally, they are the only
|
||||
* inline svg vectors that execute arbitrary html or js. Everything else is
|
||||
* allowed for maximum rendering compatibility: href and xlink:href stay so
|
||||
* use, image, a and animateMotion work, and DOMPurify still neutralizes
|
||||
* javascript: and data: uri schemes natively. External resource refs are
|
||||
* allowed by design on a local first tool, the user browser fetches them.
|
||||
*
|
||||
* The sanitized svg is always mounted inside a shadow root (see svg-shadow),
|
||||
* so an author <style> stays scoped to that root and can not reach the page.
|
||||
*/
|
||||
SANITIZE_CONFIG: {
|
||||
FORBID_TAGS: ['foreignObject', 'script'],
|
||||
USE_PROFILES: { svg: true, svgFilters: true }
|
||||
},
|
||||
SCROLL_CONTAINER_CLASS: 'svg-scroll-container',
|
||||
|
||||
// data-attributes used to stash per-block svg state on the DOM node.
|
||||
SOURCE_ATTR: 'data-svg-source',
|
||||
|
||||
TAG_PREFIX: '<svg',
|
||||
|
||||
WRAPPER_CLASS: 'svg-block-wrapper',
|
||||
|
||||
XML_LANGUAGE: 'xml'
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
export const SVG_WRAPPER_CLASS = 'svg-block-wrapper';
|
||||
export const SVG_SCROLL_CONTAINER_CLASS = 'svg-scroll-container';
|
||||
export const SVG_BLOCK_CLASS = 'svg-block';
|
||||
|
||||
export const SVG_LANGUAGE = 'svg';
|
||||
export const XML_LANGUAGE = 'xml';
|
||||
export const SVG_TAG_PREFIX = '<svg';
|
||||
|
||||
export const SVG_SOURCE_ATTR = 'data-svg-source';
|
||||
export const SVG_ID_ATTR = 'data-svg-id';
|
||||
export const SVG_RENDERED_ATTR = 'data-svg-rendered';
|
||||
|
||||
/**
|
||||
* Hard size ceiling for a single inline svg block.
|
||||
* Above this the source is left as raw text instead of being rendered.
|
||||
*/
|
||||
export const SVG_MAX_BYTES = 256 * 1024;
|
||||
|
||||
/**
|
||||
* DOMPurify config for untrusted svg coming from model output.
|
||||
*
|
||||
* foreignObject and script stay forbidden unconditionally, they are the only
|
||||
* inline svg vectors that execute arbitrary html or js. Everything else is
|
||||
* allowed for maximum rendering compatibility: href and xlink:href stay so
|
||||
* use, image, a and animateMotion work, and DOMPurify still neutralizes
|
||||
* javascript: and data: uri schemes natively. External resource refs are
|
||||
* allowed by design on a local first tool, the user browser fetches them.
|
||||
*
|
||||
* The sanitized svg is always mounted inside a shadow root (see svg-shadow),
|
||||
* so an author <style> stays scoped to that root and can not reach the page.
|
||||
*/
|
||||
export const SVG_SANITIZE_CONFIG = {
|
||||
FORBID_TAGS: ['foreignObject', 'script'],
|
||||
USE_PROFILES: { svg: true, svgFilters: true }
|
||||
};
|
||||
|
||||
/**
|
||||
* Shadow root style for an inline svg block. Mirrors the centered, padded
|
||||
* sizing the light dom used before the svg moved behind a shadow boundary.
|
||||
*/
|
||||
export const SVG_INLINE_SHADOW_STYLE =
|
||||
':host{display:block;width:100%;text-align:center}svg{display:block;margin:0 auto;width:auto;height:auto;max-width:100%;max-height:70vh;min-height:8rem;padding:3rem 1rem}';
|
||||
|
||||
/**
|
||||
* Shadow root style for the zoom dialog svg. Lets the svg grow past its
|
||||
* intrinsic size so pan and zoom have room to work.
|
||||
*/
|
||||
export const SVG_DIALOG_SHADOW_STYLE =
|
||||
':host{display:inline-block}svg{min-height:min(50vh,12rem);min-width:min(80vw,20rem);max-width:none;max-height:none;height:auto;width:auto;display:block}';
|
||||
@@ -1,22 +0,0 @@
|
||||
import { ToolSource } from '$lib/enums/tools.enums';
|
||||
|
||||
/** HTTP header carrying the working directory a tool call runs in. The server resolves relative paths against it; the model cannot override it. */
|
||||
export const X_TOOL_CWD_HEADER = 'x-tool-cwd';
|
||||
|
||||
/** HTTP header asking the server to encode a tool's output differently, e.g. read_file returning base64. Not a tool parameter, so it stays out of the definition the model sees. */
|
||||
export const X_RESP_TYPE_HEADER = 'x-resp-type';
|
||||
|
||||
/** `X_RESP_TYPE_HEADER` value that makes read_file return the raw bytes as base64 instead of text. */
|
||||
export const RESP_TYPE_BASE64 = 'base64';
|
||||
|
||||
export const TOOL_GROUP_LABELS = {
|
||||
[ToolSource.BUILTIN]: 'Built-in',
|
||||
[ToolSource.CUSTOM]: 'JSON Schema',
|
||||
[ToolSource.FRONTEND]: 'Browser'
|
||||
} as const;
|
||||
|
||||
export const TOOL_SERVER_LABELS = {
|
||||
[ToolSource.BUILTIN]: 'Built-in Tools',
|
||||
[ToolSource.CUSTOM]: 'Custom Tools',
|
||||
[ToolSource.FRONTEND]: 'Browser Tools'
|
||||
} as const;
|
||||
@@ -1 +0,0 @@
|
||||
export const TOOLTIP_DELAY_DURATION = 500;
|
||||
@@ -1,11 +1,40 @@
|
||||
import { ROUTES } from './routes';
|
||||
import { ROUTES } from './routes.constants';
|
||||
import { Package, Search, Settings, SquarePen } from '@lucide/svelte';
|
||||
import McpLogo from '$lib/components/app/mcp/McpLogo.svelte';
|
||||
import type { Component } from 'svelte';
|
||||
import { ToolSource } from '$lib/enums/tools.enums';
|
||||
import type { DesktopIconStripItem } from '$lib/types';
|
||||
|
||||
export const FORK_TREE_DEPTH_PADDING = 8;
|
||||
export const SYSTEM_MESSAGE_PLACEHOLDER = 'System message';
|
||||
|
||||
export const TOOL_GROUP_LABELS = {
|
||||
[ToolSource.BUILTIN]: 'Built-in',
|
||||
[ToolSource.CUSTOM]: 'JSON Schema',
|
||||
[ToolSource.FRONTEND]: 'Browser'
|
||||
} as const;
|
||||
|
||||
export const TOOL_SERVER_LABELS = {
|
||||
[ToolSource.BUILTIN]: 'Built-in Tools',
|
||||
[ToolSource.CUSTOM]: 'Custom Tools',
|
||||
[ToolSource.FRONTEND]: 'Browser Tools'
|
||||
} as const;
|
||||
|
||||
export const TOOLTIP_DELAY_DURATION = 500;
|
||||
|
||||
export const VIEWPORT_GUTTER = 8;
|
||||
export const MENU_OFFSET = 6;
|
||||
|
||||
export const PROCESSING_INFO_TIMEOUT = 2000;
|
||||
|
||||
/**
|
||||
* Statistics units labels
|
||||
*/
|
||||
export const STATS_UNITS = {
|
||||
TOKENS_PER_SECOND: 't/s'
|
||||
} as const;
|
||||
|
||||
export const DEFAULT_MOBILE_BREAKPOINT = 768;
|
||||
|
||||
/** Icon used for the model selector and the `/model` slash command. */
|
||||
export const MODEL_SELECTOR_ICON = Package;
|
||||
|
||||
@@ -15,16 +44,6 @@ export const ICON_STRIP_TRANSITION_DELAY_MULTIPLIER = 50;
|
||||
/** Max height for tool-result code blocks (json / source / diff / streaming code). */
|
||||
export const MAX_HEIGHT_CODE_BLOCK = '22rem';
|
||||
|
||||
export interface DesktopIconStripItem {
|
||||
icon: Component;
|
||||
tooltip: string;
|
||||
route?: string;
|
||||
activeRouteId?: string;
|
||||
activeRoutePrefix?: string;
|
||||
activeUrlIncludes?: string;
|
||||
keys?: string[];
|
||||
}
|
||||
|
||||
export const SIDEBAR_ACTIONS_ITEMS: DesktopIconStripItem[] = [
|
||||
{ icon: SquarePen, keys: ['shift', 'cmd', 'o'], route: ROUTES.NEW_CHAT, tooltip: 'New chat' },
|
||||
{ icon: Search, keys: ['cmd', 'k'], tooltip: 'Search' },
|
||||
+6
-20
@@ -8,11 +8,13 @@ export const URI_SCHEME_SEPARATOR = '://';
|
||||
/** Regex to match template expressions like {var}, {+var}, {#var}, {/var} */
|
||||
export const TEMPLATE_EXPRESSION_REGEX = /\{([+#./;?&]?)([^}]+)\}/g;
|
||||
|
||||
/** RFC 6570 URI template operators */
|
||||
export const URI_TEMPLATE_OPERATORS = {
|
||||
/** Form-style query continuation */
|
||||
FORM_CONTINUATION: '&',
|
||||
/** RFC 6570 URI template operators and separators. A single object covers both: an operator prefix character doubles as the separator written into the expansion (e.g. `{/a}`/`{;a}` use `/` and `;` for both), so the characters live here once. */
|
||||
export const URI_TEMPLATE_SYMBOLS = {
|
||||
/** Comma separator for list expansion */
|
||||
COMMA: ',',
|
||||
/** Form-style query */
|
||||
FORM_CONTINUATION: '&',
|
||||
/** Form-style query prefix */
|
||||
FORM_QUERY: '?',
|
||||
/** Fragment expansion */
|
||||
FRAGMENT: '#',
|
||||
@@ -28,22 +30,6 @@ export const URI_TEMPLATE_OPERATORS = {
|
||||
SIMPLE: ''
|
||||
} as const;
|
||||
|
||||
/** URI template separators used in expansion */
|
||||
export const URI_TEMPLATE_SEPARATORS = {
|
||||
/** Comma separator for list expansion */
|
||||
COMMA: ',',
|
||||
/** Period separator for label expansion */
|
||||
PERIOD: '.',
|
||||
/** Ampersand prefix for query continuation */
|
||||
QUERY_CONTINUATION: '&',
|
||||
/** Question mark prefix for query string */
|
||||
QUERY_PREFIX: '?',
|
||||
/** Semicolon separator for path parameters */
|
||||
SEMICOLON: ';',
|
||||
/** Slash separator for path segments */
|
||||
SLASH: '/'
|
||||
} as const;
|
||||
|
||||
/** Maximum number of leading slashes to strip during URI normalization */
|
||||
export const MAX_LEADING_SLASHES_TO_STRIP = 3;
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
export const DEFAULT_MOBILE_BREAKPOINT = 768;
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Constants for the working-directory picker's glob search.
|
||||
*
|
||||
* The picker glob-matches home-relative names client-side. Character classes
|
||||
* are built case-insensitively and the reserved glob metacharacters are
|
||||
* escaped (passed through literally) so a query never changes matching.
|
||||
*/
|
||||
|
||||
/** Label shown for the working-directory picker / `/cwd` slash command. */
|
||||
export const SET_WORKING_DIRECTORY_LABEL = 'Set working directory';
|
||||
|
||||
export const GLOB = {
|
||||
/** `C:`, the drive part of a Windows absolute path. */
|
||||
DRIVE_PREFIX_REGEX: /^[A-Za-z]:/,
|
||||
/** `C:` or `C:/`, the root of a Windows drive-absolute path. */
|
||||
DRIVE_ROOT_REGEX: /^[A-Za-z]:\/?/,
|
||||
/** Character that ends a glob character-class fragment. */
|
||||
RANGE_CLOSE: ']',
|
||||
/** Character that starts a glob character-class fragment. */
|
||||
RANGE_OPEN: '[',
|
||||
/** Query characters that carry glob meaning and are passed through literally. */
|
||||
SPECIAL_CHARS: '*?[]',
|
||||
/** `//host/share` or `//host/share/`, the root of a UNC path. */
|
||||
UNC_ROOT_REGEX: /^\/\/[^/]+\/[^/]+\/?/,
|
||||
/** Wildcard character in a glob pattern. */
|
||||
WILDCARD: '*',
|
||||
/** Separator Windows accepts alongside `/`, and a legal POSIX filename character. */
|
||||
WINDOWS_SEPARATOR: '\\'
|
||||
} as const;
|
||||
|
||||
export const SEARCH = {
|
||||
// Search tuning for the picker's file_glob_search calls.
|
||||
DEBOUNCE_MS: 180,
|
||||
LIMIT: 100,
|
||||
// Home-relative globs descend deeper than path navigation, which only
|
||||
// needs the direct children of the parent.
|
||||
MAX_DEPTH: 6,
|
||||
MAX_RESULTS_SHOWN: 20,
|
||||
NATIVE_LIMIT: 20,
|
||||
// Native folder-picker resolution searches a shallow, bounded window.
|
||||
NATIVE_MAX_DEPTH: 4,
|
||||
PATH_NAV_MAX_DEPTH: 1
|
||||
} as const;
|
||||
|
||||
export const FILE_GLOB_SEARCH_PICKERS = {
|
||||
/** Depth the pickers fall back to when the user setting is invalid. */
|
||||
DEFAULT_SEARCH_DEPTH: 10,
|
||||
/** Upper bound the mention search depth setting accepts. The server itself imposes no depth cap (0 = unlimited); this is a UI sanity bound. */
|
||||
MAX_SEARCH_DEPTH: 32
|
||||
} as const;
|
||||
@@ -1,49 +0,0 @@
|
||||
/**
|
||||
* Constants for the working-directory picker's glob search.
|
||||
*
|
||||
* The picker glob-matches home-relative names client-side. Character classes
|
||||
* are built case-insensitively and the reserved glob metacharacters are
|
||||
* escaped (passed through literally) so a query never changes matching.
|
||||
*/
|
||||
|
||||
export const GLOB_WILDCARD = '*';
|
||||
|
||||
/** Label shown for the working-directory picker / `/cwd` slash command. */
|
||||
export const SET_WORKING_DIRECTORY_LABEL = 'Set working directory';
|
||||
|
||||
/** Character that starts and ends a glob character-class fragment. */
|
||||
export const GLOB_RANGE_OPEN = '[';
|
||||
export const GLOB_RANGE_CLOSE = ']';
|
||||
|
||||
/** Query characters that carry glob meaning and are passed through literally. */
|
||||
export const GLOB_SPECIAL_CHARS = '*?[]';
|
||||
|
||||
/** Separator Windows accepts alongside `/`, and a legal POSIX filename character. */
|
||||
export const WINDOWS_SEPARATOR = '\\';
|
||||
|
||||
/** `C:`, the drive part of a Windows absolute path. */
|
||||
export const DRIVE_PREFIX_REGEX = /^[A-Za-z]:/;
|
||||
|
||||
/** `C:` or `C:/`, the root of a Windows drive-absolute path. */
|
||||
export const DRIVE_ROOT_REGEX = /^[A-Za-z]:\/?/;
|
||||
|
||||
/** `//host/share` or `//host/share/`, the root of a UNC path. */
|
||||
export const UNC_ROOT_REGEX = /^\/\/[^/]+\/[^/]+\/?/;
|
||||
|
||||
// Search tuning for the picker's file_glob_search calls.
|
||||
export const SEARCH_DEBOUNCE_MS = 180;
|
||||
export const SEARCH_LIMIT = 100;
|
||||
export const MAX_RESULTS_SHOWN = 20;
|
||||
// Home-relative globs descend deeper than path navigation, which only
|
||||
// needs the direct children of the parent.
|
||||
export const SEARCH_MAX_DEPTH = 6;
|
||||
export const PATH_NAV_MAX_DEPTH = 1;
|
||||
// Native folder-picker resolution searches a shallow, bounded window.
|
||||
export const NATIVE_MAX_DEPTH = 4;
|
||||
export const NATIVE_LIMIT = 20;
|
||||
|
||||
/** Upper bound the mention search depth setting accepts. The server itself imposes no depth cap (0 = unlimited); this is a UI sanity bound. */
|
||||
export const FILE_GLOB_SEARCH_PICKERS_MAX_SEARCH_DEPTH = 32;
|
||||
|
||||
/** Depth the pickers fall back to when the user setting is invalid. */
|
||||
export const FILE_GLOB_SEARCH_PICKERS_DEFAULT_SEARCH_DEPTH = 10;
|
||||
Reference in New Issue
Block a user