Skip to content

Commit c0e74ea

Browse files
feat: migrate from Vertex AI models to Google Gemini models (#14)
- Replace VertexAI model classes with GeminiModel for Google AI integration - Update exception naming: ModelNotDerivedError → ResponseNotDerivedError - Replace poetry with uv for dependency management - Update model references throughout codebase and tests - Refactor language_models module to use google-genai package - Update documentation to reflect new model structure - Remove poetry.lock and add uv.lock for new package manager BREAKING CHANGES: - Vertex AI models (VertexAIChatModel, VertexAIGenerativeModel, VertexAITextGenerationModel) removed - Exception class renamed from ModelNotDerivedError to ResponseNotDerivedError - Package manager changed from poetry to uv - Google AI models now use GeminiModel instead of Vertex AI classes
1 parent 50262ef commit c0e74ea

15 files changed

Lines changed: 1049 additions & 2647 deletions

README.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
</p>
44

55
# Modelsmith
6-
### Modelsmith is a Python library that allows you to get structured responses in the form of Pydantic models and Python types from Anthropic, Google Vertex AI, and OpenAI models.
6+
### Modelsmith is a Python library that allows you to get structured responses in the form of Pydantic models and Python types from Anthropic, Google Gemini, and OpenAI models.
77

88
Currently it allows you to use the following classes of model:
9-
- __AnthropicModel__ (used with Anthropic's set of models such as `claude-3-haiku`, `claude-3-sonnet`, `claude-3-opus` and `claude-3_5-sonnet`)
10-
- __OpenAIModel__ (used with OpenAI's set of models such as `gpt-3.5-turbo`, `gpt-4` and `gpt-4o`)
11-
- __VertexAIChatModel__ (used with Google Vertex AI's chat models such as `chat-bison`)
12-
- __VertexAITextGenerationModel__ (used with Google Vertex AI's text generation models such as `text-bison`)
13-
- __VertexAIGenerativeModel__ (used with Google Vertex AI's generative models such as `gemini-pro`)
9+
- __AnthropicModel__ (used with Anthropic's full set of models)
10+
- __OpenAIModel__ (used with OpenAI's full set of models)
11+
- __GeminiModel__ (used with Google's full set of Gemini models)
1412

1513
Modelsmith provides a unified interface over all of these. It has been designed to be extensible and can adapt to other models in the future.
1614

docs/getting_started.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class User(BaseModel):
1818

1919

2020
# Create your forge instance
21-
forge = Forge(model=OpenAIModel("gpt-3.5-turbo"), response_model=User)
21+
forge = Forge(model=OpenAIModel("gpt-5"), response_model=User)
2222

2323
# Generate a User instance from the prompt
2424
user = forge.generate("Terry Tate 60. Lives in Irvine, United States.")
@@ -31,7 +31,7 @@ print(user) # name='Terry Tate' age=60 city='Irvine' country='United States'
3131
Modelsmith does not restrict you to either Pydantic models or Python types. You can combine them in the same response. Below we extract a list of Pydantic model instances.
3232

3333
```python
34-
from modelsmith import Forge, VertexAIGenerativeModel
34+
from modelsmith import Forge, GeminiModel
3535
from pydantic import BaseModel, Field
3636

3737

@@ -42,7 +42,7 @@ class City(BaseModel):
4242

4343
# Pass a list of Pydantic models to the response_model argument.
4444
forge = Forge(
45-
model=VertexAIGenerativeModel("gemini-1.5-pro"),
45+
model=GeminiModel("gemini-2.5-pro"),
4646
response_model=list[City],
4747
)
4848

@@ -53,10 +53,10 @@ print(response) # [City(city='Irvine', state='CA'), City(city='Dallas', state='
5353

5454
## Using different model types
5555

56-
Using a different model is as simple as passing the desired model class to the Forge. Taking the example above lets use `text-bison` instead of `gemini-pro`.
56+
Using a different model is as simple as passing the desired model class to the Forge. Taking the example above lets use `gemini-2.5-flash` instead of `gemini-2.5-pro`.
5757

5858
```python
59-
from modelsmith import Forge, VertexAITextGenerationModel # import the correct class
59+
from modelsmith import Forge, GeminiModel # import the correct class
6060
from pydantic import BaseModel, Field
6161

6262

@@ -65,9 +65,9 @@ class City(BaseModel):
6565
state: str = Field(description="2-letter abbreviation of the state")
6666

6767

68-
# text-bison instead of gemini-pro
68+
# gemini-2.5-flash instead of gemini-2.5-pro
6969
forge = Forge(
70-
model=VertexAITextGenerationModel("text-bison"),
70+
model=GeminiModel("gemini-2.5-flash"),
7171
response_model=list[City],
7272
)
7373

@@ -76,7 +76,7 @@ response = forge.generate("I have lived in Irvine, CA and Dallas TX")
7676
print(response) # [City(city='Irvine', state='CA'), City(city='Dallas', state='TX')]
7777
```
7878

79-
If we want to use an Anthropic model the same applies. Simply select the appropriate model class, specify which Anthropic model to use (in this case `claude-3-haiku-20240307`), and pass it to the `Forge` instance.
79+
If we want to use an Anthropic model the same applies. Simply select the appropriate model class, specify which Anthropic model to use (in this case `claude-sonnet-4-20250514`), and pass it to the `Forge` instance.
8080

8181
```python
8282
from modelsmith import Forge, AnthropicModel # import the correct class
@@ -88,9 +88,9 @@ class City(BaseModel):
8888
state: str = Field(description="2-letter abbreviation of the state")
8989

9090

91-
# Anthropic's claude-3-haiku-20240307 instead of gemini-pro
91+
# Anthropic's claude-sonnet-4-20250514 instead of gemini-2.5-flash
9292
forge = Forge(
93-
model=AnthropicModel("claude-3-haiku-20240307"),
93+
model=AnthropicModel("claude-sonnet-4-20250514"),
9494
response_model=list[City],
9595
)
9696

@@ -110,7 +110,7 @@ from modelsmith import Forge, VertexAIGenerativeModel
110110

111111
# Create your forge instance
112112
forge = Forge(
113-
model=VertexAIGenerativeModel("gemini-1.5-flash"), response_model=list[str]
113+
model=VertexAIGenerativeModel("gemini-2.5-flash"), response_model=list[str]
114114
)
115115

116116
# Define examples, using inspect.cleandoc to remove indentation
@@ -177,7 +177,7 @@ The same example above would also work if the `response_model_json` was left out
177177
```python
178178
import inspect
179179

180-
from modelsmith import Forge, VertexAITextGenerationModel
180+
from modelsmith import Forge, GeminiModel
181181

182182
# Create your custom prompt
183183
my_prompt = inspect.cleandoc("""
@@ -188,7 +188,7 @@ my_prompt = inspect.cleandoc("""
188188

189189
# Create your forge instance, passing your prompt
190190
forge = Forge(
191-
model=VertexAITextGenerationModel("text-bison"),
191+
model=GeminiModel("gemini-2.5-flash"),
192192
response_model=list,
193193
prompt=my_prompt,
194194
)
@@ -224,7 +224,7 @@ You can change this by passing the `max_retries` parameter to the `Forge` class.
224224
```python
225225
# Create your forge instance, setting the number of retries
226226
forge = Forge(
227-
model=VertexAIGenerativeModel("gemini-1.0-pro"), response_model=int, max_retries=2
227+
model=GeminiModel("gemini-2.5-pro"), response_model=int, max_retries=2
228228
)
229229
```
230230

@@ -234,7 +234,7 @@ Modelsmith looks for JSON output in the LLM response. It uses regular expression
234234

235235
## Failing silently
236236

237-
Modelsmith will raise a `ModelNotDerivedError` exception if no valid response was obtained. You can change this by passing `False` to the `raise_on_failure` parameter of the `Forge` class.
237+
Modelsmith will raise a `ResponseNotDerivedError` exception if no valid response was obtained. You can change this by passing `False` to the `raise_on_failure` parameter of the `Forge` class.
238238

239239
This will suppress the exception and return `None` instead.
240240

docs/index.md

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,11 @@ Modelsmith is a Python library that allows you to get structured responses in th
44

55
Currently it allows you to use the following classes of model:
66

7-
- __AnthropicModel__ (used with Anthropic's set of models such as `claude-3-haiku`, `claude-3-sonnet`, `claude-3-opus` and `claude-3_5-sonnet`)
7+
- __AnthropicModel__ (used with Anthropic's full set of models)
88

9-
- __OpenAIModel__ (used with OpenAI's set of models such as `gpt-3.5-turbo`, `gpt-4` and `gpt-4o`)
9+
- __OpenAIModel__ (used with OpenAI's full set of models)
1010

11-
- __VertexAIChatModel__ (used with Google Vertex AI's chat models such as `chat-bison`)
12-
13-
- __VertexAITextGenerationModel__ (used with Google Vertex AI's text generation models such as `text-bison`)
14-
15-
- __VertexAIGenerativeModel__ (used with Google Vertex AI's generative models such as `gemini-pro`)
11+
- __GeminiModel__ (used with Google's full set of Gemini models)
1612

1713

1814
Modelsmith provides a unified interface over all of these. It has been designed to be extensible and can adapt to other models in the future.

docs/installation.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@ The `AnthropicModel` class takes an optional `api_key` parameter. If not provide
1515

1616
## Google Cloud Authentication
1717

18-
Authentication to Google Cloud is done via the Application Default Credentials flow. So make sure you have ADC configured. See [Google's documentation](https://cloud.google.com/docs/authentication/provide-credentials-adc) for more details.
18+
Authentication to Google Cloud is done via either:
19+
- Application Default Credentials flow. See [Google's documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/start/quickstart?usertype=adc) for more details.
20+
- Gemini API Key. See [Google Gemini API docs](https://ai.google.dev/gemini-api/docs/api-key?_gl=1*1ya8hy4*_up*MQ..*_ga*MTA2MDc3MjY2MC4xNzU3NzkwNDQz*_ga_P1DBVKWT6V*czE3NTc3OTgwNTMkbzMkZzAkdDE3NTc3OTgwNTMkajYwJGwwJGgxMDQzMjc4MTU2).
21+
22+
The `GeminiModel` allows you to pass the `vertexai`, `api_key`, `project`, and `location` when you initialize the class instance. If you do not pass this in it will be inferred from the environment variables `GOOGLE_GENAI_USE_VERTEXAI`, `GOOGLE_API_KEY`, `GOOGLE_CLOUD_PROJECT`, and `GOOGLE_CLOUD_LOCATION` as per the documentation.
1923

2024
## Open AI Authentication
2125
Authentication to OpenAI is done via the OpenAI flow. See the [OpenAI documentation](https://platform.openai.com/docs/quickstart/step-2-set-up-your-api-key) for more details.

0 commit comments

Comments
 (0)