provekit 0.6.0__tar.gz → 0.7.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.
- {provekit-0.6.0 → provekit-0.7.0}/PKG-INFO +27 -1
- {provekit-0.6.0 → provekit-0.7.0}/provekit/__init__.py +4 -2
- provekit-0.7.0/provekit/buffer.py +123 -0
- provekit-0.7.0/provekit/cli.py +626 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/config.py +26 -0
- provekit-0.7.0/provekit/conformance.py +102 -0
- provekit-0.7.0/provekit/doctor.py +261 -0
- provekit-0.7.0/provekit/grpc_ingest.py +340 -0
- provekit-0.7.0/provekit/main.py +272 -0
- provekit-0.7.0/provekit/mcp.py +327 -0
- provekit-0.7.0/provekit/migrations/versions/a2b3c4d5e6f7_usage_records.py +46 -0
- provekit-0.7.0/provekit/migrations/versions/a3b4c5d6e7f8_metric_rollups.py +74 -0
- provekit-0.7.0/provekit/migrations/versions/a7b8c9d0e1f2_replay_webhook_prompts.py +42 -0
- provekit-0.7.0/provekit/migrations/versions/a9b0c1d2e3f4_digests.py +39 -0
- provekit-0.7.0/provekit/migrations/versions/b0c1d2e3f4a5_automation_rules.py +44 -0
- provekit-0.7.0/provekit/migrations/versions/b3c4d5e6f7a8_export_schedules.py +43 -0
- provekit-0.7.0/provekit/migrations/versions/b4c5d6e7f8a9_retention_events.py +41 -0
- provekit-0.7.0/provekit/migrations/versions/b7c8d9e0f1a2_flow_studio.py +88 -0
- provekit-0.7.0/provekit/migrations/versions/b8c9d0e1f2a3_span_notes.py +38 -0
- provekit-0.7.0/provekit/migrations/versions/c1d2e3f4a5b6_prompts_and_turns.py +36 -0
- provekit-0.7.0/provekit/migrations/versions/c4d5e6f7a8b9_custom_scorers.py +39 -0
- provekit-0.7.0/provekit/migrations/versions/c5d6e7f8a9b0_search_text.py +40 -0
- provekit-0.7.0/provekit/migrations/versions/c8d9e0f1a2b3_dataset_snapshots.py +46 -0
- provekit-0.7.0/provekit/migrations/versions/c9d0e1f2a3b4_idempotent_ingest.py +40 -0
- provekit-0.7.0/provekit/migrations/versions/d0e1f2a3b4c5_alert_webhook.py +25 -0
- provekit-0.7.0/provekit/migrations/versions/d6e7f8a9b0c1_dataset_versioning.py +46 -0
- provekit-0.7.0/provekit/migrations/versions/d9e0f1a2b3c4_note_threads.py +34 -0
- provekit-0.7.0/provekit/migrations/versions/e0f1a2b3c4d5_tenant_suspend.py +24 -0
- provekit-0.7.0/provekit/migrations/versions/e1f2a3b4c5d6_audit_log.py +48 -0
- provekit-0.7.0/provekit/migrations/versions/e7f8a9b0c1d2_saved_views.py +39 -0
- provekit-0.7.0/provekit/migrations/versions/f1a2b3c4d5e6_project_invites.py +41 -0
- provekit-0.7.0/provekit/migrations/versions/f2a3b4c5d6e7_run_hot_path_indexes.py +54 -0
- provekit-0.7.0/provekit/migrations/versions/f6a7b8c9d0e1_interactive_debugging.py +61 -0
- provekit-0.7.0/provekit/migrations/versions/f8a9b0c1d2e3_webhook_subscriptions.py +40 -0
- provekit-0.7.0/provekit/models.py +751 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/observability.py +18 -1
- provekit-0.7.0/provekit/routers/activity.py +36 -0
- provekit-0.7.0/provekit/routers/admin.py +277 -0
- provekit-0.7.0/provekit/routers/alerts.py +192 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/routers/apikeys.py +17 -6
- {provekit-0.6.0 → provekit-0.7.0}/provekit/routers/auth.py +15 -14
- provekit-0.7.0/provekit/routers/automation.py +120 -0
- provekit-0.7.0/provekit/routers/dataset_writes.py +49 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/routers/datasets.py +80 -3
- provekit-0.7.0/provekit/routers/digests.py +77 -0
- provekit-0.7.0/provekit/routers/evaluators.py +119 -0
- provekit-0.7.0/provekit/routers/experiments.py +442 -0
- provekit-0.7.0/provekit/routers/export.py +171 -0
- provekit-0.7.0/provekit/routers/flows.py +403 -0
- provekit-0.7.0/provekit/routers/metrics.py +280 -0
- provekit-0.7.0/provekit/routers/playground.py +797 -0
- provekit-0.7.0/provekit/routers/projects.py +267 -0
- provekit-0.7.0/provekit/routers/prompts.py +79 -0
- provekit-0.7.0/provekit/routers/review.py +104 -0
- provekit-0.7.0/provekit/routers/scim.py +164 -0
- provekit-0.7.0/provekit/routers/sso.py +91 -0
- provekit-0.7.0/provekit/routers/traces.py +757 -0
- provekit-0.7.0/provekit/routers/views.py +97 -0
- provekit-0.7.0/provekit/routers/webhooks.py +82 -0
- provekit-0.7.0/provekit/scorers.py +756 -0
- provekit-0.7.0/provekit/services/audit.py +206 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/auth.py +41 -0
- provekit-0.7.0/provekit/services/automation.py +188 -0
- provekit-0.7.0/provekit/services/calibration.py +254 -0
- provekit-0.7.0/provekit/services/custom_scorers.py +203 -0
- provekit-0.7.0/provekit/services/datasets.py +175 -0
- provekit-0.7.0/provekit/services/digests.py +153 -0
- provekit-0.7.0/provekit/services/errors.py +253 -0
- provekit-0.7.0/provekit/services/export.py +194 -0
- provekit-0.7.0/provekit/services/export_schedule.py +174 -0
- provekit-0.7.0/provekit/services/fleet.py +300 -0
- provekit-0.7.0/provekit/services/flow_trace.py +98 -0
- provekit-0.7.0/provekit/services/impersonation.py +149 -0
- provekit-0.7.0/provekit/services/invites.py +127 -0
- provekit-0.7.0/provekit/services/limits.py +204 -0
- provekit-0.7.0/provekit/services/llm_client.py +273 -0
- provekit-0.7.0/provekit/services/mentions.py +83 -0
- provekit-0.7.0/provekit/services/notify.py +175 -0
- provekit-0.7.0/provekit/services/oidc.py +460 -0
- provekit-0.7.0/provekit/services/otel.py +332 -0
- provekit-0.7.0/provekit/services/partitions.py +151 -0
- provekit-0.7.0/provekit/services/payloads.py +163 -0
- provekit-0.7.0/provekit/services/pricing.py +104 -0
- provekit-0.7.0/provekit/services/prompts.py +111 -0
- provekit-0.7.0/provekit/services/redact.py +110 -0
- provekit-0.7.0/provekit/services/replay.py +304 -0
- provekit-0.7.0/provekit/services/roles.py +46 -0
- provekit-0.7.0/provekit/services/rollups.py +212 -0
- provekit-0.7.0/provekit/services/scim.py +568 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/sealing.py +16 -0
- provekit-0.7.0/provekit/services/search.py +116 -0
- provekit-0.7.0/provekit/services/seed.py +260 -0
- provekit-0.7.0/provekit/services/share.py +333 -0
- provekit-0.7.0/provekit/services/spool.py +201 -0
- provekit-0.7.0/provekit/services/stats.py +162 -0
- provekit-0.7.0/provekit/services/tenant.py +91 -0
- provekit-0.7.0/provekit/services/usage.py +162 -0
- provekit-0.7.0/provekit/services/webhooks.py +148 -0
- provekit-0.7.0/provekit/services/workspace.py +119 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/trace.py +191 -40
- provekit-0.7.0/provekit/vcr.py +260 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit.egg-info/PKG-INFO +27 -1
- provekit-0.7.0/provekit.egg-info/SOURCES.txt +211 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit.egg-info/entry_points.txt +2 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit.egg-info/requires.txt +27 -0
- {provekit-0.6.0 → provekit-0.7.0}/pyproject.toml +36 -1
- provekit-0.7.0/tests/test_activity.py +305 -0
- provekit-0.7.0/tests/test_admin.py +258 -0
- provekit-0.7.0/tests/test_alerts.py +119 -0
- provekit-0.7.0/tests/test_automation.py +296 -0
- provekit-0.7.0/tests/test_buffer.py +146 -0
- provekit-0.7.0/tests/test_calibration.py +249 -0
- provekit-0.7.0/tests/test_cli.py +595 -0
- provekit-0.7.0/tests/test_clock_skew.py +68 -0
- provekit-0.7.0/tests/test_conformance.py +102 -0
- provekit-0.7.0/tests/test_custom_scorers.py +304 -0
- provekit-0.7.0/tests/test_dataset_snapshots.py +91 -0
- provekit-0.7.0/tests/test_dataset_versioning.py +168 -0
- provekit-0.7.0/tests/test_dialects.py +286 -0
- provekit-0.7.0/tests/test_digests.py +260 -0
- provekit-0.7.0/tests/test_doctor.py +111 -0
- provekit-0.7.0/tests/test_error_messages.py +318 -0
- provekit-0.7.0/tests/test_evaluators.py +23 -0
- provekit-0.7.0/tests/test_experiments.py +114 -0
- provekit-0.7.0/tests/test_export.py +392 -0
- provekit-0.7.0/tests/test_export_schedule.py +230 -0
- provekit-0.7.0/tests/test_fleet.py +305 -0
- provekit-0.7.0/tests/test_flows.py +444 -0
- provekit-0.7.0/tests/test_grpc_ingest.py +329 -0
- provekit-0.7.0/tests/test_impersonation.py +324 -0
- provekit-0.7.0/tests/test_index_coverage.py +80 -0
- provekit-0.7.0/tests/test_invites.py +152 -0
- provekit-0.7.0/tests/test_mcp_writes.py +313 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_metrics.py +40 -2
- provekit-0.7.0/tests/test_migrations.py +150 -0
- provekit-0.7.0/tests/test_note_threads.py +158 -0
- provekit-0.7.0/tests/test_notify.py +195 -0
- provekit-0.7.0/tests/test_onboarding.py +348 -0
- provekit-0.7.0/tests/test_otel.py +253 -0
- provekit-0.7.0/tests/test_partitions.py +237 -0
- provekit-0.7.0/tests/test_payload_offload.py +119 -0
- provekit-0.7.0/tests/test_playground.py +574 -0
- provekit-0.7.0/tests/test_playground_depth.py +344 -0
- provekit-0.7.0/tests/test_playground_stream.py +341 -0
- provekit-0.7.0/tests/test_pricing.py +81 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_projects.py +4 -2
- provekit-0.7.0/tests/test_prompts_and_sessions.py +281 -0
- provekit-0.7.0/tests/test_provenance.py +113 -0
- provekit-0.7.0/tests/test_quality_gates.py +183 -0
- provekit-0.7.0/tests/test_quota.py +92 -0
- provekit-0.7.0/tests/test_redaction_corpus.py +85 -0
- provekit-0.7.0/tests/test_regression_triage.py +166 -0
- provekit-0.7.0/tests/test_reproducibility.py +76 -0
- provekit-0.7.0/tests/test_retention.py +135 -0
- provekit-0.7.0/tests/test_review.py +102 -0
- provekit-0.7.0/tests/test_roles.py +116 -0
- provekit-0.7.0/tests/test_rollups.py +204 -0
- provekit-0.7.0/tests/test_scim.py +675 -0
- provekit-0.7.0/tests/test_scorers_extra.py +309 -0
- provekit-0.7.0/tests/test_search.py +165 -0
- provekit-0.7.0/tests/test_share_redaction.py +301 -0
- provekit-0.7.0/tests/test_spool.py +173 -0
- provekit-0.7.0/tests/test_sso.py +647 -0
- provekit-0.7.0/tests/test_stats.py +111 -0
- provekit-0.7.0/tests/test_step_through.py +132 -0
- provekit-0.7.0/tests/test_tenant.py +153 -0
- provekit-0.7.0/tests/test_trace_cost.py +37 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_trace_sdk.py +14 -1
- provekit-0.7.0/tests/test_traces_tree.py +268 -0
- provekit-0.7.0/tests/test_usage_metering.py +165 -0
- provekit-0.7.0/tests/test_vcr.py +173 -0
- provekit-0.7.0/tests/test_views.py +75 -0
- provekit-0.7.0/tests/test_webhooks.py +216 -0
- provekit-0.6.0/provekit/main.py +0 -101
- provekit-0.6.0/provekit/mcp.py +0 -83
- provekit-0.6.0/provekit/models.py +0 -188
- provekit-0.6.0/provekit/routers/admin.py +0 -82
- provekit-0.6.0/provekit/routers/alerts.py +0 -124
- provekit-0.6.0/provekit/routers/experiments.py +0 -141
- provekit-0.6.0/provekit/routers/metrics.py +0 -143
- provekit-0.6.0/provekit/routers/projects.py +0 -140
- provekit-0.6.0/provekit/routers/traces.py +0 -275
- provekit-0.6.0/provekit/scorers.py +0 -63
- provekit-0.6.0/provekit/services/limits.py +0 -73
- provekit-0.6.0/provekit/services/otel.py +0 -183
- provekit-0.6.0/provekit/services/redact.py +0 -48
- provekit-0.6.0/provekit/services/share.py +0 -54
- provekit-0.6.0/provekit/services/workspace.py +0 -61
- provekit-0.6.0/provekit.egg-info/SOURCES.txt +0 -76
- provekit-0.6.0/tests/test_admin.py +0 -72
- provekit-0.6.0/tests/test_alerts.py +0 -55
- provekit-0.6.0/tests/test_experiments.py +0 -51
- provekit-0.6.0/tests/test_otel.py +0 -130
- provekit-0.6.0/tests/test_traces_tree.py +0 -40
- {provekit-0.6.0 → provekit-0.7.0}/README.md +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/auto.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/database.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/demo.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/eval.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/env.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/script.py.mako +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/versions/9d2c06bfa4e6_baseline.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/versions/a1b2c3d4e5f6_feedback_sessions.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/versions/b2c3d4e5f6a7_datasets.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/versions/c3d4e5f6a7b8_experiments.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/versions/d4e5f6a7b8c9_alerts.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/migrations/versions/e5f6a7b8c9d0_admin.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/routers/__init__.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/__init__.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/apikey.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/deploy.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/email.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit/services/netguard.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit.egg-info/dependency_links.txt +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/provekit.egg-info/top_level.txt +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/setup.cfg +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_account_recovery.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_apikeys.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_auth.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_auth_hardening.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_autoinstrument.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_cov_limits_auth.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_coverage_extra.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_datasets.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_eval.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_feedback.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_hardening.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_key_read_api.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_mcp.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_netguard.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_observability.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_redact.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_scorers.py +0 -0
- {provekit-0.6.0 → provekit-0.7.0}/tests/test_share.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: provekit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Drop-in agent tracing — add one decorator, get a project key, review every run your agent makes.
|
|
5
5
|
Author: ProveKit contributors
|
|
6
6
|
License: MIT
|
|
@@ -42,6 +42,16 @@ Provides-Extra: http
|
|
|
42
42
|
Requires-Dist: opentelemetry-instrumentation-httpx>=0.40b0; extra == "http"
|
|
43
43
|
Requires-Dist: opentelemetry-instrumentation-requests>=0.40b0; extra == "http"
|
|
44
44
|
Requires-Dist: opentelemetry-instrumentation-urllib>=0.40b0; extra == "http"
|
|
45
|
+
Requires-Dist: opentelemetry-instrumentation-urllib3>=0.40b0; extra == "http"
|
|
46
|
+
Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.40b0; extra == "http"
|
|
47
|
+
Provides-Extra: data
|
|
48
|
+
Requires-Dist: opentelemetry-instrumentation-botocore>=0.40b0; extra == "data"
|
|
49
|
+
Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.40b0; extra == "data"
|
|
50
|
+
Requires-Dist: opentelemetry-instrumentation-psycopg>=0.40b0; extra == "data"
|
|
51
|
+
Requires-Dist: opentelemetry-instrumentation-asyncpg>=0.40b0; extra == "data"
|
|
52
|
+
Requires-Dist: opentelemetry-instrumentation-redis>=0.40b0; extra == "data"
|
|
53
|
+
Requires-Dist: opentelemetry-instrumentation-pymongo>=0.40b0; extra == "data"
|
|
54
|
+
Requires-Dist: opentelemetry-instrumentation-elasticsearch>=0.40b0; extra == "data"
|
|
45
55
|
Provides-Extra: trace-all
|
|
46
56
|
Requires-Dist: opentelemetry-api<2,>=1.20; extra == "trace-all"
|
|
47
57
|
Requires-Dist: opentelemetry-sdk<2,>=1.20; extra == "trace-all"
|
|
@@ -56,9 +66,25 @@ Requires-Dist: openinference-instrumentation-groq>=0.1; extra == "trace-all"
|
|
|
56
66
|
Requires-Dist: openinference-instrumentation-mistralai>=0.1; extra == "trace-all"
|
|
57
67
|
Requires-Dist: openinference-instrumentation-dspy>=0.1; extra == "trace-all"
|
|
58
68
|
Requires-Dist: openinference-instrumentation-haystack>=0.1; extra == "trace-all"
|
|
69
|
+
Requires-Dist: openinference-instrumentation-google-genai>=0.1; extra == "trace-all"
|
|
70
|
+
Requires-Dist: openinference-instrumentation-vertexai>=0.1; extra == "trace-all"
|
|
71
|
+
Requires-Dist: openinference-instrumentation-portkey>=0.1; extra == "trace-all"
|
|
72
|
+
Requires-Dist: openinference-instrumentation-autogen>=0.1; extra == "trace-all"
|
|
73
|
+
Requires-Dist: openinference-instrumentation-openai-agents>=0.1; extra == "trace-all"
|
|
74
|
+
Requires-Dist: openinference-instrumentation-smolagents>=0.1; extra == "trace-all"
|
|
75
|
+
Requires-Dist: openinference-instrumentation-agno>=0.1; extra == "trace-all"
|
|
76
|
+
Requires-Dist: openinference-instrumentation-pydantic-ai>=0.1; extra == "trace-all"
|
|
77
|
+
Requires-Dist: openinference-instrumentation-beeai>=0.1; extra == "trace-all"
|
|
78
|
+
Requires-Dist: openinference-instrumentation-google-adk>=0.1; extra == "trace-all"
|
|
79
|
+
Requires-Dist: openinference-instrumentation-claude-agent-sdk>=0.1; extra == "trace-all"
|
|
80
|
+
Requires-Dist: openinference-instrumentation-guardrails>=0.1; extra == "trace-all"
|
|
81
|
+
Requires-Dist: openinference-instrumentation-instructor>=0.1; extra == "trace-all"
|
|
82
|
+
Requires-Dist: openinference-instrumentation-mcp>=0.1; extra == "trace-all"
|
|
59
83
|
Requires-Dist: opentelemetry-instrumentation-httpx>=0.40b0; extra == "trace-all"
|
|
60
84
|
Requires-Dist: opentelemetry-instrumentation-requests>=0.40b0; extra == "trace-all"
|
|
61
85
|
Requires-Dist: opentelemetry-instrumentation-urllib>=0.40b0; extra == "trace-all"
|
|
86
|
+
Requires-Dist: opentelemetry-instrumentation-urllib3>=0.40b0; extra == "trace-all"
|
|
87
|
+
Requires-Dist: opentelemetry-instrumentation-aiohttp-client>=0.40b0; extra == "trace-all"
|
|
62
88
|
Provides-Extra: mcp
|
|
63
89
|
Requires-Dist: mcp>=1.2; extra == "mcp"
|
|
64
90
|
Provides-Extra: dev
|
|
@@ -13,6 +13,8 @@ submodule (a same-named top-level export would shadow that module).
|
|
|
13
13
|
"""
|
|
14
14
|
from provekit import scorers
|
|
15
15
|
from provekit.eval import evaluate
|
|
16
|
-
from provekit.trace import configure, init, span
|
|
16
|
+
from provekit.trace import configure, get_prompt, init, span
|
|
17
|
+
from provekit.vcr import ReplayMiss, ReplayReport, replay, tool
|
|
17
18
|
|
|
18
|
-
__all__ = ["init", "configure", "span", "evaluate", "scorers"
|
|
19
|
+
__all__ = ["init", "configure", "span", "evaluate", "scorers",
|
|
20
|
+
"tool", "replay", "ReplayReport", "ReplayMiss", "get_prompt"]
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"""A bounded on-disk buffer for spans the portal wouldn't take.
|
|
2
|
+
|
|
3
|
+
Client-side half of durable ingest. The SDK is fail-open by design — a tracing library that
|
|
4
|
+
can break the app it observes is worse than no tracing — so an unreachable portal has always
|
|
5
|
+
meant the batch is dropped. That is the right call for a *long* outage and a poor one for the
|
|
6
|
+
common case: a deploy, a restart, thirty seconds of network. Those are exactly the moments
|
|
7
|
+
worth having traces for, and exactly the ones we lost.
|
|
8
|
+
|
|
9
|
+
So a failed export is written to disk and retried on the next export or flush. Bounded by
|
|
10
|
+
batch count, and oldest-first eviction when full: a buffer that grows without limit is just a
|
|
11
|
+
different way to break the user's app, which is the thing we refuse to do.
|
|
12
|
+
|
|
13
|
+
SDK module — depends only on the standard library, and imports no server code (see AGENTS.md).
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import json
|
|
18
|
+
import logging
|
|
19
|
+
import os
|
|
20
|
+
import tempfile
|
|
21
|
+
import time
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
|
|
24
|
+
log = logging.getLogger("provekit")
|
|
25
|
+
|
|
26
|
+
_DEFAULT_MAX_BATCHES = 500
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class SpanBuffer:
|
|
30
|
+
"""Failed export batches, staged on disk oldest-first.
|
|
31
|
+
|
|
32
|
+
Every method swallows its own errors. A buffer that raises has converted "we lost some
|
|
33
|
+
traces" into "we broke production", and the whole point of fail-open is that the second
|
|
34
|
+
outcome is never acceptable.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, directory: str | None = None, max_batches: int = _DEFAULT_MAX_BATCHES):
|
|
38
|
+
self._dir = Path(directory) if directory else Path(tempfile.gettempdir()) / "provekit-buffer"
|
|
39
|
+
self._max = max_batches
|
|
40
|
+
self._seq = 0
|
|
41
|
+
self._ok = True # flipped off if the directory turns out to be unwritable
|
|
42
|
+
|
|
43
|
+
# -- staging ---------------------------------------------------------------------------
|
|
44
|
+
|
|
45
|
+
def put(self, body: dict) -> bool:
|
|
46
|
+
"""Buffer one OTLP body. False if it couldn't be staged (buffer off, full, or no disk)."""
|
|
47
|
+
if not self._ok or self._max <= 0:
|
|
48
|
+
return False
|
|
49
|
+
try:
|
|
50
|
+
self._dir.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
except OSError as e:
|
|
52
|
+
# Read-only filesystem or no permission. Stop trying: this will not fix itself, and
|
|
53
|
+
# logging once per export would be its own kind of failure.
|
|
54
|
+
log.debug("provekit: span buffer unavailable (%s); exports will drop on failure", e)
|
|
55
|
+
self._ok = False
|
|
56
|
+
return False
|
|
57
|
+
self._evict()
|
|
58
|
+
self._seq += 1
|
|
59
|
+
name = f"{int(time.time() * 1000):013d}-{os.getpid()}-{self._seq:06d}.json"
|
|
60
|
+
try:
|
|
61
|
+
tmp = self._dir / (name + ".partial")
|
|
62
|
+
tmp.write_text(json.dumps(body), encoding="utf-8")
|
|
63
|
+
os.replace(tmp, self._dir / name)
|
|
64
|
+
return True
|
|
65
|
+
except (OSError, TypeError, ValueError) as e:
|
|
66
|
+
log.debug("provekit: could not buffer span batch (%s)", e)
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
def _evict(self) -> None:
|
|
70
|
+
"""Keep the buffer under its cap, dropping the oldest first.
|
|
71
|
+
|
|
72
|
+
Oldest-first because a stale batch is the least useful thing here: if the portal has
|
|
73
|
+
been down long enough to fill the buffer, the recent spans are the ones someone is
|
|
74
|
+
about to go looking for.
|
|
75
|
+
"""
|
|
76
|
+
entries = self.pending()
|
|
77
|
+
excess = len(entries) - self._max + 1
|
|
78
|
+
for path in entries[:max(0, excess)]:
|
|
79
|
+
try:
|
|
80
|
+
path.unlink()
|
|
81
|
+
except OSError:
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
# -- draining --------------------------------------------------------------------------
|
|
85
|
+
|
|
86
|
+
def pending(self) -> list[Path]:
|
|
87
|
+
try:
|
|
88
|
+
return sorted(p for p in self._dir.iterdir() if p.suffix == ".json")
|
|
89
|
+
except OSError:
|
|
90
|
+
return []
|
|
91
|
+
|
|
92
|
+
def depth(self) -> int:
|
|
93
|
+
return len(self.pending())
|
|
94
|
+
|
|
95
|
+
def drain(self, send) -> int:
|
|
96
|
+
"""Retry buffered batches with `send(body) -> bool`. Returns how many were accepted.
|
|
97
|
+
|
|
98
|
+
Stops at the first failure. If the portal is still down, walking the rest of the buffer
|
|
99
|
+
just spends the app's time on calls we already know the answer to — and this runs on
|
|
100
|
+
the exporter's thread, in the user's process.
|
|
101
|
+
"""
|
|
102
|
+
flushed = 0
|
|
103
|
+
for path in self.pending():
|
|
104
|
+
try:
|
|
105
|
+
body = json.loads(path.read_text(encoding="utf-8"))
|
|
106
|
+
except (OSError, ValueError):
|
|
107
|
+
# Unreadable entry: drop it rather than retry forever behind everything else.
|
|
108
|
+
try:
|
|
109
|
+
path.unlink()
|
|
110
|
+
except OSError:
|
|
111
|
+
pass
|
|
112
|
+
continue
|
|
113
|
+
try:
|
|
114
|
+
if not send(body):
|
|
115
|
+
break
|
|
116
|
+
except Exception:
|
|
117
|
+
break
|
|
118
|
+
try:
|
|
119
|
+
path.unlink()
|
|
120
|
+
except OSError:
|
|
121
|
+
pass
|
|
122
|
+
flushed += 1
|
|
123
|
+
return flushed
|