-
-
contest_architecture
-
Daftar Home Dashboard: Clean overview of net balances and offline-first customer ledgers.
-
Human-In-The-Loop (HITL): Merchant reviews credit alerts and manually prepares the collections call.
-
Agentic Instructions: Dynamic system prompt generation for the CALL-E agent before dialing.
-
Dual-Rail HITL: Merchant approves a mixed batch of PSTN calls and email statements.
-
Closing Agent Workflow: Gemini-powered agent executing daily reconciliation and backend tasks via Cloud Run.
-
Call Report & Proof of Action: Structured call outcomes, call IDs, and integer promises strictly recorded on-device.
-
Professional Back-Office: Auto-generated, structured PDF statements for merchant records and offline tracking.
Inspiration
Across the Arab street, many shops still close the day on paper. After the ledger is copied, the merchant still has to phone overdue customers—or names get skipped and calls get forgotten. That specific phone chore is the problem—not “AI that makes phone calls.”
Daftar (دفتر) is an offline-first debt ledger that existed before this hackathon. In August 2026 a Closing Agent (Gemini + ADK + HITL) was added for a different contest. For CALL-E the significant update is Confirm & Call: consented outbound collections calls to supported numbers at close of day, with an integer promise on device—not a payment.
What it does
- Close of day: merchant confirms the plan, opens the Collections Desk, and taps Confirm & Call (dual rail: up to five voice calls + email statements). The desk calls all supported rows in that set—not a single PSTN.
- Device ranks who can be called (aging, allowlist, do-not-call). Gemini does not pick contact IDs.
- Call rail: every region-eligible, allowlisted number in the call set gets a CALL-E
calls.create; Yemen and other unsupported regions show Can't call and stay on Gmail SMTP (accepted ≠ delivered). - Promise card: structured integer
promised_amount_minordisplays on device. No ledger transaction from the call. Payment stays a later human confirm (Model C). - Confirm & Call stays in the product after the hackathon.
Real World Impact: Close-of-day collections for shops that still use paper books—they still make those calls themselves, or they forget. CALL-E returns a promise, not cash.
How we built it
Quality of the Idea: HITL Confirm & Call on a dedicated desk—not a generic dialer. Non-obvious pieces: device-ranked dual rail; region gate refuses unsupported numbers instead of failing PSTN; integer promise never cashiers. Reusable contribution: Agent Skill ledger-collections-call (merged PR #385)—complementary to community kept; this project did not invent collections promises.
Technical Implementation: Production path is the CALL-E Developer API, not MCP. On Cloud Run service daftar-call-e, Python imports calle-ai==0.7.0 and calls CalleClient.calls.create (POST /v1/calls) at runtime—one create per eligible contact in the call set (cap 5). The Android app triggers run-batch; the device polls GET /v1/calls/{runId} (no public webhook; no create_and_wait on Cloud Run). CALL-E is a sibling FastAPI route—not a ninth ADK FunctionTool (eight-tool catalog frozen). Architecture HUD shows Call · + last-8 of call.id. Gmail send-batch is the email rail after Confirm & Send Statements.
Stack: Flutter · Drift · Riverpod · Google ADK + Gemini 3.5 Flash (proposals only) · FastAPI on Cloud Run · Secret Manager for API keys.
Product Experience & Demo: ≤3:00 video: Close today → desk → this demo: one live on-device ring (seed had one US-eligible row; owner-owned Callcentric US DID answered in Linphone, disclosed on VO) → promise card → YE email row. The product cap is still five supported calls. English VO with burned-in EN subtitles over Arabic-capable UI.
Repo: https://github.com/akrmcodes/daftar-call-e · Disclosure: docs/CONTEST_DISCLOSURE.md · Diagram: docs/architecture/contest_architecture.md
CALL-E / AIRUDDER API traffic is Singapore-hosted. Names and amounts leave the device for the call rail.
Challenges we ran into
- Region honesty: Yemen cannot be dialed on CALL-E; the product must refuse early and route to email—not pretend PSTN worked.
- HITL boundaries: Gemini proposes; the merchant confirms; the model does not dial or cashier. Separating ADK proposals from the CALL-E sibling route kept the eight-tool freeze intact.
- Proof of Action:
task_completed/ integer promise ≠ paid; SMTP 250 = Gmail accepted, not delivered; poll ≠ webhook theater.
What we learned
Importing calle-ai and calling it at runtime on the device path—plus a dry-run Agent Skill—beats laptop-only smoke. A structured integer promise is useful only if the ledger still requires a later human confirm.
What's next
Confirm & Call stays in the product. Dual rail stays for regions CALL-E cannot dial. A later Play Store listing is planned; multi-device sync stays deferred (Stage 8 quarantined in this repo).
Log in or sign up for Devpost to join the conversation.