136 lines
3.5 KiB
TypeScript
136 lines
3.5 KiB
TypeScript
/*
|
||
* 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 { useCallback, useMemo } from 'react';
|
||
|
||
import { safeJSONParse } from '@coze-arch/bot-utils';
|
||
|
||
import {
|
||
ROOT_KEY,
|
||
parseToolSchema,
|
||
stringifyEditorContent,
|
||
transDataWithStatus2Object,
|
||
transSchema2DataWithStatus,
|
||
MockDataValueType,
|
||
type MockDataWithStatus,
|
||
} from '@coze-studio/mockset-shared';
|
||
|
||
import { getMergedDataWithStatus } from '../util/utils';
|
||
|
||
/** 缓存最新一个解析结果 */
|
||
const cache: {
|
||
schema: string;
|
||
result: MockDataWithStatus | undefined;
|
||
} = {
|
||
schema: '',
|
||
result: undefined,
|
||
};
|
||
|
||
export const PRE_DEFINED_NO_EMPTY_KEY = 'response_for_model';
|
||
|
||
function useGetCachedSchemaData(schema?: string) {
|
||
const result = useMemo(() => {
|
||
if (schema && cache.schema === schema) {
|
||
return cache.result;
|
||
}
|
||
|
||
if (schema) {
|
||
cache.schema = schema;
|
||
const parsedSchema = parseToolSchema(schema);
|
||
const transData = transSchema2DataWithStatus(ROOT_KEY, parsedSchema);
|
||
cache.result = transData;
|
||
return transData;
|
||
}
|
||
|
||
return undefined;
|
||
}, [schema]);
|
||
|
||
return result;
|
||
}
|
||
|
||
export function useTransSchema(schema?: string, currentMock?: string) {
|
||
const result = useGetCachedSchemaData(schema);
|
||
|
||
const {
|
||
result: mergedResultExample,
|
||
merged: mergedResult,
|
||
incompatible,
|
||
formatted: formattedResultExample,
|
||
} = useMemo(() => {
|
||
const { result: merged, incompatible: mergedIncompatible } =
|
||
getMergedDataWithStatus(result, currentMock);
|
||
|
||
if (merged) {
|
||
const resultObj = transDataWithStatus2Object(
|
||
merged,
|
||
currentMock !== undefined,
|
||
)?.[ROOT_KEY];
|
||
|
||
return {
|
||
merged,
|
||
result: resultObj,
|
||
formatted: stringifyEditorContent(resultObj),
|
||
incompatible: mergedIncompatible,
|
||
};
|
||
} else {
|
||
return {
|
||
incompatible: mergedIncompatible,
|
||
};
|
||
}
|
||
}, [result, currentMock]);
|
||
|
||
// 特殊字段需要单独处理:response_for_model 不能为空字符串
|
||
const testValueValid = useCallback(
|
||
(value: string) => {
|
||
if (
|
||
result?.children?.some(
|
||
item =>
|
||
item.label === PRE_DEFINED_NO_EMPTY_KEY &&
|
||
item.type === MockDataValueType.STRING,
|
||
)
|
||
) {
|
||
const parsedValue = safeJSONParse(value);
|
||
if (
|
||
typeof parsedValue === 'object' &&
|
||
(typeof parsedValue[PRE_DEFINED_NO_EMPTY_KEY] !== 'string' ||
|
||
parsedValue[PRE_DEFINED_NO_EMPTY_KEY].length === 0)
|
||
) {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
},
|
||
[result],
|
||
);
|
||
|
||
return {
|
||
// 由 schema 生成的结构话数据,值为初始值
|
||
result,
|
||
// 合并模拟数据的结构话数据,全集
|
||
mergedResult,
|
||
// mergedResult 转换的 object
|
||
mergedResultExample,
|
||
// 格式化的数据
|
||
formattedResultExample,
|
||
// 是否兼容
|
||
incompatible,
|
||
// 是否合并模拟数据
|
||
isInit: currentMock === undefined,
|
||
testValueValid,
|
||
};
|
||
}
|