Skip to content

Commit

Permalink
fix(platform): Fix unexpected connection clash on two dynamic pins li…
Browse files Browse the repository at this point in the history
…nk with the same keys (#8252)
  • Loading branch information
majdyz authored Oct 9, 2024
1 parent c582b55 commit dbc603c
Show file tree
Hide file tree
Showing 4 changed files with 678 additions and 365 deletions.
2 changes: 1 addition & 1 deletion autogpt_platform/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"@supabase/ssr": "^0.4.0",
"@supabase/supabase-js": "^2.45.0",
"@tanstack/react-table": "^8.20.5",
"@xyflow/react": "^12.1.0",
"@xyflow/react": "^12.3.1",
"ajv": "^8.17.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
Expand Down
3 changes: 3 additions & 0 deletions autogpt_platform/frontend/src/components/CustomNode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ export function CustomNode({ data, id, width, height }: NodeProps<CustomNode>) {
<div key={propKey} onMouseOver={() => {}}>
{!isConnected && (
<NodeGenericInputField
nodeId={id}
className="mb-2 mt-1"
propKey={propKey}
propSchema={propSchema}
Expand Down Expand Up @@ -231,6 +232,7 @@ export function CustomNode({ data, id, width, height }: NodeProps<CustomNode>) {
)}
{!isConnected && (
<NodeGenericInputField
nodeId={id}
className="mb-2 mt-1"
propKey={propKey}
propSchema={propSchema}
Expand Down Expand Up @@ -270,6 +272,7 @@ export function CustomNode({ data, id, width, height }: NodeProps<CustomNode>) {
)}
{!isConnected && (
<NodeGenericInputField
nodeId={id}
className="mb-2 mt-1"
propKey={propKey}
propSchema={propSchema}
Expand Down
44 changes: 30 additions & 14 deletions autogpt_platform/frontend/src/components/node-input-components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { ConnectionData } from "./CustomNode";
import { CredentialsInput } from "./integrations/credentials-input";

type NodeObjectInputTreeProps = {
nodeId: string;
selfKey?: string;
schema: BlockIORootSchema | BlockIOObjectSubSchema;
object?: { [key: string]: any };
Expand All @@ -39,6 +40,7 @@ type NodeObjectInputTreeProps = {
};

const NodeObjectInputTree: FC<NodeObjectInputTreeProps> = ({
nodeId,
selfKey = "",
schema,
object,
Expand All @@ -65,6 +67,7 @@ const NodeObjectInputTree: FC<NodeObjectInputTreeProps> = ({
{propSchema.title || beautifyString(propKey)}
</span>
<NodeGenericInputField
nodeId={nodeId}
key={propKey}
propKey={childKey}
propSchema={propSchema}
Expand All @@ -85,6 +88,7 @@ const NodeObjectInputTree: FC<NodeObjectInputTreeProps> = ({
export default NodeObjectInputTree;

export const NodeGenericInputField: FC<{
nodeId: string;
propKey: string;
propSchema: BlockIOSubSchema;
currentValue?: any;
Expand All @@ -95,6 +99,7 @@ export const NodeGenericInputField: FC<{
className?: string;
displayName?: string;
}> = ({
nodeId,
propKey,
propSchema,
currentValue,
Expand Down Expand Up @@ -131,6 +136,7 @@ export const NodeGenericInputField: FC<{
if ("properties" in propSchema) {
return (
<NodeObjectInputTree
nodeId={nodeId}
selfKey={propKey}
schema={propSchema}
object={currentValue}
Expand All @@ -147,6 +153,7 @@ export const NodeGenericInputField: FC<{
if ("additionalProperties" in propSchema) {
return (
<NodeKeyValueInput
nodeId={nodeId}
selfKey={propKey}
schema={propSchema}
entries={currentValue}
Expand Down Expand Up @@ -247,6 +254,7 @@ export const NodeGenericInputField: FC<{
case "array":
return (
<NodeArrayInput
nodeId={nodeId}
selfKey={propKey}
schema={propSchema}
entries={currentValue}
Expand All @@ -261,6 +269,7 @@ export const NodeGenericInputField: FC<{
case "object":
return (
<NodeKeyValueInput
nodeId={nodeId}
selfKey={propKey}
schema={propSchema}
entries={currentValue}
Expand Down Expand Up @@ -314,6 +323,7 @@ const NodeCredentialsInput: FC<{
};

const NodeKeyValueInput: FC<{
nodeId: string;
selfKey: string;
schema: BlockIOKVSubSchema;
entries?: { [key: string]: string } | { [key: string]: number };
Expand All @@ -323,6 +333,7 @@ const NodeKeyValueInput: FC<{
className?: string;
displayName?: string;
}> = ({
nodeId,
selfKey,
entries,
schema,
Expand All @@ -333,18 +344,15 @@ const NodeKeyValueInput: FC<{
displayName,
}) => {
const getPairValues = useCallback(() => {
let defaultEntries = new Map<string, any>();

// Map will preserve the order of entries.
const defaultEntries = new Map(
Object.entries(entries ?? schema.default ?? {}),
);
const prefix = getEntryKey("");
connections
.filter((c) => c.targetHandle.startsWith(`${selfKey}_`))
.forEach((c) => {
const key = c.targetHandle.slice(`${selfKey}_#_`.length);
defaultEntries.set(key, "");
});

Object.entries(entries ?? schema.default ?? {}).forEach(([key, value]) => {
defaultEntries.set(key, value);
});
.filter((c) => c.targetHandle.startsWith(prefix))
.map((c) => c.targetHandle.slice(prefix.length))
.forEach((k) => !defaultEntries.has(k) && defaultEntries.set(k, ""));

return Array.from(defaultEntries, ([key, value]) => ({ key, value }));
}, [connections, entries, schema.default, selfKey]);
Expand Down Expand Up @@ -380,15 +388,17 @@ const NodeKeyValueInput: FC<{
return `${selfKey}_#_${key}`;
}
function isConnected(key: string): boolean {
return connections.some((c) => c.targetHandle === getEntryKey(key));
return connections.some(
(c) => c.targetHandle === getEntryKey(key) && c.target === nodeId,
);
}

return (
<div className={cn(className, "flex flex-col")}>
{displayName && <strong>{displayName}</strong>}
<div>
{keyValuePairs.map(({ key, value }, index) => (
<div key={index}>
<div key={getEntryKey(key)}>
{key && (
<NodeHandle
keyName={getEntryKey(key)}
Expand Down Expand Up @@ -461,6 +471,7 @@ const NodeKeyValueInput: FC<{
};

const NodeArrayInput: FC<{
nodeId: string;
selfKey: string;
schema: BlockIOArraySubSchema;
entries?: string[];
Expand All @@ -471,6 +482,7 @@ const NodeArrayInput: FC<{
className?: string;
displayName?: string;
}> = ({
nodeId,
selfKey,
schema,
entries,
Expand All @@ -491,7 +503,10 @@ const NodeArrayInput: FC<{
{entries.map((entry: any, index: number) => {
const entryKey = `${selfKey}_$_${index}`;
const isConnected =
connections && connections.some((c) => c.targetHandle === entryKey);
connections &&
connections.some(
(c) => c.targetHandle === entryKey && c.target === nodeId,
);
return (
<div key={entryKey} className="self-start">
<div className="mb-2 flex space-x-2">
Expand All @@ -505,6 +520,7 @@ const NodeArrayInput: FC<{
{!isConnected &&
(schema.items ? (
<NodeGenericInputField
nodeId={nodeId}
propKey={entryKey}
propSchema={schema.items}
currentValue={entry}
Expand Down
Loading

0 comments on commit dbc603c

Please sign in to comment.