diff --git a/frontend/.vscode/settings.json b/.vscode/settings.json similarity index 89% rename from frontend/.vscode/settings.json rename to .vscode/settings.json index d90530ee..91fc4437 100644 --- a/frontend/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,5 +13,6 @@ }, "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" - } -} \ No newline at end of file + }, + "eslint.validate": ["javascript"] +} diff --git a/app-server/.vscode/settings.json b/app-server/.vscode/settings.json deleted file mode 100644 index a20c02b5..00000000 --- a/app-server/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rust-analyzer.showUnlinkedFileNotification": false, - "editor.defaultFormatter": "rust-lang.rust-analyzer", - "editor.formatOnSave": true -} \ No newline at end of file diff --git a/app-server/src/api/v1/traces.rs b/app-server/src/api/v1/traces.rs index 6b17bc88..2b38ae0f 100644 --- a/app-server/src/api/v1/traces.rs +++ b/app-server/src/api/v1/traces.rs @@ -1,18 +1,13 @@ use std::sync::Arc; -use actix_web::{get, post, web, HttpRequest, HttpResponse}; +use actix_web::{post, web, HttpRequest, HttpResponse}; use bytes::Bytes; use lapin::Connection; use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::{ - db::{ - events::{self, EventObservation}, - project_api_keys::ProjectApiKey, - spans::Span, - DB, - }, + db::{events::Event, project_api_keys::ProjectApiKey, spans::Span, DB}, features::{is_feature_enabled, Feature}, opentelemetry::opentelemetry::proto::collector::trace::v1::ExportTraceServiceRequest, routes::types::ResponseResult, @@ -20,11 +15,11 @@ use crate::{ }; use prost::Message; -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Clone)] pub struct RabbitMqSpanMessage { pub project_id: Uuid, pub span: Span, - pub events: Vec, + pub events: Vec, } #[post("traces")] @@ -78,23 +73,3 @@ pub async fn process_traces( Ok(HttpResponse::Ok().finish()) } } - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GetEventsForSessionRequest { - session_id: String, -} - -#[get("session-events")] -pub async fn get_events_for_session( - request: web::Query, - project_api_key: ProjectApiKey, - db: web::Data, -) -> ResponseResult { - let project_id = project_api_key.project_id; - let session_id = request.session_id.clone(); - let events = events::get_events_for_session(&db.pool, &session_id, &project_id) - .await - .map_err(|e| anyhow::anyhow!("Failed to get events for session: {}", e))?; - Ok(HttpResponse::Ok().json(events)) -} diff --git a/app-server/src/ch/events.rs b/app-server/src/ch/events.rs index 7515b632..4bde840a 100644 --- a/app-server/src/ch/events.rs +++ b/app-server/src/ch/events.rs @@ -1,90 +1,30 @@ use anyhow::Result; -use chrono::{DateTime, Utc}; use clickhouse::Row; use serde::Serialize; -use serde_repr::Serialize_repr; use uuid::Uuid; -use crate::{ - db::{self, event_templates::EventTemplate}, - features::{is_feature_enabled, Feature}, -}; +use crate::{db::events::Event, features::is_feature_enabled, Feature}; -use super::{ - modifiers::GroupByInterval, - utils::{ - chrono_to_nanoseconds, group_by_time_absolute_statement, group_by_time_relative_statement, - }, - MetricTimeValue, -}; - -#[derive(Debug, Serialize_repr)] -#[repr(u8)] -pub enum EventSource { - CODE = 0, - AUTO = 1, - MANUAL = 2, -} - -impl From for EventSource { - fn from(source: db::events::EventSource) -> Self { - match source { - db::events::EventSource::CODE => EventSource::CODE, - db::events::EventSource::AUTO => EventSource::AUTO, - db::events::EventSource::MANUAL => EventSource::MANUAL, - } - } -} - -#[derive(Debug, Serialize_repr)] -#[repr(u8)] -pub enum EventType { - BOOLEAN = 0, - NUMBER = 1, - STRING = 2, -} - -impl From for EventType { - fn from(event_type: db::event_templates::EventType) -> Self { - match event_type { - db::event_templates::EventType::BOOLEAN => EventType::BOOLEAN, - db::event_templates::EventType::NUMBER => EventType::NUMBER, - db::event_templates::EventType::STRING => EventType::STRING, - } - } -} +use super::utils::chrono_to_nanoseconds; #[derive(Row, Serialize)] pub struct CHEvent { #[serde(with = "clickhouse::serde::uuid")] pub id: Uuid, - /// Timestamp in nanoseconds - pub timestamp: i64, - pub source: EventSource, - #[serde(with = "clickhouse::serde::uuid")] - pub template_id: Uuid, - pub template_name: String, - pub event_type: EventType, #[serde(with = "clickhouse::serde::uuid")] pub project_id: Uuid, + /// Timestamp in nanoseconds + pub timestamp: i64, + pub name: String, } impl CHEvent { - pub fn from_data( - id: Uuid, - timestamp: DateTime, - event_template: EventTemplate, - source: EventSource, - project_id: Uuid, - ) -> Self { + pub fn from_db_event(event: &Event) -> Self { CHEvent { - id, - timestamp: chrono_to_nanoseconds(timestamp), - source, - template_id: event_template.id, - template_name: event_template.name, - event_type: event_template.event_type.into(), - project_id, + id: event.id, + timestamp: chrono_to_nanoseconds(event.timestamp), + name: event.name.clone(), + project_id: event.project_id, } } } @@ -120,76 +60,3 @@ pub async fn insert_events(clickhouse: clickhouse::Client, events: Vec) } } } - -pub async fn get_total_event_count_metrics_relative( - clickhouse: clickhouse::Client, - group_by_interval: GroupByInterval, - project_id: Uuid, - template_id: Uuid, - past_hours: i64, -) -> Result>> { - let ch_round_time = group_by_interval.to_ch_truncate_time(); - - let query_string = format!( - " - SELECT - {ch_round_time}(timestamp) AS time, - COUNT(DISTINCT id) AS value - FROM events - WHERE - project_id = ? - AND template_id = ? - AND timestamp >= now() - INTERVAL ? HOUR - {}", - group_by_time_relative_statement(past_hours, group_by_interval), - ); - - let rows: Vec> = clickhouse - .query(&query_string) - .bind(project_id) - .bind(template_id) - .bind(past_hours) - .fetch_all::>() - .await?; - - Ok(rows) -} - -pub async fn get_total_event_count_metrics_absolute( - clickhouse: clickhouse::Client, - group_by_interval: GroupByInterval, - project_id: Uuid, - template_id: Uuid, - start_time: DateTime, - end_time: DateTime, -) -> Result>> { - let ch_round_time = group_by_interval.to_ch_truncate_time(); - let ch_start_time = start_time.timestamp(); - let ch_end_time = end_time.timestamp(); - - let query_string = format!( - " - SELECT - {ch_round_time}(timestamp) AS time, - COUNT(DISTINCT id) AS value - FROM events - WHERE - project_id = ? - AND template_id = ? - AND timestamp >= fromUnixTimestamp(?) - AND timestamp <= fromUnixTimestamp(?) - {}", - group_by_time_absolute_statement(start_time, end_time, group_by_interval) - ); - - let rows: Vec> = clickhouse - .query(&query_string) - .bind(project_id) - .bind(template_id) - .bind(ch_start_time) - .bind(ch_end_time) - .fetch_all::>() - .await?; - - Ok(rows) -} diff --git a/app-server/src/db/event_templates.rs b/app-server/src/db/event_templates.rs deleted file mode 100644 index 8b7153f1..00000000 --- a/app-server/src/db/event_templates.rs +++ /dev/null @@ -1,207 +0,0 @@ -use std::collections::HashMap; - -use anyhow::Result; -use chrono::{DateTime, Utc}; -use serde::{Deserialize, Serialize}; -use sqlx::PgPool; -use uuid::Uuid; - -#[derive(sqlx::Type, Deserialize, Serialize, Debug, Clone, PartialEq)] -#[sqlx(type_name = "event_type")] -pub enum EventType { - BOOLEAN, - NUMBER, - STRING, -} - -/// Event type for a project -/// -/// (name, project_id) is a unique constraint -#[derive(Serialize, sqlx::FromRow, Clone)] -#[serde(rename_all = "camelCase")] -pub struct EventTemplate { - pub id: Uuid, - pub created_at: DateTime, - pub name: String, - pub project_id: Uuid, - pub event_type: EventType, -} - -#[derive(Serialize, sqlx::FromRow, Clone)] -#[serde(rename_all = "camelCase")] -pub struct EventTemplateWithLatestTimestamp { - pub id: Uuid, - pub created_at: DateTime, - pub name: String, - pub project_id: Uuid, - pub event_type: EventType, - pub latest_timestamp: Option>, -} - -pub async fn get_event_templates_by_project_id( - pool: &PgPool, - project_id: Uuid, -) -> Result> { - let event_templates = sqlx::query_as::<_, EventTemplateWithLatestTimestamp>( - " - WITH latest_occurences as ( - SELECT - template_id, - MAX(created_at) as latest_timestamp - FROM events - GROUP BY template_id - ) - SELECT - id, - created_at, - name, - project_id, - event_type, - latest_timestamp - FROM event_templates - LEFT JOIN latest_occurences ON event_templates.id = latest_occurences.template_id - WHERE project_id = $1 - ORDER BY latest_timestamp DESC NULLS LAST", - ) - .bind(project_id) - .fetch_all(pool) - .await?; - - Ok(event_templates) -} - -/// Get event template by name and project_id -/// -/// (project_id, name) is a unique constraint -pub async fn get_event_template_by_name( - pool: &PgPool, - name: &str, - project_id: Uuid, -) -> Result> { - let event_template = sqlx::query_as::<_, EventTemplate>( - "SELECT - id, - created_at, - name, - project_id, - event_type - FROM event_templates - WHERE name = $1 AND project_id = $2", - ) - .bind(name) - .bind(project_id) - .fetch_optional(pool) - .await?; - - Ok(event_template) -} - -pub async fn get_event_template_by_id(pool: &PgPool, id: &Uuid) -> Result { - let event_template = sqlx::query_as::<_, EventTemplate>( - "SELECT - id, - created_at, - name, - project_id, - event_type - FROM event_templates - WHERE id = $1 - ORDER BY created_at DESC - LIMIT 1", - ) - .bind(id) - .fetch_one(pool) - .await?; - - Ok(event_template) -} - -/// Create event template without raising an error if it already exists -/// -/// If users send event template creation request simultaneously, we need to ensure they all have the same event type. -pub async fn create_event_template_idempotent( - pool: &PgPool, - name: &str, - project_id: Uuid, - event_type: EventType, -) -> Result { - // Do nothing on conflict, i.e. do not update event type - sqlx::query( - "INSERT INTO event_templates (name, project_id, event_type) - VALUES ($1, $2, $3) - ON CONFLICT (name, project_id) DO NOTHING", - ) - .bind(name) - .bind(project_id) - .bind(&event_type) - .execute(pool) - .await?; - - // https://stackoverflow.com/questions/34708509/how-to-use-returning-with-on-conflict-in-postgresql - let event_template = get_event_template_by_name(pool, name, project_id).await?; - let event_template = event_template.unwrap(); - - if event_template.event_type != event_type { - return Err(anyhow::anyhow!( - "Event template already exists with different event type, current: {:?}, attempted: {:?}", - event_template.event_type, - event_type - )); - } - - Ok(event_template) -} - -/// Updates event type -/// -/// This must not be possible. If you want to change the event type, you must delete the event template and create a new one. -pub async fn update_event_template( - pool: &PgPool, - id: Uuid, - project_id: Uuid, - event_type: EventType, -) -> Result { - let event_template = sqlx::query_as::<_, EventTemplate>( - "UPDATE event_templates - SET event_type = $3 - WHERE id = $1 AND project_id = $2 - RETURNING id, created_at, name, project_id, event_type", - ) - .bind(id) - .bind(project_id) - .bind(event_type) - .fetch_one(pool) - .await?; - - Ok(event_template) -} - -pub async fn delete_event_template(pool: &PgPool, id: &Uuid) -> Result<()> { - sqlx::query("DELETE FROM event_templates WHERE id = $1") - .bind(id) - .execute(pool) - .await?; - - Ok(()) -} - -pub async fn get_event_templates_map( - pool: &PgPool, - names: &Vec, - project_id: Uuid, -) -> Result> { - let records = sqlx::query_as::<_, EventTemplate>( - "SELECT id, created_at, name, project_id, event_type FROM event_templates WHERE name = ANY($1) and project_id = $2", - ) - .bind(names) - .bind(project_id) - .fetch_all(pool) - .await?; - - let mut res = HashMap::new(); - for record in records { - res.insert(record.name.clone(), record); - } - - Ok(res) -} diff --git a/app-server/src/db/events.rs b/app-server/src/db/events.rs index 669a5849..ea7f0c87 100644 --- a/app-server/src/db/events.rs +++ b/app-server/src/db/events.rs @@ -1,172 +1,57 @@ -use std::sync::Arc; - use anyhow::Result; use chrono::{DateTime, TimeZone, Utc}; -use regex::Regex; use serde::{Deserialize, Serialize}; use serde_json::Value; -use sqlx::{PgPool, Postgres, QueryBuilder}; +use sqlx::{FromRow, PgPool}; use uuid::Uuid; -use crate::{ - opentelemetry::opentelemetry_proto_trace_v1::span::Event as OtelEvent, - traces::span_attributes::EVENT_VALUE, -}; - -use super::{ - event_templates::EventType, - modifiers::{DateRange, Filter}, - utils::{add_date_range_to_query, convert_any_value_to_json_value}, - DB, -}; +use crate::opentelemetry::opentelemetry_proto_trace_v1::span::Event as OtelEvent; -#[derive(sqlx::Type, Deserialize, Serialize, Clone)] -#[sqlx(type_name = "event_source")] -pub enum EventSource { - AUTO, - MANUAL, - CODE, -} +use super::utils::convert_any_value_to_json_value; -#[derive(Deserialize, Serialize, Clone, Debug)] +#[derive(Deserialize, Serialize, Clone, FromRow)] #[serde(rename_all = "camelCase")] -pub struct EventObservation { +pub struct Event { pub id: Uuid, pub span_id: Uuid, + pub project_id: Uuid, + pub created_at: DateTime, pub timestamp: DateTime, - /// Unique type name - pub template_name: String, - pub value: Option, + pub name: String, + pub attributes: Value, } -impl EventObservation { - pub fn from_otel(event: OtelEvent, span_id: Uuid) -> Self { +impl Event { + pub fn from_otel(event: OtelEvent, span_id: Uuid, project_id: Uuid) -> Self { let attributes = event .attributes .into_iter() .map(|kv| (kv.key, convert_any_value_to_json_value(kv.value))) .collect::>(); - let value = attributes.get(EVENT_VALUE).cloned(); - Self { id: Uuid::new_v4(), span_id, + project_id, + created_at: Utc::now(), timestamp: Utc.timestamp_nanos(event.time_unix_nano as i64), - template_name: event.name, - value, + name: event.name, + attributes: Value::Object(attributes), } } } -#[derive(sqlx::FromRow, Serialize)] -#[serde(rename_all = "camelCase")] -pub struct EventWithTemplateName { - pub id: Uuid, - pub created_at: DateTime, - pub span_id: Uuid, - pub timestamp: DateTime, - pub template_id: Uuid, - pub template_name: String, - pub template_event_type: EventType, - pub source: EventSource, - pub metadata: Option, - pub value: Option, - // Usually, inputs are used for evaluated events; none for regular events - pub inputs: Option, -} - -/// Create events -/// -/// For now, record them without metadata -pub async fn create_events( - pool: &PgPool, - ids: &Vec, - span_ids: &Vec, - timestamps: &Vec>, - template_ids: &Vec, - source: &EventSource, - values: &Vec>, -) -> Result<()> { - sqlx::query( - "INSERT INTO events (id, span_id, timestamp, template_id, source, value) - SELECT unnest($1::uuid[]), unnest($2::uuid[]), unnest($3::timestamptz[]), unnest($4::uuid[]), $5, unnest($6::jsonb[])", - ) - .bind(ids) - .bind(span_ids) - .bind(timestamps) - .bind(template_ids) - .bind(source) - .bind(values) - .execute(pool) - .await?; - - Ok(()) -} - -pub async fn create_events_by_template_name( - db: Arc, - events: Vec, - template_ids: &Vec, - source: &EventSource, -) -> Result<()> { - if events.is_empty() { - return Ok(()); - } - - if events.len() != template_ids.len() { - return Err(anyhow::anyhow!( - "Number of events ({}) does not match number of template_ids ({})", - events.len(), - template_ids.len() - )); - } - - let mut ids = vec![]; - let mut span_ids = vec![]; - let mut timestamps = vec![]; - let mut values = vec![]; - - for event in events { - ids.push(event.id); - span_ids.push(event.span_id); - timestamps.push(event.timestamp); - values.push(event.value); - } - - create_events( - &db.pool, - &ids, - &span_ids, - ×tamps, - template_ids, - source, - &values, - ) - .await?; - - Ok(()) -} - -pub async fn get_events_for_span( - pool: &PgPool, - span_id: Uuid, -) -> Result> { - let events = sqlx::query_as::<_, EventWithTemplateName>( +pub async fn get_events_for_span(pool: &PgPool, span_id: Uuid) -> Result> { + let events = sqlx::query_as::<_, Event>( "SELECT e.id, e.created_at, e.span_id, + e.project_id, e.timestamp, - e.template_id, - event_templates.name as template_name, - event_templates.event_type as template_event_type, - e.source, - e.metadata, - e.value, - e.inputs + e.name, + e.attributes FROM events e - JOIN event_templates ON e.template_id = event_templates.id WHERE span_id = $1 ORDER BY e.timestamp ASC", ) @@ -177,177 +62,34 @@ pub async fn get_events_for_span( Ok(events) } -pub async fn get_events_by_template_id( - pool: &PgPool, - template_id: &Uuid, - date_range: &Option, - filters: &Option>, - offset: usize, - limit: usize, -) -> Result> { - let mut query = QueryBuilder::::new( - "SELECT - e.id, - e.created_at, - e.span_id, - e.timestamp, - e.template_id, - event_templates.name as template_name, - event_templates.event_type as template_event_type, - e.source, - e.metadata, - e.value, - e.inputs - FROM events e - JOIN event_templates ON e.template_id = event_templates.id - WHERE event_templates.id = ", - ); - query.push_bind(template_id); - - add_filters_to_events_query(&mut query, filters); - - add_date_range_to_query(&mut query, date_range, "e.timestamp", None)?; - - query.push(" ORDER BY e.timestamp DESC "); - query.push(" LIMIT "); - query.push_bind(limit as i64); - query.push(" OFFSET "); - query.push_bind(offset as i64); - - let events = query - .build_query_as::<'_, EventWithTemplateName>() - .fetch_all(pool) - .await?; - - Ok(events) -} - -#[derive(sqlx::FromRow)] -struct TotalCount { - count: i64, -} - -pub async fn count_events_by_template_id( - pool: &PgPool, - template_id: &Uuid, - date_range: &Option, - filters: &Option>, -) -> Result { - let mut query = QueryBuilder::::new( - "SELECT COUNT(*) count - FROM events e - JOIN event_templates ON e.template_id = event_templates.id - WHERE event_templates.id = ", - ); - query.push_bind(template_id); - - add_filters_to_events_query(&mut query, filters); - - add_date_range_to_query(&mut query, date_range, "e.timestamp", None)?; - - let count = query - .build_query_as::<'_, TotalCount>() - .fetch_one(pool) - .await?; - - Ok(count.count) -} - -pub async fn count_all_events_by_template_id_in_project( - pool: &PgPool, - template_id: &Uuid, - project_id: &Uuid, -) -> Result { - let count = sqlx::query_as::<_, TotalCount>( - "SELECT COUNT(*) count - FROM events e - JOIN event_templates ON e.template_id = event_templates.id - WHERE event_templates.id = $1 - AND project_id = $2", - ) - .bind(template_id) - .bind(project_id) - .fetch_one(pool) - .await?; - - Ok(count.count) -} +pub async fn insert_events(pool: &PgPool, events: &Vec) -> Result<()> { + let span_ids = events.iter().map(|e| e.span_id).collect::>(); + let project_ids = events.iter().map(|e| e.project_id).collect::>(); + let timestamps = events + .iter() + .map(|e| e.timestamp) + .collect::>>(); + let names = events + .iter() + .map(|e| e.name.clone()) + .collect::>(); + let attributes = events + .iter() + .map(|e| e.attributes.clone()) + .collect::>(); -pub async fn get_events_for_session( - pool: &PgPool, - session_id: &String, - project_id: &Uuid, -) -> Result> { - let events = sqlx::query_as::<_, EventWithTemplateName>( - "SELECT - e.id, - e.created_at, - e.span_id, - e.timestamp, - e.template_id, - event_templates.name as template_name, - event_templates.event_type as template_event_type: EventType, - e.source as source: EventSource, - e.metadata, - e.value, - e.inputs - FROM events e - JOIN event_templates ON e.template_id = event_templates.id - WHERE span_id IN ( - SELECT id from spans where trace_id IN ( - SELECT id from traces where session_id = $1 - ) - ) - AND project_id = $2", + sqlx::query( + "INSERT INTO events (span_id, project_id, timestamp, name, attributes) + VALUES (UNNEST($1), UNNEST($2), UNNEST($3), UNNEST($4), UNNEST($5)) + ", ) - .bind(session_id) - .bind(project_id) - .fetch_all(pool) + .bind(span_ids) + .bind(project_ids) + .bind(timestamps) + .bind(names) + .bind(attributes) + .execute(pool) .await?; - Ok(events) -} - -fn add_filters_to_events_query(query: &mut QueryBuilder, filters: &Option>) { - if let Some(filters) = filters { - filters.iter().for_each(|filter| { - let filter_value = match &filter.filter_value { - Value::String(v) => match serde_json::from_str(v) { - Ok(v) => v, - Err(_) => v.clone().into(), - }, - v => v.clone(), - }; - let filter_value_str = match &filter.filter_value { - Value::String(s) => s.clone(), - v => v.to_string(), - }; - if !filter.validate_column() { - log::warn!("Invalid column name: {}", filter.filter_column); - return; - } - query.push(" AND e."); - query.push(&filter.filter_column); - - query.push(filter.filter_operator.to_sql_operator()); - if ["id", "span_id"] - .iter() - .any(|col| col == &filter.filter_column.as_str()) - { - let padded_uuid = if Regex::new(r"^[\da-fA-F]{4}-[\da-fA-F]{12}$") - .unwrap() - .is_match(&filter_value_str) - { - format!("00000000-0000-0000-{}", filter_value_str) - } else { - filter_value_str - }; - query.push_bind(Uuid::parse_str(&padded_uuid).unwrap_or_default()); - } else if &filter.filter_column == "value" { - query.push_bind(filter_value); - } else { - query.push_bind(filter_value_str); - } - }); - } + Ok(()) } diff --git a/app-server/src/db/mod.rs b/app-server/src/db/mod.rs index b5ce8f2d..111a5f96 100644 --- a/app-server/src/db/mod.rs +++ b/app-server/src/db/mod.rs @@ -3,7 +3,6 @@ use sqlx::PgPool; pub mod datapoints; pub mod datasets; pub mod evaluations; -pub mod event_templates; pub mod events; pub mod labeling_queues; pub mod labels; diff --git a/app-server/src/db/spans.rs b/app-server/src/db/spans.rs index 603d1db6..c2398669 100644 --- a/app-server/src/db/spans.rs +++ b/app-server/src/db/spans.rs @@ -148,21 +148,18 @@ pub async fn get_trace_spans( "WITH span_events AS ( SELECT events.span_id, - event_templates.project_id, + events.project_id, jsonb_agg( jsonb_build_object( 'id', events.id, 'spanId', events.span_id, 'timestamp', events.timestamp, - 'templateId', events.template_id, - 'templateName', event_templates.name, - 'templateEventType', event_templates.event_type, - 'source', events.source + 'name', events.name, + 'attributes', events.attributes ) ) AS events FROM events - JOIN event_templates ON events.template_id = event_templates.id - GROUP BY events.span_id, event_templates.project_id + GROUP BY events.span_id, events.project_id ), span_labels AS ( SELECT labels.span_id, diff --git a/app-server/src/db/trace.rs b/app-server/src/db/trace.rs index 303e24f1..85335318 100644 --- a/app-server/src/db/trace.rs +++ b/app-server/src/db/trace.rs @@ -270,12 +270,7 @@ fn add_filters_to_traces_query(query: &mut QueryBuilder, filters: &Opt .strip_prefix("event.") .unwrap() .to_string(); - filter_by_event_value( - query, - template_name, - filter.filter_operator.clone(), - filter.filter_value.clone(), - ); + filter_by_event_name(query, template_name); return; } if filter.filter_column == "labels" { @@ -347,26 +342,17 @@ fn add_filters_to_traces_query(query: &mut QueryBuilder, filters: &Opt } } -fn filter_by_event_value( - query: &mut QueryBuilder, - template_name: String, - filter_operator: FilterOperator, - event_value: Value, -) { +fn filter_by_event_name(query: &mut QueryBuilder, name: String) { query.push( " AND id IN (SELECT trace_id FROM spans JOIN events ON spans.span_id = events.span_id - JOIN event_templates ON events.template_id = event_templates.id - WHERE event_templates.name = + WHERE events.name = ", ); - query.push_bind(template_name); - query.push(" AND events.value "); - query.push(filter_operator.to_sql_operator()); - query.push_bind(event_value); - query.push("::jsonb)"); + query.push_bind(name); + query.push(")"); } fn filter_by_span_label_value( diff --git a/app-server/src/db/user.rs b/app-server/src/db/user.rs index f0840397..5b13fcc1 100644 --- a/app-server/src/db/user.rs +++ b/app-server/src/db/user.rs @@ -46,27 +46,6 @@ pub async fn get_by_email(pool: &PgPool, email: &str) -> Result> { .map_err(|e| e.into()) } -pub async fn get_by_stripe_customer_id( - pool: &PgPool, - stripe_customer_id: &str, -) -> Result { - let user = sqlx::query_as::<_, UserInfo>( - "SELECT - users.id, - users.name, - users.email - FROM - users - left join user_subscription_info on users.id = user_subscription_info.user_id - WHERE user_subscription_info.stripe_customer_id = $1", - ) - .bind(stripe_customer_id) - .fetch_one(pool) - .await?; - - Ok(user) -} - pub async fn write_user(pool: &PgPool, id: &Uuid, email: &String, name: &String) -> Result<()> { sqlx::query("INSERT INTO users (id, name, email) values ($1, $2, $3)") .bind(id) diff --git a/app-server/src/main.rs b/app-server/src/main.rs index ecd316a1..cbdf5561 100644 --- a/app-server/src/main.rs +++ b/app-server/src/main.rs @@ -399,7 +399,6 @@ fn main() -> anyhow::Result<()> { .wrap(project_auth.clone()) .service(api::v1::pipelines::run_pipeline_graph) .service(api::v1::pipelines::ping_healthcheck) - .service(api::v1::traces::get_events_for_session) .service(api::v1::traces::process_traces) .service(api::v1::datasets::get_datapoints) .service(api::v1::evaluations::create_evaluation) @@ -514,12 +513,6 @@ fn main() -> anyhow::Result<()> { routes::labels::get_registered_label_classes_for_path, ) .service(routes::labels::update_label_class) - .service(routes::events::get_event_templates) - .service(routes::events::get_event_template) - .service(routes::events::update_event_template) - .service(routes::events::delete_event_template) - .service(routes::events::get_events_by_template_id) - .service(routes::events::get_events_metrics) .service(routes::traces::get_traces_metrics) .service(routes::provider_api_keys::save_api_key), ), diff --git a/app-server/src/pipeline/mod.rs b/app-server/src/pipeline/mod.rs index 54e6cdfd..428f7f6e 100644 --- a/app-server/src/pipeline/mod.rs +++ b/app-server/src/pipeline/mod.rs @@ -126,7 +126,6 @@ impl Graph { name: handle.name.clone().unwrap(), inputs: vec![output_node_input_handle.clone()], inputs_mappings: HashMap::from([(output_node_input_handle.id, handle.id)]), - output_cast_type: None, }); pred.insert(output_node.id(), vec![node.id()]); nodes.insert(output_node.name().clone(), output_node); diff --git a/app-server/src/pipeline/nodes/output.rs b/app-server/src/pipeline/nodes/output.rs index dcdebb2b..afd2621b 100644 --- a/app-server/src/pipeline/nodes/output.rs +++ b/app-server/src/pipeline/nodes/output.rs @@ -1,6 +1,5 @@ use std::{collections::HashMap, sync::Arc}; -use crate::db::event_templates::EventType; use crate::engine::{RunOutput, RunnableNode}; use crate::pipeline::context::Context; use anyhow::{Ok, Result}; @@ -11,24 +10,6 @@ use uuid::Uuid; use super::utils::map_handles; use super::{Handle, NodeInput}; -pub fn cast(input: NodeInput, output_cast_type: &EventType) -> Result { - match output_cast_type { - EventType::BOOLEAN => match input { - NodeInput::Boolean(b) => Ok(NodeInput::Boolean(b)), - NodeInput::Float(f) => Ok(NodeInput::Boolean(f > 0.0)), - NodeInput::String(s) => Ok(NodeInput::Boolean(serde_json::from_str::(&s)?)), - _ => Err(anyhow::anyhow!("Cannot cast to boolean")), - }, - EventType::NUMBER => match input { - NodeInput::Boolean(b) => Ok(NodeInput::Float(if b { 1.0 } else { 0.0 })), - NodeInput::Float(f) => Ok(NodeInput::Float(f)), - NodeInput::String(s) => Ok(NodeInput::Float(serde_json::from_str::(&s)?)), - _ => Err(anyhow::anyhow!("Cannot cast to number")), - }, - EventType::STRING => Ok(NodeInput::String(input.into())), - } -} - #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "camelCase")] pub struct OutputNode { @@ -36,8 +17,6 @@ pub struct OutputNode { pub name: String, pub inputs: Vec, pub inputs_mappings: HashMap, - #[serde(default)] - pub output_cast_type: Option, } #[async_trait] @@ -70,13 +49,7 @@ impl RunnableNode for OutputNode { ) -> Result { let input = inputs.values().next().unwrap(); - let output = match &self.output_cast_type { - None => input.clone(), - Some(output_cast_type) => { - let res = cast(input.clone(), output_cast_type)?; - res - } - }; + let output = input.clone(); Ok(RunOutput::Success((output, None))) } diff --git a/app-server/src/routes/events.rs b/app-server/src/routes/events.rs deleted file mode 100644 index 6ba0a3f3..00000000 --- a/app-server/src/routes/events.rs +++ /dev/null @@ -1,237 +0,0 @@ -use actix_web::{delete, get, post, web, HttpResponse}; -use serde::Deserialize; -use uuid::Uuid; - -use crate::{ - ch::{self, utils::get_bounds, Aggregation, MetricTimeValue}, - db::{ - self, - events::EventWithTemplateName, - modifiers::{AbsoluteDateInterval, DateRange, Filter, RelativeDateInterval}, - DB, - }, - features::{is_feature_enabled, Feature}, - routes::{PaginatedGetQueryParams, PaginatedResponse, DEFAULT_PAGE_SIZE}, -}; - -use super::{GetMetricsQueryParams, ResponseResult}; - -#[get("event-templates")] -pub async fn get_event_templates(path: web::Path, db: web::Data) -> ResponseResult { - let project_id = path.into_inner(); - let event_templates = - db::event_templates::get_event_templates_by_project_id(&db.pool, project_id).await?; - - Ok(HttpResponse::Ok().json(event_templates)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct CreateEventTemplateRequest { - event_type: db::event_templates::EventType, -} - -#[get("event-templates/{template_id}")] -pub async fn get_event_template( - path: web::Path<(Uuid, Uuid)>, - db: web::Data, -) -> ResponseResult { - let (_project_id, template_id) = path.into_inner(); - let event_template = - db::event_templates::get_event_template_by_id(&db.pool, &template_id).await?; - - Ok(HttpResponse::Ok().json(event_template)) -} - -#[post("event-templates/{template_id}")] -pub async fn update_event_template( - path: web::Path<(Uuid, Uuid)>, - db: web::Data, - req: web::Json, -) -> ResponseResult { - let (project_id, template_id) = path.into_inner(); - let req = req.into_inner(); - - let event_template = db::event_templates::update_event_template( - &db.pool, - template_id, - project_id, - req.event_type, - ) - .await?; - - Ok(HttpResponse::Ok().json(event_template)) -} - -#[delete("event-templates/{template_id}")] -pub async fn delete_event_template( - path: web::Path<(Uuid, Uuid)>, - db: web::Data, -) -> ResponseResult { - let (_project_id, template_id) = path.into_inner(); - db::event_templates::delete_event_template(&db.pool, &template_id).await?; - - Ok(HttpResponse::Ok().finish()) -} - -#[get("event-templates/{template_id}/events")] -pub async fn get_events_by_template_id( - path: web::Path<(Uuid, Uuid)>, - db: web::Data, - query_params: web::Query, -) -> ResponseResult { - let (project_id, template_id) = path.into_inner(); - let query_params = query_params.into_inner(); - let date_range = query_params.date_range; - let limit = query_params.page_size.unwrap_or(DEFAULT_PAGE_SIZE); - let offset = limit * query_params.page_number; - let filters = Filter::from_url_params(query_params.filter); - - let events = db::events::get_events_by_template_id( - &db.pool, - &template_id, - &date_range, - &filters, - offset, - limit, - ) - .await?; - - let total_count = - db::events::count_events_by_template_id(&db.pool, &template_id, &date_range, &filters) - .await? as u64; - let any_in_project = if total_count > 0 { - true - } else { - db::events::count_all_events_by_template_id_in_project(&db.pool, &template_id, &project_id) - .await? - > 0 - }; - - let result = PaginatedResponse:: { - items: events, - total_count, - any_in_project, - }; - - Ok(HttpResponse::Ok().json(result)) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -enum EventMetric { - EventCount, -} - -impl std::fmt::Display for EventMetric { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - EventMetric::EventCount => write!(f, "eventCount"), - } - } -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct GetEventMetricsParams { - /// e.g. "eventCount", "valueAverage" or "valueSum" for NUMBER type, p90, some metrics grouped by enum tags, etc. - metric: EventMetric, - #[serde(flatten)] - base_params: GetMetricsQueryParams, -} - -#[get("event-templates/{event_template_id}/metrics")] -pub async fn get_events_metrics( - params: web::Path<(Uuid, Uuid)>, - clickhouse: web::Data, - req: web::Query, -) -> ResponseResult { - let (project_id, event_template_id) = params.into_inner(); - let clickhouse = clickhouse.into_inner().as_ref().clone(); - let req = req.into_inner(); - let metric = req.metric; - let aggregation = req.base_params.aggregation; - let date_range = req.base_params.date_range.as_ref(); - let group_by_interval = req.base_params.group_by_interval; - - let defaulted_range = - date_range - .cloned() - .unwrap_or(DateRange::Relative(RelativeDateInterval { - past_hours: "all".to_string(), - })); - - let range = if let DateRange::Relative(RelativeDateInterval { past_hours }) = &defaulted_range { - if past_hours == "all" { - let (start_date, end_date) = - get_bounds(&clickhouse, &project_id, "events", "timestamp").await?; - DateRange::Absolute(AbsoluteDateInterval { - start_date, - end_date, - }) - } else { - defaulted_range - } - } else { - defaulted_range - }; - if !is_feature_enabled(Feature::FullBuild) { - return Ok(HttpResponse::Ok().json(Vec::>::new())); - } - - match range { - DateRange::Relative(interval) => { - let past_hours = interval - .past_hours - .parse::() - .map_err(|e| anyhow::anyhow!("Failed to parse past_hours as i64: {}", e))?; - match metric { - EventMetric::EventCount => match aggregation { - Aggregation::Total => { - let values = ch::events::get_total_event_count_metrics_relative( - clickhouse, - group_by_interval, - project_id, - event_template_id, - past_hours, - ) - .await?; - Ok(HttpResponse::Ok().json(values)) - } - _ => { - return Err(anyhow::anyhow!( - "Unsupported aggregation {:?} for metric {}", - aggregation, - "eventCount" - ) - .into()); - } - }, - } - } - DateRange::Absolute(interval) => match metric { - EventMetric::EventCount => match aggregation { - Aggregation::Total => { - let values = ch::events::get_total_event_count_metrics_absolute( - clickhouse, - group_by_interval, - project_id, - event_template_id, - interval.start_date, - interval.end_date, - ) - .await?; - Ok(HttpResponse::Ok().json(values)) - } - _ => { - return Err(anyhow::anyhow!( - "Unsupported aggregation {:?} for metric {}", - aggregation, - metric - ) - .into()); - } - }, - }, - } -} diff --git a/app-server/src/routes/mod.rs b/app-server/src/routes/mod.rs index 02873922..45f039f6 100644 --- a/app-server/src/routes/mod.rs +++ b/app-server/src/routes/mod.rs @@ -3,7 +3,6 @@ pub mod auth; pub mod datasets; pub mod error; pub mod evaluations; -pub mod events; pub mod labels; pub mod limits; pub mod pipelines; diff --git a/app-server/src/routes/traces.rs b/app-server/src/routes/traces.rs index 230fffaa..cc6e673d 100644 --- a/app-server/src/routes/traces.rs +++ b/app-server/src/routes/traces.rs @@ -7,7 +7,7 @@ use crate::{ ch::{self, modifiers::GroupByInterval, Aggregation}, db::{ self, - events::EventWithTemplateName, + events::Event, modifiers::{DateRange, Filter, RelativeDateInterval}, spans::Span, trace::{Session, Trace, TraceWithTopSpan}, @@ -129,7 +129,7 @@ pub async fn get_single_trace( struct SpanWithEvents { #[serde(flatten)] span: Span, - events: Vec, + events: Vec, } #[get("spans/{span_id}")] diff --git a/app-server/src/traces/consumer.rs b/app-server/src/traces/consumer.rs index 04187606..b7b6c94b 100644 --- a/app-server/src/traces/consumer.rs +++ b/app-server/src/traces/consumer.rs @@ -19,6 +19,7 @@ use crate::{ storage::Storage, traces::{ evaluators::run_evaluator, + events::record_events, utils::{record_labels_to_db, record_span_to_db}, }, }; @@ -193,6 +194,12 @@ async fn inner_process_queue_spans( .map_err(|e| log::error!("Failed to ack RabbitMQ delivery: {:?}", e)); } + if let Err(e) = + record_events(db.clone(), clickhouse.clone(), rabbitmq_span_message.events).await + { + log::error!("Failed to record events: {:?}", e); + } + if let Err(e) = record_labels_to_db( db.clone(), clickhouse.clone(), diff --git a/app-server/src/traces/events.rs b/app-server/src/traces/events.rs index 5bded461..f373fb1a 100644 --- a/app-server/src/traces/events.rs +++ b/app-server/src/traces/events.rs @@ -1,152 +1,21 @@ use std::sync::Arc; use anyhow::Result; -use serde_json::Value; -use uuid::Uuid; use crate::{ ch::{self, events::CHEvent}, - db::{ - self, - event_templates::{EventTemplate, EventType}, - events::{EventObservation, EventSource}, - DB, - }, + db::{self, events::Event, DB}, }; -// TODO: Make this function more readable and separate into smaller functions -pub async fn create_events( +pub async fn record_events( db: Arc, clickhouse: clickhouse::Client, - event_payloads: Vec, - event_source: EventSource, - project_id: Uuid, + event_payloads: Vec, ) -> Result<()> { - let template_names = event_payloads + db::events::insert_events(&db.pool, &event_payloads).await?; + let ch_events = event_payloads .iter() - .map(|o| o.template_name.clone()) - .collect::>(); - let event_templates_map = - db::event_templates::get_event_templates_map(&db.pool, &template_names, project_id).await?; - - let mut events = vec![]; - let mut event_templates = vec![]; - - for mut event_payload in event_payloads.into_iter() { - let event_template: EventTemplate = - match event_templates_map.get(&event_payload.template_name) { - Some(et) => et.clone(), - None => { - let event_type = match event_payload.value { - None => EventType::BOOLEAN, - Some(ref value) => match value { - Value::Number(_) => EventType::NUMBER, - Value::String(_) => EventType::STRING, - Value::Bool(_) => EventType::BOOLEAN, - _ => { - log::warn!( - "Skipping event with unsupported value type: {:?}", - event_payload - ); - continue; - } - }, - }; - // If the user wants to use events for simply logging, create a boolean event, if there's no template for such event - let event_template_create_res = - db::event_templates::create_event_template_idempotent( - &db.pool, - &event_payload.template_name, - project_id, - event_type, - ) - .await; - match event_template_create_res { - Ok(et) => et, - Err(e) => { - log::warn!( - "Skipping event due to error when creating event template: {:?}", - e - ); - continue; - } - } - } - }; - - match event_template.event_type { - EventType::BOOLEAN => { - let value = match event_payload.value.clone() { - Some(v) => v, - None => Value::Bool(true), // IMPORTANT: Default to true for boolean events - }; - event_payload.value = Some(value.clone()); - let _bool_value = match serde_json::from_value::(value) { - Ok(v) => v, - Err(_) => { - log::warn!( - "Skipping BOOLEAN event with non-boolean value: {:?}", - event_payload - ); - continue; - } - }; - events.push(event_payload); - event_templates.push(event_template); - } - EventType::STRING => { - let Some(value) = event_payload.value.clone() else { - log::warn!("Skipping STRING event without value: {:?}", event_payload); - continue; - }; - if serde_json::from_value::(value).is_err() { - log::warn!( - "Skipping STRING event with non-string value: {:?}", - event_payload - ); - continue; - }; - events.push(event_payload); - event_templates.push(event_template); - } - EventType::NUMBER => { - let Some(value) = event_payload.value.clone() else { - log::warn!("Skipping NUMBER event without value: {:?}", event_payload); - continue; - }; - if serde_json::from_value::(value).is_err() { - log::warn!( - "Skipping NUMBER event with non-numeric value: {:?}", - event_payload - ); - continue; - }; - events.push(event_payload); - event_templates.push(event_template); - } - } - } - - let template_ids = event_templates - .iter() - .map(|et| et.id) - .collect::>(); - db::events::create_events_by_template_name(db, events.clone(), &template_ids, &event_source) - .await?; - - let ch_events = events - .into_iter() - .zip(event_templates.into_iter()) - .map(|(event, event_template)| { - CHEvent::from_data( - event.id, - event.timestamp, - event_template, - event_source.clone().into(), - project_id, - ) - }) + .map(|e| CHEvent::from_db_event(e)) .collect::>(); - ch::events::insert_events(clickhouse, ch_events).await } diff --git a/app-server/src/traces/producer.rs b/app-server/src/traces/producer.rs index 00cd3696..0f5d5b55 100644 --- a/app-server/src/traces/producer.rs +++ b/app-server/src/traces/producer.rs @@ -10,17 +10,14 @@ use uuid::Uuid; use crate::{ api::v1::traces::RabbitMqSpanMessage, cache::Cache, - db::{events::EventObservation, spans::Span, utils::convert_any_value_to_json_value, DB}, + db::{events::Event, spans::Span, DB}, features::{is_feature_enabled, Feature}, opentelemetry::opentelemetry::proto::collector::trace::v1::{ ExportTraceServiceRequest, ExportTraceServiceResponse, }, }; -use super::{ - span_attributes::EVENT_TYPE, utils::record_span_to_db, OBSERVATIONS_EXCHANGE, - OBSERVATIONS_ROUTING_KEY, -}; +use super::{utils::record_span_to_db, OBSERVATIONS_EXCHANGE, OBSERVATIONS_ROUTING_KEY}; // TODO: Implement partial_success pub async fn push_spans_to_queue( @@ -72,31 +69,20 @@ pub async fn push_spans_to_queue( for otel_span in scope_span.spans { let span = Span::from_otel_span(otel_span.clone()); - let mut events = vec![]; - - for event in otel_span.events { - let event_attributes = event - .attributes - .clone() - .into_iter() - .map(|kv| (kv.key, convert_any_value_to_json_value(kv.value))) - .collect::>(); - - let Some(serde_json::Value::String(event_type)) = - event_attributes.get(EVENT_TYPE) - else { - if event.name != "llm.content.completion.chunk" { - log::warn!("Unknown event type: {:?}", event); + let events = otel_span + .events + .into_iter() + .filter_map(|event| { + // OpenLLMetry auto-instrumentation sends this event for every chunk + // While this is helpful to get TTFT, we don't want to store excessive + // events + if event.name == "llm.content.completion.chunk" { + None + } else { + Some(Event::from_otel(event, span.span_id, project_id)) } - continue; - }; - - if event_type == "default" { - events.push(EventObservation::from_otel(event, span.span_id)); - } else { - log::warn!("Unknown event type: {}", event_type); - } - } + }) + .collect::>(); if !span.should_save() { continue; diff --git a/app-server/src/traces/span_attributes.rs b/app-server/src/traces/span_attributes.rs index d8c913be..2b9bf113 100644 --- a/app-server/src/traces/span_attributes.rs +++ b/app-server/src/traces/span_attributes.rs @@ -28,6 +28,4 @@ pub const GEN_AI_OUTPUT_COST: &str = "gen_ai.usage.output_cost"; pub const ASSOCIATION_PROPERTIES_PREFIX: &str = "lmnr.association.properties."; pub const SPAN_TYPE: &str = "lmnr.span.type"; pub const SPAN_PATH: &str = "lmnr.span.path"; -pub const EVENT_TYPE: &str = "lmnr.event.type"; -pub const EVENT_VALUE: &str = "lmnr.event.value"; pub const LLM_NODE_RENDERED_PROMPT: &str = "lmnr.span.prompt"; diff --git a/clickhouse/001000-initial.sql b/clickhouse/001000-initial.sql index 6781a1e1..00cae55c 100644 --- a/clickhouse/001000-initial.sql +++ b/clickhouse/001000-initial.sql @@ -23,18 +23,17 @@ ENGINE = MergeTree() ORDER BY (project_id, start_time, trace_id, span_id) SETTINGS index_granularity = 8192; -CREATE TABLE events ( - id UUID, - timestamp DateTime64(9, 'UTC'), - source Enum8('CODE' = 0, 'AUTO', 'MANUAL'), - template_id UUID, - template_name String, - event_type Enum8('BOOLEAN' = 0, 'NUMBER', 'STRING'), - project_id UUID -) -ENGINE MergeTree() -ORDER BY (project_id, template_id, id) -SETTINGS index_granularity = 8192 SETTINGS flatten_nested=0; +CREATE TABLE events +( + `id` UUID, + `project_id` UUID, + `span_id` UUID, + `timestamp` DateTime64(9, 'UTC'), + `name` String +) +ENGINE MergeTree +ORDER BY (project_id, name, timestamp, span_id) +SETTINGS index_granularity = 8192; CREATE TABLE evaluation_scores ( project_id UUID, diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json index aeb35b5b..991f0dfb 100644 --- a/frontend/.eslintrc.json +++ b/frontend/.eslintrc.json @@ -38,15 +38,15 @@ "unused-imports/no-unused-imports": [ "error" ], - "sort-imports": [ - "warn", - { - "ignoreCase": true, - "allowSeparatedGroups": false - } - ] + "simple-import-sort/imports": "error", + "simple-import-sort/exports": "error" + }, + "parserOptions": { + "sourceType": "module", + "ecmaVersion": "latest" }, "plugins": [ - "unused-imports" + "unused-imports", + "simple-import-sort" ] } \ No newline at end of file diff --git a/frontend/app/api/auth/[...nextauth]/route.ts b/frontend/app/api/auth/[...nextauth]/route.ts index 38464031..5965d8f4 100644 --- a/frontend/app/api/auth/[...nextauth]/route.ts +++ b/frontend/app/api/auth/[...nextauth]/route.ts @@ -1,5 +1,6 @@ -import { authOptions } from '@/lib/auth'; import NextAuth from 'next-auth'; +import { authOptions } from '@/lib/auth'; + const handler = NextAuth(authOptions); export { handler as GET, handler as POST }; diff --git a/frontend/app/api/limits/workspace/[workspaceId]/route.ts b/frontend/app/api/limits/workspace/[workspaceId]/route.ts index d989a209..62520a36 100644 --- a/frontend/app/api/limits/workspace/[workspaceId]/route.ts +++ b/frontend/app/api/limits/workspace/[workspaceId]/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/limits/workspace/[workspaceId]/storage/route.ts b/frontend/app/api/limits/workspace/[workspaceId]/storage/route.ts index 785d7db2..daad3f24 100644 --- a/frontend/app/api/limits/workspace/[workspaceId]/storage/route.ts +++ b/frontend/app/api/limits/workspace/[workspaceId]/storage/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/api-keys/route.ts b/frontend/app/api/projects/[projectId]/api-keys/route.ts index e46fd73a..020e659b 100644 --- a/frontend/app/api/projects/[projectId]/api-keys/route.ts +++ b/frontend/app/api/projects/[projectId]/api-keys/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; -import { getServerSession } from 'next-auth'; import { type NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + +import { authOptions } from '@/lib/auth'; export async function POST( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/[datapointId]/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/[datapointId]/route.ts index 90d4c2e1..b16f3ded 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/[datapointId]/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/[datapointId]/route.ts @@ -1,11 +1,11 @@ import { and, eq } from 'drizzle-orm'; +import { getServerSession } from 'next-auth'; +import { z } from 'zod'; import { authOptions } from '@/lib/auth'; -import { datasetDatapoints } from '@/lib/db/migrations/schema'; import { db } from '@/lib/db/drizzle'; +import { datasetDatapoints } from '@/lib/db/migrations/schema'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { z } from 'zod'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/all/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/all/route.ts index 6bd16d8d..65d7e403 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/all/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/all/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function DELETE( req: Request, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/route.ts index 1530348e..bfe43203 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/datapoints/route.ts @@ -1,12 +1,12 @@ import { and, eq, inArray } from 'drizzle-orm'; -import { datapointToSpan, datasetDatapoints, datasets } from '@/lib/db/migrations/schema'; +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; +import { z } from 'zod'; import { authOptions } from '@/lib/auth'; import { db } from '@/lib/db/drizzle'; +import { datapointToSpan, datasetDatapoints, datasets } from '@/lib/db/migrations/schema'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; -import { z } from 'zod'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/download/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/download/route.ts index fc7d15a0..2dcd5fea 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/download/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/download/route.ts @@ -1,7 +1,7 @@ import { and, asc, eq } from 'drizzle-orm'; -import { datasetDatapoints, datasets } from '@/lib/db/migrations/schema'; import { db } from '@/lib/db/drizzle'; +import { datasetDatapoints, datasets } from '@/lib/db/migrations/schema'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/file-upload/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/file-upload/route.ts index d282192c..2b2dd365 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/file-upload/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/file-upload/route.ts @@ -1,7 +1,8 @@ +import { type NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { type NextRequest } from 'next/server'; export async function POST( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/index/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/index/route.ts index 74ffa797..ef66e0c5 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/index/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/index/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/route.ts b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/route.ts index 7dc4e5cb..f777e648 100644 --- a/frontend/app/api/projects/[projectId]/datasets/[datasetId]/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/[datasetId]/route.ts @@ -1,9 +1,10 @@ import { and, eq } from 'drizzle-orm'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; -import { datasets } from '@/lib/db/migrations/schema'; import { db } from '@/lib/db/drizzle'; +import { datasets } from '@/lib/db/migrations/schema'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/datasets/route.ts b/frontend/app/api/projects/[projectId]/datasets/route.ts index 3a639ba1..72502ffb 100644 --- a/frontend/app/api/projects/[projectId]/datasets/route.ts +++ b/frontend/app/api/projects/[projectId]/datasets/route.ts @@ -1,8 +1,8 @@ import { and, desc, eq, inArray } from 'drizzle-orm'; +import { NextRequest } from 'next/server'; -import { datasets } from '@/lib/db/migrations/schema'; import { db } from '@/lib/db/drizzle'; -import { NextRequest } from 'next/server'; +import { datasets } from '@/lib/db/migrations/schema'; import { paginatedGet } from '@/lib/db/utils'; export async function POST( diff --git a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/checks/route.ts b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/checks/route.ts index 161f1295..549e1793 100644 --- a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/checks/route.ts +++ b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/checks/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function PUT( req: Request, diff --git a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/log-datasets/route.ts b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/log-datasets/route.ts index 0e88ecb9..048868bc 100644 --- a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/log-datasets/route.ts +++ b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/log-datasets/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function PUT( req: Request, diff --git a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-version-graphs/route.ts b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-version-graphs/route.ts index 96759099..b3ced9f8 100644 --- a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-version-graphs/route.ts +++ b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-version-graphs/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-versions/route.ts b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-versions/route.ts index c1a9a1dd..c28b6418 100644 --- a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-versions/route.ts +++ b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/pipeline-versions/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/route.ts b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/route.ts index 4e13f9b1..cce3fc93 100644 --- a/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/route.ts +++ b/frontend/app/api/projects/[projectId]/endpoints/[endpointId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/endpoints/route.ts b/frontend/app/api/projects/[projectId]/endpoints/route.ts index 18eebe9e..4ade4c67 100644 --- a/frontend/app/api/projects/[projectId]/endpoints/route.ts +++ b/frontend/app/api/projects/[projectId]/endpoints/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/evaluation-groups/[groupId]/progression/route.ts b/frontend/app/api/projects/[projectId]/evaluation-groups/[groupId]/progression/route.ts index 8611db85..bce3e476 100644 --- a/frontend/app/api/projects/[projectId]/evaluation-groups/[groupId]/progression/route.ts +++ b/frontend/app/api/projects/[projectId]/evaluation-groups/[groupId]/progression/route.ts @@ -1,8 +1,8 @@ -import { AggregationFunction, TimeRange } from "@/lib/clickhouse/utils"; import { NextRequest, NextResponse } from "next/server"; import { clickhouseClient } from "@/lib/clickhouse/client"; import { getEvaluationTimeProgression } from "@/lib/clickhouse/evaluation-scores"; +import { AggregationFunction, TimeRange } from "@/lib/clickhouse/utils"; export const GET = async (request: NextRequest, { params }: { params: { projectId: string, groupId: string } }) => { diff --git a/frontend/app/api/projects/[projectId]/evaluation-score-distribution/route.ts b/frontend/app/api/projects/[projectId]/evaluation-score-distribution/route.ts index 5add87b8..bd152e59 100644 --- a/frontend/app/api/projects/[projectId]/evaluation-score-distribution/route.ts +++ b/frontend/app/api/projects/[projectId]/evaluation-score-distribution/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/evaluation-score-stats/route.ts b/frontend/app/api/projects/[projectId]/evaluation-score-stats/route.ts index a5217b48..dab55450 100644 --- a/frontend/app/api/projects/[projectId]/evaluation-score-stats/route.ts +++ b/frontend/app/api/projects/[projectId]/evaluation-score-stats/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/download/route.ts b/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/download/route.ts index de3de5b5..74d5b96b 100644 --- a/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/download/route.ts +++ b/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/download/route.ts @@ -1,8 +1,8 @@ import { and, asc, eq, sql } from 'drizzle-orm'; -import { evaluationResults, evaluations, evaluationScores } from '@/lib/db/migrations/schema'; +import { json2csv } from 'json-2-csv'; import { db } from '@/lib/db/drizzle'; -import { json2csv } from 'json-2-csv'; +import { evaluationResults, evaluations, evaluationScores } from '@/lib/db/migrations/schema'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/route.ts b/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/route.ts index a296c4e7..8fc73385 100644 --- a/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/route.ts +++ b/frontend/app/api/projects/[projectId]/evaluations/[evaluationId]/route.ts @@ -1,11 +1,11 @@ import { and, asc, eq, sql } from 'drizzle-orm'; + +import { db } from '@/lib/db/drizzle'; import { evaluationResults, evaluations,evaluationScores } from '@/lib/db/migrations/schema'; -import { db } from '@/lib/db/drizzle'; - export async function GET( req: Request, { params }: { params: { projectId: string; evaluationId: string } } diff --git a/frontend/app/api/projects/[projectId]/evaluations/route.ts b/frontend/app/api/projects/[projectId]/evaluations/route.ts index 266605ea..571c4af4 100644 --- a/frontend/app/api/projects/[projectId]/evaluations/route.ts +++ b/frontend/app/api/projects/[projectId]/evaluations/route.ts @@ -1,10 +1,10 @@ import { and,desc,eq,inArray,SQL } from 'drizzle-orm'; +import { NextRequest } from 'next/server'; import { db } from '@/lib/db/drizzle'; -import { Evaluation } from '@/lib/evaluation/types'; import { evaluations } from '@/lib/db/migrations/schema'; -import { NextRequest } from 'next/server'; import { paginatedGet } from '@/lib/db/utils'; +import { Evaluation } from '@/lib/evaluation/types'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/event-templates/[templateId]/events/route.ts b/frontend/app/api/projects/[projectId]/event-templates/[templateId]/events/route.ts deleted file mode 100644 index 34ba8959..00000000 --- a/frontend/app/api/projects/[projectId]/event-templates/[templateId]/events/route.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; - -export async function GET( - req: NextRequest, - { params }: { params: { projectId: string; templateId: string } } -): Promise { - const projectId = params.projectId; - const templateId = params.templateId; - - const session = await getServerSession(authOptions); - const user = session!.user; - - const res = await fetcher( - `/projects/${projectId}/event-templates/${templateId}/events?${req.nextUrl.searchParams.toString()}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${user.apiKey}` - } - } - ); - - return res; -} diff --git a/frontend/app/api/projects/[projectId]/event-templates/[templateId]/metrics/route.ts b/frontend/app/api/projects/[projectId]/event-templates/[templateId]/metrics/route.ts deleted file mode 100644 index 728d736b..00000000 --- a/frontend/app/api/projects/[projectId]/event-templates/[templateId]/metrics/route.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; - -export async function GET( - req: NextRequest, - { params }: { params: { projectId: string; templateId: string } } -): Promise { - const projectId = params.projectId; - const templateId = params.templateId; - - const session = await getServerSession(authOptions); - const user = session!.user; - - const res = await fetcher( - `/projects/${projectId}/event-templates/${templateId}/metrics?${req.nextUrl.searchParams.toString()}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${user.apiKey}` - } - } - ); - - return res; -} diff --git a/frontend/app/api/projects/[projectId]/event-templates/route.ts b/frontend/app/api/projects/[projectId]/event-templates/route.ts deleted file mode 100644 index 914912da..00000000 --- a/frontend/app/api/projects/[projectId]/event-templates/route.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; - -export async function POST( - req: Request, - { params }: { params: { projectId: string } } -): Promise { - const projectId = params.projectId; - - const session = await getServerSession(authOptions); - const user = session!.user; - - const body = await req.json(); - - const res = await fetcher(`/projects/${projectId}/event-templates`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${user.apiKey}` - }, - body: JSON.stringify(body) - }); - - return res; -} - -export async function GET( - req: Request, - { params }: { params: { projectId: string } } -): Promise { - const projectId = params.projectId; - - const session = await getServerSession(authOptions); - const user = session!.user; - - const res = await fetcher(`/projects/${projectId}/event-templates`, { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${user.apiKey}` - } - }); - - return res; -} diff --git a/frontend/app/api/projects/[projectId]/events/metrics/route.ts b/frontend/app/api/projects/[projectId]/events/metrics/route.ts deleted file mode 100644 index cb3cf953..00000000 --- a/frontend/app/api/projects/[projectId]/events/metrics/route.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; - -export async function GET( - req: NextRequest, - { params }: { params: { projectId: string } } -): Promise { - const projectId = params.projectId; - - const session = await getServerSession(authOptions); - const user = session!.user; - - return fetcher( - `/projects/${projectId}/events/metrics?` + - req.nextUrl.searchParams.toString(), - { - method: 'GET', - headers: { - Authorization: `Bearer ${user.apiKey}` - } - } - ); -} diff --git a/frontend/app/api/projects/[projectId]/events/route.ts b/frontend/app/api/projects/[projectId]/events/route.ts deleted file mode 100644 index 710ba1ea..00000000 --- a/frontend/app/api/projects/[projectId]/events/route.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; - -export async function GET( - req: NextRequest, - { params }: { params: { projectId: string } } -): Promise { - const projectId = params.projectId; - const session = await getServerSession(authOptions); - const user = session!.user; - - const res = await fetcher( - `/projects/${projectId}/events?${req.nextUrl.searchParams.toString()}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${user.apiKey}` - } - } - ); - - return new Response(res.body); -} diff --git a/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/[id]/route.ts b/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/[id]/route.ts index dc16d55c..4df4c3d6 100644 --- a/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/[id]/route.ts +++ b/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/[id]/route.ts @@ -1,5 +1,6 @@ -import { db } from '@/lib/db/drizzle'; import { eq } from 'drizzle-orm'; + +import { db } from '@/lib/db/drizzle'; import { labelClassesForPath } from '@/lib/db/migrations/schema'; export async function DELETE( diff --git a/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/route.ts b/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/route.ts index 94c23bcf..6675affd 100644 --- a/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/route.ts +++ b/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/registered-paths/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/route.ts b/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/route.ts index 94e742ce..41bb04d0 100644 --- a/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/route.ts +++ b/frontend/app/api/projects/[projectId]/label-classes/[labelClassId]/route.ts @@ -1,10 +1,10 @@ import { and, eq } from 'drizzle-orm'; +import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { db } from '@/lib/db/drizzle'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; import { labelClasses } from '@/lib/db/migrations/schema'; +import { fetcher } from '@/lib/utils'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/label-classes/registered-paths/route.ts b/frontend/app/api/projects/[projectId]/label-classes/registered-paths/route.ts index fb63cf1d..f4b07802 100644 --- a/frontend/app/api/projects/[projectId]/label-classes/registered-paths/route.ts +++ b/frontend/app/api/projects/[projectId]/label-classes/registered-paths/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipeline-versions/[pipelineVersionId]/route.ts b/frontend/app/api/projects/[projectId]/pipeline-versions/[pipelineVersionId]/route.ts index 9575d74d..697ff795 100644 --- a/frontend/app/api/projects/[projectId]/pipeline-versions/[pipelineVersionId]/route.ts +++ b/frontend/app/api/projects/[projectId]/pipeline-versions/[pipelineVersionId]/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth'; + export async function GET( req: Request, { params }: { params: { projectId: string; pipelineVersionId: string } } diff --git a/frontend/app/api/projects/[projectId]/pipeline-versions/route.ts b/frontend/app/api/projects/[projectId]/pipeline-versions/route.ts index 247696ca..98df2991 100644 --- a/frontend/app/api/projects/[projectId]/pipeline-versions/route.ts +++ b/frontend/app/api/projects/[projectId]/pipeline-versions/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/route.ts index 08f2aaff..099d6150 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function DELETE( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/target/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/target/route.ts index 75821f8c..1cd9d472 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/target/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/target/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions-info/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions-info/route.ts index 29f5409b..8df78445 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions-info/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions-info/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/overwrite/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/overwrite/route.ts index 9977d31b..ebd70b20 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/overwrite/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/overwrite/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/route.ts index ad3f2e03..b2931cd3 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/[pipelineVersionId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function POST( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/deploy/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/deploy/route.ts index a0473600..65ff0654 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/deploy/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/deploy/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth'; + export async function POST( req: Request, { params }: { params: { projectId: string; pipelineId: string } } diff --git a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/route.ts b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/route.ts index ad3aaf85..5839c8c4 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/[pipelineId]/versions/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/interrupt/graph/route.ts b/frontend/app/api/projects/[projectId]/pipelines/interrupt/graph/route.ts index a2207aec..8bf98105 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/interrupt/graph/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/interrupt/graph/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth'; + export async function POST( req: Request, { params }: { params: { projectId: string } } diff --git a/frontend/app/api/projects/[projectId]/pipelines/route.ts b/frontend/app/api/projects/[projectId]/pipelines/route.ts index cc57b7e6..47b0d65e 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/pipelines/run/graph/route.ts b/frontend/app/api/projects/[projectId]/pipelines/run/graph/route.ts index a5c32321..96ae8e40 100644 --- a/frontend/app/api/projects/[projectId]/pipelines/run/graph/route.ts +++ b/frontend/app/api/projects/[projectId]/pipelines/run/graph/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth'; + export async function POST( req: Request, { params }: { params: { projectId: string } } diff --git a/frontend/app/api/projects/[projectId]/playgrounds/[playgroundId]/route.ts b/frontend/app/api/projects/[projectId]/playgrounds/[playgroundId]/route.ts index fcbb8c92..1c30291f 100644 --- a/frontend/app/api/projects/[projectId]/playgrounds/[playgroundId]/route.ts +++ b/frontend/app/api/projects/[projectId]/playgrounds/[playgroundId]/route.ts @@ -1,8 +1,9 @@ -import { db } from "@/lib/db/drizzle"; import { eq } from "drizzle-orm"; -import { playgrounds } from "@/lib/db/migrations/schema"; import { z } from "zod"; +import { db } from "@/lib/db/drizzle"; +import { playgrounds } from "@/lib/db/migrations/schema"; + const updatePlaygroundSchema = z.object({ promptMessages: z.array(z.any()), modelId: z.string(), diff --git a/frontend/app/api/projects/[projectId]/playgrounds/route.ts b/frontend/app/api/projects/[projectId]/playgrounds/route.ts index 51135e9d..de057cae 100644 --- a/frontend/app/api/projects/[projectId]/playgrounds/route.ts +++ b/frontend/app/api/projects/[projectId]/playgrounds/route.ts @@ -1,5 +1,6 @@ -import { db } from '@/lib/db/drizzle'; import { eq } from 'drizzle-orm'; + +import { db } from '@/lib/db/drizzle'; import { playgrounds } from '@/lib/db/migrations/schema'; export async function GET(req: Request, { params }: { params: { projectId: string } }) { diff --git a/frontend/app/api/projects/[projectId]/prompt-copilot/run/route.ts b/frontend/app/api/projects/[projectId]/prompt-copilot/run/route.ts index a04f7071..a411c5d2 100644 --- a/frontend/app/api/projects/[projectId]/prompt-copilot/run/route.ts +++ b/frontend/app/api/projects/[projectId]/prompt-copilot/run/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; -import { getServerSession } from 'next-auth'; import { type NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + +import { authOptions } from '@/lib/auth'; export async function POST( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/provider-api-keys/route.ts b/frontend/app/api/projects/[projectId]/provider-api-keys/route.ts index 28655631..a1f9eb42 100644 --- a/frontend/app/api/projects/[projectId]/provider-api-keys/route.ts +++ b/frontend/app/api/projects/[projectId]/provider-api-keys/route.ts @@ -1,11 +1,11 @@ import { and, eq } from 'drizzle-orm'; +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { db } from '@/lib/db/drizzle'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; import { providerApiKeys } from '@/lib/db/migrations/schema'; +import { fetcher } from '@/lib/utils'; export async function GET(req: NextRequest, { params }: { params: { projectId: string } }): Promise { const projectId = params.projectId; diff --git a/frontend/app/api/projects/[projectId]/queues/[queueId]/move/route.ts b/frontend/app/api/projects/[projectId]/queues/[queueId]/move/route.ts index 68523da1..e3d1a6ef 100644 --- a/frontend/app/api/projects/[projectId]/queues/[queueId]/move/route.ts +++ b/frontend/app/api/projects/[projectId]/queues/[queueId]/move/route.ts @@ -1,8 +1,8 @@ import { and, asc, desc, eq, gt, lt, sql } from 'drizzle-orm'; -import { labelingQueueItems, spans } from '@/lib/db/migrations/schema'; +import { z } from 'zod'; import { db } from '@/lib/db/drizzle'; -import { z } from 'zod'; +import { labelingQueueItems, spans } from '@/lib/db/migrations/schema'; // Add request body validation schema const RequestBodySchema = z.object({ diff --git a/frontend/app/api/projects/[projectId]/queues/[queueId]/push/route.ts b/frontend/app/api/projects/[projectId]/queues/[queueId]/push/route.ts index d0ce9882..7f3d6258 100644 --- a/frontend/app/api/projects/[projectId]/queues/[queueId]/push/route.ts +++ b/frontend/app/api/projects/[projectId]/queues/[queueId]/push/route.ts @@ -1,6 +1,7 @@ +import { z } from 'zod'; + import { db } from '@/lib/db/drizzle'; import { labelingQueueItems } from '@/lib/db/migrations/schema'; -import { z } from 'zod'; const pushQueueItemSchema = z.object({ spanId: z.string(), diff --git a/frontend/app/api/projects/[projectId]/queues/[queueId]/remove/route.ts b/frontend/app/api/projects/[projectId]/queues/[queueId]/remove/route.ts index 129c372d..87ae4726 100644 --- a/frontend/app/api/projects/[projectId]/queues/[queueId]/remove/route.ts +++ b/frontend/app/api/projects/[projectId]/queues/[queueId]/remove/route.ts @@ -1,5 +1,12 @@ import { and, eq, sql } from 'drizzle-orm'; +import { getServerSession } from 'next-auth'; +import { z } from 'zod'; + +import { authOptions } from '@/lib/auth'; +import { clickhouseClient } from '@/lib/clickhouse/client'; +import { dateToNanoseconds } from '@/lib/clickhouse/utils'; +import { db } from '@/lib/db/drizzle'; import { datapointToSpan, datasetDatapoints, @@ -12,13 +19,6 @@ import { } from '@/lib/db/migrations/schema'; import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { authOptions } from '@/lib/auth'; -import { clickhouseClient } from '@/lib/clickhouse/client'; -import { dateToNanoseconds } from '@/lib/clickhouse/utils'; -import { db } from '@/lib/db/drizzle'; -import { getServerSession } from 'next-auth'; -import { z } from 'zod'; - const removeQueueItemSchema = z.object({ id: z.string(), diff --git a/frontend/app/api/projects/[projectId]/queues/route.ts b/frontend/app/api/projects/[projectId]/queues/route.ts index 31db7bd0..3324a92a 100644 --- a/frontend/app/api/projects/[projectId]/queues/route.ts +++ b/frontend/app/api/projects/[projectId]/queues/route.ts @@ -1,8 +1,8 @@ import { and, desc, eq, inArray } from 'drizzle-orm'; +import { NextRequest } from 'next/server'; import { db } from '@/lib/db/drizzle'; import { labelingQueues } from '@/lib/db/migrations/schema'; -import { NextRequest } from 'next/server'; import { paginatedGet } from '@/lib/db/utils'; export async function POST( diff --git a/frontend/app/api/projects/[projectId]/route.ts b/frontend/app/api/projects/[projectId]/route.ts index 6372cde2..a436eb6e 100644 --- a/frontend/app/api/projects/[projectId]/route.ts +++ b/frontend/app/api/projects/[projectId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function DELETE( req: Request, diff --git a/frontend/app/api/projects/[projectId]/sessions/route.ts b/frontend/app/api/projects/[projectId]/sessions/route.ts index 0c3a240c..c70d31e5 100644 --- a/frontend/app/api/projects/[projectId]/sessions/route.ts +++ b/frontend/app/api/projects/[projectId]/sessions/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/spans/[spanId]/datapoints/route.ts b/frontend/app/api/projects/[projectId]/spans/[spanId]/datapoints/route.ts index 9e82fd5c..4cef0e4b 100644 --- a/frontend/app/api/projects/[projectId]/spans/[spanId]/datapoints/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/[spanId]/datapoints/route.ts @@ -1,7 +1,8 @@ -import { datapointToSpan } from "@/lib/db/migrations/schema"; -import { db } from "@/lib/db/drizzle"; import { eq } from "drizzle-orm"; +import { db } from "@/lib/db/drizzle"; +import { datapointToSpan } from "@/lib/db/migrations/schema"; + export async function GET( request: Request, { params }: { params: { projectId: string; spanId: string } } diff --git a/frontend/app/api/projects/[projectId]/spans/[spanId]/export/route.ts b/frontend/app/api/projects/[projectId]/spans/[spanId]/export/route.ts index ad119e28..caeb4811 100644 --- a/frontend/app/api/projects/[projectId]/spans/[spanId]/export/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/[spanId]/export/route.ts @@ -1,6 +1,7 @@ -import { authOptions } from '@/lib/auth'; import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth'; + export async function POST( req: Request, { params }: { params: { projectId: string; spanId: string } } diff --git a/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/[labelId]/route.ts b/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/[labelId]/route.ts index bf0d4e78..f19a8b5a 100644 --- a/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/[labelId]/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/[labelId]/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function DELETE( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/route.ts b/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/route.ts index 4ab3588d..fc7920db 100644 --- a/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/[spanId]/labels/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/spans/[spanId]/route.ts b/frontend/app/api/projects/[projectId]/spans/[spanId]/route.ts index 1e6c78a9..d3d37582 100644 --- a/frontend/app/api/projects/[projectId]/spans/[spanId]/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/[spanId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/spans/metrics/summary/route.ts b/frontend/app/api/projects/[projectId]/spans/metrics/summary/route.ts index f5912dcb..8b73ea9e 100644 --- a/frontend/app/api/projects/[projectId]/spans/metrics/summary/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/metrics/summary/route.ts @@ -1,7 +1,8 @@ +import { NextRequest, NextResponse } from "next/server"; + import { clickhouseClient } from "@/lib/clickhouse/client"; import { getSpanMetricsSummary, SpanMetric, SpanMetricGroupBy } from "@/lib/clickhouse/spans"; import { AggregationFunction, getTimeRange } from "@/lib/clickhouse/utils"; -import { NextRequest, NextResponse } from "next/server"; export async function GET(req: NextRequest, { params }: { params: { projectId: string } }) { const { projectId } = params; diff --git a/frontend/app/api/projects/[projectId]/spans/metrics/time/route.ts b/frontend/app/api/projects/[projectId]/spans/metrics/time/route.ts index c256032c..3a0691f0 100644 --- a/frontend/app/api/projects/[projectId]/spans/metrics/time/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/metrics/time/route.ts @@ -1,8 +1,9 @@ +import { NextRequest, NextResponse } from "next/server"; + import { clickhouseClient } from "@/lib/clickhouse/client"; import { GroupByInterval } from "@/lib/clickhouse/modifiers"; import { getSpanMetricsOverTime, SpanMetric, SpanMetricGroupBy } from "@/lib/clickhouse/spans"; import { AggregationFunction, getTimeRange } from "@/lib/clickhouse/utils"; -import { NextRequest, NextResponse } from "next/server"; export async function GET(req: NextRequest, { params }: { params: { projectId: string } }) { const { projectId } = params; diff --git a/frontend/app/api/projects/[projectId]/spans/route.ts b/frontend/app/api/projects/[projectId]/spans/route.ts index c03cc67e..86817dbc 100644 --- a/frontend/app/api/projects/[projectId]/spans/route.ts +++ b/frontend/app/api/projects/[projectId]/spans/route.ts @@ -1,10 +1,10 @@ import { and, desc, eq, getTableColumns, inArray, or, sql } from 'drizzle-orm'; -import { FilterDef, filtersToSql } from '@/lib/db/modifiers'; -import { getDateRangeFilters, paginatedGet } from '@/lib/db/utils'; -import { labelClasses, labels, spans, traces } from '@/lib/db/migrations/schema'; +import { NextRequest } from 'next/server'; import { db } from '@/lib/db/drizzle'; -import { NextRequest } from 'next/server'; +import { labelClasses, labels, spans, traces } from '@/lib/db/migrations/schema'; +import { FilterDef, filtersToSql } from '@/lib/db/modifiers'; +import { getDateRangeFilters, paginatedGet } from '@/lib/db/utils'; import { Span } from '@/lib/traces/types'; export async function GET( diff --git a/frontend/app/api/projects/[projectId]/templates/route.ts b/frontend/app/api/projects/[projectId]/templates/route.ts index ff6d4791..0d0e5928 100644 --- a/frontend/app/api/projects/[projectId]/templates/route.ts +++ b/frontend/app/api/projects/[projectId]/templates/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/traces/[traceId]/route.ts b/frontend/app/api/projects/[projectId]/traces/[traceId]/route.ts index 7952efa3..8e8023cb 100644 --- a/frontend/app/api/projects/[projectId]/traces/[traceId]/route.ts +++ b/frontend/app/api/projects/[projectId]/traces/[traceId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/[projectId]/traces/metrics/route.ts b/frontend/app/api/projects/[projectId]/traces/metrics/route.ts index 0b13b8a0..7b3a1c22 100644 --- a/frontend/app/api/projects/[projectId]/traces/metrics/route.ts +++ b/frontend/app/api/projects/[projectId]/traces/metrics/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/traces/route.ts b/frontend/app/api/projects/[projectId]/traces/route.ts index ccab981a..2874f854 100644 --- a/frontend/app/api/projects/[projectId]/traces/route.ts +++ b/frontend/app/api/projects/[projectId]/traces/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET( req: NextRequest, diff --git a/frontend/app/api/projects/[projectId]/traces/workshop/[pipelineVersionId]/route.ts b/frontend/app/api/projects/[projectId]/traces/workshop/[pipelineVersionId]/route.ts index ec92501e..1ba6b6a9 100644 --- a/frontend/app/api/projects/[projectId]/traces/workshop/[pipelineVersionId]/route.ts +++ b/frontend/app/api/projects/[projectId]/traces/workshop/[pipelineVersionId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/projects/route.ts b/frontend/app/api/projects/route.ts index 2332249b..3f0252ce 100644 --- a/frontend/app/api/projects/route.ts +++ b/frontend/app/api/projects/route.ts @@ -1,8 +1,9 @@ -import { authOptions } from '@/lib/auth'; -import { fetcher } from '@/lib/utils'; +import { type NextRequest } from 'next/server'; import { getServerSession } from 'next-auth'; + +import { authOptions } from '@/lib/auth'; import { isCurrentUserMemberOfWorkspace } from '@/lib/db/utils'; -import { type NextRequest } from 'next/server'; +import { fetcher } from '@/lib/utils'; export async function POST(req: NextRequest): Promise { const session = await getServerSession(authOptions); diff --git a/frontend/app/api/workspaces/[workspaceId]/invite/route.ts b/frontend/app/api/workspaces/[workspaceId]/invite/route.ts index 387ff97b..289ea0ca 100644 --- a/frontend/app/api/workspaces/[workspaceId]/invite/route.ts +++ b/frontend/app/api/workspaces/[workspaceId]/invite/route.ts @@ -1,11 +1,11 @@ import { and, count, eq } from 'drizzle-orm'; -import { apiKeys, membersOfWorkspaces, workspaces } from '@/lib/db/migrations/schema'; +import jwt from 'jsonwebtoken'; +import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { db } from '@/lib/db/drizzle'; -import { getServerSession } from 'next-auth'; +import { apiKeys, membersOfWorkspaces, workspaces } from '@/lib/db/migrations/schema'; import { isCurrentUserMemberOfWorkspace } from '@/lib/db/utils'; -import jwt from 'jsonwebtoken'; import { sendInvitationEmail } from '@/lib/emails/utils'; export async function POST( diff --git a/frontend/app/api/workspaces/[workspaceId]/route.ts b/frontend/app/api/workspaces/[workspaceId]/route.ts index dea6078b..26ac69ce 100644 --- a/frontend/app/api/workspaces/[workspaceId]/route.ts +++ b/frontend/app/api/workspaces/[workspaceId]/route.ts @@ -1,6 +1,7 @@ +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; export async function GET( req: Request, diff --git a/frontend/app/api/workspaces/[workspaceId]/update-seats/route.ts b/frontend/app/api/workspaces/[workspaceId]/update-seats/route.ts index a95ba989..fca76a4c 100644 --- a/frontend/app/api/workspaces/[workspaceId]/update-seats/route.ts +++ b/frontend/app/api/workspaces/[workspaceId]/update-seats/route.ts @@ -1,9 +1,10 @@ -import { db } from '@/lib/db/drizzle'; import { eq } from 'drizzle-orm'; -import { isCurrentUserMemberOfWorkspace } from '@/lib/db/utils'; import { NextRequest } from 'next/server'; import Stripe from 'stripe'; + +import { db } from '@/lib/db/drizzle'; import { workspaces } from '@/lib/db/migrations/schema'; +import { isCurrentUserMemberOfWorkspace } from '@/lib/db/utils'; const SEAT_PRICE_LOOKUP_KEY = 'additional_seat_2024_11'; diff --git a/frontend/app/api/workspaces/route.ts b/frontend/app/api/workspaces/route.ts index 902667d8..c4d010fd 100644 --- a/frontend/app/api/workspaces/route.ts +++ b/frontend/app/api/workspaces/route.ts @@ -1,7 +1,8 @@ +import { NextRequest } from 'next/server'; +import { getServerSession } from 'next-auth'; + import { authOptions } from '@/lib/auth'; import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { NextRequest } from 'next/server'; export async function GET(req: NextRequest): Promise { const session = await getServerSession(authOptions); diff --git a/frontend/app/blog/[slug]/page.tsx b/frontend/app/blog/[slug]/page.tsx index f841dcbb..fe430e79 100644 --- a/frontend/app/blog/[slug]/page.tsx +++ b/frontend/app/blog/[slug]/page.tsx @@ -1,14 +1,14 @@ -import { getBlogPost } from "@/lib/blog/utils"; +import type { Metadata } from "next"; +import { getServerSession } from "next-auth"; +import { MDXRemote } from "next-mdx-remote/rsc"; -import { authOptions } from "@/lib/auth"; import BlogMeta from "@/components/blog/blog-meta"; -import { getServerSession } from "next-auth"; -import LandingHeader from "@/components/landing/landing-header"; import MDHeading from "@/components/blog/md-heading"; -import { MDXRemote } from "next-mdx-remote/rsc"; -import type { Metadata } from "next"; -import Footer from "@/components/landing/footer"; import PreHighlighter from "@/components/blog/pre-highlighter"; +import Footer from "@/components/landing/footer"; +import LandingHeader from "@/components/landing/landing-header"; +import { authOptions } from "@/lib/auth"; +import { getBlogPost } from "@/lib/blog/utils"; export const generateMetadata = async ({ params, diff --git a/frontend/app/blog/page.tsx b/frontend/app/blog/page.tsx index 55d31935..d046d947 100644 --- a/frontend/app/blog/page.tsx +++ b/frontend/app/blog/page.tsx @@ -1,3 +1,8 @@ +import { Metadata } from "next"; +import Image from "next/image"; +import Link from "next/link"; +import { getServerSession } from "next-auth"; + import Footer from "@/components/landing/footer"; import LandingHeader from "@/components/landing/landing-header"; import { Card, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; @@ -5,10 +10,6 @@ import { Label } from "@/components/ui/label"; import { authOptions } from "@/lib/auth"; import { getBlogPosts } from "@/lib/blog/utils"; import { formatUTCDate } from "@/lib/utils"; -import { Metadata } from "next"; -import { getServerSession } from "next-auth"; -import Image from "next/image"; -import Link from "next/link"; export const metadata: Metadata = { title: "Laminar Blog", diff --git a/frontend/app/checkout/page.tsx b/frontend/app/checkout/page.tsx index 8b815b2e..f5b9848c 100644 --- a/frontend/app/checkout/page.tsx +++ b/frontend/app/checkout/page.tsx @@ -1,10 +1,10 @@ -import { fetcher, fetcherJSON } from '@/lib/utils'; - -import { authOptions } from '@/lib/auth'; -import { getServerSession } from 'next-auth'; import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; import Stripe from 'stripe'; + +import { authOptions } from '@/lib/auth'; import { UserSubscriptionInfo } from '@/lib/checkout/types'; +import { fetcher, fetcherJSON } from '@/lib/utils'; export default async function CheckoutPage({ searchParams diff --git a/frontend/app/checkout/portal/page.tsx b/frontend/app/checkout/portal/page.tsx index 63980c4e..d19d55bf 100644 --- a/frontend/app/checkout/portal/page.tsx +++ b/frontend/app/checkout/portal/page.tsx @@ -1,9 +1,10 @@ -import { authOptions } from '@/lib/auth'; -import { fetcherJSON } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; import Stripe from 'stripe'; + +import { authOptions } from '@/lib/auth'; import { UserSubscriptionInfo } from '@/lib/checkout/types'; +import { fetcherJSON } from '@/lib/utils'; export default async function CheckoutPortalPage({ searchParams diff --git a/frontend/app/error.tsx b/frontend/app/error.tsx index 8f7e7d17..966d399b 100644 --- a/frontend/app/error.tsx +++ b/frontend/app/error.tsx @@ -1,9 +1,10 @@ 'use client'; // Error components must be Client Components -import icon from '@/assets/logo/icon.png'; import Image from 'next/image'; import Link from 'next/link'; +import icon from '@/assets/logo/icon.png'; + export default function Error({ error, reset diff --git a/frontend/app/errors/internal/page.tsx b/frontend/app/errors/internal/page.tsx index eacdb386..b887fa53 100644 --- a/frontend/app/errors/internal/page.tsx +++ b/frontend/app/errors/internal/page.tsx @@ -1,7 +1,8 @@ -import icon from '@/assets/logo/icon_light.svg'; import Image from 'next/image'; import Link from 'next/link'; +import icon from '@/assets/logo/icon_light.svg'; + export default function InternalError() { return (
diff --git a/frontend/app/invitations/page.tsx b/frontend/app/invitations/page.tsx index 06b4a428..d04957ea 100644 --- a/frontend/app/invitations/page.tsx +++ b/frontend/app/invitations/page.tsx @@ -1,16 +1,16 @@ -import { apiKeys, membersOfWorkspaces, workspaces } from '@/lib/db/migrations/schema'; +import { eq } from 'drizzle-orm'; import jwt, { JwtPayload } from 'jsonwebtoken'; +import { revalidatePath } from 'next/cache'; +import Image from 'next/image'; import { notFound, redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; -import { authOptions } from '@/lib/auth'; +import noise from '@/assets/landing/noise.jpeg'; +import logo from '@/assets/logo/logo.svg'; import { Button } from '@/components/ui/button'; +import { authOptions } from '@/lib/auth'; import { db } from '@/lib/db/drizzle'; -import { eq } from 'drizzle-orm'; -import { getServerSession } from 'next-auth'; -import Image from 'next/image'; -import logo from '@/assets/logo/logo.svg'; -import noise from '@/assets/landing/noise.jpeg'; -import { revalidatePath } from 'next/cache'; +import { apiKeys, membersOfWorkspaces, workspaces } from '@/lib/db/migrations/schema'; export default async function SignInPage({ params, diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index cb9346b1..187470d6 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -1,12 +1,13 @@ import '@/app/globals.css'; -import { fontMono, fontSans, fontSans2 } from '@/lib/fonts'; -import { cn } from '@/lib/utils'; -import dynamic from 'next/dynamic'; import { Metadata } from 'next'; -import { PHProvider } from './providers'; +import dynamic from 'next/dynamic'; + import { Toaster } from '@/components/ui/toaster'; +import { sans } from '@/lib/fonts'; +import { cn } from '@/lib/utils'; +import { PHProvider } from './providers'; export const metadata: Metadata = { metadataBase: new URL('https://www.lmnr.ai'), @@ -23,15 +24,10 @@ export default async function RootLayout({ children: React.ReactNode; }) { return ( - +
diff --git a/frontend/app/not-found.tsx b/frontend/app/not-found.tsx index 2fe5e1d0..09f746f7 100644 --- a/frontend/app/not-found.tsx +++ b/frontend/app/not-found.tsx @@ -1,7 +1,8 @@ -import icon from '@/assets/logo/icon.png'; import Image from 'next/image'; import Link from 'next/link'; +import icon from '@/assets/logo/icon.png'; + export default function NotFound() { return (
diff --git a/frontend/app/onboarding/page.tsx b/frontend/app/onboarding/page.tsx index fe419ac8..487ba534 100644 --- a/frontend/app/onboarding/page.tsx +++ b/frontend/app/onboarding/page.tsx @@ -1,10 +1,11 @@ -import { authOptions } from '@/lib/auth'; -import CreateFirstWorkspaceAndProject from '@/components/onboarding/create-first-workspace-and-project'; -import { getServerSession } from 'next-auth'; import { Metadata } from 'next'; -import OnboardingHeader from '@/components/onboarding/onboarding-header'; import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; + +import CreateFirstWorkspaceAndProject from '@/components/onboarding/create-first-workspace-and-project'; +import OnboardingHeader from '@/components/onboarding/onboarding-header'; import { UserContextProvider } from '@/contexts/user-context'; +import { authOptions } from '@/lib/auth'; export const metadata: Metadata = { title: 'Create workspace and project' diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index 8ea76800..c8c143be 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx @@ -1,11 +1,11 @@ -import { Feature, isFeatureEnabled } from '@/lib/features/features'; - -import { authOptions } from '@/lib/auth'; +import { Metadata } from 'next'; +import { redirect } from 'next/navigation'; import { getServerSession } from 'next-auth'; + import Landing from '@/components/landing/landing'; import LandingHeader from '@/components/landing/landing-header'; -import { Metadata } from 'next'; -import { redirect } from 'next/navigation'; +import { authOptions } from '@/lib/auth'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; export const metadata: Metadata = { diff --git a/frontend/app/posthog-pageview.tsx b/frontend/app/posthog-pageview.tsx index 5be05393..2659ce5f 100644 --- a/frontend/app/posthog-pageview.tsx +++ b/frontend/app/posthog-pageview.tsx @@ -2,8 +2,8 @@ 'use client'; import { usePathname, useSearchParams } from 'next/navigation'; -import { useEffect } from 'react'; import { usePostHog } from 'posthog-js/react'; +import { useEffect } from 'react'; export default function PostHogPageView(): null { const pathname = usePathname(); diff --git a/frontend/app/pricing/page.tsx b/frontend/app/pricing/page.tsx index c3b69218..bead6c22 100644 --- a/frontend/app/pricing/page.tsx +++ b/frontend/app/pricing/page.tsx @@ -1,8 +1,9 @@ -import { authOptions } from '@/lib/auth'; +import { Metadata } from 'next'; import { getServerSession } from 'next-auth'; + import LandingHeader from '@/components/landing/landing-header'; -import { Metadata } from 'next'; import Pricing from '@/components/landing/pricing'; +import { authOptions } from '@/lib/auth'; export const metadata: Metadata = { title: 'Pricing – Laminar' diff --git a/frontend/app/profile/usage/page.tsx b/frontend/app/profile/usage/page.tsx index bb6aaf92..e45b059b 100644 --- a/frontend/app/profile/usage/page.tsx +++ b/frontend/app/profile/usage/page.tsx @@ -1,11 +1,12 @@ -import { authOptions } from '@/lib/auth'; -import { getServerSession } from 'next-auth'; import { Metadata } from 'next'; +import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; + import Profile from '@/components/profile/profile'; import ProfileHeader from '@/components/profile/profile-header'; -import { redirect } from 'next/navigation'; -import { UserContextProvider } from '@/contexts/user-context'; import WorkspacesNavbar from '@/components/projects/workspaces-navbar'; +import { UserContextProvider } from '@/contexts/user-context'; +import { authOptions } from '@/lib/auth'; export const metadata: Metadata = { title: 'Profile | Laminar' diff --git a/frontend/app/project/[projectId]/dashboard/page.tsx b/frontend/app/project/[projectId]/dashboard/page.tsx index 1ca7b3e0..47a843f5 100644 --- a/frontend/app/project/[projectId]/dashboard/page.tsx +++ b/frontend/app/project/[projectId]/dashboard/page.tsx @@ -1,6 +1,7 @@ -import Dashboard from '@/components/dashboard/dashboard'; import { Metadata } from 'next'; +import Dashboard from '@/components/dashboard/dashboard'; + export const metadata: Metadata = { title: 'Dashboard' }; diff --git a/frontend/app/project/[projectId]/datasets/[datasetId]/page.tsx b/frontend/app/project/[projectId]/datasets/[datasetId]/page.tsx index 2d775095..25990241 100644 --- a/frontend/app/project/[projectId]/datasets/[datasetId]/page.tsx +++ b/frontend/app/project/[projectId]/datasets/[datasetId]/page.tsx @@ -1,11 +1,12 @@ import { and, eq } from 'drizzle-orm'; -import { authOptions } from '@/lib/auth'; -import Dataset from '@/components/dataset/dataset'; -import { datasets } from '@/lib/db/migrations/schema'; -import { db } from '@/lib/db/drizzle'; -import { getServerSession } from 'next-auth'; import { Metadata } from 'next'; import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; + +import Dataset from '@/components/dataset/dataset'; +import { authOptions } from '@/lib/auth'; +import { db } from '@/lib/db/drizzle'; +import { datasets } from '@/lib/db/migrations/schema'; export const metadata: Metadata = { diff --git a/frontend/app/project/[projectId]/datasets/page.tsx b/frontend/app/project/[projectId]/datasets/page.tsx index 0f02231c..b68f9d80 100644 --- a/frontend/app/project/[projectId]/datasets/page.tsx +++ b/frontend/app/project/[projectId]/datasets/page.tsx @@ -1,8 +1,9 @@ -import { authOptions } from '@/lib/auth'; -import Datasets from '@/components/datasets/datasets'; -import { getServerSession } from 'next-auth'; import { Metadata } from 'next'; import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; + +import Datasets from '@/components/datasets/datasets'; +import { authOptions } from '@/lib/auth'; export const metadata: Metadata = { title: 'Datasets' diff --git a/frontend/app/project/[projectId]/evaluations/[evaluationId]/page.tsx b/frontend/app/project/[projectId]/evaluations/[evaluationId]/page.tsx index 0e84e9f8..963de31c 100644 --- a/frontend/app/project/[projectId]/evaluations/[evaluationId]/page.tsx +++ b/frontend/app/project/[projectId]/evaluations/[evaluationId]/page.tsx @@ -1,14 +1,14 @@ import { and, asc, eq, sql } from 'drizzle-orm'; +import { Metadata } from 'next'; +import { redirect } from 'next/navigation'; + +import Evaluation from '@/components/evaluation/evaluation'; +import { db } from '@/lib/db/drizzle'; import { evaluationResults, evaluations,evaluationScores } from '@/lib/db/migrations/schema'; - -import { db } from '@/lib/db/drizzle'; -import Evaluation from '@/components/evaluation/evaluation'; import { EvaluationResultsInfo } from '@/lib/evaluation/types'; -import { Metadata } from 'next'; -import { redirect } from 'next/navigation'; export const metadata: Metadata = { diff --git a/frontend/app/project/[projectId]/evaluations/page.tsx b/frontend/app/project/[projectId]/evaluations/page.tsx index 88c533e4..c30c2a24 100644 --- a/frontend/app/project/[projectId]/evaluations/page.tsx +++ b/frontend/app/project/[projectId]/evaluations/page.tsx @@ -1,9 +1,10 @@ -import { db } from '@/lib/db/drizzle'; import { eq } from 'drizzle-orm'; -import EvalsPagePlaceholder from '@/components/evaluations/page-placeholder'; +import { Metadata } from 'next'; + import Evaluations from '@/components/evaluations/evaluations'; +import EvalsPagePlaceholder from '@/components/evaluations/page-placeholder'; +import { db } from '@/lib/db/drizzle'; import { evaluations } from '@/lib/db/migrations/schema'; -import { Metadata } from 'next'; export const metadata: Metadata = { title: 'Evaluations' diff --git a/frontend/app/project/[projectId]/events/[eventId]/page.tsx b/frontend/app/project/[projectId]/events/[eventId]/page.tsx deleted file mode 100644 index b3ff3d78..00000000 --- a/frontend/app/project/[projectId]/events/[eventId]/page.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import EventComponent from '@/components/event/event'; -import { EventTemplate } from '@/lib/events/types'; -import { fetcher } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { Metadata } from 'next'; -import { redirect } from 'next/navigation'; - -export const metadata: Metadata = { - title: 'Event' -}; - -const getEventTemplate = async ( - userApiKey: string, - projectId: string, - templateId: string -) => { - const response = await fetcher( - `/projects/${projectId}/event-templates/${templateId}`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${userApiKey}` - } - } - ); - return (await response.json()) as EventTemplate; -}; - -const getMetrics = async ( - userApiKey: string, - projectId: string, - templateId: string, - pastHours: string, - groupByInterval: string -) => { - const response = await fetcher( - `/projects/${projectId}/event-templates/${templateId}/metrics?pastHours=${pastHours}&groupByInterval=${groupByInterval}&aggregation=Total&metric=eventCount`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${userApiKey}` - } - } - ); - return (await response.json()) as any; -}; - -export default async function EventTemplatePage({ - params, - searchParams -}: { - params: { projectId: string; eventId: string }; - searchParams: { pastHours?: string }; -}) { - const session = await getServerSession(authOptions); - if (!session) { - redirect('/sign-in'); - } - - const pastHours = searchParams.pastHours ?? '24'; - - let groupByInterval = 'minute'; - if (pastHours === '1') { - groupByInterval = 'minute'; - } else if (pastHours === '7') { - groupByInterval = 'minute'; - } else if (pastHours === '24') { - groupByInterval = 'hour'; - } else { - groupByInterval = 'day'; - } - - const eventTemplate = await getEventTemplate( - session.user.apiKey, - params.projectId, - params.eventId - ); - const metrics = await getMetrics( - session.user.apiKey, - params.projectId, - params.eventId, - pastHours, - groupByInterval - ); - - return ; -} diff --git a/frontend/app/project/[projectId]/events/page.tsx b/frontend/app/project/[projectId]/events/page.tsx deleted file mode 100644 index 3c42c441..00000000 --- a/frontend/app/project/[projectId]/events/page.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import { authOptions } from '@/lib/auth'; -import Events from '@/components/events/events'; -import { EventTemplate } from '@/lib/events/types'; -import { fetcherJSON } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; -import { Metadata } from 'next'; -import { redirect } from 'next/navigation'; - -export const metadata: Metadata = { - title: 'Events' -}; - -export default async function EventTemplatesPage({ - params, - searchParams -}: { - params: { projectId: string }; - searchParams: { [key: string]: string | string[] | undefined }; -}) { - const session = await getServerSession(authOptions); - if (!session) { - redirect('/sign-in'); - } - - const user = session.user; - const pastHours = searchParams.pastHours - ? Number(searchParams.pastHours) - : 24; - - const events = (await fetcherJSON( - `/projects/${params.projectId}/event-templates?pastHours=${pastHours}`, - { - method: 'GET', - headers: { - Authorization: `Bearer ${user.apiKey}` - } - } - )) as EventTemplate[]; - - return ; -} diff --git a/frontend/app/project/[projectId]/labeling-queues/[queueId]/page.tsx b/frontend/app/project/[projectId]/labeling-queues/[queueId]/page.tsx index 0c336160..cf456c92 100644 --- a/frontend/app/project/[projectId]/labeling-queues/[queueId]/page.tsx +++ b/frontend/app/project/[projectId]/labeling-queues/[queueId]/page.tsx @@ -1,10 +1,11 @@ import { and, eq } from 'drizzle-orm'; -import { db } from '@/lib/db/drizzle'; -import { labelingQueues } from '@/lib/db/migrations/schema'; import { Metadata } from 'next'; -import Queue from '@/components/queue/queue'; import { redirect } from 'next/navigation'; +import Queue from '@/components/queue/queue'; +import { db } from '@/lib/db/drizzle'; +import { labelingQueues } from '@/lib/db/migrations/schema'; + export const metadata: Metadata = { title: 'Labeling Queue' }; diff --git a/frontend/app/project/[projectId]/layout.tsx b/frontend/app/project/[projectId]/layout.tsx index 0e396dca..17792f82 100644 --- a/frontend/app/project/[projectId]/layout.tsx +++ b/frontend/app/project/[projectId]/layout.tsx @@ -1,17 +1,17 @@ import '@/app/globals.css'; -import { Feature, isFeatureEnabled } from '@/lib/features/features'; - -import { authOptions } from '@/lib/auth'; -import { fetcherJSON } from '@/lib/utils'; -import { GetProjectResponse } from '@/lib/workspaces/types'; +import { redirect } from 'next/navigation'; import { getServerSession } from 'next-auth'; + import PostHogClient from '@/app/posthog'; -import { ProjectContextProvider } from '@/contexts/project-context'; import ProjectNavbarCollapsed from '@/components/project/project-navbar-collapsed'; import ProjectUsageBanner from '@/components/project/usage-banner'; -import { redirect } from 'next/navigation'; +import { ProjectContextProvider } from '@/contexts/project-context'; import { UserContextProvider } from '@/contexts/user-context'; +import { authOptions } from '@/lib/auth'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; +import { fetcherJSON } from '@/lib/utils'; +import { GetProjectResponse } from '@/lib/workspaces/types'; export default async function ProjectIdLayout({ params, diff --git a/frontend/app/project/[projectId]/pipelines/[pipelineId]/page.tsx b/frontend/app/project/[projectId]/pipelines/[pipelineId]/page.tsx index cfc00b3d..87948ac8 100644 --- a/frontend/app/project/[projectId]/pipelines/[pipelineId]/page.tsx +++ b/frontend/app/project/[projectId]/pipelines/[pipelineId]/page.tsx @@ -1,11 +1,12 @@ -import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { getServerSession, Session } from 'next-auth'; -import { authOptions } from '@/lib/auth'; -import { fetcherJSON } from '@/lib/utils'; import { Metadata } from 'next'; +import { redirect } from 'next/navigation'; +import { getServerSession, Session } from 'next-auth'; + import Pipeline from '@/components/pipeline/pipeline'; +import { authOptions } from '@/lib/auth'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; import { PipelineVersion } from '@/lib/pipeline/types'; -import { redirect } from 'next/navigation'; +import { fetcherJSON } from '@/lib/utils'; const URL_QUERY_PARAMS = { SELECTED_VERSION_ID: 'versionId' diff --git a/frontend/app/project/[projectId]/playgrounds/[playgroundId]/page.tsx b/frontend/app/project/[projectId]/playgrounds/[playgroundId]/page.tsx index fbf2226e..c2c48fce 100644 --- a/frontend/app/project/[projectId]/playgrounds/[playgroundId]/page.tsx +++ b/frontend/app/project/[projectId]/playgrounds/[playgroundId]/page.tsx @@ -1,8 +1,9 @@ -import { db } from '@/lib/db/drizzle'; import { eq } from 'drizzle-orm'; import { Metadata } from 'next'; import { notFound } from 'next/navigation'; + import Playground from '@/components/playground/playground'; +import { db } from '@/lib/db/drizzle'; import { playgrounds } from '@/lib/db/migrations/schema'; import { Playground as PlaygroundType } from '@/lib/playground/types'; diff --git a/frontend/app/project/[projectId]/settings/page.tsx b/frontend/app/project/[projectId]/settings/page.tsx index 1da55a23..b6ddabfd 100644 --- a/frontend/app/project/[projectId]/settings/page.tsx +++ b/frontend/app/project/[projectId]/settings/page.tsx @@ -1,9 +1,10 @@ -import { authOptions } from '@/lib/auth'; -import { fetcherJSON } from '@/lib/utils'; -import { getServerSession } from 'next-auth'; import { Metadata } from 'next'; import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; + import Settings from '@/components/settings/settings'; +import { authOptions } from '@/lib/auth'; +import { fetcherJSON } from '@/lib/utils'; export const metadata: Metadata = { title: 'Settings' diff --git a/frontend/app/project/[projectId]/traces/page.tsx b/frontend/app/project/[projectId]/traces/page.tsx index 1a3f9d7a..f20eff1d 100644 --- a/frontend/app/project/[projectId]/traces/page.tsx +++ b/frontend/app/project/[projectId]/traces/page.tsx @@ -1,10 +1,11 @@ -import { db } from '@/lib/db/drizzle'; import { eq } from 'drizzle-orm'; -import Header from '@/components/ui/header'; import { Metadata } from 'next'; -import { spans } from '@/lib/db/migrations/schema'; -import TracesDashboard from '@/components/traces/traces'; + import TracesPagePlaceholder from '@/components/traces/page-placeholder'; +import TracesDashboard from '@/components/traces/traces'; +import Header from '@/components/ui/header'; +import { db } from '@/lib/db/drizzle'; +import { spans } from '@/lib/db/migrations/schema'; export const metadata: Metadata = { title: 'Traces' diff --git a/frontend/app/projects/page.tsx b/frontend/app/projects/page.tsx index a206b699..ff47e319 100644 --- a/frontend/app/projects/page.tsx +++ b/frontend/app/projects/page.tsx @@ -1,12 +1,13 @@ -import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { authOptions } from '@/lib/auth'; -import { getServerSession } from 'next-auth'; -import Header from '@/components/ui/header'; import { Metadata } from 'next'; -import Projects from '@/components/projects/projects'; import { redirect } from 'next/navigation'; -import { UserContextProvider } from '@/contexts/user-context'; +import { getServerSession } from 'next-auth'; + +import Projects from '@/components/projects/projects'; import WorkspacesNavbar from '@/components/projects/workspaces-navbar'; +import Header from '@/components/ui/header'; +import { UserContextProvider } from '@/contexts/user-context'; +import { authOptions } from '@/lib/auth'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; export const metadata: Metadata = { title: 'Projects' diff --git a/frontend/app/sign-in/page.tsx b/frontend/app/sign-in/page.tsx index 136e0ee4..3b83a4ab 100644 --- a/frontend/app/sign-in/page.tsx +++ b/frontend/app/sign-in/page.tsx @@ -1,13 +1,13 @@ -import { Feature, isFeatureEnabled } from '@/lib/features/features'; +import Image from 'next/image'; +import { redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; +import noise from '@/assets/landing/noise.jpeg'; +import logo from '@/assets/logo/logo.svg'; import { EmailSignInButton } from '@/components/sign-in/email-signin'; -import { getServerSession } from 'next-auth'; import { GitHubSignInButton } from '@/components/sign-in/github-signin'; import { GoogleSignInButton } from '@/components/sign-in/google-signin'; -import Image from 'next/image'; -import logo from '@/assets/logo/logo.svg'; -import noise from '@/assets/landing/noise.jpeg'; -import { redirect } from 'next/navigation'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; export default async function SignInPage({ params, diff --git a/frontend/app/webhook/route.ts b/frontend/app/webhook/route.ts index b955fafa..a3f9d9f4 100644 --- a/frontend/app/webhook/route.ts +++ b/frontend/app/webhook/route.ts @@ -1,3 +1,6 @@ +import { type NextRequest } from 'next/server'; +import stripe from 'stripe'; + import { getIdFromStripeObject, isLookupKeyForAdditionalSeats, @@ -5,10 +8,7 @@ import { LOOKUP_KEY_TO_TIER_NAME, manageSubscriptionEvent } from '@/lib/checkout/utils'; - -import { type NextRequest } from 'next/server'; import { sendOnPaymentReceivedEmail } from '@/lib/emails/utils'; -import stripe from 'stripe'; async function sendEmailOnInvoiceReceived( itemDescriptions: ItemDescription[], diff --git a/frontend/app/workspace/[workspaceId]/page.tsx b/frontend/app/workspace/[workspaceId]/page.tsx index d38448d4..51275e6c 100644 --- a/frontend/app/workspace/[workspaceId]/page.tsx +++ b/frontend/app/workspace/[workspaceId]/page.tsx @@ -1,17 +1,17 @@ -import { cn, fetcherJSON } from '@/lib/utils'; -import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { membersOfWorkspaces, subscriptionTiers, users, workspaces } from '@/lib/db/migrations/schema'; +import { eq } from 'drizzle-orm'; +import { Metadata } from 'next'; import { notFound, redirect } from 'next/navigation'; +import { getServerSession } from 'next-auth'; +import WorkspacesNavbar from '@/components/projects/workspaces-navbar'; +import WorkspaceComponent from '@/components/workspace/workspace'; +import { UserContextProvider } from '@/contexts/user-context'; import { authOptions } from '@/lib/auth'; import { db } from '@/lib/db/drizzle'; -import { eq } from 'drizzle-orm'; -import { getServerSession } from 'next-auth'; -import { Metadata } from 'next'; -import { UserContextProvider } from '@/contexts/user-context'; -import WorkspaceComponent from '@/components/workspace/workspace'; -import WorkspacesNavbar from '@/components/projects/workspaces-navbar'; +import { membersOfWorkspaces, subscriptionTiers, users, workspaces } from '@/lib/db/migrations/schema'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; import { WorkspaceStats } from '@/lib/usage/types'; +import { cn, fetcherJSON } from '@/lib/utils'; import { WorkspaceWithUsers } from '@/lib/workspaces/types'; export const metadata: Metadata = { diff --git a/frontend/assets/fonts/Inter-Bold.woff b/frontend/assets/fonts/Inter-Bold.woff deleted file mode 100644 index 1e80f623..00000000 Binary files a/frontend/assets/fonts/Inter-Bold.woff and /dev/null differ diff --git a/frontend/assets/fonts/Inter-Regular.woff b/frontend/assets/fonts/Inter-Regular.woff deleted file mode 100644 index 4c6b7118..00000000 Binary files a/frontend/assets/fonts/Inter-Regular.woff and /dev/null differ diff --git a/frontend/assets/fonts/text-security-disc.woff2 b/frontend/assets/fonts/text-security-disc.woff2 deleted file mode 100644 index ddaf38b1..00000000 Binary files a/frontend/assets/fonts/text-security-disc.woff2 and /dev/null differ diff --git a/frontend/assets/landing/labels.png b/frontend/assets/landing/labels.png index 8dd02ee5..5a91526e 100644 Binary files a/frontend/assets/landing/labels.png and b/frontend/assets/landing/labels.png differ diff --git a/frontend/assets/landing/small-trace.png b/frontend/assets/landing/small-trace.png index f8e125cf..f72b7ce3 100644 Binary files a/frontend/assets/landing/small-trace.png and b/frontend/assets/landing/small-trace.png differ diff --git a/frontend/assets/landing/traces.png b/frontend/assets/landing/traces.png index fb47310b..c4c6b27f 100644 Binary files a/frontend/assets/landing/traces.png and b/frontend/assets/landing/traces.png differ diff --git a/frontend/components/blog/blog-meta.tsx b/frontend/components/blog/blog-meta.tsx index ef7656db..a9d0906c 100644 --- a/frontend/components/blog/blog-meta.tsx +++ b/frontend/components/blog/blog-meta.tsx @@ -1,8 +1,10 @@ +import Image from "next/image"; +import Link from "next/link"; + import { BlogMetadata } from "@/lib/blog/types"; import { formatUTCDate } from "@/lib/utils"; -import Image from "next/image"; + import { Label } from "../ui/label"; -import Link from "next/link"; interface BlogMetaProps { data: BlogMetadata; diff --git a/frontend/components/blog/md-heading.tsx b/frontend/components/blog/md-heading.tsx index 14f138ed..a795686d 100644 --- a/frontend/components/blog/md-heading.tsx +++ b/frontend/components/blog/md-heading.tsx @@ -1,8 +1,9 @@ -import { cn } from "@/lib/utils"; -import { headingToUrl } from "@/lib/blog/utils"; import Link from "next/link"; +import { headingToUrl } from "@/lib/blog/utils"; +import { cn } from "@/lib/utils"; + interface MDHeadingProps { props: any; level: number; diff --git a/frontend/components/blog/pre-highlighter.tsx b/frontend/components/blog/pre-highlighter.tsx index 23669d41..916ed8de 100644 --- a/frontend/components/blog/pre-highlighter.tsx +++ b/frontend/components/blog/pre-highlighter.tsx @@ -1,9 +1,10 @@ 'use client'; -import { cn } from "@/lib/utils"; -import CodeHighlighter from "@/components/ui/code-highlighter"; import React from "react"; +import CodeHighlighter from "@/components/ui/code-highlighter"; +import { cn } from "@/lib/utils"; + interface PreHighlighterProps { children?: React.ReactElement | React.ReactNode; className?: string; diff --git a/frontend/components/blog/toc.tsx b/frontend/components/blog/toc.tsx index ad253be8..bd8fea73 100644 --- a/frontend/components/blog/toc.tsx +++ b/frontend/components/blog/toc.tsx @@ -1,6 +1,7 @@ -import { cn } from "@/lib/utils"; import Link from "next/link"; +import { cn } from "@/lib/utils"; + interface TableOfContentsProps { headings: { level: number, text: string, anchor: string }[]; } diff --git a/frontend/components/button-scroll-to-bottom.tsx b/frontend/components/button-scroll-to-bottom.tsx index dc755490..8af496ef 100644 --- a/frontend/components/button-scroll-to-bottom.tsx +++ b/frontend/components/button-scroll-to-bottom.tsx @@ -3,9 +3,9 @@ import * as React from 'react'; import { Button, type ButtonProps } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { IconArrowDown } from '@/components/ui/icons'; import { useAtBottom } from '@/lib/hooks/use-at-bottom'; +import { cn } from '@/lib/utils'; export function ButtonScrollToBottom({ className, ...props }: ButtonProps) { const isAtBottom = useAtBottom(); diff --git a/frontend/components/checkout/checkout-success.tsx b/frontend/components/checkout/checkout-success.tsx index 934416a1..4ca7929c 100644 --- a/frontend/components/checkout/checkout-success.tsx +++ b/frontend/components/checkout/checkout-success.tsx @@ -1,10 +1,12 @@ 'use client'; -import { Button } from '../ui/button'; -import { Label } from '../ui/label'; import Link from 'next/link'; + import { LOOKUP_KEY_TO_TIER_NAME } from '@/lib/checkout/utils'; +import { Button } from '../ui/button'; +import { Label } from '../ui/label'; + export interface CheckoutSuccessProps { sessionId: string; lookupKey: string; diff --git a/frontend/components/client-timestamp-formatter.tsx b/frontend/components/client-timestamp-formatter.tsx index b3d73e15..1f130c3c 100644 --- a/frontend/components/client-timestamp-formatter.tsx +++ b/frontend/components/client-timestamp-formatter.tsx @@ -1,9 +1,10 @@ +import { useEffect, useState } from 'react'; + import { convertToLocalTimeWithMillis, formatTimestamp, TIME_MILLISECONDS_FORMAT } from '@/lib/utils'; -import { useEffect, useState } from 'react'; // This component is a client-side only component that will format a timestamp // If it's not used, then there will be error because SSR will try to render diff --git a/frontend/components/dashboard/dashboard.tsx b/frontend/components/dashboard/dashboard.tsx index 61c5d804..f936872c 100644 --- a/frontend/components/dashboard/dashboard.tsx +++ b/frontend/components/dashboard/dashboard.tsx @@ -1,19 +1,21 @@ 'use client'; -import { getGroupByInterval } from '@/lib/utils'; +import { useRouter, useSearchParams } from 'next/navigation'; import { useEffect } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { GroupByInterval } from '@/lib/clickhouse/modifiers'; +import { SpanMetric, SpanMetricGroupBy } from '@/lib/clickhouse/spans'; +import { AggregationFunction } from '@/lib/clickhouse/utils'; +import { getGroupByInterval } from '@/lib/utils'; + import DateRangeFilter from '../ui/date-range-filter'; -import { useRouter, useSearchParams } from 'next/navigation'; import { GroupByPeriodSelect } from '../ui/group-by-period-select'; import Header from '../ui/header'; -import { useProjectContext } from '@/contexts/project-context'; -import { TraceStatChart } from './trace-stat-chart'; -import { SpanStatChart } from './span-stat-chart'; -import { SpanMetric, SpanMetricGroupBy } from '@/lib/clickhouse/spans'; -import { GroupByInterval } from '@/lib/clickhouse/modifiers'; import { ScrollArea } from '../ui/scroll-area'; -import { AggregationFunction } from '@/lib/clickhouse/utils'; +import { SpanStatChart } from './span-stat-chart'; import SpanSummaryChart from './span-summary-chart'; +import { TraceStatChart } from './trace-stat-chart'; const AGGREGATIONS: AggregationFunction[] = [ 'AVG', diff --git a/frontend/components/dashboard/events-metrics.tsx b/frontend/components/dashboard/events-metrics.tsx deleted file mode 100644 index ed44e701..00000000 --- a/frontend/components/dashboard/events-metrics.tsx +++ /dev/null @@ -1,172 +0,0 @@ -'use client'; - -import { CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts'; -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent -} from '@/components/ui/chart'; -import { - cn, - formatTimestampFromSeconds, - getGroupByInterval -} from '@/lib/utils'; -import { useEffect, useState } from 'react'; - -import DateRangeFilter from '../ui/date-range-filter'; -import { EventTemplate } from '@/lib/events/types'; -import { GroupByPeriodSelect } from '../ui/group-by-period-select'; -import { Skeleton } from '../ui/skeleton'; -import { useSearchParams } from 'next/navigation'; - -interface CustomChartProps { - eventTemplate: EventTemplate; - pastHours?: string; - startDate?: string; - endDate?: string; - className?: string; - defaultGroupByInterval?: string; -} - -export function CustomChart({ - eventTemplate, - className, - pastHours, - startDate, - endDate, - defaultGroupByInterval -}: CustomChartProps) { - const [xAxisKey, setXAxisKey] = useState('time'); - const [yAxisKey, setYAxisKey] = useState('value'); - const [data, setData] = useState(null); - - const chartConfig = { - [xAxisKey]: { - color: 'hsl(var(--chart-2))' - } - } satisfies ChartConfig; - - const inferredGroupBy = getGroupByInterval( - pastHours, - startDate, - endDate, - defaultGroupByInterval - ); - - useEffect(() => { - let url = `/api/projects/${eventTemplate.projectId}/event-templates/${eventTemplate.id}/metrics?metric=eventCount&aggregation=Total&groupByInterval=${inferredGroupBy}`; - if (pastHours !== null) { - url += `&pastHours=${pastHours}`; - } - if (startDate != null) { - url += `&startDate=${startDate}`; - } - if (endDate != null) { - url += `&endDate=${endDate}`; - } - - fetch(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - } - }).then((res) => - res.json().then((data: any) => { - setData(data); - }) - ); - }, [eventTemplate, pastHours, startDate, endDate, defaultGroupByInterval]); - - return ( -
-
-
-
- {eventTemplate.name} -
-
-
-
- {data === null ? ( - - ) : ( - - - - - - - formatTimestampFromSeconds(p[0].payload[xAxisKey]) - } - /> - } - /> - - - - )} -
-
- ); -} - -export interface DashboardProps { - eventTemplates: EventTemplate[]; -} - -export default function Dashboard({ eventTemplates }: DashboardProps) { - const searchParams = new URLSearchParams(useSearchParams().toString()); - const pastHours = searchParams.get('pastHours') as string | undefined; - const startDate = searchParams.get('startDate') as string | undefined; - const endDate = searchParams.get('endDate') as string | undefined; - const groupByInterval = searchParams.get('groupByInterval') as - | string - | undefined; - return ( -
-
- - -
-
- {eventTemplates.map((eventTemplate) => ( -
- -
- ))} -
-
- ); -} diff --git a/frontend/components/dashboard/span-stat-chart.tsx b/frontend/components/dashboard/span-stat-chart.tsx index 1c240ea3..531585ec 100644 --- a/frontend/components/dashboard/span-stat-chart.tsx +++ b/frontend/components/dashboard/span-stat-chart.tsx @@ -1,21 +1,23 @@ +import { useEffect, useMemo, useState } from 'react'; import { Bar, BarChart, CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts'; + import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'; +import { GroupByInterval } from '@/lib/clickhouse/modifiers'; +import { MetricTimeValue, SpanMetric, SpanMetricGroupBy, SpanMetricType } from '@/lib/clickhouse/spans'; +import { AggregationFunction } from '@/lib/clickhouse/utils'; import { cn, formatTimestamp, formatTimestampWithInterval, } from '@/lib/utils'; -import { useEffect, useMemo, useState } from 'react'; -import { Skeleton } from '../ui/skeleton'; -import { AggregationFunction } from '@/lib/clickhouse/utils'; -import { MetricTimeValue, SpanMetric, SpanMetricGroupBy, SpanMetricType } from '@/lib/clickhouse/spans'; -import { GroupByInterval } from '@/lib/clickhouse/modifiers'; + import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'; +import { Skeleton } from '../ui/skeleton'; const xAxisKey = 'timestamp'; diff --git a/frontend/components/dashboard/span-summary-chart.tsx b/frontend/components/dashboard/span-summary-chart.tsx index 3de869fb..564b759d 100644 --- a/frontend/components/dashboard/span-summary-chart.tsx +++ b/frontend/components/dashboard/span-summary-chart.tsx @@ -1,10 +1,12 @@ +import { useRouter } from "next/navigation"; +import { useEffect, useMemo, useState } from "react"; + import { SpanMetric, SpanMetricGroupBy } from "@/lib/clickhouse/spans"; import { AggregationFunction } from "@/lib/clickhouse/utils"; +import { buildSpansUrl } from "@/lib/traces/utils"; import { cn, toFixedIfFloat } from "@/lib/utils"; -import { useEffect, useMemo, useState } from "react"; + import { Skeleton } from "../ui/skeleton"; -import { useRouter } from "next/navigation"; -import { buildSpansUrl } from "@/lib/traces/utils"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip"; interface SpanSummaryChartProps { diff --git a/frontend/components/dashboard/trace-stat-chart.tsx b/frontend/components/dashboard/trace-stat-chart.tsx index 98a3cce0..5d7e8755 100644 --- a/frontend/components/dashboard/trace-stat-chart.tsx +++ b/frontend/components/dashboard/trace-stat-chart.tsx @@ -1,15 +1,17 @@ +import { useEffect, useState } from 'react'; + import { ChartConfig } from '@/components/ui/chart'; +import { GroupByInterval } from '@/lib/clickhouse/modifiers'; +import { TraceMetricDatapoint } from '@/lib/traces/types'; import { cn, formatTimestampFromSeconds, toFixedIfFloat, } from '@/lib/utils'; -import { useEffect, useState } from 'react'; + import { Skeleton } from '../ui/skeleton'; -import { TraceMetricDatapoint } from '@/lib/traces/types'; -import { GroupByInterval } from '@/lib/clickhouse/modifiers'; import { DefaultLineChart } from './span-stat-chart'; diff --git a/frontend/components/dataset/add-datapoints-dialog.tsx b/frontend/components/dataset/add-datapoints-dialog.tsx index 247a9423..0679e2d9 100644 --- a/frontend/components/dataset/add-datapoints-dialog.tsx +++ b/frontend/components/dataset/add-datapoints-dialog.tsx @@ -1,3 +1,6 @@ +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -5,9 +8,6 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import React, { useState } from 'react'; - -import { Button } from '@/components/ui/button'; import DatasetUpload from './dataset-upload'; diff --git a/frontend/components/dataset/dataset-panel.tsx b/frontend/components/dataset/dataset-panel.tsx index 4e0fb016..edca6b26 100644 --- a/frontend/components/dataset/dataset-panel.tsx +++ b/frontend/components/dataset/dataset-panel.tsx @@ -1,15 +1,16 @@ import { ChevronsRight, Loader2 } from 'lucide-react'; import { useEffect, useRef, useState } from 'react'; -import { Button } from '../ui/button'; +import { useProjectContext } from '@/contexts/project-context'; import { Datapoint } from '@/lib/dataset/types'; +import { useToast } from '@/lib/hooks/use-toast'; + +import { Button } from '../ui/button'; import Formatter from '../ui/formatter'; import { Label } from '../ui/label'; import MonoWithCopy from '../ui/mono-with-copy'; import { ScrollArea } from '../ui/scroll-area'; import { Skeleton } from '../ui/skeleton'; -import { useProjectContext } from '@/contexts/project-context'; -import { useToast } from '@/lib/hooks/use-toast'; interface DatasetPanelProps { datasetId: string; diff --git a/frontend/components/dataset/dataset-upload.tsx b/frontend/components/dataset/dataset-upload.tsx index 3df97b46..6c79937e 100644 --- a/frontend/components/dataset/dataset-upload.tsx +++ b/frontend/components/dataset/dataset-upload.tsx @@ -1,10 +1,10 @@ +import { Loader2 } from 'lucide-react'; import { useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; -import { uploadFile } from '@/lib/dataset/utils'; import { useProjectContext } from '@/contexts/project-context'; +import { uploadFile } from '@/lib/dataset/utils'; import { useToast } from '@/lib/hooks/use-toast'; interface DatasetUploadProps { diff --git a/frontend/components/dataset/dataset.tsx b/frontend/components/dataset/dataset.tsx index aeeaab6e..168ab918 100644 --- a/frontend/components/dataset/dataset.tsx +++ b/frontend/components/dataset/dataset.tsx @@ -1,6 +1,21 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; +import { Loader2, Trash2 } from 'lucide-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { Resizable } from 're-resizable'; +import { useEffect, useState } from 'react'; +import useSWR from 'swr'; + +import { Button } from '@/components/ui/button'; +import { DataTable } from '@/components/ui/datatable'; +import { useProjectContext } from '@/contexts/project-context'; import { Datapoint, Dataset as DatasetType } from '@/lib/dataset/types'; +import { useToast } from '@/lib/hooks/use-toast'; +import { PaginatedResponse } from '@/lib/types'; +import { swrFetcher } from '@/lib/utils'; + +import ClientTimestampFormatter from '../client-timestamp-formatter'; import { Dialog, DialogContent, @@ -10,27 +25,13 @@ import { DialogTitle, DialogTrigger } from '../ui/dialog'; -import { Loader2, Trash2 } from 'lucide-react'; -import { useEffect, useState } from 'react'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - -import AddDatapointsDialog from './add-datapoints-dialog'; -import { Button } from '@/components/ui/button'; -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import DatasetPanel from './dataset-panel'; -import { DataTable } from '@/components/ui/datatable'; import DownloadButton from '../ui/download-button'; import Header from '../ui/header'; +import MonoWithCopy from '../ui/mono-with-copy'; +import AddDatapointsDialog from './add-datapoints-dialog'; +import DatasetPanel from './dataset-panel'; import IndexDatasetDialog from './index-dataset-dialog'; import ManualAddDatapoint from './manual-add-datapoint-dialog'; -import MonoWithCopy from '../ui/mono-with-copy'; -import { PaginatedResponse } from '@/lib/types'; -import { Resizable } from 're-resizable'; -import { swrFetcher } from '@/lib/utils'; -import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; -import { useToast } from '@/lib/hooks/use-toast'; interface DatasetProps { dataset: DatasetType; diff --git a/frontend/components/dataset/delete-datapoints-dialog.tsx b/frontend/components/dataset/delete-datapoints-dialog.tsx index df9b3c33..b6dd4f2c 100644 --- a/frontend/components/dataset/delete-datapoints-dialog.tsx +++ b/frontend/components/dataset/delete-datapoints-dialog.tsx @@ -1,3 +1,7 @@ +import { Loader2 } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '../ui/button'; import { Dialog, DialogContent, @@ -6,11 +10,7 @@ import { DialogTitle, DialogTrigger } from '../ui/dialog'; - -import { Button } from '../ui/button'; import { Label } from '../ui/label'; -import { Loader2 } from 'lucide-react'; -import { useState } from 'react'; export interface DeleteDatapointsDialogProps { selectedDatapointIds: string[]; diff --git a/frontend/components/dataset/index-dataset-dialog.tsx b/frontend/components/dataset/index-dataset-dialog.tsx index c1f23c7c..4d318f69 100644 --- a/frontend/components/dataset/index-dataset-dialog.tsx +++ b/frontend/components/dataset/index-dataset-dialog.tsx @@ -1,3 +1,8 @@ +import { Loader2 } from 'lucide-react'; +import Link from 'next/link'; +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,17 +11,13 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import React, { useState } from 'react'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; -import { Dataset } from '@/lib/dataset/types'; -import { Input } from '../ui/input'; import { Label } from '@/components/ui/label'; -import Link from 'next/link'; -import { Loader2 } from 'lucide-react'; import { useProjectContext } from '@/contexts/project-context'; +import { Dataset } from '@/lib/dataset/types'; import { useToast } from '@/lib/hooks/use-toast'; +import { cn } from '@/lib/utils'; + +import { Input } from '../ui/input'; interface IndexDatasetDialogProps { datasetId: string; diff --git a/frontend/components/dataset/manual-add-datapoint-dialog.tsx b/frontend/components/dataset/manual-add-datapoint-dialog.tsx index 96057af9..24bd0d2b 100644 --- a/frontend/components/dataset/manual-add-datapoint-dialog.tsx +++ b/frontend/components/dataset/manual-add-datapoint-dialog.tsx @@ -1,3 +1,11 @@ +import { Loader2 } from 'lucide-react'; +import { useCallback, useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; + +import { useToast } from '../../lib/hooks/use-toast'; +import { Button } from '../ui/button'; +import CodeEditor from '../ui/code-editor'; import { Dialog, DialogContent, @@ -6,13 +14,6 @@ import { DialogTitle, DialogTrigger } from '../ui/dialog'; -import { useCallback, useState } from 'react'; - -import { Button } from '../ui/button'; -import CodeEditor from '../ui/code-editor'; -import { Loader2 } from 'lucide-react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useToast } from '../../lib/hooks/use-toast'; const DEFAULT_DATA = '{\n "data": {},\n "target": {}\n}'; diff --git a/frontend/components/dataset/unstructured-file-upload.tsx b/frontend/components/dataset/unstructured-file-upload.tsx index 65419b6d..cfc283c7 100644 --- a/frontend/components/dataset/unstructured-file-upload.tsx +++ b/frontend/components/dataset/unstructured-file-upload.tsx @@ -1,10 +1,10 @@ +import { Loader2 } from 'lucide-react'; import { useRef, useState } from 'react'; import { Button } from '@/components/ui/button'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; -import { uploadFile } from '@/lib/dataset/utils'; import { useProjectContext } from '@/contexts/project-context'; +import { uploadFile } from '@/lib/dataset/utils'; import { useToast } from '@/lib/hooks/use-toast'; interface UnstructuredFileUploadProps { diff --git a/frontend/components/datasets/create-dataset-dialog.tsx b/frontend/components/datasets/create-dataset-dialog.tsx index fa56d579..311d638c 100644 --- a/frontend/components/datasets/create-dataset-dialog.tsx +++ b/frontend/components/datasets/create-dataset-dialog.tsx @@ -1,3 +1,8 @@ +import { Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,15 +11,10 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { cn } from '@/lib/utils'; interface CreateDatasetDialogProps {} diff --git a/frontend/components/datasets/datasets.tsx b/frontend/components/datasets/datasets.tsx index 53e71fef..cd25a701 100644 --- a/frontend/components/datasets/datasets.tsx +++ b/frontend/components/datasets/datasets.tsx @@ -1,5 +1,12 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; +import { Loader2, Trash2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import useSWR from 'swr'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -9,24 +16,18 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Trash2 } from 'lucide-react'; -import { TableCell, TableRow } from '../ui/table'; +import { useProjectContext } from '@/contexts/project-context'; +import { Dataset } from '@/lib/dataset/types'; +import { useToast } from '@/lib/hooks/use-toast'; +import { PaginatedResponse } from '@/lib/types'; +import { swrFetcher } from '@/lib/utils'; -import { Button } from '@/components/ui/button'; import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import CreateDatasetDialog from './create-dataset-dialog'; -import { Dataset } from '@/lib/dataset/types'; import { DataTable } from '../ui/datatable'; import Header from '../ui/header'; import Mono from '../ui/mono'; -import { PaginatedResponse } from '@/lib/types'; -import { swrFetcher } from '@/lib/utils'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; -import useSWR from 'swr'; -import { useToast } from '@/lib/hooks/use-toast'; +import { TableCell, TableRow } from '../ui/table'; +import CreateDatasetDialog from './create-dataset-dialog'; export default function Datasets() { const { projectId } = useProjectContext(); diff --git a/frontend/components/datasets/update-dataset-dialog.tsx b/frontend/components/datasets/update-dataset-dialog.tsx index eece2386..7165d873 100644 --- a/frontend/components/datasets/update-dataset-dialog.tsx +++ b/frontend/components/datasets/update-dataset-dialog.tsx @@ -1,5 +1,9 @@ 'use client'; +import { Loader2, Pencil } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -8,15 +12,11 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Pencil } from 'lucide-react'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; -import { Dataset } from '@/lib/dataset/types'; import { DropdownMenuItem } from '@/components/ui/dropdown-menu'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { useState } from 'react'; +import { Dataset } from '@/lib/dataset/types'; +import { cn } from '@/lib/utils'; interface UpdateDatasetDialogProps { oldDataset: Dataset; diff --git a/frontend/components/evaluation/chart.tsx b/frontend/components/evaluation/chart.tsx index 2afa38b3..d8fba03c 100644 --- a/frontend/components/evaluation/chart.tsx +++ b/frontend/components/evaluation/chart.tsx @@ -1,17 +1,18 @@ +import { useEffect, useState } from 'react'; import { Bar, BarChart, CartesianGrid, XAxis, YAxis } from 'recharts'; + import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'; -import { useEffect, useState } from 'react'; - +import { useProjectContext } from '@/contexts/project-context'; import { BucketRow } from '@/lib/types'; import { cn } from '@/lib/utils'; + import { Label } from '../ui/label'; import { Skeleton } from '../ui/skeleton'; -import { useProjectContext } from '@/contexts/project-context'; const getTransformedData = ( data: {[scoreName: string]: BucketRow[]} diff --git a/frontend/components/evaluation/compare-chart.tsx b/frontend/components/evaluation/compare-chart.tsx index 2781a3ef..c2be89a4 100644 --- a/frontend/components/evaluation/compare-chart.tsx +++ b/frontend/components/evaluation/compare-chart.tsx @@ -1,16 +1,17 @@ import { Bar, BarChart, CartesianGrid, XAxis } from 'recharts'; +import useSWR from 'swr'; + import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'; +import { useProjectContext } from '@/contexts/project-context'; +import { BucketRow } from '@/lib/types'; import { cn, swrFetcher } from '@/lib/utils'; -import { BucketRow } from '@/lib/types'; import { Skeleton } from '../ui/skeleton'; -import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; const getTransformedData = (data: BucketRow[]) => data.map((row: BucketRow, index: number) => ({ diff --git a/frontend/components/evaluation/evaluation.tsx b/frontend/components/evaluation/evaluation.tsx index ff77df6c..df0e3add 100644 --- a/frontend/components/evaluation/evaluation.tsx +++ b/frontend/components/evaluation/evaluation.tsx @@ -1,9 +1,22 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; +import { ArrowRight } from 'lucide-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { Resizable } from 're-resizable'; +import { useEffect, useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; import { - EvaluationDatapointPreviewWithCompared, - EvaluationResultsInfo, - Evaluation as EvaluationType + Evaluation as EvaluationType, EvaluationDatapointPreviewWithCompared, EvaluationResultsInfo } from '@/lib/evaluation/types'; +import { mergeOriginalWithComparedDatapoints } from '@/lib/evaluation/utils'; +import { useToast } from '@/lib/hooks/use-toast'; + +import TraceView from '../traces/trace-view'; +import { Button } from '../ui/button'; +import { DataTable } from '../ui/datatable'; +import DownloadButton from '../ui/download-button'; +import Header from '../ui/header'; import { Select, SelectContent, @@ -11,23 +24,9 @@ import { SelectTrigger, SelectValue } from '../ui/select'; -import { useEffect, useState } from 'react'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - -import { ArrowRight } from 'lucide-react'; -import { Button } from '../ui/button'; import Chart from './chart'; -import { ColumnDef } from '@tanstack/react-table'; import CompareChart from './compare-chart'; -import { DataTable } from '../ui/datatable'; -import DownloadButton from '../ui/download-button'; -import Header from '../ui/header'; -import { mergeOriginalWithComparedDatapoints } from '@/lib/evaluation/utils'; -import { Resizable } from 're-resizable'; import ScoreCard from './score-card'; -import TraceView from '../traces/trace-view'; -import { useProjectContext } from '@/contexts/project-context'; -import { useToast } from '@/lib/hooks/use-toast'; const URL_QUERY_PARAMS = { COMPARE_EVAL_ID: 'comparedEvaluationId' diff --git a/frontend/components/evaluation/score-card.tsx b/frontend/components/evaluation/score-card.tsx index 824ef893..276a070c 100644 --- a/frontend/components/evaluation/score-card.tsx +++ b/frontend/components/evaluation/score-card.tsx @@ -1,11 +1,12 @@ -import { useEffect, useState } from 'react'; +import { ArrowRight } from 'lucide-react'; import { usePathname, useSearchParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import useSWR from 'swr'; -import { ArrowRight } from 'lucide-react'; -import { Skeleton } from '../ui/skeleton'; -import { swrFetcher } from '@/lib/utils'; import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; +import { swrFetcher } from '@/lib/utils'; + +import { Skeleton } from '../ui/skeleton'; const URL_QUERY_PARAMS = { COMPARE_EVAL_ID: 'comparedEvaluationId' diff --git a/frontend/components/evaluations/create-evaluation-dialog.tsx b/frontend/components/evaluations/create-evaluation-dialog.tsx index aaa41f8d..23870ed3 100644 --- a/frontend/components/evaluations/create-evaluation-dialog.tsx +++ b/frontend/components/evaluations/create-evaluation-dialog.tsx @@ -1,6 +1,10 @@ 'use client'; -import { cn, getLocalDevSessions, getLocalEnvVars } from '@/lib/utils'; +import { Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -9,18 +13,15 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; - -import { Button } from '@/components/ui/button'; -import DatasetSelect from '../ui/dataset-select'; -import { DisplayableGraph } from '@/lib/flow/types'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; +import { useProjectContext } from '@/contexts/project-context'; +import { DisplayableGraph } from '@/lib/flow/types'; +import { cn, getLocalDevSessions, getLocalEnvVars } from '@/lib/utils'; + +import DatasetSelect from '../ui/dataset-select'; import PipelineSelect from '../ui/pipeline-select'; import { Switch } from '../ui/switch'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; export default function CreateEvaluationDialog() { const { projectId } = useProjectContext(); diff --git a/frontend/components/evaluations/evaluations-groups-bar.tsx b/frontend/components/evaluations/evaluations-groups-bar.tsx index e98e250f..99233ec1 100644 --- a/frontend/components/evaluations/evaluations-groups-bar.tsx +++ b/frontend/components/evaluations/evaluations-groups-bar.tsx @@ -1,12 +1,14 @@ -import { useRouter, useSearchParams } from "next/navigation"; -import ClientTimestampFormatter from "../client-timestamp-formatter"; import { ColumnDef } from "@tanstack/react-table"; -import { DataTable } from "../ui/datatable"; -import { swrFetcher } from "@/lib/utils"; +import { useRouter, useSearchParams } from "next/navigation"; import { useEffect } from "react"; -import { useProjectContext } from "@/contexts/project-context"; import useSWR from "swr"; +import { useProjectContext } from "@/contexts/project-context"; +import { swrFetcher } from "@/lib/utils"; + +import ClientTimestampFormatter from "../client-timestamp-formatter"; +import { DataTable } from "../ui/datatable"; + export default function EvaluationsGroupsBar() { const { projectId } = useProjectContext(); diff --git a/frontend/components/evaluations/evaluations.tsx b/frontend/components/evaluations/evaluations.tsx index 6c287134..e0d8f9ad 100644 --- a/frontend/components/evaluations/evaluations.tsx +++ b/frontend/components/evaluations/evaluations.tsx @@ -1,5 +1,24 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; +import { Loader2, Trash2 } from 'lucide-react'; +import { useRouter, useSearchParams } from 'next/navigation'; +import { usePostHog } from 'posthog-js/react'; +import { useState } from 'react'; +import useSWR from 'swr'; + +import { useProjectContext } from '@/contexts/project-context'; +import { useUserContext } from '@/contexts/user-context'; +import { AggregationFunction } from '@/lib/clickhouse/utils'; +import { Evaluation } from '@/lib/evaluation/types'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; +import { useToast } from '@/lib/hooks/use-toast'; +import { PaginatedResponse } from '@/lib/types'; +import { swrFetcher } from '@/lib/utils'; + +import ClientTimestampFormatter from '../client-timestamp-formatter'; +import { Button } from '../ui/button'; +import { DataTable } from '../ui/datatable'; import { Dialog, DialogContent, @@ -9,29 +28,11 @@ import { DialogTitle, DialogTrigger, } from '../ui/dialog'; -import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { Loader2, Trash2 } from 'lucide-react'; -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'; -import { useRouter, useSearchParams } from 'next/navigation'; - -import { AggregationFunction } from '@/lib/clickhouse/utils'; -import { Button } from '../ui/button'; -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { DataTable } from '../ui/datatable'; -import { Evaluation } from '@/lib/evaluation/types'; -import EvaluationsGroupsBar from './evaluations-groups-bar'; import Header from '../ui/header'; import Mono from '../ui/mono'; -import { PaginatedResponse } from '@/lib/types'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../ui/select'; +import EvaluationsGroupsBar from './evaluations-groups-bar'; import ProgressionChart from './progression-chart'; -import { swrFetcher } from '@/lib/utils'; -import { usePostHog } from 'posthog-js/react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; -import useSWR from 'swr'; -import { useToast } from '@/lib/hooks/use-toast'; -import { useUserContext } from '@/contexts/user-context'; export default function Evaluations() { diff --git a/frontend/components/evaluations/page-placeholder.tsx b/frontend/components/evaluations/page-placeholder.tsx index 18c958ce..1e7d7656 100644 --- a/frontend/components/evaluations/page-placeholder.tsx +++ b/frontend/components/evaluations/page-placeholder.tsx @@ -1,12 +1,13 @@ 'use client'; +import { useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; import { PYTHON_INSTALL, TYPESCRIPT_INSTALL } from '@/lib/const'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import CodeHighlighter from '../ui/code-highlighter'; import Header from '../ui/header'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; export default function EvalsPagePlaceholder() { const { projectId } = useProjectContext(); diff --git a/frontend/components/evaluations/progression-chart.tsx b/frontend/components/evaluations/progression-chart.tsx index cecfb975..d1ce2553 100644 --- a/frontend/components/evaluations/progression-chart.tsx +++ b/frontend/components/evaluations/progression-chart.tsx @@ -1,15 +1,17 @@ -import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts"; -import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "../ui/chart"; +import { Minus } from "lucide-react"; +import { useSearchParams } from "next/navigation"; import { useEffect, useMemo, useState } from "react"; +import { CartesianGrid, Line, LineChart, XAxis, YAxis } from "recharts"; +import useSWR from "swr"; + +import { useProjectContext } from "@/contexts/project-context"; import { AggregationFunction } from "@/lib/clickhouse/utils"; import { EvaluationTimeProgression } from "@/lib/evaluation/types"; +import { cn, formatTimestamp, swrFetcher } from "@/lib/utils"; + +import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from "../ui/chart"; import { Label } from "../ui/label"; -import { Minus } from "lucide-react"; import { Skeleton } from "../ui/skeleton"; -import { useProjectContext } from "@/contexts/project-context"; -import { useSearchParams } from "next/navigation"; -import useSWR from "swr"; -import { cn, formatTimestamp, swrFetcher } from "@/lib/utils"; interface ProgressionChartProps { className?: string; diff --git a/frontend/components/evaluator/evaluator-editor-dialog.tsx b/frontend/components/evaluator/evaluator-editor-dialog.tsx index e4e12501..5a8f8a42 100644 --- a/frontend/components/evaluator/evaluator-editor-dialog.tsx +++ b/frontend/components/evaluator/evaluator-editor-dialog.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { Dialog, DialogContent, @@ -6,11 +8,10 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; +import { Graph } from '@/lib/flow/graph'; import { LabelClass, Span } from '@/lib/traces/types'; import { EvaluatorEditor } from './evaluator-editor'; -import { Graph } from '@/lib/flow/graph'; -import React from 'react'; interface EvaluatorEditorDialogProps { span: Span; diff --git a/frontend/components/evaluator/evaluator-editor.tsx b/frontend/components/evaluator/evaluator-editor.tsx index ddc69efa..94417224 100644 --- a/frontend/components/evaluator/evaluator-editor.tsx +++ b/frontend/components/evaluator/evaluator-editor.tsx @@ -1,23 +1,24 @@ +import { Loader2, Play } from 'lucide-react'; +import { useEffect, useRef, useState } from 'react'; +import { v4 } from 'uuid'; + +import { useProjectContext } from '@/contexts/project-context'; +import { EventType } from '@/lib/events/types'; +import { Graph } from '@/lib/flow/graph'; import { CodeNode, LLMNode, NodeHandleType, NodeType, OutputNode } from '@/lib/flow/types'; import { createNodeData, renderNodeInput } from '@/lib/flow/utils'; +import { toast } from '@/lib/hooks/use-toast'; +import { LanguageModel } from '@/lib/pipeline/types'; import { LabelClass, Span } from '@/lib/traces/types'; -import { Loader2, Play } from 'lucide-react'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; -import { useEffect, useRef, useState } from 'react'; +import LanguageModelSelect from '../pipeline/nodes/components/model-select'; import { Button } from '../ui/button'; import CodeEditor from '../ui/code-editor'; import { DialogClose } from '../ui/dialog'; -import { EventType } from '@/lib/events/types'; import Formatter from '../ui/formatter'; -import { Graph } from '@/lib/flow/graph'; import { Label } from '../ui/label'; -import { LanguageModel } from '@/lib/pipeline/types'; -import LanguageModelSelect from '../pipeline/nodes/components/model-select'; import { ScrollArea } from '../ui/scroll-area'; -import { toast } from '@/lib/hooks/use-toast'; -import { useProjectContext } from '@/contexts/project-context'; -import { v4 } from 'uuid'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; interface AutoEvalsProps { span: Span; diff --git a/frontend/components/event/delete-event-template-dialog.tsx b/frontend/components/event/delete-event-template-dialog.tsx deleted file mode 100644 index 1c5d6039..00000000 --- a/frontend/components/event/delete-event-template-dialog.tsx +++ /dev/null @@ -1,77 +0,0 @@ -'use client'; - -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger -} from '@/components/ui/dialog'; - -import { Button } from '@/components/ui/button'; -import { EventTemplate } from '@/lib/events/types'; -import { Label } from '@/components/ui/label'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; - -interface DeleteEventTemplateProps { - defaultEventTemplate: EventTemplate; -} - -export default function DeleteEventTemplateDialog({ - defaultEventTemplate -}: DeleteEventTemplateProps) { - const { projectId } = useProjectContext(); - const router = useRouter(); - - const [isDialogOpen, setIsDialogOpen] = useState(false); - const [isLoading, setIsLoading] = useState(false); - - const deleteEventTemplate = async () => { - setIsLoading(true); - - const res = await fetch( - `/api/projects/${projectId}/event-templates/${defaultEventTemplate.id}`, - { - method: 'DELETE' - } - ); - - await res.text(); - - setIsLoading(false); - setIsDialogOpen(false); - router.push(`/project/${projectId}/event-templates`); - router.refresh(); - }; - - return ( - <> - - - - - - - Delete event {defaultEventTemplate.name} - - - - - - - - - ); -} diff --git a/frontend/components/event/edit-event-template-dialog.tsx b/frontend/components/event/edit-event-template-dialog.tsx deleted file mode 100644 index 1c45a6a2..00000000 --- a/frontend/components/event/edit-event-template-dialog.tsx +++ /dev/null @@ -1,122 +0,0 @@ -'use client'; -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger -} from '@/components/ui/dialog'; -import { EventTemplate, EventType } from '@/lib/events/types'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue -} from '../ui/select'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; - -interface EditEventTemplateProps { - defaultEventTemplate: EventTemplate; -} - -export default function EditEventTemplateDialog({ - defaultEventTemplate -}: EditEventTemplateProps) { - const { projectId } = useProjectContext(); - const router = useRouter(); - - const [isDialogOpen, setIsDialogOpen] = useState(false); - const [isLoading, setIsLoading] = useState(false); - - const name = defaultEventTemplate.name; - const [eventType, setEventType] = useState( - defaultEventTemplate.eventType - ); - - const updateEvent = async () => { - setIsLoading(true); - - const res = await fetch( - `/api/projects/${projectId}/event-templates/${defaultEventTemplate.id}`, - { - method: 'POST', - body: JSON.stringify({ - name, - eventType - }) - } - ); - - const data = await res.json(); - - setIsLoading(false); - setIsDialogOpen(false); - setEventType(data.eventType); - router.refresh(); - }; - - const isReady = () => eventType && name.length > 0; - - return ( - <> - - - - - - - Edit event - -
- - - - -
- - - -
-
- - ); -} diff --git a/frontend/components/event/event-view.tsx b/frontend/components/event/event-view.tsx deleted file mode 100644 index 7c0f54ca..00000000 --- a/frontend/components/event/event-view.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import { convertToLocalTimeWithMillis, swrFetcher } from '@/lib/utils'; - -import { Button } from '../ui/button'; -import { ChevronsRight } from 'lucide-react'; -import { Event } from '@/lib/events/types'; -import Formatter from '../ui/formatter'; -import { Label } from '../ui/label'; -import Mono from '../ui/mono'; -import MonoWithCopy from '../ui/mono-with-copy'; -import { ScrollArea } from '../ui/scroll-area'; -import { Span } from '@/lib/traces/types'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import useSWR from 'swr'; - -interface EventViewProps { - onClose: () => void; - event: Event; -} - -export default function EventView({ onClose, event }: EventViewProps) { - const { projectId } = useProjectContext(); - const { data: span, isLoading } = useSWR( - `/api/projects/${projectId}/spans/${event.spanId}`, - swrFetcher - ); - const traceId = span?.traceId; - const router = useRouter(); - - return ( - -
-
- -
Event
- {event.id} -
-
-
-
- - - {`${new Date(event.timestamp).toLocaleDateString()} ` + - convertToLocalTimeWithMillis(event.timestamp)} - -
- -
-
-

{event.templateName}

- - {event.templateEventType} - -
- - - -
-
-
- ); -} diff --git a/frontend/components/event/event.tsx b/frontend/components/event/event.tsx deleted file mode 100644 index cb3a6035..00000000 --- a/frontend/components/event/event.tsx +++ /dev/null @@ -1,325 +0,0 @@ -'use client'; - -import { CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts'; -import { - ChartConfig, - ChartContainer, - ChartTooltip, - ChartTooltipContent -} from '@/components/ui/chart'; -import { Event, EventTemplate } from '@/lib/events/types'; -import { useEffect, useState } from 'react'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { DataTable } from '../ui/datatable'; -import DateRangeFilter from '../ui/date-range-filter'; -import EventView from './event-view'; -import { formatTimestampFromSeconds } from '@/lib/utils'; -import Header from '../ui/header'; -import { Label } from '../ui/label'; -import { PaginatedGetResponseWithProjectPresenceFlag } from '@/lib/types'; -import { Resizable } from 're-resizable'; -import { useProjectContext } from '@/contexts/project-context'; - -// TODO: add refresh button on realtime updates. See components/traces/traces-table-traces-view.tsx for an example. - -const getEvents = async ( - projectId: string, - templateId: string, - pageNumber: number, - pageSize: number, - filter: string | string[] | undefined, - pastHours: string | null, - startDate: string | null | undefined, - endDate: string | null | undefined -): Promise> => { - let url = `/api/projects/${projectId}/event-templates/${templateId}/events?pageNumber=${pageNumber}&pageSize=${pageSize}`; - if (pastHours !== null) { - url += `&pastHours=${pastHours}`; - } - if (startDate != null) { - url += `&startDate=${startDate}`; - } - if (endDate != null) { - url += `&endDate=${endDate}`; - } - if (typeof filter === 'string') { - url += `&filter=${encodeURIComponent(filter)}`; - } else if (Array.isArray(filter)) { - const filters = encodeURIComponent(`[${filter.toString()}]`); - url += `&filter=${filters}`; - } - const res = await fetch(url, { - method: 'GET', - headers: { - 'Content-Type': 'application/json' - }, - cache: 'no-cache' - }); - return (await res.json()) as PaginatedGetResponseWithProjectPresenceFlag; -}; - -interface EventProps { - eventTemplate: EventTemplate; - metrics: { [key: string]: { [key: string]: number }[] }; -} - -export default function EventComponent({ eventTemplate, metrics }: EventProps) { - const router = useRouter(); - const pathName = usePathname(); - const searchParams = new URLSearchParams(useSearchParams().toString()); - const { projectId } = useProjectContext(); - - const parseNumericSearchParam = ( - key: string, - defaultValue: number - ): number => { - const param = searchParams.get(key); - if (Array.isArray(param)) { - return defaultValue; - } - const parsed = param ? parseInt(param as string) : defaultValue; - return isNaN(parsed) ? defaultValue : parsed; - }; - - const pageNumber = parseNumericSearchParam('pageNumber', 0); - const pageSize = Math.max(parseNumericSearchParam('pageSize', 50), 1); - const filter = searchParams.get('filter'); - const startDate = searchParams.get('startDate'); - const endDate = searchParams.get('endDate'); - const pastHours = searchParams.get('pastHours'); - - const [isSidePanelOpen, setIsSidePanelOpen] = useState(false); - const [selectedEvent, setSelectedEvent] = useState(null); - const [events, setEvents] = useState(undefined); - const [totalCount, setTotalCount] = useState(0); // including the filtering - const [anyInProject, setAnyInProject] = useState(true); - - const pageCount = Math.ceil(totalCount / pageSize); - - const handleRowClick = (row: Event) => { - setSelectedEvent(row); - setIsSidePanelOpen(true); - }; - - useEffect(() => { - setEvents(undefined); - - if (!pastHours && !startDate && !endDate) { - const sp = new URLSearchParams(); - for (const [key, value] of Object.entries(searchParams)) { - if (key !== 'pastHours') { - sp.set(key, value as string); - } - } - sp.set('pastHours', '24'); - router.push(`${pathName}?${sp.toString()}`); - return; - } - - getEvents( - projectId, - eventTemplate.id, - pageNumber, - pageSize, - filter ?? undefined, - pastHours, - startDate, - endDate - ) - .then((result) => { - console.log(result); - setEvents(result.items); - setTotalCount(result.totalCount); - }) - .catch((err) => { - console.error(err); - }); - }, [ - projectId, - pageNumber, - pageSize, - filter, - pastHours, - startDate, - endDate, - eventTemplate.id - ]); - - const columns: ColumnDef[] = [ - { - accessorKey: 'id', - header: 'ID', - id: 'id' - }, - { - header: 'Occurrence', - accessorKey: 'createdAt', - id: 'created_at', - cell: (row) => ( - - ) - }, - { - accessorFn: (row) => row.spanId.replace(/^00000000-0000-0000-/g, ''), - header: 'Span ID', - id: 'span_id' - }, - { - accessorKey: 'value', - header: 'Value', - id: 'value' - } - ]; - - return ( -
-
-
-
-
-

{eventTemplate.name}

-
-
- -
-
-
-
- -
-
-
- handleRowClick(row.original)} - paginated - focusedRowId={selectedEvent?.id} - manualPagination - pageCount={pageCount} - defaultPageNumber={pageNumber} - defaultPageSize={pageSize} - onPageChange={(pageNumber, pageSize) => { - searchParams.set('pageNumber', pageNumber.toString()); - searchParams.set('pageSize', pageSize.toString()); - router.push(`${pathName}?${searchParams.toString()}`); - }} - totalItemsCount={totalCount} - > - - -
- {isSidePanelOpen && ( -
- -
- { - // searchParams.delete('selectedid'); - // router.push(`${pathName}?${searchParams.toString()}`); - setIsSidePanelOpen(false); - // setExpandedid(null); - }} - event={selectedEvent!} - /> -
-
-
- )} -
-
- ); -} - -interface CustomChartProps { - data: any; - title: string; - xAxisKey: string; - yAxisKey: string; - className?: string; -} - -function CustomChart({ - data, - title, - xAxisKey, - yAxisKey, - className -}: CustomChartProps) { - const chartConfig = { - [xAxisKey]: { - color: 'hsl(var(--chart-2))' - } - } satisfies ChartConfig; - - return ( -
-
- {title} -
-
- - - - - - - formatTimestampFromSeconds(p[0].payload[xAxisKey]) - } - /> - } - /> - - - -
-
- ); -} diff --git a/frontend/components/events/create-event-template-dialog.tsx b/frontend/components/events/create-event-template-dialog.tsx deleted file mode 100644 index 3e3ec057..00000000 --- a/frontend/components/events/create-event-template-dialog.tsx +++ /dev/null @@ -1,115 +0,0 @@ -'use client'; - -import { - Dialog, - DialogContent, - DialogFooter, - DialogHeader, - DialogTitle, - DialogTrigger -} from '@/components/ui/dialog'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue -} from '../ui/select'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; -import { EventType } from '@/lib/events/types'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; - -export default function CreateEventTemplateDialog() { - const { projectId } = useProjectContext(); - const router = useRouter(); - - const [isDialogOpen, setIsDialogOpen] = useState(false); - const [isLoading, setIsLoading] = useState(false); - - const [name, setName] = useState(''); - const [eventType, setEventType] = useState(null); - - const createNewEvent = async () => { - setIsLoading(true); - - const res = await fetch(`/api/projects/${projectId}/event-templates`, { - method: 'POST', - body: JSON.stringify({ - name, - eventType - }) - }); - - await res.json(); - - setIsLoading(false); - setIsDialogOpen(false); - setName(''); - router.refresh(); - }; - - const isReady = () => eventType && name.length > 0; - - return ( - <> - - - - - - - Create new event - -
- - setName(e.target.value)} - /> - - -
- - - -
-
- - ); -} diff --git a/frontend/components/events/events.tsx b/frontend/components/events/events.tsx deleted file mode 100644 index 29aa7dc5..00000000 --- a/frontend/components/events/events.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client'; - -import { Feature, isFeatureEnabled } from '@/lib/features/features'; - -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { DataTable } from '../ui/datatable'; -import { EventTemplate } from '@/lib/events/types'; -import Header from '../ui/header'; -import Mono from '../ui/mono'; -import { usePostHog } from 'posthog-js/react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useUserContext } from '@/contexts/user-context'; - -export interface EventsProps { - events: EventTemplate[]; -} - -export default function Events({ events }: EventsProps) { - const { projectId } = useProjectContext(); - const router = useRouter(); - const posthog = usePostHog(); - const { email } = useUserContext(); - - if (isFeatureEnabled(Feature.POSTHOG)) { - posthog.identify(email); - } - - const columns: ColumnDef[] = [ - { - accessorKey: 'id', - cell: (row) => {String(row.getValue())}, - header: 'ID', - size: 300 - }, - { - accessorKey: 'name', - header: 'Name' - }, - { - header: 'Last occurrence', - accessorKey: 'latestTimestamp', - cell: (row) => ( - - ) - }, - { - header: 'Type', - accessorKey: 'eventType' - } - ]; - - return ( -
-
-
-

- Events -

-
-
- { - router.push(`/project/${projectId}/events/${row.original.id}`); - }} - /> -
-
- ); -} diff --git a/frontend/components/landing/footer.tsx b/frontend/components/landing/footer.tsx index 61e0a0e3..18b102d4 100644 --- a/frontend/components/landing/footer.tsx +++ b/frontend/components/landing/footer.tsx @@ -5,7 +5,7 @@ import noise from '@/assets/landing/noise2.jpeg'; export default function Footer() { return (
-
+
diff --git a/frontend/components/landing/landing-header.tsx b/frontend/components/landing/landing-header.tsx index 7ca6a102..78d5b5d5 100644 --- a/frontend/components/landing/landing-header.tsx +++ b/frontend/components/landing/landing-header.tsx @@ -1,13 +1,14 @@ 'use client'; import { Menu, X } from 'lucide-react'; -import { useEffect, useState } from 'react'; - -import { Button } from '../ui/button'; -import { cn } from '@/lib/utils'; import Image from 'next/image'; import Link from 'next/link'; +import { useEffect, useState } from 'react'; + import logo from '@/assets/logo/logo.svg'; +import { cn } from '@/lib/utils'; + +import { Button } from '../ui/button'; interface LandingHeaderProps { hasSession: boolean; @@ -30,7 +31,7 @@ export default function LandingHeader({ hasSession }: LandingHeaderProps) { return ( <>
-
+
logo @@ -64,12 +65,12 @@ export default function LandingHeader({ hasSession }: LandingHeaderProps) { Blog - - GitHub {starCount && `★ ${starCount}`} - Discord + + GitHub {starCount && `★ ${starCount}`} + + ))} +
+
+

{selectedSection.title}

+

+ {selectedSection.description} +

+ {selectedSection.docsLink && ( +
+ + + +
+ )} +
-
- - { - sections.map((section, i) => ( - - {section.title} - - )) - } - - { - sections.map((section, i) => ( - -
-
-

- {section.title} -

-

- {section.description} -

- {section.docsLink && ( -
- - Read more about {section.title.toLowerCase()} - -
- )} -
-
- {section.codeExample && ( - - )} -
-
-
- )) - } +
+
-
- { - sections.map((section, i) => ( - -
- {section.title} -
-
- )) - } +
+ {selectedSection.title}
- +
-
+
@@ -274,23 +335,16 @@ function TracingCard() { return (
-
- -
-

Zero-overhead observability

-

- All traces are sent in the background via gRPC with minimal overhead. - Tracing of text and image models is supported, audio models are coming soon. +

LLM observability that just works

+

+ Add 2 lines of code to trace all LLM calls and traces. + Traces are sent in the background via gRPC with minimal performance and latency overhead.

@@ -315,21 +369,14 @@ function TracingCard() { function DatasetCard() { return (
-
- -
-

Datasets

-

+

Datasets

+

You can build datasets from your traces, and use them in evaluations, fine-tuning and prompt engineering.

@@ -343,7 +390,7 @@ function DatasetCard() { Dataset visualization
@@ -355,22 +402,16 @@ function DatasetCard() { function EvaluationsCard() { return (
-
- -
-

Online evaluations

-

- You can setup LLM-as-a-judge or Python script evaluators to run on each received span. Evaluators label spans, which is more scalable than human labeling, and especially helpful for smaller teams. +

Online evaluations

+

+ Setup LLM or Python online evaluators to process each received span. + Evaluators automatically label spans, which is more scalable than human labeling.

@@ -395,28 +436,19 @@ function EvaluationsCard() { function PromptChainsCard({ className }: { className?: string }) { return (
-
- -
-

Prompt chain management

-

- Laminar lets you go beyond a single prompt. You can build and host - complex chains, including mixtures of agents or self-reflecting LLM - pipelines. +

Serverless LLM pipelines

+

+ Our pipeline builder is an incredible prototyping tool. It lets you quickly build and iterate on both simple prompts and complex LLM chains. After that

- Build LLM chains + Deploy LLM pipeline
@@ -437,21 +469,14 @@ function PromptChainsCard({ className }: { className?: string }) { function SelfHostCard() { return (
-
- -
-

Fully open-source

-

+

Fully open-source

+

Laminar is fully open-source and easy to self-host. Get started with just a few commands.

- Learn about self-hosting + Self-host Laminar
@@ -472,3 +497,49 @@ docker compose up -d`}
); } + +function CodeTabs({ pythonCode, tsCode }: { pythonCode?: string; tsCode?: string }) { + const [selectedLang, setSelectedLang] = useState('typescript'); + + return ( +
+
+ + +
+ +
+ {selectedLang === 'python' && ( + + )} + {selectedLang === 'typescript' && ( + + )} +
+
+ ); +} diff --git a/frontend/components/landing/pricing-card.tsx b/frontend/components/landing/pricing-card.tsx index 71171a64..34480da4 100644 --- a/frontend/components/landing/pricing-card.tsx +++ b/frontend/components/landing/pricing-card.tsx @@ -1,7 +1,8 @@ import { Check } from 'lucide-react'; -import { cn } from '@/lib/utils'; import React from 'react'; +import { cn } from '@/lib/utils'; + export interface PricingCardProps { className?: string; title: string; diff --git a/frontend/components/landing/pricing.tsx b/frontend/components/landing/pricing.tsx index e8e2000b..a879221e 100644 --- a/frontend/components/landing/pricing.tsx +++ b/frontend/components/landing/pricing.tsx @@ -1,21 +1,22 @@ 'use client'; +import Image from 'next/image'; +import Link from 'next/link'; +import { usePostHog } from 'posthog-js/react'; +import { useState } from "react"; + +import noise from '@/assets/landing/noise1.jpeg'; +import Footer from '@/components/landing/footer'; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion'; - import { Button } from '@/components/ui/button'; -import Footer from '@/components/landing/footer'; -import Image from 'next/image'; -import Link from 'next/link'; -import noise from '@/assets/landing/noise1.jpeg'; -import PricingCard from './pricing-card'; import { Slider } from "@/components/ui/slider"; -import { usePostHog } from 'posthog-js/react'; -import { useState } from "react"; + +import PricingCard from './pricing-card'; export default function Pricing() { const posthog = usePostHog(); diff --git a/frontend/components/onboarding/create-first-workspace-and-project.tsx b/frontend/components/onboarding/create-first-workspace-and-project.tsx index 4b07f4c1..e6aaa248 100644 --- a/frontend/components/onboarding/create-first-workspace-and-project.tsx +++ b/frontend/components/onboarding/create-first-workspace-and-project.tsx @@ -1,12 +1,12 @@ 'use client'; +import { Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; import React, { useState } from 'react'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; -import { useRouter } from 'next/navigation'; import { WorkspaceWithProjects } from '@/lib/workspaces/types'; interface CreateFirstWorkspaceAndProjectProps { diff --git a/frontend/components/onboarding/onboarding-header.tsx b/frontend/components/onboarding/onboarding-header.tsx index bcf0cc84..acb875f8 100644 --- a/frontend/components/onboarding/onboarding-header.tsx +++ b/frontend/components/onboarding/onboarding-header.tsx @@ -1,8 +1,9 @@ import { ChevronRight } from 'lucide-react'; -import icon from '@/assets/logo/icon.svg'; import Image from 'next/image'; import Link from 'next/link'; +import icon from '@/assets/logo/icon.svg'; + interface OnboardingHeaderProps { } export default function OnboardingHeader({ }: OnboardingHeaderProps) { diff --git a/frontend/components/pipeline/commit-button.tsx b/frontend/components/pipeline/commit-button.tsx index 0abcb4fc..b0e18c3b 100644 --- a/frontend/components/pipeline/commit-button.tsx +++ b/frontend/components/pipeline/commit-button.tsx @@ -1,3 +1,7 @@ +import { Loader2, PlusCircle } from 'lucide-react'; +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,17 +10,14 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; +import { useProjectContext } from '@/contexts/project-context'; +import useStore from '@/lib/flow/store'; +import { PipelineVersionInfo } from '@/lib/pipeline/types'; import { GRAPH_VALID, validateGraph } from '@/lib/pipeline/utils'; -import { Loader2, PlusCircle } from 'lucide-react'; -import React, { useState } from 'react'; -import { Button } from '@/components/ui/button'; +import { useToast } from '../../lib/hooks/use-toast'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { PipelineVersionInfo } from '@/lib/pipeline/types'; -import { useProjectContext } from '@/contexts/project-context'; -import useStore from '@/lib/flow/store'; -import { useToast } from '../../lib/hooks/use-toast'; interface CommitButtonProps { selectedPipelineVersion: PipelineVersionInfo; diff --git a/frontend/components/pipeline/delete-version-button.tsx b/frontend/components/pipeline/delete-version-button.tsx index ea8647f1..5fe13d79 100644 --- a/frontend/components/pipeline/delete-version-button.tsx +++ b/frontend/components/pipeline/delete-version-button.tsx @@ -1,3 +1,7 @@ +import { Loader2, MoreVertical, Trash2 } from 'lucide-react'; +import { useContext, useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -12,15 +16,11 @@ import { DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; -import { Loader2, MoreVertical, Trash2 } from 'lucide-react'; -import { useContext, useState } from 'react'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { PipelineVersionInfo } from '@/lib/pipeline/types'; import { ProjectContext } from '@/contexts/project-context'; +import { PipelineVersionInfo } from '@/lib/pipeline/types'; +import { cn } from '@/lib/utils'; interface DeletePipelineVersionButtonProps { selectedPipelineVersion: PipelineVersionInfo; diff --git a/frontend/components/pipeline/deploy-button.tsx b/frontend/components/pipeline/deploy-button.tsx index b33104df..0e9c9dac 100644 --- a/frontend/components/pipeline/deploy-button.tsx +++ b/frontend/components/pipeline/deploy-button.tsx @@ -1,3 +1,7 @@ +import { Loader2, Rocket } from 'lucide-react'; +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,19 +10,16 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { getLocalDevSessions, getLocalEnvVars } from '@/lib/utils'; +import { useProjectContext } from '@/contexts/project-context'; +import useStore from '@/lib/flow/store'; +import { PipelineVersionInfo } from '@/lib/pipeline/types'; import { GRAPH_VALID, validateGraph } from '@/lib/pipeline/utils'; -import { Loader2, Rocket } from 'lucide-react'; -import React, { useState } from 'react'; +import { getLocalDevSessions, getLocalEnvVars } from '@/lib/utils'; -import { Button } from '@/components/ui/button'; +import { useToast } from '../../lib/hooks/use-toast'; import EndpointSelect from '../ui/endpoint-select'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { PipelineVersionInfo } from '@/lib/pipeline/types'; -import { useProjectContext } from '@/contexts/project-context'; -import useStore from '@/lib/flow/store'; -import { useToast } from '../../lib/hooks/use-toast'; const CREATE_NEW_ENDPOINT_ID = 'create-new-endpoint'; diff --git a/frontend/components/pipeline/flow.tsx b/frontend/components/pipeline/flow.tsx index 14eaa58d..87c03ea5 100644 --- a/frontend/components/pipeline/flow.tsx +++ b/frontend/components/pipeline/flow.tsx @@ -10,17 +10,17 @@ import ReactFlow, { type Node, updateEdge } from 'reactflow'; +import { v4 as uuidv4 } from 'uuid'; - +import { useFlowContext } from '@/contexts/pipeline-version-context'; +import useStore from '@/lib/flow/store'; +import { NodeType } from '@/lib/flow/types'; import { createNodeData } from '@/lib/flow/utils'; + import CustomEdge from './nodes/components/custom-edge'; import GenericNodeComponent from './nodes/generic-node'; import InputNodeComponent from './nodes/input-node'; -import { NodeType } from '@/lib/flow/types'; import OutputNodeComponent from './nodes/output-node'; -import { useFlowContext } from '@/contexts/pipeline-version-context'; -import useStore from '@/lib/flow/store'; -import { v4 as uuidv4 } from 'uuid'; const nodeTypes = { [NodeType.INPUT]: InputNodeComponent, diff --git a/frontend/components/pipeline/fork-button.tsx b/frontend/components/pipeline/fork-button.tsx index 020abe74..39ee9e62 100644 --- a/frontend/components/pipeline/fork-button.tsx +++ b/frontend/components/pipeline/fork-button.tsx @@ -1,3 +1,8 @@ +import { GitFork, Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,16 +11,12 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { GitFork, Loader2 } from 'lucide-react'; -import React, { useState } from 'react'; +import { useProjectContext } from '@/contexts/project-context'; +import { PipelineVersionInfo } from '@/lib/pipeline/types'; -import { Button } from '@/components/ui/button'; +import { useToast } from '../../lib/hooks/use-toast'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { PipelineVersionInfo } from '@/lib/pipeline/types'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useToast } from '../../lib/hooks/use-toast'; interface ForkButtonProps { defaultNewPipelineName: string; diff --git a/frontend/components/pipeline/metadata-card.tsx b/frontend/components/pipeline/metadata-card.tsx index 47a03b52..840958b9 100644 --- a/frontend/components/pipeline/metadata-card.tsx +++ b/frontend/components/pipeline/metadata-card.tsx @@ -1,7 +1,8 @@ -import { Card } from '../ui/card'; import { getDurationString } from '@/lib/flow/utils'; -import { Label } from '../ui/label'; import { RunTrace } from '@/lib/traces/types'; + +import { Card } from '../ui/card'; +import { Label } from '../ui/label'; import StatusLabel from '../ui/status-label'; export default function MetadataCard({ runTrace }: { runTrace: RunTrace }) { diff --git a/frontend/components/pipeline/nodes/code-node.tsx b/frontend/components/pipeline/nodes/code-node.tsx index 22b3d66b..0f8f8e5c 100644 --- a/frontend/components/pipeline/nodes/code-node.tsx +++ b/frontend/components/pipeline/nodes/code-node.tsx @@ -1,9 +1,11 @@ -import { CodeNode } from '@/lib/flow/types'; -import GenericNodeComponent from './generic-node'; import { memo } from 'react'; -import useStore from '@/lib/flow/store'; import { useUpdateNodeInternals } from 'reactflow'; +import useStore from '@/lib/flow/store'; +import { CodeNode } from '@/lib/flow/types'; + +import GenericNodeComponent from './generic-node'; + const pythonFunctionPattern = /def\s+(\w+)\s*\(([^)]*)\)/; const compareArrays = (array1: string[], array2: string[]): boolean => diff --git a/frontend/components/pipeline/nodes/code-sandbox.tsx b/frontend/components/pipeline/nodes/code-sandbox.tsx index 6a929c3f..f5178d83 100644 --- a/frontend/components/pipeline/nodes/code-sandbox.tsx +++ b/frontend/components/pipeline/nodes/code-sandbox.tsx @@ -1,8 +1,9 @@ -import { CodeSandboxNode, NodeHandleType } from '@/lib/flow/types'; +import { v4 } from 'uuid'; + import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import useStore from '@/lib/flow/store'; -import { v4 } from 'uuid'; +import { CodeSandboxNode, NodeHandleType } from '@/lib/flow/types'; export default function CodeSandboxNodeComponent({ data diff --git a/frontend/components/pipeline/nodes/code.tsx b/frontend/components/pipeline/nodes/code.tsx index 92d761bf..4338bec3 100644 --- a/frontend/components/pipeline/nodes/code.tsx +++ b/frontend/components/pipeline/nodes/code.tsx @@ -1,9 +1,9 @@ -import { CodeNode, GenericNodeHandle, NodeHandleType } from '@/lib/flow/types'; - import Editor from '@monaco-editor/react'; -import useStore from '@/lib/flow/store'; import { v4 } from 'uuid'; +import useStore from '@/lib/flow/store'; +import { CodeNode, GenericNodeHandle, NodeHandleType } from '@/lib/flow/types'; + export const DEFAULT_CODE = `""" Implement the function "main" in this module. diff --git a/frontend/components/pipeline/nodes/components/custom-edge.tsx b/frontend/components/pipeline/nodes/components/custom-edge.tsx index d9dc8e8b..92807db1 100644 --- a/frontend/components/pipeline/nodes/components/custom-edge.tsx +++ b/frontend/components/pipeline/nodes/components/custom-edge.tsx @@ -1,3 +1,5 @@ +import { X } from 'lucide-react'; +import React from 'react'; import { BaseEdge, EdgeLabelRenderer, @@ -5,11 +7,9 @@ import { getBezierPath } from 'reactflow'; -import { cn } from '@/lib/utils'; -import React from 'react'; import { useFlowContext } from '@/contexts/pipeline-version-context'; import useStore from '@/lib/flow/store'; -import { X } from 'lucide-react'; +import { cn } from '@/lib/utils'; const onEdgeClick = (evt: any, id: any) => { evt.stopPropagation(); diff --git a/frontend/components/pipeline/nodes/components/model-select.tsx b/frontend/components/pipeline/nodes/components/model-select.tsx index e2f7b741..3cd58df9 100644 --- a/frontend/components/pipeline/nodes/components/model-select.tsx +++ b/frontend/components/pipeline/nodes/components/model-select.tsx @@ -1,5 +1,9 @@ import { Check, ChevronsUpDown } from 'lucide-react'; -import { cn, swrFetcher } from '@/lib/utils'; +import Link from 'next/link'; +import { useEffect, useState } from 'react'; +import useSWR from 'swr'; + +import { Button } from '@/components/ui/button'; import { Command, CommandEmpty, @@ -7,20 +11,16 @@ import { CommandInput, CommandItem } from '@/components/ui/command'; -import { LANGUAGE_MODELS, LanguageModel } from '@/lib/pipeline/types'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { useEffect, useState } from 'react'; - -import { Button } from '@/components/ui/button'; -import Link from 'next/link'; -import { ProviderApiKey } from '@/lib/settings/types'; import { ScrollArea } from '@/components/ui/scroll-area'; import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; +import { LANGUAGE_MODELS, LanguageModel } from '@/lib/pipeline/types'; +import { ProviderApiKey } from '@/lib/settings/types'; +import { cn, swrFetcher } from '@/lib/utils'; interface ModelSelectProps { modelId: string; diff --git a/frontend/components/pipeline/nodes/components/node-preview.tsx b/frontend/components/pipeline/nodes/components/node-preview.tsx index b16c021d..6857a063 100644 --- a/frontend/components/pipeline/nodes/components/node-preview.tsx +++ b/frontend/components/pipeline/nodes/components/node-preview.tsx @@ -2,11 +2,11 @@ import { StaticImageData, StaticImport } from 'next/dist/shared/lib/get-img-props'; - import Image from 'next/image'; +import { useState } from 'react'; + import { Label } from '@/components/ui/label'; import { Skeleton } from '@/components/ui/skeleton'; -import { useState } from 'react'; export interface NodePreviewProps { name: string; diff --git a/frontend/components/pipeline/nodes/components/semantic-cache-fields.tsx b/frontend/components/pipeline/nodes/components/semantic-cache-fields.tsx index 5713a98d..90aa1ada 100644 --- a/frontend/components/pipeline/nodes/components/semantic-cache-fields.tsx +++ b/frontend/components/pipeline/nodes/components/semantic-cache-fields.tsx @@ -1,18 +1,18 @@ -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger -} from '@/components/ui/tooltip'; - import { AlertTriangle } from 'lucide-react'; + import DatasetSelect from '@/components/ui/dataset-select'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { LLMNode } from '@/lib/flow/types'; import { Slider } from '@/components/ui/slider'; import { Switch } from '@/components/ui/switch'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '@/components/ui/tooltip'; import useStore from '@/lib/flow/store'; +import { LLMNode } from '@/lib/flow/types'; interface SemanticCacheFieldsProps { data: LLMNode; diff --git a/frontend/components/pipeline/nodes/components/structured-output-fields.tsx b/frontend/components/pipeline/nodes/components/structured-output-fields.tsx index fcc07675..954d6d80 100644 --- a/frontend/components/pipeline/nodes/components/structured-output-fields.tsx +++ b/frontend/components/pipeline/nodes/components/structured-output-fields.tsx @@ -1,3 +1,9 @@ +import Link from 'next/link'; +import { useEffect, useState } from 'react'; + +import Ide from '@/components/ui/ide'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; import { Select, SelectContent, @@ -5,15 +11,9 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; -import { useEffect, useState } from 'react'; - -import Ide from '@/components/ui/ide'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import Link from 'next/link'; -import { LLMNode } from '@/lib/flow/types'; import { Switch } from '@/components/ui/switch'; import useStore from '@/lib/flow/store'; +import { LLMNode } from '@/lib/flow/types'; interface StructuredOutputFieldsProps { className?: string; diff --git a/frontend/components/pipeline/nodes/components/templated-text-area.tsx b/frontend/components/pipeline/nodes/components/templated-text-area.tsx index 2c2f39d3..a1f59007 100644 --- a/frontend/components/pipeline/nodes/components/templated-text-area.tsx +++ b/frontend/components/pipeline/nodes/components/templated-text-area.tsx @@ -1,11 +1,11 @@ -import { GenericNodeHandle, NodeHandleType } from '@/lib/flow/types'; import { useCallback, useRef } from 'react'; +import { IAceEditorProps } from 'react-ace'; +import { v4 } from 'uuid'; import DefaultTextarea from '@/components/ui/default-textarea'; -import { IAceEditorProps } from 'react-ace'; import Ide from '@/components/ui/ide'; import { Label } from '@/components/ui/label'; -import { v4 } from 'uuid'; +import { GenericNodeHandle, NodeHandleType } from '@/lib/flow/types'; interface TemplatedTextAreaProps extends IAceEditorProps { defaultInputs: Map; diff --git a/frontend/components/pipeline/nodes/components/unify-model-select.tsx b/frontend/components/pipeline/nodes/components/unify-model-select.tsx index 06a17684..41af5914 100644 --- a/frontend/components/pipeline/nodes/components/unify-model-select.tsx +++ b/frontend/components/pipeline/nodes/components/unify-model-select.tsx @@ -1,3 +1,9 @@ +import { X } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; import { Select, SelectContent, @@ -7,12 +13,6 @@ import { } from '@/components/ui/select'; import { UnifyNode, UnifyThreshold } from '@/lib/flow/types'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { useState } from 'react'; -import { X } from 'lucide-react'; - const TYPE_MANUALLY = '– type manually –'; const selectableModelNames = [ 'claude-3-opus', diff --git a/frontend/components/pipeline/nodes/error-node.tsx b/frontend/components/pipeline/nodes/error-node.tsx index fb31127e..188667bd 100644 --- a/frontend/components/pipeline/nodes/error-node.tsx +++ b/frontend/components/pipeline/nodes/error-node.tsx @@ -1,6 +1,8 @@ +import { memo } from 'react'; + import { ErrorNode } from '@/lib/flow/types'; + import GenericNodeComponent from './generic-node'; -import { memo } from 'react'; const ErrorNodeComponent = ({ id, data }: { id: string; data: ErrorNode }) => ( <> diff --git a/frontend/components/pipeline/nodes/extractor-node.tsx b/frontend/components/pipeline/nodes/extractor-node.tsx index cc770b83..dbaad991 100644 --- a/frontend/components/pipeline/nodes/extractor-node.tsx +++ b/frontend/components/pipeline/nodes/extractor-node.tsx @@ -1,8 +1,9 @@ -import { ExtractorNode } from '@/lib/flow/types'; +import { memo } from 'react'; + import Ide from '@/components/ui/ide'; import { Label } from '@/components/ui/label'; -import { memo } from 'react'; import useStore from '@/lib/flow/store'; +import { ExtractorNode } from '@/lib/flow/types'; const ExtractorNodeComponent = ({ data }: { data: ExtractorNode }) => { const updateNodeData = useStore((state) => state.updateNodeData); diff --git a/frontend/components/pipeline/nodes/format-validator-node.tsx b/frontend/components/pipeline/nodes/format-validator-node.tsx index 10f5cd9f..cd79344f 100644 --- a/frontend/components/pipeline/nodes/format-validator-node.tsx +++ b/frontend/components/pipeline/nodes/format-validator-node.tsx @@ -1,7 +1,7 @@ -import { FormatValidatorNode } from '@/lib/flow/types'; import Ide from '@/components/ui/ide'; import { Label } from '@/components/ui/label'; import useStore from '@/lib/flow/store'; +import { FormatValidatorNode } from '@/lib/flow/types'; const FormatValidatorNodeComponent = ({ data diff --git a/frontend/components/pipeline/nodes/function-node.tsx b/frontend/components/pipeline/nodes/function-node.tsx index 902b7d1a..57c33b5a 100644 --- a/frontend/components/pipeline/nodes/function-node.tsx +++ b/frontend/components/pipeline/nodes/function-node.tsx @@ -1,12 +1,12 @@ -import { FunctionNode, NodeHandleType } from '@/lib/flow/types'; import { Plus, Trash2Icon } from 'lucide-react'; +import { memo } from 'react'; +import { v4 as uuidv4 } from 'uuid'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { memo } from 'react'; import useStore from '@/lib/flow/store'; -import { v4 as uuidv4 } from 'uuid'; +import { FunctionNode, NodeHandleType } from '@/lib/flow/types'; const FunctionNodeComponent = ({ data }: { data: FunctionNode }) => { const updateNodeData = useStore((state) => state.updateNodeData); diff --git a/frontend/components/pipeline/nodes/generic-node.tsx b/frontend/components/pipeline/nodes/generic-node.tsx index 189a1eda..ca020d62 100644 --- a/frontend/components/pipeline/nodes/generic-node.tsx +++ b/frontend/components/pipeline/nodes/generic-node.tsx @@ -1,3 +1,5 @@ +import { Info, Settings, Trash } from 'lucide-react'; +import { memo, useCallback, useEffect, useState } from 'react'; import { type Connection, Edge, @@ -7,17 +9,15 @@ import { useOnSelectionChange, useUpdateNodeInternals } from 'reactflow'; -import { createNodeData,NODE_TYPE_TO_DOCS } from '@/lib/flow/utils'; -import { type GenericNode, NodeHandleType, NodeType } from '@/lib/flow/types'; -import { Info, Settings, Trash } from 'lucide-react'; -import { memo, useCallback, useEffect, useState } from 'react'; import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { useFlowContext } from '@/contexts/pipeline-version-context'; import useStore from '@/lib/flow/store'; +import { type GenericNode, NodeHandleType, NodeType } from '@/lib/flow/types'; +import { createNodeData,NODE_TYPE_TO_DOCS } from '@/lib/flow/utils'; +import { cn } from '@/lib/utils'; interface GenericNodeComponentProps { id: string; diff --git a/frontend/components/pipeline/nodes/input-node.tsx b/frontend/components/pipeline/nodes/input-node.tsx index 723086e5..fa777d48 100644 --- a/frontend/components/pipeline/nodes/input-node.tsx +++ b/frontend/components/pipeline/nodes/input-node.tsx @@ -1,4 +1,6 @@ -import { type InputNode, NodeHandleType } from '@/lib/flow/types'; +import { memo } from 'react'; + +import { Label } from '@/components/ui/label'; import { Select, SelectContent, @@ -6,11 +8,10 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; +import useStore from '@/lib/flow/store'; +import { type InputNode, NodeHandleType } from '@/lib/flow/types'; import GenericNodeComponent from './generic-node'; -import { Label } from '@/components/ui/label'; -import { memo } from 'react'; -import useStore from '@/lib/flow/store'; const InputNodeComponent = ({ id, data }: { id: string; data: InputNode }) => { const { updateNodeData, dropEdgeForHandle } = useStore((state) => state); diff --git a/frontend/components/pipeline/nodes/json-extractor-node.tsx b/frontend/components/pipeline/nodes/json-extractor-node.tsx index e31e9240..bb24a98f 100644 --- a/frontend/components/pipeline/nodes/json-extractor-node.tsx +++ b/frontend/components/pipeline/nodes/json-extractor-node.tsx @@ -1,9 +1,10 @@ -import Ide from '@/components/ui/ide'; -import { JsonExtractorNode } from '@/lib/flow/types'; -import { Label } from '@/components/ui/label'; import Link from 'next/link'; import { memo } from 'react'; + +import Ide from '@/components/ui/ide'; +import { Label } from '@/components/ui/label'; import useStore from '@/lib/flow/store'; +import { JsonExtractorNode } from '@/lib/flow/types'; const JsonExtractorNodeComponent = ({ data }: { data: JsonExtractorNode }) => { const updateNodeData = useStore((state) => state.updateNodeData); diff --git a/frontend/components/pipeline/nodes/llm.tsx b/frontend/components/pipeline/nodes/llm.tsx index 0091a4ce..787dd87f 100644 --- a/frontend/components/pipeline/nodes/llm.tsx +++ b/frontend/components/pipeline/nodes/llm.tsx @@ -1,16 +1,16 @@ -import { GenericNodeHandle, LLMNode, NodeHandleType } from '@/lib/flow/types'; import { useEffect, useState } from 'react'; +import { v4 } from 'uuid'; import Ide from '@/components/ui/ide'; import { Label } from '@/components/ui/label'; -import LanguageModelSelect from './components/model-select'; -import { PROVIDERS } from '@/lib/pipeline/types'; -import StructuredOutputFields from './components/structured-output-fields'; import { Switch } from '@/components/ui/switch'; -import TemplatedTextArea from './components/templated-text-area'; import useStore from '@/lib/flow/store'; +import { GenericNodeHandle, LLMNode, NodeHandleType } from '@/lib/flow/types'; +import { PROVIDERS } from '@/lib/pipeline/types'; -import { v4 } from 'uuid'; +import LanguageModelSelect from './components/model-select'; +import StructuredOutputFields from './components/structured-output-fields'; +import TemplatedTextArea from './components/templated-text-area'; export default function LLM({ data, diff --git a/frontend/components/pipeline/nodes/map-node.tsx b/frontend/components/pipeline/nodes/map-node.tsx index b9c71c51..e5c8bdf3 100644 --- a/frontend/components/pipeline/nodes/map-node.tsx +++ b/frontend/components/pipeline/nodes/map-node.tsx @@ -1,12 +1,11 @@ +import { Label } from '@/components/ui/label'; +import PipelineSelect from '@/components/ui/pipeline-select'; +import useStore from '@/lib/flow/store'; import { MapNode, RunnableGraph } from '@/lib/flow/types'; -import { Label } from '@/components/ui/label'; -import PipelineSelect from '@/components/ui/pipeline-select'; -import useStore from '@/lib/flow/store'; - export default function MapNodeComponent({ data }: { data: MapNode }) { const updateNodeData = useStore((state) => state.updateNodeData); const dropEdgeForHandle = useStore((state) => state.dropEdgeForHandle); diff --git a/frontend/components/pipeline/nodes/output-node.tsx b/frontend/components/pipeline/nodes/output-node.tsx index c7518a51..8ff2b631 100644 --- a/frontend/components/pipeline/nodes/output-node.tsx +++ b/frontend/components/pipeline/nodes/output-node.tsx @@ -1,3 +1,6 @@ +import { memo } from 'react'; + +import { Label } from '@/components/ui/label'; import { Select, SelectContent, @@ -5,13 +8,11 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; - import { EventType } from '@/lib/events/types'; -import GenericNodeComponent from './generic-node'; -import { Label } from '@/components/ui/label'; -import { memo } from 'react'; -import { type OutputNode } from '@/lib/flow/types'; import useStore from '@/lib/flow/store'; +import { type OutputNode } from '@/lib/flow/types'; + +import GenericNodeComponent from './generic-node'; function capitalizeFirstLetter(s: string) { return s.charAt(0).toUpperCase() + s.slice(1); diff --git a/frontend/components/pipeline/nodes/semantic-search-node.tsx b/frontend/components/pipeline/nodes/semantic-search-node.tsx index 58337e0e..79c27cab 100644 --- a/frontend/components/pipeline/nodes/semantic-search-node.tsx +++ b/frontend/components/pipeline/nodes/semantic-search-node.tsx @@ -1,4 +1,10 @@ import { Database, X } from 'lucide-react'; +import Link from 'next/link'; +import { memo, useState } from 'react'; + +import { Button } from '@/components/ui/button'; +import DatasetSelect from '@/components/ui/dataset-select'; +import DefaultTextarea from '@/components/ui/default-textarea'; import { Dialog, DialogContent, @@ -7,19 +13,13 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { memo, useState } from 'react'; - -import { Button } from '@/components/ui/button'; -import { Dataset } from '@/lib/dataset/types'; -import DatasetSelect from '@/components/ui/dataset-select'; -import DefaultTextarea from '@/components/ui/default-textarea'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import Link from 'next/link'; -import { type SemanticSearchNode } from '@/lib/flow/types'; import { Slider } from '@/components/ui/slider'; import { useProjectContext } from '@/contexts/project-context'; +import { Dataset } from '@/lib/dataset/types'; import useStore from '@/lib/flow/store'; +import { type SemanticSearchNode } from '@/lib/flow/types'; const SemanticSearchNodeComponent = ({ data diff --git a/frontend/components/pipeline/nodes/semantic-switch-node.tsx b/frontend/components/pipeline/nodes/semantic-switch-node.tsx index 774717ff..3978094d 100644 --- a/frontend/components/pipeline/nodes/semantic-switch-node.tsx +++ b/frontend/components/pipeline/nodes/semantic-switch-node.tsx @@ -1,11 +1,11 @@ -import { NodeHandleType, SemanticSwitchNode } from '@/lib/flow/types'; +import { X } from 'lucide-react'; +import { v4 } from 'uuid'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import useStore from '@/lib/flow/store'; -import { v4 } from 'uuid'; -import { X } from 'lucide-react'; +import { NodeHandleType, SemanticSwitchNode } from '@/lib/flow/types'; export default function SemanticSwitchNodeComponent({ data diff --git a/frontend/components/pipeline/nodes/string-template-node.tsx b/frontend/components/pipeline/nodes/string-template-node.tsx index 34394f89..9f9e6b0c 100644 --- a/frontend/components/pipeline/nodes/string-template-node.tsx +++ b/frontend/components/pipeline/nodes/string-template-node.tsx @@ -1,10 +1,11 @@ +import { Label } from '@/components/ui/label'; +import useStore from '@/lib/flow/store'; import { type GenericNodeHandle, type StringTemplateNode } from '@/lib/flow/types'; -import { Label } from '@/components/ui/label'; + import TemplatedTextArea from './components/templated-text-area'; -import useStore from '@/lib/flow/store'; const StringTemplateNodeComponent = ({ data diff --git a/frontend/components/pipeline/nodes/subpipeline-node.tsx b/frontend/components/pipeline/nodes/subpipeline-node.tsx index d5ad7c76..2dbc28d4 100644 --- a/frontend/components/pipeline/nodes/subpipeline-node.tsx +++ b/frontend/components/pipeline/nodes/subpipeline-node.tsx @@ -1,3 +1,6 @@ +import { Label } from '@/components/ui/label'; +import PipelineSelect from '@/components/ui/pipeline-select'; +import useStore from '@/lib/flow/store'; import { GenericNodeHandle, InputNode, @@ -5,9 +8,6 @@ import { RunnableGraph, SubpipelineNode } from '@/lib/flow/types'; -import { Label } from '@/components/ui/label'; -import PipelineSelect from '@/components/ui/pipeline-select'; -import useStore from '@/lib/flow/store'; export default function SubpipelineNodeComponent({ data diff --git a/frontend/components/pipeline/nodes/switch-node.tsx b/frontend/components/pipeline/nodes/switch-node.tsx index 1abfdbfc..b5c1a1b2 100644 --- a/frontend/components/pipeline/nodes/switch-node.tsx +++ b/frontend/components/pipeline/nodes/switch-node.tsx @@ -1,11 +1,11 @@ -import { NodeHandleType, RouterNode } from '@/lib/flow/types'; +import { v4 } from 'uuid'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Switch } from '@/components/ui/switch'; import useStore from '@/lib/flow/store'; -import { v4 } from 'uuid'; +import { NodeHandleType, RouterNode } from '@/lib/flow/types'; export default function SwitchNodeComponent({ data }: { data: RouterNode }) { const { updateNodeData, dropEdgeForHandle } = useStore((state) => state); diff --git a/frontend/components/pipeline/nodes/unify-node.tsx b/frontend/components/pipeline/nodes/unify-node.tsx index 5f408da7..e54a6825 100644 --- a/frontend/components/pipeline/nodes/unify-node.tsx +++ b/frontend/components/pipeline/nodes/unify-node.tsx @@ -1,18 +1,18 @@ +import { memo, useEffect, useState } from 'react'; +import { v4 } from 'uuid'; + +import IdeJson from '@/components/ui/ide-json'; +import { Label } from '@/components/ui/label'; +import { Switch } from '@/components/ui/switch'; +import useStore from '@/lib/flow/store'; import { GenericNodeHandle, NodeHandleType, type UnifyNode } from '@/lib/flow/types'; -import { memo, useEffect, useState } from 'react'; - -import IdeJson from '@/components/ui/ide-json'; -import { Label } from '@/components/ui/label'; -import { Switch } from '@/components/ui/switch'; import TemplatedTextArea from './components/templated-text-area'; import UnifyModelSelect from './components/unify-model-select'; -import useStore from '@/lib/flow/store'; -import { v4 } from 'uuid'; const UnifyNodeComponent = ({ data }: { data: UnifyNode }) => { const [prompt, setSystemInstruction] = useState(data.prompt); diff --git a/frontend/components/pipeline/nodes/web-search-node.tsx b/frontend/components/pipeline/nodes/web-search-node.tsx index dbd5f1ea..e1eb0f24 100644 --- a/frontend/components/pipeline/nodes/web-search-node.tsx +++ b/frontend/components/pipeline/nodes/web-search-node.tsx @@ -1,7 +1,8 @@ +import { memo } from 'react'; + import DefaultTextarea from '@/components/ui/default-textarea'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { memo } from 'react'; import { Switch } from '@/components/ui/switch'; import useStore from '@/lib/flow/store'; import { WebSearchNode } from '@/lib/flow/types'; diff --git a/frontend/components/pipeline/nodes/zenguard-node.tsx b/frontend/components/pipeline/nodes/zenguard-node.tsx index 9cbd7bcc..82c2d252 100644 --- a/frontend/components/pipeline/nodes/zenguard-node.tsx +++ b/frontend/components/pipeline/nodes/zenguard-node.tsx @@ -1,12 +1,13 @@ -import { DetectorType, ZenguardNode } from '@/lib/flow/types'; +import { memo } from 'react'; import { Button } from '@/components/ui/button'; import { Checkbox } from '@/components/ui/checkbox'; -import GenericNodeComponent from './generic-node'; import { IconZenguard } from '@/components/ui/icons'; import { Label } from '@/components/ui/label'; -import { memo } from 'react'; import useStore from '@/lib/flow/store'; +import { DetectorType, ZenguardNode } from '@/lib/flow/types'; + +import GenericNodeComponent from './generic-node'; const DETECTOR_TYPE_TO_DISPLAY_NAME_MAP: Record = { diff --git a/frontend/components/pipeline/overwrite-workshop-button.tsx b/frontend/components/pipeline/overwrite-workshop-button.tsx index 65b84ac8..6edb0cf6 100644 --- a/frontend/components/pipeline/overwrite-workshop-button.tsx +++ b/frontend/components/pipeline/overwrite-workshop-button.tsx @@ -1,3 +1,8 @@ +import { Loader2 } from 'lucide-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,15 +11,11 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import React, { useState } from 'react'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - -import { Button } from '@/components/ui/button'; -import { Label } from '../ui/label'; -import { Loader2 } from 'lucide-react'; -import { PipelineVersionInfo } from '@/lib/pipeline/types'; import { useProjectContext } from '@/contexts/project-context'; +import { PipelineVersionInfo } from '@/lib/pipeline/types'; + import { useToast } from '../../lib/hooks/use-toast'; +import { Label } from '../ui/label'; interface OverwriteWorkshopButtonProps { workshopVersionId: string; diff --git a/frontend/components/pipeline/pipeline-bottom-panel.tsx b/frontend/components/pipeline/pipeline-bottom-panel.tsx index 05a1e0bf..e6942ad8 100644 --- a/frontend/components/pipeline/pipeline-bottom-panel.tsx +++ b/frontend/components/pipeline/pipeline-bottom-panel.tsx @@ -1,11 +1,12 @@ +import { useState } from 'react'; +import { ImperativePanelHandle } from 'react-resizable-panels'; + import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { PipelineVersion } from '@/lib/pipeline/types'; -import { ImperativePanelHandle } from 'react-resizable-panels'; +import { Skeleton } from '../ui/skeleton'; import PipelineHistory from './pipeline-history'; import PipelineOutputs from './pipeline-outputs'; -import { PipelineVersion } from '@/lib/pipeline/types'; -import { Skeleton } from '../ui/skeleton'; -import { useState } from 'react'; interface PipelineBottomPanelProps { pipelineVersion: PipelineVersion; diff --git a/frontend/components/pipeline/pipeline-env.tsx b/frontend/components/pipeline/pipeline-env.tsx index c0760a8c..45b31d0a 100644 --- a/frontend/components/pipeline/pipeline-env.tsx +++ b/frontend/components/pipeline/pipeline-env.tsx @@ -1,19 +1,19 @@ +import { LockKeyhole } from 'lucide-react'; +import { useEffect, useRef, useState } from 'react'; + +import { ENV_VAR_TO_ISSUER_URL } from '@/lib/env/utils'; +import { Graph } from '@/lib/flow/graph'; +import useStore from '@/lib/flow/store'; import { cn, deleteLocalEnvVar, getLocalEnvVars, setLocalEnvVar } from '@/lib/utils'; -import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; -import { useEffect, useRef, useState } from 'react'; - import { Button } from '../ui/button'; -import { ENV_VAR_TO_ISSUER_URL } from '@/lib/env/utils'; -import { Graph } from '@/lib/flow/graph'; import { InputPassword } from '../ui/input-password'; -import { LockKeyhole } from 'lucide-react'; -import useStore from '@/lib/flow/store'; +import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; interface PipelineEnvProps { projectId: string; diff --git a/frontend/components/pipeline/pipeline-header.tsx b/frontend/components/pipeline/pipeline-header.tsx index c25e4ad2..bfbd6dd9 100644 --- a/frontend/components/pipeline/pipeline-header.tsx +++ b/frontend/components/pipeline/pipeline-header.tsx @@ -1,10 +1,7 @@ import { GitCommitVertical, PanelLeft, PanelRight } from 'lucide-react'; -import { - Pipeline, - PipelineVersion, - PipelineVersionInfo -} from '@/lib/pipeline/types'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; import React, { useEffect, useState } from 'react'; + import { Select, SelectContent, @@ -14,18 +11,22 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - +import PresenceUserImage from '@/components/user/presence-user-image'; +import { useProjectContext } from '@/contexts/project-context'; +import { + Pipeline, + PipelineVersion, + PipelineVersionInfo +} from '@/lib/pipeline/types'; +import { PresenceUser } from '@/lib/user/types'; import { cn } from '@/lib/utils'; + +import { Skeleton } from '../ui/skeleton'; import CommitButton from './commit-button'; import ForkButton from './fork-button'; import OverwriteWorkshopButton from './overwrite-workshop-button'; -import { PresenceUser } from '@/lib/user/types'; -import PresenceUserImage from '@/components/user/presence-user-image'; import SetTargetVersionButton from './target-version'; -import { Skeleton } from '../ui/skeleton'; import UseApi from './use-api'; -import { useProjectContext } from '@/contexts/project-context'; const getWorkshopVersionId = (pipelineVersions: PipelineVersionInfo[]) => pipelineVersions.filter((pv) => pv.pipelineType === 'WORKSHOP')[0].id; diff --git a/frontend/components/pipeline/pipeline-history.tsx b/frontend/components/pipeline/pipeline-history.tsx index fca5ed77..c9934ca7 100644 --- a/frontend/components/pipeline/pipeline-history.tsx +++ b/frontend/components/pipeline/pipeline-history.tsx @@ -1,17 +1,18 @@ +import { ColumnDef } from '@tanstack/react-table'; +import { useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { PipelineVersion } from '@/lib/pipeline/types'; +import { RunTrace, TracePreview } from '@/lib/traces/types'; + +import ClientTimestampFormatter from '../client-timestamp-formatter'; import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '../ui/resizable'; -import { RunTrace, TracePreview } from '@/lib/traces/types'; - -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { PipelineVersion } from '@/lib/pipeline/types'; import { Skeleton } from '../ui/skeleton'; import StatusLabel from '../ui/status-label'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; export const TRACE_COLUMNS: ColumnDef[] = [ { diff --git a/frontend/components/pipeline/pipeline-input.tsx b/frontend/components/pipeline/pipeline-input.tsx index f1dd9a35..ace67276 100644 --- a/frontend/components/pipeline/pipeline-input.tsx +++ b/frontend/components/pipeline/pipeline-input.tsx @@ -1,10 +1,11 @@ +import { NodeHandleType } from '@/lib/flow/types'; +import { InputVariable } from '@/lib/pipeline/types'; import { ChatMessage } from '@/lib/types'; + import DefaultTextarea from '../ui/default-textarea'; import EditableChat from '../ui/editable-chat'; import EditableStringList from '../ui/editable-string-list'; -import { InputVariable } from '@/lib/pipeline/types'; import { Label } from '../ui/label'; -import { NodeHandleType } from '@/lib/flow/types'; interface PipelineTraceProps { onInputsChange: (inputs: InputVariable[]) => void; diff --git a/frontend/components/pipeline/pipeline-outputs.tsx b/frontend/components/pipeline/pipeline-outputs.tsx index 7544b8d9..c28c96d0 100644 --- a/frontend/components/pipeline/pipeline-outputs.tsx +++ b/frontend/components/pipeline/pipeline-outputs.tsx @@ -1,31 +1,32 @@ +import { + createParser, + type ParsedEvent, + type ReconnectInterval +} from 'eventsource-parser'; +import { useCallback, useEffect, useRef, useState } from 'react'; +import { v4 } from 'uuid'; + +import { useProjectContext } from '@/contexts/project-context'; +import useStore from '@/lib/flow/store'; +import { NodeInput, NodeType } from '@/lib/flow/types'; +import { filterRunRequiredEnvVars } from '@/lib/flow/utils'; +import eventEmitter from '@/lib/pipeline/eventEmitter'; import { BreakpointChunk, GraphMessage, NodeStreamChunk, PipelineVersion } from '@/lib/pipeline/types'; -import { - createParser, - type ParsedEvent, - type ReconnectInterval -} from 'eventsource-parser'; -import { getLocalDevSessions, getLocalEnvVars } from '@/lib/utils'; import { GRAPH_VALID, validateGraph, validateInputs } from '@/lib/pipeline/utils'; -import { NodeInput, NodeType } from '@/lib/flow/types'; -import { useCallback, useEffect, useRef, useState } from 'react'; - -import eventEmitter from '@/lib/pipeline/eventEmitter'; -import { filterRunRequiredEnvVars } from '@/lib/flow/utils'; import { RunTrace } from '@/lib/traces/types'; -import StreamTrace from './stream-trace'; -import { useProjectContext } from '@/contexts/project-context'; -import useStore from '@/lib/flow/store'; +import { getLocalDevSessions, getLocalEnvVars } from '@/lib/utils'; + import { useToast } from '../../lib/hooks/use-toast'; -import { v4 } from 'uuid'; +import StreamTrace from './stream-trace'; export type StreamMessage = { id: string; diff --git a/frontend/components/pipeline/pipeline-sheet.tsx b/frontend/components/pipeline/pipeline-sheet.tsx index f0af9157..40b31c80 100644 --- a/frontend/components/pipeline/pipeline-sheet.tsx +++ b/frontend/components/pipeline/pipeline-sheet.tsx @@ -1,3 +1,4 @@ +import useStore from '@/lib/flow/store'; import { CodeNode, GenericNode, @@ -11,17 +12,16 @@ import { WebSearchNode } from '@/lib/flow/types'; -import CodeNodeComponent from './nodes/code'; import { Input } from '../ui/input'; -import JsonExtractorNodeComponent from './nodes/json-extractor-node'; import { Label } from '../ui/label'; -import LLM from './nodes/llm'; import { ScrollArea } from '../ui/scroll-area'; +import CodeNodeComponent from './nodes/code'; +import JsonExtractorNodeComponent from './nodes/json-extractor-node'; +import LLM from './nodes/llm'; import SemanticSearchNodeComponent from './nodes/semantic-search-node'; import SemanticSwitchNodeComponent from './nodes/semantic-switch-node'; import StringTemplateNodeComponent from './nodes/string-template-node'; import SwitchNodeComponent from './nodes/switch-node'; -import useStore from '@/lib/flow/store'; import WebSearchNodeComponent from './nodes/web-search-node'; interface PipelineSheetProps { diff --git a/frontend/components/pipeline/pipeline-toolbar.tsx b/frontend/components/pipeline/pipeline-toolbar.tsx index 0c08a659..68dab483 100644 --- a/frontend/components/pipeline/pipeline-toolbar.tsx +++ b/frontend/components/pipeline/pipeline-toolbar.tsx @@ -1,21 +1,22 @@ +import { GripVertical, LogIn } from 'lucide-react'; +import { type DragEvent } from 'react'; + +import { NodeType } from '@/lib/flow/types'; +import { NODE_PREVIEWS, NODE_TYPE_TO_DOCS } from '@/lib/flow/utils'; + import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../ui/accordion'; -import { GripVertical, LogIn } from 'lucide-react'; -import { NODE_PREVIEWS, NODE_TYPE_TO_DOCS } from '@/lib/flow/utils'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip'; - -import { type DragEvent } from 'react'; import NodePreviewComponent from './nodes/components/node-preview'; -import { NodeType } from '@/lib/flow/types'; export default function Toolbar({ editable }: { editable: boolean }) { const onDragStart = ( diff --git a/frontend/components/pipeline/pipeline-trace.tsx b/frontend/components/pipeline/pipeline-trace.tsx index 21cc0d9e..67cec471 100644 --- a/frontend/components/pipeline/pipeline-trace.tsx +++ b/frontend/components/pipeline/pipeline-trace.tsx @@ -1,8 +1,10 @@ import { AiOutlineMinusCircle } from 'react-icons/ai'; -import PipelineInput from './pipeline-input'; -import { ScrollArea } from '../ui/scroll-area'; + import useStore from '@/lib/flow/store'; +import { ScrollArea } from '../ui/scroll-area'; +import PipelineInput from './pipeline-input'; + interface PipelineTraceProps {} export default function PipelineTrace({}: PipelineTraceProps) { diff --git a/frontend/components/pipeline/pipeline.tsx b/frontend/components/pipeline/pipeline.tsx index ffbd9197..4ce7f623 100644 --- a/frontend/components/pipeline/pipeline.tsx +++ b/frontend/components/pipeline/pipeline.tsx @@ -1,58 +1,58 @@ 'use client'; +import { createClient } from '@supabase/supabase-js'; +import { ChevronsRight, PlayIcon, StopCircle } from 'lucide-react'; +import { usePostHog } from 'posthog-js/react'; +import { useContext, useEffect, useMemo, useRef, useState } from 'react'; +import { ImperativePanelHandle } from 'react-resizable-panels'; +import { v4 as uuidv4 } from 'uuid'; import * as Y from 'yjs'; -import { ChevronsRight, PlayIcon, StopCircle } from 'lucide-react'; import { - cn, - convertAllStoredInputsToUnseen, - convertStoredInputToUnseen, - getStoredInputs, - setStoredInputs, - STORED_INPUTS_STATE_UNSEEN -} from '@/lib/utils'; + ResizableHandle, + ResizablePanel, + ResizablePanelGroup +} from '@/components/ui/resizable'; +import { FlowContextProvider } from '@/contexts/pipeline-version-context'; +import { ProjectContext } from '@/contexts/project-context'; +import { useUserContext } from '@/contexts/user-context'; +import { SUPABASE_ANON_KEY, SUPABASE_URL } from '@/lib/const'; import { Feature, isFeatureEnabled } from '@/lib/features/features'; +import { Graph } from '@/lib/flow/graph'; +import useStore from '@/lib/flow/store'; import { InputNode, NodeType } from '@/lib/flow/types'; +import { DEFAULT_INPUT_VALUE_FOR_HANDLE_TYPE } from '@/lib/flow/utils'; +import { usePrevious } from '@/lib/hooks/use-previous'; +import { useToast } from '@/lib/hooks/use-toast'; +import eventEmitter from '@/lib/pipeline/eventEmitter'; import { InputVariable, - PipelineExecutionMode, Pipeline as PipelineType, + PipelineExecutionMode, PipelineVersion } from '@/lib/pipeline/types'; +import { removeHashFromId } from '@/lib/pipeline/utils'; +import { PresenceUser } from '@/lib/user/types'; import { - ResizableHandle, - ResizablePanel, - ResizablePanelGroup -} from '@/components/ui/resizable'; -import { SUPABASE_ANON_KEY, SUPABASE_URL } from '@/lib/const'; -import { useContext, useEffect, useMemo, useRef, useState } from 'react'; + cn, + convertAllStoredInputsToUnseen, + convertStoredInputToUnseen, + getStoredInputs, + setStoredInputs, + STORED_INPUTS_STATE_UNSEEN +} from '@/lib/utils'; import { Button } from '../ui/button'; -import { createClient } from '@supabase/supabase-js'; -import { DEFAULT_INPUT_VALUE_FOR_HANDLE_TYPE } from '@/lib/flow/utils'; -import eventEmitter from '@/lib/pipeline/eventEmitter'; -import Flow from './flow'; -import { FlowContextProvider } from '@/contexts/pipeline-version-context'; -import { Graph } from '@/lib/flow/graph'; import Header from '../ui/header'; -import { ImperativePanelHandle } from 'react-resizable-panels'; import { Label } from '../ui/label'; -import PipelineBottomPanel from './pipeline-bottom-panel'; -import PipelineHeader from './pipeline-header'; -import PipelineSheet from './pipeline-sheet'; -import PipelineTrace from './pipeline-trace'; -import { PresenceUser } from '@/lib/user/types'; -import { ProjectContext } from '@/contexts/project-context'; -import { removeHashFromId } from '@/lib/pipeline/utils'; import { ScrollArea } from '../ui/scroll-area'; import { Skeleton } from '../ui/skeleton'; import { Switch } from '../ui/switch'; +import Flow from './flow'; +import PipelineBottomPanel from './pipeline-bottom-panel'; +import PipelineHeader from './pipeline-header'; +import PipelineSheet from './pipeline-sheet'; import Toolbar from './pipeline-toolbar'; -import { usePostHog } from 'posthog-js/react'; -import { usePrevious } from '@/lib/hooks/use-previous'; -import useStore from '@/lib/flow/store'; -import { useToast } from '@/lib/hooks/use-toast'; -import { useUserContext } from '@/contexts/user-context'; -import { v4 as uuidv4 } from 'uuid'; +import PipelineTrace from './pipeline-trace'; interface PipelineProps { pipeline: PipelineType; diff --git a/frontend/components/pipeline/stream-trace.tsx b/frontend/components/pipeline/stream-trace.tsx index f116e9b9..3fe8e04e 100644 --- a/frontend/components/pipeline/stream-trace.tsx +++ b/frontend/components/pipeline/stream-trace.tsx @@ -6,27 +6,28 @@ import { Loader2, Play } from 'lucide-react'; +import React, { useEffect, useState } from 'react'; +import { v4 } from 'uuid'; + +import useStore from '@/lib/flow/store'; import { ConditionValue, NodeType } from '@/lib/flow/types'; import { getDurationString, renderNodeInput } from '@/lib/flow/utils'; -import React, { useEffect, useState } from 'react'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; +import eventEmitter from '@/lib/pipeline/eventEmitter'; +import { GraphMessagePreview } from '@/lib/pipeline/types'; +import { RunTrace } from '@/lib/traces/types'; +import { cn } from '@/lib/utils'; import { Button } from '../ui/button'; -import { cn } from '@/lib/utils'; -import eventEmitter from '@/lib/pipeline/eventEmitter'; import Formatter from '../ui/formatter'; -import { GraphMessagePreview } from '@/lib/pipeline/types'; import { Label } from '../ui/label'; -import { RunTrace } from '@/lib/traces/types'; import { ScrollArea } from '../ui/scroll-area'; import { Skeleton } from '../ui/skeleton'; import StatusLabel from '../ui/status-label'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import { StreamMessage } from './pipeline-outputs'; -import useStore from '@/lib/flow/store'; -import { v4 } from 'uuid'; interface StreaTraceProps { streamMessages: StreamMessage[]; diff --git a/frontend/components/pipeline/target-version.tsx b/frontend/components/pipeline/target-version.tsx index 76ac9593..9fefffa1 100644 --- a/frontend/components/pipeline/target-version.tsx +++ b/frontend/components/pipeline/target-version.tsx @@ -1,3 +1,8 @@ +import { Loader2 } from 'lucide-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import React, { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,14 +11,10 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import React, { useState } from 'react'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - -import { Button } from '@/components/ui/button'; -import { Label } from '../ui/label'; -import { Loader2 } from 'lucide-react'; import { useProjectContext } from '@/contexts/project-context'; + import { useToast } from '../../lib/hooks/use-toast'; +import { Label } from '../ui/label'; interface SetTargetVersionButtonProps { pipelineId: string; diff --git a/frontend/components/pipeline/use-api.tsx b/frontend/components/pipeline/use-api.tsx index 17f151e2..5a4e6fcb 100644 --- a/frontend/components/pipeline/use-api.tsx +++ b/frontend/components/pipeline/use-api.tsx @@ -1,4 +1,6 @@ import { Code2, Copy } from 'lucide-react'; +import { useState } from 'react'; + import { Dialog, DialogContent, @@ -6,14 +8,13 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; +import { getRequiredEnvVars } from '@/lib/env/utils'; import { InputNode, NodeType, RunnableGraph } from '@/lib/flow/types'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; +import { getDefaultGraphInputs } from '@/lib/flow/utils'; import { Button } from '../ui/button'; import CodeHighlighter from '../ui/code-highlighter'; -import { getDefaultGraphInputs } from '@/lib/flow/utils'; -import { getRequiredEnvVars } from '@/lib/env/utils'; -import { useState } from 'react'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; interface UseApiProps { pipelineName: string; diff --git a/frontend/components/pipelines/create-pipeline-dialog.tsx b/frontend/components/pipelines/create-pipeline-dialog.tsx index c5367822..61f3b916 100644 --- a/frontend/components/pipelines/create-pipeline-dialog.tsx +++ b/frontend/components/pipelines/create-pipeline-dialog.tsx @@ -1,5 +1,10 @@ 'use client'; +import { Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -8,19 +13,15 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { useEffect, useState } from 'react'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; -import { Skeleton } from '../ui/skeleton'; -import { TemplateInfo } from '@/lib/pipeline/types'; -import TemplateSelect from './template-select'; import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; import { useToast } from '@/lib/hooks/use-toast'; +import { TemplateInfo } from '@/lib/pipeline/types'; +import { cn } from '@/lib/utils'; + +import { Skeleton } from '../ui/skeleton'; +import TemplateSelect from './template-select'; interface CreatePipelineDialogProps { onUpdate?: () => void; diff --git a/frontend/components/pipelines/pipelines.tsx b/frontend/components/pipelines/pipelines.tsx index 44d6da08..f3d1e53e 100644 --- a/frontend/components/pipelines/pipelines.tsx +++ b/frontend/components/pipelines/pipelines.tsx @@ -1,29 +1,30 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; +import { MoreVertical } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { usePostHog } from 'posthog-js/react'; +import useSWR from 'swr'; + +import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/components/ui/dropdown-menu'; +import { useProjectContext } from '@/contexts/project-context'; +import { useUserContext } from '@/contexts/user-context'; import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { TableCell, TableRow } from '../ui/table'; +import { Pipeline } from '@/lib/pipeline/types'; +import { swrFetcher } from '@/lib/utils'; -import { Button } from '@/components/ui/button'; import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { CreatePipelineDialog } from './create-pipeline-dialog'; import { DataTable } from '../ui/datatable'; import Header from '../ui/header'; -import { MoreVertical } from 'lucide-react'; -import { Pipeline } from '@/lib/pipeline/types'; -import { swrFetcher } from '@/lib/utils'; +import { TableCell, TableRow } from '../ui/table'; +import { CreatePipelineDialog } from './create-pipeline-dialog'; import { UpdatePipelineDialog } from './update-pipeline-dialog'; -import { usePostHog } from 'posthog-js/react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import useSWR from 'swr'; -import { useUserContext } from '@/contexts/user-context'; export default function Pipelines() { const { projectId } = useProjectContext(); diff --git a/frontend/components/pipelines/template-select.tsx b/frontend/components/pipelines/template-select.tsx index 5be500bc..5ad1cabe 100644 --- a/frontend/components/pipelines/template-select.tsx +++ b/frontend/components/pipelines/template-select.tsx @@ -1,7 +1,8 @@ -import { Card } from '../ui/card'; +import { TemplateInfo } from '@/lib/pipeline/types'; import { cn } from '@/lib/utils'; + +import { Card } from '../ui/card'; import { Label } from '../ui/label'; -import { TemplateInfo } from '@/lib/pipeline/types'; interface TemplateSelectProps { className?: string; diff --git a/frontend/components/pipelines/update-pipeline-dialog.tsx b/frontend/components/pipelines/update-pipeline-dialog.tsx index da0337a1..91ab7bf7 100644 --- a/frontend/components/pipelines/update-pipeline-dialog.tsx +++ b/frontend/components/pipelines/update-pipeline-dialog.tsx @@ -1,5 +1,9 @@ 'use client'; +import { Loader2, Pencil } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -8,16 +12,13 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Pencil } from 'lucide-react'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; -import { DropdownMenuItem } from '../ui/dropdown-menu'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Pipeline } from '@/lib/pipeline/types'; import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; +import { Pipeline } from '@/lib/pipeline/types'; +import { cn } from '@/lib/utils'; + +import { DropdownMenuItem } from '../ui/dropdown-menu'; interface UpdatePipelineDialogProps { oldPipeline: Pipeline; diff --git a/frontend/components/playground/playground.tsx b/frontend/components/playground/playground.tsx index be6541ca..9d541619 100644 --- a/frontend/components/playground/playground.tsx +++ b/frontend/components/playground/playground.tsx @@ -1,20 +1,21 @@ 'use client'; -import { ChatMessage, ChatMessageContent } from "@/lib/types"; -import { Graph, runGraph } from "@/lib/flow/graph"; -import { LLMNode, NodeHandleType, NodeType } from "@/lib/flow/types"; import { Loader2, PlayIcon } from "lucide-react"; import { useEffect, useState } from "react"; +import { v4 } from "uuid"; -import { Button } from "../ui/button"; +import { useProjectContext } from "@/contexts/project-context"; +import { Graph, runGraph } from "@/lib/flow/graph"; +import { LLMNode, NodeHandleType, NodeType } from "@/lib/flow/types"; import { createNodeData } from "@/lib/flow/utils"; +import { Playground as PlaygroundType } from "@/lib/playground/types"; +import { ChatMessage, ChatMessageContent } from "@/lib/types"; + +import LanguageModelSelect from "../pipeline/nodes/components/model-select"; +import { Button } from "../ui/button"; import EditableChat from "../ui/editable-chat"; import Formatter from "../ui/formatter"; import Header from "../ui/header"; -import LanguageModelSelect from "../pipeline/nodes/components/model-select"; -import { Playground as PlaygroundType } from "@/lib/playground/types"; import { ScrollArea } from "../ui/scroll-area"; -import { useProjectContext } from "@/contexts/project-context"; -import { v4 } from "uuid"; const renderText = (text: string, inputs: Record) => text.replace(/\{\{([^}]+)\}\}/g, (match, p1) => inputs[p1] || match); diff --git a/frontend/components/playgrounds/create-playground-dialog.tsx b/frontend/components/playgrounds/create-playground-dialog.tsx index 4aa58f3f..920dd8a2 100644 --- a/frontend/components/playgrounds/create-playground-dialog.tsx +++ b/frontend/components/playgrounds/create-playground-dialog.tsx @@ -1,3 +1,8 @@ +import { Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,16 +11,10 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; - - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { cn } from '@/lib/utils'; export default function CreatePlaygroundDialog() { const [newPlaygroundName, setNewPlaygroundName] = useState(''); diff --git a/frontend/components/playgrounds/playgrounds.tsx b/frontend/components/playgrounds/playgrounds.tsx index d32f2c96..44e4010a 100644 --- a/frontend/components/playgrounds/playgrounds.tsx +++ b/frontend/components/playgrounds/playgrounds.tsx @@ -1,23 +1,24 @@ 'use client'; -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'; +import { ColumnDef } from '@tanstack/react-table'; import { Loader2, Trash2 } from 'lucide-react'; -import { TableCell, TableRow } from '../ui/table'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import useSWR from 'swr'; import { Button } from '@/components/ui/button'; +import { useProjectContext } from '@/contexts/project-context'; +import { useToast } from '@/lib/hooks/use-toast'; +import { Playground } from '@/lib/playground/types'; +import { swrFetcher } from '@/lib/utils'; + import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import CreatePlaygroundDialog from './create-playground-dialog'; import { DataTable } from '../ui/datatable'; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'; import Header from '../ui/header'; import Mono from '../ui/mono'; -import { Playground } from '@/lib/playground/types'; -import { swrFetcher } from '@/lib/utils'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; -import useSWR from 'swr'; -import { useToast } from '@/lib/hooks/use-toast'; +import { TableCell, TableRow } from '../ui/table'; +import CreatePlaygroundDialog from './create-playground-dialog'; export default function Playgrounds() { const { projectId } = useProjectContext(); diff --git a/frontend/components/profile/profile.tsx b/frontend/components/profile/profile.tsx index b745484f..a95a3595 100644 --- a/frontend/components/profile/profile.tsx +++ b/frontend/components/profile/profile.tsx @@ -1,8 +1,9 @@ 'use client'; -import { Label } from '../ui/label'; import { useUserContext } from '@/contexts/user-context'; +import { Label } from '../ui/label'; + export default function Profile() { const user = useUserContext(); diff --git a/frontend/components/profile/usage.tsx b/frontend/components/profile/usage.tsx index 0742e356..95ad4bda 100644 --- a/frontend/components/profile/usage.tsx +++ b/frontend/components/profile/usage.tsx @@ -1,12 +1,14 @@ 'use client'; -import { Label } from '../ui/label'; -import { Skeleton } from '../ui/skeleton'; -import SubscriptionTierCard from './subscription-tier-card'; -import { swrFetcher } from '@/lib/utils'; import useSWR from 'swr'; + import { useUserContext } from '@/contexts/user-context'; +import { swrFetcher } from '@/lib/utils'; import { Workspace } from '@/lib/workspaces/types'; + +import { Label } from '../ui/label'; +import { Skeleton } from '../ui/skeleton'; +import SubscriptionTierCard from './subscription-tier-card'; import WorkspaceCards from './workspace-cards'; export default function Usage() { diff --git a/frontend/components/project/project-navbar-collapsed.tsx b/frontend/components/project/project-navbar-collapsed.tsx index 96db1c03..ac03a853 100644 --- a/frontend/components/project/project-navbar-collapsed.tsx +++ b/frontend/components/project/project-navbar-collapsed.tsx @@ -10,19 +10,20 @@ import { Rows4, Settings } from 'lucide-react'; +import Image from 'next/image'; +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; + +import logo from '@/assets/logo/icon.svg'; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; +import { cn } from '@/lib/utils'; import AvatarMenu from '../user/avatar-menu'; -import { cn } from '@/lib/utils'; -import Image from 'next/image'; -import Link from 'next/link'; -import logo from '@/assets/logo/icon.svg'; -import { usePathname } from 'next/navigation'; interface ProjectNavBarProps { projectId: string; diff --git a/frontend/components/project/project-navbar.tsx b/frontend/components/project/project-navbar.tsx index 1f08f1f6..8692c8f3 100644 --- a/frontend/components/project/project-navbar.tsx +++ b/frontend/components/project/project-navbar.tsx @@ -7,14 +7,15 @@ import { Rocket, Rows4 } from 'lucide-react'; - -import AvatarMenu from '../user/avatar-menu'; -import { cn } from '@/lib/utils'; import Image from 'next/image'; import Link from 'next/link'; -import logo from '@/assets/logo/laminar.svg'; import { usePathname } from 'next/navigation'; +import logo from '@/assets/logo/laminar.svg'; +import { cn } from '@/lib/utils'; + +import AvatarMenu from '../user/avatar-menu'; + interface ProjectNavBarProps { projectId: string; } diff --git a/frontend/components/project/usage-banner.tsx b/frontend/components/project/usage-banner.tsx index 783d955d..65e088d5 100644 --- a/frontend/components/project/usage-banner.tsx +++ b/frontend/components/project/usage-banner.tsx @@ -1,8 +1,9 @@ 'use client'; -import { Label } from '../ui/label'; import { useRouter } from 'next/navigation'; +import { Label } from '../ui/label'; + interface ProjectUsageBannerProps { workspaceId: string; spansThisMonth: number; diff --git a/frontend/components/projects/project-card.tsx b/frontend/components/projects/project-card.tsx index 34372e46..802a0018 100644 --- a/frontend/components/projects/project-card.tsx +++ b/frontend/components/projects/project-card.tsx @@ -1,6 +1,7 @@ -import { Card } from '@/components/ui/card'; import { ChevronRightIcon } from 'lucide-react'; import Link from 'next/link'; + +import { Card } from '@/components/ui/card'; import { Project } from '@/lib/workspaces/types'; interface ProjectCardProps { diff --git a/frontend/components/projects/project-create-dialog.tsx b/frontend/components/projects/project-create-dialog.tsx index 6c44cb06..2c96a70f 100644 --- a/frontend/components/projects/project-create-dialog.tsx +++ b/frontend/components/projects/project-create-dialog.tsx @@ -1,3 +1,7 @@ +import { Loader2, Plus } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useCallback, useState } from 'react'; + import { Dialog, DialogContent, @@ -6,8 +10,6 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Plus } from 'lucide-react'; -import { Project, WorkspaceWithProjects } from '@/lib/workspaces/types'; import { Select, SelectContent, @@ -15,13 +17,12 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; -import { useCallback, useState } from 'react'; +import { useToast } from '@/lib/hooks/use-toast'; +import { Project, WorkspaceWithProjects } from '@/lib/workspaces/types'; import { Button } from '../ui/button'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { useRouter } from 'next/navigation'; -import { useToast } from '@/lib/hooks/use-toast'; interface ProjectCreateDialogProps { onProjectCreate?: () => void; diff --git a/frontend/components/projects/projects-alert.tsx b/frontend/components/projects/projects-alert.tsx index dcea06bb..5c1ee8d2 100644 --- a/frontend/components/projects/projects-alert.tsx +++ b/frontend/components/projects/projects-alert.tsx @@ -1,7 +1,7 @@ -import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; - import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; +import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; + export default function ProjectsAlert() { return ( diff --git a/frontend/components/projects/projects.tsx b/frontend/components/projects/projects.tsx index 4634a2a0..87a4df8f 100644 --- a/frontend/components/projects/projects.tsx +++ b/frontend/components/projects/projects.tsx @@ -1,14 +1,15 @@ 'use client'; -import { cn, swrFetcher } from '@/lib/utils'; +import React from 'react'; +import useSWR from 'swr'; import ProjectCard from '@/components/projects/project-card'; -import ProjectCreateDialog from './project-create-dialog'; -import React from 'react'; +import { cn, swrFetcher } from '@/lib/utils'; +import { WorkspaceWithProjects } from '@/lib/workspaces/types'; + import { Skeleton } from '../ui/skeleton'; -import useSWR from 'swr'; +import ProjectCreateDialog from './project-create-dialog'; import WorkspaceCreateDialog from './workspace-create-dialog'; -import { WorkspaceWithProjects } from '@/lib/workspaces/types'; interface ProjectsProps { isWorkspaceEnabled: boolean; diff --git a/frontend/components/projects/workspace-create-dialog.tsx b/frontend/components/projects/workspace-create-dialog.tsx index 4d01f97f..c2e822a8 100644 --- a/frontend/components/projects/workspace-create-dialog.tsx +++ b/frontend/components/projects/workspace-create-dialog.tsx @@ -1,3 +1,7 @@ +import { Loader2, Plus } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; + import { Dialog, DialogContent, @@ -6,14 +10,11 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Plus } from 'lucide-react'; +import { WorkspaceWithProjects } from '@/lib/workspaces/types'; import { Button } from '../ui/button'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; -import { WorkspaceWithProjects } from '@/lib/workspaces/types'; interface WorkspaceCreateDialogProps { onWorkspaceCreate?: () => void; diff --git a/frontend/components/projects/workspaces-navbar.tsx b/frontend/components/projects/workspaces-navbar.tsx index dba146b9..f2e9dca2 100644 --- a/frontend/components/projects/workspaces-navbar.tsx +++ b/frontend/components/projects/workspaces-navbar.tsx @@ -1,16 +1,17 @@ 'use client'; -import { cn, swrFetcher } from '@/lib/utils'; - -import AvatarMenu from '../user/avatar-menu'; import Image from 'next/image'; import Link from 'next/link'; -import logo from '@/assets/logo/logo.svg'; -import { Skeleton } from '../ui/skeleton'; import { usePathname } from 'next/navigation'; import useSWR from 'swr'; + +import logo from '@/assets/logo/logo.svg'; +import { cn, swrFetcher } from '@/lib/utils'; import { WorkspaceWithProjects } from '@/lib/workspaces/types'; +import { Skeleton } from '../ui/skeleton'; +import AvatarMenu from '../user/avatar-menu'; + export default function WorkspacesNavbar() { const { data, isLoading } = useSWR('/api/workspaces', swrFetcher); const pathname = usePathname(); diff --git a/frontend/components/queue/labels.tsx b/frontend/components/queue/labels.tsx index 6c37d623..7212e6fb 100644 --- a/frontend/components/queue/labels.tsx +++ b/frontend/components/queue/labels.tsx @@ -1,10 +1,23 @@ +import { PopoverClose } from '@radix-ui/react-popover'; import { ChevronDown, Loader2, MoreVertical, Plus, } from 'lucide-react'; +import { useState } from 'react'; +import useSWR from 'swr'; + +import { useProjectContext } from '@/contexts/project-context'; +import { toast } from '@/lib/hooks/use-toast'; +import { + LabelClass, + Span, +} from '@/lib/traces/types'; import { cn, swrFetcher } from '@/lib/utils'; + +import { AddLabel } from '../traces/add-label'; +import { Button } from '../ui/button'; import { Dialog, DialogContent, @@ -20,10 +33,6 @@ import { DropdownMenuItem, DropdownMenuTrigger } from '../ui/dropdown-menu'; -import { - LabelClass, - Span, -} from '@/lib/traces/types'; import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; import { Table, @@ -32,14 +41,6 @@ import { TableRow } from '../ui/table'; -import { AddLabel } from '../traces/add-label'; -import { Button } from '../ui/button'; -import { PopoverClose } from '@radix-ui/react-popover'; -import { toast } from '@/lib/hooks/use-toast'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; -import useSWR from 'swr'; - interface LabelsProps { span: Span | undefined; className?: string; diff --git a/frontend/components/queue/queue.tsx b/frontend/components/queue/queue.tsx index c7b595e9..bd260abd 100644 --- a/frontend/components/queue/queue.tsx +++ b/frontend/components/queue/queue.tsx @@ -1,23 +1,24 @@ 'use client'; import { ArrowDown, ArrowUp, Loader2, X } from "lucide-react"; -import { LabelClass, Span } from '@/lib/traces/types'; -import { LabelingQueue, LabelingQueueItem } from '@/lib/queue/types'; import { useEffect, useState } from 'react'; -import { Button } from '../ui/button'; +import { useProjectContext } from '@/contexts/project-context'; +import { isChatMessageList } from '@/lib/flow/utils'; +import { LabelingQueue, LabelingQueueItem } from '@/lib/queue/types'; +import { LabelClass, Span } from '@/lib/traces/types'; + import ChatMessageListTab from '../traces/chat-message-list-tab'; +import { Button } from '../ui/button'; import DatasetSelect from '../ui/dataset-select'; import DefaultTextarea from '../ui/default-textarea'; import Formatter from '../ui/formatter'; import Header from '../ui/header'; -import { isChatMessageList } from '@/lib/flow/utils'; import { Label } from '../ui/label'; -import { Labels } from './labels'; import MonoWithCopy from "../ui/mono-with-copy"; import { ScrollArea } from '../ui/scroll-area'; import { Switch } from '../ui/switch'; -import { useProjectContext } from '@/contexts/project-context'; +import { Labels } from './labels'; interface QueueProps { queue: LabelingQueue; diff --git a/frontend/components/queues/create-queue-dialog.tsx b/frontend/components/queues/create-queue-dialog.tsx index 4acc9aa9..b49b781a 100644 --- a/frontend/components/queues/create-queue-dialog.tsx +++ b/frontend/components/queues/create-queue-dialog.tsx @@ -1,3 +1,8 @@ +import { Loader2 } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, @@ -6,15 +11,10 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; - -import { Button } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; -import { Loader2 } from 'lucide-react'; import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { cn } from '@/lib/utils'; interface CreateQueueDialogProps { } diff --git a/frontend/components/queues/queues.tsx b/frontend/components/queues/queues.tsx index cd0dabbb..ae01209f 100644 --- a/frontend/components/queues/queues.tsx +++ b/frontend/components/queues/queues.tsx @@ -1,24 +1,25 @@ 'use client'; -import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'; +import { ColumnDef } from '@tanstack/react-table'; import { Loader2, Trash2 } from 'lucide-react'; -import { TableCell, TableRow } from '../ui/table'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import useSWR from 'swr'; import { Button } from '@/components/ui/button'; +import { useProjectContext } from '@/contexts/project-context'; +import { useToast } from '@/lib/hooks/use-toast'; +import { LabelingQueue } from '@/lib/queue/types'; +import { PaginatedResponse } from '@/lib/types'; +import { swrFetcher } from '@/lib/utils'; + import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import CreateQueueDialog from './create-queue-dialog'; import { DataTable } from '../ui/datatable'; +import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '../ui/dialog'; import Header from '../ui/header'; -import { LabelingQueue } from '@/lib/queue/types'; import Mono from '../ui/mono'; -import { PaginatedResponse } from '@/lib/types'; -import { swrFetcher } from '@/lib/utils'; -import { useProjectContext } from '@/contexts/project-context'; -import { useRouter } from 'next/navigation'; -import { useState } from 'react'; -import useSWR from 'swr'; -import { useToast } from '@/lib/hooks/use-toast'; +import { TableCell, TableRow } from '../ui/table'; +import CreateQueueDialog from './create-queue-dialog'; export default function Queues() { const { projectId } = useProjectContext(); diff --git a/frontend/components/settings/add-provider-api-key-dialog.tsx b/frontend/components/settings/add-provider-api-key-dialog.tsx index edbe1508..93bca606 100644 --- a/frontend/components/settings/add-provider-api-key-dialog.tsx +++ b/frontend/components/settings/add-provider-api-key-dialog.tsx @@ -1,3 +1,18 @@ +import { Plus } from 'lucide-react'; +import { useState } from 'react'; + +import { Button } from '@/components/ui/button'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue +} from '@/components/ui/select'; +import { EnvVars } from '@/lib/env/utils'; + import { Dialog, DialogClose, @@ -7,20 +22,6 @@ import { DialogTitle, DialogTrigger } from '../ui/dialog'; -import { - Select, - SelectContent, - SelectItem, - SelectTrigger, - SelectValue -} from '@/components/ui/select'; - -import { Button } from '@/components/ui/button'; -import { EnvVars } from '@/lib/env/utils'; -import { Input } from '@/components/ui/input'; -import { Label } from '@/components/ui/label'; -import { Plus } from 'lucide-react'; -import { useState } from 'react'; interface AddProviderApiKeyDialogProps { existingKeyNames: string[] diff --git a/frontend/components/settings/delete-project.tsx b/frontend/components/settings/delete-project.tsx index 0c5ccfe3..a61ab4f5 100644 --- a/frontend/components/settings/delete-project.tsx +++ b/frontend/components/settings/delete-project.tsx @@ -1,5 +1,8 @@ 'use client'; +import { Loader2, Trash2 } from 'lucide-react'; +import { useState } from 'react'; + import { Dialog, DialogContent, @@ -8,14 +11,12 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Trash2 } from 'lucide-react'; +import { useProjectContext } from '@/contexts/project-context'; +import { cn } from '@/lib/utils'; import { Button } from '../ui/button'; -import { cn } from '@/lib/utils'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; interface DeleteProjectProps { } diff --git a/frontend/components/settings/project-api-keys.tsx b/frontend/components/settings/project-api-keys.tsx index 3adc4e22..cc4887b5 100644 --- a/frontend/components/settings/project-api-keys.tsx +++ b/frontend/components/settings/project-api-keys.tsx @@ -1,4 +1,6 @@ import { Copy, Plus } from 'lucide-react'; +import { useCallback, useState } from 'react'; + import { Dialog, DialogContent, @@ -7,19 +9,18 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; +import { useProjectContext } from '@/contexts/project-context'; import { GenerateProjectApiKeyResponse, ProjectApiKey } from '@/lib/api-keys/types'; -import { useCallback, useState } from 'react'; +import { useToast } from '@/lib/hooks/use-toast'; import { Button } from '../ui/button'; import CopyToClipboardButton from '../ui/copy-to-clipboard'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; import RevokeDialog from './revoke-dialog'; -import { useProjectContext } from '@/contexts/project-context'; -import { useToast } from '@/lib/hooks/use-toast'; interface ApiKeysProps { apiKeys: ProjectApiKey[]; diff --git a/frontend/components/settings/provider-api-keys.tsx b/frontend/components/settings/provider-api-keys.tsx index df4aabe5..e106d076 100644 --- a/frontend/components/settings/provider-api-keys.tsx +++ b/frontend/components/settings/provider-api-keys.tsx @@ -1,14 +1,15 @@ 'use client'; -import { formatTimestamp, swrFetcher } from '@/lib/utils'; +import { Trash2 } from 'lucide-react'; +import useSWR from 'swr'; -import AddProviderApiKeyVarDialog from './add-provider-api-key-dialog'; -import { Button } from '../ui/button'; import { Label } from '@/components/ui/label'; -import { ProviderApiKey } from '@/lib/settings/types'; -import { Trash2 } from 'lucide-react'; import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; +import { ProviderApiKey } from '@/lib/settings/types'; +import { formatTimestamp, swrFetcher } from '@/lib/utils'; + +import { Button } from '../ui/button'; +import AddProviderApiKeyVarDialog from './add-provider-api-key-dialog'; export default function ProviderApiKeys() { diff --git a/frontend/components/settings/revoke-dialog.tsx b/frontend/components/settings/revoke-dialog.tsx index 9d41fc14..59d75e0a 100644 --- a/frontend/components/settings/revoke-dialog.tsx +++ b/frontend/components/settings/revoke-dialog.tsx @@ -1,3 +1,10 @@ +import { Loader2, Trash2 } from 'lucide-react'; +import { useState } from 'react'; + +import { ProjectApiKey } from '@/lib/api-keys/types'; +import { cn } from '@/lib/utils'; + +import { Button } from '../ui/button'; import { Dialog, DialogContent, @@ -6,13 +13,7 @@ import { DialogTitle, DialogTrigger } from '../ui/dialog'; -import { Loader2, Trash2 } from 'lucide-react'; - -import { Button } from '../ui/button'; -import { cn } from '@/lib/utils'; import { Label } from '../ui/label'; -import { ProjectApiKey } from '@/lib/api-keys/types'; -import { useState } from 'react'; interface RevokeApiKeyDialogProps { apiKey: ProjectApiKey; diff --git a/frontend/components/settings/settings.tsx b/frontend/components/settings/settings.tsx index e18b066c..b5abcca3 100644 --- a/frontend/components/settings/settings.tsx +++ b/frontend/components/settings/settings.tsx @@ -1,8 +1,9 @@ 'use client'; -import DeleteProject from "./delete-project"; -import Header from "../ui/header"; import { ProjectApiKey } from "@/lib/api-keys/types"; + +import Header from "../ui/header"; +import DeleteProject from "./delete-project"; import ProjectApiKeys from "./project-api-keys"; import ProviderApiKeys from "./provider-api-keys"; diff --git a/frontend/components/sign-in/email-signin.tsx b/frontend/components/sign-in/email-signin.tsx index ddfb10e8..cb4d0607 100644 --- a/frontend/components/sign-in/email-signin.tsx +++ b/frontend/components/sign-in/email-signin.tsx @@ -1,10 +1,11 @@ 'use client'; +import { signIn } from 'next-auth/react'; +import { useState } from 'react'; + import { Button } from '../ui/button'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { signIn } from 'next-auth/react'; -import { useState } from 'react'; interface EmailSignInProps { showIcon?: boolean; diff --git a/frontend/components/sign-in/github-signin.tsx b/frontend/components/sign-in/github-signin.tsx index 588eaa5e..7b7f9f97 100644 --- a/frontend/components/sign-in/github-signin.tsx +++ b/frontend/components/sign-in/github-signin.tsx @@ -1,12 +1,11 @@ 'use client'; +import { signIn } from 'next-auth/react'; import * as React from 'react'; import { Button, type ButtonProps } from '@/components/ui/button'; import { IconGitHub, IconSpinner } from '@/components/ui/icons'; - import { cn } from '@/lib/utils'; -import { signIn } from 'next-auth/react'; interface GitHubSignInButtonProps extends ButtonProps { showGithubIcon?: boolean; diff --git a/frontend/components/sign-in/google-signin.tsx b/frontend/components/sign-in/google-signin.tsx index f7894551..3fe6dba7 100644 --- a/frontend/components/sign-in/google-signin.tsx +++ b/frontend/components/sign-in/google-signin.tsx @@ -1,13 +1,13 @@ 'use client'; +import Image from 'next/image'; +import { signIn } from 'next-auth/react'; import * as React from 'react'; -import { Button, type ButtonProps } from '@/components/ui/button'; -import { cn } from '@/lib/utils'; import google from '@/assets/logo/google.svg'; +import { Button, type ButtonProps } from '@/components/ui/button'; import { IconSpinner } from '@/components/ui/icons'; -import Image from 'next/image'; -import { signIn } from 'next-auth/react'; +import { cn } from '@/lib/utils'; interface GitHubSignInButtonProps extends ButtonProps { showIcon?: boolean; diff --git a/frontend/components/traces/add-label-popover.tsx b/frontend/components/traces/add-label-popover.tsx index a4b9dcf3..5c2328bc 100644 --- a/frontend/components/traces/add-label-popover.tsx +++ b/frontend/components/traces/add-label-popover.tsx @@ -1,3 +1,4 @@ +import { PopoverClose } from '@radix-ui/react-popover'; import { ChevronDown, Loader2, @@ -5,8 +6,27 @@ import { Plus, Tag } from 'lucide-react'; -import { cn, swrFetcher } from '@/lib/utils'; +import { useSearchParams } from 'next/navigation'; +import { useState } from 'react'; +import useSWR from 'swr'; +import { v4 } from 'uuid'; + +import { useProjectContext } from '@/contexts/project-context'; +import { eventEmitter } from '@/lib/event-emitter'; +import { Graph } from '@/lib/flow/graph'; import { CodeNode, LLMNode, NodeType } from '@/lib/flow/types'; +import { renderNodeInput } from '@/lib/flow/utils'; +import { toast } from '@/lib/hooks/use-toast'; +import { + LabelClass, + LabelSource, + RegisteredLabelClassForPath, + Span, +} from '@/lib/traces/types'; +import { cn, swrFetcher } from '@/lib/utils'; + +import { EvaluatorEditorDialog } from '../evaluator/evaluator-editor-dialog'; +import { Button } from '../ui/button'; import { Dialog, DialogContent, @@ -22,13 +42,8 @@ import { DropdownMenuItem, DropdownMenuTrigger } from '../ui/dropdown-menu'; -import { - LabelClass, - LabelSource, - RegisteredLabelClassForPath, - Span, -} from '@/lib/traces/types'; import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; +import { Switch } from '../ui/switch'; import { Table, TableBody, @@ -37,21 +52,7 @@ import { TableHeader, TableRow } from '../ui/table'; - import { AddLabel } from './add-label'; -import { Button } from '../ui/button'; -import { EvaluatorEditorDialog } from '../evaluator/evaluator-editor-dialog'; -import { eventEmitter } from '@/lib/event-emitter'; -import { Graph } from '@/lib/flow/graph'; -import { PopoverClose } from '@radix-ui/react-popover'; -import { renderNodeInput } from '@/lib/flow/utils'; -import { Switch } from '../ui/switch'; -import { toast } from '@/lib/hooks/use-toast'; -import { useProjectContext } from '@/contexts/project-context'; -import { useSearchParams } from 'next/navigation'; -import { useState } from 'react'; -import useSWR from 'swr'; -import { v4 } from 'uuid'; const getEvaluatorType = (labelClass: LabelClass) => { if (!labelClass.evaluatorRunnableGraph) { diff --git a/frontend/components/traces/add-label.tsx b/frontend/components/traces/add-label.tsx index 9fee7ab8..f769e6f4 100644 --- a/frontend/components/traces/add-label.tsx +++ b/frontend/components/traces/add-label.tsx @@ -1,20 +1,21 @@ import { ArrowLeft, HelpCircle, Loader2, Trash2 } from 'lucide-react'; +import { useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; import { LabelClass, LabelType, Span } from '@/lib/traces/types'; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "../ui/tooltip"; +import { EvaluatorEditorDialog } from '../evaluator/evaluator-editor-dialog'; import { Button } from '../ui/button'; import DefaultTextarea from '../ui/default-textarea'; -import { EvaluatorEditorDialog } from '../evaluator/evaluator-editor-dialog'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; import { Switch } from '../ui/switch'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "../ui/tooltip"; interface AddLabelProps { span: Span; diff --git a/frontend/components/traces/add-to-labeling-queue-popover.tsx b/frontend/components/traces/add-to-labeling-queue-popover.tsx index 88ea0644..7cfe5404 100644 --- a/frontend/components/traces/add-to-labeling-queue-popover.tsx +++ b/frontend/components/traces/add-to-labeling-queue-popover.tsx @@ -1,4 +1,8 @@ import { Loader2, Pen } from 'lucide-react'; +import { useState } from 'react'; +import useSWR from 'swr'; + +import { Button } from "@/components/ui/button"; import { Popover, PopoverContent, @@ -11,16 +15,12 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; - -import { Button } from "@/components/ui/button"; +import { useProjectContext } from '@/contexts/project-context'; +import { useToast } from "@/lib/hooks/use-toast"; import { LabelingQueue } from '@/lib/queue/types'; -import { PaginatedResponse } from '@/lib/types'; import { Span } from '@/lib/traces/types'; +import { PaginatedResponse } from '@/lib/types'; import { swrFetcher } from '@/lib/utils'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; -import useSWR from 'swr'; -import { useToast } from "@/lib/hooks/use-toast"; interface AddToLabelingQueuePopoverProps { span: Span; diff --git a/frontend/components/traces/chat-message-list-tab.tsx b/frontend/components/traces/chat-message-list-tab.tsx index 52ea9acb..eba78be1 100644 --- a/frontend/components/traces/chat-message-list-tab.tsx +++ b/frontend/components/traces/chat-message-list-tab.tsx @@ -1,7 +1,8 @@ import { ChatMessage, ChatMessageContentPart } from '@/lib/types'; -import Formatter from '../ui/formatter'; import { isStringType } from '@/lib/utils'; +import Formatter from '../ui/formatter'; + interface ContentPartTextProps { text: string; } diff --git a/frontend/components/traces/export-spans-dialog.tsx b/frontend/components/traces/export-spans-dialog.tsx index e7e474aa..65ca355a 100644 --- a/frontend/components/traces/export-spans-dialog.tsx +++ b/frontend/components/traces/export-spans-dialog.tsx @@ -1,4 +1,15 @@ import { Database, Loader2 } from 'lucide-react'; +import { useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { Dataset } from '@/lib/dataset/types'; +import { eventEmitter } from '@/lib/event-emitter'; +import { useToast } from '@/lib/hooks/use-toast'; +import { Span } from '@/lib/traces/types'; +import { cn } from '@/lib/utils'; + +import { Button } from '../ui/button'; +import DatasetSelect from '../ui/dataset-select'; import { Dialog, DialogContent, @@ -6,18 +17,8 @@ import { DialogTitle, DialogTrigger } from '../ui/dialog'; - -import { Button } from '../ui/button'; -import { cn } from '@/lib/utils'; -import { Dataset } from '@/lib/dataset/types'; -import DatasetSelect from '../ui/dataset-select'; -import { eventEmitter } from '@/lib/event-emitter'; import Formatter from '../ui/formatter'; import { Label } from '../ui/label'; -import { Span } from '@/lib/traces/types'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; -import { useToast } from '@/lib/hooks/use-toast'; interface ExportSpansDialogProps { span: Span; diff --git a/frontend/components/traces/page-placeholder.tsx b/frontend/components/traces/page-placeholder.tsx index 64ef4755..0737ffc3 100644 --- a/frontend/components/traces/page-placeholder.tsx +++ b/frontend/components/traces/page-placeholder.tsx @@ -1,13 +1,14 @@ 'use client'; -import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../ui/accordion'; +import { useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; import { PYTHON_INSTALL, TYPESCRIPT_INSTALL } from '@/lib/const'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../ui/accordion'; import CodeHighlighter from '../ui/code-highlighter'; import Header from '../ui/header'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; export default function TracesPagePlaceholder() { diff --git a/frontend/components/traces/sessions-table.tsx b/frontend/components/traces/sessions-table.tsx index 09cb6f68..d512eb7a 100644 --- a/frontend/components/traces/sessions-table.tsx +++ b/frontend/components/traces/sessions-table.tsx @@ -1,20 +1,21 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; import { ChevronDownIcon, ChevronRightIcon, RefreshCcw } from 'lucide-react'; -import { SessionPreview, Trace } from '@/lib/traces/types'; -import { useEffect, useState } from 'react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { getDurationString } from '@/lib/flow/utils'; +import { SessionPreview, Trace } from '@/lib/traces/types'; +import { PaginatedResponse } from '@/lib/types'; -import { Button } from '../ui/button'; import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; +import { Button } from '../ui/button'; import { DataTable } from '../ui/datatable'; import DataTableFilter from '../ui/datatable-filter'; import DateRangeFilter from '../ui/date-range-filter'; -import { getDurationString } from '@/lib/flow/utils'; -import { PaginatedResponse } from '@/lib/types'; import TextSearchFilter from '../ui/text-search-filter'; -import { useProjectContext } from '@/contexts/project-context'; type SessionRow = { type: string; diff --git a/frontend/components/traces/span-card.tsx b/frontend/components/traces/span-card.tsx index 8fef6bf0..2d4ee40d 100644 --- a/frontend/components/traces/span-card.tsx +++ b/frontend/components/traces/span-card.tsx @@ -1,8 +1,9 @@ import React, { useEffect, useRef, useState } from 'react'; import { getDurationString } from '@/lib/flow/utils'; -import { Label } from '../ui/label'; import { Span } from '@/lib/traces/types'; + +import { Label } from '../ui/label'; import SpanTypeIcon from './span-type-icon'; const ROW_HEIGHT = 36; diff --git a/frontend/components/traces/span-datasets.tsx b/frontend/components/traces/span-datasets.tsx index 6d99f50f..276197c1 100644 --- a/frontend/components/traces/span-datasets.tsx +++ b/frontend/components/traces/span-datasets.tsx @@ -1,14 +1,15 @@ -import { cn, swrFetcher } from '@/lib/utils'; -import { Table, TableBody, TableCell, TableRow } from '../ui/table'; - import { ArrowUpRight } from 'lucide-react'; -import { eventEmitter } from '@/lib/event-emitter'; import Link from 'next/link'; -import { Skeleton } from '../ui/skeleton'; import { useEffect } from 'react'; -import { useProjectContext } from '@/contexts/project-context'; import useSWR from 'swr'; +import { useProjectContext } from '@/contexts/project-context'; +import { eventEmitter } from '@/lib/event-emitter'; +import { cn, swrFetcher } from '@/lib/utils'; + +import { Skeleton } from '../ui/skeleton'; +import { Table, TableBody, TableCell, TableRow } from '../ui/table'; + interface SpanDatasetsProps { spanId: string; } diff --git a/frontend/components/traces/span-events-add-event.tsx b/frontend/components/traces/span-events-add-event.tsx index f9f5c320..4d51e98e 100644 --- a/frontend/components/traces/span-events-add-event.tsx +++ b/frontend/components/traces/span-events-add-event.tsx @@ -1,11 +1,12 @@ -import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; +import { useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { useToast } from '@/lib/hooks/use-toast'; import { Button } from '../ui/button'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; -import { useProjectContext } from '@/contexts/project-context'; -import { useState } from 'react'; -import { useToast } from '@/lib/hooks/use-toast'; +import { Popover, PopoverContent, PopoverTrigger } from '../ui/popover'; interface SpanEventsAddEventProps { spanId: string; diff --git a/frontend/components/traces/span-events.tsx b/frontend/components/traces/span-events.tsx index d434f328..6d8ad651 100644 --- a/frontend/components/traces/span-events.tsx +++ b/frontend/components/traces/span-events.tsx @@ -1,11 +1,11 @@ + import { useEffect, useState } from 'react'; -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { DataTable } from '../ui/datatable'; import { Event } from '@/lib/events/types'; import { Span } from '@/lib/traces/types'; -import {TIME_MILLISECONDS_FORMAT } from '@/lib/utils'; +import { convertToLocalTimeWithMillis } from '@/lib/utils'; + +import Formatter from '../ui/formatter'; interface TagsProps { span: Span; @@ -19,40 +19,16 @@ export default function SpanEvents({ span }: TagsProps) { setEvents(span.events ?? []); }, [span]); - const columns: ColumnDef[] = [ - { - accessorKey: 'templateName', - header: 'Event Name' - }, - { - accessorKey: 'timestamp', - header: 'Timestamp', - cell: ({ row }) => ( - - ) - }, - { - accessorKey: 'value', - header: 'Value', - cell: ({ row }) => ( -
- {JSON.stringify(row.original.value)} -
- ) - } - ]; + const value = events.map((event) => ({ + name: event.name, + timestamp: convertToLocalTimeWithMillis(event.timestamp), + attributes: event.attributes + })); return (
- +
); diff --git a/frontend/components/traces/span-labels.tsx b/frontend/components/traces/span-labels.tsx index 1ad77305..c795c26b 100644 --- a/frontend/components/traces/span-labels.tsx +++ b/frontend/components/traces/span-labels.tsx @@ -1,6 +1,15 @@ -import { cn, swrFetcher } from '@/lib/utils'; import { Info, X } from 'lucide-react'; +import { useSearchParams } from 'next/navigation'; +import { useEffect } from 'react'; +import useSWR from 'swr'; + +import { useProjectContext } from '@/contexts/project-context'; +import { eventEmitter } from '@/lib/event-emitter'; import { Span, SpanLabel } from '@/lib/traces/types'; +import { cn, swrFetcher } from '@/lib/utils'; + +import { Button } from '../ui/button'; +import { Skeleton } from '../ui/skeleton'; import { Table, TableBody, TableCell, TableRow } from '../ui/table'; import { Tooltip, @@ -9,14 +18,6 @@ import { TooltipTrigger } from '../ui/tooltip'; -import { Button } from '../ui/button'; -import { eventEmitter } from '@/lib/event-emitter'; -import { Skeleton } from '../ui/skeleton'; -import { useEffect } from 'react'; -import { useProjectContext } from '@/contexts/project-context'; -import { useSearchParams } from 'next/navigation'; -import useSWR from 'swr'; - interface SpanLabelsProps { span: Span; } diff --git a/frontend/components/traces/span-type-icon.tsx b/frontend/components/traces/span-type-icon.tsx index cd4c8cec..1ea19c00 100644 --- a/frontend/components/traces/span-type-icon.tsx +++ b/frontend/components/traces/span-type-icon.tsx @@ -1,8 +1,8 @@ import { Activity, ArrowRight, Braces, Gauge, MessageCircleMore } from "lucide-react"; -import { cn } from "@/lib/utils"; -import { SPAN_TYPE_TO_COLOR } from "@/lib/traces/utils"; import { SpanType } from "@/lib/traces/types"; +import { SPAN_TYPE_TO_COLOR } from "@/lib/traces/utils"; +import { cn } from "@/lib/utils"; interface SpanTypeIconProps { spanType: SpanType, diff --git a/frontend/components/traces/span-view-span.tsx b/frontend/components/traces/span-view-span.tsx index 56873c2e..4c4087a0 100644 --- a/frontend/components/traces/span-view-span.tsx +++ b/frontend/components/traces/span-view-span.tsx @@ -1,8 +1,9 @@ -import ChatMessageListTab from './chat-message-list-tab'; -import Formatter from '../ui/formatter'; import { isChatMessageList } from '@/lib/flow/utils'; -import { ScrollArea } from '../ui/scroll-area'; import { Span } from '@/lib/traces/types'; + +import Formatter from '../ui/formatter'; +import { ScrollArea } from '../ui/scroll-area'; +import ChatMessageListTab from './chat-message-list-tab'; import SpanDatasets from './span-datasets'; import SpanLabels from './span-labels'; diff --git a/frontend/components/traces/span-view.tsx b/frontend/components/traces/span-view.tsx index 40a29665..4935e905 100644 --- a/frontend/components/traces/span-view.tsx +++ b/frontend/components/traces/span-view.tsx @@ -5,20 +5,21 @@ import { Gauge, MessageCircleMore, } from 'lucide-react'; +import useSWR from 'swr'; + +import { useProjectContext } from '@/contexts/project-context'; import { Span, SpanType } from '@/lib/traces/types'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; +import { swrFetcher } from '@/lib/utils'; +import Formatter from '../ui/formatter'; +import { Skeleton } from '../ui/skeleton'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import { AddLabelPopover } from './add-label-popover'; import AddToLabelingQueuePopover from './add-to-labeling-queue-popover'; import ExportSpansDialog from './export-spans-dialog'; -import Formatter from '../ui/formatter'; -import { Skeleton } from '../ui/skeleton'; import SpanEvents from './span-events'; import { SpanViewSpan } from './span-view-span'; import StatsShields from './stats-shields'; -import { swrFetcher } from '@/lib/utils'; -import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; interface SpanViewProps { spanId: string; diff --git a/frontend/components/traces/spans-table.tsx b/frontend/components/traces/spans-table.tsx index 5ed7979a..67066dc7 100644 --- a/frontend/components/traces/spans-table.tsx +++ b/frontend/components/traces/spans-table.tsx @@ -1,26 +1,27 @@ 'use client'; +import { ColumnDef } from '@tanstack/react-table'; import { ArrowRight, RefreshCcw } from 'lucide-react'; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger -} from '../ui/tooltip'; -import { useEffect, useState } from 'react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { Span } from '@/lib/traces/types'; +import { PaginatedResponse } from '@/lib/types'; -import { Button } from '../ui/button'; import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; +import { Button } from '../ui/button'; import { DataTable } from '../ui/datatable'; import DataTableFilter from '../ui/datatable-filter'; import DateRangeFilter from '../ui/date-range-filter'; import Mono from '../ui/mono'; -import { PaginatedResponse } from '@/lib/types'; -import { Span } from '@/lib/traces/types'; -import SpanTypeIcon from './span-type-icon'; import TextSearchFilter from '../ui/text-search-filter'; -import { useProjectContext } from '@/contexts/project-context'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '../ui/tooltip'; +import SpanTypeIcon from './span-type-icon'; interface SpansTableProps { onRowClick?: (traceId: string) => void; diff --git a/frontend/components/traces/stats-shields.tsx b/frontend/components/traces/stats-shields.tsx index 74735aba..a9c94995 100644 --- a/frontend/components/traces/stats-shields.tsx +++ b/frontend/components/traces/stats-shields.tsx @@ -1,15 +1,16 @@ +import { TooltipPortal } from '@radix-ui/react-tooltip'; import { CircleDollarSign, Clock3, Coins, InfoIcon } from 'lucide-react'; + import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; - -import { cn } from '@/lib/utils'; import { getDurationString } from '@/lib/flow/utils'; +import { cn } from '@/lib/utils'; + import { Label } from '../ui/label'; -import { TooltipPortal } from '@radix-ui/react-tooltip'; interface StatsShieldsProps { startTime: string; diff --git a/frontend/components/traces/timeline.tsx b/frontend/components/traces/timeline.tsx index 211f8fb1..036b8bf7 100644 --- a/frontend/components/traces/timeline.tsx +++ b/frontend/components/traces/timeline.tsx @@ -128,7 +128,7 @@ export default function Timeline({ spans, childSpans }: TimelineProps) { segmentEvents.push({ id: event.id, - name: event.templateName, + name: event.name, left: eventLeft }); } diff --git a/frontend/components/traces/trace-view.tsx b/frontend/components/traces/trace-view.tsx index e7e701ce..2127e613 100644 --- a/frontend/components/traces/trace-view.tsx +++ b/frontend/components/traces/trace-view.tsx @@ -1,19 +1,20 @@ -import { cn, swrFetcher } from '@/lib/utils'; -import React, { useEffect, useRef, useState } from 'react'; -import { ScrollArea, ScrollBar } from '../ui/scroll-area'; +import { ChevronsRight } from 'lucide-react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import React, { useEffect, useRef, useState } from 'react'; +import useSWR from 'swr'; + +import { useProjectContext } from '@/contexts/project-context'; +import { Span } from '@/lib/traces/types'; +import { cn, swrFetcher } from '@/lib/utils'; import { Button } from '../ui/button'; -import { ChevronsRight } from 'lucide-react'; import MonoWithCopy from '../ui/mono-with-copy'; +import { ScrollArea, ScrollBar } from '../ui/scroll-area'; import { Skeleton } from '../ui/skeleton'; -import { Span } from '@/lib/traces/types'; import { SpanCard } from './span-card'; import { SpanView } from './span-view'; import StatsShields from './stats-shields'; import Timeline from './timeline'; -import { useProjectContext } from '@/contexts/project-context'; -import useSWR from 'swr'; interface TraceViewProps { traceId: string; diff --git a/frontend/components/traces/traces-metrics.tsx b/frontend/components/traces/traces-metrics.tsx index bccb70ad..48586d9b 100644 --- a/frontend/components/traces/traces-metrics.tsx +++ b/frontend/components/traces/traces-metrics.tsx @@ -1,22 +1,23 @@ 'use client'; +import { useSearchParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; import { CartesianGrid, Line, LineChart, XAxis, YAxis } from 'recharts'; + import { ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent } from '@/components/ui/chart'; +import { useProjectContext } from '@/contexts/project-context'; +import { TraceMetricDatapoint } from '@/lib/traces/types'; import { formatTimestampFromSeconds, getGroupByInterval } from '@/lib/utils'; -import { useEffect, useState } from 'react'; import { Skeleton } from '../ui/skeleton'; -import { TraceMetricDatapoint } from '@/lib/traces/types'; -import { useProjectContext } from '@/contexts/project-context'; -import { useSearchParams } from 'next/navigation'; interface CustomChartProps { metric: string; diff --git a/frontend/components/traces/traces-table.tsx b/frontend/components/traces/traces-table.tsx index e2c8fb2e..eb37b07b 100644 --- a/frontend/components/traces/traces-table.tsx +++ b/frontend/components/traces/traces-table.tsx @@ -1,30 +1,31 @@ +import { createClient } from '@supabase/supabase-js'; +import { ColumnDef } from '@tanstack/react-table'; import { ArrowRight, RefreshCcw } from 'lucide-react'; -import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { SUPABASE_ANON_KEY, SUPABASE_URL } from '@/lib/const'; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger -} from '../ui/tooltip'; -import { useEffect, useMemo, useState } from 'react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useEffect, useMemo, useState } from 'react'; + +import { useProjectContext } from '@/contexts/project-context'; +import { useUserContext } from '@/contexts/user-context'; +import { SUPABASE_ANON_KEY, SUPABASE_URL } from '@/lib/const'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; +import { Trace } from '@/lib/traces/types'; +import { PaginatedGetResponseWithProjectPresenceFlag } from '@/lib/types'; -import { Button } from '../ui/button'; import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { ColumnDef } from '@tanstack/react-table'; -import { createClient } from '@supabase/supabase-js'; +import { Button } from '../ui/button'; import { DataTable } from '../ui/datatable'; import DataTableFilter from '../ui/datatable-filter'; import DateRangeFilter from '../ui/date-range-filter'; import Mono from '../ui/mono'; -import { PaginatedGetResponseWithProjectPresenceFlag } from '@/lib/types'; -import SpanTypeIcon from './span-type-icon'; import TextSearchFilter from '../ui/text-search-filter'; -import { Trace } from '@/lib/traces/types'; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger +} from '../ui/tooltip'; import TracesPagePlaceholder from './page-placeholder'; -import { useProjectContext } from '@/contexts/project-context'; -import { useUserContext } from '@/contexts/user-context'; +import SpanTypeIcon from './span-type-icon'; interface TracesTableProps { onRowClick?: (rowId: string) => void; diff --git a/frontend/components/traces/traces.tsx b/frontend/components/traces/traces.tsx index 8a12cfed..5a2690d0 100644 --- a/frontend/components/traces/traces.tsx +++ b/frontend/components/traces/traces.tsx @@ -1,17 +1,18 @@ 'use client'; -import { Feature, isFeatureEnabled } from '@/lib/features/features'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; -import { useEffect, useState } from 'react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - +import { usePostHog } from 'posthog-js/react'; import { Resizable } from 're-resizable'; +import { useEffect, useState } from 'react'; + +import { useUserContext } from '@/contexts/user-context'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; + +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import SessionsTable from './sessions-table'; import SpansTable from './spans-table'; -import TracesTable from './traces-table'; import TraceView from './trace-view'; -import { usePostHog } from 'posthog-js/react'; -import { useUserContext } from '@/contexts/user-context'; +import TracesTable from './traces-table'; enum SelectedTab { TRACES = 'traces', diff --git a/frontend/components/ui/accordion.tsx b/frontend/components/ui/accordion.tsx index 6b88a7b6..5db4a467 100644 --- a/frontend/components/ui/accordion.tsx +++ b/frontend/components/ui/accordion.tsx @@ -1,8 +1,8 @@ 'use client'; import * as AccordionPrimitive from '@radix-ui/react-accordion'; -import * as React from 'react'; import { ChevronDownIcon } from '@radix-ui/react-icons'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -54,4 +54,4 @@ const AccordionContent = React.forwardRef< )); AccordionContent.displayName = AccordionPrimitive.Content.displayName; -export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }; +export { Accordion, AccordionContent,AccordionItem, AccordionTrigger }; diff --git a/frontend/components/ui/alert.tsx b/frontend/components/ui/alert.tsx index cb043559..606c5841 100644 --- a/frontend/components/ui/alert.tsx +++ b/frontend/components/ui/alert.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import { cva,type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -56,4 +56,4 @@ const AlertDescription = React.forwardRef< )); AlertDescription.displayName = 'AlertDescription'; -export { Alert, AlertTitle, AlertDescription }; +export { Alert, AlertDescription,AlertTitle }; diff --git a/frontend/components/ui/auto-complete.tsx b/frontend/components/ui/auto-complete.tsx index 1aafc782..d544be11 100644 --- a/frontend/components/ui/auto-complete.tsx +++ b/frontend/components/ui/auto-complete.tsx @@ -1,3 +1,5 @@ +import React from 'react'; + import { Command, CommandEmpty, @@ -6,7 +8,6 @@ import { CommandList } from '@/components/ui/command'; -import React from 'react'; import { type Tag as TagType } from './tag-input'; type AutocompleteProps = { diff --git a/frontend/components/ui/avatar.tsx b/frontend/components/ui/avatar.tsx index 31b6f8aa..3f2f619e 100644 --- a/frontend/components/ui/avatar.tsx +++ b/frontend/components/ui/avatar.tsx @@ -47,4 +47,4 @@ const AvatarFallback = React.forwardRef< )); AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName; -export { Avatar, AvatarImage, AvatarFallback }; +export { Avatar, AvatarFallback,AvatarImage }; diff --git a/frontend/components/ui/badge.tsx b/frontend/components/ui/badge.tsx index 66e50e72..5f4fd431 100644 --- a/frontend/components/ui/badge.tsx +++ b/frontend/components/ui/badge.tsx @@ -1,5 +1,5 @@ -import * as React from 'react'; import { cva,type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/button-loading.tsx b/frontend/components/ui/button-loading.tsx index 126147f8..52ff5b08 100644 --- a/frontend/components/ui/button-loading.tsx +++ b/frontend/components/ui/button-loading.tsx @@ -1,6 +1,7 @@ -import { Button } from '@/components/ui/button'; import { ReloadIcon } from '@radix-ui/react-icons'; +import { Button } from '@/components/ui/button'; + export function ButtonLoading({ loadingText = '', ...props }) { return (
diff --git a/frontend/components/ui/collapsible.tsx b/frontend/components/ui/collapsible.tsx index 86ab87d8..dccea409 100644 --- a/frontend/components/ui/collapsible.tsx +++ b/frontend/components/ui/collapsible.tsx @@ -8,4 +8,4 @@ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger; const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent; -export { Collapsible, CollapsibleTrigger, CollapsibleContent }; +export { Collapsible, CollapsibleContent,CollapsibleTrigger }; diff --git a/frontend/components/ui/command.tsx b/frontend/components/ui/command.tsx index 7fe8352e..227e7bac 100644 --- a/frontend/components/ui/command.tsx +++ b/frontend/components/ui/command.tsx @@ -1,12 +1,12 @@ 'use client'; +import { type DialogProps } from '@radix-ui/react-dialog'; +import { MagnifyingGlassIcon } from '@radix-ui/react-icons'; +import { Command as CommandPrimitive } from 'cmdk'; import * as React from 'react'; -import { Dialog, DialogContent } from '@/components/ui/dialog'; +import { Dialog, DialogContent } from '@/components/ui/dialog'; import { cn } from '@/lib/utils'; -import { Command as CommandPrimitive } from 'cmdk'; -import { type DialogProps } from '@radix-ui/react-dialog'; -import { MagnifyingGlassIcon } from '@radix-ui/react-icons'; const Command = React.forwardRef< React.ElementRef, @@ -141,11 +141,10 @@ CommandShortcut.displayName = 'CommandShortcut'; export { Command, CommandDialog, - CommandInput, - CommandList, CommandEmpty, CommandGroup, + CommandInput, CommandItem, - CommandShortcut, - CommandSeparator -}; + CommandList, + CommandSeparator, + CommandShortcut}; diff --git a/frontend/components/ui/copy-to-clipboard.tsx b/frontend/components/ui/copy-to-clipboard.tsx index c5a1eb54..22404c39 100644 --- a/frontend/components/ui/copy-to-clipboard.tsx +++ b/frontend/components/ui/copy-to-clipboard.tsx @@ -1,6 +1,7 @@ -import { Button } from "./button"; import { useToast } from "@/lib/hooks/use-toast"; +import { Button } from "./button"; + interface CopyToClipboardButtonProps { text: string; toastPrefix?: string; diff --git a/frontend/components/ui/create-button.tsx b/frontend/components/ui/create-button.tsx index 26958261..efffba57 100644 --- a/frontend/components/ui/create-button.tsx +++ b/frontend/components/ui/create-button.tsx @@ -1,8 +1,10 @@ -import { Button } from './button'; -import { cn } from '@/lib/utils'; import { Plus } from 'lucide-react'; import React from 'react'; +import { cn } from '@/lib/utils'; + +import { Button } from './button'; + interface ButtonProps extends React.ButtonHTMLAttributes {} const CreateButton: React.FC = ({ diff --git a/frontend/components/ui/dataset-select.tsx b/frontend/components/ui/dataset-select.tsx index a30df890..cd19314d 100644 --- a/frontend/components/ui/dataset-select.tsx +++ b/frontend/components/ui/dataset-select.tsx @@ -1,3 +1,5 @@ +import { useEffect, useState } from 'react'; + import { Select, SelectContent, @@ -5,11 +7,9 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; -import { useEffect, useState } from 'react'; - +import { useProjectContext } from '@/contexts/project-context'; import { Dataset } from '@/lib/dataset/types'; import { PaginatedResponse } from '@/lib/types'; -import { useProjectContext } from '@/contexts/project-context'; interface DatasetSelectProps { onDatasetChange: (dataset: Dataset) => void; diff --git a/frontend/components/ui/datatable-filter.tsx b/frontend/components/ui/datatable-filter.tsx index f991c9c2..1bbe48fb 100644 --- a/frontend/components/ui/datatable-filter.tsx +++ b/frontend/components/ui/datatable-filter.tsx @@ -1,5 +1,13 @@ -import { cn, getFilterFromUrlParams } from '@/lib/utils'; import { ListFilter, Plus, X } from 'lucide-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useState } from 'react'; + +import { DatatableFilter } from '@/lib/types'; +import { cn, getFilterFromUrlParams } from '@/lib/utils'; + +import { Button } from './button'; +import { Input } from './input'; +import { Label } from './label'; import { Popover, PopoverContent, PopoverTrigger } from './popover'; import { Select, @@ -8,13 +16,6 @@ import { SelectTrigger, SelectValue } from './select'; -import { usePathname, useRouter, useSearchParams } from 'next/navigation'; - -import { Button } from './button'; -import { DatatableFilter } from '@/lib/types'; -import { Input } from './input'; -import { Label } from './label'; -import { useState } from 'react'; interface Filter { name: string; diff --git a/frontend/components/ui/datatable-pagination.tsx b/frontend/components/ui/datatable-pagination.tsx index ec64fe8d..a0287a2a 100644 --- a/frontend/components/ui/datatable-pagination.tsx +++ b/frontend/components/ui/datatable-pagination.tsx @@ -1,4 +1,7 @@ import { ChevronLeftIcon, ChevronRightIcon } from '@radix-ui/react-icons'; +import { type Table } from '@tanstack/react-table'; + +import { Button } from '@/components/ui/button'; import { Select, SelectContent, @@ -7,9 +10,6 @@ import { SelectValue } from '@/components/ui/select'; -import { Button } from '@/components/ui/button'; -import { type Table } from '@tanstack/react-table'; - interface DataTablePaginationProps { table: Table; pageSizeOptions?: number[]; diff --git a/frontend/components/ui/datatable.tsx b/frontend/components/ui/datatable.tsx index 69075fc6..803c0779 100644 --- a/frontend/components/ui/datatable.tsx +++ b/frontend/components/ui/datatable.tsx @@ -8,8 +8,10 @@ import { Row, useReactTable } from '@tanstack/react-table'; +import { X } from 'lucide-react'; import React, { useEffect, useState } from 'react'; -import { ScrollArea, ScrollBar } from './scroll-area'; + +import { Checkbox } from '@/components/ui/checkbox'; import { Table, TableBody, @@ -18,14 +20,13 @@ import { TableHeader, TableRow } from '@/components/ui/table'; +import { cn } from '@/lib/utils'; import { Button } from './button'; -import { Checkbox } from '@/components/ui/checkbox'; -import { cn } from '@/lib/utils'; import { DataTablePagination } from './datatable-pagination'; import { Label } from './label'; +import { ScrollArea, ScrollBar } from './scroll-area'; import { Skeleton } from './skeleton'; -import { X } from 'lucide-react'; const DEFAULT_PAGE_SIZE = 50; diff --git a/frontend/components/ui/date-range-filter.tsx b/frontend/components/ui/date-range-filter.tsx index f271ee15..8133de94 100644 --- a/frontend/components/ui/date-range-filter.tsx +++ b/frontend/components/ui/date-range-filter.tsx @@ -1,15 +1,16 @@ -import { Popover, PopoverContent, PopoverTrigger } from './popover'; -import { useEffect, useState } from 'react'; +import { formatDate } from 'date-fns'; +import { CalendarIcon } from 'lucide-react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import { DateRange as ReactDateRange } from 'react-day-picker'; + +import { cn } from '@/lib/utils'; import { Button } from './button'; import { Calendar } from './calendar'; -import { CalendarIcon } from 'lucide-react'; -import { cn } from '@/lib/utils'; -import { formatDate } from 'date-fns'; import { Input } from './input'; import { Label } from './label'; -import { DateRange as ReactDateRange } from 'react-day-picker'; +import { Popover, PopoverContent, PopoverTrigger } from './popover'; type DateRange = { name: string; diff --git a/frontend/components/ui/default-textarea.tsx b/frontend/components/ui/default-textarea.tsx index 6ce149ce..9fbd7096 100644 --- a/frontend/components/ui/default-textarea.tsx +++ b/frontend/components/ui/default-textarea.tsx @@ -1,9 +1,9 @@ +import React from 'react'; import TextareaAutosize, { type TextareaAutosizeProps } from 'react-textarea-autosize'; import { cn } from '@/lib/utils'; -import React from 'react'; const DefaultTextarea = ({ className, ...props }: TextareaAutosizeProps) => ( ) { } export { - IconMinusCircle, + IconArrowDown, + IconArrowElbow, + IconArrowRight, + IconCheck, + IconChevronUpDown, + IconClose, + IconCopy, + IconDownload, IconEdit, + IconExternalLink, + IconGitHub, + IconGoogle, + IconMessage, + IconMinusCircle, + IconMoon, IconNextChat, IconOpenAI, - IconVercel, - IconGitHub, - IconSeparator, - IconArrowDown, - IconArrowRight, - IconUser, IconPlus, - IconArrowElbow, - IconSpinner, - IconMessage, - IconTrash, IconRefresh, - IconStop, + IconSeparator, + IconShare, IconSidebar, - IconMoon, + IconSpinner, + IconStop, IconSun, - IconCopy, - IconCheck, - IconDownload, - IconClose, - IconShare, + IconTrash, + IconUser, IconUsers, - IconExternalLink, - IconChevronUpDown, - IconZenguard, - IconGoogle -}; + IconVercel, + IconZenguard}; diff --git a/frontend/components/ui/input-password.tsx b/frontend/components/ui/input-password.tsx index 60d7a299..da8ed835 100644 --- a/frontend/components/ui/input-password.tsx +++ b/frontend/components/ui/input-password.tsx @@ -1,6 +1,5 @@ -import * as React from 'react'; import { EyeIcon, EyeOffIcon } from 'lucide-react'; -import { fontSans, fontSecurity } from '@/lib/fonts'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -31,7 +30,6 @@ const InputPassword = React.forwardRef( type="text" placeholder={placeholder ?? ''} className={cn( - showPassword || !value ? fontSans.variable : fontSecurity.className, 'flex h-9 px-3 w-full py-1 rounded-l-md border border-input border-r-0 text-sm transition-colors focus-visible:outline-none file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50' )} ref={ref} diff --git a/frontend/components/ui/label.tsx b/frontend/components/ui/label.tsx index 0fcab353..3edbdad5 100644 --- a/frontend/components/ui/label.tsx +++ b/frontend/components/ui/label.tsx @@ -1,8 +1,8 @@ 'use client'; import * as LabelPrimitive from '@radix-ui/react-label'; -import * as React from 'react'; import { cva,type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/mono-with-copy.tsx b/frontend/components/ui/mono-with-copy.tsx index dec8984c..1f035c4a 100644 --- a/frontend/components/ui/mono-with-copy.tsx +++ b/frontend/components/ui/mono-with-copy.tsx @@ -1,7 +1,9 @@ import { Copy } from 'lucide-react'; -import CopyToClipboard from './copy-to-clipboard'; + import Mono from '@/components/ui/mono'; +import CopyToClipboard from './copy-to-clipboard'; + interface MonoWithCopyProps { children: React.ReactNode; className?: string; diff --git a/frontend/components/ui/mono.tsx b/frontend/components/ui/mono.tsx index dfc4b573..49b8bc2e 100644 --- a/frontend/components/ui/mono.tsx +++ b/frontend/components/ui/mono.tsx @@ -1,6 +1,7 @@ -import { cn } from '@/lib/utils'; import { ReactNode } from 'react'; +import { cn } from '@/lib/utils'; + export default function Mono({ className, children diff --git a/frontend/components/ui/pagination.tsx b/frontend/components/ui/pagination.tsx index c07f27da..cfee1572 100644 --- a/frontend/components/ui/pagination.tsx +++ b/frontend/components/ui/pagination.tsx @@ -1,12 +1,11 @@ -import * as React from 'react'; - -import { ButtonProps, buttonVariants } from '@/components/ui/button'; import { ChevronLeftIcon, ChevronRightIcon, DotsHorizontalIcon } from '@radix-ui/react-icons'; +import * as React from 'react'; +import { ButtonProps, buttonVariants } from '@/components/ui/button'; import { cn } from '@/lib/utils'; const Pagination = ({ className, ...props }: React.ComponentProps<'nav'>) => ( @@ -114,9 +113,8 @@ PaginationEllipsis.displayName = 'PaginationEllipsis'; export { Pagination, PaginationContent, - PaginationLink, + PaginationEllipsis, PaginationItem, - PaginationPrevious, + PaginationLink, PaginationNext, - PaginationEllipsis -}; + PaginationPrevious}; diff --git a/frontend/components/ui/pipeline-select.tsx b/frontend/components/ui/pipeline-select.tsx index b78085ae..c2cad912 100644 --- a/frontend/components/ui/pipeline-select.tsx +++ b/frontend/components/ui/pipeline-select.tsx @@ -1,5 +1,6 @@ import { GitCommitVertical, Loader2 } from 'lucide-react'; -import { Pipeline, PipelineVersion } from '@/lib/pipeline/types'; +import { useEffect, useState } from 'react'; + import { Select, SelectContent, @@ -9,9 +10,8 @@ import { SelectTrigger, SelectValue } from '@/components/ui/select'; -import { useEffect, useState } from 'react'; - import { useProjectContext } from '@/contexts/project-context'; +import { Pipeline, PipelineVersion } from '@/lib/pipeline/types'; interface PipelineSelectProps { onPipelineChange?: (pipeline: Pipeline) => void; diff --git a/frontend/components/ui/popover.tsx b/frontend/components/ui/popover.tsx index 026866aa..8ffe283d 100644 --- a/frontend/components/ui/popover.tsx +++ b/frontend/components/ui/popover.tsx @@ -30,4 +30,4 @@ const PopoverContent = React.forwardRef< )); PopoverContent.displayName = PopoverPrimitive.Content.displayName; -export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }; +export { Popover, PopoverAnchor,PopoverContent, PopoverTrigger }; diff --git a/frontend/components/ui/radio-group.tsx b/frontend/components/ui/radio-group.tsx index 5a9fa402..dd33e810 100644 --- a/frontend/components/ui/radio-group.tsx +++ b/frontend/components/ui/radio-group.tsx @@ -1,8 +1,8 @@ 'use client'; +import { CheckIcon } from '@radix-ui/react-icons'; import * as RadioGroupPrimitive from '@radix-ui/react-radio-group'; import * as React from 'react'; -import { CheckIcon } from '@radix-ui/react-icons'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/resizable.tsx b/frontend/components/ui/resizable.tsx index 7c51be9a..0e29041a 100644 --- a/frontend/components/ui/resizable.tsx +++ b/frontend/components/ui/resizable.tsx @@ -1,9 +1,9 @@ 'use client'; +import { DragHandleDots2Icon } from '@radix-ui/react-icons'; import * as ResizablePrimitive from 'react-resizable-panels'; import { cn } from '@/lib/utils'; -import { DragHandleDots2Icon } from '@radix-ui/react-icons'; const ResizablePanelGroup = ({ className, @@ -42,4 +42,4 @@ const ResizableHandle = ({ ); -export { ResizablePanelGroup, ResizablePanel, ResizableHandle }; +export { ResizableHandle,ResizablePanel, ResizablePanelGroup }; diff --git a/frontend/components/ui/scroll-area.tsx b/frontend/components/ui/scroll-area.tsx index 75c68fa4..4e095c9e 100644 --- a/frontend/components/ui/scroll-area.tsx +++ b/frontend/components/ui/scroll-area.tsx @@ -1,7 +1,7 @@ 'use client'; -import * as React from 'react'; import * as ScrollAreaPrimitive from '@radix-ui/react-scroll-area'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/select.tsx b/frontend/components/ui/select.tsx index 9e7fd55a..b6933166 100644 --- a/frontend/components/ui/select.tsx +++ b/frontend/components/ui/select.tsx @@ -1,13 +1,13 @@ 'use client'; -import * as React from 'react'; -import * as SelectPrimitive from '@radix-ui/react-select'; import { CaretSortIcon, CheckIcon, ChevronDownIcon, ChevronUpIcon } from '@radix-ui/react-icons'; +import * as SelectPrimitive from '@radix-ui/react-select'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -152,13 +152,12 @@ SelectSeparator.displayName = SelectPrimitive.Separator.displayName; export { Select, - SelectGroup, - SelectValue, - SelectTrigger, SelectContent, - SelectLabel, + SelectGroup, SelectItem, - SelectSeparator, + SelectLabel, + SelectScrollDownButton, SelectScrollUpButton, - SelectScrollDownButton -}; + SelectSeparator, + SelectTrigger, + SelectValue}; diff --git a/frontend/components/ui/separator.tsx b/frontend/components/ui/separator.tsx index da040615..609214fa 100644 --- a/frontend/components/ui/separator.tsx +++ b/frontend/components/ui/separator.tsx @@ -1,7 +1,7 @@ 'use client'; -import * as React from 'react'; import * as SeparatorPrimitive from '@radix-ui/react-separator'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/sheet.tsx b/frontend/components/ui/sheet.tsx index a18a7bc5..85659d66 100644 --- a/frontend/components/ui/sheet.tsx +++ b/frontend/components/ui/sheet.tsx @@ -1,8 +1,8 @@ "use client"; -import * as React from "react"; import * as SheetPrimitive from "@radix-ui/react-dialog"; import { cva,type VariantProps } from "class-variance-authority"; +import * as React from "react"; import { cn } from "@/lib/utils"; @@ -123,13 +123,13 @@ SheetDescription.displayName = SheetPrimitive.Description.displayName; export { Sheet, - SheetPortal, - SheetOverlay, - SheetTrigger, SheetClose, SheetContent, - SheetHeader, + SheetDescription, SheetFooter, + SheetHeader, + SheetOverlay, + SheetPortal, SheetTitle, - SheetDescription, + SheetTrigger, }; diff --git a/frontend/components/ui/slider.tsx b/frontend/components/ui/slider.tsx index f9b332a7..5b784914 100644 --- a/frontend/components/ui/slider.tsx +++ b/frontend/components/ui/slider.tsx @@ -1,7 +1,7 @@ 'use client'; -import * as React from 'react'; import * as SliderPrimitive from '@radix-ui/react-slider'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/switch.tsx b/frontend/components/ui/switch.tsx index 9c51976b..6da84d40 100644 --- a/frontend/components/ui/switch.tsx +++ b/frontend/components/ui/switch.tsx @@ -1,7 +1,7 @@ 'use client'; -import * as React from 'react'; import * as SwitchPrimitives from '@radix-ui/react-switch'; +import * as React from 'react'; import { cn } from '@/lib/utils'; diff --git a/frontend/components/ui/table.tsx b/frontend/components/ui/table.tsx index fc7af96d..ca28b209 100644 --- a/frontend/components/ui/table.tsx +++ b/frontend/components/ui/table.tsx @@ -104,11 +104,10 @@ TableCaption.displayName = 'TableCaption'; export { Table, - TableHeader, TableBody, + TableCaption, + TableCell, TableFooter, TableHead, - TableRow, - TableCell, - TableCaption -}; + TableHeader, + TableRow}; diff --git a/frontend/components/ui/tabs.tsx b/frontend/components/ui/tabs.tsx index 0c8fa9fa..0bc98a84 100644 --- a/frontend/components/ui/tabs.tsx +++ b/frontend/components/ui/tabs.tsx @@ -1,7 +1,7 @@ 'use client'; -import * as React from 'react'; import * as TabsPrimitive from '@radix-ui/react-tabs'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -52,4 +52,4 @@ const TabsContent = React.forwardRef< )); TabsContent.displayName = TabsPrimitive.Content.displayName; -export { Tabs, TabsList, TabsTrigger, TabsContent }; +export { Tabs, TabsContent,TabsList, TabsTrigger }; diff --git a/frontend/components/ui/tag-input.tsx b/frontend/components/ui/tag-input.tsx index db9db1ad..656726bb 100644 --- a/frontend/components/ui/tag-input.tsx +++ b/frontend/components/ui/tag-input.tsx @@ -1,16 +1,18 @@ 'use client'; +import { type VariantProps } from 'class-variance-authority'; +import React from 'react'; +import { v4 as uuid } from 'uuid'; + +import { CommandInput } from '@/components/ui/command'; + +import { toast } from '../../lib/hooks/use-toast'; import { Autocomplete } from './auto-complete'; import { Button } from './button'; -import { CommandInput } from '@/components/ui/command'; import { Input } from './input'; -import React from 'react'; +import { tagVariants } from './tag'; import { TagList } from './tag-list'; import { TagPopover } from './tag-popover'; -import { tagVariants } from './tag'; -import { toast } from '../../lib/hooks/use-toast'; -import { v4 as uuid } from 'uuid'; -import { type VariantProps } from 'class-variance-authority'; export enum Delimiter { Comma = ',', diff --git a/frontend/components/ui/tag-list.tsx b/frontend/components/ui/tag-list.tsx index 98eb4960..799f21ec 100644 --- a/frontend/components/ui/tag-list.tsx +++ b/frontend/components/ui/tag-list.tsx @@ -1,7 +1,8 @@ -import { Tag, TagProps } from './tag'; +import React from 'react'; import { cn } from '@/lib/utils'; -import React from 'react'; + +import { Tag, TagProps } from './tag'; import { type Tag as TagType } from './tag-input'; export type TagListProps = { diff --git a/frontend/components/ui/tag-popover.tsx b/frontend/components/ui/tag-popover.tsx index 3b1bba05..02619f89 100644 --- a/frontend/components/ui/tag-popover.tsx +++ b/frontend/components/ui/tag-popover.tsx @@ -1,12 +1,13 @@ +import React from 'react'; + import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; -import { TagList, TagListProps } from './tag-list'; -import React from 'react'; import { type Tag as TagType } from './tag-input'; +import { TagList, TagListProps } from './tag-list'; type TagPopoverProps = { children: React.ReactNode; diff --git a/frontend/components/ui/tag.tsx b/frontend/components/ui/tag.tsx index e0a9203e..92d95592 100644 --- a/frontend/components/ui/tag.tsx +++ b/frontend/components/ui/tag.tsx @@ -1,10 +1,11 @@ -import { TagInputProps,type Tag as TagType } from './tag-input'; - -import { Button } from './button'; -import { cn } from '@/lib/utils'; import { cva } from 'class-variance-authority'; import { X } from 'lucide-react'; +import { cn } from '@/lib/utils'; + +import { Button } from './button'; +import { type Tag as TagType, TagInputProps } from './tag-input'; + export const tagVariants = cva( 'transition-all border inline-flex items-center text-sm pl-2 rounded-md', { diff --git a/frontend/components/ui/text-search-filter.tsx b/frontend/components/ui/text-search-filter.tsx index b6ce4564..528a5987 100644 --- a/frontend/components/ui/text-search-filter.tsx +++ b/frontend/components/ui/text-search-filter.tsx @@ -1,11 +1,12 @@ -import { Feature, isFeatureEnabled } from '@/lib/features/features'; import { Search, X } from 'lucide-react'; -import { SyntheticEvent, useEffect, useState } from 'react'; import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import { usePostHog } from 'posthog-js/react'; +import { SyntheticEvent, useEffect, useState } from 'react'; +import { Feature, isFeatureEnabled } from '@/lib/features/features'; import { cn } from '@/lib/utils'; + import { Input } from './input'; -import { usePostHog } from 'posthog-js/react'; export default function TextSearchFilter() { const searchParams = new URLSearchParams(useSearchParams().toString()); diff --git a/frontend/components/ui/toast.tsx b/frontend/components/ui/toast.tsx index 3c2f665e..97095224 100644 --- a/frontend/components/ui/toast.tsx +++ b/frontend/components/ui/toast.tsx @@ -1,10 +1,9 @@ -import * as React from 'react'; +import { Cross2Icon } from '@radix-ui/react-icons'; import * as ToastPrimitives from '@radix-ui/react-toast'; - import { cva, type VariantProps } from 'class-variance-authority'; +import * as React from 'react'; import { cn } from '@/lib/utils'; -import { Cross2Icon } from '@radix-ui/react-icons'; const ToastProvider = ToastPrimitives.Provider; @@ -114,13 +113,12 @@ type ToastProps = React.ComponentPropsWithoutRef; type ToastActionElement = React.ReactElement; export { - type ToastProps, + Toast, + ToastAction, type ToastActionElement, + ToastClose, + ToastDescription, + type ToastProps, ToastProvider, - ToastViewport, - Toast, ToastTitle, - ToastDescription, - ToastClose, - ToastAction -}; + ToastViewport}; diff --git a/frontend/components/ui/tooltip.tsx b/frontend/components/ui/tooltip.tsx index fc73d7c5..23e6bcf3 100644 --- a/frontend/components/ui/tooltip.tsx +++ b/frontend/components/ui/tooltip.tsx @@ -1,7 +1,7 @@ 'use client'; -import * as React from 'react'; import * as TooltipPrimitive from '@radix-ui/react-tooltip'; +import * as React from 'react'; import { cn } from '@/lib/utils'; @@ -27,4 +27,4 @@ const TooltipContent = React.forwardRef< )); TooltipContent.displayName = TooltipPrimitive.Content.displayName; -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; +export { Tooltip, TooltipContent, TooltipProvider,TooltipTrigger }; diff --git a/frontend/components/user/avatar-menu.tsx b/frontend/components/user/avatar-menu.tsx index 4007178c..355b0407 100644 --- a/frontend/components/user/avatar-menu.tsx +++ b/frontend/components/user/avatar-menu.tsx @@ -1,5 +1,10 @@ 'use client'; +import Image from 'next/image'; +import { signOut } from 'next-auth/react'; + +import { useUserContext } from '@/contexts/user-context'; + import { DropdownMenu, DropdownMenuContent, @@ -7,10 +12,6 @@ import { DropdownMenuTrigger } from '../ui/dropdown-menu'; -import Image from 'next/image'; -import { signOut } from 'next-auth/react'; -import { useUserContext } from '@/contexts/user-context'; - export default function AvatarMenu() { const { imageUrl } = useUserContext(); diff --git a/frontend/components/user/presence-user-image.tsx b/frontend/components/user/presence-user-image.tsx index 012ce0ba..1db3cafc 100644 --- a/frontend/components/user/presence-user-image.tsx +++ b/frontend/components/user/presence-user-image.tsx @@ -1,11 +1,11 @@ +import Image from 'next/image'; + import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'; - -import Image from 'next/image'; import { PresenceUser } from '@/lib/user/types'; interface PresenceUserImageProps { diff --git a/frontend/components/workspace/purchase-seats-dialog.tsx b/frontend/components/workspace/purchase-seats-dialog.tsx index 636d0dc2..cdf82e1d 100644 --- a/frontend/components/workspace/purchase-seats-dialog.tsx +++ b/frontend/components/workspace/purchase-seats-dialog.tsx @@ -1,3 +1,7 @@ +import { Loader2 } from "lucide-react"; +import { useState } from "react"; + +import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, @@ -7,11 +11,8 @@ import { DialogTrigger } from '@/components/ui/dialog'; -import { Button } from "@/components/ui/button"; import { Input } from '../ui/input'; import { Label } from "../ui/label"; -import { Loader2 } from "lucide-react"; -import { useState } from "react"; interface PurchaseSeatsDialogProps { workspaceId: string; diff --git a/frontend/components/workspace/workspace-usage.tsx b/frontend/components/workspace/workspace-usage.tsx index b391cb17..ce3ccd76 100644 --- a/frontend/components/workspace/workspace-usage.tsx +++ b/frontend/components/workspace/workspace-usage.tsx @@ -1,10 +1,12 @@ -import { Button } from '../ui/button'; -import ClientTimestampFormatter from '../client-timestamp-formatter'; -import { cn } from '@/lib/utils'; import { Label } from '@radix-ui/react-label'; import { useRouter } from 'next/navigation'; -import { Workspace } from '@/lib/workspaces/types'; + import { WorkspaceStats } from '@/lib/usage/types'; +import { cn } from '@/lib/utils'; +import { Workspace } from '@/lib/workspaces/types'; + +import ClientTimestampFormatter from '../client-timestamp-formatter'; +import { Button } from '../ui/button'; interface WorkspaceUsageProps { workspace: Workspace; diff --git a/frontend/components/workspace/workspace-users.tsx b/frontend/components/workspace/workspace-users.tsx index 6bec1c14..2cbd41f9 100644 --- a/frontend/components/workspace/workspace-users.tsx +++ b/frontend/components/workspace/workspace-users.tsx @@ -1,5 +1,9 @@ 'use client'; +import { Loader2, Plus } from 'lucide-react'; +import { useRouter } from 'next/navigation'; +import { useCallback, useState } from 'react'; + import { Dialog, DialogContent, @@ -8,7 +12,14 @@ import { DialogTitle, DialogTrigger } from '@/components/ui/dialog'; -import { Loader2, Plus } from 'lucide-react'; +import { useToast } from '@/lib/hooks/use-toast'; +import { WorkspaceStats } from '@/lib/usage/types'; +import { formatTimestamp } from '@/lib/utils'; +import { WorkspaceUser, WorkspaceWithUsers } from '@/lib/workspaces/types'; + +import { Button } from '../ui/button'; +import { Input } from '../ui/input'; +import { Label } from '../ui/label'; import { Table, TableBody, @@ -23,17 +34,7 @@ import { TooltipProvider, TooltipTrigger } from '../ui/tooltip'; -import { useCallback, useState } from 'react'; -import { WorkspaceUser, WorkspaceWithUsers } from '@/lib/workspaces/types'; - -import { Button } from '../ui/button'; -import { formatTimestamp } from '@/lib/utils'; -import { Input } from '../ui/input'; -import { Label } from '../ui/label'; import PurchaseSeatsDialog from './purchase-seats-dialog'; -import { useRouter } from 'next/navigation'; -import { useToast } from '@/lib/hooks/use-toast'; -import { WorkspaceStats } from '@/lib/usage/types'; interface WorkspaceUsersProps { workspace: WorkspaceWithUsers; diff --git a/frontend/components/workspace/workspace.tsx b/frontend/components/workspace/workspace.tsx index 55e6ae0e..d3be930a 100644 --- a/frontend/components/workspace/workspace.tsx +++ b/frontend/components/workspace/workspace.tsx @@ -1,11 +1,11 @@ 'use client'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; - import { WorkspaceStats } from '@/lib/usage/types'; +import { WorkspaceWithUsers } from '@/lib/workspaces/types'; + +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../ui/tabs'; import WorkspaceUsage from './workspace-usage'; import WorkspaceUsers from './workspace-users'; -import { WorkspaceWithUsers } from '@/lib/workspaces/types'; interface WorkspaceProps { workspace: WorkspaceWithUsers; diff --git a/frontend/lib/auth.ts b/frontend/lib/auth.ts index a7de6678..32fd8352 100644 --- a/frontend/lib/auth.ts +++ b/frontend/lib/auth.ts @@ -1,12 +1,12 @@ +import jwt from 'jsonwebtoken'; import type { DefaultSession, NextAuthOptions, User } from 'next-auth'; -import { Feature, isFeatureEnabled } from './features/features'; - import CredentialsProvider from 'next-auth/providers/credentials'; -import { fetcher } from './utils'; import GithubProvider from 'next-auth/providers/github'; import GoogleProvider from 'next-auth/providers/google'; -import jwt from 'jsonwebtoken'; + import { sendWelcomeEmail } from './emails/utils'; +import { Feature, isFeatureEnabled } from './features/features'; +import { fetcher } from './utils'; declare module 'next-auth' { interface Session { diff --git a/frontend/lib/blog/utils.ts b/frontend/lib/blog/utils.ts index fed06a94..a4b7fa99 100644 --- a/frontend/lib/blog/utils.ts +++ b/frontend/lib/blog/utils.ts @@ -1,8 +1,9 @@ -import { BlogListItem, MatterAndContent } from "./types"; import fs from "fs"; import matter from "gray-matter"; import path from "path"; +import { BlogListItem, MatterAndContent } from "./types"; + const BLOG_DIR = path.join(process.cwd(), "assets/blog"); export const getBlogPosts = ({ diff --git a/frontend/lib/clickhouse/client.ts b/frontend/lib/clickhouse/client.ts index 2670bc81..19d1d16b 100644 --- a/frontend/lib/clickhouse/client.ts +++ b/frontend/lib/clickhouse/client.ts @@ -1,5 +1,5 @@ -import { config } from "dotenv"; import { createClient } from "@clickhouse/client"; +import { config } from "dotenv"; config({ path: ".env" }); // or .env.local diff --git a/frontend/lib/clickhouse/evaluation-scores.ts b/frontend/lib/clickhouse/evaluation-scores.ts index 05220fcb..b5bac59a 100644 --- a/frontend/lib/clickhouse/evaluation-scores.ts +++ b/frontend/lib/clickhouse/evaluation-scores.ts @@ -1,8 +1,8 @@ -import { addTimeRangeToQuery, AggregationFunction, aggregationFunctionToCh, TimeRange } from "./utils"; -import { Feature, isFeatureEnabled } from "../features/features"; - import { ClickHouseClient } from "@clickhouse/client"; + import { EvaluationTimeProgression } from "../evaluation/types"; +import { Feature, isFeatureEnabled } from "../features/features"; +import { addTimeRangeToQuery, AggregationFunction, aggregationFunctionToCh, TimeRange } from "./utils"; export const getEvaluationTimeProgression = async ( clickhouseClient: ClickHouseClient, diff --git a/frontend/lib/clickhouse/spans.ts b/frontend/lib/clickhouse/spans.ts index 91f55502..930062de 100644 --- a/frontend/lib/clickhouse/spans.ts +++ b/frontend/lib/clickhouse/spans.ts @@ -1,3 +1,7 @@ +import { ClickHouseClient } from "@clickhouse/client"; + +import { Feature, isFeatureEnabled } from "../features/features"; +import { GroupByInterval, truncateTimeMap } from "./modifiers"; import { addTimeRangeToQuery, AggregationFunction, @@ -7,10 +11,6 @@ import { groupByTimeRelativeStatement, TimeRange } from "./utils"; -import { Feature, isFeatureEnabled } from "../features/features"; -import { GroupByInterval, truncateTimeMap } from "./modifiers"; - -import { ClickHouseClient } from "@clickhouse/client"; export enum SpanMetricGroupBy { Model = 'model', diff --git a/frontend/lib/clickhouse/utils.ts b/frontend/lib/clickhouse/utils.ts index d270c8ac..a0232ed9 100644 --- a/frontend/lib/clickhouse/utils.ts +++ b/frontend/lib/clickhouse/utils.ts @@ -1,7 +1,7 @@ -import { chStepMap, GroupByInterval, intervalMap, truncateTimeMap } from "./modifiers"; - import { ClickHouseClient } from "@clickhouse/client"; +import { chStepMap, GroupByInterval, intervalMap, truncateTimeMap } from "./modifiers"; + interface TimeBounds { minTime: number; maxTime: number; diff --git a/frontend/lib/db/drizzle.ts b/frontend/lib/db/drizzle.ts index 315a9bc2..06d2c81c 100644 --- a/frontend/lib/db/drizzle.ts +++ b/frontend/lib/db/drizzle.ts @@ -1,10 +1,10 @@ -import * as relations from './migrations/relations'; -import * as schema from './migrations/schema'; - import { config } from "dotenv"; import { drizzle } from 'drizzle-orm/postgres-js'; import postgres from 'postgres'; +import * as relations from './migrations/relations'; +import * as schema from './migrations/schema'; + config({ path: ".env" }); // or .env.local // Singleton function to ensure only one db instance is created diff --git a/frontend/lib/db/migrations/0010_brainy_wild_child.sql b/frontend/lib/db/migrations/0010_brainy_wild_child.sql new file mode 100644 index 00000000..9fcb8820 --- /dev/null +++ b/frontend/lib/db/migrations/0010_brainy_wild_child.sql @@ -0,0 +1,36 @@ +CREATE TABLE IF NOT EXISTS "old_events" ( + "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, + "created_at" timestamp with time zone DEFAULT now() NOT NULL, + "span_id" uuid NOT NULL, + "timestamp" timestamp with time zone NOT NULL, + "template_id" uuid NOT NULL, + "source" "event_source" NOT NULL, + "metadata" jsonb, + "value" jsonb NOT NULL, + "data" text, + "inputs" jsonb +); +--> statement-breakpoint +ALTER TABLE "events" DROP CONSTRAINT "events_template_id_fkey"; +--> statement-breakpoint +ALTER TABLE "events" ADD COLUMN "name" text NOT NULL;--> statement-breakpoint +ALTER TABLE "events" ADD COLUMN "attributes" jsonb DEFAULT '{}'::jsonb NOT NULL;--> statement-breakpoint +ALTER TABLE "events" ADD COLUMN "project_id" uuid NOT NULL;--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "old_events" ADD CONSTRAINT "events_template_id_fkey" FOREIGN KEY ("template_id") REFERENCES "public"."event_templates"("id") ON DELETE cascade ON UPDATE cascade; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +DO $$ BEGIN + ALTER TABLE "events" ADD CONSTRAINT "events_span_id_project_id_fkey" FOREIGN KEY ("span_id","project_id") REFERENCES "public"."spans"("span_id","project_id") ON DELETE cascade ON UPDATE cascade; +EXCEPTION + WHEN duplicate_object THEN null; +END $$; +--> statement-breakpoint +ALTER TABLE "events" DROP COLUMN IF EXISTS "template_id";--> statement-breakpoint +ALTER TABLE "events" DROP COLUMN IF EXISTS "source";--> statement-breakpoint +ALTER TABLE "events" DROP COLUMN IF EXISTS "metadata";--> statement-breakpoint +ALTER TABLE "events" DROP COLUMN IF EXISTS "value";--> statement-breakpoint +ALTER TABLE "events" DROP COLUMN IF EXISTS "data";--> statement-breakpoint +ALTER TABLE "events" DROP COLUMN IF EXISTS "inputs"; \ No newline at end of file diff --git a/frontend/lib/db/migrations/0011_bitter_daimon_hellstrom.sql b/frontend/lib/db/migrations/0011_bitter_daimon_hellstrom.sql new file mode 100644 index 00000000..86f27cab --- /dev/null +++ b/frontend/lib/db/migrations/0011_bitter_daimon_hellstrom.sql @@ -0,0 +1,4 @@ +DROP TABLE "event_templates" CASCADE;--> statement-breakpoint +DROP TABLE "old_events" CASCADE;--> statement-breakpoint +DROP TYPE "public"."event_source";--> statement-breakpoint +DROP TYPE "public"."event_type"; \ No newline at end of file diff --git a/frontend/lib/db/migrations/meta/0010_snapshot.json b/frontend/lib/db/migrations/meta/0010_snapshot.json new file mode 100644 index 00000000..b8a27591 --- /dev/null +++ b/frontend/lib/db/migrations/meta/0010_snapshot.json @@ -0,0 +1,2972 @@ +{ + "id": "54626aba-1a4f-46b5-882e-4fdf77a4ed31", + "prevId": "cf70f2bb-cf48-4086-9e5f-89f138e79138", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.api_keys": { + "name": "api_keys", + "schema": "", + "columns": { + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + } + }, + "indexes": { + "api_keys_user_id_idx": { + "name": "api_keys_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_user_id_fkey": { + "name": "api_keys_user_id_fkey", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "Enable insert for authenticated users only": { + "name": "Enable insert for authenticated users only", + "as": "PERMISSIVE", + "for": "ALL", + "to": [ + "service_role" + ], + "using": "true", + "withCheck": "true" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.datapoint_to_span": { + "name": "datapoint_to_span", + "schema": "", + "columns": { + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "datapoint_id": { + "name": "datapoint_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "datapoint_to_span_datapoint_id_fkey": { + "name": "datapoint_to_span_datapoint_id_fkey", + "tableFrom": "datapoint_to_span", + "tableTo": "dataset_datapoints", + "columnsFrom": [ + "datapoint_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "datapoint_to_span_span_id_project_id_fkey": { + "name": "datapoint_to_span_span_id_project_id_fkey", + "tableFrom": "datapoint_to_span", + "tableTo": "spans", + "columnsFrom": [ + "span_id", + "project_id" + ], + "columnsTo": [ + "span_id", + "project_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "datapoint_to_span_pkey": { + "name": "datapoint_to_span_pkey", + "columns": [ + "datapoint_id", + "span_id", + "project_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dataset_datapoints": { + "name": "dataset_datapoints", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "dataset_id": { + "name": "dataset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "indexed_on": { + "name": "indexed_on", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target": { + "name": "target", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "index_in_batch": { + "name": "index_in_batch", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "dataset_datapoints_dataset_id_fkey": { + "name": "dataset_datapoints_dataset_id_fkey", + "tableFrom": "dataset_datapoints", + "tableTo": "datasets", + "columnsFrom": [ + "dataset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.datasets": { + "name": "datasets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "indexed_on": { + "name": "indexed_on", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "public_datasets_project_id_fkey": { + "name": "public_datasets_project_id_fkey", + "tableFrom": "datasets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.evaluation_results": { + "name": "evaluation_results", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "evaluation_id": { + "name": "evaluation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "target": { + "name": "target", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "executor_output": { + "name": "executor_output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "index_in_batch": { + "name": "index_in_batch", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "trace_id": { + "name": "trace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "evaluation_results_evaluation_id_idx": { + "name": "evaluation_results_evaluation_id_idx", + "columns": [ + { + "expression": "evaluation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "evaluation_results_evaluation_id_fkey1": { + "name": "evaluation_results_evaluation_id_fkey1", + "tableFrom": "evaluation_results", + "tableTo": "evaluations", + "columnsFrom": [ + "evaluation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "select_by_next_api_key": { + "name": "select_by_next_api_key", + "as": "PERMISSIVE", + "for": "SELECT", + "to": [ + "anon", + "authenticated" + ], + "using": "is_evaluation_id_accessible_for_api_key(api_key(), evaluation_id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.evaluation_scores": { + "name": "evaluation_scores", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "result_id": { + "name": "result_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "score": { + "name": "score", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "label_id": { + "name": "label_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "evaluation_scores_result_id_idx": { + "name": "evaluation_scores_result_id_idx", + "columns": [ + { + "expression": "result_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hash", + "with": {} + } + }, + "foreignKeys": { + "evaluation_scores_result_id_fkey": { + "name": "evaluation_scores_result_id_fkey", + "tableFrom": "evaluation_scores", + "tableTo": "evaluation_results", + "columnsFrom": [ + "result_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "evaluation_results_names_unique": { + "name": "evaluation_results_names_unique", + "nullsNotDistinct": false, + "columns": [ + "result_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.evaluations": { + "name": "evaluations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + } + }, + "indexes": {}, + "foreignKeys": { + "evaluations_project_id_fkey1": { + "name": "evaluations_project_id_fkey1", + "tableFrom": "evaluations", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "select_by_next_api_key": { + "name": "select_by_next_api_key", + "as": "PERMISSIVE", + "for": "SELECT", + "to": [ + "anon", + "authenticated" + ], + "using": "is_evaluation_id_accessible_for_api_key(api_key(), id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.event_templates": { + "name": "event_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'BOOLEAN'" + } + }, + "indexes": {}, + "foreignKeys": { + "event_templates_project_id_fkey": { + "name": "event_templates_project_id_fkey", + "tableFrom": "event_templates", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_name_project_id": { + "name": "unique_name_project_id", + "nullsNotDistinct": false, + "columns": [ + "name", + "project_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "events_span_id_project_id_fkey": { + "name": "events_span_id_project_id_fkey", + "tableFrom": "events", + "tableTo": "spans", + "columnsFrom": [ + "span_id", + "project_id" + ], + "columnsTo": [ + "span_id", + "project_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_classes": { + "name": "label_classes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "label_type": { + "name": "label_type", + "type": "label_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value_map": { + "name": "value_map", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[false,true]'::jsonb" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "evaluator_runnable_graph": { + "name": "evaluator_runnable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "pipeline_version_id": { + "name": "pipeline_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "label_classes_project_id_fkey": { + "name": "label_classes_project_id_fkey", + "tableFrom": "label_classes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_classes_for_path": { + "name": "label_classes_for_path", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label_class_id": { + "name": "label_class_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "autoeval_labels_project_id_fkey": { + "name": "autoeval_labels_project_id_fkey", + "tableFrom": "label_classes_for_path", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_project_id_path_label_class": { + "name": "unique_project_id_path_label_class", + "nullsNotDistinct": false, + "columns": [ + "project_id", + "path", + "label_class_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.labeling_queue_items": { + "name": "labeling_queue_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "queue_id": { + "name": "queue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "labelling_queue_items_queue_id_fkey": { + "name": "labelling_queue_items_queue_id_fkey", + "tableFrom": "labeling_queue_items", + "tableTo": "labeling_queues", + "columnsFrom": [ + "queue_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.labeling_queues": { + "name": "labeling_queues", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "labeling_queues_project_id_fkey": { + "name": "labeling_queues_project_id_fkey", + "tableFrom": "labeling_queues", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.labels": { + "name": "labels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "class_id": { + "name": "class_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + }, + "label_source": { + "name": "label_source", + "type": "label_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'MANUAL'" + }, + "reasoning": { + "name": "reasoning", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "trace_tags_type_id_fkey": { + "name": "trace_tags_type_id_fkey", + "tableFrom": "labels", + "tableTo": "label_classes", + "columnsFrom": [ + "class_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "labels_span_id_class_id_user_id_key": { + "name": "labels_span_id_class_id_user_id_key", + "nullsNotDistinct": false, + "columns": [ + "class_id", + "span_id", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.llm_prices": { + "name": "llm_prices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "input_price_per_million": { + "name": "input_price_per_million", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "output_price_per_million": { + "name": "output_price_per_million", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "input_cached_price_per_million": { + "name": "input_cached_price_per_million", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "additional_prices": { + "name": "additional_prices", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.members_of_workspaces": { + "name": "members_of_workspaces", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_role": { + "name": "member_role", + "type": "workspace_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'owner'" + } + }, + "indexes": { + "members_of_workspaces_user_id_idx": { + "name": "members_of_workspaces_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "members_of_workspaces_user_id_fkey": { + "name": "members_of_workspaces_user_id_fkey", + "tableFrom": "members_of_workspaces", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "public_members_of_workspaces_workspace_id_fkey": { + "name": "public_members_of_workspaces_workspace_id_fkey", + "tableFrom": "members_of_workspaces", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "members_of_workspaces_user_workspace_unique": { + "name": "members_of_workspaces_user_workspace_unique", + "nullsNotDistinct": false, + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.old_events": { + "name": "old_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "event_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "value": { + "name": "value", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "inputs": { + "name": "inputs", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "events_template_id_fkey": { + "name": "events_template_id_fkey", + "tableFrom": "old_events", + "tableTo": "event_templates", + "columnsFrom": [ + "template_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipeline_templates": { + "name": "pipeline_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "runnable_graph": { + "name": "runnable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "displayable_graph": { + "name": "displayable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "number_of_nodes": { + "name": "number_of_nodes", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "display_group": { + "name": "display_group", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'build'" + }, + "ordinal": { + "name": "ordinal", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 500 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipeline_versions": { + "name": "pipeline_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "pipeline_id": { + "name": "pipeline_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "displayable_graph": { + "name": "displayable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "runnable_graph": { + "name": "runnable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "pipeline_type": { + "name": "pipeline_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "all_actions_by_next_api_key": { + "name": "all_actions_by_next_api_key", + "as": "PERMISSIVE", + "for": "ALL", + "to": [ + "anon", + "authenticated" + ], + "using": "is_pipeline_id_accessible_for_api_key(api_key(), pipeline_id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipelines": { + "name": "pipelines", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'PRIVATE'" + }, + "python_requirements": { + "name": "python_requirements", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": { + "pipelines_name_project_id_idx": { + "name": "pipelines_name_project_id_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "pipelines_project_id_idx": { + "name": "pipelines_project_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "pipelines_project_id_fkey": { + "name": "pipelines_project_id_fkey", + "tableFrom": "pipelines", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_project_id_pipeline_name": { + "name": "unique_project_id_pipeline_name", + "nullsNotDistinct": false, + "columns": [ + "project_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.playgrounds": { + "name": "playgrounds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "prompt_messages": { + "name": "prompt_messages", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[{\"role\":\"user\",\"content\":\"\"}]'::jsonb" + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "output_schema": { + "name": "output_schema", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "playgrounds_project_id_fkey": { + "name": "playgrounds_project_id_fkey", + "tableFrom": "playgrounds", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project_api_keys": { + "name": "project_api_keys", + "schema": "", + "columns": { + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shorthand": { + "name": "shorthand", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": { + "public_project_api_keys_project_id_fkey": { + "name": "public_project_api_keys_project_id_fkey", + "tableFrom": "project_api_keys", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "projects_workspace_id_idx": { + "name": "projects_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_fkey": { + "name": "projects_workspace_id_fkey", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.provider_api_keys": { + "name": "provider_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "nonce_hex": { + "name": "nonce_hex", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "provider_api_keys_project_id_fkey": { + "name": "provider_api_keys_project_id_fkey", + "tableFrom": "provider_api_keys", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.spans": { + "name": "spans", + "schema": "", + "columns": { + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "parent_span_id": { + "name": "parent_span_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "span_type": { + "name": "span_type", + "type": "span_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_time": { + "name": "end_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "trace_id": { + "name": "trace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "input_preview": { + "name": "input_preview", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "output_preview": { + "name": "output_preview", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "span_path_idx": { + "name": "span_path_idx", + "columns": [ + { + "expression": "(attributes -> 'lmnr.span.path'::text)", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_project_id_idx": { + "name": "spans_project_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hash", + "with": {} + }, + "spans_project_id_trace_id_start_time_idx": { + "name": "spans_project_id_trace_id_start_time_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_root_project_id_start_time_end_time_trace_id_idx": { + "name": "spans_root_project_id_start_time_end_time_trace_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "(parent_span_id IS NULL)", + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_start_time_end_time_idx": { + "name": "spans_start_time_end_time_idx", + "columns": [ + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_trace_id_idx": { + "name": "spans_trace_id_idx", + "columns": [ + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_trace_id_start_time_idx": { + "name": "spans_trace_id_start_time_idx", + "columns": [ + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "new_spans_trace_id_fkey": { + "name": "new_spans_trace_id_fkey", + "tableFrom": "spans", + "tableTo": "traces", + "columnsFrom": [ + "trace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "spans_project_id_fkey": { + "name": "spans_project_id_fkey", + "tableFrom": "spans", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "spans_pkey": { + "name": "spans_pkey", + "columns": [ + "span_id", + "project_id" + ] + } + }, + "uniqueConstraints": { + "unique_span_id_project_id": { + "name": "unique_span_id_project_id", + "nullsNotDistinct": false, + "columns": [ + "span_id", + "project_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.subscription_tiers": { + "name": "subscription_tiers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigint", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "subscription_tiers_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854776000", + "cache": "1", + "cycle": false + } + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_mib": { + "name": "storage_mib", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "log_retention_days": { + "name": "log_retention_days", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "members_per_workspace": { + "name": "members_per_workspace", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'-1'" + }, + "num_workspaces": { + "name": "num_workspaces", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'-1'" + }, + "stripe_product_id": { + "name": "stripe_product_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "events": { + "name": "events", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "spans": { + "name": "spans", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "extra_span_price": { + "name": "extra_span_price", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "extra_event_price": { + "name": "extra_event_price", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.target_pipeline_versions": { + "name": "target_pipeline_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "pipeline_id": { + "name": "pipeline_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "pipeline_version_id": { + "name": "pipeline_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "target_pipeline_versions_pipeline_id_fkey": { + "name": "target_pipeline_versions_pipeline_id_fkey", + "tableFrom": "target_pipeline_versions", + "tableTo": "pipelines", + "columnsFrom": [ + "pipeline_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "target_pipeline_versions_pipeline_version_id_fkey": { + "name": "target_pipeline_versions_pipeline_version_id_fkey", + "tableFrom": "target_pipeline_versions", + "tableTo": "pipeline_versions", + "columnsFrom": [ + "pipeline_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_pipeline_id": { + "name": "unique_pipeline_id", + "nullsNotDistinct": false, + "columns": [ + "pipeline_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.traces": { + "name": "traces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "end_time": { + "name": "end_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "total_token_count": { + "name": "total_token_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "cost": { + "name": "cost", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "trace_type": { + "name": "trace_type", + "type": "trace_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DEFAULT'" + }, + "input_token_count": { + "name": "input_token_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "output_token_count": { + "name": "output_token_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "input_cost": { + "name": "input_cost", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "output_cost": { + "name": "output_cost", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": { + "trace_metadata_gin_idx": { + "name": "trace_metadata_gin_idx", + "columns": [ + { + "expression": "metadata", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "traces_id_project_id_start_time_times_not_null_idx": { + "name": "traces_id_project_id_start_time_times_not_null_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": false, + "nulls": "first" + } + ], + "isUnique": false, + "where": "((start_time IS NOT NULL) AND (end_time IS NOT NULL))", + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_project_id_idx": { + "name": "traces_project_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_project_id_trace_type_start_time_end_time_idx": { + "name": "traces_project_id_trace_type_start_time_end_time_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "((trace_type = 'DEFAULT'::trace_type) AND (start_time IS NOT NULL) AND (end_time IS NOT NULL))", + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_session_id_idx": { + "name": "traces_session_id_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_start_time_end_time_idx": { + "name": "traces_start_time_end_time_idx", + "columns": [ + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "new_traces_project_id_fkey": { + "name": "new_traces_project_id_fkey", + "tableFrom": "traces", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "select_by_next_api_key": { + "name": "select_by_next_api_key", + "as": "PERMISSIVE", + "for": "SELECT", + "to": [ + "anon", + "authenticated" + ], + "using": "is_trace_id_accessible_for_api_key(api_key(), id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_subscription_info": { + "name": "user_subscription_info", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "activated": { + "name": "activated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "user_subscription_info_stripe_customer_id_idx": { + "name": "user_subscription_info_stripe_customer_id_idx", + "columns": [ + { + "expression": "stripe_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_subscription_info_fkey": { + "name": "user_subscription_info_fkey", + "tableFrom": "user_subscription_info", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_key": { + "name": "users_email_key", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": { + "Enable insert for authenticated users only": { + "name": "Enable insert for authenticated users only", + "as": "PERMISSIVE", + "for": "INSERT", + "to": [ + "service_role" + ], + "withCheck": "true" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_usage": { + "name": "workspace_usage", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "span_count": { + "name": "span_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "span_count_since_reset": { + "name": "span_count_since_reset", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "prev_span_count": { + "name": "prev_span_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "event_count": { + "name": "event_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "event_count_since_reset": { + "name": "event_count_since_reset", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "prev_event_count": { + "name": "prev_event_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "reset_time": { + "name": "reset_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "reset_reason": { + "name": "reset_reason", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'signup'" + } + }, + "indexes": {}, + "foreignKeys": { + "user_usage_workspace_id_fkey": { + "name": "user_usage_workspace_id_fkey", + "tableFrom": "workspace_usage", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_usage_workspace_id_key": { + "name": "user_usage_workspace_id_key", + "nullsNotDistinct": false, + "columns": [ + "workspace_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tier_id": { + "name": "tier_id", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'1'" + }, + "subscription_id": { + "name": "subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "additional_seats": { + "name": "additional_seats", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_tier_id_fkey": { + "name": "workspaces_tier_id_fkey", + "tableFrom": "workspaces", + "tableTo": "subscription_tiers", + "columnsFrom": [ + "tier_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.event_source": { + "name": "event_source", + "schema": "public", + "values": [ + "AUTO", + "MANUAL", + "CODE" + ] + }, + "public.event_type": { + "name": "event_type", + "schema": "public", + "values": [ + "BOOLEAN", + "STRING", + "NUMBER" + ] + }, + "public.label_source": { + "name": "label_source", + "schema": "public", + "values": [ + "MANUAL", + "AUTO", + "CODE" + ] + }, + "public.label_type": { + "name": "label_type", + "schema": "public", + "values": [ + "BOOLEAN", + "CATEGORICAL" + ] + }, + "public.span_type": { + "name": "span_type", + "schema": "public", + "values": [ + "DEFAULT", + "LLM", + "PIPELINE", + "EXECUTOR", + "EVALUATOR", + "EVALUATION" + ] + }, + "public.trace_type": { + "name": "trace_type", + "schema": "public", + "values": [ + "DEFAULT", + "EVENT", + "EVALUATION" + ] + }, + "public.workspace_role": { + "name": "workspace_role", + "schema": "public", + "values": [ + "member", + "owner" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/frontend/lib/db/migrations/meta/0011_snapshot.json b/frontend/lib/db/migrations/meta/0011_snapshot.json new file mode 100644 index 00000000..d33a90b8 --- /dev/null +++ b/frontend/lib/db/migrations/meta/0011_snapshot.json @@ -0,0 +1,2794 @@ +{ + "id": "da8c961c-1545-4d4d-afcf-25d310101393", + "prevId": "54626aba-1a4f-46b5-882e-4fdf77a4ed31", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.api_keys": { + "name": "api_keys", + "schema": "", + "columns": { + "api_key": { + "name": "api_key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + } + }, + "indexes": { + "api_keys_user_id_idx": { + "name": "api_keys_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "api_keys_user_id_fkey": { + "name": "api_keys_user_id_fkey", + "tableFrom": "api_keys", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "Enable insert for authenticated users only": { + "name": "Enable insert for authenticated users only", + "as": "PERMISSIVE", + "for": "ALL", + "to": [ + "service_role" + ], + "using": "true", + "withCheck": "true" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.datapoint_to_span": { + "name": "datapoint_to_span", + "schema": "", + "columns": { + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "datapoint_id": { + "name": "datapoint_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "datapoint_to_span_datapoint_id_fkey": { + "name": "datapoint_to_span_datapoint_id_fkey", + "tableFrom": "datapoint_to_span", + "tableTo": "dataset_datapoints", + "columnsFrom": [ + "datapoint_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "datapoint_to_span_span_id_project_id_fkey": { + "name": "datapoint_to_span_span_id_project_id_fkey", + "tableFrom": "datapoint_to_span", + "tableTo": "spans", + "columnsFrom": [ + "span_id", + "project_id" + ], + "columnsTo": [ + "span_id", + "project_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "datapoint_to_span_pkey": { + "name": "datapoint_to_span_pkey", + "columns": [ + "datapoint_id", + "span_id", + "project_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dataset_datapoints": { + "name": "dataset_datapoints", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "dataset_id": { + "name": "dataset_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "indexed_on": { + "name": "indexed_on", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target": { + "name": "target", + "type": "jsonb", + "primaryKey": false, + "notNull": false, + "default": "'{}'::jsonb" + }, + "index_in_batch": { + "name": "index_in_batch", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "dataset_datapoints_dataset_id_fkey": { + "name": "dataset_datapoints_dataset_id_fkey", + "tableFrom": "dataset_datapoints", + "tableTo": "datasets", + "columnsFrom": [ + "dataset_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.datasets": { + "name": "datasets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "indexed_on": { + "name": "indexed_on", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "public_datasets_project_id_fkey": { + "name": "public_datasets_project_id_fkey", + "tableFrom": "datasets", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.evaluation_results": { + "name": "evaluation_results", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "evaluation_id": { + "name": "evaluation_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "target": { + "name": "target", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "executor_output": { + "name": "executor_output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "index_in_batch": { + "name": "index_in_batch", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "trace_id": { + "name": "trace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "evaluation_results_evaluation_id_idx": { + "name": "evaluation_results_evaluation_id_idx", + "columns": [ + { + "expression": "evaluation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "evaluation_results_evaluation_id_fkey1": { + "name": "evaluation_results_evaluation_id_fkey1", + "tableFrom": "evaluation_results", + "tableTo": "evaluations", + "columnsFrom": [ + "evaluation_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "select_by_next_api_key": { + "name": "select_by_next_api_key", + "as": "PERMISSIVE", + "for": "SELECT", + "to": [ + "anon", + "authenticated" + ], + "using": "is_evaluation_id_accessible_for_api_key(api_key(), evaluation_id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.evaluation_scores": { + "name": "evaluation_scores", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "result_id": { + "name": "result_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "score": { + "name": "score", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "label_id": { + "name": "label_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "evaluation_scores_result_id_idx": { + "name": "evaluation_scores_result_id_idx", + "columns": [ + { + "expression": "result_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hash", + "with": {} + } + }, + "foreignKeys": { + "evaluation_scores_result_id_fkey": { + "name": "evaluation_scores_result_id_fkey", + "tableFrom": "evaluation_scores", + "tableTo": "evaluation_results", + "columnsFrom": [ + "result_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "evaluation_results_names_unique": { + "name": "evaluation_results_names_unique", + "nullsNotDistinct": false, + "columns": [ + "result_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.evaluations": { + "name": "evaluations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + } + }, + "indexes": {}, + "foreignKeys": { + "evaluations_project_id_fkey1": { + "name": "evaluations_project_id_fkey1", + "tableFrom": "evaluations", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "select_by_next_api_key": { + "name": "select_by_next_api_key", + "as": "PERMISSIVE", + "for": "SELECT", + "to": [ + "anon", + "authenticated" + ], + "using": "is_evaluation_id_accessible_for_api_key(api_key(), id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.events": { + "name": "events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "timestamp": { + "name": "timestamp", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "events_span_id_project_id_fkey": { + "name": "events_span_id_project_id_fkey", + "tableFrom": "events", + "tableTo": "spans", + "columnsFrom": [ + "span_id", + "project_id" + ], + "columnsTo": [ + "span_id", + "project_id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_classes": { + "name": "label_classes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "label_type": { + "name": "label_type", + "type": "label_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value_map": { + "name": "value_map", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[false,true]'::jsonb" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "evaluator_runnable_graph": { + "name": "evaluator_runnable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "pipeline_version_id": { + "name": "pipeline_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "label_classes_project_id_fkey": { + "name": "label_classes_project_id_fkey", + "tableFrom": "label_classes", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_classes_for_path": { + "name": "label_classes_for_path", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label_class_id": { + "name": "label_class_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "autoeval_labels_project_id_fkey": { + "name": "autoeval_labels_project_id_fkey", + "tableFrom": "label_classes_for_path", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_project_id_path_label_class": { + "name": "unique_project_id_path_label_class", + "nullsNotDistinct": false, + "columns": [ + "project_id", + "path", + "label_class_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.labeling_queue_items": { + "name": "labeling_queue_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "queue_id": { + "name": "queue_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "action": { + "name": "action", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "labelling_queue_items_queue_id_fkey": { + "name": "labelling_queue_items_queue_id_fkey", + "tableFrom": "labeling_queue_items", + "tableTo": "labeling_queues", + "columnsFrom": [ + "queue_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.labeling_queues": { + "name": "labeling_queues", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "labeling_queues_project_id_fkey": { + "name": "labeling_queues_project_id_fkey", + "tableFrom": "labeling_queues", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.labels": { + "name": "labels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "class_id": { + "name": "class_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false, + "default": "gen_random_uuid()" + }, + "label_source": { + "name": "label_source", + "type": "label_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'MANUAL'" + }, + "reasoning": { + "name": "reasoning", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "trace_tags_type_id_fkey": { + "name": "trace_tags_type_id_fkey", + "tableFrom": "labels", + "tableTo": "label_classes", + "columnsFrom": [ + "class_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "labels_span_id_class_id_user_id_key": { + "name": "labels_span_id_class_id_user_id_key", + "nullsNotDistinct": false, + "columns": [ + "class_id", + "span_id", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.llm_prices": { + "name": "llm_prices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "input_price_per_million": { + "name": "input_price_per_million", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "output_price_per_million": { + "name": "output_price_per_million", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "input_cached_price_per_million": { + "name": "input_cached_price_per_million", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "additional_prices": { + "name": "additional_prices", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.members_of_workspaces": { + "name": "members_of_workspaces", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "member_role": { + "name": "member_role", + "type": "workspace_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'owner'" + } + }, + "indexes": { + "members_of_workspaces_user_id_idx": { + "name": "members_of_workspaces_user_id_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "members_of_workspaces_user_id_fkey": { + "name": "members_of_workspaces_user_id_fkey", + "tableFrom": "members_of_workspaces", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "public_members_of_workspaces_workspace_id_fkey": { + "name": "public_members_of_workspaces_workspace_id_fkey", + "tableFrom": "members_of_workspaces", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "members_of_workspaces_user_workspace_unique": { + "name": "members_of_workspaces_user_workspace_unique", + "nullsNotDistinct": false, + "columns": [ + "workspace_id", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipeline_templates": { + "name": "pipeline_templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "runnable_graph": { + "name": "runnable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "displayable_graph": { + "name": "displayable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "number_of_nodes": { + "name": "number_of_nodes", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "display_group": { + "name": "display_group", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'build'" + }, + "ordinal": { + "name": "ordinal", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 500 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipeline_versions": { + "name": "pipeline_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "pipeline_id": { + "name": "pipeline_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "displayable_graph": { + "name": "displayable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "runnable_graph": { + "name": "runnable_graph", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "pipeline_type": { + "name": "pipeline_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "all_actions_by_next_api_key": { + "name": "all_actions_by_next_api_key", + "as": "PERMISSIVE", + "for": "ALL", + "to": [ + "anon", + "authenticated" + ], + "using": "is_pipeline_id_accessible_for_api_key(api_key(), pipeline_id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.pipelines": { + "name": "pipelines", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'PRIVATE'" + }, + "python_requirements": { + "name": "python_requirements", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": { + "pipelines_name_project_id_idx": { + "name": "pipelines_name_project_id_idx", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "pipelines_project_id_idx": { + "name": "pipelines_project_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "pipelines_project_id_fkey": { + "name": "pipelines_project_id_fkey", + "tableFrom": "pipelines", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_project_id_pipeline_name": { + "name": "unique_project_id_pipeline_name", + "nullsNotDistinct": false, + "columns": [ + "project_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.playgrounds": { + "name": "playgrounds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "prompt_messages": { + "name": "prompt_messages", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[{\"role\":\"user\",\"content\":\"\"}]'::jsonb" + }, + "model_id": { + "name": "model_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "output_schema": { + "name": "output_schema", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "playgrounds_project_id_fkey": { + "name": "playgrounds_project_id_fkey", + "tableFrom": "playgrounds", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project_api_keys": { + "name": "project_api_keys", + "schema": "", + "columns": { + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "shorthand": { + "name": "shorthand", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + } + }, + "indexes": {}, + "foreignKeys": { + "public_project_api_keys_project_id_fkey": { + "name": "public_project_api_keys_project_id_fkey", + "tableFrom": "project_api_keys", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.projects": { + "name": "projects", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "projects_workspace_id_idx": { + "name": "projects_workspace_id_idx", + "columns": [ + { + "expression": "workspace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "projects_workspace_id_fkey": { + "name": "projects_workspace_id_fkey", + "tableFrom": "projects", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.provider_api_keys": { + "name": "provider_api_keys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "gen_random_uuid()" + }, + "nonce_hex": { + "name": "nonce_hex", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "provider_api_keys_project_id_fkey": { + "name": "provider_api_keys_project_id_fkey", + "tableFrom": "provider_api_keys", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.spans": { + "name": "spans", + "schema": "", + "columns": { + "span_id": { + "name": "span_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "parent_span_id": { + "name": "parent_span_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "input": { + "name": "input", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "span_type": { + "name": "span_type", + "type": "span_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "start_time": { + "name": "start_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_time": { + "name": "end_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "trace_id": { + "name": "trace_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "input_preview": { + "name": "input_preview", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "output_preview": { + "name": "output_preview", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "span_path_idx": { + "name": "span_path_idx", + "columns": [ + { + "expression": "(attributes -> 'lmnr.span.path'::text)", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_project_id_idx": { + "name": "spans_project_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "hash", + "with": {} + }, + "spans_project_id_trace_id_start_time_idx": { + "name": "spans_project_id_trace_id_start_time_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_root_project_id_start_time_end_time_trace_id_idx": { + "name": "spans_root_project_id_start_time_end_time_trace_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "(parent_span_id IS NULL)", + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_start_time_end_time_idx": { + "name": "spans_start_time_end_time_idx", + "columns": [ + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_trace_id_idx": { + "name": "spans_trace_id_idx", + "columns": [ + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "spans_trace_id_start_time_idx": { + "name": "spans_trace_id_start_time_idx", + "columns": [ + { + "expression": "trace_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "new_spans_trace_id_fkey": { + "name": "new_spans_trace_id_fkey", + "tableFrom": "spans", + "tableTo": "traces", + "columnsFrom": [ + "trace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "spans_project_id_fkey": { + "name": "spans_project_id_fkey", + "tableFrom": "spans", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": { + "spans_pkey": { + "name": "spans_pkey", + "columns": [ + "span_id", + "project_id" + ] + } + }, + "uniqueConstraints": { + "unique_span_id_project_id": { + "name": "unique_span_id_project_id", + "nullsNotDistinct": false, + "columns": [ + "span_id", + "project_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.subscription_tiers": { + "name": "subscription_tiers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigint", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "subscription_tiers_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854776000", + "cache": "1", + "cycle": false + } + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "storage_mib": { + "name": "storage_mib", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "log_retention_days": { + "name": "log_retention_days", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "members_per_workspace": { + "name": "members_per_workspace", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'-1'" + }, + "num_workspaces": { + "name": "num_workspaces", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'-1'" + }, + "stripe_product_id": { + "name": "stripe_product_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "events": { + "name": "events", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "spans": { + "name": "spans", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "extra_span_price": { + "name": "extra_span_price", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "extra_event_price": { + "name": "extra_event_price", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.target_pipeline_versions": { + "name": "target_pipeline_versions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "pipeline_id": { + "name": "pipeline_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "pipeline_version_id": { + "name": "pipeline_version_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "target_pipeline_versions_pipeline_id_fkey": { + "name": "target_pipeline_versions_pipeline_id_fkey", + "tableFrom": "target_pipeline_versions", + "tableTo": "pipelines", + "columnsFrom": [ + "pipeline_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "target_pipeline_versions_pipeline_version_id_fkey": { + "name": "target_pipeline_versions_pipeline_version_id_fkey", + "tableFrom": "target_pipeline_versions", + "tableTo": "pipeline_versions", + "columnsFrom": [ + "pipeline_version_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "unique_pipeline_id": { + "name": "unique_pipeline_id", + "nullsNotDistinct": false, + "columns": [ + "pipeline_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.traces": { + "name": "traces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "end_time": { + "name": "end_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "start_time": { + "name": "start_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "total_token_count": { + "name": "total_token_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "cost": { + "name": "cost", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "trace_type": { + "name": "trace_type", + "type": "trace_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'DEFAULT'" + }, + "input_token_count": { + "name": "input_token_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "output_token_count": { + "name": "output_token_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "input_cost": { + "name": "input_cost", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "output_cost": { + "name": "output_cost", + "type": "double precision", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": { + "trace_metadata_gin_idx": { + "name": "trace_metadata_gin_idx", + "columns": [ + { + "expression": "metadata", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "traces_id_project_id_start_time_times_not_null_idx": { + "name": "traces_id_project_id_start_time_times_not_null_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": false, + "nulls": "first" + } + ], + "isUnique": false, + "where": "((start_time IS NOT NULL) AND (end_time IS NOT NULL))", + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_project_id_idx": { + "name": "traces_project_id_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_project_id_trace_type_start_time_end_time_idx": { + "name": "traces_project_id_trace_type_start_time_end_time_idx", + "columns": [ + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "((trace_type = 'DEFAULT'::trace_type) AND (start_time IS NOT NULL) AND (end_time IS NOT NULL))", + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_session_id_idx": { + "name": "traces_session_id_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "traces_start_time_end_time_idx": { + "name": "traces_start_time_end_time_idx", + "columns": [ + { + "expression": "start_time", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_time", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "new_traces_project_id_fkey": { + "name": "new_traces_project_id_fkey", + "tableFrom": "traces", + "tableTo": "projects", + "columnsFrom": [ + "project_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": { + "select_by_next_api_key": { + "name": "select_by_next_api_key", + "as": "PERMISSIVE", + "for": "SELECT", + "to": [ + "anon", + "authenticated" + ], + "using": "is_trace_id_accessible_for_api_key(api_key(), id)" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_subscription_info": { + "name": "user_subscription_info", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "stripe_customer_id": { + "name": "stripe_customer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "activated": { + "name": "activated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "user_subscription_info_stripe_customer_id_idx": { + "name": "user_subscription_info_stripe_customer_id_idx", + "columns": [ + { + "expression": "stripe_customer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_subscription_info_fkey": { + "name": "user_subscription_info_fkey", + "tableFrom": "user_subscription_info", + "tableTo": "users", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "users_email_key": { + "name": "users_email_key", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": { + "Enable insert for authenticated users only": { + "name": "Enable insert for authenticated users only", + "as": "PERMISSIVE", + "for": "INSERT", + "to": [ + "service_role" + ], + "withCheck": "true" + } + }, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspace_usage": { + "name": "workspace_usage", + "schema": "", + "columns": { + "workspace_id": { + "name": "workspace_id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "span_count": { + "name": "span_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "span_count_since_reset": { + "name": "span_count_since_reset", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "prev_span_count": { + "name": "prev_span_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "event_count": { + "name": "event_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "event_count_since_reset": { + "name": "event_count_since_reset", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "prev_event_count": { + "name": "prev_event_count", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "reset_time": { + "name": "reset_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "reset_reason": { + "name": "reset_reason", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'signup'" + } + }, + "indexes": {}, + "foreignKeys": { + "user_usage_workspace_id_fkey": { + "name": "user_usage_workspace_id_fkey", + "tableFrom": "workspace_usage", + "tableTo": "workspaces", + "columnsFrom": [ + "workspace_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_usage_workspace_id_key": { + "name": "user_usage_workspace_id_key", + "nullsNotDistinct": false, + "columns": [ + "workspace_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.workspaces": { + "name": "workspaces", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "gen_random_uuid()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tier_id": { + "name": "tier_id", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'1'" + }, + "subscription_id": { + "name": "subscription_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "additional_seats": { + "name": "additional_seats", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": {}, + "foreignKeys": { + "workspaces_tier_id_fkey": { + "name": "workspaces_tier_id_fkey", + "tableFrom": "workspaces", + "tableTo": "subscription_tiers", + "columnsFrom": [ + "tier_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "no action", + "onUpdate": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.label_source": { + "name": "label_source", + "schema": "public", + "values": [ + "MANUAL", + "AUTO", + "CODE" + ] + }, + "public.label_type": { + "name": "label_type", + "schema": "public", + "values": [ + "BOOLEAN", + "CATEGORICAL" + ] + }, + "public.span_type": { + "name": "span_type", + "schema": "public", + "values": [ + "DEFAULT", + "LLM", + "PIPELINE", + "EXECUTOR", + "EVALUATOR", + "EVALUATION" + ] + }, + "public.trace_type": { + "name": "trace_type", + "schema": "public", + "values": [ + "DEFAULT", + "EVENT", + "EVALUATION" + ] + }, + "public.workspace_role": { + "name": "workspace_role", + "schema": "public", + "values": [ + "member", + "owner" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/frontend/lib/db/migrations/meta/_journal.json b/frontend/lib/db/migrations/meta/_journal.json index cf9dfd01..9545e3cb 100644 --- a/frontend/lib/db/migrations/meta/_journal.json +++ b/frontend/lib/db/migrations/meta/_journal.json @@ -71,6 +71,20 @@ "when": 1732571729998, "tag": "0009_lean_turbo", "breakpoints": true + }, + { + "idx": 10, + "version": "7", + "when": 1733375589710, + "tag": "0010_brainy_wild_child", + "breakpoints": true + }, + { + "idx": 11, + "version": "7", + "when": 1733381569847, + "tag": "0011_bitter_daimon_hellstrom", + "breakpoints": true } ] } \ No newline at end of file diff --git a/frontend/lib/db/migrations/relations.ts b/frontend/lib/db/migrations/relations.ts index 06eb69d7..77a3cea1 100644 --- a/frontend/lib/db/migrations/relations.ts +++ b/frontend/lib/db/migrations/relations.ts @@ -1,5 +1,6 @@ import { relations } from "drizzle-orm/relations"; -import { apiKeys, datapointToSpan, datasetDatapoints, datasets, evaluationResults, evaluations, evaluationScores, events, eventTemplates, labelClasses, labelClassesForPath, labelingQueueItems, labelingQueues, labels, membersOfWorkspaces, pipelines, pipelineVersions, playgrounds, projectApiKeys, projects, providerApiKeys, spans, subscriptionTiers, targetPipelineVersions, traces, users, userSubscriptionInfo, workspaces, workspaceUsage } from "./schema"; + +import { apiKeys, datapointToSpan,datasetDatapoints, datasets, evaluationResults, evaluations, evaluationScores, events, labelClasses, labelClassesForPath, labelingQueueItems, labelingQueues, labels, membersOfWorkspaces, pipelines, pipelineVersions, playgrounds, projectApiKeys, projects, providerApiKeys, spans, subscriptionTiers, targetPipelineVersions, traces, users, userSubscriptionInfo, workspaces, workspaceUsage } from "./schema"; export const targetPipelineVersionsRelations = relations(targetPipelineVersions, ({one}) => ({ pipeline: one(pipelines, { @@ -37,7 +38,6 @@ export const projectsRelations = relations(projects, ({one, many}) => ({ labelingQueues: many(labelingQueues), providerApiKeys: many(providerApiKeys), evaluations: many(evaluations), - eventTemplates: many(eventTemplates), playgrounds: many(playgrounds), labelClassesForPaths: many(labelClassesForPath), datasets: many(datasets), @@ -67,21 +67,6 @@ export const evaluationsRelations = relations(evaluations, ({one, many}) => ({ }), })); -export const eventsRelations = relations(events, ({one}) => ({ - eventTemplate: one(eventTemplates, { - fields: [events.templateId], - references: [eventTemplates.id] - }), -})); - -export const eventTemplatesRelations = relations(eventTemplates, ({one, many}) => ({ - events: many(events), - project: one(projects, { - fields: [eventTemplates.projectId], - references: [projects.id] - }), -})); - export const labelingQueuesRelations = relations(labelingQueues, ({one, many}) => ({ project: one(projects, { fields: [labelingQueues.projectId], @@ -193,6 +178,26 @@ export const subscriptionTiersRelations = relations(subscriptionTiers, ({many}) workspaces: many(workspaces), })); +export const eventsRelations = relations(events, ({one}) => ({ + span: one(spans, { + fields: [events.spanId], + references: [spans.spanId] + }), +})); + +export const spansRelations = relations(spans, ({one, many}) => ({ + events: many(events), + datapointToSpans: many(datapointToSpan), + trace: one(traces, { + fields: [spans.traceId], + references: [traces.id] + }), + project: one(projects, { + fields: [spans.projectId], + references: [projects.id] + }), +})); + export const userSubscriptionInfoRelations = relations(userSubscriptionInfo, ({one}) => ({ user: one(users, { fields: [userSubscriptionInfo.userId], @@ -225,15 +230,3 @@ export const datapointToSpanRelations = relations(datapointToSpan, ({one}) => ({ references: [spans.spanId] }), })); - -export const spansRelations = relations(spans, ({one, many}) => ({ - datapointToSpans: many(datapointToSpan), - trace: one(traces, { - fields: [spans.traceId], - references: [traces.id] - }), - project: one(projects, { - fields: [spans.projectId], - references: [projects.id] - }), -})); diff --git a/frontend/lib/db/migrations/schema.ts b/frontend/lib/db/migrations/schema.ts index 9b1389e7..1966dd63 100644 --- a/frontend/lib/db/migrations/schema.ts +++ b/frontend/lib/db/migrations/schema.ts @@ -1,8 +1,6 @@ -import { bigint, boolean, doublePrecision, foreignKey, index, integer, jsonb, pgEnum, pgPolicy, pgTable, primaryKey, text, timestamp, unique, uuid } from "drizzle-orm/pg-core"; import { sql } from "drizzle-orm"; +import { bigint, boolean, doublePrecision, foreignKey, index, integer, jsonb, pgEnum,pgPolicy, pgTable, primaryKey, text, timestamp, unique, uuid } from "drizzle-orm/pg-core"; -export const eventSource = pgEnum("event_source", ['AUTO', 'MANUAL', 'CODE']); -export const eventType = pgEnum("event_type", ['BOOLEAN', 'STRING', 'NUMBER']); export const labelSource = pgEnum("label_source", ['MANUAL', 'AUTO', 'CODE']); export const labelType = pgEnum("label_type", ['BOOLEAN', 'CATEGORICAL']); export const spanType = pgEnum("span_type", ['DEFAULT', 'LLM', 'PIPELINE', 'EXECUTOR', 'EVALUATOR', 'EVALUATION']); @@ -82,25 +80,6 @@ export const evaluationResults = pgTable("evaluation_results", { selectByNextApiKey: pgPolicy("select_by_next_api_key", { as: "permissive", for: "select", to: ["anon", "authenticated"], using: sql`is_evaluation_id_accessible_for_api_key(api_key(), evaluation_id)` }), })); -export const events = pgTable("events", { - id: uuid().defaultRandom().primaryKey().notNull(), - createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), - spanId: uuid("span_id").notNull(), - timestamp: timestamp({ withTimezone: true, mode: 'string' }).notNull(), - templateId: uuid("template_id").notNull(), - source: eventSource().notNull(), - metadata: jsonb(), - value: jsonb().notNull(), - data: text(), - inputs: jsonb(), -}, (table) => ({ - eventsTemplateIdFkey: foreignKey({ - columns: [table.templateId], - foreignColumns: [eventTemplates.id], - name: "events_template_id_fkey" - }).onUpdate("cascade").onDelete("cascade"), -})); - export const labelingQueues = pgTable("labeling_queues", { id: uuid().defaultRandom().primaryKey().notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), @@ -191,21 +170,6 @@ export const subscriptionTiers = pgTable("subscription_tiers", { extraEventPrice: doublePrecision("extra_event_price").default(sql`'0'`).notNull(), }); -export const eventTemplates = pgTable("event_templates", { - id: uuid().defaultRandom().primaryKey().notNull(), - createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), - name: text().notNull(), - projectId: uuid("project_id").notNull(), - eventType: eventType("event_type").default('BOOLEAN').notNull(), -}, (table) => ({ - eventTemplatesProjectIdFkey: foreignKey({ - columns: [table.projectId], - foreignColumns: [projects.id], - name: "event_templates_project_id_fkey" - }).onUpdate("cascade").onDelete("cascade"), - uniqueNameProjectId: unique("unique_name_project_id").on(table.name, table.projectId), -})); - export const evaluationScores = pgTable("evaluation_scores", { id: uuid().defaultRandom().primaryKey().notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), @@ -435,6 +399,22 @@ export const users = pgTable("users", { enableInsertForAuthenticatedUsersOnly: pgPolicy("Enable insert for authenticated users only", { as: "permissive", for: "insert", to: ["service_role"], withCheck: sql`true` }), })); +export const events = pgTable("events", { + id: uuid().defaultRandom().primaryKey().notNull(), + createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), + timestamp: timestamp({ withTimezone: true, mode: 'string' }).notNull(), + name: text().notNull(), + attributes: jsonb().default({}).notNull(), + spanId: uuid("span_id").notNull(), + projectId: uuid("project_id").notNull(), +}, (table) => ({ + eventsSpanIdProjectIdFkey: foreignKey({ + columns: [table.spanId, table.projectId], + foreignColumns: [spans.spanId, spans.projectId], + name: "events_span_id_project_id_fkey" + }).onUpdate("cascade").onDelete("cascade"), +})); + export const userSubscriptionInfo = pgTable("user_subscription_info", { userId: uuid("user_id").defaultRandom().primaryKey().notNull(), createdAt: timestamp("created_at", { withTimezone: true, mode: 'string' }).defaultNow().notNull(), diff --git a/frontend/lib/db/modifiers.ts b/frontend/lib/db/modifiers.ts index bfee0f88..57b55080 100644 --- a/frontend/lib/db/modifiers.ts +++ b/frontend/lib/db/modifiers.ts @@ -1,4 +1,4 @@ -import { BinaryOperator, eq, gt, gte, lt, lte, ne, sql, SQL } from "drizzle-orm"; +import { BinaryOperator, eq, gt, gte, lt, lte, ne, SQL,sql } from "drizzle-orm"; const filterOperators: Record = { 'eq': eq, diff --git a/frontend/lib/db/utils.ts b/frontend/lib/db/utils.ts index bc8494e9..64caea50 100644 --- a/frontend/lib/db/utils.ts +++ b/frontend/lib/db/utils.ts @@ -1,11 +1,11 @@ -import { and, eq, getTableColumns, gt, lt, sql, SQL } from "drizzle-orm"; -import { apiKeys, membersOfWorkspaces, projects, users } from "./migrations/schema"; +import { and, eq, getTableColumns, gt, lt, SQL,sql } from "drizzle-orm"; import { PgTableWithColumns, SelectedFields, TableConfig } from "drizzle-orm/pg-core"; +import { getServerSession } from 'next-auth'; import { authOptions } from "../auth"; -import { db } from "./drizzle"; -import { getServerSession } from 'next-auth'; import { PaginatedResponse } from "../types"; +import { db } from "./drizzle"; +import { apiKeys, membersOfWorkspaces, projects, users } from "./migrations/schema"; export const isUserMemberOfProject = async (projectId: string, apiKey: string) => { diff --git a/frontend/lib/emails/subscription-updated-email.tsx b/frontend/lib/emails/subscription-updated-email.tsx index 8599e09b..3fca2bf6 100644 --- a/frontend/lib/emails/subscription-updated-email.tsx +++ b/frontend/lib/emails/subscription-updated-email.tsx @@ -6,9 +6,9 @@ import { Preview, Text } from '@react-email/components'; +import { Tailwind } from '@react-email/tailwind'; import { ItemDescription } from '../checkout/utils'; -import { Tailwind } from '@react-email/tailwind'; const boldClassName = 'w-full flex justify-start mb-1 mt-6'; const textClassName = 'w-full flex justify-start'; diff --git a/frontend/lib/emails/utils.ts b/frontend/lib/emails/utils.ts index c6eed178..83a4290e 100644 --- a/frontend/lib/emails/utils.ts +++ b/frontend/lib/emails/utils.ts @@ -1,5 +1,6 @@ -import { ItemDescription } from '../checkout/utils'; import { Resend } from 'resend'; + +import { ItemDescription } from '../checkout/utils'; import SubscriptionUpdatedEmail from './subscription-updated-email'; import WelcomeEmail from './welcome-email'; import WorkspaceInviteEmail from './workspace-invite'; diff --git a/frontend/lib/endpoint/types.ts b/frontend/lib/endpoint/types.ts index 390abc09..2597e9ed 100644 --- a/frontend/lib/endpoint/types.ts +++ b/frontend/lib/endpoint/types.ts @@ -1,6 +1,6 @@ +import { CheckJob } from '@/lib/check/types'; import { EndpointPipelineVersion, PipelineVersion } from '@/lib/pipeline/types'; -import { CheckJob } from '@/lib/check/types'; import { Dataset } from '../dataset/types'; import { RunnableGraph } from '../flow/types'; diff --git a/frontend/lib/events/types.ts b/frontend/lib/events/types.ts index 7a27cef8..a4710915 100644 --- a/frontend/lib/events/types.ts +++ b/frontend/lib/events/types.ts @@ -4,24 +4,10 @@ export enum EventType { NUMBER = 'NUMBER' } -export type EventTemplate = { - id: string; - createdAt: string; - name: string; - eventType: EventType; - projectId: string; - latestTimestamp: string | null; -}; - export type Event = { id: string; spanId: string; timestamp: string; - templateId: string; - templateName: string; - templateEventType: EventType; - source: string; - value: string | number | boolean | null; - metadata: Record | null; - inputs: Record | null; + name: string; + attributes: Record; }; diff --git a/frontend/lib/flow/graph.ts b/frontend/lib/flow/graph.ts index b5237b89..3770be45 100644 --- a/frontend/lib/flow/graph.ts +++ b/frontend/lib/flow/graph.ts @@ -1,3 +1,9 @@ +import { v4 } from 'uuid'; + +import { getRequiredEnvVars } from '@/lib/env/utils'; + +import { GraphMessagePreview } from '../pipeline/types'; +import { TraceMessages } from '../traces/types'; import { ConditionNode, type GenericNode, @@ -8,11 +14,6 @@ import { type OutputNode } from './types'; -import { getRequiredEnvVars } from '@/lib/env/utils'; -import { GraphMessagePreview } from '../pipeline/types'; -import { TraceMessages } from '../traces/types'; -import { v4 } from 'uuid'; - export class Graph { nodes: Map; pred: Map>; diff --git a/frontend/lib/flow/store.ts b/frontend/lib/flow/store.ts index 768f1106..bab6dd53 100644 --- a/frontend/lib/flow/store.ts +++ b/frontend/lib/flow/store.ts @@ -1,5 +1,3 @@ -import * as Y from 'yjs'; - import { addEdge, applyEdgeChanges, applyNodeChanges, type Connection, @@ -9,11 +7,12 @@ import { type OnConnect, type OnEdgesChange, type OnNodesChange, type ReactFlowInstance} from 'reactflow'; -import { type GenericNode, type NodeData } from './types'; - +import * as Y from 'yjs'; import { create } from 'zustand'; -import { Graph } from './graph'; + import { InputVariable } from '../pipeline/types'; +import { Graph } from './graph'; +import { type GenericNode, type NodeData } from './types'; // duplicating here because we can't export enums enum PipelineExecutionMode { diff --git a/frontend/lib/flow/types.ts b/frontend/lib/flow/types.ts index 1e8eb8d8..16ec0dd1 100644 --- a/frontend/lib/flow/types.ts +++ b/frontend/lib/flow/types.ts @@ -1,9 +1,9 @@ import { Edge, type Node } from 'reactflow'; -import { ChatMessage } from '../types'; import { Dataset } from '../dataset/types'; import { EventType } from '../events/types'; import { GraphMessage } from '../pipeline/types'; +import { ChatMessage } from '../types'; export enum NodeType { INPUT = 'Input', diff --git a/frontend/lib/flow/utils.ts b/frontend/lib/flow/utils.ts index 1184b68a..bf036b3a 100644 --- a/frontend/lib/flow/utils.ts +++ b/frontend/lib/flow/utils.ts @@ -1,4 +1,29 @@ +import { + StaticImageData, + StaticImport +} from 'next/dist/shared/lib/get-img-props'; +import { v4 as uuidv4 } from 'uuid'; + +import CodeNodePreview from '@/assets/pipeline/node-previews/code-node-preview.png'; +import CodeSandboxNodePreview from '@/assets/pipeline/node-previews/code-sandbox-node-preview.png'; +import FunctionNodePreview from '@/assets/pipeline/node-previews/function-node-preview.png'; +import InputNodePreview from '@/assets/pipeline/node-previews/input-node-preview.png'; +import JsonExtractorNodePreview from '@/assets/pipeline/node-previews/json-extractor-node-preview.png'; +import LLMNodePreview from '@/assets/pipeline/node-previews/llm-node-preview.png'; +import MapNodePreview from '@/assets/pipeline/node-previews/map-node-preview.png'; +import OutputNodePreview from '@/assets/pipeline/node-previews/output-node-preview.png'; +import SemanticSearchNodePreview from '@/assets/pipeline/node-previews/semantic-search-node-preview.png'; +import SemanticSimilarityNodePreview from '@/assets/pipeline/node-previews/semantic-similarity-node-preview.png'; +import SemanticSwitchNodePreview from '@/assets/pipeline/node-previews/semantic-switch-node-preview.png'; +import StringTemplateNodePreview from '@/assets/pipeline/node-previews/string-template-node-preview.png'; +import SubpipelineNodePreview from '@/assets/pipeline/node-previews/subpipeline-node-preview.png'; +import SwitchNodePreview from '@/assets/pipeline/node-previews/switch-node-preview.png'; +import ToolCallNodePreview from '@/assets/pipeline/node-previews/tool-call-node-preview.png'; +import WebSearchNodePreview from '@/assets/pipeline/node-previews/web-search-node-preview.png'; +import { DEFAULT_CODE } from '@/components/pipeline/nodes/code'; + import { ChatMessage, ChatMessageContentPart } from '../types'; +import { generateShortHash, isStringType } from '../utils'; import { CodeNode, CodeSandboxNode, @@ -23,34 +48,6 @@ import { WebSearchNode, ZenguardNode } from './types'; -import { generateShortHash, isStringType } from '../utils'; -import { - StaticImageData, - StaticImport -} from 'next/dist/shared/lib/get-img-props'; - -import CodeNodePreview from '@/assets/pipeline/node-previews/code-node-preview.png'; -import CodeSandboxNodePreview from '@/assets/pipeline/node-previews/code-sandbox-node-preview.png'; - -import { DEFAULT_CODE } from '@/components/pipeline/nodes/code'; - -import FunctionNodePreview from '@/assets/pipeline/node-previews/function-node-preview.png'; -import InputNodePreview from '@/assets/pipeline/node-previews/input-node-preview.png'; -import JsonExtractorNodePreview from '@/assets/pipeline/node-previews/json-extractor-node-preview.png'; -import LLMNodePreview from '@/assets/pipeline/node-previews/llm-node-preview.png'; -import MapNodePreview from '@/assets/pipeline/node-previews/map-node-preview.png'; -import OutputNodePreview from '@/assets/pipeline/node-previews/output-node-preview.png'; -import SemanticSearchNodePreview from '@/assets/pipeline/node-previews/semantic-search-node-preview.png'; -import SemanticSimilarityNodePreview from '@/assets/pipeline/node-previews/semantic-similarity-node-preview.png'; -import SemanticSwitchNodePreview from '@/assets/pipeline/node-previews/semantic-switch-node-preview.png'; -import StringTemplateNodePreview from '@/assets/pipeline/node-previews/string-template-node-preview.png'; -import SubpipelineNodePreview from '@/assets/pipeline/node-previews/subpipeline-node-preview.png'; -import SwitchNodePreview from '@/assets/pipeline/node-previews/switch-node-preview.png'; -import ToolCallNodePreview from '@/assets/pipeline/node-previews/tool-call-node-preview.png'; - -import { v4 as uuidv4 } from 'uuid'; - -import WebSearchNodePreview from '@/assets/pipeline/node-previews/web-search-node-preview.png'; export const NODE_TYPE_TO_DOCS = { [NodeType.INPUT]: 'https://docs.lmnr.ai/nodes/input-output', diff --git a/frontend/lib/fonts.ts b/frontend/lib/fonts.ts index 4c234ba8..2613d29e 100644 --- a/frontend/lib/fonts.ts +++ b/frontend/lib/fonts.ts @@ -1,27 +1,10 @@ import { - JetBrains_Mono as FontMono, - Inter as FontSans, - Outfit as FontSans2 + Inter, } from 'next/font/google'; -import localFont from 'next/font/local'; -export const fontSans = FontSans({ +export const sans = Inter({ subsets: ['latin'], - variable: '--font-sans' -}); - -export const fontSans2 = FontSans2({ - subsets: ['latin'], - variable: '--font-sans2' -}); - -export const fontMono = FontMono({ - subsets: ['latin'], - variable: '--font-mono' -}); - -export const fontSecurity = localFont({ - src: '../assets/fonts/text-security-disc.woff2', - weight: '500', - style: 'normal' + display: 'swap', + style: 'normal', + variable: '--font-inter' }); diff --git a/frontend/lib/hooks/use-toast.ts b/frontend/lib/hooks/use-toast.ts index b8a89ee7..3b17cf31 100644 --- a/frontend/lib/hooks/use-toast.ts +++ b/frontend/lib/hooks/use-toast.ts @@ -186,4 +186,4 @@ function useToast() { }; } -export { useToast, toast }; +export { toast,useToast }; diff --git a/frontend/lib/pipeline/types.ts b/frontend/lib/pipeline/types.ts index 979bae8c..d40905ee 100644 --- a/frontend/lib/pipeline/types.ts +++ b/frontend/lib/pipeline/types.ts @@ -1,10 +1,10 @@ +import { CheckJobStatus } from '@/lib/check/types'; import { DisplayableGraph, NodeHandleType, NodeInput, RunnableGraph } from '@/lib/flow/types'; -import { CheckJobStatus } from '@/lib/check/types'; export type PipelineType = 'WORKSHOP' | 'COMMIT'; export type PipelineVisibility = 'PUBLIC' | 'PRIVATE'; diff --git a/frontend/lib/pipeline/utils.ts b/frontend/lib/pipeline/utils.ts index 9d137705..ec1469c5 100644 --- a/frontend/lib/pipeline/utils.ts +++ b/frontend/lib/pipeline/utils.ts @@ -1,3 +1,6 @@ +import { Edge } from 'reactflow'; + +import { Graph } from '../flow/graph'; import { GenericNode, GenericNodeHandle, @@ -6,12 +9,9 @@ import { NodeType, SubpipelineNode } from '../flow/types'; -import { InputVariable, PipelineVersion } from './types'; - import { ChatMessage } from '../types'; -import { Edge } from 'reactflow'; -import { Graph } from '../flow/graph'; import { isStringType } from '../utils'; +import { InputVariable, PipelineVersion } from './types'; export const PUBLIC_PIPELINE_PROJECT_ID = 'PUBLIC-PIPELINE'; export const PUBLIC_PIPELINE_PROJECT_NAME = 'Public pipeline'; diff --git a/frontend/lib/playground/types.ts b/frontend/lib/playground/types.ts index 38b44cd4..d4737229 100644 --- a/frontend/lib/playground/types.ts +++ b/frontend/lib/playground/types.ts @@ -1,6 +1,7 @@ -import { ChatMessage } from "../types"; import { playgrounds } from "@/lib/db/migrations/schema"; +import { ChatMessage } from "../types"; + export type Playground = typeof playgrounds.$inferSelect & { promptMessages: ChatMessage[]; }; diff --git a/frontend/lib/traces/types.ts b/frontend/lib/traces/types.ts index 99029409..cd3124fe 100644 --- a/frontend/lib/traces/types.ts +++ b/frontend/lib/traces/types.ts @@ -1,6 +1,6 @@ +import { labelClasses } from '../db/migrations/schema'; import { Event } from '../events/types'; import { GraphMessagePreview } from '../pipeline/types'; -import { labelClasses } from '../db/migrations/schema'; export type TraceMessages = { [key: string]: GraphMessagePreview }; diff --git a/frontend/lib/traces/utils.ts b/frontend/lib/traces/utils.ts index e9ee2c9a..0e60617f 100644 --- a/frontend/lib/traces/utils.ts +++ b/frontend/lib/traces/utils.ts @@ -1,5 +1,5 @@ -import { DatatableFilter } from '../types'; import { SpanMetricGroupBy } from '../clickhouse/spans'; +import { DatatableFilter } from '../types'; import { SpanType } from './types'; export const SPAN_TYPE_TO_COLOR = { diff --git a/frontend/lib/utils.ts b/frontend/lib/utils.ts index d22bef27..9ccea6e2 100644 --- a/frontend/lib/utils.ts +++ b/frontend/lib/utils.ts @@ -1,11 +1,10 @@ -import * as Y from 'yjs'; - -import { ChatMessageContentPart, DatatableFilter } from './types'; import { type ClassValue, clsx } from 'clsx'; -import { InputVariable, PipelineVisibility } from './pipeline/types'; +import { twMerge } from 'tailwind-merge'; +import * as Y from 'yjs'; import { GroupByInterval } from './clickhouse/modifiers'; -import { twMerge } from 'tailwind-merge'; +import { InputVariable, PipelineVisibility } from './pipeline/types'; +import { ChatMessageContentPart, DatatableFilter } from './types'; export const TIME_MILLISECONDS_FORMAT = 'timeMilliseconds'; diff --git a/frontend/package.json b/frontend/package.json index d4750466..613207bb 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -128,6 +128,7 @@ "eslint-plugin-import": "^2.31.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^7.1.0", + "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-tailwindcss": "^3.17.5", "eslint-plugin-unused-imports": "^4.1.4", "postcss": "^8.4.47", diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index a084a6bb..3a08063d 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -345,6 +345,9 @@ importers: eslint-plugin-promise: specifier: ^7.1.0 version: 7.1.0(eslint@8.57.1) + eslint-plugin-simple-import-sort: + specifier: ^12.1.1 + version: 12.1.1(eslint@8.57.1) eslint-plugin-tailwindcss: specifier: ^3.17.5 version: 3.17.5(tailwindcss@3.4.14) @@ -3855,6 +3858,11 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + eslint-plugin-simple-import-sort@12.1.1: + resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + peerDependencies: + eslint: '>=5.0.0' + eslint-plugin-tailwindcss@3.17.5: resolution: {integrity: sha512-8Mi7p7dm+mO1dHgRHHFdPu4RDTBk69Cn4P0B40vRQR+MrguUpwmKwhZy1kqYe3Km8/4nb+cyrCF+5SodOEmaow==} engines: {node: '>=18.12.0'} @@ -10255,6 +10263,10 @@ snapshots: string.prototype.matchall: 4.0.11 string.prototype.repeat: 1.0.0 + eslint-plugin-simple-import-sort@12.1.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-plugin-tailwindcss@3.17.5(tailwindcss@3.4.14): dependencies: fast-glob: 3.3.2 diff --git a/frontend/tailwind.config.js b/frontend/tailwind.config.js index 7cb7e37a..8fcb2b82 100644 --- a/frontend/tailwind.config.js +++ b/frontend/tailwind.config.js @@ -17,6 +17,9 @@ module.exports = { }, }, extend: { + fontFamily: { + sans: ['var(--font-inter)'], + }, colors: { border: "hsl(var(--border))", input: "hsl(var(--input))", @@ -71,6 +74,17 @@ module.exports = { "accordion-down": "accordion-down 0.2s ease-out", "accordion-up": "accordion-up 0.2s ease-out", }, + fontSize: { + 'xl': ['1.25rem', { lineHeight: '1.75rem', letterSpacing: '-0.025em' }], + '2xl': ['1.5rem', { lineHeight: '2rem', letterSpacing: '-0.025em' }], + '3xl': ['1.875rem', { lineHeight: '2.25rem', letterSpacing: '-0.025em' }], + '4xl': ['2.25rem', { lineHeight: '2.5rem', letterSpacing: '-0.025em' }], + '5xl': ['3rem', { lineHeight: '1', letterSpacing: '-0.025em' }], + '6xl': ['3.75rem', { lineHeight: '1', letterSpacing: '-0.025em' }], + '7xl': ['4.5rem', { lineHeight: '1', letterSpacing: '-0.025em' }], + '8xl': ['6rem', { lineHeight: '1', letterSpacing: '-0.025em' }], + '9xl': ['8rem', { lineHeight: '1', letterSpacing: '-0.025em' }], + }, }, }, plugins: [require("tailwindcss-animate")], diff --git a/frontend/tailwind.config.ts b/frontend/tailwind.config.ts index ddf13a6e..c6cbbbd1 100644 --- a/frontend/tailwind.config.ts +++ b/frontend/tailwind.config.ts @@ -1,5 +1,3 @@ -const { fontFamily } = require('tailwindcss/defaultTheme') - /** @type {import('tailwindcss').Config} */ module.exports = { darkMode: ['class'], @@ -14,7 +12,8 @@ module.exports = { }, extend: { fontFamily: { - sans: ['var(--font-sans)', ...fontFamily.sans], + sans: ['var(--font-inter)'], + sans2: ['var(--font-outfit)'], }, colors: { border: 'hsl(var(--border))',