feat(agent): support JSON object input on begin node (#16685)

### Summary

Add object as a begin-node parameter type with JSON editor UI, webhook
schema support, and backend parsing in UserFillUp.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
天海蒼灆
2026-07-07 11:40:57 +08:00
committed by GitHub
parent b4540672e4
commit 318045dda5
6 changed files with 38 additions and 1 deletions

View File

@@ -76,7 +76,13 @@ class UserFillUp(ComponentBase):
return FileService.get_files(files, layout_recognize=layout_recognize)
if isinstance(value, dict):
return value.get("value")
raw = value.get("value")
if value.get("type") == "object" and isinstance(raw, str) and raw.strip():
try:
return json.loads(raw)
except Exception:
return raw
return raw
return value

View File

@@ -2719,6 +2719,7 @@ This process aggregates variables from multiple branches into a single variable
file: 'File upload',
integer: 'Number',
boolean: 'Boolean',
object: 'JSON object',
logTimeline: {
begin: 'Ready to begin',

View File

@@ -1781,6 +1781,7 @@ NER使用 spaCy NER 和基于规则的关键词提取来抽取实体和关系
file: '文件',
integer: '数字',
boolean: '布尔值',
object: 'JSON 对象',
name: '名称',
singleLineText: '单行文本',
variableSettings: '变量设置',

View File

@@ -44,6 +44,7 @@ export enum PromptRole {
}
import {
Braces,
CloudUpload,
ListOrdered,
OptionIcon,
@@ -804,6 +805,7 @@ export enum BeginQueryType {
File = 'file',
Integer = 'integer',
Boolean = 'boolean',
Object = 'object',
}
export const BeginQueryTypeIconMap = {
@@ -813,6 +815,7 @@ export const BeginQueryTypeIconMap = {
[BeginQueryType.File]: CloudUpload,
[BeginQueryType.Integer]: ListOrdered,
[BeginQueryType.Boolean]: ToggleLeft,
[BeginQueryType.Object]: Braces,
};
export const NoDebugOperatorsList = [
@@ -1091,6 +1094,7 @@ export enum WebhookRequestParameters {
String = TypesWithArray.String,
Number = TypesWithArray.Number,
Boolean = TypesWithArray.Boolean,
Object = TypesWithArray.Object,
}
export enum WebhookStatus {
@@ -1107,6 +1111,7 @@ export const BeginQueryTypeMap = {
[BeginQueryType.File]: 'File',
[BeginQueryType.Integer]: TypesWithArray.Number,
[BeginQueryType.Boolean]: TypesWithArray.Boolean,
[BeginQueryType.Object]: TypesWithArray.Object,
};
export const VariableRegex = /{([^{}]*)}/g;

View File

@@ -1,4 +1,5 @@
import MarkdownContent from '@/components/next-markdown-content';
import JsonEditor from '@/components/json-edit';
import { SelectWithSearch } from '@/components/originui/select-with-search';
import { ButtonLoading } from '@/components/ui/button';
import {
@@ -72,6 +73,9 @@ const DebugContent = ({
fieldSchema = z.coerce.number();
} else if (type === BeginQueryType.File) {
fieldSchema = z.array(z.record(z.any())).min(1);
} else if (type === BeginQueryType.Object) {
fieldSchema = z.union([z.record(z.any()), z.array(z.any())]);
value = {};
} else {
fieldSchema = z.record(z.any());
}
@@ -218,6 +222,25 @@ const DebugContent = ({
)}
/>
),
[BeginQueryType.Object]: (
<FormField
control={form.control}
name={props.name}
render={({ field }) => (
<FormItem className="flex-1">
<FormLabel>{props.label}</FormLabel>
<FormControl>
<JsonEditor
value={field.value ?? {}}
onChange={field.onChange}
height="200px"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
),
};
return (

View File

@@ -33,6 +33,7 @@ export function WebhookRequestSchema() {
WebhookRequestParameters.String,
WebhookRequestParameters.Number,
WebhookRequestParameters.Boolean,
WebhookRequestParameters.Object,
];
}, [isFormDataContentType]);