@oai2lmapi/opencode-provider 0.1.3 → 0.2.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/README.md +164 -266
- package/dist/config.d.ts +24 -41
- package/dist/config.d.ts.map +1 -1
- package/dist/discover.d.ts +28 -0
- package/dist/discover.d.ts.map +1 -0
- package/dist/index.d.ts +97 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +274 -333
- package/dist/index.js.map +3 -3
- package/dist/metadata.d.ts +36 -0
- package/dist/metadata.d.ts.map +1 -0
- package/oai2lm.schema.json +79 -0
- package/package.json +20 -13
- package/dist/modelDiscovery.d.ts +0 -31
- package/dist/modelDiscovery.d.ts.map +0 -1
- package/dist/modelMetadata.d.ts +0 -14
- package/dist/modelMetadata.d.ts.map +0 -1
- package/dist/provider.d.ts +0 -65
- package/dist/provider.d.ts.map +0 -1
- package/dist/types.d.ts +0 -69
- package/dist/types.d.ts.map +0 -1
- package/dist/utils.d.ts +0 -18
- package/dist/utils.d.ts.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,150 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
import {
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
createOpenAICompatible
|
|
4
|
+
} from "@ai-sdk/openai-compatible";
|
|
5
|
+
|
|
6
|
+
// src/config.ts
|
|
7
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join, isAbsolute } from "node:path";
|
|
10
|
+
function getDataDir() {
|
|
11
|
+
const xdgDataHome = process.env["XDG_DATA_HOME"];
|
|
12
|
+
if (xdgDataHome && isAbsolute(xdgDataHome)) {
|
|
13
|
+
return join(xdgDataHome, "opencode");
|
|
14
|
+
}
|
|
15
|
+
return join(homedir(), ".local", "share", "opencode");
|
|
16
|
+
}
|
|
17
|
+
function getConfigDir() {
|
|
18
|
+
const xdgConfigHome = process.env["XDG_CONFIG_HOME"];
|
|
19
|
+
if (xdgConfigHome && isAbsolute(xdgConfigHome)) {
|
|
20
|
+
return join(xdgConfigHome, "opencode");
|
|
21
|
+
}
|
|
22
|
+
return join(homedir(), ".config", "opencode");
|
|
23
|
+
}
|
|
24
|
+
var CONFIG_FILENAME = "oai2lm.json";
|
|
25
|
+
function readJsonFile(filepath) {
|
|
26
|
+
try {
|
|
27
|
+
if (!existsSync(filepath)) {
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
const content = readFileSync(filepath, "utf-8");
|
|
31
|
+
return JSON.parse(content);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
if (error instanceof SyntaxError) {
|
|
34
|
+
console.warn(
|
|
35
|
+
`Failed to parse JSON in config file ${filepath}: ${error.message}`
|
|
36
|
+
);
|
|
37
|
+
} else {
|
|
38
|
+
console.warn(`Failed to read config file ${filepath}:`, error);
|
|
39
|
+
}
|
|
40
|
+
return void 0;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function loadConfig() {
|
|
44
|
+
const dataDir = getDataDir();
|
|
45
|
+
const configDir = getConfigDir();
|
|
46
|
+
const dataPath = join(dataDir, CONFIG_FILENAME);
|
|
47
|
+
const dataConfig = readJsonFile(dataPath);
|
|
48
|
+
const configPath = join(configDir, CONFIG_FILENAME);
|
|
49
|
+
const configDirConfig = readJsonFile(configPath);
|
|
50
|
+
if (dataConfig && configDirConfig) {
|
|
51
|
+
return {
|
|
52
|
+
...configDirConfig,
|
|
53
|
+
...dataConfig,
|
|
54
|
+
headers: {
|
|
55
|
+
...configDirConfig.headers,
|
|
56
|
+
...dataConfig.headers
|
|
57
|
+
},
|
|
58
|
+
modelOverrides: {
|
|
59
|
+
...configDirConfig.modelOverrides,
|
|
60
|
+
...dataConfig.modelOverrides
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return dataConfig || configDirConfig;
|
|
65
|
+
}
|
|
66
|
+
function resolveApiKey(config) {
|
|
67
|
+
if (config.apiKey) {
|
|
68
|
+
const envMatch = config.apiKey.match(/^\{env:(\w+)\}$/);
|
|
69
|
+
if (envMatch) {
|
|
70
|
+
return process.env[envMatch[1]];
|
|
71
|
+
}
|
|
72
|
+
const fileMatch = config.apiKey.match(/^\{file:(.+)\}$/);
|
|
73
|
+
if (fileMatch) {
|
|
74
|
+
try {
|
|
75
|
+
let filePath = fileMatch[1];
|
|
76
|
+
if (filePath.startsWith("~")) {
|
|
77
|
+
filePath = join(homedir(), filePath.slice(1));
|
|
78
|
+
}
|
|
79
|
+
return readFileSync(filePath, "utf-8").trim();
|
|
80
|
+
} catch {
|
|
81
|
+
return void 0;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return config.apiKey;
|
|
85
|
+
}
|
|
86
|
+
return process.env["OAI2LM_API_KEY"];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/discover.ts
|
|
90
|
+
async function discoverModels(baseURL, apiKey, headers) {
|
|
91
|
+
const url = `${baseURL}/models`;
|
|
92
|
+
const response = await fetch(url, {
|
|
93
|
+
method: "GET",
|
|
94
|
+
headers: {
|
|
95
|
+
Authorization: `Bearer ${apiKey}`,
|
|
96
|
+
"Content-Type": "application/json",
|
|
97
|
+
...headers
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Failed to fetch models from ${url}: ${response.status} ${response.statusText}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
const models = data.data || [];
|
|
107
|
+
return models.map((model) => ({
|
|
108
|
+
id: model.id,
|
|
109
|
+
name: model.name,
|
|
110
|
+
object: model.object,
|
|
111
|
+
created: model.created,
|
|
112
|
+
owned_by: model.owned_by,
|
|
113
|
+
metadata: extractMetadataFromModel(model)
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
function extractMetadataFromModel(model) {
|
|
117
|
+
const metadata = {};
|
|
118
|
+
if (model.context_length) {
|
|
119
|
+
metadata.maxInputTokens = model.context_length;
|
|
120
|
+
}
|
|
121
|
+
if (model.max_tokens) {
|
|
122
|
+
metadata.maxOutputTokens = model.max_tokens;
|
|
123
|
+
}
|
|
124
|
+
if (model.max_input_tokens) {
|
|
125
|
+
metadata.maxInputTokens = model.max_input_tokens;
|
|
126
|
+
}
|
|
127
|
+
if (model.max_output_tokens) {
|
|
128
|
+
metadata.maxOutputTokens = model.max_output_tokens;
|
|
129
|
+
}
|
|
130
|
+
if (typeof model.function_call === "boolean") {
|
|
131
|
+
metadata.supportsToolCalling = model.function_call;
|
|
132
|
+
} else if (typeof model.supports_function_calling === "boolean") {
|
|
133
|
+
metadata.supportsToolCalling = model.supports_function_calling;
|
|
134
|
+
} else if (typeof model.supports_tools === "boolean") {
|
|
135
|
+
metadata.supportsToolCalling = model.supports_tools;
|
|
136
|
+
}
|
|
137
|
+
if (typeof model.vision === "boolean") {
|
|
138
|
+
metadata.supportsImageInput = model.vision;
|
|
139
|
+
} else if (typeof model.supports_vision === "boolean") {
|
|
140
|
+
metadata.supportsImageInput = model.supports_vision;
|
|
141
|
+
} else if (model.modalities?.includes("vision")) {
|
|
142
|
+
metadata.supportsImageInput = true;
|
|
143
|
+
} else if (model.modalities?.includes("image")) {
|
|
144
|
+
metadata.supportsImageInput = true;
|
|
145
|
+
}
|
|
146
|
+
return metadata;
|
|
147
|
+
}
|
|
3
148
|
|
|
4
149
|
// ../model-metadata/dist/esm/index.mjs
|
|
5
150
|
var DEFAULT_MODEL_METADATA = {
|
|
@@ -9,10 +154,10 @@ var DEFAULT_MODEL_METADATA = {
|
|
|
9
154
|
supportsImageInput: false,
|
|
10
155
|
modelType: "llm"
|
|
11
156
|
};
|
|
12
|
-
var md = (maxInputTokens, maxOutputTokens,
|
|
157
|
+
var md = (maxInputTokens, maxOutputTokens, supportsToolCalling, supportsImageInput, modelType = "llm") => ({
|
|
13
158
|
maxInputTokens,
|
|
14
159
|
maxOutputTokens,
|
|
15
|
-
supportsToolCalling
|
|
160
|
+
supportsToolCalling,
|
|
16
161
|
supportsImageInput,
|
|
17
162
|
modelType
|
|
18
163
|
});
|
|
@@ -536,360 +681,156 @@ function getModelMetadata(modelId) {
|
|
|
536
681
|
function getModelMetadataFromPatterns(modelId) {
|
|
537
682
|
return getModelMetadata(modelId);
|
|
538
683
|
}
|
|
684
|
+
|
|
685
|
+
// src/metadata.ts
|
|
686
|
+
function getModelMetadataFromPatterns2(modelId) {
|
|
687
|
+
return getModelMetadataFromPatterns(modelId);
|
|
688
|
+
}
|
|
539
689
|
function mergeMetadata(apiMetadata, patternMetadata) {
|
|
690
|
+
if (!apiMetadata) {
|
|
691
|
+
return patternMetadata;
|
|
692
|
+
}
|
|
540
693
|
return {
|
|
541
|
-
maxInputTokens: apiMetadata
|
|
542
|
-
maxOutputTokens: apiMetadata
|
|
543
|
-
supportsToolCalling: apiMetadata
|
|
544
|
-
supportsImageInput: apiMetadata
|
|
545
|
-
modelType:
|
|
694
|
+
maxInputTokens: apiMetadata.maxInputTokens ?? patternMetadata.maxInputTokens,
|
|
695
|
+
maxOutputTokens: apiMetadata.maxOutputTokens ?? patternMetadata.maxOutputTokens,
|
|
696
|
+
supportsToolCalling: apiMetadata.supportsToolCalling ?? patternMetadata.supportsToolCalling,
|
|
697
|
+
supportsImageInput: apiMetadata.supportsImageInput ?? patternMetadata.supportsImageInput,
|
|
698
|
+
modelType: patternMetadata.modelType
|
|
546
699
|
};
|
|
547
700
|
}
|
|
548
701
|
|
|
549
|
-
// src/
|
|
550
|
-
var
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
// 5 minutes
|
|
556
|
-
constructor(baseURL, apiKey, headers, fetchFn = fetch) {
|
|
557
|
-
this.baseURL = baseURL;
|
|
558
|
-
this.apiKey = apiKey;
|
|
559
|
-
this.headers = headers;
|
|
560
|
-
this.fetchFn = fetchFn;
|
|
702
|
+
// src/index.ts
|
|
703
|
+
var modelCache = /* @__PURE__ */ new WeakMap();
|
|
704
|
+
function findModelOverride(modelId, overrides) {
|
|
705
|
+
if (!overrides) return void 0;
|
|
706
|
+
if (overrides[modelId]) {
|
|
707
|
+
return overrides[modelId];
|
|
561
708
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
async fetchModels() {
|
|
569
|
-
const now = Date.now();
|
|
570
|
-
if (this.modelsCache.size > 0 && now - this.lastFetchTime < this.cacheDuration) {
|
|
571
|
-
return Array.from(this.modelsCache.values());
|
|
572
|
-
}
|
|
573
|
-
try {
|
|
574
|
-
const url = `${this.baseURL}/models`;
|
|
575
|
-
const response = await this.fetchFn(url, {
|
|
576
|
-
method: "GET",
|
|
577
|
-
headers: {
|
|
578
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
579
|
-
...this.headers
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
if (!response.ok) {
|
|
583
|
-
console.warn(`Failed to fetch models from ${url}: ${response.status} ${response.statusText}`);
|
|
584
|
-
return [];
|
|
709
|
+
for (const [pattern, override] of Object.entries(overrides)) {
|
|
710
|
+
if (pattern.includes("*") || pattern.includes("?")) {
|
|
711
|
+
const regex = new RegExp(
|
|
712
|
+
"^" + pattern.replace(/\*/g, ".*").replace(/\?/g, ".") + "$"
|
|
713
|
+
);
|
|
714
|
+
{
|
|
585
715
|
}
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
for (const model of models) {
|
|
589
|
-
const patternMetadata = getModelMetadataFromPatterns2(model.id);
|
|
590
|
-
const apiMetadata = this.extractMetadataFromModel(model);
|
|
591
|
-
model.metadata = mergeMetadata2(apiMetadata, patternMetadata);
|
|
592
|
-
this.modelsCache.set(model.id, model);
|
|
716
|
+
if (regex.test(modelId)) {
|
|
717
|
+
return override;
|
|
593
718
|
}
|
|
594
|
-
this.lastFetchTime = now;
|
|
595
|
-
return models;
|
|
596
|
-
} catch (error) {
|
|
597
|
-
console.error("Error fetching models:", error);
|
|
598
|
-
return [];
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Get metadata for a specific model
|
|
603
|
-
*/
|
|
604
|
-
async getModelMetadata(modelId) {
|
|
605
|
-
const cached = this.modelsCache.get(modelId);
|
|
606
|
-
if (cached?.metadata) {
|
|
607
|
-
return cached.metadata;
|
|
608
|
-
}
|
|
609
|
-
await this.fetchModels();
|
|
610
|
-
const model = this.modelsCache.get(modelId);
|
|
611
|
-
if (model?.metadata) {
|
|
612
|
-
return model.metadata;
|
|
613
|
-
}
|
|
614
|
-
return getModelMetadataFromPatterns2(modelId);
|
|
615
|
-
}
|
|
616
|
-
/**
|
|
617
|
-
* Extract metadata from model object returned by API
|
|
618
|
-
*/
|
|
619
|
-
extractMetadataFromModel(model) {
|
|
620
|
-
const metadata = {};
|
|
621
|
-
if (model.context_length) {
|
|
622
|
-
metadata.maxInputTokens = model.context_length;
|
|
623
|
-
}
|
|
624
|
-
if (model.max_tokens) {
|
|
625
|
-
metadata.maxOutputTokens = model.max_tokens;
|
|
626
|
-
}
|
|
627
|
-
if (model.max_input_tokens) {
|
|
628
|
-
metadata.maxInputTokens = model.max_input_tokens;
|
|
629
|
-
}
|
|
630
|
-
if (model.max_output_tokens) {
|
|
631
|
-
metadata.maxOutputTokens = model.max_output_tokens;
|
|
632
|
-
}
|
|
633
|
-
if (typeof model.function_call === "boolean") {
|
|
634
|
-
metadata.supportsToolCalling = model.function_call;
|
|
635
|
-
} else if (typeof model.supports_function_calling === "boolean") {
|
|
636
|
-
metadata.supportsToolCalling = model.supports_function_calling;
|
|
637
|
-
} else if (typeof model.supports_tools === "boolean") {
|
|
638
|
-
metadata.supportsToolCalling = model.supports_tools;
|
|
639
|
-
}
|
|
640
|
-
if (typeof model.vision === "boolean") {
|
|
641
|
-
metadata.supportsImageInput = model.vision;
|
|
642
|
-
} else if (typeof model.supports_vision === "boolean") {
|
|
643
|
-
metadata.supportsImageInput = model.supports_vision;
|
|
644
|
-
} else if (model.modalities?.includes("vision")) {
|
|
645
|
-
metadata.supportsImageInput = true;
|
|
646
|
-
} else if (model.modalities?.includes("image")) {
|
|
647
|
-
metadata.supportsImageInput = true;
|
|
648
|
-
}
|
|
649
|
-
return metadata;
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Clear cache
|
|
653
|
-
*/
|
|
654
|
-
clearCache() {
|
|
655
|
-
this.modelsCache.clear();
|
|
656
|
-
this.lastFetchTime = 0;
|
|
657
|
-
}
|
|
658
|
-
};
|
|
659
|
-
|
|
660
|
-
// src/utils.ts
|
|
661
|
-
function wildcardToRegex(pattern) {
|
|
662
|
-
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
663
|
-
const regex = escaped.replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
664
|
-
return new RegExp(`^${regex}$`, "i");
|
|
665
|
-
}
|
|
666
|
-
function matchesWildcard(modelId, pattern) {
|
|
667
|
-
const regex = wildcardToRegex(pattern);
|
|
668
|
-
return regex.test(modelId);
|
|
669
|
-
}
|
|
670
|
-
function findBestMatch(modelId, patterns) {
|
|
671
|
-
const matches = patterns.filter((p) => matchesWildcard(modelId, p));
|
|
672
|
-
if (matches.length === 0) {
|
|
673
|
-
return void 0;
|
|
674
|
-
}
|
|
675
|
-
matches.sort((a, b) => {
|
|
676
|
-
const aHasWildcard = a.includes("*") || a.includes("?");
|
|
677
|
-
const bHasWildcard = b.includes("*") || b.includes("?");
|
|
678
|
-
if (!aHasWildcard && bHasWildcard) return -1;
|
|
679
|
-
if (aHasWildcard && !bHasWildcard) return 1;
|
|
680
|
-
return b.length - a.length;
|
|
681
|
-
});
|
|
682
|
-
return matches[0];
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
// src/config.ts
|
|
686
|
-
import { readFileSync, existsSync } from "node:fs";
|
|
687
|
-
import { homedir } from "node:os";
|
|
688
|
-
import { join, isAbsolute } from "node:path";
|
|
689
|
-
function getDataDir() {
|
|
690
|
-
const xdgDataHome = process.env["XDG_DATA_HOME"];
|
|
691
|
-
if (xdgDataHome && isAbsolute(xdgDataHome)) {
|
|
692
|
-
return join(xdgDataHome, "opencode");
|
|
693
|
-
}
|
|
694
|
-
return join(homedir(), ".local", "share", "opencode");
|
|
695
|
-
}
|
|
696
|
-
function getConfigDir() {
|
|
697
|
-
const xdgConfigHome = process.env["XDG_CONFIG_HOME"];
|
|
698
|
-
if (xdgConfigHome && isAbsolute(xdgConfigHome)) {
|
|
699
|
-
return join(xdgConfigHome, "opencode");
|
|
700
|
-
}
|
|
701
|
-
return join(homedir(), ".config", "opencode");
|
|
702
|
-
}
|
|
703
|
-
var CONFIG_FILENAME = "oai2lm.json";
|
|
704
|
-
function readJsonFile(filepath) {
|
|
705
|
-
try {
|
|
706
|
-
if (!existsSync(filepath)) {
|
|
707
|
-
return void 0;
|
|
708
|
-
}
|
|
709
|
-
const content = readFileSync(filepath, "utf-8");
|
|
710
|
-
return JSON.parse(content);
|
|
711
|
-
} catch (error) {
|
|
712
|
-
if (error instanceof SyntaxError) {
|
|
713
|
-
const message = error.message;
|
|
714
|
-
console.warn(`Failed to parse JSON in config file ${filepath}: ${message}`);
|
|
715
|
-
} else {
|
|
716
|
-
console.warn(`Failed to read config file ${filepath}:`, error);
|
|
717
|
-
}
|
|
718
|
-
return void 0;
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
function loadConfig() {
|
|
722
|
-
const paths = [
|
|
723
|
-
join(getDataDir(), CONFIG_FILENAME),
|
|
724
|
-
join(getConfigDir(), CONFIG_FILENAME)
|
|
725
|
-
];
|
|
726
|
-
for (const configPath of paths) {
|
|
727
|
-
const config = readJsonFile(configPath);
|
|
728
|
-
if (config) {
|
|
729
|
-
return config;
|
|
730
719
|
}
|
|
731
720
|
}
|
|
732
721
|
return void 0;
|
|
733
722
|
}
|
|
734
|
-
function
|
|
735
|
-
if (
|
|
736
|
-
return explicitKey.trim();
|
|
737
|
-
}
|
|
738
|
-
const envKey = process.env["OAI2LM_API_KEY"];
|
|
739
|
-
if (typeof envKey === "string" && envKey.trim() !== "") {
|
|
740
|
-
return envKey.trim();
|
|
741
|
-
}
|
|
742
|
-
return config?.apiKey;
|
|
743
|
-
}
|
|
744
|
-
function resolveBaseURL(explicitURL, config) {
|
|
745
|
-
if (typeof explicitURL === "string" && explicitURL.trim().length > 0) {
|
|
746
|
-
return explicitURL.trim();
|
|
747
|
-
}
|
|
748
|
-
const envURL = process.env["OAI2LM_BASE_URL"];
|
|
749
|
-
if (typeof envURL === "string" && envURL.trim().length > 0) {
|
|
750
|
-
return envURL.trim();
|
|
751
|
-
}
|
|
752
|
-
if (typeof config?.baseURL === "string" && config.baseURL.trim().length > 0) {
|
|
753
|
-
return config.baseURL.trim();
|
|
754
|
-
}
|
|
755
|
-
return "https://api.openai.com/v1";
|
|
756
|
-
}
|
|
757
|
-
function createSettingsFromConfig(overrides) {
|
|
758
|
-
const config = loadConfig();
|
|
759
|
-
const apiKey = resolveApiKey(overrides?.apiKey, config);
|
|
760
|
-
if (!apiKey) {
|
|
761
|
-
const dataPath = join(getDataDir(), CONFIG_FILENAME);
|
|
762
|
-
const configPath = join(getConfigDir(), CONFIG_FILENAME);
|
|
763
|
-
throw new Error(
|
|
764
|
-
"API key not found. Please set OAI2LM_API_KEY environment variable, or add apiKey to " + dataPath + " or " + configPath + ", or pass apiKey in settings."
|
|
765
|
-
);
|
|
766
|
-
}
|
|
767
|
-
const baseURL = resolveBaseURL(overrides?.baseURL, config);
|
|
768
|
-
const modelOverrides = {
|
|
769
|
-
...config?.modelOverrides ?? {},
|
|
770
|
-
...overrides?.modelOverrides ?? {}
|
|
771
|
-
};
|
|
723
|
+
function mergeWithConfig(options, config) {
|
|
724
|
+
if (!config) return options;
|
|
772
725
|
return {
|
|
773
|
-
|
|
774
|
-
baseURL,
|
|
775
|
-
|
|
726
|
+
// Options take precedence over config
|
|
727
|
+
baseURL: options.baseURL || config.baseURL || "",
|
|
728
|
+
apiKey: options.apiKey || resolveApiKey(config),
|
|
729
|
+
name: options.name || config.name,
|
|
776
730
|
headers: {
|
|
777
|
-
...config
|
|
778
|
-
...
|
|
731
|
+
...config.headers,
|
|
732
|
+
...options.headers
|
|
733
|
+
},
|
|
734
|
+
modelFilter: options.modelFilter || config.modelFilter,
|
|
735
|
+
modelOverrides: {
|
|
736
|
+
...config.modelOverrides,
|
|
737
|
+
...options.modelOverrides
|
|
779
738
|
},
|
|
780
|
-
|
|
781
|
-
modelOverrides: Object.keys(modelOverrides).length > 0 ? modelOverrides : void 0,
|
|
782
|
-
fetch: overrides?.fetch
|
|
739
|
+
useConfigFile: options.useConfigFile
|
|
783
740
|
};
|
|
784
741
|
}
|
|
785
|
-
function
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
const fetchFn = settings.fetch || fetch;
|
|
742
|
+
function createOai2lm(options) {
|
|
743
|
+
const config = options.useConfigFile !== false ? loadConfig() : void 0;
|
|
744
|
+
const mergedOptions = mergeWithConfig(options, config);
|
|
745
|
+
if (!mergedOptions.baseURL) {
|
|
746
|
+
throw new Error(
|
|
747
|
+
"baseURL is required. Provide it in options or in oai2lm.json config file."
|
|
748
|
+
);
|
|
749
|
+
}
|
|
794
750
|
const baseProvider = createOpenAICompatible({
|
|
795
|
-
baseURL:
|
|
796
|
-
name:
|
|
797
|
-
apiKey:
|
|
798
|
-
headers:
|
|
799
|
-
fetch: fetchFn
|
|
751
|
+
baseURL: mergedOptions.baseURL.replace(/\/+$/, ""),
|
|
752
|
+
name: mergedOptions.name || "oai2lm",
|
|
753
|
+
apiKey: mergedOptions.apiKey,
|
|
754
|
+
headers: mergedOptions.headers
|
|
800
755
|
});
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
756
|
+
const cacheKey = {};
|
|
757
|
+
async function discoverAndCache() {
|
|
758
|
+
const apiKey = mergedOptions.apiKey || "";
|
|
759
|
+
const models = await discoverModels(
|
|
760
|
+
mergedOptions.baseURL,
|
|
761
|
+
apiKey,
|
|
762
|
+
mergedOptions.headers
|
|
763
|
+
);
|
|
764
|
+
let filteredModels = models;
|
|
765
|
+
if (mergedOptions.modelFilter) {
|
|
766
|
+
const filterRegex = new RegExp(mergedOptions.modelFilter);
|
|
767
|
+
filteredModels = models.filter((m) => filterRegex.test(m.id));
|
|
768
|
+
}
|
|
769
|
+
const metadataMap = /* @__PURE__ */ new Map();
|
|
770
|
+
for (const model of filteredModels) {
|
|
771
|
+
const patternMetadata = getModelMetadataFromPatterns2(model.id);
|
|
772
|
+
const metadata = mergeMetadata(model.metadata, patternMetadata);
|
|
773
|
+
const override = findModelOverride(
|
|
774
|
+
model.id,
|
|
775
|
+
mergedOptions.modelOverrides
|
|
776
|
+
);
|
|
777
|
+
if (override) {
|
|
778
|
+
if (override.maxInputTokens !== void 0) {
|
|
779
|
+
metadata.maxInputTokens = override.maxInputTokens;
|
|
780
|
+
}
|
|
781
|
+
if (override.maxOutputTokens !== void 0) {
|
|
782
|
+
metadata.maxOutputTokens = override.maxOutputTokens;
|
|
783
|
+
}
|
|
784
|
+
if (override.supportsToolCalling !== void 0) {
|
|
785
|
+
metadata.supportsToolCalling = override.supportsToolCalling;
|
|
786
|
+
}
|
|
787
|
+
if (override.supportsImageInput !== void 0) {
|
|
788
|
+
metadata.supportsImageInput = override.supportsImageInput;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
metadataMap.set(model.id, metadata);
|
|
792
|
+
}
|
|
793
|
+
modelCache.set(cacheKey, {
|
|
794
|
+
models: filteredModels,
|
|
795
|
+
metadata: metadataMap,
|
|
796
|
+
lastRefresh: Date.now()
|
|
824
797
|
});
|
|
825
798
|
}
|
|
799
|
+
async function getCache() {
|
|
800
|
+
let cache = modelCache.get(cacheKey);
|
|
801
|
+
if (!cache) {
|
|
802
|
+
await discoverAndCache();
|
|
803
|
+
cache = modelCache.get(cacheKey);
|
|
804
|
+
}
|
|
805
|
+
return cache;
|
|
806
|
+
}
|
|
826
807
|
const provider = function(modelId) {
|
|
827
|
-
return baseProvider
|
|
808
|
+
return baseProvider(modelId);
|
|
828
809
|
};
|
|
829
|
-
provider.languageModel = baseProvider.languageModel
|
|
830
|
-
provider.chatModel = baseProvider.chatModel
|
|
831
|
-
provider.completionModel = baseProvider.completionModel
|
|
832
|
-
provider.textEmbeddingModel = baseProvider.textEmbeddingModel
|
|
833
|
-
provider.imageModel = baseProvider.imageModel
|
|
834
|
-
provider.
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
enumerable: true
|
|
842
|
-
});
|
|
843
|
-
return provider;
|
|
844
|
-
}
|
|
845
|
-
function createOAI2LMProviderFromConfig(overrides) {
|
|
846
|
-
const settings = createSettingsFromConfig(overrides);
|
|
847
|
-
return createOAI2LMProvider(settings);
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
// src/index.ts
|
|
851
|
-
function isPluginInput(arg) {
|
|
852
|
-
if (typeof arg !== "object" || arg === null) {
|
|
853
|
-
return false;
|
|
854
|
-
}
|
|
855
|
-
if (!Object.prototype.hasOwnProperty.call(arg, "client")) {
|
|
856
|
-
return false;
|
|
857
|
-
}
|
|
858
|
-
const client = arg.client;
|
|
859
|
-
if (typeof client !== "object" || client === null) {
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
return true;
|
|
863
|
-
}
|
|
864
|
-
var EMPTY_HOOKS = Object.freeze({});
|
|
865
|
-
function guardPluginCall(fn) {
|
|
866
|
-
return (...args) => {
|
|
867
|
-
if (args.length > 0 && isPluginInput(args[0])) {
|
|
868
|
-
return EMPTY_HOOKS;
|
|
869
|
-
}
|
|
870
|
-
return fn(...args);
|
|
810
|
+
provider.languageModel = (modelId) => baseProvider.languageModel(modelId);
|
|
811
|
+
provider.chatModel = (modelId) => baseProvider.chatModel(modelId);
|
|
812
|
+
provider.completionModel = (modelId) => baseProvider.completionModel(modelId);
|
|
813
|
+
provider.textEmbeddingModel = (modelId) => baseProvider.textEmbeddingModel(modelId);
|
|
814
|
+
provider.imageModel = (modelId) => baseProvider.imageModel(modelId);
|
|
815
|
+
provider.listModels = async () => {
|
|
816
|
+
const cache = await getCache();
|
|
817
|
+
return cache.models;
|
|
818
|
+
};
|
|
819
|
+
provider.getModelMetadata = async (modelId) => {
|
|
820
|
+
const cache = await getCache();
|
|
821
|
+
return cache.metadata.get(modelId);
|
|
871
822
|
};
|
|
823
|
+
provider.refreshModels = async () => {
|
|
824
|
+
await discoverAndCache();
|
|
825
|
+
};
|
|
826
|
+
return provider;
|
|
872
827
|
}
|
|
873
|
-
var
|
|
874
|
-
var createOAI2LMProviderFromConfig2 = guardPluginCall(createOAI2LMProviderFromConfig);
|
|
875
|
-
var loadConfig2 = guardPluginCall(loadConfig);
|
|
876
|
-
var createSettingsFromConfig2 = guardPluginCall(createSettingsFromConfig);
|
|
877
|
-
var getConfigFilePath2 = guardPluginCall(getConfigFilePath);
|
|
878
|
-
var getDataDir2 = guardPluginCall(getDataDir);
|
|
879
|
-
var getConfigDir2 = guardPluginCall(getConfigDir);
|
|
880
|
-
var resolveApiKey2 = guardPluginCall(resolveApiKey);
|
|
881
|
-
var resolveBaseURL2 = guardPluginCall(resolveBaseURL);
|
|
882
|
-
var getModelMetadataFromPatterns3 = guardPluginCall(getModelMetadataFromPatterns2);
|
|
828
|
+
var index_default = createOai2lm;
|
|
883
829
|
export {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
getDataDir2 as getDataDir,
|
|
890
|
-
getModelMetadataFromPatterns3 as getModelMetadataFromPatterns,
|
|
891
|
-
loadConfig2 as loadConfig,
|
|
892
|
-
resolveApiKey2 as resolveApiKey,
|
|
893
|
-
resolveBaseURL2 as resolveBaseURL
|
|
830
|
+
createOai2lm,
|
|
831
|
+
index_default as default,
|
|
832
|
+
discoverModels,
|
|
833
|
+
loadConfig,
|
|
834
|
+
resolveApiKey
|
|
894
835
|
};
|
|
895
836
|
//# sourceMappingURL=index.js.map
|