Counterspell
A lightweight, embedded observability tool for Go applications that provides OpenTelemetry tracing and logging capabilities with a local SQLite database backend and REST API for data querying.
⚠️ This project is a work in progress and is not yet ready for production use. ⚠️
What it is
- Fast and easy to get started, no added extra cost
- Gives you observability UI for your LLM calls with the greatest of ease
- Prompt evals
- Prompt optimizer
- Embedded observability with otel, zerolog (uses sqlite), throwaway sqlite db
- Means no external dependencies, no xtra docker containers
- Writes logs on a separate goroutine, so your app is not affected
Getting Started
Prerequisites
- Docker and Docker Compose
- Go (1.25 or later)
- Node.js (20.x or later)
Running with Docker Compose
The easiest way to get Counterspell up and running is with Docker Compose.
docker-compose up
This will start the backend server on port 8080 and the frontend UI on port 5173.
- Backend API:
http://localhost:8080
- Frontend UI:
http://localhost:5173
Development Environment
For development, you can use the provided dev.sh script, which uses kitty to create a split-pane terminal for the backend and frontend.
./dev.sh
Counterspell
Installation
go get github.com/revrost/counterspell
Todo
- Protobuf schemas
- Agent configuration/blueprint framework
- Openrouter integration
- Lightweight execution runtime utilize goroutine (cadence/go-workflow)
- Create agent, run agent, watch UI
- Orchestrator-Executor MVP via ui
- Otel integration
- Openapi streaming spec
- Move sqlite to postgres (later)
Quick Start
The simplest way to add Counterspell to your application:
func main() {
// Example 1: Using Echo router
log.Info().Msg("Starting Echo server with Counterspell...")
e := echo.New()
// Use echo
e.Use(otelecho.Middleware("counterspell-example"))
// Add Counterspell to Echo router
if err := counterspell.AddToEcho(e,
counterspell.WithAuthToken("my-secret-token"),
counterspell.WithDBPath("counterspell_echo.db"),
); err != nil {
log.Fatal().Err(err).Msg("Failed to add Counterspell to Echo")
}
// Add your application routes
e.GET("/hello", func(c echo.Context) error {
log.Ctx(c.Request().Context()).Debug().Str("user", "demo").Msg("Hello from Echo with Counterspell!")
log.Ctx(c.Request().Context()).Error().Msg("Hello from Echo with Counterspell!")
return c.String(http.StatusOK, "Hello from Echo with Counterspell!")
})
log.Info().Msg("Echo server listening on :8080")
log.Info().Msg("Counterspell UI available at: http://localhost:8080/counterspell/health")
log.Info().Msg("Counterspell API available at: http://localhost:8080/counterspell/api/logs?secret=my-secret-token")
if err := e.Start(":8080"); err != nil {
log.Printf("Echo server stopped: %v", err)
}
}
API Endpoints
All API endpoints require authentication via the Authorization: Bearer <token> header or auth query parameter.
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Submit a pull request
License
This project is licensed under the Apache-2.0 License.