# Ulysses Improvement Tasks Last updated: 2026-07-08 ## Priority: HIGH - [ ] **Agent toolcalling loop: model narrates actions but never emits fenced blocks** Gemma-4-12b repeatedly narrates intent ("I'm calling list_vault now") without emitting the ```tool fenced block. The model clearly understands what it should do but the fenced block never arrives. This blocks agent workflows entirely when it occurs (~25% of tool calls). The anti-hallucination system prompt rule drafted yesterday is staged but not live (container not restarted). Need to investigate whether this is: (a) the missing system prompt rule, (b) a regex/parsing issue in parse_tool_blocks(), (c) the compact API-model prompt confusing non-tool-native models, or (d) a context/truncation issue preventing the fenced block from reaching the parser. - [ ] **Chat deletion dropdown broken — does not appear** Clicking the arrow on a chat in the left drawer no longer shows the dropdown menu (rename/delete/etc.). Cannot delete chats. Likely a JS event listener or DOM positioning issue — possibly zoom-related getBoundingClientRect() skew or a regression from recent dropdown/popup fixes. - [ ] **AUTO_START_LOCAL: persist & auto-restore last running model on restart** New `AUTO_START_LOCAL` env var (bool, default false). On graceful shutdown/restart, persist the currently running model + all launch parameters (engine, quantization, context length, GPU layers, etc.) to a file in `/app/data/`. On startup, if the file exists and AUTO_START_LOCAL is true, automate the full launch pipeline: resolve the saved preset, spin up the engine, and register the endpoint — skipping the manual cookbook → Launch → pick model → verify params → launch → wait → refresh cycle the user currently endures on every restart. - [ ] **Floating windows overflow viewport after zoom/font changes — unreachable controls** `:root.ui-scale-125 { zoom: 1.25 }` renders all content 25% larger, but `window.innerHeight` doesn't change with `zoom` (CSS rendering only, not DOM). The `windowResize.js` saved-size restore at line 224 clamps to `window.innerHeight`, which after zoom makes windows 1.25× the visible viewport — pushing headers, close buttons, and top resize handles off-screen. The user literally can't close or move them. Fix: (a) divide restored height by zoom factor in the restore path; (b) add a general safety net — any `.modal-content` on open should clamp to `calc(100dvh / var(--ui-zoom, 1) - 40px)`. Also `windowResize.js` line 134 `if (top + height > vh)` needs zoom-aware `vh`. Current zoom compensation rules (line 181-196) only cover `.modal-content`, `.cal-modal-content`, `.settings-modal-content`, `#theme-popup`, `#cookbook-modal`, and `.pdf-export-overlay` — many windows lack the divisor. - [x] **Fix manage_documents tool schema — missing "read" action** The `manage_documents` function-calling schema in `tool_schemas.py` had `"enum": ["list", "delete", "tidy"]` but the handler in `document_tools.py` supports `"read", "view", "open", "get"`. The model couldn't read documents through function calling. Fixed: added read/view/open/get to enum, added `document_id`/`offset`/`limit` params with read-specific descriptions, updated description with "DOCUMENT PANEL (not disk)" prefix. Also added disambiguation prefix to `create_document` and `edit_document` schemas. - [x] **Add "Send to Chat" button to document editor** Button left of the Save button in `#doc-actions-footer`. Sends a document reference (title + doc_id + snippet) to the active chat, similar to how Cursor injects file references. Must NOT paste full content — just a reference the agent can resolve. Done: "Chat" button injects `[Title](#document-) — <120-char snippet>` into the #message textarea. ## Priority: MEDIUM - [ ] **Bolster Library/Documents CRUD via MCP or native tools** Current document tools are solid but disjointed from agent-mode workflow. The agent has filesystem access (`read_file`, `write_file`, `edit_file`, `glob`, `ls`, `grep`, `bash`) but these tools operate on disk files, not Ulysses library documents. Need to bridge the gap: the agent should be able to list, read, grep, and edit library documents as naturally as files. Consider: - A unified `read_document` tool distinct from `manage_documents` (which is an admin-style multi-action tool) - A `grep_documents` or `search_documents` tool for semantic/fulltext search - Auto-inject active document content into agent context when relevant - [ ] **Deep Research: "Send to Chat" reference + agent MCP tool to read reports** Two-part feature: **(1) UI** — Add a button (alongside "Discuss") to inject a research reference (`[Title](#research-)`) into the active chat's message input, matching the document "Chat" button pattern. Applies to: research panel sidebar (panel.js:1012), research library cards (documentLibrary.js:2767), and inline result messages (chatRenderer.js:1070). **(2) Agent tooling** — Research reports are HTML artifacts served at `/api/research/report/`, not library documents. The agent currently can't resolve a research reference — pasting an ID gets a blank stare. Need an MCP tool (e.g. `read_research` or `get_research_report`) that accepts a research ID, fetches the report HTML, strips it to readable text, and returns it to the agent. Without this, the "Send to Chat" reference is dead text. - [ ] **First-party document support in agent mode** Documents feel "disjointed from the agent." The agent creates documents fine but can't easily discover or reference existing ones contextually. Ideas: - "Agent workspace" awareness — automatically surface relevant documents based on chat context - Document references in chat that are clickable and auto-expand - The "Send to Chat" button (HIGH priority) is step 1; step 2 is making the agent proactively aware of library contents - [x] **Improve `create_document` schema description** Current description is verbose and overlaps with `edit_file`/`write_file` disambiguation. Models sometimes use `create_document` for disk files. Fixed: added "DOCUMENT PANEL (not disk)" prefix, explicit "For files on disk use write_file" at end. Also applied to `edit_document`. ## Priority: LOW - [ ] **Cookbook sliders: active highlight misaligned with zoom** The rounded highlight on CPU/GPU/RAM etc. toggle sliders doesn't scale with `ui-scale-125`. The active indicator (e.g. "GPU") is partially outside the highlight pill. Low priority — cosmetic, obvious which option is selected. - [ ] **Document library: batch operations** Multi-select, bulk delete, bulk export. Currently only single-document operations. - [ ] **Document version diff view** The version history panel shows versions but doesn't offer a side-by-side diff view between versions. - [ ] **Auto-language detection on document open** The editor auto-detects language on typing but not on initial document open from the library. Opening a Python file saved as "markdown" should suggest the language switch. --- ## Completed - [x] **2026-07-08: Edit message textarea now fills full message width** `.msg-user { width: fit-content }` collapsed container when body swapped for textarea. CSS: `.msg-user.editing { width: 85% !important }`. JS: `editUserMessage()` adds/removes `editing` class. (commit f0031ea)