gemini-3.5-flash · cursor
cursor
- config
- gemini-3.5-flash--cli--cursor--dev
- batch
- 2026-07-19--unified
- transport
- cursor-agent-cli-isolated-home
- protocol
- cli · plan
- served model
- gemini-3.5-flash
- 采集于
- 2026年7月18日 11:54 · N=2
variant
live
slot 0 · P-q · sandboxed iframe

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。
similarity 邻居
最近
gemini-3.6-flash @high · api0.73gemini-3.6-flash @medium · cursor-xl0.73gemini-3.8-flash @high · agy0.73gemini-3.7-flash @high · agy0.72gemini-3.8-flash @medium · agy0.72最远
north-mini-code-free · api0.48claude-sonnet-4 · cursor0.50claude-haiku-4-5 @max · CC0.50grok-4.6 @medium · grok-cli0.51claude-sonnet-4-5-thinking · cursor-xl0.51限于 session 2026-07-19--unified
similarity 衡量本 session 内的趋同程度 —— 不是质量。
Fidelity —— 卡片展示的数据对不对?
- namematch
- conditionmatch
- datematch
- max tempmatch展示值:25.3
- min tempmatch展示值:16
- hourlymatchcoverage 24/24 · 24 命中 · 0 不符 · 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>Premium Weather Dashboard</title>
<style>
/* Reset & Base Styles */
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 0;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-color: #0b0c0f;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
overflow: hidden;
color: #f1f5f9;
}
/* Fixed 1280x800 Container */
#app-container {
width: 1280px;
height: 800px;
min-width: 1280px;
max-width: 1280px;
min-height: 800px;
max-height: 800px;
background: #111318;
border-radius: 24px;
box-shadow: 0 25px 60px rgba(0, 0, 0, 0.6);
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
border: 1px solid rgba(255, 255, 255, 0.06);
}
/* Background Ambient Glows */
#ambient-glow-1 {
position: absolute;
top: -200px;
left: -200px;
width: 600px;
height: 600px;
border-radius: 50%;
filter: blur(140px);
opacity: 0.15;
pointer-events: none;
transition: background 1s ease;
z-index: 1;
}
#ambient-glow-2 {
position: absolute;
bottom: -200px;
right: -100px;
width: 700px;
height: 700px;
border-radius: 50%;
filter: blur(160px);
opacity: 0.12;
pointer-events: none;
transition: background 1s ease;
z-index: 1;
}
/* Header Styling */
#app-header {
height: 80px;
background: rgba(18, 20, 26, 0.95);
border-bottom: 1px solid rgba(255, 255, 255, 0.06);
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 32px;
z-index: 10;
backdrop-filter: blur(20px);
}
.brand-section {
display: flex;
align-items: center;
gap: 12px;
}
.brand-logo {
width: 32px;
height: 32px;
color: #38bdf8;
}
.brand-title {
font-size: 20px;
font-weight: 700;
letter-spacing: -0.5px;
background: linear-gradient(135deg, #fff 0%, #cbd5e1 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
/* Form Controls */
.controls-form {
display: flex;
align-items: center;
gap: 16px;
}
.input-group {
display: flex;
flex-direction: column;
gap: 4px;
}
.input-label {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
color: #94a3b8;
font-weight: 600;
}
.input-field {
background: rgba(0, 0, 0, 0.35);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 8px;
color: #f1f5f9;
padding: 6px 12px;
font-size: 13px;
outline: none;
transition: all 0.2s ease;
font-family: inherit;
}
.input-field:focus {
border-color: #38bdf8;
box-shadow: 0 0 0 2px rgba(56, 189, 248, 0.2);
background: rgba(0, 0, 0, 0.5);
}
.input-field-name { width: 140px; }
.input-field-coord { width: 90px; }
.input-field-date { width: 135px; }
.btn-submit {
background: #38bdf8;
color: #0f172a;
border: none;
border-radius: 8px;
padding: 8px 18px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
align-self: flex-end;
height: 34px;
display: flex;
align-items: center;
justify-content: center;
}
.btn-submit:hover {
background: #0ea5e9;
transform: translateY(-1px);
}
.btn-submit:active {
transform: translateY(0);
}
/* Preset Buttons */
.presets-container {
display: flex;
gap: 8px;
align-items: center;
}
.preset-btn {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 100px;
color: #cbd5e1;
padding: 6px 14px;
font-size: 11px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.preset-btn:hover {
background: rgba(255, 255, 255, 0.12);
color: #fff;
border-color: rgba(255, 255, 255, 0.2);
}
/* Main Dashboard Layout */
#app-main {
flex: 1;
display: flex;
z-index: 5;
position: relative;
}
/* Left Hero Panel */
#hero-panel {
width: 420px;
border-right: 1px solid rgba(255, 255, 255, 0.06);
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 40px;
position: relative;
overflow: hidden;
transition: background 1s ease;
}
.hero-glass-overlay {
position: absolute;
inset: 0;
background: rgba(15, 23, 42, 0.25);
backdrop-filter: blur(4px);
z-index: 1;
}
.hero-content {
position: relative;
z-index: 2;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.location-info {
display: flex;
flex-direction: column;
gap: 8px;
}
.location-badge {
align-self: flex-start;
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 100px;
padding: 4px 12px;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.5px;
color: #fff;
text-transform: uppercase;
}
.location-name {
font-size: 38px;
font-weight: 800;
letter-spacing: -1px;
line-height: 1.1;
color: #fff;
word-break: break-word;
}
.current-date {
font-size: 15px;
color: rgba(255, 255, 255, 0.8);
font-weight: 500;
}
.weather-visual {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin: 40px 0;
gap: 16px;
}
.hero-icon-wrapper {
width: 140px;
height: 140px;
display: flex;
align-items: center;
justify-content: center;
animation: float 4s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
.weather-condition-text {
font-size: 24px;
font-weight: 700;
letter-spacing: -0.2px;
color: #fff;
text-align: center;
text-shadow: 0 2px 10px rgba(0,0,0,0.2);
}
.hero-temperature-section {
display: flex;
flex-direction: column;
gap: 12px;
}
.hero-extremes {
display: flex;
gap: 20px;
align-items: center;
}
.hero-extreme-item {
display: flex;
align-items: center;
gap: 8px;
}
.extreme-dot {
width: 8px;
height: 8px;
border-radius: 50%;
}
.extreme-dot.max { background: #f43f5e; }
.extreme-dot.min { background: #38bdf8; }
.extreme-label {
font-size: 13px;
color: rgba(255, 255, 255, 0.7);
}
.extreme-val {
font-size: 18px;
font-weight: 700;
color: #fff;
}
.coords-badge {
display: flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: rgba(255, 255, 255, 0.6);
font-family: monospace;
margin-top: 8px;
}
/* Right Details Panel */
#details-panel {
flex: 1;
padding: 32px;
display: flex;
flex-direction: column;
gap: 24px;
overflow: hidden;
background: #111318;
}
.section-title {
font-size: 12px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 1px;
color: #94a3b8;
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 16px;
}
.section-title svg {
width: 16px;
height: 16px;
color: #38bdf8;
}
/* Hourly Forecast Card */
.hourly-card {
background: rgba(30, 41, 59, 0.35);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 20px;
padding: 24px;
display: flex;
flex-direction: column;
gap: 16px;
backdrop-filter: blur(10px);
}
.graph-container {
width: 100%;
height: 160px;
position: relative;
}
.hourly-scroll-container {
display: flex;
gap: 12px;
overflow-x: auto;
padding-bottom: 12px;
scroll-behavior: smooth;
}
.hourly-scroll-container::-webkit-scrollbar {
height: 6px;
}
.hourly-scroll-container::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.02);
border-radius: 4px;
}
.hourly-scroll-container::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.08);
border-radius: 4px;
}
.hourly-scroll-container::-webkit-scrollbar-thumb:hover {
background: rgba(255, 255, 255, 0.15);
}
.hour-box {
min-width: 60px;
flex-shrink: 0;
background: rgba(0, 0, 0, 0.2);
border: 1px solid rgba(255, 255, 255, 0.03);
border-radius: 12px;
padding: 12px 8px;
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
transition: all 0.2s ease;
}
.hour-box:hover {
background: rgba(255, 255, 255, 0.03);
border-color: rgba(255, 255, 255, 0.08);
transform: translateY(-2px);
}
.hour-time {
font-size: 11px;
color: #94a3b8;
font-weight: 500;
}
.hour-temp {
font-size: 14px;
font-weight: 600;
color: #fff;
}
/* Metrics Grid */
.metrics-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
flex: 1;
}
.metric-card {
background: rgba(30, 41, 59, 0.35);
border: 1px solid rgba(255, 255, 255, 0.05);
border-radius: 20px;
padding: 24px;
backdrop-filter: blur(10px);
display: flex;
flex-direction: column;
}
.metric-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
}
/* Card Details Grid */
.details-list {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.detail-item {
display: flex;
flex-direction: column;
gap: 4px;
}
.detail-label {
font-size: 11px;
color: #64748b;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.detail-value {
font-size: 15px;
font-weight: 600;
color: #cbd5e1;
word-break: break-all;
}
.api-badge {
background: rgba(56, 189, 248, 0.1);
border: 1px solid rgba(56, 189, 248, 0.2);
color: #38bdf8;
padding: 2px 8px;
border-radius: 4px;
font-size: 10px;
font-family: monospace;
display: inline-block;
width: fit-content;
margin-top: 4px;
}
/* Range Bar Graphic */
.range-visual-container {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 10px;
}
.range-track-labels {
display: flex;
justify-content: space-between;
font-size: 11px;
color: #64748b;
font-weight: 600;
}
.range-track {
height: 10px;
background: rgba(0, 0, 0, 0.3);
border-radius: 100px;
position: relative;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.05);
}
.range-bar {
position: absolute;
height: 100%;
background: linear-gradient(90deg, #38bdf8 0%, #f43f5e 100%);
border-radius: 100px;
}
.range-analytic-row {
display: flex;
justify-content: space-between;
border-top: 1px solid rgba(255, 255, 255, 0.05);
padding-top: 12px;
margin-top: 12px;
}
.analytic-item {
text-align: center;
}
.analytic-val {
font-size: 18px;
font-weight: 700;
color: #fff;
}
.analytic-lbl {
font-size: 10px;
color: #64748b;
text-transform: uppercase;
font-weight: 600;
margin-top: 2px;
}
/* Loader */
#loader-overlay {
position: absolute;
inset: 0;
background: #111318;
z-index: 100;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 16px;
opacity: 1;
transition: opacity 0.4s ease, visibility 0.4s;
}
#loader-overlay.hidden {
opacity: 0;
visibility: hidden;
}
.spinner {
width: 50px;
height: 50px;
border: 3px solid rgba(56, 189, 248, 0.1);
border-top-color: #38bdf8;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.loader-text {
font-size: 14px;
font-weight: 500;
color: #94a3b8;
}
/* Error Overlay */
#error-overlay {
position: absolute;
inset: 0;
background: #111318;
z-index: 90;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 20px;
opacity: 0;
visibility: hidden;
transition: opacity 0.4s ease, visibility 0.4s;
padding: 40px;
text-align: center;
}
#error-overlay.visible {
opacity: 1;
visibility: visible;
}
.error-icon {
width: 64px;
height: 64px;
color: #f43f5e;
}
.error-title {
font-size: 22px;
font-weight: 700;
color: #fff;
}
.error-msg {
font-size: 14px;
color: #94a3b8;
max-width: 500px;
line-height: 1.6;
}
.btn-retry {
background: rgba(244, 63, 94, 0.1);
border: 1px solid rgba(244, 63, 94, 0.2);
color: #f43f5e;
padding: 10px 24px;
border-radius: 8px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-retry:hover {
background: rgba(244, 63, 94, 0.2);
border-color: rgba(244, 63, 94, 0.3);
}
</style>
</head>
<body>
<div id="app-container">
<!-- Ambient Blur Glows -->
<div id="ambient-glow-1"></div>
<div id="ambient-glow-2"></div>
<!-- Header / Nav -->
<header id="app-header">
<div class="brand-section">
<!-- Logo SVG -->
<svg class="brand-logo" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<path d="M12 2v2M4.93 4.93l1.41 1.41M20 12h2M19.07 4.93l-1.41 1.41"/>
<path d="M15.5 12.5a3.5 3.5 0 1 0-7 0"/>
<path d="M17 18a4 4 0 0 0-1-7.87A6 6 0 0 0 5 13a4 4 0 0 0 1 7.87z" fill="currentColor" fill-opacity="0.15"/>
</svg>
<span class="brand-title">Aether Weather</span>
</div>
<!-- Quick Location Presets -->
<div class="presets-container">
<button class="preset-btn" onclick="applyPreset('Berlin', 52.52, 13.405)">Berlin</button>
<button class="preset-btn" onclick="applyPreset('Paris', 48.8566, 2.3522)">Paris</button>
<button class="preset-btn" onclick="applyPreset('New York', 40.7128, -74.006)">New York</button>
<button class="preset-btn" onclick="applyPreset('Tokyo', 35.6762, 139.6503)">Tokyo</button>
<button class="preset-btn" onclick="applyPreset('Sydney', -33.8688, 151.2093)">Sydney</button>
</div>
<!-- Input Form -->
<form class="controls-form" id="search-form" onsubmit="handleFormSubmit(event)">
<div class="input-group">
<label class="input-label">Location Name</label>
<input type="text" id="input-name" class="input-field input-field-name" placeholder="Berlin" required>
</div>
<div class="input-group">
<label class="input-label">Latitude</label>
<input type="number" id="input-lat" class="input-field input-field-coord" placeholder="52.52" step="any" min="-90" max="90" required>
</div>
<div class="input-group">
<label class="input-label">Longitude</label>
<input type="number" id="input-lon" class="input-field input-field-coord" placeholder="13.405" step="any" min="-180" max="180" required>
</div>
<div class="input-group">
<label class="input-label">Date (UTC)</label>
<input type="date" id="input-date" class="input-field input-field-date" required>
</div>
<button type="submit" class="btn-submit">Update</button>
</form>
</header>
<!-- Main Section -->
<main id="app-main">
<!-- Left Panel: Hero details -->
<section id="hero-panel">
<div class="hero-glass-overlay"></div>
<div class="hero-content">
<!-- Top Location Details -->
<div class="location-info">
<span class="location-badge" id="hero-date-badge">Forecast</span>
<h1 class="location-name" id="hero-location-name">Berlin</h1>
<p class="current-date" id="hero-formatted-date">Thursday, Aug 13, 2026</p>
<div class="coords-badge" id="hero-coords">
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/>
<circle cx="12" cy="10" r="3"/>
</svg>
52.5200° N, 13.4050° E
</div>
</div>
<!-- Icon & Condition -->
<div class="weather-visual">
<div class="hero-icon-wrapper" id="hero-icon-container">
<!-- Inline SVG injected dynamically -->
</div>
<h2 class="weather-condition-text" id="hero-condition-label">Partly Cloudy</h2>
</div>
<!-- Extreme Temperatures -->
<div class="hero-temperature-section">
<div style="font-size: 11px; text-transform: uppercase; letter-spacing: 1px; color: rgba(255,255,255,0.6); font-weight: 700;">Expected Range</div>
<div class="hero-extremes">
<div class="hero-extreme-item">
<span class="extreme-dot max"></span>
<span class="extreme-label">High:</span>
<span class="extreme-val" id="hero-temp-max">--°C</span>
</div>
<div class="hero-extreme-item">
<span class="extreme-dot min"></span>
<span class="extreme-label">Low:</span>
<span class="extreme-val" id="hero-temp-min">--°C</span>
</div>
</div>
</div>
</div>
</section>
<!-- Right Panel: Data visualizations & breakdown -->
<section id="details-panel">
<!-- Card 1: Hourly Forecast -->
<div class="hourly-card">
<div class="section-title">
<!-- Clock Icon -->
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<polyline points="12 6 12 12 16 14"/>
</svg>
Hourly Temperature profile
</div>
<div class="graph-container">
<svg id="hourly-svg-graph" width="100%" height="100%" viewBox="0 0 760 160" preserveAspectRatio="none">
<!-- SVG path and gradient grid elements injected dynamically -->
</svg>
</div>
<div class="hourly-scroll-container" id="hourly-strip">
<!-- Hourly boxes injected dynamically -->
</div>
</div>
<!-- Card 2: Split Metric details -->
<div class="metrics-grid">
<!-- Metadata Card -->
<div class="metric-card">
<div class="section-title">
<!-- Info Icon -->
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<line x1="12" y1="16" x2="12" y2="12"/>
<line x1="12" y1="8" x2="12.01" y2="8"/>
</svg>
Station Metadata
</div>
<div class="metric-content">
<div class="details-list">
<div class="detail-item">
<span class="detail-label">Query latitude</span>
<span class="detail-value" id="meta-lat">--</span>
</div>
<div class="detail-item">
<span class="detail-label">Query longitude</span>
<span class="detail-value" id="meta-lon">--</span>
</div>
<div class="detail-item">
<span class="detail-label">Data timezone</span>
<span class="detail-value">UTC</span>
</div>
<div class="detail-item">
<span class="detail-label">API source</span>
<div>
<span class="detail-value" id="meta-source" style="font-size: 13px; font-weight: 700;">OM Forecast</span>
<br>
<span class="api-badge" id="meta-endpoint">/api/om/forecast</span>
</div>
</div>
</div>
</div>
</div>
<!-- Span Card -->
<div class="metric-card">
<div class="section-title">
<!-- Activity Icon -->
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
</svg>
Temperature Analysis
</div>
<div class="metric-content">
<div class="range-visual-container">
<div class="range-track-labels">
<span>-10°C</span>
<span style="color: rgba(255,255,255,0.35);">Ideal Frame (-10° to 50°)</span>
<span>50°C</span>
</div>
<div class="range-track">
<div class="range-bar" id="range-bar-graphic" style="left: 30%; right: 40%;"></div>
</div>
</div>
<div class="range-analytic-row">
<div class="analytic-item">
<div class="analytic-val" id="analytic-avg">--°C</div>
<div class="analytic-lbl">Avg Temp</div>
</div>
<div class="analytic-item">
<div class="analytic-val" id="analytic-amplitude">--°C</div>
<div class="analytic-lbl">Diurnal Swing</div>
</div>
<div class="analytic-item">
<div class="analytic-val" id="analytic-median">--°C</div>
<div class="analytic-lbl">Median Temp</div>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- Loading Overlay -->
<div id="loader-overlay">
<div class="spinner"></div>
<div class="loader-text" id="loader-status">Acquiring Atmospheric telemetry...</div>
</div>
<!-- Error Overlay -->
<div id="error-overlay">
<svg class="error-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/>
<line x1="12" y1="9" x2="12" y2="13"/>
<line x1="12" y1="17" x2="12.01" y2="17"/>
</svg>
<div class="error-title">Telemetry Interrupted</div>
<div class="error-msg" id="error-message">Unable to contact the same-origin Open-Meteo telemetry server. Please verify your connection or try again.</div>
<button class="btn-retry" onclick="window.location.reload()">Retry Connection</button>
</div>
</div>
<!-- App Scripting -->
<script>
// Constants & Global WMO mapping
const WMO_MAP = {
0: { label: 'Sunny', icon: 'sunny', gradient: 'linear-gradient(135deg, #f59e0b 0%, #ef4444 100%)', ambient: '#ef4444' },
1: { label: 'Mainly Clear', icon: 'partly-cloudy', gradient: 'linear-gradient(135deg, #38bdf8 0%, #0284c7 100%)', ambient: '#38bdf8' },
2: { label: 'Partly Cloudy', icon: 'partly-cloudy', gradient: 'linear-gradient(135deg, #38bdf8 0%, #0284c7 100%)', ambient: '#38bdf8' },
3: { label: 'Overcast', icon: 'cloudy', gradient: 'linear-gradient(135deg, #475569 0%, #1e293b 100%)', ambient: '#475569' },
45: { label: 'Foggy', icon: 'fog', gradient: 'linear-gradient(135deg, #64748b 0%, #334155 100%)', ambient: '#64748b' },
48: { label: 'Depositing Rime Fog', icon: 'fog', gradient: 'linear-gradient(135deg, #64748b 0%, #334155 100%)', ambient: '#64748b' },
51: { label: 'Light Drizzle', icon: 'rainy', gradient: 'linear-gradient(135deg, #0ea5e9 0%, #1e1b4b 100%)', ambient: '#0ea5e9' },
53: { label: 'Moderate Drizzle', icon: 'rainy', gradient: 'linear-gradient(135deg, #0ea5e9 0%, #1e1b4b 100%)', ambient: '#0ea5e9' },
55: { label: 'Dense Drizzle', icon: 'rainy', gradient: 'linear-gradient(135deg, #0ea5e9 0%, #1e1b4b 100%)', ambient: '#0ea5e9' },
56: { label: 'Light Freezing Drizzle', icon: 'rainy-snow', gradient: 'linear-gradient(135deg, #06b6d4 0%, #0f172a 100%)', ambient: '#06b6d4' },
57: { label: 'Dense Freezing Drizzle', icon: 'rainy-snow', gradient: 'linear-gradient(135deg, #06b6d4 0%, #0f172a 100%)', ambient: '#06b6d4' },
61: { label: 'Slight Rain', icon: 'rainy', gradient: 'linear-gradient(135deg, #2563eb 0%, #0f172a 100%)', ambient: '#2563eb' },
63: { label: 'Moderate Rain', icon: 'rainy', gradient: 'linear-gradient(135deg, #2563eb 0%, #0f172a 100%)', ambient: '#2563eb' },
65: { label: 'Heavy Rain', icon: 'rainy', gradient: 'linear-gradient(135deg, #1d4ed8 0%, #020617 100%)', ambient: '#1d4ed8' },
66: { label: 'Light Freezing Rain', icon: 'rainy-snow', gradient: 'linear-gradient(135deg, #06b6d4 0%, #1e1b4b 100%)', ambient: '#06b6d4' },
67: { label: 'Heavy Freezing Rain', icon: 'rainy-snow', gradient: 'linear-gradient(135deg, #0891b2 0%, #020617 100%)', ambient: '#0891b2' },
71: { label: 'Slight Snowfall', icon: 'snowy', gradient: 'linear-gradient(135deg, #cbd5e1 0%, #475569 100%)', ambient: '#cbd5e1' },
73: { label: 'Moderate Snowfall', icon: 'snowy', gradient: 'linear-gradient(135deg, #cbd5e1 0%, #475569 100%)', ambient: '#cbd5e1' },
75: { label: 'Heavy Snowfall', icon: 'snowy', gradient: 'linear-gradient(135deg, #94a3b8 0%, #1e293b 100%)', ambient: '#94a3b8' },
77: { label: 'Snow Grains', icon: 'snowy', gradient: 'linear-gradient(135deg, #94a3b8 0%, #1e293b 100%)', ambient: '#94a3b8' },
80: { label: 'Slight Rain Showers', icon: 'rainy', gradient: 'linear-gradient(135deg, #2563eb 0%, #0f172a 100%)', ambient: '#2563eb' },
81: { label: 'Moderate Rain Showers', icon: 'rainy', gradient: 'linear-gradient(135deg, #2563eb 0%, #0f172a 100%)', ambient: '#2563eb' },
82: { label: 'Violent Rain Showers', icon: 'rainy', gradient: 'linear-gradient(135deg, #1d4ed8 0%, #020617 100%)', ambient: '#1d4ed8' },
85: { label: 'Slight Snow Showers', icon: 'snowy', gradient: 'linear-gradient(135deg, #cbd5e1 0%, #1e293b 100%)', ambient: '#cbd5e1' },
86: { label: 'Heavy Snow Showers', icon: 'snowy', gradient: 'linear-gradient(135deg, #94a3b8 0%, #020617 100%)', ambient: '#94a3b8' },
95: { label: 'Thunderstorm', icon: 'thunderstorm', gradient: 'linear-gradient(135deg, #4338ca 0%, #020617 100%)', ambient: '#4338ca' },
96: { label: 'Thunderstorm with Hail', icon: 'thunderstorm', gradient: 'linear-gradient(135deg, #4338ca 0%, #020617 100%)', ambient: '#4338ca' },
99: { label: 'Thunderstorm with Heavy Hail', icon: 'thunderstorm', gradient: 'linear-gradient(135deg, #3730a3 0%, #020617 100%)', ambient: '#3730a3' }
};
const SVGS = {
'sunny': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #f59e0b; filter: drop-shadow(0 0 20px rgba(245,158,11,0.55));"><circle cx="12" cy="12" r="5" fill="#f59e0b" fill-opacity="0.2" stroke="#f59e0b" stroke-width="2"/><line x1="12" y1="1" x2="12" y2="3" stroke="#f59e0b" stroke-width="2"/><line x1="12" y1="21" x2="12" y2="23" stroke="#f59e0b" stroke-width="2"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64" stroke="#f59e0b" stroke-width="2"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78" stroke="#f59e0b" stroke-width="2"/><line x1="1" y1="12" x2="3" y2="12" stroke="#f59e0b" stroke-width="2"/><line x1="21" y1="12" x2="23" y2="12" stroke="#f59e0b" stroke-width="2"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36" stroke="#f59e0b" stroke-width="2"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22" stroke="#f59e0b" stroke-width="2"/></svg>`,
'partly-cloudy': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #38bdf8; filter: drop-shadow(0 0 20px rgba(56,189,248,0.45));"><path d="M12 2v2M4.93 4.93l1.41 1.41M20 12h2M19.07 4.93l-1.41 1.41" stroke="#f59e0b"/><path d="M17 18a4 4 0 0 0-1-7.87A6 6 0 0 0 5 13a4 4 0 0 0 1 7.87z" fill="#f1f5f9" fill-opacity="0.3" stroke="#f1f5f9"/></svg>`,
'cloudy': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #cbd5e1; filter: drop-shadow(0 0 16px rgba(203,213,225,0.3));"><path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z" fill="#cbd5e1" fill-opacity="0.25" stroke="#cbd5e1"/></svg>`,
'rainy': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #60a5fa; filter: drop-shadow(0 0 16px rgba(96,165,250,0.4));"><path d="M16 13a4 4 0 0 0-1-7.87A6 6 0 0 0 5 8a4 4 0 0 0 1 7.87z" fill="#94a3b8" fill-opacity="0.3" stroke="#94a3b8"/><line x1="8" y1="18" x2="8" y2="21" stroke="#60a5fa" stroke-width="2"/><line x1="12" y1="19" x2="12" y2="22" stroke="#60a5fa" stroke-width="2"/><line x1="16" y1="18" x2="16" y2="21" stroke="#60a5fa" stroke-width="2"/></svg>`,
'snowy': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #93c5fd; filter: drop-shadow(0 0 16px rgba(147,197,253,0.35));"><path d="M16 13a4 4 0 0 0-1-7.87A6 6 0 0 0 5 8a4 4 0 0 0 1 7.87z" fill="#f1f5f9" fill-opacity="0.4" stroke="#cbd5e1"/><circle cx="8" cy="18" r="1" fill="#fff" stroke="none"/><circle cx="12" cy="19" r="1" fill="#fff" stroke="none"/><circle cx="16" cy="18" r="1" fill="#fff" stroke="none"/><circle cx="10" cy="21" r="1" fill="#fff" stroke="none"/><circle cx="14" cy="21" r="1" fill="#fff" stroke="none"/></svg>`,
'rainy-snow': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #a5f3fc; filter: drop-shadow(0 0 16px rgba(165,243,252,0.35));"><path d="M16 13a4 4 0 0 0-1-7.87A6 6 0 0 0 5 8a4 4 0 0 0 1 7.87z" fill="#cbd5e1" fill-opacity="0.35" stroke="#94a3b8"/><line x1="8" y1="18" x2="8" y2="20" stroke="#06b6d4" stroke-width="2"/><circle cx="12" cy="19" r="1" fill="#fff" stroke="none"/><line x1="16" y1="18" x2="16" y2="20" stroke="#06b6d4" stroke-width="2"/></svg>`,
'thunderstorm': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #fbbf24; filter: drop-shadow(0 0 18px rgba(251,191,36,0.45));"><path d="M19 16.9A5 5 0 0 0 18 7h-1.26a8 8 0 1 0-11.62 8.58" fill="#475569" fill-opacity="0.4" stroke="#475569"/><polyline points="13 11 9 17 12 17 11 23 16 15 13 15" fill="#fbbf24" stroke="#fbbf24" stroke-width="2"/></svg>`,
'fog': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #e2e8f0; filter: drop-shadow(0 0 14px rgba(226,232,240,0.3));"><line x1="5" y1="8" x2="19" y2="8" stroke="#cbd5e1" stroke-width="2"/><line x1="3" y1="12" x2="21" y2="12" stroke="#94a3b8" stroke-width="2"/><line x1="6" y1="16" x2="18" y2="16" stroke="#64748b" stroke-width="2"/><line x1="8" y1="20" x2="16" y2="20" stroke="#475569" stroke-width="2"/></svg>`,
'unknown': `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="width: 100%; height: 100%; color: #64748b;"><circle cx="12" cy="12" r="10" stroke="#64748b"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" stroke="#64748b"/><line x1="12" y1="17" x2="12.01" y2="17" stroke="#64748b"/></svg>`
};
function getWmoDetails(code) {
return WMO_MAP[code] || { label: 'Unknown Atmosphere', icon: 'unknown', gradient: 'linear-gradient(135deg, #1e293b 0%, #0f172a 100%)', ambient: '#475569' };
}
// Dynamic Parameter Parsing
const params = new URLSearchParams(window.location.search);
const lat = parseFloat(params.get('lat')) || 52.52;
const lon = parseFloat(params.get('lon')) || 13.405;
const nameLabel = params.get('name') || 'Berlin';
// Defaulting date logic strictly to today in UTC format
const todayUTC = new Date().toISOString().slice(0, 10);
const dateParam = params.get('date') || todayUTC;
// UI Initial setup
document.getElementById('input-name').value = nameLabel;
document.getElementById('input-lat').value = lat;
document.getElementById('input-lon').value = lon;
document.getElementById('input-date').value = dateParam;
// Apply Presets
function applyPreset(name, latitude, longitude) {
document.getElementById('input-name').value = name;
document.getElementById('input-lat').value = latitude;
document.getElementById('input-longitude')?.value || (document.getElementById('input-lon').value = longitude);
const searchDate = document.getElementById('input-date').value || todayUTC;
window.location.href = `?lat=${latitude}&lon=${longitude}&name=${encodeURIComponent(name)}&date=${searchDate}`;
}
// Submit Handler
function handleFormSubmit(e) {
e.preventDefault();
const n = document.getElementById('input-name').value.trim();
const la = parseFloat(document.getElementById('input-lat').value);
const lo = parseFloat(document.getElementById('input-lon').value);
const d = document.getElementById('input-date').value;
window.location.href = `?lat=${la}&lon=${lo}&name=${encodeURIComponent(n)}&date=${d}`;
}
// Main Telemetry Retrieval
async function loadWeatherData() {
const isPast = dateParam < todayUTC;
const baseUrl = isPast ? '/api/om/archive' : '/api/om/forecast';
const queryStr = new URLSearchParams({
latitude: lat,
longitude: lon,
daily: 'temperature_2m_max,temperature_2m_min,weather_code',
hourly: 'temperature_2m',
timezone: 'UTC',
temperature_unit: 'celsius',
start_date: dateParam,
end_date: dateParam
}).toString();
const fetchUrl = `${baseUrl}?${queryStr}`;
try {
const response = await fetch(fetchUrl);
if (!response.ok) {
throw new Error(`API returned a terminal error code ${response.status}: ${response.statusText}`);
}
const data = await response.json();
renderDashboard(data, isPast);
} catch (err) {
showError(err.message);
}
}
// Render logic
function renderDashboard(data, isPast) {
// Validate Data Structure
const daily = data.daily || {};
const hourly = data.hourly || {};
const tempMax = daily.temperature_2m_max ? daily.temperature_2m_max[0] : null;
const tempMin = daily.temperature_2m_min ? daily.temperature_2m_min[0] : null;
const weatherCode = daily.weather_code !== undefined ? daily.weather_code[0] : null;
const hourlyTemps = hourly.temperature_2m || [];
if (tempMax === null || tempMin === null || weatherCode === null || hourlyTemps.length === 0) {
throw new Error("Telemetry payload was missing vital properties or malformed.");
}
// 1. Process WMO Condition details
const wmoInfo = getWmoDetails(weatherCode);
// 2. Adjust dynamic styling based on atmospheric condition
document.getElementById('hero-panel').style.background = wmoInfo.gradient;
document.getElementById('ambient-glow-1').style.background = wmoInfo.ambient;
document.getElementById('ambient-glow-2').style.background = wmoInfo.ambient;
// 3. Populate Hero panel info
document.getElementById('hero-date-badge').innerText = isPast ? "Archive Record" : "Active Forecast";
document.getElementById('hero-location-name').innerText = nameLabel;
// Gorgeous parsed date format
const parts = dateParam.split('-');
const parsedDate = new Date(Date.UTC(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10)));
const formattedDate = parsedDate.toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'short',
day: 'numeric',
timeZone: 'UTC'
});
document.getElementById('hero-formatted-date').innerText = formattedDate;
// Coords
const latSign = lat >= 0 ? 'N' : 'S';
const lonSign = lon >= 0 ? 'E' : 'W';
document.getElementById('hero-coords').innerHTML = `
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 4px;">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/>
<circle cx="12" cy="10" r="3"/>
</svg>
${Math.abs(lat).toFixed(4)}° ${latSign}, ${Math.abs(lon).toFixed(4)}° ${lonSign}
`;
// Weather icon & Label
document.getElementById('hero-icon-container').innerHTML = SVGS[wmoInfo.icon] || SVGS['unknown'];
document.getElementById('hero-condition-label').innerText = wmoInfo.label;
// Extremes
document.getElementById('hero-temp-max').innerText = `${tempMax.toFixed(1)}°C`;
document.getElementById('hero-temp-min').innerText = `${tempMin.toFixed(1)}°C`;
// 4. Populate Metadata
document.getElementById('meta-lat').innerText = `${lat.toFixed(4)}°`;
document.getElementById('meta-lon').innerText = `${lon.toFixed(4)}°`;
document.getElementById('meta-source').innerText = isPast ? "OM Archive" : "OM Forecast";
document.getElementById('meta-endpoint').innerText = isPast ? "/api/om/archive" : "/api/om/forecast";
// 5. Populate Detailed Stats
// Calculate Math stats from 24 hourly ticks
const sum = hourlyTemps.reduce((a, b) => a + b, 0);
const avgTemp = sum / hourlyTemps.length;
const swing = tempMax - tempMin;
const sortedHourly = [...hourlyTemps].sort((a, b) => a - b);
const medianTemp = (sortedHourly[11] + sortedHourly[12]) / 2;
document.getElementById('analytic-avg').innerText = `${avgTemp.toFixed(1)}°C`;
document.getElementById('analytic-amplitude').innerText = `${swing.toFixed(1)}°C`;
document.getElementById('analytic-median').innerText = `${medianTemp.toFixed(1)}°C`;
// Calculate slider parameters: Scale from -10 to 50
// Frame range from left: mapping minTemp & maxTemp percentage
const totalWidth = 60; // range is 60 (-10 to 50)
const leftPercent = Math.max(0, Math.min(100, ((tempMin - (-10)) / totalWidth) * 100));
const rightPercent = Math.max(0, Math.min(100, ((50 - tempMax) / totalWidth) * 100));
const barGraphic = document.getElementById('range-bar-graphic');
barGraphic.style.left = `${leftPercent}%`;
barGraphic.style.right = `${rightPercent}%`;
// 6. Draw Hourly SVG Curve Graph
drawHourlyGraph(hourlyTemps);
// 7. Inject Hourly Horizontal scrolling strip boxes
const hourlyStrip = document.getElementById('hourly-strip');
hourlyStrip.innerHTML = '';
hourlyTemps.forEach((temp, i) => {
const hourStr = String(i).padStart(2, '0') + ':00';
const box = document.createElement('div');
box.className = 'hour-box';
box.innerHTML = `
<span class="hour-time">${hourStr}</span>
<span class="hour-temp">${temp.toFixed(1)}°</span>
`;
hourlyStrip.appendChild(box);
});
// Hide Loader
document.getElementById('loader-overlay').classList.add('hidden');
}
// SVG plotting algorithm
function drawHourlyGraph(temps) {
const svg = document.getElementById('hourly-svg-graph');
svg.innerHTML = ''; // Reset
const width = 760;
const height = 160;
const paddingLeft = 32;
const paddingRight = 32;
const paddingTop = 36;
const paddingBottom = 24;
const plotWidth = width - paddingLeft - paddingRight;
const plotHeight = height - paddingTop - paddingBottom;
const minT = Math.min(...temps);
const maxT = Math.max(...temps);
const tempRange = maxT - minT === 0 ? 1 : maxT - minT;
// Construct 24 nodes coordinate system
const points = temps.map((temp, i) => {
const x = paddingLeft + (i / 23) * plotWidth;
const y = paddingTop + (1 - (temp - minT) / tempRange) * plotHeight;
return { x, y, temp, hour: i };
});
// Create definitions for gradients and glow filters
const defs = document.createElementNS('http://www.w3.org/2000/svg', 'defs');
defs.innerHTML = `
<linearGradient id="curve-gradient" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#38bdf8" stop-opacity="0.35"/>
<stop offset="100%" stop-color="#38bdf8" stop-opacity="0"/>
</linearGradient>
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="4" result="blur" />
<feComposite in="SourceGraphic" in2="blur" operator="over" />
</filter>
`;
svg.appendChild(defs);
// Construct Grid Horizontal Guides (min, max, median)
const guidValues = [maxT, (maxT + minT) / 2, minT];
guidValues.forEach(val => {
const y = paddingTop + (1 - (val - minT) / tempRange) * plotHeight;
const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', paddingLeft);
line.setAttribute('y1', y);
line.setAttribute('x2', width - paddingRight);
line.setAttribute('y2', y);
line.setAttribute('stroke', 'rgba(255,255,255,0.035)');
line.setAttribute('stroke-dasharray', '4,4');
svg.appendChild(line);
});
// Area Path Generation
let areaD = `M ${points[0].x} ${height - paddingBottom}`;
points.forEach(p => {
areaD += ` L ${p.x} ${p.y}`;
});
areaD += ` L ${points[points.length - 1].x} ${height - paddingBottom} Z`;
const areaPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
areaPath.setAttribute('d', areaD);
areaPath.setAttribute('fill', 'url(#curve-gradient)');
svg.appendChild(areaPath);
// Stroke Line Path Generation
let lineD = `M ${points[0].x} ${points[0].y}`;
for (let i = 1; i < points.length; i++) {
lineD += ` L ${points[i].x} ${points[i].y}`;
}
const linePath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
linePath.setAttribute('d', lineD);
linePath.setAttribute('fill', 'none');
linePath.setAttribute('stroke', '#38bdf8');
linePath.setAttribute('stroke-width', '3');
linePath.setAttribute('stroke-linecap', 'round');
linePath.setAttribute('stroke-linejoin', 'round');
linePath.setAttribute('filter', 'url(#glow)');
svg.appendChild(linePath);
// Hour Labels and Node Circles (Interval selection to avoid cramming text)
points.forEach((p, index) => {
// Draw circles for major 3-hour chunks or endpoints
if (index % 3 === 0 || index === 23) {
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
circle.setAttribute('cx', p.x);
circle.setAttribute('cy', p.y);
circle.setAttribute('r', '4');
circle.setAttribute('fill', '#0b0c0f');
circle.setAttribute('stroke', '#38bdf8');
circle.setAttribute('stroke-width', '2.5');
svg.appendChild(circle);
// Value above dot
const textVal = document.createElementNS('http://www.w3.org/2000/svg', 'text');
textVal.setAttribute('x', p.x);
textVal.setAttribute('y', p.y - 10);
textVal.setAttribute('fill', '#fff');
textVal.setAttribute('font-size', '10px');
textVal.setAttribute('font-weight', '600');
textVal.setAttribute('text-anchor', 'middle');
textVal.textContent = `${p.temp.toFixed(1)}°`;
svg.appendChild(textVal);
// Hour Label below grid
const textHour = document.createElementNS('http://www.w3.org/2000/svg', 'text');
textHour.setAttribute('x', p.x);
textHour.setAttribute('y', height - 4);
textHour.setAttribute('fill', '#64748b');
textHour.setAttribute('font-size', '10px');
textHour.setAttribute('font-weight', '500');
textHour.setAttribute('text-anchor', 'middle');
textHour.textContent = String(p.hour).padStart(2, '0') + ':00';
svg.appendChild(textHour);
}
});
}
// Interrupted status renderer
function showError(message) {
document.getElementById('loader-overlay').classList.add('hidden');
const errOverlay = document.getElementById('error-overlay');
document.getElementById('error-message').innerText = message;
errOverlay.classList.add('visible');
}
// Init Execution on DOM Load
window.addEventListener('DOMContentLoaded', loadWeatherData);
</script>
</body>
</html>L1 —— 廉价的确定性描述量
| bytes 总计 | 46,913 | html / css / js | 10,213 / 14,271 / 22,429 |
|---|---|---|---|
| dom 节点 | 130 | dom 深度 | 12 |
| css 规则 | 89 | 含 js | 是 |
| brightness | 41.7 | contrast | 27.5 |
| colorfulness | 52.7 | 留白 | 63.5% |
该 slot 的 telemetry
| prompt tokens | 74,372 | completion tokens | 55,265 |
|---|---|---|---|
| total tokens | 129,637 | wall | 285.5 s |
| cost | — | request id | — |
config.json574 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_NONE",
"method": "oauth-login"
},
"billing": "plan",
"config_id": "gemini-3.5-flash--cli--cursor--dev",
"effort": null,
"family": "gemini",
"m": {
"min": 2,
"q": 2
},
"model_id": "gemini-3.5-flash",
"protocol": "cli",
"served_model": "gemini-3.5-flash",
"telemetry": {
"completion_tokens": 181773,
"cost_usd": null,
"prompt_tokens": 162608,
"total_tokens": 344381,
"wall_ms": 1092060
},
"transport": "cursor-agent-cli-isolated-home",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-08-13--cursor-s2",
"config_id": "gemini-3.5-flash--cli--cursor--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-13T02:12:07.728575+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T02:07:03.495278+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-08-13T02:16:56.662496+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T02:12:11.164626+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-08-13T02:20:58.421528+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T02:17:00.105832+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-08-13T02:25:26.986114+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-13T02:21:02.941546+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
}
}
}