breadboard-ai / breadboard

A library for prototyping generative AI applications.
Apache License 2.0
185 stars 25 forks source link

Infinite recursion bug #3562

Open surma opened 1 week ago

surma commented 1 week ago

When running the attached board, the page freezes. A quick glance at DevTools seems to indicate that Entry#findOrCreate is recursing infinitely.

Board JSON ``` { "title": "dumbai", "description": "A blank board. Use it as a starting point for your creations.", "version": "0.0.1", "nodes": [ { "id": "dumbai-0b37eb16", "type": "idb://board-server-local/dumbai.bgl.json", "metadata": { "visual": { "x": -124, "y": -135, "collapsed": "advanced" }, "logLevel": "debug" }, "configuration": { "base": [ { "role": "user", "parts": [ { "text": "http://litellm.surmcluster.10.0.0.2.nip.io" } ] } ], "model": [ { "role": "user", "parts": [ { "text": "llama3.2-1b-surmbook" } ] } ], "prompt": [ { "role": "user", "parts": [ { "text": "" } ] } ], "system": [ { "role": "user", "parts": [ { "text": "You are a bot that replies to user quests in l33t sp34k!" } ] } ] } }, { "id": "input-bea2b58e", "type": "input", "metadata": { "visual": { "x": -617, "y": -68, "collapsed": "collapsed" }, "title": "Input" }, "configuration": { "schema": { "properties": { "context": { "type": "array", "title": "Context", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ] }, "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]" } }, "type": "object", "required": [] } } }, { "id": "output-b1d31c94", "type": "output", "metadata": { "visual": { "x": 609.5, "y": -52.74853515625, "collapsed": "collapsed" }, "title": "Output" }, "configuration": { "schema": { "properties": { "context": { "type": "array", "title": "Context", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ] }, "default": "null" } }, "type": "object", "required": [] } } } ], "edges": [ { "from": "input-bea2b58e", "to": "dumbai-0b37eb16", "out": "context", "in": "prompt" }, { "from": "dumbai-0b37eb16", "to": "output-b1d31c94", "out": "context", "in": "context" } ], "url": "idb://board-server-local/dumbai.bgl.json", "metadata": { "comments": [] }, "graphs": { "2f4cf71f-4890-4a20-b9c5-ed852e2dd311": { "title": "OpenAI request", "description": "A blank board. Use it as a starting point for your creations.", "version": "0.0.1", "nodes": [ { "type": "input", "id": "input", "configuration": { "schema": { "properties": { "model": { "type": "array", "title": "Model", "items": { "type": "object", "behavior": [ "llm-content" ] }, "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]", "description": "" } }, "type": "object", "required": [] } }, "metadata": { "visual": { "x": 0, "y": 187, "collapsed": "collapsed" }, "logLevel": "debug" } }, { "type": "output", "id": "output", "configuration": { "schema": { "properties": { "response": { "type": "array", "title": "Response", "items": { "type": "object", "behavior": [ "llm-content" ] }, "default": "[{\"parts\":[],\"role\":\"user\"}]", "description": "" } }, "type": "object", "required": [] } }, "metadata": { "visual": { "x": 1445, "y": 532, "collapsed": "collapsed" }, "logLevel": "debug" } }, { "id": "fetch-5952907d", "type": "fetch", "metadata": { "visual": { "x": 771, "y": 419, "collapsed": "collapsed" }, "title": "Fetch" } }, { "id": "urlTemplate-d45d8d90", "type": "urlTemplate", "metadata": { "visual": { "x": 339, "y": 0, "collapsed": "collapsed" }, "title": "URL Template", "logLevel": "debug" }, "configuration": { "template": "http://{{base}}/chat/completions" } }, { "id": "input-f28f6006", "type": "input", "metadata": { "visual": { "x": 0, "y": 351, "collapsed": "collapsed" }, "title": "Input", "logLevel": "debug" }, "configuration": { "schema": { "properties": { "system": { "type": "array", "title": "System Prompt", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ] }, "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]", "description": "" } }, "type": "object", "required": [] } } }, { "id": "input-6cb30c0b", "type": "input", "metadata": { "visual": { "x": 0, "y": 515, "collapsed": "collapsed" }, "title": "Input", "logLevel": "debug" }, "configuration": { "schema": { "properties": { "prompt": { "type": "array", "title": "Prompt", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ] }, "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]", "description": "" } }, "type": "object", "required": [] } } }, { "id": "input-6e85311d", "type": "input", "metadata": { "visual": { "x": 0, "y": 23, "collapsed": "collapsed" }, "title": "Input", "logLevel": "debug" }, "configuration": { "schema": { "properties": { "base": { "type": "array", "title": "Base URL", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ] }, "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"http://localhost:11434\"}]}]", "description": "" } }, "type": "object", "required": [] } } }, { "id": "runJavascript-08a7708c", "type": "runJavascript", "metadata": { "visual": { "x": 290, "y": 345, "collapsed": "collapsed" }, "title": "Run Javascript", "logLevel": "debug" }, "configuration": { "code": "function run({model, system, prompt}) {\n return {\n body: {\n model,\n messages: [\n {\n role: \"system\",\n content: system\n },\n {\n role: \"user\",\n content: prompt\n }\n ]\n }\n };\n}", "name": "run", "inputSchema": { "type": "object", "properties": { "model": { "type": "array", "title": "Model", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ], "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]" }, "description": "", "default": "[{\"parts\":[{\"text\":\"gpt-4o-mini\"}],\"role\":\"user\"}]" }, "system": { "type": "array", "title": "System Prompt", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ], "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]" }, "description": "", "default": "[{\"parts\":[],\"role\":\"user\"}]" }, "prompt": { "type": "array", "title": "User Prompt", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ], "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]" }, "description": "", "default": "[{\"parts\":[],\"role\":\"user\"}]" } }, "required": [] }, "outputSchema": { "type": "object", "properties": { "body": { "type": "array", "title": "Chat Completion Request Body", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ], "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]" }, "description": "", "default": "[{\"parts\":[],\"role\":\"user\"}]" } }, "required": [] } } }, { "id": "runJavascript-6d3318d5", "type": "runJavascript", "metadata": { "visual": { "x": 1061, "y": 428, "collapsed": "collapsed" }, "title": "Run Javascript", "logLevel": "debug" }, "configuration": { "inputSchema": { "type": "object", "properties": { "response": { "type": "array", "title": "Response", "items": { "type": "object", "examples": [], "behavior": [ "llm-content" ], "default": "[{\"role\":\"user\",\"parts\":[{\"text\":\"\"}]}]" }, "description": "", "default": "[{\"parts\":[],\"role\":\"user\"}]" } }, "required": [] }, "code": "function run({response}) {\n return response.choices[0].message.content\n}", "name": "run" } } ], "edges": [ { "from": "input-6e85311d", "to": "urlTemplate-d45d8d90", "in": "base", "out": "base" }, { "from": "urlTemplate-d45d8d90", "to": "fetch-5952907d", "in": "url", "out": "url" }, { "from": "input", "to": "runJavascript-08a7708c", "in": "model", "out": "model" }, { "from": "input-f28f6006", "to": "runJavascript-08a7708c", "in": "system", "out": "system" }, { "from": "input-6cb30c0b", "to": "runJavascript-08a7708c", "in": "prompt", "out": "prompt" }, { "from": "runJavascript-08a7708c", "to": "fetch-5952907d", "in": "body", "out": "result" }, { "from": "fetch-5952907d", "to": "runJavascript-6d3318d5", "in": "response", "out": "response" }, { "from": "runJavascript-6d3318d5", "to": "output", "in": "context", "out": "result" } ], "metadata": { "comments": [] } } } } ```
dglazkov commented 1 week ago

Fun! This board attempts to refer to itself, and that's why the weirdness happens.

dglazkov commented 1 week ago

it has three nodes:

We should probably not allow that 😆

dglazkov commented 1 week ago

seems like the right fix is to detect recursion in loader and bail with an error?

surma commented 1 week ago

I was trying to reference a subboard. I did that by opening the subboard, copying the URL using the tool bar icon and pasting it into the main board. Is that not the way? I could find the subboard in the components menu.

But yes, would be good to detect that ever being created, but also to detect at load.

surma commented 1 week ago

It's curious because the editor shows the correct inputs/outputs of the subboard... so it is clearly referencing the subboard. Not sure where I went wrong now 🤔

dglazkov commented 1 week ago

I did that by opening the subboard, copying the URL using the tool bar icon and pasting it into the main board

OOOH that's another bug! The URL it gave you was the main board URL!

dglazkov commented 1 week ago

The current working way of doing this is to use the invoke component, and then selecting the sub-board from the dropdown.

surma commented 1 week ago

Wait so I can paste other boards but I cannot paste a sub board? I think @paullewis is right that the name "subboard" is a misnomer. At least for me it causes associations that don't seem to hold

dglazkov commented 1 week ago

yeah, the whole "paste URL of the board as a component" hasn't propagated to sub-boards yet. Emergent software engineering 😆

dglazkov commented 1 week ago

Two bugs: