Inspiration
I live in a large residential complex, and I’ve often seen issues get discussed in our group chats without anything happening afterwards. Someone brings up a problem, people respond, and then other messages take over. The issue is still there, but the conversation has moved on.
That’s where the idea for Steward came from. I wanted a way to follow up on the things we were already talking about: what needs to be done, who is handling it, and whether it has actually been resolved. I also wanted us to be able to look back at how we dealt with similar problems before, instead of relying on someone in the group to remember.
What it does
Steward follows up on the issues people raise in their community chat. If several residents report the same broken elevator, it brings those messages into one case and checks the community’s records for previous repairs. That gives the person handling it some useful context before they start making calls or asking for quotes.
From there, Steward can prepare quote requests, compare replies and help work out the next step. It follows the community’s spending and approval rules, asks for a manager’s decision when needed, and keeps track of responses and unfinished work. A vendor saying the repair is done is followed by a check that the problem has actually been resolved.
It also helps with matters that need a discussion. If residents disagree about visitor parking, Steward can put together an agenda with the different proposals and questions that still need answering. It helps arrange the meeting and, once the outcome is confirmed, records the agreed actions and who is responsible for them.
Residents can see what is happening with their reports and tasks. Managers have a shared record of the work, the decisions behind it and anything still waiting for attention. When a similar issue comes up later, the community has something to refer back to.
How we built it
Steward has a Python backend built with FastAPI and a React/TypeScript web app. Residents and managers have different views of the same case records. A background worker handles pending jobs and follow-ups, so keeping a case moving does not depend on someone leaving the app open.
I used the Strands Agents SDK for the parts that involve understanding messages and working out what to do next. Separate agents handle incoming reports, extract details from vendor replies, prepare recommendations, and help with meeting agendas and minutes. A coordinator running on Amazon Bedrock AgentCore can review a case, look up relevant history, and call procurement or meeting specialists when needed. The agents use Amazon Nova Pro through Bedrock.
Community records are stored in PostgreSQL. Titan V2 embeddings and pgvector help retrieve relevant past cases, alongside structured repair history and vendor records. This gives the agents information about what happened before when they prepare a recommendation.
The model’s recommendation still has to pass the application’s checks. Python code enforces permissions, spending limits and the conditions for moving a case forward. Pending work and delivery records are stored in the database so the worker can recover after a restart without losing track of what it was doing.
The application runs on ECS Fargate, with RDS for the database, Cognito for sign-in, and S3 and CloudFront serving the web app. Telegram connects the community chat to Steward, and the email integration uses SES with S3, SNS and SQS for incoming messages.
Challenges we ran into
Keeping track of unfinished work was one of the harder parts. A reply can arrive late, a model call can fail, or the application can restart while a case is still open. The case can also change while an agent is preparing its recommendation. I had to make sure Steward checked the latest state before acting and could pick up pending work after a restart. Sending an order twice would create a real problem, so an uncertain delivery needs to be checked before another attempt.
Another challenge was deciding where the agent’s authority should end. Comparing quotes is useful, but a recommendation still has to fit the community’s budget and approval rules. The same applies to meetings: several people discussing an idea does not mean the community has agreed to it. I kept those checks in the application code and required confirmation before recording meeting outcomes as decisions.
Using past records also needed care. An earlier repair might be relevant without being the right answer to the current problem. I made the agents work from identifiable sources and kept that evidence available in the interface, so a manager can see what a recommendation is based on and question it.
Accomplishments we're proud of
I’m proud of bringing the different parts of Steward together into a working application. A message in a community chat can become a case with its own history, supporting records and next steps. Residents can follow what is happening, and managers can see what needs their attention and why.
Getting the Telegram integration working was a satisfying milestone. Steward can receive real messages, bring duplicate reports into the same case, and send updates through the background worker. I also tested the email workflow separately using two test addresses, covering quote requests, replies, an order and appointment confirmation, including recovery after a restart.
I built repeatable tests to check how the workflows behave when things go well and when they need to stop for human review. The recorded offline run passed 180 checks across 20 scenarios, each repeated three times. Those checks gave me a practical way to catch regressions as I continued building the product.
What we learned
I learned how much work comes after deciding what to do. There is still a reply to wait for, someone to remind, or a repair to check. Building Steward made me pay closer attention to those small steps, because any one of them can leave an otherwise straightforward issue unfinished.
I also came to think differently about community memory. Keeping old messages is useful, but a useful record should also explain what was tried, why a decision was made and whether it worked. That is the information I would want to find the next time the same problem came up in my own community.
Working on the agents made me more careful about uncertainty. When information is missing or a decision needs someone’s approval, Steward needs to make that clear. Giving people enough context to make the next decision became an important part of the product.
What's next for Steward
I’d like to try Steward with a small group of residents and a community manager who are willing to use it for everyday issues. I want to find out whether it helps them spend less time chasing updates, whether the case records are useful, and where it adds unnecessary work. Their feedback would shape what I build next.
I also want to test the full maintenance process with participating vendors, from the first request for a quote through to a resident confirming that the problem has been fixed. That would help me understand how Steward handles the delays, incomplete replies and changes of plan that come with real work.
After that, I’d focus on making it easier for another community to get started with its own residents, records and approval rules. My goal is to build something I would be comfortable proposing to the people in my own residential complex and could keep improving with their feedback.
Built With
- amazon-bedrock
- amazon-bedrock-agentcore
- amazon-cloudfront
- amazon-cognito
- amazon-ecs
- amazon-nova
- amazon-rds-relational-database-service
- amazon-ses
- amazon-sns
- amazon-sqs
- amazon-web-services
- aws-cdk
- aws-fargate
- fastapi
- pgvector
- postgresql
- python
- react
- strands-agents
- telegram
- typescript
Log in or sign up for Devpost to join the conversation.