@vllm-sr/dsh 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -10
- package/package.json +1 -1
- package/src/index.js +60 -18
- package/web/client.js +95 -55
package/README.md
CHANGED
|
@@ -75,8 +75,8 @@ instead of whole passages:
|
|
|
75
75
|
|
|
76
76
|
## See it in the Web UI
|
|
77
77
|
|
|
78
|
-
In `dsh web`, System One shows up in the conversation itself, where it acted, marked with
|
|
79
|
-
|
|
78
|
+
In `dsh web`, System One shows up in the conversation itself, where it acted, marked with a blue **System One** badge
|
|
79
|
+
(the blue of the vLLM logo) that carries the decision's latency:
|
|
80
80
|
|
|
81
81
|
- **Triage**: a card under your request with the kind of work, the effort, how unclear and how risky it is, and the
|
|
82
82
|
brief System Two was given.
|
|
@@ -94,9 +94,9 @@ badge that carries the decision's latency:
|
|
|
94
94
|
|
|
95
95
|
Routine checks (an allowed call, a clean result) are one line and fold with the turn's work. Cards stay visible when
|
|
96
96
|
the work folds, so a finished turn still shows what System One decided. Parallel calls in one step share one line or
|
|
97
|
-
card
|
|
98
|
-
|
|
99
|
-
measured latency.
|
|
97
|
+
card. A decision that takes longer than a moment shows as **Deciding** until its answer takes its place, and every
|
|
98
|
+
decision fades in once, the first time it appears (no motion with reduced motion). Each element shows the Decision
|
|
99
|
+
API's own answer: the probabilities, the model (in bold, as `vllm-sr/d3-ultra`) and the measured latency.
|
|
100
100
|
|
|
101
101
|
Set `systemOneUi` to `compact` for one line per decision, or to `off` to hide them.
|
|
102
102
|
|
|
@@ -109,18 +109,18 @@ attributes that say what it shows:
|
|
|
109
109
|
| --- | --- |
|
|
110
110
|
| `data-system-one` | `card`, `compact` (one line), `tool` (the `system_one` row) or `notice` (the free-key line) |
|
|
111
111
|
| `data-system-one-reflex` | `triage`, `guard`, `shield`, `privacy`, `done`, `tool` or `key` |
|
|
112
|
-
| `data-system-one-verdict` | triage `brief`; guard `allow`, `ask` or `deny`; shield `clean`, `removed` or `flagged`; privacy `masked`; done-check `stop` or `continue`; tool `running` or `done`; key `created` or `failed`; `error` when System One did not answer |
|
|
112
|
+
| `data-system-one-verdict` | triage `brief`; guard `allow`, `ask` or `deny`; shield `clean`, `removed` or `flagged`; privacy `masked` or `clean`; done-check `stop` or `continue`; tool `running` or `done`; key `created` or `failed`; `deciding` while System One has not answered yet, `cancelled` when the turn stopped first; `error` when System One did not answer |
|
|
113
113
|
| `data-system-one-outcome` | guard, once you answer its approval: `allowed`, `rejected`, `cancelled` or `failed` |
|
|
114
114
|
| `data-system-one-why` | done-check: `complete`, `waiting`, `unfinished`, `unchecked` or `unsupported` |
|
|
115
|
-
| `data-system-one-tone` | its colour: `ok` (green), `info` (
|
|
115
|
+
| `data-system-one-tone` | its colour: `ok` (green), `info` (blue), `warn` (amber), `bad` (red) or `muted` |
|
|
116
116
|
| `data-system-one-count` | how many decisions it holds (a batch: how many items) |
|
|
117
117
|
| `data-system-one-turn`, `data-system-one-step` | where it acted (the step for guard and shield) |
|
|
118
118
|
| `data-system-one-model` | the model that answered, as `vllm-sr/d3-ultra` |
|
|
119
119
|
| `data-system-one-span-model`, `data-system-one-spans` | the span model that marked words, as `vllm-sr/vela3-turbo`, and how many |
|
|
120
120
|
|
|
121
|
-
Inside a root, `data-system-one-part` marks `badge` (the
|
|
121
|
+
Inside a root, `data-system-one-part` marks `badge` (the blue **System One** pill), `latency`, `reflex`, `summary`,
|
|
122
122
|
`model`, `head`, `toggle` (the button of a one-line element), `rows`, `verdict`, `outcome`, `subject`, `facts`,
|
|
123
|
-
`note` and `
|
|
123
|
+
`note`, `more` and `progress` (the line that moves while it decides), in the batch row also `stack`, `legend`, `failed`, `results` and `raw`, and in the free-key line
|
|
124
124
|
`badge` (the **System Duo** pill), `summary` and `links`. Span answers add `excerpts`, each `excerpt`, every marked
|
|
125
125
|
`span` (with `data-system-one-span-label` and `data-system-one-probability`) and, in a Privacy card, the `labels`. Each
|
|
126
126
|
number is a `data-system-one-fact`: `kind`, `effort`, `unclear` and `risky` (triage), `risk`, `leaks` and `on-task`
|
|
@@ -137,7 +137,8 @@ number is a `data-system-one-fact`: `kind`, `effort`, `unclear` and `risky` (tri
|
|
|
137
137
|
| A routine check (one line) | `[data-system-one="compact"][data-system-one-reflex="guard"]`, and `"shield"` |
|
|
138
138
|
| Done-check | `[data-system-one-reflex="done"]` |
|
|
139
139
|
| Batch row, finished | `[data-system-one="tool"][data-system-one-verdict="done"]` |
|
|
140
|
-
| The
|
|
140
|
+
| The blue badge, and its latency | `[data-system-one-part="badge"]`, `[data-system-one-part="latency"]` |
|
|
141
|
+
| System One still deciding | `[data-system-one-verdict="deciding"]`, and its `[data-system-one-part="progress"]` |
|
|
141
142
|
| "Dangerous", and "You rejected it" | `[data-system-one-fact="risk"]`, `[data-system-one-part="outcome"]` |
|
|
142
143
|
| The reason | `[data-system-one-part="note"]` |
|
|
143
144
|
| The model's name (bold) | `[data-system-one-part="model"]` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vllm-sr/dsh",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "System Duo for DeepSeek Harness. Thinking, fast and slow: System One decision models guard, shield, triage and check your agent around System Two (vllm-sr/auto), with a free app.vllm-sr.ai key.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
package/src/index.js
CHANGED
|
@@ -89,6 +89,8 @@ export const Config = z.object({
|
|
|
89
89
|
const SOURCE = { kind: 'system-one' }
|
|
90
90
|
// how long a step waits for the free keys of the first run before it goes on without them
|
|
91
91
|
const KEYS_WAIT_MS = 20000
|
|
92
|
+
// a decision that takes longer than this shows in Chat as deciding until its answer takes its place
|
|
93
|
+
export const DECIDING_MS = 700
|
|
92
94
|
|
|
93
95
|
const PROMPT = `# System One
|
|
94
96
|
You are System Two: you plan, reason and act. Beside you runs System One, a fast decision model that answers typed questions with calibrated probabilities in a fraction of a second. It watches the loop:
|
|
@@ -175,6 +177,33 @@ export function apply(ctx, config) {
|
|
|
175
177
|
})
|
|
176
178
|
const sessions = new Map()
|
|
177
179
|
|
|
180
|
+
// One decision's record. It is written once the answer is there, unless the answer takes longer than DECIDING_MS:
|
|
181
|
+
// then a deciding record goes first, and the answer, which carries the same decision id, takes its place in Chat.
|
|
182
|
+
let decisions = 0
|
|
183
|
+
function deciding(session, data) {
|
|
184
|
+
const decision = `${Date.now().toString(36)}.${(decisions++).toString(36)}`
|
|
185
|
+
let shown = false
|
|
186
|
+
const timer = setTimeout(() => {
|
|
187
|
+
shown = record(session, { ...data, decision, pending: true })
|
|
188
|
+
}, DECIDING_MS)
|
|
189
|
+
timer.unref?.()
|
|
190
|
+
return {
|
|
191
|
+
// the answer is in, and its record waits for the rest of the step
|
|
192
|
+
hold() {
|
|
193
|
+
clearTimeout(timer)
|
|
194
|
+
},
|
|
195
|
+
answer(final) {
|
|
196
|
+
clearTimeout(timer)
|
|
197
|
+
return record(session, { ...data, decision, ...final })
|
|
198
|
+
},
|
|
199
|
+
// no answer: a record that said deciding now says the turn stopped first
|
|
200
|
+
drop() {
|
|
201
|
+
clearTimeout(timer)
|
|
202
|
+
if (shown) record(session, { ...data, decision, verdict: 'cancelled' })
|
|
203
|
+
},
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
178
207
|
// Whether spanModel answers span questions: `auto` asks the published models list, again every ten minutes.
|
|
179
208
|
let spanCheck
|
|
180
209
|
function spansOn() {
|
|
@@ -375,15 +404,16 @@ export function apply(ctx, config) {
|
|
|
375
404
|
`The agent now wants to run:\n${describeCall(exec)}`,
|
|
376
405
|
].join('\n\n')
|
|
377
406
|
const base = { reflex: 'guard', turn: state?.turn, step: state?.step, callId: exec.callId, tool: exec.name, call: subject(relativeTo(briefCall(exec), workspace, homedir())) }
|
|
407
|
+
const decision = deciding(exec.agent.session, base)
|
|
378
408
|
let response
|
|
379
409
|
try {
|
|
380
410
|
response = await client.ask({ model: config.model, questions: GUARD, inputs: [{ state: situation }], signal: exec.signal, timeoutMs: config.hookTimeoutMs, retries: config.hookRetries })
|
|
381
411
|
} catch (error) {
|
|
382
412
|
trace({ ev: 's1', reflex: 'guard', session: state?.id, tool: exec.name, call: briefCall(exec), error: String(error?.message ?? error) })
|
|
383
413
|
if (!exec.signal?.aborted) {
|
|
384
|
-
|
|
414
|
+
decision.answer({ verdict: config.guardOnError, error: subject(error?.message ?? error) })
|
|
385
415
|
if (config.guardOnError === 'ask') state?.asked.set(exec.callId, base)
|
|
386
|
-
}
|
|
416
|
+
} else decision.drop()
|
|
387
417
|
if (config.guardOnError === 'deny') return { kind: 'deny', reason: `System One is unavailable (${error?.message ?? error}); the call was not run.` }
|
|
388
418
|
if (config.guardOnError === 'ask') return { kind: 'ask', reason: 'System One is unavailable', displayReason: { en: 'System One is unavailable: allow this call?' } }
|
|
389
419
|
return next()
|
|
@@ -425,8 +455,8 @@ export function apply(ctx, config) {
|
|
|
425
455
|
ev: 's1', reflex: 'guard', session: state?.id, turn: state?.turn, tool: exec.name, call: briefCall(exec), model: response.model,
|
|
426
456
|
ms: ms(response.ms), verdict, why, answers: answersOf(answers), ...(danger ? { spanModel: danger.model, danger: danger.spans } : {}),
|
|
427
457
|
})
|
|
428
|
-
|
|
429
|
-
|
|
458
|
+
decision.answer({
|
|
459
|
+
model: response.model, ms: ms(response.ms), requestId: response.requestId, answers: answersOf(answers), verdict, why,
|
|
430
460
|
...(danger ? { spanModel: danger.model, spanMs: ms(danger.ms), danger: danger.spans } : {}),
|
|
431
461
|
})
|
|
432
462
|
if (verdict === 'ask') state?.asked.set(exec.callId, base)
|
|
@@ -476,7 +506,9 @@ export function apply(ctx, config) {
|
|
|
476
506
|
|
|
477
507
|
let verdict
|
|
478
508
|
let elapsed
|
|
509
|
+
let shielding
|
|
479
510
|
if (screens && full.length >= config.shieldMinChars) {
|
|
511
|
+
shielding = deciding(exec.agent.session, { reflex: 'shield', ...target })
|
|
480
512
|
const started = performance.now()
|
|
481
513
|
try {
|
|
482
514
|
verdict = await screen({
|
|
@@ -486,9 +518,11 @@ export function apply(ctx, config) {
|
|
|
486
518
|
})
|
|
487
519
|
} catch (error) {
|
|
488
520
|
trace({ ev: 's1', reflex: 'shield', session: state?.id, tool: exec.name, call: briefCall(exec), error: String(error?.message ?? error) })
|
|
489
|
-
if (!exec.signal?.aborted)
|
|
521
|
+
if (!exec.signal?.aborted) shielding.answer({ error: subject(error?.message ?? error) })
|
|
522
|
+
else shielding.drop()
|
|
490
523
|
}
|
|
491
524
|
elapsed = performance.now() - started
|
|
525
|
+
shielding.hold()
|
|
492
526
|
}
|
|
493
527
|
if (verdict) {
|
|
494
528
|
trace({
|
|
@@ -498,14 +532,20 @@ export function apply(ctx, config) {
|
|
|
498
532
|
flagged: verdict.flagged.map(entry => ({ p: round3(entry.p), text: clip(entry.text, 400), lines: entry.lines.map(line => ({ p: round3(line.p), text: line.text })), spans: entry.spans })),
|
|
499
533
|
})
|
|
500
534
|
}
|
|
501
|
-
|
|
535
|
+
let downstream
|
|
536
|
+
try {
|
|
537
|
+
downstream = await next()
|
|
538
|
+
} catch (error) {
|
|
539
|
+
shielding?.drop()
|
|
540
|
+
throw error
|
|
541
|
+
}
|
|
502
542
|
const removed = verdict && (verdict.removedLines > 0 || verdict.removedSpans > 0)
|
|
503
543
|
if (verdict) {
|
|
504
544
|
// A later handler that blocks the result keeps the whole passage from the model, so the injection was found, not removed.
|
|
505
545
|
const outcome = !removed ? 'clean' : downstream.kind === 'block' ? 'flagged' : 'removed'
|
|
506
546
|
const shown = verdict.flagged.flatMap(entry => entry.excerpts).slice(0, 2)
|
|
507
|
-
|
|
508
|
-
|
|
547
|
+
shielding.answer({
|
|
548
|
+
model: verdict.model, ms: ms(elapsed), passages: verdict.passages, flagged: verdict.flagged.length,
|
|
509
549
|
removedLines: verdict.removedLines, maxP: round3(verdict.maxP), verdict: outcome,
|
|
510
550
|
...(verdict.spanModel ? { spanModel: verdict.spanModel, spanMs: ms(verdict.spanMs) } : {}),
|
|
511
551
|
...(verdict.removedSpans ? { removedSpans: verdict.removedSpans, removedChars: verdict.removedChars, excerpts: shown } : {}),
|
|
@@ -521,7 +561,9 @@ export function apply(ctx, config) {
|
|
|
521
561
|
state.privacyOff = true
|
|
522
562
|
record(exec.agent.session, { reflex: 'privacy', ...target, verdict: 'error', error: `${config.spanModel} answers no span questions yet` })
|
|
523
563
|
}
|
|
564
|
+
let masking
|
|
524
565
|
if (masks && spans) {
|
|
566
|
+
masking = deciding(exec.agent.session, { reflex: 'privacy', ...target })
|
|
525
567
|
const started = performance.now()
|
|
526
568
|
try {
|
|
527
569
|
const parts = windows(body, 12000)
|
|
@@ -538,19 +580,17 @@ export function apply(ctx, config) {
|
|
|
538
580
|
privacy = { model, ms: performance.now() - started, spans: found }
|
|
539
581
|
} catch (error) {
|
|
540
582
|
trace({ ev: 's1', reflex: 'privacy', session: state?.id, tool: exec.name, call: briefCall(exec), error: String(error?.message ?? error) })
|
|
541
|
-
if (!exec.signal?.aborted)
|
|
583
|
+
if (!exec.signal?.aborted) masking.answer({ verdict: 'error', error: subject(error?.message ?? error) })
|
|
584
|
+
else masking.drop()
|
|
542
585
|
}
|
|
543
586
|
}
|
|
544
587
|
const hidden = privacy?.spans.length ? privacy.spans : []
|
|
545
588
|
if (privacy) {
|
|
546
589
|
const labels = labelCounts(hidden)
|
|
547
590
|
trace({ ev: 's1', reflex: 'privacy', session: state?.id, turn: state?.turn, tool: exec.name, call: briefCall(exec), model: privacy.model, ms: ms(privacy.ms), masked: hidden.length, labels })
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
excerpts: excerpts(body, hidden, { hide: true, around: 40, max: 3 }),
|
|
552
|
-
})
|
|
553
|
-
}
|
|
591
|
+
masking.answer(hidden.length
|
|
592
|
+
? { model: privacy.model, ms: ms(privacy.ms), verdict: 'masked', masked: hidden.length, labels, excerpts: excerpts(body, hidden, { hide: true, around: 40, max: 3 }) }
|
|
593
|
+
: { model: privacy.model, ms: ms(privacy.ms), verdict: 'clean', masked: 0 })
|
|
554
594
|
}
|
|
555
595
|
if (!removed && hidden.length === 0) return downstream
|
|
556
596
|
|
|
@@ -593,6 +633,7 @@ export function apply(ctx, config) {
|
|
|
593
633
|
const reads = state.reads ?? []
|
|
594
634
|
// a plain cut: clip's "(+N chars)" would read as a claim of the answer
|
|
595
635
|
const answered = (state.assistant || '').slice(0, 8000)
|
|
636
|
+
const decision = deciding(agent.session, { reflex: 'done', turn, step: state.step })
|
|
596
637
|
let haluTask
|
|
597
638
|
if (config.doneHalu && reads.length > 0 && answered && (await spansOn())) {
|
|
598
639
|
const evidence = []
|
|
@@ -617,7 +658,8 @@ export function apply(ctx, config) {
|
|
|
617
658
|
response = await client.ask({ model: config.model, questions: DONE, inputs: [{ state: situation }], signal, timeoutMs: config.hookTimeoutMs, retries: config.hookRetries })
|
|
618
659
|
} catch (error) {
|
|
619
660
|
trace({ ev: 's1', reflex: 'done', session: state.id, turn, error: String(error?.message ?? error) })
|
|
620
|
-
if (!signal?.aborted)
|
|
661
|
+
if (!signal?.aborted) decision.answer({ error: subject(error?.message ?? error) })
|
|
662
|
+
else decision.drop()
|
|
621
663
|
return
|
|
622
664
|
}
|
|
623
665
|
const answers = response.answers[0]
|
|
@@ -635,8 +677,8 @@ export function apply(ctx, config) {
|
|
|
635
677
|
ev: 's1', reflex: 'done', session: state.id, turn, model: response.model, ms: ms(response.ms), verdict: steer ? 'continue' : 'stop',
|
|
636
678
|
answers: answersOf(answers), calls: state.calls.length, ...(halu ? { spanModel: halu.model, halu: unsupported.map(span => ({ text: clip(span.text, 200), p: round3(span.probability) })) } : {}),
|
|
637
679
|
})
|
|
638
|
-
|
|
639
|
-
|
|
680
|
+
decision.answer({
|
|
681
|
+
model: response.model, ms: ms(response.ms), requestId: response.requestId, answers: answersOf(answers),
|
|
640
682
|
verdict: steer ? 'continue' : 'stop', why,
|
|
641
683
|
steers: state.steers + (steer ? 1 : 0), maxSteers: config.doneMaxSteers, calls: state.calls.length,
|
|
642
684
|
...(halu ? { spanModel: halu.model, spanMs: ms(halu.ms), unsupported: unsupported.length, excerpts: excerpts(answered, unsupported, { around: 50, max: 3 }) } : {}),
|
package/web/client.js
CHANGED
|
@@ -34,8 +34,9 @@ window.__ModuleLoader__.load({
|
|
|
34
34
|
const KINDS = { code: 'Code', data: 'Data', research: 'Research', writing: 'Writing', ops: 'Ops', chat: 'Chat' }
|
|
35
35
|
const EFFORT = ['Trivial', 'Small', 'Medium', 'Large']
|
|
36
36
|
const RISK = ['Safe', 'Normal', 'Dangerous', 'Critical']
|
|
37
|
-
|
|
38
|
-
const
|
|
37
|
+
// the vLLM logo's blue (#30A2FF) leads; its gold and cool neighbours tell the other options apart
|
|
38
|
+
const HUES = ['#30A2FF', '#1559B5', '#7CCBFF', '#6E7CF5', '#FDB515', '#2BB3A3', '#A9C6FF', '#0B3A75']
|
|
39
|
+
const RAMP = ['#C5E5FF', '#97D0FF', '#63B8FF', '#30A2FF', '#1E85E3', '#1667C4', '#0F4C94']
|
|
39
40
|
const SEVERITY = { muted: 0, ok: 1, info: 2, warn: 3, bad: 4 }
|
|
40
41
|
|
|
41
42
|
const GUARD = {
|
|
@@ -90,6 +91,8 @@ window.__ModuleLoader__.load({
|
|
|
90
91
|
const step = Number.isSafeInteger(data.step) ? data.step : undefined
|
|
91
92
|
if (data.reflex === 'triage' && turn !== undefined) return `t${turn}:triage`
|
|
92
93
|
if (['guard', 'shield', 'privacy'].includes(data.reflex) && turn !== undefined && step !== undefined) return `t${turn}:s${step}:${data.reflex}`
|
|
94
|
+
// a done-check that was still deciding and its answer share one element
|
|
95
|
+
if (data.reflex === 'done' && typeof data.decision === 'string') return `d:${data.decision}`
|
|
93
96
|
return `r${seq}`
|
|
94
97
|
}
|
|
95
98
|
|
|
@@ -106,12 +109,25 @@ window.__ModuleLoader__.load({
|
|
|
106
109
|
return { ...base, rows }
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
|
-
|
|
112
|
+
const row = { ...data, seq: event.seq, time: event.time }
|
|
113
|
+
// a decision's answer takes the place of the row that showed it deciding
|
|
114
|
+
if (typeof data.decision === 'string') {
|
|
115
|
+
const at = base.rows.findIndex(other => other.decision === data.decision)
|
|
116
|
+
if (at >= 0) {
|
|
117
|
+
const rows = base.rows.slice()
|
|
118
|
+
rows[at] = row
|
|
119
|
+
return { ...base, rows }
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return { ...base, rows: [...base.rows, row] }
|
|
110
123
|
}
|
|
111
124
|
|
|
112
125
|
// Triage and done-check frame the turn and stay visible when it folds; so does a guard or shield card that
|
|
113
126
|
// stopped something. A routine one sits with the work it checked and folds with it.
|
|
114
127
|
function standsOut(state) {
|
|
128
|
+
// a decision still deciding, or stopped, is one line until its answer comes
|
|
129
|
+
if (state.rows.every(row => row.pending || row.verdict === 'cancelled')) return false
|
|
130
|
+
if (state.reflex === 'privacy') return state.rows.some(row => row.verdict === 'masked' || row.error)
|
|
115
131
|
if (state.reflex !== 'guard' && state.reflex !== 'shield') return true
|
|
116
132
|
return state.rows.some(row => SEVERITY[viewOf(state.reflex, row).tone] >= SEVERITY.warn)
|
|
117
133
|
}
|
|
@@ -228,6 +244,9 @@ window.__ModuleLoader__.load({
|
|
|
228
244
|
|
|
229
245
|
function privacyView(row) {
|
|
230
246
|
if (row.error) return errorView(row, { text: 'so the result went to System Two unmasked', tone: 'warn' })
|
|
247
|
+
if (row.verdict === 'clean') {
|
|
248
|
+
return { verdict: 'clean', label: 'Nothing to mask', short: 'nothing to mask', tone: 'ok', subject: row.call ? { tool: row.tool, text: row.call } : undefined, facts: [{ id: 'masked', label: 'Masked', value: '0' }] }
|
|
249
|
+
}
|
|
231
250
|
const masked = num(row.masked) ?? 0
|
|
232
251
|
const labels = row.labels && typeof row.labels === 'object' ? Object.entries(row.labels).filter(([, n]) => num(n)) : []
|
|
233
252
|
return {
|
|
@@ -265,7 +284,18 @@ window.__ModuleLoader__.load({
|
|
|
265
284
|
}
|
|
266
285
|
}
|
|
267
286
|
|
|
287
|
+
// what a decision that has no answer yet says, and one whose turn stopped before it was answered
|
|
288
|
+
const WAITING = {
|
|
289
|
+
guard: 'reviewing the call', shield: 'screening the result', privacy: 'looking for personal data', done: 'checking the work', triage: 'reading the request',
|
|
290
|
+
}
|
|
291
|
+
function waitingView(reflex, row) {
|
|
292
|
+
const subject = row.call ? { tool: row.tool, text: row.call } : undefined
|
|
293
|
+
if (row.pending) return { verdict: 'deciding', label: 'Deciding', short: 'deciding', tone: 'info', pending: true, detail: WAITING[reflex] ?? 'thinking', subject, facts: [] }
|
|
294
|
+
return { verdict: 'cancelled', label: 'Stopped', short: 'stopped', tone: 'muted', detail: 'the turn stopped before System One answered', subject, facts: [] }
|
|
295
|
+
}
|
|
296
|
+
|
|
268
297
|
function viewOf(reflex, row) {
|
|
298
|
+
if (row.pending || row.verdict === 'cancelled') return waitingView(reflex, row)
|
|
269
299
|
switch (reflex) {
|
|
270
300
|
case 'triage': return triageView(row)
|
|
271
301
|
case 'guard': return guardView(row)
|
|
@@ -300,6 +330,7 @@ window.__ModuleLoader__.load({
|
|
|
300
330
|
function compactLine(view) {
|
|
301
331
|
const label = view.outcome ? `${view.label} → ${view.outcome.label}` : view.label
|
|
302
332
|
const rest = []
|
|
333
|
+
if (view.detail) rest.push(view.detail)
|
|
303
334
|
if (view.subject?.text) rest.push(`${view.subject.tool ?? ''} ${view.subject.text}`.trim())
|
|
304
335
|
const lead = view.facts.find(fact => ['risk', 'injection', 'complete', 'effort', 'masked'].includes(fact.id))
|
|
305
336
|
if (lead) rest.push(`${lead.label.toLowerCase()} ${lead.value}`)
|
|
@@ -395,10 +426,11 @@ window.__ModuleLoader__.load({
|
|
|
395
426
|
h('b', null, value))
|
|
396
427
|
}
|
|
397
428
|
|
|
398
|
-
function Row({ row, view, single }) {
|
|
429
|
+
function Row({ row, view, single, index = 0 }) {
|
|
399
430
|
const fresh = useFresh(`row:${idOf(row)}`, row.time)
|
|
400
431
|
return h('div', {
|
|
401
432
|
className: cx('vsr-s1__row', fresh && 'vsr-s1__row--fresh'),
|
|
433
|
+
style: fresh ? { '--vsr-s1-i': Math.min(index, 6) } : undefined,
|
|
402
434
|
'data-system-one-decision': view.verdict,
|
|
403
435
|
'data-system-one-outcome': view.outcomeKey,
|
|
404
436
|
'data-system-one-call': row.callId,
|
|
@@ -424,7 +456,7 @@ window.__ModuleLoader__.load({
|
|
|
424
456
|
const hidden = all ? 0 : Math.max(0, rows.length - ROWS_SHOWN)
|
|
425
457
|
return h('div', { className: 'vsr-s1__rows', 'data-system-one-part': 'rows' },
|
|
426
458
|
hidden > 0 ? h('button', { type: 'button', className: 'vsr-s1__more', 'data-system-one-part': 'more', onClick: () => setAll(true) }, `Show ${plural(hidden, `earlier ${reflex === 'guard' ? 'call' : 'result'}`)}`) : null,
|
|
427
|
-
rows.slice(hidden).map((row, index) => h(Row, { key: idOf(row), row, view: views[hidden + index], single: rows.length === 1 })))
|
|
459
|
+
rows.slice(hidden).map((row, index) => h(Row, { key: idOf(row), row, view: views[hidden + index], single: rows.length === 1, index })))
|
|
428
460
|
}
|
|
429
461
|
|
|
430
462
|
const whole = value => (Number.isSafeInteger(value) ? String(value) : undefined)
|
|
@@ -489,20 +521,23 @@ window.__ModuleLoader__.load({
|
|
|
489
521
|
const reflex = REFLEX[state.reflex] ?? state.reflex
|
|
490
522
|
const line = views.length === 1 ? compactLine(views[0]) : { label: headlineOf(state.reflex, views), tone: undefined, rest: '' }
|
|
491
523
|
const said = line.rest ? `${line.label} · ${line.rest}` : line.label
|
|
524
|
+
const deciding = views.some(view => view.pending)
|
|
492
525
|
return h('div', {
|
|
493
|
-
className: cx('vsr-s1', 'vsr-s1--compact', `vsr-s1--${worst.tone}`, open && 'vsr-s1--open', fresh && 'vsr-s1--fresh'),
|
|
526
|
+
className: cx('vsr-s1', 'vsr-s1--compact', `vsr-s1--${worst.tone}`, open && 'vsr-s1--open', fresh && 'vsr-s1--fresh', deciding && 'vsr-s1--deciding'),
|
|
494
527
|
role: 'group',
|
|
495
528
|
'aria-label': `System One ${reflex}: ${said}`,
|
|
496
|
-
|
|
529
|
+
'aria-busy': deciding || undefined,
|
|
530
|
+
...attributes('compact', state, deciding ? views.find(view => view.pending) : worst),
|
|
497
531
|
},
|
|
498
532
|
h('button', { type: 'button', className: 'vsr-s1__chip', 'data-system-one-part': 'toggle', 'aria-expanded': open, onClick: () => setOpen(!open) },
|
|
499
|
-
h(Badge, { key: idOf(last), id: idOf(last), ms: last.ms, time: last.time }),
|
|
533
|
+
h(Badge, { key: idOf(last), id: idOf(last), ms: deciding ? undefined : last.ms, time: last.time }),
|
|
500
534
|
h('span', { className: 'vsr-s1__reflex', 'data-system-one-part': 'reflex' }, reflex),
|
|
501
|
-
h('span', { className: 'vsr-s1__summary', 'data-system-one-part': 'summary', title: said },
|
|
535
|
+
h('span', { className: cx('vsr-s1__summary', deciding && 'vsr-s1__shimmer'), 'data-system-one-part': 'summary', title: said },
|
|
502
536
|
h('span', { className: cx('vsr-s1__verdict', line.tone && `vsr-s1__verdict--${line.tone}`), 'data-system-one-part': 'verdict' }, line.label),
|
|
503
537
|
line.rest ? ` · ${line.rest}` : null),
|
|
504
|
-
open ? h(Model, { model: last.model, also: state.rows.find(row => row.spanModel)?.spanModel }) : null,
|
|
538
|
+
open && !deciding ? h(Model, { model: last.model, also: state.rows.find(row => row.spanModel)?.spanModel }) : null,
|
|
505
539
|
h(Chevron)),
|
|
540
|
+
deciding ? h('span', { className: 'vsr-s1__progress', 'data-system-one-part': 'progress', 'aria-hidden': true }) : null,
|
|
506
541
|
open ? h(Rows, { reflex: state.reflex, rows: state.rows, views }) : null)
|
|
507
542
|
}
|
|
508
543
|
|
|
@@ -603,7 +638,7 @@ window.__ModuleLoader__.load({
|
|
|
603
638
|
}
|
|
604
639
|
}
|
|
605
640
|
if (summary?.type === 'noul') {
|
|
606
|
-
return { parts: [{ label: 'yes', n: summary.yes ?? 0, color: '#
|
|
641
|
+
return { parts: [{ label: 'yes', n: summary.yes ?? 0, color: '#30A2FF' }, { label: 'no', n: summary.no ?? 0, color: 'var(--vsr-s1-track)' }] }
|
|
607
642
|
}
|
|
608
643
|
if (summary?.type === 'score') {
|
|
609
644
|
const levels = Object.entries(summary.levels ?? {})
|
|
@@ -649,11 +684,12 @@ window.__ModuleLoader__.load({
|
|
|
649
684
|
|
|
650
685
|
if (phase !== 'result') {
|
|
651
686
|
const line = phase === 'preparing' ? 'Preparing a batch' : `Answering ${plural(asked, 'question')}${source ? ` over ${source}` : ''}`
|
|
652
|
-
return h('div', { className: 'vsr-s1 vsr-s1--compact vsr-s1--running', 'data-system-one': 'tool', ...common, 'data-system-one-verdict': 'running', 'data-system-one-tone': 'info' },
|
|
687
|
+
return h('div', { className: 'vsr-s1 vsr-s1--compact vsr-s1--running vsr-s1--deciding', 'aria-busy': true, 'data-system-one': 'tool', ...common, 'data-system-one-verdict': 'running', 'data-system-one-tone': 'info' },
|
|
653
688
|
h('div', { className: 'vsr-s1__chip vsr-s1__chip--static' },
|
|
654
689
|
h(Badge, { id: `${callId}:running`, time: Date.now() }),
|
|
655
690
|
h('span', { className: 'vsr-s1__reflex', 'data-system-one-part': 'reflex' }, REFLEX.tool),
|
|
656
|
-
h('span', { className: 'vsr-s1__summary vsr-s1__shimmer', 'data-system-one-part': 'summary' }, line))
|
|
691
|
+
h('span', { className: 'vsr-s1__summary vsr-s1__shimmer', 'data-system-one-part': 'summary' }, line)),
|
|
692
|
+
h('span', { className: 'vsr-s1__progress', 'data-system-one-part': 'progress', 'aria-hidden': true }))
|
|
657
693
|
}
|
|
658
694
|
|
|
659
695
|
if (block?.isError || !meta || ui === 'off') {
|
|
@@ -706,31 +742,33 @@ window.__ModuleLoader__.load({
|
|
|
706
742
|
return h(Contained, null, h(ToolRow, props))
|
|
707
743
|
}
|
|
708
744
|
|
|
709
|
-
// ---- styles: the Web UI's theme tokens, with
|
|
745
|
+
// ---- styles: the Web UI's theme tokens, with the blue of the vLLM logo (#30A2FF) for System One ----
|
|
710
746
|
|
|
711
747
|
const CSS = `
|
|
712
|
-
.vsr-s1{--vsr-s1-
|
|
748
|
+
.vsr-s1{--vsr-s1-blue:#30A2FF;--vsr-s1-blue-soft:#7CC4FF;--vsr-s1-blue-deep:#1E7FE0;--vsr-s1-ink:#166BC9;--vsr-s1-badge-a:#2290F0;--vsr-s1-badge-b:#135CB8;--vsr-s1-tint:6%;--vsr-s1-tint-2:1.5%;--vsr-s1-edge:24%;--vsr-s1-lift:rgba(16,42,84,.05);--vsr-s1-ok:var(--dsw-alias-state-success-primary,#1F9D5B);--vsr-s1-warn:var(--dsw-alias-state-warn-primary,#E8A100);--vsr-s1-bad:var(--dsw-alias-state-error-primary,#E5484D);--vsr-s1-text:var(--dsw-alias-label-primary,#1F2329);--vsr-s1-text-2:var(--dsw-alias-label-secondary,#545961);--vsr-s1-text-3:var(--dsw-alias-label-tertiary,#8A8F98);--vsr-s1-line:var(--dsw-alias-border-l2,rgba(127,127,127,.22));--vsr-s1-track:color-mix(in srgb,var(--vsr-s1-text-3) 26%,transparent);--vsr-s1-mono:ui-monospace,SFMono-Regular,"JetBrains Mono",Menlo,Consolas,monospace;--vsr-s1-ease:cubic-bezier(.22,1,.36,1);position:relative;box-sizing:border-box;width:100%;margin:6px 0;color:var(--vsr-s1-text);font-size:13.5px;line-height:1.45;text-align:left}
|
|
749
|
+
body[data-ds-dark-theme] .vsr-s1{--vsr-s1-blue-soft:#4DB0FF;--vsr-s1-ink:#6BBEFF;--vsr-s1-badge-a:#2A98F5;--vsr-s1-badge-b:#1667C9;--vsr-s1-tint:9%;--vsr-s1-tint-2:3%;--vsr-s1-edge:32%;--vsr-s1-lift:rgba(0,0,0,.28)}
|
|
713
750
|
.vsr-s1 *{box-sizing:border-box}
|
|
714
|
-
.vsr-s1--card{padding:11px 14px 12px 17px;border:1px solid color-mix(in srgb,var(--vsr-s1-
|
|
715
|
-
.vsr-s1--card.vsr-s1--bad{
|
|
716
|
-
.vsr-s1--card.vsr-s1--warn{
|
|
751
|
+
.vsr-s1--card{--vsr-s1-tone:var(--vsr-s1-blue);padding:11px 14px 12px 17px;border:1px solid color-mix(in srgb,var(--vsr-s1-tone) var(--vsr-s1-edge),var(--vsr-s1-line));border-radius:12px;background:linear-gradient(180deg,color-mix(in srgb,var(--vsr-s1-tone) var(--vsr-s1-tint),transparent),color-mix(in srgb,var(--vsr-s1-tone) var(--vsr-s1-tint-2),transparent));box-shadow:0 1px 2px var(--vsr-s1-lift),0 10px 24px -16px color-mix(in srgb,var(--vsr-s1-tone) 55%,transparent)}
|
|
752
|
+
.vsr-s1--card.vsr-s1--bad{--vsr-s1-tone:var(--vsr-s1-bad);--vsr-s1-edge:44%}
|
|
753
|
+
.vsr-s1--card.vsr-s1--warn{--vsr-s1-tone:var(--vsr-s1-warn);--vsr-s1-edge:46%}
|
|
717
754
|
.vsr-s1__sheen{position:absolute;inset:0;border-radius:inherit;overflow:hidden;pointer-events:none}
|
|
718
|
-
.vsr-s1__sheen::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--vsr-s1-
|
|
755
|
+
.vsr-s1__sheen::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--vsr-s1-blue-soft),var(--vsr-s1-blue) 45%,var(--vsr-s1-blue-deep));transform-origin:top center}
|
|
719
756
|
.vsr-s1--bad>.vsr-s1__sheen::before{background:var(--vsr-s1-bad)}
|
|
720
757
|
.vsr-s1--warn>.vsr-s1__sheen::before{background:var(--vsr-s1-warn)}
|
|
721
758
|
.vsr-s1__head{position:relative;display:flex;align-items:center;gap:9px;min-width:0}
|
|
722
|
-
.vsr-s1__badge{position:relative;display:inline-flex;flex:none;align-items:center;gap:6px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;letter-spacing:-.005em;white-space:nowrap;background:linear-gradient(
|
|
723
|
-
.vsr-s1__dot{flex:none;width:6px;height:6px;border-radius:50%;background:#fff;box-shadow:0 0
|
|
724
|
-
.vsr-s1__ms{padding-left:7px;border-left:1px solid rgba(255,255,255,.
|
|
759
|
+
.vsr-s1__badge{position:relative;display:inline-flex;flex:none;align-items:center;gap:6px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;letter-spacing:-.005em;white-space:nowrap;background:linear-gradient(135deg,var(--vsr-s1-badge-a),var(--vsr-s1-badge-b));box-shadow:0 1px 2px color-mix(in srgb,var(--vsr-s1-badge-b) 35%,transparent),inset 0 1px 0 rgba(255,255,255,.26),inset 0 0 0 .5px rgba(255,255,255,.14)}
|
|
760
|
+
.vsr-s1__dot{flex:none;width:6px;height:6px;border-radius:50%;background:#fff;box-shadow:0 0 0 2px rgba(255,255,255,.2)}
|
|
761
|
+
.vsr-s1__ms{padding-left:7px;border-left:1px solid rgba(255,255,255,.42);font-weight:750;font-variant-numeric:tabular-nums}
|
|
725
762
|
.vsr-s1__reflex{flex:none;font-weight:650;color:var(--vsr-s1-text);white-space:nowrap}
|
|
726
763
|
.vsr-s1__summary{flex:1;min-width:0;overflow:hidden;color:var(--vsr-s1-text-2);white-space:nowrap;text-overflow:ellipsis}
|
|
727
764
|
.vsr-s1__summary--bad{color:var(--vsr-s1-bad)}
|
|
728
765
|
.vsr-s1__verdict{font-weight:600;color:var(--vsr-s1-text)}
|
|
729
|
-
.vsr-s1__verdict--ok{color:var(--vsr-s1-ok)}.vsr-s1__verdict--warn{color:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__verdict--bad{color:var(--vsr-s1-bad)}.vsr-s1__verdict--info{color:var(--vsr-s1-
|
|
766
|
+
.vsr-s1__verdict--ok{color:var(--vsr-s1-ok)}.vsr-s1__verdict--warn{color:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__verdict--bad{color:var(--vsr-s1-bad)}.vsr-s1__verdict--info{color:var(--vsr-s1-ink)}.vsr-s1__verdict--muted{color:var(--vsr-s1-text-3)}
|
|
730
767
|
.vsr-s1__model{flex:none;color:var(--vsr-s1-text-2);font-size:12px;font-weight:700;letter-spacing:-.005em;white-space:nowrap}
|
|
731
768
|
.vsr-s1--notice{display:flex;align-items:center;gap:9px;min-width:0;margin:4px 0;padding:3px 0}
|
|
732
769
|
.vsr-s1--notice .vsr-s1__summary{white-space:normal}
|
|
733
|
-
.vsr-s1__duo{position:relative;display:inline-flex;flex:none;align-items:center;gap:5px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;white-space:nowrap;background:linear-gradient(110deg,var(--vsr-s1-
|
|
770
|
+
.vsr-s1__duo{position:relative;display:inline-flex;flex:none;align-items:center;gap:5px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;white-space:nowrap;background:linear-gradient(110deg,var(--vsr-s1-badge-b) 0%,var(--vsr-s1-badge-a) 55%,var(--vsr-s1-blue) 100%);box-shadow:0 1px 2px color-mix(in srgb,var(--vsr-s1-badge-b) 35%,transparent),inset 0 1px 0 rgba(255,255,255,.26)}
|
|
771
|
+
.vsr-s1__duo .vsr-s1__glyph{color:#FFD56B}
|
|
734
772
|
.vsr-s1__glyph{flex:none}
|
|
735
773
|
.vsr-s1__links{display:inline-flex;flex:none;gap:10px}
|
|
736
774
|
a.vsr-s1__link{text-decoration:none}
|
|
@@ -738,10 +776,10 @@ a.vsr-s1__link{text-decoration:none}
|
|
|
738
776
|
.vsr-s1__rows>*{grid-column:1/-1}
|
|
739
777
|
.vsr-s1__row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-columns:subgrid;column-gap:12px;align-items:start}
|
|
740
778
|
.vsr-s1__verdicts{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-width:92px}
|
|
741
|
-
.vsr-s1__pill{--tone:var(--vsr-s1-text-3);display:inline-flex;align-items:center;gap:6px;padding:1px 8px 1px 7px;border-radius:6px;color:var(--tone);background:color-mix(in srgb,var(--tone)
|
|
779
|
+
.vsr-s1__pill{--tone:var(--vsr-s1-text-3);display:inline-flex;align-items:center;gap:6px;padding:1px 8px 1px 7px;border-radius:6px;color:var(--tone);background:color-mix(in srgb,var(--tone) 12%,transparent);box-shadow:inset 0 0 0 .5px color-mix(in srgb,var(--tone) 22%,transparent);font-size:12px;font-weight:650;line-height:20px;white-space:nowrap}
|
|
742
780
|
.vsr-s1__pill::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:currentColor}
|
|
743
781
|
.vsr-s1__pill--then::before{width:auto;height:auto;border-radius:0;background:none;content:"\\21B3"}
|
|
744
|
-
.vsr-s1__pill--ok{--tone:var(--vsr-s1-ok)}.vsr-s1__pill--warn{--tone:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__pill--bad{--tone:var(--vsr-s1-bad)}.vsr-s1__pill--info{--tone:var(--vsr-s1-
|
|
782
|
+
.vsr-s1__pill--ok{--tone:var(--vsr-s1-ok)}.vsr-s1__pill--warn{--tone:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__pill--bad{--tone:var(--vsr-s1-bad)}.vsr-s1__pill--info{--tone:var(--vsr-s1-ink)}.vsr-s1__pill--muted{--tone:var(--vsr-s1-text-3)}
|
|
745
783
|
.vsr-s1__main{display:grid;gap:3px;min-width:0}
|
|
746
784
|
.vsr-s1__subject{display:flex;align-items:baseline;gap:7px;min-width:0;line-height:22px}
|
|
747
785
|
.vsr-s1__tool{flex:none;color:var(--vsr-s1-text-2);font-weight:600}
|
|
@@ -750,20 +788,20 @@ a.vsr-s1__link{text-decoration:none}
|
|
|
750
788
|
.vsr-s1__fact{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
|
|
751
789
|
.vsr-s1__fact b{color:var(--vsr-s1-text);font-weight:600;font-variant-numeric:tabular-nums}
|
|
752
790
|
.vsr-s1__bar{position:relative;width:34px;height:4px;border-radius:2px;overflow:hidden;background:var(--vsr-s1-track)}
|
|
753
|
-
.vsr-s1__bar>i{position:absolute;inset:0;border-radius:inherit;background:
|
|
791
|
+
.vsr-s1__bar>i{position:absolute;inset:0;border-radius:inherit;background:var(--vsr-s1-blue);transform-origin:left center;transform:scaleX(var(--p))}
|
|
754
792
|
.vsr-s1__bar--ok>i{background:var(--vsr-s1-ok)}.vsr-s1__bar--warn>i{background:var(--vsr-s1-warn)}.vsr-s1__bar--bad>i{background:var(--vsr-s1-bad)}
|
|
755
793
|
.vsr-s1__note{color:var(--vsr-s1-text-2);font-size:12.5px}
|
|
756
794
|
.vsr-s1__span{padding:0 3px;border-radius:4px;color:inherit;background:none;font:inherit}
|
|
757
|
-
.vsr-s1__span--removed{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad)
|
|
758
|
-
.vsr-s1__span--dangerous{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad)
|
|
759
|
-
.vsr-s1__span--unsupported{background:color-mix(in srgb,var(--vsr-s1-warn)
|
|
795
|
+
.vsr-s1__span--removed{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad) 14%,transparent);text-decoration:line-through;text-decoration-thickness:1.5px}
|
|
796
|
+
.vsr-s1__span--dangerous{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad) 16%,transparent);box-shadow:inset 0 -2px 0 var(--vsr-s1-bad);font-weight:650}
|
|
797
|
+
.vsr-s1__span--unsupported{background:color-mix(in srgb,var(--vsr-s1-warn) 22%,transparent);text-decoration:underline wavy color-mix(in srgb,var(--vsr-s1-warn) 85%,var(--vsr-s1-text));text-decoration-thickness:1.5px;text-underline-offset:3px}
|
|
760
798
|
.vsr-s1__span--masked{display:inline-block;padding:0 6px;color:var(--dsw-alias-bg-layer-1,#fff);background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--vsr-s1-text) 80%,transparent) 0 6px,color-mix(in srgb,var(--vsr-s1-text) 66%,transparent) 6px 12px);font-family:var(--vsr-s1-mono);font-size:11px;font-weight:650;letter-spacing:.02em;line-height:17px}
|
|
761
799
|
.vsr-s1__excerpts{display:grid;gap:5px;margin:3px 0 1px}
|
|
762
|
-
.vsr-s1__excerpt{padding:6px 9px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-
|
|
800
|
+
.vsr-s1__excerpt{padding:6px 9px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-blue) 50%,transparent);border-radius:0 6px 6px 0;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-text-3) 8%,transparent);font-family:var(--vsr-s1-mono);font-size:12px;line-height:1.6;white-space:pre-wrap;word-break:break-word}
|
|
763
801
|
.vsr-s1--bad .vsr-s1__excerpt{border-left-color:color-mix(in srgb,var(--vsr-s1-bad) 55%,transparent)}
|
|
764
802
|
.vsr-s1--warn .vsr-s1__excerpt{border-left-color:color-mix(in srgb,var(--vsr-s1-warn) 60%,transparent)}
|
|
765
803
|
.vsr-s1__labels{display:flex;flex-wrap:wrap;gap:4px 6px}
|
|
766
|
-
.vsr-s1__label{display:inline-flex;align-items:center;gap:5px;padding:0 7px;border-radius:5px;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-
|
|
804
|
+
.vsr-s1__label{display:inline-flex;align-items:center;gap:5px;padding:0 7px;border-radius:5px;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-blue) 10%,transparent);font-family:var(--vsr-s1-mono);font-size:11.5px;line-height:20px}
|
|
767
805
|
.vsr-s1__label b{color:var(--vsr-s1-text);font-weight:650}
|
|
768
806
|
.vsr-s1__rowms{color:var(--vsr-s1-text-3);font-size:12px;line-height:22px;font-variant-numeric:tabular-nums;white-space:nowrap}
|
|
769
807
|
.vsr-s1__more,.vsr-s1__link{justify-self:start;padding:0;border:0;background:none;color:var(--dsw-alias-link,#2F7BF6);font:inherit;font-size:12.5px;cursor:pointer}
|
|
@@ -771,9 +809,10 @@ a.vsr-s1__link{text-decoration:none}
|
|
|
771
809
|
.vsr-s1--compact{margin:4px 0}
|
|
772
810
|
.vsr-s1__chip{display:flex;align-items:center;gap:9px;width:100%;min-width:0;padding:3px 0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
|
|
773
811
|
.vsr-s1__chip--static{cursor:default}
|
|
774
|
-
.vsr-s1__chev{flex:none;color:var(--vsr-s1-text-3);transition:transform .
|
|
812
|
+
.vsr-s1__chev{flex:none;color:var(--vsr-s1-text-3);transition:transform .2s var(--vsr-s1-ease),color .2s ease}
|
|
813
|
+
.vsr-s1__chip:hover .vsr-s1__chev{color:var(--vsr-s1-text-2)}
|
|
775
814
|
.vsr-s1--open .vsr-s1__chev{transform:rotate(90deg)}
|
|
776
|
-
.vsr-s1--compact>.vsr-s1__rows{margin:4px 0 8px 3px;padding-left:12px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-
|
|
815
|
+
.vsr-s1--compact>.vsr-s1__rows{margin:4px 0 8px 3px;padding-left:12px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-blue) 40%,transparent)}
|
|
777
816
|
.vsr-s1--plain .vsr-s1__reflex{color:var(--vsr-s1-text-2)}
|
|
778
817
|
.vsr-s1__raw{margin:4px 0 8px;padding:8px 10px;max-height:320px;overflow:auto;border-radius:8px;background:color-mix(in srgb,var(--vsr-s1-text-3) 10%,transparent);font-family:var(--vsr-s1-mono);font-size:12px;white-space:pre-wrap}
|
|
779
818
|
.vsr-s1__q{display:grid;grid-template-columns:minmax(80px,140px) minmax(0,1fr);column-gap:14px;align-items:start}
|
|
@@ -789,29 +828,30 @@ a.vsr-s1__link{text-decoration:none}
|
|
|
789
828
|
.vsr-s1__swatch{flex:none;width:8px;height:8px;margin-right:6px;border-radius:2px}
|
|
790
829
|
.vsr-s1__foot{color:var(--vsr-s1-text-3);font-size:12.5px}
|
|
791
830
|
.vsr-s1__foot code{font-family:var(--vsr-s1-mono)}
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
@keyframes vsr-s1-
|
|
797
|
-
@keyframes vsr-s1-
|
|
831
|
+
.vsr-s1__progress{position:relative;display:block;height:2px;margin:0 0 4px 1px;border-radius:2px;overflow:hidden;background:color-mix(in srgb,var(--vsr-s1-blue) 12%,transparent)}
|
|
832
|
+
.vsr-s1__progress::before{content:"";position:absolute;top:0;bottom:0;left:0;width:36%;border-radius:inherit;background:linear-gradient(90deg,transparent,var(--vsr-s1-blue) 55%,transparent)}
|
|
833
|
+
.vsr-s1--deciding .vsr-s1__badge::after{content:"";position:absolute;inset:0;border-radius:inherit;background:linear-gradient(100deg,transparent 35%,rgba(255,255,255,.42) 50%,transparent 65%);background-size:220% 100%;pointer-events:none}
|
|
834
|
+
.vsr-s1__shimmer{background:linear-gradient(90deg,var(--vsr-s1-text-2) 35%,var(--vsr-s1-blue) 50%,var(--vsr-s1-text-2) 65%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent}
|
|
835
|
+
@keyframes vsr-s1-reveal{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
|
|
836
|
+
@keyframes vsr-s1-rise{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
|
|
837
|
+
@keyframes vsr-s1-draw{from{transform:scaleY(0)}to{transform:scaleY(1)}}
|
|
798
838
|
@keyframes vsr-s1-fill{from{transform:scaleX(0)}}
|
|
799
839
|
@keyframes vsr-s1-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
800
|
-
@keyframes vsr-s1-
|
|
801
|
-
@keyframes vsr-s1-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
.vsr-s1--fresh
|
|
805
|
-
.vsr-
|
|
806
|
-
.vsr-
|
|
807
|
-
.vsr-s1__row--fresh{animation:vsr-s1-
|
|
808
|
-
.vsr-s1__row--fresh .vsr-
|
|
809
|
-
|
|
810
|
-
.vsr-
|
|
811
|
-
.vsr-
|
|
812
|
-
.vsr-
|
|
813
|
-
.vsr-s1__shimmer{
|
|
814
|
-
@media (prefers-reduced-motion:reduce){.vsr-s1,.vsr-s1 *,.vsr-s1 *::before,.vsr-s1 *::after{animation:none!important;transition:none!important}.vsr-s1__shimmer{color:var(--vsr-s1-text-2)}}
|
|
840
|
+
@keyframes vsr-s1-ink{from{background-color:transparent;box-shadow:none}}
|
|
841
|
+
@keyframes vsr-s1-breathe{0%,100%{opacity:1}50%{opacity:.4}}
|
|
842
|
+
@keyframes vsr-s1-shimmer{from{background-position:130% 0}to{background-position:-30% 0}}
|
|
843
|
+
@keyframes vsr-s1-scan{from{transform:translateX(-100%)}to{transform:translateX(280%)}}
|
|
844
|
+
.vsr-s1--fresh{animation:vsr-s1-reveal .22s var(--vsr-s1-ease) both}
|
|
845
|
+
.vsr-s1--fresh>.vsr-s1__sheen::before{animation:vsr-s1-draw .42s var(--vsr-s1-ease) .06s both}
|
|
846
|
+
.vsr-s1__row--fresh{animation:vsr-s1-rise .24s var(--vsr-s1-ease) both;animation-delay:calc(60ms + var(--vsr-s1-i,0) * 45ms)}
|
|
847
|
+
.vsr-s1__row--fresh .vsr-s1__bar>i{animation:vsr-s1-fill .6s var(--vsr-s1-ease) .16s both}
|
|
848
|
+
.vsr-s1__row--fresh .vsr-s1__span{animation:vsr-s1-ink .5s ease-out .26s both}
|
|
849
|
+
.vsr-s1__stack--fresh>i{animation:vsr-s1-grow .6s var(--vsr-s1-ease) both}
|
|
850
|
+
.vsr-s1--deciding .vsr-s1__dot{animation:vsr-s1-breathe 1.4s ease-in-out infinite}
|
|
851
|
+
.vsr-s1--deciding .vsr-s1__badge::after{animation:vsr-s1-shimmer 1.8s linear infinite}
|
|
852
|
+
.vsr-s1__progress::before{animation:vsr-s1-scan 1.6s cubic-bezier(.45,0,.55,1) infinite}
|
|
853
|
+
.vsr-s1__shimmer{animation:vsr-s1-shimmer 2s linear infinite}
|
|
854
|
+
@media (prefers-reduced-motion:reduce){.vsr-s1,.vsr-s1 *,.vsr-s1 *::before,.vsr-s1 *::after{animation:none!important;transition:none!important}.vsr-s1__shimmer{color:var(--vsr-s1-text-2);background:none}.vsr-s1--deciding .vsr-s1__badge::after{display:none}.vsr-s1__progress::before{width:100%;opacity:.45;background:var(--vsr-s1-blue)}}
|
|
815
855
|
`
|
|
816
856
|
if (typeof document !== 'undefined') {
|
|
817
857
|
const tagId = `${PACKAGE}/system-one.css`
|