Skip to content

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 via omnideploy with 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_B64 supplies 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 - WindowStrategySummarize is implemented and wired into the context engine; agent.WithCompaction enables 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/registry and skills — 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):

OMNIAGENT_CONFIG_B64=$(base64 < omniagent.yaml)

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:

agent.New(cfg, agent.WithCompaction(50))

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

  • temperature no longer defaults to 0.7 — newer Claude models (Sonnet 4.6+/5, Opus 4.6+) reject any request that sets temperature at 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/health route alias — the Dockerfile HEALTHCHECK and omnideploy's Lightsail probe both targeted /api/health, but the gateway only served /health; both paths now serve the same handler.
  • cosign-installer pinned to exact v4.1.2 — the action publishes no floating v4 major tag.
  • livekit/protocol pinned below v1.51.0 (excluded) — that version changed the TransferSIPParticipant RPC signature in a way the latest released server-sdk-go predates 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 from claude-sonnet-4-20250514 to claude-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.Temperature defaulting to 0.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.