Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow specifying the organizationId in the configuration #197

Merged
merged 1 commit into from
Jan 4, 2024

Conversation

edeandrea
Copy link
Collaborator

See https://platform.openai.com/docs/api-reference/organization-optional - allow the organizationId to be specified in the configuration.

Fixes #131

@edeandrea edeandrea requested a review from a team as a code owner January 2, 2024 19:19
@edeandrea
Copy link
Collaborator Author

Just an implementation note. In OpenAiRestApi I didn't add an @ClientHeaderParam annotation because then I would have had to modify every method signature to add a @NotBody String organizationId parameter to it. I thought instead adding a ResteasyReactiveClientRequestFilter that conditionally added the header would be a better/cleaner approach.

@geoand
Copy link
Collaborator

geoand commented Jan 2, 2024

Thanks for this.

I'll have to think about this, I'm not really a fan of the filter for this case.

This might be an opportunity actually to improve the REST Client...
But like I said, I have to think about it 🙂

@edeandrea
Copy link
Collaborator Author

Yeah I'd much prefer to have just the annotation as well, but I thought having to add an extra method parameter to every method, when a lot of the time the value is null wasn't the best option either. This way, the filter is only ever added to the chain if the value is even specified, which is better IMO.

@edeandrea edeandrea force-pushed the add-organization-id branch from 91ef38e to c418ab4 Compare January 2, 2024 19:30
@geoand
Copy link
Collaborator

geoand commented Jan 2, 2024

The thing is that I don't want to have two different approaches for the parameters if it can be avoided.

I'm thinking about some improvements to the @BeanParam support of the REST Client (I think we support it, but I could be mistaken) that could apply in this case

@edeandrea
Copy link
Collaborator Author

I thought about making the filter more generic as well, something like a ClientHeaderFilter where we could configure it with different headers, rather than a specific filter for each set of headers we might want. But for now I kept it simple.

Some of the other edits (like transforming annonymous class instances to lambdas) we done by IntelliJ automatically. I can turn that off and revert those changes if you'd prefer.

@geoand
Copy link
Collaborator

geoand commented Jan 2, 2024

Yeah, no lambdas please 🙂.

But in any case, I need to look into what I mentioned above before moving this ahead

@edeandrea
Copy link
Collaborator Author

Yeah, no lambdas please

Ok I'll revert that. Can I ask why?

I feel like

return builder::build;

is way cleaner than

return new Supplier<>() {
            @Override
            public Object get() {
                return builder.build();
            }
        };

and

public void cleanUp(ShutdownContext shutdown) {
     shutdown.addShutdownTask(QuarkusOpenAiClient::clearCache);
}

is way cleaner than

    public void cleanUp(ShutdownContext shutdown) {
        shutdown.addShutdownTask(new Runnable() {
            @Override
            public void run() {
                QuarkusOpenAiClient.clearCache();
            }
        });
    }

@edeandrea edeandrea force-pushed the add-organization-id branch from 805be07 to 3ed437d Compare January 2, 2024 19:52
@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

Ok I'll revert that. Can I ask why?

Certainly!
The reason is that early on during Quarkus' development, we found that when a larger number of lambdas where bootstrapped during application initialization, startup time and RSS took a small hit.

There is no doubt that the lambdas and method references look cleaner in this case, it's just a case of us trying to eliminate lambdas in runtime code as much as possible.

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

Assuming

works fine (it works just fine in whatever test I ran), this should be rebased onto it and it will become simpler

@edeandrea
Copy link
Collaborator Author

I'll take a look at that and rebase onto this. Had somewhat of a pet medical emergency today so I might not get to it until tomorrow.

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

Hopefully your pet will be fine!

@edeandrea edeandrea force-pushed the add-organization-id branch from 3ed437d to 4e751eb Compare January 3, 2024 17:11
@edeandrea
Copy link
Collaborator Author

Thanks!

So I started rebasing this and saw what you did with the ApiMetadata metadata class and @BeanParam. Question - this organizationId header is optional, meaning that it shouldn't always be set/sent, and should never be sent in the Azure OpenAI case.

If I add another @HeaderParam value in the class, will that value be sent if the value is null?

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

A header (or whatever) will not be sent if the value is null

@edeandrea
Copy link
Collaborator Author

A header (or whatever) will not be sent if the value is null

Thats what I needed to know. I'll work on this new integration now.

Just a thought - instead of adding a new method parameter to public static ApiMetadata of(String apiKey, String apiVersion) what if I instead created a builder for the ApiMetaData? That way in the future whenever we want to add new things we don't have to touch everywhere in the codebase where we use that specific method?

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

Yeah, we can certainly have a builder, but we need to be careful of how the key translates to the two headers

@edeandrea
Copy link
Collaborator Author

Yeah, we can certainly have a builder, but we need to be careful of how the key translates to the two headers

I'll put something together and you can review.

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

👌

@edeandrea edeandrea force-pushed the add-organization-id branch from 3466d49 to 4fae868 Compare January 3, 2024 18:00
@edeandrea
Copy link
Collaborator Author

Just pushed changes. Let me know what you think.

@edeandrea edeandrea force-pushed the add-organization-id branch from 1029f5a to 73e477a Compare January 3, 2024 18:04
Copy link
Collaborator

@geoand geoand left a comment

Choose a reason for hiding this comment

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

I added a minor comment.

Also, it would be nice to have the commits squashed

import static org.acme.example.openai.MessageUtil.createChatCompletionRequest;
import static org.acme.example.openai.MessageUtil.createCompletionRequest;
import static org.acme.example.openai.MessageUtil.createEmbeddingRequest;
import static org.acme.example.openai.MessageUtil.*;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd prefer we don't use star imports

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I ran mvn impsort:sort from the project root and thats what it produced. If I commit without running that then the build fails saying I need to run it...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting

Fixes quarkiverse#131

# Conflicts:
#	openai/openai-vanilla/runtime/src/main/java/io/quarkiverse/langchain4j/openai/runtime/OpenAiRecorder.java
@edeandrea edeandrea force-pushed the add-organization-id branch from eb58e52 to 2d5e148 Compare January 3, 2024 18:08
@edeandrea
Copy link
Collaborator Author

Also, it would be nice to have the commits squashed

They are. Maybe you were looking at it just as I was squashing.

Copy link
Collaborator

@geoand geoand left a comment

Choose a reason for hiding this comment

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

Thanks a lot!

@edeandrea
Copy link
Collaborator Author

Thanks a lot!

You're welcome! I like the builder approach coupled with the metadata @BeanParam. I think its nice and flexible.

I'll still agree to disagree that

if (someOptional.isPresent()) {
  someOptional.get();
}

is an anti-pattern.

Optional<String> apiKeyOpt = runtimeConfig.apiKey();
if (apiKeyOpt.isEmpty()) {
    throw new ConfigValidationException(createApiKeyConfigProblems());
}
ChatModelConfig chatModelConfig = runtimeConfig.chatModel();
var builder = OpenAiChatModel.builder()
        .apiKey(apiKeyOpt.get());

would be much better as

var apiKey = runtimeConfig.apiKey()
    .orElseThrow(() -> new ConfigValidationException(createApiKeyConfigProblems()));
ChatModelConfig chatModelConfig = runtimeConfig.chatModel();
var builder = OpenAiChatModel.builder()
        .apiKey(apiKey);

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

I don't think I said it's an antipattern.
I definitely did say that for reasons of runtime footprint we avoid lambdas wherever possible

@edeandrea
Copy link
Collaborator Author

I don't think I said it's an antipattern.

No, I don't think you did. I'm saying it is :)

@edeandrea
Copy link
Collaborator Author

Not sure why the native java 21 build is failing. Its timing out when creating the binary. I've seen that happen in other apps for java 21. Takes longer to build the image.

@geoand
Copy link
Collaborator

geoand commented Jan 3, 2024

That's a bug in GraalVM that we need to address.

Not related to this PR

@geoand geoand merged commit d0e6c18 into quarkiverse:main Jan 4, 2024
1 of 2 checks passed
@edeandrea edeandrea deleted the add-organization-id branch January 4, 2024 12:48
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.

Allow for specifying the organization id in the configuration
2 participants