| { |
| "cells": [ |
| { |
| "cell_type": "markdown", |
| "id": "4bb251de-463e-4156-bcfc-9078721f6a8b", |
| "metadata": {}, |
| "source": [ |
| "# Imports" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 1, |
| "id": "0ae4a1f2-c40c-4c97-9c98-e8e1152a3f95", |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "from typing import List, Tuple, Optional\n", |
| "\n", |
| "import joblib\n", |
| "import openai\n", |
| "from joblib import parallel_config\n", |
| "\n", |
| "from burr.core import Application, ApplicationBuilder, Condition, State, action\n", |
| "from burr.core.application import ApplicationContext\n", |
| "from burr.tracking import LocalTrackingClient" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "id": "d3e64255-0154-496b-b1cd-7821789e05b0", |
| "metadata": {}, |
| "source": [ |
| "# Helper functions" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 2, |
| "id": "5d45a62a-3432-4159-a1a2-703ef8d91d3b", |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "def _query_llm(prompt: str) -> str:\n", |
| " \"\"\"Simple wrapper around the OpenAI API.\"\"\"\n", |
| " client = openai.Client()\n", |
| " return (\n", |
| " client.chat.completions.create(\n", |
| " model=\"gpt-4o\",\n", |
| " messages=[\n", |
| " {\"role\": \"system\", \"content\": \"You are a helpful assistant\"},\n", |
| " {\"role\": \"user\", \"content\": prompt},\n", |
| " ],\n", |
| " )\n", |
| " .choices[0]\n", |
| " .message.content\n", |
| " )" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "id": "91a4a439-9d5e-4e6d-b287-0532abd3c19e", |
| "metadata": {}, |
| "source": [ |
| "# Sub Application\n", |
| "\n", |
| "First let's write a sub-application. We're going to have it do two things:\n", |
| "\n", |
| "1. Write a poem (`write`)\n", |
| "2. Provide suggestions (`edit`)\n", |
| "\n", |
| "We're going to wrap its creation in a function so we can create it within an application. Note that we pass in `__context` -- this allows us to wire the context through for tracking." |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 3, |
| "id": "ce9afd4c-986a-4d19-b72a-67c1b2b7fa34", |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "@action(\n", |
| " reads=[\"feedback\", \"current_draft\", \"poem_type\", \"prompt\"],\n", |
| " writes=[\"current_draft\", \"draft_history\", \"num_drafts\"],\n", |
| ")\n", |
| "def write(state: State) -> Tuple[dict, State]:\n", |
| " \"\"\"Writes a draft of a poem.\"\"\"\n", |
| " poem_subject = state[\"prompt\"]\n", |
| " poem_type = state[\"poem_type\"]\n", |
| " current_draft = state.get(\"current_draft\")\n", |
| " feedback = state.get(\"feedback\")\n", |
| "\n", |
| " parts = [\n", |
| " f'You are an AI poet. Create a {poem_type} poem on the following subject: \"{poem_subject}\".'\n", |
| " ]\n", |
| "\n", |
| " if current_draft:\n", |
| " parts.append(f'Here is the current draft of the poem: \"{current_draft}\".')\n", |
| "\n", |
| " if feedback:\n", |
| " parts.append(f'Please incorporate the following feedback: \"{feedback}\".')\n", |
| "\n", |
| " parts.append(\n", |
| " f\"Ensure the poem is creative, adheres to the style of a {poem_type}, and improves upon the previous draft.\"\n", |
| " )\n", |
| "\n", |
| " prompt = \"\\n\".join(parts)\n", |
| "\n", |
| " draft = _query_llm(prompt)\n", |
| "\n", |
| " return {\"draft\": draft}, state.update(\n", |
| " current_draft=draft,\n", |
| " draft_history=state.get(\"draft_history\", []) + [draft],\n", |
| " ).increment(num_drafts=1)\n", |
| "\n", |
| "\n", |
| "@action(reads=[\"current_draft\", \"poem_type\", \"prompt\"], writes=[\"feedback\"])\n", |
| "def edit(state: State) -> Tuple[dict, State]:\n", |
| " \"\"\"Edits a draft of a poem, providing feedback\"\"\"\n", |
| " poem_subject = state[\"prompt\"]\n", |
| " poem_type = state[\"poem_type\"]\n", |
| " current_draft = state[\"current_draft\"]\n", |
| "\n", |
| " prompt = f\"\"\"\n", |
| " You are an AI poetry critic. Review the following {poem_type} poem based on the subject: \"{poem_subject}\".\n", |
| " Here is the current draft of the poem: \"{current_draft}\".\n", |
| " Provide detailed feedback to improve the poem. If the poem is already excellent and needs no changes, simply respond with an empty string.\n", |
| " \"\"\"\n", |
| "\n", |
| " feedback = _query_llm(prompt)\n", |
| "\n", |
| " return {\"feedback\": feedback}, state.update(feedback=feedback)\n", |
| "\n", |
| "\n", |
| "@action(reads=[\"current_draft\"], writes=[\"final_draft\"])\n", |
| "def final_draft(state: State) -> Tuple[dict, State]:\n", |
| " return {\"final_draft\": state[\"current_draft\"]}, state.update(final_draft=state[\"current_draft\"])\n", |
| "\n", |
| "\n", |
| "def _create_sub_application(\n", |
| " max_num_drafts: int,\n", |
| " spawning_application_context: Optional[ApplicationContext],\n", |
| " poem_type: str,\n", |
| " prompt: str,\n", |
| ") -> Application:\n", |
| " \"\"\"Utility to create sub-application -- note\"\"\"\n", |
| " builder = (\n", |
| " ApplicationBuilder()\n", |
| " .with_actions(\n", |
| " edit,\n", |
| " write,\n", |
| " final_draft,\n", |
| " )\n", |
| " .with_transitions(\n", |
| " (\"write\", \"edit\", Condition.expr(f\"num_drafts < {max_num_drafts}\")),\n", |
| " (\"write\", \"final_draft\"),\n", |
| " (\"edit\", \"final_draft\", Condition.expr(\"len(feedback) == 0\")),\n", |
| " (\"edit\", \"write\"),\n", |
| " )\n", |
| " .with_entrypoint(\"write\")\n", |
| " .with_state(\n", |
| " current_draft=None,\n", |
| " poem_type=poem_type,\n", |
| " prompt=prompt,\n", |
| " feedback=None,\n", |
| " )\n", |
| " )\n", |
| " # so we can run without it\n", |
| " if spawning_application_context:\n", |
| " builder=(\n", |
| " builder\n", |
| " .with_tracker(spawning_application_context.tracker.copy()) # remember to do `copy()` here!\n", |
| " .with_spawning_parent(\n", |
| " spawning_application_context.app_id,\n", |
| " spawning_application_context.sequence_id,\n", |
| " spawning_application_context.partition_key,\n", |
| " )\n", |
| " )\n", |
| " \n", |
| " return builder.build()" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 4, |
| "id": "52ef53b9-c3a1-4ee4-a8e0-99906c6bd8d8", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "data": { |
| "image/svg+xml": [ |
| "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", |
| "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", |
| " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", |
| "<!-- Generated by graphviz version 8.1.0 (20230707.0739)\n", |
| " -->\n", |
| "<!-- Pages: 1 -->\n", |
| "<svg width=\"99pt\" height=\"174pt\"\n", |
| " viewBox=\"0.00 0.00 98.50 174.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", |
| "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 170)\">\n", |
| "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-170 94.5,-170 94.5,4 -4,4\"/>\n", |
| "<!-- edit -->\n", |
| "<g id=\"node1\" class=\"node\">\n", |
| "<title>edit</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M42,-166C42,-166 12,-166 12,-166 6,-166 0,-160 0,-154 0,-154 0,-142 0,-142 0,-136 6,-130 12,-130 12,-130 42,-130 42,-130 48,-130 54,-136 54,-142 54,-142 54,-154 54,-154 54,-160 48,-166 42,-166\"/>\n", |
| "<text text-anchor=\"middle\" x=\"27\" y=\"-142.95\" font-family=\"Times,serif\" font-size=\"14.00\">edit</text>\n", |
| "</g>\n", |
| "<!-- write -->\n", |
| "<g id=\"node2\" class=\"node\">\n", |
| "<title>write</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M42,-101C42,-101 12,-101 12,-101 6,-101 0,-95 0,-89 0,-89 0,-77 0,-77 0,-71 6,-65 12,-65 12,-65 42,-65 42,-65 48,-65 54,-71 54,-77 54,-77 54,-89 54,-89 54,-95 48,-101 42,-101\"/>\n", |
| "<text text-anchor=\"middle\" x=\"27\" y=\"-77.95\" font-family=\"Times,serif\" font-size=\"14.00\">write</text>\n", |
| "</g>\n", |
| "<!-- edit->write -->\n", |
| "<g id=\"edge4\" class=\"edge\">\n", |
| "<title>edit->write</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M20.91,-129.78C20.36,-124.23 20.15,-117.92 20.29,-111.8\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"23.82,-112.38 20.91,-102.19 16.83,-111.97 23.82,-112.38\"/>\n", |
| "</g>\n", |
| "<!-- final_draft -->\n", |
| "<g id=\"node3\" class=\"node\">\n", |
| "<title>final_draft</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M78.5,-36C78.5,-36 29.5,-36 29.5,-36 23.5,-36 17.5,-30 17.5,-24 17.5,-24 17.5,-12 17.5,-12 17.5,-6 23.5,0 29.5,0 29.5,0 78.5,0 78.5,0 84.5,0 90.5,-6 90.5,-12 90.5,-12 90.5,-24 90.5,-24 90.5,-30 84.5,-36 78.5,-36\"/>\n", |
| "<text text-anchor=\"middle\" x=\"54\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">final_draft</text>\n", |
| "</g>\n", |
| "<!-- edit->final_draft -->\n", |
| "<g id=\"edge3\" class=\"edge\">\n", |
| "<title>edit->final_draft</title>\n", |
| "<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"5,2\" d=\"M44.84,-129.9C51.94,-121.88 59.3,-111.74 63,-101 68.99,-83.62 66.71,-63.05 62.95,-46.86\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"66.13,-46.22 60.19,-37.45 59.37,-48.01 66.13,-46.22\"/>\n", |
| "</g>\n", |
| "<!-- write->edit -->\n", |
| "<g id=\"edge1\" class=\"edge\">\n", |
| "<title>write->edit</title>\n", |
| "<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"5,2\" d=\"M33.09,-101.19C33.64,-106.75 33.85,-113.06 33.71,-119.18\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"30.18,-118.6 33.09,-128.78 37.17,-119.01 30.18,-118.6\"/>\n", |
| "</g>\n", |
| "<!-- write->final_draft -->\n", |
| "<g id=\"edge2\" class=\"edge\">\n", |
| "<title>write->final_draft</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M34.38,-64.78C36.88,-58.95 39.73,-52.29 42.48,-45.89\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"45.91,-47.76 46.63,-37.19 39.47,-45.01 45.91,-47.76\"/>\n", |
| "</g>\n", |
| "</g>\n", |
| "</svg>\n" |
| ], |
| "text/plain": [ |
| "<graphviz.graphs.Digraph at 0x16a053210>" |
| ] |
| }, |
| "execution_count": 4, |
| "metadata": {}, |
| "output_type": "execute_result" |
| } |
| ], |
| "source": [ |
| "_create_sub_application(2, None, \"sonnet\", \"state machines\").visualize()" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "id": "0f14b1f4-06d2-492c-be5c-088862445ff7", |
| "metadata": {}, |
| "source": [ |
| "# Full Application\n", |
| "\n", |
| "Next let's create the actual application. We'll call the sub-application inside the `generate_all_poems` step:" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 5, |
| "id": "0b786047-8944-45d4-a383-b32ee013a773", |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "# full agent\n", |
| "@action(\n", |
| " reads=[],\n", |
| " writes=[\n", |
| " \"max_drafts\",\n", |
| " \"poem_types\",\n", |
| " \"poem_subject\",\n", |
| " ],\n", |
| ")\n", |
| "def user_input(\n", |
| " state: State, max_drafts: int, poem_types: List[str], poem_subject: str\n", |
| ") -> Tuple[dict, State]:\n", |
| " \"\"\"Collects user input for the poem generation process.\"\"\"\n", |
| " return {\n", |
| " \"max_drafts\": max_drafts,\n", |
| " \"poem_types\": poem_types,\n", |
| " \"poem_subject\": poem_subject,\n", |
| " }, state.update(max_drafts=max_drafts, poem_types=poem_types, poem_subject=poem_subject)\n", |
| "\n", |
| "\n", |
| "@action(reads=[\"max_drafts\", \"poem_types\", \"poem_subject\"], writes=[\"proposals\"])\n", |
| "def generate_all_poems(state: State, __context: ApplicationContext) -> Tuple[dict, State]:\n", |
| " # create one each\n", |
| " apps = [\n", |
| " _create_sub_application(state[\"max_drafts\"], __context, poem_type, state[\"poem_subject\"])\n", |
| " for poem_type in state[\"poem_types\"]\n", |
| " ]\n", |
| " # run them all in parallel\n", |
| " with parallel_config(backend=\"threading\", n_jobs=3):\n", |
| " all_results = joblib.Parallel()(\n", |
| " joblib.delayed(app.run)(halt_after=[\"final_draft\"])\n", |
| " for app, poem_type in zip(apps, state[\"poem_types\"])\n", |
| " )\n", |
| " proposals = []\n", |
| " for *_, substate in all_results:\n", |
| " proposals.append(substate[\"final_draft\"])\n", |
| "\n", |
| " return {\"proposals\": proposals}, state.update(proposals=proposals)\n", |
| "\n", |
| "\n", |
| "@action(reads=[\"proposals\", \"prompts\"], writes=[\"final_results\"])\n", |
| "def final_results(state: State) -> Tuple[dict, State]:\n", |
| " # joins them into a string\n", |
| " proposals = state[\"proposals\"]\n", |
| " final_results = \"\\n\\n\".join(\n", |
| " [f\"{poem_type}:\\n{proposal}\" for poem_type, proposal in zip(state[\"poem_types\"], proposals)]\n", |
| " )\n", |
| " return {\"final_results\": final_results}, state.update(final_results=final_results)" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 6, |
| "id": "195a5ab3-1208-4200-9e9d-473ec0575e10", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "data": { |
| "image/svg+xml": [ |
| "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", |
| "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", |
| " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", |
| "<!-- Generated by graphviz version 8.1.0 (20230707.0739)\n", |
| " -->\n", |
| "<!-- Pages: 1 -->\n", |
| "<svg width=\"532pt\" height=\"239pt\"\n", |
| " viewBox=\"0.00 0.00 531.68 239.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", |
| "<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 235)\">\n", |
| "<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-235 527.68,-235 527.68,4 -4,4\"/>\n", |
| "<!-- user_input -->\n", |
| "<g id=\"node1\" class=\"node\">\n", |
| "<title>user_input</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M279.51,-166C279.51,-166 230.51,-166 230.51,-166 224.51,-166 218.51,-160 218.51,-154 218.51,-154 218.51,-142 218.51,-142 218.51,-136 224.51,-130 230.51,-130 230.51,-130 279.51,-130 279.51,-130 285.51,-130 291.51,-136 291.51,-142 291.51,-142 291.51,-154 291.51,-154 291.51,-160 285.51,-166 279.51,-166\"/>\n", |
| "<text text-anchor=\"middle\" x=\"255.01\" y=\"-142.95\" font-family=\"Times,serif\" font-size=\"14.00\">user_input</text>\n", |
| "</g>\n", |
| "<!-- generate_all_poems -->\n", |
| "<g id=\"node5\" class=\"node\">\n", |
| "<title>generate_all_poems</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M305.39,-101C305.39,-101 204.64,-101 204.64,-101 198.64,-101 192.64,-95 192.64,-89 192.64,-89 192.64,-77 192.64,-77 192.64,-71 198.64,-65 204.64,-65 204.64,-65 305.39,-65 305.39,-65 311.39,-65 317.39,-71 317.39,-77 317.39,-77 317.39,-89 317.39,-89 317.39,-95 311.39,-101 305.39,-101\"/>\n", |
| "<text text-anchor=\"middle\" x=\"255.01\" y=\"-77.95\" font-family=\"Times,serif\" font-size=\"14.00\">generate_all_poems</text>\n", |
| "</g>\n", |
| "<!-- user_input->generate_all_poems -->\n", |
| "<g id=\"edge4\" class=\"edge\">\n", |
| "<title>user_input->generate_all_poems</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M255.01,-129.78C255.01,-124.23 255.01,-117.92 255.01,-111.8\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"258.51,-112.19 255.01,-102.19 251.51,-112.19 258.51,-112.19\"/>\n", |
| "</g>\n", |
| "<!-- input__poem_types -->\n", |
| "<g id=\"node2\" class=\"node\">\n", |
| "<title>input__poem_types</title>\n", |
| "<ellipse fill=\"none\" stroke=\"black\" stroke-dasharray=\"5,2\" cx=\"80.01\" cy=\"-213\" rx=\"80.01\" ry=\"18\"/>\n", |
| "<text text-anchor=\"middle\" x=\"80.01\" y=\"-207.95\" font-family=\"Times,serif\" font-size=\"14.00\">input: poem_types</text>\n", |
| "</g>\n", |
| "<!-- input__poem_types->user_input -->\n", |
| "<g id=\"edge1\" class=\"edge\">\n", |
| "<title>input__poem_types->user_input</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M121.04,-197.23C147.11,-187.84 180.93,-175.67 208.07,-165.9\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"208.89,-168.96 217.11,-162.28 206.52,-162.38 208.89,-168.96\"/>\n", |
| "</g>\n", |
| "<!-- input__max_drafts -->\n", |
| "<g id=\"node3\" class=\"node\">\n", |
| "<title>input__max_drafts</title>\n", |
| "<ellipse fill=\"none\" stroke=\"black\" stroke-dasharray=\"5,2\" cx=\"255.01\" cy=\"-213\" rx=\"76.94\" ry=\"18\"/>\n", |
| "<text text-anchor=\"middle\" x=\"255.01\" y=\"-207.95\" font-family=\"Times,serif\" font-size=\"14.00\">input: max_drafts</text>\n", |
| "</g>\n", |
| "<!-- input__max_drafts->user_input -->\n", |
| "<g id=\"edge2\" class=\"edge\">\n", |
| "<title>input__max_drafts->user_input</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M255.01,-194.78C255.01,-189.23 255.01,-182.92 255.01,-176.8\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"258.51,-177.19 255.01,-167.19 251.51,-177.19 258.51,-177.19\"/>\n", |
| "</g>\n", |
| "<!-- input__poem_subject -->\n", |
| "<g id=\"node4\" class=\"node\">\n", |
| "<title>input__poem_subject</title>\n", |
| "<ellipse fill=\"none\" stroke=\"black\" stroke-dasharray=\"5,2\" cx=\"437.01\" cy=\"-213\" rx=\"86.67\" ry=\"18\"/>\n", |
| "<text text-anchor=\"middle\" x=\"437.01\" y=\"-207.95\" font-family=\"Times,serif\" font-size=\"14.00\">input: poem_subject</text>\n", |
| "</g>\n", |
| "<!-- input__poem_subject->user_input -->\n", |
| "<g id=\"edge3\" class=\"edge\">\n", |
| "<title>input__poem_subject->user_input</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M393.88,-197.07C366.26,-187.51 330.42,-175.1 302.07,-165.29\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"303.59,-161.76 292.99,-161.8 301.3,-168.38 303.59,-161.76\"/>\n", |
| "</g>\n", |
| "<!-- final_results -->\n", |
| "<g id=\"node6\" class=\"node\">\n", |
| "<title>final_results</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M284.39,-36C284.39,-36 225.64,-36 225.64,-36 219.64,-36 213.64,-30 213.64,-24 213.64,-24 213.64,-12 213.64,-12 213.64,-6 219.64,0 225.64,0 225.64,0 284.39,0 284.39,0 290.39,0 296.39,-6 296.39,-12 296.39,-12 296.39,-24 296.39,-24 296.39,-30 290.39,-36 284.39,-36\"/>\n", |
| "<text text-anchor=\"middle\" x=\"255.01\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">final_results</text>\n", |
| "</g>\n", |
| "<!-- generate_all_poems->final_results -->\n", |
| "<g id=\"edge5\" class=\"edge\">\n", |
| "<title>generate_all_poems->final_results</title>\n", |
| "<path fill=\"none\" stroke=\"black\" d=\"M255.01,-64.78C255.01,-59.23 255.01,-52.92 255.01,-46.8\"/>\n", |
| "<polygon fill=\"black\" stroke=\"black\" points=\"258.51,-47.19 255.01,-37.19 251.51,-47.19 258.51,-47.19\"/>\n", |
| "</g>\n", |
| "</g>\n", |
| "</svg>\n" |
| ], |
| "text/plain": [ |
| "<graphviz.graphs.Digraph at 0x16a0d8dd0>" |
| ] |
| }, |
| "execution_count": 6, |
| "metadata": {}, |
| "output_type": "execute_result" |
| } |
| ], |
| "source": [ |
| "app = (\n", |
| " ApplicationBuilder()\n", |
| " .with_actions(\n", |
| " user_input,\n", |
| " generate_all_poems,\n", |
| " final_results,\n", |
| " )\n", |
| " .with_transitions(\n", |
| " (\"user_input\", \"generate_all_poems\"),\n", |
| " (\"generate_all_poems\", \"final_results\"),\n", |
| " )\n", |
| " .with_tracker(project=\"demo:parallelism_poem_generation\")\n", |
| " .with_entrypoint(\"user_input\")\n", |
| " .build()\n", |
| ")\n", |
| "app.visualize()" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 19, |
| "id": "8db52375-6031-4b2e-8667-f7bc81f76580", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "data": { |
| "text/markdown": [ |
| "[View in UI!](http://localhost:7241/project/demo:parallelism_poem_generation/7e4abaa5-5d9f-4a35-863b-9627727eb4d4) (make sure Burr is running first)" |
| ], |
| "text/plain": [ |
| "<IPython.core.display.Markdown object>" |
| ] |
| }, |
| "execution_count": 19, |
| "metadata": {}, |
| "output_type": "execute_result" |
| } |
| ], |
| "source": [ |
| "from IPython.display import Markdown\n", |
| "Markdown(f\"[View in UI!](http://localhost:7241/project/demo:parallelism_poem_generation/{app.uid}) (make sure Burr is running first)\")" |
| ] |
| }, |
| { |
| "cell_type": "markdown", |
| "id": "9700a6a5-b6c8-475c-afaa-96ca2bf2a65b", |
| "metadata": {}, |
| "source": [ |
| "# Running it" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 7, |
| "id": "992c0e25-e504-4eda-8d13-f3ec07aa73ad", |
| "metadata": {}, |
| "outputs": [], |
| "source": [ |
| "action, state, results = app.run(\n", |
| " halt_after=[\"final_results\"],\n", |
| " inputs={\n", |
| " \"max_drafts\": 2,\n", |
| " \"poem_types\": [\n", |
| " \"sonnet\",\n", |
| " \"limerick\",\n", |
| " \"haiku\",\n", |
| " \"acrostic\",\n", |
| " ],\n", |
| " \"poem_subject\": \"state machines\",\n", |
| " },\n", |
| ")" |
| ] |
| }, |
| { |
| "cell_type": "code", |
| "execution_count": 12, |
| "id": "cb52e66c-b391-4495-aa48-b86fb96fc780", |
| "metadata": {}, |
| "outputs": [ |
| { |
| "name": "stdout", |
| "output_type": "stream", |
| "text": [ |
| "sonnet:\n", |
| "In realms of logic, where machines reside,\n", |
| "With gears of reason, wheels of choice aligned,\n", |
| "A state machine, our guiding technologic guide,\n", |
| "A dance of code within a frame confined.\n", |
| "\n", |
| "It starts with states, finite list well-traced,\n", |
| "Transitions chart its routes from here to there.\n", |
| "Encoded paths, in logic's arms embraced,\n", |
| "A web of rules, spun tight with utmost care.\n", |
| "\n", |
| "From idle calm to busy hum it shifts,\n", |
| "With each condition met, it alters course.\n", |
| "It thrives on change; its power deftly lifts,\n", |
| "Transforms through states, a tireless, coded force.\n", |
| "\n", |
| "Though hardware cold may cloak its silent might,\n", |
| "In structured change, it brings our world to light.\n", |
| "\n", |
| "limerick:\n", |
| "In realms where the data aligns,\n", |
| "Live machines with sleek, stateful designs.\n", |
| "Their transitions, so neat,\n", |
| "Make logic a treat,\n", |
| "As grand as the royals in lines.\n", |
| "\n", |
| "haiku:\n", |
| "Whispers of logic,\n", |
| "Circuits pulse in silent paths —\n", |
| "States craft vivid tales.\n", |
| "\n", |
| "acrostic:\n", |
| "**State Machines**\n", |
| "\n", |
| "**S**hadows of logic in code’s tight embrace,\n", |
| "**T**houghts intertwined in a digital space.\n", |
| "**A**lchemy of zeros ignites the race,\n", |
| "**T**ransitions intricate, guarded with grace.\n", |
| "**E**choed whispers in circuits’ high chase.\n", |
| "\n", |
| "**M**emory’s echo in silicon lanes,\n", |
| "**A**cross pathways, breaking old chains.\n", |
| "**C**elestial guides in algorithm’s reign,\n", |
| "**H**eavy with purpose, binaries plain.\n", |
| "**I**nfinite states, each proud and contained,\n", |
| "**N**avigating logic, calculations sustained,\n", |
| "**E**thos of order where chaos restrains,\n", |
| "**S**ymbiotic rhythms, precision regained.\n" |
| ] |
| } |
| ], |
| "source": [ |
| "print(results['final_results'])" |
| ] |
| } |
| ], |
| "metadata": { |
| "kernelspec": { |
| "display_name": "Python 3 (ipykernel)", |
| "language": "python", |
| "name": "python3" |
| }, |
| "language_info": { |
| "codemirror_mode": { |
| "name": "ipython", |
| "version": 3 |
| }, |
| "file_extension": ".py", |
| "mimetype": "text/x-python", |
| "name": "python", |
| "nbconvert_exporter": "python", |
| "pygments_lexer": "ipython3", |
| "version": "3.11.6" |
| } |
| }, |
| "nbformat": 4, |
| "nbformat_minor": 5 |
| } |