Skip to content

Commit

Permalink
Merge branch 'opensearch-project:main' into main_modelRegistry
Browse files Browse the repository at this point in the history
  • Loading branch information
rbhavna authored Oct 4, 2023
2 parents 144357a + 374b835 commit 74fbe08
Show file tree
Hide file tree
Showing 119 changed files with 13,288 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright 2023 Aryn
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensearch.ml.common.conversation;

/**
* Constants for conversational actions
*/
public class ActionConstants {

/** name of conversation Id field in all responses */
public final static String CONVERSATION_ID_FIELD = "conversation_id";

/** name of list of conversations in all responses */
public final static String RESPONSE_CONVERSATION_LIST_FIELD = "conversations";
/** name of list on interactions in all responses */
public final static String RESPONSE_INTERACTION_LIST_FIELD = "interactions";
/** name of interaction Id field in all responses */
public final static String RESPONSE_INTERACTION_ID_FIELD = "interaction_id";

/** name of conversation name in all requests */
public final static String REQUEST_CONVERSATION_NAME_FIELD = "name";
/** name of maxResults field name in all requests */
public final static String REQUEST_MAX_RESULTS_FIELD = "max_results";
/** name of nextToken field name in all messages */
public final static String NEXT_TOKEN_FIELD = "next_token";
/** name of input field in all requests */
public final static String INPUT_FIELD = "input";
/** name of AI response field in all respopnses */
public final static String AI_RESPONSE_FIELD = "response";
/** name of origin field in all requests */
public final static String RESPONSE_ORIGIN_FIELD = "origin";
/** name of prompt template field in all requests */
public final static String PROMPT_TEMPLATE_FIELD = "prompt_template";
/** name of metadata field in all requests */
public final static String ADDITIONAL_INFO_FIELD = "additional_info";
/** name of success field in all requests */
public final static String SUCCESS_FIELD = "success";

/** path for create conversation */
public final static String CREATE_CONVERSATION_REST_PATH = "/_plugins/_ml/memory/conversation";
/** path for list conversations */
public final static String GET_CONVERSATIONS_REST_PATH = "/_plugins/_ml/memory/conversation";
/** path for put interaction */
public final static String CREATE_INTERACTION_REST_PATH = "/_plugins/_ml/memory/conversation/{conversation_id}";
/** path for get interactions */
public final static String GET_INTERACTIONS_REST_PATH = "/_plugins/_ml/memory/conversation/{conversation_id}";
/** path for delete conversation */
public final static String DELETE_CONVERSATION_REST_PATH = "/_plugins/_ml/memory/conversation/{conversation_id}";

/** default max results returned by get operations */
public final static int DEFAULT_MAX_RESULTS = 10;

/** default username for reporting security errors if no or malformed username */
public final static String DEFAULT_USERNAME_FOR_ERRORS = "BAD_USER";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* Copyright 2023 Aryn
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensearch.ml.common.conversation;

import java.io.IOException;
import java.time.Instant;
import java.util.Map;
import java.util.Objects;

import org.opensearch.action.index.IndexRequest;
import org.opensearch.core.common.io.stream.StreamInput;
import org.opensearch.core.common.io.stream.StreamOutput;
import org.opensearch.core.common.io.stream.Writeable;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.search.SearchHit;

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
* Class for holding conversational metadata
*/
@AllArgsConstructor
public class ConversationMeta implements Writeable, ToXContentObject {

@Getter
private String id;
@Getter
private Instant createdTime;
@Getter
private String name;
@Getter
private String user;

/**
* Creates a conversationMeta object from a SearchHit object
* @param hit the search hit to transform into a conversationMeta object
* @return a new conversationMeta object representing the search hit
*/
public static ConversationMeta fromSearchHit(SearchHit hit) {
String id = hit.getId();
return ConversationMeta.fromMap(id, hit.getSourceAsMap());
}

/**
* Creates a conversationMeta object from a Map of fields in the OS index
* @param id the conversation's id
* @param docFields the map of source fields
* @return a new conversationMeta object representing the map
*/
public static ConversationMeta fromMap(String id, Map<String, Object> docFields) {
Instant created = Instant.parse((String) docFields.get(ConversationalIndexConstants.META_CREATED_FIELD));
String name = (String) docFields.get(ConversationalIndexConstants.META_NAME_FIELD);
String user = (String) docFields.get(ConversationalIndexConstants.USER_FIELD);
return new ConversationMeta(id, created, name, user);
}

/**
* Creates a conversationMeta from a stream, given the stream was written to by
* conversationMeta.writeTo
* @param in stream to read from
* @return new conversationMeta object
* @throws IOException if you're reading from a stream without a conversationMeta in it
*/
public static ConversationMeta fromStream(StreamInput in) throws IOException {
String id = in.readString();
Instant created = in.readInstant();
String name = in.readString();
String user = in.readOptionalString();
return new ConversationMeta(id, created, name, user);
}

@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(id);
out.writeInstant(createdTime);
out.writeString(name);
out.writeOptionalString(user);
}


/**
* Convert this conversationMeta object into an IndexRequest so it can be indexed
* @param index the index to send this conversation to. Should usually be .conversational-meta
* @return the IndexRequest for the client to send
*/
public IndexRequest toIndexRequest(String index) {
IndexRequest request = new IndexRequest(index);
return request.id(this.id).source(
ConversationalIndexConstants.META_CREATED_FIELD, this.createdTime,
ConversationalIndexConstants.META_NAME_FIELD, this.name
);
}

@Override
public String toString() {
return "{id=" + id
+ ", name=" + name
+ ", created=" + createdTime.toString()
+ ", user=" + user
+ "}";
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, ToXContentObject.Params params) throws IOException {
builder.startObject();
builder.field(ActionConstants.CONVERSATION_ID_FIELD, this.id);
builder.field(ConversationalIndexConstants.META_CREATED_FIELD, this.createdTime);
builder.field(ConversationalIndexConstants.META_NAME_FIELD, this.name);
if(this.user != null) {
builder.field(ConversationalIndexConstants.USER_FIELD, this.user);
}
builder.endObject();
return builder;
}

@Override
public boolean equals(Object other) {
if(!(other instanceof ConversationMeta)) {
return false;
}
ConversationMeta otherConversation = (ConversationMeta) other;
return Objects.equals(this.id, otherConversation.id) &&
Objects.equals(this.user, otherConversation.user) &&
Objects.equals(this.createdTime, otherConversation.createdTime) &&
Objects.equals(this.name, otherConversation.name);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2023 Aryn
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.opensearch.ml.common.conversation;

import org.opensearch.common.settings.Setting;

/**
* Class containing a bunch of constant defining how the conversational indices are formatted
*/
public class ConversationalIndexConstants {
/** Version of the meta index schema */
public final static Integer META_INDEX_SCHEMA_VERSION = 1;
/** Name of the conversational metadata index */
public final static String META_INDEX_NAME = ".plugins-ml-conversation-meta";
/** Name of the metadata field for initial timestamp */
public final static String META_CREATED_FIELD = "create_time";
/** Name of the metadata field for name of the conversation */
public final static String META_NAME_FIELD = "name";
/** Name of the owning user field in all indices */
public final static String USER_FIELD = "user";
/** Mappings for the conversational metadata index */
public final static String META_MAPPING = "{\n"
+ " \"_meta\": {\n"
+ " \"schema_version\": " + META_INDEX_SCHEMA_VERSION + "\n"
+ " },\n"
+ " \"properties\": {\n"
+ " \""
+ META_NAME_FIELD
+ "\": {\"type\": \"keyword\"},\n"
+ " \""
+ META_CREATED_FIELD
+ "\": {\"type\": \"date\", \"format\": \"strict_date_time||epoch_millis\"},\n"
+ " \""
+ USER_FIELD
+ "\": {\"type\": \"keyword\"}\n"
+ " }\n"
+ "}";

/** Version of the interactions index schema */
public final static Integer INTERACTIONS_INDEX_SCHEMA_VERSION = 1;
/** Name of the conversational interactions index */
public final static String INTERACTIONS_INDEX_NAME = ".plugins-ml-conversation-interactions";
/** Name of the interaction field for the conversation Id */
public final static String INTERACTIONS_CONVERSATION_ID_FIELD = "conversation_id";
/** Name of the interaction field for the human input */
public final static String INTERACTIONS_INPUT_FIELD = "input";
/** Name of the interaction field for the prompt template */
public final static String INTERACTIONS_PROMPT_TEMPLATE_FIELD = "prompt_template";
/** Name of the interaction field for the AI response */
public final static String INTERACTIONS_RESPONSE_FIELD = "response";
/** Name of the interaction field for the response's origin */
public final static String INTERACTIONS_ORIGIN_FIELD = "origin";
/** Name of the interaction field for additional metadata */
public final static String INTERACTIONS_ADDITIONAL_INFO_FIELD = "additional_info";
/** Name of the interaction field for the timestamp */
public final static String INTERACTIONS_CREATE_TIME_FIELD = "create_time";
/** Mappings for the interactions index */
public final static String INTERACTIONS_MAPPINGS = "{\n"
+ " \"_meta\": {\n"
+ " \"schema_version\": " + INTERACTIONS_INDEX_SCHEMA_VERSION + "\n"
+ " },\n"
+ " \"properties\": {\n"
+ " \""
+ INTERACTIONS_CONVERSATION_ID_FIELD
+ "\": {\"type\": \"keyword\"},\n"
+ " \""
+ INTERACTIONS_CREATE_TIME_FIELD
+ "\": {\"type\": \"date\", \"format\": \"strict_date_time||epoch_millis\"},\n"
+ " \""
+ INTERACTIONS_INPUT_FIELD
+ "\": {\"type\": \"text\"},\n"
+ " \""
+ INTERACTIONS_PROMPT_TEMPLATE_FIELD
+ "\": {\"type\": \"text\"},\n"
+ " \""
+ INTERACTIONS_RESPONSE_FIELD
+ "\": {\"type\": \"text\"},\n"
+ " \""
+ INTERACTIONS_ORIGIN_FIELD
+ "\": {\"type\": \"keyword\"},\n"
+ " \""
+ INTERACTIONS_ADDITIONAL_INFO_FIELD
+ "\": {\"type\": \"text\"}\n"
+ " }\n"
+ "}";

/** Feature Flag setting for conversational memory */
public static final Setting<Boolean> ML_COMMONS_MEMORY_FEATURE_ENABLED = Setting
.boolSetting("plugins.ml_commons.memory_feature_enabled", false, Setting.Property.NodeScope, Setting.Property.Dynamic);
}
Loading

0 comments on commit 74fbe08

Please sign in to comment.