release: v1.0.1 (#357)

This commit is contained in:
Jon Saad-Falcon
2026-05-18 20:19:37 -07:00
committed by GitHub
parent 5b847cd081
commit fea8d3e872
24 changed files with 1572 additions and 23 deletions
+105
View File
@@ -0,0 +1,105 @@
# Desktop auto-update
The OpenJarvis desktop app ships with [Tauri's updater
plugin](https://v2.tauri.app/plugin/updater/), which checks for new
versions on launch and every 30 minutes. When a newer signed build is
available, the app prompts the user to download and install it.
## How it works
```
on launch / every 30 min
GET https://github.com/open-jarvis/OpenJarvis/releases/download/desktop-latest/latest.json
Parse manifest: { "version": "X.Y.Z", "platforms": { ... } }
If manifest.version > installed_version:
download signed .dmg / .deb / .msi from manifest.platforms[target].url
verify against the minisign pubkey baked into the app
prompt user to install
```
The frontend code lives in
[`frontend/src/components/Desktop/UpdateChecker.tsx`](../frontend/src/components/Desktop/UpdateChecker.tsx);
the Tauri wiring is in
[`frontend/src-tauri/tauri.conf.json`](../frontend/src-tauri/tauri.conf.json)
under `plugins.updater`.
## How releases reach the update endpoint
The `Desktop Build & Release` GitHub Action
([`.github/workflows/desktop.yml`](../.github/workflows/desktop.yml))
publishes signed binaries plus a `latest.json` manifest to the
`desktop-latest` GitHub release on every push to `main`. The
`tauri-action` step with `includeUpdaterJson: true` generates the
manifest automatically.
Two release streams exist:
- **`desktop-latest`** (rolling pre-release): updated on every push to
`main`. This is the channel the desktop app currently polls. Users
on this channel get the most recent build the CI produced.
- **`desktop-vX.Y.Z`** (tagged stable): created when someone pushes a
`desktop-v*` git tag. Has the same artifacts but is marked as a
proper release rather than a pre-release.
The current updater endpoint points at the rolling `desktop-latest`
stream so that bug fixes (especially security and telemetry-policy
changes) reach users without waiting for a manual stable tag. A future
release may introduce a stable channel that points at
`desktop-v*` tags only.
## Signing
Binaries are signed by `tauri-action` using the minisign key pair
referenced via these GitHub Actions secrets:
| Secret | Purpose |
|---|---|
| `TAURI_SIGNING_PRIVATE_KEY` | Private key (PEM-formatted minisign) |
| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | Passphrase for the private key |
The matching public key is baked into the app at
`tauri.conf.json:plugins.updater.pubkey`. If you ever need to rotate
the key, replace the public key in the JSON file *and* update both
secrets atomically — mismatched keys cause every update download to
fail signature verification with no recovery path other than a manual
reinstall.
## Disabling the updater locally
For frontend development, set `VITE_OPENJARVIS_NO_UPDATER=1` in your
shell before running `npm run tauri dev`. Vite injects any
`VITE_`-prefixed env var into `import.meta.env`, and the
`UpdateChecker.tsx` component honors it to skip the 30-minute poll.
```bash
export VITE_OPENJARVIS_NO_UPDATER=1
npm run tauri dev
```
This is purely a dev escape hatch — it has no effect on production
builds (where `import.meta.env.VITE_OPENJARVIS_NO_UPDATER` will be
`undefined` unless you explicitly set it at build time).
## Verifying a release manually
```bash
# Download the latest manifest and confirm it parses cleanly
curl -fsSL https://github.com/open-jarvis/OpenJarvis/releases/download/desktop-latest/latest.json | jq .
# Fields:
# version — semver string, must match the tag (without leading "v")
# notes — release notes string
# pub_date — RFC3339 timestamp
# platforms — map keyed by "<target>-<arch>" e.g. "darwin-aarch64"
# each entry has { signature: "...", url: "..." }
```
A 404 on the manifest URL means the most recent desktop CI run
didn't complete or didn't have signing secrets — check the
`Desktop Build & Release` workflow logs.
+135
View File
@@ -0,0 +1,135 @@
# ACE optimizer (Agentic Context Engineering)
OpenJarvis supports [ACE](https://github.com/ace-agent/ace) as a third
optimizer alongside DSPy and GEPA. Where DSPy bootstraps few-shot
examples and GEPA evolves prompts via reflective mutation, **ACE
evolves a textual *playbook*** — annotated natural-language strategies
the agent reads at inference time. The playbook is updated by a
Generator / Reflector / Curator triad of LLM calls.
## When to pick ACE
| Task shape | DSPy | GEPA | ACE |
|---|---|---|---|
| Single-turn QA with crisp metric | strong | strong | weaker |
| Long-running agent that should accumulate guidance | weak | medium | strong |
| Open-domain where strategies matter more than templates | weak | medium | strong |
| When you want to *read* what the optimizer learned | medium | medium | strong |
ACE's headline artifact is `final_playbook.txt` — a human-readable
file like:
```
## STRATEGIES & INSIGHTS
[str-00001] helpful=5 harmful=0 :: When the user asks for unit
conversion, prefer the exact
rational form before rounding.
[str-00002] helpful=3 harmful=1 :: Cite a primary source before
stating a date claim.
```
If reading those strategies feels like the form of "what learning
should produce" for your task, ACE is the right choice.
## Setup
ACE is **not on PyPI** as of OpenJarvis v1.0.1, and the upstream
repository is structured as a research codebase (multiple top-level
directories) rather than a Python package. There's no `learning-ace`
extra for that reason. Install ACE manually instead:
```bash
# 1. Clone ACE somewhere outside your OpenJarvis checkout
git clone https://github.com/ace-agent/ace.git ~/code/ace
cd ~/code/ace
curl -LsSf https://astral.sh/uv/install.sh | sh # if you don't have uv
uv sync
# 2. Make ACE's src/ importable from your OpenJarvis venv
echo "$HOME/code/ace/src" > \
"$(python -c 'import site; print(site.getsitepackages()[0])')/ace.pth"
# 3. Set the API key for whichever provider ACE will call
cp ~/code/ace/.env.example ~/code/ace/.env
# Edit ~/code/ace/.env to set API_KEY for your chosen provider.
# 4. Verify the import resolves from OpenJarvis's venv
python -c "from openjarvis.learning.agents.ace_optimizer import HAS_ACE; print(HAS_ACE)"
# True
```
If `HAS_ACE` prints `False`, the `.pth` file isn't being picked up —
verify the path matches `site.getsitepackages()[0]` for the same
Python interpreter you're using to run OpenJarvis.
## Configuration
ACE is configured under `[learning.agent.ace]` in your OpenJarvis
config TOML:
```toml
[learning.agent]
policy = "ace"
[learning.agent.ace]
# ACE's three roles. Empty = inherit from the intelligence primitive's
# default cloud model.
generator_model = "claude-opus-4-7"
reflector_model = "claude-opus-4-7"
curator_model = "claude-sonnet-4-6"
api_provider = "openai" # sambanova | together | openai | commonstack
num_epochs = 1
max_num_rounds = 3
playbook_token_budget = 80000
max_tokens = 4096
task_name = "openjarvis"
save_dir = "" # default: ~/.openjarvis/learning/ace/<task>/
min_traces = 20
```
## Running
Once configured, the same orchestrator that runs DSPy / GEPA also runs
ACE — pick it via the `policy` field above. To force a one-shot run:
```bash
jarvis optimize agent --policy ace
```
ACE writes intermediate state and the final playbook to `save_dir`.
The OpenJarvis runtime will pick up the playbook on next agent start
(via the same sidecar overlay mechanism the Skills System uses).
## Trace adapter behavior
OpenJarvis traces are adapted into ACE's `train_samples` /
`val_samples` / `test_samples` format via a 70 / 15 / 15 split
(order-preserving for reproducibility). Each trace becomes a
`{question: trace.query, ground_truth_answer: trace.result}` sample.
Traces with empty `query` or `result` are dropped before splitting.
The `DataProcessor` ACE expects is built from `_TraceDataProcessor`
in `src/openjarvis/learning/agents/ace_optimizer.py` — it does a
case-insensitive substring match for `answer_is_correct` and averages
that for aggregate accuracy. If you're optimizing for a domain where
substring matching is the wrong correctness signal (math problems,
code, structured outputs), subclass `_TraceDataProcessor` and pass it
through your own callsite to `ACEAgentOptimizer.optimize()`.
## Limitations in v1.0.1
- **No automatic install.** Document above is the only path.
- **The trace adapter uses substring correctness.** Override for
domain-specific scoring.
- **Single provider per run.** ACE assigns the same `api_provider` to
all three roles. To mix providers, run ACE outside OpenJarvis and
hand-deliver the resulting playbook into `save_dir`.
These will get revisited once ACE publishes a PyPI package or stable
provider interface — track
[ace-agent/ace#issues](https://github.com/ace-agent/ace/issues) for
upstream changes that would let us tighten the wrapper.
+27
View File
@@ -83,6 +83,33 @@ dropped. Tests covering the patterns: [`tests/analytics/test_redaction.py`](../t
- **Never** sold, shared with advertisers, or used for anything other
than improving OpenJarvis.
## Opting out
Three independent ways to disable analytics — any one is sufficient:
1. **Set an env var** (no config file edit needed):
```bash
export DO_NOT_TRACK=1 # W3C convention, honored by other tools too
# or
export OPENJARVIS_NO_ANALYTICS=1 # project-specific, leaves other DNT-aware tools unaffected
```
Both are checked at runtime; any truthy value (`1`, `true`, `yes`,
`on`) disables analytics for that process. Truthy = anything other
than empty, `0`, `false`, `no`, `off`.
2. **Edit `~/.openjarvis/config.toml`**:
```toml
[analytics]
enabled = false
```
3. **Delete the anon ID** (`rm ~/.openjarvis/anon_id`) — events for
the prior identity are orphaned, but a new identity will be
created on the next run. Combine with #1 or #2 to fully stop.
Env-var opt-out takes precedence over the config file, so setting
`DO_NOT_TRACK=1` overrides `enabled = true` in the config.
## Retention
- Default retention: **365 days**, then events are deleted by PostHog