Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged.

## Unreleased

**Before upgrading.** Nine things change for an existing deployment:
**Before upgrading.** Eleven things change for an existing deployment:
- A hosted computer's browser is now headed by default. It uses a little more memory than headless
did; set `COMPUTER_BROWSER_MODE=headless` (Helm: `computers.browserMode: headless`) to keep the old
behaviour.
Expand Down Expand Up @@ -42,6 +42,28 @@ Newest first. `Unreleased` is what is on `main` and not yet tagged.
- On Helm's `shared` computer and the docker-compose `agent-computer`, each Bot's files now live in
`computers/<Bot id>` on the workspace volume (below). Files saved before the upgrade stay at the
root of the volume, where no Bot sees them; move them into a Bot's folder to give them back.
- With `OPENAI_BASE_URL` set to a host that is not OpenAI or Azure, `openai/...` models now use the
Chat Completions API rather than the Responses API (below). Set `COPILOTKIT_OPENAI_API=responses`
to keep the old behaviour.
- Interfaces a Bot drew before the upgrade (A2UI 0.9 surfaces) no longer draw when a conversation is
reopened; the messages around them stay. New ones use A2UI 1.0 (below).

### Generated interfaces use A2UI 1.0

With generative UI on, a Bot builds an interface from the A2UI 1.0 basic components instead of the
A2UI 0.9 ones. It's the same set of 18: text, images, icons, video, audio, rows, columns, lists,
cards, tabs, dividers, dialogs, buttons, checkboxes, text fields, date pickers, choice pickers and
sliders. They now take OpenBot's colours, radii and font, in light and dark. The gallery components a
Bot is granted are unchanged. `OPENBOT_GENERATIVE_UI=false` still switches it all off, on the server
as well as in the browser.

### CopilotKit 1.83

OpenBot now runs on CopilotKit 1.83.0 (`@copilotkit/runtime` and `react-core`, from 1.77.0) and
AG-UI 1.0.2 (`@ag-ui/core` and `@ag-ui/client`, from 1.0.1). A managed Intelligence project needs
nothing changed. A deployment whose `OPENAI_BASE_URL` points at an OpenAI-compatible gateway rather
than OpenAI or Azure now reaches `openai/...` models through Chat Completions; a gateway that only
speaks the Responses API needs `COPILOTKIT_OPENAI_API=responses`.

### The audit log reads like a log

Expand Down
5 changes: 2 additions & 3 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@ag-ui/core": "1.0.1",
"@ag-ui/core": "1.0.2",
"@base-ui/react": "^1.6.0",
"@better-auth/sso": "^1.7.1",
"@copilotkit/a2ui-renderer": "1.77.0",
"@copilotkit/react-core": "1.77.0",
"@copilotkit/react-core": "1.83.0",
"@fontsource-variable/inter": "^5.3.0",
"@openbot/shared": "workspace:*",
"@shadcn/react": "^0.3.0",
Expand Down
63 changes: 0 additions & 63 deletions app/src/lib/copilot/a2ui.css

This file was deleted.

114 changes: 114 additions & 0 deletions app/src/lib/copilot/a2ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import type { CopilotKitProviderProps } from "@copilotkit/react-core/v2";
import {
createGenerativeUI,
type GenerativeUITheme,
standardUI,
} from "@copilotkit/react-core/v2/generative-ui";

/**
* The A2UI 1.0 basic components: the same set the A2UI 0.9 basic catalog drew before. These are
* declarative primitives, not the separately granted OpenBot gallery components.
*/
export const A2UI_BASIC_COMPONENTS = [
"Text",
"Image",
"Icon",
"Video",
"AudioPlayer",
"Row",
"Column",
"List",
"Card",
"Tabs",
"Divider",
"Modal",
"Button",
"CheckBox",
"TextField",
"DateTimeInput",
"ChoicePicker",
"Slider",
] as const;

const basic: ReadonlySet<string> = new Set(A2UI_BASIC_COMPONENTS);

/**
* The components a Bot can draw an interface from: CopilotKit's standard catalog, cut down to the
* A2UI 1.0 basic components, which it carries under their A2UI names. The rest of the standard
* catalog stays out until an admin can see and govern it.
*/
export const OPENBOT_UI = createGenerativeUI({
id: "openbot/ui@1",
extends: [
standardUI.omit(
Object.keys(standardUI.manifestComponents).filter(
(name) => !basic.has(name),
) as Parameters<typeof standardUI.omit>[0],
),
],
components: {},
});

const radius = (scale: number) => `calc(var(--radius) * ${scale})`;

/**
* OpenBot's tokens, by reference. They switch under `.dark` themselves, so one set covers both
* schemes, and set at the top level they outrank the SDK's built-in dark values. Status tints,
* highlights and shadows have no OpenBot token and keep the SDK's light and dark values.
*
* The font is spelled out rather than `var(--font-sans)`: that one lives in `@theme inline`, which
* Tailwind inlines into utilities instead of emitting as a variable.
*/
export const OPENBOT_UI_THEME: GenerativeUITheme = {
"--a2ui-font-family":
'"Inter Variable", Inter, ui-sans-serif, system-ui, sans-serif',
"--a2ui-color-text-default": "var(--foreground)",
"--a2ui-color-text-prose": "var(--foreground)",
"--a2ui-color-text-primary": "var(--foreground)",
"--a2ui-color-text-emphasis": "var(--foreground)",
"--a2ui-color-text-secondary": "var(--muted-foreground)",
"--a2ui-color-text-tertiary": "var(--muted-foreground)",
"--a2ui-color-text-success": "var(--success)",
"--a2ui-color-text-danger": "var(--destructive)",
"--a2ui-color-surface": "var(--card)",
"--a2ui-color-surface-secondary": "var(--muted)",
"--a2ui-color-surface-tertiary": "var(--accent)",
"--a2ui-color-surface-elevated": "var(--popover)",
"--a2ui-color-surface-elevated-secondary": "var(--muted)",
"--a2ui-color-surface-inverted": "var(--foreground)",
"--a2ui-color-surface-soft": "var(--muted)",
"--a2ui-color-success-solid": "var(--success)",
"--a2ui-color-danger-solid": "var(--destructive)",
"--a2ui-color-border-default": "var(--border)",
"--a2ui-color-border-subtle": "var(--border)",
"--a2ui-color-border-strong": "var(--input)",
"--a2ui-color-border-control": "var(--input)",
"--a2ui-color-border-success": "var(--success)",
"--a2ui-color-border-danger": "var(--destructive)",
"--a2ui-color-accent": "var(--primary)",
"--a2ui-color-on-accent": "var(--primary-foreground)",
"--a2ui-color-panel": "var(--popover)",
"--a2ui-color-control": "var(--background)",
"--a2ui-color-focus": "var(--ring)",
"--a2ui-color-badge-secondary": "var(--secondary)",
"--a2ui-radius-sm": radius(0.6),
"--a2ui-radius-md": radius(0.8),
"--a2ui-radius-lg": radius(1),
"--a2ui-radius-xl": radius(1.4),
"--a2ui-radius-2xl": radius(1.8),
"--a2ui-radius-3xl": radius(2.2),
"--a2ui-radius-4xl": radius(2.6),
};

const GENERATIVE_UI = {
ui: OPENBOT_UI,
theme: OPENBOT_UI_THEME,
} satisfies NonNullable<CopilotKitProviderProps["generativeUI"]>;

/**
* Prop presence is what makes the browser send the catalog, so an unresolved or disabled capability
* must omit it. The server refuses the tool on its own as well; see server/src/copilot.ts.
*/
export function generativeUiProviderOptions(enabled: boolean | undefined) {
return enabled ? { generativeUI: GENERATIVE_UI } : {};
}
41 changes: 0 additions & 41 deletions app/src/lib/copilot/a2ui.tsx

This file was deleted.

5 changes: 2 additions & 3 deletions app/src/lib/copilot/provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import { CopilotKitProvider } from "@copilotkit/react-core/v2";
import { useQuery } from "@tanstack/react-query";
import type { ReactNode } from "react";
import { deploymentCapabilitiesQueryOptions } from "@/lib/deployment/queries";
import { a2uiProviderOptions } from "./a2ui";
import { generativeUiProviderOptions } from "./a2ui";
import { SignInTool } from "./sign-in-tool";
import "./a2ui.css";
import { ActiveBotProvider } from "./active-bot";
import { BotTools } from "./bot-tools";
import { ComputerTools } from "./computer-tools";
Expand Down Expand Up @@ -37,7 +36,7 @@ export function CopilotProvider({ children }: { children: ReactNode }) {
enableInspector={false}
runtimeUrl="/api/copilotkit"
credentials="include"
{...a2uiProviderOptions(capabilities?.generativeUi)}
{...generativeUiProviderOptions(capabilities?.generativeUi)}
/*
* Passed only when this deployment actually has the capability, and this is the load-bearing
* part rather than a tidiness. The SDK reads generative UI as on when EITHER the runtime says
Expand Down
Loading
Loading