← back to invincible-jha__agent-sim-bridge

Function bodies 210 total

All specs Real LLM only Function bodies
RealityEnvironment.step method · python · L161-L187 (27 LOC)
src/agent_sim_bridge/environment/real_env.py
    def step(self, action: NDArray[np.float32]) -> StepResult:
        self._ensure_open()
        self._ensure_reset()

        t_start = time.monotonic()
        obs, reward, terminated, truncated, info = self._interface.system_step(action)
        elapsed = time.monotonic() - t_start

        if self._step_timeout is not None and elapsed > self._step_timeout:
            raise StepTimeoutError(
                f"Hardware step took {elapsed:.3f}s, exceeding timeout "
                f"of {self._step_timeout}s for environment {self._info.name!r}."
            )

        self._episode_step += 1
        if self._episode_step >= self._info.max_episode_steps:
            truncated = True

        logger.debug(
            "%s step %d: reward=%.4f terminated=%s elapsed=%.3fs",
            self._info.name,
            self._episode_step,
            reward,
            terminated,
            elapsed,
        )
        return StepResult(obs, reward, terminated, truncated, info)
RealityEnvironment._ensure_reset method · python · L214-L219 (6 LOC)
src/agent_sim_bridge/environment/real_env.py
    def _ensure_reset(self) -> None:
        if self._require_reset and not self._has_reset:
            raise RuntimeError(
                f"Environment {self._info.name!r} must be reset before "
                "the first action is sent to prevent accidental actuation."
            )
SimBackend.backend_reset method · python · L33-L39 (7 LOC)
src/agent_sim_bridge/environment/sim_env.py
    def backend_reset(
        self,
        seed: int | None,
        options: dict[str, object] | None,
    ) -> NDArray[np.float32]:
        """Reset the backend and return the initial observation."""
        ...
SimBackend.backend_step method · python · L41-L46 (6 LOC)
src/agent_sim_bridge/environment/sim_env.py
    def backend_step(
        self,
        action: NDArray[np.float32],
    ) -> tuple[NDArray[np.float32], float, bool, bool, dict[str, object]]:
        """Advance by one step and return ``(obs, reward, terminated, truncated, info)``."""
        ...
SimulationEnvironment.__init__ method · python · L95-L120 (26 LOC)
src/agent_sim_bridge/environment/sim_env.py
    def __init__(
        self,
        backend: SimBackend,
        name: str = "sim-environment",
        max_episode_steps: int = 1000,
        record_trajectories: bool = False,
    ) -> None:
        if not isinstance(backend, SimBackend):
            raise TypeError(
                f"backend must satisfy the SimBackend protocol, got {type(backend)!r}"
            )
        self._backend = backend
        self._info = EnvironmentInfo(
            name=name,
            is_simulation=True,
            max_episode_steps=max_episode_steps,
        )
        self._record = record_trajectories
        self._trajectory: list[
            tuple[NDArray[np.float32], NDArray[np.float32], float]
        ] = []
        self._episode_step: int = 0
        self._current_obs: NDArray[np.float32] = np.zeros(
            self._backend.backend_state_space.shape, dtype=np.float32
        )
        self._closed: bool = False
SimulationEnvironment.reset method · python · L154-L166 (13 LOC)
src/agent_sim_bridge/environment/sim_env.py
    def reset(
        self,
        *,
        seed: int | None = None,
        options: dict[str, object] | None = None,
    ) -> tuple[NDArray[np.float32], dict[str, object]]:
        self._ensure_open()
        self._trajectory.clear()
        self._episode_step = 0
        obs = self._backend.backend_reset(seed, options)
        self._current_obs = obs
        logger.debug("%s reset (seed=%s)", self._info.name, seed)
        return obs, {}
SimulationEnvironment.step method · python · L168-L180 (13 LOC)
src/agent_sim_bridge/environment/sim_env.py
    def step(self, action: NDArray[np.float32]) -> StepResult:
        self._ensure_open()
        obs, reward, terminated, truncated, info = self._backend.backend_step(action)
        self._episode_step += 1
        self._current_obs = obs

        if self._record:
            self._trajectory.append((self._current_obs.copy(), action.copy(), reward))

        if self._episode_step >= self._info.max_episode_steps:
            truncated = True

        return StepResult(obs, reward, terminated, truncated, info)
Repobility · code-quality intelligence platform · https://repobility.com
GapEstimator.estimate_dimension method · python · L149-L181 (33 LOC)
src/agent_sim_bridge/gap/estimator.py
    def estimate_dimension(self, dim: GapDimension) -> list[DimensionGap]:
        """Compute all configured metrics for a single dimension.

        Parameters
        ----------
        dim:
            The :class:`GapDimension` to analyse.

        Returns
        -------
        list[DimensionGap]
            One :class:`DimensionGap` per configured metric.
        """
        results: list[DimensionGap] = []
        for metric in self._metrics:
            value = self._compute_metric(metric, dim)
            interpretation = self._interpret(metric, value)
            results.append(
                DimensionGap(
                    dimension_name=dim.name,
                    metric=metric,
                    value=value,
                    interpretation=interpretation,
                )
            )
            logger.debug(
                "Gap[%s, %s] = %.6f (%s)",
                dim.name,
                metric.value,
                value,
                interpretation
GapEstimator.estimate_all method · python · L183-L198 (16 LOC)
src/agent_sim_bridge/gap/estimator.py
    def estimate_all(
        self, dimensions: list[GapDimension]
    ) -> dict[str, list[DimensionGap]]:
        """Compute all configured metrics for multiple dimensions.

        Parameters
        ----------
        dimensions:
            Sequence of :class:`GapDimension` objects.

        Returns
        -------
        dict[str, list[DimensionGap]]
            Mapping from dimension name to its list of gap results.
        """
        return {dim.name: self.estimate_dimension(dim) for dim in dimensions}
GapEstimator.overall_gap_score method · python · L200-L230 (31 LOC)
src/agent_sim_bridge/gap/estimator.py
    def overall_gap_score(
        self, dimension_gaps: dict[str, list[DimensionGap]]
    ) -> float:
        """Compute a single weighted average gap score in [0, 1].

        Each :class:`DimensionGap` value is first normalised to [0, 1] using
        the ``"high"`` threshold for the respective metric before being
        averaged.  This makes the final score interpretable regardless of
        the differing natural scales of the individual metrics.

        Parameters
        ----------
        dimension_gaps:
            Output of :meth:`estimate_all`.

        Returns
        -------
        float
            Weighted average gap score ∈ [0, 1].  Returns 0.0 if there are
            no results.
        """
        normalised_values: list[float] = []
        for gaps in dimension_gaps.values():
            for gap in gaps:
                high_threshold = _THRESHOLDS[gap.metric.value][1]
                normalised = min(1.0, gap.value / high_threshold) if high_threshold > 0.0 else
GapEstimator._compute_metric method · python · L236-L263 (28 LOC)
src/agent_sim_bridge/gap/estimator.py
    def _compute_metric(self, metric: GapMetric, dim: GapDimension) -> float:
        """Dispatch to the correct statistical function for *metric*.

        Parameters
        ----------
        metric:
            The metric to compute.
        dim:
            Source of sim/real distributions.

        Returns
        -------
        float
            The computed distance value.
        """
        sim = dim.sim_distribution
        real = dim.real_distribution

        if metric is GapMetric.KL_DIVERGENCE:
            return kl_divergence(sim, real)
        if metric is GapMetric.WASSERSTEIN:
            return wasserstein_distance_1d(sim, real)
        if metric is GapMetric.MMD:
            return maximum_mean_discrepancy(sim, real)
        if metric is GapMetric.JENSEN_SHANNON:
            return jensen_shannon_divergence(sim, real)
        # Unreachable for a well-typed GapMetric, but guards future additions.
        raise ValueError(f"Unknown GapMetric: {metric!r}")  # pragma:
GapEstimator._interpret method · python · L265-L285 (21 LOC)
src/agent_sim_bridge/gap/estimator.py
    def _interpret(self, metric: GapMetric, value: float) -> str:
        """Map a raw distance value to a qualitative severity label.

        Parameters
        ----------
        metric:
            The metric whose thresholds to apply.
        value:
            The computed distance.

        Returns
        -------
        str
            ``"low"``, ``"medium"``, or ``"high"``.
        """
        low_upper, medium_upper = _THRESHOLDS[metric.value]
        if value <= low_upper:
            return "low"
        if value <= medium_upper:
            return "medium"
        return "high"
ProductionTelemetryImporter.load_jsonl method · python · L124-L166 (43 LOC)
src/agent_sim_bridge/gap/production_import.py
    def load_jsonl(
        self, content: str, source_name: str = "unknown"
    ) -> ImportedTelemetry:
        """Parse JSON Lines format telemetry.

        Parameters
        ----------
        content:
            The raw JSON Lines string (one JSON object per line).
        source_name:
            Label for this data source.

        Returns
        -------
        ImportedTelemetry
            Parsed telemetry container.
        """
        records: list[dict[str, object]] = []
        errors = 0
        for line in content.splitlines():
            line = line.strip()
            if not line:
                continue
            try:
                record = json.loads(line)
                if isinstance(record, dict):
                    records.append(record)
                else:
                    errors += 1
            except json.JSONDecodeError:
                errors += 1

        metric_names: set[str] = set()
        for record in records:
            metric_names.
ProductionTelemetryImporter.load_csv method · python · L168-L213 (46 LOC)
src/agent_sim_bridge/gap/production_import.py
    def load_csv(
        self, content: str, source_name: str = "unknown"
    ) -> ImportedTelemetry:
        """Parse CSV format telemetry.

        Parameters
        ----------
        content:
            The raw CSV string (first row = header).
        source_name:
            Label for this data source.

        Returns
        -------
        ImportedTelemetry
            Parsed telemetry container.
        """
        records: list[dict[str, object]] = []
        errors = 0
        reader = csv.DictReader(io.StringIO(content))
        for row in reader:
            parsed_row: dict[str, object] = {}
            row_ok = True
            for key, value in row.items():
                if value is None or value == "":
                    continue
                try:
                    parsed_row[key] = float(value)
                except (ValueError, TypeError):
                    parsed_row[key] = value  # Keep as string if not numeric
            if row_ok:
                r
ProductionTelemetryImporter.compare method · python · L219-L283 (65 LOC)
src/agent_sim_bridge/gap/production_import.py
    def compare(
        self,
        real_telemetry: ImportedTelemetry,
        sim_data: dict[str, list[float]],
    ) -> list[MetricComparison]:
        """Compare real telemetry against simulated data.

        For each metric in *sim_data* that also appears in *real_telemetry*,
        compute descriptive statistics and return a :class:`MetricComparison`.

        Parameters
        ----------
        real_telemetry:
            Imported real-world telemetry.
        sim_data:
            Mapping of metric name → list of simulated values.

        Returns
        -------
        list[MetricComparison]
            One comparison per matched metric.
        """
        comparisons: list[MetricComparison] = []

        # Extract real values per metric
        real_values: dict[str, list[float]] = {}
        for record in real_telemetry.records:
            for metric, value in record.items():
                if isinstance(value, (int, float)):
                    real_values.setdefa
Repobility analyzer · published findings · https://repobility.com
ProductionTelemetryImporter.extract_metric method · python · L285-L307 (23 LOC)
src/agent_sim_bridge/gap/production_import.py
    def extract_metric(
        self, telemetry: ImportedTelemetry, metric_name: str
    ) -> list[float]:
        """Extract all numeric values for a single metric from telemetry.

        Parameters
        ----------
        telemetry:
            The imported telemetry.
        metric_name:
            The metric key to extract.

        Returns
        -------
        list[float]
            All numeric values found for the metric.
        """
        values: list[float] = []
        for record in telemetry.records:
            v = record.get(metric_name)
            if isinstance(v, (int, float)):
                values.append(float(v))
        return values
ProductionTelemetryImporter._std method · python · L321-L328 (8 LOC)
src/agent_sim_bridge/gap/production_import.py
    def _std(values: list[float]) -> float:
        """Compute population standard deviation."""
        n = len(values)
        if n < 2:
            return 0.0
        mean = sum(values) / n
        variance = sum((v - mean) ** 2 for v in values) / n
        return variance ** 0.5
GapReporter.generate_report method · python · L87-L126 (40 LOC)
src/agent_sim_bridge/gap/report.py
    def generate_report(
        self,
        estimator_results: dict[str, list[DimensionGap]],
        dimensions: list[GapDimension],
    ) -> GapReport:
        """Build a :class:`GapReport` from estimator output.

        Parameters
        ----------
        estimator_results:
            Output of :meth:`~GapEstimator.estimate_all`.
        dimensions:
            The original :class:`GapDimension` list (used to build the
            estimator on-demand for the overall score).

        Returns
        -------
        GapReport
            Fully populated report.
        """
        estimator = GapEstimator()
        overall_score = estimator.overall_gap_score(estimator_results)
        summary = self._generate_summary(overall_score)
        recommendations = self._generate_recommendations(estimator_results)

        report = GapReport(
            report_id=str(uuid.uuid4()),
            created_at=datetime.now(tz=timezone.utc),
            dimensions=estimator_results,
        
GapReporter.format_text method · python · L128-L170 (43 LOC)
src/agent_sim_bridge/gap/report.py
    def format_text(self, report: GapReport) -> str:
        """Render a human-readable plain-text report.

        Parameters
        ----------
        report:
            The :class:`GapReport` to format.

        Returns
        -------
        str
            Multi-line text suitable for terminal output.
        """
        lines: list[str] = []
        lines.append("=" * 60)
        lines.append("Sim-to-Real Gap Report")
        lines.append("=" * 60)
        lines.append(f"Report ID   : {report.report_id}")
        lines.append(f"Created At  : {report.created_at.isoformat()}")
        lines.append(f"Overall Score: {report.overall_score:.4f} (0=no gap, 1=maximum gap)")
        lines.append("")
        lines.append(f"Summary: {report.summary}")
        lines.append("")

        if report.dimensions:
            lines.append("Dimension Results:")
            lines.append("-" * 60)
            for dimension_name, gaps in sorted(report.dimensions.items()):
                lines.appen
GapReporter.format_json method · python · L172-L203 (32 LOC)
src/agent_sim_bridge/gap/report.py
    def format_json(self, report: GapReport) -> str:
        """Render the report as a JSON string.

        Parameters
        ----------
        report:
            The :class:`GapReport` to format.

        Returns
        -------
        str
            Pretty-printed JSON with 2-space indentation.
        """
        payload: dict[str, object] = {
            "report_id": report.report_id,
            "created_at": report.created_at.isoformat(),
            "overall_score": report.overall_score,
            "summary": report.summary,
            "recommendations": list(report.recommendations),
            "dimensions": {
                dimension_name: [
                    {
                        "metric": gap.metric.value,
                        "value": gap.value,
                        "interpretation": gap.interpretation,
                    }
                    for gap in gaps
                ]
                for dimension_name, gaps in report.dimensions.items()
      
GapReporter.format_markdown method · python · L205-L251 (47 LOC)
src/agent_sim_bridge/gap/report.py
    def format_markdown(self, report: GapReport) -> str:
        """Render the report as a Markdown document.

        Parameters
        ----------
        report:
            The :class:`GapReport` to format.

        Returns
        -------
        str
            Markdown-formatted report suitable for GitHub, Confluence, etc.
        """
        lines: list[str] = []
        lines.append("# Sim-to-Real Gap Report")
        lines.append("")
        lines.append(f"**Report ID:** `{report.report_id}`")
        lines.append(f"**Created:** {report.created_at.isoformat()}")
        lines.append(f"**Overall Score:** {report.overall_score:.4f} *(0 = no gap, 1 = maximum gap)*")
        lines.append("")
        lines.append(f"## Summary")
        lines.append("")
        lines.append(report.summary)
        lines.append("")

        if report.dimensions:
            lines.append("## Dimension Results")
            lines.append("")
            for dimension_name, gaps in sorted(report.dimensi
GapReporter._generate_summary method · python · L257-L283 (27 LOC)
src/agent_sim_bridge/gap/report.py
    def _generate_summary(self, overall_score: float) -> str:
        """Produce a one-sentence summary from the overall score.

        Parameters
        ----------
        overall_score:
            Weighted average gap score in [0, 1].

        Returns
        -------
        str
            Human-readable severity summary.
        """
        if overall_score < 0.2:
            return (
                "The sim-to-real gap is low; the simulation closely matches the "
                "real-world distributions."
            )
        if overall_score < 0.5:
            return (
                "The sim-to-real gap is moderate; some dimensions show meaningful "
                "divergence that may affect transfer performance."
            )
        return (
            "The sim-to-real gap is high; significant distribution mismatches "
            "detected across multiple dimensions — transfer is likely unreliable."
        )
GapReporter._generate_recommendations method · python · L285-L374 (90 LOC)
src/agent_sim_bridge/gap/report.py
    def _generate_recommendations(
        self, dimension_gaps: dict[str, list[DimensionGap]]
    ) -> list[str]:
        """Produce heuristic recommendations based on gap severity.

        Rules applied (in priority order):
        - Any ``"high"`` interpretation in any dimension → recommend domain randomisation.
        - Any ``"medium"`` or ``"high"`` interpretation → recommend recalibration.
        - KL divergence is ``"high"`` → recommend re-examining reward shaping.
        - Wasserstein is ``"high"`` → recommend adjusting sim physics parameters.
        - MMD is ``"high"`` → recommend increasing sample diversity.
        - JSD is ``"high"`` → recommend reviewing observation normalisation.
        - All gaps are ``"low"`` → positive feedback.

        Parameters
        ----------
        dimension_gaps:
            Mapping from dimension name to its list of :class:`DimensionGap` values.

        Returns
        -------
        list[str]
            Deduplicated list of action
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
_smooth function · python · L42-L57 (16 LOC)
src/agent_sim_bridge/gap/statistics.py
def _smooth(values: list[float], epsilon: float = _EPSILON) -> list[float]:
    """Add *epsilon* to every element to avoid log(0) in KL computation.

    Parameters
    ----------
    values:
        Raw probability mass values (need not sum to 1).
    epsilon:
        Additive smoothing constant.

    Returns
    -------
    list[float]
        Smoothed values (not renormalised).
    """
    return [v + epsilon for v in values]
_renormalize function · python · L60-L83 (24 LOC)
src/agent_sim_bridge/gap/statistics.py
def _renormalize(values: list[float]) -> list[float]:
    """Divide each element by the total sum.

    Parameters
    ----------
    values:
        Non-negative floats.

    Returns
    -------
    list[float]
        Values that sum to 1.0.

    Raises
    ------
    ValueError
        If the sum is zero (all values are zero).
    """
    total = sum(values)
    if total == 0.0:
        raise ValueError(
            "Cannot normalise a distribution whose elements all sum to zero."
        )
    return [v / total for v in values]
_cdf function · python · L86-L105 (20 LOC)
src/agent_sim_bridge/gap/statistics.py
def _cdf(distribution: list[float]) -> list[float]:
    """Compute the empirical CDF from a probability mass vector.

    Parameters
    ----------
    distribution:
        Probability mass vector (should sum to 1.0; treated as relative weights
        if it does not).

    Returns
    -------
    list[float]
        Cumulative distribution of the same length.
    """
    cumulative: list[float] = []
    running_total = 0.0
    for mass in distribution:
        running_total += mass
        cumulative.append(running_total)
    return cumulative
_percentile function · python · L108-L134 (27 LOC)
src/agent_sim_bridge/gap/statistics.py
def _percentile(sorted_values: list[float], fraction: float) -> float:
    """Interpolated percentile for a pre-sorted list.

    Uses the linear interpolation method (equivalent to numpy's method=7).

    Parameters
    ----------
    sorted_values:
        Pre-sorted list of floats (ascending).
    fraction:
        Fraction in [0, 1] (e.g. 0.25 for Q1, 0.75 for Q3).

    Returns
    -------
    float
        The interpolated percentile value.
    """
    n = len(sorted_values)
    if n == 1:
        return sorted_values[0]
    index = fraction * (n - 1)
    lower = int(index)
    upper = lower + 1
    if upper >= n:
        return sorted_values[n - 1]
    weight = index - lower
    return sorted_values[lower] + weight * (sorted_values[upper] - sorted_values[lower])
normalize_distribution function · python · L142-L167 (26 LOC)
src/agent_sim_bridge/gap/statistics.py
def normalize_distribution(values: list[float]) -> list[float]:
    """Normalise a list of non-negative floats so they sum to 1.0.

    Parameters
    ----------
    values:
        Non-negative floats representing counts, densities, or raw weights.

    Returns
    -------
    list[float]
        Values normalised to sum to 1.0.

    Raises
    ------
    ValueError
        If *values* is empty or all elements are zero.

    Examples
    --------
    >>> normalize_distribution([1.0, 2.0, 1.0])
    [0.25, 0.5, 0.25]
    """
    if not values:
        raise ValueError("Cannot normalise an empty distribution.")
    return _renormalize(values)
kl_divergence function · python · L170-L217 (48 LOC)
src/agent_sim_bridge/gap/statistics.py
def kl_divergence(p: list[float], q: list[float]) -> float:
    """Kullback-Leibler divergence KL(P || Q).

    KL(P || Q) = Σ p(i) * log(p(i) / q(i))

    Zero-handling is performed by adding *epsilon* = 1e-10 to every element
    before normalising, preventing log(0) and division-by-zero.

    Parameters
    ----------
    p:
        Reference distribution (will be normalised internally).
    q:
        Approximate distribution (will be normalised internally).

    Returns
    -------
    float
        KL divergence ≥ 0.  Returns 0.0 for identical distributions.

    Raises
    ------
    ValueError
        If *p* and *q* have different lengths or are empty.

    Notes
    -----
    The result is not symmetric: KL(P || Q) ≠ KL(Q || P) in general.

    Examples
    --------
    >>> kl_divergence([0.5, 0.5], [0.5, 0.5])
    0.0
    """
    if not p or not q:
        raise ValueError("Distributions must be non-empty.")
    if len(p) != len(q):
        raise ValueError(
            f"Dis
wasserstein_distance_1d function · python · L220-L268 (49 LOC)
src/agent_sim_bridge/gap/statistics.py
def wasserstein_distance_1d(p: list[float], q: list[float]) -> float:
    """Wasserstein-1 (Earth Mover's) distance for 1-D distributions.

    Computed as the L1 distance between the cumulative distribution functions:

        W₁(P, Q) = Σ |CDF_P(i) - CDF_Q(i)| * bin_width

    where bin_width = 1 / n (uniform bins).

    Parameters
    ----------
    p:
        Probability mass vector for distribution P (will be normalised).
    q:
        Probability mass vector for distribution Q (will be normalised).

    Returns
    -------
    float
        Wasserstein-1 distance ≥ 0.  Returns 0.0 for identical distributions.

    Raises
    ------
    ValueError
        If *p* and *q* have different lengths or are empty.

    Examples
    --------
    >>> wasserstein_distance_1d([1.0, 0.0], [0.0, 1.0])
    0.5
    """
    if not p or not q:
        raise ValueError("Distributions must be non-empty.")
    if len(p) != len(q):
        raise ValueError(
            f"Distributions must have the sa
maximum_mean_discrepancy function · python · L271-L338 (68 LOC)
src/agent_sim_bridge/gap/statistics.py
def maximum_mean_discrepancy(
    x: list[float],
    y: list[float],
    bandwidth: float = 1.0,
) -> float:
    """Maximum Mean Discrepancy with an RBF (Gaussian) kernel.

    MMD²(X, Y) = E[k(x, x')] - 2 E[k(x, y)] + E[k(y, y')]

    where k(a, b) = exp(-||a - b||² / (2 * bandwidth²)).

    MMD is returned as the non-negative square root of MMD².

    Parameters
    ----------
    x:
        Samples from the first distribution.
    y:
        Samples from the second distribution.
    bandwidth:
        RBF kernel bandwidth σ (standard deviation of the Gaussian).
        Larger values make the kernel smoother / less sensitive to
        fine-grained differences.

    Returns
    -------
    float
        MMD ≥ 0.  Returns approximately 0 when X and Y are drawn from the
        same distribution.

    Raises
    ------
    ValueError
        If either sample is empty or *bandwidth* ≤ 0.

    Examples
    --------
    >>> maximum_mean_discrepancy([0.0, 1.0], [0.0, 1.0])  # same → ~0
  
All rows above produced by Repobility · https://repobility.com
jensen_shannon_divergence function · python · L341-L396 (56 LOC)
src/agent_sim_bridge/gap/statistics.py
def jensen_shannon_divergence(p: list[float], q: list[float]) -> float:
    """Jensen-Shannon divergence between two distributions.

    JSD(P, Q) = 0.5 * KL(P || M) + 0.5 * KL(Q || M)

    where M = 0.5 * (P + Q).

    JSD is symmetric and bounded in [0, log(2)] (using natural log).  It
    equals 0 iff P = Q.

    Parameters
    ----------
    p:
        First distribution (will be normalised internally).
    q:
        Second distribution (will be normalised internally).

    Returns
    -------
    float
        JSD ∈ [0, ln(2)] ≈ [0, 0.693].  Returns 0.0 for identical
        distributions.

    Raises
    ------
    ValueError
        If *p* and *q* have different lengths or are empty.

    Examples
    --------
    >>> jensen_shannon_divergence([0.5, 0.5], [0.5, 0.5])
    0.0
    """
    if not p or not q:
        raise ValueError("Distributions must be non-empty.")
    if len(p) != len(q):
        raise ValueError(
            f"Distributions must have the same length; got {len
descriptive_stats function · python · L399-L447 (49 LOC)
src/agent_sim_bridge/gap/statistics.py
def descriptive_stats(values: list[float]) -> dict[str, float]:
    """Compute descriptive statistics for a sample.

    Parameters
    ----------
    values:
        Sample of floats.  Must be non-empty.

    Returns
    -------
    dict[str, float]
        Dictionary with keys: ``mean``, ``std``, ``min``, ``max``,
        ``median``, ``q25``, ``q75``.

    Raises
    ------
    ValueError
        If *values* is empty.

    Examples
    --------
    >>> stats = descriptive_stats([1.0, 2.0, 3.0, 4.0, 5.0])
    >>> stats["mean"]
    3.0
    """
    if not values:
        raise ValueError("descriptive_stats requires at least one value.")

    n = len(values)
    mean = sum(values) / n
    variance = sum((v - mean) ** 2 for v in values) / n
    std = math.sqrt(variance)

    sorted_values = sorted(values)
    minimum = sorted_values[0]
    maximum = sorted_values[-1]
    median = _percentile(sorted_values, 0.5)
    q25 = _percentile(sorted_values, 0.25)
    q75 = _percentile(sorted_values
GapReport.summary method · python · L59-L70 (12 LOC)
src/agent_sim_bridge/metrics/gap.py
    def summary(self) -> dict[str, float | int | object]:
        """Return a flat dict of all gap metrics."""
        return {
            "observation_mae": self.observation_mae,
            "observation_rmse": self.observation_rmse,
            "reward_mae": self.reward_mae,
            "reward_bias": self.reward_bias,
            "trajectory_length_ratio": self.trajectory_length_ratio,
            "overall_gap_score": self.overall_gap_score,
            "n_sim_steps": self.n_sim_steps,
            "n_real_steps": self.n_real_steps,
        }
GapReport.compute_overall_score method · python · L72-L113 (42 LOC)
src/agent_sim_bridge/metrics/gap.py
    def compute_overall_score(
        self,
        obs_weight: float = 0.5,
        reward_weight: float = 0.3,
        length_weight: float = 0.2,
    ) -> float:
        """Compute and store a weighted overall gap score.

        The score is a convex combination of sub-metric scores.  Sub-metric
        contributions are normalised so they are on comparable scales:

        * Observation: MAE (already normalised per element).
        * Reward: MAE.
        * Length: |ratio - 1|.

        Parameters
        ----------
        obs_weight:
            Weight for observation MAE contribution.
        reward_weight:
            Weight for reward MAE contribution.
        length_weight:
            Weight for trajectory length ratio deviation.

        Returns
        -------
        float
            The overall gap score (stored in :attr:`overall_gap_score`).
        """
        total_weight = obs_weight + reward_weight + length_weight
        if total_weight == 0.0:
            self.
SimRealGap.measure_gap method · python · L139-L219 (81 LOC)
src/agent_sim_bridge/metrics/gap.py
    def measure_gap(
        self,
        sim_observations: list[list[float]],
        real_observations: list[list[float]],
        sim_rewards: list[float] | None = None,
        real_rewards: list[float] | None = None,
    ) -> GapReport:
        """Compute the sim-to-real gap from paired trajectories.

        Parameters
        ----------
        sim_observations:
            Observation vectors from the simulation trajectory.
        real_observations:
            Observation vectors from the real trajectory.  Must have the same
            inner dimensionality as ``sim_observations``.
        sim_rewards:
            Scalar rewards from the simulation (optional).
        real_rewards:
            Scalar rewards from the real system (optional).

        Returns
        -------
        GapReport
            Computed gap metrics with :attr:`~GapReport.overall_gap_score`
            already calculated.
        """
        n_sim = len(sim_observations)
        n_real = len(real_obse
_statistics function · python · L49-L64 (16 LOC)
src/agent_sim_bridge/metrics/performance.py
def _statistics(values: list[float]) -> dict[str, float]:
    """Compute min, max, mean, std, and count for a list of floats."""
    n = len(values)
    if n == 0:
        return {"count": 0.0, "min": float("nan"), "max": float("nan"),
                "mean": float("nan"), "std": float("nan")}
    total = sum(values)
    mean = total / n
    variance = sum((v - mean) ** 2 for v in values) / n
    return {
        "count": float(n),
        "min": min(values),
        "max": max(values),
        "mean": mean,
        "std": math.sqrt(variance),
    }
PerformanceTracker.record method · python · L90-L122 (33 LOC)
src/agent_sim_bridge/metrics/performance.py
    def record(
        self,
        name: str,
        value: float,
        step: int | None = None,
        tags: list[str] | None = None,
    ) -> None:
        """Append one value for metric ``name``.

        Parameters
        ----------
        name:
            Metric identifier.
        value:
            The scalar value to record.
        step:
            Optional step index.
        tags:
            Optional labels.
        """
        metric_record = MetricRecord(
            name=name,
            value=value,
            step=step,
            tags=tags or [],
        )
        if name not in self._records:
            self._records[name] = []
        bucket = self._records[name]
        bucket.append(metric_record)
        if self._max_records is not None and len(bucket) > self._max_records:
            bucket.pop(0)
        logger.debug("Recorded metric %r = %.6f (step=%s).", name, value, step)
PerformanceTracker.record_many method · python · L124-L135 (12 LOC)
src/agent_sim_bridge/metrics/performance.py
    def record_many(self, values: dict[str, float], step: int | None = None) -> None:
        """Convenience method to record multiple metrics at once.

        Parameters
        ----------
        values:
            Mapping of metric name to value.
        step:
            Shared step index applied to all metrics.
        """
        for name, value in values.items():
            self.record(name, value, step=step)
Repobility · code-quality intelligence platform · https://repobility.com
PerformanceTracker.get_values method · python · L137-L150 (14 LOC)
src/agent_sim_bridge/metrics/performance.py
    def get_values(self, name: str) -> list[float]:
        """Return all recorded values for metric ``name``.

        Parameters
        ----------
        name:
            Metric name.

        Returns
        -------
        list[float]
            Values in recording order.  Empty list if metric not yet recorded.
        """
        return [r.value for r in self._records.get(name, [])]
PerformanceTracker.summary method · python · L156-L167 (12 LOC)
src/agent_sim_bridge/metrics/performance.py
    def summary(self) -> dict[str, dict[str, float]]:
        """Compute statistics for every recorded metric.

        Returns
        -------
        dict[str, dict[str, float]]
            Mapping of metric name to ``{count, min, max, mean, std}``.
        """
        return {
            name: _statistics(self.get_values(name))
            for name in sorted(self._records)
        }
PerformanceTracker.metric_summary method · python · L169-L182 (14 LOC)
src/agent_sim_bridge/metrics/performance.py
    def metric_summary(self, name: str) -> dict[str, float]:
        """Compute statistics for one named metric.

        Parameters
        ----------
        name:
            Metric name.

        Returns
        -------
        dict[str, float]
            ``{count, min, max, mean, std}``.
        """
        return _statistics(self.get_values(name))
PerformanceTracker.reset method · python · L188-L199 (12 LOC)
src/agent_sim_bridge/metrics/performance.py
    def reset(self, name: str | None = None) -> None:
        """Clear recorded data.

        Parameters
        ----------
        name:
            If given, clear only that metric.  Otherwise clear all metrics.
        """
        if name is not None:
            self._records.pop(name, None)
        else:
            self._records.clear()
PerformanceTracker.__repr__ method · python · L204-L209 (6 LOC)
src/agent_sim_bridge/metrics/performance.py
    def __repr__(self) -> str:
        return (
            f"PerformanceTracker("
            f"n_metrics={len(self._records)}, "
            f"metrics={self.metric_names()})"
        )
PluginNotFoundError.__init__ method · python · L55-L62 (8 LOC)
src/agent_sim_bridge/plugins/registry.py
    def __init__(self, name: str, registry_name: str) -> None:
        self.plugin_name = name
        self.registry_name = registry_name
        super().__init__(
            f"Plugin {name!r} is not registered in the {registry_name!r} registry. "
            f"Available plugins: {name!r} was not found. "
            "Check that the package is installed and its entry-points are declared."
        )
PluginAlreadyRegisteredError.__init__ method · python · L68-L74 (7 LOC)
src/agent_sim_bridge/plugins/registry.py
    def __init__(self, name: str, registry_name: str) -> None:
        self.plugin_name = name
        self.registry_name = registry_name
        super().__init__(
            f"Plugin {name!r} is already registered in the {registry_name!r} registry. "
            "Use a unique name or explicitly deregister the existing entry first."
        )
PluginRegistry.register method · python · L100-L147 (48 LOC)
src/agent_sim_bridge/plugins/registry.py
    def register(self, name: str) -> Callable[[type[T]], type[T]]:
        """Return a class decorator that registers the decorated class.

        Parameters
        ----------
        name:
            The unique string key for this plugin.

        Returns
        -------
        Callable[[type[T]], type[T]]
            A decorator that registers the class and returns it unchanged,
            allowing it to remain usable as a normal class.

        Raises
        ------
        PluginAlreadyRegisteredError
            If ``name`` is already in use in this registry.
        TypeError
            If the decorated class does not subclass ``base_class``.

        Example
        -------
        ::

            @registry.register("my-plugin")
            class MyPlugin(BasePlugin):
                ...
        """

        def decorator(cls: type[T]) -> type[T]:
            if name in self._plugins:
                raise PluginAlreadyRegisteredError(name, self._name)
            if not (
Repobility analyzer · published findings · https://repobility.com
PluginRegistry.register_class method · python · L149-L182 (34 LOC)
src/agent_sim_bridge/plugins/registry.py
    def register_class(self, name: str, cls: type[T]) -> None:
        """Register a class directly without using the decorator syntax.

        This is useful for programmatic registration, such as inside
        ``load_entrypoints``.

        Parameters
        ----------
        name:
            The unique string key for this plugin.
        cls:
            The class to register. Must subclass ``base_class``.

        Raises
        ------
        PluginAlreadyRegisteredError
            If ``name`` is already registered.
        TypeError
            If ``cls`` is not a subclass of ``base_class``.
        """
        if name in self._plugins:
            raise PluginAlreadyRegisteredError(name, self._name)
        if not (isinstance(cls, type) and issubclass(cls, self._base_class)):
            raise TypeError(
                f"Cannot register {cls!r} under {name!r}: "
                f"it must be a subclass of {self._base_class.__name__}."
            )
        self._plugins[na
PluginRegistry.deregister method · python · L184-L200 (17 LOC)
src/agent_sim_bridge/plugins/registry.py
    def deregister(self, name: str) -> None:
        """Remove a plugin from the registry.

        Parameters
        ----------
        name:
            The key previously passed to ``register``.

        Raises
        ------
        PluginNotFoundError
            If ``name`` is not currently registered.
        """
        if name not in self._plugins:
            raise PluginNotFoundError(name, self._name)
        del self._plugins[name]
        logger.debug("Deregistered plugin %r from registry %r", name, self._name)
PluginRegistry.get method · python · L206-L227 (22 LOC)
src/agent_sim_bridge/plugins/registry.py
    def get(self, name: str) -> type[T]:
        """Return the class registered under ``name``.

        Parameters
        ----------
        name:
            The key used when registering the plugin.

        Returns
        -------
        type[T]
            The registered class (not an instance).

        Raises
        ------
        PluginNotFoundError
            If no plugin is registered under ``name``.
        """
        try:
            return self._plugins[name]
        except KeyError:
            raise PluginNotFoundError(name, self._name) from None
‹ prevpage 2 / 5next ›