Release Notes - v0.19.0¶
Release Date: 2026-09-13
v0.19.0 is OmniAgent's first production deployment: a Discord bot running
live on AWS Lightsail, deployed by omnideploy from a container image that
is now multi-arch, supply-chain-signed, and built on a shell-less
Chainguard base image. Getting there surfaced and fixed a logging
self-deadlock that silently froze every CLI invocation, wired SSM-backed
secret injection all the way through the deploy pipeline, and closed the
config-injection gap that made the web UI and other nested config
unreachable on container platforms with no volume mounts. This release also
lands LLM-based conversation summarization, durable session/cron storage,
and the first agent/skill marketplace primitives.
Highlights¶
- Production Deployment - OmniAgent's Discord bot is live on AWS
Lightsail (
us-west-2), deployed viaomnideploywith secrets sourced from SSM Parameter Store and no plaintext credentials in the deploy shell or Pulumi state. - Chainguard Static Runtime - The Docker image's runtime stage moved
from Alpine to digest-pinned
cgr.dev/chainguard/static: no shell, no package manager, no libc, built-in nonroot user. Adopted as PlexusOne's container base-image policy. - Multi-Arch, Signed Images - Published images are now
linux/amd64+linux/arm64, with SBOM and SLSA provenance attestations and keyless cosign signatures, on both GHCR (canonical) and a new Docker Hub mirror. - Full Config Injection -
OMNIAGENT_CONFIG_B64supplies a complete config document through one base64 env var, reaching nested config (team mode, per-skill blocks, vault bindings) that individual env vars can't express — the missing piece for deploying on platforms with no volume mounts. - Logging Deadlock Fixed - A slog/log bridge cycle silently froze every CLI invocation before its first log line; this was the root cause of the first failed production deployment attempt.
- Conversation Summarization -
WindowStrategySummarizeis implemented and wired into the context engine;agent.WithCompactionenables LLM-based summarization of older messages once a threshold is crossed. - Marketplace Primitives - Portable agent/skill listing types, a
provider interface with an in-memory static implementation, and
adapters from
agent/registryandskills— reusable building blocks for host applications building an agent/skill catalog.
What's New¶
Production Deployment on Lightsail¶
deploy/lightsail/deploy.yaml deploys OmniAgent's Discord bot to AWS
Lightsail via omnideploy and Pulumi. The deploy is now fully secrets-free
at the shell level:
deploy:
secrets:
- name: ANTHROPIC_API_KEY
source: ssm:/omniagent/anthropic-api-key
- name: DISCORD_BOT_TOKEN
source: ssm:/omniagent/discord-bot-token
omnideploy's Pulumi backend resolves ssm:/secretsmanager:/env:
sources at deploy time and injects them as Pulumi secrets (encrypted in
state) — a missing secret fails the deploy up front instead of shipping a
container with a silently absent credential. See the rewritten
Deployment guide for the full IAM policy, region
guidance, and Pulumi backend setup.
Chainguard Static Runtime Image¶
The production image's runtime stage is now
cgr.dev/chainguard/static, digest-pinned, replacing Alpine:
FROM cgr.dev/chainguard/static@sha256:...
COPY --from=builder /build/omniagent /opt/omniagent/omniagent
USER 65532:65532
HEALTHCHECK CMD ["/opt/omniagent/omniagent", "healthcheck"]
Three adaptations for a shell-less image: the IANA timezone database is
embedded at build time (-tags timetzdata) since there's no OS tzdata to
install; the writable /data directory is created in the builder stage and
copied in with the correct ownership; and a new omniagent healthcheck
subcommand replaces the old wget-based HEALTHCHECK — it probes the
gateway's own /health endpoint, loads no config, and resolves no
credentials.
Multi-Arch, Signed, Dual-Registry Images¶
Docker Build & Publish now builds linux/amd64 and linux/arm64 (native
cross-compilation via BUILDPLATFORM/TARGETARCH — no QEMU-emulated Go
compiles), attaches BuildKit SBOM and SLSA provenance attestations, and
signs the pushed digest with keyless cosign via the workflow's OIDC
identity. Every build publishes to both ghcr.io/plexusone/omniagent
(canonical) and docker.io/grokify/omniagent (mirror). Verify a pulled
image with:
cosign verify \
--certificate-identity-regexp 'github.com/plexusone/omniagent' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/plexusone/omniagent:latest
Full Config Injection: OMNIAGENT_CONFIG_B64¶
A complete YAML or JSON config document, base64-encoded, decoded in-process (never written to disk):
An explicit --config path still wins entirely over it; individual
OMNIAGENT_* env vars override on top, matching existing file semantics.
Alongside it, the web UI and personal-mode auth are now independently
switchable from the environment (OMNIAGENT_WEB_ENABLED,
OMNIAGENT_AUTH_ENABLED, OMNIAGENT_AUTH_OWNER_EMAIL,
OMNIAGENT_AUTH_BASE_URL), and personal mode no longer requires a
team.database.app_dsn — it defaults to a SQLite file next to the main
storage database.
Logging Self-Deadlock Fix¶
root.go wrapped slog.Default().Handler() — the stdlib bridge into the
legacy log package — while slog.SetDefault simultaneously rewired that
same log package's output back into the new handler. The first emitted
log record re-entered log.Logger.output on the same goroutine and
self-deadlocked on its non-reentrant mutex, freezing the process silently
before a single byte of output. Every omniagent CLI invocation was
affected, including gateway run — this is what caused the first
production deployment attempt to fail its health checks with an empty
container log. Fixed by wrapping a concrete slog.NewTextHandler(os.Stderr,
nil) instead, with a regression test that exercises the real logger wiring
under a timeout.
Conversation Summarization¶
context.Window's WindowStrategySummarize (previously a stub) now calls
an injected SummarizeFunc, keeping the system message and most recent
messages verbatim while replacing older ones with a single summary
message — falling back to plain recency windowing if summarization fails
or isn't configured. agent.WithCompaction(threshold) wires this to the
agent's own LLM client:
Durable Session and Cron Storage¶
gateway run now builds a durable storage backend from
storage.type/storage.path/storage.redis.url config and wires
agent.WithStorage/WithSessionStore for every agent, starting
agent.WithCronScheduler() in single-agent mode. The Discord/WebSocket
chat path now dispatches to session-aware processing whenever a session
store is configured, so persisted history is actually used in follow-up
turns, not just written and ignored.
Marketplace Primitives¶
New marketplace/ package: portable AgentListing/SkillListing types
that map from agent/registry.AgentConfig and skills.CompiledSkill
without hand-copying fields (and without accidentally carrying API keys or
system prompts), a Provider interface, an in-memory static provider
implementation, and adapters — reusable building blocks for a host
application's agent/skill catalog UI.
Bug Fixes¶
temperatureno longer defaults to 0.7 — newer Claude models (Sonnet 4.6+/5, Opus 4.6+) reject any request that setstemperatureat all with a 400 error. Zero now means "use the provider's default"; the parameter is only sent when explicitly configured.- API-key auth enforced on
POST /chat/completions— previously reachable without a key. /api/healthroute alias — the DockerfileHEALTHCHECKandomnideploy's Lightsail probe both targeted/api/health, but the gateway only served/health; both paths now serve the same handler.cosign-installerpinned to exactv4.1.2— the action publishes no floatingv4major tag.livekit/protocolpinned below v1.51.0 (excluded) — that version changed theTransferSIPParticipantRPC signature in a way the latest releasedserver-sdk-gopredates and fails to compile against.
Upgrade Notes¶
- No breaking changes. Every new env var and config field is optional and additive.
- The default model in
config.Default()and every CLI/voice fallback changed fromclaude-sonnet-4-20250514toclaude-sonnet-5. If your config or deployment explicitly set the model, this doesn't affect you; if you relied on the compiled-in default, you're now on the newer model. - If your deployment or code relied on
agent.Temperaturedefaulting to0.7, set it explicitly in config — it now defaults to unset (0, meaning "provider default"). - Container deployments building their own Dockerfile from Alpine or another shell-based image should consider adopting the Chainguard static pattern (see the Deployment guide) — not required, but it's now the PlexusOne base-image policy for static Go services.
Full Changelog¶
See CHANGELOG.md for the complete list of changes with commit references.