pi-smart-router 0.1.0 → 0.2.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/delegation-runtime.ts +12 -2
- package/README.md +55 -17
- package/dist/api/explain/router-explain.d.ts +4 -1
- package/dist/api/explain/router-explain.d.ts.map +1 -1
- package/dist/api/explain/router-explain.js +9 -9
- package/dist/api/explain/router-explain.js.map +1 -1
- package/dist/config/defaults.d.ts +4 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +10 -0
- package/dist/config/defaults.js.map +1 -1
- package/dist/domain/delegation/delegation-context.d.ts +23 -1
- package/dist/domain/delegation/delegation-context.d.ts.map +1 -1
- package/dist/domain/delegation/delegation-context.js +93 -0
- package/dist/domain/delegation/delegation-context.js.map +1 -1
- package/dist/domain/pinning/cache-breakeven.d.ts +51 -0
- package/dist/domain/pinning/cache-breakeven.d.ts.map +1 -0
- package/dist/domain/pinning/cache-breakeven.js +124 -0
- package/dist/domain/pinning/cache-breakeven.js.map +1 -0
- package/dist/domain/pinning/saar-session-state.d.ts +36 -0
- package/dist/domain/pinning/saar-session-state.d.ts.map +1 -0
- package/dist/domain/pinning/saar-session-state.js +74 -0
- package/dist/domain/pinning/saar-session-state.js.map +1 -0
- package/dist/domain/pinning/session-pinner.d.ts +35 -3
- package/dist/domain/pinning/session-pinner.d.ts.map +1 -1
- package/dist/domain/pinning/session-pinner.js +149 -1
- package/dist/domain/pinning/session-pinner.js.map +1 -1
- package/dist/domain/pipeline/router-pipeline.d.ts +15 -1
- package/dist/domain/pipeline/router-pipeline.d.ts.map +1 -1
- package/dist/domain/pipeline/router-pipeline.js +118 -6
- package/dist/domain/pipeline/router-pipeline.js.map +1 -1
- package/dist/domain/routing/tool-history-guard.d.ts +21 -5
- package/dist/domain/routing/tool-history-guard.d.ts.map +1 -1
- package/dist/domain/routing/tool-history-guard.js +77 -10
- package/dist/domain/routing/tool-history-guard.js.map +1 -1
- package/dist/domain/types/entities.d.ts +48 -0
- package/dist/domain/types/entities.d.ts.map +1 -1
- package/dist/domain/types/index.d.ts +1 -1
- package/dist/domain/types/index.d.ts.map +1 -1
- package/dist/domain/types/schemas.d.ts +24 -0
- package/dist/domain/types/schemas.d.ts.map +1 -1
- package/dist/domain/types/schemas.js +54 -0
- package/dist/domain/types/schemas.js.map +1 -1
- package/dist/infra/gemini-provider.d.ts.map +1 -1
- package/dist/infra/gemini-provider.js +2 -1
- package/dist/infra/gemini-provider.js.map +1 -1
- package/dist/infrastructure/persistence/sqlite-store.d.ts.map +1 -1
- package/dist/infrastructure/persistence/sqlite-store.js +3 -0
- package/dist/infrastructure/persistence/sqlite-store.js.map +1 -1
- package/dist/infrastructure/telemetry/routing-telemetry.d.ts +30 -2
- package/dist/infrastructure/telemetry/routing-telemetry.d.ts.map +1 -1
- package/dist/infrastructure/telemetry/routing-telemetry.js +221 -3
- package/dist/infrastructure/telemetry/routing-telemetry.js.map +1 -1
- package/package.json +5 -4
- package/src/api/explain/router-explain.ts +14 -10
- package/src/config/defaults.ts +18 -1
- package/src/domain/delegation/delegation-context.ts +124 -0
- package/src/domain/pinning/cache-breakeven.ts +219 -0
- package/src/domain/pinning/saar-session-state.ts +93 -0
- package/src/domain/pinning/session-pinner.ts +244 -3
- package/src/domain/pipeline/router-pipeline.ts +159 -7
- package/src/domain/routing/tool-history-guard.ts +108 -10
- package/src/domain/types/entities.ts +54 -0
- package/src/domain/types/index.ts +4 -0
- package/src/domain/types/schemas.ts +69 -0
- package/src/infra/gemini-provider.ts +2 -1
- package/src/infrastructure/persistence/sqlite-store.ts +6 -0
- package/src/infrastructure/telemetry/routing-telemetry.ts +327 -7
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cache breakeven economics — SAAR gate (#73), routing-roadmap P0.
|
|
3
|
+
*
|
|
4
|
+
* Decides whether a proposed tier switch is justified when a warm prefix
|
|
5
|
+
* cache would be invalidated. Switch only when:
|
|
6
|
+
*
|
|
7
|
+
* marginal_savings + future_cache_value > cache_reprime_cost
|
|
8
|
+
*
|
|
9
|
+
* Distinct from legacy FR-008 warmup rule in `cache-economics.ts` (#32).
|
|
10
|
+
*/
|
|
11
|
+
// ─── Defaults ─────────────────────────────────────────────────────────────────
|
|
12
|
+
const DEFAULT_PREFIX_CACHE_WEIGHT = 0.2;
|
|
13
|
+
const DEFAULT_PREFIX_CACHE_DISCOUNT = 0.9;
|
|
14
|
+
const TOKENS_PER_M = 1_000_000;
|
|
15
|
+
// ─── Component helpers ────────────────────────────────────────────────────────
|
|
16
|
+
function resolveSaarConfig(config) {
|
|
17
|
+
return {
|
|
18
|
+
prefixCacheWeight: config?.prefix_cache_weight ?? DEFAULT_PREFIX_CACHE_WEIGHT,
|
|
19
|
+
prefixCacheDiscount: config?.prefix_cache_discount ?? DEFAULT_PREFIX_CACHE_DISCOUNT,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function isFiniteNonNegative(value) {
|
|
23
|
+
return Number.isFinite(value) && value >= 0;
|
|
24
|
+
}
|
|
25
|
+
function isValidUsdComponent(value) {
|
|
26
|
+
return isFiniteNonNegative(value);
|
|
27
|
+
}
|
|
28
|
+
function isValidPrefixCacheWeight(weight) {
|
|
29
|
+
return Number.isFinite(weight) && weight >= 0 && weight <= 1;
|
|
30
|
+
}
|
|
31
|
+
function isValidPrefixCacheDiscount(discount) {
|
|
32
|
+
return Number.isFinite(discount) && discount >= 0 && discount <= 1;
|
|
33
|
+
}
|
|
34
|
+
function denySwitch(marginal_savings, future_cache_value, cache_reprime_cost, reason) {
|
|
35
|
+
return {
|
|
36
|
+
shouldSwitch: false,
|
|
37
|
+
marginal_savings,
|
|
38
|
+
future_cache_value,
|
|
39
|
+
cache_reprime_cost,
|
|
40
|
+
total_benefit: marginal_savings + future_cache_value,
|
|
41
|
+
reason,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Estimate the retained value of a warm prefix cache using SAAR
|
|
46
|
+
* `prefix_cache_weight`.
|
|
47
|
+
*/
|
|
48
|
+
export function computeFutureCacheValue(warm_prefix_tokens, pinned_cost_per_1m, config) {
|
|
49
|
+
if (!isFiniteNonNegative(warm_prefix_tokens) || !isFiniteNonNegative(pinned_cost_per_1m)) {
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
if (warm_prefix_tokens === 0) {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
const { prefixCacheWeight, prefixCacheDiscount } = resolveSaarConfig(config);
|
|
56
|
+
if (!isValidPrefixCacheWeight(prefixCacheWeight) || !isValidPrefixCacheDiscount(prefixCacheDiscount)) {
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
const prefixCostUsd = (warm_prefix_tokens / TOKENS_PER_M) * pinned_cost_per_1m;
|
|
60
|
+
const discountedValueUsd = prefixCostUsd * prefixCacheDiscount;
|
|
61
|
+
return discountedValueUsd * prefixCacheWeight;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Cost to re-transmit a cold prefix on the candidate provider after a switch.
|
|
65
|
+
*/
|
|
66
|
+
export function computeCacheReprimeCost(warm_prefix_tokens, candidate_cost_per_1m) {
|
|
67
|
+
if (!isFiniteNonNegative(warm_prefix_tokens) || !isFiniteNonNegative(candidate_cost_per_1m)) {
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
if (warm_prefix_tokens === 0) {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
return (warm_prefix_tokens / TOKENS_PER_M) * candidate_cost_per_1m;
|
|
74
|
+
}
|
|
75
|
+
// ─── Evaluation ───────────────────────────────────────────────────────────────
|
|
76
|
+
/**
|
|
77
|
+
* Evaluate whether a proposed switch clears the cache breakeven gate.
|
|
78
|
+
*
|
|
79
|
+
* Returns `shouldSwitch: false` on invalid inputs (fail-safe deny).
|
|
80
|
+
*/
|
|
81
|
+
export function evaluateCacheBreakeven(marginal_savings, future_cache_value, cache_reprime_cost) {
|
|
82
|
+
if (!isValidUsdComponent(marginal_savings) ||
|
|
83
|
+
!isValidUsdComponent(future_cache_value) ||
|
|
84
|
+
!isValidUsdComponent(cache_reprime_cost)) {
|
|
85
|
+
return denySwitch(marginal_savings, future_cache_value, cache_reprime_cost, 'invalid_input');
|
|
86
|
+
}
|
|
87
|
+
const total_benefit = marginal_savings + future_cache_value;
|
|
88
|
+
if (total_benefit <= cache_reprime_cost) {
|
|
89
|
+
return {
|
|
90
|
+
shouldSwitch: false,
|
|
91
|
+
marginal_savings,
|
|
92
|
+
future_cache_value,
|
|
93
|
+
cache_reprime_cost,
|
|
94
|
+
total_benefit,
|
|
95
|
+
reason: 'breakeven_not_met',
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
shouldSwitch: true,
|
|
100
|
+
marginal_savings,
|
|
101
|
+
future_cache_value,
|
|
102
|
+
cache_reprime_cost,
|
|
103
|
+
total_benefit,
|
|
104
|
+
reason: 'breakeven_pass',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Derive breakeven components from prefix token economics, then evaluate.
|
|
109
|
+
*/
|
|
110
|
+
export function evaluateCacheBreakevenForPrefix(marginal_savings, warm_prefix_tokens, pinned_cost_per_1m, candidate_cost_per_1m, config) {
|
|
111
|
+
const { prefixCacheWeight, prefixCacheDiscount } = resolveSaarConfig(config);
|
|
112
|
+
if (!isValidUsdComponent(marginal_savings) ||
|
|
113
|
+
!isFiniteNonNegative(warm_prefix_tokens) ||
|
|
114
|
+
!isFiniteNonNegative(pinned_cost_per_1m) ||
|
|
115
|
+
!isFiniteNonNegative(candidate_cost_per_1m) ||
|
|
116
|
+
!isValidPrefixCacheWeight(prefixCacheWeight) ||
|
|
117
|
+
!isValidPrefixCacheDiscount(prefixCacheDiscount)) {
|
|
118
|
+
return denySwitch(marginal_savings, 0, 0, 'invalid_input');
|
|
119
|
+
}
|
|
120
|
+
const future_cache_value = computeFutureCacheValue(warm_prefix_tokens, pinned_cost_per_1m, config);
|
|
121
|
+
const cache_reprime_cost = computeCacheReprimeCost(warm_prefix_tokens, candidate_cost_per_1m);
|
|
122
|
+
return evaluateCacheBreakeven(marginal_savings, future_cache_value, cache_reprime_cost);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=cache-breakeven.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-breakeven.js","sourceRoot":"","sources":["../../../src/domain/pinning/cache-breakeven.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SAAR per-session state tracker (SP-122, #72).
|
|
3
|
+
*
|
|
4
|
+
* Tracks turn index, planning buffer window, hard-lock, and idle timeout
|
|
5
|
+
* per Session-Aware Agentic Routing semantics.
|
|
6
|
+
*/
|
|
7
|
+
import type { SaarConfig, SaarSessionState } from '../types/index.js';
|
|
8
|
+
export interface SaarSessionStateTrackerOptions {
|
|
9
|
+
readonly config: SaarConfig;
|
|
10
|
+
readonly initial?: Partial<SaarSessionState>;
|
|
11
|
+
/** Injectable clock for tests. */
|
|
12
|
+
readonly now?: () => number;
|
|
13
|
+
}
|
|
14
|
+
export declare class SaarSessionStateTracker {
|
|
15
|
+
private state;
|
|
16
|
+
private readonly config;
|
|
17
|
+
private readonly now;
|
|
18
|
+
constructor(options: SaarSessionStateTrackerOptions);
|
|
19
|
+
getState(): Readonly<SaarSessionState>;
|
|
20
|
+
/**
|
|
21
|
+
* Advance turn index after a routed turn and refresh hard-lock.
|
|
22
|
+
* Hard-lock engages once turn_index reaches planning_turn_buffer.
|
|
23
|
+
*/
|
|
24
|
+
recordTurn(): SaarSessionState;
|
|
25
|
+
/** Turns 0..(planning_turn_buffer - 1) are inside the planning buffer. */
|
|
26
|
+
isInBufferWindow(): boolean;
|
|
27
|
+
/** True after the planning buffer has been exhausted. */
|
|
28
|
+
shouldHardLock(): boolean;
|
|
29
|
+
/** True when idle time since last activity exceeds configured timeout. */
|
|
30
|
+
isIdleExpired(): boolean;
|
|
31
|
+
/** Reset SAAR weight and reopen routing after idle timeout. */
|
|
32
|
+
resetForIdleReopen(): SaarSessionState;
|
|
33
|
+
/** Refresh last-activity without advancing turn index. */
|
|
34
|
+
touchActivity(): void;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=saar-session-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saar-session-state.d.ts","sourceRoot":"","sources":["../../../src/domain/pinning/saar-session-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEtE,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC7C,kCAAkC;IAClC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAMD,qBAAa,uBAAuB;IAClC,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,EAAE,8BAA8B;IAYnD,QAAQ,IAAI,QAAQ,CAAC,gBAAgB,CAAC;IAItC;;;OAGG;IACH,UAAU,IAAI,gBAAgB;IAU9B,0EAA0E;IAC1E,gBAAgB,IAAI,OAAO;IAI3B,yDAAyD;IACzD,cAAc,IAAI,OAAO;IAIzB,0EAA0E;IAC1E,aAAa,IAAI,OAAO;IASxB,+DAA+D;IAC/D,kBAAkB,IAAI,gBAAgB;IAStC,0DAA0D;IAC1D,aAAa,IAAI,IAAI;CAMtB"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SAAR per-session state tracker (SP-122, #72).
|
|
3
|
+
*
|
|
4
|
+
* Tracks turn index, planning buffer window, hard-lock, and idle timeout
|
|
5
|
+
* per Session-Aware Agentic Routing semantics.
|
|
6
|
+
*/
|
|
7
|
+
function toIso(ms) {
|
|
8
|
+
return new Date(ms).toISOString();
|
|
9
|
+
}
|
|
10
|
+
export class SaarSessionStateTracker {
|
|
11
|
+
state;
|
|
12
|
+
config;
|
|
13
|
+
now;
|
|
14
|
+
constructor(options) {
|
|
15
|
+
const clock = options.now ?? (() => Date.now());
|
|
16
|
+
this.now = clock;
|
|
17
|
+
this.config = options.config;
|
|
18
|
+
this.state = {
|
|
19
|
+
turn_index: options.initial?.turn_index ?? 0,
|
|
20
|
+
hard_lock: options.initial?.hard_lock ?? false,
|
|
21
|
+
last_activity_at: options.initial?.last_activity_at ?? toIso(clock()),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
getState() {
|
|
25
|
+
return this.state;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Advance turn index after a routed turn and refresh hard-lock.
|
|
29
|
+
* Hard-lock engages once turn_index reaches planning_turn_buffer.
|
|
30
|
+
*/
|
|
31
|
+
recordTurn() {
|
|
32
|
+
const nextIndex = this.state.turn_index + 1;
|
|
33
|
+
this.state = {
|
|
34
|
+
turn_index: nextIndex,
|
|
35
|
+
hard_lock: nextIndex >= this.config.planning_turn_buffer,
|
|
36
|
+
last_activity_at: toIso(this.now()),
|
|
37
|
+
};
|
|
38
|
+
return this.state;
|
|
39
|
+
}
|
|
40
|
+
/** Turns 0..(planning_turn_buffer - 1) are inside the planning buffer. */
|
|
41
|
+
isInBufferWindow() {
|
|
42
|
+
return this.state.turn_index < this.config.planning_turn_buffer;
|
|
43
|
+
}
|
|
44
|
+
/** True after the planning buffer has been exhausted. */
|
|
45
|
+
shouldHardLock() {
|
|
46
|
+
return this.state.hard_lock;
|
|
47
|
+
}
|
|
48
|
+
/** True when idle time since last activity exceeds configured timeout. */
|
|
49
|
+
isIdleExpired() {
|
|
50
|
+
const lastMs = Date.parse(this.state.last_activity_at);
|
|
51
|
+
if (Number.isNaN(lastMs)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
const idleMs = this.config.idle_timeout_seconds * 1000;
|
|
55
|
+
return this.now() - lastMs >= idleMs;
|
|
56
|
+
}
|
|
57
|
+
/** Reset SAAR weight and reopen routing after idle timeout. */
|
|
58
|
+
resetForIdleReopen() {
|
|
59
|
+
this.state = {
|
|
60
|
+
turn_index: 0,
|
|
61
|
+
hard_lock: false,
|
|
62
|
+
last_activity_at: toIso(this.now()),
|
|
63
|
+
};
|
|
64
|
+
return this.state;
|
|
65
|
+
}
|
|
66
|
+
/** Refresh last-activity without advancing turn index. */
|
|
67
|
+
touchActivity() {
|
|
68
|
+
this.state = {
|
|
69
|
+
...this.state,
|
|
70
|
+
last_activity_at: toIso(this.now()),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=saar-session-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"saar-session-state.js","sourceRoot":"","sources":["../../../src/domain/pinning/saar-session-state.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,OAAO,uBAAuB;IAC1B,KAAK,CAAmB;IACf,MAAM,CAAa;IACnB,GAAG,CAAe;IAEnC,YAAY,OAAuC;QACjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,GAAG,KAAK,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,OAAO,CAAC,OAAO,EAAE,UAAU,IAAI,CAAC;YAC5C,SAAS,EAAE,OAAO,CAAC,OAAO,EAAE,SAAS,IAAI,KAAK;YAC9C,gBAAgB,EACd,OAAO,CAAC,OAAO,EAAE,gBAAgB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;SACtD,CAAC;IACJ,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;OAGG;IACH,UAAU;QACR,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB;YACxD,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;SACpC,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,0EAA0E;IAC1E,gBAAgB;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC;IAClE,CAAC;IAED,yDAAyD;IACzD,cAAc;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;IAC9B,CAAC;IAED,0EAA0E;IAC1E,aAAa;QACX,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACvD,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACzB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,IAAI,CAAC;QACvD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,IAAI,MAAM,CAAC;IACvC,CAAC;IAED,+DAA+D;IAC/D,kBAAkB;QAChB,IAAI,CAAC,KAAK,GAAG;YACX,UAAU,EAAE,CAAC;YACb,SAAS,EAAE,KAAK;YAChB,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;SACpC,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,0DAA0D;IAC1D,aAAa;QACX,IAAI,CAAC,KAAK,GAAG;YACX,GAAG,IAAI,CAAC,KAAK;YACb,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;SACpC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -14,14 +14,18 @@
|
|
|
14
14
|
* Sub-routing (FR-024): tool-result turns below the payload threshold
|
|
15
15
|
* may use an economical model on the same provider without breaking the pin.
|
|
16
16
|
*/
|
|
17
|
-
import type { ModelProfile, PinReason, RoutingRequest, SessionPin } from '../types/index.js';
|
|
17
|
+
import type { ModelProfile, PinReason, RoutingRequest, SaarConfig, SaarSessionState, SessionPin } from '../types/index.js';
|
|
18
18
|
import type { StorePort } from '../types/store-port.js';
|
|
19
19
|
import { type CacheEconomicsConfig } from './cache-economics.js';
|
|
20
|
-
|
|
20
|
+
import { type CacheBreakevenResult } from './cache-breakeven.js';
|
|
21
|
+
export type PinAction = 'use_pin' | 'sub_route' | 'saar_route' | 'break' | 'no_pin';
|
|
22
|
+
export type PinSaarReason = 'saar_buffer_active' | 'saar_hard_lock' | 'saar_idle_reopen' | 'saar_tier_upgrade';
|
|
21
23
|
export interface PinLookupResult {
|
|
22
24
|
readonly action: PinAction;
|
|
23
25
|
readonly pinnedModel?: ModelProfile;
|
|
24
26
|
readonly subRouteModel?: ModelProfile;
|
|
27
|
+
readonly saarRouteModel?: ModelProfile;
|
|
28
|
+
readonly saarReason?: PinSaarReason;
|
|
25
29
|
readonly breakReason?: PinReason;
|
|
26
30
|
}
|
|
27
31
|
export interface SessionPinnerConfig {
|
|
@@ -29,19 +33,38 @@ export interface SessionPinnerConfig {
|
|
|
29
33
|
readonly toolResultSizeThreshold?: number;
|
|
30
34
|
/** Optional persistence — pins survive process restart when set. */
|
|
31
35
|
readonly store?: StorePort;
|
|
32
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* FR-008 rule #4: cache-warmup economics thresholds.
|
|
38
|
+
*/
|
|
33
39
|
readonly cacheEconomicsConfig?: CacheEconomicsConfig;
|
|
40
|
+
/** SAAR pin policy (SP-122). When omitted, SAAR behavior is disabled. */
|
|
41
|
+
readonly saarConfig?: SaarConfig;
|
|
42
|
+
/** Injectable clock for SAAR idle-timeout tests. */
|
|
43
|
+
readonly saarClock?: () => number;
|
|
34
44
|
/**
|
|
35
45
|
* Break pin when estimated input tokens exceed the pinned model's
|
|
36
46
|
* max_input_tokens multiplied by this margin. Default 0.90.
|
|
37
47
|
*/
|
|
38
48
|
readonly contextOverflowSafetyMargin?: number;
|
|
39
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Per-turn marginal savings from switching pinned → candidate on this request.
|
|
52
|
+
* Uses full estimated input (same basis as cache-economics per-turn savings).
|
|
53
|
+
*/
|
|
54
|
+
export declare function computeMarginalSwitchSavings(pinnedModel: ModelProfile, candidateModel: ModelProfile, estimatedInputTokens: number): number;
|
|
55
|
+
/**
|
|
56
|
+
* SAAR cache breakeven gate (#73) — shared by turn_envelope and session_pin.
|
|
57
|
+
* `warmPrefixTokens` is 0 on cold sessions (no pin); otherwise the warm prefix size.
|
|
58
|
+
*/
|
|
59
|
+
export declare function evaluateModelSwitchBreakeven(pinnedModel: ModelProfile, candidateModel: ModelProfile, estimatedInputTokens: number, warmPrefixTokens: number, saarConfig?: SaarConfig): CacheBreakevenResult;
|
|
40
60
|
export declare class SessionPinner {
|
|
41
61
|
private readonly pins;
|
|
62
|
+
private readonly saarTrackers;
|
|
42
63
|
private readonly toolResultSizeThreshold;
|
|
43
64
|
private readonly store;
|
|
44
65
|
private readonly cacheEconomicsConfig;
|
|
66
|
+
private readonly saarConfig;
|
|
67
|
+
private readonly saarClock;
|
|
45
68
|
private readonly contextOverflowSafetyMargin;
|
|
46
69
|
constructor(config?: SessionPinnerConfig);
|
|
47
70
|
/**
|
|
@@ -62,6 +85,13 @@ export declare class SessionPinner {
|
|
|
62
85
|
* Delete a session pin — used by loop escalation or external callers.
|
|
63
86
|
*/
|
|
64
87
|
breakPin(sessionId: string): void;
|
|
88
|
+
/**
|
|
89
|
+
* Record a completed turn for SAAR turn-index and hard-lock tracking.
|
|
90
|
+
* Pipeline callers invoke after routing (SP-123).
|
|
91
|
+
*/
|
|
92
|
+
recordSaarTurn(sessionId: string): SaarSessionState | null;
|
|
93
|
+
/** Read-only SAAR runtime state for telemetry (SP-126). */
|
|
94
|
+
getSaarState(sessionId: string): SaarSessionState | null;
|
|
65
95
|
/**
|
|
66
96
|
* Hydrate a pin from persistent storage (e.g. SQLite restore).
|
|
67
97
|
*/
|
|
@@ -70,6 +100,8 @@ export declare class SessionPinner {
|
|
|
70
100
|
* Read-only access to the current pin (telemetry, inspection).
|
|
71
101
|
*/
|
|
72
102
|
getPin(sessionId: string): SessionPin | null;
|
|
103
|
+
private getOrCreateSaarTracker;
|
|
104
|
+
private evaluateSaarPolicy;
|
|
73
105
|
private evaluateBreakRules;
|
|
74
106
|
private evaluateContextOverflowBreak;
|
|
75
107
|
private evaluateCacheEconomicsBreak;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-pinner.d.ts","sourceRoot":"","sources":["../../../src/domain/pinning/session-pinner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,
|
|
1
|
+
{"version":3,"file":"session-pinner.d.ts","sourceRoot":"","sources":["../../../src/domain/pinning/session-pinner.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,22 +14,75 @@
|
|
|
14
14
|
* Sub-routing (FR-024): tool-result turns below the payload threshold
|
|
15
15
|
* may use an economical model on the same provider without breaking the pin.
|
|
16
16
|
*/
|
|
17
|
+
import { DEFAULT_SAAR_CONFIG } from '../types/schemas.js';
|
|
17
18
|
import { evaluateCacheEconomics, } from './cache-economics.js';
|
|
19
|
+
import { evaluateCacheBreakevenForPrefix, } from './cache-breakeven.js';
|
|
20
|
+
import { SaarSessionStateTracker } from './saar-session-state.js';
|
|
18
21
|
// ─── Defaults ─────────────────────────────────────────────────────────────────
|
|
19
22
|
const DEFAULT_TOOL_RESULT_SIZE_THRESHOLD = 2048;
|
|
20
23
|
const DEFAULT_CONTEXT_OVERFLOW_SAFETY_MARGIN = 0.9;
|
|
24
|
+
const TIER_RANK = {
|
|
25
|
+
'zero-tier': 0,
|
|
26
|
+
'economical-cloud': 1,
|
|
27
|
+
'frontier-cloud': 2,
|
|
28
|
+
};
|
|
29
|
+
function isTierUpgrade(from, to) {
|
|
30
|
+
return TIER_RANK[to] > TIER_RANK[from];
|
|
31
|
+
}
|
|
32
|
+
function isToolLoopTurn(turnType) {
|
|
33
|
+
return turnType === 'main_loop' || turnType === 'tool_result';
|
|
34
|
+
}
|
|
35
|
+
const TOKENS_PER_M = 1_000_000;
|
|
36
|
+
/**
|
|
37
|
+
* Per-turn marginal savings from switching pinned → candidate on this request.
|
|
38
|
+
* Uses full estimated input (same basis as cache-economics per-turn savings).
|
|
39
|
+
*/
|
|
40
|
+
export function computeMarginalSwitchSavings(pinnedModel, candidateModel, estimatedInputTokens) {
|
|
41
|
+
if (!Number.isFinite(estimatedInputTokens) || estimatedInputTokens < 0) {
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
return (((pinnedModel.pricing.fallback_cost_per_1m -
|
|
45
|
+
candidateModel.pricing.fallback_cost_per_1m) *
|
|
46
|
+
estimatedInputTokens) /
|
|
47
|
+
TOKENS_PER_M);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* SAAR cache breakeven gate (#73) — shared by turn_envelope and session_pin.
|
|
51
|
+
* `warmPrefixTokens` is 0 on cold sessions (no pin); otherwise the warm prefix size.
|
|
52
|
+
*/
|
|
53
|
+
export function evaluateModelSwitchBreakeven(pinnedModel, candidateModel, estimatedInputTokens, warmPrefixTokens, saarConfig) {
|
|
54
|
+
if (pinnedModel.id === candidateModel.id) {
|
|
55
|
+
return {
|
|
56
|
+
shouldSwitch: true,
|
|
57
|
+
marginal_savings: 0,
|
|
58
|
+
future_cache_value: 0,
|
|
59
|
+
cache_reprime_cost: 0,
|
|
60
|
+
total_benefit: 0,
|
|
61
|
+
reason: 'breakeven_pass',
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const marginal_savings = computeMarginalSwitchSavings(pinnedModel, candidateModel, estimatedInputTokens);
|
|
65
|
+
return evaluateCacheBreakevenForPrefix(marginal_savings, warmPrefixTokens, pinnedModel.pricing.fallback_cost_per_1m, candidateModel.pricing.fallback_cost_per_1m, saarConfig
|
|
66
|
+
? { prefix_cache_weight: saarConfig.prefix_cache_weight }
|
|
67
|
+
: undefined);
|
|
68
|
+
}
|
|
21
69
|
// ─── SessionPinner ────────────────────────────────────────────────────────────
|
|
22
70
|
export class SessionPinner {
|
|
23
71
|
pins = new Map();
|
|
72
|
+
saarTrackers = new Map();
|
|
24
73
|
toolResultSizeThreshold;
|
|
25
74
|
store;
|
|
26
75
|
cacheEconomicsConfig;
|
|
76
|
+
saarConfig;
|
|
77
|
+
saarClock;
|
|
27
78
|
contextOverflowSafetyMargin;
|
|
28
79
|
constructor(config) {
|
|
29
80
|
this.toolResultSizeThreshold =
|
|
30
81
|
config?.toolResultSizeThreshold ?? DEFAULT_TOOL_RESULT_SIZE_THRESHOLD;
|
|
31
82
|
this.store = config?.store;
|
|
32
83
|
this.cacheEconomicsConfig = config?.cacheEconomicsConfig;
|
|
84
|
+
this.saarConfig = config?.saarConfig;
|
|
85
|
+
this.saarClock = config?.saarClock;
|
|
33
86
|
this.contextOverflowSafetyMargin =
|
|
34
87
|
config?.contextOverflowSafetyMargin ?? DEFAULT_CONTEXT_OVERFLOW_SAFETY_MARGIN;
|
|
35
88
|
}
|
|
@@ -60,6 +113,11 @@ export class SessionPinner {
|
|
|
60
113
|
if (breakResult) {
|
|
61
114
|
return breakResult;
|
|
62
115
|
}
|
|
116
|
+
// ── SAAR policy (SP-122) ────────────────────────────────────────────────
|
|
117
|
+
const saarResult = this.evaluateSaarPolicy(request, pin, fleet);
|
|
118
|
+
if (saarResult) {
|
|
119
|
+
return saarResult;
|
|
120
|
+
}
|
|
63
121
|
// ── Sub-routing (FR-024) ────────────────────────────────────────────────
|
|
64
122
|
const subRouteResult = this.evaluateSubRouting(request, pin, fleet);
|
|
65
123
|
if (subRouteResult) {
|
|
@@ -101,8 +159,24 @@ export class SessionPinner {
|
|
|
101
159
|
*/
|
|
102
160
|
breakPin(sessionId) {
|
|
103
161
|
this.pins.delete(sessionId);
|
|
162
|
+
this.saarTrackers.delete(sessionId);
|
|
104
163
|
this.deletePersistedPin(sessionId);
|
|
105
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Record a completed turn for SAAR turn-index and hard-lock tracking.
|
|
167
|
+
* Pipeline callers invoke after routing (SP-123).
|
|
168
|
+
*/
|
|
169
|
+
recordSaarTurn(sessionId) {
|
|
170
|
+
if (!this.saarConfig) {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const tracker = this.getOrCreateSaarTracker(sessionId);
|
|
174
|
+
return tracker.recordTurn();
|
|
175
|
+
}
|
|
176
|
+
/** Read-only SAAR runtime state for telemetry (SP-126). */
|
|
177
|
+
getSaarState(sessionId) {
|
|
178
|
+
return this.saarTrackers.get(sessionId)?.getState() ?? null;
|
|
179
|
+
}
|
|
106
180
|
/**
|
|
107
181
|
* Hydrate a pin from persistent storage (e.g. SQLite restore).
|
|
108
182
|
*/
|
|
@@ -116,6 +190,71 @@ export class SessionPinner {
|
|
|
116
190
|
getPin(sessionId) {
|
|
117
191
|
return this.pins.get(sessionId) ?? null;
|
|
118
192
|
}
|
|
193
|
+
// ─── SAAR policy (SP-122) ─────────────────────────────────────────────────
|
|
194
|
+
getOrCreateSaarTracker(sessionId) {
|
|
195
|
+
let tracker = this.saarTrackers.get(sessionId);
|
|
196
|
+
if (!tracker) {
|
|
197
|
+
const options = {
|
|
198
|
+
config: this.saarConfig ?? DEFAULT_SAAR_CONFIG,
|
|
199
|
+
};
|
|
200
|
+
if (this.saarClock) {
|
|
201
|
+
options.now = this.saarClock;
|
|
202
|
+
}
|
|
203
|
+
tracker = new SaarSessionStateTracker(options);
|
|
204
|
+
this.saarTrackers.set(sessionId, tracker);
|
|
205
|
+
}
|
|
206
|
+
return tracker;
|
|
207
|
+
}
|
|
208
|
+
evaluateSaarPolicy(request, pin, fleet) {
|
|
209
|
+
if (!this.saarConfig) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const tracker = this.getOrCreateSaarTracker(request.session_id);
|
|
213
|
+
if (tracker.isIdleExpired()) {
|
|
214
|
+
tracker.resetForIdleReopen();
|
|
215
|
+
this.breakPin(request.session_id);
|
|
216
|
+
return { action: 'no_pin', saarReason: 'saar_idle_reopen' };
|
|
217
|
+
}
|
|
218
|
+
tracker.touchActivity();
|
|
219
|
+
const pinnedModel = fleet.find((m) => m.id === pin.pinned_model_id && m.healthy !== false);
|
|
220
|
+
if (!pinnedModel) {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
const candidate = request.candidate_model_id
|
|
224
|
+
? fleet.find((m) => m.id === request.candidate_model_id && m.healthy !== false)
|
|
225
|
+
: undefined;
|
|
226
|
+
if (tracker.isInBufferWindow() && candidate) {
|
|
227
|
+
if (isTierUpgrade(pinnedModel.tier, candidate.tier)) {
|
|
228
|
+
return {
|
|
229
|
+
action: 'saar_route',
|
|
230
|
+
pinnedModel,
|
|
231
|
+
saarRouteModel: candidate,
|
|
232
|
+
saarReason: 'saar_buffer_active',
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (tracker.shouldHardLock()) {
|
|
237
|
+
if (isToolLoopTurn(request.turn_type) &&
|
|
238
|
+
candidate &&
|
|
239
|
+
isTierUpgrade(pinnedModel.tier, candidate.tier)) {
|
|
240
|
+
this.recordPin(request.session_id, candidate.id, pin.pin_reason);
|
|
241
|
+
const upgraded = fleet.find((m) => m.id === candidate.id);
|
|
242
|
+
return {
|
|
243
|
+
action: 'use_pin',
|
|
244
|
+
pinnedModel: upgraded,
|
|
245
|
+
saarReason: 'saar_tier_upgrade',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
if (candidate && candidate.id !== pin.pinned_model_id) {
|
|
249
|
+
return {
|
|
250
|
+
action: 'use_pin',
|
|
251
|
+
pinnedModel,
|
|
252
|
+
saarReason: 'saar_hard_lock',
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
119
258
|
// ─── Break rules (FR-008) ───────────────────────────────────────────────────
|
|
120
259
|
evaluateBreakRules(request, pin, fleet) {
|
|
121
260
|
// 1. History compaction → break pin, allow full re-route
|
|
@@ -175,10 +314,14 @@ export class SessionPinner {
|
|
|
175
314
|
const tokenEstimate = request.estimated_input_tokens ?? request.prompt_text.length;
|
|
176
315
|
const econ = evaluateCacheEconomics(pin, pinnedModel, candidate, tokenEstimate, this.cacheEconomicsConfig);
|
|
177
316
|
if (econ.shouldSwitch) {
|
|
317
|
+
const breakeven = evaluateModelSwitchBreakeven(pinnedModel, candidate, tokenEstimate, tokenEstimate, this.saarConfig);
|
|
318
|
+
if (!breakeven.shouldSwitch) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
178
321
|
this.breakPin(request.session_id);
|
|
179
322
|
return { action: 'break', breakReason: 'cache_economics' };
|
|
180
323
|
}
|
|
181
|
-
return
|
|
324
|
+
return null;
|
|
182
325
|
}
|
|
183
326
|
handleForceOverride(request, _pin, fleet) {
|
|
184
327
|
const forced = fleet.find((m) => m.id === request.force_model_id && m.healthy !== false);
|
|
@@ -227,6 +370,11 @@ export class SessionPinner {
|
|
|
227
370
|
if (!econModel) {
|
|
228
371
|
return null;
|
|
229
372
|
}
|
|
373
|
+
const tokenEstimate = request.estimated_input_tokens ?? request.prompt_text.length;
|
|
374
|
+
const breakeven = evaluateModelSwitchBreakeven(pinnedModel, econModel, tokenEstimate, tokenEstimate, this.saarConfig);
|
|
375
|
+
if (!breakeven.shouldSwitch) {
|
|
376
|
+
return null;
|
|
377
|
+
}
|
|
230
378
|
return {
|
|
231
379
|
action: 'sub_route',
|
|
232
380
|
subRouteModel: econModel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-pinner.js","sourceRoot":"","sources":["../../../src/domain/pinning/session-pinner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-pinner.js","sourceRoot":"","sources":["../../../src/domain/pinning/session-pinner.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* → safe_default → context_overflow_fallback
|
|
9
9
|
* Any stage failure falls back to safeCloudDefault(); never throws to host.
|
|
10
10
|
*/
|
|
11
|
-
import type { ModelProfile, PriceCatalog, RoutingDecision, RoutingRequest, Tier } from '../types/index.js';
|
|
11
|
+
import type { ModelProfile, PriceCatalog, RoutingDecision, RoutingRequest, SaarConfig, Tier } from '../types/index.js';
|
|
12
12
|
import type { LowIntensityConfig } from '../types/schemas.js';
|
|
13
13
|
import type { HardwareProbeConfig, SystemInfo } from '../../infrastructure/hardware/hardware-probe.js';
|
|
14
14
|
import type { HttpFetchPort, LocalZeroTierConfig } from '../../infrastructure/local/local-zero-tier.js';
|
|
@@ -62,6 +62,8 @@ export interface PipelineOptions {
|
|
|
62
62
|
/** Preloaded P(success) weights for tests; lazy-loads artifact when omitted (SP-105). */
|
|
63
63
|
readonly pSuccessWeights?: PSuccessWeights;
|
|
64
64
|
readonly pSuccessWeightsPath?: string;
|
|
65
|
+
/** SAAR pin policy (SP-123). Must match sessionPinner.saarConfig when enabled. */
|
|
66
|
+
readonly saarConfig?: SaarConfig;
|
|
65
67
|
}
|
|
66
68
|
export declare class RouterPipeline {
|
|
67
69
|
private readonly stages;
|
|
@@ -89,6 +91,8 @@ export declare class RouterPipeline {
|
|
|
89
91
|
private currentContextFitViableCount;
|
|
90
92
|
private contextOverflowPreferredProvider;
|
|
91
93
|
private contextOverflowTriggered;
|
|
94
|
+
/** Internal breakeven gate reason for SP-126 explain wiring. */
|
|
95
|
+
private currentBreakevenReason;
|
|
92
96
|
constructor(fleet: readonly ModelProfile[], options?: PipelineOptions);
|
|
93
97
|
route(request: RoutingRequest, fleetOverride?: readonly ModelProfile[]): Promise<RoutingDecision>;
|
|
94
98
|
/**
|
|
@@ -144,6 +148,16 @@ export declare class RouterPipeline {
|
|
|
144
148
|
* Sub-routes and already-pinned decisions skip persistence.
|
|
145
149
|
*/
|
|
146
150
|
private persistPinIfNeeded;
|
|
151
|
+
/** Persist pin updates and advance SAAR turn index after each routed turn (SP-123). */
|
|
152
|
+
private finalizeRoute;
|
|
153
|
+
private recordSaarTurnIfNeeded;
|
|
154
|
+
private enrichRequestWithSaarCandidate;
|
|
155
|
+
private shouldDeferPlanningForSaar;
|
|
156
|
+
/**
|
|
157
|
+
* SP-123: SAAR planning buffer explicitly allows frontier planning turns
|
|
158
|
+
* without breakeven gating (#73 composes with buffer, not replaces it).
|
|
159
|
+
*/
|
|
160
|
+
private isSaarPlanningBufferActive;
|
|
147
161
|
private static readonly TURN_TIER_MAP;
|
|
148
162
|
private turnEnvelope;
|
|
149
163
|
/**
|