gitlab-ai-provider 6.13.0 → 6.15.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/CHANGELOG.md +10 -0
- package/README.md +28 -1
- package/dist/gitlab-ai-provider-6.15.0.tgz +0 -0
- package/dist/index.d.mts +61 -1
- package/dist/index.d.ts +61 -1
- package/dist/index.js +256 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +256 -14
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/gitlab-ai-provider-6.13.0.tgz +0 -0
package/dist/index.mjs
CHANGED
|
@@ -891,7 +891,12 @@ ${message.content}` : message.content;
|
|
|
891
891
|
} else if (message.role === "assistant") {
|
|
892
892
|
const content = [];
|
|
893
893
|
for (const part of message.content) {
|
|
894
|
-
if (part.type === "
|
|
894
|
+
if (part.type === "reasoning") {
|
|
895
|
+
const thinkingBlock = this.convertReasoningPart(part);
|
|
896
|
+
if (thinkingBlock) {
|
|
897
|
+
content.push(thinkingBlock);
|
|
898
|
+
}
|
|
899
|
+
} else if (part.type === "text") {
|
|
895
900
|
content.push({ type: "text", text: part.text });
|
|
896
901
|
} else if (part.type === "tool-call") {
|
|
897
902
|
let toolInput = part.input;
|
|
@@ -1006,17 +1011,97 @@ ${message.content}` : message.content;
|
|
|
1006
1011
|
raw: params?.raw
|
|
1007
1012
|
};
|
|
1008
1013
|
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Translates the camelCase GitLab thinking config into the Anthropic Messages
|
|
1016
|
+
* request fields. `adaptive` is required by effort-based models such as Claude
|
|
1017
|
+
* Opus 4.8 and pairs `thinking: { type: 'adaptive' }` with a sibling
|
|
1018
|
+
* `output_config: { effort }`; `enabled`/`disabled` map through directly.
|
|
1019
|
+
*/
|
|
1020
|
+
buildThinkingParams(config) {
|
|
1021
|
+
if (!config) return {};
|
|
1022
|
+
if (config.type === "adaptive") {
|
|
1023
|
+
return {
|
|
1024
|
+
// Newer adaptive-only models (Claude Sonnet 5+, Opus 4.7+) default
|
|
1025
|
+
// `thinking.display` to `'omitted'`, which returns *empty* thinking
|
|
1026
|
+
// blocks — the model still reasons and effort still affects
|
|
1027
|
+
// behavior/token usage, but no visible chain-of-thought text comes
|
|
1028
|
+
// back. Older models already default to `'summarized'`, so it's
|
|
1029
|
+
// safe to always request it explicitly rather than gating on model
|
|
1030
|
+
// version.
|
|
1031
|
+
thinking: { type: "adaptive", display: "summarized" },
|
|
1032
|
+
output_config: { effort: config.effort }
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
if (config.type === "enabled") {
|
|
1036
|
+
return { thinking: { type: "enabled", budget_tokens: config.budgetTokens } };
|
|
1037
|
+
}
|
|
1038
|
+
return { thinking: { type: "disabled" } };
|
|
1039
|
+
}
|
|
1040
|
+
/** Per-call thinking configuration takes precedence over the model-level default. */
|
|
1041
|
+
resolveThinkingConfig(options) {
|
|
1042
|
+
const gitlabOptions = options.providerOptions?.["gitlab"];
|
|
1043
|
+
return gitlabOptions?.thinking ?? this.config.thinking;
|
|
1044
|
+
}
|
|
1045
|
+
validateThinkingConfig(config, maxTokens) {
|
|
1046
|
+
if (config?.type === "enabled" && config.budgetTokens >= maxTokens) {
|
|
1047
|
+
throw new GitLabError({
|
|
1048
|
+
message: `Anthropic thinking budgetTokens (${config.budgetTokens}) must be less than maxTokens (${maxTokens}).`,
|
|
1049
|
+
statusCode: 400
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Rebuild an Anthropic thinking block from a prior-turn reasoning part.
|
|
1055
|
+
* Anthropic requires thinking blocks to be replayed unmodified (with their
|
|
1056
|
+
* signature) during tool-use loops; the signature / redacted payload are
|
|
1057
|
+
* carried in the reasoning part's provider metadata under `gitlab`.
|
|
1058
|
+
*/
|
|
1059
|
+
convertReasoningPart(part) {
|
|
1060
|
+
const meta = part.providerOptions?.["gitlab"];
|
|
1061
|
+
const redactedData = meta?.["redactedData"];
|
|
1062
|
+
if (typeof redactedData === "string") {
|
|
1063
|
+
return { type: "redacted_thinking", data: redactedData };
|
|
1064
|
+
}
|
|
1065
|
+
const signature = meta?.["signature"];
|
|
1066
|
+
if (typeof signature !== "string") {
|
|
1067
|
+
return void 0;
|
|
1068
|
+
}
|
|
1069
|
+
return { type: "thinking", thinking: part.text, signature };
|
|
1070
|
+
}
|
|
1071
|
+
isThinkingActive(config) {
|
|
1072
|
+
return config?.type === "enabled" || config?.type === "adaptive";
|
|
1073
|
+
}
|
|
1074
|
+
/**
|
|
1075
|
+
* Anthropic rejects `temperature` changes while thinking is active and requires
|
|
1076
|
+
* `top_p` within [0.95, 1]; drop those params when thinking is engaged so the
|
|
1077
|
+
* gateway does not 400. Undefined values are omitted either way.
|
|
1078
|
+
*/
|
|
1079
|
+
buildSamplingParams(options, thinkingConfig) {
|
|
1080
|
+
const params = {};
|
|
1081
|
+
const thinkingActive = this.isThinkingActive(thinkingConfig);
|
|
1082
|
+
if (options.temperature != null && !thinkingActive) {
|
|
1083
|
+
params.temperature = options.temperature;
|
|
1084
|
+
}
|
|
1085
|
+
if (options.topP != null) {
|
|
1086
|
+
if (!thinkingActive || options.topP >= 0.95 && options.topP <= 1) {
|
|
1087
|
+
params.top_p = options.topP;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
return params;
|
|
1091
|
+
}
|
|
1009
1092
|
async doGenerate(options) {
|
|
1010
1093
|
return this.doGenerateWithRetry(options, false);
|
|
1011
1094
|
}
|
|
1012
1095
|
async doGenerateWithRetry(options, isRetry) {
|
|
1013
|
-
const client = await this.getAnthropicClient(isRetry);
|
|
1014
1096
|
const { system, messages } = this.convertPrompt(options.prompt);
|
|
1015
1097
|
const toolsDisabled = options.toolChoice?.type === "none";
|
|
1016
1098
|
const tools = toolsDisabled ? void 0 : this.convertTools(options.tools);
|
|
1017
1099
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
1018
1100
|
const anthropicModel = this.config.anthropicModel || "claude-sonnet-4-5-20250929";
|
|
1019
1101
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
1102
|
+
const thinkingConfig = this.resolveThinkingConfig(options);
|
|
1103
|
+
this.validateThinkingConfig(thinkingConfig, maxTokens);
|
|
1104
|
+
const client = await this.getAnthropicClient(isRetry);
|
|
1020
1105
|
const generateParams = {
|
|
1021
1106
|
model: anthropicModel,
|
|
1022
1107
|
max_tokens: maxTokens,
|
|
@@ -1024,15 +1109,27 @@ ${message.content}` : message.content;
|
|
|
1024
1109
|
messages,
|
|
1025
1110
|
tools,
|
|
1026
1111
|
tool_choice: tools ? toolChoice : void 0,
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1112
|
+
...this.buildSamplingParams(options, thinkingConfig),
|
|
1113
|
+
stop_sequences: options.stopSequences,
|
|
1114
|
+
...this.buildThinkingParams(thinkingConfig)
|
|
1030
1115
|
};
|
|
1031
1116
|
try {
|
|
1032
1117
|
const response = options.abortSignal ? await client.messages.create(generateParams, { signal: options.abortSignal }) : await client.messages.create(generateParams);
|
|
1033
1118
|
const content = [];
|
|
1034
1119
|
for (const block of response.content) {
|
|
1035
|
-
if (block.type === "
|
|
1120
|
+
if (block.type === "thinking") {
|
|
1121
|
+
content.push({
|
|
1122
|
+
type: "reasoning",
|
|
1123
|
+
text: block.thinking,
|
|
1124
|
+
providerMetadata: { gitlab: { signature: block.signature } }
|
|
1125
|
+
});
|
|
1126
|
+
} else if (block.type === "redacted_thinking") {
|
|
1127
|
+
content.push({
|
|
1128
|
+
type: "reasoning",
|
|
1129
|
+
text: "",
|
|
1130
|
+
providerMetadata: { gitlab: { redactedData: block.data } }
|
|
1131
|
+
});
|
|
1132
|
+
} else if (block.type === "text") {
|
|
1036
1133
|
content.push({
|
|
1037
1134
|
type: "text",
|
|
1038
1135
|
text: block.text
|
|
@@ -1086,13 +1183,15 @@ ${message.content}` : message.content;
|
|
|
1086
1183
|
return this.doStreamWithRetry(options, false);
|
|
1087
1184
|
}
|
|
1088
1185
|
async doStreamWithRetry(options, isRetry) {
|
|
1089
|
-
const client = await this.getAnthropicClient(isRetry);
|
|
1090
1186
|
const { system, messages } = this.convertPrompt(options.prompt);
|
|
1091
1187
|
const toolsDisabled = options.toolChoice?.type === "none";
|
|
1092
1188
|
const tools = toolsDisabled ? void 0 : this.convertTools(options.tools);
|
|
1093
1189
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
1094
1190
|
const anthropicModel = this.config.anthropicModel || "claude-sonnet-4-5-20250929";
|
|
1095
1191
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
1192
|
+
const thinkingConfig = this.resolveThinkingConfig(options);
|
|
1193
|
+
this.validateThinkingConfig(thinkingConfig, maxTokens);
|
|
1194
|
+
const client = await this.getAnthropicClient(isRetry);
|
|
1096
1195
|
const requestBody = {
|
|
1097
1196
|
model: anthropicModel,
|
|
1098
1197
|
max_tokens: maxTokens,
|
|
@@ -1100,9 +1199,9 @@ ${message.content}` : message.content;
|
|
|
1100
1199
|
messages,
|
|
1101
1200
|
tools,
|
|
1102
1201
|
tool_choice: tools ? toolChoice : void 0,
|
|
1103
|
-
|
|
1104
|
-
top_p: options.topP,
|
|
1202
|
+
...this.buildSamplingParams(options, thinkingConfig),
|
|
1105
1203
|
stop_sequences: options.stopSequences,
|
|
1204
|
+
...this.buildThinkingParams(thinkingConfig),
|
|
1106
1205
|
stream: true
|
|
1107
1206
|
};
|
|
1108
1207
|
const self = this;
|
|
@@ -1201,6 +1300,24 @@ ${message.content}` : message.content;
|
|
|
1201
1300
|
type: "text-start",
|
|
1202
1301
|
id: textId
|
|
1203
1302
|
});
|
|
1303
|
+
} else if (event.content_block.type === "thinking") {
|
|
1304
|
+
const reasoningId = `reasoning-${event.index}`;
|
|
1305
|
+
contentBlocks[event.index] = { type: "reasoning", id: reasoningId };
|
|
1306
|
+
safeEnqueue({
|
|
1307
|
+
type: "reasoning-start",
|
|
1308
|
+
id: reasoningId
|
|
1309
|
+
});
|
|
1310
|
+
} else if (event.content_block.type === "redacted_thinking") {
|
|
1311
|
+
const reasoningId = `reasoning-${event.index}`;
|
|
1312
|
+
contentBlocks[event.index] = {
|
|
1313
|
+
type: "reasoning",
|
|
1314
|
+
id: reasoningId,
|
|
1315
|
+
redactedData: event.content_block.data
|
|
1316
|
+
};
|
|
1317
|
+
safeEnqueue({
|
|
1318
|
+
type: "reasoning-start",
|
|
1319
|
+
id: reasoningId
|
|
1320
|
+
});
|
|
1204
1321
|
} else if (event.content_block.type === "tool_use") {
|
|
1205
1322
|
contentBlocks[event.index] = {
|
|
1206
1323
|
type: "tool-call",
|
|
@@ -1223,6 +1340,14 @@ ${message.content}` : message.content;
|
|
|
1223
1340
|
id: block.id,
|
|
1224
1341
|
delta: event.delta.text
|
|
1225
1342
|
});
|
|
1343
|
+
} else if (event.delta.type === "thinking_delta" && block?.type === "reasoning") {
|
|
1344
|
+
safeEnqueue({
|
|
1345
|
+
type: "reasoning-delta",
|
|
1346
|
+
id: block.id,
|
|
1347
|
+
delta: event.delta.thinking
|
|
1348
|
+
});
|
|
1349
|
+
} else if (event.delta.type === "signature_delta" && block?.type === "reasoning") {
|
|
1350
|
+
block.signature = event.delta.signature;
|
|
1226
1351
|
} else if (event.delta.type === "input_json_delta" && block?.type === "tool-call") {
|
|
1227
1352
|
block.input += event.delta.partial_json;
|
|
1228
1353
|
safeEnqueue({
|
|
@@ -1240,6 +1365,13 @@ ${message.content}` : message.content;
|
|
|
1240
1365
|
type: "text-end",
|
|
1241
1366
|
id: block.id
|
|
1242
1367
|
});
|
|
1368
|
+
} else if (block?.type === "reasoning") {
|
|
1369
|
+
const gitlabMeta = block.redactedData != null ? { redactedData: block.redactedData } : block.signature != null ? { signature: block.signature } : void 0;
|
|
1370
|
+
safeEnqueue({
|
|
1371
|
+
type: "reasoning-end",
|
|
1372
|
+
id: block.id,
|
|
1373
|
+
...gitlabMeta && { providerMetadata: { gitlab: gitlabMeta } }
|
|
1374
|
+
});
|
|
1243
1375
|
} else if (block?.type === "tool-call") {
|
|
1244
1376
|
safeEnqueue({
|
|
1245
1377
|
type: "tool-input-end",
|
|
@@ -1400,6 +1532,10 @@ var MODEL_MAPPINGS = {
|
|
|
1400
1532
|
"duo-chat-opus-4-5": { provider: "anthropic", model: "claude-opus-4-5-20251101" },
|
|
1401
1533
|
"duo-chat-sonnet-4-5": { provider: "anthropic", model: "claude-sonnet-4-5-20250929" },
|
|
1402
1534
|
"duo-chat-haiku-4-5": { provider: "anthropic", model: "claude-haiku-4-5-20251001" },
|
|
1535
|
+
// OpenAI models - Responses API
|
|
1536
|
+
// GPT-6 Astra rejects `reasoning_effort` with function tools on Chat Completions;
|
|
1537
|
+
// it must use the Responses API (matches OpenAI's own routing for GPT-5.x/GPT-6).
|
|
1538
|
+
"duo-chat-gpt-6-astra": { provider: "openai", model: "gpt-6-astra", openaiApiType: "responses" },
|
|
1403
1539
|
// OpenAI models - Chat Completions API
|
|
1404
1540
|
"duo-chat-gpt-5-1": { provider: "openai", model: "gpt-5.1-2025-11-13", openaiApiType: "chat" },
|
|
1405
1541
|
"duo-chat-gpt-5-2": { provider: "openai", model: "gpt-5.2-2025-12-11", openaiApiType: "chat" },
|
|
@@ -1592,6 +1728,17 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1592
1728
|
}
|
|
1593
1729
|
return parts.join(" | ");
|
|
1594
1730
|
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Per-call `providerOptions.gitlab.reasoningEffort` takes precedence over the
|
|
1733
|
+
* model-level default.
|
|
1734
|
+
*/
|
|
1735
|
+
resolveReasoningEffort(options) {
|
|
1736
|
+
const gitlabOptions = options.providerOptions?.["gitlab"];
|
|
1737
|
+
return gitlabOptions?.reasoningEffort ?? this.config.reasoningEffort;
|
|
1738
|
+
}
|
|
1739
|
+
asOpenAIReasoningEffort(effort) {
|
|
1740
|
+
return effort;
|
|
1741
|
+
}
|
|
1595
1742
|
convertTools(tools) {
|
|
1596
1743
|
if (!tools || tools.length === 0) {
|
|
1597
1744
|
return void 0;
|
|
@@ -1866,6 +2013,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1866
2013
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
1867
2014
|
const openaiModel = this.config.openaiModel || "gpt-4o";
|
|
1868
2015
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2016
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
1869
2017
|
const generateParams = {
|
|
1870
2018
|
model: openaiModel,
|
|
1871
2019
|
max_completion_tokens: maxTokens,
|
|
@@ -1874,7 +2022,10 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1874
2022
|
tool_choice: tools ? toolChoice : void 0,
|
|
1875
2023
|
temperature: options.temperature,
|
|
1876
2024
|
top_p: options.topP,
|
|
1877
|
-
stop: options.stopSequences
|
|
2025
|
+
stop: options.stopSequences,
|
|
2026
|
+
...reasoningEffort && {
|
|
2027
|
+
reasoning_effort: this.asOpenAIReasoningEffort(reasoningEffort)
|
|
2028
|
+
}
|
|
1878
2029
|
};
|
|
1879
2030
|
try {
|
|
1880
2031
|
const response = options.abortSignal ? await client.chat.completions.create(generateParams, { signal: options.abortSignal }) : await client.chat.completions.create(generateParams);
|
|
@@ -1937,6 +2088,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1937
2088
|
const instructions = this.extractSystemInstructions(options.prompt);
|
|
1938
2089
|
const openaiModel = this.config.openaiModel || "gpt-5-codex";
|
|
1939
2090
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2091
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
1940
2092
|
const generateParams = {
|
|
1941
2093
|
model: openaiModel,
|
|
1942
2094
|
input,
|
|
@@ -1945,7 +2097,18 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1945
2097
|
max_output_tokens: maxTokens,
|
|
1946
2098
|
temperature: options.temperature,
|
|
1947
2099
|
top_p: options.topP,
|
|
1948
|
-
store: false
|
|
2100
|
+
store: false,
|
|
2101
|
+
...reasoningEffort && {
|
|
2102
|
+
// `summary: 'auto'` opts into visible reasoning summary text.
|
|
2103
|
+
// Without it, the Responses API never returns summary content —
|
|
2104
|
+
// the model still reasons and effort still affects behavior, but
|
|
2105
|
+
// no chain-of-thought text comes back (mirrors the Anthropic
|
|
2106
|
+
// `thinking.display` gap fixed in buildThinkingParams).
|
|
2107
|
+
reasoning: {
|
|
2108
|
+
effort: this.asOpenAIReasoningEffort(reasoningEffort),
|
|
2109
|
+
summary: "auto"
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
1949
2112
|
};
|
|
1950
2113
|
try {
|
|
1951
2114
|
const response = options.abortSignal ? await client.responses.create(generateParams, { signal: options.abortSignal }) : await client.responses.create(generateParams);
|
|
@@ -1966,6 +2129,12 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1966
2129
|
toolName: item.name,
|
|
1967
2130
|
input: item.arguments
|
|
1968
2131
|
});
|
|
2132
|
+
} else if (item.type === "reasoning") {
|
|
2133
|
+
for (const summary of item.summary || []) {
|
|
2134
|
+
if (summary.type === "summary_text" && summary.text) {
|
|
2135
|
+
content.push({ type: "reasoning", text: summary.text });
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
1969
2138
|
}
|
|
1970
2139
|
}
|
|
1971
2140
|
const usage = this.createUsage({
|
|
@@ -2018,6 +2187,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2018
2187
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
2019
2188
|
const openaiModel = this.config.openaiModel || "gpt-4o";
|
|
2020
2189
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2190
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
2021
2191
|
const requestBody = {
|
|
2022
2192
|
model: openaiModel,
|
|
2023
2193
|
max_completion_tokens: maxTokens,
|
|
@@ -2027,6 +2197,9 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2027
2197
|
temperature: options.temperature,
|
|
2028
2198
|
top_p: options.topP,
|
|
2029
2199
|
stop: options.stopSequences,
|
|
2200
|
+
...reasoningEffort && {
|
|
2201
|
+
reasoning_effort: this.asOpenAIReasoningEffort(reasoningEffort)
|
|
2202
|
+
},
|
|
2030
2203
|
stream: true,
|
|
2031
2204
|
stream_options: { include_usage: true }
|
|
2032
2205
|
};
|
|
@@ -2234,6 +2407,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2234
2407
|
const instructions = this.extractSystemInstructions(options.prompt);
|
|
2235
2408
|
const openaiModel = this.config.openaiModel || "gpt-5-codex";
|
|
2236
2409
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2410
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
2237
2411
|
const requestBody = {
|
|
2238
2412
|
model: openaiModel,
|
|
2239
2413
|
input,
|
|
@@ -2243,6 +2417,17 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2243
2417
|
temperature: options.temperature,
|
|
2244
2418
|
top_p: options.topP,
|
|
2245
2419
|
store: false,
|
|
2420
|
+
...reasoningEffort && {
|
|
2421
|
+
// `summary: 'auto'` opts into visible reasoning summary text.
|
|
2422
|
+
// Without it, the Responses API never returns summary content —
|
|
2423
|
+
// the model still reasons and effort still affects behavior, but
|
|
2424
|
+
// no chain-of-thought text comes back (mirrors the Anthropic
|
|
2425
|
+
// `thinking.display` gap fixed in buildThinkingParams).
|
|
2426
|
+
reasoning: {
|
|
2427
|
+
effort: this.asOpenAIReasoningEffort(reasoningEffort),
|
|
2428
|
+
summary: "auto"
|
|
2429
|
+
}
|
|
2430
|
+
},
|
|
2246
2431
|
stream: true
|
|
2247
2432
|
};
|
|
2248
2433
|
const self = this;
|
|
@@ -2281,11 +2466,38 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2281
2466
|
}
|
|
2282
2467
|
};
|
|
2283
2468
|
const toolCalls = {};
|
|
2469
|
+
const activeReasoning = /* @__PURE__ */ new Set();
|
|
2470
|
+
const knownReasoning = /* @__PURE__ */ new Set();
|
|
2471
|
+
const reasoningWithText = /* @__PURE__ */ new Set();
|
|
2284
2472
|
let usage = self.createUsage();
|
|
2285
2473
|
let finishReason = { unified: "other", raw: void 0 };
|
|
2286
2474
|
let textStarted = false;
|
|
2287
2475
|
let contentEmitted = false;
|
|
2288
2476
|
const textId = "text-0";
|
|
2477
|
+
const reasoningId = (outputIndex, summaryIndex) => `reasoning-${outputIndex}-${summaryIndex}`;
|
|
2478
|
+
const startReasoning = (outputIndex, summaryIndex) => {
|
|
2479
|
+
const id = reasoningId(outputIndex, summaryIndex);
|
|
2480
|
+
if (!knownReasoning.has(id)) {
|
|
2481
|
+
knownReasoning.add(id);
|
|
2482
|
+
activeReasoning.add(id);
|
|
2483
|
+
contentEmitted = true;
|
|
2484
|
+
safeEnqueue({ type: "reasoning-start", id });
|
|
2485
|
+
}
|
|
2486
|
+
return id;
|
|
2487
|
+
};
|
|
2488
|
+
const emitReasoningDelta = (outputIndex, summaryIndex, delta) => {
|
|
2489
|
+
const id = startReasoning(outputIndex, summaryIndex);
|
|
2490
|
+
if (activeReasoning.has(id) && delta) {
|
|
2491
|
+
reasoningWithText.add(id);
|
|
2492
|
+
safeEnqueue({ type: "reasoning-delta", id, delta });
|
|
2493
|
+
}
|
|
2494
|
+
};
|
|
2495
|
+
const endReasoning = (outputIndex, summaryIndex) => {
|
|
2496
|
+
const id = reasoningId(outputIndex, summaryIndex);
|
|
2497
|
+
if (activeReasoning.delete(id)) {
|
|
2498
|
+
safeEnqueue({ type: "reasoning-end", id });
|
|
2499
|
+
}
|
|
2500
|
+
};
|
|
2289
2501
|
try {
|
|
2290
2502
|
const openaiStream = await client.responses.create(
|
|
2291
2503
|
{
|
|
@@ -2318,6 +2530,30 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2318
2530
|
toolName: event.item.name
|
|
2319
2531
|
});
|
|
2320
2532
|
}
|
|
2533
|
+
} else if (event.type === "response.reasoning_summary_part.added") {
|
|
2534
|
+
startReasoning(event.output_index, event.summary_index);
|
|
2535
|
+
} else if (event.type === "response.reasoning_summary_text.delta") {
|
|
2536
|
+
emitReasoningDelta(event.output_index, event.summary_index, event.delta);
|
|
2537
|
+
} else if (event.type === "response.reasoning_summary_text.done") {
|
|
2538
|
+
const id = startReasoning(event.output_index, event.summary_index);
|
|
2539
|
+
if (!reasoningWithText.has(id)) {
|
|
2540
|
+
emitReasoningDelta(event.output_index, event.summary_index, event.text);
|
|
2541
|
+
}
|
|
2542
|
+
endReasoning(event.output_index, event.summary_index);
|
|
2543
|
+
} else if (event.type === "response.reasoning_summary_part.done") {
|
|
2544
|
+
const id = startReasoning(event.output_index, event.summary_index);
|
|
2545
|
+
if (!reasoningWithText.has(id)) {
|
|
2546
|
+
emitReasoningDelta(event.output_index, event.summary_index, event.part.text);
|
|
2547
|
+
}
|
|
2548
|
+
endReasoning(event.output_index, event.summary_index);
|
|
2549
|
+
} else if (event.type === "response.output_item.done" && event.item.type === "reasoning") {
|
|
2550
|
+
const prefix = `reasoning-${event.output_index}-`;
|
|
2551
|
+
for (const id of [...activeReasoning]) {
|
|
2552
|
+
if (id.startsWith(prefix)) {
|
|
2553
|
+
activeReasoning.delete(id);
|
|
2554
|
+
safeEnqueue({ type: "reasoning-end", id });
|
|
2555
|
+
}
|
|
2556
|
+
}
|
|
2321
2557
|
} else if (event.type === "response.output_text.delta") {
|
|
2322
2558
|
contentEmitted = true;
|
|
2323
2559
|
if (!textStarted) {
|
|
@@ -2360,6 +2596,10 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2360
2596
|
}
|
|
2361
2597
|
}
|
|
2362
2598
|
}
|
|
2599
|
+
for (const id of activeReasoning) {
|
|
2600
|
+
safeEnqueue({ type: "reasoning-end", id });
|
|
2601
|
+
}
|
|
2602
|
+
activeReasoning.clear();
|
|
2363
2603
|
if (textStarted) {
|
|
2364
2604
|
safeEnqueue({ type: "text-end", id: textId });
|
|
2365
2605
|
}
|
|
@@ -2452,7 +2692,7 @@ import { AsyncResource } from "async_hooks";
|
|
|
2452
2692
|
import WebSocket from "isomorphic-ws";
|
|
2453
2693
|
|
|
2454
2694
|
// src/version.ts
|
|
2455
|
-
var VERSION = true ? "6.
|
|
2695
|
+
var VERSION = true ? "6.14.0" : "0.0.0-dev";
|
|
2456
2696
|
|
|
2457
2697
|
// src/gitlab-workflow-client.ts
|
|
2458
2698
|
var WS_CONNECT_TIMEOUT_MS = 3e4;
|
|
@@ -5299,12 +5539,14 @@ function createGitLab(options = {}) {
|
|
|
5299
5539
|
if (mapping.provider === "openai") {
|
|
5300
5540
|
return new GitLabOpenAILanguageModel(modelId, {
|
|
5301
5541
|
...baseConfig,
|
|
5302
|
-
openaiModel: agenticOptions?.providerModel ?? mapping.model
|
|
5542
|
+
openaiModel: agenticOptions?.providerModel ?? mapping.model,
|
|
5543
|
+
reasoningEffort: agenticOptions?.reasoningEffort
|
|
5303
5544
|
});
|
|
5304
5545
|
}
|
|
5305
5546
|
return new GitLabAnthropicLanguageModel(modelId, {
|
|
5306
5547
|
...baseConfig,
|
|
5307
|
-
anthropicModel: agenticOptions?.providerModel ?? mapping.model
|
|
5548
|
+
anthropicModel: agenticOptions?.providerModel ?? mapping.model,
|
|
5549
|
+
thinking: agenticOptions?.thinking
|
|
5308
5550
|
});
|
|
5309
5551
|
};
|
|
5310
5552
|
const createWorkflowChatModel = (modelId, workflowOptions) => {
|