Skip to content

feat: Responses API#1420

Draft
Oleksii-Klimov wants to merge 9 commits intodevelopmentfrom
feat/responses
Draft

feat: Responses API#1420
Oleksii-Klimov wants to merge 9 commits intodevelopmentfrom
feat/responses

Conversation

@Oleksii-Klimov
Copy link
Contributor

Initial support for Responses API.

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle


Buffer requestBody = context.getRequestBody();
proxyRequest.putHeader(HttpHeaders.CONTENT_LENGTH, Integer.toString(requestBody.length()));
context.getRequestHeaders().forEach(proxyRequest::putHeader);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you remove the line?

Copy link
Contributor Author

@Oleksii-Klimov Oleksii-Klimov Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't do anything. I removed the field.

if (!Strings.CI.contains(contentType, Proxy.HEADER_CONTENT_TYPE_APPLICATION_JSON)) {
return respond(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "Only application/json is supported");
}
return proxy.getTaskExecutor().submit(() -> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need to run the block asynchronously.

Copy link
Contributor Author

@Oleksii-Klimov Oleksii-Klimov Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

context.getRequest().body()
.compose(body -> {
log.info("Received body from client. Length: {}", body.length());
return proxy.getTaskExecutor().submit(() -> parseBody(body));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same thing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


private void sendRequest() {
UpstreamRoute route = context.getUpstreamRoute();
try {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the block should be in a separate method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved.

Buffer responseBody = context.getResponseStream().getContent();
context.setResponseBody(responseBody);
context.setResponseBodyTimestamp(System.currentTimeMillis());
Future<TokenUsage> tokenUsageFuture = collectTokenUsage(responseBody);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the method supports collecting token usage for responses API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does. At least structurally, the usage section is similar and contains information that was previously available. I’ve updated the aliases to pick up the new field names.
https://developers.openai.com/api/reference/resources/responses#(resource)%20responses%20%3E%20(model)%20response_usage%20%3E%20(schema)

if (result.failed()) {
log.warn("Failed to collect token usage", result.cause());
}
return collectResponseAttachments(responseBody);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the same thing for collecting attachments from responseAPI response

context.getResponse().reset(); // drop connection, so that partial client response won't seem complete
log.warn("Can't send response to client. Error:", error);
Deployment deployment = context.getDeployment();
if (deployment instanceof Model) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block should be revised for response API because it's tied to collecting token usage.

public enum RouteTemplate {

// OpenAI API routes
RESPONSES(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename to something meaningful at least LLM_RESPONSES_API
response is vague.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed.

.map(apiKeyData -> new AuthorizationResult(apiKeyData, null));
}

if (apiKey == null && authorization.startsWith("Bearer ")) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That may break authN flow for another IdP like Google. They send an opaque token instead of JWT.

return new ProxyContext(proxy, config, request, newApiKeyData, extractedClaims, traceId, spanId, traceFlags);
}

public Future<HttpClientRequest> createProxyRequest(Function<Deployment, String> endpointSelector) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would move to BaseDeploymentController instead of making them available for any controller.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved.

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

@ai-dial-actions
Copy link
Contributor

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 2 package(s) with unknown licenses.
See the Details below.

License Issues

settings.gradle

PackageVersionLicenseIssue Type
com.gradle:common-custom-user-data-gradle-plugin2.1NullUnknown License
com.gradle:develocity-gradle-plugin4.3.1NullUnknown License

OpenSSF Scorecard

PackageVersionScoreDetails
maven/com.gradle:common-custom-user-data-gradle-plugin 2.1 UnknownUnknown
maven/com.gradle:develocity-gradle-plugin 4.3.1 UnknownUnknown

Scanned Files

  • settings.gradle

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants