Commit Graph

9 Commits

  • [codex] Cache plugin metadata for tool suggestions (#27812)
    ## Why
    
    `built_tools` runs for every sampling request, and local plugin
    discovery was repeatedly rereading plugin manifests, skills, MCP
    configuration, and app declarations to build the same tool-suggest
    metadata.
    
    That source-derived metadata is stable until the existing plugin manager
    reloads its cache. Runtime eligibility still needs to reflect the
    current install, disable, policy, app-overlap, and authentication state.
    
    ## What changed
    
    - Add a bounded, in-memory tool-suggest metadata cache owned by
    `PluginsManager`.
    - Key cached metadata by plugin identity and source, while applying
    authentication routing each time the metadata is projected.
    - Invalidate the metadata alongside the existing loaded-plugin cache,
    including its normal configuration, marketplace refresh, and
    remote-installed-plugin invalidation paths.
    - Guard against an in-flight load repopulating stale metadata after
    invalidation.
    - Keep marketplace membership and all runtime eligibility filtering live
    rather than introducing a separate catalog or revision model.
    
    ## Impact
    
    Repeated sampling requests reuse already-loaded plugin capability
    metadata while retaining the existing plugin-manager lifecycle as the
    single freshness boundary.
    
    ## Validation
    
    - `just test -p codex-core-plugins` — 252 passed
    - Added focused coverage for cache invalidation and authentication
    reprojection.
  • [codex] Gate remote plugin catalog by auth (#28625)
    ## Summary
    
    - Treat the remote global plugin catalog as active only when
    `remote_plugin` is enabled and the current auth uses the Codex backend.
    - Skip the local OpenAI curated marketplace for remote-enabled ChatGPT
    users while preserving configured marketplaces.
    - Keep the local curated marketplace for API-key users, unauthenticated
    fallback, and ChatGPT users with `remote_plugin` disabled.
    - Apply the same effective-remote gate to the remote
    installed-marketplace cache.
    
    ## Root cause
    
    The tool-suggestion discovery path unconditionally included the local
    OpenAI curated marketplace. For remote-enabled ChatGPT users, that made
    remote discovery additive: Codex parsed every local curated
    `plugin.json` before also loading the remote catalog.
    
    ## Validation
    
    - `just fmt`
    - `cargo build -p codex-cli --bin codex`
    - Targeted auth/feature matrix tests pass, including API-key auth with
    `remote_plugin` enabled.
    - Manual CLI validation confirmed:
      - ChatGPT + remote off includes local curated.
      - ChatGPT + remote on excludes local curated.
      - API-key auth keeps local curated when remote is enabled.
    - `just test -p codex-core-plugins`: 235 passed; one unrelated existing
    marketplace test failed because it loaded the developer's home
    marketplace configuration.
  • [codex] Load API curated marketplace by auth (#28383)
    ## Summary
    - choose the local OpenAI curated marketplace manifest based on auth:
    Codex backend auth gets the existing marketplace, direct provider auth
    gets `api_marketplace.json`
    - include Bedrock API key auth in the direct-provider API marketplace
    path
    - safely skip the API marketplace when `api_marketplace.json` is absent
    
    ## Validation
    - `just fmt`
    - `git diff --check origin/main...HEAD`
    - CI should run the full validation
    
    ## Manual Testing
    
    ### - New api marketplace not available for API key sign
    1. Safely not display anything from api marketplace
    <img width="1161" height="289" alt="Screenshot 2026-06-15 at 21 37 43"
    src="https://github.com/user-attachments/assets/a5f16642-8a20-4ac1-a0de-1274a4c7b5b2"
    />
    
    ### - New api marketplace for API key sign in
    1. Setup api_marketplace.json
    ```
    {
      "name": "openai-curated",
      "interface": {
        "displayName": "Codex official"
      },
      "plugins": [
        {
          "name": "linear",
          "source": {
            "source": "local",
            "path": "./plugins/linear"
          },
          "policy": {
            "installation": "AVAILABLE",
            "authentication": "ON_INSTALL"
          },
          "category": "Productivity"
        }
      ]
    }
    ```
    
    2. Log in with API key, observe that only the defined plugin from
    api_marketplace.json is available from "Codex Official" (outside of
    local testing marketplaces)
    <img width="1167" height="446" alt="Screenshot 2026-06-15 at 21 16 53"
    src="https://github.com/user-attachments/assets/7cf61477-d826-4ef6-bc05-0a23ac1c0259"
    />
    
    also checked functionality on codex app
    
    ### - SiWC users 
    Still uses 'default' marketplace.json and renders all plugins
    <img width="1171" height="502" alt="Screenshot 2026-06-15 at 21 40 25"
    src="https://github.com/user-attachments/assets/d212ea9b-0aa5-470b-8ea4-450efe65bb2b"
    />
    
    also checked functionality on codex app
    
    
    ## Notes
    - `just test -p codex-core-plugins` was started locally before splitting
    branches, but I stopped relying on local tests per follow-up and left
    final validation to PR CI.
  • [codex] Limit app-based plugin suggestions to remote catalogs (#27988)
    ## Summary
    
    - Keep local plugin suggestions bounded to fallback and explicitly
    configured plugins.
    - Preserve app-overlap recommendations for remote plugins using cached
    catalog metadata.
    - Remove the WSL-specific local discovery exception and move
    manager-owned discovery tests into `codex-core-plugins`.
    
    ## Why
    
    Local curated marketplaces were allowlisted before plugin detail
    loading, so every uninstalled candidate could be deep-read before its
    app IDs were checked. That caused per-turn reads of candidate plugin
    manifests, skills, app configs, hooks, and MCP configs, which is
    especially expensive on slow disks.
    
    Remote discovery does not need those local candidate reads because app
    IDs are already available in the cached remote catalog. Installed local
    plugins are still loaded when needed to determine the user's installed
    app IDs.
    
    ## Validation
    
    - `just fmt`
    - `just test -p codex-core-plugins discoverable::tests` (13 passed)
    - `just test -p codex-core plugins::discoverable::tests` (4 passed)
    - `just bazel-lock-update`
    - `just bazel-lock-check`
    - `git diff --check`
  • [codex] Skip local curated discovery for remote plugins (#27311)
    ## Summary
    
    - skip the local `openai-curated` marketplace before marketplace loading
    when tool-suggest discovery uses remote plugins
    - preserve existing marketplace listing behavior for all other callers
    and when remote plugins are disabled
    - add regression coverage proving the curated marketplace is excluded
    before its malformed manifest can be read
    
    ## Why
    
    Tool-suggest discovery previously loaded every local `openai-curated`
    plugin manifest and only discarded that marketplace afterward when
    remote plugins were enabled. The remote catalog is used in that mode, so
    the local scan consumed CPU without contributing discoverable plugins.
    
    ## Impact
    
    Remote-plugin tool suggestion discovery no longer reads the local
    curated marketplace and its plugin manifests. `openai-bundled`,
    configured marketplaces, normal `plugin/list` behavior, and local
    curated discovery when remote plugins are disabled are unchanged.
    
    ## Validation
    
    - `just test -p codex-core-plugins
    list_marketplaces_can_skip_openai_curated_before_loading`
    - `just test -p codex-core
    list_tool_suggest_discoverable_plugins_omits_openai_curated_when_remote_enabled`
    - `just fmt`
    - `git diff --check`
  • [plugins] Inject remote_plugin_id into install elicitations (#26409)
    Summary
    - Propagate cached remote plugin IDs through Codex plugin discovery.
    - Inject `remote_plugin_id` and connector IDs into
    `request_plugin_install` elicitation `_meta` from the resolved plugin.
    - Keep the remote plugin ID out of the model-facing tool schema,
    arguments, and result.
    
    Validation
    - `just test -p codex-tools`
    - `just test -p codex-core-plugins`
    - `just test -p codex-core
    list_tool_suggest_discoverable_plugins_includes_cached_remote_global_plugins`
    - `just fix -p codex-tools`
    - `just fix -p codex-core-plugins`
    - `just fix -p codex-core`
    - `git diff --check`
    - `just test -p codex-core` was also attempted: 2,581 passed, 55 failed,
    and 1 timed out across unrelated sandbox/environment-sensitive
    integration tests.
  • [codex] Return workspace directory installed plugins (#27098)
    ## Summary
    
    - return installed `workspace-directory` remote plugins by default in
    `plugin/installed`
    - keep shared-with-me installed plugins gated behind `plugin_sharing`
    - filter remote installed plugin marketplaces by canonical marketplace
    name instead of coarse workspace scope
    
    ## Validation
    
    - `just fmt`
    - `just test -p codex-core-plugins`
    - `just test -p codex-app-server`
    - `just fix -p codex-core-plugins`
    - `just fix -p codex-app-server`
    - `$xin-build` targeted verification:
    - `just test -p codex-core-plugins
    build_remote_installed_plugin_marketplaces_from_cache_filters_by_marketplace_name`
    - `just test -p codex-app-server
    plugin_installed_includes_workspace_directory_without_plugin_sharing`
    - `just test -p codex-app-server
    plugin_installed_includes_remote_shared_with_me_plugins`
    - `just test -p codex-app-server
    plugin_list_omits_shared_with_me_kind_when_plugin_sharing_disabled`
  • [codex] Bound WSL local curated discovery (#26669)
    ## Context
    The installed-app suggestion expansion added in #24996 reads plugin
    details for trusted file-backed marketplace candidates because the list
    response does not include app ids. On Windows-backed WSL mounts, the
    local `openai-curated` checkout lives under `$CODEX_HOME/.tmp/plugins`,
    and those per-plugin detail reads can be very slow.
    
    Remote curated already has cached app ids, so it does not need the same
    local filesystem traversal.
    
    ## Summary
    - Keep only the WSL Windows-backed local `openai-curated` checkout on
    the legacy fallback/configured discovery path.
    - Preserve installed-app expansion for non-WSL file-backed marketplaces
    and remote curated.
    - Add focused tests for the WSL local curated path predicate.
    
    ## Test
    - `just test -p codex-core-plugins discoverable`
    - `just test -p codex-core plugins::discoverable::tests`
  • [codex] Move plugin discoverable logic into core-plugins (#25783)
    ## Summary
    - Move plugin discoverable recommendation filtering from `codex-core`
    into `codex-core-plugins` behind `ToolSuggestPluginDiscoveryInput`.
    - Keep `codex-core` as a thin adapter from `Config` to the core-plugins
    API and back to `DiscoverablePluginInfo`.
    - Keep the existing discoverable allowlist private to the core-plugins
    implementation.
    
    ## Validation
    - `just fmt`
    - `just test -p codex-core list_tool_suggest_discoverable_plugins`
    - `git diff --check`
    - Read-only subagent review: no findings