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
7 changes: 4 additions & 3 deletions apps/daemon/internal/agent/codex/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,11 @@ type SessionPlan struct {
func BuildSessionPlan(stateRoot, agentStateKey string, opts map[string]any, controls *proto.ExecutionControls) (SessionPlan, error) {
plan := SessionPlan{
// Harnesses run unattended: Codex never offers its ask-the-user tool,
// and an unreachable model host fails the Turn after the provider's
// bounded retries instead of waiting for the network forever.
// an unreachable model host fails the Turn after the provider's
// bounded retries instead of waiting for the network forever, and no
// goal starts native turns of its own after the Turn ends.
ExtraConfig: [][2]string{{"tools.experimental_request_user_input.enabled", "false"}},
DisableFeatures: []string{"unbounded_connection_retries"},
DisableFeatures: []string{"unbounded_connection_retries", "goals"},
Cleanup: func() {},
}

Expand Down
12 changes: 12 additions & 0 deletions apps/daemon/internal/agent/codex/provider_config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,18 @@ func TestModelConnectionRetriesStayBounded(t *testing.T) {
}
}

// An active Codex goal starts native turns on its own whenever its thread is
// idle, which would run work after the Turn ends.
func TestGoalsStayDisabled(t *testing.T) {
plan, err := BuildSessionPlan(t.TempDir(), "goals", map[string]any{}, nil)
if err != nil {
t.Fatal(err)
}
if !slices.Contains(plan.DisableFeatures, "goals") {
t.Fatal("goals stay enabled")
}
}

func TestProviderCredentialOnlyInNativeLoopEnvironment(t *testing.T) {
root := t.TempDir()
const token = "synthetic-private-provider-token"
Expand Down
1 change: 1 addition & 0 deletions contracts/agents-api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ Each item is Core's deliberate or native behavior where the official service beh
- An omitted reasoning effort stays null instead of taking the model's default.
- Codex maps programmatic tool calling to its native `code_mode`, whose model-written scripts call the other tools; the feature is under development upstream.
- Codex rejects programmatic tool calling together with `multi_agent`.
- Codex runs without its native goals (`create_goal`, `get_goal` and `update_goal`), because an active goal starts turns of its own after the Turn ends ([Codex Runtime](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/services/core/deploy/codex/README.md)).
- A Session's `agent.tools` omits `tool_search` declarations.
- Core rejects an inline `authorization` on a Session MCP transport, an `Authorization` entry in `headers` and a nonempty stdio `env`: credentials come only from Vaults (`credential_id`) and environment values only from the Environment (`env_vars`) ([MCP](./execution-tools.md#mcp)).
- A `stdio` MCP server needs a workspace placement and the origin `environment`. Claude Code starts the server in its workspace directory, so `cwd` must equal it, with its whole process environment, which also holds the model provider key and other servers' Vault bearer tokens, and it needs `allowed_tools` null. MiniMax Code starts the server in its private home directory, so it rejects every `stdio` server ([MCP](./execution-tools.md#mcp)).
Expand Down
3 changes: 2 additions & 1 deletion contracts/agents-api/zh/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "OpenAI 兼容性"
source: contracts/agents-api/index.md
source_hash: 1ba11a295c62e532fae58388b09d54a065648642ee17aed10081a36c65ef64f5
source_hash: 3e138165ee27672531124d2c156d24e087fb6904e60f828635990dd1d3eb8626
---

Core 实现下方固定版本的 OpenAI Agents API。本台账列出各项资源的覆盖情况、相对于官方服务的所有差异以及已知缺口。
Expand Down Expand Up @@ -82,6 +82,7 @@ Core 自身字段位于 `x_agents_core` 中([Core extensions](../../../docs/zh
- 未指定推理强度时会保持为 null,而不是采用模型的默认值。
- Codex 把程序化工具调用映射到原生 `code_mode`,由模型编写的脚本调用其他工具;该功能在上游仍处于开发中。
- Codex 拒绝同时使用程序化工具调用和 `multi_agent`。
- Codex 不启用原生 goals(`create_goal`、`get_goal` 和 `update_goal`),因为处于活动状态的 goal 会在 Turn 结束后自行启动新的 turn([Codex Runtime](https://github.com/MiniMax-AI/OpenAgentCore/blob/main/services/core/deploy/codex/README.md))。
- Session 的 `agent.tools` 会省略 `tool_search` 声明。
- Core 拒绝 Session MCP 传输中的内联 `authorization`、`headers` 中的 `Authorization` 条目以及非空的 stdio `env`:凭据只来自 Vault(`credential_id`),环境值只来自 Environment(`env_vars`)([MCP](execution-tools.md#mcp))。
- `stdio` MCP 服务器需要工作区部署位置和 `environment` 来源。Claude Code 在其工作区目录中启动服务器,因此 `cwd` 必须与之相同;服务器继承整个进程环境,其中也有模型提供方密钥和其他服务器的 Vault bearer 令牌;且 `allowed_tools` 须为 null。MiniMax Code 在其私有主目录中启动服务器,因此拒绝所有 `stdio` 服务器([MCP](execution-tools.md#mcp))。
Expand Down
2 changes: 2 additions & 0 deletions services/core/deploy/codex/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Each Session has its own `CODEX_HOME` at `<StateRoot>/daemon/agent-sessions/<sta

By default Codex retries a failed model connection forever, waiting up to 60 seconds between attempts, so a Turn whose model host is unreachable stays in progress with no events. The adapter disables that `unbounded_connection_retries` feature, so Codex falls back to its bounded defaults: up to 4 retries per request and 5 per response stream. A model host that does not resolve or refuses connections then fails the Turn with `connection_failed` within about a minute, depending on how long each lookup or connection attempt takes. Retries start only after a request fails, so slow responses are unaffected, and a stream still ends after Codex's 300 seconds without data. Codex sets no connect timeout: against a host that silently drops connections, each of the 30 attempts waits for the operating system's connect timeout.

Codex's `goals` feature is on by default: when a thread with an active goal goes idle, Codex starts another turn toward the goal on its own, so its tools and model calls would keep running after the Turn ends, outside any Turn the API reports. The adapter disables it, so the model is not offered `create_goal`, `get_goal` or `update_goal`.

## Execution controls

The adapter applies Core's typed controls and opt-ins, described in the [Runtime protocol](../../../../docs/runtime-protocol.md#capability-declarations), through native Codex settings on both new and resumed Turns.
Expand Down
Loading