Make /api/v1/responses accept openresponses clients.

378127e9647c · AtlantisPleb · · parent 0e7b80fa0786

Make /api/v1/responses accept openresponses clients.

- Add :openresponses_api pipeline without the json-only accepts check
- Fill the full ResponseResource shape the openresponses-rust client
  expects: tools, tool_choice, truncation, text format, usage details, etc.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-Authored-By
Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

Not deployed through the forge lane

No push, promotion, build, or deploy receipt references this commit (receipts are scanned over a bounded recent window). Changes shipped by full node replacement carry their proof in the release gate receipt instead.

Changed files

  • modified lib/openagents_web/controllers/responses_controller.ex
  • modified lib/openagents_web/router.ex

Diff

2 files changed, +37 -6

lib/openagents_web/controllers/responses_controller.ex modified +28 -5

@@ -494,7 +494,27 @@ defmodule OpenAgentsWeb.ResponsesController do

494 494
      "model" => model_name,
495 495
      "output" => output,
496 496
      "error" => nil,
497
      "usage" => %{"input_tokens" => 0, "output_tokens" => 0, "total_tokens" => 0}
497
      "tools" => [],
498
      "tool_choice" => "none",
499
      "truncation" => "disabled",
500
      "parallel_tool_calls" => false,
501
      "text" => %{"format" => %{"type" => "text"}},
502
      "top_p" => 1.0,
503
      "presence_penalty" => 0.0,
504
      "frequency_penalty" => 0.0,
505
      "top_logprobs" => 0,
506
      "temperature" => 1.0,
507
      "store" => false,
508
      "background" => false,
509
      "service_tier" => "auto",
510
      "metadata" => %{},
511
      "usage" => %{
512
        "input_tokens" => 0,
513
        "output_tokens" => 0,
514
        "total_tokens" => 0,
515
        "input_tokens_details" => %{"cached_tokens" => 0},
516
        "output_tokens_details" => %{"reasoning_tokens" => 0}
517
      }
498 518
    }
499 519
  end
500 520

@@ -525,13 +545,16 @@ defmodule OpenAgentsWeb.ResponsesController do

525 545
  defp usage_view(usage) do
526 546
    input = whole(usage["input_tokens"])
527 547
    output = whole(usage["output_tokens"])
548
    cached = whole(usage["cached_tokens"]) || 0
549
    reasoning = whole(usage["reasoning_tokens"]) || 0
528 550
529 551
    %{
530
      "input_tokens" => input,
531
      "output_tokens" => output,
532
      "total_tokens" => whole(usage["total_tokens"]) || (input || 0) + (output || 0)
552
      "input_tokens" => input || 0,
553
      "output_tokens" => output || 0,
554
      "total_tokens" => whole(usage["total_tokens"]) || (input || 0) + (output || 0),
555
      "input_tokens_details" => %{"cached_tokens" => cached},
556
      "output_tokens_details" => %{"reasoning_tokens" => reasoning}
533 557
    }
534
    |> Map.new(fn {key, value} -> {key, value || 0} end)
535 558
  end
536 559
537 560
  defp whole(value) when is_integer(value) and value >= 0, do: value
lib/openagents_web/router.ex modified +9 -1

@@ -74,6 +74,14 @@ defmodule OpenAgentsWeb.Router do

74 74
    plug OpenAgentsWeb.Plugs.AmbientApiTokenAuth, scope: "chat:account"
75 75
  end
76 76
77
  # OpenResponses surface. The client can ask for `text/event-stream`
78
  # (streaming) or `application/json` (non-streaming), so this pipeline does
79
  # not pin `accepts` to a single format.
80
  pipeline :openresponses_api do
81
    plug OpenAgentsWeb.Plugs.RequestOrigin
82
    plug OpenAgentsWeb.Plugs.AmbientApiTokenAuth, scope: "chat:account"
83
  end
84
77 85
  pipeline :box_control_api do
78 86
    plug :accepts, ["json"]
79 87
    plug OpenAgentsWeb.Plugs.RequestOrigin

@@ -511,7 +519,7 @@ defmodule OpenAgentsWeb.Router do

511 519
  # grants nothing and refuses nobody; see
512 520
  # `OpenAgentsWeb.Plugs.AmbientApiTokenAuth`.
513 521
  scope "/api/v1", OpenAgentsWeb do
514
    pipe_through :ambient_account_api
522
    pipe_through :openresponses_api
515 523
516 524
    post "/responses", ResponsesController, :create
517 525
  end

This page updates live while a promote is in flight · changelog