chatlas 0.4.0__tar.gz → 0.6.0__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.

Potentially problematic release.


This version of chatlas might be problematic. Click here for more details.

Files changed (167) hide show
  1. {chatlas-0.4.0 → chatlas-0.6.0}/.gitignore +3 -0
  2. {chatlas-0.4.0 → chatlas-0.6.0}/CHANGELOG.md +29 -0
  3. {chatlas-0.4.0 → chatlas-0.6.0}/Makefile +1 -1
  4. {chatlas-0.4.0 → chatlas-0.6.0}/PKG-INFO +26 -1
  5. {chatlas-0.4.0 → chatlas-0.6.0}/README.md +1 -0
  6. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/__init__.py +12 -0
  7. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_anthropic.py +22 -9
  8. chatlas-0.6.0/chatlas/_auto.py +183 -0
  9. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_chat.py +9 -7
  10. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_content.py +116 -24
  11. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_content_image.py +5 -8
  12. chatlas-0.6.0/chatlas/_content_pdf.py +94 -0
  13. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_display.py +12 -2
  14. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_github.py +1 -1
  15. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_google.py +17 -9
  16. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_groq.py +1 -1
  17. chatlas-0.6.0/chatlas/_live_render.py +116 -0
  18. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_ollama.py +1 -1
  19. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_openai.py +22 -6
  20. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_perplexity.py +1 -1
  21. chatlas-0.6.0/chatlas/_snowflake.py +321 -0
  22. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_turn.py +30 -24
  23. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_utils.py +7 -0
  24. chatlas-0.6.0/chatlas/_version.py +21 -0
  25. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/anthropic/_submit.py +23 -1
  26. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/openai/_submit.py +5 -1
  27. chatlas-0.6.0/chatlas/types/snowflake/__init__.py +8 -0
  28. chatlas-0.6.0/chatlas/types/snowflake/_submit.py +24 -0
  29. {chatlas-0.4.0 → chatlas-0.6.0}/docs/_quarto.yml +7 -0
  30. {chatlas-0.4.0 → chatlas-0.6.0}/docs/get-started.qmd +1 -1
  31. {chatlas-0.4.0 → chatlas-0.6.0}/docs/structured-data.qmd +7 -9
  32. {chatlas-0.4.0 → chatlas-0.6.0}/pyproject.toml +18 -0
  33. {chatlas-0.4.0 → chatlas-0.6.0}/scripts/_generate_openai_types.py +3 -3
  34. chatlas-0.6.0/scripts/_generate_snowflake_types.py +33 -0
  35. {chatlas-0.4.0 → chatlas-0.6.0}/scripts/main.py +1 -0
  36. chatlas-0.6.0/tests/apples.pdf +0 -0
  37. {chatlas-0.4.0 → chatlas-0.6.0}/tests/conftest.py +18 -1
  38. chatlas-0.6.0/tests/test_auto.py +109 -0
  39. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_chat.py +14 -1
  40. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_content_image.py +2 -2
  41. chatlas-0.6.0/tests/test_content_pdf.py +10 -0
  42. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_provider_anthropic.py +14 -2
  43. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_provider_azure.py +3 -2
  44. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_provider_google.py +8 -0
  45. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_provider_openai.py +6 -0
  46. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_turns.py +10 -2
  47. {chatlas-0.4.0 → chatlas-0.6.0}/.github/workflows/check-update-types.yml +0 -0
  48. {chatlas-0.4.0 → chatlas-0.6.0}/.github/workflows/docs-publish.yml +0 -0
  49. {chatlas-0.4.0 → chatlas-0.6.0}/.github/workflows/release.yml +0 -0
  50. {chatlas-0.4.0 → chatlas-0.6.0}/.github/workflows/test.yml +0 -0
  51. {chatlas-0.4.0 → chatlas-0.6.0}/.vscode/extensions.json +0 -0
  52. {chatlas-0.4.0 → chatlas-0.6.0}/.vscode/settings.json +0 -0
  53. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_interpolate.py +0 -0
  54. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_logging.py +0 -0
  55. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_merge.py +0 -0
  56. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_provider.py +0 -0
  57. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_tokens.py +0 -0
  58. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_tokens_old.py +0 -0
  59. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_tools.py +0 -0
  60. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/_typing_extensions.py +0 -0
  61. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/py.typed +0 -0
  62. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/__init__.py +0 -0
  63. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/anthropic/__init__.py +0 -0
  64. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/anthropic/_client.py +0 -0
  65. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/anthropic/_client_bedrock.py +0 -0
  66. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/google/__init__.py +0 -0
  67. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/google/_client.py +0 -0
  68. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/google/_submit.py +0 -0
  69. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/openai/__init__.py +0 -0
  70. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/openai/_client.py +0 -0
  71. {chatlas-0.4.0 → chatlas-0.6.0}/chatlas/types/openai/_client_azure.py +0 -0
  72. {chatlas-0.4.0 → chatlas-0.6.0}/docs/.gitignore +0 -0
  73. {chatlas-0.4.0 → chatlas-0.6.0}/docs/_extensions/machow/interlinks/.gitignore +0 -0
  74. {chatlas-0.4.0 → chatlas-0.6.0}/docs/_extensions/machow/interlinks/_extension.yml +0 -0
  75. {chatlas-0.4.0 → chatlas-0.6.0}/docs/_extensions/machow/interlinks/interlinks.lua +0 -0
  76. {chatlas-0.4.0 → chatlas-0.6.0}/docs/_sidebar.yml +0 -0
  77. {chatlas-0.4.0 → chatlas-0.6.0}/docs/congressional-assets.png +0 -0
  78. {chatlas-0.4.0 → chatlas-0.6.0}/docs/examples/third-party-testing.txt +0 -0
  79. {chatlas-0.4.0 → chatlas-0.6.0}/docs/images/congressional-assets.png +0 -0
  80. {chatlas-0.4.0 → chatlas-0.6.0}/docs/images/logo.png +0 -0
  81. {chatlas-0.4.0 → chatlas-0.6.0}/docs/images/posit-logo.png +0 -0
  82. {chatlas-0.4.0 → chatlas-0.6.0}/docs/images/tool-calling-right.svg +0 -0
  83. {chatlas-0.4.0 → chatlas-0.6.0}/docs/images/tool-calling-wrong.svg +0 -0
  84. {chatlas-0.4.0 → chatlas-0.6.0}/docs/index.py +0 -0
  85. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/favicon/android-chrome-192x192.png +0 -0
  86. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/favicon/android-chrome-512x512.png +0 -0
  87. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/favicon/apple-touch-icon.png +0 -0
  88. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/favicon/favicon-16x16.png +0 -0
  89. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/favicon/favicon-32x32.png +0 -0
  90. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/favicon/favicon.ico +0 -0
  91. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/icon/brand-yml-icon-black.png +0 -0
  92. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/icon/brand-yml-icon-black.svg +0 -0
  93. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/icon/brand-yml-icon-color.png +0 -0
  94. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/icon/brand-yml-icon-color.svg +0 -0
  95. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/icon/brand-yml-icon-white.png +0 -0
  96. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/icon/brand-yml-icon-white.svg +0 -0
  97. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/tall/brand-yml-tall-black.png +0 -0
  98. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/tall/brand-yml-tall-black.svg +0 -0
  99. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/tall/brand-yml-tall-color.png +0 -0
  100. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/tall/brand-yml-tall-color.svg +0 -0
  101. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/tall/brand-yml-tall-white.png +0 -0
  102. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/tall/brand-yml-tall-white.svg +0 -0
  103. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-black.png +0 -0
  104. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-black.svg +0 -0
  105. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-color.png +0 -0
  106. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-color.svg +0 -0
  107. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-large-black.png +0 -0
  108. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-large-color.png +0 -0
  109. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-large-white.png +0 -0
  110. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-white.png +0 -0
  111. {chatlas-0.4.0 → chatlas-0.6.0}/docs/logos/wide/brand-yml-wide-white.svg +0 -0
  112. {chatlas-0.4.0 → chatlas-0.6.0}/docs/prompt-design.qmd +0 -0
  113. {chatlas-0.4.0 → chatlas-0.6.0}/docs/rag.qmd +0 -0
  114. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/Chat.qmd +0 -0
  115. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatAnthropic.qmd +0 -0
  116. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatAzureOpenAI.qmd +0 -0
  117. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatBedrockAnthropic.qmd +0 -0
  118. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatGithub.qmd +0 -0
  119. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatGoogle.qmd +0 -0
  120. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatGroq.qmd +0 -0
  121. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatOllama.qmd +0 -0
  122. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatOpenAI.qmd +0 -0
  123. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatPerplexity.qmd +0 -0
  124. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/ChatVertex.qmd +0 -0
  125. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/Provider.qmd +0 -0
  126. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/Tool.qmd +0 -0
  127. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/Turn.qmd +0 -0
  128. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/content_image_file.qmd +0 -0
  129. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/content_image_plot.qmd +0 -0
  130. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/content_image_url.qmd +0 -0
  131. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/image_file.qmd +0 -0
  132. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/image_plot.qmd +0 -0
  133. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/image_url.qmd +0 -0
  134. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/index.qmd +0 -0
  135. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/interpolate.qmd +0 -0
  136. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/interpolate_file.qmd +0 -0
  137. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/token_usage.qmd +0 -0
  138. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ChatResponse.qmd +0 -0
  139. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ChatResponseAsync.qmd +0 -0
  140. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.Content.qmd +0 -0
  141. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentImage.qmd +0 -0
  142. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentImageInline.qmd +0 -0
  143. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentImageRemote.qmd +0 -0
  144. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentJson.qmd +0 -0
  145. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentText.qmd +0 -0
  146. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentToolRequest.qmd +0 -0
  147. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ContentToolResult.qmd +0 -0
  148. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.ImageContentTypes.qmd +0 -0
  149. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.MISSING.qmd +0 -0
  150. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.MISSING_TYPE.qmd +0 -0
  151. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.SubmitInputArgsT.qmd +0 -0
  152. {chatlas-0.4.0 → chatlas-0.6.0}/docs/reference/types.TokenUsage.qmd +0 -0
  153. {chatlas-0.4.0 → chatlas-0.6.0}/docs/styles.scss +0 -0
  154. {chatlas-0.4.0 → chatlas-0.6.0}/docs/tool-calling.qmd +0 -0
  155. {chatlas-0.4.0 → chatlas-0.6.0}/docs/web-apps.qmd +0 -0
  156. {chatlas-0.4.0 → chatlas-0.6.0}/pytest.ini +0 -0
  157. {chatlas-0.4.0 → chatlas-0.6.0}/scripts/_generate_anthropic_types.py +0 -0
  158. {chatlas-0.4.0 → chatlas-0.6.0}/scripts/_generate_google_types.py +0 -0
  159. {chatlas-0.4.0 → chatlas-0.6.0}/scripts/_utils.py +0 -0
  160. {chatlas-0.4.0 → chatlas-0.6.0}/tests/__init__.py +0 -0
  161. {chatlas-0.4.0 → chatlas-0.6.0}/tests/__snapshots__/test_chat.ambr +0 -0
  162. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_content.py +0 -0
  163. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_content_tools.py +0 -0
  164. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_interpolate.py +0 -0
  165. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_provider_bedrock.py +0 -0
  166. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_tokens.py +0 -0
  167. {chatlas-0.4.0 → chatlas-0.6.0}/tests/test_utils_merge.py +0 -0
@@ -12,3 +12,6 @@ sandbox/
12
12
 
13
13
  # Automatically generated by docs/index.py
14
14
  docs/index.qmd
15
+
16
+ # setuptools_scm
17
+ chatlas/_version.py
@@ -7,6 +7,35 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
8
  -->
9
9
 
10
+ ## [0.6.0] - 2025-04-01
11
+
12
+ ### New features
13
+
14
+ * New `content_pdf_file()` and `content_pdf_url()` allow you to upload PDFs to supported models. (#74)
15
+
16
+ ### Improvements
17
+
18
+ * `Turn` and `Content` now inherit from `pydantic.BaseModel` to provide easier saving to and loading from JSON. (#72)
19
+
20
+ ## [0.5.0] - 2025-03-18
21
+
22
+ ### New features
23
+
24
+ * Added a `ChatSnowflake()` class to interact with [Snowflake Cortex LLM](https://docs.snowflake.com/en/user-guide/snowflake-cortex/llm-functions). (#54)
25
+ * Added a `ChatAuto()` class, allowing for configuration of chat providers and models via environment variables. (#38, thanks @mconflitti-pbc)
26
+
27
+ ### Improvements
28
+
29
+ * Updated `ChatAnthropic()`'s `model` default to `"claude-3-7-sonnet-latest"`. (#62)
30
+ * The version is now accessible as `chatlas.__version__`. (#64)
31
+ * All provider-specific `Chat` subclasses now have an associated extras in chatlas. For example, `ChatOpenAI` has `chatlas[openai]`, `ChatPerplexity` has `chatlas[perplexity]`, `ChatBedrockAnthropic` has `chatlas[bedrock-anthropic]`, and so forth for the other `Chat` classes. (#66)
32
+
33
+ ### Bug fixes
34
+
35
+ * Fixed an issue with content getting duplicated when it overflows in a `Live()` console. (#71)
36
+ * Fix an issue with tool calls not working with `ChatVertex()`. (#61)
37
+
38
+
10
39
  ## [0.4.0] - 2025-02-19
11
40
 
12
41
  ### New features
@@ -9,7 +9,7 @@ build: ## [py] Build python package
9
9
  uv build
10
10
 
11
11
  .PHONY: check
12
- check: check-tests check-format check-types ## [py] Run python checks
12
+ check: check-format check-types check-tests ## [py] Run python checks
13
13
 
14
14
  .PHONY: check-tests
15
15
  check-tests: ## [py] Run python tests
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatlas
3
- Version: 0.4.0
3
+ Version: 0.6.0
4
4
  Summary: A simple and consistent interface for chatting with LLMs
5
5
  Project-URL: Homepage, https://posit-dev.github.io/chatlas
6
6
  Project-URL: Documentation, https://posit-dev.github.io/chatlas
@@ -20,6 +20,12 @@ Requires-Python: >=3.9
20
20
  Requires-Dist: jinja2
21
21
  Requires-Dist: pydantic>=2.0
22
22
  Requires-Dist: rich
23
+ Provides-Extra: anthropic
24
+ Requires-Dist: anthropic; extra == 'anthropic'
25
+ Provides-Extra: azure-openai
26
+ Requires-Dist: openai; extra == 'azure-openai'
27
+ Provides-Extra: bedrock-anthropic
28
+ Requires-Dist: anthropic[bedrock]; extra == 'bedrock-anthropic'
23
29
  Provides-Extra: dev
24
30
  Requires-Dist: anthropic[bedrock]; extra == 'dev'
25
31
  Requires-Dist: google-genai>=1.2.0; extra == 'dev'
@@ -30,7 +36,9 @@ Requires-Dist: pillow; extra == 'dev'
30
36
  Requires-Dist: python-dotenv; extra == 'dev'
31
37
  Requires-Dist: ruff>=0.6.5; extra == 'dev'
32
38
  Requires-Dist: shiny; extra == 'dev'
39
+ Requires-Dist: snowflake-ml-python; extra == 'dev'
33
40
  Requires-Dist: tiktoken; extra == 'dev'
41
+ Requires-Dist: torch; (python_version <= '3.11') and extra == 'dev'
34
42
  Provides-Extra: docs
35
43
  Requires-Dist: griffe>=1; extra == 'docs'
36
44
  Requires-Dist: ipykernel; extra == 'docs'
@@ -42,11 +50,27 @@ Requires-Dist: pandas; extra == 'docs'
42
50
  Requires-Dist: pyyaml; extra == 'docs'
43
51
  Requires-Dist: quartodoc>=0.7; extra == 'docs'
44
52
  Requires-Dist: sentence-transformers; extra == 'docs'
53
+ Provides-Extra: github
54
+ Requires-Dist: openai; extra == 'github'
55
+ Provides-Extra: google
56
+ Requires-Dist: google-genai; extra == 'google'
57
+ Provides-Extra: groq
58
+ Requires-Dist: openai; extra == 'groq'
59
+ Provides-Extra: ollama
60
+ Requires-Dist: openai; extra == 'ollama'
61
+ Provides-Extra: openai
62
+ Requires-Dist: openai; extra == 'openai'
63
+ Provides-Extra: perplexity
64
+ Requires-Dist: openai; extra == 'perplexity'
65
+ Provides-Extra: snowflake
66
+ Requires-Dist: snowflake-ml-python; extra == 'snowflake'
45
67
  Provides-Extra: test
46
68
  Requires-Dist: pyright>=1.1.379; extra == 'test'
47
69
  Requires-Dist: pytest-asyncio; extra == 'test'
48
70
  Requires-Dist: pytest>=8.3.2; extra == 'test'
49
71
  Requires-Dist: syrupy>=4; extra == 'test'
72
+ Provides-Extra: vertex
73
+ Requires-Dist: google-genai; extra == 'vertex'
50
74
  Description-Content-Type: text/markdown
51
75
 
52
76
  <h1 class="unnumbered unlisted"> chatlas <a href="https://posit-dev.github.io/chatlas"><img src="docs/images/logo.png" align="right" height="138" alt="chatlas website" /></a> </h1>
@@ -98,6 +122,7 @@ It also supports the following enterprise cloud providers:
98
122
 
99
123
  * AWS Bedrock: [`ChatBedrockAnthropic()`](https://posit-dev.github.io/chatlas/reference/ChatBedrockAnthropic.html).
100
124
  * Azure OpenAI: [`ChatAzureOpenAI()`](https://posit-dev.github.io/chatlas/reference/ChatAzureOpenAI.html).
125
+ * Snowflake Cortex: [`ChatSnowflake()`](https://posit-dev.github.io/chatlas/reference/ChatSnowflake.html).
101
126
  * Vertex AI: [`ChatVertex()`](https://posit-dev.github.io/chatlas/reference/ChatVertex.html).
102
127
 
103
128
  To use a model provider that isn't listed here, you have two options:
@@ -47,6 +47,7 @@ It also supports the following enterprise cloud providers:
47
47
 
48
48
  * AWS Bedrock: [`ChatBedrockAnthropic()`](https://posit-dev.github.io/chatlas/reference/ChatBedrockAnthropic.html).
49
49
  * Azure OpenAI: [`ChatAzureOpenAI()`](https://posit-dev.github.io/chatlas/reference/ChatAzureOpenAI.html).
50
+ * Snowflake Cortex: [`ChatSnowflake()`](https://posit-dev.github.io/chatlas/reference/ChatSnowflake.html).
50
51
  * Vertex AI: [`ChatVertex()`](https://posit-dev.github.io/chatlas/reference/ChatVertex.html).
51
52
 
52
53
  To use a model provider that isn't listed here, you have two options:
@@ -1,7 +1,9 @@
1
1
  from . import types
2
2
  from ._anthropic import ChatAnthropic, ChatBedrockAnthropic
3
+ from ._auto import ChatAuto
3
4
  from ._chat import Chat
4
5
  from ._content_image import content_image_file, content_image_plot, content_image_url
6
+ from ._content_pdf import content_pdf_file, content_pdf_url
5
7
  from ._github import ChatGithub
6
8
  from ._google import ChatGoogle, ChatVertex
7
9
  from ._groq import ChatGroq
@@ -10,12 +12,19 @@ from ._ollama import ChatOllama
10
12
  from ._openai import ChatAzureOpenAI, ChatOpenAI
11
13
  from ._perplexity import ChatPerplexity
12
14
  from ._provider import Provider
15
+ from ._snowflake import ChatSnowflake
13
16
  from ._tokens import token_usage
14
17
  from ._tools import Tool
15
18
  from ._turn import Turn
16
19
 
20
+ try:
21
+ from ._version import version as __version__
22
+ except ImportError: # pragma: no cover
23
+ __version__ = "0.0.0" # stub value for docs
24
+
17
25
  __all__ = (
18
26
  "ChatAnthropic",
27
+ "ChatAuto",
19
28
  "ChatBedrockAnthropic",
20
29
  "ChatGithub",
21
30
  "ChatGoogle",
@@ -24,11 +33,14 @@ __all__ = (
24
33
  "ChatOpenAI",
25
34
  "ChatAzureOpenAI",
26
35
  "ChatPerplexity",
36
+ "ChatSnowflake",
27
37
  "ChatVertex",
28
38
  "Chat",
29
39
  "content_image_file",
30
40
  "content_image_plot",
31
41
  "content_image_url",
42
+ "content_pdf_file",
43
+ "content_pdf_url",
32
44
  "interpolate",
33
45
  "interpolate_file",
34
46
  "Provider",
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import base64
3
4
  import json
4
5
  import warnings
5
6
  from typing import TYPE_CHECKING, Any, Literal, Optional, Union, cast, overload
@@ -12,6 +13,7 @@ from ._content import (
12
13
  ContentImageInline,
13
14
  ContentImageRemote,
14
15
  ContentJson,
16
+ ContentPDF,
15
17
  ContentText,
16
18
  ContentToolRequest,
17
19
  ContentToolResult,
@@ -31,6 +33,7 @@ if TYPE_CHECKING:
31
33
  ToolParam,
32
34
  ToolUseBlock,
33
35
  )
36
+ from anthropic.types.document_block_param import DocumentBlockParam
34
37
  from anthropic.types.image_block_param import ImageBlockParam
35
38
  from anthropic.types.model_param import ModelParam
36
39
  from anthropic.types.text_block_param import TextBlockParam
@@ -45,6 +48,7 @@ if TYPE_CHECKING:
45
48
  ImageBlockParam,
46
49
  ToolUseBlockParam,
47
50
  ToolResultBlockParam,
51
+ DocumentBlockParam,
48
52
  ]
49
53
  else:
50
54
  Message = object
@@ -72,7 +76,7 @@ def ChatAnthropic(
72
76
  ::: {.callout-note}
73
77
  ## API key
74
78
 
75
- Note that a Claude Prop membership does not give you the ability to call
79
+ Note that a Claude Pro membership does not give you the ability to call
76
80
  models via the API. You will need to go to the [developer
77
81
  console](https://console.anthropic.com/account/keys) to sign up (and pay
78
82
  for) a developer account that will give you an API key that you can use with
@@ -82,7 +86,7 @@ def ChatAnthropic(
82
86
  ::: {.callout-note}
83
87
  ## Python requirements
84
88
 
85
- `ChatAnthropic` requires the `anthropic` package (e.g., `pip install anthropic`).
89
+ `ChatAnthropic` requires the `anthropic` package: `pip install "chatlas[anthropic]"`.
86
90
  :::
87
91
 
88
92
  Examples
@@ -164,7 +168,7 @@ def ChatAnthropic(
164
168
  """
165
169
 
166
170
  if model is None:
167
- model = log_model_default("claude-3-5-sonnet-latest")
171
+ model = log_model_default("claude-3-7-sonnet-latest")
168
172
 
169
173
  return Chat(
170
174
  provider=AnthropicProvider(
@@ -450,12 +454,21 @@ class AnthropicProvider(Provider[Message, RawMessageStreamEvent, Message]):
450
454
  return {"text": content.text, "type": "text"}
451
455
  elif isinstance(content, ContentJson):
452
456
  return {"text": "<structured data/>", "type": "text"}
457
+ elif isinstance(content, ContentPDF):
458
+ return {
459
+ "type": "document",
460
+ "source": {
461
+ "type": "base64",
462
+ "media_type": "application/pdf",
463
+ "data": base64.b64encode(content.data).decode("utf-8"),
464
+ },
465
+ }
453
466
  elif isinstance(content, ContentImageInline):
454
467
  return {
455
468
  "type": "image",
456
469
  "source": {
457
470
  "type": "base64",
458
- "media_type": content.content_type,
471
+ "media_type": content.image_content_type,
459
472
  "data": content.data or "",
460
473
  },
461
474
  }
@@ -504,7 +517,7 @@ class AnthropicProvider(Provider[Message, RawMessageStreamEvent, Message]):
504
517
  contents = []
505
518
  for content in completion.content:
506
519
  if content.type == "text":
507
- contents.append(ContentText(content.text))
520
+ contents.append(ContentText(text=content.text))
508
521
  elif content.type == "tool_use":
509
522
  if has_data_model and content.name == "_structured_tool_call":
510
523
  if not isinstance(content.input, dict):
@@ -515,11 +528,11 @@ class AnthropicProvider(Provider[Message, RawMessageStreamEvent, Message]):
515
528
  raise ValueError(
516
529
  "Expected data extraction tool to return a 'data' field."
517
530
  )
518
- contents.append(ContentJson(content.input["data"]))
531
+ contents.append(ContentJson(value=content.input["data"]))
519
532
  else:
520
533
  contents.append(
521
534
  ContentToolRequest(
522
- content.id,
535
+ id=content.id,
523
536
  name=content.name,
524
537
  arguments=content.input,
525
538
  )
@@ -572,8 +585,8 @@ def ChatBedrockAnthropic(
572
585
  ::: {.callout-note}
573
586
  ## Python requirements
574
587
 
575
- `ChatBedrockAnthropic`, requires the `anthropic` package with the `bedrock` extras
576
- (e.g., `pip install anthropic[bedrock]`).
588
+ `ChatBedrockAnthropic`, requires the `anthropic` package with the `bedrock` extras:
589
+ `pip install "chatlas[bedrock-anthropic]"`
577
590
  :::
578
591
 
579
592
  Examples
@@ -0,0 +1,183 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import os
5
+ from typing import Callable, Literal, Optional
6
+
7
+ from ._anthropic import ChatAnthropic, ChatBedrockAnthropic
8
+ from ._chat import Chat
9
+ from ._github import ChatGithub
10
+ from ._google import ChatGoogle, ChatVertex
11
+ from ._groq import ChatGroq
12
+ from ._ollama import ChatOllama
13
+ from ._openai import ChatAzureOpenAI, ChatOpenAI
14
+ from ._perplexity import ChatPerplexity
15
+ from ._snowflake import ChatSnowflake
16
+ from ._turn import Turn
17
+
18
+ AutoProviders = Literal[
19
+ "anthropic",
20
+ "bedrock-anthropic",
21
+ "github",
22
+ "google",
23
+ "groq",
24
+ "ollama",
25
+ "openai",
26
+ "azure-openai",
27
+ "perplexity",
28
+ "snowflake",
29
+ "vertex",
30
+ ]
31
+
32
+ _provider_chat_model_map: dict[AutoProviders, Callable[..., Chat]] = {
33
+ "anthropic": ChatAnthropic,
34
+ "bedrock-anthropic": ChatBedrockAnthropic,
35
+ "github": ChatGithub,
36
+ "google": ChatGoogle,
37
+ "groq": ChatGroq,
38
+ "ollama": ChatOllama,
39
+ "openai": ChatOpenAI,
40
+ "azure-openai": ChatAzureOpenAI,
41
+ "perplexity": ChatPerplexity,
42
+ "snowflake": ChatSnowflake,
43
+ "vertex": ChatVertex,
44
+ }
45
+
46
+
47
+ def ChatAuto(
48
+ system_prompt: Optional[str] = None,
49
+ turns: Optional[list[Turn]] = None,
50
+ *,
51
+ provider: Optional[AutoProviders] = None,
52
+ model: Optional[str] = None,
53
+ **kwargs,
54
+ ) -> Chat:
55
+ """
56
+ Use environment variables (env vars) to configure the Chat provider and model.
57
+
58
+ Creates a `:class:~chatlas.Chat` instance based on the specified provider.
59
+ The provider may be specified through the `provider` parameter and/or the
60
+ `CHATLAS_CHAT_PROVIDER` env var. If both are set, the env var takes
61
+ precedence. Similarly, the provider's model may be specified through the
62
+ `model` parameter and/or the `CHATLAS_CHAT_MODEL` env var. Also, additional
63
+ configuration may be provided through the `kwargs` parameter and/or the
64
+ `CHATLAS_CHAT_ARGS` env var (as a JSON string). In this case, when both are
65
+ set, they are merged, with the env var arguments taking precedence.
66
+
67
+ As a result, `ChatAuto()` provides a convenient way to set a default
68
+ provider and model in your Python code, while allowing you to override
69
+ these settings through env vars (i.e., without modifying your code).
70
+
71
+ Prerequisites
72
+ -------------
73
+
74
+ ::: {.callout-note}
75
+ ## API key
76
+
77
+ Follow the instructions for the specific provider to obtain an API key.
78
+ :::
79
+
80
+ ::: {.callout-note}
81
+ ## Python requirements
82
+
83
+ Follow the instructions for the specific provider to install the required
84
+ Python packages.
85
+ :::
86
+
87
+
88
+ Examples
89
+ --------
90
+ First, set the environment variables for the provider, arguments, and API key:
91
+
92
+ ```bash
93
+ export CHATLAS_CHAT_PROVIDER=anthropic
94
+ export CHATLAS_CHAT_MODEL=claude-3-haiku-20240229
95
+ export CHATLAS_CHAT_ARGS='{"kwargs": {"max_retries": 3}}'
96
+ export ANTHROPIC_API_KEY=your_api_key
97
+ ```
98
+
99
+ Then, you can use the `ChatAuto` function to create a Chat instance:
100
+
101
+ ```python
102
+ from chatlas import ChatAuto
103
+
104
+ chat = ChatAuto()
105
+ chat.chat("What is the capital of France?")
106
+ ```
107
+
108
+ Parameters
109
+ ----------
110
+ provider
111
+ The name of the default chat provider to use. Providers are strings
112
+ formatted in kebab-case, e.g. to use `ChatBedrockAnthropic` set
113
+ `provider="bedrock-anthropic"`.
114
+
115
+ This value can also be provided via the `CHATLAS_CHAT_PROVIDER`
116
+ environment variable, which takes precedence over `provider`
117
+ when set.
118
+ model
119
+ The name of the default model to use. This value can also be provided
120
+ via the `CHATLAS_CHAT_MODEL` environment variable, which takes
121
+ precedence over `model` when set.
122
+ system_prompt
123
+ A system prompt to set the behavior of the assistant.
124
+ turns
125
+ A list of turns to start the chat with (i.e., continuing a previous
126
+ conversation). If not provided, the conversation begins from scratch. Do
127
+ not provide non-`None` values for both `turns` and `system_prompt`. Each
128
+ message in the list should be a dictionary with at least `role` (usually
129
+ `system`, `user`, or `assistant`, but `tool` is also possible). Normally
130
+ there is also a `content` field, which is a string.
131
+ **kwargs
132
+ Additional keyword arguments to pass to the Chat constructor. See the
133
+ documentation for each provider for more details on the available
134
+ options.
135
+
136
+ These arguments can also be provided via the `CHATLAS_CHAT_ARGS`
137
+ environment variable as a JSON string. When provided, the options
138
+ in the `CHATLAS_CHAT_ARGS` envvar take precedence over the options
139
+ passed to `kwargs`.
140
+
141
+ Note that `system_prompt` and `turns` in `kwargs` or in
142
+ `CHATLAS_CHAT_ARGS` are ignored.
143
+
144
+ Returns
145
+ -------
146
+ Chat
147
+ A chat instance using the specified provider.
148
+
149
+ Raises
150
+ ------
151
+ ValueError
152
+ If no valid provider is specified either through parameters or
153
+ environment variables.
154
+ """
155
+ the_provider = os.environ.get("CHATLAS_CHAT_PROVIDER", provider)
156
+
157
+ if the_provider is None:
158
+ raise ValueError(
159
+ "Provider name is required as parameter or `CHATLAS_CHAT_PROVIDER` must be set."
160
+ )
161
+ if the_provider not in _provider_chat_model_map:
162
+ raise ValueError(
163
+ f"Provider name '{the_provider}' is not a known chatlas provider: "
164
+ f"{', '.join(_provider_chat_model_map.keys())}"
165
+ )
166
+
167
+ # `system_prompt` and `turns` always come from `ChatAuto()`
168
+ base_args = {"system_prompt": system_prompt, "turns": turns}
169
+
170
+ if env_model := os.environ.get("CHATLAS_CHAT_MODEL"):
171
+ model = env_model
172
+
173
+ if model:
174
+ base_args["model"] = model
175
+
176
+ env_kwargs = {}
177
+ if env_kwargs_str := os.environ.get("CHATLAS_CHAT_ARGS"):
178
+ env_kwargs = json.loads(env_kwargs_str)
179
+
180
+ kwargs = {**kwargs, **env_kwargs, **base_args}
181
+ kwargs = {k: v for k, v in kwargs.items() if v is not None}
182
+
183
+ return _provider_chat_model_map[the_provider](**kwargs)
@@ -408,7 +408,9 @@ class Chat(Generic[SubmitInputArgsT, CompletionT]):
408
408
  Whether to run the app in a background thread. If `None`, the app will
409
409
  run in a background thread if the current environment is a notebook.
410
410
  echo
411
- Whether to echo text content, all content (i.e., tool calls), or no content. Defaults to `"none"` when `stream=True` and `"text"` when `stream=False`.
411
+ Whether to echo text content, all content (i.e., tool calls), or no
412
+ content. Defaults to `"none"` when `stream=True` and `"text"` when
413
+ `stream=False`.
412
414
  kwargs
413
415
  Additional keyword arguments to pass to the method used for requesting
414
416
  the response.
@@ -1246,7 +1248,7 @@ class Chat(Generic[SubmitInputArgsT, CompletionT]):
1246
1248
  id_: str,
1247
1249
  ) -> ContentToolResult:
1248
1250
  if func is None:
1249
- return ContentToolResult(id_, value=None, error="Unknown tool")
1251
+ return ContentToolResult(id=id_, value=None, error="Unknown tool")
1250
1252
 
1251
1253
  name = func.__name__
1252
1254
 
@@ -1256,10 +1258,10 @@ class Chat(Generic[SubmitInputArgsT, CompletionT]):
1256
1258
  else:
1257
1259
  result = func(arguments)
1258
1260
 
1259
- return ContentToolResult(id_, value=result, error=None, name=name)
1261
+ return ContentToolResult(id=id_, value=result, error=None, name=name)
1260
1262
  except Exception as e:
1261
1263
  log_tool_error(name, str(arguments), e)
1262
- return ContentToolResult(id_, value=None, error=str(e), name=name)
1264
+ return ContentToolResult(id=id_, value=None, error=str(e), name=name)
1263
1265
 
1264
1266
  @staticmethod
1265
1267
  async def _invoke_tool_async(
@@ -1268,7 +1270,7 @@ class Chat(Generic[SubmitInputArgsT, CompletionT]):
1268
1270
  id_: str,
1269
1271
  ) -> ContentToolResult:
1270
1272
  if func is None:
1271
- return ContentToolResult(id_, value=None, error="Unknown tool")
1273
+ return ContentToolResult(id=id_, value=None, error="Unknown tool")
1272
1274
 
1273
1275
  name = func.__name__
1274
1276
 
@@ -1278,10 +1280,10 @@ class Chat(Generic[SubmitInputArgsT, CompletionT]):
1278
1280
  else:
1279
1281
  result = await func(arguments)
1280
1282
 
1281
- return ContentToolResult(id_, value=result, error=None, name=name)
1283
+ return ContentToolResult(id=id_, value=result, error=None, name=name)
1282
1284
  except Exception as e:
1283
1285
  log_tool_error(func.__name__, str(arguments), e)
1284
- return ContentToolResult(id_, value=None, error=str(e), name=name)
1286
+ return ContentToolResult(id=id_, value=None, error=str(e), name=name)
1285
1287
 
1286
1288
  def _markdown_display(
1287
1289
  self, echo: Literal["text", "all", "none"]