Current section

Files

Jump to
nous mix.exs
Raw

mix.exs

defmodule Nous.MixProject do
use Mix.Project
@version "0.16.6"
@source_url "https://github.com/nyo16/nous"
def project do
[
app: :nous,
version: @version,
elixir: "~> 1.18",
start_permanent: Mix.env() == :prod,
deps: deps(),
docs: docs(),
aliases: aliases(),
description: "AI agent framework for Elixir with multi-provider LLM support",
source_url: @source_url,
package: package(),
elixirc_paths: elixirc_paths(Mix.env()),
dialyzer: [
plt_file: {:no_warn, "priv/plts/dialyzer.plt"},
plt_add_apps: [:mix, :ex_unit, :inets]
]
]
end
def application do
[
extra_applications: [:logger, :inets],
mod: {Nous.Application, []},
# hackney's :default pool starts automatically when the :hackney
# application starts; ensuring it's listed here is just defensive.
included_applications: []
]
end
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
defp deps do
[
# YAML (for evaluation framework)
{:yaml_elixir, "~> 2.9"},
# Validation
{:ecto, "~> 3.11"},
# HTTP clients for all LLM providers.
# Finch/Req is the default backend for both one-shot and streaming.
# Hackney is an opt-in alternative for SSE/long-streaming bodies — its
# `:async, :once` mode is truly pull-based, so the consumer paces the
# producer and a slow consumer can't OOM us via mailbox accumulation.
# (Finch.stream/5's callback is push-based; a fast LLM + slow consumer =
# unbounded mailbox growth — see review M-12.) To use the hackney
# backend, declare `{:hackney, "~> 4.0"}` in your app's deps and select
# it via `NOUS_HTTP_BACKEND=hackney` (or the streaming variant).
{:finch, "~> 0.19"},
# `or ~> 0.6` lets downstream apps adopt req 0.6.x without a resolver
# conflict against nous (we still lock 0.5.x until verified on 0.6).
{:req, "~> 0.5 or ~> 0.6"},
{:hackney, "~> 4.0", optional: true},
# Google Cloud auth for Vertex AI (optional — add to your app's deps to unlock)
{:goth, "~> 1.4", optional: true},
# HTML parsing (for web content extraction in research tools)
{:floki, "~> 0.36", optional: true},
# Memory system store backends (all optional — add to your app's deps to unlock)
# {:muninn, "~> 0.4", optional: true},
# {:zvec, "~> 0.2", optional: true},
# {:exqlite, "~> 0.27", optional: true},
# {:duckdbex, "~> 0.3", optional: true},
# Local LLM inference via llama.cpp NIFs (optional — add to your app's deps
# to unlock the LlamaCpp provider). optional: true keeps it out of
# downstream apps' builds unless they opt in, while still being available
# for Nous's own dev/test (e.g. the tagged llamacpp smoke test).
{:llama_cpp_ex, "~> 0.8", optional: true},
# Memory system embedding providers (all optional — add to your app's deps to unlock)
# {:bumblebee, "~> 0.6", optional: true},
# {:exla, "~> 0.9", optional: true},
# Process execution for command hooks and the Bash tool. A NIF-based
# runner is used (over System.cmd/Port) for fine-grained process-tree
# control and reliable kill-on-timeout of child processes. `~> 1.0` (not
# the tighter `~> 1.0.4`) so downstream apps can pick up 1.x fixes without
# waiting on a nous release.
{:net_runner, "~> 1.0"},
# Telemetry
{:telemetry, "~> 1.2"},
# Note: For Prometheus metrics, users can add {:prom_ex, "~> 1.11"} and {:plug, "~> 1.18"}
# to their deps. The Nous.PromEx.Plugin will automatically be available.
# Dev/Test
{:ex_doc, "~> 0.31", only: :dev, runtime: false},
{:dialyxir, "~> 1.4", only: [:dev, :test], runtime: false},
{:credo, "~> 1.7", only: [:dev, :test], runtime: false},
{:mox, "~> 1.1", only: :test},
# optional (not only: :test) so the `~> 2.1` constraint reaches downstream
# resolvers — Nous.PubSub integrates with phoenix_pubsub at runtime (guarded
# by Code.ensure_loaded?), and apps that bring their own copy should see a
# compatible-version requirement rather than a hidden test-only pin.
{:phoenix_pubsub, "~> 2.1", optional: true},
# Bypass = in-test HTTP server for exercising the streaming pipeline
# without hitting real LLM endpoints. Available in :dev too so
# `bench/http_backend.exs` can spin up an in-process server.
{:bypass, "~> 2.1", only: [:dev, :test]},
# Benchee = HTTP backend benchmark (`mix run bench/http_backend.exs`).
{:benchee, "~> 1.3", only: :dev}
]
end
defp docs do
[
main: "readme",
extras: [
"README.md",
"CHANGELOG.md",
{"AGENTS.md", title: "AI Agent Guide (AGENTS.md)"},
{"CONTRIBUTING.md", title: "Contributing"},
# Getting Started
{"docs/getting-started.md", filename: "getting_started", title: "Getting Started Guide"},
# Examples Overview
{"examples/README.md", filename: "examples_overview", title: "Examples Overview"},
{"docs/guides/README.md", filename: "guides_index", title: "All Guides"},
# Production Guides
{"docs/guides/skills.md", filename: "skills", title: "Skills Guide"},
{"docs/guides/hooks.md", filename: "hooks", title: "Hooks Guide"},
{"docs/guides/liveview-integration.md",
filename: "liveview_integration", title: "Phoenix LiveView Integration"},
{"docs/guides/best_practices.md",
filename: "best_practices", title: "Production Best Practices"},
{"docs/guides/tool_development.md",
filename: "tool_development", title: "Tool Development Guide"},
{"docs/guides/troubleshooting.md",
filename: "troubleshooting", title: "Troubleshooting Guide"},
{"docs/guides/migration_guide.md", filename: "migration_guide", title: "Migration Guide"},
{"docs/guides/evaluation.md",
filename: "evaluation", title: "Evaluation Framework Guide"},
{"docs/guides/structured_output.md",
filename: "structured_output", title: "Structured Output Guide"},
{"docs/guides/workflows.md", filename: "workflows", title: "Workflow Engine Guide"},
{"docs/guides/memory.md", filename: "memory", title: "Memory System Guide"},
{"docs/guides/context.md", filename: "context", title: "Context & Dependencies Guide"},
{"docs/guides/knowledge_base.md",
filename: "knowledge_base", title: "Knowledge Base Guide"},
{"docs/guides/permissions.md",
filename: "permissions", title: "Permissions & Guardrails Guide"},
{"docs/guides/observability.md",
filename: "observability", title: "Observability & Telemetry Guide"},
# Orchestration & Multi-Agent
{"docs/guides/teams.md", filename: "teams", title: "Multi-Agent Teams Guide"},
{"docs/guides/decisions.md", filename: "decisions", title: "Decision Graph Guide"},
{"docs/guides/research.md", filename: "research", title: "Deep Research Guide"},
# Providers & Backends
{"docs/guides/providers.md", filename: "providers", title: "Providers Overview"},
{"docs/guides/custom_providers.md",
filename: "custom_providers", title: "Custom Providers Guide"},
{"docs/guides/http_backends.md", filename: "http_backends", title: "HTTP Backends Guide"},
{"docs/guides/vertex_ai_setup.md",
filename: "vertex_ai_setup", title: "Vertex AI Setup Guide"},
{"docs/guides/fallback.md", filename: "fallback", title: "Fallback Chains Guide"},
# Design Documents
{"docs/design/llm_council_design.md",
filename: "council_design", title: "LLM Council Design"},
{"docs/benchmarks/http_backend.md",
filename: "http_backend_benchmark", title: "HTTP Backend Benchmark"}
],
source_ref: "v#{@version}",
source_url: @source_url,
groups_for_extras: [
"Getting Started": [
"readme.html",
"getting_started.html",
"examples_overview.html",
"guides_index.html"
],
"Production Guides": [
"skills.html",
"hooks.html",
"liveview_integration.html",
"best_practices.html",
"tool_development.html",
"troubleshooting.html",
"migration_guide.html",
"evaluation.html",
"structured_output.html",
"memory.html",
"context.html",
"knowledge_base.html",
"permissions.html",
"observability.html"
],
"Orchestration & Multi-Agent": [
"teams.html",
"decisions.html",
"research.html",
"workflows.html"
],
"Providers & Backends": [
"providers.html",
"custom_providers.html",
"http_backends.html",
"vertex_ai_setup.html",
"fallback.html"
],
Design: [
"council_design.html",
"http_backend_benchmark.html"
],
Reference: [
"changelog.html",
"agents.html",
"contributing.html"
]
],
groups_for_modules: [
"Core API": [
Nous,
Nous.Agent,
Nous.Agent.Context,
Nous.Agent.Behaviour,
Nous.Agent.Callbacks,
Nous.ReActAgent,
Nous.Transcript,
Nous.LLM,
Nous.RunContext
],
"Agent Implementations": [
Nous.Agents.BasicAgent,
Nous.Agents.ReActAgent
],
"Agent Execution": [
Nous.AgentRunner,
Nous.AgentServer
],
"Model Configuration": [
Nous.Model,
Nous.ModelDispatcher,
Nous.Fallback
],
Providers: [
Nous.Provider,
Nous.Providers.HTTP,
Nous.Providers.HTTP.JSONArrayParser,
Nous.Providers.OpenAI,
Nous.Providers.OpenAICompatible,
Nous.Providers.Anthropic,
Nous.Providers.Custom,
Nous.Providers.Gemini,
Nous.Providers.Mistral,
Nous.Providers.LMStudio,
Nous.Providers.VertexAI,
Nous.Providers.LlamaCpp,
Nous.Providers.VLLM,
Nous.Providers.SGLang
],
"Messages & Streaming": [
Nous.Message,
Nous.Message.ContentPart,
Nous.Messages,
Nous.Messages.OpenAI,
Nous.Messages.Anthropic,
Nous.Messages.Gemini,
Nous.StreamNormalizer,
Nous.StreamNormalizer.OpenAI,
Nous.StreamNormalizer.Anthropic,
Nous.StreamNormalizer.Gemini,
Nous.StreamNormalizer.LlamaCpp,
Nous.StreamNormalizer.ToolCallAccumulator
],
"HTTP Backends": [
Nous.HTTP.Backend,
Nous.HTTP.Backend.Req,
Nous.HTTP.Backend.Hackney,
Nous.HTTP.StreamBackend,
Nous.HTTP.StreamBackend.Req,
Nous.HTTP.StreamBackend.Hackney
],
"Tool System": [
Nous.Tool,
Nous.Tool.Behaviour,
Nous.Tool.ContextUpdate,
Nous.Tool.Validator,
Nous.Tool.Registry,
Nous.Tool.Schema,
Nous.ToolSchema,
Nous.ToolExecutor
],
"Structured Output": [
Nous.OutputSchema,
Nous.OutputSchema.UseMacro,
Nous.OutputSchema.Validator
],
"Research Tools": [
Nous.Tools.WebFetch,
Nous.Tools.Summarize,
Nous.Tools.SearchScrape,
Nous.Tools.TavilySearch,
Nous.Tools.BraveSearch,
Nous.Tools.ResearchNotes
],
"Coding Tools": [
Nous.Tools.Bash,
Nous.Tools.FileRead,
Nous.Tools.FileWrite,
Nous.Tools.FileEdit,
Nous.Tools.FileGlob,
Nous.Tools.FileGrep,
Nous.Tools.TodoTools,
Nous.Tools.PathGuard,
Nous.Tools.UrlGuard
],
"Utility Tools": [
Nous.Tools.DateTimeTools,
Nous.Tools.StringTools,
Nous.Tools.ReActTools
],
Testing: [
Nous.Tool.Testing
],
Templates: [
Nous.PromptTemplate
],
"Data Types": [
Nous.Types,
Nous.Usage
],
Infrastructure: [
Nous.Telemetry,
Nous.PromEx.Plugin,
Nous.Errors,
Nous.Errors.RetryInfo,
Nous.Errors.ConfigurationError,
Nous.Errors.ModelError,
Nous.Errors.ProviderError,
Nous.Errors.ToolError,
Nous.Errors.ToolTimeout,
Nous.Errors.ValidationError,
Nous.Errors.UsageLimitExceeded,
Nous.Errors.MaxIterationsExceeded,
Nous.Errors.ExecutionCancelled
],
Evaluation: [
Nous.Eval,
Nous.Eval.Suite,
Nous.Eval.TestCase,
Nous.Eval.Runner,
Nous.Eval.Evaluator,
Nous.Eval.Evaluators.Contains,
Nous.Eval.Evaluators.ExactMatch,
Nous.Eval.Evaluators.FuzzyMatch,
Nous.Eval.Evaluators.LLMJudge,
Nous.Eval.Evaluators.Schema,
Nous.Eval.Evaluators.ToolUsage,
Nous.Eval.Metrics,
Nous.Eval.Metrics.Summary,
Nous.Eval.Result,
Nous.Eval.SuiteResult,
Nous.Eval.YamlLoader,
Nous.Eval.Config,
Nous.Eval.Reporter,
Nous.Eval.Reporter.Console,
Nous.Eval.Reporter.Json,
Nous.Eval.Optimizer,
Nous.Eval.Optimizer.Parameter,
Nous.Eval.Optimizer.SearchSpace,
Nous.Eval.Optimizer.Strategy,
Nous.Eval.Optimizer.Strategies.Bayesian,
Nous.Eval.Optimizer.Strategies.GridSearch,
Nous.Eval.Optimizer.Strategies.Random
],
"Hooks System": [
Nous.Hook,
Nous.Hook.Registry,
Nous.Hook.Runner
],
"Skills System": [
Nous.Skill,
Nous.Skill.Loader,
Nous.Skill.Registry,
Nous.Plugins.Skills,
Nous.Skills.CodeReview,
Nous.Skills.TestGen,
Nous.Skills.Debug,
Nous.Skills.Refactor,
Nous.Skills.ExplainCode,
Nous.Skills.CommitMessage,
Nous.Skills.DocGen,
Nous.Skills.SecurityScan,
Nous.Skills.Architect,
Nous.Skills.TaskBreakdown,
Nous.Skills.PhoenixLiveView,
Nous.Skills.EctoPatterns,
Nous.Skills.OtpPatterns,
Nous.Skills.ElixirTesting,
Nous.Skills.ElixirIdioms,
Nous.Skills.PythonFastAPI,
Nous.Skills.PythonTesting,
Nous.Skills.PythonTyping,
Nous.Skills.PythonDataScience,
Nous.Skills.PythonSecurity,
Nous.Skills.PythonUv
],
"Plugin System": [
Nous.Plugin,
Nous.Plugins.HumanInTheLoop,
Nous.Plugins.InputGuard,
Nous.Plugins.InputGuard.Strategy,
Nous.Plugins.InputGuard.Result,
Nous.Plugins.InputGuard.Policy,
Nous.Plugins.InputGuard.Strategies.Pattern,
Nous.Plugins.InputGuard.Strategies.LLMJudge,
Nous.Plugins.InputGuard.Strategies.Semantic,
Nous.Plugins.Memory,
Nous.Plugins.SubAgent,
Nous.Plugins.Summarization,
Nous.Plugins.Decisions,
Nous.Plugins.TeamTools
],
"Multi-Agent (Teams)": [
Nous.Teams,
Nous.Teams.Supervisor,
Nous.Teams.Coordinator,
Nous.Teams.Role,
Nous.Teams.Comms,
Nous.Teams.SharedState,
Nous.Teams.RateLimiter
],
"Decision Graph": [
Nous.Decisions,
Nous.Decisions.Node,
Nous.Decisions.Edge,
Nous.Decisions.ContextBuilder,
Nous.Decisions.Store,
Nous.Decisions.Store.ETS,
Nous.Decisions.Store.DuckDB
],
Memory: [
Nous.Memory,
Nous.Memory.Entry,
Nous.Memory.Scope,
Nous.Memory.Store,
Nous.Memory.Store.ETS,
Nous.Memory.Store.SQLite,
Nous.Memory.Store.DuckDB,
Nous.Memory.Store.Muninn,
Nous.Memory.Store.Zvec,
Nous.Memory.Store.Hybrid,
Nous.Memory.Scoring,
Nous.Memory.Search,
Nous.Memory.Tools,
Nous.Memory.Embedding,
Nous.Memory.Embedding.Bumblebee,
Nous.Memory.Embedding.OpenAI,
Nous.Memory.Embedding.Local
],
PubSub: [
Nous.PubSub,
Nous.PubSub.Approval
],
Persistence: [
Nous.Persistence
],
Supervision: [
Nous.AgentRegistry,
Nous.AgentDynamicSupervisor
],
Research: [
Nous.Research,
Nous.Research.Coordinator,
Nous.Research.Planner,
Nous.Research.Searcher,
Nous.Research.Synthesizer,
Nous.Research.Reporter,
Nous.Research.Finding,
Nous.Research.Report
],
Session: [
Nous.Session.Config,
Nous.Session.Guardrails
],
Permissions: [
Nous.Permissions,
Nous.Permissions.Policy
],
"Knowledge Base": [
Nous.KnowledgeBase,
Nous.KnowledgeBase.Entry,
Nous.KnowledgeBase.Document,
Nous.KnowledgeBase.Link,
Nous.KnowledgeBase.Store,
Nous.KnowledgeBase.Store.ETS,
Nous.KnowledgeBase.Tools,
Nous.KnowledgeBase.Workflows,
Nous.KnowledgeBase.HealthReport,
Nous.KnowledgeBase.Prompts,
Nous.Plugins.KnowledgeBase,
Nous.Agents.KnowledgeBaseAgent
],
"Workflow Engine": [
Nous.Workflow,
Nous.Workflow.Graph,
Nous.Workflow.Node,
Nous.Workflow.Edge,
Nous.Workflow.State,
Nous.Workflow.Compiler,
Nous.Workflow.Engine,
Nous.Workflow.Engine.Executor,
Nous.Workflow.Engine.ParallelExecutor,
Nous.Workflow.Engine.StateMerger,
Nous.Workflow.Mermaid,
Nous.Workflow.Trace,
Nous.Workflow.Checkpoint,
Nous.Workflow.Checkpoint.Store,
Nous.Workflow.Checkpoint.ETS,
Nous.Workflow.Scratch,
Nous.Workflow.Telemetry
],
"Mix Tasks": [
Mix.Tasks.Nous.Eval,
Mix.Tasks.Nous.Optimize
]
]
]
end
defp package do
[
# Explicit files list — exclude `priv/plts/` (dialyzer artifacts) which
# the default Hex package set would otherwise bundle, bloating the
# tarball by 100MB+.
files: ~w(lib .formatter.exs mix.exs README.md LICENSE CHANGELOG.md AGENTS.md),
licenses: ["Apache-2.0"],
links: %{
"GitHub" => @source_url,
"Changelog" => "#{@source_url}/blob/master/CHANGELOG.md"
}
]
end
defp aliases do
[docs: ["docs", &copy_images/1]]
end
defp copy_images(_) do
File.mkdir_p!("doc/images")
File.cp!("images/header.jpeg", "doc/images/header.jpeg")
File.cp!("images/logo.jpeg", "doc/images/logo.jpeg")
end
end