chatlas 0.13.1__py3-none-any.whl → 0.13.2__py3-none-any.whl

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.

chatlas/_content.py CHANGED
@@ -1,7 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import inspect
4
+ import warnings
3
5
  from pprint import pformat
4
- from typing import TYPE_CHECKING, Any, Literal, Optional, Union
6
+ from typing import TYPE_CHECKING, Any, Literal, Optional, Union, cast
5
7
 
6
8
  import orjson
7
9
  from pydantic import BaseModel, ConfigDict
@@ -465,8 +467,36 @@ class ContentToolResult(Content):
465
467
 
466
468
  @staticmethod
467
469
  def _to_json(value: Any) -> object:
470
+ if hasattr(value, "to_pandas") and callable(value.to_pandas):
471
+ # Many (most?) df libs (polars, pyarrow, ...) have a .to_pandas()
472
+ # method, and pandas has a .to_json() method
473
+ value = value.to_pandas()
474
+
468
475
  if hasattr(value, "to_json") and callable(value.to_json):
469
- return value.to_json()
476
+ # pandas defaults to "columns", which is not ideal for LLMs
477
+ # https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_json.html
478
+ sig = inspect.signature(value.to_json)
479
+ if "orient" in list(sig.parameters.keys()):
480
+ return value.to_json(orient="records")
481
+ else:
482
+ return value.to_json()
483
+
484
+ # Support for df libs (beyond those with a .to_pandas() method)
485
+ if hasattr(value, "__narwhals_dataframe__"):
486
+ try:
487
+ import narwhals
488
+
489
+ val = cast(narwhals.DataFrame, narwhals.from_native(value))
490
+ return val.to_pandas().to_json(orient="records")
491
+ except ImportError:
492
+ warnings.warn(
493
+ f"Tool result object of type {type(value)} appears to be a "
494
+ "narwhals-compatible DataFrame. If you run into issues with "
495
+ "the LLM not understanding this value, try installing narwhals: "
496
+ "`pip install narwhals`.",
497
+ ImportWarning,
498
+ stacklevel=2,
499
+ )
470
500
 
471
501
  if hasattr(value, "to_dict") and callable(value.to_dict):
472
502
  value = value.to_dict()
@@ -106,7 +106,13 @@ class DatabricksProvider(OpenAIProvider):
106
106
  import httpx
107
107
  from openai import AsyncOpenAI
108
108
 
109
- super().__init__(name=name, model=model)
109
+ super().__init__(
110
+ name=name,
111
+ model=model,
112
+ # The OpenAI() constructor will fail if no API key is present.
113
+ # However, a dummy value is fine -- WorkspaceClient() handles the auth.
114
+ api_key="not-used",
115
+ )
110
116
 
111
117
  self._seed = None
112
118
 
@@ -884,7 +884,13 @@ class OpenAIAzureProvider(OpenAIProvider):
884
884
  model: Optional[str] = "UnusedValue",
885
885
  kwargs: Optional["ChatAzureClientArgs"] = None,
886
886
  ):
887
- super().__init__(name=name, model=deployment_id)
887
+ super().__init__(
888
+ name=name,
889
+ model=deployment_id,
890
+ # The OpenAI() constructor will fail if no API key is present.
891
+ # However, a dummy value is fine -- AzureOpenAI() handles the auth.
892
+ api_key=api_key or "not-used",
893
+ )
888
894
 
889
895
  self._seed = seed
890
896
 
chatlas/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.13.1'
32
- __version_tuple__ = version_tuple = (0, 13, 1)
31
+ __version__ = version = '0.13.2'
32
+ __version_tuple__ = version_tuple = (0, 13, 2)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -3,7 +3,7 @@
3
3
  # ---------------------------------------------------------
4
4
 
5
5
 
6
- from typing import Mapping, Optional, TypedDict, Union
6
+ from typing import Mapping, Optional, TypedDict
7
7
 
8
8
  import anthropic
9
9
  import httpx
@@ -13,7 +13,7 @@ class ChatClientArgs(TypedDict, total=False):
13
13
  api_key: str | None
14
14
  auth_token: str | None
15
15
  base_url: str | httpx.URL | None
16
- timeout: Union[float, anthropic.Timeout, None, anthropic.NotGiven]
16
+ timeout: float | anthropic.Timeout | None | anthropic.NotGiven
17
17
  max_retries: int
18
18
  default_headers: Optional[Mapping[str, str]]
19
19
  default_query: Optional[Mapping[str, object]]
@@ -47,26 +47,24 @@ class SubmitInputArgs(TypedDict, total=False):
47
47
  ],
48
48
  str,
49
49
  ]
50
- service_tier: Union[Literal["auto", "standard_only"], anthropic.NotGiven]
51
- stop_sequences: Union[Sequence[str], anthropic.NotGiven]
52
- stream: Union[Literal[False], Literal[True], anthropic.NotGiven]
50
+ service_tier: Union[Literal["auto", "standard_only"], anthropic.Omit]
51
+ stop_sequences: Union[Sequence[str], anthropic.Omit]
52
+ stream: Union[Literal[False], Literal[True], anthropic.Omit]
53
53
  system: Union[
54
- str,
55
- Iterable[anthropic.types.text_block_param.TextBlockParam],
56
- anthropic.NotGiven,
54
+ str, Iterable[anthropic.types.text_block_param.TextBlockParam], anthropic.Omit
57
55
  ]
58
- temperature: float | anthropic.NotGiven
56
+ temperature: float | anthropic.Omit
59
57
  thinking: Union[
60
58
  anthropic.types.thinking_config_enabled_param.ThinkingConfigEnabledParam,
61
59
  anthropic.types.thinking_config_disabled_param.ThinkingConfigDisabledParam,
62
- anthropic.NotGiven,
60
+ anthropic.Omit,
63
61
  ]
64
62
  tool_choice: Union[
65
63
  anthropic.types.tool_choice_auto_param.ToolChoiceAutoParam,
66
64
  anthropic.types.tool_choice_any_param.ToolChoiceAnyParam,
67
65
  anthropic.types.tool_choice_tool_param.ToolChoiceToolParam,
68
66
  anthropic.types.tool_choice_none_param.ToolChoiceNoneParam,
69
- anthropic.NotGiven,
67
+ anthropic.Omit,
70
68
  ]
71
69
  tools: Union[
72
70
  Iterable[
@@ -79,10 +77,10 @@ class SubmitInputArgs(TypedDict, total=False):
79
77
  anthropic.types.web_search_tool_20250305_param.WebSearchTool20250305Param,
80
78
  ]
81
79
  ],
82
- anthropic.NotGiven,
80
+ anthropic.Omit,
83
81
  ]
84
- top_k: int | anthropic.NotGiven
85
- top_p: float | anthropic.NotGiven
82
+ top_k: int | anthropic.Omit
83
+ top_p: float | anthropic.Omit
86
84
  extra_headers: Optional[Mapping[str, Union[str, anthropic.Omit]]]
87
85
  extra_query: Optional[Mapping[str, object]]
88
86
  extra_body: object | None
@@ -16,7 +16,7 @@ class ChatClientArgs(TypedDict, total=False):
16
16
  webhook_secret: str | None
17
17
  base_url: str | httpx.URL | None
18
18
  websocket_base_url: str | httpx.URL | None
19
- timeout: Union[float, openai.Timeout, None, openai.NotGiven]
19
+ timeout: float | openai.Timeout | None | openai.NotGiven
20
20
  max_retries: int
21
21
  default_headers: Optional[Mapping[str, str]]
22
22
  default_query: Optional[Mapping[str, object]]
@@ -108,61 +108,61 @@ class SubmitInputArgs(TypedDict, total=False):
108
108
  audio: Union[
109
109
  openai.types.chat.chat_completion_audio_param.ChatCompletionAudioParam,
110
110
  None,
111
- openai.NotGiven,
111
+ openai.Omit,
112
112
  ]
113
- frequency_penalty: Union[float, None, openai.NotGiven]
113
+ frequency_penalty: Union[float, None, openai.Omit]
114
114
  function_call: Union[
115
115
  Literal["none", "auto"],
116
116
  openai.types.chat.chat_completion_function_call_option_param.ChatCompletionFunctionCallOptionParam,
117
- openai.NotGiven,
117
+ openai.Omit,
118
118
  ]
119
119
  functions: Union[
120
- Iterable[openai.types.chat.completion_create_params.Function], openai.NotGiven
120
+ Iterable[openai.types.chat.completion_create_params.Function], openai.Omit
121
121
  ]
122
- logit_bias: Union[dict[str, int], None, openai.NotGiven]
123
- logprobs: Union[bool, None, openai.NotGiven]
124
- max_completion_tokens: Union[int, None, openai.NotGiven]
125
- max_tokens: Union[int, None, openai.NotGiven]
126
- metadata: Union[dict[str, str], None, openai.NotGiven]
127
- modalities: Union[list[Literal["text", "audio"]], None, openai.NotGiven]
128
- n: Union[int, None, openai.NotGiven]
129
- parallel_tool_calls: bool | openai.NotGiven
122
+ logit_bias: Union[dict[str, int], None, openai.Omit]
123
+ logprobs: Union[bool, None, openai.Omit]
124
+ max_completion_tokens: Union[int, None, openai.Omit]
125
+ max_tokens: Union[int, None, openai.Omit]
126
+ metadata: Union[dict[str, str], None, openai.Omit]
127
+ modalities: Union[list[Literal["text", "audio"]], None, openai.Omit]
128
+ n: Union[int, None, openai.Omit]
129
+ parallel_tool_calls: bool | openai.Omit
130
130
  prediction: Union[
131
131
  openai.types.chat.chat_completion_prediction_content_param.ChatCompletionPredictionContentParam,
132
132
  None,
133
- openai.NotGiven,
133
+ openai.Omit,
134
134
  ]
135
- presence_penalty: Union[float, None, openai.NotGiven]
136
- prompt_cache_key: str | openai.NotGiven
135
+ presence_penalty: Union[float, None, openai.Omit]
136
+ prompt_cache_key: str | openai.Omit
137
137
  reasoning_effort: Union[
138
- Literal["minimal", "low", "medium", "high"], None, openai.NotGiven
138
+ Literal["minimal", "low", "medium", "high"], None, openai.Omit
139
139
  ]
140
140
  response_format: Union[
141
141
  openai.types.shared_params.response_format_text.ResponseFormatText,
142
142
  openai.types.shared_params.response_format_json_schema.ResponseFormatJSONSchema,
143
143
  openai.types.shared_params.response_format_json_object.ResponseFormatJSONObject,
144
- openai.NotGiven,
144
+ openai.Omit,
145
145
  ]
146
- safety_identifier: str | openai.NotGiven
147
- seed: Union[int, None, openai.NotGiven]
146
+ safety_identifier: str | openai.Omit
147
+ seed: Union[int, None, openai.Omit]
148
148
  service_tier: Union[
149
- Literal["auto", "default", "flex", "scale", "priority"], None, openai.NotGiven
149
+ Literal["auto", "default", "flex", "scale", "priority"], None, openai.Omit
150
150
  ]
151
- stop: Union[str, None, Sequence[str], openai.NotGiven]
152
- store: Union[bool, None, openai.NotGiven]
153
- stream: Union[Literal[False], None, Literal[True], openai.NotGiven]
151
+ stop: Union[str, None, Sequence[str], openai.Omit]
152
+ store: Union[bool, None, openai.Omit]
153
+ stream: Union[Literal[False], None, Literal[True], openai.Omit]
154
154
  stream_options: Union[
155
155
  openai.types.chat.chat_completion_stream_options_param.ChatCompletionStreamOptionsParam,
156
156
  None,
157
- openai.NotGiven,
157
+ openai.Omit,
158
158
  ]
159
- temperature: Union[float, None, openai.NotGiven]
159
+ temperature: Union[float, None, openai.Omit]
160
160
  tool_choice: Union[
161
161
  Literal["none", "auto", "required"],
162
162
  openai.types.chat.chat_completion_allowed_tool_choice_param.ChatCompletionAllowedToolChoiceParam,
163
163
  openai.types.chat.chat_completion_named_tool_choice_param.ChatCompletionNamedToolChoiceParam,
164
164
  openai.types.chat.chat_completion_named_tool_choice_custom_param.ChatCompletionNamedToolChoiceCustomParam,
165
- openai.NotGiven,
165
+ openai.Omit,
166
166
  ]
167
167
  tools: Union[
168
168
  Iterable[
@@ -171,14 +171,14 @@ class SubmitInputArgs(TypedDict, total=False):
171
171
  openai.types.chat.chat_completion_custom_tool_param.ChatCompletionCustomToolParam,
172
172
  ]
173
173
  ],
174
- openai.NotGiven,
174
+ openai.Omit,
175
175
  ]
176
- top_logprobs: Union[int, None, openai.NotGiven]
177
- top_p: Union[float, None, openai.NotGiven]
178
- user: str | openai.NotGiven
179
- verbosity: Union[Literal["low", "medium", "high"], None, openai.NotGiven]
176
+ top_logprobs: Union[int, None, openai.Omit]
177
+ top_p: Union[float, None, openai.Omit]
178
+ user: str | openai.Omit
179
+ verbosity: Union[Literal["low", "medium", "high"], None, openai.Omit]
180
180
  web_search_options: (
181
- openai.types.chat.completion_create_params.WebSearchOptions | openai.NotGiven
181
+ openai.types.chat.completion_create_params.WebSearchOptions | openai.Omit
182
182
  )
183
183
  extra_headers: Optional[Mapping[str, Union[str, openai.Omit]]]
184
184
  extra_query: Optional[Mapping[str, object]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chatlas
3
- Version: 0.13.1
3
+ Version: 0.13.2
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
@@ -38,9 +38,12 @@ Requires-Dist: databricks-sdk; extra == 'dev'
38
38
  Requires-Dist: google-genai>=1.14.0; extra == 'dev'
39
39
  Requires-Dist: htmltools; extra == 'dev'
40
40
  Requires-Dist: matplotlib; extra == 'dev'
41
+ Requires-Dist: narwhals; extra == 'dev'
41
42
  Requires-Dist: numpy>1.24.4; extra == 'dev'
42
43
  Requires-Dist: openai; extra == 'dev'
44
+ Requires-Dist: pandas; extra == 'dev'
43
45
  Requires-Dist: pillow; extra == 'dev'
46
+ Requires-Dist: polars; extra == 'dev'
44
47
  Requires-Dist: python-dotenv; extra == 'dev'
45
48
  Requires-Dist: ruff>=0.6.5; extra == 'dev'
46
49
  Requires-Dist: shiny; extra == 'dev'
@@ -4,7 +4,7 @@ chatlas/_batch_chat.py,sha256=1KkHENB-l7VmhCizhdvbJO5WQmRntQS6EvcSJ6VLgvM,5546
4
4
  chatlas/_batch_job.py,sha256=2__JIOo_JpcQyAAzO07r6eS4urpAxEc9m7_zsjFieQw,7359
5
5
  chatlas/_callbacks.py,sha256=3RpPaOQonTqScjXbaShgKJ1Rc-YxzWerxKRBjVssFnc,1838
6
6
  chatlas/_chat.py,sha256=oESXNVzDCJ1DpV_fBRgwK6N_fs_EoJGrlez5dJjqx5c,90664
7
- chatlas/_content.py,sha256=BdJQ5G5onT9Cf1tNFeXsCWWTD2zSIjWz50FYIk6_DDI,22767
7
+ chatlas/_content.py,sha256=7uRVjGupv-XY6GFmV8455nJt-GuL5F_0YR3Fr1QLntw,24156
8
8
  chatlas/_content_image.py,sha256=EUK6wAint-JatLsiwvaPDu4D3W-NcIsDCkzABkXgfDg,8304
9
9
  chatlas/_content_pdf.py,sha256=cffeuJxzhUDukQ-Srkmpy62M8X12skYpU_FVq-Wvya4,2420
10
10
  chatlas/_display.py,sha256=wyQzSc6z1VqrJfkTLkw1wQcti9s1Pr4qT8UxFJESn4U,4664
@@ -16,7 +16,7 @@ chatlas/_merge.py,sha256=SGj_BetgA7gaOqSBKOhYmW3CYeQKTEehFrXvx3y4OYE,3924
16
16
  chatlas/_provider.py,sha256=-5Oyq8tehHJtbBWQUyFUvdqTqZNUcOq2pO5qfAw5oQo,9057
17
17
  chatlas/_provider_anthropic.py,sha256=sPPEaDObGuY7JDqU533wlUDA-HaX3sumYWaD3kdG4nE,30964
18
18
  chatlas/_provider_cloudflare.py,sha256=vFbqgQPmosopJa9qsVxTkjPn4vYC_wOlgqa6_QmwTho,5227
19
- chatlas/_provider_databricks.py,sha256=JIOTm0HMe0qVAt8eS0WgGKugBwBdmL80JHLFH59ongU,4850
19
+ chatlas/_provider_databricks.py,sha256=fNLhpS6tF6Uhqyhhfo2YWLpiAxfa-3gLFytEnKVFqVg,5076
20
20
  chatlas/_provider_deepseek.py,sha256=6nPtPSo-Po6sD4i8PZJHuI5T2oATpLi5djXFGdlserk,4906
21
21
  chatlas/_provider_github.py,sha256=5h7xwgUB0UdFpqr3UmUuFcC9hfn6kJvZDab0uAURIek,5642
22
22
  chatlas/_provider_google.py,sha256=0vAFSSk8SVBEtaDmy7Tl0XlHDqR4qwxWJR8HeSgh79E,21060
@@ -24,7 +24,7 @@ chatlas/_provider_groq.py,sha256=XB2JDyuF95CcSbNkgk7JHcuy9KCW7hxTVaONDSjK8U8,367
24
24
  chatlas/_provider_huggingface.py,sha256=feJ416X0UdtyoeHZbkgolFf62D7zxNwM7i_X3NYsQQw,4669
25
25
  chatlas/_provider_mistral.py,sha256=-p4rut0KCn-PrwnOlvr6lK8-K-OXvc5H9vTX-rCzUkk,5309
26
26
  chatlas/_provider_ollama.py,sha256=jFAu4v0NLUwdG_W_nKagBHOah0VKl_auTsgcYinP9rI,4119
27
- chatlas/_provider_openai.py,sha256=f8ijdXMMHy17VcuA2ImMpaYvaiKjHzcnTdR8LH1xE40,30654
27
+ chatlas/_provider_openai.py,sha256=Uo5EKOoCJHedSdzvkaDzAl0RFrwFQwqoMS29BjH-ejU,30887
28
28
  chatlas/_provider_openrouter.py,sha256=9sCXvROVIiUdwfEbkVA-15_kc6ouFUP2uV2MmUe2rFk,4385
29
29
  chatlas/_provider_perplexity.py,sha256=5q_LsUCJQ5w-jRveLDMPvZTX-GU2TVURp65mUMyDh10,4248
30
30
  chatlas/_provider_portkey.py,sha256=6wKrLZmKVxOqyO6P3HBgWqPe7y1N8une_1wp0aJq7pU,4087
@@ -35,22 +35,22 @@ chatlas/_tools.py,sha256=8rhGOsEviBJXk5Qb-a1RRb_C-DE2T3DOeN6IhblkxqI,12408
35
35
  chatlas/_turn.py,sha256=yK7alUxeP8d2iBc7amyz20BtEqcpvX6BCwWZsnlQ5R4,4515
36
36
  chatlas/_typing_extensions.py,sha256=BXmbhywjm5ssmyVLGwyP_5TWZMAobzrrgZLYkB6_etE,1076
37
37
  chatlas/_utils.py,sha256=Kku2fa1mvTYCr5D28VxE6-fwfy2e2doCi-eKQkLEg4Y,4686
38
- chatlas/_version.py,sha256=RBWKvLuPH5uJN_RJXTOaV5SvvBYz1PUZvU4D8m3gAvo,706
38
+ chatlas/_version.py,sha256=XZecU3ohLLhnQNT8_JmdvW2idqqOh08RIDcm2qzc5t8,706
39
39
  chatlas/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
40
  chatlas/data/prices.json,sha256=X6qALp-dWc4nfus9lIqHoKzk3PZDPHTLoxxcN2m6fXc,62645
41
41
  chatlas/types/__init__.py,sha256=1n0xrJ7TRIKsZ2z06FLFgGqfKMFtXSIxxPvJ2j0hvPw,850
42
42
  chatlas/types/anthropic/__init__.py,sha256=OwubA-DPHYpYo0XyRyAFwftOI0mOxtHzAyhUSLcDx54,417
43
- chatlas/types/anthropic/_client.py,sha256=t_tnOzzsW1xWNADkNoAuZJYoE9QJ8ie7DQNnFO1pvoM,697
43
+ chatlas/types/anthropic/_client.py,sha256=jOWBeabk_-XVrWHqj1hkiJ7o8Qj1A5QJC6vG_Mz86oc,686
44
44
  chatlas/types/anthropic/_client_bedrock.py,sha256=2J6U1QcSx1KwiiHfXs3i4YEXDXw11sp-x3iLOuESrgQ,792
45
- chatlas/types/anthropic/_submit.py,sha256=X7ER31k7bTZGJ9X9u8Mx-X4enJC13W0VQzt8Wz-mLeQ,3675
45
+ chatlas/types/anthropic/_submit.py,sha256=blwmeJU9iP-YdAwZPG6mrBVkf-3Epq7uSm5VRJcBjP4,3618
46
46
  chatlas/types/google/__init__.py,sha256=ZJhi8Kwvio2zp8T1TQqmvdHqkS-Khb6BGESPjREADgo,337
47
47
  chatlas/types/google/_client.py,sha256=t7aKbxYq_xOA1Z3RnWcjewifdQFSHi7vKEj6MyKMCJk,729
48
48
  chatlas/types/google/_submit.py,sha256=19Ji4fAo1lTCbNSpR6Yi0i64RJwMGBdiZKQcnoDNRwY,1796
49
49
  chatlas/types/openai/__init__.py,sha256=Q2RAr1bSH1nHsxICK05nAmKmxdhKmhbBkWD_XHiVSrI,411
50
- chatlas/types/openai/_client.py,sha256=mAoQftcJIp0ssIhS8q3TIW9u6zTRNtYDmpZJO8L0mC0,849
50
+ chatlas/types/openai/_client.py,sha256=3uKLdhRY1BnyX3dhCShv1eYVXtpABZwbpHbRb6ZxMgk,845
51
51
  chatlas/types/openai/_client_azure.py,sha256=Tf_PFRl0QAj4Nk5CD0ZNIO-SRsT39bVkEJlUTry1fb8,960
52
- chatlas/types/openai/_submit.py,sha256=EDtIUFcNIJ5QAt0wVyBXvUshK8FA9e86wcZDQ_HUOYs,7829
53
- chatlas-0.13.1.dist-info/METADATA,sha256=gG-XEXaUc9LFlqoyqHa5nNzH_Dz-QHeL6HqxECWHAgM,5635
54
- chatlas-0.13.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
55
- chatlas-0.13.1.dist-info/licenses/LICENSE,sha256=zyuGzPOC7CcbOaBHsQ3UEyKYRO56KDUkor0OA4LqqDg,1081
56
- chatlas-0.13.1.dist-info/RECORD,,
52
+ chatlas/types/openai/_submit.py,sha256=0e6YAg-99y0QH1VmkaprCUrvW9wFH5OZT0TrTK7w4_w,7701
53
+ chatlas-0.13.2.dist-info/METADATA,sha256=kpIHWgbil0ST2s_YUirwiAHxQx4bWiWYsTHXGpgRMoM,5751
54
+ chatlas-0.13.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
55
+ chatlas-0.13.2.dist-info/licenses/LICENSE,sha256=zyuGzPOC7CcbOaBHsQ3UEyKYRO56KDUkor0OA4LqqDg,1081
56
+ chatlas-0.13.2.dist-info/RECORD,,