memorix 1.4.0 → 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.
- package/CHANGELOG.md +12 -0
- package/CLAUDE.md +9 -9
- package/README.md +7 -2
- package/README.zh-CN.md +6 -2
- package/dist/cli/index.js +53 -23
- package/dist/index.js +53 -23
- package/dist/maintenance-runner.js +50 -21
- package/dist/media-video-runner.js +50 -21
- package/dist/memcode/index.js +53 -21
- package/dist/memcode-runtime/CHANGELOG.md +12 -0
- package/dist/sdk.js +52 -22
- package/dist/vector-backfill-runner.js +50 -21
- package/docs/API_REFERENCE.md +1 -1
- package/docs/KNOWN_ISSUES_AND_ROADMAP.md +52 -128
- package/package.json +5 -2
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/codegraph/current-facts.ts +1 -0
- package/docs/dev-log/progress.txt +0 -388
|
@@ -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
|
|
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 ===
|
|
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
|
|
50629
|
-
|
|
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
|
-
|
|
50635
|
-
|
|
50636
|
-
content
|
|
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
|
-
|
|
50641
|
-
|
|
50642
|
-
content
|
|
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 =
|
|
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
|
|
50800
|
-
if (!
|
|
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
|
|
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") {
|
package/dist/memcode/index.js
CHANGED
|
@@ -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
|
|
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 ===
|
|
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
|
|
93484
|
-
|
|
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
|
-
|
|
93490
|
-
|
|
93491
|
-
content
|
|
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
|
-
|
|
93496
|
-
|
|
93497
|
-
content
|
|
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 =
|
|
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
|
|
93655
|
-
if (!
|
|
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
|
|
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,18 @@
|
|
|
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
|
+
|
|
5
17
|
## [1.4.0] - 2026-08-02
|
|
6
18
|
|
|
7
19
|
### Changed
|
package/dist/sdk.js
CHANGED
|
@@ -32934,7 +32934,7 @@ var init_models_generated = __esm({
|
|
|
32934
32934
|
provider: "minimax",
|
|
32935
32935
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
32936
32936
|
reasoning: true,
|
|
32937
|
-
input: ["text", "image"],
|
|
32937
|
+
input: ["text", "image", "video"],
|
|
32938
32938
|
cost: {
|
|
32939
32939
|
input: 0.3,
|
|
32940
32940
|
output: 1.2,
|
|
@@ -32987,7 +32987,7 @@ var init_models_generated = __esm({
|
|
|
32987
32987
|
provider: "minimax-cn",
|
|
32988
32988
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
32989
32989
|
reasoning: true,
|
|
32990
|
-
input: ["text", "image"],
|
|
32990
|
+
input: ["text", "image", "video"],
|
|
32991
32991
|
cost: {
|
|
32992
32992
|
input: 0.3,
|
|
32993
32993
|
output: 1.2,
|
|
@@ -52262,11 +52262,11 @@ var init_simple_options = __esm({
|
|
|
52262
52262
|
});
|
|
52263
52263
|
|
|
52264
52264
|
// packages/ai/dist/providers/transform-messages.js
|
|
52265
|
-
function
|
|
52265
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52266
52266
|
const result = [];
|
|
52267
52267
|
let previousWasPlaceholder = false;
|
|
52268
52268
|
for (const block of content) {
|
|
52269
|
-
if (block.type ===
|
|
52269
|
+
if (block.type === dropType) {
|
|
52270
52270
|
if (!previousWasPlaceholder) {
|
|
52271
52271
|
result.push({ type: "text", text: placeholder });
|
|
52272
52272
|
}
|
|
@@ -52274,33 +52274,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52274
52274
|
continue;
|
|
52275
52275
|
}
|
|
52276
52276
|
result.push(block);
|
|
52277
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52277
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52278
52278
|
}
|
|
52279
52279
|
return result;
|
|
52280
52280
|
}
|
|
52281
|
-
function
|
|
52282
|
-
|
|
52281
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52282
|
+
const supportsImage = model.input.includes("image");
|
|
52283
|
+
const supportsVideo = model.input.includes("video");
|
|
52284
|
+
if (supportsImage && supportsVideo) {
|
|
52283
52285
|
return messages;
|
|
52284
52286
|
}
|
|
52285
52287
|
return messages.map((msg) => {
|
|
52286
52288
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52287
|
-
|
|
52288
|
-
|
|
52289
|
-
content
|
|
52290
|
-
|
|
52289
|
+
let content = msg.content;
|
|
52290
|
+
if (!supportsImage)
|
|
52291
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52292
|
+
if (!supportsVideo)
|
|
52293
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52294
|
+
return { ...msg, content };
|
|
52291
52295
|
}
|
|
52292
52296
|
if (msg.role === "toolResult") {
|
|
52293
|
-
|
|
52294
|
-
|
|
52295
|
-
content
|
|
52296
|
-
|
|
52297
|
+
let content = msg.content;
|
|
52298
|
+
if (!supportsImage)
|
|
52299
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52300
|
+
if (!supportsVideo)
|
|
52301
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52302
|
+
return { ...msg, content };
|
|
52297
52303
|
}
|
|
52298
52304
|
return msg;
|
|
52299
52305
|
});
|
|
52300
52306
|
}
|
|
52301
52307
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52302
52308
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52303
|
-
const imageAwareMessages =
|
|
52309
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52304
52310
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52305
52311
|
if (msg.role === "user") {
|
|
52306
52312
|
return msg;
|
|
@@ -52412,13 +52418,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52412
52418
|
insertSyntheticToolResults();
|
|
52413
52419
|
return result;
|
|
52414
52420
|
}
|
|
52415
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52421
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52416
52422
|
var init_transform_messages = __esm({
|
|
52417
52423
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52418
52424
|
"use strict";
|
|
52419
52425
|
init_esm_shims();
|
|
52420
52426
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52421
52427
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52428
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52429
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52422
52430
|
}
|
|
52423
52431
|
});
|
|
52424
52432
|
|
|
@@ -52449,8 +52457,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52449
52457
|
};
|
|
52450
52458
|
}
|
|
52451
52459
|
function convertContentBlocks(content) {
|
|
52452
|
-
const
|
|
52453
|
-
if (!
|
|
52460
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52461
|
+
if (!hasMedia) {
|
|
52454
52462
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52455
52463
|
}
|
|
52456
52464
|
const blocks = content.map((block) => {
|
|
@@ -52460,6 +52468,16 @@ function convertContentBlocks(content) {
|
|
|
52460
52468
|
text: sanitizeSurrogates(block.text)
|
|
52461
52469
|
};
|
|
52462
52470
|
}
|
|
52471
|
+
if (block.type === "video") {
|
|
52472
|
+
return {
|
|
52473
|
+
type: "video",
|
|
52474
|
+
source: {
|
|
52475
|
+
type: "base64",
|
|
52476
|
+
media_type: block.mimeType,
|
|
52477
|
+
data: block.data
|
|
52478
|
+
}
|
|
52479
|
+
};
|
|
52480
|
+
}
|
|
52463
52481
|
return {
|
|
52464
52482
|
type: "image",
|
|
52465
52483
|
source: {
|
|
@@ -52473,7 +52491,7 @@ function convertContentBlocks(content) {
|
|
|
52473
52491
|
if (!hasText) {
|
|
52474
52492
|
blocks.unshift({
|
|
52475
52493
|
type: "text",
|
|
52476
|
-
text: "(see attached
|
|
52494
|
+
text: "(see attached media)"
|
|
52477
52495
|
});
|
|
52478
52496
|
}
|
|
52479
52497
|
return blocks;
|
|
@@ -52823,6 +52841,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52823
52841
|
type: "text",
|
|
52824
52842
|
text: sanitizeSurrogates(item.text)
|
|
52825
52843
|
};
|
|
52844
|
+
} else if (item.type === "video") {
|
|
52845
|
+
return {
|
|
52846
|
+
type: "video",
|
|
52847
|
+
source: {
|
|
52848
|
+
type: "base64",
|
|
52849
|
+
media_type: item.mimeType,
|
|
52850
|
+
data: item.data
|
|
52851
|
+
}
|
|
52852
|
+
};
|
|
52826
52853
|
} else {
|
|
52827
52854
|
return {
|
|
52828
52855
|
type: "image",
|
|
@@ -52903,6 +52930,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52903
52930
|
toolResults.push({
|
|
52904
52931
|
type: "tool_result",
|
|
52905
52932
|
tool_use_id: msg.toolCallId,
|
|
52933
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
52934
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
52906
52935
|
content: convertContentBlocks(msg.content),
|
|
52907
52936
|
is_error: msg.isError
|
|
52908
52937
|
});
|
|
@@ -52929,7 +52958,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52929
52958
|
if (lastMessage.role === "user") {
|
|
52930
52959
|
if (Array.isArray(lastMessage.content)) {
|
|
52931
52960
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
52932
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
52961
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
52933
52962
|
lastBlock.cache_control = cacheControl;
|
|
52934
52963
|
}
|
|
52935
52964
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -152679,6 +152708,7 @@ function compareDateStrings(a, b) {
|
|
|
152679
152708
|
}
|
|
152680
152709
|
function detectStaleProgressNotes(input) {
|
|
152681
152710
|
const candidates = [
|
|
152711
|
+
"ACTIVE_WORK.md",
|
|
152682
152712
|
"progress.txt",
|
|
152683
152713
|
"docs/dev-log/progress.txt",
|
|
152684
152714
|
"docs/memcode/dev-log/progress.txt"
|
|
@@ -164129,7 +164159,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
164129
164159
|
};
|
|
164130
164160
|
const server = existingServer ?? new McpServer({
|
|
164131
164161
|
name: "memorix",
|
|
164132
|
-
version: true ? "1.4.
|
|
164162
|
+
version: true ? "1.4.1" : "1.0.1"
|
|
164133
164163
|
});
|
|
164134
164164
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
164135
164165
|
server.registerTool = ((name, ...args) => {
|