Skip to main content

langfuse_client_base/apis/
unstable_evaluation_rules_api.rs

1/*
2 * langfuse
3 *
4 * ## Authentication  Authenticate with the API using [Basic Auth](https://en.wikipedia.org/wiki/Basic_access_authentication), get API keys in the project settings:  - username: Langfuse Public Key - password: Langfuse Secret Key  ## Exports  - OpenAPI spec: https://cloud.langfuse.com/generated/api/openapi.yml
5 *
6 * The version of the OpenAPI document:
7 *
8 * Generated by: https://openapi-generator.tech
9 */
10
11use super::{configuration, ContentType, Error};
12use crate::{apis::ResponseContent, models};
13use reqwest;
14use serde::{de::Error as _, Deserialize, Serialize};
15
16/// struct for typed errors of method [`unstable_evaluation_rules_create`]
17#[derive(Debug, Clone, Serialize, Deserialize)]
18#[serde(untagged)]
19pub enum UnstableEvaluationRulesCreateError {
20    Status400(serde_json::Value),
21    Status401(serde_json::Value),
22    Status403(serde_json::Value),
23    Status404(serde_json::Value),
24    Status405(serde_json::Value),
25    Status409(models::UnstablePublicApiError),
26    Status422(models::UnstablePublicApiError),
27    Status429(models::UnstablePublicApiError),
28    Status500(models::UnstablePublicApiError),
29    UnknownValue(serde_json::Value),
30}
31
32/// struct for typed errors of method [`unstable_evaluation_rules_delete`]
33#[derive(Debug, Clone, Serialize, Deserialize)]
34#[serde(untagged)]
35pub enum UnstableEvaluationRulesDeleteError {
36    Status400(serde_json::Value),
37    Status401(serde_json::Value),
38    Status403(serde_json::Value),
39    Status404(serde_json::Value),
40    Status405(serde_json::Value),
41    Status429(models::UnstablePublicApiError),
42    Status500(models::UnstablePublicApiError),
43    UnknownValue(serde_json::Value),
44}
45
46/// struct for typed errors of method [`unstable_evaluation_rules_get`]
47#[derive(Debug, Clone, Serialize, Deserialize)]
48#[serde(untagged)]
49pub enum UnstableEvaluationRulesGetError {
50    Status400(serde_json::Value),
51    Status401(serde_json::Value),
52    Status403(serde_json::Value),
53    Status404(serde_json::Value),
54    Status405(serde_json::Value),
55    Status429(models::UnstablePublicApiError),
56    Status500(models::UnstablePublicApiError),
57    UnknownValue(serde_json::Value),
58}
59
60/// struct for typed errors of method [`unstable_evaluation_rules_list`]
61#[derive(Debug, Clone, Serialize, Deserialize)]
62#[serde(untagged)]
63pub enum UnstableEvaluationRulesListError {
64    Status400(serde_json::Value),
65    Status401(serde_json::Value),
66    Status403(serde_json::Value),
67    Status404(serde_json::Value),
68    Status405(serde_json::Value),
69    Status429(models::UnstablePublicApiError),
70    Status500(models::UnstablePublicApiError),
71    UnknownValue(serde_json::Value),
72}
73
74/// struct for typed errors of method [`unstable_evaluation_rules_update`]
75#[derive(Debug, Clone, Serialize, Deserialize)]
76#[serde(untagged)]
77pub enum UnstableEvaluationRulesUpdateError {
78    Status400(serde_json::Value),
79    Status401(serde_json::Value),
80    Status403(serde_json::Value),
81    Status404(serde_json::Value),
82    Status405(serde_json::Value),
83    Status422(models::UnstablePublicApiError),
84    Status429(models::UnstablePublicApiError),
85    Status500(models::UnstablePublicApiError),
86    UnknownValue(serde_json::Value),
87}
88
89/// Create an evaluation rule.  An evaluation rule defines **what** incoming data should be evaluated and **how prompt variables should be populated** from that data.  Use this resource after choosing an evaluator from the evaluator endpoints.  Key rules: - `name` must be unique within the project for public evaluation rules - `target` must be `observation` or `experiment` - `evaluator.name` + `evaluator.scope` must identify an existing evaluator family returned by the evaluator endpoints - Langfuse resolves that family to its latest version before saving the evaluation rule - for `target=experiment`, use dataset `id` values from `GET /api/public/v2/datasets` when filtering by `datasetId` - every evaluator prompt variable must be mapped exactly once - `expected_output` mappings are only valid for `target=experiment` - if `enabled=true`, Langfuse validates that the referenced evaluator can currently run - at most 50 evaluation rules can be effectively active in one project at the same time  If an evaluation rule with the same `name` already exists in the project, the API returns `409`. In that case, update the existing resource with `PATCH /api/public/unstable/evaluation-rules/{evaluationRuleId}` instead of creating a second one.  If enabling this resource would exceed the 50-active limit, the API also returns `409`. In that case, disable or pause another active evaluation rule before enabling a new one.  Current scope: - evaluation rules are live-ingestion rules only - they do not trigger historical backfills  Recovery guidance: - `400 invalid_filter_value`: fix the filter `column` or `value` using `details.column`, `details.invalidValues`, and `details.allowedValues` - `400 invalid_filter_value` with `details.column=datasetId`: call `GET /api/public/v2/datasets`, then retry with dataset `id` values from that response - `400 missing_variable_mapping`: fetch the evaluator again and make sure every variable in `variables` appears exactly once in `mapping` - `400 duplicate_variable_mapping`: remove repeated mappings for the same variable - `400 invalid_variable_mapping`: switch to a valid `source` for the selected `target`, or fix the variable name - `400 invalid_json_path`: remove or correct the `jsonPath` - `422 evaluator_preflight_failed`: the selected evaluator cannot run with the resolved model configuration. Fix the evaluator/default model setup, then retry the create request.
90#[bon::builder]
91pub async fn unstable_evaluation_rules_create(
92    configuration: &configuration::Configuration,
93    unstable_create_evaluation_rule_request: models::UnstableCreateEvaluationRuleRequest,
94) -> Result<models::UnstableEvaluationRule, Error<UnstableEvaluationRulesCreateError>> {
95    // add a prefix to parameters to efficiently prevent name collisions
96    let p_body_unstable_create_evaluation_rule_request = unstable_create_evaluation_rule_request;
97
98    let uri_str = format!(
99        "{}/api/public/unstable/evaluation-rules",
100        configuration.base_path
101    );
102    let mut req_builder = configuration
103        .client
104        .request(reqwest::Method::POST, &uri_str);
105
106    if let Some(ref user_agent) = configuration.user_agent {
107        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
108    }
109    if let Some(ref auth_conf) = configuration.basic_auth {
110        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
111    };
112    req_builder = req_builder.json(&p_body_unstable_create_evaluation_rule_request);
113
114    let req = req_builder.build()?;
115    let resp = configuration.client.execute(req).await?;
116
117    let status = resp.status();
118    let content_type = resp
119        .headers()
120        .get("content-type")
121        .and_then(|v| v.to_str().ok())
122        .unwrap_or("application/octet-stream");
123    let content_type = super::ContentType::from(content_type);
124
125    if !status.is_client_error() && !status.is_server_error() {
126        let content = resp.text().await?;
127        match content_type {
128            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
129            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableEvaluationRule`"))),
130            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableEvaluationRule`")))),
131        }
132    } else {
133        let content = resp.text().await?;
134        let entity: Option<UnstableEvaluationRulesCreateError> =
135            serde_json::from_str(&content).ok();
136        Err(Error::ResponseError(ResponseContent {
137            status,
138            content,
139            entity,
140        }))
141    }
142}
143
144/// Delete an evaluation rule.  This removes the live-ingestion rule only. It does not delete the referenced evaluator.
145#[bon::builder]
146pub async fn unstable_evaluation_rules_delete(
147    configuration: &configuration::Configuration,
148    evaluation_rule_id: &str,
149) -> Result<models::UnstableDeleteEvaluationRuleResponse, Error<UnstableEvaluationRulesDeleteError>>
150{
151    // add a prefix to parameters to efficiently prevent name collisions
152    let p_path_evaluation_rule_id = evaluation_rule_id;
153
154    let uri_str = format!(
155        "{}/api/public/unstable/evaluation-rules/{evaluationRuleId}",
156        configuration.base_path,
157        evaluationRuleId = crate::apis::urlencode(p_path_evaluation_rule_id)
158    );
159    let mut req_builder = configuration
160        .client
161        .request(reqwest::Method::DELETE, &uri_str);
162
163    if let Some(ref user_agent) = configuration.user_agent {
164        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
165    }
166    if let Some(ref auth_conf) = configuration.basic_auth {
167        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
168    };
169
170    let req = req_builder.build()?;
171    let resp = configuration.client.execute(req).await?;
172
173    let status = resp.status();
174    let content_type = resp
175        .headers()
176        .get("content-type")
177        .and_then(|v| v.to_str().ok())
178        .unwrap_or("application/octet-stream");
179    let content_type = super::ContentType::from(content_type);
180
181    if !status.is_client_error() && !status.is_server_error() {
182        let content = resp.text().await?;
183        match content_type {
184            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
185            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableDeleteEvaluationRuleResponse`"))),
186            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableDeleteEvaluationRuleResponse`")))),
187        }
188    } else {
189        let content = resp.text().await?;
190        let entity: Option<UnstableEvaluationRulesDeleteError> =
191            serde_json::from_str(&content).ok();
192        Err(Error::ResponseError(ResponseContent {
193            status,
194            content,
195            entity,
196        }))
197    }
198}
199
200/// Get one evaluation rule by its identifier.  Use this endpoint to inspect the current evaluator, target, mapping, filters, and effective runtime status.
201#[bon::builder]
202pub async fn unstable_evaluation_rules_get(
203    configuration: &configuration::Configuration,
204    evaluation_rule_id: &str,
205) -> Result<models::UnstableEvaluationRule, Error<UnstableEvaluationRulesGetError>> {
206    // add a prefix to parameters to efficiently prevent name collisions
207    let p_path_evaluation_rule_id = evaluation_rule_id;
208
209    let uri_str = format!(
210        "{}/api/public/unstable/evaluation-rules/{evaluationRuleId}",
211        configuration.base_path,
212        evaluationRuleId = crate::apis::urlencode(p_path_evaluation_rule_id)
213    );
214    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
215
216    if let Some(ref user_agent) = configuration.user_agent {
217        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
218    }
219    if let Some(ref auth_conf) = configuration.basic_auth {
220        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
221    };
222
223    let req = req_builder.build()?;
224    let resp = configuration.client.execute(req).await?;
225
226    let status = resp.status();
227    let content_type = resp
228        .headers()
229        .get("content-type")
230        .and_then(|v| v.to_str().ok())
231        .unwrap_or("application/octet-stream");
232    let content_type = super::ContentType::from(content_type);
233
234    if !status.is_client_error() && !status.is_server_error() {
235        let content = resp.text().await?;
236        match content_type {
237            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
238            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableEvaluationRule`"))),
239            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableEvaluationRule`")))),
240        }
241    } else {
242        let content = resp.text().await?;
243        let entity: Option<UnstableEvaluationRulesGetError> = serde_json::from_str(&content).ok();
244        Err(Error::ResponseError(ResponseContent {
245            status,
246            content,
247            entity,
248        }))
249    }
250}
251
252/// List evaluation rules in the authenticated project.  Each item describes one live evaluation rule and its effective runtime status.
253#[bon::builder]
254pub async fn unstable_evaluation_rules_list(
255    configuration: &configuration::Configuration,
256    page: Option<i32>,
257    limit: Option<i32>,
258) -> Result<models::UnstableEvaluationRules, Error<UnstableEvaluationRulesListError>> {
259    // add a prefix to parameters to efficiently prevent name collisions
260    let p_query_page = page;
261    let p_query_limit = limit;
262
263    let uri_str = format!(
264        "{}/api/public/unstable/evaluation-rules",
265        configuration.base_path
266    );
267    let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
268
269    if let Some(ref param_value) = p_query_page {
270        req_builder = req_builder.query(&[("page", &param_value.to_string())]);
271    }
272    if let Some(ref param_value) = p_query_limit {
273        req_builder = req_builder.query(&[("limit", &param_value.to_string())]);
274    }
275    if let Some(ref user_agent) = configuration.user_agent {
276        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
277    }
278    if let Some(ref auth_conf) = configuration.basic_auth {
279        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
280    };
281
282    let req = req_builder.build()?;
283    let resp = configuration.client.execute(req).await?;
284
285    let status = resp.status();
286    let content_type = resp
287        .headers()
288        .get("content-type")
289        .and_then(|v| v.to_str().ok())
290        .unwrap_or("application/octet-stream");
291    let content_type = super::ContentType::from(content_type);
292
293    if !status.is_client_error() && !status.is_server_error() {
294        let content = resp.text().await?;
295        match content_type {
296            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
297            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableEvaluationRules`"))),
298            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableEvaluationRules`")))),
299        }
300    } else {
301        let content = resp.text().await?;
302        let entity: Option<UnstableEvaluationRulesListError> = serde_json::from_str(&content).ok();
303        Err(Error::ResponseError(ResponseContent {
304            status,
305            content,
306            entity,
307        }))
308    }
309}
310
311/// Update an evaluation rule.  Typical uses: - enable or disable live execution - switch to another evaluator - adjust sampling - change filters - update variable mappings  Important behavior: - provide only the fields you want to change - if you provide `evaluator`, Langfuse resolves that evaluator family to its latest version before saving - changing `target`, `filter`, or `mapping` must still produce a valid target-specific configuration - if you change `target`, also send a compatible `filter` and `mapping` in the same request unless the existing ones are still valid for the new target - if the resulting config is enabled, Langfuse re-validates that the selected evaluator can run - if the update would move a non-active evaluation rule into the active state and the project already has 50 active evaluation rules, the API returns `409`  Recovery guidance: - if the update fails with `missing_variable_mapping` or `invalid_variable_mapping` after changing `evaluator` or `target`, resend the request with a complete new `mapping` - if the update fails with `invalid_filter_value` after changing `target`, resend the request with a target-compatible `filter`
312#[bon::builder]
313pub async fn unstable_evaluation_rules_update(
314    configuration: &configuration::Configuration,
315    evaluation_rule_id: &str,
316    unstable_update_evaluation_rule_request: models::UnstableUpdateEvaluationRuleRequest,
317) -> Result<models::UnstableEvaluationRule, Error<UnstableEvaluationRulesUpdateError>> {
318    // add a prefix to parameters to efficiently prevent name collisions
319    let p_path_evaluation_rule_id = evaluation_rule_id;
320    let p_body_unstable_update_evaluation_rule_request = unstable_update_evaluation_rule_request;
321
322    let uri_str = format!(
323        "{}/api/public/unstable/evaluation-rules/{evaluationRuleId}",
324        configuration.base_path,
325        evaluationRuleId = crate::apis::urlencode(p_path_evaluation_rule_id)
326    );
327    let mut req_builder = configuration
328        .client
329        .request(reqwest::Method::PATCH, &uri_str);
330
331    if let Some(ref user_agent) = configuration.user_agent {
332        req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
333    }
334    if let Some(ref auth_conf) = configuration.basic_auth {
335        req_builder = req_builder.basic_auth(auth_conf.0.to_owned(), auth_conf.1.to_owned());
336    };
337    req_builder = req_builder.json(&p_body_unstable_update_evaluation_rule_request);
338
339    let req = req_builder.build()?;
340    let resp = configuration.client.execute(req).await?;
341
342    let status = resp.status();
343    let content_type = resp
344        .headers()
345        .get("content-type")
346        .and_then(|v| v.to_str().ok())
347        .unwrap_or("application/octet-stream");
348    let content_type = super::ContentType::from(content_type);
349
350    if !status.is_client_error() && !status.is_server_error() {
351        let content = resp.text().await?;
352        match content_type {
353            ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
354            ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UnstableEvaluationRule`"))),
355            ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UnstableEvaluationRule`")))),
356        }
357    } else {
358        let content = resp.text().await?;
359        let entity: Option<UnstableEvaluationRulesUpdateError> =
360            serde_json::from_str(&content).ok();
361        Err(Error::ResponseError(ResponseContent {
362            status,
363            content,
364            entity,
365        }))
366    }
367}