From 0dfa7084cb9a16138708106805a6af9c5116a2e2 Mon Sep 17 00:00:00 2001 From: Superagentic AI Date: Thu, 10 Sep 2026 16:46:00 +0000 Subject: [PATCH] Upgrade GEPA dependency from 0.0.22 to 0.1.4 Bump the gepa pin and refresh uv.lock. Keep using InstructionProposalSignature for reflective prompt proposals. Document 0.1.x placeholder rename (, ) and teach MinimalGEPAProposer to accept string or multimodal LM prompts. --- CHANGELOG.md | 7 ++++++ pyproject.toml | 2 +- src/codeoptix/evolution/gepa_integration.py | 27 +++++++++++++++------ uv.lock | 12 ++++----- 4 files changed, 33 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 375849f..d11f1c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added ### Changed +- Upgraded GEPA dependency from `gepa==0.0.22` to `gepa==0.1.4`. + CodeOptiX continues to use GEPA's `InstructionProposalSignature` for reflective + prompt proposals. GEPA 0.1.x renames default template placeholders to + `` and `` (from `` / + ``). Custom `prompt_template` configs must use the + new placeholders. The MinimalGEPAProposer LLM wrapper now accepts both string + prompts and multimodal message lists to match GEPA 0.1.x LanguageModel. ### Deprecated diff --git a/pyproject.toml b/pyproject.toml index 7a7d3cf..3341f06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ dependencies = [ "numpy>=1.24.0", "litellm>=1.80.0", "tenacity>=8.0.0", - "gepa==0.0.22", + "gepa==0.1.4", "agent-client-protocol>=0.7.0", ] diff --git a/src/codeoptix/evolution/gepa_integration.py b/src/codeoptix/evolution/gepa_integration.py index 864d0cc..1f8c2f3 100644 --- a/src/codeoptix/evolution/gepa_integration.py +++ b/src/codeoptix/evolution/gepa_integration.py @@ -5,6 +5,13 @@ Note: This is NOT a full GEPA framework integration. We're using GEPA's proven instruction proposal mechanism rather than the complete GEPA optimization engine. + +GEPA 0.1.x notes: +- InstructionProposalSignature placeholders are ```` and ```` + (renamed from ```` / ```` in 0.0.x). +- Custom ``prompt_template`` values must include those 0.1.x placeholders. +- LanguageModel may receive either a string prompt or a multimodal messages list; + CodeOptiX only feeds text feedback today, so the string path is the common case. """ from typing import Any @@ -25,7 +32,8 @@ def __init__(self, llm_client, config: dict[str, Any] | None = None): Args: llm_client: LLM client compatible with GEPA's LanguageModel interface - config: Configuration dictionary + config: Configuration dictionary. Optional ``prompt_template`` must use + GEPA 0.1.x placeholders ```` and ````. """ self.llm_client = llm_client self.config = config or {} @@ -118,8 +126,7 @@ def _wrap_llm_client(self): """ Wrap CodeOptiX LLM client to GEPA's LanguageModel interface. - GEPA expects a LanguageModel Protocol with a __call__ method that takes - a prompt string and returns a string response. + GEPA 0.1.x LanguageModel accepts ``str | list[dict]`` and returns a string. """ class GEPALLMWrapper: @@ -130,16 +137,20 @@ def __init__(self, llm_client): if hasattr(llm_client, "config") and isinstance(llm_client.config, dict): self.default_model = llm_client.config.get("model", self.default_model) - def __call__(self, prompt: str) -> str: + def __call__(self, prompt: str | list[dict[str, Any]]) -> str: """ Generate response using CodeOptiX LLM client. - This implements GEPA's LanguageModel Protocol: - - Takes a prompt string - - Returns a string response + Implements GEPA's LanguageModel Protocol for both string prompts + and OpenAI-style multimodal message lists. """ + if isinstance(prompt, str): + messages: list[dict[str, Any]] = [{"role": "user", "content": prompt}] + else: + messages = prompt + response = self.llm_client.chat_completion( - messages=[{"role": "user", "content": prompt}], + messages=messages, model=self.default_model, temperature=0.7, ) diff --git a/uv.lock b/uv.lock index 30281e9..07baff2 100644 --- a/uv.lock +++ b/uv.lock @@ -312,7 +312,7 @@ wheels = [ [[package]] name = "codeoptix" -version = "0.1.2" +version = "0.1.3" source = { editable = "." } dependencies = [ { name = "agent-client-protocol" }, @@ -372,7 +372,7 @@ requires-dist = [ { name = "codeoptix", extras = ["dev", "testing", "docs"], marker = "extra == 'all'" }, { name = "coverage", marker = "extra == 'dev'", specifier = ">=7.0.0" }, { name = "coverage", marker = "extra == 'testing'", specifier = ">=7.0.0" }, - { name = "gepa", specifier = "==0.0.22" }, + { name = "gepa", specifier = "==0.1.4" }, { name = "google-genai", specifier = ">=0.8.0" }, { name = "litellm", specifier = ">=1.80.0" }, { name = "mkdocs", marker = "extra == 'docs'", specifier = ">=1.5.0" }, @@ -660,11 +660,11 @@ wheels = [ [[package]] name = "gepa" -version = "0.0.22" +version = "0.1.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ae/be/9a4c31c65c4910e73bd4a316df99347681bce4f2ef6d10877cc1ed8d57da/gepa-0.0.22.tar.gz", hash = "sha256:0b13a644efd2af52186e456eaad2ae28fcf88c6f796a9c999910c587863d4315", size = 116337, upload-time = "2025-11-10T21:39:27.044Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/56/925779e5690971f1b022f7d107caf015c33ec09560261273ec137e23a8f2/gepa-0.1.4.tar.gz", hash = "sha256:6dd153a676ae5481764860d19286a9c0e8ddb5ef70d7f13044faf24978bdb6b8", size = 351343, upload-time = "2026-07-15T14:53:59.929Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/0e/d41272b28f2163f5bf840b508cbaf4a0bc01eaeaa6e5d447558d1050eb3b/gepa-0.0.22-py3-none-any.whl", hash = "sha256:ff57ee0442399a5cc62d01411935476bc80cfa8f1c318bed82e3db4c2c834665", size = 119666, upload-time = "2025-11-10T21:39:26.028Z" }, + { url = "https://files.pythonhosted.org/packages/fd/77/5b3a281cfd9caaa9e68349b434cf27f1ca448003ee0067a1ae2184dc52d1/gepa-0.1.4-py3-none-any.whl", hash = "sha256:12b971039599625c156d2231f6d72a29c31a22e9c237689459b5f1a3c353f532", size = 290167, upload-time = "2026-07-15T14:53:58.422Z" }, ] [[package]] @@ -757,7 +757,7 @@ resolution-markers = [ "python_full_version >= '3.14'", ] dependencies = [ - { name = "typing-extensions", marker = "python_full_version >= '3.14'" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b6/e0/318c1ce3ae5a17894d5791e87aea147587c9e702f24122cc7a5c8bbaeeb1/grpcio-1.76.0.tar.gz", hash = "sha256:7be78388d6da1a25c0d5ec506523db58b18be22d9c37d8d3a32c08be4987bd73", size = 12785182, upload-time = "2025-10-21T16:23:12.106Z" } wheels = [