enno

package module
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: May 9, 2026 License: MIT Imports: 12 Imported by: 0

README

Enno

Enno is a lightweight, provider-neutral Go agent framework. It owns the core Agent loop, explicit session state, tool dispatch, provider interfaces, SDK assembly helpers, and built-in tool implementations.

The former in-repo CLI has moved to the standalone Godo project at ../godo-coding-agent. Enno now focuses on SDK/provider functionality; applications and CLIs should depend on Enno through public packages only.

Repository: github.com/dean2021/enno

Features

  • Provider-neutral core package: Agent, Session, RunResult, Provider, Tool, Message, Request, and Response.
  • OpenAI-compatible provider via provider/openai.
  • Anthropic Messages API provider via provider/anthropic.
  • High-level enno.NewAgent with enno.Config for configuring built-in tools, custom tools, permissions, hooks, policies, compaction, and prompt sections. Blank-import github.com/dean2021/enno/setup to register built-in tool builders before calling enno.NewAgent with BuiltinTools.
  • Built-in tools for task graph, filesystem, shell, grep, glob, fetch_url, subagent, load_skill, and compact.
  • Optional events for observing model calls, tool calls, results, and token usage without exposing hidden chain-of-thought.

Installation

go get github.com/dean2021/enno

For the standalone coding-agent CLI, use the Godo project:

cd ../godo-coding-agent
go install ./cmd/godo

SDK Quick Start

package main

import (
	"context"
	"fmt"
	"os"
	"time"

	"github.com/dean2021/enno"
	openaiprovider "github.com/dean2021/enno/provider/openai"
	_ "github.com/dean2021/enno/setup"
)

func main() {
	provider, err := openaiprovider.New(openaiprovider.Config{
		APIKey:  os.Getenv("ENNO_API_KEY"),
		BaseURL: os.Getenv("ENNO_BASE_URL"),
		Model:   os.Getenv("ENNO_MODEL"),
	})
	if err != nil {
		panic(err)
	}

	agent, err := enno.NewAgent(enno.Config{
		Provider:     provider,
		SystemPrompt: "Follow the application-provided sections below.",
		SystemPromptSections: []enno.SystemPromptSection{
			{Name: "Identity", Content: "You are a helpful coding agent."},
			{Name: "Output Style", Content: "Be concise and concrete."},
		},
		BuiltinTools: enno.BuiltinTools{
			TaskGraph:  &enno.TaskGraphTool{Root: ".", Timeout: 120 * time.Second},
			Filesystem: &enno.FilesystemTool{Root: "."},
			Grep:       &enno.GrepTool{Root: "."},
			Glob:       &enno.GlobTool{Root: "."},
			FetchURL:   &enno.FetchURLTool{Timeout: 30 * time.Second},
		},
	})
	if err != nil {
		panic(err)
	}

	session := &enno.Session{}
	result, err := agent.Run(context.Background(), session, "List the files in this workspace.")
	if err != nil {
		panic(err)
	}
	fmt.Println(result.Content)
}

Architecture

enno/
  agent.go              core Agent loop
  run_result.go         detailed run result types
  session.go            explicit conversation state
  stream.go             streaming interfaces and events
  request_options.go    provider-neutral request options
  hooks.go              lifecycle control hooks
  policy.go             loop policies
  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
  provider/internal     provider-shared helpers
  setup                 registers built-in tool builders (blank-import)
  builtintools           built-in tool implementations
  prompt                 SDK runtime prompt helpers
  examples              SDK usage examples
  docs                  design, usage, release, and migration docs

See:

Development

make help
make test
make verify

make verify formats code, tidies modules, and runs all SDK tests.

Safety Notes

  • Avoid enabling enno.ShellTool in production without sandboxing.
  • Always configure enno.FilesystemTool with a restricted root directory.
  • Do not hard-code API keys in source code.
  • Use separate Session values for independent conversations.

License

Enno is released under the MIT License.

Documentation

Overview

Package enno provides a provider-neutral agent runtime for Go applications.

The core type is Agent. Callers use Agent.Run with an explicit Session and receive a structured RunResult. Optional streaming, events, policies, and hooks provide additional control and observability.

Index

Constants

View Source
const (
	ToolChoiceAuto     = "auto"
	ToolChoiceNone     = "none"
	ToolChoiceRequired = "required"
	ToolChoiceTool     = "tool"
)
View Source
const (
	ResponseFormatText       = "text"
	ResponseFormatJSONObject = "json_object"
	ResponseFormatJSONSchema = "json_schema"
)
View Source
const CompactionToolName = "compact"

CompactionToolName is the registered tool name for manual compaction.

Variables

View Source
var ErrMissingProvider = errors.New("enno: missing provider")
View Source
var ErrNilSession = errors.New("enno: nil session")
View Source
var ErrUnsupportedOption = errors.New("enno: unsupported request option")

Functions

func FormatCompactSummary added in v0.5.0

func FormatCompactSummary(raw string) string

FormatCompactSummary strips <analysis>, extracts <summary> body when present, and normalizes whitespace. If no <summary> tag is found, returns the whole string trimmed (backward compatible).

func RegisterToolBuilder added in v0.13.0

func RegisterToolBuilder(b ToolBuilder)

RegisterToolBuilder installs the tool builder used by NewAgent when BuiltinTools or related config fields are set. Call this from a wiring package (e.g. main) that imports both enno and the builtintools packages.

func ToolMap

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

Types

type AfterProviderCallResult added in v0.7.0

type AfterProviderCallResult struct {
	Response *Response
	Abort    error
}

type AfterProviderCallState added in v0.7.0

type AfterProviderCallState struct {
	Round    int
	Request  Request
	Response Response
}

type AfterToolCallResult added in v0.7.0

type AfterToolCallResult struct {
	ToolResult *ToolResult
	Abort      error
}

type AfterToolCallState added in v0.7.0

type AfterToolCallState struct {
	Round      int
	Request    Request
	ToolCall   ToolCall
	ToolResult ToolResult
	Err        error
}

type Agent

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

func NewAgent

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

func (*Agent) Run

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

func (*Agent) RunStream added in v0.7.0

func (a *Agent) RunStream(ctx context.Context, session *Session, input string, handler StreamHandler) (RunResult, error)

type BeforeProviderCallResult added in v0.7.0

type BeforeProviderCallResult struct {
	Request *Request
	Abort   error
}

type BeforeProviderCallState added in v0.7.0

type BeforeProviderCallState struct {
	Round   int
	Request Request
}

type BeforeToolCallResult added in v0.7.0

type BeforeToolCallResult struct {
	ToolCall    *ToolCall
	Deny        bool
	DenyMessage string
	Abort       error
}

type BeforeToolCallState added in v0.7.0

type BeforeToolCallState struct {
	Round    int
	Request  Request
	ToolCall ToolCall
}

type BuiltTools added in v0.13.0

type BuiltTools struct {
	Tools         []Tool
	SkillsSummary string
}

BuiltTools holds the result of assembling built-in tool configuration.

type BuiltinTools added in v0.13.0

type BuiltinTools struct {
	TaskGraph  *TaskGraphTool
	Filesystem *FilesystemTool
	Shell      *ShellTool
	Grep       *GrepTool
	Glob       *GlobTool
	FetchURL   *FetchURLTool
	Subagent   *SubagentTool
	LoadSkill  *LoadSkillTool
	Compact    *CompactTool
}

type CompactTool added in v0.13.0

type CompactTool struct{}

type CompactionConfig added in v0.5.0

type CompactionConfig struct {
	Enabled bool

	// TranscriptDir stores JSONL transcripts before summarization. Empty keeps
	// transcript persistence disabled; applications that enable compaction should
	// set this when they want transcripts written to disk.
	TranscriptDir string

	// ModelContextTokens, when positive, sets auto-compact threshold to
	// ModelContextTokens - AutoCompactBufferTokens (buffer defaults to 13000 in withDefaults).
	// Takes precedence over AutoCompactInputTokens when the difference is positive.
	ModelContextTokens int64

	// AutoCompactBufferTokens is subtracted from ModelContextTokens for the effective threshold.
	// Ignored when ModelContextTokens is zero. Zero defaults to 13000 when ModelContextTokens > 0.
	AutoCompactBufferTokens int64

	// AutoCompactInputTokens triggers summarization when estimated/conservative input tokens
	// meet or exceed this value. Zero defaults to 50000 when ModelContextTokens is zero.
	AutoCompactInputTokens int64

	// KeepRecentToolResults is how many latest eligible RoleTool messages keep full content in Micro.
	// Zero defaults to 3.
	KeepRecentToolResults int

	// MicroCompactMinChars replaces longer RoleTool contents with a placeholder. Zero defaults to 100.
	MicroCompactMinChars int

	// MicroCompactToolNames, when non-empty, limits Micro compaction to tool results whose tool name
	// is in this list. Empty means all RoleTool messages participate (legacy behavior).
	MicroCompactToolNames []string

	// SkipOnSummarizeError, when true, causes automatic compaction to log an error event and continue
	// without replacing history if summarization fails. Manual compact via the compact tool remains strict.
	SkipOnSummarizeError bool
}

CompactionConfig enables optional context compaction (micro-trimming of old tool results, automatic summarization when estimated input size exceeds a threshold, and the manual compact tool). Nil in Config means compaction is disabled.

type Config

type Config struct {
	Provider             Provider
	SystemPrompt         string
	SystemPromptSections []SystemPromptSection
	BuiltinTools         BuiltinTools
	Permissions          ToolPermissions
	Tools                []Tool
	CustomTools          []Tool
	MaxToolRounds        int
	EventHandler         EventHandler
	Compaction           *CompactionConfig
	Options              RequestOptions
	Policies             []Policy
	Hooks                []Hook
}

func AssembleConfig added in v0.13.0

func AssembleConfig(config Config) (Config, error)

AssembleConfig resolves the high-level Config fields (BuiltinTools, SystemPromptSections, Permissions, CustomTools) into a low-level Config ready for Agent construction. It is called automatically by NewAgent when any assembly-level fields are set.

type Event added in v0.3.0

type Event struct {
	Type         EventType
	Round        int
	MessageCount int
	ToolCount    int
	Content      string
	Thinking     string
	ToolCall     ToolCall
	ToolResult   string
	ToolError    bool
	ToolMetadata map[string]any
	Usage        Usage
	Duration     time.Duration
	Err          error
}

type EventHandler added in v0.3.0

type EventHandler func(context.Context, Event)

type EventType added in v0.3.0

type EventType string
const (
	EventModelStart    EventType = "model_start"
	EventModelResponse EventType = "model_response"
	EventToolStart     EventType = "tool_start"
	EventToolResult    EventType = "tool_result"
	EventRoundComplete EventType = "round_complete"
	EventError         EventType = "error"
)

type FetchURLTool added in v0.13.0

type FetchURLTool struct {
	Timeout        time.Duration
	MaxOutputChars int
	UserAgent      string
}

type FilesystemTool added in v0.13.0

type FilesystemTool struct {
	Root           string
	Read           bool
	Write          bool
	MaxOutputChars int
}

type GlobTool added in v0.13.0

type GlobTool struct {
	Root           string
	Timeout        time.Duration
	MaxOutputChars int
}

type GrepTool added in v0.13.0

type GrepTool struct {
	Root           string
	Timeout        time.Duration
	MaxOutputChars int
}

type LoadSkillTool added in v0.13.0

type LoadSkillTool struct {
	Dirs []string
}

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 NoopHook added in v0.7.0

type NoopHook struct{}

func (NoopHook) AfterProviderCall added in v0.7.0

func (NoopHook) AfterToolCall added in v0.7.0

func (NoopHook) BeforeProviderCall added in v0.7.0

func (NoopHook) BeforeToolCall added in v0.7.0

type PermissionMode added in v0.13.0

type PermissionMode string
const (
	PermissionAsk   PermissionMode = "ask"
	PermissionAllow PermissionMode = "allow"
	PermissionDeny  PermissionMode = "deny"
)

type Policy added in v0.7.0

type Policy interface {
	BeforeModel(context.Context, *RunState) error
	AfterModel(context.Context, *RunState) error
	AfterTools(context.Context, *RunState) error
}

type Provider

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

type Request

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

type RequestOptions added in v0.7.0

type RequestOptions struct {
	Temperature     *float64
	MaxOutputTokens int64
	ToolChoice      ToolChoice
	ResponseFormat  ResponseFormat
	Metadata        map[string]string
}

func (RequestOptions) IsZero added in v0.7.0

func (o RequestOptions) IsZero() bool

func (RequestOptions) WithDefaults added in v0.7.0

func (o RequestOptions) WithDefaults(defaults RequestOptions) RequestOptions

type Response

type Response struct {
	Content   string
	Thinking  string
	ToolCalls []ToolCall
	Usage     Usage
}

func ConsumeStream added in v0.7.0

func ConsumeStream(ctx context.Context, stream Stream, handler StreamHandler) (Response, error)

type ResponseFormat added in v0.7.0

type ResponseFormat struct {
	Type        string
	Name        string
	Description string
	Schema      map[string]any
	Strict      *bool
}

type Role

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

type RoundResult added in v0.7.0

type RoundResult struct {
	Round      int
	ModelUsage Usage
	Assistant  Message
	ToolCalls  []ToolCallResult
	Duration   time.Duration
}

type RunResult added in v0.7.0

type RunResult struct {
	Content    string
	Messages   []Message
	Usage      Usage
	Rounds     []RoundResult
	StopReason StopReason
	Duration   time.Duration
}

type RunStartPolicy added in v0.7.0

type RunStartPolicy interface {
	OnRunStart()
}

type RunState added in v0.7.0

type RunState struct {
	Round int

	Session *Session
	Request Request

	Response   Response
	ModelUsage Usage

	ToolCallResults   []ToolCallResult
	SkipToolExecution bool
}

type Schema added in v0.7.0

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

func SchemaObject added in v0.7.0

func SchemaObject() *Schema

func (*Schema) BooleanProp added in v0.7.0

func (s *Schema) BooleanProp(name string) *Schema

func (*Schema) EnumProp added in v0.7.0

func (s *Schema) EnumProp(name string, values ...string) *Schema

func (*Schema) IntegerProp added in v0.7.0

func (s *Schema) IntegerProp(name string) *Schema

func (*Schema) Properties added in v0.7.0

func (s *Schema) Properties() map[string]any

func (*Schema) Required added in v0.7.0

func (s *Schema) Required(names ...string) *Schema

func (*Schema) RequiredFields added in v0.7.0

func (s *Schema) RequiredFields() []string

func (*Schema) StringProp added in v0.7.0

func (s *Schema) StringProp(name string) *Schema

type Session added in v0.7.0

type Session struct {
	Messages []Message
	// contains filtered or unexported fields
}

func (*Session) Append added in v0.7.0

func (s *Session) Append(message Message)

func (Session) Clone added in v0.7.0

func (s Session) Clone() Session

func (*Session) Reset added in v0.7.0

func (s *Session) Reset()

type ShellSafetyPolicy added in v0.13.0

type ShellSafetyPolicy string
const (
	ShellSafetyPolicyDenyList ShellSafetyPolicy = "denylist"
	ShellSafetyPolicyAllowAll ShellSafetyPolicy = "allow_all"
)

type ShellTool added in v0.13.0

type ShellTool struct {
	Workdir        string
	Timeout        time.Duration
	DenyList       []string
	MaxOutputChars int
	SafetyPolicy   ShellSafetyPolicy
}

type StopReason added in v0.7.0

type StopReason string
const (
	StopReasonEndTurn       StopReason = "end_turn"
	StopReasonMaxToolRounds StopReason = "max_tool_rounds"
	StopReasonError         StopReason = "error"
	StopReasonCanceled      StopReason = "canceled"
)

type Stream added in v0.7.0

type Stream interface {
	Next(context.Context) (StreamEvent, error)
	Close() error
}

func NewResponseStream added in v0.7.0

func NewResponseStream(response Response) Stream

type StreamEvent added in v0.7.0

type StreamEvent struct {
	Type     StreamEventType
	Text     string
	Thinking string
	ToolCall ToolCall
	Response Response
	Usage    Usage
	Err      error
}

type StreamEventType added in v0.7.0

type StreamEventType string
const (
	StreamEventTextDelta     StreamEventType = "text_delta"
	StreamEventThinkingDelta StreamEventType = "thinking_delta"
	StreamEventToolCallDelta StreamEventType = "tool_call_delta"
	StreamEventFinalResponse StreamEventType = "final_response"
	StreamEventUsage         StreamEventType = "usage"
)

type StreamHandler added in v0.7.0

type StreamHandler func(context.Context, StreamEvent)

type StreamProvider added in v0.7.0

type StreamProvider interface {
	Stream(context.Context, Request) (Stream, error)
}

type StructuredToolHandler added in v0.7.0

type StructuredToolHandler func(context.Context, json.RawMessage) (ToolResult, error)

type SubagentTool added in v0.13.0

type SubagentTool struct {
	SystemPrompt   string
	MaxToolRounds  int
	MaxResultChars int
	ToolName       string
	EventHandler   EventHandler
}

type SystemPromptSection added in v0.13.0

type SystemPromptSection struct {
	Name    string
	Content string
}

SystemPromptSection is an application-owned named system prompt section.

type TaskGraphTool added in v0.13.0

type TaskGraphTool struct {
	Root     string
	TasksDir string
	Timeout  time.Duration
}

type Tool

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

func NewStructuredTool added in v0.7.0

func NewStructuredTool(name, description string, properties map[string]any, required []string, handler StructuredToolHandler) Tool

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

func NewTypedToolFromSchema added in v0.7.0

func NewTypedToolFromSchema[T any](name, description string, schema *Schema, handler func(context.Context, T) (string, error)) Tool

type ToolBuilder added in v0.13.0

type ToolBuilder interface {
	BuildTools(BuiltinTools) (BuiltTools, error)
	BuildCompact() ([]Tool, error)
	BuildSubagent(SubagentTool, Provider, []Tool, []Hook) (Tool, error)
}

ToolBuilder constructs Tool slices from BuiltinTools configuration.

type ToolCall

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

type ToolCallResult added in v0.7.0

type ToolCallResult struct {
	Call     ToolCall
	Result   string
	Error    bool
	Metadata map[string]any
	Err      error
	Duration time.Duration
}

type ToolChoice added in v0.7.0

type ToolChoice struct {
	Type string
	Name string
}

type ToolHandler

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

type ToolPermissions added in v0.13.0

type ToolPermissions struct {
	Mode            PermissionMode
	AllowedTools    []string
	DisallowedTools []string
}

func (ToolPermissions) IsZero added in v0.13.0

func (p ToolPermissions) IsZero() bool

type ToolResult added in v0.7.0

type ToolResult struct {
	Content  string
	Error    bool
	Metadata map[string]any
}

type Usage added in v0.3.0

type Usage struct {
	InputTokens  int64
	OutputTokens int64
	TotalTokens  int64
	Estimated    bool
}

func EstimateUsage added in v0.3.0

func EstimateUsage(req Request) Usage

Directories

Path Synopsis
builtintools
glob
Package glob provides a read-only file listing tool backed by ripgrep (rg --files).
Package glob provides a read-only file listing tool backed by ripgrep (rg --files).
grep
Package grep provides a read-only content search tool backed by ripgrep (rg).
Package grep provides a read-only content search tool backed by ripgrep (rg).
taskgraph
Package taskgraph provides persistent DAG task tools (task_create / task_update / task_list / task_get) backed by JSON files under a configurable directory, aligned with s07-style task systems.
Package taskgraph provides persistent DAG task tools (task_create / task_update / task_list / task_get) backed by JSON files under a configurable directory, aligned with s07-style task systems.
examples
anthropic command
custom_tool command
loadskill command
sdk_walkthrough command
simple_agent command
subagent command
anthropic
Package anthropic adapts Anthropic Messages APIs to enno.Provider.
Package anthropic adapts Anthropic Messages APIs to enno.Provider.
openai
Package openai adapts OpenAI-compatible Chat Completions APIs to enno.Provider.
Package openai adapts OpenAI-compatible Chat Completions APIs to enno.Provider.
Package setup registers the default ToolBuilder that constructs built-in tools from enno.BuiltinTools configuration.
Package setup registers the default ToolBuilder that constructs built-in tools from enno.BuiltinTools configuration.

Jump to

Keyboard shortcuts

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