Skip to content

Conversation

@rpanackal
Copy link
Member

@rpanackal rpanackal commented Jan 27, 2025

Context

AI/ai-sdk-java-backlog#172.

We would like start using generated model classes for OpenAI module to keep up with spec changes easier.

Previously, thanks to Charles, we had a beautiful convenience API+model classes in place. But, we are migrating away from current convenience API to achieve parity with orchestration module. This equates to breaking changes.

100% convenience parity seems difficult due how both modules should treat ai model parameter configuration.

Model Parameter Configuration

Under orchestration scenario, the ai model itself is selected on a per request level. While, in foundation-model scenario, we have a deployment specific to a model, while parameters alone (eg: temperature) are altered per request.

=> parameters scoping under a model, like in OrchestrationAiModel class, is not sensible in OpenAI convenience API.

Feature scope:

  • Convenient request, response and error classes
  • Convenient message classes (to match orchestration)
  • Code reduction in OpenAiChatCompletionDelta
  • Reduce num of mixins

Definition of Done

  • Functionality scope stated & covered
  • Tests cover the scope above
  • Error handling created / updated & covered by the tests above
  • Aligned changes with the JavaScript SDK
  • Documentation updated
  • Release notes updated

a-d and others added 25 commits January 8, 2025 09:47
# Conflicts:
#	foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClient.java
…-openai

# Conflicts:
#	foundation-models/openai/src/main/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiChatCompletionDelta.java
#	foundation-models/openai/src/test/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClientTest.java
# Conflicts:
#	foundation-models/openai/src/test/java/com/sap/ai/sdk/foundationmodels/openai/OpenAiClientTest.java
- createDTO need to be more limited in access
…onse only

- Reasoning: to remove casting and include future changes

Note: Dependent on prev manual change of generated model class
- No tooling/function api yet
- No user-image/user-text message api
…able-conv-generated-openai

# Conflicts:
#	foundation-models/openai/pom.xml
@rpanackal rpanackal changed the title chose: [OpenAI] Stable Convenience API for OpenAI chore: [OpenAI] Stable Convenience API for OpenAI Jan 27, 2025
- No args constructor is invalid as empty list of messages in payload is invalid
- java docs and unit tests
- message convenience missing multipart
* @throws OpenAiClientException
*/
@Nonnull
public OpenAiChatCompletionOutput chatCompletion(@Nonnull final OpenAiChatCompletionPrompt prompt)
Copy link
Contributor

@newtork newtork Jan 31, 2025

Choose a reason for hiding this comment

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

(Major)

I like the convenient options you offer to the user!

But I think we should discuss API design, your branch assumes four methods for regular chat completion and four additional methods for streamed chat completion. That feels a bit much. In orchestration it's three/two - which is also not great.

Currently I'm considering to pitch a two layer-approach similar to what we have in SAP Cloud SDK for OData v2/v4 -> Generic OData Client. Unfortunately we don't have it nicely-documented. But the gist is: You can use the high-level API (convenience API) on the regular client, but if you know what you're doing and want to use the low-level API (generated model classes), you would access a second API level via new OpenAiClient(...).custom() that only allows model classes. Though I'm not sure about method naming here.

The API quality was improved significantly that way.


I'm open to have this discussion in a separate PR / ticket.

Copy link
Member Author

Choose a reason for hiding this comment

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

I felt the same way that there are too many chatCompletion methods and agree that we need to find a way to minimise this.

@Beta
@Value
@AllArgsConstructor(onConstructor = @__({@JsonCreator}), access = AccessLevel.PROTECTED)
public class OpenAiError implements ClientError {
Copy link
Contributor

@newtork newtork Jan 31, 2025

Choose a reason for hiding this comment

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

(Comment/Opinion)

I'm unhappy about the interface name "ClientError", since "Error" is reserved for non-recoverable exceptions leading to application shutdown.

No action required.

@rpanackal rpanackal changed the base branch from generated-openai to main January 31, 2025 14:16
/** Factory class for creating OpenAI Embedding Requests. */
@Accessors(fluent = true)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class OpenAiEmbeddingsRequestFactory {
Copy link
Contributor

Choose a reason for hiding this comment

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

(Minor)

I don't think we'll support this public API in that shape:

  • I think it should be @Beta
  • "Factory" name is discouraged
  • (Instead) rather have convenience class for embedding-create-request, that can be instantiated via String(s). Then we wouldn't need this class.

Copy link
Member Author

@rpanackal rpanackal Feb 3, 2025

Choose a reason for hiding this comment

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

Apart from the naming, can you expand a bit on why this is not a good approach?

My initial approach was what you suggested but later moved to the current state for the following reasons:

  1. Avoid duplication of model class
  2. User can call setters for generated model fields on top
  3. Avoid adding an additional method in client (getting bloated) for accepting high level api object for embedding
  4. In case, embedding become a bigger topic, we can add further static factory methods that returns a new convenience objects.

I might be missing some issue(s) that you are seeing.

@rpanackal rpanackal removed the please-review Request to review a pull-request label Feb 4, 2025
- keep completion and embedding calls with old api in client
- Keep tests
- improve test for reusability
@rpanackal rpanackal changed the title chore: [OpenAI] Stable Convenience API for OpenAI feat: [OpenAI] Stable Convenience API for OpenAI Feb 6, 2025
@rpanackal rpanackal changed the base branch from main to chore/openai-gen-code February 6, 2025 12:18
@rpanackal rpanackal force-pushed the chore/openai-gen-code branch from ec7e58d to 18b795b Compare February 6, 2025 12:35
@rpanackal
Copy link
Member Author

This PR has been split into two new ones

  1. feat: [OpenAI] Generated model classes for OpenAI client #322
  2. feat: [OpenAI] Stable convenience - Latest  #323

This conversation is now closed, but continued on the new PRs.

@rpanackal rpanackal closed this Feb 6, 2025
@CharlesDuboisSAP CharlesDuboisSAP deleted the chore/stable-conv-generated-openai branch February 20, 2025 09:01
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.

5 participants