north-mini-code-free · api

api
config
north-mini-code-free--zen-free--dev
batch
2026-07-19--unified
transport
opencode-zen-free-tier
protocol
api · plan
served model
north-mini-code-free
采集于
2026年7月18日 11:54 · N=2
variant
live
slot 0 · P-q · sandboxed iframe
north-mini-code-free · api P-q slot 0 截图

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。

similarity 邻居

限于 session 2026-07-19--unified

similarity 衡量本 session 内的趋同程度 —— 不是质量。

Fidelity —— 卡片展示的数据对不对?

  • namematch
  • conditionmatch
  • datematch
  • max tempambiguous展示值:25.3max-equals-min
  • min tempambiguous展示值:25.3max-equals-min
  • hourlyambiguouscoverage · 0 命中 · 0 不符 · 24 未展示
  • request sidematch0 处违规

extractor fidelity-extractor-v1+Berlin-2026-07-15

源码 —— 原始模型输出,一字节未改

下载 card.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Weather Card</title>
  <style>
    /* Reset and base styles */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
      background: #eef2f7;
      color: #333;
      display: flex;
      flex-direction: column;
      align-items: center;
      min-height: 100vh;
      width: 100%;
      padding: 20px;
    }

    /* Container for the card */
    #app {
      width: 100%;
      max-width: 1280px;
    }

    .weather-card {
      background: #ffffff;
      border-radius: 16px;
      box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
      overflow: hidden;
      padding: 32px;
      margin: 0 auto;
    }

    .weather-header {
      margin-bottom: 24px;
    }
    .location {
      margin: 0;
      font-size: 2rem;
      font-weight: 700;
      color: #222;
    }
    .date {
      display: block;
      margin-top: 4px;
      font-size: 1.125rem;
      color: #666;
    }

    .weather-main {
      display: flex;
      flex-wrap: wrap;
      align-items: center;
      gap: 32px;
      margin-bottom: 24px;
    }
    .temp-range {
      display: flex;
      gap: 16px;
    }
    .temp-high {
      font-size: 2.5rem;
      font-weight: 700;
      color: #e63946; /* Warm red for high */
    }
    .temp-low {
      font-size: 1.75rem;
      font-weight: 600;
      color: #457b9d; /* Cool blue for low */
    }
    .condition {
      font-size: 1.5rem;
      color: #555;
    }

    .hourly-section h2 {
      font-size: 1.25rem;
      margin-bottom: 16px;
      color: #444;
    }
    .hourly-list {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
      gap: 12px;
    }
    .hour-item {
      background: #f9fafb;
      border-radius: 10px;
      padding: 12px 8px;
      text-align: center;
      transition: transform 0.2s, box-shadow 0.2s;
    }
    .hour-item:hover {
      transform: translateY(-3px);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    }
    .hour-time {
      font-size: 0.85rem;
      color: #888;
      margin-bottom: 4px;
    }
    .hour-temp {
      font-size: 1.25rem;
      font-weight: 600;
      color: #222;
    }

    .error {
      background: #fdecea;
      color: #a94442;
      padding: 20px;
      border-radius: 10px;
      text-align: center;
      margin: 20px auto;
      max-width: 600px;
    }
  </style>
</head>
<body>
  <div id="app"></div>

  <script>
    // Mapping from Open-Meteo WMO weather codes to human readable conditions
    const weatherConditionMap = {
      0: "Clear sky",
      1: "Mainly clear",
      2: "Partly cloudy",
      3: "Overcast",
      45: "Fog",
      48: "Rime fog",
      51: "Light drizzle",
      53: "Moderate drizzle",
      55: "Dense drizzle",
      56: "Light freezing drizzle",
      57: "Dense freezing drizzle",
      61: "Slight rain",
      63: "Moderate rain",
      65: "Heavy rain",
      66: "Light freezing rain",
      67: "Heavy freezing rain",
      71: "Slight snow fall",
      73: "Moderate snow fall",
      75: "Heavy snow fall",
      77: "Snow grains",
      80: "Slight rain showers",
      81: "Moderate rain showers",
      82: "Violent rain showers",
      85: "Slight snow showers",
      86: "Heavy snow showers",
      95: "Thunderstorm",
      96: "Thunderstorm with slight hail",
      99: "Thunderstorm with heavy hail"
    };

    document.addEventListener('DOMContentLoaded', () => {
      // Parse URL query parameters with defaults
      const params = new URLSearchParams(window.location.search);
      const lat = params.get('lat') ?? '52.52';
      const lon = params.get('lon') ?? '13.405';
      const name = params.get('name') ?? 'Berlin';
      const dateStr = params.get('date') ?? new Date().toISOString().split('T')[0];

      // Determine which API endpoint to use (forecast for today/future, archive for past)
      const todayUTC = new Date().toISOString().split('T')[0];
      const isArchive = dateStr < todayUTC;
      const endpoint = isArchive ? '/api/om/archive' : '/api/om/forecast';

      // Build request query string
      const query = new URLSearchParams();
      query.set('latitude', lat);
      query.set('longitude', lon);
      query.set('daily', 'temperature_2m_max,temperature_2m_min,weather_code');
      query.set('hourly', 'temperature_2m');
      query.set('timezone', 'UTC');
      query.set('temperature_unit', 'celsius');
      query.set('start_date', dateStr);
      query.set('end_date', dateStr);

      const url = `${endpoint}?${query.toString()}`;

      fetch(url)
        .then(response => {
          if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
          }
          return response.json();
        })
        .then(data => {
          // Verify that the response contains the expected data
          if (!data.daily || !data.daily.time || data.daily.time.length === 0 ||
              !data.hourly || !data.hourly.time) {
            throw new Error('Missing daily or hourly data in response');
          }

          // Extract daily values for the requested date
          const dailyTime = data.daily.time;
          const idx = dailyTime.findIndex(t => t === dateStr);
          const dayIdx = idx >= 0 ? idx : 0;

          const maxTemp = data.daily.temperature_2m_max[dayIdx];
          const minTemp = data.daily.temperature_2m_min[dayIdx];
          const weatherCode = data.daily.weather_code[dayIdx];

          // Map weather code to condition
          const condition = weatherConditionMap[weatherCode] ?? `Weather code ${weatherCode}`;

          // Collect hourly temperatures for the requested date
          const hourlyTemps = [];
          data.hourly.time.forEach((t, i) => {
            if (t.startsWith(dateStr)) {
              const hourPart = t.split('T')[1];
              const hourStr = hourPart ? hourPart.substring(0, 2) + ':00' : '';
              const temp = data.hourly.temperature_2m[i];
              hourlyTemps.push({ hourStr, temp });
            }
          });

          // Format the date for display
          const displayDate = new Date(dateStr + 'T00:00:00Z').toLocaleDateString(undefined, {
            weekday: 'short',
            year: 'numeric',
            month: 'short',
            day: 'numeric'
          });

          // Build hourly HTML
          let hourlyHtml = '';
          if (hourlyTemps.length) {
            hourlyHtml = `
              <div class="hourly-section">
                <h2>Hourly temperatures for ${dateStr}</h2>
                <div class="hourly-list">
                  ${hourlyTemps.map(h => `
                    <div class="hour-item">
                      <div class="hour-time">${h.hourStr}</div>
                      <div class="hour-temp">${h.temp.toFixed(1)}°C</div>
                    </div>
                  `).join('')}
                </div>
              </div>`;
          } else {
            hourlyHtml = '<p>No hourly temperature data available.</p>';
          }

          // Assemble the weather card HTML
          const cardHtml = `
            <div class="weather-card">
              <div class="weather-header">
                <h1 class="location">${name}</h1>
                <time class="date">${displayDate}</time>
              </div>
              <div class="weather-main">
                <div class="temp-range">
                  <span class="temp-high">${maxTemp?.toFixed(1) ?? '--'}°C</span>
                  <span class="temp-low">${minTemp?.toFixed(1) ?? '--'}°C</span>
                </div>
                <div class="condition">${condition}</div>
              </div>
              ${hourlyHtml}
            </div>`;

          // Render the card
          const appDiv = document.getElementById('app');
          if (appDiv) {
            appDiv.innerHTML = cardHtml;
          }
        })
        .catch(() => {
          // On any error, show a simple error message
          const appDiv = document.getElementById('app');
          if (appDiv) {
            appDiv.innerHTML = '<div class="error">Weather data unavailable.</div>';
          }
        });
    });
  </script>
</body>
</html>

L1 —— 廉价的确定性描述量

bytes 总计8,376html / css / js258 / 2,392 / 5,726
dom 节点9dom 深度3
css 规则19含 js
brightness243.4contrast15.1
colorfulness8.1留白97.6%

该 slot 的 telemetry

prompt tokens303completion tokens8,773
total tokens9,076wall55.8 s
costrequest id
config.json568 B
{
  "N": 2,
  "auth": {
    "credential_ref": "WCB_ZEN_KEY",
    "method": "api-key"
  },
  "billing": "plan",
  "config_id": "north-mini-code-free--zen-free--dev",
  "effort": null,
  "family": "north",
  "m": {
    "min": 2,
    "q": 2
  },
  "model_id": "north-mini-code-free",
  "protocol": "api",
  "served_model": "north-mini-code-free",
  "telemetry": {
    "completion_tokens": 29070,
    "cost_usd": null,
    "prompt_tokens": 1196,
    "total_tokens": 30266,
    "wall_ms": 273369
  },
  "transport": "opencode-zen-free-tier",
  "vendor_sanction_ref": null
}
send-log2.5 KB
{
  "N": 2,
  "batch_id": "2026-07-18--dev-zen-free",
  "config_id": "north-mini-code-free--zen-free--dev",
  "positions": [
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-18T01:13:21.378264+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-18T01:12:25.538860+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-18T01:14:24.693312+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-18T01:13:24.132056+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-18T01:15:55.583245+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-18T01:14:27.487753+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-18T01:17:07.212229+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-18T01:15:58.333568+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-q"
    }
  ],
  "retry_policy": {
    "max_unreachable_retries": 5,
    "rate_limit_backoff": {
      "max_attempts": 4,
      "max_total_ms": 60000
    }
  }
}