@iris-eval/mcp-server 0.2.3 → 0.3.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/dist/config/index.js +9 -2
- package/dist/cost-estimator.d.ts +49 -0
- package/dist/cost-estimator.js +72 -0
- package/dist/dashboard/assets/index-CnDg6bYi.js +43 -0
- package/dist/dashboard/assets/index-ZsBou2-c.css +1 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/index.js +63 -17
- package/dist/storage/index.js +1 -1
- package/dist/storage/sqlite-adapter.js +3 -3
- package/package.json +1 -1
- package/server.json +2 -2
- package/dist/dashboard/assets/index-BNDB0-BX.js +0 -43
- package/dist/dashboard/assets/index-CAwaZNw5.css +0 -1
package/dist/config/index.js
CHANGED
|
@@ -38,13 +38,20 @@ function loadConfigFile(path) {
|
|
|
38
38
|
throw new Error(`Invalid JSON in config file ${path}: ${err.message}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
function parsePortEnv(value, name) {
|
|
42
|
+
const n = parseInt(value, 10);
|
|
43
|
+
if (!Number.isFinite(n) || n < 1 || n > 65535) {
|
|
44
|
+
throw new Error(`${name}=${JSON.stringify(value)} is not a valid port (must be an integer 1-65535)`);
|
|
45
|
+
}
|
|
46
|
+
return n;
|
|
47
|
+
}
|
|
41
48
|
function loadEnvVars() {
|
|
42
49
|
const config = {};
|
|
43
50
|
if (process.env.IRIS_TRANSPORT) {
|
|
44
51
|
config.transport = { type: process.env.IRIS_TRANSPORT };
|
|
45
52
|
}
|
|
46
53
|
if (process.env.IRIS_PORT) {
|
|
47
|
-
config.transport = { ...config.transport, port:
|
|
54
|
+
config.transport = { ...config.transport, port: parsePortEnv(process.env.IRIS_PORT, 'IRIS_PORT') };
|
|
48
55
|
}
|
|
49
56
|
if (process.env.IRIS_HOST) {
|
|
50
57
|
config.transport = { ...config.transport, host: process.env.IRIS_HOST };
|
|
@@ -61,7 +68,7 @@ function loadEnvVars() {
|
|
|
61
68
|
if (process.env.IRIS_DASHBOARD_PORT) {
|
|
62
69
|
config.dashboard = {
|
|
63
70
|
...config.dashboard,
|
|
64
|
-
port:
|
|
71
|
+
port: parsePortEnv(process.env.IRIS_DASHBOARD_PORT, 'IRIS_DASHBOARD_PORT'),
|
|
65
72
|
};
|
|
66
73
|
}
|
|
67
74
|
if (process.env.IRIS_API_KEY) {
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export type Provider = 'anthropic' | 'openai';
|
|
2
|
+
export interface ModelPricing {
|
|
3
|
+
/** USD per 1M input tokens. */
|
|
4
|
+
inputPerMillion: number;
|
|
5
|
+
/** USD per 1M output tokens. */
|
|
6
|
+
outputPerMillion: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Pricing as of 2026-04-21. Verify against provider documentation
|
|
10
|
+
* at minor-release boundaries.
|
|
11
|
+
*
|
|
12
|
+
* Sources:
|
|
13
|
+
* - Anthropic: anthropic.com/pricing
|
|
14
|
+
* - OpenAI: openai.com/api/pricing
|
|
15
|
+
*/
|
|
16
|
+
export declare const PRICING: Record<Provider, Record<string, ModelPricing>>;
|
|
17
|
+
export interface EstimateInput {
|
|
18
|
+
provider: Provider;
|
|
19
|
+
/** Model name. Match keys in PRICING for exact pricing; otherwise estimate returns null. */
|
|
20
|
+
model: string;
|
|
21
|
+
/** Input token count for this call. */
|
|
22
|
+
tokensIn: number;
|
|
23
|
+
/** Output token count for this call. */
|
|
24
|
+
tokensOut: number;
|
|
25
|
+
}
|
|
26
|
+
export interface CostEstimate {
|
|
27
|
+
/** USD cost for the call. */
|
|
28
|
+
totalUsd: number;
|
|
29
|
+
/** USD cost for input tokens only. */
|
|
30
|
+
inputUsd: number;
|
|
31
|
+
/** USD cost for output tokens only. */
|
|
32
|
+
outputUsd: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Estimate USD cost for a single LLM call given token counts + model.
|
|
36
|
+
* Returns null if the model is not in the pricing table — caller should
|
|
37
|
+
* either supply pricing override or accept "unknown cost" for that call.
|
|
38
|
+
*/
|
|
39
|
+
export declare function estimateCost(input: EstimateInput): CostEstimate | null;
|
|
40
|
+
/**
|
|
41
|
+
* Sum cost estimates across multiple calls. Skips calls where the model
|
|
42
|
+
* is not in the pricing table; the caller can detect via the return's
|
|
43
|
+
* `unknownModelCount`.
|
|
44
|
+
*/
|
|
45
|
+
export declare function estimateBatch(inputs: EstimateInput[]): {
|
|
46
|
+
totalUsd: number;
|
|
47
|
+
estimatedCount: number;
|
|
48
|
+
unknownModelCount: number;
|
|
49
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Cost estimator — converts (token-count × model) into USD cost.
|
|
3
|
+
*
|
|
4
|
+
* Pricing tables embedded here for the major providers. Updated when
|
|
5
|
+
* provider pricing changes; provider documentation is the source of truth.
|
|
6
|
+
*
|
|
7
|
+
* v0.3.1 — first public surface.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Pricing as of 2026-04-21. Verify against provider documentation
|
|
11
|
+
* at minor-release boundaries.
|
|
12
|
+
*
|
|
13
|
+
* Sources:
|
|
14
|
+
* - Anthropic: anthropic.com/pricing
|
|
15
|
+
* - OpenAI: openai.com/api/pricing
|
|
16
|
+
*/
|
|
17
|
+
export const PRICING = {
|
|
18
|
+
anthropic: {
|
|
19
|
+
'claude-opus-4': { inputPerMillion: 15, outputPerMillion: 75 },
|
|
20
|
+
'claude-sonnet-4': { inputPerMillion: 3, outputPerMillion: 15 },
|
|
21
|
+
'claude-haiku-4-5': { inputPerMillion: 1, outputPerMillion: 5 },
|
|
22
|
+
'claude-3-5-sonnet': { inputPerMillion: 3, outputPerMillion: 15 },
|
|
23
|
+
'claude-3-5-haiku': { inputPerMillion: 0.8, outputPerMillion: 4 },
|
|
24
|
+
},
|
|
25
|
+
openai: {
|
|
26
|
+
'gpt-4o': { inputPerMillion: 2.5, outputPerMillion: 10 },
|
|
27
|
+
'gpt-4o-mini': { inputPerMillion: 0.15, outputPerMillion: 0.6 },
|
|
28
|
+
'o1': { inputPerMillion: 15, outputPerMillion: 60 },
|
|
29
|
+
'o1-mini': { inputPerMillion: 3, outputPerMillion: 12 },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Estimate USD cost for a single LLM call given token counts + model.
|
|
34
|
+
* Returns null if the model is not in the pricing table — caller should
|
|
35
|
+
* either supply pricing override or accept "unknown cost" for that call.
|
|
36
|
+
*/
|
|
37
|
+
export function estimateCost(input) {
|
|
38
|
+
const providerTable = PRICING[input.provider];
|
|
39
|
+
if (!providerTable)
|
|
40
|
+
return null;
|
|
41
|
+
const pricing = providerTable[input.model];
|
|
42
|
+
if (!pricing)
|
|
43
|
+
return null;
|
|
44
|
+
const inputUsd = (input.tokensIn / 1_000_000) * pricing.inputPerMillion;
|
|
45
|
+
const outputUsd = (input.tokensOut / 1_000_000) * pricing.outputPerMillion;
|
|
46
|
+
return {
|
|
47
|
+
totalUsd: inputUsd + outputUsd,
|
|
48
|
+
inputUsd,
|
|
49
|
+
outputUsd,
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Sum cost estimates across multiple calls. Skips calls where the model
|
|
54
|
+
* is not in the pricing table; the caller can detect via the return's
|
|
55
|
+
* `unknownModelCount`.
|
|
56
|
+
*/
|
|
57
|
+
export function estimateBatch(inputs) {
|
|
58
|
+
let totalUsd = 0;
|
|
59
|
+
let estimatedCount = 0;
|
|
60
|
+
let unknownModelCount = 0;
|
|
61
|
+
for (const input of inputs) {
|
|
62
|
+
const est = estimateCost(input);
|
|
63
|
+
if (est === null) {
|
|
64
|
+
unknownModelCount += 1;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
totalUsd += est.totalUsd;
|
|
68
|
+
estimatedCount += 1;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return { totalUsd, estimatedCount, unknownModelCount };
|
|
72
|
+
}
|