@ljoukov/llm 4.0.9 → 4.0.11
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/dist/index.cjs +158 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +162 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4700,6 +4700,144 @@ function toOpenAiToolOutput(value) {
|
|
|
4700
4700
|
}
|
|
4701
4701
|
return mergeToolOutput(value);
|
|
4702
4702
|
}
|
|
4703
|
+
function toGeminiToolOutputItems(value) {
|
|
4704
|
+
if (isLlmToolOutputContentItem(value)) {
|
|
4705
|
+
return [value];
|
|
4706
|
+
}
|
|
4707
|
+
if (Array.isArray(value) && value.every((item) => isLlmToolOutputContentItem(item))) {
|
|
4708
|
+
return value;
|
|
4709
|
+
}
|
|
4710
|
+
return null;
|
|
4711
|
+
}
|
|
4712
|
+
function inferToolOutputMimeTypeFromFilename(filename) {
|
|
4713
|
+
const normalized = filename?.trim().toLowerCase() ?? "";
|
|
4714
|
+
if (normalized.length === 0) {
|
|
4715
|
+
return void 0;
|
|
4716
|
+
}
|
|
4717
|
+
if (normalized.endsWith(".png")) {
|
|
4718
|
+
return "image/png";
|
|
4719
|
+
}
|
|
4720
|
+
if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) {
|
|
4721
|
+
return "image/jpeg";
|
|
4722
|
+
}
|
|
4723
|
+
if (normalized.endsWith(".webp")) {
|
|
4724
|
+
return "image/webp";
|
|
4725
|
+
}
|
|
4726
|
+
if (normalized.endsWith(".gif")) {
|
|
4727
|
+
return "image/gif";
|
|
4728
|
+
}
|
|
4729
|
+
if (normalized.endsWith(".heic")) {
|
|
4730
|
+
return "image/heic";
|
|
4731
|
+
}
|
|
4732
|
+
if (normalized.endsWith(".heif")) {
|
|
4733
|
+
return "image/heif";
|
|
4734
|
+
}
|
|
4735
|
+
if (normalized.endsWith(".pdf")) {
|
|
4736
|
+
return "application/pdf";
|
|
4737
|
+
}
|
|
4738
|
+
if (normalized.endsWith(".json")) {
|
|
4739
|
+
return "application/json";
|
|
4740
|
+
}
|
|
4741
|
+
if (normalized.endsWith(".md")) {
|
|
4742
|
+
return "text/markdown";
|
|
4743
|
+
}
|
|
4744
|
+
if (normalized.endsWith(".txt")) {
|
|
4745
|
+
return "text/plain";
|
|
4746
|
+
}
|
|
4747
|
+
return void 0;
|
|
4748
|
+
}
|
|
4749
|
+
function buildGeminiToolOutputMediaPart(item) {
|
|
4750
|
+
if (item.type === "input_image") {
|
|
4751
|
+
const parsed = parseDataUrlPayload(item.image_url);
|
|
4752
|
+
if (!parsed) {
|
|
4753
|
+
return null;
|
|
4754
|
+
}
|
|
4755
|
+
return (0, import_genai2.createPartFromBase64)(parsed.dataBase64, parsed.mimeType);
|
|
4756
|
+
}
|
|
4757
|
+
if (item.type === "input_file") {
|
|
4758
|
+
const dataUrl = typeof item.file_url === "string" ? parseDataUrlPayload(item.file_url) : null;
|
|
4759
|
+
if (dataUrl) {
|
|
4760
|
+
const part = (0, import_genai2.createPartFromBase64)(dataUrl.dataBase64, dataUrl.mimeType);
|
|
4761
|
+
const displayName = item.filename?.trim();
|
|
4762
|
+
if (displayName && part.inlineData) {
|
|
4763
|
+
part.inlineData.displayName = displayName;
|
|
4764
|
+
}
|
|
4765
|
+
return part;
|
|
4766
|
+
}
|
|
4767
|
+
const inferredMimeType = inferToolOutputMimeTypeFromFilename(item.filename);
|
|
4768
|
+
if (typeof item.file_data === "string" && item.file_data.trim().length > 0 && inferredMimeType) {
|
|
4769
|
+
const part = (0, import_genai2.createPartFromBase64)(item.file_data, inferredMimeType);
|
|
4770
|
+
const displayName = item.filename?.trim();
|
|
4771
|
+
if (displayName && part.inlineData) {
|
|
4772
|
+
part.inlineData.displayName = displayName;
|
|
4773
|
+
}
|
|
4774
|
+
return part;
|
|
4775
|
+
}
|
|
4776
|
+
if (typeof item.file_url === "string" && item.file_url.trim().length > 0 && inferredMimeType) {
|
|
4777
|
+
const part = (0, import_genai2.createPartFromUri)(item.file_url, inferredMimeType);
|
|
4778
|
+
const displayName = item.filename?.trim();
|
|
4779
|
+
if (displayName && part.fileData) {
|
|
4780
|
+
part.fileData.displayName = displayName;
|
|
4781
|
+
}
|
|
4782
|
+
return part;
|
|
4783
|
+
}
|
|
4784
|
+
}
|
|
4785
|
+
return null;
|
|
4786
|
+
}
|
|
4787
|
+
function toGeminiToolOutputPlaceholder(item) {
|
|
4788
|
+
if (item.type === "input_text") {
|
|
4789
|
+
return {
|
|
4790
|
+
type: item.type,
|
|
4791
|
+
text: item.text
|
|
4792
|
+
};
|
|
4793
|
+
}
|
|
4794
|
+
if (item.type === "input_image") {
|
|
4795
|
+
const parsed = parseDataUrlPayload(item.image_url);
|
|
4796
|
+
return {
|
|
4797
|
+
type: item.type,
|
|
4798
|
+
mimeType: parsed?.mimeType ?? void 0,
|
|
4799
|
+
media: "attached-inline-data"
|
|
4800
|
+
};
|
|
4801
|
+
}
|
|
4802
|
+
const dataUrl = typeof item.file_url === "string" ? parseDataUrlPayload(item.file_url) : null;
|
|
4803
|
+
return {
|
|
4804
|
+
type: item.type,
|
|
4805
|
+
filename: item.filename ?? void 0,
|
|
4806
|
+
fileId: item.file_id ?? void 0,
|
|
4807
|
+
mimeType: dataUrl?.mimeType ?? inferToolOutputMimeTypeFromFilename(item.filename) ?? void 0,
|
|
4808
|
+
media: dataUrl || typeof item.file_data === "string" && item.file_data.trim().length > 0 ? "attached-inline-data" : typeof item.file_url === "string" && item.file_url.trim().length > 0 ? "attached-file-data" : void 0
|
|
4809
|
+
};
|
|
4810
|
+
}
|
|
4811
|
+
function buildGeminiFunctionResponseParts(options) {
|
|
4812
|
+
const outputItems = toGeminiToolOutputItems(options.outputPayload);
|
|
4813
|
+
if (!outputItems) {
|
|
4814
|
+
const responsePayload2 = isPlainRecord(options.outputPayload) ? sanitiseLogValue(options.outputPayload) : { output: sanitiseLogValue(options.outputPayload) };
|
|
4815
|
+
if (options.callId) {
|
|
4816
|
+
return [(0, import_genai2.createPartFromFunctionResponse)(options.callId, options.toolName, responsePayload2)];
|
|
4817
|
+
}
|
|
4818
|
+
return [
|
|
4819
|
+
{
|
|
4820
|
+
functionResponse: {
|
|
4821
|
+
name: options.toolName,
|
|
4822
|
+
response: responsePayload2
|
|
4823
|
+
}
|
|
4824
|
+
}
|
|
4825
|
+
];
|
|
4826
|
+
}
|
|
4827
|
+
const responseOutput = outputItems.map((item) => toGeminiToolOutputPlaceholder(item));
|
|
4828
|
+
const responseParts = outputItems.flatMap((item) => {
|
|
4829
|
+
const mediaPart = buildGeminiToolOutputMediaPart(item);
|
|
4830
|
+
return mediaPart ? [mediaPart] : [];
|
|
4831
|
+
});
|
|
4832
|
+
const responsePayload = { output: responseOutput };
|
|
4833
|
+
const functionResponsePart = options.callId ? (0, import_genai2.createPartFromFunctionResponse)(options.callId, options.toolName, responsePayload) : {
|
|
4834
|
+
functionResponse: {
|
|
4835
|
+
name: options.toolName,
|
|
4836
|
+
response: responsePayload
|
|
4837
|
+
}
|
|
4838
|
+
};
|
|
4839
|
+
return [functionResponsePart, ...responseParts];
|
|
4840
|
+
}
|
|
4703
4841
|
function parseOpenAiToolArguments(raw) {
|
|
4704
4842
|
const trimmed = raw.trim();
|
|
4705
4843
|
if (trimmed.length === 0) {
|
|
@@ -5160,7 +5298,7 @@ function resolveAttachmentExtension(mimeType) {
|
|
|
5160
5298
|
function buildLoggedAttachmentFilename(prefix, index, mimeType) {
|
|
5161
5299
|
return `${prefix}-${index.toString()}.${resolveAttachmentExtension(mimeType)}`;
|
|
5162
5300
|
}
|
|
5163
|
-
function
|
|
5301
|
+
function parseDataUrlPayload(value) {
|
|
5164
5302
|
const trimmed = value.trim();
|
|
5165
5303
|
if (!trimmed.toLowerCase().startsWith("data:")) {
|
|
5166
5304
|
return null;
|
|
@@ -5176,13 +5314,24 @@ function decodeDataUrlAttachment(value, options) {
|
|
|
5176
5314
|
try {
|
|
5177
5315
|
const bytes = isBase64 ? import_node_buffer3.Buffer.from(payload, "base64") : import_node_buffer3.Buffer.from(decodeURIComponent(payload), "utf8");
|
|
5178
5316
|
return {
|
|
5179
|
-
|
|
5317
|
+
mimeType,
|
|
5318
|
+
dataBase64: bytes.toString("base64"),
|
|
5180
5319
|
bytes
|
|
5181
5320
|
};
|
|
5182
5321
|
} catch {
|
|
5183
5322
|
return null;
|
|
5184
5323
|
}
|
|
5185
5324
|
}
|
|
5325
|
+
function decodeDataUrlAttachment(value, options) {
|
|
5326
|
+
const parsed = parseDataUrlPayload(value);
|
|
5327
|
+
if (!parsed) {
|
|
5328
|
+
return null;
|
|
5329
|
+
}
|
|
5330
|
+
return {
|
|
5331
|
+
filename: buildLoggedAttachmentFilename(options.prefix, options.index, parsed.mimeType),
|
|
5332
|
+
bytes: parsed.bytes
|
|
5333
|
+
};
|
|
5334
|
+
}
|
|
5186
5335
|
function collectPayloadAttachments(value, options) {
|
|
5187
5336
|
if (typeof value === "string") {
|
|
5188
5337
|
const attachment = decodeDataUrlAttachment(value, {
|
|
@@ -7514,14 +7663,13 @@ async function runToolLoop(request) {
|
|
|
7514
7663
|
error: result.error,
|
|
7515
7664
|
durationMs: result.durationMs
|
|
7516
7665
|
});
|
|
7517
|
-
|
|
7518
|
-
|
|
7519
|
-
|
|
7520
|
-
|
|
7521
|
-
|
|
7522
|
-
|
|
7523
|
-
|
|
7524
|
-
});
|
|
7666
|
+
responseParts.push(
|
|
7667
|
+
...buildGeminiFunctionResponseParts({
|
|
7668
|
+
toolName: entry.toolName,
|
|
7669
|
+
callId: entry.call.id,
|
|
7670
|
+
outputPayload
|
|
7671
|
+
})
|
|
7672
|
+
);
|
|
7525
7673
|
}
|
|
7526
7674
|
const stepCompletedAtMs = Date.now();
|
|
7527
7675
|
const timing = buildStepTiming({
|