Commit Graph

19 Commits

  • [app-server] feat: add v2 command execution approval flow (#6758)
    This PR adds the API V2 version of the command‑execution approval flow
    for the shell tool.
    
    This PR wires the new RPC (`item/commandExecution/requestApproval`, V2
    only) and related events (`item/started`, `item/completed`, and
    `item/commandExecution/delta`, which are emitted in both V1 and V2)
    through the app-server
    protocol. The new approval RPC is only sent when the user initiates a
    turn with the new `turn/start` API so we don't break backwards
    compatibility with VSCE.
    
    The approach I took was to make as few changes to the Codex core as
    possible, leveraging existing `EventMsg` core events, and translating
    those in app-server. I did have to add additional fields to
    `EventMsg::ExecCommandEndEvent` to capture the command's input so that
    app-server can statelessly transform these events to a
    `ThreadItem::CommandExecution` item for the `item/completed` event.
    
    Once we stabilize the API and it's complete enough for our partners, we
    can work on migrating the core to be aware of command execution items as
    a first-class concept.
    
    **Note**: We'll need followup work to make sure these APIs work for the
    unified exec tool, but will wait til that's stable and landed before
    doing a pass on app-server.
    
    Example payloads below:
    ```
    {
      "method": "item/started",
      "params": {
        "item": {
          "aggregatedOutput": null,
          "command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
          "cwd": "/Users/owen/repos/codex/codex-rs",
          "durationMs": null,
          "exitCode": null,
          "id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
          "parsedCmd": [
            {
              "cmd": "touch /tmp/should-trigger-approval",
              "type": "unknown"
            }
          ],
          "status": "inProgress",
          "type": "commandExecution"
        }
      }
    }
    ```
    
    ```
    {
      "id": 0,
      "method": "item/commandExecution/requestApproval",
      "params": {
        "itemId": "call_lNWWsbXl1e47qNaYjFRs0dyU",
        "parsedCmd": [
          {
            "cmd": "touch /tmp/should-trigger-approval",
            "type": "unknown"
          }
        ],
        "reason": "Need to create file in /tmp which is outside workspace sandbox",
        "risk": null,
        "threadId": "019a93e8-0a52-7fe3-9808-b6bc40c0989a",
        "turnId": "1"
      }
    }
    ```
    
    ```
    {
      "id": 0,
      "result": {
        "acceptSettings": {
          "forSession": false
        },
        "decision": "accept"
      }
    }
    ```
    
    ```
    {
      "params": {
        "item": {
          "aggregatedOutput": null,
          "command": "/bin/zsh -lc 'touch /tmp/should-trigger-approval'",
          "cwd": "/Users/owen/repos/codex/codex-rs",
          "durationMs": 224,
          "exitCode": 0,
          "id": "call_lNWWsbXl1e47qNaYjFRs0dyU",
          "parsedCmd": [
            {
              "cmd": "touch /tmp/should-trigger-approval",
              "type": "unknown"
            }
          ],
          "status": "completed",
          "type": "commandExecution"
        }
      }
    }
    ```
  • [App server] add mcp tool call item started/completed events (#6642)
    this PR does two things:
    1. refactor `apply_bespoke_event_handling` into a separate file as it's
    getting kind of long;
    2. add mcp tool call `item/started` and `item/completed` events. To roll
    out app server events asap we didn't properly migrate mcp core events to
    use TurnItem for mcp tool calls - this will be a follow-up PR.
    
    real events generated in log:
    ```
    {
      "method": "codex/event/mcp_tool_call_end",
      "params": {
        "conversationId": "019a8021-26af-7c20-83db-21ca81e44d68",
        "id": "0",
        "msg": {
          "call_id": "call_7EjRQkD9HnfyMWf7tGrT9FKA",
          "duration": {
            "nanos": 92708,
            "secs": 0
          },
          "invocation": {
            "arguments": {
              "server": ""
            },
            "server": "codex",
            "tool": "list_mcp_resources"
          },
          "result": {
            "Ok": {
              "content": [
                {
                  "text": "{\"resources\":[]}",
                  "type": "text"
                }
              ],
              "isError": false
            }
          },
          "type": "mcp_tool_call_end"
        }
      }
    }
    
    {
      "method": "item/completed",
      "params": {
        "item": {
          "arguments": {
            "server": ""
          },
          "error": null,
          "id": "call_7EjRQkD9HnfyMWf7tGrT9FKA",
          "result": {
            "content": [
              {
                "text": "{\"resources\":[]}",
                "type": "text"
              }
            ],
            "structuredContent": null
          },
          "server": "codex",
          "status": "completed",
          "tool": "list_mcp_resources",
          "type": "mcpToolCall"
        }
      }
    }
    ```
  • [app-server] small fixes for JSON schema export and one-of types (#6614)
    A partner is consuming our generated JSON schema bundle for app-server
    and identified a few issues:
    - not all polymorphic / one-of types have a type descriminator
    - `"$ref": "#/definitions/v2/SandboxPolicy"` is missing
    - "Option<>" is an invalid schema name, and also unnecessary
    
    This PR:
    - adds the type descriminator to the various types that are missing it
    except for `SessionSource` and `SubAgentSource` because they are
    serialized to disk (adding this would break backwards compat for
    resume), and they should not be necessary to consume for an integration
    with app-server.
    - removes the special handling in `export.rs` of various types like
    SandboxPolicy, which turned out to be unnecessary and incorrect
    - filters out `Option<>` which was auto-generated for request params
    that don't need a body
    
    For context, we currently pull in wayyy more types than we need through
    the `EventMsg` god object which we are **not** planning to expose in API
    v2 (this is how I suspect `SessionSource` and `SubAgentSource` are being
    pulled in). But until we have all the necessary v2 notifications in
    place that will allow us to remove `EventMsg`, we will keep exporting it
    for now.
  • [App-server] add new v2 events:item/reasoning/delta, item/agentMessage/delta & item/reasoning/summaryPartAdded (#6559)
    core event to app server event mapping:
    1. `codex/event/reasoning_content_delta` ->
    `item/reasoning/summaryTextDelta`.
    2. `codex/event/reasoning_raw_content_delta` ->
    `item/reasoning/textDelta`
    3. `codex/event/agent_message_content_delta` →
    `item/agentMessage/delta`.
    4. `codex/event/agent_reasoning_section_break` ->
    `item/reasoning/summaryPartAdded`.
    
    Also added a change in core to pass down content index, summary index
    and item id from events.
    
    Tested with the `git checkout owen/app_server_test_client && cargo run
    -p codex-app-server-test-client -- send-message-v2 "hello"` and verified
    that new events are emitted correctly.
  • [app-server] feat: thread/resume supports history, path, and overrides (#6483)
    This updates `thread/resume` to be at parity with v1's
    `ResumeConversationParams`. Turns out history is useful for codex cloud
    and path is useful for the VSCode extension. And config overrides are
    always useful.
  • [app-server] add item started/completed events for turn items (#6517)
    This one should be quite straightforward, as it's just a translation of
    TurnItem events we already emit to ThreadItem that app-server exposes to
    customers.
    
    To test, cp my change to owen/app_server_test_client and do the
    following:
    ```
    cargo build -p codex-cli
    RUST_LOG=codex_app_server=info CODEX_BIN=target/debug/codex cargo run -p codex-app-server-test-client -- send-message-v2 "hello"
    ```
    
    example event before (still kept there for backward compatibility):
    ```
    {
    <   "method": "codex/event/item_completed",
    <   "params": {
    <     "conversationId": "019a74cc-fad9-7ab3-83a3-f42827b7b074",
    <     "id": "0",
    <     "msg": {
    <       "item": {
    <         "Reasoning": {
    <           "id": "rs_03d183492e07e20a016913a936eb8c81a1a7671a103fee8afc",
    <           "raw_content": [],
    <           "summary_text": [
    <             "Hey! What would you like to work on? I can explore the repo, run specific tests, or implement a change. Let's keep it short and straightforward. There's no need for a lengthy introduction or elaborate planning, just a friendly greeting and an open offer to help. I want to make sure the user feels welcomed and understood right from the start. It's all about keeping the tone friendly and concise!"
    <           ]
    <         }
    <       },
    <       "thread_id": "019a74cc-fad9-7ab3-83a3-f42827b7b074",
    <       "turn_id": "0",
    <       "type": "item_completed"
    <     }
    <   }
    < }
    ```
    
    after (v2):
    ```
    < {
    <   "method": "item/completed",
    <   "params": {
    <     "item": {
    <       "id": "rs_03d183492e07e20a016913a936eb8c81a1a7671a103fee8afc",
    <       "text": "Hey! What would you like to work on? I can explore the repo, run specific tests, or implement a change. Let's keep it short and straightforward. There's no need for a lengthy introduction or elaborate planning, just a friendly greeting and an open offer to help. I want to make sure the user feels welcomed and understood right from the start. It's all about keeping the tone friendly and concise!",
    <       "type": "reasoning"
    <     }
    <   }
    < }
    ```
  • [app-server] update macro to make renaming methods less boilerplate-y (#6470)
    We already do this for notification definitions and it's really nice.
    
    Verified there are no changes to actual exported files by diff'ing
    before and after this change.
  • [app-server] chore: move initialize out of deprecated API section (#6468)
    Self-explanatory - `initialize` is not a deprecated API and works
    equally well with the v2 APIs.
  • [app-server] feat: expose additional fields on Thread (#6338)
    Add the following fields to Thread:
    
    ```
        pub preview: String,
        pub model_provider: String,
        pub created_at: i64,
    ```
    
    Will prob need another PR once this lands:
    https://github.com/openai/codex/pull/6337
  • [App-server] Implement account/read endpoint (#6336)
    This PR does two things:
    1. add a new function in core that maps the core-internal plan type to
    the external plan type;
    2. implement account/read that get account status (v2 of
    `getAuthStatus`).
  • [App Server] Add more session metadata to listConversations (#6337)
    This unlocks a few new product experience for app server consumers
  • [app-server] feat: v2 Turn APIs (#6216)
    Implements:
    ```
    turn/start
    turn/interrupt
    ```
    
    along with their integration tests. These are relatively light wrappers
    around the existing core logic, and changes to core logic are minimal.
    
    However, an improvement made for developer ergonomics:
    - `turn/start` replaces both `SendUserMessage` (no turn overrides) and
    `SendUserTurn` (can override model, approval policy, etc.)
  • [App-server] Add account/login/cancel v2 endpoint (#6288)
    Add `account/login/cancel` v2 endpoint for auth. this is similar
    implementation to `cancelLoginChatgpt` v1 endpoint.
  • [App-server] Implement v2 for account/login/start and account/login/completed (#6183)
    This PR implements `account/login/start` and `account/login/completed`.
    Instead of having separate endpoints for login with chatgpt and api, we
    have a single enum handling different login methods. For sync auth
    methods like sign in with api key, we still send a `completed`
    notification back to be compatible with the async login flow.
  • [app-server] feat: v2 Thread APIs (#6214)
    Implements:
    ```
    thread/list
    thread/start
    thread/resume
    thread/archive
    ```
    
    along with their integration tests. These are relatively light wrappers
    around the existing core logic, and changes to core logic are minimal.
    
    However, an improvement made for developer ergonomics:
    - `thread/start` and `thread/resume` automatically attaches a
    conversation listener internally, so clients don't have to make a
    separate `AddConversationListener` call like they do today.
    
    For consistency, also updated `model/list` and `feedback/upload` (naming
    conventions, list API params).
  • [app-server] feat: export.rs supports a v2 namespace, initial v2 notifications (#6212)
    **Typescript and JSON schema exports**
    While working on Thread/Turn/Items type definitions, I realize we will
    run into name conflicts between v1 and v2 APIs (e.g. `RateLimitWindow`
    which won't be reusable since v1 uses `RateLimitWindow` from `protocol/`
    which uses snake_case, but we want to expose camelCase everywhere, so
    we'll define a V2 version of that struct that serializes as camelCase).
    
    To set us up for a clean and isolated v2 API, generate types into a
    `v2/` namespace for both typescript and JSON schema.
    - TypeScript: v2 types emit under `out_dir/v2/*.ts`, and root index.ts
    now re-exports them via `export * as v2 from "./v2"`;.
    - JSON Schemas: v2 definitions bundle under `#/definitions/v2/*` rather
    than the root.
    
    The location for the original types (v1 and types pulled from
    `protocol/` and other core crates) haven't changed and are still at the
    root. This is for backwards compatibility: no breaking changes to
    existing usages of v1 APIs and types.
    
    **Notifications**
    While working on export.rs, I:
    - refactored server/client notifications with macros (like we already do
    for methods) so they also get exported (I noticed they weren't being
    exported at all).
    - removed the hardcoded list of types to export as JSON schema by
    leveraging the existing macros instead
    - and took a stab at API V2 notifications. These aren't wired up yet,
    and I expect to iterate on these this week.
  • [App-server] v2 for account/updated and account/logout (#6175)
    V2 for `account/updated` and `account/logout` for app server. correspond
    to old `authStatusChange` and `LogoutChatGpt` respectively. Followup PRs
    will make other v2 endpoints call `account/updated` instead of
    `authStatusChange` too.
  • [app-server] refactor: split API types into v1 and v2 (#6005)
    Makes it easier to figure out which types are defined in the old vs. new
    API schema.