Skip to content

Commit 3896ee6

Browse files
Merge pull request #53 from bit8bytes/exp
refactor: beago is using Unix pipe approach now
2 parents 8c384f9 + c56f358 commit 3896ee6

58 files changed

Lines changed: 925 additions & 2145 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.envrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
use flake

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,7 @@ go.work.sum
2626
.env
2727

2828
/tmp
29-
/bin
29+
/bin
30+
31+
# nix
32+
.direnv/

README.md

Lines changed: 59 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,79 @@
22

33
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) ![Test](https://github.com/bit8bytes/beago/actions/workflows/tests.yml/badge.svg) ![Sec Scan](https://github.com/bit8bytes/beago/actions/workflows/sec_scan.yml/badge.svg)
44

5-
beago provides composable building blocks for LLM-powered Go applications — pipes for structured output, agents for tool-using reasoning loops, and stores for conversation history. The core library has no external dependencies.
5+
beago brings the Unix philosophy to LLM applications: small, focused handlers connected by pipes. Each handler reads from an `io.Reader`, transforms the stream, and writes to an `io.Writer` — exactly like Unix programs connected with `|`. The core library has no external dependencies.
6+
7+
## The Unix Pipe Model
8+
9+
Unix pipes let you compose small programs into powerful workflows:
10+
11+
```
12+
echo "text" | translate | summarise | fmt
13+
```
14+
15+
beago works the same way, but for LLM pipelines:
16+
17+
```go
18+
pipe.Execute(ctx, os.Stdin, os.Stdout,
19+
llm.Prompt("Translate to French."),
20+
llm.Generate(model), // stdin | translate
21+
llm.Prompt("Summarise in one sentence."),
22+
llm.Generate(model), // | summarise
23+
)
24+
```
25+
26+
Each `pipe.Handler` is a composable unit. Handlers are chained with `pipe.Execute`, looped with `pipe.Loop`, and debugged with `pipe.Tee` — mirroring Unix's `tee(1)`.
627

728
## Core Concepts
829

9-
- **Pipes** — simple `Input → LLM → Output` pipelines with typed, structured responses
30+
- **Pipe** — the core primitive: a `Handler` that reads `io.Reader` → transforms → writes `io.Writer`
31+
- **Execute** — chains handlers sequentially, connecting each output to the next input via `io.Pipe`
32+
- **Loop** — runs a handler chain repeatedly, feeding each iteration's output as the next input; stops on `ErrDone` or a max iteration count
33+
- **Tee** — splits the stream like Unix `tee(1)`: passes data through while copying to a second writer for debugging
1034
- **Agents** — ReAct (Reasoning + Acting) loops that interleave LLM reasoning with tool execution
11-
- **Stores** — tamper-evident message history with a SHA-256 hash chain, keeping LLMs stateful across turns
1235
- **Tools** — implement the `Tool` interface to give agents new capabilities
1336

1437
## Quick Start
1538

1639
```go
17-
// Pipe: send messages and get structured output
18-
pipe := pipes.New(messages, model, parser)
19-
result, _ := pipe.Invoke(ctx)
40+
// Single handler: pipe stdin through an LLM to stdout
41+
// echo "What is 2+2?" | go run .
42+
pipe.Execute(ctx, os.Stdin, os.Stdout,
43+
llm.Generate(model),
44+
)
2045
```
21-
See [Pipe](/examples/pipes/json/main.go) for full working `pipe` example.
2246

2347
```go
24-
// Agent: reason and act with tools
25-
agent, _ := agents.NewReAct(ctx, model, tools, storage)
26-
agent.Task(ctx, "Use the helloWorld tool with name Beago")
27-
res, _ := runner.New(agent).Run(ctx)
48+
// Chain handlers: translate then summarise
49+
pipe.Execute(ctx, os.Stdin, os.Stdout,
50+
llm.Prompt("Translate to French."),
51+
llm.Generate(model),
52+
llm.Prompt("Summarise in one sentence."),
53+
llm.Generate(model),
54+
)
2855
```
2956

30-
See [Agent](/examples/agents/hello/main.go) for full working `agent` example.
57+
```go
58+
// Loop until the LLM outputs "DONE"
59+
pipe.Execute(ctx, os.Stdin, os.Stdout,
60+
pipe.Loop(10,
61+
llm.Generate(model),
62+
pipe.Exit(func(b []byte) bool {
63+
return bytes.Contains(b, []byte("DONE"))
64+
}),
65+
),
66+
)
67+
```
68+
69+
## Examples
70+
71+
| Example | Description |
72+
|---|---|
73+
| [pipe](/examples/pipe/main.go) | Single LLM call — the simplest pipe |
74+
| [pipe/tee](/examples/pipe/tee/main.go) | Split the stream with `Tee` to inspect output |
75+
| [pipe/chain](/examples/pipe/chain/main.go) | Chain two LLM calls: translate → summarise |
76+
| [pipe/loop](/examples/pipe/loop/main.go) | Loop until a stop condition is met |
77+
| [agents](/examples/agents/main.go) | ReAct agent with tools |
3178

3279
## Contributions
3380

agents/agents.go

Lines changed: 0 additions & 160 deletions
This file was deleted.

agents/messages.go

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)