@animalabs/membrane 0.5.42 → 0.5.44
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/formatters/completions.d.ts +7 -0
- package/dist/formatters/completions.d.ts.map +1 -1
- package/dist/formatters/completions.js +9 -0
- package/dist/formatters/completions.js.map +1 -1
- package/dist/formatters/index.d.ts +1 -0
- package/dist/formatters/index.js +1 -0
- package/dist/formatters/index.js.map +1 -1
- package/dist/formatters/types.d.ts +4 -0
- package/dist/membrane.d.ts +3 -0
- package/dist/membrane.d.ts.map +1 -1
- package/dist/membrane.js +75 -12
- package/dist/membrane.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +9 -1
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/bedrock.js +4 -13
- package/dist/providers/bedrock.js.map +1 -1
- package/dist/providers/gemini.js +2 -11
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai-compatible.js +15 -25
- package/dist/providers/openai-compatible.js.map +1 -1
- package/dist/providers/openai-completions.js +24 -48
- package/dist/providers/openai-completions.js.map +1 -1
- package/dist/providers/openai-responses.js +1 -6
- package/dist/providers/openai-responses.js.map +1 -1
- package/dist/providers/openai.js +15 -25
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.js +16 -35
- package/dist/providers/openrouter.js.map +1 -1
- package/dist/providers/utils.d.ts +0 -38
- package/dist/providers/utils.d.ts.map +1 -1
- package/dist/providers/utils.js +0 -86
- package/dist/providers/utils.js.map +1 -1
- package/dist/registry/default-pricing.d.ts +3 -0
- package/dist/registry/default-pricing.d.ts.map +1 -0
- package/dist/registry/default-pricing.js +75 -0
- package/dist/registry/default-pricing.js.map +1 -0
- package/dist/types/request.d.ts +0 -8
- package/dist/types/request.d.ts.map +1 -1
- package/dist/types/yielding-stream.d.ts +2 -2
- package/dist/types/yielding-stream.d.ts.map +1 -1
- package/dist/utils/cost.d.ts +10 -0
- package/dist/utils/cost.d.ts.map +1 -0
- package/dist/utils/cost.js +19 -0
- package/dist/utils/cost.js.map +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/package.json +1 -1
- package/src/formatters/completions.ts +19 -0
- package/src/membrane.ts +83 -18
- package/src/providers/anthropic.ts +13 -1
- package/src/registry/default-pricing.ts +77 -0
- package/src/types/yielding-stream.ts +2 -2
- package/src/utils/cost.ts +29 -0
- package/src/utils/index.ts +3 -0
|
@@ -3,42 +3,4 @@
|
|
|
3
3
|
* Used for tool call arguments which may be malformed from streaming.
|
|
4
4
|
*/
|
|
5
5
|
export declare function safeParseJson(str: string | undefined): Record<string, unknown>;
|
|
6
|
-
/**
|
|
7
|
-
* Create a combined AbortSignal that fires on either the caller's signal
|
|
8
|
-
* or a timeout (whichever comes first).
|
|
9
|
-
*
|
|
10
|
-
* The returned `cleanup` function MUST be called in a `finally` block to
|
|
11
|
-
* clear the timeout and remove the event listener, preventing leaks.
|
|
12
|
-
*
|
|
13
|
-
* Timeout aborts with `DOMException('Request timed out', 'AbortError')`
|
|
14
|
-
* so it classifies identically to user-initiated aborts.
|
|
15
|
-
*/
|
|
16
|
-
export declare function createCombinedSignal(signal?: AbortSignal, timeoutMs?: number): {
|
|
17
|
-
signal?: AbortSignal;
|
|
18
|
-
cleanup?: () => void;
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* SSE (Server-Sent Events) line parser that correctly handles events
|
|
22
|
-
* split across multiple TCP chunks.
|
|
23
|
-
*
|
|
24
|
-
* The naive approach of `chunk.split('\n').filter(l => l.startsWith('data: '))`
|
|
25
|
-
* silently drops events when an SSE line spans two chunks:
|
|
26
|
-
* Chunk 1: `data: {"choices":[{"delta":{"content":"don'` (no newline — incomplete)
|
|
27
|
-
* Chunk 2: `t do that"}}]}\n` (doesn't start with `data: `)
|
|
28
|
-
* Result: the entire event is lost, causing "skipped words" in output.
|
|
29
|
-
*
|
|
30
|
-
* This parser buffers partial lines and only yields complete `data: ...` lines.
|
|
31
|
-
*/
|
|
32
|
-
export declare class SSELineParser {
|
|
33
|
-
private buffer;
|
|
34
|
-
/**
|
|
35
|
-
* Feed a raw chunk from the stream reader and get back complete SSE data lines.
|
|
36
|
-
* Each returned string is the content after `data: ` (e.g. the JSON payload or `[DONE]`).
|
|
37
|
-
*/
|
|
38
|
-
feed(chunk: string): string[];
|
|
39
|
-
/**
|
|
40
|
-
* Flush any remaining buffered content (call when stream ends).
|
|
41
|
-
*/
|
|
42
|
-
flush(): string[];
|
|
43
|
-
}
|
|
44
6
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO9E
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO9E"}
|
package/dist/providers/utils.js
CHANGED
|
@@ -11,90 +11,4 @@ export function safeParseJson(str) {
|
|
|
11
11
|
return {};
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Create a combined AbortSignal that fires on either the caller's signal
|
|
16
|
-
* or a timeout (whichever comes first).
|
|
17
|
-
*
|
|
18
|
-
* The returned `cleanup` function MUST be called in a `finally` block to
|
|
19
|
-
* clear the timeout and remove the event listener, preventing leaks.
|
|
20
|
-
*
|
|
21
|
-
* Timeout aborts with `DOMException('Request timed out', 'AbortError')`
|
|
22
|
-
* so it classifies identically to user-initiated aborts.
|
|
23
|
-
*/
|
|
24
|
-
export function createCombinedSignal(signal, timeoutMs) {
|
|
25
|
-
if (!signal && !timeoutMs)
|
|
26
|
-
return {};
|
|
27
|
-
if (signal && !timeoutMs)
|
|
28
|
-
return { signal };
|
|
29
|
-
const controller = new AbortController();
|
|
30
|
-
let timeoutId;
|
|
31
|
-
if (timeoutMs) {
|
|
32
|
-
timeoutId = setTimeout(() => controller.abort(new DOMException('Request timed out', 'AbortError')), timeoutMs);
|
|
33
|
-
}
|
|
34
|
-
const onAbort = () => controller.abort(signal.reason);
|
|
35
|
-
if (signal) {
|
|
36
|
-
if (signal.aborted) {
|
|
37
|
-
controller.abort(signal.reason);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
signal.addEventListener('abort', onAbort, { once: true });
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
signal: controller.signal,
|
|
45
|
-
cleanup: () => {
|
|
46
|
-
if (timeoutId)
|
|
47
|
-
clearTimeout(timeoutId);
|
|
48
|
-
if (signal)
|
|
49
|
-
signal.removeEventListener('abort', onAbort);
|
|
50
|
-
},
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* SSE (Server-Sent Events) line parser that correctly handles events
|
|
55
|
-
* split across multiple TCP chunks.
|
|
56
|
-
*
|
|
57
|
-
* The naive approach of `chunk.split('\n').filter(l => l.startsWith('data: '))`
|
|
58
|
-
* silently drops events when an SSE line spans two chunks:
|
|
59
|
-
* Chunk 1: `data: {"choices":[{"delta":{"content":"don'` (no newline — incomplete)
|
|
60
|
-
* Chunk 2: `t do that"}}]}\n` (doesn't start with `data: `)
|
|
61
|
-
* Result: the entire event is lost, causing "skipped words" in output.
|
|
62
|
-
*
|
|
63
|
-
* This parser buffers partial lines and only yields complete `data: ...` lines.
|
|
64
|
-
*/
|
|
65
|
-
export class SSELineParser {
|
|
66
|
-
buffer = '';
|
|
67
|
-
/**
|
|
68
|
-
* Feed a raw chunk from the stream reader and get back complete SSE data lines.
|
|
69
|
-
* Each returned string is the content after `data: ` (e.g. the JSON payload or `[DONE]`).
|
|
70
|
-
*/
|
|
71
|
-
feed(chunk) {
|
|
72
|
-
this.buffer += chunk;
|
|
73
|
-
const results = [];
|
|
74
|
-
// Split on newlines, keeping the last (potentially incomplete) segment in the buffer
|
|
75
|
-
const lines = this.buffer.split('\n');
|
|
76
|
-
this.buffer = lines.pop() || '';
|
|
77
|
-
for (const line of lines) {
|
|
78
|
-
const trimmed = line.trim();
|
|
79
|
-
if (trimmed.startsWith('data: ')) {
|
|
80
|
-
results.push(trimmed.slice(6));
|
|
81
|
-
}
|
|
82
|
-
// Skip empty lines, comments (`:...`), and other SSE fields (event:, id:, retry:)
|
|
83
|
-
}
|
|
84
|
-
return results;
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Flush any remaining buffered content (call when stream ends).
|
|
88
|
-
*/
|
|
89
|
-
flush() {
|
|
90
|
-
if (!this.buffer.trim())
|
|
91
|
-
return [];
|
|
92
|
-
const trimmed = this.buffer.trim();
|
|
93
|
-
this.buffer = '';
|
|
94
|
-
if (trimmed.startsWith('data: ')) {
|
|
95
|
-
return [trimmed.slice(6)];
|
|
96
|
-
}
|
|
97
|
-
return [];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
14
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAuB;IACnD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,CAAC,CAAC,CAAC;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAuB;IACnD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,IAAI,CAAC,iDAAiD,EAAE,CAAC,CAAC,CAAC;QACnE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-pricing.d.ts","sourceRoot":"","sources":["../../src/registry/default-pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAkEzD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAU3E"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in pricing table for known models.
|
|
3
|
+
* Prices in USD per million tokens. Last updated: 2025-07.
|
|
4
|
+
*
|
|
5
|
+
* Used as fallback when no ModelRegistry is configured.
|
|
6
|
+
* Registry pricing (if available) takes precedence.
|
|
7
|
+
*/
|
|
8
|
+
const PRICING_TABLE = [
|
|
9
|
+
// Anthropic — Claude 4.6
|
|
10
|
+
{
|
|
11
|
+
prefix: 'claude-opus-4-6',
|
|
12
|
+
pricing: { inputPerMillion: 15, outputPerMillion: 75, cacheWritePerMillion: 18.75, cacheReadPerMillion: 1.50, currency: 'USD' },
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
prefix: 'claude-sonnet-4-6',
|
|
16
|
+
pricing: { inputPerMillion: 3, outputPerMillion: 15, cacheWritePerMillion: 3.75, cacheReadPerMillion: 0.30, currency: 'USD' },
|
|
17
|
+
},
|
|
18
|
+
// Anthropic — Claude 4.5
|
|
19
|
+
{
|
|
20
|
+
prefix: 'claude-haiku-4-5',
|
|
21
|
+
pricing: { inputPerMillion: 0.80, outputPerMillion: 4, cacheWritePerMillion: 1.00, cacheReadPerMillion: 0.08, currency: 'USD' },
|
|
22
|
+
},
|
|
23
|
+
// Anthropic — Claude 4
|
|
24
|
+
{
|
|
25
|
+
prefix: 'claude-opus-4',
|
|
26
|
+
pricing: { inputPerMillion: 15, outputPerMillion: 75, cacheWritePerMillion: 18.75, cacheReadPerMillion: 1.50, currency: 'USD' },
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
prefix: 'claude-sonnet-4',
|
|
30
|
+
pricing: { inputPerMillion: 3, outputPerMillion: 15, cacheWritePerMillion: 3.75, cacheReadPerMillion: 0.30, currency: 'USD' },
|
|
31
|
+
},
|
|
32
|
+
// Anthropic — Claude 3.5
|
|
33
|
+
{
|
|
34
|
+
prefix: 'claude-3-5-sonnet',
|
|
35
|
+
pricing: { inputPerMillion: 3, outputPerMillion: 15, cacheWritePerMillion: 3.75, cacheReadPerMillion: 0.30, currency: 'USD' },
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
prefix: 'claude-3-5-haiku',
|
|
39
|
+
pricing: { inputPerMillion: 0.80, outputPerMillion: 4, cacheWritePerMillion: 1.00, cacheReadPerMillion: 0.08, currency: 'USD' },
|
|
40
|
+
},
|
|
41
|
+
// OpenAI — GPT-4o
|
|
42
|
+
{
|
|
43
|
+
prefix: 'gpt-4o-2024',
|
|
44
|
+
pricing: { inputPerMillion: 2.50, outputPerMillion: 10, cacheReadPerMillion: 1.25, currency: 'USD' },
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
prefix: 'gpt-4o',
|
|
48
|
+
pricing: { inputPerMillion: 2.50, outputPerMillion: 10, cacheReadPerMillion: 1.25, currency: 'USD' },
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
prefix: 'gpt-4o-mini',
|
|
52
|
+
pricing: { inputPerMillion: 0.15, outputPerMillion: 0.60, cacheReadPerMillion: 0.075, currency: 'USD' },
|
|
53
|
+
},
|
|
54
|
+
// Google — Gemini 2.5
|
|
55
|
+
{
|
|
56
|
+
prefix: 'gemini-2.5-pro',
|
|
57
|
+
pricing: { inputPerMillion: 1.25, outputPerMillion: 10, currency: 'USD' },
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
prefix: 'gemini-2.5-flash',
|
|
61
|
+
pricing: { inputPerMillion: 0.15, outputPerMillion: 0.60, currency: 'USD' },
|
|
62
|
+
},
|
|
63
|
+
];
|
|
64
|
+
export function getDefaultPricing(modelId) {
|
|
65
|
+
let best;
|
|
66
|
+
let bestLen = 0;
|
|
67
|
+
for (const entry of PRICING_TABLE) {
|
|
68
|
+
if (modelId.startsWith(entry.prefix) && entry.prefix.length > bestLen) {
|
|
69
|
+
best = entry.pricing;
|
|
70
|
+
bestLen = entry.prefix.length;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return best;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=default-pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-pricing.js","sourceRoot":"","sources":["../../src/registry/default-pricing.ts"],"names":[],"mappings":"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"}
|
package/dist/types/request.d.ts
CHANGED
|
@@ -102,14 +102,6 @@ export interface NormalizedRequest {
|
|
|
102
102
|
* Default: 'Claude'
|
|
103
103
|
*/
|
|
104
104
|
assistantParticipant?: string;
|
|
105
|
-
/**
|
|
106
|
-
* Control streaming behavior when calling membrane.stream().
|
|
107
|
-
* - true or undefined: use streaming (default)
|
|
108
|
-
* - false: force non-streaming — membrane.stream() will internally use
|
|
109
|
-
* complete() and synthesize streaming callbacks from the full response.
|
|
110
|
-
* Useful for working around provider streaming bugs.
|
|
111
|
-
*/
|
|
112
|
-
streaming?: boolean;
|
|
113
105
|
/** Provider-specific parameters (pass-through) */
|
|
114
106
|
providerParams?: Record<string, unknown>;
|
|
115
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/types/request.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IAEd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAElB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,qCAAqC;IACrC,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF,uCAAuC;IACvC,eAAe,CAAC,EAAE;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;QACjC,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;QACtD,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;KAC1C,CAAC;CACH;AAMD,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,YAAY,GACZ,oBAAoB,CAAC;AAEzB,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAEhC,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAMD,MAAM,MAAM,QAAQ,GAChB,KAAK,GACL,QAAQ,GACR,MAAM,CAAC;AAMX,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAE9B,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,+BAA+B;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IAEzB,uBAAuB;IACvB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IAEzB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB,kCAAkC;IAClC,aAAa,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAAC;IAE9C;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/types/request.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAMjD,MAAM,WAAW,gBAAgB;IAC/B,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IAEd,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAElB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,4CAA4C;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B,qCAAqC;IACrC,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IAEF,uCAAuC;IACvC,eAAe,CAAC,EAAE;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;QACjC,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,CAAC;QACtD,SAAS,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;KAC1C,CAAC;CACH;AAMD,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,YAAY,GACZ,oBAAoB,CAAC;AAEzB,MAAM,WAAW,kBAAkB;IACjC,4BAA4B;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;IAEpB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAEhC,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAMD,MAAM,WAAW,cAAc;IAC7B,oCAAoC;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAMD,MAAM,MAAM,QAAQ,GAChB,KAAK,GACL,QAAQ,GACR,MAAM,CAAC;AAMX,MAAM,WAAW,iBAAiB;IAChC,4BAA4B;IAC5B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAE9B,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,+BAA+B;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IAEzB,uBAAuB;IACvB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IAEzB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB,kCAAkC;IAClC,aAAa,CAAC,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAAC;IAE9C;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IAEvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1C"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import type { ContentBlock } from './content.js';
|
|
11
11
|
import type { ToolCall, ToolResult, ToolContext } from './tools.js';
|
|
12
|
-
import type {
|
|
12
|
+
import type { DetailedUsage, NormalizedResponse } from './response.js';
|
|
13
13
|
import type { ChunkMeta, BlockEvent } from './streaming.js';
|
|
14
14
|
/**
|
|
15
15
|
* Token/chunk event - raw text as it arrives from the LLM.
|
|
@@ -40,7 +40,7 @@ export interface ToolCallsEvent {
|
|
|
40
40
|
*/
|
|
41
41
|
export interface UsageEvent {
|
|
42
42
|
type: 'usage';
|
|
43
|
-
usage:
|
|
43
|
+
usage: DetailedUsage;
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* Complete event - inference cycle finished successfully.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yielding-stream.d.ts","sourceRoot":"","sources":["../../src/types/yielding-stream.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"yielding-stream.d.ts","sourceRoot":"","sources":["../../src/types/yielding-stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { CostBreakdown } from '../types/response.js';
|
|
2
|
+
import type { ModelPricing } from '../types/provider.js';
|
|
3
|
+
export interface CostableUsage {
|
|
4
|
+
inputTokens: number;
|
|
5
|
+
outputTokens: number;
|
|
6
|
+
cacheCreationTokens?: number;
|
|
7
|
+
cacheReadTokens?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function calculateCost(usage: CostableUsage, pricing: ModelPricing): CostBreakdown;
|
|
10
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../src/utils/cost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,GAAG,aAAa,CAkBxF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function calculateCost(usage, pricing) {
|
|
2
|
+
const input = usage.inputTokens * pricing.inputPerMillion / 1_000_000;
|
|
3
|
+
const output = usage.outputTokens * pricing.outputPerMillion / 1_000_000;
|
|
4
|
+
const cacheWrite = pricing.cacheWritePerMillion != null
|
|
5
|
+
? (usage.cacheCreationTokens ?? 0) * pricing.cacheWritePerMillion / 1_000_000
|
|
6
|
+
: undefined;
|
|
7
|
+
const cacheRead = pricing.cacheReadPerMillion != null
|
|
8
|
+
? (usage.cacheReadTokens ?? 0) * pricing.cacheReadPerMillion / 1_000_000
|
|
9
|
+
: undefined;
|
|
10
|
+
return {
|
|
11
|
+
input,
|
|
12
|
+
output,
|
|
13
|
+
cacheWrite,
|
|
14
|
+
cacheRead,
|
|
15
|
+
total: input + output + (cacheWrite ?? 0) + (cacheRead ?? 0),
|
|
16
|
+
currency: pricing.currency,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../src/utils/cost.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,aAAa,CAAC,KAAoB,EAAE,OAAqB;IACvE,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IACtE,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IACzE,MAAM,UAAU,GAAG,OAAO,CAAC,oBAAoB,IAAI,IAAI;QACrD,CAAC,CAAC,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,oBAAoB,GAAG,SAAS;QAC7E,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,SAAS,GAAG,OAAO,CAAC,mBAAmB,IAAI,IAAI;QACnD,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,IAAI,CAAC,CAAC,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS;QACxE,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,KAAK;QACL,MAAM;QACN,UAAU;QACV,SAAS;QACT,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;QAC5D,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;AACJ,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@
|
|
|
2
2
|
* Utility exports
|
|
3
3
|
*/
|
|
4
4
|
export { parseToolCalls, formatToolResults, formatToolResult, formatToolDefinitions, getToolInstructions, hasUnclosedToolBlock, endsWithPartialToolBlock, unescapeXml, type ToolDefinitionForPrompt, } from './tool-parser.js';
|
|
5
|
+
export { calculateCost } from './cost.js';
|
|
6
|
+
export type { CostableUsage } from './cost.js';
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,WAAW,EACX,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,WAAW,EACX,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/utils/index.js
CHANGED
|
@@ -2,4 +2,5 @@
|
|
|
2
2
|
* Utility exports
|
|
3
3
|
*/
|
|
4
4
|
export { parseToolCalls, formatToolResults, formatToolResult, formatToolDefinitions, getToolInstructions, hasUnclosedToolBlock, endsWithPartialToolBlock, unescapeXml, } from './tool-parser.js';
|
|
5
|
+
export { calculateCost } from './cost.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,WAAW,GAEZ,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,wBAAwB,EACxB,WAAW,GAEZ,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
|
package/package.json
CHANGED
|
@@ -63,6 +63,14 @@ export interface CompletionsFormatterConfig extends FormatterConfig {
|
|
|
63
63
|
*/
|
|
64
64
|
maxParticipantsForStop?: number;
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Add lowercased variants of participant stop sequences.
|
|
68
|
+
* Useful for models whose tokenizer doesn't normalize casing,
|
|
69
|
+
* allowing simmed names with different casing to still trigger stops.
|
|
70
|
+
* Default: false
|
|
71
|
+
*/
|
|
72
|
+
caseInsensitiveStops?: boolean;
|
|
73
|
+
|
|
66
74
|
/**
|
|
67
75
|
* Whether to warn when images are stripped.
|
|
68
76
|
* Default: true
|
|
@@ -187,6 +195,7 @@ export class CompletionsFormatter implements PrefillFormatter {
|
|
|
187
195
|
nameFormat: config.nameFormat ?? '{name}: ',
|
|
188
196
|
messageSeparator: config.messageSeparator ?? '\n\n',
|
|
189
197
|
maxParticipantsForStop: config.maxParticipantsForStop ?? 10,
|
|
198
|
+
caseInsensitiveStops: config.caseInsensitiveStops ?? false,
|
|
190
199
|
warnOnImageStrip: config.warnOnImageStrip ?? true,
|
|
191
200
|
// Completions models don't support images - always strip
|
|
192
201
|
unsupportedMedia: 'strip',
|
|
@@ -364,6 +373,16 @@ export class CompletionsFormatter implements PrefillFormatter {
|
|
|
364
373
|
const prefix = this.config.nameFormat.replace('{name}', participant).trimEnd();
|
|
365
374
|
stops.push(`\n\n${prefix}`);
|
|
366
375
|
stops.push(`\n${prefix}`);
|
|
376
|
+
|
|
377
|
+
// Add lowercased variants if casing differs (for models that generate mixed-case names)
|
|
378
|
+
if (this.config.caseInsensitiveStops) {
|
|
379
|
+
const lower = this.config.nameFormat.replace('{name}', participant.toLowerCase()).trimEnd();
|
|
380
|
+
if (lower !== prefix) {
|
|
381
|
+
stops.push(`\n\n${lower}`);
|
|
382
|
+
stops.push(`\n${lower}`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
367
386
|
count++;
|
|
368
387
|
}
|
|
369
388
|
|
package/src/membrane.ts
CHANGED
|
@@ -53,6 +53,8 @@ import type {
|
|
|
53
53
|
import type { PrefillFormatter, StreamParser } from './formatters/types.js';
|
|
54
54
|
import { AnthropicXmlFormatter } from './formatters/anthropic-xml.js';
|
|
55
55
|
import { YieldingStreamImpl } from './yielding-stream.js';
|
|
56
|
+
import { calculateCost } from './utils/cost.js';
|
|
57
|
+
import { getDefaultPricing } from './registry/default-pricing.js';
|
|
56
58
|
|
|
57
59
|
// ============================================================================
|
|
58
60
|
// Membrane Class
|
|
@@ -273,6 +275,7 @@ export class Membrane {
|
|
|
273
275
|
const parser = formatter.createStreamParser();
|
|
274
276
|
let toolDepth = 0;
|
|
275
277
|
let totalUsage: DetailedUsage = { inputTokens: 0, outputTokens: 0 };
|
|
278
|
+
const pricing = this.resolvePricing(request.config.model);
|
|
276
279
|
const contentBlocks: ContentBlock[] = [];
|
|
277
280
|
let lastStopReason: StopReason = 'end_turn';
|
|
278
281
|
let lastStopSequence: string | undefined;
|
|
@@ -425,6 +428,7 @@ export class Membrane {
|
|
|
425
428
|
if (streamResult.usage.cacheReadTokens) {
|
|
426
429
|
totalUsage.cacheReadTokens = (totalUsage.cacheReadTokens ?? 0) + streamResult.usage.cacheReadTokens;
|
|
427
430
|
}
|
|
431
|
+
if (pricing) totalUsage.estimatedCost = calculateCost(totalUsage, pricing);
|
|
428
432
|
onUsage?.(totalUsage);
|
|
429
433
|
|
|
430
434
|
// Flush the parser to complete any in-progress streaming block
|
|
@@ -737,6 +741,7 @@ export class Membrane {
|
|
|
737
741
|
|
|
738
742
|
let toolDepth = 0;
|
|
739
743
|
let totalUsage: DetailedUsage = { inputTokens: 0, outputTokens: 0 };
|
|
744
|
+
const pricing = this.resolvePricing(request.config.model);
|
|
740
745
|
let lastStopReason: StopReason = 'end_turn';
|
|
741
746
|
let lastStopSequence: string | undefined;
|
|
742
747
|
let rawRequest: unknown;
|
|
@@ -807,6 +812,7 @@ export class Membrane {
|
|
|
807
812
|
if (streamResult.usage.cacheReadTokens) {
|
|
808
813
|
totalUsage.cacheReadTokens = (totalUsage.cacheReadTokens ?? 0) + streamResult.usage.cacheReadTokens;
|
|
809
814
|
}
|
|
815
|
+
if (pricing) totalUsage.estimatedCost = calculateCost(totalUsage, pricing);
|
|
810
816
|
onUsage?.(totalUsage);
|
|
811
817
|
|
|
812
818
|
// Parse content blocks from response
|
|
@@ -960,15 +966,23 @@ export class Membrane {
|
|
|
960
966
|
const assistantName = request.assistantParticipant
|
|
961
967
|
?? this.config.assistantParticipant ?? 'Claude';
|
|
962
968
|
|
|
969
|
+
const promptCaching = request.promptCaching ?? true;
|
|
970
|
+
const cacheControl = promptCaching ? { type: 'ephemeral' as const, ...(request.cacheTtl ? { ttl: request.cacheTtl } : {}) } : undefined;
|
|
971
|
+
|
|
963
972
|
for (const msg of messages) {
|
|
964
973
|
const isAssistant = msg.participant === assistantName;
|
|
965
974
|
const role = isAssistant ? 'assistant' : 'user';
|
|
966
|
-
|
|
975
|
+
|
|
967
976
|
// Convert content blocks
|
|
968
977
|
const content: any[] = [];
|
|
978
|
+
const includeNamePrefix = !isAssistant;
|
|
969
979
|
for (const block of msg.content) {
|
|
970
980
|
if (block.type === 'text') {
|
|
971
|
-
|
|
981
|
+
let text = block.text;
|
|
982
|
+
if (includeNamePrefix && msg.participant) {
|
|
983
|
+
text = `${msg.participant}: ${text}`;
|
|
984
|
+
}
|
|
985
|
+
const textBlock: Record<string, unknown> = { type: 'text', text };
|
|
972
986
|
if ((block as any).cache_control) {
|
|
973
987
|
textBlock.cache_control = (block as any).cache_control;
|
|
974
988
|
}
|
|
@@ -1005,19 +1019,42 @@ export class Membrane {
|
|
|
1005
1019
|
}
|
|
1006
1020
|
}
|
|
1007
1021
|
}
|
|
1008
|
-
|
|
1022
|
+
|
|
1023
|
+
// Apply cache_control to last block of messages with cacheBreakpoint
|
|
1024
|
+
if (msg.cacheBreakpoint && cacheControl && content.length > 0) {
|
|
1025
|
+
content[content.length - 1].cache_control = cacheControl;
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1009
1028
|
providerMessages.push({ role, content });
|
|
1010
1029
|
}
|
|
1011
1030
|
|
|
1012
1031
|
// Convert tools to provider format.
|
|
1013
1032
|
// Native tool names must match ^[a-zA-Z0-9_-]{1,128}$ — sanitize colons
|
|
1014
1033
|
// from the module:tool namespace convention. Reversed in parseProviderContent.
|
|
1015
|
-
const tools = request.tools?.map(tool =>
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1034
|
+
const tools = request.tools?.map((tool, idx) => {
|
|
1035
|
+
const t: Record<string, unknown> = {
|
|
1036
|
+
name: sanitizeToolName(tool.name),
|
|
1037
|
+
description: tool.description,
|
|
1038
|
+
input_schema: tool.inputSchema,
|
|
1039
|
+
};
|
|
1040
|
+
// Cache the tool list — mark the last tool with cache_control
|
|
1041
|
+
if (cacheControl && request.tools && idx === request.tools.length - 1) {
|
|
1042
|
+
t.cache_control = cacheControl;
|
|
1043
|
+
}
|
|
1044
|
+
return t;
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// Wrap system prompt with cache_control if prompt caching is enabled
|
|
1048
|
+
let system: unknown = request.system;
|
|
1049
|
+
if (cacheControl && typeof system === 'string' && system.length > 0) {
|
|
1050
|
+
system = [{ type: 'text', text: system, cache_control: cacheControl }];
|
|
1051
|
+
} else if (cacheControl && Array.isArray(system) && system.length > 0) {
|
|
1052
|
+
const blocks = system as Record<string, unknown>[];
|
|
1053
|
+
system = blocks.map((block, idx) =>
|
|
1054
|
+
idx === blocks.length - 1 ? { ...block, cache_control: cacheControl } : block
|
|
1055
|
+
);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1021
1058
|
// Build thinking config for native extended thinking
|
|
1022
1059
|
const thinking = request.config.thinking?.enabled
|
|
1023
1060
|
? {
|
|
@@ -1034,7 +1071,7 @@ export class Membrane {
|
|
|
1034
1071
|
maxTokens: request.config.maxTokens,
|
|
1035
1072
|
temperature,
|
|
1036
1073
|
messages: providerMessages,
|
|
1037
|
-
system
|
|
1074
|
+
system,
|
|
1038
1075
|
tools,
|
|
1039
1076
|
thinking,
|
|
1040
1077
|
extra: request.providerParams,
|
|
@@ -1377,6 +1414,7 @@ export class Membrane {
|
|
|
1377
1414
|
outputTokens: providerResponse.usage.outputTokens,
|
|
1378
1415
|
cacheCreationTokens: providerResponse.usage.cacheCreationTokens,
|
|
1379
1416
|
cacheReadTokens: providerResponse.usage.cacheReadTokens,
|
|
1417
|
+
estimatedCost: this.estimateCost(providerResponse.usage, request.config.model),
|
|
1380
1418
|
},
|
|
1381
1419
|
timing: {
|
|
1382
1420
|
totalDurationMs: durationMs,
|
|
@@ -1458,6 +1496,7 @@ export class Membrane {
|
|
|
1458
1496
|
},
|
|
1459
1497
|
usage: {
|
|
1460
1498
|
...usage,
|
|
1499
|
+
estimatedCost: usage.estimatedCost ?? this.estimateCost(usage, request.config.model),
|
|
1461
1500
|
},
|
|
1462
1501
|
timing: {
|
|
1463
1502
|
totalDurationMs: durationMs,
|
|
@@ -1497,13 +1536,23 @@ export class Membrane {
|
|
|
1497
1536
|
}
|
|
1498
1537
|
}
|
|
1499
1538
|
|
|
1500
|
-
private calculateCacheHitRatio(usage:
|
|
1539
|
+
private calculateCacheHitRatio(usage: Pick<DetailedUsage, 'inputTokens' | 'cacheReadTokens'>): number {
|
|
1501
1540
|
const cacheRead = usage.cacheReadTokens ?? 0;
|
|
1502
1541
|
const total = usage.inputTokens ?? 0;
|
|
1503
1542
|
if (total === 0) return 0;
|
|
1504
1543
|
return cacheRead / total;
|
|
1505
1544
|
}
|
|
1506
1545
|
|
|
1546
|
+
private resolvePricing(model: string): import('./types/provider.js').ModelPricing | undefined {
|
|
1547
|
+
return this.registry?.getPricing(model) ?? getDefaultPricing(model);
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
/** Resolve pricing + calculate cost in one call (for one-shot use outside loops). */
|
|
1551
|
+
private estimateCost(usage: import('./utils/cost.js').CostableUsage, model: string): import('./types/response.js').CostBreakdown | undefined {
|
|
1552
|
+
const pricing = this.resolvePricing(model);
|
|
1553
|
+
return pricing ? calculateCost(usage, pricing) : undefined;
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1507
1556
|
private calculateRetryDelay(attempt: number): number {
|
|
1508
1557
|
const { retryDelayMs, backoffMultiplier, maxRetryDelayMs } = this.retryConfig;
|
|
1509
1558
|
const delay = retryDelayMs * Math.pow(backoffMultiplier, attempt - 1);
|
|
@@ -1639,7 +1688,8 @@ export class Membrane {
|
|
|
1639
1688
|
const formatter = this.formatter;
|
|
1640
1689
|
const parser = formatter.createStreamParser();
|
|
1641
1690
|
let toolDepth = 0;
|
|
1642
|
-
let totalUsage:
|
|
1691
|
+
let totalUsage: DetailedUsage = { inputTokens: 0, outputTokens: 0 };
|
|
1692
|
+
const pricing = this.resolvePricing(request.config.model);
|
|
1643
1693
|
const contentBlocks: ContentBlock[] = [];
|
|
1644
1694
|
let lastStopReason: StopReason = 'end_turn';
|
|
1645
1695
|
let lastStopSequence: string | undefined;
|
|
@@ -1768,9 +1818,16 @@ export class Membrane {
|
|
|
1768
1818
|
lastStopReason = this.mapStopReason(streamResult.stopReason);
|
|
1769
1819
|
lastStopSequence = streamResult.stopSequence ?? undefined;
|
|
1770
1820
|
|
|
1771
|
-
// Accumulate usage
|
|
1821
|
+
// Accumulate usage (including cache metrics)
|
|
1772
1822
|
totalUsage.inputTokens += streamResult.usage.inputTokens;
|
|
1773
1823
|
totalUsage.outputTokens += streamResult.usage.outputTokens;
|
|
1824
|
+
if (streamResult.usage.cacheCreationTokens) {
|
|
1825
|
+
totalUsage.cacheCreationTokens = (totalUsage.cacheCreationTokens ?? 0) + streamResult.usage.cacheCreationTokens;
|
|
1826
|
+
}
|
|
1827
|
+
if (streamResult.usage.cacheReadTokens) {
|
|
1828
|
+
totalUsage.cacheReadTokens = (totalUsage.cacheReadTokens ?? 0) + streamResult.usage.cacheReadTokens;
|
|
1829
|
+
}
|
|
1830
|
+
if (pricing) totalUsage.estimatedCost = calculateCost(totalUsage, pricing);
|
|
1774
1831
|
if (emitUsage) {
|
|
1775
1832
|
stream.emit({ type: 'usage', usage: { ...totalUsage } });
|
|
1776
1833
|
}
|
|
@@ -2075,7 +2132,8 @@ export class Membrane {
|
|
|
2075
2132
|
} = options;
|
|
2076
2133
|
|
|
2077
2134
|
let toolDepth = 0;
|
|
2078
|
-
let totalUsage:
|
|
2135
|
+
let totalUsage: DetailedUsage = { inputTokens: 0, outputTokens: 0 };
|
|
2136
|
+
const pricing = this.resolvePricing(request.config.model);
|
|
2079
2137
|
let lastStopReason: StopReason = 'end_turn';
|
|
2080
2138
|
let lastStopSequence: string | undefined;
|
|
2081
2139
|
let rawRequest: unknown;
|
|
@@ -2141,9 +2199,16 @@ export class Membrane {
|
|
|
2141
2199
|
lastStopReason = this.mapStopReason(streamResult.stopReason);
|
|
2142
2200
|
lastStopSequence = streamResult.stopSequence ?? undefined;
|
|
2143
2201
|
|
|
2144
|
-
// Accumulate usage
|
|
2202
|
+
// Accumulate usage (including cache metrics)
|
|
2145
2203
|
totalUsage.inputTokens += streamResult.usage.inputTokens;
|
|
2146
2204
|
totalUsage.outputTokens += streamResult.usage.outputTokens;
|
|
2205
|
+
if (streamResult.usage.cacheCreationTokens) {
|
|
2206
|
+
totalUsage.cacheCreationTokens = (totalUsage.cacheCreationTokens ?? 0) + streamResult.usage.cacheCreationTokens;
|
|
2207
|
+
}
|
|
2208
|
+
if (streamResult.usage.cacheReadTokens) {
|
|
2209
|
+
totalUsage.cacheReadTokens = (totalUsage.cacheReadTokens ?? 0) + streamResult.usage.cacheReadTokens;
|
|
2210
|
+
}
|
|
2211
|
+
if (pricing) totalUsage.estimatedCost = calculateCost(totalUsage, pricing);
|
|
2147
2212
|
if (emitUsage) {
|
|
2148
2213
|
stream.emit({ type: 'usage', usage: { ...totalUsage } });
|
|
2149
2214
|
}
|
|
@@ -2252,9 +2317,9 @@ export class Membrane {
|
|
|
2252
2317
|
},
|
|
2253
2318
|
cache: {
|
|
2254
2319
|
markersInRequest: 0,
|
|
2255
|
-
tokensCreated: 0,
|
|
2256
|
-
tokensRead: 0,
|
|
2257
|
-
hitRatio:
|
|
2320
|
+
tokensCreated: totalUsage.cacheCreationTokens ?? 0,
|
|
2321
|
+
tokensRead: totalUsage.cacheReadTokens ?? 0,
|
|
2322
|
+
hitRatio: this.calculateCacheHitRatio(totalUsage),
|
|
2258
2323
|
},
|
|
2259
2324
|
},
|
|
2260
2325
|
raw: {
|