@juspay/neurolink 9.54.1 → 9.54.2

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.
@@ -350,11 +350,9 @@ export function convertToModelMessages(messages) {
350
350
  // Assistant messages only support text content, filter out images
351
351
  const textOnlyContent = validContent.filter((item) => item.type === "text");
352
352
  if (textOnlyContent.length === 0) {
353
- // If no text content, convert to empty string
354
- return {
355
- role: "assistant",
356
- content: "",
357
- };
353
+ // No text content (e.g., only images/files) — skip message
354
+ // to avoid sending empty content to providers like Claude
355
+ return null;
358
356
  }
359
357
  else if (textOnlyContent.length === 1) {
360
358
  // Single text item, use string content
@@ -1073,9 +1071,44 @@ export async function buildMultimodalMessagesArray(options, provider, model) {
1073
1071
  msg.role === "assistant" ||
1074
1072
  msg.role === "system") {
1075
1073
  const providerOptions = msg.providerOptions;
1074
+ // Sanitize assistant array content: strip tool_use/tool_result blocks
1075
+ // that providers cannot handle. If an assistant message ends up empty
1076
+ // after stripping, skip it to avoid sending content: "" to Claude.
1077
+ // Only assistant messages need this — user messages may contain valid
1078
+ // image/file blocks that must pass through unchanged.
1079
+ let sanitizedContent = msg.content;
1080
+ if (msg.role === "assistant" && Array.isArray(msg.content)) {
1081
+ const textParts = msg.content.filter((item) => !!item &&
1082
+ typeof item === "object" &&
1083
+ item.type === "text" &&
1084
+ typeof item.text === "string");
1085
+ if (textParts.length === 0) {
1086
+ // All content was tool_use/tool_result/non-text — skip message
1087
+ continue;
1088
+ }
1089
+ // Check if any retained text part carries providerOptions
1090
+ // (e.g. Anthropic cache_control). If so, preserve them as
1091
+ // array content to avoid losing per-block metadata.
1092
+ const hasItemProviderOptions = textParts.some((item) => !!item.providerOptions);
1093
+ if (hasItemProviderOptions) {
1094
+ sanitizedContent = textParts;
1095
+ }
1096
+ else {
1097
+ sanitizedContent =
1098
+ textParts.length === 1
1099
+ ? textParts[0].text
1100
+ : textParts
1101
+ .map((p) => p.text)
1102
+ .join(" ");
1103
+ }
1104
+ }
1105
+ // Skip empty string content to avoid Claude API rejection
1106
+ if (sanitizedContent === "") {
1107
+ continue;
1108
+ }
1076
1109
  messages.push({
1077
1110
  role: msg.role,
1078
- content: msg.content,
1111
+ content: sanitizedContent,
1079
1112
  ...(providerOptions && { providerOptions }),
1080
1113
  });
1081
1114
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.54.1",
3
+ "version": "9.54.2",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 13 providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
6
6
  "author": {