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
15 changes: 13 additions & 2 deletions .github/workflows/native.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ on:
- 'packages/tsconfig/**'
- 'scripts/build-native-installer*'
- 'scripts/native-harness-smoke.mjs'
- 'scripts/native-onboarding-smoke.mjs'
- 'services/agents-api/internal/nativeinstaller/**'
- 'scripts/build-mcode-harness.sh'
- 'go.mod'
- 'go.sum'
Expand All @@ -23,12 +25,17 @@ on:
- '.npmrc'
- '.github/workflows/native.yml'
workflow_dispatch:
workflow_call:
inputs:
ref:
type: string
required: true

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
group: native-check-${{ github.ref }}
cancel-in-progress: true

jobs:
Expand All @@ -44,6 +51,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v7
with:
ref: ${{ inputs.ref || github.sha }}
- uses: actions/setup-go@v7
with:
go-version-file: go.mod
Expand All @@ -52,7 +61,7 @@ jobs:
node-version: '22.22.0'
- name: Build the native daemon and test bundle boundaries
run: |
go build -ldflags "-X github.com/MiniMax-AI-Dev/parsar/apps/parsar-daemon/internal/cli.Version=$GITHUB_SHA" -o "$RUNNER_TEMP/oac-daemon${{ runner.os == 'Windows' && '.exe' || '' }}" ./apps/parsar-daemon/cmd/parsar-daemon
go build -ldflags "-X github.com/MiniMax-AI-Dev/parsar/apps/parsar-daemon/internal/cli.Version=$(git rev-parse HEAD)" -o "$RUNNER_TEMP/oac-daemon${{ runner.os == 'Windows' && '.exe' || '' }}" ./apps/parsar-daemon/cmd/parsar-daemon
node --test scripts/build-native-installer.test.mjs
- name: Native filesystem, authentication and process lifecycle
run: >-
Expand Down Expand Up @@ -116,6 +125,8 @@ jobs:
export CLAUDE_CODE_GIT_BASH_PATH='C:\Program Files\Git\bin\bash.exe'
fi
node scripts/build-native-installer-ci.mjs
- name: Bootstrap, authenticate, install and connect natively
run: node scripts/native-onboarding-smoke.mjs
- name: Verify native Harness protocols without model requests
run: |
if [[ "$RUNNER_OS" == Windows ]]; then
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@ jobs:
with:
ref: ${{ inputs.ref || github.sha }}

native:
uses: ./.github/workflows/native.yml
with:
ref: ${{ inputs.ref || github.sha }}

build:
needs: native
runs-on: ubuntu-22.04
timeout-minutes: 120
outputs:
Expand Down Expand Up @@ -92,8 +98,16 @@ jobs:
run: |
PYTHONDONTWRITEBYTECODE=1 python3 scripts/core-distribution-manifest.test.py
bash scripts/prepare-release-runtimes.sh
- uses: actions/download-artifact@v6
with:
pattern: oac-native-installer-*
merge-multiple: true
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"
- name: Build matched artifacts
env:
OAC_NATIVE_INSTALLER_BUILD_DIR: ${{ runner.temp }}/native-installers
RELEASE_REVISION: ${{ steps.source.outputs.revision }}
RELEASE_TAG: ${{ steps.source.outputs.release_tag }}
RELEASE_REPOSITORY: ${{ github.repository }}
Expand Down
19 changes: 17 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ existing ownership boundary rather than adding unrelated responsibilities.

The [API documentation index](docs/api/README.md) lists the three namespaces:
`/v1` for applications (Project API key), `/core/v1` for Core Web's server and
operator scripts (Core key) and `/api/v1` for machine connections (credentials
issued through `/core/v1`). New or changed routes must identify their caller and
operator scripts (Core key) and `/api/v1` for machine connections (executor credentials issued through `/core/v1`
or claimed using a short-lived Session installation authorization). New or changed routes must identify their caller and
credential there, and link their detailed contract.
Keep current integration guidance separate from historical qualification evidence.

Expand Down Expand Up @@ -3773,6 +3773,21 @@ The release bundles pinned Node/npm, native Harnesses and required adapter asset
registration lives in CLI and native activation/readiness in each adapter's optional
`agent.Installation` descriptor. Core never selects native paths or OS-specific
installation steps. See [native installation](docs/self-hosted-native.md).
Self-hosted onboarding extends authenticated Session creation/detail responses with
`x_agents_core.installation`; Web displays the same Core-produced commands. Lists
and durable event journals never retain installation authorizations. The command
uses a 30-minute, Environment- and build-scoped grant to claim one connect-only
credential. The installer persists its generated secret before claiming it; retries
must prove that same secret. Reserve the Environment UUID as the onboarding key ID.
Existing, rotated or revoked credentials are never replaced by onboarding. Machine
bootstrap routes use this grant, not an Environment ID as authentication. Public
artifact routes contain no credentials. Native bundles must match the Core source
revision and Runtime wire version. Core release qualification consumes the same
three-platform native CI artifacts and includes them in its distribution.
Bootstrap scripts own platform download/extraction only; installation, startup,
connection verification and Runtime execution remain common. Serialize background
PID inspection and publication so concurrent starts cannot create duplicate daemons.

An installed daemon discovers and registers only the adapter kinds named by its
verified installation manifest. The host PATH stays available to tools; its other
Harness executables and activation variables cannot extend that installation.
Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/docs/api-reference/core/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Operator scripts use Core’s loopback port. The public entry routes management
- [agents](/api-reference/core/agents)
- [environment-templates](/api-reference/core/environment-templates)
- [executor-credentials](/api-reference/core/executor-credentials)
- [native-installation](/api-reference/core/native-installation)
- [files](/api-reference/core/files)
- [write-audit](/api-reference/core/write-audit)
- [sessions](/api-reference/core/sessions)
Expand Down
1 change: 1 addition & 0 deletions apps/docs/content/docs/api-reference/core/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"agents",
"environment-templates",
"executor-credentials",
"native-installation",
"files",
"write-audit",
"sessions",
Expand Down
23 changes: 23 additions & 0 deletions apps/docs/content/docs/api-reference/core/native-installation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
title: Native Installation
description: >-
Native Installation. Core administration API: Core key held by Web’s server or
an operator script. Generated local management contract. This is not part of
the public OpenAI API.
full: true
_openapi:
method: GET
route: /core/v1/projects/{project_id}/environments/{environment_id}/installation
toc: []
structuredData:
headings: []
contents:
- content: >-
Core key only. The commands contain a 30-minute installation
authorization, never an executor secret. Web displays these same
commands provided in public Session creation and detail responses.
---

{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}

<APIPage document={"core-api"} operations={[{"path":"/core/v1/projects/{project_id}/environments/{environment_id}/installation","method":"get"}]} webhooks={[]} hasHead={true} />
1 change: 1 addition & 0 deletions apps/docs/content/docs/api-reference/machine/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ This schema covers node configuration, enrollment and identity. Daemon WebSocket

[API namespaces and credentials](/public-api) · [Application reference](/api-reference) · [Administration reference](/api-reference/core) · [Machine reference](/api-reference/machine)

- [native-installation](/api-reference/machine/native-installation)
- [sandbox-node](/api-reference/machine/sandbox-node)
1 change: 1 addition & 0 deletions apps/docs/content/docs/api-reference/machine/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"title": "Machine connection API",
"pages": [
"index",
"native-installation",
"sandbox-node"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Native Installation
description: >-
Native Installation. Machine connection API: Route-specific node enrollment,
node, daemon, or executor credential. Generated local machine contract. These
connections reach Core directly, never through Web.
full: true
_openapi:
toc: []
structuredData:
headings: []
contents:
- content: >-
Accepts a short-lived Environment installation Bearer authorization,
not a Project or Core key. Returns frozen connection constraints; it
does not claim or rotate credentials.
- content: >-
A valid installation Bearer authorization can claim one connect-only
key. The client persists its generated secret before submitting it.
Retries must present that same secret; a different, rotated or revoked
credential is never replaced.
---

{/* This file was generated by Fumadocs. Do not edit this file directly. Any changes should be made by running the generation command again. */}

<APIPage document={"runtime-api"} operations={[{"path":"/api/v1/agent-daemon/installation","method":"post"},{"path":"/api/v1/agent-daemon/installation/claim","method":"post"}]} webhooks={[]} hasHead={true} />
8 changes: 8 additions & 0 deletions apps/docs/content/docs/configure.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -269,4 +269,12 @@ paths must be canonical absolute paths without control characters, quotes, backs
or wildcards. Keep the installation ID and the database together; Core refuses a
missing installation ID when its database already has a deployment.

### Native daemon distributions

Release Core images include matched self-hosted installers. A standalone Core
process can set `OAC_NATIVE_INSTALLER_DIR` to the release's `native-installers`
directory. Core checks the catalog's source revision, Runtime protocol and archive
checksums before serving it. This setting supplies installation artifacts only;
it does not change Runtime preparation, permissions or execution.

[Repository source](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/docs/configuration.md)
20 changes: 16 additions & 4 deletions apps/docs/content/docs/public-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ title: "API namespaces and credentials"
description: "The public application API, private administration API and machine connection interface."
---

Core serves three namespaces. Each has one kind of caller and its own credential;
no credential works in another namespace.
Core serves three namespaces. Protected operations authenticate their own callers;
credentials cannot be substituted across these boundaries. Versioned native
installer downloads are public release content.

| Namespace | Caller | Credential | Contents | Reference |
| --- | --- | --- | --- | --- |
| `/v1` | Applications (business systems, SDKs) | Project API key | Exactly the pinned official Agents API routes. Core-only fields live only in `x_agents_core` (`harness`, `model_provider`) | [Public API](/sessions) |
| `/v1` | Applications (business systems, SDKs) | Project API key | Exactly the pinned official Agents API routes. Core-only fields live only in `x_agents_core` (`harness`, `model_provider`, Session `installation`) | [Public API](/sessions) |
| `/core/v1` | Core Web's server and operator scripts | [Core key](/troubleshooting#core-key) | Installation facts, Projects and keys, resource reads and deletion, Session archive, credential issuance, metrics, audit, sandbox deployment and nodes, deployment model providers | [Core API](#core-api), [Web API](/admin-api), [Core OpenAPI](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/core.openapi.yaml) |
| `/api/v1` | Nodes, Runtime daemons, self-hosted executors | Machine credentials: node enrollment tokens and executor credentials issued through `/core/v1`, node credentials registered with an enrollment token, and daemon credentials Core writes into hosted sandboxes | Machine connections only: `/api/v1/sandbox-node/*` and `/api/v1/agent-daemon/*`, including WebSockets; each credential works only on its own routes | [Node operations](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/services/agents-api/HOSTED-SANDBOX-MANAGER.md#register-a-host), [executor credentials](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/environment-executor-credentials.md), [machine OpenAPI](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/runtime.openapi.yaml) |
| `/api/v1` | Nodes, Runtime daemons, self-hosted executors | Machine credentials: short-lived Session installation grants, node enrollment tokens and executor credentials issued through `/core/v1` or claimed by installation, node credentials registered with an enrollment token, and daemon credentials Core writes into hosted sandboxes | Machine bootstrap and connections: `/api/v1/sandbox-node/*` and `/api/v1/agent-daemon/*`, including WebSockets; each credential works only on its own routes | [Node operations](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/services/agents-api/HOSTED-SANDBOX-MANAGER.md#register-a-host), [executor credentials](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/environment-executor-credentials.md), [machine OpenAPI](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/runtime.openapi.yaml) |

A Project API key gets 401 on `/core/v1` and `/api/v1`; the Core key gets 401 on
`/v1` and `/api/v1`. Projects own assets. Multiple equally privileged keys share
Expand Down Expand Up @@ -103,4 +104,15 @@ Core administration failures use the [Core error envelope](https://github.com/Mi
including typed optional safe details and distinct console proxy rejection codes.
The public and machine error contracts remain unchanged.

### Self-hosted installation

Authenticated Session creation/detail responses include short-lived commands in
`x_agents_core.installation`. Core Web reads the same commands at
`GET /core/v1/projects/{project_id}/environments/{environment_id}/installation`.
Machine installers use `POST /api/v1/agent-daemon/installation` and its `/claim`
subroute with the installation Bearer authorization. Qualified artifacts beneath
`/api/v1/agent-daemon/install/{version}/` are public, immutable release content.
See [native self-hosted installation](/self-hosted-native) for expiry, retry,
credential ownership and platform rules.

[Repository source](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/docs/api/README.md)
59 changes: 21 additions & 38 deletions apps/docs/content/docs/self-hosted-execution.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ description: "Connect a user-owned Runtime to its Environment with a restricted
---

A `self_hosted` Session runs on a machine the application owns. The application
creates the Session through `/v1`; the administrator issues an executor credential
in Web or through `/core/v1`; the host runs `oac-daemon` with that credential.
creates the Session through `/v1` and receives a command that installs and connects
`oac-daemon`. Web displays the same command in the Session; it is optional.
Linux, macOS and Windows use the same Runtime protocol. Core-managed Providers
remain Linux-only.

Expand All @@ -23,8 +23,8 @@ Otherwise creation fails with 400 `model_provider_required`.

## Connect a host

1. Create an existing workspace on the executor host. The application creates a
Session using that host's absolute path and its own Project API key:
1. Choose an absolute workspace path on the target host. Create a Session with
that path and the application's Project API key:

```python
import os
Expand All @@ -45,23 +45,20 @@ Otherwise creation fails with 400 `model_provider_required`.
}},
},
)
print(session.id, session.environment.id, session.environment.remote_url)
installation = session.model_dump()["x_agents_core"]["installation"]
print(installation["commands"]["posix"]) # use "powershell" for Windows
```

2. In Web, open **Session log**, then the Session's **Executor credentials**
section. Choose **Issue credential**, then **Download credential file**. Core
returns the credential only once; retain it privately before choosing **Done**.
3. Extract the native distribution and run `oac-daemon install --interactive`
(or supply all options with `--non-interactive --harness`). Use the returned
remote URL, Environment ID, matching workspace and credential file path, then
start the installed `bin/oac-daemon`.
The [native guide](/self-hosted-native#install-and-start) has Linux/macOS and
PowerShell examples. No Docker installation is required for this native path.

The console's **Connect a host** flow provides native installation guidance and
the executor credential download. Obtain the matching native distribution before
running its command. Core must be reachable from the host: `wss://` is required
outside loopback, while a local Core can use a loopback `ws://` URL.
2. Run the returned command on the target machine. Select the Harnesses and
installation directory when prompted. Installation creates the workspace if
needed, starts the daemon and checks its connection. For automation, append
`--non-interactive --harness codex` and optionally `--install-dir ABS`.

In Web, open the **Self-hosted** Session and copy the command under **Connect a
host**. A command expires after 30 minutes; fetch the Session again for a fresh
one. The [native guide](/self-hosted-native#install-and-connect) covers retry,
platform prerequisites and credential storage. Core must be reachable from the
host with TLS outside loopback. Native installation does not require Docker.

A connected Environment proves only the machine connection. Send a Turn to check
the selected harness and model. Core supplies the Session's model provider over
Expand Down Expand Up @@ -122,26 +119,12 @@ Stopping the daemon keeps its workspace and native history. Deleting a Session
does not remove host files. In an archived Project, credentials cannot be issued
or rotated; revocation remains available.

## Without Web

Scripts on the Core host can issue credentials with the Core key through Core's
loopback port (`ports.core` in `config.json`, 8091 by default). Choose a new UUID for
the credential and keep it:

```sh
key_id=$(python3 -c 'import uuid; print(uuid.uuid4())'); echo "credential ID: $key_id"
(umask 077; curl -fsS -X POST \
-H @<(printf 'Authorization: Bearer %s\n' "$(cat "$HOME/.oac/core/secrets/core.key")") \
-H 'Content-Type: application/json' -d "{\"key_id\":\"$key_id\"}" \
"http://127.0.0.1:8091/core/v1/projects/$PROJECT_ID/environments/$ENVIRONMENT_ID/executor-credentials" \
-o executor-key.json)
```
## Operator credential management

Rotate with `{"key_id":"…","rotate":true}` on the same route; revoke with
`DELETE …/executor-credentials/<key_id>`. After an uncertain response, list the
credentials with `GET` before trying again. The
[credential contract](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/environment-executor-credentials.md)
has every rule and error.
Operators can still issue, rotate or revoke executor credentials using a Core key
through Core's loopback port. This is not required for one-command onboarding.
See the [credential contract](https://github.com/MiniMax-AI/parsar-core/blob/e4d5a1d30520a967b3a44a257ed1b6c21e388388/contracts/agents-api/environment-executor-credentials.md)
for those routes and uncertain-response handling.

## Historical executor installations

Expand Down
Loading
Loading