bitfab-py 0.76.2__tar.gz → 0.76.3__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 (70) hide show
  1. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/PKG-INFO +1 -1
  2. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/__init__.py +0 -4
  3. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/traces.py +24 -69
  4. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/pyproject.toml +1 -1
  5. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/README.md +0 -0
  6. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/agent_middleware.py +0 -0
  7. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/approval.py +0 -0
  8. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/assertion_categories.py +0 -0
  9. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/baml.py +0 -0
  10. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/baml_auto_trace.py +0 -0
  11. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/categories.py +0 -0
  12. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/claude_agent_sdk.py +0 -0
  13. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/client.py +0 -0
  14. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/client_patching.py +0 -0
  15. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/cloudReplay.py +0 -0
  16. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/cloud_replay_cli.py +0 -0
  17. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/commit_ref.py +0 -0
  18. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/compress.py +0 -0
  19. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/constants.py +0 -0
  20. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/datasets.py +0 -0
  21. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/db_snapshot.py +0 -0
  22. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/error_chain.py +0 -0
  23. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/experiment_id.py +0 -0
  24. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/experiments.py +0 -0
  25. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/finalizers.py +0 -0
  26. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/git_command.py +0 -0
  27. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/git_state.py +0 -0
  28. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/graders.py +0 -0
  29. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/http.py +0 -0
  30. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/integration_fixture.py +0 -0
  31. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/jev.py +0 -0
  32. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/labels.py +0 -0
  33. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/langgraph.py +0 -0
  34. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/langgraph_integration.py +0 -0
  35. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/langgraph_runs.py +0 -0
  36. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/mock_matching.py +0 -0
  37. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/mock_override.py +0 -0
  38. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/openai_agent_sdk.py +0 -0
  39. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/organization_members.py +0 -0
  40. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/otel.py +0 -0
  41. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/payload_budget.py +0 -0
  42. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/processor_payload.py +0 -0
  43. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/provider_calls.py +0 -0
  44. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay.py +0 -0
  45. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_branch.py +0 -0
  46. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_cli.py +0 -0
  47. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_heartbeat.py +0 -0
  48. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_interrupt.py +0 -0
  49. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_invocation.py +0 -0
  50. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_memory.py +0 -0
  51. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_processes.py +0 -0
  52. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_registry.py +0 -0
  53. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/seed_cli.py +0 -0
  54. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/selective_replay.py +0 -0
  55. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/serialize.py +0 -0
  56. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/simulation_plan.py +0 -0
  57. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/span_meta.py +0 -0
  58. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/span_origin.py +0 -0
  59. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/spans.py +0 -0
  60. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/subtree.py +0 -0
  61. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/thread_propagation.py +0 -0
  62. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/timestamp.py +0 -0
  63. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/trace_completion.py +0 -0
  64. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/trace_metadata.py +0 -0
  65. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/trace_payload.py +0 -0
  66. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/tracing.py +0 -0
  67. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/transport.py +0 -0
  68. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/transport_types.py +0 -0
  69. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/verdicts.py +0 -0
  70. {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/warn_once.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitfab-py
3
- Version: 0.76.2
3
+ Version: 0.76.3
4
4
  Summary: Bitfab client for provider-based API calls with local BAML execution
5
5
  Author: Harvest Team
6
6
  Requires-Python: >=3.10
@@ -154,7 +154,6 @@ from bitfab.spans import (
154
154
  )
155
155
  from bitfab.traces import (
156
156
  AssertionCode,
157
- AssertionCodeDraft,
158
157
  AssertionEvidenceError,
159
158
  AssertionEvidenceParameter,
160
159
  AssertionEvidenceParameterType,
@@ -163,7 +162,6 @@ from bitfab.traces import (
163
162
  AssertionGenerationError,
164
163
  AssertionGenerationStatus,
165
164
  AssertionGenerationTimeoutError,
166
- AssertionKind,
167
165
  AssertionLabelEvidence,
168
166
  AssertionRewrite,
169
167
  AssertionRewriteStatus,
@@ -232,7 +230,6 @@ __all__ = [
232
230
  "AssertionCategory",
233
231
  "AssertionCategorySummary",
234
232
  "AssertionCode",
235
- "AssertionCodeDraft",
236
233
  "AssertionEvidenceError",
237
234
  "AssertionEvidenceParameter",
238
235
  "AssertionEvidenceParameterType",
@@ -241,7 +238,6 @@ __all__ = [
241
238
  "AssertionGenerationError",
242
239
  "AssertionGenerationStatus",
243
240
  "AssertionGenerationTimeoutError",
244
- "AssertionKind",
245
241
  "AssertionLabelEvidence",
246
242
  "AssertionRewrite",
247
243
  "AssertionRewriteStatus",
@@ -24,7 +24,6 @@ AssertionEvidenceSpanType = Literal[
24
24
  ]
25
25
 
26
26
  ASSERTIONS_PATH = "/api/sdk/traces/assertions"
27
- _CODE_DRAFT_SAVE_TIMEOUT_SECONDS = 300.0
28
27
  SEARCH_PATH = "/api/sdk/traces/search"
29
28
 
30
29
 
@@ -59,11 +58,8 @@ class SpanTarget(TypedDict):
59
58
  TraceTarget = OutputTarget | SpanTarget
60
59
 
61
60
 
62
- AssertionKind = Literal["judge", "code", "hybrid"]
63
-
64
-
65
61
  class AssertionCode(TypedDict):
66
- """Code that decides an assertion's verdict from a run's spans instead of the LLM judge.
62
+ """Code that decides an assertion's verdict from a run's spans, or hands the decision to the LLM judge.
67
63
 
68
64
  ``source`` is the body of an async TypeScript function (plain JavaScript
69
65
  also works) called with ``spans`` (each ``{name, index, hasData}``, in
@@ -71,12 +67,17 @@ class AssertionCode(TypedDict):
71
67
  data with ``await named("span name")``, which returns
72
68
  ``{name, index, input, output, metadata}`` for each span with that name,
73
69
  or ``await span.data()``. It returns ``"pass"``, ``"fail"``, or
74
- ``"defer"`` (hybrid assertions only: hand the rest to the LLM judge), or
75
- ``{result, reason}``. It gets one second of compute and may load the data
76
- of at most 50 spans within ten seconds. ``spanNames`` lists
77
- every span name the code expects a correct run to produce; a name missing
78
- from a replay and from the function's other sampled replays marks the code
79
- broken instead of failing the replay.
70
+ ``"defer"``, or ``{result, reason}``. ``"pass"`` and ``"fail"`` decide
71
+ the verdict with no judge call. ``"defer"`` hands the decision to the LLM
72
+ judge, and may be returned as ``{result: "defer", reason, data}``, where
73
+ ``reason`` and ``data`` are both optional and ``data`` is what the code
74
+ found that the judge needs to decide (such as the sent email's subject
75
+ and body). The judge reads the reason and data alongside the run. Code
76
+ that throws counts as ``"defer"`` with no data. It gets one second of
77
+ compute and may load the data of at most 50 spans within ten seconds.
78
+ ``spanNames`` lists every span name the code expects a correct run to
79
+ produce; a name missing from a replay and from the function's other
80
+ sampled replays marks the code broken instead of failing the replay.
80
81
  """
81
82
 
82
83
  source: str
@@ -96,7 +97,6 @@ class TraceAssertion(ApprovalFields):
96
97
  passCriteria: str | None
97
98
  failCriteria: str | None
98
99
  targetOnEvaluatedTrace: TraceTarget | None
99
- kind: AssertionKind
100
100
  code: AssertionCode | None
101
101
  codeBrokenReason: str | None
102
102
  source: TraceAssertionSource
@@ -141,31 +141,10 @@ class AssertionRewrite(TypedDict):
141
141
  error: str | None
142
142
 
143
143
 
144
- class AssertionCodeDraft(TypedDict):
145
- """Whether Bitfab wrote code for an assertion that asked for it.
146
-
147
- ``status`` is ``written`` when code of ``requestedKind`` was saved and ran
148
- on the trace, with ``reason`` None. It is ``not_written`` when no working
149
- code could be written: the assertion was saved as a ``"judge"`` assertion
150
- without code and ``reason`` says why. Reword the assertion and ask again,
151
- or send the code yourself.
152
- """
153
-
154
- requestedKind: Literal["code", "hybrid"]
155
- status: Literal["written", "not_written"]
156
- reason: str | None
157
-
158
-
159
144
  class SavedTraceAssertion(TraceAssertion):
160
- """An assertion returned by a save, with what the guided rewrite did to the entry sent for it.
161
-
162
- ``codeDraft`` reports on an entry that sent ``kind`` ``"code"`` or
163
- ``"hybrid"`` with no ``code`` for Bitfab to write, and is None for every
164
- other entry.
165
- """
145
+ """An assertion returned by a save, with what the guided rewrite did to the entry sent for it."""
166
146
 
167
147
  rewrite: AssertionRewrite
168
- codeDraft: AssertionCodeDraft | None
169
148
 
170
149
 
171
150
  class ReadTraceAssertion(TraceAssertion):
@@ -486,18 +465,12 @@ class SaveAssertion(TypedDict):
486
465
 
487
466
  Omit ``category_id`` to preserve the existing category, or pass ``None`` to
488
467
  clear it. ``category_assertion_id`` is a deprecated alias for ``category_id``;
489
- when both are set, ``category_id`` wins. ``kind`` says who decides the
490
- assertion: ``"judge"`` (the LLM judge), ``"code"`` (``code`` decides every
491
- replay), or ``"hybrid"`` (``code`` decides what it can and returns
492
- ``"defer"`` for the rest). Send ``"code"`` or ``"hybrid"`` with ``code``
493
- to set the code yourself, or without ``code`` on an assertion that has none
494
- yet to have Bitfab write it: the text is checked by the guided rewrite
495
- (unless skipped), code of that kind is written and run on this trace, and
496
- the save waits for both. The returned ``codeDraft`` says whether working
497
- code was written. At most 10 assertions per save may ask for code this
498
- way, and a save that asks for any waits up to five minutes. Omit both to keep them, or pass ``kind="judge"`` to remove the
499
- code. Code that cannot run on this trace, or that returns ``"defer"`` for a
500
- ``"code"`` assertion, is refused.
468
+ when both are set, ``category_id`` wins. Pass ``code`` to set the
469
+ assertion's code, ``None`` to remove it so the LLM judge decides every
470
+ run, or omit it to keep the current code. The code is run on this trace
471
+ before saving, and the save is refused when it throws, runs out of time,
472
+ or returns something other than a result. Bitfab may also write code for
473
+ an assertion on its own after the save, in the background.
501
474
  """
502
475
 
503
476
  category_id: NotRequired[str | None]
@@ -508,7 +481,6 @@ class SaveAssertion(TypedDict):
508
481
  passCriteria: NotRequired[str | None]
509
482
  failCriteria: NotRequired[str | None]
510
483
  targetOnEvaluatedTrace: NotRequired[TraceTarget | None]
511
- kind: NotRequired[AssertionKind]
512
484
  code: NotRequired[AssertionCode | None]
513
485
  justification: NotRequired[Justification | None]
514
486
  categoryJustification: NotRequired[Justification | None]
@@ -622,19 +594,6 @@ def _save_assertions_payload(
622
594
  }
623
595
 
624
596
 
625
- def _asks_bitfab_to_write_code(assertion: SaveAssertion) -> bool:
626
- return assertion.get("kind") in ("code", "hybrid") and "code" not in assertion
627
-
628
-
629
- def _save_request_options(updates: list[TraceAssertionsUpdate]) -> dict[str, float]:
630
- asks = any(
631
- _asks_bitfab_to_write_code(assertion)
632
- for update in updates
633
- for assertion in update["assertions"]
634
- )
635
- return {"timeout": _CODE_DRAFT_SAVE_TIMEOUT_SECONDS} if asks else {}
636
-
637
-
638
597
  def _trace_assertions_path(trace_id: str, suffix: str = "") -> str:
639
598
  return f"/api/sdk/traces/{quote(trace_id, safe='')}/assertions{suffix}"
640
599
 
@@ -776,10 +735,7 @@ class TracesClient:
776
735
  back with ``rewrite["status"] == "pending"`` while Bitfab checks it
777
736
  against the writing rules in the background and, when it breaks
778
737
  one, rewrites it in place, usually within a minute. Read the result
779
- later with ``get_assertions``, whose rows carry ``rewrite``. Entries
780
- that ask Bitfab to write their code are checked and given code before
781
- the call returns, so their ``rewrite`` and ``codeDraft`` are final.
782
- Pass ``skip_guided_rewrite=True`` to save the text exactly as sent with
738
+ later with ``get_assertions``, whose rows carry ``rewrite``. Pass ``skip_guided_rewrite=True`` to save the text exactly as sent with
783
739
  no check.
784
740
  """
785
741
  return self.save_assertions_all(
@@ -811,17 +767,16 @@ class TracesClient:
811
767
  says whether the text was rewritten, left unchanged, or could not be
812
768
  checked. Save every text in ``rewrite["separateAssertions"]`` as its
813
769
  own assertion, and act on anything in ``rewrite["unresolved"]``.
814
- Entries that ask Bitfab to write their code are checked and given code
815
- before the call returns, so their ``rewrite`` and ``codeDraft`` are
816
- final. Pass ``skip_guided_rewrite=True`` to save the text exactly as
817
- sent with no check.
770
+ An entry's ``code`` is run on its trace before anything is saved, and
771
+ code that throws, runs out of time, or returns something other than a
772
+ result refuses the save. Pass ``skip_guided_rewrite=True`` to save the
773
+ text exactly as sent with no check.
818
774
  """
819
775
  if not updates:
820
776
  return []
821
777
  result = self._http_client.request(
822
778
  ASSERTIONS_PATH,
823
779
  _save_assertions_payload(updates, source, skip_guided_rewrite),
824
- **_save_request_options(updates),
825
780
  )
826
781
  return list(result["assertions"])
827
782
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "bitfab-py"
3
- version = "0.76.2"
3
+ version = "0.76.3"
4
4
  description = "Bitfab client for provider-based API calls with local BAML execution"
5
5
  authors = ["Harvest Team"]
6
6
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes