server/app.py defaulted to allow_origins=["*"] combined with
allow_credentials=True when cors_origins was not passed. That
combination is invalid per the CORS spec — browsers reject it — and
when used loosely it signals that any cross-origin request with
credentials is allowed, exposing session cookies and auth headers.
The reference config at configs/openjarvis/config.toml binds to
0.0.0.0 without setting cors_origins, so this fallback fired in every
default deployment.
Default to a closed list (Vite dev origin + Tauri webview) instead of
the wildcard. Users who actually need a custom origin already pass it
via cors_origins.
Closes#222
The dashboard at /dashboard renders blank once the Rust security module
is compiled (uv run maturin develop ...). The middleware sets
"Content-Security-Policy: default-src 'self'", which blocks the inline
scripts and styles the dashboard HTML relies on.
Loosen the policy to allow 'unsafe-inline' and 'unsafe-eval' so the
dashboard works once the security middleware is active. The same string
is exported via SECURITY_HEADERS for tests, so update both call sites.
Closes#261
configs/openjarvis/config.toml is the file users copy as their starting
configuration. It explicitly set [security] enabled = false (with a
comment about eval performance) — meaning users who follow the
quickstart unknowingly run with GuardrailsEngine, InjectionScanner,
CapabilityPolicy, and rate limiting all disabled.
The SecurityConfig.enabled default in code is True, so removing the
override here lets every install ship with security on. Eval workflows
that genuinely need it disabled can opt out via their own config.
Closes#224
SQLite FTS5 BM25 scores collapse toward zero on small corpora — when
every indexed document contains the query term, IDF approaches zero so
scores return ~1e-6. The default context_min_score = 0.1 silently
filters out every result before injection, so memory is stored but
never reaches the model on a fresh install.
Lowering both defaults to 0.0 lets retrieved context flow through;
users who want strict filtering can still set [memory]
context_min_score in config.toml.
Closes#262
uv.lock pinned mlx-lm==0.29.1, which predates the qwen3_5 architecture.
Running mlx_lm.server with mlx-community/Qwen3.5-* models therefore
fails with 'Model type qwen3_5 not supported.' on every uv sync, even
when pyproject.toml's loose constraint (>=0.19) would otherwise allow
a newer release.
Tighten the inference-mlx extra to mlx-lm>=0.31.1 (the first release
with Qwen3.5 support) and regenerate uv.lock — resolves to mlx-lm
0.31.3.
The lockfile diff is large because uv produces a single cross-platform
lock and adds 'split' entries for a handful of transitive deps
(transformers, vllm, huggingface-hub, mistral-common, etc.). Every
split entry is marker-gated to:
python_full_version >= '3.14' and sys_platform != 'linux'
and sys_platform != 'win32'
i.e. macOS on Python 3.14+ — the very subset that actually pulls in
mlx-lm 0.31.x. Linux, Windows, and Python <= 3.13 paths keep the
existing pins (transformers 4.57.6, vllm 0.17.1, …).
Closes#191
Reported via twitter (issue #269): the macOS install guide and other
docs recommend a 4B model on CPU but the README and quickstart pull /
ask a much larger model (qwen3:8b) — confusing and slow for first-time
CPU-only users.
Switch the README quickstart and the docs/getting-started/quickstart.md
'Chat with Any Model' tile to qwen3.5:4b, with an inline note that GPU
users can scale up to qwen3.5:9b or larger. This matches the existing
chat-simple preset and the macOS guide's CPU recommendation.
Closes#269
* refactor: merge desktop/ into frontend/, eliminate duplicate Tauri scaffolding
The project had two overlapping directories: desktop/ (Tauri Rust backend +
stale React components) and frontend/ (real React app + dead Tauri stub).
This consolidates everything under frontend/:
- Move desktop/src-tauri/ → frontend/src-tauri/ (the real 1,720-line Rust
backend with Ollama sidecar, backend lifecycle, cloud keys, overlay, etc.)
- Preserve 9 old desktop React components in frontend/src/components/Desktop/
(excluded from TS build — APIs have drifted, kept for future integration)
- Delete the old frontend/src-tauri/ stub (246 lines, never compiled)
- Delete desktop/ entirely
- Fix tauri.conf.json frontendDist path (../../frontend/dist → ../dist)
- Update CI workflow, bump script, .gitignore, and docs paths
- Rename setup/ → Setup/ for consistent PascalCase component directories
* feat: add memory UI, settings, and fix memory API routes
- Add Memory tab to Data Sources page with stats, search, index path,
and manual store functionality
- Add Memory section to Settings page with backend picker, context
injection toggle, and parameter sliders (top_k, min_score, max_tokens)
- Add memory API functions to frontend (getMemoryStats, searchMemory,
storeMemory, indexMemoryPath, getMemoryConfig)
- Fix backend /v1/memory/* routes to use app-level memory backend
instead of creating fresh SQLiteMemory instances per request
- Add GET /v1/memory/config and POST /v1/memory/index endpoints
- Gracefully handle missing Rust backend (return defaults instead of 500)
- Fix nested scroll in Agents Interact tab (use viewport-relative height)
* fix: memory API routes, dialog plugin, and UI polish
- Fix memory API: use backend.retrieve() not .search(), .count() not
.stats() to match actual SQLiteMemory interface
- Handle None backend gracefully in index endpoint (503 instead of crash)
- Expand ~ in index path (expanduser + resolve)
- Install @tauri-apps/plugin-dialog for native folder picker in Tauri
- Browse button only shows in Tauri (browser can't get absolute paths)
- Redesign Memory tab: proper cards, color-coded search scores, two-column
layout for index/store, loading spinners, accent gradient on stats card
---------
Co-authored-by: Jon Saad-Falcon <41205309+jonsaadfalcon@users.noreply.github.com>
* feat: add Apple Contacts connector (macOS AddressBook)
Reads directly from ~/Library/Application Support/AddressBook/AddressBook-v22.abcddb
in read-only mode. Extracts names, phone numbers, emails, postal addresses, URLs,
social profiles, and notes for each contact. Requires Full Disk Access like
iMessage and Apple Notes connectors.
- New connector: src/openjarvis/connectors/apple_contacts.py
- Registered in connectors/__init__.py
- Added frontend catalog entry (PIM category) and icon mapping
- MCP tools: contacts_search, contacts_get_contact
* test: add comprehensive tests for Apple Contacts connector
15 tests covering: is_connected (exists/missing), sync yields all real
contacts (skips system rows), extracts all field types (phone, email,
address, URL, social, notes), cleans Apple label markup, org-only
contacts, minimal contacts, since filter, sync_status tracking,
structured metadata, disconnect, mcp_tools, registry, empty DB,
missing DB. Uses fake SQLite database — no real Contacts DB needed.
* fix: scan iCloud/Exchange source databases for all contacts
The main AddressBook database only contains locally-created contacts.
Synced contacts (iCloud, Exchange, etc.) live under
Sources/<UUID>/AddressBook-v22.abcddb. Now scans all source databases
and deduplicates by ZUNIQUEID across sources.
Adds tests for multi-source scanning and cross-source deduplication.
The project had two overlapping directories: desktop/ (Tauri Rust backend +
stale React components) and frontend/ (real React app + dead Tauri stub).
This consolidates everything under frontend/:
- Move desktop/src-tauri/ → frontend/src-tauri/ (the real 1,720-line Rust
backend with Ollama sidecar, backend lifecycle, cloud keys, overlay, etc.)
- Preserve 9 old desktop React components in frontend/src/components/Desktop/
(excluded from TS build — APIs have drifted, kept for future integration)
- Delete the old frontend/src-tauri/ stub (246 lines, never compiled)
- Delete desktop/ entirely
- Fix tauri.conf.json frontendDist path (../../frontend/dist → ../dist)
- Update CI workflow, bump script, .gitignore, and docs paths
- Rename setup/ → Setup/ for consistent PascalCase component directories
Update all human-readable strings (docstrings, comments, descriptions,
log messages, TOML config descriptions) to correctly say
"DeepResearchBench" instead of "LiveResearchBench" for the
deep_research_bench benchmark. Class names and file paths are
unchanged for backward compatibility.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Salesforce LiveResearchBench (liveresearchbench) as a new benchmark:
- Dataset provider loading 80 expert-curated research tasks with 543
checklist items from HuggingFace (Salesforce/LiveResearchBench)
- Checklist-based scorer evaluating coverage + quality dimensions
- Groups multiple checklist rows per question into single EvalRecords
Also add "deepresearch" as a CLI alias for the existing DeepResearchBench
benchmark (previously only available as "liveresearch").
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ahead of the 2026-06-02 forced-Node-24 deadline, upgrade the remaining
javascript actions flagged in the workflow annotations:
- actions/setup-python v5 → v6
- actions/setup-node v4 → v6 (skipping v5)
- actions/cache v4 → v5
- actions/deploy-pages v4 → v5
- actions/upload-pages-artifact v3 → v5.0.0
upload-pages-artifact has no rolling @v5 major tag — only the specific
v5.0.0 release — so it gets an explicit pin, same as astral-sh/setup-uv.
Not touched: swatinem/rust-cache@v2 (still on v2 majors, not flagged),
dtolnay/rust-toolchain@stable (composite), tauri-apps/tauri-action@v0
(composite), anthropics/claude-code-action@v1 (still latest major).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
astral-sh/setup-uv does not publish a rolling @v8 major tag — only the
specific v8.0.0 release. Previous commit's @v8 reference failed to
resolve and broke CI/Docs/PyPI-publish runs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- openjarvis.__version__ now comes from importlib.metadata.version("openjarvis")
instead of a hardcoded string, so it stays in sync with pyproject.toml on every
release. Tests assert against openjarvis.__version__ rather than a literal.
- Bump actions/checkout@v4 → @v6 and astral-sh/setup-uv@v4 → @v8 across every
workflow ahead of the 2026-06-02 Node.js 20 deprecation on GitHub Actions runners.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Now that the `openjarvis` name is available on PyPI, rename the
distribution from `OpenJarvisAI` to `OpenJarvis` so `pip install
openjarvis` matches the import name and the in-code install hints
(e.g. `pip install openjarvis[channel-gmail]`).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>