Jac-Zac commited on
Commit
99c28ab
·
1 Parent(s): 4df7d97

Adding per layer clustering

Browse files
Files changed (9) hide show
  1. app.py +0 -6
  2. pyproject.toml +1 -1
  3. tabs/chat.py +13 -10
  4. tabs/chat_ui.py +8 -2
  5. tabs/compare.py +77 -12
  6. utils/chat.py +13 -3
  7. utils/chat_export.py +2 -2
  8. utils/runtime.py +3 -0
  9. uv.lock +55 -55
app.py CHANGED
@@ -157,12 +157,6 @@ def main() -> None:
157
 
158
  install_catppuccin_theme(st.get_option("theme.base"))
159
 
160
- # Deferred: importing torch is slow; keep it after dotenv load (done at
161
- # module level above) so the Streamlit page config renders immediately.
162
- import torch
163
-
164
- torch.set_grad_enabled(False)
165
-
166
  sidebar = _sidebar_controls()
167
 
168
  if sidebar.active_tab == "Extract":
 
157
 
158
  install_catppuccin_theme(st.get_option("theme.base"))
159
 
 
 
 
 
 
 
160
  sidebar = _sidebar_controls()
161
 
162
  if sidebar.active_tab == "Extract":
pyproject.toml CHANGED
@@ -5,7 +5,7 @@ description = "Streamlit UI for persona-vectors"
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
8
- "persona-vectors>=0.7.2",
9
  "persona-data>=0.4.2",
10
  "datasets>=4.8.5",
11
  "huggingface-hub>=1.14.0",
 
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
8
+ "persona-vectors>=0.7.3",
9
  "persona-data>=0.4.2",
10
  "datasets>=4.8.5",
11
  "huggingface-hub>=1.14.0",
tabs/chat.py CHANGED
@@ -9,8 +9,6 @@ from tabs.chat_ui import (
9
  render_persona_prompt_controls,
10
  render_system_prompt,
11
  )
12
- from tabs.compare_chat import render_compare_mode
13
- from tabs.probe_ui import render_probe_inspector
14
  from utils.chat import (
15
  ChatReply,
16
  build_chat_messages,
@@ -155,6 +153,8 @@ def render_chat_tab(remote: bool, model_name: str, dataset_source: str) -> None:
155
  last_token_contrast_key=_LAST_TOKEN_CONTRAST_KEY,
156
  )
157
  if tools.compare_mode:
 
 
158
  render_compare_mode(
159
  remote,
160
  model_name,
@@ -225,14 +225,17 @@ def render_chat_tab(remote: bool, model_name: str, dataset_source: str) -> None:
225
  ),
226
  )
227
 
228
- render_probe_inspector(
229
- context_key=context_key,
230
- model_name=model_name,
231
- remote=remote,
232
- active_system_prompt=active_system_prompt,
233
- chat_state=chat_state,
234
- enabled=tools.probe_enabled,
235
- )
 
 
 
236
 
237
  render_chat_window(
238
  chat_log=chat_log,
 
9
  render_persona_prompt_controls,
10
  render_system_prompt,
11
  )
 
 
12
  from utils.chat import (
13
  ChatReply,
14
  build_chat_messages,
 
153
  last_token_contrast_key=_LAST_TOKEN_CONTRAST_KEY,
154
  )
155
  if tools.compare_mode:
156
+ from tabs.compare_chat import render_compare_mode
157
+
158
  render_compare_mode(
159
  remote,
160
  model_name,
 
225
  ),
226
  )
227
 
228
+ if tools.probe_enabled:
229
+ from tabs.probe_ui import render_probe_inspector
230
+
231
+ render_probe_inspector(
232
+ context_key=context_key,
233
+ model_name=model_name,
234
+ remote=remote,
235
+ active_system_prompt=active_system_prompt,
236
+ chat_state=chat_state,
237
+ enabled=True,
238
+ )
239
 
240
  render_chat_window(
241
  chat_log=chat_log,
tabs/chat_ui.py CHANGED
@@ -1,11 +1,12 @@
 
 
1
  from collections.abc import Callable
2
  from dataclasses import asdict, dataclass
3
- from typing import Any
4
 
5
  import streamlit as st
6
  from persona_data.synth_persona import PersonaData
7
 
8
- from utils.contrast import TokenContrast, render_contrast_html
9
  from utils.helpers import (
10
  CHAT_PROMPT_MODE_LABEL_TO_KEY,
11
  CHAT_PROMPT_MODE_LABELS,
@@ -14,6 +15,9 @@ from utils.helpers import (
14
  widget_key,
15
  )
16
 
 
 
 
17
  GENERATION_DEFAULTS = {
18
  "max_new_tokens": 256,
19
  "temperature": 1.0,
@@ -326,6 +330,8 @@ def render_chat_message(
326
  contrast: TokenContrast | None = message.get("_contrast") if show_contrast else None
327
  with st.chat_message(message["role"]):
328
  if contrast is not None:
 
 
329
  st.html(render_contrast_html(contrast))
330
  else:
331
  st.markdown(message["content"])
 
1
+ from __future__ import annotations
2
+
3
  from collections.abc import Callable
4
  from dataclasses import asdict, dataclass
5
+ from typing import TYPE_CHECKING, Any
6
 
7
  import streamlit as st
8
  from persona_data.synth_persona import PersonaData
9
 
 
10
  from utils.helpers import (
11
  CHAT_PROMPT_MODE_LABEL_TO_KEY,
12
  CHAT_PROMPT_MODE_LABELS,
 
15
  widget_key,
16
  )
17
 
18
+ if TYPE_CHECKING:
19
+ from utils.contrast import TokenContrast
20
+
21
  GENERATION_DEFAULTS = {
22
  "max_new_tokens": 256,
23
  "temperature": 1.0,
 
330
  contrast: TokenContrast | None = message.get("_contrast") if show_contrast else None
331
  with st.chat_message(message["role"]):
332
  if contrast is not None:
333
+ from utils.contrast import render_contrast_html
334
+
335
  st.html(render_contrast_html(contrast))
336
  else:
337
  st.markdown(message["content"])
tabs/compare.py CHANGED
@@ -72,6 +72,17 @@ _DEFAULT_PERSONA_LIMITS = {
72
  }
73
  _MAX_SIMILARITY_CELLS = 4_000_000
74
  _MAX_PAIR_TRAJECTORY_TRACES = 500
 
 
 
 
 
 
 
 
 
 
 
75
 
76
 
77
  def _is_assistant_persona(persona_id: str, persona_name: str | None = None) -> bool:
@@ -728,21 +739,65 @@ def _render_layered_figure_analysis(
728
  return
729
 
730
  n_clusters = None
 
 
 
 
731
  if figure_kind in {"pca", "umap"}:
732
- use_kmeans = st.toggle(
733
- "Color by K-means clusters",
734
  value=False,
735
- key=widget_key("load", "kmeans_enabled", scope, store_id(store)),
736
- help="Run K-means on persona vectors and color each persona by cluster.",
737
  )
738
- if use_kmeans:
739
- n_clusters = st.slider(
740
- "K (clusters)",
741
- min_value=2,
742
- max_value=min(10, len(persona_ids)),
743
- value=min(3, len(persona_ids)),
744
- key=widget_key("load", "kmeans_k", scope, store_id(store)),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
745
  )
 
746
 
747
  fig_key = widget_key(
748
  "load",
@@ -753,6 +808,10 @@ def _render_layered_figure_analysis(
753
  figure_kind,
754
  str(n_components),
755
  str(n_clusters),
 
 
 
 
756
  variant,
757
  "persona_vector",
758
  persona_key,
@@ -781,8 +840,14 @@ def _render_layered_figure_analysis(
781
  build_kwargs = {}
782
  if figure_kind in {"umap", "pca"}:
783
  build_kwargs["n_components"] = n_components
784
- if n_clusters is not None:
 
785
  build_kwargs["n_clusters"] = n_clusters
 
 
 
 
 
786
  if figure_kind == "similarity" and pair_trajectories:
787
  main_fig, extra_fig = build_similarity_figures(
788
  samples,
 
72
  }
73
  _MAX_SIMILARITY_CELLS = 4_000_000
74
  _MAX_PAIR_TRAJECTORY_TRACES = 500
75
+ _CLUSTER_METHODS = {
76
+ "K-means": "kmeans",
77
+ "Agglomerative": "agglomerative",
78
+ "HDBSCAN": "hdbscan",
79
+ }
80
+ _CLUSTER_MODES = {
81
+ "Mean across layers": "mean_across_layers",
82
+ "First selected layer": "first_layer",
83
+ "Per layer": "per_layer",
84
+ }
85
+ _CLUSTER_LINKAGES = ["ward", "complete", "average", "single"]
86
 
87
 
88
  def _is_assistant_persona(persona_id: str, persona_name: str | None = None) -> bool:
 
739
  return
740
 
741
  n_clusters = None
742
+ cluster_mode = None
743
+ cluster_method = None
744
+ cluster_linkage = None
745
+ min_cluster_size = None
746
  if figure_kind in {"pca", "umap"}:
747
+ use_clusters = st.toggle(
748
+ "Color by clusters",
749
  value=False,
750
+ key=widget_key("load", "clusters_enabled", scope, store_id(store)),
751
+ help="Cluster persona vectors and color points by cluster.",
752
  )
753
+ if use_clusters:
754
+ method_label = st.selectbox(
755
+ "Cluster algorithm",
756
+ options=list(_CLUSTER_METHODS),
757
+ index=0,
758
+ key=widget_key("load", "cluster_method", scope, store_id(store)),
759
+ )
760
+ cluster_method = _CLUSTER_METHODS[method_label]
761
+ if cluster_method in {"kmeans", "agglomerative"}:
762
+ n_clusters = st.slider(
763
+ "K (clusters)",
764
+ min_value=2,
765
+ max_value=min(10, len(persona_ids)),
766
+ value=min(3, len(persona_ids)),
767
+ key=widget_key("load", "cluster_k", scope, store_id(store)),
768
+ )
769
+ if cluster_method == "agglomerative":
770
+ cluster_linkage = st.selectbox(
771
+ "Linkage",
772
+ options=_CLUSTER_LINKAGES,
773
+ index=0,
774
+ key=widget_key("load", "cluster_linkage", scope, store_id(store)),
775
+ )
776
+ if cluster_method == "hdbscan":
777
+ min_cluster_size = st.slider(
778
+ "Minimum cluster size",
779
+ min_value=2,
780
+ max_value=len(persona_ids),
781
+ value=min(5, len(persona_ids)),
782
+ key=widget_key(
783
+ "load",
784
+ "cluster_min_cluster_size",
785
+ scope,
786
+ store_id(store),
787
+ ),
788
+ )
789
+ mode_label = st.selectbox(
790
+ "Cluster fit",
791
+ options=list(_CLUSTER_MODES),
792
+ index=0,
793
+ key=widget_key("load", "cluster_mode", scope, store_id(store)),
794
+ help=(
795
+ "Mean across layers is the previous behavior. First selected "
796
+ "layer keeps one fixed clustering from the first frame. Per layer "
797
+ "recomputes clustering for each animation frame."
798
+ ),
799
  )
800
+ cluster_mode = _CLUSTER_MODES[mode_label]
801
 
802
  fig_key = widget_key(
803
  "load",
 
808
  figure_kind,
809
  str(n_components),
810
  str(n_clusters),
811
+ str(cluster_mode),
812
+ str(cluster_method),
813
+ str(cluster_linkage),
814
+ str(min_cluster_size),
815
  variant,
816
  "persona_vector",
817
  persona_key,
 
840
  build_kwargs = {}
841
  if figure_kind in {"umap", "pca"}:
842
  build_kwargs["n_components"] = n_components
843
+ if cluster_method is not None:
844
+ build_kwargs["cluster_method"] = cluster_method
845
  build_kwargs["n_clusters"] = n_clusters
846
+ build_kwargs["cluster_mode"] = cluster_mode
847
+ if cluster_linkage is not None:
848
+ build_kwargs["cluster_linkage"] = cluster_linkage
849
+ if min_cluster_size is not None:
850
+ build_kwargs["min_cluster_size"] = min_cluster_size
851
  if figure_kind == "similarity" and pair_trajectories:
852
  main_fig, extra_fig = build_similarity_figures(
853
  samples,
utils/chat.py CHANGED
@@ -1,13 +1,17 @@
 
 
1
  import logging
2
  from contextlib import contextmanager, nullcontext
3
  from dataclasses import dataclass
4
- from typing import Literal
5
 
6
- import torch
7
- from nnterp import StandardizedTransformer
8
  from persona_data.prompts import format_messages, format_prompt, normalize_messages
9
  from persona_data.synth_persona import PersonaData
10
 
 
 
 
 
11
  logger = logging.getLogger(__name__)
12
  SystemPromptMode = Literal["empty", "templated", "biography", "custom"]
13
 
@@ -129,6 +133,8 @@ def format_generation_prompt(
129
 
130
  def resolve_saved_tensor(value: object) -> torch.Tensor:
131
  """Resolve an nnsight ``.save()`` proxy (or raw tensor) to a CPU tensor."""
 
 
132
  resolved = value.value if getattr(value, "value", None) is not None else value
133
  if not isinstance(resolved, torch.Tensor):
134
  raise TypeError(f"Trace result did not resolve to a tensor: {type(resolved)!r}")
@@ -154,6 +160,8 @@ def _seeded_rng(seed: int | None):
154
  yield
155
  return
156
 
 
 
157
  cuda_ctx = torch.random.fork_rng(devices=range(torch.cuda.device_count()))
158
  mps_ctx = (
159
  torch.random.fork_rng(devices=range(1), device_type="mps")
@@ -199,6 +207,8 @@ def generate_chat_reply(
199
  ChatReply with generated text and token ids.
200
  """
201
 
 
 
202
  tokenizer = model.tokenizer
203
  prompt, prompt_token_count = format_generation_prompt(messages, tokenizer)
204
 
 
1
+ from __future__ import annotations
2
+
3
  import logging
4
  from contextlib import contextmanager, nullcontext
5
  from dataclasses import dataclass
6
+ from typing import TYPE_CHECKING, Literal
7
 
 
 
8
  from persona_data.prompts import format_messages, format_prompt, normalize_messages
9
  from persona_data.synth_persona import PersonaData
10
 
11
+ if TYPE_CHECKING:
12
+ import torch
13
+ from nnterp import StandardizedTransformer
14
+
15
  logger = logging.getLogger(__name__)
16
  SystemPromptMode = Literal["empty", "templated", "biography", "custom"]
17
 
 
133
 
134
  def resolve_saved_tensor(value: object) -> torch.Tensor:
135
  """Resolve an nnsight ``.save()`` proxy (or raw tensor) to a CPU tensor."""
136
+ import torch
137
+
138
  resolved = value.value if getattr(value, "value", None) is not None else value
139
  if not isinstance(resolved, torch.Tensor):
140
  raise TypeError(f"Trace result did not resolve to a tensor: {type(resolved)!r}")
 
160
  yield
161
  return
162
 
163
+ import torch
164
+
165
  cuda_ctx = torch.random.fork_rng(devices=range(torch.cuda.device_count()))
166
  mps_ctx = (
167
  torch.random.fork_rng(devices=range(1), device_type="mps")
 
207
  ChatReply with generated text and token ids.
208
  """
209
 
210
+ import torch
211
+
212
  tokenizer = model.tokenizer
213
  prompt, prompt_token_count = format_generation_prompt(messages, tokenizer)
214
 
utils/chat_export.py CHANGED
@@ -3,8 +3,6 @@ from dataclasses import asdict, is_dataclass
3
  from datetime import datetime, timezone
4
  from pathlib import Path
5
 
6
- from persona_data.environment import get_artifacts_dir
7
-
8
  from utils.helpers import slugify
9
 
10
 
@@ -48,6 +46,8 @@ def save_chat_export(
48
  The path the export was written to.
49
  """
50
 
 
 
51
  payload = {
52
  "model_name": model_name,
53
  "dataset_source": dataset_source,
 
3
  from datetime import datetime, timezone
4
  from pathlib import Path
5
 
 
 
6
  from utils.helpers import slugify
7
 
8
 
 
46
  The path the export was written to.
47
  """
48
 
49
+ from persona_data.environment import get_artifacts_dir
50
+
51
  payload = {
52
  "model_name": model_name,
53
  "dataset_source": dataset_source,
utils/runtime.py CHANGED
@@ -103,6 +103,9 @@ def cached_model(model_name: str):
103
  model objects when toggling NDIF.
104
  """
105
 
 
106
  from nnterp import StandardizedTransformer
107
 
 
 
108
  return StandardizedTransformer(model_name)
 
103
  model objects when toggling NDIF.
104
  """
105
 
106
+ import torch
107
  from nnterp import StandardizedTransformer
108
 
109
+ torch.set_grad_enabled(False)
110
+
111
  return StandardizedTransformer(model_name)
uv.lock CHANGED
@@ -748,11 +748,11 @@ wheels = [
748
 
749
  [[package]]
750
  name = "idna"
751
- version = "3.13"
752
  source = { registry = "https://pypi.org/simple" }
753
- sdist = { url = "https://files.pythonhosted.org/packages/ce/cc/762dfb036166873f0059f3b7de4565e1b5bc3d6f28a414c13da27e442f99/idna-3.13.tar.gz", hash = "sha256:585ea8fe5d69b9181ec1afba340451fba6ba764af97026f92a91d4eef164a242", size = 194210, upload-time = "2026-04-22T16:42:42.314Z" }
754
  wheels = [
755
- { url = "https://files.pythonhosted.org/packages/5d/13/ad7d7ca3808a898b4612b6fe93cde56b53f3034dcde235acb1f0e1df24c6/idna-3.13-py3-none-any.whl", hash = "sha256:892ea0cde124a99ce773decba204c5552b69c3c67ffd5f232eb7696135bc8bb3", size = 68629, upload-time = "2026-04-22T16:42:40.909Z" },
756
  ]
757
 
758
  [[package]]
@@ -1498,54 +1498,54 @@ wheels = [
1498
 
1499
  [[package]]
1500
  name = "pandas"
1501
- version = "3.0.2"
1502
  source = { registry = "https://pypi.org/simple" }
1503
  dependencies = [
1504
  { name = "numpy" },
1505
  { name = "python-dateutil" },
1506
  { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" },
1507
  ]
1508
- sdist = { url = "https://files.pythonhosted.org/packages/da/99/b342345300f13440fe9fe385c3c481e2d9a595ee3bab4d3219247ac94e9a/pandas-3.0.2.tar.gz", hash = "sha256:f4753e73e34c8d83221ba58f232433fca2748be8b18dbca02d242ed153945043", size = 4645855, upload-time = "2026-03-31T06:48:30.816Z" }
1509
- wheels = [
1510
- { url = "https://files.pythonhosted.org/packages/f3/b0/c20bd4d6d3f736e6bd6b55794e9cd0a617b858eaad27c8f410ea05d953b7/pandas-3.0.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:232a70ebb568c0c4d2db4584f338c1577d81e3af63292208d615907b698a0f18", size = 10347921, upload-time = "2026-03-31T06:46:33.36Z" },
1511
- { url = "https://files.pythonhosted.org/packages/35/d0/4831af68ce30cc2d03c697bea8450e3225a835ef497d0d70f31b8cdde965/pandas-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:970762605cff1ca0d3f71ed4f3a769ea8f85fc8e6348f6e110b8fea7e6eb5a14", size = 9888127, upload-time = "2026-03-31T06:46:36.253Z" },
1512
- { url = "https://files.pythonhosted.org/packages/61/a9/16ea9346e1fc4a96e2896242d9bc674764fb9049b0044c0132502f7a771e/pandas-3.0.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aff4e6f4d722e0652707d7bcb190c445fe58428500c6d16005b02401764b1b3d", size = 10399577, upload-time = "2026-03-31T06:46:39.224Z" },
1513
- { url = "https://files.pythonhosted.org/packages/c4/a8/3a61a721472959ab0ce865ef05d10b0d6bfe27ce8801c99f33d4fa996e65/pandas-3.0.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ef8b27695c3d3dc78403c9a7d5e59a62d5464a7e1123b4e0042763f7104dc74f", size = 10880030, upload-time = "2026-03-31T06:46:42.412Z" },
1514
- { url = "https://files.pythonhosted.org/packages/da/65/7225c0ea4d6ce9cb2160a7fb7f39804871049f016e74782e5dade4d14109/pandas-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f8d68083e49e16b84734eb1a4dcae4259a75c90fb6e2251ab9a00b61120c06ab", size = 11409468, upload-time = "2026-03-31T06:46:45.2Z" },
1515
- { url = "https://files.pythonhosted.org/packages/fa/5b/46e7c76032639f2132359b5cf4c785dd8cf9aea5ea64699eac752f02b9db/pandas-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:32cc41f310ebd4a296d93515fcac312216adfedb1894e879303987b8f1e2b97d", size = 11936381, upload-time = "2026-03-31T06:46:48.293Z" },
1516
- { url = "https://files.pythonhosted.org/packages/7b/8b/721a9cff6fa6a91b162eb51019c6243b82b3226c71bb6c8ef4a9bd65cbc6/pandas-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:a4785e1d6547d8427c5208b748ae2efb64659a21bd82bf440d4262d02bfa02a4", size = 9744993, upload-time = "2026-03-31T06:46:51.488Z" },
1517
- { url = "https://files.pythonhosted.org/packages/d5/18/7f0bd34ae27b28159aa80f2a6799f47fda34f7fb938a76e20c7b7fe3b200/pandas-3.0.2-cp312-cp312-win_arm64.whl", hash = "sha256:08504503f7101300107ecdc8df73658e4347586db5cfdadabc1592e9d7e7a0fd", size = 9056118, upload-time = "2026-03-31T06:46:54.548Z" },
1518
- { url = "https://files.pythonhosted.org/packages/bf/ca/3e639a1ea6fcd0617ca4e8ca45f62a74de33a56ae6cd552735470b22c8d3/pandas-3.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5918ba197c951dec132b0c5929a00c0bf05d5942f590d3c10a807f6e15a57d3", size = 10321105, upload-time = "2026-03-31T06:46:57.327Z" },
1519
- { url = "https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668", size = 9864088, upload-time = "2026-03-31T06:46:59.935Z" },
1520
- { url = "https://files.pythonhosted.org/packages/5c/2b/341f1b04bbca2e17e13cd3f08c215b70ef2c60c5356ef1e8c6857449edc7/pandas-3.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:710246ba0616e86891b58ab95f2495143bb2bc83ab6b06747c74216f583a6ac9", size = 10369066, upload-time = "2026-03-31T06:47:02.792Z" },
1521
- { url = "https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e", size = 10876780, upload-time = "2026-03-31T06:47:06.205Z" },
1522
- { url = "https://files.pythonhosted.org/packages/98/fe/2249ae5e0a69bd0ddf17353d0a5d26611d70970111f5b3600cdc8be883e7/pandas-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3b723df9087a9a9a840e263ebd9f88b64a12075d1bf2ea401a5a42f254f084d", size = 11375181, upload-time = "2026-03-31T06:47:09.383Z" },
1523
- { url = "https://files.pythonhosted.org/packages/de/64/77a38b09e70b6464883b8d7584ab543e748e42c1b5d337a2ee088e0df741/pandas-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3096110bf9eac0070b7208465f2740e2d8a670d5cb6530b5bb884eca495fd39", size = 11928899, upload-time = "2026-03-31T06:47:12.686Z" },
1524
- { url = "https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991", size = 9746574, upload-time = "2026-03-31T06:47:15.64Z" },
1525
- { url = "https://files.pythonhosted.org/packages/88/39/21304ae06a25e8bf9fc820d69b29b2c495b2ae580d1e143146c309941760/pandas-3.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:5fdbfa05931071aba28b408e59226186b01eb5e92bea2ab78b65863ca3228d84", size = 9047156, upload-time = "2026-03-31T06:47:18.595Z" },
1526
- { url = "https://files.pythonhosted.org/packages/72/20/7defa8b27d4f330a903bb68eea33be07d839c5ea6bdda54174efcec0e1d2/pandas-3.0.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:dbc20dea3b9e27d0e66d74c42b2d0c1bed9c2ffe92adea33633e3bedeb5ac235", size = 10756238, upload-time = "2026-03-31T06:47:22.012Z" },
1527
- { url = "https://files.pythonhosted.org/packages/e9/95/49433c14862c636afc0e9b2db83ff16b3ad92959364e52b2955e44c8e94c/pandas-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b75c347eff42497452116ce05ef461822d97ce5b9ff8df6edacb8076092c855d", size = 10408520, upload-time = "2026-03-31T06:47:25.197Z" },
1528
- { url = "https://files.pythonhosted.org/packages/3b/f8/462ad2b5881d6b8ec8e5f7ed2ea1893faa02290d13870a1600fe72ad8efc/pandas-3.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1478075142e83a5571782ad007fb201ed074bdeac7ebcc8890c71442e96adf7", size = 10324154, upload-time = "2026-03-31T06:47:28.097Z" },
1529
- { url = "https://files.pythonhosted.org/packages/0a/65/d1e69b649cbcddda23ad6e4c40ef935340f6f652a006e5cbc3555ac8adb3/pandas-3.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5880314e69e763d4c8b27937090de570f1fb8d027059a7ada3f7f8e98bdcb677", size = 10714449, upload-time = "2026-03-31T06:47:30.85Z" },
1530
- { url = "https://files.pythonhosted.org/packages/47/a4/85b59bc65b8190ea3689882db6cdf32a5003c0ccd5a586c30fdcc3ffc4fc/pandas-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b5329e26898896f06035241a626d7c335daa479b9bbc82be7c2742d048e41172", size = 11338475, upload-time = "2026-03-31T06:47:34.026Z" },
1531
- { url = "https://files.pythonhosted.org/packages/1e/c4/bc6966c6e38e5d9478b935272d124d80a589511ed1612a5d21d36f664c68/pandas-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:81526c4afd31971f8b62671442a4b2b51e0aa9acc3819c9f0f12a28b6fcf85f1", size = 11786568, upload-time = "2026-03-31T06:47:36.941Z" },
1532
- { url = "https://files.pythonhosted.org/packages/e8/74/09298ca9740beed1d3504e073d67e128aa07e5ca5ca2824b0c674c0b8676/pandas-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:7cadd7e9a44ec13b621aec60f9150e744cfc7a3dd32924a7e2f45edff31823b0", size = 10488652, upload-time = "2026-03-31T06:47:40.612Z" },
1533
- { url = "https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b", size = 10326084, upload-time = "2026-03-31T06:47:43.834Z" },
1534
- { url = "https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288", size = 9914146, upload-time = "2026-03-31T06:47:46.67Z" },
1535
- { url = "https://files.pythonhosted.org/packages/8d/77/3a227ff3337aa376c60d288e1d61c5d097131d0ac71f954d90a8f369e422/pandas-3.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01f31a546acd5574ef77fe199bc90b55527c225c20ccda6601cf6b0fd5ed597c", size = 10444081, upload-time = "2026-03-31T06:47:49.681Z" },
1536
- { url = "https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535", size = 10897535, upload-time = "2026-03-31T06:47:53.033Z" },
1537
- { url = "https://files.pythonhosted.org/packages/06/9d/98cc7a7624f7932e40f434299260e2917b090a579d75937cb8a57b9d2de3/pandas-3.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f48afd9bb13300ffb5a3316973324c787054ba6665cda0da3fbd67f451995db", size = 11446992, upload-time = "2026-03-31T06:47:56.193Z" },
1538
- { url = "https://files.pythonhosted.org/packages/9a/cd/19ff605cc3760e80602e6826ddef2824d8e7050ed80f2e11c4b079741dc3/pandas-3.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6c4d8458b97a35717b62469a4ea0e85abd5ed8687277f5ccfc67f8a5126f8c53", size = 11968257, upload-time = "2026-03-31T06:47:59.137Z" },
1539
- { url = "https://files.pythonhosted.org/packages/db/60/aba6a38de456e7341285102bede27514795c1eaa353bc0e7638b6b785356/pandas-3.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:b35d14bb5d8285d9494fe93815a9e9307c0876e10f1e8e89ac5b88f728ec8dcf", size = 9865893, upload-time = "2026-03-31T06:48:02.038Z" },
1540
- { url = "https://files.pythonhosted.org/packages/08/71/e5ec979dd2e8a093dacb8864598c0ff59a0cee0bbcdc0bfec16a51684d4f/pandas-3.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:63d141b56ef686f7f0d714cfb8de4e320475b86bf4b620aa0b7da89af8cbdbbb", size = 9188644, upload-time = "2026-03-31T06:48:05.045Z" },
1541
- { url = "https://files.pythonhosted.org/packages/f1/6c/7b45d85db19cae1eb524f2418ceaa9d85965dcf7b764ed151386b7c540f0/pandas-3.0.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:140f0cffb1fa2524e874dde5b477d9defe10780d8e9e220d259b2c0874c89d9d", size = 10776246, upload-time = "2026-03-31T06:48:07.789Z" },
1542
- { url = "https://files.pythonhosted.org/packages/a8/3e/7b00648b086c106e81766f25322b48aa8dfa95b55e621dbdf2fdd413a117/pandas-3.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae37e833ff4fed0ba352f6bdd8b73ba3ab3256a85e54edfd1ab51ae40cca0af8", size = 10424801, upload-time = "2026-03-31T06:48:10.897Z" },
1543
- { url = "https://files.pythonhosted.org/packages/da/6e/558dd09a71b53b4008e7fc8a98ec6d447e9bfb63cdaeea10e5eb9b2dabe8/pandas-3.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d888a5c678a419a5bb41a2a93818e8ed9fd3172246555c0b37b7cc27027effd", size = 10345643, upload-time = "2026-03-31T06:48:13.7Z" },
1544
- { url = "https://files.pythonhosted.org/packages/be/e3/921c93b4d9a280409451dc8d07b062b503bbec0531d2627e73a756e99a82/pandas-3.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b444dc64c079e84df91baa8bf613d58405645461cabca929d9178f2cd392398d", size = 10743641, upload-time = "2026-03-31T06:48:16.659Z" },
1545
- { url = "https://files.pythonhosted.org/packages/56/ca/fd17286f24fa3b4d067965d8d5d7e14fe557dd4f979a0b068ac0deaf8228/pandas-3.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4544c7a54920de8eeacaa1466a6b7268ecfbc9bc64ab4dbb89c6bbe94d5e0660", size = 11361993, upload-time = "2026-03-31T06:48:19.475Z" },
1546
- { url = "https://files.pythonhosted.org/packages/e4/a5/2f6ed612056819de445a433ca1f2821ac3dab7f150d569a59e9cc105de1d/pandas-3.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:734be7551687c00fbd760dc0522ed974f82ad230d4a10f54bf51b80d44a08702", size = 11815274, upload-time = "2026-03-31T06:48:22.695Z" },
1547
- { url = "https://files.pythonhosted.org/packages/00/2f/b622683e99ec3ce00b0854bac9e80868592c5b051733f2cf3a868e5fea26/pandas-3.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:57a07209bebcbcf768d2d13c9b78b852f9a15978dac41b9e6421a81ad4cdd276", size = 10888530, upload-time = "2026-03-31T06:48:25.806Z" },
1548
- { url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341, upload-time = "2026-03-31T06:48:28.418Z" },
1549
  ]
1550
 
1551
  [[package]]
@@ -1594,7 +1594,7 @@ requires-dist = [
1594
  { name = "datasets", specifier = ">=4.8.5" },
1595
  { name = "huggingface-hub", specifier = ">=1.14.0" },
1596
  { name = "persona-data", specifier = ">=0.4.2" },
1597
- { name = "persona-vectors", specifier = ">=0.7.2" },
1598
  { name = "plotly", specifier = ">=6.6.0" },
1599
  { name = "python-dotenv", specifier = ">=1.2.2" },
1600
  { name = "streamlit", specifier = ">=1.44.0" },
@@ -1602,7 +1602,7 @@ requires-dist = [
1602
 
1603
  [[package]]
1604
  name = "persona-vectors"
1605
- version = "0.7.2"
1606
  source = { registry = "https://pypi.org/simple" }
1607
  dependencies = [
1608
  { name = "datasets" },
@@ -1621,9 +1621,9 @@ dependencies = [
1621
  { name = "transformers" },
1622
  { name = "umap-learn" },
1623
  ]
1624
- sdist = { url = "https://files.pythonhosted.org/packages/03/ee/3550a015546ad9e7842e4d94346e2268c1aa65a7278f39ab574dd2b702bd/persona_vectors-0.7.2.tar.gz", hash = "sha256:22f3e4349bd020fcc287ed5e00ff9d0b752dfe95b3f145b8778efc485cf7f67f", size = 27777, upload-time = "2026-05-10T10:29:07.67Z" }
1625
  wheels = [
1626
- { url = "https://files.pythonhosted.org/packages/c7/c2/334c66944f1669c7cc19e4e3c2f49ab65b0a186e6cd6cb709afd253b4268/persona_vectors-0.7.2-py3-none-any.whl", hash = "sha256:cbd5b6de2afb17fccef9414eba1b0096ffa3407a1496b253bb2d30ed548d123e", size = 32387, upload-time = "2026-05-10T10:29:06.808Z" },
1627
  ]
1628
 
1629
  [[package]]
@@ -2102,11 +2102,11 @@ wheels = [
2102
 
2103
  [[package]]
2104
  name = "python-multipart"
2105
- version = "0.0.27"
2106
  source = { registry = "https://pypi.org/simple" }
2107
- sdist = { url = "https://files.pythonhosted.org/packages/69/9b/f23807317a113dc36e74e75eb265a02dd1a4d9082abc3c1064acd22997c4/python_multipart-0.0.27.tar.gz", hash = "sha256:9870a6a8c5a20a5bf4f07c017bd1489006ff8836cff097b6933355ee2b49b602", size = 44043, upload-time = "2026-04-27T10:51:26.649Z" }
2108
  wheels = [
2109
- { url = "https://files.pythonhosted.org/packages/99/78/4126abcbdbd3c559d43e0db7f7b9173fc6befe45d39a2856cc0b8ec2a5a6/python_multipart-0.0.27-py3-none-any.whl", hash = "sha256:6fccfad17a27334bd0193681b369f476eda3409f17381a2d65aa7df3f7275645", size = 29254, upload-time = "2026-04-27T10:51:24.997Z" },
2110
  ]
2111
 
2112
  [[package]]
@@ -2278,7 +2278,7 @@ wheels = [
2278
 
2279
  [[package]]
2280
  name = "requests"
2281
- version = "2.33.1"
2282
  source = { registry = "https://pypi.org/simple" }
2283
  dependencies = [
2284
  { name = "certifi" },
@@ -2286,9 +2286,9 @@ dependencies = [
2286
  { name = "idna" },
2287
  { name = "urllib3" },
2288
  ]
2289
- sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" }
2290
  wheels = [
2291
- { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" },
2292
  ]
2293
 
2294
  [[package]]
 
748
 
749
  [[package]]
750
  name = "idna"
751
+ version = "3.14"
752
  source = { registry = "https://pypi.org/simple" }
753
+ sdist = { url = "https://files.pythonhosted.org/packages/05/b1/efac073e0c297ecf2fb33c346989a529d4e19164f1759102dee5953ee17e/idna-3.14.tar.gz", hash = "sha256:466d810d7a2cc1022bea9b037c39728d51ae7dad40d480fc9b7d7ecf98ba8ee3", size = 198272, upload-time = "2026-05-10T20:32:15.935Z" }
754
  wheels = [
755
+ { url = "https://files.pythonhosted.org/packages/6c/3c/3f62dee257eb3d6b2c1ef2a09d36d9793c7111156a73b5654d2c2305e5ce/idna-3.14-py3-none-any.whl", hash = "sha256:e677eaf072e290f7b725f9acf0b3a2bd55f9fd6f7c70abe5f0e34823d0accf69", size = 72184, upload-time = "2026-05-10T20:32:14.295Z" },
756
  ]
757
 
758
  [[package]]
 
1498
 
1499
  [[package]]
1500
  name = "pandas"
1501
+ version = "3.0.3"
1502
  source = { registry = "https://pypi.org/simple" }
1503
  dependencies = [
1504
  { name = "numpy" },
1505
  { name = "python-dateutil" },
1506
  { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" },
1507
  ]
1508
+ sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" }
1509
+ wheels = [
1510
+ { url = "https://files.pythonhosted.org/packages/24/f1/392f8c5bfc16f66a0d2d41561c01627c228fe7ed2a0d056ef11315042570/pandas-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fed2ff7fd9779120e388e285fc029bd5cf9490cdd2e4166a9ee22c0e49a9ab09", size = 10357846, upload-time = "2026-05-11T18:52:36.143Z" },
1511
+ { url = "https://files.pythonhosted.org/packages/cf/3d/b16412745651e855f357e5e66930248688378853a6e2698a214e331fba1f/pandas-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b168fc218fd80a6cbdbdbc1a97ddc7889ed057d7eb45f50d866ceab5f39904c4", size = 9899550, upload-time = "2026-05-11T18:52:38.976Z" },
1512
+ { url = "https://files.pythonhosted.org/packages/31/a8/fa2535168fffcedf67f4f6de28d2dd903a747ca7c8ea6989451aaeb3a92f/pandas-3.0.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0383c72c75cdcca61a9e116e611143902dbfd08bff356829c2f6d1cf40a9ca8c", size = 10412965, upload-time = "2026-05-11T18:52:41.915Z" },
1513
+ { url = "https://files.pythonhosted.org/packages/65/b6/09b01cdbc15224e2850365192d17b7bdebb8bdbd8780ed221fcdf0d9a515/pandas-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6dc0b3fd2169c9157deed50b4d519553a3655c8c6a96027136d654592be973a9", size = 10894600, upload-time = "2026-05-11T18:52:45.02Z" },
1514
+ { url = "https://files.pythonhosted.org/packages/c9/a4/2eb28f2fccb4ced4a2c79ab2a5dee9ade1ebf44922ebad6fea158c9f95d4/pandas-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e65d5407dc0b394f509699650e4a2ec01c0514f21850f453fa60f3be79a5dbf", size = 11422824, upload-time = "2026-05-11T18:52:48.058Z" },
1515
+ { url = "https://files.pythonhosted.org/packages/f8/45/830bb57f533a4604b355e07edcb8ea18cf88b5f94e5fca92f27052d7c597/pandas-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f8894dc474d648fe7b6ff0ca9b0bd73950d19952bc1a6534540762c5d79d305c", size = 11950889, upload-time = "2026-05-11T18:52:50.905Z" },
1516
+ { url = "https://files.pythonhosted.org/packages/b9/c5/fc1b368f303087d20e8c9bf3d6ceb186263cfac0ade735cd938538bea839/pandas-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:c7be265b62cef88e253a941e4698604973736dcfe242fdb5198f0f7bc473cdcc", size = 9755463, upload-time = "2026-05-11T18:52:53.386Z" },
1517
+ { url = "https://files.pythonhosted.org/packages/86/bd/fda8f9705b1b09c6ebe14bfc0fa0e4ec8584d54ea673628f157ff55131af/pandas-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:557409bc4178e70ee8d9ddb494798e51ebf6ea59330f6be22c51bab2a7db6c49", size = 9066158, upload-time = "2026-05-11T18:52:56.038Z" },
1518
+ { url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" },
1519
+ { url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" },
1520
+ { url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" },
1521
+ { url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" },
1522
+ { url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" },
1523
+ { url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" },
1524
+ { url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" },
1525
+ { url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" },
1526
+ { url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" },
1527
+ { url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" },
1528
+ { url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" },
1529
+ { url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" },
1530
+ { url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" },
1531
+ { url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" },
1532
+ { url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" },
1533
+ { url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" },
1534
+ { url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" },
1535
+ { url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" },
1536
+ { url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" },
1537
+ { url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" },
1538
+ { url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" },
1539
+ { url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" },
1540
+ { url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" },
1541
+ { url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" },
1542
+ { url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" },
1543
+ { url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" },
1544
+ { url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" },
1545
+ { url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" },
1546
+ { url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" },
1547
+ { url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" },
1548
+ { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" },
1549
  ]
1550
 
1551
  [[package]]
 
1594
  { name = "datasets", specifier = ">=4.8.5" },
1595
  { name = "huggingface-hub", specifier = ">=1.14.0" },
1596
  { name = "persona-data", specifier = ">=0.4.2" },
1597
+ { name = "persona-vectors", specifier = ">=0.7.3" },
1598
  { name = "plotly", specifier = ">=6.6.0" },
1599
  { name = "python-dotenv", specifier = ">=1.2.2" },
1600
  { name = "streamlit", specifier = ">=1.44.0" },
 
1602
 
1603
  [[package]]
1604
  name = "persona-vectors"
1605
+ version = "0.7.3"
1606
  source = { registry = "https://pypi.org/simple" }
1607
  dependencies = [
1608
  { name = "datasets" },
 
1621
  { name = "transformers" },
1622
  { name = "umap-learn" },
1623
  ]
1624
+ sdist = { url = "https://files.pythonhosted.org/packages/6d/36/25d766934dc43f60faeba8a51c698da78bdd9af2e5d191b7ce8721612dc4/persona_vectors-0.7.3.tar.gz", hash = "sha256:75a90e68142097419a2f1cf6d21878dc5202234c12ed342d63349796255baad6", size = 28641, upload-time = "2026-05-12T10:04:37.21Z" }
1625
  wheels = [
1626
+ { url = "https://files.pythonhosted.org/packages/6b/e7/db961133fda6755e215e6cd9d4058a1cb93719d05ab6e24030c5da885d15/persona_vectors-0.7.3-py3-none-any.whl", hash = "sha256:abf07b6715321a16b218aede69f7efac7bf6a309e090db62ee376e3f09240fde", size = 33224, upload-time = "2026-05-12T10:04:36.351Z" },
1627
  ]
1628
 
1629
  [[package]]
 
2102
 
2103
  [[package]]
2104
  name = "python-multipart"
2105
+ version = "0.0.28"
2106
  source = { registry = "https://pypi.org/simple" }
2107
+ sdist = { url = "https://files.pythonhosted.org/packages/82/54/a85eb421fbdd5007bc5af39d0f4ed9fa609e0fedbfdc2adcf0b34526870e/python_multipart-0.0.28.tar.gz", hash = "sha256:8550da197eac0f7ab748961fc9509b999fa2662ea25cef857f05249f6893c0f8", size = 45314, upload-time = "2026-05-10T11:05:16.596Z" }
2108
  wheels = [
2109
+ { url = "https://files.pythonhosted.org/packages/f3/a2/43bbc5860b5034e2af4ef99a0e04d726ff329c43e192ef3abaa8d7ecfce5/python_multipart-0.0.28-py3-none-any.whl", hash = "sha256:10faac07eb966c3f48dc415f9dee46c04cb10d58d30a35677db8027c825ed9b6", size = 29438, upload-time = "2026-05-10T11:05:15.052Z" },
2110
  ]
2111
 
2112
  [[package]]
 
2278
 
2279
  [[package]]
2280
  name = "requests"
2281
+ version = "2.34.0"
2282
  source = { registry = "https://pypi.org/simple" }
2283
  dependencies = [
2284
  { name = "certifi" },
 
2286
  { name = "idna" },
2287
  { name = "urllib3" },
2288
  ]
2289
+ sdist = { url = "https://files.pythonhosted.org/packages/43/b8/7a707d60fea4c49094e40262cc0e2ca6c768cca21587e34d3f705afec47e/requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a", size = 142436, upload-time = "2026-05-11T19:29:51.717Z" }
2290
  wheels = [
2291
+ { url = "https://files.pythonhosted.org/packages/ef/e6/e300fce5fe83c30520607a015dabd985df3251e188d234bfe9492e17a389/requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60", size = 73021, upload-time = "2026-05-11T19:29:49.923Z" },
2292
  ]
2293
 
2294
  [[package]]