Skip to content
RasaGet a free licence
Guides for AI teams

Guide · AI product engineer

Troubleshoot a slow connection with Strands and Rasa

Use your Strands network tools through Rasa to ask which area has a problem, explain the observations and keep callers’ histories separate.

by Rod Rivera

About 4 minutes

Key takeaways (3)
  • Use Rasa to collect missing details before calling your existing Strands tools.
  • Check the specialist’s history as well as the calling agent’s history.
  • An answer can recommend an action without carrying it out.

Your Strands tools already inspect network conditions. This tutorial connects them to Rasa so the assistant can ask which area has a problem and explain the result. The application also keeps one caller’s conversation out of the next caller’s input.

Our test shares one Strands specialist between two fictional callers. On the second call, the specialist receives both questions even though the calling agent has zero stored messages.

Both facts are true: record_direct_tool_call=False keeps the calling agent’s history empty, while preserve_context=True keeps the specialist’s context. The combined native control checks both in the same two-call run. Its replies are scripted; the observation is the SDK input, with no provider requests.

Direct-call recordingSpecialist contextCalling agent messages after two callsCaller labels in the second specialist input
DisabledReset0B
DisabledPreserved0A and B
EnabledReset8B
EnabledPreserved8A and B

The fixture deliberately shares one specialist across the two caller labels. Preservation is useful within one user’s task. If your service shares that instance across unrelated callers, turning off the caller’s recording does not reset the specialist. Choose its lifetime before adding another channel.

If you already have useful Strands tools, reuse them. This example gives those tools a Rasa conversation: Mantle asks for missing information, an application session supplies the chosen area, and a fixed native tool reads its observation. You keep the handlers and their registration rather than rebuilding them in another framework.

The scenario uses fictional Juniper Mobile and public synthetic network areas. It does not access a customer’s account or change a subscription.

Reuse the tools and separate caller histories

The Strands direct-tool API says, “Tools can be invoked programmatically”. We test what those direct calls retain while application code uses agent.tool. Calls use keyword arguments, and history recording can be changed for that call.

These are the two native paths exercised by the fixture:

The same read-only tool, with different history choices

Default direct call

specialist.tool.inspect_network(
    area="north", question="My private fixture question"
)

Returns source JM-N-101; the question and result are added to agent history.

Conversation handoff

specialist.tool.inspect_network(
    area="north", question="My private fixture question",
    record_direct_tool_call=False,
)

Returns the same source without adding the call to agent history. Rasa retains its own conversation state separately.

This distinction matters when a service shares an agent instance across callers. Inspect the existing handlers as well: changing agent-message recording does not erase a tool’s own logs or make a stateful handler stateless.

Check the specialist’s conversation history

A team may also have a Strands specialist that reasons through a model. Strands’ agent-as-tool wrapper describes “a clean baseline” for each default call. Our two-call controls inspect that baseline and the deliberately retained alternative. Explicit preservation keeps it between invocations. The wrapper and the direct caller each have their own history choice.

The scripted native wrapper controls make two calls with different fixture questions and inspect the actual model inputs. Default reset omits caller A’s question from caller B’s input; explicit preservation includes both, including when the calling agent stores nothing. Their scripted text model captures the native SDK inputs.

Caller agent agent.as_tool wrapper direct wrapper invocation Specialist conversation context reset by default preserve only when intended Specialist model receives messages Specialist reply returns to caller Caller agent messages default direct-call recording
  1. The wrapper resets specialist context by default; explicit preservation keeps it for the next call.
  2. The caller agent records a direct tool call by default; disable recording for that call when needed.
FigureCaller history and specialist context have different owners

The first choice controls what the specialist model receives on its next call. The second controls what the caller agent retains after the tool returns. Disabling direct-call recording leaves the caller’s messages unchanged; it does not reset a specialist whose wrapper preserves context. Use separate agent instances or an explicit user/task lifetime when retaining specialist history.

Retain an existing reasoning specialist in its own evaluated path. Choose its context lifetime deliberately and bind it to the appropriate user or task. The runnable Rasa example below reuses direct tools; its local Strands model refuses generation. The wrapper fixture captures its scripted model inputs.

Call the network tool from Rasa

The application session collects a missing public area selection before calling the tool. north selects source JM-N-101; south selects JM-S-201. A selected area cannot change in the same session. For another area, start a new conversation.

The question never becomes a tool name or an area argument:

The native call in network_specialist/handoff.py is:

        result = self.specialist.tool.inspect_network(
            area=self.area, question=question, record_direct_tool_call=False
        )
  1. The application calls the existing registered read-only tool by name.
  2. Session code supplies the selected area; the model supplies the question.
  3. The call does not add caller input to the shared Strands agent’s messages.

The application checks the returned area and observation shape before passing it to Mantle. A wrong-area result, an extra action field or a native tool error becomes network_evidence_unavailable. Those refusal controls use real native tool handlers, including deliberately malformed ones.

The same native handoff controls pass cancellation-shaped text as the question. It still reaches only inspect_network; the agent registers no cancellation tool. Keep this fixed call when reusing your own handlers rather than forwarding a tool name supplied in user text.

Public area selections and REST sender IDs are not account authentication. The demo mapping lives in process memory and resets on restart. Supply your own authorised identity and durable mapping if the task reads private customer data.

Ask for the area and explain the network result

The Rasa skill and tools separate selecting an area from asking the question. The model-facing inspection tool has a question argument, with no area or arbitrary tool-name argument.

Actual decorated binding controls reach the native Strands tool and retain separate selections for two mocked sender contexts. Their shared specialist messages remain empty. This verifies the local binding, not the authenticity of a caller.

The skill asks which synthetic area to inspect, explains the returned source ID and revision, and distinguishes an area-wide observation from a diagnosis of the user’s device. With missing evidence, it asks whether to clarify or stop. Mantle still uses its configured conversational model; evaluate the final wording when you connect it.

Run the pinned example

Start with the Rasa quickstart if Mantle is new to you. For this composition, check out the qualified source and install only the selected conversation environment:

git clone https://github.com/RasaHQ/rasa-community-resources.git
cd rasa-community-resources
git fetch origin 8917c626fae67c63921158a8e1eed18f0270d239
git checkout 8917c626fae67c63921158a8e1eed18f0270d239
python3 scripts/workspace.py start tutorials/frameworks-with-rasa/strands-mantle --owner network-conversation-demo
cd tutorials/frameworks-with-rasa/strands-mantle
make test
make validate

Before adding credentials, run the two-call context exercise from that project directory:

.venv/bin/python ../strands/demo_context.py

The native fixture prints four JSON records, one per combination in the opening table. Inspect the preserved-context, nonrecording row: caller_messages is 0, while second_input_includes_A and second_input_includes_B are both true. The fixture performs two actual wrapper invocations in each row and checks that each succeeds. Its scripted model captures the second invocation’s input; the calling agent’s model is never invoked.

For the direct read-only tool used by the Rasa handoff, run the separate history exercise:

.venv/bin/python ../strands/demo_history.py

The native reader exercise printed one JSON record per line:

{"recording": true, "source": "JM-N-101", "messages": 4}
{"recording": false, "source": "JM-N-101", "messages": 0}

Each branch creates a fresh fixture agent. The source stays the same while the stored message count changes. These counts describe the pinned SDK’s message representation; inspect the messages themselves when adapting your tools. Both exercises run without a model key.

Use Python 3.12 and the supplied lock. The conversation environment installs the native tool package from its local source. Tests need no provider credentials. Set your own RASA_LICENSE for training and OPENAI_API_KEY for an actual Mantle conversation; never commit them.

make train
make run

The supplied channel is text REST, bound to localhost on port 5018:

curl -sS http://localhost:5018/webhooks/rest/webhook \
  -H 'Content-Type: application/json' \
  -d '{"sender":"network-demo","message":"Why is my connection slow?"}'
curl -sS http://localhost:5018/webhooks/rest/webhook \
  -H 'Content-Type: application/json' \
  -d '{"sender":"network-demo","message":"Use the north demo area"}'

This is a reader exercise, not a recorded model run. Keep the same sender when supplying the missing area. Check for source JM-N-101, revision 2026-10-11 and the degraded observation. Use a second sender with the south selection to check source JM-S-201. Record whether the reply explains the observation without claiming a subscription was changed or diagnosing the user’s device.

What we tested

The qualification record records 18 distinct passing controls: 11 direct-tool and handoff controls, four agent-as-tool context controls and three Mantle binding controls. The follow-up run printed these separate literal excerpts. First, the native controls:

Ran 15 tests in 0.017s

OK

Then the Mantle binding controls:

Ran 3 tests in 1.432s

OK

Project validation, licensed training and cold archive loading passed on Rasa Pro 3.21.0.dev5 and strands-agents 1.57.1.

These native controls use public observations and scripted model inputs. Qualify your own model conversation and existing handlers before using this pattern with customer data.

Can I keep my existing Strands agent?

NetworkSession accepts an existing agent and calls its registered tool. The fixture factory supplies a model that refuses generation so the direct-tool route is explicit. Keep your configured model for a reasoning path, with its own context lifetime and acceptance tests; the wrapper controls demonstrate context behaviour with scripted text only.

Does nonrecording erase everything the tool writes?

No. It controls the Strands agent’s direct-call messages. A handler may maintain its own storage, logs or remote effects. Inspect those separately; the synthetic network handler here returns a copied public observation and performs no subscription operation.

The companion README includes the supported environment-retirement command. Keep your source, locks and acceptance results when the experiment finishes.