Skip to content

Commit 55636f2

Browse files
authored
Bring the docs, changelog and chart version in line for a release (#520)
Validated every doc against the code and fixed the drift found: - README: the Main surfaces table was missing /routines, /admin/skills, /admin/people and /admin/identity-providers, and described /admin/plugins as configuring deployment skills, which it no longer does. - configuration.md: five required vars, not three; documented AGENT_BOT_MODEL, BOT_REASONING_EFFORT and OPENAI_CONTAINER_BASE_URL; fixed a broken table column; distinguished COMPUTER_SANDBOX from the cluster sandbox provider. - architecture.md: added the command policy field and the agent-harness service. - coworkers.md: noted the provenance block the deployment appends to the standing role. - development.md: openssl and npx prerequisites, and the routine worker in the start.sh summary. - releasing.md: the two gating CI jobs the checks table omitted; the release PR now carries three changes. - deployment.md: removed the desktop folder-access section; the desktop app is not released. - plugins/google-drive.md: rewritten for the REST API the connector actually uses, replacing the abandoned MCP setup, troubleshooting and enrolment steps. CHANGELOG: added the validation-hardening sweep that had no entry yet (agent tool-call, policy dry-run and audit-event limits, component publication, sandboxed fields, catalogue entries, the four human-input gestures), calling out the component decision-function fail-open; dropped the desktop question-box entry, since the desktop app is not released. Chart version: the default image tag was the bare appVersion (0.0.4), but published tags carry a v and 0.0.4 predates the first startable release, so a default helm install sat in ImagePullBackOff. appVersion now tracks the released version (0.0.9), the tag helper prefixes v to name a tag that exists, the release workflow moves appVersion with package.json every release, and CI refuses a tree where the two have drifted.
1 parent e7bbe77 commit 55636f2

15 files changed

Lines changed: 130 additions & 115 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@ jobs:
3535
- run: bun run format:check
3636
- run: bun run lint
3737
- run: bun run typecheck
38+
# The chart's default image tag is its appVersion, and a release must move both together. They
39+
# drifted once, appVersion left pointing at a tag that was never published, and a default
40+
# `helm install` sat in ImagePullBackOff. This refuses a tree where package.json (the last
41+
# version published) and the chart's appVersion have come apart.
42+
- name: Chart appVersion tracks the release version
43+
run: |
44+
pkg=$(bun -e 'console.log(require("./package.json").version)')
45+
chart=$(bun -e 'console.log(require("yaml").parse(require("fs").readFileSync("charts/openbot/Chart.yaml","utf8")).appVersion)')
46+
if [ "$pkg" != "$chart" ]; then
47+
echo "::error::package.json is $pkg but charts/openbot/Chart.yaml appVersion is $chart. The release workflow moves them together; bring them back into line."
48+
exit 1
49+
fi
3850
3951
# The two packages that are deployables in their own right rather than root workspaces. Root
4052
# `typecheck` is `bun run --filter '*' typecheck`, and `--filter '*'` enumerates `workspaces`, which

‎.github/workflows/release.yml‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,11 @@ jobs:
103103
' -- "$BUMP" > /tmp/version
104104
version=$(cat /tmp/version)
105105
106+
# The chart's default image tag is its appVersion, so a release that moves package.json
107+
# without moving this leaves a default `helm install` pulling the previous image, or an
108+
# image tag that was never pushed. Move them together, every time.
109+
sed -i -E "s/^appVersion:.*/appVersion: \"$version\"/" charts/openbot/Chart.yaml
110+
106111
# Unreleased becomes the version, and a fresh empty Unreleased takes its place so the next
107112
# change has somewhere to go without anyone hand-editing a heading.
108113
bun -e '
@@ -139,7 +144,7 @@ jobs:
139144
- name: Preview
140145
if: inputs.dry_run
141146
run: |
142-
git --no-pager diff -- package.json CHANGELOG.md
147+
git --no-pager diff -- package.json CHANGELOG.md charts/openbot/Chart.yaml
143148
cat /tmp/pr-body.md
144149
145150
# A pull request opened by a workflow does not trigger the pull_request workflows, so the

‎CHANGELOG.md‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ tells its model the call was refused, with the status and the deployment's reaso
1717
Python LangGraph Bot already does, and the transcript draws it as a refusal. A tool that answered is
1818
passed on exactly as before.
1919

20-
### The desktop setup's question box waits for a composed character before it asks
21-
22-
Enter confirms a character being typed through an input method (Japanese, Chinese, Korean). On the
23-
final setup screen that Enter also sent the question, with its last character still unconfirmed. The
24-
box now waits for the character to be confirmed, the way a chat composer does, and an ordinary Enter
25-
still asks.
2620
### Revoking a grant with a blank ref or Bot is refused instead of reported as done
2721

2822
`DELETE /api/plugins/grants` checked its query params with truthiness, and a query param is
@@ -62,6 +56,21 @@ no check at all. Both reached the store, where the insert threw an uncaught erro
6256
caller error. A slug, a title and instructions must be non-empty strings now, the slug pattern is
6357
tested only after that, and a summary must be absent or a string; anything else is a 400 naming
6458
the field, before any refusal check, store write, or audit row.
59+
60+
### More endpoints refuse a malformed request instead of coercing it or failing open
61+
62+
The same treatment reached the rest of the write and query surface: the agent tool-call endpoint's
63+
name and arguments, the policy dry-run and audit-event list limits, a component's publication flag,
64+
the sandboxed-component fields, and a catalogue entry are each checked and answered with a 400 that
65+
names the bad field before the store is touched. The four hand-driven computer gestures — click,
66+
type, key and scroll — validate their own payloads the same way, so a click with no coordinates or a
67+
key with no key is refused rather than sent to the computer as a no-op.
68+
69+
One of these closed a hole rather than tightening an edge. A component's list of decision functions
70+
was filtered to the strings in it, so `{"functions":[123,null,{}]}` became an empty list, the
71+
permission check ran over nothing, and the answer came back `allowed` for functions the caller had in
72+
fact named. The verdict is about the functions named now, or a 400; an absent list still means none.
73+
6574
### Generated interfaces, tables and forms
6675

6776
Generative UI is enabled by default; set `OPENBOT_GENERATIVE_UI=false` or `0` to disable it.

‎README.md‎

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -139,21 +139,25 @@ Leave `EMBEDDED_POSTGRES` off and set `DATABASE_URL` to point at a database you
139139

140140
## Main surfaces
141141

142-
| Route | Purpose |
143-
| -------------------- | ------------------------------------------------------------------ |
144-
| `/` | Start and browse channels. |
145-
| `/agents` | Create, edit, duplicate, hide, delete, and launch coworkers. |
146-
| `/channel/:id` | Converse with one coworker, watch its screen, and see what it ran. |
147-
| `/bot` | Direct chat with a Bot; `?agent=<id>` selects one. |
148-
| `/skills` | Create and enable personal skills. |
149-
| `/settings` | User preferences. |
150-
| `/admin/credentials` | Store write-only encrypted credentials. |
151-
| `/admin/computers` | View, stop, and reset Bot computers. |
152-
| `/admin/boundaries` | Configure browser/file/MCP action policy. |
153-
| `/admin/components` | Publish components and govern which Bots may use them. |
154-
| `/admin/playground` | Draft and publish sandboxed components in the browser. |
155-
| `/admin/plugins` | Configure MCP servers, MCP grants, and deployment skills. |
156-
| `/admin/audit` | Review permitted, refused, and failed actions. |
142+
| Route | Purpose |
143+
| --------------------------- | ------------------------------------------------------------------ |
144+
| `/` | Start and browse channels. |
145+
| `/agents` | Create, edit, duplicate, hide, delete, and launch coworkers. |
146+
| `/channel/:id` | Converse with one coworker, watch its screen, and see what it ran. |
147+
| `/bot` | Direct chat with a Bot; `?agent=<id>` selects one. |
148+
| `/skills` | Create and enable personal skills. |
149+
| `/routines` | See the routines that are standing, and stop one. |
150+
| `/settings` | User preferences. |
151+
| `/admin/credentials` | Store write-only encrypted credentials. |
152+
| `/admin/computers` | View, stop, and reset Bot computers. |
153+
| `/admin/boundaries` | Configure browser/file/MCP action policy. |
154+
| `/admin/components` | Publish components and govern which Bots may use them. |
155+
| `/admin/playground` | Draft and publish sandboxed components in the browser. |
156+
| `/admin/plugins` | Configure MCP servers and grant their tools to Bots. |
157+
| `/admin/skills` | Write deployment skills and grant them to Bots. |
158+
| `/admin/people` | List, promote, demote, and remove people who have signed in. |
159+
| `/admin/identity-providers` | Register a company SAML or OIDC provider, routed by email domain. |
160+
| `/admin/audit` | Review permitted, refused, and failed actions. |
157161

158162
## Features
159163

‎charts/openbot/Chart.yaml‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ name: openbot
33
description: Run OpenBot on any Kubernetes cluster, managed or your own
44
type: application
55
# The chart's own version, bumped when templates or defaults change.
6-
version: 0.1.0
7-
# The OpenBot release this chart's default image tag points at.
8-
appVersion: "0.0.4"
6+
version: 0.1.1
7+
# The OpenBot release this chart's default image tag points at. Kept equal to package.json's version
8+
# (the last version published) by the release workflow, and CI refuses a tree where they have drifted.
9+
appVersion: "0.0.9"
910
home: https://github.com/CopilotKit/OpenBot
1011
sources:
1112
- https://github.com/CopilotKit/OpenBot

‎charts/openbot/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ node pool being the wrong shape is the last thing anybody checks. Either run amd
1515
architecture you have and push it somewhere the cluster can reach. Check before assuming:
1616

1717
```sh
18-
docker manifest inspect ghcr.io/copilotkit/openbot:v0.0.4 | grep architecture
18+
docker manifest inspect ghcr.io/copilotkit/openbot:v0.0.9 | grep architecture
1919
```
2020

2121
**Intelligence credentials.** OpenBot requires CopilotKit Intelligence and the chart refuses to

‎charts/openbot/templates/_helpers.tpl‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,13 @@ name it. Nothing else in the chart consults it.
183183
{{- end -}}
184184
{{- end -}}
185185

186-
{{/* The image, with the chart's appVersion as the tag unless one is named. */}}
186+
{{/*
187+
The image, with the chart's appVersion as the tag unless one is named. Published tags carry a `v`
188+
(`v0.0.9`), and appVersion is plain semver, so the default is prefixed with `v` to name a tag that
189+
actually exists. A named `image.tag` is used verbatim.
190+
*/}}
187191
{{- define "openbot.image" -}}
188-
{{- $tag := default .Chart.AppVersion .Values.image.tag -}}
192+
{{- $tag := .Values.image.tag | default (printf "v%s" .Chart.AppVersion) -}}
189193
{{- printf "%s:%s" .Values.image.repository $tag -}}
190194
{{- end -}}
191195

‎charts/openbot/values.yaml‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ fullnameOverride: ""
1212

1313
image:
1414
repository: ghcr.io/copilotkit/openbot
15-
# Empty means the chart's appVersion, so an upgrade of the chart moves the image with it.
15+
# Empty means the chart's appVersion prefixed with `v` (the form published tags take), so an
16+
# upgrade of the chart moves the image with it. A value set here is used verbatim.
1617
tag: ""
1718
pullPolicy: IfNotPresent
1819
imagePullSecrets: []

‎docs/architecture.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Regenerate it with `bun run diagram` after changing anything it shows.
1818
| `agent-computer` | 4100 | Chromium, `/workspace`, browser profile, screenshots, snapshots, and file tools. |
1919
| `agent-bot` | 4200 | Proof-of-concept AG-UI Bot. |
2020
| `agent-langgraph` | 4201 | LangGraph AG-UI Bot. |
21+
| `agent-harness` | 4202 | The Bot framework harness chosen during setup, one of the `agent-<framework>` images, behind the `harness` compose profile. |
2122
| `supervisor` | 4500 host / 4300 container | Creates, stops, resets, and lists per-Bot computer containers. |
2223
| PostgreSQL with pgvector | 5432 | Product data, audit rows, credentials, policy, grants, channels, and components. |
2324
| CopilotKit Intelligence | external | Durable threads, memory, and realtime gateway. |
@@ -54,6 +55,7 @@ Policy rules can inspect:
5455
- `page.url`, `page.host`
5556
- `element.ref`, `element.role`, `element.name`, `element.type`
5657
- `key`
58+
- `command`
5759
- `file.path`, `file.name`, `file.extension`
5860
- `mcp.server`, `mcp.tool`, `mcp.effect`
5961

‎docs/configuration.md‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ bash scripts/start.sh
2424
| `INTELLIGENCE_GATEWAY_WS_URL` | CopilotKit Intelligence realtime gateway URL. |
2525
| `INTELLIGENCE_API_KEY` | Runtime key for the Intelligence project. |
2626

27-
The three above are required together. Missing any of them stops server startup.
27+
All five above stop server startup if missing. The three `INTELLIGENCE_` values are additionally
28+
checked as a set, so a partial set is refused as a misconfiguration rather than treated as
29+
unconfigured.
2830

2931
`COPILOTKIT_LICENSE_TOKEN` is optional: managed Intelligence issues no licence token, and a
3032
self-hosted Intelligence that has one sets this and has it forwarded to the runtime.
@@ -51,8 +53,10 @@ at `agent-langgraph` on a laptop.
5153
| `ANTHROPIC_BASE_URL` | unset | Anthropic-compatible endpoint that key is spent against. |
5254
| `GOOGLE_API_KEY` | unset | Google key when `BOT_PROVIDER=google`. |
5355
| `GOOGLE_GENERATIVE_AI_BASE_URL` | unset | Google-compatible endpoint that key is spent against. |
54-
| `BOT_MODEL` | provider default from Bot code/env | Model used by the shipped Bots. |
56+
| `BOT_MODEL` | provider default from Bot code/env | Model for the framework Bot (`agent-langgraph`). Provider defaults are `gpt-5.5`, `claude-sonnet-4-5`, and `gemini-2.5-flash`. |
57+
| `AGENT_BOT_MODEL` | `gpt-5.5` | Model for the proof-of-concept Bot (`agent-bot`), kept separate because it speaks `/v1/chat/completions` directly and refuses a model it cannot use. |
5558
| `BOT_RESPONSES_API` | `false` | Makes `agent-langgraph` use the OpenAI Responses API. |
59+
| `BOT_REASONING_EFFORT` | unset (provider default) | OpenAI and the Responses API only: one of `none`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`. `agent-langgraph` refuses to start on any other value, on a non-`openai` provider, or without the Responses API. |
5660
| `AGENT_STALL_TIMEOUT_MS` | unset (off) | How long a Bot's stream may produce nothing before the turn is ended for it. |
5761
| `AGENT_TOOL_TOKEN` | unset; `start.sh` generates one | The secret a framework Bot presents when it calls a granted tool back through this server. |
5862
| `APP_DIST_DIR` | unset | Where the built app is, when this process serves it. Set inside the container image; unset in development, where Vite serves the app. |
@@ -128,6 +132,8 @@ in-cluster Service address.
128132

129133
It moves the whole deployment rather than one Bot. The API server reads it for package built-in agents, `agent-bot` reads it for the client it constructs, and `agent-langgraph` reads it for `BOT_PROVIDER=openai`.
130134

135+
`OPENAI_CONTAINER_BASE_URL` overrides that value inside the Bot containers only, for an endpoint the containers reach by a different route than the host does. Unset, the containers use `OPENAI_BASE_URL` like everything else.
136+
131137
The other two providers work the same way under their own names, because they are different APIs rather than different URLs for this one: `ANTHROPIC_BASE_URL` and `GOOGLE_GENERATIVE_AI_BASE_URL`. All three are the names the API server already reads, so one line moves the built-in agents and the Bots together and a deployment cannot end up with half of itself pointed somewhere else.
132138

133139
Model names travel verbatim, so use whatever the endpoint publishes. An endpoint that namespaces its catalogue wants both halves of the name, in `BOT_MODEL` and in the tenant package's `default_model` alike.
@@ -244,11 +250,17 @@ then is a row nothing will read.
244250
| `COMPUTER_SUPERVISOR_URL` | Supervisor URL for per-Bot computers. If absent, Bots share `AGENT_COMPUTER_URL`. |
245251
| `SUPERVISOR_TOKEN` | Bearer token required by the supervisor. |
246252
| `AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS` | Local-only private-host browsing when `true`. A deployment running with `NODE_ENV=production` refuses to start while it is set. Cloud metadata addresses are refused either way. |
247-
| `AGENT_ENDPOINT_ALLOWED_HOSTS` | unset | Private addresses an agent may be registered at, comma separated. Host, optionally with a port. Exact match; no wildcards. Never-allowed addresses cannot be named. |
253+
| `AGENT_ENDPOINT_ALLOWED_HOSTS` | Private addresses an agent may be registered at, comma separated; unset (none) by default. Host, optionally with a port. Exact match; no wildcards. Never-allowed addresses cannot be named. |
248254
| `AGENT_COMPUTER_POLICY` | JSON action policy: `{"mode":"enforce","deny":[...],"allow":[...]}`. |
249255
| `COMPUTER_RUNTIME` | Set to `runsc` to run supervised computers under gVisor. |
250256
| `COMPUTER_SANDBOX` | Set to `on` to enable Chromium's own sandbox where the host permits user namespaces. Which way it went is printed at start-up. |
251257

258+
`COMPUTER_SANDBOX` is not the cluster sandbox provider. A Kubernetes deployment can instead run each
259+
computer as a sandboxed pod, selected by `COMPUTER_SANDBOX_NAMESPACE` with `COMPUTER_SANDBOX_IDLE_AFTER`
260+
and `COMPUTER_SANDBOX_TEMPLATE_FILE` beside it; those are set by the Helm chart, not by Compose, and
261+
are covered in [charts/openbot/README.md](../../charts/openbot/README.md). The similarly named
262+
`COMPUTER_SANDBOX` above only toggles Chromium's own process sandbox on a Docker computer.
263+
252264
Changing `COMPUTER_BROWSER_MODE` affects new supervised computers. A computer that already exists is
253265
left running until its image changes or its container is recreated. To apply a mode-only change to
254266
all computers while preserving their browser profiles and workspaces, apply the new supervisor

0 commit comments

Comments
 (0)