AQIT 0.1.0
Loading...
Searching...
No Matches
feature_neighbors_check.py
Go to the documentation of this file.
1# Copyright (c) 2025-present Aquin Labs Private Limited. All Rights Reserved.
2"""`aquin feature neighbor --check` — save JSON + diagram to the current working directory."""
3
4from __future__ import annotations
5
6import json
7from datetime import datetime, timezone
8from pathlib import Path
9from typing import Any
10
11_JSON_NAME = "feature-neighbors-check.json"
12_PNG_NAME = "feature-neighbors-check.png"
13
14
15def _flatten_feature_neighbors_result(result: dict[str, Any]) -> dict[str, Any]:
16 if result.get("error"):
17 return dict(result)
18
19 data = result.get("content") or result
20 if not isinstance(data, dict):
21 return {"error": "Invalid feature-neighbors result"}
22
23 neighbors = data.get("neighbors") or []
24 return {**data, "neighbors": neighbors}
25
26
28 result: dict[str, Any],
29 *,
30 tool_name: str | None,
31 cwd: str | Path,
32) -> tuple[Path, Path]:
33 cwd = Path(cwd)
34 json_path = cwd / _JSON_NAME
35 png_path = cwd / _PNG_NAME
36
38 payload = {
39 "saved_at": datetime.now(timezone.utc).isoformat(),
40 "tool": tool_name,
41 **flat,
42 }
43 json_path.write_text(json.dumps(payload, indent=2, default=str), encoding="utf-8")
44 _plot_feature_neighbors_check(flat, png_path)
45 return json_path, png_path
46
47
48def _neighbor_label(n: dict[str, Any]) -> str:
49 ref = n.get("feature_ref")
50 if ref:
51 return str(ref)[:28]
52 idx = n.get("feature_idx", "?")
53 label = str(n.get("label") or "")
54 if label:
55 return f"{idx}:{label[:20]}"
56 return f"F{idx}"
57
58
59def _plot_feature_neighbors_check(result: dict[str, Any], png_path: Path) -> None:
60 import matplotlib
61
62 matplotlib.use("Agg")
63 import matplotlib.pyplot as plt
64
65 if result.get("error"):
66 fig, ax = plt.subplots(figsize=(6, 2), facecolor="#0f1117")
67 ax.axis("off")
68 ax.text(0.5, 0.5, f"Error: {result['error']}", ha="center", va="center", wrap=True, color="#e5e7eb")
69 fig.savefig(png_path, dpi=140, bbox_inches="tight", facecolor="#0f1117")
70 plt.close(fig)
71 return
72
73 ref = result.get("feature_ref") or result.get("feature_idx", "?")
74 layer = result.get("layer", "?")
75 label = str(result.get("label") or result.get("causal_label") or "")
76 neighbors = sorted(
77 result.get("neighbors") or [],
78 key=lambda n: float(n.get("similarity") or 0),
79 reverse=True,
80 )
81
82 title = f"Feature neighbors — {ref} · layer {layer}"
83 if label:
84 title += f" · {label[:32]}"
85
86 fig_h = max(4, min(12, len(neighbors) * 0.35 + 1.8))
87 fig, ax = plt.subplots(figsize=(9, fig_h), facecolor="#0f1117")
88 fig.suptitle(title, color="#e5e7eb", fontsize=11, y=0.98)
89
90 ax.set_facecolor("#0f1117")
91 ax.set_title("Decoder cosine similarity (nearest features)", color="#e5e7eb", fontsize=10, pad=10)
92
93 if not neighbors:
94 ax.axis("off")
95 ax.text(0.5, 0.5, "No neighbors found.", ha="center", va="center", color="#9ca3af")
96 else:
97 labels = [_neighbor_label(n) for n in neighbors]
98 vals = [float(n.get("similarity") or 0) for n in neighbors]
99 y_pos = list(range(len(neighbors)))
100 colors = ["#38bdf8" if v >= 0.9 else "#6366f1" if v >= 0.8 else "#78716c" for v in vals]
101 ax.barh(y_pos, vals, color=colors, height=0.72, alpha=0.9)
102 ax.set_yticks(y_pos)
103 ax.set_yticklabels(labels, fontsize=8, color="#d1d5db")
104 ax.invert_yaxis()
105 ax.set_xlim(0, 1.02)
106 ax.set_xlabel("Cosine similarity", color="#9ca3af", fontsize=9)
107 ax.tick_params(axis="x", colors="#6b7280", labelsize=8)
108 ax.grid(axis="x", alpha=0.2, color="#4b5563")
109 for spine in ax.spines.values():
110 spine.set_color("#374151")
111 for i, v in enumerate(vals):
112 ax.text(min(v + 0.01, 0.98), i, f"{v:.4f}", va="center", fontsize=7, color="#9ca3af")
113
114 fig.tight_layout()
115 fig.savefig(png_path, dpi=140, bbox_inches="tight", facecolor="#0f1117")
116 plt.close(fig)
tuple[Path, Path] write_feature_neighbors_check(dict[str, Any] result, *, str|None tool_name, str|Path cwd)
dict[str, Any] _flatten_feature_neighbors_result(dict[str, Any] result)
None _plot_feature_neighbors_check(dict[str, Any] result, Path png_path)