diff --git a/README.md b/README.md index 5095464..b0b0906 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@
Quick Start · Features · + Docs · + Examples · Providers · - Usage · Architecture · Contributing
@@ -100,6 +101,28 @@ Token bucket rate limiter per provider — prevents hitting API limits before th Built-in cost estimation per call, with per-provider pricing from the embedded model catalog. +## Documentation + +Detailed documentation is available in the [docs/](docs/) directory: + +- **[Architecture](docs/ARCHITECTURE.md)** — System design, data flow, and reliability features +- **[Provider Setup Guide](docs/guides/CREDENTIAL-SETUP-FLOW.md)** — Credential configuration and provider setup +- **[Dynamic Model Discovery](docs/guides/DYNAMIC-MODEL-DISCOVERY.md)** — Live model discovery architecture + +## Examples + +Runnable examples are in the [examples/](examples/) directory: + +- **[Basic Chat](examples/basic/)** — Simple synchronous chat +- **[Streaming](examples/streaming/)** — SSE streaming with event handling +- **[Multi-Provider](examples/multi-provider/)** — Fallback chains across providers + +Run any example with: + +```bash +ANTHROPIC_API_KEY=sk-... go run ./examples/basic/ +``` + ## Supported Providers | Provider | Env Variable | Notes | @@ -179,8 +202,11 @@ eyrie/ │ ├── legacy/ # Legacy model support │ ├── live/ # Live model data │ └── registry/ # Model registry +├── codeagent/ # Code agent retry & fallback strategies ├── conversation/ # Conversation engine with branching ├── credentials/ # Credential management +├── docs/ # Documentation & guides +├── examples/ # Runnable code examples ├── router/ # Weighted provider router ├── runtime/ # Runtime manifest & routing policies ├── storage/ # SQLite conversation DAG store @@ -198,6 +224,8 @@ eyrie/ └── assets/ # Logo and branding ``` +See [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) for detailed system design and data flows. + ## Ecosystem eyrie is part of the hawk-eco: diff --git a/codeagent_retry.go b/codeagent/retry.go similarity index 91% rename from codeagent_retry.go rename to codeagent/retry.go index 0b2b2d7..f9b0c6e 100644 --- a/codeagent_retry.go +++ b/codeagent/retry.go @@ -1,14 +1,8 @@ -// Package eyrie is a universal LLM provider runtime. It routes requests to -// multiple AI providers (Anthropic, OpenAI, Gemini, Azure, Bedrock, Vertex, -// and OpenAI-compatible endpoints) with reliability features: circuit breaker, -// request coalescing, output guardrails (PII / secrets / injection), -// structured-output validation with retry, request-scoped lifecycle callbacks, -// and code-agent–specific retry strategies. -// -// This file (codeagent_retry.go) implements intelligent retry and fallback -// policies tailored to code agent workloads, distinguishing rate-limit errors, -// context window overflows, and tool-call failures from generic errors. -package eyrie +// Package codeagent provides intelligent retry and fallback strategies +// tailored to code agent workloads. It distinguishes rate-limit errors, +// context window overflows, and tool-call failures from generic errors, +// applying appropriate retry or model-fallback behavior for each. +package codeagent import ( "context" diff --git a/ARCHITECTURE.md b/docs/ARCHITECTURE.md similarity index 100% rename from ARCHITECTURE.md rename to docs/ARCHITECTURE.md diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..6b0d326 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,67 @@ +# Eyrie Documentation + +Welcome to the Eyrie documentation. This directory contains detailed guides and reference material for the Universal LLM Provider Runtime. + +## Documentation Index + +### Core Documentation + +- **[Architecture](ARCHITECTURE.md)** — System architecture, data flow, and design decisions +- **[Provider Setup Guide](guides/CREDENTIAL-SETUP-FLOW.md)** — How to configure credentials and providers +- **[Dynamic Model Discovery](guides/DYNAMIC-MODEL-DISCOVERY.md)** — Architecture and implementation details for live model discovery + +### Quick Links + +- **[README](../README.md)** — Project overview and quick start +- **[Contributing Guide](../CONTRIBUTING.md)** — How to contribute to Eyrie +- **[Security Policy](../SECURITY.md)** — Security reporting and best practices +- **[Changelog](../CHANGELOG.md)** — Version history and release notes + +### Examples + +The [`examples/`](../examples/) directory contains runnable code samples: + +- **Basic Chat** — Simple synchronous chat with a single provider +- **Streaming** — Server-sent events streaming with continuation +- **Multi-Provider** — Using fallback chains across multiple providers + +## Documentation Structure + +``` +docs/ +├── README.md # This file +├── ARCHITECTURE.md # System architecture +└── guides/ + ├── CREDENTIAL-SETUP-FLOW.md # Credential configuration + └── DYNAMIC-MODEL-DISCOVERY.md # Model discovery architecture +``` + +## For Developers + +If you're contributing to Eyrie: + +1. Read [CONTRIBUTING.md](../CONTRIBUTING.md) for development setup +2. Review [ARCHITECTURE.md](ARCHITECTURE.md) to understand the system +3. Check [AGENTS.md](../AGENTS.md) for AI agent context and conventions +4. Run `make ci` locally before submitting PRs + +## For Users + +If you're using Eyrie in your application: + +1. Start with the [Quick Start](../README.md#quick-start) in the main README +2. Review the [Usage examples](../README.md#usage) for common patterns +3. Check the [examples/](../examples/) directory for complete code samples +4. Read the [Provider Setup Guide](guides/CREDENTIAL-SETUP-FLOW.md) for credential configuration + +## API Reference + +API documentation is available at: +- **[pkg.go.dev](https://pkg.go.dev/github.com/GrayCodeAI/eyrie)** — Generated Go documentation +- **[ARCHITECTURE.md](ARCHITECTURE.md)** — Core abstractions and interfaces + +## Support + +- **Issues**: [GitHub Issues](https://github.com/GrayCodeAI/eyrie/issues) +- **Discussions**: [GitHub Discussions](https://github.com/GrayCodeAI/eyrie/discussions) +- **Security**: See [SECURITY.md](../SECURITY.md) for vulnerability reporting diff --git a/plans/CREDENTIAL-SETUP-FLOW.md b/docs/guides/CREDENTIAL-SETUP-FLOW.md similarity index 100% rename from plans/CREDENTIAL-SETUP-FLOW.md rename to docs/guides/CREDENTIAL-SETUP-FLOW.md diff --git a/plans/DYNAMIC-MODEL-DISCOVERY.md b/docs/guides/DYNAMIC-MODEL-DISCOVERY.md similarity index 100% rename from plans/DYNAMIC-MODEL-DISCOVERY.md rename to docs/guides/DYNAMIC-MODEL-DISCOVERY.md diff --git a/examples/basic/main.go b/examples/basic/main.go new file mode 100644 index 0000000..66fba70 --- /dev/null +++ b/examples/basic/main.go @@ -0,0 +1,35 @@ +// Example: basic chat with eyrie. +// +// Run: +// +// ANTHROPIC_API_KEY=sk-... go run ./examples/basic/ +package main + +import ( + "context" + "fmt" + "os" + + "github.com/GrayCodeAI/eyrie/client" +) + +func main() { + c := client.Client(&client.EyrieConfig{ + Provider: client.DetectProvider(), + }) + + messages := []client.EyrieMessage{ + {Role: "user", Content: "What is 2 + 2?"}, + } + + resp, err := c.Chat(context.Background(), messages, client.ChatOptions{ + Model: "claude-sonnet-4-6", + }) + if err != nil { + fmt.Fprintf(os.Stderr, "chat error: %v\n", err) + os.Exit(1) + } + + fmt.Println(resp.Content) + fmt.Printf("Tokens: input=%d output=%d\n", resp.Usage.PromptTokens, resp.Usage.CompletionTokens) +} diff --git a/examples/multi-provider/main.go b/examples/multi-provider/main.go new file mode 100644 index 0000000..24ea441 --- /dev/null +++ b/examples/multi-provider/main.go @@ -0,0 +1,46 @@ +// Example: multi-provider fallback chain. +// +// Tries Anthropic first, falls back to OpenAI, then Gemini. +// +// Run: +// +// ANTHROPIC_API_KEY=sk-ant-... OPENAI_API_KEY=sk-... go run ./examples/multi-provider/ +package main + +import ( + "context" + "fmt" + "os" + + "github.com/GrayCodeAI/eyrie/client" +) + +func main() { + primary := client.Client(&client.EyrieConfig{ + Provider: "anthropic", + }) + secondary := client.Client(&client.EyrieConfig{ + Provider: "openai", + }) + + messages := []client.EyrieMessage{ + {Role: "user", Content: "Explain what a fallback chain is in one sentence."}, + } + + // Try primary first, fall back to secondary on failure. + resp, err := primary.Chat(context.Background(), messages, client.ChatOptions{ + Model: "claude-sonnet-4-6", + }) + if err != nil { + fmt.Fprintf(os.Stderr, "primary failed, trying secondary: %v\n", err) + resp, err = secondary.Chat(context.Background(), messages, client.ChatOptions{ + Model: "gpt-4o", + }) + if err != nil { + fmt.Fprintf(os.Stderr, "all providers failed: %v\n", err) + os.Exit(1) + } + } + + fmt.Println(resp.Content) +} diff --git a/examples/streaming/main.go b/examples/streaming/main.go new file mode 100644 index 0000000..50ace18 --- /dev/null +++ b/examples/streaming/main.go @@ -0,0 +1,48 @@ +// Example: streaming chat with auto-continuation. +// +// Run: +// +// ANTHROPIC_API_KEY=sk-... go run ./examples/streaming/ +package main + +import ( + "context" + "fmt" + "os" + + "github.com/GrayCodeAI/eyrie/client" +) + +func main() { + c := client.Client(&client.EyrieConfig{ + Provider: client.DetectProvider(), + }) + + messages := []client.EyrieMessage{ + {Role: "user", Content: "Write a short poem about programming."}, + } + + sr, err := c.StreamChat(context.Background(), messages, client.ChatOptions{ + Model: "claude-sonnet-4-6", + }) + if err != nil { + fmt.Fprintf(os.Stderr, "stream error: %v\n", err) + os.Exit(1) + } + defer sr.Close() + + for evt := range sr.Events { + switch evt.Type { + case "content": + fmt.Print(evt.Content) + case "tool_call": + if evt.ToolCall != nil { + fmt.Printf("\n[Tool call: %s]\n", evt.ToolCall.Name) + } + case "done": + fmt.Println() + case "error": + fmt.Fprintf(os.Stderr, "\nstream error: %s\n", evt.Error) + } + } +}