instructor 1.3.0__tar.gz → 1.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {instructor-1.3.0 → instructor-1.3.2}/PKG-INFO +4 -4
  2. {instructor-1.3.0 → instructor-1.3.2}/README.md +3 -3
  3. {instructor-1.3.0 → instructor-1.3.2}/instructor/__init__.py +4 -1
  4. {instructor-1.3.0 → instructor-1.3.2}/instructor/client_groq.py +3 -3
  5. {instructor-1.3.0 → instructor-1.3.2}/instructor/process_response.py +26 -6
  6. {instructor-1.3.0 → instructor-1.3.2}/pyproject.toml +1 -1
  7. {instructor-1.3.0 → instructor-1.3.2}/LICENSE +0 -0
  8. {instructor-1.3.0 → instructor-1.3.2}/instructor/_types/__init__.py +0 -0
  9. {instructor-1.3.0 → instructor-1.3.2}/instructor/_types/_alias.py +0 -0
  10. {instructor-1.3.0 → instructor-1.3.2}/instructor/cli/__init__.py +0 -0
  11. {instructor-1.3.0 → instructor-1.3.2}/instructor/cli/cli.py +0 -0
  12. {instructor-1.3.0 → instructor-1.3.2}/instructor/cli/files.py +0 -0
  13. {instructor-1.3.0 → instructor-1.3.2}/instructor/cli/hub.py +0 -0
  14. {instructor-1.3.0 → instructor-1.3.2}/instructor/cli/jobs.py +0 -0
  15. {instructor-1.3.0 → instructor-1.3.2}/instructor/cli/usage.py +0 -0
  16. {instructor-1.3.0 → instructor-1.3.2}/instructor/client.py +0 -0
  17. {instructor-1.3.0 → instructor-1.3.2}/instructor/client_anthropic.py +0 -0
  18. {instructor-1.3.0 → instructor-1.3.2}/instructor/client_cohere.py +0 -0
  19. {instructor-1.3.0 → instructor-1.3.2}/instructor/client_gemini.py +0 -0
  20. {instructor-1.3.0 → instructor-1.3.2}/instructor/client_mistral.py +0 -0
  21. {instructor-1.3.0 → instructor-1.3.2}/instructor/distil.py +0 -0
  22. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/__init__.py +0 -0
  23. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/citation.py +0 -0
  24. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/iterable.py +0 -0
  25. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/maybe.py +0 -0
  26. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/parallel.py +0 -0
  27. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/partial.py +0 -0
  28. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/simple_type.py +0 -0
  29. {instructor-1.3.0 → instructor-1.3.2}/instructor/dsl/validators.py +0 -0
  30. {instructor-1.3.0 → instructor-1.3.2}/instructor/exceptions.py +0 -0
  31. {instructor-1.3.0 → instructor-1.3.2}/instructor/function_calls.py +0 -0
  32. {instructor-1.3.0 → instructor-1.3.2}/instructor/mode.py +0 -0
  33. {instructor-1.3.0 → instructor-1.3.2}/instructor/patch.py +0 -0
  34. {instructor-1.3.0 → instructor-1.3.2}/instructor/py.typed +0 -0
  35. {instructor-1.3.0 → instructor-1.3.2}/instructor/retry.py +0 -0
  36. {instructor-1.3.0 → instructor-1.3.2}/instructor/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: instructor
3
- Version: 1.3.0
3
+ Version: 1.3.2
4
4
  Summary: structured outputs for llm
5
5
  Home-page: https://github.com/jxnl/instructor
6
6
  License: MIT
@@ -244,7 +244,7 @@ assert resp.name == "Jason"
244
244
  assert resp.age == 25
245
245
  ```
246
246
 
247
- ## Type are inferred correctly
247
+ ## Types are inferred correctly
248
248
 
249
249
  This was the dream of instructor but due to the patching of openai, it wasnt possible for me to get typing to work well. Now, with the new client, we can get typing to work well! We've also added a few `create_*` methods to make it easier to create iterables and partials, and to access the original completion.
250
250
 
@@ -272,7 +272,7 @@ user = client.chat.completions.create(
272
272
  )
273
273
  ```
274
274
 
275
- Now if you use a IDE, you can see the type is correctly inferred.
275
+ Now if you use an IDE, you can see the type is correctly inferred.
276
276
 
277
277
  ![type](./docs/blog/posts/img/type.png)
278
278
 
@@ -339,7 +339,7 @@ user, completion = client.chat.completions.create_with_completion(
339
339
 
340
340
  ### Streaming Partial Objects: `create_partial`
341
341
 
342
- In order to handle streams, we still support `Iterable[T]` and `Partial[T]` but to simply the type inference, we've added `create_iterable` and `create_partial` methods as well!
342
+ In order to handle streams, we still support `Iterable[T]` and `Partial[T]` but to simplify the type inference, we've added `create_iterable` and `create_partial` methods as well!
343
343
 
344
344
  ```python
345
345
  import openai
@@ -198,7 +198,7 @@ assert resp.name == "Jason"
198
198
  assert resp.age == 25
199
199
  ```
200
200
 
201
- ## Type are inferred correctly
201
+ ## Types are inferred correctly
202
202
 
203
203
  This was the dream of instructor but due to the patching of openai, it wasnt possible for me to get typing to work well. Now, with the new client, we can get typing to work well! We've also added a few `create_*` methods to make it easier to create iterables and partials, and to access the original completion.
204
204
 
@@ -226,7 +226,7 @@ user = client.chat.completions.create(
226
226
  )
227
227
  ```
228
228
 
229
- Now if you use a IDE, you can see the type is correctly inferred.
229
+ Now if you use an IDE, you can see the type is correctly inferred.
230
230
 
231
231
  ![type](./docs/blog/posts/img/type.png)
232
232
 
@@ -293,7 +293,7 @@ user, completion = client.chat.completions.create_with_completion(
293
293
 
294
294
  ### Streaming Partial Objects: `create_partial`
295
295
 
296
- In order to handle streams, we still support `Iterable[T]` and `Partial[T]` but to simply the type inference, we've added `create_iterable` and `create_partial` methods as well!
296
+ In order to handle streams, we still support `Iterable[T]` and `Partial[T]` but to simplify the type inference, we've added `create_iterable` and `create_partial` methods as well!
297
297
 
298
298
  ```python
299
299
  import openai
@@ -52,7 +52,10 @@ if importlib.util.find_spec("anthropic") is not None:
52
52
 
53
53
  __all__ += ["from_anthropic"]
54
54
 
55
- if importlib.util.find_spec("google.generativeai") is not None:
55
+ if (
56
+ importlib.util.find_spec("google")
57
+ and importlib.util.find_spec("google.generativeai") is not None
58
+ ):
56
59
  from .client_gemini import from_gemini
57
60
 
58
61
  __all__ += ["from_gemini"]
@@ -20,7 +20,7 @@ def from_groq(
20
20
  client: groq.AsyncGroq,
21
21
  mode: instructor.Mode = instructor.Mode.TOOLS,
22
22
  **kwargs: Any,
23
- ) -> instructor.Instructor:
23
+ ) -> instructor.AsyncInstructor:
24
24
  ...
25
25
 
26
26
 
@@ -28,7 +28,7 @@ def from_groq(
28
28
  client: groq.Groq | groq.AsyncGroq,
29
29
  mode: instructor.Mode = instructor.Mode.TOOLS,
30
30
  **kwargs: Any,
31
- ) -> instructor.Instructor:
31
+ ) -> instructor.Instructor | instructor.AsyncInstructor:
32
32
  assert mode in {
33
33
  instructor.Mode.JSON,
34
34
  instructor.Mode.TOOLS,
@@ -48,7 +48,7 @@ def from_groq(
48
48
  )
49
49
 
50
50
  else:
51
- return instructor.Instructor(
51
+ return instructor.AsyncInstructor(
52
52
  client=client,
53
53
  create=instructor.patch(create=client.chat.completions.create, mode=mode),
54
54
  provider=instructor.Provider.GROQ,
@@ -314,9 +314,7 @@ def handle_response_model(
314
314
  + "\n\n".join(openai_system_messages)
315
315
  )
316
316
 
317
- new_kwargs[
318
- "system"
319
- ] += f"""
317
+ new_kwargs["system"] += f"""
320
318
  You must only response in JSON format that adheres to the following schema:
321
319
 
322
320
  <JSON_SCHEMA>
@@ -359,6 +357,9 @@ The output must be a valid JSON object that `{response_model.__name__}.model_val
359
357
  new_kwargs["message"] = instruction
360
358
  new_kwargs["chat_history"] = chat_history
361
359
  elif mode == Mode.GEMINI_JSON:
360
+ assert (
361
+ "model" not in new_kwargs
362
+ ), "Gemini `model` must be set while patching the client, not passed as a parameter to the create method"
362
363
  message = dedent(
363
364
  f"""
364
365
  As a genius expert, your task is to understand the content and provide
@@ -388,15 +389,34 @@ The output must be a valid JSON object that `{response_model.__name__}.model_val
388
389
  "generation_config", {}
389
390
  ) | {"response_mime_type": "application/json"}
390
391
 
392
+ map_openai_args_to_gemini = {
393
+ "max_tokens": "max_output_tokens",
394
+ "temperature": "temperature",
395
+ "n": "candidate_count",
396
+ "top_p": "top_p",
397
+ "stop": "stop_sequences",
398
+ }
399
+
400
+ # update gemini config if any params are set
401
+ for k, v in map_openai_args_to_gemini.items():
402
+ val = new_kwargs.pop(k, None)
403
+ if val == None:
404
+ continue
405
+ new_kwargs["generation_config"][v] = val
406
+
407
+ # gemini has a different prompt format and params from other providers
408
+ new_kwargs["contents"] = transform_to_gemini_prompt(
409
+ new_kwargs.pop("messages")
410
+ )
411
+
391
412
  # minimize gemini safety related errors - model is highly prone to false alarms
413
+ from google.generativeai.types import HarmCategory, HarmBlockThreshold
414
+
392
415
  new_kwargs["safety_settings"] = new_kwargs.get("safety_settings", {}) | {
393
416
  HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_ONLY_HIGH,
394
417
  HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_ONLY_HIGH,
395
418
  HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT: HarmBlockThreshold.BLOCK_ONLY_HIGH,
396
419
  }
397
- # gemini has a different prompt format and params from other providers
398
- new_kwargs["contents"] = transform_to_gemini_prompt(new_kwargs["messages"])
399
- del new_kwargs["messages"]
400
420
  else:
401
421
  raise ValueError(f"Invalid patch mode: {mode}")
402
422
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "instructor"
3
- version = "1.3.0"
3
+ version = "1.3.2"
4
4
  description = "structured outputs for llm"
5
5
  authors = ["Jason Liu <jason@jxnl.co>"]
6
6
  license = "MIT"
File without changes