Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
.omc/
.DS_Store
node_modules/
dist/
*.local
.idea/
.vscode/
.cursor/
3 changes: 3 additions & 0 deletions api/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export type AIActionResult = null | string;

export interface AIChatForwardedPropsParams {
enableBuiltinTools?: boolean;
text2SqlDatasetId?: null | number;
extraBody?: null | Recordable<unknown>;
extraHeaders?: null | Recordable<string>;
frequencyPenalty?: null | number;
Expand Down Expand Up @@ -201,6 +202,7 @@ export interface AIChatComposerParams {
extra_body?: null | string;
thinking?: AIChatThinkingType | boolean | null;
enable_builtin_tools?: boolean;
text2sql_dataset_id?: null | number;
mcp_ids?: null | number[];
web_search?: AIWebSearchType;
}
Expand Down Expand Up @@ -286,6 +288,7 @@ function toForwardedProps(
): AIChatForwardedPropsParams {
return {
enableBuiltinTools: params.enable_builtin_tools ?? true,
text2SqlDatasetId: params.text2sql_dataset_id ?? null,
extraBody: parseExtraBody(params.extra_body),
extraHeaders: params.extra_headers ?? undefined,
frequencyPenalty: params.frequency_penalty,
Expand Down
224 changes: 224 additions & 0 deletions api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,228 @@ export async function deleteAIQuickPhraseApi(pk: number) {
return requestClient.delete<AIActionResult>(`/api/v1/quick-phrases/${pk}`);
}

// ---------------- Text2SQL ----------------

// 数据集
export interface AIText2SqlDatasetParams {
description?: null | string;
enabled?: number;
name: string;
sort?: number;
}

export type AIText2SqlDatasetUpdateParams = Partial<AIText2SqlDatasetParams>;

export interface AIText2SqlDatasetResult extends AIText2SqlDatasetParams {
created_time: string;
id: number;
updated_time?: null | string;
}

export interface Text2SqlDatasetEnabled {
description?: null | string;
id: number;
name: string;
}

export interface Text2SqlTableSelectable {
table_comment?: null | string;
table_name: string;
selected: boolean;
}

export interface AIText2SqlTableParams {
dataset_id: number;
custom_desc?: null | string;
enabled?: number;
schema_name?: string;
sort?: number;
table_comment?: null | string;
table_name: string;
}

export type AIText2SqlTableUpdateParams = Partial<AIText2SqlTableParams>;

export interface AIText2SqlTableResult extends AIText2SqlTableParams {
created_time: string;
id: number;
updated_time?: null | string;
}

export interface AIText2SqlExampleParams {
dataset_id: number;
enabled?: number;
note?: null | string;
question: string;
related_tables?: null | string;
sql: string;
sort?: number;
}

export type AIText2SqlExampleUpdateParams = Partial<AIText2SqlExampleParams>;

export interface AIText2SqlExampleResult extends AIText2SqlExampleParams {
created_time: string;
id: number;
updated_time?: null | string;
}

export interface Text2SqlQueryParams {
question: string;
}

export interface Text2SqlQueryResult {
columns: string[];
duration_ms: number;
history_id?: null | number;
row_count: number;
rows: Recordable<unknown>[];
sql: string;
summary: string;
}

// 数据集
export async function getEnabledDatasetsApi() {
return requestClient.get<Text2SqlDatasetEnabled[]>(
'/api/v1/text2sql/datasets/enabled',
);
}

export async function getDatasetListApi(params?: Recordable<unknown>) {
return requestClient.get<PaginationResult<AIText2SqlDatasetResult>>(
'/api/v1/text2sql/datasets',
{ params },
);
}

export async function getAllDatasetsApi() {
return requestClient.get<AIText2SqlDatasetResult[]>(
'/api/v1/text2sql/datasets/all',
);
}

export async function getDatasetApi(pk: number) {
return requestClient.get<AIText2SqlDatasetResult>(
`/api/v1/text2sql/datasets/${pk}`,
);
}

export async function createDatasetApi(data: AIText2SqlDatasetParams) {
return requestClient.post<AIActionResult>('/api/v1/text2sql/datasets', data);
}

export async function updateDatasetApi(
pk: number,
data: AIText2SqlDatasetUpdateParams,
) {
return requestClient.put<AIActionResult>(
`/api/v1/text2sql/datasets/${pk}`,
data,
);
}

export async function deleteDatasetApi(pk: number) {
return requestClient.delete<AIActionResult>(`/api/v1/text2sql/datasets/${pk}`);
}

export async function getSelectableTablesApi(
datasetId: number,
tableSchema?: string,
) {
return requestClient.get<Text2SqlTableSelectable[]>(
'/api/v1/text2sql/tables',
{ params: { dataset_id: datasetId, table_schema: tableSchema } },
);
}

export async function getTableColumnsApi(
tableName: string,
tableSchema?: string,
) {
return requestClient.get<Recordable<unknown>[]>(
`/api/v1/text2sql/tables/${tableName}/columns`,
{ params: { table_schema: tableSchema } },
);
}

export async function getSelectedTableListApi(params?: Recordable<unknown>) {
return requestClient.get<PaginationResult<AIText2SqlTableResult>>(
'/api/v1/text2sql/selected-tables',
{ params },
);
}

export async function getAllSelectedTablesApi() {
return requestClient.get<AIText2SqlTableResult[]>(
'/api/v1/text2sql/selected-tables/all',
);
}

export async function getSelectedTableApi(pk: number) {
return requestClient.get<AIText2SqlTableResult>(
`/api/v1/text2sql/selected-tables/${pk}`,
);
}

export async function createSelectedTableApi(data: AIText2SqlTableParams) {
return requestClient.post<AIActionResult>(
'/api/v1/text2sql/selected-tables',
data,
);
}

export async function updateSelectedTableApi(
pk: number,
data: AIText2SqlTableUpdateParams,
) {
return requestClient.put<AIActionResult>(
`/api/v1/text2sql/selected-tables/${pk}`,
data,
);
}

export async function deleteSelectedTableApi(pk: number) {
return requestClient.delete<AIActionResult>(
`/api/v1/text2sql/selected-tables/${pk}`,
);
}

export async function getExampleListApi(params?: Recordable<unknown>) {
return requestClient.get<PaginationResult<AIText2SqlExampleResult>>(
'/api/v1/text2sql/examples',
{ params },
);
}

export async function getAllExamplesApi() {
return requestClient.get<AIText2SqlExampleResult[]>(
'/api/v1/text2sql/examples/all',
);
}

export async function createExampleApi(data: AIText2SqlExampleParams) {
return requestClient.post<AIActionResult>('/api/v1/text2sql/examples', data);
}

export async function updateExampleApi(
pk: number,
data: AIText2SqlExampleUpdateParams,
) {
return requestClient.put<AIActionResult>(
`/api/v1/text2sql/examples/${pk}`,
data,
);
}

export async function deleteExampleApi(pk: number) {
return requestClient.delete<AIActionResult>(`/api/v1/text2sql/examples/${pk}`);
}

export async function queryText2SqlApi(data: Text2SqlQueryParams) {
return requestClient.post<Text2SqlQueryResult>(
'/api/v1/text2sql/queries',
data,
);
}

export * from './chat';
68 changes: 67 additions & 1 deletion langs/en-US/ai.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,71 @@
"provider": "Provider",
"model": "Providers & Models",
"mcp": "MCP",
"quick_phrase": "Quick Phrase"
"quick_phrase": "Quick Phrase",
"text2sql": "Dataset",
"text2sqlPage": {
"dataset": {
"title": "Datasets",
"add": "Add",
"empty": "No datasets",
"disabled": "Disabled",
"pleaseSelect": "Please select a dataset",
"name": "Dataset name",
"nameQuery": "Name",
"description": "Description",
"enabled": "Enabled",
"disabledOption": "Disabled",
"sort": "Sort",
"status": "Status",
"editTitle": "Edit Dataset",
"createTitle": "Add Dataset",
"deleteConfirm": "Are you sure you want to delete dataset \"{name}\"? Its tables and examples will be retained but no longer aggregated by this dataset.",
"saved": "Saved",
"deleted": "Deleted"
},
"table": {
"tab": "Tables",
"name": "Table name",
"schema": "Schema",
"comment": "Table comment",
"customDesc": "Custom description",
"customDescPlaceholder": "Add business semantics to improve generation accuracy",
"customDescHelp": "Add business semantics to improve generation accuracy",
"enabled": "Enabled",
"disabledOption": "Disabled",
"status": "Status",
"sort": "Sort",
"pick": "Pick Tables",
"pickPlaceholder": "Select an unselected table",
"pickCustomDescPlaceholder": "Custom description (optional; add business semantics to improve generation accuracy)",
"pickAlert": "You can only pick tables that haven't been selected yet. Table names are resolved from the fba schema.",
"editTitle": "Edit Selected Table",
"pleaseSelectDataset": "Please select a dataset first",
"pleaseSelectTable": "Please select a table to pick",
"picked": "Picked",
"unselected": "Unselected",
"allPicked": "All available tables have been picked",
"updated": "Updated"
},
"example": {
"tab": "Examples",
"question": "Question",
"sql": "Example SQL",
"relatedTables": "Related tables",
"relatedTablesPlaceholder": "users,orders",
"relatedTablesHelp": "Comma-separated table names used for retrieval",
"note": "Note",
"enabled": "Enabled",
"disabledOption": "Disabled",
"status": "Status",
"sort": "Sort",
"naturalLanguageQuestion": "Natural-language question",
"add": "Add Example",
"editTitle": "Edit Example",
"createTitle": "Add Example",
"pleaseSelectDataset": "Please select a dataset first",
"saved": "Saved",
"deleted": "Deleted"
}
}
}
Loading