Skip to content

[bug] Devin drops namespaced client tool identity and rejects CUA js #4456

Description

@jeongjin0

Client or integration

Codex App

Provider or upstream service

Devin / Cognition cloud-direct (devin, model swe-2)

OpenCodex version

@bitkyc08/opencodex 2.52.0 and dev at dc33113a9

Endpoint or capability

/v1/responses streaming client tool calls with namespaced MCP tools

Current behaviour

The Devin adapter advertises every tool to Cognition as the local tool.name, dropping its Codex namespace. For a request that declares CUA as mcp__cua_repl__js, Cognition sees and returns js. runTurn forwards that bare name unchanged, while the Responses bridge authorizes the canonical request name. The fail-closed guard then terminates the turn with HTTP 502.

Redacted local observations on 2026-09-13 recorded 14 identical 502s across four conversations from devin/swe-2 between 12:28 and 12:33 KST.

Expected behaviour

When Devin returns a bare tool name that uniquely identifies one request tool, the adapter should restore the request's canonical wire identity before the shared Responses bridge validates and dispatches it. A bare name shared by multiple request tools must fail without choosing by declaration order. Unknown names must remain subject to the existing undeclared-tool guard.

Minimal redacted request or reproduction

# OpenCodex 2.52.0, Codex CLI/App 0.154.0
# Route a Codex task through devin/swe-2 with the CUA MCP tool declared as:
#   namespace: mcp__cua_repl
#   name: js
# Ask the model to continue a browser/UI task that requires that tool.
# The adapter sends Cognition the bare name "js" and returns the same bare name.

Actual response or error

stream disconnected before completion: routed provider emitted undeclared client tool "js"; only request-declared tools may be called

Upstream documentation

Cognition's cloud-direct Connect-RPC endpoint has no public tool-naming specification. The concrete client contract is the Responses request catalog: the client declared mcp__cua_repl__js, and OpenCodex must preserve that tool identity across an adapter that intentionally advertises its local name upstream.

Relevant source on dev: src/adapters/devin.ts maps tools with name: tool.name and emits event.name unchanged. The shared bridge uses namespacedToolName(namespace, name) as the authorized wire identity.

Suggested mapping or implementation notes

Build a request-scoped map from each advertised local name to namespacedToolName(tool.namespace, tool.name). Restore only uniquely owned names on tool_call_start. Represent collisions explicitly and emit a non-retryable adapter error before dispatch; preserve unknown names for the shared fail-closed guard.

Keep Cognition's current bare-name request contract and catalog nudge unchanged. This makes the response half symmetric without broadly authorizing bare aliases in the provider-independent bridge.

Additional context and attachments

Checks

  • I searched existing provider and compatibility issues.
  • The request and response were redacted.
  • The expected behaviour is based on an upstream specification or a concrete client requirement.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    providerProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reportstoolstool_calls, MCP, web-search / sidecar tools

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions