Merge branch 'main' into feat/rag-pipeline

This commit is contained in:
zxhlyh 2025-06-06 15:01:27 +08:00
commit f9d0a7bdc8
12 changed files with 52 additions and 37 deletions

View File

@ -43,6 +43,7 @@ select = [
"S307", # suspicious-eval-usage, disallow use of `eval` and `ast.literal_eval` "S307", # suspicious-eval-usage, disallow use of `eval` and `ast.literal_eval`
"S301", # suspicious-pickle-usage, disallow use of `pickle` and its wrappers. "S301", # suspicious-pickle-usage, disallow use of `pickle` and its wrappers.
"S302", # suspicious-marshal-usage, disallow use of `marshal` module "S302", # suspicious-marshal-usage, disallow use of `marshal` module
"S311", # suspicious-non-cryptographic-random-usage
] ]
ignore = [ ignore = [

View File

@ -1,5 +1,5 @@
import logging import logging
import random import secrets
from typing import cast from typing import cast
from core.app.entities.app_invoke_entities import ModelConfigWithCredentialsEntity from core.app.entities.app_invoke_entities import ModelConfigWithCredentialsEntity
@ -38,7 +38,7 @@ def check_moderation(tenant_id: str, model_config: ModelConfigWithCredentialsEnt
if len(text_chunks) == 0: if len(text_chunks) == 0:
return True return True
text_chunk = random.choice(text_chunks) text_chunk = secrets.choice(text_chunks)
try: try:
model_provider_factory = ModelProviderFactory(tenant_id) model_provider_factory = ModelProviderFactory(tenant_id)

View File

@ -1,8 +1,9 @@
import base64 import base64
import json import json
import secrets
import string
from collections.abc import Mapping from collections.abc import Mapping
from copy import deepcopy from copy import deepcopy
from random import randint
from typing import Any, Literal from typing import Any, Literal
from urllib.parse import urlencode, urlparse from urllib.parse import urlencode, urlparse
@ -434,4 +435,4 @@ def _generate_random_string(n: int) -> str:
>>> _generate_random_string(5) >>> _generate_random_string(5)
'abcde' 'abcde'
""" """
return "".join([chr(randint(97, 122)) for _ in range(n)]) return "".join(secrets.choice(string.ascii_lowercase) for _ in range(n))

View File

@ -1,7 +1,7 @@
import json import json
import logging import logging
import random
import re import re
import secrets
import string import string
import subprocess import subprocess
import time import time
@ -176,7 +176,7 @@ def generate_string(n):
letters_digits = string.ascii_letters + string.digits letters_digits = string.ascii_letters + string.digits
result = "" result = ""
for i in range(n): for i in range(n):
result += random.choice(letters_digits) result += secrets.choice(letters_digits)
return result return result

View File

@ -1,7 +1,6 @@
import base64 import base64
import json import json
import logging import logging
import random
import secrets import secrets
import uuid import uuid
from datetime import UTC, datetime, timedelta from datetime import UTC, datetime, timedelta
@ -261,7 +260,7 @@ class AccountService:
@staticmethod @staticmethod
def generate_account_deletion_verification_code(account: Account) -> tuple[str, str]: def generate_account_deletion_verification_code(account: Account) -> tuple[str, str]:
code = "".join([str(random.randint(0, 9)) for _ in range(6)]) code = "".join([str(secrets.randbelow(exclusive_upper_bound=10)) for _ in range(6)])
token = TokenManager.generate_token( token = TokenManager.generate_token(
account=account, token_type="account_deletion", additional_data={"code": code} account=account, token_type="account_deletion", additional_data={"code": code}
) )
@ -429,7 +428,7 @@ class AccountService:
additional_data: dict[str, Any] = {}, additional_data: dict[str, Any] = {},
): ):
if not code: if not code:
code = "".join([str(random.randint(0, 9)) for _ in range(6)]) code = "".join([str(secrets.randbelow(exclusive_upper_bound=10)) for _ in range(6)])
additional_data["code"] = code additional_data["code"] = code
token = TokenManager.generate_token( token = TokenManager.generate_token(
account=account, email=email, token_type="reset_password", additional_data=additional_data account=account, email=email, token_type="reset_password", additional_data=additional_data
@ -456,7 +455,7 @@ class AccountService:
raise EmailCodeLoginRateLimitExceededError() raise EmailCodeLoginRateLimitExceededError()
code = "".join([str(random.randint(0, 9)) for _ in range(6)]) code = "".join([str(secrets.randbelow(exclusive_upper_bound=10)) for _ in range(6)])
token = TokenManager.generate_token( token = TokenManager.generate_token(
account=account, email=email, token_type="email_code_login", additional_data={"code": code} account=account, email=email, token_type="email_code_login", additional_data={"code": code}
) )

View File

@ -2,7 +2,7 @@ import copy
import datetime import datetime
import json import json
import logging import logging
import random import secrets
import time import time
import uuid import uuid
from collections import Counter from collections import Counter
@ -970,7 +970,7 @@ class DocumentService:
documents.append(document) documents.append(document)
batch = document.batch batch = document.batch
else: else:
batch = time.strftime("%Y%m%d%H%M%S") + str(random.randint(100000, 999999)) batch = time.strftime("%Y%m%d%H%M%S") + str(100000 + secrets.randbelow(exclusive_upper_bound=900000))
# save process rule # save process rule
if not dataset_process_rule: if not dataset_process_rule:
process_rule = knowledge_config.process_rule process_rule = knowledge_config.process_rule

View File

@ -1,4 +1,4 @@
import random import secrets
from datetime import UTC, datetime, timedelta from datetime import UTC, datetime, timedelta
from typing import Any, Optional, cast from typing import Any, Optional, cast
@ -66,7 +66,7 @@ class WebAppAuthService:
if email is None: if email is None:
raise ValueError("Email must be provided.") raise ValueError("Email must be provided.")
code = "".join([str(random.randint(0, 9)) for _ in range(6)]) code = "".join([str(secrets.randbelow(exclusive_upper_bound=10)) for _ in range(6)])
token = TokenManager.generate_token( token = TokenManager.generate_token(
account=account, email=email, token_type="webapp_email_code_login", additional_data={"code": code} account=account, email=email, token_type="webapp_email_code_login", additional_data={"code": code}
) )

View File

@ -1,4 +1,4 @@
import random import secrets
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
import pytest import pytest
@ -34,7 +34,7 @@ def test_retry_logic_success(mock_request):
side_effects = [] side_effects = []
for _ in range(SSRF_DEFAULT_MAX_RETRIES): for _ in range(SSRF_DEFAULT_MAX_RETRIES):
status_code = random.choice(STATUS_FORCELIST) status_code = secrets.choice(STATUS_FORCELIST)
mock_response = MagicMock() mock_response = MagicMock()
mock_response.status_code = status_code mock_response.status_code = status_code
side_effects.append(mock_response) side_effects.append(mock_response)

View File

@ -18,9 +18,10 @@ const queryDateFormat = 'YYYY-MM-DD HH:mm'
export type IChartViewProps = { export type IChartViewProps = {
appId: string appId: string
headerRight: React.ReactNode
} }
export default function ChartView({ appId }: IChartViewProps) { export default function ChartView({ appId, headerRight }: IChartViewProps) {
const { t } = useTranslation() const { t } = useTranslation()
const appDetail = useAppStore(state => state.appDetail) const appDetail = useAppStore(state => state.appDetail)
const isChatApp = appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow' const isChatApp = appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow'
@ -46,19 +47,22 @@ export default function ChartView({ appId }: IChartViewProps) {
return ( return (
<div> <div>
<div className='system-xl-semibold mb-4 mt-8 flex flex-row items-center text-text-primary'> <div className='mb-4 flex items-center justify-between'>
<span className='mr-3'>{t('appOverview.analysis.title')}</span> <div className='system-xl-semibold flex flex-row items-center text-text-primary'>
<SimpleSelect <span className='mr-3'>{t('appOverview.analysis.title')}</span>
items={Object.entries(TIME_PERIOD_MAPPING).map(([k, v]) => ({ value: k, name: t(`appLog.filter.period.${v.name}`) }))} <SimpleSelect
className='mt-0 !w-40' items={Object.entries(TIME_PERIOD_MAPPING).map(([k, v]) => ({ value: k, name: t(`appLog.filter.period.${v.name}`) }))}
onSelect={(item) => { className='mt-0 !w-40'
const id = item.value onSelect={(item) => {
const value = TIME_PERIOD_MAPPING[id]?.value ?? '-1' const id = item.value
const name = item.name || t('appLog.filter.period.allTime') const value = TIME_PERIOD_MAPPING[id]?.value ?? '-1'
onSelect({ value, name }) const name = item.name || t('appLog.filter.period.allTime')
}} onSelect({ value, name })
defaultValue={'2'} }}
/> defaultValue={'2'}
/>
</div>
{headerRight}
</div> </div>
{!isWorkflow && ( {!isWorkflow && (
<div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'> <div className='mb-6 grid w-full grid-cols-1 gap-6 xl:grid-cols-2'>

View File

@ -1,6 +1,5 @@
import React from 'react' import React from 'react'
import ChartView from './chartView' import ChartView from './chartView'
import CardView from './cardView'
import TracingPanel from './tracing/panel' import TracingPanel from './tracing/panel'
import ApikeyInfoPanel from '@/app/components/app/overview/apikey-info-panel' import ApikeyInfoPanel from '@/app/components/app/overview/apikey-info-panel'
@ -18,9 +17,10 @@ const Overview = async (props: IDevelopProps) => {
return ( return (
<div className="h-full overflow-scroll bg-chatbot-bg px-4 py-6 sm:px-12"> <div className="h-full overflow-scroll bg-chatbot-bg px-4 py-6 sm:px-12">
<ApikeyInfoPanel /> <ApikeyInfoPanel />
<TracingPanel /> <ChartView
<CardView appId={appId} /> appId={appId}
<ChartView appId={appId} /> headerRight={<TracingPanel />}
/>
</div> </div>
) )
} }

View File

@ -154,7 +154,6 @@ const Panel: FC = () => {
if (!isLoaded) { if (!isLoaded) {
return ( return (
<div className='mb-3 flex items-center justify-between'> <div className='mb-3 flex items-center justify-between'>
<Title className='h-[41px]' />
<div className='w-[200px]'> <div className='w-[200px]'>
<Loading /> <Loading />
</div> </div>
@ -163,8 +162,7 @@ const Panel: FC = () => {
} }
return ( return (
<div className={cn('mb-3 flex items-center justify-between')}> <div className={cn('flex items-center justify-between')}>
<Title className='h-[41px]' />
<div <div
className={cn( className={cn(
'flex cursor-pointer items-center rounded-xl border-l-[0.5px] border-t border-effects-highlight bg-background-default-dodge p-2 shadow-xs hover:border-effects-highlight-lightmode-off hover:bg-background-default-lighter', 'flex cursor-pointer items-center rounded-xl border-l-[0.5px] border-t border-effects-highlight bg-background-default-dodge p-2 shadow-xs hover:border-effects-highlight-lightmode-off hover:bg-background-default-lighter',

View File

@ -5,6 +5,18 @@
"engines": { "engines": {
"node": ">=v22.11.0" "node": ">=v22.11.0"
}, },
"browserslist": [
"last 1 Chrome version",
"last 1 Firefox version",
"last 1 Edge version",
"last 1 Safari version",
"iOS >=15",
"Android >= 10",
"and_chr >= 126",
"and_ff >= 137",
"and_uc >= 15.5",
"and_qq >= 14.9"
],
"scripts": { "scripts": {
"dev": "cross-env NODE_OPTIONS='--inspect' next dev", "dev": "cross-env NODE_OPTIONS='--inspect' next dev",
"build": "next build", "build": "next build",