Inspiration

Somnora: Build With Gemini Submission

Somnora came from wanting to point AI at a novel problem, not just make an existing problem easier to solve. The belief underneath it: the ability to understand yourself, and to feel understood, should not be a gatekept luxury.

The concept was forged while I was a press videographer in an active conflict zone. In that kind of volatile, high-stress environment, I needed a psychological sounding board—something to keep me grounded and help me unpack the hyper-vivid dreams I kept having. I did not want a boilerplate therapist-bot handing me canned behavioral checklists. I wanted a companion with an unapologetic, witty, deeply human personality; one that means well and genuinely entertains, but refuses to preach.

When I started building last July, it began as an experimental prototype. After earning a spot in the Google for Startups program, that experiment matured into a full multi-agent architecture. The sprint has cost me plenty of my own sleep, but the infrastructure we built is meant to give our users theirs back.

What It Does

Somnora is an agentic wellness companion that turns subconscious raw material and spontaneous cognitive overflow into structured insight, behavioral patterns, and emotional clarity.

  • Daily Journal: An interactive diary where users process daily events and emotional states in live conversation with Nora.
  • Multi-Modal Ingestion: Captures sleep profiles plus audio or text entries during the fragile waking window.
  • Eureka Mode (Apple Watch Stream): For raw thoughts caught away from a screen. Record an idea to your watch in the shower; by the time you dry off, an asynchronous queue delivers it to Nora, who interrogates it, extracts hidden links, and compiles an actionable report ready to export.
  • Dreamcatcher: An isolated visualization engine that converts dream narratives into vivid, surrealist artwork.
  • Reflection Ledger: A curiosity engine that cross-references emotional states against real HealthKit sleep cycles to surface long-term recurring themes.

How We Built It

The client is native Swift for iOS and watchOS, built on a thread-isolated, actor-based architecture so the UI never stutters; local persistence is decoupled from the main thread via a dedicated FileStorageRepository actor handling all sandbox file I/O.

The heart of the product is Nora's memory, powered by Google's Gemini models via Vertex AI. We built Somnora's Retrieval-Augmented Generation (RAG) memory system around an agentic multi-tier routing pipeline—routing complex architectural reasoning to high-capacity reasoning tiers and delegating mechanical refactors and extraction tasks to high-throughput models like gemini-3.5-flash. Memory runs in three distinct stages: formation, synthesis, and linting.

1. Formation

Every conversational turn yields candidate memories, each scored for salience before it is allowed to persist:

$$S_{\text{candidate}} = \alpha \cdot E_{\text{charge}} + \beta \cdot S_{\text{specificity}} + \gamma \cdot R_{\text{recurrence}}$$

where $E_{\text{charge}}$, $S_{\text{specificity}}$, and $R_{\text{recurrence}}$ capture emotional charge, specificity, and recurrence. Only candidates above a strict threshold survive.

2. Synthesis

A memory's salience decays over time but is reinforced whenever its theme resurfaces, so durable patterns rise and one-off noise fades:

$$S_{\text{decay}}(t) = S_0 \cdot e^{-\lambda t} + \sum_{k=1}^{n} \Delta S_k$$

At prompt-construction time, Nora ranks memories by blending semantic similarity, salience, and recency:

$$W_i = w_1 \cdot \text{Sim}(q, m_i) + w_2 \cdot S_{\text{decay}}(t) + w_3 \cdot T_{\text{recency}}(t)$$

She then packs the highest-value set that fits a fixed token budget—a 0/1 knapsack problem over the memory pool, where $C_i$ is a memory's token cost and $B$ is the packet budget:

$$\max \sum_{i} W_i x_i \quad \text{subject to} \quad \sum_{i} C_i x_i \le B, \quad x_i \in {0, 1}$$

3. Execution Gateway

Inference streams through a serverless gateway (somnora-proxy) on Google Cloud Run, fronted by a dynamic router that selects a target model node $N_{\text{target}}$ based on prompt complexity $P_{\text{complexity}}$ and a latency budget $L_{\text{budget}}$:

$$N_{\text{target}} = f(P_{\text{complexity}}, L_{\text{budget}})$$

To pressure-test Nora's persona, we ran an automated swarm of OpenClaw agents through hundreds of parallel, adversarial conversations designed to test her boundary safety and tone resilience. Fittingly, half of our feature ideas were brainstormed inside Somnora's own Eureka mode—we used the platform to expand the platform.

Challenges We Ran Into

  • Teaching Nora to Remember: The hardest problem was not storing text; it was deciding what deserves to become a memory, how to fuse it with existing knowledge, and how to stop the pool from rotting. Formation had to reject conversational filler without discarding quiet, load-bearing details. Synthesis had to reconcile schema drift across deployments, so we built memoryReaderPrecedence.js to merge and deduplicate legacy profiles with our durable RAG collections live during prompt construction. Linting bounded unbounded growth; near-duplicates are merged above a similarity threshold:

    $$\text{merge}(m_i, m_j) \iff \cos(\mathbf{e}{m_i}, \mathbf{e}{m_j}) \ge \theta_{\text{dup}}$$

    and each memory class is capped to the top $k$ entries ranked by reinforcement recency:

    $$\text{top}k(m) \quad \text{ranked by} \quad R(m_i) = S{\text{decay}}(m_i) \cdot T_{\text{recency}}(m_i)$$

  • Identity Consistency in Dream Cards: When a generated card depicts the user, it must reflect their actual demographics rather than a default model guess. We blend the user's demographic anchor $\mathbf{U}{\text{demographics}}$ with Nora's contextual interpretation vectors $\mathbf{E}{\text{nora}}$:

    $$\mathbf{I}{\text{card}} = \sigma \left( \mathbf{U}{\text{demographics}} + \sum_{k=1}^{n} w_k \mathbf{E}_{\text{nora}}(k) \right)$$

  • Context Isolation for Dreamcatcher: We constrained the image generation pipeline strictly to the dream narrative itself, filtering out unrelated conversational filler so tangential chat topics never leaked into the visual prompt.

  • The Privacy Realignment: Early designs claimed the app was entirely on-device, but running deep linguistic models requires cloud egress. We overhauled our privacy architecture to be radically transparent: health biometrics stay strictly isolated on-device, while conversational text is sanitized and processed through our private API proxy gateway.

  • Defeating Feature Overloading: Because we brainstormed expansion inside Eureka, the platform over-featurized quickly. We resolved layout clutter by restructuring the UI into a modular, widgetized framework.

Accomplishments That We're Proud Of

We made self-reflection stop feeling like work. By treating a user's thoughts with genuine curiosity instead of cold, clinical judgment, we built something people actually look forward to opening to discover their own cognitive patterns—giving it a distinct, uncompromised personality that listens without preaching.

What We Learned

Building a product at the edge of agentic AI means solving problems that do not have existing playbooks yet. As model capabilities and API architectures evolve rapidly, you cannot build solely for current-generation constraints; you have to predictively engineer decoupled scaffolding that can absorb sudden jumps in LLM intelligence without breaking the core user experience. High-capacity LLMs showed us that what you get out of an agentic system depends entirely on the intention, structure, and deterministic rules you put in.

What's Next for Somnora

  • Ecosystem Expansion (Android & Wear OS): Porting the app to Android and bringing Eureka Mode natively to Wear OS—rebuilding background listener routines in Kotlin and Jetpack Compose while mapping asynchronous telemetry queues to Health Connect.
  • Portable Memory via MCP: Building a Model Context Protocol (MCP) bridge to Obsidian, allowing users who want to take their data outside our ecosystem to let their local desktop workflows keep personal progress organized—memory that belongs to the user, not the platform.
  • Modular Interface Customization: Expanding our widgetized architecture so users can customize their own dashboard layouts, pulling specialized tracking modules from a feature store while keeping the app clean and personal.

Built With

Share this project:

Updates