@ljoukov/llm 5.0.4 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +49 -27
- package/dist/index.cjs +331 -122
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -7
- package/dist/index.d.ts +10 -7
- package/dist/index.js +333 -122
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -6,6 +6,8 @@ import path5 from "path";
|
|
|
6
6
|
import {
|
|
7
7
|
FinishReason,
|
|
8
8
|
FunctionCallingConfigMode,
|
|
9
|
+
MediaResolution,
|
|
10
|
+
PartMediaResolutionLevel,
|
|
9
11
|
ThinkingLevel,
|
|
10
12
|
createPartFromBase64,
|
|
11
13
|
createPartFromFunctionResponse,
|
|
@@ -204,11 +206,6 @@ function getGeminiImagePricing(modelId) {
|
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
// src/openai/pricing.ts
|
|
207
|
-
var OPENAI_GPT_52_PRICING = {
|
|
208
|
-
inputRate: 1.75 / 1e6,
|
|
209
|
-
cachedRate: 0.175 / 1e6,
|
|
210
|
-
outputRate: 14 / 1e6
|
|
211
|
-
};
|
|
212
209
|
var OPENAI_GPT_54_PRICING = {
|
|
213
210
|
inputRate: 2.5 / 1e6,
|
|
214
211
|
cachedRate: 0.25 / 1e6,
|
|
@@ -219,37 +216,31 @@ var OPENAI_GPT_54_PRIORITY_PRICING = {
|
|
|
219
216
|
cachedRate: 0.5 / 1e6,
|
|
220
217
|
outputRate: 30 / 1e6
|
|
221
218
|
};
|
|
222
|
-
var
|
|
223
|
-
inputRate: 1.25 / 1e6,
|
|
224
|
-
cachedRate: 0.125 / 1e6,
|
|
225
|
-
outputRate: 10 / 1e6
|
|
226
|
-
};
|
|
227
|
-
var OPENAI_GPT_5_MINI_PRICING = {
|
|
219
|
+
var OPENAI_GPT_54_MINI_PRICING = {
|
|
228
220
|
inputRate: 0.25 / 1e6,
|
|
229
221
|
cachedRate: 0.025 / 1e6,
|
|
230
222
|
outputRate: 2 / 1e6
|
|
231
223
|
};
|
|
224
|
+
var OPENAI_GPT_54_NANO_PRICING = {
|
|
225
|
+
inputRate: 0.05 / 1e6,
|
|
226
|
+
cachedRate: 5e-3 / 1e6,
|
|
227
|
+
outputRate: 0.4 / 1e6
|
|
228
|
+
};
|
|
232
229
|
function getOpenAiPricing(modelId) {
|
|
233
230
|
if (modelId.includes("gpt-5.4-fast")) {
|
|
234
231
|
return OPENAI_GPT_54_PRIORITY_PRICING;
|
|
235
232
|
}
|
|
236
|
-
if (modelId.includes("gpt-5.4")) {
|
|
237
|
-
return
|
|
238
|
-
}
|
|
239
|
-
if (modelId.includes("gpt-5.3-codex-spark")) {
|
|
240
|
-
return OPENAI_GPT_5_MINI_PRICING;
|
|
241
|
-
}
|
|
242
|
-
if (modelId.includes("gpt-5.3-codex")) {
|
|
243
|
-
return OPENAI_GPT_53_CODEX_PRICING;
|
|
233
|
+
if (modelId.includes("gpt-5.4-mini")) {
|
|
234
|
+
return OPENAI_GPT_54_MINI_PRICING;
|
|
244
235
|
}
|
|
245
|
-
if (modelId.includes("gpt-5.
|
|
246
|
-
return
|
|
236
|
+
if (modelId.includes("gpt-5.4-nano")) {
|
|
237
|
+
return OPENAI_GPT_54_NANO_PRICING;
|
|
247
238
|
}
|
|
248
|
-
if (modelId.includes("gpt-5-
|
|
249
|
-
return
|
|
239
|
+
if (modelId.includes("gpt-5.3-codex-spark")) {
|
|
240
|
+
return OPENAI_GPT_54_MINI_PRICING;
|
|
250
241
|
}
|
|
251
|
-
if (modelId.includes("gpt-5.
|
|
252
|
-
return
|
|
242
|
+
if (modelId.includes("gpt-5.4")) {
|
|
243
|
+
return OPENAI_GPT_54_PRICING;
|
|
253
244
|
}
|
|
254
245
|
return void 0;
|
|
255
246
|
}
|
|
@@ -2718,22 +2709,15 @@ async function runOpenAiCall(fn, modelId, runOptions) {
|
|
|
2718
2709
|
}
|
|
2719
2710
|
|
|
2720
2711
|
// src/openai/models.ts
|
|
2721
|
-
var OPENAI_MODEL_IDS = [
|
|
2722
|
-
"gpt-5.4",
|
|
2723
|
-
"gpt-5.3-codex",
|
|
2724
|
-
"gpt-5.2",
|
|
2725
|
-
"gpt-5.1-codex-mini"
|
|
2726
|
-
];
|
|
2712
|
+
var OPENAI_MODEL_IDS = ["gpt-5.4", "gpt-5.4-mini", "gpt-5.4-nano"];
|
|
2727
2713
|
function isOpenAiModelId(value) {
|
|
2728
2714
|
return OPENAI_MODEL_IDS.includes(value);
|
|
2729
2715
|
}
|
|
2730
2716
|
var CHATGPT_MODEL_IDS = [
|
|
2731
2717
|
"chatgpt-gpt-5.4",
|
|
2732
2718
|
"chatgpt-gpt-5.4-fast",
|
|
2733
|
-
"chatgpt-gpt-5.
|
|
2734
|
-
"chatgpt-gpt-5.3-codex-spark"
|
|
2735
|
-
"chatgpt-gpt-5.2",
|
|
2736
|
-
"chatgpt-gpt-5.1-codex-mini"
|
|
2719
|
+
"chatgpt-gpt-5.4-mini",
|
|
2720
|
+
"chatgpt-gpt-5.3-codex-spark"
|
|
2737
2721
|
];
|
|
2738
2722
|
function isChatGptModelId(value) {
|
|
2739
2723
|
return CHATGPT_MODEL_IDS.includes(value);
|
|
@@ -4417,6 +4401,72 @@ function parseCanonicalGeminiFileId(fileUri) {
|
|
|
4417
4401
|
const fileId = fileUri.slice(CANONICAL_GEMINI_FILE_URI_PREFIX.length).trim();
|
|
4418
4402
|
return fileId.length > 0 ? fileId : void 0;
|
|
4419
4403
|
}
|
|
4404
|
+
function isLlmMediaResolution(value) {
|
|
4405
|
+
return value === "auto" || value === "low" || value === "medium" || value === "high" || value === "original";
|
|
4406
|
+
}
|
|
4407
|
+
function resolveEffectiveMediaResolution(detail, fallback) {
|
|
4408
|
+
return detail ?? fallback;
|
|
4409
|
+
}
|
|
4410
|
+
function supportsOpenAiOriginalImageDetail(model) {
|
|
4411
|
+
if (!model) {
|
|
4412
|
+
return false;
|
|
4413
|
+
}
|
|
4414
|
+
const providerModel = isChatGptModelId(model) ? resolveChatGptProviderModel(model) : model;
|
|
4415
|
+
const match = /^gpt-(\d+)(?:\.(\d+))?/u.exec(providerModel);
|
|
4416
|
+
if (!match) {
|
|
4417
|
+
return false;
|
|
4418
|
+
}
|
|
4419
|
+
const major = Number(match[1]);
|
|
4420
|
+
const minor = Number(match[2] ?? "0");
|
|
4421
|
+
if (!Number.isFinite(major) || !Number.isFinite(minor)) {
|
|
4422
|
+
return false;
|
|
4423
|
+
}
|
|
4424
|
+
return major > 5 || major === 5 && minor >= 4;
|
|
4425
|
+
}
|
|
4426
|
+
function toOpenAiImageDetail(mediaResolution, model) {
|
|
4427
|
+
switch (mediaResolution) {
|
|
4428
|
+
case "low":
|
|
4429
|
+
return "low";
|
|
4430
|
+
case "medium":
|
|
4431
|
+
return "high";
|
|
4432
|
+
case "high":
|
|
4433
|
+
return "high";
|
|
4434
|
+
case "original":
|
|
4435
|
+
return supportsOpenAiOriginalImageDetail(model) ? "original" : "high";
|
|
4436
|
+
case "auto":
|
|
4437
|
+
default:
|
|
4438
|
+
return "auto";
|
|
4439
|
+
}
|
|
4440
|
+
}
|
|
4441
|
+
function toGeminiMediaResolution(mediaResolution) {
|
|
4442
|
+
switch (mediaResolution) {
|
|
4443
|
+
case "low":
|
|
4444
|
+
return MediaResolution.MEDIA_RESOLUTION_LOW;
|
|
4445
|
+
case "medium":
|
|
4446
|
+
return MediaResolution.MEDIA_RESOLUTION_MEDIUM;
|
|
4447
|
+
case "high":
|
|
4448
|
+
case "original":
|
|
4449
|
+
return MediaResolution.MEDIA_RESOLUTION_HIGH;
|
|
4450
|
+
case "auto":
|
|
4451
|
+
default:
|
|
4452
|
+
return void 0;
|
|
4453
|
+
}
|
|
4454
|
+
}
|
|
4455
|
+
function toGeminiPartMediaResolution(mediaResolution) {
|
|
4456
|
+
switch (mediaResolution) {
|
|
4457
|
+
case "low":
|
|
4458
|
+
return PartMediaResolutionLevel.MEDIA_RESOLUTION_LOW;
|
|
4459
|
+
case "medium":
|
|
4460
|
+
return PartMediaResolutionLevel.MEDIA_RESOLUTION_MEDIUM;
|
|
4461
|
+
case "high":
|
|
4462
|
+
return PartMediaResolutionLevel.MEDIA_RESOLUTION_HIGH;
|
|
4463
|
+
case "original":
|
|
4464
|
+
return PartMediaResolutionLevel.MEDIA_RESOLUTION_ULTRA_HIGH;
|
|
4465
|
+
case "auto":
|
|
4466
|
+
default:
|
|
4467
|
+
return void 0;
|
|
4468
|
+
}
|
|
4469
|
+
}
|
|
4420
4470
|
function cloneContentPart(part) {
|
|
4421
4471
|
switch (part.type) {
|
|
4422
4472
|
case "text":
|
|
@@ -4545,7 +4595,8 @@ function convertGeminiContentToLlmContent(content) {
|
|
|
4545
4595
|
parts: convertGooglePartsToLlmParts(content.parts ?? [])
|
|
4546
4596
|
};
|
|
4547
4597
|
}
|
|
4548
|
-
function toGeminiPart(part) {
|
|
4598
|
+
function toGeminiPart(part, options) {
|
|
4599
|
+
const defaultMediaResolution = options?.defaultMediaResolution;
|
|
4549
4600
|
switch (part.type) {
|
|
4550
4601
|
case "text":
|
|
4551
4602
|
return {
|
|
@@ -4553,6 +4604,18 @@ function toGeminiPart(part) {
|
|
|
4553
4604
|
thought: part.thought === true ? true : void 0
|
|
4554
4605
|
};
|
|
4555
4606
|
case "inlineData": {
|
|
4607
|
+
if (isInlineImageMime(part.mimeType)) {
|
|
4608
|
+
const mimeType = part.mimeType ?? "application/octet-stream";
|
|
4609
|
+
const geminiPart = createPartFromBase64(
|
|
4610
|
+
part.data,
|
|
4611
|
+
mimeType,
|
|
4612
|
+
toGeminiPartMediaResolution(defaultMediaResolution)
|
|
4613
|
+
);
|
|
4614
|
+
if (part.filename && geminiPart.inlineData) {
|
|
4615
|
+
geminiPart.inlineData.displayName = part.filename;
|
|
4616
|
+
}
|
|
4617
|
+
return geminiPart;
|
|
4618
|
+
}
|
|
4556
4619
|
const inlineData = {
|
|
4557
4620
|
data: part.data,
|
|
4558
4621
|
mimeType: part.mimeType
|
|
@@ -4565,31 +4628,35 @@ function toGeminiPart(part) {
|
|
|
4565
4628
|
};
|
|
4566
4629
|
}
|
|
4567
4630
|
case "input_image": {
|
|
4631
|
+
const mediaResolution = resolveEffectiveMediaResolution(part.detail, defaultMediaResolution);
|
|
4632
|
+
const geminiPartMediaResolution = toGeminiPartMediaResolution(mediaResolution);
|
|
4568
4633
|
if (part.file_id) {
|
|
4569
|
-
return
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
};
|
|
4634
|
+
return createPartFromUri(
|
|
4635
|
+
buildCanonicalGeminiFileUri(part.file_id),
|
|
4636
|
+
inferToolOutputMimeTypeFromFilename(part.filename) ?? "application/octet-stream",
|
|
4637
|
+
geminiPartMediaResolution
|
|
4638
|
+
);
|
|
4575
4639
|
}
|
|
4576
4640
|
if (typeof part.image_url !== "string" || part.image_url.trim().length === 0) {
|
|
4577
4641
|
throw new Error("input_image requires image_url or file_id.");
|
|
4578
4642
|
}
|
|
4579
4643
|
const parsed = parseDataUrlPayload(part.image_url);
|
|
4580
4644
|
if (parsed) {
|
|
4581
|
-
const geminiPart = createPartFromBase64(
|
|
4645
|
+
const geminiPart = createPartFromBase64(
|
|
4646
|
+
parsed.dataBase64,
|
|
4647
|
+
parsed.mimeType,
|
|
4648
|
+
geminiPartMediaResolution
|
|
4649
|
+
);
|
|
4582
4650
|
if (part.filename && geminiPart.inlineData) {
|
|
4583
4651
|
geminiPart.inlineData.displayName = part.filename;
|
|
4584
4652
|
}
|
|
4585
4653
|
return geminiPart;
|
|
4586
4654
|
}
|
|
4587
|
-
return
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
};
|
|
4655
|
+
return createPartFromUri(
|
|
4656
|
+
part.image_url,
|
|
4657
|
+
inferToolOutputMimeTypeFromFilename(part.filename) ?? "application/octet-stream",
|
|
4658
|
+
geminiPartMediaResolution
|
|
4659
|
+
);
|
|
4593
4660
|
}
|
|
4594
4661
|
case "input_file": {
|
|
4595
4662
|
if (part.file_id) {
|
|
@@ -4632,11 +4699,11 @@ function toGeminiPart(part) {
|
|
|
4632
4699
|
throw new Error("Unsupported LLM content part");
|
|
4633
4700
|
}
|
|
4634
4701
|
}
|
|
4635
|
-
function convertLlmContentToGeminiContent(content) {
|
|
4702
|
+
function convertLlmContentToGeminiContent(content, options) {
|
|
4636
4703
|
const role = content.role === "assistant" ? "model" : "user";
|
|
4637
4704
|
return {
|
|
4638
4705
|
role,
|
|
4639
|
-
parts: content.parts.map(toGeminiPart)
|
|
4706
|
+
parts: content.parts.map((part) => toGeminiPart(part, options))
|
|
4640
4707
|
};
|
|
4641
4708
|
}
|
|
4642
4709
|
function resolveProvider(model) {
|
|
@@ -4817,7 +4884,7 @@ async function storeCanonicalPromptFile(options) {
|
|
|
4817
4884
|
mimeType: options.mimeType
|
|
4818
4885
|
};
|
|
4819
4886
|
}
|
|
4820
|
-
async function prepareOpenAiPromptContentItem(item) {
|
|
4887
|
+
async function prepareOpenAiPromptContentItem(item, options) {
|
|
4821
4888
|
if (!isOpenAiNativeContentItem(item)) {
|
|
4822
4889
|
return item;
|
|
4823
4890
|
}
|
|
@@ -4836,7 +4903,10 @@ async function prepareOpenAiPromptContentItem(item) {
|
|
|
4836
4903
|
});
|
|
4837
4904
|
return {
|
|
4838
4905
|
type: "input_image",
|
|
4839
|
-
detail:
|
|
4906
|
+
detail: toOpenAiImageDetail(
|
|
4907
|
+
isLlmMediaResolution(item.detail) ? item.detail : void 0,
|
|
4908
|
+
options?.model
|
|
4909
|
+
),
|
|
4840
4910
|
file_id: uploaded.fileId
|
|
4841
4911
|
};
|
|
4842
4912
|
}
|
|
@@ -4873,7 +4943,7 @@ async function prepareOpenAiPromptContentItem(item) {
|
|
|
4873
4943
|
}
|
|
4874
4944
|
return item;
|
|
4875
4945
|
}
|
|
4876
|
-
async function prepareOpenAiPromptInput(input) {
|
|
4946
|
+
async function prepareOpenAiPromptInput(input, options) {
|
|
4877
4947
|
const prepareItem = async (item) => {
|
|
4878
4948
|
if (!item || typeof item !== "object") {
|
|
4879
4949
|
return item;
|
|
@@ -4883,7 +4953,7 @@ async function prepareOpenAiPromptInput(input) {
|
|
|
4883
4953
|
return {
|
|
4884
4954
|
...record,
|
|
4885
4955
|
content: await Promise.all(
|
|
4886
|
-
record.content.map((part) => prepareOpenAiPromptContentItem(part))
|
|
4956
|
+
record.content.map((part) => prepareOpenAiPromptContentItem(part, options))
|
|
4887
4957
|
)
|
|
4888
4958
|
};
|
|
4889
4959
|
}
|
|
@@ -4891,19 +4961,19 @@ async function prepareOpenAiPromptInput(input) {
|
|
|
4891
4961
|
return {
|
|
4892
4962
|
...record,
|
|
4893
4963
|
output: await Promise.all(
|
|
4894
|
-
record.output.map((part) => prepareOpenAiPromptContentItem(part))
|
|
4964
|
+
record.output.map((part) => prepareOpenAiPromptContentItem(part, options))
|
|
4895
4965
|
)
|
|
4896
4966
|
};
|
|
4897
4967
|
}
|
|
4898
|
-
return await prepareOpenAiPromptContentItem(item);
|
|
4968
|
+
return await prepareOpenAiPromptContentItem(item, options);
|
|
4899
4969
|
};
|
|
4900
4970
|
return await Promise.all(input.map((item) => prepareItem(item)));
|
|
4901
4971
|
}
|
|
4902
|
-
async function maybePrepareOpenAiPromptInput(input) {
|
|
4972
|
+
async function maybePrepareOpenAiPromptInput(input, options) {
|
|
4903
4973
|
if (estimateOpenAiInlinePromptBytes(input) <= INLINE_ATTACHMENT_PROMPT_THRESHOLD_BYTES) {
|
|
4904
4974
|
return Array.from(input);
|
|
4905
4975
|
}
|
|
4906
|
-
return await prepareOpenAiPromptInput(input);
|
|
4976
|
+
return await prepareOpenAiPromptInput(input, options);
|
|
4907
4977
|
}
|
|
4908
4978
|
function estimateGeminiInlinePromptBytes(contents) {
|
|
4909
4979
|
let total = 0;
|
|
@@ -4934,22 +5004,25 @@ async function prepareGeminiPromptContents(contents) {
|
|
|
4934
5004
|
for (const part of content.parts ?? []) {
|
|
4935
5005
|
const canonicalFileId = parseCanonicalGeminiFileId(part.fileData?.fileUri);
|
|
4936
5006
|
if (canonicalFileId) {
|
|
5007
|
+
const mediaResolution = part.mediaResolution?.level;
|
|
4937
5008
|
await getCanonicalFileMetadata(canonicalFileId);
|
|
4938
5009
|
if (backend === "api") {
|
|
4939
5010
|
const mirrored = await ensureGeminiFileMirror(canonicalFileId);
|
|
4940
|
-
parts.push(createPartFromUri(mirrored.uri, mirrored.mimeType));
|
|
5011
|
+
parts.push(createPartFromUri(mirrored.uri, mirrored.mimeType, mediaResolution));
|
|
4941
5012
|
} else {
|
|
4942
5013
|
const mirrored = await ensureVertexFileMirror(canonicalFileId);
|
|
4943
5014
|
parts.push({
|
|
4944
5015
|
fileData: {
|
|
4945
5016
|
fileUri: mirrored.fileUri,
|
|
4946
5017
|
mimeType: mirrored.mimeType
|
|
4947
|
-
}
|
|
5018
|
+
},
|
|
5019
|
+
...mediaResolution ? { mediaResolution: { level: mediaResolution } } : {}
|
|
4948
5020
|
});
|
|
4949
5021
|
}
|
|
4950
5022
|
continue;
|
|
4951
5023
|
}
|
|
4952
5024
|
if (part.inlineData?.data) {
|
|
5025
|
+
const mediaResolution = part.mediaResolution?.level;
|
|
4953
5026
|
const mimeType = part.inlineData.mimeType ?? "application/octet-stream";
|
|
4954
5027
|
const filename = normaliseAttachmentFilename(
|
|
4955
5028
|
getInlineAttachmentFilename(part.inlineData) ?? part.inlineData.displayName ?? guessInlineDataFilename(mimeType),
|
|
@@ -4962,14 +5035,15 @@ async function prepareGeminiPromptContents(contents) {
|
|
|
4962
5035
|
});
|
|
4963
5036
|
if (backend === "api") {
|
|
4964
5037
|
const mirrored = await ensureGeminiFileMirror(stored.fileId);
|
|
4965
|
-
parts.push(createPartFromUri(mirrored.uri, mirrored.mimeType));
|
|
5038
|
+
parts.push(createPartFromUri(mirrored.uri, mirrored.mimeType, mediaResolution));
|
|
4966
5039
|
} else {
|
|
4967
5040
|
const mirrored = await ensureVertexFileMirror(stored.fileId);
|
|
4968
5041
|
parts.push({
|
|
4969
5042
|
fileData: {
|
|
4970
5043
|
fileUri: mirrored.fileUri,
|
|
4971
5044
|
mimeType: mirrored.mimeType
|
|
4972
|
-
}
|
|
5045
|
+
},
|
|
5046
|
+
...mediaResolution ? { mediaResolution: { level: mediaResolution } } : {}
|
|
4973
5047
|
});
|
|
4974
5048
|
}
|
|
4975
5049
|
continue;
|
|
@@ -5432,7 +5506,7 @@ function resolveTextContents(input) {
|
|
|
5432
5506
|
}
|
|
5433
5507
|
return contents;
|
|
5434
5508
|
}
|
|
5435
|
-
function toOpenAiInput(contents) {
|
|
5509
|
+
function toOpenAiInput(contents, options) {
|
|
5436
5510
|
const OPENAI_ROLE_FROM_LLM = {
|
|
5437
5511
|
user: "user",
|
|
5438
5512
|
assistant: "assistant",
|
|
@@ -5440,6 +5514,8 @@ function toOpenAiInput(contents) {
|
|
|
5440
5514
|
developer: "developer",
|
|
5441
5515
|
tool: "assistant"
|
|
5442
5516
|
};
|
|
5517
|
+
const defaultMediaResolution = options?.defaultMediaResolution;
|
|
5518
|
+
const model = options?.model;
|
|
5443
5519
|
return contents.map((content) => {
|
|
5444
5520
|
const parts = [];
|
|
5445
5521
|
for (const part of content.parts) {
|
|
@@ -5454,7 +5530,7 @@ function toOpenAiInput(contents) {
|
|
|
5454
5530
|
const imagePart = {
|
|
5455
5531
|
type: "input_image",
|
|
5456
5532
|
image_url: dataUrl,
|
|
5457
|
-
detail:
|
|
5533
|
+
detail: toOpenAiImageDetail(defaultMediaResolution, model)
|
|
5458
5534
|
};
|
|
5459
5535
|
setInlineAttachmentFilename(
|
|
5460
5536
|
imagePart,
|
|
@@ -5471,11 +5547,15 @@ function toOpenAiInput(contents) {
|
|
|
5471
5547
|
break;
|
|
5472
5548
|
}
|
|
5473
5549
|
case "input_image": {
|
|
5550
|
+
const mediaResolution = resolveEffectiveMediaResolution(
|
|
5551
|
+
part.detail,
|
|
5552
|
+
defaultMediaResolution
|
|
5553
|
+
);
|
|
5474
5554
|
const imagePart = {
|
|
5475
5555
|
type: "input_image",
|
|
5476
5556
|
...part.file_id ? { file_id: part.file_id } : {},
|
|
5477
5557
|
...part.image_url ? { image_url: part.image_url } : {},
|
|
5478
|
-
detail:
|
|
5558
|
+
detail: toOpenAiImageDetail(mediaResolution, model)
|
|
5479
5559
|
};
|
|
5480
5560
|
if (part.filename) {
|
|
5481
5561
|
setInlineAttachmentFilename(imagePart, part.filename);
|
|
@@ -5508,9 +5588,11 @@ function toOpenAiInput(contents) {
|
|
|
5508
5588
|
};
|
|
5509
5589
|
});
|
|
5510
5590
|
}
|
|
5511
|
-
function toChatGptInput(contents) {
|
|
5591
|
+
function toChatGptInput(contents, options) {
|
|
5512
5592
|
const instructionsParts = [];
|
|
5513
5593
|
const input = [];
|
|
5594
|
+
const defaultMediaResolution = options?.defaultMediaResolution;
|
|
5595
|
+
const model = options?.model;
|
|
5514
5596
|
for (const content of contents) {
|
|
5515
5597
|
if (content.role === "system" || content.role === "developer") {
|
|
5516
5598
|
for (const part of content.parts) {
|
|
@@ -5546,7 +5628,7 @@ function toChatGptInput(contents) {
|
|
|
5546
5628
|
parts.push({
|
|
5547
5629
|
type: "input_image",
|
|
5548
5630
|
image_url: dataUrl,
|
|
5549
|
-
detail:
|
|
5631
|
+
detail: toOpenAiImageDetail(defaultMediaResolution, model)
|
|
5550
5632
|
});
|
|
5551
5633
|
} else {
|
|
5552
5634
|
parts.push({
|
|
@@ -5560,14 +5642,19 @@ function toChatGptInput(contents) {
|
|
|
5560
5642
|
}
|
|
5561
5643
|
break;
|
|
5562
5644
|
}
|
|
5563
|
-
case "input_image":
|
|
5645
|
+
case "input_image": {
|
|
5646
|
+
const mediaResolution = resolveEffectiveMediaResolution(
|
|
5647
|
+
part.detail,
|
|
5648
|
+
defaultMediaResolution
|
|
5649
|
+
);
|
|
5564
5650
|
parts.push({
|
|
5565
5651
|
type: "input_image",
|
|
5566
5652
|
...part.file_id ? { file_id: part.file_id } : {},
|
|
5567
5653
|
...part.image_url ? { image_url: part.image_url } : {},
|
|
5568
|
-
detail:
|
|
5654
|
+
detail: toOpenAiImageDetail(mediaResolution, model)
|
|
5569
5655
|
});
|
|
5570
5656
|
break;
|
|
5657
|
+
}
|
|
5571
5658
|
case "input_file":
|
|
5572
5659
|
parts.push({
|
|
5573
5660
|
type: "input_file",
|
|
@@ -5960,6 +6047,9 @@ function isLlmToolOutputContentItem(value) {
|
|
|
5960
6047
|
return false;
|
|
5961
6048
|
}
|
|
5962
6049
|
}
|
|
6050
|
+
if (value.detail !== void 0 && value.detail !== null && !isLlmMediaResolution(value.detail)) {
|
|
6051
|
+
return false;
|
|
6052
|
+
}
|
|
5963
6053
|
return value.image_url !== void 0 || value.file_id !== void 0;
|
|
5964
6054
|
}
|
|
5965
6055
|
if (itemType === "input_file") {
|
|
@@ -5974,17 +6064,30 @@ function isLlmToolOutputContentItem(value) {
|
|
|
5974
6064
|
}
|
|
5975
6065
|
return false;
|
|
5976
6066
|
}
|
|
5977
|
-
function toOpenAiToolOutput(value) {
|
|
6067
|
+
function toOpenAiToolOutput(value, options) {
|
|
6068
|
+
const normalizeImageItem = (item) => {
|
|
6069
|
+
if (item.type !== "input_image") {
|
|
6070
|
+
return item;
|
|
6071
|
+
}
|
|
6072
|
+
const mediaResolution = resolveEffectiveMediaResolution(
|
|
6073
|
+
item.detail,
|
|
6074
|
+
options?.defaultMediaResolution
|
|
6075
|
+
);
|
|
6076
|
+
return {
|
|
6077
|
+
...item,
|
|
6078
|
+
detail: toOpenAiImageDetail(mediaResolution, options?.model)
|
|
6079
|
+
};
|
|
6080
|
+
};
|
|
5978
6081
|
if (isLlmToolOutputContentItem(value)) {
|
|
5979
|
-
return [value];
|
|
6082
|
+
return [normalizeImageItem(value)];
|
|
5980
6083
|
}
|
|
5981
6084
|
if (Array.isArray(value) && value.every((item) => isLlmToolOutputContentItem(item))) {
|
|
5982
|
-
return value;
|
|
6085
|
+
return value.map((item) => normalizeImageItem(item));
|
|
5983
6086
|
}
|
|
5984
6087
|
return mergeToolOutput(value);
|
|
5985
6088
|
}
|
|
5986
|
-
function toChatGptToolOutput(value) {
|
|
5987
|
-
const toolOutput = toOpenAiToolOutput(value);
|
|
6089
|
+
function toChatGptToolOutput(value, options) {
|
|
6090
|
+
const toolOutput = toOpenAiToolOutput(value, options);
|
|
5988
6091
|
if (typeof toolOutput === "string") {
|
|
5989
6092
|
return toolOutput;
|
|
5990
6093
|
}
|
|
@@ -5996,7 +6099,12 @@ function toChatGptToolOutput(value) {
|
|
|
5996
6099
|
type: "input_image",
|
|
5997
6100
|
...item.file_id ? { file_id: item.file_id } : {},
|
|
5998
6101
|
...item.image_url ? { image_url: item.image_url } : {},
|
|
5999
|
-
...item.detail ? {
|
|
6102
|
+
...item.detail ? {
|
|
6103
|
+
detail: toOpenAiImageDetail(
|
|
6104
|
+
resolveEffectiveMediaResolution(item.detail, options?.defaultMediaResolution),
|
|
6105
|
+
options?.model
|
|
6106
|
+
)
|
|
6107
|
+
} : {}
|
|
6000
6108
|
};
|
|
6001
6109
|
});
|
|
6002
6110
|
}
|
|
@@ -6255,34 +6363,41 @@ async function maybeSpillCombinedToolCallOutputs(callResults, options) {
|
|
|
6255
6363
|
})
|
|
6256
6364
|
);
|
|
6257
6365
|
}
|
|
6258
|
-
function buildGeminiToolOutputMediaPart(item) {
|
|
6366
|
+
function buildGeminiToolOutputMediaPart(item, options) {
|
|
6259
6367
|
if (item.type === "input_image") {
|
|
6368
|
+
const mediaResolution = resolveEffectiveMediaResolution(
|
|
6369
|
+
item.detail,
|
|
6370
|
+
options?.defaultMediaResolution
|
|
6371
|
+
);
|
|
6372
|
+
const geminiPartMediaResolution = toGeminiPartMediaResolution(mediaResolution);
|
|
6260
6373
|
if (typeof item.file_id === "string" && item.file_id.trim().length > 0) {
|
|
6261
|
-
return
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
};
|
|
6374
|
+
return createPartFromUri(
|
|
6375
|
+
buildCanonicalGeminiFileUri(item.file_id),
|
|
6376
|
+
inferToolOutputMimeTypeFromFilename(item.filename) ?? "application/octet-stream",
|
|
6377
|
+
geminiPartMediaResolution
|
|
6378
|
+
);
|
|
6267
6379
|
}
|
|
6268
6380
|
if (typeof item.image_url !== "string" || item.image_url.trim().length === 0) {
|
|
6269
6381
|
return null;
|
|
6270
6382
|
}
|
|
6271
6383
|
const parsed = parseDataUrlPayload(item.image_url);
|
|
6272
6384
|
if (parsed) {
|
|
6273
|
-
const part = createPartFromBase64(
|
|
6385
|
+
const part = createPartFromBase64(
|
|
6386
|
+
parsed.dataBase64,
|
|
6387
|
+
parsed.mimeType,
|
|
6388
|
+
geminiPartMediaResolution
|
|
6389
|
+
);
|
|
6274
6390
|
const displayName = item.filename?.trim();
|
|
6275
6391
|
if (displayName && part.inlineData) {
|
|
6276
6392
|
part.inlineData.displayName = displayName;
|
|
6277
6393
|
}
|
|
6278
6394
|
return part;
|
|
6279
6395
|
}
|
|
6280
|
-
return
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
};
|
|
6396
|
+
return createPartFromUri(
|
|
6397
|
+
item.image_url,
|
|
6398
|
+
inferToolOutputMimeTypeFromFilename(item.filename) ?? "application/octet-stream",
|
|
6399
|
+
geminiPartMediaResolution
|
|
6400
|
+
);
|
|
6286
6401
|
}
|
|
6287
6402
|
if (item.type === "input_file") {
|
|
6288
6403
|
if (typeof item.file_id === "string" && item.file_id.trim().length > 0) {
|
|
@@ -6360,7 +6475,9 @@ function buildGeminiFunctionResponseParts(options) {
|
|
|
6360
6475
|
}
|
|
6361
6476
|
const responseOutput = outputItems.map((item) => toGeminiToolOutputPlaceholder(item));
|
|
6362
6477
|
const responseParts = outputItems.flatMap((item) => {
|
|
6363
|
-
const mediaPart = buildGeminiToolOutputMediaPart(item
|
|
6478
|
+
const mediaPart = buildGeminiToolOutputMediaPart(item, {
|
|
6479
|
+
defaultMediaResolution: options.defaultMediaResolution
|
|
6480
|
+
});
|
|
6364
6481
|
return mediaPart ? [mediaPart] : [];
|
|
6365
6482
|
});
|
|
6366
6483
|
const responsePayload = { output: responseOutput };
|
|
@@ -7127,6 +7244,7 @@ function startLlmCallLoggerFromContents(options) {
|
|
|
7127
7244
|
...options.request.imageAspectRatio ? { imageAspectRatio: options.request.imageAspectRatio } : {},
|
|
7128
7245
|
...options.request.imageSize ? { imageSize: options.request.imageSize } : {},
|
|
7129
7246
|
...options.request.thinkingLevel ? { thinkingLevel: options.request.thinkingLevel } : {},
|
|
7247
|
+
...options.request.mediaResolution ? { mediaResolution: options.request.mediaResolution } : {},
|
|
7130
7248
|
...options.request.openAiTextFormat ? { openAiTextFormat: sanitiseLogValue(options.request.openAiTextFormat) } : {},
|
|
7131
7249
|
...getCurrentToolCallContext() ? { toolContext: getCurrentToolCallContext() } : {}
|
|
7132
7250
|
},
|
|
@@ -7237,7 +7355,13 @@ async function runTextCall(params) {
|
|
|
7237
7355
|
const { result } = await collectFileUploadMetrics(async () => {
|
|
7238
7356
|
try {
|
|
7239
7357
|
if (provider === "openai") {
|
|
7240
|
-
const openAiInput = await maybePrepareOpenAiPromptInput(
|
|
7358
|
+
const openAiInput = await maybePrepareOpenAiPromptInput(
|
|
7359
|
+
toOpenAiInput(contents, {
|
|
7360
|
+
defaultMediaResolution: request.mediaResolution,
|
|
7361
|
+
model: request.model
|
|
7362
|
+
}),
|
|
7363
|
+
{ model: request.model }
|
|
7364
|
+
);
|
|
7241
7365
|
const openAiTools = toOpenAiTools(request.tools);
|
|
7242
7366
|
const reasoningEffort = resolveOpenAiReasoningEffort(
|
|
7243
7367
|
modelForProvider,
|
|
@@ -7311,7 +7435,10 @@ async function runTextCall(params) {
|
|
|
7311
7435
|
}
|
|
7312
7436
|
}, modelForProvider);
|
|
7313
7437
|
} else if (provider === "chatgpt") {
|
|
7314
|
-
const chatGptInput = toChatGptInput(contents
|
|
7438
|
+
const chatGptInput = toChatGptInput(contents, {
|
|
7439
|
+
defaultMediaResolution: request.mediaResolution,
|
|
7440
|
+
model: request.model
|
|
7441
|
+
});
|
|
7315
7442
|
const reasoningEffort = resolveOpenAiReasoningEffort(request.model, request.thinkingLevel);
|
|
7316
7443
|
const openAiTools = toOpenAiTools(request.tools);
|
|
7317
7444
|
const requestPayload = {
|
|
@@ -7408,12 +7535,18 @@ async function runTextCall(params) {
|
|
|
7408
7535
|
}, modelForProvider);
|
|
7409
7536
|
} else {
|
|
7410
7537
|
const geminiContents = await maybePrepareGeminiPromptContents(
|
|
7411
|
-
contents.map(
|
|
7538
|
+
contents.map(
|
|
7539
|
+
(content2) => convertLlmContentToGeminiContent(content2, {
|
|
7540
|
+
defaultMediaResolution: request.mediaResolution
|
|
7541
|
+
})
|
|
7542
|
+
)
|
|
7412
7543
|
);
|
|
7413
7544
|
const thinkingConfig = resolveGeminiThinkingConfig(modelForProvider, request.thinkingLevel);
|
|
7545
|
+
const mediaResolution = toGeminiMediaResolution(request.mediaResolution);
|
|
7414
7546
|
const config = {
|
|
7415
7547
|
maxOutputTokens: 32e3,
|
|
7416
7548
|
...thinkingConfig ? { thinkingConfig } : {},
|
|
7549
|
+
...mediaResolution ? { mediaResolution } : {},
|
|
7417
7550
|
...request.responseMimeType ? { responseMimeType: request.responseMimeType } : {},
|
|
7418
7551
|
...request.responseJsonSchema ? { responseJsonSchema: request.responseJsonSchema } : {},
|
|
7419
7552
|
...request.responseModalities ? { responseModalities: Array.from(request.responseModalities) } : {},
|
|
@@ -8091,7 +8224,10 @@ async function runToolLoop(request) {
|
|
|
8091
8224
|
summary: "detailed"
|
|
8092
8225
|
};
|
|
8093
8226
|
let previousResponseId;
|
|
8094
|
-
let input = toOpenAiInput(contents
|
|
8227
|
+
let input = toOpenAiInput(contents, {
|
|
8228
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8229
|
+
model: request.model
|
|
8230
|
+
});
|
|
8095
8231
|
for (let stepIndex = 0; stepIndex < maxSteps; stepIndex += 1) {
|
|
8096
8232
|
const turn = stepIndex + 1;
|
|
8097
8233
|
const stepStartedAtMs = Date.now();
|
|
@@ -8118,7 +8254,9 @@ async function runToolLoop(request) {
|
|
|
8118
8254
|
let reasoningSummary = "";
|
|
8119
8255
|
let stepToolCallText;
|
|
8120
8256
|
let stepToolCallPayload;
|
|
8121
|
-
const preparedInput = await maybePrepareOpenAiPromptInput(input
|
|
8257
|
+
const preparedInput = await maybePrepareOpenAiPromptInput(input, {
|
|
8258
|
+
model: request.model
|
|
8259
|
+
});
|
|
8122
8260
|
const stepRequestPayload = {
|
|
8123
8261
|
model: providerInfo.model,
|
|
8124
8262
|
input: preparedInput,
|
|
@@ -8249,7 +8387,10 @@ async function runToolLoop(request) {
|
|
|
8249
8387
|
const stepToolCalls = [];
|
|
8250
8388
|
if (responseToolCalls.length === 0) {
|
|
8251
8389
|
const steeringInput2 = steeringInternal?.drainPendingContents() ?? [];
|
|
8252
|
-
const steeringItems2 = steeringInput2.length > 0 ? toOpenAiInput(steeringInput2
|
|
8390
|
+
const steeringItems2 = steeringInput2.length > 0 ? toOpenAiInput(steeringInput2, {
|
|
8391
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8392
|
+
model: request.model
|
|
8393
|
+
}) : [];
|
|
8253
8394
|
finalText = responseText;
|
|
8254
8395
|
finalThoughts = reasoningSummary;
|
|
8255
8396
|
const stepCompletedAtMs2 = Date.now();
|
|
@@ -8380,13 +8521,19 @@ async function runToolLoop(request) {
|
|
|
8380
8521
|
toolOutputs.push({
|
|
8381
8522
|
type: "custom_tool_call_output",
|
|
8382
8523
|
call_id: entry.call.call_id,
|
|
8383
|
-
output: toOpenAiToolOutput(outputPayload
|
|
8524
|
+
output: toOpenAiToolOutput(outputPayload, {
|
|
8525
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8526
|
+
model: request.model
|
|
8527
|
+
})
|
|
8384
8528
|
});
|
|
8385
8529
|
} else {
|
|
8386
8530
|
toolOutputs.push({
|
|
8387
8531
|
type: "function_call_output",
|
|
8388
8532
|
call_id: entry.call.call_id,
|
|
8389
|
-
output: toOpenAiToolOutput(outputPayload
|
|
8533
|
+
output: toOpenAiToolOutput(outputPayload, {
|
|
8534
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8535
|
+
model: request.model
|
|
8536
|
+
})
|
|
8390
8537
|
});
|
|
8391
8538
|
}
|
|
8392
8539
|
}
|
|
@@ -8411,7 +8558,10 @@ async function runToolLoop(request) {
|
|
|
8411
8558
|
timing
|
|
8412
8559
|
});
|
|
8413
8560
|
const steeringInput = steeringInternal?.drainPendingContents() ?? [];
|
|
8414
|
-
const steeringItems = steeringInput.length > 0 ? toOpenAiInput(steeringInput
|
|
8561
|
+
const steeringItems = steeringInput.length > 0 ? toOpenAiInput(steeringInput, {
|
|
8562
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8563
|
+
model: request.model
|
|
8564
|
+
}) : [];
|
|
8415
8565
|
stepCallLogger?.complete({
|
|
8416
8566
|
responseText,
|
|
8417
8567
|
toolCallText: stepToolCallText,
|
|
@@ -8456,7 +8606,10 @@ async function runToolLoop(request) {
|
|
|
8456
8606
|
const openAiNativeTools = toOpenAiTools(request.modelTools);
|
|
8457
8607
|
const openAiTools = openAiNativeTools ? [...openAiNativeTools, ...openAiAgentTools] : [...openAiAgentTools];
|
|
8458
8608
|
const reasoningEffort = resolveOpenAiReasoningEffort(request.model, request.thinkingLevel);
|
|
8459
|
-
const toolLoopInput = toChatGptInput(contents
|
|
8609
|
+
const toolLoopInput = toChatGptInput(contents, {
|
|
8610
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8611
|
+
model: request.model
|
|
8612
|
+
});
|
|
8460
8613
|
const conversationId = `tool-loop-${randomBytes(8).toString("hex")}`;
|
|
8461
8614
|
const promptCacheKey = conversationId;
|
|
8462
8615
|
let input = [...toolLoopInput.input];
|
|
@@ -8560,7 +8713,10 @@ async function runToolLoop(request) {
|
|
|
8560
8713
|
stepToolCallText = serialiseLogArtifactText(stepToolCallPayload);
|
|
8561
8714
|
if (responseToolCalls.length === 0) {
|
|
8562
8715
|
const steeringInput2 = steeringInternal?.drainPendingContents() ?? [];
|
|
8563
|
-
const steeringItems2 = steeringInput2.length > 0 ? toChatGptInput(steeringInput2
|
|
8716
|
+
const steeringItems2 = steeringInput2.length > 0 ? toChatGptInput(steeringInput2, {
|
|
8717
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8718
|
+
model: request.model
|
|
8719
|
+
}).input : [];
|
|
8564
8720
|
finalText = responseText;
|
|
8565
8721
|
finalThoughts = reasoningSummaryText;
|
|
8566
8722
|
const stepCompletedAtMs2 = Date.now();
|
|
@@ -8692,7 +8848,10 @@ async function runToolLoop(request) {
|
|
|
8692
8848
|
toolOutputs.push({
|
|
8693
8849
|
type: "custom_tool_call_output",
|
|
8694
8850
|
call_id: entry.ids.callId,
|
|
8695
|
-
output: toChatGptToolOutput(outputPayload
|
|
8851
|
+
output: toChatGptToolOutput(outputPayload, {
|
|
8852
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8853
|
+
model: request.model
|
|
8854
|
+
})
|
|
8696
8855
|
});
|
|
8697
8856
|
} else {
|
|
8698
8857
|
toolOutputs.push({
|
|
@@ -8706,7 +8865,10 @@ async function runToolLoop(request) {
|
|
|
8706
8865
|
toolOutputs.push({
|
|
8707
8866
|
type: "function_call_output",
|
|
8708
8867
|
call_id: entry.ids.callId,
|
|
8709
|
-
output: toChatGptToolOutput(outputPayload
|
|
8868
|
+
output: toChatGptToolOutput(outputPayload, {
|
|
8869
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8870
|
+
model: request.model
|
|
8871
|
+
})
|
|
8710
8872
|
});
|
|
8711
8873
|
}
|
|
8712
8874
|
}
|
|
@@ -8730,7 +8892,10 @@ async function runToolLoop(request) {
|
|
|
8730
8892
|
timing
|
|
8731
8893
|
});
|
|
8732
8894
|
const steeringInput = steeringInternal?.drainPendingContents() ?? [];
|
|
8733
|
-
const steeringItems = steeringInput.length > 0 ? toChatGptInput(steeringInput
|
|
8895
|
+
const steeringItems = steeringInput.length > 0 ? toChatGptInput(steeringInput, {
|
|
8896
|
+
defaultMediaResolution: request.mediaResolution,
|
|
8897
|
+
model: request.model
|
|
8898
|
+
}).input : [];
|
|
8734
8899
|
stepCallLogger?.complete({
|
|
8735
8900
|
responseText,
|
|
8736
8901
|
toolCallText: stepToolCallText,
|
|
@@ -9061,7 +9226,11 @@ async function runToolLoop(request) {
|
|
|
9061
9226
|
const geminiFunctionTools = buildGeminiFunctionDeclarations(request.tools);
|
|
9062
9227
|
const geminiNativeTools = toGeminiTools(request.modelTools);
|
|
9063
9228
|
const geminiTools = geminiNativeTools ? geminiNativeTools.concat(geminiFunctionTools) : geminiFunctionTools;
|
|
9064
|
-
const geminiContents = contents.map(
|
|
9229
|
+
const geminiContents = contents.map(
|
|
9230
|
+
(content) => convertLlmContentToGeminiContent(content, {
|
|
9231
|
+
defaultMediaResolution: request.mediaResolution
|
|
9232
|
+
})
|
|
9233
|
+
);
|
|
9065
9234
|
for (let stepIndex = 0; stepIndex < maxSteps; stepIndex += 1) {
|
|
9066
9235
|
const turn = stepIndex + 1;
|
|
9067
9236
|
const stepStartedAtMs = Date.now();
|
|
@@ -9079,6 +9248,7 @@ async function runToolLoop(request) {
|
|
|
9079
9248
|
}
|
|
9080
9249
|
};
|
|
9081
9250
|
const thinkingConfig = resolveGeminiThinkingConfig(request.model, request.thinkingLevel);
|
|
9251
|
+
const mediaResolution = toGeminiMediaResolution(request.mediaResolution);
|
|
9082
9252
|
const config = {
|
|
9083
9253
|
maxOutputTokens: 32e3,
|
|
9084
9254
|
tools: geminiTools,
|
|
@@ -9087,7 +9257,8 @@ async function runToolLoop(request) {
|
|
|
9087
9257
|
mode: FunctionCallingConfigMode.VALIDATED
|
|
9088
9258
|
}
|
|
9089
9259
|
},
|
|
9090
|
-
...thinkingConfig ? { thinkingConfig } : {}
|
|
9260
|
+
...thinkingConfig ? { thinkingConfig } : {},
|
|
9261
|
+
...mediaResolution ? { mediaResolution } : {}
|
|
9091
9262
|
};
|
|
9092
9263
|
const onEvent = request.onEvent;
|
|
9093
9264
|
const preparedGeminiContents = await maybePrepareGeminiPromptContents(geminiContents);
|
|
@@ -9243,7 +9414,13 @@ async function runToolLoop(request) {
|
|
|
9243
9414
|
} else if (response.responseText.length > 0) {
|
|
9244
9415
|
geminiContents.push({ role: "model", parts: [{ text: response.responseText }] });
|
|
9245
9416
|
}
|
|
9246
|
-
geminiContents.push(
|
|
9417
|
+
geminiContents.push(
|
|
9418
|
+
...steeringInput2.map(
|
|
9419
|
+
(content) => convertLlmContentToGeminiContent(content, {
|
|
9420
|
+
defaultMediaResolution: request.mediaResolution
|
|
9421
|
+
})
|
|
9422
|
+
)
|
|
9423
|
+
);
|
|
9247
9424
|
continue;
|
|
9248
9425
|
}
|
|
9249
9426
|
const toolCalls = [];
|
|
@@ -9335,7 +9512,8 @@ async function runToolLoop(request) {
|
|
|
9335
9512
|
...buildGeminiFunctionResponseParts({
|
|
9336
9513
|
toolName: entry.toolName,
|
|
9337
9514
|
callId: entry.call.id,
|
|
9338
|
-
outputPayload
|
|
9515
|
+
outputPayload,
|
|
9516
|
+
defaultMediaResolution: request.mediaResolution
|
|
9339
9517
|
})
|
|
9340
9518
|
);
|
|
9341
9519
|
}
|
|
@@ -9380,7 +9558,13 @@ async function runToolLoop(request) {
|
|
|
9380
9558
|
geminiContents.push({ role: "user", parts: responseParts });
|
|
9381
9559
|
const steeringInput = steeringInternal?.drainPendingContents() ?? [];
|
|
9382
9560
|
if (steeringInput.length > 0) {
|
|
9383
|
-
geminiContents.push(
|
|
9561
|
+
geminiContents.push(
|
|
9562
|
+
...steeringInput.map(
|
|
9563
|
+
(content) => convertLlmContentToGeminiContent(content, {
|
|
9564
|
+
defaultMediaResolution: request.mediaResolution
|
|
9565
|
+
})
|
|
9566
|
+
)
|
|
9567
|
+
);
|
|
9384
9568
|
}
|
|
9385
9569
|
} catch (error) {
|
|
9386
9570
|
stepCallLogger?.fail(error, {
|
|
@@ -9636,7 +9820,7 @@ async function generateImages(request) {
|
|
|
9636
9820
|
}
|
|
9637
9821
|
return image;
|
|
9638
9822
|
})(),
|
|
9639
|
-
model: "gpt-5.
|
|
9823
|
+
model: "gpt-5.4-mini"
|
|
9640
9824
|
})
|
|
9641
9825
|
)
|
|
9642
9826
|
);
|
|
@@ -9942,7 +10126,6 @@ function resolveSubagentToolConfig(selection, currentDepth) {
|
|
|
9942
10126
|
maxWaitTimeoutMs,
|
|
9943
10127
|
promptPattern,
|
|
9944
10128
|
...instructions ? { instructions } : {},
|
|
9945
|
-
...config.model ? { model: config.model } : {},
|
|
9946
10129
|
...maxSteps ? { maxSteps } : {},
|
|
9947
10130
|
inheritTools: config.inheritTools !== false,
|
|
9948
10131
|
inheritFilesystemTool: config.inheritFilesystemTool !== false
|
|
@@ -9994,7 +10177,6 @@ function createSubagentToolController(options) {
|
|
|
9994
10177
|
`Subagent depth limit reached (${options.config.maxDepth}). Cannot spawn at depth ${childDepth}.`
|
|
9995
10178
|
);
|
|
9996
10179
|
}
|
|
9997
|
-
const model = options.config.model ?? options.parentModel;
|
|
9998
10180
|
const id = `agent_${randomBytes2(6).toString("hex")}`;
|
|
9999
10181
|
const now = Date.now();
|
|
10000
10182
|
const { roleName, roleInstructions } = resolveAgentType(input.agent_type);
|
|
@@ -10014,7 +10196,7 @@ function createSubagentToolController(options) {
|
|
|
10014
10196
|
const agent = {
|
|
10015
10197
|
id,
|
|
10016
10198
|
depth: childDepth,
|
|
10017
|
-
model,
|
|
10199
|
+
model: options.parentModel,
|
|
10018
10200
|
...nickname ? { nickname } : {},
|
|
10019
10201
|
agentRole: roleName,
|
|
10020
10202
|
status: "idle",
|
|
@@ -11769,7 +11951,8 @@ async function viewImageCodex(input, options) {
|
|
|
11769
11951
|
return [
|
|
11770
11952
|
{
|
|
11771
11953
|
type: "input_image",
|
|
11772
|
-
image_url: `data:${mimeType};base64,${bytes.toString("base64")}
|
|
11954
|
+
image_url: `data:${mimeType};base64,${bytes.toString("base64")}`,
|
|
11955
|
+
...options.mediaResolution ? { detail: options.mediaResolution } : {}
|
|
11773
11956
|
}
|
|
11774
11957
|
];
|
|
11775
11958
|
}
|
|
@@ -12449,7 +12632,11 @@ async function runAgentLoopInternal(request, context) {
|
|
|
12449
12632
|
const toolLoopRequestWithSteering = toolLoopRequest.steering === steeringChannel ? toolLoopRequest : { ...toolLoopRequest, steering: steeringChannel };
|
|
12450
12633
|
const filesystemSelection = filesystemTool ?? filesystem_tool;
|
|
12451
12634
|
const subagentSelection = subagentTool ?? subagent_tool ?? subagents;
|
|
12452
|
-
const filesystemTools = resolveFilesystemTools(
|
|
12635
|
+
const filesystemTools = resolveFilesystemTools(
|
|
12636
|
+
request.model,
|
|
12637
|
+
filesystemSelection,
|
|
12638
|
+
request.mediaResolution
|
|
12639
|
+
);
|
|
12453
12640
|
const resolvedSubagentConfig = resolveSubagentToolConfig(subagentSelection, context.depth);
|
|
12454
12641
|
const subagentController = createSubagentController({
|
|
12455
12642
|
runId,
|
|
@@ -12601,24 +12788,47 @@ async function runAgentLoopInternal(request, context) {
|
|
|
12601
12788
|
await subagentController?.closeAll();
|
|
12602
12789
|
}
|
|
12603
12790
|
}
|
|
12604
|
-
function resolveFilesystemTools(model, selection) {
|
|
12791
|
+
function resolveFilesystemTools(model, selection, defaultMediaResolution) {
|
|
12792
|
+
const withDefaultMediaResolution = (options) => {
|
|
12793
|
+
if (defaultMediaResolution === void 0) {
|
|
12794
|
+
return options;
|
|
12795
|
+
}
|
|
12796
|
+
return {
|
|
12797
|
+
mediaResolution: defaultMediaResolution,
|
|
12798
|
+
...options ?? {}
|
|
12799
|
+
};
|
|
12800
|
+
};
|
|
12605
12801
|
if (selection === void 0 || selection === false) {
|
|
12606
12802
|
return {};
|
|
12607
12803
|
}
|
|
12608
12804
|
if (selection === true) {
|
|
12609
|
-
return createFilesystemToolSetForModel(model,
|
|
12805
|
+
return createFilesystemToolSetForModel(model, withDefaultMediaResolution(void 0) ?? {});
|
|
12610
12806
|
}
|
|
12611
12807
|
if (typeof selection === "string") {
|
|
12612
|
-
return createFilesystemToolSetForModel(model, selection);
|
|
12808
|
+
return createFilesystemToolSetForModel(model, selection, withDefaultMediaResolution(void 0));
|
|
12613
12809
|
}
|
|
12614
12810
|
if (selection.enabled === false) {
|
|
12615
12811
|
return {};
|
|
12616
12812
|
}
|
|
12617
12813
|
if (selection.options && selection.profile !== void 0) {
|
|
12618
|
-
return createFilesystemToolSetForModel(
|
|
12814
|
+
return createFilesystemToolSetForModel(
|
|
12815
|
+
model,
|
|
12816
|
+
selection.profile,
|
|
12817
|
+
withDefaultMediaResolution(selection.options)
|
|
12818
|
+
);
|
|
12619
12819
|
}
|
|
12620
12820
|
if (selection.options) {
|
|
12621
|
-
return createFilesystemToolSetForModel(
|
|
12821
|
+
return createFilesystemToolSetForModel(
|
|
12822
|
+
model,
|
|
12823
|
+
withDefaultMediaResolution(selection.options) ?? {}
|
|
12824
|
+
);
|
|
12825
|
+
}
|
|
12826
|
+
if (defaultMediaResolution !== void 0) {
|
|
12827
|
+
return createFilesystemToolSetForModel(
|
|
12828
|
+
model,
|
|
12829
|
+
selection.profile ?? "auto",
|
|
12830
|
+
withDefaultMediaResolution(void 0)
|
|
12831
|
+
);
|
|
12622
12832
|
}
|
|
12623
12833
|
return createFilesystemToolSetForModel(model, selection.profile ?? "auto");
|
|
12624
12834
|
}
|
|
@@ -12641,7 +12851,7 @@ function createSubagentController(params) {
|
|
|
12641
12851
|
return createSubagentToolController({
|
|
12642
12852
|
config: params.resolvedSubagentConfig,
|
|
12643
12853
|
parentDepth: params.depth,
|
|
12644
|
-
parentModel: params.
|
|
12854
|
+
parentModel: params.model,
|
|
12645
12855
|
forkContextMessages: normalizeForkContextMessages(params.toolLoopRequest.input),
|
|
12646
12856
|
onBackgroundMessage: (message) => {
|
|
12647
12857
|
params.steering?.append({ role: "user", content: message });
|
|
@@ -12661,6 +12871,7 @@ function createSubagentController(params) {
|
|
|
12661
12871
|
modelTools: params.toolLoopRequest.modelTools,
|
|
12662
12872
|
maxSteps: subagentRequest.maxSteps,
|
|
12663
12873
|
thinkingLevel: params.toolLoopRequest.thinkingLevel,
|
|
12874
|
+
mediaResolution: params.toolLoopRequest.mediaResolution,
|
|
12664
12875
|
signal: subagentRequest.signal
|
|
12665
12876
|
},
|
|
12666
12877
|
{
|