gpt-5.6-luna @ max · kiro
kiromax
- config
- gpt-5.6-luna-eff-max--cli--kiro--dev
- batch
- 2026-07-19--unified
- transport
- kiro-cli-isolated-home-github-social
- protocol
- cli · plan
- served model
- gpt-5.6-luna
- 采集于
- 2026年7月18日 11:54 · N=2
variant
live
slot 0 · P-q · sandboxed iframe

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。
similarity 邻居
最近
glm-5.2-eff-enabled--api--official--dev0.67gpt-5.5 @high · api0.66gpt-5.6-sol @max · codex-oauth0.66gpt-5.6-sol @none · codex-oauth0.66claude-fable-5 @xhigh · CC0.64最远
claude-opus-4-6 @medium · kiro0.41qwen3.7-max · qoder0.42gpt-5.6-luna @high · kiro0.42minimax-m2.1 · kiro0.44claude-opus-4-6 @high · kiro0.44限于 session 2026-07-19--unified
similarity 衡量本 session 内的趋同程度 —— 不是质量。
Fidelity —— 卡片展示的数据对不对?
- namematch
- conditionmatch
- datematch
- max tempmismatch展示值:17
- min tempmatch展示值:16
- hourlymismatchcoverage 23/24 · 23 命中 · 1 不符 · 0 未展示
- 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.0">
<title>Aeris · Weather</title>
<style>
:root {
color-scheme: dark;
--ink: #f4f7fb;
--muted: #94a8bd;
--soft: #6e849c;
--line: rgba(194, 218, 241, 0.13);
--panel: rgba(18, 39, 61, 0.72);
--panel-strong: rgba(23, 48, 74, 0.9);
--accent: #f6cc79;
--accent-soft: rgba(246, 204, 121, 0.15);
--cyan: #78d4e5;
--blue: #83b9ff;
--danger: #ff9a91;
}
* {
box-sizing: border-box;
}
html,
body {
min-height: 100%;
margin: 0;
}
body {
overflow-x: hidden;
background:
radial-gradient(circle at 17% 12%, rgba(43, 112, 158, 0.24), transparent 32rem),
radial-gradient(circle at 88% 88%, rgba(76, 68, 153, 0.22), transparent 34rem),
#071320;
color: var(--ink);
font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
-webkit-font-smoothing: antialiased;
}
body::before {
position: fixed;
inset: 0;
z-index: -1;
background-image:
linear-gradient(rgba(161, 199, 230, 0.027) 1px, transparent 1px),
linear-gradient(90deg, rgba(161, 199, 230, 0.027) 1px, transparent 1px);
background-size: 48px 48px;
content: "";
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.65), transparent 76%);
}
button {
font: inherit;
}
.app {
display: grid;
min-height: 100vh;
padding: 30px 42px;
place-items: center;
}
.page {
width: min(1180px, 100%);
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 5px 17px;
color: var(--muted);
font-size: 10px;
font-weight: 700;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.brand,
.source-status {
display: flex;
align-items: center;
}
.brand {
gap: 11px;
}
.brand-mark {
display: grid;
width: 29px;
height: 29px;
border: 1px solid rgba(175, 212, 238, 0.3);
border-radius: 9px;
background: rgba(94, 160, 196, 0.14);
color: var(--cyan);
place-items: center;
}
.brand-mark svg {
width: 17px;
height: 17px;
}
.brand-name {
color: #dbeaf5;
font-size: 12px;
letter-spacing: 0.27em;
}
.brand-divider {
width: 1px;
height: 14px;
margin-left: 3px;
background: var(--line);
}
.brand-sub {
color: var(--soft);
font-size: 9px;
letter-spacing: 0.16em;
}
.source-status {
gap: 8px;
color: #8297ac;
font-size: 9px;
letter-spacing: 0.14em;
}
.status-dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--cyan);
box-shadow: 0 0 0 4px rgba(120, 212, 229, 0.1), 0 0 16px rgba(120, 212, 229, 0.7);
}
.status-dot.error {
background: var(--danger);
box-shadow: 0 0 0 4px rgba(255, 154, 145, 0.1), 0 0 16px rgba(255, 154, 145, 0.55);
}
.weather-card {
position: relative;
overflow: hidden;
border: 1px solid rgba(169, 207, 235, 0.18);
border-radius: 30px;
background:
linear-gradient(135deg, rgba(24, 57, 83, 0.92), rgba(11, 29, 49, 0.96) 62%, rgba(17, 30, 58, 0.97)),
#10263d;
box-shadow:
0 28px 80px rgba(0, 0, 0, 0.34),
inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.weather-card::before {
position: absolute;
top: -180px;
right: -110px;
width: 480px;
height: 480px;
border-radius: 50%;
background: radial-gradient(circle, rgba(106, 182, 208, 0.17), transparent 67%);
content: "";
pointer-events: none;
}
.weather-card::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(130, 203, 227, 0.34), transparent);
content: "";
}
.card-content {
position: relative;
z-index: 1;
padding: 32px 37px 22px;
}
.location-row {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 24px;
padding-bottom: 25px;
border-bottom: 1px solid var(--line);
}
.location-kicker,
.section-kicker,
.metric-label,
.hero-label {
color: var(--soft);
font-size: 9px;
font-weight: 800;
letter-spacing: 0.18em;
text-transform: uppercase;
}
.location-kicker {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 10px;
}
.location-kicker svg {
width: 14px;
height: 14px;
color: var(--cyan);
}
.location-title {
margin: 0;
color: var(--ink);
font-size: clamp(34px, 4vw, 51px);
font-weight: 650;
letter-spacing: -0.045em;
line-height: 0.98;
}
.location-date {
margin: 10px 0 0;
color: #afc2d3;
font-size: 14px;
letter-spacing: 0.01em;
}
.location-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
padding-top: 5px;
color: var(--soft);
font-size: 10px;
letter-spacing: 0.11em;
text-align: right;
text-transform: uppercase;
white-space: nowrap;
}
.coordinate-line {
color: #b4c9d9;
font-size: 11px;
letter-spacing: 0.08em;
}
.data-badge {
display: inline-flex;
align-items: center;
min-height: 25px;
padding: 0 10px;
border: 1px solid rgba(133, 204, 220, 0.19);
border-radius: 999px;
background: rgba(77, 155, 181, 0.08);
color: #8ecad9;
font-size: 8px;
letter-spacing: 0.14em;
}
.state-view {
display: grid;
min-height: 520px;
padding: 48px 20px;
place-items: center;
text-align: center;
}
.state-view[hidden],
#content[hidden] {
display: none;
}
.state-inner {
display: flex;
max-width: 390px;
flex-direction: column;
align-items: center;
}
.loading-orb,
.error-orb {
display: grid;
width: 74px;
height: 74px;
margin-bottom: 22px;
border: 1px solid rgba(131, 204, 224, 0.25);
border-radius: 25px;
background: rgba(65, 150, 180, 0.11);
place-items: center;
}
.loading-orb::before {
width: 27px;
height: 27px;
border: 2px solid rgba(132, 219, 231, 0.23);
border-top-color: var(--cyan);
border-radius: 50%;
animation: spin 0.85s linear infinite;
content: "";
}
.error-orb {
border-color: rgba(255, 154, 145, 0.22);
background: rgba(198, 76, 83, 0.1);
color: var(--danger);
}
.error-orb svg {
width: 28px;
height: 28px;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.state-title {
margin: 0;
color: var(--ink);
font-size: 22px;
font-weight: 620;
letter-spacing: -0.025em;
}
.state-copy {
margin: 10px 0 0;
color: var(--muted);
font-size: 13px;
line-height: 1.65;
}
.retry-button {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 23px;
padding: 10px 15px;
border: 1px solid rgba(133, 204, 220, 0.28);
border-radius: 10px;
background: rgba(91, 171, 194, 0.12);
color: #b8e9f0;
cursor: pointer;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.retry-button:hover {
border-color: rgba(133, 204, 220, 0.56);
background: rgba(91, 171, 194, 0.2);
transform: translateY(-1px);
}
.retry-button svg {
width: 14px;
height: 14px;
}
.summary-layout {
display: grid;
grid-template-columns: minmax(300px, 0.72fr) minmax(0, 1.28fr);
gap: 23px;
padding-top: 24px;
}
.hero-panel,
.insights-panel {
border: 1px solid rgba(172, 210, 233, 0.12);
border-radius: 21px;
background: rgba(11, 31, 51, 0.42);
}
.hero-panel {
position: relative;
overflow: hidden;
min-height: 283px;
padding: 24px 26px 20px;
}
.hero-panel::after {
position: absolute;
right: -55px;
bottom: -80px;
width: 220px;
height: 220px;
border: 1px solid rgba(116, 208, 227, 0.11);
border-radius: 50%;
box-shadow: 0 0 0 22px rgba(116, 208, 227, 0.025), 0 0 0 44px rgba(116, 208, 227, 0.018);
content: "";
pointer-events: none;
}
.hero-label {
position: relative;
z-index: 1;
}
.hero-main {
position: relative;
z-index: 1;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-top: 20px;
}
.hero-reading {
display: flex;
align-items: flex-start;
color: var(--ink);
line-height: 0.82;
}
.hero-temperature {
font-size: clamp(72px, 7vw, 101px);
font-weight: 300;
letter-spacing: -0.09em;
}
.hero-degree {
margin-top: 8px;
color: var(--accent);
font-size: 31px;
font-weight: 300;
letter-spacing: -0.06em;
}
.hero-reading-label {
margin: 13px 0 0 4px;
color: var(--soft);
font-size: 9px;
font-weight: 800;
letter-spacing: 0.16em;
text-transform: uppercase;
}
.condition-art {
display: grid;
width: 108px;
height: 108px;
margin-right: 3px;
border: 1px solid rgba(242, 211, 138, 0.14);
border-radius: 30px;
background: linear-gradient(145deg, rgba(246, 204, 121, 0.13), rgba(75, 151, 188, 0.08));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
place-items: center;
}
.weather-icon {
width: 77px;
height: 77px;
}
.condition-copy {
position: relative;
z-index: 1;
margin-top: 13px;
}
.condition-title {
margin: 0;
color: #eef5f8;
font-size: 17px;
font-weight: 600;
letter-spacing: -0.02em;
}
.condition-detail {
margin: 5px 0 0;
color: var(--muted);
font-size: 11px;
}
.hero-bottom {
position: relative;
z-index: 1;
display: flex;
align-items: center;
gap: 12px;
margin-top: 21px;
color: var(--soft);
font-size: 9px;
font-weight: 750;
letter-spacing: 0.14em;
text-transform: uppercase;
}
.hero-bottom strong {
color: #d8e5ed;
font-size: 14px;
font-weight: 550;
letter-spacing: -0.01em;
}
.hero-bottom-divider {
width: 1px;
height: 17px;
background: var(--line);
}
.insights-panel {
min-height: 283px;
padding: 20px 21px 16px;
}
.insights-heading {
display: flex;
align-items: center;
justify-content: space-between;
margin: 1px 2px 13px;
}
.insights-heading h2,
.hourly-heading h2 {
margin: 5px 0 0;
color: #e5eef4;
font-size: 16px;
font-weight: 560;
letter-spacing: -0.02em;
}
.unit-tag,
.reading-count {
color: var(--soft);
font-size: 10px;
letter-spacing: 0.1em;
}
.metric-grid {
display: grid;
grid-template-columns: 0.85fr 0.85fr 1.3fr;
gap: 9px;
}
.metric-card {
min-height: 63px;
padding: 12px 13px 10px;
border: 1px solid rgba(163, 205, 231, 0.1);
border-radius: 12px;
background: rgba(91, 149, 180, 0.07);
}
.metric-label {
display: block;
font-size: 8px;
letter-spacing: 0.14em;
}
.metric-reading {
display: flex;
align-items: baseline;
gap: 2px;
margin-top: 7px;
}
.metric-value {
color: #eff7fa;
font-size: 21px;
font-weight: 520;
letter-spacing: -0.04em;
}
.metric-unit {
color: var(--accent);
font-size: 12px;
}
.metric-condition {
overflow: hidden;
margin-top: 8px;
color: #e1edf2;
font-size: 13px;
font-weight: 550;
text-overflow: ellipsis;
white-space: nowrap;
}
.chart-wrap {
position: relative;
height: 146px;
margin-top: 8px;
overflow: hidden;
border-top: 1px solid rgba(164, 205, 230, 0.08);
}
#tempChart {
display: block;
width: 100%;
height: 100%;
overflow: visible;
}
.hourly-section {
margin-top: 23px;
}
.hourly-heading {
display: flex;
align-items: flex-end;
justify-content: space-between;
margin: 0 2px 12px;
}
.hourly-heading .section-kicker {
color: #80c8d8;
}
.reading-count {
padding-bottom: 2px;
color: var(--soft);
font-size: 9px;
text-transform: uppercase;
}
.hourly-list {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
gap: 8px;
}
.hour-card {
min-width: 0;
padding: 10px 5px 9px;
border: 1px solid rgba(162, 204, 229, 0.1);
border-radius: 11px;
background: rgba(12, 34, 56, 0.54);
text-align: center;
transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}
.hour-card:hover,
.hour-card.noon {
border-color: rgba(127, 205, 222, 0.34);
background: rgba(66, 139, 166, 0.14);
transform: translateY(-2px);
}
.hour-time {
color: #93aabd;
font-size: 9px;
font-weight: 700;
letter-spacing: 0.04em;
}
.hour-icon {
display: grid;
height: 29px;
margin: 5px auto 3px;
place-items: center;
}
.hour-icon svg {
width: 23px;
height: 23px;
}
.hour-temperature {
color: #eaf3f6;
font-size: 13px;
font-weight: 600;
letter-spacing: -0.02em;
}
.card-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-top: 17px;
padding-top: 15px;
border-top: 1px solid var(--line);
color: var(--soft);
font-size: 9px;
letter-spacing: 0.1em;
text-transform: uppercase;
}
.footer-source {
display: flex;
align-items: center;
gap: 7px;
}
.footer-source::before {
width: 5px;
height: 5px;
border-radius: 50%;
background: var(--cyan);
content: "";
}
.footer-note {
color: #71869a;
text-align: right;
}
@media (max-width: 900px) {
.app {
padding: 20px;
}
.summary-layout {
grid-template-columns: 1fr;
}
.hourly-list {
grid-template-columns: repeat(8, minmax(0, 1fr));
}
}
@media (max-width: 620px) {
.app {
padding: 12px;
}
.topbar {
margin: 0 3px 12px;
}
.brand-sub,
.brand-divider,
.source-status {
display: none;
}
.card-content {
padding: 24px 18px 18px;
}
.location-row {
flex-direction: column;
gap: 14px;
}
.location-meta {
align-items: flex-start;
text-align: left;
}
.hero-panel {
padding: 21px 19px 18px;
}
.hero-temperature {
font-size: 75px;
}
.condition-art {
width: 88px;
height: 88px;
border-radius: 24px;
}
.weather-icon {
width: 64px;
height: 64px;
}
.metric-grid {
grid-template-columns: 1fr 1fr;
}
.metric-card:last-child {
grid-column: 1 / -1;
}
.hourly-list {
grid-template-columns: repeat(6, minmax(0, 1fr));
}
.card-footer {
align-items: flex-start;
flex-direction: column;
}
.footer-note {
text-align: left;
}
}
</style>
</head>
<body>
<main class="app">
<div class="page">
<header class="topbar">
<div class="brand">
<span class="brand-mark" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M6.4 16.8a4.4 4.4 0 0 1 .3-8.8 5.6 5.6 0 0 1 10.8 1.5A3.7 3.7 0 1 1 18 16.8H6.4Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>
<path d="m8 19.6 1.2-1.7M12 20l1.2-1.7M16 19.6l1.2-1.7" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>
</span>
<span class="brand-name">Aeris</span>
<span class="brand-divider"></span>
<span class="brand-sub">Daily weather</span>
</div>
<div class="source-status">
<span id="statusDot" class="status-dot"></span>
<span id="statusLabel">Connecting to weather service</span>
</div>
</header>
<section class="weather-card" aria-live="polite">
<div class="card-content">
<div class="location-row">
<div>
<div class="location-kicker">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M19 10.3c0 5.3-7 10.2-7 10.2S5 15.6 5 10.3a7 7 0 1 1 14 0Z" stroke="currentColor" stroke-width="1.8"/>
<circle cx="12" cy="10" r="2.4" stroke="currentColor" stroke-width="1.8"/>
</svg>
<span>Weather at</span>
</div>
<h1 id="locationName" class="location-title">Berlin</h1>
<p id="dateLabel" class="location-date">Today, UTC</p>
</div>
<div class="location-meta">
<div id="coordinateLabel" class="coordinate-line">52.5200° N · 13.4050° E</div>
<div id="dataBadge" class="data-badge">UTC · Celsius</div>
</div>
</div>
<div id="loadingState" class="state-view" role="status">
<div class="state-inner">
<div class="loading-orb" aria-hidden="true"></div>
<h2 class="state-title">Reading the sky</h2>
<p class="state-copy">Fetching the forecast and hourly temperatures for this location.</p>
</div>
</div>
<div id="errorState" class="state-view" role="alert" hidden>
<div class="state-inner">
<div class="error-orb" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none">
<path d="M12 4.3 21 19.7H3L12 4.3Z" stroke="currentColor" stroke-width="1.7" stroke-linejoin="round"/>
<path d="M12 9v4.8M12 16.9v.1" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
</svg>
</div>
<h2 class="state-title">Weather data couldn't be loaded</h2>
<p id="errorCopy" class="state-copy">The weather service did not return usable data for this date.</p>
<button id="retryButton" class="retry-button" type="button">
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M19.5 8.5A8 8 0 1 0 20 13" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/>
<path d="M19.5 4.5v4h-4" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
Try again
</button>
</div>
</div>
<div id="content" hidden>
<div class="summary-layout">
<section class="hero-panel" aria-label="Daily weather summary">
<div class="hero-label">Day summary</div>
<div class="hero-main">
<div>
<div class="hero-reading">
<span id="heroMaxTemp" class="hero-temperature">--</span>
<span class="hero-degree">°</span>
</div>
<div class="hero-reading-label">Maximum</div>
</div>
<div id="conditionArt" class="condition-art" aria-hidden="true"></div>
</div>
<div class="condition-copy">
<h2 id="conditionTitle" class="condition-title">Weather condition</h2>
<p id="conditionDetail" class="condition-detail">Daily outlook</p>
</div>
<div class="hero-bottom">
<span>Minimum</span>
<strong id="heroMinTemp">--°C</strong>
<span class="hero-bottom-divider"></span>
<span>Feels like a</span>
<strong id="heroConditionShort">day</strong>
</div>
</section>
<section class="insights-panel" aria-label="Temperature details and chart">
<div class="insights-heading">
<div>
<div class="section-kicker">Temperature range</div>
<h2>How the day moves</h2>
</div>
<span class="unit-tag">°C / UTC</span>
</div>
<div class="metric-grid">
<div class="metric-card">
<span class="metric-label">Maximum</span>
<div class="metric-reading">
<strong id="metricMax" class="metric-value">--</strong>
<span class="metric-unit">°C</span>
</div>
</div>
<div class="metric-card">
<span class="metric-label">Minimum</span>
<div class="metric-reading">
<strong id="metricMin" class="metric-value">--</strong>
<span class="metric-unit">°C</span>
</div>
</div>
<div class="metric-card">
<span class="metric-label">Condition</span>
<div id="metricCondition" class="metric-condition">--</div>
</div>
</div>
<div class="chart-wrap">
<svg id="tempChart" viewBox="0 0 760 220" role="img" aria-label="Hourly temperature chart"></svg>
</div>
</section>
</div>
<section class="hourly-section" aria-label="Hourly temperatures">
<div class="hourly-heading">
<div>
<div class="section-kicker">Hourly temperature</div>
<h2>Twenty-four hour view</h2>
</div>
<div id="readingCount" class="reading-count">24 readings</div>
</div>
<div id="hourlyList" class="hourly-list"></div>
</section>
<footer class="card-footer">
<div id="footerSource" class="footer-source">Forecast data · Open-Meteo compatible API</div>
<div id="footerNote" class="footer-note">All times shown in UTC · Temperatures in Celsius</div>
</footer>
</div>
</div>
</section>
</div>
</main>
<script>
(() => {
"use strict";
const $ = (id) => document.getElementById(id);
const params = new URLSearchParams(window.location.search);
const DEFAULT_LATITUDE = 52.52;
const DEFAULT_LONGITUDE = 13.405;
const DEFAULT_NAME = "Berlin";
const utcToday = () => {
const now = new Date();
return [
now.getUTCFullYear(),
String(now.getUTCMonth() + 1).padStart(2, "0"),
String(now.getUTCDate()).padStart(2, "0")
].join("-");
};
const isValidDate = (value) => {
if (!/^\d{4}-\d{2}-\d{2}$/.test(value || "")) return false;
const [year, month, day] = value.split("-").map(Number);
const date = new Date(Date.UTC(year, month - 1, day));
return date.getUTCFullYear() === year &&
date.getUTCMonth() === month - 1 &&
date.getUTCDate() === day;
};
const numberOr = (value, fallback, min, max) => {
const number = Number(value);
return Number.isFinite(number) && number >= min && number <= max ? number : fallback;
};
const config = {
latitude: numberOr(params.get("lat"), DEFAULT_LATITUDE, -90, 90),
longitude: numberOr(params.get("lon"), DEFAULT_LONGITUDE, -180, 180),
name: (params.get("name") || DEFAULT_NAME).trim() || DEFAULT_NAME,
date: isValidDate(params.get("date")) ? params.get("date") : utcToday()
};
const SVG_NS = "http://www.w3.org/2000/svg";
const makeSvgElement = (name, attributes = {}) => {
const element = document.createElementNS(SVG_NS, name);
Object.entries(attributes).forEach(([key, value]) => {
element.setAttribute(key, String(value));
});
return element;
};
const formatDate = (dateString) => {
const date = new Date(`${dateString}T12:00:00Z`);
return new Intl.DateTimeFormat("en-US", {
weekday: "long",
month: "long",
day: "numeric",
year: "numeric",
timeZone: "UTC"
}).format(date);
};
const formatTemperature = (value) => {
if (!Number.isFinite(value)) return "—";
return String(Math.round(value));
};
const formatCoordinate = (value, positive, negative) => {
return `${Math.abs(value).toFixed(4)}° ${value >= 0 ? positive : negative}`;
};
const toNumber = (value) => {
const number = Number(value);
return Number.isFinite(number) ? number : null;
};
const weatherInfo = (code) => {
const value = Number(code);
if (value === 0) {
return {
label: "Clear sky",
detail: "Bright and cloudless",
short: "clear day",
kind: "clear",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<g stroke="#f7d37d" stroke-width="5" stroke-linecap="round">
<path d="M60 9v13M60 98v13M9 60h13M98 60h13M24 24l9 9M87 87l9 9M96 24l-9 9M33 87l-9 9"/>
</g>
<circle cx="60" cy="60" r="25" fill="#f7d37d"/>
<circle cx="51" cy="51" r="8" fill="#ffe6a5" opacity=".45"/>
</svg>`
};
}
if (value === 1 || value === 2) {
return {
label: value === 1 ? "Mainly clear" : "Partly cloudy",
detail: "A little cloud cover",
short: "partly clear day",
kind: "partly",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<g stroke="#f7d37d" stroke-width="4" stroke-linecap="round">
<path d="M69 12v10M69 70v10M39 41h-9M108 41h-9M47 19l7 7M91 63l7 7M91 19l-7 7"/>
</g>
<circle cx="69" cy="41" r="19" fill="#f7d37d"/>
<path d="M29 82.5a17.5 17.5 0 0 1 4-34.5 22 22 0 0 1 41.8 5.7h2.7a14.8 14.8 0 1 1 0 29.6H29Z" fill="#b8d3df" stroke="#d5e7ec" stroke-width="3" stroke-linejoin="round"/>
<path d="M36 72h37" stroke="#f1f8fa" stroke-width="2" opacity=".7" stroke-linecap="round"/>
</svg>`
};
}
if (value === 3) {
return {
label: "Overcast",
detail: "Cloudy through the day",
short: "cloudy day",
kind: "cloud",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M26 83a17 17 0 0 1 2.6-33.8 23 23 0 0 1 44-1.1 15.7 15.7 0 1 1 3.3 30.9H26Z" fill="#a8c4d1" stroke="#d2e5eb" stroke-width="4" stroke-linejoin="round"/>
<path d="M38 71h43" stroke="#eff8fa" stroke-width="3" stroke-linecap="round" opacity=".65"/>
<path d="M34 90h43" stroke="#6e9bad" stroke-width="3" stroke-linecap="round" opacity=".7"/>
</svg>`
};
}
if (value === 45 || value === 48) {
return {
label: "Fog",
detail: "Low visibility conditions",
short: "a foggy day",
kind: "fog",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M26 43h68M18 59h84M27 75h66M39 91h43" stroke="#c3d9e1" stroke-width="6" stroke-linecap="round" opacity=".8"/>
<path d="M42 28h37" stroke="#80b4c3" stroke-width="5" stroke-linecap="round" opacity=".8"/>
</svg>`
};
}
if (value >= 51 && value <= 57) {
return {
label: "Drizzle",
detail: "Light precipitation nearby",
short: "a drizzly day",
kind: "rain",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M26 70a17 17 0 0 1 2.8-33.7 23 23 0 0 1 43.5 1.9h2.4a15.2 15.2 0 1 1 0 30.4H26Z" fill="#9ebdcb" stroke="#d3e7ed" stroke-width="4" stroke-linejoin="round"/>
<path d="m40 84-4 8M58 84l-4 8M76 84l-4 8" stroke="#78d4e5" stroke-width="4" stroke-linecap="round"/>
</svg>`
};
}
if (value >= 61 && value <= 67 || value >= 80 && value <= 82) {
return {
label: value >= 80 ? "Rain showers" : "Rain",
detail: "Periods of rainfall",
short: "a rainy day",
kind: "rain",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M25 66a17 17 0 0 1 3-33.7 23 23 0 0 1 43.3 2h2.5a15.4 15.4 0 1 1 0 30.8H25Z" fill="#91b2c1" stroke="#d3e7ed" stroke-width="4" stroke-linejoin="round"/>
<path d="m37 82-6 14M57 82l-6 14M77 82l-6 14M97 82l-6 14" stroke="#78d4e5" stroke-width="5" stroke-linecap="round"/>
</svg>`
};
}
if (value >= 71 && value <= 77 || value >= 85 && value <= 86) {
return {
label: value >= 85 ? "Snow showers" : "Snow",
detail: "Snowfall is possible",
short: "a snowy day",
kind: "snow",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M25 65a17 17 0 0 1 3-33.7 23 23 0 0 1 43.3 2h2.5a15.4 15.4 0 1 1 0 30.8H25Z" fill="#a6c5d2" stroke="#d7e9ee" stroke-width="4" stroke-linejoin="round"/>
<g stroke="#b9e7ef" stroke-width="3" stroke-linecap="round">
<path d="M38 83v13M32 89h12M34 85l8 8M42 85l-8 8"/>
<path d="M61 83v13M55 89h12M57 85l8 8M65 85l-8 8"/>
<path d="M84 83v13M78 89h12M80 85l8 8M88 85l-8 8"/>
</g>
</svg>`
};
}
if (value >= 95) {
return {
label: "Thunderstorm",
detail: "Storm activity in the area",
short: "a stormy day",
kind: "storm",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M25 60a17 17 0 0 1 3-33.7 23 23 0 0 1 43.3 2h2.5a15.4 15.4 0 1 1 0 30.8H25Z" fill="#91a8bb" stroke="#cfdee7" stroke-width="4" stroke-linejoin="round"/>
<path d="m63 59-17 27h13l-4 20 20-31H62l10-16H63Z" fill="#f7d37d" stroke="#ffe8a3" stroke-width="2" stroke-linejoin="round"/>
</svg>`
};
}
return {
label: "Mixed conditions",
detail: "Variable weather through the day",
short: "a changeable day",
kind: "cloud",
icon: `
<svg class="weather-icon" viewBox="0 0 120 120" fill="none">
<path d="M26 77a17 17 0 0 1 3-33.7 23 23 0 0 1 43.3 2h2.5a15.4 15.4 0 1 1 0 30.8H26Z" fill="#a8c4d1" stroke="#d2e5eb" stroke-width="4" stroke-linejoin="round"/>
<path d="M39 88h42" stroke="#78d4e5" stroke-width="4" stroke-linecap="round"/>
</svg>`
};
};
const miniWeatherIcon = (hour) => {
const isNight = hour < 6 || hour >= 20;
if (isNight) {
return `
<svg viewBox="0 0 28 28" fill="none" aria-hidden="true">
<path d="M19.7 18.8a8.5 8.5 0 0 1-10.5-10A8.6 8.6 0 1 0 19.7 18.8Z" fill="#9ebed6"/>
<circle cx="19.8" cy="7.2" r="1.2" fill="#f5d58b"/>
<circle cx="23" cy="12" r=".8" fill="#f5d58b" opacity=".8"/>
</svg>`;
}
return `
<svg viewBox="0 0 28 28" fill="none" aria-hidden="true">
<g stroke="#f4cc78" stroke-width="1.7" stroke-linecap="round">
<path d="M14 2.5v3M14 22.5v3M2.5 14h3M22.5 14h3M5.9 5.9l2.1 2.1M20 20l2.1 2.1M22.1 5.9 20 8M8 20l-2.1 2.1"/>
</g>
<circle cx="14" cy="14" r="5.6" fill="#f4cc78"/>
</svg>`;
};
const setInitialLabels = () => {
$("locationName").textContent = config.name;
$("dateLabel").textContent = formatDate(config.date);
$("coordinateLabel").textContent =
`${formatCoordinate(config.latitude, "N", "S")} · ${formatCoordinate(config.longitude, "E", "W")}`;
document.title = `${config.name} · Weather`;
};
const setState = (state) => {
$("loadingState").hidden = state !== "loading";
$("errorState").hidden = state !== "error";
$("content").hidden = state !== "ready";
$("statusDot").classList.toggle("error", state === "error");
if (state === "loading") {
$("statusLabel").textContent = "Connecting to weather service";
} else if (state === "error") {
$("statusLabel").textContent = "Weather service unavailable";
} else {
$("statusLabel").textContent = "Data ready · UTC";
}
};
const getWeatherData = (payload) => {
if (!payload || !payload.daily || !payload.hourly) {
throw new Error("Incomplete weather response");
}
const dailyTimes = Array.isArray(payload.daily.time) ? payload.daily.time : [];
const dailyIndex = dailyTimes.indexOf(config.date);
if (dailyIndex < 0) {
throw new Error("Requested date is not present");
}
const maximum = toNumber(payload.daily.temperature_2m_max?.[dailyIndex]);
const minimum = toNumber(payload.daily.temperature_2m_min?.[dailyIndex]);
const code = toNumber(payload.daily.weather_code?.[dailyIndex]);
const hourlyTimes = Array.isArray(payload.hourly.time) ? payload.hourly.time : [];
const hourlyTemperatures = Array.isArray(payload.hourly.temperature_2m)
? payload.hourly.temperature_2m
: [];
const hourly = hourlyTimes
.map((time, index) => {
if (typeof time !== "string" || time.slice(0, 10) !== config.date) return null;
const match = time.match(/T(\d{2}):(\d{2})/);
const hour = match ? Number(match[1]) : index;
return {
hour,
label: match ? `${match[1]}:${match[2]}` : `${String(hour).padStart(2, "0")}:00`,
temperature: toNumber(hourlyTemperatures[index])
};
})
.filter(Boolean);
if (!hourly.length) {
throw new Error("No hourly readings returned");
}
return {
maximum,
minimum,
code,
hourly
};
};
const renderChart = (hours) => {
const chart = $("tempChart");
chart.replaceChildren();
const width = 760;
const height = 220;
const left = 34;
const right = 748;
const top = 18;
const bottom = 174;
const valid = hours
.map((item, index) => ({ ...item, index }))
.filter((item) => Number.isFinite(item.temperature));
if (!valid.length) {
const message = makeSvgElement("text", {
x: width / 2,
y: 111,
"text-anchor": "middle",
fill: "#7f95a8",
"font-size": "12"
});
message.textContent = "No chart readings available";
chart.append(message);
return;
}
let minimum = Math.min(...valid.map((item) => item.temperature));
let maximum = Math.max(...valid.map((item) => item.temperature));
if (minimum === maximum) {
minimum -= 2;
maximum += 2;
}
const range = maximum - minimum;
const lower = Math.floor((minimum - range * 0.15) / 2) * 2;
const upper = Math.ceil((maximum + range * 0.15) / 2) * 2;
const yRange = Math.max(upper - lower, 4);
const xForIndex = (index) => left + (index / Math.max(hours.length - 1, 1)) * (right - left);
const yForValue = (value) => bottom - ((value - lower) / yRange) * (bottom - top);
const defs = makeSvgElement("defs");
const gradient = makeSvgElement("linearGradient", {
id: "chartAreaGradient",
x1: "0",
y1: "0",
x2: "0",
y2: "1"
});
gradient.append(
makeSvgElement("stop", { offset: "0%", "stop-color": "#77d4e5", "stop-opacity": ".27" }),
makeSvgElement("stop", { offset: "100%", "stop-color": "#77d4e5", "stop-opacity": "0" })
);
defs.append(gradient);
chart.append(defs);
const grid = makeSvgElement("g");
for (let i = 0; i <= 3; i += 1) {
const value = upper - (yRange * i / 3);
const y = yForValue(value);
const line = makeSvgElement("line", {
x1: left,
y1: y,
x2: right,
y2: y,
stroke: "#b9d5e5",
"stroke-opacity": i === 3 ? ".15" : ".09",
"stroke-width": "1"
});
const label = makeSvgElement("text", {
x: 0,
y: y + 4,
fill: "#738ba0",
"font-size": "10"
});
label.textContent = `${Math.round(value)}°`;
grid.append(line, label);
}
chart.append(grid);
const points = valid.map((item) => ({
x: xForIndex(item.index),
y: yForValue(item.temperature),
temperature: item.temperature
}));
const linePoints = points.map((point) => `${point.x},${point.y}`).join(" ");
const areaPath = [
`M ${points[0].x} ${bottom}`,
...points.map((point) => `L ${point.x} ${point.y}`),
`L ${points[points.length - 1].x} ${bottom}`,
"Z"
].join(" ");
chart.append(
makeSvgElement("path", {
d: areaPath,
fill: "url(#chartAreaGradient)"
}),
makeSvgElement("polyline", {
points: linePoints,
fill: "none",
stroke: "#82d9e7",
"stroke-width": "3",
"stroke-linecap": "round",
"stroke-linejoin": "round"
})
);
points.forEach((point) => {
chart.append(
makeSvgElement("circle", {
cx: point.x,
cy: point.y,
r: "7",
fill: "#82d9e7",
"fill-opacity": ".1"
}),
makeSvgElement("circle", {
cx: point.x,
cy: point.y,
r: "3.5",
fill: "#d7f6f7",
stroke: "#72cfdf",
"stroke-width": "2"
})
);
});
hours.forEach((item, index) => {
if (index % 4 !== 0 && index !== hours.length - 1) return;
const label = makeSvgElement("text", {
x: xForIndex(index),
y: 205,
"text-anchor": index === 0 ? "start" : index === hours.length - 1 ? "end" : "middle",
fill: "#7890a3",
"font-size": "10"
});
label.textContent = item.label.slice(0, 2);
chart.append(label);
});
};
const renderHourly = (hours) => {
const list = $("hourlyList");
list.replaceChildren();
hours.forEach((item) => {
const card = document.createElement("div");
card.className = `hour-card${item.hour === 12 ? " noon" : ""}`;
const time = document.createElement("div");
time.className = "hour-time";
time.textContent = item.label;
const icon = document.createElement("div");
icon.className = "hour-icon";
icon.innerHTML = miniWeatherIcon(item.hour);
const temperature = document.createElement("div");
temperature.className = "hour-temperature";
temperature.textContent = Number.isFinite(item.temperature)
? `${formatTemperature(item.temperature)}°`
: "—";
card.append(time, icon, temperature);
list.append(card);
});
};
const renderWeather = (payload, endpoint) => {
const weather = getWeatherData(payload);
const info = weatherInfo(weather.code);
const endpointName = endpoint.includes("archive") ? "Archive data" : "Forecast data";
$("heroMaxTemp").textContent = formatTemperature(weather.maximum);
$("heroMinTemp").textContent = Number.isFinite(weather.minimum)
? `${formatTemperature(weather.minimum)}°C`
: "—";
$("metricMax").textContent = formatTemperature(weather.maximum);
$("metricMin").textContent = formatTemperature(weather.minimum);
$("conditionTitle").textContent = info.label;
$("conditionDetail").textContent = info.detail;
$("metricCondition").textContent = info.label;
$("heroConditionShort").textContent = info.short;
$("conditionArt").innerHTML = info.icon;
$("conditionArt").setAttribute("aria-label", info.label);
$("readingCount").textContent = `${weather.hourly.length} readings`;
$("dataBadge").textContent = `${endpointName} · UTC`;
$("footerSource").textContent = `${endpointName} · Open-Meteo compatible API`;
$("footerNote").textContent = "All times shown in UTC · Temperatures in Celsius";
renderChart(weather.hourly);
renderHourly(weather.hourly);
setState("ready");
};
const loadWeather = async () => {
setState("loading");
const endpoint = config.date < utcToday()
? "/api/om/archive"
: "/api/om/forecast";
const query = new URLSearchParams({
latitude: String(config.latitude),
longitude: String(config.longitude),
daily: "temperature_2m_max,temperature_2m_min,weather_code",
hourly: "temperature_2m",
timezone: "UTC",
temperature_unit: "celsius",
start_date: config.date,
end_date: config.date
});
try {
const response = await fetch(`${endpoint}?${query.toString()}`, {
headers: {
"Accept": "application/json"
},
cache: "no-store"
});
if (!response.ok) {
throw new Error(`Weather request failed with status ${response.status}`);
}
const payload = await response.json();
renderWeather(payload, endpoint);
} catch (error) {
$("errorCopy").textContent = "The weather service did not return usable data for this date. Please try again.";
setState("error");
}
};
setInitialLabels();
$("retryButton").addEventListener("click", loadWeather);
loadWeather();
})();
</script>
</body>
</html>L1 —— 廉价的确定性描述量
| bytes 总计 | 44,273 | html / css / js | 7,396 / 16,244 / 20,633 |
|---|---|---|---|
| dom 节点 | 105 | dom 深度 | 13 |
| css 规则 | 112 | 含 js | 是 |
| brightness | 35.6 | contrast | 17.4 |
| colorfulness | 19.2 | 留白 | 71.2% |
该 slot 的 telemetry
| prompt tokens | 0 | completion tokens | 0 |
|---|---|---|---|
| total tokens | 0 | wall | 89.2 s |
| cost | — | request id | — |
config.json565 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_NONE",
"method": "oauth-login"
},
"billing": "plan",
"config_id": "gpt-5.6-luna-eff-max--cli--kiro--dev",
"effort": "max",
"family": "gpt",
"m": {
"min": 2,
"q": 2
},
"model_id": "gpt-5.6-luna",
"protocol": "cli",
"served_model": "gpt-5.6-luna",
"telemetry": {
"completion_tokens": null,
"cost_usd": null,
"prompt_tokens": null,
"total_tokens": null,
"wall_ms": 284054
},
"transport": "kiro-cli-isolated-home-github-social",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-07-18--kiro-cli",
"config_id": "gpt-5.6-luna-eff-max--cli--kiro--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-07-18T18:13:58.382201+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-07-18T18:13:16.550887+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-18T18:15:31.418751+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-07-18T18:14:02.131966+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-18T18:17:10.649495+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-07-18T18:15:35.703949+00:00"
}
],
"block_index": 1,
"model_reaching_attempt_index": 0,
"slot_index": 1,
"terminal_state": "valid",
"variant": "P-q"
},
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-07-18T18:18:12.972672+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-07-18T18:17:14.783722+00:00"
}
],
"block_index": 1,
"model_reaching_attempt_index": 0,
"slot_index": 1,
"terminal_state": "valid",
"variant": "P-min"
}
],
"retry_policy": {
"max_unreachable_retries": 5,
"rate_limit_backoff": {
"max_attempts": 4,
"max_total_ms": 60000
}
}
}