Skip to content

Build without the unpublished :inference dependency; support Elixir 1.20#5

Open
BobbieBarker wants to merge 1 commit into
nshkrdotcom:mainfrom
BobbieBarker:fix/decouple-inference
Open

Build without the unpublished :inference dependency; support Elixir 1.20#5
BobbieBarker wants to merge 1 commit into
nshkrdotcom:mainfrom
BobbieBarker:fix/decouple-inference

Conversation

@BobbieBarker

Copy link
Copy Markdown

Summary

The published package can't be built by an external consumer. mix.exs declares {:inference, path: "../inference/apps/inference"}, a local path dependency that only exists in the author's workspace, so mix deps.get / mix compile abort at dependency resolution. The Hex artifact silently drops the path dep, which leaves GEPA.LLM.Adapters.ReqLLM and GEPA.LLM.Adapters.AgentSessionManager referencing an undefined Inference.* namespace.

This PR makes the package buildable and usable with any LLM, and brings it to Elixir 1.20.

Decoupling the optimizer core from :inference

The optimizer core (engine, proposers, Pareto selection, state, strategies, stop conditions) is already provider-agnostic: it reaches a model only through the GEPA.LLM facade, which accepts a plain function, a %GEPA.LLM.Client{}, or GEPA.LLM.Mock. Only the two provider adapters depended on :inference.

  • Removed the :inference path dependency and the now-unused agent_session_manager dependency.
  • Marked req_llm and req as optional: true; they're used only by the embeddings and RAG/Qdrant adapters, so a consumer that injects its own LLM takes on neither.
  • Deleted the :inference-coupled provider adapters (GEPA.LLM.Adapters.ReqLLM, GEPA.LLM.Adapters.AgentSessionManager, and the GEPA.LLM.ReqLLM compatibility shim that delegated to them). Their compile-time struct references (%Inference.Response{} and friends) cannot resolve without the package. The facade's provider constructors (new/2, req_llm/2, agent/2) now raise with guidance to inject an LLM, keeping their arities.

If keeping the ReqLLM/ASM adapters is preferred, the natural home for them is a small companion package that depends on :inference (or its published pieces), so the core stays installable on its own.

Elixir 1.20

  • Raised the supported version to ~> 1.20 and moved preferred_cli_env into def cli.
  • Fixed issues surfaced by the 1.20 type checker:
    • adapters/mcp.ex: a {tool, args} clause shadowed the following {:error, reason} clause, so error tuples were being rewritten into {:ok, "error", ...} tool selections instead of propagating. Reordered so errors pass through.
    • optimize_anything.ex: removed a dead || 1 fallback on a value that is always truthy.
    • evaluation_batch.ex: removed two clauses that the validation flow makes unreachable.

Tests and metadata

  • Updated the GEPA.LLM facade tests for the new Mock-or-raise default contract, and switched the Basic adapter's "normalized client" test to a plain-function LLM. Removed the provider test suites that covered the deleted adapters.
  • Strengthened two tautological != nil assertions the type checker flagged.
  • Gave the subprocess code-execution test timeout headroom so it does not race cold BEAM boot on loaded machines.
  • Dropped the deleted modules from the ExDoc module groups, removed the stale gepa/ entries from the package files, and corrected the maintainers field.

Verification

On Elixir 1.20.1 / OTP 28:

  • mix compile --warnings-as-errors — clean
  • mix test — 860 pass (844 tests, 16 properties)
  • mix credo --strict — no issues
  • mix format --check-formatted — clean
  • mix dialyzer — passed

The package cannot be built by an external consumer. mix.exs declares
`{:inference, path: "../inference/apps/inference"}`, a local path dependency
that exists only in the author's workspace, so `mix deps.get`/`mix compile`
abort at dependency resolution. The published Hex artifact silently drops the
path dep, leaving the ReqLLM and Agent-Session-Manager adapters referencing an
undefined `Inference.*` namespace.

The optimizer core (engine, proposers, Pareto selection, state, strategies,
stop conditions) is already provider-agnostic: it reaches models only through
the `GEPA.LLM` facade, which accepts a plain function, a `%GEPA.LLM.Client{}`,
or `GEPA.LLM.Mock`. Only the two provider adapters depended on `:inference`.

Decoupling:
- Remove the `:inference` path dependency and the now-unused
  `agent_session_manager` dependency.
- Mark `req_llm` and `req` as optional; they are used only by the embeddings
  and RAG/Qdrant adapters, so a consumer that injects its own LLM takes on
  neither.
- Delete the `:inference`-coupled provider adapters (`GEPA.LLM.Adapters.ReqLLM`,
  `GEPA.LLM.Adapters.AgentSessionManager`, and the `GEPA.LLM.ReqLLM` shim that
  delegated to them); their compile-time struct references (`%Inference.Response{}`
  and friends) cannot resolve without the package. The facade's provider
  constructors now raise with guidance to inject an LLM, preserving their arity.

Elixir 1.20:
- Raise the supported version to `~> 1.20` and move `preferred_cli_env` into
  `def cli`.
- Fix issues surfaced by the 1.20 type checker:
  - adapters/mcp.ex: a `{tool, args}` clause shadowed the following
    `{:error, reason}` clause, so error tuples were rewritten into
    `{:ok, "error", ...}` tool selections instead of propagating. Reordered so
    errors pass through.
  - optimize_anything.ex: remove a dead `|| 1` fallback on an always-truthy value.
  - evaluation_batch.ex: remove two clauses the validation flow makes unreachable.

Tests and metadata:
- Update the LLM facade tests for the new Mock-or-raise default contract and
  exercise a plain-function LLM in the Basic adapter test; drop the provider
  test suites that covered the removed adapters.
- Strengthen two tautological `!= nil` assertions the type checker flagged.
- Give the subprocess code-execution test timeout headroom so it does not race
  cold BEAM boot on loaded machines.
- Remove the deleted modules from the ExDoc module groups, drop the stale
  `gepa/` entries from the package file list, and correct the maintainer field.

mix compile --warnings-as-errors, mix test (860 pass), mix credo --strict,
mix format --check-formatted, and mix dialyzer all pass on Elixir 1.20.1 / OTP 28.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant