Spaces:
Sleeping
Sleeping
| """ | |
| Interactive probe – explore 3D semantic space with sliders. | |
| """ | |
| from __future__ import annotations | |
| from typing import List | |
| import numpy as np | |
| from tracescope.models.analysis import AnalysisResult | |
| from tracescope.analysis.explainer import SemanticExplainer | |
| def probe_point( | |
| result: AnalysisResult, | |
| x: float, | |
| y: float, | |
| z: float, | |
| k_nearest: int = 5, | |
| ) -> dict: | |
| """Given a 3D coordinate, return nearest texts, cluster info, and axis values. | |
| Args: | |
| result: AnalysisResult from the pipeline. | |
| x, y, z: 3D coordinates of the probe. | |
| k_nearest: Number of nearest points to return. | |
| Returns: | |
| dict with nearest_texts, nearest_indices, cluster_distances, | |
| axis_percentages, etc. | |
| """ | |
| pts = result.projected_3d | |
| probe = np.array([x, y, z]) | |
| # Distances to all points | |
| dists = np.linalg.norm(pts - probe, axis=1) | |
| nearest_indices = np.argsort(dists)[:k_nearest] | |
| nearest_texts = [ | |
| { | |
| "index": int(idx), | |
| "text": result.session.entries[idx].text, | |
| "role": result.session.entries[idx].role, | |
| "distance": float(dists[idx]), | |
| "cluster": result.clusters.labels[idx], | |
| } | |
| for idx in nearest_indices | |
| ] | |
| # Axis percentages (0-100%) | |
| mins = pts.min(axis=0) | |
| maxs = pts.max(axis=0) | |
| ranges = maxs - mins | |
| ranges[ranges == 0] = 1.0 | |
| pct = ((probe - mins) / ranges) * 100 | |
| # Cluster distances (closeness %) | |
| cluster_distances = {} | |
| max_dist = float(np.linalg.norm(maxs - mins)) | |
| for c in range(result.clusters.n_clusters): | |
| centroid = result.cluster_centroids_3d[c] | |
| dist = float(np.linalg.norm(probe - centroid)) | |
| closeness = max(0, (1 - dist / max_dist) * 100) if max_dist > 0 else 0 | |
| label = ( | |
| result.cluster_labels[c] | |
| if c < len(result.cluster_labels) | |
| else f"Cluster {c}" | |
| ) | |
| cluster_distances[label] = round(closeness, 1) | |
| return { | |
| "probe": {"x": x, "y": y, "z": z}, | |
| "axis_percentages": { | |
| result.axis_info.labels[i]: round(float(pct[i]), 1) for i in range(3) | |
| }, | |
| "nearest_texts": nearest_texts, | |
| "cluster_distances": cluster_distances, | |
| } | |
| def probe_with_explanation( | |
| result: AnalysisResult, | |
| explainer: SemanticExplainer, | |
| x: float, | |
| y: float, | |
| z: float, | |
| k_nearest: int = 5, | |
| ) -> dict: | |
| """Probe a point and get an LLM explanation of its meaning. | |
| Returns the same dict as probe_point plus an 'explanation' key. | |
| """ | |
| info = probe_point(result, x, y, z, k_nearest) | |
| # Build cluster distances string | |
| dist_str = ", ".join( | |
| f"{name}: {pct}%" for name, pct in info["cluster_distances"].items() | |
| ) | |
| nearest_texts = [item["text"] for item in info["nearest_texts"]] | |
| pcts = info["axis_percentages"] | |
| axis_labels = list(pcts.keys()) | |
| axis_vals = list(pcts.values()) | |
| explanation = explainer.explain_probe( | |
| axis_labels=axis_labels, | |
| x_val=axis_vals[0], | |
| y_val=axis_vals[1], | |
| z_val=axis_vals[2], | |
| nearest_texts=nearest_texts, | |
| cluster_distances=dist_str, | |
| ) | |
| info["explanation"] = explanation | |
| return info | |