Skip to content

fix(mmx-octopus): v1.9.0 - keep every write inside the plugin dataDir, let the user create their own mmx agent - #119

Merged
MyPrototypeWhat merged 3 commits into
MiniMax-AI:mainfrom
antianqi:fix/marketplace-v190
Nov 9, 2026
Merged

MyPrototypeWhat merged 3 commits into
MiniMax-AI:mainfrom
antianqi:fix/marketplace-v190

Conversation

@antianqi

@antianqi antianqi commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

为什么改

官方插件市场拒收了 1.8.0,理由是:插件默认会往宿主内部的 agent 目录写文件 —— 新增一个 agent.md,越出了插件自己的数据目录;用户没有明确同意就多出一个 agent,卸载后也不会清理;而且与包内的说明矛盾。

官方给了两条可合入的改法,这个 PR 两条都做了;评审随后提的两处必改也修在同一个 PR 里(第三个 commit):

  • 改法 A(第一个 commit):把那条能力整个删掉(不是改成默认关闭)—— 保证上架合规。
  • 改法 B(第二个 commit):引导用户自己建 agent,插件只负责识别 —— 保住「专属 agent」这个体验方向,同时插件全程不写宿主文件。

改了什么

改法 A:把「插件替用户建 agent」整条拿掉

  • 删除 miniapp/node/agentprov.mjs(往宿主 agent 目录写文件的模块)与 miniapp/scripts/agentprov-cli.mjs(手动新增 agent 的命令行工具)。
  • 删除「建专属 agent」这一档:不再有 DEFAULT_AGENT_MODE / normalizeAgentMode / SELF_AGENT_NAME,不再探测宿主 agent 根目录,不再为探测建临时会话。
  • 删除 POST /api/agent-mode 路由、状态机里的 agentMode / agentStatus 字段、面板上的「她用哪个 agent」二选一(设置区与首启卡片两处)。
  • 身份层回到 v1.7.0 的做法:每一轮随消息带(withIdentity / assembleChatInput)。

改法 B:想让她的性格更鲜明 ⇒ 用户自己建 agent

  • 新增 miniapp/node/agentcard.mjs:纯函数,读包内 miniapp/node/identity/AGENTS.md 与 identity/PERSONA.md,渲染出宿主认识的 agent 正文(frontmatter name: mmx / description / x-mavis.displayName + 身份层三段)。一个字都不写盘。
  • 新增只读路由 POST /api/agent-card:返回 {ok, name, found, body}。found 来自 context.agent.agents() 的只读探测(宿主 agent 列表里有没有那个 mmx)。
  • 面板设置区新增「想要更鲜明的性格?」区块与 「复制她的设定」 按钮:点了把设定正文复制到剪贴板,引导用户自己在 MiniMax Code 的 Agent 设置里新建一个名为 mmx 的 agent 并粘贴保存。建不建都行。
  • agent 名字的真源仍然只有一处:agentpick.mjs 的 PET_AGENT_NAME;agentcard.mjs 只 import 它,不自己写死。

评审要求的两处修复(第三个 commit)

评审在 PR 上提了两条必改 —— 都属实,已修:

  • state.mjs 构造函数里补回 this.petAgent = null; —— 删「建专属 agent」那一档时把初值一起删掉了,新装时是 undefined、快照里也没这个字段(契约写的是 string 或 null)。顺带删掉 438 行附近那段关于「默认建专属 agent」的过时注释、修掉 1172 行附近一处乱缩进的注释块。
  • 加载 state 时清掉 1.8.0 留下的那个 agent 名 —— 1.8.0 会把 mmx-octopus-agent 写进用户的 state.json;若原样恢复,resolvePetAgent() 会优先用它,老用户升级后仍会在那个 agent 上建会话,和「1.9.0 不再碰它」对不上。现在 agentpick.mjs 导出 LEGACY_SELF_AGENT_NAME,加载时值等于它就丢掉 ⇒ 回到用户自建的 mmx 或默认 agent;别的值一律保留(用户自己显式指定的 agent 名不会被误清)。
  • 那个遗留名字现在全包只出现一次,且只当「要丢掉的值」用 —— 任何地方拿它去建 / 选那个 agent 都算违规。

现在的行为

  • 写:只有 context.dataDir 下四个 JSON(state.json / chat.json / diary.json / style.json),原子写。这个目录之外一个字节都不写。
  • 读:包内文件、context.dataDir 里的数据,以及宿主列出来的 agent 列表 —— 只读。如果你自己建了一个叫 mmx 的 agent,她就用那个来回答;没有就用默认 agent。插件不新增、不修改、不删除任何 agent。
  • 要专属 agent? 面板里点「复制她的设定」→ 自己建一个叫 mmx 的 agent → 粘贴保存。之后插件只读地认出它并用它回答;认不出就回到「每轮随消息带」。agent 的创建与删除都是用户自己的事。
  • 版本:1.8.0 → 1.9.0(plugin.json / package.json / 两份 README)。

怎么验的

  • 自检 880 项 / 0 失败(v1.8.0 是 875 项)。新增三组判据:
    • 「第四十八轮」16 条守的是能力不存在:包内两个模块已移除、生产代码 0 处引用 agentprov、生产代码一处也不碰宿主 agent.md / AGENTS.md、落盘点仍只有那四个 JSON、状态机里没有 agentMode、面板上不再有那个二选一、用户自己的 mmx agent 仍然优先、身份层仍每轮随消息带。其中 4 条是负向注入(把写宿主 agent.md 的代码塞回 server.mjs / 把 agentprov.mjs 放回包里 / 把 agentMode 放回 state.mjs / 把那条路由塞回 server.mjs),另有 2 条是行为级判据:真起一套 server 跑一轮聊天,再扫目录,确认 dataDir 之外一个文件都没多。
    • 「第四十九轮」14 条守的是**「交设定 ≠ 写文件」**:agentcard.mjs 一个字都不写盘、渲染正文带 frontmatter 与身份层三段、buildAgentCard 真读包内身份层、名字真源唯一、面板上有按钮与引导、POST /api/agent-card 真跑返回可粘贴正文、只读认出用户建的 mmx、取正文后 dataDir 之外 0 个文件。其中 2 条是负向注入(往 agentcard.mjs 塞写盘代码 / 让它自己写死别的名字)。
    • 「第五十轮」9 条守的是评审要的那两处:构造函数初值是 null(不是 undefined)、新装快照带 petAgent 字段、加载时丢掉 1.8.0 留下的那个名字、非遗留的显式指定仍然保留(不许误丢)、丢掉后回到「用户自建的 mmx 或默认 agent」、state.mjs 里没有过时的「默认建专属 agent」口径、也没有乱缩进的注释块。其中 2 条是负向注入(拆掉加载时的遗留守卫 / 删掉构造函数里的初值)。
  • 证伪实验(证明判据不是恒真):① 把「写宿主 agent.md」的代码塞进真 server.mjs ⇒ 恰好 3 条红,诊断逐字指向 server.mjs: agent.md;② 把 writeTextAtomic 塞进真 agentcard.mjs ⇒ 恰好 4 条红(含第四十九轮专属那条)。③ 删掉 state.mjs 构造函数里的 this.petAgent = null; ⇒ 恰好 4 条红;④ 拆掉加载 state 时的遗留守卫 ⇒ 恰好 3 条红(连改写后的第四十八轮那条也抓到了「那个名字被拿去用」)。四次还原后都是 880 项全绿。
  • 另外第四十八轮那条判据按新事实改写并加严了(不是放松阈值):那个遗留名字的字面量只允许在 agentpick.mjs 出现一次,用法只允许是 state.mjs 里「≠ 它 ⇒ 丢掉」的那一处比对 —— 任何地方拿它去建 / 选那个 agent 都算红。
  • 上游仓库自己的校验:npm test 87/87 通过,npm run validate → plugins/antianqi/mmx-octopus: OK。
  • 面板实测(本地跑真实 index.html + 真实路由):首启卡片只剩「她的名字 / 她怎么叫你」,没有「她用哪个 agent」二选一;设置区能读到「复制她的设定」按钮与完整引导文案。

给 1.8.0 用户

如果你是 1.8.0 用户并让它建过专属 agent,宿主数据目录里可能还残留 agents/mmx-octopus-agent/,可以手动删掉 —— 1.9.0 不会再创建它,也不会再去碰它。如果你的状态文件里还记着那个 agent,1.9.0 加载时会忽略它,她回到用你自己建的 mmx(没有就用默认 agent)。想让她有自己的 agent,现在用面板上的「复制她的设定」自己建一个 mmx 就行。两份 README 里都写了这两段说明。

…1.9.0)

The official plugin marketplace rejected 1.8.0 because the plugin wrote into the
Host's agent directory (a new agent.md) - outside its own dataDir, without the
user asking for it, and never cleaned up on uninstall.

This version applies the official fix A: the capability is removed outright.

- Delete miniapp/node/agentprov.mjs (writes into the Host agent directory) and
  miniapp/scripts/agentprov-cli.mjs (the manual CLI).
- Drop the "dedicated agent" tier: DEFAULT_AGENT_MODE / normalizeAgentMode /
  SELF_AGENT_NAME, the Host agent-root probing, and the temporary probe session.
- Drop the POST /api/agent-mode route, the agentMode / agentStatus state fields
  and the "which agent she uses" choice in the panel (settings and first-run card).
- Identity travels with every message again (withIdentity / assembleChatInput).
- Writes are limited to four JSON files under context.dataDir, atomically.
  Reads are limited to package files, dataDir data and the Host agent list.
  The plugin adds, changes and deletes no agent.
- Version 1.8.0 -> 1.9.0 (plugin.json / package.json / both READMEs).

Self-test: 857 checks, 0 failures (new group "round 48", 16 checks).

Copy link
Copy Markdown
Collaborator

方向很好,删得很干净。两处小问题:

  1. state.mjs 构造函数里误删了 this.petAgent = null;,新装时 petAgent 会是 undefined,快照里也没有这个字段,麻烦加回来。另外 438 行附近关于「默认建专属 agent」的注释已经过时,那行和 1172 行附近的缩进也乱了,顺手清一下。
  2. 1.8.0 用户的 state.json 里可能还存着 petAgent: "mmx-octopus-agent",resolvePetAgent 会优先用它,所以升级后仍会在那个 agent 上建会话,和「1.9.0 不再碰它」对不上。麻烦在加载 state 时清掉这个值,回到用户自建的 mmx 或默认 agent。

还有一个不卡合并的小建议:1.8.0 已经在宿主里建好的 mmx-octopus-agent,1.9.0 不会清掉。可以在 README 里告诉老用户怎么手动删掉它。

改完就可以合,谢谢!

The marketplace offered two acceptable fixes for 1.8.0. The previous commit
applies fix A and removes the capability outright. This commit applies fix B:
guide the user to create the agent, and let the plugin only recognise it.

- Add miniapp/node/agentcard.mjs: a pure function that renders her character
  sheet (reads the package's own identity/AGENTS.md and identity/PERSONA.md)
  into an agent file the Host understands. It writes nothing at all.
- Add the read-only route POST /api/agent-card: returns that text plus
  "found", a read-only probe of the Host agent list for an agent named mmx.
- Add a "复制她的设定" button and a short how-to in the panel settings:
  copy the sheet, create an agent named mmx in the Host's Agent settings,
  paste it, save. Creating it is optional.
- The agent name still has exactly one source: PET_AGENT_NAME in agentpick.mjs.
  agentcard.mjs only imports it.

The plugin still writes no Host file: the user creates and deletes the agent,
the plugin only finds it and falls back to "carried with every message".

Docs: both market READMEs (What it does, Usage, Data & access, Known limits,
Upgrading from 1.8.0) describe the new flow.

Self-test: 871 checks, 0 failures (new group "round 49", 14 checks).

Copy link
Copy Markdown
Collaborator

新加的「复制她的设定」很好,全程不写宿主文件,可以保留。不过上次提的两点还没改:

  1. state.mjs 构造函数里还是少了 this.petAgent = null;,附近缩进也还乱着。
  2. 加载 state 时还没清掉 1.8.0 留下的 petAgent: "mmx-octopus-agent",老用户升级后仍会在那个 agent 上建会话。

这两处改完就可以合,谢谢!

…name (v1.9.0)

Two fixes the marketplace reviewer asked for on PR MiniMax-AI#119.

- state.mjs: restore "this.petAgent = null" in the constructor. Removing the
  "create a dedicated agent" mode took the initial value with it, so a fresh
  install had undefined and the snapshot was missing a field the contract
  declares as string or null.
- state.mjs: drop the agent name 1.8.0 left behind. agentpick.mjs now exports
  LEGACY_SELF_AGENT_NAME ('mmx-octopus-agent'); when the state is loaded, a
  stored value equal to it is discarded, so an upgraded user no longer gets a
  session on that agent any more. Any other explicitly stored name is kept.
- Also removed a stale comment about the old default and fixed one badly
  indented comment block.

The legacy name now appears exactly once in the package, and only as the value
to discard - never as something to create or to select.

Docs: both market READMEs note that a saved state still pointing at the old
agent is ignored by 1.9.0.

Self-test: 880 checks, 0 failures (new group "round 50", 9 checks).
@antianqi antianqi changed the title fix(mmx-octopus): keep every write inside the plugin's own dataDir (v1.9.0) fix(mmx-octopus): v1.9.0 - keep every write inside the plugin dataDir, let the user create their own mmx agent Nov 9, 2026
@antianqi

antianqi commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

两条必改都改好了,在同一个 PR 的第三个 commit(ab45681)里:

1. state.mjs 构造函数里补回 this.petAgent = null;

  • 确实是我在删「建专属 agent」那一档时把初值一起删掉了(v1.8.0 有、v1.9.0 没有),已加回,并补了 @type 注释。
  • 438 行附近那段关于「默认建专属 agent」的过时注释已删,换成新口径的注释。
  • 1172 行附近乱缩进的注释块已修。

2. 加载 state 时清掉 1.8.0 留下的那个 agent 名

  • 你说得对:1.8.0 会把 mmx-octopus-agent 写进 state.json,resolvePetAgent() 又优先用它 ⇒ 老用户升级后仍会在那个 agent 上建会话。
  • 现在 agentpick.mjs 导出 LEGACY_SELF_AGENT_NAME,state.mjs 加载时值等于它就丢掉,回到「用户自建的 mmx 或默认 agent」。
  • 只有那一个名字会被丢:用户自己显式指定的 agent 名仍然保留,不会被误清。
  • 这个遗留名字现在全包只出现一次(就是 agentpick.mjs 那个常量),而且只当「要丢掉的值」用 —— 任何地方拿它去建 / 选那个 agent,自检都会判红。

3. 建议项(README 告诉老用户怎么手动删)

  • 已经在两份 README 的「Upgrading from 1.8.0 / 从 1.8.0 升级」段里写了:<宿主数据目录>/agents/mmx-octopus-agent/ 可以手动删。
  • 另外补了一句:状态文件里还记着那个 agent 的话,1.9.0 加载时会忽略它。

验证

  • 自检 880 项 / 0 失败:新增「第五十轮」9 条(含 2 条负向注入:拆掉加载时的遗留守卫 / 删掉构造函数初值)。
  • 证伪实验:删掉 this.petAgent = null; ⇒ 恰好 4 条红;拆掉加载时的守卫 ⇒ 恰好 3 条红(连改写后那条「那个名字只能当值丢掉用」的判据也抓到了);还原后 880 项全绿。
  • 上游 npm test 87/87、npm run validate 通过;CI 绿,PR 现在 mergeable / clean。

麻烦再看一眼,谢谢!

@MyPrototypeWhat
MyPrototypeWhat merged commit 2c78f99 into MiniMax-AI:main Nov 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants