<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Dhruv Agarwal</title>
    <description>The latest articles on DEV Community by Dhruv Agarwal (@dhruvagar69ops).</description>
    <link>https://dev.to/dhruvagar69ops</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4153130%2F1f1cd596-3b81-49f3-af93-769011b2ea6a.jpg</url>
      <title>DEV Community: Dhruv Agarwal</title>
      <link>https://dev.to/dhruvagar69ops</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dhruvagar69ops"/>
    <language>en</language>
    <item>
      <title>Meeting Memory: Ask Your Questions about your Meetings and Get the Exact Lines Back, Built for My Club Friends</title>
      <dc:creator>Dhruv Agarwal</dc:creator>
      <pubDate>Sun, 04 Oct 2026 10:04:51 +0000</pubDate>
      <link>https://dev.to/dhruvagar69ops/meeting-memory-ask-your-meetings-questions-and-get-the-exact-lines-back-for-my-friends-in-a-club-7kc</link>
      <guid>https://dev.to/dhruvagar69ops/meeting-memory-ask-your-meetings-questions-and-get-the-exact-lines-back-for-my-friends-in-a-club-7kc</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Meeting Memory is built for my friends in a club. Clubs hold recurring meetings, and the decisions and action items from them get buried in long chats and notes or gets flushed out of memory.&lt;br&gt;
Meeting Memory loads meeting transcripts and lets you ask questions across all of them. Every answer shows the speaker, the timestamp and the lines it came from. If the meetings don't contain the answer, it says "Not found" instead of guessing. It also extracts decisions, action items and open questions, each tied to a quote.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who it's for:&lt;/strong&gt; someone who sits in recurring project meetings and loses track of what was decided. I built and evaluated it on four linked meetings from the public AMI Meeting Corpus, where a design team plans a remote control.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/zJeiElD7o40" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The app has an Ask page (a chat with a "Sources" section on every answer) and a Decisions &amp;amp; actions page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dhruvagar69-ops" rel="noopener noreferrer"&gt;
        dhruvagar69-ops
      &lt;/a&gt; / &lt;a href="https://github.com/dhruvagar69-ops/meeting-memory" rel="noopener noreferrer"&gt;
        meeting-memory
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Meeting Memory&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Ask your meetings questions and get answers that point to the exact speaker and moment.&lt;/p&gt;
&lt;p&gt;Built for the DEV &lt;strong&gt;Hacktoberfest Weekend Challenge: "Build for a Friend"&lt;/strong&gt;. Started 2026-10-02 (first commit 2026-10-03).&lt;/p&gt;
&lt;p&gt;Meeting Memory loads meeting transcripts, pulls out decisions, action items and open questions (each tied to a quote), and lets you ask questions across all the meetings. Every answer cites the lines it came from. If the meetings do not contain the answer, it says "Not found" instead of guessing.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Who it is for:&lt;/strong&gt; someone who sits in recurring project meetings and loses track of what was decided. It was built and evaluated on the public AMI Meeting Corpus. It was &lt;strong&gt;not&lt;/strong&gt; tested with a real friend or team.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;
&lt;pre class="notranslate"&gt;&lt;code&gt;transcript (AMI or plain text)
   -&amp;gt; parse into segments: speaker, start time, text, id like ES2008b-s0216
   -&amp;gt; SQLite (segments + a keyword index)
EXTRACT&lt;/code&gt;&lt;/pre&gt;…&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dhruvagar69-ops/meeting-memory" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data:&lt;/strong&gt; AMI Meeting Corpus (CC BY 4.0), downloaded by script and not redistributed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extraction:&lt;/strong&gt; a model reads each meeting in chunks and proposes decisions, actions and questions. Each item must include a quote that appears word-for-word in the cited segment. Items with a missing quote or an invented segment are dropped, owners must be real speakers, and a deadline is kept only if it was actually spoken.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ask (retrieval-augmented generation):&lt;/strong&gt; keyword search (SQLite full-text, BM25) finds the best stretches of conversation across all meetings. The model answers using only those, with numbered citations. Citations to anything it wasn't given are removed, an answer with no valid citation is flagged, and if nothing relevant is found the model isn't called at all. There are no embeddings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optional retrieval add-ons:&lt;/strong&gt; the model suggests synonyms for the question, and the search can also take the best matches from every meeting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Models:&lt;/strong&gt; &lt;code&gt;openai/gpt-oss-120b&lt;/code&gt; for extraction and &lt;code&gt;qwen/qwen3.8-27b&lt;/code&gt; for answers. Both are open-weight and were served by Groq.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App and tests:&lt;/strong&gt; a Streamlit front end, SQLite storage, and more than 50 automated tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;p&gt;I labelled everything by hand on a small sample, so treat the numbers as indicative. Some verdicts started from AI-suggested labels that I then reviewed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Answering, 16 answerable questions:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;th&gt;Correct&lt;/th&gt;
&lt;th&gt;Partly right&lt;/th&gt;
&lt;th&gt;Wrong&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Plain keyword search&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Synonyms + per-meeting sampling&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All 4 questions the meetings can't answer returned "Not found". For some of them the search found nothing, so the model was never asked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retrieval was the bottleneck.&lt;/strong&gt; The line I'd marked as the source was retrieved for 7 of 16 questions with plain search, and for 8, 10 and 9 with the add-ons. When it was retrieved, it was almost always cited. Differences of one or two questions are noise at this size, so I don't rank the variants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extraction, final meeting, 44 items:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Items&lt;/th&gt;
&lt;th&gt;Fully supported&lt;/th&gt;
&lt;th&gt;Partly&lt;/th&gt;
&lt;th&gt;Unsupported&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Decisions&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Actions&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open questions&lt;/td&gt;
&lt;td&gt;27&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Decisions were the strongest result. Open questions were poor, because the model lists questions that someone answers a line later. Model size mattered: on this meeting a smaller model run found 3 items and the 120b model found 44, though the reasoning settings also differed, so it isn't a clean comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Points where the results changed the plan:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A small model found only 3 items in the last meeting; the 120b model found 44, so I switched.&lt;/li&gt;
&lt;li&gt;Groq returned JSON-mode failures, empty replies from a reasoning model, and token-limit errors (413 and daily limits). Each one led to a fix: a fallback when JSON mode is rejected, a clear message for token limits, and a resume option for the evaluation runs.&lt;/li&gt;
&lt;li&gt;I predicted that combining synonym expansion with per-meeting sampling would score best. It did not; the differences were within noise.&lt;/li&gt;
&lt;li&gt;My labels showed 20 of 27 extracted "open questions" were unsupported, so I report decisions as the main result and questions as weak.&lt;/li&gt;
&lt;li&gt;I asked "What was the meeting about?" and the app wrongly said "Not found". It now explains that the question is too general.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Where it failed&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asked what was decided about the price, it found the 12.5 Euro production target but missed the decision to sell the remote separately at 25 Euro. That line says "Euro" and never "price", and keyword search can't connect the two.&lt;/li&gt;
&lt;li&gt;Asked why voice recognition was ruled out, it cited two real statements, but not the line I'd marked ("it's gonna add too much to the price"). The answer was reasonable, which is why my automatic score undercounts quality.&lt;/li&gt;
&lt;li&gt;General questions like "what was the meeting about?" can't be searched by keyword. The app says so and points to the Decisions &amp;amp; actions page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Limits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Small evaluation: 20 questions and one meeting series.&lt;/li&gt;
&lt;li&gt;The questions and expected answers were written by an AI assistant using lines from earlier outputs, so they lean toward content the extractor had already found.&lt;/li&gt;
&lt;li&gt;One labeller. Extraction recall was not measured.&lt;/li&gt;
&lt;li&gt;Retrieval is keyword-only.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;Open-weight models let me swap models without changing the code, and I could compare model sizes directly on the same task. The same code supports a local Ollama backend. The models ran on Groq, so questions and transcript lines left the machine. For private meetings, the local path is the right choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open Source / Hacktoberfest&lt;/li&gt;
&lt;li&gt;Build for a Friend&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
    </item>
    <item>
      <title>hello</title>
      <dc:creator>Dhruv Agarwal</dc:creator>
      <pubDate>Thu, 01 Oct 2026 11:43:33 +0000</pubDate>
      <link>https://dev.to/dhruvagar69ops/hello-2j2a</link>
      <guid>https://dev.to/dhruvagar69ops/hello-2j2a</guid>
      <description></description>
    </item>
  </channel>
</rss>
