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

feat: [Orchestration] Configuration as JSON String #177

Merged
merged 8 commits into from
Nov 25, 2024

Conversation

MatKuhr
Copy link
Member

@MatKuhr MatKuhr commented Nov 21, 2024

Context

This PR adds a feature to directly use JSON as downloaded from AI Launchpad.

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

@MatKuhr MatKuhr added the please-review Request to review a pull-request label Nov 21, 2024
Comment on lines +168 to +171
if (!prompt.getMessages().isEmpty()) {
throw new IllegalArgumentException(
"Prompt must not contain any messages when using a JSON module configuration, as the template is already defined in the JSON.");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

An OrchestrationPrompt is not the right object then. Why not accept a map of input params?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because that is missing the (optional) messages history.

OrchestrationPrompt is not the right object

I'd argue it is. We will have further cases where passing messages is not allowed, e.g. when using TemplateRef. If we want we could create another Prompt object for that to make this distinction, but so far I figured it's not worth it.

Copy link
Contributor

@jjtang1985 jjtang1985 left a comment

Choose a reason for hiding this comment

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

I left some comments.

docs/guides/ORCHESTRATION_CHAT_COMPLETION.md Show resolved Hide resolved
void testExecuteRequestFromJson() {
stubFor(post(anyUrl()).willReturn(okJson("{}")));

prompt = new OrchestrationPrompt(Map.of());
Copy link
Contributor

Choose a reason for hiding this comment

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

I would make the prompt as optional parameter.

Copy link
Member Author

@MatKuhr MatKuhr Nov 21, 2024

Choose a reason for hiding this comment

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

It's not optional, it has to be given. In this unit test I'm just skipping the effort to give params in the map

Copy link
Contributor

@jjtang1985 jjtang1985 Nov 21, 2024

Choose a reason for hiding this comment

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

It's not optional, it has to be given.

You are right, so we can discuss the API signature/design 😄

Please have a look at the following json, that I copied from the Launchpad.

{
    "module_configurations": {
        "llm_module_config": {
            "model_name": "mistralai--mistral-large-instruct",
            "model_params": {},
            "model_version": "2407"
        },
        "templating_module_config": {
            "template": [
                {
                    "role": "user",
                    "content": "How are you?"
                }
            ],
            "defaults": {}
        }
    }
}

I would assume, I've got everything from the JSON and should be able to run it with a function like

myFunction(json);

The second param (prompt in this case) is only needed (so it should be optional), when I want to pass a inputParam or provide message history like the following screenshot:

Screenshot 2024-11-21 at 20 55 47

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah true, Launchpad doesn't force you to use any variables. Okay, will update 👍🏻

Copy link
Member Author

Choose a reason for hiding this comment

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

After thinking about this again, I actually think the use case for this is not very strong. Because if there are no input params or messages history, prompt execution will always yield the same or very similar results (depending on the temperature setting).

The same is true when using template references. If we really want to support such usage, we could consider allowing new OrchestrationPrompt() for these cases. But making the prompt itself optional would mean we add 2-3 method overloads for non-productive cases..

* @return The completion response.
* @throws OrchestrationClientException If the request fails.
*/
@Beta
Copy link
Contributor

Choose a reason for hiding this comment

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

👍
Let's keep this as beta before the alignment with e.g., Launchpad.


var prompt = new OrchestrationPrompt(Map.of("your-input-parameter", "your-param-value"));

new OrchestrationClient().executeRequestFromJsonModuleConfig(prompt, configJson);
Copy link
Contributor

@newtork newtork Nov 22, 2024

Choose a reason for hiding this comment

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

Your suggested code change results in the following three methods on client:

OrchestrationClient client = new OrchestrationClient();

// execute completion request (exist)
CompletionPostRequest requestDto;
CompletionPostResponse responseDto = client
  .executeRequest(
    requestDto);

// execute prompt (exist)
OrchestrationPrompt promptConvenience;
OrchestrationModuleConfig configConvenience;
OrchestrationChatResponse responseConvenience = client
  .executeRequest(
    promptConvenience,
    configConvenience);

// execute prompt (new)
OrchestrationPrompt promptConvenience;
String configJson;
OrchestrationChatResponse responseConvenience = client
  .executeRequestFromJsonModuleConfig(
    promptConvenience,
    configJson);

(Question)

Is it not possible to derive reuse existing method and allow for OrchestrationModuleConfig to be created from String configJson? That would look a little cleaner, maybe(?)

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 also thought about this approach. But unfortunately not, because the JSON string is expected to contain things not yet supported by OrchestrationModuleConfig or it's individual config objects, i.e. throughout the entire JSON. That includes cases of oneOf, e.g. TemplateRef.

throw new IllegalArgumentException(
"The provided module configuration is not valid JSON: " + moduleConfig, e);
}
requestJson.set("orchestration_config", moduleConfigJson);
Copy link
Contributor

@newtork newtork Nov 25, 2024

Choose a reason for hiding this comment

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

(Major/Question)

Not sure, but wouldn't it make more sense applying the module config JSON to client instead of per request?

Seems like the only place where orchestration_config is provided, it could also be an optional parameter that is passed along the convenience API(?)

(My hidden motivation is to challenge this method a little.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm not exactly sure what you mean.. Do you mean setting the config on the OrchestrationClient object instead? Or something else?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes.
Boiling this down to the question: Is orchestration_config to be expected request specific or client specific?

Copy link
Member Author

@MatKuhr MatKuhr Nov 25, 2024

Choose a reason for hiding this comment

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

Essentially same as the OrchestrationConfig object: It depends how much, if any, config changes per request. But the tendency is it is tied to the client, i.e. for typical use cases the majority of config will stay the same across multiple requests.

However, we decided to not allow config per client to make the API simpler. So the same strategy is applied for this method too. If we want to, we can still change this in the future though.

Copy link
Contributor

@newtork newtork Nov 25, 2024

Choose a reason for hiding this comment

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

Understood.

To me, from a user perspective, it would feel weird to pass a String object along (over multiple controller classes potentially) just to pass to my request invocations.

But it's difficult to argue about client / request specific data handling, when I haven't yet seen a proper use-case "in the wild". Maybe we will discuss this again, after having users first interact with that.

@MatKuhr MatKuhr merged commit 918e12c into main Nov 25, 2024
5 checks passed
@MatKuhr MatKuhr deleted the feat/orchestration-string-config branch November 25, 2024 12:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
please-review Request to review a pull-request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants