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,26 @@
/*
* 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.
*/
export const FORMAT_SPACE_SETTING = 4;
export const MAX_SUBMIT_LENGTH = 102400;
export const RANDOM_BOOL_THRESHOLD = 0.5;
export const STRING_DISPLAY_PREFIX = '"';
export const STRING_DISPLAY_SUFFIX = '"';
export const RANDOM_SEQUENCE_LENGTH = 10;
export const ROOT_KEY = 'mock';
export const MOCK_SET_ERR_CODE = {
REPEAT_NAME: 600303100,
};

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.
*/
export {
MockDataValueType,
MockDataStatus,
type MockDataWithStatus,
type MockDataInfo,
} from './types';
export {
FORMAT_SPACE_SETTING,
MAX_SUBMIT_LENGTH,
RANDOM_BOOL_THRESHOLD,
STRING_DISPLAY_PREFIX,
STRING_DISPLAY_SUFFIX,
RANDOM_SEQUENCE_LENGTH,
ROOT_KEY,
MOCK_SET_ERR_CODE,
} from './constants';
export {
parseToolSchema,
calcStringSize,
getArrayItemKey,
getMockValue,
transSchema2DataWithStatus,
transDataWithStatus2Object,
stringifyEditorContent,
getEnvironment,
getMockSubjectInfo,
getPluginInfo,
} from './utils';
export {
type BizCtxInfo,
type BasicMockSetInfo,
type BindSubjectDetail,
BindSubjectInfo,
type MockSetSelectProps,
type MockSelectOptionProps,
type MockSelectRenderOptionProps,
MockSetStatus,
} from './types/interface';

View File

@@ -0,0 +1,62 @@
/*
* 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.
*/
import { type MockRule } from '@coze-arch/bot-api/debugger_api';
export enum MockDataValueType {
STRING = 'string',
INTEGER = 'integer',
NUMBER = 'number',
OBJECT = 'object',
ARRAY = 'array',
BOOLEAN = 'boolean',
}
export enum MockDataStatus {
DEFAULT = 'default',
REMOVED = 'removed',
ADDED = 'added',
}
export interface MockDataWithStatus {
/** key */
key: string;
/** 字段名称 */
label: string;
/** 字段值 */
realValue?: string | number | boolean;
/** 展示使用 */
displayValue?: string;
/** 描述 */
description?: string;
/** 是否必填 */
isRequired: boolean;
/** 字段数据类型 */
type: MockDataValueType;
/** for array */
childrenType?: MockDataValueType;
/** 字段状态 */
status: MockDataStatus;
/** 字段子节点 */
children?: MockDataWithStatus[];
}
export interface MockDataInfo {
schema?: string;
mock?: MockRule;
mergedResultExample?: string;
incompatible?: boolean;
}

View File

@@ -0,0 +1,63 @@
/*
* 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.
*/
import { type CSSProperties } from 'react';
import {
type OptionProps,
type optionRenderProps,
} from '@coze-arch/bot-semi/Select';
import {
type BizCtx,
type MockSet,
type ComponentSubject,
} from '@coze-arch/bot-api/debugger_api';
export interface BizCtxInfo
extends Omit<BizCtx, 'connectorID' | 'connectorUID' | 'ext'> {
ext?: { mockSubjectInfo?: string } & Record<string, string>;
}
export type BindSubjectInfo = ComponentSubject & { detail?: BindSubjectDetail };
export interface BasicMockSetInfo {
bindSubjectInfo: ComponentSubject;
bizCtx: BizCtx;
}
export interface BindSubjectDetail {
name?: string;
}
export interface MockSetSelectProps {
bindSubjectInfo: BindSubjectInfo;
bizCtx: BizCtxInfo;
className?: string;
style?: CSSProperties;
readonly?: boolean;
}
export enum MockSetStatus {
Incompatible = 'Incompatible',
Normal = 'Normal',
}
export interface MockSelectOptionProps extends OptionProps {
detail?: MockSet;
}
export interface MockSelectRenderOptionProps extends optionRenderProps {
detail?: MockSet;
}

View File

@@ -0,0 +1,17 @@
/*
* 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.
*/
/// <reference types='@coze-arch/bot-typings' />

View File

@@ -0,0 +1,284 @@
/*
* 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.
*/
import type { JSONSchema7, JSONSchema7TypeName } from 'json-schema';
import {
TrafficScene,
type ComponentSubject,
} from '@coze-arch/bot-api/debugger_api';
import { type BizCtxInfo } from '../types/interface';
import {
type MockDataWithStatus,
MockDataValueType,
MockDataStatus,
} from '../types';
import {
FORMAT_SPACE_SETTING,
STRING_DISPLAY_PREFIX,
STRING_DISPLAY_SUFFIX,
} from '../constants';
function safeJSONParse<T>(str: string, errCb?: () => T | undefined) {
try {
return JSON.parse(str) as T;
} catch (error) {
return errCb?.();
}
}
export function parseToolSchema(str: string) {
return safeJSONParse<JSONSchema7>(str);
}
const ARRAY_PREFIX_KEY = 'item_';
export function getArrayItemKey(index: number | string) {
return `${ARRAY_PREFIX_KEY}${index}`;
}
export const calcStringSize = (str: string) => {
if (!str) {
return 0;
}
const { size } = new Blob([str]);
return size;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- plugin resp 的类型由用户定义,包含任何可能
type PluginRespType = any;
// 转换 DataWithStatus 格式到 Object 格式
export function transDataWithStatus2Object(
data: MockDataWithStatus,
excludeRemovedItem?: boolean,
) {
if (data.status === MockDataStatus.REMOVED) {
return {};
}
switch (data.type) {
case MockDataValueType.ARRAY:
return {
[data.label]: data.children?.reduce((acc: PluginRespType[], item) => {
const realValue = transDataWithStatus2Object(
item,
excludeRemovedItem,
)[getArrayItemKey(0)];
realValue !== undefined && acc.push(realValue);
return acc;
}, []),
};
case MockDataValueType.OBJECT:
return {
[data.label]: data.children?.reduce(
(acc: Record<string, PluginRespType>, item) => {
acc = {
...acc,
...transDataWithStatus2Object(item, excludeRemovedItem),
};
return acc;
},
{},
),
};
default:
return {
[data.label]: data.realValue,
};
}
}
export function getMockValue(
type: MockDataValueType,
fns: {
getStringValue: () => string;
getNumberValue: () => number;
getBooleanValue: () => boolean;
},
): [string | number | boolean | undefined, string | undefined] {
switch (type) {
case MockDataValueType.STRING: {
const mockStr = fns.getStringValue();
return [
mockStr,
`${STRING_DISPLAY_PREFIX}${mockStr}${STRING_DISPLAY_SUFFIX}`,
];
}
case MockDataValueType.BOOLEAN: {
const mockBool = fns.getBooleanValue();
return [mockBool, `${mockBool}`];
}
case MockDataValueType.NUMBER:
case MockDataValueType.INTEGER: {
const mockNum = fns.getNumberValue();
return [mockNum, `${mockNum}`];
}
default:
return [undefined, undefined];
}
}
// 由 schema 生成 DataWithStatus 时不同类型的生成逻辑
function getInitialValue(
type: MockDataValueType,
): [string | number | boolean | undefined, string | undefined] {
return getMockValue(type, {
getBooleanValue: () => false,
getNumberValue: () => 0,
getStringValue: () => '',
});
}
function getSchemaType(type?: JSONSchema7TypeName | JSONSchema7TypeName[]) {
const val = typeof type === 'object' ? type[0] : type;
return val === 'null' ? undefined : (val as MockDataValueType);
}
// 转换 schema 格式到 DataWithStatus 格式(包含初始化逻辑)
// eslint-disable-next-line complexity
export function transSchema2DataWithStatus(
label: string,
schema?: JSONSchema7,
params?: {
required?: string[];
keyPrefix?: string;
generateFn?: (
type: MockDataValueType,
) => [string | number | boolean | undefined, string | undefined];
},
): MockDataWithStatus | undefined {
const dataTypeName = getSchemaType(schema?.type);
if (!schema || !dataTypeName) {
return undefined;
}
const { generateFn = getInitialValue } = params || {};
const [realValue, displayValue] = generateFn(dataTypeName);
const itemKey = params?.keyPrefix ? `${params?.keyPrefix}-${label}` : label;
const item: MockDataWithStatus = {
label,
realValue,
displayValue,
description: schema.description,
isRequired: params?.required?.includes(label) || false,
type: dataTypeName,
status: MockDataStatus.ADDED,
key: itemKey,
};
if (dataTypeName === MockDataValueType.OBJECT) {
const children: MockDataWithStatus[] = [];
for (const property in schema.properties) {
if (property && typeof schema.properties[property] === 'object') {
const child = transSchema2DataWithStatus(
property,
schema.properties[property] as JSONSchema7,
{
required: schema.required,
keyPrefix: itemKey,
generateFn,
},
);
child && children.push(child);
}
}
item.children = children;
}
if (
dataTypeName === MockDataValueType.ARRAY &&
typeof schema.items === 'object'
) {
const childrenSchema =
schema.items instanceof Array ? schema.items[0] : schema.items;
if (typeof childrenSchema === 'object') {
item.childrenType = getSchemaType(childrenSchema.type);
const child = transSchema2DataWithStatus(
getArrayItemKey(0),
childrenSchema as JSONSchema7,
{
required: schema.required,
keyPrefix: itemKey,
generateFn,
},
);
child ? (item.children = [child]) : undefined;
}
}
return item;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- 内容结构依赖用户定义的 plugin resp 结构,包含任何可能
export function stringifyEditorContent(value: any) {
return JSON.stringify(value, null, FORMAT_SPACE_SETTING);
}
export function getPluginInfo(
bizCtx: BizCtxInfo,
mockSubjectInfo: ComponentSubject,
): { spaceID?: string; pluginID?: string; toolID?: string } {
const { bizSpaceID, ext, trafficScene } = bizCtx || {};
const extMockSubjectInfo = safeJSONParse(ext?.mockSubjectInfo || '{}');
const { componentID, parentComponentID } = mockSubjectInfo;
switch (trafficScene) {
case TrafficScene.CozeWorkflowDebug:
return {
spaceID: bizSpaceID,
// @ts-expect-error - skip
toolID: extMockSubjectInfo?.componentID,
// @ts-expect-error - skip
pluginID: extMockSubjectInfo?.parentComponentID,
};
case TrafficScene.CozeSingleAgentDebug:
case TrafficScene.CozeMultiAgentDebug:
case TrafficScene.CozeToolDebug:
default:
return {
spaceID: bizSpaceID,
toolID: componentID,
pluginID: parentComponentID,
};
}
}
export function getMockSubjectInfo(
bizCtx: BizCtxInfo,
mockSubjectInfo: ComponentSubject,
) {
const { ext, trafficScene } = bizCtx || {};
const extMockSubjectInfo = safeJSONParse(ext?.mockSubjectInfo || '{}');
switch (trafficScene) {
case TrafficScene.CozeWorkflowDebug:
return extMockSubjectInfo;
case TrafficScene.CozeSingleAgentDebug:
case TrafficScene.CozeMultiAgentDebug:
case TrafficScene.CozeToolDebug:
default:
return mockSubjectInfo;
}
}
export function getEnvironment() {
if (!IS_PROD) {
return 'cn-boe';
}
const regionPart = IS_OVERSEA ? 'oversea' : 'cn';
const inhousePart = IS_RELEASE_VERSION ? 'release' : 'inhouse';
return [regionPart, inhousePart].join('-');
}