OpenBMB / OpenBMB/PilotDeck

Router accepts mismatched subagent model tags and strips user text

Open Beginner friendly
#430 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
4k
Forks
453
Avg merge
12h 30m
Merged PRs (30d)
46

Description

Summary

The router subagent tag parser accepts malformed tags whose opening and closing tag families do not match. For example, <ccr-subagent-model>...</pilotdeck-subagent-model> is currently treated as a valid control tag.

This can silently turn ordinary user-provided text into router control input: detectSubagent marks the request as a subagent request and extracts a model hint, while stripSubagentTagFromMessages removes the malformed text from the user message.

Code path

  • src/router/scenario/subagentDetector.ts:3 defines SUBAGENT_TAG_PATTERN with independent alternations for the opening and closing tag families.
  • src/router/scenario/subagentDetector.ts:17 uses the regex in detectSubagent and sets taggedInUserMessage, modelHint, and isSubagent.
  • src/router/scenario/subagentDetector.ts:53 uses the same regex in stripSubagentTagFromMessages and removes the matched text.
  • src/router/scenario/decideScenario.ts:26 consumes the detection result for router scenario selection.
  • src/router/RouterRuntime.ts:510 enables subagent tag stripping when the decision is considered a subagent request.

Steps to reproduce

Tested against local HEAD dbb2b416.

From the repository root:

node --import tsx --input-type=module <<'NODE'
import {
  detectSubagent,
  stripSubagentTagFromMessages,
} from './src/router/scenario/subagentDetector.ts';

const messages = [
  {
    role: 'user',
    content: [
      {
        type: 'text',
        text: '<ccr-subagent-model>openai/gpt-4o</pilotdeck-subagent-model> explain this markup',
      },
    ],
  },
];

const tools = [{ name: 'agent', inputSchema: {} }];

console.log(JSON.stringify(detectSubagent(messages, tools, true)));
console.log(JSON.stringify(stripSubagentTagFromMessages(messages)[0].content[0].text));
NODE

Current output:

{"isSubagent":true,"modelHint":"openai/gpt-4o","missingAgentTool":false,"taggedInUserMessage":true}
" explain this markup"

Expected behavior

Only same-family tag pairs should be accepted as router control tags, for example:

<pilotdeck-subagent-model>...</pilotdeck-subagent-model>
<ccr-subagent-model>...</ccr-subagent-model>

A cross-family pair should be ignored by detectSubagent and preserved by stripSubagentTagFromMessages:

<ccr-subagent-model>...</pilotdeck-subagent-model>

Actual behavior

The cross-family pair is accepted as valid. This causes:

  • detectSubagent to return isSubagent: true and taggedInUserMessage: true for malformed user text;
  • modelHint to be extracted from the malformed tag body;
  • stripSubagentTagFromMessages to delete text that was not a valid control tag.

Existing coverage

I searched existing issues for subagentDetector, subagent-model, cross-family, and malformed subagent. The only nearby matches were subagent configuration issues (#247 and #248), which do not cover this tag parser behavior.

Suggested fix

Bind the closing tag family to the opening tag family, for example with a backreference:

const SUBAGENT_TAG_PATTERN =
  /<(pilotdeck|ccr)-subagent-model>([\s\S]+?)<\/\1-subagent-model>/i;

With that shape, the model hint capture would move from match[1] to match[2].

Suggested tests

  • same-family pilotdeck tags are detected and stripped;
  • same-family ccr tags are detected and stripped;
  • cross-family tags are not detected as subagent control tags;
  • cross-family tags are preserved by stripSubagentTagFromMessages;
  • ordinary user text containing malformed XML-like snippets is not silently removed.

Submitted with Codex.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/router/scenario/subagentDetector.ts, especially SUBAGENT_TAG_PATTERN and the detectSubagent and stripSubagentTagFromMessages call sites. Run the reproduction from the issue, then add coverage for same-family detection and stripping, cross-family rejection and preservation, and malformed XML-like text. Done means only matching tag families affect router control input.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.