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
package/CHANGELOG.md
CHANGED
|
@@ -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/CLAUDE.md
CHANGED
|
@@ -77,12 +77,12 @@ Use `memorix_resolve` when a task is done or a bug is fixed. This keeps future s
|
|
|
77
77
|
| `memorix_rules_sync` | Inspect or sync rules across agents |
|
|
78
78
|
| `memorix_workspace_sync` | Inspect or migrate workspace integrations |
|
|
79
79
|
|
|
80
|
-
##
|
|
81
|
-
|
|
82
|
-
- **Repository-wide current state**: `
|
|
83
|
-
- Read that
|
|
84
|
-
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
80
|
+
## Active Work
|
|
81
|
+
|
|
82
|
+
- **Repository-wide current state**: `ACTIVE_WORK.md`
|
|
83
|
+
- Read that file after the Memory Autopilot step for long-running release or
|
|
84
|
+
development work.
|
|
85
|
+
- It is the only living work-status document. Update it after material
|
|
86
|
+
cross-session work; do not create parallel progress or dev-log files.
|
|
87
|
+
- It must stay public-safe: no local absolute paths, account identifiers,
|
|
88
|
+
credentials, raw chat transcripts, or local tool state.
|
package/README.md
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
|
-
<a href="https://registry.modelcontextprotocol.io
|
|
21
|
+
<a href="https://registry.modelcontextprotocol.io/?q=io.github.AVIDS2%2Fmemorix">Listed in the official MCP Registry</a>
|
|
22
22
|
<br>
|
|
23
|
-
<img src="https://mcptoplist.com/badge/io.github.AVIDS2%2Fmemorix.svg" alt="MCP Toplist
|
|
23
|
+
<a href="https://mcptoplist.com/server/io.github.AVIDS2%2Fmemorix"><img src="https://mcptoplist.com/badge/io.github.AVIDS2%2Fmemorix.svg" alt="View Memorix on MCP Toplist"></a>
|
|
24
24
|
</p>
|
|
25
25
|
|
|
26
26
|
<p align="center">
|
|
@@ -35,11 +35,16 @@
|
|
|
35
35
|
<a href="#quick-start">Quick Start</a> |
|
|
36
36
|
<a href="#memory-model">Memory Model</a> |
|
|
37
37
|
<a href="#memcode-bundled-terminal-agent">memcode</a> |
|
|
38
|
+
<a href="ACTIVE_WORK.md">Active Work</a> |
|
|
38
39
|
<a href="#docs">Docs</a>
|
|
39
40
|
</p>
|
|
40
41
|
|
|
41
42
|
---
|
|
42
43
|
|
|
44
|
+
> Maintainer status and the current public work boundary live in
|
|
45
|
+
> [ACTIVE_WORK.md](ACTIVE_WORK.md). It is the repository's single living work
|
|
46
|
+
> tracker.
|
|
47
|
+
|
|
43
48
|
<h2 id="what-memorix-is"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-overview.svg"><img src="assets/tags/section-overview.svg" alt="Memorix" height="32" /></picture></h2>
|
|
44
49
|
|
|
45
50
|
Memorix gives the AI coding agents you already use a shared, searchable project memory that survives new chats, IDE switches, terminal sessions, and handoffs. The memory lives under the Git project, not inside one chat window or one tool.
|
package/README.zh-CN.md
CHANGED
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
<p align="center">
|
|
21
|
-
<a href="https://registry.modelcontextprotocol.io
|
|
21
|
+
<a href="https://registry.modelcontextprotocol.io/?q=io.github.AVIDS2%2Fmemorix">已收录至官方 MCP Registry</a>
|
|
22
22
|
<br>
|
|
23
|
-
<img src="https://mcptoplist.com/badge/io.github.AVIDS2%2Fmemorix.svg" alt="MCP Toplist
|
|
23
|
+
<a href="https://mcptoplist.com/server/io.github.AVIDS2%2Fmemorix"><img src="https://mcptoplist.com/badge/io.github.AVIDS2%2Fmemorix.svg" alt="在 MCP Toplist 查看 Memorix"></a>
|
|
24
24
|
</p>
|
|
25
25
|
|
|
26
26
|
<p align="center">
|
|
@@ -35,11 +35,15 @@
|
|
|
35
35
|
<a href="#快速开始">快速开始</a> |
|
|
36
36
|
<a href="#记忆模型">记忆模型</a> |
|
|
37
37
|
<a href="#memcode内置终端-agent">memcode</a> |
|
|
38
|
+
<a href="ACTIVE_WORK.md">当前工作</a> |
|
|
38
39
|
<a href="#文档">文档</a>
|
|
39
40
|
</p>
|
|
40
41
|
|
|
41
42
|
---
|
|
42
43
|
|
|
44
|
+
> 维护者当前工作状态和公开边界统一记录在
|
|
45
|
+
> [ACTIVE_WORK.md](ACTIVE_WORK.md),这是仓库唯一的活动工作文档。
|
|
46
|
+
|
|
43
47
|
<h2 id="memorix-是什么"><picture><source media="(prefers-color-scheme: dark)" srcset="assets/tags/light/section-overview.svg"><img src="assets/tags/section-overview.svg" alt="Memorix" height="32" /></picture></h2>
|
|
44
48
|
|
|
45
49
|
Memorix 给你已经在用的 AI 编程 Agent 加上一套共享、可检索的项目记忆,让它跨越新对话、切换 IDE、重开终端 session 和交接都不丢失。记忆归属于 Git 项目,不会只困在某个聊天窗口或工具里。
|
package/dist/cli/index.js
CHANGED
|
@@ -3221,7 +3221,7 @@ ${import_picocolors.default.gray(m3)} ${s3}
|
|
|
3221
3221
|
|
|
3222
3222
|
// src/cli/version.ts
|
|
3223
3223
|
function getCliVersion() {
|
|
3224
|
-
return true ? "1.4.
|
|
3224
|
+
return true ? "1.4.1" : pkg.version;
|
|
3225
3225
|
}
|
|
3226
3226
|
var init_version = __esm({
|
|
3227
3227
|
"src/cli/version.ts"() {
|
|
@@ -42894,7 +42894,7 @@ var init_models_generated = __esm({
|
|
|
42894
42894
|
provider: "minimax",
|
|
42895
42895
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
42896
42896
|
reasoning: true,
|
|
42897
|
-
input: ["text", "image"],
|
|
42897
|
+
input: ["text", "image", "video"],
|
|
42898
42898
|
cost: {
|
|
42899
42899
|
input: 0.3,
|
|
42900
42900
|
output: 1.2,
|
|
@@ -42947,7 +42947,7 @@ var init_models_generated = __esm({
|
|
|
42947
42947
|
provider: "minimax-cn",
|
|
42948
42948
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
42949
42949
|
reasoning: true,
|
|
42950
|
-
input: ["text", "image"],
|
|
42950
|
+
input: ["text", "image", "video"],
|
|
42951
42951
|
cost: {
|
|
42952
42952
|
input: 0.3,
|
|
42953
42953
|
output: 1.2,
|
|
@@ -62222,11 +62222,11 @@ var init_simple_options = __esm({
|
|
|
62222
62222
|
});
|
|
62223
62223
|
|
|
62224
62224
|
// packages/ai/dist/providers/transform-messages.js
|
|
62225
|
-
function
|
|
62225
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
62226
62226
|
const result = [];
|
|
62227
62227
|
let previousWasPlaceholder = false;
|
|
62228
62228
|
for (const block of content) {
|
|
62229
|
-
if (block.type ===
|
|
62229
|
+
if (block.type === dropType) {
|
|
62230
62230
|
if (!previousWasPlaceholder) {
|
|
62231
62231
|
result.push({ type: "text", text: placeholder });
|
|
62232
62232
|
}
|
|
@@ -62234,33 +62234,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
62234
62234
|
continue;
|
|
62235
62235
|
}
|
|
62236
62236
|
result.push(block);
|
|
62237
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
62237
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
62238
62238
|
}
|
|
62239
62239
|
return result;
|
|
62240
62240
|
}
|
|
62241
|
-
function
|
|
62242
|
-
|
|
62241
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
62242
|
+
const supportsImage = model.input.includes("image");
|
|
62243
|
+
const supportsVideo = model.input.includes("video");
|
|
62244
|
+
if (supportsImage && supportsVideo) {
|
|
62243
62245
|
return messages;
|
|
62244
62246
|
}
|
|
62245
62247
|
return messages.map((msg) => {
|
|
62246
62248
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
62247
|
-
|
|
62248
|
-
|
|
62249
|
-
content
|
|
62250
|
-
|
|
62249
|
+
let content = msg.content;
|
|
62250
|
+
if (!supportsImage)
|
|
62251
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
62252
|
+
if (!supportsVideo)
|
|
62253
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
62254
|
+
return { ...msg, content };
|
|
62251
62255
|
}
|
|
62252
62256
|
if (msg.role === "toolResult") {
|
|
62253
|
-
|
|
62254
|
-
|
|
62255
|
-
content
|
|
62256
|
-
|
|
62257
|
+
let content = msg.content;
|
|
62258
|
+
if (!supportsImage)
|
|
62259
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
62260
|
+
if (!supportsVideo)
|
|
62261
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
62262
|
+
return { ...msg, content };
|
|
62257
62263
|
}
|
|
62258
62264
|
return msg;
|
|
62259
62265
|
});
|
|
62260
62266
|
}
|
|
62261
62267
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
62262
62268
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
62263
|
-
const imageAwareMessages =
|
|
62269
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
62264
62270
|
const transformed = imageAwareMessages.map((msg) => {
|
|
62265
62271
|
if (msg.role === "user") {
|
|
62266
62272
|
return msg;
|
|
@@ -62372,13 +62378,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
62372
62378
|
insertSyntheticToolResults();
|
|
62373
62379
|
return result;
|
|
62374
62380
|
}
|
|
62375
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
62381
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
62376
62382
|
var init_transform_messages = __esm({
|
|
62377
62383
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
62378
62384
|
"use strict";
|
|
62379
62385
|
init_esm_shims();
|
|
62380
62386
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
62381
62387
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
62388
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
62389
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
62382
62390
|
}
|
|
62383
62391
|
});
|
|
62384
62392
|
|
|
@@ -62409,8 +62417,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
62409
62417
|
};
|
|
62410
62418
|
}
|
|
62411
62419
|
function convertContentBlocks(content) {
|
|
62412
|
-
const
|
|
62413
|
-
if (!
|
|
62420
|
+
const hasMedia = content.some((c5) => c5.type === "image" || c5.type === "video");
|
|
62421
|
+
if (!hasMedia) {
|
|
62414
62422
|
return sanitizeSurrogates(content.map((c5) => c5.text).join("\n"));
|
|
62415
62423
|
}
|
|
62416
62424
|
const blocks = content.map((block) => {
|
|
@@ -62420,6 +62428,16 @@ function convertContentBlocks(content) {
|
|
|
62420
62428
|
text: sanitizeSurrogates(block.text)
|
|
62421
62429
|
};
|
|
62422
62430
|
}
|
|
62431
|
+
if (block.type === "video") {
|
|
62432
|
+
return {
|
|
62433
|
+
type: "video",
|
|
62434
|
+
source: {
|
|
62435
|
+
type: "base64",
|
|
62436
|
+
media_type: block.mimeType,
|
|
62437
|
+
data: block.data
|
|
62438
|
+
}
|
|
62439
|
+
};
|
|
62440
|
+
}
|
|
62423
62441
|
return {
|
|
62424
62442
|
type: "image",
|
|
62425
62443
|
source: {
|
|
@@ -62433,7 +62451,7 @@ function convertContentBlocks(content) {
|
|
|
62433
62451
|
if (!hasText) {
|
|
62434
62452
|
blocks.unshift({
|
|
62435
62453
|
type: "text",
|
|
62436
|
-
text: "(see attached
|
|
62454
|
+
text: "(see attached media)"
|
|
62437
62455
|
});
|
|
62438
62456
|
}
|
|
62439
62457
|
return blocks;
|
|
@@ -62783,6 +62801,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
62783
62801
|
type: "text",
|
|
62784
62802
|
text: sanitizeSurrogates(item.text)
|
|
62785
62803
|
};
|
|
62804
|
+
} else if (item.type === "video") {
|
|
62805
|
+
return {
|
|
62806
|
+
type: "video",
|
|
62807
|
+
source: {
|
|
62808
|
+
type: "base64",
|
|
62809
|
+
media_type: item.mimeType,
|
|
62810
|
+
data: item.data
|
|
62811
|
+
}
|
|
62812
|
+
};
|
|
62786
62813
|
} else {
|
|
62787
62814
|
return {
|
|
62788
62815
|
type: "image",
|
|
@@ -62863,6 +62890,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
62863
62890
|
toolResults.push({
|
|
62864
62891
|
type: "tool_result",
|
|
62865
62892
|
tool_use_id: msg.toolCallId,
|
|
62893
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
62894
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
62866
62895
|
content: convertContentBlocks(msg.content),
|
|
62867
62896
|
is_error: msg.isError
|
|
62868
62897
|
});
|
|
@@ -62889,7 +62918,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
62889
62918
|
if (lastMessage.role === "user") {
|
|
62890
62919
|
if (Array.isArray(lastMessage.content)) {
|
|
62891
62920
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
62892
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
62921
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
62893
62922
|
lastBlock.cache_control = cacheControl;
|
|
62894
62923
|
}
|
|
62895
62924
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -189639,6 +189668,7 @@ function compareDateStrings(a3, b3) {
|
|
|
189639
189668
|
}
|
|
189640
189669
|
function detectStaleProgressNotes(input) {
|
|
189641
189670
|
const candidates = [
|
|
189671
|
+
"ACTIVE_WORK.md",
|
|
189642
189672
|
"progress.txt",
|
|
189643
189673
|
"docs/dev-log/progress.txt",
|
|
189644
189674
|
"docs/memcode/dev-log/progress.txt"
|
|
@@ -213306,7 +213336,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
213306
213336
|
};
|
|
213307
213337
|
const server = existingServer ?? new McpServer({
|
|
213308
213338
|
name: "memorix",
|
|
213309
|
-
version: true ? "1.4.
|
|
213339
|
+
version: true ? "1.4.1" : "1.0.1"
|
|
213310
213340
|
});
|
|
213311
213341
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
213312
213342
|
server.registerTool = ((name, ...args) => {
|
package/dist/index.js
CHANGED
|
@@ -32930,7 +32930,7 @@ var init_models_generated = __esm({
|
|
|
32930
32930
|
provider: "minimax",
|
|
32931
32931
|
baseUrl: "https://api.minimax.io/anthropic",
|
|
32932
32932
|
reasoning: true,
|
|
32933
|
-
input: ["text", "image"],
|
|
32933
|
+
input: ["text", "image", "video"],
|
|
32934
32934
|
cost: {
|
|
32935
32935
|
input: 0.3,
|
|
32936
32936
|
output: 1.2,
|
|
@@ -32983,7 +32983,7 @@ var init_models_generated = __esm({
|
|
|
32983
32983
|
provider: "minimax-cn",
|
|
32984
32984
|
baseUrl: "https://api.minimaxi.com/anthropic",
|
|
32985
32985
|
reasoning: true,
|
|
32986
|
-
input: ["text", "image"],
|
|
32986
|
+
input: ["text", "image", "video"],
|
|
32987
32987
|
cost: {
|
|
32988
32988
|
input: 0.3,
|
|
32989
32989
|
output: 1.2,
|
|
@@ -52258,11 +52258,11 @@ var init_simple_options = __esm({
|
|
|
52258
52258
|
});
|
|
52259
52259
|
|
|
52260
52260
|
// packages/ai/dist/providers/transform-messages.js
|
|
52261
|
-
function
|
|
52261
|
+
function replaceMediaWithPlaceholder(content, dropType, placeholder) {
|
|
52262
52262
|
const result = [];
|
|
52263
52263
|
let previousWasPlaceholder = false;
|
|
52264
52264
|
for (const block of content) {
|
|
52265
|
-
if (block.type ===
|
|
52265
|
+
if (block.type === dropType) {
|
|
52266
52266
|
if (!previousWasPlaceholder) {
|
|
52267
52267
|
result.push({ type: "text", text: placeholder });
|
|
52268
52268
|
}
|
|
@@ -52270,33 +52270,39 @@ function replaceImagesWithPlaceholder(content, placeholder) {
|
|
|
52270
52270
|
continue;
|
|
52271
52271
|
}
|
|
52272
52272
|
result.push(block);
|
|
52273
|
-
previousWasPlaceholder = block.text === placeholder;
|
|
52273
|
+
previousWasPlaceholder = block.type === "text" && block.text === placeholder;
|
|
52274
52274
|
}
|
|
52275
52275
|
return result;
|
|
52276
52276
|
}
|
|
52277
|
-
function
|
|
52278
|
-
|
|
52277
|
+
function downgradeUnsupportedMedia(messages, model) {
|
|
52278
|
+
const supportsImage = model.input.includes("image");
|
|
52279
|
+
const supportsVideo = model.input.includes("video");
|
|
52280
|
+
if (supportsImage && supportsVideo) {
|
|
52279
52281
|
return messages;
|
|
52280
52282
|
}
|
|
52281
52283
|
return messages.map((msg) => {
|
|
52282
52284
|
if (msg.role === "user" && Array.isArray(msg.content)) {
|
|
52283
|
-
|
|
52284
|
-
|
|
52285
|
-
content
|
|
52286
|
-
|
|
52285
|
+
let content = msg.content;
|
|
52286
|
+
if (!supportsImage)
|
|
52287
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_USER_IMAGE_PLACEHOLDER);
|
|
52288
|
+
if (!supportsVideo)
|
|
52289
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_USER_VIDEO_PLACEHOLDER);
|
|
52290
|
+
return { ...msg, content };
|
|
52287
52291
|
}
|
|
52288
52292
|
if (msg.role === "toolResult") {
|
|
52289
|
-
|
|
52290
|
-
|
|
52291
|
-
content
|
|
52292
|
-
|
|
52293
|
+
let content = msg.content;
|
|
52294
|
+
if (!supportsImage)
|
|
52295
|
+
content = replaceMediaWithPlaceholder(content, "image", NON_VISION_TOOL_IMAGE_PLACEHOLDER);
|
|
52296
|
+
if (!supportsVideo)
|
|
52297
|
+
content = replaceMediaWithPlaceholder(content, "video", NON_VISION_TOOL_VIDEO_PLACEHOLDER);
|
|
52298
|
+
return { ...msg, content };
|
|
52293
52299
|
}
|
|
52294
52300
|
return msg;
|
|
52295
52301
|
});
|
|
52296
52302
|
}
|
|
52297
52303
|
function transformMessages(messages, model, normalizeToolCallId2) {
|
|
52298
52304
|
const toolCallIdMap = /* @__PURE__ */ new Map();
|
|
52299
|
-
const imageAwareMessages =
|
|
52305
|
+
const imageAwareMessages = downgradeUnsupportedMedia(messages, model);
|
|
52300
52306
|
const transformed = imageAwareMessages.map((msg) => {
|
|
52301
52307
|
if (msg.role === "user") {
|
|
52302
52308
|
return msg;
|
|
@@ -52408,13 +52414,15 @@ function transformMessages(messages, model, normalizeToolCallId2) {
|
|
|
52408
52414
|
insertSyntheticToolResults();
|
|
52409
52415
|
return result;
|
|
52410
52416
|
}
|
|
52411
|
-
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER;
|
|
52417
|
+
var NON_VISION_USER_IMAGE_PLACEHOLDER, NON_VISION_TOOL_IMAGE_PLACEHOLDER, NON_VISION_USER_VIDEO_PLACEHOLDER, NON_VISION_TOOL_VIDEO_PLACEHOLDER;
|
|
52412
52418
|
var init_transform_messages = __esm({
|
|
52413
52419
|
"packages/ai/dist/providers/transform-messages.js"() {
|
|
52414
52420
|
"use strict";
|
|
52415
52421
|
init_esm_shims();
|
|
52416
52422
|
NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
|
|
52417
52423
|
NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
|
|
52424
|
+
NON_VISION_USER_VIDEO_PLACEHOLDER = "(video omitted: model does not support video)";
|
|
52425
|
+
NON_VISION_TOOL_VIDEO_PLACEHOLDER = "(tool video omitted: model does not support video)";
|
|
52418
52426
|
}
|
|
52419
52427
|
});
|
|
52420
52428
|
|
|
@@ -52445,8 +52453,8 @@ function getCacheControl(model, cacheRetention) {
|
|
|
52445
52453
|
};
|
|
52446
52454
|
}
|
|
52447
52455
|
function convertContentBlocks(content) {
|
|
52448
|
-
const
|
|
52449
|
-
if (!
|
|
52456
|
+
const hasMedia = content.some((c) => c.type === "image" || c.type === "video");
|
|
52457
|
+
if (!hasMedia) {
|
|
52450
52458
|
return sanitizeSurrogates(content.map((c) => c.text).join("\n"));
|
|
52451
52459
|
}
|
|
52452
52460
|
const blocks = content.map((block) => {
|
|
@@ -52456,6 +52464,16 @@ function convertContentBlocks(content) {
|
|
|
52456
52464
|
text: sanitizeSurrogates(block.text)
|
|
52457
52465
|
};
|
|
52458
52466
|
}
|
|
52467
|
+
if (block.type === "video") {
|
|
52468
|
+
return {
|
|
52469
|
+
type: "video",
|
|
52470
|
+
source: {
|
|
52471
|
+
type: "base64",
|
|
52472
|
+
media_type: block.mimeType,
|
|
52473
|
+
data: block.data
|
|
52474
|
+
}
|
|
52475
|
+
};
|
|
52476
|
+
}
|
|
52459
52477
|
return {
|
|
52460
52478
|
type: "image",
|
|
52461
52479
|
source: {
|
|
@@ -52469,7 +52487,7 @@ function convertContentBlocks(content) {
|
|
|
52469
52487
|
if (!hasText) {
|
|
52470
52488
|
blocks.unshift({
|
|
52471
52489
|
type: "text",
|
|
52472
|
-
text: "(see attached
|
|
52490
|
+
text: "(see attached media)"
|
|
52473
52491
|
});
|
|
52474
52492
|
}
|
|
52475
52493
|
return blocks;
|
|
@@ -52819,6 +52837,15 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52819
52837
|
type: "text",
|
|
52820
52838
|
text: sanitizeSurrogates(item.text)
|
|
52821
52839
|
};
|
|
52840
|
+
} else if (item.type === "video") {
|
|
52841
|
+
return {
|
|
52842
|
+
type: "video",
|
|
52843
|
+
source: {
|
|
52844
|
+
type: "base64",
|
|
52845
|
+
media_type: item.mimeType,
|
|
52846
|
+
data: item.data
|
|
52847
|
+
}
|
|
52848
|
+
};
|
|
52822
52849
|
} else {
|
|
52823
52850
|
return {
|
|
52824
52851
|
type: "image",
|
|
@@ -52899,6 +52926,8 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52899
52926
|
toolResults.push({
|
|
52900
52927
|
type: "tool_result",
|
|
52901
52928
|
tool_use_id: msg.toolCallId,
|
|
52929
|
+
// MiniMax's Anthropic-compatible API accepts video in tool results;
|
|
52930
|
+
// the SDK's ToolResultBlockParam.content type predates video support.
|
|
52902
52931
|
content: convertContentBlocks(msg.content),
|
|
52903
52932
|
is_error: msg.isError
|
|
52904
52933
|
});
|
|
@@ -52925,7 +52954,7 @@ function convertMessages(messages, model, isOAuthToken2, cacheControl, allowEmpt
|
|
|
52925
52954
|
if (lastMessage.role === "user") {
|
|
52926
52955
|
if (Array.isArray(lastMessage.content)) {
|
|
52927
52956
|
const lastBlock = lastMessage.content[lastMessage.content.length - 1];
|
|
52928
|
-
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
|
|
52957
|
+
if (lastBlock && (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "video" || lastBlock.type === "tool_result")) {
|
|
52929
52958
|
lastBlock.cache_control = cacheControl;
|
|
52930
52959
|
}
|
|
52931
52960
|
} else if (typeof lastMessage.content === "string") {
|
|
@@ -156516,6 +156545,7 @@ function compareDateStrings(a, b) {
|
|
|
156516
156545
|
}
|
|
156517
156546
|
function detectStaleProgressNotes(input) {
|
|
156518
156547
|
const candidates = [
|
|
156548
|
+
"ACTIVE_WORK.md",
|
|
156519
156549
|
"progress.txt",
|
|
156520
156550
|
"docs/dev-log/progress.txt",
|
|
156521
156551
|
"docs/memcode/dev-log/progress.txt"
|
|
@@ -164315,7 +164345,7 @@ The path should point to a directory containing a .git folder.`
|
|
|
164315
164345
|
};
|
|
164316
164346
|
const server = existingServer ?? new McpServer({
|
|
164317
164347
|
name: "memorix",
|
|
164318
|
-
version: true ? "1.4.
|
|
164348
|
+
version: true ? "1.4.1" : "1.0.1"
|
|
164319
164349
|
});
|
|
164320
164350
|
const originalRegisterTool = server.registerTool.bind(server);
|
|
164321
164351
|
server.registerTool = ((name, ...args) => {
|
|
@@ -168580,7 +168610,7 @@ var init_serve_shared = __esm({
|
|
|
168580
168610
|
|
|
168581
168611
|
// src/cli/version.ts
|
|
168582
168612
|
function getCliVersion() {
|
|
168583
|
-
return true ? "1.4.
|
|
168613
|
+
return true ? "1.4.1" : pkg.version;
|
|
168584
168614
|
}
|
|
168585
168615
|
var init_version3 = __esm({
|
|
168586
168616
|
"src/cli/version.ts"() {
|
|
@@ -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
|
|
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 ===
|
|
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
|
|
50656
|
-
|
|
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
|
-
|
|
50662
|
-
|
|
50663
|
-
content
|
|
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
|
-
|
|
50668
|
-
|
|
50669
|
-
content
|
|
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 =
|
|
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
|
|
50827
|
-
if (!
|
|
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
|
|
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") {
|