Skip to content

Commit 3d8c043

Browse files
committed
feat: create chat first record
1 parent a1bf97a commit 3d8c043

File tree

10 files changed

+185
-229
lines changed

10 files changed

+185
-229
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
"""018_modify_chat
2+
3+
Revision ID: 863105882eba
4+
Revises: a0ba8268868d
5+
Create Date: 2025-06-30 16:44:17.123791
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
import sqlmodel.sql.sqltypes
11+
from sqlalchemy.dialects import postgresql
12+
13+
# revision identifiers, used by Alembic.
14+
revision = '863105882eba'
15+
down_revision = 'a0ba8268868d'
16+
branch_labels = None
17+
depends_on = None
18+
19+
20+
def upgrade():
21+
# ### commands auto generated by Alembic - please adjust! ###
22+
op.alter_column('chat', 'id',
23+
existing_type=sa.INTEGER(),
24+
type_=sa.BigInteger(),
25+
existing_nullable=False,
26+
autoincrement=True,
27+
existing_server_default=sa.Identity(always=True, start=1, increment=1, minvalue=1, maxvalue=2147483647, cycle=False, cache=1))
28+
op.alter_column('chat', 'datasource',
29+
existing_type=sa.INTEGER(),
30+
type_=sa.BigInteger(),
31+
existing_nullable=True)
32+
op.alter_column('chat_record', 'id',
33+
existing_type=sa.INTEGER(),
34+
type_=sa.BigInteger(),
35+
existing_nullable=False,
36+
autoincrement=True,
37+
existing_server_default=sa.Identity(always=True, start=1, increment=1, minvalue=1, maxvalue=2147483647, cycle=False, cache=1))
38+
op.alter_column('chat_record', 'chat_id',
39+
existing_type=sa.INTEGER(),
40+
type_=sa.BigInteger(),
41+
existing_nullable=False)
42+
op.alter_column('chat_record', 'ai_modal_id',
43+
existing_type=sa.INTEGER(),
44+
type_=sa.BigInteger(),
45+
existing_nullable=True)
46+
op.alter_column('chat_record', 'datasource',
47+
existing_type=sa.INTEGER(),
48+
type_=sa.BigInteger(),
49+
existing_nullable=True)
50+
# ### end Alembic commands ###
51+
52+
53+
def downgrade():
54+
# ### commands auto generated by Alembic - please adjust! ###
55+
op.alter_column('chat_record', 'datasource',
56+
existing_type=sa.BigInteger(),
57+
type_=sa.INTEGER(),
58+
existing_nullable=True)
59+
op.alter_column('chat_record', 'ai_modal_id',
60+
existing_type=sa.BigInteger(),
61+
type_=sa.INTEGER(),
62+
existing_nullable=True)
63+
op.alter_column('chat_record', 'chat_id',
64+
existing_type=sa.BigInteger(),
65+
type_=sa.INTEGER(),
66+
existing_nullable=False)
67+
op.alter_column('chat_record', 'id',
68+
existing_type=sa.BigInteger(),
69+
type_=sa.INTEGER(),
70+
existing_nullable=False,
71+
autoincrement=True,
72+
existing_server_default=sa.Identity(always=True, start=1, increment=1, minvalue=1, maxvalue=2147483647, cycle=False, cache=1))
73+
op.alter_column('chat', 'datasource',
74+
existing_type=sa.BigInteger(),
75+
type_=sa.INTEGER(),
76+
existing_nullable=True)
77+
op.alter_column('chat', 'id',
78+
existing_type=sa.BigInteger(),
79+
type_=sa.INTEGER(),
80+
existing_nullable=False,
81+
autoincrement=True,
82+
existing_server_default=sa.Identity(always=True, start=1, increment=1, minvalue=1, maxvalue=2147483647, cycle=False, cache=1))
83+
# ### end Alembic commands ###

backend/apps/chat/curd/chat.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ def get_chat_with_records(session: SessionDep, chart_id: int, current_user: Curr
6161
ChatRecord.question, ChatRecord.sql_answer, ChatRecord.sql, ChatRecord.data,
6262
ChatRecord.chart_answer, ChatRecord.chart, ChatRecord.analysis, ChatRecord.predict,
6363
ChatRecord.datasource_select_answer, ChatRecord.recommended_question_answer,
64-
ChatRecord.recommended_question,
64+
ChatRecord.recommended_question, ChatRecord.first_chat,
6565
ChatRecord.predict_data, ChatRecord.finish, ChatRecord.error, ChatRecord.run_time)).filter(
6666
and_(Chat.create_by == current_user.id, ChatRecord.chat_id == chart_id)).order_by(ChatRecord.create_time).all()
6767

@@ -111,6 +111,29 @@ def create_chat(session: SessionDep, current_user: CurrentUser, create_chat_obj:
111111
chat_info.datasource_exists = True
112112
chat_info.datasource_name = ds.name
113113

114+
if require_datasource and ds:
115+
# generate first empty record
116+
record = ChatRecord()
117+
record.chat_id = chat.id
118+
record.datasource = ds.id
119+
record.engine_type = ds.type_name
120+
record.first_chat = True
121+
record.finish = True
122+
record.create_time = datetime.datetime.now()
123+
record.create_by = current_user.id
124+
125+
_record = ChatRecord(**record.model_dump())
126+
127+
session.add(record)
128+
session.flush()
129+
session.refresh(record)
130+
_record.id = record.id
131+
session.commit()
132+
133+
# todo suggest questions
134+
135+
chat_info.records.append(_record)
136+
114137
return chat_info
115138

116139

@@ -131,6 +154,7 @@ def save_question(session: SessionDep, current_user: CurrentUser, question: Chat
131154
record.create_by = current_user.id
132155
record.datasource = chat.datasource
133156
record.engine_type = chat.engine_type
157+
record.ai_modal_id = question.ai_modal_id
134158

135159
result = ChatRecord(**record.model_dump())
136160

backend/apps/chat/models/chat_model.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,25 @@
1515

1616
class Chat(SQLModel, table=True):
1717
__tablename__ = "chat"
18-
id: Optional[int] = Field(sa_column=Column(Integer, Identity(always=True), primary_key=True))
18+
id: Optional[int] = Field(sa_column=Column(BigInteger, Identity(always=True), primary_key=True))
1919
create_time: datetime = Field(sa_column=Column(DateTime(timezone=True), nullable=True))
2020
create_by: int = Field(sa_column=Column(BigInteger, nullable=True))
2121
brief: str = Field(max_length=64, nullable=True)
2222
chat_type: str = Field(max_length=20, default="chat") # chat, datasource
23-
datasource: int = Field(sa_column=Column(Integer, nullable=True))
23+
datasource: int = Field(sa_column=Column(BigInteger, nullable=True))
2424
engine_type: str = Field(max_length=64)
2525

2626

2727
class ChatRecord(SQLModel, table=True):
2828
__tablename__ = "chat_record"
29-
id: Optional[int] = Field(sa_column=Column(Integer, Identity(always=True), primary_key=True))
30-
chat_id: int = Field(sa_column=Column(Integer, nullable=False))
31-
ai_modal_id: Optional[int] = Field(sa_column=Column(Integer))
29+
id: Optional[int] = Field(sa_column=Column(BigInteger, Identity(always=True), primary_key=True))
30+
chat_id: int = Field(sa_column=Column(BigInteger, nullable=False))
31+
ai_modal_id: Optional[int] = Field(sa_column=Column(BigInteger))
3232
first_chat: bool = Field(sa_column=Column(Boolean, nullable=True, default=False))
3333
create_time: datetime = Field(sa_column=Column(DateTime(timezone=True), nullable=True))
3434
finish_time: datetime = Field(sa_column=Column(DateTime(timezone=True), nullable=True))
3535
create_by: int = Field(sa_column=Column(BigInteger, nullable=True))
36-
datasource: int = Field(sa_column=Column(Integer, nullable=True))
36+
datasource: int = Field(sa_column=Column(BigInteger, nullable=True))
3737
engine_type: str = Field(max_length=64)
3838
question: str = Field(sa_column=Column(Text, nullable=True))
3939
sql_answer: str = Field(sa_column=Column(Text, nullable=True))
@@ -90,6 +90,7 @@ class ChatInfo(BaseModel):
9090

9191

9292
class AiModelQuestion(BaseModel):
93+
ai_modal_id: int = None
9394
engine: str = ""
9495
db_schema: str = ""
9596
sql: str = ""

backend/apps/chat/task/llm.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def __init__(self, chat_question: ChatQuestion, aimodel: AiModelDetail, history_
3939
ds: CoreDatasource = None):
4040
self.ds = ds
4141
self.chat_question = chat_question
42+
self.chat_question.ai_modal_id = aimodel.id
4243
self.config = get_llm_config(aimodel)
4344

4445
# Create LLM instance through factory

frontend/src/api/chat.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export interface ChatMessage {
2222
content?: string | number
2323
record?: ChatRecord
2424
isTyping?: boolean
25-
isWelcome?: boolean
25+
first_chat?: boolean
2626
}
2727

2828
export class ChatRecord {
@@ -42,6 +42,7 @@ export class ChatRecord {
4242
finish?: boolean = false
4343
error?: string
4444
run_time: number = 0
45+
first_chat: boolean = false
4546

4647
constructor()
4748
constructor(
@@ -60,7 +61,8 @@ export class ChatRecord {
6061
predict_data: string | undefined,
6162
finish: boolean,
6263
error: string | undefined,
63-
run_time: number
64+
run_time: number,
65+
first_chat: boolean
6466
)
6567
constructor(
6668
id?: number,
@@ -78,7 +80,8 @@ export class ChatRecord {
7880
predict_data?: string,
7981
finish?: boolean,
8082
error?: string,
81-
run_time?: number
83+
run_time?: number,
84+
first_chat?: boolean
8285
) {
8386
this.id = id
8487
this.chat_id = chat_id
@@ -93,9 +96,10 @@ export class ChatRecord {
9396
this.analysis = analysis
9497
this.predict = predict
9598
this.predict_data = predict_data
96-
this.finish = finish
99+
this.finish = !!finish
97100
this.error = error
98101
this.run_time = run_time ?? 0
102+
this.first_chat = !!first_chat
99103
}
100104
}
101105

@@ -214,7 +218,8 @@ function toChatRecord(data?: any): ChatRecord | undefined {
214218
data.predict_data,
215219
data.finish,
216220
data.error,
217-
data.run_time
221+
data.run_time,
222+
data.first_chat
218223
)
219224
}
220225

frontend/src/utils/request.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ class HttpService {
217217
if (token) {
218218
heads['X-SQLBOT-TOKEN'] = `Bearer ${token}`
219219
}
220+
// @ts-ignore
221+
const request_key = LicenseGenerator.generate()
222+
heads['X-SQLBOT-KEY'] = request_key
223+
220224
const real_url = import.meta.env.VITE_API_BASE_URL
221225
return fetch(real_url + url, {
222226
method: 'POST',
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<script setup lang="ts">
2+
import ChatBlock from './ChatBlock.vue'
3+
import { ChatInfo, type ChatMessage } from '@/api/chat.ts'
4+
import { computed } from 'vue'
5+
import { useI18n } from 'vue-i18n'
6+
7+
const { t } = useI18n()
8+
const props = defineProps<{
9+
msg: ChatMessage
10+
currentChat: ChatInfo
11+
}>()
12+
13+
const show = computed(() => {
14+
return props.msg.first_chat
15+
})
16+
</script>
17+
18+
<template>
19+
<ChatBlock v-if="show">
20+
<div class="welcome-content">
21+
<div class="ds-select-row">
22+
<div>{{ t('qa.selected_datasource') }}:</div>
23+
</div>
24+
<div>
25+
{{ currentChat.datasource_name }}
26+
</div>
27+
</div>
28+
</ChatBlock>
29+
</template>
30+
31+
<style scoped lang="less">
32+
.welcome-content {
33+
padding: 12px;
34+
display: flex;
35+
}
36+
37+
.sub {
38+
color: grey;
39+
font-size: 0.8em;
40+
}
41+
42+
.ds-select-row {
43+
margin-right: 8px;
44+
}
45+
</style>

frontend/src/views/chat/ChatRow.vue

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,16 @@
11
<script setup lang="ts">
22
import ChatBlock from './ChatBlock.vue'
3-
import WelcomeBlock from './WelcomeBlock.vue'
3+
import ChatRecordFirst from './ChatRecordFirst.vue'
44
import { ChatInfo, type ChatMessage } from '@/api/chat.ts'
5-
import { computed } from 'vue'
65
import { UserFilled } from '@element-plus/icons-vue'
76
8-
const props = withDefaults(
7+
withDefaults(
98
defineProps<{
109
msg: ChatMessage
1110
currentChat: ChatInfo
12-
datasource?: number
1311
}>(),
14-
{
15-
datasource: undefined,
16-
}
12+
{}
1713
)
18-
19-
const emits = defineEmits(['update:datasource'])
20-
21-
const _datasource = computed({
22-
get() {
23-
return props.datasource
24-
},
25-
set(v) {
26-
emits('update:datasource', v)
27-
},
28-
})
2914
</script>
3015

3116
<template>
@@ -36,13 +21,13 @@ const _datasource = computed({
3621
<UserFilled />
3722
</el-icon>
3823
</el-avatar>
39-
<ChatBlock v-if="!msg.isWelcome" :msg="msg" :class="{ 'row-full': msg.role === 'assistant' }">
24+
<ChatBlock v-if="!msg.first_chat" :msg="msg" :class="{ 'row-full': msg.role === 'assistant' }">
4025
<slot></slot>
4126
<template #footer>
4227
<slot name="footer"></slot>
4328
</template>
4429
</ChatBlock>
45-
<WelcomeBlock v-else v-model="_datasource" :current-chat="currentChat" class="row-full" />
30+
<ChatRecordFirst v-else :current-chat="currentChat" :msg="msg" />
4631
</div>
4732
</template>
4833

0 commit comments

Comments
 (0)