@codehz/ai 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -919,7 +919,7 @@ type ResponsesFunctionCall = {
919
919
  type ResponsesFunctionCallOutput = {
920
920
  type: "function_call_output";
921
921
  call_id: string;
922
- output: string;
922
+ output: string | ResponsesInputContentPart[];
923
923
  id?: string;
924
924
  status?: "in_progress" | "completed" | "incomplete";
925
925
  };
package/dist/index.mjs CHANGED
@@ -2111,6 +2111,29 @@ function mapResponsesMessageContent(role, blocks, field) {
2111
2111
  throw new AIRequestError(`${mapper$7.kind} does not support ${field} block of type "${block.type}"; only text/json/image blocks are supported`, "UNSUPPORTED_CONTENT_BLOCK");
2112
2112
  });
2113
2113
  }
2114
+ function mapResponsesToolResultOutput(blocks, field) {
2115
+ mapper$7.ensureBlocks(blocks, field, [
2116
+ "text",
2117
+ "json",
2118
+ "image"
2119
+ ], "only text/json/image blocks are supported");
2120
+ if (!blocks.some((block) => block.type === "image")) return mapper$7.textFromBlocks(blocks, field);
2121
+ return blocks.map((block) => {
2122
+ if (block.type === "text") return {
2123
+ type: "input_text",
2124
+ text: block.text
2125
+ };
2126
+ if (block.type === "json") return {
2127
+ type: "input_text",
2128
+ text: JSON.stringify(block.json)
2129
+ };
2130
+ if (block.type === "image") return {
2131
+ type: "input_image",
2132
+ image_url: block.imageUrl
2133
+ };
2134
+ throw new AIRequestError(`${mapper$7.kind} does not support ${field} block of type "${block.type}"; only text/json/image blocks are supported`, "UNSUPPORTED_CONTENT_BLOCK");
2135
+ });
2136
+ }
2114
2137
  function mapReasoningInput(item, index) {
2115
2138
  const text = mapper$7.textFromBlocks(mapper$7.ensureReasoningBlocks(item.content, "reasoning content"), "reasoning content");
2116
2139
  const id = item.id && item.id.length > 0 ? item.id : `reasoning_replay_${index}`;
@@ -2186,7 +2209,7 @@ function mapResponsesCore(request, options) {
2186
2209
  });
2187
2210
  break;
2188
2211
  case "tool_result": {
2189
- const output = mapper$7.textFromBlocks(item.content, `tool_result ${item.callId} content`);
2212
+ const output = mapResponsesToolResultOutput(item.content, `tool_result ${item.callId} content`);
2190
2213
  input.push({
2191
2214
  type: "function_call_output",
2192
2215
  call_id: item.callId,
@@ -3207,6 +3230,15 @@ function mapMessagesUserContent(blocks, field) {
3207
3230
  }
3208
3231
  return blocks.map((block) => canonicalToMessagesBlock(block, field));
3209
3232
  }
3233
+ function mapMessagesToolResultContent(blocks, field) {
3234
+ mapper$6.ensureBlocks(blocks, field, [
3235
+ "text",
3236
+ "json",
3237
+ "image"
3238
+ ], "only text/json/image blocks are supported");
3239
+ if (!blocks.some((block) => block.type === "image")) return mapper$6.textFromBlocks(blocks, field);
3240
+ return blocks.map((block) => canonicalToMessagesBlock(block, field));
3241
+ }
3210
3242
  function buildMessagesRequest(request, options) {
3211
3243
  mapper$6.assertNoServerTools(request.serverTools);
3212
3244
  const messages = [];
@@ -3252,7 +3284,7 @@ function buildMessagesRequest(request, options) {
3252
3284
  break;
3253
3285
  }
3254
3286
  case "tool_result": {
3255
- const content = mapper$6.textFromBlocks(item.content, `tool_result ${item.callId} content`);
3287
+ const content = mapMessagesToolResultContent(item.content, `tool_result ${item.callId} content`);
3256
3288
  const block = {
3257
3289
  type: "tool_result",
3258
3290
  tool_use_id: item.callId,
@@ -3688,6 +3720,29 @@ function mapChatUserContent(blocks, field) {
3688
3720
  throw new AIRequestError(`${mapper$4.kind} does not support ${field} block of type "${block.type}"; only text/json/image blocks are supported`, "UNSUPPORTED_CONTENT_BLOCK");
3689
3721
  });
3690
3722
  }
3723
+ function mapChatToolResultContent(blocks, field) {
3724
+ mapper$4.ensureBlocks(blocks, field, [
3725
+ "text",
3726
+ "json",
3727
+ "image"
3728
+ ], "only text/json/image blocks are supported");
3729
+ if (!blocks.some((block) => block.type === "image")) return mapper$4.textFromBlocks(blocks, field);
3730
+ return blocks.map((block) => {
3731
+ if (block.type === "text") return {
3732
+ type: "text",
3733
+ text: block.text
3734
+ };
3735
+ if (block.type === "json") return {
3736
+ type: "text",
3737
+ text: JSON.stringify(block.json)
3738
+ };
3739
+ if (block.type === "image") return {
3740
+ type: "image_url",
3741
+ image_url: { url: block.imageUrl }
3742
+ };
3743
+ throw new AIRequestError(`${mapper$4.kind} does not support ${field} block of type "${block.type}"; only text/json/image blocks are supported`, "UNSUPPORTED_CONTENT_BLOCK");
3744
+ });
3745
+ }
3691
3746
  function mapChatMessageContent(role, blocks, field) {
3692
3747
  if (role === "user") return mapChatUserContent(blocks, field);
3693
3748
  return mapper$4.textFromBlocks(blocks, field) || null;
@@ -3731,7 +3786,7 @@ function buildChatCompletionsRequest(request, options) {
3731
3786
  role: "tool",
3732
3787
  tool_call_id: item.callId,
3733
3788
  name: item.toolName,
3734
- content: mapper$4.textFromBlocks(item.content, `tool_result ${item.callId} content`)
3789
+ content: mapChatToolResultContent(item.content, `tool_result ${item.callId} content`)
3735
3790
  });
3736
3791
  break;
3737
3792
  case "reasoning":
@@ -4057,6 +4112,21 @@ function mapOllamaUserMessage(blocks, field) {
4057
4112
  ...images.length > 0 ? { images } : {}
4058
4113
  };
4059
4114
  }
4115
+ function mapOllamaToolResultContent(blocks, field) {
4116
+ mapper$3.ensureBlocks(blocks, field, [
4117
+ "text",
4118
+ "json",
4119
+ "image"
4120
+ ], "only text/json/image blocks are supported");
4121
+ const textBlocks = [];
4122
+ const images = [];
4123
+ for (const block of blocks) if (block.type === "image") images.push(mapOllamaImageData(block.imageUrl, field));
4124
+ else textBlocks.push(block);
4125
+ return {
4126
+ content: contentBlocksToText(textBlocks),
4127
+ ...images.length > 0 ? { images } : {}
4128
+ };
4129
+ }
4060
4130
  function buildOllamaRequest(request, options) {
4061
4131
  mapper$3.assertNoServerTools(request.serverTools);
4062
4132
  const messages = [];
@@ -4104,7 +4174,7 @@ function buildOllamaRequest(request, options) {
4104
4174
  if (queue && queue.length > 0) queue.shift();
4105
4175
  messages.push({
4106
4176
  role: "tool",
4107
- content: mapper$3.textFromBlocks(item.content, `tool_result ${item.callId} content`)
4177
+ ...mapOllamaToolResultContent(item.content, `tool_result ${item.callId} content`)
4108
4178
  });
4109
4179
  break;
4110
4180
  }
@@ -4330,6 +4400,29 @@ function mapGeminiImagePart(imageUrl, field) {
4330
4400
  data: dataUrl.data
4331
4401
  } };
4332
4402
  }
4403
+ function mapGeminiToolResultContent(blocks, field) {
4404
+ mapper$1.ensureBlocks(blocks, field, [
4405
+ "text",
4406
+ "json",
4407
+ "image"
4408
+ ], "only text/json/image blocks are supported");
4409
+ const textBlocks = [];
4410
+ const imageParts = [];
4411
+ for (const block of blocks) if (block.type === "image") imageParts.push(mapGeminiImagePart(block.imageUrl, field));
4412
+ else textBlocks.push(block);
4413
+ const text = contentBlocksToText(textBlocks);
4414
+ let response;
4415
+ try {
4416
+ const parsed = text ? JSON.parse(text) : {};
4417
+ response = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { result: text };
4418
+ } catch {
4419
+ response = { result: text };
4420
+ }
4421
+ return {
4422
+ response,
4423
+ imageParts
4424
+ };
4425
+ }
4333
4426
  function textPartsFromBlocks(blocks, field) {
4334
4427
  return mapper$1.ensureTextBlocks(blocks, field).map((block) => {
4335
4428
  if (block.type === "text") return { text: block.text };
@@ -4381,19 +4474,13 @@ function buildGeminiRequest(request, options) {
4381
4474
  } });
4382
4475
  break;
4383
4476
  case "tool_result": {
4384
- let response;
4385
- try {
4386
- const text = mapper$1.textFromBlocks(item.content, `tool_result ${item.callId} content`);
4387
- const parsed = text ? JSON.parse(text) : {};
4388
- response = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : { result: text };
4389
- } catch {
4390
- response = { result: mapper$1.textFromBlocks(item.content, `tool_result ${item.callId} content`) };
4391
- }
4477
+ const { response, imageParts } = mapGeminiToolResultContent(item.content, `tool_result ${item.callId} content`);
4392
4478
  appendPart(contents, "user", { functionResponse: {
4393
4479
  id: item.callId,
4394
4480
  name: item.toolName,
4395
4481
  response
4396
4482
  } });
4483
+ for (const imagePart of imageParts) appendPart(contents, "user", imagePart);
4397
4484
  break;
4398
4485
  }
4399
4486
  case "reasoning":