Release 0.4.0: AG-UI Protocol Unification
Highlights
0.4.0 restructures the platform around the AG-UI protocol and makes the Next.js gateway the single front door. Streaming, conversation storage, and authentication stop being per-client concerns: the web UI, Slack bot, and dynamic agents all speak one event model and share one conversation API.
Helm values for all three components are restructured. The upgrade guide below has the complete before/after mapping.
Features
AG-UI protocol
- Unified streaming: the AG-UI event model replaces legacy A2A streaming across dynamic agents, the Slack bot, and the UI. Stream events are persisted server-side.
- Stream encoder abstraction:
AGUIStreamEncoderandCustomStreamEncoderbehind aStreamEncoderABC. - Slack bot rewritten on AG-UI: typing indicators with live thoughts, todo-aware streaming, and subagent suppression.
Next.js gateway architecture
- All traffic routes through the gateway: flat
/api/v1/chat/routes authenticated withX-User-Context. Dynamic agents no longer validate tokens or accept direct browser requests. - Config ownership moved from dynamic agents to the UI: agent CRUD, MCP servers, and the models endpoint now live in local MongoDB.
- Bearer-token auth for service accounts, which is how the Slack bot authenticates.
Shared conversation API
- Server-owned ID generation with an
idempotency_keyfor cross-client dedup. - A
client_typeenum (webui|slack) on every conversation; all ten Slack handlers migrated. - Delta thread context: follow-ups embed only messages since
last_processed_ts, eliminating quadratic checkpoint growth on long threads. PATCH /api/chat/conversations/[id]/metadatawith MongoDB dot-notation$set.
Dynamic agents runtime
ClientContextand Jinja2 system-prompt rendering.- New
waitandagent_infotools; configurable middlewares. NAMESPACE_CONTEXTemitted only on change,UserContextmade opaque, and RBAC removed from chat routes (the gateway owns it).- A metrics endpoint.
UI
- Streaming markdown with rAF throttling, block animations, and cursor improvements.
- Jinja2 syntax highlighting in the system-prompt editor.
- A turns collection, decoupling
stream_eventsfrom messages. - Admin: platform statistics with Slack integration, unified filters, user detail panels, and paginated conversations.
- An LLM model config page for adding and removing models through the UI.
- A new System theme that follows the OS setting.
Fixes
- slack: add the
escalation_policyfield to the VictorOps escalation config; stop the humble-followup prompt from claiming knowledge of a reply the agent never made. - admin: key feedback dedup on
(permalink, user_email)rather than permalink alone, key the Slack feedback upsert on(message_id, user_id), and fix top-user linkage.
Breaking changes
This release contains significant breaking Helm value changes. The upgrade guide below has the complete before/after mapping.
| Change | Severity |
|---|---|
env: block removed from all components; use the flat config: map | High |
caipe-ui.seedConfig.* → caipe-ui.appConfig.* (SEED_CONFIG_PATH → APP_CONFIG_PATH) | High |
slack-bot values completely restructured to a flat config: map | High |
slack-bot.slack.tokenSecretRef → slack-bot.existingSecret | High |
slack-bot botConfig channels: qanda/ai_alerts/ai_enabled → flat agents list | High |
dynamic-agents OIDC/CORS keys removed; auth is handled by the gateway | High |
dynamic-agents.config.AUTH_ENABLED → DEBUG: "true" for the dev bypass | Medium |
Known issues
The Admin Statistics page under-reports Slack conversation counts until an
InteractionTracker equivalent is re-implemented in the new AG-UI Slack bot.
Upgrade
helm upgrade ai-platform-engineering \
oci://ghcr.io/caipe-io/charts/ai-platform-engineering \
--version 0.4.0 \
-f your-values.yaml
Upgrade guide: 0.3.x → 0.4.0
1. CAIPE UI
Merge env: into config:. All environment variables live in one flat map.
# Before (0.3.x)
caipe-ui:
env:
SKILLS_DIR: "/app/data/skills"
config:
SSO_ENABLED: "true"
# After (0.4.0)
caipe-ui:
config:
SKILLS_DIR: "/app/data/skills"
SSO_ENABLED: "true"
Rename seedConfig: to appConfig: and drop enabled:. The ConfigMap is created
automatically when any of models, mcp_servers, or agents is non-empty. The chart
swaps SEED_CONFIG_PATH for APP_CONFIG_PATH on your behalf.
2. Dynamic agents
- Merge
env:intoconfig:, then delete theenv:block. - Remove
AUTH_ENABLED. For a local dev bypass useDEBUG: "true"; in production omit it. - Remove
OIDC_ISSUER,OIDC_CLIENT_ID,OIDC_REQUIRED_ADMIN_GROUP, andCORS_ORIGINS. These belong tocaipe-uinow, because dynamic agents never see a browser request.
3. Slack bot, the bulk of the work
Named keys are replaced by a flat config: map plus a top-level existingSecret:.
| Old key (0.3.x) | New key in config: |
|---|---|
appName | APP_NAME |
botMode | SLACK_BOT_MODE |
caipeApiUrl | CAIPE_API_URL |
silenceEnv | SLACK_INTEGRATION_SILENCE_ENV |
slackWorkspaceUrl | SLACK_WORKSPACE_URL |
env.* | move into config: |
mongodb.uri | MONGODB_URI (consider a Secret instead) |
mongodb.database | MONGODB_DATABASE |
auth.enabled | SLACK_INTEGRATION_ENABLE_AUTH |
auth.tokenUrl | OAUTH2_TOKEN_URL |
auth.clientId | OAUTH2_CLIENT_ID |
auth.scope | OAUTH2_SCOPE (omit if empty) |
auth.audience | OAUTH2_AUDIENCE (omit if empty) |
prompts.responseStyle | SLACK_INTEGRATION_PROMPT_RESPONSE_STYLE |
prompts.qanda | SLACK_INTEGRATION_PROMPT_QANDA |
prompts.overthinkQanda | SLACK_INTEGRATION_PROMPT_OVERTHINK_QANDA |
prompts.mention | SLACK_INTEGRATION_PROMPT_MENTION |
prompts.humbleFollowup | SLACK_INTEGRATION_PROMPT_HUMBLE_FOLLOWUP |
prompts.aiAlerts | SLACK_INTEGRATION_PROMPT_AI_ALERTS |
slack.tokenSecretRef | existingSecret (top level, same Secret) |
The Secret contents do not change: SLACK_BOT_TOKEN, SLACK_APP_TOKEN,
SLACK_SIGNING_SECRET, and optionally OAUTH2_CLIENT_SECRET.
Bot config file moved. CAIPE_BOT_CONFIG → SLACK_INTEGRATION_BOT_CONFIG (set by
the chart), and /etc/caipe/caipe-bot-config.yaml → /etc/caipe/bot-config.yaml in a
dedicated *-bot-config ConfigMap. If neither is present the bot starts with no channel
configuration and logs a warning rather than crashing.
botConfig channels use a flat agents list. The bot rejects the old keys with an
explicit error.
# Before
botConfig:
C012345678:
name: "#example-channel"
ai_enabled: true
qanda:
enabled: true
include_bots: { enabled: true, bot_list: ["example-bot"] }
ai_alerts: { enabled: false }
# After
botConfig:
C012345678:
name: "#example-channel"
agents:
- agent_id: "example-agent"
users:
enabled: true
listen: "mention" # "mention" | "message" | "all"
overthink: { enabled: false }
bots:
enabled: true
listen: "message"
bot_list: ["example-bot"]
4. The unified config pattern
All components converge on the same shape:
component:
config: {} # flat env vars → ConfigMap → envFrom
existingSecret: "" # pre-existing Secret → envFrom secretRef
externalSecrets:
enabled: false
appConfig: {} # structured YAML file, caipe-ui only
botConfig: {} # structured YAML file, slack-bot only
config: is always flat. No nesting, no config.env: sub-keys.
5. Pre-upgrade checklist
- Back up values:
helm get values ai-platform-engineering -o yaml > values-backup.yaml -
caipe-ui: mergeenv:intoconfig:, renameseedConfig→appConfig -
dynamic-agents: mergeenv:, dropAUTH_ENABLED, drop OIDC/CORS keys -
slack-bot: restructure named keys intoconfig:, setexistingSecret -
botConfig: replaceqanda/ai_alerts/ai_enabledwith theagentslist -
helm diff upgradebefore applying - Deploy, then check pod logs for config-loading messages
Rollback
helm rollback ai-platform-engineering <previous-revision> and restore the backed-up
values file. These are configuration-only changes, so no data migration has to be undone.
The 0.3.x chart expects the old structure and the old values file works as-is.


