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
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ jobs:
path: |
~/.npm/_cacache
~/.oac/cache/microsandbox-v0.7.2-linux-x86_64.tar.gz
key: release-downloads-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('scripts/prepare-release-runtimes.sh', 'packages/mcode-harness/source.json', 'scripts/core-distribution-manifest.py') }}
key: release-downloads-v1-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('scripts/prepare-release-runtimes.sh', 'internal/harnessconfig/builtin/catalog.json', 'packages/mcode-harness/source.json', 'scripts/core-distribution-manifest.py') }}
restore-keys: |
release-downloads-v1-${{ runner.os }}-${{ runner.arch }}-
- name: Check release metadata and prepare pinned harnesses
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This guide owns how to work in the repository: documentation ownership, the repo
| Core service setup, tests and generation | [Core service guide](services/core/README.md) |
| Core implementation constraints beyond the public contracts | [Implementation constraints](services/core/IMPLEMENTATION.md) |
| Environment ownership, preparation, Skills, Plugins, packages and MCP bindings | [Environments](contracts/agents-api/environments.md) |
| Built-in Harness identifiers and display names | `internal/harnessconfig/builtin/catalog.json` and its [generated reference](contracts/agents-api/harness-catalog.md) |
| Built-in Harness identifiers, display names and version pins | `internal/harnessconfig/builtin/catalog.json` and its [generated reference](contracts/agents-api/harness-catalog.md) |
| Harness registration, support declaration and acceptance | [Harness onboarding](contracts/agents-api/harness-onboarding.md) |
| Harness selection, model providers and native parameters | [Model execution](contracts/agents-api/model-execution.md) |
| Provider registration and lifecycle | [Sandbox Provider guide](docs/sandbox-provider.md) |
Expand Down Expand Up @@ -113,7 +113,7 @@ The role needs `CREATE DATABASE`: tests of database-wide state, such as the exec

### Contract and schema rules

- `internal/harnessconfig/builtin/catalog.json` is the single authored public Harness registration list. `make generate-harness-catalog` generates Go configuration/profile registration, client identifiers/names and the reference, and projects the model-provider protocol names of `internal/modelprovider/config.go` to the client; `make openapi` derives the matching enums. `make check-harness-catalog` verifies freshness in the full gate. Native configuration rules stay in their adapter declarations; Core qualification and Runtime availability stay separate.
- `internal/harnessconfig/builtin/catalog.json` owns public Harness registration and native version pins. `make generate-harness-catalog` generates Go configuration and agent-host registration, version pin projections, client identifiers/names and the reference, and projects the model-provider protocol names of `internal/modelprovider/config.go` to the client; `make openapi` derives the matching enums. [Harness onboarding](contracts/agents-api/harness-onboarding.md#native-version-pins) owns native package and source projection rules. `make check-harness-catalog` verifies freshness in the full gate. Native configuration rules stay in their adapter declarations; Core qualification and Runtime availability stay separate.
- `make sqlc-generate` owns only `services/core/internal/db/sqlc` (sqlc v1.29.0). Do not rewrite landed migrations.
- `make check-runtime-contract` is the focused Core–Runtime contract entry point; see [Contract verification](docs/runtime-protocol.md#contract-verification). It also runs through `check-go` and `check-core`.

Expand Down
4 changes: 3 additions & 1 deletion apps/daemon/internal/agent/codex/recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import (
"errors"
"path/filepath"
"strings"

configuration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/codex"
)

func SupportsNativeSessionRecovery(version string) bool {
return strings.TrimSpace(version) == "codex-cli 0.153.4"
return strings.TrimSpace(version) == "codex-cli "+configuration.NativeVersion
}

func (s *Session) recoverRoot(plan SessionPlan) (string, error) {
Expand Down
2 changes: 1 addition & 1 deletion apps/daemon/internal/agent/mcode/declaration.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func discoverWithCheck(parent context.Context, options agent.DiscoveryOptions, i
defer cancel()
version, err := check(ctx, "")
if err != nil {
fmt.Fprintf(options.Stderr, "oac-daemon: mcode unavailable: %v\n Install: npm install -g @minimax-ai/code@0.4.12\n", err)
fmt.Fprintf(options.Stderr, "oac-daemon: mcode unavailable: %v\n", err)
return runtime
}
runtime.Info.Available, runtime.Info.Version = true, version
Expand Down
3 changes: 2 additions & 1 deletion apps/daemon/internal/agent/mcode/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import (

"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/binpath"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/versionprobe"
configuration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/mcode"
)

var ErrCLINotFound = errors.New("mcode CLI not found")

const SupportedVersion = "0.4.12"
const SupportedVersion = configuration.NativeVersion

func defaultBinary() string { return binpath.MCode() }

Expand Down
7 changes: 1 addition & 6 deletions apps/daemon/internal/cli/agent_host_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ import (
"golang.org/x/sys/unix"

"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/claudesdk"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/codex"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/mcode"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agenthost"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/daemonize"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/dispatch"
Expand Down Expand Up @@ -50,8 +47,6 @@ const (
// agentHostUIDs is the range the agent host runs its Executors as.
var agentHostUIDs = agenthost.UIDRange{First: 70000, Count: 4096}

var harnessDeclarations = []agent.Declaration{codex.Declaration, mcode.Declaration, claudesdk.Declaration}

func runAgentHost(rc *runContext, args []string) error {
return serveAgentHost(context.Background(), rc, args, harnessDeclarations)
}
Expand Down Expand Up @@ -99,7 +94,7 @@ func serveAgentHost(parent context.Context, rc *runContext, args []string, decla
ctx, cancel := daemonize.NotifyContext(parent)
defer cancel()

env, err := agent.ManifestEnvironment(agentHostManifest, claudesdk.Installation(), codex.Installation(), mcode.Installation())
env, err := agent.ManifestEnvironment(agentHostManifest, harnessInstallations...)
if err != nil {
return fmt.Errorf("agent-host: %w", err)
}
Expand Down
14 changes: 14 additions & 0 deletions apps/daemon/internal/cli/harness_catalog_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions contracts/agents-api/harness-catalog.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[//]: # (Generated by scripts/generate-harness-catalog.py; DO NOT EDIT.)
# Built-in Harness registrations

The authored registration list is [`catalog.json`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/builtin/catalog.json). Change it and run `make generate-harness-catalog`; `make check-harness-catalog` checks the generated projections.
The authored registration list and Harness version pins are [`catalog.json`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/builtin/catalog.json). Change it and run `make generate-harness-catalog`; `make check-harness-catalog` checks the generated projections.

| Identifier | Display name | Declaration |
| --- | --- | --- |
| `claude_sdk` | Claude Code | `claudesdk.Configuration` |
| `codex` | Codex | `codex.Configuration` |
| `mcode` | MiniMax Code | `mcode.Configuration` |
| Identifier | Display name | Version | Declaration |
| --- | --- | --- | --- |
| `claude_sdk` | Claude Code | `0.3.269` | `claudesdk.Configuration` |
| `codex` | Codex | `0.153.4` | `codex.Configuration` |
| `mcode` | MiniMax Code | `0.4.12` | `mcode.Configuration` |

Each declaration in `internal/harnessconfig/<package>` states the Harness's model providers and its support, the only source Core and the Runtime admit a selection against. These registrations describe the build. Which Harnesses a deployment enables is the `core.harnesses` [process setting](../../docs/configuration.md#settings), and a connected Runtime reports its own availability. [Harness onboarding](./harness-onboarding.md) describes the adapter and packaging steps.
24 changes: 16 additions & 8 deletions contracts/agents-api/harness-onboarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ Runtime: Executor preparation, reuse, idle expiry, recovery
| Adapter | Native configuration, resources, API calls, event translation and restrictions | `apps/daemon/internal/agent/<kind>` |
| Harness | Native model and tool loop and history | Pinned SDK or executable |
| Declaration | The Harness's support, against which Core and the Runtime admit each selection | `internal/harnessconfig/<kind>` |
| Registration | Adapter declarations, installed views and the installation's narrowed support | `apps/daemon/internal/agent/<kind>/declaration.go`; static list in `apps/daemon/internal/cli/agent_host_linux.go` |
| Registration | Adapter declarations, installed views and the installation's narrowed support | `apps/daemon/internal/agent/<kind>/declaration.go`; catalog-generated list in `apps/daemon/internal/cli/harness_catalog_linux.go` |

An Environment supplies execution resources. Managed E2B, Docker and microsandbox machines and application-owned machines differ in provisioning and connection; each serves the sandbox to the Linux agent host, which runs every Harness in a [view](#run-in-an-agent-host-view) of it under this same contract. Native factories receive capabilities only after the Runtime has loaded the bound installed snapshot ([capability preparation](./environments.md#runtime-capability-preparation)). Model providers supply model communication settings, not Turn scheduling or native process ownership.

## Steps

1. **Pin the native source.** Record the upstream package version and source revision and document the native entry point next to the adapter.
1. **Pin the native source.** Add the upstream package version to the [Harness catalog](./harness-catalog.md), keep any source revision in one authored owner ([native version pins](#native-version-pins)), and document the native entry point next to the adapter.
2. **Implement the adapter** in `apps/daemon/internal/agent/<kind>`: a view whose `ViewExecutorFactory` prepares an `Executor`, and a `Turn` ([required interfaces](#required-adapter-interfaces), [lifetimes](#executor-and-turn-lifetimes), [view](#run-in-an-agent-host-view)). Reuse the shared process, credential and configuration helpers.
3. **Declare its support and register it.** Declare the support in `internal/harnessconfig/<kind>` with one catalog entry ([declare support](#declare-support)), then declare the kind in the adapter and add it to the agent host's static list in `apps/daemon/internal/cli/agent_host_linux.go` ([register the adapter](#register-the-adapter)).
4. **Package native prerequisites.** Supply the adapter's installation and add the Harness to the agent-host image ([native installer participation](#native-installer-participation)).
3. **Declare its support and register it.** Declare the support in `internal/harnessconfig/<kind>` with one catalog entry ([declare support](#declare-support)), then export the adapter declaration for generated agent-host registration ([register the adapter](#register-the-adapter)).
4. **Package native prerequisites.** Supply the adapter's installation and add the Harness to the agent-host image ([native Harness packaging](#native-harness-packaging)).
5. **Enable and select the engine** with the `core.harnesses` setting and [Harness selection](./model-execution.md#harness-selection).
6. **Qualify it** ([qualify the adapter](#qualify-the-adapter)) and record each native difference in the [coverage ledger](./index.md).

Expand Down Expand Up @@ -147,7 +147,7 @@ A Harness that supports the Subagent reads implements the [neutral observation c

## Register the adapter

Registration is static and requires a build. Export one `agent.Declaration` from `apps/daemon/internal/agent/<kind>/declaration.go`, then add it to `harnessDeclarations` in [`cli/agent_host_linux.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/apps/daemon/internal/cli/agent_host_linux.go). The declaration contains the kind with the capabilities of the shared model `Configuration`'s declaration, that `Configuration` and a `Discover` function. Discovery receives the diagnostic writers, owns native configuration and availability checks, and returns the installed `agent.Runtime` with its descriptor and view declaration. Return nil when the adapter is not configured; return an unavailable descriptor without a view when configured prerequisites fail. Keep version gates and view-selection conditions inside the adapter; they only clear support.
Registration is static and requires a build. Export one `agent.Declaration` from `apps/daemon/internal/agent/<configuration>/declaration.go`. `make generate-harness-catalog` generates the agent host's declaration and `Installation()` lists in `apps/daemon/internal/cli/harness_catalog_linux.go` from each catalog entry's `configuration` package. The declaration contains the kind with the capabilities of the shared model `Configuration`'s declaration, that `Configuration` and a `Discover` function. Discovery receives the diagnostic writers, owns native configuration and availability checks, and returns the installed `agent.Runtime` with its descriptor and view declaration. Return nil when the adapter is not configured; return an unavailable descriptor without a view when configured prerequisites fail. Keep version gates and view-selection conditions inside the adapter; they only clear support.

[`cli/agent_host_linux.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/apps/daemon/internal/cli/agent_host_linux.go) registers each discovered Runtime that has a view with `RegisterKind` and `RegisterView`. The agent host then registers each such kind for dispatch through `Registry.Register`, which composes the declaration with the Environments it serves, and installs its own Executor factory with `RegisterExecutor`; that factory builds the Session's view and calls the view's `ViewExecutorFactory`.

Expand All @@ -167,7 +167,7 @@ The runnable test-only example [`testdata/onboarding/main.go`](https://github.co

## Declare support

Core recognizes the [built-in Harness registrations](./harness-catalog.md). Add one entry to `internal/harnessconfig/builtin/catalog.json` with the public `kind`, the display `label` and the model `configuration` package under `internal/harnessconfig`, then run `make generate-harness-catalog`. It generates the model configuration registry, client identifiers and display names and the registration reference; public input validators read the generated registry. `make openapi` derives Harness enums from the same catalog, so do not add handwritten enums to DTO tags or route annotations. `make check-harness-catalog` rejects stale projections.
Core recognizes the [built-in Harness registrations](./harness-catalog.md). Add one entry to `internal/harnessconfig/builtin/catalog.json` with the public `kind`, the display `label`, the pinned upstream `version` and the model `configuration` package under `internal/harnessconfig`, then run `make generate-harness-catalog`. It generates the model configuration registry, agent-host declaration and installation lists, version pin projections, client identifiers and display names and the registration reference; public input validators read the generated registry. `make openapi` derives Harness enums from the same catalog, so do not add handwritten enums to DTO tags or route annotations. `make check-harness-catalog` rejects stale projections.

The `Declaration` of `Configuration()` in `internal/harnessconfig/<kind>` is the Harness's support: a `proto.Declaration` with its `AgentKindCapabilities`, its message, image, MCP and output-schema limits, and in `Conflicts` the feature pairs it supports alone but not together. It states the adapter's maximum support and is the only source: Core reads it through `builtin.Registry()`, and the adapter's Runtime descriptor starts from it. Discovery and the Environment owner only clear support, and Core rejects a heartbeat that widens it. Declare only real differences between Harnesses; a rule that holds for every Harness is a common check in `proto.ValidateSelection`.

Expand Down Expand Up @@ -236,9 +236,17 @@ Warm continuation is the default and records cold recovery as `unverified`. To q

Run `python -m unittest discover -s services/core/tests -p qualify_public_native_test.py` with the pinned SDK to check credential handling and the owned restart boundary without a model. Existing deterministic Core integration tests remain the authority for schema validation, atomic admission, durable receipts and rejection semantics. Real-model results qualify only the selected suite, protocol, Harness and placement. Provider lifecycle, native identity, credential isolation, deferred discovery and unselected suites need separate evidence; view-only results do not qualify the public path.

## Native installer participation
## Native version pins

An adapter supplies `agent.Installation` from `installation.go` in its own package: its registered kind and activation environment. The agent host uses this declaration to activate the packaged Harness. Adapters own native layout; validate the packaged content and execution on the Linux agent host. Missing or incompatible native content fails; it never installs itself during a Turn. Self-hosted installers carry no Harness or Node.js.
`internal/harnessconfig/builtin/catalog.json` owns each built-in Harness's upstream version. Build scripts read that catalog; adapter constants and package version fields are generated projections. Update the catalog and run `make generate-harness-catalog` before building, then use `make check-harness-catalog` to verify freshness. A version change requires [native qualification](#qualify-the-adapter).

For Claude, `version` pins the official Agent SDK dependency in `packages/claude-sdk-adapter/package.json`; its pnpm lock must resolve that exact version and installs stay frozen. Update the lock through pnpm when changing the pin. Native Claude Code's version comes from the installed SDK's `claudeCodeVersion` metadata and is checked against its runtime report. Do not author a separate native Claude Code pin.

For MiniMax, `packages/mcode-harness/source.json` owns the upstream repository and source revision; its `version` is projected from the catalog. The companion artifact carries `source.json`, so its source validation and provenance work independently of the checkout.

## Native Harness packaging

An adapter supplies `agent.Installation` from `installation.go` in its own package: its registered `AgentKind` and activation `Environment`. The generated registration passes these declarations to `agent.ManifestEnvironment`, which activates the packaged Harness from the image manifest. Adapters own native layout; validate the packaged content and execution on the Linux agent host. Missing or incompatible native content fails; it never installs itself during a Turn. Self-hosted installers carry no Harness or Node.js.

`deploy/distribution/AgentHost.Dockerfile` installs each Harness in its own directory and lists it in the image's manifest, `/opt/oac/harnesses.json`. `agent.ManifestEnvironment` activates it through `Installation.Environment`. Add each new Harness to that image and manifest; use the shared [image build](../../docs/maintainers.md#runtime-images-and-helpers) and [view qualification](#qualify-the-view) workflow.

Expand Down
Loading
Loading