CedarCopilot wants to merge 0 commits into staging from fix/chat-maxsteps-100
Live on prod, no production signal yet
Libra has verdicts on 0 of 1 tracked behaviors on prod; 1 is still being checked. Libra checks hourly for 3 days after each deploy.
Raises the chat agent's tool-loop step cap from 20 → 100 on the four surfaces the user interacts with directly:
| Surface | File |
|---|---|
| Frontend (in-app chat) | chat-workflow.ts |
| Slack | slack-bot-chat.ts |
| iMessage | imessage-bot-chat.ts |
| SMS | sms-bot-chat.ts |
Background/automation paths (orchestrator dispatch, operation registry, execute-orchestrator, etc.) are intentionally left at their existing caps , this only touches direct-user chat.
Investigating why the Slack bot sometimes replies "I did not generate a response." The message is a fallback that fires only when the agent finishes with empty text. Prod telemetry (last 14 days):
{"text":""}, no buttons, no thread replies).Chat Agent (Understudy) generate() that ended on finish_reason: "tool-calls" , i.e. it hit maxSteps: 20 while still mid tool-loop (8k,24k output tokens).The prompts force multiple silent lookups (find-crm-conversations → get-conversation → write) before any output and only ever emit text inside a final <final_answer> block, so a run that exhausts the step budget has no assistant text anywhere → extractFinalAgentText returns "" → the fallback string. Raising the ceiling gives these runs room to reach their final answer.
The frontend never hit the cap in the measured window (0/238 exhaustions; it also streams, so it wouldn't blank out) , but it's raised too for consistency across direct-user surfaces.
This raises the ceiling but does not remove the failure mode , a run that still exhausts 100 steps hits the same blank-message fallback on the headless generate() path. Recommended next steps:
finish_reason: "tool-calls" / empty text, do one more "wrap up now" generate step instead of giving up.responseText = structured?.text ?? rawText (?? preserves "") so a threadReplies-only response isn't blanked.🤖 Generated with Claude Code
Raises the Mastra agent tool-loop limit from 20 to 100 for the four direct-user chat surfaces so multi-step requests have more opportunity to produce a final response.
The PR appears safe to merge, with the explicitly acknowledged increase in worst-case agent cost and latency remaining the primary operational tradeoff.
The changes only raise existing step limits on direct-user chat invocations, and the review found no concrete new timeout, retry, delivery, security, or correctness failure.
| Filename | Overview |
|---|---|
| apps/server/src/mastra/routeHandlers/imessage/imessage-bot-chat.ts | Raises the iMessage chat agent generation limit from 20 to 100 steps without changing routing or response handling. |
| apps/server/src/mastra/routeHandlers/slack/slack-bot-chat.ts | Raises the Slack chat agent generation limit from 20 to 100 steps to reduce empty responses from unfinished tool loops. |
| apps/server/src/mastra/routeHandlers/sms/sms-bot-chat.ts | Raises the SMS chat agent generation limit from 20 to 100 steps without changing surrounding behavior. |
| apps/server/src/mastra/workflows/chat/chat-workflow.ts | Applies the same 100-step limit to the legacy streamed in-app Mastra chat path. |
Reviews (1): Last reviewed commit: ["fix(chat): raise maxSteps 20→100 on user..."](https://github.com/cedarcopilot/cedar
Libra has not measured any production surfaces for this change yet.