mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-02 03:55:55 +00:00
fix: bad model field ref
This commit is contained in:
@@ -105,11 +105,16 @@ class LLMModelsService:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
pipeline = result.first()
|
pipeline = result.first()
|
||||||
if pipeline is not None and pipeline.config['ai']['local-agent']['model'] == '':
|
if pipeline is not None:
|
||||||
pipeline_config = pipeline.config
|
model_config = pipeline.config.get('ai', {}).get('local-agent', {}).get('model', {})
|
||||||
pipeline_config['ai']['local-agent']['model'] = model_data['uuid']
|
if not model_config.get('primary', ''):
|
||||||
pipeline_data = {'config': pipeline_config}
|
pipeline_config = pipeline.config
|
||||||
await self.ap.pipeline_service.update_pipeline(pipeline.uuid, pipeline_data)
|
pipeline_config['ai']['local-agent']['model'] = {
|
||||||
|
'primary': model_data['uuid'],
|
||||||
|
'fallbacks': [],
|
||||||
|
}
|
||||||
|
pipeline_data = {'config': pipeline_config}
|
||||||
|
await self.ap.pipeline_service.update_pipeline(pipeline.uuid, pipeline_data)
|
||||||
|
|
||||||
return model_data['uuid']
|
return model_data['uuid']
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,10 @@
|
|||||||
"runner": "local-agent"
|
"runner": "local-agent"
|
||||||
},
|
},
|
||||||
"local-agent": {
|
"local-agent": {
|
||||||
"model": "",
|
"model": {
|
||||||
|
"primary": "",
|
||||||
|
"fallbacks": []
|
||||||
|
},
|
||||||
"max-round": 10,
|
"max-round": 10,
|
||||||
"prompt": [
|
"prompt": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ def sample_query(sample_message_chain, sample_message_event, mock_adapter):
|
|||||||
pipeline_config={
|
pipeline_config={
|
||||||
'ai': {
|
'ai': {
|
||||||
'runner': {'runner': 'local-agent'},
|
'runner': {'runner': 'local-agent'},
|
||||||
'local-agent': {'model': 'test-model-uuid', 'prompt': 'test-prompt'},
|
'local-agent': {'model': {'primary': 'test-model-uuid', 'fallbacks': []}, 'prompt': 'test-prompt'},
|
||||||
},
|
},
|
||||||
'output': {'misc': {'at-sender': False, 'quote-origin': False}},
|
'output': {'misc': {'at-sender': False, 'quote-origin': False}},
|
||||||
'trigger': {'misc': {'combine-quote-message': False}},
|
'trigger': {'misc': {'combine-quote-message': False}},
|
||||||
@@ -219,7 +219,7 @@ def sample_pipeline_config():
|
|||||||
return {
|
return {
|
||||||
'ai': {
|
'ai': {
|
||||||
'runner': {'runner': 'local-agent'},
|
'runner': {'runner': 'local-agent'},
|
||||||
'local-agent': {'model': 'test-model-uuid', 'prompt': 'test-prompt'},
|
'local-agent': {'model': {'primary': 'test-model-uuid', 'fallbacks': []}, 'prompt': 'test-prompt'},
|
||||||
},
|
},
|
||||||
'output': {'misc': {'at-sender': False, 'quote-origin': False}},
|
'output': {'misc': {'at-sender': False, 'quote-origin': False}},
|
||||||
'trigger': {'misc': {'combine-quote-message': False}},
|
'trigger': {'misc': {'combine-quote-message': False}},
|
||||||
|
|||||||
@@ -34,6 +34,35 @@ export default function DynamicFormComponent({
|
|||||||
const previousInitialValues = useRef(initialValues);
|
const previousInitialValues = useRef(initialValues);
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
// Normalize a form value according to its field type.
|
||||||
|
// This ensures legacy/malformed data (e.g. a plain string for
|
||||||
|
// model-fallback-selector) is coerced to the expected shape
|
||||||
|
// so that downstream components never crash.
|
||||||
|
const normalizeFieldValue = (
|
||||||
|
item: IDynamicFormItemSchema,
|
||||||
|
value: unknown,
|
||||||
|
): unknown => {
|
||||||
|
if (item.type === 'model-fallback-selector') {
|
||||||
|
if (value != null && typeof value === 'object' && !Array.isArray(value)) {
|
||||||
|
const obj = value as Record<string, unknown>;
|
||||||
|
return {
|
||||||
|
primary: typeof obj.primary === 'string' ? obj.primary : '',
|
||||||
|
fallbacks: Array.isArray(obj.fallbacks)
|
||||||
|
? (obj.fallbacks as unknown[]).filter(
|
||||||
|
(v): v is string => typeof v === 'string',
|
||||||
|
)
|
||||||
|
: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Legacy string format or any other unexpected type
|
||||||
|
return {
|
||||||
|
primary: typeof value === 'string' ? value : '',
|
||||||
|
fallbacks: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
// 根据 itemConfigList 动态生成 zod schema
|
// 根据 itemConfigList 动态生成 zod schema
|
||||||
const formSchema = z.object(
|
const formSchema = z.object(
|
||||||
itemConfigList.reduce(
|
itemConfigList.reduce(
|
||||||
@@ -116,10 +145,10 @@ export default function DynamicFormComponent({
|
|||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: itemConfigList.reduce((acc, item) => {
|
defaultValues: itemConfigList.reduce((acc, item) => {
|
||||||
// 优先使用 initialValues,如果没有则使用默认值
|
// 优先使用 initialValues,如果没有则使用默认值
|
||||||
const value = initialValues?.[item.name] ?? item.default;
|
const rawValue = initialValues?.[item.name] ?? item.default;
|
||||||
return {
|
return {
|
||||||
...acc,
|
...acc,
|
||||||
[item.name]: value,
|
[item.name]: normalizeFieldValue(item, rawValue),
|
||||||
};
|
};
|
||||||
}, {} as FormValues),
|
}, {} as FormValues),
|
||||||
});
|
});
|
||||||
@@ -144,7 +173,8 @@ export default function DynamicFormComponent({
|
|||||||
// 合并默认值和初始值
|
// 合并默认值和初始值
|
||||||
const mergedValues = itemConfigList.reduce(
|
const mergedValues = itemConfigList.reduce(
|
||||||
(acc, item) => {
|
(acc, item) => {
|
||||||
acc[item.name] = initialValues[item.name] ?? item.default;
|
const rawValue = initialValues[item.name] ?? item.default;
|
||||||
|
acc[item.name] = normalizeFieldValue(item, rawValue) as object;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as Record<string, object>,
|
{} as Record<string, object>,
|
||||||
|
|||||||
@@ -348,10 +348,31 @@ export default function DynamicFormItemComponent({
|
|||||||
{} as Record<string, LLMModel[]>,
|
{} as Record<string, LLMModel[]>,
|
||||||
);
|
);
|
||||||
|
|
||||||
const modelValue = field.value as {
|
const rawModelValue = field.value;
|
||||||
primary: string;
|
const modelValue: { primary: string; fallbacks: string[] } =
|
||||||
fallbacks: string[];
|
rawModelValue != null &&
|
||||||
};
|
typeof rawModelValue === 'object' &&
|
||||||
|
!Array.isArray(rawModelValue)
|
||||||
|
? {
|
||||||
|
primary:
|
||||||
|
typeof (rawModelValue as Record<string, unknown>).primary ===
|
||||||
|
'string'
|
||||||
|
? ((rawModelValue as Record<string, unknown>)
|
||||||
|
.primary as string)
|
||||||
|
: '',
|
||||||
|
fallbacks: Array.isArray(
|
||||||
|
(rawModelValue as Record<string, unknown>).fallbacks,
|
||||||
|
)
|
||||||
|
? (
|
||||||
|
(rawModelValue as Record<string, unknown>)
|
||||||
|
.fallbacks as unknown[]
|
||||||
|
).filter((v): v is string => typeof v === 'string')
|
||||||
|
: [],
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
primary: typeof rawModelValue === 'string' ? rawModelValue : '',
|
||||||
|
fallbacks: [],
|
||||||
|
};
|
||||||
|
|
||||||
const renderModelSelect = (
|
const renderModelSelect = (
|
||||||
value: string,
|
value: string,
|
||||||
|
|||||||
Reference in New Issue
Block a user