Skip to content

Control Flow

Open In Colab

Control Flow

A Program is a static graph: you wire every module together once, at construction time, and the framework runs the same flowchart on every input (Guide 3). That sounds like it leaves no room to react to the data — to skip a step, take a different path, or do several things at once. This guide is about exactly that room. It shows how to express branching, parallelism, and recombination without leaving the declarative graph, so the result stays inspectable, serializable, and trainable.

You have already met the pieces. Guide 2 introduced the operator algebra on data models (+, &, |, ^, ~). Guide 4 introduced the control-flow modules (Decision, Branch) and the merging modules. This guide is the layer above both: it assembles those pieces into the handful of patterns you will reach for again and again.

None Is the Control Signal

Here is the single idea the whole guide rests on. In an ordinary Python program, control flow is about which lines execute. In a Synalinks graph, every wired module is always present — but a module on an inactive path produces None instead of a value. So control flow becomes a question about values, not lines:

  • a module that should not contribute on this input yields None, and
  • the operators decide what happens when a value might be None.

That is why the operators from Guide 2 are not just a convenience for gluing schemas together — they are the language of control flow. | means "whichever path actually ran." & means "only if this prerequisite is present." ^ means "exactly one of these, never both." Reading them as boolean logic over "is there a value here?" is the right mental model.

graph LR
    A["Input"] --> B["Branch"]
    B -->|"selected"| C["value"]
    B -->|"skipped"| D["None"]
    C --> E["Merge (| )"]
    D --> E
    E --> F["Output"]

Two Kinds of Control Flow

Synalinks gives you two distinct ways to make a program behave differently on different inputs, and it is worth being deliberate about which one you pick.

  • Declarative (this guide). You express the branching as part of the graph, using Decision/Branch to route and the operators to recombine. The structure stays visible: program.summary() shows it, the optimizer can train through it, and program.save() serializes it. The cost is that the shape of the flow is fixed — a Branch always has the same, finite set of arms.
  • Imperative (the Subclassing API from Guide 3). You write the forward pass as ordinary async Python and use real if/while/ recursion. This handles flows a static graph cannot — "keep calling the LM until the answer passes a check," for instance — but the framework sees your call as an opaque box.

The rule of thumb: reach for declarative control flow first. Drop to imperative Python only when the flow is genuinely unbounded or data-dependent in a way a fixed set of branches cannot capture. Most routing, fan-out, and fallback logic is declarative.

Pattern 1: Fan-Out (Parallel Branches)

The simplest non-linear shape is fan-out: send the same input to several modules at once. In Synalinks this is automatic — whenever two modules read the same input, they run concurrently. There is no special "parallel" construct; the framework infers it from the graph.

graph LR
    A["Input"] --> B["Generator: pros"]
    A --> C["Generator: cons"]
    B --> D["Merge (+)"]
    C --> D
    D --> E["Output"]
inputs = synalinks.Input(data_model=Question)

# Both read `inputs` -> they execute in parallel.
pros = await synalinks.Generator(data_model=Pros, ...)(inputs)
cons = await synalinks.Generator(data_model=Cons, ...)(inputs)

# Fan back in: + (Concat) unions the fields of both into one model.
outputs = pros + cons
program = synalinks.Program(inputs=inputs, outputs=outputs)

You have two choices for what to do with the parallel results:

  • Keep them separate. Pass a list as the program's outputs (outputs=[pros, cons]) and the program returns a list of results.
  • Merge them. Combine the branches with + (Concat) into a single data model whose fields are the union of both. If two branches share a field name, Concat keeps both by suffixing the duplicate (answer, answer_1) so no information is lost.

Use fan-out for ensembles (several answers, pick or vote), multi-faceted analysis (sentiment and topic and urgency in one pass), or simply to shave wall-clock time off independent steps.

Pattern 2: Routing (Decision and Branch)

The other fundamental shape is routing: pick one path based on what the input looks like. The primitive is Decision — single-label classification over a closed set of labels — and Branch is Decision wired directly to a list of modules.

A Branch returns a tuple with one slot per label. At runtime the classifier picks a label, the module in that slot runs, and every other slot comes back None. So the tuple is "one value, the rest None."

graph LR
    A["Input"] --> B["Branch: easy / hard"]
    B -->|"easy"| C["Generator: Answer"]
    B -->|"hard"| D["Generator: Answer+Thinking"]
    C --> E["Collapse (| )"]
    D --> E
    E --> F["Output"]
(easy, hard) = await synalinks.Branch(
    question="How hard is this query to answer?",
    labels=["easy", "hard"],
    branches=[
        synalinks.Generator(data_model=Answer, ...),          # for "easy"
        synalinks.Generator(data_model=AnswerWithThinking, ...),  # for "hard"
    ],
    language_model=language_model,
)(inputs)

# Exactly one of (easy, hard) is non-None. Collapse to the live one:
outputs = easy | hard

That last line is the canonical routing idiom: Branch produces a tuple, and | collapses it back to the single output that actually ran. | (Or) returns its first non-None operand, so it always hands you whichever branch fired.

The Operators as Control Flow

Guide 2 listed the five operators; here is what each one is for once you start thinking of None as a signal. The table below is the same algebra, read as control flow.

Operator Reach for it when…
\| Or collapsing a Branch, or falling back: primary \| backup.
& And gating: attach context only if a path is live; None if not.
+ Concat joining parallel results that are both expected to exist.
^ Xor mutual exclusion: a guard that fires only if exactly one side.
~ Not cancelling a path outright (turn any value into None).

The behavior under missing inputs is what distinguishes them, so keep this truth table close:

A B A + B A & B A \| B A ^ B
value value merged merged A None
value None A None A A
None value B None B B
None None None None None None

Two patterns built straight out of this table:

  • Fallback chain. primary | secondary | tertiary walks left to right and yields the first path that produced a value. A cheap model with an expensive backup is just cheap | expensive.
  • Safe gating. inputs & branch_output attaches the original input to a branch's result only when that branch ran — if the branch was skipped (None), the & short-circuits to None and nothing downstream crashes trying to read a missing field. This is the difference between & and +: + would raise on the None.

When you need to keep only part of a model before merging (to hide a scratch thinking field, say), use the masking helpers from Guide 2 — in_mask/out_mask — in the same pipeline.

Putting It All Together

The example below is one runnable program that uses each pattern. It fans out for a quick pros/cons pass, routes a query by difficulty and collapses the branch with |, and then demonstrates the raw operator table on concrete data models so you can see None flow through the algebra with no language model involved.

import asyncio
from dotenv import load_dotenv
import synalinks

class Question(synalinks.DataModel):
    question: str = synalinks.Field(description="The question to consider")

class Pros(synalinks.DataModel):
    pros: str = synalinks.Field(description="The strongest argument in favor")

class Cons(synalinks.DataModel):
    cons: str = synalinks.Field(description="The strongest argument against")

async def main():
    load_dotenv()
    synalinks.clear_session()
    lm = synalinks.LanguageModel(model="ollama/mistral:latest")

    # Fan-out: both generators read `inputs`, run in parallel, merge with +.
    inputs = synalinks.Input(data_model=Question)
    pros = await synalinks.Generator(data_model=Pros, language_model=lm)(inputs)
    cons = await synalinks.Generator(data_model=Cons, language_model=lm)(inputs)
    program = synalinks.Program(inputs=inputs, outputs=pros + cons)

    result = await program(Question(question="Should small teams adopt microservices?"))
    print(result.get_json())

if __name__ == "__main__":
    asyncio.run(main())

Take-Home Summary

  • Control flow in a graph is about values, not lines. An inactive path yields None; the operators decide what None means downstream.
  • Fan-out is automatic. Two modules reading the same input run in parallel. Keep the results as a list, or merge them with +.
  • Route with Branch, collapse with |. A Branch returns a tuple with one live slot and the rest None; a | b | ... hands you the live one. The same | builds fallback chains.
  • & is the safe join. inputs & maybe_none attaches context only when the path ran, short-circuiting to None otherwise — where + would raise.
  • Prefer declarative control flow (this guide) so the structure stays visible and trainable; drop to the Subclassing API only for genuinely unbounded, data-dependent flows.

API References

Answer

Bases: DataModel

A short, direct answer.

Source code in guides/5_control_flow.py
class Answer(synalinks.DataModel):
    """A short, direct answer."""

    answer: str = synalinks.Field(description="The correct answer")

AnswerWithThinking

Bases: DataModel

An answer with step-by-step reasoning.

Source code in guides/5_control_flow.py
class AnswerWithThinking(synalinks.DataModel):
    """An answer with step-by-step reasoning."""

    thinking: str = synalinks.Field(description="Your step by step thinking")
    answer: str = synalinks.Field(description="The correct answer")

Cons

Bases: DataModel

The case against.

Source code in guides/5_control_flow.py
class Cons(synalinks.DataModel):
    """The case against."""

    cons: str = synalinks.Field(description="The strongest argument against")

Pros

Bases: DataModel

The case in favor.

Source code in guides/5_control_flow.py
class Pros(synalinks.DataModel):
    """The case in favor."""

    pros: str = synalinks.Field(description="The strongest argument in favor")

Query

Bases: DataModel

A user query to route.

Source code in guides/5_control_flow.py
class Query(synalinks.DataModel):
    """A user query to route."""

    query: str = synalinks.Field(description="The user query")

Question

Bases: DataModel

A question to reason about.

Source code in guides/5_control_flow.py
class Question(synalinks.DataModel):
    """A question to reason about."""

    question: str = synalinks.Field(description="The question to consider")

Source

import asyncio

from dotenv import load_dotenv

import synalinks

# =============================================================================
# Data Models
# =============================================================================


class Question(synalinks.DataModel):
    """A question to reason about."""

    question: str = synalinks.Field(description="The question to consider")


class Pros(synalinks.DataModel):
    """The case in favor."""

    pros: str = synalinks.Field(description="The strongest argument in favor")


class Cons(synalinks.DataModel):
    """The case against."""

    cons: str = synalinks.Field(description="The strongest argument against")


class Query(synalinks.DataModel):
    """A user query to route."""

    query: str = synalinks.Field(description="The user query")


class Answer(synalinks.DataModel):
    """A short, direct answer."""

    answer: str = synalinks.Field(description="The correct answer")


class AnswerWithThinking(synalinks.DataModel):
    """An answer with step-by-step reasoning."""

    thinking: str = synalinks.Field(description="Your step by step thinking")
    answer: str = synalinks.Field(description="The correct answer")


# =============================================================================
# Main Demonstration
# =============================================================================


async def main():
    load_dotenv()
    synalinks.clear_session()
    synalinks.enable_logging()

    # synalinks.enable_observability(
    #     tracking_uri="http://localhost:5000",
    #     experiment_name="guide_5_control_flow",
    # )

    lm = synalinks.LanguageModel(model="ollama/mistral:latest")

    # -------------------------------------------------------------------------
    # Pattern 1: Fan-out (parallel branches) merged with + (Concat)
    # -------------------------------------------------------------------------
    print("=" * 60)
    print("Pattern 1: Fan-out + Concat (+)")
    print("=" * 60)

    inputs = synalinks.Input(data_model=Question)

    # Both generators read the SAME input -> they run in parallel.
    pros = await synalinks.Generator(
        data_model=Pros,
        language_model=lm,
        name="for",
    )(inputs)
    cons = await synalinks.Generator(
        data_model=Cons,
        language_model=lm,
        name="against",
    )(inputs)

    # Fan back in: + unions the fields of both branches into one model.
    fanout_program = synalinks.Program(
        inputs=inputs,
        outputs=pros + cons,
        name="fan_out",
    )
    fanout_program.summary()

    result = await fanout_program(
        Question(question="Should small teams adopt microservices?")
    )
    print(f"\nMerged fields: {list(result.get_json().keys())}")
    print(f"  pros: {result['pros'][:70]}...")
    print(f"  cons: {result['cons'][:70]}...")

    # -------------------------------------------------------------------------
    # Pattern 2: Routing with Branch, collapsed with | (Or)
    # -------------------------------------------------------------------------
    print("\n" + "=" * 60)
    print("Pattern 2: Branch routing + Or (|)")
    print("=" * 60)

    inputs = synalinks.Input(data_model=Query)

    # Branch returns a tuple with one live slot; the rest are None.
    easy, hard = await synalinks.Branch(
        question="How hard is this query to answer?",
        labels=["easy", "hard"],
        branches=[
            synalinks.Generator(data_model=Answer, language_model=lm),
            synalinks.Generator(data_model=AnswerWithThinking, language_model=lm),
        ],
        language_model=lm,
    )(inputs)

    # | collapses the tuple to whichever branch actually ran.
    routing_program = synalinks.Program(
        inputs=inputs,
        outputs=easy | hard,
        name="routing",
    )
    routing_program.summary()

    result = await routing_program(Query(query="What is 2 + 2?"))
    print(f"\nEasy query -> {result['answer']}")

    result = await routing_program(
        Query(query="Explain why the sky is blue, from first principles.")
    )
    print(f"Hard query -> {result['answer'][:70]}...")

    # -------------------------------------------------------------------------
    # Pattern 3: The operator algebra over None (no LM needed)
    # -------------------------------------------------------------------------
    print("\n" + "=" * 60)
    print("Pattern 3: Operators as control flow")
    print("=" * 60)

    a = Answer(answer="A")
    b = Cons(cons="B")

    # + (Concat): union of fields when both are present.
    print(f"\n(a + b) fields: {list((a + b).get_json().keys())}")
    # | (Or): first non-None operand -> fallback / branch collapse.
    print(f"(a | None) -> {(a | None).get_json()}")
    print(f"(None | b) -> {(None | b).get_json()}")
    # & (And): safe join, None if either side is missing.
    print(f"(a & None) -> {a & None}")
    # ^ (Xor): value only if exactly one side is present.
    print(f"(a ^ None) is not None -> {(a ^ None) is not None}")
    print(f"(a ^ b) is None      -> {(a ^ b) is None}")
    # ~ (Not): cancel a path.
    print(f"(~a) -> {~a}")


if __name__ == "__main__":
    asyncio.run(main())

Run log

This guide calls synalinks.enable_logging(), so a full run traces every module call. The log below is the unedited output of running the guide above with local models.

Full run log — guides/5_control_flow.log
(DEBUG) [Synalinks]
Call ID: 80d8e324-48c5-472a-afeb-284ef1ea662e
Parent call ID: None
Module: Generator
Module Name: for
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A question to reason about.",
    "properties": {
      "question": {
        "description": "The question to consider",
        "title": "Question",
        "type": "string"
      }
    },
    "required": [
      "question"
    ],
    "title": "Question",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 80d8e324-48c5-472a-afeb-284ef1ea662e
Parent call ID: None
Module: Generator
Module Name: for
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "The case in favor.",
    "properties": {
      "pros": {
        "description": "The strongest argument in favor",
        "title": "Pros",
        "type": "string"
      }
    },
    "required": [
      "pros"
    ],
    "title": "Pros",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 388de072-d198-4cbd-8663-ca21c043942e
Parent call ID: None
Module: Generator
Module Name: against
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A question to reason about.",
    "properties": {
      "question": {
        "description": "The question to consider",
        "title": "Question",
        "type": "string"
      }
    },
    "required": [
      "question"
    ],
    "title": "Question",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 388de072-d198-4cbd-8663-ca21c043942e
Parent call ID: None
Module: Generator
Module Name: against
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "The case against.",
    "properties": {
      "cons": {
        "description": "The strongest argument against",
        "title": "Cons",
        "type": "string"
      }
    },
    "required": [
      "cons"
    ],
    "title": "Cons",
    "type": "object"
  }
]

============================================================
Pattern 1: Fan-out + Concat (+)
============================================================
Program: fan_out
description: 'A `Functional` program is a `Program` defined as a directed graph 
of modules.'
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃                    ┃                         ┃  Vars ┃                   ┃
┃ Module (type)      ┃ Output Schema           ┃     # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_module       │ Question:               │     0 │ -                 │
│ (InputModule)      │   question: str         │       │                   │
├────────────────────┼─────────────────────────┼───────┼───────────────────┤
│ for (Generator)    │ Pros:                   │     1 │ input_module[0][… │
│                    │   pros: str             │       │                   │
├────────────────────┼─────────────────────────┼───────┼───────────────────┤
│ against            │ Cons:                   │     1 │ input_module[0][… │
│ (Generator)        │   cons: str             │       │                   │
├────────────────────┼─────────────────────────┼───────┼───────────────────┤
│ concat (Concat)    │ Pros:                   │     0 │ for[0][0],        │
│                    │   pros: str             │       │ against[0][0]     │
│                    │   cons: str             │       │                   │
└────────────────────┴─────────────────────────┴───────┴───────────────────┘
[Synalinks]
Call ID: 2b13b3aa-ebb7-4332-9769-d3ba5be8ab19
Parent call ID: None
Module: Functional
Module Name: fan_out
Module Description: A `Functional` program is a `Program` defined as a directed graph of modules.
Data Model JSON:
[
  {
    "question": "Should small teams adopt microservices?"
  }
]

[Synalinks]
Call ID: 7a53818e-f8e5-4fee-8f32-edb9a02b0764
Parent call ID: 2b13b3aa-ebb7-4332-9769-d3ba5be8ab19
Module: Generator
Module Name: for
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "question": "Should small teams adopt microservices?"
  }
]

[Synalinks]
Call ID: 72b3c822-89ec-491b-b8ba-1828d9d6f4ed
Parent call ID: 7a53818e-f8e5-4fee-8f32-edb9a02b0764
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "messages": [
      {
        "role": "system",
        "content": "<instructions>\nYour task is to answer with a JSON containing the following keys: ['pros']\n</instructions>\n"
      },
      {
        "role": "user",
        "content": "<input>\n{'question': 'Should small teams adopt microservices?'}\n</input>\n<output>\n"
      }
    ]
  }
]

[Synalinks]
Call ID: 61695190-2c82-4323-bfa9-e13ceaee64bd
Parent call ID: 72b3c822-89ec-491b-b8ba-1828d9d6f4ed
Module: Generator
Module Name: against
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "question": "Should small teams adopt microservices?"
  }
]

[Synalinks]
Call ID: cfef8e1d-9f8b-433f-8ee8-c03881e859c6
Parent call ID: 61695190-2c82-4323-bfa9-e13ceaee64bd
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "messages": [
      {
        "role": "system",
        "content": "<instructions>\nYour task is to answer with a JSON containing the following keys: ['cons']\n</instructions>\n"
      },
      {
        "role": "user",
        "content": "<input>\n{'question': 'Should small teams adopt microservices?'}\n</input>\n<output>\n"
      }
    ]
  }
]

[Synalinks]
Call ID: 72b3c822-89ec-491b-b8ba-1828d9d6f4ed
Parent call ID: 7a53818e-f8e5-4fee-8f32-edb9a02b0764
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "pros": "1. Scalability: Microservices allow for independent scaling of individual services, which can help manage resources more efficiently and improve performance. \n"
  }
]

[Synalinks]
Call ID: 7a53818e-f8e5-4fee-8f32-edb9a02b0764
Parent call ID: 2b13b3aa-ebb7-4332-9769-d3ba5be8ab19
Module: Generator
Module Name: for
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "pros": "1. Scalability: Microservices allow for independent scaling of individual services, which can help manage resources more efficiently and improve performance. \n"
  }
]

[Synalinks]
Call ID: cfef8e1d-9f8b-433f-8ee8-c03881e859c6
Parent call ID: 61695190-2c82-4323-bfa9-e13ceaee64bd
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "cons": "1. Complexity: Microservices can lead to increased complexity due to the need for multiple services, each with its own database and technology stack. This can make debugging and maintenance more challenging. \n\n2. Communication Overhead: With microservices, communication between services can become a bottleneck, especially in small teams where resources are limited. \n\n3. Data Consistency: Ensuring data consistency across multiple services can be difficult, potentially leading to inconsistent user experiences or data errors. \n\n4. Deployment and Scaling: Deploying and scaling microservices individually can be time-consuming and require more resources compared to monolithic applications. \n\n5. Network Latency: The use of multiple services can increase network latency, which may impact performance for users."
  }
]

[Synalinks]
Call ID: 61695190-2c82-4323-bfa9-e13ceaee64bd
Parent call ID: 72b3c822-89ec-491b-b8ba-1828d9d6f4ed
Module: Generator
Module Name: against
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "cons": "1. Complexity: Microservices can lead to increased complexity due to the need for multiple services, each with its own database and technology stack. This can make debugging and maintenance more challenging. \n\n2. Communication Overhead: With microservices, communication between services can become a bottleneck, especially in small teams where resources are limited. \n\n3. Data Consistency: Ensuring data consistency across multiple services can be difficult, potentially leading to inconsistent user experiences or data errors. \n\n4. Deployment and Scaling: Deploying and scaling microservices individually can be time-consuming and require more resources compared to monolithic applications. \n\n5. Network Latency: The use of multiple services can increase network latency, which may impact performance for users."
  }
]

[Synalinks]
Call ID: 2b13b3aa-ebb7-4332-9769-d3ba5be8ab19
Parent call ID: None
Module: Functional
Module Name: fan_out
Module Description: A `Functional` program is a `Program` defined as a directed graph of modules.
Data Model JSON:
[
  {
    "pros": "1. Scalability: Microservices allow for independent scaling of individual services, which can help manage resources more efficiently and improve performance. \n",
    "cons": "1. Complexity: Microservices can lead to increased complexity due to the need for multiple services, each with its own database and technology stack. This can make debugging and maintenance more challenging. \n\n2. Communication Overhead: With microservices, communication between services can become a bottleneck, especially in small teams where resources are limited. \n\n3. Data Consistency: Ensuring data consistency across multiple services can be difficult, potentially leading to inconsistent user experiences or data errors. \n\n4. Deployment and Scaling: Deploying and scaling microservices individually can be time-consuming and require more resources compared to monolithic applications. \n\n5. Network Latency: The use of multiple services can increase network latency, which may impact performance for users."
  }
]

(DEBUG) [Synalinks]
Call ID: 5b241b7e-f666-49bb-9b91-2e8d86680785
Parent call ID: None
Module: Branch
Module Name: branch
Module Description: Use a `LanguageModel` to select which module(s) to call based on an
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A user query to route.",
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      }
    },
    "required": [
      "query"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 9cbd85d3-e030-4a56-ab15-c158f86772d5
Parent call ID: 5b241b7e-f666-49bb-9b91-2e8d86680785
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A user query to route.",
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      }
    },
    "required": [
      "query"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 6283e876-6a63-4a93-bc47-f779e3bc7dc6
Parent call ID: 9cbd85d3-e030-4a56-ab15-c158f86772d5
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "question": {
        "description": "The question to ask yourself.",
        "title": "Question",
        "type": "string"
      }
    },
    "required": [
      "query",
      "question"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 6283e876-6a63-4a93-bc47-f779e3bc7dc6
Parent call ID: 9cbd85d3-e030-4a56-ab15-c158f86772d5
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 76f7e6ab-7a47-40ae-befd-0c0d686912b9
Parent call ID: 6283e876-6a63-4a93-bc47-f779e3bc7dc6
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "question": {
        "description": "The question to ask yourself.",
        "title": "Question",
        "type": "string"
      }
    },
    "required": [
      "query",
      "question"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 76f7e6ab-7a47-40ae-befd-0c0d686912b9
Parent call ID: 6283e876-6a63-4a93-bc47-f779e3bc7dc6
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 9cbd85d3-e030-4a56-ab15-c158f86772d5
Parent call ID: 5b241b7e-f666-49bb-9b91-2e8d86680785
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 983f0b1a-11ca-4e7b-b160-7718e0651c54
Parent call ID: 76f7e6ab-7a47-40ae-befd-0c0d686912b9
Module: Generator
Module Name: generator
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "query",
      "thinking",
      "choice"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 983f0b1a-11ca-4e7b-b160-7718e0651c54
Parent call ID: 76f7e6ab-7a47-40ae-befd-0c0d686912b9
Module: Generator
Module Name: generator
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A short, direct answer.",
    "properties": {
      "answer": {
        "description": "The correct answer",
        "title": "Answer",
        "type": "string"
      }
    },
    "required": [
      "answer"
    ],
    "title": "Answer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 1fec1ad1-95e9-4c53-9832-3c83e89aa49c
Parent call ID: 983f0b1a-11ca-4e7b-b160-7718e0651c54
Module: Generator
Module Name: generator_1
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "query",
      "thinking",
      "choice"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 1fec1ad1-95e9-4c53-9832-3c83e89aa49c
Parent call ID: 983f0b1a-11ca-4e7b-b160-7718e0651c54
Module: Generator
Module Name: generator_1
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "An answer with step-by-step reasoning.",
    "properties": {
      "thinking": {
        "description": "Your step by step thinking",
        "title": "Thinking",
        "type": "string"
      },
      "answer": {
        "description": "The correct answer",
        "title": "Answer",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "answer"
    ],
    "title": "AnswerWithThinking",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: d4ecd03d-5f17-43ee-8cbd-78bad685e649
Parent call ID: 1fec1ad1-95e9-4c53-9832-3c83e89aa49c
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A user query to route.",
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      }
    },
    "required": [
      "query"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 5e592aea-396f-4c50-9b22-e6f52efb8f32
Parent call ID: d4ecd03d-5f17-43ee-8cbd-78bad685e649
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "question": {
        "description": "The question to ask yourself.",
        "title": "Question",
        "type": "string"
      }
    },
    "required": [
      "query",
      "question"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 5e592aea-396f-4c50-9b22-e6f52efb8f32
Parent call ID: d4ecd03d-5f17-43ee-8cbd-78bad685e649
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: d4ecd03d-5f17-43ee-8cbd-78bad685e649
Parent call ID: 1fec1ad1-95e9-4c53-9832-3c83e89aa49c
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: d4b13295-a150-4800-973d-47a657f26ed0
Parent call ID: 5e592aea-396f-4c50-9b22-e6f52efb8f32
Module: Generator
Module Name: generator
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "query",
      "thinking",
      "choice"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: d4b13295-a150-4800-973d-47a657f26ed0
Parent call ID: 5e592aea-396f-4c50-9b22-e6f52efb8f32
Module: Generator
Module Name: generator
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "A short, direct answer.",
    "properties": {
      "answer": {
        "description": "The correct answer",
        "title": "Answer",
        "type": "string"
      }
    },
    "required": [
      "answer"
    ],
    "title": "Answer",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: e7d12208-be09-49bd-9102-b40e932543dd
Parent call ID: d4b13295-a150-4800-973d-47a657f26ed0
Module: Generator
Module Name: generator_1
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "query": {
        "description": "The user query",
        "title": "Query",
        "type": "string"
      },
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      }
    },
    "required": [
      "query",
      "thinking",
      "choice"
    ],
    "title": "Query",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: e7d12208-be09-49bd-9102-b40e932543dd
Parent call ID: d4b13295-a150-4800-973d-47a657f26ed0
Module: Generator
Module Name: generator_1
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "description": "An answer with step-by-step reasoning.",
    "properties": {
      "thinking": {
        "description": "Your step by step thinking",
        "title": "Thinking",
        "type": "string"
      },
      "answer": {
        "description": "The correct answer",
        "title": "Answer",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "answer"
    ],
    "title": "AnswerWithThinking",
    "type": "object"
  }
]

(DEBUG) [Synalinks]
Call ID: 5b241b7e-f666-49bb-9b91-2e8d86680785
Parent call ID: None
Module: Branch
Module Name: branch
Module Description: Use a `LanguageModel` to select which module(s) to call based on an
Data Model JSON Schema:
[
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      },
      "answer": {
        "description": "The correct answer",
        "title": "Answer",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice",
      "answer"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  },
  {
    "additionalProperties": false,
    "properties": {
      "thinking": {
        "description": "Your step by step thinking to choose the correct label.",
        "title": "Thinking",
        "type": "string"
      },
      "choice": {
        "enum": [
          "easy",
          "hard"
        ],
        "title": "Choice",
        "type": "string"
      },
      "thinking_1": {
        "description": "Your step by step thinking",
        "title": "Thinking 1",
        "type": "string"
      },
      "answer": {
        "description": "The correct answer",
        "title": "Answer",
        "type": "string"
      }
    },
    "required": [
      "thinking",
      "choice",
      "thinking_1",
      "answer"
    ],
    "title": "DecisionAnswer",
    "type": "object"
  }
]


Merged fields: ['pros', 'cons']
  pros: 1. Scalability: Microservices allow for independent scaling of individ...
  cons: 1. Complexity: Microservices can lead to increased complexity due to t...

============================================================
Pattern 2: Branch routing + Or (|)
============================================================
Program: routing
description: 'A `Functional` program is a `Program` defined as a directed graph 
of modules.'
┏━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃                    ┃                         ┃  Vars ┃                   ┃
┃ Module (type)      ┃ Output Schema           ┃     # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_module_1     │ Query:                  │     0 │ -                 │
│ (InputModule)      │   query: str            │       │                   │
├────────────────────┼─────────────────────────┼───────┼───────────────────┤
│ branch (Branch)    │ DecisionAnswer:         │     3 │ input_module_1[0… │
│                    │   thinking: str         │       │                   │
│                    │   choice:               │       │                   │
│                    │ Literal['easy', 'hard'] │       │                   │
│                    │   answer: str           │       │                   │
│                    │ ---                     │       │                   │
│                    │ DecisionAnswer:         │       │                   │
│                    │   thinking: str         │       │                   │
│                    │   choice:               │       │                   │
│                    │ Literal['easy', 'hard'] │       │                   │
│                    │   thinking_1: str       │       │                   │
│                    │   answer: str           │       │                   │
├────────────────────┼─────────────────────────┼───────┼───────────────────┤
│ or (Or)            │ DecisionAnswer:         │     0 │ branch[0][0],     │
│                    │   thinking: str         │       │ branch[0][1]      │
│                    │   choice:               │       │                   │
│                    │ Literal['easy', 'hard'] │       │                   │
│                    │   answer: str           │       │                   │
└────────────────────┴─────────────────────────┴───────┴───────────────────┘
[Synalinks]
Call ID: 717fdd22-62ad-4aa6-9c23-c19df90093a8
Parent call ID: None
Module: Functional
Module Name: routing
Module Description: A `Functional` program is a `Program` defined as a directed graph of modules.
Data Model JSON:
[
  {
    "query": "What is 2 + 2?"
  }
]

[Synalinks]
Call ID: 4986c872-67f0-4c78-b325-ebdded62ee10
Parent call ID: 717fdd22-62ad-4aa6-9c23-c19df90093a8
Module: Branch
Module Name: branch
Module Description: Use a `LanguageModel` to select which module(s) to call based on an
Data Model JSON:
[
  {
    "query": "What is 2 + 2?"
  }
]

[Synalinks]
Call ID: 39cbbf17-b1a4-4260-80a5-5ef7464a54b5
Parent call ID: 4986c872-67f0-4c78-b325-ebdded62ee10
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON:
[
  {
    "query": "What is 2 + 2?"
  }
]

[Synalinks]
Call ID: e2bddcf3-b943-47fe-a8be-1a863b80332e
Parent call ID: 39cbbf17-b1a4-4260-80a5-5ef7464a54b5
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "query": "What is 2 + 2?",
    "question": "How hard is this query to answer?"
  }
]

[Synalinks]
Call ID: a07da834-9d42-4e55-b085-70942c760816
Parent call ID: e2bddcf3-b943-47fe-a8be-1a863b80332e
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "messages": [
      {
        "role": "system",
        "content": "<instructions>\nYou will be given a question, your task is to answer step-by-step to choose\none the following labels: ['easy', 'hard']\n</instructions>\n"
      },
      {
        "role": "user",
        "content": "<input>\n{'query': 'What is 2 + 2?', 'question': 'How hard is this query to answer?'}\n</input>\n<output>\n"
      }
    ]
  }
]

[Synalinks]
Call ID: a07da834-9d42-4e55-b085-70942c760816
Parent call ID: e2bddcf3-b943-47fe-a8be-1a863b80332e
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "thinking": "The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.",
    "choice": "easy"
  }
]

[Synalinks]
Call ID: e2bddcf3-b943-47fe-a8be-1a863b80332e
Parent call ID: 39cbbf17-b1a4-4260-80a5-5ef7464a54b5
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "thinking": "The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.",
    "choice": "easy"
  }
]

[Synalinks]
Call ID: 39cbbf17-b1a4-4260-80a5-5ef7464a54b5
Parent call ID: 4986c872-67f0-4c78-b325-ebdded62ee10
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON:
[
  {
    "thinking": "The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.",
    "choice": "easy"
  }
]

[Synalinks]
Call ID: 9e83482e-6191-456d-8bcf-ce063d4a15d1
Parent call ID: a07da834-9d42-4e55-b085-70942c760816
Module: Generator
Module Name: generator
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "query": "What is 2 + 2?",
    "thinking": "The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.",
    "choice": "easy"
  }
]

[Synalinks]
Call ID: dcf0bc67-6429-45a2-b59a-facb892f2932
Parent call ID: 9e83482e-6191-456d-8bcf-ce063d4a15d1
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "messages": [
      {
        "role": "system",
        "content": "<instructions>\nYour task is to answer with a JSON containing the following keys: ['answer']\n</instructions>\n"
      },
      {
        "role": "user",
        "content": "<input>\n{'query': 'What is 2 + 2?', 'thinking': \"The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.\", 'choice': 'easy'}\n</input>\n<output>\n"
      }
    ]
  }
]

[Synalinks]
Call ID: dcf0bc67-6429-45a2-b59a-facb892f2932
Parent call ID: 9e83482e-6191-456d-8bcf-ce063d4a15d1
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "answer": "4"
  }
]

[Synalinks]
Call ID: 9e83482e-6191-456d-8bcf-ce063d4a15d1
Parent call ID: a07da834-9d42-4e55-b085-70942c760816
Module: Generator
Module Name: generator
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "answer": "4"
  }
]

[Synalinks]
Call ID: 4986c872-67f0-4c78-b325-ebdded62ee10
Parent call ID: 717fdd22-62ad-4aa6-9c23-c19df90093a8
Module: Branch
Module Name: branch
Module Description: Use a `LanguageModel` to select which module(s) to call based on an
Data Model JSON:
[
  {
    "thinking": "The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.",
    "choice": "easy",
    "answer": "4"
  }
]

[Synalinks]
Call ID: 717fdd22-62ad-4aa6-9c23-c19df90093a8
Parent call ID: None
Module: Functional
Module Name: routing
Module Description: A `Functional` program is a `Program` defined as a directed graph of modules.
Data Model JSON:
[
  {
    "thinking": "The question asks for a simple arithmetic operation, which can be easily solved. Therefore, the label would be 'easy'.",
    "choice": "easy",
    "answer": "4"
  }
]

[Synalinks]
Call ID: bd19d92b-5016-4f87-af19-b42c2376b03b
Parent call ID: None
Module: Functional
Module Name: routing
Module Description: A `Functional` program is a `Program` defined as a directed graph of modules.
Data Model JSON:
[
  {
    "query": "Explain why the sky is blue, from first principles."
  }
]

[Synalinks]
Call ID: fd8ec8ac-60a2-4892-8f78-bca235eac9f4
Parent call ID: bd19d92b-5016-4f87-af19-b42c2376b03b
Module: Branch
Module Name: branch
Module Description: Use a `LanguageModel` to select which module(s) to call based on an
Data Model JSON:
[
  {
    "query": "Explain why the sky is blue, from first principles."
  }
]

[Synalinks]
Call ID: 9db59e20-c8ea-402f-bf7b-48f7de7e21cd
Parent call ID: fd8ec8ac-60a2-4892-8f78-bca235eac9f4
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON:
[
  {
    "query": "Explain why the sky is blue, from first principles."
  }
]

[Synalinks]
Call ID: c0afc45c-e993-4773-9b04-eaa83cb230bc
Parent call ID: 9db59e20-c8ea-402f-bf7b-48f7de7e21cd
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "query": "Explain why the sky is blue, from first principles.",
    "question": "How hard is this query to answer?"
  }
]

[Synalinks]
Call ID: 1316be24-f2ee-4cbf-b1f6-36b338088c44
Parent call ID: c0afc45c-e993-4773-9b04-eaa83cb230bc
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "messages": [
      {
        "role": "system",
        "content": "<instructions>\nYou will be given a question, your task is to answer step-by-step to choose\none the following labels: ['easy', 'hard']\n</instructions>\n"
      },
      {
        "role": "user",
        "content": "<input>\n{'query': 'Explain why the sky is blue, from first principles.', 'question': 'How hard is this query to answer?'}\n</input>\n<output>\n"
      }
    ]
  }
]

[Synalinks]
Call ID: 1316be24-f2ee-4cbf-b1f6-36b338088c44
Parent call ID: c0afc45c-e993-4773-9b04-eaa83cb230bc
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "thinking": "The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.",
    "choice": "hard"
  }
]

[Synalinks]
Call ID: c0afc45c-e993-4773-9b04-eaa83cb230bc
Parent call ID: 9db59e20-c8ea-402f-bf7b-48f7de7e21cd
Module: Generator
Module Name: generator_decision_branch
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "thinking": "The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.",
    "choice": "hard"
  }
]

[Synalinks]
Call ID: 9db59e20-c8ea-402f-bf7b-48f7de7e21cd
Parent call ID: fd8ec8ac-60a2-4892-8f78-bca235eac9f4
Module: Decision
Module Name: decision_branch
Module Description: Perform a decision on the given input based on a question and a list of labels.
Data Model JSON:
[
  {
    "thinking": "The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.",
    "choice": "hard"
  }
]

[Synalinks]
Call ID: 566d382b-5291-4fad-b086-056a06318576
Parent call ID: 1316be24-f2ee-4cbf-b1f6-36b338088c44
Module: Generator
Module Name: generator_1
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "query": "Explain why the sky is blue, from first principles.",
    "thinking": "The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.",
    "choice": "hard"
  }
]

[Synalinks]
Call ID: 05ce4c3e-328d-46a9-8fe8-1e947a0ca632
Parent call ID: 566d382b-5291-4fad-b086-056a06318576
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "messages": [
      {
        "role": "system",
        "content": "<instructions>\nYour task is to answer with a JSON containing the following keys: ['thinking', 'answer']\n</instructions>\n"
      },
      {
        "role": "user",
        "content": "<input>\n{'query': 'Explain why the sky is blue, from first principles.', 'thinking': \"The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.\", 'choice': 'hard'}\n</input>\n<output>\n"
      }
    ]
  }
]

[Synalinks]
Call ID: 05ce4c3e-328d-46a9-8fe8-1e947a0ca632
Parent call ID: 566d382b-5291-4fad-b086-056a06318576
Module: LanguageModel
Module Name: language_model
Module Description: A language model API wrapper.
Data Model JSON:
[
  {
    "thinking": "To explain why the sky appears blue from a scientific perspective, we need to understand how light interacts with molecules in the Earth's atmosphere. The process involves Rayleigh scattering, which is the scattering of light by particles much smaller than the wavelength of light. In this case, the particles are air molecules and dust particles. Shorter wavelengths (like blue and violet) are scattered more than longer wavelengths (like red and yellow). However, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering.",
    "answer": "The sky appears blue due to a process called Rayleigh scattering, where shorter wavelengths of light (like blue) are scattered more by air molecules and dust particles in the Earth's atmosphere. Although violet light is scattered more than blue light, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering."
  }
]

[Synalinks]
Call ID: 566d382b-5291-4fad-b086-056a06318576
Parent call ID: 1316be24-f2ee-4cbf-b1f6-36b338088c44
Module: Generator
Module Name: generator_1
Module Description: Use a `LanguageModel` to generate a data model from an arbitrary input data model.
Data Model JSON:
[
  {
    "thinking": "To explain why the sky appears blue from a scientific perspective, we need to understand how light interacts with molecules in the Earth's atmosphere. The process involves Rayleigh scattering, which is the scattering of light by particles much smaller than the wavelength of light. In this case, the particles are air molecules and dust particles. Shorter wavelengths (like blue and violet) are scattered more than longer wavelengths (like red and yellow). However, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering.",
    "answer": "The sky appears blue due to a process called Rayleigh scattering, where shorter wavelengths of light (like blue) are scattered more by air molecules and dust particles in the Earth's atmosphere. Although violet light is scattered more than blue light, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering."
  }
]

[Synalinks]
Call ID: fd8ec8ac-60a2-4892-8f78-bca235eac9f4
Parent call ID: bd19d92b-5016-4f87-af19-b42c2376b03b
Module: Branch
Module Name: branch
Module Description: Use a `LanguageModel` to select which module(s) to call based on an
Data Model JSON:
[
  {
    "thinking": "The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.",
    "choice": "hard",
    "thinking_1": "To explain why the sky appears blue from a scientific perspective, we need to understand how light interacts with molecules in the Earth's atmosphere. The process involves Rayleigh scattering, which is the scattering of light by particles much smaller than the wavelength of light. In this case, the particles are air molecules and dust particles. Shorter wavelengths (like blue and violet) are scattered more than longer wavelengths (like red and yellow). However, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering.",
    "answer": "The sky appears blue due to a process called Rayleigh scattering, where shorter wavelengths of light (like blue) are scattered more by air molecules and dust particles in the Earth's atmosphere. Although violet light is scattered more than blue light, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering."
  }
]

[Synalinks]
Call ID: bd19d92b-5016-4f87-af19-b42c2376b03b
Parent call ID: None
Module: Functional
Module Name: routing
Module Description: A `Functional` program is a `Program` defined as a directed graph of modules.
Data Model JSON:
[
  {
    "thinking": "The question asks for an explanation of a scientific phenomenon based on first principles. This requires understanding and application of physics concepts such as light scattering, refraction, and absorption. Therefore, I would label this query as 'hard'.",
    "choice": "hard",
    "thinking_1": "To explain why the sky appears blue from a scientific perspective, we need to understand how light interacts with molecules in the Earth's atmosphere. The process involves Rayleigh scattering, which is the scattering of light by particles much smaller than the wavelength of light. In this case, the particles are air molecules and dust particles. Shorter wavelengths (like blue and violet) are scattered more than longer wavelengths (like red and yellow). However, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering.",
    "answer": "The sky appears blue due to a process called Rayleigh scattering, where shorter wavelengths of light (like blue) are scattered more by air molecules and dust particles in the Earth's atmosphere. Although violet light is scattered more than blue light, we see the sky as blue rather than violet because our eyes are more sensitive to blue light and because sunlight reaches us with less violet light due to scattering."
  }
]


Easy query -> 4
Hard query -> The sky appears blue due to a process called Rayleigh scattering, wher...

============================================================
Pattern 3: Operators as control flow
============================================================

(a + b) fields: ['answer', 'cons']
(a | None) -> {'answer': 'A'}
(None | b) -> {'cons': 'B'}
(a & None) -> None
(a ^ None) is not None -> True
(a ^ b) is None      -> True
(~a) -> None