heor-agent-mcp 1.10.1 → 1.11.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/README.md +2 -2
- package/dist/analytics.d.ts +18 -4
- package/dist/analytics.d.ts.map +1 -1
- package/dist/analytics.js +22 -6
- package/dist/analytics.js.map +1 -1
- package/dist/data/mfnBasket.d.ts +69 -0
- package/dist/data/mfnBasket.d.ts.map +1 -0
- package/dist/data/mfnBasket.js +130 -0
- package/dist/data/mfnBasket.js.map +1 -0
- package/dist/models/mfnSensitivity.d.ts +81 -0
- package/dist/models/mfnSensitivity.d.ts.map +1 -0
- package/dist/models/mfnSensitivity.js +104 -0
- package/dist/models/mfnSensitivity.js.map +1 -0
- package/dist/providers/types.d.ts +31 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/server.js +28 -5
- package/dist/server.js.map +1 -1
- package/dist/tools/costEffectivenessModel.d.ts.map +1 -1
- package/dist/tools/costEffectivenessModel.js +68 -0
- package/dist/tools/costEffectivenessModel.js.map +1 -1
- package/dist/tools/htaDossierPrep.d.ts.map +1 -1
- package/dist/tools/htaDossierPrep.js +139 -0
- package/dist/tools/htaDossierPrep.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,7 +45,7 @@ curl -s http://localhost:8080/health
|
|
|
45
45
|
Expected output:
|
|
46
46
|
|
|
47
47
|
```json
|
|
48
|
-
{"status":"ok","server":"heor-agent-mcp","version":"1.
|
|
48
|
+
{"status":"ok","server":"heor-agent-mcp","version":"1.10.2"}
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
✅ If you see the JSON above, the npm package works on your machine. Any further issues are in your MCP client config (Claude Desktop / Cursor / Continue), not the server.
|
|
@@ -126,7 +126,7 @@ The first prompt exercises `literature_search` + `validate_links` (free, no API
|
|
|
126
126
|
|
|
127
127
|
## What's new
|
|
128
128
|
|
|
129
|
-
See [CHANGELOG.md](./CHANGELOG.md) for full version history. Current: **v1.
|
|
129
|
+
See [CHANGELOG.md](./CHANGELOG.md) for full version history. Current: **v1.10.2** (28 tools, 44 data sources).
|
|
130
130
|
|
|
131
131
|
### v1.0.4 highlights (still in v1.6.3)
|
|
132
132
|
|
package/dist/analytics.d.ts
CHANGED
|
@@ -9,17 +9,31 @@ export type ClientSurface = "claude_anthropic_web" | "chatgpt_adapter" | "claude
|
|
|
9
9
|
export declare function inferSurface(clientName: string | undefined): ClientSurface;
|
|
10
10
|
export declare function trackEvent(event: string, properties?: Record<string, unknown>, sessionId?: string): void;
|
|
11
11
|
/**
|
|
12
|
-
* Extracts structured analytics properties from a thrown value.
|
|
13
|
-
* returns the same two property names so PostHog dashboards can query
|
|
14
|
-
* `properties.error_class` and `properties.error_message` reliably.
|
|
12
|
+
* Extracts structured analytics properties from a thrown value.
|
|
15
13
|
*
|
|
16
|
-
*
|
|
14
|
+
* Returns THREE fields so callers can pick the right one for each surface:
|
|
15
|
+
* - `error_class` — constructor/category name, stable for dashboards
|
|
16
|
+
* - `error_message` — FULL message, no truncation. Use this for the
|
|
17
|
+
* client-facing response so callers (including the
|
|
18
|
+
* ChatGPT Custom GPT) see the complete validation
|
|
19
|
+
* feedback and can recover in-conversation.
|
|
20
|
+
* - `telemetry_message` — same message capped at 500 chars. Use this for
|
|
21
|
+
* PostHog `properties.error_message` so we don't
|
|
22
|
+
* blow up event payload size on a 50KB ZodError.
|
|
23
|
+
*
|
|
24
|
+
* Why we split these (added v1.10.2): pre-v1.10.2 the capped field doubled
|
|
25
|
+
* as the client response (server.ts:475), so ChatGPT received a JSON
|
|
26
|
+
* ZodError truncated mid-key and could not recover. The 500-char cap was
|
|
27
|
+
* a telemetry-hygiene decision that quietly broke the response surface.
|
|
28
|
+
*
|
|
29
|
+
* - Error subclasses → constructor name + full message
|
|
17
30
|
* - Strings / numbers / null → class="unknown", message=stringified
|
|
18
31
|
* - Circular objects / weird values → class="unknown", message=safe stringify
|
|
19
32
|
*/
|
|
20
33
|
export declare function classifyToolError(err: unknown): {
|
|
21
34
|
error_class: string;
|
|
22
35
|
error_message: string;
|
|
36
|
+
telemetry_message: string;
|
|
23
37
|
};
|
|
24
38
|
export declare function trackToolCall(toolName: string, durationMs: number, status: "ok" | "error", sessionId?: string, properties?: Record<string, unknown>): void;
|
|
25
39
|
export declare function trackSession(event: "session_start" | "session_end", sessionId: string, properties?: Record<string, unknown>): void;
|
package/dist/analytics.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,iBAAiB,GACjB,gBAAgB,GAChB,UAAU,GACV,OAAO,GACP,UAAU,GACV,YAAY,CAAC;AAEjB,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAe1E;AAgBD,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACxC,SAAS,CAAC,EAAE,MAAM,QAanB;AAED
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,iBAAiB,GACjB,gBAAgB,GAChB,UAAU,GACV,OAAO,GACP,UAAU,GACV,YAAY,CAAC;AAEjB,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,aAAa,CAe1E;AAgBD,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACxC,SAAS,CAAC,EAAE,MAAM,QAanB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAoBA;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,IAAI,GAAG,OAAO,EACtB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,QAYzC;AAED,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,GAAG,aAAa,EACtC,SAAS,EAAE,MAAM,EACjB,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,QAGzC;AAED,wBAAsB,iBAAiB,kBAKtC"}
|
package/dist/analytics.js
CHANGED
|
@@ -47,19 +47,34 @@ export function trackEvent(event, properties = {}, sessionId) {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
/**
|
|
50
|
-
* Extracts structured analytics properties from a thrown value.
|
|
51
|
-
* returns the same two property names so PostHog dashboards can query
|
|
52
|
-
* `properties.error_class` and `properties.error_message` reliably.
|
|
50
|
+
* Extracts structured analytics properties from a thrown value.
|
|
53
51
|
*
|
|
54
|
-
*
|
|
52
|
+
* Returns THREE fields so callers can pick the right one for each surface:
|
|
53
|
+
* - `error_class` — constructor/category name, stable for dashboards
|
|
54
|
+
* - `error_message` — FULL message, no truncation. Use this for the
|
|
55
|
+
* client-facing response so callers (including the
|
|
56
|
+
* ChatGPT Custom GPT) see the complete validation
|
|
57
|
+
* feedback and can recover in-conversation.
|
|
58
|
+
* - `telemetry_message` — same message capped at 500 chars. Use this for
|
|
59
|
+
* PostHog `properties.error_message` so we don't
|
|
60
|
+
* blow up event payload size on a 50KB ZodError.
|
|
61
|
+
*
|
|
62
|
+
* Why we split these (added v1.10.2): pre-v1.10.2 the capped field doubled
|
|
63
|
+
* as the client response (server.ts:475), so ChatGPT received a JSON
|
|
64
|
+
* ZodError truncated mid-key and could not recover. The 500-char cap was
|
|
65
|
+
* a telemetry-hygiene decision that quietly broke the response surface.
|
|
66
|
+
*
|
|
67
|
+
* - Error subclasses → constructor name + full message
|
|
55
68
|
* - Strings / numbers / null → class="unknown", message=stringified
|
|
56
69
|
* - Circular objects / weird values → class="unknown", message=safe stringify
|
|
57
70
|
*/
|
|
58
71
|
export function classifyToolError(err) {
|
|
59
72
|
if (err instanceof Error) {
|
|
73
|
+
const full = err.message ?? "";
|
|
60
74
|
return {
|
|
61
75
|
error_class: err.constructor?.name ?? "Error",
|
|
62
|
-
error_message:
|
|
76
|
+
error_message: full,
|
|
77
|
+
telemetry_message: full.slice(0, 500),
|
|
63
78
|
};
|
|
64
79
|
}
|
|
65
80
|
let message;
|
|
@@ -71,7 +86,8 @@ export function classifyToolError(err) {
|
|
|
71
86
|
}
|
|
72
87
|
return {
|
|
73
88
|
error_class: "unknown",
|
|
74
|
-
error_message: message
|
|
89
|
+
error_message: message,
|
|
90
|
+
telemetry_message: message.slice(0, 500),
|
|
75
91
|
};
|
|
76
92
|
}
|
|
77
93
|
export function trackToolCall(toolName, durationMs, status, sessionId, properties = {}) {
|
package/dist/analytics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAkBvC,MAAM,UAAU,YAAY,CAAC,UAA8B;IACzD,IAAI,CAAC,UAAU;QAAE,OAAO,YAAY,CAAC;IACrC,MAAM,CAAC,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC;QAAE,OAAO,sBAAsB,CAAC;IAC/D,IAAI,CAAC,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAC9D,IACE,CAAC,KAAK,QAAQ;QACd,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC;QACzB,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAE9B,OAAO,gBAAgB,CAAC;IAC1B,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAChD,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC1C,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,UAAU,CAAC;IAChD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,IAAI,MAAM,GAAmB,IAAI,CAAC;AAElC,SAAS,SAAS;IAChB,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACxC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;QACxB,IAAI,EAAE,0BAA0B;QAChC,OAAO,EAAE,CAAC;QACV,aAAa,EAAE,KAAK;KACrB,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,KAAa,EACb,aAAsC,EAAE,EACxC,SAAkB;IAElB,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE;QAAE,OAAO;IAEhB,EAAE,CAAC,OAAO,CAAC;QACT,UAAU,EAAE,SAAS,IAAI,WAAW;QACpC,KAAK;QACL,UAAU,EAAE;YACV,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,SAAS;YAC5D,GAAG,UAAU;SACd;KACF,CAAC,CAAC;AACL,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../src/analytics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GUARD / GLOBE Most-Favored-Nation (MFN) reference basket.
|
|
3
|
+
*
|
|
4
|
+
* Source: CMS proposed payment models (GUARD = Medicare Part D MFN,
|
|
5
|
+
* GLOBE = Medicare Part B MFN). The basket is the set of OECD countries
|
|
6
|
+
* that meet BOTH:
|
|
7
|
+
* - PPP-adjusted GDP per capita ≥ 60% of the US
|
|
8
|
+
* - Total GDP ≥ $400 billion
|
|
9
|
+
*
|
|
10
|
+
* Under CMS's proposed rules, the US net price for an MFN-eligible drug
|
|
11
|
+
* is bounded by the minimum net price observed across this basket.
|
|
12
|
+
*
|
|
13
|
+
* The list below is reproduced from CMS Notice of Proposed Rulemaking
|
|
14
|
+
* (effective dates per the v1.11.0 design log #27). The criteria are
|
|
15
|
+
* public; if CMS changes the threshold, bump MFN_BASKET_REVISION below.
|
|
16
|
+
*
|
|
17
|
+
* 19 countries total — never assume "country X is in the basket" without
|
|
18
|
+
* checking against this constant.
|
|
19
|
+
*/
|
|
20
|
+
/** ISO 3166-1 alpha-2 country codes used as basket keys throughout. */
|
|
21
|
+
export type CountryIso2 = "AT" | "BE" | "CZ" | "DK" | "FR" | "DE" | "IE" | "IT" | "NL" | "NO" | "ES" | "SE" | "CH" | "GB" | "AU" | "JP" | "KR" | "CA" | "IL";
|
|
22
|
+
/**
|
|
23
|
+
* Bump this string whenever CMS revises the basket criteria or country
|
|
24
|
+
* list. Caller-facing tools should stamp this on every emitted dossier
|
|
25
|
+
* section so a 2027 reader can tell which CMS rule version applied.
|
|
26
|
+
*/
|
|
27
|
+
export declare const MFN_BASKET_REVISION = "2026-03";
|
|
28
|
+
/**
|
|
29
|
+
* Verbatim 19-country GUARD/GLOBE basket. Order matches the CMS
|
|
30
|
+
* publication groupings (Europe → Asia-Pacific → North America → other).
|
|
31
|
+
*/
|
|
32
|
+
export declare const MFN_BASKET_2026: readonly CountryIso2[];
|
|
33
|
+
/** Country display names — used in dossier-section rendering. */
|
|
34
|
+
export declare const MFN_COUNTRY_NAMES: Readonly<Record<CountryIso2, string>>;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the reference set of countries for MFN ceiling computation,
|
|
37
|
+
* with optional exclusions. Caller might exclude e.g. countries with no
|
|
38
|
+
* marketed product, or override the basket for sensitivity analysis.
|
|
39
|
+
*
|
|
40
|
+
* Default = the full 19-country basket. Excluding any country shrinks
|
|
41
|
+
* the basket; the function never adds countries beyond MFN_BASKET_2026.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getMfnReferenceCountries(opts?: {
|
|
44
|
+
excluded_countries?: readonly CountryIso2[];
|
|
45
|
+
}): readonly CountryIso2[];
|
|
46
|
+
/**
|
|
47
|
+
* Computes the projected MFN ceiling from a partial price map.
|
|
48
|
+
*
|
|
49
|
+
* Per CMS GUARD/GLOBE rules, the ceiling is the minimum net price in
|
|
50
|
+
* the reference basket EXCLUDING the US (which is the market being
|
|
51
|
+
* priced). If the caller supplies basket prices including a US entry,
|
|
52
|
+
* we strip it before taking the min.
|
|
53
|
+
*
|
|
54
|
+
* Returns null when no basket prices were supplied — the caller can
|
|
55
|
+
* then render "Insufficient basket data" rather than fabricating a
|
|
56
|
+
* ceiling from zero datapoints.
|
|
57
|
+
*
|
|
58
|
+
* Negative or non-finite prices are rejected (TypeError) — pricing data
|
|
59
|
+
* with bad sign would silently lower the ceiling and mislead a payer
|
|
60
|
+
* discussion.
|
|
61
|
+
*/
|
|
62
|
+
export declare function computeMfnCeiling(basket_prices: Partial<Record<CountryIso2, number>>, opts?: {
|
|
63
|
+
excluded_countries?: readonly CountryIso2[];
|
|
64
|
+
}): {
|
|
65
|
+
ceiling: number | null;
|
|
66
|
+
contributing_countries: CountryIso2[];
|
|
67
|
+
missing_countries: CountryIso2[];
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=mfnBasket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfnBasket.d.ts","sourceRoot":"","sources":["../../src/data/mfnBasket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,uEAAuE;AACvE,MAAM,MAAM,WAAW,GACnB,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,GACJ,IAAI,CAAC;AAET;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,WAAW,EAwBxC,CAAC;AAEX,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAoBnE,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE;IAC9C,kBAAkB,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CAC7C,GAAG,SAAS,WAAW,EAAE,CAGzB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,EACnD,IAAI,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;CAAE,GACrD;IACD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,sBAAsB,EAAE,WAAW,EAAE,CAAC;IACtC,iBAAiB,EAAE,WAAW,EAAE,CAAC;CAClC,CA4BA"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GUARD / GLOBE Most-Favored-Nation (MFN) reference basket.
|
|
3
|
+
*
|
|
4
|
+
* Source: CMS proposed payment models (GUARD = Medicare Part D MFN,
|
|
5
|
+
* GLOBE = Medicare Part B MFN). The basket is the set of OECD countries
|
|
6
|
+
* that meet BOTH:
|
|
7
|
+
* - PPP-adjusted GDP per capita ≥ 60% of the US
|
|
8
|
+
* - Total GDP ≥ $400 billion
|
|
9
|
+
*
|
|
10
|
+
* Under CMS's proposed rules, the US net price for an MFN-eligible drug
|
|
11
|
+
* is bounded by the minimum net price observed across this basket.
|
|
12
|
+
*
|
|
13
|
+
* The list below is reproduced from CMS Notice of Proposed Rulemaking
|
|
14
|
+
* (effective dates per the v1.11.0 design log #27). The criteria are
|
|
15
|
+
* public; if CMS changes the threshold, bump MFN_BASKET_REVISION below.
|
|
16
|
+
*
|
|
17
|
+
* 19 countries total — never assume "country X is in the basket" without
|
|
18
|
+
* checking against this constant.
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Bump this string whenever CMS revises the basket criteria or country
|
|
22
|
+
* list. Caller-facing tools should stamp this on every emitted dossier
|
|
23
|
+
* section so a 2027 reader can tell which CMS rule version applied.
|
|
24
|
+
*/
|
|
25
|
+
export const MFN_BASKET_REVISION = "2026-03";
|
|
26
|
+
/**
|
|
27
|
+
* Verbatim 19-country GUARD/GLOBE basket. Order matches the CMS
|
|
28
|
+
* publication groupings (Europe → Asia-Pacific → North America → other).
|
|
29
|
+
*/
|
|
30
|
+
export const MFN_BASKET_2026 = [
|
|
31
|
+
// Europe (14)
|
|
32
|
+
"AT",
|
|
33
|
+
"BE",
|
|
34
|
+
"CZ",
|
|
35
|
+
"DK",
|
|
36
|
+
"FR",
|
|
37
|
+
"DE",
|
|
38
|
+
"IE",
|
|
39
|
+
"IT",
|
|
40
|
+
"NL",
|
|
41
|
+
"NO",
|
|
42
|
+
"ES",
|
|
43
|
+
"SE",
|
|
44
|
+
"CH",
|
|
45
|
+
"GB",
|
|
46
|
+
// Asia-Pacific (3)
|
|
47
|
+
"AU",
|
|
48
|
+
"JP",
|
|
49
|
+
"KR",
|
|
50
|
+
// North America (1)
|
|
51
|
+
"CA",
|
|
52
|
+
// Other OECD (1)
|
|
53
|
+
"IL",
|
|
54
|
+
];
|
|
55
|
+
/** Country display names — used in dossier-section rendering. */
|
|
56
|
+
export const MFN_COUNTRY_NAMES = {
|
|
57
|
+
AT: "Austria",
|
|
58
|
+
BE: "Belgium",
|
|
59
|
+
CZ: "Czechia",
|
|
60
|
+
DK: "Denmark",
|
|
61
|
+
FR: "France",
|
|
62
|
+
DE: "Germany",
|
|
63
|
+
IE: "Ireland",
|
|
64
|
+
IT: "Italy",
|
|
65
|
+
NL: "Netherlands",
|
|
66
|
+
NO: "Norway",
|
|
67
|
+
ES: "Spain",
|
|
68
|
+
SE: "Sweden",
|
|
69
|
+
CH: "Switzerland",
|
|
70
|
+
GB: "United Kingdom",
|
|
71
|
+
AU: "Australia",
|
|
72
|
+
JP: "Japan",
|
|
73
|
+
KR: "South Korea",
|
|
74
|
+
CA: "Canada",
|
|
75
|
+
IL: "Israel",
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Returns the reference set of countries for MFN ceiling computation,
|
|
79
|
+
* with optional exclusions. Caller might exclude e.g. countries with no
|
|
80
|
+
* marketed product, or override the basket for sensitivity analysis.
|
|
81
|
+
*
|
|
82
|
+
* Default = the full 19-country basket. Excluding any country shrinks
|
|
83
|
+
* the basket; the function never adds countries beyond MFN_BASKET_2026.
|
|
84
|
+
*/
|
|
85
|
+
export function getMfnReferenceCountries(opts) {
|
|
86
|
+
const excluded = new Set(opts?.excluded_countries ?? []);
|
|
87
|
+
return MFN_BASKET_2026.filter((c) => !excluded.has(c));
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Computes the projected MFN ceiling from a partial price map.
|
|
91
|
+
*
|
|
92
|
+
* Per CMS GUARD/GLOBE rules, the ceiling is the minimum net price in
|
|
93
|
+
* the reference basket EXCLUDING the US (which is the market being
|
|
94
|
+
* priced). If the caller supplies basket prices including a US entry,
|
|
95
|
+
* we strip it before taking the min.
|
|
96
|
+
*
|
|
97
|
+
* Returns null when no basket prices were supplied — the caller can
|
|
98
|
+
* then render "Insufficient basket data" rather than fabricating a
|
|
99
|
+
* ceiling from zero datapoints.
|
|
100
|
+
*
|
|
101
|
+
* Negative or non-finite prices are rejected (TypeError) — pricing data
|
|
102
|
+
* with bad sign would silently lower the ceiling and mislead a payer
|
|
103
|
+
* discussion.
|
|
104
|
+
*/
|
|
105
|
+
export function computeMfnCeiling(basket_prices, opts) {
|
|
106
|
+
const reference = getMfnReferenceCountries(opts);
|
|
107
|
+
const contributing = [];
|
|
108
|
+
const missing = [];
|
|
109
|
+
let min = null;
|
|
110
|
+
for (const c of reference) {
|
|
111
|
+
const price = basket_prices[c];
|
|
112
|
+
if (price === undefined || price === null) {
|
|
113
|
+
missing.push(c);
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
if (!Number.isFinite(price) || price < 0) {
|
|
117
|
+
throw new TypeError(`computeMfnCeiling: basket price for ${c} must be a non-negative finite number, got ${String(price)}`);
|
|
118
|
+
}
|
|
119
|
+
contributing.push(c);
|
|
120
|
+
if (min === null || price < min) {
|
|
121
|
+
min = price;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
ceiling: contributing.length > 0 ? min : null,
|
|
126
|
+
contributing_countries: contributing,
|
|
127
|
+
missing_countries: missing,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=mfnBasket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfnBasket.js","sourceRoot":"","sources":["../../src/data/mfnBasket.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAwBH;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,SAAS,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,cAAc;IACd,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,mBAAmB;IACnB,IAAI;IACJ,IAAI;IACJ,IAAI;IACJ,oBAAoB;IACpB,IAAI;IACJ,iBAAiB;IACjB,IAAI;CACI,CAAC;AAEX,iEAAiE;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAA0C;IACtE,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,aAAa;IACjB,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,aAAa;IACjB,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,WAAW;IACf,EAAE,EAAE,OAAO;IACX,EAAE,EAAE,aAAa;IACjB,EAAE,EAAE,QAAQ;IACZ,EAAE,EAAE,QAAQ;CACb,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAExC;IACC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,kBAAkB,IAAI,EAAE,CAAC,CAAC;IACzD,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,iBAAiB,CAC/B,aAAmD,EACnD,IAAsD;IAMtD,MAAM,SAAS,GAAG,wBAAwB,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,YAAY,GAAkB,EAAE,CAAC;IACvC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,GAAG,GAAkB,IAAI,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;QAC/B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,IAAI,SAAS,CACjB,uCAAuC,CAAC,8CAA8C,MAAM,CAAC,KAAK,CAAC,EAAE,CACtG,CAAC;QACJ,CAAC;QACD,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,GAAG,GAAG,EAAE,CAAC;YAChC,GAAG,GAAG,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;QAC7C,sBAAsB,EAAE,YAAY;QACpC,iBAAiB,EAAE,OAAO;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MFN price-sensitivity sweep for the cost-effectiveness model (design log #27).
|
|
3
|
+
*
|
|
4
|
+
* Given a basket-driven MFN ceiling and the drug's current US net price,
|
|
5
|
+
* sweep the price across that range at N discrete points and report the
|
|
6
|
+
* ICER at each. Cheaper alternative to a full PSA re-run — produces a
|
|
7
|
+
* curve users can read directly: "at the MFN ceiling, ICER drops to $X;
|
|
8
|
+
* the WTP crossover happens at price $Y."
|
|
9
|
+
*
|
|
10
|
+
* Why a deterministic sweep rather than another Monte Carlo CEAC?
|
|
11
|
+
*
|
|
12
|
+
* - The MFN scenario is an exogenous price shock, not statistical
|
|
13
|
+
* uncertainty. Treating it as a CEAC over a uniform distribution
|
|
14
|
+
* conflates two distinct questions.
|
|
15
|
+
* - A 11-point sweep is ~11 model runs vs PSA's 1000+. Ships fast.
|
|
16
|
+
* - The output (ICER per price point + crossover price) is more
|
|
17
|
+
* payer-readable than another CEAC slide.
|
|
18
|
+
*
|
|
19
|
+
* If a true MFN-stressed PSA is needed later, this module stays — it's
|
|
20
|
+
* the deterministic complement.
|
|
21
|
+
*/
|
|
22
|
+
import type { CEModelParams } from "../providers/types.js";
|
|
23
|
+
export type CEModelInputs = CEModelParams;
|
|
24
|
+
export interface MfnSensitivityInputs {
|
|
25
|
+
/** Lower bound of the price sweep — typically min(basket excluding US). */
|
|
26
|
+
min_basket: number;
|
|
27
|
+
/** Upper bound — typically the drug's current US net price. */
|
|
28
|
+
current_us_price: number;
|
|
29
|
+
/** Number of price points to sweep (default 11 → step every 10% of range). */
|
|
30
|
+
n_points?: number;
|
|
31
|
+
/**
|
|
32
|
+
* Willingness-to-pay threshold(s) for crossover detection. When the
|
|
33
|
+
* ICER curve crosses any of these as price falls, we record the
|
|
34
|
+
* approximate crossover price. Defaults match the WTP catalog used
|
|
35
|
+
* elsewhere in this module: NHS £30K, US $100K, US $150K.
|
|
36
|
+
*/
|
|
37
|
+
wtp_thresholds?: number[];
|
|
38
|
+
}
|
|
39
|
+
export interface MfnSensitivityPoint {
|
|
40
|
+
drug_price: number;
|
|
41
|
+
/** ICER at this price; Infinity when delta_qaly <= 0. */
|
|
42
|
+
icer: number;
|
|
43
|
+
}
|
|
44
|
+
export interface MfnCrossover {
|
|
45
|
+
wtp: number;
|
|
46
|
+
/**
|
|
47
|
+
* Approximate price where ICER = wtp. Null when the ICER never
|
|
48
|
+
* crosses the threshold over the sweep range (cost-effective at
|
|
49
|
+
* every point, or cost-INeffective at every point).
|
|
50
|
+
*/
|
|
51
|
+
crossover_price: number | null;
|
|
52
|
+
}
|
|
53
|
+
export interface MfnSensitivityResult {
|
|
54
|
+
/** Echoes inputs so the caller can stamp the output for audit. */
|
|
55
|
+
range: {
|
|
56
|
+
min_basket: number;
|
|
57
|
+
current_us_price: number;
|
|
58
|
+
n_points: number;
|
|
59
|
+
};
|
|
60
|
+
/** ICER per price point, ordered low-price → high-price. */
|
|
61
|
+
curve: MfnSensitivityPoint[];
|
|
62
|
+
/** Crossover prices per WTP threshold (linear interpolation between points). */
|
|
63
|
+
crossovers: MfnCrossover[];
|
|
64
|
+
/** ICER at the MFN ceiling itself (min_basket); first point in `curve`. */
|
|
65
|
+
icer_at_ceiling: number;
|
|
66
|
+
/** ICER at the unstressed US price; last point in `curve`. */
|
|
67
|
+
icer_at_current: number;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Run the price sweep. The caller injects a `runModel` callback so this
|
|
71
|
+
* module stays decoupled from the Markov / PartSA implementations and
|
|
72
|
+
* is trivially mockable in tests.
|
|
73
|
+
*
|
|
74
|
+
* Returns sorted by ascending price. Crossover prices use linear
|
|
75
|
+
* interpolation between adjacent points — accurate enough for the
|
|
76
|
+
* payer-conversation purpose; not a root-finding bisection.
|
|
77
|
+
*/
|
|
78
|
+
export declare function runMfnSensitivity(baseParams: CEModelInputs, inputs: MfnSensitivityInputs, runModel: (params: CEModelInputs) => {
|
|
79
|
+
icer: number;
|
|
80
|
+
}): MfnSensitivityResult;
|
|
81
|
+
//# sourceMappingURL=mfnSensitivity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfnSensitivity.d.ts","sourceRoot":"","sources":["../../src/models/mfnSensitivity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC;AAE1C,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,gBAAgB,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,oBAAoB;IACnC,kEAAkE;IAClE,KAAK,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,4DAA4D;IAC5D,KAAK,EAAE,mBAAmB,EAAE,CAAC;IAC7B,gFAAgF;IAChF,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,2EAA2E;IAC3E,eAAe,EAAE,MAAM,CAAC;IACxB,8DAA8D;IAC9D,eAAe,EAAE,MAAM,CAAC;CACzB;AAID;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,aAAa,EACzB,MAAM,EAAE,oBAAoB,EAC5B,QAAQ,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GACpD,oBAAoB,CAmDtB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MFN price-sensitivity sweep for the cost-effectiveness model (design log #27).
|
|
3
|
+
*
|
|
4
|
+
* Given a basket-driven MFN ceiling and the drug's current US net price,
|
|
5
|
+
* sweep the price across that range at N discrete points and report the
|
|
6
|
+
* ICER at each. Cheaper alternative to a full PSA re-run — produces a
|
|
7
|
+
* curve users can read directly: "at the MFN ceiling, ICER drops to $X;
|
|
8
|
+
* the WTP crossover happens at price $Y."
|
|
9
|
+
*
|
|
10
|
+
* Why a deterministic sweep rather than another Monte Carlo CEAC?
|
|
11
|
+
*
|
|
12
|
+
* - The MFN scenario is an exogenous price shock, not statistical
|
|
13
|
+
* uncertainty. Treating it as a CEAC over a uniform distribution
|
|
14
|
+
* conflates two distinct questions.
|
|
15
|
+
* - A 11-point sweep is ~11 model runs vs PSA's 1000+. Ships fast.
|
|
16
|
+
* - The output (ICER per price point + crossover price) is more
|
|
17
|
+
* payer-readable than another CEAC slide.
|
|
18
|
+
*
|
|
19
|
+
* If a true MFN-stressed PSA is needed later, this module stays — it's
|
|
20
|
+
* the deterministic complement.
|
|
21
|
+
*/
|
|
22
|
+
const DEFAULT_WTP = [30000, 100000, 150000];
|
|
23
|
+
/**
|
|
24
|
+
* Run the price sweep. The caller injects a `runModel` callback so this
|
|
25
|
+
* module stays decoupled from the Markov / PartSA implementations and
|
|
26
|
+
* is trivially mockable in tests.
|
|
27
|
+
*
|
|
28
|
+
* Returns sorted by ascending price. Crossover prices use linear
|
|
29
|
+
* interpolation between adjacent points — accurate enough for the
|
|
30
|
+
* payer-conversation purpose; not a root-finding bisection.
|
|
31
|
+
*/
|
|
32
|
+
export function runMfnSensitivity(baseParams, inputs, runModel) {
|
|
33
|
+
const n = Math.max(2, inputs.n_points ?? 11);
|
|
34
|
+
if (!Number.isFinite(inputs.min_basket) || !Number.isFinite(inputs.current_us_price)) {
|
|
35
|
+
throw new TypeError("runMfnSensitivity: min_basket and current_us_price must be finite numbers");
|
|
36
|
+
}
|
|
37
|
+
if (inputs.min_basket < 0 || inputs.current_us_price < 0) {
|
|
38
|
+
throw new TypeError("runMfnSensitivity: prices must be non-negative");
|
|
39
|
+
}
|
|
40
|
+
if (inputs.min_basket > inputs.current_us_price) {
|
|
41
|
+
throw new TypeError(`runMfnSensitivity: min_basket (${inputs.min_basket}) must be <= current_us_price (${inputs.current_us_price})`);
|
|
42
|
+
}
|
|
43
|
+
const step = (inputs.current_us_price - inputs.min_basket) / (n - 1);
|
|
44
|
+
const curve = [];
|
|
45
|
+
for (let i = 0; i < n; i++) {
|
|
46
|
+
const price = inputs.min_basket + step * i;
|
|
47
|
+
const perturbed = {
|
|
48
|
+
...baseParams,
|
|
49
|
+
cost_inputs: {
|
|
50
|
+
...baseParams.cost_inputs,
|
|
51
|
+
drug_cost_annual: price,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
const { icer } = runModel(perturbed);
|
|
55
|
+
curve.push({ drug_price: price, icer });
|
|
56
|
+
}
|
|
57
|
+
const thresholds = inputs.wtp_thresholds ?? DEFAULT_WTP;
|
|
58
|
+
const crossovers = thresholds.map((wtp) => ({
|
|
59
|
+
wtp,
|
|
60
|
+
crossover_price: findCrossover(curve, wtp),
|
|
61
|
+
}));
|
|
62
|
+
return {
|
|
63
|
+
range: {
|
|
64
|
+
min_basket: inputs.min_basket,
|
|
65
|
+
current_us_price: inputs.current_us_price,
|
|
66
|
+
n_points: n,
|
|
67
|
+
},
|
|
68
|
+
curve,
|
|
69
|
+
crossovers,
|
|
70
|
+
icer_at_ceiling: curve[0].icer,
|
|
71
|
+
icer_at_current: curve[curve.length - 1].icer,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Find the price at which the ICER curve crosses `wtp` using linear
|
|
76
|
+
* interpolation between adjacent points. Returns null when the curve
|
|
77
|
+
* doesn't cross — either ICER stays below wtp everywhere (cost-effective
|
|
78
|
+
* at every price in range) or stays above (cost-INeffective everywhere).
|
|
79
|
+
*
|
|
80
|
+
* Infinity ICERs (delta_qaly <= 0) are treated as "doesn't cross" rather
|
|
81
|
+
* than collapsing the interpolation — a degenerate iteration shouldn't
|
|
82
|
+
* fabricate a crossover.
|
|
83
|
+
*/
|
|
84
|
+
function findCrossover(curve, wtp) {
|
|
85
|
+
for (let i = 0; i < curve.length - 1; i++) {
|
|
86
|
+
const a = curve[i];
|
|
87
|
+
const b = curve[i + 1];
|
|
88
|
+
if (!Number.isFinite(a.icer) || !Number.isFinite(b.icer))
|
|
89
|
+
continue;
|
|
90
|
+
const aDelta = a.icer - wtp;
|
|
91
|
+
const bDelta = b.icer - wtp;
|
|
92
|
+
if (aDelta === 0)
|
|
93
|
+
return a.drug_price;
|
|
94
|
+
if (bDelta === 0)
|
|
95
|
+
return b.drug_price;
|
|
96
|
+
if (aDelta * bDelta < 0) {
|
|
97
|
+
// Sign change between a and b → interpolate.
|
|
98
|
+
const t = aDelta / (aDelta - bDelta);
|
|
99
|
+
return a.drug_price + t * (b.drug_price - a.drug_price);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=mfnSensitivity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mfnSensitivity.js","sourceRoot":"","sources":["../../src/models/mfnSensitivity.ts"],"names":[],"mappings":"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"}
|
|
@@ -79,6 +79,12 @@ export interface CEModelParams {
|
|
|
79
79
|
survival_distribution?: "exponential" | "weibull";
|
|
80
80
|
weibull_shape?: number;
|
|
81
81
|
};
|
|
82
|
+
mfn_sensitivity?: {
|
|
83
|
+
min_basket: number;
|
|
84
|
+
current_us_price: number;
|
|
85
|
+
n_points?: number;
|
|
86
|
+
wtp_thresholds?: number[];
|
|
87
|
+
};
|
|
82
88
|
}
|
|
83
89
|
export interface PicoDefinition {
|
|
84
90
|
id: string;
|
|
@@ -126,6 +132,13 @@ export interface DossierParams {
|
|
|
126
132
|
unmet_need_summary?: string;
|
|
127
133
|
/** Design log #26: array of RegulatoryStatusResult objects from hta_workflow Phase 3.6. Renders "Regulatory Landscape" section for nice/jca/gvd/amcp. */
|
|
128
134
|
regulatory_landscape?: any[];
|
|
135
|
+
/** Design log #27: MFN (Most-Favored-Nation) pricing context. Auto-renders MFN Exposure section for hta_body="amcp"; opt-in for other bodies via basket_prices presence. Basket = 19-country CMS GUARD/GLOBE OECD set (src/data/mfnBasket.ts). */
|
|
136
|
+
mfn_context?: {
|
|
137
|
+
basket_prices?: Record<string, number>;
|
|
138
|
+
us_current_net_price?: number;
|
|
139
|
+
basket_revision?: string;
|
|
140
|
+
excluded_countries?: string[];
|
|
141
|
+
};
|
|
129
142
|
}
|
|
130
143
|
export interface ToolResult {
|
|
131
144
|
content: string | object;
|
|
@@ -184,6 +197,24 @@ export interface CEModelResult {
|
|
|
184
197
|
};
|
|
185
198
|
psa?: PSASummary;
|
|
186
199
|
owsa?: OWSASummary[];
|
|
200
|
+
/** Design log #27: MFN price-sensitivity sweep result. Present when caller supplied mfn_sensitivity. */
|
|
201
|
+
mfn_sensitivity?: {
|
|
202
|
+
range: {
|
|
203
|
+
min_basket: number;
|
|
204
|
+
current_us_price: number;
|
|
205
|
+
n_points: number;
|
|
206
|
+
};
|
|
207
|
+
curve: Array<{
|
|
208
|
+
drug_price: number;
|
|
209
|
+
icer: number;
|
|
210
|
+
}>;
|
|
211
|
+
crossovers: Array<{
|
|
212
|
+
wtp: number;
|
|
213
|
+
crossover_price: number | null;
|
|
214
|
+
}>;
|
|
215
|
+
icer_at_ceiling: number;
|
|
216
|
+
icer_at_current: number;
|
|
217
|
+
};
|
|
187
218
|
wtp_analysis: {
|
|
188
219
|
nhs: WTPAssessment;
|
|
189
220
|
us_payer: WTPAssessment;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
|