Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Reduce remote app-server resident footprint - make the updater opt-out and publish minimum hardware requirements

未关闭
#546 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
18/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
linux, node.js, typescript

调研方向

Start by locating the TypeScript app-server daemon entry point that parses mcode app-server daemon bootstrap and the internal gate a.managedUpdaterEnabled ?? !0; also read the daemon update-loop spawn and the config.yaml schema. Scope (a) first: add a supported --no-managed-updater flag or updater.enabled key, then verify mcode app-server daemon --help lists it and no updater process/state file appears after bootstrap. The probe script in the issue is the acceptance check; (b)-(d) need separate packaging and documentation changes.

由索引模型根据 Issue 内容生成。

描述

enhancement needs-triage tui
Product or interface

CLI - interactive TUI

Use case and problem

(This also affects the Desktop app, which drives the same remote app-server over SSH.)

If only one of the four items below can be addressed, please make it (a) — making the updater opt-out. It is the single largest avoidable cost, and it is the one that scales with the number of hosts rather than with the amount of work being done.

I run MiniMax Code against several remote Linux hosts over SSH. The remote app-server installation is what actually executes the agent's work, so its footprint is the thing I have to budget for on every host I connect.

Measured on a 2 GB / 2 vCPU CentOS Stream 9 host, with the official installer and the official systemd unit, mcode 0.6.13:

$ ps -eo pid,rss,args | grep app-server
734348 162016 minimax-code app-server --instance-id dedicated-persistent-1
734403 230220 minimax-code app-server --updater-generation ef2a3f92-... cli.js
737522 219888 minimax-code app-server
$ du -sh /root/.minimax /root/.minimax-code
387M    /root/.minimax
540M    /root/.minimax-code

Three separate problems, in descending order of how much they cost me:

1. The updater is a permanently resident process that sleeps 99% of its life.

$ cat /root/.minimax/app-server-control/app-server-updater.state.json
{"status":"running","pid":734403,"lastCheckAtMs":1793001898033,
 "nextCheckAtMs":1793005498853, ...}

nextCheckAtMs - lastCheckAtMs is 3601 seconds. So this process holds 230 MB resident forever in order to perform one HTTP check against the npm registry once per hour, then go back to sleep. On a 2 GB host that is >11% of total RAM spent on a timer.

I went looking for a way to turn it off and could not find one:

  • mcode app-server --help — no updater-related option
  • mcode app-server daemon --help — no updater-related option
  • config.yaml — only logLevel, defaultModel, dataContribution, memory.enabled, skipWindowsHardSafetyChecks, skipParentDeathGuard, provider
  • MCODE_* / MINIMAX_* environment variables — none appear in the app-server chunk
  • The autoUpdate setting that does exist is a TUI-session-level flag and does not affect the remote daemon's updater

Reading the bundled daemon source, the gate is a.managedUpdaterEnabled ?? !0 — an internal dependency-injection parameter with no CLI flag or environment-variable surface. daemon bootstrap unconditionally spawns app-server daemon update-loop as a detached child.

2. The per-host installation is ~930 MB, and most of it is duplicated.

387M  /root/.minimax            # daemon package: packages/app-server-daemon 339M
540M  /root/.minimax-code       # CLI package: runtime/node-v24.19.0-linux-x64 201M

The daemon package and the CLI package are installed side by side and each carries its own copy of the runtime. The node binary in runtime/ (201 MB) is what actually executes both processes, so the app-server-daemon release tree appears to ship a second copy of everything the CLI package already has.

3. The process the Desktop app spawns per connection escapes process-level controls.

PID 737522 is the client process the Desktop app starts over SSH. Its parent chain is sshd → sshd-session → app-server, and its cgroup is:

0::/user.slice/user-0.slice/session-145.scope

— not the mcode-app-server.service unit. So a MemoryMax= on the unit does not apply to it, and it does not pick up NODE_OPTIONS from /etc/environment:

PID 734348  NODE_OPTIONS=--max-old-space-size=192   (in unit cgroup)
PID 734403  NODE_OPTIONS=--max-old-space-size=192   (in unit cgroup)
PID 737522  NODE_OPTIONS=(not set)                  (in session scope)

This is why a per-host MemoryMax cannot fully bound the footprint: the piece that scales with the number of connected clients is the piece outside the limit.

The same applies to the updater: it is spawned detached by daemon bootstrap and only stays inside the unit cgroup because I moved the bootstrap call into ExecStartPost. Anyone who starts the daemon by other means gets an unbounded updater.

Desired behavior

a) Make the updater opt-out, and let it idle cheaply.

At minimum, expose the existing internal flag as a supported surface, e.g.:

mcode app-server daemon bootstrap --no-managed-updater

or a config key:

updater:
  enabled: false

Even when enabled, the updater should not need a full agent runtime resident to poll a registry every hour. A ~230 MB process that performs one HTTP request per hour could either run the check as a short-lived oneshot (timer-driven, exits immediately) or release its heap between checks.

b) Share one runtime between the CLI package and the daemon package.

If the daemon package can use the node already present in /root/.minimax-code/runtime, the per-host install drops from ~930 MB to roughly ~700 MB, and more importantly the two copies cannot drift apart.

c) Let the Desktop app's remote client inherit the host's resource limits.

When the app-server spawns the per-connection client, that process should land in a cgroup the administrator controls, and should inherit the same NODE_OPTIONS the daemon itself received. Today the only lever an administrator has is systemd unit configuration, and it does not reach this process.

d) Publish minimum hardware requirements for the remote app-server.

The download documentation lists only macOS 12+ / Windows 10+. There is no published CPU, memory, or disk guidance for the remote app-server, which makes it hard to decide whether a host can host one. A line like "1 GB RAM and 1 GB free disk per remote host" would be enough to start.

Platform

Linux

Alternatives and additional context

What I have already done as a workaround, in case it is useful as a reference for what an official configuration surface would need to replace:

  • ExecStartPost runs mcode app-server daemon bootstrap instead of calling it outside the unit, so the updater inherits the unit's MemoryHigh / MemoryMax.
  • NODE_OPTIONS=--max-old-space-size=192 is injected via /etc/environment, /etc/pam.d/sshd (session optional pam_env.so), and root's shell profiles.
  • MemoryHigh=400M, MemoryMax=700M, OOMPolicy=stop on the unit.

I also hit a separate issue while doing this — pkill -f "minimax-code app-server" inside ExecStartPre matches the /bin/sh -c command line of the unit itself, so the unit kills itself on every start (Control process exited, code=killed, status=15/TERM, NRestarts climbing forever). The [m]inimax-code bracket form avoids the self-match. That one is filed separately as #545.

The probe below collects all of the above (footprint, per-process RSS / cgroup / threads, updater interval, and the absence of any updater switch). It runs on any host with the official installer:

#!/bin/sh
# MCode remote app-server footprint probe
# Usage: sh mcode-footprint.sh
# Prints RSS/cgroup/interval facts for the local MCode app-server installation.

echo "===== 1. install footprint ====="
du -sh /root/.minimax /root/.minimax-code 2>/dev/null
du -sh /root/.minimax/packages/app-server-daemon 2>/dev/null
du -sh /root/.minimax-code/runtime 2>/dev/null

echo ""
echo "===== 2. running mcode processes ====="
ps -eo pid,ppid,rss,args | grep -E "app-server" | grep -v grep

echo ""
echo "===== 3. per-process cgroup + rss + threads ====="
for p in $(pgrep -f "app-server" 2>/dev/null); do
  echo "--- PID $p ---"
  echo "  rss     : $(awk '/VmRSS/{print $2}' /proc/$p/status) kB"
  echo "  cgroup  : $(cat /proc/$p/cgroup | head -1)"
  echo "  threads : $(ls /proc/$p/task | wc -l)"
  echo "  cmdline : $(tr '\0' ' ' < /proc/$p/cmdline | head -c 180)"
done

echo ""
echo "===== 4. updater check interval ====="
cat /root/.minimax/app-server-control/app-server-updater.state.json 2>/dev/null
echo ""
python3 -c "
import json,time
try:
    d=json.load(open('/root/.minimax/app-server-control/app-server-updater.state.json'))
    lc=d.get('lastCheckAtMs',0); nc=d.get('nextCheckAtMs',0)
    print('  check interval: %s s' % round((nc-lc)/1000))
    print('  updater uptime: %s s' % round((int(time.time()*1000)-d.get('startedAtMs',0))/1000))
except Exception as e:
    print('  (no updater state:', e, ')')
"

echo ""
echo "===== 5. is there any way to disable the updater? ====="
echo "--- config.yaml keys ---"
cat /root/.minimax/config.yaml 2>/dev/null | head -20
echo "--- mcode app-server --help ---"
/root/.minimax/packages/app-server-daemon/bin/mcode app-server --help 2>&1 | head -25
echo "--- mcode app-server daemon --help ---"
/root/.minimax/packages/app-server-daemon/bin/mcode app-server daemon --help 2>&1 | head -25

echo ""
echo "===== 6. machine capacity ====="
free -m | head -2
df -h / | tail -1
主要语言
TypeScript
星标
2k
派生
259
平均合并
9 小时 58 分钟
30 天内合并 PR
54

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

MiniMax-AI/minimax-code 的其他 Issue

查看 MiniMax-AI/minimax-code 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。