diff --git a/CHANGELOG.md b/CHANGELOG.md index b282c095..0b544ed7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Added `POST /_plugins/_ml/memory`, `POST /_plugins/_ml/memory/_search`, `{memory_id}/_search`, `{memory_id}/messages`, `PUT /_plugins/_ml/memory/{memory_id}`, `message/{message_id}`, `GET /_plugins/_ml/memory`, `GET /_plugins/_ml/memory/{memory_id}`, `_search`, `message/{message_id}`, `{memory_id}/messages`, `{memory_id}/_search`, `message/{message_id}/traces`, and `DELETE /_plugins/_ml/memory/{memory_id}` ([#771](https://github.com/opensearch-project/opensearch-api-specification/pull/771)) - Added support for evaluating response payloads in prologues and epilogues ([#772](https://github.com/opensearch-project/opensearch-api-specification/pull/772)) - Added `GET /_plugins/_ml/models/{model_id}`, `POST /_plugins/_ml/models/_search`, `POST /_plugins/_ml/models/_unload`, `_undeploy`, `_upload`, `meta`, `_register_meta`, `POST /_plugins/_ml/models/{model_id}/_load`, `_predict`, `_unload`, `chunk/{chunk_number}`, `upload_chunk/{chunk_number}`, and `PUT /_plugins/_ml/models/{model_id}` ([#733](https://github.com/opensearch-project/opensearch-api-specification/pull/733)) +- Added `GET`, `POST`, `PUT`, `DELETE /_plugins/_ml/controllers/{model_id}` ([#779](https://github.com/opensearch-project/opensearch-api-specification/pull/779)) ### Removed - Removed unsupported `_common.mapping:SourceField`'s `mode` field and associated `_common.mapping:SourceFieldMode` enum ([#652](https://github.com/opensearch-project/opensearch-api-specification/pull/652)) diff --git a/logs/test-spec-2.18.0-daeaa72ad2dd9c8f64703f44896ae7bbc6bd0a2ed2671a349103ce0d70344aaa.log b/logs/test-spec-2.18.0-daeaa72ad2dd9c8f64703f44896ae7bbc6bd0a2ed2671a349103ce0d70344aaa.log new file mode 100644 index 00000000..5ede8db6 --- /dev/null +++ b/logs/test-spec-2.18.0-daeaa72ad2dd9c8f64703f44896ae7bbc6bd0a2ed2671a349103ce0d70344aaa.log @@ -0,0 +1,335 @@ +[INFO] Authenticating with admin ... +[INFO] Connecting to https://localhost:9200 ... (1/20) +[INFO] Evaluating ml/agents.yaml ... +[INFO] => POST /_plugins/_ml/agents/_register ({}) [application/json] { + "name": "Test_Agent_For_RAG", + "type": "flow", + "description": "this is a test agent", + "tools": [ + { + "type": "VectorDBTool", + "parameters": { + "model_id": "YOUR_TEXT_EMBEDDING_MODEL_ID", + "index": "my_test_data", + "embedding_field": "embedding", + "source_field": [ + "text" + ], + "input": "test_question" + } + }, + { + "type": "MLModelTool", + "description": "A general tool to answer any question", + "parameters": { + "model_id": "YOUR_LLM_MODEL_ID" + } + } + ] +} +[INFO] <= 200 (application/json; charset=UTF-8) | { + "agent_id": "KejBUZQBaqMO3uIYKp67" +} +[INFO] $ { + "outputs": { + "test_agent_id": "KejBUZQBaqMO3uIYKp67" + } +} +[INFO] => DELETE /_plugins/_ml/agents/KejBUZQBaqMO3uIYKp67 ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "_index": ".plugins-ml-agent", + "_id": "KejBUZQBaqMO3uIYKp67", + "_version": 2, + "result": "deleted", + "forced_refresh": true, + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 19, + "_primary_term": 6 +} +[INFO] => DELETE /_plugins/_ml/agents/KejBUZQBaqMO3uIYKp67 ({}) [application/json] +[INFO] <= 404 (application/json) | { + "error": { + "root_cause": [ + { + "type": "status_exception", + "reason": "Failed to find agent with the provided agent id: KejBUZQBaqMO3uIYKp67" + } + ], + "type": "status_exception", + "reason": "Failed to find agent with the provided agent id: KejBUZQBaqMO3uIYKp67" + }, + "status": 404 +} +[INFO] Evaluating ml/connectors.yaml ... +[INFO] => POST /_plugins/_ml/connectors/_create ({}) [application/json] { + "name": "OpenAI Chat Connector", + "description": "The connector to public OpenAI model service for GPT 3.5", + "version": 1, + "protocol": "http", + "parameters": { + "endpoint": "api.openai.com", + "model": "gpt-3.5-turbo" + }, + "credential": { + "openAI_key": "test_api_key" + }, + "actions": [ + { + "action_type": "predict", + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions", + "headers": { + "Authorization": "Bearer Key" + }, + "request_body": "{ \"model\": \"model\", \"messages\": \"messages\" }" + } + ] +} +[INFO] <= 200 (application/json; charset=UTF-8) | { + "connector_id": "KujBUZQBaqMO3uIYK57K" +} +[INFO] $ { + "outputs": { + "test_connector_id": "KujBUZQBaqMO3uIYK57K" + } +} +[INFO] => GET /_plugins/_ml/connectors/KujBUZQBaqMO3uIYK57K ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "name": "OpenAI Chat Connector", + "version": "1", + "description": "The connector to public OpenAI model service for GPT 3.5", + "protocol": "http", + "parameters": { + "endpoint": "api.openai.com", + "model": "gpt-3.5-turbo" + }, + "actions": [ + { + "action_type": "PREDICT", + "method": "POST", + "url": "https://api.openai.com/v1/chat/completions", + "headers": { + "Authorization": "Bearer Key" + }, + "request_body": "{ \"model\": \"model\", \"messages\": \"messages\" }" + } + ], + "created_time": 1736538401737, + "last_updated_time": 1736538401737 +} +[INFO] => DELETE /_plugins/_ml/connectors/KujBUZQBaqMO3uIYK57K ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "_index": ".plugins-ml-connector", + "_id": "KujBUZQBaqMO3uIYK57K", + "_version": 2, + "result": "deleted", + "forced_refresh": true, + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 40, + "_primary_term": 6 +} +[INFO] => DELETE /_plugins/_ml/connectors/KujBUZQBaqMO3uIYK57K ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "_index": ".plugins-ml-connector", + "_id": "KujBUZQBaqMO3uIYK57K", + "_version": 3, + "result": "not_found", + "forced_refresh": true, + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 41, + "_primary_term": 6 +} +[INFO] Evaluating ml/model_groups.yaml ... +[INFO] => POST /_plugins/_ml/model_groups/_register ({}) [application/json] { + "name": "NLP_Group", + "description": "Model group for NLP models." +} +[INFO] <= 200 (application/json; charset=UTF-8) | { + "model_group_id": "K-jBUZQBaqMO3uIYLJ5u", + "status": "CREATED" +} +[INFO] $ { + "outputs": { + "test_model_group_id": "K-jBUZQBaqMO3uIYLJ5u" + } +} +[INFO] => GET /_plugins/_ml/model_groups/K-jBUZQBaqMO3uIYLJ5u ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "name": "NLP_Group", + "latest_version": 0, + "description": "Model group for NLP models.", + "owner": { + "name": "admin", + "backend_roles": [ + "admin" + ], + "roles": [ + "own_index", + "all_access" + ], + "custom_attribute_names": [], + "user_requested_tenant": null + }, + "access": "private", + "created_time": 1736538401901, + "last_updated_time": 1736538401901 +} +[INFO] => DELETE /_plugins/_ml/model_groups/K-jBUZQBaqMO3uIYLJ5u ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "_index": ".plugins-ml-model-group", + "_id": "K-jBUZQBaqMO3uIYLJ5u", + "_version": 2, + "result": "deleted", + "forced_refresh": true, + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 236, + "_primary_term": 6 +} +[INFO] => DELETE /_plugins/_ml/model_groups/K-jBUZQBaqMO3uIYLJ5u ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "_index": ".plugins-ml-model-group", + "_id": "K-jBUZQBaqMO3uIYLJ5u", + "_version": 3, + "result": "not_found", + "forced_refresh": true, + "_shards": { + "total": 2, + "successful": 2, + "failed": 0 + }, + "_seq_no": 237, + "_primary_term": 6 +} +[INFO] Evaluating ml/models.yaml ... +[INFO] => POST /_plugins/_ml/models/_register ({}) [application/json] { + "name": "huggingface/sentence-transformers/msmarco-distilbert-base-tas-b", + "version": "1.0.1", + "model_format": "TORCH_SCRIPT" +} +[INFO] <= 200 (application/json; charset=UTF-8) | { + "task_id": "LOjBUZQBaqMO3uIYLJ6y", + "status": "CREATED" +} +[INFO] $ { + "outputs": { + "task_id": "LOjBUZQBaqMO3uIYLJ6y" + } +} +[INFO] => GET /_plugins/_ml/tasks/LOjBUZQBaqMO3uIYLJ6y ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "CREATED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538401970, + "is_async": true +} +[INFO] { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "CREATED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538401970, + "is_async": true +} +[INFO] Failed, retrying, 5 retries left ... +[INFO] => GET /_plugins/_ml/tasks/LOjBUZQBaqMO3uIYLJ6y ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "FAILED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538407919, + "error": "/usr/share/opensearch/data/ml_cache/models_cache/register/slnBUZQBdUaAr33ZL44-/57/huggingface/sentence-transformers/msmarco-distilbert-base-tas-b.zip", + "is_async": true +} +[INFO] { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "FAILED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538407919, + "error": "/usr/share/opensearch/data/ml_cache/models_cache/register/slnBUZQBdUaAr33ZL44-/57/huggingface/sentence-transformers/msmarco-distilbert-base-tas-b.zip", + "is_async": true +} +[INFO] Failed, retrying, 4 retries left ... +[INFO] => GET /_plugins/_ml/tasks/LOjBUZQBaqMO3uIYLJ6y ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "FAILED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538407919, + "error": "/usr/share/opensearch/data/ml_cache/models_cache/register/slnBUZQBdUaAr33ZL44-/57/huggingface/sentence-transformers/msmarco-distilbert-base-tas-b.zip", + "is_async": true +} +[INFO] { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "FAILED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538407919, + "error": "/usr/share/opensearch/data/ml_cache/models_cache/register/slnBUZQBdUaAr33ZL44-/57/huggingface/sentence-transformers/msmarco-distilbert-base-tas-b.zip", + "is_async": true +} +[INFO] Failed, retrying, 3 retries left ... +[INFO] => GET /_plugins/_ml/tasks/LOjBUZQBaqMO3uIYLJ6y ({}) [application/json] +[INFO] <= 200 (application/json; charset=UTF-8) | { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "FAILED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538407919, + "error": "/usr/share/opensearch/data/ml_cache/models_cache/register/slnBUZQBdUaAr33ZL44-/57/huggingface/sentence-transformers/msmarco-distilbert-base-tas-b.zip", + "is_async": true +} +[INFO] { + "task_type": "REGISTER_MODEL", + "function_name": "TEXT_EMBEDDING", + "state": "FAILED", + "worker_node": [ + "ZcCsgpwPQsOq347BXU79jQ" + ], + "create_time": 1736538401970, + "last_update_time": 1736538407919, + "error": "/usr/share/opensearch/data/ml_cache/models_cache/register/slnBUZQBdUaAr33ZL44-/57/huggingface/sentence-transformers/msmarco-distilbert-base-tas-b.zip", + "is_async": true +} +[INFO] Failed, retrying, 2 retries left ... diff --git a/spec/namespaces/ml.yaml b/spec/namespaces/ml.yaml index bae59a07..06f16daf 100644 --- a/spec/namespaces/ml.yaml +++ b/spec/namespaces/ml.yaml @@ -585,6 +585,51 @@ paths: responses: '200': $ref: '#/components/responses/ml.get_message_traces@200' + /_plugins/_ml/controllers/{model_id}: + get: + operationId: ml.get_controller.0 + x-operation-group: ml.get_controller + x-version-added: '2.12' + description: Retrieves a controller. + parameters: + - $ref: '#/components/parameters/ml.get_controller::path.model_id' + responses: + '200': + $ref: '#/components/responses/ml.get_controller@200' + post: + operationId: ml.create_controller.0 + x-operation-group: ml.create_controller + x-version-added: '2.12' + description: Creates a controller. + requestBody: + $ref: '#/components/requestBodies/ml.create_controller' + parameters: + - $ref: '#/components/parameters/ml.create_controller::path.model_id' + responses: + '200': + $ref: '#/components/responses/ml.create_controller@200' + put: + operationId: ml.update_controller.0 + x-operation-group: ml.update_controller + x-version-added: '2.12' + description: Updates a controller. + requestBody: + $ref: '#/components/requestBodies/ml.update_controller' + parameters: + - $ref: '#/components/parameters/ml.update_controller::path.model_id' + responses: + '200': + $ref: '#/components/responses/ml.update_controller@200' + delete: + operationId: ml.delete_controller.0 + x-operation-group: ml.delete_controller + x-version-added: '2.12' + description: Deletes a controller. + parameters: + - $ref: '#/components/parameters/ml.delete_controller::path.model_id' + responses: + '200': + $ref: '#/components/responses/ml.delete_controller@200' components: requestBodies: ml.register_model_group: @@ -1171,6 +1216,24 @@ components: items: $ref: '../schemas/ml._common.yaml#/components/schemas/SortMessage' description: The sort order. + ml.create_controller: + content: + application/json: + schema: + type: object + properties: + user_rate_limiter: + $ref: '../schemas/ml._common.yaml#/components/schemas/UserRateLimiter' + ml.update_controller: + content: + application/json: + schema: + type: object + properties: + user_rate_limiter: + $ref: '../schemas/ml._common.yaml#/components/schemas/UserRateLimiter' + model_id: + $ref: '../schemas/_common.yaml#/components/schemas/Name' responses: ml.register_model_group@200: content: @@ -1478,6 +1541,36 @@ components: application/json: schema: $ref: '../schemas/ml._common.yaml#/components/schemas/GetMessageTracesResponse' + ml.get_controller@200: + content: + application/json: + schema: + type: object + properties: + user_rate_limiter: + $ref: '../schemas/ml._common.yaml#/components/schemas/UserRateLimiter' + model_id: + $ref: '../schemas/_common.yaml#/components/schemas/Name' + ml.create_controller@200: + content: + application/json: + schema: + type: object + properties: + model_id: + $ref: '../schemas/_common.yaml#/components/schemas/Name' + status: + $ref: '../schemas/ml._common.yaml#/components/schemas/Status' + ml.update_controller@200: + content: + application/json: + schema: + $ref: '../schemas/_common.yaml#/components/schemas/WriteResponseBase' + ml.delete_controller@200: + content: + application/json: + schema: + $ref: '../schemas/_common.yaml#/components/schemas/WriteResponseBase' parameters: ml.get_model_group::path.model_group_id: name: model_group_id @@ -1683,5 +1776,29 @@ components: name: message_id in: path required: true + schema: + type: string + ml.get_controller::path.model_id: + name: model_id + in: path + required: true + schema: + type: string + ml.create_controller::path.model_id: + name: model_id + in: path + required: true + schema: + type: string + ml.update_controller::path.model_id: + name: model_id + in: path + required: true + schema: + type: string + ml.delete_controller::path.model_id: + name: model_id + in: path + required: true schema: type: string \ No newline at end of file diff --git a/spec/schemas/ml._common.yaml b/spec/schemas/ml._common.yaml index 281fe255..3a043bb6 100644 --- a/spec/schemas/ml._common.yaml +++ b/spec/schemas/ml._common.yaml @@ -1233,4 +1233,27 @@ components: traces: type: array items: - $ref: '#/components/schemas/Message' \ No newline at end of file + $ref: '#/components/schemas/Message' + UserRateLimiter: + type: object + properties: + user1: + $ref: '#/components/schemas/User' + additionalProperties: true + User: + type: object + properties: + limit: + type: [integer, string] + description: Max Predict API calls per user per time unit. + unit: + type: string + description: The unit of time. + enum: + - DAYS + - HOURS + - MICROSECONDS + - MILLISECONDS + - MINUTES + - NANOSECONDS + - SECONDS \ No newline at end of file diff --git a/tests/plugins/ml/ml/controller/create.yaml b/tests/plugins/ml/ml/controller/create.yaml new file mode 100644 index 00000000..40f7fcb8 --- /dev/null +++ b/tests/plugins/ml/ml/controller/create.yaml @@ -0,0 +1,71 @@ +$schema: ../../../../../json_schemas/test_story.schema.yaml + +description: Test the creation of a controller. +version: '>= 2.12' +prologues: + - path: /_cluster/settings + method: PUT + request: + payload: + persistent: + plugins.ml_commons.native_memory_threshold: 100 + - path: /_plugins/_ml/models/_register + id: register_model + method: POST + request: + payload: + name: huggingface/sentence-transformers/msmarco-distilbert-base-tas-b + version: 1.0.1 + model_format: TORCH_SCRIPT + output: + task_id: payload.task_id + - path: /_plugins/_ml/tasks/{task_id} + id: get_completed_task + method: GET + parameters: + task_id: ${register_model.task_id} + retry: + count: 3 + wait: 10000 + response: + status: 200 + payload: + state: COMPLETED + output: + model_id: payload.model_id +epilogues: + - path: /_plugins/_ml/controllers/{model_id} + parameters: + model_id: ${create_controller.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/models/{model_id} + parameters: + model_id: ${get_completed_task.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/tasks/{task_id} + parameters: + task_id: ${register_model.task_id} + method: DELETE + status: [200, 404] +chapters: + - synopsis: Create a controller. + id: create_controller + path: /_plugins/_ml/controllers/{model_id} + method: POST + parameters: + model_id: ${get_completed_task.model_id} + request: + payload: + user_rate_limiter: + user1: + limit: 4 + unit: MINUTES + user2: + limit: 4 + unit: MINUTES + response: + status: 200 + output: + model_id: payload.model_id diff --git a/tests/plugins/ml/ml/controller/delete.yaml b/tests/plugins/ml/ml/controller/delete.yaml new file mode 100644 index 00000000..6187e5cf --- /dev/null +++ b/tests/plugins/ml/ml/controller/delete.yaml @@ -0,0 +1,75 @@ +$schema: ../../../../../json_schemas/test_story.schema.yaml + +description: Test the deletion of a controller. +version: '>= 2.12' +prologues: + - path: /_cluster/settings + method: PUT + request: + payload: + persistent: + plugins.ml_commons.native_memory_threshold: 100 + - path: /_plugins/_ml/models/_register + id: register_model + method: POST + request: + payload: + name: huggingface/sentence-transformers/msmarco-distilbert-base-tas-b + version: 1.0.1 + model_format: TORCH_SCRIPT + output: + task_id: payload.task_id + - path: /_plugins/_ml/tasks/{task_id} + id: get_completed_task + method: GET + parameters: + task_id: ${register_model.task_id} + retry: + count: 3 + wait: 10000 + response: + status: 200 + payload: + state: COMPLETED + output: + model_id: payload.model_id + - path: /_plugins/_ml/controllers/{model_id} + id: create_controller + method: POST + parameters: + model_id: ${get_completed_task.model_id} + request: + payload: + user_rate_limiter: + user1: + limit: 4 + unit: MINUTES + user2: + limit: 4 + unit: MINUTES + output: + model_id: payload.model_id +epilogues: + - path: /_plugins/_ml/controllers/{model_id} + parameters: + model_id: ${create_controller.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/models/{model_id} + parameters: + model_id: ${get_completed_task.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/tasks/{task_id} + parameters: + task_id: ${register_model.task_id} + method: DELETE + status: [200, 404] +chapters: + - synopsis: Delete a controller. + path: /_plugins/_ml/controllers/{model_id} + method: DELETE + parameters: + model_id: ${create_controller.model_id} + response: + status: 200 \ No newline at end of file diff --git a/tests/plugins/ml/ml/controller/get.yaml b/tests/plugins/ml/ml/controller/get.yaml new file mode 100644 index 00000000..3ea9d881 --- /dev/null +++ b/tests/plugins/ml/ml/controller/get.yaml @@ -0,0 +1,75 @@ +$schema: ../../../../../json_schemas/test_story.schema.yaml + +description: Test the retrieval of a controller. +version: '>= 2.12' +prologues: + - path: /_cluster/settings + method: PUT + request: + payload: + persistent: + plugins.ml_commons.native_memory_threshold: 100 + - path: /_plugins/_ml/models/_register + id: register_model + method: POST + request: + payload: + name: huggingface/sentence-transformers/msmarco-distilbert-base-tas-b + version: 1.0.1 + model_format: TORCH_SCRIPT + output: + task_id: payload.task_id + - path: /_plugins/_ml/tasks/{task_id} + id: get_completed_task + method: GET + parameters: + task_id: ${register_model.task_id} + retry: + count: 3 + wait: 10000 + response: + status: 200 + payload: + state: COMPLETED + output: + model_id: payload.model_id + - path: /_plugins/_ml/controllers/{model_id} + id: create_controller + method: POST + parameters: + model_id: ${get_completed_task.model_id} + request: + payload: + user_rate_limiter: + user1: + limit: 4 + unit: MINUTES + user2: + limit: 4 + unit: MINUTES + output: + model_id: payload.model_id +epilogues: + - path: /_plugins/_ml/controllers/{model_id} + parameters: + model_id: ${create_controller.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/models/{model_id} + parameters: + model_id: ${get_completed_task.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/tasks/{task_id} + parameters: + task_id: ${register_model.task_id} + method: DELETE + status: [200, 404] +chapters: + - synopsis: Get a controller. + path: /_plugins/_ml/controllers/{model_id} + method: GET + parameters: + model_id: ${create_controller.model_id} + response: + status: 200 \ No newline at end of file diff --git a/tests/plugins/ml/ml/controller/update.yaml b/tests/plugins/ml/ml/controller/update.yaml new file mode 100644 index 00000000..557ca813 --- /dev/null +++ b/tests/plugins/ml/ml/controller/update.yaml @@ -0,0 +1,81 @@ +$schema: ../../../../../json_schemas/test_story.schema.yaml + +description: Test updating a controller. +version: '>= 2.12' +prologues: + - path: /_cluster/settings + method: PUT + request: + payload: + persistent: + plugins.ml_commons.native_memory_threshold: 100 + - path: /_plugins/_ml/models/_register + id: register_model + method: POST + request: + payload: + name: huggingface/sentence-transformers/msmarco-distilbert-base-tas-b + version: 1.0.1 + model_format: TORCH_SCRIPT + output: + task_id: payload.task_id + - path: /_plugins/_ml/tasks/{task_id} + id: get_completed_task + method: GET + parameters: + task_id: ${register_model.task_id} + retry: + count: 3 + wait: 10000 + response: + status: 200 + payload: + state: COMPLETED + output: + model_id: payload.model_id + - path: /_plugins/_ml/controllers/{model_id} + id: create_controller + method: POST + parameters: + model_id: ${get_completed_task.model_id} + request: + payload: + user_rate_limiter: + user1: + limit: 4 + unit: MINUTES + user2: + limit: 4 + unit: MINUTES + output: + model_id: payload.model_id +epilogues: + - path: /_plugins/_ml/controllers/{model_id} + parameters: + model_id: ${create_controller.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/models/{model_id} + parameters: + model_id: ${get_completed_task.model_id} + method: DELETE + status: [200, 404] + - path: /_plugins/_ml/tasks/{task_id} + parameters: + task_id: ${register_model.task_id} + method: DELETE + status: [200, 404] +chapters: + - synopsis: Update a controller. + path: /_plugins/_ml/controllers/{model_id} + method: PUT + parameters: + model_id: ${create_controller.model_id} + request: + payload: + user_rate_limiter: + user1: + limit: 6 + unit: MINUTES + response: + status: 200