feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv 2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@ -0,0 +1,73 @@
name: "ci@backend pipeline"
trigger:
change:
paths:
- "backend/**"
jobs:
unit_test:
image: hub.byted.org/codebase/ci_go_1_24:latest
name: Unit Test
steps:
- id: mysql_scripts
name: mysql scripts
uses: actions/mysql-scripts@v1
inputs:
db_name: opencoze
host: mysql
path: "docker/atlas/migrations/*.sql"
user: root
password: root
- name: Go Test
uses: actions/codecov
inputs:
driver: go
commands:
- modules=`find . -name "go.mod" -exec dirname {} \;`
- echo $modules
- list=""
- coverpkg=""
- if [[ ! -f "go.work" ]];then go work init;fi
- for module in $modules; do go work use $module; list=$module"/... "$list; coverpkg=$module"/...,"$coverpkg; done
- go work sync
- go test -coverprofile=coverage.out -gcflags="all=-l -N" -coverpkg=$coverpkg $list
config:
status:
project:
opencoze:
minimum_coverage: 0%
paths:
- "!tests"
- "!examples/**"
- "!*/examples/**"
- "!*/mock/**"
- "!*/model/**"
diff:
eino:
line_limit: 10 # 增量行数少于多少行时,默认置成功
minimum_coverage: 0%
paths:
- "!tests"
- "!examples/**"
- "!*/examples/**"
- "!*/mock/**"
- "!*/model/**"
- name: Sonar
uses: actions/sonar@v1
inputs:
coverage_path: /tmp/coverage.out
coverage_type: go
disable_quality_gates: true
exclusions_list:
- "!tests"
- "examples/**"
- "*/mock/**"
- "*/model/**"
language: go
services:
- id: mysql
image: hub.byted.org/ee/mysql:8.0
envs:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: opencoze

View File

@ -0,0 +1,180 @@
name: CI@fe-master
trigger:
cron:
push:
branches: []
paths:
- "frontend/**"
types: [branch]
notification:
when: failure
# 搜索群名Bot Studio Monorepo CI 报警群
to: ['7350862409475031044']
manual:
notification:
when: failure
jobs:
lint: &base_job
runs-on:
env: online
name: Lint
image: hub.byted.org/base/bot_monorepo_ci_env:ae543e9bbc6d8155cffbd8f5ed27fb73
# 从最近的 CI 执行记录看install 步骤有概率会等待超时
# 目前已 oncall这里先设置一个超时时间避免阻塞
timeout: 30
envs:
RUSH_BUILD_CACHE_WRITE_ALLOWED: ${{RUSH_BUILD_CACHE_WRITE_ALLOWED}}
RUSH_BUILD_CACHE_ENABLED: ${{RUSH_BUILD_CACHE_ENABLED}}
RUSH_BUILD_CACHE_CREDENTIAL: ${{RUSH_BUILD_CACHE_CREDENTIAL}}
ACCESS_TOKEN: ${{CI_BOT_ACCESS_TOKEN}}
CI: 'true'
RUN_BYTEST_COV: 'false' # disable Jupiter default behavior of invoke bytestcov
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 'true'
CYPRESS_INSTALL_BINARY: '0'
TAIKO_SKIP_CHROMIUM_DOWNLOAD: '0'
RE2_DOWNLOAD_SKIP_PATH: '1'
RE2_DOWNLOAD_MIRROR: https://bnpm.bytedance.net/mirrors
# https://typescript-eslint.io/packages/parser/#allowautomaticsingleruninference
TSESTREE_SINGLE_RUN: 'true'
# 使用云盘缓存https://bytedance.larkoffice.com/wiki/A60lwgolSinteMkOz71cFPvFneg
# TODO:不同job的缓存key暂时使用同一个后续可以考虑区分
caches:
- backend: ebs
key: bot-studio-monorepo-master-v2-lint
size: 256
steps:
- &checkout_step
id: Checkout
uses: actions/checkout
inputs:
depth: 1
- &proxy_step
name: SetupProxy
commands:
- bash .codebase/scripts/env.sh
- &init_env_step
name: Initialization
commands:
- printenv
- git config user.name ci_flow
- git config user.email ci_flow@bytedance.com
- &install_deps_step
name: Install dependencies
commands:
- node common/scripts/install-run-rush.js install
# 暂时不启用因为eslintignore文件移除会导致解析报错后期接入可考虑动态读取eslint ignore配置
# - name: PreLint
# parallel-with-next-step: true
# commands:
# - npx oxlint@latest -A all .
- name: Lint
commands:
- NODE_OPTIONS="--max-old-space-size=4096" node common/scripts/install-run-rush.js lint
ts_check:
<<: *base_job
name: Check TS Type
timeout: 30
caches:
- backend: ebs
key: bot-studio-monorepo-master-v2-ts-check
size: 256
steps:
- *checkout_step
- *proxy_step
- *init_env_step
- *install_deps_step
- name: Check TS Type
commands:
- node common/scripts/install-run-rush.js ts-check -v
build:
<<: *base_job
name: Build
caches:
- backend: ebs
key: bot-studio-monorepo-master-v2-build
size: 256
steps:
- *checkout_step
- *proxy_step
- *init_env_step
- *install_deps_step
- name: Build
commands:
- CUSTOM_VERSION=release REGION=sg BUILD_BRANCH=test node common/scripts/install-run-rush.js build -v
test:
<<: *base_job
caches:
- backend: ebs
key: bot-studio-monorepo-master-v2-test
size: 256
name: Test
services:
# 下面启动一个mysql和mongo服务主要用于coze.hub.core相关服务的集成测试
# id需要保持跟代码中连接的host一致
- id: hub_mysql
image: hub.byted.org/ee/mysql:5.7
envs:
MYSQL_ROOT_PASSWORD: test
MYSQL_DATABASE: coze_hub
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_TCP_PORT: 3306
- id: hub_mongo
image: hub.byted.org/ee/mongo:4.0.24
commands:
- mongod --replSet rs0
- id: mongo-init
image: hub.byted.org/ee/mongo:4.0.24
commands:
- sleep 10s
- mongo mongodb://127.0.0.1:27017 --eval 'rs.initiate()'
steps:
- *checkout_step
- *proxy_step
- *init_env_step
- *install_deps_step
- name: wait mongo ready
uses: actions/mongodb-scripts
inputs:
host: 127.0.0.1
port: 27017
- name: wait mysql ready
uses: actions/mysql-scripts
inputs:
host: hub_mysql
user: test
password: test
commands:
- mysql -u test -ptest -h hub_mysql -P 3306 -e 'show databases;'
# 服务发现
- id: consul
uses: actions/setup-consul
- name: Test Coverage
id: test
commands:
- node common/scripts/install-run-rush.js test:cov -v
# https://bytedance.feishu.cn/wiki/wikcn9Z4azEdfJalVPKcOs9vxsR
security_scan:
<<: *base_job
name: Security Scan
caches:
- backend: ebs
key: bot-studio-monorepo-master-v2-scan
size: 256
steps:
- *checkout_step
- *proxy_step
- *init_env_step
- *install_deps_step
- name: build
commands:
- CUSTOM_VERSION=release REGION=sg node common/scripts/install-run-rush.js build -o app-botstudio-main -v
- id: Argus
commands:
- npm i @ies/argus-scan@0.30.37 -g
- bash .codebase/scripts/argus-scan.sh

View File

@ -0,0 +1,89 @@
name: CI@fe-tsc
trigger:
manual:
change:
# 临时支持 project-ide 项目需求,临时修改为如下格式
# 后续需调整回 integration/**
types: [create, push, restore]
paths:
- "frontend/**"
notification:
when: failure
jobs:
ts_check: &base_job
runs-on:
env: online
image: hub.byted.org/base/bot_monorepo_ci_env:ae543e9bbc6d8155cffbd8f5ed27fb73
# 从最近的 CI 执行记录看install 步骤有概率会等待超时
# 目前已 oncall这里先设置一个超时时间避免阻塞
timeout: 30
if: ${{ !Event.Change.IsPreSubmit }}
envs:
targetBranch: ${{Event.Change.Target.Branch}}
RUSH_BUILD_CACHE_WRITE_ALLOWED: ${{RUSH_BUILD_CACHE_WRITE_ALLOWED}}
RUSH_BUILD_CACHE_ENABLED: ${{RUSH_BUILD_CACHE_ENABLED}}
RUSH_BUILD_CACHE_CREDENTIAL: ${{RUSH_BUILD_CACHE_CREDENTIAL}}
ACCESS_TOKEN: ${{CI_BOT_ACCESS_TOKEN}}
CI: 'true'
RUN_BYTEST_COV: 'false'
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 'true'
CYPRESS_INSTALL_BINARY: '0'
TAIKO_SKIP_CHROMIUM_DOWNLOAD: '0'
RE2_DOWNLOAD_SKIP_PATH: '1'
RE2_DOWNLOAD_MIRROR: https://bnpm.bytedance.net/mirrors
MERGE_REQUEST_TITLE: ${{Event.Change.Title}}
TSESTREE_SINGLE_RUN: 'true'
steps:
- &checkout_step
name: Checkout
uses: actions/checkout
inputs:
submodules: true
depth: 1
- &proxy_step
name: SetupProxy
commands:
- bash .codebase/scripts/env.sh
- &remote_info_step
id: RemoteInfo
uses: 'actions/mr-remote-info'
inputs:
info_list: ['behind_commits', 'changed_files', 'changed_files_path']
- &cache_step
id: Cache
uses: actions/cache
inputs:
key: flow-monorepo-${{Event.Change.Source.Branch}}
paths:
- common/temp/pnpm-store
restore_keys:
- flow-monorepo-${{Event.Change.Source.Branch}}
- flow-monorepo-store-master
- &init_env_step
id: InitEnv
name: Initialization
commands:
- printenv
- git config user.name ci_flow
- git config user.email ci_flow@bytedance.com
- npm config set registry=https://registry.npmjs.org
- pnpm config set network-concurrency 32
- echo "$(<${{Steps.RemoteInfo.Outputs.changed_files_path}})"
- echo "::set-output name=ShouldRunBuild::${{ Event.Change.IsPreSubmit || int(Steps.RemoteInfo.Outputs.behind_commits) <= 6 }}"
- &install_deps_step
name: Install dependencies
commands:
- npx why-is-node-running@v2.x common/scripts/install-run-rush.js increment --action install -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}
- name: Prepare basic packages
commands:
- node common/scripts/install-run-rush.js pre-build -v
- name: Check TS Type
commands:
- node common/scripts/install-run-rush.js increment --action ts-check -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}

View File

@ -0,0 +1,184 @@
name: CI@fe
trigger:
manual:
change:
source-branches: ['!release/**', '!task/**']
types: [create, push, restore]
paths:
- "frontend/**"
notification:
when: failure
jobs:
lint: &base_job
runs-on:
env: online
image: hub.byted.org/base/bot_monorepo_ci_env:ae543e9bbc6d8155cffbd8f5ed27fb73
# 从最近的 CI 执行记录看install 步骤有概率会等待超时
# 目前已 oncall这里先设置一个超时时间避免阻塞
timeout: 30
if: ${{ !Event.Change.IsPreSubmit }}
envs:
targetBranch: ${{Event.Change.Target.Branch}}
RUSH_BUILD_CACHE_WRITE_ALLOWED: ${{RUSH_BUILD_CACHE_WRITE_ALLOWED}}
RUSH_BUILD_CACHE_ENABLED: ${{RUSH_BUILD_CACHE_ENABLED}}
RUSH_BUILD_CACHE_CREDENTIAL: ${{RUSH_BUILD_CACHE_CREDENTIAL}}
ACCESS_TOKEN: ${{CI_BOT_ACCESS_TOKEN}}
CI: 'true'
RUN_BYTEST_COV: 'false'
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 'true'
CYPRESS_INSTALL_BINARY: '0'
TAIKO_SKIP_CHROMIUM_DOWNLOAD: '0'
BUILD_BRANCH: ${{Event.Change.Source.Branch}}
RE2_DOWNLOAD_SKIP_PATH: '1'
MERGE_REQUEST_TITLE: ${{Event.Change.Title}}
TSESTREE_SINGLE_RUN: 'true'
caches:
- backend: ebs
key: bot-studio-monorepo-ci-v2-lint
size: 256
steps:
- &checkout_step
name: Checkout
uses: actions/checkout
inputs:
submodules: true
depth: 1
- &proxy_step
name: SetupProxy
commands:
- bash .codebase/scripts/env.sh
- &remote_info_step
id: RemoteInfo
uses: 'actions/mr-remote-info'
inputs:
info_list: ['behind_commits', 'changed_files', 'changed_files_path']
- &cache_step
id: Cache
uses: actions/cache
inputs:
key: flow-monorepo-${{Event.Change.Source.Branch}}
paths:
- common/temp/pnpm-store
- packages/arch/idl/src/auto-generated
restore_keys:
- flow-monorepo-${{Event.Change.Source.Branch}}
- flow-monorepo-store-master
- &init_env_step
id: InitEnv
name: Initialization
commands:
- printenv
- git config user.name ci_flow
- git config user.email ci_flow@bytedance.com
- npm config set registry=https://registry.npmjs.org
- pnpm config set network-concurrency 32
- echo "$(<${{Steps.RemoteInfo.Outputs.changed_files_path}})"
- echo "::set-output name=ShouldRunBuild::${{ Event.Change.IsPreSubmit || int(Steps.RemoteInfo.Outputs.behind_commits) <= 6 }}"
- &install_deps_step
name: Install dependencies
commands:
- npx why-is-node-running@v2.x common/scripts/install-run-rush.js increment --action install -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}
- name: Check Lint
commands:
- node common/scripts/install-run-rush.js increment --action lint -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}
style_check:
<<: *base_job
caches:
- backend: ebs
key: bot-studio-monorepo-ci-v2-style-check
size: 256
name: Check Stylelint
steps:
- *checkout_step
- *proxy_step
- *remote_info_step
- *cache_step
- *init_env_step
- *install_deps_step
- name: Check Stylelint
commands:
- node common/scripts/install-run-rush.js increment --action style -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}
build:
<<: *base_job
caches:
- backend: ebs
key: bot-studio-monorepo-ci-v2-build
size: 256
name: Build
timeout: 20
steps:
- *checkout_step
- *proxy_step
- *remote_info_step
- *cache_step
- *init_env_step
- *install_deps_step
- name: Build
id: build
if: ${{ Steps.InitEnv.Outputs.ShouldRunBuild }}
commands:
- node common/scripts/install-run-rush.js increment --action build -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}
test:
<<: *base_job
caches:
- backend: ebs
key: bot-studio-monorepo-ci-v2-test
size: 256
name: Test Coverage
services:
# 下面启动一个mysql和mongo服务主要用于coze.hub.core相关服务的集成测试
# id需要保持跟代码中连接的host一致
- id: hub_mysql
image: hub.byted.org/ee/mysql:5.7
envs:
MYSQL_ROOT_PASSWORD: test
MYSQL_DATABASE: coze_hub
MYSQL_USER: test
MYSQL_PASSWORD: test
MYSQL_TCP_PORT: 3306
- id: hub_mongo
image: hub.byted.org/ee/mongo:4.0.24
commands:
- mongod --replSet rs0
- id: mongo-init
image: hub.byted.org/ee/mongo:4.0.24
commands:
- sleep 10s
- mongo mongodb://127.0.0.1:27017 --eval 'rs.initiate()'
steps:
- *checkout_step
- *proxy_step
- *remote_info_step
- *cache_step
- *init_env_step
- *install_deps_step
- name: wait mongo ready
uses: actions/mongodb-scripts
inputs:
host: 127.0.0.1
port: 27017
- name: wait mysql ready
uses: actions/mysql-scripts
inputs:
host: hub_mysql
user: test
password: test
commands:
- mysql -u test -ptest -h hub_mysql -P 3306 -e 'show databases;'
# 服务发现
- id: consul
uses: actions/setup-consul
- name: Test Coverage
commands:
- git fetch --filter=blob:none --unshallow -q
- node common/scripts/install-run-rush.js increment --action test:cov -p ${{Steps.RemoteInfo.Outputs.changed_files_path}}

View File

@ -0,0 +1,14 @@
#!/bin/bash
set -ex
# 暂时只扫描 app-botstudio-main 项目的产物
result=$(argus scm -c apps/bot/dist_sg/static -n obric/cloud/bot_studio_oversea -l)
if echo "$result" | grep -q '::add-message level=error:::'; then
if [ "$CI" ]; then
echo '::add-message level=info::本地验证命令:`npm install -g @ies/argus-scan@0.30.37 && REGION=sg CUSTOM_VERSION=release rush build -o app-botstudio-main && argus scm -c apps/bot/dist_sg/static -n obric/cloud/bot_studio_oversea -l`'
fi
exit 1
else
exit 0
fi

View File

@ -0,0 +1,94 @@
#!/bin/bash
# 设置默认值
TARGET_BRANCH=${targetBranch}
CI_MODE=${CI:-false}
# Specify the pattern you want to exclude, using *space* as the separator
EXCLUDE_PATTERNS=(
'**/pnpm-lock.yaml'
'packages/arch/bot-api/src/auto-generate/**'
'apps/bot-op/src/services/bam-auto-generate/**'
'apps/prompt-platform/src/services/auto-generate/**'
".cursor/api/**"
"**/lib/**"
"**/.*/**"
'**/__tests__/**'
'**/__test__/**'
"**/__mocks__/**"
"**/__mock__/**"
"**/*.test.*/**"
"**/*.spec.*/**"
"**/__snapshots__/**"
"**/*.snap"
'**/e2e/**'
'common/changes/**'
'apps/fornax/**',
"packages/arch/semi-theme-hand01",
"packages/arch/arco-icon",
"packages/arch/resources/**"
)
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
EXCLUDE_STRING+=":(exclude)$pattern "
done
if [ "$CI_MODE" = true ]; then
files=$(git diff --name-only --diff-filter=AM "origin/$TARGET_BRANCH..." $EXCLUDE_STRING)
else
files=$(git diff --name-only --diff-filter=AM --cached $EXCLUDE_STRING)
fi
# 体积限制为512KB
size_limit=$((512))
large_files_info=""
IFS=$'\n' # 处理文件名存在空格情况
for file in $files; do
file_size=$(wc -c <"$file" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "错误: 无法获取文件 '$file' 的大小"
continue
fi
file_size_kb=$((file_size / 1024))
echo "$file file size is $file_size_kb KB"
if [ "$file_size_kb" -gt "$size_limit" ]; then
large_files_info+="- \`$file\` ($file_size_kb KB)\n"
fi
done
unset IFS
output_conclusion() {
local conclusion="$1"
echo "$conclusion" >check-file-size.log
echo "::update-check-run::check-file-size.log"
}
if [ -n "$large_files_info" ]; then
if [ "$CI_MODE" = true ]; then
CONCLUSION="{
\"name\": \"文件体积\",
\"conclusion\": \"failed\",
\"output\": {
\"summary\": \"<h1>错误: 文件体积过大</h1> <br /> 以下文件体积超过限制 (${size_limit}KB): \\n \\n $large_files_info \\n \\n <br /> 你可以将资源上传到CDN并通过URL使用。详情请参考此[文档](https://bytedance.larkoffice.com/wiki/MjoIwfyGyiVCBFkBgnXc8LFTniX)。<br /> 如遇紧急情况,可以联系 [@fanwenjie.fe](https://code.byted.org/fanwenjie.fe) 跳过此错误。\"
}
}"
output_conclusion "$CONCLUSION"
else
echo "错误: 以下文件体积超过限制 (${size_limit}KB):"
echo -e "$large_files_info"
echo "请将大文件上传到CDN并通过URL使用。详情请参考: https://bytedance.larkoffice.com/wiki/MjoIwfyGyiVCBFkBgnXc8LFTniX"
exit 1
fi
else
if [ "$CI_MODE" = true ]; then
CONCLUSION="{
\"name\": \"文件体积\",
\"conclusion\": \"success\",
\"output\": {
\"summary\": \"GOOD\"
}
}"
output_conclusion "$CONCLUSION"
fi
fi

View File

@ -0,0 +1,16 @@
#!/bin/bash
set -ex
SOURCE_BRANCH=${SOURCE_BRANCH}
TARGET_BRANCH=${targetBranch}
if [[ $TARGET_BRANCH == "master" && !($SOURCE_BRANCH =~ ^release/ || $SOURCE_BRANCH =~ ^hotfix/ || $SOURCE_BRANCH =~ ^task/ || $SOURCE_BRANCH =~ ^fix/) ]]; then
# 检查$SOURCE_BRANCH是否以'release/'或'hotfix/'或'task/'或'fix/'开头
LATEST_BRANCH="release/$(date -d '+8 hour' +%Y%m%d)"
CONCLUSION="{\"name\": \"Target Branch\", \"conclusion\": \"failed\", \"output\":{\"summary\":\"Error: Please don't merge to master directly, use [$LATEST_BRANCH](https://code.byted.org/obric/bot-studio-monorepo/commits/$LATEST_BRANCH) instead.\n You can contact [@fanwenjie.fe](https://code.byted.org/fanwenjie.fe) to skip this error.\" }}"
else
CONCLUSION="{\"name\": \"Target Branch\", \"conclusion\": \"success\", \"output\":{\"summary\":\"Good Pratice\" }}"
fi
echo $CONCLUSION >>check-merge-target.log
echo "::update-check-run::check-merge-target.log"

View File

@ -0,0 +1,55 @@
#!/bin/bash
set -ex
# Your target branch
TARGET_BRANCH=$targetBranch
if [[ ${SOURCE_BRANCH} =~ ^integration/ || ${SOURCE_BRANCH} =~ ^release/ ]]; then
# integration -> xxx or release/xxx -> master SKIP check-mr-size.
echo "::add-message level=info::SKIP check-mr-size"
exit 0
fi
# Specify the pattern you want to exclude, using *space* as the separator
EXCLUDE_PATTERNS=(
'**/pnpm-lock.yaml'
'packages/arch/bot-api/src/auto-generate/**'
'apps/bot-op/src/services/bam-auto-generate/**'
'apps/prompt-platform/src/services/auto-generate/**'
"**/lib/**"
"**/.*/**"
'**/__tests__/**'
'**/__test__/**'
"**/__mocks__/**"
"**/__mock__/**"
"**/*.test.*/**"
"**/*.spec.*/**"
"**/__snapshots__/**"
"**/*.snap"
'**/*.svg'
'ee/e2e/bot-studio/**'
'common/changes/**'
'apps/fornax/**'
"apps/api-builder/**"
"packages/api-builder/**"
)
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
EXCLUDE_STRING+=":(exclude)$pattern "
done
# Count the number of files changed but exclude certain files and folders
file_changes=$(git diff --name-only "origin/$TARGET_BRANCH..." $EXCLUDE_STRING | wc -l)
# Count the number of line changes but exclude certain files and folders
line_changes=$(git diff --shortstat "origin/$TARGET_BRANCH..." $EXCLUDE_STRING | awk '{print ($4>$6)?$4:$6}')
# Check if number of changed files is greater than 100 or if number of line changes is greater than 2000
if [ "$file_changes" -gt 100 ] || [ "$line_changes" -gt 2000 ]; then
CONCLUSION="{\"name\": \"MR Size\", \"conclusion\": \"failed\", \"output\":{\"summary\":\"Error: Too many changes. Number of changed files is **""$file_changes""**, number of changed lines is **""$line_changes""**.\n You can contact [@fanwenjie.fe](https://code.byted.org/fanwenjie.fe) to skip this error.\" }}"
else
CONCLUSION="{\"name\": \"MR Size\", \"conclusion\": \"success\", \"output\":{\"summary\":\"Good\" }}"
fi
echo $CONCLUSION >>check-mr-size.log
echo "::update-check-run::check-mr-size.log"

View File

@ -0,0 +1,14 @@
#!/bin/bash
set -ex
PRE_COMMITS=$1
# 按 codebase 给出的口径pre commits 超过 5 时容易导致 rebase 失败,因此主动给出警告,避免进入 CQ 后被弹出
if [ $PRE_COMMITS -gt 5 ]; then
CONCLUSION="{\"name\": \"Pre Commits Check\", \"conclusion\": \"failed\", \"output\":{\"summary\":\"分支已落后目标分支较多,非常容易导致进入 CQ 后被弹出,请执行 rebase/merge 同步代码后重试。\" }}"
else
CONCLUSION="{\"name\": \"Pre Commits Check\", \"conclusion\": \"success\", \"output\":{\"summary\":\"good\" }}"
fi
echo $CONCLUSION >> check-pre-commits.log
echo "::update-check-run::check-pre-commits.log"

View File

@ -0,0 +1,54 @@
#!/bin/bash
set -ex
basename=$(basename "$CHANGE_URL")
lastParam=$(echo "$basename" | cut -d'/' -f1)
targetBranch="${targetBranch}"
sourceBranch="${SOURCE_BRANCH}"
mrTitle="${MR_TITLE}"
mrDescription="${MR_DESCRIPTION}"
echo "::set-output name=mrId::$lastParam" # 输出 lastParam 的值
result=$(curl --location "https://code.byted.org/api/v4/projects/548801/merge_requests/$lastParam" \
--header "Private-Token: $GITLAB_TOKEN")
commits=$(curl --location "https://code.byted.org/api/v4/projects/548801/merge_requests/$lastParam/commits" \
--header "Private-Token: $GITLAB_TOKEN")
isSquash=$(echo "$result" | jq -r '.squash') # 使用jq提取isSquash的值
commitsCount=$(echo "$commits" | jq length)
echo "::set-output name=squash::$isSquash" # 输出 isSquash 的值
echo "::set-output name=commitsCount::$commitsCount" # 输出 commitsCount 的值
if [[ $isSquash == true ]]; then
# 勾选squash
if [[ $sourceBranch == release/* && $targetBranch == master ]]; then
echo "::add-message level=error::**release 分支合入 master 时,不可开启 squash **"
exit 1
fi
if [[ $mrDescription == \[no-squash\]* ]]; then
echo "::add-message level=error::**当前 MR 勾选了 Squash 选项,但是描述中包含[no-squash]**"
exit 1
fi
else
# 没有勾选squash
if [[ $mrDescription == \[no-squash\]* ||
$commitsCount -le 1 ||
$mrTitle == WIP:* ||
$mrTitle == wip:* ||
$sourceBranch == release/* ]]; then
exit 0
fi
echo "::add-message level=error::**当前 MR 应该勾选 Squash 选项**"
exit 1
fi

View File

@ -0,0 +1,53 @@
const fs = require('fs/promises');
const path = require('path');
const crypto = require('crypto');
// node scripts/checksum-by-change.js /usr/changed-path.json
// change-path 文件来自 ci
const changedPath = process.argv[2];
const readJson = async jsonFile => {
const content = await fs.readFile(jsonFile, 'utf-8');
let _val = null;
try {
eval(`_val = ${content}`);
return _val;
} catch (e) {
console.error(`json parse failure: `, e);
}
};
const readChangedPackages = async changedPath => {
const [changedFiles, { projects }] = await Promise.all([
readJson(changedPath),
readJson(path.resolve(__dirname, '../../rush.json')),
]);
const changedProjects = projects
.filter(project => {
const { projectFolder } = project;
const endsWithSlash = projectFolder.endsWith('/');
const compareFolder = `${projectFolder}${endsWithSlash ? '' : '/'}`;
if (!changedFiles) {
// changed-path.json 内容可能为null
return true;
}
const matched = changedFiles.find(file => file.startsWith(compareFolder));
return !!matched;
})
.map(({ packageName }) => packageName)
.sort((r1, r2) => r1.localeCompare(r2));
return changedProjects;
};
async function main() {
if (!changedPath || changedPath.length <= 0) {
throw new Error(`Please pass the correct "changedPath" path`);
}
const changedPackages = await readChangedPackages(changedPath);
const hash = crypto.createHash('md5');
changedPackages.forEach(r => hash.update(r));
const hashValue = hash.digest('hex');
console.log(`::set-output name=hash::${hashValue}`);
}
main();

26
.codebase/scripts/env.sh Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bash
echo ::set-env name=no_proxy::cn.goofy.app,.cn.goofy.app,goofy.app,.goofy.app,localhost,.byted.org,byted.org,.bytedance.net,bytedance.net,127.0.0.1,127.0.0.0/8,169.254.0.0/16,100.64.0.0/10,172.16.0.0/12,192.168.0.0/16,10.0.0.0/8,::1,fe80::/10,fd00::/8
echo ::set-env name=all_proxy::http://sys-proxy-rd-relay.byted.org:3128
echo ::set-env name=http_proxy::http://sys-proxy-rd-relay.byted.org:3128
echo ::set-env name=https_proxy::http://sys-proxy-rd-relay.byted.org:3128
#!/usr/bin/env bash
# Setup common env for CI & SCM
# 1. 忽略不影响构建的 install
export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=true
export CYPRESS_INSTALL_BINARY=0
export TAIKO_SKIP_CHROMIUM_DOWNLOAD=0
export CUSTOM_VERSION="inhouse"
export RE2_DOWNLOAD_SKIP_PATH=1
export RE2_DOWNLOAD_MIRROR="https://bnpm.bytedance.net/mirrors"
export PUPPETEER_SKIP_DOWNLOAD=true
# 2. 在 CI 环境生效:
echo ::set-env name=PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD::$PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD
echo ::set-env name=CYPRESS_INSTALL_BINARY::$CYPRESS_INSTALL_BINARY
echo ::set-env name=TAIKO_SKIP_CHROMIUM_DOWNLOAD::$TAIKO_SKIP_CHROMIUM_DOWNLOAD
echo ::set-env name=RE2_DOWNLOAD_SKIP_PATH::$RE2_DOWNLOAD_SKIP_PATH
echo ::set-env name=RE2_DOWNLOAD_MIRROR::$RE2_DOWNLOAD_MIRROR
echo ::set-env name=PUPPETEER_SKIP_DOWNLOAD::$PUPPETEER_SKIP_DOWNLOAD

16
.gitattributes vendored Normal file
View File

@ -0,0 +1,16 @@
# Don't allow people to merge changes to these generated files, because the result
# may be invalid. You need to run "rush update" again.
pnpm-lock.yaml merge=ours
shrinkwrap.yaml merge=binary
npm-shrinkwrap.json merge=binary
yarn.lock merge=binary
# 不做自动解决冲突,暴露冲突后由开发者自行 rush pull-idl 做更新
# packages/arch/idl/bam.log.json merge=ours
# Rush's JSON config files use JavaScript-style code comments. The rule below prevents pedantic
# syntax highlighters such as GitHub's from highlighting these comments as errors. Your text editor
# may also require a special configuration to allow comments in JSON.
#
# For more information, see this issue: https://github.com/microsoft/rushstack/issues/1088
#
*.json linguist-language=JSON-with-Comments

268
.github/CODEOWNERS vendored Normal file
View File

@ -0,0 +1,268 @@
* Tecvan-fe
/apps/coze-studio/ @Tecvan-fe @evan-crash @duwenhan2byte
/packages/agent-ide/agent-publish/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei @catee
/packages/agent-ide/commons/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/arch/bot-api/ @Tecvan-fe
/packages/arch/bot-http/ @Tecvan-fe
/packages/arch/logger/ @Tecvan-fe
/packages/arch/slardar-interface/ @Tecvan-fe @evan-crash
/config/eslint-config/ @Tecvan-fe @leeight @soonco
/infra/eslint-plugin/ @Tecvan-fe
/config/ts-config/ @leeight @Tecvan-fe
/config/vitest-config/ @Tecvan-fe
/packages/arch/bot-env/ @Tecvan-fe @leeight
/packages/arch/bot-env-adapter/ @dragooncjw @Tecvan-fe @leeight
/packages/arch/bot-typings/ @Tecvan-fe
/packages/arch/web-context/ @Tecvan-fe
/packages/components/bot-semi/ @Tecvan-fe
/packages/components/bot-icons/ @DingGao-Devin
/packages/arch/i18n/ @Tecvan-fe @leeight
/packages/arch/resources/studio-i18n-resource/ @dragooncjw @Tecvan-fe
/config/stylelint-config/ @Tecvan-fe
/packages/arch/idl/ @Tecvan-fe
/infra/utils/fs-enhance/ @Tecvan-fe
/packages/arch/bot-store/ @Tecvan-fe @catee @duwenhan2byte
/packages/arch/bot-error/ @haozhenfei @duwenhan2byte
/packages/foundation/space-store/ @evan-crash @duwenhan2byte
/packages/arch/bot-flags/ @Tecvan-fe
/packages/arch/report-events/ @Tecvan-fe
/packages/foundation/enterprise-store-adapter/ @evan-crash @duwenhan2byte
/packages/foundation/local-storage/ @duwenhan2byte @evan-crash
/packages/foundation/space-store-adapter/ @evan-crash @duwenhan2byte
/packages/arch/bot-tea/ @Tecvan-fe @catee @soonco
/packages/arch/tea/ @Tecvan-fe @evan-crash @soonco
/packages/arch/tea-adapter/ @dragooncjw @Tecvan-fe
/packages/arch/tea-interface/ @dragooncjw @Tecvan-fe
/packages/studio/stores/bot-detail/ @Hezi-crypto @catee @DingGao-Devin @duwenhan2byte @evan-crash
/packages/agent-ide/bot-input-length-limit/ @Hezi-crypto @catee @duwenhan2byte
/packages/agent-ide/tool-config/ @haozhenfei @catee
/packages/arch/bot-space-api/ @Tecvan-fe @duwenhan2byte
/packages/arch/bot-utils/ @Tecvan-fe
/packages/common/uploader-adapter/ @dragooncjw @Tecvan-fe
/packages/common/uploader-interface/ @dragooncjw @Tecvan-fe
/packages/studio/user-store/ @duwenhan2byte @catee @lihuiwen
/packages/arch/foundation-sdk/ @evan-crash @duwenhan2byte
/packages/common/chat-area/chat-core/ @haozhenfei @Hezi-crypto @evan-crash
/packages/common/chat-area/utils/ @Hezi-crypto @haozhenfei
/packages/arch/bot-md-box-adapter/ @Hezi-crypto @iu1340 @dragooncjw @Tecvan-fe
/packages/studio/common/file-kit/ @haozhenfei @evan-crash
/packages/arch/slardar-adapter/ @Tecvan-fe @dragooncjw
/packages/arch/default-slardar/ @Tecvan-fe @evan-crash
/packages/arch/fetch-stream/ @Hezi-crypto @haozhenfei
/packages/common/websocket-manager-adapter/ @haozhenfei @Hezi-crypto @catee
/packages/studio/autosave/ @catee
/packages/studio/bot-utils/ @catee @soonco @Hezi-crypto
/packages/common/flowgram-adapter/common/ @zxhfighter @xiamidaxia @dragooncjw
/packages/common/flowgram-adapter/free-layout-editor/ @zxhfighter @xiamidaxia @dragooncjw
/packages/agent-ide/space-bot/ @soonco @evan-crash @duwenhan2byte @catee @DingGao-Devin
/packages/agent-ide/space-bot/src/store/bot-list-filter/ @duwenhan2byte @lihuiwen
/packages/agent-ide/space-bot/src/store/bot-page/ @DingGao-Devin
/packages/agent-ide/space-bot/src/store/explore/ @Tecvan-fe
/packages/agent-ide/space-bot/src/store/risk-warning/ @lihuiwen @catee
/packages/agent-ide/context/ @evan-crash
/packages/agent-ide/bot-editor-context-store/ @Hezi-crypto @duwenhan2byte @catee
/packages/agent-ide/chat-background/ @catee
/packages/agent-ide/chat-background-config-content-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/chat-background-config-content/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/chat-background-shared/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/common/chat-area/chat-uikit/ @catee @Hezi-crypto @evan-crash @haozhenfei
/packages/common/chat-area/hooks/ @Hezi-crypto @evan-crash
/packages/common/chat-area/chat-uikit-shared/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/bot-audit-adapter/ @evan-crash @duwenhan2byte @Hezi-crypto @haozhenfei
/packages/agent-ide/bot-audit-base/ @evan-crash @duwenhan2byte @Hezi-crypto @haozhenfei
/packages/studio/components/ @soonco @evan-crash @duwenhan2byte @catee
/packages/arch/bot-hooks/ @catee @Tecvan-fe @soonco
/packages/arch/bot-hooks/src/page-jump/ @evan-crash @catee
/packages/arch/bot-hooks-adapter/ @catee @Tecvan-fe @soonco
/packages/arch/bot-hooks-base/ @catee @Tecvan-fe @soonco
/packages/arch/responsive-kit/ @Tecvan-fe @DingGao-Devin
/packages/common/chat-area/chat-area/ @Hezi-crypto @haozhenfei @evan-crash @haozhenfei
/packages/data/memory/llm-plugins/ @haozhenfei @catee @Hezi-crypto
/packages/data/common/reporter/ @soonco @catee @evan-crash
/packages/components/json-viewer/ @duwenhan2byte
/packages/components/scroll-view/ @evan-crash
/packages/common/assets/ @Tecvan-fe @catee
/packages/common/biz-components/ @duwenhan2byte
/packages/data/common/e2e/ @soonco @catee @evan-crash @haozhenfei @duwenhan2byte
/packages/agent-ide/debug-tool-list/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/model-manager/ @Hezi-crypto @catee
/packages/agent-ide/model-manager/src/components/multi-agent/ @catee
/packages/agent-ide/tool/ @catee
/packages/data/knowledge/knowledge-modal-base/ @haozhenfei @catee @Hezi-crypto
/packages/components/biz-tooltip-ui/ @Hezi-crypto @catee @evan-crash
/packages/components/table-view/ @lihuiwen
/packages/components/virtual-list/ @Tecvan-fe
/packages/data/common/utils/ @soonco @catee @evan-crash
/packages/data/knowledge/knowledge-resource-processor-core/ @haozhenfei @catee @Hezi-crypto
/packages/arch/pdfjs-shadow/ @Tecvan-fe
/packages/data/knowledge/common/stores/ @soonco @catee @evan-crash
/packages/foundation/global-store/ @duwenhan2byte @evan-crash
/config/postcss-config/ @Tecvan-fe
/config/tailwind-config/ @Tecvan-fe
/infra/utils/monorepo-kits/ @Tecvan-fe @evan-crash
/packages/studio/premium/premium-components-adapter/ @evan-crash
/packages/studio/premium/premium-store-adapter/ @evan-crash
/packages/agent-ide/onboarding/ @Hezi-crypto @catee
/packages/agent-ide/publish-to-base/ @catee
/packages/arch/report-tti/ @duwenhan2byte
/packages/data/memory/database-creator/ @haozhenfei @catee @Hezi-crypto
/packages/arch/hooks/ @Tecvan-fe @evan-crash
/packages/common/coze-mitt/ @evan-crash @duwenhan2byte
/packages/common/editor-plugins/ @haozhenfei @stream-pipe @Hezi-crypto
/packages/common/md-editor-adapter/ @haozhenfei @Hezi-crypto @catee
/packages/common/prompt-kit/main/ @haozhenfei @Hezi-crypto @catee
/packages/common/chat-area/chat-answer-action/ @Hezi-crypto @haozhenfei @lihuiwen
/packages/common/chat-area/plugin-message-grab/ @Hezi-crypto @haozhenfei
/packages/common/chat-area/text-grab/ @Hezi-crypto @haozhenfei
/packages/common/prompt-kit/adapter/ @haozhenfei @Hezi-crypto @catee
/packages/common/prompt-kit/base/ @haozhenfei @Hezi-crypto @catee
/packages/data/memory/database/ @haozhenfei @catee @Hezi-crypto
/packages/data/knowledge/knowledge-resource-processor-base/ @haozhenfei @catee @Hezi-crypto
/packages/arch/utils/ @Tecvan-fe @evan-crash
/packages/data/knowledge/common/components/ @haozhenfei @catee @Hezi-crypto
/packages/data/common/feature-register/ @haozhenfei @catee @Hezi-crypto
/packages/data/knowledge/common/hooks/ @Hezi-crypto @catee @evan-crash
/packages/data/knowledge/common/services/ @Hezi-crypto @catee @evan-crash
/packages/data/memory/database-v2-main/ @haozhenfei @catee @Hezi-crypto
/packages/data/memory/database-v2-adapter/ @haozhenfei @catee @Hezi-crypto
/packages/data/memory/database-v2-base/ @haozhenfei @catee @Hezi-crypto
/packages/data/knowledge/knowledge-data-set-for-agent/ @Hezi-crypto @catee @evan-crash
/packages/data/knowledge/knowledge-ide-base/ @haozhenfei @catee @Hezi-crypto
/packages/arch/bot-monaco-editor/ @Tecvan-fe
/packages/data/knowledge/knowledge-modal-adapter/ @haozhenfei @catee @Hezi-crypto
/packages/data/knowledge/knowledge-resource-processor-adapter/ @haozhenfei @catee @Hezi-crypto
/packages/devops/debug/debug-panel/ @soonco @evan-crash @catee
/packages/devops/json-link-preview/ @Maidang1 @Zhangchi123456
/packages/devops/common-modules/ @duwenhan2byte @evan-crash @catee
/packages/foundation/account-adapter/ @duwenhan2byte @evan-crash
/packages/foundation/account-base/ @evan-crash @duwenhan2byte
/packages/arch/api-schema/ @Tecvan-fe @evan-crash
/infra/idl/idl2ts-runtime/ @Tecvan-fe @evan-crash
/infra/idl/idl2ts-cli/ @Tecvan-fe @evan-crash
/infra/idl/idl2ts-generator/ @Tecvan-fe @evan-crash
/infra/idl/idl-parser/ @Tecvan-fe @evan-crash
/infra/utils/rush-logger/ @catee @Tecvan-fe
/infra/idl/idl2ts-helper/ @Tecvan-fe @evan-crash
/infra/idl/idl2ts-plugin/ @Tecvan-fe @evan-crash
/packages/studio/open-platform/open-env-adapter/ @soonco @Hezi-crypto @DingGao-Devin
/infra/plugins/pkg-root-webpack-plugin/ @Tecvan-fe
/packages/studio/publish-manage-hooks/ @duwenhan2byte @evan-crash
/packages/foundation/layout/ @evan-crash @duwenhan2byte
/packages/studio/open-platform/open-auth/ @evan-crash @DingGao-Devin
/packages/agent-ide/entry-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/entry/ @soonco @duwenhan2byte @catee @evan-crash
/packages/agent-ide/bot-config-area-adapter/ @haozhenfei @Hezi-crypto @duwenhan2byte @catee @evan-crash
/packages/agent-ide/bot-config-area/ @haozhenfei @Hezi-crypto @duwenhan2byte @catee @evan-crash
/packages/agent-ide/bot-plugin/entry/ @evan-crash @lihuiwen @catee
/packages/agent-ide/bot-plugin/export/ @lihuiwen @catee
/packages/agent-ide/bot-plugin/mock-set/ @lihuiwen @catee @duwenhan2byte
/packages/studio/mockset-edit-modal-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/studio/mockset-shared/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/studio/mockset-editor/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/studio/mockset-editor-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/bot-plugin/tools/ @lihuiwen @catee
/packages/studio/stores/bot-plugin/ @lihuiwen @Hezi-crypto @catee
/packages/studio/plugin-shared/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/plugin-modal-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/plugin-shared/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/community/component/ @DingGao-Devin @Hezi-crypto @evan-crash @duwenhan2byte
/packages/studio/plugin-form-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/workflow/base/ @xiamidaxia @zxhfighter
/packages/agent-ide/plugin-content-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/plugin-content/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/plugin-setting-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/plugin-setting/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/bot-plugin/plugin-risk-warning/ @catee @evan-crash
/packages/studio/plugin-publish-ui-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/studio/plugin-tool-columns-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/studio/plugin-tool-columns/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/chat-debug-area/ @soonco @duwenhan2byte @catee @Hezi-crypto @haozhenfei @evan-crash
/packages/agent-ide/chat-answer-action-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/chat-area-plugin-debug-common/ @Hezi-crypto @haozhenfei
/packages/agent-ide/chat-components-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/common/chat-area/plugin-chat-background/ @Tecvan-fe
/packages/common/chat-area/chat-area-plugin-reasoning/ @catee @Hezi-crypto
/packages/common/chat-area/plugin-resume/ @Tecvan-fe
/packages/common/chat-area/plugin-chat-shortcuts/ @haozhenfei @duwenhan2byte @Hezi-crypto
/packages/workflow/sdk/ @zxhfighter @xiamidaxia
/packages/workflow/components/ @LLLLeeJ @zxhfighter
/packages/components/loading-button/ @catee
/packages/components/mouse-pad-selector/ @zxhfighter
/packages/workflow/adapter/resources/ @LLLLeeJ @JxJuly @xiamidaxia @luics @zxhfighter @stream-pipe
/packages/common/chat-area/chat-workflow-render/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/onboarding-message-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/plugin-area-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/prompt-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/prompt/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/workflow/ @soonco @duwenhan2byte @catee
/packages/agent-ide/navigate/ @soonco @duwenhan2byte @catee
/packages/agent-ide/workflow-as-agent-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/workflow-item/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/workflow-card-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/workflow-modal/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/memory-tool-pane-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/skills-pane-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/layout-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/layout/ @soonco @duwenhan2byte @catee
/packages/agent-ide/chat-area-provider-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/agent-ide/chat-area-provider/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/studio/entity-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/foundation/account-ui-adapter/ @duwenhan2byte @evan-crash
/packages/foundation/account-ui-base/ @evan-crash @duwenhan2byte
/packages/foundation/foundation-sdk/ @evan-crash @duwenhan2byte
/packages/foundation/global/ @evan-crash @duwenhan2byte
/packages/studio/workspace/project-entity-adapter/ @Hezi-crypto @catee @duwenhan2byte
/packages/studio/workspace/project-entity-base/ @Hezi-crypto @catee @duwenhan2byte
/packages/foundation/global-adapter/ @evan-crash @duwenhan2byte
/packages/foundation/browser-upgrade-banner/ @evan-crash @duwenhan2byte
/packages/foundation/space-ui-adapter/ @evan-crash @duwenhan2byte
/packages/foundation/space-ui-base/ @evan-crash @duwenhan2byte
/packages/common/auth/ @evan-crash @duwenhan2byte
/packages/common/auth-adapter/ @evan-crash @duwenhan2byte
/packages/project-ide/main/ @dragooncjw @JxJuly @xiamidaxia @catee @lihuiwen
/packages/components/resource-tree/ @dragooncjw @xiamidaxia @JxJuly
/packages/common/flowgram-adapter/fixed-layout-editor/ @zxhfighter @xiamidaxia @dragooncjw
/packages/project-ide/biz-components/ @zxhfighter @xiamidaxia
/packages/project-ide/framework/ @dragooncjw @JxJuly @xiamidaxia
/packages/project-ide/base-adapter/ @dragooncjw @xiamidaxia
/packages/project-ide/base-interface/ @dragooncjw @xiamidaxia
/packages/project-ide/client/ @dragooncjw @JxJuly @xiamidaxia
/packages/project-ide/core/ @dragooncjw @JxJuly @xiamidaxia
/packages/project-ide/view/ @dragooncjw @JxJuly @xiamidaxia
/packages/project-ide/biz-data/ @haozhenfei @lihuiwen @catee @soonco
/packages/data/knowledge/knowledge-ide-adapter/ @haozhenfei @catee @Hezi-crypto
/packages/data/memory/variables/ @haozhenfei @catee @Hezi-crypto
/packages/project-ide/biz-plugin/ @xiamidaxia @lihuiwen @catee
/packages/project-ide/biz-plugin-registry-adapter/ @Hezi-crypto @duwenhan2byte @catee @evan-crash @haozhenfei
/packages/project-ide/biz-workflow/ @dragooncjw @JxJuly @xiamidaxia
/packages/studio/open-platform/open-chat/ @soonco @Hezi-crypto @DingGao-Devin
/packages/workflow/playground/ @LLLLeeJ @xiamidaxia @luics @zxhfighter
/packages/arch/load-remote-worker/ @Tecvan-fe
/packages/devops/mockset-manage/ @soonco @evan-crash @catee
/packages/devops/testset-manage/ @mocayo @JxJuly
/packages/workflow/adapter/base/ @LLLLeeJ @JxJuly @xiamidaxia @luics @zxhfighter @stream-pipe
/packages/workflow/adapter/code-editor/ @LLLLeeJ @JxJuly @xiamidaxia @luics @zxhfighter @stream-pipe
/packages/workflow/fabric-canvas/ @xiamidaxia @zxhfighter
/packages/workflow/feature-encapsulate/ @zxhfighter
/packages/workflow/nodes/ @xiamidaxia @zxhfighter
/packages/workflow/setters/ @Tecvan-fe
/packages/workflow/variable/ @zxhfighter @LLLLeeJ @xiamidaxia
/packages/workflow/render/ @dragooncjw @xiamidaxia
/packages/workflow/history/ @xiamidaxia @zxhfighter
/packages/workflow/adapter/nodes/ @LLLLeeJ @JxJuly @xiamidaxia @luics @zxhfighter @stream-pipe
/packages/workflow/test-run/ @JxJuly @xiamidaxia @luics @zxhfighter @dragooncjw
/packages/workflow/test-run-next/main/ @JxJuly @LLLLeeJ @xiamidaxia @zxhfighter
/packages/workflow/test-run-next/form/ @JxJuly @LLLLeeJ @xiamidaxia @zxhfighter
/packages/workflow/test-run-next/shared/ @JxJuly @LLLLeeJ @xiamidaxia @zxhfighter
/packages/workflow/test-run-next/trace/ @JxJuly @LLLLeeJ @xiamidaxia @zxhfighter
/packages/project-ide/ui-adapter/ @dragooncjw @xiamidaxia
/packages/studio/workspace/project-publish/ @catee @lihuiwen
/packages/studio/workspace/entry-adapter/ @duwenhan2byte @evan-crash
/packages/studio/workspace/entry-base/ @duwenhan2byte @catee @evan-crash
/packages/workflow/adapter/playground/ @LLLLeeJ @JxJuly @xiamidaxia @luics @zxhfighter @stream-pipe
/infra/plugins/import-watch-loader/ @Tecvan-fe
/config/rsbuild-config/ @Tecvan-fe
/packages/community/explore/ @evan-crash @duwenhan2byte
/common/_templates/node-core/ @Tecvan-fe
/common/_templates/rspack-web/ @Tecvan-fe

51
.gitignore vendored Normal file
View File

@ -0,0 +1,51 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
.env
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# the result of the go build
backend/**/output*
output/*
# Files generated by IDEs
.idea/
*.iml
# Vim swap files
*.swp
# Vscode files
.vscode
/patches
/oldimpl
.DS_Store
bin/*
docker/data/*
backend/static
node_modules
common/temp
.rush
.eslintcache

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
lts/iron

4
.prettierrc.js Normal file
View File

@ -0,0 +1,4 @@
// Do not modify this file
module.exports = {
...require('./frontend/config/eslint-config/.prettierrc.js'),
};

46
AUTHORS Normal file
View File

@ -0,0 +1,46 @@
# Below is a list of people and organizations that have contributed
# to the Coze Studio project. Names should be added to the list like so:
#
# Name/Organization <email address>
#
# Anyone who has contributed to the Coze Studio project in any way (not
# limited to submitting PRs) is welcome to submit a PR to add their
# name to this file.
#
# Thanks to everyone for your contributions!
ByteDance Ltd. and/or its Affiliates
luohuaqing.2018 <luohuaqing.2018@bytedance.com>
lipandeng <lipandeng@bytedance.com>
fanlv <fanlv@bytedance.com>
lijunwen.gigoo <lijunwen.gigoo@bytedance.com>
shentong.martin <shentong.martin@bytedance.com>
maronghong <maronghong@bytedance.com>
xuzhaonan <xuzhaonan@bytedance.com>
zhuangjie <zhuangjie.1125@bytedance.com>
liuyunchao <liuyunchao.0510@bytedance.com>
liujian.0502 <liujian.0502@bytedance.com>
wangdezheng <wangdezheng@bytedance.com>
liyubei <liyubei@bytedance.com>
xukai.luics <xukai.luics@bytedance.com>
sunzhiyuan.evan <sunzhiyuan.evan@bytedance.com>
yangyu.1 <yangyu.1@bytedance.com>
haozhenfei <haozhenfei@bytedance.com>
zengxiaohui <zengxiaohui@bytedance.com>
gaoyuanhan.duty <gaoyuanhan.duty@bytedance.com>
duwenhan <duwenhan@bytedance.com>
gaoding.devingao <gaoding.devingao@bytedance.com>
chenjiawei.inizio <chenjiawei.inizio@bytedance.com>
wencheng.lwc <wencheng.lwc@bytedance.com>
fanwenjie.fe <fanwenjie.fe@bytedance.com>
lihuiwen.123 <lihuiwen.123@bytedance.com>
liji.leej <liji.leej@bytedance.com>
fengzilong <fengzilong@bytedance.com>
shanrenkai <shanrenkai@bytedance.com>
sunkuo <sunkuo@bytedance.com>
fanchen <fanchen@bytedance.com>
lingyibin.jason <lingyibin.jason@bytedance.com>
chenchen.dabaishu <chenchen.dabaishu@bytedance.com>
jiangxujin <jiangxujin@bytedance.com>
huyongbiao <huyongbiao@bytedance.com>

128
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
conduct@cloudwego.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

51
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,51 @@
# How to Contribute
## Your First Pull Request
We use GitHub for our codebase. You can start by reading [How To Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).
## Branch Organization
We use [git-flow](https://nvie.com/posts/a-successful-git-branching-model/) as our branch organization, as known as [FDD](https://en.wikipedia.org/wiki/Feature-driven_development)
## Bugs
### 1. How to Find Known Issues
We are using [Github Issues](https://github.com/coze-dev/{project_name}/issues) for our public bugs. We keep a close eye on this and try to make it clear when we have an internal fix in progress. Before filing a new task, try to make sure your problem doesnt already exist.
### 2. Reporting New Issues
Providing a reduced test code is a recommended way for reporting issues. Then can place in:
- Just in issues
- [Golang Playground](https://play.golang.org/)
### 3. Security Bugs
Please do not report the safe disclosure of bugs to public issues. Contact us by [Support Email](mailto:opensource-studio@coze.cn)
## How to Get in Touch
- [Email](mailto:opensource-studio@coze.cn)
## Submit a Pull Request
Before you submit your Pull Request (PR) consider the following guidelines:
1. Search [GitHub](https://github.com/coze-dev/{project_name}/pulls) for an open or closed PR that relates to your submission. You don't want to duplicate existing efforts.
2. Be sure that an issue describes the problem you're fixing, or documents the design for the feature you'd like to add. Discussing the design upfront helps to ensure that we're ready to accept your work.
3. [Fork](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo) the coze-dev {project_name} repo.
4. In your forked repository, make your changes in a new git branch:
```
git checkout -b my-fix-branch develop
```
5. Create your patch, including appropriate test cases.
6. Follow our [Style Guides](#code-style-guides).
7. Commit your changes using a descriptive commit message that follows [AngularJS Git Commit Message Conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/edit).
Adherence to these conventions is necessary because release notes are automatically generated from these messages.
8. Push your branch to GitHub:
```
git push origin my-fix-branch
```
9. In GitHub, send a pull request to `{project_name}:develop`
## Contribution Prerequisites
- Our development environment keeps up with [Go Official](https://golang.org/project/).
- You need fully checking with lint tools before submit your pull request. [gofmt](https://golang.org/pkg/cmd/gofmt/) and [golangci-lint](https://github.com/golangci/golangci-lint)
- You are familiar with [GitHub](https://github.com)
- Maybe you need familiar with [Actions](https://github.com/features/actions)(our default workflow tool).
## Code Style Guides
- [Effective Go](https://golang.org/doc/effective_go)
- [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)

177
LICENSE-APACHE Normal file
View File

@ -0,0 +1,177 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

94
Makefile Normal file
View File

@ -0,0 +1,94 @@
.PHONY: debug fe server sync_db dump_db middleware web down clean python help
# 定义脚本路径
SCRIPTS_DIR := ./scripts
BUILD_FE_SCRIPT := $(SCRIPTS_DIR)/build_fe.sh
BUILD_SERVER_SCRIPT := $(SCRIPTS_DIR)/setup/server.sh
SYNC_DB_SCRIPT := $(SCRIPTS_DIR)/setup/db_migrate_apply.sh
DUMP_DB_SCRIPT := $(SCRIPTS_DIR)/setup/db_migrate_dump.sh
SETUP_DOCKER_SCRIPT := $(SCRIPTS_DIR)/setup/docker.sh
SETUP_PYTHON_SCRIPT := $(SCRIPTS_DIR)/setup/python.sh
COMPOSE_FILE := docker/docker-compose.yml
MYSQL_SCHEMA := ./docker/volumes/mysql/schema.sql
MYSQL_INIT_SQL := ./docker/volumes/mysql/sql_init.sql
ENV_FILE := ./docker/.env
debug: middleware python server
fe:
@echo "Building frontend..."
@bash $(BUILD_FE_SCRIPT)
server:
@echo "Building and run server..."
@bash $(BUILD_SERVER_SCRIPT) -start
build_server:
@echo "Building server..."
@bash $(BUILD_SERVER_SCRIPT)
sync_db:
@echo "Syncing database..."
@docker compose -f $(COMPOSE_FILE) --env-file $(ENV_FILE) --profile mysql-setup up -d
dump_db: dump_sql_schema
@echo "Dumping database..."
@bash $(DUMP_DB_SCRIPT)
sql_init:
@echo "Init sql data..."
@docker compose -f $(COMPOSE_FILE) --env-file $(ENV_FILE) --profile mysql-setup up -d
middleware:
@echo "Start middleware docker environment for opencoze app"
@docker compose -f $(COMPOSE_FILE) --env-file $(ENV_FILE) --profile middleware up -d --wait
web:
@echo "Start web server in docker"
@docker compose -f $(COMPOSE_FILE) --env-file $(ENV_FILE) --profile '*' up -d --wait
down:
@echo "Stop all docker containers"
@docker compose -f $(COMPOSE_FILE) --profile '*' down
clean: down
@echo "Remove docker containers and volumes data"
@rm -rf ./docker/data
python:
@echo "Setting up Python..."
@bash $(SETUP_PYTHON_SCRIPT)
dump_sql_schema:
@echo "Dumping mysql schema to $(MYSQL_SCHEMA)..."
@. $(ENV_FILE); \
{ echo "SET NAMES utf8mb4;\nCREATE DATABASE IF NOT EXISTS opencoze COLLATE utf8mb4_unicode_ci;"; atlas schema inspect -u $$ATLAS_URL --format "{{ sql . }}" --exclude "atlas_schema_revisions,table_*" | sed 's/CREATE TABLE/CREATE TABLE IF NOT EXISTS/g'; } > $(MYSQL_SCHEMA)
@sed -I '' -E 's/(\))[[:space:]]+CHARSET utf8mb4/\1 ENGINE=InnoDB CHARSET utf8mb4/' $(MYSQL_SCHEMA)
@echo "Dumping mysql schema to helm/charts/opencoze/files/mysql ..."
@cp $(MYSQL_SCHEMA) ./helm/charts/opencoze/files/mysql/
@cp $(MYSQL_INIT_SQL) ./helm/charts/opencoze/files/mysql/
atlas-hash:
@echo "Rehash atlas migration files..."
@(cd ./docker/atlas && atlas migrate hash)
help:
@echo "Usage: make [target]"
@echo ""
@echo "Targets:"
@echo " debug - Start the debug environment."
@echo " fe - Build the frontend."
@echo " server - Build and run the server binary."
@echo " build_server - Build the server binary."
@echo " sync_db - Sync opencoze_latest_schema.hcl to the database."
@echo " dump_db - Dump the database to opencoze_latest_schema.hcl and migrations files."
@echo " sql_init - Init sql data..."
@echo " dump_sql_schema - Dump the database schema to sql file."
@echo " middleware - Setup middlewares docker environment, but exclude the server app."
@echo " web - Setup web docker environment, include middlewares docker."
@echo " down - Stop the docker containers."
@echo " clean - Stop the docker containers and clean volumes."
@echo " python - Setup python environment."
@echo " atlas-hash - Rehash atlas migration files."
@echo " help - Show this help message."

134
README.md Normal file
View File

@ -0,0 +1,134 @@
<div align="center">
<h1>Coze Studio 社区版</h1>
<p><strong> AI Agent 开发与运维的平台级解决方案</strong></p>
<p>
<a href="#什么是Coze Studio">Coze Studio</a>
<a href="#功能清单">功能清单</a>
<a href="#快速开始">快速开始</a>
<a href="#开发指南">开发指南</a>
</p>
<p>
<img alt="License" src="https://img.shields.io/badge/license-apache2.0-blue.svg">
<img alt="Go Version" src="https://img.shields.io/badge/go-%3E%3D%201.23.4-blue">
</p>
[English](README.md) | 中文
</div>
## 什么是Coze Studio
[Coze Studio](https://www.coze.cn/home) 是一站式 AI Agent 开发工具。提供各类最新大模型和工具、多种开发模式和框架,从开发到部署,为你提供最便捷的 AI Agent 开发环境。上万家企业、数百万开发者正在使 Coze Studio。
* **提供 AI Agent 开发所需的全部核心技术**Prompt、RAG、Plugin、Workflow、UI Builder ,使得开发者可以聚焦创造 AI 核心价值。
* **开箱即用,用最低的成本开发最专业的 AI Agent**Coze Studio 为开发者提供了健全的应用模板和编排框架,你可以基于它们快速构建各种 AI Agent 将创意变为现实。Coze Studio 支持集成火山引擎各类资源,方便你的 AI Agent 实现快速扩容。
Coze Studio 是字节跳动新一代 AI Agent 开发平台**扣子Coze**的**开源版本**。通过 Coze Studio 提供的可视化设计与编排工具,开发者可以通过零代码或低代码的方式,快速打造和调试智能体、应用和工作流,实现强大的 AI 应用开发和更多定制化业务逻辑,是构建面向非编程用户的低代码 AI 产品的理想选择。Coze Studio 致力于降低 AI Agent 开发与应用门槛,鼓励社区共建和分享交流,助你在 AI 领域进行更深层次的探索与实践。
Coze Studio 的后端采用 Golang 开发,前端使用 React + TypeScript整体基于微服务架构并遵循领域驱动设计DDD原则构建。为开发者提供一个高性能、高扩展性、易于二次开发的底层框架助力开发者应对复杂的业务需求。
## 功能清单
<table>
<thead>
<tr>
<th>功能模块</th>
<th>功能点</th>
<th>商业版</th>
<th>社区版</th>
</tr>
</thead>
<tbody>
<tr>
<td rowspan="1">搭建智能体</td>
<td>编排、发布、管理智能体</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td rowspan="1">搭建应用</td>
<td>通过工作流搭建业务逻辑</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td rowspan="1">搭建工作流</td>
<td>创建、修改、发布、管理工作流</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td rowspan="2">插件等开发资源</td>
<td>插件、知识库、数据库、提示词</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td>音色、卡片、音视频通话等</td>
<td>✔️</td>
<td>-</td>
</tr>
<tr>
<td rowspan="1">企业与团队空间</td>
<td>企业团队管理、多人协作、SSO 等特性</td>
<td>✔️</td>
<td>-</td>
</tr>
<tr>
<td rowspan="3">API 与 SDK</td>
<td>OpenAPI</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td>Chat SDK</td>
<td>✔️</td>
<td>✔️</td>
</tr>
<tr>
<td>Realtime 等 SDK、API</td>
<td>✔️</td>
<td>-</td>
</tr>
</tbody>
</table>
## 快速开始
参考[快速开始](https://github.com/coze-dev/coze-studio/wiki/2.-快速开始),了解如何获取并部署 Coze Studio 社区版,快速构建项目、体验 Coze Studio 社区版。
## 开发指南
* **项目配置**
* [模型配置](https://github.com/coze-dev/coze-studio/wiki/3.-模型配置):部署 Coze Studio 社区版之前,必须配置模型服务,否则无法在搭建智能体、工作流和应用时选择模型。
* [插件配置](https://github.com/coze-dev/coze-studio/wiki/4.-插件配置):如需使用插件商店中的官方插件,必须先配置插件,添加第三方服务的鉴权秘钥。
* [基础组件配置](https://github.com/coze-dev/coze-studio/wiki/5.-基础组件配置):了解如何配置 ImageX 等服务,以便在 Coze Studio 中使用上传图片等功能。
* [API 参考](https://github.com/coze-dev/coze-studio/wiki/6.-API-参考)和商业版不同Coze Studio 社区版仅支持个人访问秘钥PAT鉴权并支持对话和工作流相关 API。
* [开发规范](https://github.com/coze-dev/coze-studio/wiki/7.-开发规范)
* [项目架构](https://github.com/coze-dev/coze-studio/wiki/7.-%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83#%E9%A1%B9%E7%9B%AE%E6%9E%B6%E6%9E%84):了解 Coze Studio 社区版的技术架构与核心组件。
* [代码开发与测试](https://github.com/coze-dev/coze-studio/wiki/7.-%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83#%E4%BB%A3%E7%A0%81%E5%BC%80%E5%8F%91%E4%B8%8E%E6%B5%8B%E8%AF%95):了解如何基于 Coze Studio 社区版进行二次开发与测试。
* [故障排查](https://github.com/coze-dev/coze-studio/wiki/7.-%E5%BC%80%E5%8F%91%E8%A7%84%E8%8C%83#%E6%95%85%E9%9A%9C%E6%8E%92%E6%9F%A5):了解如何查看容器状态、系统日志。
## 使用 Coze Studio 社区版
> 关于如何使用 Coze Studio可参考[扣子开发平台官方文档中心](https://www.coze.cn/open/docs)获取更多资料。需要注意的是,音色等部分功能限商业版本使用,社区版与商业版的功能差异可参考**功能清单**。
* [快速入门](https://www.coze.cn/open/docs/guides/quickstart):通过 Coze Studio 快速搭建一个 AI 助手智能体。
* [开发智能体](https://www.coze.cn/open/docs/guides/agent_overview)如何创建、编排、发布与管理智能体。你可以使用知识、插件等功能解决模型幻觉、专业领域知识不足等问题。除此之外Coze Studio 还提供了丰富的记忆功能,使智能体在与个人用户交互时,可根据个人用户的历史对话等生成更准确性的回复。
* [开发工作流](https://www.coze.cn/open/docs/guides/workflow):工作流是一系列可执行指令的集合,用于实现业务逻辑或完成特定任务。它为应用/智能体的数据流动和任务处理提供了一个结构化框架。 Coze Studio 提供了一个可视化画布,你可以通过拖拽节点迅速搭建工作流。
* [插件等资源](https://www.coze.cn/open/docs/guides/plugin):在 Coze Studio工作流、插件、数据库、知识库和变量统称为资源。
* **API & SDK** Coze Studio 支持[对话和工作流相关 API](https://github.com/coze-dev/coze-studio/wiki/6.-API-%E5%8F%82%E8%80%83),你也可以通过 [Chat SDK](https://www.coze.cn/open/docs/developer_guides/web_sdk_overview) 将智能体或应用集成到本地业务系统。
* [实践教程](https://www.coze.cn/open/docs/tutorial/chat_sdk_web_online_customer_service):了解如何通过 Coze Studio 实现各种 AI 场景,例如通过 Chat SDK 搭建网页在线客服。
## License
本项目采用 Apache 2.0 许可证。详情请参阅 [LICENSE](https://github.com/coze-dev/coze-studio/blob/main/LICENSE-APACHE) 文件。
## 社区贡献
我们欢迎社区贡献,贡献指南参见 [CONTRIBUTING](https://github.com/coze-dev/coze-studio/blob/main/CONTRIBUTING.md) 和 [Code of conduct](https://github.com/coze-dev/coze-studio/blob/main/CODE_OF_CONDUCT.md),期待您的贡献!
## 安全与隐私
如果你在该项目中发现潜在的安全问题,或你认为可能发现了安全问题,请通过我们的[安全中心](https://security.bytedance.com/src) 或[漏洞报告邮箱](https://code.byted.org/flowdevops/cozeloop/blob/feat/release/sec@bytedance.com)通知字节跳动安全团队。
请**不要**创建公开的 GitHub Issue。
## 加入社区
飞书移动端扫描以下二维码,加入 Coze Studio 技术交流群。
![Image](https://p9-arcosite.byteimg.com/tos-cn-i-goo7wpa0wc/194fe3b9832848f0b7540279c91700b3~tplv-goo7wpa0wc-image.image)
## 致谢
感谢所有为 Coze Studio 项目做出贡献的开发者和社区成员。特别感谢:
* Eino 框架团队提供的 LLM 集成支持
* Cloudwego 团队开发的高性能框架
* 所有参与测试和反馈的用户

42
backend/.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
*.o
*.a
*.so
_obj
_test
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.exe~
*.test
*.prof
*.rar
*.zip
*.gz
*.psd
*.bmd
*.cfg
*.pptx
*.log
*nohup.out
*settings.pyc
*.sublime-project
*.sublime-workspace
!.gitkeep
.DS_Store
/.idea
/.vscode
/output
*.local.yml
dumped_hertz_remote_config.json
/oldimpl
/vendor
*gen_test.go
/domain/workflow/internal/nodes/code/script/RestrictedPython/__pycache__/**
.env.dev
.env.local

6
backend/.hz Normal file
View File

@ -0,0 +1,6 @@
// Code generated by hz. DO NOT EDIT.
hz version: v0.9.7
handlerDir: api/handler
modelDir: api/model
routerDir: api/router

85
backend/Dockerfile Normal file
View File

@ -0,0 +1,85 @@
# Stage 1: Builder for Go application
FROM golang:1.24-alpine AS builder
WORKDIR /app
# Install build dependencies for Go
RUN apk add --no-cache git gcc libc-dev
# Copy go.mod and go.sum first to leverage Docker cache
COPY backend/go.mod backend/go.sum ./
RUN go mod download
COPY docker/proxy ./proxy
# Build the proxy application
RUN go build -ldflags="-s -w" -o /app/proxy_app ./proxy/proxy.go
# Copy the entire backend source code
COPY backend/ ./
# Build the Go application
RUN go build -ldflags="-s -w" -o /app/opencoze main.go
# Stage 2: Final image
FROM alpine:3.22.0
WORKDIR /app
# Install runtime dependencies for Go app and base for Python
# pax-utils for scanelf, python3 for running Python, python3-dev for headers/shared libs
# bind-tools for nslookup etc., file for debugging file types
RUN apk add --no-cache pax-utils python3 python3-dev bind-tools file
# Install Python build dependencies, create venv, install packages, then remove build deps
RUN apk add --no-cache --virtual .python-build-deps build-base py3-pip git && \
python3 -m venv --copies --upgrade-deps /app/.venv && \
# Activate venv and install packages
. /app/.venv/bin/activate && \
# If you want to use other third-party libraries, you can install them here.
pip install git+https://gitcode.com/gh_mirrors/re/requests-async.git@master && \
pip install urllib3==1.26.16 && \
pip install --no-cache-dir pillow==11.2.1 pdfplumber==0.11.7 python-docx==1.2.0 numpy==2.3.1 && \
# Deactivate (optional, as RUN is a new shell)
# deactivate && \
# Remove build dependencies
apk del .python-build-deps
# Copy the built Go binary from the builder stage
COPY --from=builder /app/opencoze /app/opencoze
COPY --from=builder /app/proxy_app /app/proxy
# Copy Python application scripts
COPY backend/infra/impl/document/parser/builtin/parse_pdf.py /app/parse_pdf.py
COPY backend/infra/impl/document/parser/builtin/parse_docx.py /app/parse_docx.py
# Copy static resources
COPY backend/static /app/resources/static/
COPY backend/conf /app/resources/conf/
COPY docker/.env.example /app/.env
# COPY docker/.env.ve /app/.env
# COPY docker/cert.pem /app/cert.pem
# COPY docker/key.pem /app/key.pem
# Set PATH to prioritize venv's binaries
ENV PATH="/app/.venv/bin:${PATH}"
# ENV LD_LIBRARY_PATH="/usr/lib:${LD_LIBRARY_PATH}" # Keep commented for now
# Ensure python scripts and venv executables are executable
RUN chmod +x /app/parse_pdf.py /app/parse_docx.py && \
find /app/.venv/bin -type f -exec chmod +x {} \;
# Ensure Go binaries are executable
RUN chmod +x /app/opencoze /app/proxy
EXPOSE 8888
# Use a script to start both applications
COPY backend/script/bootstrap.sh /app/bootstrap.sh
RUN chmod +x /app/bootstrap.sh
CMD ["/app/bootstrap.sh"]

1
backend/README.md Normal file
View File

@ -0,0 +1 @@
# Coze Backend API

View File

@ -0,0 +1,125 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package coze
import (
"context"
"encoding/json"
"net/http"
"github.com/hertz-contrib/sse"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/run"
"github.com/coze-dev/coze-studio/backend/application/conversation"
sseImpl "github.com/coze-dev/coze-studio/backend/infra/impl/sse"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
// AgentRun .
// @router /api/conversation/chat [POST]
func AgentRun(ctx context.Context, c *app.RequestContext) {
var err error
var req run.AgentRunRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkParams(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
sseSender := sseImpl.NewSSESender(sse.NewStream(c))
c.SetStatusCode(http.StatusOK)
c.Response.Header.Set("X-Accel-Buffering", "no")
err = conversation.ConversationSVC.Run(ctx, sseSender, &req)
if err != nil {
errData := run.ErrorData{
Code: errno.ErrConversationAgentRunError,
Msg: err.Error(),
}
ed, _ := json.Marshal(errData)
_ = sseSender.Send(ctx, &sse.Event{
Event: run.RunEventError,
Data: ed,
})
}
}
func checkParams(_ context.Context, ar *run.AgentRunRequest) error {
if ar.BotID == 0 {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "bot id is required"))
}
if ar.Scene == nil {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "scene is required"))
}
if ar.ContentType == nil {
ar.ContentType = ptr.Of(run.ContentTypeText)
}
return nil
}
// ChatV3 .
// @router /v3/chat [POST]
func ChatV3(ctx context.Context, c *app.RequestContext) {
var err error
var req run.ChatV3Request
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkParamsV3(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
c.SetStatusCode(http.StatusOK)
c.Response.Header.Set("X-Accel-Buffering", "no")
sseSender := sseImpl.NewSSESender(sse.NewStream(c))
err = conversation.ConversationOpenAPISVC.OpenapiAgentRun(ctx, sseSender, &req)
if err != nil {
errData := run.ErrorData{
Code: errno.ErrConversationAgentRunError,
Msg: err.Error(),
}
ed, _ := json.Marshal(errData)
_ = sseSender.Send(ctx, &sse.Event{
Event: run.RunEventError,
Data: ed,
})
}
}
func checkParamsV3(_ context.Context, ar *run.ChatV3Request) error {
if ar.BotID == 0 {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "bot id is required"))
}
return nil
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/api/internal/httputil"
)
func invalidParamRequestResponse(c *app.RequestContext, errMsg string) {
httputil.BadRequest(c, errMsg)
}
func internalServerErrorResponse(ctx context.Context, c *app.RequestContext, err error) {
httputil.InternalError(ctx, c, err)
}

View File

@ -0,0 +1,59 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/application/plugin"
bot_open_api "github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/bot_open_api"
)
// OauthAuthorizationCode .
// @router /api/oauth/authorization_code [GET]
func OauthAuthorizationCode(ctx context.Context, c *app.RequestContext) {
var err error
var req bot_open_api.OauthAuthorizationCodeReq
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.Code == "" {
invalidParamRequestResponse(c, "code is required")
return
}
if req.State == "" {
invalidParamRequestResponse(c, "state is required")
return
}
resp, err := plugin.PluginApplicationSVC.OauthAuthorizationCode(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,172 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/conversation"
application "github.com/coze-dev/coze-studio/backend/application/conversation"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
// ClearConversationHistory .
// @router /api/conversation/clear_message [POST]
func ClearConversationHistory(ctx context.Context, c *app.RequestContext) {
var err error
var req conversation.ClearConversationHistoryRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkCCHParams(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
resp, err := application.ConversationSVC.ClearHistory(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
func checkCCHParams(_ context.Context, req *conversation.ClearConversationHistoryRequest) error {
if req.ConversationID <= 0 {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "invalid conversation id"))
}
if req.Scene == nil {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "scene is required"))
}
return nil
}
// ClearConversationCtx .
// @router /api/conversation/create_section [POST]
func ClearConversationCtx(ctx context.Context, c *app.RequestContext) {
resp := new(conversation.ClearConversationCtxResponse)
var err error
var req conversation.ClearConversationCtxRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkCCCParams(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
newSectionID, err := application.ConversationSVC.CreateSection(ctx, req.ConversationID)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp.NewSectionID = newSectionID
c.JSON(consts.StatusOK, resp)
}
func checkCCCParams(ctx context.Context, req *conversation.ClearConversationCtxRequest) error {
if req.ConversationID <= 0 {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "invalid conversation id"))
}
if req.Scene == nil {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "scene is required"))
}
return nil
}
// CreateConversation .
// @router /api/conversation/create [POST]
func CreateConversation(ctx context.Context, c *app.RequestContext) {
var err error
var req conversation.CreateConversationRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := application.ConversationSVC.CreateConversation(ctx, req.GetBotId(), req.GetConnectorId())
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ClearConversationApi .
// @router /v1/conversations/:conversation_id/clear [POST]
func ClearConversationApi(ctx context.Context, c *app.RequestContext) {
var err error
var req conversation.ClearConversationApiRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp := new(conversation.ClearConversationApiResponse)
sectionID, err := application.ConversationSVC.CreateSection(ctx, req.ConversationID)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp.Data = &conversation.Section{
ID: sectionID,
ConversationID: req.ConversationID,
}
c.JSON(consts.StatusOK, resp)
}
// ListConversationsApi .
// @router /v1/conversations [GET]
func ListConversationsApi(ctx context.Context, c *app.RequestContext) {
var err error
var req conversation.ListConversationsApiRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := application.ConversationSVC.ListConversation(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package coze
import (
"bytes"
"context"
"net/http"
"testing"
"github.com/bytedance/sonic"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/ut"
"github.com/stretchr/testify/assert"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/conversation"
"github.com/coze-dev/coze-studio/backend/application"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
)
func TestClearConversationCtx(t *testing.T) {
h := server.Default()
err := application.Init(context.Background())
t.Logf("application init err: %v", err)
h.POST("/api/conversation/create_section", ClearConversationCtx)
req := &conversation.ClearConversationCtxRequest{
ConversationID: 7496795464885338112,
Scene: ptr.Of(common.Scene_Playground),
}
m, err := sonic.Marshal(req)
assert.Nil(t, err)
w := ut.PerformRequest(h.Engine, "POST", "/api/conversation/create_section", &ut.Body{Body: bytes.NewBuffer(m), Len: len(m)}, ut.Header{Key: "Content-Type", Value: "application/json"})
res := w.Result()
t.Logf("clear conversation ctx: %s", res.Body())
assert.Equal(t, http.StatusInternalServerError, res.StatusCode())
}
func TestClearConversationHistory(t *testing.T) {
h := server.Default()
err := application.Init(context.Background())
t.Logf("application init err: %v", err)
h.POST("/api/conversation/clear_message", ClearConversationHistory)
req := &conversation.ClearConversationHistoryRequest{
ConversationID: 7496795464885338113,
Scene: ptr.Of(common.Scene_Playground),
BotID: ptr.Of(int64(7366055842027922437)),
}
m, err := sonic.Marshal(req)
assert.Nil(t, err)
w := ut.PerformRequest(h.Engine, "POST", "/api/conversation/clear_message", &ut.Body{Body: bytes.NewBuffer(m), Len: len(m)}, ut.Header{Key: "Content-Type", Value: "application/json"})
res := w.Result()
t.Logf("clear conversation history: %s", res.Body())
assert.Equal(t, http.StatusInternalServerError, res.StatusCode())
}

View File

@ -0,0 +1,412 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/knowledge/document"
"github.com/coze-dev/coze-studio/backend/api/model/table"
"github.com/coze-dev/coze-studio/backend/application/memory"
"github.com/coze-dev/coze-studio/backend/application/singleagent"
)
// ListDatabase .
// @router /api/memory/database/list [POST]
func ListDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.ListDatabaseRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.ListDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDatabaseByID .
// @router /api/memory/database/get_by_id [POST]
func GetDatabaseByID(ctx context.Context, c *app.RequestContext) {
var err error
var req table.SingleDatabaseRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.GetDatabaseByID(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// AddDatabase .
// @router /api/memory/database/add [POST]
func AddDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.AddDatabaseRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.AddDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateDatabase .
// @router /api/memory/database/update [POST]
func UpdateDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.UpdateDatabaseRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.UpdateDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeleteDatabase .
// @router /api/memory/database/delete [POST]
func DeleteDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.DeleteDatabaseRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.DeleteDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// BindDatabase .
// @router /api/memory/database/bind_to_bot [POST]
func BindDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.BindDatabaseToBotRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := singleagent.SingleAgentSVC.BindDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UnBindDatabase .
// @router /api/memory/database/unbind_to_bot [POST]
func UnBindDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.BindDatabaseToBotRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := singleagent.SingleAgentSVC.UnBindDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListDatabaseRecords .
// @router /api/memory/database/list_records [POST]
func ListDatabaseRecords(ctx context.Context, c *app.RequestContext) {
var err error
var req table.ListDatabaseRecordsRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.ListDatabaseRecords(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateDatabaseRecords .
// @router /api/memory/database/update_records [POST]
func UpdateDatabaseRecords(ctx context.Context, c *app.RequestContext) {
var err error
var req table.UpdateDatabaseRecordsRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.UpdateDatabaseRecords(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetOnlineDatabaseId .
// @router /api/memory/database/get_online_database_id [POST]
func GetOnlineDatabaseId(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetOnlineDatabaseIdRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.GetOnlineDatabaseId(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ResetBotTable .
// @router /api/memory/database/table/reset [POST]
func ResetBotTable(ctx context.Context, c *app.RequestContext) {
var err error
var req table.ResetBotTableRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.ResetBotTable(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDatabaseTemplate .
// @router /api/memory/database/get_template [POST]
func GetDatabaseTemplate(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetDatabaseTemplateRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.GetDatabaseTemplate(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetConnectorName .
// @router /api/memory/database/get_connector_name [POST]
func GetConnectorName(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetSpaceConnectorListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.GetConnectorName(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetBotDatabase .
// @router /api/memory/database/table/list_new [POST]
func GetBotDatabase(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetBotTableRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.GetBotDatabase(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateDatabaseBotSwitch .
// @router /api/memory/database/update_bot_switch [POST]
func UpdateDatabaseBotSwitch(ctx context.Context, c *app.RequestContext) {
var err error
var req table.UpdateDatabaseBotSwitchRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := singleagent.SingleAgentSVC.UpdatePromptDisable(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDatabaseTableSchema .
// @router /api/memory/table_schema/get [POST]
func GetDatabaseTableSchema(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetTableSchemaRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
var resp *document.GetTableSchemaInfoResponse
resp, err = memory.DatabaseApplicationSVC.GetDatabaseTableSchema(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// SubmitDatabaseInsertTask .
// @router /api/memory/table_file/submit [POST]
func SubmitDatabaseInsertTask(ctx context.Context, c *app.RequestContext) {
var err error
var req table.SubmitDatabaseInsertRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.SubmitDatabaseInsertTask(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DatabaseFileProgressData .
// @router /api/memory/table_file/get_progress [POST]
func DatabaseFileProgressData(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetDatabaseFileProgressRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.DatabaseFileProgressData(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ValidateDatabaseTableSchema .
// @router /api/memory/table_schema/validate [POST]
func ValidateDatabaseTableSchema(ctx context.Context, c *app.RequestContext) {
var err error
var req table.ValidateTableSchemaRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := memory.DatabaseApplicationSVC.ValidateDatabaseTableSchema(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,463 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"crypto/sha256"
"encoding/base64"
"fmt"
"math/rand"
"time"
"unicode/utf8"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
developer_api "github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/developer_api"
"github.com/coze-dev/coze-studio/backend/application/base/ctxutil"
"github.com/coze-dev/coze-studio/backend/application/modelmgr"
"github.com/coze-dev/coze-studio/backend/application/singleagent"
application "github.com/coze-dev/coze-studio/backend/application/singleagent"
"github.com/coze-dev/coze-studio/backend/application/upload"
"github.com/coze-dev/coze-studio/backend/application/user"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
// DraftBotCreate .
// @router /api/draftbot/create [POST]
func DraftBotCreate(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.DraftBotCreateRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "space id is not set")
return
}
if req.Name == "" {
invalidParamRequestResponse(c, "name is nil")
return
}
if req.IconURI == "" {
invalidParamRequestResponse(c, "icon uri is nil")
return
}
if utf8.RuneCountInString(req.Name) > 50 {
invalidParamRequestResponse(c, "name is too long")
return
}
if utf8.RuneCountInString(req.Description) > 2000 {
invalidParamRequestResponse(c, "description is too long")
return
}
resp, err := application.SingleAgentSVC.CreateSingleAgentDraft(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeleteDraftBot .
// @router /api/draftbot/delete [POST]
func DeleteDraftBot(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.DeleteDraftBotRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := application.SingleAgentSVC.DeleteAgentDraft(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateDraftBotDisplayInfo .
// @router /api/draftbot/update_display_info [POST]
func UpdateDraftBotDisplayInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.UpdateDraftBotDisplayInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := application.SingleAgentSVC.UpdateAgentDraftDisplayInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DuplicateDraftBot .
// @router /api/draftbot/duplicate [POST]
func DuplicateDraftBot(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.DuplicateDraftBotRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := application.SingleAgentSVC.DuplicateDraftBot(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDraftBotDisplayInfo .
// @router /api/draftbot/get_display_info [POST]
func GetDraftBotDisplayInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.GetDraftBotDisplayInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := application.SingleAgentSVC.GetAgentDraftDisplayInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PublishDraftBot .
// @router /api/draftbot/publish [POST]
func PublishDraftBot(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.PublishDraftBotRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if len(req.Connectors) == 0 {
invalidParamRequestResponse(c, "connectors is nil")
return
}
resp, err := application.SingleAgentSVC.PublishAgent(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListDraftBotHistory .
// @router /api/draftbot/list_draft_history [POST]
func ListDraftBotHistory(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.ListDraftBotHistoryRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.BotID == 0 {
invalidParamRequestResponse(c, "bot id is not set")
return
}
if req.PageIndex <= 0 {
req.PageIndex = 1
}
if req.PageSize <= 0 {
req.PageSize = 30
}
resp, err := application.SingleAgentSVC.ListAgentPublishHistory(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetIcon .
// @router /api/developer/get_icon [POST]
func GetIcon(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.GetIconRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := upload.SVC.GetIcon(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetUploadAuthToken .
// @router /api/playground/upload/auth_token [POST]
func GetUploadAuthToken(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.GetUploadAuthTokenRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := application.SingleAgentSVC.GetUploadAuthToken(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
func createSecret(uid int64, fileType string) string {
num := 10
input := fmt.Sprintf("upload_%d_Ma*9)fhi_%d_gou_%s_rand_%d", uid, time.Now().Unix(), fileType, rand.Intn(100000))
// 做md5取前20个,// mapIntToBase62 把数字映射到 Base62
hash := sha256.Sum256([]byte(fmt.Sprintf("%s", input)))
hashString := base64.StdEncoding.EncodeToString(hash[:])
if len(hashString) > num {
hashString = hashString[:num]
}
result := ""
for _, char := range hashString {
index := int(char) % 62
result += string(baseWord[index])
}
return result
}
// UploadFile .
// @router /api/bot/upload_file [POST]
func UploadFile(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.UploadFileRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(developer_api.UploadFileResponse)
fileContent, err := base64.StdEncoding.DecodeString(req.Data)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
userID := ctxutil.GetUIDFromCtx(ctx)
if userID == nil {
internalServerErrorResponse(ctx, c, errorx.New(errno.ErrUploadPermissionCode, errorx.KV("msg", "session required")))
return
}
secret := createSecret(ptr.From(userID), req.FileHead.FileType)
fileName := fmt.Sprintf("%d_%d_%s.%s", ptr.From(userID), time.Now().UnixNano(), secret, req.FileHead.FileType)
objectName := fmt.Sprintf("%s/%s", req.FileHead.BizType.String(), fileName)
resp, err = upload.SVC.UploadFile(ctx, fileContent, objectName)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
const baseWord = "1Aa2Bb3Cc4Dd5Ee6Ff7Gg8Hh9Ii0JjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
// GetOnboarding .
// @router /api/playground/get_onboarding [POST]
func GetOnboarding(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.GetOnboardingRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(developer_api.GetOnboardingResponse)
c.JSON(consts.StatusOK, resp)
}
// PublishConnectorList .
// @router /api/draftbot/publish/connector/list [POST]
func PublishConnectorList(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.PublishConnectorListRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.BotID == 0 {
invalidParamRequestResponse(c, "bot id is not set")
return
}
resp, err := singleagent.SingleAgentSVC.GetPublishConnectorList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CheckDraftBotCommit .
// @router /api/draftbot/commit_check [POST]
func CheckDraftBotCommit(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.CheckDraftBotCommitRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(developer_api.CheckDraftBotCommitResponse)
c.JSON(consts.StatusOK, resp)
}
// UpdateUserProfileCheck .
// @router /api/user/update_profile_check [POST]
func UpdateUserProfileCheck(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.UpdateUserProfileCheckRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := user.UserApplicationSVC.UpdateUserProfileCheck(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetTypeList .
// @router /api/bot/get_type_list [POST]
func GetTypeList(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.GetTypeListRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := modelmgr.ModelmgrApplicationSVC.GetModelList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CommonUpload .
// @router /api/playground/upload [POST]
func CommonUpload(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.CommonUploadRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
fullUrl := string(c.Request.URI().FullURI())
resp, err := upload.SVC.UploadFileCommon(ctx, &req, fullUrl)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ApplyUploadAction .
// @router /api/playground/apply_upload_action [GET]
func ApplyUploadAction(ctx context.Context, c *app.RequestContext) {
var err error
var req developer_api.ApplyUploadActionRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(developer_api.ApplyUploadActionResponse)
host := c.Request.Host()
if ptr.From(req.Action) == "ApplyImageUpload" {
resp, err = upload.SVC.ApplyImageUpload(ctx, &req, string(host))
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
} else if ptr.From(req.Action) == "CommitImageUpload" {
resp, err = upload.SVC.CommitImageUpload(ctx, &req, string(host))
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,406 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"fmt"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/intelligence"
"github.com/coze-dev/coze-studio/backend/api/model/intelligence/common"
project "github.com/coze-dev/coze-studio/backend/api/model/project"
publish "github.com/coze-dev/coze-studio/backend/api/model/publish"
task "github.com/coze-dev/coze-studio/backend/api/model/task"
appApplication "github.com/coze-dev/coze-studio/backend/application/app"
"github.com/coze-dev/coze-studio/backend/application/search"
)
// GetDraftIntelligenceList .
// @router /api/intelligence_api/search/get_draft_intelligence_list [POST]
func GetDraftIntelligenceList(ctx context.Context, c *app.RequestContext) {
var err error
var req intelligence.GetDraftIntelligenceListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := search.SearchSVC.GetDraftIntelligenceList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDraftIntelligenceInfo .
// @router /api/intelligence_api/search/get_draft_intelligence_info [POST]
func GetDraftIntelligenceInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req intelligence.GetDraftIntelligenceInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.IntelligenceID <= 0 {
invalidParamRequestResponse(c, "invalid intelligence id")
return
}
if req.IntelligenceType != common.IntelligenceType_Project {
invalidParamRequestResponse(c, fmt.Sprintf("invalid intelligence type '%d'", req.IntelligenceType))
return
}
resp, err := appApplication.APPApplicationSVC.GetDraftIntelligenceInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetUserRecentlyEditIntelligence .
// @router /api/intelligence_api/search/get_recently_edit_intelligence [POST]
func GetUserRecentlyEditIntelligence(ctx context.Context, c *app.RequestContext) {
var err error
var req intelligence.GetUserRecentlyEditIntelligenceRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(intelligence.GetUserRecentlyEditIntelligenceResponse)
c.JSON(consts.StatusOK, resp)
}
// DraftProjectCreate .
// @router /api/intelligence_api/draft_project/create [POST]
func DraftProjectCreate(ctx context.Context, c *app.RequestContext) {
var err error
var req project.DraftProjectCreateRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "invalid space id")
return
}
if req.Name == "" || len(req.Name) > 256 {
invalidParamRequestResponse(c, "invalid name")
return
}
if req.IconURI == "" || len(req.IconURI) > 512 {
invalidParamRequestResponse(c, "invalid icon uri")
return
}
resp, err := appApplication.APPApplicationSVC.DraftProjectCreate(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DraftProjectUpdate .
// @router /api/intelligence_api/draft_project/update [POST]
func DraftProjectUpdate(ctx context.Context, c *app.RequestContext) {
var err error
var req project.DraftProjectUpdateRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
if req.Name != nil && (len(*req.Name) == 0 || len(*req.Name) > 256) {
invalidParamRequestResponse(c, "invalid name")
return
}
if req.IconURI != nil && (len(*req.IconURI) == 0 || len(*req.IconURI) > 512) {
invalidParamRequestResponse(c, "invalid icon uri")
return
}
resp, err := appApplication.APPApplicationSVC.DraftProjectUpdate(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DraftProjectDelete .
// @router /api/intelligence_api/draft_project/delete [POST]
func DraftProjectDelete(ctx context.Context, c *app.RequestContext) {
var err error
var req project.DraftProjectDeleteRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
resp, err := appApplication.APPApplicationSVC.DraftProjectDelete(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetProjectPublishedConnector .
// @router /api/intelligence_api/publish/get_published_connector [POST]
func GetProjectPublishedConnector(ctx context.Context, c *app.RequestContext) {
var err error
var req publish.GetProjectPublishedConnectorRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(publish.GetProjectPublishedConnectorResponse)
c.JSON(consts.StatusOK, resp)
}
// CheckProjectVersionNumber .
// @router /api/intelligence_api/publish/check_version_number [POST]
func CheckProjectVersionNumber(ctx context.Context, c *app.RequestContext) {
var err error
var req publish.CheckProjectVersionNumberRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
if req.VersionNumber == "" {
invalidParamRequestResponse(c, "invalid version number")
return
}
resp, err := appApplication.APPApplicationSVC.CheckProjectVersionNumber(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PublishProject .
// @router /api/intelligence_api/publish/publish_project [POST]
func PublishProject(ctx context.Context, c *app.RequestContext) {
var err error
var req publish.PublishProjectRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
if req.VersionNumber == "" {
invalidParamRequestResponse(c, "invalid version number")
return
}
resp, err := appApplication.APPApplicationSVC.PublishAPP(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPublishRecordList .
// @router /api/intelligence_api/publish/publish_record_list [POST]
func GetPublishRecordList(ctx context.Context, c *app.RequestContext) {
var err error
var req publish.GetPublishRecordListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
resp, err := appApplication.APPApplicationSVC.GetPublishRecordList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ProjectPublishConnectorList .
// @router /api/intelligence_api/publish/connector_list [POST]
func ProjectPublishConnectorList(ctx context.Context, c *app.RequestContext) {
var err error
var req publish.PublishConnectorListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
resp, err := appApplication.APPApplicationSVC.ProjectPublishConnectorList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPublishRecordDetail .
// @router /api/intelligence_api/publish/publish_record_detail [POST]
func GetPublishRecordDetail(ctx context.Context, c *app.RequestContext) {
var err error
var req publish.GetPublishRecordDetailRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
if req.PublishRecordID != nil && *req.PublishRecordID <= 0 {
invalidParamRequestResponse(c, "invalid publish record id")
return
}
resp, err := appApplication.APPApplicationSVC.GetPublishRecordDetail(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DraftProjectInnerTaskList .
// @router /api/intelligence_api/draft_project/inner_task_list [POST]
func DraftProjectInnerTaskList(ctx context.Context, c *app.RequestContext) {
var err error
var req task.DraftProjectInnerTaskListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
resp, err := appApplication.APPApplicationSVC.DraftProjectInnerTaskList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DraftProjectCopy .
// @router /api/intelligence_api/draft_project/copy [POST]
func DraftProjectCopy(ctx context.Context, c *app.RequestContext) {
var err error
var req project.DraftProjectCopyRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "invalid project id")
return
}
if req.ToSpaceID <= 0 {
invalidParamRequestResponse(c, "invalid to space id")
return
}
if req.Name == "" || len(req.Name) > 256 {
invalidParamRequestResponse(c, "invalid name")
return
}
if req.IconURI == "" || len(req.IconURI) > 512 {
invalidParamRequestResponse(c, "invalid icon uri")
return
}
resp, err := appApplication.APPApplicationSVC.DraftProjectCopy(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,528 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
dataset "github.com/coze-dev/coze-studio/backend/api/model/flow/dataengine/dataset"
application "github.com/coze-dev/coze-studio/backend/application/knowledge"
"github.com/coze-dev/coze-studio/backend/application/upload"
)
// CreateDataset .
// @router /api/knowledge/create [POST]
func CreateDataset(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.CreateDatasetRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.CreateDatasetResponse)
resp, err = application.KnowledgeSVC.CreateKnowledge(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DatasetDetail .
// @router /api/knowledge/detail [POST]
func DatasetDetail(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.DatasetDetailRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.DatasetDetailResponse)
resp, err = application.KnowledgeSVC.DatasetDetail(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListDataset .
// @router /api/knowledge/list [POST]
func ListDataset(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ListDatasetRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ListDatasetResponse)
resp, err = application.KnowledgeSVC.ListKnowledge(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeleteDataset .
// @router /api/knowledge/delete [POST]
func DeleteDataset(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.DeleteDatasetRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.DeleteDatasetResponse)
resp, err = application.KnowledgeSVC.DeleteKnowledge(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateDataset .
// @router /api/knowledge/update [POST]
func UpdateDataset(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.UpdateDatasetRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.UpdateDatasetResponse)
resp, err = application.KnowledgeSVC.UpdateKnowledge(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CreateDocument .
// @router /api/knowledge/document/create [POST]
func CreateDocument(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.CreateDocumentRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.CreateDocumentResponse)
resp, err = application.KnowledgeSVC.CreateDocument(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListDocument .
// @router /api/knowledge/document/list [POST]
func ListDocument(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ListDocumentRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ListDocumentResponse)
resp, err = application.KnowledgeSVC.ListDocument(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeleteDocument .
// @router /api/knowledge/document/delete [POST]
func DeleteDocument(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.DeleteDocumentRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.DeleteDocumentResponse)
resp, err = application.KnowledgeSVC.DeleteDocument(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateDocument .
// @router /api/knowledge/document/update [POST]
func UpdateDocument(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.UpdateDocumentRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.UpdateDocumentResponse)
resp, err = application.KnowledgeSVC.UpdateDocument(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDocumentProgress .
// @router /api/knowledge/document/progress/get [POST]
func GetDocumentProgress(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.GetDocumentProgressRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.GetDocumentProgressResponse)
resp, err = application.KnowledgeSVC.GetDocumentProgress(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// Resegment .
// @router /api/knowledge/document/resegment [POST]
func Resegment(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ResegmentRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ResegmentResponse)
resp, err = application.KnowledgeSVC.Resegment(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdatePhotoCaption .
// @router /api/knowledge/photo/caption [POST]
func UpdatePhotoCaption(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.UpdatePhotoCaptionRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.UpdatePhotoCaptionResponse)
resp, err = application.KnowledgeSVC.UpdatePhotoCaption(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListPhoto .
// @router /api/knowledge/photo/list [POST]
func ListPhoto(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ListPhotoRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ListPhotoResponse)
resp, err = application.KnowledgeSVC.ListPhoto(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PhotoDetail .
// @router /api/knowledge/photo/detail [POST]
func PhotoDetail(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.PhotoDetailRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.PhotoDetailResponse)
resp, err = application.KnowledgeSVC.PhotoDetail(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetTableSchema .
// @router /api/knowledge/table_schema/get [POST]
func GetTableSchema(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.GetTableSchemaRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.GetTableSchemaResponse)
resp, err = application.KnowledgeSVC.GetTableSchema(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ValidateTableSchema .
// @router /api/knowledge/table_schema/validate [POST]
func ValidateTableSchema(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ValidateTableSchemaRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ValidateTableSchemaResponse)
resp, err = application.KnowledgeSVC.ValidateTableSchema(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeleteSlice .
// @router /api/knowledge/slice/delete [POST]
func DeleteSlice(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.DeleteSliceRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.DeleteSliceResponse)
resp, err = application.KnowledgeSVC.DeleteSlice(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CreateSlice .
// @router /api/knowledge/slice/create [POST]
func CreateSlice(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.CreateSliceRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.CreateSliceResponse)
resp, err = application.KnowledgeSVC.CreateSlice(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateSlice .
// @router /api/knowledge/slice/update [POST]
func UpdateSlice(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.UpdateSliceRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.UpdateSliceResponse)
resp, err = application.KnowledgeSVC.UpdateSlice(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListSlice .
// @router /api/knowledge/slice/list [POST]
func ListSlice(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ListSliceRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ListSliceResponse)
resp, err = application.KnowledgeSVC.ListSlice(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CreateDocumentReview .
// @router /api/knowledge/review/create [POST]
func CreateDocumentReview(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.CreateDocumentReviewRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.CreateDocumentReviewResponse)
resp, err = application.KnowledgeSVC.CreateDocumentReview(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// MGetDocumentReview .
// @router /api/knowledge/review/mget [POST]
func MGetDocumentReview(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.MGetDocumentReviewRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.MGetDocumentReviewResponse)
resp, err = application.KnowledgeSVC.MGetDocumentReview(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// SaveDocumentReview .
// @router /api/knowledge/review/save [POST]
func SaveDocumentReview(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.SaveDocumentReviewRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.SaveDocumentReviewResponse)
resp, err = application.KnowledgeSVC.SaveDocumentReview(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetIconForDataset .
// @router /api/knowledge/icon/get [POST]
func GetIconForDataset(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.GetIconRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.GetIconResponse)
resp, err = upload.SVC.GetIconForDataset(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ExtractPhotoCaption .
// @router /api/knowledge/photo/extract_caption [POST]
func ExtractPhotoCaption(ctx context.Context, c *app.RequestContext) {
var err error
var req dataset.ExtractPhotoCaptionRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(dataset.ExtractPhotoCaptionResponse)
resp, err = application.KnowledgeSVC.ExtractPhotoCaption(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,277 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/knowledge/document"
"github.com/coze-dev/coze-studio/backend/api/model/kvmemory"
"github.com/coze-dev/coze-studio/backend/api/model/project_memory"
table "github.com/coze-dev/coze-studio/backend/api/model/table"
appApplication "github.com/coze-dev/coze-studio/backend/application/app"
"github.com/coze-dev/coze-studio/backend/application/knowledge"
"github.com/coze-dev/coze-studio/backend/application/memory"
"github.com/coze-dev/coze-studio/backend/pkg/lang/conv"
)
// GetSysVariableConf .
// @router /api/memory/sys_variable_conf [GET]
func GetSysVariableConf(ctx context.Context, c *app.RequestContext) {
var err error
var req kvmemory.GetSysVariableConfRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := memory.VariableApplicationSVC.GetSysVariableConf(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetProjectVariableList .
// @router /api/memory/project/variable/meta_list [GET]
func GetProjectVariableList(ctx context.Context, c *app.RequestContext) {
var err error
var req project_memory.GetProjectVariableListReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.ProjectID == "" {
invalidParamRequestResponse(c, "project_id is empty")
return
}
pID, err := conv.StrToInt64(req.ProjectID)
if err != nil {
invalidParamRequestResponse(c, "project_id is not int")
return
}
pInfo, err := appApplication.APPApplicationSVC.DomainSVC.GetDraftAPP(ctx, pID)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp, err := memory.VariableApplicationSVC.GetProjectVariablesMeta(ctx, pInfo.OwnerID, &req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateProjectVariable .
// @router /api/memory/project/variable/meta_update [POST]
func UpdateProjectVariable(ctx context.Context, c *app.RequestContext) {
var err error
var req project_memory.UpdateProjectVariableReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.ProjectID == "" {
invalidParamRequestResponse(c, "project_id is empty")
return
}
key2Var := make(map[string]*project_memory.Variable)
for _, v := range req.VariableList {
if v.Keyword == "" {
invalidParamRequestResponse(c, "variable name is empty")
return
}
if key2Var[v.Keyword] != nil {
invalidParamRequestResponse(c, "variable keyword is duplicate")
return
}
key2Var[v.Keyword] = v
}
resp, err := memory.VariableApplicationSVC.UpdateProjectVariable(ctx, req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// SetKvMemory .
// @router /api/memory/variable/upsert [POST]
func SetKvMemory(ctx context.Context, c *app.RequestContext) {
var err error
var req kvmemory.SetKvMemoryReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.BotID == 0 && req.GetProjectID() == "" {
invalidParamRequestResponse(c, "bot_id and project_id are both empty")
return
}
if len(req.Data) == 0 {
invalidParamRequestResponse(c, "data is empty")
return
}
resp, err := memory.VariableApplicationSVC.SetVariableInstance(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetMemoryVariableMeta .
// @router /api/memory/variable/get_meta [POST]
func GetMemoryVariableMeta(ctx context.Context, c *app.RequestContext) {
var err error
var req project_memory.GetMemoryVariableMetaReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := memory.VariableApplicationSVC.GetVariableMeta(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DelProfileMemory .
// @router /api/memory/variable/delete [POST]
func DelProfileMemory(ctx context.Context, c *app.RequestContext) {
var err error
var req kvmemory.DelProfileMemoryRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.BotID == 0 && req.GetProjectID() == "" {
invalidParamRequestResponse(c, "bot_id and project_id are both empty")
return
}
resp, err := memory.VariableApplicationSVC.DeleteVariableInstance(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPlayGroundMemory .
// @router /api/memory/variable/get [POST]
func GetPlayGroundMemory(ctx context.Context, c *app.RequestContext) {
var err error
var req kvmemory.GetProfileMemoryRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.BotID == 0 && req.GetProjectID() == "" {
invalidParamRequestResponse(c, "bot_id and project_id are both empty")
return
}
resp, err := memory.VariableApplicationSVC.GetPlayGroundMemory(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDocumentTableInfo .
// @router /api/memory/doc_table_info [GET]
func GetDocumentTableInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req document.GetDocumentTableInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(document.GetDocumentTableInfoResponse)
resp, err = knowledge.KnowledgeSVC.GetDocumentTableInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetModeConfig .
// @router /api/memory/table_mode_config [GET]
func GetModeConfig(ctx context.Context, c *app.RequestContext) {
var err error
var req table.GetModeConfigRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
if req.BotID == 0 {
invalidParamRequestResponse(c, "bot_id is zero")
return
}
resp, err := memory.DatabaseApplicationSVC.GetModeConfig(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,150 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package coze
import (
"context"
"errors"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/message"
application "github.com/coze-dev/coze-studio/backend/application/conversation"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
// GetMessageList .
// @router /api/conversation/get_message_list [POST]
func GetMessageList(ctx context.Context, c *app.RequestContext) {
var err error
var req message.GetMessageListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkMLParams(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
resp, err := application.ConversationSVC.GetMessageList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
func checkMLParams(ctx context.Context, req *message.GetMessageListRequest) error {
if req.BotID == "" {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "agent id is required"))
}
return nil
}
// DeleteMessage .
// @router /api/conversation/delete_message [POST]
func DeleteMessage(ctx context.Context, c *app.RequestContext) {
var err error
var req message.DeleteMessageRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkDMParams(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
resp, err := application.ConversationSVC.DeleteMessage(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
func checkDMParams(_ context.Context, req *message.DeleteMessageRequest) error {
if req.MessageID <= 0 {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "message id is invalid"))
}
return nil
}
// BreakMessage .
// @router /api/conversation/break_message [POST]
func BreakMessage(ctx context.Context, c *app.RequestContext) {
var err error
var req message.BreakMessageRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if checkErr := checkBMParams(ctx, &req); checkErr != nil {
invalidParamRequestResponse(c, checkErr.Error())
return
}
resp, err := application.ConversationSVC.BreakMessage(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
func checkBMParams(_ context.Context, req *message.BreakMessageRequest) error {
if req.AnswerMessageID == nil {
return errors.New("answer message id is required")
}
if *req.AnswerMessageID <= 0 {
return errorx.New(errno.ErrConversationInvalidParamCode, errorx.KV("msg", "answer message id is invalid"))
}
return nil
}
// GetApiMessageList .
// @router /v1/conversation/message/list [POST]
func GetApiMessageList(ctx context.Context, c *app.RequestContext) {
var err error
var req message.ListMessageApiRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := application.OpenapiMessageApplicationService.GetApiMessageList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,57 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package coze
import (
"bytes"
"context"
"net/http"
"testing"
"github.com/bytedance/sonic"
"github.com/cloudwego/hertz/pkg/app/server"
"github.com/cloudwego/hertz/pkg/common/ut"
"github.com/stretchr/testify/assert"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/message"
"github.com/coze-dev/coze-studio/backend/application"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
)
func TestGetMessageList(t *testing.T) {
h := server.Default()
err := application.Init(context.Background())
t.Logf("application init err: %v", err)
h.POST("/api/conversation/get_message_list", GetMessageList)
req := &message.GetMessageListRequest{
BotID: "7366055842027922437",
Scene: ptr.Of(common.Scene_Playground),
ConversationID: "7496795464885338112",
Count: 10,
Cursor: "1746534530268",
}
m, err := sonic.Marshal(req)
assert.Nil(t, err)
w := ut.PerformRequest(h.Engine, "POST", "/api/conversation/get_message_list", &ut.Body{Body: bytes.NewBuffer(m), Len: len(m)}, ut.Header{Key: "Content-Type", Value: "application/json"})
res := w.Result()
t.Logf("get message list: %s", res.Body())
assert.Equal(t, http.StatusInternalServerError, w.Code)
}

View File

@ -0,0 +1,169 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/permission/openapiauth"
openapiauthApp "github.com/coze-dev/coze-studio/backend/application/openauth"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
// GetPersonalAccessTokenAndPermission .
// @router /api/permission_api/pat/get_personal_access_token_and_permission [GET]
func GetPersonalAccessTokenAndPermission(ctx context.Context, c *app.RequestContext) {
var err error
var req openapiauth.GetPersonalAccessTokenAndPermissionRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ID == 0 {
invalidParamRequestResponse(c, "id is required")
return
}
resp, err := openapiauthApp.OpenAuthApplication.GetPersonalAccessTokenAndPermission(ctx, &req)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplicationService.GetPersonalAccessTokenAndPermission failed, err=%v", err)
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeletePersonalAccessTokenAndPermission .
// @router /api/permission_api/pat/delete_personal_access_token_and_permission [POST]
func DeletePersonalAccessTokenAndPermission(ctx context.Context, c *app.RequestContext) {
var err error
var req openapiauth.DeletePersonalAccessTokenAndPermissionRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ID <= 0 {
invalidParamRequestResponse(c, "id is required")
return
}
resp, err := openapiauthApp.OpenAuthApplication.DeletePersonalAccessTokenAndPermission(ctx, &req)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplication.DeletePersonalAccessTokenAndPermission failed, err=%v", err)
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ListPersonalAccessTokens .
// @router /api/permission_api/pat/list_personal_access_tokens [GET]
func ListPersonalAccessTokens(ctx context.Context, c *app.RequestContext) {
var err error
var req openapiauth.ListPersonalAccessTokensRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.Page == nil || *req.Page <= 0 {
req.Page = ptr.Of(int64(1))
}
if req.Size == nil || *req.Size <= 0 {
req.Size = ptr.Of(int64(10))
}
resp, err := openapiauthApp.OpenAuthApplication.ListPersonalAccessTokens(ctx, &req)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplication.ListPersonalAccessTokens failed, err=%v", err)
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CreatePersonalAccessTokenAndPermission .
// @router /api/permission_api/pat/create_personal_access_token_and_permission [POST]
func CreatePersonalAccessTokenAndPermission(ctx context.Context, c *app.RequestContext) {
var err error
var req openapiauth.CreatePersonalAccessTokenAndPermissionRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if err = checkCPATParams(ctx, &req); err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := openapiauthApp.OpenAuthApplication.CreatePersonalAccessToken(ctx, &req)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplicationService.CreatePersonalAccessToken failed, err=%v", err)
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// checkCPATParams 检查创建个人访问令牌的参数
func checkCPATParams(ctx context.Context, req *openapiauth.CreatePersonalAccessTokenAndPermissionRequest) error {
if req.Name == "" {
return errorx.New(errno.ErrPermissionInvalidParamCode, errorx.KV("msg", "name is required"))
}
return nil
}
// UpdatePersonalAccessTokenAndPermission .
// @router /api/permission_api/pat/update_personal_access_token_and_permission [POST]
func UpdatePersonalAccessTokenAndPermission(ctx context.Context, c *app.RequestContext) {
var err error
var req openapiauth.UpdatePersonalAccessTokenAndPermissionRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := openapiauthApp.OpenAuthApplication.UpdatePersonalAccessTokenAndPermission(ctx, &req)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplication.UpdatePersonalAccessTokenAndPermission failed, err=%v", err)
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,220 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"io"
"net/http"
"strings"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol"
"github.com/coze-dev/coze-studio/backend/api/model/passport"
"github.com/coze-dev/coze-studio/backend/application/user"
"github.com/coze-dev/coze-studio/backend/domain/user/entity"
"github.com/coze-dev/coze-studio/backend/pkg/hertzutil/domain"
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/types/consts"
)
// PassportWebEmailRegisterV2Post .
// @router /passport/web/email/register/v2/ [POST]
func PassportWebEmailRegisterV2Post(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.PassportWebEmailRegisterV2PostRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
locale := string(i18n.GetLocale(ctx))
resp, sessionKey, err := user.UserApplicationSVC.PassportWebEmailRegisterV2(ctx, locale, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.SetCookie(entity.SessionKey,
sessionKey,
consts.SessionMaxAgeSecond,
"/", domain.GetOriginHost(c),
protocol.CookieSameSiteDefaultMode,
false, true)
c.JSON(http.StatusOK, resp)
}
// PassportWebLogoutGet .
// @router /passport/web/logout/ [GET]
func PassportWebLogoutGet(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.PassportWebLogoutGetRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
resp, err := user.UserApplicationSVC.PassportWebLogoutGet(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(http.StatusOK, resp)
}
// PassportWebEmailLoginPost .
// @router /passport/web/email/login/ [POST]
func PassportWebEmailLoginPost(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.PassportWebEmailLoginPostRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
resp, sessionKey, err := user.UserApplicationSVC.PassportWebEmailLoginPost(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
logs.Infof("[PassportWebEmailLoginPost] sessionKey: %s", sessionKey)
c.SetCookie(entity.SessionKey,
sessionKey,
consts.SessionMaxAgeSecond,
"/", domain.GetOriginHost(c),
protocol.CookieSameSiteDefaultMode,
false, true)
c.JSON(http.StatusOK, resp)
}
// PassportWebEmailPasswordResetGet .
// @router /passport/web/email/password/reset/ [GET]
func PassportWebEmailPasswordResetGet(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.PassportWebEmailPasswordResetGetRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
resp, err := user.UserApplicationSVC.PassportWebEmailPasswordResetGet(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(http.StatusOK, resp)
}
// PassportAccountInfoV2 .
// @router /passport/account/info/v2/ [POST]
func PassportAccountInfoV2(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.PassportAccountInfoV2Request
err = c.BindAndValidate(&req)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
resp, err := user.UserApplicationSVC.PassportAccountInfoV2(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(http.StatusOK, resp)
}
// UserUpdateAvatar .
// @router web/user/update/upload_avatar/ [POST]
func UserUpdateAvatar(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.UserUpdateAvatarRequest
// 获取上传的文件
file, err := c.FormFile("avatar")
if err != nil {
logs.CtxErrorf(ctx, "Get Avatar Fail failed, err=%v", err)
invalidParamRequestResponse(c, "missing avatar file")
return
}
// 检查文件类型
if !strings.HasPrefix(file.Header.Get("Content-Type"), "image/") {
invalidParamRequestResponse(c, "invalid file type, only image allowed")
return
}
// 读取文件内容
src, err := file.Open()
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
defer src.Close()
fileContent, err := io.ReadAll(src)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
req.Avatar = fileContent
mimeType := file.Header.Get("Content-Type")
resp, err := user.UserApplicationSVC.UserUpdateAvatar(ctx, mimeType, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(http.StatusOK, resp)
}
// UserUpdateProfile .
// @router api/user/update_profile [POST]
func UserUpdateProfile(ctx context.Context, c *app.RequestContext) {
var err error
var req passport.UserUpdateProfileRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(http.StatusBadRequest, err.Error())
return
}
resp, err := user.UserApplicationSVC.UserUpdateProfile(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(http.StatusOK, resp)
}

View File

@ -0,0 +1,413 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/playground"
appApplication "github.com/coze-dev/coze-studio/backend/application/app"
"github.com/coze-dev/coze-studio/backend/application/prompt"
"github.com/coze-dev/coze-studio/backend/application/shortcutcmd"
"github.com/coze-dev/coze-studio/backend/application/singleagent"
"github.com/coze-dev/coze-studio/backend/application/upload"
"github.com/coze-dev/coze-studio/backend/application/user"
)
// UpdateDraftBotInfoAgw .
// @router /api/playground_api/draftbot/update_draft_bot_info [POST]
func UpdateDraftBotInfoAgw(ctx context.Context, c *app.RequestContext) {
var req playground.UpdateDraftBotInfoAgwRequest
err := c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.BotInfo == nil {
invalidParamRequestResponse(c, "bot info is nil")
return
}
if req.BotInfo.BotId == nil {
invalidParamRequestResponse(c, "bot id is nil")
return
}
resp, err := singleagent.SingleAgentSVC.UpdateSingleAgentDraft(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDraftBotInfoAgw .
// @router /api/playground_api/draftbot/get_draft_bot_info [POST]
func GetDraftBotInfoAgw(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetDraftBotInfoAgwRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.BotID == 0 {
invalidParamRequestResponse(c, "bot id is nil")
return
}
resp, err := singleagent.SingleAgentSVC.GetAgentBotInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetOfficialPromptResourceList .
// @router /api/playground_api/get_official_prompt_list [POST]
func GetOfficialPromptResourceList(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetOfficialPromptResourceListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := prompt.PromptSVC.GetOfficialPromptResourceList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPromptResourceInfo .
// @router /api/playground_api/get_prompt_resource_info [GET]
func GetPromptResourceInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetPromptResourceInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := prompt.PromptSVC.GetPromptResourceInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpsertPromptResource .
// @router /api/playground_api/upsert_prompt_resource [POST]
func UpsertPromptResource(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.UpsertPromptResourceRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.Prompt == nil {
invalidParamRequestResponse(c, "prompt is nil")
return
}
if req.Prompt.GetSpaceID() <= 0 {
invalidParamRequestResponse(c, "space id is invalid")
return
}
if len(req.Prompt.GetName()) <= 0 {
invalidParamRequestResponse(c, "name is empty")
return
}
resp, err := prompt.PromptSVC.UpsertPromptResource(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeletePromptResource .
// @router /api/playground_api/delete_prompt_resource [POST]
func DeletePromptResource(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.DeletePromptResourceRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := prompt.PromptSVC.DeletePromptResource(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetSpaceListV2 .
// @router /api/playground_api/space/list [POST]
func GetSpaceListV2(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetSpaceListV2Request
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := user.UserApplicationSVC.GetSpaceListV2(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetImagexShortUrl .
// @router /api/playground_api/get_imagex_url [POST]
func GetImagexShortUrl(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetImagexShortUrlRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if len(req.Uris) == 0 {
invalidParamRequestResponse(c, "uris is empty")
return
}
resp, err := singleagent.SingleAgentSVC.GetImagexShortUrl(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// MGetUserBasicInfo .
// @router /api/playground_api/mget_user_info [POST]
func MGetUserBasicInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.MGetUserBasicInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := user.UserApplicationSVC.MGetUserBasicInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetBotPopupInfo .
// @router /api/playground_api/operate/get_bot_popup_info [POST]
func GetBotPopupInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetBotPopupInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if len(req.BotPopupTypes) == 0 {
invalidParamRequestResponse(c, "bot popup types is empty")
return
}
resp, err := singleagent.SingleAgentSVC.GetAgentPopupInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateBotPopupInfo .
// @router /api/playground_api/operate/update_bot_popup_info [POST]
func UpdateBotPopupInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.UpdateBotPopupInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := singleagent.SingleAgentSVC.UpdateAgentPopupInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CreateUpdateShortcutCommand .
// @router /api/playground_api/create_update_shortcut_command [POST]
func CreateUpdateShortcutCommand(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.CreateUpdateShortcutCommandRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
shortCuts, err := shortcutcmd.ShortcutCmdSVC.Handler(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp := new(playground.CreateUpdateShortcutCommandResponse)
resp.Shortcuts = shortCuts
resp.Code = 0
resp.Msg = ""
c.JSON(consts.StatusOK, resp)
}
// ReportUserBehavior .
// @router /api/playground_api/report_user_behavior [POST]
func ReportUserBehavior(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.ReportUserBehaviorRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ResourceID <= 0 {
invalidParamRequestResponse(c, "resource id is invalid")
return
}
resp := new(playground.ReportUserBehaviorResponse)
if req.ResourceType == playground.SpaceResourceType_DraftBot {
resp, err = singleagent.SingleAgentSVC.ReportUserBehavior(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
} else if req.ResourceType == playground.SpaceResourceType_Project {
resp, err = appApplication.APPApplicationSVC.ReportUserBehavior(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
}
c.JSON(consts.StatusOK, resp)
}
// GetFileUrls .
// @router /api/playground_api/get_file_list [POST]
func GetFileUrls(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetFileUrlsRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
iconList, err := upload.SVC.GetShortcutIcons(ctx)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp := new(playground.GetFileUrlsResponse)
resp.FileList = iconList
resp.Code = 0
c.JSON(consts.StatusOK, resp)
}
// UploadFileOpen .
// @router /v1/files/upload [POST]
func UploadFileOpen(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.UploadFileOpenRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(playground.UploadFileOpenResponse)
resp, err = upload.SVC.UploadFileOpen(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetBotOnlineInfo .
// @router /v1/bot/get_online_info [GET]
func GetBotOnlineInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req playground.GetBotOnlineInfoReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp, err := singleagent.SingleAgentSVC.GetAgentOnlineInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,915 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"regexp"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/plugin_develop"
common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
"github.com/coze-dev/coze-studio/backend/application/plugin"
appworkflow "github.com/coze-dev/coze-studio/backend/application/workflow"
)
// GetPlaygroundPluginList .
// @router /api/plugin_api/get_playground_plugin_list [POST]
func GetPlaygroundPluginList(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetPlaygroundPluginListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.GetSpaceID() <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.GetPage() <= 0 {
invalidParamRequestResponse(c, "page is invalid")
return
}
if req.GetSize() >= 30 {
invalidParamRequestResponse(c, "size is invalid")
return
}
// when there is only one element in the types list, and the element type is workflow, use workflow service
// TODO Figure out when there are multiple values for types
if len(req.GetPluginTypes()) == 1 && req.GetPluginTypes()[0] == int32(common.PluginType_WORKFLOW) {
resp, err := appworkflow.SVC.GetPlaygroundPluginList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
return
}
resp, err := plugin.PluginApplicationSVC.GetPlaygroundPluginList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// RegisterPluginMeta .
// @router /api/plugin_api/register_plugin_meta [POST]
func RegisterPluginMeta(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.RegisterPluginMetaRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.GetName() == "" {
invalidParamRequestResponse(c, "plugin name is invalid")
return
}
if req.GetDesc() == "" {
invalidParamRequestResponse(c, "plugin desc is invalid")
return
}
if req.URL != nil && (*req.URL == "" || len(*req.URL) > 512) {
invalidParamRequestResponse(c, "plugin url is invalid")
return
}
if req.Icon == nil || req.Icon.URI == "" || len(req.Icon.URI) > 512 {
invalidParamRequestResponse(c, "plugin icon is invalid")
return
}
if req.AuthType == nil {
invalidParamRequestResponse(c, "plugin auth type is invalid")
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.ProjectID != nil {
if *req.ProjectID <= 0 {
invalidParamRequestResponse(c, "projectID is invalid")
return
}
}
if req.GetPluginType() != common.PluginType_PLUGIN {
invalidParamRequestResponse(c, "plugin type is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.RegisterPluginMeta(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPluginAPIs .
// @router /api/plugin_api/get_plugin_apis [POST]
func GetPluginAPIs(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetPluginAPIsRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if len(req.APIIds) == 0 {
if req.Page <= 0 {
invalidParamRequestResponse(c, "page is invalid")
return
}
if req.Size >= 30 {
invalidParamRequestResponse(c, "size is invalid")
return
}
}
resp, err := plugin.PluginApplicationSVC.GetPluginAPIs(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPluginInfo .
// @router /api/plugin_api/get_plugin_info [POST]
func GetPluginInfo(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetPluginInfoRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.GetPluginInfo(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetUpdatedAPIs .
// @router /api/plugin_api/get_updated_apis [POST]
func GetUpdatedAPIs(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetUpdatedAPIsRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.GetUpdatedAPIs(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetOAuthStatus .
// @router /api/plugin_api/get_oauth_status [POST]
func GetOAuthStatus(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetOAuthStatusRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.GetOAuthStatus(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CheckAndLockPluginEdit .
// @router /api/plugin_api/check_and_lock_plugin_edit [POST]
func CheckAndLockPluginEdit(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.CheckAndLockPluginEditRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.CheckAndLockPluginEdit(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdatePlugin .
// @router /api/plugin_api/update [POST]
func UpdatePlugin(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.UpdatePluginRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.AiPlugin == "" {
invalidParamRequestResponse(c, "plugin manifest is invalid")
return
}
if req.Openapi == "" {
invalidParamRequestResponse(c, "plugin openapi doc is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.UpdatePlugin(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DeleteAPI .
// @router /api/plugin_api/delete_api [POST]
func DeleteAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.DeleteAPIRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.APIID <= 0 {
invalidParamRequestResponse(c, "apiID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.DeleteAPI(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DelPlugin .
// @router /api/plugin_api/del_plugin [POST]
func DelPlugin(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.DelPluginRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.DelPlugin(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PublishPlugin .
// @router /api/plugin_api/publish_plugin [POST]
func PublishPlugin(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.PublishPluginRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.VersionName == "" || len(req.VersionName) > 255 {
invalidParamRequestResponse(c, "version name is invalid")
return
}
match, _ := regexp.MatchString(`^v\d+\.\d+\.\d+$`, req.VersionName)
if !match {
invalidParamRequestResponse(c, "version name is invalid")
return
}
if req.VersionDesc == "" {
invalidParamRequestResponse(c, "version desc is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.PublishPlugin(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdatePluginMeta .
// @router /api/plugin_api/update_plugin_meta [POST]
func UpdatePluginMeta(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.UpdatePluginMetaRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.Name != nil && *req.Name == "" {
invalidParamRequestResponse(c, "plugin name is invalid")
return
}
if req.Desc != nil && *req.Desc == "" {
invalidParamRequestResponse(c, "plugin desc is invalid")
return
}
if req.URL != nil && (*req.URL == "" || len(*req.URL) > 512) {
invalidParamRequestResponse(c, "plugin server url is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.UpdatePluginMeta(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetBotDefaultParams .
// @router /api/plugin_api/get_bot_default_params [POST]
func GetBotDefaultParams(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetBotDefaultParamsRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.BotID <= 0 {
invalidParamRequestResponse(c, "botID is invalid")
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.APIName == "" {
invalidParamRequestResponse(c, "apiName is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.GetBotDefaultParams(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateBotDefaultParams .
// @router /api/plugin_api/update_bot_default_params [POST]
func UpdateBotDefaultParams(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.UpdateBotDefaultParamsRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.BotID <= 0 {
invalidParamRequestResponse(c, "botID is invalid")
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.APIName == "" {
invalidParamRequestResponse(c, "apiName is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.UpdateBotDefaultParams(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// CreateAPI .
// @router /api/plugin_api/create_api [POST]
func CreateAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.CreateAPIRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.Name == "" || len(req.Name) > 255 {
invalidParamRequestResponse(c, "api name is invalid")
return
}
if req.Desc == "" {
invalidParamRequestResponse(c, "api desc is invalid")
return
}
if req.Path != nil && (*req.Path == "" || len(*req.Path) > 512) {
invalidParamRequestResponse(c, "api path is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.CreateAPI(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UpdateAPI .
// @router /api/plugin_api/update_api [POST]
func UpdateAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.UpdateAPIRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.APIID <= 0 {
invalidParamRequestResponse(c, "apiID is invalid")
return
}
if req.Name != nil && (*req.Name == "" || len(*req.Name) > 255) {
invalidParamRequestResponse(c, "api name is invalid")
return
}
if req.Desc != nil && (*req.Desc == "" || len(*req.Desc) > 255) {
invalidParamRequestResponse(c, "api desc is invalid")
return
}
if req.Path != nil && (*req.Path == "" || len(*req.Path) > 512) {
invalidParamRequestResponse(c, "api path is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.UpdateAPI(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetUserAuthority .
// @router /api/plugin_api/get_user_authority [POST]
func GetUserAuthority(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetUserAuthorityRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.GetUserAuthority(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// DebugAPI .
// @router /api/plugin_api/debug_api [POST]
func DebugAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.DebugAPIRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.APIID <= 0 {
invalidParamRequestResponse(c, "apiID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.DebugAPI(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// UnlockPluginEdit .
// @router /api/plugin_api/unlock_plugin_edit [POST]
func UnlockPluginEdit(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.UnlockPluginEditRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := plugin.PluginApplicationSVC.UnlockPluginEdit(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetPluginNextVersion .
// @router /api/plugin_api/get_plugin_next_version [POST]
func GetPluginNextVersion(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetPluginNextVersionRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := plugin.PluginApplicationSVC.GetPluginNextVersion(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// RegisterPlugin .
// @router /api/developer/register [POST]
func RegisterPlugin(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.RegisterPluginRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.GetSpaceID() <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.ProjectID != nil && *req.ProjectID <= 0 {
invalidParamRequestResponse(c, "projectID is invalid")
return
}
if req.AiPlugin == "" {
invalidParamRequestResponse(c, "plugin manifest is invalid")
return
}
if req.Openapi == "" {
invalidParamRequestResponse(c, "plugin openapi doc is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.RegisterPlugin(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetDevPluginList .
// @router /api/plugin_api/get_dev_plugin_list [POST]
func GetDevPluginList(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetDevPluginListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "projectID is invalid")
return
}
if req.GetPage() <= 0 {
invalidParamRequestResponse(c, "page is invalid")
return
}
if req.GetSize() <= 0 {
invalidParamRequestResponse(c, "size is invalid")
return
}
if req.GetSize() > 50 {
invalidParamRequestResponse(c, "size is too large")
return
}
resp, err := plugin.PluginApplicationSVC.GetDevPluginList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// Convert2OpenAPI .
// @router /api/plugin_api/convert_to_openapi [POST]
func Convert2OpenAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.Convert2OpenAPIRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.Data == "" {
invalidParamRequestResponse(c, "data is invalid")
return
}
if req.PluginURL != nil && *req.PluginURL == "" {
invalidParamRequestResponse(c, "pluginURL is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.Convert2OpenAPI(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetOAuthSchemaAPI .
// @router /api/plugin_api/get_oauth_schema [POST]
func GetOAuthSchemaAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetOAuthSchemaRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := plugin.PluginApplicationSVC.GetOAuthSchema(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetOAuthSchema .
// @router /api/plugin/get_oauth_schema [POST]
func GetOAuthSchema(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetOAuthSchemaRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp, err := plugin.PluginApplicationSVC.GetOAuthSchema(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// BatchCreateAPI .
// @router /api/plugin_api/batch_create_api [POST]
func BatchCreateAPI(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.BatchCreateAPIRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "spaceID is invalid")
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
if req.AiPlugin == "" {
invalidParamRequestResponse(c, "plugin manifest is invalid")
return
}
if req.Openapi == "" {
invalidParamRequestResponse(c, "plugin openapi doc is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.BatchCreateAPI(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// RevokeAuthToken .
// @router /api/plugin_api/revoke_auth_token [POST]
func RevokeAuthToken(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.RevokeAuthTokenRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.PluginID <= 0 {
invalidParamRequestResponse(c, "pluginID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.RevokeAuthToken(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// GetQueriedOAuthPluginList .
// @router /api/plugin_api/get_queried_oauth_plugins [POST]
func GetQueriedOAuthPluginList(ctx context.Context, c *app.RequestContext) {
var err error
var req plugin_develop.GetQueriedOAuthPluginListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.BotID <= 0 {
invalidParamRequestResponse(c, "entityID is required")
return
}
resp, err := plugin.PluginApplicationSVC.GetQueriedOAuthPluginList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,269 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"strconv"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
appworkflow "github.com/coze-dev/coze-studio/backend/application/workflow"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/developer_api"
"github.com/coze-dev/coze-studio/backend/api/model/flow/marketplace/product_common"
"github.com/coze-dev/coze-studio/backend/api/model/flow/marketplace/product_public_api"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/bot_common"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/playground"
appApplication "github.com/coze-dev/coze-studio/backend/application/app"
"github.com/coze-dev/coze-studio/backend/application/modelmgr"
"github.com/coze-dev/coze-studio/backend/application/plugin"
"github.com/coze-dev/coze-studio/backend/application/search"
"github.com/coze-dev/coze-studio/backend/application/singleagent"
"github.com/coze-dev/coze-studio/backend/application/template"
)
// PublicGetProductList .
// @router /api/marketplace/product/list [GET]
func PublicGetProductList(ctx context.Context, c *app.RequestContext) {
var err error
var req product_public_api.GetProductListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
var resp *product_public_api.GetProductListResponse
switch req.GetEntityType() {
case product_common.ProductEntityType_Plugin:
resp, err = plugin.PluginApplicationSVC.PublicGetProductList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
case product_common.ProductEntityType_TemplateCommon:
resp, err = template.ApplicationSVC.PublicGetProductList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
}
c.JSON(consts.StatusOK, resp)
}
// PublicGetProductDetail .
// @router /api/marketplace/product/detail [GET]
func PublicGetProductDetail(ctx context.Context, c *app.RequestContext) {
var err error
var req product_public_api.GetProductDetailRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.GetProductID() <= 0 {
invalidParamRequestResponse(c, "productID is invalid")
return
}
resp, err := plugin.PluginApplicationSVC.PublicGetProductDetail(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PublicFavoriteProduct .
// @router /api/marketplace/product/favorite [POST]
func PublicFavoriteProduct(ctx context.Context, c *app.RequestContext) {
var err error
var req product_public_api.FavoriteProductRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.GetEntityID() <= 0 {
invalidParamRequestResponse(c, "entityID is invalid")
return
}
// check entity id is valid
if req.GetEntityType() == product_common.ProductEntityType_Bot {
_, err = singleagent.SingleAgentSVC.ValidateAgentDraftAccess(ctx, req.GetEntityID())
} else if req.GetEntityType() == product_common.ProductEntityType_Project {
_, err = appApplication.APPApplicationSVC.ValidateDraftAPPAccess(ctx, req.GetEntityID())
}
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp, err := search.SearchSVC.PublicFavoriteProduct(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PublicGetUserFavoriteListV2 .
// @router /api/marketplace/product/favorite/list.v2 [GET]
func PublicGetUserFavoriteListV2(ctx context.Context, c *app.RequestContext) {
var err error
var req product_public_api.GetUserFavoriteListV2Request
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.GetPageSize() <= 0 {
invalidParamRequestResponse(c, "pageSize is invalid")
return
}
if req.GetEntityType() <= 0 {
invalidParamRequestResponse(c, "entityType is invalid")
return
}
resp, err := search.SearchSVC.PublicGetUserFavoriteList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// PublicDuplicateProduct .
// @router /api/marketplace/product/duplicate [POST]
func PublicDuplicateProduct(ctx context.Context, c *app.RequestContext) {
var err error
var req product_public_api.DuplicateProductRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp := new(product_public_api.DuplicateProductResponse)
resp.Data = new(product_public_api.DuplicateProductData)
switch req.GetEntityType() {
case product_common.ProductEntityType_BotTemplate:
modelListResp, err := modelmgr.ModelmgrApplicationSVC.GetModelList(ctx, &developer_api.GetTypeListRequest{})
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
if modelListResp == nil || modelListResp.Data == nil || len(modelListResp.Data.ModelList) == 0 {
invalidParamRequestResponse(c, "no model found")
return
}
bot, err := singleagent.SingleAgentSVC.DuplicateDraftBot(ctx, &developer_api.DuplicateDraftBotRequest{
BotID: req.GetProductID(),
SpaceID: req.GetSpaceID(),
})
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
botInfo, err := singleagent.SingleAgentSVC.GetAgentBotInfo(ctx, &playground.GetDraftBotInfoAgwRequest{
BotID: bot.Data.BotID,
})
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
if botInfo.Data == nil || botInfo.Data.BotInfo == nil {
invalidParamRequestResponse(c, "no bot info found")
return
}
modelInfo := botInfo.GetData().GetBotInfo().GetModelInfo()
if modelInfo == nil {
invalidParamRequestResponse(c, "no model info found in agent")
return
}
modelInfo.ModelId = &modelListResp.Data.ModelList[0].ModelType
if req.Name != nil {
_, err = singleagent.SingleAgentSVC.UpdateSingleAgentDraft(ctx, &playground.UpdateDraftBotInfoAgwRequest{
BotInfo: &bot_common.BotInfoForUpdate{
BotId: &bot.Data.BotID,
Name: req.Name,
ModelInfo: modelInfo,
},
})
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
}
resp.Data.NewEntityID = bot.Data.BotID
case product_common.ProductEntityType_WorkflowTemplateV2:
workflowResp, err := appworkflow.SVC.CopyWorkflow(ctx, &workflow.CopyWorkflowRequest{
WorkflowID: strconv.FormatInt(req.GetProductID(), 10),
SpaceID: strconv.FormatInt(req.GetSpaceID(), 10),
})
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
newWorkflowID, err := strconv.ParseInt(workflowResp.Data.WorkflowID, 10, 64)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
resp.Data.NewEntityID = newWorkflowID
resp.Data.NewPluginID = &newWorkflowID
if req.Name != nil {
_, err = appworkflow.SVC.UpdateWorkflowMeta(ctx, &workflow.UpdateWorkflowMetaRequest{
WorkflowID: workflowResp.Data.WorkflowID,
SpaceID: strconv.FormatInt(req.GetSpaceID(), 10),
Name: req.Name,
})
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
}
}
c.JSON(consts.StatusOK, resp)
}

View File

@ -0,0 +1,179 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Code generated by hertz generator.
package coze
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/protocol/consts"
appApplication "github.com/coze-dev/coze-studio/backend/application/app"
resource "github.com/coze-dev/coze-studio/backend/api/model/resource"
"github.com/coze-dev/coze-studio/backend/application/search"
)
// LibraryResourceList .
// @router /api/plugin_api/library_resource_list [POST]
func LibraryResourceList(ctx context.Context, c *app.RequestContext) {
var err error
var req resource.LibraryResourceListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "space_id is invalid")
return
}
if req.GetSize() > 100 {
invalidParamRequestResponse(c, "size is too large")
return
}
resp, err := search.SearchSVC.LibraryResourceList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ProjectResourceList .
// @router /api/plugin_api/project_resource_list [POST]
func ProjectResourceList(ctx context.Context, c *app.RequestContext) {
var err error
var req resource.ProjectResourceListRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.SpaceID <= 0 {
invalidParamRequestResponse(c, "space_id is invalid")
return
}
if req.ProjectID <= 0 {
invalidParamRequestResponse(c, "project_id is invalid")
return
}
resp, err := search.SearchSVC.ProjectResourceList(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ResourceCopyDispatch .
// @router /api/plugin_api/resource_copy_dispatch [POST]
func ResourceCopyDispatch(ctx context.Context, c *app.RequestContext) {
var err error
var req resource.ResourceCopyDispatchRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.ResID <= 0 {
invalidParamRequestResponse(c, "res_id is invalid")
return
}
if req.ResType <= 0 {
invalidParamRequestResponse(c, "res_type is invalid")
return
}
if req.GetProjectID() <= 0 {
invalidParamRequestResponse(c, "project_id is invalid")
return
}
resp, err := appApplication.APPApplicationSVC.ResourceCopyDispatch(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ResourceCopyDetail .
// @router /api/plugin_api/resource_copy_detail [POST]
func ResourceCopyDetail(ctx context.Context, c *app.RequestContext) {
var err error
var req resource.ResourceCopyDetailRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
if req.TaskID == "" {
invalidParamRequestResponse(c, "task_id is invalid")
return
}
resp, err := appApplication.APPApplicationSVC.ResourceCopyDetail(ctx, &req)
if err != nil {
internalServerErrorResponse(ctx, c, err)
return
}
c.JSON(consts.StatusOK, resp)
}
// ResourceCopyRetry .
// @router /api/plugin_api/resource_copy_retry [POST]
func ResourceCopyRetry(ctx context.Context, c *app.RequestContext) {
var err error
var req resource.ResourceCopyRetryRequest
err = c.BindAndValidate(&req)
if err != nil {
invalidParamRequestResponse(c, err.Error())
return
}
resp := new(resource.ResourceCopyRetryResponse)
c.JSON(consts.StatusOK, resp)
}
// ResourceCopyCancel .
// @router /api/plugin_api/resource_copy_cancel [POST]
func ResourceCopyCancel(ctx context.Context, c *app.RequestContext) {
var err error
var req resource.ResourceCopyCancelRequest
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
resp := new(resource.ResourceCopyCancelResponse)
c.JSON(consts.StatusOK, resp)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package httputil
import (
"context"
"errors"
"net/http"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
)
type data struct {
Code int32 `json:"code"`
Msg string `json:"msg"`
}
func BadRequest(c *app.RequestContext, errMsg string) {
c.AbortWithStatusJSON(http.StatusBadRequest, data{Code: http.StatusBadRequest, Msg: errMsg})
}
func InternalError(ctx context.Context, c *app.RequestContext, err error) {
var customErr errorx.StatusError
if errors.As(err, &customErr) && customErr.Code() != 0 {
logs.CtxWarnf(ctx, "[ErrorX] error: %v %v \n", customErr.Code(), err)
c.AbortWithStatusJSON(http.StatusOK, data{Code: customErr.Code(), Msg: customErr.Msg()})
return
}
logs.CtxErrorf(ctx, "[InternalError] error: %v \n", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, data{Code: 500, Msg: "internal server error"})
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/cloudwego/hertz/pkg/app"
)
func ContextCacheMW() app.HandlerFunc {
return func(c context.Context, ctx *app.RequestContext) {
c = ctxcache.Init(c)
ctx.Next(c)
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/types/consts"
)
func SetHostMW() app.HandlerFunc {
return func(c context.Context, ctx *app.RequestContext) {
ctxcache.Store(c, consts.HostKeyInCtx, string(ctx.Host()))
ctxcache.Store(c, consts.RequestSchemeKeyInCtx, string(ctx.GetRequest().Scheme()))
ctx.Next(c)
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"strings"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/domain/user/entity"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
"github.com/coze-dev/coze-studio/backend/types/consts"
)
func I18nMW() app.HandlerFunc {
return func(c context.Context, ctx *app.RequestContext) {
session, ok := ctxcache.Get[*entity.Session](c, consts.SessionDataKeyInCtx)
if ok {
c = i18n.SetLocale(c, session.Locale)
ctx.Next(c)
return
}
acceptLanguage := string(ctx.Request.Header.Get("Accept-Language"))
locale := "en-US"
if acceptLanguage != "" {
languages := strings.Split(acceptLanguage, ",")
if len(languages) > 0 {
locale = languages[0]
}
}
c = i18n.SetLocale(c, locale)
ctx.Next(c)
}
}

View File

@ -0,0 +1,96 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"fmt"
"net/http"
"path/filepath"
"strings"
"time"
"unsafe"
"github.com/cloudwego/hertz/pkg/app"
"github.com/google/uuid"
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
)
func AccessLogMW() app.HandlerFunc {
return func(c context.Context, ctx *app.RequestContext) {
start := time.Now()
ctx.Next(c)
status := ctx.Response.StatusCode()
path := bytesToString(ctx.Request.URI().PathOriginal())
latency := time.Since(start)
method := bytesToString(ctx.Request.Header.Method())
clientIP := ctx.ClientIP()
handlerPkgPath := strings.Split(ctx.HandlerName(), "/")
handleName := ""
if len(handlerPkgPath) > 0 {
handleName = handlerPkgPath[len(handlerPkgPath)-1]
}
requestType := ctx.GetInt32(RequestAuthTypeStr)
baseLog := fmt.Sprintf("| %s | %s | %d | %v | %s | %s | %v | %s | %d %s",
string(ctx.GetRequest().Scheme()), ctx.Host(), status,
latency, clientIP, method, path, handleName, requestType, i18n.GetLocale(c))
switch {
case status >= http.StatusInternalServerError:
logs.CtxErrorf(c, "%s", baseLog)
case status >= http.StatusBadRequest:
logs.CtxWarnf(c, "%s", baseLog)
default:
urlQuery := ctx.Request.URI().QueryString()
reqBody := bytesToString(ctx.Request.Body())
respBody := bytesToString(ctx.Response.Body())
maxPrintLen := 3 * 1024
if len(respBody) > maxPrintLen {
respBody = respBody[:maxPrintLen]
}
if len(reqBody) > maxPrintLen {
reqBody = reqBody[:maxPrintLen]
}
requestAuthType := ctx.GetInt32(RequestAuthTypeStr)
if requestAuthType != int32(RequestAuthTypeStaticFile) && filepath.Ext(path) == "" {
logs.CtxInfof(c, "%s ", baseLog)
logs.CtxDebugf(c, "query : %s \nreq : %s \nresp: %s",
urlQuery, reqBody, respBody)
}
}
}
}
func SetLogIDMW() app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
logID := uuid.New().String()
ctx = context.WithValue(ctx, "log-id", logID)
c.Header("X-Log-ID", logID)
c.Next(ctx)
}
}
func bytesToString(b []byte) string {
return *(*string)(unsafe.Pointer(&b)) // nolint
}

View File

@ -0,0 +1,141 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"crypto/md5"
"encoding/hex"
"regexp"
"strings"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/api/internal/httputil"
"github.com/coze-dev/coze-studio/backend/application/openauth"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/pkg/lang/conv"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/types/consts"
"github.com/coze-dev/coze-studio/backend/types/errno"
)
const HeaderAuthorizationKey = "Authorization"
var needAuthPath = map[string]bool{
"/v3/chat": true,
"/v1/conversations": true,
"/v1/conversation/create": true,
"/v1/conversation/message/list": true,
"/v1/files/upload": true,
"/v1/workflow/run": true,
"/v1/workflow/stream_run": true,
"/v1/workflow/stream_resume": true,
"/v1/workflow/get_run_history": true,
"/v1/bot/get_online_info": true,
}
var needAuthFunc = map[string]bool{
"^/v1/conversations/[0-9]+/clear$": true, // v1/conversations/:conversation_id/clear
}
func parseBearerAuthToken(authHeader string) string {
if len(authHeader) == 0 {
return ""
}
parts := strings.Split(authHeader, "Bearer")
if len(parts) != 2 {
return ""
}
token := strings.TrimSpace(parts[1])
if len(token) == 0 {
return ""
}
return token
}
func isNeedOpenapiAuth(c *app.RequestContext) bool {
isNeedAuth := false
uriPath := c.URI().Path()
for rule, res := range needAuthFunc {
if regexp.MustCompile(rule).MatchString(string(uriPath)) {
isNeedAuth = res
break
}
}
if needAuthPath[string(c.GetRequest().URI().Path())] {
isNeedAuth = true
}
return isNeedAuth
}
func OpenapiAuthMW() app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
requestAuthType := c.GetInt32(RequestAuthTypeStr)
if requestAuthType != int32(RequestAuthTypeOpenAPI) {
c.Next(ctx)
return
}
// open api auth
if len(c.Request.Header.Get(HeaderAuthorizationKey)) == 0 {
httputil.InternalError(ctx, c,
errorx.New(errno.ErrUserAuthenticationFailed, errorx.KV("reason", "missing authorization in header")))
return
}
apiKey := parseBearerAuthToken(c.Request.Header.Get(HeaderAuthorizationKey))
if len(apiKey) == 0 {
httputil.InternalError(ctx, c,
errorx.New(errno.ErrUserAuthenticationFailed, errorx.KV("reason", "missing api_key in request")))
return
}
md5Hash := md5.Sum([]byte(apiKey))
md5Key := hex.EncodeToString(md5Hash[:])
apiKeyInfo, err := openauth.OpenAuthApplication.CheckPermission(ctx, md5Key)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplication.CheckPermission failed, err=%v", err)
httputil.InternalError(ctx, c,
errorx.New(errno.ErrUserAuthenticationFailed, errorx.KV("reason", err.Error())))
return
}
if apiKeyInfo == nil {
httputil.InternalError(ctx, c,
errorx.New(errno.ErrUserAuthenticationFailed, errorx.KV("reason", "api key invalid")))
return
}
apiKeyInfo.ConnectorID = consts.APIConnectorID
logs.CtxInfof(ctx, "OpenapiAuthMW: apiKeyInfo=%v", conv.DebugJsonToStr(apiKeyInfo))
ctxcache.Store(ctx, consts.OpenapiAuthKeyInCtx, apiKeyInfo)
err = openauth.OpenAuthApplication.UpdateLastUsedAt(ctx, apiKeyInfo.ID, apiKeyInfo.UserID)
if err != nil {
logs.CtxErrorf(ctx, "OpenAuthApplication.UpdateLastUsedAt failed, err=%v", err)
}
c.Next(ctx)
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"strings"
"github.com/cloudwego/hertz/pkg/app"
)
const RequestAuthTypeStr = "RequestAuthTypeStr"
type RequestAuthType = int32
const (
RequestAuthTypeWebAPI RequestAuthType = 0
RequestAuthTypeOpenAPI RequestAuthType = 1
RequestAuthTypeStaticFile RequestAuthType = 2
)
func RequestInspectorMW() app.HandlerFunc {
return func(c context.Context, ctx *app.RequestContext) {
authType := RequestAuthTypeWebAPI // default is web api, session auth
if isNeedOpenapiAuth(ctx) {
authType = RequestAuthTypeOpenAPI
} else if isStaticFile(ctx) {
authType = RequestAuthTypeStaticFile
}
ctx.Set(RequestAuthTypeStr, authType)
ctx.Next(c)
}
}
var staticFilePath = map[string]bool{
"/static": true,
"/": true,
"/sign": true,
"/favicon.png": true,
}
func isStaticFile(ctx *app.RequestContext) bool {
path := string(ctx.GetRequest().URI().Path())
if staticFilePath[path] {
return true
}
if strings.HasPrefix(string(path), "/static/") ||
strings.HasPrefix(string(path), "/explore/") ||
strings.HasPrefix(string(path), "/space/") {
return true
}
return false
}

View File

@ -0,0 +1,75 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package middleware
import (
"context"
"github.com/cloudwego/hertz/pkg/app"
"github.com/coze-dev/coze-studio/backend/domain/user/entity"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/types/errno"
"github.com/coze-dev/coze-studio/backend/api/internal/httputil"
"github.com/coze-dev/coze-studio/backend/application/user"
"github.com/coze-dev/coze-studio/backend/pkg/ctxcache"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/types/consts"
)
var noNeedSessionCheckPath = map[string]bool{
"/api/passport/web/email/login/": true,
"/api/passport/web/email/register/v2/": true,
}
func SessionAuthMW() app.HandlerFunc {
return func(c context.Context, ctx *app.RequestContext) {
requestAuthType := ctx.GetInt32(RequestAuthTypeStr)
if requestAuthType != int32(RequestAuthTypeWebAPI) {
ctx.Next(c)
return
}
if noNeedSessionCheckPath[string(ctx.GetRequest().URI().Path())] {
ctx.Next(c)
return
}
s := ctx.Cookie(entity.SessionKey)
if len(s) == 0 {
logs.Errorf("[SessionAuthMW] session id is nil")
httputil.InternalError(c, ctx,
errorx.New(errno.ErrUserAuthenticationFailed, errorx.KV("reason", "missing session_key in cookie")))
return
}
// sessionID -> sessionData
session, err := user.UserApplicationSVC.ValidateSession(c, string(s))
if err != nil {
logs.Errorf("[SessionAuthMW] validate session failed, err: %v", err)
httputil.InternalError(c, ctx, err)
return
}
if session != nil {
ctxcache.Store(c, consts.SessionDataKeyInCtx, session)
}
ctx.Next(c)
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,765 @@
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
package common
import (
"database/sql"
"database/sql/driver"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
type ColumnType int64
const (
ColumnType_Unknown ColumnType = 0
// 文本
ColumnType_Text ColumnType = 1
// 数字
ColumnType_Number ColumnType = 2
// 时间
ColumnType_Date ColumnType = 3
// float
ColumnType_Float ColumnType = 4
// bool
ColumnType_Boolean ColumnType = 5
// 图片
ColumnType_Image ColumnType = 6
)
func (p ColumnType) String() string {
switch p {
case ColumnType_Unknown:
return "Unknown"
case ColumnType_Text:
return "Text"
case ColumnType_Number:
return "Number"
case ColumnType_Date:
return "Date"
case ColumnType_Float:
return "Float"
case ColumnType_Boolean:
return "Boolean"
case ColumnType_Image:
return "Image"
}
return "<UNSET>"
}
func ColumnTypeFromString(s string) (ColumnType, error) {
switch s {
case "Unknown":
return ColumnType_Unknown, nil
case "Text":
return ColumnType_Text, nil
case "Number":
return ColumnType_Number, nil
case "Date":
return ColumnType_Date, nil
case "Float":
return ColumnType_Float, nil
case "Boolean":
return ColumnType_Boolean, nil
case "Image":
return ColumnType_Image, nil
}
return ColumnType(0), fmt.Errorf("not a valid ColumnType string")
}
func ColumnTypePtr(v ColumnType) *ColumnType { return &v }
func (p *ColumnType) Scan(value interface{}) (err error) {
var result sql.NullInt64
err = result.Scan(value)
*p = ColumnType(result.Int64)
return
}
func (p *ColumnType) Value() (driver.Value, error) {
if p == nil {
return nil, nil
}
return int64(*p), nil
}
type DocTableSheet struct {
// sheet 的编号
ID int64 `thrift:"id,1" form:"id" json:"id" query:"id"`
// sheet 名
SheetName string `thrift:"sheet_name,2" form:"sheet_name" json:"sheet_name" query:"sheet_name"`
// 总行数
TotalRow int64 `thrift:"total_row,3" form:"total_row" json:"total_row" query:"total_row"`
}
func NewDocTableSheet() *DocTableSheet {
return &DocTableSheet{}
}
func (p *DocTableSheet) InitDefault() {
}
func (p *DocTableSheet) GetID() (v int64) {
return p.ID
}
func (p *DocTableSheet) GetSheetName() (v string) {
return p.SheetName
}
func (p *DocTableSheet) GetTotalRow() (v int64) {
return p.TotalRow
}
var fieldIDToName_DocTableSheet = map[int16]string{
1: "id",
2: "sheet_name",
3: "total_row",
}
func (p *DocTableSheet) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.I64 {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 3:
if fieldTypeId == thrift.I64 {
if err = p.ReadField3(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_DocTableSheet[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *DocTableSheet) ReadField1(iprot thrift.TProtocol) error {
var _field int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = v
}
p.ID = _field
return nil
}
func (p *DocTableSheet) ReadField2(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.SheetName = _field
return nil
}
func (p *DocTableSheet) ReadField3(iprot thrift.TProtocol) error {
var _field int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = v
}
p.TotalRow = _field
return nil
}
func (p *DocTableSheet) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("DocTableSheet"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
if err = p.writeField3(oprot); err != nil {
fieldId = 3
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *DocTableSheet) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("id", thrift.I64, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(p.ID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *DocTableSheet) writeField2(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("sheet_name", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.SheetName); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *DocTableSheet) writeField3(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("total_row", thrift.I64, 3); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(p.TotalRow); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
}
func (p *DocTableSheet) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("DocTableSheet(%+v)", *p)
}
// 表格的列信息
type DocTableColumn struct {
// 列 id
ID int64 `thrift:"id,1" form:"id" json:"id,string"`
// 列名
ColumnName string `thrift:"column_name,2" form:"column_name" json:"column_name" query:"column_name"`
// 是否为语义匹配列
IsSemantic bool `thrift:"is_semantic,3" form:"is_semantic" json:"is_semantic" query:"is_semantic"`
// 列原本在 excel 的序号
Sequence int64 `thrift:"sequence,4" form:"sequence" json:"sequence,string"`
// 列类型
ColumnType *ColumnType `thrift:"column_type,5,optional" form:"column_type" json:"column_type,omitempty" query:"column_type"`
ContainsEmptyValue *bool `thrift:"contains_empty_value,6,optional" form:"contains_empty_value" json:"contains_empty_value,omitempty" query:"contains_empty_value"`
// 描述
Desc *string `thrift:"desc,7,optional" form:"desc" json:"desc,omitempty" query:"desc"`
}
func NewDocTableColumn() *DocTableColumn {
return &DocTableColumn{}
}
func (p *DocTableColumn) InitDefault() {
}
func (p *DocTableColumn) GetID() (v int64) {
return p.ID
}
func (p *DocTableColumn) GetColumnName() (v string) {
return p.ColumnName
}
func (p *DocTableColumn) GetIsSemantic() (v bool) {
return p.IsSemantic
}
func (p *DocTableColumn) GetSequence() (v int64) {
return p.Sequence
}
var DocTableColumn_ColumnType_DEFAULT ColumnType
func (p *DocTableColumn) GetColumnType() (v ColumnType) {
if !p.IsSetColumnType() {
return DocTableColumn_ColumnType_DEFAULT
}
return *p.ColumnType
}
var DocTableColumn_ContainsEmptyValue_DEFAULT bool
func (p *DocTableColumn) GetContainsEmptyValue() (v bool) {
if !p.IsSetContainsEmptyValue() {
return DocTableColumn_ContainsEmptyValue_DEFAULT
}
return *p.ContainsEmptyValue
}
var DocTableColumn_Desc_DEFAULT string
func (p *DocTableColumn) GetDesc() (v string) {
if !p.IsSetDesc() {
return DocTableColumn_Desc_DEFAULT
}
return *p.Desc
}
var fieldIDToName_DocTableColumn = map[int16]string{
1: "id",
2: "column_name",
3: "is_semantic",
4: "sequence",
5: "column_type",
6: "contains_empty_value",
7: "desc",
}
func (p *DocTableColumn) IsSetColumnType() bool {
return p.ColumnType != nil
}
func (p *DocTableColumn) IsSetContainsEmptyValue() bool {
return p.ContainsEmptyValue != nil
}
func (p *DocTableColumn) IsSetDesc() bool {
return p.Desc != nil
}
func (p *DocTableColumn) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.I64 {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 3:
if fieldTypeId == thrift.BOOL {
if err = p.ReadField3(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 4:
if fieldTypeId == thrift.I64 {
if err = p.ReadField4(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 5:
if fieldTypeId == thrift.I32 {
if err = p.ReadField5(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 6:
if fieldTypeId == thrift.BOOL {
if err = p.ReadField6(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 7:
if fieldTypeId == thrift.STRING {
if err = p.ReadField7(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_DocTableColumn[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *DocTableColumn) ReadField1(iprot thrift.TProtocol) error {
var _field int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = v
}
p.ID = _field
return nil
}
func (p *DocTableColumn) ReadField2(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.ColumnName = _field
return nil
}
func (p *DocTableColumn) ReadField3(iprot thrift.TProtocol) error {
var _field bool
if v, err := iprot.ReadBool(); err != nil {
return err
} else {
_field = v
}
p.IsSemantic = _field
return nil
}
func (p *DocTableColumn) ReadField4(iprot thrift.TProtocol) error {
var _field int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = v
}
p.Sequence = _field
return nil
}
func (p *DocTableColumn) ReadField5(iprot thrift.TProtocol) error {
var _field *ColumnType
if v, err := iprot.ReadI32(); err != nil {
return err
} else {
tmp := ColumnType(v)
_field = &tmp
}
p.ColumnType = _field
return nil
}
func (p *DocTableColumn) ReadField6(iprot thrift.TProtocol) error {
var _field *bool
if v, err := iprot.ReadBool(); err != nil {
return err
} else {
_field = &v
}
p.ContainsEmptyValue = _field
return nil
}
func (p *DocTableColumn) ReadField7(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.Desc = _field
return nil
}
func (p *DocTableColumn) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("DocTableColumn"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
if err = p.writeField3(oprot); err != nil {
fieldId = 3
goto WriteFieldError
}
if err = p.writeField4(oprot); err != nil {
fieldId = 4
goto WriteFieldError
}
if err = p.writeField5(oprot); err != nil {
fieldId = 5
goto WriteFieldError
}
if err = p.writeField6(oprot); err != nil {
fieldId = 6
goto WriteFieldError
}
if err = p.writeField7(oprot); err != nil {
fieldId = 7
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *DocTableColumn) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("id", thrift.I64, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(p.ID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *DocTableColumn) writeField2(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("column_name", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.ColumnName); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *DocTableColumn) writeField3(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("is_semantic", thrift.BOOL, 3); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteBool(p.IsSemantic); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
}
func (p *DocTableColumn) writeField4(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("sequence", thrift.I64, 4); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(p.Sequence); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err)
}
func (p *DocTableColumn) writeField5(oprot thrift.TProtocol) (err error) {
if p.IsSetColumnType() {
if err = oprot.WriteFieldBegin("column_type", thrift.I32, 5); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI32(int32(*p.ColumnType)); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err)
}
func (p *DocTableColumn) writeField6(oprot thrift.TProtocol) (err error) {
if p.IsSetContainsEmptyValue() {
if err = oprot.WriteFieldBegin("contains_empty_value", thrift.BOOL, 6); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteBool(*p.ContainsEmptyValue); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err)
}
func (p *DocTableColumn) writeField7(oprot thrift.TProtocol) (err error) {
if p.IsSetDesc() {
if err = oprot.WriteFieldBegin("desc", thrift.STRING, 7); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.Desc); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 7 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 7 end error: ", p), err)
}
func (p *DocTableColumn) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("DocTableColumn(%+v)", *p)
}

View File

@ -0,0 +1,783 @@
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
package agentrun
import (
"github.com/coze-dev/coze-studio/backend/api/model/conversation/run"
"context"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
type AgentRunService interface {
AgentRun(ctx context.Context, request *run.AgentRunRequest) (r *run.AgentRunResponse, err error)
ChatV3(ctx context.Context, request *run.ChatV3Request) (r *run.ChatV3Response, err error)
}
type AgentRunServiceClient struct {
c thrift.TClient
}
func NewAgentRunServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *AgentRunServiceClient {
return &AgentRunServiceClient{
c: thrift.NewTStandardClient(f.GetProtocol(t), f.GetProtocol(t)),
}
}
func NewAgentRunServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *AgentRunServiceClient {
return &AgentRunServiceClient{
c: thrift.NewTStandardClient(iprot, oprot),
}
}
func NewAgentRunServiceClient(c thrift.TClient) *AgentRunServiceClient {
return &AgentRunServiceClient{
c: c,
}
}
func (p *AgentRunServiceClient) Client_() thrift.TClient {
return p.c
}
func (p *AgentRunServiceClient) AgentRun(ctx context.Context, request *run.AgentRunRequest) (r *run.AgentRunResponse, err error) {
var _args AgentRunServiceAgentRunArgs
_args.Request = request
var _result AgentRunServiceAgentRunResult
if err = p.Client_().Call(ctx, "AgentRun", &_args, &_result); err != nil {
return
}
return _result.GetSuccess(), nil
}
func (p *AgentRunServiceClient) ChatV3(ctx context.Context, request *run.ChatV3Request) (r *run.ChatV3Response, err error) {
var _args AgentRunServiceChatV3Args
_args.Request = request
var _result AgentRunServiceChatV3Result
if err = p.Client_().Call(ctx, "ChatV3", &_args, &_result); err != nil {
return
}
return _result.GetSuccess(), nil
}
type AgentRunServiceProcessor struct {
processorMap map[string]thrift.TProcessorFunction
handler AgentRunService
}
func (p *AgentRunServiceProcessor) AddToProcessorMap(key string, processor thrift.TProcessorFunction) {
p.processorMap[key] = processor
}
func (p *AgentRunServiceProcessor) GetProcessorFunction(key string) (processor thrift.TProcessorFunction, ok bool) {
processor, ok = p.processorMap[key]
return processor, ok
}
func (p *AgentRunServiceProcessor) ProcessorMap() map[string]thrift.TProcessorFunction {
return p.processorMap
}
func NewAgentRunServiceProcessor(handler AgentRunService) *AgentRunServiceProcessor {
self := &AgentRunServiceProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)}
self.AddToProcessorMap("AgentRun", &agentRunServiceProcessorAgentRun{handler: handler})
self.AddToProcessorMap("ChatV3", &agentRunServiceProcessorChatV3{handler: handler})
return self
}
func (p *AgentRunServiceProcessor) Process(ctx context.Context, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
name, _, seqId, err := iprot.ReadMessageBegin()
if err != nil {
return false, err
}
if processor, ok := p.GetProcessorFunction(name); ok {
return processor.Process(ctx, seqId, iprot, oprot)
}
iprot.Skip(thrift.STRUCT)
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.UNKNOWN_METHOD, "Unknown function "+name)
oprot.WriteMessageBegin(name, thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return false, x
}
type agentRunServiceProcessorAgentRun struct {
handler AgentRunService
}
func (p *agentRunServiceProcessorAgentRun) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
args := AgentRunServiceAgentRunArgs{}
if err = args.Read(iprot); err != nil {
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error())
oprot.WriteMessageBegin("AgentRun", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return false, err
}
iprot.ReadMessageEnd()
var err2 error
result := AgentRunServiceAgentRunResult{}
var retval *run.AgentRunResponse
if retval, err2 = p.handler.AgentRun(ctx, args.Request); err2 != nil {
x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing AgentRun: "+err2.Error())
oprot.WriteMessageBegin("AgentRun", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return true, err2
} else {
result.Success = retval
}
if err2 = oprot.WriteMessageBegin("AgentRun", thrift.REPLY, seqId); err2 != nil {
err = err2
}
if err2 = result.Write(oprot); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.Flush(ctx); err == nil && err2 != nil {
err = err2
}
if err != nil {
return
}
return true, err
}
type agentRunServiceProcessorChatV3 struct {
handler AgentRunService
}
func (p *agentRunServiceProcessorChatV3) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
args := AgentRunServiceChatV3Args{}
if err = args.Read(iprot); err != nil {
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error())
oprot.WriteMessageBegin("ChatV3", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return false, err
}
iprot.ReadMessageEnd()
var err2 error
result := AgentRunServiceChatV3Result{}
var retval *run.ChatV3Response
if retval, err2 = p.handler.ChatV3(ctx, args.Request); err2 != nil {
x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing ChatV3: "+err2.Error())
oprot.WriteMessageBegin("ChatV3", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return true, err2
} else {
result.Success = retval
}
if err2 = oprot.WriteMessageBegin("ChatV3", thrift.REPLY, seqId); err2 != nil {
err = err2
}
if err2 = result.Write(oprot); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.Flush(ctx); err == nil && err2 != nil {
err = err2
}
if err != nil {
return
}
return true, err
}
type AgentRunServiceAgentRunArgs struct {
Request *run.AgentRunRequest `thrift:"request,1"`
}
func NewAgentRunServiceAgentRunArgs() *AgentRunServiceAgentRunArgs {
return &AgentRunServiceAgentRunArgs{}
}
func (p *AgentRunServiceAgentRunArgs) InitDefault() {
}
var AgentRunServiceAgentRunArgs_Request_DEFAULT *run.AgentRunRequest
func (p *AgentRunServiceAgentRunArgs) GetRequest() (v *run.AgentRunRequest) {
if !p.IsSetRequest() {
return AgentRunServiceAgentRunArgs_Request_DEFAULT
}
return p.Request
}
var fieldIDToName_AgentRunServiceAgentRunArgs = map[int16]string{
1: "request",
}
func (p *AgentRunServiceAgentRunArgs) IsSetRequest() bool {
return p.Request != nil
}
func (p *AgentRunServiceAgentRunArgs) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AgentRunServiceAgentRunArgs[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AgentRunServiceAgentRunArgs) ReadField1(iprot thrift.TProtocol) error {
_field := run.NewAgentRunRequest()
if err := _field.Read(iprot); err != nil {
return err
}
p.Request = _field
return nil
}
func (p *AgentRunServiceAgentRunArgs) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("AgentRun_args"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AgentRunServiceAgentRunArgs) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("request", thrift.STRUCT, 1); err != nil {
goto WriteFieldBeginError
}
if err := p.Request.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *AgentRunServiceAgentRunArgs) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AgentRunServiceAgentRunArgs(%+v)", *p)
}
type AgentRunServiceAgentRunResult struct {
Success *run.AgentRunResponse `thrift:"success,0,optional"`
}
func NewAgentRunServiceAgentRunResult() *AgentRunServiceAgentRunResult {
return &AgentRunServiceAgentRunResult{}
}
func (p *AgentRunServiceAgentRunResult) InitDefault() {
}
var AgentRunServiceAgentRunResult_Success_DEFAULT *run.AgentRunResponse
func (p *AgentRunServiceAgentRunResult) GetSuccess() (v *run.AgentRunResponse) {
if !p.IsSetSuccess() {
return AgentRunServiceAgentRunResult_Success_DEFAULT
}
return p.Success
}
var fieldIDToName_AgentRunServiceAgentRunResult = map[int16]string{
0: "success",
}
func (p *AgentRunServiceAgentRunResult) IsSetSuccess() bool {
return p.Success != nil
}
func (p *AgentRunServiceAgentRunResult) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 0:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField0(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AgentRunServiceAgentRunResult[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AgentRunServiceAgentRunResult) ReadField0(iprot thrift.TProtocol) error {
_field := run.NewAgentRunResponse()
if err := _field.Read(iprot); err != nil {
return err
}
p.Success = _field
return nil
}
func (p *AgentRunServiceAgentRunResult) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("AgentRun_result"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField0(oprot); err != nil {
fieldId = 0
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AgentRunServiceAgentRunResult) writeField0(oprot thrift.TProtocol) (err error) {
if p.IsSetSuccess() {
if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil {
goto WriteFieldBeginError
}
if err := p.Success.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err)
}
func (p *AgentRunServiceAgentRunResult) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AgentRunServiceAgentRunResult(%+v)", *p)
}
type AgentRunServiceChatV3Args struct {
Request *run.ChatV3Request `thrift:"request,1"`
}
func NewAgentRunServiceChatV3Args() *AgentRunServiceChatV3Args {
return &AgentRunServiceChatV3Args{}
}
func (p *AgentRunServiceChatV3Args) InitDefault() {
}
var AgentRunServiceChatV3Args_Request_DEFAULT *run.ChatV3Request
func (p *AgentRunServiceChatV3Args) GetRequest() (v *run.ChatV3Request) {
if !p.IsSetRequest() {
return AgentRunServiceChatV3Args_Request_DEFAULT
}
return p.Request
}
var fieldIDToName_AgentRunServiceChatV3Args = map[int16]string{
1: "request",
}
func (p *AgentRunServiceChatV3Args) IsSetRequest() bool {
return p.Request != nil
}
func (p *AgentRunServiceChatV3Args) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AgentRunServiceChatV3Args[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AgentRunServiceChatV3Args) ReadField1(iprot thrift.TProtocol) error {
_field := run.NewChatV3Request()
if err := _field.Read(iprot); err != nil {
return err
}
p.Request = _field
return nil
}
func (p *AgentRunServiceChatV3Args) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("ChatV3_args"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AgentRunServiceChatV3Args) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("request", thrift.STRUCT, 1); err != nil {
goto WriteFieldBeginError
}
if err := p.Request.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *AgentRunServiceChatV3Args) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AgentRunServiceChatV3Args(%+v)", *p)
}
type AgentRunServiceChatV3Result struct {
Success *run.ChatV3Response `thrift:"success,0,optional"`
}
func NewAgentRunServiceChatV3Result() *AgentRunServiceChatV3Result {
return &AgentRunServiceChatV3Result{}
}
func (p *AgentRunServiceChatV3Result) InitDefault() {
}
var AgentRunServiceChatV3Result_Success_DEFAULT *run.ChatV3Response
func (p *AgentRunServiceChatV3Result) GetSuccess() (v *run.ChatV3Response) {
if !p.IsSetSuccess() {
return AgentRunServiceChatV3Result_Success_DEFAULT
}
return p.Success
}
var fieldIDToName_AgentRunServiceChatV3Result = map[int16]string{
0: "success",
}
func (p *AgentRunServiceChatV3Result) IsSetSuccess() bool {
return p.Success != nil
}
func (p *AgentRunServiceChatV3Result) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 0:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField0(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AgentRunServiceChatV3Result[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AgentRunServiceChatV3Result) ReadField0(iprot thrift.TProtocol) error {
_field := run.NewChatV3Response()
if err := _field.Read(iprot); err != nil {
return err
}
p.Success = _field
return nil
}
func (p *AgentRunServiceChatV3Result) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("ChatV3_result"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField0(oprot); err != nil {
fieldId = 0
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AgentRunServiceChatV3Result) writeField0(oprot thrift.TProtocol) (err error) {
if p.IsSetSuccess() {
if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil {
goto WriteFieldBeginError
}
if err := p.Success.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err)
}
func (p *AgentRunServiceChatV3Result) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AgentRunServiceChatV3Result(%+v)", *p)
}

View File

@ -0,0 +1,96 @@
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
package common
import (
"database/sql"
"database/sql/driver"
"fmt"
)
type Scene int64
const (
Scene_Default Scene = 0
Scene_Explore Scene = 1
Scene_BotStore Scene = 2
Scene_CozeHome Scene = 3
//调试
Scene_Playground Scene = 4
// 评测平台
Scene_Evaluation Scene = 5
Scene_AgentAPP Scene = 6
//prompt优化
Scene_PromptOptimize Scene = 7
// createbot的nl2bot功能
Scene_GenerateAgentInfo Scene = 8
//openapi
Scene_SceneOpenApi Scene = 9
)
func (p Scene) String() string {
switch p {
case Scene_Default:
return "Default"
case Scene_Explore:
return "Explore"
case Scene_BotStore:
return "BotStore"
case Scene_CozeHome:
return "CozeHome"
case Scene_Playground:
return "Playground"
case Scene_Evaluation:
return "Evaluation"
case Scene_AgentAPP:
return "AgentAPP"
case Scene_PromptOptimize:
return "PromptOptimize"
case Scene_GenerateAgentInfo:
return "GenerateAgentInfo"
case Scene_SceneOpenApi:
return "SceneOpenApi"
}
return "<UNSET>"
}
func SceneFromString(s string) (Scene, error) {
switch s {
case "Default":
return Scene_Default, nil
case "Explore":
return Scene_Explore, nil
case "BotStore":
return Scene_BotStore, nil
case "CozeHome":
return Scene_CozeHome, nil
case "Playground":
return Scene_Playground, nil
case "Evaluation":
return Scene_Evaluation, nil
case "AgentAPP":
return Scene_AgentAPP, nil
case "PromptOptimize":
return Scene_PromptOptimize, nil
case "GenerateAgentInfo":
return Scene_GenerateAgentInfo, nil
case "SceneOpenApi":
return Scene_SceneOpenApi, nil
}
return Scene(0), fmt.Errorf("not a valid Scene string")
}
func ScenePtr(v Scene) *Scene { return &v }
func (p *Scene) Scan(value interface{}) (err error) {
var result sql.NullInt64
err = result.Scan(value)
*p = Scene(result.Int64)
return
}
func (p *Scene) Value() (driver.Value, error) {
if p == nil {
return nil, nil
}
return int64(*p), nil
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,583 @@
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
package coze
import (
"github.com/coze-dev/coze-studio/backend/api/model/conversation/agentrun"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/conversation"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/message"
"github.com/coze-dev/coze-studio/backend/api/model/database"
"github.com/coze-dev/coze-studio/backend/api/model/flow/dataengine/dataset"
"github.com/coze-dev/coze-studio/backend/api/model/flow/marketplace/product_public_api"
"github.com/coze-dev/coze-studio/backend/api/model/intelligence"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/bot_open_api"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/developer_api"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/memory"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/playground"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/plugin_develop"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/workflow"
"github.com/coze-dev/coze-studio/backend/api/model/passport"
"github.com/coze-dev/coze-studio/backend/api/model/permission/openapiauth"
"github.com/coze-dev/coze-studio/backend/api/model/resource"
"github.com/apache/thrift/lib/go/thrift"
)
type IntelligenceService interface {
intelligence.IntelligenceService
}
type IntelligenceServiceClient struct {
*intelligence.IntelligenceServiceClient
}
func NewIntelligenceServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *IntelligenceServiceClient {
return &IntelligenceServiceClient{
IntelligenceServiceClient: intelligence.NewIntelligenceServiceClientFactory(t, f),
}
}
func NewIntelligenceServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *IntelligenceServiceClient {
return &IntelligenceServiceClient{
IntelligenceServiceClient: intelligence.NewIntelligenceServiceClientProtocol(t, iprot, oprot),
}
}
func NewIntelligenceServiceClient(c thrift.TClient) *IntelligenceServiceClient {
return &IntelligenceServiceClient{
IntelligenceServiceClient: intelligence.NewIntelligenceServiceClient(c),
}
}
type ConversationService interface {
conversation.ConversationService
}
type ConversationServiceClient struct {
*conversation.ConversationServiceClient
}
func NewConversationServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *ConversationServiceClient {
return &ConversationServiceClient{
ConversationServiceClient: conversation.NewConversationServiceClientFactory(t, f),
}
}
func NewConversationServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *ConversationServiceClient {
return &ConversationServiceClient{
ConversationServiceClient: conversation.NewConversationServiceClientProtocol(t, iprot, oprot),
}
}
func NewConversationServiceClient(c thrift.TClient) *ConversationServiceClient {
return &ConversationServiceClient{
ConversationServiceClient: conversation.NewConversationServiceClient(c),
}
}
type MessageService interface {
message.MessageService
}
type MessageServiceClient struct {
*message.MessageServiceClient
}
func NewMessageServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *MessageServiceClient {
return &MessageServiceClient{
MessageServiceClient: message.NewMessageServiceClientFactory(t, f),
}
}
func NewMessageServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *MessageServiceClient {
return &MessageServiceClient{
MessageServiceClient: message.NewMessageServiceClientProtocol(t, iprot, oprot),
}
}
func NewMessageServiceClient(c thrift.TClient) *MessageServiceClient {
return &MessageServiceClient{
MessageServiceClient: message.NewMessageServiceClient(c),
}
}
type AgentRunService interface {
agentrun.AgentRunService
}
type AgentRunServiceClient struct {
*agentrun.AgentRunServiceClient
}
func NewAgentRunServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *AgentRunServiceClient {
return &AgentRunServiceClient{
AgentRunServiceClient: agentrun.NewAgentRunServiceClientFactory(t, f),
}
}
func NewAgentRunServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *AgentRunServiceClient {
return &AgentRunServiceClient{
AgentRunServiceClient: agentrun.NewAgentRunServiceClientProtocol(t, iprot, oprot),
}
}
func NewAgentRunServiceClient(c thrift.TClient) *AgentRunServiceClient {
return &AgentRunServiceClient{
AgentRunServiceClient: agentrun.NewAgentRunServiceClient(c),
}
}
type OpenAPIAuthService interface {
openapiauth.OpenAPIAuthService
}
type OpenAPIAuthServiceClient struct {
*openapiauth.OpenAPIAuthServiceClient
}
func NewOpenAPIAuthServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *OpenAPIAuthServiceClient {
return &OpenAPIAuthServiceClient{
OpenAPIAuthServiceClient: openapiauth.NewOpenAPIAuthServiceClientFactory(t, f),
}
}
func NewOpenAPIAuthServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *OpenAPIAuthServiceClient {
return &OpenAPIAuthServiceClient{
OpenAPIAuthServiceClient: openapiauth.NewOpenAPIAuthServiceClientProtocol(t, iprot, oprot),
}
}
func NewOpenAPIAuthServiceClient(c thrift.TClient) *OpenAPIAuthServiceClient {
return &OpenAPIAuthServiceClient{
OpenAPIAuthServiceClient: openapiauth.NewOpenAPIAuthServiceClient(c),
}
}
type MemoryService interface {
memory.MemoryService
}
type MemoryServiceClient struct {
*memory.MemoryServiceClient
}
func NewMemoryServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *MemoryServiceClient {
return &MemoryServiceClient{
MemoryServiceClient: memory.NewMemoryServiceClientFactory(t, f),
}
}
func NewMemoryServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *MemoryServiceClient {
return &MemoryServiceClient{
MemoryServiceClient: memory.NewMemoryServiceClientProtocol(t, iprot, oprot),
}
}
func NewMemoryServiceClient(c thrift.TClient) *MemoryServiceClient {
return &MemoryServiceClient{
MemoryServiceClient: memory.NewMemoryServiceClient(c),
}
}
type PluginDevelopService interface {
plugin_develop.PluginDevelopService
}
type PluginDevelopServiceClient struct {
*plugin_develop.PluginDevelopServiceClient
}
func NewPluginDevelopServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *PluginDevelopServiceClient {
return &PluginDevelopServiceClient{
PluginDevelopServiceClient: plugin_develop.NewPluginDevelopServiceClientFactory(t, f),
}
}
func NewPluginDevelopServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *PluginDevelopServiceClient {
return &PluginDevelopServiceClient{
PluginDevelopServiceClient: plugin_develop.NewPluginDevelopServiceClientProtocol(t, iprot, oprot),
}
}
func NewPluginDevelopServiceClient(c thrift.TClient) *PluginDevelopServiceClient {
return &PluginDevelopServiceClient{
PluginDevelopServiceClient: plugin_develop.NewPluginDevelopServiceClient(c),
}
}
type PublicProductService interface {
product_public_api.PublicProductService
}
type PublicProductServiceClient struct {
*product_public_api.PublicProductServiceClient
}
func NewPublicProductServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *PublicProductServiceClient {
return &PublicProductServiceClient{
PublicProductServiceClient: product_public_api.NewPublicProductServiceClientFactory(t, f),
}
}
func NewPublicProductServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *PublicProductServiceClient {
return &PublicProductServiceClient{
PublicProductServiceClient: product_public_api.NewPublicProductServiceClientProtocol(t, iprot, oprot),
}
}
func NewPublicProductServiceClient(c thrift.TClient) *PublicProductServiceClient {
return &PublicProductServiceClient{
PublicProductServiceClient: product_public_api.NewPublicProductServiceClient(c),
}
}
type DeveloperApiService interface {
developer_api.DeveloperApiService
}
type DeveloperApiServiceClient struct {
*developer_api.DeveloperApiServiceClient
}
func NewDeveloperApiServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *DeveloperApiServiceClient {
return &DeveloperApiServiceClient{
DeveloperApiServiceClient: developer_api.NewDeveloperApiServiceClientFactory(t, f),
}
}
func NewDeveloperApiServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *DeveloperApiServiceClient {
return &DeveloperApiServiceClient{
DeveloperApiServiceClient: developer_api.NewDeveloperApiServiceClientProtocol(t, iprot, oprot),
}
}
func NewDeveloperApiServiceClient(c thrift.TClient) *DeveloperApiServiceClient {
return &DeveloperApiServiceClient{
DeveloperApiServiceClient: developer_api.NewDeveloperApiServiceClient(c),
}
}
type PlaygroundService interface {
playground.PlaygroundService
}
type PlaygroundServiceClient struct {
*playground.PlaygroundServiceClient
}
func NewPlaygroundServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *PlaygroundServiceClient {
return &PlaygroundServiceClient{
PlaygroundServiceClient: playground.NewPlaygroundServiceClientFactory(t, f),
}
}
func NewPlaygroundServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *PlaygroundServiceClient {
return &PlaygroundServiceClient{
PlaygroundServiceClient: playground.NewPlaygroundServiceClientProtocol(t, iprot, oprot),
}
}
func NewPlaygroundServiceClient(c thrift.TClient) *PlaygroundServiceClient {
return &PlaygroundServiceClient{
PlaygroundServiceClient: playground.NewPlaygroundServiceClient(c),
}
}
type DatabaseService interface {
database.DatabaseService
}
type DatabaseServiceClient struct {
*database.DatabaseServiceClient
}
func NewDatabaseServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *DatabaseServiceClient {
return &DatabaseServiceClient{
DatabaseServiceClient: database.NewDatabaseServiceClientFactory(t, f),
}
}
func NewDatabaseServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *DatabaseServiceClient {
return &DatabaseServiceClient{
DatabaseServiceClient: database.NewDatabaseServiceClientProtocol(t, iprot, oprot),
}
}
func NewDatabaseServiceClient(c thrift.TClient) *DatabaseServiceClient {
return &DatabaseServiceClient{
DatabaseServiceClient: database.NewDatabaseServiceClient(c),
}
}
type ResourceService interface {
resource.ResourceService
}
type ResourceServiceClient struct {
*resource.ResourceServiceClient
}
func NewResourceServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *ResourceServiceClient {
return &ResourceServiceClient{
ResourceServiceClient: resource.NewResourceServiceClientFactory(t, f),
}
}
func NewResourceServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *ResourceServiceClient {
return &ResourceServiceClient{
ResourceServiceClient: resource.NewResourceServiceClientProtocol(t, iprot, oprot),
}
}
func NewResourceServiceClient(c thrift.TClient) *ResourceServiceClient {
return &ResourceServiceClient{
ResourceServiceClient: resource.NewResourceServiceClient(c),
}
}
type PassportService interface {
passport.PassportService
}
type PassportServiceClient struct {
*passport.PassportServiceClient
}
func NewPassportServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *PassportServiceClient {
return &PassportServiceClient{
PassportServiceClient: passport.NewPassportServiceClientFactory(t, f),
}
}
func NewPassportServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *PassportServiceClient {
return &PassportServiceClient{
PassportServiceClient: passport.NewPassportServiceClientProtocol(t, iprot, oprot),
}
}
func NewPassportServiceClient(c thrift.TClient) *PassportServiceClient {
return &PassportServiceClient{
PassportServiceClient: passport.NewPassportServiceClient(c),
}
}
type WorkflowService interface {
workflow.WorkflowService
}
type WorkflowServiceClient struct {
*workflow.WorkflowServiceClient
}
func NewWorkflowServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *WorkflowServiceClient {
return &WorkflowServiceClient{
WorkflowServiceClient: workflow.NewWorkflowServiceClientFactory(t, f),
}
}
func NewWorkflowServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *WorkflowServiceClient {
return &WorkflowServiceClient{
WorkflowServiceClient: workflow.NewWorkflowServiceClientProtocol(t, iprot, oprot),
}
}
func NewWorkflowServiceClient(c thrift.TClient) *WorkflowServiceClient {
return &WorkflowServiceClient{
WorkflowServiceClient: workflow.NewWorkflowServiceClient(c),
}
}
type KnowledgeService interface {
dataset.DatasetService
}
type KnowledgeServiceClient struct {
*dataset.DatasetServiceClient
}
func NewKnowledgeServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *KnowledgeServiceClient {
return &KnowledgeServiceClient{
DatasetServiceClient: dataset.NewDatasetServiceClientFactory(t, f),
}
}
func NewKnowledgeServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *KnowledgeServiceClient {
return &KnowledgeServiceClient{
DatasetServiceClient: dataset.NewDatasetServiceClientProtocol(t, iprot, oprot),
}
}
func NewKnowledgeServiceClient(c thrift.TClient) *KnowledgeServiceClient {
return &KnowledgeServiceClient{
DatasetServiceClient: dataset.NewDatasetServiceClient(c),
}
}
type BotOpenApiService interface {
bot_open_api.BotOpenApiService
}
type BotOpenApiServiceClient struct {
*bot_open_api.BotOpenApiServiceClient
}
func NewBotOpenApiServiceClientFactory(t thrift.TTransport, f thrift.TProtocolFactory) *BotOpenApiServiceClient {
return &BotOpenApiServiceClient{
BotOpenApiServiceClient: bot_open_api.NewBotOpenApiServiceClientFactory(t, f),
}
}
func NewBotOpenApiServiceClientProtocol(t thrift.TTransport, iprot thrift.TProtocol, oprot thrift.TProtocol) *BotOpenApiServiceClient {
return &BotOpenApiServiceClient{
BotOpenApiServiceClient: bot_open_api.NewBotOpenApiServiceClientProtocol(t, iprot, oprot),
}
}
func NewBotOpenApiServiceClient(c thrift.TClient) *BotOpenApiServiceClient {
return &BotOpenApiServiceClient{
BotOpenApiServiceClient: bot_open_api.NewBotOpenApiServiceClient(c),
}
}
type IntelligenceServiceProcessor struct {
*intelligence.IntelligenceServiceProcessor
}
func NewIntelligenceServiceProcessor(handler IntelligenceService) *IntelligenceServiceProcessor {
self := &IntelligenceServiceProcessor{intelligence.NewIntelligenceServiceProcessor(handler)}
return self
}
type ConversationServiceProcessor struct {
*conversation.ConversationServiceProcessor
}
func NewConversationServiceProcessor(handler ConversationService) *ConversationServiceProcessor {
self := &ConversationServiceProcessor{conversation.NewConversationServiceProcessor(handler)}
return self
}
type MessageServiceProcessor struct {
*message.MessageServiceProcessor
}
func NewMessageServiceProcessor(handler MessageService) *MessageServiceProcessor {
self := &MessageServiceProcessor{message.NewMessageServiceProcessor(handler)}
return self
}
type AgentRunServiceProcessor struct {
*agentrun.AgentRunServiceProcessor
}
func NewAgentRunServiceProcessor(handler AgentRunService) *AgentRunServiceProcessor {
self := &AgentRunServiceProcessor{agentrun.NewAgentRunServiceProcessor(handler)}
return self
}
type OpenAPIAuthServiceProcessor struct {
*openapiauth.OpenAPIAuthServiceProcessor
}
func NewOpenAPIAuthServiceProcessor(handler OpenAPIAuthService) *OpenAPIAuthServiceProcessor {
self := &OpenAPIAuthServiceProcessor{openapiauth.NewOpenAPIAuthServiceProcessor(handler)}
return self
}
type MemoryServiceProcessor struct {
*memory.MemoryServiceProcessor
}
func NewMemoryServiceProcessor(handler MemoryService) *MemoryServiceProcessor {
self := &MemoryServiceProcessor{memory.NewMemoryServiceProcessor(handler)}
return self
}
type PluginDevelopServiceProcessor struct {
*plugin_develop.PluginDevelopServiceProcessor
}
func NewPluginDevelopServiceProcessor(handler PluginDevelopService) *PluginDevelopServiceProcessor {
self := &PluginDevelopServiceProcessor{plugin_develop.NewPluginDevelopServiceProcessor(handler)}
return self
}
type PublicProductServiceProcessor struct {
*product_public_api.PublicProductServiceProcessor
}
func NewPublicProductServiceProcessor(handler PublicProductService) *PublicProductServiceProcessor {
self := &PublicProductServiceProcessor{product_public_api.NewPublicProductServiceProcessor(handler)}
return self
}
type DeveloperApiServiceProcessor struct {
*developer_api.DeveloperApiServiceProcessor
}
func NewDeveloperApiServiceProcessor(handler DeveloperApiService) *DeveloperApiServiceProcessor {
self := &DeveloperApiServiceProcessor{developer_api.NewDeveloperApiServiceProcessor(handler)}
return self
}
type PlaygroundServiceProcessor struct {
*playground.PlaygroundServiceProcessor
}
func NewPlaygroundServiceProcessor(handler PlaygroundService) *PlaygroundServiceProcessor {
self := &PlaygroundServiceProcessor{playground.NewPlaygroundServiceProcessor(handler)}
return self
}
type DatabaseServiceProcessor struct {
*database.DatabaseServiceProcessor
}
func NewDatabaseServiceProcessor(handler DatabaseService) *DatabaseServiceProcessor {
self := &DatabaseServiceProcessor{database.NewDatabaseServiceProcessor(handler)}
return self
}
type ResourceServiceProcessor struct {
*resource.ResourceServiceProcessor
}
func NewResourceServiceProcessor(handler ResourceService) *ResourceServiceProcessor {
self := &ResourceServiceProcessor{resource.NewResourceServiceProcessor(handler)}
return self
}
type PassportServiceProcessor struct {
*passport.PassportServiceProcessor
}
func NewPassportServiceProcessor(handler PassportService) *PassportServiceProcessor {
self := &PassportServiceProcessor{passport.NewPassportServiceProcessor(handler)}
return self
}
type WorkflowServiceProcessor struct {
*workflow.WorkflowServiceProcessor
}
func NewWorkflowServiceProcessor(handler WorkflowService) *WorkflowServiceProcessor {
self := &WorkflowServiceProcessor{workflow.NewWorkflowServiceProcessor(handler)}
return self
}
type KnowledgeServiceProcessor struct {
*dataset.DatasetServiceProcessor
}
func NewKnowledgeServiceProcessor(handler KnowledgeService) *KnowledgeServiceProcessor {
self := &KnowledgeServiceProcessor{dataset.NewDatasetServiceProcessor(handler)}
return self
}
type BotOpenApiServiceProcessor struct {
*bot_open_api.BotOpenApiServiceProcessor
}
func NewBotOpenApiServiceProcessor(handler BotOpenApiService) *BotOpenApiServiceProcessor {
self := &BotOpenApiServiceProcessor{bot_open_api.NewBotOpenApiServiceProcessor(handler)}
return self
}

View File

@ -0,0 +1,32 @@
package agentrun
type Tool struct {
PluginID int64 `json:"plugin_id"`
ToolID int64 `json:"tool_id"`
Arguments string `json:"arguments"`
ToolName string `json:"tool_name"`
Type ToolType `json:"type"`
}
type ToolType int32
const (
ToolTypePlugin ToolType = 2
ToolTypeWorkflow ToolType = 1
)
type ToolsRetriever struct {
PluginID int64
ToolName string
ToolID int64
Arguments string
Type ToolType
}
type Usage struct {
LlmPromptTokens int64 `json:"llm_prompt_tokens"`
LlmCompletionTokens int64 `json:"llm_completion_tokens"`
LlmTotalTokens int64 `json:"llm_total_tokens"`
WorkflowTokens *int64 `json:"workflow_tokens,omitempty"`
WorkflowCost *int64 `json:"workflow_cost,omitempty"`
}

View File

@ -0,0 +1,12 @@
package connector
import "github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/developer_api"
type Connector struct {
ID int64 `json:"id"`
Name string `json:"name"`
URI string `json:"uri"`
URL string `json:"url"`
Desc string `json:"description"`
ConnectorStatus developer_api.ConnectorDynamicStatus `json:"connector_status"`
}

View File

@ -0,0 +1,45 @@
package conversation
import "github.com/coze-dev/coze-studio/backend/api/model/conversation/common"
type GetCurrent struct {
UserID int64 `json:"user_id"`
Scene common.Scene `json:"scene"`
AgentID int64 `json:"agent_id"`
ConnectorID int64 `json:"connector_id"`
}
type Scene int32
const (
SceneDefault Scene = 0
SceneExplore Scene = 1
SceneBotStore Scene = 2
SceneCozeHome Scene = 3
ScenePlayground Scene = 4
SceneEvaluation Scene = 5
SceneAgentAPP Scene = 6
ScenePromptOptimize Scene = 7
SceneGenerateAgentInfo Scene = 8
SceneOpenApi Scene = 9
)
type Conversation struct {
ID int64 `json:"id"`
SectionID int64 `json:"section_id"`
AgentID int64 `json:"agent_id"`
ConnectorID int64 `json:"connector_id"`
CreatorID int64 `json:"creator_id"`
Scene common.Scene `json:"scene"`
Status ConversationStatus `json:"status"`
Ext string `json:"ext"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
type ConversationStatus int32
const (
ConversationStatusNormal ConversationStatus = 1
ConversationStatusDeleted ConversationStatus = 2
)

View File

@ -0,0 +1,76 @@
package database
type OperateType int64
const (
OperateType_Custom OperateType = 0
OperateType_Insert OperateType = 1
OperateType_Update OperateType = 2
OperateType_Delete OperateType = 3
OperateType_Select OperateType = 4
)
type Operation int64
const (
Operation_EQUAL Operation = 1
Operation_NOT_EQUAL Operation = 2
Operation_GREATER_THAN Operation = 3
Operation_LESS_THAN Operation = 4
Operation_GREATER_EQUAL Operation = 5
Operation_LESS_EQUAL Operation = 6
Operation_IN Operation = 7
Operation_NOT_IN Operation = 8
Operation_IS_NULL Operation = 9
Operation_IS_NOT_NULL Operation = 10
Operation_LIKE Operation = 11
Operation_NOT_LIKE Operation = 12
)
type Logic int64
const (
Logic_And Logic = 1
Logic_Or Logic = 2
)
// SQLType indicates the type of SQL, e.g., parameterized (with '?') or raw SQL.
type SQLType int32
const (
SQLType_Parameterized SQLType = 0
SQLType_Raw SQLType = 1 // Complete/raw SQL
)
type DocumentSourceType int64
const (
DocumentSourceType_Document DocumentSourceType = 0
)
type TableReadDataMethod int
var (
TableReadDataMethodOnlyHeader TableReadDataMethod = 1
TableReadDataMethodPreview TableReadDataMethod = 2
TableReadDataMethodAll TableReadDataMethod = 3
TableReadDataMethodHead TableReadDataMethod = 4
)
type ColumnTypeCategory int64
const (
ColumnTypeCategoryText ColumnTypeCategory = 0
ColumnTypeCategoryNumber ColumnTypeCategory = 1
)
const (
DefaultCreateTimeColName = "bstudio_create_time"
DefaultCidColName = "bstudio_connector_id"
DefaultUidColName = "bstudio_connector_uid"
DefaultIDColName = "bstudio_id"
DefaultCreateTimeDisplayColName = "bstudio_create_time"
DefaultUidDisplayColName = "uuid"
DefaultIDDisplayColName = "id"
)

View File

@ -0,0 +1,190 @@
package database
import (
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/bot_common"
"github.com/coze-dev/coze-studio/backend/api/model/table"
)
type ExecuteSQLRequest struct {
SQL *string // set if OperateType is 0.
SQLType SQLType // SQLType indicates the type of SQL: parameterized or raw SQL. It takes effect if OperateType is 0.
DatabaseID int64
UserID string
SpaceID int64
ConnectorID *int64
SQLParams []*SQLParamVal
TableType table.TableType
OperateType OperateType
// set the following values if OperateType is not 0.
SelectFieldList *SelectFieldList
OrderByList []OrderBy
Limit *int64
Offset *int64
Condition *ComplexCondition
UpsertRows []*UpsertRow
}
type ExecuteSQLResponse struct {
// Records contains the query result, where each map represents a row.
// The map's key is the column name, and the value is the raw data from the database.
// The caller is responsible for type assertion and conversion to the desired format.
// Common types returned by database drivers include:
// - Text: []uint8 (can be converted to string)
// - Number: int64
// - Float: float64
// - Boolean: bool
// - Date: time.Time
Records []map[string]any
FieldList []*FieldItem
RowsAffected *int64
}
type PublishDatabaseRequest struct {
AgentID int64
}
type PublishDatabaseResponse struct {
OnlineDatabases []*bot_common.Database
}
type SQLParamVal struct {
ValueType table.FieldItemType
ISNull bool
Value *string
Name *string
}
type OrderBy struct {
Field string
Direction table.SortDirection
}
type UpsertRow struct {
Records []*Record
}
type Record struct {
FieldId string
FieldValue string
}
type SelectFieldList struct {
FieldID []string
IsDistinct bool
}
type ComplexCondition struct {
Conditions []*Condition
// NestedConditions *ComplexCondition
Logic Logic
}
type Condition struct {
Left string
Operation Operation
Right string
}
type FieldItem struct {
Name string
Desc string
Type table.FieldItemType
MustRequired bool
AlterID int64
IsSystemField bool
PhysicalName string
// ID int64
}
type Database struct {
ID int64
IconURI string
CreatorID int64
SpaceID int64
CreatedAtMs int64
UpdatedAtMs int64
DeletedAtMs int64
AppID int64
IconURL string
TableName string
TableDesc string
Status table.BotTableStatus
FieldList []*FieldItem
ActualTableName string
RwMode table.BotTableRWMode
PromptDisabled bool
IsVisible bool
DraftID *int64
OnlineID *int64
ExtraInfo map[string]string
IsAddedToAgent *bool
TableType *table.TableType
}
func (d *Database) GetDraftID() int64 {
if d.DraftID == nil {
return 0
}
return *d.DraftID
}
func (d *Database) GetOnlineID() int64 {
if d.OnlineID == nil {
return 0
}
return *d.OnlineID
}
type DatabaseBasic struct {
ID int64
TableType table.TableType
NeedSysFields bool
}
type DeleteDatabaseRequest struct {
ID int64
}
type AgentToDatabase struct {
AgentID int64
DatabaseID int64
TableType table.TableType
PromptDisabled bool
}
type AgentToDatabaseBasic struct {
AgentID int64
DatabaseID int64
}
type BindDatabaseToAgentRequest struct {
DraftDatabaseID int64
AgentID int64
}
type UnBindDatabaseToAgentRequest struct {
DraftDatabaseID int64
AgentID int64
}
type MGetDatabaseRequest struct {
Basics []*DatabaseBasic
}
type MGetDatabaseResponse struct {
Databases []*Database
}
type GetAllDatabaseByAppIDRequest struct {
AppID int64
}
type GetAllDatabaseByAppIDResponse struct {
Databases []*Database // online databases
}

View File

@ -0,0 +1,269 @@
package knowledge
import (
"github.com/bytedance/sonic"
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/infra/contract/chatmodel"
"github.com/coze-dev/coze-studio/backend/infra/contract/document"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
)
type ListKnowledgeRequest struct {
IDs []int64
SpaceID *int64
AppID *int64
Name *string // 完全匹配
Status []int32
UserID *int64
Query *string // 模糊匹配
Page *int
PageSize *int
Order *Order
OrderType *OrderType
FormatType *DocumentType
}
type Order int32
const (
OrderCreatedAt Order = 1
OrderUpdatedAt Order = 2
)
type OrderType int32
const (
OrderTypeAsc OrderType = 1
OrderTypeDesc OrderType = 2
)
type DocumentType int64
const (
DocumentTypeText DocumentType = 0 // 文本
DocumentTypeTable DocumentType = 1 // 表格
DocumentTypeImage DocumentType = 2 // 图片
DocumentTypeUnknown DocumentType = 9 // 未知
)
type ListKnowledgeResponse struct {
KnowledgeList []*Knowledge
Total int64
}
type Knowledge struct {
Info
SliceHit int64
Type DocumentType
Status KnowledgeStatus
}
type Info struct {
ID int64
Name string
Description string
IconURI string
IconURL string
CreatorID int64
SpaceID int64
AppID int64
CreatedAtMs int64
UpdatedAtMs int64
DeletedAtMs int64
}
type KnowledgeStatus int64
const (
KnowledgeStatusInit KnowledgeStatus = 0
KnowledgeStatusEnable KnowledgeStatus = 1
KnowledgeStatusDisable KnowledgeStatus = 3
)
type RetrieveRequest struct {
Query string
ChatHistory []*schema.Message
// 从指定的知识库和文档中召回
KnowledgeIDs []int64
DocumentIDs []int64 // todo: 确认下这个场景
// 召回策略
Strategy *RetrievalStrategy
// 用于 nl2sql 和 message to query 的 chat model config
ChatModelProtocol *chatmodel.Protocol
ChatModelConfig *chatmodel.Config
}
type RetrievalStrategy struct {
TopK *int64 // 1-10 default 3
MinScore *float64 // 0.01-0.99 default 0.5
MaxTokens *int64
SelectType SelectType // 调用方式
SearchType SearchType // 搜索策略
EnableQueryRewrite bool
EnableRerank bool
EnableNL2SQL bool
}
type SelectType int64
const (
SelectTypeAuto = 0 // 自动调用
SelectTypeOnDemand = 1 // 按需调用
)
type SearchType int64
const (
SearchTypeSemantic SearchType = 0 // 语义
SearchTypeFullText SearchType = 1 // 全文
SearchTypeHybrid SearchType = 2 // 混合
)
type RetrieveResponse struct {
RetrieveSlices []*RetrieveSlice
}
type RetrieveSlice struct {
Slice *Slice
Score float64
}
type Slice struct {
Info
KnowledgeID int64
DocumentID int64
DocumentName string
RawContent []*SliceContent
SliceStatus SliceStatus
ByteCount int64 // 切片 bytes
CharCount int64 // 切片字符数
Sequence int64 // 切片位置序号
Hit int64 // 命中次数
Extra map[string]string
}
func (s *Slice) GetSliceContent() string {
if len(s.RawContent) == 0 {
return ""
}
if s.RawContent[0].Type == SliceContentTypeTable {
contentMap := map[string]string{}
for _, column := range s.RawContent[0].Table.Columns {
contentMap[column.ColumnName] = column.GetStringValue()
}
byteData, err := sonic.Marshal(contentMap)
if err != nil {
return ""
}
return string(byteData)
}
data := ""
for i := range s.RawContent {
item := s.RawContent[i]
if item == nil {
continue
}
if item.Type == SliceContentTypeTable {
var contentMap map[string]string
for _, column := range s.RawContent[0].Table.Columns {
contentMap[column.ColumnName] = column.GetStringValue()
}
byteData, err := sonic.Marshal(contentMap)
if err != nil {
return ""
}
data += string(byteData)
}
if item.Type == SliceContentTypeText {
data += ptr.From(item.Text)
}
}
return data
}
type SliceContent struct {
Type SliceContentType
Text *string
Image *SliceImage
Table *SliceTable
}
type SliceStatus int64
const (
SliceStatusInit SliceStatus = 0 // 初始化
SliceStatusFinishStore SliceStatus = 1 // searchStore存储完成
SliceStatusFailed SliceStatus = 9 // 失败
)
type SliceContentType int64
const (
SliceContentTypeText SliceContentType = 0
//SliceContentTypeImage SliceContentType = 1
SliceContentTypeTable SliceContentType = 2
)
type SliceImage struct {
Base64 []byte
URI string
OCR bool // 是否使用 ocr 提取了文本
OCRText *string
}
type SliceTable struct { // table slice 为一行数据
Columns []*document.ColumnData
}
type DeleteKnowledgeRequest struct {
KnowledgeID int64
}
type GetKnowledgeByIDRequest struct {
KnowledgeID int64
}
type GetKnowledgeByIDResponse struct {
Knowledge *Knowledge
}
type MGetKnowledgeByIDRequest struct {
KnowledgeIDs []int64
}
type MGetKnowledgeByIDResponse struct {
Knowledge []*Knowledge
}
type CopyKnowledgeRequest struct {
KnowledgeID int64
TargetAppID int64
TargetSpaceID int64
TargetUserID int64
TaskUniqKey string
}
type CopyStatus int64
const (
CopyStatus_Successful CopyStatus = 1
CopyStatus_Processing CopyStatus = 2
CopyStatus_Failed CopyStatus = 3
CopyStatus_KeepOrigin CopyStatus = 4
)
type CopyKnowledgeResponse struct {
OriginKnowledgeID int64
TargetKnowledgeID int64
CopyStatus CopyStatus
ErrMsg string
}
type MoveKnowledgeToLibraryRequest struct {
KnowledgeID int64
}

View File

@ -0,0 +1,87 @@
package message
import (
"github.com/cloudwego/eino/schema"
"github.com/coze-dev/coze-studio/backend/api/model/conversation/message"
)
type Message struct {
ID int64 `json:"id"`
ConversationID int64 `json:"conversation_id"`
RunID int64 `json:"run_id"`
AgentID int64 `json:"agent_id"`
SectionID int64 `json:"section_id"`
Content string `json:"content"`
MultiContent []*InputMetaData `json:"multi_content"`
ContentType ContentType `json:"content_type"`
DisplayContent string `json:"display_content"`
Role schema.RoleType `json:"role"`
Name string `json:"name"`
Status MessageStatus `json:"status"`
MessageType MessageType `json:"message_type"`
ModelContent string `json:"model_content"`
Position int32 `json:"position"`
UserID string `json:"user_id"`
Ext map[string]string `json:"ext"`
ReasoningContent string `json:"reasoning_content"`
RequiredAction *message.RequiredAction `json:"required_action"`
CreatedAt int64 `json:"created_at"`
UpdatedAt int64 `json:"updated_at"`
}
type InputMetaData struct {
Type InputType `json:"type"`
Text string `json:"text"`
FileData []*FileData `json:"file_data"`
}
type MessageStatus int32
const (
MessageStatusAvailable MessageStatus = 1
MessageStatusDeleted MessageStatus = 2
MessageStatusBroken MessageStatus = 4
)
type InputType string
const (
InputTypeText InputType = "text"
InputTypeFile InputType = "file"
InputTypeImage InputType = "image"
InputTypeVideo InputType = "video"
InputTypeAudio InputType = "audio"
)
type FileData struct {
Url string `json:"url"`
Name string `json:"name"`
}
type ContentType string
const (
ContentTypeText ContentType = "text"
ContentTypeImage ContentType = "image"
ContentTypeVideo ContentType = "video"
ContentTypeMusic ContentType = "music"
ContentTypeCard ContentType = "card"
ContentTypeWidget ContentType = "widget"
ContentTypeAPP ContentType = "app"
ContentTypeMix ContentType = "mix"
)
type MessageType string
const (
MessageTypeAck MessageType = "ack"
MessageTypeQuestion MessageType = "question"
MessageTypeFunctionCall MessageType = "function_call"
MessageTypeToolResponse MessageType = "tool_response"
MessageTypeKnowledge MessageType = "knowledge"
MessageTypeAnswer MessageType = "answer"
MessageTypeFlowUp MessageType = "follow_up"
MessageTypeInterrupt MessageType = "interrupt"
MessageTypeVerbose MessageType = "verbose"
)

View File

@ -0,0 +1,68 @@
package modelmgr
type ParameterName string
const (
Temperature ParameterName = "temperature"
TopP ParameterName = "top_p"
TopK ParameterName = "top_k"
MaxTokens ParameterName = "max_tokens"
RespFormat ParameterName = "response_format"
FrequencyPenalty ParameterName = "frequency_penalty"
PresencePenalty ParameterName = "presence_penalty"
)
type ValueType string
const (
ValueTypeInt ValueType = "int"
ValueTypeFloat ValueType = "float"
ValueTypeBoolean ValueType = "boolean"
ValueTypeString ValueType = "string"
)
type DefaultType string
const (
DefaultTypeDefault DefaultType = "default_val"
DefaultTypeCreative DefaultType = "creative"
DefaultTypeBalance DefaultType = "balance"
DefaultTypePrecise DefaultType = "precise"
)
// Deprecated
type Scenario int64 // 模型实体使用场景
type Modal string
const (
ModalText Modal = "text"
ModalImage Modal = "image"
ModalFile Modal = "file"
ModalAudio Modal = "audio"
ModalVideo Modal = "video"
)
type ModelMetaStatus int64 // 模型实体状态
const (
StatusInUse ModelMetaStatus = 1 // 应用中,可使用可新建
StatusPending ModelMetaStatus = 5 // 待下线,可使用不可新建
StatusDeleted ModelMetaStatus = 10 // 已下线,不可使用不可新建
)
type Widget string
const (
WidgetSlider Widget = "slider"
WidgetRadioButtons Widget = "radio_buttons"
)
type ModelEntityStatus int64
const (
ModelEntityStatusDefault ModelEntityStatus = 0
ModelEntityStatusInUse ModelEntityStatus = 1
ModelEntityStatusPending ModelEntityStatus = 5
ModelEntityStatusDeleted ModelEntityStatus = 10
)

View File

@ -0,0 +1,171 @@
package modelmgr
import (
"fmt"
"strconv"
"github.com/coze-dev/coze-studio/backend/infra/contract/chatmodel"
"github.com/coze-dev/coze-studio/backend/pkg/i18n"
)
type MGetModelRequest struct {
IDs []int64
}
type Model struct {
ID int64 `yaml:"id"`
Name string `yaml:"name"`
Description string `yaml:"description"`
DefaultParameters []*Parameter `yaml:"default_parameters"`
CreatedAtMs int64
UpdatedAtMs int64
DeletedAtMs int64
Meta ModelMeta `yaml:"meta"`
}
type Parameter struct {
Name ParameterName `json:"name" yaml:"name"`
Label *MultilingualText `json:"label,omitempty" yaml:"label,omitempty"`
Desc *MultilingualText `json:"desc" yaml:"desc"`
Type ValueType `json:"type" yaml:"type"`
Min string `json:"min" yaml:"min"`
Max string `json:"max" yaml:"max"`
DefaultVal DefaultValue `json:"default_val" yaml:"default_val"`
Precision int `json:"precision,omitempty" yaml:"precision,omitempty"` // float precision, default 2
Options []*ParamOption `json:"options" yaml:"options"` // enum options
Style DisplayStyle `json:"param_class" yaml:"style"`
}
func (p *Parameter) GetFloat(tp DefaultType) (float64, error) {
if p.Type != ValueTypeFloat {
return 0, fmt.Errorf("unexpected paramerter type, name=%v, expect=%v, given=%v",
p.Name, ValueTypeFloat, p.Type)
}
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return 0, fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return strconv.ParseFloat(val, 64)
}
func (p *Parameter) GetInt(tp DefaultType) (int64, error) {
if p.Type != ValueTypeInt {
return 0, fmt.Errorf("unexpected paramerter type, name=%v, expect=%v, given=%v",
p.Name, ValueTypeInt, p.Type)
}
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return 0, fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return strconv.ParseInt(val, 10, 64)
}
func (p *Parameter) GetBool(tp DefaultType) (bool, error) {
if p.Type != ValueTypeBoolean {
return false, fmt.Errorf("unexpected paramerter type, name=%v, expect=%v, given=%v",
p.Name, ValueTypeBoolean, p.Type)
}
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return false, fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return strconv.ParseBool(val)
}
func (p *Parameter) GetString(tp DefaultType) (string, error) {
if tp != DefaultTypeDefault && p.DefaultVal[tp] == "" {
tp = DefaultTypeDefault
}
val, ok := p.DefaultVal[tp]
if !ok {
return "", fmt.Errorf("unexpected default type, name=%v, type=%v", p.Name, tp)
}
return val, nil
}
type ModelMeta struct {
ID int64 `yaml:"id"`
Name string `yaml:"name"`
IconURI string `yaml:"icon_uri"`
IconURL string `yaml:"icon_url"`
Description *MultilingualText `yaml:"description"`
CreatedAtMs int64
UpdatedAtMs int64
DeletedAtMs int64
Protocol chatmodel.Protocol `yaml:"protocol"` // 模型通信协议
Capability *Capability `yaml:"capability"` // 模型能力
ConnConfig *chatmodel.Config `yaml:"conn_config"` // 模型连接配置
Status ModelMetaStatus `yaml:"status"` // 模型状态
}
type DefaultValue map[DefaultType]string
type DisplayStyle struct {
Widget Widget `json:"class_id" yaml:"widget"`
Label *MultilingualText `json:"label" yaml:"label"`
}
type ParamOption struct {
Label string `json:"label"`
Value string `json:"value"`
}
type Capability struct {
// Model supports function calling
FunctionCall bool `json:"function_call" yaml:"function_call" mapstructure:"function_call"`
// Input modals
InputModal []Modal `json:"input_modal,omitempty" yaml:"input_modal,omitempty" mapstructure:"input_modal,omitempty"`
// Input tokens
InputTokens int `json:"input_tokens" yaml:"input_tokens" mapstructure:"input_tokens"`
// Model supports json mode
JSONMode bool `json:"json_mode" yaml:"json_mode" mapstructure:"json_mode"`
// Max tokens
MaxTokens int `json:"max_tokens" yaml:"max_tokens" mapstructure:"max_tokens"`
// Output modals
OutputModal []Modal `json:"output_modal,omitempty" yaml:"output_modal,omitempty" mapstructure:"output_modal,omitempty"`
// Output tokens
OutputTokens int `json:"output_tokens" yaml:"output_tokens" mapstructure:"output_tokens"`
// Model supports prefix caching
PrefixCaching bool `json:"prefix_caching" yaml:"prefix_caching" mapstructure:"prefix_caching"`
// Model supports reasoning
Reasoning bool `json:"reasoning" yaml:"reasoning" mapstructure:"reasoning"`
// Model supports prefill response
PrefillResponse bool `json:"prefill_response" yaml:"prefill_response" mapstructure:"prefill_response"`
}
type MultilingualText struct {
ZH string `json:"zh,omitempty" yaml:"zh,omitempty"`
EN string `json:"en,omitempty" yaml:"en,omitempty"`
}
func (m *MultilingualText) Read(locale i18n.Locale) string {
if m == nil {
return ""
}
switch locale {
case i18n.LocaleZH:
return m.ZH
case i18n.LocaleEN:
return m.EN
default:
return m.EN
}
}

View File

@ -0,0 +1,110 @@
package plugin
import "github.com/getkin/kin-openapi/openapi3"
type PluginType string
const (
PluginTypeOfCloud PluginType = "openapi"
)
type AuthzType string
const (
AuthzTypeOfNone AuthzType = "none"
AuthzTypeOfService AuthzType = "service_http"
AuthzTypeOfOAuth AuthzType = "oauth"
)
type AuthzSubType string
const (
AuthzSubTypeOfServiceAPIToken AuthzSubType = "token/api_key"
AuthzSubTypeOfOAuthAuthorizationCode AuthzSubType = "authorization_code"
AuthzSubTypeOfOAuthClientCredentials AuthzSubType = "client_credentials"
)
type HTTPParamLocation string
const (
ParamInHeader HTTPParamLocation = openapi3.ParameterInHeader
ParamInPath HTTPParamLocation = openapi3.ParameterInPath
ParamInQuery HTTPParamLocation = openapi3.ParameterInQuery
ParamInBody HTTPParamLocation = "body"
)
type ActivatedStatus int32
const (
ActivateTool ActivatedStatus = 0
DeactivateTool ActivatedStatus = 1
)
type ProjectType int8
const (
ProjectTypeOfAgent ProjectType = 1
ProjectTypeOfAPP ProjectType = 2
)
type ExecuteScene string
const (
ExecSceneOfOnlineAgent ExecuteScene = "online_agent"
ExecSceneOfDraftAgent ExecuteScene = "draft_agent"
ExecSceneOfWorkflow ExecuteScene = "workflow"
ExecSceneOfToolDebug ExecuteScene = "tool_debug"
)
type InvalidResponseProcessStrategy int8
const (
InvalidResponseProcessStrategyOfReturnRaw InvalidResponseProcessStrategy = 0 // If the value of a field is invalid, the raw response value of the field is returned.
InvalidResponseProcessStrategyOfReturnDefault InvalidResponseProcessStrategy = 1 // If the value of a field is invalid, the default value of the field is returned.
)
const (
APISchemaExtendAssistType = "x-assist-type"
APISchemaExtendGlobalDisable = "x-global-disable"
APISchemaExtendLocalDisable = "x-local-disable"
APISchemaExtendVariableRef = "x-variable-ref"
APISchemaExtendAuthMode = "x-auth-mode"
)
type ToolAuthMode string
const (
ToolAuthModeOfRequired ToolAuthMode = "required"
ToolAuthModeOfSupported ToolAuthMode = "supported"
ToolAuthModeOfDisabled ToolAuthMode = "disabled"
)
type APIFileAssistType string
const (
AssistTypeFile APIFileAssistType = "file"
AssistTypeImage APIFileAssistType = "image"
AssistTypeDoc APIFileAssistType = "doc"
AssistTypePPT APIFileAssistType = "ppt"
AssistTypeCode APIFileAssistType = "code"
AssistTypeExcel APIFileAssistType = "excel"
AssistTypeZIP APIFileAssistType = "zip"
AssistTypeVideo APIFileAssistType = "video"
AssistTypeAudio APIFileAssistType = "audio"
AssistTypeTXT APIFileAssistType = "txt"
)
type CopyScene string
const (
CopySceneOfToAPP CopyScene = "to_app"
CopySceneOfToLibrary CopyScene = "to_library"
CopySceneOfDuplicate CopyScene = "duplicate"
CopySceneOfAPPDuplicate CopyScene = "app_duplicate"
)
type InterruptEventType string
const (
InterruptEventTypeOfToolNeedOAuth InterruptEventType = "tool_need_oauth"
)

View File

@ -0,0 +1,270 @@
package plugin
import (
"net/http"
"github.com/getkin/kin-openapi/openapi3"
common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
)
var httpParamLocations = map[common.ParameterLocation]HTTPParamLocation{
common.ParameterLocation_Path: ParamInPath,
common.ParameterLocation_Query: ParamInQuery,
common.ParameterLocation_Body: ParamInBody,
common.ParameterLocation_Header: ParamInHeader,
}
func ToHTTPParamLocation(loc common.ParameterLocation) (HTTPParamLocation, bool) {
_loc, ok := httpParamLocations[loc]
return _loc, ok
}
var thriftHTTPParamLocations = func() map[HTTPParamLocation]common.ParameterLocation {
locations := make(map[HTTPParamLocation]common.ParameterLocation, len(httpParamLocations))
for k, v := range httpParamLocations {
locations[v] = k
}
return locations
}()
func ToThriftHTTPParamLocation(loc HTTPParamLocation) (common.ParameterLocation, bool) {
_loc, ok := thriftHTTPParamLocations[loc]
return _loc, ok
}
var openapiTypes = map[common.ParameterType]string{
common.ParameterType_String: openapi3.TypeString,
common.ParameterType_Integer: openapi3.TypeInteger,
common.ParameterType_Number: openapi3.TypeNumber,
common.ParameterType_Object: openapi3.TypeObject,
common.ParameterType_Array: openapi3.TypeArray,
common.ParameterType_Bool: openapi3.TypeBoolean,
}
func ToOpenapiParamType(typ common.ParameterType) (string, bool) {
_typ, ok := openapiTypes[typ]
return _typ, ok
}
var thriftParameterTypes = func() map[string]common.ParameterType {
types := make(map[string]common.ParameterType, len(openapiTypes))
for k, v := range openapiTypes {
types[v] = k
}
return types
}()
func ToThriftParamType(typ string) (common.ParameterType, bool) {
_typ, ok := thriftParameterTypes[typ]
return _typ, ok
}
var apiAssistTypes = map[common.AssistParameterType]APIFileAssistType{
common.AssistParameterType_DEFAULT: AssistTypeFile,
common.AssistParameterType_IMAGE: AssistTypeImage,
common.AssistParameterType_DOC: AssistTypeDoc,
common.AssistParameterType_PPT: AssistTypePPT,
common.AssistParameterType_CODE: AssistTypeCode,
common.AssistParameterType_EXCEL: AssistTypeExcel,
common.AssistParameterType_ZIP: AssistTypeZIP,
common.AssistParameterType_VIDEO: AssistTypeVideo,
common.AssistParameterType_AUDIO: AssistTypeAudio,
common.AssistParameterType_TXT: AssistTypeTXT,
}
func ToAPIAssistType(typ common.AssistParameterType) (APIFileAssistType, bool) {
_typ, ok := apiAssistTypes[typ]
return _typ, ok
}
var thriftAPIAssistTypes = func() map[APIFileAssistType]common.AssistParameterType {
types := make(map[APIFileAssistType]common.AssistParameterType, len(apiAssistTypes))
for k, v := range apiAssistTypes {
types[v] = k
}
return types
}()
func ToThriftAPIAssistType(typ APIFileAssistType) (common.AssistParameterType, bool) {
_typ, ok := thriftAPIAssistTypes[typ]
return _typ, ok
}
func IsValidAPIAssistType(typ APIFileAssistType) bool {
_, ok := thriftAPIAssistTypes[typ]
return ok
}
var httpMethods = map[common.APIMethod]string{
common.APIMethod_GET: http.MethodGet,
common.APIMethod_POST: http.MethodPost,
common.APIMethod_PUT: http.MethodPut,
common.APIMethod_DELETE: http.MethodDelete,
common.APIMethod_PATCH: http.MethodPatch,
}
var thriftAPIMethods = func() map[string]common.APIMethod {
methods := make(map[string]common.APIMethod, len(httpMethods))
for k, v := range httpMethods {
methods[v] = k
}
return methods
}()
func ToThriftAPIMethod(method string) (common.APIMethod, bool) {
_method, ok := thriftAPIMethods[method]
return _method, ok
}
func ToHTTPMethod(method common.APIMethod) (string, bool) {
_method, ok := httpMethods[method]
return _method, ok
}
var assistTypeToFormat = map[APIFileAssistType]string{
AssistTypeFile: "file_url",
AssistTypeImage: "image_url",
AssistTypeDoc: "doc_url",
AssistTypePPT: "ppt_url",
AssistTypeCode: "code_url",
AssistTypeExcel: "excel_url",
AssistTypeZIP: "zip_url",
AssistTypeVideo: "video_url",
AssistTypeAudio: "audio_url",
AssistTypeTXT: "txt_url",
}
func AssistTypeToFormat(typ APIFileAssistType) (string, bool) {
format, ok := assistTypeToFormat[typ]
return format, ok
}
var formatToAssistType = func() map[string]APIFileAssistType {
types := make(map[string]APIFileAssistType, len(assistTypeToFormat))
for k, v := range assistTypeToFormat {
types[v] = k
}
return types
}()
func FormatToAssistType(format string) (APIFileAssistType, bool) {
typ, ok := formatToAssistType[format]
return typ, ok
}
var assistTypeToThriftFormat = map[APIFileAssistType]common.PluginParamTypeFormat{
AssistTypeFile: common.PluginParamTypeFormat_FileUrl,
AssistTypeImage: common.PluginParamTypeFormat_ImageUrl,
AssistTypeDoc: common.PluginParamTypeFormat_DocUrl,
AssistTypePPT: common.PluginParamTypeFormat_PptUrl,
AssistTypeCode: common.PluginParamTypeFormat_CodeUrl,
AssistTypeExcel: common.PluginParamTypeFormat_ExcelUrl,
AssistTypeZIP: common.PluginParamTypeFormat_ZipUrl,
AssistTypeVideo: common.PluginParamTypeFormat_VideoUrl,
AssistTypeAudio: common.PluginParamTypeFormat_AudioUrl,
AssistTypeTXT: common.PluginParamTypeFormat_TxtUrl,
}
func AssistTypeToThriftFormat(typ APIFileAssistType) (common.PluginParamTypeFormat, bool) {
format, ok := assistTypeToThriftFormat[typ]
return format, ok
}
var authTypes = map[common.AuthorizationType]AuthzType{
common.AuthorizationType_None: AuthzTypeOfNone,
common.AuthorizationType_Service: AuthzTypeOfService,
common.AuthorizationType_OAuth: AuthzTypeOfOAuth,
common.AuthorizationType_Standard: AuthzTypeOfOAuth, // deprecated, the same as OAuth
}
func ToAuthType(typ common.AuthorizationType) (AuthzType, bool) {
_type, ok := authTypes[typ]
return _type, ok
}
var thriftAuthTypes = func() map[AuthzType]common.AuthorizationType {
types := make(map[AuthzType]common.AuthorizationType, len(authTypes))
for k, v := range authTypes {
if v == AuthzTypeOfOAuth {
types[v] = common.AuthorizationType_OAuth
} else {
types[v] = k
}
}
return types
}()
func ToThriftAuthType(typ AuthzType) (common.AuthorizationType, bool) {
_type, ok := thriftAuthTypes[typ]
return _type, ok
}
var subAuthTypes = map[int32]AuthzSubType{
int32(common.ServiceAuthSubType_ApiKey): AuthzSubTypeOfServiceAPIToken,
int32(common.ServiceAuthSubType_OAuthAuthorizationCode): AuthzSubTypeOfOAuthAuthorizationCode,
}
func ToAuthSubType(typ int32) (AuthzSubType, bool) {
_type, ok := subAuthTypes[typ]
return _type, ok
}
var thriftSubAuthTypes = func() map[AuthzSubType]int32 {
types := make(map[AuthzSubType]int32, len(subAuthTypes))
for k, v := range subAuthTypes {
types[v] = int32(k)
}
return types
}()
func ToThriftAuthSubType(typ AuthzSubType) (int32, bool) {
_type, ok := thriftSubAuthTypes[typ]
return _type, ok
}
var pluginTypes = map[common.PluginType]PluginType{
common.PluginType_PLUGIN: PluginTypeOfCloud,
}
func ToPluginType(typ common.PluginType) (PluginType, bool) {
_type, ok := pluginTypes[typ]
return _type, ok
}
var thriftPluginTypes = func() map[PluginType]common.PluginType {
types := make(map[PluginType]common.PluginType, len(pluginTypes))
for k, v := range pluginTypes {
types[v] = k
}
return types
}()
func ToThriftPluginType(typ PluginType) (common.PluginType, bool) {
_type, ok := thriftPluginTypes[typ]
return _type, ok
}
var apiAuthModes = map[common.PluginToolAuthType]ToolAuthMode{
common.PluginToolAuthType_Required: ToolAuthModeOfRequired,
common.PluginToolAuthType_Supported: ToolAuthModeOfSupported,
common.PluginToolAuthType_Disable: ToolAuthModeOfDisabled,
}
func ToAPIAuthMode(mode common.PluginToolAuthType) (ToolAuthMode, bool) {
_mode, ok := apiAuthModes[mode]
return _mode, ok
}
var thriftAPIAuthModes = func() map[ToolAuthMode]common.PluginToolAuthType {
modes := make(map[ToolAuthMode]common.PluginToolAuthType, len(apiAuthModes))
for k, v := range apiAuthModes {
modes[v] = k
}
return modes
}()
func ToThriftAPIAuthMode(mode ToolAuthMode) (common.PluginToolAuthType, bool) {
_mode, ok := thriftAPIAuthModes[mode]
return _mode, ok
}

View File

@ -0,0 +1,429 @@
package plugin
import (
"context"
"net/http"
"net/url"
"strconv"
"strings"
"github.com/getkin/kin-openapi/openapi3"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
"github.com/coze-dev/coze-studio/backend/pkg/logs"
"github.com/coze-dev/coze-studio/backend/types/errno"
"github.com/cloudwego/eino/schema"
)
type Openapi3T openapi3.T
func (ot Openapi3T) Validate(ctx context.Context) (err error) {
err = ptr.Of(openapi3.T(ot)).Validate(ctx)
if err != nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey, err.Error()))
}
if ot.Info == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"info is required"))
}
if ot.Info.Title == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"the title of info is required"))
}
if ot.Info.Description == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"the description of info is required"))
}
if len(ot.Servers) != 1 {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"server is required and only one server is allowed"))
}
serverURL := ot.Servers[0].URL
urlSchema, err := url.Parse(serverURL)
if err != nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"invalid server url '%s'", serverURL))
}
if urlSchema.Scheme != "https" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"server url must start with 'https://'"))
}
if urlSchema.Host == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"invalid server url '%s'", serverURL))
}
if len(serverURL) > 512 {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"server url '%s' is too long", serverURL))
}
for _, pathItem := range ot.Paths {
for _, op := range pathItem.Operations() {
err = NewOpenapi3Operation(op).Validate(ctx)
if err != nil {
return err
}
}
}
return nil
}
func NewOpenapi3Operation(op *openapi3.Operation) *Openapi3Operation {
return &Openapi3Operation{
Operation: op,
}
}
type Openapi3Operation struct {
*openapi3.Operation
}
func (op *Openapi3Operation) MarshalJSON() ([]byte, error) {
return op.Operation.MarshalJSON()
}
func (op *Openapi3Operation) UnmarshalJSON(data []byte) error {
op.Operation = &openapi3.Operation{}
return op.Operation.UnmarshalJSON(data)
}
func (op *Openapi3Operation) Validate(ctx context.Context) (err error) {
err = op.Operation.Validate(ctx)
if err != nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey, "operation is invalid, err=%s", err))
}
if op.OperationID == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey, "operationID is required"))
}
if op.Summary == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey, "summary is required"))
}
err = validateOpenapi3RequestBody(op.RequestBody)
if err != nil {
return err
}
err = validateOpenapi3Parameters(op.Parameters)
if err != nil {
return err
}
err = validateOpenapi3Responses(op.Responses)
if err != nil {
return err
}
return nil
}
func (op *Openapi3Operation) ToEinoSchemaParameterInfo(ctx context.Context) (map[string]*schema.ParameterInfo, error) {
convertType := func(openapiType string) schema.DataType {
switch openapiType {
case openapi3.TypeString:
return schema.String
case openapi3.TypeInteger:
return schema.Integer
case openapi3.TypeObject:
return schema.Object
case openapi3.TypeArray:
return schema.Array
case openapi3.TypeBoolean:
return schema.Boolean
case openapi3.TypeNumber:
return schema.Number
default:
return schema.Null
}
}
var convertReqBody func(sc *openapi3.Schema, isRequired bool) (*schema.ParameterInfo, error)
convertReqBody = func(sc *openapi3.Schema, isRequired bool) (*schema.ParameterInfo, error) {
if disabledParam(sc) {
return nil, nil
}
paramInfo := &schema.ParameterInfo{
Type: convertType(sc.Type),
Desc: sc.Description,
Required: isRequired,
}
switch sc.Type {
case openapi3.TypeObject:
required := slices.ToMap(sc.Required, func(e string) (string, bool) {
return e, true
})
subParams := make(map[string]*schema.ParameterInfo, len(sc.Properties))
for paramName, prop := range sc.Properties {
subParam, err := convertReqBody(prop.Value, required[paramName])
if err != nil {
return nil, err
}
subParams[paramName] = subParam
}
paramInfo.SubParams = subParams
case openapi3.TypeArray:
ele, err := convertReqBody(sc.Items.Value, isRequired)
if err != nil {
return nil, err
}
paramInfo.ElemInfo = ele
case openapi3.TypeString, openapi3.TypeInteger, openapi3.TypeBoolean, openapi3.TypeNumber:
return paramInfo, nil
default:
return nil, errorx.New(errno.ErrSearchInvalidParamCode, errorx.KVf(errno.PluginMsgKey,
"unsupported json type '%s'", sc.Type))
}
return paramInfo, nil
}
result := make(map[string]*schema.ParameterInfo)
for _, prop := range op.Parameters {
paramVal := prop.Value
schemaVal := paramVal.Schema.Value
if schemaVal.Type == openapi3.TypeObject || schemaVal.Type == openapi3.TypeArray {
continue
}
if disabledParam(prop.Value.Schema.Value) {
continue
}
paramInfo := &schema.ParameterInfo{
Type: convertType(schemaVal.Type),
Desc: paramVal.Description,
Required: paramVal.Required,
}
if _, ok := result[paramVal.Name]; ok {
logs.CtxWarnf(ctx, "duplicate parameter name '%s'", paramVal.Name)
continue
}
result[paramVal.Name] = paramInfo
}
if op.RequestBody == nil || op.RequestBody.Value == nil || len(op.RequestBody.Value.Content) == 0 {
return result, nil
}
for _, mType := range op.RequestBody.Value.Content {
schemaVal := mType.Schema.Value
if len(schemaVal.Properties) == 0 {
continue
}
required := slices.ToMap(schemaVal.Required, func(e string) (string, bool) {
return e, true
})
for paramName, prop := range schemaVal.Properties {
paramInfo, err := convertReqBody(prop.Value, required[paramName])
if err != nil {
return nil, err
}
if _, ok := result[paramName]; ok {
logs.CtxWarnf(ctx, "duplicate parameter name '%s'", paramName)
continue
}
result[paramName] = paramInfo
}
break // 只取一种 MIME
}
return result, nil
}
func validateOpenapi3RequestBody(bodyRef *openapi3.RequestBodyRef) (err error) {
if bodyRef == nil {
return nil
}
if bodyRef.Value == nil || len(bodyRef.Value.Content) == 0 {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"request body is required"))
}
body := bodyRef.Value
if len(body.Content) != 1 {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"request body only supports one media type"))
}
var mType *openapi3.MediaType
for _, ct := range mediaTypeArray {
var ok bool
mType, ok = body.Content[ct]
if ok {
break
}
}
if mType == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"invalid media type, request body only the following types: [%s]", strings.Join(mediaTypeArray, ", ")))
}
if mType.Schema == nil || mType.Schema.Value == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"request body schema is required"))
}
sc := mType.Schema.Value
if sc.Type == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"request body only supports 'object' type"))
}
if sc.Type != openapi3.TypeObject {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"request body only supports 'object' type"))
}
return nil
}
func validateOpenapi3Parameters(params openapi3.Parameters) (err error) {
if len(params) == 0 {
return nil
}
for _, param := range params {
if param == nil || param.Value == nil || param.Value.Schema == nil || param.Value.Schema.Value == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"parameter schema is required"))
}
paramVal := param.Value
if paramVal.In == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"parameter location is required"))
}
if paramVal.In == string(ParamInBody) {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"the location of parameter '%s' cannot be 'body'", paramVal.Name))
}
paramSchema := paramVal.Schema.Value
if paramSchema.Type == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"the type of parameter '%s' is required", paramVal.Name))
}
if paramSchema.Type == openapi3.TypeObject {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"the type of parameter '%s' cannot be 'object'", paramVal.Name))
}
if paramVal.In == openapi3.ParameterInPath && paramSchema.Type == openapi3.TypeArray {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KVf(errno.PluginMsgKey,
"the type of parameter '%s' cannot be 'array'", paramVal.Name))
}
}
return nil
}
// MIME Type
const (
MediaTypeJson = "application/json"
MediaTypeProblemJson = "application/problem+json"
MediaTypeFormURLEncoded = "application/x-www-form-urlencoded"
MediaTypeXYaml = "application/x-yaml"
MediaTypeYaml = "application/yaml"
)
var mediaTypeArray = []string{
MediaTypeJson,
MediaTypeProblemJson,
MediaTypeFormURLEncoded,
MediaTypeXYaml,
MediaTypeYaml,
}
func validateOpenapi3Responses(responses openapi3.Responses) (err error) {
if len(responses) == 0 {
return nil
}
// default status 不处理
// 只处理 '200' status
if len(responses) != 1 {
if len(responses) != 2 {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response only supports '200' status"))
} else if _, ok := responses["default"]; !ok {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response only supports '200' status"))
}
}
resp, ok := responses[strconv.Itoa(http.StatusOK)]
if !ok || resp == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response only supports '200' status"))
}
if resp.Value == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response schema is required"))
}
if len(resp.Value.Content) != 1 {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response only supports 'application/json' media type"))
}
mType, ok := resp.Value.Content[MediaTypeJson]
if !ok || mType == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response only supports 'application/json' media type"))
}
if mType.Schema == nil || mType.Schema.Value == nil {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"the media type schema of response is required"))
}
sc := mType.Schema.Value
if sc.Type == "" {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response body only supports 'object' type"))
}
if sc.Type != openapi3.TypeObject {
return errorx.New(errno.ErrPluginInvalidOpenapi3Doc, errorx.KV(errno.PluginMsgKey,
"response body only supports 'object' type"))
}
return nil
}
func disabledParam(schemaVal *openapi3.Schema) bool {
if len(schemaVal.Extensions) == 0 {
return false
}
globalDisable, localDisable := false, false
if v, ok := schemaVal.Extensions[APISchemaExtendLocalDisable]; ok {
localDisable = v.(bool)
}
if v, ok := schemaVal.Extensions[APISchemaExtendGlobalDisable]; ok {
globalDisable = v.(bool)
}
return globalDisable || localDisable
}

View File

@ -0,0 +1,51 @@
package plugin
type ExecuteToolOption struct {
ProjectInfo *ProjectInfo
AutoGenRespSchema bool
ToolVersion string
Operation *Openapi3Operation
InvalidRespProcessStrategy InvalidResponseProcessStrategy
}
type ExecuteToolOpt func(o *ExecuteToolOption)
type ProjectInfo struct {
ProjectID int64 // agentID or appID
ProjectVersion *string // if version si nil, use latest version
ProjectType ProjectType // agent or app
ConnectorID int64
}
func WithProjectInfo(info *ProjectInfo) ExecuteToolOpt {
return func(o *ExecuteToolOption) {
o.ProjectInfo = info
}
}
func WithToolVersion(version string) ExecuteToolOpt {
return func(o *ExecuteToolOption) {
o.ToolVersion = version
}
}
func WithOpenapiOperation(op *Openapi3Operation) ExecuteToolOpt {
return func(o *ExecuteToolOption) {
o.Operation = op
}
}
func WithInvalidRespProcessStrategy(strategy InvalidResponseProcessStrategy) ExecuteToolOpt {
return func(o *ExecuteToolOption) {
o.InvalidRespProcessStrategy = strategy
}
}
func WithAutoGenRespSchema() ExecuteToolOpt {
return func(o *ExecuteToolOption) {
o.AutoGenRespSchema = true
}
}

View File

@ -0,0 +1,153 @@
package plugin
import (
"github.com/getkin/kin-openapi/openapi3"
api "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
)
type VersionPlugin struct {
PluginID int64
Version string
}
type VersionTool struct {
ToolID int64
Version string
}
type MGetPluginLatestVersionResponse struct {
Versions map[int64]string // pluginID vs version
}
type PluginInfo struct {
ID int64
PluginType api.PluginType
SpaceID int64
DeveloperID int64
APPID *int64
RefProductID *int64 // for product plugin
IconURI *string
ServerURL *string
Version *string
VersionDesc *string
CreatedAt int64
UpdatedAt int64
Manifest *PluginManifest
OpenapiDoc *Openapi3T
}
func (p PluginInfo) SetName(name string) {
if p.Manifest == nil || p.OpenapiDoc == nil {
return
}
p.Manifest.NameForModel = name
p.Manifest.NameForHuman = name
p.OpenapiDoc.Info.Title = name
}
func (p PluginInfo) GetName() string {
if p.Manifest == nil {
return ""
}
return p.Manifest.NameForHuman
}
func (p PluginInfo) GetDesc() string {
if p.Manifest == nil {
return ""
}
return p.Manifest.DescriptionForHuman
}
func (p PluginInfo) GetAuthInfo() *AuthV2 {
if p.Manifest == nil {
return nil
}
return p.Manifest.Auth
}
func (p PluginInfo) IsOfficial() bool {
return p.RefProductID != nil
}
func (p PluginInfo) GetIconURI() string {
if p.IconURI == nil {
return ""
}
return *p.IconURI
}
func (p PluginInfo) Published() bool {
return p.Version != nil
}
type VersionAgentTool struct {
ToolName *string
ToolID int64
AgentVersion *string
}
type MGetAgentToolsRequest struct {
AgentID int64
SpaceID int64
IsDraft bool
VersionAgentTools []VersionAgentTool
}
type ExecuteToolRequest struct {
UserID string
PluginID int64
ToolID int64
ExecDraftTool bool // if true, execute draft tool
ExecScene ExecuteScene
ArgumentsInJson string
}
type ExecuteToolResponse struct {
Tool *ToolInfo
Request string
TrimmedResp string
RawResp string
RespSchema openapi3.Responses
}
type PublishPluginRequest struct {
PluginID int64
Version string
VersionDesc string
}
type PublishAPPPluginsRequest struct {
APPID int64
Version string
}
type PublishAPPPluginsResponse struct {
FailedPlugins []*PluginInfo
AllDraftPlugins []*PluginInfo
}
type CheckCanPublishPluginsRequest struct {
PluginIDs []int64
Version string
}
type CheckCanPublishPluginsResponse struct {
InvalidPlugins []*PluginInfo
}
type ToolInterruptEvent struct {
Event InterruptEventType
ToolNeedOAuth *ToolNeedOAuthInterruptEvent
}
type ToolNeedOAuthInterruptEvent struct {
Message string
}

View File

@ -0,0 +1,497 @@
package plugin
import (
"encoding/json"
"net/url"
"strings"
api "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
"github.com/coze-dev/coze-studio/backend/domain/plugin/utils"
"github.com/coze-dev/coze-studio/backend/pkg/errorx"
"github.com/coze-dev/coze-studio/backend/types/errno"
"github.com/bytedance/sonic"
)
type PluginManifest struct {
SchemaVersion string `json:"schema_version" yaml:"schema_version"`
NameForModel string `json:"name_for_model" yaml:"name_for_model"`
NameForHuman string `json:"name_for_human" yaml:"name_for_human"`
DescriptionForModel string `json:"description_for_model" yaml:"description_for_model"`
DescriptionForHuman string `json:"description_for_human" yaml:"description_for_human"`
Auth *AuthV2 `json:"auth" yaml:"auth"`
LogoURL string `json:"logo_url" yaml:"logo_url"`
API APIDesc `json:"api" yaml:"api"`
CommonParams map[HTTPParamLocation][]*api.CommonParamSchema `json:"common_params" yaml:"common_params"`
}
func (mf *PluginManifest) Copy() (*PluginManifest, error) {
if mf == nil {
return mf, nil
}
b, err := json.Marshal(mf)
if err != nil {
return nil, err
}
mf_ := &PluginManifest{}
err = json.Unmarshal(b, mf_)
if err != nil {
return nil, err
}
return mf_, err
}
func (mf *PluginManifest) EncryptAuthPayload() (*PluginManifest, error) {
if mf == nil || mf.Auth == nil {
return mf, nil
}
mf_, err := mf.Copy()
if err != nil {
return nil, err
}
if mf_.Auth.Payload == "" {
return mf_, nil
}
payload_, err := utils.EncryptByAES([]byte(mf_.Auth.Payload), utils.AuthSecretKey)
if err != nil {
return nil, err
}
mf_.Auth.Payload = payload_
return mf_, nil
}
func (mf *PluginManifest) Validate(skipAuthPayload bool) (err error) {
if mf.SchemaVersion != "v1" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid schema version '%s'", mf.SchemaVersion))
}
if mf.NameForModel == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"name for model is required"))
}
if mf.NameForHuman == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"name for human is required"))
}
if mf.DescriptionForModel == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"description for model is required"))
}
if mf.DescriptionForHuman == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"description for human is required"))
}
if mf.API.Type != PluginTypeOfCloud {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid api type '%s'", mf.API.Type))
}
err = mf.validateAuthInfo(skipAuthPayload)
if err != nil {
return err
}
for loc := range mf.CommonParams {
if loc != ParamInBody &&
loc != ParamInHeader &&
loc != ParamInQuery &&
loc != ParamInPath {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid location '%s' in common params", loc))
}
}
return nil
}
func (mf *PluginManifest) validateAuthInfo(skipAuthPayload bool) (err error) {
if mf.Auth == nil {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"auth is required"))
}
if mf.Auth.Payload != "" {
js := json.RawMessage{}
err = sonic.UnmarshalString(mf.Auth.Payload, &js)
if err != nil {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload"))
}
}
if mf.Auth.Type == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"auth type is required"))
}
if mf.Auth.Type != AuthzTypeOfNone &&
mf.Auth.Type != AuthzTypeOfOAuth &&
mf.Auth.Type != AuthzTypeOfService {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid auth type '%s'", mf.Auth.Type))
}
if mf.Auth.Type == AuthzTypeOfNone {
return nil
}
if mf.Auth.SubType == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"sub-auth type is required"))
}
switch mf.Auth.SubType {
case AuthzSubTypeOfServiceAPIToken:
err = mf.validateServiceToken(skipAuthPayload)
//case AuthzSubTypeOfOAuthClientCredentials:
// err = mf.validateClientCredentials()
case AuthzSubTypeOfOAuthAuthorizationCode:
err = mf.validateAuthCode(skipAuthPayload)
default:
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid sub-auth type '%s'", mf.Auth.SubType))
}
if err != nil {
return err
}
return nil
}
func (mf *PluginManifest) validateServiceToken(skipAuthPayload bool) (err error) {
if mf.Auth.AuthOfAPIToken == nil {
err = sonic.UnmarshalString(mf.Auth.Payload, &mf.Auth.AuthOfAPIToken)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload"))
}
}
if skipAuthPayload {
return nil
}
apiToken := mf.Auth.AuthOfAPIToken
if apiToken.ServiceToken == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"service token is required"))
}
if apiToken.Key == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"key is required"))
}
loc := HTTPParamLocation(strings.ToLower(string(apiToken.Location)))
if loc != ParamInHeader && loc != ParamInQuery {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid location '%s'", apiToken.Location))
}
return nil
}
func (mf *PluginManifest) validateClientCredentials() (err error) {
if mf.Auth.AuthOfOAuthClientCredentials == nil {
err = sonic.UnmarshalString(mf.Auth.Payload, &mf.Auth.AuthOfOAuthClientCredentials)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload"))
}
}
clientCredentials := mf.Auth.AuthOfOAuthClientCredentials
if clientCredentials.ClientID == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"client id is required"))
}
if clientCredentials.ClientSecret == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"client secret is required"))
}
if clientCredentials.TokenURL == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"token url is required"))
}
urlParse, err := url.Parse(clientCredentials.TokenURL)
if err != nil || urlParse.Hostname() == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid token url"))
}
if urlParse.Scheme != "https" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"token url scheme must be 'https'"))
}
return nil
}
func (mf *PluginManifest) validateAuthCode(skipAuthPayload bool) (err error) {
if mf.Auth.AuthOfOAuthAuthorizationCode == nil {
err = sonic.UnmarshalString(mf.Auth.Payload, &mf.Auth.AuthOfOAuthAuthorizationCode)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload"))
}
}
if skipAuthPayload {
return nil
}
authCode := mf.Auth.AuthOfOAuthAuthorizationCode
if authCode.ClientID == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"client id is required"))
}
if authCode.ClientSecret == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"client secret is required"))
}
if authCode.AuthorizationContentType != MediaTypeJson {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"authorization content type must be 'application/json'"))
}
if authCode.AuthorizationURL == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"token url is required"))
}
if authCode.ClientURL == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"client url is required"))
}
urlParse, err := url.Parse(authCode.AuthorizationURL)
if err != nil || urlParse.Hostname() == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid authorization url"))
}
if urlParse.Scheme != "https" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"authorization url scheme must be 'https'"))
}
urlParse, err = url.Parse(authCode.ClientURL)
if err != nil || urlParse.Hostname() == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid client url"))
}
if urlParse.Scheme != "https" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"client url scheme must be 'https'"))
}
return nil
}
type Auth struct {
Type string `json:"type" validate:"required"`
AuthorizationType string `json:"authorization_type,omitempty"`
ClientURL string `json:"client_url,omitempty"`
Scope string `json:"scope,omitempty"`
AuthorizationURL string `json:"authorization_url,omitempty"`
AuthorizationContentType string `json:"authorization_content_type,omitempty"`
Platform string `json:"platform,omitempty"`
ClientID string `json:"client_id,omitempty"`
ClientSecret string `json:"client_secret,omitempty"`
Location string `json:"location,omitempty"`
Key string `json:"key,omitempty"`
ServiceToken string `json:"service_token,omitempty"`
SubType string `json:"sub_type"`
Payload string `json:"payload"`
}
type AuthV2 struct {
Type AuthzType `json:"type" yaml:"type"`
SubType AuthzSubType `json:"sub_type" yaml:"sub_type"`
Payload string `json:"payload" yaml:"payload"`
// service
AuthOfAPIToken *AuthOfAPIToken `json:"-"`
// oauth
AuthOfOAuthAuthorizationCode *OAuthAuthorizationCodeConfig `json:"-"`
AuthOfOAuthClientCredentials *OAuthClientCredentialsConfig `json:"-"`
}
func (au *AuthV2) UnmarshalJSON(data []byte) error {
auth := &Auth{} // 兼容老数据
err := json.Unmarshal(data, auth)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid plugin manifest json"))
}
au.Type = AuthzType(auth.Type)
au.SubType = AuthzSubType(auth.SubType)
if au.Type == "" {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"plugin auth type is required"))
}
if auth.Payload != "" {
payload_, err := utils.DecryptByAES(auth.Payload, utils.AuthSecretKey)
if err == nil {
auth.Payload = string(payload_)
}
}
switch au.Type {
case AuthzTypeOfNone:
case AuthzTypeOfOAuth:
err = au.unmarshalOAuth(auth)
case AuthzTypeOfService:
err = au.unmarshalService(auth)
default:
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid plugin auth type '%s'", au.Type))
}
if err != nil {
return err
}
return nil
}
func (au *AuthV2) unmarshalService(auth *Auth) (err error) {
if au.SubType == "" && au.Payload == "" { // 兼容老数据
au.SubType = AuthzSubTypeOfServiceAPIToken
}
var payload []byte
if au.SubType == AuthzSubTypeOfServiceAPIToken {
if len(auth.ServiceToken) > 0 {
au.AuthOfAPIToken = &AuthOfAPIToken{
Location: HTTPParamLocation(strings.ToLower(auth.Location)),
Key: auth.Key,
ServiceToken: auth.ServiceToken,
}
} else {
token := &AuthOfAPIToken{}
err = json.Unmarshal([]byte(auth.Payload), token)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload json"))
}
au.AuthOfAPIToken = token
}
payload, err = json.Marshal(au.AuthOfAPIToken)
if err != nil {
return err
}
}
if len(payload) == 0 {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid plugin sub-auth type '%s'", au.SubType))
}
au.Payload = string(payload)
return nil
}
func (au *AuthV2) unmarshalOAuth(auth *Auth) (err error) {
if au.SubType == "" { // 兼容老数据
au.SubType = AuthzSubTypeOfOAuthAuthorizationCode
}
var payload []byte
if au.SubType == AuthzSubTypeOfOAuthAuthorizationCode {
if len(auth.ClientSecret) > 0 {
au.AuthOfOAuthAuthorizationCode = &OAuthAuthorizationCodeConfig{
ClientID: auth.ClientID,
ClientSecret: auth.ClientSecret,
ClientURL: auth.ClientURL,
Scope: auth.Scope,
AuthorizationURL: auth.AuthorizationURL,
AuthorizationContentType: auth.AuthorizationContentType,
}
} else {
oauth := &OAuthAuthorizationCodeConfig{}
err = json.Unmarshal([]byte(auth.Payload), oauth)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload json"))
}
au.AuthOfOAuthAuthorizationCode = oauth
}
payload, err = json.Marshal(au.AuthOfOAuthAuthorizationCode)
if err != nil {
return err
}
}
if au.SubType == AuthzSubTypeOfOAuthClientCredentials {
oauth := &OAuthClientCredentialsConfig{}
err = json.Unmarshal([]byte(auth.Payload), oauth)
if err != nil {
return errorx.WrapByCode(err, errno.ErrPluginInvalidManifest, errorx.KV(errno.PluginMsgKey,
"invalid auth payload json"))
}
au.AuthOfOAuthClientCredentials = oauth
payload, err = json.Marshal(au.AuthOfOAuthClientCredentials)
if err != nil {
return err
}
}
if len(payload) == 0 {
return errorx.New(errno.ErrPluginInvalidManifest, errorx.KVf(errno.PluginMsgKey,
"invalid plugin sub-auth type '%s'", au.SubType))
}
au.Payload = string(payload)
return nil
}
type AuthOfAPIToken struct {
// Location is the location of the parameter.
// It can be "header" or "query".
Location HTTPParamLocation `json:"location"`
// Key is the name of the parameter.
Key string `json:"key"`
// ServiceToken is the simple authorization information for the service.
ServiceToken string `json:"service_token"`
}
type OAuthAuthorizationCodeConfig struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
// ClientURL is the URL of authorization endpoint.
ClientURL string `json:"client_url"`
// Scope is the scope of the authorization request.
// If multiple scopes are requested, they must be separated by a space.
Scope string `json:"scope,omitempty"`
// AuthorizationURL is the URL of token exchange endpoint.
AuthorizationURL string `json:"authorization_url"`
// AuthorizationContentType is the content type of the authorization request, and it must be "application/json".
AuthorizationContentType string `json:"authorization_content_type"`
}
type OAuthClientCredentialsConfig struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
TokenURL string `json:"token_url"`
}
type APIDesc struct {
Type PluginType `json:"type" validate:"required"`
}

View File

@ -0,0 +1,566 @@
package plugin
import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/getkin/kin-openapi/openapi3"
gonanoid "github.com/matoous/go-nanoid"
productAPI "github.com/coze-dev/coze-studio/backend/api/model/flow/marketplace/product_public_api"
"github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
common "github.com/coze-dev/coze-studio/backend/api/model/plugin_develop_common"
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
)
type ToolInfo struct {
ID int64
PluginID int64
CreatedAt int64
UpdatedAt int64
Version *string
ActivatedStatus *ActivatedStatus
DebugStatus *plugin_develop_common.APIDebugStatus
Method *string
SubURL *string
Operation *Openapi3Operation
}
func (t ToolInfo) GetName() string {
if t.Operation == nil {
return ""
}
return t.Operation.OperationID
}
func (t ToolInfo) GetDesc() string {
if t.Operation == nil {
return ""
}
return t.Operation.Summary
}
func (t ToolInfo) GetVersion() string {
return ptr.FromOrDefault(t.Version, "")
}
func (t ToolInfo) GetActivatedStatus() ActivatedStatus {
return ptr.FromOrDefault(t.ActivatedStatus, ActivateTool)
}
func (t ToolInfo) GetSubURL() string {
return ptr.FromOrDefault(t.SubURL, "")
}
func (t ToolInfo) GetMethod() string {
return strings.ToUpper(ptr.FromOrDefault(t.Method, ""))
}
func (t ToolInfo) GetDebugStatus() common.APIDebugStatus {
return ptr.FromOrDefault(t.DebugStatus, common.APIDebugStatus_DebugWaiting)
}
func (t ToolInfo) GetResponseOpenapiSchema() (*openapi3.Schema, error) {
op := t.Operation
if op == nil {
return nil, fmt.Errorf("operation is required")
}
resp, ok := op.Responses[strconv.Itoa(http.StatusOK)]
if !ok || resp == nil || resp.Value == nil || len(resp.Value.Content) == 0 {
return nil, fmt.Errorf("response status '200' not found")
}
mType, ok := resp.Value.Content[MediaTypeJson] // only support application/json
if !ok || mType == nil || mType.Schema == nil || mType.Schema.Value == nil {
return nil, fmt.Errorf("media type '%s' not found in response", MediaTypeJson)
}
return mType.Schema.Value, nil
}
type paramMetaInfo struct {
name string
desc string
required bool
location string
}
func (t ToolInfo) ToRespAPIParameter() ([]*common.APIParameter, error) {
op := t.Operation
if op == nil {
return nil, fmt.Errorf("operation is required")
}
respSchema, err := t.GetResponseOpenapiSchema()
if err != nil {
return nil, err
}
params := make([]*common.APIParameter, 0, len(op.Parameters))
if len(respSchema.Properties) == 0 {
return params, nil
}
required := slices.ToMap(respSchema.Required, func(e string) (string, bool) {
return e, true
})
for subParamName, prop := range respSchema.Properties {
if prop == nil || prop.Value == nil {
return nil, fmt.Errorf("the schema of property '%s' is required", subParamName)
}
paramMeta := paramMetaInfo{
name: subParamName,
desc: prop.Value.Description,
location: string(ParamInBody),
required: required[subParamName],
}
apiParam, err := toAPIParameter(paramMeta, prop.Value)
if err != nil {
return nil, err
}
params = append(params, apiParam)
}
return params, nil
}
func (t ToolInfo) ToReqAPIParameter() ([]*common.APIParameter, error) {
op := t.Operation
if op == nil {
return nil, fmt.Errorf("operation is required")
}
params := make([]*common.APIParameter, 0, len(op.Parameters))
for _, param := range op.Parameters {
if param == nil || param.Value == nil || param.Value.Schema == nil || param.Value.Schema.Value == nil {
return nil, fmt.Errorf("parameter schema is required")
}
paramVal := param.Value
schemaVal := paramVal.Schema.Value
if schemaVal.Type == openapi3.TypeObject {
return nil, fmt.Errorf("the type of parameter '%s' cannot be 'object'", paramVal.Name)
}
if schemaVal.Type == openapi3.TypeArray {
if paramVal.In == openapi3.ParameterInPath {
return nil, fmt.Errorf("the type of field '%s' cannot be 'array'", paramVal.Name)
}
if schemaVal.Items == nil || schemaVal.Items.Value == nil {
return nil, fmt.Errorf("the item schema of field '%s' is required", paramVal.Name)
}
item := schemaVal.Items.Value
if item.Type == openapi3.TypeObject || item.Type == openapi3.TypeArray {
return nil, fmt.Errorf("the item type of parameter '%s' cannot be 'object' or 'array'", paramVal.Name)
}
}
paramMeta := paramMetaInfo{
name: paramVal.Name,
desc: paramVal.Description,
location: paramVal.In,
required: paramVal.Required,
}
apiParam, err := toAPIParameter(paramMeta, schemaVal)
if err != nil {
return nil, err
}
params = append(params, apiParam)
}
if op.RequestBody == nil || op.RequestBody.Value == nil || len(op.RequestBody.Value.Content) == 0 {
return params, nil
}
for _, mType := range op.RequestBody.Value.Content {
if mType == nil || mType.Schema == nil || mType.Schema.Value == nil {
return nil, fmt.Errorf("request body schema is required")
}
schemaVal := mType.Schema.Value
if len(schemaVal.Properties) == 0 {
continue
}
required := slices.ToMap(schemaVal.Required, func(e string) (string, bool) {
return e, true
})
for subParamName, prop := range schemaVal.Properties {
if prop == nil || prop.Value == nil {
return nil, fmt.Errorf("the schema of property '%s' is required", subParamName)
}
paramMeta := paramMetaInfo{
name: subParamName,
desc: prop.Value.Description,
location: string(ParamInBody),
required: required[subParamName],
}
apiParam, err := toAPIParameter(paramMeta, prop.Value)
if err != nil {
return nil, err
}
params = append(params, apiParam)
}
break // 只取一种 MIME
}
return params, nil
}
func toAPIParameter(paramMeta paramMetaInfo, sc *openapi3.Schema) (*common.APIParameter, error) {
if sc == nil {
return nil, fmt.Errorf("schema is requred")
}
apiType, ok := ToThriftParamType(strings.ToLower(sc.Type))
if !ok {
return nil, fmt.Errorf("the type '%s' of filed '%s' is invalid", sc.Type, paramMeta.name)
}
location, ok := ToThriftHTTPParamLocation(HTTPParamLocation(paramMeta.location))
if !ok {
return nil, fmt.Errorf("the location '%s' of field '%s' is invalid", paramMeta.location, paramMeta.name)
}
apiParam := &common.APIParameter{
ID: gonanoid.MustID(10),
Name: paramMeta.name,
Desc: paramMeta.desc,
Type: apiType,
Location: location, // 使用父节点的值
IsRequired: paramMeta.required,
SubParameters: []*common.APIParameter{},
}
if sc.Default != nil {
apiParam.LocalDefault = ptr.Of(fmt.Sprintf("%v", sc.Default))
}
if sc.Format != "" {
aType, ok := FormatToAssistType(sc.Format)
if !ok {
return nil, fmt.Errorf("the format '%s' of field '%s' is invalid", sc.Format, paramMeta.name)
}
_aType, ok := ToThriftAPIAssistType(aType)
if !ok {
return nil, fmt.Errorf("assist type '%s' of field '%s' is invalid", aType, paramMeta.name)
}
apiParam.AssistType = ptr.Of(_aType)
}
if v, ok := sc.Extensions[APISchemaExtendGlobalDisable]; ok {
if disable, ok := v.(bool); ok {
apiParam.GlobalDisable = disable
}
}
if v, ok := sc.Extensions[APISchemaExtendLocalDisable]; ok {
if disable, ok := v.(bool); ok {
apiParam.LocalDisable = disable
}
}
if v, ok := sc.Extensions[APISchemaExtendVariableRef]; ok {
if ref, ok := v.(string); ok {
apiParam.VariableRef = ptr.Of(ref)
apiParam.DefaultParamSource = ptr.Of(common.DefaultParamSource_Variable)
}
}
switch sc.Type {
case openapi3.TypeObject:
if len(sc.Properties) == 0 {
return apiParam, nil
}
required := slices.ToMap(sc.Required, func(e string) (string, bool) {
return e, true
})
for subParamName, prop := range sc.Properties {
if prop == nil || prop.Value == nil {
return nil, fmt.Errorf("the schema of property '%s' is required", subParamName)
}
subMeta := paramMetaInfo{
name: subParamName,
desc: prop.Value.Description,
required: required[subParamName],
location: paramMeta.location,
}
subParam, err := toAPIParameter(subMeta, prop.Value)
if err != nil {
return nil, err
}
apiParam.SubParameters = append(apiParam.SubParameters, subParam)
}
return apiParam, nil
case openapi3.TypeArray:
if sc.Items == nil || sc.Items.Value == nil {
return nil, fmt.Errorf("the item schema of field '%s' is required", paramMeta.name)
}
item := sc.Items.Value
subMeta := paramMetaInfo{
name: "[Array Item]",
desc: item.Description,
location: paramMeta.location,
required: paramMeta.required,
}
subParam, err := toAPIParameter(subMeta, item)
if err != nil {
return nil, err
}
apiParam.SubParameters = append(apiParam.SubParameters, subParam)
return apiParam, nil
}
return apiParam, nil
}
func (t ToolInfo) ToPluginParameters() ([]*common.PluginParameter, error) {
op := t.Operation
if op == nil {
return nil, fmt.Errorf("operation is required")
}
var params []*common.PluginParameter
for _, prop := range op.Parameters {
if prop == nil || prop.Value == nil || prop.Value.Schema == nil || prop.Value.Schema.Value == nil {
return nil, fmt.Errorf("parameter schema is required")
}
paramVal := prop.Value
schemaVal := paramVal.Schema.Value
if schemaVal.Type == openapi3.TypeObject {
return nil, fmt.Errorf("the type of parameter '%s' cannot be 'object'", paramVal.Name)
}
var arrayItemType string
if schemaVal.Type == openapi3.TypeArray {
if paramVal.In == openapi3.ParameterInPath {
return nil, fmt.Errorf("the type of field '%s' cannot be 'array'", paramVal.Name)
}
if schemaVal.Items == nil || schemaVal.Items.Value == nil {
return nil, fmt.Errorf("the item schema of field '%s' is required", paramVal.Name)
}
item := schemaVal.Items.Value
if item.Type == openapi3.TypeObject || item.Type == openapi3.TypeArray {
return nil, fmt.Errorf("the item type of parameter '%s' cannot be 'object' or 'array'", paramVal.Name)
}
arrayItemType = item.Type
}
if disabledParam(schemaVal) {
continue
}
var assistType *common.PluginParamTypeFormat
if v, ok := schemaVal.Extensions[APISchemaExtendAssistType]; ok {
_v, ok := v.(string)
if !ok {
continue
}
f, ok := AssistTypeToThriftFormat(APIFileAssistType(_v))
if ok {
return nil, fmt.Errorf("the assist type '%s' of field '%s' is invalid", _v, paramVal.Name)
}
assistType = ptr.Of(f)
}
params = append(params, &common.PluginParameter{
Name: paramVal.Name,
Desc: paramVal.Description,
Required: paramVal.Required,
Type: schemaVal.Type,
SubType: arrayItemType,
Format: assistType,
SubParameters: []*common.PluginParameter{},
})
}
if op.RequestBody == nil || op.RequestBody.Value == nil || len(op.RequestBody.Value.Content) == 0 {
return params, nil
}
for _, mType := range op.RequestBody.Value.Content {
if mType == nil || mType.Schema == nil || mType.Schema.Value == nil {
return nil, fmt.Errorf("request body schema is required")
}
schemaVal := mType.Schema.Value
if len(schemaVal.Properties) == 0 {
continue
}
required := slices.ToMap(schemaVal.Required, func(e string) (string, bool) {
return e, true
})
for subParamName, prop := range schemaVal.Properties {
if prop == nil || prop.Value == nil {
return nil, fmt.Errorf("the schema of property '%s' is required", subParamName)
}
paramMeta := paramMetaInfo{
name: subParamName,
desc: prop.Value.Description,
required: required[subParamName],
}
paramInfo, err := toPluginParameter(paramMeta, prop.Value)
if err != nil {
return nil, err
}
if paramInfo != nil {
params = append(params, paramInfo)
}
}
break // 只取一种 MIME
}
return params, nil
}
func toPluginParameter(paramMeta paramMetaInfo, sc *openapi3.Schema) (*common.PluginParameter, error) {
if sc == nil {
return nil, fmt.Errorf("schema is required")
}
if disabledParam(sc) {
return nil, nil
}
var assistType *common.PluginParamTypeFormat
if v, ok := sc.Extensions[APISchemaExtendAssistType]; ok {
if _v, ok := v.(string); ok {
f, ok := AssistTypeToThriftFormat(APIFileAssistType(_v))
if !ok {
return nil, fmt.Errorf("the assist type '%s' of field '%s' is invalid", _v, paramMeta.name)
}
assistType = ptr.Of(f)
}
}
pluginParam := &common.PluginParameter{
Name: paramMeta.name,
Type: sc.Type,
Desc: paramMeta.desc,
Required: paramMeta.required,
Format: assistType,
SubParameters: []*common.PluginParameter{},
}
switch sc.Type {
case openapi3.TypeObject:
if len(sc.Properties) == 0 {
return pluginParam, nil
}
required := slices.ToMap(sc.Required, func(e string) (string, bool) {
return e, true
})
for subParamName, prop := range sc.Properties {
if prop == nil || prop.Value == nil {
return nil, fmt.Errorf("the schema of property '%s' is required", subParamName)
}
subMeta := paramMetaInfo{
name: subParamName,
desc: prop.Value.Description,
required: required[subParamName],
}
subParam, err := toPluginParameter(subMeta, prop.Value)
if err != nil {
return nil, err
}
pluginParam.SubParameters = append(pluginParam.SubParameters, subParam)
}
return pluginParam, nil
case openapi3.TypeArray:
if sc.Items == nil || sc.Items.Value == nil {
return nil, fmt.Errorf("the item schema of field '%s' is required", paramMeta.name)
}
item := sc.Items.Value
pluginParam.SubType = item.Type
if item.Type != openapi3.TypeObject {
return pluginParam, nil
}
subMeta := paramMetaInfo{
desc: item.Description,
required: paramMeta.required,
}
subParam, err := toPluginParameter(subMeta, item)
if err != nil {
return nil, err
}
pluginParam.SubParameters = append(pluginParam.SubParameters, subParam.SubParameters...)
return pluginParam, nil
}
return pluginParam, nil
}
func (t ToolInfo) ToToolParameters() ([]*productAPI.ToolParameter, error) {
apiParams, err := t.ToReqAPIParameter()
if err != nil {
return nil, err
}
var toToolParams func(apiParams []*common.APIParameter) ([]*productAPI.ToolParameter, error)
toToolParams = func(apiParams []*common.APIParameter) ([]*productAPI.ToolParameter, error) {
params := make([]*productAPI.ToolParameter, 0, len(apiParams))
for _, apiParam := range apiParams {
typ, _ := ToOpenapiParamType(apiParam.Type)
toolParam := &productAPI.ToolParameter{
Name: apiParam.Name,
Description: apiParam.Desc,
Type: typ,
IsRequired: apiParam.IsRequired,
SubParameter: []*productAPI.ToolParameter{},
}
if len(apiParam.SubParameters) > 0 {
subParams, err := toToolParams(apiParam.SubParameters)
if err != nil {
return nil, err
}
toolParam.SubParameter = append(toolParam.SubParameter, subParams...)
}
params = append(params, toolParam)
}
return params, nil
}
return toToolParams(apiParams)
}

View File

@ -0,0 +1,64 @@
package search
import (
resource "github.com/coze-dev/coze-studio/backend/api/model/resource/common"
)
type ResourceDocument struct {
ResID int64 `json:"res_id"`
ResType resource.ResType `json:"res_type"`
ResSubType *int32 `json:"res_sub_type,omitempty"`
Name *string `json:"name,omitempty"`
OwnerID *int64 `json:"owner_id,omitempty"`
SpaceID *int64 `json:"space_id,omitempty"`
APPID *int64 `json:"app_id,omitempty"`
BizStatus *int64 `json:"biz_status,omitempty"`
PublishStatus *resource.PublishStatus `json:"publish_status,omitempty"`
CreateTimeMS *int64 `json:"create_time,omitempty"`
UpdateTimeMS *int64 `json:"update_time,omitempty"`
PublishTimeMS *int64 `json:"publish_time,omitempty"`
}
func (r *ResourceDocument) GetName() string {
if r.Name != nil {
return *r.Name
}
return ""
}
func (r *ResourceDocument) GetOwnerID() int64 {
if r.OwnerID != nil {
return *r.OwnerID
}
return 0
}
// GetUpdateTime 获取更新时间
func (r *ResourceDocument) GetUpdateTime() int64 {
if r.UpdateTimeMS != nil {
return *r.UpdateTimeMS
}
return 0
}
func (r *ResourceDocument) GetResSubType() int32 {
if r.ResSubType != nil {
return *r.ResSubType
}
return 0
}
func (r *ResourceDocument) GetCreateTime() int64 {
if r.CreateTimeMS == nil {
return 0
}
return *r.CreateTimeMS
}
func (r *ResourceDocument) GetPublishTime() int64 {
if r.PublishTimeMS == nil {
return 0
}
return *r.PublishTimeMS
}

View File

@ -0,0 +1,38 @@
package search
import (
resource "github.com/coze-dev/coze-studio/backend/api/model/resource/common"
)
type SearchResourcesRequest struct {
SpaceID int64
OwnerID int64
Name string
APPID int64
OrderFiledName string
OrderAsc bool
ResTypeFilter []resource.ResType
PublishStatusFilter resource.PublishStatus
SearchKeys []string
Cursor string
Page *int32
Limit int32
}
type SearchResourcesResponse struct {
HasMore bool
NextCursor string
TotalHits *int64
Data []*ResourceDocument
}
const (
FieldOfCreateTime = "create_time"
FieldOfUpdateTime = "update_time"
FieldOfPublishTime = "publish_time"
FieldOfFavTime = "fav_time"
FieldOfRecentlyOpenTime = "recently_open_time"
)

View File

@ -0,0 +1,106 @@
package singleagent
import (
"github.com/cloudwego/eino/schema"
"gorm.io/gorm"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/agentrun"
"github.com/coze-dev/coze-studio/backend/api/model/crossdomain/plugin"
"github.com/coze-dev/coze-studio/backend/api/model/ocean/cloud/bot_common"
"github.com/coze-dev/coze-studio/backend/crossdomain/contract/crossworkflow"
)
type AgentRuntime struct {
AgentVersion string
IsDraft bool
SpaceID int64
ConnectorID int64
PreRetrieveTools []*agentrun.Tool
}
type EventType string
const (
EventTypeOfChatModelAnswer EventType = "chatmodel_answer"
EventTypeOfToolsMessage EventType = "tools_message"
EventTypeOfFuncCall EventType = "func_call"
EventTypeOfSuggest EventType = "suggest"
EventTypeOfKnowledge EventType = "knowledge"
EventTypeOfInterrupt EventType = "interrupt"
)
type AgentEvent struct {
EventType EventType
ChatModelAnswer *schema.StreamReader[*schema.Message]
ToolsMessage []*schema.Message
FuncCall *schema.Message
Suggest *schema.Message
Knowledge []*schema.Document
Interrupt *InterruptInfo
}
type SingleAgent struct {
AgentID int64
CreatorID int64
SpaceID int64
Name string
Desc string
IconURI string
CreatedAt int64
UpdatedAt int64
Version string
DeletedAt gorm.DeletedAt
VariablesMetaID *int64
OnboardingInfo *bot_common.OnboardingInfo
ModelInfo *bot_common.ModelInfo
Prompt *bot_common.PromptInfo
Plugin []*bot_common.PluginInfo
Knowledge *bot_common.Knowledge
Workflow []*bot_common.WorkflowInfo
SuggestReply *bot_common.SuggestReplyInfo
JumpConfig *bot_common.JumpConfig
BackgroundImageInfoList []*bot_common.BackgroundImageInfo
Database []*bot_common.Database
ShortcutCommand []string
}
type InterruptEventType int64
const (
InterruptEventType_LocalPlugin InterruptEventType = 1
InterruptEventType_Question InterruptEventType = 2
InterruptEventType_RequireInfos InterruptEventType = 3
InterruptEventType_SceneChat InterruptEventType = 4
InterruptEventType_InputNode InterruptEventType = 5
InterruptEventType_WorkflowLocalPlugin InterruptEventType = 6
InterruptEventType_OauthPlugin InterruptEventType = 7
InterruptEventType_WorkflowLLM InterruptEventType = 100
)
type InterruptInfo struct {
AllToolInterruptData map[string]*plugin.ToolInterruptEvent
AllWfInterruptData map[string]*crossworkflow.ToolInterruptEvent
ToolCallID string
InterruptType InterruptEventType
InterruptID string
}
type ExecuteRequest struct {
Identity *AgentIdentity
UserID string
Input *schema.Message
History []*schema.Message
ResumeInfo *InterruptInfo
PreCallTools []*agentrun.ToolsRetriever
}
type AgentIdentity struct {
AgentID int64
// State AgentState
Version string
IsDraft bool
ConnectorID int64
}

View File

@ -0,0 +1,13 @@
package variables
import (
"github.com/coze-dev/coze-studio/backend/api/model/project_memory"
)
type UserVariableMeta struct {
BizType project_memory.VariableConnector
BizID string
Version string
ConnectorUID string
ConnectorID int64
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,810 @@
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
package testcase
import (
"github.com/coze-dev/coze-studio/backend/api/model/flow/devops/debugger/domain/infra"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
type CaseDataBase struct {
// 新增时不填,更新时填写
CaseID *int64 `thrift:"caseID,1,optional" json:"caseID,string" form:"caseID" query:"caseID"`
Name *string `thrift:"name,2,optional" form:"name" json:"name,omitempty" query:"name"`
Description *string `thrift:"description,3,optional" form:"description" json:"description,omitempty" query:"description"`
// json格式的输入信息
Input *string `thrift:"input,4,optional" form:"input" json:"input,omitempty" query:"input"`
IsDefault *bool `thrift:"isDefault,5,optional" form:"isDefault" json:"isDefault,omitempty" query:"isDefault"`
}
func NewCaseDataBase() *CaseDataBase {
return &CaseDataBase{}
}
func (p *CaseDataBase) InitDefault() {
}
var CaseDataBase_CaseID_DEFAULT int64
func (p *CaseDataBase) GetCaseID() (v int64) {
if !p.IsSetCaseID() {
return CaseDataBase_CaseID_DEFAULT
}
return *p.CaseID
}
var CaseDataBase_Name_DEFAULT string
func (p *CaseDataBase) GetName() (v string) {
if !p.IsSetName() {
return CaseDataBase_Name_DEFAULT
}
return *p.Name
}
var CaseDataBase_Description_DEFAULT string
func (p *CaseDataBase) GetDescription() (v string) {
if !p.IsSetDescription() {
return CaseDataBase_Description_DEFAULT
}
return *p.Description
}
var CaseDataBase_Input_DEFAULT string
func (p *CaseDataBase) GetInput() (v string) {
if !p.IsSetInput() {
return CaseDataBase_Input_DEFAULT
}
return *p.Input
}
var CaseDataBase_IsDefault_DEFAULT bool
func (p *CaseDataBase) GetIsDefault() (v bool) {
if !p.IsSetIsDefault() {
return CaseDataBase_IsDefault_DEFAULT
}
return *p.IsDefault
}
var fieldIDToName_CaseDataBase = map[int16]string{
1: "caseID",
2: "name",
3: "description",
4: "input",
5: "isDefault",
}
func (p *CaseDataBase) IsSetCaseID() bool {
return p.CaseID != nil
}
func (p *CaseDataBase) IsSetName() bool {
return p.Name != nil
}
func (p *CaseDataBase) IsSetDescription() bool {
return p.Description != nil
}
func (p *CaseDataBase) IsSetInput() bool {
return p.Input != nil
}
func (p *CaseDataBase) IsSetIsDefault() bool {
return p.IsDefault != nil
}
func (p *CaseDataBase) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.I64 {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 3:
if fieldTypeId == thrift.STRING {
if err = p.ReadField3(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 4:
if fieldTypeId == thrift.STRING {
if err = p.ReadField4(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 5:
if fieldTypeId == thrift.BOOL {
if err = p.ReadField5(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_CaseDataBase[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *CaseDataBase) ReadField1(iprot thrift.TProtocol) error {
var _field *int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = &v
}
p.CaseID = _field
return nil
}
func (p *CaseDataBase) ReadField2(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.Name = _field
return nil
}
func (p *CaseDataBase) ReadField3(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.Description = _field
return nil
}
func (p *CaseDataBase) ReadField4(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.Input = _field
return nil
}
func (p *CaseDataBase) ReadField5(iprot thrift.TProtocol) error {
var _field *bool
if v, err := iprot.ReadBool(); err != nil {
return err
} else {
_field = &v
}
p.IsDefault = _field
return nil
}
func (p *CaseDataBase) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("CaseDataBase"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
if err = p.writeField3(oprot); err != nil {
fieldId = 3
goto WriteFieldError
}
if err = p.writeField4(oprot); err != nil {
fieldId = 4
goto WriteFieldError
}
if err = p.writeField5(oprot); err != nil {
fieldId = 5
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *CaseDataBase) writeField1(oprot thrift.TProtocol) (err error) {
if p.IsSetCaseID() {
if err = oprot.WriteFieldBegin("caseID", thrift.I64, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(*p.CaseID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *CaseDataBase) writeField2(oprot thrift.TProtocol) (err error) {
if p.IsSetName() {
if err = oprot.WriteFieldBegin("name", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.Name); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *CaseDataBase) writeField3(oprot thrift.TProtocol) (err error) {
if p.IsSetDescription() {
if err = oprot.WriteFieldBegin("description", thrift.STRING, 3); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.Description); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
}
func (p *CaseDataBase) writeField4(oprot thrift.TProtocol) (err error) {
if p.IsSetInput() {
if err = oprot.WriteFieldBegin("input", thrift.STRING, 4); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.Input); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err)
}
func (p *CaseDataBase) writeField5(oprot thrift.TProtocol) (err error) {
if p.IsSetIsDefault() {
if err = oprot.WriteFieldBegin("isDefault", thrift.BOOL, 5); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteBool(*p.IsDefault); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err)
}
func (p *CaseDataBase) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("CaseDataBase(%+v)", *p)
}
type CaseDataDetail struct {
CaseBase *CaseDataBase `thrift:"caseBase,1,optional" form:"caseBase" json:"caseBase,omitempty" query:"caseBase"`
CreatorID *string `thrift:"creatorID,2,optional" form:"creatorID" json:"creatorID,omitempty" query:"creatorID"`
CreateTimeInSec *int64 `thrift:"createTimeInSec,3,optional" form:"createTimeInSec" json:"createTimeInSec,omitempty" query:"createTimeInSec"`
UpdateTimeInSec *int64 `thrift:"updateTimeInSec,4,optional" form:"updateTimeInSec" json:"updateTimeInSec,omitempty" query:"updateTimeInSec"`
// schema不兼容
SchemaIncompatible *bool `thrift:"schemaIncompatible,5,optional" form:"schemaIncompatible" json:"schemaIncompatible,omitempty" query:"schemaIncompatible"`
Updater *infra.Creator `thrift:"updater,6,optional" form:"updater" json:"updater,omitempty" query:"updater"`
}
func NewCaseDataDetail() *CaseDataDetail {
return &CaseDataDetail{}
}
func (p *CaseDataDetail) InitDefault() {
}
var CaseDataDetail_CaseBase_DEFAULT *CaseDataBase
func (p *CaseDataDetail) GetCaseBase() (v *CaseDataBase) {
if !p.IsSetCaseBase() {
return CaseDataDetail_CaseBase_DEFAULT
}
return p.CaseBase
}
var CaseDataDetail_CreatorID_DEFAULT string
func (p *CaseDataDetail) GetCreatorID() (v string) {
if !p.IsSetCreatorID() {
return CaseDataDetail_CreatorID_DEFAULT
}
return *p.CreatorID
}
var CaseDataDetail_CreateTimeInSec_DEFAULT int64
func (p *CaseDataDetail) GetCreateTimeInSec() (v int64) {
if !p.IsSetCreateTimeInSec() {
return CaseDataDetail_CreateTimeInSec_DEFAULT
}
return *p.CreateTimeInSec
}
var CaseDataDetail_UpdateTimeInSec_DEFAULT int64
func (p *CaseDataDetail) GetUpdateTimeInSec() (v int64) {
if !p.IsSetUpdateTimeInSec() {
return CaseDataDetail_UpdateTimeInSec_DEFAULT
}
return *p.UpdateTimeInSec
}
var CaseDataDetail_SchemaIncompatible_DEFAULT bool
func (p *CaseDataDetail) GetSchemaIncompatible() (v bool) {
if !p.IsSetSchemaIncompatible() {
return CaseDataDetail_SchemaIncompatible_DEFAULT
}
return *p.SchemaIncompatible
}
var CaseDataDetail_Updater_DEFAULT *infra.Creator
func (p *CaseDataDetail) GetUpdater() (v *infra.Creator) {
if !p.IsSetUpdater() {
return CaseDataDetail_Updater_DEFAULT
}
return p.Updater
}
var fieldIDToName_CaseDataDetail = map[int16]string{
1: "caseBase",
2: "creatorID",
3: "createTimeInSec",
4: "updateTimeInSec",
5: "schemaIncompatible",
6: "updater",
}
func (p *CaseDataDetail) IsSetCaseBase() bool {
return p.CaseBase != nil
}
func (p *CaseDataDetail) IsSetCreatorID() bool {
return p.CreatorID != nil
}
func (p *CaseDataDetail) IsSetCreateTimeInSec() bool {
return p.CreateTimeInSec != nil
}
func (p *CaseDataDetail) IsSetUpdateTimeInSec() bool {
return p.UpdateTimeInSec != nil
}
func (p *CaseDataDetail) IsSetSchemaIncompatible() bool {
return p.SchemaIncompatible != nil
}
func (p *CaseDataDetail) IsSetUpdater() bool {
return p.Updater != nil
}
func (p *CaseDataDetail) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 3:
if fieldTypeId == thrift.I64 {
if err = p.ReadField3(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 4:
if fieldTypeId == thrift.I64 {
if err = p.ReadField4(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 5:
if fieldTypeId == thrift.BOOL {
if err = p.ReadField5(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 6:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField6(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_CaseDataDetail[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *CaseDataDetail) ReadField1(iprot thrift.TProtocol) error {
_field := NewCaseDataBase()
if err := _field.Read(iprot); err != nil {
return err
}
p.CaseBase = _field
return nil
}
func (p *CaseDataDetail) ReadField2(iprot thrift.TProtocol) error {
var _field *string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = &v
}
p.CreatorID = _field
return nil
}
func (p *CaseDataDetail) ReadField3(iprot thrift.TProtocol) error {
var _field *int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = &v
}
p.CreateTimeInSec = _field
return nil
}
func (p *CaseDataDetail) ReadField4(iprot thrift.TProtocol) error {
var _field *int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = &v
}
p.UpdateTimeInSec = _field
return nil
}
func (p *CaseDataDetail) ReadField5(iprot thrift.TProtocol) error {
var _field *bool
if v, err := iprot.ReadBool(); err != nil {
return err
} else {
_field = &v
}
p.SchemaIncompatible = _field
return nil
}
func (p *CaseDataDetail) ReadField6(iprot thrift.TProtocol) error {
_field := infra.NewCreator()
if err := _field.Read(iprot); err != nil {
return err
}
p.Updater = _field
return nil
}
func (p *CaseDataDetail) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("CaseDataDetail"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
if err = p.writeField3(oprot); err != nil {
fieldId = 3
goto WriteFieldError
}
if err = p.writeField4(oprot); err != nil {
fieldId = 4
goto WriteFieldError
}
if err = p.writeField5(oprot); err != nil {
fieldId = 5
goto WriteFieldError
}
if err = p.writeField6(oprot); err != nil {
fieldId = 6
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *CaseDataDetail) writeField1(oprot thrift.TProtocol) (err error) {
if p.IsSetCaseBase() {
if err = oprot.WriteFieldBegin("caseBase", thrift.STRUCT, 1); err != nil {
goto WriteFieldBeginError
}
if err := p.CaseBase.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *CaseDataDetail) writeField2(oprot thrift.TProtocol) (err error) {
if p.IsSetCreatorID() {
if err = oprot.WriteFieldBegin("creatorID", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(*p.CreatorID); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *CaseDataDetail) writeField3(oprot thrift.TProtocol) (err error) {
if p.IsSetCreateTimeInSec() {
if err = oprot.WriteFieldBegin("createTimeInSec", thrift.I64, 3); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(*p.CreateTimeInSec); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
}
func (p *CaseDataDetail) writeField4(oprot thrift.TProtocol) (err error) {
if p.IsSetUpdateTimeInSec() {
if err = oprot.WriteFieldBegin("updateTimeInSec", thrift.I64, 4); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(*p.UpdateTimeInSec); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err)
}
func (p *CaseDataDetail) writeField5(oprot thrift.TProtocol) (err error) {
if p.IsSetSchemaIncompatible() {
if err = oprot.WriteFieldBegin("schemaIncompatible", thrift.BOOL, 5); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteBool(*p.SchemaIncompatible); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 5 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 5 end error: ", p), err)
}
func (p *CaseDataDetail) writeField6(oprot thrift.TProtocol) (err error) {
if p.IsSetUpdater() {
if err = oprot.WriteFieldBegin("updater", thrift.STRUCT, 6); err != nil {
goto WriteFieldBeginError
}
if err := p.Updater.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 6 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 6 end error: ", p), err)
}
func (p *CaseDataDetail) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("CaseDataDetail(%+v)", *p)
}

View File

@ -0,0 +1,298 @@
// Code generated by thriftgo (0.4.1). DO NOT EDIT.
package marketplace_common
import (
"database/sql"
"database/sql/driver"
"fmt"
"github.com/apache/thrift/lib/go/thrift"
)
type FollowType int64
const (
// 无关系
FollowType_Unknown FollowType = 0
// 关注
FollowType_Followee FollowType = 1
// 粉丝
FollowType_Follower FollowType = 2
// 互相关注
FollowType_MutualFollow FollowType = 3
)
func (p FollowType) String() string {
switch p {
case FollowType_Unknown:
return "Unknown"
case FollowType_Followee:
return "Followee"
case FollowType_Follower:
return "Follower"
case FollowType_MutualFollow:
return "MutualFollow"
}
return "<UNSET>"
}
func FollowTypeFromString(s string) (FollowType, error) {
switch s {
case "Unknown":
return FollowType_Unknown, nil
case "Followee":
return FollowType_Followee, nil
case "Follower":
return FollowType_Follower, nil
case "MutualFollow":
return FollowType_MutualFollow, nil
}
return FollowType(0), fmt.Errorf("not a valid FollowType string")
}
func FollowTypePtr(v FollowType) *FollowType { return &v }
func (p *FollowType) Scan(value interface{}) (err error) {
var result sql.NullInt64
err = result.Scan(value)
*p = FollowType(result.Int64)
return
}
func (p *FollowType) Value() (driver.Value, error) {
if p == nil {
return nil, nil
}
return int64(*p), nil
}
type Price struct {
// 金额
Amount int64 `thrift:"Amount,1" form:"amount" json:"amount,string"`
// 币种如USD、CNY
Currency string `thrift:"Currency,2" form:"currency" json:"currency"`
// 小数位数
DecimalNum int8 `thrift:"DecimalNum,3" form:"decimal_num" json:"decimal_num"`
}
func NewPrice() *Price {
return &Price{}
}
func (p *Price) InitDefault() {
}
func (p *Price) GetAmount() (v int64) {
return p.Amount
}
func (p *Price) GetCurrency() (v string) {
return p.Currency
}
func (p *Price) GetDecimalNum() (v int8) {
return p.DecimalNum
}
var fieldIDToName_Price = map[int16]string{
1: "Amount",
2: "Currency",
3: "DecimalNum",
}
func (p *Price) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.I64 {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 3:
if fieldTypeId == thrift.BYTE {
if err = p.ReadField3(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_Price[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *Price) ReadField1(iprot thrift.TProtocol) error {
var _field int64
if v, err := iprot.ReadI64(); err != nil {
return err
} else {
_field = v
}
p.Amount = _field
return nil
}
func (p *Price) ReadField2(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.Currency = _field
return nil
}
func (p *Price) ReadField3(iprot thrift.TProtocol) error {
var _field int8
if v, err := iprot.ReadByte(); err != nil {
return err
} else {
_field = v
}
p.DecimalNum = _field
return nil
}
func (p *Price) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("Price"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
if err = p.writeField3(oprot); err != nil {
fieldId = 3
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *Price) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("Amount", thrift.I64, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI64(p.Amount); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *Price) writeField2(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("Currency", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.Currency); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *Price) writeField3(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("DecimalNum", thrift.BYTE, 3); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteByte(p.DecimalNum); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
}
func (p *Price) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("Price(%+v)", *p)
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More