Skip to content

Releases: OAraLabs/Prometheus

Prometheus v0.9.20

Choose a tag to compare

@github-actions github-actions released this 03 Nov 02:01
479c514

Prometheus 0.9.20 — beta

0.9.20 fixes a security issue: a file tool could be redirected through a link to a file the permission gate protects. It also:

  • turns off memory learning from chats with one switch;
  • connects to MCP tool servers over HTTP;
  • lets the operator hold a device to a profile;
  • keeps addresses out of /anatomy sent through a chat service.

Security

  • A file tool opens exactly the path the gate checked (GHSA-wgcv-xw9m-9q9q).
    • Before: the file tools (write_file, edit_file, read_file, notebook_edit, download_file, image_generate, tts, youtube_transcript, video_generate, grep, lsp, and the coding run's view, edit and create tools) run inside the daemon, outside the shell floors. The permission gate checked a tool's path, resolved; the tool then opened the path again by name, following links. A folder in the workspace swapped for a link to a protected folder between the two, by a shell or task running at the same time, sent the write or read to the protected file. A hard link to a protected file inside the workspace passed the gate with no race at all.
    • Now: the path the gate checked travels with the call, and the tool refuses, naming both paths, when its own resolution differs. The file is opened one folder at a time from / without following any link, so a link that appears after the check fails the open. Writes go to a temporary file in the same folder and replace the target atomically, keeping its read, write and execute bits; a reader never sees half a file. A file with more than one link is not read when it is one of the files the gate refuses to read. A tool called with no gate (a script, a test) still checks the floor itself.
    • Behaviour change: a link that already exists when the gate checks still works, and a write to a symlinked file still writes its target. A write now replaces the file instead of rewriting it, so a file that has other hard links gets a new file under the name you wrote, and its other names keep the old contents; its owner, extended attributes and ACLs are those of a new file. A file this user may not write is refused as before. A single file bind-mounted into a container, which cannot be replaced, is rewritten in place.

Also

  • /anatomy sent through Telegram, Discord or Slack no longer shows hostnames, IP addresses, URLs or the names and addresses of your tailnet peers. Those services keep every message on their servers. The reply keeps what the machines can do, and counts the peers. In the terminal and in Beacon /anatomy shows everything, as before. anatomy.include_addresses_in_chat: true shows everything on chat too. (#885)
  • When a model server runs on another machine and no SSH user is set to read its GPU, /anatomy, the model's Infrastructure section and doctor now say the GPU is "not configured". Before, every scan logged a warning that the probe failed, /anatomy called the GPU unreachable, and doctor reported no GPU and running on CPU. (#885)
  • memory.extraction.enabled: false stops memory being learned from chats. The fact extractor, the wiki compile after it, the SENTINEL insight writer, the agent's memory tool and wiki_query's saving of questions are not built or started. Recall, /note and the memory editor are unchanged. prometheus doctor reports the switch. (#889)
  • MCP servers can be remote: a url connects over streamable HTTP (transport: streamable-http) or SSE (the default). Before, a url server was always marked failed as "not yet implemented". The server's stored headers are sent on every request to it and are never shown or logged. The server store now refuses a url that isn't http:// or https://, and a header name or value that could break the request. (#892)
  • Devices: the operator can hold a device to a profile (PUT /api/devices/{id}/profile). Every run under that device's sessions is offered only the profile's tools and refused any other at the call, with no fallback that widens it, and the device cannot lift or change the hold. One instance can then serve its owner with every tool beside a server-to-server caller that stays read-only. (#893)

Upgrading from 0.9.19

  • Nothing to do beyond the upgrade. A file tool that now refuses a path names both the path it checked and the one it found; a refusal like that means a link changed under it.
  • Linux with the AppArmor profile: if you have not yet installed 0.9.18's profile, do it now (see the 0.9.18 notes); 0.9.20 adds no new rules.

Prometheus v0.9.19

Choose a tag to compare

@github-actions github-actions released this 02 Nov 19:33
47a2538

Prometheus 0.9.19 — beta

0.9.19 is a small patch release. Its fix: file_watch tasks never fired with watchdog 7 (fresh pip and Homebrew installs of 0.9.18). It also:

  • installs watchdog from a wheel on a Mac with Python 3.14, so file_watch is event-driven there again;
  • names the model that answered on every chat response (served_by);
  • sends a keyed llama.cpp server its key from oara doctor, the anatomy scan and the terminal chat;
  • keeps hostnames and addresses out of what the model is told about your machines.

The fix

  • Tasks: a file_watch task fires again when watchdog 7 is installed. watchdog 7.0 (2026-10-31) matches a handler's patterns against the whole path, so *.json stopped matching /dir/result.json and the task waited until its timeout. 0.9.18 allows watchdog 7, so a fresh pip install on Linux or on a Mac with Python 3.13 or older, and the Homebrew formula, got it; installs from the lock (the Mac app, scripts/deploy.sh) kept 6.0.0. The file's name is now matched against the pattern the same way the check for a file that is already there does.

Also

  • Install: watchdog is a base dependency on every platform again, from 7.0, the first release with macOS wheels for Python 3.14. 0.9.18 skipped it on exactly that platform; a Mac on Python 3.14 now installs it from a wheel and gets event-driven file_watch instead of polling. Polling stays for an install without watchdog.
  • Models: oara doctor's Inference row, the anatomy scan and the terminal chat now ask a llama.cpp server started with an API key with that key, so a keyed server no longer shows as not responding and the chat can read its model and chat template. The key is the model's own (model.api_key_env), read from the environment and then the env file. A named variable that is set in neither is reported by name instead of as "not responding".
  • The model is no longer told where your machines are. The Infrastructure section of its prompt and the anatomy tool's answers keep what the machines can do (CPU, RAM, GPU and VRAM, the model, its engine, context window and vision) and leave out hostnames, IP addresses, URLs, the tailnet peer list and the folder a model file sits in, on local and hosted models alike. Before, a reply could quote the model server's address or list your tailnet peers. anatomy.include_addresses: true restores the old text. The /anatomy command you run yourself is unchanged.
  • Each chat response names the model that answered: served_by on POST /api/chat and on the chat_done frame, and prometheus.served_by on /v1/chat/completions (on the final chunk when streamed). When a fallback answers instead of the configured model, served_by names the fallback. /v1's model still echoes the key you asked for.

Upgrading from 0.9.18

  • Nothing to do beyond the upgrade. If a file_watch task never fired on 0.9.18, it fires on 0.9.19; re-create any that timed out.
  • Linux with the AppArmor profile: if you have not yet installed 0.9.18's profile, do it now (see the 0.9.18 notes); 0.9.19 adds no new rules.

Prometheus v0.9.18

Choose a tag to compare

@github-actions github-actions released this 02 Nov 07:14
f7a68a4

Prometheus 0.9.18 — beta

0.9.18 fixes two security issues: a model's shell and file tools could read this machine's private keys and change what the daemon starts at boot, and an agent profile's tool list hid tools from the model without stopping it calling them. It updates authlib, dnspython, joserfc, pyasn1 and graphql-core for published advisories. It also:

  • lets a paired app check it reached the Prometheus it paired with before it sends its token;
  • lets voice use a speech server on another machine, with local fallback;
  • uses a llama.cpp server started with an API key;
  • says which local AI app answered setup's look, and why none is usable;
  • keeps your account name, your machine's layout and a purged chat's facts out of what the model is sent and keeps;
  • fixes five computer-use problems on Linux desktops;
  • installs on a Mac with Python 3.14 without a compiler.

Security

  • A model's shell and file tools can't read the node keys or change what starts the daemon (GHSA-9ff8-vhh2-r2cw).
    • Before: the floors from GHSA-wq93-7fvg-53pj (the macOS sandbox profile, the Linux AppArmor profile, the permission gate's always-denied list) left out the node keys (node/node.key and node/instance.key, which paired apps pin), the MCP server store (data/mcp_servers.json, started at boot), the xAI sign-in tokens (xai_oauth.json), the cron jobs' PATH shims (data/job-python/), lcm.db (each conversation's workspace and profile), config_pins.yaml, the file checkpoints, the custom agent profiles, and what starts Prometheus: its LaunchAgent plist, its systemd unit and drop-in folder, and the install it runs from. Your cron jobs, the daemon's worker and coding-run launches and command hooks ran as login shells, outside the floors, so a login file a model's shell had written ran there.
    • Now: the keys, the MCP store and the xAI tokens can't be read or written, and the rest can't be written, by a shell or a file tool, wherever PROMETHEUS_NODE_DIR, PROMETHEUS_DATA_DIR or PROMETHEUS_CONFIG_DIR put them. A file tool's write to a profile asks the owner. The startup files covered are the plist, the unit and its drop-ins, the deploy's venvs and clone (~/prometheus-venvs, ~/prometheus-deploy/scripts and src), a pipx or uv tool install, and the install the daemon runs from. Reading and running them still works. Each stored MCP server is checked again before it starts, and one that fails is skipped and named in the log. A checkpoint never copies a link or Prometheus's own files into its store. A restore writes only inside the conversation's own workspace, never through a link, never into Prometheus's own files and never with setuid, setgid or sticky bits.
    • Behaviour change: your cron jobs, worker and coding-run launches and command hooks run bash --noprofile --norc -c, and BASH_ENV and ENV are dropped, even from a hook's env_allowlist. A job or hook that relied on its login profile for PATH or a variable must set that up itself, for example with source ~/.profile at the start of the command. A stored MCP server saved before a check was added may need saving again.
    • Known limit: files your own programs read later (your shell's login files, an editor's or another tool's config and plugins) are yours, not Prometheus's, and the floor does not cover them.
    • Linux: install the new AppArmor profile and reload it (sudo cp deploy/apparmor/prometheus-bash /etc/apparmor.d/prometheus-bash then sudo apparmor_parser -r -W /etc/apparmor.d/prometheus-bash). Until you do, the shell keeps its old floor and the daemon reports the profile as stale at startup, with that command. An install outside the profile's default places is named at startup. macOS needs nothing.
  • An agent profile limits what a conversation can run (GHSA-qgfv-m38j-2c6w, #860). Before, a model that named a tool its profile left out (research has no file writes; exclude_tools: [bash] drops bash) ran it, under the same approvals and floors as the full profile. Now such a call is refused with an error naming the profile. A subagent gets only the tools both its type and the conversation's profile allow, task_create runs a shell command (local_bash, poll) only when the profile includes bash, and a profile that leaves any tool out starts no worker process (task_create local_agent, sessions_spawn); its subagents keep the limits instead. Deferred tools the profile allows, and tools left out only by max_tool_schemas, still run.
  • Dependencies in the lock, for published advisories: authlib 1.9.1 and dnspython 2.9.0 (#867; CVE-2026-96760, CVE-2026-114614 to CVE-2026-114618, CVE-2026-114620, CVE-2026-114605), joserfc 1.7.7 (#875; CVE-2026-119284), pyasn1 0.6.5 (CVE-2026-119194 to CVE-2026-119197) and graphql-core 3.3.1 (CVE-2026-119286). All reach Prometheus only through the evals extra, and pyasn1 also through the google provider.

Identity and pairing (#864, #865, #866)

  • Identity check: POST /api/identity/challenge lets a paired app check it reached the Prometheus it paired with before it sends its token. The daemon signs the app's 32-byte nonce with its node key, binding the instance id, the node key, and on the TLS port the certificate's SPKI digest. No token, no cookie, nothing written; hello's rate limit. FOUNDATION is now Version 4: the node key may sign identity challenges, and is still never proof of the user (the bearer token is).
  • Pairing: every route a device joins through (an approved request, an owner code, same-Mac pairing) now hands it instance_id and node_pub, the key it pins for the identity check. A request that sends match_code_version: 2 gets a 4-digit code that also covers the node key, so the owner's check confirms it; requests that don't send it get the same code as before. Contract pairing/0.2.
  • Status: GET /api/status gains name and fp, the same values GET /api/hello answers, beside node_pub and instance_id, so a client paired with several Prometheus instances can tell them apart. Additive only; /health still carries no identity.

Voice on another machine (#862, #876)

  • Speech-to-text and text-to-speech can use a voice server on another machine. Set stt.url (an OpenAI-compatible /v1/audio/transcriptions server) or tts.url (/v1/audio/speech); naming just the server (http://127.0.0.1:8001) is enough, and whisper.url is accepted for stt.url. The key comes from the variable named in api_key_env, else PROMETHEUS_STT_API_KEY / PROMETHEUS_TTS_API_KEY, read from the environment or the env file and never from prometheus.yaml. With tts.voice empty, now the default, the server picks its own voice.
  • If the server can't be reached, that request runs on the local engines and leaves one log line. A refused key or a 400 (an unknown voice or model) also falls back to local, but logs an ERROR. oara doctor shows whether each configured server answers. With no url set, voice runs locally as before. This covers Telegram and Discord voice notes, Telegram voice replies, oara --voice and the tts tool.

Models and setup

  • llama.cpp with an API key (#877): a llama.cpp server started with --api-key can be used as the main model, in a router rule or fallback, and as a named backend. Name the variable that holds the key in api_key_env (the key itself goes in the env file); it is sent as a bearer token on every request, including the probes, and never logged. A named variable that is not set is an error naming it. With no key set nothing changes. An api_key_env on an Ollama entry is still refused, since Ollama takes no key.
  • Setup says what it found (#868): when Prometheus looks for an AI app on this computer (GET /api/setup/detect) or on one you name (POST /api/setup/probe), it says which app answered (Ollama, LM Studio, llama.cpp, vLLM or another OpenAI-compatible app), which models it serves, and why none is usable when none is: too short a context window, nothing loaded, no chat model, needs a key, or no answer. Configure checks the chosen model the same way. A model needs a window of at least 24,576 tokens. GET /api/setup/status lists local_probe in features.
  • Doctor (#861): the Config check looks for prometheus.yaml where the daemon does (--config, then the checkout's config/prometheus.yaml, then $PROMETHEUS_CONFIG_DIR, default ~/.prometheus) and names the file it found. Before, a daemon running on ~/.prometheus/prometheus.yaml logged "config/prometheus.yaml not found" at every start.
  • Config (#873): five keys nothing read are gone from the shipped prometheus.yaml: model.fallback_provider and model.fallback_url (a fallback model is set under model.fallback), and infrastructure.gpu_host, mini_host and mini_port. oara setup no longer writes model.fallback_url, and the env file oara init writes no longer suggests PROMETHEUS_TELEGRAM_CHAT_IDS; the chats Telegram answers in are gateway.allowed_chat_ids. An existing config with these keys keeps working.

What the model is sent and what is kept

  • No account name or machine layout in every prompt (#853, #856): hosted models are sent paths under your home folder as ~/… instead of absolute paths, and tool descriptions no longer name a person (the brain-vault tool says "the owner's second brain"). They no longer receive this machine's hardware, services and network (the anatomy section, which could include tailnet peer names) in every prompt; they get a pointer to the anatomy tool and call it when a task needs the layout. anatomy.include_in_hosted_prompt: true restores the old behaviour. Local models are unchanged.
  • A purged chat's facts go too (#854): purging a chat now also retracts what was learned fro...
Read more

Prometheus v0.9.17

Choose a tag to compare

@github-actions github-actions released this 26 Oct 20:24
4876e99

Prometheus 0.9.17 — beta

0.9.17 fixes two security issues: chat gateways let anyone in an allowed group approve tool calls and change what the agent remembers, and a shell command the model ran could rewrite the files Prometheus trusts as its own. It pins the Mac app's bundled Python at 3.12.15 (OpenSSL 3.5.9), and updates opentelemetry, filelock and setuptools for published advisories. It also:

  • warns when the web API token sits where the agent's shell can read it;
  • asks before a file tool writes a project instruction file, and refuses invisible text in skills and memory;
  • keeps the memory extractor from skipping messages when its model call fails;
  • makes computer use work with SENTINEL off, and type into GTK4 text fields;
  • keeps genuine user requests in self-improvement evidence (#788, by @sepehrtaji-dev).

Security

  • Only a chat gateway's owner approves and teaches (GHSA-c3c2-8vrj-x346).
    • Before: the Telegram, Slack and Discord gateways went by which chat a message came from, not who sent it. In an allowed group chat, Slack channel or Discord server, any member could approve or deny the agent's tool calls (including /approve always and /gate off), have their message run as if the owner had typed it, and add to memory, skills and self-improvement data. Approval prompts and the daemon's own notices that had no chat of their own went to the first allowed chat, so a group listed first saw them.
    • Now: each gateway has an owner. Only the owner approves tool calls or uses the owner-only commands. Members can still chat: their messages are recorded as theirs, any tool their message asks for waits for the owner, and nothing they say goes into memory, skills, self-improvement or training data. Approval prompts, cron-failure notices and background-task notices go only to the owner's private chat.
    • Not affected: Telegram with only your own private chat allowed, and Beacon and the REST and WebSocket API, which authenticate devices rather than chats.
  • A model's shell can't rewrite Prometheus's trusted state (GHSA-wq93-7fvg-53pj).
    • Before: none of the shell's floors (the macOS sandbox profile, the Linux AppArmor profile, the permission gate's always-denied list) covered the device registry, the config file, the identity files, MEMORY.md and USER.md, skills, or the scheduled-jobs files. A shell command the model was talked into running could create a trusted device token, rewrite the config, plant lasting instructions, or plant a cron job that runs as the owner. Mainly macOS, where the shell has no write floor.
    • Now: these files are under the same floors as your keys. Writing, appending, replacing, deleting, linking, planting a side file and renaming their folders are refused; reading still works, and so do Prometheus's own writers. The file tools refuse the device registry, the config file and the scheduled-jobs files, and ask before writing the identity files, memory or skills. The daemon tests the floor at startup and reports a stale AppArmor profile at ERROR.
  • The Mac app's build pins CPython 3.12.15 and OpenSSL 3.5.9 (#843). The 0.9.16 app was rebuilt with them by hand; from 0.9.17 every build gets them. They fix CVE-2026-19445 and CVE-2026-19553 (ssl), CVE-2026-82049, CVE-2026-19672 and CVE-2026-87910 (tarfile), CVE-2026-15310 (zipfile), CVE-2026-15806 (urllib) and CVE-2026-17084 (StringPrep). The unused libpython dylib is no longer shipped.
  • opentelemetry 1.45.1 and arize-phoenix-otel 0.17.2 (#844) fix CVE-2026-114603, in the evals extra only. filelock 4.2.4 and setuptools 84.2.1 (#857) fix CVE-2026-112940, CVE-2026-112913 and CVE-2026-112907 (filelock) and GHSA-xmj3-9gf7-h52w (setuptools). Only uv.lock changes.

The API token's location is checked

  • What changed. At startup, in GET /api/status and in oara doctor, Prometheus says so loudly when the web API token sits where the agent's shell can read it even with the bash read floor on:
    • web.api_token is set in prometheus.yaml;
    • PROMETHEUS_API_TOKEN_FILE names a file outside ~/.config/<name>/*env;
    • the env file holding the token was moved out of that pattern by PROMETHEUS_ENV_FILE or XDG_CONFIG_HOME.
  • What to do. Move the token to ~/.config/prometheus/env as PROMETHEUS_API_TOKEN=<token> (oara token show prints it), then remove the setting that held it, and restart.
  • Without an active read floor (it is off, or the daemon runs in a container) every location is readable alike, so nothing is said. The warning never names the token or the token file's path.

Hardening shipped with GHSA-wq93-7fvg-53pj

  • Project instruction files ask first. A file tool's write to a project instruction file asks the owner, even inside the workspace, with approvals off or under a saved grant. These are the files the prompt assembler loads from the session's workspace upward (PROMETHEUS.md, AGENTS.md and the other convention files the README lists) and .prometheus/rules/*.md.
  • Skills and memory refuse invisible text. Characters that hide text from a person reading it are refused: tag characters, bidi embeddings, overrides and isolates, the zero-width space, the word joiner, invisible operators, a byte-order mark mid-text, and the supplementary variation selectors. The zero-width joiner and non-joiner, LRM and RLM, the emoji variation selector and a leading byte-order mark stay allowed.

Memory extraction (#841, #842)

  • A failed model call no longer loses messages (#842, from #832 by @sepehrtaji-dev). An outage, rate limit or timeout used to look the same as "nothing to remember", so the extractor's cursor moved past the batch. Now the cursor stays where it was and the next pass retries the batch.
  • JSON-shaped output with no facts is logged (#841, from #807 by @lijinhongucl-pixel). A reply that looks like JSON but yields no facts logs a WARNING. Prose with no brace, [] and {"facts": []} stay quiet.

Self-improvement keeps genuine user requests (#788, by @sepehrtaji-dev)

  • GEPA's request evidence no longer drops a message whose provenance is user just because its trust flag is false. Untrusted messages from other sources are still withheld.

Computer use (#845, #846)

  • The desktop cockpit works with SENTINEL off (#845), the shipped default. Before, Beacon never saw its own app pick, any step, the end of a task or a thumbnail, because only SENTINEL built the signal bus the cockpit rides.
  • A GTK4 app's text fields can be set (#846). GTK4 reports them as "text box", a role the candidate table did not offer, so a task could never type into GNOME Text Editor or any other GTK4 field.

Upgrading from 0.9.16

  • Linux with the AppArmor profile: reload it BEFORE restarting the daemon. Until you do, the daemon reports a STALE PROFILE at ERROR:
    sudo apparmor_parser -r -W /etc/apparmor.d/prometheus-bash
    
  • Telegram: if you allow only your own private chat, nothing changes. If you allow a group, set gateway.owner_user_ids to your Telegram user id.
  • Slack: set gateway.slack.owner_user_ids. Until you do, nobody on Slack can approve, and Slack messages don't add to memory.
  • Discord: the owner of the bot's Discord application is the owner unless you set gateway.discord.owner_user_ids.
  • Telegram notices: approval prompts with no chat of their own, cron-failure notices and task notices go to gateway.briefing_chat_id when it is a private chat, else to your private chat, else nowhere. A group briefing_chat_id is not used for them, with a warning.
  • File-tool writes to identity files, memory, skills and project instruction files now ask you, even with approvals off or under a saved grant.
  • API clients: GET /api/status gains a top-level warnings list of {code, level, message, fix}.

Prometheus v0.9.16

Choose a tag to compare

@github-actions github-actions released this 22 Oct 23:52
aa1a8eb

Prometheus 0.9.16 — beta

0.9.16 makes a fresh setup listen on this machine only until you choose otherwise, and turns on the context compactor that installs made by oara setup, setup mode and Beacon's first run never had. It updates certifi and Pillow for published advisories. It also:

  • makes Beacon's model list show whether your own AI is reachable, and name it;
  • makes oara doctor and the boot check look for your model server where the config says it is;
  • removes the CancelledError traceback that every shutdown and restart logged;
  • makes oara pair --owner fit a Beacon on this Mac as well as one on another computer.

Security

  • Setup mode listens on this machine only unless you choose otherwise (#833).
    • Before: a daemon started with no config and no --bind (pip, brew, source, oara install-service) listened on every interface until setup finished. Anyone on the same network could try the six-digit pairing code. A right guess (5 tries in a million per start, within the code's 15 minutes) returned the daemon's API token, and five wrong guesses locked the owner out until a restart.
    • Not affected: the Mac app (always loopback), the container image (it sets PROMETHEUS_WEB_BIND on purpose), and anyone who ran oara setup first.
    • Now: to set up a headless box from another computer, start it with oara daemon --bind 0.0.0.0. Setup mode then listens on every interface, and so does the daemon it becomes.
  • certifi 2026.10.19 and Pillow 13.0.0 (#839). They fix PYSEC-2026-4320 (certifi) and CVE-2026-112395, -112397, -112400, -112404, -112895, -112896, -112897 and -112899 (Pillow). Only uv.lock changes; the floors in pyproject.toml are unchanged.
  • The Mac app now bundles Python 3.12.15 with OpenSSL 3.5.9, which includes the CPython SSL fixes CVE-2026-19445 and CVE-2026-19553.

The context compactor is on for installs Prometheus set up (#834)

  • What went wrong. No config written by oara setup (interactive or --fast), by setup mode, or by Beacon's first run turned the compactor on. Without compaction.enabled it is not built, so those installs have run without it since it shipped in June. The template ships it on. LCM still summarised history between turns, but nothing kept a long multi-round tool turn inside a small local window.
  • What changed.
    • Every writer now writes compaction: {enabled: true}.
    • At start, a config with no compaction.enabled follows the template, turns the compactor on, and logs a warning naming the line to write. The file is not edited.
    • An explicit compaction.enabled: false stays off.

Beacon's model list tells the truth about your own AI (#835)

  • The Local row's available follows the last probe of the primary. It was always true.
  • GET /api/models re-probes the primary when that probe is older than backend_probe.ttl_s.
  • The row is labelled with the engine and the model it serves, for example "llama.cpp · Qwen3.8-27B", instead of "Local".
  • A primary the registry does not probe (LM Studio, vLLM, a cloud primary) stays available, as before.

Doctor probes the configured address (#836)

  • What went wrong. The boot check and the chat /doctor used model.base_url only for llama.cpp. For every other provider they probed model.fallback_url, by default localhost:11434. So an Ollama, LM Studio or vLLM server at any other address, and any cloud model, was reported "not responding". oara doctor defaulted every local provider to :8080, and asked /v1/v1/models for a base ending in /v1.
  • What changed.
    • Every check probes the address the provider is reached at: model.base_url, else its base-URL variable, else its default.
    • Ollama is asked /api/tags. The OpenAI-shaped servers are asked /v1/models, once.
    • A cloud primary gets an info row instead of a probe.

Clean shutdown (#837)

  • What went wrong. Stopping or restarting the daemon logged a CancelledError traceback at ERROR. The daemon cancelled the web server's task, so uvicorn never ran its own shutdown, and its shutdown steps (withdrawing the network announcement, stopping the pairing sweeper) ran only as the process exited.
  • What changed. The web server now shuts down properly when it is stopped. It waits at most 5 seconds for open requests.

oara pair --owner fits this Mac and another computer (#838)

  • The code banner and the expiry line no longer say "the other computer".
  • When the code is used, the terminal says whether that Beacon was on this Mac or on another computer, from what the daemon saw. A relay on this machine, such as Tailscale serve or cloudflared, counts as another computer.
  • The owner_code frame's redeemed_by gains this_host.
  • The example device name in the owner-code tests and docs is "Alex's MacBook Pro".

Upgrading from 0.9.15

  • Setup from another computer: start the daemon with oara daemon --bind 0.0.0.0 (or set PROMETHEUS_WEB_BIND). Without either, setup mode now listens on this machine only.
  • Compactor: an install whose config has no compaction.enabled gets the compactor at its next start, with a warning naming the line to write. To keep it off, write compaction.enabled: false.
  • Beacon and other API clients: the Local row of GET /api/models is labelled with the engine and the model it serves, and carries detail (the served path) when the primary was probed. Its available can now be false.
  • No migration.

Known issues

  • The known issues listed for 0.9.13 still apply.

Prometheus v0.9.15

Choose a tag to compare

@github-actions github-actions released this 19 Oct 21:17
2502c5a

Prometheus 0.9.15 — beta

A small maintenance release.

  • Dependency security update. The minimum aiohttp version is now 3.14.4 (with yarl 1.25.1), picking up upstream security fixes. Only the optional Discord and Slack gateways use aiohttp; Prometheus's own web server does not.
  • Slack extra fixed. pip install 'oara-prometheus[slack]' now installs everything the Slack gateway needs.
  • Docs and tests use a generic example device name.

No config, service or deploy changes since 0.9.14. Upgrade with Homebrew, or pip install -U oara-prometheus.

Prometheus v0.9.14

Choose a tag to compare

@github-actions github-actions released this 18 Oct 03:27
27055db

Prometheus 0.9.14 — beta

Two small fixes for installs that aren't a git checkout of Prometheus, such as Homebrew and pip.

  • No more false "new code on disk" notice. On Homebrew and pip installs, /api/status now reports not_checkout with no commit SHAs instead of comparing against a repo that isn't there. (#827)
  • Git fetches only happen in a Prometheus checkout. The update check now fetches from origin only when Prometheus is running from its own git checkout. (#826)

No config, service or deploy changes since 0.9.13. Upgrade with Homebrew, or pip install -U oara-prometheus.

Prometheus v0.9.13

Choose a tag to compare

@github-actions github-actions released this 17 Oct 17:47
df11489

Prometheus 0.9.13 fixes tool calling on local models: a local turn can now call every tool, where since late July it could reach only the dozen or so always sent to it.

Highlights

  • Every tool is callable on local turns (#819). On a 27B model, the right tool was picked 12 of 12 times, with correct arguments first try 11 of 12.
  • Smaller first request on local turns (#820): about 19.2k → 13.8k tokens.
  • llama.cpp reply cap back to 4096 (#813), so 32k sessions don't compact early.
  • Beacon shows the text of turns the loop ends itself (#811).
  • Ollama gets the context window Prometheus plans for (#815), with no more silent front-truncation.
  • Startup warnings for guessed context windows and overrides that match nothing (#814).
  • Hardening on Linux (#825): the daemon process is non-dumpable, and the service unit no longer passes keys through the environment.

Upgrading

  • pip install -U oara-prometheus, or update the Mac app.
  • Linux service installs: an upgrade doesn't rewrite the installed unit. If you installed it with oara install-service, run oara install-service --force, then systemctl --user restart prometheus.service (the old unit is backed up to prometheus.service.bak). If you wrote your own unit, just delete its EnvironmentFile= line, then systemctl --user daemon-reload and restart.
  • Read "Upgrading from 0.9.12" in the CHANGELOG for config changes.

Prometheus v0.9.12

Choose a tag to compare

@github-actions github-actions released this 16 Oct 03:17
e3c1787

Prometheus 0.9.12 — beta. Compaction now counts in the server's own tokens and, when a server says the prompt is too long, compacts and retries once instead of ending the turn (#805). Beacon sessions can use subagents: the agent tool always failed from Beacon before (#806). Each model gets its own reply-size cap instead of a flat 4096, and a tool call that the cap cut off is refused with an explanation instead of running with empty arguments (#806). web_search names its error and retries once, and Beacon no longer badges every assistant reply "untrusted" (#806). Coding mode sees files at the root of a repo: code_glob and code_grep read **/ as "any number of directories, including none" (#802, fixes #801; first tagged as 0.9.11, which was never published).

Upgrading from 0.9.10: local sessions will compact more often, because the 80% line is now measured in the server's tokens rather than a low estimate; the reply cap changed for every request (llama.cpp models ask for up to 8192 tokens, known cloud models get their own value, unknown models keep 4096); context.model_overrides.<model>.max_output_tokens pins one model's cap. No config change is needed. The lock also moves pydantic-ai-slim to 1.107.7 for eight advisories; it is used only by the evals extra, not by the daemon, the Mac app or the Docker image. Full list in CHANGELOG.md.

Known issues

  • A tool call cut off three times in a row ends the turn (#809). The circuit breaker counts the cut-off refusals like malformed calls, and its recovery (a stricter adapter tier) does nothing about length.
  • A daemon started with --config <path> outside the search path does not hand that path on (#799, #800): managed coding runs refuse with "coding mode is disabled", and the daily-briefing cron job reads its config from the search path.
  • The memory extractor can save no facts, silently, when the model pretty-prints its JSON (#798). Seen with a 7B model on Ollama; the log line MemoryExtractor: persisted 0 memories from N messages is the only sign.

Install

  • Mac (Apple Silicon, macOS 13 or later): Prometheus-mac-arm64.zip below, signed and notarized by Apple; Beacon can install it for you.
  • pip: pip install 'oara-prometheus[full]', or pip install oara-prometheus for the base install. PyPI

Prometheus v0.9.10

Choose a tag to compare

@github-actions github-actions released this 14 Oct 19:09
ac8b592

Draft release for v0.9.10 — publish manually after review.