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.
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/PKG-INFO +1 -1
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/__init__.py +0 -4
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/traces.py +24 -69
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/pyproject.toml +1 -1
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/README.md +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/agent_middleware.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/approval.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/assertion_categories.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/baml.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/baml_auto_trace.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/categories.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/claude_agent_sdk.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/client.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/client_patching.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/cloudReplay.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/cloud_replay_cli.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/commit_ref.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/compress.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/constants.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/datasets.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/db_snapshot.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/error_chain.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/experiment_id.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/experiments.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/finalizers.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/git_command.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/git_state.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/graders.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/http.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/integration_fixture.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/jev.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/labels.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/langgraph.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/langgraph_integration.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/langgraph_runs.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/mock_matching.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/mock_override.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/openai_agent_sdk.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/organization_members.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/otel.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/payload_budget.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/processor_payload.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/provider_calls.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_branch.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_cli.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_heartbeat.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_interrupt.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_invocation.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_memory.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_processes.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/replay_registry.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/seed_cli.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/selective_replay.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/serialize.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/simulation_plan.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/span_meta.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/span_origin.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/spans.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/subtree.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/thread_propagation.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/timestamp.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/trace_completion.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/trace_metadata.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/trace_payload.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/tracing.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/transport.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/transport_types.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/verdicts.py +0 -0
- {bitfab_py-0.76.2 → bitfab_py-0.76.3}/bitfab/warn_once.py +0 -0
|
@@ -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
|
|
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"
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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. ``
|
|
490
|
-
assertion
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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``.
|
|
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
|
-
|
|
815
|
-
|
|
816
|
-
|
|
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
|
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|