diff --git a/assets/Cannoli College/1. Basics/1. Hello world.canvas b/assets/Cannoli College/1. Basics/1. Hello world.canvas index fce128e..a7991b9 100644 --- a/assets/Cannoli College/1. Basics/1. Hello world.canvas +++ b/assets/Cannoli College/1. Basics/1. Hello world.canvas @@ -1 +1,15 @@ -{"nodes":[{"type":"group","id":"161279baf7763214","x":-174,"y":-160,"width":394,"height":340,"label":"Cannoli"},{"type":"text","text":"Hello world!","id":"dc3f9351f787531e","x":-97,"y":-91,"width":250,"height":60},{"type":"text","text":"","id":"bc1a550bbb4aac7b","x":-97,"y":60,"width":250,"height":60,"color":"6"},{"type":"text","text":"The purple node is a content node. Content nodes can be used to store and display text that can be read or written by you or another node.","id":"f77169b141243e65","x":240,"y":30,"width":420,"height":120},{"type":"text","text":"The colorless, green, or yellow node is a call node. Call nodes make a chat completion call to the LLM with the text of the node as a user message.","id":"0af5a453bd4d6ec9","x":240,"y":-110,"width":380,"height":120},{"type":"text","text":"If a node in a cannoli is floating (no arrows attached) it won't affect the cannoli unless it is formatted in a special way we'll go over later.","id":"7d005c80299f3674","x":-202,"y":220,"width":461,"height":112},{"type":"text","text":"This is a Cannoli. It's made up of different types of nodes and arrows.\n\nTry running it by clicking the Cannoli button in the control ribbon on the left side of your Obsidian window.","id":"24dd96c964700992","x":-147,"y":-400,"width":350,"height":180},{"type":"text","text":"Cannolis can be run in several ways:\n\n- Click the Cannoli ribbon icon\n - If you're on a canvas file, it will be run as a cannoli\n - If you're on a note with a \"cannoli\" property, the canvas file in that property will be run as a cannoli\n- Run the \"Start/Stop cannoli\" command in the command palette (functions the same as the ribbon icon)\n- If a canvas file name ends with \".cno\", it will have its own run command in the command palette\n- Make an audio recording on a note with a \"cannoli\" property\n\t- That recording will be transcribed, replace the reference, and trigger the cannoli defined in the property.","id":"927cf33512b0dfc1","x":-740,"y":-182,"width":538,"height":402}],"edges":[{"id":"23c2d7dffb49bf75","fromNode":"dc3f9351f787531e","fromSide":"bottom","toNode":"bc1a550bbb4aac7b","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"161279baf7763214","x":-174,"y":-160,"width":394,"height":340,"label":"Cannoli"}, + {"type":"text","text":"Hello world!","id":"dc3f9351f787531e","x":-97,"y":-91,"width":250,"height":60}, + {"type":"text","text":"","id":"bc1a550bbb4aac7b","x":-97,"y":60,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"The purple node is a content node. Content nodes can be used to store and display text that can be read or written by you or another node.","id":"f77169b141243e65","x":240,"y":30,"width":420,"height":120}, + {"type":"text","text":"The colorless, green, or yellow node is a call node. Call nodes make a chat completion call to the LLM with the text of the node as a user message.","id":"0af5a453bd4d6ec9","x":240,"y":-110,"width":380,"height":120}, + {"type":"text","text":"If a node in a cannoli is floating (no arrows attached) it won't affect the cannoli unless it is formatted in a special way we'll go over later.","id":"7d005c80299f3674","x":-202,"y":220,"width":461,"height":112}, + {"type":"text","text":"This is a Cannoli. It's made up of different types of nodes and arrows.\n\nTry running it by clicking the Cannoli button in the control ribbon on the left side of your Obsidian window.","id":"24dd96c964700992","x":-147,"y":-400,"width":350,"height":180}, + {"type":"text","text":"Cannolis can be run in several ways:\n\n- Click the Cannoli ribbon icon\n - If you're on a canvas file, it will be run as a cannoli\n - If you're on a note with a \"cannoli\" property, the canvas file in that property will be run as a cannoli\n- Run the \"Start/Stop cannoli\" command in the command palette (functions the same as the ribbon icon)\n- If a canvas file name ends with \".cno\", it will have its own run command in the command palette\n- Make an audio recording on a note with a \"cannoli\" property\n\t- That recording will be transcribed, replace the reference, and trigger the cannoli defined in the property.","id":"927cf33512b0dfc1","x":-740,"y":-182,"width":538,"height":402} + ], + "edges":[ + {"id":"23c2d7dffb49bf75","fromNode":"dc3f9351f787531e","fromSide":"bottom","toNode":"bc1a550bbb4aac7b","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/1. Basics/2. Blank arrows.canvas b/assets/Cannoli College/1. Basics/2. Blank arrows.canvas index 62f91b8..b271a31 100644 --- a/assets/Cannoli College/1. Basics/2. Blank arrows.canvas +++ b/assets/Cannoli College/1. Basics/2. Blank arrows.canvas @@ -1 +1,18 @@ -{"nodes":[{"type":"group","id":"e77c462deb61200c","x":-200,"y":-240,"width":360,"height":600,"label":"Blank Arrows"},{"type":"text","text":"This first arrow is going from a call node to another call node, so it will pass the chat history along.","id":"ab7c414710f7f130","x":-478,"y":-160,"width":268,"height":135},{"type":"text","text":"The third arrow is going from a content node to a content node, so it will just copy its content.","id":"ccd789ee75f32cfa","x":-513,"y":191,"width":303,"height":102},{"type":"text","text":"This is the second user message, after an LLM response","id":"78cc7edc0acf7754","x":-145,"y":-39,"width":250,"height":110},{"type":"text","text":"This is the first user message","id":"f20327851c3175bd","x":-145,"y":-190,"width":250,"height":60},{"type":"text","text":"","id":"ffdc926f780c7c6f","x":-145,"y":131,"width":250,"height":60,"color":"6"},{"type":"text","text":"","id":"2a451cf329dad9eb","x":-145,"y":260,"width":250,"height":60,"color":"6"},{"type":"text","text":"The second arrow is going to a content node, so it will just pass the content of the LLM's response along.","id":"69c75646befb238b","x":170,"y":49,"width":344,"height":112},{"type":"text","text":"Arrows behave differently depending on their color, their label, and the type of their source and target (the node they are coming from and the node they point to).","id":"7f3c629307341974","x":-210,"y":-440,"width":380,"height":130}],"edges":[{"id":"3e2d98fc5ddeb168","fromNode":"78cc7edc0acf7754","fromSide":"bottom","toNode":"ffdc926f780c7c6f","toSide":"top"},{"id":"321db5e7d72b0151","fromNode":"ffdc926f780c7c6f","fromSide":"bottom","toNode":"2a451cf329dad9eb","toSide":"top"},{"id":"d08c98406e290f66","fromNode":"f20327851c3175bd","fromSide":"bottom","toNode":"78cc7edc0acf7754","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"e77c462deb61200c","x":-200,"y":-240,"width":360,"height":600,"label":"Blank Arrows"}, + {"type":"text","text":"This first arrow is going from a call node to another call node, so it will pass the chat history along.","id":"ab7c414710f7f130","x":-478,"y":-160,"width":268,"height":135}, + {"type":"text","text":"The third arrow is going from a content node to a content node, so it will just copy its content.","id":"ccd789ee75f32cfa","x":-513,"y":191,"width":303,"height":102}, + {"type":"text","text":"This is the second user message, after an LLM response","id":"78cc7edc0acf7754","x":-145,"y":-39,"width":250,"height":110}, + {"type":"text","text":"This is the first user message","id":"f20327851c3175bd","x":-145,"y":-190,"width":250,"height":60}, + {"type":"text","text":"","id":"ffdc926f780c7c6f","x":-145,"y":131,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"","id":"2a451cf329dad9eb","x":-145,"y":260,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"The second arrow is going to a content node, so it will just pass the content of the LLM's response along.","id":"69c75646befb238b","x":170,"y":49,"width":344,"height":112}, + {"type":"text","text":"Arrows behave differently depending on their color, their label, and the type of their source and target (the node they are coming from and the node they point to).","id":"7f3c629307341974","x":-210,"y":-440,"width":380,"height":130} + ], + "edges":[ + {"id":"3e2d98fc5ddeb168","fromNode":"78cc7edc0acf7754","fromSide":"bottom","toNode":"ffdc926f780c7c6f","toSide":"top"}, + {"id":"321db5e7d72b0151","fromNode":"ffdc926f780c7c6f","fromSide":"bottom","toNode":"2a451cf329dad9eb","toSide":"top"}, + {"id":"d08c98406e290f66","fromNode":"f20327851c3175bd","fromSide":"bottom","toNode":"78cc7edc0acf7754","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/1. Basics/3. Branching.canvas b/assets/Cannoli College/1. Basics/3. Branching.canvas index aa3bde9..336d467 100644 --- a/assets/Cannoli College/1. Basics/3. Branching.canvas +++ b/assets/Cannoli College/1. Basics/3. Branching.canvas @@ -1 +1,31 @@ -{"nodes":[{"type":"group","id":"7c382706de4d0696","x":-160,"y":-409,"width":695,"height":770,"label":"Multiple outgoing arrows"},{"type":"group","id":"5a24d53646b10364","x":-132,"y":480,"width":640,"height":480,"label":"Branching chats"},{"type":"text","text":"In this case, we are sending the output of each call node to a content node as well as another call node.\n\nThis shows us the LLM's response to each user message.","id":"a920f9e049043602","x":-460,"y":-228,"width":280,"height":240},{"type":"text","text":"","id":"69ab78708b319e8d","x":140,"y":-329,"width":340,"height":110,"color":"6"},{"type":"text","text":"","id":"c096758e55238bfe","x":175,"y":-178,"width":340,"height":250,"color":"6"},{"type":"text","text":"What's the best Italian dessert?","id":"7b37496e496da827","x":-137,"y":-359,"width":250,"height":60},{"type":"text","text":"How do you make it?","id":"aea9dcb543944bb1","x":-137,"y":-189,"width":250,"height":60},{"type":"text","text":"Give me a simpler recipe","id":"2f59408c2be9b7ae","x":-137,"y":12,"width":250,"height":60},{"type":"text","text":"","id":"ddb05069cb9f6f3e","x":113,"y":137,"width":390,"height":190,"color":"6"},{"type":"text","text":"Nodes can have multiple arrows coming out of them. They can carry information to different kinds of nodes.","id":"6d316338bfce7b20","x":28,"y":-580,"width":340,"height":100},{"type":"text","text":"Nf3","id":"248594446ba6eca2","x":-97,"y":691,"width":250,"height":60},{"type":"text","text":"Lets play chess. Here's my first move: e4","id":"891f6d7945759cd7","x":69,"y":500,"width":250,"height":60},{"type":"text","text":"Nc3","id":"5d4454ca8f7bdb3a","x":228,"y":691,"width":250,"height":60},{"type":"text","text":"","id":"3492caf4ead7f8cb","x":-107,"y":853,"width":260,"height":78,"color":"6"},{"type":"text","text":"","id":"9f9ba5852d437657","x":228,"y":853,"width":254,"height":78,"color":"6"},{"type":"text","text":"We can also use multiple outgoing arrows to create different branches of a chat","id":"5347076c683c8346","x":-392,"y":680,"width":255,"height":104}],"edges":[{"id":"d8d4ab1340924892","fromNode":"2f59408c2be9b7ae","fromSide":"bottom","toNode":"ddb05069cb9f6f3e","toSide":"left"},{"id":"806865b0c75a6687","fromNode":"aea9dcb543944bb1","fromSide":"bottom","toNode":"2f59408c2be9b7ae","toSide":"top"},{"id":"44a20edc995a84d8","fromNode":"aea9dcb543944bb1","fromSide":"bottom","toNode":"c096758e55238bfe","toSide":"left"},{"id":"b59766f15e6812d8","fromNode":"7b37496e496da827","fromSide":"bottom","toNode":"aea9dcb543944bb1","toSide":"top"},{"id":"8fd655a2583e6f98","fromNode":"7b37496e496da827","fromSide":"bottom","toNode":"69ab78708b319e8d","toSide":"left"},{"id":"7d1bb4c2b5052c34","fromNode":"891f6d7945759cd7","fromSide":"bottom","toNode":"248594446ba6eca2","toSide":"top"},{"id":"bc0b97379618ae28","fromNode":"891f6d7945759cd7","fromSide":"bottom","toNode":"5d4454ca8f7bdb3a","toSide":"top"},{"id":"08fda0370caa615e","fromNode":"248594446ba6eca2","fromSide":"bottom","toNode":"3492caf4ead7f8cb","toSide":"top"},{"id":"e1a68493483394b4","fromNode":"5d4454ca8f7bdb3a","fromSide":"bottom","toNode":"9f9ba5852d437657","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"7c382706de4d0696","x":-160,"y":-409,"width":695,"height":770,"label":"Multiple outgoing arrows"}, + {"type":"group","id":"5a24d53646b10364","x":-132,"y":480,"width":640,"height":480,"label":"Branching chats"}, + {"type":"text","text":"In this case, we are sending the output of each call node to a content node as well as another call node.\n\nThis shows us the LLM's response to each user message.","id":"a920f9e049043602","x":-460,"y":-228,"width":280,"height":240}, + {"type":"text","text":"","id":"69ab78708b319e8d","x":140,"y":-329,"width":340,"height":110,"color":"6"}, + {"type":"text","text":"","id":"c096758e55238bfe","x":175,"y":-178,"width":340,"height":250,"color":"6"}, + {"type":"text","text":"What's the best Italian dessert?","id":"7b37496e496da827","x":-137,"y":-359,"width":250,"height":60}, + {"type":"text","text":"How do you make it?","id":"aea9dcb543944bb1","x":-137,"y":-189,"width":250,"height":60}, + {"type":"text","text":"Give me a simpler recipe","id":"2f59408c2be9b7ae","x":-137,"y":12,"width":250,"height":60}, + {"type":"text","text":"","id":"ddb05069cb9f6f3e","x":113,"y":137,"width":390,"height":190,"color":"6"}, + {"type":"text","text":"Nodes can have multiple arrows coming out of them. They can carry information to different kinds of nodes.","id":"6d316338bfce7b20","x":28,"y":-580,"width":340,"height":100}, + {"type":"text","text":"Nf3","id":"248594446ba6eca2","x":-97,"y":691,"width":250,"height":60}, + {"type":"text","text":"Lets play chess. Here's my first move: e4","id":"891f6d7945759cd7","x":69,"y":500,"width":250,"height":60}, + {"type":"text","text":"Nc3","id":"5d4454ca8f7bdb3a","x":228,"y":691,"width":250,"height":60}, + {"type":"text","text":"","id":"3492caf4ead7f8cb","x":-107,"y":853,"width":260,"height":78,"color":"6"}, + {"type":"text","text":"","id":"9f9ba5852d437657","x":228,"y":853,"width":254,"height":78,"color":"6"}, + {"type":"text","text":"We can also use multiple outgoing arrows to create different branches of a chat","id":"5347076c683c8346","x":-392,"y":680,"width":255,"height":104} + ], + "edges":[ + {"id":"d8d4ab1340924892","fromNode":"2f59408c2be9b7ae","fromSide":"bottom","toNode":"ddb05069cb9f6f3e","toSide":"left"}, + {"id":"806865b0c75a6687","fromNode":"aea9dcb543944bb1","fromSide":"bottom","toNode":"2f59408c2be9b7ae","toSide":"top"}, + {"id":"44a20edc995a84d8","fromNode":"aea9dcb543944bb1","fromSide":"bottom","toNode":"c096758e55238bfe","toSide":"left"}, + {"id":"b59766f15e6812d8","fromNode":"7b37496e496da827","fromSide":"bottom","toNode":"aea9dcb543944bb1","toSide":"top"}, + {"id":"8fd655a2583e6f98","fromNode":"7b37496e496da827","fromSide":"bottom","toNode":"69ab78708b319e8d","toSide":"left"}, + {"id":"7d1bb4c2b5052c34","fromNode":"891f6d7945759cd7","fromSide":"bottom","toNode":"248594446ba6eca2","toSide":"top"}, + {"id":"bc0b97379618ae28","fromNode":"891f6d7945759cd7","fromSide":"bottom","toNode":"5d4454ca8f7bdb3a","toSide":"top"}, + {"id":"08fda0370caa615e","fromNode":"248594446ba6eca2","fromSide":"bottom","toNode":"3492caf4ead7f8cb","toSide":"top"}, + {"id":"e1a68493483394b4","fromNode":"5d4454ca8f7bdb3a","fromSide":"bottom","toNode":"9f9ba5852d437657","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/1. Basics/4. System messages.canvas b/assets/Cannoli College/1. Basics/4. System messages.canvas index 13f2efc..4162881 100644 --- a/assets/Cannoli College/1. Basics/4. System messages.canvas +++ b/assets/Cannoli College/1. Basics/4. System messages.canvas @@ -1 +1,22 @@ -{"nodes":[{"type":"group","id":"9a74aa8d0afdb942","x":-334,"y":-395,"width":669,"height":790,"label":"System Messages"},{"type":"text","text":"You are a silly goofy guy","id":"d005ba1be8656e6e","x":-314,"y":-205,"width":250,"height":60,"color":"6"},{"type":"text","text":"Hey what's a fun outing","id":"2c1e68fdaf20b936","x":-314,"y":-25,"width":250,"height":60},{"type":"text","text":"","id":"606e8b604062817a","x":-314,"y":111,"width":250,"height":154,"color":"6"},{"type":"text","text":"","id":"d0edacf3895cacc4","x":65,"y":-95,"width":250,"height":155,"color":"6"},{"type":"text","text":"Respond with a description of a very confused AI assistant that can't keep it together. Nothing else should be in your response. It should start with: \"you are a...\"","id":"59b7fc9dda9a50c1","x":65,"y":-375,"width":250,"height":232},{"type":"text","text":"This call node will include the above content node text as a system message.","id":"4b95de6b15e52400","x":-620,"y":-45,"width":260,"height":125},{"type":"text","text":"Here we're using a call node to generate a system message.","id":"9f14bc97186eabc0","x":360,"y":-143,"width":260,"height":98},{"type":"text","text":"Who invented mail?","id":"b8465e3c0926341e","x":65,"y":111,"width":250,"height":60},{"type":"text","text":"Blank arrows going from content nodes to call nodes will pass their content as a system message. System messages are used to give instructions on how the LLM should respond to user messages.","id":"225fa9e654db31d6","x":-189,"y":-620,"width":414,"height":157},{"type":"text","text":"","id":"661a61495dfeaf24","x":65,"y":218,"width":250,"height":157,"color":"6"}],"edges":[{"id":"4cfad5a8ec2be98f","fromNode":"d005ba1be8656e6e","fromSide":"bottom","toNode":"2c1e68fdaf20b936","toSide":"top"},{"id":"2a357972e7682b3d","fromNode":"2c1e68fdaf20b936","fromSide":"bottom","toNode":"606e8b604062817a","toSide":"top"},{"id":"c19d63a0e7873549","fromNode":"d0edacf3895cacc4","fromSide":"bottom","toNode":"b8465e3c0926341e","toSide":"top"},{"id":"04fc452e98f4b80f","fromNode":"59b7fc9dda9a50c1","fromSide":"bottom","toNode":"d0edacf3895cacc4","toSide":"top"},{"id":"ff5fd1f32d515a9f","fromNode":"b8465e3c0926341e","fromSide":"bottom","toNode":"661a61495dfeaf24","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"9a74aa8d0afdb942","x":-334,"y":-395,"width":669,"height":790,"label":"System Messages"}, + {"type":"text","text":"You are a silly goofy guy","id":"d005ba1be8656e6e","x":-314,"y":-205,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"Hey what's a fun outing","id":"2c1e68fdaf20b936","x":-314,"y":-25,"width":250,"height":60}, + {"type":"text","text":"","id":"606e8b604062817a","x":-314,"y":111,"width":250,"height":154,"color":"6"}, + {"type":"text","text":"","id":"d0edacf3895cacc4","x":65,"y":-95,"width":250,"height":155,"color":"6"}, + {"type":"text","text":"Respond with a description of a very confused AI assistant that can't keep it together. Nothing else should be in your response. It should start with: \"you are a...\"","id":"59b7fc9dda9a50c1","x":65,"y":-375,"width":250,"height":232}, + {"type":"text","text":"This call node will include the above content node text as a system message.","id":"4b95de6b15e52400","x":-620,"y":-45,"width":260,"height":125}, + {"type":"text","text":"Here we're using a call node to generate a system message.","id":"9f14bc97186eabc0","x":360,"y":-143,"width":260,"height":98}, + {"type":"text","text":"Who invented mail?","id":"b8465e3c0926341e","x":65,"y":111,"width":250,"height":60}, + {"type":"text","text":"Blank arrows going from content nodes to call nodes will pass their content as a system message. System messages are used to give instructions on how the LLM should respond to user messages.","id":"225fa9e654db31d6","x":-189,"y":-620,"width":414,"height":157}, + {"type":"text","text":"","id":"661a61495dfeaf24","x":65,"y":218,"width":250,"height":157,"color":"6"} + ], + "edges":[ + {"id":"4cfad5a8ec2be98f","fromNode":"d005ba1be8656e6e","fromSide":"bottom","toNode":"2c1e68fdaf20b936","toSide":"top"}, + {"id":"2a357972e7682b3d","fromNode":"2c1e68fdaf20b936","fromSide":"bottom","toNode":"606e8b604062817a","toSide":"top"}, + {"id":"c19d63a0e7873549","fromNode":"d0edacf3895cacc4","fromSide":"bottom","toNode":"b8465e3c0926341e","toSide":"top"}, + {"id":"04fc452e98f4b80f","fromNode":"59b7fc9dda9a50c1","fromSide":"bottom","toNode":"d0edacf3895cacc4","toSide":"top"}, + {"id":"ff5fd1f32d515a9f","fromNode":"b8465e3c0926341e","fromSide":"bottom","toNode":"661a61495dfeaf24","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/1. Basics/5. Variable arrows.canvas b/assets/Cannoli College/1. Basics/5. Variable arrows.canvas index 08f85c7..0dcb896 100644 --- a/assets/Cannoli College/1. Basics/5. Variable arrows.canvas +++ b/assets/Cannoli College/1. Basics/5. Variable arrows.canvas @@ -1 +1,36 @@ -{"nodes":[{"type":"group","id":"4dd63eded63256f2","x":-172,"y":240,"width":665,"height":460,"label":"Multiple variables"},{"type":"group","id":"d83444fe5b49fb2c","x":-160,"y":800,"width":653,"height":463,"label":"Between call nodes"},{"type":"group","id":"c409a28317a5ae26","x":11,"y":-360,"width":294,"height":510,"label":"Variables"},{"type":"text","text":"Pannetone","id":"0d48f7722e5db52e","x":31,"y":-340,"width":250,"height":60,"color":"6"},{"type":"text","text":"The label of the arrow names the variable, and you can inject it into a call node using the format \"{{variable name}}\"","id":"1a3b5db348375dba","x":-380,"y":-199,"width":371,"height":119},{"type":"text","text":"How do you make {{dessert}}?","id":"10cedae5ccf81664","x":31,"y":-180,"width":250,"height":60},{"type":"text","text":"","id":"5cf958d72a55d52d","x":32,"y":-24,"width":250,"height":154,"color":"6"},{"type":"text","text":"Labeling an arrow makes it a variable you can access in call nodes.","id":"db8924f8ddaaa08e","x":-13,"y":-520,"width":330,"height":86},{"type":"text","text":"Hannibal","id":"b2aa8b695a7b7774","x":-152,"y":260,"width":250,"height":60,"color":"6"},{"type":"text","text":"Elephants","id":"c23271f22630c4a9","x":223,"y":260,"width":250,"height":60,"color":"6"},{"type":"text","text":"What connects {{a}} and {{b}}?","id":"4f84654825f9df4c","x":34,"y":420,"width":293,"height":75},{"type":"text","text":"You can name and inject the output of call nodes the same way.","id":"835c4e523796df6e","x":-500,"y":915,"width":320,"height":80},{"type":"text","text":"Rate this limerick:\n{{limerick}}","id":"25d842fe884f4e78","x":-140,"y":995,"width":250,"height":60},{"type":"text","text":"Respond with a limerick about Cannolis","id":"1714bc9f52099a91","x":-140,"y":820,"width":250,"height":60},{"type":"text","text":"","id":"84fb2c8243704c1a","x":55,"y":550,"width":250,"height":130,"color":"6"},{"type":"text","text":"","id":"13cde1cb12272304","x":-140,"y":1110,"width":250,"height":133,"color":"6"},{"type":"text","text":"Are you sure its {{city}}?","id":"fe8260fd047fe01a","x":192,"y":996,"width":250,"height":60},{"type":"text","text":"","id":"26d4da45eb95d333","x":192,"y":1110,"width":250,"height":133,"color":"6"},{"type":"text","text":"What's the capital of Italy?","id":"44d0ee25c2f23e66","x":192,"y":820,"width":250,"height":60},{"type":"text","text":"Multiple arrows going into a call node can be used to inject multiple variables.","id":"0fd0a4b39c942f0b","x":-426,"y":399,"width":246,"height":117},{"type":"text","text":"Labeled basic arrows between call nodes will not pass along the chat history by default, only the content of the response.\n\nYou can override this by adding a \"|\" symbol at the end of the arrow label like so. Then you can continue a conversation as well as use a variable.","id":"1fadbba4649fa725","x":520,"y":955,"width":380,"height":245}],"edges":[{"id":"139dad9317421572","fromNode":"0d48f7722e5db52e","fromSide":"bottom","toNode":"10cedae5ccf81664","toSide":"top","label":"dessert"},{"id":"fa1b26557addc3e5","fromNode":"b2aa8b695a7b7774","fromSide":"bottom","toNode":"4f84654825f9df4c","toSide":"top","label":"a"},{"id":"ece89fb689451485","fromNode":"c23271f22630c4a9","fromSide":"bottom","toNode":"4f84654825f9df4c","toSide":"top","label":"b"},{"id":"b9eadfcbf2c54fe1","fromNode":"10cedae5ccf81664","fromSide":"bottom","toNode":"5cf958d72a55d52d","toSide":"top"},{"id":"3a41dc5849268edf","fromNode":"4f84654825f9df4c","fromSide":"bottom","toNode":"84fb2c8243704c1a","toSide":"top"},{"id":"7cf5bbc070866504","fromNode":"25d842fe884f4e78","fromSide":"bottom","toNode":"13cde1cb12272304","toSide":"top"},{"id":"3b347865a761d32b","fromNode":"1714bc9f52099a91","fromSide":"bottom","toNode":"25d842fe884f4e78","toSide":"top","label":"limerick"},{"id":"f93a6b2b699a1bf6","fromNode":"44d0ee25c2f23e66","fromSide":"bottom","toNode":"fe8260fd047fe01a","toSide":"top","label":"city|"},{"id":"0fa4378c8752aca4","fromNode":"fe8260fd047fe01a","fromSide":"bottom","toNode":"26d4da45eb95d333","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"4dd63eded63256f2","x":-172,"y":240,"width":665,"height":460,"label":"Multiple variables"}, + {"type":"group","id":"d83444fe5b49fb2c","x":-160,"y":800,"width":653,"height":463,"label":"Between call nodes"}, + {"type":"group","id":"c409a28317a5ae26","x":11,"y":-360,"width":294,"height":510,"label":"Variables"}, + {"type":"text","text":"Pannetone","id":"0d48f7722e5db52e","x":31,"y":-340,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"The label of the arrow names the variable, and you can inject it into a call node using the format \"{{variable name}}\"","id":"1a3b5db348375dba","x":-380,"y":-199,"width":371,"height":119}, + {"type":"text","text":"How do you make {{dessert}}?","id":"10cedae5ccf81664","x":31,"y":-180,"width":250,"height":60}, + {"type":"text","text":"","id":"5cf958d72a55d52d","x":32,"y":-24,"width":250,"height":154,"color":"6"}, + {"type":"text","text":"Labeling an arrow makes it a variable you can access in call nodes.","id":"db8924f8ddaaa08e","x":-13,"y":-520,"width":330,"height":86}, + {"type":"text","text":"Hannibal","id":"b2aa8b695a7b7774","x":-152,"y":260,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"Elephants","id":"c23271f22630c4a9","x":223,"y":260,"width":250,"height":60,"color":"6"}, + {"type":"text","text":"What connects {{a}} and {{b}}?","id":"4f84654825f9df4c","x":34,"y":420,"width":293,"height":75}, + {"type":"text","text":"You can name and inject the output of call nodes the same way.","id":"835c4e523796df6e","x":-500,"y":915,"width":320,"height":80}, + {"type":"text","text":"Rate this limerick:\n{{limerick}}","id":"25d842fe884f4e78","x":-140,"y":995,"width":250,"height":60}, + {"type":"text","text":"Respond with a limerick about Cannolis","id":"1714bc9f52099a91","x":-140,"y":820,"width":250,"height":60}, + {"type":"text","text":"","id":"84fb2c8243704c1a","x":55,"y":550,"width":250,"height":130,"color":"6"}, + {"type":"text","text":"","id":"13cde1cb12272304","x":-140,"y":1110,"width":250,"height":133,"color":"6"}, + {"type":"text","text":"Are you sure its {{city}}?","id":"fe8260fd047fe01a","x":192,"y":996,"width":250,"height":60}, + {"type":"text","text":"","id":"26d4da45eb95d333","x":192,"y":1110,"width":250,"height":133,"color":"6"}, + {"type":"text","text":"What's the capital of Italy?","id":"44d0ee25c2f23e66","x":192,"y":820,"width":250,"height":60}, + {"type":"text","text":"Multiple arrows going into a call node can be used to inject multiple variables.","id":"0fd0a4b39c942f0b","x":-426,"y":399,"width":246,"height":117}, + {"type":"text","text":"Labeled basic arrows between call nodes will not pass along the chat history by default, only the content of the response.\n\nYou can override this by adding a \"|\" symbol at the end of the arrow label like so. Then you can continue a conversation as well as use a variable.","id":"1fadbba4649fa725","x":520,"y":955,"width":380,"height":245} + ], + "edges":[ + {"id":"139dad9317421572","fromNode":"0d48f7722e5db52e","fromSide":"bottom","toNode":"10cedae5ccf81664","toSide":"top","label":"dessert"}, + {"id":"fa1b26557addc3e5","fromNode":"b2aa8b695a7b7774","fromSide":"bottom","toNode":"4f84654825f9df4c","toSide":"top","label":"a"}, + {"id":"ece89fb689451485","fromNode":"c23271f22630c4a9","fromSide":"bottom","toNode":"4f84654825f9df4c","toSide":"top","label":"b"}, + {"id":"b9eadfcbf2c54fe1","fromNode":"10cedae5ccf81664","fromSide":"bottom","toNode":"5cf958d72a55d52d","toSide":"top"}, + {"id":"3a41dc5849268edf","fromNode":"4f84654825f9df4c","fromSide":"bottom","toNode":"84fb2c8243704c1a","toSide":"top"}, + {"id":"7cf5bbc070866504","fromNode":"25d842fe884f4e78","fromSide":"bottom","toNode":"13cde1cb12272304","toSide":"top"}, + {"id":"3b347865a761d32b","fromNode":"1714bc9f52099a91","fromSide":"bottom","toNode":"25d842fe884f4e78","toSide":"top","label":"limerick"}, + {"id":"f93a6b2b699a1bf6","fromNode":"44d0ee25c2f23e66","fromSide":"bottom","toNode":"fe8260fd047fe01a","toSide":"top","label":"city|"}, + {"id":"0fa4378c8752aca4","fromNode":"fe8260fd047fe01a","fromSide":"bottom","toNode":"26d4da45eb95d333","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/2. Special arrows/2. Field arrows.canvas b/assets/Cannoli College/2. Special arrows/3. Field arrows.canvas similarity index 100% rename from assets/Cannoli College/2. Special arrows/2. Field arrows.canvas rename to assets/Cannoli College/2. Special arrows/3. Field arrows.canvas diff --git a/assets/Cannoli College/2. Special arrows/3. Choice arrows.canvas b/assets/Cannoli College/2. Special arrows/4. Choice arrows.canvas similarity index 100% rename from assets/Cannoli College/2. Special arrows/3. Choice arrows.canvas rename to assets/Cannoli College/2. Special arrows/4. Choice arrows.canvas diff --git a/assets/Cannoli College/2. Special arrows/4. Chat arrows.cno.canvas b/assets/Cannoli College/2. Special arrows/5. Chat arrows.cno.canvas similarity index 100% rename from assets/Cannoli College/2. Special arrows/4. Chat arrows.cno.canvas rename to assets/Cannoli College/2. Special arrows/5. Chat arrows.cno.canvas diff --git a/assets/Cannoli College/4. Vault interaction/3. Dynamic note references.canvas b/assets/Cannoli College/4. Vault interaction/3. Dynamic note references.canvas index 23af5b8..04dc568 100644 --- a/assets/Cannoli College/4. Vault interaction/3. Dynamic note references.canvas +++ b/assets/Cannoli College/4. Vault interaction/3. Dynamic note references.canvas @@ -1 +1,36 @@ -{"nodes":[{"type":"group","id":"3884a37115998334","x":-200,"y":1160,"width":520,"height":760,"label":"Dynamic reference nodes"},{"type":"group","id":"1d4638cc848ce883","x":-160,"y":460,"width":460,"height":575,"label":"Ensuring proper note names"},{"type":"group","id":"190c7fe39136a4e6","x":-175,"y":-400,"width":321,"height":575,"label":"Note names as variables"},{"type":"text","text":"What's this about:\n{{@note}}","id":"4e5095e59d3b1f75","x":-140,"y":-100,"width":250,"height":58},{"type":"text","text":"","id":"78a31a6b0db6e00a","x":-155,"y":40,"width":281,"height":115,"color":"6"},{"type":"text","text":"An \"@\" symbol in front of a variable reference will have the node attempt to extract the content of the note with that name.","id":"8dc52a792fef349a","x":-460,"y":-146,"width":275,"height":150},{"type":"text","text":"Respond with the name of one of these notes without square brackets:\n[[Apple Trees]],\n[[Lemons for Cleaning]]","id":"71fc4d9bcf7e5cef","x":-140,"y":-380,"width":250,"height":160},{"type":"text","text":"In addition to statically referencing notes, you can have the LLM generate note names that you expect to be valid, and reference them in prompts.","id":"aa35fa7b42662498","x":-220,"y":-580,"width":387,"height":120},{"type":"text","text":"Respond with the name of one of these notes:\n[[Apple Trees]],\n[[Lemons for Cleaning]]","id":"a563177e81b5c95e","x":-125,"y":480,"width":250,"height":140},{"type":"text","text":"The square bracket signifies that you'd like the LLM to respond with a note name, and Cannoli uses function calling to ensure that the response is only one of the note names present in the prompt.","id":"e2632c0409b0c31e","x":-500,"y":581,"width":335,"height":179},{"type":"text","text":"","id":"39b8926cc93a3400","x":-140,"y":860,"width":281,"height":155,"color":"6"},{"type":"text","text":"You can use this to build Cannolis that interact with your vault in dynamic ways, navigating through it using links.","id":"8c08925cfa290c8a","x":-508,"y":818,"width":343,"height":127},{"type":"text","text":"The same format can also be used for reference nodes.","id":"ff34fc6b7a9db4a4","x":-540,"y":1281,"width":335,"height":79},{"type":"text","text":"In this example, the LLM chooses a note and writes to it.","id":"c185a020e676b84a","x":-548,"y":1500,"width":343,"height":82},{"type":"text","text":"","id":"65d38a62ff03dbfe","x":110,"y":671,"width":175,"height":60,"color":"6"},{"type":"text","text":"Write an article with that title.","id":"d192686ddf19160b","x":40,"y":1430,"width":250,"height":60},{"type":"text","text":"Respond with the name of one of these notes:\n[[Apple Trees]],\n[[Lemons for Cleaning]]","id":"6b6b4b634889aad8","x":-165,"y":1180,"width":250,"height":140},{"type":"text","text":"{{@note}}","id":"8a0e100e00bdcaea","x":-165,"y":1582,"width":250,"height":58,"color":"6"},{"type":"text","text":"What's this about:\n{{@note}}","id":"0db897a7e991783c","x":-125,"y":760,"width":250,"height":58},{"type":"text","text":"","id":"1394a8cbb5db72d9","x":-165,"y":1720,"width":455,"height":180,"color":"6"},{"type":"text","text":"Getting the LLM to properly name notes can be a challenge. You can ensure the response is a valid note name the LLM has seen by using a single square bracket prefix on an arrow label.","id":"8b52c0b7a2e3aa8a","x":-220,"y":240,"width":442,"height":141}],"edges":[{"id":"f0ecaa4ebe5d824b","fromNode":"71fc4d9bcf7e5cef","fromSide":"bottom","toNode":"4e5095e59d3b1f75","toSide":"top","label":"note"},{"id":"303a7695b62bb265","fromNode":"4e5095e59d3b1f75","fromSide":"bottom","toNode":"78a31a6b0db6e00a","toSide":"top","color":"2"},{"id":"cb401d73afd6b5b0","fromNode":"a563177e81b5c95e","fromSide":"bottom","toNode":"0db897a7e991783c","toSide":"top","label":"[note"},{"id":"87145bcd5b0ef58a","fromNode":"0db897a7e991783c","fromSide":"bottom","toNode":"39b8926cc93a3400","toSide":"top","color":"2"},{"id":"d7621f4a15b0b7fb","fromNode":"6b6b4b634889aad8","fromSide":"bottom","toNode":"8a0e100e00bdcaea","toSide":"top","label":"[note"},{"id":"8748f38aca7e3e66","fromNode":"6b6b4b634889aad8","fromSide":"bottom","toNode":"d192686ddf19160b","toSide":"top"},{"id":"6b0d63d0cc50d49a","fromNode":"d192686ddf19160b","fromSide":"bottom","toNode":"8a0e100e00bdcaea","toSide":"top"},{"id":"b2e6acd4ac04fdb5","fromNode":"a563177e81b5c95e","fromSide":"right","toNode":"65d38a62ff03dbfe","toSide":"top","label":"[note"},{"id":"3cbecc9da0226b67","fromNode":"8a0e100e00bdcaea","fromSide":"bottom","toNode":"1394a8cbb5db72d9","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"3884a37115998334","x":-200,"y":1160,"width":520,"height":760,"label":"Dynamic reference nodes"}, + {"type":"group","id":"1d4638cc848ce883","x":-160,"y":460,"width":460,"height":575,"label":"Ensuring proper note names"}, + {"type":"group","id":"190c7fe39136a4e6","x":-175,"y":-400,"width":321,"height":575,"label":"Note names as variables"}, + {"type":"text","text":"What's this about:\n{{@note}}","id":"4e5095e59d3b1f75","x":-140,"y":-100,"width":250,"height":58}, + {"type":"text","text":"","id":"78a31a6b0db6e00a","x":-155,"y":40,"width":281,"height":115,"color":"6"}, + {"type":"text","text":"An \"@\" symbol in front of a variable reference will have the node attempt to extract the content of the note with that name.","id":"8dc52a792fef349a","x":-460,"y":-146,"width":275,"height":150}, + {"type":"text","text":"Respond with the name of one of these notes without square brackets:\n[[Apple Trees]],\n[[Lemons for Cleaning]]","id":"71fc4d9bcf7e5cef","x":-140,"y":-380,"width":250,"height":160}, + {"type":"text","text":"In addition to statically referencing notes, you can have the LLM generate note names that you expect to be valid, and reference them in prompts.","id":"aa35fa7b42662498","x":-220,"y":-580,"width":387,"height":120}, + {"type":"text","text":"Respond with the name of one of these notes:\n[[Apple Trees]],\n[[Lemons for Cleaning]]","id":"a563177e81b5c95e","x":-125,"y":480,"width":250,"height":140}, + {"type":"text","text":"The square bracket signifies that you'd like the LLM to respond with a note name, and Cannoli uses function calling to ensure that the response is only one of the note names present in the prompt.","id":"e2632c0409b0c31e","x":-500,"y":581,"width":335,"height":179}, + {"type":"text","text":"","id":"39b8926cc93a3400","x":-140,"y":860,"width":281,"height":155,"color":"6"}, + {"type":"text","text":"You can use this to build Cannolis that interact with your vault in dynamic ways, navigating through it using links.","id":"8c08925cfa290c8a","x":-508,"y":818,"width":343,"height":127}, + {"type":"text","text":"The same format can also be used for reference nodes.","id":"ff34fc6b7a9db4a4","x":-540,"y":1281,"width":335,"height":79}, + {"type":"text","text":"In this example, the LLM chooses a note and writes to it.","id":"c185a020e676b84a","x":-548,"y":1500,"width":343,"height":82}, + {"type":"text","text":"","id":"65d38a62ff03dbfe","x":110,"y":671,"width":175,"height":60,"color":"6"}, + {"type":"text","text":"Write an article with that title.","id":"d192686ddf19160b","x":40,"y":1430,"width":250,"height":60}, + {"type":"text","text":"Respond with the name of one of these notes:\n[[Apple Trees]],\n[[Lemons for Cleaning]]","id":"6b6b4b634889aad8","x":-165,"y":1180,"width":250,"height":140}, + {"type":"text","text":"{{@note}}","id":"8a0e100e00bdcaea","x":-165,"y":1582,"width":250,"height":58,"color":"6"}, + {"type":"text","text":"What's this about:\n{{@note}}","id":"0db897a7e991783c","x":-125,"y":760,"width":250,"height":58}, + {"type":"text","text":"","id":"1394a8cbb5db72d9","x":-165,"y":1720,"width":455,"height":180,"color":"6"}, + {"type":"text","text":"Getting the LLM to properly name notes can be a challenge. You can ensure the response is a valid note name the LLM has seen by using a single square bracket prefix on an arrow label.","id":"8b52c0b7a2e3aa8a","x":-220,"y":240,"width":442,"height":141} + ], + "edges":[ + {"id":"f0ecaa4ebe5d824b","fromNode":"71fc4d9bcf7e5cef","fromSide":"bottom","toNode":"4e5095e59d3b1f75","toSide":"top","label":"note"}, + {"id":"303a7695b62bb265","fromNode":"4e5095e59d3b1f75","fromSide":"bottom","toNode":"78a31a6b0db6e00a","toSide":"top","color":"2"}, + {"id":"cb401d73afd6b5b0","fromNode":"a563177e81b5c95e","fromSide":"bottom","toNode":"0db897a7e991783c","toSide":"top","label":"[note"}, + {"id":"87145bcd5b0ef58a","fromNode":"0db897a7e991783c","fromSide":"bottom","toNode":"39b8926cc93a3400","toSide":"top","color":"2"}, + {"id":"d7621f4a15b0b7fb","fromNode":"6b6b4b634889aad8","fromSide":"bottom","toNode":"8a0e100e00bdcaea","toSide":"top","label":"[note"}, + {"id":"8748f38aca7e3e66","fromNode":"6b6b4b634889aad8","fromSide":"bottom","toNode":"d192686ddf19160b","toSide":"top"}, + {"id":"6b0d63d0cc50d49a","fromNode":"d192686ddf19160b","fromSide":"bottom","toNode":"8a0e100e00bdcaea","toSide":"top"}, + {"id":"b2e6acd4ac04fdb5","fromNode":"a563177e81b5c95e","fromSide":"right","toNode":"65d38a62ff03dbfe","toSide":"top","label":"[note"}, + {"id":"3cbecc9da0226b67","fromNode":"8a0e100e00bdcaea","fromSide":"bottom","toNode":"1394a8cbb5db72d9","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/4. Vault interaction/5. Referencing selections.canvas b/assets/Cannoli College/4. Vault interaction/5. Referencing selections.canvas index 0e02f57..4cfcee6 100644 --- a/assets/Cannoli College/4. Vault interaction/5. Referencing selections.canvas +++ b/assets/Cannoli College/4. Vault interaction/5. Referencing selections.canvas @@ -1 +1,18 @@ -{"nodes":[{"id":"8c02946171040e71","type":"group","x":30,"y":-145,"width":350,"height":345,"label":"Special \"SELECTION\" variable"},{"id":"a0047756f6bf199f","type":"group","x":30,"y":280,"width":350,"height":320,"label":"Replacing selections"},{"id":"28278bc5135af80c","type":"text","text":"Respond with a more concise version of this text:\n{{SELECTION}}","x":75,"y":-125,"width":250,"height":120},{"id":"9b5312d8361c2f5e","type":"text","text":"","x":75,"y":40,"width":250,"height":130,"color":"6"},{"id":"6f34b064907441fd","type":"text","text":"This works in any workspace where you can select text, including canvas files.\n\nTry it on the sentence above.","x":-313,"y":-100,"width":324,"height":140},{"id":"21dc5d31fab5298f","type":"text","text":"You can reference the current selection (the text highlighted by your cursor when you started the cannoli) using the {{SELECTION}} variable","x":11,"y":-360,"width":378,"height":142},{"id":"2deb4b62d41bbfb7","type":"text","text":"Respond with a more concise version of this text:\n{{SELECTION}}","x":75,"y":300,"width":250,"height":120},{"id":"6e8591393bf5e285","type":"text","text":"You can write to a selection reference node just like a Note reference node. \n\nWriting to a {{SELECTION}} node will replace the text if there is a selection, or insert it at the cursor if there isn't.","x":-340,"y":325,"width":351,"height":175},{"id":"880831fc3c8b5e93","type":"text","text":"{{SELECTION}}","x":75,"y":500,"width":250,"height":60,"color":"6"},{"id":"c940877ff5ddd66f","type":"text","text":"Note that if you click away from a selection before the cannoli reaches this node, it will change where the replacement happens, so be wary of long cannolis that use this feature.","x":389,"y":346,"width":404,"height":133}],"edges":[{"id":"ff57adf1f2f08d4d","fromNode":"28278bc5135af80c","fromSide":"bottom","toNode":"9b5312d8361c2f5e","toSide":"top"},{"id":"e6c1d0371468967e","fromNode":"2deb4b62d41bbfb7","fromSide":"bottom","toNode":"880831fc3c8b5e93","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"id":"8c02946171040e71","type":"group","x":30,"y":-145,"width":350,"height":345,"label":"Special \"SELECTION\" variable"}, + {"id":"a0047756f6bf199f","type":"group","x":30,"y":280,"width":350,"height":320,"label":"Replacing selections"}, + {"id":"28278bc5135af80c","type":"text","text":"Respond with a more concise version of this text:\n{{SELECTION}}","x":75,"y":-125,"width":250,"height":120}, + {"id":"9b5312d8361c2f5e","type":"text","text":"","x":75,"y":40,"width":250,"height":130,"color":"6"}, + {"id":"6f34b064907441fd","type":"text","text":"This works in any workspace where you can select text, including canvas files.\n\nTry it on the sentence above.","x":-313,"y":-100,"width":324,"height":140}, + {"id":"21dc5d31fab5298f","type":"text","text":"You can reference the current selection (the text highlighted by your cursor when you started the cannoli) using the {{SELECTION}} variable","x":11,"y":-360,"width":378,"height":142}, + {"id":"2deb4b62d41bbfb7","type":"text","text":"Respond with a more concise version of this text:\n{{SELECTION}}","x":75,"y":300,"width":250,"height":120}, + {"id":"6e8591393bf5e285","type":"text","text":"You can write to a selection reference node just like a Note reference node. \n\nWriting to a {{SELECTION}} node will replace the text if there is a selection, or insert it at the cursor if there isn't.","x":-340,"y":325,"width":351,"height":175}, + {"id":"880831fc3c8b5e93","type":"text","text":"{{SELECTION}}","x":75,"y":500,"width":250,"height":60,"color":"6"}, + {"id":"c940877ff5ddd66f","type":"text","text":"Note that if you click away from a selection before the cannoli reaches this node, it will change where the replacement happens, so be wary of long cannolis that use this feature.","x":389,"y":346,"width":404,"height":133} + ], + "edges":[ + {"id":"ff57adf1f2f08d4d","fromNode":"28278bc5135af80c","fromSide":"bottom","toNode":"9b5312d8361c2f5e","toSide":"top"}, + {"id":"e6c1d0371468967e","fromNode":"2deb4b62d41bbfb7","fromSide":"bottom","toNode":"880831fc3c8b5e93","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/4. Vault interaction/6. Dataview.canvas b/assets/Cannoli College/4. Vault interaction/6. Dataview.canvas new file mode 100644 index 0000000..63feed5 --- /dev/null +++ b/assets/Cannoli College/4. Vault interaction/6. Dataview.canvas @@ -0,0 +1,32 @@ +{ + "nodes":[ + {"id":"abdd7f206ec179b5","type":"group","x":-292,"y":2360,"width":926,"height":786,"label":"Selecting notes from Dataview queries"}, + {"id":"866cf47b85828224","type":"group","x":-280,"y":200,"width":901,"height":800,"label":"Dataview Queries"}, + {"id":"54821284bfffa404","type":"group","x":-280,"y":1240,"width":901,"height":800,"label":"Embedding notes with Dataview"}, + {"id":"d496337fb835112d","type":"text","text":"Here is a dataview query:\n```dataview\nLIST\nFROM #cannoliArticle\n```\nWhat do you think are inside these notes?","x":-237,"y":220,"width":339,"height":246}, + {"id":"0a4607692e99ccc4","type":"text","text":"Tell me about this table\n\n```dataview\nTABLE file.name,file.ctime\nFROM #cannoliArticle\n```","x":207,"y":220,"width":390,"height":255}, + {"id":"2a540f6685096f40","type":"text","text":"","x":-260,"y":560,"width":385,"height":420,"color":"6"}, + {"id":"4991b1a604f5b0c0","type":"text","text":"","x":203,"y":560,"width":398,"height":420,"color":"6"}, + {"id":"86b5e262c31686a5","type":"text","text":"Read these notes and write a haiku about each one:\n\n{{\n```dataview\nLIST\nFROM #cannoliArticle\n```\n}}","x":-237,"y":1260,"width":339,"height":280}, + {"id":"e00b70c20e8b5de4","type":"text","text":"Read these notes and write a haiku about each one:\n\n{{\n```dataview\nLIST\nFROM #cannoliArticle\n```\n!#}}","x":207,"y":1260,"width":390,"height":280}, + {"id":"af6026eb8c26d15b","type":"text","text":"Sometimes you want the LLM to see the contents of all of the resulting links of a dataview query. To do that you can simply wrap the query in double curly brackets the way you would with a note embed. This looks better with lists than with tables.","x":-160,"y":1080,"width":680,"height":108}, + {"id":"025b43bd8ffaa90d","type":"text","text":"Cannoli renders Dataview DQL queries so the LLM can see them. \n\nIf you have the Dataview plugin enabled on a vault, and there's a valid query inside of a node or embedded note, the LLM will see the results of that query as a Markdown list or table.\n\nDataviewJS queries are not implemented yet, but we're still working to get that in as well. (p.s. if you're reading this and have arcane dataview knowledge that might help please reach out on the repo)","x":-131,"y":-120,"width":623,"height":257}, + {"id":"9c168db7948ae50a","type":"text","text":"","x":-260,"y":1600,"width":385,"height":420,"color":"6"}, + {"id":"5fdb171ce82f69ef","type":"text","text":"","x":203,"y":1600,"width":398,"height":420,"color":"6"}, + {"id":"ffbe198b39af63cb","type":"text","text":"You can use the same syntax for including or excluding note titles and properties as you can in normal note embeds. (see [[1. Referencing notes.canvas|1. Referencing notes]])","x":660,"y":1340,"width":440,"height":120}, + {"id":"cdfbde60f7de0699","type":"text","text":"Which of these notes looks most interesting:\n\n```dataview\nLIST\nFROM #cannoliArticle\n```","x":-272,"y":2380,"width":339,"height":280}, + {"id":"e05c95af482766e8","type":"text","text":"","x":195,"y":2490,"width":385,"height":516,"color":"6"}, + {"id":"522c7968323ab01f","type":"text","text":"","x":-228,"y":2946,"width":398,"height":160,"color":"6"}, + {"id":"480170f0f0cf1c3d","type":"text","text":"Do you find this note interesting?\n\n{{@mostInteresting}}","x":-228,"y":2748,"width":250,"height":130}, + {"id":"fe2b51ed55928420","type":"text","text":"You can also use the note selection syntax on arrows leaving call nodes to get the LLM to output a selection from the links it sees.\n\nFor more on this see [[3. Dynamic note references.canvas|3. Dynamic note references]]","x":-62,"y":2120,"width":503,"height":160} + ], + "edges":[ + {"id":"2ebd28fb6c5c101d","fromNode":"d496337fb835112d","fromSide":"bottom","toNode":"2a540f6685096f40","toSide":"top","color":"2"}, + {"id":"8ee71d334a61b7db","fromNode":"0a4607692e99ccc4","fromSide":"bottom","toNode":"4991b1a604f5b0c0","toSide":"top","color":"2"}, + {"id":"a9b3dffa5e282eac","fromNode":"86b5e262c31686a5","fromSide":"bottom","toNode":"9c168db7948ae50a","toSide":"top","color":"2"}, + {"id":"a7d1263d7926e2df","fromNode":"e00b70c20e8b5de4","fromSide":"bottom","toNode":"5fdb171ce82f69ef","toSide":"top","color":"2"}, + {"id":"c66428ad3bf6bee0","fromNode":"480170f0f0cf1c3d","fromSide":"right","toNode":"e05c95af482766e8","toSide":"left","color":"2"}, + {"id":"dc0fdfc897e3f0d4","fromNode":"cdfbde60f7de0699","fromSide":"bottom","toNode":"480170f0f0cf1c3d","toSide":"top","label":"[mostInteresting"}, + {"id":"5c40358a63c8ae10","fromNode":"480170f0f0cf1c3d","fromSide":"bottom","toNode":"522c7968323ab01f","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/5. Groups/1. Basic groups.canvas b/assets/Cannoli College/5. Groups/1. Basic groups.canvas index 86ac61a..ff94e95 100644 --- a/assets/Cannoli College/5. Groups/1. Basic groups.canvas +++ b/assets/Cannoli College/5. Groups/1. Basic groups.canvas @@ -1 +1,27 @@ -{"nodes":[{"type":"group","id":"3507f53b8ef19875","x":-400,"y":-280,"width":610,"height":940,"label":"Basic Groups"},{"type":"group","id":"9ea4603066155724","x":-100,"y":-220,"width":290,"height":273,"label":"Group 1"},{"type":"group","id":"9d076987e99ce6a6","x":-100,"y":260,"width":290,"height":240,"label":"Group 2"},{"type":"text","text":"Hey what model are you?","id":"554b1577865f24d4","x":-80,"y":280,"width":250,"height":60},{"type":"text","text":"Actually you don't know that.","id":"35881fd57b1d4269","x":-80,"y":420,"width":250,"height":60},{"type":"text","text":"","id":"fd9b2131408190a4","x":-80,"y":520,"width":250,"height":120,"color":"6"},{"type":"text","text":"gpt-4","id":"e7d78cc1a7a948f8","x":-320,"y":250,"width":105,"height":60,"color":"6"},{"type":"text","text":"Rubiks cube","id":"e83b4c5b2409b738","x":-370,"y":-163,"width":180,"height":57,"color":"6"},{"type":"text","text":"Here we use a basic group to provide all of the member nodes with a variable.","id":"1354395dbba49c59","x":-700,"y":-163,"width":290,"height":93},{"type":"text","text":"Basic groups allow you to conveniently provide variables or change config settings of multiple nodes.\n\nFunctionally, its the same as drawing arrows to every node in the group.","id":"cb4e55a56aa20105","x":-320,"y":-500,"width":423,"height":170},{"type":"text","text":"Groups whose label is not an integer are basic groups.","id":"ad8c877c4bdbc784","x":-298,"y":-620,"width":380,"height":94},{"type":"text","text":"You can use {{a}} in this node","id":"3f724ea642f3f39d","x":-80,"y":-200,"width":250,"height":60},{"type":"text","text":"And you can use {{a}} in this node","id":"6b128a864045c0e7","x":-80,"y":-27,"width":250,"height":60},{"type":"text","text":"","id":"b6f9f0b26ae8e68e","x":-80,"y":80,"width":250,"height":100,"color":"6"},{"type":"text","text":"Here we change the model config setting of all the member nodes of a group.","id":"e58e6effa966f52b","x":-728,"y":242,"width":318,"height":98}],"edges":[{"id":"3986f98e5c79c58a","fromNode":"e83b4c5b2409b738","fromSide":"right","toNode":"9ea4603066155724","toSide":"left","label":"a"},{"id":"b54add99d36d3b53","fromNode":"e7d78cc1a7a948f8","fromSide":"right","toNode":"9d076987e99ce6a6","toSide":"left","color":"2","label":"model"},{"id":"3ec08b096671959f","fromNode":"3f724ea642f3f39d","fromSide":"bottom","toNode":"6b128a864045c0e7","toSide":"top"},{"id":"71449d8dc3ac9bac","fromNode":"6b128a864045c0e7","fromSide":"bottom","toNode":"b6f9f0b26ae8e68e","toSide":"top","color":"2"},{"id":"b2ca430257741d71","fromNode":"554b1577865f24d4","fromSide":"bottom","toNode":"35881fd57b1d4269","toSide":"top"},{"id":"948da6eeffd07b7e","fromNode":"35881fd57b1d4269","fromSide":"bottom","toNode":"fd9b2131408190a4","toSide":"top","color":"2"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"3507f53b8ef19875","x":-400,"y":-280,"width":610,"height":940,"label":"Basic Groups"}, + {"type":"group","id":"9ea4603066155724","x":-100,"y":-220,"width":290,"height":273,"label":"Group 1"}, + {"type":"group","id":"9d076987e99ce6a6","x":-100,"y":260,"width":290,"height":240,"label":"Group 2"}, + {"type":"text","text":"Hey what model are you?","id":"554b1577865f24d4","x":-80,"y":280,"width":250,"height":60}, + {"type":"text","text":"Actually you don't know that.","id":"35881fd57b1d4269","x":-80,"y":420,"width":250,"height":60}, + {"type":"text","text":"","id":"fd9b2131408190a4","x":-80,"y":520,"width":250,"height":120,"color":"6"}, + {"type":"text","text":"gpt-4","id":"e7d78cc1a7a948f8","x":-320,"y":250,"width":105,"height":60,"color":"6"}, + {"type":"text","text":"Rubiks cube","id":"e83b4c5b2409b738","x":-370,"y":-163,"width":180,"height":57,"color":"6"}, + {"type":"text","text":"Here we use a basic group to provide all of the member nodes with a variable.","id":"1354395dbba49c59","x":-700,"y":-163,"width":290,"height":93}, + {"type":"text","text":"Basic groups allow you to conveniently provide variables or change config settings of multiple nodes.\n\nFunctionally, its the same as drawing arrows to every node in the group.","id":"cb4e55a56aa20105","x":-320,"y":-500,"width":423,"height":170}, + {"type":"text","text":"Groups whose label is not an integer are basic groups.","id":"ad8c877c4bdbc784","x":-298,"y":-620,"width":380,"height":94}, + {"type":"text","text":"You can use {{a}} in this node","id":"3f724ea642f3f39d","x":-80,"y":-200,"width":250,"height":60}, + {"type":"text","text":"And you can use {{a}} in this node","id":"6b128a864045c0e7","x":-80,"y":-27,"width":250,"height":60}, + {"type":"text","text":"","id":"b6f9f0b26ae8e68e","x":-80,"y":80,"width":250,"height":100,"color":"6"}, + {"type":"text","text":"Here we change the model config setting of all the member nodes of a group.","id":"e58e6effa966f52b","x":-728,"y":242,"width":318,"height":98} + ], + "edges":[ + {"id":"3986f98e5c79c58a","fromNode":"e83b4c5b2409b738","fromSide":"right","toNode":"9ea4603066155724","toSide":"left","label":"a"}, + {"id":"b54add99d36d3b53","fromNode":"e7d78cc1a7a948f8","fromSide":"right","toNode":"9d076987e99ce6a6","toSide":"left","color":"2","label":"model"}, + {"id":"3ec08b096671959f","fromNode":"3f724ea642f3f39d","fromSide":"bottom","toNode":"6b128a864045c0e7","toSide":"top"}, + {"id":"71449d8dc3ac9bac","fromNode":"6b128a864045c0e7","fromSide":"bottom","toNode":"b6f9f0b26ae8e68e","toSide":"top","color":"2"}, + {"id":"b2ca430257741d71","fromNode":"554b1577865f24d4","fromSide":"bottom","toNode":"35881fd57b1d4269","toSide":"top"}, + {"id":"948da6eeffd07b7e","fromNode":"35881fd57b1d4269","fromSide":"bottom","toNode":"fd9b2131408190a4","toSide":"top","color":"2"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/5. Groups/2. Loop groups.canvas b/assets/Cannoli College/5. Groups/2. Loop groups.canvas index 7c069a5..69d9cf7 100644 --- a/assets/Cannoli College/5. Groups/2. Loop groups.canvas +++ b/assets/Cannoli College/5. Groups/2. Loop groups.canvas @@ -1 +1,39 @@ -{"nodes":[{"type":"group","id":"33e7457728f9ef47","x":-320,"y":-80,"width":820,"height":560,"label":"Nested loop groups"},{"type":"group","id":"0064c11720e6cf20","x":-320,"y":560,"width":820,"height":480,"label":"The loop number variable"},{"type":"group","id":"81cdef3b9de52df9","x":-200,"y":-880,"width":460,"height":680,"label":"Loop groups"},{"type":"group","id":"df42bd1da1866b7f","x":-300,"y":0,"width":330,"height":420,"label":"2"},{"type":"group","id":"2ae53ef6008eeb4e","x":-300,"y":640,"width":360,"height":360,"label":"2"},{"type":"group","id":"986991747df080b2","x":-115,"y":-720,"width":290,"height":260,"label":"3"},{"type":"group","id":"d83bf39a509c67bd","x":-280,"y":150,"width":280,"height":250,"label":"2"},{"type":"group","id":"76b98e9977f73412","x":-280,"y":790,"width":310,"height":190,"label":"2"},{"type":"text","text":"When all the nodes in a loop group are finished, all nodes will reset and the group will restart. \n\nIt will loop as many times as are defined in the label, and only the result of the final loop will be sent along the arrows leaving the group.","id":"6e5fbad373215bd8","x":-660,"y":-695,"width":441,"height":170},{"type":"text","text":"Loop groups are colorless groups that have a positive integer in their label.","id":"a408edeafd6bc62f","x":-169,"y":-1040,"width":399,"height":89},{"type":"text","text":"This message will be sent once","id":"2a9251ad533d8576","x":-95,"y":-860,"width":250,"height":60},{"type":"text","text":"This one will be sent 3 times","id":"896ace77fa0c6a7e","x":-95,"y":-700,"width":250,"height":60},{"type":"text","text":"Only the last response will be written to the content node outside the loop.","id":"c6b8d6a1f384022f","x":-95,"y":-610,"width":250,"height":120},{"type":"text","text":"","id":"96f3935e8174877f","x":-95,"y":-400,"width":250,"height":180,"color":"6"},{"type":"text","text":"Nested loop groups will fully reset, meaning in this case the inner group will repeat 4 times.","id":"24835b0cc486957f","x":-690,"y":64,"width":350,"height":106},{"type":"text","text":"This message will be sent 2 times","id":"d09815f95971b8a6","x":-260,"y":20,"width":250,"height":60},{"type":"text","text":"This will be sent 4 times","id":"479bd3009fb464b0","x":-260,"y":170,"width":250,"height":60},{"type":"text","text":"","id":"cdc967d2e777ade5","x":85,"y":-40,"width":395,"height":500,"color":"6"},{"type":"text","text":"Be careful with nested loop groups","id":"bc61ab59035be49d","x":-260,"y":280,"width":250,"height":90},{"type":"text","text":"Logging edges from loop groups will log out what happens on each loop and sub-loop (if its nested)","id":"17c0c46b3378bd79","x":520,"y":120,"width":321,"height":102},{"type":"text","text":"","id":"7b6747a24b1ed36e","x":85,"y":600,"width":395,"height":400,"color":"6"},{"type":"text","text":"Inner loop number: {{#}}\nOuter loop number: {{##}}","id":"a1e4bbbafcec0850","x":-260,"y":840,"width":270,"height":100},{"id":"f029d4309bd2b1fc","x":-650,"y":665,"width":310,"height":260,"type":"text","text":"You can access the current loop number/iteration of the loop group a node is in using the variable {{#}} or {{##...}}.\n\nThe number of \"#\"s corresponds to the depth of the loop number you want to see, in the case of nested loops."},{"type":"text","text":"Hello there","id":"4b6e4eac00d4ca2a","x":-250,"y":680,"width":250,"height":60},{"id":"ea53365b1b01a031","x":520,"y":740,"width":356,"height":217,"type":"text","text":"This is useful for processing lists of items using the loop group, as you can tell the LLM to handle a specific item in the list iteratively.\n\n(There is a forEach group feature on its way, where this would be handled in parallel)"}],"edges":[{"id":"270794f37f25bb76","fromNode":"c6b8d6a1f384022f","fromSide":"bottom","toNode":"96f3935e8174877f","toSide":"top"},{"id":"fa5fd9941ce413fa","fromNode":"896ace77fa0c6a7e","fromSide":"bottom","toNode":"c6b8d6a1f384022f","toSide":"top"},{"id":"f0286819a9f22127","fromNode":"2a9251ad533d8576","fromSide":"bottom","toNode":"896ace77fa0c6a7e","toSide":"top"},{"id":"007d49590f64ef9d","fromNode":"d09815f95971b8a6","fromSide":"bottom","toNode":"479bd3009fb464b0","toSide":"top"},{"id":"65ef095c89dded80","fromNode":"479bd3009fb464b0","fromSide":"bottom","toNode":"bc61ab59035be49d","toSide":"top"},{"id":"adc29be9103fb02b","fromNode":"bc61ab59035be49d","fromSide":"right","toNode":"cdc967d2e777ade5","toSide":"left","color":"2"},{"id":"734208df80c9a33e","fromNode":"a1e4bbbafcec0850","fromSide":"right","toNode":"7b6747a24b1ed36e","toSide":"left","color":"2"},{"id":"8c921de751762ac3","fromNode":"4b6e4eac00d4ca2a","fromSide":"bottom","toNode":"a1e4bbbafcec0850","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"33e7457728f9ef47","x":-320,"y":-80,"width":820,"height":560,"label":"Nested loop groups"}, + {"type":"group","id":"0064c11720e6cf20","x":-320,"y":560,"width":820,"height":480,"label":"The loop number variable"}, + {"type":"group","id":"81cdef3b9de52df9","x":-200,"y":-880,"width":460,"height":680,"label":"Loop groups"}, + {"type":"group","id":"df42bd1da1866b7f","x":-300,"y":0,"width":330,"height":420,"label":"2"}, + {"type":"group","id":"2ae53ef6008eeb4e","x":-300,"y":640,"width":360,"height":360,"label":"2"}, + {"type":"group","id":"986991747df080b2","x":-115,"y":-720,"width":290,"height":260,"label":"3"}, + {"type":"group","id":"d83bf39a509c67bd","x":-280,"y":150,"width":280,"height":250,"label":"2"}, + {"type":"group","id":"76b98e9977f73412","x":-280,"y":790,"width":310,"height":190,"label":"2"}, + {"type":"text","text":"When all the nodes in a loop group are finished, all nodes will reset and the group will restart. \n\nIt will loop as many times as are defined in the label, and only the result of the final loop will be sent along the arrows leaving the group.","id":"6e5fbad373215bd8","x":-660,"y":-695,"width":441,"height":170}, + {"type":"text","text":"Loop groups are colorless groups that have a positive integer in their label.","id":"a408edeafd6bc62f","x":-169,"y":-1040,"width":399,"height":89}, + {"type":"text","text":"This message will be sent once","id":"2a9251ad533d8576","x":-95,"y":-860,"width":250,"height":60}, + {"type":"text","text":"This one will be sent 3 times","id":"896ace77fa0c6a7e","x":-95,"y":-700,"width":250,"height":60}, + {"type":"text","text":"Only the last response will be written to the content node outside the loop.","id":"c6b8d6a1f384022f","x":-95,"y":-610,"width":250,"height":120}, + {"type":"text","text":"","id":"96f3935e8174877f","x":-95,"y":-400,"width":250,"height":180,"color":"6"}, + {"type":"text","text":"Nested loop groups will fully reset, meaning in this case the inner group will repeat 4 times.","id":"24835b0cc486957f","x":-690,"y":64,"width":350,"height":106}, + {"type":"text","text":"This message will be sent 2 times","id":"d09815f95971b8a6","x":-260,"y":20,"width":250,"height":60}, + {"type":"text","text":"This will be sent 4 times","id":"479bd3009fb464b0","x":-260,"y":170,"width":250,"height":60}, + {"type":"text","text":"","id":"cdc967d2e777ade5","x":85,"y":-40,"width":395,"height":500,"color":"6"}, + {"type":"text","text":"Be careful with nested loop groups","id":"bc61ab59035be49d","x":-260,"y":280,"width":250,"height":90}, + {"type":"text","text":"Logging edges from loop groups will log out what happens on each loop and sub-loop (if its nested)","id":"17c0c46b3378bd79","x":520,"y":120,"width":321,"height":102}, + {"type":"text","text":"","id":"7b6747a24b1ed36e","x":85,"y":600,"width":395,"height":400,"color":"6"}, + {"type":"text","text":"Inner loop number: {{#}}\nOuter loop number: {{##}}","id":"a1e4bbbafcec0850","x":-260,"y":840,"width":270,"height":100}, + {"id":"f029d4309bd2b1fc","x":-650,"y":665,"width":310,"height":260,"type":"text","text":"You can access the current loop number/iteration of the loop group a node is in using the variable {{#}} or {{##...}}.\n\nThe number of \"#\"s corresponds to the depth of the loop number you want to see, in the case of nested loops."}, + {"type":"text","text":"Hello there","id":"4b6e4eac00d4ca2a","x":-250,"y":680,"width":250,"height":60}, + {"id":"ea53365b1b01a031","x":520,"y":740,"width":356,"height":217,"type":"text","text":"This is useful for processing lists of items using the loop group, as you can tell the LLM to handle a specific item in the list iteratively.\n\n(There is a forEach group feature on its way, where this would be handled in parallel)"} + ], + "edges":[ + {"id":"270794f37f25bb76","fromNode":"c6b8d6a1f384022f","fromSide":"bottom","toNode":"96f3935e8174877f","toSide":"top"}, + {"id":"fa5fd9941ce413fa","fromNode":"896ace77fa0c6a7e","fromSide":"bottom","toNode":"c6b8d6a1f384022f","toSide":"top"}, + {"id":"f0286819a9f22127","fromNode":"2a9251ad533d8576","fromSide":"bottom","toNode":"896ace77fa0c6a7e","toSide":"top"}, + {"id":"007d49590f64ef9d","fromNode":"d09815f95971b8a6","fromSide":"bottom","toNode":"479bd3009fb464b0","toSide":"top"}, + {"id":"65ef095c89dded80","fromNode":"479bd3009fb464b0","fromSide":"bottom","toNode":"bc61ab59035be49d","toSide":"top"}, + {"id":"adc29be9103fb02b","fromNode":"bc61ab59035be49d","fromSide":"right","toNode":"cdc967d2e777ade5","toSide":"left","color":"2"}, + {"id":"734208df80c9a33e","fromNode":"a1e4bbbafcec0850","fromSide":"right","toNode":"7b6747a24b1ed36e","toSide":"left","color":"2"}, + {"id":"8c921de751762ac3","fromNode":"4b6e4eac00d4ca2a","fromSide":"bottom","toNode":"a1e4bbbafcec0850","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/5. Groups/3. Loop group features.canvas b/assets/Cannoli College/5. Groups/3. Loop group features.canvas index 0379c78..a880302 100644 --- a/assets/Cannoli College/5. Groups/3. Loop group features.canvas +++ b/assets/Cannoli College/5. Groups/3. Loop group features.canvas @@ -1 +1,40 @@ -{"nodes":[{"type":"group","id":"cd5aefdec24485a6","x":-395,"y":920,"width":1200,"height":1187,"label":"Conditional loop groups"},{"type":"group","id":"b41f5d77d2587137","x":-215,"y":-344,"width":840,"height":948,"label":"Feedback variables"},{"type":"group","id":"a8db6171d1ed7037","x":-375,"y":987,"width":680,"height":1040,"label":"3"},{"type":"group","id":"308eacb6bc673cc4","x":5,"y":-136,"width":290,"height":240,"label":"3"},{"type":"text","text":"Crisp shell, sweet delight, Ricotta whispers within, Sicily's soft night.","id":"8bd344c2d351a946","x":25,"y":-324,"width":250,"height":100,"color":"6"},{"type":"text","text":"If a variable edge is pointing from a group member to the group itself, this variable will be accessible on subsequent loops. (This is an exception to the rule that the Cannoli must be a DAG)","id":"69c0aa7ba528fd7f","x":25,"y":-604,"width":378,"height":187},{"type":"text","text":"Critique this haiku:\n{{a}}","id":"4522c0d5f13ecbf2","x":25,"y":-104,"width":250,"height":60},{"type":"text","text":"Respond with a rewrite. Nothing else should be in your response.","id":"08d62752b952d1b9","x":25,"y":-14,"width":250,"height":90},{"type":"text","text":"If there are multiple available arrows with the same name, the node will prefer the self-group-pointing one.\n\nYou can use this to pre-load variables with an initial version for the first loop, which will be written over in later loops.","id":"1547e2e1c8e36e01","x":-625,"y":-214,"width":390,"height":221},{"type":"text","text":"This is an example of a rewrite loop, where we have the LLM rewrite a piece of content several times and output the final result.","id":"39f5077b01de86bc","x":-618,"y":215,"width":383,"height":121},{"type":"text","text":"","id":"0209622577e4d8e4","x":-195,"y":196,"width":270,"height":205,"color":"6"},{"type":"text","text":"","id":"a8c82e1399aa0667","x":144,"y":217,"width":461,"height":367,"color":"6"},{"type":"text","text":"If a loop group has incoming arrows from within itself, it will only loop if they are all activated.\n\nThis means you can use choice arrows to create groups that stop looping based on a decision the LLM makes.","id":"109c6d143c904ac2","x":-40,"y":700,"width":559,"height":153},{"type":"text","text":"Are there any obvious improvements to this article?\n\n{{article}}","id":"c9ac27366825fb46","x":-271,"y":1327,"width":283,"height":122},{"type":"text","text":"What would you change?","id":"42e65836e7bc0d2d","x":-254,"y":1540,"width":250,"height":60},{"type":"file","file":"Cannoli College/Example notes/Lemons for Cleaning.md","text":"{{[[Lemons for Cleaning]]}}","id":"9b09ade8a96fdc49","x":-330,"y":1025,"width":400,"height":203},{"type":"text","text":"In this example, we use choice arrows to have the LLM decide whether to edit a note.\n\nThe decision to edit it activates a path that points to the group itself, so the group will loop again once it is done.\n\nIf that path is rejected, the group will not loop again.","id":"3ae1b1035e633274","x":-814,"y":1228,"width":402,"height":259},{"type":"text","text":"Respond with a rewrite based on your feedback.","id":"92dee3525bb5528a","x":-289,"y":1660,"width":320,"height":100},{"type":"text","text":"","id":"65d12403b1902562","x":120,"y":1328,"width":165,"height":121,"color":"6"},{"type":"text","text":"","id":"c19decb87eb68f4e","x":340,"y":1443,"width":440,"height":535,"color":"6"},{"type":"text","text":"It doesn't matter what the node pointing at the group is, or what kind of arrow. In this case we use a blank arrow to signal that the rewrite path was chosen and add the chat history suppression suffix (~) so we don't continue the conversation in the next loop.","id":"07a8d464729bd7db","x":-800,"y":1864,"width":388,"height":196},{"type":"file","file":"Cannoli College/Example notes/Lemons for Cleaning.md","text":"{{[[Lemons for Cleaning]]}}","id":"a447b4af7f9b59af","x":-329,"y":1820,"width":400,"height":180}],"edges":[{"id":"98bface3c4272939","fromNode":"08d62752b952d1b9","fromSide":"right","toNode":"308eacb6bc673cc4","toSide":"right","label":"a"},{"id":"01117e93ffd16810","fromNode":"8bd344c2d351a946","fromSide":"bottom","toNode":"4522c0d5f13ecbf2","toSide":"top","label":"a"},{"id":"4705bd8c3ac7a1dd","fromNode":"4522c0d5f13ecbf2","fromSide":"bottom","toNode":"08d62752b952d1b9","toSide":"top"},{"id":"09153b08d8afc249","fromNode":"08d62752b952d1b9","fromSide":"bottom","toNode":"0209622577e4d8e4","toSide":"top"},{"id":"d74b679a0e9c5a8e","fromNode":"08d62752b952d1b9","fromSide":"bottom","toNode":"a8c82e1399aa0667","toSide":"top","color":"2"},{"id":"313f7dba1ac082e7","fromNode":"a447b4af7f9b59af","fromSide":"bottom","toNode":"a8db6171d1ed7037","toSide":"bottom","label":"~"},{"id":"ae86725de62f454c","fromNode":"92dee3525bb5528a","fromSide":"right","toNode":"c19decb87eb68f4e","toSide":"left","color":"2"},{"id":"28dd5bf26534621f","fromNode":"9b09ade8a96fdc49","fromSide":"bottom","toNode":"c9ac27366825fb46","toSide":"top","label":"article"},{"id":"cb414a8bed4cab51","fromNode":"c9ac27366825fb46","fromSide":"bottom","toNode":"42e65836e7bc0d2d","toSide":"top","color":"3","label":"yes"},{"id":"8e14d432eb6409d9","fromNode":"c9ac27366825fb46","fromSide":"right","toNode":"65d12403b1902562","toSide":"left","color":"3","label":"no"},{"id":"e151468f90fae46f","fromNode":"42e65836e7bc0d2d","fromSide":"bottom","toNode":"92dee3525bb5528a","toSide":"top"},{"id":"e9279e94dd7a9109","fromNode":"92dee3525bb5528a","fromSide":"bottom","toNode":"a447b4af7f9b59af","toSide":"top"}]} \ No newline at end of file +{ + "nodes":[ + {"type":"group","id":"cd5aefdec24485a6","x":-395,"y":920,"width":1200,"height":1187,"label":"Conditional loop groups"}, + {"type":"group","id":"b41f5d77d2587137","x":-215,"y":-344,"width":840,"height":948,"label":"Feedback variables"}, + {"type":"group","id":"a8db6171d1ed7037","x":-375,"y":987,"width":680,"height":1040,"label":"3"}, + {"type":"group","id":"308eacb6bc673cc4","x":5,"y":-136,"width":290,"height":240,"label":"3"}, + {"type":"text","text":"Crisp shell, sweet delight, Ricotta whispers within, Sicily's soft night.","id":"8bd344c2d351a946","x":25,"y":-324,"width":250,"height":100,"color":"6"}, + {"type":"text","text":"If a variable edge is pointing from a group member to the group itself, this variable will be accessible on subsequent loops. (This is an exception to the rule that the Cannoli must be a DAG)","id":"69c0aa7ba528fd7f","x":25,"y":-604,"width":378,"height":187}, + {"type":"text","text":"Critique this haiku:\n{{a}}","id":"4522c0d5f13ecbf2","x":25,"y":-104,"width":250,"height":60}, + {"type":"text","text":"Respond with a rewrite. Nothing else should be in your response.","id":"08d62752b952d1b9","x":25,"y":-14,"width":250,"height":90}, + {"type":"text","text":"If there are multiple available arrows with the same name, the node will prefer the self-group-pointing one.\n\nYou can use this to pre-load variables with an initial version for the first loop, which will be written over in later loops.","id":"1547e2e1c8e36e01","x":-625,"y":-214,"width":390,"height":221}, + {"type":"text","text":"This is an example of a rewrite loop, where we have the LLM rewrite a piece of content several times and output the final result.","id":"39f5077b01de86bc","x":-618,"y":215,"width":383,"height":121}, + {"type":"text","text":"","id":"0209622577e4d8e4","x":-195,"y":196,"width":270,"height":205,"color":"6"}, + {"type":"text","text":"","id":"a8c82e1399aa0667","x":144,"y":217,"width":461,"height":367,"color":"6"}, + {"type":"text","text":"If a loop group has incoming arrows from within itself, it will only loop if they are all activated.\n\nThis means you can use choice arrows to create groups that stop looping based on a decision the LLM makes.","id":"109c6d143c904ac2","x":-40,"y":700,"width":559,"height":153}, + {"type":"text","text":"Are there any obvious improvements to this article?\n\n{{article}}","id":"c9ac27366825fb46","x":-271,"y":1327,"width":283,"height":122}, + {"type":"text","text":"What would you change?","id":"42e65836e7bc0d2d","x":-254,"y":1540,"width":250,"height":60}, + {"type":"file","file":"Cannoli College/Example notes/Lemons for Cleaning.md","text":"{{[[Lemons for Cleaning]]}}","id":"9b09ade8a96fdc49","x":-330,"y":1025,"width":400,"height":203}, + {"type":"text","text":"In this example, we use choice arrows to have the LLM decide whether to edit a note.\n\nThe decision to edit it activates a path that points to the group itself, so the group will loop again once it is done.\n\nIf that path is rejected, the group will not loop again.","id":"3ae1b1035e633274","x":-814,"y":1228,"width":402,"height":259}, + {"type":"text","text":"Respond with a rewrite based on your feedback.","id":"92dee3525bb5528a","x":-289,"y":1660,"width":320,"height":100}, + {"type":"text","text":"","id":"65d12403b1902562","x":120,"y":1328,"width":165,"height":121,"color":"6"}, + {"type":"text","text":"","id":"c19decb87eb68f4e","x":340,"y":1443,"width":440,"height":535,"color":"6"}, + {"type":"text","text":"It doesn't matter what the node pointing at the group is, or what kind of arrow. In this case we use a blank arrow to signal that the rewrite path was chosen and add the chat history suppression suffix (~) so we don't continue the conversation in the next loop.","id":"07a8d464729bd7db","x":-800,"y":1864,"width":388,"height":196}, + {"type":"file","file":"Cannoli College/Example notes/Lemons for Cleaning.md","text":"{{[[Lemons for Cleaning]]}}","id":"a447b4af7f9b59af","x":-329,"y":1820,"width":400,"height":180} + ], + "edges":[ + {"id":"98bface3c4272939","fromNode":"08d62752b952d1b9","fromSide":"right","toNode":"308eacb6bc673cc4","toSide":"right","label":"a"}, + {"id":"01117e93ffd16810","fromNode":"8bd344c2d351a946","fromSide":"bottom","toNode":"4522c0d5f13ecbf2","toSide":"top","label":"a"}, + {"id":"4705bd8c3ac7a1dd","fromNode":"4522c0d5f13ecbf2","fromSide":"bottom","toNode":"08d62752b952d1b9","toSide":"top"}, + {"id":"09153b08d8afc249","fromNode":"08d62752b952d1b9","fromSide":"bottom","toNode":"0209622577e4d8e4","toSide":"top"}, + {"id":"d74b679a0e9c5a8e","fromNode":"08d62752b952d1b9","fromSide":"bottom","toNode":"a8c82e1399aa0667","toSide":"top","color":"2"}, + {"id":"313f7dba1ac082e7","fromNode":"a447b4af7f9b59af","fromSide":"bottom","toNode":"a8db6171d1ed7037","toSide":"bottom","label":"~"}, + {"id":"ae86725de62f454c","fromNode":"92dee3525bb5528a","fromSide":"right","toNode":"c19decb87eb68f4e","toSide":"left","color":"2"}, + {"id":"28dd5bf26534621f","fromNode":"9b09ade8a96fdc49","fromSide":"bottom","toNode":"c9ac27366825fb46","toSide":"top","label":"article"}, + {"id":"cb414a8bed4cab51","fromNode":"c9ac27366825fb46","fromSide":"bottom","toNode":"42e65836e7bc0d2d","toSide":"top","color":"3","label":"yes"}, + {"id":"8e14d432eb6409d9","fromNode":"c9ac27366825fb46","fromSide":"right","toNode":"65d12403b1902562","toSide":"left","color":"3","label":"no"}, + {"id":"e151468f90fae46f","fromNode":"42e65836e7bc0d2d","fromSide":"bottom","toNode":"92dee3525bb5528a","toSide":"top"}, + {"id":"e9279e94dd7a9109","fromNode":"92dee3525bb5528a","fromSide":"bottom","toNode":"a447b4af7f9b59af","toSide":"top"} + ] +} \ No newline at end of file diff --git a/assets/Cannoli College/Example notes/Apple Trees.md b/assets/Cannoli College/Example notes/Apple Trees.md index 21698b9..afdd2a2 100644 --- a/assets/Cannoli College/Example notes/Apple Trees.md +++ b/assets/Cannoli College/Example notes/Apple Trees.md @@ -1,3 +1,7 @@ +--- +tags: + - cannoliArticle +--- Apple trees, scientifically known as *Malus domestica*, are not just providers of one of the world's most consumed fruits but are also a model of efficiency and adaptability. Originating in Central Asia, these trees have been cultivated for thousands of years and have adapted to a variety of climates, from temperate to sub-tropical. The tree's rootstock can often be grafted to optimize for disease resistance, soil compatibility, or fruit yield, a testament to its remarkable genetic flexibility. The life cycle of an apple tree involves a series of well-coordinated biological events. After the cold dormancy of winter, apple trees enter a phase of bud break in the spring, followed by flowering and pollination. Apple trees are usually not self-pollinating and require cross-pollination from another apple tree of a different variety. This ensures genetic diversity, which is crucial for the tree's adaptability and long-term survival. Post-pollination, the tree focuses on fruit development, channeling nutrients and energy into the growing apples. diff --git a/assets/Cannoli College/Example notes/Lemons for Cleaning.md b/assets/Cannoli College/Example notes/Lemons for Cleaning.md index daca8d1..997809f 100644 --- a/assets/Cannoli College/Example notes/Lemons for Cleaning.md +++ b/assets/Cannoli College/Example notes/Lemons for Cleaning.md @@ -1,3 +1,7 @@ +--- +tags: + - cannoliArticle +--- Cleaning your home with lemons is not only effective but also environmentally friendly. Lemons, with their natural disinfecting properties and high citric acid content, can tackle a wide range of cleaning tasks. Here are some detailed tips to maximize the cleaning power of lemons: 1. All-Purpose Cleaner: Create a potent all-purpose cleaner by mixing equal parts lemon juice and water. Lemons contain citric acid, which is effective in killing germs, bacteria, and odors. Squeeze the juice of fresh lemons into a spray bottle, adding an equal amount of water. Shake the bottle well to thoroughly blend the solution. This natural disinfectant is perfect for countertops, sinks, cutting boards, and food containers. To use, simply spray the solution onto the surface and let it sit for a few minutes to allow the citric acid to work its magic. Then, scrub with a sponge or cloth and rinse thoroughly with water. diff --git a/assets/cannoliCollege.js b/assets/cannoliCollege.js index e682e93..86b67fa 100644 --- a/assets/cannoliCollege.js +++ b/assets/cannoliCollege.js @@ -1,5 +1,5 @@ export const cannoliCollege = { - "1. Basics": [ + "1. Basics": [ { name: "1. Hello world.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"161279baf7763214\",\"x\":-174,\"y\":-160,\"width\":394,\"height\":340,\"label\":\"Cannoli\"},{\"type\":\"text\",\"text\":\"Hello world!\",\"id\":\"dc3f9351f787531e\",\"x\":-97,\"y\":-91,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"\",\"id\":\"bc1a550bbb4aac7b\",\"x\":-97,\"y\":60,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"The purple node is a content node. Content nodes can be used to store and display text that can be read or written by you or another node.\",\"id\":\"f77169b141243e65\",\"x\":240,\"y\":30,\"width\":420,\"height\":120},{\"type\":\"text\",\"text\":\"The colorless, green, or yellow node is a call node. Call nodes make a chat completion call to the LLM with the text of the node as a user message.\",\"id\":\"0af5a453bd4d6ec9\",\"x\":240,\"y\":-110,\"width\":380,\"height\":120},{\"type\":\"text\",\"text\":\"If a node in a cannoli is floating (no arrows attached) it won't affect the cannoli unless it is formatted in a special way we'll go over later.\",\"id\":\"7d005c80299f3674\",\"x\":-202,\"y\":220,\"width\":461,\"height\":112},{\"type\":\"text\",\"text\":\"This is a Cannoli. It's made up of different types of nodes and arrows.\\n\\nTry running it by clicking the Cannoli button in the control ribbon on the left side of your Obsidian window.\",\"id\":\"24dd96c964700992\",\"x\":-147,\"y\":-400,\"width\":350,\"height\":180},{\"type\":\"text\",\"text\":\"Cannolis can be run in several ways:\\n\\n- Click the Cannoli ribbon icon\\n - If you're on a canvas file, it will be run as a cannoli\\n - If you're on a note with a \\\"cannoli\\\" property, the canvas file in that property will be run as a cannoli\\n- Run the \\\"Start/Stop cannoli\\\" command in the command palette (functions the same as the ribbon icon)\\n- If a canvas file name ends with \\\".cno\\\", it will have its own run command in the command palette\\n- Make an audio recording on a note with a \\\"cannoli\\\" property\\n\\t- That recording will be transcribed, replace the reference, and trigger the cannoli defined in the property.\",\"id\":\"927cf33512b0dfc1\",\"x\":-740,\"y\":-182,\"width\":538,\"height\":402}],\"edges\":[{\"id\":\"23c2d7dffb49bf75\",\"fromNode\":\"dc3f9351f787531e\",\"fromSide\":\"bottom\",\"toNode\":\"bc1a550bbb4aac7b\",\"toSide\":\"top\"}]}" @@ -20,8 +20,8 @@ export const cannoliCollege = { name: "5. Variable arrows.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"4dd63eded63256f2\",\"x\":-172,\"y\":240,\"width\":665,\"height\":460,\"label\":\"Multiple variables\"},{\"type\":\"group\",\"id\":\"d83444fe5b49fb2c\",\"x\":-160,\"y\":800,\"width\":653,\"height\":463,\"label\":\"Between call nodes\"},{\"type\":\"group\",\"id\":\"c409a28317a5ae26\",\"x\":11,\"y\":-360,\"width\":294,\"height\":510,\"label\":\"Variables\"},{\"type\":\"text\",\"text\":\"Pannetone\",\"id\":\"0d48f7722e5db52e\",\"x\":31,\"y\":-340,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"The label of the arrow names the variable, and you can inject it into a call node using the format \\\"{{variable name}}\\\"\",\"id\":\"1a3b5db348375dba\",\"x\":-380,\"y\":-199,\"width\":371,\"height\":119},{\"type\":\"text\",\"text\":\"How do you make {{dessert}}?\",\"id\":\"10cedae5ccf81664\",\"x\":31,\"y\":-180,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"\",\"id\":\"5cf958d72a55d52d\",\"x\":32,\"y\":-24,\"width\":250,\"height\":154,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Labeling an arrow makes it a variable you can access in call nodes.\",\"id\":\"db8924f8ddaaa08e\",\"x\":-13,\"y\":-520,\"width\":330,\"height\":86},{\"type\":\"text\",\"text\":\"Hannibal\",\"id\":\"b2aa8b695a7b7774\",\"x\":-152,\"y\":260,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Elephants\",\"id\":\"c23271f22630c4a9\",\"x\":223,\"y\":260,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"What connects {{a}} and {{b}}?\",\"id\":\"4f84654825f9df4c\",\"x\":34,\"y\":420,\"width\":293,\"height\":75},{\"type\":\"text\",\"text\":\"You can name and inject the output of call nodes the same way.\",\"id\":\"835c4e523796df6e\",\"x\":-500,\"y\":915,\"width\":320,\"height\":80},{\"type\":\"text\",\"text\":\"Rate this limerick:\\n{{limerick}}\",\"id\":\"25d842fe884f4e78\",\"x\":-140,\"y\":995,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"Respond with a limerick about Cannolis\",\"id\":\"1714bc9f52099a91\",\"x\":-140,\"y\":820,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"\",\"id\":\"84fb2c8243704c1a\",\"x\":55,\"y\":550,\"width\":250,\"height\":130,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"\",\"id\":\"13cde1cb12272304\",\"x\":-140,\"y\":1110,\"width\":250,\"height\":133,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Are you sure its {{city}}?\",\"id\":\"fe8260fd047fe01a\",\"x\":192,\"y\":996,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"\",\"id\":\"26d4da45eb95d333\",\"x\":192,\"y\":1110,\"width\":250,\"height\":133,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"What's the capital of Italy?\",\"id\":\"44d0ee25c2f23e66\",\"x\":192,\"y\":820,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"Multiple arrows going into a call node can be used to inject multiple variables.\",\"id\":\"0fd0a4b39c942f0b\",\"x\":-426,\"y\":399,\"width\":246,\"height\":117},{\"type\":\"text\",\"text\":\"Labeled basic arrows between call nodes will not pass along the chat history by default, only the content of the response.\\n\\nYou can override this by adding a \\\"|\\\" symbol at the end of the arrow label like so. Then you can continue a conversation as well as use a variable.\",\"id\":\"1fadbba4649fa725\",\"x\":520,\"y\":955,\"width\":380,\"height\":245}],\"edges\":[{\"id\":\"139dad9317421572\",\"fromNode\":\"0d48f7722e5db52e\",\"fromSide\":\"bottom\",\"toNode\":\"10cedae5ccf81664\",\"toSide\":\"top\",\"label\":\"dessert\"},{\"id\":\"fa1b26557addc3e5\",\"fromNode\":\"b2aa8b695a7b7774\",\"fromSide\":\"bottom\",\"toNode\":\"4f84654825f9df4c\",\"toSide\":\"top\",\"label\":\"a\"},{\"id\":\"ece89fb689451485\",\"fromNode\":\"c23271f22630c4a9\",\"fromSide\":\"bottom\",\"toNode\":\"4f84654825f9df4c\",\"toSide\":\"top\",\"label\":\"b\"},{\"id\":\"b9eadfcbf2c54fe1\",\"fromNode\":\"10cedae5ccf81664\",\"fromSide\":\"bottom\",\"toNode\":\"5cf958d72a55d52d\",\"toSide\":\"top\"},{\"id\":\"3a41dc5849268edf\",\"fromNode\":\"4f84654825f9df4c\",\"fromSide\":\"bottom\",\"toNode\":\"84fb2c8243704c1a\",\"toSide\":\"top\"},{\"id\":\"7cf5bbc070866504\",\"fromNode\":\"25d842fe884f4e78\",\"fromSide\":\"bottom\",\"toNode\":\"13cde1cb12272304\",\"toSide\":\"top\"},{\"id\":\"3b347865a761d32b\",\"fromNode\":\"1714bc9f52099a91\",\"fromSide\":\"bottom\",\"toNode\":\"25d842fe884f4e78\",\"toSide\":\"top\",\"label\":\"limerick\"},{\"id\":\"f93a6b2b699a1bf6\",\"fromNode\":\"44d0ee25c2f23e66\",\"fromSide\":\"bottom\",\"toNode\":\"fe8260fd047fe01a\",\"toSide\":\"top\",\"label\":\"city|\"},{\"id\":\"0fa4378c8752aca4\",\"fromNode\":\"fe8260fd047fe01a\",\"fromSide\":\"bottom\",\"toNode\":\"26d4da45eb95d333\",\"toSide\":\"top\"}]}" }, - ], - "2. Special arrows": [ +], + "2. Special arrows": [ { name: "1. Config arrows.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"b388b74fc76f9d5b\",\"x\":-411,\"y\":420,\"width\":800,\"height\":480,\"label\":\"Config Arrows\"},{\"type\":\"group\",\"id\":\"50e47210c3597f2c\",\"x\":-382,\"y\":-274,\"width\":742,\"height\":442,\"label\":\"Logging Arrows\"},{\"type\":\"text\",\"text\":\"What's the weakest?\",\"id\":\"01b6cd0557436d0d\",\"x\":-362,\"y\":77,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"You're an expert in metallurgy\",\"id\":\"cd8bccad9c0ff0e1\",\"x\":-362,\"y\":-254,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"What's the strongest metal?\",\"id\":\"d90d1eda5b1cee39\",\"x\":-362,\"y\":-94,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"The logging arrow will write the chat history, response, and config of the call node to the content node it is pointing to.\",\"id\":\"82607dbca24bcc3b\",\"x\":-720,\"y\":48,\"width\":325,\"height\":120},{\"type\":\"text\",\"text\":\"As a cannoli gets more complex, it can be difficult to know what the LLM is actually seeing in each call node.\\n\\nA blank config arrow leaving a call node will log out everything the LLM saw on that call, as well as the config of that call node.\",\"id\":\"2eddfb2df05ffd92\",\"x\":-932,\"y\":-224,\"width\":537,\"height\":160},{\"type\":\"text\",\"text\":\"Orange arrows are config arrows. You can change the color of arrows by left clicking on them and then clicking on the color pallet \",\"id\":\"f1b3951087221764\",\"x\":-160,\"y\":-440,\"width\":393,\"height\":118},{\"type\":\"text\",\"text\":\"\",\"id\":\"18629c0795e99c52\",\"x\":-28,\"y\":-158,\"width\":365,\"height\":295,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Labeled config arrows pointing to call nodes will try to set their content to the LLM config setting named in the arrow's label.\",\"id\":\"9750898ccab8b2ec\",\"x\":-190,\"y\":240,\"width\":325,\"height\":130},{\"type\":\"text\",\"text\":\"1.5\",\"id\":\"f2066662ccfdf12b\",\"x\":-228,\"y\":450,\"width\":106,\"height\":68,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"When will gpt-5 come out?\",\"id\":\"901e534d654dbe8d\",\"x\":-285,\"y\":640,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"gpt-4\",\"id\":\"32895b9cbe65ebf5\",\"x\":-385,\"y\":450,\"width\":100,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"\",\"id\":\"f9768071dcaaf641\",\"x\":24,\"y\":445,\"width\":345,\"height\":415,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Config arrows can also be used to set the LLM config of call nodes, overriding the default.\",\"id\":\"f75c463c060098f5\",\"x\":-760,\"y\":442,\"width\":324,\"height\":106},{\"type\":\"text\",\"text\":\"This call node will request a gpt-4 response with a temperature of 1.5, overriding the defaults.\\n\\n(You can set the defaults in the plugin settings)\",\"id\":\"1a6e63c23f2fd598\",\"x\":-760,\"y\":581,\"width\":324,\"height\":179}],\"edges\":[{\"id\":\"3e19de32f2cf2234\",\"fromNode\":\"01b6cd0557436d0d\",\"fromSide\":\"right\",\"toNode\":\"18629c0795e99c52\",\"toSide\":\"left\",\"color\":\"2\"},{\"id\":\"a5ea03afb9e7519f\",\"fromNode\":\"d90d1eda5b1cee39\",\"fromSide\":\"bottom\",\"toNode\":\"01b6cd0557436d0d\",\"toSide\":\"top\"},{\"id\":\"e60e398ffd796673\",\"fromNode\":\"cd8bccad9c0ff0e1\",\"fromSide\":\"bottom\",\"toNode\":\"d90d1eda5b1cee39\",\"toSide\":\"top\"},{\"id\":\"4802b580405f5936\",\"fromNode\":\"f2066662ccfdf12b\",\"fromSide\":\"bottom\",\"toNode\":\"901e534d654dbe8d\",\"toSide\":\"top\",\"color\":\"2\",\"label\":\"temperature\"},{\"id\":\"44d9a85dc1209c3f\",\"fromNode\":\"901e534d654dbe8d\",\"fromSide\":\"right\",\"toNode\":\"f9768071dcaaf641\",\"toSide\":\"left\",\"color\":\"2\"},{\"id\":\"18f98f277862e948\",\"fromNode\":\"32895b9cbe65ebf5\",\"fromSide\":\"bottom\",\"toNode\":\"901e534d654dbe8d\",\"toSide\":\"left\",\"color\":\"2\",\"label\":\"model\"}]}" @@ -42,8 +42,8 @@ export const cannoliCollege = { name: "5. Chat arrows.cno.canvas", content: "{\"nodes\":[{\"id\":\"167d3b7b2f6f548d\",\"type\":\"group\",\"x\":-460,\"y\":400,\"width\":1004,\"height\":660,\"label\":\"Limiting chat messages\"},{\"id\":\"ec1597e4e7f3530c\",\"type\":\"group\",\"x\":-209,\"y\":-208,\"width\":290,\"height\":348,\"label\":\"Chat arrows\"},{\"id\":\"09ce49517baf7eda\",\"type\":\"text\",\"text\":\"\",\"x\":-189,\"y\":-60,\"width\":250,\"height\":60},{\"id\":\"b90c7fbfa70e4300\",\"type\":\"text\",\"text\":\"{{NOTE}}\",\"x\":-189,\"y\":60,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"4857524edbae8263\",\"type\":\"text\",\"text\":\"This chat arrow will parse the contents of the reference node into an array of messages\",\"x\":100,\"y\":-147,\"width\":380,\"height\":87},{\"id\":\"ef3cdc2a117f9156\",\"type\":\"text\",\"text\":\"{{NOTE}}\",\"x\":-330,\"y\":420,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"82ba7993840f1760\",\"type\":\"text\",\"text\":\"\",\"x\":-330,\"y\":568,\"width\":250,\"height\":60},{\"id\":\"09a9d8dd0741d74b\",\"type\":\"text\",\"text\":\"\",\"x\":163,\"y\":568,\"width\":250,\"height\":60},{\"id\":\"9a309223d6ce3931\",\"type\":\"text\",\"text\":\"\",\"x\":-440,\"y\":680,\"width\":471,\"height\":360,\"color\":\"6\"},{\"id\":\"f2d8da368e1c51b6\",\"type\":\"text\",\"text\":\"\",\"x\":53,\"y\":680,\"width\":471,\"height\":360,\"color\":\"6\"},{\"id\":\"cd757b7484ffd798\",\"type\":\"text\",\"text\":\"{{NOTE}}\",\"x\":163,\"y\":420,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"d9739a4acdf10a34\",\"type\":\"text\",\"text\":\"This chat node is empty, so it will just send the previous messages it was given to the LLM\",\"x\":-610,\"y\":-86,\"width\":343,\"height\":106},{\"id\":\"2b08e45e39b8eb39\",\"type\":\"text\",\"text\":\"This chat arrow will append the content of the response to the same note, as a stream.\",\"x\":100,\"y\":-30,\"width\":380,\"height\":120},{\"id\":\"ce80fff3047872f3\",\"type\":\"text\",\"text\":\"The final chat arrow only sends the final response, so you can do anything you like with the space between the two chat arrows. \\n\\nUse this flexibility to build chatbots that send http requests, make decisions, edit notes, or gather relevant context.\",\"x\":-717,\"y\":60,\"width\":459,\"height\":200},{\"id\":\"1097b1b80a3abe81\",\"type\":\"text\",\"text\":\"{{NOTE}}\",\"x\":-189,\"y\":-188,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"a8e6750d3ca80fff\",\"type\":\"text\",\"text\":\"This is a special reference node that references the note that was active when the cannoli was run.\",\"x\":-717,\"y\":-211,\"width\":450,\"height\":83},{\"id\":\"2d01d9688ecbe4da\",\"type\":\"text\",\"text\":\"Green arrows are chat arrows. They can be used to build custom chatbots within obsidian using Cannoli.\\n\\nTry this by moving to a note, then running this cannoli using the \\\"4. Chat arrows\\\" command.\",\"x\":-277,\"y\":-440,\"width\":427,\"height\":180},{\"id\":\"6ff1bc87ce822f42\",\"x\":-890,\"y\":489,\"width\":403,\"height\":218,\"type\":\"text\",\"text\":\"You can limit the number of messages parsed from a note by adding a number to the label.\\n\\nJust a number will limit the number of messages, and adding a \\\"#\\\" to the beginning of the label will limit based on an approximation of tokens. \"},{\"id\":\"2213c3caec2e3835\",\"x\":-800,\"y\":804,\"width\":315,\"height\":96,\"type\":\"text\",\"text\":\"The example on the left will send the most recent two messages from the note\"},{\"id\":\"fd4602caf5adb9bc\",\"x\":560,\"y\":508,\"width\":440,\"height\":90,\"type\":\"text\",\"text\":\"This chat arrow will send messages not exceeding the estimated token limit (but at least 1 message)\"}],\"edges\":[{\"id\":\"dddd3b587c8b7340\",\"fromNode\":\"1097b1b80a3abe81\",\"fromSide\":\"bottom\",\"toNode\":\"09ce49517baf7eda\",\"toSide\":\"top\",\"color\":\"4\"},{\"id\":\"847946cb0fc14d7a\",\"fromNode\":\"09ce49517baf7eda\",\"fromSide\":\"bottom\",\"toNode\":\"b90c7fbfa70e4300\",\"toSide\":\"top\",\"color\":\"4\"},{\"id\":\"8cc7de72b0881d19\",\"fromNode\":\"ef3cdc2a117f9156\",\"fromSide\":\"bottom\",\"toNode\":\"82ba7993840f1760\",\"toSide\":\"top\",\"color\":\"4\",\"label\":\"2\"},{\"id\":\"a738da5d15aa4bd8\",\"fromNode\":\"82ba7993840f1760\",\"fromSide\":\"bottom\",\"toNode\":\"9a309223d6ce3931\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"b2376898a9f7d1f1\",\"fromNode\":\"09a9d8dd0741d74b\",\"fromSide\":\"bottom\",\"toNode\":\"f2d8da368e1c51b6\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"9406dd17d5c41032\",\"fromNode\":\"cd757b7484ffd798\",\"fromSide\":\"bottom\",\"toNode\":\"09a9d8dd0741d74b\",\"toSide\":\"top\",\"color\":\"4\",\"label\":\"#500\"}]}" }, - ], - "3. Special nodes": [ +], + "3. Special nodes": [ { name: "1. Floating nodes.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"6221f4693ddb3417\",\"x\":-320,\"y\":-80,\"width\":600,\"height\":460,\"label\":\"Floating nodes\"},{\"type\":\"text\",\"text\":\"Use a specific format on a floating node (no attached arrows) to create a global variable. You can read and write to this variable anywhere in the cannoli.\",\"id\":\"9650a6926008b16f\",\"x\":-234,\"y\":-259,\"width\":414,\"height\":119},{\"type\":\"text\",\"text\":\"Now just write the new version by itself in your next response.\",\"id\":\"867aca6f08aff01f\",\"x\":-1,\"y\":124,\"width\":250,\"height\":116},{\"type\":\"text\",\"text\":\"Please critique and rewrite this email to be a bit more apologetic:\\n{{[Email Draft]}}\",\"id\":\"848648ac1ab74998\",\"x\":-14,\"y\":-60,\"width\":274,\"height\":120},{\"type\":\"text\",\"text\":\"{{[Email Draft]}}\",\"id\":\"5246f4d07c4012a8\",\"x\":-1,\"y\":300,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"In this example we reference and write to a floating node.\",\"id\":\"38e2ac4e746d3f44\",\"x\":-580,\"y\":-30,\"width\":250,\"height\":90},{\"type\":\"text\",\"text\":\"When a floating node's first line is in single square brackets, it can be accessed as a variable.\",\"id\":\"ff6cf4c87583cf77\",\"x\":-580,\"y\":111,\"width\":250,\"height\":129},{\"type\":\"text\",\"text\":\"You can reference floating node variables the same way you'd reference normal variables, but with the addition of single square brackets.\",\"id\":\"80a63e1ff8700f60\",\"x\":300,\"y\":-40,\"width\":340,\"height\":120},{\"type\":\"text\",\"text\":\"This is an example of a Reference Node. When a content node is just a floating node reference or note reference wrapped in double curly braces, you can write to the referenced location instead of the node itself.\",\"id\":\"f0466f473408290b\",\"x\":300,\"y\":240,\"width\":516,\"height\":127},{\"type\":\"text\",\"text\":\"[Email Draft]\\nLet me get back to you on that\",\"id\":\"329298ec10140a51\",\"x\":-300,\"y\":75,\"width\":250,\"height\":99}],\"edges\":[{\"id\":\"f33f402d10538f79\",\"fromNode\":\"848648ac1ab74998\",\"fromSide\":\"bottom\",\"toNode\":\"867aca6f08aff01f\",\"toSide\":\"top\"},{\"id\":\"bfad0ddbfa29f18f\",\"fromNode\":\"867aca6f08aff01f\",\"fromSide\":\"bottom\",\"toNode\":\"5246f4d07c4012a8\",\"toSide\":\"top\"}]}" @@ -60,8 +60,8 @@ export const cannoliCollege = { name: "4. Reference nodes.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"546578b6fae29490\",\"x\":-420,\"y\":-160,\"width\":580,\"height\":640,\"label\":\"Reference nodes\"},{\"id\":\"8d414d7be725ce11\",\"type\":\"group\",\"x\":-420,\"y\":880,\"width\":610,\"height\":259,\"label\":\"Getting properties\"},{\"id\":\"8fd4e3f6e22304ba\",\"type\":\"group\",\"x\":-420,\"y\":560,\"width\":290,\"height\":259,\"label\":\"Getting note name\"},{\"id\":\"8c0fb44530075f7d\",\"type\":\"group\",\"x\":-420,\"y\":1200,\"width\":290,\"height\":259,\"label\":\"Getting note path\"},{\"type\":\"text\",\"text\":\"{{[Current state]}}\",\"id\":\"079588e3f7e0afa0\",\"x\":-393,\"y\":203,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Reference nodes can reference floating nodes or notes from your vault.\",\"id\":\"a8346a9d96a737bb\",\"x\":-692,\"y\":238,\"width\":262,\"height\":114},{\"type\":\"text\",\"text\":\"Reference nodes are content nodes surrounded by double curly braces.\",\"id\":\"a9ea85b101bc8776\",\"x\":-686,\"y\":-149,\"width\":250,\"height\":129},{\"type\":\"text\",\"text\":\"You can write or read from them the same way you use normal content nodes.\",\"id\":\"be5c114d263a0107\",\"x\":-686,\"y\":66,\"width\":250,\"height\":137},{\"type\":\"text\",\"text\":\"Write a poem about walking\",\"id\":\"fba8c017a84a0a74\",\"x\":-380,\"y\":-124,\"width\":250,\"height\":60,\"color\":\"0\"},{\"type\":\"text\",\"text\":\"{{[[Walking Poem]]}}\",\"id\":\"e8e998b3d784e3a1\",\"x\":-380,\"y\":6,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Reference nodes can be used to write to and read from notes in your vault or floating nodes on the cannoli.\",\"id\":\"28c071d10dfda17f\",\"x\":-333,\"y\":-340,\"width\":379,\"height\":122},{\"type\":\"text\",\"text\":\"[Current state]\\nNot much going on\",\"id\":\"e08885cd2f146f7d\",\"x\":-113,\"y\":203,\"width\":250,\"height\":92},{\"id\":\"344bb3da359269a4\",\"type\":\"text\",\"text\":\"\",\"x\":-100,\"y\":327,\"width\":237,\"height\":113,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Does this change our plan at all:\\n{{a}}\",\"id\":\"e9768515f6295d9b\",\"x\":-393,\"y\":333,\"width\":250,\"height\":100,\"color\":\"0\"},{\"id\":\"963eacfd11f92b34\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-400,\"y\":580,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"ef10f47160ceb92a\",\"type\":\"text\",\"text\":\"\",\"x\":-400,\"y\":739,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"f85bdd621bacd536\",\"type\":\"text\",\"text\":\"If a variable arrow coming from a reference node starts with a square bracket, it will extract the link for the reference.\\n\\nThis is uses in cases when you dynamically create nodes and need to get their link reliably.\",\"x\":-763,\"y\":580,\"width\":318,\"height\":239},{\"id\":\"da10ade6ef9ec7fb\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-400,\"y\":900,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"d0e83b31dc2a1576\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-90,\"y\":900,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"1566407420c6d37d\",\"type\":\"text\",\"text\":\"\",\"x\":-400,\"y\":1059,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"68e42dd6d4721f26\",\"type\":\"text\",\"text\":\"\",\"x\":-90,\"y\":1059,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"28a0281c87a0c588\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-400,\"y\":1220,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"babacacceece0d0f\",\"type\":\"text\",\"text\":\"\",\"x\":-400,\"y\":1379,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"bad9bf674fca2bfa\",\"type\":\"text\",\"text\":\"You can use arrows that start with \\\":\\\" to retrieve the associated property of the same name from a note.\\n\\nIf there is nothing on the arrow other than \\\":\\\", all properties will be retrieved. \",\"x\":-763,\"y\":900,\"width\":318,\"height\":239},{\"id\":\"b6b1e156ad3548a2\",\"type\":\"text\",\"text\":\"You can use arrows that start with \\\"/\\\" to retrieve the path of a reference node.\\n\\nThis could be useful for creating notes in the same folder as dynamically selected notes.\",\"x\":-763,\"y\":1220,\"width\":318,\"height\":219}],\"edges\":[{\"id\":\"bc3f3aa5abc3914d\",\"fromNode\":\"fba8c017a84a0a74\",\"fromSide\":\"bottom\",\"toNode\":\"e8e998b3d784e3a1\",\"toSide\":\"top\"},{\"id\":\"c98efd6bf2dff5d4\",\"fromNode\":\"079588e3f7e0afa0\",\"fromSide\":\"bottom\",\"toNode\":\"e9768515f6295d9b\",\"toSide\":\"top\",\"label\":\"a\"},{\"id\":\"20b93bd61e36c19f\",\"fromNode\":\"963eacfd11f92b34\",\"fromSide\":\"bottom\",\"toNode\":\"ef10f47160ceb92a\",\"toSide\":\"top\",\"label\":\"[\"},{\"id\":\"d1ab9632f705d309\",\"fromNode\":\"e9768515f6295d9b\",\"fromSide\":\"right\",\"toNode\":\"344bb3da359269a4\",\"toSide\":\"left\",\"color\":\"2\"},{\"id\":\"4320417bc6736dd9\",\"fromNode\":\"da10ade6ef9ec7fb\",\"fromSide\":\"bottom\",\"toNode\":\"1566407420c6d37d\",\"toSide\":\"top\",\"label\":\":Date\"},{\"id\":\"e56ac04c2a7ef6da\",\"fromNode\":\"d0e83b31dc2a1576\",\"fromSide\":\"bottom\",\"toNode\":\"68e42dd6d4721f26\",\"toSide\":\"top\",\"label\":\":\"},{\"id\":\"06d6a4450c69c049\",\"fromNode\":\"28a0281c87a0c588\",\"fromSide\":\"bottom\",\"toNode\":\"babacacceece0d0f\",\"toSide\":\"top\",\"label\":\"/\"}]}" }, - ], - "4. Vault interaction": [ +], + "4. Vault interaction": [ { name: "1. Referencing notes.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"1e30c5b622c33707\",\"x\":-700,\"y\":-160,\"width\":600,\"height\":500,\"label\":\"Reference nodes\"},{\"type\":\"group\",\"id\":\"34ab67ca730bb363\",\"x\":-700,\"y\":420,\"width\":600,\"height\":500,\"label\":\"Extraction modifiers\"},{\"type\":\"group\",\"id\":\"4b47baa584657fc0\",\"x\":-700,\"y\":-620,\"width\":650,\"height\":360,\"label\":\"Notes as variables\"},{\"id\":\"3c55aea3ab7679cf\",\"type\":\"group\",\"x\":-690,\"y\":1680,\"width\":610,\"height\":259,\"label\":\"Getting properties\"},{\"id\":\"71f82d60459605e9\",\"type\":\"group\",\"x\":-690,\"y\":1000,\"width\":290,\"height\":290,\"label\":\"Special \\\"NOTE\\\" reference\"},{\"id\":\"bc6196ed2a59141c\",\"type\":\"group\",\"x\":-690,\"y\":1360,\"width\":290,\"height\":259,\"label\":\"Getting note names\"},{\"id\":\"f5c0436b8aa42d7f\",\"type\":\"group\",\"x\":-690,\"y\":2000,\"width\":290,\"height\":259,\"label\":\"Getting note path\"},{\"type\":\"text\",\"text\":\"Check this out:\\n{{[[Lemons for Cleaning]]}}\",\"id\":\"24fc10789416284c\",\"x\":-680,\"y\":-600,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"What was in that note?\",\"id\":\"e62b59877d19a53b\",\"x\":-680,\"y\":-490,\"width\":250,\"height\":50},{\"type\":\"text\",\"text\":\"\",\"id\":\"62447884955fc816\",\"x\":-409,\"y\":-560,\"width\":349,\"height\":280,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"You can reference notes in Cannolis to give LLMs up-to-date context conveniently.\",\"id\":\"305dbf844cee4b22\",\"x\":-562,\"y\":-780,\"width\":328,\"height\":102},{\"type\":\"text\",\"text\":\"To show the LLM the content of a note, simply wrap a note link in curly braces, just as you would a variable.\",\"id\":\"9ae16a6025e83401\",\"x\":-1060,\"y\":-521,\"width\":345,\"height\":113},{\"type\":\"file\",\"file\":\"Cannoli College/Example notes/Apple Trees.md\",\"text\":\"{{[[Apple Trees]]}}\",\"id\":\"b7597d6f39e7acc9\",\"x\":-690,\"y\":-120,\"width\":283,\"height\":145},{\"type\":\"text\",\"text\":\"What's the note above about\",\"id\":\"8039b20f5e260110\",\"x\":-673,\"y\":80,\"width\":250,\"height\":80},{\"type\":\"text\",\"text\":\"What's this about:\\n{{a}}\",\"id\":\"dec28b770c6e0601\",\"x\":-359,\"y\":80,\"width\":250,\"height\":80},{\"type\":\"text\",\"text\":\"\",\"id\":\"37c33e8f19a09beb\",\"x\":-680,\"y\":-380,\"width\":250,\"height\":100,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"You can also pull the content of notes with arrows leaving Obsidian's built-in file cards.\",\"id\":\"7563d53b40bf5f1a\",\"x\":-986,\"y\":-101,\"width\":271,\"height\":126},{\"type\":\"text\",\"text\":\"The same effect can be achieved with a reference node, using this double curly brace notation in a content node.\",\"id\":\"7486aafd14a866f8\",\"x\":-80,\"y\":-103,\"width\":340,\"height\":111},{\"type\":\"text\",\"text\":\"{{[[Lemons for Cleaning]]}}\",\"id\":\"aa6a67a2ff0f2fe8\",\"x\":-359,\"y\":-77,\"width\":250,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"\",\"id\":\"a96e14fbb7d1265f\",\"x\":-673,\"y\":200,\"width\":250,\"height\":120,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"\",\"id\":\"7f19194be69549ec\",\"x\":-359,\"y\":200,\"width\":250,\"height\":120,\"color\":\"6\"},{\"id\":\"e7990bd20a1a3f11\",\"type\":\"text\",\"text\":\"{{NOTE}}\",\"x\":-670,\"y\":1020,\"width\":250,\"height\":60},{\"id\":\"da19d9eee04a6946\",\"type\":\"text\",\"text\":\"This reference node will always correspond to the active note when the cannoli was started.\\n\\nYou can use this syntax to build chatbots (see [[4. Chat arrows.cno.canvas|4. Chat arrows.cno]]) or cannolis that process the content of the active note somehow.\",\"x\":-1039,\"y\":1010,\"width\":324,\"height\":260},{\"id\":\"dd06bd8ffd8959c3\",\"type\":\"text\",\"text\":\"\",\"x\":-670,\"y\":1140,\"width\":250,\"height\":130,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"You can change how notes are extracted or edited using symbols after the note within a reference.\\n\\nThese modifiers will override the related settings you chose in the cannoli settings.\",\"id\":\"f98df3d186b6b8b3\",\"x\":-1080,\"y\":410,\"width\":365,\"height\":205},{\"id\":\"21a132196d1026bf\",\"type\":\"text\",\"text\":\"To add the filename of a note as a header, reference it like this:\\n{{[[Note]]#}}\\n\\nIf your default setting is to add the filename header, you can remove it like this:\\n{{[[Note]]!#}}\",\"x\":-1074,\"y\":660,\"width\":354,\"height\":245},{\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]^}}\",\"id\":\"10439db683a6c0a7\",\"x\":-368,\"y\":473,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"0856fc4c98e0e01c\",\"type\":\"text\",\"text\":\"To include the properties (YAML frontmatter) in the note, reference it like this:\\n{{[[Note]]^}}\\n\\nIf your default setting is to include the properties, you can remove them like this:\\n{{[[Note]]!^}}\\n\\nIf you are editing a note, this modifier will also change if the edit can affect the existing properties. This is useful if you don't want to overwrite properties when you edit a note.\",\"x\":-80,\"y\":408,\"width\":420,\"height\":342},{\"id\":\"8352e64802f9ff93\",\"type\":\"text\",\"text\":\"You can add multiple modifiers in a single reference:\\n{{[[Note]]^!#}}\",\"x\":-80,\"y\":780,\"width\":398,\"height\":120},{\"id\":\"b63aa69459ed0e33\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-670,\"y\":1380,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"d19cad0060fcb71c\",\"type\":\"text\",\"text\":\"\",\"x\":-670,\"y\":1539,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"9aff2c48988f7fdf\",\"type\":\"text\",\"text\":\"If a variable arrow coming from a reference node starts with a square bracket, it will extract the link for the reference.\\n\\nThis is uses in cases when you dynamically create nodes and need to get their link reliably.\",\"x\":-1033,\"y\":1380,\"width\":318,\"height\":239},{\"id\":\"d399962128a18b2e\",\"type\":\"text\",\"text\":\"\",\"x\":-680,\"y\":615,\"width\":268,\"height\":277,\"color\":\"6\"},{\"id\":\"919f3852d5538bac\",\"type\":\"text\",\"text\":\"\",\"x\":-377,\"y\":615,\"width\":268,\"height\":277,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]#}}\",\"id\":\"30afb34c1019f5df\",\"x\":-670,\"y\":473,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"9967b60050a55863\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-670,\"y\":1700,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"570d87dc498def43\",\"type\":\"text\",\"text\":\"\",\"x\":-670,\"y\":1859,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"94c9f6ee12de2723\",\"type\":\"text\",\"text\":\"You can use arrows that start with \\\":\\\" to retrieve the associated property of the same name from a note.\\n\\nIf there is nothing on the arrow other than \\\":\\\", all properties will be retrieved. \",\"x\":-1033,\"y\":1700,\"width\":318,\"height\":239},{\"id\":\"382cdbdf89daa53c\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-360,\"y\":1700,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"386367aa8acf2917\",\"type\":\"text\",\"text\":\"\",\"x\":-360,\"y\":1859,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"47f1774a10a6de98\",\"type\":\"text\",\"text\":\"{{[[Meeting Notes]]}}\",\"x\":-670,\"y\":2020,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"09ec11f71f736c5a\",\"type\":\"text\",\"text\":\"\",\"x\":-670,\"y\":2179,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"82df68e8b67c09c8\",\"type\":\"text\",\"text\":\"You can use arrows that start with \\\"/\\\" to retrieve the path of a reference node.\\n\\nThis could be useful for creating notes in the same folder as dynamically selected notes.\",\"x\":-1033,\"y\":2020,\"width\":318,\"height\":219}],\"edges\":[{\"id\":\"7ebbdaba21c78245\",\"fromNode\":\"24fc10789416284c\",\"fromSide\":\"right\",\"toNode\":\"62447884955fc816\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"ee4e6166d0ffe43d\",\"fromNode\":\"24fc10789416284c\",\"fromSide\":\"bottom\",\"toNode\":\"e62b59877d19a53b\",\"toSide\":\"top\"},{\"id\":\"063d6d8d083b2666\",\"fromNode\":\"b7597d6f39e7acc9\",\"fromSide\":\"bottom\",\"toNode\":\"8039b20f5e260110\",\"toSide\":\"top\"},{\"id\":\"9bcad28d8d703638\",\"fromNode\":\"aa6a67a2ff0f2fe8\",\"fromSide\":\"bottom\",\"toNode\":\"dec28b770c6e0601\",\"toSide\":\"top\",\"label\":\"a\"},{\"id\":\"ba5e154b30f8168f\",\"fromNode\":\"e62b59877d19a53b\",\"fromSide\":\"bottom\",\"toNode\":\"37c33e8f19a09beb\",\"toSide\":\"top\"},{\"id\":\"6e838ae4192a0925\",\"fromNode\":\"8039b20f5e260110\",\"fromSide\":\"bottom\",\"toNode\":\"a96e14fbb7d1265f\",\"toSide\":\"top\"},{\"id\":\"7f3f25c31ae38f6d\",\"fromNode\":\"dec28b770c6e0601\",\"fromSide\":\"bottom\",\"toNode\":\"7f19194be69549ec\",\"toSide\":\"top\"},{\"id\":\"8af2e272382f3038\",\"fromNode\":\"e7990bd20a1a3f11\",\"fromSide\":\"bottom\",\"toNode\":\"dd06bd8ffd8959c3\",\"toSide\":\"top\"},{\"id\":\"aba263db1eb0f4b6\",\"fromNode\":\"9967b60050a55863\",\"fromSide\":\"bottom\",\"toNode\":\"570d87dc498def43\",\"toSide\":\"top\",\"label\":\":Date\"},{\"id\":\"f0e0c3d61fe7aca3\",\"fromNode\":\"30afb34c1019f5df\",\"fromSide\":\"bottom\",\"toNode\":\"d399962128a18b2e\",\"toSide\":\"top\"},{\"id\":\"e137cb2b47fff78e\",\"fromNode\":\"10439db683a6c0a7\",\"fromSide\":\"bottom\",\"toNode\":\"919f3852d5538bac\",\"toSide\":\"top\"},{\"id\":\"7919954c7360c103\",\"fromNode\":\"b63aa69459ed0e33\",\"fromSide\":\"bottom\",\"toNode\":\"d19cad0060fcb71c\",\"toSide\":\"top\",\"label\":\"[\"},{\"id\":\"a149899b3a0f51b7\",\"fromNode\":\"47f1774a10a6de98\",\"fromSide\":\"bottom\",\"toNode\":\"09ec11f71f736c5a\",\"toSide\":\"top\",\"label\":\"/\"},{\"id\":\"1bb84d00af5d18f5\",\"fromNode\":\"382cdbdf89daa53c\",\"fromSide\":\"bottom\",\"toNode\":\"386367aa8acf2917\",\"toSide\":\"top\",\"label\":\":\"}]}" @@ -82,8 +82,12 @@ export const cannoliCollege = { name: "5. Referencing selections.canvas", content: "{\"nodes\":[{\"id\":\"8c02946171040e71\",\"type\":\"group\",\"x\":30,\"y\":-145,\"width\":350,\"height\":345,\"label\":\"Special \\\"SELECTION\\\" variable\"},{\"id\":\"a0047756f6bf199f\",\"type\":\"group\",\"x\":30,\"y\":280,\"width\":350,\"height\":320,\"label\":\"Replacing selections\"},{\"id\":\"28278bc5135af80c\",\"type\":\"text\",\"text\":\"Respond with a more concise version of this text:\\n{{SELECTION}}\",\"x\":75,\"y\":-125,\"width\":250,\"height\":120},{\"id\":\"9b5312d8361c2f5e\",\"type\":\"text\",\"text\":\"\",\"x\":75,\"y\":40,\"width\":250,\"height\":130,\"color\":\"6\"},{\"id\":\"6f34b064907441fd\",\"type\":\"text\",\"text\":\"This works in any workspace where you can select text, including canvas files.\\n\\nTry it on the sentence above.\",\"x\":-313,\"y\":-100,\"width\":324,\"height\":140},{\"id\":\"21dc5d31fab5298f\",\"type\":\"text\",\"text\":\"You can reference the current selection (the text highlighted by your cursor when you started the cannoli) using the {{SELECTION}} variable\",\"x\":11,\"y\":-360,\"width\":378,\"height\":142},{\"id\":\"2deb4b62d41bbfb7\",\"type\":\"text\",\"text\":\"Respond with a more concise version of this text:\\n{{SELECTION}}\",\"x\":75,\"y\":300,\"width\":250,\"height\":120},{\"id\":\"6e8591393bf5e285\",\"type\":\"text\",\"text\":\"You can write to a selection reference node just like a Note reference node. \\n\\nWriting to a {{SELECTION}} node will replace the text if there is a selection, or insert it at the cursor if there isn't.\",\"x\":-340,\"y\":325,\"width\":351,\"height\":175},{\"id\":\"880831fc3c8b5e93\",\"type\":\"text\",\"text\":\"{{SELECTION}}\",\"x\":75,\"y\":500,\"width\":250,\"height\":60,\"color\":\"6\"},{\"id\":\"c940877ff5ddd66f\",\"type\":\"text\",\"text\":\"Note that if you click away from a selection before the cannoli reaches this node, it will change where the replacement happens, so be wary of long cannolis that use this feature.\",\"x\":389,\"y\":346,\"width\":404,\"height\":133}],\"edges\":[{\"id\":\"ff57adf1f2f08d4d\",\"fromNode\":\"28278bc5135af80c\",\"fromSide\":\"bottom\",\"toNode\":\"9b5312d8361c2f5e\",\"toSide\":\"top\"},{\"id\":\"e6c1d0371468967e\",\"fromNode\":\"2deb4b62d41bbfb7\",\"fromSide\":\"bottom\",\"toNode\":\"880831fc3c8b5e93\",\"toSide\":\"top\"}]}" }, - ], - "5. Groups": [ + { + name: "6. Dataview.canvas", + content: "{\"nodes\":[{\"id\":\"abdd7f206ec179b5\",\"type\":\"group\",\"x\":-292,\"y\":2360,\"width\":926,\"height\":786,\"label\":\"Selecting notes from Dataview queries\"},{\"id\":\"866cf47b85828224\",\"type\":\"group\",\"x\":-280,\"y\":200,\"width\":901,\"height\":800,\"label\":\"Dataview Queries\"},{\"id\":\"54821284bfffa404\",\"type\":\"group\",\"x\":-280,\"y\":1240,\"width\":901,\"height\":800,\"label\":\"Embedding notes with Dataview\"},{\"id\":\"d496337fb835112d\",\"type\":\"text\",\"text\":\"Here is a dataview query:\\n```dataview\\nLIST\\nFROM #cannoliArticle\\n```\\nWhat do you think are inside these notes?\",\"x\":-237,\"y\":220,\"width\":339,\"height\":246},{\"id\":\"0a4607692e99ccc4\",\"type\":\"text\",\"text\":\"Tell me about this table\\n\\n```dataview\\nTABLE file.name,file.ctime\\nFROM #cannoliArticle\\n```\",\"x\":207,\"y\":220,\"width\":390,\"height\":255},{\"id\":\"2a540f6685096f40\",\"type\":\"text\",\"text\":\"\",\"x\":-260,\"y\":560,\"width\":385,\"height\":420,\"color\":\"6\"},{\"id\":\"4991b1a604f5b0c0\",\"type\":\"text\",\"text\":\"\",\"x\":203,\"y\":560,\"width\":398,\"height\":420,\"color\":\"6\"},{\"id\":\"86b5e262c31686a5\",\"type\":\"text\",\"text\":\"Read these notes and write a haiku about each one:\\n\\n{{\\n```dataview\\nLIST\\nFROM #cannoliArticle\\n```\\n}}\",\"x\":-237,\"y\":1260,\"width\":339,\"height\":280},{\"id\":\"e00b70c20e8b5de4\",\"type\":\"text\",\"text\":\"Read these notes and write a haiku about each one:\\n\\n{{\\n```dataview\\nLIST\\nFROM #cannoliArticle\\n```\\n!#}}\",\"x\":207,\"y\":1260,\"width\":390,\"height\":280},{\"id\":\"af6026eb8c26d15b\",\"type\":\"text\",\"text\":\"Sometimes you want the LLM to see the contents of all of the resulting links of a dataview query. To do that you can simply wrap the query in double curly brackets the way you would with a note embed. This looks better with lists than with tables.\",\"x\":-160,\"y\":1080,\"width\":680,\"height\":108},{\"id\":\"025b43bd8ffaa90d\",\"type\":\"text\",\"text\":\"Cannoli renders Dataview DQL queries so the LLM can see them. \\n\\nIf you have the Dataview plugin enabled on a vault, and there's a valid query inside of a node or embedded note, the LLM will see the results of that query as a Markdown list or table.\\n\\nDataviewJS queries are not implemented yet, but we're still working to get that in as well. (p.s. if you're reading this and have arcane dataview knowledge that might help please reach out on the repo)\",\"x\":-131,\"y\":-120,\"width\":623,\"height\":257},{\"id\":\"9c168db7948ae50a\",\"type\":\"text\",\"text\":\"\",\"x\":-260,\"y\":1600,\"width\":385,\"height\":420,\"color\":\"6\"},{\"id\":\"5fdb171ce82f69ef\",\"type\":\"text\",\"text\":\"\",\"x\":203,\"y\":1600,\"width\":398,\"height\":420,\"color\":\"6\"},{\"id\":\"ffbe198b39af63cb\",\"type\":\"text\",\"text\":\"You can use the same syntax for including or excluding note titles and properties as you can in normal note embeds. (see [[1. Referencing notes.canvas|1. Referencing notes]])\",\"x\":660,\"y\":1340,\"width\":440,\"height\":120},{\"id\":\"cdfbde60f7de0699\",\"type\":\"text\",\"text\":\"Which of these notes looks most interesting:\\n\\n```dataview\\nLIST\\nFROM #cannoliArticle\\n```\",\"x\":-272,\"y\":2380,\"width\":339,\"height\":280},{\"id\":\"e05c95af482766e8\",\"type\":\"text\",\"text\":\"\",\"x\":195,\"y\":2490,\"width\":385,\"height\":516,\"color\":\"6\"},{\"id\":\"522c7968323ab01f\",\"type\":\"text\",\"text\":\"\",\"x\":-228,\"y\":2946,\"width\":398,\"height\":160,\"color\":\"6\"},{\"id\":\"480170f0f0cf1c3d\",\"type\":\"text\",\"text\":\"Do you find this note interesting?\\n\\n{{@mostInteresting}}\",\"x\":-228,\"y\":2748,\"width\":250,\"height\":130},{\"id\":\"fe2b51ed55928420\",\"type\":\"text\",\"text\":\"You can also use the note selection syntax on arrows leaving call nodes to get the LLM to output a selection from the links it sees.\\n\\nFor more on this see [[3. Dynamic note references.canvas|3. Dynamic note references]]\",\"x\":-62,\"y\":2120,\"width\":503,\"height\":160}],\"edges\":[{\"id\":\"2ebd28fb6c5c101d\",\"fromNode\":\"d496337fb835112d\",\"fromSide\":\"bottom\",\"toNode\":\"2a540f6685096f40\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"8ee71d334a61b7db\",\"fromNode\":\"0a4607692e99ccc4\",\"fromSide\":\"bottom\",\"toNode\":\"4991b1a604f5b0c0\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"a9b3dffa5e282eac\",\"fromNode\":\"86b5e262c31686a5\",\"fromSide\":\"bottom\",\"toNode\":\"9c168db7948ae50a\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"a7d1263d7926e2df\",\"fromNode\":\"e00b70c20e8b5de4\",\"fromSide\":\"bottom\",\"toNode\":\"5fdb171ce82f69ef\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"c66428ad3bf6bee0\",\"fromNode\":\"480170f0f0cf1c3d\",\"fromSide\":\"right\",\"toNode\":\"e05c95af482766e8\",\"toSide\":\"left\",\"color\":\"2\"},{\"id\":\"dc0fdfc897e3f0d4\",\"fromNode\":\"cdfbde60f7de0699\",\"fromSide\":\"bottom\",\"toNode\":\"480170f0f0cf1c3d\",\"toSide\":\"top\",\"label\":\"[mostInteresting\"},{\"id\":\"5c40358a63c8ae10\",\"fromNode\":\"480170f0f0cf1c3d\",\"fromSide\":\"bottom\",\"toNode\":\"522c7968323ab01f\",\"toSide\":\"top\"}]}" + }, +], + "5. Groups": [ { name: "1. Basic groups.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"3507f53b8ef19875\",\"x\":-400,\"y\":-280,\"width\":610,\"height\":940,\"label\":\"Basic Groups\"},{\"type\":\"group\",\"id\":\"9ea4603066155724\",\"x\":-100,\"y\":-220,\"width\":290,\"height\":273,\"label\":\"Group 1\"},{\"type\":\"group\",\"id\":\"9d076987e99ce6a6\",\"x\":-100,\"y\":260,\"width\":290,\"height\":240,\"label\":\"Group 2\"},{\"type\":\"text\",\"text\":\"Hey what model are you?\",\"id\":\"554b1577865f24d4\",\"x\":-80,\"y\":280,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"Actually you don't know that.\",\"id\":\"35881fd57b1d4269\",\"x\":-80,\"y\":420,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"\",\"id\":\"fd9b2131408190a4\",\"x\":-80,\"y\":520,\"width\":250,\"height\":120,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"gpt-4\",\"id\":\"e7d78cc1a7a948f8\",\"x\":-320,\"y\":250,\"width\":105,\"height\":60,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Rubiks cube\",\"id\":\"e83b4c5b2409b738\",\"x\":-370,\"y\":-163,\"width\":180,\"height\":57,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Here we use a basic group to provide all of the member nodes with a variable.\",\"id\":\"1354395dbba49c59\",\"x\":-700,\"y\":-163,\"width\":290,\"height\":93},{\"type\":\"text\",\"text\":\"Basic groups allow you to conveniently provide variables or change config settings of multiple nodes.\\n\\nFunctionally, its the same as drawing arrows to every node in the group.\",\"id\":\"cb4e55a56aa20105\",\"x\":-320,\"y\":-500,\"width\":423,\"height\":170},{\"type\":\"text\",\"text\":\"Groups whose label is not an integer are basic groups.\",\"id\":\"ad8c877c4bdbc784\",\"x\":-298,\"y\":-620,\"width\":380,\"height\":94},{\"type\":\"text\",\"text\":\"You can use {{a}} in this node\",\"id\":\"3f724ea642f3f39d\",\"x\":-80,\"y\":-200,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"And you can use {{a}} in this node\",\"id\":\"6b128a864045c0e7\",\"x\":-80,\"y\":-27,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"\",\"id\":\"b6f9f0b26ae8e68e\",\"x\":-80,\"y\":80,\"width\":250,\"height\":100,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"Here we change the model config setting of all the member nodes of a group.\",\"id\":\"e58e6effa966f52b\",\"x\":-728,\"y\":242,\"width\":318,\"height\":98}],\"edges\":[{\"id\":\"3986f98e5c79c58a\",\"fromNode\":\"e83b4c5b2409b738\",\"fromSide\":\"right\",\"toNode\":\"9ea4603066155724\",\"toSide\":\"left\",\"label\":\"a\"},{\"id\":\"b54add99d36d3b53\",\"fromNode\":\"e7d78cc1a7a948f8\",\"fromSide\":\"right\",\"toNode\":\"9d076987e99ce6a6\",\"toSide\":\"left\",\"color\":\"2\",\"label\":\"model\"},{\"id\":\"3ec08b096671959f\",\"fromNode\":\"3f724ea642f3f39d\",\"fromSide\":\"bottom\",\"toNode\":\"6b128a864045c0e7\",\"toSide\":\"top\"},{\"id\":\"71449d8dc3ac9bac\",\"fromNode\":\"6b128a864045c0e7\",\"fromSide\":\"bottom\",\"toNode\":\"b6f9f0b26ae8e68e\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"b2ca430257741d71\",\"fromNode\":\"554b1577865f24d4\",\"fromSide\":\"bottom\",\"toNode\":\"35881fd57b1d4269\",\"toSide\":\"top\"},{\"id\":\"948da6eeffd07b7e\",\"fromNode\":\"35881fd57b1d4269\",\"fromSide\":\"bottom\",\"toNode\":\"fd9b2131408190a4\",\"toSide\":\"top\",\"color\":\"2\"}]}" @@ -96,15 +100,15 @@ export const cannoliCollege = { name: "3. Loop group features.canvas", content: "{\"nodes\":[{\"type\":\"group\",\"id\":\"cd5aefdec24485a6\",\"x\":-395,\"y\":920,\"width\":1200,\"height\":1187,\"label\":\"Conditional loop groups\"},{\"type\":\"group\",\"id\":\"b41f5d77d2587137\",\"x\":-215,\"y\":-344,\"width\":840,\"height\":948,\"label\":\"Feedback variables\"},{\"type\":\"group\",\"id\":\"a8db6171d1ed7037\",\"x\":-375,\"y\":987,\"width\":680,\"height\":1040,\"label\":\"3\"},{\"type\":\"group\",\"id\":\"308eacb6bc673cc4\",\"x\":5,\"y\":-136,\"width\":290,\"height\":240,\"label\":\"3\"},{\"type\":\"text\",\"text\":\"Crisp shell, sweet delight, Ricotta whispers within, Sicily's soft night.\",\"id\":\"8bd344c2d351a946\",\"x\":25,\"y\":-324,\"width\":250,\"height\":100,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"If a variable edge is pointing from a group member to the group itself, this variable will be accessible on subsequent loops. (This is an exception to the rule that the Cannoli must be a DAG)\",\"id\":\"69c0aa7ba528fd7f\",\"x\":25,\"y\":-604,\"width\":378,\"height\":187},{\"type\":\"text\",\"text\":\"Critique this haiku:\\n{{a}}\",\"id\":\"4522c0d5f13ecbf2\",\"x\":25,\"y\":-104,\"width\":250,\"height\":60},{\"type\":\"text\",\"text\":\"Respond with a rewrite. Nothing else should be in your response.\",\"id\":\"08d62752b952d1b9\",\"x\":25,\"y\":-14,\"width\":250,\"height\":90},{\"type\":\"text\",\"text\":\"If there are multiple available arrows with the same name, the node will prefer the self-group-pointing one.\\n\\nYou can use this to pre-load variables with an initial version for the first loop, which will be written over in later loops.\",\"id\":\"1547e2e1c8e36e01\",\"x\":-625,\"y\":-214,\"width\":390,\"height\":221},{\"type\":\"text\",\"text\":\"This is an example of a rewrite loop, where we have the LLM rewrite a piece of content several times and output the final result.\",\"id\":\"39f5077b01de86bc\",\"x\":-618,\"y\":215,\"width\":383,\"height\":121},{\"type\":\"text\",\"text\":\"\",\"id\":\"0209622577e4d8e4\",\"x\":-195,\"y\":196,\"width\":270,\"height\":205,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"\",\"id\":\"a8c82e1399aa0667\",\"x\":144,\"y\":217,\"width\":461,\"height\":367,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"If a loop group has incoming arrows from within itself, it will only loop if they are all activated.\\n\\nThis means you can use choice arrows to create groups that stop looping based on a decision the LLM makes.\",\"id\":\"109c6d143c904ac2\",\"x\":-40,\"y\":700,\"width\":559,\"height\":153},{\"type\":\"text\",\"text\":\"Are there any obvious improvements to this article?\\n\\n{{article}}\",\"id\":\"c9ac27366825fb46\",\"x\":-271,\"y\":1327,\"width\":283,\"height\":122},{\"type\":\"text\",\"text\":\"What would you change?\",\"id\":\"42e65836e7bc0d2d\",\"x\":-254,\"y\":1540,\"width\":250,\"height\":60},{\"type\":\"file\",\"file\":\"Cannoli College/Example notes/Lemons for Cleaning.md\",\"text\":\"{{[[Lemons for Cleaning]]}}\",\"id\":\"9b09ade8a96fdc49\",\"x\":-330,\"y\":1025,\"width\":400,\"height\":203},{\"type\":\"text\",\"text\":\"In this example, we use choice arrows to have the LLM decide whether to edit a note.\\n\\nThe decision to edit it activates a path that points to the group itself, so the group will loop again once it is done.\\n\\nIf that path is rejected, the group will not loop again.\",\"id\":\"3ae1b1035e633274\",\"x\":-814,\"y\":1228,\"width\":402,\"height\":259},{\"type\":\"text\",\"text\":\"Respond with a rewrite based on your feedback.\",\"id\":\"92dee3525bb5528a\",\"x\":-289,\"y\":1660,\"width\":320,\"height\":100},{\"type\":\"text\",\"text\":\"\",\"id\":\"65d12403b1902562\",\"x\":120,\"y\":1328,\"width\":165,\"height\":121,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"\",\"id\":\"c19decb87eb68f4e\",\"x\":340,\"y\":1443,\"width\":440,\"height\":535,\"color\":\"6\"},{\"type\":\"text\",\"text\":\"It doesn't matter what the node pointing at the group is, or what kind of arrow. In this case we use a blank arrow to signal that the rewrite path was chosen and add the chat history suppression suffix (~) so we don't continue the conversation in the next loop.\",\"id\":\"07a8d464729bd7db\",\"x\":-800,\"y\":1864,\"width\":388,\"height\":196},{\"type\":\"file\",\"file\":\"Cannoli College/Example notes/Lemons for Cleaning.md\",\"text\":\"{{[[Lemons for Cleaning]]}}\",\"id\":\"a447b4af7f9b59af\",\"x\":-329,\"y\":1820,\"width\":400,\"height\":180}],\"edges\":[{\"id\":\"98bface3c4272939\",\"fromNode\":\"08d62752b952d1b9\",\"fromSide\":\"right\",\"toNode\":\"308eacb6bc673cc4\",\"toSide\":\"right\",\"label\":\"a\"},{\"id\":\"01117e93ffd16810\",\"fromNode\":\"8bd344c2d351a946\",\"fromSide\":\"bottom\",\"toNode\":\"4522c0d5f13ecbf2\",\"toSide\":\"top\",\"label\":\"a\"},{\"id\":\"4705bd8c3ac7a1dd\",\"fromNode\":\"4522c0d5f13ecbf2\",\"fromSide\":\"bottom\",\"toNode\":\"08d62752b952d1b9\",\"toSide\":\"top\"},{\"id\":\"09153b08d8afc249\",\"fromNode\":\"08d62752b952d1b9\",\"fromSide\":\"bottom\",\"toNode\":\"0209622577e4d8e4\",\"toSide\":\"top\"},{\"id\":\"d74b679a0e9c5a8e\",\"fromNode\":\"08d62752b952d1b9\",\"fromSide\":\"bottom\",\"toNode\":\"a8c82e1399aa0667\",\"toSide\":\"top\",\"color\":\"2\"},{\"id\":\"313f7dba1ac082e7\",\"fromNode\":\"a447b4af7f9b59af\",\"fromSide\":\"bottom\",\"toNode\":\"a8db6171d1ed7037\",\"toSide\":\"bottom\",\"label\":\"~\"},{\"id\":\"ae86725de62f454c\",\"fromNode\":\"92dee3525bb5528a\",\"fromSide\":\"right\",\"toNode\":\"c19decb87eb68f4e\",\"toSide\":\"left\",\"color\":\"2\"},{\"id\":\"28dd5bf26534621f\",\"fromNode\":\"9b09ade8a96fdc49\",\"fromSide\":\"bottom\",\"toNode\":\"c9ac27366825fb46\",\"toSide\":\"top\",\"label\":\"article\"},{\"id\":\"cb414a8bed4cab51\",\"fromNode\":\"c9ac27366825fb46\",\"fromSide\":\"bottom\",\"toNode\":\"42e65836e7bc0d2d\",\"toSide\":\"top\",\"color\":\"3\",\"label\":\"yes\"},{\"id\":\"8e14d432eb6409d9\",\"fromNode\":\"c9ac27366825fb46\",\"fromSide\":\"right\",\"toNode\":\"65d12403b1902562\",\"toSide\":\"left\",\"color\":\"3\",\"label\":\"no\"},{\"id\":\"e151468f90fae46f\",\"fromNode\":\"42e65836e7bc0d2d\",\"fromSide\":\"bottom\",\"toNode\":\"92dee3525bb5528a\",\"toSide\":\"top\"},{\"id\":\"e9279e94dd7a9109\",\"fromNode\":\"92dee3525bb5528a\",\"fromSide\":\"bottom\",\"toNode\":\"a447b4af7f9b59af\",\"toSide\":\"top\"}]}" }, - ], - "Example notes": [ +], + "Example notes": [ { name: "Apple Trees.md", - content: "Apple trees, scientifically known as *Malus domestica*, are not just providers of one of the world's most consumed fruits but are also a model of efficiency and adaptability. Originating in Central Asia, these trees have been cultivated for thousands of years and have adapted to a variety of climates, from temperate to sub-tropical. The tree's rootstock can often be grafted to optimize for disease resistance, soil compatibility, or fruit yield, a testament to its remarkable genetic flexibility.\n\nThe life cycle of an apple tree involves a series of well-coordinated biological events. After the cold dormancy of winter, apple trees enter a phase of bud break in the spring, followed by flowering and pollination. Apple trees are usually not self-pollinating and require cross-pollination from another apple tree of a different variety. This ensures genetic diversity, which is crucial for the tree's adaptability and long-term survival. Post-pollination, the tree focuses on fruit development, channeling nutrients and energy into the growing apples.\n\nApple trees also have a profound impact on ecosystems. They offer habitat and food sources for various species, including but not limited to, bees, birds, and small mammals. Their flowers provide nectar for bees, aiding in the process of pollination for not just apple trees but other plants in the ecosystem. Their leaves and bark offer shelter and their fallen fruits are a food source for multiple ground-dwelling organisms. \n\nHowever, it's worth considering the impact of monoculture and industrial farming practices on apple trees. While these methods might increase short-term yield, they can also make the trees more susceptible to diseases and pests by reducing genetic diversity. This opens up a discourse on the need for more sustainable and diversified farming practices. In a world that's increasingly facing the brunt of climate change and biodiversity loss, the apple tree stands as a symbol of both the possibilities and responsibilities that come with cultivation.\n" + content: "---\ntags:\n - cannoliArticle\n---\nApple trees, scientifically known as *Malus domestica*, are not just providers of one of the world's most consumed fruits but are also a model of efficiency and adaptability. Originating in Central Asia, these trees have been cultivated for thousands of years and have adapted to a variety of climates, from temperate to sub-tropical. The tree's rootstock can often be grafted to optimize for disease resistance, soil compatibility, or fruit yield, a testament to its remarkable genetic flexibility.\n\nThe life cycle of an apple tree involves a series of well-coordinated biological events. After the cold dormancy of winter, apple trees enter a phase of bud break in the spring, followed by flowering and pollination. Apple trees are usually not self-pollinating and require cross-pollination from another apple tree of a different variety. This ensures genetic diversity, which is crucial for the tree's adaptability and long-term survival. Post-pollination, the tree focuses on fruit development, channeling nutrients and energy into the growing apples.\n\nApple trees also have a profound impact on ecosystems. They offer habitat and food sources for various species, including but not limited to, bees, birds, and small mammals. Their flowers provide nectar for bees, aiding in the process of pollination for not just apple trees but other plants in the ecosystem. Their leaves and bark offer shelter and their fallen fruits are a food source for multiple ground-dwelling organisms. \n\nHowever, it's worth considering the impact of monoculture and industrial farming practices on apple trees. While these methods might increase short-term yield, they can also make the trees more susceptible to diseases and pests by reducing genetic diversity. This opens up a discourse on the need for more sustainable and diversified farming practices. In a world that's increasingly facing the brunt of climate change and biodiversity loss, the apple tree stands as a symbol of both the possibilities and responsibilities that come with cultivation.\n" }, { name: "Lemons for Cleaning.md", - content: "Cleaning your home with lemons is not only effective but also environmentally friendly. Lemons, with their natural disinfecting properties and high citric acid content, can tackle a wide range of cleaning tasks. Here are some detailed tips to maximize the cleaning power of lemons:\n\n1. All-Purpose Cleaner: Create a potent all-purpose cleaner by mixing equal parts lemon juice and water. Lemons contain citric acid, which is effective in killing germs, bacteria, and odors. Squeeze the juice of fresh lemons into a spray bottle, adding an equal amount of water. Shake the bottle well to thoroughly blend the solution. This natural disinfectant is perfect for countertops, sinks, cutting boards, and food containers. To use, simply spray the solution onto the surface and let it sit for a few minutes to allow the citric acid to work its magic. Then, scrub with a sponge or cloth and rinse thoroughly with water.\n\n2. Streak-Free Glass Cleaner: Make your glass surfaces shine with a lemon-based glass cleaner. In a spray bottle, mix equal parts lemon juice and water. The acidity of lemons helps break down dirt and grime, while the natural oils leave a streak-free finish. For tougher stains or spots, add a small amount of vinegar. Shake the bottle well to ensure the ingredients are evenly mixed. To use the cleaner, spray the solution onto the glass surface and use a lint-free cloth or newspaper to wipe it clean. Begin wiping from the top to prevent streaks. Allow the solution to sit on stubborn spots for a few minutes before wiping them away.\n\n3. Eliminating Stains on Faucets and Fixtures: Bid farewell to stains on faucets and fixtures with the natural power of lemons. Cut a lemon in half and rub it directly onto the affected areas, focusing on the stains. The citric acid in lemons effectively breaks down stains while the natural oils give a polished look. After thoroughly rubbing the lemon onto the surface, rinse it with water to remove any residue. Finally, use a dry cloth to polish the faucets and fixtures for a gleaming finish.\n\n4. Rust and Hard Water Stain Remover: Lemons excel at tackling rust and hard water stains. To remove these stubborn stains, dip a cloth or sponge into fresh lemon juice and scrub the affected areas such as faucets, showerheads, or stainless steel appliances. The acidic properties of lemons help dissolve the stains effortlessly. For tougher stains, sprinkle a little salt on the lemon before scrubbing. The salt acts as an abrasive agent. After scrubbing, rinse well with water and dry the surface to prevent further rusting.\n\n5. Natural Air Freshener: Create an inviting and refreshing atmosphere in your home using lemon juice. In a spray bottle, mix lemon juice, water, and a few drops of your favorite essential oil. Lemons have a fresh, citrus scent that naturally eliminates unwanted odors, while the essential oil adds a pleasant fragrance of your choice. Shake the bottle well to ensure the ingredients are properly blended. Spritz this delightful blend around your living spaces to naturally freshen the air. The pleasant, lemony fragrance will replace unwanted odors and create a beautifully scented environment.\n\n6. Polishing and Shining: Lemons can also act as a natural polish for various surfaces. To restore the shine to hardwood furniture, brass, or copper items, cut a lemon in half and dip it into a small amount of salt. Gently rub the lemon onto the surface, allowing the salt and lemon juice to lift dirt and tarnish. The abrasive action of the salt combined with the citric acid helps restore the natural beauty and shine of the items. Rinse the item with water and buff with a soft cloth to reveal the brilliant shine.\n\nBy following these comprehensive tips, you can harness the full cleaning power of lemons to keep your home fresh, sparkling, and free from bacteria and stains. Say goodbye to harsh chemicals and embrace the natural brilliance of lemons. Happy cleaning!" + content: "---\ntags:\n - cannoliArticle\n---\nCleaning your home with lemons is not only effective but also environmentally friendly. Lemons, with their natural disinfecting properties and high citric acid content, can tackle a wide range of cleaning tasks. Here are some detailed tips to maximize the cleaning power of lemons:\n\n1. All-Purpose Cleaner: Create a potent all-purpose cleaner by mixing equal parts lemon juice and water. Lemons contain citric acid, which is effective in killing germs, bacteria, and odors. Squeeze the juice of fresh lemons into a spray bottle, adding an equal amount of water. Shake the bottle well to thoroughly blend the solution. This natural disinfectant is perfect for countertops, sinks, cutting boards, and food containers. To use, simply spray the solution onto the surface and let it sit for a few minutes to allow the citric acid to work its magic. Then, scrub with a sponge or cloth and rinse thoroughly with water.\n\n2. Streak-Free Glass Cleaner: Make your glass surfaces shine with a lemon-based glass cleaner. In a spray bottle, mix equal parts lemon juice and water. The acidity of lemons helps break down dirt and grime, while the natural oils leave a streak-free finish. For tougher stains or spots, add a small amount of vinegar. Shake the bottle well to ensure the ingredients are evenly mixed. To use the cleaner, spray the solution onto the glass surface and use a lint-free cloth or newspaper to wipe it clean. Begin wiping from the top to prevent streaks. Allow the solution to sit on stubborn spots for a few minutes before wiping them away.\n\n3. Eliminating Stains on Faucets and Fixtures: Bid farewell to stains on faucets and fixtures with the natural power of lemons. Cut a lemon in half and rub it directly onto the affected areas, focusing on the stains. The citric acid in lemons effectively breaks down stains while the natural oils give a polished look. After thoroughly rubbing the lemon onto the surface, rinse it with water to remove any residue. Finally, use a dry cloth to polish the faucets and fixtures for a gleaming finish.\n\n4. Rust and Hard Water Stain Remover: Lemons excel at tackling rust and hard water stains. To remove these stubborn stains, dip a cloth or sponge into fresh lemon juice and scrub the affected areas such as faucets, showerheads, or stainless steel appliances. The acidic properties of lemons help dissolve the stains effortlessly. For tougher stains, sprinkle a little salt on the lemon before scrubbing. The salt acts as an abrasive agent. After scrubbing, rinse well with water and dry the surface to prevent further rusting.\n\n5. Natural Air Freshener: Create an inviting and refreshing atmosphere in your home using lemon juice. In a spray bottle, mix lemon juice, water, and a few drops of your favorite essential oil. Lemons have a fresh, citrus scent that naturally eliminates unwanted odors, while the essential oil adds a pleasant fragrance of your choice. Shake the bottle well to ensure the ingredients are properly blended. Spritz this delightful blend around your living spaces to naturally freshen the air. The pleasant, lemony fragrance will replace unwanted odors and create a beautifully scented environment.\n\n6. Polishing and Shining: Lemons can also act as a natural polish for various surfaces. To restore the shine to hardwood furniture, brass, or copper items, cut a lemon in half and dip it into a small amount of salt. Gently rub the lemon onto the surface, allowing the salt and lemon juice to lift dirt and tarnish. The abrasive action of the salt combined with the citric acid helps restore the natural beauty and shine of the items. Rinse the item with water and buff with a soft cloth to reveal the brilliant shine.\n\nBy following these comprehensive tips, you can harness the full cleaning power of lemons to keep your home fresh, sparkling, and free from bacteria and stains. Say goodbye to harsh chemicals and embrace the natural brilliance of lemons. Happy cleaning!" }, { name: "Meeting Notes.md", @@ -114,5 +118,5 @@ export const cannoliCollege = { name: "Walking Poem.md", content: "In the early dawn, when daylight gleams,\nA journey begins, a walk to dream.\nFootsteps upon the earth’s embrace,\nInto the boundless, open space.\n\nBeneath the azure canopy above,\nGuided by whispers of a gentle dove.\nMy soul alights with each tranquil stride,\nBound to the world, I’m opened wide.\n\nThrough groves and meadows, I wander free,\nThe earth, my canvas, my muse, you see.\nAs daisies sway, and the willows weep,\nI find solace in footsteps, slow and deep.\n\nThrough cobbled streets of history,\nI stroll amongst tales of reverie.\nThe past’s echoes guide my way,\nUnveiling lost stories of yesterday.\n\nFootprints on sand, near the ocean's shore,\nSoft whispers of waves, beguiling more.\nThe salty breeze upon my face,\nA dance of nature, in this sacred place.\n\nUp slopes and mountains, I ascend,\nEager to conquer, to transcend.\nWith each steep climb, my spirit soars,\nCloaked by nature's abundant doors.\n\nThrough crowded cities, I navigate,\nObscured by chaos, yet radiate\nA sense of peace, a tranquil grace,\nFostering moments, without a chase.\n\nInto the woods, where silence bloomed,\nUnderneath arboreal canopy, assumed.\nWhispers of leaves, in serenade,\nA sacred symphony, nature's accolade.\n\nWalking through life, step by step,\nEach footfall closer, as dreams intercept.\nTrusting the path, as it twists and turns,\nWith newfound knowledge, my spirit yearns.\n\nFor walking uncovers hidden truth,\nAs thoughts diffuse, my heart finds youth.\nIt is in motion that I discover,\nThe world and myself, forever uncover.\n\nSo embark on journeys, in each new day,\nFor walking provides solace, come what may.\nTake time to marvel, to breathe and roam,\nFor in the rhythm of footsteps, we find our home." }, - ], +], }; diff --git a/src/providers.ts b/src/providers.ts index f4c4632..5a63f87 100644 --- a/src/providers.ts +++ b/src/providers.ts @@ -202,12 +202,14 @@ export class LLMProvider { apiKey: config.apiKey, model: config.model, temperature: config.temperature, + maxRetries: 3, }); case "groq": return new ChatGroq({ apiKey: config.apiKey, model: config.model, temperature: config.temperature, + maxRetries: 3, }); default: throw new Error("Unsupported provider"); diff --git a/src/run.ts b/src/run.ts index 14a2684..d235464 100644 --- a/src/run.ts +++ b/src/run.ts @@ -1236,27 +1236,52 @@ export class Run { */ async replaceDataviewQueries(content: string): Promise { let newContent = content; - const dataviewRegex = /(\{\{\n)?```dataview\n([\s\S]*?)\n```\n?(}})?/g; + // Regex to capture the entire block and any modifiers after the code block + const blockRegex = /(\{\{\s*)?```dataview\s*([\s\S]*?)```(\s*\n)?(\s*[^}]*)(\s*}})?/g; const dvApi = getAPI(this.cannoli.app); if (dvApi) { let match; - while ((match = dataviewRegex.exec(content)) !== null) { + while ((match = blockRegex.exec(content)) !== null) { const fullBlock = match[0]; - const doubleBraced = match[1] && match[3]; // Check if both opening and closing braces are present + const doubleBraced = match[1] && match[5]; const query = match[2].trim(); + const postCodeModifiers = match[4].trim(); // Capture any modifiers after the code block const dvContent = await dvApi.queryMarkdown(query); if (dvContent.successful) { let resultContent = dvContent.value; + // Initialize settings with an assumption to not include anything unless specified + let includeName = false; + let includeProperties = false; + + // First check for explicit disabling, prioritized over enabling + if (postCodeModifiers.includes('!#')) { + includeName = false; + } else if (postCodeModifiers.includes('#')) { + includeName = true; + } else { + // If no explicit modifiers, fallback to default setting + includeName = this.cannoli.settings.includeFilenameAsHeader; + } + + if (postCodeModifiers.includes('!^')) { + includeProperties = false; + } else if (postCodeModifiers.includes('^')) { + includeProperties = true; + } else { + // If no explicit modifiers, fallback to default setting + includeProperties = this.cannoli.settings.includePropertiesInExtractedNotes; + } + // Replace markdown links with contents from getNote if the query block was double-braced if (doubleBraced) { - resultContent = await this.replaceLinks(resultContent); + resultContent = await this.replaceLinks(resultContent, includeName, includeProperties); } - // Remove list formatting if we've replaced links + // Remove list formatting if links were replaced if (doubleBraced) { resultContent = this.removeListFormatting(resultContent); } @@ -1269,34 +1294,32 @@ export class Run { return newContent; } - // Helper function to replace all markdown links with their corresponding note contents - async replaceLinks(resultContent: string): Promise { + + + async replaceLinks(resultContent: string, includeName: boolean, includeProperties: boolean): Promise { const linkRegex = /\[\[([^\]]+)\]\]/g; let processedContent = ""; let lastIndex = 0; let match; while ((match = linkRegex.exec(resultContent)) !== null) { - // Append text between last link and this one processedContent += resultContent.substring(lastIndex, match.index); - // Create a new reference object for the note const reference = { name: match[1], type: ReferenceType.Note, shouldExtract: true, - includeName: true, + includeName: includeName, + includeProperties: includeProperties }; const noteContent = await this.getNote(reference); processedContent += noteContent + "\n\n"; // Add newline for spacing lastIndex = match.index + match[0].length; } - // Append any remaining text after the last link processedContent += resultContent.substring(lastIndex); return processedContent; } - // Function to remove markdown list formatting removeListFormatting(text: string): string { return text.replace(/^\s*-\s*/gm, ''); } @@ -1305,6 +1328,7 @@ export class Run { + // Attempting to replace dataviewjs queries // const dataviewsjs = newContent.match( // /```dataviewjs\n([\s\S]*?)\n```/g