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
19 changes: 17 additions & 2 deletions .github/workflows/check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,30 @@ jobs:
compose:
needs: plan
if: needs.plan.result == 'success' && contains(fromJSON(needs.plan.outputs.jobs || '[]'), 'compose')
runs-on: ${{ vars.OAC_USE_GITHUB_RUNNERS == 'true' && 'ubuntu-22.04' || 'blacksmith-2vcpu-ubuntu-2204' }}
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-24.04
architecture: amd64
- runner: ubuntu-24.04-arm
architecture: arm64
runs-on: ${{ matrix.runner }}
env:
GOARCH: ${{ matrix.architecture }}
timeout-minutes: 30
steps:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.ref || github.sha }}
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- name: Test the native Core installation lifecycle
run: go test ./services/core/cmd/oac -count=1 -timeout=3m
- uses: ./.github/actions/e2b-provider
- name: Build and verify the architecture-matched E2B helper
run: bash scripts/build-e2b-provider.sh
- name: Allocate an isolated Compose project
run: python3 -c 'import uuid; print("COMPOSE_SMOKE_PROJECT=oac-smoke-" + uuid.uuid4().hex)' >> "$GITHUB_ENV"
- name: Build the images, start the installation and verify it
Expand Down
22 changes: 22 additions & 0 deletions .github/workflows/native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ jobs:
run: |
go build -ldflags "-X github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/cli.Version=$(git rev-parse HEAD)" -o "$RUNNER_TEMP/oac-daemon${{ runner.os == 'Windows' && '.exe' || '' }}" ./apps/daemon/cmd/oac-daemon
node --test scripts/build-native-installer.test.mjs
- name: Build and test the shared Core installer
run: |
go build -o "$RUNNER_TEMP/oac${{ runner.os == 'Windows' && '.exe' || '' }}" ./services/core/cmd/oac
go test ./services/core/cmd/oac -count=1 -timeout=3m
- name: Exercise the Windows Core launcher
if: runner.os == 'Windows'
shell: pwsh
run: ./deploy/test_install.ps1 -Binary "$env:RUNNER_TEMP/oac.exe"
- name: Verify native download bootstrap and recovery
run: go test ./services/core/internal/nativeinstaller -count=1 -timeout=3m
- name: Native filesystem, authentication and process lifecycle
Expand Down Expand Up @@ -163,3 +171,17 @@ jobs:
path: ${{ runner.temp }}/native-ci-diagnostics/
retention-days: 7
if-no-files-found: ignore

core-intel-mac:
name: Core installer (macOS Intel)
runs-on: macos-15-intel
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.ref || github.sha }}
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
- run: go test ./services/core/cmd/oac -count=1 -timeout=3m
- run: go build -o "$RUNNER_TEMP/oac" ./services/core/cmd/oac
7 changes: 5 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ jobs:
path: ${{ runner.temp }}/native-artifacts
- name: Assemble the native installation catalog
run: node scripts/build-native-catalog.mjs "$RUNNER_TEMP/native-artifacts" "$RUNNER_TEMP/native-installers"
- uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- uses: ./.github/actions/e2b-provider
- name: Build matched artifacts
env:
Expand All @@ -133,8 +136,8 @@ jobs:
for asset in "$HOME/.oac/build/core-distribution/"*; do
if [[ -f "$asset" ]]; then ln "$asset" "$HOME/.oac/build/release-upload/"; fi
done
cp deploy/install.sh "$HOME/.oac/build/release-upload/install.sh"
(cd "$HOME/.oac/build/release-upload" && sha256sum install.sh > install.sh.sha256)
cp deploy/install.sh deploy/install.ps1 "$HOME/.oac/build/release-upload/"
(cd "$HOME/.oac/build/release-upload" && sha256sum install.sh > install.sh.sha256 && sha256sum install.ps1 > install.ps1.sha256)
- name: Sign in to GHCR
if: github.event_name == 'push' || inputs.draft_release
env:
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ check-microsandbox-provider:
.PHONY: check-distribution build-core-distribution
check-distribution:
node --test scripts/build-native-catalog.test.mjs
go test ./services/web -count=1
go test ./services/web ./services/core/cmd/oac -count=1
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s deploy/node -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s deploy/compose -p 'test_*.py'
PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s scripts/acceptance -p 'test_*.py'
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@ Core keeps durable execution state. The Runtime runs the chosen harness inside t

## Install

On a Linux amd64 host with Docker and Python 3.9+:
On Linux or macOS with [Docker configured](https://openagentcore.dev/docs/getting-started/install#prerequisites):

```sh
curl -fsSL https://github.com/MiniMax-AI/OpenAgentCore/releases/latest/download/install.sh | bash
```

Windows PowerShell:

```powershell
irm https://github.com/MiniMax-AI/OpenAgentCore/releases/latest/download/install.ps1 | iex
```

Then:

1. **Sign in to Web**, the admin console, with the Core key the installer created, and **configure the domain and HTTPS**.
Expand Down
8 changes: 7 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,18 @@ OpenAgentCore 在你自己的基础设施上运行 AI Agent,对外提供 [Open

## 安装

在已准备 Docker 和 Python 3.9+ 的 Linux amd64 主机上:
在已按[前置条件](https://openagentcore.dev/zh/docs/getting-started/install#prerequisites)准备 Docker 的 Linux 或 macOS 上:

```sh
curl -fsSL https://github.com/MiniMax-AI/OpenAgentCore/releases/latest/download/install.sh | bash
```

Windows PowerShell:

```powershell
irm https://github.com/MiniMax-AI/OpenAgentCore/releases/latest/download/install.ps1 | iex
```

然后:

1. 用安装器生成的 Core key **登录 Web**(管理控制台),并**配置域名和 HTTPS**。
Expand Down
2 changes: 1 addition & 1 deletion apps/web/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ A failed action whose outcome needs a decision (a sandbox change with no answer,
A local-only installation has the same amber notice on Overview, Nodes and System: other machines cannot connect, followed by Core's configuration path and apply command as copyable values. If Core has no configuration snapshot, state that those instructions are unavailable; never fill in a path or command. Add node is disabled with its reason beside the action, and Getting started leaves its first step to do with the address fix visible. A pending or failed installation read cannot complete that step; a failed read shows Unknown and Retry.

### Onboarding
Signing in and the console tour share one frame: a dark stage on the left (always dark, whatever the theme) and the task panel on the right, which follows the theme. The stage is the product's one authored moment: a flickering indigo dot grid under slow light rays (Magic UI's flickering grid and light rays), Core as the OpenAgentCore mark on a tile with a travelling border beam, and two orbits of Agents, Sessions, Skills, Vaults, files, templates and machines around it; the OpenAgentCore mark is itself nodes on a ring. Brand copy sits bottom-left in solid ink; it is a paragraph, not a heading, because the panel's title names the task. Signing in asks for one thing, the deployment's Core key, in a single password field; the default key location and a copyable read command stay visible beneath it, with a reminder to substitute a custom installation directory. The key’s authority stays in a help tip. A refused key, too many attempts or an unavailable console is an error beside the field. Signing in opens the console on the Overview. The optional tour has three chapters — Monitor, Resources, Platform — whose stage shows a real dark screenshot of those pages, tilted towards the panel; it takes the place of the console until its last button, Skip or Escape, and then returns the focus to the control that opened it. Entering the console or the tour, and leaving the tour, happen inside a View Transition: the old page dissolves forward and the new one is revealed in a circle growing from the pressed button. With reduced motion the orbits hold their places, the grid is a still frame and no transition runs.
Signing in and the console tour share one frame: a dark stage on the left (always dark, whatever the theme) and the task panel on the right, which follows the theme. The stage is the product's one authored moment: a flickering indigo dot grid under slow light rays (Magic UI's flickering grid and light rays), Core as the OpenAgentCore mark on a tile with a travelling border beam, and two orbits of Agents, Sessions, Skills, Vaults, files, templates and machines around it; the OpenAgentCore mark is itself nodes on a ring. Brand copy sits bottom-left in solid ink; it is a paragraph, not a heading, because the panel's title names the task. Signing in asks for one thing, the deployment's Core key, in a single password field; a copyable Docker Compose command to read the key stays visible beneath it, with a reminder to substitute a custom installation directory. The key’s authority stays in a help tip. A refused key, too many attempts or an unavailable console is an error beside the field. Signing in opens the console on the Overview. The optional tour has three chapters — Monitor, Resources, Platform — whose stage shows a real dark screenshot of those pages, tilted towards the panel; it takes the place of the console until its last button, Skip or Escape, and then returns the focus to the control that opened it. Entering the console or the tour, and leaving the tour, happen inside a View Transition: the old page dissolves forward and the new one is revealed in a circle growing from the pressed button. With reduced motion the orbits hold their places, the grid is a still frame and no transition runs.

### Getting started
The first card on the Overview while any step is to do: a card header ("Getting started", "n of 4 done", a help tip, then a ghost Take the tour button and an icon button that hides it) over four rows split by Faint Rules. Each row has a 22px numbered ring (a check on the tile wash when done), a 13px/600 title over one 12.5px Graphite line, a status dot (Done in green, To do in Pencil, Checking pending, Unknown for a failed read) and one outline action while the step is to do: Set up sandboxes, Add node, Open Nodes or Open sandbox backend; Open System; Create project (which continues to the new project's first key) or Issue key; See how to call (the newest active project, preferring one with an active key), or Projects and keys without an active project. Add node, Create project and Issue key open their page with the dialog already open; Open System brings the Default model provider section to the top of the page body and focuses the default harness's Set or Replace; See how to call opens the project and, once its keys, usage and address are read, brings its How to call heading to the top of the page body, focused. Only the page body scrolls; the page header stays. Every step done turns it into one line, "You're set", with Take the tour and Dismiss; it stays, through the tour, until dismissed, and the checklist does not come back on its own. The choice is kept per installation in the browser, also while the deployment cannot be read; Show Getting started, a quiet row above the sidebar's account controls, opens it again at any time.
Expand Down
2 changes: 1 addition & 1 deletion apps/web/PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ The console runs beside the administrator's own Core, with execution, files and

## Operating Context

- Paired console (`services/web`): the administrator signs in with the deployment's Core key, the administration credential the installer writes to `secrets/core.key` under the installation directory (by default `~/.oac/core/secrets/core.key`; keeping and rotating it is described in [Core key](../../docs/getting-started/operations.md#core-key)). There are no console accounts or usernames. Sign-in shows the default file location and a copyable `cat ~/.oac/core/secrets/core.key` command for the Core host, with a reminder to substitute a custom installation directory. The browser sends the key only to sign in and keeps only the session cookie; the console server holds the Core key and forwards the Web API (`/core/v1/**`, including sandbox administration under `/core/v1/sandbox/**`). The console never calls `/v1`.
- Paired console (`services/web`): the administrator signs in with the deployment's [Core key](../../docs/getting-started/operations.md#core-key). Sign-in shows a copyable Docker Compose command to read the key on the Core host, with a reminder to substitute a custom installation directory. The browser sends the key only to sign in and keeps only the session cookie; the console server holds the Core key and forwards the Web API (`/core/v1/**`, including sandbox administration under `/core/v1/sandbox/**`). The console never calls `/v1`.
- The Core key is not an Agents API identity and cannot call `/v1`. An administrator who wants to call the Agents API issues a project API key like any other caller.
- `/console/config` reports the node installer (`node_installer`, `node_installer_sha256`), offered only with a 64-hex digest. Native self-hosted installation does not depend on this endpoint. It also lists the providers it has node files for (`node_artifacts`); without the deployment's provider, Add node says so and issues no command. Signing in grants administration, sandbox administration included.
- Chinese and English UI; light and dark themes; reduced motion honored.
Expand Down
4 changes: 2 additions & 2 deletions apps/web/e2e/access.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ test("signs in with the Core key, keeps it out of the browser, and signs out and
await page.goto("/");

await expect(page.getByRole("heading", { name: "Sign in to OpenAgentCore" })).toBeVisible();
await expect(page.getByText("cat ~/.oac/core/secrets/core.key", { exact: true })).toBeVisible();
await expect(page.getByText('docker compose -f "$HOME/.oac/core/compose.yaml" exec -T web oac-web core-key', { exact: true })).toBeVisible();
await expect(page.getByText("For a custom installation directory, replace the path in this command.")).toBeVisible();
await page.context().grantPermissions(["clipboard-read", "clipboard-write"]);
await page.getByRole("button", { name: "Copy key read command" }).click();
expect(await page.evaluate(() => navigator.clipboard.readText())).toBe("cat ~/.oac/core/secrets/core.key");
expect(await page.evaluate(() => navigator.clipboard.readText())).toBe('docker compose -f "$HOME/.oac/core/compose.yaml" exec -T web oac-web core-key');
await signIn(page, "not-the-core-key");
await expect(page.getByRole("alert")).toHaveText("This Core key is not correct. Check it and try again.");
await signIn(page, FIXTURE_CORE_KEY);
Expand Down
11 changes: 2 additions & 9 deletions apps/web/src/features/first-run/ConsoleAccess.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,6 @@ import { withTransition } from "../onboarding/view-transition";
import { changeConsoleAuth, ConsoleAuthError, readConsoleAuth, type ConsoleAuth } from "./auth";
import "./console-access.css";

/**
* Where the installer writes the Core key: its file inside the installation
* directory, and that file under the default installation directory. The
* visible sign-in instructions name both; the actual custom path is not public.
*/
const CORE_KEY_LOCATION = { file: "secrets/core.key", defaultPath: "~/.oac/core/secrets/core.key" } as const;

const ConsoleAccountContext = createContext<{ logout: () => Promise<void> } | null>(null);
export const useConsoleAccount = () => useContext(ConsoleAccountContext);

Expand Down Expand Up @@ -146,8 +139,8 @@ function CoreKeyForm({ onAuthenticated }: {
readOnly={busy} aria-invalid={error ? true : undefined} aria-describedby={`${id}-location${error ? ` ${id}-error` : ""}`} />
</div>
<div className="console-key-location" id={`${id}-location`}>
<p>{t("The installer saved the key in {{file}} inside the installation directory. On the Core host, read the default location with:", CORE_KEY_LOCATION)}</p>
<CopyableId id={`cat ${CORE_KEY_LOCATION.defaultPath}`} label={t("Copy key read command")} />
<p>{t("On the Core host, run this command to read the Core key:")}</p>
<CopyableId id={'docker compose -f "$HOME/.oac/core/compose.yaml" exec -T web oac-web core-key'} label={t("Copy key read command")} />
<p>{t("For a custom installation directory, replace the path in this command.")}</p>
</div>
{error ? <p className="console-auth-error" id={`${id}-error`} role="alert">{error}</p> : null}
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/i18n/locales/en/core-errors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const coreErrors = {
"invalid_admin_key": "The console's Core key was rejected. Update secrets/core.key on the Core host and run oac apply.",
"invalid_admin_key": "The console's Core key was rejected. Rotate it on the Core host, then sign in again.",
"console_sign_in_required": "Sign in to the console again.",
"console_origin_rejected": "Open the console at its configured address.",
"console_request_invalid": "The console request was rejected. Reload the page.",
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/i18n/locales/zh-CN/core-errors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const coreErrors = {
"invalid_admin_key": "控制台的 Core Key 被拒绝。请更新 Core 主机上的 secrets/core.key,再运行 oac apply。",
"invalid_admin_key": "控制台的 Core Key 被拒绝。请在 Core 主机上轮换密钥,然后重新登录。",
"console_sign_in_required": "请重新登录控制台。",
"console_origin_rejected": "请通过配置的地址打开控制台。",
"console_request_invalid": "控制台请求被拒绝,请重新加载页面。",
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/lib/console-auth-strings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ export const consoleAuthChinese = {
"Core key": "Core Key",
"The Core key is an administration credential: it cannot call the /v1 Agents API, and the console never keeps it in your browser.":
"Core Key 是管理凭据:不能调用 /v1 Agents API,控制台也不会把它保存在你的浏览器里。",
"The installer saved the key in {{file}} inside the installation directory. On the Core host, read the default location with:":
"安装器将 key 保存在安装目录下的 {{file}} 中。在 Core 主机上运行以下命令可读取默认位置:",
"On the Core host, run this command to read the Core key:":
"在 Core 主机上运行以下命令,读取 Core Key:",
"Copy key read command": "复制 key 读取命令",
"For a custom installation directory, replace the path in this command.": "如果使用了自定义安装目录,请替换命令中的路径。",
"Sign in": "登录",
Expand Down
Loading
Loading