Skip to content

Cloned Repo 2 weeks ago, before loss of data - #8

Open
CyberoniOntoni wants to merge 336 commits into
arcahyadi:mainfrom
CyberoniOntoni:dev
Open

Cloned Repo 2 weeks ago, before loss of data#8
CyberoniOntoni wants to merge 336 commits into
arcahyadi:mainfrom
CyberoniOntoni:dev

Conversation

@CyberoniOntoni

Copy link
Copy Markdown

Summary

Target branch

  • This PR targets dev, not main. All PRs land in dev; main is curated by the maintainer at each release. If your PR is on main by accident, click "Edit" on this PR and change the base.

Linked Issue

Fixes #

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)
  • New feature (non-breaking — adds new behaviour)
  • Breaking change (changes or removes existing behaviour)
  • Refactor / cleanup (behaviour unchanged)
  • Documentation only
  • CI / tooling / configuration

Checklist

  • I searched open issues and open PRs — this is not a duplicate.
  • This PR targets dev
  • My changes are limited to the scope described above — no unrelated refactors or whitespace changes mixed in.
  • I actually ran the app (docker compose up or uvicorn app:app) and verified the change works end-to-end. Type-checks and unit tests are not enough.

How to Test

Visual / UI changes — REQUIRED if you touched anything that renders

Anything that changes what the UI looks like — buttons, icons, padding, colors, fonts, spacing, layout, CSS, HTML, SVG, or any static/js/ module that draws to the DOM — needs all of the following. PRs that change rendering without these WILL be closed.

  • Screenshot or short clip of the change in the running app, attached below. Mobile screenshot too if the change affects mobile.
  • Style match: the change uses Odysseus's existing visual language. Specifically:
    • Reuse existing CSS variables (--red, --fg, --bg, --card, --border, etc.) — do not introduce new color values, font sizes, or spacing units.
    • Reuse existing button/input/card/border classes. Don't invent parallel styling.
    • No Unicode emoji in UI or code. Use inline SVG (matching the monochrome icon style already in static/index.html) or plain text.
    • Monospaced font (Fira Code) for primary UI text. Don't override.
    • Dark theme is the default; any light-mode work must be wired through the existing theme system, not hard-coded.
  • No new component patterns. If a similar widget already exists in the app, extend it instead of writing a parallel one.
  • I am not an LLM agent submitting a bulk PR. If you are, please open an issue describing the problem first — bulk auto-generated PRs that don't match the project's visual style are closed on sight, even when the underlying fix is correct.

Screenshots / clips

pewdiepie-archdaemon and others added 30 commits June 27, 2026 20:46
An account configured with SMTP only (no imap_host) has no inbox, but the
inbox list path still called _imap_connect, which handed an empty host to
imaplib. imaplib.IMAP4("", 993) silently dials localhost:993 and fails with
"[Errno 111] Connection refused", so the email panel's poll logged a
"Failed to list emails" ERROR every ~60s and surfaced a scary error in the UI.

_imap_connect now fails fast with a typed EmailNotConfiguredError (subclass of
RuntimeError, so existing broad handlers keep working) when no imap_host is set,
and the inbox list returns an empty result for that case instead of an error.
SMTP send is unaffected.
Keep an unhealthy MemoryVectorStore instance available for health reporting instead of discarding it as disabled. This lets health checks report a degraded/down vector-store state while preserving focused regression coverage for initializer behavior.
jagadish-zentiti and others added 25 commits July 11, 2026 13:44
…-call (#5106)

stream_agent_loop's per-tool drain loop had no cleanup path for early
generator close. Starlette throws GeneratorExit into the generator at
whatever await point it's suspended on when the SSE client disconnects
(aclose()) - here that's 'await _progress_q.get()' inside the drain
loop, before the final 'await _tool_task' line ever runs. The task,
which wraps execute_tool_block, was left running unawaited and
uncancelled.

For bash/python tools this orphans the underlying subprocess:
subprocess_tools.py already has correct CancelledError handling that
kills the child process, but only runs if the task is actually
cancelled. A client disconnecting mid long-running command left that
subprocess running server-side for its full duration with nothing
left to reap it.

Wrap the drain loop in try/finally: on early exit, cancel _tool_task
(if not already done) and await it so the existing subprocess-kill
path runs.

Adds a regression test that drives the real stream_agent_loop with a
fake tool handler, closes the generator mid tool-call (mirroring what
Starlette does on disconnect), and asserts the handler observed
cancellation immediately - not merely via asyncio.run()'s own
end-of-run task cleanup, which would mask the bug.

Fixes #5105
* fix(chat): Expand user chat bubble edit textbox width

- Update user chat bubble width from `fit-content` to `85%` to ensure consistency with the AI chat bubble edit textbox width.

* style(chat): Refine user message bubble width logic

- Change general bubble width to `fit-content`
- Set width to 85% specifically for user messages containing a `textarea`
…hes (#5149)

conn.search() / conn.fetch() operate on volatile positional sequence
numbers that shift whenever messages are deleted or expunged. Three call
sites in the sig-learner (_pull_headers, _fetch_bodies) and morning-brief
email section were storing these as "uid" and reusing them in subsequent
fetches — causing wrong-message returns or NO responses if another client
modified the mailbox concurrently.

Replaced with conn.uid("SEARCH", ...) / conn.uid("FETCH", ...), which use
persistent RFC 3501 UIDs. _scan_one (urgency action) already did this
correctly; these were the remaining callers.

The reproduction window is narrow (requires concurrent deletion between
search and fetch), so the fix is verified by regression tests rather than
manual end-to-end: _SpyImap raises AssertionError if conn.search() or
conn.fetch() are called instead of conn.uid().
…ls (#5420)

* fix: harden stabilization attachment and agent guards

* fix(uploads): preserve durable references during cleanup

* fix(uploads): close cleanup and compaction races
…(#4411) (#5160)

* docs: update static/js/MODULE_SUMMARY.md to reflect current ES6 frontend

Rewrite the stale module summary to match the current no-build,
ES6-module frontend architecture. Adds coverage of app.js orchestration,
the chat/SSE pipeline (chat.js, chatStream.js, chatRenderer.js,
streamingRenderer.js), new subsystems (research/, compare/, document
streaming, cookbook*, skills.js), and removes the obsolete <script> load
order assumptions.

* cleanup: remove dead MEMORY_DOC / memory_doc paths (closes #4411)

Removes the unused MEMORY_DOC constant and the matching DataConfig
memory_doc field / set_data_paths entry. No runtime code imports or
references these paths, so this is a no-behavior-change dead-code
cleanup under the storage-architecture tracker #4377.
* fix(db): restrict data/app.db to 0600

app.db holds bearer-token hashes, bcrypt password hashes, and encrypted
provider keys but was created under the default umask (0644 -> world-readable),
unlike .app_key/vault/integrations which are already 0600 via safe_chmod.

init_db() now chmods the SQLite file to 0600 right after create_all (POSIX
only; no-op on Windows, skipped for Postgres / in-memory). Unconditional and
idempotent, so it also re-locks already-deployed 0644 installs on next
startup. The transient rollback journal inherits 0600 from the parent file at
creation - no sidecar handling needed; -wal/-shm don't exist until WAL is
enabled (#4409 C4) and inherit the same mode then.

Satisfies Rule B, unblocking #4413 and the vault/integration secret moves.
Mirrors src/secret_storage.py:43-45.

Verified: security + DB-permission suites pass; 6 pre-existing visual_report
failures (missing markdown/nh3 deps) are unrelated.

Closes #4407

* fix(db): harden SQLite path parsing and re-lock sidecars

Address review feedback on #4420.

P2: derive the file to chmod from engine.url (SQLAlchemy's parsed URL)
via _sqlite_db_path(), instead of DATABASE_URL.replace("sqlite:///", "").
A driver-qualified URL (sqlite+pysqlite://) or one carrying query args
(?cache=shared) previously slipped past the prefix check / string slice
and left the DB world-readable; the parsed path resolves correctly and
drops the query.

P3: re-lock stale -wal/-shm/-journal sidecars to 0o600 at startup. The
main file is chmod'd first, so any sidecar SQLite creates afterward
inherits 0o600, but a -wal/-shm left world-readable by an older 0o644
install (once WAL was enabled) could still expose DB pages. Absent
sidecars are the normal case, not an error.

Tests: unit-test _sqlite_db_path across driver/query/memory/postgres URL
forms, and a subprocess test asserting stale 0o644 -wal/-shm are
re-locked on startup.

* fix(db): handle sqlite file URI app db permissions

* fix(db): close remaining SQLite permission bypasses

---------

Co-authored-by: Ethan <23321960+0xLeathery@users.noreply.github.com>
Co-authored-by: Alexandre Teixeira <alexandremagteixeira@gmail.com>
chat_stream() references `_explicit_web_intent` in three places
(disabled-tools gating, global-disabled web allowance, and the
per-turn tool filter) but the assignment was dropped during a
branch merge. Every chat request raised

    NameError: name '_explicit_web_intent' is not defined

at routes/chat_routes.py, surfacing to the client as a bare
"Internal Server Error" before any LLM call was made — chat was
fully broken on dev and main.

Restore the original definition, computed from the already-derived
tool intent, immediately before its first use:

    _explicit_web_intent = bool(_tool_intent and _tool_intent.category == "web")

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 2d81770)
…mporter (#5261)

* Harden skill importer against SSRF: block private targets + revalidate redirects per hop

The skill importer validated only the initial URL with the lenient SSRF guard
(block_private=False) and then fetched with follow_redirects=True, so a 3xx to
an internal/metadata address (169.254.169.254, 127.0.0.1, RFC-1918) was still
connected to — inconsistent with the hardened services/search/content.py
:_get_public_url path.

Add a _get_checked() helper that follows redirects manually and re-runs the
SSRF guard with block_private=True on every hop, and route all three fetch
sites (skills.sh unwrap, _fetch_bytes, _list_github_dir) through it. GitHub's
own redirects and the final-host _assert_github_url checks are preserved.

Adds hermetic regression tests (IP-literal hosts, faked HTTP layer) and updates
the existing mock signature for the new block_private kwarg.

Defense-in-depth: the endpoint is admin-gated (require_admin) and admins are
trusted per THREAT_MODEL.md, so this is not a cross-boundary vulnerability.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test: enforce follow_redirects=False invariant in mock client

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Add Arch-specific package installation and NVIDIA runtime configuration
to the Docker setup guide. Cover passthrough verification, the NVIDIA
Compose overlay, and the distinction between GPU passthrough and
CUDA-backed model serving

Refs #831
…7-odysseus

chore: sync upstream changes from odysseus-dev/odysseus
fix(docker): bump Docker CLI to a patched release
fix(docker): bump Docker CLI to a patched release
* feat(models): define capability schema and readers

* fix(models): harden Google catalog probing

Restrict native catalog probing to the Gemini host, keep provider keys out of request URLs, filter non-chat model resources, and preserve the manual refresh default in the built-in Google add flow.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown

⚠️ PR description — action needed

The following required sections are missing or incomplete. Please update the PR description to address them:

  • Summary is empty or too short — describe what changed and why.
  • Linked Issue — add a reference like Fixes #NNN, a bare #NNN, or a link to the issue.
  • Type of Change — check at least one box.
  • Checklist — check the duplicate-search box to confirm you searched existing issues and PRs.
  • How to Test — explain how a reviewer can verify this change. Numbered steps, the commands you ran, or a short code block all work — give a sentence or two of real detail (not just "tested locally").

This comment is deleted automatically once all sections are complete.

@CyberoniOntoni

Copy link
Copy Markdown
Author

Dunno if its a right way to go haha

jeroenev pushed a commit to jeroenev/odysseus that referenced this pull request Aug 3, 2026
scroll-snap-type: y mandatory (docs/index.html:28) forces the viewport to
always rest on a snap point. The footer is far shorter than a viewport, so
scrolling down past the last min-height:100vh section snaps back to that
section's start and the footer can never settle in view. Switch the snap
type to 'proximity' so sections still snap when the user is near them but
the footer (and any sub-viewport tail) is freely reachable.

Fixes arcahyadi#8

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
smchik pushed a commit to smchik/odysseus that referenced this pull request Aug 4, 2026
scroll-snap-type: y mandatory (docs/index.html:28) forces the viewport to
always rest on a snap point. The footer is far shorter than a viewport, so
scrolling down past the last min-height:100vh section snaps back to that
section's start and the footer can never settle in view. Switch the snap
type to 'proximity' so sections still snap when the user is near them but
the footer (and any sub-viewport tail) is freely reachable.

Fixes arcahyadi#8

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
bstruong added a commit to bstruong/odysseus-old-arcahyadi-fork that referenced this pull request Aug 9, 2026
….js fix

This is a SINGLE UNSPLIT commit bundling 12 distinct, independently-
developed fixes for durability only — it exists purely to move this work
off of "uncommitted on disk" (fragile: one `git clean`, forced checkout,
or disk issue away from losing sessions of debugging) and onto
"committed and pushed" as fast as safely possible.

This is explicitly NOT the reviewable 12-way PR split proposed in Phase 2
session 9's Part C. That split still needs to happen in a later session,
working from this commit via:

    git reset --soft <this-commit>~1

which un-does exactly this commit, non-destructively, and restores the
working tree to today's on-disk diff for interactive per-fix staging.

Bundled in this commit:
  1. TOOL_SECTIONS entries for 5 previously-unreachable email tools
     (search_emails, draft_email, draft_email_reply, ai_draft_email_reply,
     download_attachment) — src/agent_loop.py
  2. _KEYWORD_HINTS entries for the same 5 tools — src/tool_index.py
  3. IMAP search rewrite: term-AND matching instead of one literal phrase
     — mcp_servers/email_server.py
  4. agent_email_confirm gate extended to archive_email/delete_email/
     mark_email_read/bulk_email (previously only send_email/reply_to_email
     were gated) — mcp_servers/email_server.py, routes/email_routes.py,
     src/agent_loop.py (TOOL_SECTIONS prose)
  5. Domain-classifier keyword-gate widened from 3 hardcoded names to
     general correspondence-verb patterns — src/agent_loop.py
  6. list_emails MCP schema strictness: additionalProperties:false +
     owner/limit argument declarations — src/tool_schemas.py,
     mcp_servers/email_server.py
  7. list_emails attention-query (unread_only/unresponded_only) max_results
     cap raised 20 -> 200 so busy inboxes aren't silently truncated —
     mcp_servers/email_server.py, src/tool_schemas.py, src/agent_loop.py
  8. FUNCTION_TOOL_SCHEMAS entries for the same 5 tools, fixing native/
     API-mode tool-calling reachability — src/tool_schemas.py
  9. BUILTIN_TOOL_DESCRIPTIONS entries for the same 5 tools, fixing
     semantic-RAG reachability — src/tool_index.py
  10. Stale comment correction in src/tool_security.py (folded in with arcahyadi#8)
  11. _DOMAIN_TOOL_MAP["email"] now derived from the canonical
      tool_security.BUILTIN_EMAIL_TOOLS registry instead of a 5th
      hand-typed, drift-prone list — src/agent_loop.py
  12. chat.js live-stream thinking-boundary fix: gemma4:e4b replies whose
      reasoning arrives as unflagged "Thinking Process:" text could get
      stuck permanently collapsed in the thinking box, never rendering
      the real answer — static/js/chat.js

7 new regression tests included (tests/test_*.py). Full narrative and
per-fix session provenance: NOTES.md.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.