diff --git a/pyproject.toml b/pyproject.toml index b1cf302..f52f294 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "jira>=3.10.5", "slack-sdk>=3.37.0", "pydantic-settings>=2.11.0", + "google-genai >= 1.52.0", ] [dependency-groups] diff --git a/rcav2/model.py b/rcav2/model.py index 0cedc81..d0649d9 100644 --- a/rcav2/model.py +++ b/rcav2/model.py @@ -54,13 +54,24 @@ def __exit__(self, *args): def get_lm(settings: Settings, name: str, max_tokens: int) -> dspy.LM: - return dspy.LM( - f"gemini/{name}", - temperature=settings.LLM_TEMPERATURE, - max_tokens=max_tokens, - api_key=settings.LLM_GEMINI_KEY, - ) - + kwargs = { + "temperature": settings.LLM_TEMPERATURE, + "max_tokens": max_tokens, + "api_key": settings.LLM_GEMINI_KEY, + } + model_version = name.split("-")[1] + if model_version.startswith("3"): + from google import genai + from google.genai import types + + # Thinking levels: https://ai.google.dev/gemini-api/docs/thinking#thinking-levels + thinking_config = types.GenerateContentConfig( + thinking_config=types.ThinkingConfig( + thinking_level=types.ThinkingLevel.HIGH, # accepted: HIGH, LOW, potentially MEDIUM + ) + ) + kwargs["config"] = thinking_config + return dspy.LM(f"gemini/{name}", **kwargs) # From: https://dspy.ai/tutorials/observability/?h=callback#building-a-custom-logging-solution # 1. Define a custom callback class that extends BaseCallback class @@ -101,6 +112,7 @@ def init_dspy(settings: Settings) -> None: log_graph=True, ) dspy.configure( + # lm=get_lm(settings, "gemini-3-pro-preview", 1024 * 1024), lm=get_lm(settings, "gemini-2.5-pro", 1024 * 1024), callbacks=[opik_callback], ) diff --git a/uv.lock b/uv.lock index 0486395..c9e01b8 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 4 requires-python = ">=3.12" [[package]] @@ -573,6 +573,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7d/de/6b36d65bb85f46b40b96e04eb7facfcdb674b6cec554a821be2e44cd4871/gepa-0.0.7-py3-none-any.whl", hash = "sha256:59b8b74f5e384a62d6f590ac6ffe0fa8a0e62fee8d8d6c539f490823d0ffb25c", size = 52316, upload-time = "2025-08-25T03:46:40.424Z" }, ] +[[package]] +name = "google-auth" +version = "2.43.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachetools" }, + { name = "pyasn1-modules" }, + { name = "rsa" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ff/ef/66d14cf0e01b08d2d51ffc3c20410c4e134a1548fc246a6081eae585a4fe/google_auth-2.43.0.tar.gz", hash = "sha256:88228eee5fc21b62a1b5fe773ca15e67778cb07dc8363adcb4a8827b52d81483", size = 296359, upload-time = "2025-11-06T00:13:36.587Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6f/d1/385110a9ae86d91cc14c5282c61fe9f4dc41c0b9f7d423c6ad77038c4448/google_auth-2.43.0-py2.py3-none-any.whl", hash = "sha256:af628ba6fa493f75c7e9dbe9373d148ca9f4399b5ea29976519e0a3848eddd16", size = 223114, upload-time = "2025-11-06T00:13:35.209Z" }, +] + +[[package]] +name = "google-genai" +version = "1.52.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "google-auth" }, + { name = "httpx" }, + { name = "pydantic" }, + { name = "requests" }, + { name = "tenacity" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/09/4e/0ad8585d05312074bb69711b2d81cfed69ce0ae441913d57bf169bed20a7/google_genai-1.52.0.tar.gz", hash = "sha256:a74e8a4b3025f23aa98d6a0f84783119012ca6c336fd68f73c5d2b11465d7fc5", size = 258743, upload-time = "2025-11-21T02:18:55.742Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/66/03f663e7bca7abe9ccfebe6cb3fe7da9a118fd723a5abb278d6117e7990e/google_genai-1.52.0-py3-none-any.whl", hash = "sha256:c8352b9f065ae14b9322b949c7debab8562982f03bf71d44130cd2b798c20743", size = 261219, upload-time = "2025-11-21T02:18:54.515Z" }, +] + [[package]] name = "greenlet" version = "3.2.4" @@ -1418,6 +1451,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/16/794c114f6041bbe2de23eb418ef58a0f45de27224d5540f5dbb266a73d72/propcache-0.4.0-py3-none-any.whl", hash = "sha256:015b2ca2f98ea9e08ac06eecc409d5d988f78c5fd5821b2ad42bc9afcd6b1557", size = 13183, upload-time = "2025-10-04T21:57:38.054Z" }, ] +[[package]] +name = "pyasn1" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/e6/78ebbb10a8c8e4b61a59249394a4a594c1a7af95593dc933a349c8d00964/pyasn1_modules-0.4.2.tar.gz", hash = "sha256:677091de870a80aae844b1ca6134f54652fa2c8c5a52aa396440ac3106e941e6", size = 307892, upload-time = "2025-03-28T02:41:22.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/8d/d529b5d697919ba8c11ad626e835d4039be708a35b0d22de83a269a6682c/pyasn1_modules-0.4.2-py3-none-any.whl", hash = "sha256:29253a9207ce32b64c3ac6600edc75368f98473906e8fd1043bd6b5b1de2c14a", size = 181259, upload-time = "2025-03-28T02:41:19.028Z" }, +] + [[package]] name = "pydantic" version = "2.11.7" @@ -1633,6 +1687,7 @@ source = { editable = "." } dependencies = [ { name = "dspy" }, { name = "fastapi", extra = ["standard"] }, + { name = "google-genai" }, { name = "httpx" }, { name = "httpx-gssapi" }, { name = "httpx-ws" }, @@ -1656,6 +1711,7 @@ requires-dist = [ { name = "dspy", specifier = "==3.0.3" }, { name = "fastapi", specifier = ">=0.116.1" }, { name = "fastapi", extras = ["standard"] }, + { name = "google-genai", specifier = ">=1.52.0" }, { name = "httpx", specifier = ">=0.28.1" }, { name = "httpx-gssapi", specifier = ">=0.4" }, { name = "httpx-ws", specifier = ">=0.7.2" }, @@ -1960,6 +2016,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/32/7d/97119da51cb1dd3f2f3c0805f155a3aa4a95fa44fe7d78ae15e69edf4f34/rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772", size = 230097, upload-time = "2025-08-27T12:15:03.961Z" }, ] +[[package]] +name = "rsa" +version = "4.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyasn1" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/8a/22b7beea3ee0d44b1916c0c1cb0ee3af23b700b6da9f04991899d0c555d4/rsa-4.9.1.tar.gz", hash = "sha256:e7bdbfdb5497da4c07dfd35530e1a902659db6ff241e39d9953cad06ebd0ae75", size = 29034, upload-time = "2025-04-16T09:51:18.218Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/8d/0133e4eb4beed9e425d9a98ed6e081a55d195481b7632472be1af08d2f6b/rsa-4.9.1-py3-none-any.whl", hash = "sha256:68635866661c6836b8d39430f97a996acbd61bfa49406748ea243539fe239762", size = 34696, upload-time = "2025-04-16T09:51:17.142Z" }, +] + [[package]] name = "ruff" version = "0.12.11"