From 963e7979a07ecd89fc9e16116f8625dcdd41ac13 Mon Sep 17 00:00:00 2001 From: SaladDay <1203511142@qq.com> Date: Wed, 7 Oct 2026 18:20:34 +0000 Subject: [PATCH] Run Codex on Windows with the default verbosity Protocol medium is the default text amount: a model with verbosity support applies the override, and Codex ignores it for any other model. Codex therefore needs no catalog probe for medium, so it is available on Windows, where the probe cannot run, with TextVerbosity unsupported. Core requires TextVerbosity only for an explicit non-medium verbosity. --- apps/daemon/internal/agent/codex/declaration.go | 5 ----- .../internal/agent/codex/model_verbosity.go | 6 ++++++ .../internal/agent/codex/model_verbosity_test.go | 15 +++++---------- docs/getting-started/self-hosted.md | 2 +- docs/zh/getting-started/self-hosted.md | 4 ++-- services/core/internal/execution/support.go | 2 +- services/core/tests/integration/dispatch_test.go | 3 ++- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/apps/daemon/internal/agent/codex/declaration.go b/apps/daemon/internal/agent/codex/declaration.go index 809d7e718..440f255ab 100644 --- a/apps/daemon/internal/agent/codex/declaration.go +++ b/apps/daemon/internal/agent/codex/declaration.go @@ -41,11 +41,6 @@ func discover(ctx context.Context, options agent.DiscoveryOptions, info proto.Su } func discoverWithCheck(parent context.Context, options agent.DiscoveryOptions, info proto.SupportedAgentKind, check func(context.Context, string) (string, error)) *agent.Runtime { runtime := &agent.Runtime{Info: info} - if !SupportsTextVerbosity { - // Every execution carries a text verbosity, which needs the bounded catalog probe. - fmt.Fprintln(options.Stderr, "oac-daemon: codex unavailable: text verbosity requires Unix process-group cancellation support") - return runtime - } ctx, cancel := context.WithTimeout(parent, 15*time.Second) defer cancel() version, err := check(ctx, "") diff --git a/apps/daemon/internal/agent/codex/model_verbosity.go b/apps/daemon/internal/agent/codex/model_verbosity.go index 79027522a..ca9c23fc8 100644 --- a/apps/daemon/internal/agent/codex/model_verbosity.go +++ b/apps/daemon/internal/agent/codex/model_verbosity.go @@ -25,6 +25,12 @@ func prepareModelVerbosity(ctx context.Context, binary string, plan *SessionPlan } func verifyModelVerbosity(ctx context.Context, probe catalogProbe, plan *SessionPlan) error { + // Protocol medium is the default text amount: a model with verbosity support + // applies the override and Codex ignores it for any other, so no catalog + // decision depends on it. + if slices.Contains(plan.ExtraConfig, [2]string{"model_verbosity", `"medium"`}) { + return nil + } args := []string{} for _, kv := range plan.ExtraConfig { args = append(args, "-c", kv[0]+"="+kv[1]) diff --git a/apps/daemon/internal/agent/codex/model_verbosity_test.go b/apps/daemon/internal/agent/codex/model_verbosity_test.go index 3e1905255..4cbb5ee4b 100644 --- a/apps/daemon/internal/agent/codex/model_verbosity_test.go +++ b/apps/daemon/internal/agent/codex/model_verbosity_test.go @@ -4,6 +4,7 @@ import ( "context" "os" "path/filepath" + "slices" "strings" "testing" @@ -95,17 +96,11 @@ func TestPrepareDefaultModelVerbosity(t *testing.T) { if err != nil { t.Fatal(err) } - found := false - for _, kv := range plan.ExtraConfig { - if kv[0] == "model_verbosity" { - found = true - if kv[1] != `"`+level+`"` { - t.Fatal("configured verbosity changed", kv) - } - } + if !slices.Contains(plan.ExtraConfig, [2]string{"model_verbosity", `"` + level + `"`}) || plan.Model != model { + t.Fatal("configured verbosity or model identity changed", plan.ExtraConfig, plan.Model) } - if found != (model == "supported") || plan.Model != model { - t.Fatal("native default or model identity changed", plan.ExtraConfig, plan.Model) + if level == "medium" { + return // the default amount needs no catalog decision } kv := plan.ExtraConfig[len(plan.ExtraConfig)-1] raw, err := os.ReadFile(strings.Trim(kv[1], `"`)) diff --git a/docs/getting-started/self-hosted.md b/docs/getting-started/self-hosted.md index a2936f3fc..e5b8382a0 100644 --- a/docs/getting-started/self-hosted.md +++ b/docs/getting-started/self-hosted.md @@ -14,7 +14,7 @@ The Session's model provider resolves as for any other Session, so the installat | --- | --- | --- | --- | | Linux amd64 | Supported | Supported | Supported | | macOS arm64 | Supported | Supported | Supported | -| Windows amd64 | Not supported | Supported | Not supported | +| Windows amd64 | Supported | Supported | Not supported | The installer brings its own pinned Node.js and Harness versions (listed in [`scripts/build-native-installer.mjs`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/scripts/build-native-installer.mjs)) and leaves other installations of those tools untouched. On a platform without a matching installer, the command fails. diff --git a/docs/zh/getting-started/self-hosted.md b/docs/zh/getting-started/self-hosted.md index df6b1af3f..055fcb883 100644 --- a/docs/zh/getting-started/self-hosted.md +++ b/docs/zh/getting-started/self-hosted.md @@ -1,7 +1,7 @@ --- title: "自托管执行器" source: docs/getting-started/self-hosted.md -source_hash: 6f39aff3240eec960d278d7b21665b105ce14337517eb8961424ec141bfcfbe5 +source_hash: 19506e4bab34b802e5c3c8a1818bcb5c8397aa91fdf9ace512b5aaeb99341b3a --- `self_hosted` Session 在应用拥有的机器上运行:工作站、虚拟机或你管理的沙箱。应用通过 `/v1` 创建 Session,并获得安装 `oac-daemon`、启动它并连接 Core 的命令。Web 在 Session 页面展示同一命令;Web 是可选的。Core 不创建、停止或回收这台机器。 @@ -16,7 +16,7 @@ Session 的模型提供商与其他 Session 一样解析,因此当 Session 及 | --- | --- | --- | --- | | Linux amd64 | 支持 | 支持 | 支持 | | macOS arm64 | 支持 | 支持 | 支持 | -| Windows amd64 | 不支持 | 支持 | 不支持 | +| Windows amd64 | 支持 | 支持 | 不支持 | 安装程序自带固定版本的 Node.js 和 Harness(列于 [`scripts/build-native-installer.mjs`](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/scripts/build-native-installer.mjs)),不修改这些工具的其他安装。在没有匹配安装程序的平台上,命令会失败。 diff --git a/services/core/internal/execution/support.go b/services/core/internal/execution/support.go index 7650347c5..8e83a75a1 100644 --- a/services/core/internal/execution/support.go +++ b/services/core/internal/execution/support.go @@ -99,7 +99,7 @@ func (p Policy) engineCapabilities(peer *runtimegateway.Session, engine string, if snapshot.Agent.Text.Format.Type == "json_schema" && (!caps.StructuredOutput.IsSupported() || !caps.MessageItems.IsSupported()) { return fail("device must support structured output and message observations") } - if profile.TextVerbosity.IsSupported() && !caps.TextVerbosity.IsSupported() { + if verbosity := snapshot.Agent.Text.Verbosity; verbosity != "" && verbosity != "medium" && !caps.TextVerbosity.IsSupported() { return fail("device must advertise text_verbosity") } if snapshot.Agent.MultiAgent.Enabled && !caps.SubagentObservations.IsSupported() { diff --git a/services/core/tests/integration/dispatch_test.go b/services/core/tests/integration/dispatch_test.go index a2002117b..1faa6487e 100644 --- a/services/core/tests/integration/dispatch_test.go +++ b/services/core/tests/integration/dispatch_test.go @@ -435,7 +435,8 @@ func TestExecutionRejectsRuntimeMissingCapabilityBeforeClaim(t *testing.T) { } { missing := tc.missing t.Run(missing, func(t *testing.T) { - h := newDispatchHarness(t) + // Only an explicit non-medium verbosity needs text_verbosity. + h := newDispatchHarnessForSession(t, []byte(`{"agent":{"model":"test-model","instructions":"Keep this instruction.","text":{"verbosity":"high"}},"environment":{"type":"none"}}`), false) caps := prototest.Capabilities(proto.AgentKindCapabilities{WebSearchControl: proto.CapabilityFromBool(missing != "web_search_control"), TextVerbosity: proto.CapabilityFromBool(missing != "text_verbosity"), SubagentControl: proto.CapabilityFromBool(missing != "subagent_control"), EnvironmentNone: proto.CapabilityFromBool(missing != "environment_none")}) h.write("", proto.TypeHeartbeat, proto.HeartbeatPayload{HomeRemoval: proto.CapabilityUnsupported, SupportedAgentKinds: []proto.SupportedAgentKind{{Kind: "codex", Available: true, Capabilities: caps}}}) deadline := time.Now().Add(3 * time.Second)