chore: add app version when querying ai configuratino (#724)
* chore: update api endpoint that accepts app version * chore: update env * chore: disable locai ai config test
This commit is contained in:
parent
7878a018a1
commit
71d292ebcd
|
|
@ -89,6 +89,8 @@ jobs:
|
||||||
sed -i 's|APPFLOWY_MAILER_SMTP_USERNAME=.*|APPFLOWY_MAILER_SMTP_USERNAME=${{ secrets.CI_GOTRUE_SMTP_USER }}|' .env
|
sed -i 's|APPFLOWY_MAILER_SMTP_USERNAME=.*|APPFLOWY_MAILER_SMTP_USERNAME=${{ secrets.CI_GOTRUE_SMTP_USER }}|' .env
|
||||||
sed -i 's|APPFLOWY_MAILER_SMTP_PASSWORD=.*|APPFLOWY_MAILER_SMTP_PASSWORD=${{ secrets.CI_GOTRUE_SMTP_PASS }}|' .env
|
sed -i 's|APPFLOWY_MAILER_SMTP_PASSWORD=.*|APPFLOWY_MAILER_SMTP_PASSWORD=${{ secrets.CI_GOTRUE_SMTP_PASS }}|' .env
|
||||||
sed -i 's|APPFLOWY_AI_OPENAI_API_KEY=.*|APPFLOWY_AI_OPENAI_API_KEY=${{ secrets.CI_OPENAI_API_KEY }}|' .env
|
sed -i 's|APPFLOWY_AI_OPENAI_API_KEY=.*|APPFLOWY_AI_OPENAI_API_KEY=${{ secrets.CI_OPENAI_API_KEY }}|' .env
|
||||||
|
sed -i "s|LOCAL_AI_AWS_ACCESS_KEY_ID=.*|LOCAL_AI_AWS_ACCESS_KEY_ID=${{ secrets.LOCAL_AI_AWS_ACCESS_KEY_ID }}|" .env
|
||||||
|
sed -i "s|LOCAL_AI_AWS_SECRET_ACCESS_KEY=.*|LOCAL_AI_AWS_SECRET_ACCESS_KEY=${{ secrets.LOCAL_AI_AWS_SECRET_ACCESS_KEY }}|" .env
|
||||||
sed -i 's|APPFLOWY_INDEXER_REDIS_URL=.*|APPFLOWY_INDEXER_REDIS_URL=redis://localhost:6379|' .env
|
sed -i 's|APPFLOWY_INDEXER_REDIS_URL=.*|APPFLOWY_INDEXER_REDIS_URL=redis://localhost:6379|' .env
|
||||||
sed -i 's|APPFLOWY_INDEXER_DATABASE_URL=.*|APPFLOWY_INDEXER_DATABASE_URL=postgres://postgres:password@localhost:5432/postgres|' .env
|
sed -i 's|APPFLOWY_INDEXER_DATABASE_URL=.*|APPFLOWY_INDEXER_DATABASE_URL=postgres://postgres:password@localhost:5432/postgres|' .env
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
|
||||||
|
|
@ -287,4 +287,4 @@ collab-document = { git = "https://github.com/AppFlowy-IO/AppFlowy-Collab", rev
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
history = []
|
history = []
|
||||||
ai-test-enabled = []
|
ai-test-enabled = ["client-api-test/ai-test-enabled"]
|
||||||
|
|
|
||||||
|
|
@ -112,6 +112,7 @@ APPFLOWY_AI_OPENAI_API_KEY=
|
||||||
APPFLOWY_AI_SERVER_PORT=5001
|
APPFLOWY_AI_SERVER_PORT=5001
|
||||||
APPFLOWY_AI_SERVER_HOST=ai
|
APPFLOWY_AI_SERVER_HOST=ai
|
||||||
APPFLOWY_AI_DATABASE_URL=postgresql+psycopg://postgres:password@postgres:5432/postgres
|
APPFLOWY_AI_DATABASE_URL=postgresql+psycopg://postgres:password@postgres:5432/postgres
|
||||||
|
APPFLOWY_LOCAL_AI_TEST_ENABLED=false
|
||||||
|
|
||||||
# AppFlowy History
|
# AppFlowy History
|
||||||
APPFLOWY_HISTORY_URL=http://localhost:50051
|
APPFLOWY_HISTORY_URL=http://localhost:50051
|
||||||
|
|
|
||||||
1
dev.env
1
dev.env
|
|
@ -103,6 +103,7 @@ APPFLOWY_AI_OPENAI_API_KEY=
|
||||||
APPFLOWY_AI_SERVER_PORT=5001
|
APPFLOWY_AI_SERVER_PORT=5001
|
||||||
APPFLOWY_AI_SERVER_HOST=localhost
|
APPFLOWY_AI_SERVER_HOST=localhost
|
||||||
APPFLOWY_AI_DATABASE_URL=postgresql+psycopg://postgres:password@postgres:5432/postgres
|
APPFLOWY_AI_DATABASE_URL=postgresql+psycopg://postgres:password@postgres:5432/postgres
|
||||||
|
APPFLOWY_LOCAL_AI_TEST_ENABLED=false
|
||||||
|
|
||||||
# AppFlowy History
|
# AppFlowy History
|
||||||
APPFLOWY_HISTORY_URL=http://localhost:50051
|
APPFLOWY_HISTORY_URL=http://localhost:50051
|
||||||
|
|
|
||||||
|
|
@ -291,8 +291,19 @@ impl AppFlowyAIClient {
|
||||||
.into_data()
|
.into_data()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_local_ai_config(&self, platform: &str) -> Result<LocalAIConfig, AIError> {
|
pub async fn get_local_ai_config(
|
||||||
let url = format!("{}/local_ai/config?platform={platform}", self.url);
|
&self,
|
||||||
|
platform: &str,
|
||||||
|
app_version: Option<String>,
|
||||||
|
) -> Result<LocalAIConfig, AIError> {
|
||||||
|
// Start with the base URL including the platform parameter
|
||||||
|
let mut url = format!("{}/local_ai/config?platform={}", self.url, platform);
|
||||||
|
|
||||||
|
// If app_version is provided, append it as a query parameter
|
||||||
|
if let Some(version) = app_version {
|
||||||
|
url = format!("{}&app_version={}", url, version);
|
||||||
|
}
|
||||||
|
|
||||||
let resp = self.http_client(Method::GET, &url)?.send().await?;
|
let resp = self.http_client(Method::GET, &url)?.send().await?;
|
||||||
AIResponse::<LocalAIConfig>::from_response(resp)
|
AIResponse::<LocalAIConfig>::from_response(resp)
|
||||||
.await?
|
.await?
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,10 @@ async fn download_package_test() {
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn get_local_ai_config_test() {
|
async fn get_local_ai_config_test() {
|
||||||
let client = appflowy_ai_client();
|
let client = appflowy_ai_client();
|
||||||
let config = client.get_local_ai_config("macos").await.unwrap();
|
let config = client
|
||||||
|
.get_local_ai_config("macos", Some("0.6.10".to_string()))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
assert!(!config.models.is_empty());
|
assert!(!config.models.is_empty());
|
||||||
|
|
||||||
assert!(!config.models[0].embedding_model.download_url.is_empty());
|
assert!(!config.models[0].embedding_model.download_url.is_empty());
|
||||||
|
|
|
||||||
|
|
@ -41,4 +41,5 @@ web-sys = { version = "0.3", features = ["console"] }
|
||||||
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
collab-sync = ["client-api/collab-sync"]
|
collab-sync = ["client-api/collab-sync"]
|
||||||
|
ai-test-enabled = []
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
use tracing::trace;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use {
|
use {
|
||||||
std::sync::Once,
|
std::sync::Once,
|
||||||
|
|
@ -16,6 +17,31 @@ fn get_bool_from_env_var(env_var_name: &str) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_env() {
|
||||||
|
// load once
|
||||||
|
static START: Once = Once::new();
|
||||||
|
START.call_once(|| {
|
||||||
|
dotenvy::dotenv().ok();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn local_ai_test_enabled() -> bool {
|
||||||
|
// In appflowy GitHub CI, we enable 'ai-test-enabled' feature by default, so even if the env var is not set,
|
||||||
|
// we still enable the local ai test.
|
||||||
|
if cfg!(feature = "ai-test-enabled") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
load_env();
|
||||||
|
|
||||||
|
// local ai test is disable by default
|
||||||
|
let enabled = get_bool_from_env_var("APPFLOWY_LOCAL_AI_TEST_ENABLED");
|
||||||
|
if enabled {
|
||||||
|
trace!("Local AI test is enabled");
|
||||||
|
}
|
||||||
|
enabled
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub fn setup_log() {
|
pub fn setup_log() {
|
||||||
if get_bool_from_env_var("DISABLE_CI_TEST_LOG") {
|
if get_bool_from_env_var("DISABLE_CI_TEST_LOG") {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{localhost_client_with_device_id, setup_log};
|
use crate::{load_env, localhost_client_with_device_id, setup_log};
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use assert_json_diff::{
|
use assert_json_diff::{
|
||||||
assert_json_eq, assert_json_include, assert_json_matches_no_panic, CompareMode, Config,
|
assert_json_eq, assert_json_include, assert_json_matches_no_panic, CompareMode, Config,
|
||||||
|
|
@ -56,6 +56,7 @@ pub struct TestCollab {
|
||||||
}
|
}
|
||||||
impl TestClient {
|
impl TestClient {
|
||||||
pub async fn new(registered_user: User, start_ws_conn: bool) -> Self {
|
pub async fn new(registered_user: User, start_ws_conn: bool) -> Self {
|
||||||
|
load_env();
|
||||||
setup_log();
|
setup_log();
|
||||||
let device_id = Uuid::new_v4().to_string();
|
let device_id = Uuid::new_v4().to_string();
|
||||||
Self::new_with_device_id(&device_id, registered_user, start_ws_conn).await
|
Self::new_with_device_id(&device_id, registered_user, start_ws_conn).await
|
||||||
|
|
|
||||||
|
|
@ -126,15 +126,15 @@ impl Client {
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let reqwest_client = reqwest::Client::new();
|
let reqwest_client = reqwest::Client::new();
|
||||||
let client_version = Version::parse(client_id).unwrap_or_else(|_| {
|
let client_version = Version::parse(client_id).unwrap_or_else(|_| {
|
||||||
warn!("Failed to parse client version, defaulting to 0.6.3");
|
warn!("Failed to parse client version, defaulting to 0.6.6");
|
||||||
Version::new(0, 6, 3)
|
Version::new(0, 6, 6)
|
||||||
});
|
});
|
||||||
|
|
||||||
// The latest version of appflowy frontend application is 0.6.3.
|
// The latest version of appflowy frontend application is 0.6.6.
|
||||||
// Ensure the client version is at least 0.6.3. Just in case client passes a lower version.
|
// Ensure the client version is at least 0.6.6. Just in case client passes a lower version.
|
||||||
let min_version = Version::new(0, 6, 3);
|
let min_version = Version::new(0, 6, 6);
|
||||||
let client_version = if client_version < min_version {
|
let client_version = if client_version < min_version {
|
||||||
warn!("Client version is less than 0.6.3, setting it to 0.6.3");
|
warn!("Client version is less than 0.6.6, setting it to 0.6.6");
|
||||||
min_version
|
min_version
|
||||||
} else {
|
} else {
|
||||||
client_version
|
client_version
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,9 @@ impl Client {
|
||||||
workspace_id: &str,
|
workspace_id: &str,
|
||||||
platform: &str,
|
platform: &str,
|
||||||
) -> Result<LocalAIConfig, AppResponseError> {
|
) -> Result<LocalAIConfig, AppResponseError> {
|
||||||
|
let client_version = self.client_version.to_string();
|
||||||
let url = format!(
|
let url = format!(
|
||||||
"{}/api/ai/{}/local/config?platform={platform}",
|
"{}/api/ai/{}/local/config?platform={platform}&app_version={client_version}",
|
||||||
self.base_url, workspace_id
|
self.base_url, workspace_id
|
||||||
);
|
);
|
||||||
let resp = self
|
let resp = self
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,14 @@ use appflowy_ai_client::dto::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use futures_util::{stream, TryStreamExt};
|
use futures_util::{stream, TryStreamExt};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use shared_entity::dto::ai_dto::{
|
use shared_entity::dto::ai_dto::{
|
||||||
CompleteTextParams, SummarizeRowData, SummarizeRowParams, SummarizeRowResponse,
|
CompleteTextParams, SummarizeRowData, SummarizeRowParams, SummarizeRowResponse,
|
||||||
};
|
};
|
||||||
use shared_entity::response::{AppResponse, JsonAppResponse};
|
use shared_entity::response::{AppResponse, JsonAppResponse};
|
||||||
|
|
||||||
use tracing::{error, instrument};
|
use tracing::{error, instrument, trace};
|
||||||
|
|
||||||
pub fn ai_completion_scope() -> Scope {
|
pub fn ai_completion_scope() -> Scope {
|
||||||
web::scope("/api/ai/{workspace_id}")
|
web::scope("/api/ai/{workspace_id}")
|
||||||
|
|
@ -128,17 +129,19 @@ async fn translate_row_handler(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize, Debug)]
|
||||||
struct ConfigQuery {
|
struct ConfigQuery {
|
||||||
platform: String,
|
platform: String,
|
||||||
|
app_version: Option<String>,
|
||||||
}
|
}
|
||||||
#[instrument(level = "debug", skip_all, err)]
|
#[instrument(level = "debug", skip_all, err)]
|
||||||
async fn local_ai_config_handler(
|
async fn local_ai_config_handler(
|
||||||
state: web::Data<AppState>,
|
state: web::Data<AppState>,
|
||||||
query: web::Query<ConfigQuery>,
|
query: web::Query<ConfigQuery>,
|
||||||
// req: HttpRequest,
|
|
||||||
) -> actix_web::Result<Json<AppResponse<LocalAIConfig>>> {
|
) -> actix_web::Result<Json<AppResponse<LocalAIConfig>>> {
|
||||||
let platform = match query.into_inner().platform.as_str() {
|
let query = query.into_inner();
|
||||||
|
trace!("query ai configuration: {:?}", query);
|
||||||
|
let platform = match query.platform.as_str() {
|
||||||
"macos" => "macos",
|
"macos" => "macos",
|
||||||
"linux" => "ubuntu",
|
"linux" => "ubuntu",
|
||||||
"ubuntu" => "ubuntu",
|
"ubuntu" => "ubuntu",
|
||||||
|
|
@ -150,22 +153,8 @@ async fn local_ai_config_handler(
|
||||||
|
|
||||||
let config = state
|
let config = state
|
||||||
.ai_client
|
.ai_client
|
||||||
.get_local_ai_config(platform)
|
.get_local_ai_config(platform, query.app_version)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| AppError::AIServiceUnavailable(err.to_string()))?;
|
.map_err(|err| AppError::AIServiceUnavailable(err.to_string()))?;
|
||||||
Ok(AppResponse::Ok().with_data(config).into())
|
Ok(AppResponse::Ok().with_data(config).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn device_info_from_headers(headers: &HeaderMap) -> std::result::Result<String, AppError> {
|
|
||||||
// headers
|
|
||||||
// .get("device_id")
|
|
||||||
// .ok_or(AppError::InvalidRequest(
|
|
||||||
// "Missing device_id header".to_string(),
|
|
||||||
// ))
|
|
||||||
// .and_then(|header| {
|
|
||||||
// header
|
|
||||||
// .to_str()
|
|
||||||
// .map_err(|err| AppError::InvalidRequest(format!("Failed to parse device_id: {}", err)))
|
|
||||||
// })
|
|
||||||
// .map(|s| s.to_string())
|
|
||||||
// }
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use crate::ai_test::util::read_text_from_asset;
|
||||||
use appflowy_ai_client::dto::{ChatContextLoader, CreateTextChatContext};
|
use appflowy_ai_client::dto::{ChatContextLoader, CreateTextChatContext};
|
||||||
use assert_json_diff::assert_json_eq;
|
use assert_json_diff::assert_json_eq;
|
||||||
use client_api::entity::QuestionStreamValue;
|
use client_api::entity::QuestionStreamValue;
|
||||||
use client_api_test::TestClient;
|
use client_api_test::{local_ai_test_enabled, TestClient};
|
||||||
use database_entity::dto::{
|
use database_entity::dto::{
|
||||||
ChatMessage, ChatMessageMetadata, ChatMetadataData, CreateChatMessageParams, CreateChatParams,
|
ChatMessage, ChatMessageMetadata, ChatMetadataData, CreateChatMessageParams, CreateChatParams,
|
||||||
MessageCursor,
|
MessageCursor,
|
||||||
|
|
@ -12,6 +12,10 @@ use serde_json::json;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn create_chat_and_create_messages_test() {
|
async fn create_chat_and_create_messages_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let test_client = TestClient::new_user_without_ws_conn().await;
|
let test_client = TestClient::new_user_without_ws_conn().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
|
|
||||||
|
|
@ -101,6 +105,9 @@ async fn create_chat_and_create_messages_test() {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn chat_qa_test() {
|
async fn chat_qa_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user_without_ws_conn().await;
|
let test_client = TestClient::new_user_without_ws_conn().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
let chat_id = uuid::Uuid::new_v4().to_string();
|
let chat_id = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
@ -174,6 +181,9 @@ async fn chat_qa_test() {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn generate_chat_message_answer_test() {
|
async fn generate_chat_message_answer_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user_without_ws_conn().await;
|
let test_client = TestClient::new_user_without_ws_conn().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
let chat_id = uuid::Uuid::new_v4().to_string();
|
let chat_id = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
@ -216,6 +226,9 @@ async fn generate_chat_message_answer_test() {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn generate_stream_answer_test() {
|
async fn generate_stream_answer_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user_without_ws_conn().await;
|
let test_client = TestClient::new_user_without_ws_conn().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
let chat_id = uuid::Uuid::new_v4().to_string();
|
let chat_id = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
@ -271,6 +284,9 @@ async fn generate_stream_answer_test() {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn create_chat_context_test() {
|
async fn create_chat_context_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user_without_ws_conn().await;
|
let test_client = TestClient::new_user_without_ws_conn().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
let chat_id = uuid::Uuid::new_v4().to_string();
|
let chat_id = uuid::Uuid::new_v4().to_string();
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
use appflowy_ai_client::dto::{AIModel, CompletionType};
|
use appflowy_ai_client::dto::{AIModel, CompletionType};
|
||||||
use client_api_test::TestClient;
|
use client_api_test::{local_ai_test_enabled, TestClient};
|
||||||
use shared_entity::dto::ai_dto::CompleteTextParams;
|
use shared_entity::dto::ai_dto::CompleteTextParams;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn improve_writing_test() {
|
async fn improve_writing_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user().await;
|
let test_client = TestClient::new_user().await;
|
||||||
test_client.api_client.set_ai_model(AIModel::GPT4o);
|
test_client.api_client.set_ai_model(AIModel::GPT4o);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
use client_api_test::TestClient;
|
use client_api_test::{local_ai_test_enabled, TestClient};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn get_local_ai_config_test() {
|
async fn get_local_ai_config_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user().await;
|
let test_client = TestClient::new_user().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
let config = test_client
|
let config = test_client
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
use client_api_test::TestClient;
|
use client_api_test::{local_ai_test_enabled, TestClient};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use shared_entity::dto::ai_dto::{SummarizeRowData, SummarizeRowParams};
|
use shared_entity::dto::ai_dto::{SummarizeRowData, SummarizeRowParams};
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn summarize_row_test() {
|
async fn summarize_row_test() {
|
||||||
|
if !local_ai_test_enabled() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let test_client = TestClient::new_user().await;
|
let test_client = TestClient::new_user().await;
|
||||||
let workspace_id = test_client.workspace_id().await;
|
let workspace_id = test_client.workspace_id().await;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
#[cfg(feature = "ai-test-enabled")]
|
|
||||||
mod ai_test;
|
mod ai_test;
|
||||||
mod collab;
|
mod collab;
|
||||||
mod collab_history;
|
mod collab_history;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue