-
Notifications
You must be signed in to change notification settings - Fork 155
Prompt Management Create API #3779
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
base: feature/prompt
Are you sure you want to change the base?
Prompt Management Create API #3779
Conversation
Apply spotless: |
import java.io.IOException; | ||
import java.io.UncheckedIOException; | ||
|
||
import org.opensearch.ml.common.utils.IndexUtils; | ||
|
||
import static org.opensearch.ml.common.CommonValue.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't use * in import. Disable wilecard import: https://www.baeldung.com/intellij-disable-wildcard-import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it. Thank you!
if (tag != null) { | ||
builder.field(TAG_FIELD, tag); | ||
} | ||
if (createTime != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tenantid is missing here.
.build(); | ||
} | ||
|
||
/*public void update(MLCreatePromptInput updateContent) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we remove this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not commit my changes frequently while working on this project. To avoid ending up with a large PR that would be difficult for reviewers to go through, I am creating multiple smaller PRs instead.
So, I am manually commenting out unrelated code so that each PR stays focused on a specific topic. I will be using this method for Update api.
…mpanied by text (opensearch-project#3755) * fix: handle model response when toolUse is not accompanied by text Signed-off-by: Pavan Yekbote <[email protected]> * feat: add test case for parseLLMOutput Signed-off-by: Pavan Yekbote <[email protected]> --------- Signed-off-by: Pavan Yekbote <[email protected]>
…ent empty response (opensearch-project#3756) * fix: expose max_iteration for react Signed-off-by: Pavan Yekbote <[email protected]> * fix: defaults for agent execution and differentiate between step and step result Signed-off-by: Pavan Yekbote <[email protected]> * fix: return react agent id in agent response to expose more details Signed-off-by: Pavan Yekbote <[email protected]> * spotless Signed-off-by: Pavan Yekbote <[email protected]> * fix: remove test prompt from react system prompt Signed-off-by: Pavan Yekbote <[email protected]> * refactor: rename parameters exposed to user to executor Signed-off-by: Pavan Yekbote <[email protected]> * fix: give user complete control over planner system prompt Signed-off-by: Pavan Yekbote <[email protected]> --------- Signed-off-by: Pavan Yekbote <[email protected]>
Signed-off-by: rithin-pullela-aws <[email protected]>
@ohltyler, Hey Tyler, This is my first draft PR for CREATE API for pormpt management:) |
|
||
@Getter | ||
@EqualsAndHashCode | ||
public class MLPrompt implements ToXContentObject, Writeable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add java doc for every class and main method so that it's readable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a new file, a header is needed. Check the other classes and copy the header in all new files.
/*
- Copyright OpenSearch Contributors
- SPDX-License-Identifier: Apache-2.0
*/
} | ||
|
||
public MLPrompt(StreamInput input) throws IOException { | ||
Version streamInputVersion = input.getVersion(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the version a mandatory field?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think the version should be a mandatory field, and should throw an error if the version field is not provided by the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we do version has a default one if no version is required? I would assume when I don't put a version, it has an initial version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I will make the version field optional. Thank you!
this.prompt = input.readMap(s -> s.readString(), s -> s.readString()); | ||
} | ||
this.tag = input.readOptionalString(); | ||
tenantId = streamInputVersion.onOrAfter(VERSION_2_19_0) ? input.readOptionalString() : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.tenantId?
|
||
private void indexPrompt(MLPrompt prompt, ActionListener<MLCreatePromptResponse> listener) { | ||
log.info("prompt created, indexing into the prompt system index"); | ||
mlIndicesHandler.initMLPromptIndex(ActionListener.wrap(indexCreated -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when creating the index, do you have validation to check if the prompt id is existed? can you create a prompt twice with the same prompt id?
also thinking can user create two prompt with the same name? have you consider the scenarios?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I decided to make prompt create api consistent as the other create apis, like connector. I noticed that the connector_id is set to a document id that is generated when a new document is stored in index. So, I followed the same mechanism without including any validation checks on promptId, since we are not manually creating one. Naming as well, other ml-commons features such as connector and model don't have a unique name and do not throw any errors when existing name is used.
"type": "text" | ||
}, | ||
"prompt": { | ||
"type": "flat_object" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are you trying add tags later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exciting work so far lets keep it up! 😄
@@ -119,6 +123,7 @@ public void initMLIndexIfAbsent(MLIndex index, ActionListener<Boolean> listener) | |||
log.debug("index:{} is already created", indexName); | |||
if (indexMappingUpdated.containsKey(indexName) && !indexMappingUpdated.get(indexName).get()) { | |||
shouldUpdateIndex(indexName, index.getVersion(), ActionListener.wrap(r -> { | |||
log.info("r is " + r); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now looking back is this a log for your dev purpose? If so lets delete it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^
out.writeOptionalString(name); | ||
out.writeOptionalString(description); | ||
if (prompt != null) { | ||
out.writeBoolean(true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its not to clear what field this boolean pertains to I'm assuming its a update version sort of boolean can we refactor so we assign some variable affected by this to make it clear to the reader what is this related to?
String description, | ||
Map<String, String> prompt, | ||
String tag, | ||
boolean dryRun, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whats your interpretation of dryRun?
Version streamInputVersion = input.getVersion(); | ||
name = input.readOptionalString(); | ||
description = input.readOptionalString(); | ||
if (input.readBoolean()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updatePrompt = input.readBoolean();
if(updatePrompt){
// Read from streamInput logic
}
tag = input.readOptionalString(); | ||
dryRun = input.readBoolean(); | ||
if (streamInputVersion.onOrAfter(VERSION_2_19_0)) { | ||
input.readOptionalString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we read here and not use and not store does this advance to the next item?
public ActionRequestValidationException validate() { | ||
ActionRequestValidationException exception = null; | ||
if (mlCreatePromptInput == null) { | ||
exception = addValidationError("ML Prompt input can't be null", exception); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- If this string gets used over
"ML Prompt input can't be null
lets put it in a file to reference later if you intend to reuse the string over other actions/methods.
|
||
private static final Version MINIMAL_SUPPORTED_VERSION_FOR_CLIENT_CONFIG = CommonValue.VERSION_2_13_0; | ||
|
||
public static final String DRY_RUN_PROMPT_NAME = "dryRunPrompt"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Walk me though this variable what are its implications I see this variable used a lot "dryRyn*"
try (ThreadContext.StoredContext context = client.threadPool().getThreadContext().stashContext()) { | ||
prompt.setCreateTime(Instant.now()); | ||
prompt.setLastUpdateTime(Instant.now()); | ||
sdkClient |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets do some refactoring to avoid callback hell
|
||
@Getter | ||
@EqualsAndHashCode | ||
public class MLPrompt implements ToXContentObject, Writeable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is a new file, a header is needed. Check the other classes and copy the header in all new files.
/*
- Copyright OpenSearch Contributors
- SPDX-License-Identifier: Apache-2.0
*/
this.name = name; | ||
this.description = description; | ||
this.prompt = prompt; | ||
this.tag = tag; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any of these shouldn't be null? I think at least the name shouldn't be null, so it's better to add validation here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call, I think name and prompt should not be null and force user to specify fields additionally do we think we ought to make prompt not be empty as well (@Rycho)?
if (!request.hasContent()) { | ||
throw new IOException("Create Prompt request has empty body"); | ||
} | ||
XContentParser parser = request.contentParser(); | ||
ensureExpectedToken(XContentParser.Token.START_OBJECT, parser.nextToken(), parser); | ||
MLCreatePromptInput mlCreatePromptInput = MLCreatePromptInput.parse(parser); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to either add validation in here or in the MLCreatePromptInput
* initial commit for MCP server in OpenSearch Signed-off-by: zane-neo <[email protected]> * Make change to support register or remove tools across cluster Signed-off-by: zane-neo <[email protected]> * format code Signed-off-by: zane-neo <[email protected]> * fix UT failure caused by code change Signed-off-by: zane-neo <[email protected]> * format code Signed-off-by: zane-neo <[email protected]> * format code Signed-off-by: zane-neo <[email protected]> * add license header Signed-off-by: zane-neo <[email protected]> * fix notifications initialized not respond issue Signed-off-by: zane-neo <[email protected]> * fix minor issues and add UTs Signed-off-by: zane-neo <[email protected]> * Add more UTs Signed-off-by: zane-neo <[email protected]> --------- Signed-off-by: zane-neo <[email protected]>
…3795) (cherry picked from commit 3f503f1) Signed-off-by: Peter Zhu <[email protected]> Co-authored-by: Peter Zhu <[email protected]>
* Increment version to 3.1.0-SNAPSHOT Signed-off-by: opensearch-ci-bot <[email protected]> * Update build.gradle Signed-off-by: Peter Zhu <[email protected]> --------- Signed-off-by: opensearch-ci-bot <[email protected]> Signed-off-by: Peter Zhu <[email protected]> Co-authored-by: opensearch-ci-bot <[email protected]> Co-authored-by: Peter Zhu <[email protected]>
Signed-off-by: Mingshi Liu <[email protected]>
* support MCP session management Signed-off-by: zane-neo <[email protected]> * Addressing comments Signed-off-by: zane-neo <[email protected]> * add feature flag for mcp server and renaming mcp connector feature flag Signed-off-by: zane-neo <[email protected]> * Address critical comments in opensearch-project#3781 Signed-off-by: zane-neo <[email protected]> --------- Signed-off-by: zane-neo <[email protected]>
* upgrade http client to versoin align with core Signed-off-by: zane-neo <[email protected]> * upgrade httpclient-h2 to correct versiono Signed-off-by: zane-neo <[email protected]> * use placeholder approach Signed-off-by: zane-neo <[email protected]> --------- Signed-off-by: zane-neo <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there; I think we should tweak the exception messages but other than that looks good to me
} | ||
if (!prompt.containsKey(PROMPT_FIELD_SYSTEM_PROMPT)) { | ||
throw new IllegalArgumentException("Prompt prompt field require system prompt"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar flow for ones in same method
throw new IllegalArgumentException("Prompt prompt field require system prompt"); | |
throw new IllegalArgumentException("MLPrompt prompt field requires {PROMPT_FIELD_SYSTEM_PROMPT} parameter"); |
@@ -166,7 +179,7 @@ public static MLCreatePromptInput parse(XContentParser parser, boolean updatePro | |||
break; | |||
} | |||
} | |||
return new MLCreatePromptInput(name, description, prompt, tag, tenantId, updatePrompt); | |||
return new MLCreatePromptInput(name, description, version, prompt, tags, tenantId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh can we not use the builder here?
private void handlePromptPutFailure(Exception cause, ActionListener<MLCreatePromptResponse> listener) { | ||
log.error("Failed to save ML Prompt", cause); | ||
private void handlePromptPutFailure(Exception cause, ActionListener<MLCreatePromptResponse> listener, String likelyCause) { | ||
log.error("Failed to save ML Prompt: {}", likelyCause, cause); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!!! This makes the method more user friendly do you think we can resuse the method elswhere?
public static final String PROMPT_FIELD_USER_PROMPT = "user"; | ||
public static final String PROMPT_FIELD_SYSTEM_PROMPT = "system"; | ||
|
||
private static final Version MINIMAL_SUPPORTED_VERSION_FOR_CLIENT_CONFIG = CommonValue.VERSION_2_13_0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, just fixed this :)
this.version = input.readOptionalString(); | ||
this.prompt = input.readMap(s -> s.readString(), s -> s.readString()); | ||
this.tags = input.readOptionalStringList(); | ||
this.tenantId = streamInputVersion.onOrAfter(VERSION_2_19_0) ? input.readOptionalString() : null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually do this type of check for the backward compatibility for the older versions. So I don't think we need this type of check here, as multi-tenancy feature is already published.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
got it!
Hey Ryan Lets add UTs for this PR :) |
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
Signed-off-by: seungwon cho <[email protected]>
2b5c24a
to
e97d7bb
Compare
Description
Implements an API to create prompt, and creates a new system index for prompt
Related Issues
Resolves #[Issue number to be closed when this PR is merged]
Check List
--signoff
.By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.