AiBot güncellemeleri
This commit is contained in:
parent
52e52bb03c
commit
196b0dc24b
7 changed files with 226 additions and 721 deletions
|
|
@ -6,5 +6,6 @@ namespace Sozsoft.Platform.AiBots;
|
||||||
public class AiBotDto : FullAuditedEntityDto<Guid>
|
public class AiBotDto : FullAuditedEntityDto<Guid>
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
|
public string ApiUrl { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"AiBots": [
|
"AiBots": [
|
||||||
{
|
{
|
||||||
"Name": "Chat Bot",
|
"Name": "Chat",
|
||||||
"Description": "A general purpose chat bot that can answer questions and have conversations.",
|
"Description": "Sözsoft Chat Bot",
|
||||||
"ApiUrl": "https://api.openai.com/v1/chat/completions",
|
"ApiUrl": "https://ai.sozsoft.com/webhook/chat",
|
||||||
"IsActive": true
|
"IsActive": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1200,7 +1200,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
|
||||||
SelectCommandType = SelectCommandTypeEnum.Table,
|
SelectCommandType = SelectCommandTypeEnum.Table,
|
||||||
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.AiBot)),
|
SelectCommand = TableNameResolver.GetFullTableName(nameof(TableNameEnum.AiBot)),
|
||||||
KeyFieldName = "Id",
|
KeyFieldName = "Id",
|
||||||
KeyFieldDbSourceType = DbType.Int32,
|
KeyFieldDbSourceType = DbType.Guid,
|
||||||
SortMode = GridOptions.SortModeSingle,
|
SortMode = GridOptions.SortModeSingle,
|
||||||
FilterRowJson = DefaultFilterRowJson,
|
FilterRowJson = DefaultFilterRowJson,
|
||||||
HeaderFilterJson = DefaultHeaderFilterJson,
|
HeaderFilterJson = DefaultHeaderFilterJson,
|
||||||
|
|
|
||||||
194
configs/ai/Chat.json
Normal file
194
configs/ai/Chat.json
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
{
|
||||||
|
"name": "Chat",
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"multipleMethods": true,
|
||||||
|
"httpMethod": [
|
||||||
|
"POST"
|
||||||
|
],
|
||||||
|
"path": "chat",
|
||||||
|
"responseMode": "lastNode",
|
||||||
|
"responseData": "allEntries",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.webhook",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
-704,
|
||||||
|
224
|
||||||
|
],
|
||||||
|
"id": "5624c28a-5e8f-4fd9-88ac-bc9a630a9cc0",
|
||||||
|
"name": "Webhook",
|
||||||
|
"webhookId": "562dfd4f-4e0b-4292-9986-2fbd3b8ecdc9",
|
||||||
|
"alwaysOutputData": true,
|
||||||
|
"executeOnce": false,
|
||||||
|
"retryOnFail": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"promptType": "define",
|
||||||
|
"text": "={{ $('Webhook').item.json.body.question }}",
|
||||||
|
"options": {
|
||||||
|
"systemMessage": "Kullanıcı: {{ $json.body.question }}\n\nDoğrudan yanıt ver. Açıklayıcı, öğretici ve samimi ol."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"type": "@n8n/n8n-nodes-langchain.agent",
|
||||||
|
"typeVersion": 1.8,
|
||||||
|
"position": [
|
||||||
|
-48,
|
||||||
|
224
|
||||||
|
],
|
||||||
|
"id": "f5a4eb80-6e3f-47a3-9e42-069fb6992a8b",
|
||||||
|
"name": "AI Chat",
|
||||||
|
"alwaysOutputData": false,
|
||||||
|
"onError": "continueErrorOutput"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "@n8n/n8n-nodes-langchain.memoryManager",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [
|
||||||
|
-448,
|
||||||
|
224
|
||||||
|
],
|
||||||
|
"id": "f008f540-216b-42f3-815c-b17658b4c7ad",
|
||||||
|
"name": "Chat Memory Manager",
|
||||||
|
"alwaysOutputData": false,
|
||||||
|
"disabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"sessionIdType": "customKey",
|
||||||
|
"sessionKey": "={{ $('Webhook').item.json.body.sessionId }}",
|
||||||
|
"contextWindowLength": 100
|
||||||
|
},
|
||||||
|
"type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
|
||||||
|
"typeVersion": 1.3,
|
||||||
|
"position": [
|
||||||
|
-304,
|
||||||
|
480
|
||||||
|
],
|
||||||
|
"id": "80c637b6-06e1-41b1-a946-84065a9e327a",
|
||||||
|
"name": "Simple Memory"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
|
||||||
|
"typeVersion": 1,
|
||||||
|
"position": [
|
||||||
|
-48,
|
||||||
|
480
|
||||||
|
],
|
||||||
|
"id": "08879cec-78df-4bd7-a8aa-f0ec6fc5e0ae",
|
||||||
|
"name": "Google Gemini Chat Model",
|
||||||
|
"credentials": {
|
||||||
|
"googlePalmApi": {
|
||||||
|
"id": "2y8O0r5mQKG5cdcc",
|
||||||
|
"name": "Google Gemini(PaLM) Api account"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"jsCode": "const cleanText = (text) =>\n text\n .replace(/\\\\/g, \"\\\\\\\\\") // ters slash\n .replace(/\"/g, '\\\\\"'); // çift tırnak\n\nreturn [\n {\n json: {\n type: \"chat\",\n question: $('Webhook').first().json.body.question,\n sql: null,\n answer: cleanText($input.first().json.output),\n chart: null,\n error: $input.first().json.error || null\n }\n }\n];\n\n"
|
||||||
|
},
|
||||||
|
"type": "n8n-nodes-base.code",
|
||||||
|
"typeVersion": 2,
|
||||||
|
"position": [
|
||||||
|
560,
|
||||||
|
224
|
||||||
|
],
|
||||||
|
"id": "7f66cfbf-d19e-421b-92c3-d9a1909c1434",
|
||||||
|
"name": "Chat Code",
|
||||||
|
"alwaysOutputData": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"pinData": {},
|
||||||
|
"connections": {
|
||||||
|
"Webhook": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Chat Memory Manager",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"AI Chat": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Chat Code",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Chat Code",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Chat Memory Manager": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "AI Chat",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Simple Memory": {
|
||||||
|
"ai_memory": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "AI Chat",
|
||||||
|
"type": "ai_memory",
|
||||||
|
"index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"node": "Chat Memory Manager",
|
||||||
|
"type": "ai_memory",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Google Gemini Chat Model": {
|
||||||
|
"ai_languageModel": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "AI Chat",
|
||||||
|
"type": "ai_languageModel",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"active": true,
|
||||||
|
"settings": {
|
||||||
|
"executionOrder": "v1",
|
||||||
|
"availableInMCP": false
|
||||||
|
},
|
||||||
|
"versionId": "84010ee3-81a9-48c8-9b48-a0661355d85c",
|
||||||
|
"meta": {
|
||||||
|
"templateCredsSetupCompleted": true,
|
||||||
|
"instanceId": "1d288821beaaeeada5e8dce6f282c802098a0c83ef6ddb35a174b09a9d43850e"
|
||||||
|
},
|
||||||
|
"id": "R1V2XtEQCknLJvSkwUW6s",
|
||||||
|
"tags": []
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -2,4 +2,5 @@ import { FullAuditedEntityDto } from '../abp'
|
||||||
|
|
||||||
export interface AiDto extends FullAuditedEntityDto<string> {
|
export interface AiDto extends FullAuditedEntityDto<string> {
|
||||||
name: string
|
name: string
|
||||||
|
apiUrl?: string
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,13 @@ const Assistant = () => {
|
||||||
const [messages, setMessages] = useState<Message[]>([])
|
const [messages, setMessages] = useState<Message[]>([])
|
||||||
const [input, setInput] = useState('')
|
const [input, setInput] = useState('')
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [bot, setBot] = useState<{ key: string; name: string }[]>([])
|
const [bot, setBot] = useState<AiDto[]>([])
|
||||||
const [selectedBot, setSelectedBot] = useState<string | null>(null)
|
const [selectedBot, setSelectedBot] = useState<string | null>(null)
|
||||||
|
|
||||||
const { id, avatar } = useStoreState((state) => state.auth.user)
|
const { id, avatar } = useStoreState((state) => state.auth.user)
|
||||||
const inputRef = useRef<HTMLTextAreaElement | null>(null)
|
const inputRef = useRef<HTMLTextAreaElement | null>(null)
|
||||||
const bottomRef = useRef<HTMLDivElement | null>(null)
|
const bottomRef = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
||||||
const { VITE_AI_URL } = import.meta.env
|
|
||||||
const { translate } = useLocalization()
|
const { translate } = useLocalization()
|
||||||
|
|
||||||
const aiPosts = useStoreState((state) => state.base.messages.aiPosts)
|
const aiPosts = useStoreState((state) => state.base.messages.aiPosts)
|
||||||
|
|
@ -66,14 +65,16 @@ const Assistant = () => {
|
||||||
maxResultCount: 1000,
|
maxResultCount: 1000,
|
||||||
sorting: 'name',
|
sorting: 'name',
|
||||||
})
|
})
|
||||||
const items =
|
|
||||||
result?.data?.items?.map((bot: AiDto) => ({
|
|
||||||
key: bot.id!,
|
|
||||||
name: bot.name,
|
|
||||||
})) ?? []
|
|
||||||
|
|
||||||
setBot(items)
|
if (!result?.data?.items) {
|
||||||
if (items.length > 0) setSelectedBot(items[0].key)
|
console.warn('Bot listesi boş veya hatalı formatta:', result)
|
||||||
|
setBot([])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setBot(result?.data?.items)
|
||||||
|
const firstBotId = result?.data?.items?.find((item) => item.id)?.id ?? null
|
||||||
|
setSelectedBot(firstBotId)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Bot listesi alınırken hata oluştu:', error)
|
console.error('Bot listesi alınırken hata oluştu:', error)
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +111,14 @@ const Assistant = () => {
|
||||||
setMessages((prev) => [...prev, { role: 'user', content: userMessage }])
|
setMessages((prev) => [...prev, { role: 'user', content: userMessage }])
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(VITE_AI_URL + selectedBot, {
|
const selectedBotItem = bot.find((item) => item.id === selectedBot)
|
||||||
|
const targetUrl = (selectedBotItem?.apiUrl || '').trim()
|
||||||
|
|
||||||
|
if (!targetUrl) {
|
||||||
|
throw new Error('AI bot URL bulunamadı.')
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await fetch(targetUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
|
@ -340,15 +348,16 @@ const Assistant = () => {
|
||||||
<Dropdown
|
<Dropdown
|
||||||
placement="top-start"
|
placement="top-start"
|
||||||
title={
|
title={
|
||||||
bot.find((item) => item.key === selectedBot)?.name ||
|
bot.find((item) => item.id === selectedBot)?.name || translate('::AI.SelectModel')
|
||||||
translate('::AI.SelectModel')
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{bot.map((item) => (
|
{bot
|
||||||
<Dropdown.Item key={item.key} eventKey={item.key} onSelect={onBotItemClick}>
|
.filter((item) => !!item.id)
|
||||||
{item.name}
|
.map((item) => (
|
||||||
</Dropdown.Item>
|
<Dropdown.Item key={item.id!} eventKey={item.id!} onSelect={onBotItemClick}>
|
||||||
))}
|
{item.name}
|
||||||
|
</Dropdown.Item>
|
||||||
|
))}
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue