Skip to content

Commit df748e9

Browse files
committed
hook for redacting PII
1 parent 9dd2eec commit df748e9

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

sentience/tracer_factory.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from typing import Optional
2-
31
"""
42
Tracer factory with automatic tier detection.
53
@@ -10,7 +8,8 @@
108
import os
119
import uuid
1210
from pathlib import Path
13-
from typing import Any
11+
from typing import Any, Optional
12+
from collections.abc import Callable
1413

1514
import requests
1615

@@ -31,6 +30,7 @@ def create_tracer(
3130
agent_type: str | None = None,
3231
llm_model: str | None = None,
3332
start_url: str | None = None,
33+
screenshot_processor: Callable[[str], str] | None = None,
3434
) -> Tracer:
3535
"""
3636
Create tracer with automatic tier detection.
@@ -55,6 +55,9 @@ def create_tracer(
5555
agent_type: Type of agent running (e.g., "SentienceAgent", "CustomAgent")
5656
llm_model: LLM model used (e.g., "gpt-4-turbo", "claude-3-5-sonnet")
5757
start_url: Starting URL of the agent run (e.g., "https://amazon.com")
58+
screenshot_processor: Optional function to process screenshots before upload.
59+
Takes base64 string, returns processed base64 string.
60+
Useful for PII redaction or custom image processing.
5861
5962
Returns:
6063
Tracer configured with appropriate sink
@@ -71,6 +74,17 @@ def create_tracer(
7174
... )
7275
>>> # Returns: Tracer with CloudTraceSink
7376
>>>
77+
>>> # With screenshot processor for PII redaction
78+
>>> def redact_pii(screenshot_base64: str) -> str:
79+
... # Your custom redaction logic
80+
... return redacted_screenshot
81+
>>>
82+
>>> tracer = create_tracer(
83+
... api_key="sk_pro_xyz",
84+
... screenshot_processor=redact_pii
85+
... )
86+
>>> # Screenshots will be processed before upload
87+
>>>
7488
>>> # Free tier user
7589
>>> tracer = create_tracer(run_id="demo")
7690
>>> # Returns: Tracer with JsonlTraceSink (local-only)
@@ -133,6 +147,7 @@ def create_tracer(
133147
api_url=api_url,
134148
logger=logger,
135149
),
150+
screenshot_processor=screenshot_processor,
136151
)
137152
else:
138153
print("⚠️ [Sentience] Cloud init response missing upload_url")
@@ -191,7 +206,11 @@ def create_tracer(
191206
local_path = traces_dir / f"{run_id}.jsonl"
192207
print(f"💾 [Sentience] Local tracing: {local_path}")
193208

194-
return Tracer(run_id=run_id, sink=JsonlTraceSink(str(local_path)))
209+
return Tracer(
210+
run_id=run_id,
211+
sink=JsonlTraceSink(str(local_path)),
212+
screenshot_processor=screenshot_processor,
213+
)
195214

196215

197216
def _recover_orphaned_traces(api_key: str, api_url: str = SENTIENCE_API_URL) -> None:

sentience/tracing.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from datetime import datetime
1111
from pathlib import Path
1212
from typing import Any, Optional
13+
from collections.abc import Callable
1314

1415
from .models import TraceStats
1516
from .trace_file_manager import TraceFileManager
@@ -163,10 +164,36 @@ class Tracer:
163164
164165
Manages sequence numbers and provides convenient methods for emitting events.
165166
Tracks execution statistics and final status for trace completion.
167+
168+
Args:
169+
run_id: Unique identifier for this trace run
170+
sink: TraceSink implementation for writing events
171+
screenshot_processor: Optional function to process screenshots before emission.
172+
Takes base64 string, returns processed base64 string.
173+
Useful for PII redaction or custom image processing.
174+
175+
Example:
176+
>>> from sentience import Tracer, JsonlTraceSink
177+
>>>
178+
>>> # Basic usage
179+
>>> sink = JsonlTraceSink("trace.jsonl")
180+
>>> tracer = Tracer(run_id="abc123", sink=sink)
181+
>>>
182+
>>> # With screenshot processor for PII redaction
183+
>>> def redact_pii(screenshot_base64: str) -> str:
184+
... # Your custom redaction logic
185+
... return redacted_screenshot
186+
>>>
187+
>>> tracer = Tracer(
188+
... run_id="abc123",
189+
... sink=sink,
190+
... screenshot_processor=redact_pii
191+
... )
166192
"""
167193

168194
run_id: str
169195
sink: TraceSink
196+
screenshot_processor: Callable[[str], str] | None = None
170197
seq: int = field(default=0, init=False)
171198
# Stats tracking
172199
total_steps: int = field(default=0, init=False)
@@ -196,6 +223,11 @@ def emit(
196223
self.seq += 1
197224
self.total_events += 1
198225

226+
# Apply screenshot processor if configured and screenshot is present
227+
if self.screenshot_processor and "screenshot_base64" in data:
228+
data = data.copy() # Don't modify the original dict
229+
data["screenshot_base64"] = self.screenshot_processor(data["screenshot_base64"])
230+
199231
# Generate timestamps
200232
ts_ms = int(time.time() * 1000)
201233
ts = time.strftime("%Y-%m-%dT%H:%M:%S.000Z", time.gmtime())

0 commit comments

Comments
 (0)