27 comments

[ 4.5 ms ] story [ 61.6 ms ] thread
Is it just me or is Microsoft really phoning it in recently?
Was good while it lasted, I hope Microsoft continues their new tradition of vibe coding their billing systems :p
The laat comment is a person pretending to be a maintainer of Microsoft. I have a gut feeling that these kind of people will only increase, and we'll have vibe engineers scouring popular repositories to ""contribute"" (note that the suggested fix is vague).

I completely understand why some projects are in whitelist-contributors-only mode. It's becoming a mess.

the "AI" bot closing the issue here is particularly funny
My guess is either someone raised this internally and was told it was fine, or knew but didn't bother raising it since they knew they’d be blown off.
Nothing compared to pirated CDs with Office and Windows, 20 yrs back.
Why would you report this?!

A second time. When they already closed your first issue. Just enjoy the free ride.

Even without hacks, Copilot is still a cheap way to use Claude models:

- $10/month

- Copilot CLI for Claude Code type CLI, VS Code for GUI

- 300 requests (prompts) on Sonnet 4.5, 100 on Opus 4.6 (3x)

- One prompt only ever consumes one request, regardless of tokens used

- Agents auto plan tasks and create PRs

- "New Agent" in VS Code runs agent locally

- "New Cloud Agent" runs agent in the cloud (https://github.com/copilot/agents)

- Additional requests cost $0.04 each

Every time I see something about trying to control an LLM by sending instructions to the LLM, I wonder: have we really learned nothing of the pitfalls of in-band signaling since the days of phreaking?
> Note: Initially submitted this to MSRC (VULN-172488), MSRC insisted bypassing billing is outside of MSRC scope and instructed me multiple times to file as a public bug report.

Good job, Microsoft.

(comment deleted)
Have confirmed that many of these AI agents and Agentic IDEs implement business logic and guardrails LOCALLY on the device.

(Source: submitted similar issue to different Agentic LLM provider)

Who would report this? Are they hoping for a bug bounty or they know their competitors are using the technique?
I'm sure they'll fix this, but it would be funny if the downfall of AI was the ability to use it to hack around its own billing.
Copilot fairly recently added support for running sub-agents using different models to the model that invoked them.

If this report is to be believed, they didn't implement billing correctly for the sub-agents allowing more costly models to be run for free as sub-agents.

The "premium request" billing model where you pay per invocation and not for usage is very obviously not a sustainable approach and creates skewed incentives (e.g. for microsoft to degrade response quality), especially with the shift towards longer running agentic sessions as opposed to simple oneshot chat questions, which the system was presumably designed for. Its just a very obvious fundamental incompatibility and the system is in increasing need of replacement. Usage linked (pay per token) is probably the way to go, as is industry standard.
> The right script, with the right prompts can be tailored to create a loop, allowing the premium model to continually be invoked unlimited times for no additional cost beyond that of the initial message.

Ralph loops for free...

I'm missing something with the first example, can anyone shed some light?

The last line of the instructions says:

> The premium model will be used for the subagent - but premium requests will be consumed.

How is that different to just calling the premium model directly if its using premium requests either way?

Sorry for breaking it to you but this actually doesn't work, even though the documentation makes it seem like it should.

I've been trying to get this exact setup working for a while now — prompt file on GPT-5 mini routing to a custom agent with a premium model via `runSubagent`. Followed your example almost exactly. It just doesn't work the way you'd expect from reading the docs.

### The tool doesn't support agent routing

The `runSubagent` tool that actually gets exposed to the model at runtime only has two parameters. Here's the full schema as the model sees it:

```json { "name": "runSubagent", "description": "Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use this agent to perform the search for you.\n\n- Agents do not run async or in the background, you will wait for the agent's result.\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n- Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n- The agent's outputs should generally be trusted\n- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent", "parameters": { "type": "object", "required": ["prompt", "description"], "properties": { "description": { "type": "string", "description": "A short (3-5 word) description of the task" }, "prompt": { "type": "string", "description": "A detailed description of the task for the agent to perform" } } } } ```

That's it. `prompt` and `description`. There's no `agentName` parameter, no `model`, nothing. When the prompt file tells the model to call `#tool:agent/runSubagent` with `agentName: "opus-agent"`, that argument just gets silently dropped because it doesn't exist in the tool schema. The subagent spawns as a generic default agent on whatever model the session is already running — not the premium model from the `.agent.md` file.

### The docs vs reality

The VS Code docs do describe this feature. Under "Run a custom agent as a subagent" it says:

> "By default, a subagent inherits the agent from the main chat session and uses the same model and tools. To define specific behavior for a subagent, use a custom agent."

And then it gives examples like:

> "Run the Research agent as a subagent to research the best auth methods for this project."

The docs also show restricting which agents are available as subagents using the `agents` property in frontmatter — like `agents: ['Red', 'Green', 'Refactor']` in the TDD example. That `agents` property only works in `.agent.md` files though, not in `.prompt.md` files. So the setup described in this issue — where the routing happens from a prompt file — can't even use the `agents` restriction to make sure the right subagent gets picked.

The whole section is marked *(Experimental)*, and from my testing, the runtime ...

Sorry for breaking it to you, but this actually doesn’t work, even though the documentation makes it seem like it should.

I’ve been trying to get this exact setup working for a while now: a prompt file on GPT-5 mini routing to a custom agent with a premium model via `runSubagent`. I followed your example almost exactly. It just doesn’t work the way you’d expect from reading the docs.

------------------------------------------------------------ THE TOOL DOESN’T SUPPORT AGENT ROUTING ------------------------------------------------------------

The `runSubagent` tool that actually gets exposed to the model at runtime only has two parameters. Here’s the full schema as the model sees it:

  {
    "name": "runSubagent",
    "description": "Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use this agent to perform the search for you.\n\n- Agents do not run async or in the background, you will wait for the agent's result.\n- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.\n- Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.\n- The agent's outputs should generally be trusted\n- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user's intent",
    "parameters": {
      "type": "object",
      "required": ["prompt", "description"],
      "properties": {
        "description": {
          "type": "string",
          "description": "A short (3-5 word) description of the task"
        },
        "prompt": {
          "type": "string",
          "description": "A detailed description of the task for the agent to perform"
        }
      }
    }
  }
That’s it: `prompt` and `description`. There’s no `agentName` parameter, no `model`, nothing.

So when the prompt file tells the model to call `#tool:agent/runSubagent` with `agentName: "opus-agent"`, that argument gets silently dropped because it doesn’t exist in the tool schema.

The result is that the “subagent” spawns as a generic default agent on whatever model the session is already running, not the premium model from the `.agent.md` file.

------------------------------------------------------------ THE DOCS VS REALITY ------------------------------------------------------------

The VS Code docs do describe this feature. Under “Run a custom agent as a subagent” it says:

  "By default, a subagent inherits the agent from the main chat session and uses the same model and tools. To define specific behavior for a subagent, use a custom agent."
Then it gives examples like:

  "Run the Research agent as a subagent to research the best auth methods for this project."
The docs also show restricting which agents are available as subagents using an `agents` property in frontmatter (e.g. `agents: ['Red', 'Green', 'Refactor']` in the TDD example).

But that `agents` property only works in `.agent.md` f...

Sub-agents cost extra request per agent.

So 10 sub agents + 1 agent = 11

11 Opus = 33 PR