# A simple echo out Λ-gent
#! /usr/bin/env nix-shell
#! nix-shell --keep --pure -i runghc
#! nix-shell --keep --pure -p haskell.compiler.ghc9103
#! nix-shell --keep --pure -p 'haskellPackages.ghcWithPackages (ps: with ps; [A-gent])'
As we did in the basic example from the chat tab, we add, on the top of the file, the following header as that will allow us to run the code as a script.
Notice that we don’t add the packages cacert and curl as we are only going
to make an Λ-gent that will echo (repeat and fade away) the
provided input n times.
We add the exact code options and language features to ensure clean and maintainable code as well as ensuring it ONLY executes safe-code and behaves nicely:
> {-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
>
> {-# LANGUAGE Safe #-}
> {-# LANGUAGE NoGeneralizedNewtypeDeriving #-}
Licensing information as well and fewer library imports:
> --------------------------------------------------------------------------------
> --
> -- Λ-gent, (c) 2026 SPISE MISU ApS, https://spdx.org/licenses/SSPL-1.0
> --
> --------------------------------------------------------------------------------
>
> import Agent.LLM
> ( Eval
> , Mode(Echo)
> , mode
> , replWithMode
> )
No need to define (showable) communication data entities as we aren’t going to
interact with any external resources. In this case, we will ONLY handle the
echo-mode. However, we don’t need to create separate logic as we can just handle
that in the eval function, but, we will do anyway due to protection rings, see
section below:
> eval :: Eval String
> eval ctx txt =
> case mode ctx of
> Echo -> return $ echo ctx txt
> ____ -> return (ctx, "Only echo-mode is available for this agent")
> echo
> :: Context String
> -> String
> -> (Context String, String)
> echo ctx txt =
> (ctx, rep)
> where
> rep = concatMap id $ take num $ repeat $ txt ++ " "
> num = 3
And finally, in this case, we will use the replWithMode which allow us to pass
a specific Λ-gent mode on execution:
> main :: IO ()
> main =
> replWithMode Echo eval
Notice how we do NOT need to define any effects and the script will still execute.
Note: And by copying the text from this section, except this note, and saving it to a
.lhsscript (*) file and once again converting it to an executable file withchmox +x echo.lhs, you now execute it like this:./echo.lhsfrom a terminal.(*) - You MUST install the
nixpackage manager on your operating system for this script to work: https://nixos.org/download/
The result from executing the script will be:
# Quit Λ-gent with `/exit`. For more commands, type `/help`.
Λ-echo> hello
hello hello hello
Λ-echo> world
world world world
Λ-echo> /help
# Supported commands
* /help : This message
* /exit : Quit Λ-gent
* /mode : Change mode to {auto|chat|code|docs|echo|plan|test}`. Ex:`/mode code`
Λ-echo> /mode chat
Changed to chat-mode
Λ-chat> hello
Only echo-mode is available for this agent
Λ-chat> /exit
Λ-gent will shutdown
# Protection rings
If we look at the definition at Wikipedia:
«In computer science, hierarchical protection domains, often called protection rings, are mechanisms to protect data and functionality from faults (by improving fault tolerance) and malicious behavior (by providing computer security)»
| Figure 0: Derived Priv rings (Hertzsprung) CC BY-SA-3.0 |
Notice that from eval (kernel or core), we will be able to execute all
restricted IO effects. We want to avoid being in ring 0 as much as
possible. Therefore, we would ideally branch out for each of the modes our
Λ-gents need to support.
Furthermore, we would like to keep branching in case some of the subprocesses need to read and write files as well as interact with web services.
For the sake of transparency and clarity, a ring (sunburst)
chart seems to reflect best how typical Λ-gents behave.