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.js
CHANGED
|
@@ -970,7 +970,12 @@ ${message.content}` : message.content;
|
|
|
970
970
|
} else if (message.role === "assistant") {
|
|
971
971
|
const content = [];
|
|
972
972
|
for (const part of message.content) {
|
|
973
|
-
if (part.type === "
|
|
973
|
+
if (part.type === "reasoning") {
|
|
974
|
+
const thinkingBlock = this.convertReasoningPart(part);
|
|
975
|
+
if (thinkingBlock) {
|
|
976
|
+
content.push(thinkingBlock);
|
|
977
|
+
}
|
|
978
|
+
} else if (part.type === "text") {
|
|
974
979
|
content.push({ type: "text", text: part.text });
|
|
975
980
|
} else if (part.type === "tool-call") {
|
|
976
981
|
let toolInput = part.input;
|
|
@@ -1085,17 +1090,97 @@ ${message.content}` : message.content;
|
|
|
1085
1090
|
raw: params?.raw
|
|
1086
1091
|
};
|
|
1087
1092
|
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Translates the camelCase GitLab thinking config into the Anthropic Messages
|
|
1095
|
+
* request fields. `adaptive` is required by effort-based models such as Claude
|
|
1096
|
+
* Opus 4.8 and pairs `thinking: { type: 'adaptive' }` with a sibling
|
|
1097
|
+
* `output_config: { effort }`; `enabled`/`disabled` map through directly.
|
|
1098
|
+
*/
|
|
1099
|
+
buildThinkingParams(config) {
|
|
1100
|
+
if (!config) return {};
|
|
1101
|
+
if (config.type === "adaptive") {
|
|
1102
|
+
return {
|
|
1103
|
+
// Newer adaptive-only models (Claude Sonnet 5+, Opus 4.7+) default
|
|
1104
|
+
// `thinking.display` to `'omitted'`, which returns *empty* thinking
|
|
1105
|
+
// blocks — the model still reasons and effort still affects
|
|
1106
|
+
// behavior/token usage, but no visible chain-of-thought text comes
|
|
1107
|
+
// back. Older models already default to `'summarized'`, so it's
|
|
1108
|
+
// safe to always request it explicitly rather than gating on model
|
|
1109
|
+
// version.
|
|
1110
|
+
thinking: { type: "adaptive", display: "summarized" },
|
|
1111
|
+
output_config: { effort: config.effort }
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
if (config.type === "enabled") {
|
|
1115
|
+
return { thinking: { type: "enabled", budget_tokens: config.budgetTokens } };
|
|
1116
|
+
}
|
|
1117
|
+
return { thinking: { type: "disabled" } };
|
|
1118
|
+
}
|
|
1119
|
+
/** Per-call thinking configuration takes precedence over the model-level default. */
|
|
1120
|
+
resolveThinkingConfig(options) {
|
|
1121
|
+
const gitlabOptions = options.providerOptions?.["gitlab"];
|
|
1122
|
+
return gitlabOptions?.thinking ?? this.config.thinking;
|
|
1123
|
+
}
|
|
1124
|
+
validateThinkingConfig(config, maxTokens) {
|
|
1125
|
+
if (config?.type === "enabled" && config.budgetTokens >= maxTokens) {
|
|
1126
|
+
throw new GitLabError({
|
|
1127
|
+
message: `Anthropic thinking budgetTokens (${config.budgetTokens}) must be less than maxTokens (${maxTokens}).`,
|
|
1128
|
+
statusCode: 400
|
|
1129
|
+
});
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* Rebuild an Anthropic thinking block from a prior-turn reasoning part.
|
|
1134
|
+
* Anthropic requires thinking blocks to be replayed unmodified (with their
|
|
1135
|
+
* signature) during tool-use loops; the signature / redacted payload are
|
|
1136
|
+
* carried in the reasoning part's provider metadata under `gitlab`.
|
|
1137
|
+
*/
|
|
1138
|
+
convertReasoningPart(part) {
|
|
1139
|
+
const meta = part.providerOptions?.["gitlab"];
|
|
1140
|
+
const redactedData = meta?.["redactedData"];
|
|
1141
|
+
if (typeof redactedData === "string") {
|
|
1142
|
+
return { type: "redacted_thinking", data: redactedData };
|
|
1143
|
+
}
|
|
1144
|
+
const signature = meta?.["signature"];
|
|
1145
|
+
if (typeof signature !== "string") {
|
|
1146
|
+
return void 0;
|
|
1147
|
+
}
|
|
1148
|
+
return { type: "thinking", thinking: part.text, signature };
|
|
1149
|
+
}
|
|
1150
|
+
isThinkingActive(config) {
|
|
1151
|
+
return config?.type === "enabled" || config?.type === "adaptive";
|
|
1152
|
+
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Anthropic rejects `temperature` changes while thinking is active and requires
|
|
1155
|
+
* `top_p` within [0.95, 1]; drop those params when thinking is engaged so the
|
|
1156
|
+
* gateway does not 400. Undefined values are omitted either way.
|
|
1157
|
+
*/
|
|
1158
|
+
buildSamplingParams(options, thinkingConfig) {
|
|
1159
|
+
const params = {};
|
|
1160
|
+
const thinkingActive = this.isThinkingActive(thinkingConfig);
|
|
1161
|
+
if (options.temperature != null && !thinkingActive) {
|
|
1162
|
+
params.temperature = options.temperature;
|
|
1163
|
+
}
|
|
1164
|
+
if (options.topP != null) {
|
|
1165
|
+
if (!thinkingActive || options.topP >= 0.95 && options.topP <= 1) {
|
|
1166
|
+
params.top_p = options.topP;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
return params;
|
|
1170
|
+
}
|
|
1088
1171
|
async doGenerate(options) {
|
|
1089
1172
|
return this.doGenerateWithRetry(options, false);
|
|
1090
1173
|
}
|
|
1091
1174
|
async doGenerateWithRetry(options, isRetry) {
|
|
1092
|
-
const client = await this.getAnthropicClient(isRetry);
|
|
1093
1175
|
const { system, messages } = this.convertPrompt(options.prompt);
|
|
1094
1176
|
const toolsDisabled = options.toolChoice?.type === "none";
|
|
1095
1177
|
const tools = toolsDisabled ? void 0 : this.convertTools(options.tools);
|
|
1096
1178
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
1097
1179
|
const anthropicModel = this.config.anthropicModel || "claude-sonnet-4-5-20250929";
|
|
1098
1180
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
1181
|
+
const thinkingConfig = this.resolveThinkingConfig(options);
|
|
1182
|
+
this.validateThinkingConfig(thinkingConfig, maxTokens);
|
|
1183
|
+
const client = await this.getAnthropicClient(isRetry);
|
|
1099
1184
|
const generateParams = {
|
|
1100
1185
|
model: anthropicModel,
|
|
1101
1186
|
max_tokens: maxTokens,
|
|
@@ -1103,15 +1188,27 @@ ${message.content}` : message.content;
|
|
|
1103
1188
|
messages,
|
|
1104
1189
|
tools,
|
|
1105
1190
|
tool_choice: tools ? toolChoice : void 0,
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1191
|
+
...this.buildSamplingParams(options, thinkingConfig),
|
|
1192
|
+
stop_sequences: options.stopSequences,
|
|
1193
|
+
...this.buildThinkingParams(thinkingConfig)
|
|
1109
1194
|
};
|
|
1110
1195
|
try {
|
|
1111
1196
|
const response = options.abortSignal ? await client.messages.create(generateParams, { signal: options.abortSignal }) : await client.messages.create(generateParams);
|
|
1112
1197
|
const content = [];
|
|
1113
1198
|
for (const block of response.content) {
|
|
1114
|
-
if (block.type === "
|
|
1199
|
+
if (block.type === "thinking") {
|
|
1200
|
+
content.push({
|
|
1201
|
+
type: "reasoning",
|
|
1202
|
+
text: block.thinking,
|
|
1203
|
+
providerMetadata: { gitlab: { signature: block.signature } }
|
|
1204
|
+
});
|
|
1205
|
+
} else if (block.type === "redacted_thinking") {
|
|
1206
|
+
content.push({
|
|
1207
|
+
type: "reasoning",
|
|
1208
|
+
text: "",
|
|
1209
|
+
providerMetadata: { gitlab: { redactedData: block.data } }
|
|
1210
|
+
});
|
|
1211
|
+
} else if (block.type === "text") {
|
|
1115
1212
|
content.push({
|
|
1116
1213
|
type: "text",
|
|
1117
1214
|
text: block.text
|
|
@@ -1165,13 +1262,15 @@ ${message.content}` : message.content;
|
|
|
1165
1262
|
return this.doStreamWithRetry(options, false);
|
|
1166
1263
|
}
|
|
1167
1264
|
async doStreamWithRetry(options, isRetry) {
|
|
1168
|
-
const client = await this.getAnthropicClient(isRetry);
|
|
1169
1265
|
const { system, messages } = this.convertPrompt(options.prompt);
|
|
1170
1266
|
const toolsDisabled = options.toolChoice?.type === "none";
|
|
1171
1267
|
const tools = toolsDisabled ? void 0 : this.convertTools(options.tools);
|
|
1172
1268
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
1173
1269
|
const anthropicModel = this.config.anthropicModel || "claude-sonnet-4-5-20250929";
|
|
1174
1270
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
1271
|
+
const thinkingConfig = this.resolveThinkingConfig(options);
|
|
1272
|
+
this.validateThinkingConfig(thinkingConfig, maxTokens);
|
|
1273
|
+
const client = await this.getAnthropicClient(isRetry);
|
|
1175
1274
|
const requestBody = {
|
|
1176
1275
|
model: anthropicModel,
|
|
1177
1276
|
max_tokens: maxTokens,
|
|
@@ -1179,9 +1278,9 @@ ${message.content}` : message.content;
|
|
|
1179
1278
|
messages,
|
|
1180
1279
|
tools,
|
|
1181
1280
|
tool_choice: tools ? toolChoice : void 0,
|
|
1182
|
-
|
|
1183
|
-
top_p: options.topP,
|
|
1281
|
+
...this.buildSamplingParams(options, thinkingConfig),
|
|
1184
1282
|
stop_sequences: options.stopSequences,
|
|
1283
|
+
...this.buildThinkingParams(thinkingConfig),
|
|
1185
1284
|
stream: true
|
|
1186
1285
|
};
|
|
1187
1286
|
const self = this;
|
|
@@ -1280,6 +1379,24 @@ ${message.content}` : message.content;
|
|
|
1280
1379
|
type: "text-start",
|
|
1281
1380
|
id: textId
|
|
1282
1381
|
});
|
|
1382
|
+
} else if (event.content_block.type === "thinking") {
|
|
1383
|
+
const reasoningId = `reasoning-${event.index}`;
|
|
1384
|
+
contentBlocks[event.index] = { type: "reasoning", id: reasoningId };
|
|
1385
|
+
safeEnqueue({
|
|
1386
|
+
type: "reasoning-start",
|
|
1387
|
+
id: reasoningId
|
|
1388
|
+
});
|
|
1389
|
+
} else if (event.content_block.type === "redacted_thinking") {
|
|
1390
|
+
const reasoningId = `reasoning-${event.index}`;
|
|
1391
|
+
contentBlocks[event.index] = {
|
|
1392
|
+
type: "reasoning",
|
|
1393
|
+
id: reasoningId,
|
|
1394
|
+
redactedData: event.content_block.data
|
|
1395
|
+
};
|
|
1396
|
+
safeEnqueue({
|
|
1397
|
+
type: "reasoning-start",
|
|
1398
|
+
id: reasoningId
|
|
1399
|
+
});
|
|
1283
1400
|
} else if (event.content_block.type === "tool_use") {
|
|
1284
1401
|
contentBlocks[event.index] = {
|
|
1285
1402
|
type: "tool-call",
|
|
@@ -1302,6 +1419,14 @@ ${message.content}` : message.content;
|
|
|
1302
1419
|
id: block.id,
|
|
1303
1420
|
delta: event.delta.text
|
|
1304
1421
|
});
|
|
1422
|
+
} else if (event.delta.type === "thinking_delta" && block?.type === "reasoning") {
|
|
1423
|
+
safeEnqueue({
|
|
1424
|
+
type: "reasoning-delta",
|
|
1425
|
+
id: block.id,
|
|
1426
|
+
delta: event.delta.thinking
|
|
1427
|
+
});
|
|
1428
|
+
} else if (event.delta.type === "signature_delta" && block?.type === "reasoning") {
|
|
1429
|
+
block.signature = event.delta.signature;
|
|
1305
1430
|
} else if (event.delta.type === "input_json_delta" && block?.type === "tool-call") {
|
|
1306
1431
|
block.input += event.delta.partial_json;
|
|
1307
1432
|
safeEnqueue({
|
|
@@ -1319,6 +1444,13 @@ ${message.content}` : message.content;
|
|
|
1319
1444
|
type: "text-end",
|
|
1320
1445
|
id: block.id
|
|
1321
1446
|
});
|
|
1447
|
+
} else if (block?.type === "reasoning") {
|
|
1448
|
+
const gitlabMeta = block.redactedData != null ? { redactedData: block.redactedData } : block.signature != null ? { signature: block.signature } : void 0;
|
|
1449
|
+
safeEnqueue({
|
|
1450
|
+
type: "reasoning-end",
|
|
1451
|
+
id: block.id,
|
|
1452
|
+
...gitlabMeta && { providerMetadata: { gitlab: gitlabMeta } }
|
|
1453
|
+
});
|
|
1322
1454
|
} else if (block?.type === "tool-call") {
|
|
1323
1455
|
safeEnqueue({
|
|
1324
1456
|
type: "tool-input-end",
|
|
@@ -1479,6 +1611,10 @@ var MODEL_MAPPINGS = {
|
|
|
1479
1611
|
"duo-chat-opus-4-5": { provider: "anthropic", model: "claude-opus-4-5-20251101" },
|
|
1480
1612
|
"duo-chat-sonnet-4-5": { provider: "anthropic", model: "claude-sonnet-4-5-20250929" },
|
|
1481
1613
|
"duo-chat-haiku-4-5": { provider: "anthropic", model: "claude-haiku-4-5-20251001" },
|
|
1614
|
+
// OpenAI models - Responses API
|
|
1615
|
+
// GPT-6 Astra rejects `reasoning_effort` with function tools on Chat Completions;
|
|
1616
|
+
// it must use the Responses API (matches OpenAI's own routing for GPT-5.x/GPT-6).
|
|
1617
|
+
"duo-chat-gpt-6-astra": { provider: "openai", model: "gpt-6-astra", openaiApiType: "responses" },
|
|
1482
1618
|
// OpenAI models - Chat Completions API
|
|
1483
1619
|
"duo-chat-gpt-5-1": { provider: "openai", model: "gpt-5.1-2025-11-13", openaiApiType: "chat" },
|
|
1484
1620
|
"duo-chat-gpt-5-2": { provider: "openai", model: "gpt-5.2-2025-12-11", openaiApiType: "chat" },
|
|
@@ -1671,6 +1807,17 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1671
1807
|
}
|
|
1672
1808
|
return parts.join(" | ");
|
|
1673
1809
|
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Per-call `providerOptions.gitlab.reasoningEffort` takes precedence over the
|
|
1812
|
+
* model-level default.
|
|
1813
|
+
*/
|
|
1814
|
+
resolveReasoningEffort(options) {
|
|
1815
|
+
const gitlabOptions = options.providerOptions?.["gitlab"];
|
|
1816
|
+
return gitlabOptions?.reasoningEffort ?? this.config.reasoningEffort;
|
|
1817
|
+
}
|
|
1818
|
+
asOpenAIReasoningEffort(effort) {
|
|
1819
|
+
return effort;
|
|
1820
|
+
}
|
|
1674
1821
|
convertTools(tools) {
|
|
1675
1822
|
if (!tools || tools.length === 0) {
|
|
1676
1823
|
return void 0;
|
|
@@ -1945,6 +2092,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1945
2092
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
1946
2093
|
const openaiModel = this.config.openaiModel || "gpt-4o";
|
|
1947
2094
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2095
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
1948
2096
|
const generateParams = {
|
|
1949
2097
|
model: openaiModel,
|
|
1950
2098
|
max_completion_tokens: maxTokens,
|
|
@@ -1953,7 +2101,10 @@ var GitLabOpenAILanguageModel = class {
|
|
|
1953
2101
|
tool_choice: tools ? toolChoice : void 0,
|
|
1954
2102
|
temperature: options.temperature,
|
|
1955
2103
|
top_p: options.topP,
|
|
1956
|
-
stop: options.stopSequences
|
|
2104
|
+
stop: options.stopSequences,
|
|
2105
|
+
...reasoningEffort && {
|
|
2106
|
+
reasoning_effort: this.asOpenAIReasoningEffort(reasoningEffort)
|
|
2107
|
+
}
|
|
1957
2108
|
};
|
|
1958
2109
|
try {
|
|
1959
2110
|
const response = options.abortSignal ? await client.chat.completions.create(generateParams, { signal: options.abortSignal }) : await client.chat.completions.create(generateParams);
|
|
@@ -2016,6 +2167,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2016
2167
|
const instructions = this.extractSystemInstructions(options.prompt);
|
|
2017
2168
|
const openaiModel = this.config.openaiModel || "gpt-5-codex";
|
|
2018
2169
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2170
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
2019
2171
|
const generateParams = {
|
|
2020
2172
|
model: openaiModel,
|
|
2021
2173
|
input,
|
|
@@ -2024,7 +2176,18 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2024
2176
|
max_output_tokens: maxTokens,
|
|
2025
2177
|
temperature: options.temperature,
|
|
2026
2178
|
top_p: options.topP,
|
|
2027
|
-
store: false
|
|
2179
|
+
store: false,
|
|
2180
|
+
...reasoningEffort && {
|
|
2181
|
+
// `summary: 'auto'` opts into visible reasoning summary text.
|
|
2182
|
+
// Without it, the Responses API never returns summary content —
|
|
2183
|
+
// the model still reasons and effort still affects behavior, but
|
|
2184
|
+
// no chain-of-thought text comes back (mirrors the Anthropic
|
|
2185
|
+
// `thinking.display` gap fixed in buildThinkingParams).
|
|
2186
|
+
reasoning: {
|
|
2187
|
+
effort: this.asOpenAIReasoningEffort(reasoningEffort),
|
|
2188
|
+
summary: "auto"
|
|
2189
|
+
}
|
|
2190
|
+
}
|
|
2028
2191
|
};
|
|
2029
2192
|
try {
|
|
2030
2193
|
const response = options.abortSignal ? await client.responses.create(generateParams, { signal: options.abortSignal }) : await client.responses.create(generateParams);
|
|
@@ -2045,6 +2208,12 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2045
2208
|
toolName: item.name,
|
|
2046
2209
|
input: item.arguments
|
|
2047
2210
|
});
|
|
2211
|
+
} else if (item.type === "reasoning") {
|
|
2212
|
+
for (const summary of item.summary || []) {
|
|
2213
|
+
if (summary.type === "summary_text" && summary.text) {
|
|
2214
|
+
content.push({ type: "reasoning", text: summary.text });
|
|
2215
|
+
}
|
|
2216
|
+
}
|
|
2048
2217
|
}
|
|
2049
2218
|
}
|
|
2050
2219
|
const usage = this.createUsage({
|
|
@@ -2097,6 +2266,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2097
2266
|
const toolChoice = toolsDisabled ? void 0 : this.convertToolChoice(options.toolChoice);
|
|
2098
2267
|
const openaiModel = this.config.openaiModel || "gpt-4o";
|
|
2099
2268
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2269
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
2100
2270
|
const requestBody = {
|
|
2101
2271
|
model: openaiModel,
|
|
2102
2272
|
max_completion_tokens: maxTokens,
|
|
@@ -2106,6 +2276,9 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2106
2276
|
temperature: options.temperature,
|
|
2107
2277
|
top_p: options.topP,
|
|
2108
2278
|
stop: options.stopSequences,
|
|
2279
|
+
...reasoningEffort && {
|
|
2280
|
+
reasoning_effort: this.asOpenAIReasoningEffort(reasoningEffort)
|
|
2281
|
+
},
|
|
2109
2282
|
stream: true,
|
|
2110
2283
|
stream_options: { include_usage: true }
|
|
2111
2284
|
};
|
|
@@ -2313,6 +2486,7 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2313
2486
|
const instructions = this.extractSystemInstructions(options.prompt);
|
|
2314
2487
|
const openaiModel = this.config.openaiModel || "gpt-5-codex";
|
|
2315
2488
|
const maxTokens = options.maxOutputTokens || this.config.maxTokens || 8192;
|
|
2489
|
+
const reasoningEffort = this.resolveReasoningEffort(options);
|
|
2316
2490
|
const requestBody = {
|
|
2317
2491
|
model: openaiModel,
|
|
2318
2492
|
input,
|
|
@@ -2322,6 +2496,17 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2322
2496
|
temperature: options.temperature,
|
|
2323
2497
|
top_p: options.topP,
|
|
2324
2498
|
store: false,
|
|
2499
|
+
...reasoningEffort && {
|
|
2500
|
+
// `summary: 'auto'` opts into visible reasoning summary text.
|
|
2501
|
+
// Without it, the Responses API never returns summary content —
|
|
2502
|
+
// the model still reasons and effort still affects behavior, but
|
|
2503
|
+
// no chain-of-thought text comes back (mirrors the Anthropic
|
|
2504
|
+
// `thinking.display` gap fixed in buildThinkingParams).
|
|
2505
|
+
reasoning: {
|
|
2506
|
+
effort: this.asOpenAIReasoningEffort(reasoningEffort),
|
|
2507
|
+
summary: "auto"
|
|
2508
|
+
}
|
|
2509
|
+
},
|
|
2325
2510
|
stream: true
|
|
2326
2511
|
};
|
|
2327
2512
|
const self = this;
|
|
@@ -2360,11 +2545,38 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2360
2545
|
}
|
|
2361
2546
|
};
|
|
2362
2547
|
const toolCalls = {};
|
|
2548
|
+
const activeReasoning = /* @__PURE__ */ new Set();
|
|
2549
|
+
const knownReasoning = /* @__PURE__ */ new Set();
|
|
2550
|
+
const reasoningWithText = /* @__PURE__ */ new Set();
|
|
2363
2551
|
let usage = self.createUsage();
|
|
2364
2552
|
let finishReason = { unified: "other", raw: void 0 };
|
|
2365
2553
|
let textStarted = false;
|
|
2366
2554
|
let contentEmitted = false;
|
|
2367
2555
|
const textId = "text-0";
|
|
2556
|
+
const reasoningId = (outputIndex, summaryIndex) => `reasoning-${outputIndex}-${summaryIndex}`;
|
|
2557
|
+
const startReasoning = (outputIndex, summaryIndex) => {
|
|
2558
|
+
const id = reasoningId(outputIndex, summaryIndex);
|
|
2559
|
+
if (!knownReasoning.has(id)) {
|
|
2560
|
+
knownReasoning.add(id);
|
|
2561
|
+
activeReasoning.add(id);
|
|
2562
|
+
contentEmitted = true;
|
|
2563
|
+
safeEnqueue({ type: "reasoning-start", id });
|
|
2564
|
+
}
|
|
2565
|
+
return id;
|
|
2566
|
+
};
|
|
2567
|
+
const emitReasoningDelta = (outputIndex, summaryIndex, delta) => {
|
|
2568
|
+
const id = startReasoning(outputIndex, summaryIndex);
|
|
2569
|
+
if (activeReasoning.has(id) && delta) {
|
|
2570
|
+
reasoningWithText.add(id);
|
|
2571
|
+
safeEnqueue({ type: "reasoning-delta", id, delta });
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
const endReasoning = (outputIndex, summaryIndex) => {
|
|
2575
|
+
const id = reasoningId(outputIndex, summaryIndex);
|
|
2576
|
+
if (activeReasoning.delete(id)) {
|
|
2577
|
+
safeEnqueue({ type: "reasoning-end", id });
|
|
2578
|
+
}
|
|
2579
|
+
};
|
|
2368
2580
|
try {
|
|
2369
2581
|
const openaiStream = await client.responses.create(
|
|
2370
2582
|
{
|
|
@@ -2397,6 +2609,30 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2397
2609
|
toolName: event.item.name
|
|
2398
2610
|
});
|
|
2399
2611
|
}
|
|
2612
|
+
} else if (event.type === "response.reasoning_summary_part.added") {
|
|
2613
|
+
startReasoning(event.output_index, event.summary_index);
|
|
2614
|
+
} else if (event.type === "response.reasoning_summary_text.delta") {
|
|
2615
|
+
emitReasoningDelta(event.output_index, event.summary_index, event.delta);
|
|
2616
|
+
} else if (event.type === "response.reasoning_summary_text.done") {
|
|
2617
|
+
const id = startReasoning(event.output_index, event.summary_index);
|
|
2618
|
+
if (!reasoningWithText.has(id)) {
|
|
2619
|
+
emitReasoningDelta(event.output_index, event.summary_index, event.text);
|
|
2620
|
+
}
|
|
2621
|
+
endReasoning(event.output_index, event.summary_index);
|
|
2622
|
+
} else if (event.type === "response.reasoning_summary_part.done") {
|
|
2623
|
+
const id = startReasoning(event.output_index, event.summary_index);
|
|
2624
|
+
if (!reasoningWithText.has(id)) {
|
|
2625
|
+
emitReasoningDelta(event.output_index, event.summary_index, event.part.text);
|
|
2626
|
+
}
|
|
2627
|
+
endReasoning(event.output_index, event.summary_index);
|
|
2628
|
+
} else if (event.type === "response.output_item.done" && event.item.type === "reasoning") {
|
|
2629
|
+
const prefix = `reasoning-${event.output_index}-`;
|
|
2630
|
+
for (const id of [...activeReasoning]) {
|
|
2631
|
+
if (id.startsWith(prefix)) {
|
|
2632
|
+
activeReasoning.delete(id);
|
|
2633
|
+
safeEnqueue({ type: "reasoning-end", id });
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2400
2636
|
} else if (event.type === "response.output_text.delta") {
|
|
2401
2637
|
contentEmitted = true;
|
|
2402
2638
|
if (!textStarted) {
|
|
@@ -2439,6 +2675,10 @@ var GitLabOpenAILanguageModel = class {
|
|
|
2439
2675
|
}
|
|
2440
2676
|
}
|
|
2441
2677
|
}
|
|
2678
|
+
for (const id of activeReasoning) {
|
|
2679
|
+
safeEnqueue({ type: "reasoning-end", id });
|
|
2680
|
+
}
|
|
2681
|
+
activeReasoning.clear();
|
|
2442
2682
|
if (textStarted) {
|
|
2443
2683
|
safeEnqueue({ type: "text-end", id: textId });
|
|
2444
2684
|
}
|
|
@@ -2531,7 +2771,7 @@ var import_node_async_hooks = require("async_hooks");
|
|
|
2531
2771
|
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
|
|
2532
2772
|
|
|
2533
2773
|
// src/version.ts
|
|
2534
|
-
var VERSION = true ? "6.
|
|
2774
|
+
var VERSION = true ? "6.14.0" : "0.0.0-dev";
|
|
2535
2775
|
|
|
2536
2776
|
// src/gitlab-workflow-client.ts
|
|
2537
2777
|
var WS_CONNECT_TIMEOUT_MS = 3e4;
|
|
@@ -5378,12 +5618,14 @@ function createGitLab(options = {}) {
|
|
|
5378
5618
|
if (mapping.provider === "openai") {
|
|
5379
5619
|
return new GitLabOpenAILanguageModel(modelId, {
|
|
5380
5620
|
...baseConfig,
|
|
5381
|
-
openaiModel: agenticOptions?.providerModel ?? mapping.model
|
|
5621
|
+
openaiModel: agenticOptions?.providerModel ?? mapping.model,
|
|
5622
|
+
reasoningEffort: agenticOptions?.reasoningEffort
|
|
5382
5623
|
});
|
|
5383
5624
|
}
|
|
5384
5625
|
return new GitLabAnthropicLanguageModel(modelId, {
|
|
5385
5626
|
...baseConfig,
|
|
5386
|
-
anthropicModel: agenticOptions?.providerModel ?? mapping.model
|
|
5627
|
+
anthropicModel: agenticOptions?.providerModel ?? mapping.model,
|
|
5628
|
+
thinking: agenticOptions?.thinking
|
|
5387
5629
|
});
|
|
5388
5630
|
};
|
|
5389
5631
|
const createWorkflowChatModel = (modelId, workflowOptions) => {
|