mirror of
https://github.com/open-webui/open-webui
synced 2024-11-22 08:07:55 +00:00
enh: knowledge author info
This commit is contained in:
parent
a2a25fb571
commit
6c3e6710ef
@ -8,6 +8,7 @@ from open_webui.apps.webui.internal.db import Base, get_db
|
|||||||
from open_webui.env import SRC_LOG_LEVELS
|
from open_webui.env import SRC_LOG_LEVELS
|
||||||
|
|
||||||
from open_webui.apps.webui.models.files import FileMetadataResponse
|
from open_webui.apps.webui.models.files import FileMetadataResponse
|
||||||
|
from open_webui.apps.webui.models.users import Users, UserResponse
|
||||||
|
|
||||||
|
|
||||||
from pydantic import BaseModel, ConfigDict
|
from pydantic import BaseModel, ConfigDict
|
||||||
@ -79,17 +80,15 @@ class KnowledgeModel(BaseModel):
|
|||||||
####################
|
####################
|
||||||
|
|
||||||
|
|
||||||
class KnowledgeResponse(BaseModel):
|
class KnowledgeUserModel(KnowledgeModel):
|
||||||
id: str
|
user: Optional[UserResponse] = None
|
||||||
name: str
|
|
||||||
description: str
|
|
||||||
data: Optional[dict] = None
|
|
||||||
meta: Optional[dict] = None
|
|
||||||
|
|
||||||
access_control: Optional[dict] = None
|
|
||||||
created_at: int # timestamp in epoch
|
|
||||||
updated_at: int # timestamp in epoch
|
|
||||||
|
|
||||||
|
class KnowledgeResponse(KnowledgeModel):
|
||||||
|
files: Optional[list[FileMetadataResponse | dict]] = None
|
||||||
|
|
||||||
|
|
||||||
|
class KnowledgeUserResponse(KnowledgeUserModel):
|
||||||
files: Optional[list[FileMetadataResponse | dict]] = None
|
files: Optional[list[FileMetadataResponse | dict]] = None
|
||||||
|
|
||||||
|
|
||||||
@ -127,10 +126,15 @@ class KnowledgeTable:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_knowledge_bases(self) -> list[KnowledgeModel]:
|
def get_knowledge_bases(self) -> list[KnowledgeUserModel]:
|
||||||
with get_db() as db:
|
with get_db() as db:
|
||||||
return [
|
return [
|
||||||
KnowledgeModel.model_validate(knowledge)
|
KnowledgeUserModel.model_validate(
|
||||||
|
{
|
||||||
|
**KnowledgeModel.model_validate(knowledge).model_dump(),
|
||||||
|
"user": Users.get_user_by_id(knowledge.user_id).model_dump(),
|
||||||
|
}
|
||||||
|
)
|
||||||
for knowledge in db.query(Knowledge)
|
for knowledge in db.query(Knowledge)
|
||||||
.order_by(Knowledge.updated_at.desc())
|
.order_by(Knowledge.updated_at.desc())
|
||||||
.all()
|
.all()
|
||||||
@ -138,7 +142,7 @@ class KnowledgeTable:
|
|||||||
|
|
||||||
def get_knowledge_bases_by_user_id(
|
def get_knowledge_bases_by_user_id(
|
||||||
self, user_id: str, permission: str = "write"
|
self, user_id: str, permission: str = "write"
|
||||||
) -> list[KnowledgeModel]:
|
) -> list[KnowledgeUserModel]:
|
||||||
knowledge_bases = self.get_knowledge_bases()
|
knowledge_bases = self.get_knowledge_bases()
|
||||||
return [
|
return [
|
||||||
knowledge_base
|
knowledge_base
|
||||||
|
@ -8,6 +8,7 @@ from open_webui.apps.webui.models.knowledge import (
|
|||||||
Knowledges,
|
Knowledges,
|
||||||
KnowledgeForm,
|
KnowledgeForm,
|
||||||
KnowledgeResponse,
|
KnowledgeResponse,
|
||||||
|
KnowledgeUserResponse,
|
||||||
)
|
)
|
||||||
from open_webui.apps.webui.models.files import Files, FileModel
|
from open_webui.apps.webui.models.files import Files, FileModel
|
||||||
from open_webui.apps.retrieval.vector.connector import VECTOR_DB_CLIENT
|
from open_webui.apps.retrieval.vector.connector import VECTOR_DB_CLIENT
|
||||||
@ -32,7 +33,7 @@ router = APIRouter()
|
|||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
||||||
@router.get("/", response_model=list[KnowledgeResponse])
|
@router.get("/", response_model=list[KnowledgeUserResponse])
|
||||||
async def get_knowledge(user=Depends(get_verified_user)):
|
async def get_knowledge(user=Depends(get_verified_user)):
|
||||||
knowledge_bases = []
|
knowledge_bases = []
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ async def get_knowledge(user=Depends(get_verified_user)):
|
|||||||
return knowledge_bases
|
return knowledge_bases
|
||||||
|
|
||||||
|
|
||||||
@router.get("/list", response_model=list[KnowledgeResponse])
|
@router.get("/list", response_model=list[KnowledgeUserResponse])
|
||||||
async def get_knowledge_list(user=Depends(get_verified_user)):
|
async def get_knowledge_list(user=Depends(get_verified_user)):
|
||||||
knowledge_bases = []
|
knowledge_bases = []
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
import Search from '../icons/Search.svelte';
|
import Search from '../icons/Search.svelte';
|
||||||
import Plus from '../icons/Plus.svelte';
|
import Plus from '../icons/Plus.svelte';
|
||||||
import Spinner from '../common/Spinner.svelte';
|
import Spinner from '../common/Spinner.svelte';
|
||||||
|
import { capitalizeFirstLetter } from '$lib/utils';
|
||||||
|
import Tooltip from '../common/Tooltip.svelte';
|
||||||
|
|
||||||
let loaded = false;
|
let loaded = false;
|
||||||
|
|
||||||
@ -137,7 +139,11 @@
|
|||||||
>
|
>
|
||||||
<div class=" w-full">
|
<div class=" w-full">
|
||||||
<div class="flex items-center justify-between -mt-1">
|
<div class="flex items-center justify-between -mt-1">
|
||||||
<div class=" font-semibold line-clamp-1 h-fit">{item.name}</div>
|
{#if item?.meta?.document}
|
||||||
|
<Badge type="muted" content={$i18n.t('Document')} />
|
||||||
|
{:else}
|
||||||
|
<Badge type="success" content={$i18n.t('Collection')} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class=" flex self-center">
|
<div class=" flex self-center">
|
||||||
<ItemMenu
|
<ItemMenu
|
||||||
@ -150,17 +156,23 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class=" self-center flex-1">
|
<div class=" self-center flex-1">
|
||||||
|
<div class=" font-semibold line-clamp-1 h-fit">{item.name}</div>
|
||||||
|
|
||||||
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
|
<div class=" text-xs overflow-hidden text-ellipsis line-clamp-1">
|
||||||
{item.description}
|
{item.description}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-5 flex justify-between">
|
<div class="mt-3 flex justify-between">
|
||||||
<div>
|
<div class="text-xs">
|
||||||
{#if item?.meta?.document}
|
<Tooltip
|
||||||
<Badge type="muted" content={$i18n.t('Document')} />
|
content={item?.user?.email}
|
||||||
{:else}
|
className="flex shrink-0"
|
||||||
<Badge type="success" content={$i18n.t('Collection')} />
|
placement="top-start"
|
||||||
{/if}
|
>
|
||||||
|
{$i18n.t('By {{name}}', {
|
||||||
|
name: capitalizeFirstLetter(item?.user?.name ?? item?.user?.email)
|
||||||
|
})}
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class=" text-xs text-gray-500 line-clamp-1">
|
<div class=" text-xs text-gray-500 line-clamp-1">
|
||||||
{$i18n.t('Updated')}
|
{$i18n.t('Updated')}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
import ChevronRight from '../icons/ChevronRight.svelte';
|
import ChevronRight from '../icons/ChevronRight.svelte';
|
||||||
import Switch from '../common/Switch.svelte';
|
import Switch from '../common/Switch.svelte';
|
||||||
import Spinner from '../common/Spinner.svelte';
|
import Spinner from '../common/Spinner.svelte';
|
||||||
|
import { capitalizeFirstLetter } from '$lib/utils';
|
||||||
|
|
||||||
let shiftKey = false;
|
let shiftKey = false;
|
||||||
|
|
||||||
@ -288,7 +289,9 @@
|
|||||||
<div class="flex gap-1 text-xs overflow-hidden">
|
<div class="flex gap-1 text-xs overflow-hidden">
|
||||||
<Tooltip content={model?.user?.email} className="flex shrink-0" placement="top-start">
|
<Tooltip content={model?.user?.email} className="flex shrink-0" placement="top-start">
|
||||||
<div class="shrink-0 text-gray-500">
|
<div class="shrink-0 text-gray-500">
|
||||||
By <span class=" capitalize">{model?.user?.name ?? model?.user?.email}</span>
|
{$i18n.t('By {{name}}', {
|
||||||
|
name: capitalizeFirstLetter(model?.user?.name ?? model?.user?.email)
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,6 +8,7 @@ import { TTS_RESPONSE_SPLIT } from '$lib/types';
|
|||||||
// Helper functions
|
// Helper functions
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
|
|
||||||
export const replaceTokens = (content, char, user) => {
|
export const replaceTokens = (content, char, user) => {
|
||||||
const charToken = /{{char}}/gi;
|
const charToken = /{{char}}/gi;
|
||||||
const userToken = /{{user}}/gi;
|
const userToken = /{{user}}/gi;
|
||||||
|
Loading…
Reference in New Issue
Block a user