Navigator was over a year in the making. It came from projects, apps, personal exploration, and just plain curiosity. But let's start.


Part 1: Milo (Spring/Summer 2025)

Logo and start page for Milo.


Over the spring and summer of 2025, I began work on Milo: an AI companion for older adults facing loneliness and isolation, where it would remember conversations with users, know their preferences, and proactively ask the user to have a conversation.

{

"user": {

"name": "",

"age": "",

"birthday": {

"month": "",

"day": "",

"year": ""

},

"personality": [],

"interests": [],

"experiences": [],

"preferences": {

"tone": "",

"responseLength": "",

"creativity": "",

"languages": [],

"chat_times": [],


               "accessibility": {

          "base_text_size": "",

          "contrast": "",

          "element_size": ""

       }

},

Excerpt of user preferences that Milo learns and updates as it interacts with the user.


Onboarding was designed to be a conversation with the user about their life and what they enjoy, rather than pressing buttons or selecting settings on a screen.

Example of a conversation in an early version of Milo. Milo would remember what the user said a few chats ago, the user's appointments, friends, hobbies, and more. Milo was designed to provide warmth with a humanistic personality.


However, while making Milo, there was always the question of "Can't ChatGPT/Gemini/Claude already do this?". The question grew louder and louder.

Part 2: Side Projects (Summer 2025)

for entry in candidates:

original_markdown = entry["original_markdown"]

alt_text = entry["alt_text"]

img_path = entry["img_path"]

absolute_path = Path(img_path).resolve()

desc = entry.get("description", "ERROR: no description generated")


obj = json.dumps({"path": str(absolute_path), "description": desc}, ensure_ascii=False)


new_markdown_tag = f"![]({absolute_path})"

insertion = f"""{new_markdown_tag}\n\n```json\n"description": "{desc}"\n```\n\n"""


# Replace only the first occurrence to preserve order and identical tags elsewhere

content = content.replace(original_markdown, insertion, 1)

logger.debug("Inserted description for %s", img_path)

Excerpts of code from image processing pipeline for crawled government minutes.


While building Milo, I also had a few side-projects I would work on, one of which was an app to chat with government minutes. It would crawl minutes from local city governments' websites, process text and images/charts on the minutes' PDFs, and then store the processed minutes into a searchable index for LLMs to understand the latest policy developments.

Logs from a crawling run for meeting minutes from Los Altos' city government website. Most government sites around Santa Clara County used a similar format where minutes were located in numerical indexes in a ViewFile/Item page within their archives.


Minutes would then be processed into high-dimensional vectors representing semantic meaning, placed into a lightweight index, and made searchable based on relevance to a query.

for s in sources:

if s not in seen:

unique_sources.append(s)

seen.add(s)


if unique_sources and "Sources from the Los Altos Government:" not in partial:

partial += "\n\nSources from the Los Altos Government:\n" + "\n".join(unique_sources)




# 10) Persist

chat_history.extend([

{"role": "user", "content": message},

{"role": "assistant", "content": partial}

])



# 11) Finalize

history[-1] = (message, partial)

yield history, gr.update(value="")


…



with gr.Blocks() as demo:

gr.Markdown("## Minutes Chat with Gemma 3 12B")

chat = gr.Chatbot(value=[])

query = gr.Textbox(label="Ask a question", placeholder="Type your question and press Enter")

query.submit(user_input, inputs=[query, chat], outputs=[chat, query], queue=True)


Excerpts of code from the chatting interface for crawled government minutes.


Ultimately, an LLM would search through the index, find the most relevant minutes, and respond with an answer to the user's question with the minutes as a source of evidence and context.


Milo could search across conversations to find the user's preferences and remember past interactions. This project could search across government minutes to answer questions from nonprofit staff about policy changes.


The key was a knowledge base to search through.

Part 3: Navigator (Present)

Design of Navigator's interface for users.


Navigator came from plugging the ability to search into an organization's documents.


Milo understood a user by searching through conversations, and my project understood policy changes by searching meeting minutes. Navigator understood organizations by searching files, emails, chats, and more.


Navigator was created because having institutional knowledge saved the hours spent in the back office switching between tabs, files, and folders trying to find information that AI can find in a matter of seconds. An hour saved from the back is an hour returned to the community that relies on the organization and its staff.

Design of Navigator's knowledge base.


Navigator could learn about an organization and its mission to tailor its responses from institutional knowledge contained in files, chats, emails, CRMs, notes, and more. Navigator was built around an organization's rich knowledge across years of reports, operations, and community impact. Its knowledge base goes beyond word-based search to wrap in human connections, partnerships, and priorities key to a nonprofit's strategic operations.

Design of Navigator's Slack-posting capability.


With the knowledge base, Navigator can then provide targeted strategic insights to staff, such as analyzing policy changes, the latest community news, or funder updates and connecting them to an organization's mission and priorities.

Design of Navigator's model reasoning indicators.


Navigator connects institutional knowledge to external, real-time information, connecting the dots between an organization and its community. This allows for strategic and fundraising work such as grant responses based on funder priorities and giving history, or identifying partners suitable for expanding an existing program.


These capabilities allow Navigator to complete work that would have taken staff hours in a matter of minutes, returning them to human relationship-building or working closely with their communities on the frontlines.

Ultimately, Navigator's ability to turn raw data across an organization: spreadsheets, slideshows, reports, and emails into strategic insights that connect to real-time press releases from corporate partners, financial statements from donors, or updates on a community is what makes it helpful for organizations.


In a case study with Successful Aging Solutions & Community Consulting, Navigator was able to save 12 hours for a sizeable AARP grant, and 3-11 hours on fundraising tasks in general with it performing particularly well in researching fundraising opportunities. Navigator was also able to reduce partnership tasks from 4 hours to 30 minutes.


With the saved time, staff were able to work on frontline coordination such as with a community-wide computer distribution event and relationship-building for fundraising and strategic efforts.


This is Navigator. It came from passion projects and apps that accumulated into the backbone of its knowledge layer and strategic insights. As it enters early access, Navigator is now implemented in operations impacting over 300,000 people in the San Francisco Bay Area across multiple social organizations.