# A simple echo out Λ-gent

#! /usr/bin/env nix-shell
#! nix-shell --keep --pure -i runghc
#! nix-shell --keep --pure -p '(haskellPackages.extend (self: super: {pin = self.callHackageDirect { pkg = "A-gent"; ver = "0.11.0.18"; sha256 = "BsvlGOludmvVvfjLYvjBkQumj2VuIe6M8kB/9CYkLlo=";} {};})).ghcWithPackages (ps: with ps; [ pin ])'

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. However, we do pin the latest Λ-gent package.

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           Prelude             hiding ( mod )
>
> import           Agent.IO.Restricted
>   ( RIO
>   )
> import           Agent.LLM
>   ( Eval
>   , Context (Context, mode)
>   , Mode(Echo)
>   , mode
>   , replWithMode
>   )
> import qualified Agent.LLM.Action    as ACT
> import qualified Agent.LLM.Message   as MSG

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 it-sec tab:

> eval :: Eval ()
> eval ctx msg =
>   case ctx of
>     Context { mode = Echo } -> echo    ctx           msg
>     _______________________ -> return (ctx, ACT.text err)
>   where
>     mod = mode ctx
>     err = show mod ++ " mode is not available for this agent"
> echo
>   :: Context ()
>   -> MSG.Message
>   -> RIO (Context (), ACT.Action)
> echo ctx msg =
>   case msg of
>     MSG.Text txt ->
>       return (ctx, ACT.text rep)
>       where
>         rep = concat $ replicate num $ txt ++ " "
>         num = 3
>     ____________ ->
>       return
>         ( ctx
>         , ACT.text
>           $ "The following message '" ++ show msg ++ "', is not supported"
>         )

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 Nothing

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 .lhs script (*) file and once again converting it to an executable file with chmox +x echo.lhs, you now execute it like this: ./echo.lhs from a terminal.

(*) - You MUST install the nix package manager on your operating system for this script to work: https://nixos.org/download/

The result from executing the script will be:

# Exit Λ-gent with /e or /exit. For more commands, type /? or /help.
Λ-echo> hello
hello hello hello 
Λ-echo> world
world world world 
Λ-echo> /help
# Supported commands:
--------------------------------------------------------------------------------
/?   or /help   | This message
/e   or /exit   | Exit Λ-gent
/w   or /wipe   | Clear screen
--------------------------------------------------------------------------------
/m m or /mode m | Change to {auto|chat|code|docs|echo|plan|test}. Ex: /m plan
--------------------------------------------------------------------------------
/h   or /hist   | View history (input and output)
        /chit   | View history (only input) 
        /chat   | View history (only output)
--------------------------------------------------------------------------------
/l f or /list f | List of files, limited by mode, file masks and filter
/p   or /pile   | Show stored list of files. See /list above
/f i or /file i | Show file with the given index. See /pile above
/n i or /nums i | Show file with line numbers. See /file above
--------------------------------------------------------------------------------
/s m or /send m | Sending /pile to LLM as context to the message
/r o or /ruck o | View files (opt index) from LLM response. See /send
/a d or /atom d | Atomically save /ruck files to a GIT branch (+ description)
        /repo   | List GIT branches (+ description). See /atom above
--------------------------------------------------------------------------------
Λ-echo> /mode chat
Changed to chat-mode
Λ-chat> hello
Only echo-mode is available for this agent
Λ-chat> /exit
Λ-gent will shutdown