variably-sdk 2.7.1__tar.gz → 2.9.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/PKG-INFO +1 -1
  2. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/pyproject.toml +1 -1
  3. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/client.py +63 -3
  4. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/version.py +1 -1
  5. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably_sdk.egg-info/PKG-INFO +1 -1
  6. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/README.md +0 -0
  7. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/setup.cfg +0 -0
  8. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/setup.py +0 -0
  9. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/__init__.py +0 -0
  10. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/cache.py +0 -0
  11. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/config.py +0 -0
  12. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/errors.py +0 -0
  13. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/http_client.py +0 -0
  14. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/logger.py +0 -0
  15. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/observe.py +0 -0
  16. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably/types.py +0 -0
  17. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably_sdk.egg-info/SOURCES.txt +0 -0
  18. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably_sdk.egg-info/dependency_links.txt +0 -0
  19. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably_sdk.egg-info/requires.txt +0 -0
  20. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/src/variably_sdk.egg-info/top_level.txt +0 -0
  21. {variably_sdk-2.7.1 → variably_sdk-2.9.0}/tests/test_streaming.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: variably-sdk
3
- Version: 2.7.1
3
+ Version: 2.9.0
4
4
  Summary: Official Python SDK for Variably feature flags, LLM experimentation, and prompt optimization platform
5
5
  Author: Variably
6
6
  Author-email: Variably <support@variably.com>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "variably-sdk"
7
- version = "2.7.1"
7
+ version = "2.9.0"
8
8
  description = "Official Python SDK for Variably feature flags, LLM experimentation, and prompt optimization platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.7"
@@ -554,6 +554,20 @@ class VariablyClient:
554
554
 
555
555
  return StreamingEvaluateResponse(raw_response)
556
556
 
557
+ # Allowed values for the `kind` parameter on submit_response. Marks
558
+ # what type of LLM turn this is so the dashboard can suppress
559
+ # grounding/hallucination/attribution scoring on turns where those
560
+ # dimensions don't apply (router, classifier, tool-use). Default
561
+ # "generative" preserves existing behavior for callers not yet on
562
+ # this version.
563
+ _SUBMIT_RESPONSE_KINDS = (
564
+ "generative", # default — narrative answer; full 41D scoring
565
+ "classifier", # intent / safety / routing decision; no claims
566
+ "router", # workflow control turn; no claims
567
+ "tool_use", # function/tool call; no narrative response
568
+ "transformer", # query rewrite / expansion / summarization step
569
+ )
570
+
557
571
  def submit_response(
558
572
  self,
559
573
  experiment_key: str,
@@ -568,8 +582,33 @@ class VariablyClient:
568
582
  prompt_tokens: Optional[int] = None,
569
583
  completion_tokens: Optional[int] = None,
570
584
  evaluation_context: Optional[Dict[str, Any]] = None,
585
+ tags: Optional[List[str]] = None,
586
+ metadata: Optional[Dict[str, Any]] = None,
587
+ kind: Optional[str] = None,
571
588
  ) -> SubmitResponseResult:
572
- """Submit your own LLM response for 41-dimensional evaluation (BYOR step 3)."""
589
+ """Submit your own LLM response for 41-dimensional evaluation (BYOR step 3).
590
+
591
+ Args:
592
+ tags: Grouping labels for filtering (e.g. ["production", "rag-v2"]).
593
+ metadata: Arbitrary key-value data attached to this evaluation
594
+ (e.g. {"customer_id": "...", "release": "..."}).
595
+ kind: What type of LLM turn this is. One of:
596
+ - "generative" (default) — a narrative answer with claims
597
+ to ground. Full 41-dimensional scoring applies.
598
+ - "classifier" — an intent / safety / routing decision
599
+ (e.g. {"is_relevant": true, "should_generate": true}).
600
+ No factual claims, so grounding/hallucination/attribution
601
+ scores will be suppressed in dashboards.
602
+ - "router" — a workflow control turn (chooses next node).
603
+ - "tool_use" — a function/tool call with no narrative.
604
+ - "transformer" — a query rewrite / expansion / summary
605
+ step that's part of the pipeline, not the answer.
606
+
607
+ When non-generative kinds are passed, the SDK injects the
608
+ kind into tags (as `kind:<value>`) and metadata so the
609
+ dashboard can filter and skip grounding scores. Latency,
610
+ token, and variant-level analytics still work.
611
+ """
573
612
  if not experiment_key or not isinstance(experiment_key, str):
574
613
  raise ConfigurationError(
575
614
  "Experiment key must be a non-empty string", "experiment_key"
@@ -578,6 +617,22 @@ class VariablyClient:
578
617
  raise ConfigurationError(
579
618
  "Variant key must be a non-empty string", "variant_key"
580
619
  )
620
+ if kind is not None and kind not in self._SUBMIT_RESPONSE_KINDS:
621
+ raise ConfigurationError(
622
+ f"kind must be one of {self._SUBMIT_RESPONSE_KINDS}, got {kind!r}",
623
+ "kind",
624
+ )
625
+
626
+ # Inject kind into tags + metadata so the dashboard can filter
627
+ # without needing a backend deploy. Preserves any caller-supplied
628
+ # values; we only add, never overwrite.
629
+ if kind and kind != "generative":
630
+ kind_tag = f"kind:{kind}"
631
+ tags = list(tags) if tags else []
632
+ if kind_tag not in tags:
633
+ tags.append(kind_tag)
634
+ metadata = dict(metadata) if metadata else {}
635
+ metadata.setdefault("kind", kind)
581
636
 
582
637
  data: Dict[str, Any] = {
583
638
  "experiment_key": experiment_key,
@@ -586,8 +641,7 @@ class VariablyClient:
586
641
  "response": response,
587
642
  }
588
643
  if user_context:
589
- # Convert snake_case keys to camelCase for the Go backend
590
- data["user_context"] = self.http_client._convert_user_context(dict(user_context))
644
+ data["user_context"] = dict(user_context)
591
645
  if input_variables:
592
646
  data["input_variables"] = input_variables
593
647
  if provider:
@@ -602,6 +656,12 @@ class VariablyClient:
602
656
  data["completion_tokens"] = completion_tokens
603
657
  if evaluation_context:
604
658
  data["evaluation_context"] = evaluation_context
659
+ if tags:
660
+ data["tags"] = tags
661
+ if metadata:
662
+ data["metadata"] = metadata
663
+ if kind:
664
+ data["kind"] = kind
605
665
 
606
666
  result = self.http_client.submit_response(data)
607
667
 
@@ -1,3 +1,3 @@
1
1
  """Version information for Variably SDK."""
2
2
 
3
- __version__ = "2.6.1"
3
+ __version__ = "2.9.0"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: variably-sdk
3
- Version: 2.7.1
3
+ Version: 2.9.0
4
4
  Summary: Official Python SDK for Variably feature flags, LLM experimentation, and prompt optimization platform
5
5
  Author: Variably
6
6
  Author-email: Variably <support@variably.com>
File without changes
File without changes
File without changes