pi-smart-router 0.7.0 → 0.9.0
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/.pi/extensions/smart-router/command-formatters.ts +88 -7
- package/.pi/extensions/smart-router/commands.ts +4 -1
- package/.pi/extensions/smart-router/index.ts +4 -0
- package/README.md +75 -10
- package/config/benchmark-profiles.json +33 -67
- package/config/operator-config.json.example +8 -0
- package/dist/config/defaults.d.ts +1 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +3 -2
- package/dist/config/defaults.js.map +1 -1
- package/dist/domain/pinning/loop-escalation.d.ts +23 -1
- package/dist/domain/pinning/loop-escalation.d.ts.map +1 -1
- package/dist/domain/pinning/loop-escalation.js +107 -20
- package/dist/domain/pinning/loop-escalation.js.map +1 -1
- package/dist/domain/pipeline/router-pipeline.d.ts +7 -1
- package/dist/domain/pipeline/router-pipeline.d.ts.map +1 -1
- package/dist/domain/pipeline/router-pipeline.js +63 -7
- package/dist/domain/pipeline/router-pipeline.js.map +1 -1
- package/dist/domain/triage/triage-engine.d.ts.map +1 -1
- package/dist/domain/triage/triage-engine.js +15 -0
- package/dist/domain/triage/triage-engine.js.map +1 -1
- package/dist/domain/triage/turn-envelope.d.ts.map +1 -1
- package/dist/domain/triage/turn-envelope.js +4 -0
- package/dist/domain/triage/turn-envelope.js.map +1 -1
- package/dist/domain/types/schemas.d.ts +15 -0
- package/dist/domain/types/schemas.d.ts.map +1 -1
- package/dist/domain/types/schemas.js +20 -0
- package/dist/domain/types/schemas.js.map +1 -1
- package/dist/infrastructure/telemetry/routing-telemetry.d.ts +4 -0
- package/dist/infrastructure/telemetry/routing-telemetry.d.ts.map +1 -1
- package/dist/infrastructure/telemetry/routing-telemetry.js +13 -0
- package/dist/infrastructure/telemetry/routing-telemetry.js.map +1 -1
- package/package.json +3 -2
- package/src/config/defaults.ts +9 -1
- package/src/domain/pinning/loop-escalation.ts +136 -20
- package/src/domain/pipeline/router-pipeline.ts +88 -11
- package/src/domain/triage/triage-engine.ts +15 -0
- package/src/domain/triage/turn-envelope.ts +4 -0
- package/src/domain/types/schemas.ts +24 -0
- package/src/infrastructure/telemetry/routing-telemetry.ts +15 -0
|
@@ -2,7 +2,11 @@ import {
|
|
|
2
2
|
DEFAULT_HISTORY_LIMIT,
|
|
3
3
|
MAX_HISTORY_LIMIT,
|
|
4
4
|
} from '../../../src/infrastructure/telemetry/telemetry-limits.js';
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ModelProfile,
|
|
7
|
+
RoutingDecision,
|
|
8
|
+
RoutingTelemetry,
|
|
9
|
+
} from '../../../src/domain/types/index.js';
|
|
6
10
|
import { SMART_ROUTER_USAGE } from './commands.js';
|
|
7
11
|
import {
|
|
8
12
|
DEFAULT_TELEMETRY_CONTRIB_EXPORT_LIMIT,
|
|
@@ -15,6 +19,78 @@ import {
|
|
|
15
19
|
import { formatPricingStalenessLine } from './pricing-lifecycle.js';
|
|
16
20
|
import type { FleetMode, SmartRouterCommand, SmartRouterRuntime } from './types.js';
|
|
17
21
|
|
|
22
|
+
/** Opaque / virtual auto ids that hide the concrete delegated fleet model (SP-178). */
|
|
23
|
+
function isBareOrSmartRouterAuto(modelId: string): boolean {
|
|
24
|
+
return modelId === 'auto' || modelId === 'smart-router/auto';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the operator-facing model id for history/status (SP-178 / #99).
|
|
29
|
+
* Prefer a concrete delegated/primary id over virtual `auto`.
|
|
30
|
+
*/
|
|
31
|
+
export function resolveHistoryModelId(
|
|
32
|
+
entry: Pick<
|
|
33
|
+
RoutingTelemetry,
|
|
34
|
+
| 'selected_model_id'
|
|
35
|
+
| 'planning_delegate_primary_model_id'
|
|
36
|
+
| 'planning_delegate_model_id'
|
|
37
|
+
>,
|
|
38
|
+
fleet?: readonly ModelProfile[],
|
|
39
|
+
): string {
|
|
40
|
+
let modelId = entry.selected_model_id;
|
|
41
|
+
|
|
42
|
+
if (isBareOrSmartRouterAuto(modelId)) {
|
|
43
|
+
const primary = entry.planning_delegate_primary_model_id;
|
|
44
|
+
if (primary && !isBareOrSmartRouterAuto(primary)) {
|
|
45
|
+
modelId = primary;
|
|
46
|
+
} else if (
|
|
47
|
+
entry.planning_delegate_model_id &&
|
|
48
|
+
!isBareOrSmartRouterAuto(entry.planning_delegate_model_id)
|
|
49
|
+
) {
|
|
50
|
+
modelId = entry.planning_delegate_model_id;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return qualifyModelIdForDisplay(modelId, fleet);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Qualify bare `auto` with provider when fleet is available so history never
|
|
59
|
+
* looks like the smart-router virtual model.
|
|
60
|
+
*/
|
|
61
|
+
export function qualifyModelIdForDisplay(
|
|
62
|
+
modelId: string,
|
|
63
|
+
fleet?: readonly ModelProfile[],
|
|
64
|
+
): string {
|
|
65
|
+
if (modelId !== 'auto') {
|
|
66
|
+
return modelId;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const profile = fleet?.find((m) => m.id === 'auto');
|
|
70
|
+
if (profile) {
|
|
71
|
+
return `${profile.provider}/${profile.id}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Cursor opaque auto is the common bare-`auto` fleet id; never leave it unqualified.
|
|
75
|
+
return 'cursor/auto';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export function resolveStatusModelId(
|
|
79
|
+
decision: RoutingDecision,
|
|
80
|
+
fleet?: readonly ModelProfile[],
|
|
81
|
+
): string {
|
|
82
|
+
const primary = decision.features?.planning_delegate?.primary_model_id ?? null;
|
|
83
|
+
const delegate = decision.features?.planning_delegate?.delegate_model_id ?? null;
|
|
84
|
+
return resolveHistoryModelId(
|
|
85
|
+
{
|
|
86
|
+
selected_model_id: decision.selected_model_id,
|
|
87
|
+
planning_delegate_primary_model_id: primary,
|
|
88
|
+
planning_delegate_model_id: delegate,
|
|
89
|
+
},
|
|
90
|
+
fleet,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
18
94
|
export function parseHistoryLimit(raw: string | undefined): number {
|
|
19
95
|
if (raw === undefined) {
|
|
20
96
|
return DEFAULT_HISTORY_LIMIT;
|
|
@@ -142,8 +218,9 @@ export function formatStatusMessage(
|
|
|
142
218
|
return lines.join('\n');
|
|
143
219
|
}
|
|
144
220
|
|
|
221
|
+
const displayModelId = resolveStatusModelId(decision, runtime.streamDeps.fleet);
|
|
145
222
|
lines.push(
|
|
146
|
-
`Model: ${
|
|
223
|
+
`Model: ${displayModelId}`,
|
|
147
224
|
`Stage: ${decision.stage}`,
|
|
148
225
|
`Reason: ${decision.reason_code}`,
|
|
149
226
|
`Latency: ${decision.routing_latency_ms}ms`,
|
|
@@ -151,16 +228,20 @@ export function formatStatusMessage(
|
|
|
151
228
|
return lines.join('\n');
|
|
152
229
|
}
|
|
153
230
|
|
|
154
|
-
export function formatHistoryMessage(
|
|
231
|
+
export function formatHistoryMessage(
|
|
232
|
+
entries: readonly RoutingTelemetry[],
|
|
233
|
+
options?: { fleet?: readonly ModelProfile[] },
|
|
234
|
+
): string {
|
|
155
235
|
if (entries.length === 0) {
|
|
156
236
|
return 'No routing history yet.';
|
|
157
237
|
}
|
|
158
238
|
|
|
239
|
+
const fleet = options?.fleet;
|
|
159
240
|
return entries
|
|
160
|
-
.map(
|
|
161
|
-
(entry)
|
|
162
|
-
|
|
163
|
-
)
|
|
241
|
+
.map((entry) => {
|
|
242
|
+
const modelId = resolveHistoryModelId(entry, fleet);
|
|
243
|
+
return `${entry.timestamp} | ${modelId} | ${entry.stage} | ${entry.turn_type} | ${entry.routing_latency_ms}ms`;
|
|
244
|
+
})
|
|
164
245
|
.join('\n');
|
|
165
246
|
}
|
|
166
247
|
|
|
@@ -160,7 +160,10 @@ export function registerSmartRouterCommand(
|
|
|
160
160
|
throwIfCommandAborted(signal);
|
|
161
161
|
const rows = await runtime.store.listTelemetry({ limit: parsed.limit });
|
|
162
162
|
throwIfCommandAborted(signal);
|
|
163
|
-
ctx.ui.notify(
|
|
163
|
+
ctx.ui.notify(
|
|
164
|
+
formatHistoryMessage(rows, { fleet: runtime.streamDeps.fleet }),
|
|
165
|
+
'info',
|
|
166
|
+
);
|
|
164
167
|
return;
|
|
165
168
|
}
|
|
166
169
|
|
|
@@ -38,6 +38,8 @@ import {
|
|
|
38
38
|
formatHistoryMessage,
|
|
39
39
|
formatStatusMessage,
|
|
40
40
|
parseSmartRouterArgs,
|
|
41
|
+
resolveHistoryModelId,
|
|
42
|
+
qualifyModelIdForDisplay,
|
|
41
43
|
} from './command-formatters.js';
|
|
42
44
|
import { formatPricingStalenessLine, refreshPricingCatalog } from './pricing-lifecycle.js';
|
|
43
45
|
import {
|
|
@@ -87,8 +89,10 @@ export {
|
|
|
87
89
|
getSmartRouterArgumentCompletions,
|
|
88
90
|
mapContextMessages,
|
|
89
91
|
parseSmartRouterArgs,
|
|
92
|
+
qualifyModelIdForDisplay,
|
|
90
93
|
refreshPricingCatalog,
|
|
91
94
|
resolveDelegationOptions,
|
|
95
|
+
resolveHistoryModelId,
|
|
92
96
|
logRoutingDecision,
|
|
93
97
|
toDatasetExportRecord,
|
|
94
98
|
capturePreRouteOutcomes,
|
package/README.md
CHANGED
|
@@ -197,7 +197,7 @@ Cursor models bill against your **Cursor Pro subscription quota**, not per-token
|
|
|
197
197
|
|---------|---------|
|
|
198
198
|
| `/smart-router` | Same as `status` (default when no subcommand is given) |
|
|
199
199
|
| `/smart-router status` | Show fleet mode, fleet size, pricing freshness/staleness, and the last routing decision (stage, tier, selected model, latency) |
|
|
200
|
-
| `/smart-router history` | Show recent routing telemetry from SQLite (default limit; optional numeric limit, e.g. `/smart-router history 20`) |
|
|
200
|
+
| `/smart-router history` | Show recent routing telemetry from SQLite (default limit; optional numeric limit, e.g. `/smart-router history 20`). Displays the concrete delegated model id (never bare virtual `auto`) |
|
|
201
201
|
| `/smart-router mode scoped` | Route only among pi's **enabled model patterns** (default) |
|
|
202
202
|
| `/smart-router mode all` | Route among **all authenticated models** in the registry |
|
|
203
203
|
| `/smart-router pricing refresh` | Manually fetch LiteLLM pricing from `LITELLM_PRICING_URL`, persist to SQLite, and rebuild the fleet with updated rates |
|
|
@@ -339,7 +339,7 @@ Cluster IDs are stable reason-code prefixes (`cluster_low_stakes_general`, `clus
|
|
|
339
339
|
| Variable | Default | Purpose |
|
|
340
340
|
|----------|---------|---------|
|
|
341
341
|
| `ROUTER_STATE_DB_PATH` | `./.pi-smart-router/state.db` | Override SQLite state store location (telemetry, pricing catalog, session data) |
|
|
342
|
-
| `SMART_ROUTER_LOG_ROUTING` | (unset) | Set to `1` to log each routing decision to stderr as JSON (debugging dogfood sessions) |
|
|
342
|
+
| `SMART_ROUTER_LOG_ROUTING` | (unset) | Set to `1` to log each routing decision to stderr as JSON (debugging dogfood sessions). Canonical payload builder (`buildRoutingDecisionLogPayload`) includes top-level `stage`, `reason_code`, `low_intensity_score`, `tier_hint`, `local_eligible_reason`, and `cluster_id` (plus nested `cluster_summary` / `features`). The pi extension’s live stderr logger is still a slim subset — see [LOG_ROUTING field checklist](#log_routing-field-checklist) |
|
|
343
343
|
| `SMART_ROUTER_DATASET` | (unset) | Set to `1` to opt in to privacy-safe routing dataset capture (metadata and feature fields only; 30-day / 10k-row retention). Prompt text, messages, and tool arguments are never stored. Required for outcome labels and P(success) training export. See [#8](https://github.com/beettlle/pi-smart-router/issues/8). |
|
|
344
344
|
| `SMART_ROUTER_DATASET_FINGERPRINT` | (unset) | Set to `1` (requires `SMART_ROUTER_DATASET=1`) to store an install-local HMAC-SHA256 fingerprint of each normalized prompt for duplicate detection within this install. The install pepper lives in `.pi-smart-router/.dataset-key` (gitignored) and is never exported. **Warning:** short or common prompts are vulnerable to offline rainbow-table guessing; use only when you accept that tradeoff. See [#10](https://github.com/beettlle/pi-smart-router/issues/10). |
|
|
345
345
|
| `MODELS_YAML_PATH` | `./config/models.yaml` | Fleet catalog path (library API only) |
|
|
@@ -354,6 +354,23 @@ Cluster IDs are stable reason-code prefixes (`cluster_low_stakes_general`, `clus
|
|
|
354
354
|
| `ROUTER_SAFE_DEFAULT_TIER` | `economical-cloud` | Fallback tier on any routing failure |
|
|
355
355
|
| `LITELLM_PRICING_URL` | — | LiteLLM pricing JSON source |
|
|
356
356
|
|
|
357
|
+
### LOG_ROUTING field checklist
|
|
358
|
+
|
|
359
|
+
When `SMART_ROUTER_LOG_ROUTING=1`, prefer the canonical payload from `buildRoutingDecisionLogPayload` (library / tests). Checklist for [#99](https://github.com/beettlle/pi-smart-router/issues/99):
|
|
360
|
+
|
|
361
|
+
| Field | In payload builder? | Notes |
|
|
362
|
+
|-------|---------------------|-------|
|
|
363
|
+
| `stage` | Yes (top-level) | Pipeline stage that decided |
|
|
364
|
+
| `reason_code` | Yes (top-level) | Machine-readable reason |
|
|
365
|
+
| `low_intensity_score` | Yes (top-level + `cluster_summary`) | Null when low-intensity stage did not run |
|
|
366
|
+
| `tier_hint` | Yes (top-level + `cluster_summary`) | Null when no tier hint |
|
|
367
|
+
| `local_eligible_reason` | Yes (top-level + `features`) | Null when local_zero did not evaluate eligibility |
|
|
368
|
+
| `cluster_id` | Yes (top-level + `cluster_summary`) | Null when no cluster match |
|
|
369
|
+
|
|
370
|
+
**Gap:** the pi extension’s live stderr path (`logRoutingDecision` in `.pi/extensions/smart-router`) still emits a slim JSON object (`selected_model_id`, `stage`, `reason_code`, `features`, `delegate`) and does **not** yet call `buildRoutingDecisionLogPayload`. SQLite `/smart-router history` and the payload builder carry the full checklist; wire the extension logger in a follow-up if dogfood needs identical stderr shape.
|
|
371
|
+
|
|
372
|
+
**History model id:** `/smart-router history` resolves bare/`smart-router` virtual `auto` to the concrete planning-delegate primary (or qualifies Cursor opaque `auto` as `cursor/auto`) so operators see the delegated fleet model, not the virtual router id.
|
|
373
|
+
|
|
357
374
|
### SAAR session pin and cache breakeven (v0.2.0 Continuity)
|
|
358
375
|
|
|
359
376
|
v0.2.0 adds **Session-Aware Agentic Routing (SAAR)** pin knobs ([#72](https://github.com/beettlle/pi-smart-router/issues/72)) and a **cache breakeven gate** ([#73](https://github.com/beettlle/pi-smart-router/issues/73)) that blocks tier switches when `marginal_savings + future_cache_value <= cache_reprime_cost` — preventing cheap-turn savings from invalidating a warm prefix cache.
|
|
@@ -567,8 +584,10 @@ Additional operator defaults:
|
|
|
567
584
|
|
|
568
585
|
| Key | Default | Purpose |
|
|
569
586
|
|-----|---------|---------|
|
|
570
|
-
| `loop_escalation.threshold` | 3 | Consecutive identical failures before escalating to frontier |
|
|
587
|
+
| `loop_escalation.threshold` | 3 | Consecutive identical failures before escalating to frontier. Also used as the default **zero-tier tool-call churn** threshold (SP-178 / [#99](https://github.com/beettlle/pi-smart-router/issues/99)): while pinned to `zero-tier`, unsupported/unknown tool results escalate immediately, and N `tool_result` turns escalate via the same `loop_escalation` pin path (FR-014) — not a cache-breakeven bypass |
|
|
571
588
|
| `pin_only_fallback` | `false` | Emergency pin-on-first-turn mode — see [Pin-only emergency fallback](#pin-only-emergency-fallback) |
|
|
589
|
+
| `local_zero.enabled` | `true` | When `false`, skip `local_zero` dispatch (fall through to later stages). Default keeps the cheap local path for true trivial traffic |
|
|
590
|
+
| `local_zero.max_tool_use_requirement` | `0.25` | Ceiling (0–1) on cheap predicted tool_use for `local_zero`. Effective limit is `min(local model tool_use, this value)`. Skips agentic git/bash/edit/explore/delete/repo cues with telemetry reason `tool_use_capability_shortfall` (SP-177 / [#98](https://github.com/beettlle/pi-smart-router/issues/98)) |
|
|
572
591
|
| `local.min_memory_gb_full` | 16 | Minimum RAM for full local inference |
|
|
573
592
|
| `local.battery_threshold_pct` | 20 | Minimum battery to allow local inference |
|
|
574
593
|
| `pricing.staleness_days` | 14 | Max age before re-fetching pricing data |
|
|
@@ -809,7 +828,7 @@ npm run routing:eval-replay
|
|
|
809
828
|
|
|
810
829
|
### Benchmark profile refresh
|
|
811
830
|
|
|
812
|
-
Capability scores in `config/benchmark-profiles.json` are grounded from public leaderboard snapshots under `tests/fixtures/benchmark-leaderboards
|
|
831
|
+
Capability scores in `config/benchmark-profiles.json` are grounded from public leaderboard snapshots under `tests/fixtures/benchmark-leaderboards/` (and optional **recorded** live snapshots under `tests/fixtures/benchmark-leaderboards/recorded/`). Each artifact records provenance (`source_urls`, `scrape_date`, `catalog_freeze_date`) in its header.
|
|
813
832
|
|
|
814
833
|
**Fleet ID aliases (SP-174):** live pi/Cursor scoped-fleet model IDs often differ from leaderboard `model_id` strings. The artifact’s optional `aliases` map sends those fleet IDs to an existing grounded row (never invents scores). `mapPiModelToProfile` sets `capability_source` to `benchmark` when a direct row or alias hits, otherwise `pattern_default`. Operators can also call `getCapabilitySource(modelId)` / `resolveBenchmarkModelId(modelId)`.
|
|
815
834
|
|
|
@@ -821,16 +840,61 @@ Capability scores in `config/benchmark-profiles.json` are grounded from public l
|
|
|
821
840
|
4. Re-run ingest anytime — the CLI **preserves** existing `aliases` from the output file. Seed defaults live in `DEFAULT_FLEET_BENCHMARK_ALIASES` when no prior artifact exists.
|
|
822
841
|
5. Confirm with `npm run routing:verify-benchmark-profiles` and a mapper unit test that `capability_source === 'benchmark'` for the fleet id.
|
|
823
842
|
|
|
843
|
+
**Operator refresh command (SP-179 / SP-180):**
|
|
844
|
+
|
|
845
|
+
| Mode | Command | Network? | When to use |
|
|
846
|
+
|------|---------|----------|-------------|
|
|
847
|
+
| **Fixtures (default)** | `npm run routing:ingest-benchmarks` | No | Local edits, CI, PR smoke |
|
|
848
|
+
| **Recorded replay** | `npm run routing:ingest-benchmarks -- --recorded` | No | Replay last successful live snapshots offline |
|
|
849
|
+
| **Live + record** | `npm run routing:ingest-benchmarks -- --live` | Yes | Operator refresh; writes `tests/fixtures/benchmark-leaderboards/recorded/` then regenerates profiles |
|
|
850
|
+
|
|
851
|
+
Optional flags: `--catalog-freeze-date YYYY-MM-DD`, `--scrape-date YYYY-MM-DD`, `--record-dir DIR`, `--live-url BENCHMARK=URL`, `--output PATH`. See `npm run routing:ingest-benchmarks -- --help`.
|
|
852
|
+
|
|
853
|
+
**Live sources (per benchmark):** each `--live` run resolves independently — live adapter → recorded → checked-in fixtures. One failing source never invents scores or blocks siblings. Logs: `ingest-benchmark-profiles: <id> source=live|recorded|fixture (…)`.
|
|
854
|
+
|
|
855
|
+
| Benchmark | Default live fetch | Score field | Fallback |
|
|
856
|
+
|-----------|-------------------|-------------|----------|
|
|
857
|
+
| `swebench_verified` | Native: [SWE-bench `leaderboards.json`](https://raw.githubusercontent.com/SWE-bench/swe-bench.github.io/master/data/leaderboards.json) (Verified board) | `resolved` → `score` (0–100) | recorded → fixtures |
|
|
858
|
+
| `livecodebench` | Native: [LCB `performances_generation.json`](https://raw.githubusercontent.com/LiveCodeBench/livecodebench.github.io/main/src/mocks/performances_generation.json) | aggregate `pass@1` | recorded → fixtures |
|
|
859
|
+
| `bfcl` | Native: [Gorilla `data_overall.csv`](https://raw.githubusercontent.com/ShishirPatil/gorilla/gh-pages/data_overall.csv) | `Overall Acc` | recorded → fixtures |
|
|
860
|
+
| `terminal_bench` | **No free stable JSON** (tbench.ai is HTML; HF leaderboard is submissions-only; paid Parse API is **not** the default). Pass `--live-url terminal_bench=URL` at a fixture-shaped mirror | `score` (0–100) | recorded → fixtures |
|
|
861
|
+
|
|
862
|
+
**Terminal-Bench operator mirror schema** (SP-185 / #104):
|
|
863
|
+
|
|
864
|
+
```json
|
|
865
|
+
{
|
|
866
|
+
"benchmark": "terminal_bench",
|
|
867
|
+
"source_url": "https://www.tbench.ai/leaderboard",
|
|
868
|
+
"scrape_date": "YYYY-MM-DD",
|
|
869
|
+
"entries": [{ "model_id": "claude-opus-4-5", "score": 72.5 }]
|
|
870
|
+
}
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
Example: `npm run routing:ingest-benchmarks -- --live --live-url terminal_bench=https://example.com/tb-mirror.json`. HTML bodies fail fast; without `--live-url`, TB uses recorded/fixtures. `release:refresh-benchmarks` uses the same `--live` path (fixture fallback on total failure).
|
|
874
|
+
|
|
875
|
+
**Cadence (release-tied, not calendar):**
|
|
876
|
+
|
|
877
|
+
| Trigger | When | Behavior |
|
|
878
|
+
|---------|------|----------|
|
|
879
|
+
| **Pre-tag release gate** | `npm run release:check` → `release:refresh-benchmarks` | Attempt **live** ingest; on failure fall back to fixtures; **fail if** `config/benchmark-profiles.json` or recorded snapshots are dirty — commit on `main`, re-run, then `npm version` / tag |
|
|
880
|
+
| **Manual dispatch** | Actions → *Benchmark Profile Refresh* → `workflow_dispatch` (`use_live` default `true`) | Same live-or-fixture path; opens a bot PR when scores change; set `use_live=false` for fixtures-only |
|
|
881
|
+
| **PR smoke** | PRs touching fixtures / ingest / artifact / workflow | **Fixtures only** — `npm run routing:verify-benchmark-profiles` (offline, no network) |
|
|
882
|
+
|
|
883
|
+
There is **no monthly cron**. Refresh runs when you ship so each release packages the latest grounded scores. Tag-triggered Release publish uses `--ignore-scripts` and does not re-fetch (profiles are already frozen in the tag). Offline skip: `SMART_ROUTER_SKIP_LIVE_BENCHMARK_REFRESH=1 npm run release:check`.
|
|
884
|
+
|
|
824
885
|
**Operator policy:**
|
|
825
886
|
|
|
826
|
-
1. **PR smoke** —
|
|
827
|
-
2. **
|
|
828
|
-
3. **
|
|
887
|
+
1. **PR smoke** — fixture-only verify so PRs never require live network.
|
|
888
|
+
2. **Every release** — live with fixture fallback via `release:check`; commit any profile/recorded diffs on `main` before tagging.
|
|
889
|
+
3. **Ad-hoc** — Actions dispatch or local `--live` when refreshing between releases.
|
|
890
|
+
4. **Manual local updates** — prefer fixtures or `--recorded` for offline work; use `--live` when refreshing from public leaderboard JSON endpoints.
|
|
829
891
|
|
|
830
|
-
|
|
892
|
+
Verify after any regenerate:
|
|
831
893
|
|
|
832
894
|
```bash
|
|
833
895
|
npm run routing:ingest-benchmarks
|
|
896
|
+
# or: npm run routing:ingest-benchmarks -- --live
|
|
897
|
+
# or: npm run routing:ingest-benchmarks -- --recorded
|
|
834
898
|
npm run routing:verify-benchmark-profiles
|
|
835
899
|
```
|
|
836
900
|
|
|
@@ -844,7 +908,7 @@ Tag-triggered publish via GitHub Actions (requires `NPMSECRET` repository secret
|
|
|
844
908
|
2. `routing:verify-benchmark-profiles` — checked-in capability profiles match fixture ingest
|
|
845
909
|
3. `assert-release-gates --fixtures tests/eval/fixtures --baseline-version 0.6.0` — eval harness aggregate metrics vs `config/release-gates.json` and semver baseline regression vs `tests/eval/baselines/v0.6.0.json`
|
|
846
910
|
|
|
847
|
-
`release:check` runs the full pre-release path: `verify:ci`, consumer pack verify, then Tier 0 functional smoke.
|
|
911
|
+
`release:check` runs the full pre-release path: **live benchmark profile refresh** (fixture fallback; dirty-tree fail), then `verify:ci`, consumer pack verify, then Tier 0 functional smoke.
|
|
848
912
|
|
|
849
913
|
**Baseline re-capture (post-tag):** after shipping a new semver (e.g. v0.7.0), freeze harness metrics for the next regression reference:
|
|
850
914
|
|
|
@@ -857,7 +921,8 @@ npm run routing:capture-baseline -- --version 0.7.0
|
|
|
857
921
|
|
|
858
922
|
Commit the new baseline JSON and update `baseline_regression.reference_version` in `config/release-gates.json` plus the `--baseline-version` flag in `release:functional-smoke`. Re-run `npm run release:check` before tagging the next release.
|
|
859
923
|
|
|
860
|
-
1. `npm run release:check` (CI parity + consumer pack + Tier 0 functional smoke)
|
|
924
|
+
1. `npm run release:check` (live benchmark refresh → CI parity + consumer pack + Tier 0 functional smoke)
|
|
925
|
+
- If refresh rewrites profiles/recorded snapshots, **commit them on `main`** and re-run until clean
|
|
861
926
|
2. `npm version 0.1.1` (creates commit + `v0.1.1` tag)
|
|
862
927
|
3. `git push && git push --tags`
|
|
863
928
|
4. Actions → **Release** runs pack smoke, consumer pack verify, Tier 0 functional smoke, `npm publish`, and creates a GitHub Release
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"livecodebench": "https://livecodebench.github.io/leaderboard.html",
|
|
8
8
|
"bfcl": "https://gorilla.cs.berkeley.edu/leaderboard.html"
|
|
9
9
|
},
|
|
10
|
-
"scrape_date": "2026-07-
|
|
11
|
-
"catalog_freeze_date": "2026-07-
|
|
10
|
+
"scrape_date": "2026-07-11",
|
|
11
|
+
"catalog_freeze_date": "2026-07-11"
|
|
12
12
|
},
|
|
13
13
|
"aliases": {
|
|
14
14
|
"claude-3-5-sonnet": "claude-sonnet-4-6",
|
|
@@ -34,50 +34,24 @@
|
|
|
34
34
|
},
|
|
35
35
|
"models": [
|
|
36
36
|
{
|
|
37
|
-
"model_id": "claude-
|
|
37
|
+
"model_id": "claude-opus-4-5",
|
|
38
38
|
"capabilities": {
|
|
39
|
-
"reasoning": 0.
|
|
40
|
-
"code_gen": 0.
|
|
41
|
-
"tool_use": 0.
|
|
39
|
+
"reasoning": 0.7585,
|
|
40
|
+
"code_gen": 0.708,
|
|
41
|
+
"tool_use": 0.7498
|
|
42
42
|
},
|
|
43
43
|
"benchmark_sources": {
|
|
44
44
|
"bfcl": {
|
|
45
|
-
"raw_score":
|
|
46
|
-
"normalized": 0.
|
|
45
|
+
"raw_score": 77.47,
|
|
46
|
+
"normalized": 0.7746999999999999
|
|
47
47
|
},
|
|
48
48
|
"livecodebench": {
|
|
49
|
-
"raw_score": 55,
|
|
50
|
-
"normalized": 0.55
|
|
51
|
-
},
|
|
52
|
-
"swebench_verified": {
|
|
53
49
|
"raw_score": 62.4,
|
|
54
50
|
"normalized": 0.624
|
|
55
51
|
},
|
|
56
|
-
"terminal_bench": {
|
|
57
|
-
"raw_score": 51.3,
|
|
58
|
-
"normalized": 0.513
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
"model_id": "claude-opus-4-5",
|
|
64
|
-
"capabilities": {
|
|
65
|
-
"reasoning": 0.767,
|
|
66
|
-
"code_gen": 0.7915,
|
|
67
|
-
"tool_use": 0.8035
|
|
68
|
-
},
|
|
69
|
-
"benchmark_sources": {
|
|
70
|
-
"bfcl": {
|
|
71
|
-
"raw_score": 88.2,
|
|
72
|
-
"normalized": 0.882
|
|
73
|
-
},
|
|
74
|
-
"livecodebench": {
|
|
75
|
-
"raw_score": 77.4,
|
|
76
|
-
"normalized": 0.774
|
|
77
|
-
},
|
|
78
52
|
"swebench_verified": {
|
|
79
|
-
"raw_score":
|
|
80
|
-
"normalized": 0.
|
|
53
|
+
"raw_score": 79.2,
|
|
54
|
+
"normalized": 0.792
|
|
81
55
|
},
|
|
82
56
|
"terminal_bench": {
|
|
83
57
|
"raw_score": 72.5,
|
|
@@ -88,22 +62,22 @@
|
|
|
88
62
|
{
|
|
89
63
|
"model_id": "claude-sonnet-4-6",
|
|
90
64
|
"capabilities": {
|
|
91
|
-
"reasoning": 0.
|
|
92
|
-
"code_gen": 0.
|
|
93
|
-
"tool_use": 0.
|
|
65
|
+
"reasoning": 0.724,
|
|
66
|
+
"code_gen": 0.681,
|
|
67
|
+
"tool_use": 0.7062
|
|
94
68
|
},
|
|
95
69
|
"benchmark_sources": {
|
|
96
70
|
"bfcl": {
|
|
97
|
-
"raw_score":
|
|
98
|
-
"normalized": 0.
|
|
71
|
+
"raw_score": 73.24,
|
|
72
|
+
"normalized": 0.7323999999999999
|
|
99
73
|
},
|
|
100
74
|
"livecodebench": {
|
|
101
|
-
"raw_score":
|
|
102
|
-
"normalized": 0.
|
|
75
|
+
"raw_score": 59.4,
|
|
76
|
+
"normalized": 0.594
|
|
103
77
|
},
|
|
104
78
|
"swebench_verified": {
|
|
105
|
-
"raw_score":
|
|
106
|
-
"normalized": 0.
|
|
79
|
+
"raw_score": 76.8,
|
|
80
|
+
"normalized": 0.768
|
|
107
81
|
},
|
|
108
82
|
"terminal_bench": {
|
|
109
83
|
"raw_score": 68,
|
|
@@ -114,22 +88,22 @@
|
|
|
114
88
|
{
|
|
115
89
|
"model_id": "gemini-2.5-flash",
|
|
116
90
|
"capabilities": {
|
|
117
|
-
"reasoning": 0.
|
|
118
|
-
"code_gen": 0.
|
|
119
|
-
"tool_use": 0.
|
|
91
|
+
"reasoning": 0.3827,
|
|
92
|
+
"code_gen": 0.5192,
|
|
93
|
+
"tool_use": 0.5202
|
|
120
94
|
},
|
|
121
95
|
"benchmark_sources": {
|
|
122
96
|
"bfcl": {
|
|
123
|
-
"raw_score":
|
|
124
|
-
"normalized": 0.
|
|
97
|
+
"raw_score": 56.24,
|
|
98
|
+
"normalized": 0.5624
|
|
125
99
|
},
|
|
126
100
|
"livecodebench": {
|
|
127
|
-
"raw_score":
|
|
128
|
-
"normalized": 0.
|
|
101
|
+
"raw_score": 75.1,
|
|
102
|
+
"normalized": 0.7509999999999999
|
|
129
103
|
},
|
|
130
104
|
"swebench_verified": {
|
|
131
|
-
"raw_score":
|
|
132
|
-
"normalized": 0.
|
|
105
|
+
"raw_score": 28.73,
|
|
106
|
+
"normalized": 0.2873
|
|
133
107
|
},
|
|
134
108
|
"terminal_bench": {
|
|
135
109
|
"raw_score": 47.8,
|
|
@@ -140,22 +114,14 @@
|
|
|
140
114
|
{
|
|
141
115
|
"model_id": "gpt-5.3-codex",
|
|
142
116
|
"capabilities": {
|
|
143
|
-
"reasoning": 0.
|
|
144
|
-
"code_gen": 0.
|
|
145
|
-
"tool_use": 0.
|
|
117
|
+
"reasoning": 0.743,
|
|
118
|
+
"code_gen": 0.744,
|
|
119
|
+
"tool_use": 0.742
|
|
146
120
|
},
|
|
147
121
|
"benchmark_sources": {
|
|
148
|
-
"bfcl": {
|
|
149
|
-
"raw_score": 90.1,
|
|
150
|
-
"normalized": 0.9009999999999999
|
|
151
|
-
},
|
|
152
|
-
"livecodebench": {
|
|
153
|
-
"raw_score": 81.6,
|
|
154
|
-
"normalized": 0.816
|
|
155
|
-
},
|
|
156
122
|
"swebench_verified": {
|
|
157
|
-
"raw_score":
|
|
158
|
-
"normalized": 0.
|
|
123
|
+
"raw_score": 74.4,
|
|
124
|
+
"normalized": 0.7440000000000001
|
|
159
125
|
},
|
|
160
126
|
"terminal_bench": {
|
|
161
127
|
"raw_score": 74.2,
|
|
@@ -60,5 +60,13 @@
|
|
|
60
60
|
"exclude_execution_history": true
|
|
61
61
|
}
|
|
62
62
|
},
|
|
63
|
+
"local_zero": {
|
|
64
|
+
"enabled": true,
|
|
65
|
+
"max_tool_use_requirement": 0.25,
|
|
66
|
+
"_documentation": {
|
|
67
|
+
"enabled": "When false, skip local_zero entirely (fall through to triage cloud / HyDRA). Default true — does not disable local for trivial traffic.",
|
|
68
|
+
"max_tool_use_requirement": "Ceiling (0–1) on cheap predicted tool_use for local_zero dispatch. Effective limit is min(local model tool_use capability, this value). Default 0.25 keeps format/lint local while skipping agentic git/bash/edit/explore/delete/repo cues (SP-177, #98)."
|
|
69
|
+
}
|
|
70
|
+
},
|
|
63
71
|
"pin_only_fallback": false
|
|
64
72
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Values sourced from specs/001-build-smart-router/data-model.md § Configuration (Operator).
|
|
4
4
|
*/
|
|
5
5
|
import { type OperatorConfig } from '../domain/types/schemas.js';
|
|
6
|
-
export { DEFAULT_PLANNING_DELEGATE_CONFIG, DEFAULT_SAAR_CONFIG, resolvePlanningDelegateConfigFromEnv, resolveSaarConfigFromEnv } from '../domain/types/schemas.js';
|
|
6
|
+
export { DEFAULT_LOCAL_ZERO_CONFIG, DEFAULT_PLANNING_DELEGATE_CONFIG, DEFAULT_SAAR_CONFIG, resolvePlanningDelegateConfigFromEnv, resolveSaarConfigFromEnv, } from '../domain/types/schemas.js';
|
|
7
7
|
/** Merge operator env overrides onto defaults (SAAR and planning delegate sections). */
|
|
8
8
|
export declare function resolveOperatorConfigFromEnv(base?: OperatorConfig): OperatorConfig;
|
|
9
9
|
export declare const DEFAULT_OPERATOR_CONFIG: Readonly<OperatorConfig>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACL,yBAAyB,EACzB,gCAAgC,EAChC,mBAAmB,EACnB,oCAAoC,EACpC,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,wFAAwF;AACxF,wBAAgB,4BAA4B,CAC1C,IAAI,GAAE,cAAwC,GAC7C,cAAc,CAMhB;AAED,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,cAAc,CAgCnD,CAAC"}
|
package/dist/config/defaults.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Operator configuration defaults (FR-021).
|
|
3
3
|
* Values sourced from specs/001-build-smart-router/data-model.md § Configuration (Operator).
|
|
4
4
|
*/
|
|
5
|
-
import { DEFAULT_PLANNING_DELEGATE_CONFIG, DEFAULT_SAAR_CONFIG, resolvePlanningDelegateConfigFromEnv, resolveSaarConfigFromEnv, } from '../domain/types/schemas.js';
|
|
5
|
+
import { DEFAULT_LOCAL_ZERO_CONFIG, DEFAULT_PLANNING_DELEGATE_CONFIG, DEFAULT_SAAR_CONFIG, resolvePlanningDelegateConfigFromEnv, resolveSaarConfigFromEnv, } from '../domain/types/schemas.js';
|
|
6
6
|
import { DEFAULT_LOW_INTENSITY_WEIGHTS } from '../domain/routing/tier-features.js';
|
|
7
|
-
export { DEFAULT_PLANNING_DELEGATE_CONFIG, DEFAULT_SAAR_CONFIG, resolvePlanningDelegateConfigFromEnv, resolveSaarConfigFromEnv } from '../domain/types/schemas.js';
|
|
7
|
+
export { DEFAULT_LOCAL_ZERO_CONFIG, DEFAULT_PLANNING_DELEGATE_CONFIG, DEFAULT_SAAR_CONFIG, resolvePlanningDelegateConfigFromEnv, resolveSaarConfigFromEnv, } from '../domain/types/schemas.js';
|
|
8
8
|
/** Merge operator env overrides onto defaults (SAAR and planning delegate sections). */
|
|
9
9
|
export function resolveOperatorConfigFromEnv(base = DEFAULT_OPERATOR_CONFIG) {
|
|
10
10
|
return {
|
|
@@ -43,6 +43,7 @@ export const DEFAULT_OPERATOR_CONFIG = {
|
|
|
43
43
|
},
|
|
44
44
|
saar: DEFAULT_SAAR_CONFIG,
|
|
45
45
|
planning_delegate: DEFAULT_PLANNING_DELEGATE_CONFIG,
|
|
46
|
+
local_zero: DEFAULT_LOCAL_ZERO_CONFIG,
|
|
46
47
|
pin_only_fallback: false,
|
|
47
48
|
};
|
|
48
49
|
//# sourceMappingURL=defaults.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,oCAAoC,EACpC,wBAAwB,GAEzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAEnF,OAAO,
|
|
1
|
+
{"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/config/defaults.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,yBAAyB,EACzB,gCAAgC,EAChC,mBAAmB,EACnB,oCAAoC,EACpC,wBAAwB,GAEzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AAEnF,OAAO,EACL,yBAAyB,EACzB,gCAAgC,EAChC,mBAAmB,EACnB,oCAAoC,EACpC,wBAAwB,GACzB,MAAM,4BAA4B,CAAC;AAEpC,wFAAwF;AACxF,MAAM,UAAU,4BAA4B,CAC1C,OAAuB,uBAAuB;IAE9C,OAAO;QACL,GAAG,IAAI;QACP,IAAI,EAAE,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC;QACzC,iBAAiB,EAAE,oCAAoC,CAAC,IAAI,CAAC,iBAAiB,CAAC;KAChF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAA6B;IAC/D,SAAS,EAAE;QACT,WAAW,EAAE,GAAG;QAChB,cAAc,EAAE,GAAG;QACnB,gBAAgB,EAAE,IAAI;KACvB;IACD,eAAe,EAAE;QACf,SAAS,EAAE,CAAC;KACb;IACD,OAAO,EAAE;QACP,cAAc,EAAE,EAAE;KACnB;IACD,KAAK,EAAE;QACL,kBAAkB,EAAE,EAAE;QACtB,4BAA4B,EAAE,CAAC;QAC/B,qBAAqB,EAAE,EAAE;KAC1B;IACD,KAAK,EAAE;QACL,mBAAmB,EAAE,0BAA0B;QAC/C,OAAO,EAAE,QAAQ;QACjB,WAAW,EAAE,oBAAoB;KAClC;IACD,aAAa,EAAE;QACb,OAAO,EAAE,6BAA6B;QACtC,cAAc,EAAE,IAAI;QACpB,aAAa,EAAE,IAAI;QACnB,eAAe,EAAE,GAAG;KACrB;IACD,IAAI,EAAE,mBAAmB;IACzB,iBAAiB,EAAE,gCAAgC;IACnD,UAAU,EAAE,yBAAyB;IACrC,iBAAiB,EAAE,KAAK;CAChB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Loop escalation — FR-014, FR-008 rule #3.
|
|
2
|
+
* Loop escalation — FR-014, FR-008 rule #3 / #4.
|
|
3
3
|
*
|
|
4
4
|
* Detects bounded repeated identical tool failures and signals
|
|
5
5
|
* session pin escalation to a frontier-capable tier.
|
|
@@ -7,12 +7,27 @@
|
|
|
7
7
|
* Escalation fires once per session; no tier oscillation (FR-008).
|
|
8
8
|
* Threshold defaults to 3 identical tool failures (operator configurable).
|
|
9
9
|
*
|
|
10
|
+
* Zero-tier observational pin-break (SP-178 / #99):
|
|
11
|
+
* SAAR pins preserve prefix-cache value, but a zero-tier pin that faces
|
|
12
|
+
* unsupported/unknown tools or sustained tool-loop churn is a capability
|
|
13
|
+
* mismatch — the same class of observational signal as identical tool
|
|
14
|
+
* failures (FR-014). Escalation reuses the `loop_escalation` pin reason
|
|
15
|
+
* (allowed FR-008 break) rather than inventing a cache-economics bypass.
|
|
16
|
+
* Voluntary cross-provider switches still go through breakeven; this path
|
|
17
|
+
* only fires on observational evidence that the pinned zero-tier model
|
|
18
|
+
* cannot complete the tool loop.
|
|
19
|
+
*
|
|
10
20
|
* Design: pure evaluation function — caller (pipeline stage) is
|
|
11
21
|
* responsible for applying pin state updates via SessionPinner.
|
|
12
22
|
*/
|
|
13
23
|
import type { ModelProfile, RoutingRequest, SessionPin } from '../types/index.js';
|
|
14
24
|
export interface LoopEscalationConfig {
|
|
15
25
|
readonly threshold: number;
|
|
26
|
+
/**
|
|
27
|
+
* Tool-result turns while pinned to zero-tier before observational escalate.
|
|
28
|
+
* Defaults to `threshold` when omitted (same operator knob, no schema change).
|
|
29
|
+
*/
|
|
30
|
+
readonly zero_tier_tool_call_threshold?: number;
|
|
16
31
|
}
|
|
17
32
|
export interface LoopEscalationResult {
|
|
18
33
|
readonly shouldEscalate: boolean;
|
|
@@ -20,6 +35,8 @@ export interface LoopEscalationResult {
|
|
|
20
35
|
readonly escalationTarget: ModelProfile | null;
|
|
21
36
|
readonly reason: string;
|
|
22
37
|
}
|
|
38
|
+
/** Stable signature for zero-tier tool-call churn counting (SP-178). */
|
|
39
|
+
export declare const ZERO_TIER_TOOL_CHURN_SIGNATURE: "zt:tool_churn";
|
|
23
40
|
/**
|
|
24
41
|
* Extract a tool-failure signature from the request's messages.
|
|
25
42
|
* Returns null when the request does not carry a tool failure.
|
|
@@ -28,6 +45,11 @@ export interface LoopEscalationResult {
|
|
|
28
45
|
* carry observational failure signals (FR-014: no post-generation judging).
|
|
29
46
|
*/
|
|
30
47
|
export declare function extractToolFailureSignature(request: RoutingRequest): string | null;
|
|
48
|
+
/**
|
|
49
|
+
* True when the latest tool result reports an unsupported/unknown tool
|
|
50
|
+
* (capability mismatch — escalate immediately on zero-tier pins).
|
|
51
|
+
*/
|
|
52
|
+
export declare function isUnsupportedOrUnknownToolResult(request: RoutingRequest): boolean;
|
|
31
53
|
/**
|
|
32
54
|
* Evaluate whether the session should escalate to a higher tier.
|
|
33
55
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loop-escalation.d.ts","sourceRoot":"","sources":["../../../src/domain/pinning/loop-escalation.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"loop-escalation.d.ts","sourceRoot":"","sources":["../../../src/domain/pinning/loop-escalation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIlF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,6BAA6B,CAAC,EAAE,MAAM,CAAC;CACjD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,gBAAgB,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,EAAG,eAAwB,CAAC;AA4BvE;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAOlF;AAED;;;GAGG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAKjF;AA+GD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,UAAU,GAAG,IAAI,EACtB,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,MAAM,EAAE,oBAAoB,GAC3B,oBAAoB,CAwDtB"}
|