Add dynamic variable support to Assistant model and related components

- Introduce dynamic variable definitions in AssistantConfig and Assistant models, allowing for flexible prompt customization.
- Implement validation for dynamic variable names and types in the schema.
- Update backend services and routes to handle dynamic variables in assistant configurations and runtime processing.
- Enhance frontend components to support dynamic variable definitions, including a new editor for managing variables.
- Add tests to ensure proper functionality and validation of dynamic variables in various scenarios.
This commit is contained in:
Xin Wang
2026-07-12 23:42:56 +08:00
parent 7c9a18c806
commit deaf3d7730
21 changed files with 1396 additions and 12 deletions

View File

@@ -75,6 +75,8 @@ type ToolForm = {
secretHeaders: string;
parameters: string;
body: string;
dynamicVariableAssignments: string;
secretDynamicVariables: string;
};
const EMPTY_OBJECT = "{}";
@@ -97,6 +99,8 @@ function blankForm(): ToolForm {
secretHeaders: EMPTY_OBJECT,
parameters: EMPTY_ARRAY,
body: EMPTY_OBJECT,
dynamicVariableAssignments: EMPTY_OBJECT,
secretDynamicVariables: EMPTY_OBJECT,
};
}
@@ -121,8 +125,19 @@ function formFromTool(tool: Tool): ToolForm {
base.headers = pretty(tool.definition.config.headers, EMPTY_OBJECT);
base.parameters = pretty(tool.definition.config.parameters, EMPTY_ARRAY);
base.body = pretty(tool.definition.config.body, EMPTY_OBJECT);
const secrets = tool.secrets as { headers?: Record<string, string> };
base.dynamicVariableAssignments = pretty(
tool.definition.config.dynamicVariableAssignments ?? {},
EMPTY_OBJECT,
);
const secrets = tool.secrets as {
headers?: Record<string, string>;
dynamic_variables?: Record<string, string>;
};
base.secretHeaders = pretty(secrets.headers ?? {}, EMPTY_OBJECT);
base.secretDynamicVariables = pretty(
secrets.dynamic_variables ?? {},
EMPTY_OBJECT,
);
return base;
}
@@ -191,6 +206,14 @@ function payloadFromForm(form: ToolForm): ToolUpsert {
const headers = parseObject(form.headers, "Header");
const secretHeaders = parseObject(form.secretHeaders, "敏感 Header");
const body = parseObject(form.body, "固定 Body");
const dynamicVariableAssignments = parseObject(
form.dynamicVariableAssignments,
"变量赋值",
);
const secretDynamicVariables = parseObject(
form.secretDynamicVariables,
"密钥变量",
);
const parameters = parseParameters(form.parameters);
return {
name: form.name.trim(),
@@ -207,9 +230,13 @@ function payloadFromForm(form: ToolForm): ToolUpsert {
headers: headers as Record<string, string>,
parameters,
body,
dynamicVariableAssignments: dynamicVariableAssignments as Record<string, string>,
},
},
secrets: { headers: secretHeaders },
secrets: {
headers: secretHeaders,
dynamic_variables: secretDynamicVariables,
},
};
}
@@ -741,6 +768,20 @@ function HttpFields({
<JsonField label="敏感 Header" value={form.secretHeaders} onChange={(secretHeaders) => setForm((current) => ({ ...current, secretHeaders }))} />
<JsonField label="参数定义" value={form.parameters} onChange={(parameters) => setForm((current) => ({ ...current, parameters }))} rows={6} />
<JsonField label="固定 Body" value={form.body} onChange={(body) => setForm((current) => ({ ...current, body }))} />
<JsonField
label="响应变量赋值"
value={form.dynamicVariableAssignments}
onChange={(dynamicVariableAssignments) =>
setForm((current) => ({ ...current, dynamicVariableAssignments }))
}
/>
<JsonField
label="密钥变量"
value={form.secretDynamicVariables}
onChange={(secretDynamicVariables) =>
setForm((current) => ({ ...current, secretDynamicVariables }))
}
/>
</div>
);
}