359 lines
14 KiB
XML
Executable File
359 lines
14 KiB
XML
Executable File
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="1352"
|
|
viewBox="0 0 1600 1352" role="img" aria-labelledby="title desc">
|
|
<title id="title">Frosty Deno Logic Flow</title>
|
|
<desc
|
|
id="desc">Control-flow diagram of the Frosty Deno request lifecycle, including middleware order, admin and inference branches, cache and fallback decisions, error handling, and background loops.</desc>
|
|
<defs>
|
|
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="5"
|
|
orient="auto" markerUnits="strokeWidth">
|
|
<path d="M 0 0 L 10 5 L 0 10 z" fill="#334155" />
|
|
</marker>
|
|
<marker id="arrow-red" markerWidth="10" markerHeight="10" refX="8" refY="5"
|
|
orient="auto" markerUnits="strokeWidth">
|
|
<path d="M 0 0 L 10 5 L 0 10 z" fill="#b91c1c" />
|
|
</marker>
|
|
<style>
|
|
text {
|
|
font-family: Arial, Helvetica, sans-serif;
|
|
fill: #0f172a;
|
|
font-size: 14px;
|
|
}
|
|
.title {
|
|
font-size: 26px;
|
|
font-weight: 700;
|
|
}
|
|
.subtitle {
|
|
font-size: 15px;
|
|
fill: #334155;
|
|
}
|
|
.entity {
|
|
fill: #eef6d7;
|
|
stroke: #3f6212;
|
|
stroke-width: 2;
|
|
}
|
|
.process {
|
|
fill: #e2e8f0;
|
|
stroke: #334155;
|
|
stroke-width: 2;
|
|
}
|
|
.decision {
|
|
fill: #fff7ed;
|
|
stroke: #c2410c;
|
|
stroke-width: 2;
|
|
}
|
|
.store {
|
|
fill: #dbeafe;
|
|
stroke: #1d4ed8;
|
|
stroke-width: 2;
|
|
}
|
|
.aux {
|
|
fill: #f8fafc;
|
|
stroke: #64748b;
|
|
stroke-width: 2;
|
|
stroke-dasharray: 8 6;
|
|
}
|
|
.legend {
|
|
fill: #ffffff;
|
|
stroke: #334155;
|
|
stroke-width: 1.5;
|
|
}
|
|
.line {
|
|
fill: none;
|
|
stroke: #334155;
|
|
stroke-width: 2.5;
|
|
marker-end: url(#arrow);
|
|
}
|
|
.line-thin {
|
|
fill: none;
|
|
stroke: #334155;
|
|
stroke-width: 2;
|
|
marker-end: url(#arrow);
|
|
}
|
|
.line-error {
|
|
fill: none;
|
|
stroke: #b91c1c;
|
|
stroke-width: 2.5;
|
|
stroke-dasharray: 8 6;
|
|
marker-end: url(#arrow-red);
|
|
}
|
|
.line-async {
|
|
fill: none;
|
|
stroke: #64748b;
|
|
stroke-width: 2;
|
|
stroke-dasharray: 7 5;
|
|
marker-end: url(#arrow);
|
|
}
|
|
.small {
|
|
font-size: 12px;
|
|
fill: #475569;
|
|
}
|
|
.label {
|
|
font-size: 12px;
|
|
font-weight: 700;
|
|
fill: #334155;
|
|
/* Halo so an edge label stays readable where it must cross a
|
|
connector. Repositioning fixes label-on-box; this fixes
|
|
label-on-line, which no amount of nudging avoids. */
|
|
paint-order: stroke;
|
|
stroke: #f8fafc;
|
|
stroke-width: 4px;
|
|
stroke-linejoin: round;
|
|
}
|
|
.center {
|
|
text-anchor: middle;
|
|
}
|
|
</style>
|
|
</defs>
|
|
|
|
<g id="layer-background">
|
|
<rect x="0" y="0" width="1600" height="1352" fill="#f8fafc" />
|
|
</g>
|
|
|
|
<g id="layer-title">
|
|
<text x="40" y="54" class="title">Frosty Deno Logic Flow</text>
|
|
<text x="40" y="82"
|
|
class="subtitle">Verified request path from client entry through middleware, routing, admission, caching, dispatch, translation, and response</text>
|
|
</g>
|
|
|
|
<!-- Legend is a single bottom strip, not a floating block. The previous
|
|
top-right placement overlapped the admin branch, and its right-hand column
|
|
put 14px labels at x=1452, so "Background or async path" ran to ~1620 and was
|
|
clipped by the 1600 canvas. A strip in dedicated space cannot collide, and
|
|
every x below is placed from the measured label width. -->
|
|
<g id="layer-legend">
|
|
<rect x="40" y="1252" width="1520" height="84" rx="12" class="legend" />
|
|
<text x="64" y="1300" class="label" style="font-size:14px;">Legend</text>
|
|
|
|
<rect x="146" y="1282" width="44" height="26" rx="13" class="entity" />
|
|
<text x="200" y="1300">External entity</text>
|
|
|
|
<rect x="336" y="1282" width="44" height="26" class="process" />
|
|
<text x="390" y="1300">Process or component</text>
|
|
|
|
<polygon points="584,1282 606,1295 584,1308 562,1295" class="decision" />
|
|
<text x="616" y="1300">Decision</text>
|
|
|
|
<path d="M701 1282 L701 1308 L745 1308 L745 1282 Q723 1292 701 1282 z"
|
|
class="store" />
|
|
<text x="755" y="1300">Persistent store</text>
|
|
|
|
<path d="M898 1295 L954 1295" class="line-thin" />
|
|
<text x="964" y="1300">Primary flow</text>
|
|
|
|
<path d="M1078 1295 L1134 1295" class="line-error" />
|
|
<text x="1144" y="1300">Error path</text>
|
|
|
|
<path d="M1243 1295 L1299 1295" class="line-async" />
|
|
<text x="1309" y="1300">Background or async path</text>
|
|
</g>
|
|
|
|
<g id="layer-entities">
|
|
<rect x="52" y="150" width="220" height="76" rx="18" class="entity" />
|
|
<text x="162" y="182" class="center"
|
|
style="font-weight:700;">API Client</text>
|
|
<text x="162" y="204" class="center small">OpenAI-compatible callers</text>
|
|
|
|
<rect x="52" y="264" width="220" height="76" rx="18" class="entity" />
|
|
<text x="162" y="296" class="center"
|
|
style="font-weight:700;">Operator Browser</text>
|
|
<text x="162" y="318" class="center small">Same-origin control UI</text>
|
|
|
|
<rect x="1330" y="1048" width="210" height="84" rx="18" class="entity" />
|
|
<text x="1435" y="1082" class="center"
|
|
style="font-weight:700;">HTTP Response</text>
|
|
<text x="1435" y="1104"
|
|
class="center small">SSE, JSON, files, or errors</text>
|
|
</g>
|
|
|
|
<g id="layer-main-flow">
|
|
<rect x="360" y="194" width="230" height="84" class="process" />
|
|
<text x="475" y="228" class="center"
|
|
style="font-weight:700;">Gateway Listener</text>
|
|
<text x="475" y="250" class="center small">Deno.serve on :8080</text>
|
|
|
|
<rect x="658" y="156" width="288" height="160" class="process" />
|
|
<text x="802" y="188" class="center"
|
|
style="font-weight:700;">Middleware Stack</text>
|
|
<text x="802" y="214"
|
|
class="center small">error handler, plugins, compat rewrite,</text>
|
|
<text x="802" y="234"
|
|
class="center small">request logger, metrics, origin guard,</text>
|
|
<text x="802" y="254"
|
|
class="center small">admin auth, governance, telemetry</text>
|
|
|
|
<polygon points="1046,176 1130,236 1046,296 962,236" class="decision" />
|
|
<text x="1046" y="230" class="center" style="font-weight:700;">Admin</text>
|
|
<text x="1046" y="248" class="center small">path?</text>
|
|
|
|
<rect x="1230" y="126" width="248" height="82" class="process" />
|
|
<text x="1354" y="160" class="center"
|
|
style="font-weight:700;">Origin Guard + Admin Auth</text>
|
|
<text x="1354" y="182"
|
|
class="center small">protects /api/* before body parsing</text>
|
|
|
|
<rect x="1230" y="250" width="248" height="82" class="process" />
|
|
<text x="1354" y="284" class="center"
|
|
style="font-weight:700;">Admin Route Handlers</text>
|
|
<text x="1354" y="306"
|
|
class="center small">providers, config, logs, settings, MCP</text>
|
|
|
|
<rect x="922" y="360" width="248" height="82" class="process" />
|
|
<text x="1046" y="394" class="center"
|
|
style="font-weight:700;">Governance Middleware</text>
|
|
<text x="1046" y="416"
|
|
class="center small">virtual keys, budgets, rate limits</text>
|
|
|
|
<polygon points="1046,472 1130,532 1046,592 962,532" class="decision" />
|
|
<text x="1046" y="526" class="center"
|
|
style="font-weight:700;">Admitted</text>
|
|
<text x="1046" y="544" class="center small">to execute?</text>
|
|
|
|
<rect x="922" y="620" width="248" height="82" class="process" />
|
|
<text x="1046" y="654" class="center"
|
|
style="font-weight:700;">Route Handler</text>
|
|
<text x="1046" y="676"
|
|
class="center small">inference, compat, advanced, or MCP</text>
|
|
|
|
<polygon points="1046,734 1130,794 1046,854 962,794" class="decision" />
|
|
<text x="1046" y="788" class="center"
|
|
style="font-weight:700;">Cache hit</text>
|
|
<text x="1046" y="806" class="center small">and usable?</text>
|
|
|
|
<rect x="1230" y="744" width="248" height="82" class="process" />
|
|
<text x="1354" y="778" class="center"
|
|
style="font-weight:700;">Return Cached Response</text>
|
|
<text x="1354" y="800"
|
|
class="center small">exact or semantic cache result</text>
|
|
|
|
<rect x="922" y="882" width="248" height="82" class="process" />
|
|
<text x="1046" y="916" class="center"
|
|
style="font-weight:700;">Provider Resolution</text>
|
|
<text x="1046" y="938"
|
|
class="center small">default, alias, account, fallback chain</text>
|
|
|
|
<rect x="922" y="994" width="248" height="82" class="process" />
|
|
<text x="1046" y="1028" class="center"
|
|
style="font-weight:700;">Dispatch With Fallback</text>
|
|
<text x="1046" y="1050"
|
|
class="center small">retry only on 429, 5xx, or network error</text>
|
|
|
|
<polygon points="1046,1104 1130,1164 1046,1224 962,1164" class="decision" />
|
|
<text x="1046" y="1158" class="center"
|
|
style="font-weight:700;">Retryable</text>
|
|
<text x="1046" y="1176" class="center small">failure?</text>
|
|
|
|
<rect x="1230" y="882" width="248" height="74" class="process" />
|
|
<text x="1354" y="914" class="center"
|
|
style="font-weight:700;">Stream Tee + Translation</text>
|
|
<text x="1354" y="936"
|
|
class="center small">canonical SSE, edge format translation</text>
|
|
|
|
<rect x="1230" y="962" width="248" height="82" class="process" />
|
|
<text x="1354" y="994" class="center"
|
|
style="font-weight:700;">Late Telemetry Enrichment</text>
|
|
<text x="1354" y="1016"
|
|
class="center small">tokens, cost, log patch, metrics</text>
|
|
|
|
<rect x="1266" y="408" width="196" height="82" class="process" />
|
|
<text x="1364" y="442" class="center"
|
|
style="font-weight:700;">Canonical Error</text>
|
|
<text x="1364" y="464"
|
|
class="center small">{error:{message,type,param,code}}</text>
|
|
</g>
|
|
|
|
<g id="layer-stores">
|
|
<path d="M286 654 L286 1018 L514 1018 L514 654 Q400 688 286 654 z"
|
|
class="store" />
|
|
<path d="M286 654 Q400 620 514 654" class="store" fill="none" />
|
|
<text x="400" y="734" class="center"
|
|
style="font-weight:700;">PostgreSQL</text>
|
|
<text x="400" y="758"
|
|
class="center small">state, counters, log store,</text>
|
|
<text x="400" y="778" class="center small">response cache, pgvector</text>
|
|
</g>
|
|
|
|
<g id="layer-background-loops">
|
|
<rect x="40" y="760" width="190" height="64" class="aux" />
|
|
<text x="135" y="794" class="center"
|
|
style="font-weight:700;">Pricing Sync</text>
|
|
<text x="135" y="814" class="center small">optional LiteLLM feed</text>
|
|
|
|
<rect x="40" y="846" width="190" height="64" class="aux" />
|
|
<text x="135" y="880" class="center"
|
|
style="font-weight:700;">Cache Janitor</text>
|
|
<text x="135" y="900" class="center small">removes expired rows</text>
|
|
|
|
<rect x="40" y="932" width="190" height="64" class="aux" />
|
|
<text x="135" y="966" class="center"
|
|
style="font-weight:700;">Config Reconcile Poll</text>
|
|
<text x="135" y="986" class="center small">backs up LISTEN/NOTIFY</text>
|
|
|
|
<rect x="40" y="1018" width="190" height="64" class="aux" />
|
|
<text x="135" y="1052" class="center"
|
|
style="font-weight:700;">MCP Health Monitor</text>
|
|
<text x="135" y="1072" class="center small">checks configured clients</text>
|
|
|
|
<rect x="40" y="1104" width="190" height="64" class="aux" />
|
|
<text x="135" y="1138" class="center"
|
|
style="font-weight:700;">OTLP Flush Loop</text>
|
|
<text x="135" y="1158" class="center small">ships batched spans</text>
|
|
</g>
|
|
|
|
<g id="layer-connectors">
|
|
<path d="M272 188 H360" class="line" />
|
|
<path d="M272 302 H360" class="line" />
|
|
<path d="M590 236 H658" class="line" />
|
|
<path d="M946 236 H962" class="line" />
|
|
|
|
<path d="M1130 236 H1230" class="line" />
|
|
<text x="1168" y="224" class="label">Yes</text>
|
|
<path d="M1354 208 V250" class="line" />
|
|
<path d="M1230 166 H1170 V430 H1266" class="line-error" />
|
|
<text x="1166" y="160" class="label" style="fill:#b91c1c;">401 / 403</text>
|
|
|
|
<path d="M1046 296 V360" class="line" />
|
|
<text x="1060" y="330" class="label">No</text>
|
|
<path d="M1046 442 V472" class="line" />
|
|
<!-- Reaches the Canonical Error box on its own. It used to stop at
|
|
x=1266 and rely on the long vertical that ran there; that vertical now
|
|
routes up the right margin, so without this the arrow pointed at
|
|
nothing. -->
|
|
<path d="M1130 532 H1218 V462 H1266" class="line-error" />
|
|
<text x="1160" y="520" class="label" style="fill:#b91c1c;">Denied</text>
|
|
|
|
<path d="M1046 592 V620" class="line" />
|
|
<path d="M1046 702 V734" class="line" />
|
|
<path d="M1130 794 H1230" class="line" />
|
|
<text x="1168" y="782" class="label">Yes</text>
|
|
<!-- A bypass, so it routes around Stream Tee and Late Telemetry instead
|
|
of crossing both, which read as though the cached path went through
|
|
them. -->
|
|
<path d="M1354 826 V854 H1502 V1048" class="line" />
|
|
<path d="M1046 854 V882" class="line" />
|
|
<text x="1060" y="870" class="label">No</text>
|
|
<path d="M1046 964 V994" class="line" />
|
|
<path d="M1046 1076 V1104" class="line" />
|
|
<path d="M1130 1164 H1190 V1032 H1230" class="line" />
|
|
<text x="1144" y="1152" class="label">No</text>
|
|
<path d="M1046 1104 H898 V922 H922" class="line" />
|
|
<text x="890" y="1010" class="label">Yes, next provider</text>
|
|
<!-- Up the right margin (x=1560), not x=1266: the old route crossed
|
|
Return Cached Response, Stream Tee and Late Telemetry. 1560 clears the
|
|
column (ends 1478) and the HTTP Response box (ends 1540). -->
|
|
<path d="M1130 1210 H1560 V449 H1462" class="line-error" />
|
|
<text x="1150" y="1200" class="label" style="fill:#b91c1c;">No, fail</text>
|
|
<path d="M1478 1004 V1048" class="line" />
|
|
|
|
<path d="M514 732 H922" class="line-async" />
|
|
<path d="M514 780 H1002" class="line-async" />
|
|
<path d="M514 832 H1230" class="line-async" />
|
|
<path d="M514 884 H1230" class="line-async" />
|
|
|
|
<path d="M230 792 H286" class="line-async" />
|
|
<path d="M230 878 H286" class="line-async" />
|
|
<path d="M230 964 H286" class="line-async" />
|
|
<path d="M230 1050 H286" class="line-async" />
|
|
<path d="M230 1136 H1230" class="line-async" />
|
|
</g>
|
|
</svg>
|