Commit Graph

15651 Commits

Author SHA1 Message Date
Timothy Jaeryang Baek
7806cd5aef feat: use CodeMirror editor for HTML source view, hide save in preview mode
- HTML preview (iframe) no longer shows Edit/Save toolbar buttons
- Clicking Source toggle opens CodeMirror editor with syntax highlighting
- Save button appears only in source mode, using saveCodeFile()
- Ctrl+S saving supported via CodeMirror keybinding
2026-03-06 20:00:12 -06:00
Timothy Jaeryang Baek
b3622474d7 refac 2026-03-06 16:25:00 -06:00
Timothy Jaeryang Baek
d8bb8c58d0 refac 2026-03-06 16:21:42 -06:00
Classic298
d93cb3658d perf(models): batch-fetch function valves to eliminate N+1 queries (#22301)
* perf(models): batch-fetch function valves to eliminate N+1 queries

get_action_priority() called Functions.get_function_valves_by_id()
individually for every action on every model — an N+1 query pattern
that issued one DB round-trip per (action x model) pair.

Add Functions.get_function_valves_by_ids() that fetches all valves in
a single WHERE IN query, then look up each action's valves from the
pre-fetched dict inside get_action_priority().

No functional change — same priority resolution, same sort order.

* Update models.py

* Update models.py
2026-03-06 15:56:01 -06:00
Shirasawa
200fb093b1 fix: Use toBlob on first mobile export to avoid black canvas image on Android (#22317) 2026-03-06 15:48:44 -06:00
Timothy Jaeryang Baek
4ab831b259 refac 2026-03-06 15:42:13 -06:00
Classic298
576ee92438 perf: rewrite createMessagesList from recursive to iterative (#22194)
Replace the recursive spread-based implementation with an iterative
push+reverse approach. The recursive version created a new array at
each level of recursion via spread, resulting in O(d^2) array copies
where d is the conversation depth. The iterative version walks from
the target message to the root, pushes each message, and reverses
once at the end for O(d) total work.

No behavioral change - same input produces the same output array.
2026-03-06 15:36:13 -06:00
Timothy Jaeryang Baek
af4500e504 refac 2026-03-06 15:29:38 -06:00
Timothy Jaeryang Baek
016928722c refac 2026-03-06 15:23:29 -06:00
Timothy Jaeryang Baek
73b69ae408 refac 2026-03-06 15:13:21 -06:00
Timothy Jaeryang Baek
80376a3fdc revert 2026-03-06 15:05:36 -06:00
Timothy Jaeryang Baek
305e591ec2 feat: use CodeMirror for always-editable code file preview
- Add FileCodeEditor.svelte: CodeMirror wrapper with auto language
  detection, dark mode, Ctrl+S save, reactive to value/filePath changes
- Replace Shiki read-only highlighting + textarea editing with
  always-editable CodeMirror for code files in FileNav preview
- Show persistent Save button for code files in toolbar
- Non-code text files keep existing Edit/Save/Cancel textarea flow
- SVG retains Shiki highlighting for visual preview mode
2026-03-06 15:03:23 -06:00
Algorithm5838
39deadcab1 perf: convert APIKeyRestrictionMiddleware to pure ASGI (#22188) 2026-03-06 14:54:03 -06:00
Timothy Jaeryang Baek
2153c8ec9f refac 2026-03-06 14:53:09 -06:00
Classic298
a70c718a0d fix: TTS reading thinking content when reasoning has code blocks (#22237)
removeAllDetails() uses replaceOutsideCode() which splits content on
triple-backtick code blocks before applying the details-removal regex.

When thinking/reasoning content inside a <details> block contained
code blocks (backticks survive html.escape), the <details> opening
and </details> closing tags ended up in different split segments,
making the regex unable to match either. This caused thinking content
to leak through to TTS playback.

Fix: add a direct <details> strip (without code-block splitting) as
the first step of getMessageContentParts(), which is the TTS-specific
entry point. This catches the edge case while keeping removeAllDetails
safe for copy-to-clipboard (where legitimate <details> inside code
blocks should be preserved).

Fixes #22197
2026-03-06 14:46:31 -06:00
Classic298
c73efab192 feat: load banners on navigation to homepage, not only on refresh (#22340) 2026-03-06 14:46:00 -06:00
Classic298
ce54b1df23 perf: guard TTS sentence parsing behind showCallOverlay check (#22195)
The chatCompletionEventHandler runs getMessageContentParts() and
removeAllDetails() on every streaming token to extract sentences
for real-time TTS dispatch via CustomEvent('chat'). These functions
perform multiple O(n) regex passes over the full accumulated message
content, resulting in O(n^2) total work over a streaming response.

The only consumer of these events is CallOverlay.svelte, which is
only mounted when showCallOverlay is true. Without the overlay open,
the parsing runs but the dispatched events have no listeners.

Wrap all three TTS parsing blocks in an if () guard
so the expensive regex work is skipped entirely for the vast majority
of users who are not using the voice call feature.
2026-03-06 14:32:05 -06:00
Classic298
16701befe7 fix: show floating action buttons when chat model is unavailable (#22149) 2026-03-06 14:30:24 -06:00
Abdul Moiz
8a6af40d9f fix: correct conflicting output format instruction in follow-up generation prompt (#22212)
The Guidelines section instructed LLMs to return "a JSON array of strings"
while the Output section showed a JSON object with a "follow_ups" key.
This mismatch caused some models to return a top-level array, which the
frontend parser cannot handle (it looks for `{ }` delimiters and the
`follow_ups` key). Updated the guideline to consistently request a JSON
object matching the expected format.

Fixes #22187
2026-03-06 14:25:42 -06:00
Shamil
9cf6108527 feat: add otel system metrics instrumentation (#22265) 2026-03-06 14:24:24 -06:00
Algorithm5838
1c1c1c3100 fix: allow clearing file upload settings (#22336) 2026-03-06 14:23:20 -06:00
Timothy Jaeryang Baek
def954134c refac 2026-03-06 14:21:38 -06:00
Timothy Jaeryang Baek
c85afce702 fix: import
Co-Authored-By: Steven Schveighoffer <580778+schveiguy@users.noreply.github.com>
2026-03-06 14:10:50 -06:00
Algorithm5838
a25ecfa856 perf: skip token parsing when raw content is unchanged (#22183) 2026-03-06 14:08:12 -06:00
Timothy Jaeryang Baek
47b007ef19 refac 2026-03-06 14:07:34 -06:00
Classic298
04fae8b357 fix: use NullPool for SQLCipher engine to prevent segfault (#22273)
The SQLCipher engine used a dummy sqlite:// URL with a creator function,
which caused SQLAlchemy to auto-select SingletonThreadPool. This pool
non-deterministically closes in-use connections when thread count exceeds
pool_size (default 5), leading to use-after-free segfaults (exit code 139)
in the native sqlcipher3 C library during multi-threaded operations like
user signup.

Now defaults to NullPool (each operation creates/closes its own connection)
for maximum safety with the native C extension. Also respects the
DATABASE_POOL_SIZE setting: if explicitly set >0, QueuePool is used with
the configured pool parameters, matching the behavior of other DB paths.

Fixes #22258
2026-03-06 14:04:10 -06:00
Classic298
1850a985b5 perf: replace O(n²) unshift with O(n) push+reverse in buildMessages (#22280)
Array.unshift() is O(n) per call because it shifts all existing
elements. In a loop building an n-element array, this makes the
total cost O(n²). Replace with push() + reverse() which is O(n)
total. Produces the identical message ordering.
2026-03-06 14:02:57 -06:00
Timothy Jaeryang Baek
339ed1d72e refac 2026-03-06 14:02:05 -06:00
Erhhung Yuan
fa1ebfa4fd fix: use same metric description as OTel (#22192) (#22293)
Signed-off-by: Erhhung Yuan <erhhung@gmail.com>
2026-03-06 13:58:25 -06:00
Timothy Jaeryang Baek
0820abbc64 refac 2026-03-06 13:54:55 -06:00
Shirasawa
b94e1c9458 fix: Fix memory leaking in Artifacts (#22303) 2026-03-06 13:49:06 -06:00
Classic298
fe58ef69d9 perf(frontend): lazy-load shiki to remove ~5-10MB from initial bundle (#22304)
codeHighlight.ts had a top-level static import of shiki that pulled
the entire highlighter engine (~5-10MB of JavaScript including all
language grammars) into any page that imported the module - even if
only the lightweight isCodeFile() function was used.

Replace the static shiki import with:
- A static set of ~85 common language IDs for synchronous extension
  checks (isCodeFile, extToLang) - no shiki dependency needed
- A dynamic import('shiki') inside highlightCode(), which is already
  async so callers are completely unaffected

The static language set covers all commonly-used file extensions.
Obscure extensions not in the set simply won't be detected by
isCodeFile() (the file still opens fine, just won't show the code
file indicator). Highlighting itself still works for all shiki
languages since the full bundle loads on demand.
2026-03-06 13:47:17 -06:00
Kylapaallikko
cc6b51e5ae Update fi-FI translation.json (#22328)
Added and updated translations.
2026-03-06 13:45:56 -06:00
Timothy Jaeryang Baek
cd2c315495 refac 2026-03-05 16:13:35 -06:00
Timothy Jaeryang Baek
4b3ed3e802 feat: notebook per-cell execution via open-terminal REST endpoints
- Add notebook API functions (createNotebookSession, executeNotebookCell, stopNotebookSession)
- Create CellEditor component with CodeMirror for cell editing
- Rewrite NotebookView with session-based execution, Run All, Restart, Stop
- Kernel status indicator with tooltips
- Wire baseUrl/apiKey through FilePreview and FileNav
2026-03-05 16:08:11 -06:00
Classic298
8cd2157564 Perf: precompile katex unicode regex (#22196)
* perf: pre-compile KaTeX Unicode regex at module load time

The katexStart() function was creating a new RegExp with Unicode
property escapes (\p{Script=Han}, \p{Script=Hiragana}, etc.) on
every invocation. Unicode property escapes are extremely expensive
to compile as the regex engine must build character class tables
covering tens of thousands of code points.

Since marked calls the start() function at every character position
while scanning source text, this meant hundreds of regex compilations
per marked.lexer() call, and lexer runs ~60 times/sec during streaming.
Profiling showed KaTeX regex consuming 87% (320ms/365ms) of total
markdown rendering time.

Changes:
- Pre-compile SURROUNDING_CHARS_REGEX once at module load time
- Use .test() instead of .match() to avoid array allocations
- Fix delimiter search to find earliest match, not last match

* perf: replace katexStart with single-pass character scan

The katexStart() function was the dominant cost in marked's lexer,
consuming 55-58% of total markdown rendering time per profiling.

It was called at every character position by marked and each call:
- Looped through 3-5 delimiters, each doing indexOf() on the full
  remaining source (3-5 x O(n) string scans per call)
- Ran the complex ruleReg regex with Unicode lookaheads for validation
- On failed validation, created substrings and looped again

Replace with a single linear character scan using charCodeAt that:
- Checks only for $ (charCode 36) or backslash (charCode 92)
- Filters backslash hits by next character to avoid false positives
- Preserves the surrounding-character validation
- Returns immediately on first valid candidate
- Lets the tokenizer handle full validation (it already does this)

This reduces start() from O(n * delimiters * retries) to O(n) with
a very small constant factor per call.

* Update katex-extension.ts
2026-03-05 16:02:00 -06:00
Timothy Jaeryang Baek
aaa49bdd6d refac 2026-03-05 14:52:50 -06:00
Timothy Jaeryang Baek
8da02c669e refac 2026-03-05 14:47:48 -06:00
Timothy Jaeryang Baek
828656b35f feat: auto-refresh FileNav on write_file, replace_file_content, and run_command
Backend emits terminal events for write_file, replace_file_content,
and run_command. Frontend showFileNavDir subscriber uses startsWith
path matching to smartly refresh only when the event is relevant:
- write_file/replace_file_content: refresh if path is in current view
- run_command: always refresh (uses root '/' which matches everything)
- Also adds copy-to-clipboard button and code preview full-height fix
2026-03-05 14:41:18 -06:00
Timothy Jaeryang Baek
3b97c8d89b refac 2026-03-05 13:55:02 -06:00
Timothy Jaeryang Baek
f5ea1ce250 feat: add copy-to-clipboard button next to download in file toolbar 2026-03-05 13:53:19 -06:00
Timothy Jaeryang Baek
a181b4a731 feat: add SQLite database browser in FileNav
- New SqliteView component with table tabs, paginated data view
  (100 rows/page), SQL query editor (Cmd+Enter), NULL/BLOB formatting,
  sticky column headers, and dark mode
- Supports .db, .sqlite, .sqlite3, .db3 extensions
- Uses sql.js WASM served locally from /sql.js/sql-wasm.wasm
- Also fixes display_file handling when another file is already open
2026-03-05 13:34:21 -06:00
Timothy Jaeryang Baek
114f709337 refac 2026-03-04 17:14:12 -06:00
Timothy Jaeryang Baek
a6fb5a0460 refac 2026-03-04 17:09:02 -06:00
Timothy Jaeryang Baek
7ef181bc13 refac 2026-03-04 16:52:01 -06:00
Timothy Jaeryang Baek
49a2e5bf57 feat: show refresh button when viewing files, not just directories
- Move refresh button out of directory-only block in FileNavToolbar
- When viewing a file, refresh reloads that file's content
- When in directory view, refresh reloads the listing (unchanged)
2026-03-04 16:48:01 -06:00
Classic298
4403c7b6c2 feat: Timeout for event_call events (#22222)
* Update main.py

* Update env.py

* Update main.py

* Update env.py
2026-03-04 16:39:53 -06:00
Timothy Jaeryang Baek
b081e33c0a feat: add Jupyter Notebook (.ipynb) preview in FileNav
- New NotebookView component renders markdown cells (marked+DOMPurify),
  code cells (Shiki-highlighted with execution count gutter), and
  outputs (text, HTML tables, base64 images, error tracebacks)
- ANSI escape codes stripped from error output
- Source toggle shows raw JSON
- Dark mode support throughout
2026-03-04 16:14:26 -06:00
Timothy Jaeryang Baek
f4c38e6001 feat: add JSON collapsible tree view, SVG rendered preview, and source toggle
- New JsonTreeView component with recursive collapsible nodes,
  auto-expand depth, and GitHub-themed dark mode colors
- JSON/JSONC/JSON5 files show tree view by default, toggle to
  Shiki-highlighted source
- SVG files show rendered preview (DOMPurify-sanitized) by default,
  toggle to Shiki-highlighted XML source
- SVG removed from IMAGE_EXTS to enable text-based preview
- YAML/TOML already covered by Shiki bundled languages
2026-03-04 16:10:15 -06:00
Timothy Jaeryang Baek
c40f26946f feat: add Shiki syntax highlighting, video, and audio previews in FileNav
- Add Shiki-powered syntax highlighting for code files with dual
  light/dark themes (github-light/github-dark), line numbers, and
  source/preview toggle
- Add native <video> player for mp4, webm, mov, ogv, avi, mkv
- Add native <audio> player for mp3, wav, ogg, flac, m4a, aac, opus
- New utility: src/lib/utils/codeHighlight.ts with extension-to-lang
  mapping using Shiki's bundled language registry
2026-03-04 16:04:47 -06:00