Skip to content

Commit

Permalink
Merge branch 'fix/remove-refreshing-sign' into deploy/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
douxc committed Dec 31, 2024
2 parents 5b38b46 + 9c88cf7 commit 2e4301c
Show file tree
Hide file tree
Showing 181 changed files with 2,728 additions and 394 deletions.
4 changes: 2 additions & 2 deletions api/.ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ ignore = [
]
"tests/*" = [
"F811", # redefined-while-unused
"F401", # unused-import
]

[lint.pyflakes]
extend-generics = [
allowed-unused-imports = [
"_pytest.monkeypatch",
"tests.integration_tests",
"tests.unit_tests",
]
2 changes: 1 addition & 1 deletion api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ RUN apt-get update \
&& echo "deb http://deb.debian.org/debian testing main" > /etc/apt/sources.list \
&& apt-get update \
# For Security
&& apt-get install -y --no-install-recommends expat=2.6.4-1 libldap-2.5-0=2.5.18+dfsg-3+b1 perl=5.40.0-8 libsqlite3-0=3.46.1-1 zlib1g=1:1.3.dfsg+really1.3.1-1+b1 \
&& apt-get install -y --no-install-recommends expat=2.6.4-1 libldap-2.5-0=2.5.19+dfsg-1 perl=5.40.0-8 libsqlite3-0=3.46.1-1 zlib1g=1:1.3.dfsg+really1.3.1-1+b1 \
# install a chinese font to support the use of tools like matplotlib
&& apt-get install -y fonts-noto-cjk \
&& apt-get autoremove -y \
Expand Down
30 changes: 28 additions & 2 deletions api/controllers/console/app/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import logging

from flask import abort, request
from flask_restful import Resource, marshal_with, reqparse # type: ignore
from flask_restful import Resource, inputs, marshal_with, reqparse # type: ignore
from werkzeug.exceptions import Forbidden, InternalServerError, NotFound

import services
Expand All @@ -14,7 +14,7 @@
from core.app.apps.base_app_queue_manager import AppQueueManager
from core.app.entities.app_invoke_entities import InvokeFrom
from factories import variable_factory
from fields.workflow_fields import workflow_fields
from fields.workflow_fields import workflow_fields, workflow_pagination_fields
from fields.workflow_run_fields import workflow_run_node_execution_fields
from libs import helper
from libs.helper import TimestampField, uuid_value
Expand Down Expand Up @@ -440,6 +440,31 @@ def get(self, app_model: App):
}


class PublishedAllWorkflowApi(Resource):
@setup_required
@login_required
@account_initialization_required
@get_app_model(mode=[AppMode.ADVANCED_CHAT, AppMode.WORKFLOW])
@marshal_with(workflow_pagination_fields)
def get(self, app_model: App):
"""
Get published workflows
"""
if not current_user.is_editor:
raise Forbidden()

parser = reqparse.RequestParser()
parser.add_argument("page", type=inputs.int_range(1, 99999), required=False, default=1, location="args")
parser.add_argument("limit", type=inputs.int_range(1, 100), required=False, default=20, location="args")
args = parser.parse_args()
page = args.get("page")
limit = args.get("limit")
workflow_service = WorkflowService()
workflows, has_more = workflow_service.get_all_published_workflow(app_model=app_model, page=page, limit=limit)

return {"items": workflows, "page": page, "limit": limit, "has_more": has_more}


api.add_resource(DraftWorkflowApi, "/apps/<uuid:app_id>/workflows/draft")
api.add_resource(WorkflowConfigApi, "/apps/<uuid:app_id>/workflows/draft/config")
api.add_resource(AdvancedChatDraftWorkflowRunApi, "/apps/<uuid:app_id>/advanced-chat/workflows/draft/run")
Expand All @@ -454,6 +479,7 @@ def get(self, app_model: App):
WorkflowDraftRunIterationNodeApi, "/apps/<uuid:app_id>/workflows/draft/iteration/nodes/<string:node_id>/run"
)
api.add_resource(PublishedWorkflowApi, "/apps/<uuid:app_id>/workflows/publish")
api.add_resource(PublishedAllWorkflowApi, "/apps/<uuid:app_id>/workflows")
api.add_resource(DefaultBlockConfigsApi, "/apps/<uuid:app_id>/workflows/default-workflow-block-configs")
api.add_resource(
DefaultBlockConfigApi, "/apps/<uuid:app_id>/workflows/default-workflow-block-configs/<string:block_type>"
Expand Down
9 changes: 8 additions & 1 deletion api/controllers/console/explore/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,17 @@ def post(self, installed_app, message_id):

parser = reqparse.RequestParser()
parser.add_argument("rating", type=str, choices=["like", "dislike", None], location="json")
parser.add_argument("content", type=str, location="json")
args = parser.parse_args()

try:
MessageService.create_feedback(app_model, message_id, current_user, args.get("rating"), args.get("content"))
MessageService.create_feedback(
app_model=app_model,
message_id=message_id,
user=current_user,
rating=args.get("rating"),
content=args.get("content"),
)
except services.errors.message.MessageNotExistsError:
raise NotFound("Message Not Exists.")

Expand Down
2 changes: 1 addition & 1 deletion api/controllers/console/workspace/members.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def put(self, member_id):
return {"code": "invalid-role", "message": "Invalid role"}, 400

member = db.session.get(Account, str(member_id))
if member:
if not member:
abort(404)

try:
Expand Down
8 changes: 7 additions & 1 deletion api/controllers/service_api/app/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,13 @@ def post(self, app_model: App, end_user: EndUser, message_id):
args = parser.parse_args()

try:
MessageService.create_feedback(app_model, message_id, end_user, args.get("rating"), args.get("content"))
MessageService.create_feedback(
app_model=app_model,
message_id=message_id,
user=end_user,
rating=args.get("rating"),
content=args.get("content"),
)
except services.errors.message.MessageNotExistsError:
raise NotFound("Message Not Exists.")

Expand Down
29 changes: 19 additions & 10 deletions api/controllers/service_api/dataset/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
import services.dataset_service
from controllers.common.errors import FilenameNotExistsError
from controllers.service_api import api
from controllers.service_api.app.error import ProviderNotInitializeError
from controllers.service_api.app.error import (
FileTooLargeError,
NoFileUploadedError,
ProviderNotInitializeError,
TooManyFilesError,
UnsupportedFileTypeError,
)
from controllers.service_api.dataset.error import (
ArchivedDocumentImmutableError,
DocumentIndexingError,
NoFileUploadedError,
TooManyFilesError,
)
from controllers.service_api.wraps import DatasetApiResource, cloud_edition_billing_resource_check
from core.errors.error import ProviderTokenNotInitError
Expand Down Expand Up @@ -238,13 +242,18 @@ def post(self, tenant_id, dataset_id, document_id):
if not file.filename:
raise FilenameNotExistsError

upload_file = FileService.upload_file(
filename=file.filename,
content=file.read(),
mimetype=file.mimetype,
user=current_user,
source="datasets",
)
try:
upload_file = FileService.upload_file(
filename=file.filename,
content=file.read(),
mimetype=file.mimetype,
user=current_user,
source="datasets",
)
except services.errors.file.FileTooLargeError as file_too_large_error:
raise FileTooLargeError(file_too_large_error.description)
except services.errors.file.UnsupportedFileTypeError:
raise UnsupportedFileTypeError()
data_source = {"type": "upload_file", "info_list": {"file_info_list": {"file_ids": [upload_file.id]}}}
args["data_source"] = data_source
# validate args
Expand Down
10 changes: 5 additions & 5 deletions api/core/agent/base_agent_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,13 +339,13 @@ def save_agent_thought(
raise ValueError(f"Agent thought {agent_thought.id} not found")
agent_thought = queried_thought

if thought is not None:
if thought:
agent_thought.thought = thought

if tool_name is not None:
if tool_name:
agent_thought.tool = tool_name

if tool_input is not None:
if tool_input:
if isinstance(tool_input, dict):
try:
tool_input = json.dumps(tool_input, ensure_ascii=False)
Expand All @@ -354,7 +354,7 @@ def save_agent_thought(

agent_thought.tool_input = tool_input

if observation is not None:
if observation:
if isinstance(observation, dict):
try:
observation = json.dumps(observation, ensure_ascii=False)
Expand All @@ -363,7 +363,7 @@ def save_agent_thought(

agent_thought.observation = observation

if answer is not None:
if answer:
agent_thought.answer = answer

if messages_ids is not None and len(messages_ids) > 0:
Expand Down
1 change: 1 addition & 0 deletions api/core/model_runtime/model_providers/wenxin/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ class _CommonWenxin:
"bge-large-zh": "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/bge_large_zh",
"tao-8k": "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/embeddings/tao_8k",
"bce-reranker-base_v1": "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/reranker/bce_reranker_base",
"ernie-lite-pro-128k": "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/ernie-lite-pro-128k",
}

function_calling_supports = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
model: ernie-lite-pro-128k
label:
en_US: Ernie-Lite-Pro-128K
model_type: llm
features:
- agent-thought
model_properties:
mode: chat
context_size: 128000
parameter_rules:
- name: temperature
use_template: temperature
min: 0.1
max: 1.0
default: 0.8
- name: top_p
use_template: top_p
- name: min_output_tokens
label:
en_US: "Min Output Tokens"
zh_Hans: "最小输出Token数"
use_template: max_tokens
min: 2
max: 2048
help:
zh_Hans: 指定模型最小输出token数
en_US: Specifies the lower limit on the length of generated results.
- name: max_output_tokens
label:
en_US: "Max Output Tokens"
zh_Hans: "最大输出Token数"
use_template: max_tokens
min: 2
max: 2048
default: 2048
help:
zh_Hans: 指定模型最大输出token数
en_US: Specifies the upper limit on the length of generated results. If the generated results are truncated, you can increase this parameter.
- name: presence_penalty
use_template: presence_penalty
- name: frequency_penalty
use_template: frequency_penalty
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import re
from typing import Optional
from typing import Optional, cast


class JiebaKeywordTableHandler:
Expand All @@ -8,18 +8,20 @@ def __init__(self):

from core.rag.datasource.keyword.jieba.stopwords import STOPWORDS

jieba.analyse.default_tfidf.stop_words = STOPWORDS
jieba.analyse.default_tfidf.stop_words = STOPWORDS # type: ignore

def extract_keywords(self, text: str, max_keywords_per_chunk: Optional[int] = 10) -> set[str]:
"""Extract keywords with JIEBA tfidf."""
import jieba # type: ignore
import jieba.analyse # type: ignore

keywords = jieba.analyse.extract_tags(
sentence=text,
topK=max_keywords_per_chunk,
)
# jieba.analyse.extract_tags returns list[Any] when withFlag is False by default.
keywords = cast(list[str], keywords)

return set(self._expand_tokens_with_subtokens(keywords))
return set(self._expand_tokens_with_subtokens(set(keywords)))

def _expand_tokens_with_subtokens(self, tokens: set[str]) -> set[str]:
"""Get subtokens from a list of tokens., filtering for stopwords."""
Expand Down
29 changes: 18 additions & 11 deletions api/core/rag/extractor/notion_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,24 @@ def _get_notion_block_data(self, page_id: str) -> list[str]:
block_url = BLOCK_CHILD_URL_TMPL.format(block_id=page_id)
while True:
query_dict: dict[str, Any] = {} if not start_cursor else {"start_cursor": start_cursor}
res = requests.request(
"GET",
block_url,
headers={
"Authorization": "Bearer " + self._notion_access_token,
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
},
params=query_dict,
)
data = res.json()
try:
res = requests.request(
"GET",
block_url,
headers={
"Authorization": "Bearer " + self._notion_access_token,
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
},
params=query_dict,
)
if res.status_code != 200:
raise ValueError(f"Error fetching Notion block data: {res.text}")
data = res.json()
except requests.RequestException as e:
raise ValueError("Error fetching Notion block data") from e
if "results" not in data or not isinstance(data["results"], list):
raise ValueError("Error fetching Notion block data")
for result in data["results"]:
result_type = result["type"]
result_obj = result[result_type]
Expand Down
8 changes: 4 additions & 4 deletions api/core/tools/provider/builtin/aws/tools/bedrock_retrieve.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def _bedrock_retrieve(

retrieval_configuration = {"vectorSearchConfiguration": {"numberOfResults": num_results}}

# 如果有元数据过滤条件,则添加到检索配置中
# Add metadata filter to retrieval configuration if present
if metadata_filter:
retrieval_configuration["vectorSearchConfiguration"]["filter"] = metadata_filter

Expand Down Expand Up @@ -77,7 +77,7 @@ def _invoke(
if not query:
return self.create_text_message("Please input query")

# 获取元数据过滤条件(如果存在)
# Get metadata filter conditions (if they exist)
metadata_filter_str = tool_parameters.get("metadata_filter")
metadata_filter = json.loads(metadata_filter_str) if metadata_filter_str else None

Expand All @@ -86,7 +86,7 @@ def _invoke(
query_input=query,
knowledge_base_id=self.knowledge_base_id,
num_results=self.topk,
metadata_filter=metadata_filter, # 将元数据过滤条件传递给检索方法
metadata_filter=metadata_filter,
)

line = 5
Expand All @@ -109,7 +109,7 @@ def validate_parameters(self, parameters: dict[str, Any]) -> None:
if not parameters.get("query"):
raise ValueError("query is required")

# 可选:可以验证元数据过滤条件是否为有效的 JSON 字符串(如果提供)
# Optional: Validate if metadata filter is a valid JSON string (if provided)
metadata_filter_str = parameters.get("metadata_filter")
if metadata_filter_str and not isinstance(json.loads(metadata_filter_str), dict):
raise ValueError("metadata_filter must be a valid JSON object")
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ parameters:
llm_description: AWS region where the Bedrock Knowledge Base is located
form: form

- name: metadata_filter
type: string
required: false
- name: metadata_filter # Additional parameter for metadata filtering
type: string # String type, expects JSON-formatted filter conditions
required: false # Optional field - can be omitted
label:
en_US: Metadata Filter
zh_Hans: 元数据过滤器
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from core.tools.entities.tool_entities import ToolInvokeMessage
from core.tools.tool.builtin_tool import BuiltinTool

# 定义标签映射
LABEL_MAPPING = {"LABEL_0": "SAFE", "LABEL_1": "NO_SAFE"}
# Define label mappings
LABEL_MAPPING = {0: "SAFE", 1: "NO_SAFE"}


class ContentModerationTool(BuiltinTool):
Expand All @@ -28,12 +28,12 @@ def _invoke_sagemaker(self, payload: dict, endpoint: str):
# Handle nested JSON if present
if isinstance(json_obj, dict) and "body" in json_obj:
body_content = json.loads(json_obj["body"])
raw_label = body_content.get("label")
prediction_result = body_content.get("prediction")
else:
raw_label = json_obj.get("label")
prediction_result = json_obj.get("prediction")

# 映射标签并返回
result = LABEL_MAPPING.get(raw_label, "NO_SAFE") # 如果映射中没有找到,默认返回NO_SAFE
# Map labels and return
result = LABEL_MAPPING.get(prediction_result, "NO_SAFE") # If not found in mapping, default to NO_SAFE
return result

def _invoke(
Expand Down
Loading

0 comments on commit 2e4301c

Please sign in to comment.