memorix 1.3.4 → 1.4.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.
@@ -31308,7 +31308,7 @@ var init_models_generated = __esm({
31308
31308
  provider: "minimax",
31309
31309
  baseUrl: "https://api.minimax.io/anthropic",
31310
31310
  reasoning: true,
31311
- input: ["text", "image"],
31311
+ input: ["text", "image", "video"],
31312
31312
  cost: {
31313
31313
  input: 0.3,
31314
31314
  output: 1.2,
@@ -31361,7 +31361,7 @@ var init_models_generated = __esm({
31361
31361
  provider: "minimax-cn",
31362
31362
  baseUrl: "https://api.minimaxi.com/anthropic",
31363
31363
  reasoning: true,
31364
- input: ["text", "image"],
31364
+ input: ["text", "image", "video"],
31365
31365
  cost: {
31366
31366
  input: 0.3,
31367
31367
  output: 1.2,
@@ -50636,11 +50636,11 @@ var init_simple_options = __esm({
50636
50636
  });
50637
50637
 
50638
50638
  // packages/ai/dist/providers/transform-messages.js
50639
- function replaceImagesWithPlaceholder(content, placeholder) {
50639
+ function replaceMediaWithPlaceholder(content, dropType, placeholder) {
50640
50640
  const result = [];
50641
50641
  let previousWasPlaceholder = false;
50642
50642
  for (const block of content) {
50643
- if (block.type === "image") {
50643
+ if (block.type === dropType) {
50644
50644
  if (!previousWasPlaceholder) {
50645
50645
  result.push({ type: "text", text: placeholder });
50646
50646
  }
@@ -50648,33 +50648,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
50648
50648
  continue;
50649
50649
  }
50650
50650
  result.push(block);
50651
- previousWasPlaceholder = block.text === placeholder;
50651
+ previousWasPlaceholder = block.type === "text" && block.text === placeholder;
50652
50652
  }
50653
50653
  return result;
50654
50654
  }
50655
- function downgradeUnsupportedImages(messages, model) {
50656
- if (model.input.includes("image")) {
50655
+ function downgradeUnsupportedMedia(messages, model) {
50656
+ const supportsImage = model.input.includes("image");
50657
+ const supportsVideo = model.input.includes("video");
50658
+ if (supportsImage && supportsVideo) {
50657
50659
  return messages;
50658
50660
  }
50659
50661
  return messages.map((msg) => {
50660
50662
  if (msg.role === "user" && Array.isArray(msg.content)) {
50661
- return {
50662
- ...msg,
50663
- content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER)
50664
- };
50663
+ let content = msg.content;
50664
+ if (!supportsImage)
50665
+ content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
50666
+ if (!supportsVideo)
50667
+ content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
50668
+ return { ...msg, content };
50665
50669
  }
50666
50670
  if (msg.role === "toolResult") {
50667
- return {
50668
- ...msg,
50669
- content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER)
50670
- };
50671
+ let content = msg.content;
50672
+ if (!supportsImage)
50673
+ content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
50674
+ if (!supportsVideo)
50675
+ content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
50676
+ return { ...msg, content };
50671
50677
  }
50672
50678
  return msg;
50673
50679
  });
50674
50680
  }
50675
50681
  function transformMessages(messages, model, normalizeToolCallId2) {
50676
50682
  const toolCallIdMap = /* @__PURE__ */ new Map();
50677
- const imageAwareMessages = downgradeUnsupportedImages(messages, model);
50683
+ const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
50678
50684
  const transformed = imageAwareMessages.map((msg) => {
50679
50685
  if (msg.role === "user") {
50680
50686
  return msg;
@@ -50786,13 +50792,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
50786
50792
  insertSyntheticToolResults();
50787
50793
  return result;
50788
50794
  }
50789
- var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
50795
+ var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
50790
50796
  var init_transform_messages = __esm({
50791
50797
  "packages/ai/dist/providers/transform-messages.js"() {
50792
50798
  "use strict";
50793
50799
  init_esm_shims();
50794
50800
  NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
50795
50801
  NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
50802
+ NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
50803
+ NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
50796
50804
  }
50797
50805
  });
50798
50806
 
@@ -50823,8 +50831,8 @@ function getCacheControl(model, cacheRetention) {
50823
50831
  };
50824
50832
  }
50825
50833
  function convertContentBlocks(content) {
50826
- const hasImages = content.some((c) => c.type === "image");
50827
- if (!hasImages) {
50834
+ const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
50835
+ if (!hasMedia) {
50828
50836
  return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
50829
50837
  }
50830
50838
  const blocks = content.map((block) => {
@@ -50834,6 +50842,16 @@ function convertContentBlocks(content) {
50834
50842
  text: sanitizeSurrogates(block.text)
50835
50843
  };
50836
50844
  }
50845
+ if (block.type === "video") {
50846
+ return {
50847
+ type: "video",
50848
+ source: {
50849
+ type: "base64",
50850
+ media_type: block.mimeType,
50851
+ data: block.data
50852
+ }
50853
+ };
50854
+ }
50837
50855
  return {
50838
50856
  type: "image",
50839
50857
  source: {
@@ -50847,7 +50865,7 @@ function convertContentBlocks(content) {
50847
50865
  if (!hasText) {
50848
50866
  blocks.unshift({
50849
50867
  type: "text",
50850
- text: "(see attached image)"
50868
+ text: "(see attached media)"
50851
50869
  });
50852
50870
  }
50853
50871
  return blocks;
@@ -51197,6 +51215,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
51197
51215
  type: "text",
51198
51216
  text: sanitizeSurrogates(item.text)
51199
51217
  };
51218
+ } else if (item.type === "video") {
51219
+ return {
51220
+ type: "video",
51221
+ source: {
51222
+ type: "base64",
51223
+ media_type: item.mimeType,
51224
+ data: item.data
51225
+ }
51226
+ };
51200
51227
  } else {
51201
51228
  return {
51202
51229
  type: "image",
@@ -51277,6 +51304,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
51277
51304
  toolResults.push({
51278
51305
  type: "tool_result",
51279
51306
  tool_use_id: msg.toolCallId,
51307
+ // MiniMax's Anthropic-compatible API accepts video in tool results;
51308
+ // the SDK's ToolResultBlockParam.content type predates video support.
51280
51309
  content: convertContentBlocks(msg.content),
51281
51310
  is_error: msg.isError
51282
51311
  });
@@ -51303,7 +51332,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
51303
51332
  if (lastMessage.role === "user") {
51304
51333
  if (Array.isArray(lastMessage.content)) {
51305
51334
  const lastBlock = lastMessage.content[lastMessage.content.length - 1];
51306
- if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
51335
+ if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
51307
51336
  lastBlock.cache_control = cacheControl;
51308
51337
  }
51309
51338
  } else if (typeof lastMessage.content === "string") {
@@ -31281,7 +31281,7 @@ var init_models_generated = __esm({
31281
31281
  provider: "minimax",
31282
31282
  baseUrl: "https://api.minimax.io/anthropic",
31283
31283
  reasoning: true,
31284
- input: ["text", "image"],
31284
+ input: ["text", "image", "video"],
31285
31285
  cost: {
31286
31286
  input: 0.3,
31287
31287
  output: 1.2,
@@ -31334,7 +31334,7 @@ var init_models_generated = __esm({
31334
31334
  provider: "minimax-cn",
31335
31335
  baseUrl: "https://api.minimaxi.com/anthropic",
31336
31336
  reasoning: true,
31337
- input: ["text", "image"],
31337
+ input: ["text", "image", "video"],
31338
31338
  cost: {
31339
31339
  input: 0.3,
31340
31340
  output: 1.2,
@@ -50609,11 +50609,11 @@ var init_simple_options = __esm({
50609
50609
  });
50610
50610
 
50611
50611
  // packages/ai/dist/providers/transform-messages.js
50612
- function replaceImagesWithPlaceholder(content, placeholder) {
50612
+ function replaceMediaWithPlaceholder(content, dropType, placeholder) {
50613
50613
  const result = [];
50614
50614
  let previousWasPlaceholder = false;
50615
50615
  for (const block of content) {
50616
- if (block.type === "image") {
50616
+ if (block.type === dropType) {
50617
50617
  if (!previousWasPlaceholder) {
50618
50618
  result.push({ type: "text", text: placeholder });
50619
50619
  }
@@ -50621,33 +50621,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
50621
50621
  continue;
50622
50622
  }
50623
50623
  result.push(block);
50624
- previousWasPlaceholder = block.text === placeholder;
50624
+ previousWasPlaceholder = block.type === "text" && block.text === placeholder;
50625
50625
  }
50626
50626
  return result;
50627
50627
  }
50628
- function downgradeUnsupportedImages(messages, model) {
50629
- if (model.input.includes("image")) {
50628
+ function downgradeUnsupportedMedia(messages, model) {
50629
+ const supportsImage = model.input.includes("image");
50630
+ const supportsVideo = model.input.includes("video");
50631
+ if (supportsImage && supportsVideo) {
50630
50632
  return messages;
50631
50633
  }
50632
50634
  return messages.map((msg) => {
50633
50635
  if (msg.role === "user" && Array.isArray(msg.content)) {
50634
- return {
50635
- ...msg,
50636
- content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER)
50637
- };
50636
+ let content = msg.content;
50637
+ if (!supportsImage)
50638
+ content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
50639
+ if (!supportsVideo)
50640
+ content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
50641
+ return { ...msg, content };
50638
50642
  }
50639
50643
  if (msg.role === "toolResult") {
50640
- return {
50641
- ...msg,
50642
- content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER)
50643
- };
50644
+ let content = msg.content;
50645
+ if (!supportsImage)
50646
+ content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
50647
+ if (!supportsVideo)
50648
+ content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
50649
+ return { ...msg, content };
50644
50650
  }
50645
50651
  return msg;
50646
50652
  });
50647
50653
  }
50648
50654
  function transformMessages(messages, model, normalizeToolCallId2) {
50649
50655
  const toolCallIdMap = /* @__PURE__ */ new Map();
50650
- const imageAwareMessages = downgradeUnsupportedImages(messages, model);
50656
+ const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
50651
50657
  const transformed = imageAwareMessages.map((msg) => {
50652
50658
  if (msg.role === "user") {
50653
50659
  return msg;
@@ -50759,13 +50765,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
50759
50765
  insertSyntheticToolResults();
50760
50766
  return result;
50761
50767
  }
50762
- var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
50768
+ var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
50763
50769
  var init_transform_messages = __esm({
50764
50770
  "packages/ai/dist/providers/transform-messages.js"() {
50765
50771
  "use strict";
50766
50772
  init_esm_shims();
50767
50773
  NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
50768
50774
  NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
50775
+ NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
50776
+ NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
50769
50777
  }
50770
50778
  });
50771
50779
 
@@ -50796,8 +50804,8 @@ function getCacheControl(model, cacheRetention) {
50796
50804
  };
50797
50805
  }
50798
50806
  function convertContentBlocks(content) {
50799
- const hasImages = content.some((c) => c.type === "image");
50800
- if (!hasImages) {
50807
+ const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
50808
+ if (!hasMedia) {
50801
50809
  return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
50802
50810
  }
50803
50811
  const blocks = content.map((block) => {
@@ -50807,6 +50815,16 @@ function convertContentBlocks(content) {
50807
50815
  text: sanitizeSurrogates(block.text)
50808
50816
  };
50809
50817
  }
50818
+ if (block.type === "video") {
50819
+ return {
50820
+ type: "video",
50821
+ source: {
50822
+ type: "base64",
50823
+ media_type: block.mimeType,
50824
+ data: block.data
50825
+ }
50826
+ };
50827
+ }
50810
50828
  return {
50811
50829
  type: "image",
50812
50830
  source: {
@@ -50820,7 +50838,7 @@ function convertContentBlocks(content) {
50820
50838
  if (!hasText) {
50821
50839
  blocks.unshift({
50822
50840
  type: "text",
50823
- text: "(see attached image)"
50841
+ text: "(see attached media)"
50824
50842
  });
50825
50843
  }
50826
50844
  return blocks;
@@ -51170,6 +51188,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
51170
51188
  type: "text",
51171
51189
  text: sanitizeSurrogates(item.text)
51172
51190
  };
51191
+ } else if (item.type === "video") {
51192
+ return {
51193
+ type: "video",
51194
+ source: {
51195
+ type: "base64",
51196
+ media_type: item.mimeType,
51197
+ data: item.data
51198
+ }
51199
+ };
51173
51200
  } else {
51174
51201
  return {
51175
51202
  type: "image",
@@ -51250,6 +51277,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
51250
51277
  toolResults.push({
51251
51278
  type: "tool_result",
51252
51279
  tool_use_id: msg.toolCallId,
51280
+ // MiniMax's Anthropic-compatible API accepts video in tool results;
51281
+ // the SDK's ToolResultBlockParam.content type predates video support.
51253
51282
  content: convertContentBlocks(msg.content),
51254
51283
  is_error: msg.isError
51255
51284
  });
@@ -51276,7 +51305,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
51276
51305
  if (lastMessage.role === "user") {
51277
51306
  if (Array.isArray(lastMessage.content)) {
51278
51307
  const lastBlock = lastMessage.content[lastMessage.content.length - 1];
51279
- if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
51308
+ if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
51280
51309
  lastBlock.cache_control = cacheControl;
51281
51310
  }
51282
51311
  } else if (typeof lastMessage.content === "string") {
@@ -74127,7 +74127,7 @@ var init_models_generated = __esm({
74127
74127
  provider: "minimax",
74128
74128
  baseUrl: "https://api.minimax.io/anthropic",
74129
74129
  reasoning: true,
74130
- input: ["text", "image"],
74130
+ input: ["text", "image", "video"],
74131
74131
  cost: {
74132
74132
  input: 0.3,
74133
74133
  output: 1.2,
@@ -74180,7 +74180,7 @@ var init_models_generated = __esm({
74180
74180
  provider: "minimax-cn",
74181
74181
  baseUrl: "https://api.minimaxi.com/anthropic",
74182
74182
  reasoning: true,
74183
- input: ["text", "image"],
74183
+ input: ["text", "image", "video"],
74184
74184
  cost: {
74185
74185
  input: 0.3,
74186
74186
  output: 1.2,
@@ -93464,11 +93464,11 @@ var init_simple_options = __esm({
93464
93464
  });
93465
93465
 
93466
93466
  // packages/ai/dist/providers/transform-messages.js
93467
- function replaceImagesWithPlaceholder(content, placeholder) {
93467
+ function replaceMediaWithPlaceholder(content, dropType, placeholder) {
93468
93468
  const result = [];
93469
93469
  let previousWasPlaceholder = false;
93470
93470
  for (const block2 of content) {
93471
- if (block2.type === "image") {
93471
+ if (block2.type === dropType) {
93472
93472
  if (!previousWasPlaceholder) {
93473
93473
  result.push({ type: "text", text: placeholder });
93474
93474
  }
@@ -93476,33 +93476,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
93476
93476
  continue;
93477
93477
  }
93478
93478
  result.push(block2);
93479
- previousWasPlaceholder = block2.text === placeholder;
93479
+ previousWasPlaceholder = block2.type === "text" && block2.text === placeholder;
93480
93480
  }
93481
93481
  return result;
93482
93482
  }
93483
- function downgradeUnsupportedImages(messages, model) {
93484
- if (model.input.includes("image")) {
93483
+ function downgradeUnsupportedMedia(messages, model) {
93484
+ const supportsImage = model.input.includes("image");
93485
+ const supportsVideo = model.input.includes("video");
93486
+ if (supportsImage && supportsVideo) {
93485
93487
  return messages;
93486
93488
  }
93487
93489
  return messages.map((msg) => {
93488
93490
  if (msg.role === "user" && Array.isArray(msg.content)) {
93489
- return {
93490
- ...msg,
93491
- content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER)
93492
- };
93491
+ let content = msg.content;
93492
+ if (!supportsImage)
93493
+ content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
93494
+ if (!supportsVideo)
93495
+ content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
93496
+ return { ...msg, content };
93493
93497
  }
93494
93498
  if (msg.role === "toolResult") {
93495
- return {
93496
- ...msg,
93497
- content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER)
93498
- };
93499
+ let content = msg.content;
93500
+ if (!supportsImage)
93501
+ content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
93502
+ if (!supportsVideo)
93503
+ content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
93504
+ return { ...msg, content };
93499
93505
  }
93500
93506
  return msg;
93501
93507
  });
93502
93508
  }
93503
93509
  function transformMessages(messages, model, normalizeToolCallId2) {
93504
93510
  const toolCallIdMap = /* @__PURE__ */ new Map();
93505
- const imageAwareMessages = downgradeUnsupportedImages(messages, model);
93511
+ const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
93506
93512
  const transformed = imageAwareMessages.map((msg) => {
93507
93513
  if (msg.role === "user") {
93508
93514
  return msg;
@@ -93614,13 +93620,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
93614
93620
  insertSyntheticToolResults();
93615
93621
  return result;
93616
93622
  }
93617
- var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
93623
+ var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
93618
93624
  var init_transform_messages = __esm({
93619
93625
  "packages/ai/dist/providers/transform-messages.js"() {
93620
93626
  "use strict";
93621
93627
  init_esm_shims();
93622
93628
  NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
93623
93629
  NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
93630
+ NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
93631
+ NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
93624
93632
  }
93625
93633
  });
93626
93634
 
@@ -93651,8 +93659,8 @@ function getCacheControl(model, cacheRetention) {
93651
93659
  };
93652
93660
  }
93653
93661
  function convertContentBlocks(content) {
93654
- const hasImages = content.some((c) => c.type === "image");
93655
- if (!hasImages) {
93662
+ const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
93663
+ if (!hasMedia) {
93656
93664
  return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
93657
93665
  }
93658
93666
  const blocks = content.map((block2) => {
@@ -93662,6 +93670,16 @@ function convertContentBlocks(content) {
93662
93670
  text: sanitizeSurrogates(block2.text)
93663
93671
  };
93664
93672
  }
93673
+ if (block2.type === "video") {
93674
+ return {
93675
+ type: "video",
93676
+ source: {
93677
+ type: "base64",
93678
+ media_type: block2.mimeType,
93679
+ data: block2.data
93680
+ }
93681
+ };
93682
+ }
93665
93683
  return {
93666
93684
  type: "image",
93667
93685
  source: {
@@ -93675,7 +93693,7 @@ function convertContentBlocks(content) {
93675
93693
  if (!hasText) {
93676
93694
  blocks.unshift({
93677
93695
  type: "text",
93678
- text: "(see attached image)"
93696
+ text: "(see attached media)"
93679
93697
  });
93680
93698
  }
93681
93699
  return blocks;
@@ -94025,6 +94043,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
94025
94043
  type: "text",
94026
94044
  text: sanitizeSurrogates(item.text)
94027
94045
  };
94046
+ } else if (item.type === "video") {
94047
+ return {
94048
+ type: "video",
94049
+ source: {
94050
+ type: "base64",
94051
+ media_type: item.mimeType,
94052
+ data: item.data
94053
+ }
94054
+ };
94028
94055
  } else {
94029
94056
  return {
94030
94057
  type: "image",
@@ -94105,6 +94132,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
94105
94132
  toolResults.push({
94106
94133
  type: "tool_result",
94107
94134
  tool_use_id: msg.toolCallId,
94135
+ // MiniMax's Anthropic-compatible API accepts video in tool results;
94136
+ // the SDK's ToolResultBlockParam.content type predates video support.
94108
94137
  content: convertContentBlocks(msg.content),
94109
94138
  is_error: msg.isError
94110
94139
  });
@@ -94131,7 +94160,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
94131
94160
  if (lastMessage.role === "user") {
94132
94161
  if (Array.isArray(lastMessage.content)) {
94133
94162
  const lastBlock = lastMessage.content[lastMessage.content.length - 1];
94134
- if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
94163
+ if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
94135
94164
  lastBlock.cache_control = cacheControl;
94136
94165
  }
94137
94166
  } else if (typeof lastMessage.content === "string") {
@@ -233195,6 +233224,9 @@ function contentToText(content) {
233195
233224
  if (block2.type === "text") {
233196
233225
  return block2.text;
233197
233226
  }
233227
+ if (block2.type === "video") {
233228
+ return `[video:${block2.mimeType}:${block2.data.length}]`;
233229
+ }
233198
233230
  return `[image:${block2.mimeType}:${block2.data.length}]`;
233199
233231
  }).join("\n");
233200
233232
  }
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.4.1] - 2026-08-03
6
+
7
+ ### Added
8
+ - **MiniMax M3 video input** -- The bundled `@memorix/ai` provider layer now advertises and routes MiniMax M3 video content through MiniMax's Anthropic-compatible API. Base64 video is covered by focused request-shape tests, and image-only models still receive a clear text fallback instead of an invalid video block. Contributed by [@octo-patch](https://github.com/octo-patch) in #153.
9
+
10
+ ### Changed
11
+ - **Maintained product roadmap** -- Replaced the stale version-by-version roadmap with current product boundaries, operating constraints, and public directions. Release facts now live in this changelog and active maintainer work lives in `ACTIVE_WORK.md`. Contributed by [@FBISiri](https://github.com/FBISiri) in #140.
12
+
13
+ ### Fixed
14
+ - **Deterministic provider tests** -- `@memorix/ai` unit tests no longer discover local API keys or Pi OAuth credentials and unexpectedly call paid, changing provider endpoints. Routine tests are offline by default; deliberate live validation requires `MEMORIX_AI_LIVE_TESTS=1` plus the required credentials.
15
+ - **Stable model metadata assertion** -- Removed a test-only assumption that OpenRouter will permanently list `moonshotai/kimi-k2.6:free`; the bundled catalog snapshot no longer contains that route, while coverage remains for the supported Kimi K2.6 compatibility metadata.
16
+
17
+ ## [1.4.0] - 2026-08-02
18
+
19
+ ### Changed
20
+ - **Stable multimodal release** -- Promoted the controlled media lifecycle, explicit MiniMax image/video generation, and honest multimodal embedding foundation introduced in 1.3.3 to the stable line after the 1.3.4 Windows, MCP binding, cancellation, cleanup, configuration-migration, and fresh-package hardening work.
21
+
22
+ ### Verified
23
+ - **Release evidence** -- Full local regression, fresh npm-package MCP smoke, GitHub Actions on Windows and Ubuntu, Docker control-plane startup, native SQLite compatibility, npm provenance publication, and official MCP Registry publication all passed before this release.
24
+ - **Release boundary** -- “Stable” means no known release blocker after those gates. It does not claim that any software is mathematically free of future defects.
25
+
5
26
  ## [1.3.4] - 2026-08-02
6
27
 
7
28
  ### Fixed