diff --git a/CHANGELOG.md b/CHANGELOG.md index 11fb9c67f..e8247f03b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,19 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged. ## Unreleased +### Setting up needs one Intelligence credential, not two + +`COPILOTKIT_LICENSE_TOKEN` is no longer required. Managed Intelligence derives entitlement from the +project key, so the second credential people were sent to fetch had stopped existing, and startup +was still refusing to boot without it. A deployment now needs `INTELLIGENCE_API_URL`, +`INTELLIGENCE_GATEWAY_WS_URL` and `INTELLIGENCE_API_KEY`. A licence token is still read and still +forwarded to the runtime when set, which is what a self-hosted Intelligence with its own licence +needs. + +The Helm chart failed harder than the docs did: it *required* `secrets.licenseToken`, so a +managed-Intelligence install was refused at `helm install` rather than merely misdocumented. That +value is now optional. + ### Duplicating a coworker keeps the endpoint it was copied from Duplicate used to point every copy at this deployment's own managed Bot, whatever the coworker being @@ -106,6 +119,22 @@ roster never said so. A reported time is now capped at the server's own clock. bound a random port while the published mapping still pointed at 4300. Empty now means the default 4300; a non-numeric or out-of-range value refuses to start instead of binding port 30 from a typo like `30o0`. +### Tool arguments and results are redacted in the audit trail whatever their spelling + +The sensitive-key list redacted `tool_result` and `tool_arguments` but not `toolResult` and +`toolArguments`, which is the spelling MCP and computer tool calls use. Those payloads were stored +verbatim in `audit_events.payload`, nested ones included, while every other sensitive key already +carried both spellings. New rows are redacted; rows already written are not rewritten, so a +deployment that has been running MCP or computer tools still holds unredacted arguments and results +in its existing trail. + +### An IPv6 address listed in `AGENT_ENDPOINT_ALLOWED_HOSTS` is now actually allowed + +A bracketed IPv6 host was normalised one way when the list was read and another way when an endpoint +was checked, so the two could never match: `[::1]:8080` became `::1]:8080` on one side and +`::1:8080` on the other. Registering a Bot at a listed IPv6 address was refused as a private +address anyway. IPv4 was unaffected. + ### An empty `PORT` no longer starts the server on a port nobody asked for `PORT` and `SERVER_PORT` name one number, and either is meant to move the server. A `PORT` that was @@ -116,6 +145,12 @@ that polls `SERVER_PORT` reported it had never started. An empty value now count every other setting already treats it, and a value that is not a whole port number (`30o1` used to start the server on port 30) refuses to start instead. +### `TRUSTED_ORIGINS` falls back to the port the app is actually served on + +Unset, it fell back to `http://localhost:3000`, while the app is served on 3010 everywhere else in +this repository. `appUrl` reads the first trusted origin, so a deployment that left the variable +blank built OAuth redirects against a port nothing was listening on. + ### Coworkers are made in a wizard and managed in a dialog Creating a coworker is now a three-step wizard — who it is, who may see it, then where it runs, @@ -228,6 +263,33 @@ showing a conversation that had been deleted until the page was reloaded. A server now tells the browsers it is holding to refetch when its subscription is re-established. Nothing to configure, and no change for a deployment whose database connection never drops. +### A Bot can answer with a picture instead of describing one + +Ask for a chart and a Bot replied in prose, or handed back a fenced block of HTML for somebody to +read instead of look at. Set `OPENBOT_GENERATIVE_UI=true` and it may answer with an interface it +writes itself, drawn in the transcript. Off unless asked for, and deliberately so: it runs code a +model wrote, so a deployment acquires the capability by choosing it rather than by upgrading. + +### The sidebar collapses, and the roster is reachable on a phone + +The sidebar could always collapse, but nothing in the app ever drew the trigger. The only +affordance was a 16px transparent rail carrying `tabIndex={-1}`, which the eye could not find and +the keyboard could not reach. Below 768px that same sidebar becomes a sheet whose open state starts +false, so with no trigger the roster was unreachable on a phone, and the roster is how you reach a +channel, Skills, Agents and your own account. There is now a toggle in the header each screen +already draws, with Cmd/Ctrl+B on it, and the collapsed choice survives a reload: the state was +written to a cookie that nothing ever read back. Fifteen screens that previously drew no header bar +gain 40px above their heading, because the toggle has to sit at the pane's edge. + +### A button drawn as a link answers the keyboard and announces itself + +Six controls navigate rather than submit, so they render a router link through the shared button: +New skill, New agent, the sidebar's new-channel control, two empty-state returns, and the back +button that draws on five routes. Base UI was told each was a native `