[{"name":".storybook","kind":"directory","size":0,"lastCommitHash":"e031d956797f9a10f704fa523fe5fd9b72e9015c","lastCommitWhen":"2026-08-05T08:06:37+02:00","lastCommitMessage":"ui: Update vulnerable packages + cleanup Storybook config (#26607)\n\n* chore: Upgrade Storybook\n\n* chore: Bump package-lock\n\n* chore: bump vitest to 4.1.10\n\n* ui: bump fast-uri to 3.1.5\n\n* ui: bump ip-address to 10.4.0\n\n* ui: bump js-yaml to 4.3.1\n\n* ui: bump immutable to 5.1.9\n\n* ui: bump postcss to 8.5.25\n\n* ui: bump brace-expansion to safe versions\n\n* ui: bump sharp to 0.35.3 via override\n\n* ui: bump body-parser to 2.3.0\n\n* ui: bump vite to 7.3.6 and esbuild to 0.28.1\n\nAssisted-by: Claude Sonnet\n\n* ui: bump hono to 4.13.0\n\n* ui: bump dompurify to 3.4.13\n\n* ui: bump @sveltejs/kit to 2.70.2\n\n* ui: bump @modelcontextprotocol/sdk to 1.30.0\n\n* ui: bump valibot to 1.4.2 via override\n\n* chore: Remove legacy setup file\n\n* refactor: Nits cleanup"},{"name":"scripts","kind":"directory","size":0,"lastCommitHash":"e21152dc9636c6d2db6edc9b4531dfc5b2d1cba3","lastCommitWhen":"2026-08-13T06:53:56+02:00","lastCommitMessage":"ui: Constants refactor (#26908)\n\n* refactor: Constants\n\n* refactor: Constants/Enums cleanup\n\n* refactor: Constant objects instead of multiple single value constants\n\n* refactor: Cleanup constants"},{"name":"src","kind":"directory","size":0,"lastCommitHash":"d05f89562d50e16e8c025081aa03bf3e449efd82","lastCommitWhen":"2026-08-23T19:37:19+02:00","lastCommitMessage":"fix: Change chat tabs nav shortcuts (#27609)"},{"name":"static","kind":"directory","size":0,"lastCommitHash":"32beb244f5c2ca91c583be15d4671643b54ba238","lastCommitWhen":"2026-07-15T20:31:45+02:00","lastCommitMessage":"ui: Agentic Content UX improvements (#25450)\n\n* feat: Add shimmer text animation for processing state indicators\n\n* feat: Redesign CollapsibleContentBlock component with improved UX\n\n* feat: Add conditional setting display support with dependsOn field\n\n* feat: Add showAgenticTurnStats setting for per-turn statistics\n\n* feat: Update ChatMessageAgenticContent with improved UI and new features\n\n* feat: Enhance file read tool UI/UX\n\n* feat: Refine styling of collapsible content and code preview blocks\n\n* feat: add terminal variant to CollapsibleContentBlock\n\n* feat: add built-in tools UI registry\n\n* feat: extract ChatMessageReasoningBlock and ChatMessageToolCallBlock\n\n* refactor: simplify ChatMessageAgenticContent to use extracted blocks\n\n* fix: correct markdown content block margin spacing\n\n* fix: reorganize SettingsChatFields layout and reset button positioning\n\n* fix: use direct map access in agentic store session methods\n\n* refactor: remove reasoning preview/throttle system from CollapsibleContentBlock\n\n* feat: add auto-scroll to reasoning block and remove showThoughtInProgress\n\n* feat: add ChatMessageToolCallDateTime component and support for new tool types\n\n* feat: improve auto-scroll reliability in reasoning block with RAF coalescing and MutationObserver\n\n* feat: show MCP server favicon for tools without a built-in icon\n\n* feat: add search-results parsing utilities and tests\n\n* feat: add ChatMessageToolCallSearchResults component\n\n* feat: integrate search results rendering into ChatMessageAgenticContent\n\n* feat: display tool call input alongside output in ChatMessageToolCallBlock\n\n* style: use muted foreground color in reasoning block content\n\n* chore: Format\n\n* feat: Refine reasoning block layout and make pending thoughts display configurable\n\n* feat: Stream tool call code blocks with auto-scroll and handle partial JSON\n\n* feat: add streaming permission gate infrastructure\n\n* feat: wire permission gate into the agentic loop\n\n* fix: bail out on abort and skip already-approved tool calls\n\n* fix: clear partial tool calls on abort and savePartialResponse\n\n* test: cover partial tool call cleanup end-to-end\n\n* refactor: Remove streaming permission gate logic\n\n* fix: Correct autoscroll and streaming gates for tool calls and reasoning blocks\n\n* refactor: Chat Message Assistant componentization\n\n* fix: Show health metadata for disabled MCP servers and promote connections on enable\n\n* fix: Inherit global enabled state for missing MCP per-chat overrides\n\n* refactor: Cleanup\n\n* refactor: Split ChatMessageToolCallBlock into dedicated components\n\n* feat: Add live streaming and auto-scroll for tool execution output\n\n* feat: Add line numbers and change markers to file edit diffs\n\n* chore: Formatting\n\n* feat: Add type definitions and utilities for recommended MCP servers\n\n* feat: Add recommended MCP servers configuration and storage key\n\n* feat: Add McpServerCardCompact component for recommended servers\n\n* feat: Add recommended servers section to Add New Server dialog\n\n* feat: Update McpServerForm to support authorization requirements\n\n* feat: Add select-none classes for text selection prevention\n\n* feat: Add recommended MCP server icon assets\n\n* refactor: Store dismissed MCP recommendations as a boolean flag\n\n* feat: Render tool results as JSON or Markdown based on detected content type\n\n* feat: UI improvement\n\n* feat: Render search block early and update heading to show execution state\n\n* fix: Prevent non-web-search tools from triggering the search UI block\n\n* refactor: Cleanup\n\n* refactor: Extract hardcoded icon size classes into shared constants\n\n* refactor: Extract hardcoded tool result separator into a shared constant\n\n* refactor: Tool Calls UI/logic\n\n* refactor: Cleanup\n\n* refactor: Cleanup\n\n* refactor: Cleanup"},{"name":"tests","kind":"directory","size":0,"lastCommitHash":"8144f3192e5a3131cd043f284525e6ceebf82d0f","lastCommitWhen":"2026-08-23T10:46:49+02:00","lastCommitMessage":"ui: Chat Conversation Tabbed navigation (#27263)\n\n* ui : add browser-style conversation tabs store\n\nTrack open conversation tabs in order, persisted to localStorage and\npruned against the loaded conversation list on init. The chat layout\nsyncs the route's tab on every navigation, so any way of reaching a\nconversation opens a tab for it.\n\n* ui : add temporary new-chat tabs\n\nNew-chat tabs are unsaved conversations carrying a temporary id used\ndirectly as the route (#/chat/<id>). They live in memory and are only\npersisted to the database - keeping the same id so the route and tab\nstay stable - when the first message is sent. Deleting one drops it\nwithout confirmation, and deleting conversations now closes their tabs.\n\n* ui : render conversation tab bar in chat layout\n\nDesktop-only tab bar above the chat screen, one tab per open\nconversation or new-chat tab. The active tab follows the route id;\nclicking navigates, middle-click or the close button closes (switching\nto the left neighbor), and a trailing + starts a new chat. Tabs appear\nonly on chat-id routes; the bare #/ new-chat view has none. The bare\nroute stays put unless a prompt/model deep-link routes it to a new-chat\ntab.\n\n* ui : route new-chat entry points through tabs\n\nThe sidebar New chat item, Cmd+Shift+O, the search page and the\narrow-key fallback now open a new-chat tab instead of navigating to the\n?new_chat URL, which is removed. New chat is no longer a special route\nbut a tab like any other conversation.\n\n* ui : track sidebar expanded state in a shared ui store\n\nMove the desktop sidebar expanded/collapsed state out of deviceStore into a\ndedicated uiStore so the chat tab bar can react to it.\n\nAssisted-by: pi\n\n* chat : add opt-in conversation tabs setting\n\nAdd a Display setting that turns browser-style conversation tabs on or off,\nenabled by default.\n\nAssisted-by: pi\n\n* chat : add browser-style conversation tabs with a new-chat screen\n\nTrack open conversations as tabs above the chat, one per open chat, plus a\nsingle New chat tab for the bare `#/` route. New chat is just the `#/`\nscreen - no temporary conversations - and its tab is dropped when navigating\naway. Sending the first message creates a real conversation and opens a tab\nfor it.\n\nAssisted-by: pi\n\n* chat : turn tab bar into a horizontally scrollable carousel\n\nMake the tab bar a horizontally scrollable carousel with edge scroll buttons\nand active-tab centering, and align its styling with the sidebar.\n\nAssisted-by: pi\n\n* chat : restyle the scroll-to-bottom button to match tab styling\n\nAssisted-by: pi\n\n* chat : add close-tab keyboard shortcut\n\nAssisted-by: pi\n\n* chat : soften tab bar fade and dim inactive tabs\n\nAssisted-by: pi\n\n* feat: Add stop button to tabs\n\n* refactor: Componentize\n\n* ui : fix carousel scrollability detection\n\nObserve the content wrapper as well as the container, since adding overflowing items does not change the container's own box size. Also expose an onScrollableChange callback.\n\nAssisted-by: pi\n\n* ui : add unified ScrollCarousel component\n\nSingle carousel component with top/center variants, gap and scroll options, and hover-revealed chevrons. Rename the HorizontalScrollCarousel accessibility story accordingly.\n\nAssisted-by: pi\n\n* ui : migrate carousels to ScrollCarousel\n\nSwitch the settings mobile header, attachments list, thumbnail strip, and MCP resources to the unified component, and drop HorizontalScrollCarousel.\n\nAssisted-by: pi\n\n* ui : improve chat tabs carousel UX\n\nScroll newly added tabs into view, fade overflowing tabs at the edges, and hide the New chat button while a new-chat tab is open.\n\nAssisted-by: pi\n\n* refactor: Naming\n\n* chat : add keyboard shortcut to jump between conversation tabs\n\nShift+Cmd/Ctrl+Left/Right cycles the open tabs, mirroring the existing\nShift+Cmd/Ctrl+Up/Down conversation navigation.\n\nAssisted-by: pi\n\n* chat : make the whole tab item act as a link\n\nThe full tab is now a link instead of only the inner label button, while\nthe stop and close buttons stay interactive by swallowing their clicks.\n\nAssisted-by: pi\n\n* chat : adjust tab bar width and use a shared offset variable\n\nWiden the tab bar for the expanded sidebar and rename the tab bar height\nvariable to --chat-tabs-offset with a smaller value so the chat screen\nmin-height accounts for the overlay without overshooting.\n\nAssisted-by: pi\n\n* chat : account for the tab bar offset in the assistant min-height\n\nSubtract the tab bar offset when it is shown so the last assistant message\ndoes not overflow the available viewport space.\n\nAssisted-by: pi\n\n* refactor: Post-review fixes\n\n* ui : restore deep links on the chat start page\n\n- handle ?model selection, with ?load=true eager router loading\n- ?q now creates a conversation, sends the prompt, and clears the params\n- show the not-available-model dialog for unknown models\n- never block mount on the conversation list\n\nAssisted-by: pi\n\n* ui : fix tab item link nesting and centralize tab constants\n\n- the tab anchor covers the whole item while stop/close stay siblings,\n  so interactive elements are never nested inside the anchor\n- cmd/ctrl/middle clicks are left to the browser (new window)\n- extract the tab labels, the active-tab data attribute, and the\n  sidebar-offset max widths into constants\n\nAssisted-by: pi\n\n* ui : tidy scroll carousel hook and keep mobile header arrows on\n\n- drop the dead scrollLeft/scrollRight helpers and the unused\n  onScrollableChange/scrollBy props\n- init the carousel once instead of inside a derived\n- restore items-start on the center variant\n- always show the settings header arrows on touch\n\nAssisted-by: pi\n\n* ui : keep the new-chat tab across reloads and fall back on close\n\n- the new-chat sentinel is no longer pruned on init, so reloading on\n  the bare new-chat route keeps the tab the user is on\n- closing the active conversation falls back to the new-chat screen\n  when Conversation tabs are off\n\nAssisted-by: pi\n\n* ui : don't block startup on the conversation list\n\n- prune persisted tabs after the list loads in the background instead\n  of awaiting it during init\n- openNewChat now returns void; its return value was never read\n\nAssisted-by: pi\n\n* ui: fix routing nits\n\n* chore: Update doc comments\n\n* refactor: Mark fire-and-forget openNewChat calls as `void`\n\n* chat: fix the deep-linked prompt, the tab width and the tab shortcuts\n\nThe chat start page creates the conversation and hands the prompt over\nto the chat route, which still sees it in the query string. Sending it\non both sides queues the second copy as a pending message, which shows\nup as a stray user bubble once the answer lands and vanishes on reload\nsince it never reaches the database.\n\nThe tab bar takes the max width of the collapsed sidebar while it is\nexpanded, and the other way round.\n\nThe tab list is pruned against a snapshot of the loaded conversations,\nso a conversation created while that list is still loading loses its\ntab even though the route just opened it. The active tab then falls out\nof the list and the cycling shortcut jumps to an edge on every keypress\ninstead of moving one tab over. Tabs synced from the route are kept as\nthey are, only the persisted ones are pruned.\n\nThe rich chat input claims ctrl or alt with shift and an arrow for its\nbadge-aware word jump, which now belongs to the tab cycling shortcut.\nHolding shift hands the key combination over, the plain word jump is\nunchanged.\n\nThe close-tab shortcut consumes the event before checking whether the\nsetting is on, and the logo background loses its importance flag.\n\n---------\n\nCo-authored-by: Pascal <admin@serveurperso.com>"},{"name":".env.example","kind":"file","size":100,"lastCommitHash":"f8e67fc58335a1495ca1b3cd6827cbd44503800e","lastCommitWhen":"2026-06-02T10:23:19+02:00","lastCommitMessage":"ui: Add Thinking mode toggle with reasoning effort levels + improvements for Chat Form Add Action UI (#23434)\n\n* feat: Add \"Thinking\" toggle and status icon + redesign Chat Form Actions Add panel\n\n* test: Update test reference\n\n* fix: Icon\n\n* fix: E2E test command\n\n* fix: wait for greeting h1 to be visible in e2e test\n\n* fix: remove duplicate PDF option in attachment dropdown\n\n* fix: use label-based group toggle to avoid stale references\n\n* refactor: inline MCP server and tool toggles in mobile sheet\n\n* fix: serve correct build directory in e2e playwright config\n\n* feat: add reasoning effort levels selector in model dropdown\n\n* feat: Reasoning effort\n\n* refactor: Make server origin configurable via environment variable\n\n* feat: Add chat template thinking detector utility\n\n* feat: Add thinking support detection to models store\n\n* refactor: Update model selector components with thinking detection and message-specific indicators\n\n* feat: Update chat form components for model selection and thinking support\n\n* feat: Improve Reasoning controls UI\n\n* refactor: Apply suggestions from code review\n\nCo-authored-by: Aleksander Grygier <aleksander.grygier@gmail.com>\n\n* fix: Model tags\n\n* refactor: Cleanup\n\n* refactor: Remove unneeded components\n\n* refactor: Cleanup"},{"name":".gitignore","kind":"file","size":492,"lastCommitHash":"61328e6a9150b5d83f70416c93d2dfa607b442d0","lastCommitWhen":"2026-07-22T17:52:55+02:00","lastCommitMessage":"feat(ui): add symbolic math support to JS sandbox via nerdamer (#25948)\n\n* feat(ui): add symbolic math support to JS sandbox via nerdamer\n\nPreload nerdamer (with decimal.js) in the sandboxed worker,\nexposing the `nerdamer` global for symbolic computation:\nsimplify, expand, factor, diff, integrate, solve, laplace,\nilt, limit, partfrac, gcd/lcm, roots, coefficients, and more.\n\nMirrors the math.js integration pattern from the\nfeature/sandbox-symbolic-math branch, but uses nerdamer\nfor a lighter, more focused symbolic math engine.\n\n* Update sandbox-harness.ts\n\n* docs(ui): update sandbox tool description with detailed nerdamer usage guide\n\n* Clarify nerdamer usage in sandbox tool description\n\nUpdated the description of the sandbox tool to clarify usage of nerdamer.\n\n* ui: build nerdamer sandbox prelude from vendored source\n\nReplace the vendored all.min.js with the readable nerdamer-prime\nsource and its two bundled deps (big-integer, decimal.js), licenses\nincluded. A vite plugin bundles and minifies them at build time with\nthe upstream esbuild flags, exposed as virtual:nerdamer and imported\nlazily on first sandbox use. The vendors package.json pins commonjs\nso the project level type: module does not break esbuild format\ndetection. The harness gains a CSP removing network egress from the\nworker, and browser tests cover the prelude, exact arithmetic, the\nfetch block and the timeout.\n\nUpstream snapshot: together-science/nerdamer-prime@1936145\n\n* feat(ui): make symbolic math (nerdamer) a user-toggleable setting\n\n- Add SYMBOLIC_MATH_ENABLED setting key and registry entry (checkbox, default false)\n- Convert SANDBOX_TOOL_DEFINITION to buildSandboxToolDefinition(includeSymbolicMath)\n  so the tool description includes/excludes nerdamer API docs dynamically\n- Cache sandbox harness per variant ('nerdamer' / 'plain') for instant toggle\n- Deprecate SANDBOX_TOOL_DEFINITION constant alias for backward compatibility\n- Update tools store to pass symbolic math config into tool definition\n\n* docs(ui): tell LLM to list nerdamer functions first, do not guess\n\n* test(ui): enable symbolic math in sandbox tests via settingsStore config\n\n* style(ui): fix formatting for tools.svelte.ts\n\n---------\n\nCo-authored-by: Pascal <admin@serveurperso.com>"},{"name":".npmrc","kind":"file","size":57,"lastCommitHash":"34e9ee57f59d680db718e3a3466caceef7c24932","lastCommitWhen":"2026-08-07T14:53:51+02:00","lastCommitMessage":"ui: set npm `min-release-age` to protect against supply-chain attacks (#26711)\n\n* ui: set npm `min-release-age` to protect against supply-chain attacks\n\n* ui: bump to 7 days"},{"name":".prettierignore","kind":"file","size":273,"lastCommitHash":"61328e6a9150b5d83f70416c93d2dfa607b442d0","lastCommitWhen":"2026-07-22T17:52:55+02:00","lastCommitMessage":"feat(ui): add symbolic math support to JS sandbox via nerdamer (#25948)\n\n* feat(ui): add symbolic math support to JS sandbox via nerdamer\n\nPreload nerdamer (with decimal.js) in the sandboxed worker,\nexposing the `nerdamer` global for symbolic computation:\nsimplify, expand, factor, diff, integrate, solve, laplace,\nilt, limit, partfrac, gcd/lcm, roots, coefficients, and more.\n\nMirrors the math.js integration pattern from the\nfeature/sandbox-symbolic-math branch, but uses nerdamer\nfor a lighter, more focused symbolic math engine.\n\n* Update sandbox-harness.ts\n\n* docs(ui): update sandbox tool description with detailed nerdamer usage guide\n\n* Clarify nerdamer usage in sandbox tool description\n\nUpdated the description of the sandbox tool to clarify usage of nerdamer.\n\n* ui: build nerdamer sandbox prelude from vendored source\n\nReplace the vendored all.min.js with the readable nerdamer-prime\nsource and its two bundled deps (big-integer, decimal.js), licenses\nincluded. A vite plugin bundles and minifies them at build time with\nthe upstream esbuild flags, exposed as virtual:nerdamer and imported\nlazily on first sandbox use. The vendors package.json pins commonjs\nso the project level type: module does not break esbuild format\ndetection. The harness gains a CSP removing network egress from the\nworker, and browser tests cover the prelude, exact arithmetic, the\nfetch block and the timeout.\n\nUpstream snapshot: together-science/nerdamer-prime@1936145\n\n* feat(ui): make symbolic math (nerdamer) a user-toggleable setting\n\n- Add SYMBOLIC_MATH_ENABLED setting key and registry entry (checkbox, default false)\n- Convert SANDBOX_TOOL_DEFINITION to buildSandboxToolDefinition(includeSymbolicMath)\n  so the tool description includes/excludes nerdamer API docs dynamically\n- Cache sandbox harness per variant ('nerdamer' / 'plain') for instant toggle\n- Deprecate SANDBOX_TOOL_DEFINITION constant alias for backward compatibility\n- Update tools store to pass symbolic math config into tool definition\n\n* docs(ui): tell LLM to list nerdamer functions first, do not guess\n\n* test(ui): enable symbolic math in sandbox tests via settingsStore config\n\n* style(ui): fix formatting for tools.svelte.ts\n\n---------\n\nCo-authored-by: Pascal <admin@serveurperso.com>"},{"name":".prettierrc","kind":"file","size":296,"lastCommitHash":"59778f0196a82db32580bb649d5d839355d6d7bf","lastCommitWhen":"2026-05-16T02:02:40+02:00","lastCommitMessage":"ui: Restructure repo to use `tools/ui` folder and `ui` / `UI` / `llama-ui` / `LLAMA_UI` naming (#23064)\n\n* webui: Move static build output from `tools/server/public` to `build/ui` directory\n\n* refactor: Move to `tools/ui`\n\n* refactor: rename CMake variables and preprocessor defines\n\n- Rename LLAMA_BUILD_WEBUI -> LLAMA_BUILD_UI (old kept as deprecated)\n- Rename LLAMA_USE_PREBUILT_WEBUI -> LLAMA_USE_PREBUILT_UI (old kept as deprecated)\n- Backward compat: old vars auto-forward to new ones with DEPRECATION warning\n- Rename internal vars: WEBUI_SOURCE -> UI_SOURCE, WEBUI_SOURCE_DIR -> UI_SOURCE_DIR, etc.\n- Rename HF bucket: LLAMA_WEBUI_HF_BUCKET -> LLAMA_UI_HF_BUCKET\n- Emit both LLAMA_BUILD_WEBUI and LLAMA_BUILD_UI preprocessor defines\n- Emit both LLAMA_WEBUI_DEFAULT_ENABLED and LLAMA_UI_DEFAULT_ENABLED\n\n* refactor: rename CLI flags (--webui -> --ui) with backward compat\n\n- Add --ui/--no-ui (old --webui/--no-webui kept as deprecated aliases)\n- Add --ui-config (old --webui-config kept as deprecated alias)\n- Add --ui-config-file (old --webui-config-file kept as deprecated alias)\n- Add --ui-mcp-proxy/--no-ui-mcp-proxy (old --webui-mcp-proxy kept as deprecated)\n- Add new env vars: LLAMA_ARG_UI, LLAMA_ARG_UI_CONFIG, LLAMA_ARG_UI_CONFIG_FILE, LLAMA_ARG_UI_MCP_PROXY\n- C++ struct fields: params.ui, params.ui_config_json, params.ui_mcp_proxy added alongside old fields\n- Backward compat: old fields synced to new ones in g_params_to_internals\n\n* refactor: update C++ server internals with backward compat\n\n- Rename json_webui_settings -> json_ui_settings (both kept in server_context_meta)\n- Rename params.webui usage -> params.ui (both synced, old still works)\n- JSON API emits both \"ui\"/\"ui_settings\" and \"webui\"/\"webui_settings\" keys\n- Server routes use params.ui_mcp_proxy || params.webui_mcp_proxy\n- Preprocessor guards use #if defined(LLAMA_BUILD_UI) || defined(LLAMA_BUILD_WEBUI)\n\n* refactor: rename CI/CD workflows, artifacts, and build script\n\n- Rename webui-build.yml -> ui-build.yml; artifact webui-build -> ui-build\n- Rename webui-publish.yml -> ui-publish.yml; var HF_BUCKET_WEBUI_STATIC_OUTPUT -> HF_BUCKET_UI_STATIC_OUTPUT\n- Rename server-webui.yml -> server-ui.yml; job webui-build/checks -> ui-build/checks\n- Update server.yml: job/artifact refs webui-build -> ui-build\n- Update release.yml: all webui-build/publish refs -> ui-build/publish; HF_TOKEN_WEBUI_STATIC_OUTPUT -> HF_TOKEN_UI_STATIC_OUTPUT\n- Update server-self-hosted.yml: webui-build -> ui-build\n- Update build-self-hosted.yml: HF_WEBUI_VERSION -> HF_UI_VERSION\n- Rename webui-download.cmake -> ui-download.cmake (internal refs updated)\n- Update labeler.yml: server/webui -> server/ui path label\n\n* docs: update CODEOWNERS and server README docs\n\n- Update CODEOWNERS: team ggml-org/llama-webui -> ggml-org/llama-ui, path /tools/server/webui/ -> /tools/ui/\n- Update server README.md: CLI tables show --ui flags with deprecated --webui aliases\n- Update server README-dev.md: \"WebUI\" -> \"UI\", paths updated to tools/ui/\n\n* fix: Small fixes for UI build\n\n* fix: CMake.txt syntax\n\n* chore: Formatting\n\n* fix: `.editorconfig` for llama-ui\n\n* chore: Formatting\n\n* refactor: Use `APP_NAME` in Error route\n\n* refactor: Cleanup\n\n* refactor: Single migration service\n\n* make llama-ui a linkable target\n\n* fix: UI Build output\n\n* fix: Missing change\n\n* fix: separate llama-ui npm build output into build/tools/ui/dist subfolder + use cmake npm build instead of downloading ui-build.yml artifacts in CI\n\n* refactor: UI workflows cleanup\n\n---------\n\nCo-authored-by: Xuan Son Nguyen <son@huggingface.co>"},{"name":"CMakeLists.txt","kind":"file","size":5192,"lastCommitHash":"11924d4c17abc27383376a1ac6a24fa3e36c1c0c","lastCommitWhen":"2026-08-02T00:16:29+02:00","lastCommitMessage":"test: fix some CI errors (#26415)"},{"name":"components.json","kind":"file","size":359,"lastCommitHash":"59778f0196a82db32580bb649d5d839355d6d7bf","lastCommitWhen":"2026-05-16T02:02:40+02:00","lastCommitMessage":"ui: Restructure repo to use `tools/ui` folder and `ui` / `UI` / `llama-ui` / `LLAMA_UI` naming (#23064)\n\n* webui: Move static build output from `tools/server/public` to `build/ui` directory\n\n* refactor: Move to `tools/ui`\n\n* refactor: rename CMake variables and preprocessor defines\n\n- Rename LLAMA_BUILD_WEBUI -> LLAMA_BUILD_UI (old kept as deprecated)\n- Rename LLAMA_USE_PREBUILT_WEBUI -> LLAMA_USE_PREBUILT_UI (old kept as deprecated)\n- Backward compat: old vars auto-forward to new ones with DEPRECATION warning\n- Rename internal vars: WEBUI_SOURCE -> UI_SOURCE, WEBUI_SOURCE_DIR -> UI_SOURCE_DIR, etc.\n- Rename HF bucket: LLAMA_WEBUI_HF_BUCKET -> LLAMA_UI_HF_BUCKET\n- Emit both LLAMA_BUILD_WEBUI and LLAMA_BUILD_UI preprocessor defines\n- Emit both LLAMA_WEBUI_DEFAULT_ENABLED and LLAMA_UI_DEFAULT_ENABLED\n\n* refactor: rename CLI flags (--webui -> --ui) with backward compat\n\n- Add --ui/--no-ui (old --webui/--no-webui kept as deprecated aliases)\n- Add --ui-config (old --webui-config kept as deprecated alias)\n- Add --ui-config-file (old --webui-config-file kept as deprecated alias)\n- Add --ui-mcp-proxy/--no-ui-mcp-proxy (old --webui-mcp-proxy kept as deprecated)\n- Add new env vars: LLAMA_ARG_UI, LLAMA_ARG_UI_CONFIG, LLAMA_ARG_UI_CONFIG_FILE, LLAMA_ARG_UI_MCP_PROXY\n- C++ struct fields: params.ui, params.ui_config_json, params.ui_mcp_proxy added alongside old fields\n- Backward compat: old fields synced to new ones in g_params_to_internals\n\n* refactor: update C++ server internals with backward compat\n\n- Rename json_webui_settings -> json_ui_settings (both kept in server_context_meta)\n- Rename params.webui usage -> params.ui (both synced, old still works)\n- JSON API emits both \"ui\"/\"ui_settings\" and \"webui\"/\"webui_settings\" keys\n- Server routes use params.ui_mcp_proxy || params.webui_mcp_proxy\n- Preprocessor guards use #if defined(LLAMA_BUILD_UI) || defined(LLAMA_BUILD_WEBUI)\n\n* refactor: rename CI/CD workflows, artifacts, and build script\n\n- Rename webui-build.yml -> ui-build.yml; artifact webui-build -> ui-build\n- Rename webui-publish.yml -> ui-publish.yml; var HF_BUCKET_WEBUI_STATIC_OUTPUT -> HF_BUCKET_UI_STATIC_OUTPUT\n- Rename server-webui.yml -> server-ui.yml; job webui-build/checks -> ui-build/checks\n- Update server.yml: job/artifact refs webui-build -> ui-build\n- Update release.yml: all webui-build/publish refs -> ui-build/publish; HF_TOKEN_WEBUI_STATIC_OUTPUT -> HF_TOKEN_UI_STATIC_OUTPUT\n- Update server-self-hosted.yml: webui-build -> ui-build\n- Update build-self-hosted.yml: HF_WEBUI_VERSION -> HF_UI_VERSION\n- Rename webui-download.cmake -> ui-download.cmake (internal refs updated)\n- Update labeler.yml: server/webui -> server/ui path label\n\n* docs: update CODEOWNERS and server README docs\n\n- Update CODEOWNERS: team ggml-org/llama-webui -> ggml-org/llama-ui, path /tools/server/webui/ -> /tools/ui/\n- Update server README.md: CLI tables show --ui flags with deprecated --webui aliases\n- Update server README-dev.md: \"WebUI\" -> \"UI\", paths updated to tools/ui/\n\n* fix: Small fixes for UI build\n\n* fix: CMake.txt syntax\n\n* chore: Formatting\n\n* fix: `.editorconfig` for llama-ui\n\n* chore: Formatting\n\n* refactor: Use `APP_NAME` in Error route\n\n* refactor: Cleanup\n\n* refactor: Single migration service\n\n* make llama-ui a linkable target\n\n* fix: UI Build output\n\n* fix: Missing change\n\n* fix: separate llama-ui npm build output into build/tools/ui/dist subfolder + use cmake npm build instead of downloading ui-build.yml artifacts in CI\n\n* refactor: UI workflows cleanup\n\n---------\n\nCo-authored-by: Xuan Son Nguyen <son@huggingface.co>"},{"name":"embed.cpp","kind":"file","size":11297,"lastCommitHash":"ed1c3a20f5e3f0892ac7135d43542815bd7c4aba","lastCommitWhen":"2026-08-17T21:20:12+02:00","lastCommitMessage":"mtmd: use sha256 for input hashing (#27274)\n\n* mtmd: use sha256 for input hashing\n\n* void conflict with boringssl"},{"name":"eslint.config.js","kind":"file","size":7159,"lastCommitHash":"521a64cd01979bb5b1a466152c576a9d809b068d","lastCommitWhen":"2026-08-20T19:02:04+02:00","lastCommitMessage":"ui: Stores split refactor (#27240)\n\n* ui: Extract server stream lifecycle from chatStore into ChatStreamManager\n\nDiscovery, attach/replay, resume retry and the remote-running snapshot\nformed a cohesive cluster inside chatStore. It now lives in\nchat-streams.svelte.ts as ChatStreamManager, owned by chatStore, which\nkeeps the public entry points as delegates so components are\nunchanged. chatStore: 2877 -> 2418 lines.\n\n* ui: Extract user interaction gates from agenticStore into AgenticGates\n\nTool permission requests, turn-limit continue prompts and queued\nsteering messages are the state the loop waits on between turns. They\nhad no coupling to session state, so they now live in\nagentic-gates.svelte.ts; agenticStore keeps delegates so components\nare unchanged. agenticStore: 1196 -> 1073 lines.\n\n* ui: Compose MCP resources under mcpStore.resources\n\nResource state was a second import scope next to mcpStore. Consumers\nnow go through mcpStore.resources, so the MCP surface is one store;\nmcp-resources.svelte.ts stays a separate file owned by mcpStore.\n\n* ui: Reorganize stores into domain namespaces\n\n* fix: Update stale doc comments\n\n* ui: Consolidate conv running-state into a chat activity ledger\n\nRunning-state was split across chatStore.chatLoadingStates (local\npipes), ChatStreamManager.remoteRunningConvs (backend sessions) and\nattachingConvs (attach lifecycle), unioned by hand in\ngetAllLoadingChats and cross-cleaned by setChatLoading calling\nstreams.clearRemoteRunning - the 'spinner ghosts until tab toggle'\nworkaround.\n\nchatActivityStore now owns both sets with one transition per event:\nmarkLocal / localEnded (local pipe end also drops the stale remote\nhint, no cross-owner call) / applyRemoteSnapshot (diffed). The\nsidebar reads chatStore.activity.loadingConvs through the unchanged\ngetAllLoadingChats entry point.\n\nConsequences:\n- isStreamingActive and its five manual writers are gone; isStreaming()\n  now reports whether the active conversation has a live streaming\n  pipe, which is what all four consumers (assistant row, stop action,\n  context gauge, chat screen) actually check\n- isLoading/isReasoning become derived from the per-conv maps plus\n  the active conversation, dropping the manual resync in\n  syncLoadingStateForChat and clearUIState\n- attachingConvs and the last-attach coordination disappear from\n  ChatStreamManager\n- getAllStreamingChats (no consumers) is removed\n\n* ui: Give store collaborators narrow host interfaces\n\nCollaborators took 'host: typeof <store>', i.e. the store's entire\npublic surface, which is how chatStore's streamChatCompletion,\ncreateAssistantMessage, getApiOptions and setStreamingActive got\nwidened to public. Replace with per-collaborator interfaces carrying\nonly the members each one drives:\n\n- ChatStreamHost (chat/streams) - activity, processing, streaming\n  states, abort controller, loading/streaming setters\n- ChatFlowsHost (chat/flows) - streaming core, message creation,\n  per-conv state setters\n- McpHealthHost (mcp/health) - connection registry + reconnection\n- ModelPropsHost / ModelStatusHost (models) - model rows, feed\n  updates; the managers write modalities/status back onto the host's\n  rows, so those members stay writable\n- ConversationsPreferencesHost (conversations) - the active row and\n  the conversation list\n\nThe store classes now declare 'implements <Host>' so the contract is\nvisible at the class level, and the 'import type { <store> }' back\nreferences in the collaborators disappear entirely - the host\ncontract is local to each collaborator file, and collaborators can\nno longer reach around their slice. Members stay public (structural\ntyping), but the collaborator side is now compiler-enforced.\n\n* test: Chat Activity store test\n\n* refactor: Cleanup\n\n* chore: Remove legacy architecture docs\n\n* ui: Memoize findMessageIndex for the streaming hot path\n\nStreaming looks up the same message index on every chunk, a linear\nscan of activeMessages each time. Cache the last lookup and reuse it\nafter validating the id still sits at the same position (O(1)); any\nstructural change to the array fails validation and falls back to a\nfull scan.\n\n* ui: Throttle per-chunk stream state writes to localStorage\n\nsaveStreamState ran JSON.stringify + a synchronous localStorage.setItem\non every decoded chunk of the stream. The read loop now goes through a\nnew saveStreamStateThrottled (one write per conversation per 500ms,\nlatest value held pending); the public saveStreamState keeps its\nimmediate-write contract for stream start and pre-fetch, and also\nresets the throttle window.\n\nA pending offset is force-flushed at resume boundaries (resumeStream\nreads the offset back from localStorage), on visibilitychange->hidden\nand on pagehide, so a reload always finds a usable offset. The resume\noffset only needs to be roughly current since the server retransmits\nfrom a line boundary and the client discards its partial line.\n\nAdds unit tests for the throttled/flush/clear interplay.\n\n* ui: Compute context gauge timing stats in one pass\n\ncurrentRead/Fresh/Cache/Output were separate deriveds, each running a\nfull reverse scan of activeMessages for the last assistant timings,\nand cumulative ran its own forward scan plus an agentic filter - 4-5\nO(n) passes per chunk while streaming. Replace with a single\nsummarizeAssistantTimings() pass (last assistant timings, last\nagentic llm totals and the cumulative sums) feeding a shared derived\nsnapshot. Semantics unchanged, including the live-stats overrides and\nthe agentic llm-totals branch.\n\n* agentic : clear session state when a conversation is deleted\n\nEvery conversation that ran an agentic flow left an AgenticSession in the\nstore forever; clearSession was never called. conversationsStore now\nnotifies deletion listeners and agenticStore drops the matching sessions,\navoiding a circular import back into conversationsStore.\n\n* chat : extract ChatService.normalizeMessagesForApi\n\nThe DB->API message normalization (convert + drop empty system messages)\nwas duplicated in sendMessage, preEncode and the agentic flow. Extract it\ninto one shared method and call it from all three.\n\n* sse : share record splitting and data extraction\n\nsplitSseRecords and extractSseDataPayload centralize the record-boundary\nsplitting and data: line extraction used by parseSseJsonStream and the\nmodels status feed. chat.service keeps its own line-based parser for\nresume support.\n\n* api : delegate apiFetchWithParams to apiFetch\n\napiFetchWithParams duplicated apiFetch's headers/fetch/error handling\nbody-for-body; it only differs in URL construction. Build the URL and\ndelegate.\n\n* chat flows : dedupe title, timings and cleanup handling\n\n- conversationsStore.applyTitleFromContent centralizes the title-from-first-\n  message logic duplicated in 5 places\n- ChatProcessingStore.applyStreamTimings centralizes the onTimings handler\n  shared by the chat and continue flows\n- host.cleanupStreaming centralizes the loading/streaming/processing reset\n  repeated across the continue flow's exit paths\n\n* conversations : centralize conversation update mirroring\n\nrename, pin, mcp override, reasoning effort and cwd all repeated the same\nwrite-DB-then-mirror-into-list-and-active dance. A single\napplyConversationUpdate(id, updates) on the host collapses all five and\nremoves the forgot-to-mirror-one-field bug class. Drops the redundant\narray reassignment in setCwd (deep  field assignment is reactive).\n\n* mcp : dedupe tool execution, server parsing and tool indexing\n\n- executeTool delegates to executeToolByName (only diff was argument parsing)\n- drop the private #parseServerSettings copy; use parseMcpServerSettings\n- cache getServers() keyed on the raw config value (hot path)\n- indexServerTools() unifies the three identical toolsIndex rebuild loops\n\nAssisted-by: Claude\n\n* mcp : share cursor pagination and tool indexing\n\n- MCPService.paginate() collapses the identical do-while loops in\n  listAllResources and listAllResourceTemplates\n- promoteHealthCheckToConnection now uses indexServerTools like the other\n  connect paths\n\nAssisted-by: Claude\n\n* database : share message parent-child bookkeeping\n\n- addChildToParent() dedups the append-to-children update in createMessageBranch\n  and createSystemMessage\n- removeChildFromParent() dedups the remove-from-children cleanup in deleteMessage\n  and deleteMessageCascading\n- bulkAdd the cloned messages when forking a conversation instead of one add\n  per message\n\nAssisted-by: Claude\n\n* chore: Lint/format\n\n* fix: `pagehide` event from `window`\n\n* refactor: Api Fetch util\n\n* docs : rewrite architecture sections in README\n\nUpdate the high-level diagram, routes, hooks, stores, services and data\nflow tables to match the current UI structure (mcp/settings/search\nroutes, agentic/tools/mcp stores, MCPService/ToolsService/SandboxService,\n/tools API). Fix stale architectural patterns for per-conversation state\nand modality validation.\n\n* chore : add ESLint rule for blank lines between accessors\n\nEnforce a blank line between consecutive class accessors. The core\npadding-line-between-statements rule does not cover class members, so a\nlocal rule is needed.\n\n* refactor : reorder store members and unify naming\n\nOrder store class members as public fields, private fields, constructor,\ngetters, public methods, then private methods. Normalize private naming\nto the `private` keyword (drop `#` and the `_` prefix where there is no\nmatching public getter). Rename conversationsStore.init() to\ninitialize() to match the other stores.\n\n* refactor : prefix lookup methods with get in agentic and chat stores\n\nUnify bare-name lookup methods with the get* prefix used across the\nother stores (mcp, models, tools, settings). Renames currentTurn,\ntotalToolCalls, lastError, streamingToolCall, executingToolCallId,\npendingPermissionRequest, pendingContinueRequest,\npendingSteeringMessageContent, pendingSteeringMessageExtras in the\nagentic store and pendingMessageContent, pendingMessageExtras in the\nchat store. Updates the two consuming components and a doc comment.\n\n* refactor: Clean up comments in stores' and services' code\n\n* chore : add ESLint rule for class member ordering\n\nEnforce structural order (public fields -> private fields -> constructor ->\ngetters -> setters -> public methods -> private methods) with alphabetical\nsorting within each group via perfectionist/sort-classes. Dependency\ndetection keeps Svelte $derived fields in a valid dependency order instead\nof alphabetizing them, since Svelte rejects forward references.\n\nAssisted-by: Claude\n\n* refactor : reorder class members to match new ESLint rule\n\nApply the sort-classes rule across stores, services, hooks and utils.\nPure reordering - verified no logic changes by comparing sorted line\nmultisets before/after. All tests and svelte-check pass."},{"name":"package-lock.json","kind":"file","size":585457,"lastCommitHash":"92d1bb0c996f49bb09561f755ba784565e1aa51c","lastCommitWhen":"2026-08-10T08:38:37+02:00","lastCommitMessage":"ui: Linting & Formatting scripts (#26819)"},{"name":"package.json","kind":"file","size":3963,"lastCommitHash":"92d1bb0c996f49bb09561f755ba784565e1aa51c","lastCommitWhen":"2026-08-10T08:38:37+02:00","lastCommitMessage":"ui: Linting & Formatting scripts (#26819)"},{"name":"playwright.config.ts","kind":"file","size":653,"lastCommitHash":"92d1bb0c996f49bb09561f755ba784565e1aa51c","lastCommitWhen":"2026-08-10T08:38:37+02:00","lastCommitMessage":"ui: Linting & Formatting scripts (#26819)"},{"name":"pwa-assets-dark.config.ts","kind":"file","size":648,"lastCommitHash":"e21152dc9636c6d2db6edc9b4531dfc5b2d1cba3","lastCommitWhen":"2026-08-13T06:53:56+02:00","lastCommitMessage":"ui: Constants refactor (#26908)\n\n* refactor: Constants\n\n* refactor: Constants/Enums cleanup\n\n* refactor: Constant objects instead of multiple single value constants\n\n* refactor: Cleanup constants"},{"name":"pwa-assets.config.ts","kind":"file","size":2056,"lastCommitHash":"e21152dc9636c6d2db6edc9b4531dfc5b2d1cba3","lastCommitWhen":"2026-08-13T06:53:56+02:00","lastCommitMessage":"ui: Constants refactor (#26908)\n\n* refactor: Constants\n\n* refactor: Constants/Enums cleanup\n\n* refactor: Constant objects instead of multiple single value constants\n\n* refactor: Cleanup constants"},{"name":"README.md","kind":"file","size":26082,"lastCommitHash":"521a64cd01979bb5b1a466152c576a9d809b068d","lastCommitWhen":"2026-08-20T19:02:04+02:00","lastCommitMessage":"ui: Stores split refactor (#27240)\n\n* ui: Extract server stream lifecycle from chatStore into ChatStreamManager\n\nDiscovery, attach/replay, resume retry and the remote-running snapshot\nformed a cohesive cluster inside chatStore. It now lives in\nchat-streams.svelte.ts as ChatStreamManager, owned by chatStore, which\nkeeps the public entry points as delegates so components are\nunchanged. chatStore: 2877 -> 2418 lines.\n\n* ui: Extract user interaction gates from agenticStore into AgenticGates\n\nTool permission requests, turn-limit continue prompts and queued\nsteering messages are the state the loop waits on between turns. They\nhad no coupling to session state, so they now live in\nagentic-gates.svelte.ts; agenticStore keeps delegates so components\nare unchanged. agenticStore: 1196 -> 1073 lines.\n\n* ui: Compose MCP resources under mcpStore.resources\n\nResource state was a second import scope next to mcpStore. Consumers\nnow go through mcpStore.resources, so the MCP surface is one store;\nmcp-resources.svelte.ts stays a separate file owned by mcpStore.\n\n* ui: Reorganize stores into domain namespaces\n\n* fix: Update stale doc comments\n\n* ui: Consolidate conv running-state into a chat activity ledger\n\nRunning-state was split across chatStore.chatLoadingStates (local\npipes), ChatStreamManager.remoteRunningConvs (backend sessions) and\nattachingConvs (attach lifecycle), unioned by hand in\ngetAllLoadingChats and cross-cleaned by setChatLoading calling\nstreams.clearRemoteRunning - the 'spinner ghosts until tab toggle'\nworkaround.\n\nchatActivityStore now owns both sets with one transition per event:\nmarkLocal / localEnded (local pipe end also drops the stale remote\nhint, no cross-owner call) / applyRemoteSnapshot (diffed). The\nsidebar reads chatStore.activity.loadingConvs through the unchanged\ngetAllLoadingChats entry point.\n\nConsequences:\n- isStreamingActive and its five manual writers are gone; isStreaming()\n  now reports whether the active conversation has a live streaming\n  pipe, which is what all four consumers (assistant row, stop action,\n  context gauge, chat screen) actually check\n- isLoading/isReasoning become derived from the per-conv maps plus\n  the active conversation, dropping the manual resync in\n  syncLoadingStateForChat and clearUIState\n- attachingConvs and the last-attach coordination disappear from\n  ChatStreamManager\n- getAllStreamingChats (no consumers) is removed\n\n* ui: Give store collaborators narrow host interfaces\n\nCollaborators took 'host: typeof <store>', i.e. the store's entire\npublic surface, which is how chatStore's streamChatCompletion,\ncreateAssistantMessage, getApiOptions and setStreamingActive got\nwidened to public. Replace with per-collaborator interfaces carrying\nonly the members each one drives:\n\n- ChatStreamHost (chat/streams) - activity, processing, streaming\n  states, abort controller, loading/streaming setters\n- ChatFlowsHost (chat/flows) - streaming core, message creation,\n  per-conv state setters\n- McpHealthHost (mcp/health) - connection registry + reconnection\n- ModelPropsHost / ModelStatusHost (models) - model rows, feed\n  updates; the managers write modalities/status back onto the host's\n  rows, so those members stay writable\n- ConversationsPreferencesHost (conversations) - the active row and\n  the conversation list\n\nThe store classes now declare 'implements <Host>' so the contract is\nvisible at the class level, and the 'import type { <store> }' back\nreferences in the collaborators disappear entirely - the host\ncontract is local to each collaborator file, and collaborators can\nno longer reach around their slice. Members stay public (structural\ntyping), but the collaborator side is now compiler-enforced.\n\n* test: Chat Activity store test\n\n* refactor: Cleanup\n\n* chore: Remove legacy architecture docs\n\n* ui: Memoize findMessageIndex for the streaming hot path\n\nStreaming looks up the same message index on every chunk, a linear\nscan of activeMessages each time. Cache the last lookup and reuse it\nafter validating the id still sits at the same position (O(1)); any\nstructural change to the array fails validation and falls back to a\nfull scan.\n\n* ui: Throttle per-chunk stream state writes to localStorage\n\nsaveStreamState ran JSON.stringify + a synchronous localStorage.setItem\non every decoded chunk of the stream. The read loop now goes through a\nnew saveStreamStateThrottled (one write per conversation per 500ms,\nlatest value held pending); the public saveStreamState keeps its\nimmediate-write contract for stream start and pre-fetch, and also\nresets the throttle window.\n\nA pending offset is force-flushed at resume boundaries (resumeStream\nreads the offset back from localStorage), on visibilitychange->hidden\nand on pagehide, so a reload always finds a usable offset. The resume\noffset only needs to be roughly current since the server retransmits\nfrom a line boundary and the client discards its partial line.\n\nAdds unit tests for the throttled/flush/clear interplay.\n\n* ui: Compute context gauge timing stats in one pass\n\ncurrentRead/Fresh/Cache/Output were separate deriveds, each running a\nfull reverse scan of activeMessages for the last assistant timings,\nand cumulative ran its own forward scan plus an agentic filter - 4-5\nO(n) passes per chunk while streaming. Replace with a single\nsummarizeAssistantTimings() pass (last assistant timings, last\nagentic llm totals and the cumulative sums) feeding a shared derived\nsnapshot. Semantics unchanged, including the live-stats overrides and\nthe agentic llm-totals branch.\n\n* agentic : clear session state when a conversation is deleted\n\nEvery conversation that ran an agentic flow left an AgenticSession in the\nstore forever; clearSession was never called. conversationsStore now\nnotifies deletion listeners and agenticStore drops the matching sessions,\navoiding a circular import back into conversationsStore.\n\n* chat : extract ChatService.normalizeMessagesForApi\n\nThe DB->API message normalization (convert + drop empty system messages)\nwas duplicated in sendMessage, preEncode and the agentic flow. Extract it\ninto one shared method and call it from all three.\n\n* sse : share record splitting and data extraction\n\nsplitSseRecords and extractSseDataPayload centralize the record-boundary\nsplitting and data: line extraction used by parseSseJsonStream and the\nmodels status feed. chat.service keeps its own line-based parser for\nresume support.\n\n* api : delegate apiFetchWithParams to apiFetch\n\napiFetchWithParams duplicated apiFetch's headers/fetch/error handling\nbody-for-body; it only differs in URL construction. Build the URL and\ndelegate.\n\n* chat flows : dedupe title, timings and cleanup handling\n\n- conversationsStore.applyTitleFromContent centralizes the title-from-first-\n  message logic duplicated in 5 places\n- ChatProcessingStore.applyStreamTimings centralizes the onTimings handler\n  shared by the chat and continue flows\n- host.cleanupStreaming centralizes the loading/streaming/processing reset\n  repeated across the continue flow's exit paths\n\n* conversations : centralize conversation update mirroring\n\nrename, pin, mcp override, reasoning effort and cwd all repeated the same\nwrite-DB-then-mirror-into-list-and-active dance. A single\napplyConversationUpdate(id, updates) on the host collapses all five and\nremoves the forgot-to-mirror-one-field bug class. Drops the redundant\narray reassignment in setCwd (deep  field assignment is reactive).\n\n* mcp : dedupe tool execution, server parsing and tool indexing\n\n- executeTool delegates to executeToolByName (only diff was argument parsing)\n- drop the private #parseServerSettings copy; use parseMcpServerSettings\n- cache getServers() keyed on the raw config value (hot path)\n- indexServerTools() unifies the three identical toolsIndex rebuild loops\n\nAssisted-by: Claude\n\n* mcp : share cursor pagination and tool indexing\n\n- MCPService.paginate() collapses the identical do-while loops in\n  listAllResources and listAllResourceTemplates\n- promoteHealthCheckToConnection now uses indexServerTools like the other\n  connect paths\n\nAssisted-by: Claude\n\n* database : share message parent-child bookkeeping\n\n- addChildToParent() dedups the append-to-children update in createMessageBranch\n  and createSystemMessage\n- removeChildFromParent() dedups the remove-from-children cleanup in deleteMessage\n  and deleteMessageCascading\n- bulkAdd the cloned messages when forking a conversation instead of one add\n  per message\n\nAssisted-by: Claude\n\n* chore: Lint/format\n\n* fix: `pagehide` event from `window`\n\n* refactor: Api Fetch util\n\n* docs : rewrite architecture sections in README\n\nUpdate the high-level diagram, routes, hooks, stores, services and data\nflow tables to match the current UI structure (mcp/settings/search\nroutes, agentic/tools/mcp stores, MCPService/ToolsService/SandboxService,\n/tools API). Fix stale architectural patterns for per-conversation state\nand modality validation.\n\n* chore : add ESLint rule for blank lines between accessors\n\nEnforce a blank line between consecutive class accessors. The core\npadding-line-between-statements rule does not cover class members, so a\nlocal rule is needed.\n\n* refactor : reorder store members and unify naming\n\nOrder store class members as public fields, private fields, constructor,\ngetters, public methods, then private methods. Normalize private naming\nto the `private` keyword (drop `#` and the `_` prefix where there is no\nmatching public getter). Rename conversationsStore.init() to\ninitialize() to match the other stores.\n\n* refactor : prefix lookup methods with get in agentic and chat stores\n\nUnify bare-name lookup methods with the get* prefix used across the\nother stores (mcp, models, tools, settings). Renames currentTurn,\ntotalToolCalls, lastError, streamingToolCall, executingToolCallId,\npendingPermissionRequest, pendingContinueRequest,\npendingSteeringMessageContent, pendingSteeringMessageExtras in the\nagentic store and pendingMessageContent, pendingMessageExtras in the\nchat store. Updates the two consuming components and a doc comment.\n\n* refactor: Clean up comments in stores' and services' code\n\n* chore : add ESLint rule for class member ordering\n\nEnforce structural order (public fields -> private fields -> constructor ->\ngetters -> setters -> public methods -> private methods) with alphabetical\nsorting within each group via perfectionist/sort-classes. Dependency\ndetection keeps Svelte $derived fields in a valid dependency order instead\nof alphabetizing them, since Svelte rejects forward references.\n\nAssisted-by: Claude\n\n* refactor : reorder class members to match new ESLint rule\n\nApply the sort-classes rule across stores, services, hooks and utils.\nPure reordering - verified no logic changes by comparing sorted line\nmultisets before/after. All tests and svelte-check pass."},{"name":"sources.cmake","kind":"file","size":296,"lastCommitHash":"6cb18b2f2ec72c177681051f22e7e7a4f154bb99","lastCommitWhen":"2026-06-29T10:55:52+02:00","lastCommitMessage":"tools/ui: restore Tailwind scanning in ignored worktrees (#24879)"},{"name":"svelte.config.js","kind":"file","size":858,"lastCommitHash":"f2efd64141b9f9003c592375adf287f5fe1e5b80","lastCommitWhen":"2026-08-13T08:13:52+02:00","lastCommitMessage":"ui: Move `styles/` to `$lib` scope (#26950)\n\n* refactor: Move `styles/` to `src/lib` and remove legacy alias\n\n* chore: Add newline"},{"name":"tsconfig.json","kind":"file","size":1031,"lastCommitHash":"61328e6a9150b5d83f70416c93d2dfa607b442d0","lastCommitWhen":"2026-07-22T17:52:55+02:00","lastCommitMessage":"feat(ui): add symbolic math support to JS sandbox via nerdamer (#25948)\n\n* feat(ui): add symbolic math support to JS sandbox via nerdamer\n\nPreload nerdamer (with decimal.js) in the sandboxed worker,\nexposing the `nerdamer` global for symbolic computation:\nsimplify, expand, factor, diff, integrate, solve, laplace,\nilt, limit, partfrac, gcd/lcm, roots, coefficients, and more.\n\nMirrors the math.js integration pattern from the\nfeature/sandbox-symbolic-math branch, but uses nerdamer\nfor a lighter, more focused symbolic math engine.\n\n* Update sandbox-harness.ts\n\n* docs(ui): update sandbox tool description with detailed nerdamer usage guide\n\n* Clarify nerdamer usage in sandbox tool description\n\nUpdated the description of the sandbox tool to clarify usage of nerdamer.\n\n* ui: build nerdamer sandbox prelude from vendored source\n\nReplace the vendored all.min.js with the readable nerdamer-prime\nsource and its two bundled deps (big-integer, decimal.js), licenses\nincluded. A vite plugin bundles and minifies them at build time with\nthe upstream esbuild flags, exposed as virtual:nerdamer and imported\nlazily on first sandbox use. The vendors package.json pins commonjs\nso the project level type: module does not break esbuild format\ndetection. The harness gains a CSP removing network egress from the\nworker, and browser tests cover the prelude, exact arithmetic, the\nfetch block and the timeout.\n\nUpstream snapshot: together-science/nerdamer-prime@1936145\n\n* feat(ui): make symbolic math (nerdamer) a user-toggleable setting\n\n- Add SYMBOLIC_MATH_ENABLED setting key and registry entry (checkbox, default false)\n- Convert SANDBOX_TOOL_DEFINITION to buildSandboxToolDefinition(includeSymbolicMath)\n  so the tool description includes/excludes nerdamer API docs dynamically\n- Cache sandbox harness per variant ('nerdamer' / 'plain') for instant toggle\n- Deprecate SANDBOX_TOOL_DEFINITION constant alias for backward compatibility\n- Update tools store to pass symbolic math config into tool definition\n\n* docs(ui): tell LLM to list nerdamer functions first, do not guess\n\n* test(ui): enable symbolic math in sandbox tests via settingsStore config\n\n* style(ui): fix formatting for tools.svelte.ts\n\n---------\n\nCo-authored-by: Pascal <admin@serveurperso.com>"},{"name":"vite.config.ts","kind":"file","size":2807,"lastCommitHash":"9c5531e2bf2c95e86eeac807d7109de29266ca7b","lastCommitWhen":"2026-08-13T19:31:51+02:00","lastCommitMessage":"ui: fix VITE_PUBLIC_SERVER variable reading (#24845)"},{"name":"vitest-setup-client.ts","kind":"file","size":2400,"lastCommitHash":"92d1bb0c996f49bb09561f755ba784565e1aa51c","lastCommitWhen":"2026-08-10T08:38:37+02:00","lastCommitMessage":"ui: Linting & Formatting scripts (#26819)"},{"name":"vitest.shims.d.ts","kind":"file","size":53,"lastCommitHash":"6db130445d29b243ee2171efb8cd61b84a1c5322","lastCommitWhen":"2026-05-19T10:16:04+02:00","lastCommitMessage":"ui: Bump packages + address build warnings (#23300)\n\n* chore: Update vulnerable packages\n\n* chore: Formatting\n\n* refactor: Update Tailwind CSS imports\n\n* ci: Use `ubuntu-latest` for Unit/E2E UI tests\n\n* chore: Bump package\n\n* fix: Add missing tag\n\n* refactor: Enums files naming"}]