Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from application.flow.step_node.function_lib_node.i_function_lib_node import IFunctionLibNode
from common.exception.app_exception import AppApiException
from common.util.function_code import FunctionExecutor
from common.util.rsa_util import rsa_long_decrypt
from function_lib.models.function import FunctionLib
from smartdoc.const import CONFIG

Expand Down Expand Up @@ -107,8 +108,11 @@ def execute(self, function_lib_id, input_field_list, **kwargs) -> NodeResult:
), **field}
for field in
function_lib.input_field_list]}

self.context['params'] = params
result = function_executor.exec_code(function_lib.code, params)
# 合并初始化参数
all_params = json.loads(rsa_long_decrypt(function_lib.init_params)) | params
result = function_executor.exec_code(function_lib.code, all_params)
return NodeResult({'result': result}, {}, _write_context=write_context)

def get_details(self, index: int, **kwargs):
Expand Down
8 changes: 5 additions & 3 deletions apps/application/serializers/application_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from dataset.models import DataSet, Document, Image
from dataset.serializers.common_serializers import list_paragraph, get_embedding_model_by_dataset_id_list
from embedding.models import SearchMode
from function_lib.models.function import FunctionLib, PermissionType
from function_lib.models.function import FunctionLib, PermissionType, FunctionType
from function_lib.serializers.function_lib_serializer import FunctionLibSerializer, FunctionLibModelSerializer
from setting.models import AuthOperate, TeamMemberPermission
from setting.models.model_management import Model
Expand Down Expand Up @@ -810,8 +810,10 @@ def list_function_lib(self, with_valid=True):
if with_valid:
self.is_valid(raise_exception=True)
application = QuerySet(Application).filter(id=self.data.get("application_id")).first()
return FunctionLibSerializer.Query(data={'user_id': application.user_id, 'is_active': True}).list(
with_valid=True)
return FunctionLibSerializer.Query(
data={'user_id': application.user_id, 'is_active': True,
'function_type': FunctionType.PUBLIC}
).list(with_valid=True)

def get_function_lib(self, function_lib_id, with_valid=True):
if with_valid:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Generated by Django 4.2.15 on 2025-03-13 07:21

from django.db import migrations, models

function_template = '''
INSERT INTO function_lib (create_time, update_time, id, name, "desc", code, input_field_list, user_id, is_active, permission_type, function_type, icon, init_field_list, init_params, template_id) VALUES ('2025-03-10 06:20:35.945414 +00:00', '2025-03-10 09:19:23.608026 +00:00', 'c75cb48e-fd77-11ef-84d2-5618c4394482', '博查AI', '从博查搜索任何信息和网页URL', e'def bocha_search(query, apikey):
import requests
import json
url = "https://api.bochaai.com/v1/web-search"
payload = json.dumps({
"query": query,
"Boolean": "true",
"count": 8
})

headers = {
"Authorization": "Bearer " + apikey, #鉴权参数,示例:Bearer xxxxxx,API KEY请先前往博查AI开放平台(https://open.bochaai.com)> API KEY 管理中获取。
"Content-Type": "application/json"
}

response = requests.request("POST", url, headers=headers, data=payload)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"API请求失败: {response.status_code}, 错误信息: {response.text}")
return (response.text)', '{"{\\"name\\": \\"query\\", \\"type\\": \\"string\\", \\"source\\": \\"reference\\", \\"is_required\\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', TRUE, 'PUBLIC', 'INTERNAL', '/src/assets/fx/bochaai/icon.png', '[{"attrs": {"type": "password", "maxlength": 200, "minlength": 1, "show-password": true, "show-word-limit": true}, "field": "apikey", "label": "apikey", "required": true, "input_type": "PasswordInput", "props_info": {"rules": [{"message": "apikey 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "apikey长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}]', '', NULL);
INSERT INTO function_lib (create_time, update_time, id, name, "desc", code, input_field_list, user_id, is_active, permission_type, function_type, icon, init_field_list, init_params, template_id) VALUES ('2025-02-26 03:36:48.187286 +00:00', '2025-03-11 07:23:46.123972 +00:00', 'e89ad2ae-f3f2-11ef-ad09-0242ac110002', 'Google Search', 'Google Web Search', e'def google_search(query, apikey, cx):
import requests
import json
url = "https://customsearch.googleapis.com/customsearch/v1"
params = {
"q": query,
"key": apikey,
"cx": cx,
"num": 10, # 每次最多返回10条
}

response = requests.get(url, params=params)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"API请求失败: {response.status_code}, 错误信息: {response.text}")
return (response.text)', '{"{\\"name\\": \\"query\\", \\"type\\": \\"string\\", \\"source\\": \\"reference\\", \\"is_required\\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', TRUE, 'PUBLIC', 'INTERNAL', '/src/assets/fx/google_search/icon.png', '[{"attrs": {"type": "password", "maxlength": 200, "minlength": 1, "show-password": true, "show-word-limit": true}, "field": "apikey", "label": "apikey", "required": true, "input_type": "PasswordInput", "props_info": {"rules": [{"message": "apikey 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "apikey长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}, {"attrs": {"maxlength": 200, "minlength": 1, "show-word-limit": true}, "field": "cx", "label": "cx", "required": true, "input_type": "TextInput", "props_info": {"rules": [{"message": "cx 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "cx长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}]', '', NULL);
INSERT INTO function_lib (create_time, update_time, id, name, "desc", code, input_field_list, user_id, is_active, permission_type, function_type, icon, init_field_list, init_params, template_id) VALUES ('2025-02-25 07:44:40.141515 +00:00', '2025-03-11 06:33:53.248495 +00:00', '5e912f00-f34c-11ef-8a9c-5618c4394482', 'LangSearch API', e'A Web Search API supporting natural language search
', e'
def langsearch(query, apikey):
import json
import requests

url = "https://api.langsearch.com/v1/web-search"
payload = json.dumps({
"query": query,
"summary": True,
"freshness": "noLimit",
"livecrawl": True,
"count": 20
})
headers = {
"Authorization": apikey,
"Content-Type": "application/json"
}
# key从官网申请 https://langsearch.com/
response = requests.request("POST", url, headers=headers, data=payload)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"API请求失败: {response.status_code}, 错误信息: {response.text}")
return (response.text)', '{"{\\"name\\": \\"query\\", \\"type\\": \\"string\\", \\"source\\": \\"reference\\", \\"is_required\\": true}"}', 'f0dd8f71-e4ee-11ee-8c84-a8a1595801ab', TRUE, 'PUBLIC', 'INTERNAL', '/src/assets/fx/langsearch/icon.png', '[{"attrs": {"type": "password", "maxlength": 200, "minlength": 1, "show-password": true, "show-word-limit": true}, "field": "apikey", "label": "apikey", "required": true, "input_type": "PasswordInput", "props_info": {"rules": [{"message": "apikey 为必填属性", "required": true}, {"max": 200, "min": 1, "message": "apikey长度在 1 到 200 个字符", "trigger": "blur"}]}, "default_value": "x", "show_default_value": false}]', '', NULL);

'''


class Migration(migrations.Migration):
dependencies = [
('function_lib', '0002_functionlib_is_active_functionlib_permission_type'),
]

operations = [
migrations.AddField(
model_name='functionlib',
name='function_type',
field=models.CharField(choices=[('INTERNAL', '内置'), ('PUBLIC', '公开')],
default='PUBLIC', max_length=20, verbose_name='函数类型'),
),
migrations.AddField(
model_name='functionlib',
name='icon',
field=models.CharField(default='/ui/favicon.ico', max_length=256,
verbose_name='函数库icon'),
),
migrations.AddField(
model_name='functionlib',
name='init_field_list',
field=models.JSONField(default=list, verbose_name='启动字段列表'),
),
migrations.AddField(
model_name='functionlib',
name='init_params',
field=models.CharField(max_length=102400, null=True, verbose_name='初始化参数'),
),
migrations.AddField(
model_name='functionlib',
name='template_id',
field=models.UUIDField(default=None, null=True, verbose_name='模版id'),
),
migrations.RunSQL(function_template)
]
10 changes: 10 additions & 0 deletions apps/function_lib/models/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class PermissionType(models.TextChoices):
PUBLIC = "PUBLIC", '公开'
PRIVATE = "PRIVATE", "私有"

class FunctionType(models.TextChoices):
INTERNAL = "INTERNAL", '内置'
PUBLIC = "PUBLIC", "公开"


class FunctionLib(AppModelMixin):
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid1, editable=False, verbose_name="主键id")
Expand All @@ -29,9 +33,15 @@ class FunctionLib(AppModelMixin):
input_field_list = ArrayField(verbose_name="输入字段列表",
base_field=models.JSONField(verbose_name="输入字段", default=dict)
, default=list)
init_field_list = models.JSONField(verbose_name="启动字段列表", default=list)
icon = models.CharField(max_length=256, verbose_name="函数库icon", default="/ui/favicon.ico")
is_active = models.BooleanField(default=True)
permission_type = models.CharField(max_length=20, verbose_name='权限类型', choices=PermissionType.choices,
default=PermissionType.PRIVATE)
function_type = models.CharField(max_length=20, verbose_name='函数类型', choices=FunctionType.choices,
default=FunctionType.PUBLIC)
template_id = models.UUIDField(max_length=128, verbose_name="模版id", null=True, default=None)
init_params = models.CharField(max_length=102400, verbose_name="初始化参数", null=True)

class Meta:
db_table = "function_lib"
8 changes: 8 additions & 0 deletions apps/function_lib/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# coding=utf-8
"""
@project: MaxKB
@Author:虎
@file: __init__.py.py
@date:2024/8/2 14:55
@desc:
"""
Loading