mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-06-18 10:45:31 -04:00
Settings overhaul + UI polish pass
Two months of iteration on the Settings panel, integration forms, and small visual nudges across the app. Highlights: Settings restructure - Add Models: split into separate Local + API cards (no more in-card tabs); each fuses Type/Provider with the URL input. - Added Models: new dedicated sidebar tab, with Probe + Clear-offline pulled into its header; Local/API sub-section icons accent-tinted. - Search: Web Search and a new Deep Research card (Model + tuning), with a cross-link to AI Defaults. Provider hints use real clickable anchors; Web Search Test button shows a whirlpool spinner. - AI Defaults: Image Generation card returns; Research Model card carries only Endpoint+Model with a cross-link to Search; Vision / Default / Utility fallbacks unified under one numbered-row design matching Search's chain. - API Permissions (was 'API Tokens'): per-row rename, inline Permissions toggle that expands the scope-edit panel, in-field copy icons (icon→check on success). Empty state accent-tinted. - Integrations: + Add Integration drops a type-picker menu directly under the button (drop-up on tight viewports); each integration form (API, CalDAV, CardDAV, Email, Codex/Claude, Vault, MCP) uses the same accent-outlined Save/Test/Cancel buttons right-aligned. - Danger Zone: Wipe→Delete with trash icons; new 'Delete everything' row at the bottom that loops every category. AI Synthesis (Reminders) - Persona dropdown sourced from PROMPT_TEMPLATES + custom preset. - src/reminder_personas.py mirrors the five built-ins for the server-side synthesis path. - dispatch_reminder() reads reminder_llm_persona and uses the persona's system prompt; empty/unknown falls back to warm-neutral. Esc handling - Kebab menus and the provider picker intercept Esc in capture phase so dismissing a popup no longer closes the whole Settings modal. Accent tinting - Scoped CSS rule across data-settings-panel=ai/services/added-models/ search/integrations/reminders for card h2 icons + the Added Models sub-section icons. Codex/Claude integration form - No more auto-creation on form open — explicit Create token button. - New tokens start with every scope granted; existing tokens move out of the integration form into the API Permissions card. - Setup reveal: copy buttons inline inside the token + setup code blocks; shorter subtitle wording. Misc visual polish - Save/Test/Cancel uniformly accent-outlined and right-aligned on every integration form. - Provider logos render inline next to the search fallback selects and the Deep Research Search dropdown. - Trash icons in fallback rows bumped to 20x20 so they fill the 32px button. - Image generation default flipped to off.
This commit is contained in:
@@ -199,11 +199,20 @@ def _fit_inline_attachment_text(
|
||||
return text[:remaining] + marker, 0
|
||||
|
||||
|
||||
def _process_office_document(path: str, display_name: str) -> str:
|
||||
def _process_office_document(
|
||||
path: str,
|
||||
display_name: str,
|
||||
session_id: str | None = None,
|
||||
auto_opened_docs: list[Dict[str, Any]] | None = None,
|
||||
owner: str | None = None,
|
||||
) -> str:
|
||||
"""Extract an Office/EPUB document to Markdown via the optional markitdown dep.
|
||||
|
||||
Falls back to a friendly banner when markitdown is unavailable or finds no
|
||||
text, so a missing optional dependency never breaks the chat path.
|
||||
text, so a missing optional dependency never breaks the chat path. When a
|
||||
session_id is provided AND the extraction succeeded, the FULL text is also
|
||||
saved as a Document so the agent can page through it via
|
||||
`manage_documents action=read offset=…` after the inline copy is capped.
|
||||
"""
|
||||
from src.markitdown_runtime import (
|
||||
is_markitdown_format,
|
||||
@@ -218,6 +227,46 @@ def _process_office_document(path: str, display_name: str) -> str:
|
||||
if markdown and markdown.strip():
|
||||
title = os.path.splitext(os.path.basename(path))[0]
|
||||
body, marker = _truncate_inline(markdown)
|
||||
|
||||
# Persist the full extracted text as a Document. The agent's existing
|
||||
# manage_documents tool can then read past the inline cap with offset.
|
||||
doc_id = None
|
||||
if session_id:
|
||||
try:
|
||||
from src.office_doc import create_office_document
|
||||
doc_id = create_office_document(
|
||||
session_id=session_id,
|
||||
upload_id=os.path.basename(path),
|
||||
title=title,
|
||||
body_text=markdown,
|
||||
)
|
||||
if doc_id and auto_opened_docs is not None:
|
||||
from src.database import SessionLocal, Document
|
||||
_db = SessionLocal()
|
||||
try:
|
||||
_d = _db.query(Document).filter(Document.id == doc_id).first()
|
||||
if _d:
|
||||
auto_opened_docs.append({
|
||||
"doc_id": _d.id,
|
||||
"title": _d.title,
|
||||
"language": _d.language,
|
||||
"content": _d.current_content,
|
||||
"version": _d.version_count,
|
||||
})
|
||||
finally:
|
||||
_db.close()
|
||||
except Exception as e:
|
||||
logger.warning("Office auto-doc creation failed for %s: %s", path, e)
|
||||
|
||||
# Upgrade the truncation marker with a hint pointing at the full doc so
|
||||
# the agent knows it can read the rest.
|
||||
if doc_id and marker:
|
||||
marker = (
|
||||
f"\n[…truncated for inline context — full {len(markdown):,} chars "
|
||||
f"saved as document `{doc_id}`. Use `manage_documents` with "
|
||||
f"action=read, document_id={doc_id}, offset=<N> to page through.]"
|
||||
)
|
||||
|
||||
return f"\n\n[Document content — {title}]:\n{body}{marker}"
|
||||
|
||||
# No content: tell the user whether to install the optional dep or whether
|
||||
@@ -521,7 +570,13 @@ def build_user_content(
|
||||
elif mime.startswith("text/") or _is_text_file(path):
|
||||
extracted_text = _process_text_file(path)
|
||||
else:
|
||||
extracted_text = _process_office_document(path, display_name)
|
||||
extracted_text = _process_office_document(
|
||||
path,
|
||||
display_name,
|
||||
session_id=session_id,
|
||||
auto_opened_docs=auto_opened_docs,
|
||||
owner=owner,
|
||||
)
|
||||
|
||||
extracted_text, inline_attachment_remaining = _fit_inline_attachment_text(
|
||||
extracted_text,
|
||||
|
||||
Reference in New Issue
Block a user