File size: 19,520 Bytes
a276429
 
 
 
0ffff7f
 
a276429
 
0ffff7f
a276429
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
 
 
a276429
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
0ffff7f
 
a276429
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
a276429
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0ffff7f
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="2100" height="1320" viewBox="0 0 2100 1320" role="img" aria-labelledby="title desc">
  <title id="title">GLiNER StreamingSpan architecture</title>
  <desc id="desc">Minimal architecture diagram showing a cached entity-type prompt on the left, an incrementally appended input stream on the right, a causal transformer with a reusable key-value cache, cached label and word states, rolling span representations, similarity scores, and a revised entity snapshot.</desc>

  <defs>
    <marker id="arrow" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
      <path d="M0 0L10 5L0 10Z" fill="#31383f"/>
    </marker>
    <marker id="arrowRed" viewBox="0 0 10 10" refX="8.5" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
      <path d="M0 0L10 5L0 10Z" fill="#df5961"/>
    </marker>

    <g id="vecPrompt">
      <rect width="48" height="64" fill="#f7f5f5" stroke="#9b6870" stroke-width="1.4"/>
      <rect x="8" y="7" width="32" height="8" fill="#c7a2a8"/>
      <rect x="8" y="19" width="32" height="8" fill="#7f666b"/>
      <rect x="8" y="31" width="32" height="8" fill="#d9c2c5"/>
      <rect x="8" y="43" width="32" height="8" fill="#9d7b80"/>
      <rect x="8" y="55" width="32" height="5" fill="#5e4f52"/>
    </g>
    <g id="vecCached">
      <rect width="48" height="64" fill="#f4f6f7" stroke="#75828a" stroke-width="1.4"/>
      <rect x="8" y="7" width="32" height="8" fill="#c0c8cc"/>
      <rect x="8" y="19" width="32" height="8" fill="#7b878e"/>
      <rect x="8" y="31" width="32" height="8" fill="#d3d9dc"/>
      <rect x="8" y="43" width="32" height="8" fill="#929da3"/>
      <rect x="8" y="55" width="32" height="5" fill="#626d73"/>
    </g>
    <g id="vecNew">
      <rect width="48" height="64" fill="#edf7fb" stroke="#3885a8" stroke-width="2"/>
      <rect x="8" y="7" width="32" height="8" fill="#a7d0e1"/>
      <rect x="8" y="19" width="32" height="8" fill="#4f90ae"/>
      <rect x="8" y="31" width="32" height="8" fill="#c7e2ed"/>
      <rect x="8" y="43" width="32" height="8" fill="#72abc4"/>
      <rect x="8" y="55" width="32" height="5" fill="#2f6f8d"/>
    </g>
    <g id="vecRevised">
      <rect width="48" height="64" fill="#fff4f4" stroke="#df5961" stroke-width="2" stroke-dasharray="5 4"/>
      <rect x="8" y="7" width="32" height="8" fill="#efb4b8"/>
      <rect x="8" y="19" width="32" height="8" fill="#b36c72"/>
      <rect x="8" y="31" width="32" height="8" fill="#f4d2d5"/>
      <rect x="8" y="43" width="32" height="8" fill="#d78b91"/>
      <rect x="8" y="55" width="32" height="5" fill="#8f555a"/>
    </g>

    <style>
      text { font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; fill: #111820; }
      .title { font-size: 26.1px; font-weight: 720; letter-spacing: .2px; }
      .subtitle { font-size: 11.3px; fill: #596570; }
      .section { font-size: 18.3px; font-weight: 720; }
      .heading { font-size: 14.8px; font-weight: 720; }
      .body { font-size: 11.3px; }
      .small { font-size: 9.6px; fill: #4f5b65; }
      .tiny { font-size: 8.3px; fill: #59646d; }
      .mono { font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; }
      .chip-text { font-size: 9.6px; font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; text-anchor: middle; dominant-baseline: middle; }
      .panel { stroke: #4f5962; stroke-width: 1.35; }
      .dash { stroke-dasharray: 6 5; }
      .flow { fill: none; stroke: #31383f; stroke-width: 1.8; marker-end: url(#arrow); }
      .flow-red { fill: none; stroke: #df5961; stroke-width: 1.8; stroke-dasharray: 6 5; marker-end: url(#arrowRed); }
      .prompt { fill: #eadff0; stroke: #725d82; stroke-width: 1.25; }
      .marker { fill: #faeeee; stroke: #df6770; stroke-width: 1.25; }
      .sep { fill: #d8e9ee; stroke: #537581; stroke-width: 1.25; }
      .cached { fill: #e1e9ed; stroke: #70808a; stroke-width: 1.25; }
      .current { fill: #cce5f0; stroke: #397c9b; stroke-width: 1.4; }
      .person { fill: #eadff2; stroke: #7658a0; stroke-width: 1.2; }
      .organization { fill: #f2e3a9; stroke: #a17a00; stroke-width: 1.2; }
      .location { fill: #d6e8d5; stroke: #398148; stroke-width: 1.2; }
    </style>
  </defs>

  <rect width="2100" height="1320" fill="#f1f2f2"/>
  <g transform="translate(15 4.5) scale(1.15)">
  <rect x="22" y="18" width="1756" height="1104" fill="none" stroke="#323a41" stroke-width="1.4" stroke-dasharray="6 5"/>

  <!-- Title and legend -->
  <text x="900" y="52" class="title" text-anchor="middle">GLiNER StreamingSpan Architecture</text>
  <text x="900" y="75" class="subtitle" text-anchor="middle">Causal cache reuse · rolling span revision · complete entity snapshots</text>
  <g transform="translate(1435 49)">
    <rect x="0" y="-10" width="13" height="13" rx="2" class="cached"/>
    <text x="20" y="1" class="tiny">cached</text>
    <rect x="79" y="-10" width="13" height="13" rx="2" class="current"/>
    <text x="99" y="1" class="tiny">new</text>
    <line x1="145" y1="-3" x2="171" y2="-3" stroke="#df5961" stroke-width="2" stroke-dasharray="6 4"/>
    <text x="179" y="1" class="tiny">rescored</text>
  </g>

  <!-- Prompt on the left -->
  <text x="435" y="108" class="heading" text-anchor="middle" fill="#cf4e55">Target entity types prompt</text>
  <line x1="322" y1="114" x2="548" y2="114" stroke="#cf4e55" stroke-width="1.5"/>
  <rect x="55" y="122" width="760" height="153" fill="#f8e9e7" class="panel dash"/>
  <text x="82" y="151" class="tiny" font-weight="700">SERIALIZED ON THE COLD PASS</text>
  <g>
    <rect x="80" y="172" width="100" height="43" rx="5" class="person"/>
    <text x="130" y="193.5" class="chip-text">person</text>
    <rect x="188" y="172" width="90" height="43" rx="5" class="marker"/>
    <text x="233" y="193.5" class="chip-text">&lt;&lt;LABEL&gt;&gt;</text>
    <rect x="286" y="172" width="140" height="43" rx="5" class="organization"/>
    <text x="356" y="193.5" class="chip-text">organization</text>
    <rect x="434" y="172" width="90" height="43" rx="5" class="marker"/>
    <text x="479" y="193.5" class="chip-text">&lt;&lt;LABEL&gt;&gt;</text>
    <rect x="532" y="172" width="110" height="43" rx="5" class="location"/>
    <text x="587" y="193.5" class="chip-text">location</text>
    <rect x="650" y="172" width="90" height="43" rx="5" class="marker"/>
    <text x="695" y="193.5" class="chip-text">&lt;&lt;LABEL&gt;&gt;</text>
  </g>
  <text x="435" y="249" class="small" text-anchor="middle">label marker states → compact label encoder → cached label embeddings</text>

  <!-- Separator between prompt and text -->
  <text x="870" y="154" class="tiny" text-anchor="middle" font-weight="700">BOUNDARY</text>
  <rect x="827" y="172" width="86" height="43" rx="5" class="sep"/>
  <text x="870" y="193.5" class="chip-text">&lt;&lt;SEP&gt;&gt;</text>

  <!-- Stream on the right -->
  <text x="1345" y="108" class="heading" text-anchor="middle" fill="#3d8a31">Input text stream</text>
  <line x1="1262" y1="114" x2="1428" y2="114" stroke="#3d8a31" stroke-width="1.5"/>
  <rect x="925" y="122" width="820" height="153" fill="#e7f2e2" class="panel dash"/>
  <text x="950" y="151" class="tiny" font-weight="700">CACHED TEXT · t−1</text>
  <text x="1234" y="151" class="tiny" font-weight="700" fill="#28718f">APPEND · t</text>
  <g>
    <rect x="950" y="172" width="80" height="43" rx="5" class="cached"/>
    <text x="990" y="193.5" class="chip-text">Alice</text>
    <rect x="1038" y="172" width="100" height="43" rx="5" class="cached"/>
    <text x="1088" y="193.5" class="chip-text">Johnson</text>
    <rect x="1146" y="172" width="46" height="43" rx="5" class="cached"/>
    <text x="1169" y="193.5" class="chip-text"></text>
    <line x1="1213" y1="158" x2="1213" y2="226" stroke="#3985a7" stroke-width="1.6" stroke-dasharray="5 4"/>
    <rect x="1233" y="172" width="88" height="43" rx="5" class="current"/>
    <text x="1277" y="193.5" class="chip-text">joined</text>
    <rect x="1329" y="172" width="76" height="43" rx="5" class="current"/>
    <text x="1367" y="193.5" class="chip-text">Acme</text>
    <rect x="1413" y="172" width="46" height="43" rx="5" class="current"/>
    <text x="1436" y="193.5" class="chip-text">in</text>
    <rect x="1467" y="172" width="76" height="43" rx="5" class="current"/>
    <text x="1505" y="193.5" class="chip-text">Paris</text>
  </g>
  <text x="1335" y="249" class="small" text-anchor="middle">the session may receive one word, sentence, or arbitrary text chunk per call</text>

  <path d="M435 275L435 307" class="flow"/>
  <path d="M1335 275L1335 307" class="flow"/>

  <!-- Causal backbone -->
  <rect x="55" y="309" width="1690" height="132" rx="7" fill="#cfe2f3" class="panel"/>
  <text x="900" y="344" class="section" text-anchor="middle">1 · Causal Transformer Language Model</text>
  <text x="900" y="368" class="body" text-anchor="middle">SmolLM2, Qwen, or another compatible decoder backbone</text>
  <text x="900" y="388" class="small" text-anchor="middle">Cold pass: prompt + first chunk · warm pass: current tokens attend to cached history</text>

  <rect x="430" y="398" width="207" height="31" rx="5" fill="#e9e5f0" stroke="#716485" stroke-width="1.15"/>
  <text x="533.5" y="413.5" class="chip-text">KV cache · t−1</text>
  <path d="M637 413.5L721 413.5" class="flow"/>
  <rect x="723" y="398" width="354" height="31" rx="5" fill="#eef5f8" stroke="#628092" stroke-width="1.15"/>
  <text x="900" y="413.5" class="chip-text">new token IDs + absolute positions</text>
  <path d="M1077 413.5L1161 413.5" class="flow"/>
  <rect x="1163" y="398" width="207" height="31" rx="5" fill="#e9e5f0" stroke="#716485" stroke-width="1.15"/>
  <text x="1266.5" y="413.5" class="chip-text">updated KV cache · t</text>

  <path d="M900 441L900 472" class="flow"/>

  <!-- Decoder states -->
  <text x="900" y="485" class="heading" text-anchor="middle">Reusable decoder token / word representations</text>
  <text x="286" y="507" class="tiny" text-anchor="middle" font-weight="700">LABEL MARKER STATES · COLD ONLY</text>
  <text x="842" y="507" class="tiny" text-anchor="middle" font-weight="700">CACHED WORD STATES</text>
  <text x="1266" y="507" class="tiny" text-anchor="middle" font-weight="700" fill="#28718f">NEW WORD STATES</text>
  <g>
    <use href="#vecPrompt" x="145" y="518"/>
    <use href="#vecPrompt" x="255" y="518"/>
    <use href="#vecPrompt" x="365" y="518"/>
    <rect x="483" y="518" width="48" height="64" fill="#eef6f7" stroke="#537581" stroke-width="1.4"/>
    <rect x="491" y="527" width="32" height="8" fill="#aac5ce"/><rect x="491" y="539" width="32" height="8" fill="#62828e"/><rect x="491" y="551" width="32" height="8" fill="#d1e1e6"/><rect x="491" y="563" width="32" height="13" fill="#7898a3"/>

    <use href="#vecCached" x="710" y="518"/>
    <use href="#vecCached" x="785" y="518"/>
    <use href="#vecCached" x="860" y="518"/>
    <use href="#vecCached" x="935" y="518"/>
    <line x1="1026" y1="507" x2="1026" y2="592" stroke="#3985a7" stroke-width="1.6" stroke-dasharray="5 4"/>
    <use href="#vecNew" x="1095" y="518"/>
    <use href="#vecNew" x="1170" y="518"/>
    <use href="#vecNew" x="1245" y="518"/>
    <use href="#vecNew" x="1320" y="518"/>
  </g>
  <g class="tiny" text-anchor="middle">
    <text x="169" y="598">person</text><text x="279" y="598">organization</text><text x="389" y="598">location</text><text x="507" y="598">SEP</text>
    <text x="734" y="598">Alice</text><text x="809" y="598">Johnson</text><text x="884" y="598"></text><text x="959" y="598">past</text>
    <text x="1119" y="598">joined</text><text x="1194" y="598">Acme</text><text x="1269" y="598">in</text><text x="1344" y="598">latest</text>
  </g>
  <path d="M1368 550L1448 550" class="flow"/>
  <rect x="1450" y="520" width="235" height="59" rx="5" fill="#ece9f0" stroke="#7a7087" stroke-width="1.2"/>
  <text x="1567.5" y="541" class="body" text-anchor="middle" font-weight="700">Session cache</text>
  <text x="1567.5" y="561" class="small mono" text-anchor="middle">KV · words · labels · span scores</text>

  <path d="M450 608L450 631" class="flow"/>
  <path d="M1315 608L1315 631" class="flow"/>

  <!-- Representation branches -->
  <rect x="70" y="633" width="760" height="91" rx="5" fill="#f3b9bf" class="panel"/>
  <text x="450" y="666" class="heading" text-anchor="middle">2A · Label representation layer</text>
  <text x="450" y="691" class="body" text-anchor="middle">prompt slice through &lt;&lt;SEP&gt;&gt; → compact context encoder → one vector per &lt;&lt;LABEL&gt;&gt;</text>
  <text x="450" y="710" class="tiny" text-anchor="middle">computed on the cold pass and reused for every warm append</text>

  <rect x="900" y="633" width="830" height="91" rx="5" fill="#f3b9bf" class="panel"/>
  <text x="1315" y="666" class="heading" text-anchor="middle">2B · Rolling span representation layer</text>
  <text x="1315" y="691" class="body" text-anchor="middle">MarkerV2(start ⊕ end ⊕ latest) · width ≤ max_width</text>
  <text x="1315" y="710" class="tiny" text-anchor="middle">all new endings + recent endings where latest − end ≤ right_context_width</text>

  <path d="M450 724L450 751" class="flow"/>
  <path d="M1315 724L1315 751" class="flow"/>

  <!-- Label and span embeddings -->
  <text x="450" y="760" class="small" text-anchor="middle" font-weight="700">CACHED LABEL EMBEDDINGS</text>
  <g>
    <use href="#vecPrompt" x="205" y="773"/>
    <use href="#vecPrompt" x="425" y="773"/>
    <use href="#vecPrompt" x="645" y="773"/>
    <rect x="180" y="844" width="98" height="25" rx="3" class="person"/>
    <text x="229" y="856.5" class="chip-text">ℓ_person</text>
    <rect x="376" y="844" width="146" height="25" rx="3" class="organization"/>
    <text x="449" y="856.5" class="chip-text">ℓ_organization</text>
    <rect x="620" y="844" width="98" height="25" rx="3" class="location"/>
    <text x="669" y="856.5" class="chip-text">ℓ_location</text>
  </g>

  <text x="1315" y="760" class="small" text-anchor="middle" font-weight="700">ROLLING SPAN EMBEDDINGS</text>
  <g>
    <use href="#vecRevised" x="978" y="773"/>
    <use href="#vecNew" x="1110" y="773"/>
    <use href="#vecNew" x="1242" y="773"/>
    <use href="#vecNew" x="1374" y="773"/>
    <use href="#vecNew" x="1506" y="773"/>
    <use href="#vecNew" x="1638" y="773"/>
  </g>
  <g class="tiny" text-anchor="middle">
    <text x="1002" y="850" fill="#c84f56">(0,1) revised</text>
    <text x="1134" y="850">(1,3)</text>
    <text x="1266" y="850">(3,4)</text>
    <text x="1398" y="850">(4,4)</text>
    <text x="1530" y="850">(4,6)</text>
    <text x="1662" y="850">(6,6)</text>
  </g>

  <path d="M450 869L450 886" class="flow"/>
  <path d="M1100 869L1100 886" class="flow"/>

  <!-- Similarity matrix -->
  <rect x="70" y="888" width="1055" height="165" fill="#ffffff" fill-opacity="0.42" class="panel"/>
  <text x="610" y="913" class="heading" text-anchor="middle">3 · Entity type × span similarity</text>
  <text x="1097" y="912" class="tiny" text-anchor="end">illustrative probabilities</text>

  <g class="tiny" text-anchor="middle">
    <text x="405" y="936">Alice Johnson</text>
    <text x="555" y="936">Johnson … joined</text>
    <text x="705" y="936">Acme</text>
    <text x="855" y="936">Acme in Paris</text>
    <text x="1005" y="936">Paris</text>
  </g>

  <rect x="115" y="945" width="185" height="26" class="person"/>
  <text x="207.5" y="958" class="chip-text">person</text>
  <rect x="115" y="974" width="185" height="26" class="organization"/>
  <text x="207.5" y="987" class="chip-text">organization</text>
  <rect x="115" y="1003" width="185" height="26" class="location"/>
  <text x="207.5" y="1016" class="chip-text">location</text>

  <g class="chip-text">
    <!-- person row -->
    <rect x="330" y="945" width="150" height="26" fill="#d9c9e9" stroke="#63717a"/><text x="405" y="958">0.93</text>
    <rect x="480" y="945" width="150" height="26" fill="#eef2f3" stroke="#63717a"/><text x="555" y="958">0.21</text>
    <rect x="630" y="945" width="150" height="26" fill="#f6f7f7" stroke="#63717a"/><text x="705" y="958">0.03</text>
    <rect x="780" y="945" width="150" height="26" fill="#f5f6f6" stroke="#63717a"/><text x="855" y="958">0.05</text>
    <rect x="930" y="945" width="150" height="26" fill="#f7f8f8" stroke="#63717a"/><text x="1005" y="958">0.02</text>
    <!-- organization row -->
    <rect x="330" y="974" width="150" height="26" fill="#f6f7f7" stroke="#63717a"/><text x="405" y="987">0.04</text>
    <rect x="480" y="974" width="150" height="26" fill="#f2f3f3" stroke="#63717a"/><text x="555" y="987">0.10</text>
    <rect x="630" y="974" width="150" height="26" fill="#eedb8d" stroke="#63717a"/><text x="705" y="987">0.88</text>
    <rect x="780" y="974" width="150" height="26" fill="#f3e9c4" stroke="#63717a"/><text x="855" y="987">0.44</text>
    <rect x="930" y="974" width="150" height="26" fill="#f7f8f8" stroke="#63717a"/><text x="1005" y="987">0.02</text>
    <!-- location row -->
    <rect x="330" y="1003" width="150" height="26" fill="#f6f7f7" stroke="#63717a"/><text x="405" y="1016">0.03</text>
    <rect x="480" y="1003" width="150" height="26" fill="#f4f5f5" stroke="#63717a"/><text x="555" y="1016">0.08</text>
    <rect x="630" y="1003" width="150" height="26" fill="#f5f6f6" stroke="#63717a"/><text x="705" y="1016">0.06</text>
    <rect x="780" y="1003" width="150" height="26" fill="#e8f0e7" stroke="#63717a"/><text x="855" y="1016">0.33</text>
    <rect x="930" y="1003" width="150" height="26" fill="#c9e2c8" stroke="#63717a"/><text x="1005" y="1016">0.91</text>
  </g>

  <path d="M1125 970L1148 970" class="flow"/>

  <!-- Revision and output -->
  <rect x="1150" y="888" width="580" height="165" fill="#dcebdc" class="panel"/>
  <text x="1440" y="917" class="heading" text-anchor="middle">4 · Revise history and decode</text>
  <text x="1180" y="946" class="body">• matching (start, end): replace the recent score</text>
  <text x="1180" y="970" class="body">• new boundary: append → threshold → flat / nested NER</text>
  <line x1="1180" y1="983" x2="1700" y2="983" stroke="#7d9680" stroke-width="1"/>
  <text x="1180" y="1002" class="tiny" font-weight="700">COMPLETE SNAPSHOT · t</text>
  <rect x="1180" y="1010" width="225" height="30" rx="4" fill="#f8f7fb" stroke="#7658a0" stroke-width="1.2"/>
  <circle cx="1196" cy="1025" r="4" fill="#7658a0"/>
  <text x="1300" y="1025" class="chip-text">Alice Johnson · person .93</text>
  <rect x="1420" y="1010" width="145" height="30" rx="4" fill="#fffaf0" stroke="#a17a00" stroke-width="1.2"/>
  <circle cx="1436" cy="1025" r="4" fill="#a17a00"/>
  <text x="1498" y="1025" class="chip-text">Acme · org .88</text>
  <rect x="1580" y="1010" width="130" height="30" rx="4" fill="#f5faf5" stroke="#398148" stroke-width="1.2"/>
  <circle cx="1596" cy="1025" r="4" fill="#398148"/>
  <text x="1649" y="1025" class="chip-text">Paris · loc .91</text>

  <!-- Compact operational note -->
  <text x="900" y="1082" class="body" text-anchor="middle" font-weight="650">Every append reuses KV, word, and label caches · only rolling candidates are rescored · the result is the full current snapshot</text>
  <text x="900" y="1106" class="small mono" text-anchor="middle">StreamingBatch  ·  AsyncStreamingEngine  ·  inference(session_id=…)</text>
  </g>
</svg>