universal-llm-client 3.0.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/LICENSE +21 -0
- package/README.md +414 -0
- package/dist/ai-model.d.ts +53 -0
- package/dist/ai-model.d.ts.map +1 -0
- package/dist/ai-model.js +159 -0
- package/dist/ai-model.js.map +1 -0
- package/dist/auditor.d.ts +78 -0
- package/dist/auditor.d.ts.map +1 -0
- package/dist/auditor.js +104 -0
- package/dist/auditor.js.map +1 -0
- package/dist/client.d.ts +75 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +240 -0
- package/dist/client.js.map +1 -0
- package/dist/http.d.ts +47 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +186 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +324 -0
- package/dist/interfaces.d.ts.map +1 -0
- package/dist/interfaces.js +63 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/mcp.d.ts +85 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +255 -0
- package/dist/mcp.js.map +1 -0
- package/dist/providers/google.d.ts +33 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +426 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +7 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/ollama.d.ts +26 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +304 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai.d.ts +20 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +251 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/router.d.ts +87 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +260 -0
- package/dist/router.js.map +1 -0
- package/dist/stream-decoder.d.ts +112 -0
- package/dist/stream-decoder.d.ts.map +1 -0
- package/dist/stream-decoder.js +238 -0
- package/dist/stream-decoder.js.map +1 -0
- package/dist/tools.d.ts +78 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +207 -0
- package/dist/tools.js.map +1 -0
- package/package.json +91 -0
package/dist/http.js
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal LLM Client v3 — HTTP Utilities
|
|
3
|
+
*
|
|
4
|
+
* Zero-dependency HTTP layer using native fetch.
|
|
5
|
+
* Works on Node 22+, Bun, Deno, and browsers.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// HTTP Request
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Make an HTTP request with timeout and error handling.
|
|
12
|
+
* Uses native fetch (available in all target runtimes).
|
|
13
|
+
*/
|
|
14
|
+
export async function httpRequest(url, options = {}) {
|
|
15
|
+
const { method = 'GET', headers = {}, body, timeout = 30000, signal } = options;
|
|
16
|
+
const controller = new AbortController();
|
|
17
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
18
|
+
// Combine external signal with timeout
|
|
19
|
+
const combinedSignal = signal
|
|
20
|
+
? AbortSignal.any([signal, controller.signal])
|
|
21
|
+
: controller.signal;
|
|
22
|
+
try {
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
method,
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
...headers,
|
|
28
|
+
},
|
|
29
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
30
|
+
signal: combinedSignal,
|
|
31
|
+
});
|
|
32
|
+
clearTimeout(timeoutId);
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
const errorText = await response.text().catch(() => 'Unknown error');
|
|
35
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
36
|
+
}
|
|
37
|
+
const data = (await response.json());
|
|
38
|
+
return {
|
|
39
|
+
ok: response.ok,
|
|
40
|
+
status: response.status,
|
|
41
|
+
data,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
clearTimeout(timeoutId);
|
|
46
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
47
|
+
throw new Error(`Request timeout after ${timeout}ms: ${url}`);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Streaming HTTP
|
|
54
|
+
// ============================================================================
|
|
55
|
+
/**
|
|
56
|
+
* Make a streaming HTTP request.
|
|
57
|
+
* Yields raw string chunks as they arrive.
|
|
58
|
+
*/
|
|
59
|
+
export async function* httpStream(url, options = {}) {
|
|
60
|
+
const { method = 'POST', headers = {}, body, timeout = 120000, signal } = options;
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
63
|
+
const combinedSignal = signal
|
|
64
|
+
? AbortSignal.any([signal, controller.signal])
|
|
65
|
+
: controller.signal;
|
|
66
|
+
try {
|
|
67
|
+
const response = await fetch(url, {
|
|
68
|
+
method,
|
|
69
|
+
headers: {
|
|
70
|
+
'Content-Type': 'application/json',
|
|
71
|
+
...headers,
|
|
72
|
+
},
|
|
73
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
74
|
+
signal: combinedSignal,
|
|
75
|
+
});
|
|
76
|
+
clearTimeout(timeoutId);
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
const errorText = await response.text().catch(() => 'Unknown error');
|
|
79
|
+
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
80
|
+
}
|
|
81
|
+
if (!response.body) {
|
|
82
|
+
throw new Error('No response body for streaming');
|
|
83
|
+
}
|
|
84
|
+
const reader = response.body.getReader();
|
|
85
|
+
const decoder = new TextDecoder();
|
|
86
|
+
try {
|
|
87
|
+
while (true) {
|
|
88
|
+
const { done, value } = await reader.read();
|
|
89
|
+
if (done)
|
|
90
|
+
break;
|
|
91
|
+
yield decoder.decode(value, { stream: true });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
reader.releaseLock();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
clearTimeout(timeoutId);
|
|
100
|
+
if (error instanceof Error && error.name === 'AbortError') {
|
|
101
|
+
throw new Error(`Stream timeout after ${timeout}ms: ${url}`);
|
|
102
|
+
}
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// Protocol Parsers
|
|
108
|
+
// ============================================================================
|
|
109
|
+
/**
|
|
110
|
+
* Parse NDJSON (newline-delimited JSON) stream.
|
|
111
|
+
* Used by Ollama's streaming API.
|
|
112
|
+
*/
|
|
113
|
+
export async function* parseNDJSON(stream) {
|
|
114
|
+
let buffer = '';
|
|
115
|
+
for await (const chunk of stream) {
|
|
116
|
+
buffer += chunk;
|
|
117
|
+
const lines = buffer.split('\n');
|
|
118
|
+
buffer = lines.pop() ?? '';
|
|
119
|
+
for (const line of lines) {
|
|
120
|
+
const trimmed = line.trim();
|
|
121
|
+
if (!trimmed)
|
|
122
|
+
continue;
|
|
123
|
+
try {
|
|
124
|
+
yield JSON.parse(trimmed);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// Skip invalid JSON lines
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Handle remaining buffer
|
|
132
|
+
if (buffer.trim()) {
|
|
133
|
+
try {
|
|
134
|
+
yield JSON.parse(buffer);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// Skip invalid JSON
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Parse Server-Sent Events stream.
|
|
143
|
+
* Used by OpenAI-compatible APIs and LlamaCpp/vLLM.
|
|
144
|
+
*/
|
|
145
|
+
export async function* parseSSE(stream) {
|
|
146
|
+
let buffer = '';
|
|
147
|
+
for await (const chunk of stream) {
|
|
148
|
+
buffer += chunk;
|
|
149
|
+
// Split by double newlines (SSE event delimiter)
|
|
150
|
+
const events = buffer.split('\n\n');
|
|
151
|
+
buffer = events.pop() ?? '';
|
|
152
|
+
for (const event of events) {
|
|
153
|
+
const lines = event.split('\n');
|
|
154
|
+
let eventType;
|
|
155
|
+
const dataLines = [];
|
|
156
|
+
for (const line of lines) {
|
|
157
|
+
if (line.startsWith('event:')) {
|
|
158
|
+
eventType = line.slice(6).trim();
|
|
159
|
+
}
|
|
160
|
+
else if (line.startsWith('data:')) {
|
|
161
|
+
dataLines.push(line.slice(5).trim());
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const data = dataLines.join('\n');
|
|
165
|
+
if (data && data !== '[DONE]') {
|
|
166
|
+
yield { event: eventType, data };
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// ============================================================================
|
|
172
|
+
// Header Utilities
|
|
173
|
+
// ============================================================================
|
|
174
|
+
/**
|
|
175
|
+
* Build standard headers for LLM API requests.
|
|
176
|
+
*/
|
|
177
|
+
export function buildHeaders(options) {
|
|
178
|
+
const headers = {
|
|
179
|
+
'Content-Type': 'application/json',
|
|
180
|
+
};
|
|
181
|
+
if (options.apiKey) {
|
|
182
|
+
headers['Authorization'] = `Bearer ${options.apiKey}`;
|
|
183
|
+
}
|
|
184
|
+
return headers;
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal LLM Client v3
|
|
3
|
+
*
|
|
4
|
+
* A universal LLM client with transparent provider failover,
|
|
5
|
+
* streaming tool execution, pluggable reasoning, and native observability.
|
|
6
|
+
*
|
|
7
|
+
* @module @akaito/universal-llm-client
|
|
8
|
+
*/
|
|
9
|
+
export { AIModel } from './ai-model.js';
|
|
10
|
+
export { AIModelApiType, AIModelType, type AIModelConfig, type ProviderConfig, type LLMClientOptions, type LLMChatMessage, type LLMMessageContent, type LLMContentPart, type LLMTextContent, type LLMImageContent, type LLMChatResponse, type TokenUsageInfo, type LLMToolCall, type LLMToolDefinition, type LLMFunction, type ToolHandler, type ToolExecutionResult, type ToolRegistry, type ToolRegistryEntry, type ChatOptions, type ModelMetadata, textContent, imageContent, multimodalMessage, extractTextContent, hasImages, } from './interfaces.js';
|
|
11
|
+
export { type Auditor, type AuditEvent, type AuditEventType, NoopAuditor, ConsoleAuditor, BufferedAuditor, } from './auditor.js';
|
|
12
|
+
export { type StreamDecoder, type DecodedEvent, type DecoderCallback, type DecoderType, type DecoderOptions, createDecoder, PassthroughDecoder, StandardChatDecoder, InterleavedReasoningDecoder, } from './stream-decoder.js';
|
|
13
|
+
export { ToolBuilder, ToolExecutor, createTimeTool, createRandomNumberTool, } from './tools.js';
|
|
14
|
+
export { httpRequest, httpStream, parseNDJSON, parseSSE, buildHeaders, type HttpRequestOptions, type HttpResponse, } from './http.js';
|
|
15
|
+
export { MCPToolBridge, type MCPBridgeConfig, type MCPServerConfig, type MCPTool, } from './mcp.js';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAMxC,OAAO,EAEH,cAAc,EACd,WAAW,EAEX,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAErB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,eAAe,EAEpB,KAAK,eAAe,EACpB,KAAK,cAAc,EAEnB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,mBAAmB,EACxB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EAEtB,KAAK,WAAW,EAEhB,KAAK,aAAa,EAElB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,GACZ,MAAM,iBAAiB,CAAC;AAMzB,OAAO,EACH,KAAK,OAAO,EACZ,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,WAAW,EACX,cAAc,EACd,eAAe,GAClB,MAAM,cAAc,CAAC;AAMtB,OAAO,EACH,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,GAC9B,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EACH,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACzB,MAAM,YAAY,CAAC;AAMpB,OAAO,EACH,WAAW,EACX,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,YAAY,GACpB,MAAM,WAAW,CAAC;AAMnB,OAAO,EACH,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,OAAO,GACf,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal LLM Client v3
|
|
3
|
+
*
|
|
4
|
+
* A universal LLM client with transparent provider failover,
|
|
5
|
+
* streaming tool execution, pluggable reasoning, and native observability.
|
|
6
|
+
*
|
|
7
|
+
* @module @akaito/universal-llm-client
|
|
8
|
+
*/
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Public API — The Universal Client
|
|
11
|
+
// ============================================================================
|
|
12
|
+
export { AIModel } from './ai-model.js';
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Types & Interfaces
|
|
15
|
+
// ============================================================================
|
|
16
|
+
export {
|
|
17
|
+
// Enums
|
|
18
|
+
AIModelApiType, AIModelType,
|
|
19
|
+
// Helpers
|
|
20
|
+
textContent, imageContent, multimodalMessage, extractTextContent, hasImages, } from './interfaces.js';
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Observability
|
|
23
|
+
// ============================================================================
|
|
24
|
+
export { NoopAuditor, ConsoleAuditor, BufferedAuditor, } from './auditor.js';
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Stream Decoding
|
|
27
|
+
// ============================================================================
|
|
28
|
+
export { createDecoder, PassthroughDecoder, StandardChatDecoder, InterleavedReasoningDecoder, } from './stream-decoder.js';
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Tool Utilities
|
|
31
|
+
// ============================================================================
|
|
32
|
+
export { ToolBuilder, ToolExecutor, createTimeTool, createRandomNumberTool, } from './tools.js';
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// HTTP Utilities (for advanced use cases)
|
|
35
|
+
// ============================================================================
|
|
36
|
+
export { httpRequest, httpStream, parseNDJSON, parseSSE, buildHeaders, } from './http.js';
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// MCP Integration
|
|
39
|
+
// ============================================================================
|
|
40
|
+
export { MCPToolBridge, } from './mcp.js';
|
|
41
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,oCAAoC;AACpC,+EAA+E;AAE/E,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E,OAAO;AACH,QAAQ;AACR,cAAc,EACd,WAAW;AA0BX,UAAU;AACV,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,GACZ,MAAM,iBAAiB,CAAC;AAEzB,+EAA+E;AAC/E,gBAAgB;AAChB,+EAA+E;AAE/E,OAAO,EAIH,WAAW,EACX,cAAc,EACd,eAAe,GAClB,MAAM,cAAc,CAAC;AAEtB,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,OAAO,EAMH,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,GAC9B,MAAM,qBAAqB,CAAC;AAE7B,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E,OAAO,EACH,WAAW,EACX,YAAY,EACZ,cAAc,EACd,sBAAsB,GACzB,MAAM,YAAY,CAAC;AAEpB,+EAA+E;AAC/E,0CAA0C;AAC1C,+EAA+E;AAE/E,OAAO,EACH,WAAW,EACX,UAAU,EACV,WAAW,EACX,QAAQ,EACR,YAAY,GAGf,MAAM,WAAW,CAAC;AAEnB,+EAA+E;AAC/E,kBAAkB;AAClB,+EAA+E;AAE/E,OAAO,EACH,aAAa,GAIhB,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal LLM Client v3 — Core Interfaces
|
|
3
|
+
*
|
|
4
|
+
* All types, enums, and helper functions used throughout the library.
|
|
5
|
+
* Zero dependencies — pure TypeScript types.
|
|
6
|
+
*/
|
|
7
|
+
export declare enum AIModelType {
|
|
8
|
+
Chat = "chat",
|
|
9
|
+
Embedding = "embedding"
|
|
10
|
+
}
|
|
11
|
+
export declare enum AIModelApiType {
|
|
12
|
+
Ollama = "ollama",
|
|
13
|
+
OpenAI = "openai",
|
|
14
|
+
Google = "google",
|
|
15
|
+
Vertex = "vertex",
|
|
16
|
+
LlamaCpp = "llamacpp"
|
|
17
|
+
}
|
|
18
|
+
export interface ModelMetadata {
|
|
19
|
+
/** Model name as reported by provider */
|
|
20
|
+
model?: string;
|
|
21
|
+
/** Context window size in tokens */
|
|
22
|
+
contextLength: number;
|
|
23
|
+
/** Model architecture (e.g., "llama", "mistral3") */
|
|
24
|
+
architecture?: string;
|
|
25
|
+
/** Parameter count */
|
|
26
|
+
parameterCount?: number;
|
|
27
|
+
/** Model capabilities reported by provider (e.g., "tools", "vision", "thinking") */
|
|
28
|
+
capabilities?: string[];
|
|
29
|
+
}
|
|
30
|
+
export interface ProviderConfig {
|
|
31
|
+
/** Provider type */
|
|
32
|
+
type: AIModelApiType | 'ollama' | 'openai' | 'google' | 'vertex' | 'llamacpp';
|
|
33
|
+
/** Provider endpoint URL (has sensible defaults per type) */
|
|
34
|
+
url?: string;
|
|
35
|
+
/** API key or Bearer token */
|
|
36
|
+
apiKey?: string;
|
|
37
|
+
/** Override model name for this specific provider */
|
|
38
|
+
model?: string;
|
|
39
|
+
/** Explicit priority (default: array order, lower = higher priority) */
|
|
40
|
+
priority?: number;
|
|
41
|
+
/** Vertex AI region (e.g., "us-central1") */
|
|
42
|
+
region?: string;
|
|
43
|
+
/** Google API version (default: "v1beta") */
|
|
44
|
+
apiVersion?: 'v1' | 'v1beta';
|
|
45
|
+
}
|
|
46
|
+
export interface AIModelConfig {
|
|
47
|
+
/** Model name (used across all providers unless overridden) */
|
|
48
|
+
model: string;
|
|
49
|
+
/** Ordered list of providers (first = highest priority) */
|
|
50
|
+
providers: ProviderConfig[];
|
|
51
|
+
/** Default parameters for all requests (temperature, top_p, etc.) */
|
|
52
|
+
defaultParameters?: Record<string, unknown>;
|
|
53
|
+
/** Enable thinking/reasoning mode */
|
|
54
|
+
thinking?: boolean;
|
|
55
|
+
/** Request timeout in ms (default: 30000) */
|
|
56
|
+
timeout?: number;
|
|
57
|
+
/** Retries per provider before failover (default: 2) */
|
|
58
|
+
retries?: number;
|
|
59
|
+
/** Observability hooks */
|
|
60
|
+
auditor?: import('./auditor.js').Auditor;
|
|
61
|
+
/** Enable debug logging */
|
|
62
|
+
debug?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface LLMClientOptions {
|
|
65
|
+
/** Model name */
|
|
66
|
+
model: string;
|
|
67
|
+
/** Base URL for the API */
|
|
68
|
+
url: string;
|
|
69
|
+
/** API type for protocol variations */
|
|
70
|
+
apiType: AIModelApiType;
|
|
71
|
+
/** Model type (chat or embedding) */
|
|
72
|
+
modelType?: AIModelType;
|
|
73
|
+
/** Default parameters for requests */
|
|
74
|
+
defaultParameters?: Record<string, unknown>;
|
|
75
|
+
/** Enable thinking/reasoning mode */
|
|
76
|
+
thinking?: boolean;
|
|
77
|
+
/** Request timeout in ms */
|
|
78
|
+
timeout?: number;
|
|
79
|
+
/** Number of retries for failed requests */
|
|
80
|
+
retries?: number;
|
|
81
|
+
/** API key for authenticated endpoints */
|
|
82
|
+
apiKey?: string;
|
|
83
|
+
/** Enable debug logging */
|
|
84
|
+
debug?: boolean;
|
|
85
|
+
/** Vertex AI region */
|
|
86
|
+
region?: string;
|
|
87
|
+
/** Google API version */
|
|
88
|
+
apiVersion?: 'v1' | 'v1beta';
|
|
89
|
+
}
|
|
90
|
+
export interface LLMTextContent {
|
|
91
|
+
type: 'text';
|
|
92
|
+
text: string;
|
|
93
|
+
}
|
|
94
|
+
export interface LLMImageContent {
|
|
95
|
+
type: 'image_url';
|
|
96
|
+
image_url: {
|
|
97
|
+
url: string;
|
|
98
|
+
detail?: 'auto' | 'low' | 'high';
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export type LLMContentPart = LLMTextContent | LLMImageContent;
|
|
102
|
+
export type LLMMessageContent = string | LLMContentPart[];
|
|
103
|
+
export interface LLMChatMessage {
|
|
104
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
105
|
+
content: LLMMessageContent;
|
|
106
|
+
tool_call_id?: string;
|
|
107
|
+
tool_calls?: LLMToolCall[];
|
|
108
|
+
}
|
|
109
|
+
export interface LLMToolCall {
|
|
110
|
+
id: string;
|
|
111
|
+
type: 'function';
|
|
112
|
+
function: {
|
|
113
|
+
name: string;
|
|
114
|
+
arguments: string;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Gemini 3.x thought signature — encrypted reasoning context.
|
|
118
|
+
* Must be echoed back exactly when sending conversation history
|
|
119
|
+
* during multi-turn function calling. Mandatory for Gemini 3,
|
|
120
|
+
* optional for Gemini 2.5, ignored by other providers.
|
|
121
|
+
*/
|
|
122
|
+
thoughtSignature?: string;
|
|
123
|
+
}
|
|
124
|
+
export interface LLMFunction {
|
|
125
|
+
name: string;
|
|
126
|
+
description: string;
|
|
127
|
+
parameters: {
|
|
128
|
+
type: 'object';
|
|
129
|
+
properties?: Record<string, unknown>;
|
|
130
|
+
required?: string[];
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export interface LLMToolDefinition {
|
|
134
|
+
type: 'function';
|
|
135
|
+
function: LLMFunction;
|
|
136
|
+
}
|
|
137
|
+
export interface ToolExecutionResult {
|
|
138
|
+
tool_call_id: string;
|
|
139
|
+
output: unknown;
|
|
140
|
+
error?: string;
|
|
141
|
+
duration?: number;
|
|
142
|
+
}
|
|
143
|
+
export type ToolHandler = (args: unknown) => Promise<unknown> | unknown;
|
|
144
|
+
export interface ToolRegistryEntry {
|
|
145
|
+
definition: LLMFunction;
|
|
146
|
+
handler: ToolHandler;
|
|
147
|
+
}
|
|
148
|
+
export interface ToolRegistry {
|
|
149
|
+
[toolName: string]: ToolRegistryEntry;
|
|
150
|
+
}
|
|
151
|
+
export interface ChatOptions {
|
|
152
|
+
/** Override temperature */
|
|
153
|
+
temperature?: number;
|
|
154
|
+
/** Max tokens to generate */
|
|
155
|
+
maxTokens?: number;
|
|
156
|
+
/** Tool definitions (auto-populated from registry if not set) */
|
|
157
|
+
tools?: LLMToolDefinition[];
|
|
158
|
+
/** Tool choice mode */
|
|
159
|
+
toolChoice?: 'none' | 'auto' | 'required';
|
|
160
|
+
/** Additional provider-specific parameters */
|
|
161
|
+
parameters?: Record<string, unknown>;
|
|
162
|
+
/** Enable/disable tool execution for chatWithTools */
|
|
163
|
+
executeTools?: boolean;
|
|
164
|
+
/** Maximum tool execution rounds (default: 10) */
|
|
165
|
+
maxIterations?: number;
|
|
166
|
+
/** Stream decoder type */
|
|
167
|
+
decoder?: import('./stream-decoder.js').DecoderType;
|
|
168
|
+
}
|
|
169
|
+
export interface TokenUsageInfo {
|
|
170
|
+
inputTokens: number;
|
|
171
|
+
outputTokens: number;
|
|
172
|
+
totalTokens: number;
|
|
173
|
+
}
|
|
174
|
+
export interface LLMChatResponse {
|
|
175
|
+
message: LLMChatMessage;
|
|
176
|
+
/** Reasoning/thinking content from the model (if supported) */
|
|
177
|
+
reasoning?: string;
|
|
178
|
+
/** Token usage info */
|
|
179
|
+
usage?: TokenUsageInfo;
|
|
180
|
+
/** Tool execution trace (populated by chatWithTools) */
|
|
181
|
+
toolExecutions?: ToolExecutionResult[];
|
|
182
|
+
/** Which provider served this response */
|
|
183
|
+
provider?: string;
|
|
184
|
+
}
|
|
185
|
+
export interface OllamaResponse {
|
|
186
|
+
model: string;
|
|
187
|
+
created_at: string;
|
|
188
|
+
message: {
|
|
189
|
+
role: string;
|
|
190
|
+
content: string;
|
|
191
|
+
thinking?: string;
|
|
192
|
+
tool_calls?: LLMToolCall[];
|
|
193
|
+
};
|
|
194
|
+
done: boolean;
|
|
195
|
+
prompt_eval_count?: number;
|
|
196
|
+
eval_count?: number;
|
|
197
|
+
prompt_eval_duration?: number;
|
|
198
|
+
eval_duration?: number;
|
|
199
|
+
}
|
|
200
|
+
export interface OpenAIResponse {
|
|
201
|
+
id: string;
|
|
202
|
+
object: string;
|
|
203
|
+
created: number;
|
|
204
|
+
model: string;
|
|
205
|
+
choices: Array<{
|
|
206
|
+
index: number;
|
|
207
|
+
message: {
|
|
208
|
+
role: string;
|
|
209
|
+
content: string | null;
|
|
210
|
+
tool_calls?: LLMToolCall[];
|
|
211
|
+
};
|
|
212
|
+
finish_reason: string;
|
|
213
|
+
}>;
|
|
214
|
+
usage?: {
|
|
215
|
+
prompt_tokens: number;
|
|
216
|
+
completion_tokens: number;
|
|
217
|
+
total_tokens: number;
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
export interface OllamaModelInfo {
|
|
221
|
+
name: string;
|
|
222
|
+
size: number;
|
|
223
|
+
digest: string;
|
|
224
|
+
details: {
|
|
225
|
+
format: string;
|
|
226
|
+
family: string;
|
|
227
|
+
families: string[];
|
|
228
|
+
parameter_size: string;
|
|
229
|
+
quantization_level: string;
|
|
230
|
+
};
|
|
231
|
+
modified_at: string;
|
|
232
|
+
}
|
|
233
|
+
export interface OpenAIModelInfo {
|
|
234
|
+
id: string;
|
|
235
|
+
object: string;
|
|
236
|
+
created: number;
|
|
237
|
+
owned_by: string;
|
|
238
|
+
}
|
|
239
|
+
export interface GooglePart {
|
|
240
|
+
text?: string;
|
|
241
|
+
functionCall?: {
|
|
242
|
+
name: string;
|
|
243
|
+
args: Record<string, unknown>;
|
|
244
|
+
};
|
|
245
|
+
functionResponse?: {
|
|
246
|
+
name: string;
|
|
247
|
+
response: Record<string, unknown>;
|
|
248
|
+
};
|
|
249
|
+
inlineData?: {
|
|
250
|
+
mimeType: string;
|
|
251
|
+
data: string;
|
|
252
|
+
};
|
|
253
|
+
/** Gemini 3.x thought signature — must be echoed back on functionCall parts */
|
|
254
|
+
thoughtSignature?: string;
|
|
255
|
+
}
|
|
256
|
+
export interface GoogleContent {
|
|
257
|
+
role: 'user' | 'model' | 'function';
|
|
258
|
+
parts: GooglePart[];
|
|
259
|
+
}
|
|
260
|
+
export interface GoogleGenerationConfig {
|
|
261
|
+
responseMimeType?: string;
|
|
262
|
+
temperature?: number;
|
|
263
|
+
maxOutputTokens?: number;
|
|
264
|
+
topK?: number;
|
|
265
|
+
topP?: number;
|
|
266
|
+
thinkingConfig?: {
|
|
267
|
+
thinkingBudget?: number;
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
export interface GoogleFunctionDeclaration {
|
|
271
|
+
name: string;
|
|
272
|
+
description: string;
|
|
273
|
+
parameters: {
|
|
274
|
+
type: 'object';
|
|
275
|
+
properties: Record<string, unknown>;
|
|
276
|
+
required?: string[];
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
export interface GoogleToolConfig {
|
|
280
|
+
functionCallingConfig?: {
|
|
281
|
+
mode: 'AUTO' | 'ANY' | 'NONE';
|
|
282
|
+
allowedFunctionNames?: string[];
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
export interface GoogleRequest {
|
|
286
|
+
contents: GoogleContent[];
|
|
287
|
+
generationConfig?: GoogleGenerationConfig;
|
|
288
|
+
systemInstruction?: {
|
|
289
|
+
parts: Array<{
|
|
290
|
+
text: string;
|
|
291
|
+
}>;
|
|
292
|
+
};
|
|
293
|
+
tools?: Array<{
|
|
294
|
+
functionDeclarations: GoogleFunctionDeclaration[];
|
|
295
|
+
}>;
|
|
296
|
+
toolConfig?: GoogleToolConfig;
|
|
297
|
+
}
|
|
298
|
+
export interface GoogleCandidate {
|
|
299
|
+
content: {
|
|
300
|
+
parts: GooglePart[];
|
|
301
|
+
role: string;
|
|
302
|
+
};
|
|
303
|
+
finishReason?: string;
|
|
304
|
+
index: number;
|
|
305
|
+
}
|
|
306
|
+
export interface GoogleResponse {
|
|
307
|
+
candidates: GoogleCandidate[];
|
|
308
|
+
usageMetadata?: {
|
|
309
|
+
promptTokenCount: number;
|
|
310
|
+
candidatesTokenCount: number;
|
|
311
|
+
totalTokenCount: number;
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
/** Create a text content part */
|
|
315
|
+
export declare function textContent(text: string): LLMTextContent;
|
|
316
|
+
/** Create an image content part from base64 data or URL */
|
|
317
|
+
export declare function imageContent(base64DataOrUrl: string, mimeType?: string, detail?: 'auto' | 'low' | 'high'): LLMImageContent;
|
|
318
|
+
/** Create a multimodal user message with text and images */
|
|
319
|
+
export declare function multimodalMessage(text: string, images: string[], mimeType?: string): LLMChatMessage;
|
|
320
|
+
/** Extract text content from a message content value */
|
|
321
|
+
export declare function extractTextContent(content: LLMMessageContent): string;
|
|
322
|
+
/** Check if message content contains images */
|
|
323
|
+
export declare function hasImages(content: LLMMessageContent): boolean;
|
|
324
|
+
//# sourceMappingURL=interfaces.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Universal LLM Client v3 — Core Interfaces
|
|
3
|
+
*
|
|
4
|
+
* All types, enums, and helper functions used throughout the library.
|
|
5
|
+
* Zero dependencies — pure TypeScript types.
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Enums
|
|
9
|
+
// ============================================================================
|
|
10
|
+
export var AIModelType;
|
|
11
|
+
(function (AIModelType) {
|
|
12
|
+
AIModelType["Chat"] = "chat";
|
|
13
|
+
AIModelType["Embedding"] = "embedding";
|
|
14
|
+
})(AIModelType || (AIModelType = {}));
|
|
15
|
+
export var AIModelApiType;
|
|
16
|
+
(function (AIModelApiType) {
|
|
17
|
+
AIModelApiType["Ollama"] = "ollama";
|
|
18
|
+
AIModelApiType["OpenAI"] = "openai";
|
|
19
|
+
AIModelApiType["Google"] = "google";
|
|
20
|
+
AIModelApiType["Vertex"] = "vertex";
|
|
21
|
+
AIModelApiType["LlamaCpp"] = "llamacpp";
|
|
22
|
+
})(AIModelApiType || (AIModelApiType = {}));
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Helper Functions
|
|
25
|
+
// ============================================================================
|
|
26
|
+
/** Create a text content part */
|
|
27
|
+
export function textContent(text) {
|
|
28
|
+
return { type: 'text', text };
|
|
29
|
+
}
|
|
30
|
+
/** Create an image content part from base64 data or URL */
|
|
31
|
+
export function imageContent(base64DataOrUrl, mimeType = 'image/jpeg', detail) {
|
|
32
|
+
const url = base64DataOrUrl.startsWith('data:') || base64DataOrUrl.startsWith('http')
|
|
33
|
+
? base64DataOrUrl
|
|
34
|
+
: `data:${mimeType};base64,${base64DataOrUrl}`;
|
|
35
|
+
return {
|
|
36
|
+
type: 'image_url',
|
|
37
|
+
image_url: { url, detail },
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Create a multimodal user message with text and images */
|
|
41
|
+
export function multimodalMessage(text, images, mimeType = 'image/jpeg') {
|
|
42
|
+
const content = [
|
|
43
|
+
textContent(text),
|
|
44
|
+
...images.map(img => imageContent(img, mimeType)),
|
|
45
|
+
];
|
|
46
|
+
return { role: 'user', content };
|
|
47
|
+
}
|
|
48
|
+
/** Extract text content from a message content value */
|
|
49
|
+
export function extractTextContent(content) {
|
|
50
|
+
if (typeof content === 'string')
|
|
51
|
+
return content;
|
|
52
|
+
return content
|
|
53
|
+
.filter((part) => part.type === 'text')
|
|
54
|
+
.map(part => part.text)
|
|
55
|
+
.join('');
|
|
56
|
+
}
|
|
57
|
+
/** Check if message content contains images */
|
|
58
|
+
export function hasImages(content) {
|
|
59
|
+
if (typeof content === 'string')
|
|
60
|
+
return false;
|
|
61
|
+
return content.some(part => part.type === 'image_url');
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=interfaces.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACnB,4BAAa,CAAA;IACb,sCAAuB,CAAA;AAC3B,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB;AAED,MAAM,CAAN,IAAY,cAMX;AAND,WAAY,cAAc;IACtB,mCAAiB,CAAA;IACjB,mCAAiB,CAAA;IACjB,mCAAiB,CAAA;IACjB,mCAAiB,CAAA;IACjB,uCAAqB,CAAA;AACzB,CAAC,EANW,cAAc,KAAd,cAAc,QAMzB;AAoXD,+EAA+E;AAC/E,mBAAmB;AACnB,+EAA+E;AAE/E,iCAAiC;AACjC,MAAM,UAAU,WAAW,CAAC,IAAY;IACpC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,YAAY,CACxB,eAAuB,EACvB,WAAmB,YAAY,EAC/B,MAAgC;IAEhC,MAAM,GAAG,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,eAAe,CAAC,UAAU,CAAC,MAAM,CAAC;QACjF,CAAC,CAAC,eAAe;QACjB,CAAC,CAAC,QAAQ,QAAQ,WAAW,eAAe,EAAE,CAAC;IACnD,OAAO;QACH,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE;KAC7B,CAAC;AACN,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,iBAAiB,CAC7B,IAAY,EACZ,MAAgB,EAChB,WAAmB,YAAY;IAE/B,MAAM,OAAO,GAAqB;QAC9B,WAAW,CAAC,IAAI,CAAC;QACjB,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;KACpD,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACrC,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,kBAAkB,CAAC,OAA0B;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,OAAO;SACT,MAAM,CAAC,CAAC,IAAI,EAA0B,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;SAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACtB,IAAI,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,SAAS,CAAC,OAA0B;IAChD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC;AAC3D,CAAC"}
|