Skip to content

6.6.0

Latest

Choose a tag to compare

@github-actions github-actions released this 20 Oct 19:08
· 43 commits to main since this release
273e03a

EDDI 6.6.0 is about running EDDI at scale and under failure, and about control over what agents do.

  • 📈 Scale and overload. Turns run on virtual threads behind an in-flight limit, EDDI scales out on NATS JetStream, database round trips per turn dropped from 16.7 to about 6.5, and overload is refused early with 503 instead of queueing without bound.
  • 🛟 LLM turns that survive failure. Failures are classified and retried by one owner, bad output is re-asked, a failing model is circuit-broken, and callers get structured errors and Idempotency-Key retries.
  • 🎚️ Every provider parameter. All 19 LLM integrations now read every parameter their API accepts (topP, seed, stopSequences, reasoning controls and vendor fields). A model-aware catalog warns about settings a model rejects or ignores, and the Manager has a settings panel. A new openai-compatible type covers vLLM, llama-server, TGI and LiteLLM.
  • 📚 RAG you can see and trust. Ingestion shows live progress, run details and schedule status in the Manager, a knowledge-base inspector tests retrieval, and every knowledge base now has an isolated store.
  • 🚧 Governance. Input and output guardrails (including a classifier backed by your own safety model), a per-conversation cost ceiling, an enforced tenant monthly budget, and agent test suites ("golden conversations").
  • 🔌 Integration. A signed inbound webhook channel (CloudEvents), A2A 1.0, and W3C trace propagation on outbound calls.
  • 🔒 Hardening. Fixes for secret handling, authorization gaps, outbound requests and deployment defaults. Many apply to code that shipped in 6.5.0 or earlier, so upgrading is recommended regardless of the new features.

Please read the Breaking Changes before upgrading.


🚀 What's New

📈 Scale & Overload

  • 🧵 Virtual-thread turns. eddi.conversation.max-in-flight-turns is now derived from the heap by default. Past the limit a turn is refused with 503 capacity_exceeded and Retry-After, before any database read. One conversation may queue at most 20 turns, and a MongoDB pool wait is capped at 10 s instead of 120 s.
  • ⏱️ The turn timeout holds under load. agentTimeoutInSeconds counts from the request's arrival. A caller whose time ran out gets 408, and a turn still queued for them is dropped without running (input kept, Idempotency-Key released). /q/metrics is served on its own threads, so graphs no longer go blank during a burst.
  • 🗄️ Fewer database round trips per turn: 16.7 → about 6.5.
  • 🌐 Cluster mode. eddi.messaging.type=nats is read at runtime from the one image: any number of replicas behind a round-robin load balancer, one database, one NATS cluster. Leases with fencing, dead letters, and one turn per idempotency key across nodes. The Manager gets a cluster console with health, leases, dead letters and safe recovery actions. in-memory stays the default.
  • 📏 Load-test suite (scripts/loadtest): throughput, streaming time to first token, cluster scaling, group discussions, and a CI gate on database operations per turn.

🛟 Resilient LLM Turns

  • Failure classification: a daily quota is no longer retried like a per-minute limit, the provider's retry delay is honoured, and langchain4j's own retries no longer stack under EDDI's.
  • Recovery policies: responseValidation can re-ask the same model before escalating (onInvalidJson, onSchemaMismatch, onContextTooLong). responseSchema and nonBlankFields catch valid JSON of the wrong shape.
  • circuitBreaker (opt-in) skips a model that cannot answer at all.
  • One turn deadline (turnDeadlineMs, X-EDDI-Turn-Deadline-Ms) across retries, cascade steps and HTTP calls.
  • Tool repeat guard refuses identical failing tool calls (on by default, see Breaking Changes).
  • Structured errors and idempotent turns: a failed turn returns error.code, retryable and Retry-After; resending with the same Idempotency-Key returns the finished answer instead of 409 IN_PROGRESS.

🚧 Governance & Testing

  • Guardrails. inputGuardrails and outputGuardrails on an LLM task screen for prompt-injection phrasing, PII, regex, length and JSON shape with block, warn, redact or reprompt, on every path including streaming and HITL resume. A classifier guardrail sends the text to a safety model you configure (Granite Guardian, ShieldGemma, any registered provider or OpenAI-compatible endpoint). Only a positive match of safeLabel counts as safe, and failMode defaults to closed.
  • Cost. maxCostPerConversationUsd on the agent bounds one conversation, group-member turns included. The tenant maxMonthlyCostUsd budget was stored but never metered; settled turns and Dream runs are now charged and the model-call gate trips when it is spent.
  • Agent test suites. An AgentTestSuite config holds scripted cases with per-turn expectations (actionsContain, properties, outputContains, toolCalled, maxCostUsd) and tool mocks that fail closed. Runs go against the test environment, are capped by a per-run dollar ceiling (default $1) and never touch long-term user memory. Available over REST, MCP and in the Manager.

🔌 Integration

  • Signed webhook channel. channelType: "webhook" exposes POST /integrations/webhook/{integrationId}. The HMAC over the raw body is checked fail-closed (eddi-v1, github or generic-hmac). CloudEvents and plain JSON arrive as the context value event (data, never a template) and route by event type to an agent or group.
  • A2A 1.0. Agent Cards and tasks follow the spec (1.0 and 0.3 served from one endpoint). Task states are honest: a failing LLM or a HITL pause is no longer reported as completed. Tasks survive a restart.
  • Observability. W3C trace context propagates on outbound calls, and every tool call gets an execute_tool span.
  • Platform Operator. It can look up the running version, edit configs that hold vault references, and explain 503, 408 and node sizing.

🔄 Promote Without Ending Conversations

A conversation follows newer agent versions only within its compatibility generation, and imports and syncs used to break it. Now:

  • POST /backup/import and /backup/import/sync[/batch] take compatible (default false, so nothing changes unless you ask). Previews show how many open conversations would follow.
  • POST /administration/{environment}/upgradeconversations/{agentId} (MCP: upgrade_conversations) moves already-pinned conversations onto the current version. It defaults to a dry run.

⚠️ Breaking Changes & Upgrade Notes

Change Impact
🔑 Secret creates need allowedHosts With eddi.vault.grant-enforcement=enforce (the default), creating a secret without allowedHosts returns 400. ["*"] opts out explicitly. Rotations are unaffected.
🗄️ MongoDB user EDDI connects as eddi_app instead of root. Compose and Helm create the user on every start, so existing volumes migrate without a manual step. Kustomize users with their own mongodb-secrets need the patch in docs/upgrading-from-6.5.md.
🪪 Keycloak default password docker-compose.auth.yml refuses to start Keycloak off loopback while the bootstrap password is unset or admin.
🚦 Overload answers Clients can now receive 503 capacity_exceeded (limit reached, queue full, database pool wait) and 408 (their time ran out) and should honour Retry-After.
📦 Resource defaults The image uses 75 % of the memory limit as heap, G1, and exits on out-of-memory. Helm and Kustomize request 1 CPU and 3 GiB (production overlay 2 CPU and 4 GiB). Check that your nodes can schedule it.
🔁 Tool repeat guard on by default Disable per agent with "toolRepeatGuard": {"enabled": false}.
🌐 SSRF switch covers more With eddi.security.ssrf-protection.enabled=true, LLM, embedding, vector-store and OpenAPI-discovery targets are checked too. Self-hosted model servers on private addresses should use the openai-compatible type or leave the switch off.
🔒 Credentials hidden from editors Non-admins no longer read plaintext credentials in any config store. Resetting a tenant's vault requires confirm=true.
🧩 Hugging Face Uses the langchain4j default router when baseUrl is unset. baseUrl is the service root without models/.
🛰️ Cluster Messaging is chosen by eddi.messaging.type at runtime. Any value other than in-memory or nats fails the boot.

Take a backup before upgrading.


🔒 Security

  • Secrets go only where allowed: allowedHosts is enforced for LLM, embedding, vector-store, MCP and A2A references and editable in the Manager; no default grant on create; wider redaction of provider key shapes and Digest headers.
  • Authorization gaps closed in directory listings, workflow references, group USE checks, platform.* variables and group attachments. GDPR erasure and export now reach group discussions.
  • Outbound requests: one facade for SSRF policy, redirects, header stripping and body caps; unreadable hosts are refused; log lines are sanitised.
  • Hostile input: the expression parser, dictionary regexes, template string operations and JSON fence stripping are bounded.
  • Deployment: CI/CD, Helm, Compose and installer fixes. SHA256SUMS is signed with cosign and the installers verify it.
  • MCP: remote tool schemas are checked, redirects refused, tool budgets enforced by default, and read_audit_trail hides compiledPrompt from callers without VIEW on the agent.

🐛 Bug Fixes

  • Malformed model JSON no longer fails a turn; fenced or prose-wrapped JSON is recovered.
  • A HITL-paused turn is delivered only after the pause is persisted, and approval cards are never approvable before they describe the pause.
  • 5.x migration: the properties migration runs in the background with progress logging, 5.x LLM defaults carry over, and nested conditionals convert correctly.
  • An idle sweep no longer loads every open conversation; a bulk "end inactive conversations" exists.
  • Alert rules are shipped and loaded, and empty or duplicate monitoring panels are fixed.

📦 Dependency Updates

langchain4j 1.20.2 → 1.22.0, quarkus-mcp-server 2.0.1 → 2.0.3, PostgreSQL JDBC 42.7.13 → 42.7.14, classgraph 4.8.196 → 4.8.199, Node (UI build) 24.21.0 → 24.22.0.


🖥️ EDDI Manager

New screens for guardrails, agent test suites, cost limits, the cluster console and ingestion; a model picker that shows the full catalog; and a consistency pass over saves, unsaved-changes guards, layout at every screen size and RTL.


📋 Full Changelog

6.5.0...6.6.0. See docs/changelog.md and docs/changelog/2026-10.md for per-change detail and design decisions.


🐳 Docker Image

docker pull labsai/eddi:6.6.0
cosign verify \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity-regexp '^https://github\.com/labsai/EDDI/\.github/workflows/ci\.yml@refs/(heads/main|tags/[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?)$' \
  labsai/eddi:6.6.0

EDDI is distributed exclusively as a Docker image. There are no binary downloads.