Jac-Zac commited on
Commit
73d72c1
·
1 Parent(s): 7ad2026

Updated with latest versions

Browse files
Files changed (6) hide show
  1. pyproject.toml +4 -4
  2. tabs/compare.py +76 -42
  3. tabs/extract.py +74 -62
  4. utils/chat.py +4 -6
  5. utils/helpers.py +1 -0
  6. uv.lock +178 -74
pyproject.toml CHANGED
@@ -1,12 +1,12 @@
1
  [project]
2
  name = "persona-ui"
3
- version = "0.1.1"
4
  description = "Streamlit UI for persona-vectors"
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
8
- "persona-vectors>=0.3.2",
9
- "persona-data>=0.2.3",
10
  "streamlit>=1.44.0",
11
  "plotly>=6.6.0",
12
  "python-dotenv>=1.2.2",
@@ -15,7 +15,7 @@ dependencies = [
15
 
16
  # Local development:
17
  [tool.uv.sources]
18
- persona-vectors = { path = "../persona-vectors", editable = true }
19
  # persona-data = { path = "../persona-data", editable = true }
20
 
21
  # [build-system]
 
1
  [project]
2
  name = "persona-ui"
3
+ version = "0.2.0"
4
  description = "Streamlit UI for persona-vectors"
5
  readme = "README.md"
6
  requires-python = ">=3.12"
7
  dependencies = [
8
+ "persona-vectors>=0.4.0",
9
+ "persona-data>=0.2.5",
10
  "streamlit>=1.44.0",
11
  "plotly>=6.6.0",
12
  "python-dotenv>=1.2.2",
 
15
 
16
  # Local development:
17
  [tool.uv.sources]
18
+ # persona-vectors = { path = "../persona-vectors", editable = true }
19
  # persona-data = { path = "../persona-data", editable = true }
20
 
21
  # [build-system]
tabs/compare.py CHANGED
@@ -1,9 +1,14 @@
 
 
1
  import streamlit as st
2
  import torch
3
  from persona_data.environment import get_artifacts_dir
4
  from persona_data.prompts import BASELINE_PERSONA_ID
5
- from persona_vectors.analysis import LayeredSamples, load_persona_mean_samples
6
- from persona_vectors.artifacts import SUPPORTED_VARIANTS, ActivationStore
 
 
 
7
  from persona_vectors.artifacts import list_layers as list_available_layers
8
  from persona_vectors.artifacts import list_personas as list_available_personas
9
  from persona_vectors.artifacts import load_mean_activations, load_persona_names
@@ -37,7 +42,6 @@ _list_layers_cached = st.cache_data(show_spinner=False)(list_available_layers)
37
  _LAST_COSINE_PERSONAS_KEY = "compare:last_personas:cosine"
38
  _LAST_PROJECTION_PERSONAS_KEY = "compare:last_personas:projection"
39
  _LAST_MASK_STRATEGY_KEY = "compare:last_mask_strategy"
40
- _COMPARABLE_VARIANTS = tuple(v for v in SUPPORTED_VARIANTS if v != "baseline")
41
 
42
 
43
  def _select_artifact_personas(
@@ -155,7 +159,7 @@ def _render_cosine_similarity(
155
  store: ActivationStore,
156
  mask_strategy: MaskStrategy,
157
  ) -> None:
158
- if len(_COMPARABLE_VARIANTS) < 2:
159
  st.info("Need at least two non-baseline variants for cosine comparison.")
160
  return
161
 
@@ -163,7 +167,7 @@ def _render_cosine_similarity(
163
  with col1:
164
  variant_a = st.selectbox(
165
  "Variant A",
166
- options=_COMPARABLE_VARIANTS,
167
  index=0,
168
  format_func=prompt_variant_label,
169
  key=widget_key("load", "variant_a"),
@@ -171,8 +175,8 @@ def _render_cosine_similarity(
171
  with col2:
172
  variant_b = st.selectbox(
173
  "Variant B",
174
- options=_COMPARABLE_VARIANTS,
175
- index=min(1, len(_COMPARABLE_VARIANTS) - 1),
176
  format_func=prompt_variant_label,
177
  key=widget_key("load", "variant_b"),
178
  )
@@ -207,6 +211,13 @@ def _render_cosine_similarity(
207
  variant_a,
208
  variant_b,
209
  )
 
 
 
 
 
 
 
210
 
211
  if st.button("Compare vectors", type="primary"):
212
  traces, loaded_names, errors = load_mean_activations(
@@ -242,13 +253,57 @@ def _render_cosine_similarity(
242
  title=f"{prompt_variant_label(variant_a)} vs {prompt_variant_label(variant_b)}",
243
  show=False,
244
  )
245
- st.session_state[cosine_fig_key] = (fig, len(traces))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
 
247
  if cosine_fig_key in st.session_state:
248
- fig, n_traces = st.session_state[cosine_fig_key]
249
  st.plotly_chart(fig, width="stretch")
250
- _render_save_buttons([fig], [filename], "cosine")
 
 
 
 
 
 
 
251
  st.success(f"Loaded {n_traces} personas for cosine comparison.")
 
 
252
 
253
 
254
  def _select_single_variant_samples(
@@ -258,9 +313,9 @@ def _select_single_variant_samples(
258
  ) -> tuple[str, list[str], str, list[int]] | None:
259
  variant = st.selectbox(
260
  "Variant",
261
- options=_COMPARABLE_VARIANTS,
262
- index=_COMPARABLE_VARIANTS.index("biography")
263
- if "biography" in _COMPARABLE_VARIANTS
264
  else 0,
265
  format_func=prompt_variant_label,
266
  key=widget_key("load", "variant", scope),
@@ -316,7 +371,7 @@ def _baseline_available(
316
  return BASELINE_PERSONA_ID in list_available_personas(
317
  store.root_dir,
318
  store.model_name,
319
- ["baseline"],
320
  mask_strategy=mask_strategy,
321
  warn_missing=False,
322
  )
@@ -336,30 +391,11 @@ def _render_baseline_reference_toggle(
336
  help=(
337
  "Adds the single saved baseline artifact as one reference sample."
338
  if available
339
- else "Run extraction for the baseline variant first."
340
  ),
341
  )
342
 
343
 
344
- def _append_baseline_reference(
345
- store: ActivationStore,
346
- mask_strategy: MaskStrategy,
347
- samples: LayeredSamples,
348
- ) -> LayeredSamples:
349
- baseline_samples = load_persona_mean_samples(
350
- store.root_dir,
351
- store.model_name,
352
- "baseline",
353
- mask_strategy=mask_strategy,
354
- persona_ids=[BASELINE_PERSONA_ID],
355
- )
356
- return LayeredSamples(
357
- vectors=torch.cat([samples.vectors, baseline_samples.vectors], dim=0),
358
- labels=[*samples.labels, *baseline_samples.labels],
359
- hover_text=[*samples.hover_text, *baseline_samples.hover_text],
360
- )
361
-
362
-
363
  def _render_similarity_matrix(
364
  store: ActivationStore,
365
  mask_strategy: MaskStrategy,
@@ -386,7 +422,7 @@ def _render_similarity_matrix(
386
  variant,
387
  "persona_mean",
388
  persona_key,
389
- "baseline" if include_baseline else "no_baseline",
390
  )
391
  filename = _filename(
392
  "compare",
@@ -396,7 +432,7 @@ def _render_similarity_matrix(
396
  variant,
397
  "persona_mean",
398
  persona_key,
399
- "baseline" if include_baseline else "",
400
  )
401
 
402
  if st.button("Generate similarity matrix", type="primary"):
@@ -407,9 +443,8 @@ def _render_similarity_matrix(
407
  variant,
408
  mask_strategy=mask_strategy,
409
  persona_ids=persona_ids,
 
410
  )
411
- if include_baseline:
412
- samples = _append_baseline_reference(store, mask_strategy, samples)
413
  matrix_fig = build_layered_figure(
414
  samples,
415
  "similarity",
@@ -479,7 +514,7 @@ def _render_embedding_analysis(
479
  variant,
480
  "persona_mean",
481
  persona_key,
482
- "baseline" if include_baseline else "no_baseline",
483
  )
484
  filename = _filename(
485
  "compare",
@@ -489,7 +524,7 @@ def _render_embedding_analysis(
489
  variant,
490
  "persona_mean",
491
  persona_key,
492
- "baseline" if include_baseline else "",
493
  )
494
 
495
  if st.button(f"Generate {analysis_mode} projection", type="primary"):
@@ -500,9 +535,8 @@ def _render_embedding_analysis(
500
  variant,
501
  mask_strategy=mask_strategy,
502
  persona_ids=persona_ids,
 
503
  )
504
- if include_baseline:
505
- samples = _append_baseline_reference(store, mask_strategy, samples)
506
  fig = build_layered_figure(
507
  samples,
508
  figure_kind,
 
1
+ from itertools import combinations
2
+
3
  import streamlit as st
4
  import torch
5
  from persona_data.environment import get_artifacts_dir
6
  from persona_data.prompts import BASELINE_PERSONA_ID
7
+ from persona_vectors.analysis import load_persona_mean_samples
8
+ from persona_vectors.artifacts import (
9
+ PERSONA_VARIANTS,
10
+ ActivationStore,
11
+ )
12
  from persona_vectors.artifacts import list_layers as list_available_layers
13
  from persona_vectors.artifacts import list_personas as list_available_personas
14
  from persona_vectors.artifacts import load_mean_activations, load_persona_names
 
42
  _LAST_COSINE_PERSONAS_KEY = "compare:last_personas:cosine"
43
  _LAST_PROJECTION_PERSONAS_KEY = "compare:last_personas:projection"
44
  _LAST_MASK_STRATEGY_KEY = "compare:last_mask_strategy"
 
45
 
46
 
47
  def _select_artifact_personas(
 
159
  store: ActivationStore,
160
  mask_strategy: MaskStrategy,
161
  ) -> None:
162
+ if len(PERSONA_VARIANTS) < 2:
163
  st.info("Need at least two non-baseline variants for cosine comparison.")
164
  return
165
 
 
167
  with col1:
168
  variant_a = st.selectbox(
169
  "Variant A",
170
+ options=PERSONA_VARIANTS,
171
  index=0,
172
  format_func=prompt_variant_label,
173
  key=widget_key("load", "variant_a"),
 
175
  with col2:
176
  variant_b = st.selectbox(
177
  "Variant B",
178
+ options=PERSONA_VARIANTS,
179
+ index=min(1, len(PERSONA_VARIANTS) - 1),
180
  format_func=prompt_variant_label,
181
  key=widget_key("load", "variant_b"),
182
  )
 
211
  variant_a,
212
  variant_b,
213
  )
214
+ pairs_filename = _filename(
215
+ "compare",
216
+ "cosine_pairs",
217
+ store.model_name,
218
+ mask_strategy.value,
219
+ "_".join(PERSONA_VARIANTS),
220
+ )
221
 
222
  if st.button("Compare vectors", type="primary"):
223
  traces, loaded_names, errors = load_mean_activations(
 
253
  title=f"{prompt_variant_label(variant_a)} vs {prompt_variant_label(variant_b)}",
254
  show=False,
255
  )
256
+
257
+ pair_traces = []
258
+ pair_errors: list[str] = []
259
+ for left, right in combinations(PERSONA_VARIANTS, 2):
260
+ pair_data, _, pair_load_errors = load_mean_activations(
261
+ store.root_dir,
262
+ store.model_name,
263
+ persona_ids,
264
+ left,
265
+ right,
266
+ mask_strategy=mask_strategy,
267
+ )
268
+ pair_errors.extend(pair_load_errors)
269
+ if not pair_data:
270
+ continue
271
+ pair_traces.append(
272
+ (
273
+ f"{prompt_variant_label(left)} vs {prompt_variant_label(right)}",
274
+ torch.stack([short for _, short, _ in pair_data]).mean(dim=0),
275
+ torch.stack([long for _, _, long in pair_data]).mean(dim=0),
276
+ )
277
+ )
278
+
279
+ if pair_errors:
280
+ for err in pair_errors:
281
+ st.warning(f"Skipped pair trace: `{err}`")
282
+ pair_fig = (
283
+ plot_layer_similarity(
284
+ pair_traces,
285
+ title="Variant-pair cosine similarity averaged over selected personas",
286
+ show=False,
287
+ )
288
+ if pair_traces
289
+ else None
290
+ )
291
+ st.session_state[cosine_fig_key] = (fig, pair_fig, len(traces), len(pair_traces))
292
 
293
  if cosine_fig_key in st.session_state:
294
+ fig, pair_fig, n_traces, n_pair_traces = st.session_state[cosine_fig_key]
295
  st.plotly_chart(fig, width="stretch")
296
+ figs = [fig]
297
+ filenames = [filename]
298
+ if pair_fig is not None:
299
+ st.subheader("Variant pairs")
300
+ st.plotly_chart(pair_fig, width="stretch")
301
+ figs.append(pair_fig)
302
+ filenames.append(pairs_filename)
303
+ _render_save_buttons(figs, filenames, "cosine")
304
  st.success(f"Loaded {n_traces} personas for cosine comparison.")
305
+ if pair_fig is not None:
306
+ st.caption(f"Generated {n_pair_traces} averaged variant-pair trace(s).")
307
 
308
 
309
  def _select_single_variant_samples(
 
313
  ) -> tuple[str, list[str], str, list[int]] | None:
314
  variant = st.selectbox(
315
  "Variant",
316
+ options=PERSONA_VARIANTS,
317
+ index=PERSONA_VARIANTS.index("biography")
318
+ if "biography" in PERSONA_VARIANTS
319
  else 0,
320
  format_func=prompt_variant_label,
321
  key=widget_key("load", "variant", scope),
 
371
  return BASELINE_PERSONA_ID in list_available_personas(
372
  store.root_dir,
373
  store.model_name,
374
+ [BASELINE_PERSONA_ID],
375
  mask_strategy=mask_strategy,
376
  warn_missing=False,
377
  )
 
391
  help=(
392
  "Adds the single saved baseline artifact as one reference sample."
393
  if available
394
+ else "Run Assistant baseline extraction first."
395
  ),
396
  )
397
 
398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  def _render_similarity_matrix(
400
  store: ActivationStore,
401
  mask_strategy: MaskStrategy,
 
422
  variant,
423
  "persona_mean",
424
  persona_key,
425
+ BASELINE_PERSONA_ID if include_baseline else "no_baseline",
426
  )
427
  filename = _filename(
428
  "compare",
 
432
  variant,
433
  "persona_mean",
434
  persona_key,
435
+ BASELINE_PERSONA_ID if include_baseline else "",
436
  )
437
 
438
  if st.button("Generate similarity matrix", type="primary"):
 
443
  variant,
444
  mask_strategy=mask_strategy,
445
  persona_ids=persona_ids,
446
+ include_baseline=include_baseline,
447
  )
 
 
448
  matrix_fig = build_layered_figure(
449
  samples,
450
  "similarity",
 
514
  variant,
515
  "persona_mean",
516
  persona_key,
517
+ BASELINE_PERSONA_ID if include_baseline else "no_baseline",
518
  )
519
  filename = _filename(
520
  "compare",
 
524
  variant,
525
  "persona_mean",
526
  persona_key,
527
+ BASELINE_PERSONA_ID if include_baseline else "",
528
  )
529
 
530
  if st.button(f"Generate {analysis_mode} projection", type="primary"):
 
535
  variant,
536
  mask_strategy=mask_strategy,
537
  persona_ids=persona_ids,
538
+ include_baseline=include_baseline,
539
  )
 
 
540
  fig = build_layered_figure(
541
  samples,
542
  figure_kind,
tabs/extract.py CHANGED
@@ -5,10 +5,10 @@ import streamlit as st
5
  from persona_data.prompts import (
6
  BASELINE_PERSONA_ID,
7
  BASELINE_PERSONA_NAME,
8
- system_prompt_for_variant,
9
  )
10
  from persona_data.synth_persona import PersonaData, QAPair
11
- from persona_vectors.artifacts import SUPPORTED_VARIANTS
12
  from persona_vectors.extraction import (
13
  MaskStrategy,
14
  PreparedInput,
@@ -28,6 +28,7 @@ from utils.runtime import cached_model
28
  # Cross-model / remote-switch persistence — same pattern as compare.py.
29
  # Written on every render so selections survive model or NDIF toggles.
30
  _LAST_VARIANTS_KEY = "extract:last_variants"
 
31
  _LAST_PERSONA_IDS_KEY = "extract:last_persona_ids"
32
  _LAST_QA_TYPE_KEY = "extract:last_qa_type"
33
  _LAST_DIFFICULTY_KEY = "extract:last_difficulty"
@@ -37,29 +38,24 @@ _LAST_MASK_STRATEGY_KEY = "extract:last_mask_strategy"
37
  _QA_TYPE_OPTIONS = ["all", "explicit", "implicit"]
38
 
39
 
40
- def _baseline_persona() -> PersonaData:
41
- return PersonaData(
42
- id=BASELINE_PERSONA_ID,
43
- persona={"first_name": BASELINE_PERSONA_NAME, "last_name": ""},
44
- templated_view=BASELINE_PERSONA_NAME,
45
- biography_view=BASELINE_PERSONA_NAME,
46
- )
47
-
48
-
49
  def _build_run_plan(
50
  selected_variants: list[str],
51
  runs: list[tuple[PersonaData, list[QAPair]]],
52
- ) -> list[tuple[PersonaData, list[QAPair], str]]:
53
- regular_variants = [v for v in selected_variants if v != "baseline"]
54
- run_plan = [
55
- (persona, qa_pairs, variant)
56
- for persona, qa_pairs in runs
57
- for variant in regular_variants
58
- ]
59
- if "baseline" in selected_variants:
60
- _, baseline_qa_pairs = runs[0]
61
- run_plan.append((_baseline_persona(), baseline_qa_pairs, "baseline"))
62
- return run_plan
 
 
 
 
63
 
64
 
65
  def _extract_widget_key(
@@ -165,25 +161,41 @@ def render_extract_tab(remote: bool, model_name: str, dataset_source: str) -> No
165
  if dataset_source == "Local JSONL upload":
166
  _render_local_dataset_uploads()
167
 
168
- last_variants = st.session_state.get(_LAST_VARIANTS_KEY, list(SUPPORTED_VARIANTS))
169
- default_variants = [v for v in last_variants if v in SUPPORTED_VARIANTS] or list(
170
- SUPPORTED_VARIANTS
171
  )
172
- selected_variants = st.multiselect(
173
- "Prompt variants",
174
- options=SUPPORTED_VARIANTS,
175
- default=default_variants,
 
 
 
176
  format_func=prompt_variant_label,
177
- key=_extract_widget_key(model_name, remote, dataset_source, "prompt_variants"),
 
 
 
 
178
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
179
  st.session_state[_LAST_VARIANTS_KEY] = selected_variants
 
180
  if not selected_variants:
181
- st.info("Select at least one prompt variant.")
182
  return
183
- if "baseline" in selected_variants:
184
- st.caption(
185
- "Baseline uses the persona-less Assistant prompt and is saved once as an Assistant reference. It uses the first selected persona's QA set for extraction."
186
- )
187
 
188
  try:
189
  dataset, dataset_status = load_dataset(
@@ -333,24 +345,30 @@ def render_extract_tab(remote: bool, model_name: str, dataset_source: str) -> No
333
  with preview_col:
334
  preview_clicked = st.button("Preview tokens", use_container_width=True)
335
 
 
 
 
 
 
 
336
  if preview_clicked:
337
  with st.spinner("Loading tokenizer..."):
338
  model = cached_model(model_name=model_name, remote=remote)
339
  st.markdown(_TOKEN_LEGEND, unsafe_allow_html=True)
340
- for persona, qa_pairs, variant in _build_run_plan(selected_variants, runs):
341
- system_prompt = system_prompt_for_variant(persona, variant)
 
 
 
 
342
  prepared = prepare_inputs_for_strategy(
343
  tokenizer=model.tokenizer,
344
  system_prompt=system_prompt,
345
  qa_pairs=qa_pairs[:max_questions],
346
  mask_strategy=mask_strategy,
347
  )
348
- display_name = (
349
- BASELINE_PERSONA_NAME if variant == "baseline" else persona.name
350
- )
351
- st.caption(f"{display_name} · {prompt_variant_label(variant)}")
352
- shown = prepared[:_MAX_PREVIEW_SAMPLES]
353
- for i, p in enumerate(shown):
354
  question = (
355
  p.question if len(p.question) <= 60 else p.question[:57] + "..."
356
  )
@@ -383,31 +401,25 @@ def render_extract_tab(remote: bool, model_name: str, dataset_source: str) -> No
383
  model = cached_model(model_name=model_name, remote=remote)
384
 
385
  try:
386
- run_plan = _build_run_plan(selected_variants, runs)
387
  total_steps = len(run_plan)
388
- step = 0
389
  results = []
390
-
391
- for persona, qa_pairs, variant in run_plan:
392
- display_name = (
393
- BASELINE_PERSONA_NAME if variant == "baseline" else persona.name
394
- )
395
  progress.progress(
396
  step / total_steps if total_steps else 1.0,
397
- text=f"{display_name} · {prompt_variant_label(variant)} ({step + 1}/{total_steps})",
398
  )
399
- variant_results = run_extraction(
400
- model=model,
401
- model_name=model_name,
402
- persona=persona,
403
- qa_pairs=qa_pairs[:max_questions],
404
- variants=(variant,),
405
- mask_strategy=mask_strategy,
406
- remote=remote,
407
- on_status=_on_ndif_status if remote else None,
 
 
408
  )
409
- results.extend(variant_results)
410
- step += 1
411
 
412
  progress.progress(1.0, text="Extraction complete")
413
  except Exception as exc:
 
5
  from persona_data.prompts import (
6
  BASELINE_PERSONA_ID,
7
  BASELINE_PERSONA_NAME,
8
+ format_roleplay_prompt,
9
  )
10
  from persona_data.synth_persona import PersonaData, QAPair
11
+ from persona_vectors.artifacts import PERSONA_VARIANTS
12
  from persona_vectors.extraction import (
13
  MaskStrategy,
14
  PreparedInput,
 
28
  # Cross-model / remote-switch persistence — same pattern as compare.py.
29
  # Written on every render so selections survive model or NDIF toggles.
30
  _LAST_VARIANTS_KEY = "extract:last_variants"
31
+ _LAST_BASELINE_KEY = "extract:last_include_baseline"
32
  _LAST_PERSONA_IDS_KEY = "extract:last_persona_ids"
33
  _LAST_QA_TYPE_KEY = "extract:last_qa_type"
34
  _LAST_DIFFICULTY_KEY = "extract:last_difficulty"
 
38
  _QA_TYPE_OPTIONS = ["all", "explicit", "implicit"]
39
 
40
 
 
 
 
 
 
 
 
 
 
41
  def _build_run_plan(
42
  selected_variants: list[str],
43
  runs: list[tuple[PersonaData, list[QAPair]]],
44
+ ) -> list[tuple[PersonaData | None, list[QAPair], str]]:
45
+ """Expand selected variants × personas into one (persona, qa, variant) per call.
46
+
47
+ The baseline variant is run once across the first persona's QA pairs and
48
+ has no associated persona.
49
+ """
50
+ plan: list[tuple[PersonaData | None, list[QAPair], str]] = []
51
+ for variant in selected_variants:
52
+ if variant == BASELINE_PERSONA_ID:
53
+ _, qa_pairs = runs[0]
54
+ plan.append((None, qa_pairs, variant))
55
+ else:
56
+ for persona, qa_pairs in runs:
57
+ plan.append((persona, qa_pairs, variant))
58
+ return plan
59
 
60
 
61
  def _extract_widget_key(
 
161
  if dataset_source == "Local JSONL upload":
162
  _render_local_dataset_uploads()
163
 
164
+ last_variants = st.session_state.get(
165
+ _LAST_VARIANTS_KEY, [*PERSONA_VARIANTS, BASELINE_PERSONA_ID]
 
166
  )
167
+ default_persona_variants = [
168
+ v for v in last_variants if v in PERSONA_VARIANTS
169
+ ] or list(PERSONA_VARIANTS)
170
+ selected_persona_variants = st.multiselect(
171
+ "Persona variants",
172
+ options=PERSONA_VARIANTS,
173
+ default=default_persona_variants,
174
  format_func=prompt_variant_label,
175
+ key=_extract_widget_key(model_name, remote, dataset_source, "persona_variants"),
176
+ help="Extract these variants for each selected persona.",
177
+ )
178
+ include_baseline_default = st.session_state.get(
179
+ _LAST_BASELINE_KEY, BASELINE_PERSONA_ID in last_variants
180
  )
181
+ include_baseline = st.checkbox(
182
+ "Extract Assistant baseline",
183
+ value=include_baseline_default,
184
+ key=_extract_widget_key(model_name, remote, dataset_source, "baseline"),
185
+ help=(
186
+ "Extracts the persona-less Assistant prompt once using the first "
187
+ "selected persona's QA set."
188
+ ),
189
+ )
190
+ selected_variants = [
191
+ *selected_persona_variants,
192
+ *([BASELINE_PERSONA_ID] if include_baseline else []),
193
+ ]
194
  st.session_state[_LAST_VARIANTS_KEY] = selected_variants
195
+ st.session_state[_LAST_BASELINE_KEY] = include_baseline
196
  if not selected_variants:
197
+ st.info("Select at least one persona variant or enable the baseline.")
198
  return
 
 
 
 
199
 
200
  try:
201
  dataset, dataset_status = load_dataset(
 
345
  with preview_col:
346
  preview_clicked = st.button("Preview tokens", use_container_width=True)
347
 
348
+ run_plan = _build_run_plan(selected_variants, runs)
349
+
350
+ def _row_label(persona: PersonaData | None, variant: str) -> str:
351
+ name = persona.name if persona is not None else BASELINE_PERSONA_NAME
352
+ return f"{name} · {prompt_variant_label(variant)}"
353
+
354
  if preview_clicked:
355
  with st.spinner("Loading tokenizer..."):
356
  model = cached_model(model_name=model_name, remote=remote)
357
  st.markdown(_TOKEN_LEGEND, unsafe_allow_html=True)
358
+ for persona, qa_pairs, variant in run_plan:
359
+ system_prompt = (
360
+ format_roleplay_prompt()
361
+ if persona is None
362
+ else format_roleplay_prompt(getattr(persona, f"{variant}_view"))
363
+ )
364
  prepared = prepare_inputs_for_strategy(
365
  tokenizer=model.tokenizer,
366
  system_prompt=system_prompt,
367
  qa_pairs=qa_pairs[:max_questions],
368
  mask_strategy=mask_strategy,
369
  )
370
+ st.caption(_row_label(persona, variant))
371
+ for i, p in enumerate(prepared[:_MAX_PREVIEW_SAMPLES]):
 
 
 
 
372
  question = (
373
  p.question if len(p.question) <= 60 else p.question[:57] + "..."
374
  )
 
401
  model = cached_model(model_name=model_name, remote=remote)
402
 
403
  try:
 
404
  total_steps = len(run_plan)
 
405
  results = []
406
+ for step, (persona, qa_pairs, variant) in enumerate(run_plan):
 
 
 
 
407
  progress.progress(
408
  step / total_steps if total_steps else 1.0,
409
+ text=f"{_row_label(persona, variant)} ({step + 1}/{total_steps})",
410
  )
411
+ results.extend(
412
+ run_extraction(
413
+ model=model,
414
+ model_name=model_name,
415
+ qa_pairs=qa_pairs[:max_questions],
416
+ variants=(variant,),
417
+ persona=persona,
418
+ mask_strategy=mask_strategy,
419
+ remote=remote,
420
+ on_status=_on_ndif_status if remote else None,
421
+ )
422
  )
 
 
423
 
424
  progress.progress(1.0, text="Extraction complete")
425
  except Exception as exc:
utils/chat.py CHANGED
@@ -5,11 +5,7 @@ from typing import Literal
5
 
6
  import torch
7
  from nnterp import StandardizedTransformer
8
- from persona_data.prompts import (
9
- _normalize_messages,
10
- format_roleplay_prompt,
11
- system_prompt_for_variant,
12
- )
13
  from persona_data.synth_persona import PersonaData
14
 
15
  logger = logging.getLogger(__name__)
@@ -42,7 +38,9 @@ def resolve_system_prompt(
42
  if mode == "custom":
43
  return format_roleplay_prompt(mode="conversational")
44
  if mode in ("templated", "biography"):
45
- return system_prompt_for_variant(persona, mode, mode="conversational")
 
 
46
  raise ValueError(f"Unsupported system prompt mode: {mode}")
47
 
48
 
 
5
 
6
  import torch
7
  from nnterp import StandardizedTransformer
8
+ from persona_data.prompts import _normalize_messages, format_roleplay_prompt
 
 
 
 
9
  from persona_data.synth_persona import PersonaData
10
 
11
  logger = logging.getLogger(__name__)
 
38
  if mode == "custom":
39
  return format_roleplay_prompt(mode="conversational")
40
  if mode in ("templated", "biography"):
41
+ return format_roleplay_prompt(
42
+ getattr(persona, f"{mode}_view"), mode="conversational"
43
+ )
44
  raise ValueError(f"Unsupported system prompt mode: {mode}")
45
 
46
 
utils/helpers.py CHANGED
@@ -5,6 +5,7 @@ from persona_data.synth_persona import PersonaData
5
  # Variant key -> human-readable label mapping
6
  VARIANT_LABELS = {
7
  "empty": "None",
 
8
  "templated": "Template",
9
  "biography": "Biography",
10
  "custom": "Custom",
 
5
  # Variant key -> human-readable label mapping
6
  VARIANT_LABELS = {
7
  "empty": "None",
8
+ "baseline": "Baseline",
9
  "templated": "Template",
10
  "biography": "Biography",
11
  "custom": "Custom",
uv.lock CHANGED
@@ -213,15 +213,16 @@ wheels = [
213
 
214
  [[package]]
215
  name = "choreographer"
216
- version = "1.2.1"
217
  source = { registry = "https://pypi.org/simple" }
218
  dependencies = [
219
  { name = "logistro" },
 
220
  { name = "simplejson" },
221
  ]
222
- sdist = { url = "https://files.pythonhosted.org/packages/74/47/64a035c6f764450ea9f902cbeba14c8c70316c2641125510066d8f912bfa/choreographer-1.2.1.tar.gz", hash = "sha256:022afd72b1e9b0bcb950420b134e70055a294c791b6f36cfb47d89745b701b5f", size = 43399, upload-time = "2025-11-09T23:04:44.749Z" }
223
  wheels = [
224
- { url = "https://files.pythonhosted.org/packages/b7/9f/d73dfb85d7a5b1a56a99adc50f2074029468168c970ff5daeade4ad819e4/choreographer-1.2.1-py3-none-any.whl", hash = "sha256:9af5385effa3c204dbc337abf7ac74fd8908ced326a15645dc31dde75718c77e", size = 49338, upload-time = "2025-11-09T23:04:43.154Z" },
225
  ]
226
 
227
  [[package]]
@@ -259,7 +260,7 @@ name = "cuda-bindings"
259
  version = "13.2.0"
260
  source = { registry = "https://pypi.org/simple" }
261
  dependencies = [
262
- { name = "cuda-pathfinder", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
263
  ]
264
  wheels = [
265
  { url = "https://files.pythonhosted.org/packages/52/c8/b2589d68acf7e3d63e2be330b84bc25712e97ed799affbca7edd7eae25d6/cuda_bindings-13.2.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e865447abfb83d6a98ad5130ed3c70b1fc295ae3eeee39fd07b4ddb0671b6788", size = 5722404, upload-time = "2026-03-11T00:12:44.041Z" },
@@ -290,37 +291,37 @@ wheels = [
290
 
291
  [package.optional-dependencies]
292
  cublas = [
293
- { name = "nvidia-cublas", marker = "sys_platform == 'linux'" },
294
  ]
295
  cudart = [
296
- { name = "nvidia-cuda-runtime", marker = "sys_platform == 'linux'" },
297
  ]
298
  cufft = [
299
- { name = "nvidia-cufft", marker = "sys_platform == 'linux'" },
300
  ]
301
  cufile = [
302
  { name = "nvidia-cufile", marker = "sys_platform == 'linux'" },
303
  ]
304
  cupti = [
305
- { name = "nvidia-cuda-cupti", marker = "sys_platform == 'linux'" },
306
  ]
307
  curand = [
308
- { name = "nvidia-curand", marker = "sys_platform == 'linux'" },
309
  ]
310
  cusolver = [
311
- { name = "nvidia-cusolver", marker = "sys_platform == 'linux'" },
312
  ]
313
  cusparse = [
314
- { name = "nvidia-cusparse", marker = "sys_platform == 'linux'" },
315
  ]
316
  nvjitlink = [
317
- { name = "nvidia-nvjitlink", marker = "sys_platform == 'linux'" },
318
  ]
319
  nvrtc = [
320
- { name = "nvidia-cuda-nvrtc", marker = "sys_platform == 'linux'" },
321
  ]
322
  nvtx = [
323
- { name = "nvidia-nvtx", marker = "sys_platform == 'linux'" },
324
  ]
325
 
326
  [[package]]
@@ -373,14 +374,14 @@ wheels = [
373
 
374
  [[package]]
375
  name = "gitpython"
376
- version = "3.1.48"
377
  source = { registry = "https://pypi.org/simple" }
378
  dependencies = [
379
  { name = "gitdb" },
380
  ]
381
- sdist = { url = "https://files.pythonhosted.org/packages/a6/c3/e4a9656f3cdb280f5dc65a68cc6fc46e79f897d27c1a36bbb4f0f47aaac5/gitpython-3.1.48.tar.gz", hash = "sha256:b7c49ff4a49946fce38ac84116efa311b15e7dad06dc3787fc9e206bf9ef75e1", size = 217288, upload-time = "2026-04-28T05:35:45.328Z" }
382
  wheels = [
383
- { url = "https://files.pythonhosted.org/packages/94/50/bb9703c364c00e7be67ccda03536f3d684766ce109d184c9d1f072d866ca/gitpython-3.1.48-py3-none-any.whl", hash = "sha256:737698b05889cca0f9aba7054d796620df2092c68926ee1470e5c7f5ac886680", size = 209800, upload-time = "2026-04-28T05:35:42.543Z" },
384
  ]
385
 
386
  [[package]]
@@ -437,6 +438,35 @@ wheels = [
437
  { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
438
  ]
439
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  [[package]]
441
  name = "httpx"
442
  version = "0.28.1"
@@ -454,7 +484,7 @@ wheels = [
454
 
455
  [[package]]
456
  name = "huggingface-hub"
457
- version = "1.12.0"
458
  source = { registry = "https://pypi.org/simple" }
459
  dependencies = [
460
  { name = "filelock" },
@@ -467,9 +497,9 @@ dependencies = [
467
  { name = "typer" },
468
  { name = "typing-extensions" },
469
  ]
470
- sdist = { url = "https://files.pythonhosted.org/packages/56/52/1b54cb569509c725a32c1315261ac9fd0e6b91bbbf74d86fca10d3376164/huggingface_hub-1.12.0.tar.gz", hash = "sha256:7c3fe85e24b652334e5d456d7a812cd9a071e75630fac4365d9165ab5e4a34b6", size = 763091, upload-time = "2026-04-24T13:32:08.674Z" }
471
  wheels = [
472
- { url = "https://files.pythonhosted.org/packages/7e/2b/ef03ddb96bd1123503c2bd6932001020292deea649e9bf4caa2cb65a85bf/huggingface_hub-1.12.0-py3-none-any.whl", hash = "sha256:d74939969585ee35748bd66de09baf84099d461bda7287cd9043bfb99b0e424d", size = 646806, upload-time = "2026-04-24T13:32:06.717Z" },
473
  ]
474
 
475
  [[package]]
@@ -524,6 +554,15 @@ wheels = [
524
  { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" },
525
  ]
526
 
 
 
 
 
 
 
 
 
 
527
  [[package]]
528
  name = "jedi"
529
  version = "0.19.2"
@@ -937,7 +976,7 @@ name = "nvidia-cudnn-cu13"
937
  version = "9.19.0.56"
938
  source = { registry = "https://pypi.org/simple" }
939
  dependencies = [
940
- { name = "nvidia-cublas", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
941
  ]
942
  wheels = [
943
  { url = "https://files.pythonhosted.org/packages/f1/84/26025437c1e6b61a707442184fa0c03d083b661adf3a3eecfd6d21677740/nvidia_cudnn_cu13-9.19.0.56-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:6ed29ffaee1176c612daf442e4dd6cfeb6a0caa43ddcbeb59da94953030b1be4", size = 433781201, upload-time = "2026-02-03T20:40:53.805Z" },
@@ -949,7 +988,7 @@ name = "nvidia-cufft"
949
  version = "12.0.0.61"
950
  source = { registry = "https://pypi.org/simple" }
951
  dependencies = [
952
- { name = "nvidia-nvjitlink", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
953
  ]
954
  wheels = [
955
  { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" },
@@ -979,9 +1018,9 @@ name = "nvidia-cusolver"
979
  version = "12.0.4.66"
980
  source = { registry = "https://pypi.org/simple" }
981
  dependencies = [
982
- { name = "nvidia-cublas", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
983
- { name = "nvidia-cusparse", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
984
- { name = "nvidia-nvjitlink", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
985
  ]
986
  wheels = [
987
  { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" },
@@ -993,7 +1032,7 @@ name = "nvidia-cusparse"
993
  version = "12.6.3.3"
994
  source = { registry = "https://pypi.org/simple" }
995
  dependencies = [
996
- { name = "nvidia-nvjitlink", marker = "sys_platform != 'emscripten' and sys_platform != 'win32'" },
997
  ]
998
  wheels = [
999
  { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" },
@@ -1170,7 +1209,7 @@ wheels = [
1170
 
1171
  [[package]]
1172
  name = "persona-data"
1173
- version = "0.2.3"
1174
  source = { registry = "https://pypi.org/simple" }
1175
  dependencies = [
1176
  { name = "huggingface-hub" },
@@ -1179,14 +1218,14 @@ dependencies = [
1179
  { name = "python-dotenv" },
1180
  { name = "torch" },
1181
  ]
1182
- sdist = { url = "https://files.pythonhosted.org/packages/76/1e/a0a2ba12a61b1b73149dde197f01305fce1d6b5fb79f4c931865d9286124/persona_data-0.2.3.tar.gz", hash = "sha256:6aa5570a5a5d85b7b2ec61ee7f0674c52a9e010ae655e56238ceb6c93e0959f4", size = 8692, upload-time = "2026-04-29T07:08:30.115Z" }
1183
  wheels = [
1184
- { url = "https://files.pythonhosted.org/packages/f4/5f/76cf58a938104de117bb869fbff028b1fc7dbaf3df164c526a9c395d5720/persona_data-0.2.3-py3-none-any.whl", hash = "sha256:5584fe720aa0eebf435edeb762fd7a0fe91b8aae4957c91ac5306efe48cfa1f1", size = 11357, upload-time = "2026-04-29T07:08:30.912Z" },
1185
  ]
1186
 
1187
  [[package]]
1188
  name = "persona-ui"
1189
- version = "0.1.1"
1190
  source = { virtual = "." }
1191
  dependencies = [
1192
  { name = "persona-data" },
@@ -1199,8 +1238,8 @@ dependencies = [
1199
 
1200
  [package.metadata]
1201
  requires-dist = [
1202
- { name = "persona-data", specifier = ">=0.2.3" },
1203
- { name = "persona-vectors", editable = "../persona-vectors" },
1204
  { name = "plotly", specifier = ">=6.6.0" },
1205
  { name = "python-dotenv", specifier = ">=1.2.2" },
1206
  { name = "streamlit", specifier = ">=1.44.0" },
@@ -1209,8 +1248,8 @@ requires-dist = [
1209
 
1210
  [[package]]
1211
  name = "persona-vectors"
1212
- version = "0.3.2"
1213
- source = { editable = "../persona-vectors" }
1214
  dependencies = [
1215
  { name = "kaleido" },
1216
  { name = "nnsight" },
@@ -1226,22 +1265,9 @@ dependencies = [
1226
  { name = "transformers" },
1227
  { name = "umap-learn" },
1228
  ]
1229
-
1230
- [package.metadata]
1231
- requires-dist = [
1232
- { name = "kaleido", specifier = ">=1.0.0" },
1233
- { name = "nnsight", specifier = ">=0.6.1" },
1234
- { name = "nnterp", specifier = ">=1.3.0" },
1235
- { name = "persona-data", specifier = ">=0.2.3" },
1236
- { name = "plotly", specifier = ">=6.6.0" },
1237
- { name = "python-dotenv", specifier = ">=1.2.2" },
1238
- { name = "safetensors", specifier = ">=0.7.0" },
1239
- { name = "scikit-learn", specifier = ">=1.6.0" },
1240
- { name = "torch", specifier = ">=2.10.0" },
1241
- { name = "torchvision", specifier = ">=0.26.0" },
1242
- { name = "tqdm", specifier = ">=4.67.3" },
1243
- { name = "transformers", specifier = ">=5.2.0" },
1244
- { name = "umap-learn", specifier = ">=0.5.7" },
1245
  ]
1246
 
1247
  [[package]]
@@ -1325,6 +1351,15 @@ wheels = [
1325
  { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" },
1326
  ]
1327
 
 
 
 
 
 
 
 
 
 
1328
  [[package]]
1329
  name = "plotly"
1330
  version = "6.7.0"
@@ -1652,6 +1687,15 @@ wheels = [
1652
  { url = "https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl", hash = "sha256:f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399", size = 59847, upload-time = "2026-02-06T23:38:04.861Z" },
1653
  ]
1654
 
 
 
 
 
 
 
 
 
 
1655
  [[package]]
1656
  name = "python-socketio"
1657
  version = "5.16.1"
@@ -2170,16 +2214,32 @@ wheels = [
2170
  { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" },
2171
  ]
2172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2173
  [[package]]
2174
  name = "streamlit"
2175
- version = "1.56.0"
2176
  source = { registry = "https://pypi.org/simple" }
2177
  dependencies = [
2178
  { name = "altair" },
 
2179
  { name = "blinker" },
2180
  { name = "cachetools" },
2181
  { name = "click" },
2182
  { name = "gitpython" },
 
 
2183
  { name = "numpy" },
2184
  { name = "packaging" },
2185
  { name = "pandas" },
@@ -2187,16 +2247,19 @@ dependencies = [
2187
  { name = "protobuf" },
2188
  { name = "pyarrow" },
2189
  { name = "pydeck" },
 
2190
  { name = "requests" },
 
2191
  { name = "tenacity" },
2192
  { name = "toml" },
2193
- { name = "tornado" },
2194
  { name = "typing-extensions" },
 
2195
  { name = "watchdog", marker = "sys_platform != 'darwin'" },
 
2196
  ]
2197
- sdist = { url = "https://files.pythonhosted.org/packages/03/85/7c669b3a1336d34ef39fa9760fbd343185f3b15db2ad0838fd78423d1c7f/streamlit-1.56.0.tar.gz", hash = "sha256:1176acfa89ae1318b79078e8efe689a9d02e8d58e325c00fc0e55fa2f3fe8d6a", size = 8559239, upload-time = "2026-03-31T22:29:38.59Z" }
2198
  wheels = [
2199
- { url = "https://files.pythonhosted.org/packages/e4/91/cb6f13a89e376ef179309d74f37a70ea0041d5e4b5ba5c4836dbf6e020ad/streamlit-1.56.0-py3-none-any.whl", hash = "sha256:8677a335734a30a51bc57ad0ec910e365d95f7c456fc02c60032927cd0729dc5", size = 9052089, upload-time = "2026-03-31T22:29:36.342Z" },
2200
  ]
2201
 
2202
  [[package]]
@@ -2339,23 +2402,6 @@ wheels = [
2339
  { url = "https://files.pythonhosted.org/packages/d0/6a/09f3844c10643f6c0de5d95abc863420cfaf194c88c7dffd0ac523e2015f/torchvision-0.26.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e9d0e022c19a78552fb055d0414d47fecb4a649309b9968573daea160ba6869c", size = 4454275, upload-time = "2026-03-23T18:12:27.487Z" },
2340
  ]
2341
 
2342
- [[package]]
2343
- name = "tornado"
2344
- version = "6.5.5"
2345
- source = { registry = "https://pypi.org/simple" }
2346
- sdist = { url = "https://files.pythonhosted.org/packages/f8/f1/3173dfa4a18db4a9b03e5d55325559dab51ee653763bb8745a75af491286/tornado-6.5.5.tar.gz", hash = "sha256:192b8f3ea91bd7f1f50c06955416ed76c6b72f96779b962f07f911b91e8d30e9", size = 516006, upload-time = "2026-03-10T21:31:02.067Z" }
2347
- wheels = [
2348
- { url = "https://files.pythonhosted.org/packages/59/8c/77f5097695f4dd8255ecbd08b2a1ed8ba8b953d337804dd7080f199e12bf/tornado-6.5.5-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:487dc9cc380e29f58c7ab88f9e27cdeef04b2140862e5076a66fb6bb68bb1bfa", size = 445983, upload-time = "2026-03-10T21:30:44.28Z" },
2349
- { url = "https://files.pythonhosted.org/packages/ab/5e/7625b76cd10f98f1516c36ce0346de62061156352353ef2da44e5c21523c/tornado-6.5.5-cp39-abi3-macosx_10_9_x86_64.whl", hash = "sha256:65a7f1d46d4bb41df1ac99f5fcb685fb25c7e61613742d5108b010975a9a6521", size = 444246, upload-time = "2026-03-10T21:30:46.571Z" },
2350
- { url = "https://files.pythonhosted.org/packages/b2/04/7b5705d5b3c0fab088f434f9c83edac1573830ca49ccf29fb83bf7178eec/tornado-6.5.5-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e74c92e8e65086b338fd56333fb9a68b9f6f2fe7ad532645a290a464bcf46be5", size = 447229, upload-time = "2026-03-10T21:30:48.273Z" },
2351
- { url = "https://files.pythonhosted.org/packages/34/01/74e034a30ef59afb4097ef8659515e96a39d910b712a89af76f5e4e1f93c/tornado-6.5.5-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:435319e9e340276428bbdb4e7fa732c2d399386d1de5686cb331ec8eee754f07", size = 448192, upload-time = "2026-03-10T21:30:51.22Z" },
2352
- { url = "https://files.pythonhosted.org/packages/be/00/fe9e02c5a96429fce1a1d15a517f5d8444f9c412e0bb9eadfbe3b0fc55bf/tornado-6.5.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3f54aa540bdbfee7b9eb268ead60e7d199de5021facd276819c193c0fb28ea4e", size = 448039, upload-time = "2026-03-10T21:30:53.52Z" },
2353
- { url = "https://files.pythonhosted.org/packages/82/9e/656ee4cec0398b1d18d0f1eb6372c41c6b889722641d84948351ae19556d/tornado-6.5.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:36abed1754faeb80fbd6e64db2758091e1320f6bba74a4cf8c09cd18ccce8aca", size = 447445, upload-time = "2026-03-10T21:30:55.541Z" },
2354
- { url = "https://files.pythonhosted.org/packages/5a/76/4921c00511f88af86a33de770d64141170f1cfd9c00311aea689949e274e/tornado-6.5.5-cp39-abi3-win32.whl", hash = "sha256:dd3eafaaeec1c7f2f8fdcd5f964e8907ad788fe8a5a32c4426fbbdda621223b7", size = 448582, upload-time = "2026-03-10T21:30:57.142Z" },
2355
- { url = "https://files.pythonhosted.org/packages/2c/23/f6c6112a04d28eed765e374435fb1a9198f73e1ec4b4024184f21faeb1ad/tornado-6.5.5-cp39-abi3-win_amd64.whl", hash = "sha256:6443a794ba961a9f619b1ae926a2e900ac20c34483eea67be4ed8f1e58d3ef7b", size = 448990, upload-time = "2026-03-10T21:30:58.857Z" },
2356
- { url = "https://files.pythonhosted.org/packages/b7/c8/876602cbc96469911f0939f703453c1157b0c826ecb05bdd32e023397d4e/tornado-6.5.5-cp39-abi3-win_arm64.whl", hash = "sha256:2c9a876e094109333f888539ddb2de4361743e5d21eece20688e3e351e4990a6", size = 448016, upload-time = "2026-03-10T21:31:00.43Z" },
2357
- ]
2358
-
2359
  [[package]]
2360
  name = "tqdm"
2361
  version = "4.67.3"
@@ -2379,7 +2425,7 @@ wheels = [
2379
 
2380
  [[package]]
2381
  name = "transformers"
2382
- version = "5.6.2"
2383
  source = { registry = "https://pypi.org/simple" }
2384
  dependencies = [
2385
  { name = "huggingface-hub" },
@@ -2392,9 +2438,9 @@ dependencies = [
2392
  { name = "tqdm" },
2393
  { name = "typer" },
2394
  ]
2395
- sdist = { url = "https://files.pythonhosted.org/packages/a4/e9/c6c80a07690142a7d05444271f47b9f3c8aac7dea01d52e1137ee480ad78/transformers-5.6.2.tar.gz", hash = "sha256:e657134c3e5a6bc00a3c35f4e2674bb51adfcd89898495b788a18552bac2b91a", size = 8311867, upload-time = "2026-04-23T18:33:29.332Z" }
2396
  wheels = [
2397
- { url = "https://files.pythonhosted.org/packages/5d/95/0b0218149b0d6f14df35f5b8f676fa83df4f19ed253c3cc447107ef86eca/transformers-5.6.2-py3-none-any.whl", hash = "sha256:f8d3a1bb96778fed9b8aabfd0dd6e19843e4b0f2bb6b59f32b8a92051b0f348f", size = 10364898, upload-time = "2026-04-23T18:33:26.081Z" },
2398
  ]
2399
 
2400
  [[package]]
@@ -2485,6 +2531,19 @@ wheels = [
2485
  { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
2486
  ]
2487
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2488
  [[package]]
2489
  name = "watchdog"
2490
  version = "6.0.0"
@@ -2521,6 +2580,51 @@ wheels = [
2521
  { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616, upload-time = "2025-10-07T21:16:34.951Z" },
2522
  ]
2523
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2524
  [[package]]
2525
  name = "wsproto"
2526
  version = "1.3.2"
 
213
 
214
  [[package]]
215
  name = "choreographer"
216
+ version = "1.3.0"
217
  source = { registry = "https://pypi.org/simple" }
218
  dependencies = [
219
  { name = "logistro" },
220
+ { name = "platformdirs" },
221
  { name = "simplejson" },
222
  ]
223
+ sdist = { url = "https://files.pythonhosted.org/packages/17/69/3058cd4f16d6b75c80e8f95e5b713d930526353ce294df9a7887453ba215/choreographer-1.3.0.tar.gz", hash = "sha256:6c44a0e48e9b37977344d40bfa5a9ed88575fe4bc0fd836771bf702bc24d6884", size = 48291, upload-time = "2026-04-28T22:57:45.114Z" }
224
  wheels = [
225
+ { url = "https://files.pythonhosted.org/packages/ba/6c/ff8bf52315064dbeb55cb5067e191120a5b2e58bb648d0d34cf7969dc2c2/choreographer-1.3.0-py3-none-any.whl", hash = "sha256:cea4cb739e4f61625e4b53888a8d3fa1d3bf73948b56753e460ab44da7d8d44f", size = 52622, upload-time = "2026-04-28T22:57:44.015Z" },
226
  ]
227
 
228
  [[package]]
 
260
  version = "13.2.0"
261
  source = { registry = "https://pypi.org/simple" }
262
  dependencies = [
263
+ { name = "cuda-pathfinder" },
264
  ]
265
  wheels = [
266
  { url = "https://files.pythonhosted.org/packages/52/c8/b2589d68acf7e3d63e2be330b84bc25712e97ed799affbca7edd7eae25d6/cuda_bindings-13.2.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e865447abfb83d6a98ad5130ed3c70b1fc295ae3eeee39fd07b4ddb0671b6788", size = 5722404, upload-time = "2026-03-11T00:12:44.041Z" },
 
291
 
292
  [package.optional-dependencies]
293
  cublas = [
294
+ { name = "nvidia-cublas", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
295
  ]
296
  cudart = [
297
+ { name = "nvidia-cuda-runtime", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
298
  ]
299
  cufft = [
300
+ { name = "nvidia-cufft", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
301
  ]
302
  cufile = [
303
  { name = "nvidia-cufile", marker = "sys_platform == 'linux'" },
304
  ]
305
  cupti = [
306
+ { name = "nvidia-cuda-cupti", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
307
  ]
308
  curand = [
309
+ { name = "nvidia-curand", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
310
  ]
311
  cusolver = [
312
+ { name = "nvidia-cusolver", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
313
  ]
314
  cusparse = [
315
+ { name = "nvidia-cusparse", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
316
  ]
317
  nvjitlink = [
318
+ { name = "nvidia-nvjitlink", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
319
  ]
320
  nvrtc = [
321
+ { name = "nvidia-cuda-nvrtc", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
322
  ]
323
  nvtx = [
324
+ { name = "nvidia-nvtx", marker = "sys_platform == 'linux' or sys_platform == 'win32'" },
325
  ]
326
 
327
  [[package]]
 
374
 
375
  [[package]]
376
  name = "gitpython"
377
+ version = "3.1.49"
378
  source = { registry = "https://pypi.org/simple" }
379
  dependencies = [
380
  { name = "gitdb" },
381
  ]
382
+ sdist = { url = "https://files.pythonhosted.org/packages/e1/63/210aaa302d6a0a78daa67c5c15bbac2cad361722841278b0209b6da20855/gitpython-3.1.49.tar.gz", hash = "sha256:42f9399c9eb33fc581014bedd76049dfbaf6375aa2a5754575966387280315e1", size = 219367, upload-time = "2026-04-29T00:31:20.478Z" }
383
  wheels = [
384
+ { url = "https://files.pythonhosted.org/packages/fd/6f/b842bfa6f21d6f87c57f9abf7194225e55279d96d869775e19e9f7236fc5/gitpython-3.1.49-py3-none-any.whl", hash = "sha256:024b0422d7f84d15cd794844e029ffebd4c5d42a7eb9b936b458697ef550a02c", size = 212190, upload-time = "2026-04-29T00:31:18.412Z" },
385
  ]
386
 
387
  [[package]]
 
438
  { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
439
  ]
440
 
441
+ [[package]]
442
+ name = "httptools"
443
+ version = "0.7.1"
444
+ source = { registry = "https://pypi.org/simple" }
445
+ sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" }
446
+ wheels = [
447
+ { url = "https://files.pythonhosted.org/packages/53/7f/403e5d787dc4942316e515e949b0c8a013d84078a915910e9f391ba9b3ed/httptools-0.7.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:38e0c83a2ea9746ebbd643bdfb521b9aa4a91703e2cd705c20443405d2fd16a5", size = 206280, upload-time = "2025-10-10T03:54:39.274Z" },
448
+ { url = "https://files.pythonhosted.org/packages/2a/0d/7f3fd28e2ce311ccc998c388dd1c53b18120fda3b70ebb022b135dc9839b/httptools-0.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f25bbaf1235e27704f1a7b86cd3304eabc04f569c828101d94a0e605ef7205a5", size = 110004, upload-time = "2025-10-10T03:54:40.403Z" },
449
+ { url = "https://files.pythonhosted.org/packages/84/a6/b3965e1e146ef5762870bbe76117876ceba51a201e18cc31f5703e454596/httptools-0.7.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c15f37ef679ab9ecc06bfc4e6e8628c32a8e4b305459de7cf6785acd57e4d03", size = 517655, upload-time = "2025-10-10T03:54:41.347Z" },
450
+ { url = "https://files.pythonhosted.org/packages/11/7d/71fee6f1844e6fa378f2eddde6c3e41ce3a1fb4b2d81118dd544e3441ec0/httptools-0.7.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7fe6e96090df46b36ccfaf746f03034e5ab723162bc51b0a4cf58305324036f2", size = 511440, upload-time = "2025-10-10T03:54:42.452Z" },
451
+ { url = "https://files.pythonhosted.org/packages/22/a5/079d216712a4f3ffa24af4a0381b108aa9c45b7a5cc6eb141f81726b1823/httptools-0.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f72fdbae2dbc6e68b8239defb48e6a5937b12218e6ffc2c7846cc37befa84362", size = 495186, upload-time = "2025-10-10T03:54:43.937Z" },
452
+ { url = "https://files.pythonhosted.org/packages/e9/9e/025ad7b65278745dee3bd0ebf9314934c4592560878308a6121f7f812084/httptools-0.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e99c7b90a29fd82fea9ef57943d501a16f3404d7b9ee81799d41639bdaae412c", size = 499192, upload-time = "2025-10-10T03:54:45.003Z" },
453
+ { url = "https://files.pythonhosted.org/packages/6d/de/40a8f202b987d43afc4d54689600ff03ce65680ede2f31df348d7f368b8f/httptools-0.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:3e14f530fefa7499334a79b0cf7e7cd2992870eb893526fb097d51b4f2d0f321", size = 86694, upload-time = "2025-10-10T03:54:45.923Z" },
454
+ { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" },
455
+ { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" },
456
+ { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" },
457
+ { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" },
458
+ { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" },
459
+ { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" },
460
+ { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" },
461
+ { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" },
462
+ { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" },
463
+ { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" },
464
+ { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" },
465
+ { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" },
466
+ { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" },
467
+ { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" },
468
+ ]
469
+
470
  [[package]]
471
  name = "httpx"
472
  version = "0.28.1"
 
484
 
485
  [[package]]
486
  name = "huggingface-hub"
487
+ version = "1.12.2"
488
  source = { registry = "https://pypi.org/simple" }
489
  dependencies = [
490
  { name = "filelock" },
 
497
  { name = "typer" },
498
  { name = "typing-extensions" },
499
  ]
500
+ sdist = { url = "https://files.pythonhosted.org/packages/3e/9f/3fda8b014db3ae239addc9b48b35c2cf7d318950b430712f34a2473ef81d/huggingface_hub-1.12.2.tar.gz", hash = "sha256:282c4999e641c89affdc4c02c265eddea944c1390dc19e89dac8ad3ae76dbdaf", size = 763393, upload-time = "2026-04-29T09:45:09.202Z" }
501
  wheels = [
502
+ { url = "https://files.pythonhosted.org/packages/71/c1/1fa4162f6dd53259daf2ad31385273341821fa0acce164cd03971937a60e/huggingface_hub-1.12.2-py3-none-any.whl", hash = "sha256:7968e897fdbc6343c871c240d87d4434efe0ad9f80d57daa1cc5678c6d148529", size = 647757, upload-time = "2026-04-29T09:45:07.63Z" },
503
  ]
504
 
505
  [[package]]
 
554
  { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" },
555
  ]
556
 
557
+ [[package]]
558
+ name = "itsdangerous"
559
+ version = "2.2.0"
560
+ source = { registry = "https://pypi.org/simple" }
561
+ sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" }
562
+ wheels = [
563
+ { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" },
564
+ ]
565
+
566
  [[package]]
567
  name = "jedi"
568
  version = "0.19.2"
 
976
  version = "9.19.0.56"
977
  source = { registry = "https://pypi.org/simple" }
978
  dependencies = [
979
+ { name = "nvidia-cublas" },
980
  ]
981
  wheels = [
982
  { url = "https://files.pythonhosted.org/packages/f1/84/26025437c1e6b61a707442184fa0c03d083b661adf3a3eecfd6d21677740/nvidia_cudnn_cu13-9.19.0.56-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:6ed29ffaee1176c612daf442e4dd6cfeb6a0caa43ddcbeb59da94953030b1be4", size = 433781201, upload-time = "2026-02-03T20:40:53.805Z" },
 
988
  version = "12.0.0.61"
989
  source = { registry = "https://pypi.org/simple" }
990
  dependencies = [
991
+ { name = "nvidia-nvjitlink" },
992
  ]
993
  wheels = [
994
  { url = "https://files.pythonhosted.org/packages/8b/ae/f417a75c0259e85c1d2f83ca4e960289a5f814ed0cea74d18c353d3e989d/nvidia_cufft-12.0.0.61-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2708c852ef8cd89d1d2068bdbece0aa188813a0c934db3779b9b1faa8442e5f5", size = 214053554, upload-time = "2025-09-04T08:31:38.196Z" },
 
1018
  version = "12.0.4.66"
1019
  source = { registry = "https://pypi.org/simple" }
1020
  dependencies = [
1021
+ { name = "nvidia-cublas" },
1022
+ { name = "nvidia-cusparse" },
1023
+ { name = "nvidia-nvjitlink" },
1024
  ]
1025
  wheels = [
1026
  { url = "https://files.pythonhosted.org/packages/c8/c3/b30c9e935fc01e3da443ec0116ed1b2a009bb867f5324d3f2d7e533e776b/nvidia_cusolver-12.0.4.66-py3-none-manylinux_2_27_aarch64.whl", hash = "sha256:02c2457eaa9e39de20f880f4bd8820e6a1cfb9f9a34f820eb12a155aa5bc92d2", size = 223467760, upload-time = "2025-09-04T08:33:04.222Z" },
 
1032
  version = "12.6.3.3"
1033
  source = { registry = "https://pypi.org/simple" }
1034
  dependencies = [
1035
+ { name = "nvidia-nvjitlink" },
1036
  ]
1037
  wheels = [
1038
  { url = "https://files.pythonhosted.org/packages/f8/94/5c26f33738ae35276672f12615a64bd008ed5be6d1ebcb23579285d960a9/nvidia_cusparse-12.6.3.3-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:80bcc4662f23f1054ee334a15c72b8940402975e0eab63178fc7e670aa59472c", size = 162155568, upload-time = "2025-09-04T08:33:42.864Z" },
 
1209
 
1210
  [[package]]
1211
  name = "persona-data"
1212
+ version = "0.2.5"
1213
  source = { registry = "https://pypi.org/simple" }
1214
  dependencies = [
1215
  { name = "huggingface-hub" },
 
1218
  { name = "python-dotenv" },
1219
  { name = "torch" },
1220
  ]
1221
+ sdist = { url = "https://files.pythonhosted.org/packages/e2/93/694d05273378f142c188b8a4826f962c89d1f449ed5949806a98a3912647/persona_data-0.2.5.tar.gz", hash = "sha256:d20a55fe488d61034ab2449a460e744a99a3aaa3ead128e5fe832ea14eb31c51", size = 8546, upload-time = "2026-04-29T09:25:59.28Z" }
1222
  wheels = [
1223
+ { url = "https://files.pythonhosted.org/packages/de/06/6f81542a68c97fbbc6fabae7b4f406b046c61787977f623199172292bd5e/persona_data-0.2.5-py3-none-any.whl", hash = "sha256:70e8caa15ab31e8a2bd1e248d02acf118a43725acd262b10b594ee754986f2a9", size = 11199, upload-time = "2026-04-29T09:25:58.119Z" },
1224
  ]
1225
 
1226
  [[package]]
1227
  name = "persona-ui"
1228
+ version = "0.2.0"
1229
  source = { virtual = "." }
1230
  dependencies = [
1231
  { name = "persona-data" },
 
1238
 
1239
  [package.metadata]
1240
  requires-dist = [
1241
+ { name = "persona-data", specifier = ">=0.2.5" },
1242
+ { name = "persona-vectors", specifier = ">=0.4.0" },
1243
  { name = "plotly", specifier = ">=6.6.0" },
1244
  { name = "python-dotenv", specifier = ">=1.2.2" },
1245
  { name = "streamlit", specifier = ">=1.44.0" },
 
1248
 
1249
  [[package]]
1250
  name = "persona-vectors"
1251
+ version = "0.4.0"
1252
+ source = { registry = "https://pypi.org/simple" }
1253
  dependencies = [
1254
  { name = "kaleido" },
1255
  { name = "nnsight" },
 
1265
  { name = "transformers" },
1266
  { name = "umap-learn" },
1267
  ]
1268
+ sdist = { url = "https://files.pythonhosted.org/packages/c4/f8/b2b9f8f6d7510c15e7a90d9f01c2df059cd3132c50ebd28f358a13cc1660/persona_vectors-0.4.0.tar.gz", hash = "sha256:e3057f7217f6c179eb003f50973e16160230d9c430fcc2f1380e0633c1c596dd", size = 20830, upload-time = "2026-04-29T09:40:01.563Z" }
1269
+ wheels = [
1270
+ { url = "https://files.pythonhosted.org/packages/57/53/8266e7649c7e565bad92a14d7dc439f58dba9b64871e68ff887fed4214b6/persona_vectors-0.4.0-py3-none-any.whl", hash = "sha256:d305728fe83db2c302b3d049084f84d6a8da5b4698950033e789249c723270d3", size = 24732, upload-time = "2026-04-29T09:40:00.405Z" },
 
 
 
 
 
 
 
 
 
 
 
 
 
1271
  ]
1272
 
1273
  [[package]]
 
1351
  { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" },
1352
  ]
1353
 
1354
+ [[package]]
1355
+ name = "platformdirs"
1356
+ version = "4.9.6"
1357
+ source = { registry = "https://pypi.org/simple" }
1358
+ sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" }
1359
+ wheels = [
1360
+ { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" },
1361
+ ]
1362
+
1363
  [[package]]
1364
  name = "plotly"
1365
  version = "6.7.0"
 
1687
  { url = "https://files.pythonhosted.org/packages/aa/54/0cce26da03a981f949bb8449c9778537f75f5917c172e1d2992ff25cb57d/python_engineio-4.13.1-py3-none-any.whl", hash = "sha256:f32ad10589859c11053ad7d9bb3c9695cdf862113bfb0d20bc4d890198287399", size = 59847, upload-time = "2026-02-06T23:38:04.861Z" },
1688
  ]
1689
 
1690
+ [[package]]
1691
+ name = "python-multipart"
1692
+ version = "0.0.27"
1693
+ source = { registry = "https://pypi.org/simple" }
1694
+ 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" }
1695
+ wheels = [
1696
+ { 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" },
1697
+ ]
1698
+
1699
  [[package]]
1700
  name = "python-socketio"
1701
  version = "5.16.1"
 
2214
  { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" },
2215
  ]
2216
 
2217
+ [[package]]
2218
+ name = "starlette"
2219
+ version = "1.0.0"
2220
+ source = { registry = "https://pypi.org/simple" }
2221
+ dependencies = [
2222
+ { name = "anyio" },
2223
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
2224
+ ]
2225
+ sdist = { url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hash = "sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149", size = 2655289, upload-time = "2026-03-22T18:29:46.779Z" }
2226
+ wheels = [
2227
+ { url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl", hash = "sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b", size = 72651, upload-time = "2026-03-22T18:29:45.111Z" },
2228
+ ]
2229
+
2230
  [[package]]
2231
  name = "streamlit"
2232
+ version = "1.57.0"
2233
  source = { registry = "https://pypi.org/simple" }
2234
  dependencies = [
2235
  { name = "altair" },
2236
+ { name = "anyio" },
2237
  { name = "blinker" },
2238
  { name = "cachetools" },
2239
  { name = "click" },
2240
  { name = "gitpython" },
2241
+ { name = "httptools" },
2242
+ { name = "itsdangerous" },
2243
  { name = "numpy" },
2244
  { name = "packaging" },
2245
  { name = "pandas" },
 
2247
  { name = "protobuf" },
2248
  { name = "pyarrow" },
2249
  { name = "pydeck" },
2250
+ { name = "python-multipart" },
2251
  { name = "requests" },
2252
+ { name = "starlette" },
2253
  { name = "tenacity" },
2254
  { name = "toml" },
 
2255
  { name = "typing-extensions" },
2256
+ { name = "uvicorn" },
2257
  { name = "watchdog", marker = "sys_platform != 'darwin'" },
2258
+ { name = "websockets" },
2259
  ]
2260
+ sdist = { url = "https://files.pythonhosted.org/packages/5d/f8/b2daf7a5f8ae15527daf94406e771bb6075e958a01c3dde9eba79dc3c9a3/streamlit-1.57.0.tar.gz", hash = "sha256:0b028d305c1a1a757071b2c9504966787602842fc8af6e873795ca58d2b4d12f", size = 8678859, upload-time = "2026-04-28T22:13:32.238Z" }
2261
  wheels = [
2262
+ { url = "https://files.pythonhosted.org/packages/d8/1a/3ca2293d8552bacea3e67e9600d2d1df7df4a325059769ad83d91c279595/streamlit-1.57.0-py3-none-any.whl", hash = "sha256:0d1d41972aeade5637dbb0e7f0eefa5312272f85304923d240a1b1f0475249c8", size = 9194216, upload-time = "2026-04-28T22:13:29.624Z" },
2263
  ]
2264
 
2265
  [[package]]
 
2402
  { url = "https://files.pythonhosted.org/packages/d0/6a/09f3844c10643f6c0de5d95abc863420cfaf194c88c7dffd0ac523e2015f/torchvision-0.26.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e9d0e022c19a78552fb055d0414d47fecb4a649309b9968573daea160ba6869c", size = 4454275, upload-time = "2026-03-23T18:12:27.487Z" },
2403
  ]
2404
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2405
  [[package]]
2406
  name = "tqdm"
2407
  version = "4.67.3"
 
2425
 
2426
  [[package]]
2427
  name = "transformers"
2428
+ version = "5.7.0"
2429
  source = { registry = "https://pypi.org/simple" }
2430
  dependencies = [
2431
  { name = "huggingface-hub" },
 
2438
  { name = "tqdm" },
2439
  { name = "typer" },
2440
  ]
2441
+ sdist = { url = "https://files.pythonhosted.org/packages/4d/fe/7e84d20ac7d4d5d14bac2eab5976088d86342959fc2c0da54b4c2fc99856/transformers-5.7.0.tar.gz", hash = "sha256:a9d35cf39804e3456c1f9bc1a79ad5ffa878640a61f51f66f71c97f4b4e2ce10", size = 8401287, upload-time = "2026-04-28T18:30:09.75Z" }
2442
  wheels = [
2443
+ { url = "https://files.pythonhosted.org/packages/60/60/86a9fe3037bec221094e2acb680219ad88b77006edba42fc0407a577ca93/transformers-5.7.0-py3-none-any.whl", hash = "sha256:869660cd8fc92badc041f5551bf755a42f4b9558c93341bf3fa3eeed7065079c", size = 10474236, upload-time = "2026-04-28T18:30:05.655Z" },
2444
  ]
2445
 
2446
  [[package]]
 
2531
  { url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
2532
  ]
2533
 
2534
+ [[package]]
2535
+ name = "uvicorn"
2536
+ version = "0.46.0"
2537
+ source = { registry = "https://pypi.org/simple" }
2538
+ dependencies = [
2539
+ { name = "click" },
2540
+ { name = "h11" },
2541
+ ]
2542
+ sdist = { url = "https://files.pythonhosted.org/packages/1f/93/041fca8274050e40e6791f267d82e0e2e27dd165627bd640d3e0e378d877/uvicorn-0.46.0.tar.gz", hash = "sha256:fb9da0926999cc6cb22dc7cd71a94a632f078e6ae47ff683c5c420750fb7413d", size = 88758, upload-time = "2026-04-23T07:16:00.151Z" }
2543
+ wheels = [
2544
+ { url = "https://files.pythonhosted.org/packages/31/a3/5b1562db76a5a488274b2332a97199b32d0442aca0ed193697fd47786316/uvicorn-0.46.0-py3-none-any.whl", hash = "sha256:bbebbcbed972d162afca128605223022bedd345b7bc7855ce66deb31487a9048", size = 70926, upload-time = "2026-04-23T07:15:58.355Z" },
2545
+ ]
2546
+
2547
  [[package]]
2548
  name = "watchdog"
2549
  version = "6.0.0"
 
2580
  { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616, upload-time = "2025-10-07T21:16:34.951Z" },
2581
  ]
2582
 
2583
+ [[package]]
2584
+ name = "websockets"
2585
+ version = "16.0"
2586
+ source = { registry = "https://pypi.org/simple" }
2587
+ sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" }
2588
+ wheels = [
2589
+ { url = "https://files.pythonhosted.org/packages/84/7b/bac442e6b96c9d25092695578dda82403c77936104b5682307bd4deb1ad4/websockets-16.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:71c989cbf3254fbd5e84d3bff31e4da39c43f884e64f2551d14bb3c186230f00", size = 177365, upload-time = "2026-01-10T09:22:46.787Z" },
2590
+ { url = "https://files.pythonhosted.org/packages/b0/fe/136ccece61bd690d9c1f715baaeefd953bb2360134de73519d5df19d29ca/websockets-16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:8b6e209ffee39ff1b6d0fa7bfef6de950c60dfb91b8fcead17da4ee539121a79", size = 175038, upload-time = "2026-01-10T09:22:47.999Z" },
2591
+ { url = "https://files.pythonhosted.org/packages/40/1e/9771421ac2286eaab95b8575b0cb701ae3663abf8b5e1f64f1fd90d0a673/websockets-16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:86890e837d61574c92a97496d590968b23c2ef0aeb8a9bc9421d174cd378ae39", size = 175328, upload-time = "2026-01-10T09:22:49.809Z" },
2592
+ { url = "https://files.pythonhosted.org/packages/18/29/71729b4671f21e1eaa5d6573031ab810ad2936c8175f03f97f3ff164c802/websockets-16.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9b5aca38b67492ef518a8ab76851862488a478602229112c4b0d58d63a7a4d5c", size = 184915, upload-time = "2026-01-10T09:22:51.071Z" },
2593
+ { url = "https://files.pythonhosted.org/packages/97/bb/21c36b7dbbafc85d2d480cd65df02a1dc93bf76d97147605a8e27ff9409d/websockets-16.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e0334872c0a37b606418ac52f6ab9cfd17317ac26365f7f65e203e2d0d0d359f", size = 186152, upload-time = "2026-01-10T09:22:52.224Z" },
2594
+ { url = "https://files.pythonhosted.org/packages/4a/34/9bf8df0c0cf88fa7bfe36678dc7b02970c9a7d5e065a3099292db87b1be2/websockets-16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a0b31e0b424cc6b5a04b8838bbaec1688834b2383256688cf47eb97412531da1", size = 185583, upload-time = "2026-01-10T09:22:53.443Z" },
2595
+ { url = "https://files.pythonhosted.org/packages/47/88/4dd516068e1a3d6ab3c7c183288404cd424a9a02d585efbac226cb61ff2d/websockets-16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:485c49116d0af10ac698623c513c1cc01c9446c058a4e61e3bf6c19dff7335a2", size = 184880, upload-time = "2026-01-10T09:22:55.033Z" },
2596
+ { url = "https://files.pythonhosted.org/packages/91/d6/7d4553ad4bf1c0421e1ebd4b18de5d9098383b5caa1d937b63df8d04b565/websockets-16.0-cp312-cp312-win32.whl", hash = "sha256:eaded469f5e5b7294e2bdca0ab06becb6756ea86894a47806456089298813c89", size = 178261, upload-time = "2026-01-10T09:22:56.251Z" },
2597
+ { url = "https://files.pythonhosted.org/packages/c3/f0/f3a17365441ed1c27f850a80b2bc680a0fa9505d733fe152fdf5e98c1c0b/websockets-16.0-cp312-cp312-win_amd64.whl", hash = "sha256:5569417dc80977fc8c2d43a86f78e0a5a22fee17565d78621b6bb264a115d4ea", size = 178693, upload-time = "2026-01-10T09:22:57.478Z" },
2598
+ { url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364, upload-time = "2026-01-10T09:22:59.333Z" },
2599
+ { url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039, upload-time = "2026-01-10T09:23:01.171Z" },
2600
+ { url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323, upload-time = "2026-01-10T09:23:02.341Z" },
2601
+ { url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975, upload-time = "2026-01-10T09:23:03.756Z" },
2602
+ { url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203, upload-time = "2026-01-10T09:23:05.01Z" },
2603
+ { url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653, upload-time = "2026-01-10T09:23:06.301Z" },
2604
+ { url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920, upload-time = "2026-01-10T09:23:07.492Z" },
2605
+ { url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255, upload-time = "2026-01-10T09:23:09.245Z" },
2606
+ { url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689, upload-time = "2026-01-10T09:23:10.483Z" },
2607
+ { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" },
2608
+ { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" },
2609
+ { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" },
2610
+ { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" },
2611
+ { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" },
2612
+ { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" },
2613
+ { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" },
2614
+ { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" },
2615
+ { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" },
2616
+ { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" },
2617
+ { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" },
2618
+ { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" },
2619
+ { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" },
2620
+ { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" },
2621
+ { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" },
2622
+ { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" },
2623
+ { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" },
2624
+ { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" },
2625
+ { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" },
2626
+ ]
2627
+
2628
  [[package]]
2629
  name = "wsproto"
2630
  version = "1.3.2"