| | import os |
| | import random |
| | import uuid |
| | from typing import Any, Dict, List, Optional |
| |
|
| | from .bundle import write_bundle_zip |
| |
|
| |
|
| | def _env_fingerprint() -> Dict[str, Any]: |
| | return { |
| | "python": os.environ.get("PYTHON_VERSION") or "unknown", |
| | "space": os.environ.get("SPACE_ID") or os.environ.get("HF_SPACE_ID") or "unknown", |
| | } |
| |
|
| |
|
| | def _mk_event(kind: str, step: str, payload: Dict[str, Any]) -> Dict[str, Any]: |
| | return {"kind": kind, "step": step, "payload": payload} |
| |
|
| |
|
| | def make_demo_bundle_zip(out_path: str, *, seed: int, chaos: float, label: str) -> str: |
| | """ |
| | Creates a synthetic agent timeline with controlled randomness. |
| | 'chaos' increases divergence probability. |
| | Also includes reward_total in state snapshots to demonstrate reward delta. |
| | """ |
| | rng = random.Random(seed) |
| | run_id = f"demo-{label}-{uuid.uuid4().hex[:8]}" |
| | framework = "demo-agent" |
| | model_id = "demo-llm" |
| |
|
| | events: List[Dict[str, Any]] = [] |
| | memory: Dict[str, Any] = {"goal": "reach_target", "notes": []} |
| | reward_total = 0.0 |
| |
|
| | |
| | replay = { |
| | "base_url": "https://example.com/replay", |
| | "pattern": "/?run_id={run_id}&i={i}", |
| | } |
| |
|
| | for i in range(40): |
| | action = rng.choice(["scan", "move", "ask_tool", "write_memory"]) |
| | if rng.random() < chaos: |
| | action = rng.choice(["scan", "move", "ask_tool", "write_memory", "panic"]) |
| |
|
| | score = rng.random() |
| | events.append(_mk_event("plan_step", f"t{i}.plan", {"action": action, "score": score})) |
| |
|
| | if action == "ask_tool": |
| | q = rng.choice(["price", "status", "latency", "risk"]) |
| | events.append(_mk_event("tool_call", f"t{i}.tool_call", {"tool": "mock_api", "query": q})) |
| | if rng.random() < (0.15 + chaos * 0.2): |
| | events.append(_mk_event("tool_result", f"t{i}.tool_result", {"ok": False, "error": "timeout"})) |
| | reward_total -= 0.5 |
| | else: |
| | val = rng.randint(1, 100) |
| | events.append(_mk_event("tool_result", f"t{i}.tool_result", {"ok": True, "value": val})) |
| | reward_total += 0.2 |
| | elif action == "write_memory": |
| | note = rng.choice(["cached", "retry", "validated", "unsafe", "needs_review"]) |
| | memory["notes"].append(note) |
| | events.append(_mk_event("memory_write", f"t{i}.mem", {"write": {"notes": list(memory["notes"])}})) |
| | reward_total += 0.05 |
| | elif action == "panic": |
| | events.append(_mk_event("guardrail", f"t{i}.guardrail", {"blocked": True, "reason": "anomaly"})) |
| | events.append( |
| | _mk_event("state_snapshot", f"t{i}.state", {"memory": memory, "mode": "halt", "reward_total": reward_total}) |
| | ) |
| | break |
| | else: |
| | |
| | x = rng.randint(0, 9) |
| | y = rng.randint(0, 9) |
| | reward_total += 0.01 |
| | events.append(_mk_event("state_snapshot", f"t{i}.state", {"x": x, "y": y, "memory": memory, "reward_total": reward_total})) |
| |
|
| | txt = rng.choice( |
| | [ |
| | "Proceed with caution.", |
| | "Tool looks stable.", |
| | "Memory updated.", |
| | "Need more evidence.", |
| | "I will retry once.", |
| | ] |
| | ) |
| | if rng.random() < chaos: |
| | txt = rng.choice( |
| | [ |
| | "Unexpected output detected.", |
| | "I am uncertain; escalating.", |
| | "This seems inconsistent.", |
| | "Plan changed due to drift.", |
| | ] |
| | ) |
| | events.append(_mk_event("llm_sample", f"t{i}.llm", {"text": txt, "tokens": rng.randint(20, 180)})) |
| |
|
| | return write_bundle_zip( |
| | out_path, |
| | run_id=run_id, |
| | framework=framework, |
| | model_id=model_id, |
| | env_fingerprint=_env_fingerprint(), |
| | events_payloads=events, |
| | replay=replay, |
| | ) |
| |
|
| |
|
| | def fork_patch_bundle( |
| | out_path: str, |
| | *, |
| | source_zip: str, |
| | fork_at_index: int, |
| | patch_kind: Optional[str] = None, |
| | patch_step: Optional[str] = None, |
| | patch_payload_json: Optional[Dict[str, Any]] = None, |
| | ) -> str: |
| | """ |
| | Counterfactual workflow: patch an event at index N, re-hash-chain into a new bundle. |
| | """ |
| | from .bundle import load_bundle, write_bundle_zip |
| |
|
| | b = load_bundle(source_zip) |
| | src_events = b.events |
| |
|
| | payloads: List[Dict[str, Any]] = [] |
| | for ev in src_events: |
| | payloads.append( |
| | { |
| | "ts": ev.get("ts"), |
| | "kind": ev.get("kind"), |
| | "step": ev.get("step"), |
| | "payload": ev.get("payload", {}), |
| | } |
| | ) |
| |
|
| | if 0 <= fork_at_index < len(payloads): |
| | if patch_kind: |
| | payloads[fork_at_index]["kind"] = patch_kind |
| | if patch_step: |
| | payloads[fork_at_index]["step"] = patch_step |
| | if patch_payload_json is not None: |
| | payloads[fork_at_index]["payload"] = patch_payload_json |
| |
|
| | new_run = f"{b.manifest.get('run_id','run')}-fork" |
| | return write_bundle_zip( |
| | out_path, |
| | run_id=new_run, |
| | framework=b.manifest.get("framework", "unknown"), |
| | model_id=b.manifest.get("model_id", "unknown"), |
| | env_fingerprint=b.manifest.get("env", {}), |
| | events_payloads=payloads, |
| | replay=b.manifest.get("replay"), |
| | run_url=b.manifest.get("run_url"), |
| | ) |