diff --git a/.generator/schemas/v2/openapi.yaml b/.generator/schemas/v2/openapi.yaml index 60ae5f2857..0334b34754 100644 --- a/.generator/schemas/v2/openapi.yaml +++ b/.generator/schemas/v2/openapi.yaml @@ -43111,6 +43111,78 @@ components: - type - attributes type: object + LLMObsDatasetDraftStateData: + description: Data object for an LLM Observability dataset draft state. + properties: + attributes: + $ref: "#/components/schemas/LLMObsDatasetDraftStateDataAttributes" + id: + description: Unique identifier of the dataset draft state. Matches the dataset ID. + example: "9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d" + type: string + type: + $ref: "#/components/schemas/LLMObsDatasetDraftStateType" + required: + - id + - type + - attributes + type: object + LLMObsDatasetDraftStateDataAttributes: + description: Attributes of an LLM Observability dataset draft state. + properties: + drafting_since: + description: Timestamp when the dataset draft session started. + example: "2024-01-15T10:30:00Z" + format: date-time + type: string + user: + $ref: "#/components/schemas/LLMObsDatasetDraftStateUser" + required: + - user + - drafting_since + type: object + LLMObsDatasetDraftStateResponse: + description: Response containing the draft state of an LLM Observability dataset. + properties: + data: + $ref: "#/components/schemas/LLMObsDatasetDraftStateData" + required: + - data + type: object + LLMObsDatasetDraftStateType: + description: Resource type of an LLM Observability dataset draft state. + enum: + - draft_state_data + example: draft_state_data + type: string + x-enum-varnames: + - DRAFT_STATE_DATA + LLMObsDatasetDraftStateUser: + description: User information associated with a dataset draft state. + properties: + email: + description: Email address of the user. + example: "jane.doe@example.com" + type: string + handle: + description: Handle of the user. + example: "jane.doe@example.com" + type: string + icon: + description: Icon for the user. + example: "" + type: string + id: + description: Unique identifier of the user holding the draft lock. + example: "00000000-0000-0000-0000-000000000010" + type: string + name: + description: Display name of the user. + example: "Jane Doe" + type: string + required: + - id + type: object LLMObsDatasetRecordDataResponse: description: A single LLM Observability dataset record. properties: @@ -43337,6 +43409,67 @@ components: required: - data type: object + LLMObsDatasetVersionData: + description: Data object for an LLM Observability dataset version. + properties: + attributes: + $ref: "#/components/schemas/LLMObsDatasetVersionDataAttributes" + id: + description: Unique identifier of the dataset version. + example: "3fd6b5e0-8910-4b1c-a7d0-5b84de329012" + type: string + type: + $ref: "#/components/schemas/LLMObsDatasetVersionType" + required: + - id + - type + - attributes + type: object + LLMObsDatasetVersionDataAttributes: + description: Attributes of an LLM Observability dataset version. + properties: + dataset_id: + description: Unique identifier of the dataset this version belongs to. + example: "9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d" + type: string + last_used: + description: Timestamp when this dataset version was last referenced. Null if the version has never been used. + example: "2024-01-15T10:30:00Z" + format: date-time + nullable: true + type: string + version_number: + description: Sequential version number for this dataset version. + example: 1 + format: int32 + maximum: 2147483647 + type: integer + required: + - dataset_id + - version_number + - last_used + type: object + LLMObsDatasetVersionType: + description: Resource type of an LLM Observability dataset version. + enum: + - dataset_version + example: dataset_version + type: string + x-enum-varnames: + - DATASET_VERSION + LLMObsDatasetVersionsResponse: + description: Response containing the active versions of an LLM Observability dataset. + properties: + data: + $ref: "#/components/schemas/LLMObsDatasetVersionsResponseData" + required: + - data + type: object + LLMObsDatasetVersionsResponseData: + description: List of dataset versions. + items: + $ref: "#/components/schemas/LLMObsDatasetVersionData" + type: array LLMObsDatasetsResponse: description: Response containing a list of LLM Observability datasets. properties: @@ -125122,6 +125255,229 @@ paths: x-unstable: |- **Note**: This endpoint is in preview and is subject to change. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/draft_state: + get: + description: Retrieve the draft state of a dataset, including whether it is currently locked for editing and which user holds the lock. + operationId: GetLLMObsDatasetDraftState + parameters: + - description: The ID of the LLM Observability project. + example: "a33671aa-24fd-4dcd-9b33-a8ec7dde7751" + in: path + name: project_id + required: true + schema: + type: string + - description: The ID of the LLM Observability dataset. + example: "9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d" + in: path + name: dataset_id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + drafting_since: "2024-01-15T10:30:00Z" + user: + email: jane.doe@example.com + handle: jane.doe@example.com + id: 00000000-0000-0000-0000-000000000010 + name: Jane Doe + id: 9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d + type: draft_state_data + schema: + $ref: "#/components/schemas/LLMObsDatasetDraftStateResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Internal Server Error + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Get LLM Observability dataset draft state + tags: + - LLM Observability + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/draft_state/lock: + patch: + description: Acquire the draft lock on a dataset for the calling user. The lock prevents other users from concurrently editing the dataset draft. + operationId: LockLLMObsDatasetDraftState + parameters: + - description: The ID of the LLM Observability project. + example: "a33671aa-24fd-4dcd-9b33-a8ec7dde7751" + in: path + name: project_id + required: true + schema: + type: string + - description: The ID of the LLM Observability dataset. + example: "9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d" + in: path + name: dataset_id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + attributes: + drafting_since: "2024-01-15T10:30:00Z" + user: + email: jane.doe@example.com + handle: jane.doe@example.com + id: 00000000-0000-0000-0000-000000000010 + name: Jane Doe + id: 9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d + type: draft_state_data + schema: + $ref: "#/components/schemas/LLMObsDatasetDraftStateResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Internal Server Error + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Lock LLM Observability dataset draft state + tags: + - LLM Observability + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/draft_state/unlock: + patch: + description: Release the draft lock on a dataset held by the calling user, allowing other users to edit the dataset draft. + operationId: UnlockLLMObsDatasetDraftState + parameters: + - description: The ID of the LLM Observability project. + example: "a33671aa-24fd-4dcd-9b33-a8ec7dde7751" + in: path + name: project_id + required: true + schema: + type: string + - description: The ID of the LLM Observability dataset. + example: "9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d" + in: path + name: dataset_id + required: true + schema: + type: string + responses: + "200": + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Internal Server Error + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: Unlock LLM Observability dataset draft state + tags: + - LLM Observability + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/records: get: description: List all records in an LLM Observability dataset, sorted by creation date, newest first. @@ -125432,6 +125788,89 @@ paths: x-unstable: |- **Note**: This endpoint is in preview and is subject to change. If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). + /api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/versions: + get: + description: List the active versions of a dataset. A version is created each time a dataset is referenced by an experiment run. + operationId: ListLLMObsDatasetVersions + parameters: + - description: The ID of the LLM Observability project. + example: "a33671aa-24fd-4dcd-9b33-a8ec7dde7751" + in: path + name: project_id + required: true + schema: + type: string + - description: The ID of the LLM Observability dataset. + example: "9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d" + in: path + name: dataset_id + required: true + schema: + type: string + responses: + "200": + content: + application/json: + examples: + default: + value: + data: + - attributes: + dataset_id: 9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d + last_used: "2024-01-15T10:30:00Z" + version_number: 1 + id: 3fd6b5e0-8910-4b1c-a7d0-5b84de329012 + type: dataset_version + - attributes: + dataset_id: 9f64e5c7-dc5a-45c8-a17c-1b85f0bec97d + last_used: "2024-02-20T14:45:00Z" + version_number: 2 + id: 4ee7c6f1-9a01-5c2d-b8e1-6c95ef43a123 + type: dataset_version + schema: + $ref: "#/components/schemas/LLMObsDatasetVersionsResponse" + description: OK + "400": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Bad Request + "401": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Unauthorized + "403": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Forbidden + "404": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Not Found + "429": + $ref: "#/components/responses/TooManyRequestsResponse" + "500": + content: + application/json: + schema: + $ref: "#/components/schemas/JSONAPIErrorResponse" + description: Internal Server Error + security: + - apiKeyAuth: [] + appKeyAuth: [] + summary: List LLM Observability dataset versions + tags: + - LLM Observability + x-unstable: |- + **Note**: This endpoint is in preview and is subject to change. + If you have any feedback, contact [Datadog support](https://docs.datadoghq.com/help/). /api/v2/llm-obs/v3/experiments/{experiment_id}/events: get: description: Retrieve spans and experiment-level summary metrics for a given experiment with cursor-based pagination. diff --git a/examples/v2_llm-observability_GetLLMObsDatasetDraftState.rs b/examples/v2_llm-observability_GetLLMObsDatasetDraftState.rs new file mode 100644 index 0000000000..26e50c595f --- /dev/null +++ b/examples/v2_llm-observability_GetLLMObsDatasetDraftState.rs @@ -0,0 +1,18 @@ +// Get LLM Observability dataset draft state returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_llm_observability::LLMObservabilityAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.GetLLMObsDatasetDraftState", true); + let api = LLMObservabilityAPI::with_config(configuration); + let resp = api + .get_llm_obs_dataset_draft_state("project_id".to_string(), "dataset_id".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_llm-observability_ListLLMObsDatasetVersions.rs b/examples/v2_llm-observability_ListLLMObsDatasetVersions.rs new file mode 100644 index 0000000000..b54ad78193 --- /dev/null +++ b/examples/v2_llm-observability_ListLLMObsDatasetVersions.rs @@ -0,0 +1,18 @@ +// List LLM Observability dataset versions returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_llm_observability::LLMObservabilityAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.ListLLMObsDatasetVersions", true); + let api = LLMObservabilityAPI::with_config(configuration); + let resp = api + .list_llm_obs_dataset_versions("project_id".to_string(), "dataset_id".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_llm-observability_LockLLMObsDatasetDraftState.rs b/examples/v2_llm-observability_LockLLMObsDatasetDraftState.rs new file mode 100644 index 0000000000..5b20c7e0a1 --- /dev/null +++ b/examples/v2_llm-observability_LockLLMObsDatasetDraftState.rs @@ -0,0 +1,18 @@ +// Lock LLM Observability dataset draft state returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_llm_observability::LLMObservabilityAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.LockLLMObsDatasetDraftState", true); + let api = LLMObservabilityAPI::with_config(configuration); + let resp = api + .lock_llm_obs_dataset_draft_state("project_id".to_string(), "dataset_id".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/examples/v2_llm-observability_UnlockLLMObsDatasetDraftState.rs b/examples/v2_llm-observability_UnlockLLMObsDatasetDraftState.rs new file mode 100644 index 0000000000..0a577cbe9a --- /dev/null +++ b/examples/v2_llm-observability_UnlockLLMObsDatasetDraftState.rs @@ -0,0 +1,18 @@ +// Unlock LLM Observability dataset draft state returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV2::api_llm_observability::LLMObservabilityAPI; + +#[tokio::main] +async fn main() { + let mut configuration = datadog::Configuration::new(); + configuration.set_unstable_operation_enabled("v2.UnlockLLMObsDatasetDraftState", true); + let api = LLMObservabilityAPI::with_config(configuration); + let resp = api + .unlock_llm_obs_dataset_draft_state("project_id".to_string(), "dataset_id".to_string()) + .await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadog/configuration.rs b/src/datadog/configuration.rs index ff15e22654..15a2548b2b 100644 --- a/src/datadog/configuration.rs +++ b/src/datadog/configuration.rs @@ -173,18 +173,22 @@ impl Default for Configuration { false, ), ("v2.get_llm_obs_custom_eval_config".to_owned(), false), + ("v2.get_llm_obs_dataset_draft_state".to_owned(), false), ("v2.list_llm_obs_annotation_queues".to_owned(), false), ("v2.list_llm_obs_dataset_records".to_owned(), false), ("v2.list_llm_obs_datasets".to_owned(), false), + ("v2.list_llm_obs_dataset_versions".to_owned(), false), ("v2.list_llm_obs_experiment_events".to_owned(), false), ("v2.list_llm_obs_experiments".to_owned(), false), ("v2.list_llm_obs_integration_accounts".to_owned(), false), ("v2.list_llm_obs_integration_models".to_owned(), false), ("v2.list_llm_obs_projects".to_owned(), false), ("v2.list_llm_obs_spans".to_owned(), false), + ("v2.lock_llm_obs_dataset_draft_state".to_owned(), false), ("v2.search_llm_obs_experimentation".to_owned(), false), ("v2.search_llm_obs_spans".to_owned(), false), ("v2.simple_search_llm_obs_experimentation".to_owned(), false), + ("v2.unlock_llm_obs_dataset_draft_state".to_owned(), false), ("v2.update_llm_obs_annotation_queue".to_owned(), false), ( "v2.update_llm_obs_annotation_queue_label_schema".to_owned(), diff --git a/src/datadogV2/api/api_llm_observability.rs b/src/datadogV2/api/api_llm_observability.rs index 87ecd212dd..833ad40766 100644 --- a/src/datadogV2/api/api_llm_observability.rs +++ b/src/datadogV2/api/api_llm_observability.rs @@ -510,6 +510,15 @@ pub enum GetLLMObsCustomEvalConfigError { UnknownValue(serde_json::Value), } +/// GetLLMObsDatasetDraftStateError is a struct for typed errors of method [`LLMObservabilityAPI::get_llm_obs_dataset_draft_state`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum GetLLMObsDatasetDraftStateError { + JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse), + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// ListLLMObsAnnotationQueuesError is a struct for typed errors of method [`LLMObservabilityAPI::list_llm_obs_annotation_queues`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -528,6 +537,15 @@ pub enum ListLLMObsDatasetRecordsError { UnknownValue(serde_json::Value), } +/// ListLLMObsDatasetVersionsError is a struct for typed errors of method [`LLMObservabilityAPI::list_llm_obs_dataset_versions`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum ListLLMObsDatasetVersionsError { + JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse), + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// ListLLMObsDatasetsError is a struct for typed errors of method [`LLMObservabilityAPI::list_llm_obs_datasets`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -591,6 +609,15 @@ pub enum ListLLMObsSpansError { UnknownValue(serde_json::Value), } +/// LockLLMObsDatasetDraftStateError is a struct for typed errors of method [`LLMObservabilityAPI::lock_llm_obs_dataset_draft_state`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum LockLLMObsDatasetDraftStateError { + JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse), + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// SearchLLMObsExperimentationError is a struct for typed errors of method [`LLMObservabilityAPI::search_llm_obs_experimentation`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -618,6 +645,15 @@ pub enum SimpleSearchLLMObsExperimentationError { UnknownValue(serde_json::Value), } +/// UnlockLLMObsDatasetDraftStateError is a struct for typed errors of method [`LLMObservabilityAPI::unlock_llm_obs_dataset_draft_state`] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(untagged)] +pub enum UnlockLLMObsDatasetDraftStateError { + JSONAPIErrorResponse(crate::datadogV2::model::JSONAPIErrorResponse), + APIErrorResponse(crate::datadogV2::model::APIErrorResponse), + UnknownValue(serde_json::Value), +} + /// UpdateLLMObsAnnotationQueueError is a struct for typed errors of method [`LLMObservabilityAPI::update_llm_obs_annotation_queue`] #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] @@ -3889,6 +3925,129 @@ impl LLMObservabilityAPI { } } + /// Retrieve the draft state of a dataset, including whether it is currently locked for editing and which user holds the lock. + pub async fn get_llm_obs_dataset_draft_state( + &self, + project_id: String, + dataset_id: String, + ) -> Result< + crate::datadogV2::model::LLMObsDatasetDraftStateResponse, + datadog::Error, + > { + match self + .get_llm_obs_dataset_draft_state_with_http_info(project_id, dataset_id) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Retrieve the draft state of a dataset, including whether it is currently locked for editing and which user holds the lock. + pub async fn get_llm_obs_dataset_draft_state_with_http_info( + &self, + project_id: String, + dataset_id: String, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.get_llm_obs_dataset_draft_state"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.get_llm_obs_dataset_draft_state' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/draft_state", + local_configuration.get_operation_host(operation_id), + project_id = datadog::urlencode(project_id), + dataset_id = datadog::urlencode(dataset_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// List annotation queues. Optionally filter by project ID or queue IDs. These parameters are mutually exclusive. /// If neither is provided, all queues in the organization are returned. pub async fn list_llm_obs_annotation_queues( @@ -4167,6 +4326,129 @@ impl LLMObservabilityAPI { } } + /// List the active versions of a dataset. A version is created each time a dataset is referenced by an experiment run. + pub async fn list_llm_obs_dataset_versions( + &self, + project_id: String, + dataset_id: String, + ) -> Result< + crate::datadogV2::model::LLMObsDatasetVersionsResponse, + datadog::Error, + > { + match self + .list_llm_obs_dataset_versions_with_http_info(project_id, dataset_id) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// List the active versions of a dataset. A version is created each time a dataset is referenced by an experiment run. + pub async fn list_llm_obs_dataset_versions_with_http_info( + &self, + project_id: String, + dataset_id: String, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.list_llm_obs_dataset_versions"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.list_llm_obs_dataset_versions' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/versions", + local_configuration.get_operation_host(operation_id), + project_id = datadog::urlencode(project_id), + dataset_id = datadog::urlencode(dataset_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::GET, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// List all LLM Observability datasets for a project, sorted by creation date, newest first. pub async fn list_llm_obs_datasets( &self, @@ -5150,6 +5432,129 @@ impl LLMObservabilityAPI { } } + /// Acquire the draft lock on a dataset for the calling user. The lock prevents other users from concurrently editing the dataset draft. + pub async fn lock_llm_obs_dataset_draft_state( + &self, + project_id: String, + dataset_id: String, + ) -> Result< + crate::datadogV2::model::LLMObsDatasetDraftStateResponse, + datadog::Error, + > { + match self + .lock_llm_obs_dataset_draft_state_with_http_info(project_id, dataset_id) + .await + { + Ok(response_content) => { + if let Some(e) = response_content.entity { + Ok(e) + } else { + Err(datadog::Error::Serde(serde::de::Error::custom( + "response content was None", + ))) + } + } + Err(err) => Err(err), + } + } + + /// Acquire the draft lock on a dataset for the calling user. The lock prevents other users from concurrently editing the dataset draft. + pub async fn lock_llm_obs_dataset_draft_state_with_http_info( + &self, + project_id: String, + dataset_id: String, + ) -> Result< + datadog::ResponseContent, + datadog::Error, + > { + let local_configuration = &self.config; + let operation_id = "v2.lock_llm_obs_dataset_draft_state"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.lock_llm_obs_dataset_draft_state' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/draft_state/lock", + local_configuration.get_operation_host(operation_id), + project_id = datadog::urlencode(project_id), + dataset_id = datadog::urlencode(dataset_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("application/json")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + match serde_json::from_str::( + &local_content, + ) { + Ok(e) => { + return Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: Some(e), + }) + } + Err(e) => return Err(datadog::Error::Serde(e)), + }; + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Search across LLM Observability experimentation entities — projects, datasets, dataset records, experiments, and experiment runs — using cursor-based pagination. /// /// The `filter.scope` field controls which entity types are returned. At least one valid scope must be provided. @@ -5661,6 +6066,109 @@ impl LLMObservabilityAPI { } } + /// Release the draft lock on a dataset held by the calling user, allowing other users to edit the dataset draft. + pub async fn unlock_llm_obs_dataset_draft_state( + &self, + project_id: String, + dataset_id: String, + ) -> Result<(), datadog::Error> { + match self + .unlock_llm_obs_dataset_draft_state_with_http_info(project_id, dataset_id) + .await + { + Ok(_) => Ok(()), + Err(err) => Err(err), + } + } + + /// Release the draft lock on a dataset held by the calling user, allowing other users to edit the dataset draft. + pub async fn unlock_llm_obs_dataset_draft_state_with_http_info( + &self, + project_id: String, + dataset_id: String, + ) -> Result, datadog::Error> + { + let local_configuration = &self.config; + let operation_id = "v2.unlock_llm_obs_dataset_draft_state"; + if local_configuration.is_unstable_operation_enabled(operation_id) { + warn!("Using unstable operation {operation_id}"); + } else { + let local_error = datadog::UnstableOperationDisabledError { + msg: "Operation 'v2.unlock_llm_obs_dataset_draft_state' is not enabled".to_string(), + }; + return Err(datadog::Error::UnstableOperationDisabledError(local_error)); + } + + let local_client = &self.client; + + let local_uri_str = format!( + "{}/api/v2/llm-obs/v1/{project_id}/datasets/{dataset_id}/draft_state/unlock", + local_configuration.get_operation_host(operation_id), + project_id = datadog::urlencode(project_id), + dataset_id = datadog::urlencode(dataset_id) + ); + let mut local_req_builder = + local_client.request(reqwest::Method::PATCH, local_uri_str.as_str()); + + // build headers + let mut headers = HeaderMap::new(); + headers.insert("Accept", HeaderValue::from_static("*/*")); + + // build user agent + match HeaderValue::from_str(local_configuration.user_agent.as_str()) { + Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent), + Err(e) => { + log::warn!("Failed to parse user agent header: {e}, falling back to default"); + headers.insert( + reqwest::header::USER_AGENT, + HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()), + ) + } + }; + + // build auth + if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") { + headers.insert( + "DD-API-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-API-KEY header"), + ); + }; + if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") { + headers.insert( + "DD-APPLICATION-KEY", + HeaderValue::from_str(local_key.key.as_str()) + .expect("failed to parse DD-APPLICATION-KEY header"), + ); + }; + + local_req_builder = local_req_builder.headers(headers); + let local_req = local_req_builder.build()?; + log::debug!("request content: {:?}", local_req.body()); + let local_resp = local_client.execute(local_req).await?; + + let local_status = local_resp.status(); + let local_content = local_resp.text().await?; + log::debug!("response content: {}", local_content); + + if !local_status.is_client_error() && !local_status.is_server_error() { + Ok(datadog::ResponseContent { + status: local_status, + content: local_content, + entity: None, + }) + } else { + let local_entity: Option = + serde_json::from_str(&local_content).ok(); + let local_error = datadog::ResponseContent { + status: local_status, + content: local_content, + entity: local_entity, + }; + Err(datadog::Error::ResponseError(local_error)) + } + } + /// Partially update an annotation queue. The `name`, `description`, and `annotation_schema` fields can be updated. pub async fn update_llm_obs_annotation_queue( &self, diff --git a/src/datadogV2/model/mod.rs b/src/datadogV2/model/mod.rs index d506516d13..8037ded73f 100644 --- a/src/datadogV2/model/mod.rs +++ b/src/datadogV2/model/mod.rs @@ -5366,6 +5366,16 @@ pub mod model_llm_obs_dataset_update_data_request; pub use self::model_llm_obs_dataset_update_data_request::LLMObsDatasetUpdateDataRequest; pub mod model_llm_obs_dataset_update_data_attributes_request; pub use self::model_llm_obs_dataset_update_data_attributes_request::LLMObsDatasetUpdateDataAttributesRequest; +pub mod model_llm_obs_dataset_draft_state_response; +pub use self::model_llm_obs_dataset_draft_state_response::LLMObsDatasetDraftStateResponse; +pub mod model_llm_obs_dataset_draft_state_data; +pub use self::model_llm_obs_dataset_draft_state_data::LLMObsDatasetDraftStateData; +pub mod model_llm_obs_dataset_draft_state_data_attributes; +pub use self::model_llm_obs_dataset_draft_state_data_attributes::LLMObsDatasetDraftStateDataAttributes; +pub mod model_llm_obs_dataset_draft_state_user; +pub use self::model_llm_obs_dataset_draft_state_user::LLMObsDatasetDraftStateUser; +pub mod model_llm_obs_dataset_draft_state_type; +pub use self::model_llm_obs_dataset_draft_state_type::LLMObsDatasetDraftStateType; pub mod model_llm_obs_dataset_records_list_response; pub use self::model_llm_obs_dataset_records_list_response::LLMObsDatasetRecordsListResponse; pub mod model_llm_obs_dataset_records_update_request; @@ -5396,6 +5406,14 @@ pub mod model_llm_obs_delete_dataset_records_data_request; pub use self::model_llm_obs_delete_dataset_records_data_request::LLMObsDeleteDatasetRecordsDataRequest; pub mod model_llm_obs_delete_dataset_records_data_attributes_request; pub use self::model_llm_obs_delete_dataset_records_data_attributes_request::LLMObsDeleteDatasetRecordsDataAttributesRequest; +pub mod model_llm_obs_dataset_versions_response; +pub use self::model_llm_obs_dataset_versions_response::LLMObsDatasetVersionsResponse; +pub mod model_llm_obs_dataset_version_data; +pub use self::model_llm_obs_dataset_version_data::LLMObsDatasetVersionData; +pub mod model_llm_obs_dataset_version_data_attributes; +pub use self::model_llm_obs_dataset_version_data_attributes::LLMObsDatasetVersionDataAttributes; +pub mod model_llm_obs_dataset_version_type; +pub use self::model_llm_obs_dataset_version_type::LLMObsDatasetVersionType; pub mod model_llm_obs_experiment_events_v2_response; pub use self::model_llm_obs_experiment_events_v2_response::LLMObsExperimentEventsV2Response; pub mod model_llm_obs_experiment_events_v2_data_response; diff --git a/src/datadogV2/model/model_llm_obs_dataset_draft_state_data.rs b/src/datadogV2/model/model_llm_obs_dataset_draft_state_data.rs new file mode 100644 index 0000000000..497c0548eb --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_draft_state_data.rs @@ -0,0 +1,126 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data object for an LLM Observability dataset draft state. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetDraftStateData { + /// Attributes of an LLM Observability dataset draft state. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::LLMObsDatasetDraftStateDataAttributes, + /// Unique identifier of the dataset draft state. Matches the dataset ID. + #[serde(rename = "id")] + pub id: String, + /// Resource type of an LLM Observability dataset draft state. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::LLMObsDatasetDraftStateType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetDraftStateData { + pub fn new( + attributes: crate::datadogV2::model::LLMObsDatasetDraftStateDataAttributes, + id: String, + type_: crate::datadogV2::model::LLMObsDatasetDraftStateType, + ) -> LLMObsDatasetDraftStateData { + LLMObsDatasetDraftStateData { + attributes, + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetDraftStateData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetDraftStateDataVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetDraftStateDataVisitor { + type Value = LLMObsDatasetDraftStateData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::LLMObsDatasetDraftStateDataAttributes, + > = None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::LLMObsDatasetDraftStateType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = LLMObsDatasetDraftStateData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetDraftStateDataVisitor) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_draft_state_data_attributes.rs b/src/datadogV2/model/model_llm_obs_dataset_draft_state_data_attributes.rs new file mode 100644 index 0000000000..e3d0f2d05f --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_draft_state_data_attributes.rs @@ -0,0 +1,107 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of an LLM Observability dataset draft state. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetDraftStateDataAttributes { + /// Timestamp when the dataset draft session started. + #[serde(rename = "drafting_since")] + pub drafting_since: chrono::DateTime, + /// User information associated with a dataset draft state. + #[serde(rename = "user")] + pub user: crate::datadogV2::model::LLMObsDatasetDraftStateUser, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetDraftStateDataAttributes { + pub fn new( + drafting_since: chrono::DateTime, + user: crate::datadogV2::model::LLMObsDatasetDraftStateUser, + ) -> LLMObsDatasetDraftStateDataAttributes { + LLMObsDatasetDraftStateDataAttributes { + drafting_since, + user, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetDraftStateDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetDraftStateDataAttributesVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetDraftStateDataAttributesVisitor { + type Value = LLMObsDatasetDraftStateDataAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut drafting_since: Option> = None; + let mut user: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "drafting_since" => { + drafting_since = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "user" => { + user = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let drafting_since = + drafting_since.ok_or_else(|| M::Error::missing_field("drafting_since"))?; + let user = user.ok_or_else(|| M::Error::missing_field("user"))?; + + let content = LLMObsDatasetDraftStateDataAttributes { + drafting_since, + user, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetDraftStateDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_draft_state_response.rs b/src/datadogV2/model/model_llm_obs_dataset_draft_state_response.rs new file mode 100644 index 0000000000..3a635bde64 --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_draft_state_response.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Response containing the draft state of an LLM Observability dataset. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetDraftStateResponse { + /// Data object for an LLM Observability dataset draft state. + #[serde(rename = "data")] + pub data: crate::datadogV2::model::LLMObsDatasetDraftStateData, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetDraftStateResponse { + pub fn new( + data: crate::datadogV2::model::LLMObsDatasetDraftStateData, + ) -> LLMObsDatasetDraftStateResponse { + LLMObsDatasetDraftStateResponse { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetDraftStateResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetDraftStateResponseVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetDraftStateResponseVisitor { + type Value = LLMObsDatasetDraftStateResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = LLMObsDatasetDraftStateResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetDraftStateResponseVisitor) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_draft_state_type.rs b/src/datadogV2/model/model_llm_obs_dataset_draft_state_type.rs new file mode 100644 index 0000000000..bd2df25738 --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_draft_state_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum LLMObsDatasetDraftStateType { + DRAFT_STATE_DATA, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for LLMObsDatasetDraftStateType { + fn to_string(&self) -> String { + match self { + Self::DRAFT_STATE_DATA => String::from("draft_state_data"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for LLMObsDatasetDraftStateType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetDraftStateType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "draft_state_data" => Self::DRAFT_STATE_DATA, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_draft_state_user.rs b/src/datadogV2/model/model_llm_obs_dataset_draft_state_user.rs new file mode 100644 index 0000000000..6480115a36 --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_draft_state_user.rs @@ -0,0 +1,160 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// User information associated with a dataset draft state. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetDraftStateUser { + /// Email address of the user. + #[serde(rename = "email")] + pub email: Option, + /// Handle of the user. + #[serde(rename = "handle")] + pub handle: Option, + /// Icon for the user. + #[serde(rename = "icon")] + pub icon: Option, + /// Unique identifier of the user holding the draft lock. + #[serde(rename = "id")] + pub id: String, + /// Display name of the user. + #[serde(rename = "name")] + pub name: Option, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetDraftStateUser { + pub fn new(id: String) -> LLMObsDatasetDraftStateUser { + LLMObsDatasetDraftStateUser { + email: None, + handle: None, + icon: None, + id, + name: None, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn email(mut self, value: String) -> Self { + self.email = Some(value); + self + } + + pub fn handle(mut self, value: String) -> Self { + self.handle = Some(value); + self + } + + pub fn icon(mut self, value: String) -> Self { + self.icon = Some(value); + self + } + + pub fn name(mut self, value: String) -> Self { + self.name = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetDraftStateUser { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetDraftStateUserVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetDraftStateUserVisitor { + type Value = LLMObsDatasetDraftStateUser; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut email: Option = None; + let mut handle: Option = None; + let mut icon: Option = None; + let mut id: Option = None; + let mut name: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "email" => { + if v.is_null() { + continue; + } + email = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "handle" => { + if v.is_null() { + continue; + } + handle = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "icon" => { + if v.is_null() { + continue; + } + icon = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "name" => { + if v.is_null() { + continue; + } + name = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + + let content = LLMObsDatasetDraftStateUser { + email, + handle, + icon, + id, + name, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetDraftStateUserVisitor) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_version_data.rs b/src/datadogV2/model/model_llm_obs_dataset_version_data.rs new file mode 100644 index 0000000000..326f3fbd52 --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_version_data.rs @@ -0,0 +1,126 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Data object for an LLM Observability dataset version. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetVersionData { + /// Attributes of an LLM Observability dataset version. + #[serde(rename = "attributes")] + pub attributes: crate::datadogV2::model::LLMObsDatasetVersionDataAttributes, + /// Unique identifier of the dataset version. + #[serde(rename = "id")] + pub id: String, + /// Resource type of an LLM Observability dataset version. + #[serde(rename = "type")] + pub type_: crate::datadogV2::model::LLMObsDatasetVersionType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetVersionData { + pub fn new( + attributes: crate::datadogV2::model::LLMObsDatasetVersionDataAttributes, + id: String, + type_: crate::datadogV2::model::LLMObsDatasetVersionType, + ) -> LLMObsDatasetVersionData { + LLMObsDatasetVersionData { + attributes, + id, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetVersionData { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetVersionDataVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetVersionDataVisitor { + type Value = LLMObsDatasetVersionData; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut attributes: Option< + crate::datadogV2::model::LLMObsDatasetVersionDataAttributes, + > = None; + let mut id: Option = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "attributes" => { + attributes = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "id" => { + id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV2::model::LLMObsDatasetVersionType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let attributes = attributes.ok_or_else(|| M::Error::missing_field("attributes"))?; + let id = id.ok_or_else(|| M::Error::missing_field("id"))?; + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = LLMObsDatasetVersionData { + attributes, + id, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetVersionDataVisitor) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_version_data_attributes.rs b/src/datadogV2/model/model_llm_obs_dataset_version_data_attributes.rs new file mode 100644 index 0000000000..e79216867f --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_version_data_attributes.rs @@ -0,0 +1,119 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Attributes of an LLM Observability dataset version. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetVersionDataAttributes { + /// Unique identifier of the dataset this version belongs to. + #[serde(rename = "dataset_id")] + pub dataset_id: String, + /// Timestamp when this dataset version was last referenced. Null if the version has never been used. + #[serialize_always] + #[serde(rename = "last_used")] + pub last_used: Option>, + /// Sequential version number for this dataset version. + #[serde(rename = "version_number")] + pub version_number: i32, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetVersionDataAttributes { + pub fn new( + dataset_id: String, + last_used: Option>, + version_number: i32, + ) -> LLMObsDatasetVersionDataAttributes { + LLMObsDatasetVersionDataAttributes { + dataset_id, + last_used, + version_number, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetVersionDataAttributes { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetVersionDataAttributesVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetVersionDataAttributesVisitor { + type Value = LLMObsDatasetVersionDataAttributes; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut dataset_id: Option = None; + let mut last_used: Option>> = None; + let mut version_number: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "dataset_id" => { + dataset_id = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "last_used" => { + last_used = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "version_number" => { + version_number = + Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let dataset_id = dataset_id.ok_or_else(|| M::Error::missing_field("dataset_id"))?; + let last_used = last_used.ok_or_else(|| M::Error::missing_field("last_used"))?; + let version_number = + version_number.ok_or_else(|| M::Error::missing_field("version_number"))?; + + let content = LLMObsDatasetVersionDataAttributes { + dataset_id, + last_used, + version_number, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetVersionDataAttributesVisitor) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_version_type.rs b/src/datadogV2/model/model_llm_obs_dataset_version_type.rs new file mode 100644 index 0000000000..df30f27bd2 --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_version_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum LLMObsDatasetVersionType { + DATASET_VERSION, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for LLMObsDatasetVersionType { + fn to_string(&self) -> String { + match self { + Self::DATASET_VERSION => String::from("dataset_version"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for LLMObsDatasetVersionType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetVersionType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "dataset_version" => Self::DATASET_VERSION, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/src/datadogV2/model/model_llm_obs_dataset_versions_response.rs b/src/datadogV2/model/model_llm_obs_dataset_versions_response.rs new file mode 100644 index 0000000000..a10ec91497 --- /dev/null +++ b/src/datadogV2/model/model_llm_obs_dataset_versions_response.rs @@ -0,0 +1,94 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// Response containing the active versions of an LLM Observability dataset. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LLMObsDatasetVersionsResponse { + /// List of dataset versions. + #[serde(rename = "data")] + pub data: Vec, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LLMObsDatasetVersionsResponse { + pub fn new( + data: Vec, + ) -> LLMObsDatasetVersionsResponse { + LLMObsDatasetVersionsResponse { + data, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LLMObsDatasetVersionsResponse { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LLMObsDatasetVersionsResponseVisitor; + impl<'a> Visitor<'a> for LLMObsDatasetVersionsResponseVisitor { + type Value = LLMObsDatasetVersionsResponse; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut data: Option> = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "data" => { + data = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let data = data.ok_or_else(|| M::Error::missing_field("data"))?; + + let content = LLMObsDatasetVersionsResponse { + data, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LLMObsDatasetVersionsResponseVisitor) + } +} diff --git a/tests/scenarios/features/v2/llm_observability.feature b/tests/scenarios/features/v2/llm_observability.feature index d21a1f8048..63b64631db 100644 --- a/tests/scenarios/features/v2/llm_observability.feature +++ b/tests/scenarios/features/v2/llm_observability.feature @@ -417,6 +417,33 @@ Feature: LLM Observability When the request is sent Then the response status is 404 Not Found + @generated @skip @team:DataDog/ml-observability + Scenario: Get LLM Observability dataset draft state returns "Bad Request" response + Given operation "GetLLMObsDatasetDraftState" enabled + And new "GetLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/ml-observability + Scenario: Get LLM Observability dataset draft state returns "Not Found" response + Given operation "GetLLMObsDatasetDraftState" enabled + And new "GetLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/ml-observability + Scenario: Get LLM Observability dataset draft state returns "OK" response + Given operation "GetLLMObsDatasetDraftState" enabled + And new "GetLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability Scenario: Get a custom evaluator configuration returns "Bad Request" response Given operation "GetLLMObsCustomEvalConfig" enabled @@ -538,6 +565,33 @@ Feature: LLM Observability When the request is sent Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability + Scenario: List LLM Observability dataset versions returns "Bad Request" response + Given operation "ListLLMObsDatasetVersions" enabled + And new "ListLLMObsDatasetVersions" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/ml-observability + Scenario: List LLM Observability dataset versions returns "Not Found" response + Given operation "ListLLMObsDatasetVersions" enabled + And new "ListLLMObsDatasetVersions" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/ml-observability + Scenario: List LLM Observability dataset versions returns "OK" response + Given operation "ListLLMObsDatasetVersions" enabled + And new "ListLLMObsDatasetVersions" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability Scenario: List LLM Observability datasets returns "Bad Request" response Given operation "ListLLMObsDatasets" enabled @@ -662,6 +716,33 @@ Feature: LLM Observability When the request is sent Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability + Scenario: Lock LLM Observability dataset draft state returns "Bad Request" response + Given operation "LockLLMObsDatasetDraftState" enabled + And new "LockLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/ml-observability + Scenario: Lock LLM Observability dataset draft state returns "Not Found" response + Given operation "LockLLMObsDatasetDraftState" enabled + And new "LockLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/ml-observability + Scenario: Lock LLM Observability dataset draft state returns "OK" response + Given operation "LockLLMObsDatasetDraftState" enabled + And new "LockLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability Scenario: Push events for an LLM Observability experiment returns "Accepted" response Given operation "CreateLLMObsExperimentEvents" enabled @@ -765,6 +846,33 @@ Feature: LLM Observability When the request is sent Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability + Scenario: Unlock LLM Observability dataset draft state returns "Bad Request" response + Given operation "UnlockLLMObsDatasetDraftState" enabled + And new "UnlockLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 400 Bad Request + + @generated @skip @team:DataDog/ml-observability + Scenario: Unlock LLM Observability dataset draft state returns "Not Found" response + Given operation "UnlockLLMObsDatasetDraftState" enabled + And new "UnlockLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 404 Not Found + + @generated @skip @team:DataDog/ml-observability + Scenario: Unlock LLM Observability dataset draft state returns "OK" response + Given operation "UnlockLLMObsDatasetDraftState" enabled + And new "UnlockLLMObsDatasetDraftState" request + And request contains "project_id" parameter from "REPLACE.ME" + And request contains "dataset_id" parameter from "REPLACE.ME" + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/ml-observability Scenario: Update LLM Observability dataset records returns "Bad Request" response Given operation "UpdateLLMObsDatasetRecords" enabled diff --git a/tests/scenarios/features/v2/undo.json b/tests/scenarios/features/v2/undo.json index e93351a7e2..f452679baf 100644 --- a/tests/scenarios/features/v2/undo.json +++ b/tests/scenarios/features/v2/undo.json @@ -3925,6 +3925,24 @@ "type": "idempotent" } }, + "GetLLMObsDatasetDraftState": { + "tag": "LLM Observability", + "undo": { + "type": "safe" + } + }, + "LockLLMObsDatasetDraftState": { + "tag": "LLM Observability", + "undo": { + "type": "idempotent" + } + }, + "UnlockLLMObsDatasetDraftState": { + "tag": "LLM Observability", + "undo": { + "type": "idempotent" + } + }, "ListLLMObsDatasetRecords": { "tag": "LLM Observability", "undo": { @@ -3962,6 +3980,12 @@ "type": "unsafe" } }, + "ListLLMObsDatasetVersions": { + "tag": "LLM Observability", + "undo": { + "type": "safe" + } + }, "ListLLMObsExperimentEvents": { "tag": "LLM Observability", "undo": { diff --git a/tests/scenarios/function_mappings.rs b/tests/scenarios/function_mappings.rs index e40df65135..7c03a174b2 100644 --- a/tests/scenarios/function_mappings.rs +++ b/tests/scenarios/function_mappings.rs @@ -2280,6 +2280,18 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.UpdateLLMObsDataset".into(), test_v2_update_llm_obs_dataset, ); + world.function_mappings.insert( + "v2.GetLLMObsDatasetDraftState".into(), + test_v2_get_llm_obs_dataset_draft_state, + ); + world.function_mappings.insert( + "v2.LockLLMObsDatasetDraftState".into(), + test_v2_lock_llm_obs_dataset_draft_state, + ); + world.function_mappings.insert( + "v2.UnlockLLMObsDatasetDraftState".into(), + test_v2_unlock_llm_obs_dataset_draft_state, + ); world.function_mappings.insert( "v2.ListLLMObsDatasetRecords".into(), test_v2_list_llm_obs_dataset_records, @@ -2296,6 +2308,10 @@ pub fn collect_function_calls(world: &mut DatadogWorld) { "v2.DeleteLLMObsDatasetRecords".into(), test_v2_delete_llm_obs_dataset_records, ); + world.function_mappings.insert( + "v2.ListLLMObsDatasetVersions".into(), + test_v2_list_llm_obs_dataset_versions, + ); world.function_mappings.insert( "v2.ListLLMObsExperimentEvents".into(), test_v2_list_llm_obs_experiment_events, @@ -15432,6 +15448,105 @@ fn test_v2_update_llm_obs_dataset(world: &mut DatadogWorld, _parameters: &HashMa world.response.code = response.status.as_u16(); } +fn test_v2_get_llm_obs_dataset_draft_state( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_llm_observability + .as_ref() + .expect("api instance not found"); + let project_id = + serde_json::from_value(_parameters.get("project_id").unwrap().clone()).unwrap(); + let dataset_id = + serde_json::from_value(_parameters.get("dataset_id").unwrap().clone()).unwrap(); + let response = match block_on( + api.get_llm_obs_dataset_draft_state_with_http_info(project_id, dataset_id), + ) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_lock_llm_obs_dataset_draft_state( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_llm_observability + .as_ref() + .expect("api instance not found"); + let project_id = + serde_json::from_value(_parameters.get("project_id").unwrap().clone()).unwrap(); + let dataset_id = + serde_json::from_value(_parameters.get("dataset_id").unwrap().clone()).unwrap(); + let response = + match block_on(api.lock_llm_obs_dataset_draft_state_with_http_info(project_id, dataset_id)) + { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + +fn test_v2_unlock_llm_obs_dataset_draft_state( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_llm_observability + .as_ref() + .expect("api instance not found"); + let project_id = + serde_json::from_value(_parameters.get("project_id").unwrap().clone()).unwrap(); + let dataset_id = + serde_json::from_value(_parameters.get("dataset_id").unwrap().clone()).unwrap(); + let response = match block_on( + api.unlock_llm_obs_dataset_draft_state_with_http_info(project_id, dataset_id), + ) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_llm_obs_dataset_records( world: &mut DatadogWorld, _parameters: &HashMap, @@ -15581,6 +15696,38 @@ fn test_v2_delete_llm_obs_dataset_records( world.response.code = response.status.as_u16(); } +fn test_v2_list_llm_obs_dataset_versions( + world: &mut DatadogWorld, + _parameters: &HashMap, +) { + let api = world + .api_instances + .v2_api_llm_observability + .as_ref() + .expect("api instance not found"); + let project_id = + serde_json::from_value(_parameters.get("project_id").unwrap().clone()).unwrap(); + let dataset_id = + serde_json::from_value(_parameters.get("dataset_id").unwrap().clone()).unwrap(); + let response = + match block_on(api.list_llm_obs_dataset_versions_with_http_info(project_id, dataset_id)) { + Ok(response) => response, + Err(error) => { + return match error { + Error::ResponseError(e) => { + world.response.code = e.status.as_u16(); + if let Some(entity) = e.entity { + world.response.object = serde_json::to_value(entity).unwrap(); + } + } + _ => panic!("error parsing response: {error}"), + }; + } + }; + world.response.object = serde_json::to_value(response.entity).unwrap(); + world.response.code = response.status.as_u16(); +} + fn test_v2_list_llm_obs_experiment_events( world: &mut DatadogWorld, _parameters: &HashMap,