chatlas 0.2.0__tar.gz → 0.4.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 (169) hide show
  1. {chatlas-0.2.0 → chatlas-0.4.0}/.github/workflows/check-update-types.yml +5 -0
  2. {chatlas-0.2.0 → chatlas-0.4.0}/.github/workflows/release.yml +1 -4
  3. {chatlas-0.2.0 → chatlas-0.4.0}/.github/workflows/test.yml +1 -0
  4. chatlas-0.4.0/CHANGELOG.md +43 -0
  5. {chatlas-0.2.0 → chatlas-0.4.0}/PKG-INFO +25 -11
  6. {chatlas-0.2.0 → chatlas-0.4.0}/README.md +19 -8
  7. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/__init__.py +2 -1
  8. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_anthropic.py +104 -6
  9. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_chat.py +246 -24
  10. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_content.py +20 -7
  11. chatlas-0.4.0/chatlas/_google.py +607 -0
  12. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_merge.py +1 -1
  13. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_ollama.py +8 -0
  14. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_openai.py +64 -7
  15. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_provider.py +16 -8
  16. chatlas-0.4.0/chatlas/py.typed +0 -0
  17. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/__init__.py +5 -1
  18. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/anthropic/_client.py +0 -8
  19. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/anthropic/_submit.py +2 -3
  20. chatlas-0.4.0/chatlas/types/google/_client.py +22 -0
  21. chatlas-0.4.0/chatlas/types/google/_submit.py +66 -0
  22. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/openai/_client.py +1 -0
  23. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/openai/_client_azure.py +1 -0
  24. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/openai/_submit.py +10 -2
  25. {chatlas-0.2.0 → chatlas-0.4.0}/docs/_quarto.yml +22 -3
  26. {chatlas-0.2.0 → chatlas-0.4.0}/docs/_sidebar.yml +5 -0
  27. {chatlas-0.2.0 → chatlas-0.4.0}/docs/get-started.qmd +2 -2
  28. chatlas-0.4.0/docs/images/logo.png +0 -0
  29. chatlas-0.4.0/docs/images/posit-logo.png +0 -0
  30. {chatlas-0.2.0 → chatlas-0.4.0}/docs/index.py +5 -0
  31. {chatlas-0.2.0 → chatlas-0.4.0}/docs/prompt-design.qmd +10 -10
  32. chatlas-0.4.0/docs/rag.qmd +78 -0
  33. chatlas-0.4.0/docs/reference/Chat.qmd +500 -0
  34. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatAnthropic.qmd +6 -6
  35. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatAzureOpenAI.qmd +8 -8
  36. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatBedrockAnthropic.qmd +58 -10
  37. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatGithub.qmd +7 -7
  38. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatGoogle.qmd +8 -12
  39. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatGroq.qmd +7 -7
  40. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatOllama.qmd +21 -15
  41. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatOpenAI.qmd +7 -7
  42. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/ChatPerplexity.qmd +7 -7
  43. chatlas-0.4.0/docs/reference/ChatVertex.qmd +62 -0
  44. chatlas-0.4.0/docs/reference/Turn.qmd +48 -0
  45. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/content_image_file.qmd +6 -6
  46. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/index.qmd +17 -7
  47. chatlas-0.4.0/docs/reference/interpolate.qmd +37 -0
  48. chatlas-0.4.0/docs/reference/interpolate_file.qmd +39 -0
  49. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.ChatResponse.qmd +2 -13
  50. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.ChatResponseAsync.qmd +2 -11
  51. chatlas-0.4.0/docs/reference/types.ContentImage.qmd +11 -0
  52. chatlas-0.4.0/docs/reference/types.ContentImageInline.qmd +18 -0
  53. chatlas-0.4.0/docs/reference/types.ContentImageRemote.qmd +17 -0
  54. chatlas-0.4.0/docs/reference/types.ContentJson.qmd +16 -0
  55. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.ContentText.qmd +1 -0
  56. chatlas-0.4.0/docs/reference/types.ContentToolRequest.qmd +19 -0
  57. chatlas-0.4.0/docs/reference/types.ContentToolResult.qmd +20 -0
  58. {chatlas-0.2.0 → chatlas-0.4.0}/docs/web-apps.qmd +7 -7
  59. {chatlas-0.2.0 → chatlas-0.4.0}/pyproject.toml +5 -1
  60. {chatlas-0.2.0 → chatlas-0.4.0}/scripts/_generate_google_types.py +6 -14
  61. {chatlas-0.2.0 → chatlas-0.4.0}/tests/__snapshots__/test_chat.ambr +0 -2
  62. {chatlas-0.2.0 → chatlas-0.4.0}/tests/conftest.py +23 -3
  63. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_chat.py +1 -2
  64. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_content_tools.py +1 -0
  65. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_provider_anthropic.py +6 -1
  66. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_provider_google.py +4 -4
  67. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_provider_openai.py +5 -1
  68. chatlas-0.4.0/tests/test_tokens.py +72 -0
  69. chatlas-0.2.0/CHANGELOG.md +0 -12
  70. chatlas-0.2.0/chatlas/_google.py +0 -456
  71. chatlas-0.2.0/chatlas/types/google/_client.py +0 -101
  72. chatlas-0.2.0/chatlas/types/google/_submit.py +0 -113
  73. chatlas-0.2.0/docs/reference/Chat.qmd +0 -296
  74. chatlas-0.2.0/docs/reference/Turn.qmd +0 -47
  75. chatlas-0.2.0/docs/reference/types.ContentImage.qmd +0 -6
  76. chatlas-0.2.0/docs/reference/types.ContentImageInline.qmd +0 -6
  77. chatlas-0.2.0/docs/reference/types.ContentImageRemote.qmd +0 -6
  78. chatlas-0.2.0/docs/reference/types.ContentJson.qmd +0 -6
  79. chatlas-0.2.0/docs/reference/types.ContentToolRequest.qmd +0 -6
  80. chatlas-0.2.0/docs/reference/types.ContentToolResult.qmd +0 -6
  81. chatlas-0.2.0/tests/test_tokens.py +0 -34
  82. {chatlas-0.2.0 → chatlas-0.4.0}/.github/workflows/docs-publish.yml +0 -0
  83. {chatlas-0.2.0 → chatlas-0.4.0}/.gitignore +0 -0
  84. {chatlas-0.2.0 → chatlas-0.4.0}/.vscode/extensions.json +0 -0
  85. {chatlas-0.2.0 → chatlas-0.4.0}/.vscode/settings.json +0 -0
  86. {chatlas-0.2.0 → chatlas-0.4.0}/Makefile +0 -0
  87. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_content_image.py +0 -0
  88. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_display.py +0 -0
  89. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_github.py +0 -0
  90. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_groq.py +0 -0
  91. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_interpolate.py +0 -0
  92. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_logging.py +0 -0
  93. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_perplexity.py +0 -0
  94. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_tokens.py +0 -0
  95. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_tokens_old.py +0 -0
  96. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_tools.py +0 -0
  97. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_turn.py +0 -0
  98. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_typing_extensions.py +0 -0
  99. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/_utils.py +0 -0
  100. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/anthropic/__init__.py +0 -0
  101. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/anthropic/_client_bedrock.py +0 -0
  102. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/google/__init__.py +0 -0
  103. {chatlas-0.2.0 → chatlas-0.4.0}/chatlas/types/openai/__init__.py +0 -0
  104. {chatlas-0.2.0 → chatlas-0.4.0}/docs/.gitignore +0 -0
  105. {chatlas-0.2.0 → chatlas-0.4.0}/docs/_extensions/machow/interlinks/.gitignore +0 -0
  106. {chatlas-0.2.0 → chatlas-0.4.0}/docs/_extensions/machow/interlinks/_extension.yml +0 -0
  107. {chatlas-0.2.0 → chatlas-0.4.0}/docs/_extensions/machow/interlinks/interlinks.lua +0 -0
  108. {chatlas-0.2.0 → chatlas-0.4.0}/docs/congressional-assets.png +0 -0
  109. {chatlas-0.2.0 → chatlas-0.4.0}/docs/examples/third-party-testing.txt +0 -0
  110. {chatlas-0.2.0 → chatlas-0.4.0}/docs/images/congressional-assets.png +0 -0
  111. {chatlas-0.2.0 → chatlas-0.4.0}/docs/images/tool-calling-right.svg +0 -0
  112. {chatlas-0.2.0 → chatlas-0.4.0}/docs/images/tool-calling-wrong.svg +0 -0
  113. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/favicon/android-chrome-192x192.png +0 -0
  114. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/favicon/android-chrome-512x512.png +0 -0
  115. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/favicon/apple-touch-icon.png +0 -0
  116. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/favicon/favicon-16x16.png +0 -0
  117. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/favicon/favicon-32x32.png +0 -0
  118. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/favicon/favicon.ico +0 -0
  119. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/icon/brand-yml-icon-black.png +0 -0
  120. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/icon/brand-yml-icon-black.svg +0 -0
  121. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/icon/brand-yml-icon-color.png +0 -0
  122. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/icon/brand-yml-icon-color.svg +0 -0
  123. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/icon/brand-yml-icon-white.png +0 -0
  124. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/icon/brand-yml-icon-white.svg +0 -0
  125. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/tall/brand-yml-tall-black.png +0 -0
  126. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/tall/brand-yml-tall-black.svg +0 -0
  127. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/tall/brand-yml-tall-color.png +0 -0
  128. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/tall/brand-yml-tall-color.svg +0 -0
  129. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/tall/brand-yml-tall-white.png +0 -0
  130. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/tall/brand-yml-tall-white.svg +0 -0
  131. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-black.png +0 -0
  132. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-black.svg +0 -0
  133. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-color.png +0 -0
  134. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-color.svg +0 -0
  135. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-large-black.png +0 -0
  136. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-large-color.png +0 -0
  137. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-large-white.png +0 -0
  138. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-white.png +0 -0
  139. {chatlas-0.2.0 → chatlas-0.4.0}/docs/logos/wide/brand-yml-wide-white.svg +0 -0
  140. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/Provider.qmd +0 -0
  141. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/Tool.qmd +0 -0
  142. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/content_image_plot.qmd +0 -0
  143. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/content_image_url.qmd +0 -0
  144. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/image_file.qmd +0 -0
  145. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/image_plot.qmd +0 -0
  146. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/image_url.qmd +0 -0
  147. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/token_usage.qmd +0 -0
  148. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.Content.qmd +0 -0
  149. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.ImageContentTypes.qmd +0 -0
  150. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.MISSING.qmd +0 -0
  151. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.MISSING_TYPE.qmd +0 -0
  152. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.SubmitInputArgsT.qmd +0 -0
  153. {chatlas-0.2.0 → chatlas-0.4.0}/docs/reference/types.TokenUsage.qmd +0 -0
  154. {chatlas-0.2.0 → chatlas-0.4.0}/docs/structured-data.qmd +0 -0
  155. {chatlas-0.2.0 → chatlas-0.4.0}/docs/styles.scss +0 -0
  156. {chatlas-0.2.0 → chatlas-0.4.0}/docs/tool-calling.qmd +0 -0
  157. {chatlas-0.2.0 → chatlas-0.4.0}/pytest.ini +0 -0
  158. {chatlas-0.2.0 → chatlas-0.4.0}/scripts/_generate_anthropic_types.py +0 -0
  159. {chatlas-0.2.0 → chatlas-0.4.0}/scripts/_generate_openai_types.py +0 -0
  160. {chatlas-0.2.0 → chatlas-0.4.0}/scripts/_utils.py +0 -0
  161. {chatlas-0.2.0 → chatlas-0.4.0}/scripts/main.py +0 -0
  162. {chatlas-0.2.0 → chatlas-0.4.0}/tests/__init__.py +0 -0
  163. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_content.py +0 -0
  164. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_content_image.py +0 -0
  165. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_interpolate.py +0 -0
  166. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_provider_azure.py +0 -0
  167. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_provider_bedrock.py +0 -0
  168. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_turns.py +0 -0
  169. {chatlas-0.2.0 → chatlas-0.4.0}/tests/test_utils_merge.py +0 -0
@@ -36,7 +36,12 @@ jobs:
36
36
  # Fail if there are changes under chatlas/types and throw a useful error message
37
37
  - name: Check for changes
38
38
  run: |
39
+ echo "Checking for changes in types..."
40
+ git status chatlas/types
41
+ git diff --stat chatlas/types
39
42
  if [[ -n $(git diff chatlas/types) ]]; then
43
+ echo "Changes detected:"
44
+ git diff chatlas/types
40
45
  echo "::error::Types are out of date. Please run 'make update-types' and commit the changes."
41
46
  exit 1
42
47
  fi
@@ -5,8 +5,7 @@ on:
5
5
  types: [published]
6
6
 
7
7
  env:
8
- UV_VERSION: "0.4.x"
9
- PYTHON_VERSION: 3.13
8
+ PYTHON_VERSION: 3.12
10
9
 
11
10
  jobs:
12
11
  pypi-release:
@@ -27,8 +26,6 @@ jobs:
27
26
 
28
27
  - name: 🚀 Install uv
29
28
  uses: astral-sh/setup-uv@v3
30
- with:
31
- version: ${{ env.UV_VERSION }}
32
29
 
33
30
  - name: 🐍 Set up Python ${{ env.PYTHON_VERSION }}
34
31
  run: uv python install ${{ env.PYTHON_VERSION }}
@@ -50,6 +50,7 @@ jobs:
50
50
  run: make check-tests
51
51
 
52
52
  - name: 📝 Check types
53
+ if: ${{ matrix.config.python-version != '3.9' }}
53
54
  run: make check-types
54
55
 
55
56
  - name: 📐 Check formatting
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ <!--
4
+ All notable changes to this project will be documented in this file.
5
+
6
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
7
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
8
+ -->
9
+
10
+ ## [0.4.0] - 2025-02-19
11
+
12
+ ### New features
13
+
14
+ * Added a `ChatVertex()` class to interact with Google Cloud's Vertex AI. (#50)
15
+ * Added `.app(*, echo=)` support. This allows for chatlas to change the echo behavior when running the Shiny app. (#31)
16
+
17
+ ### Improvements
18
+
19
+ * Migrated `ChatGoogle()`'s underlying python SDK from `google-generative` to `google-genai`. As a result, streaming tools are now working properly. (#50)
20
+
21
+ ### Bug fixes
22
+
23
+ * Fixed a bug where synchronous chat tools would not work properly when used in a `_async()` context. (#56)
24
+ * Fix broken `Chat`'s Shiny app when `.app(*, stream=True)` by using async chat tools. (#31)
25
+ * Update formatting of exported markdown to use `repr()` instead of `str()` when exporting tool call results. (#30)
26
+
27
+ ## [0.3.0] - 2024-12-20
28
+
29
+ ### New features
30
+
31
+ * `Chat`'s `.tokens()` method gains a `values` argument. Set it to `"discrete"` to get a result that can be summed to determine the token cost of submitting the current turns. The default (`"cumulative"`), remains the same (the result can be summed to determine the overall token cost of the conversation).
32
+ * `Chat` gains a `.token_count()` method to help estimate token cost of new input. (#23)
33
+
34
+ ### Bug fixes
35
+
36
+ * `ChatOllama` no longer fails when a `OPENAI_API_KEY` environment variable is not set.
37
+ * `ChatOpenAI` now correctly includes the relevant `detail` on `ContentImageRemote()` input.
38
+ * `ChatGoogle` now correctly logs its `token_usage()`. (#23)
39
+
40
+
41
+ ## [0.2.0] - 2024-12-11
42
+
43
+ First stable release of `chatlas`, see the website to learn more <https://posit-dev.github.io/chatlas/>
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: chatlas
3
- Version: 0.2.0
3
+ Version: 0.4.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
@@ -22,7 +22,7 @@ Requires-Dist: pydantic>=2.0
22
22
  Requires-Dist: rich
23
23
  Provides-Extra: dev
24
24
  Requires-Dist: anthropic[bedrock]; extra == 'dev'
25
- Requires-Dist: google-generativeai>=0.8.3; extra == 'dev'
25
+ Requires-Dist: google-genai>=1.2.0; extra == 'dev'
26
26
  Requires-Dist: matplotlib; extra == 'dev'
27
27
  Requires-Dist: numpy>1.24.4; extra == 'dev'
28
28
  Requires-Dist: openai; extra == 'dev'
@@ -30,15 +30,18 @@ Requires-Dist: pillow; extra == 'dev'
30
30
  Requires-Dist: python-dotenv; extra == 'dev'
31
31
  Requires-Dist: ruff>=0.6.5; extra == 'dev'
32
32
  Requires-Dist: shiny; extra == 'dev'
33
+ Requires-Dist: tiktoken; extra == 'dev'
33
34
  Provides-Extra: docs
34
35
  Requires-Dist: griffe>=1; extra == 'docs'
35
36
  Requires-Dist: ipykernel; extra == 'docs'
36
37
  Requires-Dist: ipywidgets; extra == 'docs'
37
38
  Requires-Dist: nbclient; extra == 'docs'
38
39
  Requires-Dist: nbformat; extra == 'docs'
40
+ Requires-Dist: numpy; extra == 'docs'
39
41
  Requires-Dist: pandas; extra == 'docs'
40
42
  Requires-Dist: pyyaml; extra == 'docs'
41
43
  Requires-Dist: quartodoc>=0.7; extra == 'docs'
44
+ Requires-Dist: sentence-transformers; extra == 'docs'
42
45
  Provides-Extra: test
43
46
  Requires-Dist: pyright>=1.1.379; extra == 'test'
44
47
  Requires-Dist: pytest-asyncio; extra == 'test'
@@ -46,14 +49,24 @@ Requires-Dist: pytest>=8.3.2; extra == 'test'
46
49
  Requires-Dist: syrupy>=4; extra == 'test'
47
50
  Description-Content-Type: text/markdown
48
51
 
49
- # chatlas
52
+ <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>
53
+
54
+
55
+
56
+ <p>
57
+ <!-- badges start -->
58
+ <a href="https://pypi.org/project/chatlas/"><img alt="PyPI" src="https://img.shields.io/pypi/v/chatlas?logo=python&logoColor=white&color=orange"></a>
59
+ <a href="https://choosealicense.com/licenses/mit/"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License"></a>
60
+ <a href="https://github.com/posit-dev/chatlas"><img src="https://github.com/posit-dev/chatlas/actions/workflows/test.yml/badge.svg?branch=main" alt="Python Tests"></a>
61
+ <!-- badges end -->
62
+ </p>
50
63
 
51
64
  chatlas provides a simple and unified interface across large language model (llm) providers in Python.
52
- It abstracts away complexity from common tasks like streaming chat interfaces, tool calling, structured output, and much more.
53
- chatlas helps you prototype faster without painting you into a corner; for example, switching providers is as easy as changing one line of code, but provider specific features are still accessible when needed.
54
- Developer experience is also a key focus of chatlas: typing support, rich console output, and built-in tooling are all included.
65
+ It helps you prototype faster by abstracting away complexity from common tasks like streaming chat interfaces, tool calling, structured output, and much more.
66
+ Switching providers is also as easy as changing one line of code, but you can also reach for provider-specific features when you need them.
67
+ Developer experience is also a key focus of chatlas: typing support, rich console output, and extension points are all included.
55
68
 
56
- (Looking for something similar to chatlas, but in R? Check out [elmer](https://elmer.tidyverse.org/)!)
69
+ (Looking for something similar to chatlas, but in R? Check out [ellmer](https://ellmer.tidyverse.org/)!)
57
70
 
58
71
  ## Install
59
72
 
@@ -85,6 +98,7 @@ It also supports the following enterprise cloud providers:
85
98
 
86
99
  * AWS Bedrock: [`ChatBedrockAnthropic()`](https://posit-dev.github.io/chatlas/reference/ChatBedrockAnthropic.html).
87
100
  * Azure OpenAI: [`ChatAzureOpenAI()`](https://posit-dev.github.io/chatlas/reference/ChatAzureOpenAI.html).
101
+ * Vertex AI: [`ChatVertex()`](https://posit-dev.github.io/chatlas/reference/ChatVertex.html).
88
102
 
89
103
  To use a model provider that isn't listed here, you have two options:
90
104
 
@@ -123,7 +137,7 @@ From a `chat` instance, it's simple to start a web-based or terminal-based chat
123
137
  chat.app()
124
138
  ```
125
139
 
126
- <div style="display:flex;justify-content:center;">
140
+ <div align="center">
127
141
  <img width="500" alt="A web app for chatting with an LLM via chatlas" src="https://github.com/user-attachments/assets/e43f60cb-3686-435a-bd11-8215cb024d2e" class="border rounded">
128
142
  </div>
129
143
 
@@ -279,7 +293,7 @@ asyncio.run(main())
279
293
 
280
294
  `chatlas` has full typing support, meaning that, among other things, autocompletion just works in your favorite editor:
281
295
 
282
- <div style="display:flex;justify-content:center;">
296
+ <div align="center">
283
297
  <img width="500" alt="Autocompleting model options in ChatOpenAI" src="https://github.com/user-attachments/assets/163d6d8a-7d58-422d-b3af-cc9f2adee759" class="rounded">
284
298
  </div>
285
299
 
@@ -299,7 +313,7 @@ This shows important information like tool call results, finish reasons, and mor
299
313
  If the problem isn't self-evident, you can also reach into the `.get_last_turn()`, which contains the full response object, with full details about the completion.
300
314
 
301
315
 
302
- <div style="display:flex;justify-content:center;">
316
+ <div align="center">
303
317
  <img width="500" alt="Turn completion details with typing support" src="https://github.com/user-attachments/assets/eaea338d-e44a-4e23-84a7-2e998d8af3ba" class="rounded">
304
318
  </div>
305
319
 
@@ -1,11 +1,21 @@
1
- # chatlas
1
+ <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>
2
+
3
+
4
+
5
+ <p>
6
+ <!-- badges start -->
7
+ <a href="https://pypi.org/project/chatlas/"><img alt="PyPI" src="https://img.shields.io/pypi/v/chatlas?logo=python&logoColor=white&color=orange"></a>
8
+ <a href="https://choosealicense.com/licenses/mit/"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="MIT License"></a>
9
+ <a href="https://github.com/posit-dev/chatlas"><img src="https://github.com/posit-dev/chatlas/actions/workflows/test.yml/badge.svg?branch=main" alt="Python Tests"></a>
10
+ <!-- badges end -->
11
+ </p>
2
12
 
3
13
  chatlas provides a simple and unified interface across large language model (llm) providers in Python.
4
- It abstracts away complexity from common tasks like streaming chat interfaces, tool calling, structured output, and much more.
5
- chatlas helps you prototype faster without painting you into a corner; for example, switching providers is as easy as changing one line of code, but provider specific features are still accessible when needed.
6
- Developer experience is also a key focus of chatlas: typing support, rich console output, and built-in tooling are all included.
14
+ It helps you prototype faster by abstracting away complexity from common tasks like streaming chat interfaces, tool calling, structured output, and much more.
15
+ Switching providers is also as easy as changing one line of code, but you can also reach for provider-specific features when you need them.
16
+ Developer experience is also a key focus of chatlas: typing support, rich console output, and extension points are all included.
7
17
 
8
- (Looking for something similar to chatlas, but in R? Check out [elmer](https://elmer.tidyverse.org/)!)
18
+ (Looking for something similar to chatlas, but in R? Check out [ellmer](https://ellmer.tidyverse.org/)!)
9
19
 
10
20
  ## Install
11
21
 
@@ -37,6 +47,7 @@ It also supports the following enterprise cloud providers:
37
47
 
38
48
  * AWS Bedrock: [`ChatBedrockAnthropic()`](https://posit-dev.github.io/chatlas/reference/ChatBedrockAnthropic.html).
39
49
  * Azure OpenAI: [`ChatAzureOpenAI()`](https://posit-dev.github.io/chatlas/reference/ChatAzureOpenAI.html).
50
+ * Vertex AI: [`ChatVertex()`](https://posit-dev.github.io/chatlas/reference/ChatVertex.html).
40
51
 
41
52
  To use a model provider that isn't listed here, you have two options:
42
53
 
@@ -75,7 +86,7 @@ From a `chat` instance, it's simple to start a web-based or terminal-based chat
75
86
  chat.app()
76
87
  ```
77
88
 
78
- <div style="display:flex;justify-content:center;">
89
+ <div align="center">
79
90
  <img width="500" alt="A web app for chatting with an LLM via chatlas" src="https://github.com/user-attachments/assets/e43f60cb-3686-435a-bd11-8215cb024d2e" class="border rounded">
80
91
  </div>
81
92
 
@@ -231,7 +242,7 @@ asyncio.run(main())
231
242
 
232
243
  `chatlas` has full typing support, meaning that, among other things, autocompletion just works in your favorite editor:
233
244
 
234
- <div style="display:flex;justify-content:center;">
245
+ <div align="center">
235
246
  <img width="500" alt="Autocompleting model options in ChatOpenAI" src="https://github.com/user-attachments/assets/163d6d8a-7d58-422d-b3af-cc9f2adee759" class="rounded">
236
247
  </div>
237
248
 
@@ -251,7 +262,7 @@ This shows important information like tool call results, finish reasons, and mor
251
262
  If the problem isn't self-evident, you can also reach into the `.get_last_turn()`, which contains the full response object, with full details about the completion.
252
263
 
253
264
 
254
- <div style="display:flex;justify-content:center;">
265
+ <div align="center">
255
266
  <img width="500" alt="Turn completion details with typing support" src="https://github.com/user-attachments/assets/eaea338d-e44a-4e23-84a7-2e998d8af3ba" class="rounded">
256
267
  </div>
257
268
 
@@ -3,7 +3,7 @@ from ._anthropic import ChatAnthropic, ChatBedrockAnthropic
3
3
  from ._chat import Chat
4
4
  from ._content_image import content_image_file, content_image_plot, content_image_url
5
5
  from ._github import ChatGithub
6
- from ._google import ChatGoogle
6
+ from ._google import ChatGoogle, ChatVertex
7
7
  from ._groq import ChatGroq
8
8
  from ._interpolate import interpolate, interpolate_file
9
9
  from ._ollama import ChatOllama
@@ -24,6 +24,7 @@ __all__ = (
24
24
  "ChatOpenAI",
25
25
  "ChatAzureOpenAI",
26
26
  "ChatPerplexity",
27
+ "ChatVertex",
27
28
  "Chat",
28
29
  "content_image_file",
29
30
  "content_image_plot",
@@ -20,7 +20,7 @@ from ._logging import log_model_default
20
20
  from ._provider import Provider
21
21
  from ._tokens import tokens_log
22
22
  from ._tools import Tool, basemodel_to_param_schema
23
- from ._turn import Turn, normalize_turns
23
+ from ._turn import Turn, normalize_turns, user_turn
24
24
 
25
25
  if TYPE_CHECKING:
26
26
  from anthropic.types import (
@@ -311,7 +311,8 @@ class AnthropicProvider(Provider[Message, RawMessageStreamEvent, Message]):
311
311
  if stream:
312
312
  stream = False
313
313
  warnings.warn(
314
- "Anthropic does not support structured data extraction in streaming mode."
314
+ "Anthropic does not support structured data extraction in streaming mode.",
315
+ stacklevel=2,
315
316
  )
316
317
 
317
318
  kwargs_full: "SubmitInputArgs" = {
@@ -371,15 +372,65 @@ class AnthropicProvider(Provider[Message, RawMessageStreamEvent, Message]):
371
372
 
372
373
  return completion
373
374
 
374
- def stream_turn(self, completion, has_data_model, stream) -> Turn:
375
- return self._as_turn(completion, has_data_model)
376
-
377
- async def stream_turn_async(self, completion, has_data_model, stream) -> Turn:
375
+ def stream_turn(self, completion, has_data_model) -> Turn:
378
376
  return self._as_turn(completion, has_data_model)
379
377
 
380
378
  def value_turn(self, completion, has_data_model) -> Turn:
381
379
  return self._as_turn(completion, has_data_model)
382
380
 
381
+ def token_count(
382
+ self,
383
+ *args: Content | str,
384
+ tools: dict[str, Tool],
385
+ data_model: Optional[type[BaseModel]],
386
+ ) -> int:
387
+ kwargs = self._token_count_args(
388
+ *args,
389
+ tools=tools,
390
+ data_model=data_model,
391
+ )
392
+ res = self._client.messages.count_tokens(**kwargs)
393
+ return res.input_tokens
394
+
395
+ async def token_count_async(
396
+ self,
397
+ *args: Content | str,
398
+ tools: dict[str, Tool],
399
+ data_model: Optional[type[BaseModel]],
400
+ ) -> int:
401
+ kwargs = self._token_count_args(
402
+ *args,
403
+ tools=tools,
404
+ data_model=data_model,
405
+ )
406
+ res = await self._async_client.messages.count_tokens(**kwargs)
407
+ return res.input_tokens
408
+
409
+ def _token_count_args(
410
+ self,
411
+ *args: Content | str,
412
+ tools: dict[str, Tool],
413
+ data_model: Optional[type[BaseModel]],
414
+ ) -> dict[str, Any]:
415
+ turn = user_turn(*args)
416
+
417
+ kwargs = self._chat_perform_args(
418
+ stream=False,
419
+ turns=[turn],
420
+ tools=tools,
421
+ data_model=data_model,
422
+ )
423
+
424
+ args_to_keep = [
425
+ "messages",
426
+ "model",
427
+ "system",
428
+ "tools",
429
+ "tool_choice",
430
+ ]
431
+
432
+ return {arg: kwargs[arg] for arg in args_to_keep if arg in kwargs}
433
+
383
434
  def _as_message_params(self, turns: list[Turn]) -> list["MessageParam"]:
384
435
  messages: list["MessageParam"] = []
385
436
  for turn in turns:
@@ -575,6 +626,53 @@ def ChatBedrockAnthropic(
575
626
  Additional arguments to pass to the `anthropic.AnthropicBedrock()`
576
627
  client constructor.
577
628
 
629
+ Troubleshooting
630
+ ---------------
631
+
632
+ If you encounter 400 or 403 errors when trying to use the model, keep the
633
+ following in mind:
634
+
635
+ ::: {.callout-note}
636
+ #### Incorrect model name
637
+
638
+ If the model name is completely incorrect, you'll see an error like
639
+ `Error code: 400 - {'message': 'The provided model identifier is invalid.'}`
640
+
641
+ Make sure the model name is correct and active in the specified region.
642
+ :::
643
+
644
+ ::: {.callout-note}
645
+ #### Models are region specific
646
+
647
+ If you encounter errors similar to `Error code: 403 - {'message': "You don't
648
+ have access to the model with the specified model ID."}`, make sure your
649
+ model is active in the relevant `aws_region`.
650
+
651
+ Keep in mind, if `aws_region` is not specified, and AWS_REGION is not set,
652
+ the region defaults to us-east-1, which may not match to your AWS config's
653
+ default region.
654
+ :::
655
+
656
+ ::: {.callout-note}
657
+ #### Cross region inference ID
658
+
659
+ In some cases, even if you have the right model and the right region, you
660
+ may still encounter an error like `Error code: 400 - {'message':
661
+ 'Invocation of model ID anthropic.claude-3-5-sonnet-20240620-v1:0 with
662
+ on-demand throughput isn't supported. Retry your request with the ID or ARN
663
+ of an inference profile that contains this model.'}`
664
+
665
+ In this case, you'll need to look up the 'cross region inference ID' for
666
+ your model. This might required opening your `aws-console` and navigating to
667
+ the 'Anthropic Bedrock' service page. From there, go to the 'cross region
668
+ inference' tab and copy the relevant ID.
669
+
670
+ For example, if the desired model ID is
671
+ `anthropic.claude-3-5-sonnet-20240620-v1:0`, the cross region ID might look
672
+ something like `us.anthropic.claude-3-5-sonnet-20240620-v1:0`.
673
+ :::
674
+
675
+
578
676
  Returns
579
677
  -------
580
678
  Chat