> For the complete documentation index, see [llms.txt](https://myshell-ai.gitbook.io/neuralautomata/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://myshell-ai.gitbook.io/neuralautomata/guidelines.md).

# Guidelines

### App

In Python implementation of NeuralAutomata, the app is implemented by `AutomataGradio` class, since the UI is achieved by gradio. For example:

```python
from neuralautomata.renderers import GradioRenderer

automata = AutomataGradio(
    name="duolingo_demo",
    start_at="login_page",
    event_listeners={
        'login_page:signup_btn.click': "signup_page",
        'signup_page:login_btn.click': 'login_page',
    },
    states={
        "login_page": login_page,
        "signup_page": signup_page,
        "setup_language_page": setup_language_page,
        "learn_page": learn_page,
        "quiz_image_page": quiz_image_page,
        "quiz_explain_page": quiz_explain_page,
        "quiz_translation_page": quiz_translation_page,
        "summary_page": summary_page,
    }
)
GradioRenderer.render(automata)
```

the `GradioRender.render`function will launch the gradio app.

### Page

We need to define the state transfer inside each page. It is recommended to draw a graph of the states before writing the code. The `AutomataPage` class is inherited from the `NestedState` with an extra attribute called `layout` which is helpful to control how the UI components display in the page. Please refer to [here](/neuralautomata/layout.md) for detailed grammar of the layout.

### States

It is crucial to understand how to arrange the states inside a page to make it work properly. As a `NestedState`, the execution of  `AutomataPage` would start from the state defined by `start_at` and perform state transfer according to the `next_state` property of each state, and stop when the `next_state` of a state is `None` or the current state name equals the `end_at` attribute. When the state machine is halted, we can use event listeners to jump to another state and resume the automata. A common case is that when we want the user to input some information (e.g., via `Textbox`, `Dropdown`, etc):

```python
page= AutomataPage(
    name="test_page",
    start_at="first_state",
    end_at="end_state",
    next_state="next_page",
    layout=None,
    event_listeners={
        "confirm_btn.click": {
            "goto": {
                "next_state": "input_state",
            },
        }
    },
    states={
        "first_state": TaskState(
            ...,
            next_state=None, # the automata will halt here
        ),
        "input_state": TaskState(
            name="signup_state",
            inputs={
                "username": Textbox(
                    value="",
                    placeholder="username",
                    show_label=False,
                ),
                "password": Textbox(
                    value="",
                    text_type="password",
                    placeholder="password",
                    show_label=False,
                ),
                "confirm_btn": Button(
                    value="Signup",
                    interactive=True,
                ),
            },
            next_state="end_state"
        ),
        "end_state": TaskState(
            ...
        ),
    } 
)

```

in the example above, the automata will halt after the execution of first\_state, and when the user click the `confirm_btn` it will jump to `input_state` and resume the automata.

It is a common usage that a page will stop at the very beginning to wait for user inputs. We then introduce a new attribute for `NestedState` called `use_idle_state`. When `use_idle_state=True`, an idle state (the `next_state` of which is None) is created and the nested state will start from it and then halt to wait for user inputs.

### Context

The context in NeuralAutomata means the existing variables in the current scope. Context (or ctx in code) is defined in each NestedState. At the initialization of Automata, it will recursively set a `prefix` for each `NestedState` to identify the namespace. Manipulation of the variables inside a `NestedState` will not affect the variables with the same names in another `NestedState` by default. When using recursive `NestedState`, it is common to pass some variables from the parent ctx to the children ctx and obtain the processed results of the variables from the children ctx, which can be achieved by specifying the `inputs` and `outputs` of the children `NestedState`, please see [here ](/neuralautomata/states/nestedstate.md)for details.

### Other tricks

#### Setting the Next State Dynamically

Sometimes we need to dynamically determine the next state name. This can be achieved by modifying the value of `NEXT_STATE_NAME`&#x20;

```python
from neuralautomata.core.state import NEXT_STATE_NAME
```

&#x20;If `NEXT_STATE_NAME` is set properly, the `get_next_state` method of `NestedState`will return that instead of self.next\_state
