gitlab-ai-provider 5.0.0 → 5.1.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.
- package/CHANGELOG.md +12 -0
- package/dist/gitlab-ai-provider-5.1.1.tgz +0 -0
- package/dist/index.d.mts +56 -1
- package/dist/index.d.ts +1214 -1296
- package/dist/index.js +319 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +316 -65
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
GitLabDirectAccessClient: () => GitLabDirectAccessClient,
|
|
42
42
|
GitLabError: () => GitLabError,
|
|
43
43
|
GitLabModelCache: () => GitLabModelCache,
|
|
44
|
+
GitLabModelConfigRegistry: () => GitLabModelConfigRegistry,
|
|
44
45
|
GitLabModelDiscovery: () => GitLabModelDiscovery,
|
|
45
46
|
GitLabOAuthManager: () => GitLabOAuthManager,
|
|
46
47
|
GitLabOpenAILanguageModel: () => GitLabOpenAILanguageModel,
|
|
@@ -69,7 +70,8 @@ __export(index_exports, {
|
|
|
69
70
|
getWorkflowModelRef: () => getWorkflowModelRef,
|
|
70
71
|
gitlab: () => gitlab,
|
|
71
72
|
isResponsesApiModel: () => isResponsesApiModel,
|
|
72
|
-
isWorkflowModel: () => isWorkflowModel
|
|
73
|
+
isWorkflowModel: () => isWorkflowModel,
|
|
74
|
+
parseModelsYml: () => parseModelsYml
|
|
73
75
|
});
|
|
74
76
|
module.exports = __toCommonJS(index_exports);
|
|
75
77
|
|
|
@@ -357,7 +359,8 @@ var GitLabAnthropicLanguageModel = class {
|
|
|
357
359
|
const messages = [];
|
|
358
360
|
for (const message of prompt) {
|
|
359
361
|
if (message.role === "system") {
|
|
360
|
-
systemMessage =
|
|
362
|
+
systemMessage = systemMessage ? `${systemMessage}
|
|
363
|
+
${message.content}` : message.content;
|
|
361
364
|
continue;
|
|
362
365
|
}
|
|
363
366
|
if (message.role === "user") {
|
|
@@ -1573,7 +1576,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1573
1576
|
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
|
|
1574
1577
|
|
|
1575
1578
|
// src/version.ts
|
|
1576
|
-
var VERSION = true ? "
|
|
1579
|
+
var VERSION = true ? "5.1.0" : "0.0.0-dev";
|
|
1577
1580
|
|
|
1578
1581
|
// src/gitlab-workflow-types.ts
|
|
1579
1582
|
var WorkflowType = /* @__PURE__ */ ((WorkflowType2) => {
|
|
@@ -1910,7 +1913,8 @@ function sanitizeErrorMessage(message) {
|
|
|
1910
1913
|
if (!message) return "";
|
|
1911
1914
|
return message.replace(/\bBearer\s+[A-Za-z0-9\-_.~+/]+=*/gi, "Bearer [REDACTED]").replace(/\bgl(?:pat|oat|cbt|dt|oas|rt|soat|ffct|sapat)-[A-Za-z0-9_-]+/g, "[REDACTED]").replace(/([?&](?:private_token|access_token|token)=)[^&\s"']*/gi, "$1[REDACTED]").replace(/:\/\/([^:@/\s]+):([^@/\s]+)@/g, "://$1:[REDACTED]@");
|
|
1912
1915
|
}
|
|
1913
|
-
function mapBuiltinTool(dwsToolName, data) {
|
|
1916
|
+
function mapBuiltinTool(dwsToolName, data, availableTools) {
|
|
1917
|
+
const has = (name) => !availableTools || availableTools.has(name);
|
|
1914
1918
|
switch (dwsToolName) {
|
|
1915
1919
|
case "runReadFile":
|
|
1916
1920
|
return { toolName: "read", args: { filePath: data.filepath } };
|
|
@@ -1924,20 +1928,51 @@ function mapBuiltinTool(dwsToolName, data) {
|
|
|
1924
1928
|
args: { filePaths: paths }
|
|
1925
1929
|
};
|
|
1926
1930
|
}
|
|
1927
|
-
case "runWriteFile":
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
}
|
|
1940
|
-
|
|
1931
|
+
case "runWriteFile": {
|
|
1932
|
+
if (has("write")) {
|
|
1933
|
+
return {
|
|
1934
|
+
toolName: "write",
|
|
1935
|
+
args: { filePath: data.filepath, content: data.contents }
|
|
1936
|
+
};
|
|
1937
|
+
}
|
|
1938
|
+
const filePath = String(data.filepath ?? "");
|
|
1939
|
+
const content = String(data.contents ?? "");
|
|
1940
|
+
const patchLines = [
|
|
1941
|
+
"*** Begin Patch",
|
|
1942
|
+
`*** Add File: ${filePath}`,
|
|
1943
|
+
...content.split("\n").map((l) => `+${l}`),
|
|
1944
|
+
"*** End Patch"
|
|
1945
|
+
].join("\n");
|
|
1946
|
+
return { toolName: "apply_patch", args: { patchText: patchLines } };
|
|
1947
|
+
}
|
|
1948
|
+
case "runEditFile": {
|
|
1949
|
+
const editOldString = String(data.oldString ?? data.old_string ?? "");
|
|
1950
|
+
const editNewString = String(data.newString ?? data.new_string ?? "");
|
|
1951
|
+
if (has("edit")) {
|
|
1952
|
+
return {
|
|
1953
|
+
toolName: "edit",
|
|
1954
|
+
args: {
|
|
1955
|
+
filePath: data.filepath,
|
|
1956
|
+
oldString: editOldString,
|
|
1957
|
+
newString: editNewString
|
|
1958
|
+
}
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
const editPath = String(data.filepath ?? "");
|
|
1962
|
+
const oldStr = editOldString;
|
|
1963
|
+
const newStr = editNewString;
|
|
1964
|
+
const oldLines = oldStr.split("\n");
|
|
1965
|
+
const newLines = newStr.split("\n");
|
|
1966
|
+
const patchContent = [
|
|
1967
|
+
"*** Begin Patch",
|
|
1968
|
+
`*** Update File: ${editPath}`,
|
|
1969
|
+
"@@",
|
|
1970
|
+
...oldLines.map((l) => `-${l}`),
|
|
1971
|
+
...newLines.map((l) => `+${l}`),
|
|
1972
|
+
"*** End Patch"
|
|
1973
|
+
].join("\n");
|
|
1974
|
+
return { toolName: "apply_patch", args: { patchText: patchContent } };
|
|
1975
|
+
}
|
|
1941
1976
|
case "runShellCommand": {
|
|
1942
1977
|
const command = data.command;
|
|
1943
1978
|
if (!command || typeof command !== "string") {
|
|
@@ -2060,6 +2095,87 @@ function mapBuiltinTool(dwsToolName, data) {
|
|
|
2060
2095
|
return { toolName: dwsToolName, args: data };
|
|
2061
2096
|
}
|
|
2062
2097
|
}
|
|
2098
|
+
function validateSafePath(filePath) {
|
|
2099
|
+
if (!filePath) {
|
|
2100
|
+
throw new Error("filePath is required");
|
|
2101
|
+
}
|
|
2102
|
+
if (filePath.includes("\0")) {
|
|
2103
|
+
throw new Error("filePath contains null bytes");
|
|
2104
|
+
}
|
|
2105
|
+
const path5 = require("path");
|
|
2106
|
+
const resolved = path5.resolve(filePath);
|
|
2107
|
+
const cwd = process.cwd();
|
|
2108
|
+
if (!resolved.startsWith(cwd + path5.sep) && resolved !== cwd) {
|
|
2109
|
+
throw new Error(`filePath resolves outside the working directory: ${filePath}`);
|
|
2110
|
+
}
|
|
2111
|
+
return resolved;
|
|
2112
|
+
}
|
|
2113
|
+
function executeBuiltinFallback(toolName, argsJson) {
|
|
2114
|
+
if (toolName !== "edit" && toolName !== "write") {
|
|
2115
|
+
return null;
|
|
2116
|
+
}
|
|
2117
|
+
const fs4 = require("fs");
|
|
2118
|
+
let args;
|
|
2119
|
+
try {
|
|
2120
|
+
args = JSON.parse(argsJson);
|
|
2121
|
+
} catch {
|
|
2122
|
+
return { result: "", error: `${toolName} fallback: invalid JSON arguments` };
|
|
2123
|
+
}
|
|
2124
|
+
try {
|
|
2125
|
+
if (toolName === "write") {
|
|
2126
|
+
const filePath2 = String(args.filePath ?? "");
|
|
2127
|
+
if (!filePath2) {
|
|
2128
|
+
return { result: "", error: "write fallback: filePath is required" };
|
|
2129
|
+
}
|
|
2130
|
+
const safePath2 = validateSafePath(filePath2);
|
|
2131
|
+
const content2 = String(args.content ?? "");
|
|
2132
|
+
fs4.writeFileSync(safePath2, content2, "utf-8");
|
|
2133
|
+
return {
|
|
2134
|
+
result: "File written successfully.",
|
|
2135
|
+
title: filePath2,
|
|
2136
|
+
metadata: { output: "File written successfully." }
|
|
2137
|
+
};
|
|
2138
|
+
}
|
|
2139
|
+
const filePath = String(args.filePath ?? "");
|
|
2140
|
+
const oldString = String(args.oldString ?? "");
|
|
2141
|
+
const newString = String(args.newString ?? "");
|
|
2142
|
+
if (!filePath) {
|
|
2143
|
+
return { result: "", error: "edit fallback: filePath is required" };
|
|
2144
|
+
}
|
|
2145
|
+
if (!oldString && !newString) {
|
|
2146
|
+
return { result: "", error: "edit fallback: oldString and newString are both empty" };
|
|
2147
|
+
}
|
|
2148
|
+
const safePath = validateSafePath(filePath);
|
|
2149
|
+
let content;
|
|
2150
|
+
try {
|
|
2151
|
+
content = fs4.readFileSync(safePath, "utf-8");
|
|
2152
|
+
} catch {
|
|
2153
|
+
content = "";
|
|
2154
|
+
}
|
|
2155
|
+
if (oldString === "") {
|
|
2156
|
+
fs4.writeFileSync(safePath, newString, "utf-8");
|
|
2157
|
+
return {
|
|
2158
|
+
result: "Edit applied successfully.",
|
|
2159
|
+
title: filePath,
|
|
2160
|
+
metadata: { output: "Edit applied successfully." }
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
const idx = content.indexOf(oldString);
|
|
2164
|
+
if (idx === -1) {
|
|
2165
|
+
return { result: "", error: `edit fallback: could not find oldString in ${filePath}` };
|
|
2166
|
+
}
|
|
2167
|
+
const newContent = content.substring(0, idx) + newString + content.substring(idx + oldString.length);
|
|
2168
|
+
fs4.writeFileSync(safePath, newContent, "utf-8");
|
|
2169
|
+
return {
|
|
2170
|
+
result: "Edit applied successfully.",
|
|
2171
|
+
title: filePath,
|
|
2172
|
+
metadata: { output: "Edit applied successfully." }
|
|
2173
|
+
};
|
|
2174
|
+
} catch (e) {
|
|
2175
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
2176
|
+
return { result: "", error: sanitizeErrorMessage(msg) };
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2063
2179
|
|
|
2064
2180
|
// src/gitlab-workflow-token-client.ts
|
|
2065
2181
|
var TOKEN_CACHE_DURATION_MS = 25 * 60 * 1e3;
|
|
@@ -3150,6 +3266,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3150
3266
|
const preapprovedTools = this.workflowOptions.preapprovedTools ?? mcpTools.map((t) => t.name);
|
|
3151
3267
|
const additionalContext = this.buildAdditionalContext(options.prompt);
|
|
3152
3268
|
const toolExecutor = this.toolExecutor ?? null;
|
|
3269
|
+
const availableToolNames = new Set(options.tools?.map((t) => t.name) ?? []);
|
|
3153
3270
|
await this.tokenClient.getToken(
|
|
3154
3271
|
this.workflowOptions.workflowDefinition ?? DEFAULT_WORKFLOW_DEFINITION,
|
|
3155
3272
|
this.workflowOptions.rootNamespaceId
|
|
@@ -3210,7 +3327,8 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3210
3327
|
controller,
|
|
3211
3328
|
wsClient,
|
|
3212
3329
|
toolExecutor,
|
|
3213
|
-
() => `text-${textBlockCounter++}
|
|
3330
|
+
() => `text-${textBlockCounter++}`,
|
|
3331
|
+
availableToolNames
|
|
3214
3332
|
);
|
|
3215
3333
|
}
|
|
3216
3334
|
);
|
|
@@ -3291,7 +3409,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3291
3409
|
// ---------------------------------------------------------------------------
|
|
3292
3410
|
// Event handling
|
|
3293
3411
|
// ---------------------------------------------------------------------------
|
|
3294
|
-
handleWorkflowEvent(ss, event, controller, wsClient, toolExecutor, nextTextId) {
|
|
3412
|
+
handleWorkflowEvent(ss, event, controller, wsClient, toolExecutor, nextTextId, availableToolNames) {
|
|
3295
3413
|
if (ss.streamClosed) {
|
|
3296
3414
|
return;
|
|
3297
3415
|
}
|
|
@@ -3348,7 +3466,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3348
3466
|
break;
|
|
3349
3467
|
}
|
|
3350
3468
|
case "builtin-tool-request": {
|
|
3351
|
-
const mapped = mapBuiltinTool(event.toolName, event.data);
|
|
3469
|
+
const mapped = mapBuiltinTool(event.toolName, event.data, availableToolNames);
|
|
3352
3470
|
const mappedArgs = JSON.stringify(mapped.args);
|
|
3353
3471
|
if (ss.activeTextBlockId) {
|
|
3354
3472
|
controller.enqueue({ type: "text-end", id: ss.activeTextBlockId });
|
|
@@ -3548,37 +3666,19 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3548
3666
|
};
|
|
3549
3667
|
try {
|
|
3550
3668
|
if (toolExecutor) {
|
|
3551
|
-
|
|
3669
|
+
let result = await toolExecutor(toolName, argsJson, requestID);
|
|
3670
|
+
if (result.error && /^Unknown tool:/.test(result.error)) {
|
|
3671
|
+
const fallback = executeBuiltinFallback(toolName, argsJson);
|
|
3672
|
+
if (fallback) {
|
|
3673
|
+
result = fallback;
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3552
3676
|
wsClient.sendActionResponse(requestID, result.result, result.error);
|
|
3553
3677
|
ss.streamedInputChars += argsJson.length;
|
|
3554
3678
|
ss.streamedOutputChars += result.result.length;
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
try {
|
|
3559
|
-
const parsed = JSON.parse(result.result);
|
|
3560
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3561
|
-
if (typeof parsed.output === "string") {
|
|
3562
|
-
toolOutput = parsed.output;
|
|
3563
|
-
} else if (parsed.output != null) {
|
|
3564
|
-
toolOutput = JSON.stringify(parsed.output);
|
|
3565
|
-
}
|
|
3566
|
-
if (typeof parsed.title === "string") toolTitle = parsed.title;
|
|
3567
|
-
if (parsed.metadata && typeof parsed.metadata === "object") {
|
|
3568
|
-
toolMetadata = {};
|
|
3569
|
-
for (const [k, v] of Object.entries(parsed.metadata)) {
|
|
3570
|
-
toolMetadata[k] = typeof v === "string" ? v : JSON.stringify(v);
|
|
3571
|
-
}
|
|
3572
|
-
if (!("output" in toolMetadata)) {
|
|
3573
|
-
toolMetadata.output = toolOutput;
|
|
3574
|
-
}
|
|
3575
|
-
}
|
|
3576
|
-
} else if (Array.isArray(parsed)) {
|
|
3577
|
-
toolOutput = JSON.stringify(parsed);
|
|
3578
|
-
toolMetadata = { output: toolOutput };
|
|
3579
|
-
}
|
|
3580
|
-
} catch {
|
|
3581
|
-
}
|
|
3679
|
+
const toolOutput = result.result;
|
|
3680
|
+
const toolTitle = result.title ?? `${toolName} result`;
|
|
3681
|
+
const toolMetadata = result.metadata ?? { output: result.result };
|
|
3582
3682
|
if (result.error) {
|
|
3583
3683
|
let errorText;
|
|
3584
3684
|
if (typeof result.error === "string") {
|
|
@@ -3588,16 +3688,11 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3588
3688
|
} else {
|
|
3589
3689
|
errorText = String(result.error);
|
|
3590
3690
|
}
|
|
3591
|
-
const errorOutput = toolOutput || errorText;
|
|
3592
3691
|
safeEnqueue({
|
|
3593
3692
|
type: "tool-result",
|
|
3594
3693
|
toolCallId: requestID,
|
|
3595
3694
|
toolName,
|
|
3596
|
-
result:
|
|
3597
|
-
output: errorOutput,
|
|
3598
|
-
title: toolTitle,
|
|
3599
|
-
metadata: { ...toolMetadata, error: errorText }
|
|
3600
|
-
},
|
|
3695
|
+
result: errorText,
|
|
3601
3696
|
isError: true,
|
|
3602
3697
|
providerExecuted: true
|
|
3603
3698
|
});
|
|
@@ -3622,11 +3717,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3622
3717
|
type: "tool-result",
|
|
3623
3718
|
toolCallId: requestID,
|
|
3624
3719
|
toolName,
|
|
3625
|
-
result:
|
|
3626
|
-
output: errorMsg,
|
|
3627
|
-
title: `${toolName} error`,
|
|
3628
|
-
metadata: { output: errorMsg }
|
|
3629
|
-
},
|
|
3720
|
+
result: errorMsg,
|
|
3630
3721
|
isError: true,
|
|
3631
3722
|
providerExecuted: true
|
|
3632
3723
|
});
|
|
@@ -3639,11 +3730,7 @@ var GitLabWorkflowLanguageModel = class _GitLabWorkflowLanguageModel {
|
|
|
3639
3730
|
type: "tool-result",
|
|
3640
3731
|
toolCallId: requestID,
|
|
3641
3732
|
toolName,
|
|
3642
|
-
result:
|
|
3643
|
-
output: errorMsg,
|
|
3644
|
-
title: `${toolName} error`,
|
|
3645
|
-
metadata: { output: errorMsg }
|
|
3646
|
-
},
|
|
3733
|
+
result: errorMsg,
|
|
3647
3734
|
isError: true,
|
|
3648
3735
|
providerExecuted: true
|
|
3649
3736
|
});
|
|
@@ -4242,6 +4329,170 @@ function createGitLab(options = {}) {
|
|
|
4242
4329
|
return provider;
|
|
4243
4330
|
}
|
|
4244
4331
|
var gitlab = createGitLab();
|
|
4332
|
+
|
|
4333
|
+
// src/gitlab-model-config.ts
|
|
4334
|
+
var fs3 = __toESM(require("fs"));
|
|
4335
|
+
var path4 = __toESM(require("path"));
|
|
4336
|
+
var os3 = __toESM(require("os"));
|
|
4337
|
+
var DEFAULT_MODELS_YML_URL = "https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/-/raw/main/ai_gateway/model_selection/models.yml";
|
|
4338
|
+
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
4339
|
+
var DEFAULT_CONTEXT = 2e5;
|
|
4340
|
+
var DEFAULT_OUTPUT = 64e3;
|
|
4341
|
+
function getCacheFilePath2() {
|
|
4342
|
+
const cacheHome = process.env.XDG_CACHE_HOME || path4.join(os3.homedir(), ".cache");
|
|
4343
|
+
return path4.join(cacheHome, "opencode", "gitlab-model-configs.json");
|
|
4344
|
+
}
|
|
4345
|
+
function readCacheFile() {
|
|
4346
|
+
try {
|
|
4347
|
+
const filePath = getCacheFilePath2();
|
|
4348
|
+
if (!fs3.existsSync(filePath)) return null;
|
|
4349
|
+
const raw = fs3.readFileSync(filePath, "utf-8");
|
|
4350
|
+
return JSON.parse(raw);
|
|
4351
|
+
} catch {
|
|
4352
|
+
return null;
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
function writeCacheFile(configs) {
|
|
4356
|
+
try {
|
|
4357
|
+
const filePath = getCacheFilePath2();
|
|
4358
|
+
const dir = path4.dirname(filePath);
|
|
4359
|
+
fs3.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
4360
|
+
const data = {
|
|
4361
|
+
configs: Object.fromEntries(configs),
|
|
4362
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
4363
|
+
};
|
|
4364
|
+
fs3.writeFileSync(filePath, JSON.stringify(data, null, 2), { mode: 384 });
|
|
4365
|
+
} catch {
|
|
4366
|
+
}
|
|
4367
|
+
}
|
|
4368
|
+
function loadCacheFile(ttlMs) {
|
|
4369
|
+
const cached = readCacheFile();
|
|
4370
|
+
if (!cached) return null;
|
|
4371
|
+
const writtenAt = new Date(cached.updatedAt).getTime();
|
|
4372
|
+
const age = Date.now() - writtenAt;
|
|
4373
|
+
if (age > ttlMs) return null;
|
|
4374
|
+
return { configs: new Map(Object.entries(cached.configs)), writtenAt };
|
|
4375
|
+
}
|
|
4376
|
+
var GitLabModelConfigRegistry = class {
|
|
4377
|
+
url;
|
|
4378
|
+
ttlMs;
|
|
4379
|
+
fetchFn;
|
|
4380
|
+
memCache = null;
|
|
4381
|
+
memExpiresAt = 0;
|
|
4382
|
+
pending = null;
|
|
4383
|
+
constructor(options) {
|
|
4384
|
+
this.url = options?.url ?? DEFAULT_MODELS_YML_URL;
|
|
4385
|
+
this.ttlMs = options?.ttlMs ?? DEFAULT_TTL_MS;
|
|
4386
|
+
this.fetchFn = options?.fetch ?? fetch;
|
|
4387
|
+
}
|
|
4388
|
+
/**
|
|
4389
|
+
* Get model configs, fetching and caching as needed.
|
|
4390
|
+
* Returns a Map keyed by `gitlab_identifier` (the discovery `ref`).
|
|
4391
|
+
*/
|
|
4392
|
+
async getConfigs() {
|
|
4393
|
+
if (this.memCache && Date.now() < this.memExpiresAt) {
|
|
4394
|
+
return this.memCache;
|
|
4395
|
+
}
|
|
4396
|
+
const fileCached = loadCacheFile(this.ttlMs);
|
|
4397
|
+
if (fileCached) {
|
|
4398
|
+
this.memCache = fileCached.configs;
|
|
4399
|
+
this.memExpiresAt = fileCached.writtenAt + this.ttlMs;
|
|
4400
|
+
return fileCached.configs;
|
|
4401
|
+
}
|
|
4402
|
+
if (this.pending) return this.pending;
|
|
4403
|
+
this.pending = this.fetchConfigs();
|
|
4404
|
+
try {
|
|
4405
|
+
return await this.pending;
|
|
4406
|
+
} finally {
|
|
4407
|
+
this.pending = null;
|
|
4408
|
+
}
|
|
4409
|
+
}
|
|
4410
|
+
/**
|
|
4411
|
+
* Look up config for a single model ref.
|
|
4412
|
+
* Returns defaults if the ref is not found or fetch fails.
|
|
4413
|
+
*/
|
|
4414
|
+
async getConfig(ref) {
|
|
4415
|
+
const configs = await this.getConfigs();
|
|
4416
|
+
return configs.get(ref) ?? { context: DEFAULT_CONTEXT, output: DEFAULT_OUTPUT };
|
|
4417
|
+
}
|
|
4418
|
+
/** Invalidate both in-memory and file caches. */
|
|
4419
|
+
invalidateCache() {
|
|
4420
|
+
this.memCache = null;
|
|
4421
|
+
this.memExpiresAt = 0;
|
|
4422
|
+
try {
|
|
4423
|
+
const filePath = getCacheFilePath2();
|
|
4424
|
+
if (fs3.existsSync(filePath)) {
|
|
4425
|
+
fs3.unlinkSync(filePath);
|
|
4426
|
+
}
|
|
4427
|
+
} catch {
|
|
4428
|
+
}
|
|
4429
|
+
}
|
|
4430
|
+
async fetchConfigs() {
|
|
4431
|
+
try {
|
|
4432
|
+
const res = await this.fetchFn(this.url);
|
|
4433
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
4434
|
+
const text = await res.text();
|
|
4435
|
+
const configs = parseModelsYml(text);
|
|
4436
|
+
this.memCache = configs;
|
|
4437
|
+
this.memExpiresAt = Date.now() + this.ttlMs;
|
|
4438
|
+
writeCacheFile(configs);
|
|
4439
|
+
return configs;
|
|
4440
|
+
} catch {
|
|
4441
|
+
return this.memCache ?? loadCacheFile(Infinity)?.configs ?? /* @__PURE__ */ new Map();
|
|
4442
|
+
}
|
|
4443
|
+
}
|
|
4444
|
+
};
|
|
4445
|
+
function parseModelsYml(text) {
|
|
4446
|
+
const configs = /* @__PURE__ */ new Map();
|
|
4447
|
+
let currentIdentifier = null;
|
|
4448
|
+
let currentContext = 0;
|
|
4449
|
+
let currentOutput = 0;
|
|
4450
|
+
let inParams = false;
|
|
4451
|
+
let paramsIndent = -1;
|
|
4452
|
+
for (const line of text.split("\n")) {
|
|
4453
|
+
const idMatch = line.match(/^\s*gitlab_identifier:\s*"?([^"#\s]+)"?/);
|
|
4454
|
+
if (idMatch) {
|
|
4455
|
+
if (currentIdentifier) {
|
|
4456
|
+
configs.set(currentIdentifier, {
|
|
4457
|
+
context: currentContext || DEFAULT_CONTEXT,
|
|
4458
|
+
output: currentOutput || DEFAULT_OUTPUT
|
|
4459
|
+
});
|
|
4460
|
+
}
|
|
4461
|
+
currentIdentifier = idMatch[1];
|
|
4462
|
+
currentContext = 0;
|
|
4463
|
+
currentOutput = 0;
|
|
4464
|
+
inParams = false;
|
|
4465
|
+
paramsIndent = -1;
|
|
4466
|
+
}
|
|
4467
|
+
const ctxMatch = line.match(/^\s*max_context_tokens:\s*([0-9_]+)/);
|
|
4468
|
+
if (ctxMatch && currentIdentifier) {
|
|
4469
|
+
currentContext = parseInt(ctxMatch[1].replace(/_/g, ""), 10);
|
|
4470
|
+
}
|
|
4471
|
+
if (/^\s*params:\s*$/.test(line)) {
|
|
4472
|
+
inParams = true;
|
|
4473
|
+
paramsIndent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
4474
|
+
} else if (inParams && /^\s*\S+:/.test(line)) {
|
|
4475
|
+
const indent = line.match(/^(\s*)/)?.[1].length ?? 0;
|
|
4476
|
+
if (indent <= paramsIndent) {
|
|
4477
|
+
inParams = false;
|
|
4478
|
+
paramsIndent = -1;
|
|
4479
|
+
}
|
|
4480
|
+
}
|
|
4481
|
+
if (inParams) {
|
|
4482
|
+
const maxTokensMatch = line.match(/^\s*max_tokens:\s*([0-9_]+)/);
|
|
4483
|
+
if (maxTokensMatch && currentIdentifier) {
|
|
4484
|
+
currentOutput = parseInt(maxTokensMatch[1].replace(/_/g, ""), 10);
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
}
|
|
4488
|
+
if (currentIdentifier) {
|
|
4489
|
+
configs.set(currentIdentifier, {
|
|
4490
|
+
context: currentContext || DEFAULT_CONTEXT,
|
|
4491
|
+
output: currentOutput || DEFAULT_OUTPUT
|
|
4492
|
+
});
|
|
4493
|
+
}
|
|
4494
|
+
return configs;
|
|
4495
|
+
}
|
|
4245
4496
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4246
4497
|
0 && (module.exports = {
|
|
4247
4498
|
AGENT_PRIVILEGES,
|
|
@@ -4256,6 +4507,7 @@ var gitlab = createGitLab();
|
|
|
4256
4507
|
GitLabDirectAccessClient,
|
|
4257
4508
|
GitLabError,
|
|
4258
4509
|
GitLabModelCache,
|
|
4510
|
+
GitLabModelConfigRegistry,
|
|
4259
4511
|
GitLabModelDiscovery,
|
|
4260
4512
|
GitLabOAuthManager,
|
|
4261
4513
|
GitLabOpenAILanguageModel,
|
|
@@ -4284,6 +4536,7 @@ var gitlab = createGitLab();
|
|
|
4284
4536
|
getWorkflowModelRef,
|
|
4285
4537
|
gitlab,
|
|
4286
4538
|
isResponsesApiModel,
|
|
4287
|
-
isWorkflowModel
|
|
4539
|
+
isWorkflowModel,
|
|
4540
|
+
parseModelsYml
|
|
4288
4541
|
});
|
|
4289
4542
|
//# sourceMappingURL=index.js.map
|