Skip to content

Vendor Adapters

New since v0.9.1 (hotfix #130; already in npm latest)

⏳ Interim workaround — not a permanent design

This adapter is an interim patch, not anet's vendor-specific lock-in roadmap. anet has reached out to the InternLM team to push an upstream fix — once intern-s2-preview emits standard Anthropic tool_use content blocks by default, this adapter can be retired.

We added this layer to unblock users immediately for intern + multi-agent coordination (before v0.9.0 promote, intern tool calling was completely broken). It's not because anet wants to take on the long-term maintenance cost of "hugging some vendor's specific behavior." See §5 Future polish — Upstream coordination status for tracking.

agent-node's claude-agent-sdk runtime is an Anthropic Messages API client, so in theory any Anthropic-compatible endpoint (InternLM / DeepSeek / GLM / Kimi / MiniMax / OpenRouter / self-hosted lmdeploy …) should just work. In practice, each vendor's RLHF fine-tuning takes its own path, and the same Anthropic-protocol payload produces behavioral divergence across vendors:

  • MiniMax / Anthropic native: tool calls work out of the box; stop_reason: "tool_use", content blocks correct
  • InternLM intern-s2-preview: accepts the tools parameter but under tool_choice: "auto" defaults to verbose "Thinking Process" free-form text — does not emit tool_use content blocks. Forcing tool_choice: {type:"tool", name:...} is rejected with -20077 不支持的 tool_choice 值.

To stop users getting stuck on "the same prompt works on MiniMax but not on Intern", as an interim patch agent-node introduces vendor adapters: detect the vendor by ANTHROPIC_BASE_URL and prepend a tailored system-prompt bias that nudges the model's RLHF behavior back to Anthropic-standard. The end state we want: upstream fixes the RLHF → this adapter gets retired.


Current adapters

intern (InternLM 书生)

Trigger condition: ANTHROPIC_BASE_URL matches the regex /intern-ai\.org\.cn|chat\.intern-ai/i (agent-node/src/cli.ts processWithClaude).

Injection: a short bias is prepended before the user's system prompt, instructing the model to emit tool_use content blocks directly and skip the verbose thinking process.

Effect (verified by direct curl; full data in the research report):

DimensionWithout adapter (pre-v0.9.1)With adapter (v0.9.1+, already in npm latest)
stop_reasonmax_tokens (free text capped at limit)tool_use (clean stop)
output_tokens1024 (saturated)122 (concise)
content[1]No tool_use block{type:"tool_use", name:"commhub_send_task", input:{...}}
Multi-agent coordinationTasks often fail to dispatch — hub sees no send_taskDispatch closes the loop

Generalises: the detection regex matches both intern-ai.org.cn and chat.intern-ai subdomains, so future intern-* endpoints don't need code changes.


⚠ Side effects (must read)

The vendor adapter is the minimum viable fix for an RLHF bias, not a free lunch. Five known user-visible side effects:

1. Loses Intern's "Thinking Process" transparency

The bias makes the model skip the thinking stage and emit tool_use directly — flattening one of intern-s2-preview's signature features (visible chain-of-reasoning). You can't see the model's decision reasoning when debugging.

Correction (source-verified 2026-07-16): ⚠️ the note here and several below — that anet node start --prompt replaces/disables the bias and reverts the model to native RLHF — is inaccurate. In reality: ① anet node start has no --prompt flag (--prompt is an agent-node flag; set a node's system prompt via its config.json systemPrompt field); ② for intern endpoints the bias is prepended unconditionally (agent-node/src/cli.ts combinedSystemPrompt = internToolUseBias + SYSTEM_PROMPT) — a custom prompt is appended after the bias, not a replacement, and does not revert the model to native RLHF. To see the raw Thinking Process, don't use the intern endpoint (or wait for the upstream fix to retire the adapter); a code-level --no-vendor-bias switch is not yet implemented (see §5 backlog).

2. Detection fragility — URL regex only matches the chat.intern-ai.org.cn family

The regex /intern-ai\.org\.cn|chat\.intern-ai/i is a plain string match. Three edge cases bypass the bias:

  • Self-hosted lmdeploy + InternLM2.5 (base URL like http://your-server:23333)
  • Intern behind a proxy (https://your-proxy.com/intern)
  • Aggregators (OpenRouter / your own gateway) routing to intern models

In these cases the bias never fires and tool calling stays broken.

Migration hint: for self-hosted / proxy setups (the endpoint doesn't match the intern regex, so the bias isn't auto-applied), if you want the bias, copy its content into the node's config.json systemPrompt (or agent-node --prompt; anet node start has no such flag). The exact bias content is in agent-node source — commit 4cd0024 (~10 lines).

3. Silent injection — the bias is invisibly prepended to your system prompt

The bias is an implicit injection — when you customize a system prompt, you don't know it's there.

Typical debugging confusion: "I wrote prompt X but the model behaves like Y, why isn't it listening?" — because what actually ran was <bias> + <your X>.

Migration hint: anet info <alias> already prints tools: + flags: lines (companion to #101's create banner). A polish-gap follow-up plans to add bias_active: true/false to make the bias state explicit.

4. Forced tool-calling style — bias says "MUST emit tool_use"

The bias's core instruction is "must emit tool_use". This is net positive for multi-agent coordination (agents dispatching tasks to each other). It's a drag on single-agent report generation (you want the model to write a markdown summary, not call tools) — the model becomes over-eager to invoke tools instead of producing text.

Typical use-case skew: you ask an intern agent to write a weekly report, but the bias makes it frantically try to call Read / WebFetch instead of writing prose.

Migration hint: setting a custom system prompt (via the node's config.json systemPrompt field, e.g. "Only produce reports; do not call tools.") can steer behavior, but for intern endpoints it does not turn off the tool-use bias (the bias is still prepended unconditionally, your prompt is appended after it — see the correction under #1).

5. Fewer tokens out = less explainability

Same root cause as #1: intern's default output saturates 1024 tokens (verbose reasoning) → with the bias it cleanly stops at 122. A clean tool-call chain is good, but you lose insight into why the model decided this way.

Migration hint: a verbose mode (preview gap) is planned to dump the model's full raw response. For now, to get model-thinking visibility you have to avoid the intern-biased path (see the correction under #1); there is no --prompt shortcut.


Can you turn off the bias? (currently: no)

For intern endpoints the tool-use bias is prepended unconditionally (agent-node/src/cli.ts combinedSystemPrompt = internToolUseBias + SYSTEM_PROMPT) — there is no switch to disable it right now:

  • Setting a custom system prompt (the node's config.json systemPrompt field, or agent-node --prompt directly) is appended after the bias — it does not replace or remove it.
  • anet node start has no --prompt flag.
  • To run with no bias at all: use a non-intern endpoint, or wait for the --no-vendor-bias switch to land (P1 backlog, see §5).

The prompt can also be persisted in the prompt field of .anet/nodes/<alias>/config.json (agent-node reads it via loadProfile).


Future polish (open gaps)

Aligned with the follow-up gaps listed in #130's engineering code trace:

  • P1 anet info <alias> to print bias_active: true/false — make silent injection explicit
  • P1 --no-vendor-bias flag — turn off the bias without replacing the system prompt
  • P2 Verbose mode (--log-level debug chain?) — dump the model's raw response including the thinking process
  • P2 Self-hosted / proxy detection fallback — detection beyond URL regex (model name / startup banner probe?)

Upstream coordination status

VendorStatusChannel
InternLM🟡 As of 2026-05-16, the anet team has reached out to the InternLM team to push an upstream fix (have tool_choice: auto emit standard Anthropic tool_use content blocks by default)anet team contacts

Adapter retirement conditions (either is sufficient to remove the vendor adapter layer):

  • After an intern endpoint update, a direct curl A/B with tool_choice: auto emits a tool_use block by itself (no system-prompt bias needed)
  • Or: upstream agrees to embed the prompt bias server-side on the endpoint, transparent to clients

Tracking: when InternLM team feedback lands (new version release notes / API change notice), we'll add a timeline entry here; adapter removal will get its own changelog item and we'll keep backward compatibility (older anet versions that still carry the bias must still run; the new version may drop it).


References

Powered by Sleep2AGI