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
51 changes: 0 additions & 51 deletions apps/daemon/internal/agent/binpath/binpath.go

This file was deleted.

36 changes: 0 additions & 36 deletions apps/daemon/internal/agent/binpath/binpath_test.go

This file was deleted.

5 changes: 3 additions & 2 deletions apps/daemon/internal/agent/claudesdk/installation.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ import (
"context"
"fmt"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent"
declaration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/claudesdk"
"path/filepath"
"runtime"
)

func Installation() agent.Installation {
return agent.Installation{AgentKind: "claude_sdk", Version: "0.3.269", Supported: func() bool { return runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows" },
return agent.Installation{AgentKind: "claude_sdk", Version: declaration.Declaration.Native.Version, Supported: func() bool { return runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows" },
Environment: func(dir, node string) map[string]string {
return map[string]string{"OAC_RUNTIME_CLAUDE_SDK_ENTRYPOINT": filepath.Join(dir, "dist", "main.js"), "OAC_RUNTIME_CLAUDE_SDK_NODE": node}
},
Check: func(ctx context.Context, dir, node string, env []string) error {
got, err := CheckRuntime(ctx, Config{Node: node, Entrypoint: filepath.Join(dir, "dist", "main.js"), Env: env})
if err != nil || got.SDK != "0.3.269" || !got.SupportsLocalRuntime() {
if err != nil || got.SDK != declaration.Declaration.Native.Version || !got.SupportsLocalRuntime() {
return fmt.Errorf("Claude installation is incompatible; Windows requires Git Bash")
}
return nil
Expand Down
10 changes: 7 additions & 3 deletions apps/daemon/internal/agent/codex/installation.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@ import (
"fmt"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/installroot"
declaration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/codex"
"path/filepath"
"runtime"
)

// versionOutput is what the pinned native binary prints for --version.
var versionOutput = "codex-cli " + declaration.Declaration.Native.Version

func Installation() agent.Installation {
binary := func(dir string) string {
name := "codex"
Expand All @@ -17,13 +21,13 @@ func Installation() agent.Installation {
}
return filepath.Join(dir, "bin", name)
}
return agent.Installation{AgentKind: "codex", Version: "0.153.4", Supported: func() bool { return runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows" },
return agent.Installation{AgentKind: "codex", Version: declaration.Declaration.Native.Version, Supported: func() bool { return runtime.GOOS == "linux" || runtime.GOOS == "darwin" || runtime.GOOS == "windows" },
Environment: func(dir, node string) map[string]string {
return map[string]string{"OAC_RUNTIME_CODEX_BIN": binary(dir)}
return map[string]string{binaryEnv: binary(dir)}
},
Check: func(ctx context.Context, dir, node string, env []string) error {
got, err := installroot.Probe(ctx, binary(dir), []string{"--version"}, env, dir)
if err != nil || got != "codex-cli 0.153.4" {
if err != nil || got != versionOutput {
return fmt.Errorf("Codex installation is incompatible")
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion apps/daemon/internal/agent/codex/recovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
)

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

func (s *Session) recoverRoot(plan SessionPlan) (string, error) {
Expand Down
20 changes: 13 additions & 7 deletions apps/daemon/internal/agent/codex/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,27 @@ import (
"context"
"errors"
"fmt"
"os"
"os/exec"
"strings"

"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/binpath"
)

// InstallURL points operators at the Codex install instructions when
// the daemon can see the adapter but not the CLI binary.
const InstallURL = "https://github.com/openai/codex"

// defaultBinary is the executable to probe and spawn: binpath.Codex()
// honours the OAC_RUNTIME_CODEX_BIN override so a bare-name PATH lookup can
// be bypassed in images where PATH is not under our control. A function
// rather than a const so the env is read at call time.
func defaultBinary() string { return binpath.Codex() }
// binaryEnv pins the codex executable in images where PATH is not under our
// control, so the version probe and the run-time spawn resolve the same binary.
const binaryEnv = "OAC_RUNTIME_CODEX_BIN"

// defaultBinary is the executable to probe and spawn: the trimmed binaryEnv
// override, else "codex" on PATH. Read at call time.
func defaultBinary() string {
if v := strings.TrimSpace(os.Getenv(binaryEnv)); v != "" {
return v
}
return "codex"
}

// ErrCLINotFound is returned by CheckCLIAvailable when the binary
// cannot be located on PATH. Callers use errors.Is to distinguish an
Expand Down
3 changes: 1 addition & 2 deletions apps/daemon/internal/agent/mcode/discovery_workspace.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"path/filepath"

"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/binpath"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/localworkspace"
"github.com/MiniMax-AI/OpenAgentCore/internal/agentdaemon/proto"
)
Expand Down Expand Up @@ -41,7 +40,7 @@ func discoverWorkspace(parent context.Context, options agent.DiscoveryOptions, r
fail(err)
return nil
}
binary, err := exec.LookPath(binpath.MCode())
binary, err := exec.LookPath(defaultBinary())
if err != nil {
fail(err)
return nil
Expand Down
2 changes: 1 addition & 1 deletion apps/daemon/internal/agent/mcode/installation.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
func Installation() agent.Installation {
return agent.Installation{AgentKind: "mcode", Version: SupportedVersion, Supported: func() bool { return runtime.GOOS == "linux" || runtime.GOOS == "darwin" },
Environment: func(dir, node string) map[string]string {
return map[string]string{"OAC_RUNTIME_MCODE_BIN": filepath.Join(dir, "native", "cli.js"), "OAC_RUNTIME_MCODE_NODE": node, "OAC_RUNTIME_MCODE_COMPANION": dir}
return map[string]string{binaryEnv: filepath.Join(dir, "native", "cli.js"), "OAC_RUNTIME_MCODE_NODE": node, "OAC_RUNTIME_MCODE_COMPANION": dir}
},
Check: func(ctx context.Context, dir, node string, env []string) error {
got, err := installroot.Probe(ctx, node, []string{filepath.Join(dir, "native", "cli.js"), "--version"}, env, dir)
Expand Down
18 changes: 15 additions & 3 deletions apps/daemon/internal/agent/mcode/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,28 @@ import (
"context"
"errors"
"fmt"
"os"
"strings"

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

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

const SupportedVersion = "0.4.12"
var SupportedVersion = declaration.Declaration.Native.Version

func defaultBinary() string { return binpath.MCode() }
// binaryEnv pins the mcode executable in images where PATH is not under our
// control, so the version probe and the run-time spawn resolve the same binary.
const binaryEnv = "OAC_RUNTIME_MCODE_BIN"

// defaultBinary is the trimmed binaryEnv override, else "mcode" on PATH. Read at call time.
func defaultBinary() string {
if v := strings.TrimSpace(os.Getenv(binaryEnv)); v != "" {
return v
}
return "mcode"
}

func CheckCLIAvailable(ctx context.Context, binary string) (string, error) {
version, err := versionprobe.Check(ctx, binary, versionprobe.Config{Name: "mcode", DefaultBinary: defaultBinary(), MissingError: ErrCLINotFound, TrimBinary: true})
Expand Down
7 changes: 6 additions & 1 deletion apps/daemon/internal/cli/native_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import (
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/codex"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/installroot"
"github.com/MiniMax-AI/OpenAgentCore/apps/daemon/internal/agent/mcode"
claudedeclaration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/claudesdk"
codexdeclaration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/codex"
mcodedeclaration "github.com/MiniMax-AI/OpenAgentCore/internal/harnessconfig/mcode"
)

func nativeExe(name string) string {
Expand Down Expand Up @@ -69,7 +72,9 @@ func withNativeEnv(values map[string]string) []string {

// Installation registration is local to Runtime; Core does not see native paths.
var nativeHarnesses = map[string]agent.Installation{
"codex": codex.Installation(), "claude": claudesdk.Installation(), "minimax": mcode.Installation(),
codexdeclaration.Declaration.Native.Component: codex.Installation(),
claudedeclaration.Declaration.Native.Component: claudesdk.Installation(),
mcodedeclaration.Declaration.Native.Component: mcode.Installation(),
}
var probeNativeInstallation = checkNativeInstallation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ func initializationBash() (string, error) {
// Git Bash preserves setup's Bash syntax. Never substitute cmd.exe, PowerShell
// or the Windows WSL launcher for a missing Bash implementation.
candidates := []string{}
if explicit := os.Getenv("CLAUDE_CODE_GIT_BASH_PATH"); explicit != "" {
candidates = append(candidates, explicit)
} else if git, err := exec.LookPath("git.exe"); err == nil {
if git, err := exec.LookPath("git.exe"); err == nil {
candidates = append(candidates, filepath.Join(filepath.Dir(git), "..", "bin", "bash.exe"), filepath.Join(filepath.Dir(git), "bash.exe"))
}
for _, candidate := range candidates {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,6 @@ func TestRuntimeInitializationSetupUsesBashAndPhysicalWorkspace(t *testing.T) {
func TestRuntimeInitializationMissingDependenciesAndInvalidRequests(t *testing.T) {
b := initializationFixture(t)
t.Setenv("PATH", t.TempDir())
t.Setenv("CLAUDE_CODE_GIT_BASH_PATH", "")
if err := b.initializeRuntime(t.Context(), proto.RuntimeInitialization{Action: "configure"}); err != nil {
t.Fatal(err)
}
Expand Down
10 changes: 5 additions & 5 deletions contracts/agents-api/harness-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ title: "Built-in Harness registrations"

Each Harness is the one `declaration.go` in its `internal/harnessconfig/<package>` directory. Adding a directory with a `declaration.go` registers the Harness; `make generate-harness-catalog` regenerates the registrations and this page, and `make check-harness-catalog` checks them.

| Identifier | Display name | Declaration |
| --- | --- | --- |
| `claude_sdk` | Claude Code | [`claudesdk/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/claudesdk/declaration.go) |
| `codex` | Codex | [`codex/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/codex/declaration.go) |
| `mcode` | MiniMax Code | [`mcode/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/mcode/declaration.go) |
| Identifier | Display name | Native version | Declaration |
| --- | --- | --- | --- |
| `claude_sdk` | Claude Code | `0.3.269` | [`claudesdk/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/claudesdk/declaration.go) |
| `codex` | Codex | `0.153.4` | [`codex/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/codex/declaration.go) |
| `mcode` | MiniMax Code | `0.4.12` | [`mcode/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/mcode/declaration.go) |

These registrations describe the build. Which Harnesses a deployment enables is the `OAC_HARNESSES` [process setting](../../docs/configuration.md#settings), [Harness capabilities](./harness-capabilities.md) lists what each Harness supports, and a connected Runtime reports its own availability. [Harness protocol](./harness-onboarding.md) describes the adapter and packaging steps.
4 changes: 2 additions & 2 deletions contracts/agents-api/harness-onboarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ An Environment supplies execution resources. Managed E2B, Docker and microsandbo

## 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.** Set the upstream package version in the declaration's `Native` field, which the adapter and `make check-harness-catalog` read for every other projection of the pin. Record the source revision and document the native entry point next to the adapter.
2. **Implement the adapter** in `apps/daemon/internal/agent/<package>`, where `<package>` is the kind without underscores: an `ExecutorFactory`, an `Executor` and a `Turn` ([required interfaces](#required-adapter-interfaces), [lifetimes](#executor-and-turn-lifetimes)). Reuse the shared process, credential, configuration and local workspace helpers.
3. **Write the declaration** in `internal/harnessconfig/<package>/declaration.go` and bind it to the adapter's discovery ([declare the Harness](#declare-the-harness), [register the adapter](#register-the-adapter)). Run `make generate-harness-catalog` to register both.
4. **Package native prerequisites.** Add a Runtime image under `services/core/deploy/<kind>` and, optionally, [native installer participation](#native-installer-participation).
Expand Down Expand Up @@ -208,7 +208,7 @@ The declaration's ordered `protocols` list is the only source of accepted protoc

## Native installer participation

An adapter may supply `agent.Installation` from `installation.go` in its own package: registered kind, pinned version, supported platforms, activation environment and a bounded readiness probe. Register it in `cli/native_harness.go` and add its pinned component to the native distribution builder. This optional contract does not change Executor and Turn semantics. The Runtime owns checksums, copying, locks and additive installation; adapters own native layout and probes. Validate installation and execution on each advertised platform. Missing or incompatible native content fails; it never installs itself during a Turn.
An adapter may supply `agent.Installation` from `installation.go` in its own package: registered kind, pinned version (read from the declaration's `Native.Version`), supported platforms, activation environment and a bounded readiness probe. Register it in `cli/native_harness.go` and add its pinned component to the native distribution builder. This optional contract does not change Executor and Turn semantics. The Runtime owns checksums, copying, locks and additive installation; adapters own native layout and probes. Validate installation and execution on each advertised platform. Missing or incompatible native content fails; it never installs itself during a Turn.

## Native process ownership

Expand Down
10 changes: 5 additions & 5 deletions contracts/agents-api/zh/harness-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ title: "内置 Harness 注册"

每个 Harness 对应 `internal/harnessconfig/<package>` 目录中唯一的 `declaration.go`。新增包含 `declaration.go` 的目录即注册该 Harness;`make generate-harness-catalog` 重新生成注册代码和本页,`make check-harness-catalog` 检查生成结果。

| 标识符 | 显示名称 | 声明 |
| --- | --- | --- |
| `claude_sdk` | Claude Code | [`claudesdk/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/claudesdk/declaration.go) |
| `codex` | Codex | [`codex/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/codex/declaration.go) |
| `mcode` | MiniMax Code | [`mcode/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/mcode/declaration.go) |
| 标识符 | 显示名称 | 原生版本 | 声明 |
| --- | --- | --- | --- |
| `claude_sdk` | Claude Code | `0.3.269` | [`claudesdk/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/claudesdk/declaration.go) |
| `codex` | Codex | `0.153.4` | [`codex/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/codex/declaration.go) |
| `mcode` | MiniMax Code | `0.4.12` | [`mcode/declaration.go`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/internal/harnessconfig/mcode/declaration.go) |

这些注册描述当前构建。部署启用的 Harness 由 `OAC_HARNESSES` [进程设置](../../../docs/zh/configuration.md#settings)决定;[Harness 能力](./harness-capabilities.md)列出各 Harness 的支持范围,连接的 Runtime 报告自身可用性。[Harness protocol](./harness-onboarding.md)介绍适配器和打包步骤。
Loading
Loading