Skip to content

fix(minimax-bot): bind a new Bot session to an Agent the host can open - #56

Open
coder-bat wants to merge 1 commit into
MiniMax-AI:mainfrom
coder-bat:fix/minimax-bot-agent-binding
Open

coder-bat wants to merge 1 commit into
MiniMax-AI:mainfrom
coder-bat:fix/minimax-bot-agent-binding

Conversation

@coder-bat

@coder-bat coder-bat commented Oct 21, 2026 •

Copy link
Copy Markdown

What breaks

A Bot team on some MiniMax Code runtimes cannot talk to its Bots at all. Every turn — message_bot, a group reply, a scheduled task, a background job — fails the same way and nothing reaches the model:

Host runtime log:  Mini App Agent run {"pluginId":"minimax-bot", "phase":"rejected",
                   "errorCode":"AGENT_UNAVAILABLE", "stage":"create-session",
                   "operation":"run", "errorName":"SessionServiceError"}

The user only sees the generic "The Agent is temporarily unavailable. Try again shortly" notice, which reads like a busy host rather than a session that never opened. On the machine this was found on, 30 Bot turns had been stored and exactly one had succeeded — the greeting Chief sends when it is created. Nothing had ever worked.

Root cause

docs/agent.md says a new Node-initiated session runs as "the primary agent", and that an Agent may be named with run({ agent }), where the name must come from agents() and "the alias main is rejected".

The plugin never named one, so every session was created for the primary Agent, and the primary was resolved by that name alone. That works when the runtime stores the primary under its canonical name. It does not when the runtime still stores the primary under the legacy main name: the host then

  • offers the primary to the Mini App under its canonical name, and
  • rejects main as an alias,

while the session service resolves the name against the stored registry row. The two never meet, the session is never created, and the turn fails with AGENT_UNAVAILABLE at create-session.

The runtime itself reports the split it is in:

primary_agent_execution_identity {"storage_owner":"main","execution_owner":"main","outcome":"legacy_fallback"}

legacy_fallback means the canonical row was never seeded and the runtime is serving the legacy one. The rest of the product copes with that (it resolves the primary through the primary-family chain), but the Mini App session path did not.

This is visible in the host bundle, not only in the log:

  • MINIAPP_AGENT_NAME = 'mavis' — the name the Mini App gateway uses for a new session.
  • listAgentOptions() — offers agent.canonicalViewName and flags primary: name === MINIAPP_AGENT_NAME.
  • the session service resolves the name with a raw lookup on the agents table (Agent not found: mavis).

The fix

The turn now names an Agent when the host cannot bind the default one:

  • The Agents the host offers are tried in turn, primary first, and the one that works is used for the sessions that follow. The probe therefore happens once per Mini App start rather than on every new session.
  • A continued session never names an Agent — the host rejects agent on an existing session, and a session keeps the Agent it was created with.
  • Only a bind failure (AGENT_UNAVAILABLE) triggers the fallback. A busy session is reported as BUSY and a rejected name as INVALID_ARGUMENTS; neither is a bind failure, so neither is retried with a different Agent.
  • When no Agent can be bound, the host's own failure is reported unchanged, so nothing is masked.
  • The host log now says which Agent was bound (minimax_bot.agent_bound), so the fallback is visible next to the turn that used it.

On a runtime where the primary binds normally, nothing changes: the default is tried first and succeeds, exactly as before.

Tests

New tests/agent-binding.test.mjs (5 cases, mock Agent, no model needed):

Case Asserts
default Agent cannot be bound the turn runs as the first Agent the host offers that works (undefined → mavis → general), and the host log names it
the Agent that worked the next new session goes straight to it, without probing again
a continued session no agent key is ever sent
a host that cannot list Agents the host's failure is reported unchanged, one call only
a failure that is not a bind failure no other Agent is tried
npm ci --prefix plugins/minimax-ai/minimax-bot/tests --ignore-scripts --no-audit --no-fund
node --test plugins/minimax-ai/minimax-bot/tests/*.test.mjs     # 210 passed, 0 failed
npm run check                                                   # exit 0, 69 passed, 0 failed

npm run check reports plugins/minimax-ai/minimax-bot: OK.

Tested environment

MiniMax Code 3.1.2 on macOS. The failure was found on macOS 27.2.0 against a runtime that stores its primary under the legacy main name; the fix is a host-version-independent code path and the tests use the plugin's own mock Agent, not a real model. The change was not verified end to end against a real host runtime with the legacy-named primary: the installed package is verified by content digest, so a patched build cannot be loaded locally. The behaviour it relies on — agents() returning { agents: [{ name, displayName, primary }] } and run({ agent }) naming the Agent of a new session — is the contract in docs/agent.md.

Note for the host

The deeper fix belongs in the host: the Mini App session path should resolve the primary through the same primary-family chain the rest of the runtime uses, so that a session created for the canonical name binds the primary even when the runtime still stores it under the legacy alias. The change in this pull request is a plugin-side safety net for that case: it keeps a Bot team working without it, and it is a no-op wherever the primary binds normally.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

A new Bot session bound to the host's primary Agent, because the plugin
never named one. The host offers the primary under its canonical name
and rejects the legacy `main` alias, so a runtime that still stores the
primary under that alias cannot bind it: the session never opens and
every turn fails with AGENT_UNAVAILABLE before the model is reached.

A Bot team on such a runtime could not talk to its Bots at all. Every
turn failed the same way, and the only trace was the generic "The Agent
is temporarily unavailable" notice, which reads like a busy host rather
than a session that never opened.

The turn now names an Agent when the host cannot bind the default one.
The Agents the host offers are tried in turn, primary first, and the one
that works is used for the sessions that follow, so the probe happens
once instead of on every new session. A continued session keeps the
Agent it was created with, and a failure that is not a bind failure is
never retried with another Agent. When no Agent can be bound, the host's
own failure is reported unchanged.

The host log now says which Agent was bound, so the fallback is visible
next to the turn that used it.
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.

1 participant