Commit Graph
221 Commits
Author SHA1 Message Date
Robby ManihaniandGitHub 8e6bc343d8 fix(connectors): validate credentials before persisting + populate Gmail URLs (#410) 2026-05-25 11:07:35 -07:00
Tanvir BhathalandGitHub c84f1fddee feat: proactive agent approval bell with approve/deny UI (#370) 2026-05-22 17:38:48 -07:00
Robby ManihaniandGitHub 363bdbfa41 feat: Deep Research Granola integration + citation fixes (#366) 2026-05-20 15:56:42 -07:00
krypticmouseandClaude Opus 4.7 e087773b36 style: ruff line-length + import fixes for #340 and #202
Follow-up on the cherry-picks from @Dilligaf371's #340 and
@bootcrowns's #202. Both fail ruff's E501 (88-char line limit) on
main:

- ``src/openjarvis/agents/executor.py:325`` (from #340) — the
  ``self._system is not None and getattr(..., "tool_executor", None)
  is not None`` guard was 101 chars. Wrapped the condition.
- ``src/openjarvis/telemetry/gpu_monitor.py:55-60`` (from #202) —
  five new GPU_SPECS entries (Jetson Orin NX 16GB/8GB, AGX Orin,
  Snapdragon X Elite/Plus) were 90-93 chars. Wrapped each
  GpuHardwareSpec constructor call onto its own block.
- ``tests/telemetry/test_gpu_monitor.py`` (from #202) — removed a
  spurious blank line between imports and the first ``#`` comment
  block, picked up by ``ruff check --fix`` (rule I001).

No behavior change — pure formatting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 20:22:44 +00:00
Abhinav Cherukuruandkrypticmouse 9c9c883f24 test: update test_all_specs_present with 7 new GPUs 2026-05-20 20:20:58 +00:00
Eddie Richterandkrypticmouse 86c42e4e4a tests: wrap lemonade host override signature 2026-05-20 20:20:53 +00:00
Eddie Richterandkrypticmouse a65cd12ea2 lemonade: update default host and recommended model 2026-05-20 20:20:53 +00:00
Jon Saad-FalconandGitHub c8f1b3c54a Consolidate top-priority contributor PRs (#235 + #339 + #293 + #294 + #295) (#362)
Lands 5 high-priority contributor PRs as one bundle, with original authorship preserved on every commit, plus follow-up commits from me to make each PR CI-green and non-regressive. See PR #362 for the full per-author commit breakdown and credits.

Credits: @tomaioo (#235), @Dilligaf371 (#339), @TX-Huang (#293, #294, #295).
2026-05-20 13:11:34 -07:00
Robby ManihaniandGitHub 855ed51780 feat: Deep Research Slack integration (#365) 2026-05-20 12:02:05 -07:00
Tanvir BhathalandGitHub 4652b6e8a8 [FEAT] Proactive Agents (#364) 2026-05-20 12:00:19 -07:00
krypticmouseandClaude Opus 4.7 9a42e62172 style: wrap long line in test_ask_agent.py
Follow-up on @TX-Huang's PR #295. The new
test_soul_md_content_reaches_engine_in_simple_agent test has one
line at 92 chars that trips ruff's E501 (88 char limit). Wrap the
ternary onto multiple lines so the file passes ruff check on CI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:37:18 +00:00
90f009e906 feat(ask): wire SystemPromptBuilder so SOUL.md / MEMORY.md / USER.md actually load
`SystemPromptBuilder` is fully implemented and tested in
`openjarvis.prompt.builder`, and `BaseAgent.__init__` accepts a
`prompt_builder` kwarg. But no production code path ever instantiates
the builder, so the persona-files feature documented in
`MemoryFilesConfig` (SOUL.md / MEMORY.md / USER.md) had no effect.
Users could write a fully-customized `~/.openjarvis/SOUL.md` and the
file was never read.

This PR wires it up in `_run_agent` (called by `jarvis ask --agent
<name>` and the new fallback from #294):

```python
if "prompt_builder" in inspect.signature(agent_cls.__init__).parameters:
    agent_kwargs["prompt_builder"] = SystemPromptBuilder(
        agent_template=config.agent.default_system_prompt or "",
        memory_files_config=config.memory_files,
        system_prompt_config=config.system_prompt,
    )
```

The `inspect` guard means agents that override `__init__` without
forwarding `prompt_builder` (e.g. OrchestratorAgent, which has its
own tool-aware system prompt) opt out automatically and keep
working unchanged. SimpleAgent and any future agent that inherits
`BaseAgent.__init__` directly picks up the persona files.

Also fixes a latent bug in `SystemPromptBuilder._load_file`: it
called `path.read_text()` with no encoding, which on Windows falls
back to the system code page (cp950 / cp932 / cp949) and raises
`UnicodeDecodeError` on any non-ASCII persona content. Pin to UTF-8.

## Tests

- Add `test_soul_md_content_reaches_engine_in_simple_agent` — writes
  sentinel SOUL.md / MEMORY.md / USER.md to tmp_path, runs the
  command, and asserts each sentinel appears in the SYSTEM message
  passed to engine.generate.
- Add `test_orchestrator_keeps_its_own_system_prompt` — exercises
  the `inspect`-based opt-out so OrchestratorAgent doesn't crash
  on the unexpected kwarg.

Run: `pytest tests/cli/test_ask_agent.py tests/cli/test_ask_router.py
tests/cli/test_ask_e2e.py tests/agents/ tests/prompt/`

The 6 remaining failures (test_base_agent, test_loop_guard,
test_manager, test_native_openhands) are pre-existing on
origin/main and unrelated to this change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:37:18 +00:00
krypticmouseandClaude Opus 4.7 0217a901dd test(energy_wiring): opt out of #294 default-agent fallback in _energy_config
Follow-up on @TX-Huang's PR #294. The default-agent fallback now
routes `jarvis ask "..."` (no --agent) through `config.agent.default_agent`,
which dataclass-defaults to `"simple"`. The autouse `_clean_registries`
fixture in tests/conftest.py clears AgentRegistry between tests, so
the fallback then fails with `Unknown agent: simple` and every
CLI-driven test_energy_wiring test exits with code 1.

These tests exercise engine-level instrumentation, not agent dispatch
— ``test_engine_wrapped_with_instrumented``, the energy-monitor
lifecycle tests, and the end-to-end pipeline tests all care that the
engine gets wrapped and telemetry lands in SQLite, regardless of
whether the call goes through an agent. Set ``cfg.agent.default_agent
= ""`` in ``_energy_config`` to keep these tests on the direct-engine
path they were originally designed for. The dedicated
``test_agent_mode_uses_instrumented_engine`` (which explicitly passes
``--agent``) is unaffected.

Same pattern PR #294 already uses in tests/cli/test_ask_router.py
for the two MagicMock-config tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:37:09 +00:00
c7f451fbc8 fix(ask): honor agent.default_agent from config when --agent omitted
`jarvis ask "..."` (no `--agent` flag) routed straight to
`engine.generate()` regardless of `agent.default_agent` in the user's
config. As a result the persona stack — `agent.default_system_prompt`,
SOUL.md, MEMORY.md, USER.md — was silently bypassed for the most
common command.

Behavior now:
- `--agent X`              → use agent X (unchanged)
- `--agent ""` (empty)     → explicit opt-out, direct-to-engine mode
- (omitted)                → fall back to `config.agent.default_agent`,
                             which dataclass-defaults to `"simple"`,
                             so persona settings finally take effect

Tests:
- Rename `test_no_agent_uses_direct_mode` to
  `test_no_agent_flag_falls_back_to_config_default_agent` and update
  its docstring to document the new behavior.
- Add `test_explicit_empty_agent_opts_out_of_agent_mode`.
- Add `test_no_agent_with_blank_config_default_uses_direct_mode` to
  cover the case where the user clears `default_agent`.
- Update `_patch_engine` (test_ask_router) and `_patch_ask`
  (test_ask_e2e) to re-register `SimpleAgent` after the autouse
  `_clean_registries` conftest fixture, since the agent path now
  runs in tests that previously short-circuited to direct mode.
- Add explicit `cfg.agent.default_agent = ""` to two
  `test_ask_router` tests that mock load_config with a MagicMock
  (so `cfg.agent.default_agent` doesn't auto-create as a truthy mock).

Note: `tests/cli/test_ask_context.py` has 2 unrelated pre-existing
failures on origin/main (memory backend returns None on Windows);
those are out of scope for this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:37:09 +00:00
30ac635e83 fix: force UTF-8 stdout on Windows for CJK CLI output
On Windows the default Python stdout encoding follows the system
ANSI code page (cp950 for zh-TW, cp932 for ja, cp949 for ko).
`click.echo()` then raises `UnicodeEncodeError` whenever a CJK
character lands in CLI output — `jarvis ask` returning Chinese
crashes with `'cp950' codec can't encode character '义'`.

Reconfigure `sys.stdout` and `sys.stderr` to UTF-8 with
`errors='replace'` at the `main()` entry point. Scoped to
`win32` so other platforms are untouched. Two unit tests verify
the reconfigure happens on Windows and doesn't on Linux.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:36:55 +00:00
31efd9e672 fix: detect total RAM on Windows via GlobalMemoryStatusEx
`_total_ram_gb()` had branches for Darwin (sysctl) and Linux
(/proc/meminfo) but no Windows path, so `jarvis init` reported
"0.0 GB RAM" on every Windows host. The downstream
`recommend_model()` then fell back to VRAM-only sizing, often
selecting a smaller tier than the system can actually run.

Add a Windows branch that calls `GlobalMemoryStatusEx` via
ctypes — no new dependency. Add a platform-skip-aware test for
each OS branch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:36:55 +00:00
krypticmouseandClaude Opus 4.7 8b5a304222 test(mcp): regression test for StdioTransport.send_notification
Follow-up on @Dilligaf371's PR #339 fix. Adds a regression test that
spawns a subprocess which consumes stdin without ever writing to
stdout, then issues `send_notification` from a worker thread. If the
override is missing, the thread blocks forever on `proc.stdout.readline()`
and the 2-second join timeout fires.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 03:36:37 +00:00
Tanvir BhathalandGitHub a58d6b6c48 Auto Update (#358) 2026-05-19 11:57:10 -07:00
Jon Saad-FalconandGitHub fea8d3e872 release: v1.0.1 (#357) 2026-05-18 20:19:37 -07:00
Robby ManihaniandGitHub 9af0dfe336 feat: Deep Research — personal deep research over Gmail with hybrid retrieval and agentic synthesis (#354) 2026-05-18 17:46:12 -07:00
Tanvir BhathalandGitHub 7081be7bd3 [FEAT] Telemetry (#351) 2026-05-17 13:07:05 -07:00
Jon Saad-FalconandGitHub e97088f199 release: v1.0.0 (#349) 2026-05-16 13:47:23 -07:00
Jon Saad-FalconandGitHub 9540e85dfb ci: fix env-dependent test failures (gated datasets, server extra, router prefix) (#348) 2026-05-15 21:31:13 -07:00
Jon Saad-FalconandGitHub eacf34e500 spec_search: drop CLI stubs, rename, and ship paper-aligned tutorial + configs (#346) 2026-05-15 14:17:23 -07:00
Jon Saad-FalconandGitHub 44815e8544 feat(evals): add TerminalBench V2.1 benchmark (#345) 2026-05-14 20:23:14 -07:00
Avanika NarayanandGitHub b8c3b417ec feat(mining): validate Gemma E4B and Qwen 3.6 Pearl artifacts (#328) 2026-05-14 20:11:24 -07:00
Jon Saad-FalconandGitHub 57151327b3 feat: LLM-guided spec search building blocks (split-aware sampling, external corpora, agent-trace adapter) (#332) 2026-05-08 20:18:40 -07:00
Jon Saad-FalconandGitHub b8245136db fix(security): block IPv4-mapped IPv6 addresses in SSRF check (#327) 2026-05-07 14:55:52 -07:00
Jack HamiltonandGitHub 9e7366fc05 Close KnowledgeStore connections in connectors_router endpoints (#209)
* fix: close KnowledgeStore connections in connectors_router endpoints

KnowledgeStore opens a persistent SQLite connection in __init__ but was
never closed at the three instantiation sites in connectors_router.py,
leaking one file descriptor (plus its WAL handle) per call. The worst
offender is _connector_summary(), which is invoked per-connector on
every GET /connectors poll from the frontend — after ~100 polls the
backend hits the default macOS per-process FD limit (256) and asyncio's
accept() starts failing with OSError: [Errno 24] Too many open files.

Add __enter__/__exit__ to KnowledgeStore (close() already existed) and
wrap all three instantiation sites in `with` blocks so the connection
is released deterministically when the scope exits.

- connectors/store.py: add context manager protocol
- server/connectors_router.py: use `with KnowledgeStore() as store:`
  in _connector_summary, _ingest, and _run_sync

* test: cover KnowledgeStore context manager + connectors_router close leak

- test_store.py: add two tests for the new __enter__/__exit__ protocol
  verifying the connection closes on normal exit and on exceptions.
- test_connectors_router.py: add a regression test that monkeypatches
  KnowledgeStore.close to count invocations and asserts every store
  opened by GET /v1/connectors is paired with a close.

Also fix a pre-existing bug in the test_connectors_router fixture: the
router is created with prefix="/v1/connectors" internally (line 92 of
connectors_router.py), and the fixture was wrapping it again with
prefix="/v1", producing "/v1/v1/connectors". All 6 existing router
tests were failing with 404 before this fix. 5 of them now pass; the
remaining failure (test_trigger_sync) is an unrelated KeyError on a
missing response field and is out of scope for this PR.

* test: drop connectors_router regression test — skipped in CI anyway

The regression test added in the previous commit relies on FastAPI
being importable, but CI's dev-extra install does not include fastapi
(it lives in the `server` optional group). All tests in
test_connectors_router.py silently skip on CI with "fastapi not
installed", so the regression test would never actually execute there.

Revert test_connectors_router.py to the upstream main version. The
fixture bug I fixed (double prefix) and the connection-leak regression
test both deserve a separate PR scoped to test infrastructure — that
PR should either add fastapi to dev deps, split server tests into
their own CI job, or both.

The KnowledgeStore context manager tests in test_store.py are kept
because they have no fastapi dependency and will run in CI.
2026-05-06 23:44:43 -07:00
4935053ac7 feat(mining): register ScalingIntelligence Pearl models (#324)
Co-authored-by: krypticmouse <herumbshandilya123@gmail.com>
2026-05-06 22:20:18 -07:00
8fb9d5ece3 feat(mining): add Pearl model conversion workflow (#323)
* feat(mining): add Pearl model conversion workflow

* test(mining): tolerate missing Docker device request type

* docs(mining): record Gemma and Qwen conversion evidence

* docs(mining): record Qwen local validation evidence

---------

Co-authored-by: krypticmouse <herumbshandilya123@gmail.com>
2026-05-06 16:20:27 -07:00
Avanika NarayanandGitHub daaa5577f0 feat(mining): inspect Pearl model artifacts before launch
Add jarvis mine inspect-model to fail fast on missing Pearl/Hugging Face artifact metadata before GPU startup.
2026-05-05 21:21:33 -07:00
a689be0c69 fix(evals): clean up AI stack runtime harness (#320)
Co-authored-by: krypticmouse <herumbshandilya123@gmail.com>
2026-05-05 19:28:50 -07:00
Jon Saad-FalconandGitHub f41cf420be feat(mining): Pearl mining integration
Consolidates NVIDIA vLLM, Apple Silicon, CPU Pearl mining support, CLI/docs, and live H100 validation.
2026-05-05 19:11:15 -07:00
Avanika NarayanandGitHub e79bc1e196 Add cold-start CLI installer (#313) 2026-05-05 14:42:48 -07:00
Avanika NarayanandGitHub a3ba63d148 AI_stack_support: subprocess-based external framework harness (#311) 2026-05-05 13:37:33 -07:00
Avanika NarayanandGitHub d7624510bb Eval framework: silent-failure detection, surgical reruns, continuous-score reporting (#303) 2026-05-03 21:07:44 -07:00
Robby ManihaniandGitHub 259f97b81c fix(server): allow Tauri 2 webview origins on every platform (#292)
The desktop app's chat-completions stream relies on a raw browser
fetch from the Tauri webview to the FastAPI backend, so it is
subject to CORS. The default allowlist only contained
`tauri://localhost`, which is the production webview origin on
macOS, Linux, and iOS. On Windows and Android, Tauri 2 serves the
app from `http://tauri.localhost` (or `https://tauri.localhost`
when `windows.useHttpsScheme` is enabled), so the preflight for
`POST /v1/chat/completions` was rejected and the streaming fetch
threw `TypeError: Failed to fetch` before any byte was read.

Symptom users reported: in the Logs tab the request appears to
succeed up to "Request sent", followed immediately by
"Stream error: Failed to fetch" and "Response: 22 chars" -- which
is exactly the length of the synthesized fallback string
`Error: Failed to fetch` written by InputArea.tsx when streamChat
throws.

Add `http://tauri.localhost` and `https://tauri.localhost` to both
default origin lists (`ServerConfig.cors_origins` and the
`create_app` fallback), and add a regression test that drives a
real preflight against `/v1/chat/completions` for each of the
three Tauri origin schemes.

Browser model loading kept working because it is routed through
the Rust `tauriInvoke('fetch_models')` command, which is a
server-to-server HTTP call not subject to browser CORS -- only
streaming chat goes through the webview's fetch.
2026-04-29 12:55:25 -07:00
Jon Saad-FalconandGitHub f5695845b7 feat(distillation): M1→M2→M3 spec-level distillation pipeline + hill-climb optimizer (#273) 2026-04-20 19:18:10 -07:00
Robby ManihaniandGitHub 8258295f51 Feature/twitter bot (#272) 2026-04-20 15:33:51 -07:00
Robby ManihaniandGitHub ef03d98fc0 Feature/twitter bot (#259) 2026-04-17 15:22:17 -07:00
Andrew ParkandGitHub 30d4d45a7d refactor(system): decompose JarvisSystem god-object into system/ package (#257) 2026-04-17 11:02:56 -07:00
Andrew ParkandGitHub 88a7ebcaa3 test: add live marker, CI coverage gate, rust bridge boundary tests (#256) 2026-04-17 11:02:21 -07:00
Andrew ParkandGitHub 28e913f706 fix(agents): bind built-in tools, live tool-call UI, Markdown streaming (#255) 2026-04-17 11:01:50 -07:00
Andrew ParkandGitHub 54d79ef235 feat: add Apple Contacts connector (macOS AddressBook) (#248)
* 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.
2026-04-14 09:49:08 -07:00
Andrew ParkandGitHub ed2acf1895 fix(skills): implement skill remove and search CLI commands (#240) 2026-04-13 15:03:39 -07:00
Avanika NarayanandGitHub a3789212ec refactor: remove dead shims, stale files, and test duplication (#243) 2026-04-13 15:03:03 -07:00
Jon Saad-FalconandClaude Opus 4.6 db4b031c45 fix: rename DeepResearchBench references in docs, configs, and tests
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>
2026-04-13 18:59:24 +00:00
Jon Saad-FalconandClaude Opus 4.6 70cbda8a73 chore: derive __version__ from metadata, bump GHA action versions
- 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>
2026-04-11 13:19:19 -07:00
Tanvir BhathalandGitHub 0e122cd776 DGX Spark Fix (#231) 2026-04-10 11:40:03 -07:00