Skip to content
Open
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
71 changes: 71 additions & 0 deletions docs/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,77 @@
}
}
},
"/answer/admin/api/ai-prompt-config": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "get AI prompt configuration",
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "get AI prompt configuration",
"responses": {
"200": {
"description": "OK",
"schema": {
"allOf": [
{
"$ref": "#/definitions/handler.RespBody"
},
{
"type": "object",
"properties": {
"data": {
"$ref": "#/definitions/schema.AIPromptConfig"
}
}
}
]
}
}
}
},
"put": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "update AI prompt configuration",
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "update AI prompt configuration",
"parameters": [
{
"description": "AI prompt config",
"name": "data",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/schema.AIPromptConfig"
}
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/handler.RespBody"
}
}
}
}
},
"/answer/admin/api/ai-provider": {
"get": {
"security": [
Expand Down
8 changes: 6 additions & 2 deletions i18n/en_US.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2354,8 +2354,14 @@ ui:
model:
label: Model
msg: Model is required
prompt:
label: Prompt
text: Shows the prompt for the current language. Edit and save to apply.
add_success: AI settings updated successfully.
conversations:
tabs:
conversations: Conversations
settings: Settings
topic: Topic
helpful: Helpful
unhelpful: Unhelpful
Expand Down Expand Up @@ -2482,5 +2488,3 @@ ui:
copy: Copy to clipboard
copied: Copied
external_content_warning: External images/media are not displayed.


10 changes: 7 additions & 3 deletions i18n/zh_CN.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1796,7 +1796,7 @@ ui:
security: 安全
files: 文件
apikeys: API 密钥
intelligence: 智力
intelligence: 智能
ai_assistant: AI 助手
ai_settings: AI 设置
mcp: MCP
Expand Down Expand Up @@ -2318,8 +2318,14 @@ ui:
model:
label: 模型
msg: 模型是必需的
prompt:
label: 提示词
text: 显示当前语言环境的提示词,可在此修改并保存。
add_success: AI 设置更新成功。
conversations:
tabs:
conversations: 对话
settings: 设置
topic: 主题
helpful: 有帮助
unhelpful: 没有帮助
Expand Down Expand Up @@ -2446,5 +2452,3 @@ ui:
copy: 复制到剪贴板
copied: 已复制
external_content_warning: 外部图像/媒体未显示。


32 changes: 32 additions & 0 deletions internal/controller_admin/siteinfo_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,38 @@ func (sc *SiteInfoController) UpdateAIConfig(ctx *gin.Context) {
handler.HandleResponse(ctx, err, nil)
}

// GetAIPromptConfig get AI prompt configuration
// @Summary get AI prompt configuration
// @Description get AI prompt configuration
// @Security ApiKeyAuth
// @Tags admin
// @Produce json
// @Success 200 {object} handler.RespBody{data=schema.AIPromptConfig}
// @Router /answer/admin/api/ai-prompt-config [get]
func (sc *SiteInfoController) GetAIPromptConfig(ctx *gin.Context) {
resp, err := sc.siteInfoService.GetAIPromptConfig(ctx)
handler.HandleResponse(ctx, err, resp)
}

// UpdateAIPromptConfig update AI prompt configuration
// @Summary update AI prompt configuration
// @Description update AI prompt configuration
// @Security ApiKeyAuth
// @Tags admin
// @Param data body schema.AIPromptConfig true "AI prompt config"
// @Produce json
// @Success 200 {object} handler.RespBody{}
// @Router /answer/admin/api/ai-prompt-config [put]
func (sc *SiteInfoController) UpdateAIPromptConfig(ctx *gin.Context) {
req := &schema.AIPromptConfig{}
if handler.BindAndCheck(ctx, req) {
return
}

err := sc.siteInfoService.SaveAIPromptConfig(ctx, req)
handler.HandleResponse(ctx, err, nil)
}

// GetAIProvider get AI provider configuration
// @Summary get AI provider configuration
// @Description get AI provider configuration
Expand Down
2 changes: 2 additions & 0 deletions internal/router/answer_api_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ func (a *AnswerAPIRouter) RegisterAnswerAdminAPIRouter(r *gin.RouterGroup) {
// ai config
r.GET("/ai-config", a.adminSiteInfoController.GetAIConfig)
r.PUT("/ai-config", a.adminSiteInfoController.UpdateAIConfig)
r.GET("/ai-prompt-config", a.adminSiteInfoController.GetAIPromptConfig)
r.PUT("/ai-prompt-config", a.adminSiteInfoController.UpdateAIPromptConfig)
r.GET("/ai-provider", a.adminSiteInfoController.GetAIProvider)
r.POST("/ai-models", a.adminSiteInfoController.RequestAIModels)

Expand Down
42 changes: 39 additions & 3 deletions internal/service/siteinfo/siteinfo_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,16 +365,52 @@ func (s *SiteInfoService) GetSiteAI(ctx context.Context) (resp *schema.SiteAIRes
return resp, nil
}

// GetAIPromptConfig get AI prompt configuration
func (s *SiteInfoService) GetAIPromptConfig(ctx context.Context) (resp *schema.AIPromptConfig, err error) {
siteAI, err := s.siteInfoCommonService.GetSiteAI(ctx)
if err != nil {
return nil, err
}
if siteAI.PromptConfig != nil {
return &schema.AIPromptConfig{
ZhCN: siteAI.PromptConfig.ZhCN,
EnUS: siteAI.PromptConfig.EnUS,
}, nil
}
return &schema.AIPromptConfig{
ZhCN: constant.DefaultAIPromptConfigZhCN,
EnUS: constant.DefaultAIPromptConfigEnUS,
}, nil
}

// SaveAIPromptConfig save AI prompt configuration
func (s *SiteInfoService) SaveAIPromptConfig(ctx context.Context, req *schema.AIPromptConfig) (err error) {
siteAI, err := s.siteInfoCommonService.GetSiteAI(ctx)
if err != nil {
return err
}
siteAI.PromptConfig = req

content, _ := json.Marshal(siteAI)
siteInfo := &entity.SiteInfo{
Type: constant.SiteTypeAI,
Content: string(content),
Status: 1,
}
return s.siteInfoRepo.SaveByType(ctx, constant.SiteTypeAI, siteInfo)
}

// SaveSiteAI save site AI configuration
func (s *SiteInfoService) SaveSiteAI(ctx context.Context, req *schema.SiteAIReq) (err error) {
if err := s.restoreMaskedAIKeys(ctx, req); err != nil {
return err
}
if req.PromptConfig == nil {
req.PromptConfig = &schema.AIPromptConfig{
ZhCN: constant.DefaultAIPromptConfigZhCN,
EnUS: constant.DefaultAIPromptConfigEnUS,
promptConfig, err := s.GetAIPromptConfig(ctx)
if err != nil {
return err
}
req.PromptConfig = promptConfig
}

aiProvider, err := s.GetAIProvider(ctx)
Expand Down
5 changes: 5 additions & 0 deletions ui/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ export const ADMIN_QA_NAV_MENUS = [
{ name: 'settings', path: '/admin/qa/settings' },
];

export const ADMIN_AI_ASSISTANT_NAV_MENUS = [
{ name: 'conversations', path: '/admin/ai-assistant' },
{ name: 'settings', path: '/admin/ai-assistant/settings' },
];

export const ADMIN_TAGS_NAV_MENUS = [
// { name: 'tags', path: '/admin/tags' },
{
Expand Down
6 changes: 6 additions & 0 deletions ui/src/common/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,11 @@ export interface AddOrEditApiKeyParams {
id?: number;
}

export interface AIPromptConfig {
zh_cn: string;
en_us: string;
}

export interface AiConfig {
enabled: boolean;
chosen_provider: string;
Expand All @@ -834,6 +839,7 @@ export interface AiConfig {
api_key: string;
model: string;
}>;
prompt_config?: AIPromptConfig;
}

export interface AiProviderItem {
Expand Down
7 changes: 5 additions & 2 deletions ui/src/components/TabNav/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ import { Nav } from 'react-bootstrap';
import { NavLink, useLocation } from 'react-router-dom';
import { useTranslation } from 'react-i18next';

const TabNav: FC<{ menus: { name: string; path: string }[] }> = ({ menus }) => {
const { t } = useTranslation('translation', { keyPrefix: 'nav_menus' });
const TabNav: FC<{
menus: { name: string; path: string }[];
i18nKeyPrefix?: string;
}> = ({ menus, i18nKeyPrefix = 'nav_menus' }) => {
const { t } = useTranslation('translation', { keyPrefix: i18nKeyPrefix });
const { pathname } = useLocation();
return (
<Nav variant="underline" className="mb-4 border-bottom">
Expand Down
Loading