feat(frontend): Add field extraction handle for block with object output (#8900)
This addresses https://github.com/Significant-Gravitas/AutoGPT/issues/8741 We have quite a few blocks with (object) outputs. The only way to really use these is to use a "Find In Dictionary" block to pick out that property. If the structure of the output object is known, we should expose the properties of the object directly as sub-outputs. This will make a huge difference in UX and make using these blocks much much easier. ### Changes 🏗️ Recursively flatten object fields into output node handles <img width="637" alt="image" src="https://github.com/user-attachments/assets/dac1f691-9866-4bb7-96b7-20fa6ddbb616"> <img width="773" alt="image" src="https://github.com/user-attachments/assets/f8e7f97c-b245-40bd-b84f-2c044f5f9e23"> ### Checklist 📋 #### For code changes: - [ ] I have clearly listed my changes in the PR description - [ ] I have made a test plan - [ ] I have tested my changes according to the test plan: <!-- Put your test plan here: --> - [ ] ... <details> <summary>Example test plan</summary> - [ ] Create from scratch and execute an agent with at least 3 blocks - [ ] Import an agent from file upload, and confirm it executes correctly - [ ] Upload agent to marketplace - [ ] Import an agent from marketplace and confirm it executes correctly - [ ] Edit an agent from monitor, and confirm it executes correctly </details> #### For configuration changes: - [ ] `.env.example` is updated or already compatible with my changes - [ ] `docker-compose.yml` is updated or already compatible with my changes - [ ] I have included a list of my configuration changes in the PR description (under **Changes**) <details> <summary>Examples of configuration changes</summary> - Changing ports - Adding new services that need to communicate with each other - Secrets or environment variable changes - New or infrastructure changes such as databases </details> Co-authored-by: Nicholas Tindle <nicholas.tindle@agpt.co>
This commit is contained in:
parent
e6d728b081
commit
79c0c314e2
|
@ -13,6 +13,7 @@ import InputModalComponent from "./InputModalComponent";
|
|||
import OutputModalComponent from "./OutputModalComponent";
|
||||
import {
|
||||
BlockIORootSchema,
|
||||
BlockIOSubSchema,
|
||||
BlockIOStringSubSchema,
|
||||
Category,
|
||||
NodeExecutionResult,
|
||||
|
@ -167,17 +168,38 @@ export function CustomNode({
|
|||
nodeType === BlockUIType.NOTE
|
||||
)
|
||||
return null;
|
||||
const keys = Object.keys(schema.properties);
|
||||
return keys.map((key) => (
|
||||
<div key={key}>
|
||||
<NodeHandle
|
||||
keyName={key}
|
||||
isConnected={isOutputHandleConnected(key)}
|
||||
schema={schema.properties[key]}
|
||||
side="right"
|
||||
/>
|
||||
</div>
|
||||
));
|
||||
|
||||
const renderHandles = (
|
||||
propSchema: { [key: string]: BlockIOSubSchema },
|
||||
keyPrefix = "",
|
||||
titlePrefix = "",
|
||||
) => {
|
||||
return Object.keys(propSchema).map((propKey) => {
|
||||
const fieldSchema = propSchema[propKey];
|
||||
const fieldTitle =
|
||||
titlePrefix + (fieldSchema.title || beautifyString(propKey));
|
||||
|
||||
return (
|
||||
<div key={propKey}>
|
||||
<NodeHandle
|
||||
title={fieldTitle}
|
||||
keyName={`${keyPrefix}${propKey}`}
|
||||
isConnected={isOutputHandleConnected(propKey)}
|
||||
schema={fieldSchema}
|
||||
side="right"
|
||||
/>
|
||||
{"properties" in fieldSchema &&
|
||||
renderHandles(
|
||||
fieldSchema.properties,
|
||||
`${keyPrefix}${propKey}_#_`,
|
||||
`${fieldTitle}.`,
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
return renderHandles(schema.properties);
|
||||
};
|
||||
|
||||
const generateInputHandles = (
|
||||
|
|
|
@ -10,6 +10,7 @@ type HandleProps = {
|
|||
isConnected: boolean;
|
||||
isRequired?: boolean;
|
||||
side: "left" | "right";
|
||||
title?: string;
|
||||
};
|
||||
|
||||
const NodeHandle: FC<HandleProps> = ({
|
||||
|
@ -18,6 +19,7 @@ const NodeHandle: FC<HandleProps> = ({
|
|||
isConnected,
|
||||
isRequired,
|
||||
side,
|
||||
title,
|
||||
}) => {
|
||||
const typeName: Record<string, string> = {
|
||||
string: "text",
|
||||
|
@ -34,7 +36,7 @@ const NodeHandle: FC<HandleProps> = ({
|
|||
const label = (
|
||||
<div className="flex flex-grow flex-row">
|
||||
<span className="text-m green flex items-end pr-2 text-gray-900">
|
||||
{schema.title || beautifyString(keyName.toLowerCase())}
|
||||
{title || schema.title || beautifyString(keyName.toLowerCase())}
|
||||
{isRequired ? "*" : ""}
|
||||
</span>
|
||||
<span className={`${typeClass} flex items-end`}>
|
||||
|
|
Loading…
Reference in New Issue