Inspiration
Many of us have experienced the frustration of workplace commitments slipping through the cracks. Someone promises in a team message to "send the Q3 report by 5 PM" or "deploy the hotfix once QA approves", but as conversation moves on, those promises get buried and forgotten.
I built Loose Ends to solve this. I wanted an assistant that could read message logs, keep track of who promised what to whom, check if blocking dependencies were resolved, and draft necessary follow-ups, all while keeping a human firmly in control before any final action is taken.
What it does
Loose Ends is a commitment-tracking assistant built using the Strands Agents SDK. It processes workplace message streams through three main stages:
- Detection: Analyzes message logs to find explicit promises, identifying the action, owner, recipient, deadline, and any blocking dependency.
- Dependency Resolution: Keeps tracked items in a
WAITING_FOR_DEPENDENCYstate until a secondary agent scans new messages for clear, explicit evidence that the blocker is resolved, updating the status toREADY_TO_ACT. - Action Preparation & Review: Searches internal documents to gather facts needed to fulfill ready tasks, drafts a response, and displays it in a local web dashboard. A runtime guardrail blocks automatic completion, requiring an explicit human click to mark any task
COMPLETED.
How I built it
I built Loose Ends around the Strands Agents SDK:
- Model Flexibility: I created a model builder in
loose_ends/agent.pythat works with Google Gemini (gemini-2.5-flash-lite), Amazon Bedrock (anthropic.claude-3-haiku-20240307-v1:0), or an offline fallback for testing without API keys. - Runtime Guardrails: I used Strands typed event hooks (
BeforeToolCallEvent) to enforce safety at the code level. If an agent tries to callupdate_commitmentwithstatus="COMPLETED", the hook intercepts the call and raises an error:
$$\text{ToolCall}(\text{update_commitment}, \text{status}=\text{COMPLETED}) \implies \text{Raise ValueError}(\text{Guardrail Triggered})$$
- Scoped Tool Privileges: Agents only receive the exact tools they need for their specific phase (for example, reading documents vs updating commitments).
- Serverless & Local Runtime: Built a Python HTTP server (
app.py/loose_ends/server.py) for the local UI, and addedlambda_function.pywith an AWS SAM template (template.yaml) for serverless deployment on AWS Bedrock AgentCore.
Challenges I ran into
- Preventing Premature Resolution: Early on, model responses would sometimes assume a dependency was resolved just because a message mentioned similar keywords. I had to combine strict system prompts with domain model state validation so status changes only occur when explicit evidence is present.
- Hook Event Integration: Wiring
BeforeToolCallEventinto the Strands event registry required matching the exact type annotations expected by the SDK's callback inspector. - Test State Isolation: With a 405-test suite, keeping the in-memory store clean between test runs required careful setup and teardown logic.
Accomplishments that I'm proud of
- 405 Passing Tests: Built a suite of 405 unit and integration tests verifying store isolation, state transitions, tool execution, and guardrail enforcement.
- Real Human-in-the-Loop Safeguards: Demonstrated how AI can handle detection and research while keeping humans in charge of final approvals.
- Fast & Zero-Cost Testing: Kept local execution completely functional offline without needing expensive cloud resources during development.
What I learned
- Deterministic Hooks vs Prompting: System prompts are great for guidance, but hard runtime hooks (
BeforeToolCallEvent) are what actually guarantee safety rules are respected. - Tool Isolation Matters: Restricting tool access per workflow phase prevents accidental state mutations and keeps agent behavior predictable.
What's next for Loose Ends
My current MVP processes unstructured message streams and local documents for a single demonstrative workspace. Moving forward, I plan to expand Loose Ends by building:
- User Authentication & Multi-Tenant Isolation: Adding OAuth2 / OpenID authentication and per-user data scoping so team members only view and manage their own private commitments and drafts.
- Live Slack & MS Teams Webhooks: Ingesting real-time messages from channels and direct messages.
- Gmail & Outlook Connectors: Automatically tracking promises made across email threads.
- Task Syncing: Pushing approved commitments to Google Calendar, Linear, or Jira.
Built With
- amazon-bedrock
- amazon-web-services
- aws-lambda
- aws-sam
- cloudformation
- css3
- git
- google-gemini
- html5
- javascript
- json
- pytest
- python
- rest-api
- strands-agents-sdk
Log in or sign up for Devpost to join the conversation.