heor-agent-mcp 0.2.0 → 0.7.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.
Files changed (93) hide show
  1. package/README.md +44 -0
  2. package/dist/formatters/comparisonMarkdown.d.ts +3 -0
  3. package/dist/formatters/comparisonMarkdown.d.ts.map +1 -0
  4. package/dist/formatters/comparisonMarkdown.js +68 -0
  5. package/dist/formatters/comparisonMarkdown.js.map +1 -0
  6. package/dist/models/evppi.d.ts +33 -0
  7. package/dist/models/evppi.d.ts.map +1 -0
  8. package/dist/models/evppi.js +75 -0
  9. package/dist/models/evppi.js.map +1 -0
  10. package/dist/models/modelUtils.d.ts +7 -2
  11. package/dist/models/modelUtils.d.ts.map +1 -1
  12. package/dist/models/modelUtils.js +49 -31
  13. package/dist/models/modelUtils.js.map +1 -1
  14. package/dist/models/psa.d.ts +4 -0
  15. package/dist/models/psa.d.ts.map +1 -1
  16. package/dist/models/psa.js +29 -2
  17. package/dist/models/psa.js.map +1 -1
  18. package/dist/models/survivalFitting.d.ts +47 -0
  19. package/dist/models/survivalFitting.d.ts.map +1 -0
  20. package/dist/models/survivalFitting.js +342 -0
  21. package/dist/models/survivalFitting.js.map +1 -0
  22. package/dist/network/bucher.d.ts +29 -0
  23. package/dist/network/bucher.d.ts.map +1 -0
  24. package/dist/network/bucher.js +125 -0
  25. package/dist/network/bucher.js.map +1 -0
  26. package/dist/network/frequentistNma.d.ts +12 -0
  27. package/dist/network/frequentistNma.d.ts.map +1 -0
  28. package/dist/network/frequentistNma.js +230 -0
  29. package/dist/network/frequentistNma.js.map +1 -0
  30. package/dist/network/index.d.ts +4 -1
  31. package/dist/network/index.d.ts.map +1 -1
  32. package/dist/network/index.js +3 -0
  33. package/dist/network/index.js.map +1 -1
  34. package/dist/network/pathfinder.d.ts +14 -0
  35. package/dist/network/pathfinder.d.ts.map +1 -0
  36. package/dist/network/pathfinder.js +93 -0
  37. package/dist/network/pathfinder.js.map +1 -0
  38. package/dist/network/types.d.ts +45 -0
  39. package/dist/network/types.d.ts.map +1 -1
  40. package/dist/providers/direct/index.d.ts.map +1 -1
  41. package/dist/providers/direct/index.js +82 -27
  42. package/dist/providers/direct/index.js.map +1 -1
  43. package/dist/providers/direct/iqwig.js +1 -1
  44. package/dist/providers/direct/iqwig.js.map +1 -1
  45. package/dist/providers/direct/niceTa.d.ts +4 -0
  46. package/dist/providers/direct/niceTa.d.ts.map +1 -1
  47. package/dist/providers/direct/niceTa.js +76 -25
  48. package/dist/providers/direct/niceTa.js.map +1 -1
  49. package/dist/providers/direct/tlv.js +1 -1
  50. package/dist/providers/direct/tlv.js.map +1 -1
  51. package/dist/providers/types.d.ts +6 -0
  52. package/dist/providers/types.d.ts.map +1 -1
  53. package/dist/server.js +89 -9
  54. package/dist/server.js.map +1 -1
  55. package/dist/tools/budgetImpactModel.d.ts +116 -0
  56. package/dist/tools/budgetImpactModel.d.ts.map +1 -0
  57. package/dist/tools/budgetImpactModel.js +257 -0
  58. package/dist/tools/budgetImpactModel.js.map +1 -0
  59. package/dist/tools/costEffectivenessModel.d.ts +18 -0
  60. package/dist/tools/costEffectivenessModel.d.ts.map +1 -1
  61. package/dist/tools/costEffectivenessModel.js +155 -27
  62. package/dist/tools/costEffectivenessModel.js.map +1 -1
  63. package/dist/tools/htaDossierPrep.d.ts.map +1 -1
  64. package/dist/tools/htaDossierPrep.js +119 -0
  65. package/dist/tools/htaDossierPrep.js.map +1 -1
  66. package/dist/tools/indirectComparison.d.ts +73 -0
  67. package/dist/tools/indirectComparison.d.ts.map +1 -0
  68. package/dist/tools/indirectComparison.js +191 -0
  69. package/dist/tools/indirectComparison.js.map +1 -0
  70. package/dist/tools/knowledgeWrite.d.ts.map +1 -1
  71. package/dist/tools/knowledgeWrite.js +17 -3
  72. package/dist/tools/knowledgeWrite.js.map +1 -1
  73. package/dist/tools/literatureSearch.d.ts +4 -0
  74. package/dist/tools/literatureSearch.d.ts.map +1 -1
  75. package/dist/tools/literatureSearch.js +43 -1
  76. package/dist/tools/literatureSearch.js.map +1 -1
  77. package/dist/tools/populationAdjustedComparison.d.ts +145 -0
  78. package/dist/tools/populationAdjustedComparison.d.ts.map +1 -0
  79. package/dist/tools/populationAdjustedComparison.js +431 -0
  80. package/dist/tools/populationAdjustedComparison.js.map +1 -0
  81. package/dist/tools/screenAbstracts.d.ts +99 -0
  82. package/dist/tools/screenAbstracts.d.ts.map +1 -0
  83. package/dist/tools/screenAbstracts.js +442 -0
  84. package/dist/tools/screenAbstracts.js.map +1 -0
  85. package/dist/tools/survivalFitting.d.ts +56 -0
  86. package/dist/tools/survivalFitting.d.ts.map +1 -0
  87. package/dist/tools/survivalFitting.js +147 -0
  88. package/dist/tools/survivalFitting.js.map +1 -0
  89. package/dist/tools/validateLinks.d.ts +24 -0
  90. package/dist/tools/validateLinks.d.ts.map +1 -0
  91. package/dist/tools/validateLinks.js +171 -0
  92. package/dist/tools/validateLinks.js.map +1 -0
  93. package/package.json +4 -2
@@ -35,6 +35,10 @@ export declare const literatureSearchToolSchema: {
35
35
  type: string;
36
36
  description: string;
37
37
  };
38
+ runs: {
39
+ type: string;
40
+ description: string;
41
+ };
38
42
  };
39
43
  required: string[];
40
44
  };
@@ -1 +1 @@
1
- {"version":3,"file":"literatureSearch.d.ts","sourceRoot":"","sources":["../../src/tools/literatureSearch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA4DxD,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqFtC,CAAC"}
1
+ {"version":3,"file":"literatureSearch.d.ts","sourceRoot":"","sources":["../../src/tools/literatureSearch.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA0GxD,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,UAAU,CAAC,CAIrB;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0FtC,CAAC"}
@@ -1,5 +1,26 @@
1
1
  import { z } from "zod";
2
2
  import { createProvider } from "../providers/factory.js";
3
+ const SOURCE_ALIASES = {
4
+ nice: "nice_ta",
5
+ cadth: "cadth_reviews",
6
+ "cda-amc": "cadth_reviews",
7
+ icer: "icer_reports",
8
+ pbac: "pbac_psd",
9
+ gba: "gba_decisions",
10
+ "g-ba": "gba_decisions",
11
+ has: "has_tc",
12
+ ct: "clinicaltrials",
13
+ "clinicaltrials.gov": "clinicaltrials",
14
+ ncbi: "pubmed",
15
+ elsevier: "embase",
16
+ world_bank_data: "world_bank",
17
+ worldbank: "world_bank",
18
+ who: "who_gho",
19
+ gbd: "ihme_gbd",
20
+ nadac: "cms_nadac",
21
+ nhs: "nhs_costs",
22
+ pbs: "pbs_schedule",
23
+ };
3
24
  const LiteratureSearchSchema = z.object({
4
25
  query: z.string().min(1, "query is required"),
5
26
  sources: z
@@ -54,9 +75,26 @@ const LiteratureSearchSchema = z.object({
54
75
  .optional(),
55
76
  output_format: z.enum(["text", "json", "docx"]).optional(),
56
77
  project: z.string().optional(),
78
+ runs: z
79
+ .number()
80
+ .int()
81
+ .min(1)
82
+ .max(5)
83
+ .optional()
84
+ .describe("Number of search runs to perform (1-5, default 1). Multiple runs are deduplicated and ranked by consistency — studies found in more runs are ranked higher. Use runs=3 for comprehensive, stable results."),
57
85
  });
86
+ function resolveSourceAliases(params) {
87
+ if (typeof params === "object" &&
88
+ params !== null &&
89
+ "sources" in params &&
90
+ Array.isArray(params.sources)) {
91
+ const p = params;
92
+ p.sources = p.sources.map((s) => SOURCE_ALIASES[s.toLowerCase()] ?? s);
93
+ }
94
+ return params;
95
+ }
58
96
  export async function handleLiteratureSearch(rawParams) {
59
- const params = LiteratureSearchSchema.parse(rawParams);
97
+ const params = LiteratureSearchSchema.parse(resolveSourceAliases(rawParams));
60
98
  const provider = createProvider();
61
99
  return provider.searchLiterature(params);
62
100
  }
@@ -137,6 +175,10 @@ export const literatureSearchToolSchema = {
137
175
  type: "string",
138
176
  description: "Project ID for knowledge base persistence. When set, results are saved to ~/.heor-agent/projects/{project}/raw/literature/",
139
177
  },
178
+ runs: {
179
+ type: "number",
180
+ description: "Number of search runs (1-5, default 1). Multiple runs deduplicate and rank by consistency. Use runs=3 for comprehensive, stable results.",
181
+ },
140
182
  },
141
183
  required: ["query"],
142
184
  },
@@ -1 +1 @@
1
- {"version":3,"file":"literatureSearch.js","sourceRoot":"","sources":["../../src/tools/literatureSearch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"literatureSearch.js","sourceRoot":"","sources":["../../src/tools/literatureSearch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,145 @@
1
+ import type { ToolResult } from "../providers/types.js";
2
+ export declare function handlePopulationAdjustedComparison(rawParams: unknown): Promise<ToolResult>;
3
+ export declare const populationAdjustedComparisonToolSchema: {
4
+ name: string;
5
+ description: string;
6
+ inputSchema: {
7
+ type: string;
8
+ properties: {
9
+ index_trial: {
10
+ type: string;
11
+ description: string;
12
+ properties: {
13
+ name: {
14
+ type: string;
15
+ description: string;
16
+ };
17
+ treatment: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ comparator: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ n: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ effect: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ ci_lower: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ ci_upper: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ measure: {
42
+ type: string;
43
+ enum: string[];
44
+ };
45
+ covariates: {
46
+ type: string;
47
+ items: {
48
+ type: string;
49
+ properties: {
50
+ name: {
51
+ type: string;
52
+ description: string;
53
+ };
54
+ mean: {
55
+ type: string;
56
+ };
57
+ sd: {
58
+ type: string;
59
+ };
60
+ };
61
+ required: string[];
62
+ };
63
+ };
64
+ };
65
+ required: string[];
66
+ };
67
+ target_trial: {
68
+ type: string;
69
+ description: string;
70
+ properties: {
71
+ name: {
72
+ type: string;
73
+ };
74
+ treatment: {
75
+ type: string;
76
+ };
77
+ comparator: {
78
+ type: string;
79
+ };
80
+ n: {
81
+ type: string;
82
+ };
83
+ effect: {
84
+ type: string;
85
+ };
86
+ ci_lower: {
87
+ type: string;
88
+ };
89
+ ci_upper: {
90
+ type: string;
91
+ };
92
+ measure: {
93
+ type: string;
94
+ enum: string[];
95
+ };
96
+ covariates: {
97
+ type: string;
98
+ items: {
99
+ type: string;
100
+ properties: {
101
+ name: {
102
+ type: string;
103
+ };
104
+ mean: {
105
+ type: string;
106
+ };
107
+ sd: {
108
+ type: string;
109
+ };
110
+ };
111
+ required: string[];
112
+ };
113
+ };
114
+ };
115
+ required: string[];
116
+ };
117
+ effect_modifiers: {
118
+ type: string;
119
+ items: {
120
+ type: string;
121
+ };
122
+ description: string;
123
+ };
124
+ method: {
125
+ type: string;
126
+ enum: string[];
127
+ description: string;
128
+ };
129
+ outcome_name: {
130
+ type: string;
131
+ description: string;
132
+ };
133
+ output_format: {
134
+ type: string;
135
+ enum: string[];
136
+ };
137
+ project: {
138
+ type: string;
139
+ description: string;
140
+ };
141
+ };
142
+ required: string[];
143
+ };
144
+ };
145
+ //# sourceMappingURL=populationAdjustedComparison.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"populationAdjustedComparison.d.ts","sourceRoot":"","sources":["../../src/tools/populationAdjustedComparison.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AA6SxD,wBAAsB,kCAAkC,CACtD,SAAS,EAAE,OAAO,GACjB,OAAO,CAAC,UAAU,CAAC,CA6JrB;AAED,eAAO,MAAM,sCAAsC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoFlD,CAAC"}
@@ -0,0 +1,431 @@
1
+ import { z } from "zod";
2
+ import { createAuditRecord, addAssumption, addWarning, setMethodology, } from "../audit/builder.js";
3
+ import { auditToMarkdown } from "../formatters/markdown.js";
4
+ /**
5
+ * Population-Adjusted Indirect Comparison (MAIC / STC)
6
+ *
7
+ * MAIC: Matching-Adjusted Indirect Comparison — reweights individual-level
8
+ * data (or simulated summary-level data) to match the target population,
9
+ * then computes an adjusted treatment effect.
10
+ *
11
+ * STC: Simulated Treatment Comparison — uses outcome regression to adjust
12
+ * for differences in effect modifiers between trials.
13
+ *
14
+ * Both methods follow NICE DSU TSD 18 (Phillippo 2016) and ISPOR guidance.
15
+ */
16
+ const CovariateSummarySchema = z.object({
17
+ name: z.string().min(1),
18
+ mean: z.number(),
19
+ sd: z.number().nonnegative(),
20
+ });
21
+ const TrialSchema = z.object({
22
+ name: z.string().min(1),
23
+ treatment: z.string().min(1),
24
+ comparator: z.string().min(1),
25
+ n: z.number().int().positive(),
26
+ effect: z.number(),
27
+ ci_lower: z.number(),
28
+ ci_upper: z.number(),
29
+ measure: z.enum(["MD", "OR", "RR", "HR"]),
30
+ covariates: z.array(CovariateSummarySchema),
31
+ });
32
+ const PopAdjSchema = z.object({
33
+ index_trial: TrialSchema.describe("Trial with individual patient data (or summary stats to simulate from)"),
34
+ target_trial: TrialSchema.describe("Trial whose population characteristics are the matching target"),
35
+ effect_modifiers: z
36
+ .array(z.string())
37
+ .min(1)
38
+ .describe("Covariate names that are effect modifiers (must exist in both trials' covariates)"),
39
+ method: z
40
+ .enum(["auto", "maic", "stc"])
41
+ .default("auto")
42
+ .describe("auto selects MAIC when covariates are sufficient, else STC"),
43
+ outcome_name: z.string().default("primary"),
44
+ output_format: z.enum(["text", "json"]).optional(),
45
+ project: z.string().optional(),
46
+ });
47
+ function isLogScale(measure) {
48
+ return ["OR", "RR", "HR"].includes(measure);
49
+ }
50
+ function seFromCI(estimate, ciLower, ciUpper, logScale) {
51
+ if (logScale) {
52
+ return (Math.log(ciUpper) - Math.log(ciLower)) / 3.92;
53
+ }
54
+ return (ciUpper - ciLower) / 3.92;
55
+ }
56
+ /**
57
+ * MAIC using summary-level data (Signorovitch 2010, 2012).
58
+ *
59
+ * Simulates N patients from the index trial using normal distributions,
60
+ * then computes propensity weights to match target trial covariate means.
61
+ * Uses method of moments for the logistic regression (Newton-Raphson).
62
+ */
63
+ function runMAIC(params) {
64
+ const idx = params.index_trial;
65
+ const tgt = params.target_trial;
66
+ const logScale = isLogScale(idx.measure);
67
+ const modifiers = params.effect_modifiers;
68
+ // Build covariate lookup
69
+ const idxCovs = new Map(idx.covariates.map((c) => [c.name, c]));
70
+ const tgtCovs = new Map(tgt.covariates.map((c) => [c.name, c]));
71
+ // Simulate IPD from index trial summary stats (N patients)
72
+ const N = idx.n;
73
+ const nMods = modifiers.length;
74
+ // For each modifier, compute the mean difference (target - index)
75
+ // This drives the propensity weights
76
+ const meanDiffs = [];
77
+ const indexSDs = [];
78
+ for (const mod of modifiers) {
79
+ const idxC = idxCovs.get(mod);
80
+ const tgtC = tgtCovs.get(mod);
81
+ if (!idxC || !tgtC)
82
+ throw new Error(`Covariate '${mod}' missing from one or both trials`);
83
+ meanDiffs.push(tgtC.mean - idxC.mean);
84
+ indexSDs.push(idxC.sd || 1);
85
+ }
86
+ // Method of moments MAIC weights (Signorovitch 2010):
87
+ // For summary-level MAIC, the weight for each simulated patient i is:
88
+ // w_i = exp(sum_k alpha_k * x_ik)
89
+ // where alpha solves: sum_i w_i * x_ik / sum_i w_i = target_mean_k
90
+ //
91
+ // With simulated normal data and known means/SDs, the optimal alpha
92
+ // can be derived analytically: alpha_k = meanDiff_k / sd_k^2
93
+ const alphas = meanDiffs.map((d, k) => d / (indexSDs[k] * indexSDs[k]));
94
+ // Simulate patients and compute weights using a seeded PRNG
95
+ // (Simple Box-Muller for reproducibility)
96
+ let seed = 42;
97
+ function nextRand() {
98
+ seed = (seed * 1664525 + 1013904223) & 0x7fffffff;
99
+ return seed / 0x7fffffff;
100
+ }
101
+ function boxMuller() {
102
+ const u1 = Math.max(1e-10, nextRand());
103
+ const u2 = nextRand();
104
+ return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
105
+ }
106
+ const weights = [];
107
+ for (let i = 0; i < N; i++) {
108
+ let logWeight = 0;
109
+ for (let k = 0; k < nMods; k++) {
110
+ const x = idxCovs.get(modifiers[k]).mean + indexSDs[k] * boxMuller();
111
+ logWeight += alphas[k] * x;
112
+ }
113
+ weights.push(Math.exp(logWeight));
114
+ }
115
+ // Normalize weights
116
+ const sumW = weights.reduce((a, b) => a + b, 0);
117
+ const normWeights = weights.map((w) => w / sumW * N);
118
+ // Effective sample size: (sum w)^2 / sum(w^2)
119
+ const sumNormW = normWeights.reduce((a, b) => a + b, 0);
120
+ const sumNormW2 = normWeights.reduce((a, b) => a + b * b, 0);
121
+ const ess = (sumNormW * sumNormW) / sumNormW2;
122
+ // Adjusted treatment effect:
123
+ // The index trial effect is reweighted. For summary-level MAIC,
124
+ // the adjusted effect is approximately:
125
+ // effect_adj = effect_index (on original scale) — the reweighting
126
+ // adjusts the population, not the point estimate directly.
127
+ // The SE inflates by sqrt(N/ESS).
128
+ const originalSE = seFromCI(idx.effect, idx.ci_lower, idx.ci_upper, logScale);
129
+ const seInflation = Math.sqrt(N / ess);
130
+ const adjustedSE = originalSE * seInflation;
131
+ // The point estimate shifts based on the covariate adjustment
132
+ // For MAIC with summary data, the adjusted effect accounts for
133
+ // the population difference via the anchored comparison
134
+ const idxEffect = logScale ? Math.log(idx.effect) : idx.effect;
135
+ const tgtEffect = logScale ? Math.log(tgt.effect) : tgt.effect;
136
+ // Anchored MAIC: adjusted indirect comparison
137
+ // effect_AC = effect_AB_adj - effect_CB
138
+ // where AB_adj is the reweighted index trial effect
139
+ // and CB is the target trial effect (C vs B, same comparator)
140
+ const adjustedIndirect = idxEffect - tgtEffect;
141
+ const tgtSE = seFromCI(tgt.effect, tgt.ci_lower, tgt.ci_upper, logScale);
142
+ const combinedSE = Math.sqrt(adjustedSE * adjustedSE + tgtSE * tgtSE);
143
+ const adjusted_effect = logScale
144
+ ? Math.exp(adjustedIndirect)
145
+ : adjustedIndirect;
146
+ const adjusted_ci_lower = logScale
147
+ ? Math.exp(adjustedIndirect - 1.96 * combinedSE)
148
+ : adjustedIndirect - 1.96 * combinedSE;
149
+ const adjusted_ci_upper = logScale
150
+ ? Math.exp(adjustedIndirect + 1.96 * combinedSE)
151
+ : adjustedIndirect + 1.96 * combinedSE;
152
+ return {
153
+ adjusted_effect,
154
+ adjusted_se: logScale ? combinedSE : combinedSE, // on native or log scale
155
+ adjusted_ci_lower,
156
+ adjusted_ci_upper,
157
+ ess: Math.round(ess),
158
+ weight_ratio: N / ess,
159
+ method: "maic",
160
+ };
161
+ }
162
+ /**
163
+ * Simulated Treatment Comparison (STC).
164
+ *
165
+ * Uses outcome regression to adjust the index trial effect for differences
166
+ * in effect modifiers. Simpler than MAIC but assumes a linear relationship
167
+ * between covariates and outcome.
168
+ */
169
+ function runSTC(params) {
170
+ const idx = params.index_trial;
171
+ const tgt = params.target_trial;
172
+ const logScale = isLogScale(idx.measure);
173
+ const modifiers = params.effect_modifiers;
174
+ const idxCovs = new Map(idx.covariates.map((c) => [c.name, c]));
175
+ const tgtCovs = new Map(tgt.covariates.map((c) => [c.name, c]));
176
+ // STC adjusts the treatment effect by estimating how much the
177
+ // covariate imbalance biases the comparison.
178
+ // Adjustment = sum_k beta_k * (mean_target_k - mean_index_k)
179
+ // where beta_k is the interaction coefficient (treatment * covariate)
180
+ //
181
+ // Without IPD, we approximate beta_k from the effect size and
182
+ // covariate spread using a heuristic regression coefficient.
183
+ const idxEffect = logScale ? Math.log(idx.effect) : idx.effect;
184
+ const tgtEffect = logScale ? Math.log(tgt.effect) : tgt.effect;
185
+ const idxSE = seFromCI(idx.effect, idx.ci_lower, idx.ci_upper, logScale);
186
+ const tgtSE = seFromCI(tgt.effect, tgt.ci_lower, tgt.ci_upper, logScale);
187
+ let totalAdjustment = 0;
188
+ let adjustmentVariance = 0;
189
+ for (const mod of modifiers) {
190
+ const idxC = idxCovs.get(mod);
191
+ const tgtC = tgtCovs.get(mod);
192
+ if (!idxC || !tgtC)
193
+ continue;
194
+ const meanDiff = tgtC.mean - idxC.mean;
195
+ const pooledSD = Math.sqrt((idxC.sd * idxC.sd + tgtC.sd * tgtC.sd) / 2);
196
+ // Standardized mean difference
197
+ const smd = pooledSD > 0 ? meanDiff / pooledSD : 0;
198
+ // Heuristic: interaction effect is proportional to main effect * SMD
199
+ // This is a simplification; with real IPD you'd fit the regression
200
+ const interactionEffect = idxEffect * 0.1 * smd;
201
+ totalAdjustment += interactionEffect;
202
+ // Variance of adjustment (approximation)
203
+ const adjVar = (idxSE * 0.1 * smd) * (idxSE * 0.1 * smd) +
204
+ (idxEffect * 0.1 * (1 / Math.sqrt(idx.n))) *
205
+ (idxEffect * 0.1 * (1 / Math.sqrt(idx.n)));
206
+ adjustmentVariance += adjVar;
207
+ }
208
+ // Adjusted indirect comparison
209
+ const adjustedIndirect = idxEffect + totalAdjustment - tgtEffect;
210
+ const combinedSE = Math.sqrt(idxSE * idxSE + tgtSE * tgtSE + adjustmentVariance);
211
+ const adjusted_effect = logScale
212
+ ? Math.exp(adjustedIndirect)
213
+ : adjustedIndirect;
214
+ const adjusted_ci_lower = logScale
215
+ ? Math.exp(adjustedIndirect - 1.96 * combinedSE)
216
+ : adjustedIndirect - 1.96 * combinedSE;
217
+ const adjusted_ci_upper = logScale
218
+ ? Math.exp(adjustedIndirect + 1.96 * combinedSE)
219
+ : adjustedIndirect + 1.96 * combinedSE;
220
+ // ESS for STC is approximately the index trial N (less inflation than MAIC)
221
+ const ess = Math.round(idx.n * 0.9);
222
+ return {
223
+ adjusted_effect,
224
+ adjusted_se: combinedSE,
225
+ adjusted_ci_lower,
226
+ adjusted_ci_upper,
227
+ ess,
228
+ method: "stc",
229
+ };
230
+ }
231
+ export async function handlePopulationAdjustedComparison(rawParams) {
232
+ const params = PopAdjSchema.parse(rawParams);
233
+ const outputFormat = params.output_format ?? "text";
234
+ let audit = createAuditRecord("population_adjusted_comparison", params, outputFormat);
235
+ // Validate effect modifiers exist in both trials
236
+ for (const mod of params.effect_modifiers) {
237
+ const inIdx = params.index_trial.covariates.some((c) => c.name === mod);
238
+ const inTgt = params.target_trial.covariates.some((c) => c.name === mod);
239
+ if (!inIdx || !inTgt) {
240
+ audit = addWarning(audit, `Effect modifier '${mod}' not found in both trials — will be skipped`);
241
+ }
242
+ }
243
+ // Auto-select method
244
+ let method = params.method;
245
+ if (method === "auto") {
246
+ // MAIC preferred when sufficient covariates and reasonable sample size
247
+ method =
248
+ params.effect_modifiers.length >= 2 && params.index_trial.n >= 50
249
+ ? "maic"
250
+ : "stc";
251
+ }
252
+ audit = setMethodology(audit, method === "maic"
253
+ ? "Matching-Adjusted Indirect Comparison (MAIC) — NICE DSU TSD 18 (Phillippo 2016), Signorovitch 2010"
254
+ : "Simulated Treatment Comparison (STC) — NICE DSU TSD 18 (Phillippo 2016)");
255
+ audit = addAssumption(audit, `Index trial: ${params.index_trial.name} (N=${params.index_trial.n})`);
256
+ audit = addAssumption(audit, `Target trial: ${params.target_trial.name} (N=${params.target_trial.n})`);
257
+ audit = addAssumption(audit, `Effect modifiers adjusted: ${params.effect_modifiers.join(", ")}`);
258
+ audit = addAssumption(audit, `Summary-level data used (no individual patient data) — results are approximate`);
259
+ let result;
260
+ try {
261
+ result =
262
+ method === "maic" ? runMAIC(params) : runSTC(params);
263
+ }
264
+ catch (err) {
265
+ const msg = err instanceof Error ? err.message : String(err);
266
+ audit = addWarning(audit, `${method.toUpperCase()} failed: ${msg}`);
267
+ return {
268
+ content: `Error running ${method.toUpperCase()}: ${msg}`,
269
+ audit,
270
+ };
271
+ }
272
+ const measure = params.index_trial.measure;
273
+ const logScale = isLogScale(measure);
274
+ // ESS warning
275
+ if (result.ess < params.index_trial.n * 0.5) {
276
+ audit = addWarning(audit, `Effective sample size (${result.ess}) is less than 50% of original N (${params.index_trial.n}) — large covariate imbalance, results may be unstable`);
277
+ }
278
+ if (outputFormat === "json") {
279
+ return {
280
+ content: {
281
+ method: result.method,
282
+ index_trial: params.index_trial.name,
283
+ target_trial: params.target_trial.name,
284
+ comparison: `${params.index_trial.treatment} vs ${params.target_trial.treatment}`,
285
+ outcome: params.outcome_name,
286
+ measure,
287
+ adjusted_effect: result.adjusted_effect,
288
+ adjusted_ci_lower: result.adjusted_ci_lower,
289
+ adjusted_ci_upper: result.adjusted_ci_upper,
290
+ ess: result.ess,
291
+ original_n: params.index_trial.n,
292
+ effect_modifiers: params.effect_modifiers,
293
+ },
294
+ audit,
295
+ };
296
+ }
297
+ const fmtEff = (v) => logScale ? v.toFixed(3) : v.toFixed(4);
298
+ const sig = (result.adjusted_ci_lower > (logScale ? 1 : 0) ||
299
+ result.adjusted_ci_upper < (logScale ? 1 : 0))
300
+ ? "statistically significant"
301
+ : "not statistically significant";
302
+ const lines = [
303
+ `## Population-Adjusted Indirect Comparison (${result.method.toUpperCase()})`,
304
+ ``,
305
+ `### Comparison`,
306
+ `**${params.index_trial.treatment}** vs **${params.target_trial.treatment}**`,
307
+ ``,
308
+ `| | Index Trial | Target Trial |`,
309
+ `|--|------------|-------------|`,
310
+ `| Trial | ${params.index_trial.name} | ${params.target_trial.name} |`,
311
+ `| N | ${params.index_trial.n} | ${params.target_trial.n} |`,
312
+ `| Treatment | ${params.index_trial.treatment} | ${params.target_trial.treatment} |`,
313
+ `| Comparator | ${params.index_trial.comparator} | ${params.target_trial.comparator} |`,
314
+ `| Effect (${measure}) | ${fmtEff(params.index_trial.effect)} (${fmtEff(params.index_trial.ci_lower)}–${fmtEff(params.index_trial.ci_upper)}) | ${fmtEff(params.target_trial.effect)} (${fmtEff(params.target_trial.ci_lower)}–${fmtEff(params.target_trial.ci_upper)}) |`,
315
+ ``,
316
+ `### Effect Modifiers Adjusted`,
317
+ ...params.effect_modifiers.map((mod) => {
318
+ const idxC = params.index_trial.covariates.find((c) => c.name === mod);
319
+ const tgtC = params.target_trial.covariates.find((c) => c.name === mod);
320
+ return `- **${mod}**: Index ${idxC?.mean.toFixed(1)} (SD ${idxC?.sd.toFixed(1)}) vs Target ${tgtC?.mean.toFixed(1)} (SD ${tgtC?.sd.toFixed(1)})`;
321
+ }),
322
+ ``,
323
+ `### Adjusted Result`,
324
+ `| Metric | Value |`,
325
+ `|--------|-------|`,
326
+ `| Method | ${result.method.toUpperCase()} |`,
327
+ `| Adjusted ${measure} | **${fmtEff(result.adjusted_effect)}** |`,
328
+ `| 95% CI | ${fmtEff(result.adjusted_ci_lower)} – ${fmtEff(result.adjusted_ci_upper)} |`,
329
+ `| Effective Sample Size | ${result.ess} (original: ${params.index_trial.n}) |`,
330
+ `| Statistical Significance | ${sig} |`,
331
+ ``,
332
+ result.ess < params.index_trial.n * 0.5
333
+ ? `> **Warning:** ESS is ${((result.ess / params.index_trial.n) * 100).toFixed(0)}% of original N — substantial precision loss from population adjustment.\n`
334
+ : "",
335
+ `### Limitations`,
336
+ `1. Summary-level data used — results are approximate compared to IPD-based MAIC/STC`,
337
+ `2. ${result.method === "maic" ? "Assumes covariates are normally distributed in the index trial" : "Assumes linear relationship between covariates and outcome"}`,
338
+ `3. Only observed effect modifiers can be adjusted — unobserved confounders remain`,
339
+ `4. Anchored comparison assumes a common comparator across trials`,
340
+ `5. Results should be interpreted alongside unadjusted indirect comparisons (e.g., Bucher method)`,
341
+ ``,
342
+ `---`,
343
+ `> **Disclaimer:** This population-adjusted comparison is for orientation only. Final analyses should use individual patient data where available and be validated by a qualified statistician.`,
344
+ ``,
345
+ auditToMarkdown(audit),
346
+ ]
347
+ .filter(Boolean)
348
+ .join("\n");
349
+ return { content: lines, audit };
350
+ }
351
+ export const populationAdjustedComparisonToolSchema = {
352
+ name: "population_adjusted_comparison",
353
+ description: "Perform a population-adjusted indirect comparison using MAIC (Matching-Adjusted Indirect Comparison) or STC (Simulated Treatment Comparison). Adjusts for differences in effect modifiers between two trials that share a common comparator. Follows NICE DSU TSD 18 (Phillippo 2016) and ISPOR guidance. Accepts summary-level statistics (mean, SD per covariate) — no individual patient data required.",
354
+ inputSchema: {
355
+ type: "object",
356
+ properties: {
357
+ index_trial: {
358
+ type: "object",
359
+ description: "Trial with data to be reweighted (the trial for which you want to adjust)",
360
+ properties: {
361
+ name: { type: "string", description: "Trial name (e.g., 'SUSTAIN-7')" },
362
+ treatment: { type: "string", description: "Treatment arm name" },
363
+ comparator: { type: "string", description: "Comparator arm name" },
364
+ n: { type: "number", description: "Sample size" },
365
+ effect: { type: "number", description: "Point estimate (HR, OR, RR, or MD)" },
366
+ ci_lower: { type: "number", description: "Lower 95% CI" },
367
+ ci_upper: { type: "number", description: "Upper 95% CI" },
368
+ measure: { type: "string", enum: ["MD", "OR", "RR", "HR"] },
369
+ covariates: {
370
+ type: "array",
371
+ items: {
372
+ type: "object",
373
+ properties: {
374
+ name: { type: "string", description: "Covariate name (e.g., 'age', 'bmi', 'hba1c_baseline')" },
375
+ mean: { type: "number" },
376
+ sd: { type: "number" },
377
+ },
378
+ required: ["name", "mean", "sd"],
379
+ },
380
+ },
381
+ },
382
+ required: ["name", "treatment", "comparator", "n", "effect", "ci_lower", "ci_upper", "measure", "covariates"],
383
+ },
384
+ target_trial: {
385
+ type: "object",
386
+ description: "Trial whose population is the matching target",
387
+ properties: {
388
+ name: { type: "string" },
389
+ treatment: { type: "string" },
390
+ comparator: { type: "string" },
391
+ n: { type: "number" },
392
+ effect: { type: "number" },
393
+ ci_lower: { type: "number" },
394
+ ci_upper: { type: "number" },
395
+ measure: { type: "string", enum: ["MD", "OR", "RR", "HR"] },
396
+ covariates: {
397
+ type: "array",
398
+ items: {
399
+ type: "object",
400
+ properties: {
401
+ name: { type: "string" },
402
+ mean: { type: "number" },
403
+ sd: { type: "number" },
404
+ },
405
+ required: ["name", "mean", "sd"],
406
+ },
407
+ },
408
+ },
409
+ required: ["name", "treatment", "comparator", "n", "effect", "ci_lower", "ci_upper", "measure", "covariates"],
410
+ },
411
+ effect_modifiers: {
412
+ type: "array",
413
+ items: { type: "string" },
414
+ description: "Names of covariates that are effect modifiers (must appear in both trials' covariates)",
415
+ },
416
+ method: {
417
+ type: "string",
418
+ enum: ["auto", "maic", "stc"],
419
+ description: "auto (default): MAIC when >=2 modifiers and N>=50, else STC",
420
+ },
421
+ outcome_name: {
422
+ type: "string",
423
+ description: "Name of the outcome being compared (e.g., 'HbA1c change')",
424
+ },
425
+ output_format: { type: "string", enum: ["text", "json"] },
426
+ project: { type: "string", description: "Project ID for persistence" },
427
+ },
428
+ required: ["index_trial", "target_trial", "effect_modifiers"],
429
+ },
430
+ };
431
+ //# sourceMappingURL=populationAdjustedComparison.js.map