Your helper can now handle a customer request. You will give it a second job: ask a coding agent, called the builder, for a small proposed change and show you exactly which file came back. The proposal will remain separate from the running helper.
Allow 25–35 minutes. Start with a local fixture so you can test the connection before spending on code generation. The fixture copies a supplied Python function that returns a pretend line status without changing anything. It is a known sample, not newly generated code. Mantle’s own conversation calls still use your API key. The optional generation step uses OpenAI’s hosted Agents API; the sample needs no hosted builder session.
Prepare the builder environment
Leave the original Inspector running for now. Open a new terminal, which this chapter calls the builder terminal. Run:
B=/workspaces/rasa-community-resources/workshops/software-factories-masterclass/router-helper/builder
python3 -m venv "$HOME/.venv-builder"
"$HOME/.venv-builder/bin/pip" install --upgrade openai mcp==1.28.1
"$HOME/.venv-builder/bin/python" "$B/builder.py" --fixture
The separate environment keeps the builder’s software development kit (SDK) apart from Mantle’s dependencies. The last command should print mode: fixture (no Agents session), followed by saved: True, an absolute file path and a hash. Keep the path for the next part.
If it instead says mode: live, stop and check that you included --fixture. If installation fails, keep the package error; do not upgrade Mantle’s environment to fix the builder’s environment.
Each fixture run gets a new output folder. An existing file is not silently overwritten. Nothing has been applied to the helper.
The fixture tests check unique paths, saved bytes and a gate invocation from another folder. Run them in this separate environment:
cd "$B"
"$HOME/.venv-builder/bin/python" -m unittest test_builder_fixture -v
Expect three tests ending in OK. They replace the OpenAI client with a failure if constructed, so a passing fixture test also checks that this mode avoids creating that client. If a test fails, preserve its named failure before proceeding to the tool server.
Start the local tool server
Open another terminal, the server terminal. Set its own path variable; terminal variables do not carry across windows:
B=/workspaces/rasa-community-resources/workshops/software-factories-masterclass/router-helper/builder
"$HOME/.venv-builder/bin/python" "$B/builder_server.py" --fixture
Leave it running. It should say Builder mode: fixture (no Agents sessions). The server listens on the Codespace’s loopback address. The connection uses Model Context Protocol, or MCP, so the helper can call a tool without importing the builder’s SDK into its own environment.
Do not make this server a public port. If its port is already in use, find your earlier server terminal and stop that owned process with Ctrl+C before starting another.
Add the skill to the helper
Return to the original Inspector terminal and press Ctrl+C. Leave the server terminal alone. Open a spare terminal and run:
B=/workspaces/rasa-community-resources/workshops/software-factories-masterclass/router-helper/builder
"$HOME/.venv-mantle/bin/python" "$B/change_builder/install_change_builder.py" "$HOME/router-helper-agent"
cd "$HOME/router-helper-agent"
"$HOME/.venv-mantle/bin/rasa" train
"$HOME/.venv-mantle/bin/rasa" inspect --port 5010
The installer copies the change-builder skill and gives custom tools at least 450 seconds to wait. The MCP client waits up to 360 seconds inside that outer limit. An inner wait cannot extend a shorter engine timeout; that is why the installer changes the agent setting too.

The two waits belong to different components. Extending the inner wait alone would still leave the engine able to stop waiting first.
Wait for the server-ready message, then reopen the Inspector address from the first part. Start a new conversation so you can distinguish this model’s result from the previous helper.
Ask for a proposal
Type add a check that tells me the line status.
The receipt must begin Fixture build. It must contain a build identifier, an absolute path, a full hash, Nothing was applied to the helper, and No Agents session was started.
Those fields come from the tool server. The local adapter sends them directly to the conversation through the tool context. It does not ask the model to invent or summarize the path. Keep the newest path; the earlier direct fixture and this MCP fixture have different output folders.
If you only see a generic follow-up, the receipt is missing. Inspect the tool events and the server terminal. If you see an unknown-outcome or timeout message, do not assume that no request reached a live builder. Check the original server before trying again. After a timeout, the hosted session’s state remains unknown until you check it.
You have now exercised the local request, file, and display path. You have not tested an Agents session. You can continue to the gate with this explicitly labeled sample.
Optional: make one real proposal
Do not run the standalone live builder as well. To make one real build through the helper, stop the fixture server with Ctrl+C in its terminal, then restart it without the fixture flag:
B=/workspaces/rasa-community-resources/workshops/software-factories-masterclass/router-helper/builder
"$HOME/.venv-builder/bin/python" "$B/builder_server.py"
The server should say live (model usage is billed). Ask for the same change once in a new Inspector conversation. The receipt should now begin Build, not Fixture build, and give the new path and hash. Keep that actual result even if a later operation fails. Do not turn an uncertain outcome into a second paid attempt.
The builder uses the OpenAI Agents API, whose session runs in a hosted environment. It is separate from the Agents SDK’s local agent loop. The shared instructions require one no-argument function with an exact return value. Your free-form request supplies the reason for the change; it does not replace that file contract.