@f3d1/llmkit-sdk 0.0.1

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.
@@ -0,0 +1,30 @@
1
+ import type { CostBreakdown, LLMKitConfig, LLMRequest, LLMResponse, TokenUsage } from '@f3d1/llmkit-shared';
2
+ type ChatRequest = Omit<LLMRequest, 'provider'> & {
3
+ provider?: string;
4
+ };
5
+ export declare class LLMKit {
6
+ private config;
7
+ private sessionId?;
8
+ constructor(config: LLMKitConfig);
9
+ session(id?: string): LLMKit;
10
+ chat(req: ChatRequest): Promise<LLMResponse>;
11
+ chatStream(req: ChatRequest): Promise<ChatStream>;
12
+ private fetch;
13
+ }
14
+ export declare class ChatStream {
15
+ private response;
16
+ private _usage?;
17
+ private _cost?;
18
+ private _model?;
19
+ private _provider?;
20
+ private _id?;
21
+ constructor(response: Response);
22
+ get usage(): TokenUsage | undefined;
23
+ get cost(): CostBreakdown | undefined;
24
+ get model(): string | undefined;
25
+ get provider(): string | undefined;
26
+ get id(): string | undefined;
27
+ [Symbol.asyncIterator](): AsyncGenerator<string>;
28
+ }
29
+ export {};
30
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAI5G,KAAK,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExE,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,SAAS,CAAC,CAAS;gBAEf,MAAM,EAAE,YAAY;IAQhC,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAQtB,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAY5C,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAYvD,OAAO,CAAC,KAAK;CAoBd;AAGD,qBAAa,UAAU;IAOT,OAAO,CAAC,QAAQ;IAN5B,OAAO,CAAC,MAAM,CAAC,CAAa;IAC5B,OAAO,CAAC,KAAK,CAAC,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,GAAG,CAAC,CAAS;gBAED,QAAQ,EAAE,QAAQ;IAEtC,IAAI,KAAK,2BAA0B;IACnC,IAAI,IAAI,8BAAyB;IACjC,IAAI,KAAK,uBAA0B;IACnC,IAAI,QAAQ,uBAA6B;IACzC,IAAI,EAAE,uBAAuB;IAEtB,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC;CAsDxD"}
package/dist/client.js ADDED
@@ -0,0 +1,124 @@
1
+ const DEFAULT_BASE_URL = 'https://api.llmkit.dev';
2
+ export class LLMKit {
3
+ config;
4
+ sessionId;
5
+ constructor(config) {
6
+ this.config = {
7
+ apiKey: config.apiKey,
8
+ baseUrl: config.baseUrl || DEFAULT_BASE_URL,
9
+ };
10
+ this.sessionId = config.sessionId;
11
+ }
12
+ session(id) {
13
+ const clone = new LLMKit({
14
+ ...this.config,
15
+ sessionId: id || crypto.randomUUID(),
16
+ });
17
+ return clone;
18
+ }
19
+ async chat(req) {
20
+ const res = await this.fetch(req);
21
+ if (!res.ok) {
22
+ const body = await res.json().catch(() => null);
23
+ const msg = body?.error?.message || body?.message || res.statusText;
24
+ throw new Error(msg);
25
+ }
26
+ return res.json();
27
+ }
28
+ async chatStream(req) {
29
+ const res = await this.fetch({ ...req, stream: true });
30
+ if (!res.ok) {
31
+ const body = await res.json().catch(() => null);
32
+ const msg = body?.error?.message || body?.message || res.statusText;
33
+ throw new Error(msg);
34
+ }
35
+ return new ChatStream(res);
36
+ }
37
+ fetch(req) {
38
+ const headers = {
39
+ 'Authorization': `Bearer ${this.config.apiKey}`,
40
+ 'Content-Type': 'application/json',
41
+ 'x-llmkit-format': 'llmkit',
42
+ };
43
+ if (this.sessionId) {
44
+ headers['x-llmkit-session-id'] = this.sessionId;
45
+ }
46
+ if (req.provider) {
47
+ headers['x-llmkit-provider'] = req.provider;
48
+ }
49
+ return fetch(`${this.config.baseUrl}/v1/chat/completions`, {
50
+ method: 'POST',
51
+ headers,
52
+ body: JSON.stringify(req),
53
+ });
54
+ }
55
+ }
56
+ // async iterable that yields text chunks and exposes metadata after completion
57
+ export class ChatStream {
58
+ response;
59
+ _usage;
60
+ _cost;
61
+ _model;
62
+ _provider;
63
+ _id;
64
+ constructor(response) {
65
+ this.response = response;
66
+ }
67
+ get usage() { return this._usage; }
68
+ get cost() { return this._cost; }
69
+ get model() { return this._model; }
70
+ get provider() { return this._provider; }
71
+ get id() { return this._id; }
72
+ async *[Symbol.asyncIterator]() {
73
+ if (!this.response.body)
74
+ throw new Error('No response body');
75
+ const reader = this.response.body.getReader();
76
+ const decoder = new TextDecoder();
77
+ let buffer = '';
78
+ let currentEvent = '';
79
+ try {
80
+ while (true) {
81
+ const { done, value } = await reader.read();
82
+ if (done)
83
+ break;
84
+ buffer += decoder.decode(value, { stream: true });
85
+ const lines = buffer.split('\n');
86
+ buffer = lines.pop();
87
+ for (const line of lines) {
88
+ if (line.startsWith('event: ')) {
89
+ currentEvent = line.slice(7).trim();
90
+ continue;
91
+ }
92
+ if (!line.startsWith('data: ')) {
93
+ if (line === '')
94
+ currentEvent = '';
95
+ continue;
96
+ }
97
+ const raw = line.slice(6).trim();
98
+ if (!raw)
99
+ continue;
100
+ try {
101
+ const data = JSON.parse(raw);
102
+ if (currentEvent === 'delta' && data.text !== undefined) {
103
+ yield data.text;
104
+ }
105
+ if (currentEvent === 'done') {
106
+ this._usage = data.usage;
107
+ this._cost = data.cost;
108
+ this._model = data.model;
109
+ this._provider = data.provider;
110
+ this._id = data.id;
111
+ }
112
+ }
113
+ catch {
114
+ // partial JSON, will be completed in next chunk
115
+ }
116
+ }
117
+ }
118
+ }
119
+ finally {
120
+ reader.releaseLock();
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type { CostBreakdown, LLMKitConfig, LLMRequest, LLMResponse, ProviderName, SessionSummary, TokenUsage, } from '@f3d1/llmkit-shared';
2
+ export { ChatStream, LLMKit } from './client';
3
+ export type { CostEntry } from './tracker';
4
+ export { CostTracker } from './tracker';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,aAAa,EACb,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACd,UAAU,GACX,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC9C,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { ChatStream, LLMKit } from './client';
2
+ export { CostTracker } from './tracker';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { type ProviderName } from '@f3d1/llmkit-shared';
2
+ interface UsageInput {
3
+ inputTokens: number;
4
+ outputTokens: number;
5
+ cacheReadTokens?: number;
6
+ cacheWriteTokens?: number;
7
+ sessionId?: string;
8
+ }
9
+ export interface CostEntry {
10
+ provider: ProviderName;
11
+ model: string;
12
+ inputTokens: number;
13
+ outputTokens: number;
14
+ cacheReadTokens: number;
15
+ cacheWriteTokens: number;
16
+ costCents: number;
17
+ sessionId?: string;
18
+ timestamp: Date;
19
+ }
20
+ interface OpenAILikeUsage {
21
+ prompt_tokens: number;
22
+ completion_tokens: number;
23
+ }
24
+ interface AnthropicLikeUsage {
25
+ input_tokens: number;
26
+ output_tokens: number;
27
+ cache_read_input_tokens?: number;
28
+ cache_creation_input_tokens?: number;
29
+ }
30
+ type CostListener = (entry: CostEntry) => void;
31
+ interface TrackerConfig {
32
+ log?: boolean;
33
+ onTrack?: CostListener;
34
+ }
35
+ interface Bucket {
36
+ cents: number;
37
+ requests: number;
38
+ inputTokens: number;
39
+ outputTokens: number;
40
+ }
41
+ export declare class CostTracker {
42
+ private entries;
43
+ private listeners;
44
+ private shouldLog;
45
+ constructor(config?: TrackerConfig);
46
+ track(provider: ProviderName, model: string, usage: UsageInput): CostEntry;
47
+ trackResponse(provider: ProviderName, response: {
48
+ model: string;
49
+ usage: OpenAILikeUsage | AnthropicLikeUsage;
50
+ }): CostEntry;
51
+ on(listener: CostListener): () => void;
52
+ get totalCents(): number;
53
+ get totalDollars(): string;
54
+ get requestCount(): number;
55
+ byProvider(): Record<string, Bucket>;
56
+ byModel(): Record<string, Bucket>;
57
+ bySession(): Record<string, Bucket>;
58
+ summary(): string;
59
+ reset(): void;
60
+ private emit;
61
+ private groupBy;
62
+ }
63
+ export {};
64
+ //# sourceMappingURL=tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEvE,UAAU,UAAU;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,YAAY,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;CACjB;AAGD,UAAU,eAAe;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,UAAU,kBAAkB;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,KAAK,YAAY,GAAG,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;AAE/C,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAED,UAAU,MAAM;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,SAAS,CAAsB;IACvC,OAAO,CAAC,SAAS,CAAU;gBAEf,MAAM,GAAE,aAAkB;IAKtC,KAAK,CAAC,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,SAAS;IAyB1E,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,eAAe,GAAG,kBAAkB,CAAA;KAAE,GAAG,SAAS;IAkB1H,EAAE,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,IAAI;IAQtC,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIpC,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIjC,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAInC,OAAO,IAAI,MAAM;IA0BjB,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,IAAI;IAWZ,OAAO,CAAC,OAAO;CAahB"}
@@ -0,0 +1,121 @@
1
+ import { calculateCost } from '@f3d1/llmkit-shared';
2
+ export class CostTracker {
3
+ entries = [];
4
+ listeners = [];
5
+ shouldLog;
6
+ constructor(config = {}) {
7
+ this.shouldLog = config.log ?? false;
8
+ if (config.onTrack)
9
+ this.listeners.push(config.onTrack);
10
+ }
11
+ track(provider, model, usage) {
12
+ const costDollars = calculateCost(provider, model, usage.inputTokens, usage.outputTokens, usage.cacheReadTokens ?? 0, usage.cacheWriteTokens ?? 0);
13
+ const entry = {
14
+ provider,
15
+ model,
16
+ inputTokens: usage.inputTokens,
17
+ outputTokens: usage.outputTokens,
18
+ cacheReadTokens: usage.cacheReadTokens ?? 0,
19
+ cacheWriteTokens: usage.cacheWriteTokens ?? 0,
20
+ costCents: +(costDollars * 100).toFixed(4),
21
+ sessionId: usage.sessionId,
22
+ timestamp: new Date(),
23
+ };
24
+ this.entries.push(entry);
25
+ this.emit(entry);
26
+ return entry;
27
+ }
28
+ // accepts a raw response from OpenAI SDK (prompt_tokens) or Anthropic SDK (input_tokens)
29
+ trackResponse(provider, response) {
30
+ const { model, usage } = response;
31
+ if ('prompt_tokens' in usage) {
32
+ return this.track(provider, model, {
33
+ inputTokens: usage.prompt_tokens,
34
+ outputTokens: usage.completion_tokens,
35
+ });
36
+ }
37
+ return this.track(provider, model, {
38
+ inputTokens: usage.input_tokens,
39
+ outputTokens: usage.output_tokens,
40
+ cacheReadTokens: usage.cache_read_input_tokens,
41
+ cacheWriteTokens: usage.cache_creation_input_tokens,
42
+ });
43
+ }
44
+ on(listener) {
45
+ this.listeners.push(listener);
46
+ return () => {
47
+ const idx = this.listeners.indexOf(listener);
48
+ if (idx >= 0)
49
+ this.listeners.splice(idx, 1);
50
+ };
51
+ }
52
+ get totalCents() {
53
+ return this.entries.reduce((sum, e) => sum + e.costCents, 0);
54
+ }
55
+ get totalDollars() {
56
+ return (this.totalCents / 100).toFixed(4);
57
+ }
58
+ get requestCount() {
59
+ return this.entries.length;
60
+ }
61
+ byProvider() {
62
+ return this.groupBy((e) => e.provider);
63
+ }
64
+ byModel() {
65
+ return this.groupBy((e) => e.model);
66
+ }
67
+ bySession() {
68
+ return this.groupBy((e) => e.sessionId || 'default');
69
+ }
70
+ summary() {
71
+ const lines = [
72
+ `LLMKit Cost Summary`,
73
+ `---`,
74
+ `Total: $${this.totalDollars} (${this.requestCount} requests)`,
75
+ '',
76
+ ];
77
+ const providers = this.byProvider();
78
+ if (Object.keys(providers).length > 1) {
79
+ lines.push('By provider:');
80
+ for (const [name, b] of Object.entries(providers)) {
81
+ lines.push(` ${name}: $${fmtCents(b.cents)} (${b.requests} reqs)`);
82
+ }
83
+ lines.push('');
84
+ }
85
+ const models = this.byModel();
86
+ lines.push('By model:');
87
+ for (const [name, b] of Object.entries(models)) {
88
+ lines.push(` ${name}: $${fmtCents(b.cents)} (${b.requests} reqs)`);
89
+ }
90
+ return lines.join('\n');
91
+ }
92
+ reset() {
93
+ this.entries = [];
94
+ }
95
+ emit(entry) {
96
+ if (this.shouldLog) {
97
+ const cache = entry.cacheReadTokens > 0 ? `, ${entry.cacheReadTokens} cached` : '';
98
+ console.log(`[llmkit] ${entry.provider}/${entry.model}: $${fmtCents(entry.costCents)} ` +
99
+ `(${entry.inputTokens} in, ${entry.outputTokens} out${cache})`);
100
+ }
101
+ for (const fn of this.listeners)
102
+ fn(entry);
103
+ }
104
+ groupBy(keyFn) {
105
+ const out = {};
106
+ for (const e of this.entries) {
107
+ const key = keyFn(e);
108
+ const b = out[key] || { cents: 0, requests: 0, inputTokens: 0, outputTokens: 0 };
109
+ b.cents += e.costCents;
110
+ b.requests++;
111
+ b.inputTokens += e.inputTokens;
112
+ b.outputTokens += e.outputTokens;
113
+ out[key] = b;
114
+ }
115
+ return out;
116
+ }
117
+ }
118
+ function fmtCents(cents) {
119
+ return (cents / 100).toFixed(4);
120
+ }
121
+ //# sourceMappingURL=tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracker.js","sourceRoot":"","sources":["../src/tracker.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@f3d1/llmkit-sdk",
3
+ "version": "0.0.1",
4
+ "license": "MIT",
5
+ "description": "TypeScript SDK for LLMKit - cost tracking, provider routing, budget enforcement",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": ["dist"],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "typecheck": "tsc --noEmit",
20
+ "clean": "rm -rf dist"
21
+ },
22
+ "dependencies": {
23
+ "@f3d1/llmkit-shared": "workspace:*"
24
+ }
25
+ }