enno

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 7, 2026 License: MIT Imports: 5 Imported by: 0

README

Enno

Enno is a lightweight Go agent framework that can be embedded as a package or installed as a CLI agent.

It provides a provider-agnostic Agent loop, a composable tool system, built-in OpenAI-compatible and Anthropic providers, and optional tools for todo tracking, filesystem access, and shell execution.

Repository: github.com/dean2021/enno

Features

  • Provider-neutral core package: Agent, Provider, Tool, Message, Request, and Response.
  • OpenAI-compatible provider via provider/openai.
  • Anthropic Messages API provider via provider/anthropic.
  • Optional built-in tools:
    • tools/todo
    • tools/filesystem
    • tools/shell
  • Installable CLI at cmd/enno.
  • Extensible tool and provider interfaces for custom integrations.

Installation

Install the CLI:

go install github.com/dean2021/enno/cmd/enno@latest

Use as a Go package:

go get github.com/dean2021/enno

Install a specific version:

go install github.com/dean2021/enno/cmd/enno@v0.1.0
go get github.com/dean2021/enno@v0.1.0

CLI Usage

Start the terminal UI interactive mode:

enno

Type a task and press Enter. Use Esc, Ctrl+C, q, or exit to leave the interactive UI.

Run a single prompt:

enno run "Analyze this repository"

Configure the CLI in ~/.enno/config.yaml. If the default config file does not exist, Enno creates a commented template on startup:

provider: openai
model: your-model
api_key: your-key
base_url: https://example.com/v1
max_tokens: 4096
shell: true
filesystem: true

Use a custom config file:

enno --config /path/to/config.yaml
enno run --config /path/to/config.yaml "Analyze this repository"

Common flags:

enno --workdir .
enno --no-shell
enno --no-filesystem

Provider, model, API key, base URL, and max token settings are read from config.yaml only. The CLI does not read ENNO_* environment variables for these values.

Package Usage

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/dean2021/enno"
	openaiprovider "github.com/dean2021/enno/provider/openai"
	"github.com/dean2021/enno/tools/filesystem"
	"github.com/dean2021/enno/tools/todo"
)

func main() {
	tools := []enno.Tool{todo.New()}
	tools = append(tools, filesystem.New(filesystem.Config{Root: "."})...)

	agent, err := enno.NewAgent(enno.Config{
		Provider: openaiprovider.New(openaiprovider.Config{
			APIKey:  os.Getenv("ENNO_API_KEY"),
			BaseURL: os.Getenv("ENNO_BASE_URL"),
			Model:   os.Getenv("ENNO_MODEL"),
		}),
		SystemPrompt: "You are a helpful coding agent.",
		Tools:        tools,
	})
	if err != nil {
		panic(err)
	}

	answer, err := agent.Run(context.Background(), "List the files in this workspace.")
	if err != nil {
		panic(err)
	}
	fmt.Println(answer)
}

Anthropic Provider

agent, err := enno.NewAgent(enno.Config{
	Provider: anthropicprovider.New(anthropicprovider.Config{
		APIKey:    os.Getenv("ANTHROPIC_API_KEY"),
		Model:     "claude-sonnet-4-5-20250929",
		MaxTokens: 4096,
	}),
	SystemPrompt: "You are a helpful agent.",
	Tools:        []enno.Tool{todo.New()},
})

Custom Tools

type GreetArgs struct {
	Name string `json:"name"`
}

greet := enno.NewTypedTool("greet", "Greet a person by name.", map[string]any{
	"name": map[string]any{"type": "string"},
}, []string{"name"}, func(ctx context.Context, args GreetArgs) (string, error) {
	return "Hello, " + args.Name + "!", nil
})

Then pass the tool to an agent:

agent, err := enno.NewAgent(enno.Config{
	Provider: provider,
	Tools:    []enno.Tool{greet},
})

Architecture

enno/
  agent.go              core Agent loop
  config.go             Agent configuration
  message.go            provider-neutral messages
  tool.go               tool declaration and execution API
  provider_iface.go     provider interface

  provider/openai       OpenAI-compatible provider
  provider/anthropic    Anthropic provider
  tools/todo            todo tool
  tools/filesystem      file read/write/edit tools
  tools/shell           shell tool
  internal/cliui        CLI-only terminal UI
  internal/cliconfig    CLI-only configuration parsing
  cmd/enno              installable CLI
  examples              usage examples
  docs                  design and usage documentation

See:

Versioning

Enno follows Semantic Versioning. The current initial release line is v0.x.y while the public API is still evolving.

Useful release commands:

make help
make version
make release-check
make tag

make tag creates a Git tag for the version in VERSION, such as v0.1.0. Pushing the tag triggers the release workflow.

Safety Notes

  • Avoid enabling tools/shell in production without sandboxing.
  • Always configure tools/filesystem with a restricted root directory.
  • Do not hard-code API keys in source code.
  • Use separate Agent instances for independent user sessions.

License

Enno is released under the MIT License.

Documentation

Index

Constants

View Source
const DefaultMaxToolRounds = 50

Variables

View Source
var ErrMissingProvider = errors.New("enno: missing provider")

Functions

func ToolMap

func ToolMap(tools []Tool) map[string]Tool

Types

type Agent

type Agent struct {
	// contains filtered or unexported fields
}

func NewAgent

func NewAgent(config Config) (*Agent, error)

func (*Agent) Messages

func (a *Agent) Messages() []Message

func (*Agent) Reset

func (a *Agent) Reset()

func (*Agent) Run

func (a *Agent) Run(ctx context.Context, input string) (string, error)

type Config

type Config struct {
	Provider      Provider
	SystemPrompt  string
	Tools         []Tool
	MaxToolRounds int
}

type Message

type Message struct {
	Role       Role
	Content    string
	ToolCallID string
	ToolCalls  []ToolCall
}

func AssistantMessage

func AssistantMessage(content string, toolCalls []ToolCall) Message

func ToolMessage

func ToolMessage(toolCallID, content string) Message

func UserMessage

func UserMessage(content string) Message

type Provider

type Provider interface {
	Complete(ctx context.Context, req Request) (Response, error)
}

type Request

type Request struct {
	SystemPrompt string
	Messages     []Message
	Tools        []Tool
}

type Response

type Response struct {
	Content   string
	ToolCalls []ToolCall
}

type Role

type Role string
const (
	RoleUser      Role = "user"
	RoleAssistant Role = "assistant"
	RoleTool      Role = "tool"
)

type Tool

type Tool struct {
	Name        string
	Description string
	Properties  map[string]any
	Required    []string
	Handler     ToolHandler
}

func NewTool

func NewTool(name, description string, properties map[string]any, required []string, handler ToolHandler) Tool

func NewTypedTool

func NewTypedTool[T any](name, description string, properties map[string]any, required []string, handler func(context.Context, T) (string, error)) Tool

type ToolCall

type ToolCall struct {
	ID        string
	Name      string
	Arguments json.RawMessage
}

type ToolHandler

type ToolHandler func(context.Context, json.RawMessage) (string, error)

Directories

Path Synopsis
cmd
enno command
examples
anthropic command
custom_tool command
simple_agent command
internal
tools

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL