mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-24 20:52:11 +00:00
added metadata for bm25 and also confidence levels
This commit is contained in:
parent
b3ba945b98
commit
c78a8f05ef
@ -3655,6 +3655,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3804576966"] = "Por
|
|||||||
-- Connection failed.
|
-- Connection failed.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3820825672"] = "Connection failed."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3820825672"] = "Connection failed."
|
||||||
|
|
||||||
|
-- Compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T3995796156"] = "Compliance level"
|
||||||
|
|
||||||
-- Your security policy
|
-- Your security policy
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T4081226330"] = "Your security policy"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1DIALOG::T4081226330"] = "Your security policy"
|
||||||
|
|
||||||
@ -3772,6 +3775,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3448155331"] =
|
|||||||
-- ERI server port
|
-- ERI server port
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3843835535"] = "ERI server port"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3843835535"] = "ERI server port"
|
||||||
|
|
||||||
|
-- Compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T3995796156"] = "Compliance level"
|
||||||
|
|
||||||
-- Your security policy
|
-- Your security policy
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T4081226330"] = "Your security policy"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T4081226330"] = "Your security policy"
|
||||||
|
|
||||||
@ -3787,6 +3793,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T470340825"] = "
|
|||||||
-- the security requirements of the data provider
|
-- the security requirements of the data provider
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T503852885"] = "the security requirements of the data provider"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T503852885"] = "the security requirements of the data provider"
|
||||||
|
|
||||||
|
-- the compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T607609781"] = "the compliance level"
|
||||||
|
|
||||||
-- When to use
|
-- When to use
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T629595477"] = "When to use"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCEERI_V1INFODIALOG::T629595477"] = "When to use"
|
||||||
|
|
||||||
@ -3838,6 +3847,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1312296210"
|
|||||||
-- No embedding selected
|
-- No embedding selected
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1359179968"] = "No embedding selected"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1359179968"] = "No embedding selected"
|
||||||
|
|
||||||
|
-- Maximum number of tokens per chunk for this data source. Use 0 to use the embedding provider setting.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1529596777"] = "Maximum number of tokens per chunk for this data source. Use 0 to use the embedding provider setting."
|
||||||
|
|
||||||
-- Tokenizer
|
-- Tokenizer
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1696723386"] = "Tokenizer"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1696723386"] = "Tokenizer"
|
||||||
|
|
||||||
@ -3856,29 +3868,26 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1847791252"
|
|||||||
-- In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method.
|
-- In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1948697886"] = "In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T1948697886"] = "In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method."
|
||||||
|
|
||||||
|
-- The overlap must be smaller than the effective token limit.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2101951526"] = "The overlap must be smaller than the effective token limit."
|
||||||
|
|
||||||
-- Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap.
|
-- Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2263831524"] = "Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2263831524"] = "Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap."
|
||||||
|
|
||||||
-- Please enter 0 or a positive max embedding size.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2571963846"] = "Please enter 0 or a positive max embedding size."
|
|
||||||
|
|
||||||
-- Add
|
-- Add
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2646845972"] = "Add"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2646845972"] = "Add"
|
||||||
|
|
||||||
-- Max embedding size
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2812251281"] = "Max embedding size"
|
|
||||||
|
|
||||||
-- The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.
|
-- The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2814869210"] = "The embedding you selected runs locally or in your organization. Your data is not sent to the cloud."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2814869210"] = "The embedding you selected runs locally or in your organization. Your data is not sent to the cloud."
|
||||||
|
|
||||||
|
-- The data source token limit must be smaller than the embedding provider token limit ({0}). Use 0 to use the provider setting.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2834874159"] = "The data source token limit must be smaller than the embedding provider token limit ({0}). Use 0 to use the provider setting."
|
||||||
|
|
||||||
-- Embedding
|
-- Embedding
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2838542994"] = "Embedding"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2838542994"] = "Embedding"
|
||||||
|
|
||||||
-- Maximum number of tokens per embedded chunk for this data source. Use 0 to use the embedding provider setting.
|
-- Token limit
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T287150655"] = "Maximum number of tokens per embedded chunk for this data source. Use 0 to use the embedding provider setting."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T2961294165"] = "Token limit"
|
||||||
|
|
||||||
-- The overlap must be smaller than the effective max embedding size.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3100817060"] = "The overlap must be smaller than the effective max embedding size."
|
|
||||||
|
|
||||||
-- Please enter 0 or a positive overlap length.
|
-- Please enter 0 or a positive overlap length.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3242265813"] = "Please enter 0 or a positive overlap length."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3242265813"] = "Please enter 0 or a positive overlap length."
|
||||||
@ -3889,8 +3898,11 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3359366900"
|
|||||||
-- Show Expert Settings
|
-- Show Expert Settings
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3361153305"] = "Show Expert Settings"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3361153305"] = "Show Expert Settings"
|
||||||
|
|
||||||
-- Embedding overlap
|
-- Please enter 0 or a positive token limit.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T375910361"] = "Embedding overlap"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3659673500"] = "Please enter 0 or a positive token limit."
|
||||||
|
|
||||||
|
-- Compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T3995796156"] = "Compliance level"
|
||||||
|
|
||||||
-- Your security policy
|
-- Your security policy
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T4081226330"] = "Your security policy"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T4081226330"] = "Your security policy"
|
||||||
@ -3898,15 +3910,15 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T4081226330"
|
|||||||
-- Select the base directory
|
-- Select the base directory
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T562479068"] = "Select the base directory"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T562479068"] = "Select the base directory"
|
||||||
|
|
||||||
-- The data source max embedding size must be smaller than the embedding provider limit ({0}). Use 0 to use the provider setting.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T607909514"] = "The data source max embedding size must be smaller than the embedding provider limit ({0}). Use 0 to use the provider setting."
|
|
||||||
|
|
||||||
-- Data Source Name
|
-- Data Source Name
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T813773421"] = "Data Source Name"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T813773421"] = "Data Source Name"
|
||||||
|
|
||||||
-- Cancel
|
-- Cancel
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T900713019"] = "Cancel"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T900713019"] = "Cancel"
|
||||||
|
|
||||||
|
-- Token overlap
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYDIALOG::T981382809"] = "Token overlap"
|
||||||
|
|
||||||
-- the total directory size
|
-- the total directory size
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T1082241458"] = "the total directory size"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T1082241458"] = "the total directory size"
|
||||||
|
|
||||||
@ -3967,6 +3979,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3602384
|
|||||||
-- Path
|
-- Path
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3949388886"] = "Path"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3949388886"] = "Path"
|
||||||
|
|
||||||
|
-- Compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T3995796156"] = "Compliance level"
|
||||||
|
|
||||||
-- Your security policy
|
-- Your security policy
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4081226330"] = "Your security policy"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4081226330"] = "Your security policy"
|
||||||
|
|
||||||
@ -3979,6 +3994,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T4438734
|
|||||||
-- The directory chosen for the data source exists.
|
-- The directory chosen for the data source exists.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T445858624"] = "The directory chosen for the data source exists."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T445858624"] = "The directory chosen for the data source exists."
|
||||||
|
|
||||||
|
-- the compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALDIRECTORYINFODIALOG::T607609781"] = "the compliance level"
|
||||||
|
|
||||||
-- Hide Expert Settings
|
-- Hide Expert Settings
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1108876344"] = "Hide Expert Settings"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1108876344"] = "Hide Expert Settings"
|
||||||
|
|
||||||
@ -3994,6 +4012,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1220918127"] = "
|
|||||||
-- No embedding selected
|
-- No embedding selected
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1359179968"] = "No embedding selected"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1359179968"] = "No embedding selected"
|
||||||
|
|
||||||
|
-- Maximum number of tokens per chunk for this data source. Use 0 to use the embedding provider setting.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1529596777"] = "Maximum number of tokens per chunk for this data source. Use 0 to use the embedding provider setting."
|
||||||
|
|
||||||
-- Tokenizer
|
-- Tokenizer
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1696723386"] = "Tokenizer"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1696723386"] = "Tokenizer"
|
||||||
|
|
||||||
@ -4009,32 +4030,29 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1847791252"] = "
|
|||||||
-- In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method.
|
-- In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1948697886"] = "In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T1948697886"] = "In order for the AI to be able to determine the appropriate data at any time, you must choose an embedding method."
|
||||||
|
|
||||||
|
-- The overlap must be smaller than the effective token limit.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2101951526"] = "The overlap must be smaller than the effective token limit."
|
||||||
|
|
||||||
-- Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap.
|
-- Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2263831524"] = "Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2263831524"] = "Number of tokens repeated at the start of the next chunk. Use 0 to disable overlap."
|
||||||
|
|
||||||
-- Please enter 0 or a positive max embedding size.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2571963846"] = "Please enter 0 or a positive max embedding size."
|
|
||||||
|
|
||||||
-- Add
|
-- Add
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2646845972"] = "Add"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2646845972"] = "Add"
|
||||||
|
|
||||||
-- Max embedding size
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2812251281"] = "Max embedding size"
|
|
||||||
|
|
||||||
-- The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.
|
-- The embedding you selected runs locally or in your organization. Your data is not sent to the cloud.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2814869210"] = "The embedding you selected runs locally or in your organization. Your data is not sent to the cloud."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2814869210"] = "The embedding you selected runs locally or in your organization. Your data is not sent to the cloud."
|
||||||
|
|
||||||
|
-- The data source token limit must be smaller than the embedding provider token limit ({0}). Use 0 to use the provider setting.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2834874159"] = "The data source token limit must be smaller than the embedding provider token limit ({0}). Use 0 to use the provider setting."
|
||||||
|
|
||||||
-- Embedding
|
-- Embedding
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2838542994"] = "Embedding"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2838542994"] = "Embedding"
|
||||||
|
|
||||||
-- Describe what data this file contains to help the AI select it.
|
-- Describe what data this file contains to help the AI select it.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2859265837"] = "Describe what data this file contains to help the AI select it."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2859265837"] = "Describe what data this file contains to help the AI select it."
|
||||||
|
|
||||||
-- Maximum number of tokens per embedded chunk for this data source. Use 0 to use the embedding provider setting.
|
-- Token limit
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T287150655"] = "Maximum number of tokens per embedded chunk for this data source. Use 0 to use the embedding provider setting."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T2961294165"] = "Token limit"
|
||||||
|
|
||||||
-- The overlap must be smaller than the effective max embedding size.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3100817060"] = "The overlap must be smaller than the effective max embedding size."
|
|
||||||
|
|
||||||
-- Please enter 0 or a positive overlap length.
|
-- Please enter 0 or a positive overlap length.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3242265813"] = "Please enter 0 or a positive overlap length."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3242265813"] = "Please enter 0 or a positive overlap length."
|
||||||
@ -4045,11 +4063,14 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3359366900"] = "
|
|||||||
-- Show Expert Settings
|
-- Show Expert Settings
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3361153305"] = "Show Expert Settings"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3361153305"] = "Show Expert Settings"
|
||||||
|
|
||||||
|
-- Please enter 0 or a positive token limit.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3659673500"] = "Please enter 0 or a positive token limit."
|
||||||
|
|
||||||
-- Select the file
|
-- Select the file
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3740148848"] = "Select the file"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3740148848"] = "Select the file"
|
||||||
|
|
||||||
-- Embedding overlap
|
-- Compliance level
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T375910361"] = "Embedding overlap"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T3995796156"] = "Compliance level"
|
||||||
|
|
||||||
-- Your security policy
|
-- Your security policy
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T4081226330"] = "Your security policy"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T4081226330"] = "Your security policy"
|
||||||
@ -4057,9 +4078,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T4081226330"] = "
|
|||||||
-- This data source already has indexed embeddings. Delete and recreate it to change the file path or embedding model.
|
-- This data source already has indexed embeddings. Delete and recreate it to change the file path or embedding model.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T458267883"] = "This data source already has indexed embeddings. Delete and recreate it to change the file path or embedding model."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T458267883"] = "This data source already has indexed embeddings. Delete and recreate it to change the file path or embedding model."
|
||||||
|
|
||||||
-- The data source max embedding size must be smaller than the embedding provider limit ({0}). Use 0 to use the provider setting.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T607909514"] = "The data source max embedding size must be smaller than the embedding provider limit ({0}). Use 0 to use the provider setting."
|
|
||||||
|
|
||||||
-- Data Source Name
|
-- Data Source Name
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T813773421"] = "Data Source Name"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T813773421"] = "Data Source Name"
|
||||||
|
|
||||||
@ -4069,6 +4087,9 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T900713019"] = "C
|
|||||||
-- Selected file path for this data source
|
-- Selected file path for this data source
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T939749563"] = "Selected file path for this data source"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T939749563"] = "Selected file path for this data source"
|
||||||
|
|
||||||
|
-- Token overlap
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEDIALOG::T981382809"] = "Token overlap"
|
||||||
|
|
||||||
-- The file chosen for the data source exists.
|
-- The file chosen for the data source exists.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T1294177559"] = "The file chosen for the data source exists."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T1294177559"] = "The file chosen for the data source exists."
|
||||||
|
|
||||||
@ -4123,9 +4144,15 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3650018664"]
|
|||||||
-- The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud.
|
-- The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] = "The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3688254408"] = "The embedding runs in the cloud. All your data within the file '{0}' will be sent to the cloud."
|
||||||
|
|
||||||
|
-- Compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T3995796156"] = "Compliance level"
|
||||||
|
|
||||||
-- Your security policy
|
-- Your security policy
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Your security policy"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T4081226330"] = "Your security policy"
|
||||||
|
|
||||||
|
-- the compliance level
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DATASOURCELOCALFILEINFODIALOG::T607609781"] = "the compliance level"
|
||||||
|
|
||||||
-- Markdown View
|
-- Markdown View
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown View"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::DOCUMENTCHECKDIALOG::T1373123357"] = "Markdown View"
|
||||||
|
|
||||||
@ -4270,9 +4297,6 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2331453405"] = "(O
|
|||||||
-- Invalid tokenizer:
|
-- Invalid tokenizer:
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2448302543"] = "Invalid tokenizer:"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2448302543"] = "Invalid tokenizer:"
|
||||||
|
|
||||||
-- Please enter a max embedding size greater than 0.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2608328491"] = "Please enter a max embedding size greater than 0."
|
|
||||||
|
|
||||||
-- Add
|
-- Add
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2646845972"] = "Add"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2646845972"] = "Add"
|
||||||
|
|
||||||
@ -4282,15 +4306,18 @@ UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T278585345"] = "Sel
|
|||||||
-- No models loaded or available.
|
-- No models loaded or available.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2810182573"] = "No models loaded or available."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2810182573"] = "No models loaded or available."
|
||||||
|
|
||||||
-- Max embedding size
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2812251281"] = "Max embedding size"
|
|
||||||
|
|
||||||
-- Instance Name
|
-- Instance Name
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2842060373"] = "Instance Name"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2842060373"] = "Instance Name"
|
||||||
|
|
||||||
-- Currently, we cannot query the embedding models for the selected provider and/or host. Therefore, please enter the model name manually.
|
-- Currently, we cannot query the embedding models for the selected provider and/or host. Therefore, please enter the model name manually.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T290547799"] = "Currently, we cannot query the embedding models for the selected provider and/or host. Therefore, please enter the model name manually."
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T290547799"] = "Currently, we cannot query the embedding models for the selected provider and/or host. Therefore, please enter the model name manually."
|
||||||
|
|
||||||
|
-- Token limit
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T2961294165"] = "Token limit"
|
||||||
|
|
||||||
|
-- Please enter a token limit greater than 0.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T3316544737"] = "Please enter a token limit greater than 0."
|
||||||
|
|
||||||
-- Show Expert Settings
|
-- Show Expert Settings
|
||||||
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T3361153305"] = "Show Expert Settings"
|
UI_TEXT_CONTENT["AISTUDIO::DIALOGS::EMBEDDINGPROVIDERDIALOG::T3361153305"] = "Show Expert Settings"
|
||||||
|
|
||||||
@ -6394,6 +6421,9 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1132433749"] = "The Tokenizer li
|
|||||||
-- ID mismatch: the plugin ID differs from the enterprise configuration ID.
|
-- ID mismatch: the plugin ID differs from the enterprise configuration ID.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1137744461"] = "ID mismatch: the plugin ID differs from the enterprise configuration ID."
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1137744461"] = "ID mismatch: the plugin ID differs from the enterprise configuration ID."
|
||||||
|
|
||||||
|
-- SQLite stores local RAG indexing metadata, searchable chunk text, and the file fingerprints used to decide whether local files need to be indexed again, without requiring a separate database server or a system SQLite installation.
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T117115925"] = "SQLite stores local RAG indexing metadata, searchable chunk text, and the file fingerprints used to decide whether local files need to be indexed again, without requiring a separate database server or a system SQLite installation."
|
||||||
|
|
||||||
-- This is a private AI Studio installation. It runs without an enterprise configuration.
|
-- This is a private AI Studio installation. It runs without an enterprise configuration.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1209549230"] = "This is a private AI Studio installation. It runs without an enterprise configuration."
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T1209549230"] = "This is a private AI Studio installation. It runs without an enterprise configuration."
|
||||||
|
|
||||||
@ -6481,9 +6511,6 @@ UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2173617769"] = "This library is
|
|||||||
-- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.
|
-- For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose.
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2174764529"] = "For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose."
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2174764529"] = "For the secure communication between the user interface and the runtime, we need to create certificates. This Rust library is great for this purpose."
|
||||||
|
|
||||||
-- SQLite stores local RAG indexing metadata and the file fingerprints used to decide whether local files need to be indexed again, without requiring a separate database server or a system SQLite installation.
|
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T224267373"] = "SQLite stores local RAG indexing metadata and the file fingerprints used to decide whether local files need to be indexed again, without requiring a separate database server or a system SQLite installation."
|
|
||||||
|
|
||||||
-- OK
|
-- OK
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2246359087"] = "OK"
|
UI_TEXT_CONTENT["AISTUDIO::PAGES::INFORMATION::T2246359087"] = "OK"
|
||||||
|
|
||||||
@ -6994,6 +7021,9 @@ UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCELEVELEXTENSIONS::T3063224793"] =
|
|||||||
-- High
|
-- High
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCELEVELEXTENSIONS::T3188327965"] = "High"
|
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCELEVELEXTENSIONS::T3188327965"] = "High"
|
||||||
|
|
||||||
|
-- Unknown
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCELEVELEXTENSIONS::T3424652889"] = "Unknown"
|
||||||
|
|
||||||
-- Very Low
|
-- Very Low
|
||||||
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCELEVELEXTENSIONS::T786675843"] = "Very Low"
|
UI_TEXT_CONTENT["AISTUDIO::PROVIDER::CONFIDENCELEVELEXTENSIONS::T786675843"] = "Very Low"
|
||||||
|
|
||||||
@ -7459,6 +7489,9 @@ UI_TEXT_CONTENT["AISTUDIO::TOOLS::DATABASES::EMBEDDINGSTATE::SQLITEEMBEDDINGSTAT
|
|||||||
-- Indexed files
|
-- Indexed files
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::DATABASES::EMBEDDINGSTATE::SQLITEEMBEDDINGSTATECLIENTIMPLEMENTATION::T2235289713"] = "Indexed files"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::DATABASES::EMBEDDINGSTATE::SQLITEEMBEDDINGSTATECLIENTIMPLEMENTATION::T2235289713"] = "Indexed files"
|
||||||
|
|
||||||
|
-- Search chunks
|
||||||
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::DATABASES::EMBEDDINGSTATE::SQLITEEMBEDDINGSTATECLIENTIMPLEMENTATION::T2333737457"] = "Search chunks"
|
||||||
|
|
||||||
-- Indexed data sources
|
-- Indexed data sources
|
||||||
UI_TEXT_CONTENT["AISTUDIO::TOOLS::DATABASES::EMBEDDINGSTATE::SQLITEEMBEDDINGSTATECLIENTIMPLEMENTATION::T3524534748"] = "Indexed data sources"
|
UI_TEXT_CONTENT["AISTUDIO::TOOLS::DATABASES::EMBEDDINGSTATE::SQLITEEMBEDDINGSTATECLIENTIMPLEMENTATION::T3524534748"] = "Indexed data sources"
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Provider
|
||||||
@using AIStudio.Tools.ERIClient.DataModel
|
@using AIStudio.Tools.ERIClient.DataModel
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
@ -119,6 +120,15 @@
|
|||||||
</MudSelectItem>
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
|
<MudSelect @bind-Value="@this.dataComplianceLevel" Text="@this.dataComplianceLevel.GetName()" Label="@T("Compliance level")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start">
|
||||||
|
@foreach (var level in this.ComplianceLevels)
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@level.Value">
|
||||||
|
@level.Name
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
|
||||||
<MudNumericField T="ushort" Min="10" @bind-Value="@this.dataMaxMatches" Label="@T("How many matches do you want at most per query?")" Variant="Variant.Outlined" Step="10" />
|
<MudNumericField T="ushort" Min="10" @bind-Value="@this.dataMaxMatches" Label="@T("How many matches do you want at most per query?")" Variant="Variant.Outlined" Step="10" />
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
using AIStudio.Components;
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Provider;
|
||||||
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.ERIClient;
|
using AIStudio.Tools.ERIClient;
|
||||||
using AIStudio.Tools.ERIClient.DataModel;
|
using AIStudio.Tools.ERIClient.DataModel;
|
||||||
@ -46,6 +48,7 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
|
|||||||
private string dataEditingPreviousInstanceName = string.Empty;
|
private string dataEditingPreviousInstanceName = string.Empty;
|
||||||
private List<AuthMethod> availableAuthMethods = [];
|
private List<AuthMethod> availableAuthMethods = [];
|
||||||
private DataSourceSecurity dataSecurityPolicy;
|
private DataSourceSecurity dataSecurityPolicy;
|
||||||
|
private ConfidenceLevel dataComplianceLevel = ConfidenceLevel.UNKNOWN;
|
||||||
private SecurityRequirements dataSourceSecurityRequirements;
|
private SecurityRequirements dataSourceSecurityRequirements;
|
||||||
private ushort dataMaxMatches = 10;
|
private ushort dataMaxMatches = 10;
|
||||||
private bool connectionTested;
|
private bool connectionTested;
|
||||||
@ -105,6 +108,7 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
|
|||||||
this.dataAuthMethod = this.DataSource.AuthMethod;
|
this.dataAuthMethod = this.DataSource.AuthMethod;
|
||||||
this.dataUsername = this.DataSource.Username;
|
this.dataUsername = this.DataSource.Username;
|
||||||
this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
|
this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
|
||||||
|
this.dataComplianceLevel = this.DataSource.ComplianceLevel;
|
||||||
this.dataMaxMatches = this.DataSource.MaxMatches;
|
this.dataMaxMatches = this.DataSource.MaxMatches;
|
||||||
|
|
||||||
// We cannot load the retrieval processes now, since we have
|
// We cannot load the retrieval processes now, since we have
|
||||||
@ -157,6 +161,8 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
private IEnumerable<ConfigurationSelectData<ConfidenceLevel>> ComplianceLevels => ConfigurationSelectDataFactory.GetDataSourceComplianceLevelsData();
|
||||||
|
|
||||||
private DataSourceERI_V1 CreateDataSource()
|
private DataSourceERI_V1 CreateDataSource()
|
||||||
{
|
{
|
||||||
var cleanedHostname = this.dataHostname.Trim();
|
var cleanedHostname = this.dataHostname.Trim();
|
||||||
@ -172,6 +178,7 @@ public partial class DataSourceERI_V1Dialog : MSGComponentBase, ISecretId
|
|||||||
UsernamePasswordMode = DataSourceERIUsernamePasswordMode.USER_MANAGED,
|
UsernamePasswordMode = DataSourceERIUsernamePasswordMode.USER_MANAGED,
|
||||||
Type = DataSourceType.ERI_V1,
|
Type = DataSourceType.ERI_V1,
|
||||||
SecurityPolicy = this.dataSecurityPolicy,
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
|
ComplianceLevel = this.dataComplianceLevel,
|
||||||
SelectedRetrievalId = this.dataSelectedRetrievalProcess.Id,
|
SelectedRetrievalId = this.dataSelectedRetrievalProcess.Id,
|
||||||
MaxMatches = this.dataMaxMatches,
|
MaxMatches = this.dataMaxMatches,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Provider
|
||||||
@using AIStudio.Tools.ERIClient.DataModel
|
@using AIStudio.Tools.ERIClient.DataModel
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
@ -27,6 +28,7 @@
|
|||||||
<TextInfoLines Label="@T("Server description")" MaxLines="14" Value="@this.serverDescription" ClipboardTooltipSubject="@T("the server description")"/>
|
<TextInfoLines Label="@T("Server description")" MaxLines="14" Value="@this.serverDescription" ClipboardTooltipSubject="@T("the server description")"/>
|
||||||
<TextInfoLines Label="@T("Security requirements of the data provider")" MaxLines="3" Value="@this.securityRequirements.Explain()" ClipboardTooltipSubject="@T("the security requirements of the data provider")"/>
|
<TextInfoLines Label="@T("Security requirements of the data provider")" MaxLines="3" Value="@this.securityRequirements.Explain()" ClipboardTooltipSubject="@T("the security requirements of the data provider")"/>
|
||||||
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
||||||
|
<TextInfoLine Label="@T("Compliance level")" Value="@this.DataSource.ComplianceLevel.GetName()" ClipboardTooltipSubject="@T("the compliance level")"/>
|
||||||
<TextInfoLine Label="@T("Maximum matches per query")" Value="@this.DataSource.MaxMatches.ToString()" ClipboardTooltipSubject="@T("the maximum number of matches per query")"/>
|
<TextInfoLine Label="@T("Maximum matches per query")" Value="@this.DataSource.MaxMatches.ToString()" ClipboardTooltipSubject="@T("the maximum number of matches per query")"/>
|
||||||
|
|
||||||
<MudText Typo="Typo.h5" Class="mt-6">
|
<MudText Typo="Typo.h5" Class="mt-6">
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Provider
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
@ -136,6 +137,15 @@
|
|||||||
</MudSelectItem>
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
|
<MudSelect @bind-Value="@this.dataComplianceLevel" Text="@this.dataComplianceLevel.GetName()" Label="@T("Compliance level")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start">
|
||||||
|
@foreach (var level in this.ComplianceLevels)
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@level.Value">
|
||||||
|
@level.Name
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
|
||||||
<MudNumericField T="ushort" Min="10" @bind-Value="@this.dataMaxMatches" Label="@T("How many matches do you want at most per query?")" Variant="Variant.Outlined" Step="10" />
|
<MudNumericField T="ushort" Min="10" @bind-Value="@this.dataMaxMatches" Label="@T("How many matches do you want at most per query?")" Variant="Variant.Outlined" Step="10" />
|
||||||
</MudForm>
|
</MudForm>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using AIStudio.Components;
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.Validation;
|
using AIStudio.Tools.Validation;
|
||||||
@ -49,6 +50,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase
|
|||||||
private ushort dataMaxMatches = 10;
|
private ushort dataMaxMatches = 10;
|
||||||
private bool showExpertSettings;
|
private bool showExpertSettings;
|
||||||
private DataSourceSecurity dataSecurityPolicy;
|
private DataSourceSecurity dataSecurityPolicy;
|
||||||
|
private ConfidenceLevel dataComplianceLevel = ConfidenceLevel.UNKNOWN;
|
||||||
|
|
||||||
// We get the form reference from Blazor code to validate it manually:
|
// We get the form reference from Blazor code to validate it manually:
|
||||||
private MudForm form = null!;
|
private MudForm form = null!;
|
||||||
@ -86,6 +88,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase
|
|||||||
this.dataMaxChunkTokenLength = this.DataSource.MaxChunkTokenLength;
|
this.dataMaxChunkTokenLength = this.DataSource.MaxChunkTokenLength;
|
||||||
this.dataChunkOverlapTokenLength = this.DataSource.ChunkOverlapTokenLength;
|
this.dataChunkOverlapTokenLength = this.DataSource.ChunkOverlapTokenLength;
|
||||||
this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
|
this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
|
||||||
|
this.dataComplianceLevel = this.DataSource.ComplianceLevel;
|
||||||
this.dataMaxMatches = this.DataSource.MaxMatches;
|
this.dataMaxMatches = this.DataSource.MaxMatches;
|
||||||
this.showExpertSettings = this.dataMaxChunkTokenLength > 0 || this.dataChunkOverlapTokenLength > 0;
|
this.showExpertSettings = this.dataMaxChunkTokenLength > 0 || this.dataChunkOverlapTokenLength > 0;
|
||||||
}
|
}
|
||||||
@ -112,6 +115,8 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase
|
|||||||
|
|
||||||
private bool CanChangeSourceAndEmbedding => !this.IsEditing || !this.LockSourceAndEmbedding;
|
private bool CanChangeSourceAndEmbedding => !this.IsEditing || !this.LockSourceAndEmbedding;
|
||||||
|
|
||||||
|
private IEnumerable<ConfigurationSelectData<ConfidenceLevel>> ComplianceLevels => ConfigurationSelectDataFactory.GetDataSourceComplianceLevelsData();
|
||||||
|
|
||||||
private string SelectedEmbeddingTokenizerText => this.SelectedEmbedding is null
|
private string SelectedEmbeddingTokenizerText => this.SelectedEmbedding is null
|
||||||
? T("No embedding selected")
|
? T("No embedding selected")
|
||||||
: string.IsNullOrWhiteSpace(this.SelectedEmbedding.TokenizerPath)
|
: string.IsNullOrWhiteSpace(this.SelectedEmbedding.TokenizerPath)
|
||||||
@ -130,6 +135,7 @@ public partial class DataSourceLocalDirectoryDialog : MSGComponentBase
|
|||||||
MaxChunkTokenLength = this.dataMaxChunkTokenLength,
|
MaxChunkTokenLength = this.dataMaxChunkTokenLength,
|
||||||
ChunkOverlapTokenLength = this.dataChunkOverlapTokenLength,
|
ChunkOverlapTokenLength = this.dataChunkOverlapTokenLength,
|
||||||
SecurityPolicy = this.dataSecurityPolicy,
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
|
ComplianceLevel = this.dataComplianceLevel,
|
||||||
MaxMatches = this.dataMaxMatches,
|
MaxMatches = this.dataMaxMatches,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Provider
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
@ -38,6 +39,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
||||||
|
<TextInfoLine Label="@T("Compliance level")" Value="@this.DataSource.ComplianceLevel.GetName()" ClipboardTooltipSubject="@T("the compliance level")"/>
|
||||||
<TextInfoLine Label="@T("Maximum matches per query")" Value="@this.DataSource.MaxMatches.ToString()" ClipboardTooltipSubject="@T("the maximum number of matches per query")"/>
|
<TextInfoLine Label="@T("Maximum matches per query")" Value="@this.DataSource.MaxMatches.ToString()" ClipboardTooltipSubject="@T("the maximum number of matches per query")"/>
|
||||||
|
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("Number of files")" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="@T("the number of files in the directory")"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("Number of files")" Value="@this.NumberFilesInDirectory" ClipboardTooltipSubject="@T("the number of files in the directory")"/>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Provider
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
@ -136,6 +137,15 @@
|
|||||||
</MudSelectItem>
|
</MudSelectItem>
|
||||||
}
|
}
|
||||||
</MudSelect>
|
</MudSelect>
|
||||||
|
|
||||||
|
<MudSelect @bind-Value="@this.dataComplianceLevel" Text="@this.dataComplianceLevel.GetName()" Label="@T("Compliance level")" Class="mb-3" OpenIcon="@Icons.Material.Filled.ExpandMore" AdornmentColor="Color.Info" Adornment="Adornment.Start">
|
||||||
|
@foreach (var level in this.ComplianceLevels)
|
||||||
|
{
|
||||||
|
<MudSelectItem Value="@level.Value">
|
||||||
|
@level.Name
|
||||||
|
</MudSelectItem>
|
||||||
|
}
|
||||||
|
</MudSelect>
|
||||||
|
|
||||||
<MudNumericField T="ushort" Min="10" @bind-Value="@this.dataMaxMatches" Label="@T("How many matches do you want at most per query?")" Variant="Variant.Outlined" Step="10" />
|
<MudNumericField T="ushort" Min="10" @bind-Value="@this.dataMaxMatches" Label="@T("How many matches do you want at most per query?")" Variant="Variant.Outlined" Step="10" />
|
||||||
</MudForm>
|
</MudForm>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using AIStudio.Components;
|
using AIStudio.Components;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.Validation;
|
using AIStudio.Tools.Validation;
|
||||||
@ -49,6 +50,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase
|
|||||||
private ushort dataMaxMatches = 10;
|
private ushort dataMaxMatches = 10;
|
||||||
private bool showExpertSettings;
|
private bool showExpertSettings;
|
||||||
private DataSourceSecurity dataSecurityPolicy;
|
private DataSourceSecurity dataSecurityPolicy;
|
||||||
|
private ConfidenceLevel dataComplianceLevel = ConfidenceLevel.UNKNOWN;
|
||||||
|
|
||||||
// We get the form reference from Blazor code to validate it manually:
|
// We get the form reference from Blazor code to validate it manually:
|
||||||
private MudForm form = null!;
|
private MudForm form = null!;
|
||||||
@ -86,6 +88,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase
|
|||||||
this.dataMaxChunkTokenLength = this.DataSource.MaxChunkTokenLength;
|
this.dataMaxChunkTokenLength = this.DataSource.MaxChunkTokenLength;
|
||||||
this.dataChunkOverlapTokenLength = this.DataSource.ChunkOverlapTokenLength;
|
this.dataChunkOverlapTokenLength = this.DataSource.ChunkOverlapTokenLength;
|
||||||
this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
|
this.dataSecurityPolicy = this.DataSource.SecurityPolicy;
|
||||||
|
this.dataComplianceLevel = this.DataSource.ComplianceLevel;
|
||||||
this.dataMaxMatches = this.DataSource.MaxMatches;
|
this.dataMaxMatches = this.DataSource.MaxMatches;
|
||||||
this.showExpertSettings = this.dataMaxChunkTokenLength > 0 || this.dataChunkOverlapTokenLength > 0;
|
this.showExpertSettings = this.dataMaxChunkTokenLength > 0 || this.dataChunkOverlapTokenLength > 0;
|
||||||
}
|
}
|
||||||
@ -112,6 +115,8 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase
|
|||||||
|
|
||||||
private bool CanChangeSourceAndEmbedding => !this.IsEditing || !this.LockSourceAndEmbedding;
|
private bool CanChangeSourceAndEmbedding => !this.IsEditing || !this.LockSourceAndEmbedding;
|
||||||
|
|
||||||
|
private IEnumerable<ConfigurationSelectData<ConfidenceLevel>> ComplianceLevels => ConfigurationSelectDataFactory.GetDataSourceComplianceLevelsData();
|
||||||
|
|
||||||
private string SelectedEmbeddingTokenizerText => this.SelectedEmbedding is null
|
private string SelectedEmbeddingTokenizerText => this.SelectedEmbedding is null
|
||||||
? T("No embedding selected")
|
? T("No embedding selected")
|
||||||
: string.IsNullOrWhiteSpace(this.SelectedEmbedding.TokenizerPath)
|
: string.IsNullOrWhiteSpace(this.SelectedEmbedding.TokenizerPath)
|
||||||
@ -130,6 +135,7 @@ public partial class DataSourceLocalFileDialog : MSGComponentBase
|
|||||||
MaxChunkTokenLength = this.dataMaxChunkTokenLength,
|
MaxChunkTokenLength = this.dataMaxChunkTokenLength,
|
||||||
ChunkOverlapTokenLength = this.dataChunkOverlapTokenLength,
|
ChunkOverlapTokenLength = this.dataChunkOverlapTokenLength,
|
||||||
SecurityPolicy = this.dataSecurityPolicy,
|
SecurityPolicy = this.dataSecurityPolicy,
|
||||||
|
ComplianceLevel = this.dataComplianceLevel,
|
||||||
MaxMatches = this.dataMaxMatches,
|
MaxMatches = this.dataMaxMatches,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
@using AIStudio.Settings.DataModel
|
@using AIStudio.Settings.DataModel
|
||||||
|
@using AIStudio.Provider
|
||||||
@inherits MSGComponentBase
|
@inherits MSGComponentBase
|
||||||
|
|
||||||
<MudDialog>
|
<MudDialog>
|
||||||
@ -38,6 +39,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
<TextInfoLines Label="@T("Your security policy")" MaxLines="3" Value="@this.DataSource.SecurityPolicy.ToInfoText()" Color="@this.DataSource.SecurityPolicy.GetColor()" ClipboardTooltipSubject="@T("your security policy")"/>
|
||||||
|
<TextInfoLine Label="@T("Compliance level")" Value="@this.DataSource.ComplianceLevel.GetName()" ClipboardTooltipSubject="@T("the compliance level")"/>
|
||||||
<TextInfoLine Label="@T("Maximum matches per query")" Value="@this.DataSource.MaxMatches.ToString()" ClipboardTooltipSubject="@T("the maximum number of matches per query")"/>
|
<TextInfoLine Label="@T("Maximum matches per query")" Value="@this.DataSource.MaxMatches.ToString()" ClipboardTooltipSubject="@T("the maximum number of matches per query")"/>
|
||||||
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("File size")" Value="@this.FileSize" ClipboardTooltipSubject="@T("the file size")"/>
|
<TextInfoLine Icon="@Icons.Material.Filled.SquareFoot" Label="@T("File size")" Value="@this.FileSize" ClipboardTooltipSubject="@T("the file size")"/>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
|
|||||||
@ -290,7 +290,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
<ThirdPartyComponent Name="Qdrant Edge" Developer="Andrey Vasnetsov, Tim Visée, Arnaud Gourlay, Luis Cossío, Ivan Pleshkov, Roman Titov, xzfc, JojiiOfficial & Open Source Community" LicenseName="Apache-2.0" LicenseUrl="https://github.com/qdrant/qdrant/blob/master/LICENSE" RepositoryUrl="https://github.com/qdrant/qdrant" UseCase="@T("Qdrant Edge is an embedded vector database and vector similarity search engine. We use it to realize local RAG—retrieval-augmented generation—within AI Studio. Thanks for the effort and great work that has been and is being put into Qdrant.")"/>
|
<ThirdPartyComponent Name="Qdrant Edge" Developer="Andrey Vasnetsov, Tim Visée, Arnaud Gourlay, Luis Cossío, Ivan Pleshkov, Roman Titov, xzfc, JojiiOfficial & Open Source Community" LicenseName="Apache-2.0" LicenseUrl="https://github.com/qdrant/qdrant/blob/master/LICENSE" RepositoryUrl="https://github.com/qdrant/qdrant" UseCase="@T("Qdrant Edge is an embedded vector database and vector similarity search engine. We use it to realize local RAG—retrieval-augmented generation—within AI Studio. Thanks for the effort and great work that has been and is being put into Qdrant.")"/>
|
||||||
<ThirdPartyComponent Name="SQLite" Developer="SQLite developers & Open Source Community" LicenseName="Public Domain" LicenseUrl="https://www.sqlite.org/copyright.html" RepositoryUrl="https://www.sqlite.org/src/" UseCase="@T("SQLite stores local RAG indexing metadata and the file fingerprints used to decide whether local files need to be indexed again, without requiring a separate database server or a system SQLite installation.")"/>
|
<ThirdPartyComponent Name="SQLite" Developer="SQLite developers & Open Source Community" LicenseName="Public Domain" LicenseUrl="https://www.sqlite.org/copyright.html" RepositoryUrl="https://www.sqlite.org/src/" UseCase="@T("SQLite stores local RAG indexing metadata, searchable chunk text, and the file fingerprints used to decide whether local files need to be indexed again, without requiring a separate database server or a system SQLite installation.")"/>
|
||||||
<ThirdPartyComponent Name="axum" Developer="David Pedersen, Jonas Platte, tottoto, David Mládek, Yann Simon, Tobias Bieniek, Open Source Community & Tokio Project" LicenseName="MIT" LicenseUrl="https://github.com/tokio-rs/axum/blob/main/LICENSE" RepositoryUrl="https://github.com/tokio-rs/axum" UseCase="@T("Axum is used to provide the small internal service that connects the Rust runtime with the app's user interface. This lets both parts of AI Studio exchange information while the app is running.")"/>
|
<ThirdPartyComponent Name="axum" Developer="David Pedersen, Jonas Platte, tottoto, David Mládek, Yann Simon, Tobias Bieniek, Open Source Community & Tokio Project" LicenseName="MIT" LicenseUrl="https://github.com/tokio-rs/axum/blob/main/LICENSE" RepositoryUrl="https://github.com/tokio-rs/axum" UseCase="@T("Axum is used to provide the small internal service that connects the Rust runtime with the app's user interface. This lets both parts of AI Studio exchange information while the app is running.")"/>
|
||||||
<ThirdPartyComponent Name="axum-server" Developer="Eray Karatay, Adi Salimgereyev, daxpedda & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/programatik29/axum-server/blob/master/LICENSE" RepositoryUrl="https://github.com/programatik29/axum-server" UseCase="@T("Axum server runs the internal axum service over a secure local connection. This helps AI Studio protect the communication between the Rust runtime and the user interface.")"/>
|
<ThirdPartyComponent Name="axum-server" Developer="Eray Karatay, Adi Salimgereyev, daxpedda & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/programatik29/axum-server/blob/master/LICENSE" RepositoryUrl="https://github.com/programatik29/axum-server" UseCase="@T("Axum server runs the internal axum service over a secure local connection. This helps AI Studio protect the communication between the Rust runtime and the user interface.")"/>
|
||||||
<ThirdPartyComponent Name="Rustls" Developer="Joe Birr-Pixton, Dirkjan Ochtman, Daniel McCarney, Brian Smith, Jacob Hoffman-Andrews, Jorge Aparicio & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rustls/rustls/blob/main/LICENSE-MIT" RepositoryUrl="https://github.com/rustls/rustls" UseCase="@T("Rustls helps secure the internal connection between the app's user interface and the Rust runtime. This protects the local communication that AI Studio needs while it is running.")"/>
|
<ThirdPartyComponent Name="Rustls" Developer="Joe Birr-Pixton, Dirkjan Ochtman, Daniel McCarney, Brian Smith, Jacob Hoffman-Andrews, Jorge Aparicio & Open Source Community" LicenseName="MIT" LicenseUrl="https://github.com/rustls/rustls/blob/main/LICENSE-MIT" RepositoryUrl="https://github.com/rustls/rustls" UseCase="@T("Rustls helps secure the internal connection between the app's user interface and the Rust runtime. This protects the local communication that AI Studio needs while it is running.")"/>
|
||||||
|
|||||||
@ -150,6 +150,7 @@ CONFIG["EMBEDDING_PROVIDERS"] = {}
|
|||||||
|
|
||||||
-- ERI v1 data sources for retrieval-augmented generation:
|
-- ERI v1 data sources for retrieval-augmented generation:
|
||||||
CONFIG["DATA_SOURCES"] = {}
|
CONFIG["DATA_SOURCES"] = {}
|
||||||
|
-- Allowed compliance levels are: UNTRUSTED, UNKNOWN, VERY_LOW, LOW, MODERATE, MEDIUM, HIGH
|
||||||
|
|
||||||
-- Example: ERI v1 data source with a shared access token.
|
-- Example: ERI v1 data source with a shared access token.
|
||||||
-- CONFIG["DATA_SOURCES"][#CONFIG["DATA_SOURCES"]+1] = {
|
-- CONFIG["DATA_SOURCES"][#CONFIG["DATA_SOURCES"]+1] = {
|
||||||
@ -161,6 +162,7 @@ CONFIG["DATA_SOURCES"] = {}
|
|||||||
-- ["AuthMethod"] = "TOKEN",
|
-- ["AuthMethod"] = "TOKEN",
|
||||||
-- ["Token"] = "ENC:v1:<base64-encoded encrypted token>",
|
-- ["Token"] = "ENC:v1:<base64-encoded encrypted token>",
|
||||||
-- ["SecurityPolicy"] = "SELF_HOSTED",
|
-- ["SecurityPolicy"] = "SELF_HOSTED",
|
||||||
|
-- ["ComplianceLevel"] = "UNKNOWN",
|
||||||
-- ["SelectedRetrievalId"] = "<retrieval process ID from the ERI server>",
|
-- ["SelectedRetrievalId"] = "<retrieval process ID from the ERI server>",
|
||||||
-- ["MaxMatches"] = 10,
|
-- ["MaxMatches"] = 10,
|
||||||
-- }
|
-- }
|
||||||
@ -177,6 +179,7 @@ CONFIG["DATA_SOURCES"] = {}
|
|||||||
-- ["Username"] = "<shared username>",
|
-- ["Username"] = "<shared username>",
|
||||||
-- ["Password"] = "ENC:v1:<base64-encoded encrypted password>",
|
-- ["Password"] = "ENC:v1:<base64-encoded encrypted password>",
|
||||||
-- ["SecurityPolicy"] = "SELF_HOSTED",
|
-- ["SecurityPolicy"] = "SELF_HOSTED",
|
||||||
|
-- ["ComplianceLevel"] = "UNKNOWN",
|
||||||
-- ["SelectedRetrievalId"] = "<retrieval process ID from the ERI server>",
|
-- ["SelectedRetrievalId"] = "<retrieval process ID from the ERI server>",
|
||||||
-- ["MaxMatches"] = 10,
|
-- ["MaxMatches"] = 10,
|
||||||
-- }
|
-- }
|
||||||
@ -192,6 +195,7 @@ CONFIG["DATA_SOURCES"] = {}
|
|||||||
-- ["UsernamePasswordMode"] = "OS_USERNAME_SHARED_PASSWORD",
|
-- ["UsernamePasswordMode"] = "OS_USERNAME_SHARED_PASSWORD",
|
||||||
-- ["Password"] = "ENC:v1:<base64-encoded encrypted password>",
|
-- ["Password"] = "ENC:v1:<base64-encoded encrypted password>",
|
||||||
-- ["SecurityPolicy"] = "SELF_HOSTED",
|
-- ["SecurityPolicy"] = "SELF_HOSTED",
|
||||||
|
-- ["ComplianceLevel"] = "UNKNOWN",
|
||||||
-- ["SelectedRetrievalId"] = "<retrieval process ID from the ERI server>",
|
-- ["SelectedRetrievalId"] = "<retrieval process ID from the ERI server>",
|
||||||
-- ["MaxMatches"] = 10,
|
-- ["MaxMatches"] = 10,
|
||||||
-- }
|
-- }
|
||||||
|
|||||||
@ -12,6 +12,7 @@ public static class ConfidenceLevelExtensions
|
|||||||
ConfidenceLevel.NONE => TB("No provider selected"),
|
ConfidenceLevel.NONE => TB("No provider selected"),
|
||||||
|
|
||||||
ConfidenceLevel.UNTRUSTED => TB("Untrusted"),
|
ConfidenceLevel.UNTRUSTED => TB("Untrusted"),
|
||||||
|
ConfidenceLevel.UNKNOWN => TB("Unknown"),
|
||||||
ConfidenceLevel.VERY_LOW => TB("Very Low"),
|
ConfidenceLevel.VERY_LOW => TB("Very Low"),
|
||||||
ConfidenceLevel.LOW => TB("Low"),
|
ConfidenceLevel.LOW => TB("Low"),
|
||||||
ConfidenceLevel.MODERATE => TB("Moderate"),
|
ConfidenceLevel.MODERATE => TB("Moderate"),
|
||||||
|
|||||||
@ -294,6 +294,17 @@ public static class ConfigurationSelectDataFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<ConfigurationSelectData<ConfidenceLevel>> GetDataSourceComplianceLevelsData()
|
||||||
|
{
|
||||||
|
foreach (var level in Enum.GetValues<ConfidenceLevel>())
|
||||||
|
{
|
||||||
|
if (level is ConfidenceLevel.NONE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
yield return new(level.GetName(), level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static IEnumerable<ConfigurationSelectData<Themes>> GetThemesData()
|
public static IEnumerable<ConfigurationSelectData<Themes>> GetThemesData()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
using AIStudio.Assistants.ERI;
|
using AIStudio.Assistants.ERI;
|
||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Tools.ERIClient;
|
using AIStudio.Tools.ERIClient;
|
||||||
using AIStudio.Tools.ERIClient.DataModel;
|
using AIStudio.Tools.ERIClient.DataModel;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
@ -57,6 +58,9 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ConfidenceLevel ComplianceLevel { get; init; } = ConfidenceLevel.UNKNOWN;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsEnterpriseConfiguration { get; init; }
|
public bool IsEnterpriseConfiguration { get; init; }
|
||||||
|
|
||||||
@ -206,6 +210,16 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var complianceLevel = ConfidenceLevel.UNKNOWN;
|
||||||
|
if (table.TryGetValue("ComplianceLevel", out var complianceLevelValue) &&
|
||||||
|
(!complianceLevelValue.TryRead<string>(out var complianceLevelText) ||
|
||||||
|
!Enum.TryParse(complianceLevelText, true, out complianceLevel) ||
|
||||||
|
complianceLevel is ConfidenceLevel.NONE))
|
||||||
|
{
|
||||||
|
LOGGER.LogWarning($"The configured data source {idx} contains an invalid compliance level. Falling back to UNKNOWN. (Plugin ID: {configPluginId})");
|
||||||
|
complianceLevel = ConfidenceLevel.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
if (!table.TryGetValue("SelectedRetrievalId", out var selectedRetrievalIdValue) || !selectedRetrievalIdValue.TryRead<string>(out var selectedRetrievalId) || string.IsNullOrWhiteSpace(selectedRetrievalId))
|
if (!table.TryGetValue("SelectedRetrievalId", out var selectedRetrievalIdValue) || !selectedRetrievalIdValue.TryRead<string>(out var selectedRetrievalId) || string.IsNullOrWhiteSpace(selectedRetrievalId))
|
||||||
{
|
{
|
||||||
LOGGER.LogWarning($"The configured data source {idx} must specify a selected retrieval ID. (Plugin ID: {configPluginId})");
|
LOGGER.LogWarning($"The configured data source {idx} must specify a selected retrieval ID. (Plugin ID: {configPluginId})");
|
||||||
@ -263,6 +277,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
Username = username,
|
Username = username,
|
||||||
UsernamePasswordMode = usernamePasswordMode,
|
UsernamePasswordMode = usernamePasswordMode,
|
||||||
SecurityPolicy = securityPolicy,
|
SecurityPolicy = securityPolicy,
|
||||||
|
ComplianceLevel = complianceLevel,
|
||||||
Version = ERIVersion.V1,
|
Version = ERIVersion.V1,
|
||||||
SelectedRetrievalId = selectedRetrievalId,
|
SelectedRetrievalId = selectedRetrievalId,
|
||||||
MaxMatches = (ushort)maxMatches,
|
MaxMatches = (ushort)maxMatches,
|
||||||
@ -323,6 +338,7 @@ public readonly record struct DataSourceERI_V1 : IERIDataSource
|
|||||||
{{usernameLine}}
|
{{usernameLine}}
|
||||||
{{secretLine}}
|
{{secretLine}}
|
||||||
["SecurityPolicy"] = "{{this.SecurityPolicy}}",
|
["SecurityPolicy"] = "{{this.SecurityPolicy}}",
|
||||||
|
["ComplianceLevel"] = "{{this.ComplianceLevel}}",
|
||||||
["SelectedRetrievalId"] = "{{LuaTools.EscapeLuaString(this.SelectedRetrievalId)}}",
|
["SelectedRetrievalId"] = "{{LuaTools.EscapeLuaString(this.SelectedRetrievalId)}}",
|
||||||
["MaxMatches"] = {{this.MaxMatches}},
|
["MaxMatches"] = {{this.MaxMatches}},
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Tools.RAG;
|
using AIStudio.Tools.RAG;
|
||||||
|
|
||||||
namespace AIStudio.Settings.DataModel;
|
namespace AIStudio.Settings.DataModel;
|
||||||
@ -42,6 +43,9 @@ public readonly record struct DataSourceLocalDirectory : IInternalDataSource
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ConfidenceLevel ComplianceLevel { get; init; } = ConfidenceLevel.UNKNOWN;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsEnterpriseConfiguration { get; init; }
|
public bool IsEnterpriseConfiguration { get; init; }
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Tools.RAG;
|
using AIStudio.Tools.RAG;
|
||||||
|
|
||||||
namespace AIStudio.Settings.DataModel;
|
namespace AIStudio.Settings.DataModel;
|
||||||
@ -42,6 +43,9 @@ public readonly record struct DataSourceLocalFile : IInternalDataSource
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
public DataSourceSecurity SecurityPolicy { get; init; } = DataSourceSecurity.NOT_SPECIFIED;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public ConfidenceLevel ComplianceLevel { get; init; } = ConfidenceLevel.UNKNOWN;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool IsEnterpriseConfiguration { get; init; }
|
public bool IsEnterpriseConfiguration { get; init; }
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
using AIStudio.Chat;
|
using AIStudio.Chat;
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
using AIStudio.Tools.RAG;
|
using AIStudio.Tools.RAG;
|
||||||
@ -25,6 +26,11 @@ public interface IDataSource : IConfigurationObject
|
|||||||
/// Which data security policy is applied to this data source?
|
/// Which data security policy is applied to this data source?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DataSourceSecurity SecurityPolicy { get; init; }
|
public DataSourceSecurity SecurityPolicy { get; init; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Which compliance level is assigned to this data source?
|
||||||
|
/// </summary>
|
||||||
|
public ConfidenceLevel ComplianceLevel { get; init; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The maximum number of matches to return when retrieving data from the ERI server.
|
/// The maximum number of matches to return when retrieving data from the ERI server.
|
||||||
|
|||||||
@ -65,7 +65,7 @@ public sealed partial class DatabaseClientProvider(RustService rustService, ILog
|
|||||||
|
|
||||||
return new NoEmbeddingStateClient(
|
return new NoEmbeddingStateClient(
|
||||||
client.Name,
|
client.Name,
|
||||||
"The configured database client does not support embedding state operations.",
|
"The configured database client does not support local RAG index operations.",
|
||||||
client.Status);
|
client.Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,15 +24,30 @@ public abstract class EmbeddingStateClient(string name, string path) : DatabaseC
|
|||||||
|
|
||||||
public abstract Task DeleteFileAsync(string dataSourceId, string filePath, CancellationToken token);
|
public abstract Task DeleteFileAsync(string dataSourceId, string filePath, CancellationToken token);
|
||||||
|
|
||||||
|
public abstract Task UpsertChunksAsync(string dataSourceId, IReadOnlyList<EmbeddingStateChunk> chunks, CancellationToken token);
|
||||||
|
|
||||||
public abstract Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token);
|
public abstract Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed record EmbeddingStateFile(
|
public sealed record EmbeddingStateFile(
|
||||||
string FilePath,
|
string ParentFileId,
|
||||||
|
string AbsolutePath,
|
||||||
string FileName,
|
string FileName,
|
||||||
string RelativePath,
|
string RelativePath,
|
||||||
|
string FileType,
|
||||||
string Fingerprint,
|
string Fingerprint,
|
||||||
long FileSize,
|
long FileSize,
|
||||||
|
DateTime CreationUtc,
|
||||||
DateTime LastWriteUtc,
|
DateTime LastWriteUtc,
|
||||||
DateTime EmbeddedAtUtc,
|
DateTime EmbeddedAtUtc,
|
||||||
int ChunkCount);
|
int ChunkCount,
|
||||||
|
string ComplianceLevel,
|
||||||
|
int ComplianceLevelRank);
|
||||||
|
|
||||||
|
public sealed record EmbeddingStateChunk(
|
||||||
|
string ChunkId,
|
||||||
|
string ParentFileId,
|
||||||
|
int? PageNumber,
|
||||||
|
int ChunkIndex,
|
||||||
|
string ChunkText,
|
||||||
|
DateTime EmbeddedAtUtc);
|
||||||
|
|||||||
@ -44,6 +44,8 @@ public sealed class NoEmbeddingStateClient(string name, string? unavailableReaso
|
|||||||
|
|
||||||
public override Task DeleteFileAsync(string dataSourceId, string filePath, CancellationToken token) => Task.CompletedTask;
|
public override Task DeleteFileAsync(string dataSourceId, string filePath, CancellationToken token) => Task.CompletedTask;
|
||||||
|
|
||||||
|
public override Task UpsertChunksAsync(string dataSourceId, IReadOnlyList<EmbeddingStateChunk> chunks, CancellationToken token) => Task.CompletedTask;
|
||||||
|
|
||||||
public override Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token) => Task.CompletedTask;
|
public override Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token) => Task.CompletedTask;
|
||||||
|
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
|
|||||||
@ -14,8 +14,8 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
string basePath,
|
string basePath,
|
||||||
string version) : EmbeddingStateClient(name, basePath)
|
string version) : EmbeddingStateClient(name, basePath)
|
||||||
{
|
{
|
||||||
private const string DATABASE_NAME = "SQLite";
|
private const string DATABASE_NAME = "Local RAG Index";
|
||||||
private const string DATABASE_FILENAME = "rag-embedding-state.sqlite3";
|
private const string DATABASE_FILENAME = "rag-index.sqlite3";
|
||||||
|
|
||||||
private readonly string databasePath = databasePath;
|
private readonly string databasePath = databasePath;
|
||||||
private readonly string connectionString = new SqliteConnectionStringBuilder
|
private readonly string connectionString = new SqliteConnectionStringBuilder
|
||||||
@ -57,7 +57,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
logger.LogWarning(exception, "{DatabaseName} is not available. Indexed file fingerprints are disabled.", DATABASE_NAME);
|
logger.LogWarning(exception, "{DatabaseName} is not available. Indexed file fingerprints and search chunks are disabled.", DATABASE_NAME);
|
||||||
return CreateNoEmbeddingStateClient(DATABASE_NAME, exception.Message, DatabaseClientStatus.UNAVAILABLE, databaseClientLogger);
|
return CreateNoEmbeddingStateClient(DATABASE_NAME, exception.Message, DatabaseClientStatus.UNAVAILABLE, databaseClientLogger);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -69,6 +69,7 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
yield return (TB("Storage size"), this.GetStorageSize());
|
yield return (TB("Storage size"), this.GetStorageSize());
|
||||||
yield return (TB("Indexed data sources"), (await this.CountAsync("data_sources", CancellationToken.None)).ToString(CultureInfo.InvariantCulture));
|
yield return (TB("Indexed data sources"), (await this.CountAsync("data_sources", CancellationToken.None)).ToString(CultureInfo.InvariantCulture));
|
||||||
yield return (TB("Indexed files"), (await this.CountAsync("embedded_files", CancellationToken.None)).ToString(CultureInfo.InvariantCulture));
|
yield return (TB("Indexed files"), (await this.CountAsync("embedded_files", CancellationToken.None)).ToString(CultureInfo.InvariantCulture));
|
||||||
|
yield return (TB("Search chunks"), (await this.CountAsync("embedding_chunks", CancellationToken.None)).ToString(CultureInfo.InvariantCulture));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<DataSourceEmbeddingManifest> GetManifestAsync(string dataSourceId, CancellationToken token)
|
public override async Task<DataSourceEmbeddingManifest> GetManifestAsync(string dataSourceId, CancellationToken token)
|
||||||
@ -94,9 +95,10 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
await using (var command = CreateCommand(connection, """
|
await using (var command = CreateCommand(connection, """
|
||||||
SELECT file_path, fingerprint, file_size, last_write_utc, embedded_at_utc, chunk_count
|
SELECT absolute_path, fingerprint, file_size, last_write_utc, embedded_at_utc, chunk_count
|
||||||
FROM embedded_files
|
FROM embedded_files
|
||||||
WHERE data_source_id = $dataSourceId
|
WHERE data_source_id = $dataSourceId
|
||||||
|
AND chunk_count > 0
|
||||||
"""))
|
"""))
|
||||||
{
|
{
|
||||||
command.Parameters.AddWithValue("$dataSourceId", dataSourceId);
|
command.Parameters.AddWithValue("$dataSourceId", dataSourceId);
|
||||||
@ -197,43 +199,64 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
await using var connection = await this.OpenConnectionAsync(token);
|
await using var connection = await this.OpenConnectionAsync(token);
|
||||||
await ExecuteNonQueryAsync(connection, """
|
await ExecuteNonQueryAsync(connection, """
|
||||||
INSERT INTO embedded_files (
|
INSERT INTO embedded_files (
|
||||||
|
parent_file_id,
|
||||||
data_source_id,
|
data_source_id,
|
||||||
file_path,
|
absolute_path,
|
||||||
file_name,
|
file_name,
|
||||||
relative_path,
|
relative_path,
|
||||||
|
file_type,
|
||||||
fingerprint,
|
fingerprint,
|
||||||
file_size,
|
file_size,
|
||||||
|
creation_utc,
|
||||||
last_write_utc,
|
last_write_utc,
|
||||||
embedded_at_utc,
|
embedded_at_utc,
|
||||||
chunk_count)
|
chunk_count,
|
||||||
|
compliance_level,
|
||||||
|
compliance_level_rank)
|
||||||
VALUES (
|
VALUES (
|
||||||
|
$parentFileId,
|
||||||
$dataSourceId,
|
$dataSourceId,
|
||||||
$filePath,
|
$absolutePath,
|
||||||
$fileName,
|
$fileName,
|
||||||
$relativePath,
|
$relativePath,
|
||||||
|
$fileType,
|
||||||
$fingerprint,
|
$fingerprint,
|
||||||
$fileSize,
|
$fileSize,
|
||||||
|
$creationUtc,
|
||||||
$lastWriteUtc,
|
$lastWriteUtc,
|
||||||
$embeddedAtUtc,
|
$embeddedAtUtc,
|
||||||
$chunkCount)
|
$chunkCount,
|
||||||
ON CONFLICT(data_source_id, file_path) DO UPDATE SET
|
$complianceLevel,
|
||||||
|
$complianceLevelRank)
|
||||||
|
ON CONFLICT(parent_file_id) DO UPDATE SET
|
||||||
|
data_source_id = excluded.data_source_id,
|
||||||
|
absolute_path = excluded.absolute_path,
|
||||||
file_name = excluded.file_name,
|
file_name = excluded.file_name,
|
||||||
relative_path = excluded.relative_path,
|
relative_path = excluded.relative_path,
|
||||||
|
file_type = excluded.file_type,
|
||||||
fingerprint = excluded.fingerprint,
|
fingerprint = excluded.fingerprint,
|
||||||
file_size = excluded.file_size,
|
file_size = excluded.file_size,
|
||||||
|
creation_utc = excluded.creation_utc,
|
||||||
last_write_utc = excluded.last_write_utc,
|
last_write_utc = excluded.last_write_utc,
|
||||||
embedded_at_utc = excluded.embedded_at_utc,
|
embedded_at_utc = excluded.embedded_at_utc,
|
||||||
chunk_count = excluded.chunk_count
|
chunk_count = excluded.chunk_count,
|
||||||
|
compliance_level = excluded.compliance_level,
|
||||||
|
compliance_level_rank = excluded.compliance_level_rank
|
||||||
""", token,
|
""", token,
|
||||||
|
("$parentFileId", file.ParentFileId),
|
||||||
("$dataSourceId", dataSourceId),
|
("$dataSourceId", dataSourceId),
|
||||||
("$filePath", file.FilePath),
|
("$absolutePath", file.AbsolutePath),
|
||||||
("$fileName", file.FileName),
|
("$fileName", file.FileName),
|
||||||
("$relativePath", file.RelativePath),
|
("$relativePath", file.RelativePath),
|
||||||
|
("$fileType", file.FileType),
|
||||||
("$fingerprint", file.Fingerprint),
|
("$fingerprint", file.Fingerprint),
|
||||||
("$fileSize", file.FileSize),
|
("$fileSize", file.FileSize),
|
||||||
|
("$creationUtc", ToUtcText(file.CreationUtc)),
|
||||||
("$lastWriteUtc", ToUtcText(file.LastWriteUtc)),
|
("$lastWriteUtc", ToUtcText(file.LastWriteUtc)),
|
||||||
("$embeddedAtUtc", ToUtcText(file.EmbeddedAtUtc)),
|
("$embeddedAtUtc", ToUtcText(file.EmbeddedAtUtc)),
|
||||||
("$chunkCount", file.ChunkCount));
|
("$chunkCount", file.ChunkCount),
|
||||||
|
("$complianceLevel", file.ComplianceLevel),
|
||||||
|
("$complianceLevelRank", file.ComplianceLevelRank));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task DeleteFileAsync(string dataSourceId, string filePath, CancellationToken token)
|
public override async Task DeleteFileAsync(string dataSourceId, string filePath, CancellationToken token)
|
||||||
@ -242,12 +265,57 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
await ExecuteNonQueryAsync(connection, """
|
await ExecuteNonQueryAsync(connection, """
|
||||||
DELETE FROM embedded_files
|
DELETE FROM embedded_files
|
||||||
WHERE data_source_id = $dataSourceId
|
WHERE data_source_id = $dataSourceId
|
||||||
AND file_path = $filePath
|
AND absolute_path = $filePath
|
||||||
""", token,
|
""", token,
|
||||||
("$dataSourceId", dataSourceId),
|
("$dataSourceId", dataSourceId),
|
||||||
("$filePath", filePath));
|
("$filePath", filePath));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task UpsertChunksAsync(string dataSourceId, IReadOnlyList<EmbeddingStateChunk> chunks, CancellationToken token)
|
||||||
|
{
|
||||||
|
if (chunks.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await using var connection = await this.OpenConnectionAsync(token);
|
||||||
|
await using var transaction = (SqliteTransaction)await connection.BeginTransactionAsync(token);
|
||||||
|
|
||||||
|
foreach (var chunk in chunks)
|
||||||
|
{
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
await ExecuteNonQueryAsync(connection, transaction, """
|
||||||
|
INSERT INTO embedding_chunks (
|
||||||
|
chunk_id,
|
||||||
|
parent_file_id,
|
||||||
|
page_number,
|
||||||
|
chunk_index,
|
||||||
|
chunk_text,
|
||||||
|
embedded_at_utc)
|
||||||
|
VALUES (
|
||||||
|
$chunkId,
|
||||||
|
$parentFileId,
|
||||||
|
$pageNumber,
|
||||||
|
$chunkIndex,
|
||||||
|
$chunkText,
|
||||||
|
$embeddedAtUtc)
|
||||||
|
ON CONFLICT(chunk_id) DO UPDATE SET
|
||||||
|
parent_file_id = excluded.parent_file_id,
|
||||||
|
page_number = excluded.page_number,
|
||||||
|
chunk_index = excluded.chunk_index,
|
||||||
|
chunk_text = excluded.chunk_text,
|
||||||
|
embedded_at_utc = excluded.embedded_at_utc
|
||||||
|
""", token,
|
||||||
|
("$chunkId", chunk.ChunkId),
|
||||||
|
("$parentFileId", chunk.ParentFileId),
|
||||||
|
("$pageNumber", chunk.PageNumber),
|
||||||
|
("$chunkIndex", chunk.ChunkIndex),
|
||||||
|
("$chunkText", chunk.ChunkText),
|
||||||
|
("$embeddedAtUtc", ToUtcText(chunk.EmbeddedAtUtc)));
|
||||||
|
}
|
||||||
|
|
||||||
|
await transaction.CommitAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
public override async Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token)
|
public override async Task DeleteDataSourceAsync(string dataSourceId, CancellationToken token)
|
||||||
{
|
{
|
||||||
await using var connection = await this.OpenConnectionAsync(token);
|
await using var connection = await this.OpenConnectionAsync(token);
|
||||||
@ -281,26 +349,109 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS embedded_files (
|
CREATE TABLE IF NOT EXISTS embedded_files (
|
||||||
|
parent_file_id TEXT PRIMARY KEY,
|
||||||
data_source_id TEXT NOT NULL,
|
data_source_id TEXT NOT NULL,
|
||||||
file_path TEXT COLLATE NOCASE NOT NULL,
|
absolute_path TEXT COLLATE NOCASE NOT NULL,
|
||||||
file_name TEXT NOT NULL,
|
file_name TEXT NOT NULL,
|
||||||
relative_path TEXT NOT NULL,
|
relative_path TEXT NOT NULL,
|
||||||
|
file_type TEXT NOT NULL,
|
||||||
fingerprint TEXT NOT NULL,
|
fingerprint TEXT NOT NULL,
|
||||||
file_size INTEGER NOT NULL,
|
file_size INTEGER NOT NULL,
|
||||||
|
creation_utc TEXT NOT NULL,
|
||||||
last_write_utc TEXT NOT NULL,
|
last_write_utc TEXT NOT NULL,
|
||||||
embedded_at_utc TEXT NOT NULL,
|
embedded_at_utc TEXT NOT NULL,
|
||||||
chunk_count INTEGER NOT NULL,
|
chunk_count INTEGER NOT NULL,
|
||||||
PRIMARY KEY (data_source_id, file_path),
|
compliance_level TEXT NOT NULL,
|
||||||
|
compliance_level_rank INTEGER NOT NULL,
|
||||||
FOREIGN KEY (data_source_id)
|
FOREIGN KEY (data_source_id)
|
||||||
REFERENCES data_sources(data_source_id)
|
REFERENCES data_sources(data_source_id)
|
||||||
ON DELETE CASCADE
|
ON DELETE CASCADE,
|
||||||
|
UNIQUE(data_source_id, absolute_path)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS embedding_chunks (
|
||||||
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
chunk_id TEXT NOT NULL UNIQUE,
|
||||||
|
parent_file_id TEXT NOT NULL,
|
||||||
|
page_number INTEGER NULL,
|
||||||
|
chunk_index INTEGER NOT NULL,
|
||||||
|
chunk_text TEXT NOT NULL,
|
||||||
|
embedded_at_utc TEXT NOT NULL,
|
||||||
|
FOREIGN KEY (parent_file_id)
|
||||||
|
REFERENCES embedded_files(parent_file_id)
|
||||||
|
ON DELETE CASCADE,
|
||||||
|
UNIQUE(parent_file_id, chunk_index)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS idx_embedded_files_data_source
|
CREATE INDEX IF NOT EXISTS idx_embedded_files_data_source
|
||||||
ON embedded_files(data_source_id);
|
ON embedded_files(data_source_id);
|
||||||
""", token);
|
|
||||||
|
|
||||||
await EnsureColumnAsync(connection, "data_sources", "source_hash", "TEXT NOT NULL DEFAULT ''", token);
|
CREATE INDEX IF NOT EXISTS idx_embedded_files_absolute_path
|
||||||
|
ON embedded_files(absolute_path);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_embedded_files_file_type
|
||||||
|
ON embedded_files(file_type);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_embedded_files_compliance
|
||||||
|
ON embedded_files(compliance_level_rank);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_embedding_chunks_parent_file
|
||||||
|
ON embedding_chunks(parent_file_id);
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_embedding_chunks_page
|
||||||
|
ON embedding_chunks(page_number);
|
||||||
|
|
||||||
|
CREATE VIRTUAL TABLE IF NOT EXISTS embedding_chunks_fts
|
||||||
|
USING fts5(chunk_id UNINDEXED, file_name, chunk_text);
|
||||||
|
|
||||||
|
CREATE TRIGGER IF NOT EXISTS embedding_chunks_ai
|
||||||
|
AFTER INSERT ON embedding_chunks
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO embedding_chunks_fts(rowid, chunk_id, file_name, chunk_text)
|
||||||
|
VALUES (
|
||||||
|
new.id,
|
||||||
|
new.chunk_id,
|
||||||
|
(SELECT file_name FROM embedded_files WHERE parent_file_id = new.parent_file_id),
|
||||||
|
new.chunk_text);
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER IF NOT EXISTS embedding_chunks_ad
|
||||||
|
AFTER DELETE ON embedding_chunks
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM embedding_chunks_fts
|
||||||
|
WHERE rowid = old.id;
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER IF NOT EXISTS embedding_chunks_au
|
||||||
|
AFTER UPDATE ON embedding_chunks
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM embedding_chunks_fts
|
||||||
|
WHERE rowid = old.id;
|
||||||
|
|
||||||
|
INSERT INTO embedding_chunks_fts(rowid, chunk_id, file_name, chunk_text)
|
||||||
|
VALUES (
|
||||||
|
new.id,
|
||||||
|
new.chunk_id,
|
||||||
|
(SELECT file_name FROM embedded_files WHERE parent_file_id = new.parent_file_id),
|
||||||
|
new.chunk_text);
|
||||||
|
END;
|
||||||
|
|
||||||
|
CREATE TRIGGER IF NOT EXISTS embedded_files_file_name_au
|
||||||
|
AFTER UPDATE OF file_name ON embedded_files
|
||||||
|
BEGIN
|
||||||
|
DELETE FROM embedding_chunks_fts
|
||||||
|
WHERE rowid IN (
|
||||||
|
SELECT id
|
||||||
|
FROM embedding_chunks
|
||||||
|
WHERE parent_file_id = new.parent_file_id
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO embedding_chunks_fts(rowid, chunk_id, file_name, chunk_text)
|
||||||
|
SELECT id, chunk_id, new.file_name, chunk_text
|
||||||
|
FROM embedding_chunks
|
||||||
|
WHERE parent_file_id = new.parent_file_id;
|
||||||
|
END;
|
||||||
|
""", token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> GetSqliteVersionAsync(CancellationToken token)
|
private async Task<string> GetSqliteVersionAsync(CancellationToken token)
|
||||||
@ -319,21 +470,6 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
return Convert.ToInt64(countObject, CultureInfo.InvariantCulture);
|
return Convert.ToInt64(countObject, CultureInfo.InvariantCulture);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task EnsureColumnAsync(SqliteConnection connection, string tableName, string columnName, string columnDefinition, CancellationToken token)
|
|
||||||
{
|
|
||||||
await using (var command = CreateCommand(connection, $"PRAGMA table_info({tableName})"))
|
|
||||||
{
|
|
||||||
await using var reader = await command.ExecuteReaderAsync(token);
|
|
||||||
while (await reader.ReadAsync(token))
|
|
||||||
{
|
|
||||||
if (string.Equals(reader.GetString(1), columnName, StringComparison.OrdinalIgnoreCase))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await ExecuteNonQueryAsync(connection, $"ALTER TABLE {tableName} ADD COLUMN {columnName} {columnDefinition}", token);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<SqliteConnection> OpenConnectionAsync(CancellationToken token)
|
private async Task<SqliteConnection> OpenConnectionAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
var connection = new SqliteConnection(this.connectionString);
|
var connection = new SqliteConnection(this.connectionString);
|
||||||
@ -361,6 +497,21 @@ public sealed class SqliteEmbeddingStateClientImplementation(
|
|||||||
await command.ExecuteNonQueryAsync(token);
|
await command.ExecuteNonQueryAsync(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task ExecuteNonQueryAsync(
|
||||||
|
SqliteConnection connection,
|
||||||
|
SqliteTransaction transaction,
|
||||||
|
string commandText,
|
||||||
|
CancellationToken token,
|
||||||
|
params (string Name, object? Value)[] parameters)
|
||||||
|
{
|
||||||
|
await using var command = CreateCommand(connection, commandText);
|
||||||
|
command.Transaction = transaction;
|
||||||
|
foreach (var (name, value) in parameters)
|
||||||
|
command.Parameters.AddWithValue(name, value ?? DBNull.Value);
|
||||||
|
|
||||||
|
await command.ExecuteNonQueryAsync(token);
|
||||||
|
}
|
||||||
|
|
||||||
private static string ToUtcText(DateTime dateTime)
|
private static string ToUtcText(DateTime dateTime)
|
||||||
{
|
{
|
||||||
var utc = dateTime.Kind is DateTimeKind.Utc ? dateTime : dateTime.ToUniversalTime();
|
var utc = dateTime.Kind is DateTimeKind.Utc ? dateTime : dateTime.ToUniversalTime();
|
||||||
|
|||||||
@ -6,11 +6,19 @@ public sealed record VectorStoragePoint(
|
|||||||
string DataSourceId,
|
string DataSourceId,
|
||||||
string DataSourceName,
|
string DataSourceName,
|
||||||
string DataSourceType,
|
string DataSourceType,
|
||||||
|
string ChunkId,
|
||||||
|
string ParentFileId,
|
||||||
string FilePath,
|
string FilePath,
|
||||||
|
string AbsolutePath,
|
||||||
string FileName,
|
string FileName,
|
||||||
string RelativePath,
|
string RelativePath,
|
||||||
|
string FileType,
|
||||||
|
int? PageNumber,
|
||||||
int ChunkIndex,
|
int ChunkIndex,
|
||||||
string Text,
|
string Text,
|
||||||
string Fingerprint,
|
string Fingerprint,
|
||||||
|
DateTime CreationUtc,
|
||||||
DateTime LastWriteUtc,
|
DateTime LastWriteUtc,
|
||||||
DateTime EmbeddedAtUtc);
|
DateTime EmbeddedAtUtc,
|
||||||
|
string ComplianceLevel,
|
||||||
|
int ComplianceLevelRank);
|
||||||
|
|||||||
@ -2,8 +2,10 @@ using System.Security.Cryptography;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
using AIStudio.Provider;
|
||||||
using AIStudio.Settings;
|
using AIStudio.Settings;
|
||||||
using AIStudio.Settings.DataModel;
|
using AIStudio.Settings.DataModel;
|
||||||
|
using AIStudio.Tools.Databases.EmbeddingState;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
using AIStudio.Tools.Rust;
|
using AIStudio.Tools.Rust;
|
||||||
|
|
||||||
@ -27,6 +29,8 @@ public sealed partial class DataSourceEmbeddingService
|
|||||||
|
|
||||||
private sealed record ExtractedFileContent(string Text, IReadOnlyList<string> SourceSegments);
|
private sealed record ExtractedFileContent(string Text, IReadOnlyList<string> SourceSegments);
|
||||||
|
|
||||||
|
private sealed record EmbeddingChunkDraft(string ChunkId, string Text, int ChunkIndex, int? PageNumber);
|
||||||
|
|
||||||
private sealed record ChunkingOptions(int MaxChunkTokenLength, int OverlapTokenLength);
|
private sealed record ChunkingOptions(int MaxChunkTokenLength, int OverlapTokenLength);
|
||||||
|
|
||||||
private sealed record ChunkingStrategy(string Name, IReadOnlyList<ChunkingRule> Rules);
|
private sealed record ChunkingStrategy(string Name, IReadOnlyList<ChunkingRule> Rules);
|
||||||
@ -748,6 +752,7 @@ public sealed partial class DataSourceEmbeddingService
|
|||||||
embeddingProvider.Hostname,
|
embeddingProvider.Hostname,
|
||||||
embeddingProvider.TokenizerPath,
|
embeddingProvider.TokenizerPath,
|
||||||
embeddingProvider.EffectiveTokenLimit,
|
embeddingProvider.EffectiveTokenLimit,
|
||||||
|
GetDataSourceComplianceLevel(dataSource).ToString(),
|
||||||
dataSource is IInternalDataSource internalDataSource ? internalDataSource.MaxChunkTokenLength : 0,
|
dataSource is IInternalDataSource internalDataSource ? internalDataSource.MaxChunkTokenLength : 0,
|
||||||
dataSource is IInternalDataSource overlapDataSource ? overlapDataSource.ChunkOverlapTokenLength : 0,
|
dataSource is IInternalDataSource overlapDataSource ? overlapDataSource.ChunkOverlapTokenLength : 0,
|
||||||
chunkingOptions.MaxChunkTokenLength,
|
chunkingOptions.MaxChunkTokenLength,
|
||||||
@ -847,6 +852,59 @@ public sealed partial class DataSourceEmbeddingService
|
|||||||
return Convert.ToHexString(bytes);
|
return Convert.ToHexString(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private EmbeddingStateFile CreateEmbeddingStateFile(IDataSource dataSource, FileInfo file, string fingerprint, int chunkCount, DateTime embeddedAtUtc)
|
||||||
|
{
|
||||||
|
file.Refresh();
|
||||||
|
var absolutePath = Path.GetFullPath(file.FullName);
|
||||||
|
var complianceLevel = GetDataSourceComplianceLevel(dataSource);
|
||||||
|
return new(
|
||||||
|
this.CreateParentFileId(dataSource.Id, absolutePath),
|
||||||
|
absolutePath,
|
||||||
|
file.Name,
|
||||||
|
this.TryGetRelativePath(dataSource, file),
|
||||||
|
GetFileType(file),
|
||||||
|
fingerprint,
|
||||||
|
file.Exists ? file.Length : 0,
|
||||||
|
file.Exists ? file.CreationTimeUtc : DateTime.UnixEpoch,
|
||||||
|
file.Exists ? file.LastWriteTimeUtc : DateTime.UnixEpoch,
|
||||||
|
embeddedAtUtc,
|
||||||
|
chunkCount,
|
||||||
|
complianceLevel.ToString(),
|
||||||
|
(int)complianceLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IReadOnlyList<EmbeddingStateChunk> CreateEmbeddingStateChunks(EmbeddingStateFile parentFile, IReadOnlyList<EmbeddingChunkDraft> batch, DateTime embeddedAtUtc)
|
||||||
|
{
|
||||||
|
return batch
|
||||||
|
.Select(chunk => new EmbeddingStateChunk(
|
||||||
|
chunk.ChunkId,
|
||||||
|
parentFile.ParentFileId,
|
||||||
|
chunk.PageNumber,
|
||||||
|
chunk.ChunkIndex,
|
||||||
|
chunk.Text,
|
||||||
|
embeddedAtUtc))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ConfidenceLevel GetDataSourceComplianceLevel(IDataSource dataSource) =>
|
||||||
|
dataSource.ComplianceLevel is ConfidenceLevel.NONE
|
||||||
|
? ConfidenceLevel.UNKNOWN
|
||||||
|
: dataSource.ComplianceLevel;
|
||||||
|
|
||||||
|
private static string GetFileType(FileInfo file)
|
||||||
|
{
|
||||||
|
var extension = file.Extension.TrimStart('.').ToLowerInvariant();
|
||||||
|
return string.IsNullOrWhiteSpace(extension) ? "unknown" : extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? TryExtractPageNumber(string chunk)
|
||||||
|
{
|
||||||
|
var match = Regex.Match(chunk, @"^\s*#\s+Page\s+(\d+)\b", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
|
||||||
|
return match.Success && int.TryParse(match.Groups[1].Value, out var pageNumber) && pageNumber > 0
|
||||||
|
? pageNumber
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
private string GetCollectionName(string dataSourceName, string dataSourceId)
|
private string GetCollectionName(string dataSourceName, string dataSourceId)
|
||||||
{
|
{
|
||||||
var safeId = dataSourceId
|
var safeId = dataSourceId
|
||||||
@ -864,9 +922,14 @@ public sealed partial class DataSourceEmbeddingService
|
|||||||
return $"rag_{safeName}_{safeId}";
|
return $"rag_{safeName}_{safeId}";
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreatePointId(string dataSourceId, string fingerprint, int chunkIndex)
|
private string CreatePointId(string dataSourceId, string fingerprint, int chunkIndex) =>
|
||||||
|
CreateStableGuid($"{dataSourceId}:chunk:{fingerprint}:{chunkIndex}");
|
||||||
|
|
||||||
|
private string CreateParentFileId(string dataSourceId, string absolutePath) =>
|
||||||
|
CreateStableGuid($"{dataSourceId}:parent-file:{absolutePath}");
|
||||||
|
|
||||||
|
private static string CreateStableGuid(string source)
|
||||||
{
|
{
|
||||||
var source = $"{dataSourceId}:{fingerprint}:{chunkIndex}";
|
|
||||||
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(source));
|
var hash = SHA256.HashData(Encoding.UTF8.GetBytes(source));
|
||||||
var guidBytes = hash[..16].ToArray();
|
var guidBytes = hash[..16].ToArray();
|
||||||
|
|
||||||
|
|||||||
@ -17,11 +17,11 @@ public sealed partial class DataSourceEmbeddingService
|
|||||||
embeddingState ??= await databaseClientProvider.GetEmbeddingStateAsync(token);
|
embeddingState ??= await databaseClientProvider.GetEmbeddingStateAsync(token);
|
||||||
if (!embeddingState.IsAvailable)
|
if (!embeddingState.IsAvailable)
|
||||||
{
|
{
|
||||||
logger.LogWarning("Could not delete SQLite embedding state for data source '{DataSourceId}' because the embedding state database '{DatabaseName}' is unavailable.", dataSourceId, embeddingState.Name);
|
logger.LogWarning("Could not delete local RAG index state for data source '{DataSourceId}' because the database '{DatabaseName}' is unavailable.", dataSourceId, embeddingState.Name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await embeddingState.DeleteDataSourceAsync(dataSourceId, token);
|
await embeddingState.DeleteDataSourceAsync(dataSourceId, token);
|
||||||
logger.LogInformation("Reset persisted embedding state for data source '{DataSourceId}'.", dataSourceId);
|
logger.LogInformation("Reset persisted local RAG index state for data source '{DataSourceId}'.", dataSourceId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -162,7 +162,7 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
var embeddingState = await databaseClientProvider.GetEmbeddingStateAsync(token);
|
var embeddingState = await databaseClientProvider.GetEmbeddingStateAsync(token);
|
||||||
if (!embeddingState.IsAvailable)
|
if (!embeddingState.IsAvailable)
|
||||||
{
|
{
|
||||||
logger.LogWarning("Locking identity settings for data source '{DataSourceId}' because the embedding state database '{DatabaseName}' is unavailable.", dataSourceId, embeddingState.Name);
|
logger.LogWarning("Locking identity settings for data source '{DataSourceId}' because the local RAG index database '{DatabaseName}' is unavailable.", dataSourceId, embeddingState.Name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -395,7 +395,7 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
dataSource.Id,
|
dataSource.Id,
|
||||||
embeddingState.Name);
|
embeddingState.Name);
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
this.UpsertStatus(this.GetFallbackStatus(dataSource, "The SQLite embedding state database is not available."));
|
this.UpsertStatus(this.GetFallbackStatus(dataSource, "The local RAG index database is not available."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -522,15 +522,7 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
chunkCount);
|
chunkCount);
|
||||||
await embeddingState.UpsertFileAsync(
|
await embeddingState.UpsertFileAsync(
|
||||||
dataSource.Id,
|
dataSource.Id,
|
||||||
new EmbeddingStateFile(
|
this.CreateEmbeddingStateFile(dataSource, file, fingerprint, chunkCount, embeddedAtUtc),
|
||||||
file.FullName,
|
|
||||||
file.Name,
|
|
||||||
this.TryGetRelativePath(dataSource, file),
|
|
||||||
fingerprint,
|
|
||||||
file.Length,
|
|
||||||
file.LastWriteTimeUtc,
|
|
||||||
embeddedAtUtc,
|
|
||||||
chunkCount),
|
|
||||||
token);
|
token);
|
||||||
manifest.Files[file.FullName] = record;
|
manifest.Files[file.FullName] = record;
|
||||||
completedFiles++;
|
completedFiles++;
|
||||||
@ -603,22 +595,26 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
file.FullName,
|
file.FullName,
|
||||||
collectionName);
|
collectionName);
|
||||||
await this.DeleteFilePointsAsync(vectorStore, collectionName, file.FullName, token);
|
await this.DeleteFilePointsAsync(vectorStore, collectionName, file.FullName, token);
|
||||||
|
await embeddingState.DeleteFileAsync(dataSource.Id, file.FullName, token);
|
||||||
|
|
||||||
|
var parentFile = this.CreateEmbeddingStateFile(dataSource, file, fingerprint, 0, DateTime.UtcNow);
|
||||||
|
await embeddingState.UpsertFileAsync(dataSource.Id, parentFile, token);
|
||||||
|
|
||||||
var embeddingBatchSize = embeddingProvider.EffectiveEmbeddingBatchSize;
|
var embeddingBatchSize = embeddingProvider.EffectiveEmbeddingBatchSize;
|
||||||
var batch = new List<(string Text, int ChunkIndex)>(embeddingBatchSize);
|
var batch = new List<EmbeddingChunkDraft>(embeddingBatchSize);
|
||||||
var totalChunkCount = 0;
|
var totalChunkCount = 0;
|
||||||
|
|
||||||
await foreach (var chunk in this.StreamEmbeddingChunksAsync(file.FullName, dataSource, embeddingProvider, token))
|
await foreach (var chunk in this.StreamEmbeddingChunksAsync(file.FullName, dataSource, embeddingProvider, token))
|
||||||
{
|
{
|
||||||
batch.Add((chunk, totalChunkCount));
|
batch.Add(new(this.CreatePointId(dataSource.Id, fingerprint, totalChunkCount), chunk, totalChunkCount, TryExtractPageNumber(chunk)));
|
||||||
totalChunkCount++;
|
totalChunkCount++;
|
||||||
|
|
||||||
if (batch.Count >= embeddingBatchSize)
|
if (batch.Count >= embeddingBatchSize)
|
||||||
await this.FlushBatchAsync(embeddingState, vectorStore, dataSource, file, fingerprint, embeddingProvider, provider, manifest, collectionName, batch, token);
|
await this.FlushBatchAsync(embeddingState, vectorStore, dataSource, file, fingerprint, parentFile, embeddingProvider, provider, manifest, collectionName, batch, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batch.Count > 0)
|
if (batch.Count > 0)
|
||||||
await this.FlushBatchAsync(embeddingState, vectorStore, dataSource, file, fingerprint, embeddingProvider, provider, manifest, collectionName, batch, token);
|
await this.FlushBatchAsync(embeddingState, vectorStore, dataSource, file, fingerprint, parentFile, embeddingProvider, provider, manifest, collectionName, batch, token);
|
||||||
|
|
||||||
if (totalChunkCount == 0)
|
if (totalChunkCount == 0)
|
||||||
throw new InvalidOperationException($"The file '{file.Name}' did not yield any text chunks.");
|
throw new InvalidOperationException($"The file '{file.Name}' did not yield any text chunks.");
|
||||||
@ -639,11 +635,12 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
IDataSource dataSource,
|
IDataSource dataSource,
|
||||||
FileInfo file,
|
FileInfo file,
|
||||||
string fingerprint,
|
string fingerprint,
|
||||||
|
EmbeddingStateFile parentFile,
|
||||||
EmbeddingProvider embeddingProvider,
|
EmbeddingProvider embeddingProvider,
|
||||||
IProvider provider,
|
IProvider provider,
|
||||||
DataSourceEmbeddingManifest manifest,
|
DataSourceEmbeddingManifest manifest,
|
||||||
string collectionName,
|
string collectionName,
|
||||||
List<(string Text, int ChunkIndex)> batch,
|
List<EmbeddingChunkDraft> batch,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
logger.LogDebug(
|
logger.LogDebug(
|
||||||
@ -694,15 +691,22 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
}
|
}
|
||||||
|
|
||||||
token.ThrowIfCancellationRequested();
|
token.ThrowIfCancellationRequested();
|
||||||
|
var embeddedAtUtc = DateTime.UtcNow;
|
||||||
await this.UpsertPointsAsync(
|
await this.UpsertPointsAsync(
|
||||||
vectorStore,
|
vectorStore,
|
||||||
collectionName,
|
collectionName,
|
||||||
dataSource,
|
dataSource,
|
||||||
file,
|
file,
|
||||||
fingerprint,
|
fingerprint,
|
||||||
|
parentFile,
|
||||||
batch,
|
batch,
|
||||||
vectors,
|
vectors,
|
||||||
this.TryGetRelativePath(dataSource, file),
|
embeddedAtUtc,
|
||||||
|
token);
|
||||||
|
token.ThrowIfCancellationRequested();
|
||||||
|
await embeddingState.UpsertChunksAsync(
|
||||||
|
dataSource.Id,
|
||||||
|
this.CreateEmbeddingStateChunks(parentFile, batch, embeddedAtUtc),
|
||||||
token);
|
token);
|
||||||
|
|
||||||
logger.LogDebug(
|
logger.LogDebug(
|
||||||
@ -725,26 +729,34 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
IDataSource dataSource,
|
IDataSource dataSource,
|
||||||
FileInfo file,
|
FileInfo file,
|
||||||
string fingerprint,
|
string fingerprint,
|
||||||
IReadOnlyList<(string Text, int ChunkIndex)> batch,
|
EmbeddingStateFile parentFile,
|
||||||
|
IReadOnlyList<EmbeddingChunkDraft> batch,
|
||||||
IReadOnlyList<IReadOnlyList<float>> vectors,
|
IReadOnlyList<IReadOnlyList<float>> vectors,
|
||||||
string relativePath,
|
DateTime embeddedAtUtc,
|
||||||
CancellationToken token)
|
CancellationToken token)
|
||||||
{
|
{
|
||||||
var embeddedAtUtc = DateTime.UtcNow;
|
|
||||||
var points = batch.Select((item, index) => new VectorStoragePoint(
|
var points = batch.Select((item, index) => new VectorStoragePoint(
|
||||||
this.CreatePointId(dataSource.Id, fingerprint, item.ChunkIndex),
|
item.ChunkId,
|
||||||
vectors[index],
|
vectors[index],
|
||||||
dataSource.Id,
|
dataSource.Id,
|
||||||
dataSource.Name,
|
dataSource.Name,
|
||||||
dataSource.Type.ToString(),
|
dataSource.Type.ToString(),
|
||||||
|
item.ChunkId,
|
||||||
|
parentFile.ParentFileId,
|
||||||
file.FullName,
|
file.FullName,
|
||||||
file.Name,
|
parentFile.AbsolutePath,
|
||||||
relativePath,
|
parentFile.FileName,
|
||||||
|
parentFile.RelativePath,
|
||||||
|
parentFile.FileType,
|
||||||
|
item.PageNumber,
|
||||||
item.ChunkIndex,
|
item.ChunkIndex,
|
||||||
item.Text,
|
item.Text,
|
||||||
fingerprint,
|
fingerprint,
|
||||||
file.LastWriteTimeUtc,
|
parentFile.CreationUtc,
|
||||||
embeddedAtUtc)).ToList();
|
parentFile.LastWriteUtc,
|
||||||
|
embeddedAtUtc,
|
||||||
|
parentFile.ComplianceLevel,
|
||||||
|
parentFile.ComplianceLevelRank)).ToList();
|
||||||
|
|
||||||
await vectorStore.InsertEmbedding(collectionName, points, token);
|
await vectorStore.InsertEmbedding(collectionName, points, token);
|
||||||
}
|
}
|
||||||
@ -805,7 +817,7 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
logger.LogInformation(
|
logger.LogInformation(
|
||||||
"Starting initial persisted hash check for {DataSourceCount} supported internal data source(s). Incomplete or failed embedding state will be retried during this pass. File watchers will be activated after this check completes.",
|
"Starting initial persisted hash check for {DataSourceCount} supported internal data source(s). Incomplete or failed local RAG index state will be retried during this pass. File watchers will be activated after this check completes.",
|
||||||
supportedDataSources.Count);
|
supportedDataSources.Count);
|
||||||
|
|
||||||
foreach (var dataSource in supportedDataSources)
|
foreach (var dataSource in supportedDataSources)
|
||||||
@ -875,7 +887,7 @@ public sealed partial class DataSourceEmbeddingService(SettingsManager settingsM
|
|||||||
var manifest = await embeddingState.GetManifestAsync(dataSource.Id, token);
|
var manifest = await embeddingState.GetManifestAsync(dataSource.Id, token);
|
||||||
|
|
||||||
logger.LogInformation(
|
logger.LogInformation(
|
||||||
"Loaded persisted embedding manifest for data source '{DataSourceName}' ({DataSourceId}). StoredFiles={StoredFiles}, StoredSourceHashPrefix={StoredSourceHashPrefix}, StoredSignaturePrefix={StoredSignaturePrefix}, CurrentSignaturePrefix={CurrentSignaturePrefix}.",
|
"Loaded persisted local RAG index manifest for data source '{DataSourceName}' ({DataSourceId}). StoredFiles={StoredFiles}, StoredSourceHashPrefix={StoredSourceHashPrefix}, StoredSignaturePrefix={StoredSignaturePrefix}, CurrentSignaturePrefix={CurrentSignaturePrefix}.",
|
||||||
dataSource.Name,
|
dataSource.Name,
|
||||||
dataSource.Id,
|
dataSource.Id,
|
||||||
manifest.Files.Count,
|
manifest.Files.Count,
|
||||||
|
|||||||
@ -67,14 +67,22 @@ pub struct QdrantEdgeStoragePoint {
|
|||||||
pub data_source_id: String,
|
pub data_source_id: String,
|
||||||
pub data_source_name: String,
|
pub data_source_name: String,
|
||||||
pub data_source_type: String,
|
pub data_source_type: String,
|
||||||
|
pub chunk_id: String,
|
||||||
|
pub parent_file_id: String,
|
||||||
pub file_path: String,
|
pub file_path: String,
|
||||||
|
pub absolute_path: String,
|
||||||
pub file_name: String,
|
pub file_name: String,
|
||||||
pub relative_path: String,
|
pub relative_path: String,
|
||||||
|
pub file_type: String,
|
||||||
|
pub page_number: Option<i32>,
|
||||||
pub chunk_index: i32,
|
pub chunk_index: i32,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
pub fingerprint: String,
|
pub fingerprint: String,
|
||||||
|
pub creation_utc: String,
|
||||||
pub last_write_utc: String,
|
pub last_write_utc: String,
|
||||||
pub embedded_at_utc: String,
|
pub embedded_at_utc: String,
|
||||||
|
pub compliance_level: String,
|
||||||
|
pub compliance_level_rank: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -509,14 +517,22 @@ fn to_qdrant_edge_point(point: QdrantEdgeStoragePoint) -> qdrant_edge::PointStru
|
|||||||
"data_source_id": point.data_source_id,
|
"data_source_id": point.data_source_id,
|
||||||
"data_source_name": point.data_source_name,
|
"data_source_name": point.data_source_name,
|
||||||
"data_source_type": point.data_source_type,
|
"data_source_type": point.data_source_type,
|
||||||
|
"chunk_id": point.chunk_id,
|
||||||
|
"parent_file_id": point.parent_file_id,
|
||||||
"file_path": point.file_path,
|
"file_path": point.file_path,
|
||||||
|
"absolute_path": point.absolute_path,
|
||||||
"file_name": point.file_name,
|
"file_name": point.file_name,
|
||||||
"relative_path": point.relative_path,
|
"relative_path": point.relative_path,
|
||||||
|
"file_type": point.file_type,
|
||||||
|
"page_number": point.page_number,
|
||||||
"chunk_index": point.chunk_index,
|
"chunk_index": point.chunk_index,
|
||||||
"text": point.text,
|
"text": point.text,
|
||||||
"fingerprint": point.fingerprint,
|
"fingerprint": point.fingerprint,
|
||||||
|
"creation_utc": point.creation_utc,
|
||||||
"last_write_utc": point.last_write_utc,
|
"last_write_utc": point.last_write_utc,
|
||||||
"embedded_at_utc": point.embedded_at_utc,
|
"embedded_at_utc": point.embedded_at_utc,
|
||||||
|
"compliance_level": point.compliance_level,
|
||||||
|
"compliance_level_rank": point.compliance_level_rank,
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.into()
|
.into()
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user